@leancodepl/kratos 9.2.0 → 9.3.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 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
@@ -161,6 +234,7 @@ import { LoginFlow } from "./kratosService"
161
234
  function LoginPage() {
162
235
  return (
163
236
  <LoginFlow
237
+ loaderComponent={Loader}
164
238
  chooseMethodForm={ChooseMethodForm}
165
239
  secondFactorForm={SecondFactorForm}
166
240
  secondFactorEmailForm={SecondFactorEmailForm}
@@ -352,7 +426,7 @@ export const Input = ({ errors, ...props }: InputProps) => (
352
426
  ```tsx
353
427
  import { loginFlow } from "@leancodepl/kratos"
354
428
  import { LoginFlow, getErrorMessage } from "./kratosService"
355
- import type { AuthTraitsConfig } from "./kratosService"
429
+ import type { AuthTraitsConfig } from "./traits"
356
430
 
357
431
  function LoginPage() {
358
432
  return (
@@ -364,28 +438,30 @@ function LoginPage() {
364
438
  }
365
439
 
366
440
  function ChooseMethodForm(props: loginFlow.ChooseMethodFormProps) {
367
- if (props.isLoading) {
368
- return <p>Loading login methods...</p>
369
- }
370
-
371
- const { Password, Google, Passkey, Apple, Facebook, errors, isSubmitting, isValidating } = props
441
+ const { errors, isSubmitting, isValidating } = props
372
442
 
373
443
  if (props.isRefresh) {
374
- const { identifier } = props
444
+ const { passwordFields, Google, Passkey, Apple, Facebook, identifier } = props
375
445
 
376
446
  return (
377
447
  <div>
378
- <h2>
379
- Complete login process as <strong>{identifier}</strong>
380
- </h2>
381
-
382
- {Password && (
383
- <Password>
384
- <input placeholder="Password" />
385
- </Password>
448
+ {identifier && (
449
+ <h2>
450
+ Complete login process as <strong>{identifier}</strong>
451
+ </h2>
386
452
  )}
387
453
 
388
- <button type="submit">Login</button>
454
+ {passwordFields && (
455
+ <>
456
+ <passwordFields.Password>
457
+ <input placeholder="Password" />
458
+ </passwordFields.Password>
459
+
460
+ <passwordFields.Submit>
461
+ <button>Login</button>
462
+ </passwordFields.Submit>
463
+ </>
464
+ )}
389
465
 
390
466
  {Google && (
391
467
  <Google>
@@ -422,47 +498,43 @@ function ChooseMethodForm(props: loginFlow.ChooseMethodFormProps) {
422
498
  )
423
499
  }
424
500
 
425
- const { Identifier } = props
501
+ const {
502
+ passwordFields: { Identifier, Password, Submit },
503
+ Google,
504
+ Passkey,
505
+ Apple,
506
+ Facebook,
507
+ } = props
426
508
 
427
509
  return (
428
510
  <div>
429
- {Identifier && (
430
- <Identifier>
431
- <input placeholder="Identifier" />
432
- </Identifier>
433
- )}
511
+ <Identifier>
512
+ <input placeholder="Identifier" />
513
+ </Identifier>
434
514
 
435
- {Password && (
436
- <Password>
437
- <input placeholder="Password" />
438
- </Password>
439
- )}
515
+ <Password>
516
+ <input placeholder="Password" />
517
+ </Password>
440
518
 
441
- <button type="submit">Login</button>
519
+ <Submit>
520
+ <button>Login</button>
521
+ </Submit>
442
522
 
443
- {Google && (
444
- <Google>
445
- <button>Sign in with Google</button>
446
- </Google>
447
- )}
523
+ <Google>
524
+ <button>Sign in with Google</button>
525
+ </Google>
448
526
 
449
- {Apple && (
450
- <Apple>
451
- <button>Sign in with Apple</button>
452
- </Apple>
453
- )}
527
+ <Apple>
528
+ <button>Sign in with Apple</button>
529
+ </Apple>
454
530
 
455
- {Facebook && (
456
- <Facebook>
457
- <button>Sign in with Facebook</button>
458
- </Facebook>
459
- )}
531
+ <Facebook>
532
+ <button>Sign in with Facebook</button>
533
+ </Facebook>
460
534
 
461
- {Passkey && (
462
- <Passkey>
463
- <button>Sign in with Passkey</button>
464
- </Passkey>
465
- )}
535
+ <Passkey>
536
+ <button>Sign in with Passkey</button>
537
+ </Passkey>
466
538
 
467
539
  {errors && errors.length > 0 && (
468
540
  <div>
@@ -481,7 +553,7 @@ function ChooseMethodForm(props: loginFlow.ChooseMethodFormProps) {
481
553
  ```tsx
482
554
  import { registrationFlow } from "@leancodepl/kratos"
483
555
  import { RegistrationFlow, getErrorMessage } from "./kratosService"
484
- import type { AuthTraitsConfig } from "./kratosService"
556
+ import type { AuthTraitsConfig } from "./traits"
485
557
 
486
558
  function RegisterPage() {
487
559
  return (