@scalemule/news-publication 0.0.69 → 0.0.72

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.
@@ -0,0 +1,318 @@
1
+ export { R as READER_SSO_EVENTS, a as READER_SSO_PROPERTY_KEYS, b as ReaderSsoEventDefinition, c as ReaderSsoEventName } from './reader-sso-events-DBw8pGSM.cjs';
2
+
3
+ type ReaderSsoMode = "interactive" | "silent";
4
+ type ReaderSsoProvider = "google" | "email";
5
+ type ReaderSsoMethod = ReaderSsoProvider | "link" | "switch" | "unknown";
6
+ declare const READER_SSO_FLOW_SECONDS = 600;
7
+ declare const READER_SSO_NEGATIVE_CACHE_SECONDS = 300;
8
+ declare const READER_SSO_SIGNED_OUT_SECONDS = 86400;
9
+ declare const READER_SSO_PENDING_SECONDS = 600;
10
+ declare const LEDVERY_ISSUER_ORIGIN = "https://api.ledvery.com";
11
+ /** Ledvery results that mean "no silent session here"; never authentication failures. */
12
+ declare const SILENT_NEGATIVE_ERRORS: readonly ["login_required", "consent_required", "interaction_required", "account_selection_required"];
13
+ type ReaderSsoCookieNames = {
14
+ /** The reader's platform session token. */
15
+ session: string;
16
+ /** Sealed sign-in transaction (10 minutes). */
17
+ flow: string;
18
+ /** Newsletter consent carried through email verification. */
19
+ newsletter: string;
20
+ /** Negative cache: a silent check ran recently and found nothing. */
21
+ ssoChecked: string;
22
+ /** Explicit sign-out: silent sign-in stays off until an explicit sign-in. */
23
+ signedOut: string;
24
+ /** A verified session waiting for the reader to choose between two accounts. */
25
+ pending: string;
26
+ };
27
+ /** Cookie names derived from a `__Host-` prefix, e.g. `__Host-media` → `__Host-media-reader`. */
28
+ declare function readerSsoCookieNames(prefix: string): ReaderSsoCookieNames;
29
+ /** One Set-Cookie instruction. Every reader cookie is host-only, HttpOnly, Secure and Lax. */
30
+ type CookieInstruction = {
31
+ name: string;
32
+ value: string;
33
+ maxAge?: number;
34
+ expires?: Date;
35
+ };
36
+ declare const readerSsoCookieOptions: {
37
+ httpOnly: boolean;
38
+ secure: boolean;
39
+ sameSite: "lax";
40
+ path: string;
41
+ };
42
+ /** Apply instructions to a Next.js `cookies()` jar (or anything with the same `set`). */
43
+ declare function applyCookies(jar: {
44
+ set(name: string, value: string, options: typeof readerSsoCookieOptions & {
45
+ maxAge?: number;
46
+ expires?: Date;
47
+ }): unknown;
48
+ }, cookies: CookieInstruction[]): void;
49
+ /** The same instruction as a raw Set-Cookie header value. */
50
+ declare function setCookieHeader(cookie: CookieInstruction): string;
51
+ type CookieReader = (name: string) => string | undefined;
52
+ /** Read a cookie from a Cookie header. A name sent twice is treated as absent. */
53
+ declare function cookieReader(header: string | null | undefined): CookieReader;
54
+ type ReaderSsoFailure = "cancelled" | "provider_error" | "state" | "exchange" | "unverified" | "session" | "unavailable" | "link_invalid" | "disabled" | "mfa_required";
55
+ type ReaderSsoCheckOutcome = (typeof SILENT_NEGATIVE_ERRORS)[number] | "error" | "link_required" | "suppressed" | "switch_offered" | "switch_declined";
56
+ type ReaderSsoEvent = {
57
+ name: "reader_signin_started";
58
+ properties: {
59
+ method: ReaderSsoMethod;
60
+ mode: ReaderSsoMode;
61
+ transaction: string;
62
+ };
63
+ } | {
64
+ name: "reader_signin_completed";
65
+ properties: {
66
+ method: ReaderSsoMethod;
67
+ mode: ReaderSsoMode;
68
+ is_new: "true" | "false";
69
+ transaction?: string;
70
+ };
71
+ } | {
72
+ name: "reader_signin_failed";
73
+ properties: {
74
+ reason: ReaderSsoFailure;
75
+ mode: ReaderSsoMode;
76
+ transaction?: string;
77
+ };
78
+ } | {
79
+ name: "reader_sso_check";
80
+ properties: {
81
+ outcome: ReaderSsoCheckOutcome;
82
+ mode: ReaderSsoMode;
83
+ transaction?: string;
84
+ };
85
+ } | {
86
+ name: "reader_signed_out";
87
+ properties: {
88
+ method: "explicit";
89
+ };
90
+ } | {
91
+ name: "reader_account_linked";
92
+ properties: {
93
+ transaction?: string;
94
+ };
95
+ };
96
+
97
+ type ReaderSsoResponse = {
98
+ status: number;
99
+ body: unknown;
100
+ };
101
+ type ReaderSsoRequest = (path: string, init: {
102
+ method: "GET" | "POST";
103
+ body?: unknown;
104
+ token?: string;
105
+ }) => Promise<ReaderSsoResponse>;
106
+ type ReaderSsoConfig = {
107
+ /** `__Host-media` on most papers; `__Host-trivalley` on Tri-Valley Weekly. */
108
+ prefix: string;
109
+ /** HMAC key for sealed cookies. The site's API key is used today; never sent to the browser. */
110
+ key: string;
111
+ /** Canonical https origin of the publication, e.g. `https://sanramontimes.com`. */
112
+ origin: string;
113
+ /** Ledvery OIDC client id for this publication (env LEDVERY_CLIENT_ID, default `napsite-<slug>`). */
114
+ clientId: string;
115
+ request: ReaderSsoRequest;
116
+ record?: (event: ReaderSsoEvent) => void;
117
+ callbackPath?: string;
118
+ accountPath?: string;
119
+ issuerOrigin?: string;
120
+ /** Explicit email sign-in through Ledvery (env LEDVERY_EMAIL_SIGNIN); off by default. */
121
+ emailSignIn?: boolean;
122
+ /** Emergency off switch for all Ledvery sign-in. */
123
+ enabled?: boolean;
124
+ /** Validates a local return path per mode; returns "" when the path is not allowed. */
125
+ returnPath?: (next: string, mode: ReaderSsoMode) => string;
126
+ /** Where an interactive failure sends the reader; defaults to `/account?signin=retry[&next=]`. */
127
+ retryPath?: (flow: ReaderSsoFlow | null) => string;
128
+ now?: () => number;
129
+ random?: () => string;
130
+ };
131
+ /** Any same-site path: no protocol-relative URLs, control characters or API routes. */
132
+ declare function localReturnPath(value: unknown): string;
133
+ declare function stateDigest(state: string): string;
134
+ declare function validState(state: string | null | undefined, digest: string | undefined): boolean;
135
+ type ReaderSsoFlow = {
136
+ digest: string;
137
+ subscribe: boolean;
138
+ expires: number;
139
+ returnTo: string;
140
+ mode: ReaderSsoMode;
141
+ provider?: ReaderSsoProvider;
142
+ tx?: string;
143
+ };
144
+ declare function sealReaderFlow(input: {
145
+ state: string;
146
+ subscribe?: boolean;
147
+ returnTo?: string;
148
+ mode?: ReaderSsoMode;
149
+ provider?: ReaderSsoProvider;
150
+ tx?: string;
151
+ }, key: string, now?: number): string;
152
+ declare function openReaderFlow(cookie: string | undefined, key: string, now?: number, returnPath?: (next: string, mode: ReaderSsoMode) => string): ReaderSsoFlow | null;
153
+ /** A verified session the reader has not yet chosen over their current one. */
154
+ type PendingSession = {
155
+ token: string;
156
+ expires: number;
157
+ userId: string;
158
+ name: string;
159
+ mode: ReaderSsoMode;
160
+ method: ReaderSsoMethod;
161
+ returnTo: string;
162
+ subscribe: boolean;
163
+ tx?: string;
164
+ };
165
+ declare function sealPendingSession(pending: PendingSession, key: string, now?: number): string;
166
+ declare function openPendingSession(cookie: string | undefined, key: string, now?: number): PendingSession | null;
167
+ declare function authorizeUrl(value: string, state: string, callback: string, mode: ReaderSsoMode, issuerOrigin?: string): string;
168
+ type StartSignInInput = {
169
+ mode: ReaderSsoMode;
170
+ provider?: ReaderSsoProvider;
171
+ subscribe?: boolean;
172
+ next?: string;
173
+ cookies: CookieReader;
174
+ };
175
+ type StartSignInResult = {
176
+ ok: true;
177
+ url: string;
178
+ tx: string;
179
+ cookies: CookieInstruction[];
180
+ } | {
181
+ ok: false;
182
+ status: number;
183
+ error: string;
184
+ reason: "disabled" | "suppressed" | "session" | "unavailable" | "provider";
185
+ redirect: string;
186
+ cookies: CookieInstruction[];
187
+ };
188
+ declare function startSignIn(config: ReaderSsoConfig, input: StartSignInInput): Promise<StartSignInResult>;
189
+ type SessionUser = {
190
+ id: string;
191
+ email_verified: boolean;
192
+ full_name: string;
193
+ locale?: string;
194
+ time_zone?: string;
195
+ };
196
+ /** ADR 3.2: an active session for Bob is never replaced by Alice without an explicit choice. */
197
+ declare function precedence(current: SessionUser | null, incoming: SessionUser): "replace" | "renew" | "switch";
198
+ type CompleteSignInInput = {
199
+ url: string | URL;
200
+ cookies: CookieReader;
201
+ };
202
+ type CompleteSignInResult = {
203
+ kind: "redirect";
204
+ location: string;
205
+ cookies: CookieInstruction[];
206
+ outcome: ReaderSsoCheckOutcome | ReaderSsoFailure;
207
+ flow: ReaderSsoFlow | null;
208
+ } | {
209
+ kind: "signed-in";
210
+ location: string;
211
+ cookies: CookieInstruction[];
212
+ token: string;
213
+ expiresAt: Date;
214
+ user: SessionUser;
215
+ flow: ReaderSsoFlow;
216
+ isNew: boolean;
217
+ };
218
+ /**
219
+ * Finish a transaction that Ledvery returned to the callback. Produces cookies and
220
+ * a destination; the caller subscribes to the newsletter (interactive consent only)
221
+ * and performs the redirect with private, no-store headers.
222
+ */
223
+ declare function completeSignIn(config: ReaderSsoConfig, input: CompleteSignInInput): Promise<CompleteSignInResult>;
224
+ type LinkAccountInput = {
225
+ challenge_id: unknown;
226
+ password: unknown;
227
+ mfa_code?: unknown;
228
+ cookies: CookieReader;
229
+ next?: string;
230
+ subscribe?: boolean;
231
+ };
232
+ type LinkAccountResult = {
233
+ ok: true;
234
+ switch: false;
235
+ cookies: CookieInstruction[];
236
+ token: string;
237
+ expiresAt: Date;
238
+ user: SessionUser;
239
+ location: string;
240
+ } | {
241
+ ok: true;
242
+ switch: true;
243
+ cookies: CookieInstruction[];
244
+ location: string;
245
+ } | {
246
+ ok: false;
247
+ status: number;
248
+ error: string;
249
+ cookies: CookieInstruction[];
250
+ mfaRequired?: boolean;
251
+ };
252
+ /** Platform answers to an ownership proof that are not a plain "wrong details". */
253
+ declare function linkFailureMessage(code: string): {
254
+ error: string;
255
+ mfaRequired?: boolean;
256
+ } | null;
257
+ declare function linkAccount(config: ReaderSsoConfig, input: LinkAccountInput): Promise<LinkAccountResult>;
258
+ type SwitchAccountResult = {
259
+ ok: true;
260
+ choice: "continue";
261
+ cookies: CookieInstruction[];
262
+ token: string;
263
+ location: string;
264
+ subscribe: boolean;
265
+ } | {
266
+ ok: true;
267
+ choice: "stay";
268
+ cookies: CookieInstruction[];
269
+ location: string;
270
+ } | {
271
+ ok: false;
272
+ status: number;
273
+ error: string;
274
+ cookies: CookieInstruction[];
275
+ };
276
+ /** Names shown on the switch prompt. Nothing here is ever an email address. */
277
+ declare function pendingSwitch(config: ReaderSsoConfig, cookies: CookieReader): Promise<{
278
+ current: string;
279
+ pending: string;
280
+ } | null>;
281
+ declare function switchAccount(config: ReaderSsoConfig, input: {
282
+ choice: unknown;
283
+ cookies: CookieReader;
284
+ }): Promise<SwitchAccountResult>;
285
+ type SignOutResult = {
286
+ cookies: CookieInstruction[];
287
+ endSessionUrl: string;
288
+ state: string;
289
+ };
290
+ declare function signOut(config: ReaderSsoConfig, input: {
291
+ cookies: CookieReader;
292
+ extraCookies?: CookieInstruction[];
293
+ }): Promise<SignOutResult>;
294
+ type SessionSummary = {
295
+ authenticated: false;
296
+ } | {
297
+ authenticated: true;
298
+ full_name: string;
299
+ locale?: string;
300
+ time_zone?: string;
301
+ };
302
+ declare function sessionSummary(config: ReaderSsoConfig, cookies: CookieReader): Promise<SessionSummary>;
303
+ /**
304
+ * Session summary plus the cookies to clear when a present session cookie no
305
+ * longer validates (revoked elsewhere). The site's session route applies them
306
+ * so a stale cookie stops suppressing sign-in (release review R5).
307
+ */
308
+ declare function sessionSummaryWithCookies(config: ReaderSsoConfig, cookies: CookieReader): Promise<{
309
+ summary: SessionSummary;
310
+ cookies: CookieInstruction[];
311
+ }>;
312
+ /** Flags the layout passes to `ReaderSsoBoot`; the cookies themselves are HttpOnly. */
313
+ declare function readerSsoBootFlags(cookies: CookieReader, names: ReaderSsoCookieNames): {
314
+ hasSession: boolean;
315
+ suppressed: boolean;
316
+ };
317
+
318
+ export { type CompleteSignInInput, type CompleteSignInResult, type CookieInstruction, type CookieReader, LEDVERY_ISSUER_ORIGIN, type LinkAccountInput, type LinkAccountResult, type PendingSession, READER_SSO_FLOW_SECONDS, READER_SSO_NEGATIVE_CACHE_SECONDS, READER_SSO_PENDING_SECONDS, READER_SSO_SIGNED_OUT_SECONDS, type ReaderSsoCheckOutcome, type ReaderSsoConfig, type ReaderSsoCookieNames, type ReaderSsoEvent, type ReaderSsoFailure, type ReaderSsoFlow, type ReaderSsoMethod, type ReaderSsoMode, type ReaderSsoProvider, type ReaderSsoRequest, type ReaderSsoResponse, SILENT_NEGATIVE_ERRORS, type SessionSummary, type SessionUser, type SignOutResult, type StartSignInInput, type StartSignInResult, type SwitchAccountResult, applyCookies, authorizeUrl, completeSignIn, cookieReader, linkAccount, linkFailureMessage, localReturnPath, openPendingSession, openReaderFlow, pendingSwitch, precedence, readerSsoBootFlags, readerSsoCookieNames, readerSsoCookieOptions, sealPendingSession, sealReaderFlow, sessionSummary, sessionSummaryWithCookies, setCookieHeader, signOut, startSignIn, stateDigest, switchAccount, validState };
@@ -0,0 +1,318 @@
1
+ export { R as READER_SSO_EVENTS, a as READER_SSO_PROPERTY_KEYS, b as ReaderSsoEventDefinition, c as ReaderSsoEventName } from './reader-sso-events-DBw8pGSM.js';
2
+
3
+ type ReaderSsoMode = "interactive" | "silent";
4
+ type ReaderSsoProvider = "google" | "email";
5
+ type ReaderSsoMethod = ReaderSsoProvider | "link" | "switch" | "unknown";
6
+ declare const READER_SSO_FLOW_SECONDS = 600;
7
+ declare const READER_SSO_NEGATIVE_CACHE_SECONDS = 300;
8
+ declare const READER_SSO_SIGNED_OUT_SECONDS = 86400;
9
+ declare const READER_SSO_PENDING_SECONDS = 600;
10
+ declare const LEDVERY_ISSUER_ORIGIN = "https://api.ledvery.com";
11
+ /** Ledvery results that mean "no silent session here"; never authentication failures. */
12
+ declare const SILENT_NEGATIVE_ERRORS: readonly ["login_required", "consent_required", "interaction_required", "account_selection_required"];
13
+ type ReaderSsoCookieNames = {
14
+ /** The reader's platform session token. */
15
+ session: string;
16
+ /** Sealed sign-in transaction (10 minutes). */
17
+ flow: string;
18
+ /** Newsletter consent carried through email verification. */
19
+ newsletter: string;
20
+ /** Negative cache: a silent check ran recently and found nothing. */
21
+ ssoChecked: string;
22
+ /** Explicit sign-out: silent sign-in stays off until an explicit sign-in. */
23
+ signedOut: string;
24
+ /** A verified session waiting for the reader to choose between two accounts. */
25
+ pending: string;
26
+ };
27
+ /** Cookie names derived from a `__Host-` prefix, e.g. `__Host-media` → `__Host-media-reader`. */
28
+ declare function readerSsoCookieNames(prefix: string): ReaderSsoCookieNames;
29
+ /** One Set-Cookie instruction. Every reader cookie is host-only, HttpOnly, Secure and Lax. */
30
+ type CookieInstruction = {
31
+ name: string;
32
+ value: string;
33
+ maxAge?: number;
34
+ expires?: Date;
35
+ };
36
+ declare const readerSsoCookieOptions: {
37
+ httpOnly: boolean;
38
+ secure: boolean;
39
+ sameSite: "lax";
40
+ path: string;
41
+ };
42
+ /** Apply instructions to a Next.js `cookies()` jar (or anything with the same `set`). */
43
+ declare function applyCookies(jar: {
44
+ set(name: string, value: string, options: typeof readerSsoCookieOptions & {
45
+ maxAge?: number;
46
+ expires?: Date;
47
+ }): unknown;
48
+ }, cookies: CookieInstruction[]): void;
49
+ /** The same instruction as a raw Set-Cookie header value. */
50
+ declare function setCookieHeader(cookie: CookieInstruction): string;
51
+ type CookieReader = (name: string) => string | undefined;
52
+ /** Read a cookie from a Cookie header. A name sent twice is treated as absent. */
53
+ declare function cookieReader(header: string | null | undefined): CookieReader;
54
+ type ReaderSsoFailure = "cancelled" | "provider_error" | "state" | "exchange" | "unverified" | "session" | "unavailable" | "link_invalid" | "disabled" | "mfa_required";
55
+ type ReaderSsoCheckOutcome = (typeof SILENT_NEGATIVE_ERRORS)[number] | "error" | "link_required" | "suppressed" | "switch_offered" | "switch_declined";
56
+ type ReaderSsoEvent = {
57
+ name: "reader_signin_started";
58
+ properties: {
59
+ method: ReaderSsoMethod;
60
+ mode: ReaderSsoMode;
61
+ transaction: string;
62
+ };
63
+ } | {
64
+ name: "reader_signin_completed";
65
+ properties: {
66
+ method: ReaderSsoMethod;
67
+ mode: ReaderSsoMode;
68
+ is_new: "true" | "false";
69
+ transaction?: string;
70
+ };
71
+ } | {
72
+ name: "reader_signin_failed";
73
+ properties: {
74
+ reason: ReaderSsoFailure;
75
+ mode: ReaderSsoMode;
76
+ transaction?: string;
77
+ };
78
+ } | {
79
+ name: "reader_sso_check";
80
+ properties: {
81
+ outcome: ReaderSsoCheckOutcome;
82
+ mode: ReaderSsoMode;
83
+ transaction?: string;
84
+ };
85
+ } | {
86
+ name: "reader_signed_out";
87
+ properties: {
88
+ method: "explicit";
89
+ };
90
+ } | {
91
+ name: "reader_account_linked";
92
+ properties: {
93
+ transaction?: string;
94
+ };
95
+ };
96
+
97
+ type ReaderSsoResponse = {
98
+ status: number;
99
+ body: unknown;
100
+ };
101
+ type ReaderSsoRequest = (path: string, init: {
102
+ method: "GET" | "POST";
103
+ body?: unknown;
104
+ token?: string;
105
+ }) => Promise<ReaderSsoResponse>;
106
+ type ReaderSsoConfig = {
107
+ /** `__Host-media` on most papers; `__Host-trivalley` on Tri-Valley Weekly. */
108
+ prefix: string;
109
+ /** HMAC key for sealed cookies. The site's API key is used today; never sent to the browser. */
110
+ key: string;
111
+ /** Canonical https origin of the publication, e.g. `https://sanramontimes.com`. */
112
+ origin: string;
113
+ /** Ledvery OIDC client id for this publication (env LEDVERY_CLIENT_ID, default `napsite-<slug>`). */
114
+ clientId: string;
115
+ request: ReaderSsoRequest;
116
+ record?: (event: ReaderSsoEvent) => void;
117
+ callbackPath?: string;
118
+ accountPath?: string;
119
+ issuerOrigin?: string;
120
+ /** Explicit email sign-in through Ledvery (env LEDVERY_EMAIL_SIGNIN); off by default. */
121
+ emailSignIn?: boolean;
122
+ /** Emergency off switch for all Ledvery sign-in. */
123
+ enabled?: boolean;
124
+ /** Validates a local return path per mode; returns "" when the path is not allowed. */
125
+ returnPath?: (next: string, mode: ReaderSsoMode) => string;
126
+ /** Where an interactive failure sends the reader; defaults to `/account?signin=retry[&next=]`. */
127
+ retryPath?: (flow: ReaderSsoFlow | null) => string;
128
+ now?: () => number;
129
+ random?: () => string;
130
+ };
131
+ /** Any same-site path: no protocol-relative URLs, control characters or API routes. */
132
+ declare function localReturnPath(value: unknown): string;
133
+ declare function stateDigest(state: string): string;
134
+ declare function validState(state: string | null | undefined, digest: string | undefined): boolean;
135
+ type ReaderSsoFlow = {
136
+ digest: string;
137
+ subscribe: boolean;
138
+ expires: number;
139
+ returnTo: string;
140
+ mode: ReaderSsoMode;
141
+ provider?: ReaderSsoProvider;
142
+ tx?: string;
143
+ };
144
+ declare function sealReaderFlow(input: {
145
+ state: string;
146
+ subscribe?: boolean;
147
+ returnTo?: string;
148
+ mode?: ReaderSsoMode;
149
+ provider?: ReaderSsoProvider;
150
+ tx?: string;
151
+ }, key: string, now?: number): string;
152
+ declare function openReaderFlow(cookie: string | undefined, key: string, now?: number, returnPath?: (next: string, mode: ReaderSsoMode) => string): ReaderSsoFlow | null;
153
+ /** A verified session the reader has not yet chosen over their current one. */
154
+ type PendingSession = {
155
+ token: string;
156
+ expires: number;
157
+ userId: string;
158
+ name: string;
159
+ mode: ReaderSsoMode;
160
+ method: ReaderSsoMethod;
161
+ returnTo: string;
162
+ subscribe: boolean;
163
+ tx?: string;
164
+ };
165
+ declare function sealPendingSession(pending: PendingSession, key: string, now?: number): string;
166
+ declare function openPendingSession(cookie: string | undefined, key: string, now?: number): PendingSession | null;
167
+ declare function authorizeUrl(value: string, state: string, callback: string, mode: ReaderSsoMode, issuerOrigin?: string): string;
168
+ type StartSignInInput = {
169
+ mode: ReaderSsoMode;
170
+ provider?: ReaderSsoProvider;
171
+ subscribe?: boolean;
172
+ next?: string;
173
+ cookies: CookieReader;
174
+ };
175
+ type StartSignInResult = {
176
+ ok: true;
177
+ url: string;
178
+ tx: string;
179
+ cookies: CookieInstruction[];
180
+ } | {
181
+ ok: false;
182
+ status: number;
183
+ error: string;
184
+ reason: "disabled" | "suppressed" | "session" | "unavailable" | "provider";
185
+ redirect: string;
186
+ cookies: CookieInstruction[];
187
+ };
188
+ declare function startSignIn(config: ReaderSsoConfig, input: StartSignInInput): Promise<StartSignInResult>;
189
+ type SessionUser = {
190
+ id: string;
191
+ email_verified: boolean;
192
+ full_name: string;
193
+ locale?: string;
194
+ time_zone?: string;
195
+ };
196
+ /** ADR 3.2: an active session for Bob is never replaced by Alice without an explicit choice. */
197
+ declare function precedence(current: SessionUser | null, incoming: SessionUser): "replace" | "renew" | "switch";
198
+ type CompleteSignInInput = {
199
+ url: string | URL;
200
+ cookies: CookieReader;
201
+ };
202
+ type CompleteSignInResult = {
203
+ kind: "redirect";
204
+ location: string;
205
+ cookies: CookieInstruction[];
206
+ outcome: ReaderSsoCheckOutcome | ReaderSsoFailure;
207
+ flow: ReaderSsoFlow | null;
208
+ } | {
209
+ kind: "signed-in";
210
+ location: string;
211
+ cookies: CookieInstruction[];
212
+ token: string;
213
+ expiresAt: Date;
214
+ user: SessionUser;
215
+ flow: ReaderSsoFlow;
216
+ isNew: boolean;
217
+ };
218
+ /**
219
+ * Finish a transaction that Ledvery returned to the callback. Produces cookies and
220
+ * a destination; the caller subscribes to the newsletter (interactive consent only)
221
+ * and performs the redirect with private, no-store headers.
222
+ */
223
+ declare function completeSignIn(config: ReaderSsoConfig, input: CompleteSignInInput): Promise<CompleteSignInResult>;
224
+ type LinkAccountInput = {
225
+ challenge_id: unknown;
226
+ password: unknown;
227
+ mfa_code?: unknown;
228
+ cookies: CookieReader;
229
+ next?: string;
230
+ subscribe?: boolean;
231
+ };
232
+ type LinkAccountResult = {
233
+ ok: true;
234
+ switch: false;
235
+ cookies: CookieInstruction[];
236
+ token: string;
237
+ expiresAt: Date;
238
+ user: SessionUser;
239
+ location: string;
240
+ } | {
241
+ ok: true;
242
+ switch: true;
243
+ cookies: CookieInstruction[];
244
+ location: string;
245
+ } | {
246
+ ok: false;
247
+ status: number;
248
+ error: string;
249
+ cookies: CookieInstruction[];
250
+ mfaRequired?: boolean;
251
+ };
252
+ /** Platform answers to an ownership proof that are not a plain "wrong details". */
253
+ declare function linkFailureMessage(code: string): {
254
+ error: string;
255
+ mfaRequired?: boolean;
256
+ } | null;
257
+ declare function linkAccount(config: ReaderSsoConfig, input: LinkAccountInput): Promise<LinkAccountResult>;
258
+ type SwitchAccountResult = {
259
+ ok: true;
260
+ choice: "continue";
261
+ cookies: CookieInstruction[];
262
+ token: string;
263
+ location: string;
264
+ subscribe: boolean;
265
+ } | {
266
+ ok: true;
267
+ choice: "stay";
268
+ cookies: CookieInstruction[];
269
+ location: string;
270
+ } | {
271
+ ok: false;
272
+ status: number;
273
+ error: string;
274
+ cookies: CookieInstruction[];
275
+ };
276
+ /** Names shown on the switch prompt. Nothing here is ever an email address. */
277
+ declare function pendingSwitch(config: ReaderSsoConfig, cookies: CookieReader): Promise<{
278
+ current: string;
279
+ pending: string;
280
+ } | null>;
281
+ declare function switchAccount(config: ReaderSsoConfig, input: {
282
+ choice: unknown;
283
+ cookies: CookieReader;
284
+ }): Promise<SwitchAccountResult>;
285
+ type SignOutResult = {
286
+ cookies: CookieInstruction[];
287
+ endSessionUrl: string;
288
+ state: string;
289
+ };
290
+ declare function signOut(config: ReaderSsoConfig, input: {
291
+ cookies: CookieReader;
292
+ extraCookies?: CookieInstruction[];
293
+ }): Promise<SignOutResult>;
294
+ type SessionSummary = {
295
+ authenticated: false;
296
+ } | {
297
+ authenticated: true;
298
+ full_name: string;
299
+ locale?: string;
300
+ time_zone?: string;
301
+ };
302
+ declare function sessionSummary(config: ReaderSsoConfig, cookies: CookieReader): Promise<SessionSummary>;
303
+ /**
304
+ * Session summary plus the cookies to clear when a present session cookie no
305
+ * longer validates (revoked elsewhere). The site's session route applies them
306
+ * so a stale cookie stops suppressing sign-in (release review R5).
307
+ */
308
+ declare function sessionSummaryWithCookies(config: ReaderSsoConfig, cookies: CookieReader): Promise<{
309
+ summary: SessionSummary;
310
+ cookies: CookieInstruction[];
311
+ }>;
312
+ /** Flags the layout passes to `ReaderSsoBoot`; the cookies themselves are HttpOnly. */
313
+ declare function readerSsoBootFlags(cookies: CookieReader, names: ReaderSsoCookieNames): {
314
+ hasSession: boolean;
315
+ suppressed: boolean;
316
+ };
317
+
318
+ export { type CompleteSignInInput, type CompleteSignInResult, type CookieInstruction, type CookieReader, LEDVERY_ISSUER_ORIGIN, type LinkAccountInput, type LinkAccountResult, type PendingSession, READER_SSO_FLOW_SECONDS, READER_SSO_NEGATIVE_CACHE_SECONDS, READER_SSO_PENDING_SECONDS, READER_SSO_SIGNED_OUT_SECONDS, type ReaderSsoCheckOutcome, type ReaderSsoConfig, type ReaderSsoCookieNames, type ReaderSsoEvent, type ReaderSsoFailure, type ReaderSsoFlow, type ReaderSsoMethod, type ReaderSsoMode, type ReaderSsoProvider, type ReaderSsoRequest, type ReaderSsoResponse, SILENT_NEGATIVE_ERRORS, type SessionSummary, type SessionUser, type SignOutResult, type StartSignInInput, type StartSignInResult, type SwitchAccountResult, applyCookies, authorizeUrl, completeSignIn, cookieReader, linkAccount, linkFailureMessage, localReturnPath, openPendingSession, openReaderFlow, pendingSwitch, precedence, readerSsoBootFlags, readerSsoCookieNames, readerSsoCookieOptions, sealPendingSession, sealReaderFlow, sessionSummary, sessionSummaryWithCookies, setCookieHeader, signOut, startSignIn, stateDigest, switchAccount, validState };