@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 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
- // kratosService.ts
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 "./kratosService"
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 "./kratosService"
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("InvalidVerifivactionCodeOrAlreadyUsed");
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 { useState, useEffect, useMemo, useContext, createContext, useCallback } from 'react';
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("InvalidVerifivactionCodeOrAlreadyUsed");
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.0",
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.0",
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: "VerificationFlowError_InvalidVerifivactionCodeOrAlreadyUsed";
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: {