@owlmeans/web-oauth 0.1.18-rc.2 → 0.1.18-rc.21

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
@@ -6,7 +6,7 @@ This package ships embedded agent skills under `agent-meta/`. After installing y
6
6
  your project's skill store (`.agents/skills/`):
7
7
 
8
8
  ```sh
9
- npx @owlmeans/agent-skills@^0.1.18-rc.30
9
+ npx @owlmeans/agent-skills@^0.1.18-rc.49
10
10
  ```
11
11
 
12
12
  The embedded files are version-matched to this package release. Do not edit them
@@ -1,8 +1,8 @@
1
1
  {
2
2
  "schemaVersion": 2,
3
3
  "package": "@owlmeans/web-oauth",
4
- "version": "0.1.18-rc.2",
5
- "generatedAt": "2026-09-19T13:42:56.269Z",
4
+ "version": "0.1.18-rc.21",
5
+ "generatedAt": "2026-10-05T21:03:06.408Z",
6
6
  "canonicalRepo": "https://github.com/owlmeans/common",
7
7
  "entries": [
8
8
  {
@@ -8,7 +8,7 @@ user-invocable: false
8
8
  # @owlmeans/web-oauth
9
9
 
10
10
  **Layer:** Web (React, shadcn + Tailwind v4)
11
- **Install:** `"@owlmeans/web-oauth": "^0.1.18-rc.2"` in `dependencies`
11
+ **Install:** `"@owlmeans/web-oauth": "^0.1.18-rc.21"` in `dependencies`
12
12
  **Contracts:** `@owlmeans/oauth` — aliases, `makeOAuthProtocols`, `oauthFlow`, `ConsentView`
13
13
  **Server half:** `@owlmeans/server-oauth` (its `consentUrl`/`deviceUrl` must point at these screens)
14
14
 
@@ -80,9 +80,9 @@ of this package's runtime, and `tests/package-boundary.spec.ts` fails on any `fr
80
80
 
81
81
  The consent screen never assumes a session. When `auth.authenticated()` is empty it builds
82
82
  `makeFlowModel(oauthFlow)` (never the live flow slot), sets `ref`, transits the explicit `sign-in`
83
- step, calls `suspendFlow(context, model, { expiresAt: now + OAUTH_SUSPEND_TTL_MS })` and sends the
83
+ step, calls `flowLandingOf(context).suspendFlow(model, { expiresAt: now + OAUTH_SUSPEND_TTL_MS })` and sends the
84
84
  browser to `DISPATCHER`. The chooser / Google / supervisor sign-in then lands through
85
- `resumeSuspendedFlow` (the landing rule in `/login-plugins`, `/client-flow`) — back on the consent
85
+ `flowLandingOf(context).resumeSuspendedFlow` (the landing rule in `/login-plugins`, `/client-flow`) — back on the consent
86
86
  screen with the **same `ref`**, now authenticated. What is stored is the destination entrypoint alias
87
87
  plus the payload query, delete-on-read and expiry-checked, in `FLOW_STATE` (IndexedDB, so it survives
88
88
  Google's full-page round trip). A plugin that still navigates to `HOME` instead of the landing breaks
@@ -3,7 +3,7 @@ import { useCallback, useEffect, useState } from 'react';
3
3
  import { useContext, useNavigate } from '@owlmeans/client';
4
4
  import { useI18nLib } from '@owlmeans/client-i18n';
5
5
  import { makeFlowModel } from '@owlmeans/flow';
6
- import { normalizeUserCode, oauthFlow, OAuthFlowStep, OAUTH_PAYLOAD_REF } from '@owlmeans/oauth';
6
+ import { oauthFlow, oauthFormatHelper, OAuthFlowStep, OAUTH_PAYLOAD_REF } from '@owlmeans/oauth';
7
7
  import { OAUTH_I18N } from '../consts.js';
8
8
  import { Button } from '../@/components/ui/button.js';
9
9
  import { Card, CardContent, CardDescription, CardHeader, CardTitle } from '../@/components/ui/card.js';
@@ -25,7 +25,7 @@ export const OAuthDeviceScreen = () => {
25
25
  const proceed = useCallback(async (typed) => {
26
26
  const model = await makeFlowModel(oauthFlow);
27
27
  model.enter(OAuthFlowStep.Verify);
28
- model.updatePayload({ [OAUTH_PAYLOAD_REF]: normalizeUserCode(typed) });
28
+ model.updatePayload({ [OAUTH_PAYLOAD_REF]: oauthFormatHelper.normalizeUserCode(typed) });
29
29
  model.transit('next', true);
30
30
  const destination = model.step();
31
31
  await nav.navigate(context.entrypoint(destination.module), { query: model.payload() });
@@ -1 +1 @@
1
- {"version":3,"file":"device-screen.js","sourceRoot":"","sources":["../../src/components/device-screen.tsx"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"device-screen.js","sourceRoot":"","sources":["../../src/components/device-screen.tsx"],"names":[],"mappings":"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"}
@@ -0,0 +1,16 @@
1
+ import type { ConsentView } from '@owlmeans/oauth';
2
+ export type ConsentStage = 'checking' | 'signing-in' | 'loading' | 'ready' | 'deciding' | 'done' | 'error';
3
+ /** Why the screen cannot go on — the screen phrases each kind as ONE sentence, never the wire text. */
4
+ export type ConsentErrorKind = 'missing' | 'not-found' | 'expired' | 'forbidden' | 'failed';
5
+ export interface UseOAuthConsent {
6
+ stage: ConsentStage;
7
+ view: ConsentView | null;
8
+ /** The raw failure, for a log; what a person reads is `errorKind`. */
9
+ error: string | null;
10
+ errorKind: ConsentErrorKind | null;
11
+ approve: () => Promise<void>;
12
+ deny: () => Promise<void>;
13
+ /** Sign the current session out and go through the sign-in again, returning to this request. */
14
+ switchAccount: () => Promise<void>;
15
+ }
16
+ //# sourceMappingURL=types.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/hooks/types.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,iBAAiB,CAAA;AAElD,MAAM,MAAM,YAAY,GAAG,UAAU,GAAG,YAAY,GAAG,SAAS,GAAG,OAAO,GAAG,UAAU,GAAG,MAAM,GAAG,OAAO,CAAA;AAE1G,uGAAuG;AACvG,MAAM,MAAM,gBAAgB,GAAG,SAAS,GAAG,WAAW,GAAG,SAAS,GAAG,WAAW,GAAG,QAAQ,CAAA;AAE3F,MAAM,WAAW,eAAe;IAC9B,KAAK,EAAE,YAAY,CAAA;IACnB,IAAI,EAAE,WAAW,GAAG,IAAI,CAAA;IACxB,sEAAsE;IACtE,KAAK,EAAE,MAAM,GAAG,IAAI,CAAA;IACpB,SAAS,EAAE,gBAAgB,GAAG,IAAI,CAAA;IAClC,OAAO,EAAE,MAAM,OAAO,CAAC,IAAI,CAAC,CAAA;IAC5B,IAAI,EAAE,MAAM,OAAO,CAAC,IAAI,CAAC,CAAA;IACzB,gGAAgG;IAChG,aAAa,EAAE,MAAM,OAAO,CAAC,IAAI,CAAC,CAAA;CACnC"}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=types.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.js","sourceRoot":"","sources":["../../src/hooks/types.ts"],"names":[],"mappings":""}
@@ -1,18 +1,5 @@
1
- import type { ConsentView, OAuthEntrypointOptions } from '@owlmeans/oauth';
2
- export type ConsentStage = 'checking' | 'signing-in' | 'loading' | 'ready' | 'deciding' | 'done' | 'error';
3
- /** Why the screen cannot go on — the screen phrases each kind as ONE sentence, never the wire text. */
4
- export type ConsentErrorKind = 'missing' | 'not-found' | 'expired' | 'forbidden' | 'failed';
5
- export interface UseOAuthConsent {
6
- stage: ConsentStage;
7
- view: ConsentView | null;
8
- /** The raw failure, for a log; what a person reads is `errorKind`. */
9
- error: string | null;
10
- errorKind: ConsentErrorKind | null;
11
- approve: () => Promise<void>;
12
- deny: () => Promise<void>;
13
- /** Sign the current session out and go through the sign-in again, returning to this request. */
14
- switchAccount: () => Promise<void>;
15
- }
1
+ import { type OAuthEntrypointOptions } from '@owlmeans/oauth';
2
+ import type { UseOAuthConsent } from './types.js';
16
3
  /**
17
4
  * The whole consent screen's logic, headless — so the rendered component stays a thin shell over
18
5
  * whatever a consuming app's own primitives look like, the same split `@owlmeans/web-auth-token`
@@ -1 +1 @@
1
- {"version":3,"file":"use-oauth-consent.d.ts","sourceRoot":"","sources":["../../src/hooks/use-oauth-consent.ts"],"names":[],"mappings":"AAWA,OAAO,KAAK,EAAE,WAAW,EAAE,sBAAsB,EAAE,MAAM,iBAAiB,CAAA;AAI1E,MAAM,MAAM,YAAY,GAAG,UAAU,GAAG,YAAY,GAAG,SAAS,GAAG,OAAO,GAAG,UAAU,GAAG,MAAM,GAAG,OAAO,CAAA;AAE1G,uGAAuG;AACvG,MAAM,MAAM,gBAAgB,GAAG,SAAS,GAAG,WAAW,GAAG,SAAS,GAAG,WAAW,GAAG,QAAQ,CAAA;AAE3F,MAAM,WAAW,eAAe;IAC9B,KAAK,EAAE,YAAY,CAAA;IACnB,IAAI,EAAE,WAAW,GAAG,IAAI,CAAA;IACxB,sEAAsE;IACtE,KAAK,EAAE,MAAM,GAAG,IAAI,CAAA;IACpB,SAAS,EAAE,gBAAgB,GAAG,IAAI,CAAA;IAClC,OAAO,EAAE,MAAM,OAAO,CAAC,IAAI,CAAC,CAAA;IAC5B,IAAI,EAAE,MAAM,OAAO,CAAC,IAAI,CAAC,CAAA;IACzB,gGAAgG;IAChG,aAAa,EAAE,MAAM,OAAO,CAAC,IAAI,CAAC,CAAA;CACnC;AAQD;;;;;;;;;GASG;AACH,eAAO,MAAM,eAAe,QAAS,MAAM,GAAG,IAAI,YAAY,sBAAsB,KAAG,eAkHtF,CAAA"}
1
+ {"version":3,"file":"use-oauth-consent.d.ts","sourceRoot":"","sources":["../../src/hooks/use-oauth-consent.ts"],"names":[],"mappings":"AAOA,OAAO,EAAyG,KAAK,sBAAsB,EAAE,MAAM,iBAAiB,CAAA;AAGpK,OAAO,KAAK,EAAkC,eAAe,EAAE,MAAM,YAAY,CAAA;AASjF;;;;;;;;;GASG;AACH,eAAO,MAAM,eAAe,QAAS,MAAM,GAAG,IAAI,YAAY,sBAAsB,KAAG,eAkHtF,CAAA"}
@@ -2,11 +2,11 @@ import { useCallback, useEffect, useRef, useState } from 'react';
2
2
  import { useContext, useNavigate } from '@owlmeans/client';
3
3
  import { DEFAULT_ALIAS as AUTH_SERVICE } from '@owlmeans/client-auth';
4
4
  import { DISPATCHER } from '@owlmeans/auth';
5
- import { suspendFlow } from '@owlmeans/client-flow';
6
5
  import { makeFlowModel } from '@owlmeans/flow';
7
6
  import { ResilientError } from '@owlmeans/error';
8
7
  import { makeOAuthProtocols, oauthFlow, OAuthFlowStep, OAUTH_PAYLOAD_KIND, OAUTH_PAYLOAD_REF } from '@owlmeans/oauth';
9
8
  import { OAUTH_SUSPEND_TTL_MS } from '../consts.js';
9
+ import { flowLandingOf } from '@owlmeans/client-flow';
10
10
  const errorKindOf = (message) => message.includes('request-expired') ? 'expired'
11
11
  : message.includes('request-not-found') ? 'not-found'
12
12
  : message.includes('forbidden') ? 'forbidden'
@@ -44,7 +44,7 @@ export const useOAuthConsent = (ref, aliases) => {
44
44
  const model = await makeFlowModel(oauthFlow);
45
45
  model.updatePayload({ [OAUTH_PAYLOAD_REF]: target });
46
46
  model.transit(OAuthFlowStep.SignIn, true);
47
- await suspendFlow(context, model, { expiresAt: Date.now() + OAUTH_SUSPEND_TTL_MS });
47
+ await flowLandingOf(context).suspendFlow(model, { expiresAt: Date.now() + OAUTH_SUSPEND_TTL_MS });
48
48
  const dispatcher = await context.entrypoint(DISPATCHER).url();
49
49
  window.location.href = dispatcher;
50
50
  };
@@ -1 +1 @@
1
- {"version":3,"file":"use-oauth-consent.js","sourceRoot":"","sources":["../../src/hooks/use-oauth-consent.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"use-oauth-consent.js","sourceRoot":"","sources":["../../src/hooks/use-oauth-consent.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,35 @@
1
+ {
2
+ "consent": {
3
+ "checking": "Vérification de votre session…",
4
+ "loading": "Chargement de la demande…",
5
+ "framed": "Cet écran ne peut pas s’afficher dans une autre page. Ouvrez-le directement.",
6
+ "error": "Une erreur est survenue. Réessayez depuis l’application qui vous a envoyé ici.",
7
+ "title": "{{client}} souhaite accéder à votre compte",
8
+ "known": "Vous avez déjà utilisé cette application.",
9
+ "known-by-host": "Demande provenant de {{host}}.",
10
+ "unverified": "Cette application s’est enregistrée elle-même et n’a pas été vérifiée.",
11
+ "device-code": "Code : {{code}}",
12
+ "device-name": "Appareil : {{name}}",
13
+ "redirect-host": "Vous retournerez vers {{host}}.",
14
+ "localhost-warning": "Cette application n’a enregistré que des adresses de votre ordinateur. N’approuvez que si vous venez de démarrer vous-même la connexion.",
15
+ "scope": "Accès demandé : {{scopes}}",
16
+ "approve": "Autoriser",
17
+ "deny": "Refuser",
18
+ "error-missing": "Il n’y a rien à autoriser ici. Redémarrez la connexion depuis l’application.",
19
+ "error-not-found": "Cette demande est inconnue ou a déjà été utilisée. Redémarrez la connexion depuis l’application.",
20
+ "error-expired": "Cette demande a expiré. Redémarrez la connexion depuis l’application.",
21
+ "error-forbidden": "Ce type de compte ne peut pas autoriser l’accès. Connectez-vous avec le compte que vous utilisez pour OwlMeans puis réessayez.",
22
+ "switch-account": "Utiliser un autre compte"
23
+ },
24
+ "device": {
25
+ "title": "Connecter un appareil",
26
+ "description": "Saisissez le code affiché par l’application que vous connectez.",
27
+ "code-label": "Code",
28
+ "continue": "Continuer"
29
+ },
30
+ "done": {
31
+ "title": "Vous êtes connecté",
32
+ "message": "Vous pouvez fermer cette fenêtre et continuer dans l’application qui vous a envoyé ici.",
33
+ "device-message": "Vous pouvez fermer cette fenêtre. L’application poursuivra automatiquement."
34
+ }
35
+ }
package/build/i18n.js CHANGED
@@ -1,4 +1,3 @@
1
- import { addI18nLib } from '@owlmeans/i18n';
2
1
  import { OAUTH_I18N } from './consts.js';
3
2
  import en from './i18n/en.json' with { type: 'json' };
4
3
  import pl from './i18n/pl.json' with { type: 'json' };
@@ -7,11 +6,14 @@ import be from './i18n/be.json' with { type: 'json' };
7
6
  import uk from './i18n/uk.json' with { type: 'json' };
8
7
  import es from './i18n/es.json' with { type: 'json' };
9
8
  import de from './i18n/de.json' with { type: 'json' };
10
- addI18nLib('en', OAUTH_I18N, en);
11
- addI18nLib('pl', OAUTH_I18N, pl);
12
- addI18nLib('ru', OAUTH_I18N, ru);
13
- addI18nLib('be', OAUTH_I18N, be);
14
- addI18nLib('uk', OAUTH_I18N, uk);
15
- addI18nLib('es', OAUTH_I18N, es);
16
- addI18nLib('de', OAUTH_I18N, de);
9
+ import fr from './i18n/fr.json' with { type: 'json' };
10
+ import { i18nHelper } from '@owlmeans/i18n';
11
+ i18nHelper.addI18nLib('en', OAUTH_I18N, en);
12
+ i18nHelper.addI18nLib('pl', OAUTH_I18N, pl);
13
+ i18nHelper.addI18nLib('ru', OAUTH_I18N, ru);
14
+ i18nHelper.addI18nLib('be', OAUTH_I18N, be);
15
+ i18nHelper.addI18nLib('uk', OAUTH_I18N, uk);
16
+ i18nHelper.addI18nLib('es', OAUTH_I18N, es);
17
+ i18nHelper.addI18nLib('de', OAUTH_I18N, de);
18
+ i18nHelper.addI18nLib('fr', OAUTH_I18N, fr);
17
19
  //# sourceMappingURL=i18n.js.map
package/build/i18n.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"i18n.js","sourceRoot":"","sources":["../src/i18n.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,MAAM,gBAAgB,CAAA;AAC3C,OAAO,EAAE,UAAU,EAAE,MAAM,aAAa,CAAA;AAExC,OAAO,EAAE,MAAM,gBAAgB,CAAC,OAAO,IAAI,EAAE,MAAM,EAAE,CAAA;AACrD,OAAO,EAAE,MAAM,gBAAgB,CAAC,OAAO,IAAI,EAAE,MAAM,EAAE,CAAA;AACrD,OAAO,EAAE,MAAM,gBAAgB,CAAC,OAAO,IAAI,EAAE,MAAM,EAAE,CAAA;AACrD,OAAO,EAAE,MAAM,gBAAgB,CAAC,OAAO,IAAI,EAAE,MAAM,EAAE,CAAA;AACrD,OAAO,EAAE,MAAM,gBAAgB,CAAC,OAAO,IAAI,EAAE,MAAM,EAAE,CAAA;AACrD,OAAO,EAAE,MAAM,gBAAgB,CAAC,OAAO,IAAI,EAAE,MAAM,EAAE,CAAA;AACrD,OAAO,EAAE,MAAM,gBAAgB,CAAC,OAAO,IAAI,EAAE,MAAM,EAAE,CAAA;AAErD,UAAU,CAAC,IAAI,EAAE,UAAU,EAAE,EAAE,CAAC,CAAA;AAChC,UAAU,CAAC,IAAI,EAAE,UAAU,EAAE,EAAE,CAAC,CAAA;AAChC,UAAU,CAAC,IAAI,EAAE,UAAU,EAAE,EAAE,CAAC,CAAA;AAChC,UAAU,CAAC,IAAI,EAAE,UAAU,EAAE,EAAE,CAAC,CAAA;AAChC,UAAU,CAAC,IAAI,EAAE,UAAU,EAAE,EAAE,CAAC,CAAA;AAChC,UAAU,CAAC,IAAI,EAAE,UAAU,EAAE,EAAE,CAAC,CAAA;AAChC,UAAU,CAAC,IAAI,EAAE,UAAU,EAAE,EAAE,CAAC,CAAA"}
1
+ {"version":3,"file":"i18n.js","sourceRoot":"","sources":["../src/i18n.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,UAAU,EAAE,MAAM,aAAa,CAAA;AAExC,OAAO,EAAE,MAAM,gBAAgB,CAAC,OAAO,IAAI,EAAE,MAAM,EAAE,CAAA;AACrD,OAAO,EAAE,MAAM,gBAAgB,CAAC,OAAO,IAAI,EAAE,MAAM,EAAE,CAAA;AACrD,OAAO,EAAE,MAAM,gBAAgB,CAAC,OAAO,IAAI,EAAE,MAAM,EAAE,CAAA;AACrD,OAAO,EAAE,MAAM,gBAAgB,CAAC,OAAO,IAAI,EAAE,MAAM,EAAE,CAAA;AACrD,OAAO,EAAE,MAAM,gBAAgB,CAAC,OAAO,IAAI,EAAE,MAAM,EAAE,CAAA;AACrD,OAAO,EAAE,MAAM,gBAAgB,CAAC,OAAO,IAAI,EAAE,MAAM,EAAE,CAAA;AACrD,OAAO,EAAE,MAAM,gBAAgB,CAAC,OAAO,IAAI,EAAE,MAAM,EAAE,CAAA;AACrD,OAAO,EAAE,MAAM,gBAAgB,CAAC,OAAO,IAAI,EAAE,MAAM,EAAE,CAAA;AACrD,OAAO,EAAE,UAAU,EAAE,MAAM,gBAAgB,CAAA;AAE3C,UAAU,CAAC,UAAU,CAAC,IAAI,EAAE,UAAU,EAAE,EAAE,CAAC,CAAA;AAC3C,UAAU,CAAC,UAAU,CAAC,IAAI,EAAE,UAAU,EAAE,EAAE,CAAC,CAAA;AAC3C,UAAU,CAAC,UAAU,CAAC,IAAI,EAAE,UAAU,EAAE,EAAE,CAAC,CAAA;AAC3C,UAAU,CAAC,UAAU,CAAC,IAAI,EAAE,UAAU,EAAE,EAAE,CAAC,CAAA;AAC3C,UAAU,CAAC,UAAU,CAAC,IAAI,EAAE,UAAU,EAAE,EAAE,CAAC,CAAA;AAC3C,UAAU,CAAC,UAAU,CAAC,IAAI,EAAE,UAAU,EAAE,EAAE,CAAC,CAAA;AAC3C,UAAU,CAAC,UAAU,CAAC,IAAI,EAAE,UAAU,EAAE,EAAE,CAAC,CAAA;AAC3C,UAAU,CAAC,UAAU,CAAC,IAAI,EAAE,UAAU,EAAE,EAAE,CAAC,CAAA"}
package/build/index.d.ts CHANGED
@@ -2,6 +2,7 @@ export * from './consts.js';
2
2
  export * from './append.js';
3
3
  export * from './entrypoints.js';
4
4
  export * from './hooks/use-oauth-consent.js';
5
+ export type * from './hooks/types.js';
5
6
  export * from './components/index.js';
6
7
  export * from './i18n.js';
7
8
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,cAAc,aAAa,CAAA;AAC3B,cAAc,aAAa,CAAA;AAC3B,cAAc,kBAAkB,CAAA;AAChC,cAAc,8BAA8B,CAAA;AAC5C,cAAc,uBAAuB,CAAA;AACrC,cAAc,WAAW,CAAA"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,cAAc,aAAa,CAAA;AAC3B,cAAc,aAAa,CAAA;AAC3B,cAAc,kBAAkB,CAAA;AAChC,cAAc,8BAA8B,CAAA;AAC5C,mBAAmB,kBAAkB,CAAA;AACrC,cAAc,uBAAuB,CAAA;AACrC,cAAc,WAAW,CAAA"}
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,cAAc,aAAa,CAAA;AAC3B,cAAc,aAAa,CAAA;AAC3B,cAAc,kBAAkB,CAAA;AAChC,cAAc,8BAA8B,CAAA;AAC5C,cAAc,uBAAuB,CAAA;AACrC,cAAc,WAAW,CAAA"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,cAAc,aAAa,CAAA;AAC3B,cAAc,aAAa,CAAA;AAC3B,cAAc,kBAAkB,CAAA;AAChC,cAAc,8BAA8B,CAAA;AAE5C,cAAc,uBAAuB,CAAA;AACrC,cAAc,WAAW,CAAA"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@owlmeans/web-oauth",
3
- "version": "0.1.18-rc.2",
3
+ "version": "0.1.18-rc.21",
4
4
  "license": "MIT",
5
5
  "description": "The browser half of @owlmeans/oauth — the consent, device-code and done screens an OAuth 2.1 sign-in ends on, driven by the shared consent flow, plus the entrypoints and app-config helper that put them on a web app with no wiring beyond configuration.",
6
6
  "type": "module",
@@ -23,20 +23,20 @@
23
23
  }
24
24
  },
25
25
  "dependencies": {
26
- "@owlmeans/auth-common": "^0.1.18-rc.30",
27
- "@owlmeans/client": "^0.1.18-rc.33",
28
- "@owlmeans/client-auth": "^0.1.18-rc.39",
29
- "@owlmeans/client-context": "^0.1.18-rc.31",
30
- "@owlmeans/client-entrypoint": "^0.1.18-rc.30",
31
- "@owlmeans/client-flow": "^0.1.18-rc.35",
32
- "@owlmeans/client-i18n": "^0.1.18-rc.32",
33
- "@owlmeans/context": "^0.1.18-rc.26",
34
- "@owlmeans/entrypoint": "^0.1.18-rc.29",
35
- "@owlmeans/error": "^0.1.18-rc.28",
36
- "@owlmeans/flow": "^0.1.18-rc.31",
37
- "@owlmeans/i18n": "^0.1.18-rc.29",
38
- "@owlmeans/oauth": "^0.1.18-rc.2",
39
- "@owlmeans/route": "^0.1.18-rc.27"
26
+ "@owlmeans/auth-common": "^0.1.18-rc.47",
27
+ "@owlmeans/client": "^0.1.18-rc.51",
28
+ "@owlmeans/client-auth": "^0.1.18-rc.58",
29
+ "@owlmeans/client-context": "^0.1.18-rc.48",
30
+ "@owlmeans/client-entrypoint": "^0.1.18-rc.47",
31
+ "@owlmeans/client-flow": "^0.1.18-rc.54",
32
+ "@owlmeans/client-i18n": "^0.1.18-rc.50",
33
+ "@owlmeans/context": "^0.1.18-rc.34",
34
+ "@owlmeans/entrypoint": "^0.1.18-rc.41",
35
+ "@owlmeans/error": "^0.1.18-rc.38",
36
+ "@owlmeans/flow": "^0.1.18-rc.45",
37
+ "@owlmeans/i18n": "^0.1.18-rc.39",
38
+ "@owlmeans/oauth": "^0.1.18-rc.16",
39
+ "@owlmeans/route": "^0.1.18-rc.35"
40
40
  },
41
41
  "peerDependencies": {
42
42
  "@radix-ui/react-label": "*",
@@ -50,26 +50,26 @@
50
50
  },
51
51
  "devDependencies": {
52
52
  "@owlmeans/dep-config": "workspace:*",
53
- "@owlmeans/test-auth": "^0.1.18-rc.29",
54
- "@owlmeans/test-ui": "^0.1.18-rc.31",
55
- "@owlmeans/web-client": "^0.1.18-rc.42",
56
- "@owlmeans/web-flow": "^0.1.18-rc.34",
57
- "@radix-ui/react-label": "^2.1.0",
58
- "@radix-ui/react-slot": "^1.1.0",
59
- "@tailwindcss/vite": "^4.0.0",
60
- "@types/bun": "^1.4.0",
61
- "@types/react": "^19.2.17",
62
- "@types/react-dom": "^19.2.3",
63
- "@vitejs/plugin-react": "^6.0.3",
64
- "class-variance-authority": "^0.7.0",
65
- "clsx": "^2.1.0",
66
- "idb-keyval": "^6.2.1",
53
+ "@owlmeans/test-auth": "^0.1.18-rc.46",
54
+ "@owlmeans/test-ui": "^0.1.18-rc.49",
55
+ "@owlmeans/web-client": "^0.1.18-rc.61",
56
+ "@owlmeans/web-flow": "^0.1.18-rc.53",
57
+ "@radix-ui/react-label": "^2.1.15",
58
+ "@radix-ui/react-slot": "^1.3.3",
59
+ "@tailwindcss/vite": "^4.3.3",
60
+ "@types/bun": "^1.4.2",
61
+ "@types/react": "^19.3.0",
62
+ "@types/react-dom": "^19.3.0",
63
+ "@vitejs/plugin-react": "^6.1.1",
64
+ "class-variance-authority": "^0.7.1",
65
+ "clsx": "^2.1.1",
66
+ "idb-keyval": "^6.3.0",
67
67
  "nodemon": "^3.1.14",
68
- "playwright": "^1.61.1",
69
- "tailwind-merge": "^3.6.0",
70
- "tailwindcss": "^4.0.0",
68
+ "playwright": "^1.63.0",
69
+ "tailwind-merge": "^3.7.0",
70
+ "tailwindcss": "^4.3.3",
71
71
  "typescript": "^7.0.2",
72
- "vite": "^8.1.2"
72
+ "vite": "^8.3.2"
73
73
  },
74
74
  "publishConfig": {
75
75
  "access": "public"
@@ -5,7 +5,7 @@ import type { RoutedComponent } from '@owlmeans/client'
5
5
  import { useI18nLib } from '@owlmeans/client-i18n'
6
6
  import type { ClientEntrypoint } from '@owlmeans/client-entrypoint'
7
7
  import { makeFlowModel } from '@owlmeans/flow'
8
- import { normalizeUserCode, oauthFlow, OAuthFlowStep, OAUTH_PAYLOAD_REF } from '@owlmeans/oauth'
8
+ import { oauthFlow, oauthFormatHelper, OAuthFlowStep, OAUTH_PAYLOAD_REF } from '@owlmeans/oauth'
9
9
  import { OAUTH_I18N } from '../consts.js'
10
10
  import { Button } from '../@/components/ui/button.js'
11
11
  import { Card, CardContent, CardDescription, CardHeader, CardTitle } from '../@/components/ui/card.js'
@@ -29,7 +29,7 @@ export const OAuthDeviceScreen: RoutedComponent = () => {
29
29
  const proceed = useCallback(async (typed: string) => {
30
30
  const model = await makeFlowModel(oauthFlow)
31
31
  model.enter(OAuthFlowStep.Verify)
32
- model.updatePayload({ [OAUTH_PAYLOAD_REF]: normalizeUserCode(typed) })
32
+ model.updatePayload({ [OAUTH_PAYLOAD_REF]: oauthFormatHelper.normalizeUserCode(typed) })
33
33
  model.transit('next', true)
34
34
  const destination = model.step()
35
35
  await nav.navigate(
@@ -0,0 +1,18 @@
1
+ import type { ConsentView } from '@owlmeans/oauth'
2
+
3
+ export type ConsentStage = 'checking' | 'signing-in' | 'loading' | 'ready' | 'deciding' | 'done' | 'error'
4
+
5
+ /** Why the screen cannot go on — the screen phrases each kind as ONE sentence, never the wire text. */
6
+ export type ConsentErrorKind = 'missing' | 'not-found' | 'expired' | 'forbidden' | 'failed'
7
+
8
+ export interface UseOAuthConsent {
9
+ stage: ConsentStage
10
+ view: ConsentView | null
11
+ /** The raw failure, for a log; what a person reads is `errorKind`. */
12
+ error: string | null
13
+ errorKind: ConsentErrorKind | null
14
+ approve: () => Promise<void>
15
+ deny: () => Promise<void>
16
+ /** Sign the current session out and go through the sign-in again, returning to this request. */
17
+ switchAccount: () => Promise<void>
18
+ }
@@ -3,32 +3,13 @@ import { useContext, useNavigate } from '@owlmeans/client'
3
3
  import { DEFAULT_ALIAS as AUTH_SERVICE } from '@owlmeans/client-auth'
4
4
  import type { AuthService } from '@owlmeans/auth-common'
5
5
  import { DISPATCHER } from '@owlmeans/auth'
6
- import { suspendFlow } from '@owlmeans/client-flow'
7
6
  import { makeFlowModel } from '@owlmeans/flow'
8
7
  import { ResilientError } from '@owlmeans/error'
9
- import {
10
- makeOAuthProtocols, oauthFlow, OAuthFlowStep, OAUTH_PAYLOAD_KIND, OAUTH_PAYLOAD_REF
11
- } from '@owlmeans/oauth'
12
- import type { ConsentView, OAuthEntrypointOptions } from '@owlmeans/oauth'
8
+ import { makeOAuthProtocols, oauthFlow, OAuthFlowStep, OAUTH_PAYLOAD_KIND, OAUTH_PAYLOAD_REF, type ConsentView, type OAuthEntrypointOptions } from '@owlmeans/oauth'
13
9
  import type { ClientEntrypoint } from '@owlmeans/client-entrypoint'
14
10
  import { OAUTH_SUSPEND_TTL_MS } from '../consts.js'
15
-
16
- export type ConsentStage = 'checking' | 'signing-in' | 'loading' | 'ready' | 'deciding' | 'done' | 'error'
17
-
18
- /** Why the screen cannot go on — the screen phrases each kind as ONE sentence, never the wire text. */
19
- export type ConsentErrorKind = 'missing' | 'not-found' | 'expired' | 'forbidden' | 'failed'
20
-
21
- export interface UseOAuthConsent {
22
- stage: ConsentStage
23
- view: ConsentView | null
24
- /** The raw failure, for a log; what a person reads is `errorKind`. */
25
- error: string | null
26
- errorKind: ConsentErrorKind | null
27
- approve: () => Promise<void>
28
- deny: () => Promise<void>
29
- /** Sign the current session out and go through the sign-in again, returning to this request. */
30
- switchAccount: () => Promise<void>
31
- }
11
+ import type { ConsentErrorKind, ConsentStage, UseOAuthConsent } from './types.js'
12
+ import { flowLandingOf } from '@owlmeans/client-flow'
32
13
 
33
14
  const errorKindOf = (message: string): ConsentErrorKind =>
34
15
  message.includes('request-expired') ? 'expired'
@@ -72,7 +53,7 @@ export const useOAuthConsent = (ref: string | null, aliases?: OAuthEntrypointOpt
72
53
  const model = await makeFlowModel(oauthFlow)
73
54
  model.updatePayload({ [OAUTH_PAYLOAD_REF]: target })
74
55
  model.transit(OAuthFlowStep.SignIn, true)
75
- await suspendFlow(context, model, { expiresAt: Date.now() + OAUTH_SUSPEND_TTL_MS })
56
+ await flowLandingOf(context).suspendFlow(model, { expiresAt: Date.now() + OAUTH_SUSPEND_TTL_MS })
76
57
 
77
58
  const dispatcher = await context.entrypoint<ClientEntrypoint<string>>(DISPATCHER).url()
78
59
  window.location.href = dispatcher
@@ -0,0 +1,35 @@
1
+ {
2
+ "consent": {
3
+ "checking": "Vérification de votre session…",
4
+ "loading": "Chargement de la demande…",
5
+ "framed": "Cet écran ne peut pas s’afficher dans une autre page. Ouvrez-le directement.",
6
+ "error": "Une erreur est survenue. Réessayez depuis l’application qui vous a envoyé ici.",
7
+ "title": "{{client}} souhaite accéder à votre compte",
8
+ "known": "Vous avez déjà utilisé cette application.",
9
+ "known-by-host": "Demande provenant de {{host}}.",
10
+ "unverified": "Cette application s’est enregistrée elle-même et n’a pas été vérifiée.",
11
+ "device-code": "Code : {{code}}",
12
+ "device-name": "Appareil : {{name}}",
13
+ "redirect-host": "Vous retournerez vers {{host}}.",
14
+ "localhost-warning": "Cette application n’a enregistré que des adresses de votre ordinateur. N’approuvez que si vous venez de démarrer vous-même la connexion.",
15
+ "scope": "Accès demandé : {{scopes}}",
16
+ "approve": "Autoriser",
17
+ "deny": "Refuser",
18
+ "error-missing": "Il n’y a rien à autoriser ici. Redémarrez la connexion depuis l’application.",
19
+ "error-not-found": "Cette demande est inconnue ou a déjà été utilisée. Redémarrez la connexion depuis l’application.",
20
+ "error-expired": "Cette demande a expiré. Redémarrez la connexion depuis l’application.",
21
+ "error-forbidden": "Ce type de compte ne peut pas autoriser l’accès. Connectez-vous avec le compte que vous utilisez pour OwlMeans puis réessayez.",
22
+ "switch-account": "Utiliser un autre compte"
23
+ },
24
+ "device": {
25
+ "title": "Connecter un appareil",
26
+ "description": "Saisissez le code affiché par l’application que vous connectez.",
27
+ "code-label": "Code",
28
+ "continue": "Continuer"
29
+ },
30
+ "done": {
31
+ "title": "Vous êtes connecté",
32
+ "message": "Vous pouvez fermer cette fenêtre et continuer dans l’application qui vous a envoyé ici.",
33
+ "device-message": "Vous pouvez fermer cette fenêtre. L’application poursuivra automatiquement."
34
+ }
35
+ }
package/src/i18n.ts CHANGED
@@ -1,4 +1,4 @@
1
- import { addI18nLib } from '@owlmeans/i18n'
1
+
2
2
  import { OAUTH_I18N } from './consts.js'
3
3
 
4
4
  import en from './i18n/en.json' with { type: 'json' }
@@ -8,11 +8,14 @@ import be from './i18n/be.json' with { type: 'json' }
8
8
  import uk from './i18n/uk.json' with { type: 'json' }
9
9
  import es from './i18n/es.json' with { type: 'json' }
10
10
  import de from './i18n/de.json' with { type: 'json' }
11
+ import fr from './i18n/fr.json' with { type: 'json' }
12
+ import { i18nHelper } from '@owlmeans/i18n'
11
13
 
12
- addI18nLib('en', OAUTH_I18N, en)
13
- addI18nLib('pl', OAUTH_I18N, pl)
14
- addI18nLib('ru', OAUTH_I18N, ru)
15
- addI18nLib('be', OAUTH_I18N, be)
16
- addI18nLib('uk', OAUTH_I18N, uk)
17
- addI18nLib('es', OAUTH_I18N, es)
18
- addI18nLib('de', OAUTH_I18N, de)
14
+ i18nHelper.addI18nLib('en', OAUTH_I18N, en)
15
+ i18nHelper.addI18nLib('pl', OAUTH_I18N, pl)
16
+ i18nHelper.addI18nLib('ru', OAUTH_I18N, ru)
17
+ i18nHelper.addI18nLib('be', OAUTH_I18N, be)
18
+ i18nHelper.addI18nLib('uk', OAUTH_I18N, uk)
19
+ i18nHelper.addI18nLib('es', OAUTH_I18N, es)
20
+ i18nHelper.addI18nLib('de', OAUTH_I18N, de)
21
+ i18nHelper.addI18nLib('fr', OAUTH_I18N, fr)
package/src/index.ts CHANGED
@@ -2,5 +2,6 @@ export * from './consts.js'
2
2
  export * from './append.js'
3
3
  export * from './entrypoints.js'
4
4
  export * from './hooks/use-oauth-consent.js'
5
+ export type * from './hooks/types.js'
5
6
  export * from './components/index.js'
6
7
  export * from './i18n.js'
@@ -1,12 +1,12 @@
1
1
  import { afterAll, describe, expect, test } from 'bun:test'
2
- import { closeBrowser } from '@owlmeans/test-ui'
3
2
  import { OAUTH_CONSENT_PATH, oauth } from '@owlmeans/oauth'
4
3
  import { OAUTH_SUSPEND_TTL_MS } from '../src/consts.js'
5
4
  import en from '../src/i18n/en.json' with { type: 'json' }
6
- import { bearer, codeView, deviceView, open, refusal, TIMEOUT } from './helpers.js'
5
+ import { bearer, codeView, deviceView, open, refusal, TIMEOUT, untilPath } from './helpers.js'
7
6
  import { HARNESS_URL } from './context.js'
7
+ import { browserHelper } from '@owlmeans/test-ui'
8
8
 
9
- afterAll(async () => { await closeBrowser() })
9
+ afterAll(async () => { await browserHelper.closeBrowser() })
10
10
 
11
11
  const CONSENT = `${OAUTH_CONSENT_PATH}?ref=ABCD-EFGH`
12
12
 
@@ -15,7 +15,7 @@ describe('consent screen — signed out', () => {
15
15
  const before = Date.now()
16
16
  const { page, calls, close } = await open(CONSENT)
17
17
  try {
18
- await page.waitForURL(url => url.pathname === '/dispatcher', { timeout: 45_000 })
18
+ await untilPath(page, '/dispatcher', 45_000)
19
19
 
20
20
  // Nobody is signed in, so there is nothing to load and nothing to approve.
21
21
  expect(calls).toEqual([])
@@ -44,7 +44,7 @@ describe('consent screen — the round trip through sign-in', () => {
44
44
  authenticate: true, stubs: { load: { json: deviceView() }, approve: { json: {} } },
45
45
  })
46
46
  try {
47
- await page.waitForURL(url => url.pathname === '/dispatcher', { timeout: 45_000 })
47
+ await untilPath(page, '/dispatcher', 45_000)
48
48
  expect(await page.evaluate(async () => await (window as any).__oauth.suspended())).not.toBeNull()
49
49
 
50
50
  // Any sign-in method ends the same way: the dispatcher is handed a token.
@@ -79,7 +79,7 @@ describe('consent screen — signed in', () => {
79
79
  expect(calls).toEqual(['GET ABCD-EFGH'])
80
80
 
81
81
  await page.getByTestId('oauth-consent-approve').click()
82
- await page.waitForURL(url => url.pathname === '/oauth/done', { timeout: 30_000 })
82
+ await untilPath(page, '/oauth/done', 30_000)
83
83
 
84
84
  expect(calls).toEqual(['GET ABCD-EFGH', 'POST ABCD-EFGH/approve'])
85
85
  expect(new URL(page.url()).searchParams.get('kind')).toBe('device')
@@ -127,7 +127,7 @@ describe('consent screen — signed in', () => {
127
127
  try {
128
128
  await page.getByTestId('oauth-consent-approve').waitFor({ state: 'visible', timeout: 45_000 })
129
129
  await page.getByTestId('oauth-consent-approve').click()
130
- await page.waitForURL(url => url.pathname === '/client-callback', { timeout: 30_000 })
130
+ await untilPath(page, '/client-callback', 30_000)
131
131
 
132
132
  expect(page.url()).toBe(target)
133
133
  expect(calls).toEqual(['GET req-1', 'POST req-1/approve'])
@@ -144,7 +144,7 @@ describe('consent screen — signed in', () => {
144
144
  try {
145
145
  await code.page.getByTestId('oauth-consent-deny').waitFor({ state: 'visible', timeout: 45_000 })
146
146
  await code.page.getByTestId('oauth-consent-deny').click()
147
- await code.page.waitForURL(url => url.pathname === '/client-callback', { timeout: 30_000 })
147
+ await untilPath(code.page, '/client-callback', 30_000)
148
148
 
149
149
  expect(code.page.url()).toBe(back)
150
150
  expect(code.calls).toEqual(['GET req-1', 'POST req-1/deny'])
@@ -158,7 +158,7 @@ describe('consent screen — signed in', () => {
158
158
  try {
159
159
  await device.page.getByTestId('oauth-consent-deny').waitFor({ state: 'visible', timeout: 45_000 })
160
160
  await device.page.getByTestId('oauth-consent-deny').click()
161
- await device.page.waitForURL(url => url.pathname === '/oauth/done', { timeout: 30_000 })
161
+ await untilPath(device.page, '/oauth/done', 30_000)
162
162
 
163
163
  expect(device.calls).toEqual(['GET ABCD-EFGH', 'POST ABCD-EFGH/deny'])
164
164
  expect(await device.page.getByTestId('oauth-done-card').count()).toBe(1)
@@ -176,7 +176,7 @@ describe('consent screen — signed in', () => {
176
176
  expect(await page.evaluate(async () => await (window as any).__oauth.token())).not.toBeNull()
177
177
 
178
178
  await page.getByTestId('oauth-consent-switch').click()
179
- await page.waitForURL(url => url.pathname === '/dispatcher', { timeout: 45_000 })
179
+ await untilPath(page, '/dispatcher', 45_000)
180
180
 
181
181
  expect(await page.evaluate(async () => await (window as any).__oauth.token())).toBeNull()
182
182
  const record = await page.evaluate(async () => await (window as any).__oauth.suspended()) as
@@ -1,9 +1,9 @@
1
1
  import { afterAll, describe, expect, test } from 'bun:test'
2
- import { closeBrowser } from '@owlmeans/test-ui'
3
2
  import { OAUTH_CONSENT_PATH, OAUTH_DEVICE_PATH } from '@owlmeans/oauth'
4
3
  import { deviceView, open, TIMEOUT } from './helpers.js'
4
+ import { browserHelper } from '@owlmeans/test-ui'
5
5
 
6
- afterAll(async () => { await closeBrowser() })
6
+ afterAll(async () => { await browserHelper.closeBrowser() })
7
7
 
8
8
  describe('device screen — a link that already carries the code', () => {
9
9
  test('goes straight to the consent screen for that code, normalised', async () => {
@@ -1,10 +1,10 @@
1
1
  import { afterAll, describe, expect, test } from 'bun:test'
2
- import { closeBrowser } from '@owlmeans/test-ui'
3
2
  import { OAUTH_DONE_PATH } from '@owlmeans/oauth'
4
3
  import en from '../src/i18n/en.json' with { type: 'json' }
5
4
  import { open, TIMEOUT } from './helpers.js'
5
+ import { browserHelper } from '@owlmeans/test-ui'
6
6
 
7
- afterAll(async () => { await closeBrowser() })
7
+ afterAll(async () => { await browserHelper.closeBrowser() })
8
8
 
9
9
  describe('done screen', () => {
10
10
  test('a device sign-in tells the person to close the window — the application picks it up', async () => {
@@ -0,0 +1 @@
1
+ declare module '*.css'
@@ -45,6 +45,10 @@ service({
45
45
  }, base)
46
46
  base.security = { unsecure: true }
47
47
  ;(base as { i18n?: unknown }).i18n = { defaultLng: lng, fallbackLng: lng }
48
+ // The app starts in a persisted choice first and the BROWSER's language second — headless Chromium
49
+ // says `en-US`, which beats `fallbackLng`. Stored the way `setLanguage` stores a person's choice
50
+ // (`owlmeans-lng`), so `?lng` wins on every load, whatever an earlier page of this context chose.
51
+ try { localStorage.setItem('owlmeans-lng', lng) } catch (_) { /* storage blocked: stays on the browser's */ }
48
52
 
49
53
  // `ready` stays false: the Router compiles the entrypoint tree into routes ONLY while the context
50
54
  // is un-initialized.
package/tests/helpers.ts CHANGED
@@ -1,8 +1,9 @@
1
- import { launchBrowser } from '@owlmeans/test-ui'
1
+
2
2
  import type { Page } from '@owlmeans/test-ui'
3
3
  import { makeBearer, USER } from '@owlmeans/test-auth'
4
4
  import type { ConsentView } from '@owlmeans/oauth'
5
5
  import { HARNESS_URL } from './context.js'
6
+ import { browserHelper } from '@owlmeans/test-ui'
6
7
 
7
8
  /** Generous: a cold harness compiles the whole app on its first request. */
8
9
  export const TIMEOUT = 60_000
@@ -56,7 +57,7 @@ export interface Opened {
56
57
  export const open = async (
57
58
  path: string, opts: { stubs?: Stubs, signedIn?: boolean, lng?: string, authenticate?: boolean } = {}
58
59
  ): Promise<Opened> => {
59
- const browser = await launchBrowser({ headless: true })
60
+ const browser = await browserHelper.launchBrowser({ headless: true })
60
61
  const context = await browser.newContext()
61
62
  const page = await context.newPage()
62
63
  page.setDefaultTimeout(30_000)
@@ -95,3 +96,17 @@ export const open = async (
95
96
 
96
97
  return { page, calls, close: async () => { await context.close() } }
97
98
  }
99
+
100
+ /**
101
+ * Wait until the page sits on `pathname`, reading `page.url()` rather than awaiting a navigation.
102
+ * Signing out reloads before the router pushes the dispatcher, and under load `waitForURL` sees the
103
+ * superseded navigation abort (`net::ERR_ABORTED; maybe frame was detached?`) instead of the one that lands.
104
+ */
105
+ export const untilPath = async (page: Page, pathname: string, timeout = 45_000): Promise<void> => {
106
+ const deadline = Date.now() + timeout
107
+ while (new URL(page.url()).pathname !== pathname) {
108
+ if (Date.now() > deadline) throw new Error(`still on ${page.url()} after ${timeout} ms, expected ${pathname}`)
109
+ await new Promise(resolve => setTimeout(resolve, 100))
110
+ }
111
+ await page.waitForLoadState('load').catch(() => undefined)
112
+ }
@@ -1,5 +1,4 @@
1
1
  import { afterAll, describe, expect, test } from 'bun:test'
2
- import { closeBrowser } from '@owlmeans/test-ui'
3
2
  import { OAUTH_CONSENT_PATH } from '@owlmeans/oauth'
4
3
  import en from '../src/i18n/en.json' with { type: 'json' }
5
4
  import pl from '../src/i18n/pl.json' with { type: 'json' }
@@ -9,8 +8,9 @@ import uk from '../src/i18n/uk.json' with { type: 'json' }
9
8
  import es from '../src/i18n/es.json' with { type: 'json' }
10
9
  import de from '../src/i18n/de.json' with { type: 'json' }
11
10
  import { deviceView, open, TIMEOUT } from './helpers.js'
11
+ import { browserHelper } from '@owlmeans/test-ui'
12
12
 
13
- afterAll(async () => { await closeBrowser() })
13
+ afterAll(async () => { await browserHelper.closeBrowser() })
14
14
 
15
15
  const LANGUAGES = { en, pl, ru, be, uk, es, de }
16
16