@equinor/fusion-framework-module-msal 10.0.1 → 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 +173 -0
- package/README.md +17 -368
- package/dist/esm/MsalClient.js +9 -0
- package/dist/esm/MsalClient.js.map +1 -1
- package/dist/esm/MsalConfigurator.js +178 -88
- package/dist/esm/MsalConfigurator.js.map +1 -1
- package/dist/esm/MsalProvider.js +20 -1
- package/dist/esm/MsalProvider.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/create-client-log-callback.js +1 -0
- package/dist/esm/create-client-log-callback.js.map +1 -1
- package/dist/esm/create-proxy-provider.js +5 -0
- package/dist/esm/create-proxy-provider.js.map +1 -1
- 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/module.js +3 -2
- package/dist/esm/module.js.map +1 -1
- 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/util/normalize-uri.js.map +1 -1
- package/dist/esm/v2/Logger.js +173 -0
- package/dist/esm/v2/Logger.js.map +1 -0
- package/dist/esm/v2/create-proxy-client.js +6 -0
- package/dist/esm/v2/create-proxy-client.js.map +1 -1
- package/dist/esm/v2/create-proxy-provider.js +4 -0
- package/dist/esm/v2/create-proxy-provider.js.map +1 -1
- package/dist/esm/v2/types.js +3 -124
- package/dist/esm/v2/types.js.map +1 -1
- package/dist/esm/v4/create-proxy-provider.js +1 -0
- package/dist/esm/v4/create-proxy-provider.js.map +1 -1
- package/dist/esm/v4/types.js.map +1 -1
- package/dist/esm/version.js +1 -1
- package/dist/esm/version.js.map +1 -1
- package/dist/esm/versioning/VersionError.js.map +1 -1
- package/dist/esm/versioning/resolve-version.js +4 -1
- package/dist/esm/versioning/resolve-version.js.map +1 -1
- package/dist/tsconfig.tsbuildinfo +1 -1
- package/dist/types/MsalClient.d.ts +4 -0
- package/dist/types/MsalConfigurator.d.ts +97 -20
- package/dist/types/MsalProvider.d.ts +13 -0
- 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/create-proxy-provider.d.ts +3 -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/static.d.ts +1 -1
- package/dist/types/telemetry-config-schema.d.ts +8 -0
- package/dist/types/v2/IAuthClient.interface.d.ts +2 -2
- package/dist/types/v2/Logger.d.ts +92 -0
- package/dist/types/v2/MsalProvider.interface.d.ts +1 -1
- package/dist/types/v2/types.d.ts +3 -49
- package/dist/types/v4/types.d.ts +1 -3
- 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 +14 -7
- package/src/MsalClient.ts +9 -0
- package/src/MsalConfigurator.ts +204 -115
- package/src/MsalProvider.ts +20 -1
- 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/create-client-log-callback.ts +1 -0
- package/src/create-proxy-provider.ts +5 -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/module.ts +3 -2
- package/src/msal-config-schema.ts +81 -0
- package/src/telemetry-config-schema.ts +25 -0
- package/src/v2/IAuthClient.interface.ts +2 -2
- package/src/v2/Logger.ts +204 -0
- package/src/v2/MsalProvider.interface.ts +1 -1
- package/src/v2/create-proxy-client.ts +6 -0
- package/src/v2/create-proxy-provider.ts +4 -0
- package/src/v2/types.ts +8 -158
- package/src/v4/create-proxy-provider.ts +1 -0
- package/src/v4/types.ts +3 -3
- package/src/version.ts +1 -1
- package/src/versioning/resolve-version.ts +4 -1
- package/vitest.config.ts +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,178 @@
|
|
|
1
1
|
# Change Log
|
|
2
2
|
|
|
3
|
+
## 11.0.0-next.0
|
|
4
|
+
|
|
5
|
+
### Minor Changes
|
|
6
|
+
|
|
7
|
+
- 2836e0b: Move the MSAL configuration schema into `MsalConfig.schema.ts` and add `MsalConfigExtension`, an extension point for variants of this module.
|
|
8
|
+
|
|
9
|
+
`MsalConfig` is now the schema's inferred type intersected with `MsalConfigExtension`, an empty interface a variant merges its own configuration into:
|
|
10
|
+
|
|
11
|
+
```typescript
|
|
12
|
+
declare module "@equinor/fusion-framework-module-msal" {
|
|
13
|
+
interface MsalConfigExtension {
|
|
14
|
+
mock?: { account?: MsalMockUser };
|
|
15
|
+
}
|
|
16
|
+
}
|
|
17
|
+
```
|
|
18
|
+
|
|
19
|
+
`BaseConfigBuilder._set` derives its target from `MsalConfig`, so before this a key the type did not know about could only be set by casting past the builder. Making the configurator generic over its configuration cannot solve that: a dot-path union over an unresolved type parameter defers, which takes every existing literal path down with it.
|
|
20
|
+
|
|
21
|
+
The schema is unchanged and still describes exactly what reaches `MsalProvider` — it strips anything merged in, so an extension carries a declaration across the builder and stops there. `MsalConfigSchema`, `TelemetryConfigSchema` and their types are re-exported from `MsalConfigurator` as before.
|
|
22
|
+
|
|
23
|
+
- 2836e0b: Extract client construction from `MsalConfigurator._processConfig` into overridable seams.
|
|
24
|
+
|
|
25
|
+
`_processConfig` now only decides _whether_ a client is needed; `protected _createClient(config, init)` decides _what_ to build, and `protected _createClientConfig(config)` resolves the `MsalClientConfig` it is built from — authority derived from the tenant, cache location, telemetry-backed logging and cache lookup policy included.
|
|
26
|
+
|
|
27
|
+
Behaviour is unchanged for consumers: the client is still auto-created from `setClientConfig`, and a client supplied through `setClient` still wins, because `_createClient` is consulted only when no client was set.
|
|
28
|
+
|
|
29
|
+
This gives a supported seam for authenticating through something other than Entra ID:
|
|
30
|
+
|
|
31
|
+
```typescript
|
|
32
|
+
class MyConfigurator extends MsalConfigurator {
|
|
33
|
+
protected override async _createClient(
|
|
34
|
+
config: MsalConfig,
|
|
35
|
+
): Promise<IMsalClient> {
|
|
36
|
+
// same fully resolved configuration the real client is built from
|
|
37
|
+
return new MyOwnMsalClient(this._createClientConfig(config));
|
|
38
|
+
}
|
|
39
|
+
}
|
|
40
|
+
```
|
|
41
|
+
|
|
42
|
+
Overriding it replaces only the client, leaving the builder, the schema validation and `MsalProvider` untouched.
|
|
43
|
+
|
|
44
|
+
No client is built when the module is hoisted onto a host application's provider — an app running inside a portal authenticates through the host, so a client built during configuration would be discarded, or worse, shadow the host's signed-in user. `protected _isHoisted(init)` exposes that decision to subclasses.
|
|
45
|
+
|
|
46
|
+
Also adds `getClientConfig()`, the counterpart to `setClientConfig`, so a subclass can tell "nothing was declared" apart from "declared, and here it is".
|
|
47
|
+
|
|
48
|
+
`_createClientConfig` applies its defaults to a copy of the declared configuration, not the object itself, so a caller reusing or asserting on it never sees it rewritten, and a shared constant can be used as a default without one configurator's client contaminating the next.
|
|
49
|
+
|
|
50
|
+
- 2836e0b: Give `MsalMockClient` a real account cache, so its account APIs agree with each other and with MSAL.
|
|
51
|
+
|
|
52
|
+
Previously the client held a single nullable account, which made its surface inconsistent: `getAccount(filter)` ignored the filter, `getAllAccounts()` reported an account even after one had only been made active, and signing out merely blanked a field.
|
|
53
|
+
|
|
54
|
+
The client now keeps a cache keyed by `homeAccountId` alongside an active account, matching MSAL:
|
|
55
|
+
|
|
56
|
+
- `getAccount(filter)` matches on `homeAccountId`, `localAccountId`, `username` and `tenantId`.
|
|
57
|
+
- `getAllAccounts()` returns everything cached.
|
|
58
|
+
- Signing in adds the account and activates it; signing out removes it, rather than leaving a stale entry behind.
|
|
59
|
+
- `setUser` replaces the session, so declaring a second user never leaves two accounts cached.
|
|
60
|
+
|
|
61
|
+
`setActiveAccount` deliberately departs from MSAL in one respect: an account that was never issued by a sign-in is accepted and added to the cache. That makes swapping the user between tests a single line, without rebuilding the framework:
|
|
62
|
+
|
|
63
|
+
```typescript
|
|
64
|
+
beforeEach(() => {
|
|
65
|
+
fusion.modules.auth.client.setActiveAccount(account);
|
|
66
|
+
});
|
|
67
|
+
```
|
|
68
|
+
|
|
69
|
+
- 2836e0b: Added a `./mock` entry point so applications can run against the auth module without credentials or network access.
|
|
70
|
+
|
|
71
|
+
```ts
|
|
72
|
+
import {
|
|
73
|
+
enableMsalMock,
|
|
74
|
+
createMsalMockClient,
|
|
75
|
+
} from "@equinor/fusion-framework-module-msal/mock";
|
|
76
|
+
|
|
77
|
+
// default mock user
|
|
78
|
+
enableMsalMock(configurator);
|
|
79
|
+
|
|
80
|
+
// or a specific one
|
|
81
|
+
enableMsalMock(configurator, (builder) => {
|
|
82
|
+
builder.setAccount({ name: "Ada Lovelace" });
|
|
83
|
+
});
|
|
84
|
+
```
|
|
85
|
+
|
|
86
|
+
Only the MSAL **client** is substituted. `MsalMockClient` resolves tokens in-process and takes the same `MsalClientConfig` as the real `MsalClient`, so `setClientConfig` means the same thing whether a test runs against Entra ID or in-process. `MsalMockConfigurator` builds it through the `_createClient` seam, and `msalMockModule` differs from the real module in its `configure` alone — `initialize` is the production one, untouched, so `MsalProvider`, schema validation and the whole start-up path run exactly as they do in production. `IMsalProvider` and `MsalConfigurator` are untouched.
|
|
87
|
+
|
|
88
|
+
The same client works with the plain module, without the mock module:
|
|
89
|
+
|
|
90
|
+
```ts
|
|
91
|
+
enableMSAL(configurator, (builder) =>
|
|
92
|
+
builder.setClient(
|
|
93
|
+
createMsalMockClient(
|
|
94
|
+
{ auth: { clientId: "my-app" } },
|
|
95
|
+
{ name: "Ada Lovelace" },
|
|
96
|
+
),
|
|
97
|
+
),
|
|
98
|
+
);
|
|
99
|
+
```
|
|
100
|
+
|
|
101
|
+
Tokens are structurally valid, unsigned JWTs and are identical between runs. They are not cryptographically valid and are rejected by any real service.
|
|
102
|
+
|
|
103
|
+
Exports `enableMsalMock`, `msalMockModule`, `MsalMockConfigurator`, `MsalMockClient`, `createMsalMockClient` and `createMockToken`. The entry point has no test-runner dependency.
|
|
104
|
+
|
|
105
|
+
- 2836e0b: Add `setAccount` to `MsalMockConfigurator`, so a test declares the signed-in user on the builder instead of baking it into a client.
|
|
106
|
+
|
|
107
|
+
```typescript
|
|
108
|
+
enableMsalMock(configurator, (builder) => {
|
|
109
|
+
builder.setAccount({ name: "Ada Lovelace", username: "ada@equinor.com" });
|
|
110
|
+
});
|
|
111
|
+
```
|
|
112
|
+
|
|
113
|
+
It takes an object, `null` when nobody is signed in, or an ordinary `ConfigBuilderCallback` resolving either:
|
|
114
|
+
|
|
115
|
+
```typescript
|
|
116
|
+
builder.setAccount(null);
|
|
117
|
+
builder.setAccount(async ({ hasModule }) => ({
|
|
118
|
+
name: hasModule("app") ? "App User" : "Portal User",
|
|
119
|
+
}));
|
|
120
|
+
```
|
|
121
|
+
|
|
122
|
+
The callback is the builder's own type rather than a bespoke one, so it is handed the same arguments every other configuration callback receives and is resolved by the same machinery.
|
|
123
|
+
|
|
124
|
+
`null` and `{ signedOut: true }` both start without a session, and differ in what a later login resolves to: `null` forgets the identity, `signedOut` keeps it. A declared `null` is a declaration in its own right, so it overrides the default signed-in user — only an absent declaration means the test said nothing.
|
|
125
|
+
|
|
126
|
+
`setAccount` writes to `mock.account` on the configuration rather than to a field on the builder, so the user travels the ordinary builder pipeline: a callback is resolved by `_buildConfig` with the same arguments every other configuration callback receives, and the result is on the raw configuration before validation. The schema strips the key, so nothing about a test reaches `MsalProvider` — the branch exists purely to carry the declaration across the builder. `MsalMockConfig` is exported for code that reads it.
|
|
127
|
+
|
|
128
|
+
`setAccount` records configuration only — the user is signed in on the client as it is built, so it may be declared at any point before initialization and the last declaration wins. Keeping the user off `MsalClientConfig` is what lets `MsalMockClient` take the same argument the real `MsalClient` takes: a client is configured with _what it talks to_, never with _who is signed in_.
|
|
129
|
+
|
|
130
|
+
Because the user is in place before `MsalProvider.initialize()` runs, the provider's own start-up path acts on it. Pairing `{ signedOut: true }` with `setRequiresAuth(true)` therefore exercises the real automatic login, rather than a state assigned after initialization had already finished.
|
|
131
|
+
|
|
132
|
+
Because who is signed in is session state rather than client configuration, the user is applied to whichever client the module ends up authenticating through — wherever that client was built. When the module is hoisted onto a host application's provider, no client is built here, so the user is signed in on the _host's_ client instead. Without that, a declaration made in an application's test would silently do nothing precisely when the application is being tested inside a portal. The session is shared, so the host sees the same user, as it does in production; when the host does not authenticate through a mock client the declaration throws rather than failing quietly.
|
|
133
|
+
|
|
134
|
+
`setClient` replaces the client, but not the rule: a mock client supplied that way receives the declared user too.
|
|
135
|
+
|
|
136
|
+
### Patch Changes
|
|
137
|
+
|
|
138
|
+
- e8aae1f: Internal: publish every package on the `next` pre-release tag so the whole framework can be installed as a coherent set.
|
|
139
|
+
|
|
140
|
+
Packages without their own changes are bumped only to receive a `-next.N` version and the `next` dist-tag on npm. Install with:
|
|
141
|
+
|
|
142
|
+
```bash
|
|
143
|
+
pnpm add @equinor/fusion-framework-react-app@next
|
|
144
|
+
```
|
|
145
|
+
|
|
146
|
+
- 2836e0b: Restructure documentation so each README is an entry point rather than a manual.
|
|
147
|
+
|
|
148
|
+
Long-form content moved into per-package `docs/` folders, matching the convention already used by `@equinor/fusion-framework-module` and `@equinor/fusion-framework-module-http`. Each README now keeps the elevator pitch, the shortest working example and a documentation table linking to the rest.
|
|
149
|
+
|
|
150
|
+
- **msal** — `docs/api-reference.md`, `docs/auth-code-flow.md`, `docs/testing.md`, `docs/version-management.md`, `docs/migration-v2-to-v4.md`, `docs/troubleshooting.md`. The README also gained the top-level heading it was missing.
|
|
151
|
+
- **service-discovery** — `docs/configuration.md`, `docs/testing.md`, `docs/session-overrides.md`, `docs/api-reference.md`.
|
|
152
|
+
- **framework** — `docs/testing-choosing-a-layer.md`, `docs/testing.md`, `docs/testing-design.md`, `docs/testing-extending.md`, `docs/testing-api.md`.
|
|
153
|
+
|
|
154
|
+
Both module READMEs now document their `/mock` entry point, which was previously undocumented, and state that spying on an individual call is the test runner's job rather than something these packages provide.
|
|
155
|
+
|
|
156
|
+
- 2836e0b: Remove a stray `console.log` left in `resolveVersion`'s minor-version-mismatch warning path.
|
|
157
|
+
- Updated dependencies [e8aae1f]
|
|
158
|
+
- Updated dependencies [2836e0b]
|
|
159
|
+
- Updated dependencies [2836e0b]
|
|
160
|
+
- Updated dependencies [2836e0b]
|
|
161
|
+
- Updated dependencies [2836e0b]
|
|
162
|
+
- Updated dependencies [2836e0b]
|
|
163
|
+
- @equinor/fusion-framework-module@6.1.3-next.0
|
|
164
|
+
- @equinor/fusion-framework-module-telemetry@8.0.0-next.0
|
|
165
|
+
|
|
166
|
+
## 10.0.2
|
|
167
|
+
|
|
168
|
+
### Patch Changes
|
|
169
|
+
|
|
170
|
+
- 80c3e4a: Internal: resolve `noExplicitAny`/`noConfusingVoidType` Biome warnings in `enableMSAL`'s configurator widening and the `onRedirectNavigate` callback types (v2/v4), plus safely tighten interface method return types (`login`/`acquireToken` in `IAuthClient`, `MsalProvider`) from `| void` to `| undefined`. No public API or behavior change.
|
|
171
|
+
- 80c3e4a: Internal: add required fusion-lint intent comments explaining `as unknown as T` casts in the v2 proxy client and provider adapters. No behavior change.
|
|
172
|
+
- 80c3e4a: Internal: resolve fusion-lint warnings across the package — added missing TSDoc (`@returns`, `@param`, `@throws`, `@template`) on public APIs, added intent comments above control-flow, `switch`, and RxJS/array chains, and split the v2-compatible `Logger` class out of `v2/types.ts` into `v2/Logger.ts` to satisfy the single-export-per-file rule. No public behavior changes; `Logger` remains available from `@equinor/fusion-framework-module-msal/v2`.
|
|
173
|
+
|
|
174
|
+
Two deferred TODOs now reference tracked issues: throwing when `MsalProvider.acquireToken` is called with empty scopes and no default scope (https://github.com/equinor/fusion-framework/issues/5113), and reconsidering the `MsalModule` proxy-provider fallback once all apps migrate to v4 (https://github.com/equinor/fusion-framework/issues/5114).
|
|
175
|
+
|
|
3
176
|
## 10.0.1
|
|
4
177
|
|
|
5
178
|
### Patch Changes
|
package/README.md
CHANGED
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
# `@equinor/fusion-framework-module-msal`
|
|
1
2
|
|
|
2
3
|
`@equinor/fusion-framework-module-msal` provides secure Azure AD authentication for browser applications using Microsoft's MSAL (Microsoft Authentication Library). Perfect for web applications, SPAs, and React apps that need to authenticate with Microsoft services.
|
|
3
4
|
|
|
@@ -78,92 +79,16 @@ try {
|
|
|
78
79
|
> [!IMPORTANT]
|
|
79
80
|
> The `@equinor/fusion-framework-app` enables this package by default, so applications using the app package do not need to enable this module manually.
|
|
80
81
|
|
|
81
|
-
##
|
|
82
|
+
## Documentation
|
|
82
83
|
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
```typescript
|
|
92
|
-
import { enableMSAL } from '@equinor/fusion-framework-module-msal';
|
|
93
|
-
|
|
94
|
-
enableMSAL(configurator, (builder) => {
|
|
95
|
-
builder.setClientConfig({
|
|
96
|
-
auth: {
|
|
97
|
-
clientId: 'your-client-id',
|
|
98
|
-
tenantId: 'your-tenant-id'
|
|
99
|
-
}
|
|
100
|
-
});
|
|
101
|
-
|
|
102
|
-
// Backend injects auth code as window.MSAL_AUTH_CODE during initial first page load
|
|
103
|
-
// This is the most secure approach - only available on first render, cleared after use
|
|
104
|
-
if (typeof window !== 'undefined' && window.MSAL_AUTH_CODE) {
|
|
105
|
-
builder.setAuthCode(window.MSAL_AUTH_CODE);
|
|
106
|
-
delete (window as any).MSAL_AUTH_CODE; // Clear after consuming
|
|
107
|
-
}
|
|
108
|
-
|
|
109
|
-
builder.setRequiresAuth(true);
|
|
110
|
-
});
|
|
111
|
-
```
|
|
112
|
-
|
|
113
|
-
### How It Works
|
|
114
|
-
|
|
115
|
-
1. Backend authenticates user and generates short-lived auth code
|
|
116
|
-
2. Frontend passes auth code to MSAL: `builder.setAuthCode(authCode)`
|
|
117
|
-
3. During `initialize()`: auth code exchanged for tokens (before `requiresAuth` check)
|
|
118
|
-
4. Tokens cached by MSAL → user automatically signed in
|
|
119
|
-
5. Falls back to standard MSAL flows on exchange failure
|
|
120
|
-
|
|
121
|
-
### API: `setAuthCode(authCode?: string)`
|
|
122
|
-
|
|
123
|
-
Sets backend-issued auth code for token exchange during initialization.
|
|
124
|
-
|
|
125
|
-
Pass `undefined` to clear/reset a previously configured auth code.
|
|
126
|
-
|
|
127
|
-
**Returns:** configurator instance (chainable)
|
|
128
|
-
|
|
129
|
-
**Behavior:**
|
|
130
|
-
- Exchange happens before `requiresAuth` check
|
|
131
|
-
- On success: user auto-authenticated, no login prompt
|
|
132
|
-
- On failure: falls back to standard MSAL login
|
|
133
|
-
- Auth code cleared after exchange (no reuse)
|
|
134
|
-
- `setAuthCode(undefined)` clears configured auth code
|
|
135
|
-
- `setAuthCode('')` is treated as absent auth code
|
|
136
|
-
- `setAuthCode(' ')` is trimmed and treated as absent auth code
|
|
137
|
-
- No auth-code exchange is attempted when auth code is absent/cleared
|
|
138
|
-
|
|
139
|
-
**Example:**
|
|
140
|
-
|
|
141
|
-
```typescript
|
|
142
|
-
// Best practice: Backend injects auth code on initial page load as window.MSAL_AUTH_CODE
|
|
143
|
-
if (typeof window !== 'undefined' && window.MSAL_AUTH_CODE) {
|
|
144
|
-
builder.setAuthCode(window.MSAL_AUTH_CODE);
|
|
145
|
-
delete (window as any).MSAL_AUTH_CODE; // Clear after consuming to prevent reuse
|
|
146
|
-
}
|
|
147
|
-
|
|
148
|
-
// Clear/reset auth code when input is missing
|
|
149
|
-
builder.setAuthCode(undefined);
|
|
150
|
-
```
|
|
151
|
-
|
|
152
|
-
### Security
|
|
153
|
-
|
|
154
|
-
- ✅ Auth codes: single-use, short-lived (5-10 min)
|
|
155
|
-
- ✅ MSAL validates tokens from Microsoft authority
|
|
156
|
-
- ✅ Tokens stored securely, refresh tokens auto-managed
|
|
157
|
-
- ⚠️ Pass codes securely: HTTPS, HTTP-only cookies, or encrypted channels
|
|
158
|
-
|
|
159
|
-
### Troubleshooting
|
|
160
|
-
|
|
161
|
-
| Issue | Solution |
|
|
162
|
-
|-------|----------|
|
|
163
|
-
| Auth code not exchanged | Verify `setAuthCode()` called before init |
|
|
164
|
-
| Invalid auth code error | Confirm backend `WithSpaAuthCode` enabled, code is fresh |
|
|
165
|
-
| Still shows login prompt | Check auth code exchange completes before `requiresAuth` check |
|
|
166
|
-
| Exchange fails | Auth code may have expired; backend should generate fresh code per load |
|
|
84
|
+
| Guide | Covers |
|
|
85
|
+
| --- | --- |
|
|
86
|
+
| [Configuration](./docs/api-reference.md) | `enableMSAL`, builder methods, `IMsalProvider`, and type definitions |
|
|
87
|
+
| [Backend-Issued Auth Code Flow](./docs/auth-code-flow.md) | Signing a user in from a backend-issued SPA auth code, without an interactive prompt |
|
|
88
|
+
| [Testing](./docs/testing.md) | The `/mock` entry point: in-process authentication, deterministic tokens, and spying |
|
|
89
|
+
| [Version Management](./docs/version-management.md) | Version resolution, compatibility checking, and related errors |
|
|
90
|
+
| [Migration v2 to v4](./docs/migration-v2-to-v4.md) | Moving from MSAL Browser v2 to v4, including the compatibility proxy |
|
|
91
|
+
| [Troubleshooting](./docs/troubleshooting.md) | Common failures and where to get help |
|
|
167
92
|
|
|
168
93
|
## Configuration
|
|
169
94
|
|
|
@@ -193,92 +118,21 @@ AZURE_TENANT_ID=your-tenant-id
|
|
|
193
118
|
AZURE_REDIRECT_URI=https://your-app.com/callback
|
|
194
119
|
```
|
|
195
120
|
|
|
196
|
-
##
|
|
197
|
-
|
|
198
|
-
### `enableMSAL(configurator, configure?)`
|
|
199
|
-
|
|
200
|
-
Enables the MSAL module in your Fusion Framework application.
|
|
201
|
-
|
|
202
|
-
**Parameters:**
|
|
203
|
-
- `configurator`: `IModulesConfigurator` - The modules configurator instance
|
|
204
|
-
- `configure?`: `(builder: { setClientConfig, setRequiresAuth }) => void` - Optional configuration function
|
|
205
|
-
|
|
206
|
-
**Returns:** `void`
|
|
207
|
-
|
|
208
|
-
**Example:**
|
|
209
|
-
```typescript
|
|
210
|
-
enableMSAL(configurator, (builder) => {
|
|
211
|
-
builder.setClientConfig({ auth: { clientId: '...', tenantId: '...' } });
|
|
212
|
-
builder.setRequiresAuth(true);
|
|
213
|
-
});
|
|
214
|
-
```
|
|
215
|
-
|
|
216
|
-
### Type Definitions
|
|
121
|
+
## Testing
|
|
217
122
|
|
|
218
|
-
|
|
123
|
+
Import from `@equinor/fusion-framework-module-msal/mock` to authenticate in-process instead of against Entra ID. The real configurator, provider and schema validation still run — only the client that would contact Entra ID is substituted.
|
|
219
124
|
|
|
220
125
|
```typescript
|
|
221
|
-
|
|
222
|
-
request: PopupRequest | RedirectRequest; // MSAL request object
|
|
223
|
-
behavior?: 'popup' | 'redirect'; // Auth method (default: 'redirect')
|
|
224
|
-
silent?: boolean; // Attempt silent auth first (default: true)
|
|
225
|
-
};
|
|
226
|
-
```
|
|
227
|
-
|
|
228
|
-
#### `LogoutOptions`
|
|
126
|
+
import { enableMsalMock } from '@equinor/fusion-framework-module-msal/mock';
|
|
229
127
|
|
|
230
|
-
|
|
231
|
-
type LogoutOptions = {
|
|
232
|
-
redirectUri?: string; // Redirect after logout
|
|
233
|
-
account?: AccountInfo; // Account to logout (defaults to active)
|
|
234
|
-
};
|
|
128
|
+
enableMsalMock(configurator);
|
|
235
129
|
```
|
|
236
130
|
|
|
237
|
-
|
|
131
|
+
A user named `Test User` is signed in, and tokens are real JWTs minted in-process with a fixed issue time, so they are identical across runs and machines.
|
|
238
132
|
|
|
239
|
-
|
|
240
|
-
type AcquireTokenOptions = {
|
|
241
|
-
request: PopupRequest | RedirectRequest; // MSAL request with scopes
|
|
242
|
-
behavior?: 'popup' | 'redirect'; // Auth method (default: 'redirect')
|
|
243
|
-
silent?: boolean; // Attempt silent first (default: true if account available)
|
|
244
|
-
};
|
|
245
|
-
```
|
|
246
|
-
|
|
247
|
-
### `IMsalProvider`
|
|
248
|
-
|
|
249
|
-
The authentication provider interface available at `framework.auth`:
|
|
250
|
-
|
|
251
|
-
```typescript
|
|
252
|
-
interface IMsalProvider {
|
|
253
|
-
// The MSAL PublicClientApplication instance
|
|
254
|
-
readonly client: IMsalClient;
|
|
255
|
-
|
|
256
|
-
// Current user account information
|
|
257
|
-
readonly account: AccountInfo | null;
|
|
258
|
-
|
|
259
|
-
// Initialize the MSAL provider
|
|
260
|
-
initialize(): Promise<void>;
|
|
261
|
-
|
|
262
|
-
// Acquire an access token for the specified scopes
|
|
263
|
-
acquireAccessToken(options: AcquireTokenOptionsLegacy): Promise<string | undefined>;
|
|
264
|
-
|
|
265
|
-
// Acquire full authentication result
|
|
266
|
-
acquireToken(options: AcquireTokenOptionsLegacy): Promise<AcquireTokenResult>;
|
|
267
|
-
|
|
268
|
-
// Login user interactively
|
|
269
|
-
login(options: LoginOptions): Promise<LoginResult>;
|
|
270
|
-
|
|
271
|
-
// Logout user (returns boolean)
|
|
272
|
-
logout(options?: LogoutOptions): Promise<boolean>;
|
|
273
|
-
|
|
274
|
-
// Handle authentication redirect (returns AuthenticationResult | null)
|
|
275
|
-
handleRedirect(): Promise<AuthenticationResult | null>;
|
|
276
|
-
}
|
|
277
|
-
|
|
278
|
-
// Note: defaultAccount and other deprecated v2 properties are available only
|
|
279
|
-
// when using a v2-compatible proxy via createProxyProvider()
|
|
280
|
-
```
|
|
133
|
+
The entry point has **no test-runner dependency**, and ships no mocking API of its own — spying on a call is your test runner's job.
|
|
281
134
|
|
|
135
|
+
See [Testing](./docs/testing.md) for choosing the signed-in user, signed-out behaviour and runner guidance, or [`@equinor/fusion-framework/mock`](../../framework/docs/testing.md) to mock every framework boundary at once.
|
|
282
136
|
|
|
283
137
|
## Module Hoisting
|
|
284
138
|
|
|
@@ -287,208 +141,6 @@ The module implements a hoisting pattern where the authentication provider is cr
|
|
|
287
141
|
> [!IMPORTANT]
|
|
288
142
|
> **Configure the auth module only in the root Fusion Framework instance** - Sub-instances will automatically inherit the authentication configuration from the parent.
|
|
289
143
|
|
|
290
|
-
## Migration Guide
|
|
291
|
-
|
|
292
|
-
### MSAL v2 to v4 Migration
|
|
293
|
-
|
|
294
|
-
This package has been upgraded from MSAL Browser v2 to v4, providing the latest security improvements and features from Microsoft.
|
|
295
|
-
|
|
296
|
-
#### What Changed in v4
|
|
297
|
-
|
|
298
|
-
**New MSAL Browser v4 Features:**
|
|
299
|
-
- Enhanced security with improved token management
|
|
300
|
-
- Better performance and memory usage
|
|
301
|
-
- New authentication API structure with nested request objects
|
|
302
|
-
- Improved error handling and retry mechanisms
|
|
303
|
-
|
|
304
|
-
**Architecture Changes:**
|
|
305
|
-
- **Module Hoisting**: The module uses module hoisting, meaning sub-module instances proxy the parent module instance
|
|
306
|
-
- **Shared Authentication State**: Authentication state is shared across all module instances
|
|
307
|
-
- **Async Initialization**: New `initialize()` method must be called before using the provider
|
|
308
|
-
|
|
309
|
-
#### Breaking Changes
|
|
310
|
-
|
|
311
|
-
1. **Auto-initialization via Framework**
|
|
312
|
-
```typescript
|
|
313
|
-
// The provider initializes automatically when framework loads
|
|
314
|
-
const framework = await initialize(configurator);
|
|
315
|
-
const auth = framework.auth; // Already initialized
|
|
316
|
-
|
|
317
|
-
// Manual initialization is only needed for standalone usage
|
|
318
|
-
const provider = new MsalProvider(config);
|
|
319
|
-
await provider.initialize();
|
|
320
|
-
```
|
|
321
|
-
|
|
322
|
-
2. **API Method Signature Updates**
|
|
323
|
-
- `logout()` now returns `Promise<boolean>` instead of `Promise<void>`
|
|
324
|
-
- `handleRedirect()` now returns `Promise<AuthenticationResult | null>` instead of `Promise<void>`
|
|
325
|
-
- Methods now expect nested request objects (v4 format)
|
|
326
|
-
|
|
327
|
-
3. **Account Property Changes**
|
|
328
|
-
- Use `account` property (returns `AccountInfo | null`) - v4 native
|
|
329
|
-
- `defaultAccount` is deprecated and only available via v2 proxy layer
|
|
330
|
-
- Migration: Replace `defaultAccount` with `account` throughout your code
|
|
331
|
-
|
|
332
|
-
#### Migration Steps
|
|
333
|
-
|
|
334
|
-
1. **Update Token Acquisition** (Recommended)
|
|
335
|
-
```typescript
|
|
336
|
-
// Before (v2 format - still works via proxy)
|
|
337
|
-
const token = await framework.auth.acquireAccessToken({
|
|
338
|
-
scopes: ['api.read']
|
|
339
|
-
});
|
|
340
|
-
|
|
341
|
-
// After (v4 format - recommended)
|
|
342
|
-
const token = await framework.auth.acquireAccessToken({
|
|
343
|
-
request: { scopes: ['api.read'] }
|
|
344
|
-
});
|
|
345
|
-
```
|
|
346
|
-
|
|
347
|
-
2. **Update Logout Handling**
|
|
348
|
-
```typescript
|
|
349
|
-
// Before
|
|
350
|
-
await framework.auth.logout();
|
|
351
|
-
|
|
352
|
-
// After (check return value)
|
|
353
|
-
const success = await framework.auth.logout();
|
|
354
|
-
if (success) {
|
|
355
|
-
// Handle successful logout
|
|
356
|
-
}
|
|
357
|
-
```
|
|
358
|
-
|
|
359
|
-
3. **Update Redirect Handling**
|
|
360
|
-
```typescript
|
|
361
|
-
// Before
|
|
362
|
-
await framework.auth.handleRedirect();
|
|
363
|
-
|
|
364
|
-
// After (handle result)
|
|
365
|
-
const result = await framework.auth.handleRedirect();
|
|
366
|
-
if (result?.account) {
|
|
367
|
-
// User authenticated successfully
|
|
368
|
-
console.log('Logged in as:', result.account.username);
|
|
369
|
-
}
|
|
370
|
-
```
|
|
371
|
-
|
|
372
|
-
4. **Update Configuration** (if needed)
|
|
373
|
-
```typescript
|
|
374
|
-
// Ensure only the root module configures MSAL
|
|
375
|
-
enableMSAL(configurator, (builder) => {
|
|
376
|
-
builder.setClientConfig({
|
|
377
|
-
auth: {
|
|
378
|
-
clientId: 'your-client-id',
|
|
379
|
-
tenantId: 'your-tenant-id',
|
|
380
|
-
redirectUri: 'https://your-app.com/callback'
|
|
381
|
-
}
|
|
382
|
-
});
|
|
383
|
-
builder.setRequiresAuth(true);
|
|
384
|
-
});
|
|
385
|
-
```
|
|
386
|
-
|
|
387
|
-
5. **Remove Duplicate Configurations**: Remove MSAL configuration from child modules
|
|
388
|
-
|
|
389
|
-
#### Backward Compatibility
|
|
390
|
-
|
|
391
|
-
The module includes a **v2 proxy layer** that automatically converts v2 API calls to v4 format. This means:
|
|
392
|
-
- ✅ Existing code continues to work without changes
|
|
393
|
-
- ✅ Legacy format `{ scopes: [] }` is still supported
|
|
394
|
-
- ✅ Deprecated v2 properties like `defaultAccount` are available via v2 proxy (with deprecation warnings)
|
|
395
|
-
- ⚠️ New v4 features require using v4 format
|
|
396
|
-
|
|
397
|
-
#### Benefits of Migration
|
|
398
|
-
|
|
399
|
-
- **Better Security**: Latest MSAL v4 security improvements and token handling
|
|
400
|
-
- **Improved Performance**: Faster token acquisition, better caching, reduced memory usage
|
|
401
|
-
- **Enhanced Error Handling**: More robust error recovery and retry mechanisms
|
|
402
|
-
- **Future-Proof**: Access to latest Microsoft authentication features and updates
|
|
403
|
-
- **Shared State**: Improved authentication state management across app scopes via module hoisting
|
|
404
|
-
- **Better Developer Experience**: Cleaner API, better TypeScript support, comprehensive documentation
|
|
405
|
-
|
|
406
|
-
## Troubleshooting
|
|
407
|
-
|
|
408
|
-
### Common Issues
|
|
409
|
-
|
|
410
|
-
| Issue | Solution |
|
|
411
|
-
|-------|----------|
|
|
412
|
-
| **Authentication Loop** | Ensure redirect URIs match your application's routing |
|
|
413
|
-
| **Token Acquisition Fails** | Check that required scopes are properly configured |
|
|
414
|
-
| **Module Not Found** | Ensure the module is properly configured and framework is initialized |
|
|
415
|
-
| **Multiple MSAL Instances** | Remove duplicate configurations from child modules |
|
|
416
|
-
| **Redirect Returns Void** | For redirect flows, use `handleRedirect()` after navigation completes |
|
|
417
|
-
| **Token Empty/Undefined** | Verify user is authenticated and scopes are correct |
|
|
418
|
-
|
|
419
|
-
### Getting Help
|
|
420
|
-
|
|
421
|
-
- 📖 [MSAL Cookbook](https://github.com/equinor/fusion-framework/tree/main/cookbooks/app-react-msal) - Complete working examples
|
|
422
|
-
- 🐛 [Report Issues](https://github.com/equinor/fusion/issues) - Bug reports and feature requests
|
|
423
|
-
|
|
424
|
-
## Version Management
|
|
425
|
-
|
|
426
|
-
The MSAL module includes built-in version checking to ensure compatibility between different MSAL library versions.
|
|
427
|
-
|
|
428
|
-
### Version Resolution
|
|
429
|
-
|
|
430
|
-
```typescript
|
|
431
|
-
import { resolveVersion, VersionError } from '@equinor/fusion-framework-module-msal/versioning';
|
|
432
|
-
|
|
433
|
-
// Resolve and validate a version
|
|
434
|
-
const result = resolveVersion('2.0.0');
|
|
435
|
-
console.log(result.isLatest); // false
|
|
436
|
-
console.log(result.satisfiesLatest); // true
|
|
437
|
-
console.log(result.enumVersion); // MsalModuleVersion.V2
|
|
438
|
-
```
|
|
439
|
-
|
|
440
|
-
### Version Checking Behavior
|
|
441
|
-
|
|
442
|
-
- **Major Version Incompatibility**: Throws `VersionError` if requested major version is greater than latest
|
|
443
|
-
- **Minor Version Mismatch**: Logs warning but allows execution
|
|
444
|
-
- **Patch Differences**: Ignored for compatibility
|
|
445
|
-
- **Invalid Versions**: Throws `VersionError` with descriptive message
|
|
446
|
-
|
|
447
|
-
### API Reference
|
|
448
|
-
|
|
449
|
-
#### `resolveVersion(version: string | SemVer): ResolvedVersion`
|
|
450
|
-
|
|
451
|
-
Resolves and validates a version string against the latest available MSAL version.
|
|
452
|
-
|
|
453
|
-
**Parameters:**
|
|
454
|
-
- `version` - Version string or SemVer object to resolve
|
|
455
|
-
|
|
456
|
-
**Returns:** `ResolvedVersion` object containing:
|
|
457
|
-
- `wantedVersion: SemVer` - The parsed requested version
|
|
458
|
-
- `latestVersion: SemVer` - The latest available version
|
|
459
|
-
- `isLatest: boolean` - Whether the version is exactly the latest
|
|
460
|
-
- `satisfiesLatest: boolean` - Whether the major version matches latest
|
|
461
|
-
- `enumVersion: MsalModuleVersion` - Corresponding enum version
|
|
462
|
-
|
|
463
|
-
**Throws:** `VersionError` for invalid or incompatible versions
|
|
464
|
-
|
|
465
|
-
#### `VersionError`
|
|
466
|
-
|
|
467
|
-
Error class for version-related issues with the following types:
|
|
468
|
-
- `InvalidVersion` - Requested version is not a valid semver
|
|
469
|
-
- `InvalidLatestVersion` - Latest version parsing failed (build issue)
|
|
470
|
-
- `MajorIncompatibility` - Major version is greater than latest
|
|
471
|
-
- `MinorMismatch` - Minor version differs (warning only)
|
|
472
|
-
- `PatchDifference` - Patch version differs (info only)
|
|
473
|
-
- `IncompatibleVersion` - General incompatibility
|
|
474
|
-
|
|
475
|
-
### Error Handling
|
|
476
|
-
|
|
477
|
-
```typescript
|
|
478
|
-
import { resolveVersion, VersionError } from '@equinor/fusion-framework-module-msal/versioning';
|
|
479
|
-
|
|
480
|
-
try {
|
|
481
|
-
const result = resolveVersion('3.0.0'); // Assuming latest is 2.x
|
|
482
|
-
} catch (error) {
|
|
483
|
-
if (error instanceof VersionError) {
|
|
484
|
-
console.error('Version error:', error.message);
|
|
485
|
-
console.error('Requested:', error.requestedVersion);
|
|
486
|
-
console.error('Latest:', error.latestVersion);
|
|
487
|
-
console.error('Type:', error.type);
|
|
488
|
-
}
|
|
489
|
-
}
|
|
490
|
-
```
|
|
491
|
-
|
|
492
144
|
## Additional Resources
|
|
493
145
|
|
|
494
146
|
### Official Documentation
|
|
@@ -507,6 +159,3 @@ try {
|
|
|
507
159
|
- 💬 For questions: [Fusion Framework Discussions](https://github.com/equinor/fusion-framework/discussions)
|
|
508
160
|
- 🐛 Report bugs: [Fusion Framework Issues](https://github.com/equinor/fusion-framework/issues)
|
|
509
161
|
- 📧 Contact: Equinor Fusion Framework Team
|
|
510
|
-
|
|
511
|
-
|
|
512
|
-
|
package/dist/esm/MsalClient.js
CHANGED
|
@@ -84,11 +84,14 @@ export class MsalClient extends PublicClientApplication {
|
|
|
84
84
|
* - **Redirect**: Navigates browser to Microsoft login page. Returns `void` because the browser
|
|
85
85
|
* navigates to a new page. After redirect completes, the result will be available via
|
|
86
86
|
* `handleRedirectPromise()` when the app loads on the new page.
|
|
87
|
+
*
|
|
88
|
+
* @throws {Error} If an invalid `options.behavior` value is provided.
|
|
87
89
|
*/
|
|
88
90
|
async login(options) {
|
|
89
91
|
// Attempt silent authentication first if enabled
|
|
90
92
|
// This provides better UX by avoiding unnecessary popups/redirects
|
|
91
93
|
if (options.silent) {
|
|
94
|
+
// Warn early when neither an account nor login hint is available for silent SSO
|
|
92
95
|
if (!options.request.account && !options.request.loginHint) {
|
|
93
96
|
this.getLogger().warning('No account or login hint provided, please provide an account or login hint in the request', options.request.correlationId || FUSION_CORRELATION_ID);
|
|
94
97
|
}
|
|
@@ -146,6 +149,7 @@ export class MsalClient extends PublicClientApplication {
|
|
|
146
149
|
* ```
|
|
147
150
|
*/
|
|
148
151
|
async logout(options) {
|
|
152
|
+
// Warn when no account was supplied since the active account will be used instead
|
|
149
153
|
if (!options?.account) {
|
|
150
154
|
this.getLogger().warning('No account available for logout, please provide an account in the options', FUSION_CORRELATION_ID);
|
|
151
155
|
}
|
|
@@ -177,18 +181,23 @@ export class MsalClient extends PublicClientApplication {
|
|
|
177
181
|
*
|
|
178
182
|
* The default silent behavior is determined by presence of account in the request.
|
|
179
183
|
* This provides optimal UX by minimizing unnecessary user interactions.
|
|
184
|
+
*
|
|
185
|
+
* @throws {Error} If no `request` is provided in `options`.
|
|
180
186
|
*/
|
|
181
187
|
async acquireToken(options) {
|
|
182
188
|
const { behavior = 'redirect', silent = !!options.request?.account, request } = options;
|
|
189
|
+
// A request is required to know which scopes/account to acquire a token for
|
|
183
190
|
if (!request) {
|
|
184
191
|
throw new Error('No request provided, please provide a request in the options');
|
|
185
192
|
}
|
|
193
|
+
// Warn when no scopes are requested, since MSAL requires at least one scope
|
|
186
194
|
if (request.scopes.length === 0) {
|
|
187
195
|
this.getLogger().warning('No scopes provided, please provide scopes in the request option, see options.request for more information.', request.correlationId || FUSION_CORRELATION_ID);
|
|
188
196
|
}
|
|
189
197
|
// Attempt silent token acquisition first
|
|
190
198
|
// This fetches from cache or uses refresh token without user interaction
|
|
191
199
|
if (silent) {
|
|
200
|
+
// Only silent-acquire when an account is available to look up cached tokens for
|
|
192
201
|
if (request.account) {
|
|
193
202
|
try {
|
|
194
203
|
this.getLogger().verbose('Attempting to acquire token silently', request.correlationId || FUSION_CORRELATION_ID);
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"MsalClient.js","sourceRoot":"","sources":["../../src/MsalClient.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,uBAAuB,GAOxB,MAAM,qBAAqB,CAAC;AAa7B;;;GAGG;AACH,MAAM,qBAAqB,GAAG,EAAE,CAAC;AAqCjC;;;;;;;;;;;;;;;;;;;GAmBG;AACH,MAAM,OAAO,UAAW,SAAQ,uBAAuB;IACrD,SAAS,CAAU;IACnB,SAAS,CAAU;IACnB,kBAAkB,CAAqB;IAEvC;;;;OAIG;IACH,YAAY,MAAwB;QAClC,KAAK,CAAC,MAAM,CAAC,CAAC;QACd,IAAI,CAAC,SAAS,GAAG,MAAM,CAAC,IAAI,EAAE,QAAQ,CAAC;QACvC,IAAI,CAAC,SAAS,GAAG,MAAM,CAAC,IAAI,EAAE,QAAQ,CAAC;QACvC,IAAI,CAAC,kBAAkB,GAAG,MAAM,CAAC,iBAAiB,CAAC;IACrD,CAAC;IAED;;;;OAIG;IACH,IAAI,QAAQ;QACV,OAAO,IAAI,CAAC,SAAS,CAAC;IACxB,CAAC;IAED;;;;OAIG;IACH,IAAI,QAAQ;QACV,OAAO,IAAI,CAAC,SAAS,CAAC;IACxB,CAAC;IAED;;;;;;;OAOG;IACH,IAAI,cAAc;QAChB,MAAM,aAAa,GAAG,IAAI,CAAC,gBAAgB,EAAE,EAAE,aAAa,CAAC;QAC7D,wEAAwE;QACxE,OAAO,MAAM,CAAC,aAAa,EAAE,GAAG,CAAC,GAAG,MAAM,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,GAAG,EAAE,GAAG,IAAI,CAAC,CAAC,CAAC;IAC3E,CAAC;IAED
|
|
1
|
+
{"version":3,"file":"MsalClient.js","sourceRoot":"","sources":["../../src/MsalClient.ts"],"names":[],"mappings":"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"}
|