cauthy-auth 0.19.0 → 0.22.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.
Files changed (43) hide show
  1. package/dist/{cauthy-Bn3iv50y.d.ts → cauthy-DGAy45G2.d.ts} +1 -1
  2. package/dist/{cauthy-C29HCvag.d.mts → cauthy-XkIbG5gE.d.mts} +1 -1
  3. package/dist/client.d.mts +157 -2
  4. package/dist/client.d.ts +157 -2
  5. package/dist/client.js +37 -2
  6. package/dist/client.js.map +1 -1
  7. package/dist/client.mjs +37 -2
  8. package/dist/client.mjs.map +1 -1
  9. package/dist/express.d.mts +2 -2
  10. package/dist/express.d.ts +2 -2
  11. package/dist/fastify.d.mts +2 -2
  12. package/dist/fastify.d.ts +2 -2
  13. package/dist/hono.d.mts +2 -2
  14. package/dist/hono.d.ts +2 -2
  15. package/dist/index.d.mts +2 -2
  16. package/dist/index.d.ts +2 -2
  17. package/dist/index.js +181 -6
  18. package/dist/index.js.map +1 -1
  19. package/dist/index.mjs +181 -6
  20. package/dist/index.mjs.map +1 -1
  21. package/dist/next.d.mts +2 -2
  22. package/dist/next.d.ts +2 -2
  23. package/dist/react.d.mts +192 -1
  24. package/dist/react.d.ts +192 -1
  25. package/dist/react.js +279 -23
  26. package/dist/react.js.map +1 -1
  27. package/dist/react.mjs +278 -23
  28. package/dist/react.mjs.map +1 -1
  29. package/dist/svelte.d.mts +3 -3
  30. package/dist/svelte.d.ts +3 -3
  31. package/dist/svelte.js +37 -2
  32. package/dist/svelte.js.map +1 -1
  33. package/dist/svelte.mjs +37 -2
  34. package/dist/svelte.mjs.map +1 -1
  35. package/dist/{system-ZD_Wa8Bm.d.mts → system-BxMsSIu1.d.mts} +2 -0
  36. package/dist/{system-DhRr_WxR.d.ts → system-DTIeDXDP.d.ts} +2 -0
  37. package/dist/vue.d.mts +3 -3
  38. package/dist/vue.d.ts +3 -3
  39. package/dist/vue.js +37 -2
  40. package/dist/vue.js.map +1 -1
  41. package/dist/vue.mjs +37 -2
  42. package/dist/vue.mjs.map +1 -1
  43. package/package.json +1 -1
package/dist/react.mjs CHANGED
@@ -229,8 +229,14 @@ function createAuthClient(options = {}) {
229
229
  return null;
230
230
  }
231
231
  }
232
+ const upgradeUrl = (provider, o = {}) => `${base}/me/upgrade/social/${encodeURIComponent(provider)}${o.returnTo ? `?return_to=${encodeURIComponent(o.returnTo)}` : ""}`;
232
233
  const linkUrl = (provider, o = {}) => `${base}/me/identities/link/${encodeURIComponent(provider)}${o.returnTo ? `?return_to=${encodeURIComponent(o.returnTo)}` : ""}`;
233
234
  const socialUrl = (provider, o = {}) => `${base}/sign-in/social/${encodeURIComponent(provider)}${o.returnTo ? `?return_to=${encodeURIComponent(o.returnTo)}` : ""}`;
235
+ const ssoUrl = (target, o = {}) => {
236
+ const q = new URLSearchParams("connection" in target ? { connection: target.connection } : { email: target.email.trim() });
237
+ if (o.returnTo) q.set("return_to", o.returnTo);
238
+ return `${base}/sign-in/sso?${q}`;
239
+ };
234
240
  const passkeyUrl = (o = {}) => {
235
241
  const q = new URLSearchParams({ method: "passkey" });
236
242
  if (o.returnTo) q.set("return_to", o.returnTo);
@@ -242,11 +248,11 @@ function createAuthClient(options = {}) {
242
248
  const res = await doFetch(`${base}/methods`, { credentials: "same-origin", headers: { accept: "application/json" } });
243
249
  if (res.ok) {
244
250
  const m = await res.json();
245
- return { providers: [], signUp: true, magicLink: false, passkey: false, ...m, passkeyHere: m.passkeyHere === true, passkeyOnCauthy: m.passkeyOnCauthy ?? m.passkey === true };
251
+ return { providers: [], signUp: true, magicLink: false, passkey: false, ...m, passkeyHere: m.passkeyHere === true, passkeyOnCauthy: m.passkeyOnCauthy ?? m.passkey === true, sso: m.sso === true };
246
252
  }
247
253
  } catch {
248
254
  }
249
- return { providers: [], signUp: true, magicLink: false, passkey: false, passkeyHere: false, passkeyOnCauthy: false };
255
+ return { providers: [], signUp: true, magicLink: false, passkey: false, passkeyHere: false, passkeyOnCauthy: false, sso: false };
250
256
  }
251
257
  async function ceremony(begin, finish, form, run, more = {}) {
252
258
  const begun = await post(begin, form, null);
@@ -261,6 +267,7 @@ function createAuthClient(options = {}) {
261
267
  }
262
268
  return {
263
269
  signIn: {
270
+ anonymously: (f = {}) => post("/sign-in/anonymous", {}, null, f.captchaToken),
264
271
  email: (f) => post("/sign-in/email", { email: f.email, password: f.password }, firstProblem(checkEmail(f.email), checkPassword(f.password)), f.captchaToken),
265
272
  mfa: (f) => post("/sign-in/mfa", { code: f.code }, checkCode(f.code)),
266
273
  mfaMethods: () => post("/sign-in/mfa/methods", {}, null),
@@ -344,6 +351,11 @@ function createAuthClient(options = {}) {
344
351
  socialUrl,
345
352
  social(provider, o) {
346
353
  window.location.assign(socialUrl(provider, o));
354
+ },
355
+ ssoDiscover: (f) => post("/sign-in/sso/discover", { email: f.email.trim() }, checkEmail(f.email)),
356
+ ssoUrl,
357
+ sso(target, o) {
358
+ window.location.assign(ssoUrl(target, o));
347
359
  }
348
360
  },
349
361
  signUp: {
@@ -353,6 +365,24 @@ function createAuthClient(options = {}) {
353
365
  resetPassword: (f) => post("/reset-password", { token: f.token, password: f.password }, checkNewPassword(f.password)),
354
366
  verifyEmail: (f) => post("/verify-email", { token: f.token }, null),
355
367
  signOut: () => post("/sign-out", {}, null),
368
+ organizations: {
369
+ async list(system) {
370
+ const body = await read(`/me/organizations${system ? `?system=${encodeURIComponent(system)}` : ""}`);
371
+ return body && Array.isArray(body.organizations) ? body.organizations : [];
372
+ },
373
+ async members(id) {
374
+ const body = await read(`/me/organizations/members?id=${encodeURIComponent(id)}`);
375
+ return body && Array.isArray(body.members) ? body.members : null;
376
+ },
377
+ async roles(id) {
378
+ const body = await read(`/me/organizations/roles?id=${encodeURIComponent(id)}`);
379
+ return body && Array.isArray(body.roles) ? body.roles : null;
380
+ },
381
+ add: (id, f) => post("/me/organizations/members/add", { organizationId: id, email: f.email, role: f.role, name: f.name ?? "", locale: f.locale ?? "" }, checkEmail(f.email)),
382
+ setRole: (id, userId, role) => post("/me/organizations/members/role", { organizationId: id, userId, role }, null),
383
+ remove: (id, userId) => post("/me/organizations/members/remove", { organizationId: id, userId }, null),
384
+ inviteAgain: (id, userId, f = {}) => post("/me/organizations/members/invite", { organizationId: id, userId, locale: f.locale ?? "" }, null)
385
+ },
356
386
  account: {
357
387
  async get() {
358
388
  const body = await read("/me");
@@ -391,6 +421,11 @@ function createAuthClient(options = {}) {
391
421
  return body && Array.isArray(body.sessions) ? body.sessions : [];
392
422
  },
393
423
  signOutEverywhere: () => post("/me/sessions/end", {}, null),
424
+ upgrade: (f) => post("/me/upgrade", { email: f.email, password: f.password, name: f.name ?? "" }, firstProblem(checkName(f.name), checkEmail(f.email), checkNewPassword(f.password))),
425
+ upgradeUrl,
426
+ upgradeWith(provider, o) {
427
+ window.location.assign(upgradeUrl(provider, o));
428
+ },
394
429
  async agents() {
395
430
  const body = await read("/me/agents");
396
431
  return body && Array.isArray(body.agents) ? body.agents : [];
@@ -564,7 +599,30 @@ var TEXTS = {
564
599
  linkWith: "Link",
565
600
  unlink: "Unlink",
566
601
  linked: "The account was linked.",
602
+ ssoOnly: "Your company signs you in to this account.",
603
+ members: "Members",
604
+ membersHidden: "Your role here does not let you see the members.",
605
+ organizationMissing: "You do not belong to this organization.",
606
+ memberYou: "you",
607
+ memberInvited: "invited",
608
+ memberManager: "manages members",
609
+ memberRole: "Role",
610
+ memberAdd: "Add member",
611
+ memberAdded: "{email} is a member now.",
612
+ memberRemove: "Remove",
613
+ memberRemoveConfirm: "Remove {who}?",
614
+ memberLeave: "Leave",
615
+ memberLeaveConfirm: "Leave {org}? You will need an invitation to come back.",
616
+ memberInviteAgain: "Send the invitation again",
617
+ memberInvitationSent: "The invitation is on its way.",
618
+ yes: "Yes",
619
+ cancel: "Cancel",
567
620
  errors: {
621
+ not_allowed: "Your role in this organization does not allow that.",
622
+ last_manager: "Somebody else must manage the members first: give that role to another member.",
623
+ already_member: "That person already belongs to the organization. Change their role instead.",
624
+ unknown_role: "Choose one of the roles offered.",
625
+ user_not_active: "That account is disabled.",
568
626
  required: "This is required.",
569
627
  invalid_email: "That does not look like an email address.",
570
628
  too_short: "Use at least 8 characters.",
@@ -592,7 +650,15 @@ var TEXTS = {
592
650
  captcha_failed: "The check that you are not a bot did not pass. Try it again.",
593
651
  passkey_failed: "The passkey could not be used. Try again, or sign in another way.",
594
652
  passkey_exists: "This device already has a passkey for your account.",
595
- passkey_unavailable: "Passkeys cannot be used here."
653
+ passkey_unavailable: "Passkeys cannot be used here.",
654
+ sso_required: "This address signs in through its company.",
655
+ sso_not_found: "No company sign-in answers for this address.",
656
+ sso_failed: "The sign-in with your company could not be completed. Try again.",
657
+ sso_unavailable: "Your company's sign-in cannot be reached right now. Try again in a moment.",
658
+ invalid_assertion: "Your company's answer could not be checked. Try again.",
659
+ provisioning_disabled: "Your company's sign-in worked, but this workspace has no account for you. Ask its admin to add you.",
660
+ connection_inactive: "Your company's sign-in is turned off for this workspace.",
661
+ invalid_grant: "That sign-in expired. Try again."
596
662
  }
597
663
  },
598
664
  es: {
@@ -679,7 +745,30 @@ var TEXTS = {
679
745
  linkWith: "Vincular",
680
746
  unlink: "Desvincular",
681
747
  linked: "La cuenta qued\xF3 vinculada.",
748
+ ssoOnly: "A esta cuenta entras con el inicio de sesi\xF3n de tu empresa.",
749
+ members: "Miembros",
750
+ membersHidden: "Tu rol aqu\xED no te deja ver los miembros.",
751
+ organizationMissing: "No perteneces a esta organizaci\xF3n.",
752
+ memberYou: "t\xFA",
753
+ memberInvited: "invitado",
754
+ memberManager: "administra los miembros",
755
+ memberRole: "Rol",
756
+ memberAdd: "Agregar miembro",
757
+ memberAdded: "{email} ya es miembro.",
758
+ memberRemove: "Quitar",
759
+ memberRemoveConfirm: "\xBFQuitar a {who}?",
760
+ memberLeave: "Salir",
761
+ memberLeaveConfirm: "\xBFSalir de {org}? Necesitar\xE1s una invitaci\xF3n para volver.",
762
+ memberInviteAgain: "Enviar la invitaci\xF3n de nuevo",
763
+ memberInvitationSent: "La invitaci\xF3n va en camino.",
764
+ yes: "S\xED",
765
+ cancel: "Cancelar",
682
766
  errors: {
767
+ not_allowed: "Tu rol en esta organizaci\xF3n no permite eso.",
768
+ last_manager: "Primero alguien m\xE1s debe administrar los miembros: dale ese rol a otro miembro.",
769
+ already_member: "Esa persona ya pertenece a la organizaci\xF3n. Cambia su rol.",
770
+ unknown_role: "Escoge uno de los roles ofrecidos.",
771
+ user_not_active: "Esa cuenta est\xE1 desactivada.",
683
772
  required: "Este dato es obligatorio.",
684
773
  invalid_email: "Eso no parece un correo.",
685
774
  too_short: "Usa al menos 8 caracteres.",
@@ -707,7 +796,15 @@ var TEXTS = {
707
796
  captcha_failed: "La verificaci\xF3n de que no eres un robot no pas\xF3. Int\xE9ntalo de nuevo.",
708
797
  passkey_failed: "No se pudo usar la llave de acceso. Intenta de nuevo o entra de otra forma.",
709
798
  passkey_exists: "Este dispositivo ya tiene una llave de acceso de tu cuenta.",
710
- passkey_unavailable: "Aqu\xED no se pueden usar llaves de acceso."
799
+ passkey_unavailable: "Aqu\xED no se pueden usar llaves de acceso.",
800
+ sso_required: "Este correo entra con el inicio de sesi\xF3n de su empresa.",
801
+ sso_not_found: "Ninguna empresa usa inicio de sesi\xF3n propio con este correo.",
802
+ sso_failed: "No se pudo completar el ingreso con tu empresa. Intenta de nuevo.",
803
+ sso_unavailable: "Ahora no se puede llegar al inicio de sesi\xF3n de tu empresa. Intenta en un momento.",
804
+ invalid_assertion: "No se pudo verificar la respuesta de tu empresa. Intenta de nuevo.",
805
+ provisioning_disabled: "El ingreso con tu empresa funcion\xF3, pero este workspace no tiene una cuenta para ti. P\xEDdele a su admin que te agregue.",
806
+ connection_inactive: "El inicio de sesi\xF3n de tu empresa est\xE1 apagado en este workspace.",
807
+ invalid_grant: "Ese ingreso venci\xF3. Intenta de nuevo."
711
808
  }
712
809
  }
713
810
  };
@@ -900,6 +997,25 @@ function SignIn(props) {
900
997
  };
901
998
  const autofill = useRef(null);
902
999
  const [offer, setOffer] = useState(0);
1000
+ const [company, setCompany] = useState(null);
1001
+ useEffect(() => {
1002
+ if (!methods?.sso || checkEmail(email) !== null) return setCompany(null);
1003
+ let current = true;
1004
+ const t = setTimeout(() => {
1005
+ void auth.signIn.ssoDiscover({ email }).then((r) => {
1006
+ if (current) setCompany(r.ok && r.status === "found" ? r.connection : null);
1007
+ });
1008
+ }, 350);
1009
+ return () => {
1010
+ current = false;
1011
+ clearTimeout(t);
1012
+ };
1013
+ }, [email, methods]);
1014
+ const toCompany = () => {
1015
+ autofill.current?.abort();
1016
+ f.setBusy(true);
1017
+ auth.signIn.sso({ email }, { returnTo: props.returnTo });
1018
+ };
903
1019
  useEffect(() => {
904
1020
  void auth.methods().then(setMethods);
905
1021
  const back = returnedError();
@@ -932,9 +1048,11 @@ function SignIn(props) {
932
1048
  autofill.current?.abort();
933
1049
  f.setBusy(true);
934
1050
  f.setError(null);
1051
+ if (step === "password" && company?.enforced) return toCompany();
935
1052
  const r = step === "code" ? await auth.signIn.mfa({ code }) : step === "sent" ? await auth.signIn.emailCode({ code }) : await auth.signIn.email({ email, password, captchaToken: challenge.token });
936
1053
  f.setBusy(false);
937
1054
  if (step === "password") challenge.renew();
1055
+ if (!r.ok && r.error.code === "sso_required") return toCompany();
938
1056
  if (!r.ok) {
939
1057
  setOffer((n) => n + 1);
940
1058
  return f.setError(r.error);
@@ -960,6 +1078,7 @@ function SignIn(props) {
960
1078
  const r = await auth.signIn.magicLink({ email, captchaToken: challenge.token, create: props.createAccounts, returnTo: props.returnTo });
961
1079
  f.setBusy(false);
962
1080
  challenge.renew();
1081
+ if (!r.ok && r.error.code === "sso_required") return toCompany();
963
1082
  if (!r.ok) return f.setError(r.error);
964
1083
  setStep("sent");
965
1084
  };
@@ -994,23 +1113,31 @@ function SignIn(props) {
994
1113
  methods?.passkey && /* @__PURE__ */ jsx(f.Button, { type: "button", disabled: f.busy, className: f.cx("providerButton"), onClick: () => void usePasskey(), children: f.t.usePasskey }),
995
1114
  ((methods?.providers.length ?? 0) > 0 || methods?.passkey) && /* @__PURE__ */ jsx("p", { className: f.cx("separator"), children: f.t.orWithEmail }),
996
1115
  /* @__PURE__ */ jsx(Field, { f, name: "email", type: "email", label: f.t.email, value: email, autoComplete: methods?.passkeyHere ? "username webauthn" : "username", required: true, onChange: setEmail }),
997
- /* @__PURE__ */ jsx(
998
- Field,
999
- {
1000
- f,
1001
- name: "password",
1002
- type: "password",
1003
- label: f.t.password,
1004
- value: password,
1005
- autoComplete: "current-password",
1006
- required: true,
1007
- onChange: setPassword,
1008
- aside: props.links?.forgotPassword ? /* @__PURE__ */ jsx("a", { className: f.cx("link"), href: props.links.forgotPassword, children: f.t.forgotPassword }) : void 0
1009
- }
1010
- ),
1011
- challenge.node,
1012
- /* @__PURE__ */ jsx(f.Button, { type: "submit", disabled: f.busy, className: f.cx("button"), children: f.t.signIn }),
1013
- methods?.magicLink && /* @__PURE__ */ jsx(f.Button, { type: "button", disabled: f.busy, className: f.cx("providerButton"), onClick: () => void sendLink(), children: f.t.emailMeALink }),
1116
+ company && /* @__PURE__ */ jsxs(f.Button, { type: "button", disabled: f.busy, className: f.cx(company.enforced ? "button" : "providerButton"), onClick: toCompany, children: [
1117
+ f.t.continueWith,
1118
+ " ",
1119
+ company.name
1120
+ ] }),
1121
+ company?.enforced && /* @__PURE__ */ jsx("p", { className: f.cx("notice"), children: f.t.ssoOnly }),
1122
+ !company?.enforced && /* @__PURE__ */ jsxs(Fragment, { children: [
1123
+ /* @__PURE__ */ jsx(
1124
+ Field,
1125
+ {
1126
+ f,
1127
+ name: "password",
1128
+ type: "password",
1129
+ label: f.t.password,
1130
+ value: password,
1131
+ autoComplete: "current-password",
1132
+ required: true,
1133
+ onChange: setPassword,
1134
+ aside: props.links?.forgotPassword ? /* @__PURE__ */ jsx("a", { className: f.cx("link"), href: props.links.forgotPassword, children: f.t.forgotPassword }) : void 0
1135
+ }
1136
+ ),
1137
+ challenge.node,
1138
+ /* @__PURE__ */ jsx(f.Button, { type: "submit", disabled: f.busy, className: f.cx("button"), children: f.t.signIn })
1139
+ ] }),
1140
+ methods?.magicLink && !company?.enforced && /* @__PURE__ */ jsx(f.Button, { type: "button", disabled: f.busy, className: f.cx("providerButton"), onClick: () => void sendLink(), children: f.t.emailMeALink }),
1014
1141
  methods?.signUp !== false && props.links?.signUp && /* @__PURE__ */ jsxs("p", { className: f.cx("footer"), children: [
1015
1142
  f.t.noAccount,
1016
1143
  " ",
@@ -1045,7 +1172,7 @@ function SignUp(props) {
1045
1172
  e.preventDefault();
1046
1173
  f.setBusy(true);
1047
1174
  f.setError(null);
1048
- const r = await auth.signUp.email({ name, email, password, captchaToken: challenge.token });
1175
+ const r = auth.session?.user.isAnonymous === true ? await auth.account.upgrade({ name, email, password }) : await auth.signUp.email({ name, email, password, captchaToken: challenge.token });
1049
1176
  f.setBusy(false);
1050
1177
  challenge.renew();
1051
1178
  if (!r.ok) return f.setError(r.error);
@@ -1215,6 +1342,130 @@ function Account(props) {
1215
1342
  ] })
1216
1343
  ] });
1217
1344
  }
1345
+ function OrganizationMembers(props) {
1346
+ const auth = useAuth();
1347
+ const { root } = useForm(props);
1348
+ const { f, done, setDone, run } = useSection(props);
1349
+ const problem = f.error && f.error.field !== "email" ? f.error : null;
1350
+ const [seat, setSeat] = useState(void 0);
1351
+ const [members, setMembers] = useState(null);
1352
+ const [roles, setRoles] = useState([]);
1353
+ const [email, setEmail] = useState("");
1354
+ const [role, setRole] = useState("");
1355
+ const [asking, setAsking] = useState(null);
1356
+ const id = props.organizationId;
1357
+ const when = props.formatDate ?? ((iso) => new Date(iso).toLocaleDateString());
1358
+ const load = async () => {
1359
+ const [list, people, choices] = await Promise.all([auth.organizations.list(), auth.organizations.members(id), auth.organizations.roles(id)]);
1360
+ setSeat(list.find((o) => o.id === id) ?? null);
1361
+ setMembers(people);
1362
+ setRoles(choices ?? []);
1363
+ if (choices && choices.length > 0 && !choices.some((c) => c.role === role)) setRole(choices[0].role);
1364
+ };
1365
+ useEffect(() => {
1366
+ void load();
1367
+ }, [id]);
1368
+ if (seat === void 0) return /* @__PURE__ */ jsx("div", { className: f.cx("account"), ...root, "aria-busy": "true" });
1369
+ if (seat === null) return /* @__PURE__ */ jsx("div", { className: f.cx("account"), ...root, children: /* @__PURE__ */ jsx("p", { className: f.cx("notice"), children: f.t.organizationMissing }) });
1370
+ const manage = seat.can.manageMembers;
1371
+ const label = (r) => roles.find((c) => c.role === r)?.name || r;
1372
+ const add = async (e) => {
1373
+ e.preventDefault();
1374
+ const r = await run(() => auth.organizations.add(id, { email, role, locale: props.locale }));
1375
+ if (!r.ok) return;
1376
+ setEmail("");
1377
+ setDone(f.t.memberAdded.replace("{email}", r.member.email));
1378
+ await load();
1379
+ };
1380
+ const change = async (m, next) => {
1381
+ const r = await run(() => auth.organizations.setRole(id, m.userId, next));
1382
+ if (r.ok) await load();
1383
+ };
1384
+ const remove = async (m) => {
1385
+ setAsking(null);
1386
+ const r = await run(() => auth.organizations.remove(id, m.userId));
1387
+ if (!r.ok) return;
1388
+ if (m.you) setSeat(null);
1389
+ else await load();
1390
+ };
1391
+ const inviteAgain = async (m) => {
1392
+ const r = await run(() => auth.organizations.inviteAgain(id, m.userId, { locale: props.locale }));
1393
+ if (r.ok) setDone(f.t.memberInvitationSent);
1394
+ };
1395
+ return /* @__PURE__ */ jsxs("div", { className: f.cx("account"), ...root, children: [
1396
+ /* @__PURE__ */ jsxs("section", { className: f.cx("section"), children: [
1397
+ /* @__PURE__ */ jsxs("h2", { className: f.cx("heading"), children: [
1398
+ f.t.members,
1399
+ " \xB7 ",
1400
+ seat.name
1401
+ ] }),
1402
+ problem && /* @__PURE__ */ jsx("p", { role: "alert", className: f.cx("error"), children: f.say(problem) }),
1403
+ members === null ? /* @__PURE__ */ jsxs(Fragment, { children: [
1404
+ /* @__PURE__ */ jsx("p", { className: f.cx("notice"), children: f.t.membersHidden }),
1405
+ auth.session && (asking === auth.session.user.id ? /* @__PURE__ */ jsxs("span", { role: "group", "aria-label": f.t.memberLeave, children: [
1406
+ /* @__PURE__ */ jsx("span", { children: f.t.memberLeaveConfirm.replace("{org}", seat.name) }),
1407
+ " ",
1408
+ /* @__PURE__ */ jsx(
1409
+ f.Button,
1410
+ {
1411
+ type: "button",
1412
+ disabled: f.busy,
1413
+ className: f.cx("providerButton"),
1414
+ onClick: () => void remove({ userId: auth.session.user.id, you: true }),
1415
+ children: f.t.yes
1416
+ }
1417
+ ),
1418
+ /* @__PURE__ */ jsx(f.Button, { type: "button", disabled: f.busy, className: f.cx("providerButton"), onClick: () => setAsking(null), children: f.t.cancel })
1419
+ ] }) : /* @__PURE__ */ jsx(f.Button, { type: "button", disabled: f.busy, className: f.cx("providerButton"), onClick: () => setAsking(auth.session.user.id), children: f.t.memberLeave }))
1420
+ ] }) : /* @__PURE__ */ jsx("ul", { className: f.cx("sessions"), children: members.map((m) => {
1421
+ const who = m.name || m.email;
1422
+ return /* @__PURE__ */ jsxs("li", { className: f.cx("session"), children: [
1423
+ /* @__PURE__ */ jsxs("span", { children: [
1424
+ who,
1425
+ m.name ? ` \xB7 ${m.email}` : "",
1426
+ m.you ? ` (${f.t.memberYou})` : "",
1427
+ m.invited ? ` \xB7 ${f.t.memberInvited}` : "",
1428
+ m.manager ? ` \xB7 ${f.t.memberManager}` : "",
1429
+ " \xB7 ",
1430
+ when(m.since)
1431
+ ] }),
1432
+ " ",
1433
+ manage && roles.length > 0 ? /* @__PURE__ */ jsx(
1434
+ "select",
1435
+ {
1436
+ "aria-label": `${f.t.memberRole}: ${who}`,
1437
+ className: f.cx("input"),
1438
+ value: m.role,
1439
+ disabled: f.busy,
1440
+ onChange: (e) => void change(m, e.target.value),
1441
+ children: roles.map((c) => /* @__PURE__ */ jsx("option", { value: c.role, children: c.name || c.role }, c.role))
1442
+ }
1443
+ ) : /* @__PURE__ */ jsx("span", { children: label(m.role) }),
1444
+ " ",
1445
+ asking === m.userId ? /* @__PURE__ */ jsxs("span", { role: "group", "aria-label": m.you ? f.t.memberLeave : f.t.memberRemove, children: [
1446
+ /* @__PURE__ */ jsx("span", { children: m.you ? f.t.memberLeaveConfirm.replace("{org}", seat.name) : f.t.memberRemoveConfirm.replace("{who}", who) }),
1447
+ " ",
1448
+ /* @__PURE__ */ jsx(f.Button, { type: "button", disabled: f.busy, className: f.cx("providerButton"), onClick: () => void remove(m), children: f.t.yes }),
1449
+ /* @__PURE__ */ jsx(f.Button, { type: "button", disabled: f.busy, className: f.cx("providerButton"), onClick: () => setAsking(null), children: f.t.cancel })
1450
+ ] }) : /* @__PURE__ */ jsxs(Fragment, { children: [
1451
+ manage && m.invited && /* @__PURE__ */ jsx(f.Button, { type: "button", disabled: f.busy, className: f.cx("providerButton"), onClick: () => void inviteAgain(m), children: f.t.memberInviteAgain }),
1452
+ (manage || m.you) && /* @__PURE__ */ jsx(f.Button, { type: "button", disabled: f.busy, className: f.cx("providerButton"), onClick: () => setAsking(m.userId), children: m.you ? f.t.memberLeave : f.t.memberRemove })
1453
+ ] })
1454
+ ] }, m.userId);
1455
+ }) }),
1456
+ done && /* @__PURE__ */ jsx("p", { role: "status", className: f.cx("notice"), children: done })
1457
+ ] }),
1458
+ manage && roles.length > 0 && /* @__PURE__ */ jsxs("form", { className: f.cx("section"), onSubmit: add, noValidate: true, children: [
1459
+ /* @__PURE__ */ jsx("h2", { className: f.cx("heading"), children: f.t.memberAdd }),
1460
+ /* @__PURE__ */ jsx(Field, { f, name: "email", type: "email", label: f.t.email, value: email, autoComplete: "off", required: true, onChange: setEmail }),
1461
+ /* @__PURE__ */ jsxs("label", { className: f.cx("field"), children: [
1462
+ /* @__PURE__ */ jsx("span", { className: f.cx("label"), children: f.t.memberRole }),
1463
+ /* @__PURE__ */ jsx("select", { name: "role", className: f.cx("input"), value: role, onChange: (e) => setRole(e.target.value), children: roles.map((c) => /* @__PURE__ */ jsx("option", { value: c.role, children: c.name || c.role }, c.role)) })
1464
+ ] }),
1465
+ /* @__PURE__ */ jsx(f.Button, { type: "submit", disabled: f.busy, className: f.cx("button"), children: f.t.memberAdd })
1466
+ ] })
1467
+ ] });
1468
+ }
1218
1469
  function PasskeysPart({ props, account, accountUrl, when }) {
1219
1470
  const auth = useAuth();
1220
1471
  const { f, done, setDone, run, general } = useSection(props);
@@ -1636,6 +1887,7 @@ function useAuth() {
1636
1887
  ...client,
1637
1888
  signIn: {
1638
1889
  ...client.signIn,
1890
+ anonymously: (f) => then(client.signIn.anonymously(f)),
1639
1891
  email: (f) => then(client.signIn.email(f)),
1640
1892
  mfa: (f) => then(client.signIn.mfa(f)),
1641
1893
  magicLinkVerify: (f) => then(client.signIn.magicLinkVerify(f)),
@@ -1651,7 +1903,9 @@ function useAuth() {
1651
1903
  // What is on screen says the new name, and knows when the session ended.
1652
1904
  update: (f) => then(client.account.update(f)),
1653
1905
  changePassword: (f) => then(client.account.changePassword(f)),
1654
- signOutEverywhere: () => then(client.account.signOutEverywhere())
1906
+ signOutEverywhere: () => then(client.account.signOutEverywhere()),
1907
+ // The guest is now the account: what is on screen says so.
1908
+ upgrade: (f) => then(client.account.upgrade(f))
1655
1909
  },
1656
1910
  session,
1657
1911
  status,
@@ -1664,6 +1918,7 @@ export {
1664
1918
  CauthyProvider,
1665
1919
  ForgotPassword,
1666
1920
  GoogleOneTap,
1921
+ OrganizationMembers,
1667
1922
  ResetPassword,
1668
1923
  SignIn,
1669
1924
  SignUp,