cauthy-auth 0.30.0 → 0.31.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +10 -3
- package/dist/{cauthy-BXgsZ-Um.d.mts → cauthy-2jtP2LVQ.d.mts} +1 -1
- package/dist/{cauthy-CHENs452.d.ts → cauthy-CKfvvv_i.d.ts} +1 -1
- package/dist/cli.js +8 -5
- package/dist/client.d.mts +47 -6
- package/dist/client.d.ts +47 -6
- package/dist/client.js +16 -2
- package/dist/client.js.map +1 -1
- package/dist/client.mjs +16 -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 +64 -21
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +64 -21
- 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 +61 -5
- package/dist/react.d.ts +61 -5
- package/dist/react.js +183 -46
- package/dist/react.js.map +1 -1
- package/dist/react.mjs +182 -46
- package/dist/react.mjs.map +1 -1
- package/dist/styles.css +8 -0
- package/dist/svelte.d.mts +2 -2
- package/dist/svelte.d.ts +2 -2
- package/dist/svelte.js +16 -2
- package/dist/svelte.js.map +1 -1
- package/dist/svelte.mjs +16 -2
- package/dist/svelte.mjs.map +1 -1
- package/dist/{system-0mHrdAgO.d.mts → system-BrrJsrFW.d.mts} +14 -0
- package/dist/{system-BIYbS7h2.d.ts → system-BvvoNs2y.d.ts} +14 -0
- package/dist/vue.d.mts +2 -2
- package/dist/vue.d.ts +2 -2
- package/dist/vue.js +16 -2
- package/dist/vue.js.map +1 -1
- package/dist/vue.mjs +16 -2
- package/dist/vue.mjs.map +1 -1
- package/package.json +1 -1
package/dist/react.mjs
CHANGED
|
@@ -373,11 +373,11 @@ function createAuthClient(options = {}) {
|
|
|
373
373
|
if (res.ok) {
|
|
374
374
|
const m = await res.json();
|
|
375
375
|
if (m.password) policy = passwordPolicyOf(m.password);
|
|
376
|
-
return { providers: [], signUp: true, magicLink: false, passkey: false, ...m, ...policy ? { password: policy } : {}, passkeyHere: m.passkeyHere === true, passkeyOnCauthy: m.passkeyOnCauthy ?? m.passkey === true, sso: m.sso === true };
|
|
376
|
+
return { providers: [], signUp: true, magicLink: false, passkey: false, ...m, ...policy ? { password: policy } : {}, passwordSignIn: m.passwordSignIn !== false, passkeyHere: m.passkeyHere === true, passkeyOnCauthy: m.passkeyOnCauthy ?? m.passkey === true, sso: m.sso === true };
|
|
377
377
|
}
|
|
378
378
|
} catch {
|
|
379
379
|
}
|
|
380
|
-
return { providers: [], signUp: true, magicLink: false, passkey: false, passkeyHere: false, passkeyOnCauthy: false, sso: false };
|
|
380
|
+
return { providers: [], signUp: true, passwordSignIn: true, magicLink: false, passkey: false, passkeyHere: false, passkeyOnCauthy: false, sso: false };
|
|
381
381
|
}
|
|
382
382
|
async function ceremony(begin, finish, form, run, more = {}) {
|
|
383
383
|
const begun = await post(begin, form, null);
|
|
@@ -524,6 +524,20 @@ function createAuthClient(options = {}) {
|
|
|
524
524
|
forgotPassword: (f) => post("/forgot-password", { email: f.email }, checkEmail(f.email), f.captchaToken),
|
|
525
525
|
resetPassword: (f) => post("/reset-password", { token: f.token, password: f.password }, checkNewPassword(f.password, policy)),
|
|
526
526
|
verifyEmail: (f) => post("/verify-email", { token: f.token }, null),
|
|
527
|
+
async invitation(token) {
|
|
528
|
+
const bad = { ok: false, error: { code: "invalid_token", message: "This invitation is not valid, or it has expired." } };
|
|
529
|
+
if (typeof token !== "string" || token.trim() === "") return bad;
|
|
530
|
+
try {
|
|
531
|
+
const res = await doFetch(`${base}/invitation?token=${encodeURIComponent(token.trim())}`, { credentials: "same-origin", headers: { accept: "application/json" } });
|
|
532
|
+
const body = await res.json().catch(() => null);
|
|
533
|
+
if (res.ok && body?.invitation) return { ok: true, status: "ok", invitation: body.invitation };
|
|
534
|
+
const e = body?.error;
|
|
535
|
+
return { ok: false, error: e && typeof e.code === "string" ? { code: e.code, message: String(e.message ?? "") } : UNAVAILABLE };
|
|
536
|
+
} catch {
|
|
537
|
+
return { ok: false, error: UNAVAILABLE };
|
|
538
|
+
}
|
|
539
|
+
},
|
|
540
|
+
acceptInvitation: (token, password) => post("/invitation/accept", { token, password }, checkNewPassword(password, policy)),
|
|
527
541
|
signOut: () => post("/sign-out", {}, null),
|
|
528
542
|
organizations: {
|
|
529
543
|
async list(system) {
|
|
@@ -760,6 +774,13 @@ var TEXTS = {
|
|
|
760
774
|
passwordChanged: "Your password was changed. You can sign in with it now.",
|
|
761
775
|
confirming: "Confirming your address\u2026",
|
|
762
776
|
emailConfirmed: "Your address is confirmed. You can sign in now.",
|
|
777
|
+
invitedTo: "You've been invited to {workspace}",
|
|
778
|
+
invitedToOrganization: "You've been invited to {organization} on {workspace}",
|
|
779
|
+
invitedAs: "You will sign in as {email}.",
|
|
780
|
+
choosePassword: "Choose a password",
|
|
781
|
+
acceptInvite: "Accept and sign in",
|
|
782
|
+
openingInvitation: "Opening your invitation\u2026",
|
|
783
|
+
invitationInvalid: "This invitation is not valid: it was already used, or it has expired. Ask whoever invited you to send it again.",
|
|
763
784
|
profile: "Profile",
|
|
764
785
|
save: "Save",
|
|
765
786
|
saved: "Saved.",
|
|
@@ -874,7 +895,9 @@ var TEXTS = {
|
|
|
874
895
|
invalid_assertion: "Your company's answer could not be checked. Try again.",
|
|
875
896
|
provisioning_disabled: "Your company's sign-in worked, but this workspace has no account for you. Ask its admin to add you.",
|
|
876
897
|
connection_inactive: "Your company's sign-in is turned off for this workspace.",
|
|
877
|
-
invalid_grant: "That sign-in expired. Try again."
|
|
898
|
+
invalid_grant: "That sign-in expired. Try again.",
|
|
899
|
+
password_disabled: "This workspace does not sign in with a password. Use one of the other ways.",
|
|
900
|
+
passkeys_disabled: "Passkeys are turned off for this workspace."
|
|
878
901
|
}
|
|
879
902
|
},
|
|
880
903
|
es: {
|
|
@@ -927,6 +950,13 @@ var TEXTS = {
|
|
|
927
950
|
passwordChanged: "Tu contrase\xF1a se cambi\xF3. Ya puedes entrar con ella.",
|
|
928
951
|
confirming: "Confirmando tu correo\u2026",
|
|
929
952
|
emailConfirmed: "Tu correo qued\xF3 confirmado. Ya puedes entrar.",
|
|
953
|
+
invitedTo: "Te invitaron a {workspace}",
|
|
954
|
+
invitedToOrganization: "Te invitaron a {organization} en {workspace}",
|
|
955
|
+
invitedAs: "Vas a entrar como {email}.",
|
|
956
|
+
choosePassword: "Elige una contrase\xF1a",
|
|
957
|
+
acceptInvite: "Aceptar y entrar",
|
|
958
|
+
openingInvitation: "Abriendo tu invitaci\xF3n\u2026",
|
|
959
|
+
invitationInvalid: "Esta invitaci\xF3n no es v\xE1lida: ya se us\xF3 o venci\xF3. P\xEDdele a quien te invit\xF3 que te la env\xEDe de nuevo.",
|
|
930
960
|
profile: "Perfil",
|
|
931
961
|
save: "Guardar",
|
|
932
962
|
saved: "Guardado.",
|
|
@@ -1041,7 +1071,9 @@ var TEXTS = {
|
|
|
1041
1071
|
invalid_assertion: "No se pudo verificar la respuesta de tu empresa. Intenta de nuevo.",
|
|
1042
1072
|
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.",
|
|
1043
1073
|
connection_inactive: "El inicio de sesi\xF3n de tu empresa est\xE1 apagado en este workspace.",
|
|
1044
|
-
invalid_grant: "Ese ingreso venci\xF3. Intenta de nuevo."
|
|
1074
|
+
invalid_grant: "Ese ingreso venci\xF3. Intenta de nuevo.",
|
|
1075
|
+
password_disabled: "En este workspace no se entra con contrase\xF1a. Usa una de las otras formas.",
|
|
1076
|
+
passkeys_disabled: "Las llaves de acceso est\xE1n desactivadas en este workspace."
|
|
1045
1077
|
}
|
|
1046
1078
|
}
|
|
1047
1079
|
};
|
|
@@ -1236,23 +1268,16 @@ function useMailedToken(name, open) {
|
|
|
1236
1268
|
open(takeToken(name));
|
|
1237
1269
|
}, []);
|
|
1238
1270
|
}
|
|
1239
|
-
function
|
|
1240
|
-
const auth =
|
|
1241
|
-
const f = useForm(props);
|
|
1242
|
-
const [methods, setMethods] = useState(null);
|
|
1243
|
-
const [email, setEmail] = useState("");
|
|
1244
|
-
const [password, setPassword] = useState("");
|
|
1271
|
+
function SecondStepForm(p) {
|
|
1272
|
+
const { f, auth } = p;
|
|
1245
1273
|
const [code, setCode] = useState("");
|
|
1246
|
-
const [step, setStep] = useState("password");
|
|
1247
|
-
const challenge = useChallenge(methods?.captchaSiteKey, props.locale);
|
|
1248
1274
|
const [phoneWay, setPhoneWay] = useState(null);
|
|
1249
1275
|
const [phoneSent, setPhoneSent] = useState("");
|
|
1250
1276
|
useEffect(() => {
|
|
1251
|
-
if (step !== "code") return;
|
|
1252
1277
|
void auth.signIn.mfaMethods().then((r) => {
|
|
1253
1278
|
if (r.ok) setPhoneWay({ totp: r.totp, phone: r.phone, push: r.push, email: r.email });
|
|
1254
1279
|
});
|
|
1255
|
-
}, [
|
|
1280
|
+
}, []);
|
|
1256
1281
|
const sendEmail = async () => {
|
|
1257
1282
|
f.setBusy(true);
|
|
1258
1283
|
f.setError(null);
|
|
@@ -1288,6 +1313,55 @@ function SignIn(props) {
|
|
|
1288
1313
|
if (!r.ok) return f.setError(r.error);
|
|
1289
1314
|
setPhoneSent(r.sentTo);
|
|
1290
1315
|
};
|
|
1316
|
+
const submit = async (e) => {
|
|
1317
|
+
e.preventDefault();
|
|
1318
|
+
f.setBusy(true);
|
|
1319
|
+
f.setError(null);
|
|
1320
|
+
const r = await auth.signIn.mfa({ code });
|
|
1321
|
+
f.setBusy(false);
|
|
1322
|
+
if (!r.ok) return f.setError(r.error);
|
|
1323
|
+
f.done();
|
|
1324
|
+
};
|
|
1325
|
+
const general = f.error && !f.error.field ? f.error : null;
|
|
1326
|
+
const to = phoneWay?.phone?.number ?? "";
|
|
1327
|
+
return /* @__PURE__ */ jsxs("form", { className: f.cx("form"), ...f.root, onSubmit: submit, noValidate: true, children: [
|
|
1328
|
+
/* @__PURE__ */ jsx("p", { className: f.cx("notice"), children: phoneSent ? f.t.codeSent.replace("{to}", phoneSent) : phoneWay?.email ? f.t.codeHelpEmail.replace("{to}", phoneWay.email.to) : phoneWay?.phone && !phoneWay.totp ? f.t.codeHelpPhone : f.t.codeHelp }),
|
|
1329
|
+
general && /* @__PURE__ */ jsx("p", { role: "alert", className: f.cx("error"), children: f.say(general) }),
|
|
1330
|
+
phoneWay?.email && /* @__PURE__ */ jsx(f.Button, { type: "button", disabled: f.busy, className: f.cx("providerButton"), onClick: () => void sendEmail(), children: f.t.sendEmailAgain }),
|
|
1331
|
+
pushNumber > 0 ? /* @__PURE__ */ jsxs("div", { className: f.cx("notice"), role: "status", "aria-live": "polite", children: [
|
|
1332
|
+
/* @__PURE__ */ jsx("p", { children: f.t.pushPick.replace("{n}", String(pushNumber)) }),
|
|
1333
|
+
/* @__PURE__ */ jsx("p", { style: { fontSize: 48, fontWeight: 700, margin: "4px 0", textAlign: "center" }, children: pushNumber }),
|
|
1334
|
+
/* @__PURE__ */ jsx("p", { children: f.t.pushWaiting })
|
|
1335
|
+
] }) : phoneWay?.push && /* @__PURE__ */ jsx(f.Button, { type: "button", disabled: f.busy, className: f.cx("button"), onClick: () => void sendPush(), children: f.t.pushSend }),
|
|
1336
|
+
phoneWay?.phone && /* @__PURE__ */ jsx(f.Button, { type: "button", disabled: f.busy, className: f.cx("providerButton"), onClick: () => void sendCode(), children: (phoneWay.phone.channel === "whatsapp" ? f.t.sendCodeWhatsapp : f.t.sendCodeSms).replace("{to}", to) }),
|
|
1337
|
+
/* @__PURE__ */ jsx(Field, { f, name: "code", type: "text", label: f.t.code, value: code, autoComplete: "one-time-code", required: true, onChange: setCode }),
|
|
1338
|
+
/* @__PURE__ */ jsx(f.Button, { type: "submit", disabled: f.busy, className: f.cx("button"), children: f.t.verify })
|
|
1339
|
+
] });
|
|
1340
|
+
}
|
|
1341
|
+
function ProviderButtons(p) {
|
|
1342
|
+
const { f } = p;
|
|
1343
|
+
return /* @__PURE__ */ jsx(Fragment, { children: p.providers.map((provider) => /* @__PURE__ */ jsxs(f.Button, { type: "button", className: f.cx("providerButton"), onClick: () => p.onPick(provider.id), children: [
|
|
1344
|
+
provider.iconUrl && /* @__PURE__ */ jsx("img", { src: provider.iconUrl, alt: "", width: 18, height: 18, className: f.cx("providerIcon") }),
|
|
1345
|
+
f.t.continueWith,
|
|
1346
|
+
" ",
|
|
1347
|
+
provider.name
|
|
1348
|
+
] }, provider.id)) });
|
|
1349
|
+
}
|
|
1350
|
+
function signInOffers(methods) {
|
|
1351
|
+
const password = methods?.passwordSignIn !== false;
|
|
1352
|
+
return { password, email: password || methods?.magicLink === true || methods?.sso === true, passkey: methods?.passkey === true };
|
|
1353
|
+
}
|
|
1354
|
+
function SignIn(props) {
|
|
1355
|
+
const auth = useAuth();
|
|
1356
|
+
const f = useForm(props);
|
|
1357
|
+
const [methods, setMethods] = useState(null);
|
|
1358
|
+
const [email, setEmail] = useState("");
|
|
1359
|
+
const [password, setPassword] = useState("");
|
|
1360
|
+
const [code, setCode] = useState("");
|
|
1361
|
+
const [step, setStep] = useState("password");
|
|
1362
|
+
const challenge = useChallenge(methods?.captchaSiteKey, props.locale);
|
|
1363
|
+
const offers = signInOffers(methods);
|
|
1364
|
+
const passwordOn = offers.password;
|
|
1291
1365
|
const autofill = useRef(null);
|
|
1292
1366
|
const [offer, setOffer] = useState(0);
|
|
1293
1367
|
const [company, setCompany] = useState(null);
|
|
@@ -1339,10 +1413,18 @@ function SignIn(props) {
|
|
|
1339
1413
|
const submit = async (e) => {
|
|
1340
1414
|
e.preventDefault();
|
|
1341
1415
|
autofill.current?.abort();
|
|
1416
|
+
if (step === "password" && company?.enforced) {
|
|
1417
|
+
f.setError(null);
|
|
1418
|
+
return toCompany();
|
|
1419
|
+
}
|
|
1420
|
+
if (step === "password" && !passwordOn) {
|
|
1421
|
+
if (company) return toCompany();
|
|
1422
|
+
if (methods?.magicLink) return sendLink();
|
|
1423
|
+
return;
|
|
1424
|
+
}
|
|
1342
1425
|
f.setBusy(true);
|
|
1343
1426
|
f.setError(null);
|
|
1344
|
-
|
|
1345
|
-
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 });
|
|
1427
|
+
const r = step === "sent" ? await auth.signIn.emailCode({ code }) : await auth.signIn.email({ email, password, captchaToken: challenge.token });
|
|
1346
1428
|
f.setBusy(false);
|
|
1347
1429
|
if (step === "password") challenge.renew();
|
|
1348
1430
|
if (!r.ok && r.error.code === "sso_required") return toCompany();
|
|
@@ -1376,6 +1458,7 @@ function SignIn(props) {
|
|
|
1376
1458
|
setStep("sent");
|
|
1377
1459
|
};
|
|
1378
1460
|
const general = f.error && !f.error.field ? f.error : null;
|
|
1461
|
+
const asksEmail = offers.email;
|
|
1379
1462
|
if (step === "opening") return /* @__PURE__ */ jsx("div", { className: f.cx("form"), ...f.root, "aria-busy": "true" });
|
|
1380
1463
|
if (step === "sent") {
|
|
1381
1464
|
return /* @__PURE__ */ jsxs("form", { className: f.cx("form"), ...f.root, onSubmit: submit, noValidate: true, children: [
|
|
@@ -1386,39 +1469,20 @@ function SignIn(props) {
|
|
|
1386
1469
|
/* @__PURE__ */ jsx(f.Button, { type: "submit", disabled: f.busy, className: f.cx("button"), children: f.t.verify })
|
|
1387
1470
|
] });
|
|
1388
1471
|
}
|
|
1389
|
-
if (step === "code") {
|
|
1390
|
-
const to = phoneWay?.phone?.number ?? "";
|
|
1391
|
-
return /* @__PURE__ */ jsxs("form", { className: f.cx("form"), ...f.root, onSubmit: submit, noValidate: true, children: [
|
|
1392
|
-
/* @__PURE__ */ jsx("p", { className: f.cx("notice"), children: phoneSent ? f.t.codeSent.replace("{to}", phoneSent) : phoneWay?.email ? f.t.codeHelpEmail.replace("{to}", phoneWay.email.to) : phoneWay?.phone && !phoneWay.totp ? f.t.codeHelpPhone : f.t.codeHelp }),
|
|
1393
|
-
general && /* @__PURE__ */ jsx("p", { role: "alert", className: f.cx("error"), children: f.say(general) }),
|
|
1394
|
-
phoneWay?.email && /* @__PURE__ */ jsx(f.Button, { type: "button", disabled: f.busy, className: f.cx("providerButton"), onClick: () => void sendEmail(), children: f.t.sendEmailAgain }),
|
|
1395
|
-
pushNumber > 0 ? /* @__PURE__ */ jsxs("div", { className: f.cx("notice"), role: "status", "aria-live": "polite", children: [
|
|
1396
|
-
/* @__PURE__ */ jsx("p", { children: f.t.pushPick.replace("{n}", String(pushNumber)) }),
|
|
1397
|
-
/* @__PURE__ */ jsx("p", { style: { fontSize: 48, fontWeight: 700, margin: "4px 0", textAlign: "center" }, children: pushNumber }),
|
|
1398
|
-
/* @__PURE__ */ jsx("p", { children: f.t.pushWaiting })
|
|
1399
|
-
] }) : phoneWay?.push && /* @__PURE__ */ jsx(f.Button, { type: "button", disabled: f.busy, className: f.cx("button"), onClick: () => void sendPush(), children: f.t.pushSend }),
|
|
1400
|
-
phoneWay?.phone && /* @__PURE__ */ jsx(f.Button, { type: "button", disabled: f.busy, className: f.cx("providerButton"), onClick: () => void sendCode(), children: (phoneWay.phone.channel === "whatsapp" ? f.t.sendCodeWhatsapp : f.t.sendCodeSms).replace("{to}", to) }),
|
|
1401
|
-
/* @__PURE__ */ jsx(Field, { f, name: "code", type: "text", label: f.t.code, value: code, autoComplete: "one-time-code", required: true, onChange: setCode }),
|
|
1402
|
-
/* @__PURE__ */ jsx(f.Button, { type: "submit", disabled: f.busy, className: f.cx("button"), children: f.t.verify })
|
|
1403
|
-
] });
|
|
1404
|
-
}
|
|
1472
|
+
if (step === "code") return /* @__PURE__ */ jsx(SecondStepForm, { f, auth });
|
|
1405
1473
|
return /* @__PURE__ */ jsxs("form", { className: f.cx("form"), ...f.root, onSubmit: submit, noValidate: true, children: [
|
|
1406
1474
|
general && /* @__PURE__ */ jsx("p", { role: "alert", className: f.cx("error"), children: f.say(general) }),
|
|
1407
|
-
|
|
1408
|
-
|
|
1409
|
-
|
|
1410
|
-
|
|
1411
|
-
] }, p.id)),
|
|
1412
|
-
methods?.passkey && /* @__PURE__ */ jsx(f.Button, { type: "button", disabled: f.busy, className: f.cx("providerButton"), onClick: () => void usePasskey(), children: f.t.usePasskey }),
|
|
1413
|
-
((methods?.providers.length ?? 0) > 0 || methods?.passkey) && /* @__PURE__ */ jsx("p", { className: f.cx("separator"), children: f.t.orWithEmail }),
|
|
1414
|
-
/* @__PURE__ */ jsx(Field, { f, name: "email", type: "email", label: f.t.email, value: email, autoComplete: methods?.passkeyHere ? "username webauthn" : "username", required: true, onChange: setEmail }),
|
|
1475
|
+
/* @__PURE__ */ jsx(ProviderButtons, { f, providers: methods?.providers ?? [], onPick: (id) => auth.signIn.social(id, { returnTo: props.returnTo }) }),
|
|
1476
|
+
offers.passkey && /* @__PURE__ */ jsx(f.Button, { type: "button", disabled: f.busy, className: f.cx("providerButton"), onClick: () => void usePasskey(), children: f.t.usePasskey }),
|
|
1477
|
+
asksEmail && ((methods?.providers.length ?? 0) > 0 || offers.passkey) && /* @__PURE__ */ jsx("p", { className: f.cx("separator"), children: f.t.orWithEmail }),
|
|
1478
|
+
asksEmail && /* @__PURE__ */ jsx(Field, { f, name: "email", type: "email", label: f.t.email, value: email, autoComplete: methods?.passkeyHere ? "username webauthn" : "username", required: true, onChange: setEmail }),
|
|
1415
1479
|
company && /* @__PURE__ */ jsxs(f.Button, { type: "button", disabled: f.busy, className: f.cx(company.enforced ? "button" : "providerButton"), onClick: toCompany, children: [
|
|
1416
1480
|
f.t.continueWith,
|
|
1417
1481
|
" ",
|
|
1418
1482
|
company.name
|
|
1419
1483
|
] }),
|
|
1420
1484
|
company?.enforced && /* @__PURE__ */ jsx("p", { className: f.cx("notice"), children: f.t.ssoOnly }),
|
|
1421
|
-
!company?.enforced && /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
1485
|
+
!company?.enforced && passwordOn && /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
1422
1486
|
/* @__PURE__ */ jsx(
|
|
1423
1487
|
Field,
|
|
1424
1488
|
{
|
|
@@ -1436,6 +1500,7 @@ function SignIn(props) {
|
|
|
1436
1500
|
challenge.node,
|
|
1437
1501
|
/* @__PURE__ */ jsx(f.Button, { type: "submit", disabled: f.busy, className: f.cx("button"), children: f.t.signIn })
|
|
1438
1502
|
] }),
|
|
1503
|
+
!company?.enforced && !passwordOn && methods?.magicLink && challenge.node,
|
|
1439
1504
|
methods?.magicLink && !company?.enforced && /* @__PURE__ */ jsx(f.Button, { type: "button", disabled: f.busy, className: f.cx("providerButton"), onClick: () => void sendLink(), children: f.t.emailMeALink }),
|
|
1440
1505
|
methods?.signUp !== false && props.links?.signUp && /* @__PURE__ */ jsxs("p", { className: f.cx("footer"), children: [
|
|
1441
1506
|
f.t.noAccount,
|
|
@@ -1495,14 +1560,30 @@ function SignUp(props) {
|
|
|
1495
1560
|
f.done();
|
|
1496
1561
|
};
|
|
1497
1562
|
const general = f.error && !f.error.field ? f.error : null;
|
|
1563
|
+
const passwordOn = methods?.passwordSignIn !== false;
|
|
1564
|
+
const providers = auth.session?.user.isAnonymous === true || methods?.organization?.required ? [] : methods?.providers ?? [];
|
|
1498
1565
|
if (sent) {
|
|
1499
1566
|
return /* @__PURE__ */ jsxs("div", { className: f.cx("form"), ...f.root, children: [
|
|
1500
1567
|
/* @__PURE__ */ jsx("p", { className: f.cx("notice"), children: f.t.checkEmail }),
|
|
1501
1568
|
props.links?.signIn && /* @__PURE__ */ jsx("a", { className: f.cx("link"), href: props.links.signIn, children: f.t.backToSignIn })
|
|
1502
1569
|
] });
|
|
1503
1570
|
}
|
|
1571
|
+
const footer = props.links?.signIn && /* @__PURE__ */ jsxs("p", { className: f.cx("footer"), children: [
|
|
1572
|
+
f.t.haveAccount,
|
|
1573
|
+
" ",
|
|
1574
|
+
/* @__PURE__ */ jsx("a", { className: f.cx("link"), href: props.links.signIn, children: f.t.signIn })
|
|
1575
|
+
] });
|
|
1576
|
+
if (!passwordOn) {
|
|
1577
|
+
return /* @__PURE__ */ jsxs("div", { className: f.cx("form"), ...f.root, children: [
|
|
1578
|
+
general && /* @__PURE__ */ jsx("p", { role: "alert", className: f.cx("error"), children: f.say(general) }),
|
|
1579
|
+
/* @__PURE__ */ jsx(ProviderButtons, { f, providers, onPick: (id) => auth.signIn.social(id, { returnTo: props.returnTo }) }),
|
|
1580
|
+
footer
|
|
1581
|
+
] });
|
|
1582
|
+
}
|
|
1504
1583
|
return /* @__PURE__ */ jsxs("form", { className: f.cx("form"), ...f.root, onSubmit: submit, noValidate: true, children: [
|
|
1505
1584
|
general && /* @__PURE__ */ jsx("p", { role: "alert", className: f.cx("error"), children: f.say(general) }),
|
|
1585
|
+
/* @__PURE__ */ jsx(ProviderButtons, { f, providers, onPick: (id) => auth.signIn.social(id, { returnTo: props.returnTo }) }),
|
|
1586
|
+
providers.length > 0 && /* @__PURE__ */ jsx("p", { className: f.cx("separator"), children: f.t.orWithEmail }),
|
|
1506
1587
|
methods?.organization?.ask && /* @__PURE__ */ jsx(Field, { f, name: "organization", type: "text", label: f.t.company, value: organization, autoComplete: "organization", required: methods.organization.required, onChange: setOrganization }),
|
|
1507
1588
|
/* @__PURE__ */ jsx(Field, { f, name: "name", type: "text", label: f.t.name, value: name, autoComplete: "name", onChange: setName }),
|
|
1508
1589
|
/* @__PURE__ */ jsx(Field, { f, name: "email", type: "email", label: f.t.email, value: email, autoComplete: "username", required: true, onChange: setEmail }),
|
|
@@ -1528,11 +1609,7 @@ function SignUp(props) {
|
|
|
1528
1609
|
] }, p.key)),
|
|
1529
1610
|
challenge.node,
|
|
1530
1611
|
/* @__PURE__ */ jsx(f.Button, { type: "submit", disabled: f.busy, className: f.cx("button"), children: f.t.signUp }),
|
|
1531
|
-
|
|
1532
|
-
f.t.haveAccount,
|
|
1533
|
-
" ",
|
|
1534
|
-
/* @__PURE__ */ jsx("a", { className: f.cx("link"), href: props.links.signIn, children: f.t.signIn })
|
|
1535
|
-
] })
|
|
1612
|
+
footer
|
|
1536
1613
|
] });
|
|
1537
1614
|
}
|
|
1538
1615
|
function ForgotPassword(props) {
|
|
@@ -1629,6 +1706,62 @@ function VerifyEmail(props) {
|
|
|
1629
1706
|
state !== "confirming" && props.links?.signIn && /* @__PURE__ */ jsx("a", { className: f.cx("link"), href: props.links.signIn, children: f.t.backToSignIn })
|
|
1630
1707
|
] });
|
|
1631
1708
|
}
|
|
1709
|
+
function AcceptInvite(props) {
|
|
1710
|
+
const auth = useAuth();
|
|
1711
|
+
const f = useForm(props);
|
|
1712
|
+
const [token, setToken] = useState("");
|
|
1713
|
+
const [invitation, setInvitation] = useState(null);
|
|
1714
|
+
const [state, setState] = useState("opening");
|
|
1715
|
+
const [password, setPassword] = useState("");
|
|
1716
|
+
usePasswordPolicy(f, useMethods(auth));
|
|
1717
|
+
useMailedToken("token", (t) => {
|
|
1718
|
+
if (!t) return setState("invalid");
|
|
1719
|
+
setToken(t);
|
|
1720
|
+
void auth.invitation(t).then((r) => {
|
|
1721
|
+
if (r.ok) {
|
|
1722
|
+
setInvitation(r.invitation);
|
|
1723
|
+
return setState("ready");
|
|
1724
|
+
}
|
|
1725
|
+
if (r.error.code !== "invalid_token") f.setError(r.error);
|
|
1726
|
+
setState("invalid");
|
|
1727
|
+
});
|
|
1728
|
+
});
|
|
1729
|
+
const submit = async (e) => {
|
|
1730
|
+
e.preventDefault();
|
|
1731
|
+
f.setBusy(true);
|
|
1732
|
+
f.setError(null);
|
|
1733
|
+
const r = await auth.acceptInvitation(token, password);
|
|
1734
|
+
f.setBusy(false);
|
|
1735
|
+
if (!r.ok) {
|
|
1736
|
+
if (r.error.code === "invalid_token") return setState("invalid");
|
|
1737
|
+
return f.setError(r.error);
|
|
1738
|
+
}
|
|
1739
|
+
if (r.status === "mfa_required") return setState("code");
|
|
1740
|
+
f.done();
|
|
1741
|
+
};
|
|
1742
|
+
const general = f.error && !f.error.field ? f.error : null;
|
|
1743
|
+
const back = props.links?.signIn && /* @__PURE__ */ jsx("a", { className: f.cx("link"), href: props.links.signIn, children: f.t.backToSignIn });
|
|
1744
|
+
if (state === "opening") {
|
|
1745
|
+
return /* @__PURE__ */ jsx("div", { className: f.cx("form"), ...f.root, "aria-busy": "true", children: /* @__PURE__ */ jsx("p", { className: f.cx("notice"), children: f.t.openingInvitation }) });
|
|
1746
|
+
}
|
|
1747
|
+
if (state === "invalid") {
|
|
1748
|
+
return /* @__PURE__ */ jsxs("div", { className: f.cx("form"), ...f.root, children: [
|
|
1749
|
+
/* @__PURE__ */ jsx("p", { role: "alert", className: f.cx("error"), children: general ? f.say(general) : f.t.invitationInvalid }),
|
|
1750
|
+
back
|
|
1751
|
+
] });
|
|
1752
|
+
}
|
|
1753
|
+
if (state === "code") return /* @__PURE__ */ jsx(SecondStepForm, { f, auth });
|
|
1754
|
+
const workspace = invitation?.workspace ?? "";
|
|
1755
|
+
const heading = invitation?.organization ? f.t.invitedToOrganization.replace("{organization}", invitation.organization).replace("{workspace}", workspace) : f.t.invitedTo.replace("{workspace}", workspace);
|
|
1756
|
+
return /* @__PURE__ */ jsxs("form", { className: f.cx("form"), ...f.root, onSubmit: submit, noValidate: true, children: [
|
|
1757
|
+
/* @__PURE__ */ jsx("h2", { className: f.cx("heading"), children: heading }),
|
|
1758
|
+
/* @__PURE__ */ jsx("p", { className: f.cx("notice"), children: f.t.invitedAs.replace("{email}", invitation?.email ?? "") }),
|
|
1759
|
+
general && /* @__PURE__ */ jsx("p", { role: "alert", className: f.cx("error"), children: f.say(general) }),
|
|
1760
|
+
/* @__PURE__ */ jsx("input", { type: "email", name: "username", autoComplete: "username", value: invitation?.email ?? "", readOnly: true, hidden: true }),
|
|
1761
|
+
/* @__PURE__ */ jsx(Field, { f, name: "password", type: "password", label: f.t.choosePassword, value: password, autoComplete: "new-password", required: true, onChange: setPassword, hint: f.passwordRule }),
|
|
1762
|
+
/* @__PURE__ */ jsx(f.Button, { type: "submit", disabled: f.busy, className: f.cx("button"), children: f.t.acceptInvite })
|
|
1763
|
+
] });
|
|
1764
|
+
}
|
|
1632
1765
|
function useSection(props) {
|
|
1633
1766
|
const f = useForm({ ...props, unstyled: true });
|
|
1634
1767
|
const [done, setDone] = useState(null);
|
|
@@ -2276,6 +2409,8 @@ function useAuth() {
|
|
|
2276
2409
|
googleOneTap: (o) => then(client.signIn.googleOneTap(o))
|
|
2277
2410
|
},
|
|
2278
2411
|
signUp: { email: (f) => then(client.signUp.email(f)) },
|
|
2412
|
+
// The invited person is signed in once they accept.
|
|
2413
|
+
acceptInvitation: (token, password) => then(client.acceptInvitation(token, password)),
|
|
2279
2414
|
signOut: () => then(client.signOut()),
|
|
2280
2415
|
account: {
|
|
2281
2416
|
...client.account,
|
|
@@ -2293,6 +2428,7 @@ function useAuth() {
|
|
|
2293
2428
|
}, [basePath, refresh, session, status]);
|
|
2294
2429
|
}
|
|
2295
2430
|
export {
|
|
2431
|
+
AcceptInvite,
|
|
2296
2432
|
Account,
|
|
2297
2433
|
CauthyProvider,
|
|
2298
2434
|
ForgotPassword,
|