cauthy-auth 0.34.0 → 0.35.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 +11 -3
- package/dist/react.d.mts +22 -8
- package/dist/react.d.ts +22 -8
- package/dist/react.js +118 -42
- package/dist/react.js.map +1 -1
- package/dist/react.mjs +118 -42
- package/dist/react.mjs.map +1 -1
- package/dist/styles.css +43 -0
- package/package.json +1 -1
package/dist/react.mjs
CHANGED
|
@@ -774,6 +774,7 @@ var TEXTS = {
|
|
|
774
774
|
savePassword: "Save the password",
|
|
775
775
|
passwordChanged: "Your password was changed. You can sign in with it now.",
|
|
776
776
|
confirming: "Confirming your address\u2026",
|
|
777
|
+
loading: "Loading\u2026",
|
|
777
778
|
emailConfirmed: "Your address is confirmed. You can sign in now.",
|
|
778
779
|
invitedTo: "You've been invited to {workspace}",
|
|
779
780
|
invitedToOrganization: "You've been invited to {organization} on {workspace}",
|
|
@@ -955,6 +956,7 @@ var TEXTS = {
|
|
|
955
956
|
savePassword: "Guardar la contrase\xF1a",
|
|
956
957
|
passwordChanged: "Tu contrase\xF1a se cambi\xF3. Ya puedes entrar con ella.",
|
|
957
958
|
confirming: "Confirmando tu correo\u2026",
|
|
959
|
+
loading: "Cargando\u2026",
|
|
958
960
|
emailConfirmed: "Tu correo qued\xF3 confirmado. Ya puedes entrar.",
|
|
959
961
|
invitedTo: "Te invitaron a {workspace}",
|
|
960
962
|
invitedToOrganization: "Te invitaron a {organization} en {workspace}",
|
|
@@ -1087,7 +1089,14 @@ var TEXTS = {
|
|
|
1087
1089
|
}
|
|
1088
1090
|
}
|
|
1089
1091
|
};
|
|
1090
|
-
var PlainButton = ({ variant: _variant, loading
|
|
1092
|
+
var PlainButton = ({ variant: _variant, loading, children, ...p }) => /* @__PURE__ */ jsxs("button", { ...p, "aria-busy": loading || void 0, children: [
|
|
1093
|
+
loading && /* @__PURE__ */ jsx("span", { className: "cauthy-spinner", "aria-hidden": "true" }),
|
|
1094
|
+
children
|
|
1095
|
+
] });
|
|
1096
|
+
var UnstyledButton = ({ variant: _variant, loading, children, ...p }) => /* @__PURE__ */ jsxs("button", { ...p, "aria-busy": loading || void 0, children: [
|
|
1097
|
+
children,
|
|
1098
|
+
loading && /* @__PURE__ */ jsx("span", { "aria-hidden": "true", children: "\u2026" })
|
|
1099
|
+
] });
|
|
1091
1100
|
var PlainInput = (p) => /* @__PURE__ */ jsx("input", { ...p });
|
|
1092
1101
|
var looks = /* @__PURE__ */ new Map();
|
|
1093
1102
|
var loaded = /* @__PURE__ */ new Set();
|
|
@@ -1195,12 +1204,15 @@ function sameOrigin(to) {
|
|
|
1195
1204
|
return void 0;
|
|
1196
1205
|
}
|
|
1197
1206
|
}
|
|
1198
|
-
function
|
|
1207
|
+
function isPending(v) {
|
|
1208
|
+
return typeof v?.then === "function";
|
|
1209
|
+
}
|
|
1210
|
+
function useForm(props, opts = {}) {
|
|
1199
1211
|
const t = { ...TEXTS[props.locale ?? "en"], ...props.texts, errors: { ...TEXTS[props.locale ?? "en"].errors, ...props.texts?.errors } };
|
|
1200
1212
|
const cx = (slot) => props.classNames?.[slot] ?? `cauthy-${slot}`;
|
|
1201
1213
|
const own = (slot) => props.classNames?.[slot];
|
|
1202
1214
|
const C = props.components ?? {};
|
|
1203
|
-
const Button = C.Button ?? PlainButton;
|
|
1215
|
+
const Button = C.Button ?? (props.unstyled ? UnstyledButton : PlainButton);
|
|
1204
1216
|
const Input = C.Input ?? PlainInput;
|
|
1205
1217
|
const [error, setOnlyError] = useState(null);
|
|
1206
1218
|
const [problems, setProblems] = useState({ list: [], round: 0 });
|
|
@@ -1217,9 +1229,32 @@ function useForm(props) {
|
|
|
1217
1229
|
const fieldError = (name) => problems.list.find((e) => e.field === name) ?? (error?.field === name ? error : null);
|
|
1218
1230
|
const firstWrong = (name) => problems.list[0]?.field === name ? problems.round : 0;
|
|
1219
1231
|
const [acting, setActing] = useState(null);
|
|
1220
|
-
const busy = acting !== null;
|
|
1232
|
+
const busy = acting !== null || opts.waiting === true;
|
|
1221
1233
|
const setBusy = useCallback((on) => setActing(on === false ? null : on === true ? SUBMIT : on), []);
|
|
1222
1234
|
const loading = (key = SUBMIT) => acting === key;
|
|
1235
|
+
const shown = useRef(true);
|
|
1236
|
+
useEffect(() => {
|
|
1237
|
+
shown.current = true;
|
|
1238
|
+
const back = (e) => {
|
|
1239
|
+
if (e.persisted) setActing(null);
|
|
1240
|
+
};
|
|
1241
|
+
window.addEventListener("pageshow", back);
|
|
1242
|
+
return () => {
|
|
1243
|
+
shown.current = false;
|
|
1244
|
+
window.removeEventListener("pageshow", back);
|
|
1245
|
+
};
|
|
1246
|
+
}, []);
|
|
1247
|
+
const hold = (after) => {
|
|
1248
|
+
if (!isPending(after)) return;
|
|
1249
|
+
const free = () => {
|
|
1250
|
+
if (shown.current) setActing(null);
|
|
1251
|
+
};
|
|
1252
|
+
after.then(free, free);
|
|
1253
|
+
};
|
|
1254
|
+
const fail = (e) => {
|
|
1255
|
+
setActing(null);
|
|
1256
|
+
setError(e);
|
|
1257
|
+
};
|
|
1223
1258
|
const [policy, setPolicy] = useState(void 0);
|
|
1224
1259
|
const locale = props.locale ?? "en";
|
|
1225
1260
|
const say = (e) => {
|
|
@@ -1228,15 +1263,18 @@ function useForm(props) {
|
|
|
1228
1263
|
};
|
|
1229
1264
|
const passwordRule = describePasswordPolicy(policy, locale);
|
|
1230
1265
|
const done = (to) => {
|
|
1231
|
-
|
|
1266
|
+
setActing((a) => a ?? SUBMIT);
|
|
1267
|
+
if (props.onSuccess) hold(props.onSuccess());
|
|
1232
1268
|
else window.location.assign(sitePath(to) ?? sameOrigin(props.returnTo) ?? "/");
|
|
1233
1269
|
};
|
|
1234
|
-
const root = useRoot(props);
|
|
1235
|
-
|
|
1270
|
+
const root = useRoot(opts.part ? { ...props, unstyled: true } : props);
|
|
1271
|
+
const plain = props.unstyled === true;
|
|
1272
|
+
return { t, cx, own, C, Button, Input, error, setError, fail, check, fieldError, firstWrong, busy, setBusy, loading, hold, say, done, root, plain, policy, setPolicy, passwordRule };
|
|
1236
1273
|
}
|
|
1237
1274
|
var SUBMIT = "submit";
|
|
1238
1275
|
function Wrap(p) {
|
|
1239
1276
|
const { Form: OwnForm } = p.f.C;
|
|
1277
|
+
const busy = p.busy ?? (p.f.busy || void 0);
|
|
1240
1278
|
if (OwnForm) {
|
|
1241
1279
|
const own = /* @__PURE__ */ jsx(
|
|
1242
1280
|
OwnForm,
|
|
@@ -1244,7 +1282,7 @@ function Wrap(p) {
|
|
|
1244
1282
|
as: p.as === "form" ? "form" : "div",
|
|
1245
1283
|
onSubmit: p.onSubmit,
|
|
1246
1284
|
noValidate: p.noValidate,
|
|
1247
|
-
"aria-busy":
|
|
1285
|
+
"aria-busy": busy,
|
|
1248
1286
|
className: p.slot ? p.f.own(p.slot) : void 0,
|
|
1249
1287
|
section: p.section,
|
|
1250
1288
|
children: p.children
|
|
@@ -1253,7 +1291,16 @@ function Wrap(p) {
|
|
|
1253
1291
|
return p.root?.["data-cauthy"] !== void 0 ? /* @__PURE__ */ jsx("div", { ...p.root, children: own }) : own;
|
|
1254
1292
|
}
|
|
1255
1293
|
const Tag2 = p.as;
|
|
1256
|
-
|
|
1294
|
+
const children = p.busy && p.children === void 0 ? /* @__PURE__ */ jsx(Pending, { f: p.f }) : p.children;
|
|
1295
|
+
return /* @__PURE__ */ jsx(Tag2, { className: p.slot ? p.f.cx(p.slot) : void 0, ...p.root, onSubmit: p.onSubmit, noValidate: p.noValidate, "aria-busy": busy, children });
|
|
1296
|
+
}
|
|
1297
|
+
function Pending({ f }) {
|
|
1298
|
+
if (f.plain) return /* @__PURE__ */ jsx("p", { role: "status", children: f.t.loading });
|
|
1299
|
+
return /* @__PURE__ */ jsxs("p", { role: "status", className: f.cx("pending"), children: [
|
|
1300
|
+
/* @__PURE__ */ jsx("span", { className: "cauthy-spinner", "aria-hidden": "true" }),
|
|
1301
|
+
" ",
|
|
1302
|
+
f.t.loading
|
|
1303
|
+
] });
|
|
1257
1304
|
}
|
|
1258
1305
|
function Note({ f, children, footer }) {
|
|
1259
1306
|
const { Text } = f.C;
|
|
@@ -1294,10 +1341,10 @@ function Check(p) {
|
|
|
1294
1341
|
const { f } = p;
|
|
1295
1342
|
const { Checkbox } = f.C;
|
|
1296
1343
|
if (Checkbox) {
|
|
1297
|
-
return /* @__PURE__ */ jsx(Checkbox, { id, name: p.name, checked: p.checked, required: p.required, className: f.own("check"), onChange: p.onChange, children: p.children });
|
|
1344
|
+
return /* @__PURE__ */ jsx(Checkbox, { id, name: p.name, checked: p.checked, required: p.required, disabled: f.busy, className: f.own("check"), onChange: p.onChange, children: p.children });
|
|
1298
1345
|
}
|
|
1299
1346
|
return /* @__PURE__ */ jsxs("label", { className: f.cx("check"), children: [
|
|
1300
|
-
/* @__PURE__ */ jsx("input", { type: "checkbox", name: p.name, checked: p.checked, required: p.required, onChange: (e) => p.onChange(e.target.checked) }),
|
|
1347
|
+
/* @__PURE__ */ jsx("input", { type: "checkbox", name: p.name, checked: p.checked, required: p.required, disabled: f.busy, onChange: (e) => p.onChange(e.target.checked) }),
|
|
1301
1348
|
/* @__PURE__ */ jsx("span", { children: p.children })
|
|
1302
1349
|
] });
|
|
1303
1350
|
}
|
|
@@ -1306,10 +1353,11 @@ function Pick(p) {
|
|
|
1306
1353
|
const id = p.id ?? made;
|
|
1307
1354
|
const { f } = p;
|
|
1308
1355
|
const { Select } = f.C;
|
|
1356
|
+
const disabled = p.disabled || f.busy;
|
|
1309
1357
|
if (Select) {
|
|
1310
|
-
return /* @__PURE__ */ jsx(Select, { id, name: p.name, value: p.value, options: p.options, disabled
|
|
1358
|
+
return /* @__PURE__ */ jsx(Select, { id, name: p.name, value: p.value, options: p.options, disabled, "aria-label": p.label, className: f.own("input"), onChange: p.onChange });
|
|
1311
1359
|
}
|
|
1312
|
-
return /* @__PURE__ */ jsx("select", { id, name: p.name, "aria-label": p.label, className: f.cx("input"), value: p.value, disabled
|
|
1360
|
+
return /* @__PURE__ */ jsx("select", { id, name: p.name, "aria-label": p.label, className: f.cx("input"), value: p.value, disabled, onChange: (e) => p.onChange(e.target.value), children: p.options.map((o) => /* @__PURE__ */ jsx("option", { value: o.value, children: o.label }, o.value)) });
|
|
1313
1361
|
}
|
|
1314
1362
|
function Labelled({ f, id, label, children }) {
|
|
1315
1363
|
const { Field: OwnField } = f.C;
|
|
@@ -1363,6 +1411,7 @@ function Field(p) {
|
|
|
1363
1411
|
value: p.value,
|
|
1364
1412
|
autoComplete: p.autoComplete,
|
|
1365
1413
|
required: p.required,
|
|
1414
|
+
disabled: f.busy,
|
|
1366
1415
|
className: f.cx("input"),
|
|
1367
1416
|
"aria-invalid": bad ? true : void 0,
|
|
1368
1417
|
"aria-describedby": described || void 0,
|
|
@@ -1452,6 +1501,7 @@ function SecondStepForm(p) {
|
|
|
1452
1501
|
if (ctl.signal.aborted) return;
|
|
1453
1502
|
setPushNumber(0);
|
|
1454
1503
|
if (!done.ok) return f.setError(done.error);
|
|
1504
|
+
f.setBusy("push");
|
|
1455
1505
|
f.done();
|
|
1456
1506
|
};
|
|
1457
1507
|
const sendCode = async () => {
|
|
@@ -1467,8 +1517,7 @@ function SecondStepForm(p) {
|
|
|
1467
1517
|
f.setBusy(true);
|
|
1468
1518
|
f.setError(null);
|
|
1469
1519
|
const r = await auth.signIn.mfa({ code });
|
|
1470
|
-
f.
|
|
1471
|
-
if (!r.ok) return f.setError(r.error);
|
|
1520
|
+
if (!r.ok) return f.fail(r.error);
|
|
1472
1521
|
f.done();
|
|
1473
1522
|
};
|
|
1474
1523
|
const general = f.error && !f.error.field ? f.error : null;
|
|
@@ -1496,7 +1545,11 @@ function SecondStepForm(p) {
|
|
|
1496
1545
|
}
|
|
1497
1546
|
function ProviderButtons(p) {
|
|
1498
1547
|
const { f } = p;
|
|
1499
|
-
|
|
1548
|
+
const pick = (id) => {
|
|
1549
|
+
f.setBusy(`provider:${id}`);
|
|
1550
|
+
p.onPick(id);
|
|
1551
|
+
};
|
|
1552
|
+
return /* @__PURE__ */ jsx(Fragment2, { children: p.providers.map((provider) => /* @__PURE__ */ jsxs(f.Button, { type: "button", variant: "secondary", loading: f.loading(`provider:${provider.id}`), disabled: f.busy, className: f.cx("providerButton"), onClick: () => pick(provider.id), children: [
|
|
1500
1553
|
provider.iconUrl && /* @__PURE__ */ jsx("img", { src: provider.iconUrl, alt: "", width: 18, height: 18, className: f.cx("providerIcon") }),
|
|
1501
1554
|
f.t.continueWith,
|
|
1502
1555
|
" ",
|
|
@@ -1509,8 +1562,8 @@ function signInOffers(methods) {
|
|
|
1509
1562
|
}
|
|
1510
1563
|
function SignIn(props) {
|
|
1511
1564
|
const auth = useAuth();
|
|
1512
|
-
const f = useForm(props);
|
|
1513
1565
|
const [methods, setMethods] = useState(null);
|
|
1566
|
+
const f = useForm(props, { waiting: methods === null });
|
|
1514
1567
|
const [email, setEmail] = useState("");
|
|
1515
1568
|
const [password, setPassword] = useState("");
|
|
1516
1569
|
const [code, setCode] = useState("");
|
|
@@ -1582,14 +1635,16 @@ function SignIn(props) {
|
|
|
1582
1635
|
f.setBusy(true);
|
|
1583
1636
|
f.setError(null);
|
|
1584
1637
|
const r = step === "sent" ? await auth.signIn.emailCode({ code }) : await auth.signIn.email({ email, password, captchaToken: challenge.token });
|
|
1585
|
-
f.setBusy(false);
|
|
1586
1638
|
if (step === "password") challenge.renew();
|
|
1587
1639
|
if (!r.ok && r.error.code === "sso_required") return toCompany();
|
|
1588
1640
|
if (!r.ok) {
|
|
1589
1641
|
setOffer((n) => n + 1);
|
|
1590
|
-
return f.
|
|
1642
|
+
return f.fail(r.error);
|
|
1643
|
+
}
|
|
1644
|
+
if (r.status === "mfa_required") {
|
|
1645
|
+
f.setBusy(false);
|
|
1646
|
+
return setStep("code");
|
|
1591
1647
|
}
|
|
1592
|
-
if (r.status === "mfa_required") return setStep("code");
|
|
1593
1648
|
f.done("returnTo" in r && typeof r.returnTo === "string" ? r.returnTo : void 0);
|
|
1594
1649
|
};
|
|
1595
1650
|
const usePasskey = async () => {
|
|
@@ -1598,10 +1653,10 @@ function SignIn(props) {
|
|
|
1598
1653
|
f.setError(null);
|
|
1599
1654
|
const r = await auth.signIn.passkey({ returnTo: props.returnTo, locale: props.locale, email });
|
|
1600
1655
|
if (r.ok && r.status === "redirected") return;
|
|
1656
|
+
if (r.ok) return f.done();
|
|
1601
1657
|
f.setBusy(false);
|
|
1602
|
-
|
|
1603
|
-
if (
|
|
1604
|
-
f.done();
|
|
1658
|
+
setOffer((n) => n + 1);
|
|
1659
|
+
if (r.error.code !== "cancelled") f.setError(r.error);
|
|
1605
1660
|
};
|
|
1606
1661
|
const sendLink = async () => {
|
|
1607
1662
|
autofill.current?.abort();
|
|
@@ -1718,10 +1773,12 @@ function SignUp(props) {
|
|
|
1718
1773
|
...legal ? { acceptLegal, consents } : {},
|
|
1719
1774
|
captchaToken: challenge.token
|
|
1720
1775
|
});
|
|
1721
|
-
f.setBusy(false);
|
|
1722
1776
|
challenge.renew();
|
|
1723
|
-
if (!r.ok) return f.
|
|
1724
|
-
if (r.status === "verification_required")
|
|
1777
|
+
if (!r.ok) return f.fail(r.error);
|
|
1778
|
+
if (r.status === "verification_required") {
|
|
1779
|
+
f.setBusy(false);
|
|
1780
|
+
return setSent(true);
|
|
1781
|
+
}
|
|
1725
1782
|
f.done();
|
|
1726
1783
|
};
|
|
1727
1784
|
const general = f.error && !f.error.field ? f.error : null;
|
|
@@ -1884,13 +1941,16 @@ function AcceptInvite(props) {
|
|
|
1884
1941
|
f.setBusy(true);
|
|
1885
1942
|
f.setError(null);
|
|
1886
1943
|
const r = await auth.acceptInvitation(token, password);
|
|
1887
|
-
f.setBusy(false);
|
|
1888
1944
|
if (!r.ok) {
|
|
1945
|
+
f.setBusy(false);
|
|
1889
1946
|
if (r.error.code === "invalid_token") return setState("invalid");
|
|
1890
1947
|
return f.setError(r.error);
|
|
1891
1948
|
}
|
|
1892
1949
|
props.onSaved?.({ kind: "invitation.accepted", email: invitation?.email ?? "", ...invitation?.organization ? { organization: invitation.organization } : {} });
|
|
1893
|
-
if (r.status === "mfa_required")
|
|
1950
|
+
if (r.status === "mfa_required") {
|
|
1951
|
+
f.setBusy(false);
|
|
1952
|
+
return setState("code");
|
|
1953
|
+
}
|
|
1894
1954
|
f.done();
|
|
1895
1955
|
};
|
|
1896
1956
|
const general = f.error && !f.error.field ? f.error : null;
|
|
@@ -1928,10 +1988,11 @@ function PendingTerms(props) {
|
|
|
1928
1988
|
f.setBusy(true);
|
|
1929
1989
|
f.setError(null);
|
|
1930
1990
|
const r = await auth.account.acceptLegal({ kinds: owed.map((d) => d.kind) });
|
|
1991
|
+
if (!r.ok) return f.fail(r.error);
|
|
1992
|
+
const after = props.onSuccess?.();
|
|
1993
|
+
if (isPending(after)) await Promise.resolve(after).catch(() => void 0);
|
|
1931
1994
|
f.setBusy(false);
|
|
1932
|
-
if (!r.ok) return f.setError(r.error);
|
|
1933
1995
|
setOwed([]);
|
|
1934
|
-
props.onSuccess?.();
|
|
1935
1996
|
};
|
|
1936
1997
|
return /* @__PURE__ */ jsxs(Wrap, { f, as: "div", slot: "form", root: f.root, children: [
|
|
1937
1998
|
/* @__PURE__ */ jsx(Heading, { f, children: f.t.termsChanged }),
|
|
@@ -1946,15 +2007,15 @@ function PendingTerms(props) {
|
|
|
1946
2007
|
}
|
|
1947
2008
|
var ACCOUNT_SECTIONS = ["profile", "email", "password", "linked", "secondStep", "phone", "passkeys", "agents", "sessions"];
|
|
1948
2009
|
function useSection(props) {
|
|
1949
|
-
const f = useForm(
|
|
2010
|
+
const f = useForm(props, { part: true });
|
|
1950
2011
|
const [done, setDone] = useState(null);
|
|
1951
|
-
const run = async (action, key = SUBMIT) => {
|
|
2012
|
+
const run = async (action, key = SUBMIT, leaves = false) => {
|
|
1952
2013
|
f.setBusy(key);
|
|
1953
2014
|
f.setError(null);
|
|
1954
2015
|
setDone(null);
|
|
1955
2016
|
const r = await action();
|
|
1956
|
-
f.
|
|
1957
|
-
if (!
|
|
2017
|
+
if (!r.ok) f.fail(r.error);
|
|
2018
|
+
else if (!leaves) f.setBusy(false);
|
|
1958
2019
|
return r;
|
|
1959
2020
|
};
|
|
1960
2021
|
const general = f.error && !f.error.field ? f.error : null;
|
|
@@ -2367,11 +2428,26 @@ function LinkedPart({ props }) {
|
|
|
2367
2428
|
" ",
|
|
2368
2429
|
/* @__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 })
|
|
2369
2430
|
] }, x.provider)) }),
|
|
2370
|
-
offered.filter((p) => !linked.some((x) => x.provider === p.id)).map((p) => /* @__PURE__ */ jsxs(
|
|
2371
|
-
f.
|
|
2372
|
-
|
|
2373
|
-
|
|
2374
|
-
|
|
2431
|
+
offered.filter((p) => !linked.some((x) => x.provider === p.id)).map((p) => /* @__PURE__ */ jsxs(
|
|
2432
|
+
f.Button,
|
|
2433
|
+
{
|
|
2434
|
+
type: "button",
|
|
2435
|
+
variant: "secondary",
|
|
2436
|
+
loading: f.loading(`link:${p.id}`),
|
|
2437
|
+
disabled: f.busy,
|
|
2438
|
+
className: f.cx("providerButton"),
|
|
2439
|
+
onClick: () => {
|
|
2440
|
+
f.setBusy(`link:${p.id}`);
|
|
2441
|
+
auth.account.link(p.id, { returnTo: here });
|
|
2442
|
+
},
|
|
2443
|
+
children: [
|
|
2444
|
+
f.t.linkWith,
|
|
2445
|
+
" ",
|
|
2446
|
+
p.name
|
|
2447
|
+
]
|
|
2448
|
+
},
|
|
2449
|
+
p.id
|
|
2450
|
+
))
|
|
2375
2451
|
] });
|
|
2376
2452
|
}
|
|
2377
2453
|
function PasswordPart({ props }) {
|
|
@@ -2529,7 +2605,7 @@ function PhonePart({ props, account, onChanged }) {
|
|
|
2529
2605
|
!ways.phone && /* @__PURE__ */ jsx(Field, { f, name: "phone", type: "tel", label: f.t.phone, value: number, autoComplete: "tel", required: true, onChange: setNumber }),
|
|
2530
2606
|
!ways.phone && ways.phoneChannels.length > 1 && f.C.Select && /* @__PURE__ */ jsx(ChannelPick, { f, value: channel, channels: ways.phoneChannels, onChange: setChannel }),
|
|
2531
2607
|
!ways.phone && ways.phoneChannels.length > 1 && !f.C.Select && /* @__PURE__ */ jsx("div", { className: f.cx("field"), role: "radiogroup", children: ways.phoneChannels.map((c) => /* @__PURE__ */ jsxs("label", { className: f.cx("label"), children: [
|
|
2532
|
-
/* @__PURE__ */ jsx("input", { type: "radio", name: "channel", value: c, checked: channel === c, onChange: () => setChannel(c) }),
|
|
2608
|
+
/* @__PURE__ */ jsx("input", { type: "radio", name: "channel", value: c, checked: channel === c, disabled: f.busy, onChange: () => setChannel(c) }),
|
|
2533
2609
|
" ",
|
|
2534
2610
|
c === "whatsapp" ? f.t.byWhatsapp : f.t.bySms
|
|
2535
2611
|
] }, c)) }),
|
|
@@ -2576,10 +2652,10 @@ function SessionsPart({ props, when }) {
|
|
|
2576
2652
|
void auth.account.sessions().then(setSessions);
|
|
2577
2653
|
}, []);
|
|
2578
2654
|
const end = async () => {
|
|
2579
|
-
const r = await run(() => auth.account.signOutEverywhere());
|
|
2655
|
+
const r = await run(() => auth.account.signOutEverywhere(), SUBMIT, true);
|
|
2580
2656
|
if (!r.ok) return;
|
|
2581
2657
|
props.onSaved?.({ kind: "sessions.ended" });
|
|
2582
|
-
if (props.onSignedOut) props.onSignedOut();
|
|
2658
|
+
if (props.onSignedOut) f.hold(props.onSignedOut());
|
|
2583
2659
|
else window.location.assign("/");
|
|
2584
2660
|
};
|
|
2585
2661
|
return /* @__PURE__ */ jsxs(Wrap, { f, as: "section", slot: "section", section: "sessions", children: [
|