Estructura inicial del proyecto

This commit is contained in:
2026-06-02 16:57:08 +00:00
commit 8b306b9afc
9864 changed files with 1435687 additions and 0 deletions

View File

@ -0,0 +1,17 @@
/*
* Copyright (c) Microsoft Corporation. All rights reserved.
* Licensed under the MIT License.
*/
import { PlatformAuthRequest } from "./PlatformAuthRequest.js";
import { PlatformAuthResponse } from "./PlatformAuthResponse.js";
/**
* Interface for the Platform Broker Handlers
*/
export interface IPlatformAuthHandler {
getExtensionId(): string | undefined;
getExtensionVersion(): string | undefined;
getExtensionName(): string | undefined;
sendMessage(request: PlatformAuthRequest): Promise<PlatformAuthResponse>;
}

View File

@ -0,0 +1,14 @@
/*
* Copyright (c) Microsoft Corporation. All rights reserved.
* Licensed under the MIT License.
*/
// Status Codes that can be thrown by WAM
export const USER_INTERACTION_REQUIRED = "USER_INTERACTION_REQUIRED";
export const USER_CANCEL = "USER_CANCEL";
export const NO_NETWORK = "NO_NETWORK";
export const TRANSIENT_ERROR = "TRANSIENT_ERROR";
export const PERSISTENT_ERROR = "PERSISTENT_ERROR";
export const DISABLED = "DISABLED";
export const ACCOUNT_UNAVAILABLE = "ACCOUNT_UNAVAILABLE";
export const UX_NOT_ALLOWED = "UX_NOT_ALLOWED";

View File

@ -0,0 +1,281 @@
/*
* Copyright (c) Microsoft Corporation. All rights reserved.
* Licensed under the MIT License.
*/
import {
Logger,
createAuthError,
AuthErrorCodes,
IPerformanceClient,
StringDict,
} from "@azure/msal-common/browser";
import {
DOMExtraParameters,
PlatformAuthRequest,
PlatformDOMTokenRequest,
} from "./PlatformAuthRequest.js";
import { PlatformAuthConstants } from "../../utils/BrowserConstants.js";
import {
PlatformAuthResponse,
PlatformDOMTokenResponse,
} from "./PlatformAuthResponse.js";
import { createNativeAuthError } from "../../error/NativeAuthError.js";
import { IPlatformAuthHandler } from "./IPlatformAuthHandler.js";
export class PlatformAuthDOMHandler implements IPlatformAuthHandler {
protected logger: Logger;
protected performanceClient: IPerformanceClient;
protected correlationId: string;
platformAuthType: string;
constructor(
logger: Logger,
performanceClient: IPerformanceClient,
correlationId: string
) {
this.logger = logger;
this.performanceClient = performanceClient;
this.correlationId = correlationId;
this.platformAuthType = PlatformAuthConstants.PLATFORM_DOM_PROVIDER;
}
static async createProvider(
logger: Logger,
performanceClient: IPerformanceClient,
correlationId: string
): Promise<PlatformAuthDOMHandler | undefined> {
logger.trace(
"PlatformAuthDOMHandler: createProvider called",
correlationId
);
// @ts-ignore
if (window.navigator?.platformAuthentication) {
const supportedContracts =
// @ts-ignore
await window.navigator.platformAuthentication.getSupportedContracts(
PlatformAuthConstants.MICROSOFT_ENTRA_BROKERID
);
if (
supportedContracts?.includes(
PlatformAuthConstants.PLATFORM_DOM_APIS
)
) {
logger.trace(
"Platform auth api available in DOM",
correlationId
);
return new PlatformAuthDOMHandler(
logger,
performanceClient,
correlationId
);
}
}
return undefined;
}
/**
* Returns the Id for the broker extension this handler is communicating with
* @returns
*/
getExtensionId(): string {
return PlatformAuthConstants.MICROSOFT_ENTRA_BROKERID;
}
getExtensionVersion(): string | undefined {
return "";
}
getExtensionName(): string | undefined {
return PlatformAuthConstants.DOM_API_NAME;
}
/**
* Send token request to platform broker via browser DOM API
* @param request
* @returns
*/
async sendMessage(
request: PlatformAuthRequest
): Promise<PlatformAuthResponse> {
this.logger.trace(
`'${this.platformAuthType}' - Sending request to browser DOM API`,
request.correlationId
);
try {
const platformDOMRequest: PlatformDOMTokenRequest =
this.initializePlatformDOMRequest(request);
const response: object =
// @ts-ignore
await window.navigator.platformAuthentication.executeGetToken(
platformDOMRequest
);
return this.validatePlatformBrokerResponse(
response,
request.correlationId
);
} catch (e) {
this.logger.error(
`'${this.platformAuthType}' - executeGetToken DOM API error`,
request.correlationId
);
throw e;
}
}
private initializePlatformDOMRequest(
request: PlatformAuthRequest
): PlatformDOMTokenRequest {
this.logger.trace(
`'${this.platformAuthType}' - initializeNativeDOMRequest called`,
request.correlationId
);
const {
accountId,
clientId,
authority,
scope,
redirectUri,
correlationId,
state,
storeInCache,
embeddedClientId,
extraParameters,
...remainingProperties
} = request;
const validExtraParameters: DOMExtraParameters = this.getDOMExtraParams(
remainingProperties,
correlationId
);
const platformDOMRequest: PlatformDOMTokenRequest = {
accountId: accountId,
brokerId: this.getExtensionId(),
authority: authority,
clientId: clientId,
correlationId: correlationId || this.correlationId,
extraParameters: {
...extraParameters,
...validExtraParameters,
},
isSecurityTokenService: false,
redirectUri: redirectUri,
scope: scope,
state: state,
storeInCache: storeInCache,
embeddedClientId: embeddedClientId,
};
return platformDOMRequest;
}
private validatePlatformBrokerResponse(
response: object,
correlationId: string
): PlatformAuthResponse {
if (response.hasOwnProperty("isSuccess")) {
if (
response.hasOwnProperty("accessToken") &&
response.hasOwnProperty("idToken") &&
response.hasOwnProperty("clientInfo") &&
response.hasOwnProperty("account") &&
response.hasOwnProperty("scopes") &&
response.hasOwnProperty("expiresIn")
) {
this.logger.trace(
`'${this.platformAuthType}' - platform broker returned successful and valid response`,
correlationId
);
return this.convertToPlatformBrokerResponse(
response as PlatformDOMTokenResponse,
correlationId
);
} else if (response.hasOwnProperty("error")) {
const errorResponse = response as PlatformDOMTokenResponse;
if (
errorResponse.isSuccess === false &&
errorResponse.error &&
errorResponse.error.code
) {
this.logger.trace(
`'${this.platformAuthType}' - platform broker returned error response`,
correlationId
);
throw createNativeAuthError(
errorResponse.error.code,
errorResponse.error.description,
{
error: parseInt(errorResponse.error.errorCode),
protocol_error: errorResponse.error.protocolError,
status: errorResponse.error.status,
properties: errorResponse.error.properties,
}
);
}
}
}
throw createAuthError(
AuthErrorCodes.unexpectedError,
"Response missing expected properties."
);
}
private convertToPlatformBrokerResponse(
response: PlatformDOMTokenResponse,
correlationId: string
): PlatformAuthResponse {
this.logger.trace(
`'${this.platformAuthType}' - convertToNativeResponse called`,
correlationId
);
const nativeResponse: PlatformAuthResponse = {
access_token: response.accessToken,
id_token: response.idToken,
client_info: response.clientInfo,
account: response.account,
expires_in: response.expiresIn,
scope: response.scopes,
state: response.state || "",
properties: response.properties || {},
extendedLifetimeToken: response.extendedLifetimeToken ?? false,
shr: response.proofOfPossessionPayload,
};
return nativeResponse;
}
private getDOMExtraParams(
extraParameters: Record<string, unknown>,
correlationId: string
): DOMExtraParameters {
try {
const stringifiedProperties: StringDict = {};
for (const [key, value] of Object.entries(extraParameters)) {
if (!value) {
continue;
}
if (typeof value === "object") {
stringifiedProperties[key] = JSON.stringify(value);
} else {
stringifiedProperties[key] = String(value);
}
}
return stringifiedProperties;
} catch (e) {
this.logger.error(
`'${this.platformAuthType}' - Error stringifying extra parameters`,
correlationId
);
this.logger.errorPii(
`'${this.platformAuthType}' - Error stringifying extra parameters: '${e}'`,
correlationId
);
return {};
}
}
}

View File

@ -0,0 +1,452 @@
/*
* Copyright (c) Microsoft Corporation. All rights reserved.
* Licensed under the MIT License.
*/
import {
PlatformAuthConstants,
NativeExtensionMethod,
} from "../../utils/BrowserConstants.js";
import {
Logger,
AuthError,
createAuthError,
AuthErrorCodes,
InProgressPerformanceEvent,
IPerformanceClient,
} from "@azure/msal-common/browser";
import * as BrowserPerformanceEvents from "../../telemetry/BrowserPerformanceEvents.js";
import {
NativeExtensionRequest,
NativeExtensionRequestBody,
PlatformAuthRequest,
} from "./PlatformAuthRequest.js";
import { createNativeAuthError } from "../../error/NativeAuthError.js";
import {
createBrowserAuthError,
BrowserAuthErrorCodes,
} from "../../error/BrowserAuthError.js";
import { createNewGuid } from "../../crypto/BrowserCrypto.js";
import { PlatformAuthResponse } from "./PlatformAuthResponse.js";
import { IPlatformAuthHandler } from "./IPlatformAuthHandler.js";
import { createGuid } from "../../utils/BrowserUtils.js";
type ResponseResolvers<T> = {
resolve: (value: T | PromiseLike<T>) => void;
reject: (
value: AuthError | Error | PromiseLike<Error> | PromiseLike<AuthError>
) => void;
};
export class PlatformAuthExtensionHandler implements IPlatformAuthHandler {
private extensionId: string | undefined;
private extensionVersion: string | undefined;
private logger: Logger;
private readonly handshakeTimeoutMs: number;
private timeoutId: number | undefined;
private resolvers: Map<string, ResponseResolvers<object>>;
private handshakeResolvers: Map<string, ResponseResolvers<void>>;
private messageChannel: MessageChannel;
private readonly windowListener: (event: MessageEvent) => void;
private readonly performanceClient: IPerformanceClient;
private readonly handshakeEvent: InProgressPerformanceEvent;
platformAuthType: string;
constructor(
logger: Logger,
handshakeTimeoutMs: number,
performanceClient: IPerformanceClient,
extensionId?: string
) {
this.logger = logger;
this.handshakeTimeoutMs = handshakeTimeoutMs;
this.extensionId = extensionId;
this.resolvers = new Map(); // Used for non-handshake messages
this.handshakeResolvers = new Map(); // Used for handshake messages
this.messageChannel = new MessageChannel();
this.windowListener = this.onWindowMessage.bind(this); // Window event callback doesn't have access to 'this' unless it's bound
this.performanceClient = performanceClient;
this.handshakeEvent = this.performanceClient.startMeasurement(
BrowserPerformanceEvents.NativeMessageHandlerHandshake
);
this.platformAuthType =
PlatformAuthConstants.PLATFORM_EXTENSION_PROVIDER;
}
/**
* Sends a given message to the extension and resolves with the extension response
* @param request
*/
async sendMessage(
request: PlatformAuthRequest
): Promise<PlatformAuthResponse> {
this.logger.trace(
`'${this.platformAuthType}' - sendMessage called.`,
request.correlationId
);
// fall back to native calls
const messageBody: NativeExtensionRequestBody = {
method: NativeExtensionMethod.GetToken,
request: request,
};
const req: NativeExtensionRequest = {
channel: PlatformAuthConstants.CHANNEL_ID,
extensionId: this.extensionId,
responseId: createNewGuid(),
body: messageBody,
};
this.logger.trace(
`'${this.platformAuthType}' - Sending request to browser extension`,
request.correlationId
);
this.logger.tracePii(
`'${
this.platformAuthType
}' - Sending request to browser extension: '${JSON.stringify(
req
)}'`,
request.correlationId
);
this.messageChannel.port1.postMessage(req);
const response: object = await new Promise((resolve, reject) => {
this.resolvers.set(req.responseId, { resolve, reject });
});
const validatedResponse: PlatformAuthResponse =
this.validatePlatformBrokerResponse(response);
return validatedResponse;
}
/**
* Returns an instance of the MessageHandler that has successfully established a connection with an extension
* @param {Logger} logger
* @param {number} handshakeTimeoutMs
* @param {IPerformanceClient} performanceClient
* @param {ICrypto} crypto
*/
static async createProvider(
logger: Logger,
handshakeTimeoutMs: number,
performanceClient: IPerformanceClient,
correlationId: string
): Promise<PlatformAuthExtensionHandler> {
logger.trace(
"PlatformAuthExtensionHandler - createProvider called.",
correlationId
);
try {
const preferredProvider = new PlatformAuthExtensionHandler(
logger,
handshakeTimeoutMs,
performanceClient,
PlatformAuthConstants.PREFERRED_EXTENSION_ID
);
await preferredProvider.sendHandshakeRequest(correlationId);
return preferredProvider;
} catch (e) {
// If preferred extension fails for whatever reason, fallback to using any installed extension
const backupProvider = new PlatformAuthExtensionHandler(
logger,
handshakeTimeoutMs,
performanceClient
);
await backupProvider.sendHandshakeRequest(correlationId);
return backupProvider;
}
}
/**
* Send handshake request helper.
*/
private async sendHandshakeRequest(correlationId: string): Promise<void> {
this.logger.trace(
`'${this.platformAuthType}' - sendHandshakeRequest called.`,
correlationId
);
// Register this event listener before sending handshake
window.addEventListener("message", this.windowListener, false); // false is important, because content script message processing should work first
const req: NativeExtensionRequest = {
channel: PlatformAuthConstants.CHANNEL_ID,
extensionId: this.extensionId,
responseId: createNewGuid(),
body: {
method: NativeExtensionMethod.HandshakeRequest,
},
};
this.handshakeEvent.add({
extensionId: this.extensionId,
extensionHandshakeTimeoutMs: this.handshakeTimeoutMs,
});
this.messageChannel.port1.onmessage = (event) => {
this.onChannelMessage(event);
};
window.postMessage(req, window.origin, [this.messageChannel.port2]);
return new Promise((resolve, reject) => {
this.handshakeResolvers.set(req.responseId, { resolve, reject });
this.timeoutId = window.setTimeout(() => {
/*
* Throw an error if neither HandshakeResponse nor original Handshake request are received in a reasonable timeframe.
* This typically suggests an event handler stopped propagation of the Handshake request but did not respond to it on the MessageChannel port
*/
window.removeEventListener(
"message",
this.windowListener,
false
);
this.messageChannel.port1.close();
this.messageChannel.port2.close();
this.handshakeEvent.end({
extensionHandshakeTimedOut: true,
success: false,
});
reject(
createBrowserAuthError(
BrowserAuthErrorCodes.nativeHandshakeTimeout
)
);
this.handshakeResolvers.delete(req.responseId);
}, this.handshakeTimeoutMs); // Use a reasonable timeout in milliseconds here
});
}
/**
* Invoked when a message is posted to the window. If a handshake request is received it means the extension is not installed.
* @param event
*/
private onWindowMessage(event: MessageEvent): void {
const correlationId = createGuid();
this.logger.trace(
`'${this.platformAuthType}' - onWindowMessage called`,
correlationId
);
// We only accept messages from ourselves
if (event.source !== window) {
return;
}
const request = event.data;
if (
!request.channel ||
request.channel !== PlatformAuthConstants.CHANNEL_ID
) {
return;
}
if (request.extensionId && request.extensionId !== this.extensionId) {
return;
}
if (request.body.method === NativeExtensionMethod.HandshakeRequest) {
const handshakeResolver = this.handshakeResolvers.get(
request.responseId
);
/*
* Filter out responses with no matched resolvers sooner to keep channel ports open while waiting for
* the proper response.
*/
if (!handshakeResolver) {
this.logger.trace(
`'${this.platformAuthType}'.onWindowMessage - resolver can't be found for request '${request.responseId}'`,
correlationId
);
return;
}
// If we receive this message back it means no extension intercepted the request, meaning no extension supporting handshake protocol is installed
this.logger.verbose(
request.extensionId
? `Extension with id: ${request.extensionId} not installed`
: "No extension installed",
correlationId
);
clearTimeout(this.timeoutId);
this.messageChannel.port1.close();
this.messageChannel.port2.close();
window.removeEventListener("message", this.windowListener, false);
this.handshakeEvent.end({
success: false,
extensionInstalled: false,
});
handshakeResolver.reject(
createBrowserAuthError(
BrowserAuthErrorCodes.nativeExtensionNotInstalled
)
);
}
}
/**
* Invoked when a message is received from the extension on the MessageChannel port
* @param event
*/
private onChannelMessage(event: MessageEvent): void {
const correlationId = createGuid();
this.logger.trace(
`'${this.platformAuthType}' - onChannelMessage called.`,
correlationId
);
const request = event.data;
const resolver = this.resolvers.get(request.responseId);
const handshakeResolver = this.handshakeResolvers.get(
request.responseId
);
try {
const method = request.body.method;
if (method === NativeExtensionMethod.Response) {
if (!resolver) {
return;
}
const response = request.body.response;
this.logger.trace(
`'${this.platformAuthType}' - Received response from browser extension`,
correlationId
);
this.logger.tracePii(
`'${
this.platformAuthType
}' - Received response from browser extension: '${JSON.stringify(
response
)}'`,
correlationId
);
if (response.status !== "Success") {
resolver.reject(
createNativeAuthError(
response.code,
response.description,
response.ext
)
);
} else if (response.result) {
if (
response.result["code"] &&
response.result["description"]
) {
resolver.reject(
createNativeAuthError(
response.result["code"],
response.result["description"],
response.result["ext"]
)
);
} else {
resolver.resolve(response.result);
}
} else {
throw createAuthError(
AuthErrorCodes.unexpectedError,
"Event does not contain result."
);
}
this.resolvers.delete(request.responseId);
} else if (method === NativeExtensionMethod.HandshakeResponse) {
if (!handshakeResolver) {
this.logger.trace(
`'${this.platformAuthType}'.onChannelMessage - resolver can't be found for request '${request.responseId}'`,
correlationId
);
return;
}
clearTimeout(this.timeoutId); // Clear setTimeout
window.removeEventListener(
"message",
this.windowListener,
false
); // Remove 'No extension' listener
this.extensionId = request.extensionId;
this.extensionVersion = request.body.version;
this.logger.verbose(
`'${this.platformAuthType}' - Received HandshakeResponse from extension: '${this.extensionId}'`,
correlationId
);
this.handshakeEvent.end({
extensionInstalled: true,
success: true,
});
handshakeResolver.resolve();
this.handshakeResolvers.delete(request.responseId);
}
// Do nothing if method is not Response or HandshakeResponse
} catch (err) {
this.logger.error(
"Error parsing response from WAM Extension",
correlationId
);
this.logger.errorPii(
`Error parsing response from WAM Extension: '${err as string}'`,
correlationId
);
this.logger.errorPii(`Unable to parse '${event}'`, correlationId);
if (resolver) {
resolver.reject(err as AuthError);
} else if (handshakeResolver) {
handshakeResolver.reject(err as AuthError);
}
}
}
/**
* Validates native platform response before processing
* @param response
*/
private validatePlatformBrokerResponse(
response: object
): PlatformAuthResponse {
if (
response.hasOwnProperty("access_token") &&
response.hasOwnProperty("id_token") &&
response.hasOwnProperty("client_info") &&
response.hasOwnProperty("account") &&
response.hasOwnProperty("scope") &&
response.hasOwnProperty("expires_in")
) {
return response as PlatformAuthResponse;
} else {
throw createAuthError(
AuthErrorCodes.unexpectedError,
"Response missing expected properties."
);
}
}
/**
* Returns the Id for the browser extension this handler is communicating with
* @returns
*/
getExtensionId(): string | undefined {
return this.extensionId;
}
/**
* Returns the version for the browser extension this handler is communicating with
* @returns
*/
getExtensionVersion(): string | undefined {
return this.extensionVersion;
}
getExtensionName(): string | undefined {
return this.getExtensionId() ===
PlatformAuthConstants.PREFERRED_EXTENSION_ID
? "chrome"
: this.getExtensionId()?.length
? "unknown"
: undefined;
}
}

View File

@ -0,0 +1,171 @@
/*
* Copyright (c) Microsoft Corporation. All rights reserved.
* Licensed under the MIT License.
*/
import {
LoggerOptions,
IPerformanceClient,
Logger,
Constants,
StubPerformanceClient,
createClientConfigurationError,
ClientConfigurationErrorCodes,
} from "@azure/msal-common/browser";
import { name, version } from "../../packageMetadata.js";
import {
BrowserConfiguration,
DEFAULT_NATIVE_BROKER_HANDSHAKE_TIMEOUT_MS,
} from "../../config/Configuration.js";
import { PlatformAuthExtensionHandler } from "./PlatformAuthExtensionHandler.js";
import { IPlatformAuthHandler } from "./IPlatformAuthHandler.js";
import { PlatformAuthDOMHandler } from "./PlatformAuthDOMHandler.js";
import { createNewGuid } from "../../crypto/BrowserCrypto.js";
/**
* Checks if the platform broker is available in the current environment.
* @param domConfig - Whether to enable platform broker DOM API support (required)
* @param loggerOptions - Optional logger options
* @param perfClient - Optional performance client
* @param correlationId - Optional correlation ID
* @returns Promise<boolean> indicating if platform broker is available
*/
export async function isPlatformBrokerAvailable(
domConfig: boolean,
loggerOptions?: LoggerOptions,
perfClient?: IPerformanceClient,
correlationId?: string
): Promise<boolean> {
const logger = new Logger(loggerOptions || {}, name, version);
const performanceClient = perfClient || new StubPerformanceClient();
if (typeof window === "undefined") {
logger.trace(
"Non-browser environment detected, returning false",
correlationId || createNewGuid()
);
return false;
}
return !!(await getPlatformAuthProvider(
logger,
performanceClient,
correlationId || createNewGuid(),
undefined,
domConfig
));
}
export async function getPlatformAuthProvider(
logger: Logger,
performanceClient: IPerformanceClient,
correlationId: string,
nativeBrokerHandshakeTimeout?: number,
enablePlatformBrokerDOMSupport?: boolean
): Promise<IPlatformAuthHandler | undefined> {
logger.trace("getPlatformAuthProvider called", correlationId);
logger.trace(
`Has client allowed platform auth via DOM API: '${enablePlatformBrokerDOMSupport}'`,
correlationId
);
let platformAuthProvider: IPlatformAuthHandler | undefined;
try {
if (enablePlatformBrokerDOMSupport) {
// Check if DOM platform API is supported first
platformAuthProvider = await PlatformAuthDOMHandler.createProvider(
logger,
performanceClient,
correlationId
);
}
if (!platformAuthProvider) {
logger.trace(
"Platform auth via DOM API not available, checking for extension",
correlationId
);
/*
* If DOM APIs are not available, check if browser extension is available.
* Platform authentication via DOM APIs is preferred over extension APIs.
*/
platformAuthProvider =
await PlatformAuthExtensionHandler.createProvider(
logger,
nativeBrokerHandshakeTimeout ||
DEFAULT_NATIVE_BROKER_HANDSHAKE_TIMEOUT_MS,
performanceClient,
correlationId
);
}
} catch (e) {
logger.trace("Platform auth not available", e as string);
}
return platformAuthProvider;
}
/**
* Returns boolean indicating whether or not the request should attempt to use platform broker
* @param logger
* @param config
* @param correlationId
* @param platformAuthProvider
* @param authenticationScheme
*/
export function isPlatformAuthAllowed(
config: BrowserConfiguration,
logger: Logger,
correlationId: string,
platformAuthProvider?: IPlatformAuthHandler,
authenticationScheme?: Constants.AuthenticationScheme
): boolean {
logger.trace("isPlatformAuthAllowed called", correlationId);
// throw an error if allowPlatformBroker is not enabled and allowPlatformBrokerWithDOM is enabled
if (
!config.system.allowPlatformBroker &&
config.experimental.allowPlatformBrokerWithDOM
) {
throw createClientConfigurationError(
ClientConfigurationErrorCodes.invalidPlatformBrokerConfiguration
);
}
if (!config.system.allowPlatformBroker) {
logger.trace(
"isPlatformAuthAllowed: allowPlatformBroker is not enabled, returning false",
correlationId
);
// Developer disabled WAM
return false;
}
if (!platformAuthProvider) {
logger.trace(
"isPlatformAuthAllowed: Platform auth provider is not initialized, returning false",
correlationId
);
// Platform broker auth providers are not available
return false;
}
if (authenticationScheme) {
switch (authenticationScheme) {
case Constants.AuthenticationScheme.BEARER:
case Constants.AuthenticationScheme.POP:
logger.trace(
"isPlatformAuthAllowed: authenticationScheme is supported, returning true",
correlationId
);
return true;
default:
logger.trace(
"isPlatformAuthAllowed: authenticationScheme is not supported, returning false",
correlationId
);
return false;
}
}
return true;
}

View File

@ -0,0 +1,94 @@
/*
* Copyright (c) Microsoft Corporation. All rights reserved.
* Licensed under the MIT License.
*/
import { NativeExtensionMethod } from "../../utils/BrowserConstants.js";
import { StoreInCache, StringDict } from "@azure/msal-common/browser";
/**
* Token request which native broker will use to acquire tokens
*/
export type PlatformAuthRequest = {
accountId: string; // WAM specific account id used for identification of WAM account. This can be any broker-id eventually
clientId: string;
authority: string;
redirectUri: string;
scope: string;
correlationId: string;
windowTitleSubstring: string; // The name of the document title. This helps the native prompt properly "parent" to the window making the request
prompt?: string;
nonce?: string;
claims?: string;
state?: string;
reqCnf?: string;
keyId?: string;
tokenType?: string;
shrClaims?: string;
shrNonce?: string;
resourceRequestMethod?: string;
resourceRequestUri?: string;
extendedExpiryToken?: boolean;
resource?: string;
extraParameters?: StringDict;
storeInCache?: StoreInCache; // Object of booleans indicating whether to store tokens in the cache or not (default is true)
signPopToken?: boolean; // Set to true only if token request deos not contain a PoP keyId
embeddedClientId?: string;
};
/**
* Request which will be forwarded to native broker by the browser extension
*/
export type NativeExtensionRequestBody = {
method: NativeExtensionMethod;
request?: PlatformAuthRequest;
};
/**
* Browser extension request
*/
export type NativeExtensionRequest = {
channel: string;
responseId: string;
extensionId?: string;
body: NativeExtensionRequestBody;
};
export type PlatformDOMTokenRequest = {
brokerId: string;
accountId?: string;
clientId: string;
authority: string;
scope: string;
redirectUri: string;
correlationId: string;
isSecurityTokenService: boolean;
state?: string;
/*
* Known optional parameters will go into extraQueryParameters.
* List of known parameters is:
* "prompt", "nonce", "claims", "loginHint", "instanceAware", "windowTitleSubstring", "extendedExpiryToken", "storeInCache",
* ProofOfPossessionParams: "reqCnf", "keyId", "tokenType", "shrClaims", "shrNonce", "resourceRequestMethod", "resourceRequestUri", "signPopToken"
*/
extraParameters?: DOMExtraParameters;
embeddedClientId?: string;
storeInCache?: StoreInCache; // Object of booleans indicating whether to store tokens in the cache or not (default is true)
};
export type DOMExtraParameters = StringDict & {
prompt?: string;
nonce?: string;
claims?: string;
loginHint?: string;
instanceAware?: string;
windowTitleSubstring?: string;
extendedExpiryToken?: string;
reqCnf?: string;
keyId?: string;
tokenType?: string;
shrClaims?: string;
shrNonce?: string;
resourceRequestMethod?: string;
resourceRequestUri?: string;
signPopToken?: string; // Set to true only if token request deos not contain a PoP keyId
};

View File

@ -0,0 +1,80 @@
/*
* Copyright (c) Microsoft Corporation. All rights reserved.
* Licensed under the MIT License.
*/
/**
* Account properties returned by Native Platform e.g. WAM
*/
export type NativeAccountInfo = {
id: string;
properties: object;
userName: string;
};
/**
* Token response returned by Native Platform
*/
export type PlatformAuthResponse = {
access_token: string;
account: NativeAccountInfo;
client_info: string;
expires_in: number;
id_token: string;
properties: NativeResponseProperties;
scope: string;
state: string;
shr?: string;
extendedLifetimeToken?: boolean;
};
/**
* Properties returned under "properties" of the NativeResponse
*/
export type NativeResponseProperties = {
MATS?: string;
};
/**
* The native token broker can optionally include additional information about operations it performs. If that data is returned, MSAL.js will include the following properties in the telemetry it collects.
*/
export type MATS = {
is_cached?: number;
broker_version?: string;
account_join_on_start?: string;
account_join_on_end?: string;
device_join?: string;
prompt_behavior?: string;
api_error_code?: number;
ui_visible?: boolean;
silent_code?: number;
silent_bi_sub_code?: number;
silent_message?: string;
silent_status?: number;
http_status?: number;
http_event_count?: number;
};
export type PlatformDOMTokenResponse = {
isSuccess: boolean;
state?: string;
accessToken: string;
expiresIn: number;
account: NativeAccountInfo;
clientInfo: string;
idToken: string;
scopes: string;
proofOfPossessionPayload?: string;
extendedLifetimeToken?: boolean;
error: ErrorResult;
properties?: Record<string, string>;
};
export type ErrorResult = {
code: string;
description?: string;
errorCode: string;
protocolError?: string;
status: string;
properties?: object;
};