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
@@ -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"}
@@ -0,0 +1,5 @@
"use strict";
// Copyright (c) Microsoft Corporation.
// Licensed under the MIT License.
Object.defineProperty(exports, "__esModule", { value: true });
//# sourceMappingURL=flows.js.map
@@ -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"}
@@ -0,0 +1,208 @@
"use strict";
// Copyright (c) Microsoft Corporation.
// Licensed under the MIT License.
Object.defineProperty(exports, "__esModule", { value: true });
exports.MSALAuthCode = void 0;
const tslib_1 = require("tslib");
const msalBrowser = tslib_1.__importStar(require("@azure/msal-browser"));
const msalBrowserCommon_js_1 = require("./msalBrowserCommon.js");
const utils_js_1 = require("../utils.js");
const errors_js_1 = require("../../errors.js");
const logger_1 = require("@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
*/
class MSALAuthCode extends msalBrowserCommon_js_1.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: (0, utils_js_1.defaultLoggerCallback)(this.logger, "Browser"),
logLevel: (0, utils_js_1.getMSALLogLevel)((0, logger_1.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((0, utils_js_1.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 (0, utils_js_1.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 (0, utils_js_1.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 (0, utils_js_1.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 (0, utils_js_1.msalToPublic)(this.clientId, account);
}
/**
* Attempts to retrieve a token from cache.
*/
async getTokenSilent(scopes, options) {
const account = await this.getActiveAccount();
if (!account) {
throw new errors_js_1.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: (0, utils_js_1.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 (0, utils_js_1.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 errors_js_1.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: (0, utils_js_1.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));
}
}
}
exports.MSALAuthCode = MSALAuthCode;
//# 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":"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"}
@@ -0,0 +1,121 @@
"use strict";
// Copyright (c) Microsoft Corporation.
// Licensed under the MIT License.
Object.defineProperty(exports, "__esModule", { value: true });
exports.MsalBrowser = void 0;
exports.defaultBrowserMsalConfig = defaultBrowserMsalConfig;
const errors_js_1 = require("../../errors.js");
const logging_js_1 = require("../../util/logging.js");
const utils_js_1 = require("../utils.js");
const tenantIdUtils_js_1 = require("../../util/tenantIdUtils.js");
const constants_js_1 = require("../../constants.js");
/**
* Generates a MSAL configuration that generally works for browsers
* @internal
*/
function defaultBrowserMsalConfig(options) {
const tenantId = options.tenantId || constants_js_1.DefaultTenantId;
const authority = (0, utils_js_1.getAuthority)(tenantId, options.authorityHost);
return {
auth: {
clientId: options.clientId,
authority,
knownAuthorities: (0, utils_js_1.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
*/
class MsalBrowser {
constructor(options) {
var _a;
this.logger = options.logger;
this.loginStyle = options.loginStyle;
if (!options.clientId) {
throw new errors_js_1.CredentialUnavailableError("A client ID is required in browsers");
}
this.clientId = options.clientId;
this.additionallyAllowedTenantIds = (0, tenantIdUtils_js_1.resolveAdditionallyAllowedTenantIds)((_a = options === null || options === void 0 ? void 0 : options.tokenCredentialOptions) === null || _a === void 0 ? void 0 : _a.additionallyAllowedTenants);
this.tenantId = (0, tenantIdUtils_js_1.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 = (0, tenantIdUtils_js_1.processMultiTenantRequest)(this.tenantId, options, this.additionallyAllowedTenantIds) ||
this.tenantId;
if (!options.authority) {
options.authority = (0, utils_js_1.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 errors_js_1.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 = (0, utils_js_1.msalToPublic)(this.clientId, result.account);
}
(0, utils_js_1.ensureValidMsalToken)(scopes, result, getTokenOptions);
this.logger.getToken.info((0, logging_js_1.formatSuccess)(scopes));
return {
token: result.accessToken,
expiresOnTimestamp: result.expiresOn.getTime(),
refreshAfterTimestamp: (_a = result.refreshOn) === null || _a === void 0 ? void 0 : _a.getTime(),
tokenType: "Bearer",
};
}
}
exports.MsalBrowser = MsalBrowser;
//# sourceMappingURL=msalBrowserCommon.js.map
File diff suppressed because one or more lines are too long
+52
View File
@@ -0,0 +1,52 @@
import type { AccessToken, GetTokenOptions } from "@azure/core-auth";
import type { AuthenticationRecord } from "./types.js";
/**
* The MSAL clients `getToken` requests can receive a `correlationId` and `disableAutomaticAuthentication`.
* (which is used to prevent `getToken` from triggering the manual authentication if `getTokenSilent` fails).
* @internal
*/
export interface CredentialFlowGetTokenOptions extends GetTokenOptions {
/**
* Unique identifier useful to track outgoing requests.
*/
correlationId?: string;
/**
* Makes getToken throw if a manual authentication is necessary.
*/
disableAutomaticAuthentication?: boolean;
/**
* Authority, to overwrite the default one, if necessary.
*/
authority?: string;
/**
* Claims received from challenges.
*/
claims?: string;
/**
* Indicates to allow Continuous Access Evaluation or not
*/
enableCae?: boolean;
/**
* Client Assertion
*/
getAssertion?: () => Promise<string>;
}
/**
* Simplified representation of the internal authentication flow.
* @internal
*/
export interface CredentialFlow {
/**
* Clears the MSAL cache.
*/
logout(): Promise<void>;
/**
* Tries to load the active account, either from memory or from MSAL.
*/
getActiveAccount(): Promise<AuthenticationRecord | undefined>;
/**
* Calls to the implementation's doGetToken method.
*/
getToken(scopes?: string[], options?: CredentialFlowGetTokenOptions): Promise<AccessToken | null>;
}
//# sourceMappingURL=credentials.d.ts.map
+1
View File
@@ -0,0 +1 @@
{"version":3,"file":"credentials.d.ts","sourceRoot":"","sources":["../../../src/msal/credentials.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,WAAW,EAAE,eAAe,EAAE,MAAM,kBAAkB,CAAC;AACrE,OAAO,KAAK,EAAE,oBAAoB,EAAE,MAAM,YAAY,CAAC;AAEvD;;;;GAIG;AACH,MAAM,WAAW,6BAA8B,SAAQ,eAAe;IACpE;;OAEG;IACH,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB;;OAEG;IACH,8BAA8B,CAAC,EAAE,OAAO,CAAC;IACzC;;OAEG;IACH,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB;;OAEG;IACH,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB;;OAEG;IACH,SAAS,CAAC,EAAE,OAAO,CAAC;IACpB;;OAEG;IACH,YAAY,CAAC,EAAE,MAAM,OAAO,CAAC,MAAM,CAAC,CAAC;CACtC;AAED;;;GAGG;AACH,MAAM,WAAW,cAAc;IAC7B;;OAEG;IACH,MAAM,IAAI,OAAO,CAAC,IAAI,CAAC,CAAC;IACxB;;OAEG;IACH,gBAAgB,IAAI,OAAO,CAAC,oBAAoB,GAAG,SAAS,CAAC,CAAC;IAC9D;;OAEG;IACH,QAAQ,CAAC,MAAM,CAAC,EAAE,MAAM,EAAE,EAAE,OAAO,CAAC,EAAE,6BAA6B,GAAG,OAAO,CAAC,WAAW,GAAG,IAAI,CAAC,CAAC;CACnG"}
+5
View File
@@ -0,0 +1,5 @@
"use strict";
// Copyright (c) Microsoft Corporation.
// Licensed under the MIT License.
Object.defineProperty(exports, "__esModule", { value: true });
//# sourceMappingURL=credentials.js.map
+1
View File
@@ -0,0 +1 @@
{"version":3,"file":"credentials.js","sourceRoot":"","sources":["../../../src/msal/credentials.ts"],"names":[],"mappings":";AAAA,uCAAuC;AACvC,kCAAkC","sourcesContent":["// Copyright (c) Microsoft Corporation.\n// Licensed under the MIT License.\n\nimport type { AccessToken, GetTokenOptions } from \"@azure/core-auth\";\nimport type { AuthenticationRecord } from \"./types.js\";\n\n/**\n * The MSAL clients `getToken` requests can receive a `correlationId` and `disableAutomaticAuthentication`.\n * (which is used to prevent `getToken` from triggering the manual authentication if `getTokenSilent` fails).\n * @internal\n */\nexport interface CredentialFlowGetTokenOptions extends GetTokenOptions {\n /**\n * Unique identifier useful to track outgoing requests.\n */\n correlationId?: string;\n /**\n * Makes getToken throw if a manual authentication is necessary.\n */\n disableAutomaticAuthentication?: boolean;\n /**\n * Authority, to overwrite the default one, if necessary.\n */\n authority?: string;\n /**\n * Claims received from challenges.\n */\n claims?: string;\n /**\n * Indicates to allow Continuous Access Evaluation or not\n */\n enableCae?: boolean;\n /**\n * Client Assertion\n */\n getAssertion?: () => Promise<string>;\n}\n\n/**\n * Simplified representation of the internal authentication flow.\n * @internal\n */\nexport interface CredentialFlow {\n /**\n * Clears the MSAL cache.\n */\n logout(): Promise<void>;\n /**\n * Tries to load the active account, either from memory or from MSAL.\n */\n getActiveAccount(): Promise<AuthenticationRecord | undefined>;\n /**\n * Calls to the implementation's doGetToken method.\n */\n getToken(scopes?: string[], options?: CredentialFlowGetTokenOptions): Promise<AccessToken | null>;\n}\n"]}
+3
View File
@@ -0,0 +1,3 @@
import * as msalCommon from "@azure/msal-node";
export { msalCommon };
//# sourceMappingURL=msal.d.ts.map
+1
View File
@@ -0,0 +1 @@
{"version":3,"file":"msal.d.ts","sourceRoot":"","sources":["../../../src/msal/msal.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,UAAU,MAAM,kBAAkB,CAAC;AAE/C,OAAO,EAAE,UAAU,EAAE,CAAC"}
+9
View File
@@ -0,0 +1,9 @@
"use strict";
// Copyright (c) Microsoft Corporation.
// Licensed under the MIT License.
Object.defineProperty(exports, "__esModule", { value: true });
exports.msalCommon = void 0;
const tslib_1 = require("tslib");
const msalCommon = tslib_1.__importStar(require("@azure/msal-node"));
exports.msalCommon = msalCommon;
//# sourceMappingURL=msal.js.map
+1
View File
@@ -0,0 +1 @@
{"version":3,"file":"msal.js","sourceRoot":"","sources":["../../../src/msal/msal.ts"],"names":[],"mappings":";AAAA,uCAAuC;AACvC,kCAAkC;;;;AAElC,qEAA+C;AAEtC,gCAAU","sourcesContent":["// Copyright (c) Microsoft Corporation.\n// Licensed under the MIT License.\n\nimport * as msalCommon from \"@azure/msal-node\";\n\nexport { msalCommon };\n"]}
@@ -0,0 +1,44 @@
/**
* Parameters that enable WAM broker authentication in the InteractiveBrowserCredential.
*/
export type BrokerOptions = BrokerEnabledOptions | BrokerDisabledOptions;
/**
* Parameters when WAM broker authentication is disabled.
*/
export interface BrokerDisabledOptions {
/**
* If set to true, broker will be enabled for WAM support on Windows.
*/
enabled: false;
/**
* If set to true, MSA account will be passed through, required for WAM authentication.
*/
legacyEnableMsaPassthrough?: undefined;
/**
* Window handle for parent window, required for WAM authentication.
*/
parentWindowHandle: undefined;
}
/**
* Parameters when WAM broker authentication is enabled.
*/
export interface BrokerEnabledOptions {
/**
* If set to true, broker will be enabled for WAM support on Windows.
*/
enabled: true;
/**
* If set to true, MSA account will be passed through, required for WAM authentication.
*/
legacyEnableMsaPassthrough?: boolean;
/**
* Window handle for parent window, required for WAM authentication.
*/
parentWindowHandle: Uint8Array;
/**
* If set to true, the credential will attempt to use the default broker account for authentication before falling back to interactive authentication.
* Default is set to false.
*/
useDefaultBrokerAccount?: boolean;
}
//# sourceMappingURL=brokerOptions.d.ts.map
@@ -0,0 +1 @@
{"version":3,"file":"brokerOptions.d.ts","sourceRoot":"","sources":["../../../../src/msal/nodeFlows/brokerOptions.ts"],"names":[],"mappings":"AAEA;;GAEG;AACH,MAAM,MAAM,aAAa,GAAG,oBAAoB,GAAG,qBAAqB,CAAC;AAEzE;;GAEG;AACH,MAAM,WAAW,qBAAqB;IACpC;;OAEG;IACH,OAAO,EAAE,KAAK,CAAC;IAEf;;OAEG;IACH,0BAA0B,CAAC,EAAE,SAAS,CAAC;IACvC;;OAEG;IACH,kBAAkB,EAAE,SAAS,CAAC;CAC/B;AAED;;GAEG;AACH,MAAM,WAAW,oBAAoB;IACnC;;OAEG;IACH,OAAO,EAAE,IAAI,CAAC;IACd;;OAEG;IACH,0BAA0B,CAAC,EAAE,OAAO,CAAC;IACrC;;OAEG;IACH,kBAAkB,EAAE,UAAU,CAAC;IAE/B;;;OAGG;IACH,uBAAuB,CAAC,EAAE,OAAO,CAAC;CACnC"}
@@ -0,0 +1,3 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
//# sourceMappingURL=brokerOptions.js.map
@@ -0,0 +1 @@
{"version":3,"file":"brokerOptions.js","sourceRoot":"","sources":["../../../../src/msal/nodeFlows/brokerOptions.ts"],"names":[],"mappings":"","sourcesContent":["// Copyright (c) Microsoft Corporation.\n// Licensed under the MIT License.\n/**\n * Parameters that enable WAM broker authentication in the InteractiveBrowserCredential.\n */\nexport type BrokerOptions = BrokerEnabledOptions | BrokerDisabledOptions;\n\n/**\n * Parameters when WAM broker authentication is disabled.\n */\nexport interface BrokerDisabledOptions {\n /**\n * If set to true, broker will be enabled for WAM support on Windows.\n */\n enabled: false;\n\n /**\n * If set to true, MSA account will be passed through, required for WAM authentication.\n */\n legacyEnableMsaPassthrough?: undefined;\n /**\n * Window handle for parent window, required for WAM authentication.\n */\n parentWindowHandle: undefined;\n}\n\n/**\n * Parameters when WAM broker authentication is enabled.\n */\nexport interface BrokerEnabledOptions {\n /**\n * If set to true, broker will be enabled for WAM support on Windows.\n */\n enabled: true;\n /**\n * If set to true, MSA account will be passed through, required for WAM authentication.\n */\n legacyEnableMsaPassthrough?: boolean;\n /**\n * Window handle for parent window, required for WAM authentication.\n */\n parentWindowHandle: Uint8Array;\n\n /**\n * If set to true, the credential will attempt to use the default broker account for authentication before falling back to interactive authentication.\n * Default is set to false.\n */\n useDefaultBrokerAccount?: boolean;\n}\n"]}
@@ -0,0 +1,186 @@
import * as msal from "@azure/msal-node";
import type { AccessToken, GetTokenOptions } from "@azure/core-auth";
import type { AuthenticationRecord, CertificateParts } from "../types.js";
import type { CredentialLogger } from "../../util/logging.js";
import type { BrokerOptions } from "./brokerOptions.js";
import type { DeviceCodePromptCallback } from "../../credentials/deviceCodeCredentialOptions.js";
import { IdentityClient } from "../../client/identityClient.js";
import type { InteractiveBrowserCredentialNodeOptions } from "../../credentials/interactiveBrowserCredentialOptions.js";
import type { TokenCachePersistenceOptions } from "./tokenCachePersistenceOptions.js";
/**
* Represents the options for acquiring a token using flows that support silent authentication.
*/
export interface GetTokenWithSilentAuthOptions extends GetTokenOptions {
/**
* Disables automatic authentication. If set to true, the method will throw an error if the user needs to authenticate.
*
* @remarks
*
* This option will be set to `false` when the user calls `authenticate` directly on a credential that supports it.
*/
disableAutomaticAuthentication?: boolean;
}
/**
* Represents the options for acquiring a token interactively.
*/
export interface GetTokenInteractiveOptions extends GetTokenWithSilentAuthOptions {
/**
* Window handle for parent window, required for WAM authentication.
*/
parentWindowHandle?: Buffer;
/**
* Shared configuration options for browser customization
*/
browserCustomizationOptions?: InteractiveBrowserCredentialNodeOptions["browserCustomizationOptions"];
/**
* loginHint allows a user name to be pre-selected for interactive logins.
* Setting this option skips the account selection prompt and immediately attempts to login with the specified account.
*/
loginHint?: string;
}
/**
* Represents a client for interacting with the Microsoft Authentication Library (MSAL).
*/
export interface MsalClient {
/**
*
* Retrieves an access token by using the on-behalf-of flow and a client assertion callback of the calling service.
*
* @param scopes - The scopes for which the access token is requested. These represent the resources that the application wants to access.
* @param userAssertionToken - The access token that was sent to the middle-tier API. This token must have an audience of the app making this OBO request.
* @param clientCredentials - The client secret OR client certificate OR client `getAssertion` callback.
* @param options - Additional options that may be provided to the method.
* @returns An access token.
*/
getTokenOnBehalfOf(scopes: string[], userAssertionToken: string, clientCredentials: string | CertificateParts | (() => Promise<string>), options?: GetTokenOptions): Promise<AccessToken>;
/**
* Retrieves an access token by using an interactive prompt (InteractiveBrowserCredential).
* @param scopes - The scopes for which the access token is requested. These represent the resources that the application wants to access.
* @param options - Additional options that may be provided to the method.
* @returns An access token.
*/
getTokenByInteractiveRequest(scopes: string[], options: GetTokenInteractiveOptions): Promise<AccessToken>;
/**
* Retrieves an access token by using a user's username and password.
*
* @param scopes - The scopes for which the access token is requested. These represent the resources that the application wants to access.
* @param username - The username provided by the developer.
* @param password - The user's password provided by the developer.
* @param options - Additional options that may be provided to the method.
* @returns An access token.
*/
getTokenByUsernamePassword(scopes: string[], username: string, password: string, options?: GetTokenOptions): Promise<AccessToken>;
/**
* Retrieves an access token by prompting the user to authenticate using a device code.
*
* @param scopes - The scopes for which the access token is requested. These represent the resources that the application wants to access.
* @param userPromptCallback - The callback function that allows developers to customize the prompt message.
* @param options - Additional options that may be provided to the method.
* @returns An access token.
*/
getTokenByDeviceCode(scopes: string[], userPromptCallback: DeviceCodePromptCallback, options?: GetTokenWithSilentAuthOptions): Promise<AccessToken>;
/**
* Retrieves an access token by using a client certificate.
*
* @param scopes - The scopes for which the access token is requested. These represent the resources that the application wants to access.
* @param certificate - The client certificate used for authentication.
* @param options - Additional options that may be provided to the method.
* @returns An access token.
*/
getTokenByClientCertificate(scopes: string[], certificate: CertificateParts, options?: GetTokenOptions): Promise<AccessToken>;
/**
* Retrieves an access token by using a client assertion.
*
* @param scopes - The scopes for which the access token is requested. These represent the resources that the application wants to access.
* @param clientAssertion - The client `getAssertion` callback used for authentication.
* @param options - Additional options that may be provided to the method.
* @returns An access token.
*/
getTokenByClientAssertion(scopes: string[], clientAssertion: () => Promise<string>, options?: GetTokenOptions): Promise<AccessToken>;
/**
* Retrieves an access token by using a client secret.
*
* @param scopes - The scopes for which the access token is requested. These represent the resources that the application wants to access.
* @param clientSecret - The client secret of the application. This is a credential that the application can use to authenticate itself.
* @param options - Additional options that may be provided to the method.
* @returns An access token.
*/
getTokenByClientSecret(scopes: string[], clientSecret: string, options?: GetTokenOptions): Promise<AccessToken>;
/**
* Retrieves an access token by using an authorization code flow.
*
* @param scopes - The scopes for which the access token is requested. These represent the resources that the application wants to access.
* @param authorizationCode - An authorization code that was received from following the
authorization code flow. This authorization code must not
have already been used to obtain an access token.
* @param redirectUri - The redirect URI that was used to request the authorization code.
Must be the same URI that is configured for the App Registration.
* @param clientSecret - An optional client secret that was generated for the App Registration.
* @param options - Additional options that may be provided to the method.
*/
getTokenByAuthorizationCode(scopes: string[], redirectUri: string, authorizationCode: string, clientSecret?: string, options?: GetTokenWithSilentAuthOptions): Promise<AccessToken>;
/**
* Retrieves the last authenticated account. This method expects an authentication record to have been previously loaded.
*
* An authentication record could be loaded by calling the `getToken` method, or by providing an `authenticationRecord` when creating a credential.
*/
getActiveAccount(): AuthenticationRecord | undefined;
}
/**
* Represents the options for configuring the MsalClient.
*/
export interface MsalClientOptions {
/**
* Parameters that enable WAM broker authentication in the InteractiveBrowserCredential.
*/
brokerOptions?: BrokerOptions;
/**
* Parameters that enable token cache persistence in the Identity credentials.
*/
tokenCachePersistenceOptions?: TokenCachePersistenceOptions;
/**
* A custom authority host.
*/
authorityHost?: IdentityClient["tokenCredentialOptions"]["authorityHost"];
/**
* Allows users to configure settings for logging policy options, allow logging account information and personally identifiable information for customer support.
*/
loggingOptions?: IdentityClient["tokenCredentialOptions"]["loggingOptions"];
/**
* The token credential options for the MsalClient.
*/
tokenCredentialOptions?: IdentityClient["tokenCredentialOptions"];
/**
* Determines whether instance discovery is disabled.
*/
disableInstanceDiscovery?: boolean;
/**
* The logger for the MsalClient.
*/
logger?: CredentialLogger;
/**
* The authentication record for the MsalClient.
*/
authenticationRecord?: AuthenticationRecord;
}
/**
* Generates the configuration for MSAL (Microsoft Authentication Library).
*
* @param clientId - The client ID of the application.
* @param tenantId - The tenant ID of the Azure Active Directory.
* @param msalClientOptions - Optional. Additional options for creating the MSAL client.
* @returns The MSAL configuration object.
*/
export declare function generateMsalConfiguration(clientId: string, tenantId: string, msalClientOptions?: MsalClientOptions): msal.Configuration;
/**
* Creates an instance of the MSAL (Microsoft Authentication Library) client.
*
* @param clientId - The client ID of the application.
* @param tenantId - The tenant ID of the Azure Active Directory.
* @param createMsalClientOptions - Optional. Additional options for creating the MSAL client.
* @returns An instance of the MSAL client.
*
* @public
*/
export declare function createMsalClient(clientId: string, tenantId: string, createMsalClientOptions?: MsalClientOptions): MsalClient;
//# sourceMappingURL=msalClient.d.ts.map
@@ -0,0 +1 @@
{"version":3,"file":"msalClient.d.ts","sourceRoot":"","sources":["../../../../src/msal/nodeFlows/msalClient.ts"],"names":[],"mappings":"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"}
+474
View File
@@ -0,0 +1,474 @@
"use strict";
// Copyright (c) Microsoft Corporation.
// Licensed under the MIT License.
Object.defineProperty(exports, "__esModule", { value: true });
exports.generateMsalConfiguration = generateMsalConfiguration;
exports.createMsalClient = createMsalClient;
const tslib_1 = require("tslib");
const msal = tslib_1.__importStar(require("@azure/msal-node"));
const logging_js_1 = require("../../util/logging.js");
const msalPlugins_js_1 = require("./msalPlugins.js");
const utils_js_1 = require("../utils.js");
const errors_js_1 = require("../../errors.js");
const identityClient_js_1 = require("../../client/identityClient.js");
const regionalAuthority_js_1 = require("../../regionalAuthority.js");
const logger_1 = require("@azure/logger");
const tenantIdUtils_js_1 = require("../../util/tenantIdUtils.js");
/**
* The default logger used if no logger was passed in by the credential.
*/
const msalLogger = (0, logging_js_1.credentialLogger)("MsalClient");
/**
* Generates the configuration for MSAL (Microsoft Authentication Library).
*
* @param clientId - The client ID of the application.
* @param tenantId - The tenant ID of the Azure Active Directory.
* @param msalClientOptions - Optional. Additional options for creating the MSAL client.
* @returns The MSAL configuration object.
*/
function generateMsalConfiguration(clientId, tenantId, msalClientOptions = {}) {
var _a, _b, _c;
const resolvedTenant = (0, tenantIdUtils_js_1.resolveTenantId)((_a = msalClientOptions.logger) !== null && _a !== void 0 ? _a : msalLogger, tenantId, clientId);
// TODO: move and reuse getIdentityClientAuthorityHost
const authority = (0, utils_js_1.getAuthority)(resolvedTenant, (0, utils_js_1.getAuthorityHost)(msalClientOptions));
const httpClient = new identityClient_js_1.IdentityClient(Object.assign(Object.assign({}, msalClientOptions.tokenCredentialOptions), { authorityHost: authority, loggingOptions: msalClientOptions.loggingOptions }));
const msalConfig = {
auth: {
clientId,
authority,
knownAuthorities: (0, utils_js_1.getKnownAuthorities)(resolvedTenant, authority, msalClientOptions.disableInstanceDiscovery),
},
system: {
networkClient: httpClient,
loggerOptions: {
loggerCallback: (0, utils_js_1.defaultLoggerCallback)((_b = msalClientOptions.logger) !== null && _b !== void 0 ? _b : msalLogger),
logLevel: (0, utils_js_1.getMSALLogLevel)((0, logger_1.getLogLevel)()),
piiLoggingEnabled: (_c = msalClientOptions.loggingOptions) === null || _c === void 0 ? void 0 : _c.enableUnsafeSupportLogging,
},
},
};
return msalConfig;
}
/**
* Creates an instance of the MSAL (Microsoft Authentication Library) client.
*
* @param clientId - The client ID of the application.
* @param tenantId - The tenant ID of the Azure Active Directory.
* @param createMsalClientOptions - Optional. Additional options for creating the MSAL client.
* @returns An instance of the MSAL client.
*
* @public
*/
function createMsalClient(clientId, tenantId, createMsalClientOptions = {}) {
var _a;
const state = {
msalConfig: generateMsalConfiguration(clientId, tenantId, createMsalClientOptions),
cachedAccount: createMsalClientOptions.authenticationRecord
? (0, utils_js_1.publicToMsal)(createMsalClientOptions.authenticationRecord)
: null,
pluginConfiguration: msalPlugins_js_1.msalPlugins.generatePluginConfiguration(createMsalClientOptions),
logger: (_a = createMsalClientOptions.logger) !== null && _a !== void 0 ? _a : msalLogger,
};
const publicApps = new Map();
async function getPublicApp(options = {}) {
const appKey = options.enableCae ? "CAE" : "default";
let publicClientApp = publicApps.get(appKey);
if (publicClientApp) {
state.logger.getToken.info("Existing PublicClientApplication found in cache, returning it.");
return publicClientApp;
}
// Initialize a new app and cache it
state.logger.getToken.info(`Creating new PublicClientApplication with CAE ${options.enableCae ? "enabled" : "disabled"}.`);
const cachePlugin = options.enableCae
? state.pluginConfiguration.cache.cachePluginCae
: state.pluginConfiguration.cache.cachePlugin;
state.msalConfig.auth.clientCapabilities = options.enableCae ? ["cp1"] : undefined;
publicClientApp = new msal.PublicClientApplication(Object.assign(Object.assign({}, state.msalConfig), { broker: { nativeBrokerPlugin: state.pluginConfiguration.broker.nativeBrokerPlugin }, cache: { cachePlugin: await cachePlugin } }));
publicApps.set(appKey, publicClientApp);
return publicClientApp;
}
const confidentialApps = new Map();
async function getConfidentialApp(options = {}) {
const appKey = options.enableCae ? "CAE" : "default";
let confidentialClientApp = confidentialApps.get(appKey);
if (confidentialClientApp) {
state.logger.getToken.info("Existing ConfidentialClientApplication found in cache, returning it.");
return confidentialClientApp;
}
// Initialize a new app and cache it
state.logger.getToken.info(`Creating new ConfidentialClientApplication with CAE ${options.enableCae ? "enabled" : "disabled"}.`);
const cachePlugin = options.enableCae
? state.pluginConfiguration.cache.cachePluginCae
: state.pluginConfiguration.cache.cachePlugin;
state.msalConfig.auth.clientCapabilities = options.enableCae ? ["cp1"] : undefined;
confidentialClientApp = new msal.ConfidentialClientApplication(Object.assign(Object.assign({}, state.msalConfig), { broker: { nativeBrokerPlugin: state.pluginConfiguration.broker.nativeBrokerPlugin }, cache: { cachePlugin: await cachePlugin } }));
confidentialApps.set(appKey, confidentialClientApp);
return confidentialClientApp;
}
async function getTokenSilent(app, scopes, options = {}) {
if (state.cachedAccount === null) {
state.logger.getToken.info("No cached account found in local state.");
throw new errors_js_1.AuthenticationRequiredError({ scopes });
}
// Keep track and reuse the claims we received across challenges
if (options.claims) {
state.cachedClaims = options.claims;
}
const silentRequest = {
account: state.cachedAccount,
scopes,
claims: state.cachedClaims,
};
if (state.pluginConfiguration.broker.isEnabled) {
silentRequest.tokenQueryParameters || (silentRequest.tokenQueryParameters = {});
if (state.pluginConfiguration.broker.enableMsaPassthrough) {
silentRequest.tokenQueryParameters["msal_request_type"] = "consumer_passthrough";
}
}
if (options.proofOfPossessionOptions) {
silentRequest.shrNonce = options.proofOfPossessionOptions.nonce;
silentRequest.authenticationScheme = "pop";
silentRequest.resourceRequestMethod = options.proofOfPossessionOptions.resourceRequestMethod;
silentRequest.resourceRequestUri = options.proofOfPossessionOptions.resourceRequestUrl;
}
state.logger.getToken.info("Attempting to acquire token silently");
try {
return await app.acquireTokenSilent(silentRequest);
}
catch (err) {
throw (0, utils_js_1.handleMsalError)(scopes, err, options);
}
}
/**
* Builds an authority URL for the given request. The authority may be different than the one used when creating the MSAL client
* if the user is creating cross-tenant requests
*/
function calculateRequestAuthority(options) {
if (options === null || options === void 0 ? void 0 : options.tenantId) {
return (0, utils_js_1.getAuthority)(options.tenantId, (0, utils_js_1.getAuthorityHost)(createMsalClientOptions));
}
return state.msalConfig.auth.authority;
}
/**
* Performs silent authentication using MSAL to acquire an access token.
* If silent authentication fails, falls back to interactive authentication.
*
* @param msalApp - The MSAL application instance.
* @param scopes - The scopes for which to acquire the access token.
* @param options - The options for acquiring the access token.
* @param onAuthenticationRequired - A callback function to handle interactive authentication when silent authentication fails.
* @returns A promise that resolves to an AccessToken object containing the access token and its expiration timestamp.
*/
async function withSilentAuthentication(msalApp, scopes, options, onAuthenticationRequired) {
var _a, _b;
let response = null;
try {
response = await getTokenSilent(msalApp, scopes, options);
}
catch (e) {
if (e.name !== "AuthenticationRequiredError") {
throw e;
}
if (options.disableAutomaticAuthentication) {
throw new errors_js_1.AuthenticationRequiredError({
scopes,
getTokenOptions: options,
message: "Automatic authentication has been disabled. You may call the authentication() method.",
});
}
}
// Silent authentication failed
if (response === null) {
try {
response = await onAuthenticationRequired();
}
catch (err) {
throw (0, utils_js_1.handleMsalError)(scopes, err, options);
}
}
// At this point we should have a token, process it
(0, utils_js_1.ensureValidMsalToken)(scopes, response, options);
state.cachedAccount = (_a = response === null || response === void 0 ? void 0 : response.account) !== null && _a !== void 0 ? _a : null;
state.logger.getToken.info((0, logging_js_1.formatSuccess)(scopes));
return {
token: response.accessToken,
expiresOnTimestamp: response.expiresOn.getTime(),
refreshAfterTimestamp: (_b = response.refreshOn) === null || _b === void 0 ? void 0 : _b.getTime(),
tokenType: response.tokenType,
};
}
async function getTokenByClientSecret(scopes, clientSecret, options = {}) {
var _a;
state.logger.getToken.info(`Attempting to acquire token using client secret`);
state.msalConfig.auth.clientSecret = clientSecret;
const msalApp = await getConfidentialApp(options);
try {
const response = await msalApp.acquireTokenByClientCredential({
scopes,
authority: calculateRequestAuthority(options),
azureRegion: (0, regionalAuthority_js_1.calculateRegionalAuthority)(),
claims: options === null || options === void 0 ? void 0 : options.claims,
});
(0, utils_js_1.ensureValidMsalToken)(scopes, response, options);
state.logger.getToken.info((0, logging_js_1.formatSuccess)(scopes));
return {
token: response.accessToken,
expiresOnTimestamp: response.expiresOn.getTime(),
refreshAfterTimestamp: (_a = response.refreshOn) === null || _a === void 0 ? void 0 : _a.getTime(),
tokenType: response.tokenType,
};
}
catch (err) {
throw (0, utils_js_1.handleMsalError)(scopes, err, options);
}
}
async function getTokenByClientAssertion(scopes, clientAssertion, options = {}) {
var _a;
state.logger.getToken.info(`Attempting to acquire token using client assertion`);
state.msalConfig.auth.clientAssertion = clientAssertion;
const msalApp = await getConfidentialApp(options);
try {
const response = await msalApp.acquireTokenByClientCredential({
scopes,
authority: calculateRequestAuthority(options),
azureRegion: (0, regionalAuthority_js_1.calculateRegionalAuthority)(),
claims: options === null || options === void 0 ? void 0 : options.claims,
clientAssertion,
});
(0, utils_js_1.ensureValidMsalToken)(scopes, response, options);
state.logger.getToken.info((0, logging_js_1.formatSuccess)(scopes));
return {
token: response.accessToken,
expiresOnTimestamp: response.expiresOn.getTime(),
refreshAfterTimestamp: (_a = response.refreshOn) === null || _a === void 0 ? void 0 : _a.getTime(),
tokenType: response.tokenType,
};
}
catch (err) {
throw (0, utils_js_1.handleMsalError)(scopes, err, options);
}
}
async function getTokenByClientCertificate(scopes, certificate, options = {}) {
var _a;
state.logger.getToken.info(`Attempting to acquire token using client certificate`);
state.msalConfig.auth.clientCertificate = certificate;
const msalApp = await getConfidentialApp(options);
try {
const response = await msalApp.acquireTokenByClientCredential({
scopes,
authority: calculateRequestAuthority(options),
azureRegion: (0, regionalAuthority_js_1.calculateRegionalAuthority)(),
claims: options === null || options === void 0 ? void 0 : options.claims,
});
(0, utils_js_1.ensureValidMsalToken)(scopes, response, options);
state.logger.getToken.info((0, logging_js_1.formatSuccess)(scopes));
return {
token: response.accessToken,
expiresOnTimestamp: response.expiresOn.getTime(),
refreshAfterTimestamp: (_a = response.refreshOn) === null || _a === void 0 ? void 0 : _a.getTime(),
tokenType: response.tokenType,
};
}
catch (err) {
throw (0, utils_js_1.handleMsalError)(scopes, err, options);
}
}
async function getTokenByDeviceCode(scopes, deviceCodeCallback, options = {}) {
state.logger.getToken.info(`Attempting to acquire token using device code`);
const msalApp = await getPublicApp(options);
return withSilentAuthentication(msalApp, scopes, options, () => {
var _a, _b;
const requestOptions = {
scopes,
cancel: (_b = (_a = options === null || options === void 0 ? void 0 : options.abortSignal) === null || _a === void 0 ? void 0 : _a.aborted) !== null && _b !== void 0 ? _b : false,
deviceCodeCallback,
authority: calculateRequestAuthority(options),
claims: options === null || options === void 0 ? void 0 : options.claims,
};
const deviceCodeRequest = msalApp.acquireTokenByDeviceCode(requestOptions);
if (options.abortSignal) {
options.abortSignal.addEventListener("abort", () => {
requestOptions.cancel = true;
});
}
return deviceCodeRequest;
});
}
async function getTokenByUsernamePassword(scopes, username, password, options = {}) {
state.logger.getToken.info(`Attempting to acquire token using username and password`);
const msalApp = await getPublicApp(options);
return withSilentAuthentication(msalApp, scopes, options, () => {
const requestOptions = {
scopes,
username,
password,
authority: calculateRequestAuthority(options),
claims: options === null || options === void 0 ? void 0 : options.claims,
};
return msalApp.acquireTokenByUsernamePassword(requestOptions);
});
}
function getActiveAccount() {
if (!state.cachedAccount) {
return undefined;
}
return (0, utils_js_1.msalToPublic)(clientId, state.cachedAccount);
}
async function getTokenByAuthorizationCode(scopes, redirectUri, authorizationCode, clientSecret, options = {}) {
state.logger.getToken.info(`Attempting to acquire token using authorization code`);
let msalApp;
if (clientSecret) {
// If a client secret is provided, we need to use a confidential client application
// See https://learn.microsoft.com/entra/identity-platform/v2-oauth2-auth-code-flow#request-an-access-token-with-a-client_secret
state.msalConfig.auth.clientSecret = clientSecret;
msalApp = await getConfidentialApp(options);
}
else {
msalApp = await getPublicApp(options);
}
return withSilentAuthentication(msalApp, scopes, options, () => {
return msalApp.acquireTokenByCode({
scopes,
redirectUri,
code: authorizationCode,
authority: calculateRequestAuthority(options),
claims: options === null || options === void 0 ? void 0 : options.claims,
});
});
}
async function getTokenOnBehalfOf(scopes, userAssertionToken, clientCredentials, options = {}) {
var _a;
msalLogger.getToken.info(`Attempting to acquire token on behalf of another user`);
if (typeof clientCredentials === "string") {
// Client secret
msalLogger.getToken.info(`Using client secret for on behalf of flow`);
state.msalConfig.auth.clientSecret = clientCredentials;
}
else if (typeof clientCredentials === "function") {
// Client Assertion
msalLogger.getToken.info(`Using client assertion callback for on behalf of flow`);
state.msalConfig.auth.clientAssertion = clientCredentials;
}
else {
// Client certificate
msalLogger.getToken.info(`Using client certificate for on behalf of flow`);
state.msalConfig.auth.clientCertificate = clientCredentials;
}
const msalApp = await getConfidentialApp(options);
try {
const response = await msalApp.acquireTokenOnBehalfOf({
scopes,
authority: calculateRequestAuthority(options),
claims: options.claims,
oboAssertion: userAssertionToken,
});
(0, utils_js_1.ensureValidMsalToken)(scopes, response, options);
msalLogger.getToken.info((0, logging_js_1.formatSuccess)(scopes));
return {
token: response.accessToken,
expiresOnTimestamp: response.expiresOn.getTime(),
refreshAfterTimestamp: (_a = response.refreshOn) === null || _a === void 0 ? void 0 : _a.getTime(),
tokenType: response.tokenType,
};
}
catch (err) {
throw (0, utils_js_1.handleMsalError)(scopes, err, options);
}
}
async function getTokenByInteractiveRequest(scopes, options = {}) {
msalLogger.getToken.info(`Attempting to acquire token interactively`);
const app = await getPublicApp(options);
/**
* A helper function that supports brokered authentication through the MSAL's public application.
*
* When options.useDefaultBrokerAccount is true, the method will attempt to authenticate using the default broker account.
* If the default broker account is not available, the method will fall back to interactive authentication.
*/
async function getBrokeredToken(useDefaultBrokerAccount) {
var _a;
msalLogger.verbose("Authentication will resume through the broker");
const interactiveRequest = createBaseInteractiveRequest();
if (state.pluginConfiguration.broker.parentWindowHandle) {
interactiveRequest.windowHandle = Buffer.from(state.pluginConfiguration.broker.parentWindowHandle);
}
else {
// this is a bug, as the pluginConfiguration handler should validate this case.
msalLogger.warning("Parent window handle is not specified for the broker. This may cause unexpected behavior. Please provide the parentWindowHandle.");
}
if (state.pluginConfiguration.broker.enableMsaPassthrough) {
((_a = interactiveRequest.tokenQueryParameters) !== null && _a !== void 0 ? _a : (interactiveRequest.tokenQueryParameters = {}))["msal_request_type"] =
"consumer_passthrough";
}
if (useDefaultBrokerAccount) {
interactiveRequest.prompt = "none";
msalLogger.verbose("Attempting broker authentication using the default broker account");
}
else {
msalLogger.verbose("Attempting broker authentication without the default broker account");
}
if (options.proofOfPossessionOptions) {
interactiveRequest.shrNonce = options.proofOfPossessionOptions.nonce;
interactiveRequest.authenticationScheme = "pop";
interactiveRequest.resourceRequestMethod =
options.proofOfPossessionOptions.resourceRequestMethod;
interactiveRequest.resourceRequestUri = options.proofOfPossessionOptions.resourceRequestUrl;
}
try {
return await app.acquireTokenInteractive(interactiveRequest);
}
catch (e) {
msalLogger.verbose(`Failed to authenticate through the broker: ${e.message}`);
// If we tried to use the default broker account and failed, fall back to interactive authentication
if (useDefaultBrokerAccount) {
return getBrokeredToken(/* useDefaultBrokerAccount: */ false);
}
else {
throw e;
}
}
}
function createBaseInteractiveRequest() {
var _a, _b;
return {
openBrowser: async (url) => {
const open = await import("open");
await open.default(url, { wait: true, newInstance: true });
},
scopes,
authority: calculateRequestAuthority(options),
claims: options === null || options === void 0 ? void 0 : options.claims,
loginHint: options === null || options === void 0 ? void 0 : options.loginHint,
errorTemplate: (_a = options === null || options === void 0 ? void 0 : options.browserCustomizationOptions) === null || _a === void 0 ? void 0 : _a.errorMessage,
successTemplate: (_b = options === null || options === void 0 ? void 0 : options.browserCustomizationOptions) === null || _b === void 0 ? void 0 : _b.successMessage,
prompt: (options === null || options === void 0 ? void 0 : options.loginHint) ? "login" : "select_account",
};
}
return withSilentAuthentication(app, scopes, options, async () => {
var _a;
const interactiveRequest = createBaseInteractiveRequest();
if (state.pluginConfiguration.broker.isEnabled) {
return getBrokeredToken((_a = state.pluginConfiguration.broker.useDefaultBrokerAccount) !== null && _a !== void 0 ? _a : false);
}
if (options.proofOfPossessionOptions) {
interactiveRequest.shrNonce = options.proofOfPossessionOptions.nonce;
interactiveRequest.authenticationScheme = "pop";
interactiveRequest.resourceRequestMethod =
options.proofOfPossessionOptions.resourceRequestMethod;
interactiveRequest.resourceRequestUri = options.proofOfPossessionOptions.resourceRequestUrl;
}
return app.acquireTokenInteractive(interactiveRequest);
});
}
return {
getActiveAccount,
getTokenByClientSecret,
getTokenByClientAssertion,
getTokenByClientCertificate,
getTokenByDeviceCode,
getTokenByUsernamePassword,
getTokenByAuthorizationCode,
getTokenOnBehalfOf,
getTokenByInteractiveRequest,
};
}
//# sourceMappingURL=msalClient.js.map
File diff suppressed because one or more lines are too long
@@ -0,0 +1,91 @@
import type * as msalNode from "@azure/msal-node";
import type { MsalClientOptions } from "./msalClient.js";
import type { NativeBrokerPluginControl } from "../../plugins/provider.js";
import type { TokenCachePersistenceOptions } from "./tokenCachePersistenceOptions.js";
/**
* Configuration for the plugins used by the MSAL node client.
*/
export interface PluginConfiguration {
/**
* Configuration for the cache plugin.
*/
cache: {
/**
* The non-CAE cache plugin handler.
*/
cachePlugin?: Promise<msalNode.ICachePlugin>;
/**
* The CAE cache plugin handler - persisted to a different file.
*/
cachePluginCae?: Promise<msalNode.ICachePlugin>;
};
/**
* Configuration for the broker plugin.
*/
broker: {
/**
* True if the broker plugin is enabled and available. False otherwise.
*
* It is a bug if this is true and the broker plugin is not available.
*/
isEnabled: boolean;
/**
* If true, MSA account will be passed through, required for WAM authentication.
*/
enableMsaPassthrough: boolean;
/**
* The parent window handle for the broker.
*/
parentWindowHandle?: Uint8Array;
/**
* The native broker plugin handler.
*/
nativeBrokerPlugin?: msalNode.INativeBrokerPlugin;
/**
* If set to true, the credential will attempt to use the default broker account for authentication before falling back to interactive authentication. Default is set to false.
*/
useDefaultBrokerAccount?: boolean;
};
}
/**
* The current persistence provider, undefined by default.
* @internal
*/
export declare let persistenceProvider: ((options?: TokenCachePersistenceOptions) => Promise<msalNode.ICachePlugin>) | undefined;
/**
* An object that allows setting the persistence provider.
* @internal
*/
export declare const msalNodeFlowCacheControl: {
setPersistence(pluginProvider: Exclude<typeof persistenceProvider, undefined>): void;
};
/**
* The current native broker provider, undefined by default.
* @internal
*/
export declare let nativeBrokerInfo: {
broker: msalNode.INativeBrokerPlugin;
} | undefined;
export declare function hasNativeBroker(): boolean;
/**
* An object that allows setting the native broker provider.
* @internal
*/
export declare const msalNodeFlowNativeBrokerControl: NativeBrokerPluginControl;
/**
* Configures plugins, validating that required plugins are available and enabled.
*
* Does not create the plugins themselves, but rather returns the configuration that will be used to create them.
*
* @param options - options for creating the MSAL client
* @returns plugin configuration
*/
declare function generatePluginConfiguration(options: MsalClientOptions): PluginConfiguration;
/**
* Wraps generatePluginConfiguration as a writeable property for test stubbing purposes.
*/
export declare const msalPlugins: {
generatePluginConfiguration: typeof generatePluginConfiguration;
};
export {};
//# sourceMappingURL=msalPlugins.d.ts.map
@@ -0,0 +1 @@
{"version":3,"file":"msalPlugins.d.ts","sourceRoot":"","sources":["../../../../src/msal/nodeFlows/msalPlugins.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,KAAK,QAAQ,MAAM,kBAAkB,CAAC;AAQlD,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,iBAAiB,CAAC;AACzD,OAAO,KAAK,EAAE,yBAAyB,EAAE,MAAM,2BAA2B,CAAC;AAC3E,OAAO,KAAK,EAAE,4BAA4B,EAAE,MAAM,mCAAmC,CAAC;AAEtF;;GAEG;AACH,MAAM,WAAW,mBAAmB;IAClC;;OAEG;IACH,KAAK,EAAE;QACL;;WAEG;QACH,WAAW,CAAC,EAAE,OAAO,CAAC,QAAQ,CAAC,YAAY,CAAC,CAAC;QAC7C;;WAEG;QACH,cAAc,CAAC,EAAE,OAAO,CAAC,QAAQ,CAAC,YAAY,CAAC,CAAC;KACjD,CAAC;IACF;;OAEG;IACH,MAAM,EAAE;QACN;;;;WAIG;QACH,SAAS,EAAE,OAAO,CAAC;QACnB;;WAEG;QACH,oBAAoB,EAAE,OAAO,CAAC;QAC9B;;WAEG;QACH,kBAAkB,CAAC,EAAE,UAAU,CAAC;QAChC;;WAEG;QACH,kBAAkB,CAAC,EAAE,QAAQ,CAAC,mBAAmB,CAAC;QAClD;;WAEG;QACH,uBAAuB,CAAC,EAAE,OAAO,CAAC;KACnC,CAAC;CACH;AAED;;;GAGG;AACH,eAAO,IAAI,mBAAmB,EAC1B,CAAC,CAAC,OAAO,CAAC,EAAE,4BAA4B,KAAK,OAAO,CAAC,QAAQ,CAAC,YAAY,CAAC,CAAC,GAC5E,SAAqB,CAAC;AAE1B;;;GAGG;AACH,eAAO,MAAM,wBAAwB;mCACJ,OAAO,CAAC,OAAO,mBAAmB,EAAE,SAAS,CAAC,GAAG,IAAI;CAGrF,CAAC;AAEF;;;GAGG;AACH,eAAO,IAAI,gBAAgB,EACvB;IACE,MAAM,EAAE,QAAQ,CAAC,mBAAmB,CAAC;CACtC,GACD,SAAqB,CAAC;AAE1B,wBAAgB,eAAe,IAAI,OAAO,CAEzC;AAED;;;GAGG;AACH,eAAO,MAAM,+BAA+B,EAAE,yBAM7C,CAAC;AAEF;;;;;;;GAOG;AACH,iBAAS,2BAA2B,CAAC,OAAO,EAAE,iBAAiB,GAAG,mBAAmB,CAgDpF;AAED;;GAEG;AACH,eAAO,MAAM,WAAW;;CAEvB,CAAC"}
@@ -0,0 +1,91 @@
"use strict";
// Copyright (c) Microsoft Corporation.
// Licensed under the MIT License.
Object.defineProperty(exports, "__esModule", { value: true });
exports.msalPlugins = exports.msalNodeFlowNativeBrokerControl = exports.nativeBrokerInfo = exports.msalNodeFlowCacheControl = exports.persistenceProvider = void 0;
exports.hasNativeBroker = hasNativeBroker;
const constants_js_1 = require("../../constants.js");
/**
* The current persistence provider, undefined by default.
* @internal
*/
exports.persistenceProvider = undefined;
/**
* An object that allows setting the persistence provider.
* @internal
*/
exports.msalNodeFlowCacheControl = {
setPersistence(pluginProvider) {
exports.persistenceProvider = pluginProvider;
},
};
/**
* The current native broker provider, undefined by default.
* @internal
*/
exports.nativeBrokerInfo = undefined;
function hasNativeBroker() {
return exports.nativeBrokerInfo !== undefined;
}
/**
* An object that allows setting the native broker provider.
* @internal
*/
exports.msalNodeFlowNativeBrokerControl = {
setNativeBroker(broker) {
exports.nativeBrokerInfo = {
broker,
};
},
};
/**
* Configures plugins, validating that required plugins are available and enabled.
*
* Does not create the plugins themselves, but rather returns the configuration that will be used to create them.
*
* @param options - options for creating the MSAL client
* @returns plugin configuration
*/
function generatePluginConfiguration(options) {
var _a, _b, _c, _d, _e, _f, _g;
const config = {
cache: {},
broker: {
isEnabled: (_b = (_a = options.brokerOptions) === null || _a === void 0 ? void 0 : _a.enabled) !== null && _b !== void 0 ? _b : false,
enableMsaPassthrough: (_d = (_c = options.brokerOptions) === null || _c === void 0 ? void 0 : _c.legacyEnableMsaPassthrough) !== null && _d !== void 0 ? _d : false,
parentWindowHandle: (_e = options.brokerOptions) === null || _e === void 0 ? void 0 : _e.parentWindowHandle,
},
};
if ((_f = options.tokenCachePersistenceOptions) === null || _f === void 0 ? void 0 : _f.enabled) {
if (exports.persistenceProvider === undefined) {
throw new Error([
"Persistent token caching was requested, but no persistence provider was configured.",
"You must install the identity-cache-persistence plugin package (`npm install --save @azure/identity-cache-persistence`)",
"and enable it by importing `useIdentityPlugin` from `@azure/identity` and calling",
"`useIdentityPlugin(cachePersistencePlugin)` before using `tokenCachePersistenceOptions`.",
].join(" "));
}
const cacheBaseName = options.tokenCachePersistenceOptions.name || constants_js_1.DEFAULT_TOKEN_CACHE_NAME;
config.cache.cachePlugin = (0, exports.persistenceProvider)(Object.assign({ name: `${cacheBaseName}.${constants_js_1.CACHE_NON_CAE_SUFFIX}` }, options.tokenCachePersistenceOptions));
config.cache.cachePluginCae = (0, exports.persistenceProvider)(Object.assign({ name: `${cacheBaseName}.${constants_js_1.CACHE_CAE_SUFFIX}` }, options.tokenCachePersistenceOptions));
}
if ((_g = options.brokerOptions) === null || _g === void 0 ? void 0 : _g.enabled) {
if (exports.nativeBrokerInfo === undefined) {
throw new Error([
"Broker for WAM was requested to be enabled, but no native broker was configured.",
"You must install the identity-broker plugin package (`npm install --save @azure/identity-broker`)",
"and enable it by importing `useIdentityPlugin` from `@azure/identity` and calling",
"`useIdentityPlugin(createNativeBrokerPlugin())` before using `enableBroker`.",
].join(" "));
}
config.broker.nativeBrokerPlugin = exports.nativeBrokerInfo.broker;
}
return config;
}
/**
* Wraps generatePluginConfiguration as a writeable property for test stubbing purposes.
*/
exports.msalPlugins = {
generatePluginConfiguration,
};
//# sourceMappingURL=msalPlugins.js.map
File diff suppressed because one or more lines are too long
@@ -0,0 +1,24 @@
/**
* Parameters that enable token cache persistence in the Identity credentials.
*/
export interface TokenCachePersistenceOptions {
/**
* If set to true, persistent token caching will be enabled for this credential instance.
*/
enabled: boolean;
/**
* Unique identifier for the persistent token cache.
*
* Based on this identifier, the persistence file will be located in any of the following places:
* - Darwin: '/Users/user/.IdentityService/<name>'
* - Windows 8+: 'C:\\Users\\user\\AppData\\Local\\.IdentityService\\<name>'
* - Linux: '/home/user/.IdentityService/<name>'
*/
name?: string;
/**
* If set to true, the cache will be stored without encryption if no OS level user encryption is available.
* When set to false, the PersistentTokenCache will throw an error if no OS level user encryption is available.
*/
unsafeAllowUnencryptedStorage?: boolean;
}
//# sourceMappingURL=tokenCachePersistenceOptions.d.ts.map
@@ -0,0 +1 @@
{"version":3,"file":"tokenCachePersistenceOptions.d.ts","sourceRoot":"","sources":["../../../../src/msal/nodeFlows/tokenCachePersistenceOptions.ts"],"names":[],"mappings":"AAGA;;GAEG;AACH,MAAM,WAAW,4BAA4B;IAC3C;;OAEG;IACH,OAAO,EAAE,OAAO,CAAC;IACjB;;;;;;;OAOG;IACH,IAAI,CAAC,EAAE,MAAM,CAAC;IACd;;;OAGG;IACH,6BAA6B,CAAC,EAAE,OAAO,CAAC;CACzC"}
@@ -0,0 +1,5 @@
"use strict";
// Copyright (c) Microsoft Corporation.
// Licensed under the MIT License.
Object.defineProperty(exports, "__esModule", { value: true });
//# sourceMappingURL=tokenCachePersistenceOptions.js.map
@@ -0,0 +1 @@
{"version":3,"file":"tokenCachePersistenceOptions.js","sourceRoot":"","sources":["../../../../src/msal/nodeFlows/tokenCachePersistenceOptions.ts"],"names":[],"mappings":";AAAA,uCAAuC;AACvC,kCAAkC","sourcesContent":["// Copyright (c) Microsoft Corporation.\n// Licensed under the MIT License.\n\n/**\n * Parameters that enable token cache persistence in the Identity credentials.\n */\nexport interface TokenCachePersistenceOptions {\n /**\n * If set to true, persistent token caching will be enabled for this credential instance.\n */\n enabled: boolean;\n /**\n * Unique identifier for the persistent token cache.\n *\n * Based on this identifier, the persistence file will be located in any of the following places:\n * - Darwin: '/Users/user/.IdentityService/<name>'\n * - Windows 8+: 'C:\\\\Users\\\\user\\\\AppData\\\\Local\\\\.IdentityService\\\\<name>'\n * - Linux: '/home/user/.IdentityService/<name>'\n */\n name?: string;\n /**\n * If set to true, the cache will be stored without encryption if no OS level user encryption is available.\n * When set to false, the PersistentTokenCache will throw an error if no OS level user encryption is available.\n */\n unsafeAllowUnencryptedStorage?: boolean;\n}\n"]}
+87
View File
@@ -0,0 +1,87 @@
/**
* @internal
*/
export type AppType = "public" | "confidential" | "publicFirst" | "confidentialFirst";
/**
* The shape we use return the token (and the expiration date).
* @internal
*/
export interface MsalToken {
accessToken?: string;
expiresOn: Date | null;
}
/**
* Represents a valid (i.e. complete) MSAL token.
*/
export type ValidMsalToken = {
[P in keyof MsalToken]-?: NonNullable<MsalToken[P]>;
};
/**
* Internal representation of MSAL's Account information.
* Helps us to disambiguate the MSAL classes accross environments.
* @internal
*/
export interface MsalAccountInfo {
homeAccountId: string;
environment?: string;
tenantId: string;
username: string;
localAccountId: string;
name?: string;
idTokenClaims?: object;
}
/**
* Represents the common properties of any of the MSAL responses.
* @internal
*/
export interface MsalResult {
authority?: string;
account: MsalAccountInfo | null;
accessToken: string;
expiresOn: Date | null;
refreshOn?: Date | null;
}
/**
* The record to use to find the cached tokens in the cache.
*/
export interface AuthenticationRecord {
/**
* Entity which issued the token represented by the domain of the issuer (e.g. login.microsoftonline.com)
*/
authority: string;
/**
* The home account Id.
*/
homeAccountId: string;
/**
* The associated client ID.
*/
clientId: string;
/**
* The associated tenant ID.
*/
tenantId: string;
/**
* The username of the logged in account.
*/
username: string;
}
/**
* Represents a parsed certificate
* @internal
*/
export interface CertificateParts {
/**
* Hex encoded X.509 SHA-1 thumbprint of the certificate.
*/
thumbprint: string;
/**
* The PEM encoded private key.
*/
privateKey: string;
/**
* x5c header.
*/
x5c?: string;
}
//# sourceMappingURL=types.d.ts.map
+1
View File
@@ -0,0 +1 @@
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../../src/msal/types.ts"],"names":[],"mappings":"AAGA;;GAEG;AACH,MAAM,MAAM,OAAO,GAAG,QAAQ,GAAG,cAAc,GAAG,aAAa,GAAG,mBAAmB,CAAC;AAEtF;;;GAGG;AACH,MAAM,WAAW,SAAS;IACxB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,SAAS,EAAE,IAAI,GAAG,IAAI,CAAC;CACxB;AAED;;GAEG;AACH,MAAM,MAAM,cAAc,GAAG;KAAG,CAAC,IAAI,MAAM,SAAS,CAAC,CAAC,GAAG,WAAW,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC;CAAE,CAAC;AAErF;;;;GAIG;AACH,MAAM,WAAW,eAAe;IAC9B,aAAa,EAAE,MAAM,CAAC;IACtB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,QAAQ,EAAE,MAAM,CAAC;IACjB,QAAQ,EAAE,MAAM,CAAC;IACjB,cAAc,EAAE,MAAM,CAAC;IACvB,IAAI,CAAC,EAAE,MAAM,CAAC;IAEd,aAAa,CAAC,EAAE,MAAM,CAAC;CACxB;AAED;;;GAGG;AACH,MAAM,WAAW,UAAU;IACzB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,OAAO,EAAE,eAAe,GAAG,IAAI,CAAC;IAChC,WAAW,EAAE,MAAM,CAAC;IACpB,SAAS,EAAE,IAAI,GAAG,IAAI,CAAC;IACvB,SAAS,CAAC,EAAE,IAAI,GAAG,IAAI,CAAC;CACzB;AAED;;GAEG;AACH,MAAM,WAAW,oBAAoB;IACnC;;OAEG;IACH,SAAS,EAAE,MAAM,CAAC;IAClB;;OAEG;IACH,aAAa,EAAE,MAAM,CAAC;IACtB;;OAEG;IACH,QAAQ,EAAE,MAAM,CAAC;IACjB;;OAEG;IACH,QAAQ,EAAE,MAAM,CAAC;IACjB;;OAEG;IACH,QAAQ,EAAE,MAAM,CAAC;CAClB;AAED;;;GAGG;AACH,MAAM,WAAW,gBAAgB;IAC/B;;OAEG;IACH,UAAU,EAAE,MAAM,CAAC;IAEnB;;OAEG;IACH,UAAU,EAAE,MAAM,CAAC;IACnB;;OAEG;IACH,GAAG,CAAC,EAAE,MAAM,CAAC;CACd"}
+5
View File
@@ -0,0 +1,5 @@
"use strict";
// Copyright (c) Microsoft Corporation.
// Licensed under the MIT License.
Object.defineProperty(exports, "__esModule", { value: true });
//# sourceMappingURL=types.js.map
+1
View File
@@ -0,0 +1 @@
{"version":3,"file":"types.js","sourceRoot":"","sources":["../../../src/msal/types.ts"],"names":[],"mappings":";AAAA,uCAAuC;AACvC,kCAAkC","sourcesContent":["// Copyright (c) Microsoft Corporation.\n// Licensed under the MIT License.\n\n/**\n * @internal\n */\nexport type AppType = \"public\" | \"confidential\" | \"publicFirst\" | \"confidentialFirst\";\n\n/**\n * The shape we use return the token (and the expiration date).\n * @internal\n */\nexport interface MsalToken {\n accessToken?: string;\n expiresOn: Date | null;\n}\n\n/**\n * Represents a valid (i.e. complete) MSAL token.\n */\nexport type ValidMsalToken = { [P in keyof MsalToken]-?: NonNullable<MsalToken[P]> };\n\n/**\n * Internal representation of MSAL's Account information.\n * Helps us to disambiguate the MSAL classes accross environments.\n * @internal\n */\nexport interface MsalAccountInfo {\n homeAccountId: string;\n environment?: string;\n tenantId: string;\n username: string;\n localAccountId: string;\n name?: string;\n // Leaving idTokenClaims as object since that's how MSAL has this assigned.\n idTokenClaims?: object;\n}\n\n/**\n * Represents the common properties of any of the MSAL responses.\n * @internal\n */\nexport interface MsalResult {\n authority?: string;\n account: MsalAccountInfo | null;\n accessToken: string;\n expiresOn: Date | null;\n refreshOn?: Date | null;\n}\n\n/**\n * The record to use to find the cached tokens in the cache.\n */\nexport interface AuthenticationRecord {\n /**\n * Entity which issued the token represented by the domain of the issuer (e.g. login.microsoftonline.com)\n */\n authority: string;\n /**\n * The home account Id.\n */\n homeAccountId: string;\n /**\n * The associated client ID.\n */\n clientId: string;\n /**\n * The associated tenant ID.\n */\n tenantId: string;\n /**\n * The username of the logged in account.\n */\n username: string;\n}\n\n/**\n * Represents a parsed certificate\n * @internal\n */\nexport interface CertificateParts {\n /**\n * Hex encoded X.509 SHA-1 thumbprint of the certificate.\n */\n thumbprint: string;\n\n /**\n * The PEM encoded private key.\n */\n privateKey: string;\n /**\n * x5c header.\n */\n x5c?: string;\n}\n"]}
+95
View File
@@ -0,0 +1,95 @@
import type { AuthenticationRecord, MsalAccountInfo, MsalToken, ValidMsalToken } from "./types.js";
import type { CredentialLogger } from "../util/logging.js";
import type { AzureLogLevel } from "@azure/logger";
import type { GetTokenOptions } from "@azure/core-auth";
import { msalCommon } from "./msal.js";
export interface ILoggerCallback {
(level: msalCommon.LogLevel, message: string, containsPii: boolean): void;
}
/**
* Ensures the validity of the MSAL token
* @internal
*/
export declare function ensureValidMsalToken(scopes: string | string[], msalToken?: MsalToken | null, getTokenOptions?: GetTokenOptions): asserts msalToken is ValidMsalToken;
/**
* Returns the authority host from either the options bag or the AZURE_AUTHORITY_HOST environment variable.
*
* Defaults to {@link DefaultAuthorityHost}.
* @internal
*/
export declare function getAuthorityHost(options?: {
authorityHost?: string;
}): string;
/**
* Generates a valid authority by combining a host with a tenantId.
* @internal
*/
export declare function getAuthority(tenantId: string, host?: string): string;
/**
* Generates the known authorities.
* If the Tenant Id is `adfs`, the authority can't be validated since the format won't match the expected one.
* For that reason, we have to force MSAL to disable validating the authority
* by sending it within the known authorities in the MSAL configuration.
* @internal
*/
export declare function getKnownAuthorities(tenantId: string, authorityHost: string, disableInstanceDiscovery?: boolean): string[];
/**
* Generates a logger that can be passed to the MSAL clients.
* @param credLogger - The logger of the credential.
* @internal
*/
export declare const defaultLoggerCallback: (logger: CredentialLogger, platform?: "Node" | "Browser") => ILoggerCallback;
/**
* @internal
*/
export declare function getMSALLogLevel(logLevel: AzureLogLevel | undefined): msalCommon.LogLevel;
/**
* Wraps core-util's randomUUID in order to allow for mocking in tests.
* This prepares the library for the upcoming core-util update to ESM.
*
* @internal
* @returns A string containing a random UUID
*/
export declare function randomUUID(): string;
/**
* Handles MSAL errors.
*/
export declare function handleMsalError(scopes: string[], error: Error, getTokenOptions?: GetTokenOptions): Error;
export declare function publicToMsal(account: AuthenticationRecord): msalCommon.AccountInfo;
export declare function msalToPublic(clientId: string, account: MsalAccountInfo): AuthenticationRecord;
/**
* Serializes an `AuthenticationRecord` into a string.
*
* The output of a serialized authentication record will contain the following properties:
*
* - "authority"
* - "homeAccountId"
* - "clientId"
* - "tenantId"
* - "username"
* - "version"
*
* To later convert this string to a serialized `AuthenticationRecord`, please use the exported function `deserializeAuthenticationRecord()`.
*/
export declare function serializeAuthenticationRecord(record: AuthenticationRecord): string;
/**
* Deserializes a previously serialized authentication record from a string into an object.
*
* The input string must contain the following properties:
*
* - "authority"
* - "homeAccountId"
* - "clientId"
* - "tenantId"
* - "username"
* - "version"
*
* If the version we receive is unsupported, an error will be thrown.
*
* At the moment, the only available version is: "1.0", which is always set when the authentication record is serialized.
*
* @param serializedRecord - Authentication record previously serialized into string.
* @returns AuthenticationRecord.
*/
export declare function deserializeAuthenticationRecord(serializedRecord: string): AuthenticationRecord;
//# sourceMappingURL=utils.d.ts.map
+1
View File
@@ -0,0 +1 @@
{"version":3,"file":"utils.d.ts","sourceRoot":"","sources":["../../../src/msal/utils.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,oBAAoB,EAAE,eAAe,EAAE,SAAS,EAAE,cAAc,EAAE,MAAM,YAAY,CAAC;AAEnG,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,oBAAoB,CAAC;AAM3D,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,eAAe,CAAC;AACnD,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,kBAAkB,CAAC;AACxD,OAAO,EAAE,UAAU,EAAE,MAAM,WAAW,CAAC;AAEvC,MAAM,WAAW,eAAe;IAC9B,CAAC,KAAK,EAAE,UAAU,CAAC,QAAQ,EAAE,OAAO,EAAE,MAAM,EAAE,WAAW,EAAE,OAAO,GAAG,IAAI,CAAC;CAC3E;AAaD;;;GAGG;AACH,wBAAgB,oBAAoB,CAClC,MAAM,EAAE,MAAM,GAAG,MAAM,EAAE,EACzB,SAAS,CAAC,EAAE,SAAS,GAAG,IAAI,EAC5B,eAAe,CAAC,EAAE,eAAe,GAChC,OAAO,CAAC,SAAS,IAAI,cAAc,CAkBrC;AAED;;;;;GAKG;AACH,wBAAgB,gBAAgB,CAAC,OAAO,CAAC,EAAE;IAAE,aAAa,CAAC,EAAE,MAAM,CAAA;CAAE,GAAG,MAAM,CAQ7E;AAED;;;GAGG;AACH,wBAAgB,YAAY,CAAC,QAAQ,EAAE,MAAM,EAAE,IAAI,CAAC,EAAE,MAAM,GAAG,MAAM,CAYpE;AAED;;;;;;GAMG;AACH,wBAAgB,mBAAmB,CACjC,QAAQ,EAAE,MAAM,EAChB,aAAa,EAAE,MAAM,EACrB,wBAAwB,CAAC,EAAE,OAAO,GACjC,MAAM,EAAE,CAKV;AAED;;;;GAIG;AACH,eAAO,MAAM,qBAAqB,EAAE,CAClC,MAAM,EAAE,gBAAgB,EACxB,QAAQ,CAAC,EAAE,MAAM,GAAG,SAAS,KAC1B,eAoBF,CAAC;AAEJ;;GAEG;AACH,wBAAgB,eAAe,CAAC,QAAQ,EAAE,aAAa,GAAG,SAAS,GAAG,UAAU,CAAC,QAAQ,CAcxF;AAED;;;;;;GAMG;AACH,wBAAgB,UAAU,IAAI,MAAM,CAEnC;AAED;;GAEG;AACH,wBAAgB,eAAe,CAC7B,MAAM,EAAE,MAAM,EAAE,EAChB,KAAK,EAAE,KAAK,EACZ,eAAe,CAAC,EAAE,eAAe,GAChC,KAAK,CA6CP;AAGD,wBAAgB,YAAY,CAAC,OAAO,EAAE,oBAAoB,GAAG,UAAU,CAAC,WAAW,CAQlF;AAED,wBAAgB,YAAY,CAAC,QAAQ,EAAE,MAAM,EAAE,OAAO,EAAE,eAAe,GAAG,oBAAoB,CAU7F;AAED;;;;;;;;;;;;;GAaG;AACH,wBAAgB,6BAA6B,CAAC,MAAM,EAAE,oBAAoB,GAAG,MAAM,CAElF;AAED;;;;;;;;;;;;;;;;;;GAkBG;AACH,wBAAgB,+BAA+B,CAAC,gBAAgB,EAAE,MAAM,GAAG,oBAAoB,CAQ9F"}
+253
View File
@@ -0,0 +1,253 @@
"use strict";
// Copyright (c) Microsoft Corporation.
// Licensed under the MIT License.
Object.defineProperty(exports, "__esModule", { value: true });
exports.defaultLoggerCallback = void 0;
exports.ensureValidMsalToken = ensureValidMsalToken;
exports.getAuthorityHost = getAuthorityHost;
exports.getAuthority = getAuthority;
exports.getKnownAuthorities = getKnownAuthorities;
exports.getMSALLogLevel = getMSALLogLevel;
exports.randomUUID = randomUUID;
exports.handleMsalError = handleMsalError;
exports.publicToMsal = publicToMsal;
exports.msalToPublic = msalToPublic;
exports.serializeAuthenticationRecord = serializeAuthenticationRecord;
exports.deserializeAuthenticationRecord = deserializeAuthenticationRecord;
const errors_js_1 = require("../errors.js");
const logging_js_1 = require("../util/logging.js");
const constants_js_1 = require("../constants.js");
const core_util_1 = require("@azure/core-util");
const abort_controller_1 = require("@azure/abort-controller");
const msal_js_1 = require("./msal.js");
/**
* @internal
*/
const logger = (0, logging_js_1.credentialLogger)("IdentityUtils");
/**
* Latest AuthenticationRecord version
* @internal
*/
const LatestAuthenticationRecordVersion = "1.0";
/**
* Ensures the validity of the MSAL token
* @internal
*/
function ensureValidMsalToken(scopes, msalToken, getTokenOptions) {
const error = (message) => {
logger.getToken.info(message);
return new errors_js_1.AuthenticationRequiredError({
scopes: Array.isArray(scopes) ? scopes : [scopes],
getTokenOptions,
message,
});
};
if (!msalToken) {
throw error("No response");
}
if (!msalToken.expiresOn) {
throw error(`Response had no "expiresOn" property.`);
}
if (!msalToken.accessToken) {
throw error(`Response had no "accessToken" property.`);
}
}
/**
* Returns the authority host from either the options bag or the AZURE_AUTHORITY_HOST environment variable.
*
* Defaults to {@link DefaultAuthorityHost}.
* @internal
*/
function getAuthorityHost(options) {
let authorityHost = options === null || options === void 0 ? void 0 : options.authorityHost;
if (!authorityHost && core_util_1.isNodeLike) {
authorityHost = process.env.AZURE_AUTHORITY_HOST;
}
return authorityHost !== null && authorityHost !== void 0 ? authorityHost : constants_js_1.DefaultAuthorityHost;
}
/**
* Generates a valid authority by combining a host with a tenantId.
* @internal
*/
function getAuthority(tenantId, host) {
if (!host) {
host = constants_js_1.DefaultAuthorityHost;
}
if (new RegExp(`${tenantId}/?$`).test(host)) {
return host;
}
if (host.endsWith("/")) {
return host + tenantId;
}
else {
return `${host}/${tenantId}`;
}
}
/**
* Generates the known authorities.
* If the Tenant Id is `adfs`, the authority can't be validated since the format won't match the expected one.
* For that reason, we have to force MSAL to disable validating the authority
* by sending it within the known authorities in the MSAL configuration.
* @internal
*/
function getKnownAuthorities(tenantId, authorityHost, disableInstanceDiscovery) {
if ((tenantId === "adfs" && authorityHost) || disableInstanceDiscovery) {
return [authorityHost];
}
return [];
}
/**
* Generates a logger that can be passed to the MSAL clients.
* @param credLogger - The logger of the credential.
* @internal
*/
const defaultLoggerCallback = (credLogger, platform = core_util_1.isNode ? "Node" : "Browser") => (level, message, containsPii) => {
if (containsPii) {
return;
}
switch (level) {
case msal_js_1.msalCommon.LogLevel.Error:
credLogger.info(`MSAL ${platform} V2 error: ${message}`);
return;
case msal_js_1.msalCommon.LogLevel.Info:
credLogger.info(`MSAL ${platform} V2 info message: ${message}`);
return;
case msal_js_1.msalCommon.LogLevel.Verbose:
credLogger.info(`MSAL ${platform} V2 verbose message: ${message}`);
return;
case msal_js_1.msalCommon.LogLevel.Warning:
credLogger.info(`MSAL ${platform} V2 warning: ${message}`);
return;
}
};
exports.defaultLoggerCallback = defaultLoggerCallback;
/**
* @internal
*/
function getMSALLogLevel(logLevel) {
switch (logLevel) {
case "error":
return msal_js_1.msalCommon.LogLevel.Error;
case "info":
return msal_js_1.msalCommon.LogLevel.Info;
case "verbose":
return msal_js_1.msalCommon.LogLevel.Verbose;
case "warning":
return msal_js_1.msalCommon.LogLevel.Warning;
default:
// default msal logging level should be Info
return msal_js_1.msalCommon.LogLevel.Info;
}
}
/**
* Wraps core-util's randomUUID in order to allow for mocking in tests.
* This prepares the library for the upcoming core-util update to ESM.
*
* @internal
* @returns A string containing a random UUID
*/
function randomUUID() {
return (0, core_util_1.randomUUID)();
}
/**
* Handles MSAL errors.
*/
function handleMsalError(scopes, error, getTokenOptions) {
if (error.name === "AuthError" ||
error.name === "ClientAuthError" ||
error.name === "BrowserAuthError") {
const msalError = error;
switch (msalError.errorCode) {
case "endpoints_resolution_error":
logger.info((0, logging_js_1.formatError)(scopes, error.message));
return new errors_js_1.CredentialUnavailableError(error.message);
case "device_code_polling_cancelled":
return new abort_controller_1.AbortError("The authentication has been aborted by the caller.");
case "consent_required":
case "interaction_required":
case "login_required":
logger.info((0, logging_js_1.formatError)(scopes, `Authentication returned errorCode ${msalError.errorCode}`));
break;
default:
logger.info((0, logging_js_1.formatError)(scopes, `Failed to acquire token: ${error.message}`));
break;
}
}
if (error.name === "ClientConfigurationError" ||
error.name === "BrowserConfigurationAuthError" ||
error.name === "AbortError" ||
error.name === "AuthenticationError") {
return error;
}
if (error.name === "NativeAuthError") {
logger.info((0, logging_js_1.formatError)(scopes, `Error from the native broker: ${error.message} with status code: ${error.statusCode}`));
return error;
}
return new errors_js_1.AuthenticationRequiredError({ scopes, getTokenOptions, message: error.message });
}
// transformations
function publicToMsal(account) {
return {
localAccountId: account.homeAccountId,
environment: account.authority,
username: account.username,
homeAccountId: account.homeAccountId,
tenantId: account.tenantId,
};
}
function msalToPublic(clientId, account) {
var _a;
const record = {
authority: (_a = account.environment) !== null && _a !== void 0 ? _a : constants_js_1.DefaultAuthority,
homeAccountId: account.homeAccountId,
tenantId: account.tenantId || constants_js_1.DefaultTenantId,
username: account.username,
clientId,
version: LatestAuthenticationRecordVersion,
};
return record;
}
/**
* Serializes an `AuthenticationRecord` into a string.
*
* The output of a serialized authentication record will contain the following properties:
*
* - "authority"
* - "homeAccountId"
* - "clientId"
* - "tenantId"
* - "username"
* - "version"
*
* To later convert this string to a serialized `AuthenticationRecord`, please use the exported function `deserializeAuthenticationRecord()`.
*/
function serializeAuthenticationRecord(record) {
return JSON.stringify(record);
}
/**
* Deserializes a previously serialized authentication record from a string into an object.
*
* The input string must contain the following properties:
*
* - "authority"
* - "homeAccountId"
* - "clientId"
* - "tenantId"
* - "username"
* - "version"
*
* If the version we receive is unsupported, an error will be thrown.
*
* At the moment, the only available version is: "1.0", which is always set when the authentication record is serialized.
*
* @param serializedRecord - Authentication record previously serialized into string.
* @returns AuthenticationRecord.
*/
function deserializeAuthenticationRecord(serializedRecord) {
const parsed = JSON.parse(serializedRecord);
if (parsed.version && parsed.version !== LatestAuthenticationRecordVersion) {
throw Error("Unsupported AuthenticationRecord version");
}
return parsed;
}
//# sourceMappingURL=utils.js.map
File diff suppressed because one or more lines are too long