@alxia/react-router 0.12.1 → 0.14.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +79 -1
- package/dist/chunks/index-0tyw54ad.js +160 -0
- package/dist/chunks/index-0tyw54ad.js.map +15 -0
- package/dist/chunks/index-c3k47yw7.js +124 -0
- package/dist/chunks/index-c3k47yw7.js.map +14 -0
- package/dist/errors/api-error.d.ts +18 -0
- package/dist/errors/api-error.d.ts.map +1 -1
- package/dist/errors/api-errors.d.ts +16 -0
- package/dist/errors/api-errors.d.ts.map +1 -1
- package/dist/errors/describe.d.ts +1 -1
- package/dist/errors/describe.d.ts.map +1 -1
- package/dist/errors/index.d.ts +1 -1
- package/dist/errors/index.d.ts.map +1 -1
- package/dist/errors/index.js +51 -113
- package/dist/errors/index.js.map +6 -10
- package/dist/errors/json-actions.d.ts.map +1 -1
- package/dist/errors/same-site.d.ts +25 -0
- package/dist/errors/same-site.d.ts.map +1 -0
- package/dist/session/codes.d.ts +7 -0
- package/dist/session/codes.d.ts.map +1 -0
- package/dist/session/cookies.d.ts +60 -0
- package/dist/session/cookies.d.ts.map +1 -0
- package/dist/session/flow-types.d.ts +178 -0
- package/dist/session/flow-types.d.ts.map +1 -0
- package/dist/session/guard.d.ts +10 -0
- package/dist/session/guard.d.ts.map +1 -0
- package/dist/session/index.d.ts +18 -0
- package/dist/session/index.d.ts.map +1 -0
- package/dist/session/index.js +637 -0
- package/dist/session/index.js.map +23 -0
- package/dist/session/land.d.ts +26 -0
- package/dist/session/land.d.ts.map +1 -0
- package/dist/session/link-land.d.ts +18 -0
- package/dist/session/link-land.d.ts.map +1 -0
- package/dist/session/link-token.d.ts +22 -0
- package/dist/session/link-token.d.ts.map +1 -0
- package/dist/session/link-types.d.ts +124 -0
- package/dist/session/link-types.d.ts.map +1 -0
- package/dist/session/links.d.ts +14 -0
- package/dist/session/links.d.ts.map +1 -0
- package/dist/session/model/index.d.ts +7 -0
- package/dist/session/model/index.d.ts.map +1 -0
- package/dist/session/model/index.js +25 -0
- package/dist/session/model/index.js.map +9 -0
- package/dist/session/model/paths.d.ts +24 -0
- package/dist/session/model/paths.d.ts.map +1 -0
- package/dist/session/model/safe-next.d.ts +15 -0
- package/dist/session/model/safe-next.d.ts.map +1 -0
- package/dist/session/model/second-factor.d.ts +16 -0
- package/dist/session/model/second-factor.d.ts.map +1 -0
- package/dist/session/model/site-path.d.ts +10 -0
- package/dist/session/model/site-path.d.ts.map +1 -0
- package/dist/session/model/step-up-answers.d.ts +40 -0
- package/dist/session/model/step-up-answers.d.ts.map +1 -0
- package/dist/session/model/step-up-props.d.ts +21 -0
- package/dist/session/model/step-up-props.d.ts.map +1 -0
- package/dist/session/model/step-up.d.ts +48 -0
- package/dist/session/model/step-up.d.ts.map +1 -0
- package/dist/session/second-factor.d.ts +22 -0
- package/dist/session/second-factor.d.ts.map +1 -0
- package/dist/session/serialize.d.ts +34 -0
- package/dist/session/serialize.d.ts.map +1 -0
- package/dist/session/sign-in.d.ts +17 -0
- package/dist/session/sign-in.d.ts.map +1 -0
- package/dist/session/step-up-codes.d.ts +9 -0
- package/dist/session/step-up-codes.d.ts.map +1 -0
- package/dist/session/step-up-types.d.ts +69 -0
- package/dist/session/step-up-types.d.ts.map +1 -0
- package/dist/session/step-up.d.ts +17 -0
- package/dist/session/step-up.d.ts.map +1 -0
- package/dist/session/step.d.ts +20 -0
- package/dist/session/step.d.ts.map +1 -0
- package/dist/session/viewer.d.ts +33 -0
- package/dist/session/viewer.d.ts.map +1 -0
- package/docs/README.md +1 -0
- package/docs/guide/errors.md +45 -0
- package/docs/guide/session.md +955 -0
- package/docs/roadmap.md +27 -0
- package/docs/troubleshooting.md +362 -1
- package/package.json +15 -2
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
export interface SessionCookiesOptions {
|
|
2
|
+
/**
|
|
3
|
+
* The base name of the session cookie, e.g. `'my-app_session'`. With
|
|
4
|
+
* `secure`, the cookie is named `__Host-my-app_session`.
|
|
5
|
+
*/
|
|
6
|
+
readonly session: string;
|
|
7
|
+
/**
|
|
8
|
+
* The base name of the second-factor challenge's cookie. With `secure`, it
|
|
9
|
+
* is named `__Secure-<name>`.
|
|
10
|
+
*/
|
|
11
|
+
readonly challenge: string;
|
|
12
|
+
/**
|
|
13
|
+
* The app is served over HTTPS. Required, and never read from the
|
|
14
|
+
* environment: pass `!import.meta.env.DEV`. `false` drops `Secure` and the
|
|
15
|
+
* prefixes (Safari drops a `Secure` cookie over `http://localhost`).
|
|
16
|
+
*/
|
|
17
|
+
readonly secure: boolean;
|
|
18
|
+
/** Where the browser sends the challenge. `'/sign-in'` by default. */
|
|
19
|
+
readonly challengePath?: string | undefined;
|
|
20
|
+
/** The most the challenge lives. 300, `@nxgt/janus`'s lifetime, by default. */
|
|
21
|
+
readonly challengeSeconds?: number | undefined;
|
|
22
|
+
}
|
|
23
|
+
/** What the session cookie holds: the token, and the expiry (ms) it was last set to. */
|
|
24
|
+
export interface CookieSession {
|
|
25
|
+
readonly token: string;
|
|
26
|
+
readonly expiresAt: number;
|
|
27
|
+
}
|
|
28
|
+
export interface SessionCookies {
|
|
29
|
+
/** The names as sent, prefixes included. */
|
|
30
|
+
readonly names: {
|
|
31
|
+
readonly session: string;
|
|
32
|
+
readonly challenge: string;
|
|
33
|
+
};
|
|
34
|
+
/** The session cookie of the request; `null` when absent or not `<ms>.<token>`. */
|
|
35
|
+
read(request: Request): CookieSession | null;
|
|
36
|
+
/** The session token of the request, or `null`. */
|
|
37
|
+
token(request: Request): string | null;
|
|
38
|
+
/** A `Set-Cookie` value keeping `token` until `expiresAt`. */
|
|
39
|
+
commit(token: string, expiresAt: string | Date, now?: number): string;
|
|
40
|
+
/** A `Set-Cookie` value removing the session cookie. */
|
|
41
|
+
destroy(): string;
|
|
42
|
+
/** The `Set-Cookie` header that keeps the cookie as long as the session lives; empty when the expiry did not move, or is absent or not a date. */
|
|
43
|
+
refreshed(session: CookieSession, expiresAt: string | Date | null): HeadersInit;
|
|
44
|
+
/** The challenge cookie of the request, or `null`. */
|
|
45
|
+
challengeOf(request: Request): string | null;
|
|
46
|
+
/** A `Set-Cookie` value keeping the challenge for the code page. */
|
|
47
|
+
commitChallenge(challenge: string, expiresAt?: string | Date | null, now?: number): string;
|
|
48
|
+
/** A `Set-Cookie` value removing the challenge. */
|
|
49
|
+
destroyChallenge(): string;
|
|
50
|
+
/**
|
|
51
|
+
* What a signed-out visit of the sign-in page sets: the challenge cleared
|
|
52
|
+
* blind (a client navigation fetches `/sign-in.data`, which the cookie's
|
|
53
|
+
* path does not match, so the request never shows it), and a dead
|
|
54
|
+
* session's cookie when `deadSession`.
|
|
55
|
+
*/
|
|
56
|
+
signInPageHeaders(deadSession: boolean): Headers;
|
|
57
|
+
}
|
|
58
|
+
/** The cookies of a BFF's session and of its second-factor challenge. */
|
|
59
|
+
export declare function sessionCookies(options: SessionCookiesOptions): SessionCookies;
|
|
60
|
+
//# sourceMappingURL=cookies.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"cookies.d.ts","sourceRoot":"","sources":["../../src/session/cookies.ts"],"names":[],"mappings":"AASA,MAAM,WAAW,qBAAqB;IACrC;;;OAGG;IACH,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;IACzB;;;OAGG;IACH,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAC;IAC3B;;;;OAIG;IACH,QAAQ,CAAC,MAAM,EAAE,OAAO,CAAC;IACzB,sEAAsE;IACtE,QAAQ,CAAC,aAAa,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;IAC5C,+EAA+E;IAC/E,QAAQ,CAAC,gBAAgB,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;CAC/C;AAED,wFAAwF;AACxF,MAAM,WAAW,aAAa;IAC7B,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;IACvB,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAC;CAC3B;AAED,MAAM,WAAW,cAAc;IAC9B,4CAA4C;IAC5C,QAAQ,CAAC,KAAK,EAAE;QAAE,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;QAAC,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAA;KAAE,CAAC;IACzE,mFAAmF;IACnF,IAAI,CAAC,OAAO,EAAE,OAAO,GAAG,aAAa,GAAG,IAAI,CAAC;IAC7C,mDAAmD;IACnD,KAAK,CAAC,OAAO,EAAE,OAAO,GAAG,MAAM,GAAG,IAAI,CAAC;IACvC,8DAA8D;IAC9D,MAAM,CAAC,KAAK,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,GAAG,IAAI,EAAE,GAAG,CAAC,EAAE,MAAM,GAAG,MAAM,CAAC;IACtE,wDAAwD;IACxD,OAAO,IAAI,MAAM,CAAC;IAClB,kJAAkJ;IAClJ,SAAS,CACR,OAAO,EAAE,aAAa,EACtB,SAAS,EAAE,MAAM,GAAG,IAAI,GAAG,IAAI,GAC7B,WAAW,CAAC;IACf,sDAAsD;IACtD,WAAW,CAAC,OAAO,EAAE,OAAO,GAAG,MAAM,GAAG,IAAI,CAAC;IAC7C,oEAAoE;IACpE,eAAe,CACd,SAAS,EAAE,MAAM,EACjB,SAAS,CAAC,EAAE,MAAM,GAAG,IAAI,GAAG,IAAI,EAChC,GAAG,CAAC,EAAE,MAAM,GACV,MAAM,CAAC;IACV,mDAAmD;IACnD,gBAAgB,IAAI,MAAM,CAAC;IAC3B;;;;;OAKG;IACH,iBAAiB,CAAC,WAAW,EAAE,OAAO,GAAG,OAAO,CAAC;CACjD;AAiBD,yEAAyE;AACzE,wBAAgB,cAAc,CAAC,OAAO,EAAE,qBAAqB,GAAG,cAAc,CA6E7E"}
|
|
@@ -0,0 +1,178 @@
|
|
|
1
|
+
import type { data } from 'react-router';
|
|
2
|
+
import type { ApiErrorLike } from '../errors/api-error';
|
|
3
|
+
import type { ApiErrors } from '../errors/api-errors';
|
|
4
|
+
import type { JsonActions } from '../errors/json-actions';
|
|
5
|
+
import type { SessionCookies } from './cookies';
|
|
6
|
+
import type { SecondFactorKind, SignInPaths, SignInStatus } from './model';
|
|
7
|
+
/**
|
|
8
|
+
* What a sign-in step answers, in `@nxgt/janus`'s words. An app maps its
|
|
9
|
+
* API's enums to it, once: `SIGNED_IN` to `signedIn`, `SECOND_FACTOR` to
|
|
10
|
+
* `secondFactor`, and anything else (such as a `LINKED`) to `other`.
|
|
11
|
+
*/
|
|
12
|
+
export type SignInAnswer = {
|
|
13
|
+
readonly status: 'signedIn';
|
|
14
|
+
readonly token: string;
|
|
15
|
+
readonly expiresAt: string | Date;
|
|
16
|
+
} | {
|
|
17
|
+
readonly status: 'secondFactor';
|
|
18
|
+
/** A secret: it goes in the challenge cookie, never in a URL. */
|
|
19
|
+
readonly challenge: string;
|
|
20
|
+
readonly expiresAt?: string | Date | null | undefined;
|
|
21
|
+
} | {
|
|
22
|
+
readonly status: 'other';
|
|
23
|
+
};
|
|
24
|
+
/** What a sign-in form's action answers when it stays on the page. */
|
|
25
|
+
export type SignInFormError<T = object> = T & {
|
|
26
|
+
formError: string;
|
|
27
|
+
};
|
|
28
|
+
/** The codes the flow tells apart; `@nxgt/janus`'s by default. */
|
|
29
|
+
export interface SignInCodes {
|
|
30
|
+
/** A wrong code that may leave tries (`'CODE_INVALID'`). */
|
|
31
|
+
readonly invalidCode?: string | undefined;
|
|
32
|
+
/** The codes that end the challenge (`TOKEN_UNKNOWN`, `TOKEN_SPENT`, `TOKEN_EXPIRED`). */
|
|
33
|
+
readonly challengeOver?: readonly string[] | undefined;
|
|
34
|
+
}
|
|
35
|
+
export interface SignInFlowOptions<L extends string> {
|
|
36
|
+
readonly cookies: SessionCookies;
|
|
37
|
+
/** The app's `createApiErrors` instance. */
|
|
38
|
+
readonly errors: ApiErrors<L>;
|
|
39
|
+
/** The app's `jsonActions({ origin })`, so a body is read with the same CSRF check. */
|
|
40
|
+
readonly json: JsonActions;
|
|
41
|
+
/** Ends a session at the API (the app's sign-out mutation); a failure is ignored. */
|
|
42
|
+
revoke(token: string, request: Request): Promise<unknown>;
|
|
43
|
+
/** A refused code's tries left, worded ("3 tries left"). */
|
|
44
|
+
attemptsLeft(count: number, language: L): string;
|
|
45
|
+
/** The sign-in pages' paths; `SIGN_IN_PATHS` by default. */
|
|
46
|
+
readonly paths?: Partial<SignInPaths> | undefined;
|
|
47
|
+
/**
|
|
48
|
+
* `Set-Cookie` values a new session and a sign-out also clear, such as an
|
|
49
|
+
* app's per-account preferences.
|
|
50
|
+
*/
|
|
51
|
+
readonly clear?: (() => readonly string[]) | undefined;
|
|
52
|
+
/** What a sign-in says when the API cannot be reached; `errors.unavailableMessage` by default. */
|
|
53
|
+
readonly unavailable?: ((language: L) => string) | undefined;
|
|
54
|
+
readonly codes?: SignInCodes | undefined;
|
|
55
|
+
/**
|
|
56
|
+
* The query key a sign-in redirect adds (as `?expired=1`) when the request
|
|
57
|
+
* carried a session cookie, to say the session ended. Off by default.
|
|
58
|
+
*/
|
|
59
|
+
readonly endedParam?: string | undefined;
|
|
60
|
+
}
|
|
61
|
+
/** A form step's answer when it stays on the page: the form's message, with a status. */
|
|
62
|
+
export type SignInStayed<T extends object> = ReturnType<typeof data<SignInFormError<T>>>;
|
|
63
|
+
export interface SignInFlow<L extends string> {
|
|
64
|
+
/** The cookies the flow was built with. */
|
|
65
|
+
readonly cookies: SessionCookies;
|
|
66
|
+
/** The `createApiErrors` instance the flow was built with. */
|
|
67
|
+
readonly errors: ApiErrors<L>;
|
|
68
|
+
/** The `jsonActions` instance the flow was built with. */
|
|
69
|
+
readonly json: JsonActions;
|
|
70
|
+
/** A refused code's tries left, worded (the `attemptsLeft` option). */
|
|
71
|
+
attemptsLeft(count: number, language: L): string;
|
|
72
|
+
/**
|
|
73
|
+
* The guard every step of the flow that signs in, out, spends or mails
|
|
74
|
+
* runs first, for an app's own step (a passkey's): a native form post is
|
|
75
|
+
* redirected back to its page, and a JSON post from another site is a 403
|
|
76
|
+
* (`Origin` and `Sec-Fetch-Site`, as `readJson` reads them). It reads
|
|
77
|
+
* headers only. Call it in a POST action, never in a GET callback, which
|
|
78
|
+
* carries no JSON content type and would be redirected to itself.
|
|
79
|
+
*/
|
|
80
|
+
guard(request: Request): void;
|
|
81
|
+
/** What a sign-in says when the API cannot be reached: the `unavailable` option, else `errors.unavailableMessage`. */
|
|
82
|
+
unavailable(language: L): string;
|
|
83
|
+
/** The `Set-Cookie` values a new session and a sign-out also clear (the `clear` option); none by default. */
|
|
84
|
+
clear(): readonly string[];
|
|
85
|
+
/** The `next` a sign-in page was opened with, safe to redirect to. */
|
|
86
|
+
nextParam(request: Request): string;
|
|
87
|
+
/** The sign-in page, coming back to this request's page, with the session cookie cleared. */
|
|
88
|
+
signInRedirect(request: Request): Response;
|
|
89
|
+
/**
|
|
90
|
+
* Where an answer leads: signed in, to `next` with the session cookie and
|
|
91
|
+
* the challenge cleared; a second factor, to its page with the challenge
|
|
92
|
+
* in its cookie. `null` for any other answer.
|
|
93
|
+
*/
|
|
94
|
+
landing(answer: SignInAnswer, next: string): Response | null;
|
|
95
|
+
/**
|
|
96
|
+
* `landing`, ending the session the browser held first, when the answer's
|
|
97
|
+
* status is in `revokeOn` (a new session only, by default).
|
|
98
|
+
*/
|
|
99
|
+
landReplacing(answer: SignInAnswer, next: string, options: {
|
|
100
|
+
readonly request: Request;
|
|
101
|
+
readonly revokeOn?: readonly SignInStatus[] | undefined;
|
|
102
|
+
}): Promise<Response | null>;
|
|
103
|
+
/**
|
|
104
|
+
* Runs a sign-in step and redirects where its answer leads. An API
|
|
105
|
+
* refusal is the form's message with its status; an API it cannot reach
|
|
106
|
+
* says `unavailable` with a 503.
|
|
107
|
+
*/
|
|
108
|
+
signInStep<T extends object>(run: () => Promise<SignInAnswer>, options: {
|
|
109
|
+
readonly request: Request;
|
|
110
|
+
readonly language: L;
|
|
111
|
+
readonly next: string;
|
|
112
|
+
/** Fields every refusal carries. */
|
|
113
|
+
readonly extra: T;
|
|
114
|
+
/** Answers an error before the default message: a redirect, a richer message. */
|
|
115
|
+
readonly refused?: ((error: ApiErrorLike) => Response | string | undefined) | undefined;
|
|
116
|
+
}): Promise<Response | SignInStayed<T>>;
|
|
117
|
+
/**
|
|
118
|
+
* A refused code's message with the tries left; `undefined` when the
|
|
119
|
+
* challenge is over (sign in again). With no try left, `whenNone` is
|
|
120
|
+
* added to the message instead, when given.
|
|
121
|
+
*/
|
|
122
|
+
codeRefusal(error: ApiErrorLike, language: L, whenNone?: string): string | undefined;
|
|
123
|
+
/** The code a second-factor page posted, with how it is given; a 400 otherwise. */
|
|
124
|
+
readCodeInput(request: Request): Promise<{
|
|
125
|
+
kind: SecondFactorKind;
|
|
126
|
+
code: string;
|
|
127
|
+
}>;
|
|
128
|
+
/** The code against the challenge: `confirm` for an issued code, `recover` for a recovery code. */
|
|
129
|
+
codeStep(input: {
|
|
130
|
+
readonly kind: SecondFactorKind;
|
|
131
|
+
readonly code: string;
|
|
132
|
+
}, challenge: string, steps: {
|
|
133
|
+
confirm(challenge: string, code: string): Promise<SignInAnswer>;
|
|
134
|
+
recover(challenge: string, code: string): Promise<SignInAnswer>;
|
|
135
|
+
}): Promise<SignInAnswer>;
|
|
136
|
+
/** Ends the request's session at the API; true when it carried one. */
|
|
137
|
+
revokeSession(request: Request): Promise<boolean>;
|
|
138
|
+
/**
|
|
139
|
+
* Revokes the session, clears its cookies and redirects (to the sign-in
|
|
140
|
+
* page with `?signed-out=1` by default; `to` goes through `safeNext`). It
|
|
141
|
+
* reads the body as JSON first, so another site cannot sign anyone out.
|
|
142
|
+
*/
|
|
143
|
+
signOut(request: Request, options?: {
|
|
144
|
+
readonly to?: string | undefined;
|
|
145
|
+
}): Promise<Response>;
|
|
146
|
+
/**
|
|
147
|
+
* The viewer `read` finds for the session cookie's token (or `token`):
|
|
148
|
+
* `null` when the API refuses it with a 401, `undefined` without a cookie
|
|
149
|
+
* or when the API cannot tell.
|
|
150
|
+
*/
|
|
151
|
+
viewer<V>(request: Request, read: (token: string) => Promise<V | null>, token?: string): Promise<V | null | undefined>;
|
|
152
|
+
/**
|
|
153
|
+
* The signed-in viewer, else the sign-in redirect (thrown): no cookie, a
|
|
154
|
+
* 401, or no viewer. Any other failure is thrown through `routeError`.
|
|
155
|
+
* `headers` set the cookie again when the API moved the session's end.
|
|
156
|
+
*/
|
|
157
|
+
requireViewer<V>(request: Request, read: (token: string) => Promise<V | null>, expiresAt: (viewer: V) => string | null): Promise<{
|
|
158
|
+
viewer: V;
|
|
159
|
+
headers: HeadersInit;
|
|
160
|
+
}>;
|
|
161
|
+
}
|
|
162
|
+
/** The options once resolved, as the flow's functions take them. */
|
|
163
|
+
export interface FlowContext<L extends string> {
|
|
164
|
+
readonly options: SignInFlowOptions<L>;
|
|
165
|
+
readonly paths: SignInPaths;
|
|
166
|
+
readonly invalidCode: string;
|
|
167
|
+
readonly challengeOver: readonly string[];
|
|
168
|
+
}
|
|
169
|
+
/**
|
|
170
|
+
* What `codeRefusal` reads of the flow: the wording, and the codes it tells
|
|
171
|
+
* apart. A `FlowContext` is one; so is what `stepUpSteps` builds.
|
|
172
|
+
*/
|
|
173
|
+
export interface CodeWording<L extends string> {
|
|
174
|
+
readonly options: Pick<SignInFlowOptions<L>, 'errors' | 'attemptsLeft'>;
|
|
175
|
+
readonly invalidCode: string;
|
|
176
|
+
readonly challengeOver: readonly string[];
|
|
177
|
+
}
|
|
178
|
+
//# sourceMappingURL=flow-types.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"flow-types.d.ts","sourceRoot":"","sources":["../../src/session/flow-types.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import type { JsonActions } from '../errors/json-actions';
|
|
2
|
+
/**
|
|
3
|
+
* What every step that signs in, out, spends or mails runs first: a native
|
|
4
|
+
* form post (before hydration) goes back to its page, which then posts JSON
|
|
5
|
+
* (`json.requireJsonPost`), and a request from another site is a 403 even
|
|
6
|
+
* when it is JSON (the `Origin` and `Sec-Fetch-Site` rule of `readJson`). It
|
|
7
|
+
* reads headers only, never the body.
|
|
8
|
+
*/
|
|
9
|
+
export declare function samesitePost(json: JsonActions, request: Request): void;
|
|
10
|
+
//# sourceMappingURL=guard.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"guard.d.ts","sourceRoot":"","sources":["../../src/session/guard.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,wBAAwB,CAAC;AAG1D;;;;;;GAMG;AACH,wBAAgB,YAAY,CAAC,IAAI,EAAE,WAAW,EAAE,OAAO,EAAE,OAAO,GAAG,IAAI,CAGtE"}
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* `@alxia/react-router/session`: the session of a BFF, the app that renders
|
|
3
|
+
* pages over a GraphQL API and keeps the API's session token in its own
|
|
4
|
+
* cookie. The subpath may import `react-router` and `/errors`' files,
|
|
5
|
+
* nothing else.
|
|
6
|
+
*/
|
|
7
|
+
export { CHALLENGE_OVER, INVALID_CODE, MAIL_THROTTLED } from './codes';
|
|
8
|
+
export { type CookieSession, type SessionCookies, type SessionCookiesOptions, sessionCookies, } from './cookies';
|
|
9
|
+
export type { SignInAnswer, SignInCodes, SignInFlow, SignInFlowOptions, SignInFormError, SignInStayed, } from './flow-types';
|
|
10
|
+
export { TOKEN_PAGE_HEADERS } from './link-token';
|
|
11
|
+
export type { AuthLinks, AuthLinksCodes, AuthLinksOptions, LinkStayed, RequestLinkAnswer, SpendOptions, Spent, } from './link-types';
|
|
12
|
+
export { authLinks } from './links';
|
|
13
|
+
export { readCookie, type SerializeOptions, secondsUntil, serializeCookie, } from './serialize';
|
|
14
|
+
export { signInFlow } from './sign-in';
|
|
15
|
+
export { stepUpSteps } from './step-up';
|
|
16
|
+
export { STEP_UP_OVER, STEP_UP_REQUIRED } from './step-up-codes';
|
|
17
|
+
export type { StepUpCall, StepUpCodes, StepUpStayed, StepUpSteps, StepUpStepsOptions, } from './step-up-types';
|
|
18
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/session/index.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AACH,OAAO,EAAE,cAAc,EAAE,YAAY,EAAE,cAAc,EAAE,MAAM,SAAS,CAAC;AACvE,OAAO,EACN,KAAK,aAAa,EAClB,KAAK,cAAc,EACnB,KAAK,qBAAqB,EAC1B,cAAc,GACd,MAAM,WAAW,CAAC;AACnB,YAAY,EACX,YAAY,EACZ,WAAW,EACX,UAAU,EACV,iBAAiB,EACjB,eAAe,EACf,YAAY,GACZ,MAAM,cAAc,CAAC;AACtB,OAAO,EAAE,kBAAkB,EAAE,MAAM,cAAc,CAAC;AAClD,YAAY,EACX,SAAS,EACT,cAAc,EACd,gBAAgB,EAChB,UAAU,EACV,iBAAiB,EACjB,YAAY,EACZ,KAAK,GACL,MAAM,cAAc,CAAC;AACtB,OAAO,EAAE,SAAS,EAAE,MAAM,SAAS,CAAC;AACpC,OAAO,EACN,UAAU,EACV,KAAK,gBAAgB,EACrB,YAAY,EACZ,eAAe,GACf,MAAM,aAAa,CAAC;AACrB,OAAO,EAAE,UAAU,EAAE,MAAM,WAAW,CAAC;AACvC,OAAO,EAAE,WAAW,EAAE,MAAM,WAAW,CAAC;AACxC,OAAO,EAAE,YAAY,EAAE,gBAAgB,EAAE,MAAM,iBAAiB,CAAC;AACjE,YAAY,EACX,UAAU,EACV,WAAW,EACX,YAAY,EACZ,WAAW,EACX,kBAAkB,GAClB,MAAM,iBAAiB,CAAC"}
|