@equinor/fusion-framework-module-msal 10.0.2 → 11.0.0-next.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/CHANGELOG.md +163 -0
- package/README.md +17 -368
- package/dist/esm/MsalConfigurator.js +176 -88
- package/dist/esm/MsalConfigurator.js.map +1 -1
- package/dist/esm/__tests__/MsalConfigurator.test.js +75 -0
- package/dist/esm/__tests__/MsalConfigurator.test.js.map +1 -1
- package/dist/esm/__tests__/create-proxy-provider.test.js +53 -0
- package/dist/esm/__tests__/create-proxy-provider.test.js.map +1 -0
- package/dist/esm/__tests__/mock/msal-mock.test.js +399 -0
- package/dist/esm/__tests__/mock/msal-mock.test.js.map +1 -0
- package/dist/esm/index.js +5 -0
- package/dist/esm/index.js.map +1 -1
- package/dist/esm/mock/MsalMockClient.js +467 -0
- package/dist/esm/mock/MsalMockClient.js.map +1 -0
- package/dist/esm/mock/MsalMockConfigurator.js +187 -0
- package/dist/esm/mock/MsalMockConfigurator.js.map +1 -0
- package/dist/esm/mock/create-mock-token.js +60 -0
- package/dist/esm/mock/create-mock-token.js.map +1 -0
- package/dist/esm/mock/create-msal-mock-client.js +20 -0
- package/dist/esm/mock/create-msal-mock-client.js.map +1 -0
- package/dist/esm/mock/decode-jwt-segment.js +22 -0
- package/dist/esm/mock/decode-jwt-segment.js.map +1 -0
- package/dist/esm/mock/index.js +30 -0
- package/dist/esm/mock/index.js.map +1 -0
- package/dist/esm/mock/module.js +38 -0
- package/dist/esm/mock/module.js.map +1 -0
- package/dist/esm/msal-config-schema.js +37 -0
- package/dist/esm/msal-config-schema.js.map +1 -0
- package/dist/esm/telemetry-config-schema.js +16 -0
- package/dist/esm/telemetry-config-schema.js.map +1 -0
- package/dist/esm/version.js +1 -1
- package/dist/esm/version.js.map +1 -1
- package/dist/esm/versioning/resolve-version.js +0 -1
- package/dist/esm/versioning/resolve-version.js.map +1 -1
- package/dist/tsconfig.tsbuildinfo +1 -1
- package/dist/types/MsalConfigurator.d.ts +96 -20
- package/dist/types/__tests__/create-proxy-provider.test.d.ts +1 -0
- package/dist/types/__tests__/mock/msal-mock.test.d.ts +1 -0
- package/dist/types/index.d.ts +5 -0
- package/dist/types/mock/MsalMockClient.d.ts +270 -0
- package/dist/types/mock/MsalMockConfigurator.d.ts +156 -0
- package/dist/types/mock/create-mock-token.d.ts +54 -0
- package/dist/types/mock/create-msal-mock-client.d.ts +14 -0
- package/dist/types/mock/decode-jwt-segment.d.ts +13 -0
- package/dist/types/mock/index.d.ts +29 -0
- package/dist/types/mock/module.d.ts +35 -0
- package/dist/types/msal-config-schema.d.ts +64 -0
- package/dist/types/telemetry-config-schema.d.ts +8 -0
- package/dist/types/version.d.ts +1 -1
- package/docs/api-reference.md +85 -0
- package/docs/auth-code-flow.md +86 -0
- package/docs/migration-v2-to-v4.md +115 -0
- package/docs/testing.md +167 -0
- package/docs/troubleshooting.md +17 -0
- package/docs/version-management.md +67 -0
- package/package.json +12 -5
- package/src/MsalConfigurator.ts +202 -115
- package/src/__tests__/MsalConfigurator.test.ts +106 -0
- package/src/__tests__/create-proxy-provider.test.ts +77 -0
- package/src/__tests__/mock/msal-mock.test.ts +544 -0
- package/src/index.ts +6 -0
- package/src/mock/MsalMockClient.ts +599 -0
- package/src/mock/MsalMockConfigurator.ts +241 -0
- package/src/mock/create-mock-token.ts +92 -0
- package/src/mock/create-msal-mock-client.ts +25 -0
- package/src/mock/decode-jwt-segment.ts +22 -0
- package/src/mock/index.ts +29 -0
- package/src/mock/module.ts +54 -0
- package/src/msal-config-schema.ts +81 -0
- package/src/telemetry-config-schema.ts +25 -0
- package/src/version.ts +1 -1
- package/src/versioning/resolve-version.ts +0 -1
- package/vitest.config.ts +1 -1
|
@@ -1,43 +1,12 @@
|
|
|
1
|
-
import
|
|
2
|
-
import {
|
|
3
|
-
import
|
|
4
|
-
import { TelemetryLevel, } from '@equinor/fusion-framework-module-telemetry';
|
|
1
|
+
import { BaseConfigBuilder, } from '@equinor/fusion-framework-module';
|
|
2
|
+
import { TelemetryLevel } from '@equinor/fusion-framework-module-telemetry';
|
|
3
|
+
import { CacheLookupPolicy, LogLevel } from '@azure/msal-browser';
|
|
5
4
|
import { MsalClient } from './MsalClient';
|
|
6
5
|
import { createClientLogCallback } from './create-client-log-callback';
|
|
7
|
-
import { CacheLookupPolicy, LogLevel } from '@azure/msal-browser';
|
|
8
6
|
import { version } from './version';
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
* @internal
|
|
13
|
-
*/
|
|
14
|
-
const TelemetryConfigSchema = z.object({
|
|
15
|
-
provider: z.custom().optional(),
|
|
16
|
-
metadata: z.record(z.string(), z.unknown()).optional().default({
|
|
17
|
-
module: 'msal',
|
|
18
|
-
version,
|
|
19
|
-
}),
|
|
20
|
-
scope: z.array(z.string()).optional().default(['framework', 'authentication']),
|
|
21
|
-
});
|
|
22
|
-
/**
|
|
23
|
-
* Zod schema for MSAL module configuration validation.
|
|
24
|
-
*
|
|
25
|
-
* @internal
|
|
26
|
-
*/
|
|
27
|
-
const MsalConfigSchema = z.object({
|
|
28
|
-
client: z.custom().optional(),
|
|
29
|
-
provider: z.custom().optional(),
|
|
30
|
-
requiresAuth: z.boolean().optional(),
|
|
31
|
-
redirectUri: z.string().optional(),
|
|
32
|
-
loginHint: z.string().optional(),
|
|
33
|
-
authCode: z.string().optional(),
|
|
34
|
-
cacheLookupPolicy: z
|
|
35
|
-
.custom((val) => typeof val === 'number' &&
|
|
36
|
-
Object.values(CacheLookupPolicy).includes(val))
|
|
37
|
-
.optional(),
|
|
38
|
-
version: z.string().transform((x) => String(semver.coerce(x))),
|
|
39
|
-
telemetry: TelemetryConfigSchema,
|
|
40
|
-
});
|
|
7
|
+
import { MsalConfigSchema } from './msal-config-schema';
|
|
8
|
+
export { MsalConfigSchema, } from './msal-config-schema';
|
|
9
|
+
export { TelemetryConfigSchema } from './telemetry-config-schema';
|
|
41
10
|
/**
|
|
42
11
|
* Configuration builder for MSAL v4 authentication module.
|
|
43
12
|
*
|
|
@@ -53,6 +22,7 @@ const MsalConfigSchema = z.object({
|
|
|
53
22
|
*/
|
|
54
23
|
export class MsalConfigurator extends BaseConfigBuilder {
|
|
55
24
|
#msalConfig;
|
|
25
|
+
#client;
|
|
56
26
|
/**
|
|
57
27
|
* The MSAL module version being configured.
|
|
58
28
|
*
|
|
@@ -79,6 +49,9 @@ export class MsalConfigurator extends BaseConfigBuilder {
|
|
|
79
49
|
return telemetry;
|
|
80
50
|
}
|
|
81
51
|
});
|
|
52
|
+
// Always resolve the configured client instance through the builder.
|
|
53
|
+
// This keeps the client getter live and avoids re-registering the same config key.
|
|
54
|
+
this._set('client', async () => this.#client);
|
|
82
55
|
// Default cache lookup policy to AccessTokenAndRefreshToken to avoid iframe fallback delays
|
|
83
56
|
this._set('cacheLookupPolicy', async () => CacheLookupPolicy.AccessTokenAndRefreshToken);
|
|
84
57
|
}
|
|
@@ -106,6 +79,22 @@ export class MsalConfigurator extends BaseConfigBuilder {
|
|
|
106
79
|
this.#msalConfig = config;
|
|
107
80
|
return this;
|
|
108
81
|
}
|
|
82
|
+
/**
|
|
83
|
+
* Returns the client configuration declared through
|
|
84
|
+
* {@link MsalConfigurator.setClientConfig | setClientConfig}, if any.
|
|
85
|
+
*
|
|
86
|
+
* @remarks
|
|
87
|
+
* This is the configuration as declared, not the resolved one a client is
|
|
88
|
+
* built from — see
|
|
89
|
+
* {@link MsalConfigurator._createClientConfig | _createClientConfig} for that.
|
|
90
|
+
* Reading it is how a subclass can tell "nothing was declared" apart from
|
|
91
|
+
* "declared, and here it is", without re-deriving that from a resolved value.
|
|
92
|
+
*
|
|
93
|
+
* @returns The declared client configuration, or `undefined` when none was declared.
|
|
94
|
+
*/
|
|
95
|
+
getClientConfig() {
|
|
96
|
+
return this.#msalConfig;
|
|
97
|
+
}
|
|
109
98
|
/**
|
|
110
99
|
* Sets the cache lookup policy used for every silent token acquisition.
|
|
111
100
|
*
|
|
@@ -239,9 +228,21 @@ export class MsalConfigurator extends BaseConfigBuilder {
|
|
|
239
228
|
* ```
|
|
240
229
|
*/
|
|
241
230
|
setClient(client) {
|
|
242
|
-
this
|
|
231
|
+
this.#client = client;
|
|
243
232
|
return this;
|
|
244
233
|
}
|
|
234
|
+
/**
|
|
235
|
+
* Returns the currently configured MSAL client, if one has been set.
|
|
236
|
+
*
|
|
237
|
+
* @remarks
|
|
238
|
+
* This is useful in tests when a mock client has been provided and the test
|
|
239
|
+
* wants to adjust its state after it has been assigned to the configurator.
|
|
240
|
+
*
|
|
241
|
+
* @returns The configured client, or `undefined` when none has been set.
|
|
242
|
+
*/
|
|
243
|
+
getClient() {
|
|
244
|
+
return this.#client;
|
|
245
|
+
}
|
|
245
246
|
/**
|
|
246
247
|
* Sets telemetry provider for MSAL authentication events.
|
|
247
248
|
*
|
|
@@ -289,64 +290,151 @@ export class MsalConfigurator extends BaseConfigBuilder {
|
|
|
289
290
|
/**
|
|
290
291
|
* Processes and validates the configuration.
|
|
291
292
|
*
|
|
292
|
-
* @param
|
|
293
|
+
* @param rawConfig - Raw configuration object
|
|
294
|
+
* @param init - The builder arguments, carrying the host reference when hoisted
|
|
293
295
|
* @returns Processed and validated configuration
|
|
294
296
|
*/
|
|
295
|
-
async _processConfig(rawConfig) {
|
|
297
|
+
async _processConfig(rawConfig, init) {
|
|
296
298
|
// Validate and coerce configuration using Zod schema
|
|
297
299
|
const config = await MsalConfigSchema.parseAsync(rawConfig);
|
|
298
|
-
// Auto-create client if
|
|
300
|
+
// Auto-create client if no client instance was supplied
|
|
299
301
|
// This allows users to provide configuration without manually instantiating the client
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
|
|
302
|
+
// A hoisted module authenticates through the host's provider, so any client built here
|
|
303
|
+
// would be discarded — gate it here rather than in `_createClient`, so a substituted
|
|
304
|
+
// client (see `MsalMockConfigurator`) cannot shadow the host's signed-in user
|
|
305
|
+
if (!config.client && !this._isHoisted(init)) {
|
|
306
|
+
config.client = await this._createClient(config, init);
|
|
307
|
+
}
|
|
308
|
+
return config;
|
|
309
|
+
}
|
|
310
|
+
/**
|
|
311
|
+
* Creates the client to authenticate through, when none was supplied.
|
|
312
|
+
*
|
|
313
|
+
* @remarks
|
|
314
|
+
* Called by {@link MsalConfigurator._processConfig | _processConfig} only when
|
|
315
|
+
* no client was set, so a client supplied through
|
|
316
|
+
* {@link MsalConfigurator.setClient | setClient} always wins. It is likewise
|
|
317
|
+
* not called when the module is hoisted onto a host application's provider —
|
|
318
|
+
* see {@link MsalConfigurator._isHoisted | _isHoisted}.
|
|
319
|
+
*
|
|
320
|
+
* This is the seam for authenticating through something other than Entra ID.
|
|
321
|
+
* Overriding it replaces only the client, leaving the builder, the schema
|
|
322
|
+
* validation and `MsalProvider` untouched — which is how
|
|
323
|
+
* `MsalMockConfigurator` substitutes an in-process client for tests.
|
|
324
|
+
*
|
|
325
|
+
* An override normally builds from
|
|
326
|
+
* {@link MsalConfigurator._createClientConfig | _createClientConfig}, so it
|
|
327
|
+
* receives the same fully-resolved {@link MsalClientConfig} the real client is
|
|
328
|
+
* built from rather than re-deriving it.
|
|
329
|
+
*
|
|
330
|
+
* Returning `undefined` is legitimate and means "there is nothing to build a
|
|
331
|
+
* client from", which leaves the module without one.
|
|
332
|
+
*
|
|
333
|
+
* @param config - The validated configuration the client is built from.
|
|
334
|
+
* @param init - The builder arguments, carrying the host reference when hoisted.
|
|
335
|
+
* @returns The client, or `undefined` when there is nothing to build one from.
|
|
336
|
+
*/
|
|
337
|
+
async _createClient(config, _init) {
|
|
338
|
+
const clientConfig = this._createClientConfig(config);
|
|
339
|
+
// A client can be omitted for a hoisted module or an intentionally incomplete setup.
|
|
340
|
+
if (!clientConfig) {
|
|
341
|
+
return undefined;
|
|
342
|
+
}
|
|
343
|
+
// Instantiate MSAL client with fully configured options
|
|
344
|
+
return new MsalClient(clientConfig);
|
|
345
|
+
}
|
|
346
|
+
/**
|
|
347
|
+
* Whether this module is hoisted onto a host application's authentication.
|
|
348
|
+
*
|
|
349
|
+
* @remarks
|
|
350
|
+
* When an application runs inside a host — a portal loading an app, or an app
|
|
351
|
+
* loading a widget — the module initializer returns a proxy of the host's
|
|
352
|
+
* provider instead of building its own (see the host-provider branch of the
|
|
353
|
+
* module initializer). A client built during configuration would therefore be
|
|
354
|
+
* constructed and immediately discarded.
|
|
355
|
+
*
|
|
356
|
+
* Detecting this during configuration lets the configurator skip building a
|
|
357
|
+
* client entirely, which matters most for substituted clients: a mock client
|
|
358
|
+
* built here would otherwise silently shadow the host's real signed-in user.
|
|
359
|
+
*
|
|
360
|
+
* @param init - The builder arguments, carrying the host reference when hoisted.
|
|
361
|
+
* @returns `true` when a host provider will be used instead of a locally built client.
|
|
362
|
+
*/
|
|
363
|
+
_isHoisted(init) {
|
|
364
|
+
return !!init?.ref?.auth;
|
|
365
|
+
}
|
|
366
|
+
/**
|
|
367
|
+
* Resolves the full MSAL client configuration to build a client from.
|
|
368
|
+
*
|
|
369
|
+
* @remarks
|
|
370
|
+
* Applies the defaults a client is expected to be built with — authority
|
|
371
|
+
* derived from the tenant, cache location, telemetry-backed logging and the
|
|
372
|
+
* configured cache lookup policy.
|
|
373
|
+
*
|
|
374
|
+
* Kept separate from {@link MsalConfigurator._createClient | _createClient} so
|
|
375
|
+
* that substituting the client does not also mean re-implementing this
|
|
376
|
+
* resolution. `MsalMockConfigurator` relies on it to hand its mock client the
|
|
377
|
+
* very same configuration the real client would have received.
|
|
378
|
+
*
|
|
379
|
+
* @param config - The validated configuration.
|
|
380
|
+
* @returns The client configuration, or `undefined` when none was declared.
|
|
381
|
+
*/
|
|
382
|
+
_createClientConfig(config) {
|
|
383
|
+
const declared = this.#msalConfig;
|
|
384
|
+
// Do not construct a client when configuration has not supplied client settings.
|
|
385
|
+
if (!declared) {
|
|
386
|
+
return undefined;
|
|
387
|
+
}
|
|
388
|
+
config.telemetry.provider?.trackEvent({
|
|
389
|
+
name: 'module-msal.configurator._processConfig.creating-client',
|
|
390
|
+
level: TelemetryLevel.Debug,
|
|
391
|
+
scope: config.telemetry.scope,
|
|
392
|
+
metadata: { ...config.telemetry.metadata, clientConfig: declared },
|
|
393
|
+
});
|
|
394
|
+
// Copied rather than enriched in place, so the object a caller passed to
|
|
395
|
+
// `setClientConfig` is never rewritten behind its back — a caller may well
|
|
396
|
+
// be reusing or asserting on it
|
|
397
|
+
const clientConfig = {
|
|
398
|
+
...declared,
|
|
399
|
+
auth: { ...declared.auth },
|
|
400
|
+
// Default to localStorage: MSAL supports sessionStorage too, but
|
|
401
|
+
// localStorage is the standard for persistent auth in browsers
|
|
402
|
+
cache: declared.cache ?? { cacheLocation: 'localStorage' },
|
|
403
|
+
};
|
|
404
|
+
// Auto-generate authority URL from tenant ID if not explicitly provided
|
|
405
|
+
// This simplifies configuration for most common cases
|
|
406
|
+
if (!clientConfig.auth.authority && clientConfig.auth.tenantId) {
|
|
407
|
+
clientConfig.auth.authority = `https://login.microsoftonline.com/${clientConfig.auth.tenantId}`;
|
|
408
|
+
}
|
|
409
|
+
// Integrate framework telemetry with MSAL logging system
|
|
410
|
+
// This allows MSAL events to flow through the framework's telemetry pipeline
|
|
411
|
+
if (!clientConfig.system?.loggerOptions && config.telemetry?.provider) {
|
|
412
|
+
const { provider, metadata, scope } = config.telemetry;
|
|
413
|
+
provider.trackEvent({
|
|
414
|
+
name: 'module-msal.configurator._processConfig.client-telemetry-connected',
|
|
304
415
|
level: TelemetryLevel.Debug,
|
|
305
|
-
scope
|
|
306
|
-
metadata
|
|
416
|
+
scope,
|
|
417
|
+
metadata,
|
|
307
418
|
});
|
|
308
|
-
|
|
309
|
-
|
|
310
|
-
|
|
311
|
-
|
|
312
|
-
|
|
313
|
-
|
|
314
|
-
|
|
315
|
-
|
|
316
|
-
|
|
317
|
-
|
|
318
|
-
|
|
319
|
-
|
|
320
|
-
|
|
321
|
-
const { provider, metadata, scope } = config.telemetry;
|
|
322
|
-
provider.trackEvent({
|
|
323
|
-
name: 'module-msal.configurator._processConfig.client-telemetry-connected',
|
|
324
|
-
level: TelemetryLevel.Debug,
|
|
325
|
-
scope,
|
|
326
|
-
metadata,
|
|
327
|
-
});
|
|
328
|
-
clientConfig.system = {
|
|
329
|
-
...clientConfig.system,
|
|
330
|
-
loggerOptions: {
|
|
331
|
-
// Only log PII in development to protect user privacy in production
|
|
332
|
-
piiLoggingEnabled: process.env.NODE_ENV === 'development',
|
|
333
|
-
// Bridge MSAL log events to framework telemetry system
|
|
334
|
-
loggerCallback: createClientLogCallback(provider, metadata, [...scope, '3rd-party']),
|
|
335
|
-
// Use Warning level by default - captures errors and warnings without being verbose
|
|
336
|
-
logLevel: LogLevel.Warning,
|
|
337
|
-
// Preserve any user-provided logger options (allows customization)
|
|
338
|
-
...clientConfig.system?.loggerOptions,
|
|
339
|
-
},
|
|
340
|
-
};
|
|
341
|
-
}
|
|
342
|
-
// Apply silent cache lookup policy if configured
|
|
343
|
-
if (config.cacheLookupPolicy !== undefined) {
|
|
344
|
-
clientConfig.cacheLookupPolicy = config.cacheLookupPolicy;
|
|
345
|
-
}
|
|
346
|
-
// Instantiate MSAL client with fully configured options
|
|
347
|
-
config.client = new MsalClient(clientConfig);
|
|
419
|
+
clientConfig.system = {
|
|
420
|
+
...clientConfig.system,
|
|
421
|
+
loggerOptions: {
|
|
422
|
+
// Only log PII in development to protect user privacy in production
|
|
423
|
+
piiLoggingEnabled: process.env.NODE_ENV === 'development',
|
|
424
|
+
// Bridge MSAL log events to framework telemetry system
|
|
425
|
+
loggerCallback: createClientLogCallback(provider, metadata, [...scope, '3rd-party']),
|
|
426
|
+
// Use Warning level by default - captures errors and warnings without being verbose
|
|
427
|
+
logLevel: LogLevel.Warning,
|
|
428
|
+
// Preserve any user-provided logger options (allows customization)
|
|
429
|
+
...clientConfig.system?.loggerOptions,
|
|
430
|
+
},
|
|
431
|
+
};
|
|
348
432
|
}
|
|
349
|
-
|
|
433
|
+
// Apply silent cache lookup policy if configured
|
|
434
|
+
if (config.cacheLookupPolicy !== undefined) {
|
|
435
|
+
clientConfig.cacheLookupPolicy = config.cacheLookupPolicy;
|
|
436
|
+
}
|
|
437
|
+
return clientConfig;
|
|
350
438
|
}
|
|
351
439
|
}
|
|
352
440
|
//# sourceMappingURL=MsalConfigurator.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"MsalConfigurator.js","sourceRoot":"","sources":["../../src/MsalConfigurator.ts"],"names":[],"mappings":"AAAA,OAAO,
|
|
1
|
+
{"version":3,"file":"MsalConfigurator.js","sourceRoot":"","sources":["../../src/MsalConfigurator.ts"],"names":[],"mappings":"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"}
|
|
@@ -14,6 +14,16 @@ const createInitialConfig = () => ({
|
|
|
14
14
|
},
|
|
15
15
|
});
|
|
16
16
|
describe('MsalConfigurator', () => {
|
|
17
|
+
it('enriches a copy, leaving the declared client configuration untouched', async () => {
|
|
18
|
+
// A caller may reuse or assert on the object it passed, and the defaults
|
|
19
|
+
// applied here are derived — rewriting it behind their back is not ours to do
|
|
20
|
+
const declared = { auth: { clientId: 'my-app', tenantId: 'my-tenant' } };
|
|
21
|
+
const configurator = new MsalConfigurator();
|
|
22
|
+
configurator.setClientConfig(declared);
|
|
23
|
+
const config = await configurator.createConfigAsync(createConfigCallbackArgs(), createInitialConfig());
|
|
24
|
+
expect(declared).toEqual({ auth: { clientId: 'my-app', tenantId: 'my-tenant' } });
|
|
25
|
+
expect(config.client?.tenantId).toBe('my-tenant');
|
|
26
|
+
});
|
|
17
27
|
it('setAuthCode should normalize surrounding whitespace', async () => {
|
|
18
28
|
const configurator = new MsalConfigurator();
|
|
19
29
|
configurator.setClient(createClient());
|
|
@@ -41,6 +51,71 @@ describe('MsalConfigurator', () => {
|
|
|
41
51
|
const config = await configurator.createConfigAsync(createConfigCallbackArgs(), createInitialConfig());
|
|
42
52
|
expect(config.client).toBeUndefined();
|
|
43
53
|
});
|
|
54
|
+
describe('_createClient', () => {
|
|
55
|
+
it('builds from the same resolved client config the real client would get', async () => {
|
|
56
|
+
// The mock relies on this: substituting the client must not also mean
|
|
57
|
+
// re-implementing authority, cache and telemetry resolution
|
|
58
|
+
const received = [];
|
|
59
|
+
class CustomConfigurator extends MsalConfigurator {
|
|
60
|
+
async _createClient(config) {
|
|
61
|
+
received.push(this._createClientConfig(config));
|
|
62
|
+
return createClient();
|
|
63
|
+
}
|
|
64
|
+
}
|
|
65
|
+
const configurator = new CustomConfigurator();
|
|
66
|
+
configurator.setClientConfig({ auth: { clientId: 'client-id', tenantId: 'tenant-id' } });
|
|
67
|
+
await configurator.createConfigAsync(createConfigCallbackArgs(), createInitialConfig());
|
|
68
|
+
expect(received).toEqual([
|
|
69
|
+
expect.objectContaining({
|
|
70
|
+
auth: expect.objectContaining({
|
|
71
|
+
clientId: 'client-id',
|
|
72
|
+
// derived by the configurator, not by the caller
|
|
73
|
+
authority: 'https://login.microsoftonline.com/tenant-id',
|
|
74
|
+
}),
|
|
75
|
+
cache: { cacheLocation: 'localStorage' },
|
|
76
|
+
}),
|
|
77
|
+
]);
|
|
78
|
+
});
|
|
79
|
+
it('supplies the client when none was set', async () => {
|
|
80
|
+
const client = createClient();
|
|
81
|
+
class CustomConfigurator extends MsalConfigurator {
|
|
82
|
+
async _createClient() {
|
|
83
|
+
return client;
|
|
84
|
+
}
|
|
85
|
+
}
|
|
86
|
+
const config = await new CustomConfigurator().createConfigAsync(createConfigCallbackArgs(), createInitialConfig());
|
|
87
|
+
expect(config.client).toBe(client);
|
|
88
|
+
});
|
|
89
|
+
it('is not consulted when a client was set, so setClient always wins', async () => {
|
|
90
|
+
const own = createClient();
|
|
91
|
+
const createOther = vi.fn().mockResolvedValue(createClient());
|
|
92
|
+
class CustomConfigurator extends MsalConfigurator {
|
|
93
|
+
_createClient() {
|
|
94
|
+
return createOther();
|
|
95
|
+
}
|
|
96
|
+
}
|
|
97
|
+
const configurator = new CustomConfigurator();
|
|
98
|
+
configurator.setClient(own);
|
|
99
|
+
const config = await configurator.createConfigAsync(createConfigCallbackArgs(), createInitialConfig());
|
|
100
|
+
expect(config.client).toBe(own);
|
|
101
|
+
expect(createOther).not.toHaveBeenCalled();
|
|
102
|
+
});
|
|
103
|
+
it('is not consulted when hoisted, so a host provider is never shadowed', async () => {
|
|
104
|
+
// A hoisted module authenticates through the host's provider, so anything
|
|
105
|
+
// built here would be discarded — or worse, shadow the host's user
|
|
106
|
+
const createOther = vi.fn().mockResolvedValue(createClient());
|
|
107
|
+
class CustomConfigurator extends MsalConfigurator {
|
|
108
|
+
_createClient() {
|
|
109
|
+
return createOther();
|
|
110
|
+
}
|
|
111
|
+
}
|
|
112
|
+
const configurator = new CustomConfigurator();
|
|
113
|
+
configurator.setClientConfig({ auth: { clientId: 'client-id', tenantId: 'tenant-id' } });
|
|
114
|
+
const config = await configurator.createConfigAsync({ ...createConfigCallbackArgs(), ref: { auth: {} } }, createInitialConfig());
|
|
115
|
+
expect(config.client).toBeUndefined();
|
|
116
|
+
expect(createOther).not.toHaveBeenCalled();
|
|
117
|
+
});
|
|
118
|
+
});
|
|
44
119
|
describe('cacheLookupPolicy', () => {
|
|
45
120
|
it('defaults to CacheLookupPolicy.AccessTokenAndRefreshToken', async () => {
|
|
46
121
|
const configurator = new MsalConfigurator();
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"MsalConfigurator.test.js","sourceRoot":"","sources":["../../../src/__tests__/MsalConfigurator.test.ts"],"names":[],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"MsalConfigurator.test.js","sourceRoot":"","sources":["../../../src/__tests__/MsalConfigurator.test.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
import { describe, expect, it, vi } from 'vitest';
|
|
2
|
+
import { MsalProvider } from '../MsalProvider';
|
|
3
|
+
import { MsalModuleVersion } from '../static';
|
|
4
|
+
const createClient = () => {
|
|
5
|
+
const acquireToken = vi.fn(async () => ({ accessToken: 'v4-token' }));
|
|
6
|
+
const handleRedirectPromise = vi.fn(async () => ({ accessToken: 'redirect-token' }));
|
|
7
|
+
return {
|
|
8
|
+
client: {
|
|
9
|
+
clientId: 'test-client-id',
|
|
10
|
+
initialize: vi.fn(async () => undefined),
|
|
11
|
+
acquireToken,
|
|
12
|
+
handleRedirectPromise,
|
|
13
|
+
setActiveAccount: vi.fn(),
|
|
14
|
+
getActiveAccount: vi.fn(() => null),
|
|
15
|
+
},
|
|
16
|
+
acquireToken,
|
|
17
|
+
handleRedirectPromise,
|
|
18
|
+
};
|
|
19
|
+
};
|
|
20
|
+
const createConfig = (client) => ({
|
|
21
|
+
client,
|
|
22
|
+
version: '7.0.0',
|
|
23
|
+
requiresAuth: false,
|
|
24
|
+
telemetry: {
|
|
25
|
+
metadata: { module: 'msal', version: '7.0.0' },
|
|
26
|
+
scope: ['framework', 'authentication'],
|
|
27
|
+
},
|
|
28
|
+
});
|
|
29
|
+
describe('MsalProvider.createProxyProvider (v2)', () => {
|
|
30
|
+
it('tags the proxy as v2 while delegating through the same v4 provider', () => {
|
|
31
|
+
const mockClient = createClient();
|
|
32
|
+
const provider = new MsalProvider(createConfig(mockClient.client));
|
|
33
|
+
const v2Provider = provider.createProxyProvider(MsalModuleVersion.V2);
|
|
34
|
+
expect(v2Provider.msalVersion).toBe(MsalModuleVersion.V2);
|
|
35
|
+
});
|
|
36
|
+
it('adapts the legacy v2 acquireToken shape into a v4 request before delegating', async () => {
|
|
37
|
+
const mockClient = createClient();
|
|
38
|
+
const provider = new MsalProvider(createConfig(mockClient.client));
|
|
39
|
+
const v2Provider = provider.createProxyProvider(MsalModuleVersion.V2);
|
|
40
|
+
await expect(v2Provider.acquireToken({ scopes: ['User.Read'] })).resolves.toMatchObject({
|
|
41
|
+
accessToken: 'v4-token',
|
|
42
|
+
});
|
|
43
|
+
expect(mockClient.acquireToken).toHaveBeenCalledWith(expect.objectContaining({ request: expect.objectContaining({ scopes: ['User.Read'] }) }));
|
|
44
|
+
});
|
|
45
|
+
it('discards the host’s redirect result, honoring v2’s null contract, while still processing it', async () => {
|
|
46
|
+
const mockClient = createClient();
|
|
47
|
+
const provider = new MsalProvider(createConfig(mockClient.client));
|
|
48
|
+
const v2Provider = provider.createProxyProvider(MsalModuleVersion.V2);
|
|
49
|
+
await expect(v2Provider.handleRedirect()).resolves.toBeNull();
|
|
50
|
+
expect(mockClient.handleRedirectPromise).toHaveBeenCalledTimes(1);
|
|
51
|
+
});
|
|
52
|
+
});
|
|
53
|
+
//# sourceMappingURL=create-proxy-provider.test.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"create-proxy-provider.test.js","sourceRoot":"","sources":["../../../src/__tests__/create-proxy-provider.test.ts"],"names":[],"mappings":"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"}
|