@equinor/fusion-framework-vite-plugin-spa 4.1.4 → 5.1.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/README.md CHANGED
@@ -177,7 +177,6 @@ fusionSpaPlugin({
177
177
  redirectUri: 'https://my-app.com/auth-callback',
178
178
  requiresAuth: 'true',
179
179
  mock: 'true', // (Optional) Use mock authentication for CI/Playwright
180
- mockToken: '<token>', // (Optional) JWT that identifies the mock user
181
180
  },
182
181
 
183
182
  // Service Worker configuration for API proxying and authentication
@@ -241,7 +240,6 @@ Configures Azure AD authentication via the Microsoft Authentication Library (MSA
241
240
  - `redirectUri` — URL to redirect to after authentication
242
241
  - `requiresAuth` _(optional, string)_ — When `'true'`, automatically prompts for login on first load
243
242
  - `mock` _(optional, string)_ — When `'true'`, uses mock authentication instead of Entra ID
244
- - `mockToken` _(optional, string)_ — JWT used as-is to identify and authenticate the mock user
245
243
 
246
244
  ### Service Worker
247
245
 
@@ -396,8 +394,8 @@ FUSION_SPA_MSAL_REDIRECT_URI=https://my-app.com/auth-callback
396
394
  FUSION_SPA_MSAL_REQUIRES_AUTH=true
397
395
  # Set to skip Entra ID and sign in a mock user instead — for CI/Playwright runs
398
396
  FUSION_SPA_MSAL_MOCK=true
399
- # Optional: a mock JWT whose claims (name, preferred_username, oid, tid, scp) name the signed-in user
400
- FUSION_SPA_MSAL_MOCK_TOKEN=eyJhbGciOiJub25lIiwidHlwIjoiSldUIn0....
397
+ # Optional: standalone mock-server origin used for session-scoped token acquisition
398
+ FUSION_SPA_MSAL_MOCK_SERVER_URL=http://localhost:4010
401
399
 
402
400
  # Telemetry
403
401
  FUSION_SPA_TELEMETRY_CONSOLE_LEVEL=2
@@ -423,103 +421,23 @@ server headlessly in GitHub Actions or a Playwright suite.
423
421
  FUSION_SPA_MSAL_MOCK=true
424
422
  ```
425
423
 
426
- By default the mock signs in a generic `Test User`. To control who that user is, set
427
- `FUSION_SPA_MSAL_MOCK_TOKEN` to a JWT — generate one with `createMockToken` from
428
- `@equinor/fusion-framework-module-msal/mock`, or use one issued by your backend's own mock —
429
- and its `name`, `preferred_username`, `oid`, `tid`, and `scp` claims name the signed-in user:
430
-
431
- ```ts
432
- import { createMockToken } from '@equinor/fusion-framework-module-msal/mock';
433
-
434
- const token = createMockToken({
435
- name: 'Ada Lovelace',
436
- preferred_username: 'ada.lovelace@equinor.com',
437
- oid: 'ada-object-id',
438
- scp: 'user_impersonation',
439
- });
440
- ```
441
-
442
- ```sh
443
- FUSION_SPA_MSAL_MOCK_TOKEN=<token>
444
- ```
445
-
446
- ### Generate a mock user and update `.env`
447
-
448
- > [!WARNING]
449
- > The script below writes `FUSION_SPA_MSAL_MOCK=true` to the project-root `.env`. This is
450
- > persistent configuration: the application remains locked to mock authentication across restarts
451
- > until the variable is removed or set to `false`. `ffc app dev --mock` and
452
- > `ffc app serve --mock` already enable mock authentication for that command, so do not persist
453
- > `FUSION_SPA_MSAL_MOCK=true` merely to use those CLI flags. Never deploy an environment file that
454
- > enables mock authentication.
455
-
456
- Run the following from the application root. The application needs
457
- `@equinor/fusion-framework-module-msal` as a direct development dependency so the Node.js script
458
- can import `createMockToken` when pnpm uses strict dependency resolution:
459
-
460
- ```sh
461
- pnpm add --save-dev @equinor/fusion-framework-module-msal
462
- ```
463
-
464
- Create `scripts/set-mock-user.mjs`. The script creates the project-root `.env` when it does not
465
- exist. When `.env` already exists, it preserves comments and unrelated variables while replacing
466
- the existing mock-auth values or appending them when absent:
467
-
468
- ```js
469
- #!/usr/bin/env node
470
-
471
- import { readFile, writeFile } from 'node:fs/promises';
472
- import { createMockToken } from '@equinor/fusion-framework-module-msal/mock';
473
-
474
- const envFile = new URL('../.env', import.meta.url);
475
- const token = createMockToken({
476
- name: 'Ada Lovelace',
477
- preferred_username: 'ada.lovelace@equinor.com',
478
- oid: 'ada-object-id',
479
- scp: 'user_impersonation',
480
- });
481
-
482
- let contents = await readFile(envFile, 'utf8').catch((error) => {
483
- if (error.code === 'ENOENT') return '';
484
- throw error;
485
- });
486
-
487
- const updates = {
488
- FUSION_SPA_MSAL_MOCK: 'true',
489
- FUSION_SPA_MSAL_MOCK_TOKEN: token,
490
- };
491
-
492
- for (const [key, value] of Object.entries(updates)) {
493
- const line = `${key}=${value}`;
494
- const existing = new RegExp(`^${key}=.*$`, 'm');
495
- if (existing.test(contents)) {
496
- contents = contents.replace(existing, line);
497
- } else {
498
- const separator = contents.length > 0 && !contents.endsWith('\n') ? '\n' : '';
499
- contents = `${contents}${separator}${line}\n`;
500
- }
501
- }
502
-
503
- await writeFile(envFile, contents);
504
- console.log('Updated .env with the mock user token.');
505
- ```
506
-
507
- Make the script executable and run it:
424
+ By default the mock signs in a generic `Test User`. To select and switch users at runtime, start
425
+ the standalone mock server with the browser origin explicitly allowed, then point the app at it:
508
426
 
509
427
  ```sh
510
- chmod +x scripts/set-mock-user.mjs
511
- ./scripts/set-mock-user.mjs
428
+ ffc mock-server ./mocks --port 4010 --allow-origin http://localhost:3000
429
+ ffc app dev --mock http://localhost:4010
512
430
  ```
513
431
 
514
- Restart the Vite or Fusion Framework development server after updating `.env`. To return to real
515
- Entra ID authentication, remove both `FUSION_SPA_MSAL_MOCK` and `FUSION_SPA_MSAL_MOCK_TOKEN` from
516
- `.env` (or set `FUSION_SPA_MSAL_MOCK=false`), then restart the server again. The generated JWT is
517
- deterministic and unsigned; use it only with the in-process MSAL mock and mocked backend services,
518
- never as a credential for a real service.
432
+ The `--mock` option enables mock authentication and supplies the mock-server URL to the SPA. A
433
+ direct Vite setup can provide the same values through `FUSION_SPA_MSAL_MOCK=true` and
434
+ `FUSION_SPA_MSAL_MOCK_SERVER_URL=http://localhost:4010`.
519
435
 
520
- The token itself is also sent as-is as the access/id token — it is not regenerated — so a
521
- backend mock that validates its own tokens (specific claims, audience, or signature) sees
522
- exactly the token it issued.
436
+ Playwright and other cookie-aware HTTP clients can select users through `createMockAuth` from
437
+ `@equinor/fusion-openapi-mock-server`. The standalone mock server stores the user per browser
438
+ context and issues an unsigned OBO-style token for each scope set requested by Fusion MSAL. This
439
+ supports switching and parallel personas without restarting the app or dev server; see the
440
+ [Playwright guide](../../utils/openapi-mock-server/docs/testing-with-playwright.md).
523
441
 
524
442
  Mocking authentication does not mock the rest of the API surface — service discovery and
525
443
  any backend calls the portal makes still hit real URLs unless you also override them. Use
@@ -718,5 +636,3 @@ See [API Service Plugin docs](https://github.com/equinor/fusion-framework/tree/m
718
636
  ## Contributing
719
637
 
720
638
  Contributions, bug reports, and feature requests are welcome! See [CONTRIBUTING.md](../../../CONTRIBUTING.md) for guidelines.
721
-
722
-
@@ -0,0 +1,40 @@
1
+ /**
2
+ * Acquires a token for the active browser session from a Fusion mock server.
3
+ *
4
+ * @param mockServerUrl - Origin of the standalone mock server.
5
+ * @param scopes - OAuth scopes requested by MSAL.
6
+ * @param request - Fetch-compatible browser request function.
7
+ * @returns The issued token, or `null` when the session has no selected user.
8
+ * @throws When the mock server rejects the request or returns an unsupported response.
9
+ */
10
+ export async function acquireMockServerToken(mockServerUrl, scopes, request = globalThis.fetch) {
11
+ const response = await request(new URL('/@fusion-mock/auth/token', mockServerUrl), {
12
+ method: 'POST',
13
+ credentials: 'include',
14
+ headers: { 'content-type': 'application/json' },
15
+ body: JSON.stringify({ scopes }),
16
+ });
17
+ // Surface protocol and configuration failures instead of falling back to another identity.
18
+ if (!response.ok) {
19
+ throw new Error(`Mock auth token acquisition failed with status ${response.status}`);
20
+ }
21
+ const resolution = await response.json();
22
+ // A missing persona deliberately restores the MSAL mock's built-in identity.
23
+ if (typeof resolution === 'object' &&
24
+ resolution !== null &&
25
+ 'status' in resolution &&
26
+ resolution.status === 'missing') {
27
+ return null;
28
+ }
29
+ // Accept only the documented issued-token response shape.
30
+ if (typeof resolution === 'object' &&
31
+ resolution !== null &&
32
+ 'status' in resolution &&
33
+ resolution.status === 'issued' &&
34
+ 'token' in resolution &&
35
+ typeof resolution.token === 'string') {
36
+ return resolution.token;
37
+ }
38
+ throw new Error('Mock auth token acquisition returned an unsupported status');
39
+ }
40
+ //# sourceMappingURL=acquire-mock-server-token.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"acquire-mock-server-token.js","sourceRoot":"","sources":["../../../src/html/acquire-mock-server-token.ts"],"names":[],"mappings":"AAEA;;;;;;;;GAQG;AACH,MAAM,CAAC,KAAK,UAAU,sBAAsB,CAC1C,aAAqB,EACrB,MAAgB,EAChB,OAAO,GAAoB,UAAU,CAAC,KAAK;IAE3C,MAAM,QAAQ,GAAG,MAAM,OAAO,CAAC,IAAI,GAAG,CAAC,0BAA0B,EAAE,aAAa,CAAC,EAAE;QACjF,MAAM,EAAE,MAAM;QACd,WAAW,EAAE,SAAS;QACtB,OAAO,EAAE,EAAE,cAAc,EAAE,kBAAkB,EAAE;QAC/C,IAAI,EAAE,IAAI,CAAC,SAAS,CAAC,EAAE,MAAM,EAAE,CAAC;KACjC,CAAC,CAAC;IAEH,2FAA2F;IAC3F,IAAI,CAAC,QAAQ,CAAC,EAAE,EAAE,CAAC;QACjB,MAAM,IAAI,KAAK,CAAC,kDAAkD,QAAQ,CAAC,MAAM,EAAE,CAAC,CAAC;IACvF,CAAC;IAED,MAAM,UAAU,GAAY,MAAM,QAAQ,CAAC,IAAI,EAAE,CAAC;IAClD,6EAA6E;IAC7E,IACE,OAAO,UAAU,KAAK,QAAQ;QAC9B,UAAU,KAAK,IAAI;QACnB,QAAQ,IAAI,UAAU;QACtB,UAAU,CAAC,MAAM,KAAK,SAAS,EAC/B,CAAC;QACD,OAAO,IAAI,CAAC;IACd,CAAC;IACD,0DAA0D;IAC1D,IACE,OAAO,UAAU,KAAK,QAAQ;QAC9B,UAAU,KAAK,IAAI;QACnB,QAAQ,IAAI,UAAU;QACtB,UAAU,CAAC,MAAM,KAAK,QAAQ;QAC9B,OAAO,IAAI,UAAU;QACrB,OAAO,UAAU,CAAC,KAAK,KAAK,QAAQ,EACpC,CAAC;QACD,OAAO,UAAU,CAAC,KAAK,CAAC;IAC1B,CAAC;IACD,MAAM,IAAI,KAAK,CAAC,4DAA4D,CAAC,CAAC;AAChF,CAAC"}
@@ -4,6 +4,7 @@ import { enableMSAL } from '@equinor/fusion-framework-module-msal';
4
4
  import { enableServiceDiscovery, } from '@equinor/fusion-framework-module-service-discovery';
5
5
  import { enableTelemetry, TelemetryLevel, } from '@equinor/fusion-framework-module-telemetry';
6
6
  import { ConsoleAdapter } from '@equinor/fusion-framework-module-telemetry/console-adapter';
7
+ import { acquireMockServerToken } from './acquire-mock-server-token.js';
7
8
  import { createPortalEntryPoint } from './create-portal-entry-point.js';
8
9
  import { isEnabledEnvValue } from './is-enabled-env-value.js';
9
10
  import { registerServiceWorker } from './register-service-worker.js';
@@ -27,12 +28,12 @@ enableServiceDiscovery(configurator, async (builder) => {
27
28
  // Avoid interactive Entra ID authentication when the SPA runs in CI or Playwright.
28
29
  if (isEnabledEnvValue(import.meta.env.FUSION_SPA_MSAL_MOCK)) {
29
30
  const { enableMsalMock } = await import('@equinor/fusion-framework-module-msal/mock');
30
- const mockToken = import.meta.env.FUSION_SPA_MSAL_MOCK_TOKEN;
31
+ const mockServerUrl = import.meta.env.FUSION_SPA_MSAL_MOCK_SERVER_URL;
31
32
  enableMsalMock(configurator, (builder) => {
32
- // Preserve the mock client's default identity when no backend-specific token is configured.
33
- if (!mockToken)
34
- return;
35
- builder.setToken(mockToken);
33
+ // The SPA owns the HTTP adapter; MSAL owns applying the returned token and account.
34
+ if (mockServerUrl) {
35
+ builder.setAcquireToken(({ scopes }) => acquireMockServerToken(mockServerUrl, scopes));
36
+ }
36
37
  });
37
38
  }
38
39
  else {
@@ -1 +1 @@
1
- {"version":3,"file":"bootstrap.js","sourceRoot":"","sources":["../../../src/html/bootstrap.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"bootstrap.js","sourceRoot":"","sources":["../../../src/html/bootstrap.ts"],"names":[],"mappings":"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"}
@@ -28,6 +28,10 @@ export const html = `
28
28
  <script>
29
29
  // Set AG Grid license key globally if provided
30
30
  window.FUSION_AG_GRID_KEY = '%FUSION_SPA_AG_GRID_KEY%';
31
+
32
+ // Expose the mock server origin when served with --mock, so the portal can tell it is
33
+ // running against local mocks; the placeholder stays unreplaced (not a URL) otherwise.
34
+ window.FUSION_MOCK_SERVER_URL = '%FUSION_SPA_MSAL_MOCK_SERVER_URL%';
31
35
 
32
36
  // suppress console error for custom elements already defined.
33
37
  // WebComponents should be added by the portal, but not removed from application
@@ -1 +1 @@
1
- {"version":3,"file":"html.js","sourceRoot":"","sources":["../../../src/html/html.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,eAAe,CAAC;AAExC;;;;;;;;;;;;;;;;GAgBG;AACH,MAAM,CAAC,MAAM,IAAI,GAAG;;;;;;wDAMoC,OAAO;;;;;;;;;;;;;;;;;;;;;;;;;;;CA2B9D,CAAC;AAEF,eAAe,IAAI,CAAC"}
1
+ {"version":3,"file":"html.js","sourceRoot":"","sources":["../../../src/html/html.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,eAAe,CAAC;AAExC;;;;;;;;;;;;;;;;GAgBG;AACH,MAAM,CAAC,MAAM,IAAI,GAAG;;;;;;wDAMoC,OAAO;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CA+B9D,CAAC;AAEF,eAAe,IAAI,CAAC"}
@@ -1,3 +1,3 @@
1
1
  // Generated by genversion.
2
- export const version = '4.1.4';
2
+ export const version = '5.1.0';
3
3
  //# sourceMappingURL=version.js.map
@@ -1,4 +1,4 @@
1
- import { c as createErrorClass, _ as __extends, e as errorContext, E as EMPTY_SUBSCRIPTION, S as Subscription, a as arrRemove, O as Observable, b as __values, d as __spreadArray, f as __read, i as isFunction$1, g as SafeSubscriber, h as EmptyError, o as operate, j as executeSchedule, k as innerFrom, l as createOperatorSubscriber, m as map, n as mergeMap, p as identity, q as isArrayLike, r as isScheduler, s as popScheduler, t as popNumber, u as EMPTY, v as from, w as mergeInternals, x as scanInternals, y as noop, z as popResultSelector, A as reduce, B as lastValueFrom, M as ModuleEventLevel, C as filter, D as BaseModuleProvider, F as catchError, G as of, H as object, I as _instanceof, J as _enum, K as string, L as boolean, N as record, P as union, Q as __rest, R as __assign, T as switchMap, U as observeOn, V as deepmerge, W as BaseConfigBuilder, X as TelemetryExceptionSchema, Y as TelemetryItemNames, Z as TelemetryType, $ as TelemetryEventSchema, a0 as TelemetryMetricSchema, a1 as TelemetryCustomEventSchema, a2 as array, a3 as TelemetryLevel, a4 as enableMSAL } from '../module-CybelWKy.js';
1
+ import { c as createErrorClass, _ as __extends, e as errorContext, E as EMPTY_SUBSCRIPTION, S as Subscription, a as arrRemove, O as Observable, b as __values, d as __spreadArray, f as __read, i as isFunction$1, g as SafeSubscriber, h as EmptyError, o as operate, j as executeSchedule, k as innerFrom, l as createOperatorSubscriber, m as map, n as mergeMap, p as identity, q as isArrayLike, r as isScheduler, s as popScheduler, t as popNumber, u as EMPTY, v as from, w as mergeInternals, x as scanInternals, y as noop, z as popResultSelector, A as reduce, B as lastValueFrom, M as ModuleEventLevel, C as filter, D as BaseModuleProvider, F as catchError, G as of, H as object, I as _instanceof, J as _enum, K as string, L as boolean, N as record, P as union, Q as __rest, R as __assign, T as switchMap, U as observeOn, V as deepmerge, W as BaseConfigBuilder, X as TelemetryExceptionSchema, Y as TelemetryItemNames, Z as TelemetryType, $ as TelemetryEventSchema, a0 as TelemetryMetricSchema, a1 as TelemetryCustomEventSchema, a2 as array, a3 as TelemetryLevel, a4 as enableMSAL } from '../module-DzjJ4gjy.js';
2
2
 
3
3
  var ObjectUnsubscribedError = createErrorClass(function (_super) {
4
4
  return function ObjectUnsubscribedErrorImpl() {
@@ -2993,7 +2993,7 @@ class HttpClientConfigurator {
2993
2993
  }
2994
2994
 
2995
2995
  // Generated by genversion.
2996
- const version$3 = '8.1.1';
2996
+ const version$3 = '8.1.2';
2997
2997
 
2998
2998
  /** URL protocols accepted as valid ad-hoc base URIs. */
2999
2999
  const SUPPORTED_PROTOCOLS = ['http:', 'https:', 'ws:', 'wss:'];
@@ -9127,6 +9127,46 @@ class ConsoleAdapter extends BaseTelemetryAdapter {
9127
9127
  }
9128
9128
  }
9129
9129
 
9130
+ /**
9131
+ * Acquires a token for the active browser session from a Fusion mock server.
9132
+ *
9133
+ * @param mockServerUrl - Origin of the standalone mock server.
9134
+ * @param scopes - OAuth scopes requested by MSAL.
9135
+ * @param request - Fetch-compatible browser request function.
9136
+ * @returns The issued token, or `null` when the session has no selected user.
9137
+ * @throws When the mock server rejects the request or returns an unsupported response.
9138
+ */
9139
+ async function acquireMockServerToken(mockServerUrl, scopes, request = globalThis.fetch) {
9140
+ const response = await request(new URL('/@fusion-mock/auth/token', mockServerUrl), {
9141
+ method: 'POST',
9142
+ credentials: 'include',
9143
+ headers: { 'content-type': 'application/json' },
9144
+ body: JSON.stringify({ scopes }),
9145
+ });
9146
+ // Surface protocol and configuration failures instead of falling back to another identity.
9147
+ if (!response.ok) {
9148
+ throw new Error(`Mock auth token acquisition failed with status ${response.status}`);
9149
+ }
9150
+ const resolution = await response.json();
9151
+ // A missing persona deliberately restores the MSAL mock's built-in identity.
9152
+ if (typeof resolution === 'object' &&
9153
+ resolution !== null &&
9154
+ 'status' in resolution &&
9155
+ resolution.status === 'missing') {
9156
+ return null;
9157
+ }
9158
+ // Accept only the documented issued-token response shape.
9159
+ if (typeof resolution === 'object' &&
9160
+ resolution !== null &&
9161
+ 'status' in resolution &&
9162
+ resolution.status === 'issued' &&
9163
+ 'token' in resolution &&
9164
+ typeof resolution.token === 'string') {
9165
+ return resolution.token;
9166
+ }
9167
+ throw new Error('Mock auth token acquisition returned an unsupported status');
9168
+ }
9169
+
9130
9170
  /**
9131
9171
  * Builds the portal template entrypoint URL used by the SPA bootstrap loader.
9132
9172
  *
@@ -9362,7 +9402,7 @@ async function registerServiceWorker(framework) {
9362
9402
  }
9363
9403
 
9364
9404
  // Generated by genversion.
9365
- const version = '4.1.4';
9405
+ const version = '5.1.0';
9366
9406
 
9367
9407
  // Allow dynamic import without vite
9368
9408
  const importWithoutVite = (path) => import(/* @vite-ignore */ path);
@@ -9382,13 +9422,13 @@ enableServiceDiscovery(configurator, async (builder) => {
9382
9422
  });
9383
9423
  // Avoid interactive Entra ID authentication when the SPA runs in CI or Playwright.
9384
9424
  if (isEnabledEnvValue(import.meta.env.FUSION_SPA_MSAL_MOCK)) {
9385
- const { enableMsalMock } = await import('../index-8TS-eku8.js');
9386
- const mockToken = import.meta.env.FUSION_SPA_MSAL_MOCK_TOKEN;
9425
+ const { enableMsalMock } = await import('../index-Df9EZ6lh.js');
9426
+ const mockServerUrl = import.meta.env.FUSION_SPA_MSAL_MOCK_SERVER_URL;
9387
9427
  enableMsalMock(configurator, (builder) => {
9388
- // Preserve the mock client's default identity when no backend-specific token is configured.
9389
- if (!mockToken)
9390
- return;
9391
- builder.setToken(mockToken);
9428
+ // The SPA owns the HTTP adapter; MSAL owns applying the returned token and account.
9429
+ if (mockServerUrl) {
9430
+ builder.setAcquireToken(({ scopes }) => acquireMockServerToken(mockServerUrl, scopes));
9431
+ }
9392
9432
  });
9393
9433
  }
9394
9434
  else {