Initial commit

This commit is contained in:
2025-03-07 19:22:02 +01:00
commit 4a98255d83
55743 changed files with 5280367 additions and 0 deletions
+42
View File
@@ -0,0 +1,42 @@
import type { AccessToken } from "@azure/core-auth";
import type { AuthenticationRecord } from "../types.js";
import type { CredentialFlowGetTokenOptions } from "../credentials.js";
import type { CredentialLogger } from "../../util/logging.js";
/**
* Union of the constructor parameters that all MSAL flow types take.
* @internal
*/
export interface MsalFlowOptions {
logger: CredentialLogger;
clientId?: string;
tenantId?: string;
authorityHost?: string;
authenticationRecord?: AuthenticationRecord;
disableAutomaticAuthentication?: boolean;
disableInstanceDiscovery?: boolean;
getAssertion?: () => Promise<string>;
enableMsaPassthrough?: boolean;
}
/**
* The common methods we use to work with the MSAL flows.
* @internal
*/
export interface MsalFlow {
/**
* Allows for any setup before any request is processed.
*/
init(options?: CredentialFlowGetTokenOptions): Promise<void>;
/**
* Tries to load the active account, either from memory or from MSAL.
*/
getActiveAccount(): Promise<AuthenticationRecord | undefined>;
/**
* Tries to retrieve the token silently using MSAL.
*/
getTokenSilent(scopes?: string[], options?: CredentialFlowGetTokenOptions): Promise<AccessToken>;
/**
* Calls to the implementation's doGetToken method.
*/
getToken(scopes?: string[], options?: CredentialFlowGetTokenOptions): Promise<AccessToken>;
}
//# sourceMappingURL=flows.d.ts.map
@@ -0,0 +1 @@
{"version":3,"file":"flows.d.ts","sourceRoot":"","sources":["../../../../src/msal/browserFlows/flows.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,kBAAkB,CAAC;AACpD,OAAO,KAAK,EAAE,oBAAoB,EAAE,MAAM,aAAa,CAAC;AACxD,OAAO,KAAK,EAAE,6BAA6B,EAAE,MAAM,mBAAmB,CAAC;AACvE,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,uBAAuB,CAAC;AAE9D;;;GAGG;AACH,MAAM,WAAW,eAAe;IAC9B,MAAM,EAAE,gBAAgB,CAAC;IACzB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,oBAAoB,CAAC,EAAE,oBAAoB,CAAC;IAC5C,8BAA8B,CAAC,EAAE,OAAO,CAAC;IACzC,wBAAwB,CAAC,EAAE,OAAO,CAAC;IACnC,YAAY,CAAC,EAAE,MAAM,OAAO,CAAC,MAAM,CAAC,CAAC;IACrC,oBAAoB,CAAC,EAAE,OAAO,CAAC;CAChC;AAED;;;GAGG;AACH,MAAM,WAAW,QAAQ;IACvB;;OAEG;IACH,IAAI,CAAC,OAAO,CAAC,EAAE,6BAA6B,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IAC7D;;OAEG;IACH,gBAAgB,IAAI,OAAO,CAAC,oBAAoB,GAAG,SAAS,CAAC,CAAC;IAC9D;;OAEG;IACH,cAAc,CAAC,MAAM,CAAC,EAAE,MAAM,EAAE,EAAE,OAAO,CAAC,EAAE,6BAA6B,GAAG,OAAO,CAAC,WAAW,CAAC,CAAC;IACjG;;OAEG;IACH,QAAQ,CAAC,MAAM,CAAC,EAAE,MAAM,EAAE,EAAE,OAAO,CAAC,EAAE,6BAA6B,GAAG,OAAO,CAAC,WAAW,CAAC,CAAC;CAC5F"}
+4
View File
@@ -0,0 +1,4 @@
// Copyright (c) Microsoft Corporation.
// Licensed under the MIT License.
export {};
//# sourceMappingURL=flows.js.map
+1
View File
@@ -0,0 +1 @@
{"version":3,"file":"flows.js","sourceRoot":"","sources":["../../../../src/msal/browserFlows/flows.ts"],"names":[],"mappings":"AAAA,uCAAuC;AACvC,kCAAkC","sourcesContent":["// Copyright (c) Microsoft Corporation.\n// Licensed under the MIT License.\n\nimport type { AccessToken } from \"@azure/core-auth\";\nimport type { AuthenticationRecord } from \"../types.js\";\nimport type { CredentialFlowGetTokenOptions } from \"../credentials.js\";\nimport type { CredentialLogger } from \"../../util/logging.js\";\n\n/**\n * Union of the constructor parameters that all MSAL flow types take.\n * @internal\n */\nexport interface MsalFlowOptions {\n logger: CredentialLogger;\n clientId?: string;\n tenantId?: string;\n authorityHost?: string;\n authenticationRecord?: AuthenticationRecord;\n disableAutomaticAuthentication?: boolean;\n disableInstanceDiscovery?: boolean;\n getAssertion?: () => Promise<string>;\n enableMsaPassthrough?: boolean;\n}\n\n/**\n * The common methods we use to work with the MSAL flows.\n * @internal\n */\nexport interface MsalFlow {\n /**\n * Allows for any setup before any request is processed.\n */\n init(options?: CredentialFlowGetTokenOptions): Promise<void>;\n /**\n * Tries to load the active account, either from memory or from MSAL.\n */\n getActiveAccount(): Promise<AuthenticationRecord | undefined>;\n /**\n * Tries to retrieve the token silently using MSAL.\n */\n getTokenSilent(scopes?: string[], options?: CredentialFlowGetTokenOptions): Promise<AccessToken>;\n /**\n * Calls to the implementation's doGetToken method.\n */\n getToken(scopes?: string[], options?: CredentialFlowGetTokenOptions): Promise<AccessToken>;\n}\n"]}
@@ -0,0 +1,48 @@
import type { MsalBrowserFlowOptions } from "./msalBrowserCommon.js";
import { MsalBrowser } from "./msalBrowserCommon.js";
import type { AccessToken } from "@azure/core-auth";
import type { AuthenticationRecord } from "../types.js";
import type { CredentialFlowGetTokenOptions } from "../credentials.js";
/**
* Uses MSAL Browser 2.X for browser authentication,
* which uses the [Auth Code Flow](https://learn.microsoft.com/en-us/azure/active-directory/develop/v2-oauth2-auth-code-flow).
* @internal
*/
export declare class MSALAuthCode extends MsalBrowser {
private loginHint?;
/**
* Sets up an MSAL object based on the given parameters.
* MSAL with Auth Code allows sending a previously obtained `authenticationRecord` through the optional parameters,
* which is set to be the active account.
* @param options - Parameters necessary and otherwise used to create the MSAL object.
*/
constructor(options: MsalBrowserFlowOptions);
private getApp;
/**
* Loads the account based on the result of the authentication.
* If no result was received, tries to load the account from the cache.
* @param result - Result object received from MSAL.
*/
private handleBrowserResult;
/**
* Uses MSAL to handle the redirect.
*/
handleRedirect(): Promise<AuthenticationRecord | undefined>;
/**
* Uses MSAL to trigger a redirect or a popup login.
*/
login(scopes?: string | string[]): Promise<AuthenticationRecord | undefined>;
/**
* Uses MSAL to retrieve the active account.
*/
getActiveAccount(): Promise<AuthenticationRecord | undefined>;
/**
* Attempts to retrieve a token from cache.
*/
getTokenSilent(scopes: string[], options?: CredentialFlowGetTokenOptions): Promise<AccessToken>;
/**
* Attempts to retrieve the token in the browser.
*/
protected doGetToken(scopes: string[], options?: CredentialFlowGetTokenOptions): Promise<AccessToken>;
}
//# sourceMappingURL=msalAuthCode.d.ts.map
@@ -0,0 +1 @@
{"version":3,"file":"msalAuthCode.d.ts","sourceRoot":"","sources":["../../../../src/msal/browserFlows/msalAuthCode.ts"],"names":[],"mappings":"AAKA,OAAO,KAAK,EAAE,sBAAsB,EAAE,MAAM,wBAAwB,CAAC;AACrE,OAAO,EAAE,WAAW,EAAE,MAAM,wBAAwB,CAAC;AASrD,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,kBAAkB,CAAC;AACpD,OAAO,KAAK,EAAE,oBAAoB,EAAE,MAAM,aAAa,CAAC;AAExD,OAAO,KAAK,EAAE,6BAA6B,EAAE,MAAM,mBAAmB,CAAC;AAMvE;;;;GAIG;AACH,qBAAa,YAAa,SAAQ,WAAW;IAC3C,OAAO,CAAC,SAAS,CAAC,CAAS;IAE3B;;;;;OAKG;gBACS,OAAO,EAAE,sBAAsB;YAuB7B,MAAM;IAgBpB;;;;OAIG;YACW,mBAAmB;IAsDjC;;OAEG;IACU,cAAc,IAAI,OAAO,CAAC,oBAAoB,GAAG,SAAS,CAAC;IAKxE;;OAEG;IACU,KAAK,CAAC,MAAM,GAAE,MAAM,GAAG,MAAM,EAAO,GAAG,OAAO,CAAC,oBAAoB,GAAG,SAAS,CAAC;IAiB7F;;OAEG;IACU,gBAAgB,IAAI,OAAO,CAAC,oBAAoB,GAAG,SAAS,CAAC;IAS1E;;OAEG;IACU,cAAc,CACzB,MAAM,EAAE,MAAM,EAAE,EAChB,OAAO,CAAC,EAAE,6BAA6B,GACtC,OAAO,CAAC,WAAW,CAAC;IA8BvB;;OAEG;cACa,UAAU,CACxB,MAAM,EAAE,MAAM,EAAE,EAChB,OAAO,CAAC,EAAE,6BAA6B,GACtC,OAAO,CAAC,WAAW,CAAC;CAgCxB"}
+203
View File
@@ -0,0 +1,203 @@
// Copyright (c) Microsoft Corporation.
// Licensed under the MIT License.
import * as msalBrowser from "@azure/msal-browser";
import { MsalBrowser } from "./msalBrowserCommon.js";
import { defaultLoggerCallback, getMSALLogLevel, handleMsalError, msalToPublic, publicToMsal, } from "../utils.js";
import { AuthenticationRequiredError } from "../../errors.js";
import { getLogLevel } from "@azure/logger";
// We keep a copy of the redirect hash.
const redirectHash = self.location.hash;
/**
* Uses MSAL Browser 2.X for browser authentication,
* which uses the [Auth Code Flow](https://learn.microsoft.com/en-us/azure/active-directory/develop/v2-oauth2-auth-code-flow).
* @internal
*/
export class MSALAuthCode extends MsalBrowser {
/**
* Sets up an MSAL object based on the given parameters.
* MSAL with Auth Code allows sending a previously obtained `authenticationRecord` through the optional parameters,
* which is set to be the active account.
* @param options - Parameters necessary and otherwise used to create the MSAL object.
*/
constructor(options) {
var _a;
super(options);
this.loginHint = options.loginHint;
this.msalConfig.cache = {
cacheLocation: "sessionStorage",
storeAuthStateInCookie: true, // Set to true to improve the experience on IE11 and Edge.
};
this.msalConfig.system = {
loggerOptions: {
loggerCallback: defaultLoggerCallback(this.logger, "Browser"),
logLevel: getMSALLogLevel(getLogLevel()),
piiLoggingEnabled: (_a = options.loggingOptions) === null || _a === void 0 ? void 0 : _a.enableUnsafeSupportLogging,
},
};
if (options.authenticationRecord) {
this.account = Object.assign(Object.assign({}, options.authenticationRecord), { tenantId: this.tenantId });
}
}
async getApp() {
if (!this.app) {
// Prepare the MSAL application
this.app = await msalBrowser.PublicClientApplication.createPublicClientApplication(this.msalConfig);
// setting the account right after the app is created.
if (this.account) {
this.app.setActiveAccount(publicToMsal(this.account));
}
}
return this.app;
}
/**
* Loads the account based on the result of the authentication.
* If no result was received, tries to load the account from the cache.
* @param result - Result object received from MSAL.
*/
async handleBrowserResult(result) {
try {
const app = await this.getApp();
if (result && result.account) {
this.logger.info(`MSAL Browser V2 authentication successful.`);
app.setActiveAccount(result.account);
return msalToPublic(this.clientId, result.account);
}
// If by this point we happen to have an active account, we should stop trying to parse this.
const activeAccount = await this.app.getActiveAccount();
if (activeAccount) {
return msalToPublic(this.clientId, activeAccount);
}
// If we don't have an active account, we try to activate it from all the already loaded accounts.
const accounts = app.getAllAccounts();
if (accounts.length > 1) {
// If there's more than one account in memory, we force the user to authenticate again.
// At this point we can't identify which account should this credential work with,
// since at this point the user won't have provided enough information.
// We log a message in case that helps.
this.logger.info(`More than one account was found authenticated for this Client ID and Tenant ID.
However, no "authenticationRecord" has been provided for this credential,
therefore we're unable to pick between these accounts.
A new login attempt will be requested, to ensure the correct account is picked.
To work with multiple accounts for the same Client ID and Tenant ID, please provide an "authenticationRecord" when initializing "InteractiveBrowserCredential".`);
// To safely trigger a new login, we're also ensuring the local cache is cleared up for this MSAL object.
// However, we want to avoid kicking the user out of their authentication on the Azure side.
// We do this by calling to logout while specifying a `onRedirectNavigate` that returns false.
await app.logout({
onRedirectNavigate: () => false,
});
return;
}
// If there's only one account for this MSAL object, we can safely activate it.
if (accounts.length === 1) {
const account = accounts[0];
app.setActiveAccount(account);
return msalToPublic(this.clientId, account);
}
this.logger.info(`No accounts were found through MSAL.`);
}
catch (e) {
this.logger.info(`Failed to acquire token through MSAL. ${e.message}`);
}
return;
}
/**
* Uses MSAL to handle the redirect.
*/
async handleRedirect() {
const app = await this.getApp();
return this.handleBrowserResult((await app.handleRedirectPromise(redirectHash)) || undefined);
}
/**
* Uses MSAL to trigger a redirect or a popup login.
*/
async login(scopes = []) {
const arrayScopes = Array.isArray(scopes) ? scopes : [scopes];
const loginRequest = {
scopes: arrayScopes,
loginHint: this.loginHint,
};
const app = await this.getApp();
switch (this.loginStyle) {
case "redirect": {
await app.loginRedirect(loginRequest);
return;
}
case "popup":
return this.handleBrowserResult(await app.loginPopup(loginRequest));
}
}
/**
* Uses MSAL to retrieve the active account.
*/
async getActiveAccount() {
const app = await this.getApp();
const account = app.getActiveAccount();
if (!account) {
return;
}
return msalToPublic(this.clientId, account);
}
/**
* Attempts to retrieve a token from cache.
*/
async getTokenSilent(scopes, options) {
const account = await this.getActiveAccount();
if (!account) {
throw new AuthenticationRequiredError({
scopes,
getTokenOptions: options,
message: "Silent authentication failed. We couldn't retrieve an active account from the cache.",
});
}
const parameters = {
authority: (options === null || options === void 0 ? void 0 : options.authority) || this.msalConfig.auth.authority,
correlationId: options === null || options === void 0 ? void 0 : options.correlationId,
claims: options === null || options === void 0 ? void 0 : options.claims,
account: publicToMsal(account),
forceRefresh: false,
scopes,
};
try {
this.logger.info("Attempting to acquire token silently");
const app = await this.getApp();
const response = await app.acquireTokenSilent(parameters);
return this.handleResult(scopes, response);
}
catch (err) {
throw handleMsalError(scopes, err, options);
}
}
/**
* Attempts to retrieve the token in the browser.
*/
async doGetToken(scopes, options) {
const account = await this.getActiveAccount();
if (!account) {
throw new AuthenticationRequiredError({
scopes,
getTokenOptions: options,
message: "Silent authentication failed. We couldn't retrieve an active account from the cache.",
});
}
const parameters = {
authority: (options === null || options === void 0 ? void 0 : options.authority) || this.msalConfig.auth.authority,
correlationId: options === null || options === void 0 ? void 0 : options.correlationId,
claims: options === null || options === void 0 ? void 0 : options.claims,
account: publicToMsal(account),
loginHint: this.loginHint,
scopes,
};
const app = await this.getApp();
switch (this.loginStyle) {
case "redirect":
// This will go out of the page.
// Once the InteractiveBrowserCredential is initialized again,
// we'll load the MSAL account in the constructor.
await app.acquireTokenRedirect(parameters);
return { token: "", expiresOnTimestamp: 0, tokenType: "Bearer" };
case "popup":
return this.handleResult(scopes, await app.acquireTokenPopup(parameters));
}
}
}
//# sourceMappingURL=msalAuthCode.js.map
File diff suppressed because one or more lines are too long
@@ -0,0 +1,106 @@
import type * as msalBrowser from "@azure/msal-browser";
import type { AccessToken, GetTokenOptions } from "@azure/core-auth";
import type { AuthenticationRecord, MsalResult } from "../types.js";
import type { CredentialLogger } from "../../util/logging.js";
import type { MsalFlow, MsalFlowOptions } from "./flows.js";
import type { BrowserLoginStyle } from "../../credentials/interactiveBrowserCredentialOptions.js";
import type { CredentialFlowGetTokenOptions } from "../credentials.js";
import type { LogPolicyOptions } from "@azure/core-rest-pipeline";
import type { MultiTenantTokenCredentialOptions } from "../../credentials/multiTenantTokenCredentialOptions.js";
/**
* Union of the constructor parameters that all MSAL flow types take.
* Some properties might not be used by some flow types.
*/
export interface MsalBrowserFlowOptions extends MsalFlowOptions {
tokenCredentialOptions: MultiTenantTokenCredentialOptions;
redirectUri?: string;
loginStyle: BrowserLoginStyle;
loginHint?: string;
/**
* Allows users to configure settings for logging policy options, allow logging account information and personally identifiable information for customer support.
*/
loggingOptions?: LogPolicyOptions & {
/**
* Allows logging account information once the authentication flow succeeds.
*/
allowLoggingAccountIdentifiers?: boolean;
/**
* Allows logging personally identifiable information for customer support.
*/
enableUnsafeSupportLogging?: boolean;
};
}
/**
* The common methods we use to work with the MSAL browser flows.
* @internal
*/
export interface MsalBrowserFlow extends MsalFlow {
login(scopes?: string[]): Promise<AuthenticationRecord | undefined>;
handleRedirect(): Promise<AuthenticationRecord | undefined>;
}
/**
* Generates a MSAL configuration that generally works for browsers
* @internal
*/
export declare function defaultBrowserMsalConfig(options: MsalBrowserFlowOptions): msalBrowser.Configuration;
/**
* MSAL partial base client for the browsers.
*
* It completes the input configuration with some default values.
* It also provides with utility protected methods that can be used from any of the clients,
* which includes handlers for successful responses and errors.
*
* @internal
*/
export declare abstract class MsalBrowser implements MsalBrowserFlow {
protected loginStyle: BrowserLoginStyle;
protected clientId: string;
protected tenantId: string;
protected additionallyAllowedTenantIds: string[];
protected authorityHost?: string;
protected account: AuthenticationRecord | undefined;
protected msalConfig: msalBrowser.Configuration;
protected disableAutomaticAuthentication?: boolean;
protected app?: msalBrowser.IPublicClientApplication;
protected logger: CredentialLogger;
constructor(options: MsalBrowserFlowOptions);
/**
* In the browsers we don't need to init()
*/
init(): Promise<void>;
/**
* Attempts to handle a redirection request the least amount of times possible.
*/
abstract handleRedirect(): Promise<AuthenticationRecord | undefined>;
/**
* Clears MSAL's cache.
*/
logout(): Promise<void>;
/**
* Uses MSAL to retrieve the active account.
*/
abstract getActiveAccount(): Promise<AuthenticationRecord | undefined>;
/**
* Uses MSAL to trigger a redirect or a popup login.
*/
abstract login(scopes?: string | string[]): Promise<AuthenticationRecord | undefined>;
/**
* Attempts to retrieve a token from cache.
*/
abstract getTokenSilent(scopes: string[]): Promise<AccessToken>;
/**
* Attempts to retrieve the token in the browser.
*/
protected abstract doGetToken(scopes: string[]): Promise<AccessToken>;
/**
* Attempts to retrieve an authenticated token from MSAL.
*/
getToken(scopes: string[], options?: CredentialFlowGetTokenOptions): Promise<AccessToken>;
/**
* Handles the MSAL authentication result.
* If the result has an account, we update the local account reference.
* If the token received is invalid, an error will be thrown depending on what's missing.
*/
protected handleResult(scopes: string | string[], result?: MsalResult, getTokenOptions?: GetTokenOptions): AccessToken;
}
//# sourceMappingURL=msalBrowserCommon.d.ts.map
@@ -0,0 +1 @@
{"version":3,"file":"msalBrowserCommon.d.ts","sourceRoot":"","sources":["../../../../src/msal/browserFlows/msalBrowserCommon.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,KAAK,WAAW,MAAM,qBAAqB,CAAC;AAExD,OAAO,KAAK,EAAE,WAAW,EAAE,eAAe,EAAE,MAAM,kBAAkB,CAAC;AACrE,OAAO,KAAK,EAAE,oBAAoB,EAAE,UAAU,EAAE,MAAM,aAAa,CAAC;AAEpE,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,uBAAuB,CAAC;AAE9D,OAAO,KAAK,EAAE,QAAQ,EAAE,eAAe,EAAE,MAAM,YAAY,CAAC;AAQ5D,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,0DAA0D,CAAC;AAClG,OAAO,KAAK,EAAE,6BAA6B,EAAE,MAAM,mBAAmB,CAAC;AAEvE,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,2BAA2B,CAAC;AAClE,OAAO,KAAK,EAAE,iCAAiC,EAAE,MAAM,wDAAwD,CAAC;AAEhH;;;GAGG;AACH,MAAM,WAAW,sBAAuB,SAAQ,eAAe;IAC7D,sBAAsB,EAAE,iCAAiC,CAAC;IAC1D,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,UAAU,EAAE,iBAAiB,CAAC;IAC9B,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB;;OAEG;IACH,cAAc,CAAC,EAAE,gBAAgB,GAAG;QAClC;;WAEG;QACH,8BAA8B,CAAC,EAAE,OAAO,CAAC;QACzC;;WAEG;QACH,0BAA0B,CAAC,EAAE,OAAO,CAAC;KACtC,CAAC;CACH;AAED;;;GAGG;AACH,MAAM,WAAW,eAAgB,SAAQ,QAAQ;IAC/C,KAAK,CAAC,MAAM,CAAC,EAAE,MAAM,EAAE,GAAG,OAAO,CAAC,oBAAoB,GAAG,SAAS,CAAC,CAAC;IACpE,cAAc,IAAI,OAAO,CAAC,oBAAoB,GAAG,SAAS,CAAC,CAAC;CAC7D;AAED;;;GAGG;AACH,wBAAgB,wBAAwB,CACtC,OAAO,EAAE,sBAAsB,GAC9B,WAAW,CAAC,aAAa,CAc3B;AAED;;;;;;;;GAQG;AACH,8BAAsB,WAAY,YAAW,eAAe;IAC1D,SAAS,CAAC,UAAU,EAAE,iBAAiB,CAAC;IACxC,SAAS,CAAC,QAAQ,EAAE,MAAM,CAAC;IAC3B,SAAS,CAAC,QAAQ,EAAE,MAAM,CAAC;IAC3B,SAAS,CAAC,4BAA4B,EAAE,MAAM,EAAE,CAAC;IACjD,SAAS,CAAC,aAAa,CAAC,EAAE,MAAM,CAAC;IACjC,SAAS,CAAC,OAAO,EAAE,oBAAoB,GAAG,SAAS,CAAC;IACpD,SAAS,CAAC,UAAU,EAAE,WAAW,CAAC,aAAa,CAAC;IAChD,SAAS,CAAC,8BAA8B,CAAC,EAAE,OAAO,CAAC;IACnD,SAAS,CAAC,GAAG,CAAC,EAAE,WAAW,CAAC,wBAAwB,CAAC;IACrD,SAAS,CAAC,MAAM,EAAE,gBAAgB,CAAC;gBAEvB,OAAO,EAAE,sBAAsB;IAuB3C;;OAEG;IACG,IAAI,IAAI,OAAO,CAAC,IAAI,CAAC;IAI3B;;OAEG;aACa,cAAc,IAAI,OAAO,CAAC,oBAAoB,GAAG,SAAS,CAAC;IAE3E;;OAEG;IACG,MAAM,IAAI,OAAO,CAAC,IAAI,CAAC;IAI7B;;OAEG;aACa,gBAAgB,IAAI,OAAO,CAAC,oBAAoB,GAAG,SAAS,CAAC;IAE7E;;OAEG;aACa,KAAK,CAAC,MAAM,CAAC,EAAE,MAAM,GAAG,MAAM,EAAE,GAAG,OAAO,CAAC,oBAAoB,GAAG,SAAS,CAAC;IAE5F;;OAEG;aACa,cAAc,CAAC,MAAM,EAAE,MAAM,EAAE,GAAG,OAAO,CAAC,WAAW,CAAC;IAEtE;;OAEG;IACH,SAAS,CAAC,QAAQ,CAAC,UAAU,CAAC,MAAM,EAAE,MAAM,EAAE,GAAG,OAAO,CAAC,WAAW,CAAC;IAErE;;OAEG;IACU,QAAQ,CACnB,MAAM,EAAE,MAAM,EAAE,EAChB,OAAO,GAAE,6BAAkC,GAC1C,OAAO,CAAC,WAAW,CAAC;IAkCvB;;;;OAIG;IACH,SAAS,CAAC,YAAY,CACpB,MAAM,EAAE,MAAM,GAAG,MAAM,EAAE,EACzB,MAAM,CAAC,EAAE,UAAU,EACnB,eAAe,CAAC,EAAE,eAAe,GAChC,WAAW;CAaf"}
@@ -0,0 +1,116 @@
// Copyright (c) Microsoft Corporation.
// Licensed under the MIT License.
import { AuthenticationRequiredError, CredentialUnavailableError } from "../../errors.js";
import { formatSuccess } from "../../util/logging.js";
import { ensureValidMsalToken, getAuthority, getKnownAuthorities, msalToPublic } from "../utils.js";
import { processMultiTenantRequest, resolveAdditionallyAllowedTenantIds, resolveTenantId, } from "../../util/tenantIdUtils.js";
import { DefaultTenantId } from "../../constants.js";
/**
* Generates a MSAL configuration that generally works for browsers
* @internal
*/
export function defaultBrowserMsalConfig(options) {
const tenantId = options.tenantId || DefaultTenantId;
const authority = getAuthority(tenantId, options.authorityHost);
return {
auth: {
clientId: options.clientId,
authority,
knownAuthorities: getKnownAuthorities(tenantId, authority, options.disableInstanceDiscovery),
// If the users picked redirect as their login style,
// but they didn't provide a redirectUri,
// we can try to use the current page we're in as a default value.
redirectUri: options.redirectUri || self.location.origin,
},
};
}
/**
* MSAL partial base client for the browsers.
*
* It completes the input configuration with some default values.
* It also provides with utility protected methods that can be used from any of the clients,
* which includes handlers for successful responses and errors.
*
* @internal
*/
export class MsalBrowser {
constructor(options) {
var _a;
this.logger = options.logger;
this.loginStyle = options.loginStyle;
if (!options.clientId) {
throw new CredentialUnavailableError("A client ID is required in browsers");
}
this.clientId = options.clientId;
this.additionallyAllowedTenantIds = resolveAdditionallyAllowedTenantIds((_a = options === null || options === void 0 ? void 0 : options.tokenCredentialOptions) === null || _a === void 0 ? void 0 : _a.additionallyAllowedTenants);
this.tenantId = resolveTenantId(this.logger, options.tenantId, options.clientId);
this.authorityHost = options.authorityHost;
this.msalConfig = defaultBrowserMsalConfig(options);
this.disableAutomaticAuthentication = options.disableAutomaticAuthentication;
if (options.authenticationRecord) {
this.account = Object.assign(Object.assign({}, options.authenticationRecord), { tenantId: this.tenantId });
}
}
/**
* In the browsers we don't need to init()
*/
async init() {
// Nothing to do here.
}
/**
* Clears MSAL's cache.
*/
async logout() {
var _a;
(_a = this.app) === null || _a === void 0 ? void 0 : _a.logout();
}
/**
* Attempts to retrieve an authenticated token from MSAL.
*/
async getToken(scopes, options = {}) {
const tenantId = processMultiTenantRequest(this.tenantId, options, this.additionallyAllowedTenantIds) ||
this.tenantId;
if (!options.authority) {
options.authority = getAuthority(tenantId, this.authorityHost);
}
// We ensure that redirection is handled at this point.
await this.handleRedirect();
if (!(await this.getActiveAccount()) && !this.disableAutomaticAuthentication) {
await this.login(scopes);
}
return this.getTokenSilent(scopes).catch((err) => {
if (err.name !== "AuthenticationRequiredError") {
throw err;
}
if (options === null || options === void 0 ? void 0 : options.disableAutomaticAuthentication) {
throw new AuthenticationRequiredError({
scopes,
getTokenOptions: options,
message: "Automatic authentication has been disabled. You may call the authentication() method.",
});
}
this.logger.info(`Silent authentication failed, falling back to interactive method ${this.loginStyle}`);
return this.doGetToken(scopes);
});
}
/**
* Handles the MSAL authentication result.
* If the result has an account, we update the local account reference.
* If the token received is invalid, an error will be thrown depending on what's missing.
*/
handleResult(scopes, result, getTokenOptions) {
var _a;
if (result === null || result === void 0 ? void 0 : result.account) {
this.account = msalToPublic(this.clientId, result.account);
}
ensureValidMsalToken(scopes, result, getTokenOptions);
this.logger.getToken.info(formatSuccess(scopes));
return {
token: result.accessToken,
expiresOnTimestamp: result.expiresOn.getTime(),
refreshAfterTimestamp: (_a = result.refreshOn) === null || _a === void 0 ? void 0 : _a.getTime(),
tokenType: "Bearer",
};
}
}
//# sourceMappingURL=msalBrowserCommon.js.map
File diff suppressed because one or more lines are too long