cauthy-auth 0.32.0 → 0.34.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 +25 -4
- package/dist/{cauthy-CKfvvv_i.d.ts → cauthy-BUozWD72.d.ts} +1 -1
- package/dist/{cauthy-2jtP2LVQ.d.mts → cauthy-C-GoRXy9.d.mts} +1 -1
- package/dist/cli.js +1 -1
- package/dist/client.d.mts +7 -3
- package/dist/client.d.ts +7 -3
- package/dist/client.js.map +1 -1
- 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 +3 -1
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +3 -1
- 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 +59 -8
- package/dist/react.d.ts +59 -8
- package/dist/react.js +188 -113
- package/dist/react.js.map +1 -1
- package/dist/react.mjs +191 -116
- package/dist/react.mjs.map +1 -1
- package/dist/svelte.d.mts +2 -2
- package/dist/svelte.d.ts +2 -2
- package/dist/svelte.js.map +1 -1
- package/dist/svelte.mjs.map +1 -1
- package/dist/{system-BvvoNs2y.d.ts → system-Bz4haPrI.d.ts} +10 -2
- package/dist/{system-BrrJsrFW.d.mts → system-DUGV040y.d.mts} +10 -2
- package/dist/vue.d.mts +2 -2
- package/dist/vue.d.ts +2 -2
- package/dist/vue.js.map +1 -1
- package/dist/vue.mjs.map +1 -1
- package/package.json +1 -1
package/dist/react.mjs
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
'use client';
|
|
2
2
|
|
|
3
3
|
// src/react.tsx
|
|
4
|
-
import { createContext, useCallback, useContext, useEffect as useEffect2, useMemo, useRef as useRef2, useState as useState2 } from "react";
|
|
4
|
+
import { createContext, useCallback as useCallback2, useContext, useEffect as useEffect2, useMemo, useRef as useRef2, useState as useState2 } from "react";
|
|
5
5
|
|
|
6
6
|
// src/passkey.ts
|
|
7
7
|
function canUsePasskeys() {
|
|
@@ -721,7 +721,7 @@ function definePolicy(given) {
|
|
|
721
721
|
}
|
|
722
722
|
|
|
723
723
|
// src/components.tsx
|
|
724
|
-
import { Fragment, useEffect, useId, useRef, useState } from "react";
|
|
724
|
+
import { Fragment, useCallback, useEffect, useId, useRef, useState } from "react";
|
|
725
725
|
import { Fragment as Fragment2, jsx, jsxs } from "react/jsx-runtime";
|
|
726
726
|
var TEXTS = {
|
|
727
727
|
en: {
|
|
@@ -861,6 +861,7 @@ var TEXTS = {
|
|
|
861
861
|
last_manager: "Somebody else must manage the members first: give that role to another member.",
|
|
862
862
|
last_owner: "An organization keeps at least one owner: make another member owner first.",
|
|
863
863
|
organization_not_found: "That organization no longer exists.",
|
|
864
|
+
member_exists: "That person already belongs to the organization; their role was not changed. Change it in the list instead.",
|
|
864
865
|
already_member: "That person already belongs to the organization. Change their role instead.",
|
|
865
866
|
unknown_role: "Choose one of the roles offered.",
|
|
866
867
|
user_not_active: "That account is disabled.",
|
|
@@ -1041,6 +1042,7 @@ var TEXTS = {
|
|
|
1041
1042
|
last_manager: "Primero alguien m\xE1s debe administrar los miembros: dale ese rol a otro miembro.",
|
|
1042
1043
|
last_owner: "Una organizaci\xF3n conserva al menos un propietario: primero haz propietario a otro miembro.",
|
|
1043
1044
|
organization_not_found: "Esa organizaci\xF3n ya no existe.",
|
|
1045
|
+
member_exists: "Esa persona ya pertenece a la organizaci\xF3n; su rol no cambi\xF3. C\xE1mbialo en la lista.",
|
|
1044
1046
|
already_member: "Esa persona ya pertenece a la organizaci\xF3n. Cambia su rol.",
|
|
1045
1047
|
unknown_role: "Escoge uno de los roles ofrecidos.",
|
|
1046
1048
|
user_not_active: "Esa cuenta est\xE1 desactivada.",
|
|
@@ -1085,7 +1087,7 @@ var TEXTS = {
|
|
|
1085
1087
|
}
|
|
1086
1088
|
}
|
|
1087
1089
|
};
|
|
1088
|
-
var PlainButton = (p) => /* @__PURE__ */ jsx("button", { ...p });
|
|
1090
|
+
var PlainButton = ({ variant: _variant, loading: _loading, ...p }) => /* @__PURE__ */ jsx("button", { ...p });
|
|
1089
1091
|
var PlainInput = (p) => /* @__PURE__ */ jsx("input", { ...p });
|
|
1090
1092
|
var looks = /* @__PURE__ */ new Map();
|
|
1091
1093
|
var loaded = /* @__PURE__ */ new Set();
|
|
@@ -1200,8 +1202,24 @@ function useForm(props) {
|
|
|
1200
1202
|
const C = props.components ?? {};
|
|
1201
1203
|
const Button = C.Button ?? PlainButton;
|
|
1202
1204
|
const Input = C.Input ?? PlainInput;
|
|
1203
|
-
const [error,
|
|
1204
|
-
const [
|
|
1205
|
+
const [error, setOnlyError] = useState(null);
|
|
1206
|
+
const [problems, setProblems] = useState({ list: [], round: 0 });
|
|
1207
|
+
const setError = useCallback((e) => {
|
|
1208
|
+
setOnlyError(e);
|
|
1209
|
+
setProblems((p) => p.list.length === 0 ? p : { list: [], round: p.round });
|
|
1210
|
+
}, []);
|
|
1211
|
+
const check = (...found) => {
|
|
1212
|
+
const list = found.filter((e) => Boolean(e));
|
|
1213
|
+
setOnlyError(null);
|
|
1214
|
+
setProblems((p) => ({ list, round: list.length > 0 ? p.round + 1 : p.round }));
|
|
1215
|
+
return list.length === 0;
|
|
1216
|
+
};
|
|
1217
|
+
const fieldError = (name) => problems.list.find((e) => e.field === name) ?? (error?.field === name ? error : null);
|
|
1218
|
+
const firstWrong = (name) => problems.list[0]?.field === name ? problems.round : 0;
|
|
1219
|
+
const [acting, setActing] = useState(null);
|
|
1220
|
+
const busy = acting !== null;
|
|
1221
|
+
const setBusy = useCallback((on) => setActing(on === false ? null : on === true ? SUBMIT : on), []);
|
|
1222
|
+
const loading = (key = SUBMIT) => acting === key;
|
|
1205
1223
|
const [policy, setPolicy] = useState(void 0);
|
|
1206
1224
|
const locale = props.locale ?? "en";
|
|
1207
1225
|
const say = (e) => {
|
|
@@ -1214,7 +1232,28 @@ function useForm(props) {
|
|
|
1214
1232
|
else window.location.assign(sitePath(to) ?? sameOrigin(props.returnTo) ?? "/");
|
|
1215
1233
|
};
|
|
1216
1234
|
const root = useRoot(props);
|
|
1217
|
-
return { t, cx, own, C, Button, Input, error, setError, busy, setBusy, say, done, root, policy, setPolicy, passwordRule };
|
|
1235
|
+
return { t, cx, own, C, Button, Input, error, setError, check, fieldError, firstWrong, busy, setBusy, loading, say, done, root, policy, setPolicy, passwordRule };
|
|
1236
|
+
}
|
|
1237
|
+
var SUBMIT = "submit";
|
|
1238
|
+
function Wrap(p) {
|
|
1239
|
+
const { Form: OwnForm } = p.f.C;
|
|
1240
|
+
if (OwnForm) {
|
|
1241
|
+
const own = /* @__PURE__ */ jsx(
|
|
1242
|
+
OwnForm,
|
|
1243
|
+
{
|
|
1244
|
+
as: p.as === "form" ? "form" : "div",
|
|
1245
|
+
onSubmit: p.onSubmit,
|
|
1246
|
+
noValidate: p.noValidate,
|
|
1247
|
+
"aria-busy": p.busy,
|
|
1248
|
+
className: p.slot ? p.f.own(p.slot) : void 0,
|
|
1249
|
+
section: p.section,
|
|
1250
|
+
children: p.children
|
|
1251
|
+
}
|
|
1252
|
+
);
|
|
1253
|
+
return p.root?.["data-cauthy"] !== void 0 ? /* @__PURE__ */ jsx("div", { ...p.root, children: own }) : own;
|
|
1254
|
+
}
|
|
1255
|
+
const Tag2 = p.as;
|
|
1256
|
+
return /* @__PURE__ */ jsx(Tag2, { className: p.slot ? p.f.cx(p.slot) : void 0, ...p.root, onSubmit: p.onSubmit, noValidate: p.noValidate, "aria-busy": p.busy, children: p.children });
|
|
1218
1257
|
}
|
|
1219
1258
|
function Note({ f, children, footer }) {
|
|
1220
1259
|
const { Text } = f.C;
|
|
@@ -1295,6 +1334,11 @@ function isPasswordRule(e) {
|
|
|
1295
1334
|
if (e.code === "weak_password" || PASSWORD_RULES.includes(e.code)) return true;
|
|
1296
1335
|
return (e.code === "too_short" || e.code === "too_long") && (e.field === "password" || e.field === "newPassword");
|
|
1297
1336
|
}
|
|
1337
|
+
function newPasswordProblem(value, policy, field = "password") {
|
|
1338
|
+
const bad = checkNewPassword(value, policy);
|
|
1339
|
+
if (!bad) return null;
|
|
1340
|
+
return { code: bad.code, message: bad.message, field, ...bad.code === "required" ? {} : { reasons: passwordProblems(value, policy) } };
|
|
1341
|
+
}
|
|
1298
1342
|
function usePasswordPolicy(f, methods) {
|
|
1299
1343
|
const { setPolicy } = f;
|
|
1300
1344
|
useEffect(() => {
|
|
@@ -1304,7 +1348,11 @@ function usePasswordPolicy(f, methods) {
|
|
|
1304
1348
|
function Field(p) {
|
|
1305
1349
|
const id = useId();
|
|
1306
1350
|
const { f } = p;
|
|
1307
|
-
const bad = f.
|
|
1351
|
+
const bad = f.fieldError(p.name);
|
|
1352
|
+
const focus = f.firstWrong(p.name);
|
|
1353
|
+
useEffect(() => {
|
|
1354
|
+
if (focus > 0 && typeof document !== "undefined") document.getElementById(id)?.focus();
|
|
1355
|
+
}, [focus, id]);
|
|
1308
1356
|
const described = [bad ? `${id}-error` : "", p.hint ? `${id}-hint` : ""].filter(Boolean).join(" ");
|
|
1309
1357
|
const input = /* @__PURE__ */ jsx(
|
|
1310
1358
|
f.Input,
|
|
@@ -1380,7 +1428,7 @@ function SecondStepForm(p) {
|
|
|
1380
1428
|
});
|
|
1381
1429
|
}, []);
|
|
1382
1430
|
const sendEmail = async () => {
|
|
1383
|
-
f.setBusy(
|
|
1431
|
+
f.setBusy("email");
|
|
1384
1432
|
f.setError(null);
|
|
1385
1433
|
const r = await auth.signIn.mfaSendEmail();
|
|
1386
1434
|
f.setBusy(false);
|
|
@@ -1391,7 +1439,7 @@ function SecondStepForm(p) {
|
|
|
1391
1439
|
const pushWait = useRef(null);
|
|
1392
1440
|
useEffect(() => () => pushWait.current?.abort(), []);
|
|
1393
1441
|
const sendPush = async () => {
|
|
1394
|
-
f.setBusy(
|
|
1442
|
+
f.setBusy("push");
|
|
1395
1443
|
f.setError(null);
|
|
1396
1444
|
const r = await auth.signIn.mfaPush();
|
|
1397
1445
|
f.setBusy(false);
|
|
@@ -1407,7 +1455,7 @@ function SecondStepForm(p) {
|
|
|
1407
1455
|
f.done();
|
|
1408
1456
|
};
|
|
1409
1457
|
const sendCode = async () => {
|
|
1410
|
-
f.setBusy(
|
|
1458
|
+
f.setBusy("phone");
|
|
1411
1459
|
f.setError(null);
|
|
1412
1460
|
const r = await auth.signIn.mfaSendCode();
|
|
1413
1461
|
f.setBusy(false);
|
|
@@ -1425,10 +1473,10 @@ function SecondStepForm(p) {
|
|
|
1425
1473
|
};
|
|
1426
1474
|
const general = f.error && !f.error.field ? f.error : null;
|
|
1427
1475
|
const to = phoneWay?.phone?.number ?? "";
|
|
1428
|
-
return /* @__PURE__ */ jsxs("form",
|
|
1476
|
+
return /* @__PURE__ */ jsxs(Wrap, { f, as: "form", slot: "form", root: f.root, onSubmit: submit, noValidate: true, children: [
|
|
1429
1477
|
/* @__PURE__ */ jsx(Note, { f, 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 }),
|
|
1430
1478
|
general && /* @__PURE__ */ jsx(Say, { f, tone: "danger", children: f.say(general) }),
|
|
1431
|
-
phoneWay?.email && /* @__PURE__ */ jsx(f.Button, { type: "button", disabled: f.busy, className: f.cx("providerButton"), onClick: () => void sendEmail(), children: f.t.sendEmailAgain }),
|
|
1479
|
+
phoneWay?.email && /* @__PURE__ */ jsx(f.Button, { type: "button", variant: "secondary", loading: f.loading("email"), disabled: f.busy, className: f.cx("providerButton"), onClick: () => void sendEmail(), children: f.t.sendEmailAgain }),
|
|
1432
1480
|
pushNumber > 0 ? f.C.Text ? (
|
|
1433
1481
|
// The application's text: the number to pick drawn large, by its own rules.
|
|
1434
1482
|
/* @__PURE__ */ jsxs("div", { role: "status", "aria-live": "polite", children: [
|
|
@@ -1440,15 +1488,15 @@ function SecondStepForm(p) {
|
|
|
1440
1488
|
/* @__PURE__ */ jsx("p", { children: f.t.pushPick.replace("{n}", String(pushNumber)) }),
|
|
1441
1489
|
/* @__PURE__ */ jsx("p", { style: { fontSize: 48, fontWeight: 700, margin: "4px 0", textAlign: "center" }, children: pushNumber }),
|
|
1442
1490
|
/* @__PURE__ */ jsx("p", { children: f.t.pushWaiting })
|
|
1443
|
-
] }) : phoneWay?.push && /* @__PURE__ */ jsx(f.Button, { type: "button", disabled: f.busy, className: f.cx("button"), onClick: () => void sendPush(), children: f.t.pushSend }),
|
|
1444
|
-
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) }),
|
|
1491
|
+
] }) : phoneWay?.push && /* @__PURE__ */ jsx(f.Button, { type: "button", variant: "secondary", loading: f.loading("push"), disabled: f.busy, className: f.cx("button"), onClick: () => void sendPush(), children: f.t.pushSend }),
|
|
1492
|
+
phoneWay?.phone && /* @__PURE__ */ jsx(f.Button, { type: "button", variant: "secondary", loading: f.loading("phone"), disabled: f.busy, className: f.cx("providerButton"), onClick: () => void sendCode(), children: (phoneWay.phone.channel === "whatsapp" ? f.t.sendCodeWhatsapp : f.t.sendCodeSms).replace("{to}", to) }),
|
|
1445
1493
|
/* @__PURE__ */ jsx(Field, { f, name: "code", type: "text", label: f.t.code, value: code, autoComplete: "one-time-code", required: true, onChange: setCode }),
|
|
1446
|
-
/* @__PURE__ */ jsx(f.Button, { type: "submit", disabled: f.busy, className: f.cx("button"), children: f.t.verify })
|
|
1494
|
+
/* @__PURE__ */ jsx(f.Button, { type: "submit", variant: "primary", loading: f.loading(), disabled: f.busy, className: f.cx("button"), children: f.t.verify })
|
|
1447
1495
|
] });
|
|
1448
1496
|
}
|
|
1449
1497
|
function ProviderButtons(p) {
|
|
1450
1498
|
const { f } = p;
|
|
1451
|
-
return /* @__PURE__ */ jsx(Fragment2, { children: p.providers.map((provider) => /* @__PURE__ */ jsxs(f.Button, { type: "button", className: f.cx("providerButton"), onClick: () => p.onPick(provider.id), children: [
|
|
1499
|
+
return /* @__PURE__ */ jsx(Fragment2, { children: p.providers.map((provider) => /* @__PURE__ */ jsxs(f.Button, { type: "button", variant: "secondary", className: f.cx("providerButton"), onClick: () => p.onPick(provider.id), children: [
|
|
1452
1500
|
provider.iconUrl && /* @__PURE__ */ jsx("img", { src: provider.iconUrl, alt: "", width: 18, height: 18, className: f.cx("providerIcon") }),
|
|
1453
1501
|
f.t.continueWith,
|
|
1454
1502
|
" ",
|
|
@@ -1488,7 +1536,7 @@ function SignIn(props) {
|
|
|
1488
1536
|
}, [email, methods]);
|
|
1489
1537
|
const toCompany = () => {
|
|
1490
1538
|
autofill.current?.abort();
|
|
1491
|
-
f.setBusy(
|
|
1539
|
+
f.setBusy("sso");
|
|
1492
1540
|
auth.signIn.sso({ email }, { returnTo: props.returnTo });
|
|
1493
1541
|
};
|
|
1494
1542
|
useEffect(() => {
|
|
@@ -1530,6 +1578,7 @@ function SignIn(props) {
|
|
|
1530
1578
|
if (methods?.magicLink) return sendLink();
|
|
1531
1579
|
return;
|
|
1532
1580
|
}
|
|
1581
|
+
if (step === "password" && !f.check(checkEmail(email), checkPassword(password))) return;
|
|
1533
1582
|
f.setBusy(true);
|
|
1534
1583
|
f.setError(null);
|
|
1535
1584
|
const r = step === "sent" ? await auth.signIn.emailCode({ code }) : await auth.signIn.email({ email, password, captchaToken: challenge.token });
|
|
@@ -1545,7 +1594,7 @@ function SignIn(props) {
|
|
|
1545
1594
|
};
|
|
1546
1595
|
const usePasskey = async () => {
|
|
1547
1596
|
autofill.current?.abort();
|
|
1548
|
-
f.setBusy(
|
|
1597
|
+
f.setBusy("passkey");
|
|
1549
1598
|
f.setError(null);
|
|
1550
1599
|
const r = await auth.signIn.passkey({ returnTo: props.returnTo, locale: props.locale, email });
|
|
1551
1600
|
if (r.ok && r.status === "redirected") return;
|
|
@@ -1556,7 +1605,7 @@ function SignIn(props) {
|
|
|
1556
1605
|
};
|
|
1557
1606
|
const sendLink = async () => {
|
|
1558
1607
|
autofill.current?.abort();
|
|
1559
|
-
f.setBusy(
|
|
1608
|
+
f.setBusy("link");
|
|
1560
1609
|
f.setError(null);
|
|
1561
1610
|
const r = await auth.signIn.magicLink({ email, captchaToken: challenge.token, create: props.createAccounts, returnTo: props.returnTo });
|
|
1562
1611
|
f.setBusy(false);
|
|
@@ -1567,24 +1616,24 @@ function SignIn(props) {
|
|
|
1567
1616
|
};
|
|
1568
1617
|
const general = f.error && !f.error.field ? f.error : null;
|
|
1569
1618
|
const asksEmail = offers.email;
|
|
1570
|
-
if (step === "opening") return /* @__PURE__ */ jsx("div",
|
|
1619
|
+
if (step === "opening") return /* @__PURE__ */ jsx(Wrap, { f, as: "div", slot: "form", root: f.root, busy: true });
|
|
1571
1620
|
if (step === "sent") {
|
|
1572
|
-
return /* @__PURE__ */ jsxs("form",
|
|
1621
|
+
return /* @__PURE__ */ jsxs(Wrap, { f, as: "form", slot: "form", root: f.root, onSubmit: submit, noValidate: true, children: [
|
|
1573
1622
|
/* @__PURE__ */ jsx(Note, { f, children: f.t.signInLinkSent }),
|
|
1574
1623
|
general && /* @__PURE__ */ jsx(Say, { f, tone: "danger", children: f.say(general) }),
|
|
1575
1624
|
/* @__PURE__ */ jsx(Note, { f, children: f.t.codeFromMail }),
|
|
1576
1625
|
/* @__PURE__ */ jsx(Field, { f, name: "code", type: "text", label: f.t.code, value: code, autoComplete: "one-time-code", required: true, onChange: setCode }),
|
|
1577
|
-
/* @__PURE__ */ jsx(f.Button, { type: "submit", disabled: f.busy, className: f.cx("button"), children: f.t.verify })
|
|
1626
|
+
/* @__PURE__ */ jsx(f.Button, { type: "submit", variant: "primary", loading: f.loading(), disabled: f.busy, className: f.cx("button"), children: f.t.verify })
|
|
1578
1627
|
] });
|
|
1579
1628
|
}
|
|
1580
1629
|
if (step === "code") return /* @__PURE__ */ jsx(SecondStepForm, { f, auth });
|
|
1581
|
-
return /* @__PURE__ */ jsxs("form",
|
|
1630
|
+
return /* @__PURE__ */ jsxs(Wrap, { f, as: "form", slot: "form", root: f.root, onSubmit: submit, noValidate: true, children: [
|
|
1582
1631
|
general && /* @__PURE__ */ jsx(Say, { f, tone: "danger", children: f.say(general) }),
|
|
1583
1632
|
/* @__PURE__ */ jsx(ProviderButtons, { f, providers: methods?.providers ?? [], onPick: (id) => auth.signIn.social(id, { returnTo: props.returnTo }) }),
|
|
1584
|
-
offers.passkey && /* @__PURE__ */ jsx(f.Button, { type: "button", disabled: f.busy, className: f.cx("providerButton"), onClick: () => void usePasskey(), children: f.t.usePasskey }),
|
|
1633
|
+
offers.passkey && /* @__PURE__ */ jsx(f.Button, { type: "button", variant: "secondary", loading: f.loading("passkey"), disabled: f.busy, className: f.cx("providerButton"), onClick: () => void usePasskey(), children: f.t.usePasskey }),
|
|
1585
1634
|
asksEmail && ((methods?.providers.length ?? 0) > 0 || offers.passkey) && /* @__PURE__ */ jsx(Or, { f, children: f.t.orWithEmail }),
|
|
1586
1635
|
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 }),
|
|
1587
|
-
company && /* @__PURE__ */ jsxs(f.Button, { type: "button", disabled: f.busy, className: f.cx(company.enforced ? "button" : "providerButton"), onClick: toCompany, children: [
|
|
1636
|
+
company && /* @__PURE__ */ jsxs(f.Button, { type: "button", variant: company.enforced ? "primary" : "secondary", loading: f.loading("sso"), disabled: f.busy, className: f.cx(company.enforced ? "button" : "providerButton"), onClick: toCompany, children: [
|
|
1588
1637
|
f.t.continueWith,
|
|
1589
1638
|
" ",
|
|
1590
1639
|
company.name
|
|
@@ -1606,10 +1655,10 @@ function SignIn(props) {
|
|
|
1606
1655
|
}
|
|
1607
1656
|
),
|
|
1608
1657
|
challenge.node,
|
|
1609
|
-
/* @__PURE__ */ jsx(f.Button, { type: "submit", disabled: f.busy, className: f.cx("button"), children: f.t.signIn })
|
|
1658
|
+
/* @__PURE__ */ jsx(f.Button, { type: "submit", variant: "primary", loading: f.loading(), disabled: f.busy, className: f.cx("button"), children: f.t.signIn })
|
|
1610
1659
|
] }),
|
|
1611
1660
|
!company?.enforced && !passwordOn && methods?.magicLink && challenge.node,
|
|
1612
|
-
methods?.magicLink && !company?.enforced && /* @__PURE__ */ jsx(f.Button, { type: "button", disabled: f.busy, className: f.cx("providerButton"), onClick: () => void sendLink(), children: f.t.emailMeALink }),
|
|
1661
|
+
methods?.magicLink && !company?.enforced && /* @__PURE__ */ jsx(f.Button, { type: "button", variant: "secondary", loading: f.loading("link"), disabled: f.busy, className: f.cx("providerButton"), onClick: () => void sendLink(), children: f.t.emailMeALink }),
|
|
1613
1662
|
methods?.signUp !== false && props.links?.signUp && /* @__PURE__ */ jsxs(Note, { f, footer: true, children: [
|
|
1614
1663
|
f.t.noAccount,
|
|
1615
1664
|
" ",
|
|
@@ -1649,11 +1698,19 @@ function SignUp(props) {
|
|
|
1649
1698
|
const [acceptLegal, setAcceptLegal] = useState(false);
|
|
1650
1699
|
const [consents, setConsents] = useState({});
|
|
1651
1700
|
const legal = methods?.legal;
|
|
1701
|
+
const guest = auth.session?.user.isAnonymous === true;
|
|
1652
1702
|
const submit = async (e) => {
|
|
1653
1703
|
e.preventDefault();
|
|
1704
|
+
const asksCompany = methods?.organization?.ask === true;
|
|
1705
|
+
if (!f.check(
|
|
1706
|
+
asksCompany && checkOrganization(organization, methods?.organization?.required === true),
|
|
1707
|
+
checkName(name),
|
|
1708
|
+
checkEmail(email),
|
|
1709
|
+
newPasswordProblem(password, f.policy)
|
|
1710
|
+
)) return;
|
|
1654
1711
|
f.setBusy(true);
|
|
1655
1712
|
f.setError(null);
|
|
1656
|
-
const r =
|
|
1713
|
+
const r = guest ? await auth.account.upgrade({ name, email, password }) : await auth.signUp.email({
|
|
1657
1714
|
name,
|
|
1658
1715
|
email,
|
|
1659
1716
|
password,
|
|
@@ -1669,30 +1726,31 @@ function SignUp(props) {
|
|
|
1669
1726
|
};
|
|
1670
1727
|
const general = f.error && !f.error.field ? f.error : null;
|
|
1671
1728
|
const passwordOn = methods?.passwordSignIn !== false;
|
|
1672
|
-
const providers =
|
|
1729
|
+
const providers = guest || methods?.organization?.required ? [] : methods?.providers ?? [];
|
|
1673
1730
|
if (sent) {
|
|
1674
|
-
return /* @__PURE__ */ jsxs("div",
|
|
1731
|
+
return /* @__PURE__ */ jsxs(Wrap, { f, as: "div", slot: "form", root: f.root, children: [
|
|
1675
1732
|
/* @__PURE__ */ jsx(Note, { f, children: f.t.checkEmail }),
|
|
1676
1733
|
props.links?.signIn && /* @__PURE__ */ jsx(A, { f, href: props.links.signIn, children: f.t.backToSignIn })
|
|
1677
1734
|
] });
|
|
1678
1735
|
}
|
|
1736
|
+
if (methods === null) return /* @__PURE__ */ jsx(Wrap, { f, as: "div", slot: "form", root: f.root, busy: true });
|
|
1679
1737
|
const footer = props.links?.signIn && /* @__PURE__ */ jsxs(Note, { f, footer: true, children: [
|
|
1680
1738
|
f.t.haveAccount,
|
|
1681
1739
|
" ",
|
|
1682
1740
|
/* @__PURE__ */ jsx(A, { f, href: props.links.signIn, children: f.t.signIn })
|
|
1683
1741
|
] });
|
|
1684
1742
|
if (!passwordOn) {
|
|
1685
|
-
return /* @__PURE__ */ jsxs("div",
|
|
1743
|
+
return /* @__PURE__ */ jsxs(Wrap, { f, as: "div", slot: "form", root: f.root, children: [
|
|
1686
1744
|
general && /* @__PURE__ */ jsx(Say, { f, tone: "danger", children: f.say(general) }),
|
|
1687
1745
|
/* @__PURE__ */ jsx(ProviderButtons, { f, providers, onPick: (id) => auth.signIn.social(id, { returnTo: props.returnTo }) }),
|
|
1688
1746
|
footer
|
|
1689
1747
|
] });
|
|
1690
1748
|
}
|
|
1691
|
-
return /* @__PURE__ */ jsxs("form",
|
|
1749
|
+
return /* @__PURE__ */ jsxs(Wrap, { f, as: "form", slot: "form", root: f.root, onSubmit: submit, noValidate: true, children: [
|
|
1692
1750
|
general && /* @__PURE__ */ jsx(Say, { f, tone: "danger", children: f.say(general) }),
|
|
1693
1751
|
/* @__PURE__ */ jsx(ProviderButtons, { f, providers, onPick: (id) => auth.signIn.social(id, { returnTo: props.returnTo }) }),
|
|
1694
1752
|
providers.length > 0 && /* @__PURE__ */ jsx(Or, { f, children: f.t.orWithEmail }),
|
|
1695
|
-
methods
|
|
1753
|
+
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 }),
|
|
1696
1754
|
/* @__PURE__ */ jsx(Field, { f, name: "name", type: "text", label: f.t.name, value: name, autoComplete: "name", onChange: setName }),
|
|
1697
1755
|
/* @__PURE__ */ jsx(Field, { f, name: "email", type: "email", label: f.t.email, value: email, autoComplete: "username", required: true, onChange: setEmail }),
|
|
1698
1756
|
/* @__PURE__ */ jsx(Field, { f, name: "password", type: "password", label: f.t.password, value: password, autoComplete: "new-password", required: true, onChange: setPassword, hint: f.passwordRule }),
|
|
@@ -1703,7 +1761,7 @@ function SignUp(props) {
|
|
|
1703
1761
|
] }),
|
|
1704
1762
|
legal?.consentPurposes.map((p) => /* @__PURE__ */ jsx(Check, { f, name: `consent_${p.key}`, checked: consents[p.key] === true, required: p.required, onChange: (on) => setConsents({ ...consents, [p.key]: on }), children: p.label }, p.key)),
|
|
1705
1763
|
challenge.node,
|
|
1706
|
-
/* @__PURE__ */ jsx(f.Button, { type: "submit", disabled: f.busy, className: f.cx("button"), children: f.t.signUp }),
|
|
1764
|
+
/* @__PURE__ */ jsx(f.Button, { type: "submit", variant: "primary", loading: f.loading(), disabled: f.busy, className: f.cx("button"), children: f.t.signUp }),
|
|
1707
1765
|
footer
|
|
1708
1766
|
] });
|
|
1709
1767
|
}
|
|
@@ -1725,16 +1783,16 @@ function ForgotPassword(props) {
|
|
|
1725
1783
|
};
|
|
1726
1784
|
const general = f.error && !f.error.field ? f.error : null;
|
|
1727
1785
|
if (sent) {
|
|
1728
|
-
return /* @__PURE__ */ jsxs("div",
|
|
1786
|
+
return /* @__PURE__ */ jsxs(Wrap, { f, as: "div", slot: "form", root: f.root, children: [
|
|
1729
1787
|
/* @__PURE__ */ jsx(Note, { f, children: f.t.linkSent }),
|
|
1730
1788
|
props.links?.signIn && /* @__PURE__ */ jsx(A, { f, href: props.links.signIn, children: f.t.backToSignIn })
|
|
1731
1789
|
] });
|
|
1732
1790
|
}
|
|
1733
|
-
return /* @__PURE__ */ jsxs("form",
|
|
1791
|
+
return /* @__PURE__ */ jsxs(Wrap, { f, as: "form", slot: "form", root: f.root, onSubmit: submit, noValidate: true, children: [
|
|
1734
1792
|
general && /* @__PURE__ */ jsx(Say, { f, tone: "danger", children: f.say(general) }),
|
|
1735
1793
|
/* @__PURE__ */ jsx(Field, { f, name: "email", type: "email", label: f.t.email, value: email, autoComplete: "username", required: true, onChange: setEmail }),
|
|
1736
1794
|
challenge.node,
|
|
1737
|
-
/* @__PURE__ */ jsx(f.Button, { type: "submit", disabled: f.busy, className: f.cx("button"), children: f.t.sendLink }),
|
|
1795
|
+
/* @__PURE__ */ jsx(f.Button, { type: "submit", variant: "primary", loading: f.loading(), disabled: f.busy, className: f.cx("button"), children: f.t.sendLink }),
|
|
1738
1796
|
props.links?.signIn && /* @__PURE__ */ jsx(Note, { f, footer: true, children: /* @__PURE__ */ jsx(A, { f, href: props.links.signIn, children: f.t.backToSignIn }) })
|
|
1739
1797
|
] });
|
|
1740
1798
|
}
|
|
@@ -1761,21 +1819,21 @@ function ResetPassword(props) {
|
|
|
1761
1819
|
const general = f.error && !f.error.field ? f.error : null;
|
|
1762
1820
|
const back = props.links?.signIn && /* @__PURE__ */ jsx(A, { f, href: props.links.signIn, children: f.t.backToSignIn });
|
|
1763
1821
|
if (changed) {
|
|
1764
|
-
return /* @__PURE__ */ jsxs("div",
|
|
1822
|
+
return /* @__PURE__ */ jsxs(Wrap, { f, as: "div", slot: "form", root: f.root, children: [
|
|
1765
1823
|
/* @__PURE__ */ jsx(Note, { f, children: f.t.passwordChanged }),
|
|
1766
1824
|
back
|
|
1767
1825
|
] });
|
|
1768
1826
|
}
|
|
1769
1827
|
if (token === "") {
|
|
1770
|
-
return /* @__PURE__ */ jsxs("div",
|
|
1828
|
+
return /* @__PURE__ */ jsxs(Wrap, { f, as: "div", slot: "form", root: f.root, children: [
|
|
1771
1829
|
general && /* @__PURE__ */ jsx(Say, { f, tone: "danger", children: f.say(general) }),
|
|
1772
1830
|
props.links?.forgotPassword && /* @__PURE__ */ jsx(A, { f, href: props.links.forgotPassword, children: f.t.forgotPassword })
|
|
1773
1831
|
] });
|
|
1774
1832
|
}
|
|
1775
|
-
return /* @__PURE__ */ jsxs("form",
|
|
1833
|
+
return /* @__PURE__ */ jsxs(Wrap, { f, as: "form", slot: "form", root: f.root, onSubmit: submit, noValidate: true, children: [
|
|
1776
1834
|
general && /* @__PURE__ */ jsx(Say, { f, tone: "danger", children: f.say(general) }),
|
|
1777
1835
|
/* @__PURE__ */ jsx(Field, { f, name: "password", type: "password", label: f.t.newPassword, value: password, autoComplete: "new-password", required: true, onChange: setPassword, hint: f.passwordRule }),
|
|
1778
|
-
/* @__PURE__ */ jsx(f.Button, { type: "submit", disabled: f.busy || token === null, className: f.cx("button"), children: f.t.savePassword })
|
|
1836
|
+
/* @__PURE__ */ jsx(f.Button, { type: "submit", variant: "primary", loading: f.loading(), disabled: f.busy || token === null, className: f.cx("button"), children: f.t.savePassword })
|
|
1779
1837
|
] });
|
|
1780
1838
|
}
|
|
1781
1839
|
function VerifyEmail(props) {
|
|
@@ -1794,7 +1852,7 @@ function VerifyEmail(props) {
|
|
|
1794
1852
|
setState("failed");
|
|
1795
1853
|
});
|
|
1796
1854
|
});
|
|
1797
|
-
return /* @__PURE__ */ jsxs("div",
|
|
1855
|
+
return /* @__PURE__ */ jsxs(Wrap, { f, as: "div", slot: "form", root: f.root, busy: state === "confirming", children: [
|
|
1798
1856
|
state === "confirming" && /* @__PURE__ */ jsx(Note, { f, children: f.t.confirming }),
|
|
1799
1857
|
state === "confirmed" && /* @__PURE__ */ jsx(Note, { f, children: f.t.emailConfirmed }),
|
|
1800
1858
|
state === "failed" && f.error && /* @__PURE__ */ jsx(Say, { f, tone: "danger", children: f.say(f.error) }),
|
|
@@ -1838,10 +1896,10 @@ function AcceptInvite(props) {
|
|
|
1838
1896
|
const general = f.error && !f.error.field ? f.error : null;
|
|
1839
1897
|
const back = props.links?.signIn && /* @__PURE__ */ jsx(A, { f, href: props.links.signIn, children: f.t.backToSignIn });
|
|
1840
1898
|
if (state === "opening") {
|
|
1841
|
-
return /* @__PURE__ */ jsx("div",
|
|
1899
|
+
return /* @__PURE__ */ jsx(Wrap, { f, as: "div", slot: "form", root: f.root, busy: true, children: /* @__PURE__ */ jsx(Note, { f, children: f.t.openingInvitation }) });
|
|
1842
1900
|
}
|
|
1843
1901
|
if (state === "invalid") {
|
|
1844
|
-
return /* @__PURE__ */ jsxs("div",
|
|
1902
|
+
return /* @__PURE__ */ jsxs(Wrap, { f, as: "div", slot: "form", root: f.root, children: [
|
|
1845
1903
|
/* @__PURE__ */ jsx(Say, { f, tone: "danger", children: general ? f.say(general) : f.t.invitationInvalid }),
|
|
1846
1904
|
back
|
|
1847
1905
|
] });
|
|
@@ -1849,13 +1907,13 @@ function AcceptInvite(props) {
|
|
|
1849
1907
|
if (state === "code") return /* @__PURE__ */ jsx(SecondStepForm, { f, auth });
|
|
1850
1908
|
const workspace = invitation?.workspace ?? "";
|
|
1851
1909
|
const heading = invitation?.organization ? f.t.invitedToOrganization.replace("{organization}", invitation.organization).replace("{workspace}", workspace) : f.t.invitedTo.replace("{workspace}", workspace);
|
|
1852
|
-
return /* @__PURE__ */ jsxs("form",
|
|
1910
|
+
return /* @__PURE__ */ jsxs(Wrap, { f, as: "form", slot: "form", root: f.root, onSubmit: submit, noValidate: true, children: [
|
|
1853
1911
|
/* @__PURE__ */ jsx(Heading, { f, children: heading }),
|
|
1854
1912
|
/* @__PURE__ */ jsx(Note, { f, children: f.t.invitedAs.replace("{email}", invitation?.email ?? "") }),
|
|
1855
1913
|
general && /* @__PURE__ */ jsx(Say, { f, tone: "danger", children: f.say(general) }),
|
|
1856
1914
|
/* @__PURE__ */ jsx("input", { type: "email", name: "username", autoComplete: "username", value: invitation?.email ?? "", readOnly: true, hidden: true }),
|
|
1857
1915
|
/* @__PURE__ */ jsx(Field, { f, name: "password", type: "password", label: f.t.choosePassword, value: password, autoComplete: "new-password", required: true, onChange: setPassword, hint: f.passwordRule }),
|
|
1858
|
-
/* @__PURE__ */ jsx(f.Button, { type: "submit", disabled: f.busy, className: f.cx("button"), children: f.t.acceptInvite })
|
|
1916
|
+
/* @__PURE__ */ jsx(f.Button, { type: "submit", variant: "primary", loading: f.loading(), disabled: f.busy, className: f.cx("button"), children: f.t.acceptInvite })
|
|
1859
1917
|
] });
|
|
1860
1918
|
}
|
|
1861
1919
|
function PendingTerms(props) {
|
|
@@ -1875,7 +1933,7 @@ function PendingTerms(props) {
|
|
|
1875
1933
|
setOwed([]);
|
|
1876
1934
|
props.onSuccess?.();
|
|
1877
1935
|
};
|
|
1878
|
-
return /* @__PURE__ */ jsxs("div",
|
|
1936
|
+
return /* @__PURE__ */ jsxs(Wrap, { f, as: "div", slot: "form", root: f.root, children: [
|
|
1879
1937
|
/* @__PURE__ */ jsx(Heading, { f, children: f.t.termsChanged }),
|
|
1880
1938
|
/* @__PURE__ */ jsxs(Note, { f, children: [
|
|
1881
1939
|
f.t.termsChangedHelp,
|
|
@@ -1883,15 +1941,15 @@ function PendingTerms(props) {
|
|
|
1883
1941
|
/* @__PURE__ */ jsx(Documents, { f, documents: owed })
|
|
1884
1942
|
] }),
|
|
1885
1943
|
f.error && /* @__PURE__ */ jsx(Say, { f, tone: "danger", children: f.say(f.error) }),
|
|
1886
|
-
/* @__PURE__ */ jsx(f.Button, { type: "button", disabled: f.busy, className: f.cx("button"), onClick: () => void accept(), children: f.t.acceptTerms })
|
|
1944
|
+
/* @__PURE__ */ jsx(f.Button, { type: "button", variant: "primary", loading: f.loading(), disabled: f.busy, className: f.cx("button"), onClick: () => void accept(), children: f.t.acceptTerms })
|
|
1887
1945
|
] });
|
|
1888
1946
|
}
|
|
1889
1947
|
var ACCOUNT_SECTIONS = ["profile", "email", "password", "linked", "secondStep", "phone", "passkeys", "agents", "sessions"];
|
|
1890
1948
|
function useSection(props) {
|
|
1891
1949
|
const f = useForm({ ...props, unstyled: true });
|
|
1892
1950
|
const [done, setDone] = useState(null);
|
|
1893
|
-
const run = async (action) => {
|
|
1894
|
-
f.setBusy(
|
|
1951
|
+
const run = async (action, key = SUBMIT) => {
|
|
1952
|
+
f.setBusy(key);
|
|
1895
1953
|
f.setError(null);
|
|
1896
1954
|
setDone(null);
|
|
1897
1955
|
const r = await action();
|
|
@@ -1905,13 +1963,12 @@ function useSection(props) {
|
|
|
1905
1963
|
function Account(props) {
|
|
1906
1964
|
const auth = useAuth();
|
|
1907
1965
|
const { accountUrl } = useSession();
|
|
1908
|
-
const
|
|
1909
|
-
const cx = (slot) => props.classNames?.[slot] ?? `cauthy-${slot}`;
|
|
1966
|
+
const f = useForm(props);
|
|
1910
1967
|
const [account, setAccount] = useState(null);
|
|
1911
1968
|
useEffect(() => {
|
|
1912
1969
|
void auth.account.get().then(setAccount);
|
|
1913
1970
|
}, []);
|
|
1914
|
-
if (account === null) return /* @__PURE__ */ jsx("div",
|
|
1971
|
+
if (account === null) return /* @__PURE__ */ jsx(Wrap, { f, as: "div", slot: "account", root: f.root, busy: true });
|
|
1915
1972
|
const when = props.formatDate ?? ((iso) => new Date(iso).toLocaleString());
|
|
1916
1973
|
const mfa = (mfaEnabled) => setAccount({ ...account, mfaEnabled });
|
|
1917
1974
|
const part = (section) => {
|
|
@@ -1936,7 +1993,7 @@ function Account(props) {
|
|
|
1936
1993
|
return /* @__PURE__ */ jsx(SessionsPart, { props, when });
|
|
1937
1994
|
}
|
|
1938
1995
|
};
|
|
1939
|
-
return /* @__PURE__ */ jsx("div",
|
|
1996
|
+
return /* @__PURE__ */ jsx(Wrap, { f, as: "div", slot: "account", root: f.root, children: (props.sections ?? ACCOUNT_SECTIONS).map((section) => /* @__PURE__ */ jsx(Fragment, { children: part(section) }, section)) });
|
|
1940
1997
|
}
|
|
1941
1998
|
function AccountProfile(props) {
|
|
1942
1999
|
return /* @__PURE__ */ jsx(Account, { ...props, sections: ["profile"] });
|
|
@@ -2009,15 +2066,20 @@ function OrganizationMembers(props) {
|
|
|
2009
2066
|
useEffect(() => {
|
|
2010
2067
|
void load();
|
|
2011
2068
|
}, [id]);
|
|
2012
|
-
if (gone !== null) return /* @__PURE__ */ jsx("div",
|
|
2013
|
-
if (seat === void 0) return /* @__PURE__ */ jsx("div",
|
|
2014
|
-
if (seat === null) return /* @__PURE__ */ jsx("div",
|
|
2069
|
+
if (gone !== null) return /* @__PURE__ */ jsx(Wrap, { f, as: "div", slot: "account", root, children: /* @__PURE__ */ jsx(Say, { f, tone: "success", children: gone }) });
|
|
2070
|
+
if (seat === void 0) return /* @__PURE__ */ jsx(Wrap, { f, as: "div", slot: "account", root, busy: true });
|
|
2071
|
+
if (seat === null) return /* @__PURE__ */ jsx(Wrap, { f, as: "div", slot: "account", root, children: /* @__PURE__ */ jsx(Note, { f, children: f.t.organizationMissing }) });
|
|
2015
2072
|
const manage = seat.can.manageMembers;
|
|
2016
2073
|
const giveable = rolesToGive(seat, roles, props.roles);
|
|
2017
|
-
const
|
|
2074
|
+
const roleName = (c) => props.roleLabel?.(c) || c.name || c.role;
|
|
2075
|
+
const label = (r) => {
|
|
2076
|
+
const c = roles.find((x) => x.role === r);
|
|
2077
|
+
return c ? roleName(c) : r;
|
|
2078
|
+
};
|
|
2018
2079
|
const add = async (e) => {
|
|
2019
2080
|
e.preventDefault();
|
|
2020
|
-
|
|
2081
|
+
if (!f.check(checkEmail(email))) return;
|
|
2082
|
+
const r = await run(() => auth.organizations.add(id, { email, role, locale: props.locale }), "add");
|
|
2021
2083
|
if (!r.ok) return;
|
|
2022
2084
|
setEmail("");
|
|
2023
2085
|
setDone(f.t.memberAdded.replace("{email}", r.member.email));
|
|
@@ -2025,28 +2087,28 @@ function OrganizationMembers(props) {
|
|
|
2025
2087
|
await load();
|
|
2026
2088
|
};
|
|
2027
2089
|
const change = async (m, next) => {
|
|
2028
|
-
const r = await run(() => auth.organizations.setRole(id, m.userId, next));
|
|
2090
|
+
const r = await run(() => auth.organizations.setRole(id, m.userId, next), `role:${m.userId}`);
|
|
2029
2091
|
if (!r.ok) return;
|
|
2030
2092
|
saved({ kind: "member.role_changed", organizationId: id, userId: m.userId, role: next, previousRole: m.role });
|
|
2031
2093
|
await load();
|
|
2032
2094
|
};
|
|
2033
2095
|
const remove = async (m) => {
|
|
2034
2096
|
setAsking(null);
|
|
2035
|
-
const r = await run(() => auth.organizations.remove(id, m.userId));
|
|
2097
|
+
const r = await run(() => auth.organizations.remove(id, m.userId), `remove:${m.userId}`);
|
|
2036
2098
|
if (!r.ok) return;
|
|
2037
2099
|
saved({ kind: m.you ? "member.left" : "member.removed", organizationId: id, userId: m.userId });
|
|
2038
2100
|
if (m.you) setSeat(null);
|
|
2039
2101
|
else await load();
|
|
2040
2102
|
};
|
|
2041
2103
|
const inviteAgain = async (m) => {
|
|
2042
|
-
const r = await run(() => auth.organizations.inviteAgain(id, m.userId, { locale: props.locale }));
|
|
2104
|
+
const r = await run(() => auth.organizations.inviteAgain(id, m.userId, { locale: props.locale }), `invite:${m.userId}`);
|
|
2043
2105
|
if (!r.ok) return;
|
|
2044
2106
|
setDone(f.t.memberInvitationSent);
|
|
2045
2107
|
saved({ kind: "member.invited_again", organizationId: id, userId: m.userId });
|
|
2046
2108
|
};
|
|
2047
2109
|
const rename = async (e) => {
|
|
2048
2110
|
e.preventDefault();
|
|
2049
|
-
const r = await run(() => auth.organizations.rename(id, name));
|
|
2111
|
+
const r = await run(() => auth.organizations.rename(id, name), "rename");
|
|
2050
2112
|
if (!r.ok) return;
|
|
2051
2113
|
setSeat(r.organization);
|
|
2052
2114
|
setName(r.organization.name);
|
|
@@ -2055,7 +2117,7 @@ function OrganizationMembers(props) {
|
|
|
2055
2117
|
};
|
|
2056
2118
|
const close = async (how) => {
|
|
2057
2119
|
setAsking(null);
|
|
2058
|
-
const r = await run(() => how === "archive" ? auth.organizations.archive(id) : auth.organizations.delete(id));
|
|
2120
|
+
const r = await run(() => how === "archive" ? auth.organizations.archive(id) : auth.organizations.delete(id), how);
|
|
2059
2121
|
if (!r.ok) return;
|
|
2060
2122
|
setGone((how === "archive" ? f.t.organizationArchived : f.t.organizationDeleted).replace("{org}", seat.name));
|
|
2061
2123
|
saved({ kind: how === "archive" ? "organization.archived" : "organization.deleted", organizationId: id });
|
|
@@ -2070,8 +2132,8 @@ function OrganizationMembers(props) {
|
|
|
2070
2132
|
const confirming = (text2, label2, yes) => /* @__PURE__ */ jsxs("span", { role: "group", "aria-label": label2, children: [
|
|
2071
2133
|
/* @__PURE__ */ jsx("span", { children: text2 }),
|
|
2072
2134
|
" ",
|
|
2073
|
-
/* @__PURE__ */ jsx(f.Button, { type: "button", disabled: f.busy, className: f.cx("providerButton"), onClick: yes, children: f.t.yes }),
|
|
2074
|
-
/* @__PURE__ */ jsx(f.Button, { type: "button", disabled: f.busy, className: f.cx("providerButton"), onClick: () => setAsking(null), children: f.t.cancel })
|
|
2135
|
+
/* @__PURE__ */ jsx(f.Button, { type: "button", variant: "danger", disabled: f.busy, className: f.cx("providerButton"), onClick: yes, children: f.t.yes }),
|
|
2136
|
+
/* @__PURE__ */ jsx(f.Button, { type: "button", variant: "secondary", disabled: f.busy, className: f.cx("providerButton"), onClick: () => setAsking(null), children: f.t.cancel })
|
|
2075
2137
|
] });
|
|
2076
2138
|
const leaveQuestion = f.t.memberLeaveConfirm.replace("{org}", seat.name);
|
|
2077
2139
|
const archiveQuestion = f.t.organizationArchiveConfirm.replace("{org}", seat.name);
|
|
@@ -2079,8 +2141,8 @@ function OrganizationMembers(props) {
|
|
|
2079
2141
|
const archiving = seat.can.archive && !hidden("archive");
|
|
2080
2142
|
const deleting = seat.can.delete && !hidden("delete");
|
|
2081
2143
|
const renaming = seat.can.update && !hidden("rename");
|
|
2082
|
-
return /* @__PURE__ */ jsxs("div",
|
|
2083
|
-
/* @__PURE__ */ jsxs("section",
|
|
2144
|
+
return /* @__PURE__ */ jsxs(Wrap, { f, as: "div", slot: "account", root, children: [
|
|
2145
|
+
/* @__PURE__ */ jsxs(Wrap, { f, as: "section", slot: "section", section: "members", children: [
|
|
2084
2146
|
/* @__PURE__ */ jsxs(Heading, { f, children: [
|
|
2085
2147
|
f.t.members,
|
|
2086
2148
|
" \xB7 ",
|
|
@@ -2093,6 +2155,8 @@ function OrganizationMembers(props) {
|
|
|
2093
2155
|
f.Button,
|
|
2094
2156
|
{
|
|
2095
2157
|
type: "button",
|
|
2158
|
+
variant: "danger",
|
|
2159
|
+
loading: f.loading(`remove:${auth.session.user.id}`),
|
|
2096
2160
|
disabled: f.busy,
|
|
2097
2161
|
className: f.cx("providerButton"),
|
|
2098
2162
|
onClick: () => ask(auth.session.user.id, f.t.memberLeave, leaveQuestion, () => void remove({ userId: auth.session.user.id, you: true })),
|
|
@@ -2127,34 +2191,34 @@ function OrganizationMembers(props) {
|
|
|
2127
2191
|
label: `${f.t.memberRole}: ${who}`,
|
|
2128
2192
|
value: m.role,
|
|
2129
2193
|
disabled: f.busy,
|
|
2130
|
-
options: choices.map((c) => ({ value: c.role, label: c
|
|
2194
|
+
options: choices.map((c) => ({ value: c.role, label: roleName(c) })),
|
|
2131
2195
|
onChange: (next) => void change(m, next)
|
|
2132
2196
|
}
|
|
2133
2197
|
) : f.C.Badge ? /* @__PURE__ */ jsx(f.C.Badge, { tone: "neutral", children: label(m.role) }) : /* @__PURE__ */ jsx("span", { children: label(m.role) }),
|
|
2134
2198
|
" ",
|
|
2135
2199
|
asking === m.userId ? confirming(question, action, () => void remove(m)) : /* @__PURE__ */ jsxs(Fragment2, { children: [
|
|
2136
|
-
may.inviteAgain && /* @__PURE__ */ jsx(f.Button, { type: "button", disabled: f.busy, className: f.cx("providerButton"), onClick: () => void inviteAgain(m), children: f.t.memberInviteAgain }),
|
|
2137
|
-
removable && /* @__PURE__ */ jsx(f.Button, { type: "button", disabled: f.busy, className: f.cx("providerButton"), onClick: () => ask(m.userId, action, question, () => void remove(m)), children: action })
|
|
2200
|
+
may.inviteAgain && /* @__PURE__ */ jsx(f.Button, { type: "button", variant: "secondary", loading: f.loading(`invite:${m.userId}`), disabled: f.busy, className: f.cx("providerButton"), onClick: () => void inviteAgain(m), children: f.t.memberInviteAgain }),
|
|
2201
|
+
removable && /* @__PURE__ */ jsx(f.Button, { type: "button", variant: "danger", loading: f.loading(`remove:${m.userId}`), disabled: f.busy, className: f.cx("providerButton"), onClick: () => ask(m.userId, action, question, () => void remove(m)), children: action })
|
|
2138
2202
|
] })
|
|
2139
2203
|
] }, m.userId);
|
|
2140
2204
|
}) }),
|
|
2141
2205
|
done && /* @__PURE__ */ jsx(Say, { f, tone: "success", children: done })
|
|
2142
2206
|
] }),
|
|
2143
|
-
manage && giveable.length > 0 && /* @__PURE__ */ jsxs("form",
|
|
2207
|
+
manage && giveable.length > 0 && /* @__PURE__ */ jsxs(Wrap, { f, as: "form", slot: "section", section: "add-member", onSubmit: add, noValidate: true, children: [
|
|
2144
2208
|
/* @__PURE__ */ jsx(Heading, { f, children: f.t.memberAdd }),
|
|
2145
2209
|
/* @__PURE__ */ jsx(Field, { f, name: "email", type: "email", label: f.t.email, value: email, autoComplete: "off", required: true, onChange: setEmail }),
|
|
2146
|
-
/* @__PURE__ */ jsx(AddRole, { f, value: role, options: giveable.map((c) => ({ value: c.role, label: c
|
|
2147
|
-
/* @__PURE__ */ jsx(f.Button, { type: "submit", disabled: f.busy, className: f.cx("button"), children: f.t.memberAdd })
|
|
2210
|
+
/* @__PURE__ */ jsx(AddRole, { f, value: role, options: giveable.map((c) => ({ value: c.role, label: roleName(c) })), onChange: setRole }),
|
|
2211
|
+
/* @__PURE__ */ jsx(f.Button, { type: "submit", variant: "primary", loading: f.loading("add"), disabled: f.busy, className: f.cx("button"), children: f.t.memberAdd })
|
|
2148
2212
|
] }),
|
|
2149
|
-
(renaming || archiving || deleting) && /* @__PURE__ */ jsxs("section",
|
|
2213
|
+
(renaming || archiving || deleting) && /* @__PURE__ */ jsxs(Wrap, { f, as: "section", slot: "section", section: "organization", children: [
|
|
2150
2214
|
/* @__PURE__ */ jsx(Heading, { f, children: f.t.organization }),
|
|
2151
|
-
renaming && /* @__PURE__ */ jsxs("form",
|
|
2215
|
+
renaming && /* @__PURE__ */ jsxs(Wrap, { f, as: "form", section: "rename", onSubmit: rename, noValidate: true, children: [
|
|
2152
2216
|
/* @__PURE__ */ jsx(Field, { f, name: "name", type: "text", label: f.t.name, value: name, autoComplete: "organization", required: true, onChange: setName }),
|
|
2153
|
-
/* @__PURE__ */ jsx(f.Button, { type: "submit", disabled: f.busy, className: f.cx("button"), children: f.t.organizationRename })
|
|
2217
|
+
/* @__PURE__ */ jsx(f.Button, { type: "submit", variant: "primary", loading: f.loading("rename"), disabled: f.busy, className: f.cx("button"), children: f.t.organizationRename })
|
|
2154
2218
|
] }),
|
|
2155
2219
|
asking === "archive" ? confirming(archiveQuestion, f.t.organizationArchive, () => void close("archive")) : asking === "delete" ? confirming(deleteQuestion, f.t.organizationDelete, () => void close("delete")) : /* @__PURE__ */ jsxs(Fragment2, { children: [
|
|
2156
|
-
archiving && /* @__PURE__ */ jsx(f.Button, { type: "button", disabled: f.busy, className: f.cx("providerButton"), onClick: () => ask("archive", f.t.organizationArchive, archiveQuestion, () => void close("archive")), children: f.t.organizationArchive }),
|
|
2157
|
-
deleting && /* @__PURE__ */ jsx(f.Button, { type: "button", disabled: f.busy, className: f.cx("providerButton"), onClick: () => ask("delete", f.t.organizationDelete, deleteQuestion, () => void close("delete")), children: f.t.organizationDelete })
|
|
2220
|
+
archiving && /* @__PURE__ */ jsx(f.Button, { type: "button", variant: "danger", loading: f.loading("archive"), disabled: f.busy, className: f.cx("providerButton"), onClick: () => ask("archive", f.t.organizationArchive, archiveQuestion, () => void close("archive")), children: f.t.organizationArchive }),
|
|
2221
|
+
deleting && /* @__PURE__ */ jsx(f.Button, { type: "button", variant: "danger", loading: f.loading("delete"), disabled: f.busy, className: f.cx("providerButton"), onClick: () => ask("delete", f.t.organizationDelete, deleteQuestion, () => void close("delete")), children: f.t.organizationDelete })
|
|
2158
2222
|
] })
|
|
2159
2223
|
] })
|
|
2160
2224
|
] });
|
|
@@ -2179,14 +2243,15 @@ function PasskeysPart({ props, account, accountUrl, when }) {
|
|
|
2179
2243
|
}, []);
|
|
2180
2244
|
if (here === null) return null;
|
|
2181
2245
|
if (!here) {
|
|
2182
|
-
return /* @__PURE__ */ jsxs("section",
|
|
2246
|
+
return /* @__PURE__ */ jsxs(Wrap, { f, as: "section", slot: "section", section: "passkeys", children: [
|
|
2183
2247
|
/* @__PURE__ */ jsx(Heading, { f, children: f.t.passkeys }),
|
|
2184
2248
|
/* @__PURE__ */ jsx(A, { f, href: accountUrl, children: f.t.managePasskeys })
|
|
2185
2249
|
] });
|
|
2186
2250
|
}
|
|
2187
2251
|
const add = async (e, kind = "device") => {
|
|
2188
2252
|
e?.preventDefault();
|
|
2189
|
-
|
|
2253
|
+
if (account.hasPassword && !f.check(checkPassword(password))) return;
|
|
2254
|
+
const r = await run(() => auth.account.addPasskey({ name, password, kind }), kind === "security_key" ? "security_key" : SUBMIT);
|
|
2190
2255
|
if (!r.ok) {
|
|
2191
2256
|
if (r.error.code === "cancelled") f.setError(null);
|
|
2192
2257
|
return;
|
|
@@ -2198,12 +2263,12 @@ function PasskeysPart({ props, account, accountUrl, when }) {
|
|
|
2198
2263
|
props.onSaved?.({ kind: "passkey.added", id: r.passkey.id });
|
|
2199
2264
|
};
|
|
2200
2265
|
const remove = async (id) => {
|
|
2201
|
-
const r = await run(() => auth.account.removePasskey(id));
|
|
2266
|
+
const r = await run(() => auth.account.removePasskey(id), `remove:${id}`);
|
|
2202
2267
|
if (!r.ok) return;
|
|
2203
2268
|
setList(list.filter((p) => p.id !== id));
|
|
2204
2269
|
props.onSaved?.({ kind: "passkey.removed", id });
|
|
2205
2270
|
};
|
|
2206
|
-
return /* @__PURE__ */ jsxs("form",
|
|
2271
|
+
return /* @__PURE__ */ jsxs(Wrap, { f, as: "form", slot: "section", section: "passkeys", onSubmit: add, noValidate: true, children: [
|
|
2207
2272
|
/* @__PURE__ */ jsx(Heading, { f, children: f.t.passkeys }),
|
|
2208
2273
|
/* @__PURE__ */ jsx(Note, { f, children: f.t.passkeysHelp }),
|
|
2209
2274
|
general && /* @__PURE__ */ jsx(Say, { f, tone: "danger", children: f.say(general) }),
|
|
@@ -2213,12 +2278,12 @@ function PasskeysPart({ props, account, accountUrl, when }) {
|
|
|
2213
2278
|
" \xB7 ",
|
|
2214
2279
|
when(p.createdAt),
|
|
2215
2280
|
" ",
|
|
2216
|
-
/* @__PURE__ */ jsx(f.Button, { type: "button", disabled: f.busy, className: f.cx("providerButton"), onClick: () => void remove(p.id), children: f.t.removePasskey })
|
|
2281
|
+
/* @__PURE__ */ jsx(f.Button, { type: "button", variant: "danger", loading: f.loading(`remove:${p.id}`), disabled: f.busy, className: f.cx("providerButton"), onClick: () => void remove(p.id), children: f.t.removePasskey })
|
|
2217
2282
|
] }, p.id)) }),
|
|
2218
2283
|
/* @__PURE__ */ jsx(Field, { f, name: "name", type: "text", label: f.t.passkeyName, value: name, autoComplete: "off", onChange: setName }),
|
|
2219
2284
|
account.hasPassword && /* @__PURE__ */ jsx(Field, { f, name: "password", type: "password", label: f.t.currentPassword, value: password, autoComplete: "current-password", required: true, onChange: setPassword }),
|
|
2220
|
-
/* @__PURE__ */ jsx(f.Button, { type: "submit", disabled: f.busy, className: f.cx("button"), children: f.t.addPasskeyDevice }),
|
|
2221
|
-
/* @__PURE__ */ jsx(f.Button, { type: "button", disabled: f.busy, className: f.cx("providerButton"), onClick: () => void add(null, "security_key"), children: f.t.addSecurityKey }),
|
|
2285
|
+
/* @__PURE__ */ jsx(f.Button, { type: "submit", variant: "primary", loading: f.loading(), disabled: f.busy, className: f.cx("button"), children: f.t.addPasskeyDevice }),
|
|
2286
|
+
/* @__PURE__ */ jsx(f.Button, { type: "button", variant: "secondary", loading: f.loading("security_key"), disabled: f.busy, className: f.cx("providerButton"), onClick: () => void add(null, "security_key"), children: f.t.addSecurityKey }),
|
|
2222
2287
|
done && /* @__PURE__ */ jsx(Say, { f, tone: "success", children: done })
|
|
2223
2288
|
] });
|
|
2224
2289
|
}
|
|
@@ -2234,12 +2299,12 @@ function ProfilePart({ props, account, onSaved }) {
|
|
|
2234
2299
|
setDone(f.t.saved);
|
|
2235
2300
|
props.onSaved?.({ kind: "profile.saved", name: r.account.name });
|
|
2236
2301
|
};
|
|
2237
|
-
return /* @__PURE__ */ jsxs("form",
|
|
2302
|
+
return /* @__PURE__ */ jsxs(Wrap, { f, as: "form", slot: "section", section: "profile", onSubmit: submit, noValidate: true, children: [
|
|
2238
2303
|
/* @__PURE__ */ jsx(Heading, { f, children: f.t.profile }),
|
|
2239
2304
|
/* @__PURE__ */ jsx(Note, { f, children: account.email }),
|
|
2240
2305
|
general && /* @__PURE__ */ jsx(Say, { f, tone: "danger", children: f.say(general) }),
|
|
2241
2306
|
/* @__PURE__ */ jsx(Field, { f, name: "name", type: "text", label: f.t.name, value: name, autoComplete: "name", onChange: setName }),
|
|
2242
|
-
/* @__PURE__ */ jsx(f.Button, { type: "submit", disabled: f.busy, className: f.cx("button"), children: f.t.save }),
|
|
2307
|
+
/* @__PURE__ */ jsx(f.Button, { type: "submit", variant: "primary", loading: f.loading(), disabled: f.busy, className: f.cx("button"), children: f.t.save }),
|
|
2243
2308
|
done && /* @__PURE__ */ jsx(Say, { f, tone: "success", children: done })
|
|
2244
2309
|
] });
|
|
2245
2310
|
}
|
|
@@ -2250,19 +2315,20 @@ function EmailPart({ props, account }) {
|
|
|
2250
2315
|
const [password, setPassword] = useState("");
|
|
2251
2316
|
const submit = async (e) => {
|
|
2252
2317
|
e.preventDefault();
|
|
2318
|
+
if (!f.check(checkEmail(email), account.hasPassword && checkPassword(password))) return;
|
|
2253
2319
|
const r = await run(() => auth.account.changeEmail({ email, password }));
|
|
2254
2320
|
if (!r.ok) return;
|
|
2255
2321
|
setPassword("");
|
|
2256
2322
|
setDone(f.t.emailSent.replace("{email}", r.email));
|
|
2257
2323
|
props.onSaved?.({ kind: "email.change_requested", email: r.email });
|
|
2258
2324
|
};
|
|
2259
|
-
return /* @__PURE__ */ jsxs("form",
|
|
2325
|
+
return /* @__PURE__ */ jsxs(Wrap, { f, as: "form", slot: "section", section: "email", onSubmit: submit, noValidate: true, children: [
|
|
2260
2326
|
/* @__PURE__ */ jsx(Heading, { f, children: f.t.emailAddress }),
|
|
2261
2327
|
/* @__PURE__ */ jsx(Note, { f, children: account.email }),
|
|
2262
2328
|
general && /* @__PURE__ */ jsx(Say, { f, tone: "danger", children: f.say(general) }),
|
|
2263
2329
|
/* @__PURE__ */ jsx(Field, { f, name: "email", type: "email", label: f.t.newEmail, value: email, autoComplete: "email", required: true, onChange: setEmail }),
|
|
2264
2330
|
account.hasPassword && /* @__PURE__ */ jsx(Field, { f, name: "password", type: "password", label: f.t.currentPassword, value: password, autoComplete: "current-password", required: true, onChange: setPassword }),
|
|
2265
|
-
/* @__PURE__ */ jsx(f.Button, { type: "submit", disabled: f.busy, className: f.cx("button"), children: f.t.changeEmail }),
|
|
2331
|
+
/* @__PURE__ */ jsx(f.Button, { type: "submit", variant: "primary", loading: f.loading(), disabled: f.busy, className: f.cx("button"), children: f.t.changeEmail }),
|
|
2266
2332
|
done && /* @__PURE__ */ jsx(Say, { f, tone: "success", children: done })
|
|
2267
2333
|
] });
|
|
2268
2334
|
}
|
|
@@ -2285,13 +2351,13 @@ function LinkedPart({ props }) {
|
|
|
2285
2351
|
if (linked === null) return null;
|
|
2286
2352
|
const name = (id) => offered.find((p) => p.id === id)?.name ?? id;
|
|
2287
2353
|
const unlink = async (provider) => {
|
|
2288
|
-
const r = await run(() => auth.account.unlink(provider));
|
|
2354
|
+
const r = await run(() => auth.account.unlink(provider), `unlink:${provider}`);
|
|
2289
2355
|
if (!r.ok) return;
|
|
2290
2356
|
setLinked(linked.filter((x) => x.provider !== provider));
|
|
2291
2357
|
props.onSaved?.({ kind: "identity.unlinked", provider });
|
|
2292
2358
|
};
|
|
2293
2359
|
const here = typeof window === "undefined" ? void 0 : window.location.pathname;
|
|
2294
|
-
return /* @__PURE__ */ jsxs("section",
|
|
2360
|
+
return /* @__PURE__ */ jsxs(Wrap, { f, as: "section", slot: "section", section: "linked", children: [
|
|
2295
2361
|
/* @__PURE__ */ jsx(Heading, { f, children: f.t.linkedAccounts }),
|
|
2296
2362
|
came && /* @__PURE__ */ jsx(Say, { f, tone: "success", children: f.t.linked }),
|
|
2297
2363
|
general && /* @__PURE__ */ jsx(Say, { f, tone: "danger", children: f.say(general) }),
|
|
@@ -2299,9 +2365,9 @@ function LinkedPart({ props }) {
|
|
|
2299
2365
|
name(x.provider),
|
|
2300
2366
|
x.email ? ` \xB7 ${x.email}` : "",
|
|
2301
2367
|
" ",
|
|
2302
|
-
/* @__PURE__ */ jsx(f.Button, { type: "button", disabled: f.busy, className: f.cx("providerButton"), onClick: () => void unlink(x.provider), children: f.t.unlink })
|
|
2368
|
+
/* @__PURE__ */ jsx(f.Button, { type: "button", variant: "danger", loading: f.loading(`unlink:${x.provider}`), disabled: f.busy, className: f.cx("providerButton"), onClick: () => void unlink(x.provider), children: f.t.unlink })
|
|
2303
2369
|
] }, x.provider)) }),
|
|
2304
|
-
offered.filter((p) => !linked.some((x) => x.provider === p.id)).map((p) => /* @__PURE__ */ jsxs(f.Button, { type: "button", className: f.cx("providerButton"), onClick: () => auth.account.link(p.id, { returnTo: here }), children: [
|
|
2370
|
+
offered.filter((p) => !linked.some((x) => x.provider === p.id)).map((p) => /* @__PURE__ */ jsxs(f.Button, { type: "button", variant: "secondary", className: f.cx("providerButton"), onClick: () => auth.account.link(p.id, { returnTo: here }), children: [
|
|
2305
2371
|
f.t.linkWith,
|
|
2306
2372
|
" ",
|
|
2307
2373
|
p.name
|
|
@@ -2316,6 +2382,7 @@ function PasswordPart({ props }) {
|
|
|
2316
2382
|
usePasswordPolicy(f, useMethods(auth));
|
|
2317
2383
|
const submit = async (e) => {
|
|
2318
2384
|
e.preventDefault();
|
|
2385
|
+
if (!f.check(checkPassword(password), newPasswordProblem(newPassword, f.policy, "newPassword"))) return;
|
|
2319
2386
|
const r = await run(() => auth.account.changePassword({ password, newPassword }));
|
|
2320
2387
|
if (!r.ok) return;
|
|
2321
2388
|
setPassword("");
|
|
@@ -2323,12 +2390,12 @@ function PasswordPart({ props }) {
|
|
|
2323
2390
|
setDone(f.t.passwordChangedHere);
|
|
2324
2391
|
props.onSaved?.({ kind: "password.changed" });
|
|
2325
2392
|
};
|
|
2326
|
-
return /* @__PURE__ */ jsxs("form",
|
|
2393
|
+
return /* @__PURE__ */ jsxs(Wrap, { f, as: "form", slot: "section", section: "password", onSubmit: submit, noValidate: true, children: [
|
|
2327
2394
|
/* @__PURE__ */ jsx(Heading, { f, children: f.t.changePassword }),
|
|
2328
2395
|
general && /* @__PURE__ */ jsx(Say, { f, tone: "danger", children: f.say(general) }),
|
|
2329
2396
|
/* @__PURE__ */ jsx(Field, { f, name: "password", type: "password", label: f.t.currentPassword, value: password, autoComplete: "current-password", required: true, onChange: setPassword }),
|
|
2330
2397
|
/* @__PURE__ */ jsx(Field, { f, name: "newPassword", type: "password", label: f.t.newPassword, value: newPassword, autoComplete: "new-password", required: true, onChange: setNewPassword, hint: f.passwordRule }),
|
|
2331
|
-
/* @__PURE__ */ jsx(f.Button, { type: "submit", disabled: f.busy, className: f.cx("button"), children: f.t.changePassword }),
|
|
2398
|
+
/* @__PURE__ */ jsx(f.Button, { type: "submit", variant: "primary", loading: f.loading(), disabled: f.busy, className: f.cx("button"), children: f.t.changePassword }),
|
|
2332
2399
|
done && /* @__PURE__ */ jsx(Say, { f, tone: "success", children: done })
|
|
2333
2400
|
] });
|
|
2334
2401
|
}
|
|
@@ -2365,7 +2432,7 @@ function SecondStepPart({ props, account, onChanged }) {
|
|
|
2365
2432
|
props.onSaved?.({ kind: "mfa.disabled" });
|
|
2366
2433
|
};
|
|
2367
2434
|
const renew = async () => {
|
|
2368
|
-
const r = await run(() => auth.account.mfa.recoveryCodes({ password }));
|
|
2435
|
+
const r = await run(() => auth.account.mfa.recoveryCodes({ password }), "codes");
|
|
2369
2436
|
if (!r.ok) return;
|
|
2370
2437
|
setCodes(r.recoveryCodes);
|
|
2371
2438
|
props.onSaved?.({ kind: "recovery_codes.regenerated" });
|
|
@@ -2376,24 +2443,24 @@ function SecondStepPart({ props, account, onChanged }) {
|
|
|
2376
2443
|
/* @__PURE__ */ jsx("ul", { className: f.cx("codes"), children: codes.map((c) => /* @__PURE__ */ jsx("li", { children: /* @__PURE__ */ jsx("code", { children: c }) }, c)) })
|
|
2377
2444
|
] });
|
|
2378
2445
|
if (setup) {
|
|
2379
|
-
return /* @__PURE__ */ jsxs("form",
|
|
2446
|
+
return /* @__PURE__ */ jsxs(Wrap, { f, as: "form", slot: "section", section: "secondStep", onSubmit: confirm, noValidate: true, children: [
|
|
2380
2447
|
/* @__PURE__ */ jsx(Heading, { f, children: f.t.secondStep }),
|
|
2381
2448
|
/* @__PURE__ */ jsx(Note, { f, children: f.t.addToApp }),
|
|
2382
2449
|
/* @__PURE__ */ jsx("code", { className: f.cx("secret"), children: setup.secret }),
|
|
2383
2450
|
/* @__PURE__ */ jsx(A, { f, href: setup.otpauthUri, children: f.t.openInApp }),
|
|
2384
2451
|
general && /* @__PURE__ */ jsx(Say, { f, tone: "danger", children: f.say(general) }),
|
|
2385
2452
|
/* @__PURE__ */ jsx(Field, { f, name: "code", type: "text", label: f.t.code, value: code, autoComplete: "one-time-code", required: true, onChange: setCode }),
|
|
2386
|
-
/* @__PURE__ */ jsx(f.Button, { type: "submit", disabled: f.busy, className: f.cx("button"), children: f.t.verify })
|
|
2453
|
+
/* @__PURE__ */ jsx(f.Button, { type: "submit", variant: "primary", loading: f.loading(), disabled: f.busy, className: f.cx("button"), children: f.t.verify })
|
|
2387
2454
|
] });
|
|
2388
2455
|
}
|
|
2389
|
-
return /* @__PURE__ */ jsxs("form",
|
|
2456
|
+
return /* @__PURE__ */ jsxs(Wrap, { f, as: "form", slot: "section", section: "secondStep", onSubmit: account.mfaEnabled ? turnOff : start, noValidate: true, children: [
|
|
2390
2457
|
/* @__PURE__ */ jsx(Heading, { f, children: f.t.secondStep }),
|
|
2391
2458
|
/* @__PURE__ */ jsx(Note, { f, children: account.mfaEnabled ? f.t.secondStepOn : f.t.secondStepOff }),
|
|
2392
2459
|
shown,
|
|
2393
2460
|
general && /* @__PURE__ */ jsx(Say, { f, tone: "danger", children: f.say(general) }),
|
|
2394
2461
|
passwordField,
|
|
2395
|
-
/* @__PURE__ */ jsx(f.Button, { type: "submit", disabled: f.busy, className: f.cx("button"), children: account.mfaEnabled ? f.t.turnOff : f.t.turnOn }),
|
|
2396
|
-
account.mfaEnabled && /* @__PURE__ */ jsx(f.Button, { type: "button", disabled: f.busy, className: f.cx("providerButton"), onClick: () => void renew(), children: f.t.newRecoveryCodes })
|
|
2462
|
+
/* @__PURE__ */ jsx(f.Button, { type: "submit", variant: account.mfaEnabled ? "danger" : "primary", loading: f.loading(), disabled: f.busy, className: f.cx("button"), children: account.mfaEnabled ? f.t.turnOff : f.t.turnOn }),
|
|
2463
|
+
account.mfaEnabled && /* @__PURE__ */ jsx(f.Button, { type: "button", variant: "secondary", loading: f.loading("codes"), disabled: f.busy, className: f.cx("providerButton"), onClick: () => void renew(), children: f.t.newRecoveryCodes })
|
|
2397
2464
|
] });
|
|
2398
2465
|
}
|
|
2399
2466
|
function PhonePart({ props, account, onChanged }) {
|
|
@@ -2443,15 +2510,15 @@ function PhonePart({ props, account, onChanged }) {
|
|
|
2443
2510
|
};
|
|
2444
2511
|
const passwordField = account.hasPassword && /* @__PURE__ */ jsx(Field, { f, name: "password", type: "password", label: f.t.currentPassword, value: password, autoComplete: "current-password", required: true, onChange: setPassword });
|
|
2445
2512
|
if (sentTo) {
|
|
2446
|
-
return /* @__PURE__ */ jsxs("form",
|
|
2513
|
+
return /* @__PURE__ */ jsxs(Wrap, { f, as: "form", slot: "section", section: "phone", onSubmit: confirm, noValidate: true, children: [
|
|
2447
2514
|
/* @__PURE__ */ jsx(Heading, { f, children: f.t.phone }),
|
|
2448
2515
|
/* @__PURE__ */ jsx(Note, { f, children: f.t.codeSent.replace("{to}", sentTo) }),
|
|
2449
2516
|
general && /* @__PURE__ */ jsx(Say, { f, tone: "danger", children: f.say(general) }),
|
|
2450
2517
|
/* @__PURE__ */ jsx(Field, { f, name: "code", type: "text", label: f.t.code, value: code, autoComplete: "one-time-code", required: true, onChange: setCode }),
|
|
2451
|
-
/* @__PURE__ */ jsx(f.Button, { type: "submit", disabled: f.busy, className: f.cx("button"), children: f.t.verify })
|
|
2518
|
+
/* @__PURE__ */ jsx(f.Button, { type: "submit", variant: "primary", loading: f.loading(), disabled: f.busy, className: f.cx("button"), children: f.t.verify })
|
|
2452
2519
|
] });
|
|
2453
2520
|
}
|
|
2454
|
-
return /* @__PURE__ */ jsxs("form",
|
|
2521
|
+
return /* @__PURE__ */ jsxs(Wrap, { f, as: "form", slot: "section", section: "phone", onSubmit: ways.phone ? remove : add, noValidate: true, children: [
|
|
2455
2522
|
/* @__PURE__ */ jsx(Heading, { f, children: f.t.phone }),
|
|
2456
2523
|
/* @__PURE__ */ jsx(Note, { f, children: ways.phone ? f.t.phoneOn.replace("{to}", ways.phone.number) : `${f.t.phoneOff} ${f.t.phoneHelp}` }),
|
|
2457
2524
|
codes && /* @__PURE__ */ jsxs(Fragment2, { children: [
|
|
@@ -2467,7 +2534,7 @@ function PhonePart({ props, account, onChanged }) {
|
|
|
2467
2534
|
c === "whatsapp" ? f.t.byWhatsapp : f.t.bySms
|
|
2468
2535
|
] }, c)) }),
|
|
2469
2536
|
passwordField,
|
|
2470
|
-
/* @__PURE__ */ jsx(f.Button, { type: "submit", disabled: f.busy, className: f.cx("button"), children: ways.phone ? f.t.removePhone : f.t.addPhone })
|
|
2537
|
+
/* @__PURE__ */ jsx(f.Button, { type: "submit", variant: ways.phone ? "danger" : "primary", loading: f.loading(), disabled: f.busy, className: f.cx("button"), children: ways.phone ? f.t.removePhone : f.t.addPhone })
|
|
2471
2538
|
] });
|
|
2472
2539
|
}
|
|
2473
2540
|
function AgentsPart({ props, when }) {
|
|
@@ -2479,12 +2546,12 @@ function AgentsPart({ props, when }) {
|
|
|
2479
2546
|
}, []);
|
|
2480
2547
|
if (list.length === 0) return null;
|
|
2481
2548
|
const disconnect = async (id) => {
|
|
2482
|
-
const r = await run(() => auth.account.disconnectAgent(id));
|
|
2549
|
+
const r = await run(() => auth.account.disconnectAgent(id), `disconnect:${id}`);
|
|
2483
2550
|
if (!r.ok) return;
|
|
2484
2551
|
setList(list.filter((a) => a.id !== id));
|
|
2485
2552
|
props.onSaved?.({ kind: "agent.disconnected", id });
|
|
2486
2553
|
};
|
|
2487
|
-
return /* @__PURE__ */ jsxs("section",
|
|
2554
|
+
return /* @__PURE__ */ jsxs(Wrap, { f, as: "section", slot: "section", section: "agents", children: [
|
|
2488
2555
|
/* @__PURE__ */ jsx(Heading, { f, children: f.t.agents }),
|
|
2489
2556
|
/* @__PURE__ */ jsx(Note, { f, children: f.t.agentsHelp }),
|
|
2490
2557
|
general && /* @__PURE__ */ jsx(Say, { f, tone: "danger", children: f.say(general) }),
|
|
@@ -2497,7 +2564,7 @@ function AgentsPart({ props, when }) {
|
|
|
2497
2564
|
" \xB7 ",
|
|
2498
2565
|
when(a.lastUsedAt),
|
|
2499
2566
|
" ",
|
|
2500
|
-
/* @__PURE__ */ jsx(f.Button, { type: "button", disabled: f.busy, className: f.cx("providerButton"), onClick: () => void disconnect(a.id), children: f.t.disconnect })
|
|
2567
|
+
/* @__PURE__ */ jsx(f.Button, { type: "button", variant: "danger", loading: f.loading(`disconnect:${a.id}`), disabled: f.busy, className: f.cx("providerButton"), onClick: () => void disconnect(a.id), children: f.t.disconnect })
|
|
2501
2568
|
] }, a.id)) })
|
|
2502
2569
|
] });
|
|
2503
2570
|
}
|
|
@@ -2515,7 +2582,7 @@ function SessionsPart({ props, when }) {
|
|
|
2515
2582
|
if (props.onSignedOut) props.onSignedOut();
|
|
2516
2583
|
else window.location.assign("/");
|
|
2517
2584
|
};
|
|
2518
|
-
return /* @__PURE__ */ jsxs("section",
|
|
2585
|
+
return /* @__PURE__ */ jsxs(Wrap, { f, as: "section", slot: "section", section: "sessions", children: [
|
|
2519
2586
|
/* @__PURE__ */ jsx(Heading, { f, children: f.t.sessions }),
|
|
2520
2587
|
/* @__PURE__ */ jsx("ul", { className: f.cx("sessions"), children: sessions.map((s, i) => /* @__PURE__ */ jsxs("li", { className: f.cx("session"), children: [
|
|
2521
2588
|
s.device || f.t.unknownDevice,
|
|
@@ -2525,7 +2592,7 @@ function SessionsPart({ props, when }) {
|
|
|
2525
2592
|
when(s.createdAt)
|
|
2526
2593
|
] }, i)) }),
|
|
2527
2594
|
general && /* @__PURE__ */ jsx(Say, { f, tone: "danger", children: f.say(general) }),
|
|
2528
|
-
/* @__PURE__ */ jsx(f.Button, { type: "button", disabled: f.busy, className: f.cx("button"), onClick: () => void end(), children: f.t.signOutEverywhere })
|
|
2595
|
+
/* @__PURE__ */ jsx(f.Button, { type: "button", variant: "danger", loading: f.loading(), disabled: f.busy, className: f.cx("button"), onClick: () => void end(), children: f.t.signOutEverywhere })
|
|
2529
2596
|
] });
|
|
2530
2597
|
}
|
|
2531
2598
|
function ChannelPick({ f, value, channels, onChange }) {
|
|
@@ -2546,15 +2613,22 @@ function ChannelPick({ f, value, channels, onChange }) {
|
|
|
2546
2613
|
// src/react.tsx
|
|
2547
2614
|
import { jsx as jsx2 } from "react/jsx-runtime";
|
|
2548
2615
|
var Ctx = createContext(null);
|
|
2616
|
+
var LocaleCtx = createContext(() => void 0);
|
|
2549
2617
|
var AHEAD_MS = 6e4;
|
|
2550
|
-
function CauthyProvider({ children, basePath = "/api/auth", initialSession }) {
|
|
2618
|
+
function CauthyProvider({ children, basePath = "/api/auth", initialSession, locale }) {
|
|
2551
2619
|
const base = withoutTrailingSlashes(basePath);
|
|
2620
|
+
const said = useRef2(locale);
|
|
2621
|
+
said.current = locale;
|
|
2622
|
+
const readLocale = useCallback2(() => {
|
|
2623
|
+
const l = said.current;
|
|
2624
|
+
return typeof l === "function" ? l() : l;
|
|
2625
|
+
}, []);
|
|
2552
2626
|
const [session, setSession] = useState2(initialSession ?? null);
|
|
2553
2627
|
const [status, setStatus] = useState2(
|
|
2554
2628
|
initialSession === void 0 ? "loading" : initialSession === null ? "unauthenticated" : "authenticated"
|
|
2555
2629
|
);
|
|
2556
2630
|
const asking = useRef2(null);
|
|
2557
|
-
const refresh =
|
|
2631
|
+
const refresh = useCallback2(() => {
|
|
2558
2632
|
asking.current ??= (async () => {
|
|
2559
2633
|
try {
|
|
2560
2634
|
const res = await fetch(`${base}/session`, { credentials: "same-origin", headers: { accept: "application/json" } });
|
|
@@ -2612,7 +2686,7 @@ function CauthyProvider({ children, basePath = "/api/auth", initialSession }) {
|
|
|
2612
2686
|
}),
|
|
2613
2687
|
[session, status, refresh, base]
|
|
2614
2688
|
);
|
|
2615
|
-
return /* @__PURE__ */ jsx2(Ctx.Provider, { value, children });
|
|
2689
|
+
return /* @__PURE__ */ jsx2(Ctx.Provider, { value, children: /* @__PURE__ */ jsx2(LocaleCtx.Provider, { value: readLocale, children }) });
|
|
2616
2690
|
}
|
|
2617
2691
|
function useSession() {
|
|
2618
2692
|
const ctx = useContext(Ctx);
|
|
@@ -2621,8 +2695,9 @@ function useSession() {
|
|
|
2621
2695
|
}
|
|
2622
2696
|
function useAuth() {
|
|
2623
2697
|
const { session, status, refresh, basePath } = useSession();
|
|
2698
|
+
const locale = useContext(LocaleCtx);
|
|
2624
2699
|
return useMemo(() => {
|
|
2625
|
-
const client = createAuthClient({ basePath });
|
|
2700
|
+
const client = createAuthClient({ basePath, locale });
|
|
2626
2701
|
const then = async (running) => {
|
|
2627
2702
|
const r = await running;
|
|
2628
2703
|
await refresh();
|
|
@@ -2659,7 +2734,7 @@ function useAuth() {
|
|
|
2659
2734
|
status,
|
|
2660
2735
|
refresh
|
|
2661
2736
|
};
|
|
2662
|
-
}, [basePath, refresh, session, status]);
|
|
2737
|
+
}, [basePath, locale, refresh, session, status]);
|
|
2663
2738
|
}
|
|
2664
2739
|
export {
|
|
2665
2740
|
AcceptInvite,
|