@azure/msal-browser 3.20.0 → 3.21.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/app/IPublicClientApplication.d.ts +53 -53
- package/dist/app/IPublicClientApplication.mjs +105 -105
- package/dist/app/PublicClientApplication.d.ts +293 -293
- package/dist/app/PublicClientApplication.mjs +364 -364
- package/dist/app/PublicClientNext.d.ts +276 -276
- package/dist/app/PublicClientNext.mjs +354 -354
- package/dist/broker/nativeBroker/NativeMessageHandler.d.ts +62 -62
- package/dist/broker/nativeBroker/NativeMessageHandler.mjs +254 -254
- package/dist/broker/nativeBroker/NativeRequest.d.ts +45 -45
- package/dist/broker/nativeBroker/NativeResponse.d.ts +48 -48
- package/dist/broker/nativeBroker/NativeStatusCodes.d.ts +7 -7
- package/dist/broker/nativeBroker/NativeStatusCodes.mjs +11 -11
- package/dist/cache/AccountManager.d.ts +48 -48
- package/dist/cache/AccountManager.mjs +126 -126
- package/dist/cache/AsyncMemoryStorage.d.ts +50 -50
- package/dist/cache/AsyncMemoryStorage.mjs +131 -131
- package/dist/cache/BrowserCacheManager.d.ts +410 -385
- package/dist/cache/BrowserCacheManager.d.ts.map +1 -1
- package/dist/cache/BrowserCacheManager.mjs +1364 -1294
- package/dist/cache/BrowserCacheManager.mjs.map +1 -1
- package/dist/cache/BrowserStorage.d.ts +11 -11
- package/dist/cache/BrowserStorage.mjs +32 -32
- package/dist/cache/DatabaseStorage.d.ts +56 -56
- package/dist/cache/DatabaseStorage.mjs +200 -200
- package/dist/cache/IAsyncStorage.d.ts +27 -27
- package/dist/cache/ITokenCache.d.ts +11 -11
- package/dist/cache/IWindowStorage.d.ts +27 -27
- package/dist/cache/MemoryStorage.d.ts +11 -11
- package/dist/cache/MemoryStorage.mjs +31 -31
- package/dist/cache/TokenCache.d.ts +77 -77
- package/dist/cache/TokenCache.mjs +195 -195
- package/dist/config/Configuration.d.ts +213 -208
- package/dist/config/Configuration.d.ts.map +1 -1
- package/dist/config/Configuration.mjs +128 -128
- package/dist/config/Configuration.mjs.map +1 -1
- package/dist/controllers/ControllerFactory.d.ts +5 -5
- package/dist/controllers/ControllerFactory.mjs +25 -25
- package/dist/controllers/IController.d.ts +60 -60
- package/dist/controllers/NestedAppAuthController.d.ts +202 -202
- package/dist/controllers/NestedAppAuthController.mjs +473 -473
- package/dist/controllers/StandardController.d.ts +405 -405
- package/dist/controllers/StandardController.d.ts.map +1 -1
- package/dist/controllers/StandardController.mjs +1334 -1316
- package/dist/controllers/StandardController.mjs.map +1 -1
- package/dist/controllers/UnknownOperatingContextController.d.ts +86 -86
- package/dist/controllers/UnknownOperatingContextController.mjs +256 -256
- package/dist/crypto/BrowserCrypto.d.ts +52 -52
- package/dist/crypto/BrowserCrypto.mjs +151 -151
- package/dist/crypto/CryptoOps.d.ts +74 -74
- package/dist/crypto/CryptoOps.mjs +176 -176
- package/dist/crypto/PkceGenerator.d.ts +8 -8
- package/dist/crypto/PkceGenerator.mjs +54 -54
- package/dist/crypto/SignedHttpRequest.d.ts +30 -30
- package/dist/crypto/SignedHttpRequest.mjs +39 -39
- package/dist/encode/Base64Decode.d.ts +9 -9
- package/dist/encode/Base64Decode.mjs +36 -36
- package/dist/encode/Base64Encode.d.ts +19 -19
- package/dist/encode/Base64Encode.mjs +43 -43
- package/dist/error/BrowserAuthError.d.ts +256 -255
- package/dist/error/BrowserAuthError.d.ts.map +1 -1
- package/dist/error/BrowserAuthError.mjs +265 -264
- package/dist/error/BrowserAuthError.mjs.map +1 -1
- package/dist/error/BrowserAuthErrorCodes.d.ts +47 -46
- package/dist/error/BrowserAuthErrorCodes.d.ts.map +1 -1
- package/dist/error/BrowserAuthErrorCodes.mjs +53 -52
- package/dist/error/BrowserAuthErrorCodes.mjs.map +1 -1
- package/dist/error/BrowserConfigurationAuthError.d.ts +33 -33
- package/dist/error/BrowserConfigurationAuthError.mjs +40 -40
- package/dist/error/BrowserConfigurationAuthError.mjs.map +1 -1
- package/dist/error/BrowserConfigurationAuthErrorCodes.d.ts +3 -3
- package/dist/error/BrowserConfigurationAuthErrorCodes.mjs +7 -7
- package/dist/error/NativeAuthError.d.ts +29 -29
- package/dist/error/NativeAuthError.mjs +60 -60
- package/dist/error/NativeAuthErrorCodes.d.ts +2 -2
- package/dist/error/NativeAuthErrorCodes.mjs +6 -6
- package/dist/error/NestedAppAuthError.d.ts +14 -14
- package/dist/error/NestedAppAuthError.mjs +23 -23
- package/dist/event/EventHandler.d.ts +41 -41
- package/dist/event/EventHandler.mjs +125 -125
- package/dist/event/EventMessage.d.ts +25 -25
- package/dist/event/EventMessage.mjs +68 -68
- package/dist/event/EventType.d.ts +29 -29
- package/dist/event/EventType.mjs +32 -32
- package/dist/index.d.ts +40 -40
- package/dist/index.mjs +1 -1
- package/dist/interaction_client/BaseInteractionClient.d.ts +50 -50
- package/dist/interaction_client/BaseInteractionClient.mjs +106 -106
- package/dist/interaction_client/HybridSpaAuthorizationCodeClient.d.ts +4 -4
- package/dist/interaction_client/HybridSpaAuthorizationCodeClient.mjs +10 -10
- package/dist/interaction_client/NativeInteractionClient.d.ts +151 -151
- package/dist/interaction_client/NativeInteractionClient.mjs +621 -621
- package/dist/interaction_client/PopupClient.d.ts +118 -105
- package/dist/interaction_client/PopupClient.d.ts.map +1 -1
- package/dist/interaction_client/PopupClient.mjs +460 -434
- package/dist/interaction_client/PopupClient.mjs.map +1 -1
- package/dist/interaction_client/RedirectClient.d.ts +50 -50
- package/dist/interaction_client/RedirectClient.d.ts.map +1 -1
- package/dist/interaction_client/RedirectClient.mjs +349 -317
- package/dist/interaction_client/RedirectClient.mjs.map +1 -1
- package/dist/interaction_client/SilentAuthCodeClient.d.ts +23 -23
- package/dist/interaction_client/SilentAuthCodeClient.mjs +57 -57
- package/dist/interaction_client/SilentCacheClient.d.ts +16 -16
- package/dist/interaction_client/SilentCacheClient.mjs +42 -42
- package/dist/interaction_client/SilentIframeClient.d.ts +32 -32
- package/dist/interaction_client/SilentIframeClient.d.ts.map +1 -1
- package/dist/interaction_client/SilentIframeClient.mjs +111 -101
- package/dist/interaction_client/SilentIframeClient.mjs.map +1 -1
- package/dist/interaction_client/SilentRefreshClient.d.ts +20 -20
- package/dist/interaction_client/SilentRefreshClient.mjs +47 -47
- package/dist/interaction_client/StandardInteractionClient.d.ts +48 -48
- package/dist/interaction_client/StandardInteractionClient.mjs +199 -199
- package/dist/interaction_handler/InteractionHandler.d.ts +33 -33
- package/dist/interaction_handler/InteractionHandler.mjs +93 -93
- package/dist/interaction_handler/RedirectHandler.d.ts +32 -32
- package/dist/interaction_handler/RedirectHandler.d.ts.map +1 -1
- package/dist/interaction_handler/RedirectHandler.mjs +135 -134
- package/dist/interaction_handler/RedirectHandler.mjs.map +1 -1
- package/dist/interaction_handler/SilentHandler.d.ts +13 -13
- package/dist/interaction_handler/SilentHandler.mjs +134 -134
- package/dist/naa/AccountInfo.d.ts +11 -11
- package/dist/naa/AuthBridge.d.ts +8 -8
- package/dist/naa/AuthResult.d.ts +6 -6
- package/dist/naa/BridgeAccountContext.d.ts +12 -12
- package/dist/naa/BridgeCapabilities.d.ts +3 -3
- package/dist/naa/BridgeError.d.ts +9 -9
- package/dist/naa/BridgeError.mjs +7 -7
- package/dist/naa/BridgeProxy.d.ts +67 -67
- package/dist/naa/BridgeProxy.d.ts.map +1 -1
- package/dist/naa/BridgeProxy.mjs +153 -148
- package/dist/naa/BridgeProxy.mjs.map +1 -1
- package/dist/naa/BridgeRequest.d.ts +7 -7
- package/dist/naa/BridgeRequestEnvelope.d.ts +12 -12
- package/dist/naa/BridgeResponseEnvelope.d.ts +13 -13
- package/dist/naa/BridgeStatusCode.d.ts +11 -11
- package/dist/naa/BridgeStatusCode.mjs +14 -14
- package/dist/naa/IBridgeProxy.d.ts +10 -10
- package/dist/naa/InitContext.d.ts +8 -8
- package/dist/naa/TokenRequest.d.ts +18 -18
- package/dist/naa/TokenResponse.d.ts +13 -13
- package/dist/naa/mapping/NestedAppAuthAdapter.d.ts +35 -35
- package/dist/naa/mapping/NestedAppAuthAdapter.mjs +179 -179
- package/dist/navigation/INavigationClient.d.ts +16 -16
- package/dist/navigation/NavigationClient.d.ts +22 -22
- package/dist/navigation/NavigationClient.mjs +40 -40
- package/dist/navigation/NavigationOptions.d.ts +12 -12
- package/dist/network/FetchClient.d.ts +26 -26
- package/dist/network/FetchClient.mjs +99 -99
- package/dist/operatingcontext/BaseOperatingContext.d.ts +41 -41
- package/dist/operatingcontext/BaseOperatingContext.mjs +94 -94
- package/dist/operatingcontext/NestedAppOperatingContext.d.ts +34 -34
- package/dist/operatingcontext/NestedAppOperatingContext.mjs +71 -71
- package/dist/operatingcontext/StandardOperatingContext.d.ts +25 -25
- package/dist/operatingcontext/StandardOperatingContext.mjs +43 -43
- package/dist/operatingcontext/UnknownOperatingContext.d.ts +25 -25
- package/dist/operatingcontext/UnknownOperatingContext.mjs +42 -42
- package/dist/packageMetadata.d.ts +2 -2
- package/dist/packageMetadata.mjs +4 -4
- package/dist/request/AuthorizationCodeRequest.d.ts +8 -8
- package/dist/request/AuthorizationUrlRequest.d.ts +8 -8
- package/dist/request/ClearCacheRequest.d.ts +10 -10
- package/dist/request/EndSessionPopupRequest.d.ts +18 -18
- package/dist/request/EndSessionRequest.d.ts +15 -15
- package/dist/request/InitializeApplicationRequest.d.ts +8 -8
- package/dist/request/PopupRequest.d.ts +34 -34
- package/dist/request/PopupWindowAttributes.d.ts +15 -15
- package/dist/request/RedirectRequest.d.ts +40 -35
- package/dist/request/RedirectRequest.d.ts.map +1 -1
- package/dist/request/RequestHelpers.d.ts +13 -13
- package/dist/request/RequestHelpers.mjs +53 -53
- package/dist/request/SilentRequest.d.ts +33 -33
- package/dist/request/SsoSilentRequest.d.ts +29 -29
- package/dist/response/AuthenticationResult.d.ts +4 -4
- package/dist/response/ResponseHandler.d.ts +7 -7
- package/dist/response/ResponseHandler.mjs +36 -36
- package/dist/telemetry/BrowserPerformanceClient.d.ts +38 -34
- package/dist/telemetry/BrowserPerformanceClient.d.ts.map +1 -1
- package/dist/telemetry/BrowserPerformanceClient.mjs +163 -163
- package/dist/telemetry/BrowserPerformanceClient.mjs.map +1 -1
- package/dist/telemetry/BrowserPerformanceMeasurement.d.ts +21 -21
- package/dist/telemetry/BrowserPerformanceMeasurement.mjs +92 -92
- package/dist/utils/BrowserConstants.d.ts +182 -180
- package/dist/utils/BrowserConstants.d.ts.map +1 -1
- package/dist/utils/BrowserConstants.mjs +214 -212
- package/dist/utils/BrowserConstants.mjs.map +1 -1
- package/dist/utils/BrowserProtocolUtils.d.ts +11 -11
- package/dist/utils/BrowserProtocolUtils.mjs +21 -21
- package/dist/utils/BrowserUtils.d.ts +75 -75
- package/dist/utils/BrowserUtils.mjs +157 -157
- package/lib/msal-browser.cjs +19027 -18857
- package/lib/msal-browser.cjs.map +1 -1
- package/lib/msal-browser.js +19027 -18857
- package/lib/msal-browser.js.map +1 -1
- package/lib/msal-browser.min.js +62 -62
- package/package.json +2 -2
- package/src/cache/BrowserCacheManager.ts +95 -0
- package/src/config/Configuration.ts +9 -1
- package/src/controllers/StandardController.ts +30 -12
- package/src/error/BrowserAuthError.ts +2 -0
- package/src/error/BrowserAuthErrorCodes.ts +1 -0
- package/src/interaction_client/PopupClient.ts +202 -117
- package/src/interaction_client/RedirectClient.ts +62 -2
- package/src/interaction_client/SilentIframeClient.ts +41 -3
- package/src/interaction_handler/RedirectHandler.ts +1 -0
- package/src/naa/BridgeProxy.ts +7 -2
- package/src/packageMetadata.ts +1 -1
- package/src/request/RedirectRequest.ts +5 -0
- package/src/telemetry/BrowserPerformanceClient.ts +1 -1
- package/src/utils/BrowserConstants.ts +2 -0
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
/*! @azure/msal-browser v3.
|
|
1
|
+
/*! @azure/msal-browser v3.21.0 2024-08-13 */
|
|
2
2
|
'use strict';
|
|
3
3
|
import { DEFAULT_CRYPTO_IMPLEMENTATION, buildStaticAuthorityOptions, PerformanceEvents, TimeUtils, OIDC_DEFAULT_SCOPES, AccountEntity } from '@azure/msal-common';
|
|
4
4
|
import { InteractionType, DEFAULT_REQUEST } from '../utils/BrowserConstants.mjs';
|
|
@@ -10,478 +10,478 @@ import { EventType } from '../event/EventType.mjs';
|
|
|
10
10
|
import { BrowserCacheManager, DEFAULT_BROWSER_CACHE_MANAGER } from '../cache/BrowserCacheManager.mjs';
|
|
11
11
|
import { getAccount, setActiveAccount, getAllAccounts, getAccountByUsername, getAccountByHomeId, getAccountByLocalId, getActiveAccount } from '../cache/AccountManager.mjs';
|
|
12
12
|
|
|
13
|
-
/*
|
|
14
|
-
* Copyright (c) Microsoft Corporation. All rights reserved.
|
|
15
|
-
* Licensed under the MIT License.
|
|
16
|
-
*/
|
|
17
|
-
class NestedAppAuthController {
|
|
18
|
-
constructor(operatingContext) {
|
|
19
|
-
this.operatingContext = operatingContext;
|
|
20
|
-
const proxy = this.operatingContext.getBridgeProxy();
|
|
21
|
-
if (proxy !== undefined) {
|
|
22
|
-
this.bridgeProxy = proxy;
|
|
23
|
-
}
|
|
24
|
-
else {
|
|
25
|
-
throw new Error("unexpected: bridgeProxy is undefined");
|
|
26
|
-
}
|
|
27
|
-
// Set the configuration.
|
|
28
|
-
this.config = operatingContext.getConfig();
|
|
29
|
-
// Initialize logger
|
|
30
|
-
this.logger = this.operatingContext.getLogger();
|
|
31
|
-
// Initialize performance client
|
|
32
|
-
this.performanceClient = this.config.telemetry.client;
|
|
33
|
-
// Initialize the crypto class.
|
|
34
|
-
this.browserCrypto = operatingContext.isBrowserEnvironment()
|
|
35
|
-
? new CryptoOps(this.logger, this.performanceClient)
|
|
36
|
-
: DEFAULT_CRYPTO_IMPLEMENTATION;
|
|
37
|
-
// Initialize the browser storage class.
|
|
38
|
-
this.browserStorage = this.operatingContext.isBrowserEnvironment()
|
|
39
|
-
? new BrowserCacheManager(this.config.auth.clientId, this.config.cache, this.browserCrypto, this.logger, buildStaticAuthorityOptions(this.config.auth))
|
|
40
|
-
: DEFAULT_BROWSER_CACHE_MANAGER(this.config.auth.clientId, this.logger);
|
|
41
|
-
this.eventHandler = new EventHandler(this.logger, this.browserCrypto);
|
|
42
|
-
this.nestedAppAuthAdapter = new NestedAppAuthAdapter(this.config.auth.clientId, this.config.auth.clientCapabilities, this.browserCrypto, this.logger);
|
|
43
|
-
// Set the active account if available
|
|
44
|
-
const accountContext = this.bridgeProxy.getAccountContext();
|
|
45
|
-
if (accountContext) {
|
|
46
|
-
const cachedAccount = getAccount(accountContext, this.logger, this.browserStorage);
|
|
47
|
-
setActiveAccount(cachedAccount, this.browserStorage);
|
|
48
|
-
}
|
|
49
|
-
}
|
|
50
|
-
/**
|
|
51
|
-
* Returns the event handler instance
|
|
52
|
-
* @returns EventHandler
|
|
53
|
-
*/
|
|
54
|
-
getEventHandler() {
|
|
55
|
-
return this.eventHandler;
|
|
56
|
-
}
|
|
57
|
-
/**
|
|
58
|
-
* Factory function to create a new instance of NestedAppAuthController
|
|
59
|
-
* @param operatingContext
|
|
60
|
-
* @returns Promise<IController>
|
|
61
|
-
*/
|
|
62
|
-
static async createController(operatingContext) {
|
|
63
|
-
const controller = new NestedAppAuthController(operatingContext);
|
|
64
|
-
return Promise.resolve(controller);
|
|
65
|
-
}
|
|
66
|
-
/**
|
|
67
|
-
* Specific implementation of initialize function for NestedAppAuthController
|
|
68
|
-
* @returns
|
|
69
|
-
*/
|
|
70
|
-
initialize() {
|
|
71
|
-
// do nothing not required by this controller
|
|
72
|
-
return Promise.resolve();
|
|
73
|
-
}
|
|
74
|
-
/**
|
|
75
|
-
* Validate the incoming request and add correlationId if not present
|
|
76
|
-
* @param request
|
|
77
|
-
* @returns
|
|
78
|
-
*/
|
|
79
|
-
ensureValidRequest(request) {
|
|
80
|
-
if (request?.correlationId) {
|
|
81
|
-
return request;
|
|
82
|
-
}
|
|
83
|
-
return {
|
|
84
|
-
...request,
|
|
85
|
-
correlationId: this.browserCrypto.createNewGuid(),
|
|
86
|
-
};
|
|
87
|
-
}
|
|
88
|
-
/**
|
|
89
|
-
* Internal implementation of acquireTokenInteractive flow
|
|
90
|
-
* @param request
|
|
91
|
-
* @returns
|
|
92
|
-
*/
|
|
93
|
-
async acquireTokenInteractive(request) {
|
|
94
|
-
const validRequest = this.ensureValidRequest(request);
|
|
95
|
-
this.eventHandler.emitEvent(EventType.ACQUIRE_TOKEN_START, InteractionType.Popup, validRequest);
|
|
96
|
-
const atPopupMeasurement = this.performanceClient.startMeasurement(PerformanceEvents.AcquireTokenPopup, validRequest.correlationId);
|
|
97
|
-
atPopupMeasurement?.add({ nestedAppAuthRequest: true });
|
|
98
|
-
try {
|
|
99
|
-
const naaRequest = this.nestedAppAuthAdapter.toNaaTokenRequest(validRequest);
|
|
100
|
-
const reqTimestamp = TimeUtils.nowSeconds();
|
|
101
|
-
const response = await this.bridgeProxy.getTokenInteractive(naaRequest);
|
|
102
|
-
const result = this.nestedAppAuthAdapter.fromNaaTokenResponse(naaRequest, response, reqTimestamp);
|
|
103
|
-
// cache the tokens in the response
|
|
104
|
-
await this.hydrateCache(result, request);
|
|
105
|
-
this.browserStorage.setActiveAccount(result.account);
|
|
106
|
-
this.eventHandler.emitEvent(EventType.ACQUIRE_TOKEN_SUCCESS, InteractionType.Popup, result);
|
|
107
|
-
atPopupMeasurement.add({
|
|
108
|
-
accessTokenSize: result.accessToken.length,
|
|
109
|
-
idTokenSize: result.idToken.length,
|
|
110
|
-
});
|
|
111
|
-
atPopupMeasurement.end({
|
|
112
|
-
success: true,
|
|
113
|
-
requestId: result.requestId,
|
|
114
|
-
});
|
|
115
|
-
return result;
|
|
116
|
-
}
|
|
117
|
-
catch (e) {
|
|
118
|
-
const error = this.nestedAppAuthAdapter.fromBridgeError(e);
|
|
119
|
-
this.eventHandler.emitEvent(EventType.ACQUIRE_TOKEN_FAILURE, InteractionType.Popup, null, e);
|
|
120
|
-
atPopupMeasurement.end({
|
|
121
|
-
success: false,
|
|
122
|
-
}, e);
|
|
123
|
-
throw error;
|
|
124
|
-
}
|
|
125
|
-
}
|
|
126
|
-
/**
|
|
127
|
-
* Internal implementation of acquireTokenSilent flow
|
|
128
|
-
* @param request
|
|
129
|
-
* @returns
|
|
130
|
-
*/
|
|
131
|
-
async acquireTokenSilentInternal(request) {
|
|
132
|
-
const validRequest = this.ensureValidRequest(request);
|
|
133
|
-
this.eventHandler.emitEvent(EventType.ACQUIRE_TOKEN_START, InteractionType.Silent, validRequest);
|
|
134
|
-
// Look for tokens in the cache first
|
|
135
|
-
const result = await this.acquireTokenFromCache(validRequest);
|
|
136
|
-
if (result) {
|
|
137
|
-
this.eventHandler.emitEvent(EventType.ACQUIRE_TOKEN_SUCCESS, InteractionType.Silent, result);
|
|
138
|
-
return result;
|
|
139
|
-
}
|
|
140
|
-
// proceed with acquiring tokens via the host
|
|
141
|
-
const ssoSilentMeasurement = this.performanceClient.startMeasurement(PerformanceEvents.SsoSilent, validRequest.correlationId);
|
|
142
|
-
ssoSilentMeasurement?.increment({
|
|
143
|
-
visibilityChangeCount: 0,
|
|
144
|
-
});
|
|
145
|
-
ssoSilentMeasurement?.add({
|
|
146
|
-
nestedAppAuthRequest: true,
|
|
147
|
-
});
|
|
148
|
-
try {
|
|
149
|
-
const naaRequest = this.nestedAppAuthAdapter.toNaaTokenRequest(validRequest);
|
|
150
|
-
const reqTimestamp = TimeUtils.nowSeconds();
|
|
151
|
-
const response = await this.bridgeProxy.getTokenSilent(naaRequest);
|
|
152
|
-
const result = this.nestedAppAuthAdapter.fromNaaTokenResponse(naaRequest, response, reqTimestamp);
|
|
153
|
-
// cache the tokens in the response
|
|
154
|
-
await this.hydrateCache(result, request);
|
|
155
|
-
this.browserStorage.setActiveAccount(result.account);
|
|
156
|
-
this.eventHandler.emitEvent(EventType.ACQUIRE_TOKEN_SUCCESS, InteractionType.Silent, result);
|
|
157
|
-
ssoSilentMeasurement?.add({
|
|
158
|
-
accessTokenSize: result.accessToken.length,
|
|
159
|
-
idTokenSize: result.idToken.length,
|
|
160
|
-
});
|
|
161
|
-
ssoSilentMeasurement?.end({
|
|
162
|
-
success: true,
|
|
163
|
-
requestId: result.requestId,
|
|
164
|
-
});
|
|
165
|
-
return result;
|
|
166
|
-
}
|
|
167
|
-
catch (e) {
|
|
168
|
-
const error = this.nestedAppAuthAdapter.fromBridgeError(e);
|
|
169
|
-
this.eventHandler.emitEvent(EventType.ACQUIRE_TOKEN_FAILURE, InteractionType.Silent, null, e);
|
|
170
|
-
ssoSilentMeasurement?.end({
|
|
171
|
-
success: false,
|
|
172
|
-
}, e);
|
|
173
|
-
throw error;
|
|
174
|
-
}
|
|
175
|
-
}
|
|
176
|
-
/**
|
|
177
|
-
* acquires tokens from cache
|
|
178
|
-
* @param request
|
|
179
|
-
* @returns
|
|
180
|
-
*/
|
|
181
|
-
async acquireTokenFromCache(request) {
|
|
182
|
-
const atsMeasurement = this.performanceClient.startMeasurement(PerformanceEvents.AcquireTokenSilent, request.correlationId);
|
|
183
|
-
atsMeasurement?.add({
|
|
184
|
-
nestedAppAuthRequest: true,
|
|
185
|
-
});
|
|
186
|
-
const result = await this.acquireTokenFromCacheInternal(request);
|
|
187
|
-
if (result) {
|
|
188
|
-
this.eventHandler.emitEvent(EventType.ACQUIRE_TOKEN_SUCCESS, InteractionType.Silent, result);
|
|
189
|
-
atsMeasurement?.add({
|
|
190
|
-
accessTokenSize: result?.accessToken.length,
|
|
191
|
-
idTokenSize: result?.idToken.length,
|
|
192
|
-
});
|
|
193
|
-
atsMeasurement?.end({
|
|
194
|
-
success: true,
|
|
195
|
-
});
|
|
196
|
-
return result;
|
|
197
|
-
}
|
|
198
|
-
this.logger.error("Cached tokens are not found for the account, proceeding with silent token request.");
|
|
199
|
-
this.eventHandler.emitEvent(EventType.ACQUIRE_TOKEN_FAILURE, InteractionType.Silent, null);
|
|
200
|
-
atsMeasurement?.end({
|
|
201
|
-
success: false,
|
|
202
|
-
});
|
|
203
|
-
return null;
|
|
204
|
-
}
|
|
205
|
-
/**
|
|
206
|
-
*
|
|
207
|
-
* @param request
|
|
208
|
-
* @returns
|
|
209
|
-
*/
|
|
210
|
-
async acquireTokenFromCacheInternal(request) {
|
|
211
|
-
const accountContext = this.bridgeProxy.getAccountContext();
|
|
212
|
-
let currentAccount = null;
|
|
213
|
-
if (accountContext) {
|
|
214
|
-
const hubAccount = getAccount(accountContext, this.logger, this.browserStorage);
|
|
215
|
-
// always prioritize for hub account context, the reqirement of `request.account` will be removed soon
|
|
216
|
-
currentAccount = hubAccount || request.account;
|
|
217
|
-
}
|
|
218
|
-
// fall back to brokering if no cached account is found
|
|
219
|
-
if (!currentAccount) {
|
|
220
|
-
this.logger.verbose("No active account found, falling back to the host");
|
|
221
|
-
return Promise.resolve(null);
|
|
222
|
-
}
|
|
223
|
-
this.logger.verbose("active account found, attempting to acquire token silently");
|
|
224
|
-
const authRequest = {
|
|
225
|
-
...request,
|
|
226
|
-
correlationId: request.correlationId || this.browserCrypto.createNewGuid(),
|
|
227
|
-
authority: request.authority || currentAccount.environment,
|
|
228
|
-
scopes: request.scopes?.length
|
|
229
|
-
? request.scopes
|
|
230
|
-
: [...OIDC_DEFAULT_SCOPES],
|
|
231
|
-
};
|
|
232
|
-
// fetch access token and check for expiry
|
|
233
|
-
const tokenKeys = this.browserStorage.getTokenKeys();
|
|
234
|
-
const cachedAccessToken = this.browserStorage.getAccessToken(currentAccount, authRequest, tokenKeys, currentAccount.tenantId, this.performanceClient, authRequest.correlationId);
|
|
235
|
-
// If there is no access token, log it and return null
|
|
236
|
-
if (!cachedAccessToken) {
|
|
237
|
-
this.logger.verbose("No cached access token found");
|
|
238
|
-
return Promise.resolve(null);
|
|
239
|
-
// If access token has expired, remove the token from cache and return null
|
|
240
|
-
}
|
|
241
|
-
else if (TimeUtils.wasClockTurnedBack(cachedAccessToken.cachedAt) ||
|
|
242
|
-
TimeUtils.isTokenExpired(cachedAccessToken.expiresOn, this.config.system.tokenRenewalOffsetSeconds)) {
|
|
243
|
-
this.logger.verbose("Cached access token has expired, deleting all related tokens from cache");
|
|
244
|
-
const accountEntity = AccountEntity.createFromAccountInfo(currentAccount);
|
|
245
|
-
await this.browserStorage.removeAccountContext(accountEntity);
|
|
246
|
-
return Promise.resolve(null);
|
|
247
|
-
}
|
|
248
|
-
const cachedIdToken = this.browserStorage.getIdToken(currentAccount, tokenKeys, currentAccount.tenantId, this.performanceClient, authRequest.correlationId);
|
|
249
|
-
if (!cachedIdToken) {
|
|
250
|
-
this.logger.verbose("No cached id token found");
|
|
251
|
-
return Promise.resolve(null);
|
|
252
|
-
}
|
|
253
|
-
return this.nestedAppAuthAdapter.toAuthenticationResultFromCache(currentAccount, cachedIdToken, cachedAccessToken, authRequest, authRequest.correlationId);
|
|
254
|
-
}
|
|
255
|
-
/**
|
|
256
|
-
* acquireTokenPopup flow implementation
|
|
257
|
-
* @param request
|
|
258
|
-
* @returns
|
|
259
|
-
*/
|
|
260
|
-
async acquireTokenPopup(request) {
|
|
261
|
-
return this.acquireTokenInteractive(request);
|
|
262
|
-
}
|
|
263
|
-
/**
|
|
264
|
-
* acquireTokenRedirect flow is not supported in nested app auth
|
|
265
|
-
* @param request
|
|
266
|
-
*/
|
|
267
|
-
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
|
268
|
-
acquireTokenRedirect(request) {
|
|
269
|
-
throw NestedAppAuthError.createUnsupportedError();
|
|
270
|
-
}
|
|
271
|
-
/**
|
|
272
|
-
* acquireTokenSilent flow implementation
|
|
273
|
-
* @param silentRequest
|
|
274
|
-
* @returns
|
|
275
|
-
*/
|
|
276
|
-
async acquireTokenSilent(silentRequest) {
|
|
277
|
-
return this.acquireTokenSilentInternal(silentRequest);
|
|
278
|
-
}
|
|
279
|
-
/**
|
|
280
|
-
* Hybrid flow is not currently supported in nested app auth
|
|
281
|
-
* @param request
|
|
282
|
-
*/
|
|
283
|
-
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
|
284
|
-
acquireTokenByCode(request // eslint-disable-line @typescript-eslint/no-unused-vars
|
|
285
|
-
) {
|
|
286
|
-
throw NestedAppAuthError.createUnsupportedError();
|
|
287
|
-
}
|
|
288
|
-
/**
|
|
289
|
-
* acquireTokenNative flow is not currently supported in nested app auth
|
|
290
|
-
* @param request
|
|
291
|
-
* @param apiId
|
|
292
|
-
* @param accountId
|
|
293
|
-
*/
|
|
294
|
-
acquireTokenNative(request, apiId, // eslint-disable-line @typescript-eslint/no-unused-vars
|
|
295
|
-
accountId // eslint-disable-line @typescript-eslint/no-unused-vars
|
|
296
|
-
) {
|
|
297
|
-
throw NestedAppAuthError.createUnsupportedError();
|
|
298
|
-
}
|
|
299
|
-
/**
|
|
300
|
-
* acquireTokenByRefreshToken flow is not currently supported in nested app auth
|
|
301
|
-
* @param commonRequest
|
|
302
|
-
* @param silentRequest
|
|
303
|
-
*/
|
|
304
|
-
acquireTokenByRefreshToken(commonRequest, // eslint-disable-line @typescript-eslint/no-unused-vars
|
|
305
|
-
silentRequest // eslint-disable-line @typescript-eslint/no-unused-vars
|
|
306
|
-
) {
|
|
307
|
-
throw NestedAppAuthError.createUnsupportedError();
|
|
308
|
-
}
|
|
309
|
-
/**
|
|
310
|
-
* Adds event callbacks to array
|
|
311
|
-
* @param callback
|
|
312
|
-
*/
|
|
313
|
-
addEventCallback(callback) {
|
|
314
|
-
return this.eventHandler.addEventCallback(callback);
|
|
315
|
-
}
|
|
316
|
-
/**
|
|
317
|
-
* Removes callback with provided id from callback array
|
|
318
|
-
* @param callbackId
|
|
319
|
-
*/
|
|
320
|
-
removeEventCallback(callbackId) {
|
|
321
|
-
this.eventHandler.removeEventCallback(callbackId);
|
|
322
|
-
}
|
|
323
|
-
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
|
324
|
-
addPerformanceCallback(callback) {
|
|
325
|
-
throw NestedAppAuthError.createUnsupportedError();
|
|
326
|
-
}
|
|
327
|
-
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
|
328
|
-
removePerformanceCallback(callbackId) {
|
|
329
|
-
throw NestedAppAuthError.createUnsupportedError();
|
|
330
|
-
}
|
|
331
|
-
enableAccountStorageEvents() {
|
|
332
|
-
throw NestedAppAuthError.createUnsupportedError();
|
|
333
|
-
}
|
|
334
|
-
disableAccountStorageEvents() {
|
|
335
|
-
throw NestedAppAuthError.createUnsupportedError();
|
|
336
|
-
}
|
|
337
|
-
// #region Account APIs
|
|
338
|
-
/**
|
|
339
|
-
* Returns all the accounts in the cache that match the optional filter. If no filter is provided, all accounts are returned.
|
|
340
|
-
* @param accountFilter - (Optional) filter to narrow down the accounts returned
|
|
341
|
-
* @returns Array of AccountInfo objects in cache
|
|
342
|
-
*/
|
|
343
|
-
getAllAccounts(accountFilter) {
|
|
344
|
-
return getAllAccounts(this.logger, this.browserStorage, this.isBrowserEnv(), accountFilter);
|
|
345
|
-
}
|
|
346
|
-
/**
|
|
347
|
-
* Returns the first account found in the cache that matches the account filter passed in.
|
|
348
|
-
* @param accountFilter
|
|
349
|
-
* @returns The first account found in the cache matching the provided filter or null if no account could be found.
|
|
350
|
-
*/
|
|
351
|
-
getAccount(accountFilter) {
|
|
352
|
-
return getAccount(accountFilter, this.logger, this.browserStorage);
|
|
353
|
-
}
|
|
354
|
-
/**
|
|
355
|
-
* Returns the signed in account matching username.
|
|
356
|
-
* (the account object is created at the time of successful login)
|
|
357
|
-
* or null when no matching account is found.
|
|
358
|
-
* This API is provided for convenience but getAccountById should be used for best reliability
|
|
359
|
-
* @param username
|
|
360
|
-
* @returns The account object stored in MSAL
|
|
361
|
-
*/
|
|
362
|
-
getAccountByUsername(username) {
|
|
363
|
-
return getAccountByUsername(username, this.logger, this.browserStorage);
|
|
364
|
-
}
|
|
365
|
-
/**
|
|
366
|
-
* Returns the signed in account matching homeAccountId.
|
|
367
|
-
* (the account object is created at the time of successful login)
|
|
368
|
-
* or null when no matching account is found
|
|
369
|
-
* @param homeAccountId
|
|
370
|
-
* @returns The account object stored in MSAL
|
|
371
|
-
*/
|
|
372
|
-
getAccountByHomeId(homeAccountId) {
|
|
373
|
-
return getAccountByHomeId(homeAccountId, this.logger, this.browserStorage);
|
|
374
|
-
}
|
|
375
|
-
/**
|
|
376
|
-
* Returns the signed in account matching localAccountId.
|
|
377
|
-
* (the account object is created at the time of successful login)
|
|
378
|
-
* or null when no matching account is found
|
|
379
|
-
* @param localAccountId
|
|
380
|
-
* @returns The account object stored in MSAL
|
|
381
|
-
*/
|
|
382
|
-
getAccountByLocalId(localAccountId) {
|
|
383
|
-
return getAccountByLocalId(localAccountId, this.logger, this.browserStorage);
|
|
384
|
-
}
|
|
385
|
-
/**
|
|
386
|
-
* Sets the account to use as the active account. If no account is passed to the acquireToken APIs, then MSAL will use this active account.
|
|
387
|
-
* @param account
|
|
388
|
-
*/
|
|
389
|
-
setActiveAccount(account) {
|
|
390
|
-
/*
|
|
391
|
-
* StandardController uses this to allow the developer to set the active account
|
|
392
|
-
* in the nested app auth scenario the active account is controlled by the app hosting the nested app
|
|
393
|
-
*/
|
|
394
|
-
return setActiveAccount(account, this.browserStorage);
|
|
395
|
-
}
|
|
396
|
-
/**
|
|
397
|
-
* Gets the currently active account
|
|
398
|
-
*/
|
|
399
|
-
getActiveAccount() {
|
|
400
|
-
return getActiveAccount(this.browserStorage);
|
|
401
|
-
}
|
|
402
|
-
// #endregion
|
|
403
|
-
handleRedirectPromise(hash // eslint-disable-line @typescript-eslint/no-unused-vars
|
|
404
|
-
) {
|
|
405
|
-
return Promise.resolve(null);
|
|
406
|
-
}
|
|
407
|
-
loginPopup(request // eslint-disable-line @typescript-eslint/no-unused-vars
|
|
408
|
-
) {
|
|
409
|
-
return this.acquireTokenInteractive(request || DEFAULT_REQUEST);
|
|
410
|
-
}
|
|
411
|
-
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
|
412
|
-
loginRedirect(request) {
|
|
413
|
-
throw NestedAppAuthError.createUnsupportedError();
|
|
414
|
-
}
|
|
415
|
-
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
|
416
|
-
logout(logoutRequest) {
|
|
417
|
-
throw NestedAppAuthError.createUnsupportedError();
|
|
418
|
-
}
|
|
419
|
-
logoutRedirect(logoutRequest // eslint-disable-line @typescript-eslint/no-unused-vars
|
|
420
|
-
) {
|
|
421
|
-
throw NestedAppAuthError.createUnsupportedError();
|
|
422
|
-
}
|
|
423
|
-
logoutPopup(logoutRequest // eslint-disable-line @typescript-eslint/no-unused-vars
|
|
424
|
-
) {
|
|
425
|
-
throw NestedAppAuthError.createUnsupportedError();
|
|
426
|
-
}
|
|
427
|
-
ssoSilent(
|
|
428
|
-
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
|
429
|
-
request) {
|
|
430
|
-
return this.acquireTokenSilentInternal(request);
|
|
431
|
-
}
|
|
432
|
-
getTokenCache() {
|
|
433
|
-
throw NestedAppAuthError.createUnsupportedError();
|
|
434
|
-
}
|
|
435
|
-
/**
|
|
436
|
-
* Returns the logger instance
|
|
437
|
-
*/
|
|
438
|
-
getLogger() {
|
|
439
|
-
return this.logger;
|
|
440
|
-
}
|
|
441
|
-
/**
|
|
442
|
-
* Replaces the default logger set in configurations with new Logger with new configurations
|
|
443
|
-
* @param logger Logger instance
|
|
444
|
-
*/
|
|
445
|
-
setLogger(logger) {
|
|
446
|
-
this.logger = logger;
|
|
447
|
-
}
|
|
448
|
-
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
|
449
|
-
initializeWrapperLibrary(sku, version) {
|
|
450
|
-
/*
|
|
451
|
-
* Standard controller uses this to set the sku and version of the wrapper library in the storage
|
|
452
|
-
* we do nothing here
|
|
453
|
-
*/
|
|
454
|
-
return;
|
|
455
|
-
}
|
|
456
|
-
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
|
457
|
-
setNavigationClient(navigationClient) {
|
|
458
|
-
this.logger.warning("setNavigationClient is not supported in nested app auth");
|
|
459
|
-
}
|
|
460
|
-
getConfiguration() {
|
|
461
|
-
return this.config;
|
|
462
|
-
}
|
|
463
|
-
isBrowserEnv() {
|
|
464
|
-
return this.operatingContext.isBrowserEnvironment();
|
|
465
|
-
}
|
|
466
|
-
getBrowserCrypto() {
|
|
467
|
-
return this.browserCrypto;
|
|
468
|
-
}
|
|
469
|
-
getPerformanceClient() {
|
|
470
|
-
throw NestedAppAuthError.createUnsupportedError();
|
|
471
|
-
}
|
|
472
|
-
getRedirectResponse() {
|
|
473
|
-
throw NestedAppAuthError.createUnsupportedError();
|
|
474
|
-
}
|
|
475
|
-
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
|
476
|
-
async clearCache(logoutRequest) {
|
|
477
|
-
throw NestedAppAuthError.createUnsupportedError();
|
|
478
|
-
}
|
|
479
|
-
async hydrateCache(result, request) {
|
|
480
|
-
this.logger.verbose("hydrateCache called");
|
|
481
|
-
const accountEntity = AccountEntity.createFromAccountInfo(result.account, result.cloudGraphHostName, result.msGraphHost);
|
|
482
|
-
this.browserStorage.setAccount(accountEntity);
|
|
483
|
-
return this.browserStorage.hydrateCache(result, request);
|
|
484
|
-
}
|
|
13
|
+
/*
|
|
14
|
+
* Copyright (c) Microsoft Corporation. All rights reserved.
|
|
15
|
+
* Licensed under the MIT License.
|
|
16
|
+
*/
|
|
17
|
+
class NestedAppAuthController {
|
|
18
|
+
constructor(operatingContext) {
|
|
19
|
+
this.operatingContext = operatingContext;
|
|
20
|
+
const proxy = this.operatingContext.getBridgeProxy();
|
|
21
|
+
if (proxy !== undefined) {
|
|
22
|
+
this.bridgeProxy = proxy;
|
|
23
|
+
}
|
|
24
|
+
else {
|
|
25
|
+
throw new Error("unexpected: bridgeProxy is undefined");
|
|
26
|
+
}
|
|
27
|
+
// Set the configuration.
|
|
28
|
+
this.config = operatingContext.getConfig();
|
|
29
|
+
// Initialize logger
|
|
30
|
+
this.logger = this.operatingContext.getLogger();
|
|
31
|
+
// Initialize performance client
|
|
32
|
+
this.performanceClient = this.config.telemetry.client;
|
|
33
|
+
// Initialize the crypto class.
|
|
34
|
+
this.browserCrypto = operatingContext.isBrowserEnvironment()
|
|
35
|
+
? new CryptoOps(this.logger, this.performanceClient)
|
|
36
|
+
: DEFAULT_CRYPTO_IMPLEMENTATION;
|
|
37
|
+
// Initialize the browser storage class.
|
|
38
|
+
this.browserStorage = this.operatingContext.isBrowserEnvironment()
|
|
39
|
+
? new BrowserCacheManager(this.config.auth.clientId, this.config.cache, this.browserCrypto, this.logger, buildStaticAuthorityOptions(this.config.auth))
|
|
40
|
+
: DEFAULT_BROWSER_CACHE_MANAGER(this.config.auth.clientId, this.logger);
|
|
41
|
+
this.eventHandler = new EventHandler(this.logger, this.browserCrypto);
|
|
42
|
+
this.nestedAppAuthAdapter = new NestedAppAuthAdapter(this.config.auth.clientId, this.config.auth.clientCapabilities, this.browserCrypto, this.logger);
|
|
43
|
+
// Set the active account if available
|
|
44
|
+
const accountContext = this.bridgeProxy.getAccountContext();
|
|
45
|
+
if (accountContext) {
|
|
46
|
+
const cachedAccount = getAccount(accountContext, this.logger, this.browserStorage);
|
|
47
|
+
setActiveAccount(cachedAccount, this.browserStorage);
|
|
48
|
+
}
|
|
49
|
+
}
|
|
50
|
+
/**
|
|
51
|
+
* Returns the event handler instance
|
|
52
|
+
* @returns EventHandler
|
|
53
|
+
*/
|
|
54
|
+
getEventHandler() {
|
|
55
|
+
return this.eventHandler;
|
|
56
|
+
}
|
|
57
|
+
/**
|
|
58
|
+
* Factory function to create a new instance of NestedAppAuthController
|
|
59
|
+
* @param operatingContext
|
|
60
|
+
* @returns Promise<IController>
|
|
61
|
+
*/
|
|
62
|
+
static async createController(operatingContext) {
|
|
63
|
+
const controller = new NestedAppAuthController(operatingContext);
|
|
64
|
+
return Promise.resolve(controller);
|
|
65
|
+
}
|
|
66
|
+
/**
|
|
67
|
+
* Specific implementation of initialize function for NestedAppAuthController
|
|
68
|
+
* @returns
|
|
69
|
+
*/
|
|
70
|
+
initialize() {
|
|
71
|
+
// do nothing not required by this controller
|
|
72
|
+
return Promise.resolve();
|
|
73
|
+
}
|
|
74
|
+
/**
|
|
75
|
+
* Validate the incoming request and add correlationId if not present
|
|
76
|
+
* @param request
|
|
77
|
+
* @returns
|
|
78
|
+
*/
|
|
79
|
+
ensureValidRequest(request) {
|
|
80
|
+
if (request?.correlationId) {
|
|
81
|
+
return request;
|
|
82
|
+
}
|
|
83
|
+
return {
|
|
84
|
+
...request,
|
|
85
|
+
correlationId: this.browserCrypto.createNewGuid(),
|
|
86
|
+
};
|
|
87
|
+
}
|
|
88
|
+
/**
|
|
89
|
+
* Internal implementation of acquireTokenInteractive flow
|
|
90
|
+
* @param request
|
|
91
|
+
* @returns
|
|
92
|
+
*/
|
|
93
|
+
async acquireTokenInteractive(request) {
|
|
94
|
+
const validRequest = this.ensureValidRequest(request);
|
|
95
|
+
this.eventHandler.emitEvent(EventType.ACQUIRE_TOKEN_START, InteractionType.Popup, validRequest);
|
|
96
|
+
const atPopupMeasurement = this.performanceClient.startMeasurement(PerformanceEvents.AcquireTokenPopup, validRequest.correlationId);
|
|
97
|
+
atPopupMeasurement?.add({ nestedAppAuthRequest: true });
|
|
98
|
+
try {
|
|
99
|
+
const naaRequest = this.nestedAppAuthAdapter.toNaaTokenRequest(validRequest);
|
|
100
|
+
const reqTimestamp = TimeUtils.nowSeconds();
|
|
101
|
+
const response = await this.bridgeProxy.getTokenInteractive(naaRequest);
|
|
102
|
+
const result = this.nestedAppAuthAdapter.fromNaaTokenResponse(naaRequest, response, reqTimestamp);
|
|
103
|
+
// cache the tokens in the response
|
|
104
|
+
await this.hydrateCache(result, request);
|
|
105
|
+
this.browserStorage.setActiveAccount(result.account);
|
|
106
|
+
this.eventHandler.emitEvent(EventType.ACQUIRE_TOKEN_SUCCESS, InteractionType.Popup, result);
|
|
107
|
+
atPopupMeasurement.add({
|
|
108
|
+
accessTokenSize: result.accessToken.length,
|
|
109
|
+
idTokenSize: result.idToken.length,
|
|
110
|
+
});
|
|
111
|
+
atPopupMeasurement.end({
|
|
112
|
+
success: true,
|
|
113
|
+
requestId: result.requestId,
|
|
114
|
+
});
|
|
115
|
+
return result;
|
|
116
|
+
}
|
|
117
|
+
catch (e) {
|
|
118
|
+
const error = this.nestedAppAuthAdapter.fromBridgeError(e);
|
|
119
|
+
this.eventHandler.emitEvent(EventType.ACQUIRE_TOKEN_FAILURE, InteractionType.Popup, null, e);
|
|
120
|
+
atPopupMeasurement.end({
|
|
121
|
+
success: false,
|
|
122
|
+
}, e);
|
|
123
|
+
throw error;
|
|
124
|
+
}
|
|
125
|
+
}
|
|
126
|
+
/**
|
|
127
|
+
* Internal implementation of acquireTokenSilent flow
|
|
128
|
+
* @param request
|
|
129
|
+
* @returns
|
|
130
|
+
*/
|
|
131
|
+
async acquireTokenSilentInternal(request) {
|
|
132
|
+
const validRequest = this.ensureValidRequest(request);
|
|
133
|
+
this.eventHandler.emitEvent(EventType.ACQUIRE_TOKEN_START, InteractionType.Silent, validRequest);
|
|
134
|
+
// Look for tokens in the cache first
|
|
135
|
+
const result = await this.acquireTokenFromCache(validRequest);
|
|
136
|
+
if (result) {
|
|
137
|
+
this.eventHandler.emitEvent(EventType.ACQUIRE_TOKEN_SUCCESS, InteractionType.Silent, result);
|
|
138
|
+
return result;
|
|
139
|
+
}
|
|
140
|
+
// proceed with acquiring tokens via the host
|
|
141
|
+
const ssoSilentMeasurement = this.performanceClient.startMeasurement(PerformanceEvents.SsoSilent, validRequest.correlationId);
|
|
142
|
+
ssoSilentMeasurement?.increment({
|
|
143
|
+
visibilityChangeCount: 0,
|
|
144
|
+
});
|
|
145
|
+
ssoSilentMeasurement?.add({
|
|
146
|
+
nestedAppAuthRequest: true,
|
|
147
|
+
});
|
|
148
|
+
try {
|
|
149
|
+
const naaRequest = this.nestedAppAuthAdapter.toNaaTokenRequest(validRequest);
|
|
150
|
+
const reqTimestamp = TimeUtils.nowSeconds();
|
|
151
|
+
const response = await this.bridgeProxy.getTokenSilent(naaRequest);
|
|
152
|
+
const result = this.nestedAppAuthAdapter.fromNaaTokenResponse(naaRequest, response, reqTimestamp);
|
|
153
|
+
// cache the tokens in the response
|
|
154
|
+
await this.hydrateCache(result, request);
|
|
155
|
+
this.browserStorage.setActiveAccount(result.account);
|
|
156
|
+
this.eventHandler.emitEvent(EventType.ACQUIRE_TOKEN_SUCCESS, InteractionType.Silent, result);
|
|
157
|
+
ssoSilentMeasurement?.add({
|
|
158
|
+
accessTokenSize: result.accessToken.length,
|
|
159
|
+
idTokenSize: result.idToken.length,
|
|
160
|
+
});
|
|
161
|
+
ssoSilentMeasurement?.end({
|
|
162
|
+
success: true,
|
|
163
|
+
requestId: result.requestId,
|
|
164
|
+
});
|
|
165
|
+
return result;
|
|
166
|
+
}
|
|
167
|
+
catch (e) {
|
|
168
|
+
const error = this.nestedAppAuthAdapter.fromBridgeError(e);
|
|
169
|
+
this.eventHandler.emitEvent(EventType.ACQUIRE_TOKEN_FAILURE, InteractionType.Silent, null, e);
|
|
170
|
+
ssoSilentMeasurement?.end({
|
|
171
|
+
success: false,
|
|
172
|
+
}, e);
|
|
173
|
+
throw error;
|
|
174
|
+
}
|
|
175
|
+
}
|
|
176
|
+
/**
|
|
177
|
+
* acquires tokens from cache
|
|
178
|
+
* @param request
|
|
179
|
+
* @returns
|
|
180
|
+
*/
|
|
181
|
+
async acquireTokenFromCache(request) {
|
|
182
|
+
const atsMeasurement = this.performanceClient.startMeasurement(PerformanceEvents.AcquireTokenSilent, request.correlationId);
|
|
183
|
+
atsMeasurement?.add({
|
|
184
|
+
nestedAppAuthRequest: true,
|
|
185
|
+
});
|
|
186
|
+
const result = await this.acquireTokenFromCacheInternal(request);
|
|
187
|
+
if (result) {
|
|
188
|
+
this.eventHandler.emitEvent(EventType.ACQUIRE_TOKEN_SUCCESS, InteractionType.Silent, result);
|
|
189
|
+
atsMeasurement?.add({
|
|
190
|
+
accessTokenSize: result?.accessToken.length,
|
|
191
|
+
idTokenSize: result?.idToken.length,
|
|
192
|
+
});
|
|
193
|
+
atsMeasurement?.end({
|
|
194
|
+
success: true,
|
|
195
|
+
});
|
|
196
|
+
return result;
|
|
197
|
+
}
|
|
198
|
+
this.logger.error("Cached tokens are not found for the account, proceeding with silent token request.");
|
|
199
|
+
this.eventHandler.emitEvent(EventType.ACQUIRE_TOKEN_FAILURE, InteractionType.Silent, null);
|
|
200
|
+
atsMeasurement?.end({
|
|
201
|
+
success: false,
|
|
202
|
+
});
|
|
203
|
+
return null;
|
|
204
|
+
}
|
|
205
|
+
/**
|
|
206
|
+
*
|
|
207
|
+
* @param request
|
|
208
|
+
* @returns
|
|
209
|
+
*/
|
|
210
|
+
async acquireTokenFromCacheInternal(request) {
|
|
211
|
+
const accountContext = this.bridgeProxy.getAccountContext();
|
|
212
|
+
let currentAccount = null;
|
|
213
|
+
if (accountContext) {
|
|
214
|
+
const hubAccount = getAccount(accountContext, this.logger, this.browserStorage);
|
|
215
|
+
// always prioritize for hub account context, the reqirement of `request.account` will be removed soon
|
|
216
|
+
currentAccount = hubAccount || request.account;
|
|
217
|
+
}
|
|
218
|
+
// fall back to brokering if no cached account is found
|
|
219
|
+
if (!currentAccount) {
|
|
220
|
+
this.logger.verbose("No active account found, falling back to the host");
|
|
221
|
+
return Promise.resolve(null);
|
|
222
|
+
}
|
|
223
|
+
this.logger.verbose("active account found, attempting to acquire token silently");
|
|
224
|
+
const authRequest = {
|
|
225
|
+
...request,
|
|
226
|
+
correlationId: request.correlationId || this.browserCrypto.createNewGuid(),
|
|
227
|
+
authority: request.authority || currentAccount.environment,
|
|
228
|
+
scopes: request.scopes?.length
|
|
229
|
+
? request.scopes
|
|
230
|
+
: [...OIDC_DEFAULT_SCOPES],
|
|
231
|
+
};
|
|
232
|
+
// fetch access token and check for expiry
|
|
233
|
+
const tokenKeys = this.browserStorage.getTokenKeys();
|
|
234
|
+
const cachedAccessToken = this.browserStorage.getAccessToken(currentAccount, authRequest, tokenKeys, currentAccount.tenantId, this.performanceClient, authRequest.correlationId);
|
|
235
|
+
// If there is no access token, log it and return null
|
|
236
|
+
if (!cachedAccessToken) {
|
|
237
|
+
this.logger.verbose("No cached access token found");
|
|
238
|
+
return Promise.resolve(null);
|
|
239
|
+
// If access token has expired, remove the token from cache and return null
|
|
240
|
+
}
|
|
241
|
+
else if (TimeUtils.wasClockTurnedBack(cachedAccessToken.cachedAt) ||
|
|
242
|
+
TimeUtils.isTokenExpired(cachedAccessToken.expiresOn, this.config.system.tokenRenewalOffsetSeconds)) {
|
|
243
|
+
this.logger.verbose("Cached access token has expired, deleting all related tokens from cache");
|
|
244
|
+
const accountEntity = AccountEntity.createFromAccountInfo(currentAccount);
|
|
245
|
+
await this.browserStorage.removeAccountContext(accountEntity);
|
|
246
|
+
return Promise.resolve(null);
|
|
247
|
+
}
|
|
248
|
+
const cachedIdToken = this.browserStorage.getIdToken(currentAccount, tokenKeys, currentAccount.tenantId, this.performanceClient, authRequest.correlationId);
|
|
249
|
+
if (!cachedIdToken) {
|
|
250
|
+
this.logger.verbose("No cached id token found");
|
|
251
|
+
return Promise.resolve(null);
|
|
252
|
+
}
|
|
253
|
+
return this.nestedAppAuthAdapter.toAuthenticationResultFromCache(currentAccount, cachedIdToken, cachedAccessToken, authRequest, authRequest.correlationId);
|
|
254
|
+
}
|
|
255
|
+
/**
|
|
256
|
+
* acquireTokenPopup flow implementation
|
|
257
|
+
* @param request
|
|
258
|
+
* @returns
|
|
259
|
+
*/
|
|
260
|
+
async acquireTokenPopup(request) {
|
|
261
|
+
return this.acquireTokenInteractive(request);
|
|
262
|
+
}
|
|
263
|
+
/**
|
|
264
|
+
* acquireTokenRedirect flow is not supported in nested app auth
|
|
265
|
+
* @param request
|
|
266
|
+
*/
|
|
267
|
+
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
|
268
|
+
acquireTokenRedirect(request) {
|
|
269
|
+
throw NestedAppAuthError.createUnsupportedError();
|
|
270
|
+
}
|
|
271
|
+
/**
|
|
272
|
+
* acquireTokenSilent flow implementation
|
|
273
|
+
* @param silentRequest
|
|
274
|
+
* @returns
|
|
275
|
+
*/
|
|
276
|
+
async acquireTokenSilent(silentRequest) {
|
|
277
|
+
return this.acquireTokenSilentInternal(silentRequest);
|
|
278
|
+
}
|
|
279
|
+
/**
|
|
280
|
+
* Hybrid flow is not currently supported in nested app auth
|
|
281
|
+
* @param request
|
|
282
|
+
*/
|
|
283
|
+
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
|
284
|
+
acquireTokenByCode(request // eslint-disable-line @typescript-eslint/no-unused-vars
|
|
285
|
+
) {
|
|
286
|
+
throw NestedAppAuthError.createUnsupportedError();
|
|
287
|
+
}
|
|
288
|
+
/**
|
|
289
|
+
* acquireTokenNative flow is not currently supported in nested app auth
|
|
290
|
+
* @param request
|
|
291
|
+
* @param apiId
|
|
292
|
+
* @param accountId
|
|
293
|
+
*/
|
|
294
|
+
acquireTokenNative(request, apiId, // eslint-disable-line @typescript-eslint/no-unused-vars
|
|
295
|
+
accountId // eslint-disable-line @typescript-eslint/no-unused-vars
|
|
296
|
+
) {
|
|
297
|
+
throw NestedAppAuthError.createUnsupportedError();
|
|
298
|
+
}
|
|
299
|
+
/**
|
|
300
|
+
* acquireTokenByRefreshToken flow is not currently supported in nested app auth
|
|
301
|
+
* @param commonRequest
|
|
302
|
+
* @param silentRequest
|
|
303
|
+
*/
|
|
304
|
+
acquireTokenByRefreshToken(commonRequest, // eslint-disable-line @typescript-eslint/no-unused-vars
|
|
305
|
+
silentRequest // eslint-disable-line @typescript-eslint/no-unused-vars
|
|
306
|
+
) {
|
|
307
|
+
throw NestedAppAuthError.createUnsupportedError();
|
|
308
|
+
}
|
|
309
|
+
/**
|
|
310
|
+
* Adds event callbacks to array
|
|
311
|
+
* @param callback
|
|
312
|
+
*/
|
|
313
|
+
addEventCallback(callback) {
|
|
314
|
+
return this.eventHandler.addEventCallback(callback);
|
|
315
|
+
}
|
|
316
|
+
/**
|
|
317
|
+
* Removes callback with provided id from callback array
|
|
318
|
+
* @param callbackId
|
|
319
|
+
*/
|
|
320
|
+
removeEventCallback(callbackId) {
|
|
321
|
+
this.eventHandler.removeEventCallback(callbackId);
|
|
322
|
+
}
|
|
323
|
+
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
|
324
|
+
addPerformanceCallback(callback) {
|
|
325
|
+
throw NestedAppAuthError.createUnsupportedError();
|
|
326
|
+
}
|
|
327
|
+
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
|
328
|
+
removePerformanceCallback(callbackId) {
|
|
329
|
+
throw NestedAppAuthError.createUnsupportedError();
|
|
330
|
+
}
|
|
331
|
+
enableAccountStorageEvents() {
|
|
332
|
+
throw NestedAppAuthError.createUnsupportedError();
|
|
333
|
+
}
|
|
334
|
+
disableAccountStorageEvents() {
|
|
335
|
+
throw NestedAppAuthError.createUnsupportedError();
|
|
336
|
+
}
|
|
337
|
+
// #region Account APIs
|
|
338
|
+
/**
|
|
339
|
+
* Returns all the accounts in the cache that match the optional filter. If no filter is provided, all accounts are returned.
|
|
340
|
+
* @param accountFilter - (Optional) filter to narrow down the accounts returned
|
|
341
|
+
* @returns Array of AccountInfo objects in cache
|
|
342
|
+
*/
|
|
343
|
+
getAllAccounts(accountFilter) {
|
|
344
|
+
return getAllAccounts(this.logger, this.browserStorage, this.isBrowserEnv(), accountFilter);
|
|
345
|
+
}
|
|
346
|
+
/**
|
|
347
|
+
* Returns the first account found in the cache that matches the account filter passed in.
|
|
348
|
+
* @param accountFilter
|
|
349
|
+
* @returns The first account found in the cache matching the provided filter or null if no account could be found.
|
|
350
|
+
*/
|
|
351
|
+
getAccount(accountFilter) {
|
|
352
|
+
return getAccount(accountFilter, this.logger, this.browserStorage);
|
|
353
|
+
}
|
|
354
|
+
/**
|
|
355
|
+
* Returns the signed in account matching username.
|
|
356
|
+
* (the account object is created at the time of successful login)
|
|
357
|
+
* or null when no matching account is found.
|
|
358
|
+
* This API is provided for convenience but getAccountById should be used for best reliability
|
|
359
|
+
* @param username
|
|
360
|
+
* @returns The account object stored in MSAL
|
|
361
|
+
*/
|
|
362
|
+
getAccountByUsername(username) {
|
|
363
|
+
return getAccountByUsername(username, this.logger, this.browserStorage);
|
|
364
|
+
}
|
|
365
|
+
/**
|
|
366
|
+
* Returns the signed in account matching homeAccountId.
|
|
367
|
+
* (the account object is created at the time of successful login)
|
|
368
|
+
* or null when no matching account is found
|
|
369
|
+
* @param homeAccountId
|
|
370
|
+
* @returns The account object stored in MSAL
|
|
371
|
+
*/
|
|
372
|
+
getAccountByHomeId(homeAccountId) {
|
|
373
|
+
return getAccountByHomeId(homeAccountId, this.logger, this.browserStorage);
|
|
374
|
+
}
|
|
375
|
+
/**
|
|
376
|
+
* Returns the signed in account matching localAccountId.
|
|
377
|
+
* (the account object is created at the time of successful login)
|
|
378
|
+
* or null when no matching account is found
|
|
379
|
+
* @param localAccountId
|
|
380
|
+
* @returns The account object stored in MSAL
|
|
381
|
+
*/
|
|
382
|
+
getAccountByLocalId(localAccountId) {
|
|
383
|
+
return getAccountByLocalId(localAccountId, this.logger, this.browserStorage);
|
|
384
|
+
}
|
|
385
|
+
/**
|
|
386
|
+
* Sets the account to use as the active account. If no account is passed to the acquireToken APIs, then MSAL will use this active account.
|
|
387
|
+
* @param account
|
|
388
|
+
*/
|
|
389
|
+
setActiveAccount(account) {
|
|
390
|
+
/*
|
|
391
|
+
* StandardController uses this to allow the developer to set the active account
|
|
392
|
+
* in the nested app auth scenario the active account is controlled by the app hosting the nested app
|
|
393
|
+
*/
|
|
394
|
+
return setActiveAccount(account, this.browserStorage);
|
|
395
|
+
}
|
|
396
|
+
/**
|
|
397
|
+
* Gets the currently active account
|
|
398
|
+
*/
|
|
399
|
+
getActiveAccount() {
|
|
400
|
+
return getActiveAccount(this.browserStorage);
|
|
401
|
+
}
|
|
402
|
+
// #endregion
|
|
403
|
+
handleRedirectPromise(hash // eslint-disable-line @typescript-eslint/no-unused-vars
|
|
404
|
+
) {
|
|
405
|
+
return Promise.resolve(null);
|
|
406
|
+
}
|
|
407
|
+
loginPopup(request // eslint-disable-line @typescript-eslint/no-unused-vars
|
|
408
|
+
) {
|
|
409
|
+
return this.acquireTokenInteractive(request || DEFAULT_REQUEST);
|
|
410
|
+
}
|
|
411
|
+
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
|
412
|
+
loginRedirect(request) {
|
|
413
|
+
throw NestedAppAuthError.createUnsupportedError();
|
|
414
|
+
}
|
|
415
|
+
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
|
416
|
+
logout(logoutRequest) {
|
|
417
|
+
throw NestedAppAuthError.createUnsupportedError();
|
|
418
|
+
}
|
|
419
|
+
logoutRedirect(logoutRequest // eslint-disable-line @typescript-eslint/no-unused-vars
|
|
420
|
+
) {
|
|
421
|
+
throw NestedAppAuthError.createUnsupportedError();
|
|
422
|
+
}
|
|
423
|
+
logoutPopup(logoutRequest // eslint-disable-line @typescript-eslint/no-unused-vars
|
|
424
|
+
) {
|
|
425
|
+
throw NestedAppAuthError.createUnsupportedError();
|
|
426
|
+
}
|
|
427
|
+
ssoSilent(
|
|
428
|
+
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
|
429
|
+
request) {
|
|
430
|
+
return this.acquireTokenSilentInternal(request);
|
|
431
|
+
}
|
|
432
|
+
getTokenCache() {
|
|
433
|
+
throw NestedAppAuthError.createUnsupportedError();
|
|
434
|
+
}
|
|
435
|
+
/**
|
|
436
|
+
* Returns the logger instance
|
|
437
|
+
*/
|
|
438
|
+
getLogger() {
|
|
439
|
+
return this.logger;
|
|
440
|
+
}
|
|
441
|
+
/**
|
|
442
|
+
* Replaces the default logger set in configurations with new Logger with new configurations
|
|
443
|
+
* @param logger Logger instance
|
|
444
|
+
*/
|
|
445
|
+
setLogger(logger) {
|
|
446
|
+
this.logger = logger;
|
|
447
|
+
}
|
|
448
|
+
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
|
449
|
+
initializeWrapperLibrary(sku, version) {
|
|
450
|
+
/*
|
|
451
|
+
* Standard controller uses this to set the sku and version of the wrapper library in the storage
|
|
452
|
+
* we do nothing here
|
|
453
|
+
*/
|
|
454
|
+
return;
|
|
455
|
+
}
|
|
456
|
+
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
|
457
|
+
setNavigationClient(navigationClient) {
|
|
458
|
+
this.logger.warning("setNavigationClient is not supported in nested app auth");
|
|
459
|
+
}
|
|
460
|
+
getConfiguration() {
|
|
461
|
+
return this.config;
|
|
462
|
+
}
|
|
463
|
+
isBrowserEnv() {
|
|
464
|
+
return this.operatingContext.isBrowserEnvironment();
|
|
465
|
+
}
|
|
466
|
+
getBrowserCrypto() {
|
|
467
|
+
return this.browserCrypto;
|
|
468
|
+
}
|
|
469
|
+
getPerformanceClient() {
|
|
470
|
+
throw NestedAppAuthError.createUnsupportedError();
|
|
471
|
+
}
|
|
472
|
+
getRedirectResponse() {
|
|
473
|
+
throw NestedAppAuthError.createUnsupportedError();
|
|
474
|
+
}
|
|
475
|
+
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
|
476
|
+
async clearCache(logoutRequest) {
|
|
477
|
+
throw NestedAppAuthError.createUnsupportedError();
|
|
478
|
+
}
|
|
479
|
+
async hydrateCache(result, request) {
|
|
480
|
+
this.logger.verbose("hydrateCache called");
|
|
481
|
+
const accountEntity = AccountEntity.createFromAccountInfo(result.account, result.cloudGraphHostName, result.msGraphHost);
|
|
482
|
+
this.browserStorage.setAccount(accountEntity);
|
|
483
|
+
return this.browserStorage.hydrateCache(result, request);
|
|
484
|
+
}
|
|
485
485
|
}
|
|
486
486
|
|
|
487
487
|
export { NestedAppAuthController };
|