@equinor/fusion-framework-module-msal 11.0.0 → 11.0.1
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/esm/version.js +1 -1
- package/dist/tsconfig.tsbuildinfo +1 -1
- package/dist/types/version.d.ts +1 -1
- package/package.json +8 -5
- package/CHANGELOG.md +0 -1212
- package/docs/api-reference.md +0 -85
- package/docs/auth-code-flow.md +0 -86
- package/docs/migration-v2-to-v4.md +0 -115
- package/docs/testing.md +0 -191
- package/docs/troubleshooting.md +0 -17
- package/docs/version-management.md +0 -67
- package/src/MsalClient.interface.ts +0 -139
- package/src/MsalClient.ts +0 -326
- package/src/MsalConfigurator.ts +0 -486
- package/src/MsalProvider.interface.ts +0 -179
- package/src/MsalProvider.ts +0 -776
- package/src/MsalProxyProvider.interface.ts +0 -72
- package/src/__tests__/MsalConfigurator.test.ts +0 -222
- package/src/__tests__/MsalProvider.test.ts +0 -74
- package/src/__tests__/create-proxy-provider.test.ts +0 -77
- package/src/__tests__/mock/create-mock-user-from-token.test.ts +0 -46
- package/src/__tests__/mock/msal-mock.test.ts +0 -613
- package/src/__tests__/versioning/resolve-version.test.ts +0 -161
- package/src/create-client-log-callback.ts +0 -102
- package/src/create-proxy-provider.ts +0 -97
- package/src/index.ts +0 -48
- package/src/mock/MsalMockClient.ts +0 -618
- package/src/mock/MsalMockConfigurator.ts +0 -305
- package/src/mock/create-mock-token.ts +0 -92
- package/src/mock/create-mock-user-from-token.ts +0 -46
- package/src/mock/create-msal-mock-client.ts +0 -25
- package/src/mock/decode-jwt-segment.ts +0 -22
- package/src/mock/index.ts +0 -30
- package/src/mock/module.ts +0 -54
- package/src/module.ts +0 -142
- package/src/msal-config-schema.ts +0 -81
- package/src/static.ts +0 -38
- package/src/telemetry-config-schema.ts +0 -25
- package/src/types.ts +0 -16
- package/src/util/compare-origin.ts +0 -18
- package/src/util/normalize-uri.ts +0 -24
- package/src/util/redirect.ts +0 -19
- package/src/v2/IAuthClient.interface.ts +0 -114
- package/src/v2/Logger.ts +0 -204
- package/src/v2/MsalProvider.interface.ts +0 -102
- package/src/v2/create-proxy-client.ts +0 -195
- package/src/v2/create-proxy-provider.ts +0 -177
- package/src/v2/map-account-info.ts +0 -23
- package/src/v2/map-authentication-result.ts +0 -28
- package/src/v2/types.ts +0 -674
- package/src/v4/create-proxy-provider.ts +0 -75
- package/src/v4/index.ts +0 -13
- package/src/v4/types.ts +0 -727
- package/src/version.ts +0 -2
- package/src/versioning/VersionError.ts +0 -64
- package/src/versioning/index.ts +0 -29
- package/src/versioning/resolve-version.ts +0 -154
- package/src/versioning/types.ts +0 -60
- package/tsconfig.json +0 -18
- package/vitest.config.ts +0 -11
package/src/module.ts
DELETED
|
@@ -1,142 +0,0 @@
|
|
|
1
|
-
import {
|
|
2
|
-
type Module,
|
|
3
|
-
type IModulesConfigurator,
|
|
4
|
-
type ModuleConfigType,
|
|
5
|
-
SemanticVersion,
|
|
6
|
-
} from '@equinor/fusion-framework-module';
|
|
7
|
-
|
|
8
|
-
import { MsalConfigurator } from './MsalConfigurator';
|
|
9
|
-
import { MsalProvider, type IMsalProvider } from './MsalProvider';
|
|
10
|
-
|
|
11
|
-
import { version } from './version';
|
|
12
|
-
|
|
13
|
-
/**
|
|
14
|
-
* MSAL authentication module configuration.
|
|
15
|
-
*
|
|
16
|
-
* This module provides Microsoft Authentication Library (MSAL) integration for the
|
|
17
|
-
* Fusion Framework, supporting MSAL v4 with backward compatibility for v2 applications.
|
|
18
|
-
*/
|
|
19
|
-
export type MsalModule = Module<'auth', IMsalProvider, MsalConfigurator, [MsalModule]>;
|
|
20
|
-
|
|
21
|
-
/**
|
|
22
|
-
* MSAL authentication module definition.
|
|
23
|
-
*
|
|
24
|
-
* This module manages authentication providers with the following initialization flow:
|
|
25
|
-
* 1. Check for custom provider configuration
|
|
26
|
-
* 2. Check for existing provider in parent module (for proxy compatibility)
|
|
27
|
-
* 3. Create new provider with client configuration
|
|
28
|
-
*
|
|
29
|
-
* @remarks
|
|
30
|
-
* The module supports proxy providers for version compatibility, allowing v4 implementations
|
|
31
|
-
* to work with v2-compatible code during migration periods.
|
|
32
|
-
*/
|
|
33
|
-
export const module: MsalModule = {
|
|
34
|
-
name: 'auth',
|
|
35
|
-
version: new SemanticVersion(version),
|
|
36
|
-
configure: () => new MsalConfigurator(),
|
|
37
|
-
initialize: async (init) => {
|
|
38
|
-
const config = await init.config.createConfigAsync(init);
|
|
39
|
-
|
|
40
|
-
// Priority 1: Use custom provider if explicitly configured
|
|
41
|
-
if (config.provider) {
|
|
42
|
-
return config.provider;
|
|
43
|
-
}
|
|
44
|
-
|
|
45
|
-
// Priority 2: Check if provider exists in parent module (proxy compatibility)
|
|
46
|
-
// This allows child applications to reuse parent's authentication provider
|
|
47
|
-
const hostProvider = init.ref?.auth;
|
|
48
|
-
// Reuse the parent's provider (via a version-compatible proxy) when available
|
|
49
|
-
if (hostProvider) {
|
|
50
|
-
try {
|
|
51
|
-
const proxyProvider = hostProvider.createProxyProvider(config.version);
|
|
52
|
-
return proxyProvider;
|
|
53
|
-
} catch (error) {
|
|
54
|
-
console.error('MsalModule::Failed to create proxy provider', error);
|
|
55
|
-
// Fallback to host provider to prevent app breakage during migration
|
|
56
|
-
// TODO(#5114): Consider throwing error instead once all apps are migrated to v4
|
|
57
|
-
return hostProvider;
|
|
58
|
-
}
|
|
59
|
-
}
|
|
60
|
-
|
|
61
|
-
// Priority 3: Validate client configuration is provided
|
|
62
|
-
if (!config.client) {
|
|
63
|
-
throw new Error(
|
|
64
|
-
'Client configuration is required when provider is not in the parent module nor defined',
|
|
65
|
-
);
|
|
66
|
-
}
|
|
67
|
-
|
|
68
|
-
// Create new MSAL provider instance
|
|
69
|
-
const provider = new MsalProvider(config);
|
|
70
|
-
|
|
71
|
-
// Initialize the provider (handles redirect callbacks, SSO, etc.)
|
|
72
|
-
await provider.initialize();
|
|
73
|
-
|
|
74
|
-
return provider;
|
|
75
|
-
},
|
|
76
|
-
};
|
|
77
|
-
|
|
78
|
-
/**
|
|
79
|
-
* Configuration function type for MSAL module setup.
|
|
80
|
-
*
|
|
81
|
-
* This function receives a builder object with methods to configure the MSAL client
|
|
82
|
-
* and authentication requirements.
|
|
83
|
-
*/
|
|
84
|
-
export type AuthConfigFn<TRef = unknown> = (
|
|
85
|
-
configurator: ModuleConfigType<MsalModule>,
|
|
86
|
-
ref?: TRef,
|
|
87
|
-
) => void;
|
|
88
|
-
|
|
89
|
-
/**
|
|
90
|
-
* Enables MSAL authentication module in the framework.
|
|
91
|
-
*
|
|
92
|
-
* This is a convenience function that adds the MSAL module configuration to the
|
|
93
|
-
* framework configurator with optional configuration callback.
|
|
94
|
-
*
|
|
95
|
-
* @param configurator - The framework modules configurator instance
|
|
96
|
-
* @param configure - Optional configuration callback for MSAL setup
|
|
97
|
-
*
|
|
98
|
-
* @example
|
|
99
|
-
* ```typescript
|
|
100
|
-
* enableMSAL(frameworkConfigurator, (builder) => {
|
|
101
|
-
* builder.setClientConfig({
|
|
102
|
-
* auth: { clientId: 'your-client-id', tenantId: 'your-tenant-id' }
|
|
103
|
-
* });
|
|
104
|
-
* builder.setRequiresAuth(true);
|
|
105
|
-
* });
|
|
106
|
-
* ```
|
|
107
|
-
*/
|
|
108
|
-
export const enableMSAL = (
|
|
109
|
-
// biome-ignore lint/suspicious/noExplicitAny: must be any to support all module types
|
|
110
|
-
configurator: IModulesConfigurator<any, any>,
|
|
111
|
-
configure?: AuthConfigFn,
|
|
112
|
-
): void => {
|
|
113
|
-
const config = configure ? configureMsal(configure) : { module };
|
|
114
|
-
configurator.addConfig(config);
|
|
115
|
-
};
|
|
116
|
-
|
|
117
|
-
/**
|
|
118
|
-
* Creates MSAL module configuration with custom setup.
|
|
119
|
-
*
|
|
120
|
-
* @param configure - Configuration callback function
|
|
121
|
-
* @returns Module configuration object ready for framework integration
|
|
122
|
-
*
|
|
123
|
-
* @example
|
|
124
|
-
* ```typescript
|
|
125
|
-
* const msalConfig = configureMsal((builder) => {
|
|
126
|
-
* builder.setClientConfig(msalClientConfig);
|
|
127
|
-
* builder.setRequiresAuth(true);
|
|
128
|
-
* });
|
|
129
|
-
* ```
|
|
130
|
-
*/
|
|
131
|
-
export const configureMsal = (configure: AuthConfigFn) => ({
|
|
132
|
-
module,
|
|
133
|
-
configure,
|
|
134
|
-
});
|
|
135
|
-
|
|
136
|
-
declare module '@equinor/fusion-framework-module' {
|
|
137
|
-
interface Modules {
|
|
138
|
-
auth: MsalModule;
|
|
139
|
-
}
|
|
140
|
-
}
|
|
141
|
-
|
|
142
|
-
export default module;
|
|
@@ -1,81 +0,0 @@
|
|
|
1
|
-
import z from 'zod';
|
|
2
|
-
import semver from 'semver';
|
|
3
|
-
import { CacheLookupPolicy } from '@azure/msal-browser';
|
|
4
|
-
|
|
5
|
-
import type { IMsalClient } from './MsalClient.interface';
|
|
6
|
-
import type { IMsalProvider } from './MsalProvider.interface';
|
|
7
|
-
import { TelemetryConfigSchema } from './telemetry-config-schema';
|
|
8
|
-
export type { TelemetryConfig } from './telemetry-config-schema';
|
|
9
|
-
|
|
10
|
-
/**
|
|
11
|
-
* Zod schema for MSAL module configuration validation.
|
|
12
|
-
*
|
|
13
|
-
* @remarks
|
|
14
|
-
* Kept in its own module so the configuration can be extended at its source.
|
|
15
|
-
* The schema itself describes what reaches `MsalProvider` and strips anything
|
|
16
|
-
* else; keys a variant of this module needs only while the configuration is
|
|
17
|
-
* being built are declared on {@link MsalConfigExtension} instead.
|
|
18
|
-
*/
|
|
19
|
-
export const MsalConfigSchema = z.object({
|
|
20
|
-
client: z.custom<IMsalClient>().optional(),
|
|
21
|
-
provider: z.custom<IMsalProvider>().optional(),
|
|
22
|
-
requiresAuth: z.boolean().optional(),
|
|
23
|
-
redirectUri: z.string().optional(),
|
|
24
|
-
loginHint: z.string().optional(),
|
|
25
|
-
authCode: z.string().optional(),
|
|
26
|
-
cacheLookupPolicy: z
|
|
27
|
-
.custom<CacheLookupPolicy>(
|
|
28
|
-
(val) =>
|
|
29
|
-
typeof val === 'number' &&
|
|
30
|
-
Object.values(CacheLookupPolicy).includes(val as CacheLookupPolicy),
|
|
31
|
-
)
|
|
32
|
-
.optional(),
|
|
33
|
-
version: z.string().transform((value, ctx) => {
|
|
34
|
-
const coerced = semver.coerce(value);
|
|
35
|
-
// `semver.coerce` returns `null` for an unparseable version; without this guard it
|
|
36
|
-
// would silently become the literal string "null" instead of failing validation.
|
|
37
|
-
if (!coerced) {
|
|
38
|
-
ctx.addIssue({ code: z.ZodIssueCode.custom, message: 'Invalid MSAL module version' });
|
|
39
|
-
return z.NEVER;
|
|
40
|
-
}
|
|
41
|
-
return coerced.version;
|
|
42
|
-
}),
|
|
43
|
-
telemetry: TelemetryConfigSchema,
|
|
44
|
-
});
|
|
45
|
-
|
|
46
|
-
/**
|
|
47
|
-
* Configuration a variant of this module adds to {@link MsalConfig}.
|
|
48
|
-
*
|
|
49
|
-
* @remarks
|
|
50
|
-
* Empty by design: production MSAL configuration is exactly the schema. This
|
|
51
|
-
* exists so a variant — the test double in `./mock`, for instance — can declare
|
|
52
|
-
* its own branch of the configuration through declaration merging:
|
|
53
|
-
*
|
|
54
|
-
* ```typescript
|
|
55
|
-
* declare module '@equinor/fusion-framework-module-msal' {
|
|
56
|
-
* interface MsalConfigExtension {
|
|
57
|
-
* mock?: { account?: MsalMockUser };
|
|
58
|
-
* }
|
|
59
|
-
* }
|
|
60
|
-
* ```
|
|
61
|
-
*
|
|
62
|
-
* That is what keeps `BaseConfigBuilder._set` honest about the added key. Its
|
|
63
|
-
* target is a dot-path union derived from {@link MsalConfig}, so a key the type
|
|
64
|
-
* does not know about can only be set by casting past the builder — and a
|
|
65
|
-
* generic configurator cannot help, because a dot-path union over an unresolved
|
|
66
|
-
* type parameter defers, taking every existing literal path down with it.
|
|
67
|
-
*
|
|
68
|
-
* The key exists to carry a declaration across the builder, not to reach the
|
|
69
|
-
* provider: the schema strips it during validation, so it is readable from the
|
|
70
|
-
* raw configuration and absent from the validated one.
|
|
71
|
-
*/
|
|
72
|
-
// biome-ignore lint/suspicious/noEmptyInterface: the extension point is the point
|
|
73
|
-
export interface MsalConfigExtension {}
|
|
74
|
-
|
|
75
|
-
/**
|
|
76
|
-
* Complete configuration object for MSAL authentication module.
|
|
77
|
-
*
|
|
78
|
-
* This type represents the full configuration including client setup, authentication
|
|
79
|
-
* requirements, telemetry, and version information.
|
|
80
|
-
*/
|
|
81
|
-
export type MsalConfig = z.infer<typeof MsalConfigSchema> & MsalConfigExtension;
|
package/src/static.ts
DELETED
|
@@ -1,38 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Module identifier for the MSAL authentication module.
|
|
3
|
-
*
|
|
4
|
-
* This constant is used to register and identify the MSAL module within the Fusion Framework.
|
|
5
|
-
*/
|
|
6
|
-
export const ModuleName = 'msal' as const;
|
|
7
|
-
|
|
8
|
-
/**
|
|
9
|
-
* Enumeration of supported MSAL module versions.
|
|
10
|
-
*
|
|
11
|
-
* This enum defines the available MSAL versions and provides type-safe access to version identifiers.
|
|
12
|
-
*
|
|
13
|
-
* @remarks
|
|
14
|
-
* - `V2`: MSAL v2 compatibility (legacy support)
|
|
15
|
-
* - `V4`: MSAL v4 compatibility (supports @azure/msal-browser 4.x)
|
|
16
|
-
* - `V5`: MSAL v5 compatibility (supports @azure/msal-browser 5.x)
|
|
17
|
-
*
|
|
18
|
-
* @example
|
|
19
|
-
* ```typescript
|
|
20
|
-
* import { MsalModuleVersion } from '@equinor/fusion-framework-module-msal';
|
|
21
|
-
*
|
|
22
|
-
* // Check version
|
|
23
|
-
* if (version === MsalModuleVersion.V5) {
|
|
24
|
-
* console.log('Using MSAL v5 compatible version');
|
|
25
|
-
* }
|
|
26
|
-
*
|
|
27
|
-
* // Create version-specific proxy
|
|
28
|
-
* const proxy = provider.createProxyProvider(MsalModuleVersion.V2);
|
|
29
|
-
* ```
|
|
30
|
-
*/
|
|
31
|
-
export enum MsalModuleVersion {
|
|
32
|
-
/** MSAL v2 compatibility version (legacy support) */
|
|
33
|
-
V2 = 'v2',
|
|
34
|
-
/** MSAL v4 compatibility version (supports @azure/msal-browser 4.x) */
|
|
35
|
-
V4 = 'v4',
|
|
36
|
-
/** MSAL v5 compatibility version (supports @azure/msal-browser 5.x) */
|
|
37
|
-
V5 = 'v5',
|
|
38
|
-
}
|
|
@@ -1,25 +0,0 @@
|
|
|
1
|
-
import z from 'zod';
|
|
2
|
-
import type { ITelemetryProvider } from '@equinor/fusion-framework-module-telemetry';
|
|
3
|
-
import { version } from './version';
|
|
4
|
-
|
|
5
|
-
/**
|
|
6
|
-
* Zod schema for telemetry configuration validation.
|
|
7
|
-
*
|
|
8
|
-
* @internal
|
|
9
|
-
*/
|
|
10
|
-
export const TelemetryConfigSchema = z.object({
|
|
11
|
-
provider: z.custom<ITelemetryProvider>().optional(),
|
|
12
|
-
metadata: z.record(z.string(), z.unknown()).optional().default({
|
|
13
|
-
module: 'msal',
|
|
14
|
-
version,
|
|
15
|
-
}),
|
|
16
|
-
scope: z.array(z.string()).optional().default(['framework', 'authentication']),
|
|
17
|
-
});
|
|
18
|
-
|
|
19
|
-
/**
|
|
20
|
-
* Telemetry configuration for MSAL module.
|
|
21
|
-
*
|
|
22
|
-
* This configuration controls how authentication events are tracked and logged
|
|
23
|
-
* through the framework's telemetry system.
|
|
24
|
-
*/
|
|
25
|
-
export type TelemetryConfig = z.infer<typeof TelemetryConfigSchema>;
|
package/src/types.ts
DELETED
|
@@ -1,16 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Re-exports of core MSAL types from @azure/msal-browser.
|
|
3
|
-
*
|
|
4
|
-
* This module provides convenient access to commonly used MSAL types without
|
|
5
|
-
* requiring direct imports from @azure/msal-browser. These types represent
|
|
6
|
-
* fundamental authentication entities used throughout the MSAL module.
|
|
7
|
-
*
|
|
8
|
-
* @module
|
|
9
|
-
*/
|
|
10
|
-
|
|
11
|
-
export {
|
|
12
|
-
/** Represents account information for an authenticated user */
|
|
13
|
-
AccountInfo,
|
|
14
|
-
/** Represents the result of an authentication operation including tokens and account */
|
|
15
|
-
AuthenticationResult,
|
|
16
|
-
} from '@azure/msal-browser';
|
|
@@ -1,18 +0,0 @@
|
|
|
1
|
-
import { normalizeUri } from './normalize-uri';
|
|
2
|
-
|
|
3
|
-
/**
|
|
4
|
-
* Compares two URIs after normalizing them to their canonical form.
|
|
5
|
-
*
|
|
6
|
-
* Both values are passed through {@link normalizeUri} before comparison, so relative
|
|
7
|
-
* paths, double slashes, and trailing slashes are handled transparently.
|
|
8
|
-
*
|
|
9
|
-
* @internal
|
|
10
|
-
*
|
|
11
|
-
* @param a - First URI or relative path
|
|
12
|
-
* @param b - Second URI or relative path
|
|
13
|
-
* @returns `true` when both URIs resolve to the same normalized string
|
|
14
|
-
*/
|
|
15
|
-
export const compareOrigin = (a: string, b: string): boolean => {
|
|
16
|
-
const url = { a: normalizeUri(a), b: normalizeUri(b) };
|
|
17
|
-
return url.a === url.b;
|
|
18
|
-
};
|
|
@@ -1,24 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Creates and normalizes a redirect URI.
|
|
3
|
-
*
|
|
4
|
-
* Resolves relative paths against the provided base URL and strips double and trailing slashes
|
|
5
|
-
* from the resulting pathname. Used internally to sanitize redirect URIs before passing them
|
|
6
|
-
* to MSAL authentication flows.
|
|
7
|
-
*
|
|
8
|
-
* @internal
|
|
9
|
-
*
|
|
10
|
-
* @param uri - Relative path (e.g. `/callback`) or absolute URL (e.g. `https://app.com/callback`)
|
|
11
|
-
* @param home - Base URL for resolving relative paths. Defaults to `window.location.origin`.
|
|
12
|
-
* @returns Fully-qualified, normalized URI string
|
|
13
|
-
*
|
|
14
|
-
* @example
|
|
15
|
-
* ```typescript
|
|
16
|
-
* normalizeUri('/callback'); // https://current-origin.com/callback
|
|
17
|
-
* normalizeUri('https://app.com//callback/'); // https://app.com/callback
|
|
18
|
-
* ```
|
|
19
|
-
*/
|
|
20
|
-
export const normalizeUri = (uri: string, home: string = window.location.origin): string => {
|
|
21
|
-
uri = uri.match(/^http[s]?/) ? uri : home + uri;
|
|
22
|
-
const { origin, pathname } = new URL(uri);
|
|
23
|
-
return origin + pathname.replace(/([^:]\/)\/+/g, '$1');
|
|
24
|
-
};
|
package/src/util/redirect.ts
DELETED
|
@@ -1,19 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Redirects the browser to the specified URL.
|
|
3
|
-
*
|
|
4
|
-
* If the browser has not navigated away within the given timeout, the returned
|
|
5
|
-
* promise is rejected. This acts as a safeguard against redirect failures.
|
|
6
|
-
*
|
|
7
|
-
* @internal
|
|
8
|
-
*
|
|
9
|
-
* @param url - Endpoint to navigate to
|
|
10
|
-
* @param timeout - Maximum milliseconds to wait before considering the redirect failed. Defaults to `3000`.
|
|
11
|
-
* @param history - When `true`, uses `location.assign()` so the current page is kept in browser history.
|
|
12
|
-
* Otherwise uses `location.replace()` which replaces the current history entry.
|
|
13
|
-
* @returns A promise that rejects after the timeout (it never resolves because a successful redirect
|
|
14
|
-
* causes the page to unload)
|
|
15
|
-
*/
|
|
16
|
-
export const redirect = (url: string, timeout = 3000, history?: boolean): Promise<void> => {
|
|
17
|
-
history ? window.location.assign(url) : window.location.replace(url);
|
|
18
|
-
return new Promise((_, reject) => setTimeout(reject, timeout));
|
|
19
|
-
};
|
|
@@ -1,114 +0,0 @@
|
|
|
1
|
-
import type {
|
|
2
|
-
AccountInfo as AccountInfoBase,
|
|
3
|
-
AuthenticationResult,
|
|
4
|
-
IPublicClientApplication,
|
|
5
|
-
} from './types';
|
|
6
|
-
|
|
7
|
-
/**
|
|
8
|
-
* Simplified ID token claims used by the v2 compatibility layer.
|
|
9
|
-
*
|
|
10
|
-
* @property aud - Token audience (application ID)
|
|
11
|
-
* @property exp - Token expiration time (seconds since epoch)
|
|
12
|
-
*/
|
|
13
|
-
export type IdTokenClaims = {
|
|
14
|
-
aud: string;
|
|
15
|
-
exp: number;
|
|
16
|
-
};
|
|
17
|
-
|
|
18
|
-
/**
|
|
19
|
-
* Extended account information for v2 compatibility.
|
|
20
|
-
*
|
|
21
|
-
* Augments the base v2 `AccountInfo` with typed ID token claims.
|
|
22
|
-
*/
|
|
23
|
-
export type AccountInfo = AccountInfoBase & {
|
|
24
|
-
idTokenClaims?: IdTokenClaims;
|
|
25
|
-
};
|
|
26
|
-
|
|
27
|
-
/**
|
|
28
|
-
* Authentication behavior type for v2-compatible login and token flows.
|
|
29
|
-
*
|
|
30
|
-
* - `'popup'` — Opens a popup window for authentication
|
|
31
|
-
* - `'redirect'` — Navigates the browser to the Microsoft login page
|
|
32
|
-
*/
|
|
33
|
-
export type AuthBehavior = 'popup' | 'redirect';
|
|
34
|
-
|
|
35
|
-
/**
|
|
36
|
-
* Simplified authentication request for v2-compatible methods.
|
|
37
|
-
*
|
|
38
|
-
* @property scopes - Optional OAuth scopes to request (e.g. `['User.Read']`)
|
|
39
|
-
* @property loginHint - Optional username hint to pre-fill the login form
|
|
40
|
-
*/
|
|
41
|
-
export type AuthRequest = {
|
|
42
|
-
scopes?: string[];
|
|
43
|
-
loginHint?: string;
|
|
44
|
-
};
|
|
45
|
-
|
|
46
|
-
/**
|
|
47
|
-
* Interface for MSAL v2 compatible authentication client.
|
|
48
|
-
*
|
|
49
|
-
* This interface defines the contract for authentication clients that maintain
|
|
50
|
-
* backward compatibility with MSAL v2 API while using MSAL v4 implementation
|
|
51
|
-
* under the hood. This is useful for gradual migration scenarios.
|
|
52
|
-
*
|
|
53
|
-
* @example
|
|
54
|
-
* ```typescript
|
|
55
|
-
* const client: IAuthClient_v2 = createProxyClient(baseClient);
|
|
56
|
-
*
|
|
57
|
-
* // Use v2 compatible API
|
|
58
|
-
* const account = client.account;
|
|
59
|
-
* const result = await client.login({ scopes: ['User.Read'] });
|
|
60
|
-
* ```
|
|
61
|
-
*/
|
|
62
|
-
export interface IAuthClient extends IPublicClientApplication {
|
|
63
|
-
/**
|
|
64
|
-
* Tenant ID for the client domain
|
|
65
|
-
*/
|
|
66
|
-
readonly tenantId: string;
|
|
67
|
-
|
|
68
|
-
/**
|
|
69
|
-
* Returns account for client tenant that MSAL currently has data for.
|
|
70
|
-
* (the account object is created at the time of successful login)
|
|
71
|
-
*/
|
|
72
|
-
get account(): AccountInfo | undefined;
|
|
73
|
-
|
|
74
|
-
/**
|
|
75
|
-
* Check if the current account has valid claims
|
|
76
|
-
*/
|
|
77
|
-
get hasValidClaims(): boolean;
|
|
78
|
-
|
|
79
|
-
/**
|
|
80
|
-
* Configured client ID
|
|
81
|
-
*/
|
|
82
|
-
get clientId(): string | undefined;
|
|
83
|
-
|
|
84
|
-
/**
|
|
85
|
-
* Request origin from browser storage
|
|
86
|
-
*/
|
|
87
|
-
get requestOrigin(): string | null;
|
|
88
|
-
|
|
89
|
-
/**
|
|
90
|
-
* Login user with optional silent authentication fallback
|
|
91
|
-
* @param options - Optional authentication request options
|
|
92
|
-
* @param behavior - Authentication method: 'popup' or 'redirect'
|
|
93
|
-
* @param silent - Whether to attempt silent authentication first
|
|
94
|
-
* @returns Promise resolving to authentication result or void
|
|
95
|
-
*/
|
|
96
|
-
login(
|
|
97
|
-
options?: AuthRequest,
|
|
98
|
-
behavior?: AuthBehavior,
|
|
99
|
-
silent?: boolean,
|
|
100
|
-
): Promise<AuthenticationResult | undefined>;
|
|
101
|
-
|
|
102
|
-
/**
|
|
103
|
-
* Acquire access token with optional silent authentication fallback
|
|
104
|
-
* @param options - Authentication request options
|
|
105
|
-
* @param behavior - Authentication method: 'popup' or 'redirect'
|
|
106
|
-
* @param silent - Whether to attempt silent authentication first
|
|
107
|
-
* @returns Promise resolving to authentication result or void
|
|
108
|
-
*/
|
|
109
|
-
acquireToken(
|
|
110
|
-
options?: AuthRequest,
|
|
111
|
-
behavior?: AuthBehavior,
|
|
112
|
-
silent?: boolean,
|
|
113
|
-
): Promise<AuthenticationResult | undefined>;
|
|
114
|
-
}
|
package/src/v2/Logger.ts
DELETED
|
@@ -1,204 +0,0 @@
|
|
|
1
|
-
import { LogLevel, type ILoggerCallback, type LoggerOptions } from './types.js';
|
|
2
|
-
|
|
3
|
-
/**
|
|
4
|
-
* Class which facilitates logging of messages to a specific place
|
|
5
|
-
*/
|
|
6
|
-
export class Logger {
|
|
7
|
-
// Correlation ID for request, usually set by user.
|
|
8
|
-
private correlationId: string;
|
|
9
|
-
|
|
10
|
-
// Current log level, defaults to info.
|
|
11
|
-
private level: LogLevel = LogLevel.Info;
|
|
12
|
-
|
|
13
|
-
// Boolean describing whether PII logging is allowed.
|
|
14
|
-
private piiLoggingEnabled: boolean;
|
|
15
|
-
|
|
16
|
-
// Callback to send messages to.
|
|
17
|
-
private localCallback: ILoggerCallback;
|
|
18
|
-
|
|
19
|
-
// Package name implementing this logger
|
|
20
|
-
private packageName: string;
|
|
21
|
-
|
|
22
|
-
// Package version implementing this logger
|
|
23
|
-
private packageVersion: string;
|
|
24
|
-
|
|
25
|
-
/**
|
|
26
|
-
* Creates a new `Logger`.
|
|
27
|
-
*
|
|
28
|
-
* @param loggerOptions - Logger configuration, including callback, PII, and log level settings.
|
|
29
|
-
* @param packageName - Name of the package implementing this logger.
|
|
30
|
-
* @param packageVersion - Version of the package implementing this logger.
|
|
31
|
-
*/
|
|
32
|
-
constructor(loggerOptions: LoggerOptions, packageName?: string, packageVersion?: string) {
|
|
33
|
-
const defaultLoggerCallback = () => {
|
|
34
|
-
return;
|
|
35
|
-
};
|
|
36
|
-
const setLoggerOptions = loggerOptions || Logger.createDefaultLoggerOptions();
|
|
37
|
-
this.localCallback = setLoggerOptions.loggerCallback || defaultLoggerCallback;
|
|
38
|
-
this.piiLoggingEnabled = setLoggerOptions.piiLoggingEnabled || false;
|
|
39
|
-
this.level =
|
|
40
|
-
typeof setLoggerOptions.logLevel === 'number' ? setLoggerOptions.logLevel : LogLevel.Info;
|
|
41
|
-
this.correlationId = setLoggerOptions.correlationId || '';
|
|
42
|
-
this.packageName = packageName || '';
|
|
43
|
-
this.packageVersion = packageVersion || '';
|
|
44
|
-
}
|
|
45
|
-
|
|
46
|
-
/**
|
|
47
|
-
* Creates the default logger options used when none are provided.
|
|
48
|
-
*
|
|
49
|
-
* @returns Default logger options with a no-op callback, PII logging disabled, and Info level.
|
|
50
|
-
*/
|
|
51
|
-
private static createDefaultLoggerOptions(): LoggerOptions {
|
|
52
|
-
return {
|
|
53
|
-
loggerCallback: () => {
|
|
54
|
-
// allow users to not set loggerCallback
|
|
55
|
-
},
|
|
56
|
-
piiLoggingEnabled: false,
|
|
57
|
-
logLevel: LogLevel.Info,
|
|
58
|
-
};
|
|
59
|
-
}
|
|
60
|
-
|
|
61
|
-
/**
|
|
62
|
-
* Create new Logger with existing configurations.
|
|
63
|
-
*
|
|
64
|
-
* @param packageName - Name of the package implementing this logger.
|
|
65
|
-
* @param packageVersion - Version of the package implementing this logger.
|
|
66
|
-
* @param correlationId - Correlation ID to use, falling back to this logger's own if omitted.
|
|
67
|
-
* @returns A new `Logger` instance cloned from this one.
|
|
68
|
-
*/
|
|
69
|
-
public clone(packageName: string, packageVersion: string, correlationId?: string): Logger {
|
|
70
|
-
return new Logger(
|
|
71
|
-
{
|
|
72
|
-
loggerCallback: this.localCallback,
|
|
73
|
-
piiLoggingEnabled: this.piiLoggingEnabled,
|
|
74
|
-
logLevel: this.level,
|
|
75
|
-
correlationId: correlationId || this.correlationId,
|
|
76
|
-
},
|
|
77
|
-
packageName,
|
|
78
|
-
packageVersion,
|
|
79
|
-
);
|
|
80
|
-
}
|
|
81
|
-
|
|
82
|
-
/**
|
|
83
|
-
* Logs error messages.
|
|
84
|
-
*
|
|
85
|
-
* @param message - The message to log.
|
|
86
|
-
* @param correlationId - Correlation ID to attach to the log entry, if any.
|
|
87
|
-
*/
|
|
88
|
-
error(message: string, correlationId?: string): void {
|
|
89
|
-
this.logMessage(message, {
|
|
90
|
-
logLevel: LogLevel.Error,
|
|
91
|
-
containsPii: false,
|
|
92
|
-
correlationId: correlationId || '',
|
|
93
|
-
});
|
|
94
|
-
}
|
|
95
|
-
|
|
96
|
-
/**
|
|
97
|
-
* Logs warning messages.
|
|
98
|
-
*
|
|
99
|
-
* @param message - The message to log.
|
|
100
|
-
* @param correlationId - Correlation ID to attach to the log entry, if any.
|
|
101
|
-
*/
|
|
102
|
-
warning(message: string, correlationId?: string): void {
|
|
103
|
-
this.logMessage(message, {
|
|
104
|
-
logLevel: LogLevel.Warning,
|
|
105
|
-
containsPii: false,
|
|
106
|
-
correlationId: correlationId || '',
|
|
107
|
-
});
|
|
108
|
-
}
|
|
109
|
-
|
|
110
|
-
/**
|
|
111
|
-
* Logs info messages.
|
|
112
|
-
*
|
|
113
|
-
* @param message - The message to log.
|
|
114
|
-
* @param correlationId - Correlation ID to attach to the log entry, if any.
|
|
115
|
-
*/
|
|
116
|
-
info(message: string, correlationId?: string): void {
|
|
117
|
-
this.logMessage(message, {
|
|
118
|
-
logLevel: LogLevel.Info,
|
|
119
|
-
containsPii: false,
|
|
120
|
-
correlationId: correlationId || '',
|
|
121
|
-
});
|
|
122
|
-
}
|
|
123
|
-
|
|
124
|
-
/**
|
|
125
|
-
* Logs verbose messages.
|
|
126
|
-
*
|
|
127
|
-
* @param message - The message to log.
|
|
128
|
-
* @param correlationId - Correlation ID to attach to the log entry, if any.
|
|
129
|
-
*/
|
|
130
|
-
verbose(message: string, correlationId?: string): void {
|
|
131
|
-
this.logMessage(message, {
|
|
132
|
-
logLevel: LogLevel.Verbose,
|
|
133
|
-
containsPii: false,
|
|
134
|
-
correlationId: correlationId || '',
|
|
135
|
-
});
|
|
136
|
-
}
|
|
137
|
-
|
|
138
|
-
/**
|
|
139
|
-
* Logs trace messages.
|
|
140
|
-
*
|
|
141
|
-
* @param message - The message to log.
|
|
142
|
-
* @param correlationId - Correlation ID to attach to the log entry, if any.
|
|
143
|
-
*/
|
|
144
|
-
trace(message: string, correlationId?: string): void {
|
|
145
|
-
this.logMessage(message, {
|
|
146
|
-
logLevel: LogLevel.Trace,
|
|
147
|
-
containsPii: false,
|
|
148
|
-
correlationId: correlationId || '',
|
|
149
|
-
});
|
|
150
|
-
}
|
|
151
|
-
|
|
152
|
-
/**
|
|
153
|
-
* Returns whether PII Logging is enabled or not.
|
|
154
|
-
*
|
|
155
|
-
* @returns `true` when PII logging is enabled, otherwise `false`.
|
|
156
|
-
*/
|
|
157
|
-
isPiiLoggingEnabled(): boolean {
|
|
158
|
-
return this.piiLoggingEnabled || false;
|
|
159
|
-
}
|
|
160
|
-
|
|
161
|
-
/**
|
|
162
|
-
* Formats and dispatches a log message to the configured callback, unless it
|
|
163
|
-
* is below the configured log level or contains PII while PII logging is disabled.
|
|
164
|
-
*
|
|
165
|
-
* @param logMessage - The raw message to log.
|
|
166
|
-
* @param options - Log level, PII flag, and correlation ID for this message.
|
|
167
|
-
*/
|
|
168
|
-
private logMessage(
|
|
169
|
-
logMessage: string,
|
|
170
|
-
options: {
|
|
171
|
-
logLevel: LogLevel;
|
|
172
|
-
containsPii: boolean;
|
|
173
|
-
correlationId: string;
|
|
174
|
-
},
|
|
175
|
-
): void {
|
|
176
|
-
// Skip messages below the configured level or containing PII when PII logging is disabled
|
|
177
|
-
if (options.logLevel > this.level || (!this.piiLoggingEnabled && options.containsPii)) {
|
|
178
|
-
return;
|
|
179
|
-
}
|
|
180
|
-
const timestamp = new Date().toUTCString();
|
|
181
|
-
|
|
182
|
-
// Add correlationId to logs if set, correlationId provided on log messages take precedence
|
|
183
|
-
const logHeader = `[${timestamp}] : [${options.correlationId || this.correlationId || ''}]`;
|
|
184
|
-
|
|
185
|
-
const log = `${logHeader} : ${this.packageName}@${
|
|
186
|
-
this.packageVersion
|
|
187
|
-
} : ${LogLevel[options.logLevel]} - ${logMessage}`;
|
|
188
|
-
this.executeCallback(options.logLevel, log, options.containsPii || false);
|
|
189
|
-
}
|
|
190
|
-
|
|
191
|
-
/**
|
|
192
|
-
* Execute callback with message.
|
|
193
|
-
*
|
|
194
|
-
* @param level - The log level of the message.
|
|
195
|
-
* @param message - The formatted message to send to the callback.
|
|
196
|
-
* @param containsPii - Whether the message contains personally identifiable information.
|
|
197
|
-
*/
|
|
198
|
-
executeCallback(level: LogLevel, message: string, containsPii: boolean): void {
|
|
199
|
-
// Only invoke the callback when one has been configured
|
|
200
|
-
if (this.localCallback) {
|
|
201
|
-
this.localCallback(level, message, containsPii);
|
|
202
|
-
}
|
|
203
|
-
}
|
|
204
|
-
}
|