Skip to content

Adjust InjectionToken<T> constants in msal-angular to support typed Angular 14+ inject() #7484

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

Closed
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
{
"type": "minor",
"comment": "Adjust InjectionToken<T> usage so that properly-typed tokens can be used with new `inject(TOKEN)` syntax.",
"packageName": "@azure/msal-angular",
"email": "[email protected]",
"dependentChangeType": "major"
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
{
"type": "patch",
"comment": "Fix expires_in format & double brokering errors #7646",
"packageName": "@azure/msal-browser",
"email": "[email protected]",
"dependentChangeType": "patch"
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
{
"type": "minor",
"comment": "Refactor /authorize request generation",
"packageName": "@azure/msal-browser",
"email": "[email protected]",
"dependentChangeType": "patch"
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
{
"type": "patch",
"comment": "encodeURIComponent during QS generation",
"packageName": "@azure/msal-common",
"email": "[email protected]",
"dependentChangeType": "patch"
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
{
"type": "minor",
"comment": "Refactor /authorize request generation",
"packageName": "@azure/msal-common",
"email": "[email protected]",
"dependentChangeType": "patch"
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
{
"type": "none",
"comment": "Test changes",
"packageName": "@azure/msal-node",
"email": "[email protected]",
"dependentChangeType": "none"
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
{
"type": "minor",
"comment": "Refactor /authorize request generation",
"packageName": "@azure/msal-node",
"email": "[email protected]",
"dependentChangeType": "patch"
}
20 changes: 12 additions & 8 deletions lib/msal-angular/src/constants.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,17 +4,21 @@
*/

import { InjectionToken } from "@angular/core";
import { type IPublicClientApplication } from "@azure/msal-browser";
import { type MsalBroadcastConfiguration } from "./msal.broadcast.config";
import { type MsalGuardConfiguration } from "./msal.guard.config";
import { type MsalInterceptorConfiguration } from "./msal.interceptor.config";

export const MSAL_INSTANCE = new InjectionToken<string>("MSAL_INSTANCE");
export const MSAL_INSTANCE = new InjectionToken<IPublicClientApplication>(
"MSAL_INSTANCE"
);

export const MSAL_GUARD_CONFIG = new InjectionToken<string>(
export const MSAL_GUARD_CONFIG = new InjectionToken<MsalGuardConfiguration>(
"MSAL_GUARD_CONFIG"
);

export const MSAL_INTERCEPTOR_CONFIG = new InjectionToken<string>(
"MSAL_INTERCEPTOR_CONFIG"
);
export const MSAL_INTERCEPTOR_CONFIG =
new InjectionToken<MsalInterceptorConfiguration>("MSAL_INTERCEPTOR_CONFIG");

export const MSAL_BROADCAST_CONFIG = new InjectionToken<string>(
"MSAL_BROADCAST_CONFIG"
);
export const MSAL_BROADCAST_CONFIG =
new InjectionToken<MsalBroadcastConfiguration>("MSAL_BROADCAST_CONFIG");
Original file line number Diff line number Diff line change
Expand Up @@ -498,7 +498,15 @@ export class NativeInteractionClient extends BaseInteractionClient {
nativeAccountId: request.accountId,
})?.homeAccountId;

// add exception for double brokering, please note this is temporary and will be fortified in future
if (
request.extraParameters?.child_client_id &&
response.account.id !== request.accountId
) {
this.logger.info(
"handleNativeServerResponse: Double broker flow detected, ignoring accountId mismatch"
);
} else if (
homeAccountIdentifier !== cachedhomeAccountId &&
response.account.id !== request.accountId
) {
Expand All @@ -525,6 +533,9 @@ export class NativeInteractionClient extends BaseInteractionClient {
this.logger
);

// Ensure expires_in is in number format
response.expires_in = Number(response.expires_in);

// generate authenticationResult
const result = await this.generateAuthenticationResult(
response,
Expand Down
61 changes: 40 additions & 21 deletions lib/msal-browser/src/interaction_client/PopupClient.ts
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,8 @@ import { PopupWindowAttributes } from "../request/PopupWindowAttributes.js";
import { EventError } from "../event/EventMessage.js";
import { AuthenticationResult } from "../response/AuthenticationResult.js";
import * as ResponseHandler from "../response/ResponseHandler.js";
import { getAuthCodeRequestUrl } from "../protocol/Authorize.js";
import { generatePkceCodes } from "../crypto/PkceGenerator.js";

export type PopupParams = {
popup?: Window | null;
Expand Down Expand Up @@ -217,6 +219,17 @@ export class PopupClient extends StandardInteractionClient {
this.correlationId
)(request, InteractionType.Popup);

const pkce =
pkceCodes ||
(await invokeAsync(
generatePkceCodes,
PerformanceEvents.GeneratePkceCodes,
this.logger,
this.performanceClient,
this.correlationId
)(this.performanceClient, this.logger, this.correlationId));
validRequest.codeChallenge = pkce.challenge;

/*
* Skip pre-connect for async popups to reduce time between user interaction and popup window creation to avoid
* popup from being blocked by browsers with shorter popup timers
Expand All @@ -226,16 +239,6 @@ export class PopupClient extends StandardInteractionClient {
}

try {
// Create auth code request and generate PKCE params
const authCodeRequest: CommonAuthorizationCodeRequest =
await invokeAsync(
this.initializeAuthorizationCodeRequest.bind(this),
PerformanceEvents.StandardInteractionClientInitializeAuthorizationCodeRequest,
this.logger,
this.performanceClient,
this.correlationId
)(validRequest, pkceCodes);

// Initialize the client
const authClient: AuthorizationCodeClient = await invokeAsync(
this.createAuthCodeClient.bind(this),
Expand Down Expand Up @@ -269,16 +272,19 @@ export class PopupClient extends StandardInteractionClient {
}

// Create acquire token url.
const navigateUrl = await authClient.getAuthCodeUrl({
...validRequest,
platformBroker: isPlatformBroker,
});

// Create popup interaction handler.
const interactionHandler = new InteractionHandler(
authClient,
this.browserStorage,
authCodeRequest,
const navigateUrl = await invokeAsync(
getAuthCodeRequestUrl,
PerformanceEvents.GetAuthCodeUrl,
this.logger,
this.performanceClient,
validRequest.correlationId
)(
this.config,
authClient.authority,
{
...validRequest,
platformBroker: isPlatformBroker,
},
this.logger,
this.performanceClient
);
Expand Down Expand Up @@ -316,7 +322,7 @@ export class PopupClient extends StandardInteractionClient {
ThrottlingUtils.removeThrottle(
this.browserStorage,
this.config.auth.clientId,
authCodeRequest
validRequest
);

if (serverParams.accountId) {
Expand Down Expand Up @@ -361,6 +367,19 @@ export class PopupClient extends StandardInteractionClient {
});
}

const authCodeRequest: CommonAuthorizationCodeRequest = {
...validRequest,
code: serverParams.code || "",
codeVerifier: pkce.verifier,
};
// Create popup interaction handler.
const interactionHandler = new InteractionHandler(
authClient,
this.browserStorage,
authCodeRequest,
this.logger,
this.performanceClient
);
// Handle response from hash string.
const result = await interactionHandler.handleCodeResponse(
serverParams,
Expand Down
63 changes: 41 additions & 22 deletions lib/msal-browser/src/interaction_client/RedirectClient.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ import {
ServerTelemetryManager,
Constants,
ProtocolUtils,
ServerAuthorizationCodeResponse,
AuthorizeResponse,
ThrottlingUtils,
ICrypto,
Logger,
Expand Down Expand Up @@ -48,6 +48,8 @@ import { INavigationClient } from "../navigation/INavigationClient.js";
import { EventError } from "../event/EventMessage.js";
import { AuthenticationResult } from "../response/AuthenticationResult.js";
import * as ResponseHandler from "../response/ResponseHandler.js";
import { getAuthCodeRequestUrl } from "../protocol/Authorize.js";
import { generatePkceCodes } from "../crypto/PkceGenerator.js";

function getNavigationType(): NavigationTimingType | undefined {
if (
Expand Down Expand Up @@ -107,6 +109,15 @@ export class RedirectClient extends StandardInteractionClient {
this.correlationId
)(request, InteractionType.Redirect);

const pkceCodes = await invokeAsync(
generatePkceCodes,
PerformanceEvents.GeneratePkceCodes,
this.logger,
this.performanceClient,
this.correlationId
)(this.performanceClient, this.logger, this.correlationId);
validRequest.codeChallenge = pkceCodes.challenge;

this.browserStorage.updateCacheEntries(
validRequest.state,
validRequest.nonce,
Expand All @@ -133,16 +144,6 @@ export class RedirectClient extends StandardInteractionClient {
};

try {
// Create auth code request and generate PKCE params
const authCodeRequest: CommonAuthorizationCodeRequest =
await invokeAsync(
this.initializeAuthorizationCodeRequest.bind(this),
PerformanceEvents.StandardInteractionClientInitializeAuthorizationCodeRequest,
this.logger,
this.performanceClient,
this.correlationId
)(validRequest);

// Initialize the client
const authClient: AuthorizationCodeClient = await invokeAsync(
this.createAuthCodeClient.bind(this),
Expand All @@ -158,6 +159,11 @@ export class RedirectClient extends StandardInteractionClient {
account: validRequest.account,
});

const authCodeRequest: CommonAuthorizationCodeRequest = {
...validRequest,
code: "", // Will get filled in after the redirect
codeVerifier: pkceCodes.verifier,
};
// Create redirect interaction handler.
const interactionHandler = new RedirectHandler(
authClient,
Expand All @@ -168,15 +174,28 @@ export class RedirectClient extends StandardInteractionClient {
);

// Create acquire token url.
const navigateUrl = await authClient.getAuthCodeUrl({
...validRequest,
platformBroker: NativeMessageHandler.isPlatformBrokerAvailable(
this.config,
this.logger,
this.nativeMessageHandler,
request.authenticationScheme
),
});
const navigateUrl = await invokeAsync(
getAuthCodeRequestUrl,
PerformanceEvents.GetAuthCodeUrl,
this.logger,
this.performanceClient,
validRequest.correlationId
)(
this.config,
authClient.authority,
{
...validRequest,
platformBroker:
NativeMessageHandler.isPlatformBrokerAvailable(
this.config,
this.logger,
this.nativeMessageHandler,
request.authenticationScheme
),
},
this.logger,
this.performanceClient
);

const redirectStartPage = this.getRedirectStartPage(
request.redirectStartPage
Expand Down Expand Up @@ -373,7 +392,7 @@ export class RedirectClient extends StandardInteractionClient {
*/
protected getRedirectResponse(
userProvidedResponse: string
): [ServerAuthorizationCodeResponse | null, string] {
): [AuthorizeResponse | null, string] {
this.logger.verbose("getRedirectResponseHash called");
// Get current location hash from window or cache.
let responseString = userProvidedResponse;
Expand Down Expand Up @@ -439,7 +458,7 @@ export class RedirectClient extends StandardInteractionClient {
* @param state
*/
protected async handleResponse(
serverParams: ServerAuthorizationCodeResponse,
serverParams: AuthorizeResponse,
serverTelemetryManager: ServerTelemetryManager
): Promise<AuthenticationResult> {
const state = serverParams.state;
Expand Down
Loading