cauthy-auth 0.11.0 → 0.13.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/dist/react.d.mts CHANGED
@@ -212,6 +212,12 @@ type AuthField = 'email' | 'password' | 'newPassword' | 'name' | 'code';
212
212
 
213
213
  /** Whether this browser can use a passkey at all. */
214
214
  declare function canUsePasskeys(): boolean;
215
+ /**
216
+ * Whether this browser offers passkeys in the autofill of a field marked
217
+ * `autocomplete="username webauthn"`, so the person picks one without
218
+ * looking for a button.
219
+ */
220
+ declare function canAutofillPasskeys(): Promise<boolean>;
215
221
 
216
222
  /** What went wrong, in a form the screen can show. */
217
223
  interface AuthError {
@@ -252,6 +258,13 @@ interface AuthMethods {
252
258
  * page that cannot, or a browser that refuses to here, sends the person.
253
259
  */
254
260
  passkeyOnCauthy: boolean;
261
+ /**
262
+ * The workspace's Cloudflare Turnstile site key, when it asks for the
263
+ * challenge: signing in, creating an account, and asking for a sign-in link
264
+ * or a new password then take its answer (`captchaToken`). The ready-made
265
+ * forms show it themselves.
266
+ */
267
+ captchaSiteKey?: string;
255
268
  }
256
269
  /** A passkey of the signed-in account. Moments are UTC. */
257
270
  interface Passkey {
@@ -293,6 +306,17 @@ interface LinkedIdentity {
293
306
  /** When it was linked, in UTC (ISO 8601). */
294
307
  linkedAt: string;
295
308
  }
309
+ /** How an account takes its second step. */
310
+ interface SecondStep {
311
+ totp: boolean;
312
+ /** The phone codes are sent to, masked (`+57 ••• ••• 4567`). */
313
+ phone: {
314
+ number: string;
315
+ channel: string;
316
+ } | null;
317
+ /** The ways the workspace sends codes to phones. */
318
+ phoneChannels: string[];
319
+ }
296
320
  interface AccountClient {
297
321
  /** The account, or null when nobody is signed in. */
298
322
  get(): Promise<Account$1 | null>;
@@ -331,6 +355,30 @@ interface AccountClient {
331
355
  }): Promise<AuthResult<'renewed', {
332
356
  recoveryCodes: string[];
333
357
  }>>;
358
+ /**
359
+ * How the account takes its second step: an authenticator app, a phone
360
+ * (masked), and the ways the workspace sends codes to phones (`sms`,
361
+ * `whatsapp`; none when it has no Twilio account for it).
362
+ */
363
+ factors(): Promise<SecondStep | null>;
364
+ /** Adds a phone as the second step: a code is sent to it, for `verifyPhone`. */
365
+ addPhone(form: {
366
+ phone: string;
367
+ channel: 'sms' | 'whatsapp';
368
+ password: string;
369
+ }): Promise<AuthResult<'sent', {
370
+ sentTo: string;
371
+ channel: string;
372
+ }>>;
373
+ /** Proves the phone with the code it received. `recoveryCodes` come with a first second step, shown this once. */
374
+ verifyPhone(form: {
375
+ code: string;
376
+ }): Promise<AuthResult<'enabled', {
377
+ recoveryCodes: string[];
378
+ }>>;
379
+ removePhone(form: {
380
+ password: string;
381
+ }): Promise<AuthResult<'removed'>>;
334
382
  };
335
383
  /**
336
384
  * Asks to sign in with another address. Nothing changes yet: the new address
@@ -387,6 +435,7 @@ interface AuthClient {
387
435
  email(form: {
388
436
  email: string;
389
437
  password: string;
438
+ captchaToken?: string;
390
439
  }): Promise<AuthResult<'signed_in', {
391
440
  session: PublicSession;
392
441
  }> | AuthResult<'mfa_required'>>;
@@ -396,9 +445,23 @@ interface AuthClient {
396
445
  }): Promise<AuthResult<'signed_in', {
397
446
  session: PublicSession;
398
447
  }>>;
448
+ /** While the second step is asked for: whether the account has an authenticator app, and the phone (masked) a code can be sent to. */
449
+ mfaMethods(): Promise<AuthResult<'ok', {
450
+ totp: boolean;
451
+ phone: {
452
+ number: string;
453
+ channel: string;
454
+ } | null;
455
+ }>>;
456
+ /** Sends a code to the account's phone, by SMS or WhatsApp; `mfa` takes it. A few per sign-in. */
457
+ mfaSendCode(): Promise<AuthResult<'sent', {
458
+ sentTo: string;
459
+ channel: string;
460
+ }>>;
399
461
  /** Mails a link that signs the person in. The answer is the same whether or not the address has an account. */
400
462
  magicLink(form: {
401
463
  email: string;
464
+ captchaToken?: string;
402
465
  }): Promise<AuthResult<'sent'>>;
403
466
  /** Signs in with the token the mailed link opened the page with (`ml_token`). */
404
467
  magicLinkVerify(form: {
@@ -426,6 +489,34 @@ interface AuthClient {
426
489
  }): Promise<AuthResult<'signed_in', {
427
490
  session: PublicSession;
428
491
  }> | AuthResult<'redirected'>>;
492
+ /**
493
+ * Offers the person's passkeys in the browser's autofill of the email
494
+ * field, which must carry `autocomplete="username webauthn"`, and signs in
495
+ * with the one they pick. It waits until they pick one or `signal`
496
+ * aborts: abort it before calling `passkey` or sending the form.
497
+ * `cancelled`: aborted, or this browser or page cannot (then there is
498
+ * nothing to offer, and the passkey button still works).
499
+ */
500
+ passkeyAutofill(options?: {
501
+ signal?: AbortSignal;
502
+ }): Promise<AuthResult<'signed_in', {
503
+ session: PublicSession;
504
+ }>>;
505
+ /**
506
+ * Google One Tap: Google's prompt over the page offers the Google account
507
+ * the browser already has, and signs in with it in one tap, as the Google
508
+ * sign-in does (the same account). Needs the workspace's Google sign-in,
509
+ * and the page's address among the Google client's authorized JavaScript
510
+ * origins. Waits until the person picks an account or closes the prompt
511
+ * (`cancelled`), or `signal` aborts. `one_tap_unavailable`: the workspace
512
+ * has no Google sign-in.
513
+ */
514
+ googleOneTap(options?: {
515
+ signal?: AbortSignal;
516
+ context?: 'signin' | 'signup' | 'use';
517
+ }): Promise<AuthResult<'signed_in', {
518
+ session: PublicSession;
519
+ }>>;
429
520
  /** Where `passkey` sends the browser when this page cannot use the passkey itself. */
430
521
  passkeyUrl(options?: {
431
522
  returnTo?: string;
@@ -446,6 +537,7 @@ interface AuthClient {
446
537
  email: string;
447
538
  password: string;
448
539
  name?: string;
540
+ captchaToken?: string;
449
541
  }): Promise<AuthResult<'signed_in', {
450
542
  session: PublicSession;
451
543
  }> | AuthResult<'verification_required', {
@@ -455,6 +547,7 @@ interface AuthClient {
455
547
  /** Mails a link to choose a new password. The answer is the same whether or not the address has an account. */
456
548
  forgotPassword(form: {
457
549
  email: string;
550
+ captchaToken?: string;
458
551
  }): Promise<AuthResult<'sent'>>;
459
552
  /** Sets the new password, with the token the mailed link opened the page with (`token`). */
460
553
  resetPassword(form: {
@@ -508,6 +601,20 @@ interface AuthTexts {
508
601
  sendLink: string;
509
602
  linkSent: string;
510
603
  codeHelp: string;
604
+ /** The second step when it is a phone only. */
605
+ codeHelpPhone: string;
606
+ /** "{to}" is the phone, masked. */
607
+ sendCodeSms: string;
608
+ sendCodeWhatsapp: string;
609
+ codeSent: string;
610
+ phone: string;
611
+ phoneHelp: string;
612
+ phoneOn: string;
613
+ phoneOff: string;
614
+ addPhone: string;
615
+ removePhone: string;
616
+ bySms: string;
617
+ byWhatsapp: string;
511
618
  verify: string;
512
619
  checkEmail: string;
513
620
  backToSignIn: string;
@@ -623,6 +730,21 @@ interface AuthFormProps {
623
730
  };
624
731
  }
625
732
  declare function SignIn(props: AuthFormProps): react.JSX.Element;
733
+ interface GoogleOneTapProps {
734
+ /** Where to go once signed in. Without it (and without `onSuccess`), the page stays and its session updates. */
735
+ returnTo?: string;
736
+ /** Called once signed in, instead of going to `returnTo`. */
737
+ onSuccess?: () => void;
738
+ /** The prompt's words: sign in (default), sign up, or use the application. */
739
+ context?: 'signin' | 'signup' | 'use';
740
+ }
741
+ /**
742
+ * Google One Tap: put it on any page, and a person who is not signed in sees
743
+ * Google's prompt with the Google account the browser has; one tap signs them
744
+ * in. It draws nothing of its own, and shows nothing to somebody signed in or
745
+ * where the workspace has no Google sign-in.
746
+ */
747
+ declare function GoogleOneTap(props: GoogleOneTapProps): null;
626
748
  declare function SignUp(props: AuthFormProps): react.JSX.Element;
627
749
  declare function ForgotPassword(props: AuthFormProps): react.JSX.Element;
628
750
  /** The page a "choose a new password" link opens: `pages.resetPassword`. */
@@ -685,4 +807,4 @@ declare function useSession(): SessionContext;
685
807
  */
686
808
  declare function useAuth(): AuthClient & Pick<SessionContext, 'session' | 'status' | 'refresh'>;
687
809
 
688
- export { Account, type AccountClient, type Account$1 as AccountDetails, type AccountProps, type AccountSession, type AuthClient, type AuthError, type AuthFormProps, type AuthMethods, type AuthResult, type AuthTexts, CauthyProvider, type CauthyProviderProps, ForgotPassword, type JsonValue, type LinkedIdentity, type Passkey, type PermissionOf, type Policy, type PublicSession, ResetPassword, type RoleOf, type SessionContext, type SessionOrganization, type SessionUser, SignIn, SignUp, VerifyEmail, can, canUsePasskeys, createAuthClient, definePolicy, useAuth, useSession };
810
+ export { Account, type AccountClient, type Account$1 as AccountDetails, type AccountProps, type AccountSession, type AuthClient, type AuthError, type AuthFormProps, type AuthMethods, type AuthResult, type AuthTexts, CauthyProvider, type CauthyProviderProps, ForgotPassword, GoogleOneTap, type GoogleOneTapProps, type JsonValue, type LinkedIdentity, type Passkey, type PermissionOf, type Policy, type PublicSession, ResetPassword, type RoleOf, type SecondStep, type SessionContext, type SessionOrganization, type SessionUser, SignIn, SignUp, VerifyEmail, can, canAutofillPasskeys, canUsePasskeys, createAuthClient, definePolicy, useAuth, useSession };
package/dist/react.d.ts CHANGED
@@ -212,6 +212,12 @@ type AuthField = 'email' | 'password' | 'newPassword' | 'name' | 'code';
212
212
 
213
213
  /** Whether this browser can use a passkey at all. */
214
214
  declare function canUsePasskeys(): boolean;
215
+ /**
216
+ * Whether this browser offers passkeys in the autofill of a field marked
217
+ * `autocomplete="username webauthn"`, so the person picks one without
218
+ * looking for a button.
219
+ */
220
+ declare function canAutofillPasskeys(): Promise<boolean>;
215
221
 
216
222
  /** What went wrong, in a form the screen can show. */
217
223
  interface AuthError {
@@ -252,6 +258,13 @@ interface AuthMethods {
252
258
  * page that cannot, or a browser that refuses to here, sends the person.
253
259
  */
254
260
  passkeyOnCauthy: boolean;
261
+ /**
262
+ * The workspace's Cloudflare Turnstile site key, when it asks for the
263
+ * challenge: signing in, creating an account, and asking for a sign-in link
264
+ * or a new password then take its answer (`captchaToken`). The ready-made
265
+ * forms show it themselves.
266
+ */
267
+ captchaSiteKey?: string;
255
268
  }
256
269
  /** A passkey of the signed-in account. Moments are UTC. */
257
270
  interface Passkey {
@@ -293,6 +306,17 @@ interface LinkedIdentity {
293
306
  /** When it was linked, in UTC (ISO 8601). */
294
307
  linkedAt: string;
295
308
  }
309
+ /** How an account takes its second step. */
310
+ interface SecondStep {
311
+ totp: boolean;
312
+ /** The phone codes are sent to, masked (`+57 ••• ••• 4567`). */
313
+ phone: {
314
+ number: string;
315
+ channel: string;
316
+ } | null;
317
+ /** The ways the workspace sends codes to phones. */
318
+ phoneChannels: string[];
319
+ }
296
320
  interface AccountClient {
297
321
  /** The account, or null when nobody is signed in. */
298
322
  get(): Promise<Account$1 | null>;
@@ -331,6 +355,30 @@ interface AccountClient {
331
355
  }): Promise<AuthResult<'renewed', {
332
356
  recoveryCodes: string[];
333
357
  }>>;
358
+ /**
359
+ * How the account takes its second step: an authenticator app, a phone
360
+ * (masked), and the ways the workspace sends codes to phones (`sms`,
361
+ * `whatsapp`; none when it has no Twilio account for it).
362
+ */
363
+ factors(): Promise<SecondStep | null>;
364
+ /** Adds a phone as the second step: a code is sent to it, for `verifyPhone`. */
365
+ addPhone(form: {
366
+ phone: string;
367
+ channel: 'sms' | 'whatsapp';
368
+ password: string;
369
+ }): Promise<AuthResult<'sent', {
370
+ sentTo: string;
371
+ channel: string;
372
+ }>>;
373
+ /** Proves the phone with the code it received. `recoveryCodes` come with a first second step, shown this once. */
374
+ verifyPhone(form: {
375
+ code: string;
376
+ }): Promise<AuthResult<'enabled', {
377
+ recoveryCodes: string[];
378
+ }>>;
379
+ removePhone(form: {
380
+ password: string;
381
+ }): Promise<AuthResult<'removed'>>;
334
382
  };
335
383
  /**
336
384
  * Asks to sign in with another address. Nothing changes yet: the new address
@@ -387,6 +435,7 @@ interface AuthClient {
387
435
  email(form: {
388
436
  email: string;
389
437
  password: string;
438
+ captchaToken?: string;
390
439
  }): Promise<AuthResult<'signed_in', {
391
440
  session: PublicSession;
392
441
  }> | AuthResult<'mfa_required'>>;
@@ -396,9 +445,23 @@ interface AuthClient {
396
445
  }): Promise<AuthResult<'signed_in', {
397
446
  session: PublicSession;
398
447
  }>>;
448
+ /** While the second step is asked for: whether the account has an authenticator app, and the phone (masked) a code can be sent to. */
449
+ mfaMethods(): Promise<AuthResult<'ok', {
450
+ totp: boolean;
451
+ phone: {
452
+ number: string;
453
+ channel: string;
454
+ } | null;
455
+ }>>;
456
+ /** Sends a code to the account's phone, by SMS or WhatsApp; `mfa` takes it. A few per sign-in. */
457
+ mfaSendCode(): Promise<AuthResult<'sent', {
458
+ sentTo: string;
459
+ channel: string;
460
+ }>>;
399
461
  /** Mails a link that signs the person in. The answer is the same whether or not the address has an account. */
400
462
  magicLink(form: {
401
463
  email: string;
464
+ captchaToken?: string;
402
465
  }): Promise<AuthResult<'sent'>>;
403
466
  /** Signs in with the token the mailed link opened the page with (`ml_token`). */
404
467
  magicLinkVerify(form: {
@@ -426,6 +489,34 @@ interface AuthClient {
426
489
  }): Promise<AuthResult<'signed_in', {
427
490
  session: PublicSession;
428
491
  }> | AuthResult<'redirected'>>;
492
+ /**
493
+ * Offers the person's passkeys in the browser's autofill of the email
494
+ * field, which must carry `autocomplete="username webauthn"`, and signs in
495
+ * with the one they pick. It waits until they pick one or `signal`
496
+ * aborts: abort it before calling `passkey` or sending the form.
497
+ * `cancelled`: aborted, or this browser or page cannot (then there is
498
+ * nothing to offer, and the passkey button still works).
499
+ */
500
+ passkeyAutofill(options?: {
501
+ signal?: AbortSignal;
502
+ }): Promise<AuthResult<'signed_in', {
503
+ session: PublicSession;
504
+ }>>;
505
+ /**
506
+ * Google One Tap: Google's prompt over the page offers the Google account
507
+ * the browser already has, and signs in with it in one tap, as the Google
508
+ * sign-in does (the same account). Needs the workspace's Google sign-in,
509
+ * and the page's address among the Google client's authorized JavaScript
510
+ * origins. Waits until the person picks an account or closes the prompt
511
+ * (`cancelled`), or `signal` aborts. `one_tap_unavailable`: the workspace
512
+ * has no Google sign-in.
513
+ */
514
+ googleOneTap(options?: {
515
+ signal?: AbortSignal;
516
+ context?: 'signin' | 'signup' | 'use';
517
+ }): Promise<AuthResult<'signed_in', {
518
+ session: PublicSession;
519
+ }>>;
429
520
  /** Where `passkey` sends the browser when this page cannot use the passkey itself. */
430
521
  passkeyUrl(options?: {
431
522
  returnTo?: string;
@@ -446,6 +537,7 @@ interface AuthClient {
446
537
  email: string;
447
538
  password: string;
448
539
  name?: string;
540
+ captchaToken?: string;
449
541
  }): Promise<AuthResult<'signed_in', {
450
542
  session: PublicSession;
451
543
  }> | AuthResult<'verification_required', {
@@ -455,6 +547,7 @@ interface AuthClient {
455
547
  /** Mails a link to choose a new password. The answer is the same whether or not the address has an account. */
456
548
  forgotPassword(form: {
457
549
  email: string;
550
+ captchaToken?: string;
458
551
  }): Promise<AuthResult<'sent'>>;
459
552
  /** Sets the new password, with the token the mailed link opened the page with (`token`). */
460
553
  resetPassword(form: {
@@ -508,6 +601,20 @@ interface AuthTexts {
508
601
  sendLink: string;
509
602
  linkSent: string;
510
603
  codeHelp: string;
604
+ /** The second step when it is a phone only. */
605
+ codeHelpPhone: string;
606
+ /** "{to}" is the phone, masked. */
607
+ sendCodeSms: string;
608
+ sendCodeWhatsapp: string;
609
+ codeSent: string;
610
+ phone: string;
611
+ phoneHelp: string;
612
+ phoneOn: string;
613
+ phoneOff: string;
614
+ addPhone: string;
615
+ removePhone: string;
616
+ bySms: string;
617
+ byWhatsapp: string;
511
618
  verify: string;
512
619
  checkEmail: string;
513
620
  backToSignIn: string;
@@ -623,6 +730,21 @@ interface AuthFormProps {
623
730
  };
624
731
  }
625
732
  declare function SignIn(props: AuthFormProps): react.JSX.Element;
733
+ interface GoogleOneTapProps {
734
+ /** Where to go once signed in. Without it (and without `onSuccess`), the page stays and its session updates. */
735
+ returnTo?: string;
736
+ /** Called once signed in, instead of going to `returnTo`. */
737
+ onSuccess?: () => void;
738
+ /** The prompt's words: sign in (default), sign up, or use the application. */
739
+ context?: 'signin' | 'signup' | 'use';
740
+ }
741
+ /**
742
+ * Google One Tap: put it on any page, and a person who is not signed in sees
743
+ * Google's prompt with the Google account the browser has; one tap signs them
744
+ * in. It draws nothing of its own, and shows nothing to somebody signed in or
745
+ * where the workspace has no Google sign-in.
746
+ */
747
+ declare function GoogleOneTap(props: GoogleOneTapProps): null;
626
748
  declare function SignUp(props: AuthFormProps): react.JSX.Element;
627
749
  declare function ForgotPassword(props: AuthFormProps): react.JSX.Element;
628
750
  /** The page a "choose a new password" link opens: `pages.resetPassword`. */
@@ -685,4 +807,4 @@ declare function useSession(): SessionContext;
685
807
  */
686
808
  declare function useAuth(): AuthClient & Pick<SessionContext, 'session' | 'status' | 'refresh'>;
687
809
 
688
- export { Account, type AccountClient, type Account$1 as AccountDetails, type AccountProps, type AccountSession, type AuthClient, type AuthError, type AuthFormProps, type AuthMethods, type AuthResult, type AuthTexts, CauthyProvider, type CauthyProviderProps, ForgotPassword, type JsonValue, type LinkedIdentity, type Passkey, type PermissionOf, type Policy, type PublicSession, ResetPassword, type RoleOf, type SessionContext, type SessionOrganization, type SessionUser, SignIn, SignUp, VerifyEmail, can, canUsePasskeys, createAuthClient, definePolicy, useAuth, useSession };
810
+ export { Account, type AccountClient, type Account$1 as AccountDetails, type AccountProps, type AccountSession, type AuthClient, type AuthError, type AuthFormProps, type AuthMethods, type AuthResult, type AuthTexts, CauthyProvider, type CauthyProviderProps, ForgotPassword, GoogleOneTap, type GoogleOneTapProps, type JsonValue, type LinkedIdentity, type Passkey, type PermissionOf, type Policy, type PublicSession, ResetPassword, type RoleOf, type SecondStep, type SessionContext, type SessionOrganization, type SessionUser, SignIn, SignUp, VerifyEmail, can, canAutofillPasskeys, canUsePasskeys, createAuthClient, definePolicy, useAuth, useSession };