@leancodepl/kratos 9.2.0 → 9.2.1
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 +82 -9
- package/index.cjs.js +33 -28
- package/index.esm.js +34 -29
- package/package.json +2 -2
- package/src/lib/hooks/useFlowManager.d.ts +2 -1
- package/src/lib/utils/errors.d.ts +1 -4
package/README.md
CHANGED
|
@@ -71,16 +71,24 @@ Manages Ory Kratos session and identity state with React Query integration.
|
|
|
71
71
|
To use the library, you need to create new instance of Kratos client with `mkKratos` factory:
|
|
72
72
|
|
|
73
73
|
```typescript
|
|
74
|
-
//
|
|
75
|
-
|
|
76
|
-
import { queryClient } from "./queryService"
|
|
74
|
+
// traits.ts
|
|
77
75
|
|
|
78
|
-
const traitsConfig = {
|
|
76
|
+
export const traitsConfig = {
|
|
79
77
|
Email: { trait: "email", type: "string" },
|
|
80
78
|
GivenName: { trait: "given_name", type: "string" },
|
|
81
79
|
RegulationsAccepted: { trait: "regulations_accepted", type: "boolean" },
|
|
82
80
|
} as const
|
|
83
81
|
|
|
82
|
+
export type AuthTraitsConfig = typeof traitsConfig
|
|
83
|
+
```
|
|
84
|
+
|
|
85
|
+
```typescript
|
|
86
|
+
// kratosService.ts
|
|
87
|
+
|
|
88
|
+
import { environment } from "./environments"
|
|
89
|
+
import { queryClient } from "./queryService"
|
|
90
|
+
import { traitsConfig } from "./traits"
|
|
91
|
+
|
|
84
92
|
const {
|
|
85
93
|
session: { sessionManager },
|
|
86
94
|
providers: { KratosProviders },
|
|
@@ -99,9 +107,6 @@ export { KratosProviders }
|
|
|
99
107
|
|
|
100
108
|
// flows
|
|
101
109
|
export { LoginFlow, RecoveryFlow, RegistrationFlow, SettingsFlow, useLogout, VerificationFlow }
|
|
102
|
-
|
|
103
|
-
// traits
|
|
104
|
-
export type AuthTraitsConfig = typeof traitsConfig
|
|
105
110
|
```
|
|
106
111
|
|
|
107
112
|
And then wrap your app with `KratosProviders` from `mkKratos`:
|
|
@@ -128,6 +133,74 @@ function App() {
|
|
|
128
133
|
}
|
|
129
134
|
```
|
|
130
135
|
|
|
136
|
+
### Extending session manager
|
|
137
|
+
|
|
138
|
+
You can add new functionalities to the session manager by extending `BaseSessionManager` class:
|
|
139
|
+
|
|
140
|
+
```typescript
|
|
141
|
+
// session.ts
|
|
142
|
+
|
|
143
|
+
import { BaseSessionManager } from "@leancodepl/kratos"
|
|
144
|
+
import { queryClient } from "./queryService"
|
|
145
|
+
import type { AuthTraitsConfig } from "./traits"
|
|
146
|
+
|
|
147
|
+
export class SessionManager extends BaseSessionManager<AuthTraitsConfig> {
|
|
148
|
+
getTraits = async () => {
|
|
149
|
+
const identity = await this.getIdentity()
|
|
150
|
+
|
|
151
|
+
return identity?.traits
|
|
152
|
+
}
|
|
153
|
+
|
|
154
|
+
getEmail = async () => {
|
|
155
|
+
const traits = await this.getTraits()
|
|
156
|
+
|
|
157
|
+
return traits?.email
|
|
158
|
+
}
|
|
159
|
+
|
|
160
|
+
// Hooks for React components
|
|
161
|
+
|
|
162
|
+
useTraits = () => {
|
|
163
|
+
const { identity, isLoading, error } = this.useIdentity()
|
|
164
|
+
|
|
165
|
+
return {
|
|
166
|
+
traits: identity?.traits,
|
|
167
|
+
isLoading,
|
|
168
|
+
error,
|
|
169
|
+
}
|
|
170
|
+
}
|
|
171
|
+
|
|
172
|
+
useEmail = () => {
|
|
173
|
+
const { traits, isLoading, error } = this.useTraits()
|
|
174
|
+
|
|
175
|
+
return {
|
|
176
|
+
email: traits?.email,
|
|
177
|
+
isLoading,
|
|
178
|
+
error,
|
|
179
|
+
}
|
|
180
|
+
}
|
|
181
|
+
}
|
|
182
|
+
```
|
|
183
|
+
|
|
184
|
+
```typescript
|
|
185
|
+
// kratosService.ts
|
|
186
|
+
|
|
187
|
+
import { environment } from "./environments"
|
|
188
|
+
import { queryClient } from "./queryService"
|
|
189
|
+
import { SessionManager } from "./session"
|
|
190
|
+
import { traitsConfig } from "./traits"
|
|
191
|
+
|
|
192
|
+
const {
|
|
193
|
+
session: { sessionManager },
|
|
194
|
+
providers: { KratosProviders },
|
|
195
|
+
flows: { LoginFlow, RegistrationFlow, SettingsFlow, VerificationFlow, RecoveryFlow, useLogout },
|
|
196
|
+
} = mkKratos({
|
|
197
|
+
queryClient,
|
|
198
|
+
basePath: environment.authUrl,
|
|
199
|
+
traits: traitsConfig,
|
|
200
|
+
SessionManager,
|
|
201
|
+
})
|
|
202
|
+
```
|
|
203
|
+
|
|
131
204
|
### Session Management
|
|
132
205
|
|
|
133
206
|
```tsx
|
|
@@ -352,7 +425,7 @@ export const Input = ({ errors, ...props }: InputProps) => (
|
|
|
352
425
|
```tsx
|
|
353
426
|
import { loginFlow } from "@leancodepl/kratos"
|
|
354
427
|
import { LoginFlow, getErrorMessage } from "./kratosService"
|
|
355
|
-
import type { AuthTraitsConfig } from "./
|
|
428
|
+
import type { AuthTraitsConfig } from "./traits"
|
|
356
429
|
|
|
357
430
|
function LoginPage() {
|
|
358
431
|
return (
|
|
@@ -481,7 +554,7 @@ function ChooseMethodForm(props: loginFlow.ChooseMethodFormProps) {
|
|
|
481
554
|
```tsx
|
|
482
555
|
import { registrationFlow } from "@leancodepl/kratos"
|
|
483
556
|
import { RegistrationFlow, getErrorMessage } from "./kratosService"
|
|
484
|
-
import type { AuthTraitsConfig } from "./
|
|
557
|
+
import type { AuthTraitsConfig } from "./traits"
|
|
485
558
|
|
|
486
559
|
function RegisterPage() {
|
|
487
560
|
return (
|
package/index.cjs.js
CHANGED
|
@@ -32,6 +32,29 @@ var GetFlowError;
|
|
|
32
32
|
GetFlowError[GetFlowError["FlowRestartRequired"] = 1] = "FlowRestartRequired";
|
|
33
33
|
})(GetFlowError || (GetFlowError = {}));
|
|
34
34
|
|
|
35
|
+
var kratosSessionContext = /*#__PURE__*/ react.createContext(undefined);
|
|
36
|
+
function useKratosSessionContext() {
|
|
37
|
+
var context = react.useContext(kratosSessionContext);
|
|
38
|
+
if (context === undefined) {
|
|
39
|
+
throw new Error("useKratosSessionContext must be used within a KratosSessionContextProvider");
|
|
40
|
+
}
|
|
41
|
+
return context;
|
|
42
|
+
}
|
|
43
|
+
function KratosSessionProvider(param) {
|
|
44
|
+
var children = param.children, sessionManager = param.sessionManager;
|
|
45
|
+
var kratosSessionContextData = react.useMemo(function() {
|
|
46
|
+
return {
|
|
47
|
+
sessionManager: sessionManager
|
|
48
|
+
};
|
|
49
|
+
}, [
|
|
50
|
+
sessionManager
|
|
51
|
+
]);
|
|
52
|
+
return /*#__PURE__*/ jsxRuntime.jsx(kratosSessionContext.Provider, {
|
|
53
|
+
value: kratosSessionContextData,
|
|
54
|
+
children: children
|
|
55
|
+
});
|
|
56
|
+
}
|
|
57
|
+
|
|
35
58
|
function _array_like_to_array$b(arr, len) {
|
|
36
59
|
if (len == null || len > arr.length) len = arr.length;
|
|
37
60
|
for(var i = 0, arr2 = new Array(len); i < len; i++)arr2[i] = arr[i];
|
|
@@ -79,15 +102,18 @@ function _unsupported_iterable_to_array$b(o, minLen) {
|
|
|
79
102
|
if (n === "Arguments" || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n)) return _array_like_to_array$b(o, minLen);
|
|
80
103
|
}
|
|
81
104
|
var useFlowManager = function(param) {
|
|
82
|
-
var initialFlowId = param.initialFlowId, currentFlowId = param.currentFlowId, error = param.error, onFlowRestart = param.onFlowRestart, createFlow = param.createFlow, setFlowId = param.setFlowId;
|
|
105
|
+
var initialFlowId = param.initialFlowId, currentFlowId = param.currentFlowId, error = param.error, onFlowRestart = param.onFlowRestart, createFlow = param.createFlow, setFlowId = param.setFlowId, waitForSession = param.waitForSession;
|
|
83
106
|
var _useState = _sliced_to_array$7(react.useState(false), 2), initialFlowIdUsed = _useState[0], setInitialFlowIdUsed = _useState[1];
|
|
84
107
|
var _useState1 = _sliced_to_array$7(react.useState(initialFlowId), 2), prevInitialFlowId = _useState1[0], setPrevInitialFlowId = _useState1[1];
|
|
108
|
+
var sessionManager = useKratosSessionContext().sessionManager;
|
|
109
|
+
var isLoading = sessionManager.useSession().isLoading;
|
|
85
110
|
if (prevInitialFlowId !== initialFlowId) {
|
|
86
111
|
setInitialFlowIdUsed(false);
|
|
87
112
|
setPrevInitialFlowId(initialFlowId);
|
|
88
113
|
}
|
|
114
|
+
var shouldWait = !!waitForSession && isLoading;
|
|
89
115
|
react.useEffect(function() {
|
|
90
|
-
if (currentFlowId) {
|
|
116
|
+
if (currentFlowId || shouldWait) {
|
|
91
117
|
return;
|
|
92
118
|
}
|
|
93
119
|
if (initialFlowId && !initialFlowIdUsed) {
|
|
@@ -102,7 +128,8 @@ var useFlowManager = function(param) {
|
|
|
102
128
|
currentFlowId,
|
|
103
129
|
setFlowId,
|
|
104
130
|
onFlowRestart,
|
|
105
|
-
initialFlowIdUsed
|
|
131
|
+
initialFlowIdUsed,
|
|
132
|
+
shouldWait
|
|
106
133
|
]);
|
|
107
134
|
react.useEffect(function() {
|
|
108
135
|
if (error && error.cause === GetFlowError.FlowRestartRequired) {
|
|
@@ -6982,7 +7009,7 @@ var mapToAuthError = function(error) {
|
|
|
6982
7009
|
return createRecoveryFlowError("InvalidRecoveryCodeOrAlreadyUsed");
|
|
6983
7010
|
// Verification Flow Errors
|
|
6984
7011
|
case 4070001:
|
|
6985
|
-
return createVerificationFlowError("
|
|
7012
|
+
return createVerificationFlowError("InvalidVerificationCodeOrAlreadyUsed");
|
|
6986
7013
|
case 4070002:
|
|
6987
7014
|
return createVerificationFlowError("VerificationRequestAlreadyCompletedSuccessfully");
|
|
6988
7015
|
case 4070003:
|
|
@@ -7374,29 +7401,6 @@ function KratosClientProvider(param) {
|
|
|
7374
7401
|
});
|
|
7375
7402
|
}
|
|
7376
7403
|
|
|
7377
|
-
var kratosSessionContext = /*#__PURE__*/ react.createContext(undefined);
|
|
7378
|
-
function useKratosSessionContext() {
|
|
7379
|
-
var context = react.useContext(kratosSessionContext);
|
|
7380
|
-
if (context === undefined) {
|
|
7381
|
-
throw new Error("useKratosSessionContext must be used within a KratosSessionContextProvider");
|
|
7382
|
-
}
|
|
7383
|
-
return context;
|
|
7384
|
-
}
|
|
7385
|
-
function KratosSessionProvider(param) {
|
|
7386
|
-
var children = param.children, sessionManager = param.sessionManager;
|
|
7387
|
-
var kratosSessionContextData = react.useMemo(function() {
|
|
7388
|
-
return {
|
|
7389
|
-
sessionManager: sessionManager
|
|
7390
|
-
};
|
|
7391
|
-
}, [
|
|
7392
|
-
sessionManager
|
|
7393
|
-
]);
|
|
7394
|
-
return /*#__PURE__*/ jsxRuntime.jsx(kratosSessionContext.Provider, {
|
|
7395
|
-
value: kratosSessionContextData,
|
|
7396
|
-
children: children
|
|
7397
|
-
});
|
|
7398
|
-
}
|
|
7399
|
-
|
|
7400
7404
|
var emailVerificationFormContext = /*#__PURE__*/ react.createContext(undefined);
|
|
7401
7405
|
function EmailVerificationFormProvider(param) {
|
|
7402
7406
|
var children = param.children, emailVerificationForm = param.emailVerificationForm;
|
|
@@ -10638,7 +10642,8 @@ function LoginFlowWrapper(param) {
|
|
|
10638
10642
|
error: getLoginFlowError !== null && getLoginFlowError !== void 0 ? getLoginFlowError : undefined,
|
|
10639
10643
|
onFlowRestart: onFlowRestart,
|
|
10640
10644
|
createFlow: createLoginFlow,
|
|
10641
|
-
setFlowId: setLoginFlowId
|
|
10645
|
+
setFlowId: setLoginFlowId,
|
|
10646
|
+
waitForSession: true
|
|
10642
10647
|
});
|
|
10643
10648
|
react.useEffect(function() {
|
|
10644
10649
|
if (isSessionAlreadyAvailable(createLoginFlowError)) {
|
package/index.esm.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { jsx, jsxs, Fragment } from 'react/jsx-runtime';
|
|
2
|
-
import {
|
|
2
|
+
import { useContext, createContext, useMemo, useState, useEffect, useCallback } from 'react';
|
|
3
3
|
import * as Slot from '@radix-ui/react-slot';
|
|
4
4
|
import { useQueryClient, useMutation, useQuery } from '@tanstack/react-query';
|
|
5
5
|
import { useForm } from '@tanstack/react-form';
|
|
@@ -11,6 +11,29 @@ var GetFlowError;
|
|
|
11
11
|
GetFlowError[GetFlowError["FlowRestartRequired"] = 1] = "FlowRestartRequired";
|
|
12
12
|
})(GetFlowError || (GetFlowError = {}));
|
|
13
13
|
|
|
14
|
+
var kratosSessionContext = /*#__PURE__*/ createContext(undefined);
|
|
15
|
+
function useKratosSessionContext() {
|
|
16
|
+
var context = useContext(kratosSessionContext);
|
|
17
|
+
if (context === undefined) {
|
|
18
|
+
throw new Error("useKratosSessionContext must be used within a KratosSessionContextProvider");
|
|
19
|
+
}
|
|
20
|
+
return context;
|
|
21
|
+
}
|
|
22
|
+
function KratosSessionProvider(param) {
|
|
23
|
+
var children = param.children, sessionManager = param.sessionManager;
|
|
24
|
+
var kratosSessionContextData = useMemo(function() {
|
|
25
|
+
return {
|
|
26
|
+
sessionManager: sessionManager
|
|
27
|
+
};
|
|
28
|
+
}, [
|
|
29
|
+
sessionManager
|
|
30
|
+
]);
|
|
31
|
+
return /*#__PURE__*/ jsx(kratosSessionContext.Provider, {
|
|
32
|
+
value: kratosSessionContextData,
|
|
33
|
+
children: children
|
|
34
|
+
});
|
|
35
|
+
}
|
|
36
|
+
|
|
14
37
|
function _array_like_to_array$b(arr, len) {
|
|
15
38
|
if (len == null || len > arr.length) len = arr.length;
|
|
16
39
|
for(var i = 0, arr2 = new Array(len); i < len; i++)arr2[i] = arr[i];
|
|
@@ -58,15 +81,18 @@ function _unsupported_iterable_to_array$b(o, minLen) {
|
|
|
58
81
|
if (n === "Arguments" || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n)) return _array_like_to_array$b(o, minLen);
|
|
59
82
|
}
|
|
60
83
|
var useFlowManager = function(param) {
|
|
61
|
-
var initialFlowId = param.initialFlowId, currentFlowId = param.currentFlowId, error = param.error, onFlowRestart = param.onFlowRestart, createFlow = param.createFlow, setFlowId = param.setFlowId;
|
|
84
|
+
var initialFlowId = param.initialFlowId, currentFlowId = param.currentFlowId, error = param.error, onFlowRestart = param.onFlowRestart, createFlow = param.createFlow, setFlowId = param.setFlowId, waitForSession = param.waitForSession;
|
|
62
85
|
var _useState = _sliced_to_array$7(useState(false), 2), initialFlowIdUsed = _useState[0], setInitialFlowIdUsed = _useState[1];
|
|
63
86
|
var _useState1 = _sliced_to_array$7(useState(initialFlowId), 2), prevInitialFlowId = _useState1[0], setPrevInitialFlowId = _useState1[1];
|
|
87
|
+
var sessionManager = useKratosSessionContext().sessionManager;
|
|
88
|
+
var isLoading = sessionManager.useSession().isLoading;
|
|
64
89
|
if (prevInitialFlowId !== initialFlowId) {
|
|
65
90
|
setInitialFlowIdUsed(false);
|
|
66
91
|
setPrevInitialFlowId(initialFlowId);
|
|
67
92
|
}
|
|
93
|
+
var shouldWait = !!waitForSession && isLoading;
|
|
68
94
|
useEffect(function() {
|
|
69
|
-
if (currentFlowId) {
|
|
95
|
+
if (currentFlowId || shouldWait) {
|
|
70
96
|
return;
|
|
71
97
|
}
|
|
72
98
|
if (initialFlowId && !initialFlowIdUsed) {
|
|
@@ -81,7 +107,8 @@ var useFlowManager = function(param) {
|
|
|
81
107
|
currentFlowId,
|
|
82
108
|
setFlowId,
|
|
83
109
|
onFlowRestart,
|
|
84
|
-
initialFlowIdUsed
|
|
110
|
+
initialFlowIdUsed,
|
|
111
|
+
shouldWait
|
|
85
112
|
]);
|
|
86
113
|
useEffect(function() {
|
|
87
114
|
if (error && error.cause === GetFlowError.FlowRestartRequired) {
|
|
@@ -6961,7 +6988,7 @@ var mapToAuthError = function(error) {
|
|
|
6961
6988
|
return createRecoveryFlowError("InvalidRecoveryCodeOrAlreadyUsed");
|
|
6962
6989
|
// Verification Flow Errors
|
|
6963
6990
|
case 4070001:
|
|
6964
|
-
return createVerificationFlowError("
|
|
6991
|
+
return createVerificationFlowError("InvalidVerificationCodeOrAlreadyUsed");
|
|
6965
6992
|
case 4070002:
|
|
6966
6993
|
return createVerificationFlowError("VerificationRequestAlreadyCompletedSuccessfully");
|
|
6967
6994
|
case 4070003:
|
|
@@ -7353,29 +7380,6 @@ function KratosClientProvider(param) {
|
|
|
7353
7380
|
});
|
|
7354
7381
|
}
|
|
7355
7382
|
|
|
7356
|
-
var kratosSessionContext = /*#__PURE__*/ createContext(undefined);
|
|
7357
|
-
function useKratosSessionContext() {
|
|
7358
|
-
var context = useContext(kratosSessionContext);
|
|
7359
|
-
if (context === undefined) {
|
|
7360
|
-
throw new Error("useKratosSessionContext must be used within a KratosSessionContextProvider");
|
|
7361
|
-
}
|
|
7362
|
-
return context;
|
|
7363
|
-
}
|
|
7364
|
-
function KratosSessionProvider(param) {
|
|
7365
|
-
var children = param.children, sessionManager = param.sessionManager;
|
|
7366
|
-
var kratosSessionContextData = useMemo(function() {
|
|
7367
|
-
return {
|
|
7368
|
-
sessionManager: sessionManager
|
|
7369
|
-
};
|
|
7370
|
-
}, [
|
|
7371
|
-
sessionManager
|
|
7372
|
-
]);
|
|
7373
|
-
return /*#__PURE__*/ jsx(kratosSessionContext.Provider, {
|
|
7374
|
-
value: kratosSessionContextData,
|
|
7375
|
-
children: children
|
|
7376
|
-
});
|
|
7377
|
-
}
|
|
7378
|
-
|
|
7379
7383
|
var emailVerificationFormContext = /*#__PURE__*/ createContext(undefined);
|
|
7380
7384
|
function EmailVerificationFormProvider(param) {
|
|
7381
7385
|
var children = param.children, emailVerificationForm = param.emailVerificationForm;
|
|
@@ -10617,7 +10621,8 @@ function LoginFlowWrapper(param) {
|
|
|
10617
10621
|
error: getLoginFlowError !== null && getLoginFlowError !== void 0 ? getLoginFlowError : undefined,
|
|
10618
10622
|
onFlowRestart: onFlowRestart,
|
|
10619
10623
|
createFlow: createLoginFlow,
|
|
10620
|
-
setFlowId: setLoginFlowId
|
|
10624
|
+
setFlowId: setLoginFlowId,
|
|
10625
|
+
waitForSession: true
|
|
10621
10626
|
});
|
|
10622
10627
|
useEffect(function() {
|
|
10623
10628
|
if (isSessionAlreadyAvailable(createLoginFlowError)) {
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@leancodepl/kratos",
|
|
3
|
-
"version": "9.2.
|
|
3
|
+
"version": "9.2.1",
|
|
4
4
|
"license": "Apache-2.0",
|
|
5
5
|
"publishConfig": {
|
|
6
6
|
"access": "public",
|
|
@@ -10,7 +10,7 @@
|
|
|
10
10
|
"node": ">=18.0.0"
|
|
11
11
|
},
|
|
12
12
|
"dependencies": {
|
|
13
|
-
"@leancodepl/utils": "9.2.
|
|
13
|
+
"@leancodepl/utils": "9.2.1",
|
|
14
14
|
"@radix-ui/react-slot": ">=1.0.0",
|
|
15
15
|
"@tanstack/react-form": ">=1.0.0",
|
|
16
16
|
"@tanstack/react-query": ">=5.0.0"
|
|
@@ -5,6 +5,7 @@ type UseFlowManagerProps = {
|
|
|
5
5
|
onFlowRestart?: () => void;
|
|
6
6
|
createFlow: () => void;
|
|
7
7
|
setFlowId: (flowId: string | undefined) => void;
|
|
8
|
+
waitForSession?: boolean;
|
|
8
9
|
};
|
|
9
|
-
export declare const useFlowManager: ({ initialFlowId, currentFlowId, error, onFlowRestart, createFlow, setFlowId, }: UseFlowManagerProps) => void;
|
|
10
|
+
export declare const useFlowManager: ({ initialFlowId, currentFlowId, error, onFlowRestart, createFlow, setFlowId, waitForSession, }: UseFlowManagerProps) => void;
|
|
10
11
|
export {};
|
|
@@ -353,7 +353,7 @@ export declare const mapToAuthError: (error: UiTextError) => {
|
|
|
353
353
|
id: "RecoveryFlowError_InvalidRecoveryCodeOrAlreadyUsed";
|
|
354
354
|
originalError: UiTextError;
|
|
355
355
|
} | {
|
|
356
|
-
id: "
|
|
356
|
+
id: "VerificationFlowError_InvalidVerificationCodeOrAlreadyUsed";
|
|
357
357
|
originalError: UiTextError;
|
|
358
358
|
} | {
|
|
359
359
|
id: "VerificationFlowError_VerificationRequestAlreadyCompletedSuccessfully";
|
|
@@ -371,9 +371,6 @@ export declare const mapToAuthError: (error: UiTextError) => {
|
|
|
371
371
|
} | {
|
|
372
372
|
id: "VerificationFlowError_VerificationFlowExpired";
|
|
373
373
|
originalError: UiTextError;
|
|
374
|
-
} | {
|
|
375
|
-
id: "VerificationFlowError_InvalidVerificationCodeOrAlreadyUsed";
|
|
376
|
-
originalError: UiTextError;
|
|
377
374
|
} | {
|
|
378
375
|
id: "Error_Generic_WithContext";
|
|
379
376
|
context: {
|