@cauthyhq/react 0.0.0 → 1.0.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/LICENSE +202 -0
- package/NOTICE +3 -0
- package/README.md +69 -1
- package/dist/index.d.mts +724 -0
- package/dist/index.d.ts +724 -0
- package/dist/index.js +2694 -0
- package/dist/index.js.map +1 -0
- package/dist/index.mjs +2639 -0
- package/dist/index.mjs.map +1 -0
- package/dist/styles.css +511 -0
- package/package.json +104 -4
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,724 @@
|
|
|
1
|
+
import * as react from 'react';
|
|
2
|
+
import { ReactNode, ComponentType, FormEvent } from 'react';
|
|
3
|
+
import { PublicSession, AuthClient, OrganizationsClient, OrganizationSeat, AuthError, SignInFlow, FlowState, OrganizationRoleChoice } from '@cauthyhq/js';
|
|
4
|
+
export { AccountClient, Account as AccountDetails, AccountSession, AuthClient, AuthError, AuthMethods, AuthResult, CauthyError, ConnectedAgent, FlowState, FlowStep, Invitation, JsonValue, LinkedIdentity, NextStep, OrganizationPerson, OrganizationRoleChoice, OrganizationSeat, OrganizationsClient, Passkey, PasskeyKind, PendingLegal, PermissionOf, Policy, PublicSession, RoleOf, SSOConnection, SecondStep, SessionOrganization, SessionUser, SignInFlow, can, canAutofillPasskeys, canUsePasskeys, createAuthClient, createSessionStore, createSignInFlow, definePolicy, unwrap } from '@cauthyhq/js';
|
|
5
|
+
import { CauthyTheme } from '@cauthyhq/js/theme';
|
|
6
|
+
export { CauthyTheme, themeFromCss, themeFromStackmyth, themeVariables, tokensFromStackmyth } from '@cauthyhq/js/theme';
|
|
7
|
+
|
|
8
|
+
interface SessionContext {
|
|
9
|
+
/** The signed-in person and their organizations, or null. */
|
|
10
|
+
session: PublicSession | null;
|
|
11
|
+
status: 'loading' | 'authenticated' | 'unauthenticated';
|
|
12
|
+
/** Sends the browser to sign in, and back to `returnTo` (default: where it is now). */
|
|
13
|
+
signIn(options?: {
|
|
14
|
+
returnTo?: string;
|
|
15
|
+
locale?: string;
|
|
16
|
+
prompt?: 'login';
|
|
17
|
+
}): void;
|
|
18
|
+
/** Signs out of this application and of Cauthy in this browser. */
|
|
19
|
+
signOut(): void;
|
|
20
|
+
/** Asks the server again who is signed in. */
|
|
21
|
+
refresh(): Promise<PublicSession | null>;
|
|
22
|
+
/** Where the person looks after their account: password, second step, passkeys. */
|
|
23
|
+
accountUrl(returnTo?: string): string;
|
|
24
|
+
/** Where the server mounted the routes. */
|
|
25
|
+
basePath: string;
|
|
26
|
+
}
|
|
27
|
+
interface CauthyProviderProps {
|
|
28
|
+
children: ReactNode;
|
|
29
|
+
/**
|
|
30
|
+
* Where the server mounted the routes. Default: `/api/auth`. Fixed for the
|
|
31
|
+
* life of the provider: it is the session store's address, so a different
|
|
32
|
+
* one means another store, with the session asked again and every flow
|
|
33
|
+
* started over. To move it, remount the provider (`key={basePath}`).
|
|
34
|
+
*/
|
|
35
|
+
basePath?: string;
|
|
36
|
+
/**
|
|
37
|
+
* The session the server already read while rendering (SSR): the first
|
|
38
|
+
* paint is then right, with no "loading". `null` means "nobody"; leave it
|
|
39
|
+
* out when the server did not look.
|
|
40
|
+
*/
|
|
41
|
+
initialSession?: PublicSession | null;
|
|
42
|
+
/**
|
|
43
|
+
* The language the person reads, for what Cauthy mails them from
|
|
44
|
+
* `useAuth()` and the ready-made forms (a sign-in link, a new password, a
|
|
45
|
+
* confirmation): a tag like `es` or `es-CO`, or a function that answers it
|
|
46
|
+
* when the person can change it. Default: the page's own (`<html lang>`),
|
|
47
|
+
* else the browser's.
|
|
48
|
+
*/
|
|
49
|
+
locale?: string | (() => string | undefined);
|
|
50
|
+
/**
|
|
51
|
+
* The application's own look for every ready-made part, over the one set in
|
|
52
|
+
* Cauthy's dashboard: colours, corners, typeface. An application built with
|
|
53
|
+
* stackmyth passes its tokens: `theme={themeFromStackmyth(css).theme}`.
|
|
54
|
+
*/
|
|
55
|
+
theme?: CauthyTheme;
|
|
56
|
+
/** The fetch the routes are called with. Default: the page's own. */
|
|
57
|
+
fetch?: typeof fetch;
|
|
58
|
+
/** Called once when the server does not say `Cauthy-Protocol: 1`. Default: one console warning. */
|
|
59
|
+
onProtocolMismatch?: (seen: string | null) => void;
|
|
60
|
+
}
|
|
61
|
+
declare function CauthyProvider({ children, basePath, initialSession, locale, theme, fetch, onProtocolMismatch }: CauthyProviderProps): react.JSX.Element;
|
|
62
|
+
declare function useSession(): SessionContext;
|
|
63
|
+
/**
|
|
64
|
+
* The application's own sign-in screens: the functions a form calls.
|
|
65
|
+
*
|
|
66
|
+
* const { signIn, signUp, forgotPassword, signOut, session } = useAuth()
|
|
67
|
+
* const r = await signIn.email({ email, password })
|
|
68
|
+
*
|
|
69
|
+
* They are `createAuthClient()`'s, and what is on screen follows them: after
|
|
70
|
+
* a sign-in or a sign-out, `session` is the new one with no reload.
|
|
71
|
+
*/
|
|
72
|
+
declare function useAuth(): AuthClient & Pick<SessionContext, 'session' | 'status' | 'refresh'>;
|
|
73
|
+
|
|
74
|
+
interface UseOrganizations extends OrganizationsClient {
|
|
75
|
+
/** The person's organizations; empty while loading or signed out. */
|
|
76
|
+
organizations: OrganizationSeat[];
|
|
77
|
+
loading: boolean;
|
|
78
|
+
/** Why the last list could not be had, or null: an empty list with no error is a person in no organization. */
|
|
79
|
+
error: AuthError | null;
|
|
80
|
+
/** Asks for the list again. */
|
|
81
|
+
reload(): Promise<void>;
|
|
82
|
+
}
|
|
83
|
+
declare function useOrganizations(options?: {
|
|
84
|
+
system?: string;
|
|
85
|
+
}): UseOrganizations;
|
|
86
|
+
|
|
87
|
+
declare function useSignInFlow(): SignInFlow & FlowState;
|
|
88
|
+
|
|
89
|
+
interface UserButtonTexts {
|
|
90
|
+
signIn: string;
|
|
91
|
+
/** The button's accessible name; `{name}` is the person's. */
|
|
92
|
+
menu: string;
|
|
93
|
+
manageAccount: string;
|
|
94
|
+
signOut: string;
|
|
95
|
+
}
|
|
96
|
+
type Part = 'root' | 'trigger' | 'avatar' | 'menu' | 'identity' | 'item';
|
|
97
|
+
interface UserButtonProps {
|
|
98
|
+
/** The language of the built-in words. Default: `en`. */
|
|
99
|
+
locale?: 'en' | 'es';
|
|
100
|
+
texts?: Partial<UserButtonTexts>;
|
|
101
|
+
/** Where "Manage account" goes: the application's own account page. Default: Cauthy's hosted one. */
|
|
102
|
+
accountHref?: string;
|
|
103
|
+
/** Where "Sign in" goes: the application's own sign-in page. Default: Cauthy's hosted one. */
|
|
104
|
+
signInHref?: string;
|
|
105
|
+
/** Called once signed out, instead of going to `/`. */
|
|
106
|
+
onSignOut?: () => void;
|
|
107
|
+
/** More entries for the menu, after "Manage account". Give each `role="menuitem"` and `tabIndex={-1}`. */
|
|
108
|
+
children?: ReactNode;
|
|
109
|
+
/** No look at all: no `data-cauthy`, no class names but the ones given. */
|
|
110
|
+
unstyled?: boolean;
|
|
111
|
+
classNames?: Partial<Record<Part, string>>;
|
|
112
|
+
}
|
|
113
|
+
/** Two letters for a person: the first and last word of the name, else the address's first letter. */
|
|
114
|
+
declare function initialsOf(name: string, email: string): string;
|
|
115
|
+
declare function UserButton(props: UserButtonProps): react.JSX.Element;
|
|
116
|
+
|
|
117
|
+
/** Every sentence the forms show. Give any of them to change it. */
|
|
118
|
+
interface AuthTexts {
|
|
119
|
+
email: string;
|
|
120
|
+
password: string;
|
|
121
|
+
name: string;
|
|
122
|
+
code: string;
|
|
123
|
+
signIn: string;
|
|
124
|
+
signUp: string;
|
|
125
|
+
continueWith: string;
|
|
126
|
+
orWithEmail: string;
|
|
127
|
+
/** The sign-in's box to stay signed in, shown when the application's client allows it. */
|
|
128
|
+
keepSignedIn: string;
|
|
129
|
+
forgotPassword: string;
|
|
130
|
+
noAccount: string;
|
|
131
|
+
createAccount: string;
|
|
132
|
+
/** The label of the company's name, asked when the application's system makes an organization per sign-up. */
|
|
133
|
+
company: string;
|
|
134
|
+
/** The legal box: "I have read and accept" + "the Terms of Service" + "and" + "the Privacy Policy", linked. */
|
|
135
|
+
iAccept: string;
|
|
136
|
+
and: string;
|
|
137
|
+
termsOfService: string;
|
|
138
|
+
privacyPolicy: string;
|
|
139
|
+
haveAccount: string;
|
|
140
|
+
sendLink: string;
|
|
141
|
+
linkSent: string;
|
|
142
|
+
codeHelp: string;
|
|
143
|
+
/** The second step when it is a phone only. */
|
|
144
|
+
codeHelpPhone: string;
|
|
145
|
+
/** The second step by email (the account has no factor): "{to}" is the address, masked. */
|
|
146
|
+
codeHelpEmail: string;
|
|
147
|
+
sendEmailAgain: string;
|
|
148
|
+
/** "{to}" is the phone, masked. */
|
|
149
|
+
sendCodeSms: string;
|
|
150
|
+
sendCodeWhatsapp: string;
|
|
151
|
+
codeSent: string;
|
|
152
|
+
/** The second step approved on the phone; "{n}" is the number to pick. */
|
|
153
|
+
pushSend: string;
|
|
154
|
+
pushPick: string;
|
|
155
|
+
pushWaiting: string;
|
|
156
|
+
phone: string;
|
|
157
|
+
phoneHelp: string;
|
|
158
|
+
phoneOn: string;
|
|
159
|
+
phoneOff: string;
|
|
160
|
+
addPhone: string;
|
|
161
|
+
removePhone: string;
|
|
162
|
+
bySms: string;
|
|
163
|
+
byWhatsapp: string;
|
|
164
|
+
/** The label of the channel phone codes go by, where the application draws it as a select. */
|
|
165
|
+
channel: string;
|
|
166
|
+
verify: string;
|
|
167
|
+
checkEmail: string;
|
|
168
|
+
backToSignIn: string;
|
|
169
|
+
emailMeALink: string;
|
|
170
|
+
/** The sign-in link's own step: what it does, its send button, the way back. */
|
|
171
|
+
linkHelp: string;
|
|
172
|
+
sendMeTheLink: string;
|
|
173
|
+
back: string;
|
|
174
|
+
usePasskey: string;
|
|
175
|
+
codeFromMail: string;
|
|
176
|
+
signInLinkSent: string;
|
|
177
|
+
newPassword: string;
|
|
178
|
+
savePassword: string;
|
|
179
|
+
passwordChanged: string;
|
|
180
|
+
confirming: string;
|
|
181
|
+
emailConfirmed: string;
|
|
182
|
+
invitedTo: string;
|
|
183
|
+
invitedToOrganization: string;
|
|
184
|
+
invitedAs: string;
|
|
185
|
+
choosePassword: string;
|
|
186
|
+
acceptInvite: string;
|
|
187
|
+
openingInvitation: string;
|
|
188
|
+
invitationInvalid: string;
|
|
189
|
+
profile: string;
|
|
190
|
+
save: string;
|
|
191
|
+
saved: string;
|
|
192
|
+
currentPassword: string;
|
|
193
|
+
changePassword: string;
|
|
194
|
+
passwordChangedHere: string;
|
|
195
|
+
secondStep: string;
|
|
196
|
+
secondStepOn: string;
|
|
197
|
+
secondStepOff: string;
|
|
198
|
+
turnOn: string;
|
|
199
|
+
turnOff: string;
|
|
200
|
+
addToApp: string;
|
|
201
|
+
openInApp: string;
|
|
202
|
+
qrAlt: string;
|
|
203
|
+
recoveryCodes: string;
|
|
204
|
+
newRecoveryCodes: string;
|
|
205
|
+
keepCodes: string;
|
|
206
|
+
/** Beside recovery codes just made: copy them all, or save them as a text file. */
|
|
207
|
+
copyCodes: string;
|
|
208
|
+
downloadCodes: string;
|
|
209
|
+
codesCopied: string;
|
|
210
|
+
/** Said when the browser would not copy: the codes stay on screen to select. */
|
|
211
|
+
codesNotCopied: string;
|
|
212
|
+
/** The action that opens the form of a part already set (the name). */
|
|
213
|
+
change: string;
|
|
214
|
+
/** The password part, when the account has one. */
|
|
215
|
+
passwordSet: string;
|
|
216
|
+
/** Opens the form that adds another passkey, once the account has one. */
|
|
217
|
+
addAnotherPasskey: string;
|
|
218
|
+
passkeys: string;
|
|
219
|
+
managePasskeys: string;
|
|
220
|
+
passkeysHelp: string;
|
|
221
|
+
noPasskeys: string;
|
|
222
|
+
passkeyName: string;
|
|
223
|
+
/** @deprecated Unused since 0.19.0: the account screen offers `addPasskeyDevice` and `addSecurityKey`. */
|
|
224
|
+
addPasskey: string;
|
|
225
|
+
addPasskeyDevice: string;
|
|
226
|
+
addSecurityKey: string;
|
|
227
|
+
passkeyKinds: Record<'security_key' | 'synced' | 'device', string>;
|
|
228
|
+
removePasskey: string;
|
|
229
|
+
passkeyAdded: string;
|
|
230
|
+
passkeyUnnamed: string;
|
|
231
|
+
sessions: string;
|
|
232
|
+
signOutEverywhere: string;
|
|
233
|
+
agents: string;
|
|
234
|
+
agentsHelp: string;
|
|
235
|
+
disconnect: string;
|
|
236
|
+
anAgent: string;
|
|
237
|
+
unknownDevice: string;
|
|
238
|
+
emailAddress: string;
|
|
239
|
+
newEmail: string;
|
|
240
|
+
changeEmail: string;
|
|
241
|
+
emailSent: string;
|
|
242
|
+
linkedAccounts: string;
|
|
243
|
+
noLinkedAccounts: string;
|
|
244
|
+
linkWith: string;
|
|
245
|
+
unlink: string;
|
|
246
|
+
linked: string;
|
|
247
|
+
ssoOnly: string;
|
|
248
|
+
members: string;
|
|
249
|
+
membersHidden: string;
|
|
250
|
+
organizationMissing: string;
|
|
251
|
+
memberYou: string;
|
|
252
|
+
memberInvited: string;
|
|
253
|
+
memberManager: string;
|
|
254
|
+
memberRole: string;
|
|
255
|
+
memberAdd: string;
|
|
256
|
+
memberAdded: string;
|
|
257
|
+
memberRemove: string;
|
|
258
|
+
memberRemoveConfirm: string;
|
|
259
|
+
memberLeave: string;
|
|
260
|
+
memberLeaveConfirm: string;
|
|
261
|
+
memberInviteAgain: string;
|
|
262
|
+
memberInvitationSent: string;
|
|
263
|
+
organization: string;
|
|
264
|
+
organizationRename: string;
|
|
265
|
+
organizationRenamed: string;
|
|
266
|
+
organizationArchive: string;
|
|
267
|
+
organizationArchiveConfirm: string;
|
|
268
|
+
organizationArchived: string;
|
|
269
|
+
organizationDelete: string;
|
|
270
|
+
organizationDeleteConfirm: string;
|
|
271
|
+
organizationDeleted: string;
|
|
272
|
+
yes: string;
|
|
273
|
+
cancel: string;
|
|
274
|
+
termsChanged: string;
|
|
275
|
+
termsChangedHelp: string;
|
|
276
|
+
acceptTerms: string;
|
|
277
|
+
/** By error code; one missing shows what the server said. */
|
|
278
|
+
errors: Record<string, string>;
|
|
279
|
+
}
|
|
280
|
+
type Slot = 'form' | 'field' | 'label' | 'input' | 'button' | 'providerButton' | 'providerIcon' | 'link' | 'error' | 'fieldError' | 'hint' | 'notice' | 'pending' | 'separator' | 'footer' | 'check' | 'account' | 'section' | 'heading' | 'secret' | 'qr' | 'codes' | 'sessions' | 'session';
|
|
281
|
+
interface AuthFormProps {
|
|
282
|
+
/** The language of the built-in sentences. Default: `en`. */
|
|
283
|
+
locale?: 'en' | 'es';
|
|
284
|
+
/** Sentences of the application's own, over the built-in ones. */
|
|
285
|
+
texts?: Partial<Omit<AuthTexts, 'errors'>> & {
|
|
286
|
+
errors?: Record<string, string>;
|
|
287
|
+
};
|
|
288
|
+
/**
|
|
289
|
+
* Called once the person is signed in, instead of going to `returnTo`. The
|
|
290
|
+
* form stays busy (its button loading, every control disabled) until it
|
|
291
|
+
* leaves the page. When the application keeps the form on screen while it
|
|
292
|
+
* moves on (a router's navigation, loading the session), return a Promise:
|
|
293
|
+
* the form waits for it, then is free again if it is still shown.
|
|
294
|
+
*/
|
|
295
|
+
onSuccess?: () => void | Promise<unknown>;
|
|
296
|
+
/** Where to go after signing in, and where a provider returns to. Default: `/`. */
|
|
297
|
+
returnTo?: string;
|
|
298
|
+
/**
|
|
299
|
+
* `<SignIn />`: a sign-in link sent to an address with no account makes
|
|
300
|
+
* one when it is used (if the workspace accepts new accounts), so this one
|
|
301
|
+
* screen signs people in and up alike. Default: off.
|
|
302
|
+
*/
|
|
303
|
+
createAccounts?: boolean;
|
|
304
|
+
/** Paths of the application's other screens, for the links between them. */
|
|
305
|
+
links?: {
|
|
306
|
+
signIn?: string;
|
|
307
|
+
signUp?: string;
|
|
308
|
+
forgotPassword?: string;
|
|
309
|
+
};
|
|
310
|
+
/** A class for each part the form renders. A part given one is left to it by `styles.css`. */
|
|
311
|
+
classNames?: Partial<Record<Slot, string>>;
|
|
312
|
+
/**
|
|
313
|
+
* No look of Cauthy's at all: `styles.css` leaves the form alone and the
|
|
314
|
+
* workspace's colours are not read. For a form drawn wholly with the
|
|
315
|
+
* application's own `components` or `classNames`.
|
|
316
|
+
*/
|
|
317
|
+
unstyled?: boolean;
|
|
318
|
+
/**
|
|
319
|
+
* Take the colours, corners and typeface a person set for the workspace in
|
|
320
|
+
* Cauthy's dashboard. Default: true. False keeps `styles.css`'s own, and
|
|
321
|
+
* whatever `--cauthy-*` variables the application sets.
|
|
322
|
+
*/
|
|
323
|
+
workspaceLook?: boolean;
|
|
324
|
+
/**
|
|
325
|
+
* The application's own parts, to draw the form with: its form layout,
|
|
326
|
+
* button, input, checkbox, select, field, text, badge, link, divider, alert
|
|
327
|
+
* and confirmation. A part not given is drawn as before; with every part given
|
|
328
|
+
* and `unstyled`, the form adds no element that carries a look of its own.
|
|
329
|
+
*/
|
|
330
|
+
components?: AuthComponents;
|
|
331
|
+
}
|
|
332
|
+
/**
|
|
333
|
+
* What the application's button is given: what a `<button>` would be, and
|
|
334
|
+
* what kind of button it is. `primary` sends the form; `secondary` is any
|
|
335
|
+
* other action (a provider, a passkey, a sign-in link, cancel, send again);
|
|
336
|
+
* `danger` removes, leaves, deletes, disconnects or turns something off.
|
|
337
|
+
* `loading` is true on the one button whose action is under way; every
|
|
338
|
+
* button is `disabled` meanwhile. Draw a spinner (or the like) on the button
|
|
339
|
+
* while `loading` is true, and keep its label: after a sign-in it stays true
|
|
340
|
+
* until the page is left, so the person sees the work go on.
|
|
341
|
+
*/
|
|
342
|
+
interface AuthButtonProps {
|
|
343
|
+
type: 'submit' | 'button';
|
|
344
|
+
disabled?: boolean;
|
|
345
|
+
className?: string;
|
|
346
|
+
onClick?: () => void;
|
|
347
|
+
children: ReactNode;
|
|
348
|
+
variant?: 'primary' | 'secondary' | 'danger';
|
|
349
|
+
loading?: boolean;
|
|
350
|
+
}
|
|
351
|
+
/**
|
|
352
|
+
* What the application's form layout is given: every element the forms put
|
|
353
|
+
* around their parts — a whole form, each step of it, each part of the
|
|
354
|
+
* account and members screens — so its own stack lays them out. `as` says
|
|
355
|
+
* which element it stands for: a `form` sends with `onSubmit` (render a
|
|
356
|
+
* `<form>` with it for Enter to submit), a `div` only groups.
|
|
357
|
+
*/
|
|
358
|
+
interface AuthFormLayoutProps {
|
|
359
|
+
as: 'form' | 'div';
|
|
360
|
+
onSubmit?: (e: FormEvent) => void;
|
|
361
|
+
noValidate?: boolean;
|
|
362
|
+
'aria-busy'?: boolean;
|
|
363
|
+
className?: string;
|
|
364
|
+
/**
|
|
365
|
+
* Which part of `<Account />` or `<OrganizationMembers />` this is, for an
|
|
366
|
+
* application that draws each as a card: an `AccountSection`
|
|
367
|
+
* (`profile`, `passkeys`…), or `members`, `add-member`, `organization`
|
|
368
|
+
* and `rename` (the form inside `organization`). Not set on a whole form.
|
|
369
|
+
*/
|
|
370
|
+
section?: string;
|
|
371
|
+
children: ReactNode;
|
|
372
|
+
}
|
|
373
|
+
/** What the application's input is given: what an `<input>` would be. */
|
|
374
|
+
interface AuthInputProps {
|
|
375
|
+
id: string;
|
|
376
|
+
name: string;
|
|
377
|
+
type: string;
|
|
378
|
+
value: string;
|
|
379
|
+
autoComplete?: string;
|
|
380
|
+
required?: boolean;
|
|
381
|
+
disabled?: boolean;
|
|
382
|
+
className?: string;
|
|
383
|
+
'aria-invalid'?: boolean;
|
|
384
|
+
'aria-describedby'?: string;
|
|
385
|
+
onChange: (e: {
|
|
386
|
+
target: {
|
|
387
|
+
value: string;
|
|
388
|
+
};
|
|
389
|
+
}) => void;
|
|
390
|
+
}
|
|
391
|
+
/** A box to tick: the legal documents and each consent of a sign-up. `children` is its label. */
|
|
392
|
+
interface AuthCheckboxProps {
|
|
393
|
+
id: string;
|
|
394
|
+
name: string;
|
|
395
|
+
checked: boolean;
|
|
396
|
+
required?: boolean;
|
|
397
|
+
disabled?: boolean;
|
|
398
|
+
className?: string;
|
|
399
|
+
onChange: (checked: boolean) => void;
|
|
400
|
+
children: ReactNode;
|
|
401
|
+
}
|
|
402
|
+
/** One choice of a few: a member's role, the channel of phone codes. Without a visible label it carries `aria-label`. */
|
|
403
|
+
interface AuthSelectProps {
|
|
404
|
+
id: string;
|
|
405
|
+
name: string;
|
|
406
|
+
value: string;
|
|
407
|
+
options: {
|
|
408
|
+
value: string;
|
|
409
|
+
label: string;
|
|
410
|
+
}[];
|
|
411
|
+
disabled?: boolean;
|
|
412
|
+
className?: string;
|
|
413
|
+
'aria-label'?: string;
|
|
414
|
+
onChange: (value: string) => void;
|
|
415
|
+
}
|
|
416
|
+
/**
|
|
417
|
+
* A label, its control (`children`) and what is said under it. The control's
|
|
418
|
+
* `aria-describedby` names `${id}-hint` and `${id}-error`: give the help and
|
|
419
|
+
* the error those ids for a screen reader to read them with it.
|
|
420
|
+
*/
|
|
421
|
+
interface AuthFieldProps {
|
|
422
|
+
id: string;
|
|
423
|
+
label: ReactNode;
|
|
424
|
+
children: ReactNode;
|
|
425
|
+
/** Beside the label: "Forgot your password?". */
|
|
426
|
+
aside?: ReactNode;
|
|
427
|
+
/** What the field takes (a new password's rule). Not given while there is an error. */
|
|
428
|
+
help?: ReactNode;
|
|
429
|
+
error?: ReactNode;
|
|
430
|
+
required?: boolean;
|
|
431
|
+
className?: string;
|
|
432
|
+
}
|
|
433
|
+
/** A sentence of the form: help, a state, the footer (`size: 'sm'`), a section's heading (`as: 'h2'`). */
|
|
434
|
+
interface AuthTextProps {
|
|
435
|
+
as?: 'p' | 'span' | 'h2';
|
|
436
|
+
tone?: 'muted' | 'danger' | 'success';
|
|
437
|
+
size?: 'sm' | 'md' | 'lg';
|
|
438
|
+
children: ReactNode;
|
|
439
|
+
}
|
|
440
|
+
/** A short mark beside a name: "you", "invited", a role, a passkey's kind. */
|
|
441
|
+
interface AuthBadgeProps {
|
|
442
|
+
tone?: 'neutral' | 'success' | 'warning' | 'danger';
|
|
443
|
+
children: ReactNode;
|
|
444
|
+
}
|
|
445
|
+
/** A link: to another screen, or a legal document (`newTab`). */
|
|
446
|
+
interface AuthLinkProps {
|
|
447
|
+
href?: string;
|
|
448
|
+
onClick?: () => void;
|
|
449
|
+
newTab?: boolean;
|
|
450
|
+
children: ReactNode;
|
|
451
|
+
}
|
|
452
|
+
/** The line between the providers and the address: "or with your email". */
|
|
453
|
+
interface AuthDividerProps {
|
|
454
|
+
label?: ReactNode;
|
|
455
|
+
}
|
|
456
|
+
/**
|
|
457
|
+
* What went wrong (`danger`), what was done (`success`) or what to know
|
|
458
|
+
* (`info`). The built-in one is announced: `role="alert"` for danger,
|
|
459
|
+
* `role="status"` otherwise; the application's should be too.
|
|
460
|
+
*/
|
|
461
|
+
interface AuthAlertProps {
|
|
462
|
+
tone: 'danger' | 'info' | 'success';
|
|
463
|
+
children: ReactNode;
|
|
464
|
+
}
|
|
465
|
+
/** What a confirmation asks: removing a member, leaving, archiving or deleting the organization. */
|
|
466
|
+
interface AuthConfirmOptions {
|
|
467
|
+
title: string;
|
|
468
|
+
body?: string;
|
|
469
|
+
confirmLabel: string;
|
|
470
|
+
cancelLabel: string;
|
|
471
|
+
danger?: boolean;
|
|
472
|
+
}
|
|
473
|
+
/** The parts a form may be drawn with. See `AuthFormProps.components`. */
|
|
474
|
+
interface AuthComponents {
|
|
475
|
+
/**
|
|
476
|
+
* Every element around the form's parts: the form itself, each step, each
|
|
477
|
+
* part of the account and members screens. Not given: the `form`, `div` or
|
|
478
|
+
* `section` the forms have always drawn.
|
|
479
|
+
*/
|
|
480
|
+
Form?: ComponentType<AuthFormLayoutProps>;
|
|
481
|
+
Button?: ComponentType<AuthButtonProps>;
|
|
482
|
+
Input?: ComponentType<AuthInputProps>;
|
|
483
|
+
Checkbox?: ComponentType<AuthCheckboxProps>;
|
|
484
|
+
Select?: ComponentType<AuthSelectProps>;
|
|
485
|
+
Field?: ComponentType<AuthFieldProps>;
|
|
486
|
+
Text?: ComponentType<AuthTextProps>;
|
|
487
|
+
Badge?: ComponentType<AuthBadgeProps>;
|
|
488
|
+
Link?: ComponentType<AuthLinkProps>;
|
|
489
|
+
Divider?: ComponentType<AuthDividerProps>;
|
|
490
|
+
Alert?: ComponentType<AuthAlertProps>;
|
|
491
|
+
/**
|
|
492
|
+
* Asks before something that cannot be undone, and answers whether to go
|
|
493
|
+
* on: the application's own dialog. Not given: the question shows inline,
|
|
494
|
+
* with a yes and a cancel button. Never the browser's own dialog.
|
|
495
|
+
*/
|
|
496
|
+
Confirm?: (options: AuthConfirmOptions) => Promise<boolean>;
|
|
497
|
+
}
|
|
498
|
+
declare function SignIn(props: AuthFormProps): react.JSX.Element;
|
|
499
|
+
interface GoogleOneTapProps {
|
|
500
|
+
/** Where to go once signed in. Without it (and without `onSuccess`), the page stays and its session updates. */
|
|
501
|
+
returnTo?: string;
|
|
502
|
+
/** Called once signed in, instead of going to `returnTo`. */
|
|
503
|
+
onSuccess?: () => void;
|
|
504
|
+
/** The prompt's words: sign in (default), sign up, or use the application. */
|
|
505
|
+
context?: 'signin' | 'signup' | 'use';
|
|
506
|
+
/** Whether the person asked to stay signed in, read when they tap. */
|
|
507
|
+
remember?: () => boolean;
|
|
508
|
+
}
|
|
509
|
+
/**
|
|
510
|
+
* Google One Tap: put it on any page, and a person who is not signed in sees
|
|
511
|
+
* Google's prompt with the Google account the browser has; one tap signs them
|
|
512
|
+
* in. It draws nothing of its own, and shows nothing to somebody signed in or
|
|
513
|
+
* where the workspace has no Google sign-in.
|
|
514
|
+
*/
|
|
515
|
+
declare function GoogleOneTap(props: GoogleOneTapProps): null;
|
|
516
|
+
declare function SignUp(props: AuthFormProps): react.JSX.Element;
|
|
517
|
+
declare function ForgotPassword(props: AuthFormProps): react.JSX.Element;
|
|
518
|
+
/** The page a "choose a new password" link opens: `pages.resetPassword`. */
|
|
519
|
+
declare function ResetPassword(props: AuthFormProps): react.JSX.Element;
|
|
520
|
+
/** The page a "confirm your address" link opens: `pages.verifyEmail`. It confirms as it opens. */
|
|
521
|
+
declare function VerifyEmail(props: AuthFormProps): react.JSX.Element;
|
|
522
|
+
/**
|
|
523
|
+
* The page an invitation opens: `pages.acceptInvite`. It says who is invited
|
|
524
|
+
* to what, asks for a password under the workspace's policy, signs the person
|
|
525
|
+
* in (with the second step, when their account owes one) and goes on to
|
|
526
|
+
* `returnTo`. The invitation is good until it is accepted: reading it, or a
|
|
527
|
+
* password refused, does not spend it.
|
|
528
|
+
*/
|
|
529
|
+
/** What `<AcceptInvite />` tells the application once the invitation is accepted. */
|
|
530
|
+
type AcceptInviteEvent = {
|
|
531
|
+
kind: 'invitation.accepted';
|
|
532
|
+
email: string;
|
|
533
|
+
organization?: string;
|
|
534
|
+
};
|
|
535
|
+
interface AcceptInviteProps extends AuthFormProps {
|
|
536
|
+
/** Called once the invitation is accepted, before the second step when the account owes one. */
|
|
537
|
+
onSaved?: (event: AcceptInviteEvent) => void;
|
|
538
|
+
}
|
|
539
|
+
declare function AcceptInvite(props: AcceptInviteProps): react.JSX.Element;
|
|
540
|
+
interface PendingTermsProps extends Omit<AuthFormProps, 'links' | 'returnTo' | 'createAccounts'> {
|
|
541
|
+
/**
|
|
542
|
+
* Called once the person accepted. Nothing else happens: the application
|
|
543
|
+
* decides what follows. A Promise keeps the button loading until it settles.
|
|
544
|
+
*/
|
|
545
|
+
onSuccess?: () => void | Promise<unknown>;
|
|
546
|
+
}
|
|
547
|
+
/**
|
|
548
|
+
* The legal documents the signed-in person still owes (a new version of the
|
|
549
|
+
* terms, say), linked, with the action that accepts them. It shows nothing
|
|
550
|
+
* while it reads them, when nothing is owed, and once they are accepted.
|
|
551
|
+
* Nothing stops the person meanwhile: the application decides what waits.
|
|
552
|
+
*/
|
|
553
|
+
declare function PendingTerms(props: PendingTermsProps): react.JSX.Element | null;
|
|
554
|
+
/** The parts of `<Account />`, by name: what `sections` lists. */
|
|
555
|
+
type AccountSection = 'profile' | 'email' | 'password' | 'linked' | 'secondStep' | 'phone' | 'passkeys' | 'agents' | 'sessions';
|
|
556
|
+
/**
|
|
557
|
+
* What `<Account />` tells the application after each change it saved, for
|
|
558
|
+
* the application's own toast or its own data to follow.
|
|
559
|
+
*/
|
|
560
|
+
type AccountEvent = {
|
|
561
|
+
kind: 'profile.saved';
|
|
562
|
+
name: string;
|
|
563
|
+
} | {
|
|
564
|
+
kind: 'email.change_requested';
|
|
565
|
+
email: string;
|
|
566
|
+
} | {
|
|
567
|
+
kind: 'password.changed';
|
|
568
|
+
} | {
|
|
569
|
+
kind: 'identity.linked';
|
|
570
|
+
provider: string;
|
|
571
|
+
} | {
|
|
572
|
+
kind: 'identity.unlinked';
|
|
573
|
+
provider: string;
|
|
574
|
+
} | {
|
|
575
|
+
kind: 'mfa.enabled';
|
|
576
|
+
} | {
|
|
577
|
+
kind: 'mfa.disabled';
|
|
578
|
+
} | {
|
|
579
|
+
kind: 'recovery_codes.regenerated';
|
|
580
|
+
} | {
|
|
581
|
+
kind: 'phone.added';
|
|
582
|
+
channel: 'sms' | 'whatsapp';
|
|
583
|
+
} | {
|
|
584
|
+
kind: 'phone.removed';
|
|
585
|
+
} | {
|
|
586
|
+
kind: 'passkey.added';
|
|
587
|
+
id: string;
|
|
588
|
+
} | {
|
|
589
|
+
kind: 'passkey.removed';
|
|
590
|
+
id: string;
|
|
591
|
+
} | {
|
|
592
|
+
kind: 'agent.disconnected';
|
|
593
|
+
id: string;
|
|
594
|
+
} | {
|
|
595
|
+
kind: 'sessions.ended';
|
|
596
|
+
};
|
|
597
|
+
interface AccountProps extends Omit<AuthFormProps, 'links' | 'returnTo' | 'onSuccess'> {
|
|
598
|
+
/** Called after "sign out everywhere". Default: go to `/`. A Promise keeps the button loading until it settles. */
|
|
599
|
+
onSignedOut?: () => void | Promise<unknown>;
|
|
600
|
+
/** The moment of a session, as the application writes dates. Default: the browser's own way, in the reader's time zone. */
|
|
601
|
+
formatDate?: (iso: string) => string;
|
|
602
|
+
/**
|
|
603
|
+
* The parts shown, in this order. Default: all of them, as listed in
|
|
604
|
+
* `AccountSection`. A part with nothing to show (the password of an account
|
|
605
|
+
* without one, agents when none is connected) stays out either way.
|
|
606
|
+
*/
|
|
607
|
+
sections?: AccountSection[];
|
|
608
|
+
/** Called after every change saved, with what changed. */
|
|
609
|
+
onSaved?: (event: AccountEvent) => void;
|
|
610
|
+
}
|
|
611
|
+
/**
|
|
612
|
+
* The signed-in person's account, in the application: their name, their
|
|
613
|
+
* password, the second step, and where they are signed in. Each part saves on
|
|
614
|
+
* its own. Like the other forms, it carries no styles.
|
|
615
|
+
*/
|
|
616
|
+
declare function Account(props: AccountProps): react.JSX.Element;
|
|
617
|
+
/** What each part of the account screen takes, shown on its own: `<Account />`'s props but `sections`. */
|
|
618
|
+
type AccountPartProps = Omit<AccountProps, 'sections'>;
|
|
619
|
+
/** The person's name. */
|
|
620
|
+
declare function AccountProfile(props: AccountPartProps): react.JSX.Element;
|
|
621
|
+
/** Changing the address: a link goes to the new one. */
|
|
622
|
+
declare function AccountEmail(props: AccountPartProps): react.JSX.Element;
|
|
623
|
+
/** Changing the password, for an account that has one. */
|
|
624
|
+
declare function AccountPassword(props: AccountPartProps): react.JSX.Element;
|
|
625
|
+
/** The providers the account signs in with. */
|
|
626
|
+
declare function AccountLinked(props: AccountPartProps): react.JSX.Element;
|
|
627
|
+
/** The second step with an authenticator app, and the recovery codes. */
|
|
628
|
+
declare function AccountSecondStep(props: AccountPartProps): react.JSX.Element;
|
|
629
|
+
/** The phone codes go to, where the workspace sends them. */
|
|
630
|
+
declare function AccountPhone(props: AccountPartProps): react.JSX.Element;
|
|
631
|
+
/** The account's passkeys. */
|
|
632
|
+
declare function AccountPasskeys(props: AccountPartProps): react.JSX.Element;
|
|
633
|
+
/** The AI agents the person connected, when there is one. */
|
|
634
|
+
declare function AccountAgents(props: AccountPartProps): react.JSX.Element;
|
|
635
|
+
/** Where the person is signed in, and "sign out everywhere". */
|
|
636
|
+
declare function AccountSessions(props: AccountPartProps): react.JSX.Element;
|
|
637
|
+
/** An action `<OrganizationMembers hide={...} />` never offers. */
|
|
638
|
+
type OrganizationMembersAction = 'archive' | 'delete' | 'rename' | 'leave';
|
|
639
|
+
/**
|
|
640
|
+
* What `<OrganizationMembers />` tells the application after each change it
|
|
641
|
+
* saved, for the application's own toast or its own data to follow.
|
|
642
|
+
*/
|
|
643
|
+
type OrganizationMembersEvent = {
|
|
644
|
+
kind: 'member.added';
|
|
645
|
+
organizationId: string;
|
|
646
|
+
userId: string;
|
|
647
|
+
email: string;
|
|
648
|
+
role: string;
|
|
649
|
+
} | {
|
|
650
|
+
kind: 'member.role_changed';
|
|
651
|
+
organizationId: string;
|
|
652
|
+
userId: string;
|
|
653
|
+
role: string;
|
|
654
|
+
previousRole: string;
|
|
655
|
+
} | {
|
|
656
|
+
kind: 'member.removed';
|
|
657
|
+
organizationId: string;
|
|
658
|
+
userId: string;
|
|
659
|
+
} | {
|
|
660
|
+
kind: 'member.left';
|
|
661
|
+
organizationId: string;
|
|
662
|
+
userId: string;
|
|
663
|
+
} | {
|
|
664
|
+
kind: 'member.invited_again';
|
|
665
|
+
organizationId: string;
|
|
666
|
+
userId: string;
|
|
667
|
+
} | {
|
|
668
|
+
kind: 'organization.renamed';
|
|
669
|
+
organizationId: string;
|
|
670
|
+
name: string;
|
|
671
|
+
} | {
|
|
672
|
+
kind: 'organization.archived';
|
|
673
|
+
organizationId: string;
|
|
674
|
+
} | {
|
|
675
|
+
kind: 'organization.deleted';
|
|
676
|
+
organizationId: string;
|
|
677
|
+
};
|
|
678
|
+
interface OrganizationMembersProps extends Omit<AuthFormProps, 'links' | 'returnTo' | 'onSuccess' | 'createAccounts'> {
|
|
679
|
+
/** The organization, by the id Cauthy gave it. */
|
|
680
|
+
organizationId: string;
|
|
681
|
+
/** The moment of a membership, as the application writes dates. Default: the browser's own way. */
|
|
682
|
+
formatDate?: (iso: string) => string;
|
|
683
|
+
/**
|
|
684
|
+
* The roles offered when adding a member or changing one's role: those for
|
|
685
|
+
* which it answers true. A member already holding another role keeps it,
|
|
686
|
+
* and it shows. Default: every role the person may give.
|
|
687
|
+
*/
|
|
688
|
+
roles?: (role: string, choice: OrganizationRoleChoice) => boolean;
|
|
689
|
+
/** Actions never offered, whatever the person's role allows. */
|
|
690
|
+
hide?: OrganizationMembersAction[];
|
|
691
|
+
/** A role's name wherever one shows: a member's, the role choices, adding one. Default: the name the catalog gives it. */
|
|
692
|
+
roleLabel?: (choice: OrganizationRoleChoice) => string;
|
|
693
|
+
/** Called after every change saved, with what changed. */
|
|
694
|
+
onSaved?: (event: OrganizationMembersEvent) => void;
|
|
695
|
+
}
|
|
696
|
+
/**
|
|
697
|
+
* The people of one of the signed-in person's organizations, administered
|
|
698
|
+
* from the application. What it offers follows the person's role in the
|
|
699
|
+
* system's catalog: cauthy:members read lists the people; manage adds them by
|
|
700
|
+
* address (one with no account is invited), changes their role and sends an
|
|
701
|
+
* invitation again; remove removes them. Anybody may leave. Only an owner
|
|
702
|
+
* gives the owner role or changes an owner. cauthy:organization update,
|
|
703
|
+
* archive and delete rename the organization, archive it, delete it. Cauthy
|
|
704
|
+
* checks each change with the person's own session; the application
|
|
705
|
+
* authorizes nothing. Like the other forms, it carries no styles.
|
|
706
|
+
*/
|
|
707
|
+
declare function OrganizationMembers(props: OrganizationMembersProps): react.JSX.Element;
|
|
708
|
+
|
|
709
|
+
type ListPart = 'organizations' | 'organizationList' | 'organization' | 'organizationRole' | 'retry';
|
|
710
|
+
interface OrganizationsProps extends Omit<OrganizationMembersProps, 'organizationId'> {
|
|
711
|
+
/** Only one system's organizations. */
|
|
712
|
+
system?: string;
|
|
713
|
+
/** The one shown first. Default: the first of the list. */
|
|
714
|
+
defaultOrganizationId?: string;
|
|
715
|
+
/** Called when the person picks one. */
|
|
716
|
+
onSelect?: (organization: OrganizationSeat) => void;
|
|
717
|
+
/** Show the people of the one picked. Default: true. */
|
|
718
|
+
showMembers?: boolean;
|
|
719
|
+
/** A class for each part of the list; the members part takes `classNames`. */
|
|
720
|
+
listClassNames?: Partial<Record<ListPart, string>>;
|
|
721
|
+
}
|
|
722
|
+
declare function Organizations(props: OrganizationsProps): react.JSX.Element;
|
|
723
|
+
|
|
724
|
+
export { AcceptInvite, type AcceptInviteEvent, type AcceptInviteProps, Account, AccountAgents, AccountEmail, type AccountEvent, AccountLinked, type AccountPartProps, AccountPasskeys, AccountPassword, AccountPhone, AccountProfile, type AccountProps, AccountSecondStep, type AccountSection, AccountSessions, type AuthAlertProps, type AuthBadgeProps, type AuthButtonProps, type AuthCheckboxProps, type AuthComponents, type AuthConfirmOptions, type AuthDividerProps, type AuthFieldProps, type AuthFormLayoutProps, type AuthFormProps, type AuthInputProps, type AuthLinkProps, type AuthSelectProps, type AuthTextProps, type AuthTexts, CauthyProvider, type CauthyProviderProps, ForgotPassword, GoogleOneTap, type GoogleOneTapProps, OrganizationMembers, type OrganizationMembersAction, type OrganizationMembersEvent, type OrganizationMembersProps, Organizations, type OrganizationsProps, PendingTerms, type PendingTermsProps, ResetPassword, type SessionContext, SignIn, SignUp, type UseOrganizations, UserButton, type UserButtonProps, type UserButtonTexts, VerifyEmail, initialsOf, useAuth, useOrganizations, useSession, useSignInFlow };
|