@owlmeans/client-auth 0.1.18-rc.47 → 0.1.18-rc.49
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 +4 -2
- package/agent-meta/manifest.json +2 -2
- package/agent-meta/skills/client-auth/SKILL.md +4 -2
- package/build/login/land.d.ts +4 -2
- package/build/login/land.d.ts.map +1 -1
- package/build/login/land.js +16 -8
- package/build/login/land.js.map +1 -1
- package/build/login/screen.d.ts.map +1 -1
- package/build/login/screen.js +5 -25
- package/build/login/screen.js.map +1 -1
- package/build/login/terms.d.ts +44 -0
- package/build/login/terms.d.ts.map +1 -1
- package/build/login/terms.js +59 -1
- package/build/login/terms.js.map +1 -1
- package/build/login/types.d.ts +24 -8
- package/build/login/types.d.ts.map +1 -1
- package/package.json +21 -21
- package/src/login/land.ts +19 -9
- package/src/login/screen.tsx +13 -33
- package/src/login/terms.ts +79 -1
- package/src/login/types.ts +24 -8
- package/src/manager/README.md +1 -1
- package/tests/land.spec.ts +53 -0
- package/tests/terms-deferred.spec.ts +65 -0
- package/tests/terms.spec.ts +55 -1
package/README.md
CHANGED
|
@@ -12,7 +12,7 @@ legacy). The server-side counterpart is `@owlmeans/server-auth`.
|
|
|
12
12
|
## Installation
|
|
13
13
|
|
|
14
14
|
```bash
|
|
15
|
-
bun add @owlmeans/client-auth@^0.1.18-rc.
|
|
15
|
+
bun add @owlmeans/client-auth@^0.1.18-rc.49
|
|
16
16
|
```
|
|
17
17
|
|
|
18
18
|
## Concepts
|
|
@@ -259,6 +259,8 @@ The plugin-authoring surface, with no registration side effect.
|
|
|
259
259
|
| `registerMethodSource`, `listMethodSources`, `resolveLoginMethods(ctx, cfg?, extra?)`, `primaryLoginMethod(methods)` | function | Global method sources and resolution |
|
|
260
260
|
| `LoginMethod`, `LoginMethodSource`, `LoginMethodContext` | type | Method contract |
|
|
261
261
|
| `resolveTerms(cfg?)`, `termsAccepted(resolved)`, `acceptTerms(resolved, accepted)`, `ResolvedTerms` | function, type | Terms confirmation, stored in `localStorage` against a version derived from the URLs |
|
|
262
|
+
| `termsLabelResolver(translate, locale)`, `termsAcceptanceOf(resolved, locale?)`, `TermsAcceptanceRef` | function, type | The one document-label resolver every terms renderer shares; the wire shape a sign-in-time acceptance sends the server (structurally `@owlmeans/marketing-consent`'s `TermsAcceptance`, no dependency on it) |
|
|
263
|
+
| `termsDeferred(ctx)` | function | True once a registered AND bound `LoginStep` declares `confirmsTerms` — the sign-in screen then renders no checkbox and blocks nothing, because the confirmation lives on that step instead |
|
|
262
264
|
| `resolveCredit(cfg?, brand?, service?)`, `ResolvedCredit` | function, type | The credit and copyright line |
|
|
263
265
|
| `FallbackLoginScreen`, `LoginScreenProps`, `LoginScreenComponent` | component, type | The plain screen used when no UI family registered one |
|
|
264
266
|
| `surrogatePath(ctx, target)`, `SurrogateTarget` | function, type | Where a surrogate window opens; `null` on an entrypoint list without the surrogate route |
|
|
@@ -319,7 +321,7 @@ This package ships embedded agent skills under `agent-meta/`. After installing y
|
|
|
319
321
|
your project's skill store (`.agents/skills/`):
|
|
320
322
|
|
|
321
323
|
```sh
|
|
322
|
-
npx @owlmeans/agent-skills@^0.1.18-rc.
|
|
324
|
+
npx @owlmeans/agent-skills@^0.1.18-rc.39
|
|
323
325
|
```
|
|
324
326
|
|
|
325
327
|
The embedded files are version-matched to this package release. Do not edit them
|
package/agent-meta/manifest.json
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
{
|
|
2
2
|
"schemaVersion": 2,
|
|
3
3
|
"package": "@owlmeans/client-auth",
|
|
4
|
-
"version": "0.1.18-rc.
|
|
5
|
-
"generatedAt": "2026-09-
|
|
4
|
+
"version": "0.1.18-rc.49",
|
|
5
|
+
"generatedAt": "2026-09-25T12:22:06.186Z",
|
|
6
6
|
"canonicalRepo": "https://github.com/owlmeans/common",
|
|
7
7
|
"entries": [
|
|
8
8
|
{
|
|
@@ -8,7 +8,7 @@ user-invocable: false
|
|
|
8
8
|
# @owlmeans/client-auth
|
|
9
9
|
|
|
10
10
|
**Layer:** Client
|
|
11
|
-
**Install:** `"@owlmeans/client-auth": "^0.1.18-rc.
|
|
11
|
+
**Install:** `"@owlmeans/client-auth": "^0.1.18-rc.49"` in `dependencies`
|
|
12
12
|
|
|
13
13
|
Five subpaths, five jobs:
|
|
14
14
|
|
|
@@ -88,9 +88,11 @@ browsing context the round trip can complete at all.
|
|
|
88
88
|
| `registerMethodSource`, `listMethodSources`, `resolveLoginMethods`, `primaryLoginMethod` | Which sign-in methods are offered — see `login-methods` |
|
|
89
89
|
| `LoginMethod`, `LoginMethodSource`, `LoginMethodContext` | Method types |
|
|
90
90
|
| `landAfterLogin(ctx, opts?)`, `continueLogin(ctx, opts?)`, `landingUrl(ctx, landing)`, `useContinueLogin()` | The post-login landing decision (`src/login/land.ts`) — see `login-plugins`. `landAfterLogin` runs due landing hooks then delegates to `continueLogin`, which walks pending `LoginStep`s, then `resumeSuspendedFlow`, then `LandOptions.fallback ?? { alias: HOME }`; `landingUrl` builds the absolute URL a plugin's own `window.location.href` needs; `useContinueLogin()` is what a step's own screen calls once satisfied |
|
|
91
|
-
| `LoginStep`, `LoginLanding`, `LoginLandingHook`, `LandOptions`, `LoginLandingParams` | Landing-seam types. `registerStep`/`steps`/`onLanded`/`landingHooks` on `LoginService` are the same replace-by-alias, priority-sorted registries as `registerPlugin` |
|
|
91
|
+
| `LoginStep`, `LoginLanding`, `LoginLandingHook`, `LandOptions`, `LoginLandingParams` | Landing-seam types. `registerStep`/`steps`/`onLanded`/`landingHooks` on `LoginService` are the same replace-by-alias, priority-sorted registries as `registerPlugin`. `LoginStep` also carries `confirmsTerms?: boolean` (this step is where the Terms confirmation lives — see `termsDeferred` below) and `required?: boolean` (a throw/timeout in `pending` reads as PENDING, not "not pending" — see `login-plugins`) |
|
|
92
92
|
| `LOGIN_STEP_TIMEOUT`, `LOGIN_LANDED_STORAGE` | A step's `pending`/a hook's `landed` is bounded by the former; the latter is where the last-landed token is recorded (the raw string, never a digest) |
|
|
93
93
|
| `resolveTerms`, `termsAccepted`, `acceptTerms`, `termsSentence`, `ResolvedTerms`, `ResolvedTermsDocument`, `TermsSentencePart` | The confirmation. `resolveTerms` produces `documents` (what the checkbox agrees to: terms, then billing/product/custom when configured) and `notices` (what is only disclosed: privacy, plus cookies per its own inclusion rule) — see the terms-confirmation section of `login-methods`. The extra `LoginTermsConfig` fields (`billing`, `product`, `documents`, `revisions`, `showRevision`) are added by module augmentation in `src/login/terms-config.ts`, never by editing `@owlmeans/config` — importing anything from `@owlmeans/client-auth/login` pulls it in |
|
|
94
|
+
| `termsLabelResolver(translate, locale)`, `termsAcceptanceOf(resolved, locale?)`, `TermsAcceptanceRef` | The ONE document-label resolver and ONE wire-shape builder every terms renderer/recorder shares (`FallbackLoginScreen`, `web-panel`'s `LoginTerms`, `web-marketing-consent`'s Terms box and `termsRecorder`) — no more hand-kept duplicate `DEFAULT_LABEL`/`resolveLabelFor` per package. `termsAcceptanceOf` keeps only `{key, href, revisedAt}` per document — structurally `@owlmeans/marketing-consent`'s `TermsAcceptance`, with no dependency on that package |
|
|
95
|
+
| `termsDeferred(ctx)` | True once a registered AND BOUND `LoginStep` declares `confirmsTerms` — see the "Deferring the confirmation" section of `login-methods`. Reads `ctx.hasService`/`.hasEntrypoint` directly, never `ensureLoginService` (which has the side effect of registering an empty host) |
|
|
94
96
|
| `resolveCredit`, `ResolvedCredit` | The credit and copyright line |
|
|
95
97
|
| `FallbackLoginScreen`, `LoginScreenProps` (now also carries `locale?: string`, for `Intl.ListFormat` and a custom document's locale-keyed label), `LoginScreenComponent` | The plain sign-in screen a relying party renders when no UI family registered one |
|
|
96
98
|
| `surrogatePath(ctx, target)`, `SurrogateTarget` | Where a surrogate login window opens; `null` on an older entrypoint list |
|
package/build/login/land.d.ts
CHANGED
|
@@ -2,8 +2,10 @@ import type { LandOptions, LoginContext, LoginLanding } from './types.js';
|
|
|
2
2
|
/**
|
|
3
3
|
* Bound on a single step's `pending` check, or a landing hook's `landed` call.
|
|
4
4
|
*
|
|
5
|
-
* A step/hook that hangs must never
|
|
6
|
-
* `landAfterLogin` treat a timeout exactly like a rejection
|
|
5
|
+
* A step/hook that hangs must never HANG sign-in itself — both `continueLogin` and
|
|
6
|
+
* `landAfterLogin` treat a timeout exactly like a rejection, resolving within this budget either
|
|
7
|
+
* way. What that resolves TO is fail-open ("not pending") for an ordinary step, and fail-closed
|
|
8
|
+
* ("pending") for one that declared itself `required` — see `continueLogin`'s `onBroken`.
|
|
7
9
|
*/
|
|
8
10
|
export declare const LOGIN_STEP_TIMEOUT = 5000;
|
|
9
11
|
/** Where a browser records the last token a landing hook has already run for. */
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"land.d.ts","sourceRoot":"","sources":["../../src/login/land.ts"],"names":[],"mappings":"AAUA,OAAO,KAAK,EAAE,WAAW,EAAE,YAAY,EAAE,YAAY,EAAgB,MAAM,YAAY,CAAA;AAEvF
|
|
1
|
+
{"version":3,"file":"land.d.ts","sourceRoot":"","sources":["../../src/login/land.ts"],"names":[],"mappings":"AAUA,OAAO,KAAK,EAAE,WAAW,EAAE,YAAY,EAAE,YAAY,EAAgB,MAAM,YAAY,CAAA;AAEvF;;;;;;;GAOG;AACH,eAAO,MAAM,kBAAkB,OAAQ,CAAA;AAEvC,iFAAiF;AACjF,eAAO,MAAM,oBAAoB,2BAA2B,CAAA;AAiE5D;;;;;;;;;GASG;AACH,eAAO,MAAM,aAAa,QAAe,YAAY,SAAS,WAAW,KAAG,OAAO,CAAC,YAAY,CAkD/F,CAAA;AAED;;;;;;;GAOG;AACH,eAAO,MAAM,cAAc,QAAe,YAAY,SAAS,WAAW,KAAG,OAAO,CAAC,YAAY,CAWhG,CAAA;AAED;;;GAGG;AACH,eAAO,MAAM,UAAU,QAAe,YAAY,WAAW,YAAY,KAAG,OAAO,CAAC,MAAM,CAGvF,CAAA;AAEH;;;;;;GAMG;AACH,eAAO,MAAM,gBAAgB,QAAO,CAAC,CAAC,IAAI,CAAC,EAAE,WAAW,KAAK,OAAO,CAAC,IAAI,CAAC,CAQzE,CAAA"}
|
package/build/login/land.js
CHANGED
|
@@ -8,24 +8,29 @@ import { ensureLoginService } from './service.js';
|
|
|
8
8
|
/**
|
|
9
9
|
* Bound on a single step's `pending` check, or a landing hook's `landed` call.
|
|
10
10
|
*
|
|
11
|
-
* A step/hook that hangs must never
|
|
12
|
-
* `landAfterLogin` treat a timeout exactly like a rejection
|
|
11
|
+
* A step/hook that hangs must never HANG sign-in itself — both `continueLogin` and
|
|
12
|
+
* `landAfterLogin` treat a timeout exactly like a rejection, resolving within this budget either
|
|
13
|
+
* way. What that resolves TO is fail-open ("not pending") for an ordinary step, and fail-closed
|
|
14
|
+
* ("pending") for one that declared itself `required` — see `continueLogin`'s `onBroken`.
|
|
13
15
|
*/
|
|
14
16
|
export const LOGIN_STEP_TIMEOUT = 5_000;
|
|
15
17
|
/** Where a browser records the last token a landing hook has already run for. */
|
|
16
18
|
export const LOGIN_LANDED_STORAGE = '_owlmeans-login-landed';
|
|
17
19
|
/**
|
|
18
|
-
* Race a promise against a bound, resolving `
|
|
20
|
+
* Race a promise against a bound, resolving to `onTimeout` (never rejecting) if the bound wins.
|
|
19
21
|
*
|
|
20
22
|
* A synchronous throw from the wrapped call is turned into a rejection by the caller before this
|
|
21
|
-
* ever sees it, so the only two outcomes here are "settled in time" and "timed out".
|
|
23
|
+
* ever sees it, so the only two outcomes here are "settled in time" and "timed out". `onTimeout`
|
|
24
|
+
* defaults to `undefined` — every existing caller that omits it keeps its old fail-open meaning;
|
|
25
|
+
* `continueLogin` passes a step's own `required` flag through it so a step that hangs is read the
|
|
26
|
+
* same way as one that throws.
|
|
22
27
|
*/
|
|
23
|
-
const withTimeout = async (promise, ms) => {
|
|
28
|
+
const withTimeout = async (promise, ms, onTimeout) => {
|
|
24
29
|
let timer;
|
|
25
30
|
try {
|
|
26
31
|
return await Promise.race([
|
|
27
32
|
promise,
|
|
28
|
-
new Promise(resolve => { timer = setTimeout(() => resolve(
|
|
33
|
+
new Promise(resolve => { timer = setTimeout(() => resolve(onTimeout), ms); }),
|
|
29
34
|
]);
|
|
30
35
|
}
|
|
31
36
|
finally {
|
|
@@ -102,8 +107,11 @@ export const continueLogin = async (ctx, opts) => {
|
|
|
102
107
|
if (!ctx.hasEntrypoint(step.entrypoint)) {
|
|
103
108
|
continue;
|
|
104
109
|
}
|
|
105
|
-
// A step that throws or hangs
|
|
106
|
-
|
|
110
|
+
// A step that throws or hangs fails OPEN ("not pending") by default — UNLESS it declared
|
|
111
|
+
// itself `required`, in which case a broken read must show the step rather than let the
|
|
112
|
+
// person through it unconfirmed (a Terms box moved here from the sign-in screen).
|
|
113
|
+
const onBroken = step.required === true;
|
|
114
|
+
const pending = await withTimeout(Promise.resolve().then(() => step.pending(ctx)), timeout, onBroken).catch(() => onBroken);
|
|
107
115
|
if (pending === true) {
|
|
108
116
|
return { alias: step.entrypoint, query: await step.query?.(ctx), step: step.alias };
|
|
109
117
|
}
|
package/build/login/land.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"land.js","sourceRoot":"","sources":["../../src/login/land.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,WAAW,EAAE,MAAM,OAAO,CAAA;AAEnC,OAAO,EAAE,UAAU,EAAE,MAAM,gBAAgB,CAAA;AAC3C,OAAO,EAAE,IAAI,EAAE,MAAM,mBAAmB,CAAA;AACxC,OAAO,EAAE,UAAU,EAAE,WAAW,EAAE,MAAM,kBAAkB,CAAA;AAG1D,OAAO,EAAE,mBAAmB,EAAE,MAAM,uBAAuB,CAAA;AAC3D,OAAO,EAAE,aAAa,IAAI,UAAU,EAAE,MAAM,cAAc,CAAA;AAC1D,OAAO,EAAE,kBAAkB,EAAE,MAAM,cAAc,CAAA;AAGjD
|
|
1
|
+
{"version":3,"file":"land.js","sourceRoot":"","sources":["../../src/login/land.ts"],"names":[],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"screen.d.ts","sourceRoot":"","sources":["../../src/login/screen.tsx"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAiB,EAAE,EAAa,MAAM,OAAO,CAAA;AAGzD,OAAO,KAAK,EAA6B,gBAAgB,EAAgB,MAAM,YAAY,CAAA;
|
|
1
|
+
{"version":3,"file":"screen.d.ts","sourceRoot":"","sources":["../../src/login/screen.tsx"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAiB,EAAE,EAAa,MAAM,OAAO,CAAA;AAGzD,OAAO,KAAK,EAA6B,gBAAgB,EAAgB,MAAM,YAAY,CAAA;AAuC3F;;;;;;;;;;;;GAYG;AACH,eAAO,MAAM,mBAAmB,EAAE,EAAE,CAAC,gBAAgB,CAuGpD,CAAA"}
|
package/build/login/screen.js
CHANGED
|
@@ -3,29 +3,8 @@ import { useCallback, useState } from 'react';
|
|
|
3
3
|
import { useContext } from '@owlmeans/client';
|
|
4
4
|
import { LOGIN_SERVICE } from './consts.js';
|
|
5
5
|
import { primaryLoginMethod } from './methods.js';
|
|
6
|
-
import { acceptTerms, resolveTerms, termsAccepted, termsSentence } from './terms.js';
|
|
6
|
+
import { acceptTerms, resolveTerms, termsAccepted, termsDeferred, termsLabelResolver, termsSentence, } from './terms.js';
|
|
7
7
|
import { resolveCredit } from './credit.js';
|
|
8
|
-
/** The same English fallbacks `@owlmeans/web-panel`'s `LoginTerms` uses, kept in sync by hand. */
|
|
9
|
-
const DEFAULT_LABEL = {
|
|
10
|
-
terms: 'Terms & Conditions',
|
|
11
|
-
privacy: 'Privacy Policy',
|
|
12
|
-
cookies: 'Cookie Policy',
|
|
13
|
-
billing: 'Billing Terms',
|
|
14
|
-
product: '{{product}} Product Terms',
|
|
15
|
-
};
|
|
16
|
-
const resolveLabelFor = (translate, locale) => (doc) => {
|
|
17
|
-
const fromMap = doc.labelMap != null
|
|
18
|
-
? (locale != null ? doc.labelMap[locale] : undefined) ?? Object.values(doc.labelMap)[0]
|
|
19
|
-
: undefined;
|
|
20
|
-
let label = doc.label ?? fromMap
|
|
21
|
-
?? (doc.i18nKey != null ? translate(doc.i18nKey, DEFAULT_LABEL[doc.key] ?? doc.key) : doc.key);
|
|
22
|
-
if (doc.params != null) {
|
|
23
|
-
for (const [key, value] of Object.entries(doc.params)) {
|
|
24
|
-
label = label.split(`{{${key}}}`).join(value);
|
|
25
|
-
}
|
|
26
|
-
}
|
|
27
|
-
return label;
|
|
28
|
-
};
|
|
29
8
|
const renderParts = (parts) => parts.map((part, index) => part.href != null
|
|
30
9
|
? _jsx("a", { href: part.href, target: "_blank", rel: "noreferrer noopener", children: part.text }, index)
|
|
31
10
|
: _jsx("span", { children: part.text }, index));
|
|
@@ -73,7 +52,8 @@ export const FallbackLoginScreen = props => {
|
|
|
73
52
|
const env = login.env();
|
|
74
53
|
const resolved = resolveTerms(props.terms ?? cfg?.terms);
|
|
75
54
|
const credit = resolveCredit(cfg?.credit, brand, context.cfg.service);
|
|
76
|
-
const resolveLabel =
|
|
55
|
+
const resolveLabel = termsLabelResolver(t, props.locale);
|
|
56
|
+
const deferred = termsDeferred(context);
|
|
77
57
|
const [accepted, setAccepted] = useState(() => termsAccepted(resolved));
|
|
78
58
|
const [attempted, setAttempted] = useState(false);
|
|
79
59
|
const all = login.methods({ context, env });
|
|
@@ -81,7 +61,7 @@ export const FallbackLoginScreen = props => {
|
|
|
81
61
|
? props.methods(all)
|
|
82
62
|
: props.methods ?? all;
|
|
83
63
|
const primary = primaryLoginMethod(methods);
|
|
84
|
-
const blocked = resolved != null && resolved.required && !accepted;
|
|
64
|
+
const blocked = resolved != null && resolved.required && !deferred && !accepted;
|
|
85
65
|
const select = useCallback((method) => {
|
|
86
66
|
if (blocked) {
|
|
87
67
|
setAttempted(true);
|
|
@@ -96,6 +76,6 @@ export const FallbackLoginScreen = props => {
|
|
|
96
76
|
}, [resolved]);
|
|
97
77
|
return _jsx("div", { "data-login-screen": true, style: page, children: _jsxs("div", { style: box, children: [_jsx("h1", { style: { fontSize: '1.25rem', marginBottom: '.25rem' }, children: props.title ?? t('login.title', 'Sign in') }), _jsx("p", { style: { opacity: .75, marginTop: 0 }, children: props.subtitle ?? t('login.subtitle', 'Choose how you would like to continue.') }), methods.length < 1
|
|
98
78
|
? _jsx("p", { role: "status", children: t('login.empty', 'No sign-in method is configured for this application.') })
|
|
99
|
-
: methods.map(method => _jsx("button", { type: "button", "data-login-method": method.id, "aria-disabled": blocked, "data-blocked": blocked ? 'true' : undefined, style: { ...button(method.emphasis), opacity: blocked ? .6 : 1 }, autoFocus: method.id === primary?.id, onClick: () => select(method), children: method.label ?? t(`login.method.${method.i18nKey ?? method.id}`, method.id) }, method.id)), resolved != null && _jsx("p", { style: { marginTop: '1rem', fontSize: '.875rem' }, children: _jsxs("label", { children: [_jsx("input", { type: "checkbox", checked: accepted, "data-login-terms": true, onChange: event => onAccept(event.target.checked) }), ' ', renderParts(termsSentence(t('login.terms.accept', 'I have read and agree to the {{documents}}.'), resolved, props.locale, resolveLabel))] }) }), resolved?.revisedAt != null && _jsx("p", { "data-login-revised": true, style: { fontSize: '.75rem', opacity: .7 }, children: t('login.terms.revised', 'Last updated: {{date}}').split('{{date}}').join(resolved.revisedAt) }), resolved != null && _jsx("p", { "data-login-privacy": true, style: { fontSize: '.875rem' }, children: renderParts(termsSentence(t('login.terms.notice', 'How we handle your personal data: {{notices}}.'), resolved, props.locale, resolveLabel)) }), attempted && blocked && resolved != null && _jsx("p", { role: "alert", style: { color: '#b00', fontSize: '.875rem' }, children: renderParts(termsSentence(t('login.terms.required', 'Please confirm the {{documents}} to continue.'), resolved, props.locale, resolveLabel)) }), props.footer ?? _jsxs("p", { style: { marginTop: '2rem', fontSize: '.75rem', opacity: .7 }, children: [credit.poweredBy && _jsx("span", { children: t('login.credit.powered', 'Powered by OwlMeans') }), credit.poweredBy && credit.line != null && ' · ', credit.line] })] }) });
|
|
79
|
+
: methods.map(method => _jsx("button", { type: "button", "data-login-method": method.id, "aria-disabled": blocked, "data-blocked": blocked ? 'true' : undefined, style: { ...button(method.emphasis), opacity: blocked ? .6 : 1 }, autoFocus: method.id === primary?.id, onClick: () => select(method), children: method.label ?? t(`login.method.${method.i18nKey ?? method.id}`, method.id) }, method.id)), resolved != null && !deferred && _jsx("p", { style: { marginTop: '1rem', fontSize: '.875rem' }, children: _jsxs("label", { children: [_jsx("input", { type: "checkbox", checked: accepted, "data-login-terms": true, onChange: event => onAccept(event.target.checked) }), ' ', renderParts(termsSentence(t('login.terms.accept', 'I have read and agree to the {{documents}}.'), resolved, props.locale, resolveLabel))] }) }), resolved?.revisedAt != null && !deferred && _jsx("p", { "data-login-revised": true, style: { fontSize: '.75rem', opacity: .7 }, children: t('login.terms.revised', 'Last updated: {{date}}').split('{{date}}').join(resolved.revisedAt) }), resolved != null && _jsx("p", { "data-login-privacy": true, style: { fontSize: '.875rem' }, children: renderParts(termsSentence(t('login.terms.notice', 'How we handle your personal data: {{notices}}.'), resolved, props.locale, resolveLabel)) }), attempted && blocked && resolved != null && _jsx("p", { role: "alert", style: { color: '#b00', fontSize: '.875rem' }, children: renderParts(termsSentence(t('login.terms.required', 'Please confirm the {{documents}} to continue.'), resolved, props.locale, resolveLabel)) }), props.footer ?? _jsxs("p", { style: { marginTop: '2rem', fontSize: '.75rem', opacity: .7 }, children: [credit.poweredBy && _jsx("span", { children: t('login.credit.powered', 'Powered by OwlMeans') }), credit.poweredBy && credit.line != null && ' · ', credit.line] })] }) });
|
|
100
80
|
};
|
|
101
81
|
//# sourceMappingURL=screen.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"screen.js","sourceRoot":"","sources":["../../src/login/screen.tsx"],"names":[],"mappings":";AAAA,OAAO,EAAE,WAAW,EAAE,QAAQ,EAAE,MAAM,OAAO,CAAA;AAE7C,OAAO,EAAE,UAAU,EAAE,MAAM,kBAAkB,CAAA;AAG7C,OAAO,EAAE,aAAa,EAAE,MAAM,aAAa,CAAA;AAC3C,OAAO,EAAE,kBAAkB,EAAE,MAAM,cAAc,CAAA;AACjD,OAAO,
|
|
1
|
+
{"version":3,"file":"screen.js","sourceRoot":"","sources":["../../src/login/screen.tsx"],"names":[],"mappings":";AAAA,OAAO,EAAE,WAAW,EAAE,QAAQ,EAAE,MAAM,OAAO,CAAA;AAE7C,OAAO,EAAE,UAAU,EAAE,MAAM,kBAAkB,CAAA;AAG7C,OAAO,EAAE,aAAa,EAAE,MAAM,aAAa,CAAA;AAC3C,OAAO,EAAE,kBAAkB,EAAE,MAAM,cAAc,CAAA;AACjD,OAAO,EACL,WAAW,EAAE,YAAY,EAAE,aAAa,EAAE,aAAa,EAAE,kBAAkB,EAAE,aAAa,GAC3F,MAAM,YAAY,CAAA;AAEnB,OAAO,EAAE,aAAa,EAAE,MAAM,aAAa,CAAA;AAE3C,MAAM,WAAW,GAAG,CAAC,KAA0B,EAAa,EAAE,CAC5D,KAAK,CAAC,GAAG,CAAC,CAAC,IAAI,EAAE,KAAK,EAAE,EAAE,CAAC,IAAI,CAAC,IAAI,IAAI,IAAI;IAC1C,CAAC,CAAC,YAAe,IAAI,EAAE,IAAI,CAAC,IAAI,EAAE,MAAM,EAAC,QAAQ,EAAC,GAAG,EAAC,qBAAqB,YAAE,IAAI,CAAC,IAAI,IAA5E,KAAK,CAA4E;IAC3F,CAAC,CAAC,yBAAmB,IAAI,CAAC,IAAI,IAAjB,KAAK,CAAoB,CAAC,CAAA;AAE3C;;;;;;GAMG;AACH,MAAM,IAAI,GAAkB;IAC1B,OAAO,EAAE,MAAM,EAAE,UAAU,EAAE,QAAQ,EAAE,cAAc,EAAE,QAAQ;IAC/D,SAAS,EAAE,QAAQ,EAAE,OAAO,EAAE,MAAM;IACpC,UAAU,EAAE,uBAAuB,EAAE,UAAU,EAAE,GAAG;CACrD,CAAA;AAED,gFAAgF;AAChF,MAAM,GAAG,GAAkB;IACzB,KAAK,EAAE,MAAM,EAAE,QAAQ,EAAE,OAAO,EAAE,OAAO,EAAE,QAAQ,EAAE,SAAS,EAAE,QAAQ;CACzE,CAAA;AAED,MAAM,MAAM,GAAG,CAAC,QAAiB,EAAiB,EAAE,CAAC,CAAC;IACpD,OAAO,EAAE,OAAO,EAAE,KAAK,EAAE,MAAM,EAAE,SAAS,EAAE,OAAO,EAAE,OAAO,EAAE,cAAc;IAC5E,QAAQ,EAAE,MAAM,EAAE,MAAM,EAAE,SAAS,EAAE,YAAY,EAAE,SAAS;IAC5D,MAAM,EAAE,wBAAwB;IAChC,GAAG,CAAC,QAAQ,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,UAAU,EAAE,GAAG,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;CACvD,CAAC,CAAA;AAEF;;;;;;;;;;;;GAYG;AACH,MAAM,CAAC,MAAM,mBAAmB,GAAyB,KAAK,CAAC,EAAE;IAC/D,MAAM,OAAO,GAAG,UAAU,EAA6B,CAAA;IACvD,MAAM,CAAC,GAAG,KAAK,CAAC,SAAS,IAAI,CAAC,CAAC,IAAY,EAAE,YAAoB,EAAE,EAAE,CAAC,YAAY,CAAC,CAAA;IACnF,MAAM,GAAG,GAAG,KAAK,CAAC,MAAM,IAAK,OAAO,CAAC,GAAoB,CAAC,QAAQ,EAAE,IAAI,EAAE,KAAK,CAAA;IAC/E,MAAM,KAAK,GAAI,OAAO,CAAC,GAAoB,CAAC,KAAK,CAAA;IAEjD,MAAM,KAAK,GAAG,OAAO,CAAC,OAAO,CAAe,aAAa,CAAC,CAAA;IAC1D,MAAM,GAAG,GAAG,KAAK,CAAC,GAAG,EAAE,CAAA;IACvB,MAAM,QAAQ,GAAG,YAAY,CAAC,KAAK,CAAC,KAAK,IAAI,GAAG,EAAE,KAAK,CAAC,CAAA;IACxD,MAAM,MAAM,GAAG,aAAa,CAAC,GAAG,EAAE,MAAM,EAAE,KAAK,EAAE,OAAO,CAAC,GAAG,CAAC,OAAO,CAAC,CAAA;IACrE,MAAM,YAAY,GAAG,kBAAkB,CAAC,CAAC,EAAE,KAAK,CAAC,MAAM,CAAC,CAAA;IACxD,MAAM,QAAQ,GAAG,aAAa,CAAC,OAAO,CAAC,CAAA;IAEvC,MAAM,CAAC,QAAQ,EAAE,WAAW,CAAC,GAAG,QAAQ,CAAC,GAAG,EAAE,CAAC,aAAa,CAAC,QAAQ,CAAC,CAAC,CAAA;IACvE,MAAM,CAAC,SAAS,EAAE,YAAY,CAAC,GAAG,QAAQ,CAAC,KAAK,CAAC,CAAA;IAEjD,MAAM,GAAG,GAAG,KAAK,CAAC,OAAO,CAAC,EAAE,OAAO,EAAE,GAAG,EAAE,CAAC,CAAA;IAC3C,MAAM,OAAO,GAAG,OAAO,KAAK,CAAC,OAAO,KAAK,UAAU;QACjD,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,GAAG,CAAC;QACpB,CAAC,CAAC,KAAK,CAAC,OAAO,IAAI,GAAG,CAAA;IACxB,MAAM,OAAO,GAAG,kBAAkB,CAAC,OAAO,CAAC,CAAA;IAE3C,MAAM,OAAO,GAAG,QAAQ,IAAI,IAAI,IAAI,QAAQ,CAAC,QAAQ,IAAI,CAAC,QAAQ,IAAI,CAAC,QAAQ,CAAA;IAE/E,MAAM,MAAM,GAAG,WAAW,CAAC,CAAC,MAAmB,EAAE,EAAE;QACjD,IAAI,OAAO,EAAE,CAAC;YACZ,YAAY,CAAC,IAAI,CAAC,CAAA;YAClB,OAAM;QACR,CAAC;QACD,KAAK,MAAM,CAAC,KAAK,CAAC,EAAE,OAAO,EAAE,GAAG,EAAE,CAAC,CAAA;IACrC,CAAC,EAAE,CAAC,OAAO,EAAE,OAAO,EAAE,GAAG,CAAC,CAAC,CAAA;IAE3B,MAAM,QAAQ,GAAG,WAAW,CAAC,CAAC,KAAc,EAAE,EAAE;QAC9C,WAAW,CAAC,KAAK,CAAC,CAAA;QAClB,YAAY,CAAC,KAAK,CAAC,CAAA;QACnB,WAAW,CAAC,QAAQ,EAAE,KAAK,CAAC,CAAA;IAC9B,CAAC,EAAE,CAAC,QAAQ,CAAC,CAAC,CAAA;IAEd,OAAO,yCAAuB,KAAK,EAAE,IAAI,YAAE,eAAK,KAAK,EAAE,GAAG,aACxD,aAAI,KAAK,EAAE,EAAE,QAAQ,EAAE,SAAS,EAAE,YAAY,EAAE,QAAQ,EAAE,YACvD,KAAK,CAAC,KAAK,IAAI,CAAC,CAAC,aAAa,EAAE,SAAS,CAAC,GACxC,EACL,YAAG,KAAK,EAAE,EAAE,OAAO,EAAE,GAAG,EAAE,SAAS,EAAE,CAAC,EAAE,YACrC,KAAK,CAAC,QAAQ,IAAI,CAAC,CAAC,gBAAgB,EAAE,wCAAwC,CAAC,GAC9E,EAEH,OAAO,CAAC,MAAM,GAAG,CAAC;oBACjB,CAAC,CAAC,YAAG,IAAI,EAAC,QAAQ,YAAE,CAAC,CAAC,aAAa,EAAE,uDAAuD,CAAC,GAAK;oBAClG,CAAC,CAAC,OAAO,CAAC,GAAG,CAAC,MAAM,CAAC,EAAE,CAAC,iBACN,IAAI,EAAC,QAAQ,uBAAoB,MAAM,CAAC,EAAE,mBAG3C,OAAO,kBAAgB,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,SAAS,EAClE,KAAK,EAAE,EAAE,GAAG,MAAM,CAAC,MAAM,CAAC,QAAQ,CAAC,EAAE,OAAO,EAAE,OAAO,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,EAAE,EAChE,SAAS,EAAE,MAAM,CAAC,EAAE,KAAK,OAAO,EAAE,EAAE,EACpC,OAAO,EAAE,GAAG,EAAE,CAAC,MAAM,CAAC,MAAM,CAAC,YAE5B,MAAM,CAAC,KAAK,IAAI,CAAC,CAAC,gBAAgB,MAAM,CAAC,OAAO,IAAI,MAAM,CAAC,EAAE,EAAE,EAAE,MAAM,CAAC,EAAE,CAAC,IARvE,MAAM,CAAC,EAAE,CASP,CAAC,EAMX,QAAQ,IAAI,IAAI,IAAI,CAAC,QAAQ,IAAI,YAAG,KAAK,EAAE,EAAE,SAAS,EAAE,MAAM,EAAE,QAAQ,EAAE,SAAS,EAAE,YAEpF,4BACE,gBACE,IAAI,EAAC,UAAU,EAAC,OAAO,EAAE,QAAQ,4BACjC,QAAQ,EAAE,KAAK,CAAC,EAAE,CAAC,QAAQ,CAAC,KAAK,CAAC,MAAM,CAAC,OAAO,CAAC,GACjD,EAAC,GAAG,EACL,WAAW,CAAC,aAAa,CACxB,CAAC,CAAC,oBAAoB,EAAE,6CAA6C,CAAC,EACtE,QAAQ,EAAE,KAAK,CAAC,MAAM,EAAE,YAAY,CACrC,CAAC,IACI,GACN,EAEH,QAAQ,EAAE,SAAS,IAAI,IAAI,IAAI,CAAC,QAAQ,IAAI,wCAAsB,KAAK,EAAE,EAAE,QAAQ,EAAE,QAAQ,EAAE,OAAO,EAAE,EAAE,EAAE,YAC1G,CAAC,CAAC,qBAAqB,EAAE,wBAAwB,CAAC,CAAC,KAAK,CAAC,UAAU,CAAC,CAAC,IAAI,CAAC,QAAQ,CAAC,SAAS,CAAC,GAC5F,EAGH,QAAQ,IAAI,IAAI,IAAI,wCAAsB,KAAK,EAAE,EAAE,QAAQ,EAAE,SAAS,EAAE,YACtE,WAAW,CAAC,aAAa,CACxB,CAAC,CAAC,oBAAoB,EAAE,gDAAgD,CAAC,EACzE,QAAQ,EAAE,KAAK,CAAC,MAAM,EAAE,YAAY,CACrC,CAAC,GACA,EAEH,SAAS,IAAI,OAAO,IAAI,QAAQ,IAAI,IAAI,IAAI,YAAG,IAAI,EAAC,OAAO,EAAC,KAAK,EAAE,EAAE,KAAK,EAAE,MAAM,EAAE,QAAQ,EAAE,SAAS,EAAE,YACvG,WAAW,CAAC,aAAa,CACxB,CAAC,CAAC,sBAAsB,EAAE,+CAA+C,CAAC,EAC1E,QAAQ,EAAE,KAAK,CAAC,MAAM,EAAE,YAAY,CACrC,CAAC,GACA,EAEH,KAAK,CAAC,MAAM,IAAI,aAAG,KAAK,EAAE,EAAE,SAAS,EAAE,MAAM,EAAE,QAAQ,EAAE,QAAQ,EAAE,OAAO,EAAE,EAAE,EAAE,aAC9E,MAAM,CAAC,SAAS,IAAI,yBAAO,CAAC,CAAC,sBAAsB,EAAE,qBAAqB,CAAC,GAAQ,EACnF,MAAM,CAAC,SAAS,IAAI,MAAM,CAAC,IAAI,IAAI,IAAI,IAAI,KAAK,EAChD,MAAM,CAAC,IAAI,IACV,IACA,GAAM,CAAA;AACd,CAAC,CAAA"}
|
package/build/login/terms.d.ts
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import type { LoginTermsConfig } from '@owlmeans/config';
|
|
2
|
+
import type { LoginContext } from './types.js';
|
|
2
3
|
import './terms-config.js';
|
|
3
4
|
/** One document (or notice) a sign-in screen links to. */
|
|
4
5
|
export interface ResolvedTermsDocument {
|
|
@@ -39,6 +40,49 @@ export declare const resolveTerms: (cfg?: LoginTermsConfig | false) => ResolvedT
|
|
|
39
40
|
*/
|
|
40
41
|
export declare const termsAccepted: (resolved: ResolvedTerms | null) => boolean;
|
|
41
42
|
export declare const acceptTerms: (resolved: ResolvedTerms | null, accepted: boolean) => void;
|
|
43
|
+
/**
|
|
44
|
+
* A document's own label: a caller's literal `label`, else its `labelMap` for the current locale,
|
|
45
|
+
* else its `i18nKey` translated — each with `params` (e.g. `{ product: 'Acme' }`) interpolated
|
|
46
|
+
* afterwards, since the `translate` contract every renderer shares is a plain
|
|
47
|
+
* `(key, defaultValue) => string` with no interpolation option of its own.
|
|
48
|
+
*
|
|
49
|
+
* The one label resolver every renderer of a terms sentence uses — `FallbackLoginScreen` here, and
|
|
50
|
+
* `@owlmeans/web-panel`'s `LoginTerms` — so the English fallbacks and the resolution order live in
|
|
51
|
+
* exactly one place instead of two hand-kept copies.
|
|
52
|
+
*/
|
|
53
|
+
export declare const termsLabelResolver: (translate: (key: string, defaultValue: string) => string, locale: string | undefined) => (doc: ResolvedTermsDocument) => string;
|
|
54
|
+
/** One document as `@owlmeans/marketing-consent`'s `TermsDocumentRef` shape — structurally, with
|
|
55
|
+
* no dependency on that package (client-auth is a layer below it). */
|
|
56
|
+
export interface TermsAcceptanceRef {
|
|
57
|
+
key: string;
|
|
58
|
+
href: string;
|
|
59
|
+
revisedAt?: string;
|
|
60
|
+
}
|
|
61
|
+
/**
|
|
62
|
+
* What a sign-in-time terms acceptance sends the server — structurally
|
|
63
|
+
* `@owlmeans/marketing-consent`'s `TermsAcceptance`, so `client.recordTerms(termsAcceptanceOf(...))`
|
|
64
|
+
* type-checks with no dependency in this direction. Shared by `termsRecorder` (the sign-in screen's
|
|
65
|
+
* own local acceptance, copied at landing) and a Terms-mode consent screen recording the box it
|
|
66
|
+
* just showed.
|
|
67
|
+
*/
|
|
68
|
+
export declare const termsAcceptanceOf: (resolved: Pick<ResolvedTerms, 'documents' | 'notices' | 'version'>, locale?: string) => {
|
|
69
|
+
documents: TermsAcceptanceRef[];
|
|
70
|
+
notices: TermsAcceptanceRef[];
|
|
71
|
+
version: string;
|
|
72
|
+
locale?: string;
|
|
73
|
+
};
|
|
74
|
+
/**
|
|
75
|
+
* Whether the Terms confirmation has been moved off the sign-in screen onto a registered step.
|
|
76
|
+
*
|
|
77
|
+
* True only when a step both DECLARES `confirmsTerms` and is BOUND (`ctx.hasEntrypoint`) — an app
|
|
78
|
+
* that registers the step (e.g. `appendMarketingConsent({ terms: 'step' })`) but never binds its
|
|
79
|
+
* screen (an older target, a partial import) keeps the sign-in checkbox, fail-closed: a person must
|
|
80
|
+
* never find the confirmation missing from both places at once.
|
|
81
|
+
*
|
|
82
|
+
* Reads the service directly (`ctx.hasService`), never `ensureLoginService` — that registers an
|
|
83
|
+
* empty host as a side effect, which a render-time check must not do.
|
|
84
|
+
*/
|
|
85
|
+
export declare const termsDeferred: (ctx: LoginContext) => boolean;
|
|
42
86
|
/** One fragment of an interpolated terms sentence — plain text, or a link to a document. */
|
|
43
87
|
export interface TermsSentencePart {
|
|
44
88
|
text: string;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"terms.d.ts","sourceRoot":"","sources":["../../src/login/terms.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,kBAAkB,CAAA;AAExD,OAAO,mBAAmB,CAAA;AAE1B,0DAA0D;AAC1D,MAAM,WAAW,qBAAqB;IACpC,GAAG,EAAE,MAAM,CAAA;IACX,IAAI,EAAE,MAAM,CAAA;IACZ,kGAAkG;IAClG,KAAK,CAAC,EAAE,MAAM,CAAA;IACd,qGAAqG;IACrG,QAAQ,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAA;IACjC,yEAAyE;IACzE,OAAO,CAAC,EAAE,MAAM,CAAA;IAChB,SAAS,CAAC,EAAE,MAAM,CAAA;IAClB,2FAA2F;IAC3F,MAAM,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAA;CAChC;AAED,MAAM,WAAW,aAAa;IAC5B,QAAQ,EAAE,OAAO,CAAA;IACjB,KAAK,EAAE,MAAM,CAAA;IACb,OAAO,EAAE,MAAM,CAAA;IACf,OAAO,CAAC,EAAE,MAAM,CAAA;IAChB,OAAO,EAAE,MAAM,CAAA;IACf,8FAA8F;IAC9F,SAAS,EAAE,qBAAqB,EAAE,CAAA;IAClC,+FAA+F;IAC/F,OAAO,EAAE,qBAAqB,EAAE,CAAA;IAChC,4FAA4F;IAC5F,SAAS,CAAC,EAAE,MAAM,CAAA;IAClB,YAAY,EAAE,OAAO,CAAA;CACtB;AA0BD,eAAO,MAAM,YAAY,SAAU,gBAAgB,GAAG,KAAK,KAAG,aAAa,GAAG,IAuF7E,CAAA;AAED;;;;;;;GAOG;AACH,eAAO,MAAM,aAAa,aAAc,aAAa,GAAG,IAAI,KAAG,OAW9D,CAAA;AAED,eAAO,MAAM,WAAW,aAAc,aAAa,GAAG,IAAI,YAAY,OAAO,KAAG,IAW/E,CAAA;AAED,4FAA4F;AAC5F,MAAM,WAAW,iBAAiB;IAChC,IAAI,EAAE,MAAM,CAAA;IACZ,IAAI,CAAC,EAAE,MAAM,CAAA;IACb,WAAW,CAAC,EAAE,MAAM,CAAA;CACrB;AAyCD;;;;;;;;GAQG;AACH,eAAO,MAAM,aAAa,aACd,MAAM,YACN,IAAI,CAAC,aAAa,EAAE,WAAW,GAAG,SAAS,CAAC,UAC9C,MAAM,GAAG,SAAS,gBACZ,CAAC,GAAG,EAAE,qBAAqB,KAAK,MAAM,KACnD,iBAAiB,EAiCnB,CAAA"}
|
|
1
|
+
{"version":3,"file":"terms.d.ts","sourceRoot":"","sources":["../../src/login/terms.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,kBAAkB,CAAA;AAExD,OAAO,KAAK,EAAE,YAAY,EAAgB,MAAM,YAAY,CAAA;AAC5D,OAAO,mBAAmB,CAAA;AAE1B,0DAA0D;AAC1D,MAAM,WAAW,qBAAqB;IACpC,GAAG,EAAE,MAAM,CAAA;IACX,IAAI,EAAE,MAAM,CAAA;IACZ,kGAAkG;IAClG,KAAK,CAAC,EAAE,MAAM,CAAA;IACd,qGAAqG;IACrG,QAAQ,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAA;IACjC,yEAAyE;IACzE,OAAO,CAAC,EAAE,MAAM,CAAA;IAChB,SAAS,CAAC,EAAE,MAAM,CAAA;IAClB,2FAA2F;IAC3F,MAAM,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAA;CAChC;AAED,MAAM,WAAW,aAAa;IAC5B,QAAQ,EAAE,OAAO,CAAA;IACjB,KAAK,EAAE,MAAM,CAAA;IACb,OAAO,EAAE,MAAM,CAAA;IACf,OAAO,CAAC,EAAE,MAAM,CAAA;IAChB,OAAO,EAAE,MAAM,CAAA;IACf,8FAA8F;IAC9F,SAAS,EAAE,qBAAqB,EAAE,CAAA;IAClC,+FAA+F;IAC/F,OAAO,EAAE,qBAAqB,EAAE,CAAA;IAChC,4FAA4F;IAC5F,SAAS,CAAC,EAAE,MAAM,CAAA;IAClB,YAAY,EAAE,OAAO,CAAA;CACtB;AA0BD,eAAO,MAAM,YAAY,SAAU,gBAAgB,GAAG,KAAK,KAAG,aAAa,GAAG,IAuF7E,CAAA;AAED;;;;;;;GAOG;AACH,eAAO,MAAM,aAAa,aAAc,aAAa,GAAG,IAAI,KAAG,OAW9D,CAAA;AAED,eAAO,MAAM,WAAW,aAAc,aAAa,GAAG,IAAI,YAAY,OAAO,KAAG,IAW/E,CAAA;AAWD;;;;;;;;;GASG;AACH,eAAO,MAAM,kBAAkB,cAClB,CAAC,GAAG,EAAE,MAAM,EAAE,YAAY,EAAE,MAAM,KAAK,MAAM,UAAU,MAAM,GAAG,SAAS,WAC3E,qBAAqB,KAAG,MAclC,CAAA;AAED;sEACsE;AACtE,MAAM,WAAW,kBAAkB;IACjC,GAAG,EAAE,MAAM,CAAA;IACX,IAAI,EAAE,MAAM,CAAA;IACZ,SAAS,CAAC,EAAE,MAAM,CAAA;CACnB;AAED;;;;;;GAMG;AACH,eAAO,MAAM,iBAAiB,aAClB,IAAI,CAAC,aAAa,EAAE,WAAW,GAAG,SAAS,GAAG,SAAS,CAAC,WAAW,MAAM,KAClF;IAAE,SAAS,EAAE,kBAAkB,EAAE,CAAC;IAAC,OAAO,EAAE,kBAAkB,EAAE,CAAC;IAAC,OAAO,EAAE,MAAM,CAAC;IAAC,MAAM,CAAC,EAAE,MAAM,CAAA;CAKnG,CAAA;AAEF;;;;;;;;;;GAUG;AACH,eAAO,MAAM,aAAa,QAAS,YAAY,KAAG,OAGkC,CAAA;AAEpF,4FAA4F;AAC5F,MAAM,WAAW,iBAAiB;IAChC,IAAI,EAAE,MAAM,CAAA;IACZ,IAAI,CAAC,EAAE,MAAM,CAAA;IACb,WAAW,CAAC,EAAE,MAAM,CAAA;CACrB;AAyCD;;;;;;;;GAQG;AACH,eAAO,MAAM,aAAa,aACd,MAAM,YACN,IAAI,CAAC,aAAa,EAAE,WAAW,GAAG,SAAS,CAAC,UAC9C,MAAM,GAAG,SAAS,gBACZ,CAAC,GAAG,EAAE,qBAAqB,KAAK,MAAM,KACnD,iBAAiB,EAiCnB,CAAA"}
|
package/build/login/terms.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { OWLMEANS_COOKIES_URL, OWLMEANS_PRIVACY_URL, OWLMEANS_TERMS_URL } from '@owlmeans/config';
|
|
2
|
-
import { LOGIN_TERMS_STORAGE } from './consts.js';
|
|
2
|
+
import { LOGIN_SERVICE, LOGIN_TERMS_STORAGE } from './consts.js';
|
|
3
3
|
import './terms-config.js';
|
|
4
4
|
/**
|
|
5
5
|
* A stable identity for one set of documents.
|
|
@@ -123,6 +123,64 @@ export const acceptTerms = (resolved, accepted) => {
|
|
|
123
123
|
}
|
|
124
124
|
catch { /* nothing to remember if storage was never available */ }
|
|
125
125
|
};
|
|
126
|
+
/** The same English fallback a document's `i18nKey` translates to when nothing else names it. */
|
|
127
|
+
const DEFAULT_LABEL = {
|
|
128
|
+
terms: 'Terms & Conditions',
|
|
129
|
+
privacy: 'Privacy Policy',
|
|
130
|
+
cookies: 'Cookie Policy',
|
|
131
|
+
billing: 'Billing Terms',
|
|
132
|
+
product: '{{product}} Product Terms',
|
|
133
|
+
};
|
|
134
|
+
/**
|
|
135
|
+
* A document's own label: a caller's literal `label`, else its `labelMap` for the current locale,
|
|
136
|
+
* else its `i18nKey` translated — each with `params` (e.g. `{ product: 'Acme' }`) interpolated
|
|
137
|
+
* afterwards, since the `translate` contract every renderer shares is a plain
|
|
138
|
+
* `(key, defaultValue) => string` with no interpolation option of its own.
|
|
139
|
+
*
|
|
140
|
+
* The one label resolver every renderer of a terms sentence uses — `FallbackLoginScreen` here, and
|
|
141
|
+
* `@owlmeans/web-panel`'s `LoginTerms` — so the English fallbacks and the resolution order live in
|
|
142
|
+
* exactly one place instead of two hand-kept copies.
|
|
143
|
+
*/
|
|
144
|
+
export const termsLabelResolver = (translate, locale) => (doc) => {
|
|
145
|
+
const fromMap = doc.labelMap != null
|
|
146
|
+
? (locale != null ? doc.labelMap[locale] : undefined) ?? Object.values(doc.labelMap)[0]
|
|
147
|
+
: undefined;
|
|
148
|
+
let label = doc.label ?? fromMap
|
|
149
|
+
?? (doc.i18nKey != null ? translate(doc.i18nKey, DEFAULT_LABEL[doc.key] ?? doc.key) : doc.key);
|
|
150
|
+
if (doc.params != null) {
|
|
151
|
+
for (const [key, value] of Object.entries(doc.params)) {
|
|
152
|
+
label = label.split(`{{${key}}}`).join(value);
|
|
153
|
+
}
|
|
154
|
+
}
|
|
155
|
+
return label;
|
|
156
|
+
};
|
|
157
|
+
/**
|
|
158
|
+
* What a sign-in-time terms acceptance sends the server — structurally
|
|
159
|
+
* `@owlmeans/marketing-consent`'s `TermsAcceptance`, so `client.recordTerms(termsAcceptanceOf(...))`
|
|
160
|
+
* type-checks with no dependency in this direction. Shared by `termsRecorder` (the sign-in screen's
|
|
161
|
+
* own local acceptance, copied at landing) and a Terms-mode consent screen recording the box it
|
|
162
|
+
* just showed.
|
|
163
|
+
*/
|
|
164
|
+
export const termsAcceptanceOf = (resolved, locale) => ({
|
|
165
|
+
documents: resolved.documents.map(doc => ({ key: doc.key, href: doc.href, revisedAt: doc.revisedAt })),
|
|
166
|
+
notices: resolved.notices.map(doc => ({ key: doc.key, href: doc.href, revisedAt: doc.revisedAt })),
|
|
167
|
+
version: resolved.version,
|
|
168
|
+
...(locale != null ? { locale } : {}),
|
|
169
|
+
});
|
|
170
|
+
/**
|
|
171
|
+
* Whether the Terms confirmation has been moved off the sign-in screen onto a registered step.
|
|
172
|
+
*
|
|
173
|
+
* True only when a step both DECLARES `confirmsTerms` and is BOUND (`ctx.hasEntrypoint`) — an app
|
|
174
|
+
* that registers the step (e.g. `appendMarketingConsent({ terms: 'step' })`) but never binds its
|
|
175
|
+
* screen (an older target, a partial import) keeps the sign-in checkbox, fail-closed: a person must
|
|
176
|
+
* never find the confirmation missing from both places at once.
|
|
177
|
+
*
|
|
178
|
+
* Reads the service directly (`ctx.hasService`), never `ensureLoginService` — that registers an
|
|
179
|
+
* empty host as a side effect, which a render-time check must not do.
|
|
180
|
+
*/
|
|
181
|
+
export const termsDeferred = (ctx) => ctx.hasService(LOGIN_SERVICE)
|
|
182
|
+
&& ctx.service(LOGIN_SERVICE).steps()
|
|
183
|
+
.some(step => step.confirmsTerms === true && ctx.hasEntrypoint(step.entrypoint));
|
|
126
184
|
/**
|
|
127
185
|
* Format a list of documents into sentence parts, via `Intl.ListFormat` when it exists ("A, B and
|
|
128
186
|
* C" in the caller's own locale and conjunction word), falling back to a plain ", "/" and " join
|
package/build/login/terms.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"terms.js","sourceRoot":"","sources":["../../src/login/terms.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,oBAAoB,EAAE,oBAAoB,EAAE,kBAAkB,EAAE,MAAM,kBAAkB,CAAA;AAEjG,OAAO,EAAE,mBAAmB,EAAE,MAAM,aAAa,CAAA;
|
|
1
|
+
{"version":3,"file":"terms.js","sourceRoot":"","sources":["../../src/login/terms.ts"],"names":[],"mappings":"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"}
|
package/build/login/types.d.ts
CHANGED
|
@@ -265,14 +265,6 @@ export interface LoginService extends LazyService {
|
|
|
265
265
|
/** Drop this document's authentication. The single de-adoption path. */
|
|
266
266
|
revoke: () => Promise<void>;
|
|
267
267
|
}
|
|
268
|
-
/**
|
|
269
|
-
* A step to run after sign-in completes, before the ordinary landing.
|
|
270
|
-
*
|
|
271
|
-
* Registered by a package that must collect something from a freshly authenticated user before
|
|
272
|
-
* the application resumes wherever it was headed — the marketing-consent screen is the first
|
|
273
|
-
* consumer. `landAfterLogin`/`continueLogin` (./land.js) walk the registered steps in priority
|
|
274
|
-
* order and land on the first one whose `pending` resolves `true`.
|
|
275
|
-
*/
|
|
276
268
|
/**
|
|
277
269
|
* The value shape a landing's `params`/`query` carries.
|
|
278
270
|
*
|
|
@@ -282,6 +274,14 @@ export interface LoginService extends LazyService {
|
|
|
282
274
|
* dispatcher's own forwarded `params`/`query` without a lossy re-cast at every call site.
|
|
283
275
|
*/
|
|
284
276
|
export type LoginLandingParams = Record<string, string | number | boolean | undefined | null>;
|
|
277
|
+
/**
|
|
278
|
+
* A step to run after sign-in completes, before the ordinary landing.
|
|
279
|
+
*
|
|
280
|
+
* Registered by a package that must collect something from a freshly authenticated user before
|
|
281
|
+
* the application resumes wherever it was headed — the marketing-consent screen is the first
|
|
282
|
+
* consumer. `landAfterLogin`/`continueLogin` (./land.js) walk the registered steps in priority
|
|
283
|
+
* order and land on the first one whose `pending` resolves `true`.
|
|
284
|
+
*/
|
|
285
285
|
export interface LoginStep {
|
|
286
286
|
alias: string;
|
|
287
287
|
/** Higher runs first. Defaults to 0. */
|
|
@@ -292,6 +292,22 @@ export interface LoginStep {
|
|
|
292
292
|
query?: (ctx: LoginContext) => LoginLandingParams | undefined;
|
|
293
293
|
/** Whether this step still has something to collect from the signed-in user. */
|
|
294
294
|
pending: (ctx: LoginContext) => Promise<boolean>;
|
|
295
|
+
/**
|
|
296
|
+
* This step is where the Terms confirmation lives instead of on the sign-in screen.
|
|
297
|
+
*
|
|
298
|
+
* `termsDeferred(ctx)` (`./terms.js`) is true only while a step with this flag is both
|
|
299
|
+
* registered AND bound (`ctx.hasEntrypoint(step.entrypoint)`) — an app that registers the step
|
|
300
|
+
* but never binds its screen keeps the sign-in checkbox, fail-closed.
|
|
301
|
+
*/
|
|
302
|
+
confirmsTerms?: boolean;
|
|
303
|
+
/**
|
|
304
|
+
* A `pending` that throws or times out counts as PENDING rather than "not pending".
|
|
305
|
+
*
|
|
306
|
+
* The default (`undefined`/`false`) keeps every existing step fail-open, exactly as before —
|
|
307
|
+
* this flag is for a step whose whole point is to gate the landing on something the person must
|
|
308
|
+
* do (Terms confirmation), where a broken read must show the step rather than let it through.
|
|
309
|
+
*/
|
|
310
|
+
required?: boolean;
|
|
295
311
|
}
|
|
296
312
|
/** Where a finished sign-in (or a pending step) lands. */
|
|
297
313
|
export interface LoginLanding {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/login/types.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,aAAa,EAAE,aAAa,EAAE,SAAS,EAAE,MAAM,OAAO,CAAA;AACpE,OAAO,KAAK,EAAE,WAAW,EAAE,YAAY,EAAE,MAAM,mBAAmB,CAAA;AAClE,OAAO,KAAK,EAAE,mBAAmB,EAAE,iBAAiB,EAAE,gBAAgB,EAAE,MAAM,kBAAkB,CAAA;AAEhG;;;;;;GAMG;AACH,MAAM,MAAM,YAAY,GAAG,YAAY,CAAC,GAAG,CAAC,CAAA;AAE5C;;;;;;GAMG;AACH,MAAM,WAAW,QAAQ;IACvB,yEAAyE;IACzE,SAAS,EAAE,OAAO,CAAA;IAClB,kGAAkG;IAClG,QAAQ,EAAE,OAAO,CAAA;IACjB,yFAAyF;IACzF,SAAS,EAAE,OAAO,CAAA;IAClB,uFAAuF;IACvF,SAAS,EAAE,OAAO,CAAA;CACnB;AAED,oEAAoE;AACpE,oBAAY,YAAY;IACtB,sFAAsF;IACtF,OAAO,YAAY;IACnB,qFAAqF;IACrF,MAAM,WAAW;IACjB,oFAAoF;IACpF,UAAU,eAAe;IACzB,0FAA0F;IAC1F,OAAO,YAAY;IACnB,6EAA6E;IAC7E,QAAQ,aAAa;IACrB,gGAAgG;IAChG,MAAM,WAAW;IACjB;;;;;;OAMG;IACH,OAAO,YAAY;CACpB;AAED,yCAAyC;AACzC,oBAAY,WAAW;IACrB,KAAK,UAAU;IACf,MAAM,WAAW;CAClB;AAED,MAAM,WAAW,YAAY;IAC3B,wFAAwF;IACxF,GAAG,EAAE,MAAM,CAAA;IACX;;;;OAIG;IACH,QAAQ,CAAC,EAAE,MAAM,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC,CAAA;IACrC,iDAAiD;IACjD,MAAM,CAAC,EAAE,MAAM,CAAA;CAChB;AAED,MAAM,WAAW,aAAa;IAC5B,iEAAiE;IACjE,GAAG,EAAE,MAAM,CAAA;IACX,8DAA8D;IAC9D,QAAQ,CAAC,EAAE,MAAM,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC,CAAA;CACtC;AAED;;;;;;;GAOG;AACH,MAAM,WAAW,WAAW;IAC1B,KAAK,EAAE,MAAM,CAAA;IACb,yDAAyD;IACzD,QAAQ,CAAC,EAAE,MAAM,CAAA;IACjB,+DAA+D;IAC/D,IAAI,CAAC,EAAE,MAAM,CAAA;IACb,uDAAuD;IACvD,KAAK,CAAC,EAAE,CAAC,GAAG,EAAE,QAAQ,EAAE,GAAG,CAAC,EAAE,YAAY,KAAK,OAAO,CAAA;IAEtD;;;;;;OAMG;IACH,KAAK,CAAC,EAAE,CAAC,GAAG,EAAE,YAAY,EAAE,GAAG,EAAE,QAAQ,KAAK,IAAI,CAAA;IAElD;;;;;OAKG;IACH,KAAK,EAAE,CAAC,GAAG,EAAE,YAAY,EAAE,OAAO,EAAE,YAAY,EAAE,GAAG,EAAE,QAAQ,KAAK,OAAO,CAAC,YAAY,CAAC,CAAA;IAEzF,qEAAqE;IACrE,SAAS,EAAE,CAAC,GAAG,EAAE,YAAY,EAAE,GAAG,EAAE,MAAM,EAAE,GAAG,EAAE,QAAQ,KAAK,OAAO,CAAC,YAAY,CAAC,CAAA;IAEnF,yEAAyE;IACzE,QAAQ,EAAE,CAAC,GAAG,EAAE,YAAY,EAAE,KAAK,EAAE,MAAM,EAAE,GAAG,EAAE,QAAQ,KAAK,OAAO,CAAC,YAAY,CAAC,CAAA;IAEpF;;;;;;;;;;OAUG;IACH,MAAM,CAAC,EAAE,CAAC,GAAG,EAAE,YAAY,EAAE,KAAK,EAAE,MAAM,EAAE,GAAG,EAAE,QAAQ,KAAK,OAAO,CAAC,YAAY,CAAC,CAAA;IAEnF;;;;;OAKG;IACH,MAAM,CAAC,EAAE,CAAC,GAAG,EAAE,YAAY,EAAE,OAAO,EAAE,aAAa,EAAE,GAAG,EAAE,QAAQ,KAAK,OAAO,CAAC,YAAY,CAAC,CAAA;IAE5F,6EAA6E;IAC7E,cAAc,CAAC,EAAE,CAAC,GAAG,EAAE,YAAY,EAAE,GAAG,EAAE,QAAQ,KAAK,OAAO,CAAC,YAAY,CAAC,CAAA;CAC7E;AAED;;;;;;;;;;GAUG;AACH,MAAM,WAAW,iBAAiB;IAChC,KAAK,EAAE,MAAM,CAAA;IACb,wCAAwC;IACxC,QAAQ,CAAC,EAAE,MAAM,CAAA;IACjB,KAAK,EAAE,CAAC,GAAG,EAAE,YAAY,EAAE,OAAO,EAAE,YAAY,EAAE,GAAG,EAAE,QAAQ,KAAK,OAAO,CAAA;CAC5E;AAED,sEAAsE;AACtE,MAAM,WAAW,kBAAkB;IACjC,OAAO,EAAE,YAAY,CAAA;IACrB,GAAG,EAAE,QAAQ,CAAA;IACb,uDAAuD;IACvD,QAAQ,CAAC,EAAE,CAAC,KAAK,EAAE,MAAM,EAAE,MAAM,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,KAAK,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC,CAAA;CACpF;AAED;;;;;GAKG;AACH,MAAM,WAAW,WAAW;IAC1B,EAAE,EAAE,MAAM,CAAA;IACV,6DAA6D;IAC7D,IAAI,CAAC,EAAE,MAAM,CAAA;IACb,KAAK,CAAC,EAAE,MAAM,CAAA;IACd,OAAO,CAAC,EAAE,MAAM,CAAA;IAChB,IAAI,CAAC,EAAE,MAAM,CAAA;IACb,KAAK,CAAC,EAAE,MAAM,CAAA;IACd,QAAQ,CAAC,EAAE,mBAAmB,CAAA;IAC9B,UAAU,CAAC,EAAE,OAAO,CAAA;IACpB,MAAM,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAA;IAC/B,KAAK,EAAE,CAAC,GAAG,EAAE,kBAAkB,KAAK,OAAO,CAAC,YAAY,CAAC,CAAA;CAC1D;AAED,MAAM,WAAW,iBAAiB;IAChC,KAAK,EAAE,MAAM,CAAA;IACb,IAAI,EAAE,CAAC,GAAG,EAAE,kBAAkB,KAAK,WAAW,EAAE,CAAA;CACjD;AAED,kFAAkF;AAClF,MAAM,WAAW,gBAAgB;IAC/B,mEAAmE;IACnE,IAAI,CAAC,EAAE,aAAa,CAAC;QAAE,SAAS,CAAC,EAAE,MAAM,CAAA;KAAE,CAAC,GAAG,SAAS,CAAA;IACxD,KAAK,CAAC,EAAE,SAAS,CAAA;IACjB,QAAQ,CAAC,EAAE,SAAS,CAAA;IACpB;;;OAGG;IACH,SAAS,CAAC,EAAE,CAAC,GAAG,EAAE,MAAM,EAAE,YAAY,EAAE,MAAM,KAAK,MAAM,CAAA;IACzD;;;;;OAKG;IACH,MAAM,CAAC,EAAE,MAAM,CAAA;IACf,qDAAqD;IACrD,OAAO,CAAC,EAAE,WAAW,EAAE,GAAG,CAAC,CAAC,OAAO,EAAE,WAAW,EAAE,KAAK,WAAW,EAAE,CAAC,CAAA;IACrE,KAAK,CAAC,EAAE,gBAAgB,GAAG,KAAK,CAAA;IAChC,MAAM,CAAC,EAAE,iBAAiB,CAAA;IAC1B,kDAAkD;IAClD,MAAM,CAAC,EAAE,SAAS,CAAA;IAClB,SAAS,CAAC,EAAE,MAAM,CAAA;IAClB,kBAAkB,CAAC,EAAE,MAAM,CAAA;IAC3B;;;;;;OAMG;IACH,KAAK,CAAC,EAAE,aAAa,CAAA;CACtB;AAED,MAAM,MAAM,oBAAoB,GAAG,aAAa,CAAC,gBAAgB,CAAC,CAAA;AAElE;;;;;;;;GAQG;AACH,MAAM,MAAM,aAAa,GAAG,CAAC,OAAO,EAAE,YAAY,EAAE,GAAG,EAAE,QAAQ,KAAK,IAAI,CAAA;AAE1E,MAAM,WAAW,YAAa,SAAQ,WAAW;IAC/C,cAAc,EAAE,CAAC,MAAM,EAAE,WAAW,KAAK,IAAI,CAAA;IAC7C,uEAAuE;IACvE,MAAM,EAAE,CAAC,GAAG,CAAC,EAAE,QAAQ,KAAK,WAAW,CAAA;IACvC,6DAA6D;IAC7D,GAAG,EAAE,MAAM,QAAQ,CAAA;IACnB,0FAA0F;IAC1F,oBAAoB,EAAE,CAAC,YAAY,EAAE,iBAAiB,KAAK,IAAI,CAAA;IAC/D,qEAAqE;IACrE,oBAAoB,EAAE,CAAC,MAAM,EAAE,iBAAiB,KAAK,IAAI,CAAA;IACzD,OAAO,EAAE,CAAC,GAAG,EAAE,kBAAkB,KAAK,WAAW,EAAE,CAAA;IACnD;;;;;OAKG;IACH,cAAc,EAAE,CAAC,MAAM,EAAE,oBAAoB,KAAK,IAAI,CAAA;IACtD,MAAM,EAAE,MAAM,oBAAoB,GAAG,IAAI,CAAA;IACzC,8EAA8E;IAC9E,gBAAgB,EAAE,CAAC,QAAQ,EAAE,aAAa,KAAK,IAAI,CAAA;IACnD,oFAAoF;IACpF,YAAY,EAAE,CAAC,IAAI,EAAE,SAAS,KAAK,IAAI,CAAA;IACvC,6DAA6D;IAC7D,KAAK,EAAE,MAAM,SAAS,EAAE,CAAA;IACxB,sGAAsG;IACtG,QAAQ,EAAE,CAAC,IAAI,EAAE,gBAAgB,KAAK,IAAI,CAAA;IAC1C,qEAAqE;IACrE,YAAY,EAAE,MAAM,gBAAgB,EAAE,CAAA;IAItC,KAAK,EAAE,MAAM,IAAI,CAAA;IACjB,KAAK,EAAE,CAAC,OAAO,EAAE,YAAY,KAAK,OAAO,CAAC,YAAY,CAAC,CAAA;IACvD,SAAS,EAAE,CAAC,GAAG,EAAE,MAAM,KAAK,OAAO,CAAC,YAAY,CAAC,CAAA;IACjD,QAAQ,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,OAAO,CAAC,YAAY,CAAC,CAAA;IAClD,MAAM,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,OAAO,CAAC,YAAY,CAAC,CAAA;IAChD,MAAM,EAAE,CAAC,OAAO,EAAE,aAAa,KAAK,OAAO,CAAC,YAAY,CAAC,CAAA;IACzD,cAAc,EAAE,MAAM,OAAO,CAAC,YAAY,CAAC,CAAA;IAC3C,qEAAqE;IACrE,KAAK,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,OAAO,CAAC,IAAI,CAAC,CAAA;IACvC,wEAAwE;IACxE,MAAM,EAAE,MAAM,OAAO,CAAC,IAAI,CAAC,CAAA;CAC5B;AAED;;;;;;;GAOG;AACH
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/login/types.ts"],"names":[],"mappings":"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"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@owlmeans/client-auth",
|
|
3
|
-
"version": "0.1.18-rc.
|
|
3
|
+
"version": "0.1.18-rc.49",
|
|
4
4
|
"license": "MIT",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"scripts": {
|
|
@@ -50,26 +50,26 @@
|
|
|
50
50
|
}
|
|
51
51
|
},
|
|
52
52
|
"dependencies": {
|
|
53
|
-
"@owlmeans/auth": "^0.1.18-rc.
|
|
54
|
-
"@owlmeans/auth-common": "^0.1.18-rc.
|
|
55
|
-
"@owlmeans/basic-envelope": "^0.1.18-rc.
|
|
56
|
-
"@owlmeans/basic-keys": "^0.1.18-rc.
|
|
57
|
-
"@owlmeans/client": "^0.1.18-rc.
|
|
58
|
-
"@owlmeans/client-context": "^0.1.18-rc.
|
|
59
|
-
"@owlmeans/client-entrypoint": "^0.1.18-rc.
|
|
60
|
-
"@owlmeans/client-flow": "^0.1.18-rc.
|
|
61
|
-
"@owlmeans/client-resource": "^0.1.18-rc.
|
|
62
|
-
"@owlmeans/client-socket": "^0.1.18-rc.
|
|
63
|
-
"@owlmeans/config": "^0.1.18-rc.
|
|
53
|
+
"@owlmeans/auth": "^0.1.18-rc.36",
|
|
54
|
+
"@owlmeans/auth-common": "^0.1.18-rc.38",
|
|
55
|
+
"@owlmeans/basic-envelope": "^0.1.18-rc.37",
|
|
56
|
+
"@owlmeans/basic-keys": "^0.1.18-rc.39",
|
|
57
|
+
"@owlmeans/client": "^0.1.18-rc.42",
|
|
58
|
+
"@owlmeans/client-context": "^0.1.18-rc.39",
|
|
59
|
+
"@owlmeans/client-entrypoint": "^0.1.18-rc.38",
|
|
60
|
+
"@owlmeans/client-flow": "^0.1.18-rc.45",
|
|
61
|
+
"@owlmeans/client-resource": "^0.1.18-rc.38",
|
|
62
|
+
"@owlmeans/client-socket": "^0.1.18-rc.40",
|
|
63
|
+
"@owlmeans/config": "^0.1.18-rc.38",
|
|
64
64
|
"@owlmeans/context": "^0.1.18-rc.32",
|
|
65
|
-
"@owlmeans/did": "^0.1.18-rc.
|
|
66
|
-
"@owlmeans/entrypoint": "^0.1.18-rc.
|
|
67
|
-
"@owlmeans/error": "^0.1.18-rc.
|
|
68
|
-
"@owlmeans/flow": "^0.1.18-rc.
|
|
69
|
-
"@owlmeans/i18n": "^0.1.18-rc.
|
|
70
|
-
"@owlmeans/resource": "^0.1.18-rc.
|
|
71
|
-
"@owlmeans/socket": "^0.1.18-rc.
|
|
72
|
-
"@owlmeans/web-flow": "^0.1.18-rc.
|
|
65
|
+
"@owlmeans/did": "^0.1.18-rc.37",
|
|
66
|
+
"@owlmeans/entrypoint": "^0.1.18-rc.37",
|
|
67
|
+
"@owlmeans/error": "^0.1.18-rc.36",
|
|
68
|
+
"@owlmeans/flow": "^0.1.18-rc.39",
|
|
69
|
+
"@owlmeans/i18n": "^0.1.18-rc.37",
|
|
70
|
+
"@owlmeans/resource": "^0.1.18-rc.36",
|
|
71
|
+
"@owlmeans/socket": "^0.1.18-rc.34",
|
|
72
|
+
"@owlmeans/web-flow": "^0.1.18-rc.44",
|
|
73
73
|
"@scure/base": "^2.3.0"
|
|
74
74
|
},
|
|
75
75
|
"peerDependencies": {
|
|
@@ -78,7 +78,7 @@
|
|
|
78
78
|
},
|
|
79
79
|
"devDependencies": {
|
|
80
80
|
"@owlmeans/dep-config": "workspace:*",
|
|
81
|
-
"@owlmeans/test-auth": "^0.1.18-rc.
|
|
81
|
+
"@owlmeans/test-auth": "^0.1.18-rc.37",
|
|
82
82
|
"@types/bun": "^1.4.0",
|
|
83
83
|
"@types/react": "^19.2.17",
|
|
84
84
|
"nodemon": "^3.1.14",
|
package/src/login/land.ts
CHANGED
|
@@ -13,8 +13,10 @@ import type { LandOptions, LoginContext, LoginLanding, LoginService } from './ty
|
|
|
13
13
|
/**
|
|
14
14
|
* Bound on a single step's `pending` check, or a landing hook's `landed` call.
|
|
15
15
|
*
|
|
16
|
-
* A step/hook that hangs must never
|
|
17
|
-
* `landAfterLogin` treat a timeout exactly like a rejection
|
|
16
|
+
* A step/hook that hangs must never HANG sign-in itself — both `continueLogin` and
|
|
17
|
+
* `landAfterLogin` treat a timeout exactly like a rejection, resolving within this budget either
|
|
18
|
+
* way. What that resolves TO is fail-open ("not pending") for an ordinary step, and fail-closed
|
|
19
|
+
* ("pending") for one that declared itself `required` — see `continueLogin`'s `onBroken`.
|
|
18
20
|
*/
|
|
19
21
|
export const LOGIN_STEP_TIMEOUT = 5_000
|
|
20
22
|
|
|
@@ -22,17 +24,22 @@ export const LOGIN_STEP_TIMEOUT = 5_000
|
|
|
22
24
|
export const LOGIN_LANDED_STORAGE = '_owlmeans-login-landed'
|
|
23
25
|
|
|
24
26
|
/**
|
|
25
|
-
* Race a promise against a bound, resolving `
|
|
27
|
+
* Race a promise against a bound, resolving to `onTimeout` (never rejecting) if the bound wins.
|
|
26
28
|
*
|
|
27
29
|
* A synchronous throw from the wrapped call is turned into a rejection by the caller before this
|
|
28
|
-
* ever sees it, so the only two outcomes here are "settled in time" and "timed out".
|
|
30
|
+
* ever sees it, so the only two outcomes here are "settled in time" and "timed out". `onTimeout`
|
|
31
|
+
* defaults to `undefined` — every existing caller that omits it keeps its old fail-open meaning;
|
|
32
|
+
* `continueLogin` passes a step's own `required` flag through it so a step that hangs is read the
|
|
33
|
+
* same way as one that throws.
|
|
29
34
|
*/
|
|
30
|
-
const withTimeout = async <T>(
|
|
35
|
+
const withTimeout = async <T>(
|
|
36
|
+
promise: Promise<T>, ms: number, onTimeout?: T
|
|
37
|
+
): Promise<T | undefined> => {
|
|
31
38
|
let timer: ReturnType<typeof setTimeout> | undefined
|
|
32
39
|
try {
|
|
33
40
|
return await Promise.race<T | undefined>([
|
|
34
41
|
promise,
|
|
35
|
-
new Promise<undefined>(resolve => { timer = setTimeout(() => resolve(
|
|
42
|
+
new Promise<T | undefined>(resolve => { timer = setTimeout(() => resolve(onTimeout), ms) }),
|
|
36
43
|
])
|
|
37
44
|
} finally {
|
|
38
45
|
if (timer != null) {
|
|
@@ -117,10 +124,13 @@ export const continueLogin = async (ctx: LoginContext, opts?: LandOptions): Prom
|
|
|
117
124
|
continue
|
|
118
125
|
}
|
|
119
126
|
|
|
120
|
-
// A step that throws or hangs
|
|
127
|
+
// A step that throws or hangs fails OPEN ("not pending") by default — UNLESS it declared
|
|
128
|
+
// itself `required`, in which case a broken read must show the step rather than let the
|
|
129
|
+
// person through it unconfirmed (a Terms box moved here from the sign-in screen).
|
|
130
|
+
const onBroken = step.required === true
|
|
121
131
|
const pending = await withTimeout(
|
|
122
|
-
Promise.resolve().then(() => step.pending(ctx)), timeout
|
|
123
|
-
).catch(() =>
|
|
132
|
+
Promise.resolve().then(() => step.pending(ctx)), timeout, onBroken
|
|
133
|
+
).catch(() => onBroken)
|
|
124
134
|
|
|
125
135
|
if (pending === true) {
|
|
126
136
|
return { alias: step.entrypoint, query: await step.query?.(ctx), step: step.alias }
|
package/src/login/screen.tsx
CHANGED
|
@@ -5,37 +5,12 @@ import type { CommonConfig } from '@owlmeans/config'
|
|
|
5
5
|
import type { LoginContext, LoginMethod, LoginScreenProps, LoginService } from './types.js'
|
|
6
6
|
import { LOGIN_SERVICE } from './consts.js'
|
|
7
7
|
import { primaryLoginMethod } from './methods.js'
|
|
8
|
-
import {
|
|
9
|
-
|
|
8
|
+
import {
|
|
9
|
+
acceptTerms, resolveTerms, termsAccepted, termsDeferred, termsLabelResolver, termsSentence,
|
|
10
|
+
} from './terms.js'
|
|
11
|
+
import type { TermsSentencePart } from './terms.js'
|
|
10
12
|
import { resolveCredit } from './credit.js'
|
|
11
13
|
|
|
12
|
-
/** The same English fallbacks `@owlmeans/web-panel`'s `LoginTerms` uses, kept in sync by hand. */
|
|
13
|
-
const DEFAULT_LABEL: Record<string, string> = {
|
|
14
|
-
terms: 'Terms & Conditions',
|
|
15
|
-
privacy: 'Privacy Policy',
|
|
16
|
-
cookies: 'Cookie Policy',
|
|
17
|
-
billing: 'Billing Terms',
|
|
18
|
-
product: '{{product}} Product Terms',
|
|
19
|
-
}
|
|
20
|
-
|
|
21
|
-
const resolveLabelFor = (
|
|
22
|
-
translate: (key: string, defaultValue: string) => string, locale: string | undefined
|
|
23
|
-
) => (doc: ResolvedTermsDocument): string => {
|
|
24
|
-
const fromMap = doc.labelMap != null
|
|
25
|
-
? (locale != null ? doc.labelMap[locale] : undefined) ?? Object.values(doc.labelMap)[0]
|
|
26
|
-
: undefined
|
|
27
|
-
let label = doc.label ?? fromMap
|
|
28
|
-
?? (doc.i18nKey != null ? translate(doc.i18nKey, DEFAULT_LABEL[doc.key] ?? doc.key) : doc.key)
|
|
29
|
-
|
|
30
|
-
if (doc.params != null) {
|
|
31
|
-
for (const [key, value] of Object.entries(doc.params)) {
|
|
32
|
-
label = label.split(`{{${key}}}`).join(value)
|
|
33
|
-
}
|
|
34
|
-
}
|
|
35
|
-
|
|
36
|
-
return label
|
|
37
|
-
}
|
|
38
|
-
|
|
39
14
|
const renderParts = (parts: TermsSentencePart[]): ReactNode =>
|
|
40
15
|
parts.map((part, index) => part.href != null
|
|
41
16
|
? <a key={index} href={part.href} target="_blank" rel="noreferrer noopener">{part.text}</a>
|
|
@@ -89,7 +64,8 @@ export const FallbackLoginScreen: FC<LoginScreenProps> = props => {
|
|
|
89
64
|
const env = login.env()
|
|
90
65
|
const resolved = resolveTerms(props.terms ?? cfg?.terms)
|
|
91
66
|
const credit = resolveCredit(cfg?.credit, brand, context.cfg.service)
|
|
92
|
-
const resolveLabel =
|
|
67
|
+
const resolveLabel = termsLabelResolver(t, props.locale)
|
|
68
|
+
const deferred = termsDeferred(context)
|
|
93
69
|
|
|
94
70
|
const [accepted, setAccepted] = useState(() => termsAccepted(resolved))
|
|
95
71
|
const [attempted, setAttempted] = useState(false)
|
|
@@ -100,7 +76,7 @@ export const FallbackLoginScreen: FC<LoginScreenProps> = props => {
|
|
|
100
76
|
: props.methods ?? all
|
|
101
77
|
const primary = primaryLoginMethod(methods)
|
|
102
78
|
|
|
103
|
-
const blocked = resolved != null && resolved.required && !accepted
|
|
79
|
+
const blocked = resolved != null && resolved.required && !deferred && !accepted
|
|
104
80
|
|
|
105
81
|
const select = useCallback((method: LoginMethod) => {
|
|
106
82
|
if (blocked) {
|
|
@@ -138,7 +114,11 @@ export const FallbackLoginScreen: FC<LoginScreenProps> = props => {
|
|
|
138
114
|
{method.label ?? t(`login.method.${method.i18nKey ?? method.id}`, method.id)}
|
|
139
115
|
</button>)}
|
|
140
116
|
|
|
141
|
-
{
|
|
117
|
+
{/* When a registered, bound step confirms the terms instead, this screen shows neither the
|
|
118
|
+
checkbox nor its "last updated" line — that document is agreed to over there, and this
|
|
119
|
+
screen is never `blocked` on it. The privacy notice below still renders either way: it was
|
|
120
|
+
never inside the consented label, so deferring the checkbox does not touch it. */}
|
|
121
|
+
{resolved != null && !deferred && <p style={{ marginTop: '1rem', fontSize: '.875rem' }}>
|
|
142
122
|
{/* The ONLY place `data-login-terms` appears — never duplicated onto a second control. */}
|
|
143
123
|
<label>
|
|
144
124
|
<input
|
|
@@ -152,7 +132,7 @@ export const FallbackLoginScreen: FC<LoginScreenProps> = props => {
|
|
|
152
132
|
</label>
|
|
153
133
|
</p>}
|
|
154
134
|
|
|
155
|
-
{resolved?.revisedAt != null && <p data-login-revised style={{ fontSize: '.75rem', opacity: .7 }}>
|
|
135
|
+
{resolved?.revisedAt != null && !deferred && <p data-login-revised style={{ fontSize: '.75rem', opacity: .7 }}>
|
|
156
136
|
{t('login.terms.revised', 'Last updated: {{date}}').split('{{date}}').join(resolved.revisedAt)}
|
|
157
137
|
</p>}
|
|
158
138
|
|
package/src/login/terms.ts
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { OWLMEANS_COOKIES_URL, OWLMEANS_PRIVACY_URL, OWLMEANS_TERMS_URL } from '@owlmeans/config'
|
|
2
2
|
import type { LoginTermsConfig } from '@owlmeans/config'
|
|
3
|
-
import { LOGIN_TERMS_STORAGE } from './consts.js'
|
|
3
|
+
import { LOGIN_SERVICE, LOGIN_TERMS_STORAGE } from './consts.js'
|
|
4
|
+
import type { LoginContext, LoginService } from './types.js'
|
|
4
5
|
import './terms-config.js'
|
|
5
6
|
|
|
6
7
|
/** One document (or notice) a sign-in screen links to. */
|
|
@@ -180,6 +181,83 @@ export const acceptTerms = (resolved: ResolvedTerms | null, accepted: boolean):
|
|
|
180
181
|
} catch { /* nothing to remember if storage was never available */ }
|
|
181
182
|
}
|
|
182
183
|
|
|
184
|
+
/** The same English fallback a document's `i18nKey` translates to when nothing else names it. */
|
|
185
|
+
const DEFAULT_LABEL: Record<string, string> = {
|
|
186
|
+
terms: 'Terms & Conditions',
|
|
187
|
+
privacy: 'Privacy Policy',
|
|
188
|
+
cookies: 'Cookie Policy',
|
|
189
|
+
billing: 'Billing Terms',
|
|
190
|
+
product: '{{product}} Product Terms',
|
|
191
|
+
}
|
|
192
|
+
|
|
193
|
+
/**
|
|
194
|
+
* A document's own label: a caller's literal `label`, else its `labelMap` for the current locale,
|
|
195
|
+
* else its `i18nKey` translated — each with `params` (e.g. `{ product: 'Acme' }`) interpolated
|
|
196
|
+
* afterwards, since the `translate` contract every renderer shares is a plain
|
|
197
|
+
* `(key, defaultValue) => string` with no interpolation option of its own.
|
|
198
|
+
*
|
|
199
|
+
* The one label resolver every renderer of a terms sentence uses — `FallbackLoginScreen` here, and
|
|
200
|
+
* `@owlmeans/web-panel`'s `LoginTerms` — so the English fallbacks and the resolution order live in
|
|
201
|
+
* exactly one place instead of two hand-kept copies.
|
|
202
|
+
*/
|
|
203
|
+
export const termsLabelResolver = (
|
|
204
|
+
translate: (key: string, defaultValue: string) => string, locale: string | undefined
|
|
205
|
+
) => (doc: ResolvedTermsDocument): string => {
|
|
206
|
+
const fromMap = doc.labelMap != null
|
|
207
|
+
? (locale != null ? doc.labelMap[locale] : undefined) ?? Object.values(doc.labelMap)[0]
|
|
208
|
+
: undefined
|
|
209
|
+
let label = doc.label ?? fromMap
|
|
210
|
+
?? (doc.i18nKey != null ? translate(doc.i18nKey, DEFAULT_LABEL[doc.key] ?? doc.key) : doc.key)
|
|
211
|
+
|
|
212
|
+
if (doc.params != null) {
|
|
213
|
+
for (const [key, value] of Object.entries(doc.params)) {
|
|
214
|
+
label = label.split(`{{${key}}}`).join(value)
|
|
215
|
+
}
|
|
216
|
+
}
|
|
217
|
+
|
|
218
|
+
return label
|
|
219
|
+
}
|
|
220
|
+
|
|
221
|
+
/** One document as `@owlmeans/marketing-consent`'s `TermsDocumentRef` shape — structurally, with
|
|
222
|
+
* no dependency on that package (client-auth is a layer below it). */
|
|
223
|
+
export interface TermsAcceptanceRef {
|
|
224
|
+
key: string
|
|
225
|
+
href: string
|
|
226
|
+
revisedAt?: string
|
|
227
|
+
}
|
|
228
|
+
|
|
229
|
+
/**
|
|
230
|
+
* What a sign-in-time terms acceptance sends the server — structurally
|
|
231
|
+
* `@owlmeans/marketing-consent`'s `TermsAcceptance`, so `client.recordTerms(termsAcceptanceOf(...))`
|
|
232
|
+
* type-checks with no dependency in this direction. Shared by `termsRecorder` (the sign-in screen's
|
|
233
|
+
* own local acceptance, copied at landing) and a Terms-mode consent screen recording the box it
|
|
234
|
+
* just showed.
|
|
235
|
+
*/
|
|
236
|
+
export const termsAcceptanceOf = (
|
|
237
|
+
resolved: Pick<ResolvedTerms, 'documents' | 'notices' | 'version'>, locale?: string
|
|
238
|
+
): { documents: TermsAcceptanceRef[], notices: TermsAcceptanceRef[], version: string, locale?: string } => ({
|
|
239
|
+
documents: resolved.documents.map(doc => ({ key: doc.key, href: doc.href, revisedAt: doc.revisedAt })),
|
|
240
|
+
notices: resolved.notices.map(doc => ({ key: doc.key, href: doc.href, revisedAt: doc.revisedAt })),
|
|
241
|
+
version: resolved.version,
|
|
242
|
+
...(locale != null ? { locale } : {}),
|
|
243
|
+
})
|
|
244
|
+
|
|
245
|
+
/**
|
|
246
|
+
* Whether the Terms confirmation has been moved off the sign-in screen onto a registered step.
|
|
247
|
+
*
|
|
248
|
+
* True only when a step both DECLARES `confirmsTerms` and is BOUND (`ctx.hasEntrypoint`) — an app
|
|
249
|
+
* that registers the step (e.g. `appendMarketingConsent({ terms: 'step' })`) but never binds its
|
|
250
|
+
* screen (an older target, a partial import) keeps the sign-in checkbox, fail-closed: a person must
|
|
251
|
+
* never find the confirmation missing from both places at once.
|
|
252
|
+
*
|
|
253
|
+
* Reads the service directly (`ctx.hasService`), never `ensureLoginService` — that registers an
|
|
254
|
+
* empty host as a side effect, which a render-time check must not do.
|
|
255
|
+
*/
|
|
256
|
+
export const termsDeferred = (ctx: LoginContext): boolean =>
|
|
257
|
+
ctx.hasService(LOGIN_SERVICE)
|
|
258
|
+
&& ctx.service<LoginService>(LOGIN_SERVICE).steps()
|
|
259
|
+
.some(step => step.confirmsTerms === true && ctx.hasEntrypoint(step.entrypoint))
|
|
260
|
+
|
|
183
261
|
/** One fragment of an interpolated terms sentence — plain text, or a link to a document. */
|
|
184
262
|
export interface TermsSentencePart {
|
|
185
263
|
text: string
|
package/src/login/types.ts
CHANGED
|
@@ -289,14 +289,6 @@ export interface LoginService extends LazyService {
|
|
|
289
289
|
revoke: () => Promise<void>
|
|
290
290
|
}
|
|
291
291
|
|
|
292
|
-
/**
|
|
293
|
-
* A step to run after sign-in completes, before the ordinary landing.
|
|
294
|
-
*
|
|
295
|
-
* Registered by a package that must collect something from a freshly authenticated user before
|
|
296
|
-
* the application resumes wherever it was headed — the marketing-consent screen is the first
|
|
297
|
-
* consumer. `landAfterLogin`/`continueLogin` (./land.js) walk the registered steps in priority
|
|
298
|
-
* order and land on the first one whose `pending` resolves `true`.
|
|
299
|
-
*/
|
|
300
292
|
/**
|
|
301
293
|
* The value shape a landing's `params`/`query` carries.
|
|
302
294
|
*
|
|
@@ -307,6 +299,14 @@ export interface LoginService extends LazyService {
|
|
|
307
299
|
*/
|
|
308
300
|
export type LoginLandingParams = Record<string, string | number | boolean | undefined | null>
|
|
309
301
|
|
|
302
|
+
/**
|
|
303
|
+
* A step to run after sign-in completes, before the ordinary landing.
|
|
304
|
+
*
|
|
305
|
+
* Registered by a package that must collect something from a freshly authenticated user before
|
|
306
|
+
* the application resumes wherever it was headed — the marketing-consent screen is the first
|
|
307
|
+
* consumer. `landAfterLogin`/`continueLogin` (./land.js) walk the registered steps in priority
|
|
308
|
+
* order and land on the first one whose `pending` resolves `true`.
|
|
309
|
+
*/
|
|
310
310
|
export interface LoginStep {
|
|
311
311
|
alias: string
|
|
312
312
|
/** Higher runs first. Defaults to 0. */
|
|
@@ -317,6 +317,22 @@ export interface LoginStep {
|
|
|
317
317
|
query?: (ctx: LoginContext) => LoginLandingParams | undefined
|
|
318
318
|
/** Whether this step still has something to collect from the signed-in user. */
|
|
319
319
|
pending: (ctx: LoginContext) => Promise<boolean>
|
|
320
|
+
/**
|
|
321
|
+
* This step is where the Terms confirmation lives instead of on the sign-in screen.
|
|
322
|
+
*
|
|
323
|
+
* `termsDeferred(ctx)` (`./terms.js`) is true only while a step with this flag is both
|
|
324
|
+
* registered AND bound (`ctx.hasEntrypoint(step.entrypoint)`) — an app that registers the step
|
|
325
|
+
* but never binds its screen keeps the sign-in checkbox, fail-closed.
|
|
326
|
+
*/
|
|
327
|
+
confirmsTerms?: boolean
|
|
328
|
+
/**
|
|
329
|
+
* A `pending` that throws or times out counts as PENDING rather than "not pending".
|
|
330
|
+
*
|
|
331
|
+
* The default (`undefined`/`false`) keeps every existing step fail-open, exactly as before —
|
|
332
|
+
* this flag is for a step whose whole point is to gate the landing on something the person must
|
|
333
|
+
* do (Terms confirmation), where a broken read must show the step rather than let it through.
|
|
334
|
+
*/
|
|
335
|
+
required?: boolean
|
|
320
336
|
}
|
|
321
337
|
|
|
322
338
|
/** Where a finished sign-in (or a pending step) lands. */
|
package/src/manager/README.md
CHANGED
|
@@ -37,7 +37,7 @@ Comprehensive error handling for authentication scenarios:
|
|
|
37
37
|
This manager is part of the `@owlmeans/client-auth` package:
|
|
38
38
|
|
|
39
39
|
```bash
|
|
40
|
-
npm install @owlmeans/client-auth@^0.1.18-rc.
|
|
40
|
+
npm install @owlmeans/client-auth@^0.1.18-rc.49
|
|
41
41
|
```
|
|
42
42
|
|
|
43
43
|
## API Reference
|
package/tests/land.spec.ts
CHANGED
|
@@ -171,6 +171,59 @@ describe('continueLogin — steps', () => {
|
|
|
171
171
|
})
|
|
172
172
|
})
|
|
173
173
|
|
|
174
|
+
describe('continueLogin — a `required` step', () => {
|
|
175
|
+
test('a `required` step whose `pending` throws is treated as PENDING — fail closed', async () => {
|
|
176
|
+
const [context, login] = await bootstrap({ authenticated: true })
|
|
177
|
+
allowEntrypoints(context, 'required-screen')
|
|
178
|
+
|
|
179
|
+
login.registerStep(step({
|
|
180
|
+
alias: 'required-broken', entrypoint: 'required-screen', required: true,
|
|
181
|
+
pending: async () => { throw new Error('boom') },
|
|
182
|
+
}))
|
|
183
|
+
|
|
184
|
+
expect(await continueLogin(context)).toEqual({
|
|
185
|
+
alias: 'required-screen', query: undefined, step: 'required-broken',
|
|
186
|
+
})
|
|
187
|
+
})
|
|
188
|
+
|
|
189
|
+
test('a `required` step whose `pending` never resolves is treated as PENDING after the timeout', async () => {
|
|
190
|
+
const [context, login] = await bootstrap({ authenticated: true })
|
|
191
|
+
allowEntrypoints(context, 'required-hanging-screen')
|
|
192
|
+
|
|
193
|
+
login.registerStep(step({
|
|
194
|
+
alias: 'required-hanging', entrypoint: 'required-hanging-screen', required: true,
|
|
195
|
+
pending: () => new Promise<boolean>(() => { /* never settles */ }),
|
|
196
|
+
}))
|
|
197
|
+
|
|
198
|
+
expect(await continueLogin(context, { stepTimeout: 20 })).toEqual({
|
|
199
|
+
alias: 'required-hanging-screen', query: undefined, step: 'required-hanging',
|
|
200
|
+
})
|
|
201
|
+
})
|
|
202
|
+
|
|
203
|
+
test('a `required` but UNBOUND step is still skipped, never blocks', async () => {
|
|
204
|
+
const [context, login] = await bootstrap({ authenticated: true })
|
|
205
|
+
let called = false
|
|
206
|
+
|
|
207
|
+
login.registerStep(step({
|
|
208
|
+
alias: 'required-unbound', entrypoint: 'nowhere', required: true,
|
|
209
|
+
pending: async () => { called = true; return true },
|
|
210
|
+
}))
|
|
211
|
+
|
|
212
|
+
expect(await continueLogin(context)).toEqual({ alias: HOME })
|
|
213
|
+
expect(called).toBe(false)
|
|
214
|
+
})
|
|
215
|
+
|
|
216
|
+
test('a `required` step that answers false, or true, still behaves ordinarily', async () => {
|
|
217
|
+
const [context, login] = await bootstrap({ authenticated: true })
|
|
218
|
+
allowEntrypoints(context, 'required-screen')
|
|
219
|
+
|
|
220
|
+
login.registerStep(step({
|
|
221
|
+
alias: 'required-ok', entrypoint: 'required-screen', required: true, pending: async () => false,
|
|
222
|
+
}))
|
|
223
|
+
expect(await continueLogin(context)).toEqual({ alias: HOME })
|
|
224
|
+
})
|
|
225
|
+
})
|
|
226
|
+
|
|
174
227
|
describe('landAfterLogin — the surrogate short circuit', () => {
|
|
175
228
|
test('returns DISPATCHER immediately; no step or hook ever runs', async () => {
|
|
176
229
|
const [context, login] = await bootstrap({ authenticated: true })
|
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
import { describe, expect, test } from 'bun:test'
|
|
2
|
+
import type { BasicContext, BasicConfig } from '@owlmeans/context'
|
|
3
|
+
import { makeTestContext } from './context.js'
|
|
4
|
+
import { appendLogin } from '../src/login/service.js'
|
|
5
|
+
import { termsDeferred } from '../src/login/terms.js'
|
|
6
|
+
import type { LoginStep } from '../src/login/types.js'
|
|
7
|
+
|
|
8
|
+
/** Grant a fake alias existence without building a real entrypoint/route graph. */
|
|
9
|
+
const allowEntrypoints = (context: BasicContext<BasicConfig>, ...aliases: string[]): void => {
|
|
10
|
+
(context as unknown as { hasEntrypoint: (alias: string) => boolean }).hasEntrypoint =
|
|
11
|
+
alias => aliases.includes(alias)
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
const step = (over: Partial<LoginStep> & { alias: string, entrypoint: string }): LoginStep => ({
|
|
15
|
+
pending: async () => false, ...over,
|
|
16
|
+
})
|
|
17
|
+
|
|
18
|
+
describe('termsDeferred', () => {
|
|
19
|
+
test('false with no login service registered at all', () => {
|
|
20
|
+
const context = makeTestContext()
|
|
21
|
+
|
|
22
|
+
expect(termsDeferred(context)).toBe(false)
|
|
23
|
+
})
|
|
24
|
+
|
|
25
|
+
test('false with a login service but no confirming step', () => {
|
|
26
|
+
const context = makeTestContext()
|
|
27
|
+
const contextual = appendLogin(context)
|
|
28
|
+
allowEntrypoints(context, 'consent-screen')
|
|
29
|
+
contextual.login().registerStep(step({ alias: 'other', entrypoint: 'consent-screen' }))
|
|
30
|
+
|
|
31
|
+
expect(termsDeferred(context)).toBe(false)
|
|
32
|
+
})
|
|
33
|
+
|
|
34
|
+
test('false when the confirming step is registered but its screen is not bound', () => {
|
|
35
|
+
const context = makeTestContext()
|
|
36
|
+
const contextual = appendLogin(context)
|
|
37
|
+
// hasEntrypoint left at its default (nothing bound) — an app that registered the step but
|
|
38
|
+
// never bound its screen keeps the sign-in checkbox, fail-closed.
|
|
39
|
+
contextual.login().registerStep(step({
|
|
40
|
+
alias: 'consent', entrypoint: 'consent-screen', confirmsTerms: true,
|
|
41
|
+
}))
|
|
42
|
+
|
|
43
|
+
expect(termsDeferred(context)).toBe(false)
|
|
44
|
+
})
|
|
45
|
+
|
|
46
|
+
test('true once a confirming step is both registered AND bound', () => {
|
|
47
|
+
const context = makeTestContext()
|
|
48
|
+
const contextual = appendLogin(context)
|
|
49
|
+
allowEntrypoints(context, 'consent-screen')
|
|
50
|
+
contextual.login().registerStep(step({
|
|
51
|
+
alias: 'consent', entrypoint: 'consent-screen', confirmsTerms: true,
|
|
52
|
+
}))
|
|
53
|
+
|
|
54
|
+
expect(termsDeferred(context)).toBe(true)
|
|
55
|
+
})
|
|
56
|
+
|
|
57
|
+
test('a non-confirming step bound elsewhere does not defer', () => {
|
|
58
|
+
const context = makeTestContext()
|
|
59
|
+
const contextual = appendLogin(context)
|
|
60
|
+
allowEntrypoints(context, 'other-screen')
|
|
61
|
+
contextual.login().registerStep(step({ alias: 'other', entrypoint: 'other-screen' }))
|
|
62
|
+
|
|
63
|
+
expect(termsDeferred(context)).toBe(false)
|
|
64
|
+
})
|
|
65
|
+
})
|
package/tests/terms.spec.ts
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { describe, expect, test } from 'bun:test'
|
|
2
2
|
import { OWLMEANS_COOKIES_URL, OWLMEANS_PRIVACY_URL, OWLMEANS_TERMS_URL } from '@owlmeans/config'
|
|
3
3
|
import type { LoginTermsConfig } from '@owlmeans/config'
|
|
4
|
-
import { resolveTerms, termsSentence } from '../src/login/terms.js'
|
|
4
|
+
import { resolveTerms, termsAcceptanceOf, termsLabelResolver, termsSentence } from '../src/login/terms.js'
|
|
5
5
|
import type { ResolvedTermsDocument } from '../src/login/terms.js'
|
|
6
6
|
|
|
7
7
|
/**
|
|
@@ -200,3 +200,57 @@ describe('termsSentence', () => {
|
|
|
200
200
|
expect(parts).toEqual([{ text: 'Terms & Conditions', href: 'https://a.test/terms', documentKey: 'terms' }])
|
|
201
201
|
})
|
|
202
202
|
})
|
|
203
|
+
|
|
204
|
+
describe('termsLabelResolver', () => {
|
|
205
|
+
test('resolves a document label the same way the two renderers used to, by hand', () => {
|
|
206
|
+
const translate = (key: string, defaultValue: string) => key === 'login.terms.custom' ? 'Custom!' : defaultValue
|
|
207
|
+
const resolve = termsLabelResolver(translate, 'en')
|
|
208
|
+
|
|
209
|
+
expect(resolve({ key: 'terms', href: 'https://a.test/terms', i18nKey: 'login.terms.terms' }))
|
|
210
|
+
.toBe('Terms & Conditions')
|
|
211
|
+
expect(resolve({ key: 'x', href: 'https://a.test/x', i18nKey: 'login.terms.custom' })).toBe('Custom!')
|
|
212
|
+
expect(resolve({ key: 'x', href: 'https://a.test/x', label: 'Literal' })).toBe('Literal')
|
|
213
|
+
expect(resolve({ key: 'x', href: 'https://a.test/x', labelMap: { en: 'English', fr: 'Français' } }))
|
|
214
|
+
.toBe('English')
|
|
215
|
+
expect(resolve({
|
|
216
|
+
key: 'product', href: 'https://a.test/p', i18nKey: 'login.terms.product', params: { product: 'Acme' },
|
|
217
|
+
})).toBe('{{product}} Product Terms'.replace('{{product}}', 'Acme'))
|
|
218
|
+
})
|
|
219
|
+
})
|
|
220
|
+
|
|
221
|
+
describe('termsAcceptanceOf', () => {
|
|
222
|
+
test('keeps only key/href/revisedAt — never i18nKey, params or label', () => {
|
|
223
|
+
// A viable-shaped config: billing, a product document carrying `params`, and revisions —
|
|
224
|
+
// exactly what `termsRecorder`/a Terms-mode consent screen sends the server.
|
|
225
|
+
const resolved = resolveTerms({
|
|
226
|
+
terms: 'https://a.test/terms', privacy: 'https://a.test/privacy', cookies: 'https://a.test/cookies',
|
|
227
|
+
billing: { href: 'https://a.test/billing', revisedAt: '2026-02-01' },
|
|
228
|
+
product: { name: 'Acme', href: 'https://a.test/product' },
|
|
229
|
+
revisions: { terms: '2026-01-15', privacy: '2026-01-15' },
|
|
230
|
+
})!
|
|
231
|
+
|
|
232
|
+
const acceptance = termsAcceptanceOf(resolved, 'en')
|
|
233
|
+
|
|
234
|
+
expect(acceptance.version).toBe(resolved.version)
|
|
235
|
+
expect(acceptance.locale).toBe('en')
|
|
236
|
+
expect(acceptance.documents).toEqual([
|
|
237
|
+
{ key: 'terms', href: 'https://a.test/terms', revisedAt: '2026-01-15' },
|
|
238
|
+
{ key: 'billing', href: 'https://a.test/billing', revisedAt: '2026-02-01' },
|
|
239
|
+
{ key: 'product', href: 'https://a.test/product', revisedAt: undefined },
|
|
240
|
+
])
|
|
241
|
+
expect(acceptance.notices).toEqual([
|
|
242
|
+
{ key: 'privacy', href: 'https://a.test/privacy', revisedAt: '2026-01-15' },
|
|
243
|
+
{ key: 'cookies', href: 'https://a.test/cookies', revisedAt: undefined },
|
|
244
|
+
])
|
|
245
|
+
// Every key is exactly {key, href, revisedAt} — no i18nKey, params or label leaked through.
|
|
246
|
+
for (const doc of [...acceptance.documents, ...acceptance.notices]) {
|
|
247
|
+
expect(Object.keys(doc).sort()).toEqual(['href', 'key', 'revisedAt'])
|
|
248
|
+
}
|
|
249
|
+
})
|
|
250
|
+
|
|
251
|
+
test('omits `locale` entirely when none is given', () => {
|
|
252
|
+
const resolved = resolveTerms({ terms: 'https://a.test/terms' })!
|
|
253
|
+
|
|
254
|
+
expect(termsAcceptanceOf(resolved)).not.toHaveProperty('locale')
|
|
255
|
+
})
|
|
256
|
+
})
|