@alxia/react-router 0.27.0 → 0.28.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 +6 -1
- package/dist/chunks/{index-3jfeew2y.js → index-fpy7f4bz.js} +5 -58
- package/dist/chunks/index-fpy7f4bz.js.map +11 -0
- package/dist/chunks/index-xvx63t7n.js +59 -0
- package/dist/chunks/index-xvx63t7n.js.map +13 -0
- package/dist/session/index.d.ts +1 -1
- package/dist/session/index.d.ts.map +1 -1
- package/dist/session/index.js +20 -2
- package/dist/session/index.js.map +3 -3
- package/dist/session/model/index.js +5 -3
- package/dist/session/model/index.js.map +1 -1
- package/dist/session/react/index.d.ts +3 -2
- package/dist/session/react/index.d.ts.map +1 -1
- package/dist/session/react/index.js +199 -17
- package/dist/session/react/index.js.map +8 -3
- package/dist/session/react/step-up/answers.d.ts +9 -0
- package/dist/session/react/step-up/answers.d.ts.map +1 -0
- package/dist/session/react/step-up/dialog-props.d.ts +27 -0
- package/dist/session/react/step-up/dialog-props.d.ts.map +1 -0
- package/dist/session/react/step-up/index.d.ts +6 -0
- package/dist/session/react/step-up/index.d.ts.map +1 -0
- package/dist/session/react/step-up/phase.d.ts +8 -0
- package/dist/session/react/step-up/phase.d.ts.map +1 -0
- package/dist/session/react/step-up/use-step-up-replay.d.ts +54 -0
- package/dist/session/react/step-up/use-step-up-replay.d.ts.map +1 -0
- package/dist/session/react/step-up/use-step-up.d.ts +51 -0
- package/dist/session/react/step-up/use-step-up.d.ts.map +1 -0
- package/dist/session/step-up-types.d.ts +25 -0
- package/dist/session/step-up-types.d.ts.map +1 -1
- package/dist/session/step-up.d.ts.map +1 -1
- package/docs/guide/session.md +133 -2
- package/docs/guide/subscriptions.md +18 -4
- package/docs/troubleshooting.md +24 -4
- package/package.json +4 -4
- package/dist/chunks/index-3jfeew2y.js.map +0 -15
|
@@ -1,15 +1,190 @@
|
|
|
1
|
+
import {
|
|
2
|
+
INITIAL_STEP_UP2,
|
|
3
|
+
stepUpReducer2,
|
|
4
|
+
stepUpProps2
|
|
5
|
+
} from "../../chunks/index-fpy7f4bz.js";
|
|
6
|
+
|
|
7
|
+
// src/session/react/step-up/answers.ts
|
|
8
|
+
var intentOf = (data) => typeof data === "object" && data !== null ? data.intent : undefined;
|
|
9
|
+
function requestAnswerOf(data) {
|
|
10
|
+
return intentOf(data) === "request-step-up" ? data : undefined;
|
|
11
|
+
}
|
|
12
|
+
function confirmAnswerOf(data) {
|
|
13
|
+
return intentOf(data) === "confirm-step-up" ? data : undefined;
|
|
14
|
+
}
|
|
15
|
+
// src/session/react/step-up/dialog-props.ts
|
|
16
|
+
function dialogPropsOf(stepUp, open, cancel) {
|
|
17
|
+
return {
|
|
18
|
+
open,
|
|
19
|
+
phase: stepUp.phase,
|
|
20
|
+
via: stepUp.phase === "code" ? stepUp.via : undefined,
|
|
21
|
+
props: stepUp.props,
|
|
22
|
+
message: stepUp.message,
|
|
23
|
+
busy: stepUp.busy,
|
|
24
|
+
confirming: stepUp.phase === "confirmed",
|
|
25
|
+
onCancel: cancel,
|
|
26
|
+
onRetry: () => stepUp.start(),
|
|
27
|
+
onSubmit: (code) => stepUp.submit(code),
|
|
28
|
+
onResend: stepUp.via === "email" ? () => stepUp.start() : undefined
|
|
29
|
+
};
|
|
30
|
+
}
|
|
31
|
+
// src/session/react/step-up/phase.ts
|
|
32
|
+
function stepUpDialogPhase(state) {
|
|
33
|
+
if (state.phase === "done")
|
|
34
|
+
return "confirmed";
|
|
35
|
+
if (state.challenge)
|
|
36
|
+
return "code";
|
|
37
|
+
if (state.error === "expired")
|
|
38
|
+
return "expired";
|
|
39
|
+
return state.error ? "failed" : "asking";
|
|
40
|
+
}
|
|
41
|
+
function asksStepUp(answer) {
|
|
42
|
+
if (typeof answer !== "object" || answer === null)
|
|
43
|
+
return false;
|
|
44
|
+
const a = answer;
|
|
45
|
+
return !a.ok && Boolean(a.stepUp);
|
|
46
|
+
}
|
|
47
|
+
// src/session/react/step-up/use-step-up.ts
|
|
48
|
+
import { useEffect, useReducer, useRef } from "react";
|
|
49
|
+
function useStepUp({ request, confirm, onConfirmed }) {
|
|
50
|
+
const [state, dispatch] = useReducer(stepUpReducer2, INITIAL_STEP_UP2);
|
|
51
|
+
const confirmedRun = useRef(onConfirmed);
|
|
52
|
+
confirmedRun.current = onConfirmed;
|
|
53
|
+
const live = useRef(false);
|
|
54
|
+
const handledRequest = useRef(request.answer);
|
|
55
|
+
const handledConfirm = useRef(confirm.answer);
|
|
56
|
+
useEffect(() => {
|
|
57
|
+
const answer = request.answer;
|
|
58
|
+
if (!answer || handledRequest.current === answer)
|
|
59
|
+
return;
|
|
60
|
+
handledRequest.current = answer;
|
|
61
|
+
if (!live.current)
|
|
62
|
+
return;
|
|
63
|
+
dispatch({ type: "requested", answer });
|
|
64
|
+
}, [request.answer]);
|
|
65
|
+
useEffect(() => {
|
|
66
|
+
const answer = confirm.answer;
|
|
67
|
+
if (!answer || handledConfirm.current === answer)
|
|
68
|
+
return;
|
|
69
|
+
handledConfirm.current = answer;
|
|
70
|
+
if (!live.current)
|
|
71
|
+
return;
|
|
72
|
+
dispatch({ type: "confirmed", answer });
|
|
73
|
+
if (answer.ok)
|
|
74
|
+
confirmedRun.current();
|
|
75
|
+
}, [confirm.answer]);
|
|
76
|
+
return {
|
|
77
|
+
phase: stepUpDialogPhase(state),
|
|
78
|
+
via: state.via,
|
|
79
|
+
props: stepUpProps2(state),
|
|
80
|
+
message: state.message,
|
|
81
|
+
busy: request.busy || confirm.busy,
|
|
82
|
+
start() {
|
|
83
|
+
live.current = true;
|
|
84
|
+
dispatch({ type: "start" });
|
|
85
|
+
request.post({});
|
|
86
|
+
},
|
|
87
|
+
submit(code) {
|
|
88
|
+
if (!state.challenge)
|
|
89
|
+
return;
|
|
90
|
+
dispatch({ type: "submit" });
|
|
91
|
+
confirm.post({ challenge: state.challenge, code, via: state.via });
|
|
92
|
+
},
|
|
93
|
+
release() {
|
|
94
|
+
live.current = false;
|
|
95
|
+
request.reset?.();
|
|
96
|
+
confirm.reset?.();
|
|
97
|
+
handledRequest.current = request.answer;
|
|
98
|
+
handledConfirm.current = confirm.answer;
|
|
99
|
+
dispatch({ type: "release" });
|
|
100
|
+
}
|
|
101
|
+
};
|
|
102
|
+
}
|
|
103
|
+
// src/session/react/step-up/use-step-up-replay.ts
|
|
104
|
+
import { useEffect as useEffect2, useRef as useRef2, useState } from "react";
|
|
105
|
+
function useStepUpReplay({
|
|
106
|
+
answer,
|
|
107
|
+
replay,
|
|
108
|
+
action,
|
|
109
|
+
spendsCode,
|
|
110
|
+
request,
|
|
111
|
+
confirm
|
|
112
|
+
}) {
|
|
113
|
+
const [open, setOpen] = useState(false);
|
|
114
|
+
const [confirmedNotice, setConfirmedNotice] = useState(false);
|
|
115
|
+
const isOpen = useRef2(false);
|
|
116
|
+
const replaying = useRef2(false);
|
|
117
|
+
const latest = useRef2({ replay, action, spendsCode });
|
|
118
|
+
latest.current = { replay, action, spendsCode };
|
|
119
|
+
function show(value) {
|
|
120
|
+
isOpen.current = value;
|
|
121
|
+
setOpen(value);
|
|
122
|
+
}
|
|
123
|
+
const stepUp = useStepUp({
|
|
124
|
+
request,
|
|
125
|
+
confirm,
|
|
126
|
+
onConfirmed() {
|
|
127
|
+
if (!isOpen.current)
|
|
128
|
+
return;
|
|
129
|
+
const { replay, action, spendsCode } = latest.current;
|
|
130
|
+
const spent = stepUpRef.current.via === "secondFactor" && action !== undefined && spendsCode?.(action) === true;
|
|
131
|
+
if (spent) {
|
|
132
|
+
stepUpRef.current.release();
|
|
133
|
+
show(false);
|
|
134
|
+
setConfirmedNotice(true);
|
|
135
|
+
return;
|
|
136
|
+
}
|
|
137
|
+
replaying.current = true;
|
|
138
|
+
replay();
|
|
139
|
+
}
|
|
140
|
+
});
|
|
141
|
+
const stepUpRef = useRef2(stepUp);
|
|
142
|
+
stepUpRef.current = stepUp;
|
|
143
|
+
const handled = useRef2(answer);
|
|
144
|
+
useEffect2(() => {
|
|
145
|
+
if (!answer || handled.current === answer)
|
|
146
|
+
return;
|
|
147
|
+
handled.current = answer;
|
|
148
|
+
if (asksStepUp(answer)) {
|
|
149
|
+
replaying.current = false;
|
|
150
|
+
setConfirmedNotice(false);
|
|
151
|
+
show(true);
|
|
152
|
+
stepUpRef.current.start();
|
|
153
|
+
return;
|
|
154
|
+
}
|
|
155
|
+
setConfirmedNotice(false);
|
|
156
|
+
if (replaying.current) {
|
|
157
|
+
replaying.current = false;
|
|
158
|
+
show(false);
|
|
159
|
+
stepUpRef.current.release();
|
|
160
|
+
}
|
|
161
|
+
}, [answer]);
|
|
162
|
+
function cancel() {
|
|
163
|
+
replaying.current = false;
|
|
164
|
+
stepUp.release();
|
|
165
|
+
show(false);
|
|
166
|
+
setConfirmedNotice(false);
|
|
167
|
+
}
|
|
168
|
+
return {
|
|
169
|
+
open,
|
|
170
|
+
confirmedNotice,
|
|
171
|
+
dialogProps: dialogPropsOf(stepUp, open, cancel),
|
|
172
|
+
cancel,
|
|
173
|
+
stepUp
|
|
174
|
+
};
|
|
175
|
+
}
|
|
1
176
|
// src/session/react/use-code-field.ts
|
|
2
177
|
import {
|
|
3
178
|
useCallback,
|
|
4
|
-
useEffect,
|
|
5
|
-
useRef,
|
|
6
|
-
useState
|
|
179
|
+
useEffect as useEffect3,
|
|
180
|
+
useRef as useRef3,
|
|
181
|
+
useState as useState2
|
|
7
182
|
} from "react";
|
|
8
183
|
function useOnRefusal(refusal, handler) {
|
|
9
|
-
const handled =
|
|
10
|
-
const latest =
|
|
184
|
+
const handled = useRef3(refusal);
|
|
185
|
+
const latest = useRef3(handler);
|
|
11
186
|
latest.current = handler;
|
|
12
|
-
|
|
187
|
+
useEffect3(() => {
|
|
13
188
|
if (!refusal || handled.current === refusal)
|
|
14
189
|
return;
|
|
15
190
|
handled.current = refusal;
|
|
@@ -17,9 +192,9 @@ function useOnRefusal(refusal, handler) {
|
|
|
17
192
|
}, [refusal]);
|
|
18
193
|
}
|
|
19
194
|
function useCodeField(schema, refusal) {
|
|
20
|
-
const [code, setCodeState] =
|
|
21
|
-
const [error, setError] =
|
|
22
|
-
const ref =
|
|
195
|
+
const [code, setCodeState] = useState2("");
|
|
196
|
+
const [error, setError] = useState2();
|
|
197
|
+
const ref = useRef3(null);
|
|
23
198
|
const setCode = useCallback((next) => {
|
|
24
199
|
setCodeState(next);
|
|
25
200
|
setError(undefined);
|
|
@@ -44,21 +219,21 @@ function useCodeField(schema, refusal) {
|
|
|
44
219
|
return { code, setCode, ref, error, check };
|
|
45
220
|
}
|
|
46
221
|
// src/session/react/use-link-param.ts
|
|
47
|
-
import { useEffect as
|
|
222
|
+
import { useEffect as useEffect4, useState as useState3 } from "react";
|
|
48
223
|
import { useLocation, useSearchParams } from "react-router";
|
|
49
224
|
function useLinkParam(name, { drop = false, live = false } = {}) {
|
|
50
225
|
const [params] = useSearchParams();
|
|
51
226
|
const { key } = useLocation();
|
|
52
227
|
const followed = live ? key : null;
|
|
53
228
|
const current = params.get(name) || null;
|
|
54
|
-
const [kept, setKept] =
|
|
55
|
-
const [seen, setSeen] =
|
|
229
|
+
const [kept, setKept] = useState3(current);
|
|
230
|
+
const [seen, setSeen] = useState3(current);
|
|
56
231
|
if (live && current !== seen) {
|
|
57
232
|
setSeen(current);
|
|
58
233
|
if (!drop || current !== null)
|
|
59
234
|
setKept(current);
|
|
60
235
|
}
|
|
61
|
-
|
|
236
|
+
useEffect4(() => {
|
|
62
237
|
if (!drop)
|
|
63
238
|
return;
|
|
64
239
|
const url = new URL(window.location.href);
|
|
@@ -72,7 +247,7 @@ function useLinkParam(name, { drop = false, live = false } = {}) {
|
|
|
72
247
|
return kept;
|
|
73
248
|
}
|
|
74
249
|
// src/session/react/use-sign-out.ts
|
|
75
|
-
import { useCallback as useCallback2, useState as
|
|
250
|
+
import { useCallback as useCallback2, useState as useState4 } from "react";
|
|
76
251
|
import { useNavigation, useSubmit } from "react-router";
|
|
77
252
|
var SIGN_OUT_PATH = "/sign-out";
|
|
78
253
|
async function signOutAfter(before, submit) {
|
|
@@ -84,7 +259,7 @@ async function signOutAfter(before, submit) {
|
|
|
84
259
|
function useSignOut(options = {}) {
|
|
85
260
|
const { action = SIGN_OUT_PATH, before } = options;
|
|
86
261
|
const submit = useSubmit();
|
|
87
|
-
const [preparing, setPreparing] =
|
|
262
|
+
const [preparing, setPreparing] = useState4(false);
|
|
88
263
|
const submitting = useNavigation().formAction === action;
|
|
89
264
|
const signOut = useCallback2(() => {
|
|
90
265
|
setPreparing(true);
|
|
@@ -94,12 +269,19 @@ function useSignOut(options = {}) {
|
|
|
94
269
|
}
|
|
95
270
|
export {
|
|
96
271
|
SIGN_OUT_PATH,
|
|
272
|
+
asksStepUp,
|
|
273
|
+
confirmAnswerOf,
|
|
274
|
+
dialogPropsOf,
|
|
275
|
+
requestAnswerOf,
|
|
97
276
|
signOutAfter,
|
|
277
|
+
stepUpDialogPhase,
|
|
98
278
|
useCodeField,
|
|
99
279
|
useLinkParam,
|
|
100
280
|
useOnRefusal,
|
|
101
|
-
useSignOut
|
|
281
|
+
useSignOut,
|
|
282
|
+
useStepUp,
|
|
283
|
+
useStepUpReplay
|
|
102
284
|
};
|
|
103
285
|
|
|
104
|
-
//# debugId=
|
|
286
|
+
//# debugId=5FBD780FA282A7A264756E2164756E21
|
|
105
287
|
//# sourceMappingURL=index.js.map
|
|
@@ -1,12 +1,17 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
|
-
"sources": ["../src/session/react/use-code-field.ts", "../src/session/react/use-link-param.ts", "../src/session/react/use-sign-out.ts"],
|
|
3
|
+
"sources": ["../src/session/react/step-up/answers.ts", "../src/session/react/step-up/dialog-props.ts", "../src/session/react/step-up/phase.ts", "../src/session/react/step-up/use-step-up.ts", "../src/session/react/step-up/use-step-up-replay.ts", "../src/session/react/use-code-field.ts", "../src/session/react/use-link-param.ts", "../src/session/react/use-sign-out.ts"],
|
|
4
4
|
"sourcesContent": [
|
|
5
|
+
"import type {\n\tStepUpConfirmAnswer,\n\tStepUpRequestAnswer,\n} from '../../model/step-up-answers';\n\nconst intentOf = (data: unknown) =>\n\ttypeof data === 'object' && data !== null\n\t\t? (data as { intent?: unknown }).intent\n\t\t: undefined;\n\n/**\n * The step-up route answers both intents from one action, so a fetcher's data\n * is their union: this is the request's answer, or `undefined` for any other.\n */\nexport function requestAnswerOf(\n\tdata: unknown,\n): StepUpRequestAnswer | undefined {\n\treturn intentOf(data) === 'request-step-up'\n\t\t? (data as StepUpRequestAnswer)\n\t\t: undefined;\n}\n\n/** The confirm's answer out of the route's union, or `undefined` for any other. */\nexport function confirmAnswerOf(\n\tdata: unknown,\n): StepUpConfirmAnswer | undefined {\n\treturn intentOf(data) === 'confirm-step-up'\n\t\t? (data as StepUpConfirmAnswer)\n\t\t: undefined;\n}\n",
|
|
6
|
+
"import type { StepUpVia } from '../../model/second-factor';\nimport type { StepUpProps } from '../../model/step-up-props';\nimport type { StepUpDialogPhase } from './phase';\nimport type { useStepUp } from './use-step-up';\n\n/** What a step-up dialog is given: the phase to show and the handlers. */\nexport interface StepUpDialogProps {\n\topen: boolean;\n\tphase: StepUpDialogPhase;\n\t/** How the code is confirmed, once there is a challenge. */\n\tvia: StepUpVia | undefined;\n\t/** The words of the code form (`stepUpProps`). */\n\tprops: StepUpProps;\n\t/** The last refusal worded by the server. */\n\tmessage: string | undefined;\n\tbusy: boolean;\n\t/** The code was accepted and the action is being sent again. */\n\tconfirming: boolean;\n\tonCancel(): void;\n\t/** \"Retry\" after a refused request or an over challenge. */\n\tonRetry(): void;\n\tonSubmit(code: string): void;\n\t/** \"Resend code\", for a mailed code only. */\n\tonResend: (() => void) | undefined;\n}\n\n/** The dialog's props out of a step-up: plain, so any host can build them. */\nexport function dialogPropsOf(\n\tstepUp: ReturnType<typeof useStepUp>,\n\topen: boolean,\n\tcancel: () => void,\n): StepUpDialogProps {\n\treturn {\n\t\topen,\n\t\tphase: stepUp.phase,\n\t\tvia: stepUp.phase === 'code' ? stepUp.via : undefined,\n\t\tprops: stepUp.props,\n\t\tmessage: stepUp.message,\n\t\tbusy: stepUp.busy,\n\t\tconfirming: stepUp.phase === 'confirmed',\n\t\tonCancel: cancel,\n\t\tonRetry: () => stepUp.start(),\n\t\tonSubmit: (code) => stepUp.submit(code),\n\t\tonResend: stepUp.via === 'email' ? () => stepUp.start() : undefined,\n\t};\n}\n",
|
|
7
|
+
"import type { StepUpState } from '../../model/step-up';\n\n/** Where a step-up is, as a dialog shows it. */\nexport type StepUpDialogPhase =\n\t| 'asking'\n\t| 'failed'\n\t| 'code'\n\t| 'expired'\n\t| 'confirmed';\n\n/** The phase a reducer state is in: what the dialog shows. */\nexport function stepUpDialogPhase(state: StepUpState): StepUpDialogPhase {\n\tif (state.phase === 'done') return 'confirmed';\n\tif (state.challenge) return 'code';\n\tif (state.error === 'expired') return 'expired';\n\treturn state.error ? 'failed' : 'asking';\n}\n\n/** Whether an answer is a refusal asking for a step-up (`stepUp` set, not ok). */\nexport function asksStepUp(answer: unknown): boolean {\n\tif (typeof answer !== 'object' || answer === null) return false;\n\tconst a = answer as { ok?: unknown; stepUp?: unknown };\n\treturn !a.ok && Boolean(a.stepUp);\n}\n",
|
|
8
|
+
"import { useEffect, useReducer, useRef } from 'react';\nimport type { StepUpVia } from '../../model/second-factor';\nimport { INITIAL_STEP_UP, stepUpReducer } from '../../model/step-up';\nimport type {\n\tStepUpConfirmAnswer,\n\tStepUpRequestAnswer,\n} from '../../model/step-up-answers';\nimport { stepUpProps } from '../../model/step-up-props';\nimport { stepUpDialogPhase } from './phase';\n\n/**\n * One step-up intent as the host posts it: its own `post` (so the fields stay\n * typed by the host's action), the settled answer it got since it mounted\n * (`undefined` before), and whether it is in flight. `reset` forgets the\n * answer (a fetcher's `reset`).\n */\nexport interface StepUpChannel<Fields, Answer> {\n\tpost(fields: Fields): void;\n\treadonly answer: Answer | undefined;\n\treadonly busy: boolean;\n\treset?(): void;\n}\n\nexport interface StepUpOptions {\n\t/** Posts `{ intent: 'request-step-up' }`, to the route that serves `stepUpSteps().route`. */\n\trequest: StepUpChannel<Record<string, never>, StepUpRequestAnswer>;\n\t/** Posts `{ intent: 'confirm-step-up', challenge, code, via }`. */\n\tconfirm: StepUpChannel<\n\t\t{ challenge: string; code: string; via: StepUpVia | undefined },\n\t\tStepUpConfirmAnswer\n\t>;\n\t/** Runs once the API accepted the code. */\n\tonConfirmed(): void;\n}\n\n/**\n * The step-up as the page lives it, on `stepUpReducer`: `start` asks for a\n * challenge, `submit` posts the code, and once it is accepted `onConfirmed`\n * runs. The challenge lives in the reducer's state and the channels' answers\n * only; `release` forgets everything, and an answer that lands after it (a\n * request or a code in flight when the host closed) is ignored.\n */\nexport function useStepUp({ request, confirm, onConfirmed }: StepUpOptions) {\n\tconst [state, dispatch] = useReducer(stepUpReducer, INITIAL_STEP_UP);\n\tconst confirmedRun = useRef(onConfirmed);\n\tconfirmedRun.current = onConfirmed;\n\t// True from `start` to `release`: only then are answers this step-up's.\n\tconst live = useRef(false);\n\n\t// Each settled answer once, even one worded as the last (a new object).\n\tconst handledRequest = useRef(request.answer);\n\tconst handledConfirm = useRef(confirm.answer);\n\tuseEffect(() => {\n\t\tconst answer = request.answer;\n\t\tif (!answer || handledRequest.current === answer) return;\n\t\thandledRequest.current = answer;\n\t\tif (!live.current) return;\n\t\tdispatch({ type: 'requested', answer });\n\t}, [request.answer]);\n\tuseEffect(() => {\n\t\tconst answer = confirm.answer;\n\t\tif (!answer || handledConfirm.current === answer) return;\n\t\thandledConfirm.current = answer;\n\t\tif (!live.current) return;\n\t\tdispatch({ type: 'confirmed', answer });\n\t\tif (answer.ok) confirmedRun.current();\n\t}, [confirm.answer]);\n\n\treturn {\n\t\tphase: stepUpDialogPhase(state),\n\t\t/** How the challenge held (or the last one) is confirmed. */\n\t\tvia: state.via,\n\t\t/** What a dialog words its texts from (`stepUpProps`). */\n\t\tprops: stepUpProps(state),\n\t\t/** The last refusal worded by the server: the fallback of the dialog's own words. */\n\t\tmessage: state.message,\n\t\t/** A request or a code is in flight. */\n\t\tbusy: request.busy || confirm.busy,\n\t\t/** Asks for a challenge: the first, or \"Resend code\" / \"New code\". */\n\t\tstart() {\n\t\t\tlive.current = true;\n\t\t\tdispatch({ type: 'start' });\n\t\t\trequest.post({});\n\t\t},\n\t\t/** Posts the code for the challenge held. */\n\t\tsubmit(code: string) {\n\t\t\tif (!state.challenge) return;\n\t\t\tdispatch({ type: 'submit' });\n\t\t\tconfirm.post({ challenge: state.challenge, code, via: state.via });\n\t\t},\n\t\t/** Forgets the challenge, the answers and the errors. */\n\t\trelease() {\n\t\t\tlive.current = false;\n\t\t\trequest.reset?.();\n\t\t\tconfirm.reset?.();\n\t\t\thandledRequest.current = request.answer;\n\t\t\thandledConfirm.current = confirm.answer;\n\t\t\tdispatch({ type: 'release' });\n\t\t},\n\t};\n}\n",
|
|
9
|
+
"import { useEffect, useRef, useState } from 'react';\nimport { dialogPropsOf } from './dialog-props';\nimport { asksStepUp } from './phase';\nimport { type StepUpOptions, useStepUp } from './use-step-up';\n\nexport interface StepUpReplayOptions<Action>\n\textends Pick<StepUpOptions, 'request' | 'confirm'> {\n\t/**\n\t * The settled answer of the sensitive action. A refusal carrying `stepUp`\n\t * opens the step-up; the first answer after the replay closes it.\n\t */\n\tanswer: unknown;\n\t/** Sends the refused action again, once the session is confirmed. */\n\treplay(): void;\n\t/** The action that was refused, for `spendsCode`. */\n\taction?: Action | undefined;\n\t/**\n\t * Whether the action carries a one-time code that a step-up by the\n\t * second factor just spent. Such an action is not replayed: the dialog\n\t * closes and `confirmedNotice` is true (\"confirmed, type a new code\").\n\t */\n\tspendsCode?(action: Action): boolean;\n}\n\n/**\n * The step-up a sensitive action asks for: an answer carrying `stepUp` opens\n * it; once the session is confirmed the same action is sent again by itself\n * (`replay`), except an action that `spendsCode` after a step-up by the\n * second factor, whose code was just spent: the user types the next one\n * (`confirmedNotice`). The dialog stays, saying so, until the replayed\n * action is answered; if that is refused for a step-up again, it asks again.\n * Generic over the host's `post`s, so each intent keeps its typed fields.\n *\n * @example\n * const { open, dialogProps, cancel, confirmedNotice } = useStepUpReplay({\n * \tanswer: fetcher.data,\n * \treplay: () => post(lastAction.current),\n * \trequest: { post: () => stepUpPost({ intent: 'request-step-up' }), answer, busy },\n * \tconfirm: { post: (f) => stepUpPost({ intent: 'confirm-step-up', ...f }), answer, busy },\n * });\n */\nexport function useStepUpReplay<Action = never>({\n\tanswer,\n\treplay,\n\taction,\n\tspendsCode,\n\trequest,\n\tconfirm,\n}: StepUpReplayOptions<Action>) {\n\tconst [open, setOpen] = useState(false);\n\tconst [confirmedNotice, setConfirmedNotice] = useState(false);\n\tconst isOpen = useRef(false);\n\tconst replaying = useRef(false);\n\tconst latest = useRef({ replay, action, spendsCode });\n\tlatest.current = { replay, action, spendsCode };\n\n\tfunction show(value: boolean) {\n\t\tisOpen.current = value;\n\t\tsetOpen(value);\n\t}\n\n\tconst stepUp = useStepUp({\n\t\trequest,\n\t\tconfirm,\n\t\tonConfirmed() {\n\t\t\t// A code accepted after the host cancelled replays nothing.\n\t\t\tif (!isOpen.current) return;\n\t\t\tconst { replay, action, spendsCode } = latest.current;\n\t\t\tconst spent =\n\t\t\t\tstepUpRef.current.via === 'secondFactor' &&\n\t\t\t\taction !== undefined &&\n\t\t\t\tspendsCode?.(action) === true;\n\t\t\tif (spent) {\n\t\t\t\tstepUpRef.current.release();\n\t\t\t\tshow(false);\n\t\t\t\tsetConfirmedNotice(true);\n\t\t\t\treturn;\n\t\t\t}\n\t\t\t// The dialog stays, saying so, until the action is answered.\n\t\t\treplaying.current = true;\n\t\t\treplay();\n\t\t},\n\t});\n\tconst stepUpRef = useRef(stepUp);\n\tstepUpRef.current = stepUp;\n\n\t// Each answer once: a refusal asking for a step-up opens it; the answer\n\t// of the replayed action closes it (a new step-up opens it again).\n\tconst handled = useRef(answer);\n\tuseEffect(() => {\n\t\tif (!answer || handled.current === answer) return;\n\t\thandled.current = answer;\n\t\tif (asksStepUp(answer)) {\n\t\t\treplaying.current = false;\n\t\t\tsetConfirmedNotice(false);\n\t\t\tshow(true);\n\t\t\tstepUpRef.current.start();\n\t\t\treturn;\n\t\t}\n\t\tsetConfirmedNotice(false);\n\t\tif (replaying.current) {\n\t\t\treplaying.current = false;\n\t\t\tshow(false);\n\t\t\tstepUpRef.current.release();\n\t\t}\n\t}, [answer]);\n\n\tfunction cancel() {\n\t\treplaying.current = false;\n\t\tstepUp.release();\n\t\tshow(false);\n\t\tsetConfirmedNotice(false);\n\t}\n\n\treturn {\n\t\topen,\n\t\t/** True after a step-up by the second factor spent the action's own code. */\n\t\tconfirmedNotice,\n\t\tdialogProps: dialogPropsOf(stepUp, open, cancel),\n\t\t/** Closes the dialog without sending the action again. */\n\t\tcancel,\n\t\tstepUp,\n\t};\n}\n",
|
|
5
10
|
"import {\n\ttype RefObject,\n\tuseCallback,\n\tuseEffect,\n\tuseRef,\n\tuseState,\n} from 'react';\n\n/** The part of a Standard Schema (`~standard`) this hook reads; Zod, Valibot and ArkType satisfy it. */\nexport interface CodeSchema {\n\treadonly '~standard': {\n\t\tvalidate(value: unknown): unknown;\n\t};\n}\n\n/**\n * Calls `handler` once for each new `refusal` (a new object each time,\n * `undefined` when there is none). A refusal already there when the\n * component mounted is not new: it is the page's own, seen again.\n * Library-agnostic: pair it with any form library's `reset` and `focus`.\n */\nexport function useOnRefusal(\n\trefusal: object | undefined,\n\thandler: () => void,\n): void {\n\tconst handled = useRef(refusal);\n\tconst latest = useRef(handler);\n\tlatest.current = handler;\n\tuseEffect(() => {\n\t\tif (!refusal || handled.current === refusal) return;\n\t\thandled.current = refusal;\n\t\tlatest.current();\n\t}, [refusal]);\n}\n\nexport interface CodeField {\n\t/** The code typed so far. */\n\treadonly code: string;\n\treadonly setCode: (code: string) => void;\n\t/** On the input, so a refusal can focus it. */\n\treadonly ref: RefObject<HTMLInputElement | null>;\n\t/** The first issue's message of the last `check`, cleared by typing. */\n\treadonly error: string | undefined;\n\t/**\n\t * Validates the code against the schema: the parsed value, or\n\t * `undefined` and `error` set. Synchronous schemas only.\n\t */\n\treadonly check: () => unknown;\n}\n\n/**\n * A one-code field (an authenticator app's code, a recovery code) with no\n * form library: it holds the code, checks it against `schema`, and on each\n * new `refusal` clears the refused code and focuses the input for the next\n * try. With react-hook-form, use `useOnRefusal` and its `setValue` and\n * `setFocus` instead.\n */\nexport function useCodeField(\n\tschema: CodeSchema,\n\trefusal: object | undefined,\n): CodeField {\n\tconst [code, setCodeState] = useState('');\n\tconst [error, setError] = useState<string | undefined>();\n\tconst ref = useRef<HTMLInputElement | null>(null);\n\tconst setCode = useCallback((next: string) => {\n\t\tsetCodeState(next);\n\t\tsetError(undefined);\n\t}, []);\n\tuseOnRefusal(refusal, () => {\n\t\tsetCode('');\n\t\tref.current?.focus();\n\t});\n\tconst check = () => {\n\t\tconst result = schema['~standard'].validate(code);\n\t\tif (result instanceof Promise) {\n\t\t\tthrow new TypeError('useCodeField takes a synchronous schema');\n\t\t}\n\t\tconst { issues, value } = result as {\n\t\t\tissues?: ReadonlyArray<{ message: string }>;\n\t\t\tvalue?: unknown;\n\t\t};\n\t\tif (issues?.length) {\n\t\t\tsetError(issues[0]?.message);\n\t\t\treturn undefined;\n\t\t}\n\t\tsetError(undefined);\n\t\treturn value;\n\t};\n\treturn { code, setCode, ref, error, check };\n}\n",
|
|
6
11
|
"import { useEffect, useState } from 'react';\nimport { useLocation, useSearchParams } from 'react-router';\n\nexport interface LinkParamOptions {\n\t/**\n\t * Remove the parameter from the address bar once read\n\t * (`history.replaceState`), so a token is not left in the history, a\n\t * bookmark or a shared screen. Default `false`.\n\t */\n\treadonly drop?: boolean;\n\t/**\n\t * Follow the URL instead of reading it once. A parameter that a redirect\n\t * or a link adds to the SAME mounted route (`?state=linked`) is seen, and\n\t * each new location is read again. Without `drop` the value is the\n\t * parameter of the current location. With `drop` the value is kept after\n\t * the address bar loses the parameter, until a location carries a new\n\t * one: a navigation that has none does not clear it. Default `false`.\n\t */\n\treadonly live?: boolean;\n}\n\n/**\n * The query parameter a mail's link carries (`token`, `code`, `state`),\n * read once: the value of the first render is kept for the page's life, so\n * dropping it from the address bar never loses it. With `live: true` it\n * follows the URL instead (see `LinkParamOptions`). `null` when absent or\n * empty. Safe to render on the server, where nothing is dropped.\n */\nexport function useLinkParam(\n\tname: string,\n\t{ drop = false, live = false }: LinkParamOptions = {},\n): string | null {\n\tconst [params] = useSearchParams();\n\tconst { key } = useLocation();\n\tconst followed = live ? key : null;\n\tconst current = params.get(name) || null;\n\tconst [kept, setKept] = useState(current);\n\tconst [seen, setSeen] = useState(current);\n\tif (live && current !== seen) {\n\t\tsetSeen(current);\n\t\tif (!drop || current !== null) setKept(current);\n\t}\n\tuseEffect(() => {\n\t\tif (!drop) return;\n\t\tconst url = new URL(window.location.href);\n\t\tif (!url.searchParams.has(name)) return;\n\t\turl.searchParams.delete(name);\n\t\twindow.history.replaceState(\n\t\t\twindow.history.state,\n\t\t\t'',\n\t\t\t`${url.pathname}${url.search}${url.hash}`,\n\t\t);\n\t}, [drop, name, followed]);\n\tif (live && !drop) return current;\n\treturn kept;\n}\n",
|
|
7
12
|
"import { useCallback, useState } from 'react';\nimport { useNavigation, useSubmit } from 'react-router';\n\n/** Where `signInFlow`'s sign-out action is mounted unless the app says otherwise. */\nexport const SIGN_OUT_PATH = '/sign-out';\n\nexport interface SignOutOptions {\n\t/** The sign-out route (default `/sign-out`). */\n\treadonly action?: string;\n\t/**\n\t * Runs before the post: clear the worker's caches, a local store. A\n\t * rejection never keeps the user signed in: the sign-out goes on.\n\t */\n\treadonly before?: () => Promise<unknown> | unknown;\n}\n\n/**\n * Runs `before`, then `submit`. A `before` that throws or rejects is\n * ignored, so a failed cleanup cannot keep a session alive.\n */\nexport async function signOutAfter(\n\tbefore: (() => Promise<unknown> | unknown) | undefined,\n\tsubmit: () => Promise<void> | void,\n): Promise<void> {\n\ttry {\n\t\tawait before?.();\n\t} catch {\n\t\t// Signing out matters more than the cleanup.\n\t}\n\tawait submit();\n}\n\n/**\n * The one way a page signs out, wherever the control is: posts `{}` as JSON\n * to the sign-out route (same-origin and JSON only, as `signInFlow`'s action\n * requires). `busy` from the call until the navigation it starts has ended.\n */\nexport function useSignOut(options: SignOutOptions = {}): {\n\tsignOut: () => void;\n\tbusy: boolean;\n} {\n\tconst { action = SIGN_OUT_PATH, before } = options;\n\tconst submit = useSubmit();\n\tconst [preparing, setPreparing] = useState(false);\n\tconst submitting = useNavigation().formAction === action;\n\tconst signOut = useCallback(() => {\n\t\tsetPreparing(true);\n\t\tvoid signOutAfter(before, () =>\n\t\t\tsubmit({}, { method: 'post', action, encType: 'application/json' }),\n\t\t).finally(() => setPreparing(false));\n\t}, [submit, action, before]);\n\treturn { signOut, busy: preparing || submitting };\n}\n"
|
|
8
13
|
],
|
|
9
|
-
"mappings": ";AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;
|
|
10
|
-
"debugId": "
|
|
14
|
+
"mappings": "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",
|
|
15
|
+
"debugId": "5FBD780FA282A7A264756E2164756E21",
|
|
11
16
|
"names": []
|
|
12
17
|
}
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import type { StepUpConfirmAnswer, StepUpRequestAnswer } from '../../model/step-up-answers';
|
|
2
|
+
/**
|
|
3
|
+
* The step-up route answers both intents from one action, so a fetcher's data
|
|
4
|
+
* is their union: this is the request's answer, or `undefined` for any other.
|
|
5
|
+
*/
|
|
6
|
+
export declare function requestAnswerOf(data: unknown): StepUpRequestAnswer | undefined;
|
|
7
|
+
/** The confirm's answer out of the route's union, or `undefined` for any other. */
|
|
8
|
+
export declare function confirmAnswerOf(data: unknown): StepUpConfirmAnswer | undefined;
|
|
9
|
+
//# sourceMappingURL=answers.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"answers.d.ts","sourceRoot":"","sources":["../../../../src/session/react/step-up/answers.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EACX,mBAAmB,EACnB,mBAAmB,EACnB,MAAM,6BAA6B,CAAC;AAOrC;;;GAGG;AACH,wBAAgB,eAAe,CAC9B,IAAI,EAAE,OAAO,GACX,mBAAmB,GAAG,SAAS,CAIjC;AAED,mFAAmF;AACnF,wBAAgB,eAAe,CAC9B,IAAI,EAAE,OAAO,GACX,mBAAmB,GAAG,SAAS,CAIjC"}
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
import type { StepUpVia } from '../../model/second-factor';
|
|
2
|
+
import type { StepUpProps } from '../../model/step-up-props';
|
|
3
|
+
import type { StepUpDialogPhase } from './phase';
|
|
4
|
+
import type { useStepUp } from './use-step-up';
|
|
5
|
+
/** What a step-up dialog is given: the phase to show and the handlers. */
|
|
6
|
+
export interface StepUpDialogProps {
|
|
7
|
+
open: boolean;
|
|
8
|
+
phase: StepUpDialogPhase;
|
|
9
|
+
/** How the code is confirmed, once there is a challenge. */
|
|
10
|
+
via: StepUpVia | undefined;
|
|
11
|
+
/** The words of the code form (`stepUpProps`). */
|
|
12
|
+
props: StepUpProps;
|
|
13
|
+
/** The last refusal worded by the server. */
|
|
14
|
+
message: string | undefined;
|
|
15
|
+
busy: boolean;
|
|
16
|
+
/** The code was accepted and the action is being sent again. */
|
|
17
|
+
confirming: boolean;
|
|
18
|
+
onCancel(): void;
|
|
19
|
+
/** "Retry" after a refused request or an over challenge. */
|
|
20
|
+
onRetry(): void;
|
|
21
|
+
onSubmit(code: string): void;
|
|
22
|
+
/** "Resend code", for a mailed code only. */
|
|
23
|
+
onResend: (() => void) | undefined;
|
|
24
|
+
}
|
|
25
|
+
/** The dialog's props out of a step-up: plain, so any host can build them. */
|
|
26
|
+
export declare function dialogPropsOf(stepUp: ReturnType<typeof useStepUp>, open: boolean, cancel: () => void): StepUpDialogProps;
|
|
27
|
+
//# sourceMappingURL=dialog-props.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"dialog-props.d.ts","sourceRoot":"","sources":["../../../../src/session/react/step-up/dialog-props.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,2BAA2B,CAAC;AAC3D,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,2BAA2B,CAAC;AAC7D,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,SAAS,CAAC;AACjD,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,eAAe,CAAC;AAE/C,0EAA0E;AAC1E,MAAM,WAAW,iBAAiB;IACjC,IAAI,EAAE,OAAO,CAAC;IACd,KAAK,EAAE,iBAAiB,CAAC;IACzB,4DAA4D;IAC5D,GAAG,EAAE,SAAS,GAAG,SAAS,CAAC;IAC3B,kDAAkD;IAClD,KAAK,EAAE,WAAW,CAAC;IACnB,6CAA6C;IAC7C,OAAO,EAAE,MAAM,GAAG,SAAS,CAAC;IAC5B,IAAI,EAAE,OAAO,CAAC;IACd,gEAAgE;IAChE,UAAU,EAAE,OAAO,CAAC;IACpB,QAAQ,IAAI,IAAI,CAAC;IACjB,4DAA4D;IAC5D,OAAO,IAAI,IAAI,CAAC;IAChB,QAAQ,CAAC,IAAI,EAAE,MAAM,GAAG,IAAI,CAAC;IAC7B,6CAA6C;IAC7C,QAAQ,EAAE,CAAC,MAAM,IAAI,CAAC,GAAG,SAAS,CAAC;CACnC;AAED,8EAA8E;AAC9E,wBAAgB,aAAa,CAC5B,MAAM,EAAE,UAAU,CAAC,OAAO,SAAS,CAAC,EACpC,IAAI,EAAE,OAAO,EACb,MAAM,EAAE,MAAM,IAAI,GAChB,iBAAiB,CAcnB"}
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
export { confirmAnswerOf, requestAnswerOf } from './answers';
|
|
2
|
+
export { dialogPropsOf, type StepUpDialogProps } from './dialog-props';
|
|
3
|
+
export { asksStepUp, type StepUpDialogPhase, stepUpDialogPhase } from './phase';
|
|
4
|
+
export { type StepUpChannel, type StepUpOptions, useStepUp, } from './use-step-up';
|
|
5
|
+
export { type StepUpReplayOptions, useStepUpReplay, } from './use-step-up-replay';
|
|
6
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../src/session/react/step-up/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,eAAe,EAAE,eAAe,EAAE,MAAM,WAAW,CAAC;AAC7D,OAAO,EAAE,aAAa,EAAE,KAAK,iBAAiB,EAAE,MAAM,gBAAgB,CAAC;AACvE,OAAO,EAAE,UAAU,EAAE,KAAK,iBAAiB,EAAE,iBAAiB,EAAE,MAAM,SAAS,CAAC;AAChF,OAAO,EACN,KAAK,aAAa,EAClB,KAAK,aAAa,EAClB,SAAS,GACT,MAAM,eAAe,CAAC;AACvB,OAAO,EACN,KAAK,mBAAmB,EACxB,eAAe,GACf,MAAM,sBAAsB,CAAC"}
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import type { StepUpState } from '../../model/step-up';
|
|
2
|
+
/** Where a step-up is, as a dialog shows it. */
|
|
3
|
+
export type StepUpDialogPhase = 'asking' | 'failed' | 'code' | 'expired' | 'confirmed';
|
|
4
|
+
/** The phase a reducer state is in: what the dialog shows. */
|
|
5
|
+
export declare function stepUpDialogPhase(state: StepUpState): StepUpDialogPhase;
|
|
6
|
+
/** Whether an answer is a refusal asking for a step-up (`stepUp` set, not ok). */
|
|
7
|
+
export declare function asksStepUp(answer: unknown): boolean;
|
|
8
|
+
//# sourceMappingURL=phase.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"phase.d.ts","sourceRoot":"","sources":["../../../../src/session/react/step-up/phase.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,qBAAqB,CAAC;AAEvD,gDAAgD;AAChD,MAAM,MAAM,iBAAiB,GAC1B,QAAQ,GACR,QAAQ,GACR,MAAM,GACN,SAAS,GACT,WAAW,CAAC;AAEf,8DAA8D;AAC9D,wBAAgB,iBAAiB,CAAC,KAAK,EAAE,WAAW,GAAG,iBAAiB,CAKvE;AAED,kFAAkF;AAClF,wBAAgB,UAAU,CAAC,MAAM,EAAE,OAAO,GAAG,OAAO,CAInD"}
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
import { type StepUpOptions } from './use-step-up';
|
|
2
|
+
export interface StepUpReplayOptions<Action> extends Pick<StepUpOptions, 'request' | 'confirm'> {
|
|
3
|
+
/**
|
|
4
|
+
* The settled answer of the sensitive action. A refusal carrying `stepUp`
|
|
5
|
+
* opens the step-up; the first answer after the replay closes it.
|
|
6
|
+
*/
|
|
7
|
+
answer: unknown;
|
|
8
|
+
/** Sends the refused action again, once the session is confirmed. */
|
|
9
|
+
replay(): void;
|
|
10
|
+
/** The action that was refused, for `spendsCode`. */
|
|
11
|
+
action?: Action | undefined;
|
|
12
|
+
/**
|
|
13
|
+
* Whether the action carries a one-time code that a step-up by the
|
|
14
|
+
* second factor just spent. Such an action is not replayed: the dialog
|
|
15
|
+
* closes and `confirmedNotice` is true ("confirmed, type a new code").
|
|
16
|
+
*/
|
|
17
|
+
spendsCode?(action: Action): boolean;
|
|
18
|
+
}
|
|
19
|
+
/**
|
|
20
|
+
* The step-up a sensitive action asks for: an answer carrying `stepUp` opens
|
|
21
|
+
* it; once the session is confirmed the same action is sent again by itself
|
|
22
|
+
* (`replay`), except an action that `spendsCode` after a step-up by the
|
|
23
|
+
* second factor, whose code was just spent: the user types the next one
|
|
24
|
+
* (`confirmedNotice`). The dialog stays, saying so, until the replayed
|
|
25
|
+
* action is answered; if that is refused for a step-up again, it asks again.
|
|
26
|
+
* Generic over the host's `post`s, so each intent keeps its typed fields.
|
|
27
|
+
*
|
|
28
|
+
* @example
|
|
29
|
+
* const { open, dialogProps, cancel, confirmedNotice } = useStepUpReplay({
|
|
30
|
+
* answer: fetcher.data,
|
|
31
|
+
* replay: () => post(lastAction.current),
|
|
32
|
+
* request: { post: () => stepUpPost({ intent: 'request-step-up' }), answer, busy },
|
|
33
|
+
* confirm: { post: (f) => stepUpPost({ intent: 'confirm-step-up', ...f }), answer, busy },
|
|
34
|
+
* });
|
|
35
|
+
*/
|
|
36
|
+
export declare function useStepUpReplay<Action = never>({ answer, replay, action, spendsCode, request, confirm, }: StepUpReplayOptions<Action>): {
|
|
37
|
+
open: boolean;
|
|
38
|
+
/** True after a step-up by the second factor spent the action's own code. */
|
|
39
|
+
confirmedNotice: boolean;
|
|
40
|
+
dialogProps: import("./dialog-props").StepUpDialogProps;
|
|
41
|
+
/** Closes the dialog without sending the action again. */
|
|
42
|
+
cancel: () => void;
|
|
43
|
+
stepUp: {
|
|
44
|
+
phase: import("./phase").StepUpDialogPhase;
|
|
45
|
+
via: import("../../model").StepUpVia | undefined;
|
|
46
|
+
props: import("../../model").StepUpProps;
|
|
47
|
+
message: string | undefined;
|
|
48
|
+
busy: boolean;
|
|
49
|
+
start(): void;
|
|
50
|
+
submit(code: string): void;
|
|
51
|
+
release(): void;
|
|
52
|
+
};
|
|
53
|
+
};
|
|
54
|
+
//# sourceMappingURL=use-step-up-replay.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"use-step-up-replay.d.ts","sourceRoot":"","sources":["../../../../src/session/react/step-up/use-step-up-replay.ts"],"names":[],"mappings":"AAGA,OAAO,EAAE,KAAK,aAAa,EAAa,MAAM,eAAe,CAAC;AAE9D,MAAM,WAAW,mBAAmB,CAAC,MAAM,CAC1C,SAAQ,IAAI,CAAC,aAAa,EAAE,SAAS,GAAG,SAAS,CAAC;IAClD;;;OAGG;IACH,MAAM,EAAE,OAAO,CAAC;IAChB,qEAAqE;IACrE,MAAM,IAAI,IAAI,CAAC;IACf,qDAAqD;IACrD,MAAM,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;IAC5B;;;;OAIG;IACH,UAAU,CAAC,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC;CACrC;AAED;;;;;;;;;;;;;;;;GAgBG;AACH,wBAAgB,eAAe,CAAC,MAAM,GAAG,KAAK,EAAE,EAC/C,MAAM,EACN,MAAM,EACN,MAAM,EACN,UAAU,EACV,OAAO,EACP,OAAO,GACP,EAAE,mBAAmB,CAAC,MAAM,CAAC;;IAoE5B,6EAA6E;;;IAG7E,0DAA0D;;;;;;;;;;;;EAI3D"}
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
import type { StepUpVia } from '../../model/second-factor';
|
|
2
|
+
import type { StepUpConfirmAnswer, StepUpRequestAnswer } from '../../model/step-up-answers';
|
|
3
|
+
/**
|
|
4
|
+
* One step-up intent as the host posts it: its own `post` (so the fields stay
|
|
5
|
+
* typed by the host's action), the settled answer it got since it mounted
|
|
6
|
+
* (`undefined` before), and whether it is in flight. `reset` forgets the
|
|
7
|
+
* answer (a fetcher's `reset`).
|
|
8
|
+
*/
|
|
9
|
+
export interface StepUpChannel<Fields, Answer> {
|
|
10
|
+
post(fields: Fields): void;
|
|
11
|
+
readonly answer: Answer | undefined;
|
|
12
|
+
readonly busy: boolean;
|
|
13
|
+
reset?(): void;
|
|
14
|
+
}
|
|
15
|
+
export interface StepUpOptions {
|
|
16
|
+
/** Posts `{ intent: 'request-step-up' }`, to the route that serves `stepUpSteps().route`. */
|
|
17
|
+
request: StepUpChannel<Record<string, never>, StepUpRequestAnswer>;
|
|
18
|
+
/** Posts `{ intent: 'confirm-step-up', challenge, code, via }`. */
|
|
19
|
+
confirm: StepUpChannel<{
|
|
20
|
+
challenge: string;
|
|
21
|
+
code: string;
|
|
22
|
+
via: StepUpVia | undefined;
|
|
23
|
+
}, StepUpConfirmAnswer>;
|
|
24
|
+
/** Runs once the API accepted the code. */
|
|
25
|
+
onConfirmed(): void;
|
|
26
|
+
}
|
|
27
|
+
/**
|
|
28
|
+
* The step-up as the page lives it, on `stepUpReducer`: `start` asks for a
|
|
29
|
+
* challenge, `submit` posts the code, and once it is accepted `onConfirmed`
|
|
30
|
+
* runs. The challenge lives in the reducer's state and the channels' answers
|
|
31
|
+
* only; `release` forgets everything, and an answer that lands after it (a
|
|
32
|
+
* request or a code in flight when the host closed) is ignored.
|
|
33
|
+
*/
|
|
34
|
+
export declare function useStepUp({ request, confirm, onConfirmed }: StepUpOptions): {
|
|
35
|
+
phase: import("./phase").StepUpDialogPhase;
|
|
36
|
+
/** How the challenge held (or the last one) is confirmed. */
|
|
37
|
+
via: StepUpVia | undefined;
|
|
38
|
+
/** What a dialog words its texts from (`stepUpProps`). */
|
|
39
|
+
props: import("../../model").StepUpProps;
|
|
40
|
+
/** The last refusal worded by the server: the fallback of the dialog's own words. */
|
|
41
|
+
message: string | undefined;
|
|
42
|
+
/** A request or a code is in flight. */
|
|
43
|
+
busy: boolean;
|
|
44
|
+
/** Asks for a challenge: the first, or "Resend code" / "New code". */
|
|
45
|
+
start(): void;
|
|
46
|
+
/** Posts the code for the challenge held. */
|
|
47
|
+
submit(code: string): void;
|
|
48
|
+
/** Forgets the challenge, the answers and the errors. */
|
|
49
|
+
release(): void;
|
|
50
|
+
};
|
|
51
|
+
//# sourceMappingURL=use-step-up.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"use-step-up.d.ts","sourceRoot":"","sources":["../../../../src/session/react/step-up/use-step-up.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,2BAA2B,CAAC;AAE3D,OAAO,KAAK,EACX,mBAAmB,EACnB,mBAAmB,EACnB,MAAM,6BAA6B,CAAC;AAIrC;;;;;GAKG;AACH,MAAM,WAAW,aAAa,CAAC,MAAM,EAAE,MAAM;IAC5C,IAAI,CAAC,MAAM,EAAE,MAAM,GAAG,IAAI,CAAC;IAC3B,QAAQ,CAAC,MAAM,EAAE,MAAM,GAAG,SAAS,CAAC;IACpC,QAAQ,CAAC,IAAI,EAAE,OAAO,CAAC;IACvB,KAAK,CAAC,IAAI,IAAI,CAAC;CACf;AAED,MAAM,WAAW,aAAa;IAC7B,6FAA6F;IAC7F,OAAO,EAAE,aAAa,CAAC,MAAM,CAAC,MAAM,EAAE,KAAK,CAAC,EAAE,mBAAmB,CAAC,CAAC;IACnE,mEAAmE;IACnE,OAAO,EAAE,aAAa,CACrB;QAAE,SAAS,EAAE,MAAM,CAAC;QAAC,IAAI,EAAE,MAAM,CAAC;QAAC,GAAG,EAAE,SAAS,GAAG,SAAS,CAAA;KAAE,EAC/D,mBAAmB,CACnB,CAAC;IACF,2CAA2C;IAC3C,WAAW,IAAI,IAAI,CAAC;CACpB;AAED;;;;;;GAMG;AACH,wBAAgB,SAAS,CAAC,EAAE,OAAO,EAAE,OAAO,EAAE,WAAW,EAAE,EAAE,aAAa;;IA4BxE,6DAA6D;;IAE7D,0DAA0D;;IAE1D,qFAAqF;;IAErF,wCAAwC;;IAExC,sEAAsE;;IAMtE,6CAA6C;iBAChC,MAAM;IAKnB,yDAAyD;;EAU1D"}
|
|
@@ -43,6 +43,22 @@ export interface StepUpCall<L extends string> {
|
|
|
43
43
|
readonly request: Request;
|
|
44
44
|
readonly language: L;
|
|
45
45
|
}
|
|
46
|
+
/**
|
|
47
|
+
* What `StepUpSteps.route` calls for each intent: the app's own API calls,
|
|
48
|
+
* with the fields the page posted.
|
|
49
|
+
*/
|
|
50
|
+
export interface StepUpRun {
|
|
51
|
+
/** Asks the API for a challenge (`requestStepUp`). */
|
|
52
|
+
request(): Promise<{
|
|
53
|
+
readonly challenge: string;
|
|
54
|
+
readonly via: StepUpVia;
|
|
55
|
+
}>;
|
|
56
|
+
/** Confirms the code of the challenge (`confirmStepUp`). */
|
|
57
|
+
confirm(input: {
|
|
58
|
+
readonly challenge: string;
|
|
59
|
+
readonly code: string;
|
|
60
|
+
}): Promise<unknown>;
|
|
61
|
+
}
|
|
46
62
|
export interface StepUpSteps<L extends string> {
|
|
47
63
|
/**
|
|
48
64
|
* Starts a step-up (`requestStepUp`): the challenge and how it is
|
|
@@ -66,6 +82,15 @@ export interface StepUpSteps<L extends string> {
|
|
|
66
82
|
confirm(run: () => Promise<unknown>, options: StepUpCall<L> & {
|
|
67
83
|
readonly via?: StepUpVia | undefined;
|
|
68
84
|
}): Promise<StepUpConfirmAnswer | StepUpStayed<StepUpConfirmAnswer>>;
|
|
85
|
+
/**
|
|
86
|
+
* The whole action of a resource route that serves the step-up to any
|
|
87
|
+
* page: reads the same-site JSON body, runs `request` for
|
|
88
|
+
* `{ intent: 'request-step-up' }` and `confirm` for
|
|
89
|
+
* `{ intent: 'confirm-step-up', challenge, code, via? }`, and answers what
|
|
90
|
+
* those steps answer. Any other intent, or a confirm with no challenge or
|
|
91
|
+
* code, is a 400.
|
|
92
|
+
*/
|
|
93
|
+
route(run: StepUpRun, options: StepUpCall<L>): Promise<StepUpRequestAnswer | StepUpConfirmAnswer | StepUpStayed<StepUpRequestAnswer> | StepUpStayed<StepUpConfirmAnswer>>;
|
|
69
94
|
/** Whether `error` is the API asking for a step-up first. */
|
|
70
95
|
isStepUpRequired(error: unknown): boolean;
|
|
71
96
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"step-up-types.d.ts","sourceRoot":"","sources":["../../src/session/step-up-types.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,cAAc,CAAC;AACzC,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,qBAAqB,CAAC;AACxD,OAAO,KAAK,EAAE,WAAW,EAAE,UAAU,EAAE,MAAM,cAAc,CAAC;AAC5D,OAAO,KAAK,EACX,mBAAmB,EACnB,mBAAmB,EACnB,SAAS,EACT,MAAM,SAAS,CAAC;AAEjB,qEAAqE;AACrE,MAAM,WAAW,WAAY,SAAQ,WAAW;IAC/C,gFAAgF;IAChF,QAAQ,CAAC,cAAc,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;IAC7C,uJAAuJ;IACvJ,QAAQ,CAAC,aAAa,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;CAC5C;AAED,MAAM,WAAW,kBAAkB,CAAC,CAAC,SAAS,MAAM,EAAE,CAAC,GAAG,SAAS;IAClE;;;;;OAKG;IACH,QAAQ,CAAC,MAAM,EAAE,UAAU,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC;IAClC,+DAA+D;IAC/D,KAAK,CAAC,QAAQ,EAAE,CAAC,GAAG,MAAM,CAAC;IAC3B;;;OAGG;IACH,QAAQ,CAAC,MAAM,CAAC,EAAE,CAAC,CAAC,QAAQ,EAAE,CAAC,KAAK,MAAM,CAAC,GAAG,SAAS,CAAC;IACxD;;;;OAIG;IACH,QAAQ,CAAC,OAAO,CAAC,EACd,CAAC,CAAC,KAAK,EAAE,YAAY,EAAE,QAAQ,EAAE,CAAC,KAAK,MAAM,GAAG,SAAS,CAAC,GAC1D,SAAS,CAAC;IACb,QAAQ,CAAC,KAAK,CAAC,EAAE,WAAW,GAAG,SAAS,CAAC;CACzC;AAED,2EAA2E;AAC3E,MAAM,MAAM,YAAY,CAAC,CAAC,IAAI,UAAU,CAAC,OAAO,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC;AAEzD;;;;GAIG;AACH,MAAM,WAAW,UAAU,CAAC,CAAC,SAAS,MAAM;IAC3C,QAAQ,CAAC,OAAO,EAAE,OAAO,CAAC;IAC1B,QAAQ,CAAC,QAAQ,EAAE,CAAC,CAAC;CACrB;AAED,MAAM,WAAW,WAAW,CAAC,CAAC,SAAS,MAAM;IAC5C;;;;;;;OAOG;IACH,OAAO,CACN,GAAG,EAAE,MAAM,OAAO,CAAC;QAAE,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAC;QAAC,QAAQ,CAAC,GAAG,EAAE,SAAS,CAAA;KAAE,CAAC,EAC3E,OAAO,EAAE,UAAU,CAAC,CAAC,CAAC,GACpB,OAAO,CAAC,mBAAmB,GAAG,YAAY,CAAC,mBAAmB,CAAC,CAAC,CAAC;IACpE;;;;;;OAMG;IACH,OAAO,CACN,GAAG,EAAE,MAAM,OAAO,CAAC,OAAO,CAAC,EAC3B,OAAO,EAAE,UAAU,CAAC,CAAC,CAAC,GAAG;QAAE,QAAQ,CAAC,GAAG,CAAC,EAAE,SAAS,GAAG,SAAS,CAAA;KAAE,GAC/D,OAAO,CAAC,mBAAmB,GAAG,YAAY,CAAC,mBAAmB,CAAC,CAAC,CAAC;IACpE,6DAA6D;IAC7D,gBAAgB,CAAC,KAAK,EAAE,OAAO,GAAG,OAAO,CAAC;CAC1C"}
|
|
1
|
+
{"version":3,"file":"step-up-types.d.ts","sourceRoot":"","sources":["../../src/session/step-up-types.ts"],"names":[],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"step-up.d.ts","sourceRoot":"","sources":["../../src/session/step-up.ts"],"names":[],"mappings":"AAkBA,OAAO,KAAK,
|
|
1
|
+
{"version":3,"file":"step-up.d.ts","sourceRoot":"","sources":["../../src/session/step-up.ts"],"names":[],"mappings":"AAkBA,OAAO,KAAK,EAGX,WAAW,EACX,kBAAkB,EAClB,MAAM,iBAAiB,CAAC;AAiMzB;;;;;;;;;;;;;GAaG;AACH,wBAAgB,WAAW,CAAC,CAAC,SAAS,MAAM,EAAE,CAAC,GAAG,SAAS,EAC1D,OAAO,EAAE,kBAAkB,CAAC,CAAC,EAAE,CAAC,CAAC,GAC/B,WAAW,CAAC,CAAC,CAAC,CAShB"}
|