Skip to content

Move nagivateToLoginRequestUrl out of Configuration #7855

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 30 commits into from
Jun 25, 2025
Merged
Show file tree
Hide file tree
Changes from 26 commits
Commits
Show all changes
30 commits
Select commit Hold shift + click to select a range
48c37cc
Add debug param to 1p-build
hectormmg Jun 5, 2025
99f93ea
Add debug param to 1p-build (#7811)
hectormmg Jun 5, 2025
90eb889
Merge branch 'dev' of https://github.com/AzureAD/microsoft-authentica…
hectormmg Jun 5, 2025
75f6237
Suppress false-positive CodeQL finding in NavigationClient (#7814)
konstantin-msft Jun 6, 2025
fa85c44
[v4] Remove access tokens synchronously (#7822)
tnorling Jun 11, 2025
1eb9ee5
Release PR: official (#7829)
msal-js-release-automation[bot] Jun 11, 2025
97ea591
Bumped axios to latest version in all msal-node samples (#7831)
Robbie-Microsoft Jun 16, 2025
4b956d0
Bumped the dotenv package in all msal-node samples (#7823)
Robbie-Microsoft Jun 16, 2025
aedd762
Client Credential Sample: Moved client secret from code to .env file …
Robbie-Microsoft Jun 16, 2025
14fe619
Added support for DEFAULT_IDENTITY_CLIENT_ID environment variable in …
Robbie-Microsoft Jun 16, 2025
24170c2
Merge branch 'dev' of https://github.com/AzureAD/microsoft-authentica…
hectormmg Jun 17, 2025
5c8521d
Merge branch 'dev' into msal-v5
hectormmg Jun 17, 2025
24eb724
Merge branch 'msal-v5' of https://github.com/AzureAD/microsoft-authen…
hectormmg Jun 19, 2025
d16f8cb
Move navigateToLoginRequestUrl to request config
hectormmg Jun 19, 2025
9192903
Update interface and docs
hectormmg Jun 19, 2025
7fae6d2
Change files
hectormmg Jun 19, 2025
12a247a
Update API review and documentating comments
hectormmg Jun 19, 2025
609284a
Update API review
hectormmg Jun 19, 2025
d81962c
Format fix
hectormmg Jun 19, 2025
16dd784
Merge branch 'msal-v5' into navigate-to-login
hectormmg Jun 23, 2025
9f0d806
Add HandleRedirectPromiseOptions type and remove navigateToLoginReque…
hectormmg Jun 24, 2025
d5f1763
Format fix and API review update
hectormmg Jun 24, 2025
524bc98
Update lib/msal-browser/docs/v4-migration.md
hectormmg Jun 24, 2025
8d7d70a
Update handleRedirectPromise signature to consolidate hash into optio…
hectormmg Jun 24, 2025
c27f458
Merge branch 'navigate-to-login' of https://github.com/AzureAD/micros…
hectormmg Jun 24, 2025
f3b825b
Merge branch 'msal-v5' into navigate-to-login
hectormmg Jun 24, 2025
8f0f1c1
Update apiReview
hectormmg Jun 24, 2025
2edc1ff
Fix angular handleRedirectPromise
hectormmg Jun 24, 2025
334d544
Change files
hectormmg Jun 24, 2025
4244d8f
Fix formatting for angular
hectormmg Jun 24, 2025
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
{
"type": "major",
"comment": "Move navigateToLoginRequestUrl to request config",
"packageName": "@azure/msal-browser",
"email": "hemoral@microsoft.com",
"dependentChangeType": "patch"
}
2 changes: 1 addition & 1 deletion lib/msal-browser/FAQ.md
Original file line number Diff line number Diff line change
Expand Up @@ -171,7 +171,7 @@ For a full implementation, please refer to the app creation scripts in the [Vani

The redirect flow can be confusing, as redirecting away from the page means you are creating a whole new instance of the application when you return. This means that calling a redirect method cannot return anything. Rather, what happens is that the page is redirected away, you enter your credentials, and you are redirected back to your application with the response in the url hash.

If `navigateToLoginRequestUrl` property in MSAL configuration parameters is set to **true**, you will be redirected again to the page you were on when you called `loginRedirect`, unless that page was also set as your `redirectUri`. On the final page your application must call `handleRedirectPromise()` in order to process the hash and cache tokens in local/session storage.
If `navigateToLoginRequestUrl` property is passed in as an option to `handleRedirectPromise` and set to **true**, you will be redirected again to the page you were on when you called `loginRedirect`, unless that page was also set as your `redirectUri`. Your application must call `handleRedirectPromise()` in the page your `redirectUri` points to in order to process the hash and cache tokens in local/session storage.

As this function returns a promise you can call `.then` and `.catch`, similar to `loginPopup`.

Expand Down
29 changes: 17 additions & 12 deletions lib/msal-browser/apiReview/msal-browser.api.md
Original file line number Diff line number Diff line change
Expand Up @@ -281,7 +281,6 @@ export type BrowserAuthOptions = {
authorityMetadata?: string;
redirectUri?: string;
postLogoutRedirectUri?: string | null;
navigateToLoginRequestUrl?: boolean;
clientCapabilities?: Array<string>;
OIDCOptions?: OIDCOptions;
azureCloudOptions?: AzureCloudOptions;
Expand Down Expand Up @@ -731,7 +730,9 @@ export interface IController {
// @internal (undocumented)
getPerformanceClient(): IPerformanceClient;
// (undocumented)
handleRedirectPromise(hash?: string): Promise<AuthenticationResult | null>;
handleRedirectPromise(hash?: string, options?: {
navigateToLoginRequestUrl?: boolean;
}): Promise<AuthenticationResult | null>;
// (undocumented)
hydrateCache(result: AuthenticationResult, request: SilentRequest | SsoSilentRequest | RedirectRequest | PopupRequest): Promise<void>;
// (undocumented)
Expand Down Expand Up @@ -1212,8 +1213,8 @@ export { ProtocolMode }
//
// @public
export class PublicClientApplication implements IPublicClientApplication {
// Warning: (tsdoc-undefined-tag) The TSDoc tag "@constructor" is not defined in this configuration
// Warning: (tsdoc-escape-right-brace) The "}" character should be escaped using a backslash to avoid confusion with a TSDoc inline tag
// Warning: (tsdoc-undefined-tag) The TSDoc tag "@constructor" is not defined in this configuration
// Warning: (tsdoc-malformed-inline-tag) Expecting a TSDoc tag starting with "{@"
// Warning: (tsdoc-escape-right-brace) The "}" character should be escaped using a backslash to avoid confusion with a TSDoc inline tag
// Warning: (tsdoc-escape-right-brace) The "}" character should be escaped using a backslash to avoid confusion with a TSDoc inline tag
Expand All @@ -1237,17 +1238,17 @@ export class PublicClientApplication implements IPublicClientApplication {
// Warning: (tsdoc-param-tag-missing-hyphen) The @param block should be followed by a parameter name and then a hyphen
// Warning: (tsdoc-param-tag-missing-hyphen) The @param block should be followed by a parameter name and then a hyphen
addEventCallback(callback: EventCallbackFunction, eventTypes?: Array<EventType>): string | null;
// Warning: (tsdoc-param-tag-missing-hyphen) The @param block should be followed by a parameter name and then a hyphen
// Warning: (tsdoc-param-tag-with-invalid-type) The @param block should not include a JSDoc-style '{type}'
// Warning: (tsdoc-param-tag-missing-hyphen) The @param block should be followed by a parameter name and then a hyphen
// Warning: (tsdoc-escape-right-brace) The "}" character should be escaped using a backslash to avoid confusion with a TSDoc inline tag
// Warning: (tsdoc-malformed-inline-tag) Expecting a TSDoc tag starting with "{@"
addPerformanceCallback(callback: PerformanceCallbackFunction): string;
// Warning: (tsdoc-param-tag-missing-hyphen) The @param block should be followed by a parameter name and then a hyphen
clearCache(logoutRequest?: ClearCacheRequest): Promise<void>;
// (undocumented)
protected controller: IController;
// Warning: (tsdoc-param-tag-missing-hyphen) The @param block should be followed by a parameter name and then a hyphen
// Warning: (tsdoc-param-tag-with-invalid-type) The @param block should not include a JSDoc-style '{type}'
// Warning: (tsdoc-param-tag-missing-hyphen) The @param block should be followed by a parameter name and then a hyphen
static createPublicClientApplication(configuration: Configuration): Promise<IPublicClientApplication>;
// Warning: (tsdoc-param-tag-missing-hyphen) The @param block should be followed by a parameter name and then a hyphen
getAccount(accountFilter: AccountFilter): AccountInfo | null;
Expand All @@ -1257,7 +1258,10 @@ export class PublicClientApplication implements IPublicClientApplication {
getConfiguration(): BrowserConfiguration;
getLogger(): Logger;
// Warning: (tsdoc-param-tag-missing-hyphen) The @param block should be followed by a parameter name and then a hyphen
handleRedirectPromise(hash?: string | undefined): Promise<AuthenticationResult | null>;
// Warning: (tsdoc-param-tag-missing-hyphen) The @param block should be followed by a parameter name and then a hyphen
handleRedirectPromise(hash?: string | undefined, options?: {
navigateToLoginRequestUrl?: boolean;
}): Promise<AuthenticationResult | null>;
// Warning: (tsdoc-param-tag-missing-hyphen) The @param block should be followed by a parameter name and then a hyphen
hydrateCache(result: AuthenticationResult, request: SilentRequest | SsoSilentRequest | RedirectRequest | PopupRequest): Promise<void>;
// Warning: (tsdoc-param-tag-missing-hyphen) The @param block should be followed by a parameter name and then a hyphen
Expand All @@ -1278,8 +1282,8 @@ export class PublicClientApplication implements IPublicClientApplication {
logoutRedirect(logoutRequest?: EndSessionRequest): Promise<void>;
// Warning: (tsdoc-param-tag-missing-hyphen) The @param block should be followed by a parameter name and then a hyphen
removeEventCallback(callbackId: string): void;
// Warning: (tsdoc-param-tag-missing-hyphen) The @param block should be followed by a parameter name and then a hyphen
// Warning: (tsdoc-param-tag-with-invalid-type) The @param block should not include a JSDoc-style '{type}'
// Warning: (tsdoc-param-tag-missing-hyphen) The @param block should be followed by a parameter name and then a hyphen
// Warning: (tsdoc-escape-right-brace) The "}" character should be escaped using a backslash to avoid confusion with a TSDoc inline tag
// Warning: (tsdoc-malformed-inline-tag) Expecting a TSDoc tag starting with "{@"
removePerformanceCallback(callbackId: string): boolean;
Expand Down Expand Up @@ -1309,8 +1313,8 @@ export class PublicClientNext implements IPublicClientApplication {
acquireTokenSilent(silentRequest: SilentRequest): Promise<AuthenticationResult>;
// Warning: (tsdoc-param-tag-missing-hyphen) The @param block should be followed by a parameter name and then a hyphen
addEventCallback(callback: EventCallbackFunction, eventTypes?: Array<EventType>): string | null;
// Warning: (tsdoc-param-tag-missing-hyphen) The @param block should be followed by a parameter name and then a hyphen
// Warning: (tsdoc-param-tag-with-invalid-type) The @param block should not include a JSDoc-style '{type}'
// Warning: (tsdoc-param-tag-missing-hyphen) The @param block should be followed by a parameter name and then a hyphen
// Warning: (tsdoc-escape-right-brace) The "}" character should be escaped using a backslash to avoid confusion with a TSDoc inline tag
// Warning: (tsdoc-malformed-inline-tag) Expecting a TSDoc tag starting with "{@"
addPerformanceCallback(callback: PerformanceCallbackFunction): string;
Expand Down Expand Up @@ -1347,8 +1351,8 @@ export class PublicClientNext implements IPublicClientApplication {
logoutRedirect(logoutRequest?: EndSessionRequest): Promise<void>;
// Warning: (tsdoc-param-tag-missing-hyphen) The @param block should be followed by a parameter name and then a hyphen
removeEventCallback(callbackId: string): void;
// Warning: (tsdoc-param-tag-missing-hyphen) The @param block should be followed by a parameter name and then a hyphen
// Warning: (tsdoc-param-tag-with-invalid-type) The @param block should not include a JSDoc-style '{type}'
// Warning: (tsdoc-param-tag-missing-hyphen) The @param block should be followed by a parameter name and then a hyphen
// Warning: (tsdoc-escape-right-brace) The "}" character should be escaped using a backslash to avoid confusion with a TSDoc inline tag
// Warning: (tsdoc-malformed-inline-tag) Expecting a TSDoc tag starting with "{@"
removePerformanceCallback(callbackId: string): boolean;
Expand Down Expand Up @@ -1382,6 +1386,7 @@ function redirectPreflightCheck(initialized: boolean, config: BrowserConfigurati
export type RedirectRequest = Partial<Omit<CommonAuthorizationUrlRequest, "responseMode" | "scopes" | "earJwk" | "codeChallenge" | "codeChallengeMethod" | "requestedClaimsHash" | "platformBroker">> & {
scopes: Array<string>;
redirectStartPage?: string;
navigateToLoginRequestUrl?: boolean;
};

// Warning: (ae-missing-release-tag) "replaceHash" is part of the package's API, but it is missing a release tag (@alpha, @beta, @public, or @internal)
Expand Down Expand Up @@ -1555,8 +1560,8 @@ export type WrapperSKU = (typeof WrapperSKU)[keyof typeof WrapperSKU];

// Warnings were encountered during analysis:
//
// src/app/PublicClientNext.ts:69:8 - (tsdoc-undefined-tag) The TSDoc tag "@constructor" is not defined in this configuration
// src/app/PublicClientNext.ts:78:87 - (tsdoc-escape-right-brace) The "}" character should be escaped using a backslash to avoid confusion with a TSDoc inline tag
// src/app/PublicClientNext.ts:68:5 - (tsdoc-escape-right-brace) The "}" character should be escaped using a backslash to avoid confusion with a TSDoc inline tag
// src/app/PublicClientNext.ts:68:5 - (tsdoc-undefined-tag) The TSDoc tag "@constructor" is not defined in this configuration
// src/app/PublicClientNext.ts:78:60 - (tsdoc-malformed-inline-tag) Expecting a TSDoc tag starting with "{@"
// src/app/PublicClientNext.ts:84:64 - (tsdoc-escape-right-brace) The "}" character should be escaped using a backslash to avoid confusion with a TSDoc inline tag
// src/app/PublicClientNext.ts:84:77 - (tsdoc-escape-right-brace) The "}" character should be escaped using a backslash to avoid confusion with a TSDoc inline tag
Expand All @@ -1569,7 +1574,7 @@ export type WrapperSKU = (typeof WrapperSKU)[keyof typeof WrapperSKU];
// src/cache/LocalStorage.ts:297:8 - (tsdoc-param-tag-missing-hyphen) The @param block should be followed by a parameter name and then a hyphen
// src/cache/LocalStorage.ts:355:8 - (tsdoc-param-tag-missing-hyphen) The @param block should be followed by a parameter name and then a hyphen
// src/cache/LocalStorage.ts:386:8 - (tsdoc-param-tag-missing-hyphen) The @param block should be followed by a parameter name and then a hyphen
// src/config/Configuration.ts:210:5 - (ae-forgotten-export) The symbol "InternalAuthOptions" needs to be exported by the entry point index.d.ts
// src/config/Configuration.ts:207:5 - (ae-forgotten-export) The symbol "InternalAuthOptions" needs to be exported by the entry point index.d.ts
// src/event/EventHandler.ts:113:8 - (tsdoc-param-tag-missing-hyphen) The @param block should be followed by a parameter name and then a hyphen
// src/event/EventHandler.ts:139:8 - (tsdoc-param-tag-missing-hyphen) The @param block should be followed by a parameter name and then a hyphen
// src/index.ts:8:12 - (tsdoc-characters-after-block-tag) The token "@azure" looks like a TSDoc tag but contains an invalid character "/"; if it is not a tag, use a backslash to escape the "@"
Expand Down
22 changes: 22 additions & 0 deletions lib/msal-browser/docs/v4-migration.md
Original file line number Diff line number Diff line change
Expand Up @@ -58,13 +58,35 @@ await loadExternalTokens(
);
```

### `handleRedirectPromise` API signature has changed

Previously, `PublicClientApplication.handleRedirectPromise` took in an optional hash parameter. A new options type called `HandleRedirectPromiseOptions` has been introduced. As of MSAL Browser v5, an optional object with type `HandleRedirectPromiseOptions` is the only parameter `handleRedirectPromise()` accepts.

```javascript
// BEFORE
const hash = window.location.hash; // Arbitrary example value
pca.handleRedirectPromise(hash)


// AFTER
pca.handleRedirectPromise({
hash: window.location.hash, // Option nested inside a `HandleRedirectPromiseOptions` object
navigateToLoginRequestUrl: true // Additional option
})
```

## Configuration changes

### BrowserAuthOptions changes

1. The `skipAuthorityMetadataCache` parameter has been removed from BrowserAuthOptions in Configuration.
1. The `protocolMode` parameter has been moved to SystemOptions instead of BrowserAuthOptions in Configuration.
1. The `supportsNestedAppAuth` parameter has been removed. Use the `createNestablePublicClientApplication` API for Nested Apps instead. Read more about Nested Apps [here](./initialization.md#nested-app-configuration).
1. The `navigateTologinRequestUrl` parameter has been removed from BrowserAuthOptions in Configuration and can instead now be provided inside an options object as a parameter on the call to `handleRedirectPromise`:

```typescript
pca.handleRedirectPromise({ navigateToLoginRequestUrl: false })
```

### CacheOptions changes

Expand Down
5 changes: 4 additions & 1 deletion lib/msal-browser/src/app/IPublicClientApplication.ts
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@ import { EventCallbackFunction } from "../event/EventMessage.js";
import { ClearCacheRequest } from "../request/ClearCacheRequest.js";
import { InitializeApplicationRequest } from "../request/InitializeApplicationRequest.js";
import { EventType } from "../event/EventType.js";
import { HandleRedirectPromiseOptions } from "../controllers/IController.js";

export interface IPublicClientApplication {
// TODO: Make request mandatory in the next major version?
Expand All @@ -49,7 +50,9 @@ export interface IPublicClientApplication {
removePerformanceCallback(callbackId: string): boolean;
getAccount(accountFilter: AccountFilter): AccountInfo | null;
getAllAccounts(): AccountInfo[];
handleRedirectPromise(hash?: string): Promise<AuthenticationResult | null>;
handleRedirectPromise(
options?: HandleRedirectPromiseOptions
): Promise<AuthenticationResult | null>;
loginPopup(request?: PopupRequest): Promise<AuthenticationResult>;
loginRedirect(request?: RedirectRequest): Promise<void>;
logoutRedirect(logoutRequest?: EndSessionRequest): Promise<void>;
Expand Down
10 changes: 7 additions & 3 deletions lib/msal-browser/src/app/PublicClientApplication.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,10 @@ import { RedirectRequest } from "../request/RedirectRequest.js";
import { SilentRequest } from "../request/SilentRequest.js";
import { WrapperSKU } from "../utils/BrowserConstants.js";
import { IPublicClientApplication } from "./IPublicClientApplication.js";
import { IController } from "../controllers/IController.js";
import {
HandleRedirectPromiseOptions,
IController,
} from "../controllers/IController.js";
import {
PerformanceCallbackFunction,
AccountInfo,
Expand Down Expand Up @@ -212,12 +215,13 @@ export class PublicClientApplication implements IPublicClientApplication {
* has loaded during redirect flows. This should be invoked on all page loads involved in redirect
* auth flows.
* @param hash Hash to process. Defaults to the current value of window.location.hash. Only needs to be provided explicitly if the response to be handled is not contained in the current value.
* @param options Object containing optional configuration for redirect promise handling.
* @returns Token response or null. If the return value is null, then no auth redirect was detected.
*/
handleRedirectPromise(
hash?: string | undefined
options?: HandleRedirectPromiseOptions
): Promise<AuthenticationResult | null> {
return this.controller.handleRedirectPromise(hash);
return this.controller.handleRedirectPromise(options);
}

/**
Expand Down
9 changes: 6 additions & 3 deletions lib/msal-browser/src/app/PublicClientNext.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,10 @@ import { RedirectRequest } from "../request/RedirectRequest.js";
import { SilentRequest } from "../request/SilentRequest.js";
import { WrapperSKU } from "../utils/BrowserConstants.js";
import { IPublicClientApplication } from "./IPublicClientApplication.js";
import { IController } from "../controllers/IController.js";
import {
HandleRedirectPromiseOptions,
IController,
} from "../controllers/IController.js";
import {
PerformanceCallbackFunction,
AccountInfo,
Expand Down Expand Up @@ -237,9 +240,9 @@ export class PublicClientNext implements IPublicClientApplication {
* @returns Token response or null. If the return value is null, then no auth redirect was detected.
*/
handleRedirectPromise(
hash?: string | undefined
options?: HandleRedirectPromiseOptions
): Promise<AuthenticationResult | null> {
return this.controller.handleRedirectPromise(hash);
return this.controller.handleRedirectPromise(options);
}

/**
Expand Down
6 changes: 1 addition & 5 deletions lib/msal-browser/src/config/Configuration.ts
Original file line number Diff line number Diff line change
Expand Up @@ -69,10 +69,7 @@ export type BrowserAuthOptions = {
* The redirect URI where the window navigates after a successful logout.
*/
postLogoutRedirectUri?: string | null;
/**
* Boolean indicating whether to navigate to the original request URL after the auth server navigates to the redirect URL.
*/
navigateToLoginRequestUrl?: boolean;

/**
* Array of capabilities which will be added to the claims.access_token.xms_cc request property on every network request.
*/
Expand Down Expand Up @@ -241,7 +238,6 @@ export function buildConfiguration(
redirectUri:
typeof window !== "undefined" ? BrowserUtils.getCurrentUri() : "",
postLogoutRedirectUri: "",
navigateToLoginRequestUrl: true,
clientCapabilities: [],
OIDCOptions: {
responseMode: Constants.ResponseMode.FRAGMENT,
Expand Down
9 changes: 8 additions & 1 deletion lib/msal-browser/src/controllers/IController.ts
Original file line number Diff line number Diff line change
Expand Up @@ -72,7 +72,9 @@ export interface IController {

getAllAccounts(accountFilter?: AccountFilter): AccountInfo[];

handleRedirectPromise(hash?: string): Promise<AuthenticationResult | null>;
handleRedirectPromise(
options?: HandleRedirectPromiseOptions
): Promise<AuthenticationResult | null>;

loginPopup(request?: PopupRequest): Promise<AuthenticationResult>;

Expand Down Expand Up @@ -116,3 +118,8 @@ export interface IController {
/** @internal */
getPerformanceClient(): IPerformanceClient;
}

export type HandleRedirectPromiseOptions = {
hash?: string;
navigateToLoginRequestUrl?: boolean;
};
4 changes: 2 additions & 2 deletions lib/msal-browser/src/controllers/NestedAppAuthController.ts
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@ import {
DEFAULT_REQUEST,
CacheLookupPolicy,
} from "../utils/BrowserConstants.js";
import { IController } from "./IController.js";
import { IController, HandleRedirectPromiseOptions } from "./IController.js";
import { NestedAppOperatingContext } from "../operatingcontext/NestedAppOperatingContext.js";
import { IBridgeProxy } from "../naa/IBridgeProxy.js";
import { CryptoOps } from "../crypto/CryptoOps.js";
Expand Down Expand Up @@ -752,7 +752,7 @@ export class NestedAppAuthController implements IController {
// #endregion

handleRedirectPromise(
hash?: string | undefined // eslint-disable-line @typescript-eslint/no-unused-vars
options?: HandleRedirectPromiseOptions // eslint-disable-line @typescript-eslint/no-unused-vars
): Promise<AuthenticationResult | null> {
return Promise.resolve(null);
}
Expand Down
Loading