cauthy-auth 0.34.0 → 0.35.1
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 +20 -8
- package/dist/react.d.ts +20 -8
- package/dist/react.js +135 -42
- package/dist/react.js.map +1 -1
- package/dist/react.mjs +136 -43
- package/dist/react.mjs.map +1 -1
- package/dist/styles.css +45 -0
- package/package.json +1 -1
package/dist/react.mjs
CHANGED
|
@@ -721,7 +721,7 @@ function definePolicy(given) {
|
|
|
721
721
|
}
|
|
722
722
|
|
|
723
723
|
// src/components.tsx
|
|
724
|
-
import { Fragment, useCallback, useEffect, useId, useRef, useState } from "react";
|
|
724
|
+
import { Fragment, useCallback, useEffect, useId, useRef, useState, useSyncExternalStore } from "react";
|
|
725
725
|
import { Fragment as Fragment2, jsx, jsxs } from "react/jsx-runtime";
|
|
726
726
|
var TEXTS = {
|
|
727
727
|
en: {
|
|
@@ -1087,7 +1087,38 @@ var TEXTS = {
|
|
|
1087
1087
|
}
|
|
1088
1088
|
}
|
|
1089
1089
|
};
|
|
1090
|
-
var PlainButton = ({ variant: _variant, loading
|
|
1090
|
+
var PlainButton = ({ variant: _variant, loading, children, ...p }) => /* @__PURE__ */ jsxs("button", { ...p, "aria-busy": loading || void 0, children: [
|
|
1091
|
+
loading && /* @__PURE__ */ jsx(Spinner, {}),
|
|
1092
|
+
children
|
|
1093
|
+
] });
|
|
1094
|
+
var UnstyledButton = ({ variant: _variant, loading, children, ...p }) => /* @__PURE__ */ jsxs("button", { ...p, "aria-busy": loading || void 0, children: [
|
|
1095
|
+
loading && /* @__PURE__ */ jsxs(Fragment2, { children: [
|
|
1096
|
+
/* @__PURE__ */ jsx(Spinner, { plain: true }),
|
|
1097
|
+
" "
|
|
1098
|
+
] }),
|
|
1099
|
+
children
|
|
1100
|
+
] });
|
|
1101
|
+
function Spinner({ plain }) {
|
|
1102
|
+
if (!plain) return /* @__PURE__ */ jsx("span", { className: "cauthy-spinner", "aria-hidden": "true" });
|
|
1103
|
+
return /* @__PURE__ */ jsx(SpinnerIcon, {});
|
|
1104
|
+
}
|
|
1105
|
+
var LESS_MOTION = "(prefers-reduced-motion: reduce)";
|
|
1106
|
+
function watchMotion(changed) {
|
|
1107
|
+
if (typeof window === "undefined" || typeof window.matchMedia !== "function") return () => {
|
|
1108
|
+
};
|
|
1109
|
+
const query = window.matchMedia(LESS_MOTION);
|
|
1110
|
+
query.addEventListener?.("change", changed);
|
|
1111
|
+
return () => query.removeEventListener?.("change", changed);
|
|
1112
|
+
}
|
|
1113
|
+
var stillHere = () => typeof window.matchMedia === "function" && window.matchMedia(LESS_MOTION).matches;
|
|
1114
|
+
var stillOnServer = () => true;
|
|
1115
|
+
function SpinnerIcon() {
|
|
1116
|
+
const still = useSyncExternalStore(watchMotion, stillHere, stillOnServer);
|
|
1117
|
+
return /* @__PURE__ */ jsxs("svg", { className: "cauthy-spinner-icon", width: "1em", height: "1em", viewBox: "0 0 16 16", fill: "none", "aria-hidden": "true", focusable: "false", children: [
|
|
1118
|
+
/* @__PURE__ */ jsx("circle", { cx: "8", cy: "8", r: "6.5", stroke: "currentColor", strokeOpacity: "0.25", strokeWidth: "2" }),
|
|
1119
|
+
/* @__PURE__ */ jsx("path", { d: "M14.5 8A6.5 6.5 0 0 0 8 1.5", stroke: "currentColor", strokeWidth: "2", strokeLinecap: "round", children: !still && /* @__PURE__ */ jsx("animateTransform", { attributeName: "transform", type: "rotate", from: "0 8 8", to: "360 8 8", dur: "0.7s", repeatCount: "indefinite" }) })
|
|
1120
|
+
] });
|
|
1121
|
+
}
|
|
1091
1122
|
var PlainInput = (p) => /* @__PURE__ */ jsx("input", { ...p });
|
|
1092
1123
|
var looks = /* @__PURE__ */ new Map();
|
|
1093
1124
|
var loaded = /* @__PURE__ */ new Set();
|
|
@@ -1195,12 +1226,15 @@ function sameOrigin(to) {
|
|
|
1195
1226
|
return void 0;
|
|
1196
1227
|
}
|
|
1197
1228
|
}
|
|
1198
|
-
function
|
|
1229
|
+
function isPending(v) {
|
|
1230
|
+
return typeof v?.then === "function";
|
|
1231
|
+
}
|
|
1232
|
+
function useForm(props, opts = {}) {
|
|
1199
1233
|
const t = { ...TEXTS[props.locale ?? "en"], ...props.texts, errors: { ...TEXTS[props.locale ?? "en"].errors, ...props.texts?.errors } };
|
|
1200
1234
|
const cx = (slot) => props.classNames?.[slot] ?? `cauthy-${slot}`;
|
|
1201
1235
|
const own = (slot) => props.classNames?.[slot];
|
|
1202
1236
|
const C = props.components ?? {};
|
|
1203
|
-
const Button = C.Button ?? PlainButton;
|
|
1237
|
+
const Button = C.Button ?? (props.unstyled ? UnstyledButton : PlainButton);
|
|
1204
1238
|
const Input = C.Input ?? PlainInput;
|
|
1205
1239
|
const [error, setOnlyError] = useState(null);
|
|
1206
1240
|
const [problems, setProblems] = useState({ list: [], round: 0 });
|
|
@@ -1217,9 +1251,32 @@ function useForm(props) {
|
|
|
1217
1251
|
const fieldError = (name) => problems.list.find((e) => e.field === name) ?? (error?.field === name ? error : null);
|
|
1218
1252
|
const firstWrong = (name) => problems.list[0]?.field === name ? problems.round : 0;
|
|
1219
1253
|
const [acting, setActing] = useState(null);
|
|
1220
|
-
const busy = acting !== null;
|
|
1254
|
+
const busy = acting !== null || opts.waiting === true;
|
|
1221
1255
|
const setBusy = useCallback((on) => setActing(on === false ? null : on === true ? SUBMIT : on), []);
|
|
1222
1256
|
const loading = (key = SUBMIT) => acting === key;
|
|
1257
|
+
const shown = useRef(true);
|
|
1258
|
+
useEffect(() => {
|
|
1259
|
+
shown.current = true;
|
|
1260
|
+
const back = (e) => {
|
|
1261
|
+
if (e.persisted) setActing(null);
|
|
1262
|
+
};
|
|
1263
|
+
window.addEventListener("pageshow", back);
|
|
1264
|
+
return () => {
|
|
1265
|
+
shown.current = false;
|
|
1266
|
+
window.removeEventListener("pageshow", back);
|
|
1267
|
+
};
|
|
1268
|
+
}, []);
|
|
1269
|
+
const hold = (after) => {
|
|
1270
|
+
if (!isPending(after)) return;
|
|
1271
|
+
const free = () => {
|
|
1272
|
+
if (shown.current) setActing(null);
|
|
1273
|
+
};
|
|
1274
|
+
after.then(free, free);
|
|
1275
|
+
};
|
|
1276
|
+
const fail = (e) => {
|
|
1277
|
+
setActing(null);
|
|
1278
|
+
setError(e);
|
|
1279
|
+
};
|
|
1223
1280
|
const [policy, setPolicy] = useState(void 0);
|
|
1224
1281
|
const locale = props.locale ?? "en";
|
|
1225
1282
|
const say = (e) => {
|
|
@@ -1228,15 +1285,18 @@ function useForm(props) {
|
|
|
1228
1285
|
};
|
|
1229
1286
|
const passwordRule = describePasswordPolicy(policy, locale);
|
|
1230
1287
|
const done = (to) => {
|
|
1231
|
-
|
|
1288
|
+
setActing((a) => a ?? SUBMIT);
|
|
1289
|
+
if (props.onSuccess) hold(props.onSuccess());
|
|
1232
1290
|
else window.location.assign(sitePath(to) ?? sameOrigin(props.returnTo) ?? "/");
|
|
1233
1291
|
};
|
|
1234
|
-
const root = useRoot(props);
|
|
1235
|
-
|
|
1292
|
+
const root = useRoot(opts.part ? { ...props, unstyled: true } : props);
|
|
1293
|
+
const plain = props.unstyled === true;
|
|
1294
|
+
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
1295
|
}
|
|
1237
1296
|
var SUBMIT = "submit";
|
|
1238
1297
|
function Wrap(p) {
|
|
1239
1298
|
const { Form: OwnForm } = p.f.C;
|
|
1299
|
+
const busy = p.busy ?? (p.f.busy || void 0);
|
|
1240
1300
|
if (OwnForm) {
|
|
1241
1301
|
const own = /* @__PURE__ */ jsx(
|
|
1242
1302
|
OwnForm,
|
|
@@ -1244,7 +1304,7 @@ function Wrap(p) {
|
|
|
1244
1304
|
as: p.as === "form" ? "form" : "div",
|
|
1245
1305
|
onSubmit: p.onSubmit,
|
|
1246
1306
|
noValidate: p.noValidate,
|
|
1247
|
-
"aria-busy":
|
|
1307
|
+
"aria-busy": busy,
|
|
1248
1308
|
className: p.slot ? p.f.own(p.slot) : void 0,
|
|
1249
1309
|
section: p.section,
|
|
1250
1310
|
children: p.children
|
|
@@ -1253,7 +1313,11 @@ function Wrap(p) {
|
|
|
1253
1313
|
return p.root?.["data-cauthy"] !== void 0 ? /* @__PURE__ */ jsx("div", { ...p.root, children: own }) : own;
|
|
1254
1314
|
}
|
|
1255
1315
|
const Tag2 = p.as;
|
|
1256
|
-
|
|
1316
|
+
const children = p.busy && p.children === void 0 ? /* @__PURE__ */ jsx(Pending, { f: p.f }) : p.children;
|
|
1317
|
+
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 });
|
|
1318
|
+
}
|
|
1319
|
+
function Pending({ f }) {
|
|
1320
|
+
return /* @__PURE__ */ jsx("div", { className: f.cx("pending"), children: /* @__PURE__ */ jsx(Spinner, { plain: f.plain }) });
|
|
1257
1321
|
}
|
|
1258
1322
|
function Note({ f, children, footer }) {
|
|
1259
1323
|
const { Text } = f.C;
|
|
@@ -1294,10 +1358,10 @@ function Check(p) {
|
|
|
1294
1358
|
const { f } = p;
|
|
1295
1359
|
const { Checkbox } = f.C;
|
|
1296
1360
|
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 });
|
|
1361
|
+
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
1362
|
}
|
|
1299
1363
|
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) }),
|
|
1364
|
+
/* @__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
1365
|
/* @__PURE__ */ jsx("span", { children: p.children })
|
|
1302
1366
|
] });
|
|
1303
1367
|
}
|
|
@@ -1306,10 +1370,11 @@ function Pick(p) {
|
|
|
1306
1370
|
const id = p.id ?? made;
|
|
1307
1371
|
const { f } = p;
|
|
1308
1372
|
const { Select } = f.C;
|
|
1373
|
+
const disabled = p.disabled || f.busy;
|
|
1309
1374
|
if (Select) {
|
|
1310
|
-
return /* @__PURE__ */ jsx(Select, { id, name: p.name, value: p.value, options: p.options, disabled
|
|
1375
|
+
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
1376
|
}
|
|
1312
|
-
return /* @__PURE__ */ jsx("select", { id, name: p.name, "aria-label": p.label, className: f.cx("input"), value: p.value, disabled
|
|
1377
|
+
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
1378
|
}
|
|
1314
1379
|
function Labelled({ f, id, label, children }) {
|
|
1315
1380
|
const { Field: OwnField } = f.C;
|
|
@@ -1363,6 +1428,7 @@ function Field(p) {
|
|
|
1363
1428
|
value: p.value,
|
|
1364
1429
|
autoComplete: p.autoComplete,
|
|
1365
1430
|
required: p.required,
|
|
1431
|
+
disabled: f.busy,
|
|
1366
1432
|
className: f.cx("input"),
|
|
1367
1433
|
"aria-invalid": bad ? true : void 0,
|
|
1368
1434
|
"aria-describedby": described || void 0,
|
|
@@ -1452,6 +1518,7 @@ function SecondStepForm(p) {
|
|
|
1452
1518
|
if (ctl.signal.aborted) return;
|
|
1453
1519
|
setPushNumber(0);
|
|
1454
1520
|
if (!done.ok) return f.setError(done.error);
|
|
1521
|
+
f.setBusy("push");
|
|
1455
1522
|
f.done();
|
|
1456
1523
|
};
|
|
1457
1524
|
const sendCode = async () => {
|
|
@@ -1467,8 +1534,7 @@ function SecondStepForm(p) {
|
|
|
1467
1534
|
f.setBusy(true);
|
|
1468
1535
|
f.setError(null);
|
|
1469
1536
|
const r = await auth.signIn.mfa({ code });
|
|
1470
|
-
f.
|
|
1471
|
-
if (!r.ok) return f.setError(r.error);
|
|
1537
|
+
if (!r.ok) return f.fail(r.error);
|
|
1472
1538
|
f.done();
|
|
1473
1539
|
};
|
|
1474
1540
|
const general = f.error && !f.error.field ? f.error : null;
|
|
@@ -1496,7 +1562,11 @@ function SecondStepForm(p) {
|
|
|
1496
1562
|
}
|
|
1497
1563
|
function ProviderButtons(p) {
|
|
1498
1564
|
const { f } = p;
|
|
1499
|
-
|
|
1565
|
+
const pick = (id) => {
|
|
1566
|
+
f.setBusy(`provider:${id}`);
|
|
1567
|
+
p.onPick(id);
|
|
1568
|
+
};
|
|
1569
|
+
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
1570
|
provider.iconUrl && /* @__PURE__ */ jsx("img", { src: provider.iconUrl, alt: "", width: 18, height: 18, className: f.cx("providerIcon") }),
|
|
1501
1571
|
f.t.continueWith,
|
|
1502
1572
|
" ",
|
|
@@ -1509,8 +1579,8 @@ function signInOffers(methods) {
|
|
|
1509
1579
|
}
|
|
1510
1580
|
function SignIn(props) {
|
|
1511
1581
|
const auth = useAuth();
|
|
1512
|
-
const f = useForm(props);
|
|
1513
1582
|
const [methods, setMethods] = useState(null);
|
|
1583
|
+
const f = useForm(props, { waiting: methods === null });
|
|
1514
1584
|
const [email, setEmail] = useState("");
|
|
1515
1585
|
const [password, setPassword] = useState("");
|
|
1516
1586
|
const [code, setCode] = useState("");
|
|
@@ -1582,14 +1652,16 @@ function SignIn(props) {
|
|
|
1582
1652
|
f.setBusy(true);
|
|
1583
1653
|
f.setError(null);
|
|
1584
1654
|
const r = step === "sent" ? await auth.signIn.emailCode({ code }) : await auth.signIn.email({ email, password, captchaToken: challenge.token });
|
|
1585
|
-
f.setBusy(false);
|
|
1586
1655
|
if (step === "password") challenge.renew();
|
|
1587
1656
|
if (!r.ok && r.error.code === "sso_required") return toCompany();
|
|
1588
1657
|
if (!r.ok) {
|
|
1589
1658
|
setOffer((n) => n + 1);
|
|
1590
|
-
return f.
|
|
1659
|
+
return f.fail(r.error);
|
|
1660
|
+
}
|
|
1661
|
+
if (r.status === "mfa_required") {
|
|
1662
|
+
f.setBusy(false);
|
|
1663
|
+
return setStep("code");
|
|
1591
1664
|
}
|
|
1592
|
-
if (r.status === "mfa_required") return setStep("code");
|
|
1593
1665
|
f.done("returnTo" in r && typeof r.returnTo === "string" ? r.returnTo : void 0);
|
|
1594
1666
|
};
|
|
1595
1667
|
const usePasskey = async () => {
|
|
@@ -1598,10 +1670,10 @@ function SignIn(props) {
|
|
|
1598
1670
|
f.setError(null);
|
|
1599
1671
|
const r = await auth.signIn.passkey({ returnTo: props.returnTo, locale: props.locale, email });
|
|
1600
1672
|
if (r.ok && r.status === "redirected") return;
|
|
1673
|
+
if (r.ok) return f.done();
|
|
1601
1674
|
f.setBusy(false);
|
|
1602
|
-
|
|
1603
|
-
if (
|
|
1604
|
-
f.done();
|
|
1675
|
+
setOffer((n) => n + 1);
|
|
1676
|
+
if (r.error.code !== "cancelled") f.setError(r.error);
|
|
1605
1677
|
};
|
|
1606
1678
|
const sendLink = async () => {
|
|
1607
1679
|
autofill.current?.abort();
|
|
@@ -1718,10 +1790,12 @@ function SignUp(props) {
|
|
|
1718
1790
|
...legal ? { acceptLegal, consents } : {},
|
|
1719
1791
|
captchaToken: challenge.token
|
|
1720
1792
|
});
|
|
1721
|
-
f.setBusy(false);
|
|
1722
1793
|
challenge.renew();
|
|
1723
|
-
if (!r.ok) return f.
|
|
1724
|
-
if (r.status === "verification_required")
|
|
1794
|
+
if (!r.ok) return f.fail(r.error);
|
|
1795
|
+
if (r.status === "verification_required") {
|
|
1796
|
+
f.setBusy(false);
|
|
1797
|
+
return setSent(true);
|
|
1798
|
+
}
|
|
1725
1799
|
f.done();
|
|
1726
1800
|
};
|
|
1727
1801
|
const general = f.error && !f.error.field ? f.error : null;
|
|
@@ -1884,13 +1958,16 @@ function AcceptInvite(props) {
|
|
|
1884
1958
|
f.setBusy(true);
|
|
1885
1959
|
f.setError(null);
|
|
1886
1960
|
const r = await auth.acceptInvitation(token, password);
|
|
1887
|
-
f.setBusy(false);
|
|
1888
1961
|
if (!r.ok) {
|
|
1962
|
+
f.setBusy(false);
|
|
1889
1963
|
if (r.error.code === "invalid_token") return setState("invalid");
|
|
1890
1964
|
return f.setError(r.error);
|
|
1891
1965
|
}
|
|
1892
1966
|
props.onSaved?.({ kind: "invitation.accepted", email: invitation?.email ?? "", ...invitation?.organization ? { organization: invitation.organization } : {} });
|
|
1893
|
-
if (r.status === "mfa_required")
|
|
1967
|
+
if (r.status === "mfa_required") {
|
|
1968
|
+
f.setBusy(false);
|
|
1969
|
+
return setState("code");
|
|
1970
|
+
}
|
|
1894
1971
|
f.done();
|
|
1895
1972
|
};
|
|
1896
1973
|
const general = f.error && !f.error.field ? f.error : null;
|
|
@@ -1928,10 +2005,11 @@ function PendingTerms(props) {
|
|
|
1928
2005
|
f.setBusy(true);
|
|
1929
2006
|
f.setError(null);
|
|
1930
2007
|
const r = await auth.account.acceptLegal({ kinds: owed.map((d) => d.kind) });
|
|
2008
|
+
if (!r.ok) return f.fail(r.error);
|
|
2009
|
+
const after = props.onSuccess?.();
|
|
2010
|
+
if (isPending(after)) await Promise.resolve(after).catch(() => void 0);
|
|
1931
2011
|
f.setBusy(false);
|
|
1932
|
-
if (!r.ok) return f.setError(r.error);
|
|
1933
2012
|
setOwed([]);
|
|
1934
|
-
props.onSuccess?.();
|
|
1935
2013
|
};
|
|
1936
2014
|
return /* @__PURE__ */ jsxs(Wrap, { f, as: "div", slot: "form", root: f.root, children: [
|
|
1937
2015
|
/* @__PURE__ */ jsx(Heading, { f, children: f.t.termsChanged }),
|
|
@@ -1946,15 +2024,15 @@ function PendingTerms(props) {
|
|
|
1946
2024
|
}
|
|
1947
2025
|
var ACCOUNT_SECTIONS = ["profile", "email", "password", "linked", "secondStep", "phone", "passkeys", "agents", "sessions"];
|
|
1948
2026
|
function useSection(props) {
|
|
1949
|
-
const f = useForm(
|
|
2027
|
+
const f = useForm(props, { part: true });
|
|
1950
2028
|
const [done, setDone] = useState(null);
|
|
1951
|
-
const run = async (action, key = SUBMIT) => {
|
|
2029
|
+
const run = async (action, key = SUBMIT, leaves = false) => {
|
|
1952
2030
|
f.setBusy(key);
|
|
1953
2031
|
f.setError(null);
|
|
1954
2032
|
setDone(null);
|
|
1955
2033
|
const r = await action();
|
|
1956
|
-
f.
|
|
1957
|
-
if (!
|
|
2034
|
+
if (!r.ok) f.fail(r.error);
|
|
2035
|
+
else if (!leaves) f.setBusy(false);
|
|
1958
2036
|
return r;
|
|
1959
2037
|
};
|
|
1960
2038
|
const general = f.error && !f.error.field ? f.error : null;
|
|
@@ -2367,11 +2445,26 @@ function LinkedPart({ props }) {
|
|
|
2367
2445
|
" ",
|
|
2368
2446
|
/* @__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
2447
|
] }, x.provider)) }),
|
|
2370
|
-
offered.filter((p) => !linked.some((x) => x.provider === p.id)).map((p) => /* @__PURE__ */ jsxs(
|
|
2371
|
-
f.
|
|
2372
|
-
|
|
2373
|
-
|
|
2374
|
-
|
|
2448
|
+
offered.filter((p) => !linked.some((x) => x.provider === p.id)).map((p) => /* @__PURE__ */ jsxs(
|
|
2449
|
+
f.Button,
|
|
2450
|
+
{
|
|
2451
|
+
type: "button",
|
|
2452
|
+
variant: "secondary",
|
|
2453
|
+
loading: f.loading(`link:${p.id}`),
|
|
2454
|
+
disabled: f.busy,
|
|
2455
|
+
className: f.cx("providerButton"),
|
|
2456
|
+
onClick: () => {
|
|
2457
|
+
f.setBusy(`link:${p.id}`);
|
|
2458
|
+
auth.account.link(p.id, { returnTo: here });
|
|
2459
|
+
},
|
|
2460
|
+
children: [
|
|
2461
|
+
f.t.linkWith,
|
|
2462
|
+
" ",
|
|
2463
|
+
p.name
|
|
2464
|
+
]
|
|
2465
|
+
},
|
|
2466
|
+
p.id
|
|
2467
|
+
))
|
|
2375
2468
|
] });
|
|
2376
2469
|
}
|
|
2377
2470
|
function PasswordPart({ props }) {
|
|
@@ -2529,7 +2622,7 @@ function PhonePart({ props, account, onChanged }) {
|
|
|
2529
2622
|
!ways.phone && /* @__PURE__ */ jsx(Field, { f, name: "phone", type: "tel", label: f.t.phone, value: number, autoComplete: "tel", required: true, onChange: setNumber }),
|
|
2530
2623
|
!ways.phone && ways.phoneChannels.length > 1 && f.C.Select && /* @__PURE__ */ jsx(ChannelPick, { f, value: channel, channels: ways.phoneChannels, onChange: setChannel }),
|
|
2531
2624
|
!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) }),
|
|
2625
|
+
/* @__PURE__ */ jsx("input", { type: "radio", name: "channel", value: c, checked: channel === c, disabled: f.busy, onChange: () => setChannel(c) }),
|
|
2533
2626
|
" ",
|
|
2534
2627
|
c === "whatsapp" ? f.t.byWhatsapp : f.t.bySms
|
|
2535
2628
|
] }, c)) }),
|
|
@@ -2576,10 +2669,10 @@ function SessionsPart({ props, when }) {
|
|
|
2576
2669
|
void auth.account.sessions().then(setSessions);
|
|
2577
2670
|
}, []);
|
|
2578
2671
|
const end = async () => {
|
|
2579
|
-
const r = await run(() => auth.account.signOutEverywhere());
|
|
2672
|
+
const r = await run(() => auth.account.signOutEverywhere(), SUBMIT, true);
|
|
2580
2673
|
if (!r.ok) return;
|
|
2581
2674
|
props.onSaved?.({ kind: "sessions.ended" });
|
|
2582
|
-
if (props.onSignedOut) props.onSignedOut();
|
|
2675
|
+
if (props.onSignedOut) f.hold(props.onSignedOut());
|
|
2583
2676
|
else window.location.assign("/");
|
|
2584
2677
|
};
|
|
2585
2678
|
return /* @__PURE__ */ jsxs(Wrap, { f, as: "section", slot: "section", section: "sessions", children: [
|