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.
- package/dist/{cauthy-Bn3iv50y.d.ts → cauthy-DGAy45G2.d.ts} +1 -1
- package/dist/{cauthy-C29HCvag.d.mts → cauthy-XkIbG5gE.d.mts} +1 -1
- package/dist/client.d.mts +157 -2
- package/dist/client.d.ts +157 -2
- package/dist/client.js +37 -2
- package/dist/client.js.map +1 -1
- package/dist/client.mjs +37 -2
- package/dist/client.mjs.map +1 -1
- package/dist/express.d.mts +2 -2
- package/dist/express.d.ts +2 -2
- package/dist/fastify.d.mts +2 -2
- package/dist/fastify.d.ts +2 -2
- package/dist/hono.d.mts +2 -2
- package/dist/hono.d.ts +2 -2
- package/dist/index.d.mts +2 -2
- package/dist/index.d.ts +2 -2
- package/dist/index.js +181 -6
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +181 -6
- package/dist/index.mjs.map +1 -1
- package/dist/next.d.mts +2 -2
- package/dist/next.d.ts +2 -2
- package/dist/react.d.mts +192 -1
- package/dist/react.d.ts +192 -1
- package/dist/react.js +279 -23
- package/dist/react.js.map +1 -1
- package/dist/react.mjs +278 -23
- package/dist/react.mjs.map +1 -1
- package/dist/svelte.d.mts +3 -3
- package/dist/svelte.d.ts +3 -3
- package/dist/svelte.js +37 -2
- package/dist/svelte.js.map +1 -1
- package/dist/svelte.mjs +37 -2
- package/dist/svelte.mjs.map +1 -1
- package/dist/{system-ZD_Wa8Bm.d.mts → system-BxMsSIu1.d.mts} +2 -0
- package/dist/{system-DhRr_WxR.d.ts → system-DTIeDXDP.d.ts} +2 -0
- package/dist/vue.d.mts +3 -3
- package/dist/vue.d.ts +3 -3
- package/dist/vue.js +37 -2
- package/dist/vue.js.map +1 -1
- package/dist/vue.mjs +37 -2
- package/dist/vue.mjs.map +1 -1
- package/package.json +1 -1
package/dist/react.js
CHANGED
|
@@ -25,6 +25,7 @@ __export(react_exports, {
|
|
|
25
25
|
CauthyProvider: () => CauthyProvider,
|
|
26
26
|
ForgotPassword: () => ForgotPassword,
|
|
27
27
|
GoogleOneTap: () => GoogleOneTap,
|
|
28
|
+
OrganizationMembers: () => OrganizationMembers,
|
|
28
29
|
ResetPassword: () => ResetPassword,
|
|
29
30
|
SignIn: () => SignIn,
|
|
30
31
|
SignUp: () => SignUp,
|
|
@@ -266,8 +267,14 @@ function createAuthClient(options = {}) {
|
|
|
266
267
|
return null;
|
|
267
268
|
}
|
|
268
269
|
}
|
|
270
|
+
const upgradeUrl = (provider, o = {}) => `${base}/me/upgrade/social/${encodeURIComponent(provider)}${o.returnTo ? `?return_to=${encodeURIComponent(o.returnTo)}` : ""}`;
|
|
269
271
|
const linkUrl = (provider, o = {}) => `${base}/me/identities/link/${encodeURIComponent(provider)}${o.returnTo ? `?return_to=${encodeURIComponent(o.returnTo)}` : ""}`;
|
|
270
272
|
const socialUrl = (provider, o = {}) => `${base}/sign-in/social/${encodeURIComponent(provider)}${o.returnTo ? `?return_to=${encodeURIComponent(o.returnTo)}` : ""}`;
|
|
273
|
+
const ssoUrl = (target, o = {}) => {
|
|
274
|
+
const q = new URLSearchParams("connection" in target ? { connection: target.connection } : { email: target.email.trim() });
|
|
275
|
+
if (o.returnTo) q.set("return_to", o.returnTo);
|
|
276
|
+
return `${base}/sign-in/sso?${q}`;
|
|
277
|
+
};
|
|
271
278
|
const passkeyUrl = (o = {}) => {
|
|
272
279
|
const q = new URLSearchParams({ method: "passkey" });
|
|
273
280
|
if (o.returnTo) q.set("return_to", o.returnTo);
|
|
@@ -279,11 +286,11 @@ function createAuthClient(options = {}) {
|
|
|
279
286
|
const res = await doFetch(`${base}/methods`, { credentials: "same-origin", headers: { accept: "application/json" } });
|
|
280
287
|
if (res.ok) {
|
|
281
288
|
const m = await res.json();
|
|
282
|
-
return { providers: [], signUp: true, magicLink: false, passkey: false, ...m, passkeyHere: m.passkeyHere === true, passkeyOnCauthy: m.passkeyOnCauthy ?? m.passkey === true };
|
|
289
|
+
return { providers: [], signUp: true, magicLink: false, passkey: false, ...m, passkeyHere: m.passkeyHere === true, passkeyOnCauthy: m.passkeyOnCauthy ?? m.passkey === true, sso: m.sso === true };
|
|
283
290
|
}
|
|
284
291
|
} catch {
|
|
285
292
|
}
|
|
286
|
-
return { providers: [], signUp: true, magicLink: false, passkey: false, passkeyHere: false, passkeyOnCauthy: false };
|
|
293
|
+
return { providers: [], signUp: true, magicLink: false, passkey: false, passkeyHere: false, passkeyOnCauthy: false, sso: false };
|
|
287
294
|
}
|
|
288
295
|
async function ceremony(begin, finish, form, run, more = {}) {
|
|
289
296
|
const begun = await post(begin, form, null);
|
|
@@ -298,6 +305,7 @@ function createAuthClient(options = {}) {
|
|
|
298
305
|
}
|
|
299
306
|
return {
|
|
300
307
|
signIn: {
|
|
308
|
+
anonymously: (f = {}) => post("/sign-in/anonymous", {}, null, f.captchaToken),
|
|
301
309
|
email: (f) => post("/sign-in/email", { email: f.email, password: f.password }, firstProblem(checkEmail(f.email), checkPassword(f.password)), f.captchaToken),
|
|
302
310
|
mfa: (f) => post("/sign-in/mfa", { code: f.code }, checkCode(f.code)),
|
|
303
311
|
mfaMethods: () => post("/sign-in/mfa/methods", {}, null),
|
|
@@ -381,6 +389,11 @@ function createAuthClient(options = {}) {
|
|
|
381
389
|
socialUrl,
|
|
382
390
|
social(provider, o) {
|
|
383
391
|
window.location.assign(socialUrl(provider, o));
|
|
392
|
+
},
|
|
393
|
+
ssoDiscover: (f) => post("/sign-in/sso/discover", { email: f.email.trim() }, checkEmail(f.email)),
|
|
394
|
+
ssoUrl,
|
|
395
|
+
sso(target, o) {
|
|
396
|
+
window.location.assign(ssoUrl(target, o));
|
|
384
397
|
}
|
|
385
398
|
},
|
|
386
399
|
signUp: {
|
|
@@ -390,6 +403,24 @@ function createAuthClient(options = {}) {
|
|
|
390
403
|
resetPassword: (f) => post("/reset-password", { token: f.token, password: f.password }, checkNewPassword(f.password)),
|
|
391
404
|
verifyEmail: (f) => post("/verify-email", { token: f.token }, null),
|
|
392
405
|
signOut: () => post("/sign-out", {}, null),
|
|
406
|
+
organizations: {
|
|
407
|
+
async list(system) {
|
|
408
|
+
const body = await read(`/me/organizations${system ? `?system=${encodeURIComponent(system)}` : ""}`);
|
|
409
|
+
return body && Array.isArray(body.organizations) ? body.organizations : [];
|
|
410
|
+
},
|
|
411
|
+
async members(id) {
|
|
412
|
+
const body = await read(`/me/organizations/members?id=${encodeURIComponent(id)}`);
|
|
413
|
+
return body && Array.isArray(body.members) ? body.members : null;
|
|
414
|
+
},
|
|
415
|
+
async roles(id) {
|
|
416
|
+
const body = await read(`/me/organizations/roles?id=${encodeURIComponent(id)}`);
|
|
417
|
+
return body && Array.isArray(body.roles) ? body.roles : null;
|
|
418
|
+
},
|
|
419
|
+
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)),
|
|
420
|
+
setRole: (id, userId, role) => post("/me/organizations/members/role", { organizationId: id, userId, role }, null),
|
|
421
|
+
remove: (id, userId) => post("/me/organizations/members/remove", { organizationId: id, userId }, null),
|
|
422
|
+
inviteAgain: (id, userId, f = {}) => post("/me/organizations/members/invite", { organizationId: id, userId, locale: f.locale ?? "" }, null)
|
|
423
|
+
},
|
|
393
424
|
account: {
|
|
394
425
|
async get() {
|
|
395
426
|
const body = await read("/me");
|
|
@@ -428,6 +459,11 @@ function createAuthClient(options = {}) {
|
|
|
428
459
|
return body && Array.isArray(body.sessions) ? body.sessions : [];
|
|
429
460
|
},
|
|
430
461
|
signOutEverywhere: () => post("/me/sessions/end", {}, null),
|
|
462
|
+
upgrade: (f) => post("/me/upgrade", { email: f.email, password: f.password, name: f.name ?? "" }, firstProblem(checkName(f.name), checkEmail(f.email), checkNewPassword(f.password))),
|
|
463
|
+
upgradeUrl,
|
|
464
|
+
upgradeWith(provider, o) {
|
|
465
|
+
window.location.assign(upgradeUrl(provider, o));
|
|
466
|
+
},
|
|
431
467
|
async agents() {
|
|
432
468
|
const body = await read("/me/agents");
|
|
433
469
|
return body && Array.isArray(body.agents) ? body.agents : [];
|
|
@@ -601,7 +637,30 @@ var TEXTS = {
|
|
|
601
637
|
linkWith: "Link",
|
|
602
638
|
unlink: "Unlink",
|
|
603
639
|
linked: "The account was linked.",
|
|
640
|
+
ssoOnly: "Your company signs you in to this account.",
|
|
641
|
+
members: "Members",
|
|
642
|
+
membersHidden: "Your role here does not let you see the members.",
|
|
643
|
+
organizationMissing: "You do not belong to this organization.",
|
|
644
|
+
memberYou: "you",
|
|
645
|
+
memberInvited: "invited",
|
|
646
|
+
memberManager: "manages members",
|
|
647
|
+
memberRole: "Role",
|
|
648
|
+
memberAdd: "Add member",
|
|
649
|
+
memberAdded: "{email} is a member now.",
|
|
650
|
+
memberRemove: "Remove",
|
|
651
|
+
memberRemoveConfirm: "Remove {who}?",
|
|
652
|
+
memberLeave: "Leave",
|
|
653
|
+
memberLeaveConfirm: "Leave {org}? You will need an invitation to come back.",
|
|
654
|
+
memberInviteAgain: "Send the invitation again",
|
|
655
|
+
memberInvitationSent: "The invitation is on its way.",
|
|
656
|
+
yes: "Yes",
|
|
657
|
+
cancel: "Cancel",
|
|
604
658
|
errors: {
|
|
659
|
+
not_allowed: "Your role in this organization does not allow that.",
|
|
660
|
+
last_manager: "Somebody else must manage the members first: give that role to another member.",
|
|
661
|
+
already_member: "That person already belongs to the organization. Change their role instead.",
|
|
662
|
+
unknown_role: "Choose one of the roles offered.",
|
|
663
|
+
user_not_active: "That account is disabled.",
|
|
605
664
|
required: "This is required.",
|
|
606
665
|
invalid_email: "That does not look like an email address.",
|
|
607
666
|
too_short: "Use at least 8 characters.",
|
|
@@ -629,7 +688,15 @@ var TEXTS = {
|
|
|
629
688
|
captcha_failed: "The check that you are not a bot did not pass. Try it again.",
|
|
630
689
|
passkey_failed: "The passkey could not be used. Try again, or sign in another way.",
|
|
631
690
|
passkey_exists: "This device already has a passkey for your account.",
|
|
632
|
-
passkey_unavailable: "Passkeys cannot be used here."
|
|
691
|
+
passkey_unavailable: "Passkeys cannot be used here.",
|
|
692
|
+
sso_required: "This address signs in through its company.",
|
|
693
|
+
sso_not_found: "No company sign-in answers for this address.",
|
|
694
|
+
sso_failed: "The sign-in with your company could not be completed. Try again.",
|
|
695
|
+
sso_unavailable: "Your company's sign-in cannot be reached right now. Try again in a moment.",
|
|
696
|
+
invalid_assertion: "Your company's answer could not be checked. Try again.",
|
|
697
|
+
provisioning_disabled: "Your company's sign-in worked, but this workspace has no account for you. Ask its admin to add you.",
|
|
698
|
+
connection_inactive: "Your company's sign-in is turned off for this workspace.",
|
|
699
|
+
invalid_grant: "That sign-in expired. Try again."
|
|
633
700
|
}
|
|
634
701
|
},
|
|
635
702
|
es: {
|
|
@@ -716,7 +783,30 @@ var TEXTS = {
|
|
|
716
783
|
linkWith: "Vincular",
|
|
717
784
|
unlink: "Desvincular",
|
|
718
785
|
linked: "La cuenta qued\xF3 vinculada.",
|
|
786
|
+
ssoOnly: "A esta cuenta entras con el inicio de sesi\xF3n de tu empresa.",
|
|
787
|
+
members: "Miembros",
|
|
788
|
+
membersHidden: "Tu rol aqu\xED no te deja ver los miembros.",
|
|
789
|
+
organizationMissing: "No perteneces a esta organizaci\xF3n.",
|
|
790
|
+
memberYou: "t\xFA",
|
|
791
|
+
memberInvited: "invitado",
|
|
792
|
+
memberManager: "administra los miembros",
|
|
793
|
+
memberRole: "Rol",
|
|
794
|
+
memberAdd: "Agregar miembro",
|
|
795
|
+
memberAdded: "{email} ya es miembro.",
|
|
796
|
+
memberRemove: "Quitar",
|
|
797
|
+
memberRemoveConfirm: "\xBFQuitar a {who}?",
|
|
798
|
+
memberLeave: "Salir",
|
|
799
|
+
memberLeaveConfirm: "\xBFSalir de {org}? Necesitar\xE1s una invitaci\xF3n para volver.",
|
|
800
|
+
memberInviteAgain: "Enviar la invitaci\xF3n de nuevo",
|
|
801
|
+
memberInvitationSent: "La invitaci\xF3n va en camino.",
|
|
802
|
+
yes: "S\xED",
|
|
803
|
+
cancel: "Cancelar",
|
|
719
804
|
errors: {
|
|
805
|
+
not_allowed: "Tu rol en esta organizaci\xF3n no permite eso.",
|
|
806
|
+
last_manager: "Primero alguien m\xE1s debe administrar los miembros: dale ese rol a otro miembro.",
|
|
807
|
+
already_member: "Esa persona ya pertenece a la organizaci\xF3n. Cambia su rol.",
|
|
808
|
+
unknown_role: "Escoge uno de los roles ofrecidos.",
|
|
809
|
+
user_not_active: "Esa cuenta est\xE1 desactivada.",
|
|
720
810
|
required: "Este dato es obligatorio.",
|
|
721
811
|
invalid_email: "Eso no parece un correo.",
|
|
722
812
|
too_short: "Usa al menos 8 caracteres.",
|
|
@@ -744,7 +834,15 @@ var TEXTS = {
|
|
|
744
834
|
captcha_failed: "La verificaci\xF3n de que no eres un robot no pas\xF3. Int\xE9ntalo de nuevo.",
|
|
745
835
|
passkey_failed: "No se pudo usar la llave de acceso. Intenta de nuevo o entra de otra forma.",
|
|
746
836
|
passkey_exists: "Este dispositivo ya tiene una llave de acceso de tu cuenta.",
|
|
747
|
-
passkey_unavailable: "Aqu\xED no se pueden usar llaves de acceso."
|
|
837
|
+
passkey_unavailable: "Aqu\xED no se pueden usar llaves de acceso.",
|
|
838
|
+
sso_required: "Este correo entra con el inicio de sesi\xF3n de su empresa.",
|
|
839
|
+
sso_not_found: "Ninguna empresa usa inicio de sesi\xF3n propio con este correo.",
|
|
840
|
+
sso_failed: "No se pudo completar el ingreso con tu empresa. Intenta de nuevo.",
|
|
841
|
+
sso_unavailable: "Ahora no se puede llegar al inicio de sesi\xF3n de tu empresa. Intenta en un momento.",
|
|
842
|
+
invalid_assertion: "No se pudo verificar la respuesta de tu empresa. Intenta de nuevo.",
|
|
843
|
+
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.",
|
|
844
|
+
connection_inactive: "El inicio de sesi\xF3n de tu empresa est\xE1 apagado en este workspace.",
|
|
845
|
+
invalid_grant: "Ese ingreso venci\xF3. Intenta de nuevo."
|
|
748
846
|
}
|
|
749
847
|
}
|
|
750
848
|
};
|
|
@@ -937,6 +1035,25 @@ function SignIn(props) {
|
|
|
937
1035
|
};
|
|
938
1036
|
const autofill = (0, import_react.useRef)(null);
|
|
939
1037
|
const [offer, setOffer] = (0, import_react.useState)(0);
|
|
1038
|
+
const [company, setCompany] = (0, import_react.useState)(null);
|
|
1039
|
+
(0, import_react.useEffect)(() => {
|
|
1040
|
+
if (!methods?.sso || checkEmail(email) !== null) return setCompany(null);
|
|
1041
|
+
let current = true;
|
|
1042
|
+
const t = setTimeout(() => {
|
|
1043
|
+
void auth.signIn.ssoDiscover({ email }).then((r) => {
|
|
1044
|
+
if (current) setCompany(r.ok && r.status === "found" ? r.connection : null);
|
|
1045
|
+
});
|
|
1046
|
+
}, 350);
|
|
1047
|
+
return () => {
|
|
1048
|
+
current = false;
|
|
1049
|
+
clearTimeout(t);
|
|
1050
|
+
};
|
|
1051
|
+
}, [email, methods]);
|
|
1052
|
+
const toCompany = () => {
|
|
1053
|
+
autofill.current?.abort();
|
|
1054
|
+
f.setBusy(true);
|
|
1055
|
+
auth.signIn.sso({ email }, { returnTo: props.returnTo });
|
|
1056
|
+
};
|
|
940
1057
|
(0, import_react.useEffect)(() => {
|
|
941
1058
|
void auth.methods().then(setMethods);
|
|
942
1059
|
const back = returnedError();
|
|
@@ -969,9 +1086,11 @@ function SignIn(props) {
|
|
|
969
1086
|
autofill.current?.abort();
|
|
970
1087
|
f.setBusy(true);
|
|
971
1088
|
f.setError(null);
|
|
1089
|
+
if (step === "password" && company?.enforced) return toCompany();
|
|
972
1090
|
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 });
|
|
973
1091
|
f.setBusy(false);
|
|
974
1092
|
if (step === "password") challenge.renew();
|
|
1093
|
+
if (!r.ok && r.error.code === "sso_required") return toCompany();
|
|
975
1094
|
if (!r.ok) {
|
|
976
1095
|
setOffer((n) => n + 1);
|
|
977
1096
|
return f.setError(r.error);
|
|
@@ -997,6 +1116,7 @@ function SignIn(props) {
|
|
|
997
1116
|
const r = await auth.signIn.magicLink({ email, captchaToken: challenge.token, create: props.createAccounts, returnTo: props.returnTo });
|
|
998
1117
|
f.setBusy(false);
|
|
999
1118
|
challenge.renew();
|
|
1119
|
+
if (!r.ok && r.error.code === "sso_required") return toCompany();
|
|
1000
1120
|
if (!r.ok) return f.setError(r.error);
|
|
1001
1121
|
setStep("sent");
|
|
1002
1122
|
};
|
|
@@ -1031,23 +1151,31 @@ function SignIn(props) {
|
|
|
1031
1151
|
methods?.passkey && /* @__PURE__ */ (0, import_jsx_runtime.jsx)(f.Button, { type: "button", disabled: f.busy, className: f.cx("providerButton"), onClick: () => void usePasskey(), children: f.t.usePasskey }),
|
|
1032
1152
|
((methods?.providers.length ?? 0) > 0 || methods?.passkey) && /* @__PURE__ */ (0, import_jsx_runtime.jsx)("p", { className: f.cx("separator"), children: f.t.orWithEmail }),
|
|
1033
1153
|
/* @__PURE__ */ (0, import_jsx_runtime.jsx)(Field, { f, name: "email", type: "email", label: f.t.email, value: email, autoComplete: methods?.passkeyHere ? "username webauthn" : "username", required: true, onChange: setEmail }),
|
|
1034
|
-
/* @__PURE__ */ (0, import_jsx_runtime.
|
|
1035
|
-
|
|
1036
|
-
|
|
1037
|
-
|
|
1038
|
-
|
|
1039
|
-
|
|
1040
|
-
|
|
1041
|
-
|
|
1042
|
-
|
|
1043
|
-
|
|
1044
|
-
|
|
1045
|
-
|
|
1046
|
-
|
|
1047
|
-
|
|
1048
|
-
|
|
1049
|
-
|
|
1050
|
-
|
|
1154
|
+
company && /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(f.Button, { type: "button", disabled: f.busy, className: f.cx(company.enforced ? "button" : "providerButton"), onClick: toCompany, children: [
|
|
1155
|
+
f.t.continueWith,
|
|
1156
|
+
" ",
|
|
1157
|
+
company.name
|
|
1158
|
+
] }),
|
|
1159
|
+
company?.enforced && /* @__PURE__ */ (0, import_jsx_runtime.jsx)("p", { className: f.cx("notice"), children: f.t.ssoOnly }),
|
|
1160
|
+
!company?.enforced && /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(import_jsx_runtime.Fragment, { children: [
|
|
1161
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsx)(
|
|
1162
|
+
Field,
|
|
1163
|
+
{
|
|
1164
|
+
f,
|
|
1165
|
+
name: "password",
|
|
1166
|
+
type: "password",
|
|
1167
|
+
label: f.t.password,
|
|
1168
|
+
value: password,
|
|
1169
|
+
autoComplete: "current-password",
|
|
1170
|
+
required: true,
|
|
1171
|
+
onChange: setPassword,
|
|
1172
|
+
aside: props.links?.forgotPassword ? /* @__PURE__ */ (0, import_jsx_runtime.jsx)("a", { className: f.cx("link"), href: props.links.forgotPassword, children: f.t.forgotPassword }) : void 0
|
|
1173
|
+
}
|
|
1174
|
+
),
|
|
1175
|
+
challenge.node,
|
|
1176
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsx)(f.Button, { type: "submit", disabled: f.busy, className: f.cx("button"), children: f.t.signIn })
|
|
1177
|
+
] }),
|
|
1178
|
+
methods?.magicLink && !company?.enforced && /* @__PURE__ */ (0, import_jsx_runtime.jsx)(f.Button, { type: "button", disabled: f.busy, className: f.cx("providerButton"), onClick: () => void sendLink(), children: f.t.emailMeALink }),
|
|
1051
1179
|
methods?.signUp !== false && props.links?.signUp && /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("p", { className: f.cx("footer"), children: [
|
|
1052
1180
|
f.t.noAccount,
|
|
1053
1181
|
" ",
|
|
@@ -1082,7 +1210,7 @@ function SignUp(props) {
|
|
|
1082
1210
|
e.preventDefault();
|
|
1083
1211
|
f.setBusy(true);
|
|
1084
1212
|
f.setError(null);
|
|
1085
|
-
const r = await auth.signUp.email({ name, email, password, captchaToken: challenge.token });
|
|
1213
|
+
const r = auth.session?.user.isAnonymous === true ? await auth.account.upgrade({ name, email, password }) : await auth.signUp.email({ name, email, password, captchaToken: challenge.token });
|
|
1086
1214
|
f.setBusy(false);
|
|
1087
1215
|
challenge.renew();
|
|
1088
1216
|
if (!r.ok) return f.setError(r.error);
|
|
@@ -1252,6 +1380,130 @@ function Account(props) {
|
|
|
1252
1380
|
] })
|
|
1253
1381
|
] });
|
|
1254
1382
|
}
|
|
1383
|
+
function OrganizationMembers(props) {
|
|
1384
|
+
const auth = useAuth();
|
|
1385
|
+
const { root } = useForm(props);
|
|
1386
|
+
const { f, done, setDone, run } = useSection(props);
|
|
1387
|
+
const problem = f.error && f.error.field !== "email" ? f.error : null;
|
|
1388
|
+
const [seat, setSeat] = (0, import_react.useState)(void 0);
|
|
1389
|
+
const [members, setMembers] = (0, import_react.useState)(null);
|
|
1390
|
+
const [roles, setRoles] = (0, import_react.useState)([]);
|
|
1391
|
+
const [email, setEmail] = (0, import_react.useState)("");
|
|
1392
|
+
const [role, setRole] = (0, import_react.useState)("");
|
|
1393
|
+
const [asking, setAsking] = (0, import_react.useState)(null);
|
|
1394
|
+
const id = props.organizationId;
|
|
1395
|
+
const when = props.formatDate ?? ((iso) => new Date(iso).toLocaleDateString());
|
|
1396
|
+
const load = async () => {
|
|
1397
|
+
const [list, people, choices] = await Promise.all([auth.organizations.list(), auth.organizations.members(id), auth.organizations.roles(id)]);
|
|
1398
|
+
setSeat(list.find((o) => o.id === id) ?? null);
|
|
1399
|
+
setMembers(people);
|
|
1400
|
+
setRoles(choices ?? []);
|
|
1401
|
+
if (choices && choices.length > 0 && !choices.some((c) => c.role === role)) setRole(choices[0].role);
|
|
1402
|
+
};
|
|
1403
|
+
(0, import_react.useEffect)(() => {
|
|
1404
|
+
void load();
|
|
1405
|
+
}, [id]);
|
|
1406
|
+
if (seat === void 0) return /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", { className: f.cx("account"), ...root, "aria-busy": "true" });
|
|
1407
|
+
if (seat === null) return /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", { className: f.cx("account"), ...root, children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)("p", { className: f.cx("notice"), children: f.t.organizationMissing }) });
|
|
1408
|
+
const manage = seat.can.manageMembers;
|
|
1409
|
+
const label = (r) => roles.find((c) => c.role === r)?.name || r;
|
|
1410
|
+
const add = async (e) => {
|
|
1411
|
+
e.preventDefault();
|
|
1412
|
+
const r = await run(() => auth.organizations.add(id, { email, role, locale: props.locale }));
|
|
1413
|
+
if (!r.ok) return;
|
|
1414
|
+
setEmail("");
|
|
1415
|
+
setDone(f.t.memberAdded.replace("{email}", r.member.email));
|
|
1416
|
+
await load();
|
|
1417
|
+
};
|
|
1418
|
+
const change = async (m, next) => {
|
|
1419
|
+
const r = await run(() => auth.organizations.setRole(id, m.userId, next));
|
|
1420
|
+
if (r.ok) await load();
|
|
1421
|
+
};
|
|
1422
|
+
const remove = async (m) => {
|
|
1423
|
+
setAsking(null);
|
|
1424
|
+
const r = await run(() => auth.organizations.remove(id, m.userId));
|
|
1425
|
+
if (!r.ok) return;
|
|
1426
|
+
if (m.you) setSeat(null);
|
|
1427
|
+
else await load();
|
|
1428
|
+
};
|
|
1429
|
+
const inviteAgain = async (m) => {
|
|
1430
|
+
const r = await run(() => auth.organizations.inviteAgain(id, m.userId, { locale: props.locale }));
|
|
1431
|
+
if (r.ok) setDone(f.t.memberInvitationSent);
|
|
1432
|
+
};
|
|
1433
|
+
return /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { className: f.cx("account"), ...root, children: [
|
|
1434
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsxs)("section", { className: f.cx("section"), children: [
|
|
1435
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsxs)("h2", { className: f.cx("heading"), children: [
|
|
1436
|
+
f.t.members,
|
|
1437
|
+
" \xB7 ",
|
|
1438
|
+
seat.name
|
|
1439
|
+
] }),
|
|
1440
|
+
problem && /* @__PURE__ */ (0, import_jsx_runtime.jsx)("p", { role: "alert", className: f.cx("error"), children: f.say(problem) }),
|
|
1441
|
+
members === null ? /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(import_jsx_runtime.Fragment, { children: [
|
|
1442
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("p", { className: f.cx("notice"), children: f.t.membersHidden }),
|
|
1443
|
+
auth.session && (asking === auth.session.user.id ? /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("span", { role: "group", "aria-label": f.t.memberLeave, children: [
|
|
1444
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("span", { children: f.t.memberLeaveConfirm.replace("{org}", seat.name) }),
|
|
1445
|
+
" ",
|
|
1446
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsx)(
|
|
1447
|
+
f.Button,
|
|
1448
|
+
{
|
|
1449
|
+
type: "button",
|
|
1450
|
+
disabled: f.busy,
|
|
1451
|
+
className: f.cx("providerButton"),
|
|
1452
|
+
onClick: () => void remove({ userId: auth.session.user.id, you: true }),
|
|
1453
|
+
children: f.t.yes
|
|
1454
|
+
}
|
|
1455
|
+
),
|
|
1456
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsx)(f.Button, { type: "button", disabled: f.busy, className: f.cx("providerButton"), onClick: () => setAsking(null), children: f.t.cancel })
|
|
1457
|
+
] }) : /* @__PURE__ */ (0, import_jsx_runtime.jsx)(f.Button, { type: "button", disabled: f.busy, className: f.cx("providerButton"), onClick: () => setAsking(auth.session.user.id), children: f.t.memberLeave }))
|
|
1458
|
+
] }) : /* @__PURE__ */ (0, import_jsx_runtime.jsx)("ul", { className: f.cx("sessions"), children: members.map((m) => {
|
|
1459
|
+
const who = m.name || m.email;
|
|
1460
|
+
return /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("li", { className: f.cx("session"), children: [
|
|
1461
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsxs)("span", { children: [
|
|
1462
|
+
who,
|
|
1463
|
+
m.name ? ` \xB7 ${m.email}` : "",
|
|
1464
|
+
m.you ? ` (${f.t.memberYou})` : "",
|
|
1465
|
+
m.invited ? ` \xB7 ${f.t.memberInvited}` : "",
|
|
1466
|
+
m.manager ? ` \xB7 ${f.t.memberManager}` : "",
|
|
1467
|
+
" \xB7 ",
|
|
1468
|
+
when(m.since)
|
|
1469
|
+
] }),
|
|
1470
|
+
" ",
|
|
1471
|
+
manage && roles.length > 0 ? /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
|
|
1472
|
+
"select",
|
|
1473
|
+
{
|
|
1474
|
+
"aria-label": `${f.t.memberRole}: ${who}`,
|
|
1475
|
+
className: f.cx("input"),
|
|
1476
|
+
value: m.role,
|
|
1477
|
+
disabled: f.busy,
|
|
1478
|
+
onChange: (e) => void change(m, e.target.value),
|
|
1479
|
+
children: roles.map((c) => /* @__PURE__ */ (0, import_jsx_runtime.jsx)("option", { value: c.role, children: c.name || c.role }, c.role))
|
|
1480
|
+
}
|
|
1481
|
+
) : /* @__PURE__ */ (0, import_jsx_runtime.jsx)("span", { children: label(m.role) }),
|
|
1482
|
+
" ",
|
|
1483
|
+
asking === m.userId ? /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("span", { role: "group", "aria-label": m.you ? f.t.memberLeave : f.t.memberRemove, children: [
|
|
1484
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("span", { children: m.you ? f.t.memberLeaveConfirm.replace("{org}", seat.name) : f.t.memberRemoveConfirm.replace("{who}", who) }),
|
|
1485
|
+
" ",
|
|
1486
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsx)(f.Button, { type: "button", disabled: f.busy, className: f.cx("providerButton"), onClick: () => void remove(m), children: f.t.yes }),
|
|
1487
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsx)(f.Button, { type: "button", disabled: f.busy, className: f.cx("providerButton"), onClick: () => setAsking(null), children: f.t.cancel })
|
|
1488
|
+
] }) : /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(import_jsx_runtime.Fragment, { children: [
|
|
1489
|
+
manage && m.invited && /* @__PURE__ */ (0, import_jsx_runtime.jsx)(f.Button, { type: "button", disabled: f.busy, className: f.cx("providerButton"), onClick: () => void inviteAgain(m), children: f.t.memberInviteAgain }),
|
|
1490
|
+
(manage || m.you) && /* @__PURE__ */ (0, import_jsx_runtime.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 })
|
|
1491
|
+
] })
|
|
1492
|
+
] }, m.userId);
|
|
1493
|
+
}) }),
|
|
1494
|
+
done && /* @__PURE__ */ (0, import_jsx_runtime.jsx)("p", { role: "status", className: f.cx("notice"), children: done })
|
|
1495
|
+
] }),
|
|
1496
|
+
manage && roles.length > 0 && /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("form", { className: f.cx("section"), onSubmit: add, noValidate: true, children: [
|
|
1497
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("h2", { className: f.cx("heading"), children: f.t.memberAdd }),
|
|
1498
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsx)(Field, { f, name: "email", type: "email", label: f.t.email, value: email, autoComplete: "off", required: true, onChange: setEmail }),
|
|
1499
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsxs)("label", { className: f.cx("field"), children: [
|
|
1500
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("span", { className: f.cx("label"), children: f.t.memberRole }),
|
|
1501
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("select", { name: "role", className: f.cx("input"), value: role, onChange: (e) => setRole(e.target.value), children: roles.map((c) => /* @__PURE__ */ (0, import_jsx_runtime.jsx)("option", { value: c.role, children: c.name || c.role }, c.role)) })
|
|
1502
|
+
] }),
|
|
1503
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsx)(f.Button, { type: "submit", disabled: f.busy, className: f.cx("button"), children: f.t.memberAdd })
|
|
1504
|
+
] })
|
|
1505
|
+
] });
|
|
1506
|
+
}
|
|
1255
1507
|
function PasskeysPart({ props, account, accountUrl, when }) {
|
|
1256
1508
|
const auth = useAuth();
|
|
1257
1509
|
const { f, done, setDone, run, general } = useSection(props);
|
|
@@ -1673,6 +1925,7 @@ function useAuth() {
|
|
|
1673
1925
|
...client,
|
|
1674
1926
|
signIn: {
|
|
1675
1927
|
...client.signIn,
|
|
1928
|
+
anonymously: (f) => then(client.signIn.anonymously(f)),
|
|
1676
1929
|
email: (f) => then(client.signIn.email(f)),
|
|
1677
1930
|
mfa: (f) => then(client.signIn.mfa(f)),
|
|
1678
1931
|
magicLinkVerify: (f) => then(client.signIn.magicLinkVerify(f)),
|
|
@@ -1688,7 +1941,9 @@ function useAuth() {
|
|
|
1688
1941
|
// What is on screen says the new name, and knows when the session ended.
|
|
1689
1942
|
update: (f) => then(client.account.update(f)),
|
|
1690
1943
|
changePassword: (f) => then(client.account.changePassword(f)),
|
|
1691
|
-
signOutEverywhere: () => then(client.account.signOutEverywhere())
|
|
1944
|
+
signOutEverywhere: () => then(client.account.signOutEverywhere()),
|
|
1945
|
+
// The guest is now the account: what is on screen says so.
|
|
1946
|
+
upgrade: (f) => then(client.account.upgrade(f))
|
|
1692
1947
|
},
|
|
1693
1948
|
session,
|
|
1694
1949
|
status,
|
|
@@ -1702,6 +1957,7 @@ function useAuth() {
|
|
|
1702
1957
|
CauthyProvider,
|
|
1703
1958
|
ForgotPassword,
|
|
1704
1959
|
GoogleOneTap,
|
|
1960
|
+
OrganizationMembers,
|
|
1705
1961
|
ResetPassword,
|
|
1706
1962
|
SignIn,
|
|
1707
1963
|
SignUp,
|