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