@auth-link/web 0.0.5 → 1.1.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/CHANGELOG.md +20 -0
- package/README.md +102 -762
- package/dist/index.js +469 -155
- package/dist/index.js.map +3 -3
- package/dist/react.js +473 -152
- package/dist/react.js.map +3 -3
- package/dist/styles.css +6 -0
- package/dist/types/core.d.ts +2 -0
- package/dist/types/i18n.d.ts +1 -1
- package/dist/types/index.d.ts +2 -0
- package/dist/types/modal.d.ts +2 -0
- package/dist/types/passcode.d.ts +29 -0
- package/dist/types/react.d.ts +4 -0
- package/dist/types/types.d.ts +2 -1
- package/dist/types/view.d.ts +4 -0
- package/dist/types/vue.d.ts +4 -0
- package/dist/vue.js +485 -152
- package/dist/vue.js.map +3 -3
- package/docs/README.en.md +36 -256
- package/docs/README.ja.md +36 -256
- package/docs/README.zh-CN.md +36 -256
- package/examples/react-client.tsx +16 -34
- package/examples/vue-client.vue +22 -46
- package/package.json +1 -1
package/dist/react.js
CHANGED
|
@@ -1679,10 +1679,9 @@ function validateTicket(value, expectedMode, trustedOrigin) {
|
|
|
1679
1679
|
}
|
|
1680
1680
|
if (qr.v !== 1 || qr.requestId !== m.requestId || typeof qr.token !== "string" || !token.test(qr.token) || origin.protocol !== "https:" || origin.origin !== qr.origin || origin.origin.length > 512 || origin.username || origin.password || trustedOrigin && origin.origin !== trustedOrigin) fail("UNTRUSTED_QR");
|
|
1681
1681
|
const displayCode = m.displayCode === void 0 ? void 0 : validateDisplayCode(m.displayCode);
|
|
1682
|
-
if (m.purpose === "confirm" && !displayCode) fail("DYNAMIC_CODE_REQUIRED");
|
|
1683
1682
|
const expiry = Date.parse(String(m.expiresAt));
|
|
1684
1683
|
const now = displayCode ? Date.parse(displayCode.serverTime) : Date.now();
|
|
1685
|
-
if (!Number.isFinite(expiry) || expiry > now +
|
|
1684
|
+
if (!Number.isFinite(expiry) || expiry > now + 36e4) fail("INVALID_EXPIRY");
|
|
1686
1685
|
return {
|
|
1687
1686
|
requestId: m.requestId,
|
|
1688
1687
|
purpose: m.purpose,
|
|
@@ -1714,116 +1713,117 @@ function abortable(promise, signal) {
|
|
|
1714
1713
|
}
|
|
1715
1714
|
async function observeRequest(input, options) {
|
|
1716
1715
|
const { client, signal, onUpdate } = options;
|
|
1717
|
-
const interval = options.intervalMs ?? 1500;
|
|
1718
1716
|
let ticket;
|
|
1719
1717
|
try {
|
|
1720
|
-
if (interval < 250 || interval > 1e4 || !Number.isFinite(interval)) fail("INVALID_INTERVAL");
|
|
1721
1718
|
ticket = validateTicket(input, options.expectedMode);
|
|
1722
1719
|
} catch (error) {
|
|
1723
|
-
if (!signal.aborted)
|
|
1724
|
-
const e = error instanceof Error ? error : new AuthLinkError("INVALID_TICKET");
|
|
1725
|
-
onUpdate({ ...initialSnapshot(), status: "error", error: e });
|
|
1726
|
-
options.onError?.(e);
|
|
1727
|
-
}
|
|
1720
|
+
if (!signal.aborted) options.onError?.(error);
|
|
1728
1721
|
return;
|
|
1729
1722
|
}
|
|
1730
|
-
let frame = ticket.displayCode;
|
|
1731
|
-
let serverAnchor = frame ? Date.parse(frame.serverTime) : Date.now();
|
|
1732
|
-
let monotonicAnchor = performance.now();
|
|
1733
|
-
const serverNow = () => serverAnchor + performance.now() - monotonicAnchor;
|
|
1734
1723
|
const expiry = Date.parse(ticket.expiresAt);
|
|
1735
|
-
|
|
1724
|
+
const deadline = performance.now() + Math.max(0, expiry - Date.now());
|
|
1725
|
+
let ended = false, busy = false;
|
|
1726
|
+
let done;
|
|
1727
|
+
const finished = new Promise((resolve) => {
|
|
1728
|
+
done = resolve;
|
|
1729
|
+
});
|
|
1736
1730
|
const controller = new AbortController();
|
|
1737
|
-
const cancel = () =>
|
|
1738
|
-
|
|
1739
|
-
|
|
1740
|
-
|
|
1741
|
-
const update = (value) => {
|
|
1742
|
-
if (signal.aborted) return;
|
|
1743
|
-
if (JSON.stringify(value) !== JSON.stringify(last)) {
|
|
1744
|
-
last = value;
|
|
1745
|
-
onUpdate(value);
|
|
1746
|
-
}
|
|
1731
|
+
const cancel = () => {
|
|
1732
|
+
ended = true;
|
|
1733
|
+
controller.abort();
|
|
1734
|
+
done();
|
|
1747
1735
|
};
|
|
1736
|
+
signal.addEventListener("abort", cancel, { once: true });
|
|
1737
|
+
let snapshot = initialSnapshot();
|
|
1738
|
+
const remaining = () => Math.max(0, (deadline - performance.now()) / 1e3);
|
|
1748
1739
|
const tick = () => {
|
|
1749
1740
|
if (ended || signal.aborted) return;
|
|
1750
|
-
|
|
1751
|
-
|
|
1752
|
-
controller.abort(
|
|
1741
|
+
if (remaining() <= 0) {
|
|
1742
|
+
ended = true;
|
|
1743
|
+
controller.abort();
|
|
1744
|
+
onUpdate({ ...snapshot, status: "expired", code: null, submitting: false });
|
|
1745
|
+
void Promise.resolve().then(() => options.onExpired?.()).catch(() => options.onError?.(new AuthLinkError("CALLBACK_FAILED")));
|
|
1746
|
+
done();
|
|
1753
1747
|
return;
|
|
1754
1748
|
}
|
|
1755
|
-
|
|
1756
|
-
|
|
1757
|
-
update({
|
|
1749
|
+
snapshot = {
|
|
1750
|
+
...snapshot,
|
|
1758
1751
|
status: "pending",
|
|
1759
|
-
code:
|
|
1760
|
-
secondsRemaining: Math.
|
|
1761
|
-
codeSecondsRemaining: Math.ceil(
|
|
1762
|
-
|
|
1763
|
-
}
|
|
1752
|
+
code: ticket.pairingCode,
|
|
1753
|
+
secondsRemaining: Math.ceil(remaining()),
|
|
1754
|
+
codeSecondsRemaining: Math.ceil(remaining()),
|
|
1755
|
+
submitting: busy
|
|
1756
|
+
};
|
|
1757
|
+
onUpdate(snapshot);
|
|
1764
1758
|
};
|
|
1765
|
-
const
|
|
1766
|
-
|
|
1767
|
-
if (
|
|
1768
|
-
|
|
1769
|
-
|
|
1770
|
-
|
|
1771
|
-
let effect = void 0;
|
|
1772
|
-
if (status === "confirmed") effect = options.onConfirmed?.(result);
|
|
1773
|
-
else if (status === "rejected") effect = options.onRejected?.({ status: "rejected", code: "REJECTED", requestId: ticket.requestId, purpose: ticket.purpose });
|
|
1774
|
-
else if (status === "expired") effect = options.onExpired?.();
|
|
1775
|
-
else options.onError?.(error);
|
|
1776
|
-
void Promise.resolve(effect).catch(() => {
|
|
1777
|
-
if (!signal.aborted) options.onError?.(new AuthLinkError("CALLBACK_FAILED"));
|
|
1778
|
-
});
|
|
1779
|
-
} catch {
|
|
1780
|
-
if (status !== "error") options.onError?.(new AuthLinkError("CALLBACK_FAILED"));
|
|
1759
|
+
const submit = async (confirmationCode) => {
|
|
1760
|
+
if (ended || signal.aborted || busy) return;
|
|
1761
|
+
if (!/^[0-9]{6}$/.test(confirmationCode)) {
|
|
1762
|
+
snapshot = { ...snapshot, error: new AuthLinkError("CONFIRMATION_CODE_REQUIRED") };
|
|
1763
|
+
tick();
|
|
1764
|
+
return;
|
|
1781
1765
|
}
|
|
1782
|
-
|
|
1783
|
-
|
|
1766
|
+
if (remaining() <= 0) {
|
|
1767
|
+
tick();
|
|
1768
|
+
return;
|
|
1769
|
+
}
|
|
1770
|
+
busy = true;
|
|
1771
|
+
snapshot = { ...snapshot, error: null };
|
|
1784
1772
|
tick();
|
|
1785
|
-
|
|
1786
|
-
controller.signal.
|
|
1787
|
-
|
|
1788
|
-
controller.signal.throwIfAborted();
|
|
1773
|
+
try {
|
|
1774
|
+
const value = object(await abortable(client.result(ticket, controller.signal, confirmationCode), controller.signal));
|
|
1775
|
+
if (ended || signal.aborted) return;
|
|
1789
1776
|
if (value.requestId !== ticket.requestId) fail("REQUEST_MISMATCH");
|
|
1790
1777
|
if (value.status === "confirmed") {
|
|
1791
|
-
if (!token.test(String(value.verificationId)) ||
|
|
1792
|
-
|
|
1793
|
-
|
|
1794
|
-
|
|
1795
|
-
|
|
1796
|
-
|
|
1797
|
-
|
|
1798
|
-
}
|
|
1799
|
-
if (!["new", "pending", "approved", "consumed"].includes(String(value.status))) fail("INVALID_RESPONSE");
|
|
1800
|
-
if (value.displayCode !== void 0) {
|
|
1801
|
-
const nextFrame = validateDisplayCode(value.displayCode);
|
|
1802
|
-
const nextExpiry = Date.parse(nextFrame.validUntil);
|
|
1803
|
-
const currentExpiry = frame ? Date.parse(frame.validUntil) : 0;
|
|
1804
|
-
if (!frame || nextExpiry > currentExpiry) {
|
|
1805
|
-
serverAnchor = Math.max(serverNow(), Date.parse(nextFrame.serverTime));
|
|
1806
|
-
monotonicAnchor = performance.now();
|
|
1778
|
+
if (!token.test(String(value.verificationId)) || value.authenticationPolicy !== "device-presence.v1" || value.expiresAt !== ticket.expiresAt || value.purpose !== ticket.purpose || remaining() <= 0 || "action" in value || "transactionHash" in value) fail("INVALID_CONFIRMATION");
|
|
1779
|
+
ended = true;
|
|
1780
|
+
onUpdate({ ...snapshot, status: "confirmed", code: null, submitting: false });
|
|
1781
|
+
try {
|
|
1782
|
+
await options.onConfirmed?.(value);
|
|
1783
|
+
} catch {
|
|
1784
|
+
options.onError?.(new AuthLinkError("CALLBACK_FAILED"));
|
|
1807
1785
|
}
|
|
1808
|
-
|
|
1786
|
+
done();
|
|
1787
|
+
} else if (value.status === "rejected" || value.status === "expired") {
|
|
1788
|
+
ended = true;
|
|
1789
|
+
onUpdate({ ...snapshot, status: value.status, code: null, submitting: false });
|
|
1790
|
+
try {
|
|
1791
|
+
if (value.status === "rejected") await options.onRejected?.({ status: "rejected", code: "REJECTED", requestId: ticket.requestId, purpose: ticket.purpose });
|
|
1792
|
+
else await options.onExpired?.();
|
|
1793
|
+
} catch {
|
|
1794
|
+
options.onError?.(new AuthLinkError("CALLBACK_FAILED"));
|
|
1795
|
+
} finally {
|
|
1796
|
+
done();
|
|
1797
|
+
}
|
|
1798
|
+
} else {
|
|
1799
|
+
fail("CONFIRMATION_NOT_READY");
|
|
1809
1800
|
}
|
|
1810
|
-
|
|
1811
|
-
|
|
1812
|
-
|
|
1813
|
-
|
|
1814
|
-
|
|
1815
|
-
|
|
1816
|
-
|
|
1817
|
-
|
|
1801
|
+
} catch (error) {
|
|
1802
|
+
if (!ended && !signal.aborted) {
|
|
1803
|
+
const raw = error instanceof Error ? error : new AuthLinkError("NETWORK_ERROR");
|
|
1804
|
+
const code = raw.message.replace(/^AUTHLINK_/, "");
|
|
1805
|
+
const failure = ["CONFIRMATION_CODE_LOCKED", "CONFIRMATION_CODE_INVALID", "APPROVAL_REQUIRED", "REQUEST_EXPIRED"].includes(code) ? new AuthLinkError(code) : raw;
|
|
1806
|
+
snapshot = { ...snapshot, error: failure };
|
|
1807
|
+
if (code === "CONFIRMATION_CODE_LOCKED" || code === "REQUEST_EXPIRED") {
|
|
1808
|
+
ended = true;
|
|
1809
|
+
onUpdate({ ...snapshot, code: null, submitting: false, status: code === "REQUEST_EXPIRED" ? "expired" : "error" });
|
|
1810
|
+
if (code === "REQUEST_EXPIRED") void Promise.resolve().then(() => options.onExpired?.()).catch(() => options.onError?.(new AuthLinkError("CALLBACK_FAILED")));
|
|
1811
|
+
else options.onError?.(failure);
|
|
1812
|
+
done();
|
|
1813
|
+
} else options.onError?.(failure);
|
|
1818
1814
|
}
|
|
1815
|
+
} finally {
|
|
1816
|
+
busy = false;
|
|
1817
|
+
tick();
|
|
1819
1818
|
}
|
|
1820
|
-
}
|
|
1821
|
-
|
|
1822
|
-
|
|
1823
|
-
|
|
1824
|
-
|
|
1819
|
+
};
|
|
1820
|
+
tick();
|
|
1821
|
+
options.onReady?.(submit);
|
|
1822
|
+
const timer = setInterval(tick, 1e3);
|
|
1823
|
+
if (signal.aborted) cancel();
|
|
1824
|
+
try {
|
|
1825
|
+
await finished;
|
|
1825
1826
|
} finally {
|
|
1826
|
-
ended = true;
|
|
1827
1827
|
clearInterval(timer);
|
|
1828
1828
|
controller.abort();
|
|
1829
1829
|
signal.removeEventListener("abort", cancel);
|
|
@@ -1835,8 +1835,8 @@ var en_default = {
|
|
|
1835
1835
|
bind: "Bind your phone",
|
|
1836
1836
|
confirm: "Confirm verification",
|
|
1837
1837
|
scan: "Scan with AuthLink",
|
|
1838
|
-
code: "Matching
|
|
1839
|
-
help: "
|
|
1838
|
+
code: "Matching digits",
|
|
1839
|
+
help: "Approve in the App, then enter its 6-digit confirmation code here.",
|
|
1840
1840
|
waiting: "Waiting for your phone",
|
|
1841
1841
|
loading: "Connecting",
|
|
1842
1842
|
confirmed: "Confirmed",
|
|
@@ -1849,7 +1849,16 @@ var en_default = {
|
|
|
1849
1849
|
close: "Close",
|
|
1850
1850
|
cancel: "Cancel",
|
|
1851
1851
|
autoUpdate: "Code updates automatically every 30 seconds",
|
|
1852
|
-
expiring: "Request expiring soon"
|
|
1852
|
+
expiring: "Request expiring soon",
|
|
1853
|
+
confirmationCode: "App confirmation code",
|
|
1854
|
+
submitCode: "Verify",
|
|
1855
|
+
codeError: "The code could not be verified. Check the code and approval, then retry.",
|
|
1856
|
+
codeLocked: "Too many incorrect codes. Close this window and start a new request.",
|
|
1857
|
+
otpCode: "App verification code",
|
|
1858
|
+
otpHelp: "Open AuthLink and enter this account\u2019s current six-digit code. No approval is needed.",
|
|
1859
|
+
otpWaiting: "Enter the current code",
|
|
1860
|
+
otpError: "Verification failed. Check the account; wait for a new code if already used. After repeated failures, try again later.",
|
|
1861
|
+
otpSetup: "Enable verification codes on this account\u2019s card in the app first."
|
|
1853
1862
|
};
|
|
1854
1863
|
|
|
1855
1864
|
// src/locales/zh-CN.json
|
|
@@ -1857,8 +1866,8 @@ var zh_CN_default = {
|
|
|
1857
1866
|
bind: "\u7ED1\u5B9A\u624B\u673A",
|
|
1858
1867
|
confirm: "\u786E\u8BA4\u8EAB\u4EFD\u9A8C\u8BC1",
|
|
1859
1868
|
scan: "\u4F7F\u7528 AuthLink \u626B\u63CF\u4E8C\u7EF4\u7801",
|
|
1860
|
-
code: "\
|
|
1861
|
-
help: "\
|
|
1869
|
+
code: "\u6838\u5BF9\u6570\u5B57",
|
|
1870
|
+
help: "\u5728 App \u6838\u5BF9\u5E76\u6279\u51C6\u540E\uFF0C\u5C06 App \u663E\u793A\u7684 6 \u4F4D\u786E\u8BA4\u7801\u8F93\u5165\u4E0B\u65B9\u3002",
|
|
1862
1871
|
waiting: "\u7B49\u5F85\u624B\u673A\u786E\u8BA4",
|
|
1863
1872
|
loading: "\u6B63\u5728\u8FDE\u63A5",
|
|
1864
1873
|
confirmed: "\u5DF2\u786E\u8BA4",
|
|
@@ -1871,7 +1880,16 @@ var zh_CN_default = {
|
|
|
1871
1880
|
close: "\u5173\u95ED",
|
|
1872
1881
|
cancel: "\u53D6\u6D88",
|
|
1873
1882
|
autoUpdate: "\u6838\u5BF9\u7801\u6BCF 30 \u79D2\u81EA\u52A8\u66F4\u65B0",
|
|
1874
|
-
expiring: "\u8BF7\u6C42\u5373\u5C06\u8FC7\u671F"
|
|
1883
|
+
expiring: "\u8BF7\u6C42\u5373\u5C06\u8FC7\u671F",
|
|
1884
|
+
confirmationCode: "App \u786E\u8BA4\u7801",
|
|
1885
|
+
submitCode: "\u63D0\u4EA4\u9A8C\u8BC1",
|
|
1886
|
+
codeError: "\u9A8C\u8BC1\u672A\u901A\u8FC7\uFF0C\u8BF7\u68C0\u67E5\u786E\u8BA4\u7801\u548C\u624B\u673A\u6279\u51C6\u72B6\u6001\u540E\u91CD\u8BD5\u3002",
|
|
1887
|
+
codeLocked: "\u786E\u8BA4\u7801\u8F93\u5165\u9519\u8BEF\u6B21\u6570\u8FC7\u591A\uFF0C\u8BF7\u5173\u95ED\u7A97\u53E3\u540E\u91CD\u65B0\u53D1\u8D77\u8BF7\u6C42\u3002",
|
|
1888
|
+
otpCode: "App \u52A8\u6001\u7801",
|
|
1889
|
+
otpHelp: "\u6253\u5F00 AuthLink\uFF0C\u8F93\u5165\u8BE5\u8D26\u53F7\u5F53\u524D\u7684\u516D\u4F4D\u52A8\u6001\u7801\uFF0C\u65E0\u9700\u6279\u51C6\u8BF7\u6C42\u3002",
|
|
1890
|
+
otpWaiting: "\u8BF7\u8F93\u5165\u5F53\u524D\u52A8\u6001\u7801",
|
|
1891
|
+
otpError: "\u9A8C\u8BC1\u672A\u901A\u8FC7\u3002\u8BF7\u6838\u5BF9\u8D26\u53F7\uFF1B\u5DF2\u4F7F\u7528\u7684\u7801\u9700\u7B49\u5F85\u66F4\u65B0\uFF0C\u591A\u6B21\u5931\u8D25\u8BF7\u7A0D\u540E\u91CD\u8BD5\u3002",
|
|
1892
|
+
otpSetup: "\u8BF7\u5148\u5728 App \u7684\u8D26\u53F7\u5361\u7247\u4E2D\u542F\u7528\u52A8\u6001\u7801\u3002"
|
|
1875
1893
|
};
|
|
1876
1894
|
|
|
1877
1895
|
// src/locales/zh-TW.json
|
|
@@ -1879,8 +1897,8 @@ var zh_TW_default = {
|
|
|
1879
1897
|
bind: "\u7D81\u5B9A\u624B\u6A5F",
|
|
1880
1898
|
confirm: "\u78BA\u8A8D\u8EAB\u5206\u9A57\u8B49",
|
|
1881
1899
|
scan: "\u4F7F\u7528 AuthLink \u6383\u63CF QR \u78BC",
|
|
1882
|
-
code: "\
|
|
1883
|
-
help: "\
|
|
1900
|
+
code: "\u6838\u5C0D\u6578\u5B57",
|
|
1901
|
+
help: "\u5728 App \u6838\u5C0D\u4E26\u6279\u51C6\u5F8C\uFF0C\u5C07 App \u986F\u793A\u7684 6 \u4F4D\u78BA\u8A8D\u78BC\u8F38\u5165\u4E0B\u65B9\u3002",
|
|
1884
1902
|
waiting: "\u7B49\u5F85\u624B\u6A5F\u78BA\u8A8D",
|
|
1885
1903
|
loading: "\u6B63\u5728\u9023\u7DDA",
|
|
1886
1904
|
confirmed: "\u5DF2\u78BA\u8A8D",
|
|
@@ -1893,7 +1911,16 @@ var zh_TW_default = {
|
|
|
1893
1911
|
close: "\u95DC\u9589",
|
|
1894
1912
|
cancel: "\u53D6\u6D88",
|
|
1895
1913
|
autoUpdate: "\u6838\u5C0D\u78BC\u6BCF 30 \u79D2\u81EA\u52D5\u66F4\u65B0",
|
|
1896
|
-
expiring: "\u8ACB\u6C42\u5373\u5C07\u5230\u671F"
|
|
1914
|
+
expiring: "\u8ACB\u6C42\u5373\u5C07\u5230\u671F",
|
|
1915
|
+
confirmationCode: "App \u78BA\u8A8D\u78BC",
|
|
1916
|
+
submitCode: "\u63D0\u4EA4\u9A57\u8B49",
|
|
1917
|
+
codeError: "\u9A57\u8B49\u672A\u901A\u904E\uFF0C\u8ACB\u6AA2\u67E5\u78BA\u8A8D\u78BC\u53CA\u624B\u6A5F\u6279\u51C6\u72C0\u614B\u5F8C\u91CD\u8A66\u3002",
|
|
1918
|
+
codeLocked: "\u78BA\u8A8D\u78BC\u8F38\u5165\u932F\u8AA4\u6B21\u6578\u904E\u591A\uFF0C\u8ACB\u95DC\u9589\u8996\u7A97\u5F8C\u91CD\u65B0\u767C\u8D77\u8ACB\u6C42\u3002",
|
|
1919
|
+
otpCode: "App \u52D5\u614B\u78BC",
|
|
1920
|
+
otpHelp: "\u958B\u555F AuthLink\uFF0C\u8F38\u5165\u6B64\u5E33\u865F\u76EE\u524D\u7684\u516D\u4F4D\u52D5\u614B\u78BC\uFF0C\u7121\u9700\u6279\u51C6\u8ACB\u6C42\u3002",
|
|
1921
|
+
otpWaiting: "\u8ACB\u8F38\u5165\u76EE\u524D\u7684\u52D5\u614B\u78BC",
|
|
1922
|
+
otpError: "\u9A57\u8B49\u672A\u901A\u904E\u3002\u8ACB\u6838\u5C0D\u5E33\u865F\uFF1B\u5DF2\u4F7F\u7528\u7684\u78BC\u9700\u7B49\u5F85\u66F4\u65B0\uFF0C\u591A\u6B21\u5931\u6557\u8ACB\u7A0D\u5F8C\u91CD\u8A66\u3002",
|
|
1923
|
+
otpSetup: "\u8ACB\u5148\u5728 App \u7684\u5E33\u865F\u5361\u7247\u4E2D\u555F\u7528\u52D5\u614B\u78BC\u3002"
|
|
1897
1924
|
};
|
|
1898
1925
|
|
|
1899
1926
|
// src/locales/ja.json
|
|
@@ -1901,8 +1928,8 @@ var ja_default = {
|
|
|
1901
1928
|
bind: "\u30B9\u30DE\u30FC\u30C8\u30D5\u30A9\u30F3\u3092\u767B\u9332",
|
|
1902
1929
|
confirm: "\u672C\u4EBA\u78BA\u8A8D",
|
|
1903
1930
|
scan: "AuthLink \u3067 QR \u30B3\u30FC\u30C9\u3092\u30B9\u30AD\u30E3\u30F3",
|
|
1904
|
-
code: "\u7167\u5408\
|
|
1905
|
-
help: "\
|
|
1931
|
+
code: "\u7167\u5408\u7528\u306E\u6570\u5B57",
|
|
1932
|
+
help: "App \u3067\u627F\u8A8D\u3057\u305F\u5F8C\u3001\u8868\u793A\u3055\u308C\u305F6\u6841\u306E\u78BA\u8A8D\u30B3\u30FC\u30C9\u3092\u5165\u529B\u3057\u3066\u304F\u3060\u3055\u3044\u3002",
|
|
1906
1933
|
waiting: "\u30B9\u30DE\u30FC\u30C8\u30D5\u30A9\u30F3\u306E\u78BA\u8A8D\u3092\u5F85\u3063\u3066\u3044\u307E\u3059",
|
|
1907
1934
|
loading: "\u63A5\u7D9A\u4E2D",
|
|
1908
1935
|
confirmed: "\u78BA\u8A8D\u6E08\u307F",
|
|
@@ -1915,7 +1942,16 @@ var ja_default = {
|
|
|
1915
1942
|
close: "\u9589\u3058\u308B",
|
|
1916
1943
|
cancel: "\u30AD\u30E3\u30F3\u30BB\u30EB",
|
|
1917
1944
|
autoUpdate: "\u7167\u5408\u30B3\u30FC\u30C9\u306F30\u79D2\u3054\u3068\u306B\u81EA\u52D5\u66F4\u65B0",
|
|
1918
|
-
expiring: "\u30EA\u30AF\u30A8\u30B9\u30C8\u306E\u6709\u52B9\u671F\u9650\u304C\u307E\u3082\u306A\u304F\u5207\u308C\u307E\u3059"
|
|
1945
|
+
expiring: "\u30EA\u30AF\u30A8\u30B9\u30C8\u306E\u6709\u52B9\u671F\u9650\u304C\u307E\u3082\u306A\u304F\u5207\u308C\u307E\u3059",
|
|
1946
|
+
confirmationCode: "App \u306E\u78BA\u8A8D\u30B3\u30FC\u30C9",
|
|
1947
|
+
submitCode: "\u78BA\u8A8D\u3059\u308B",
|
|
1948
|
+
codeError: "\u78BA\u8A8D\u3067\u304D\u307E\u305B\u3093\u3067\u3057\u305F\u3002\u30B3\u30FC\u30C9\u3068\u627F\u8A8D\u72B6\u6CC1\u3092\u78BA\u8A8D\u3057\u3066\u518D\u8A66\u884C\u3057\u3066\u304F\u3060\u3055\u3044\u3002",
|
|
1949
|
+
codeLocked: "\u30B3\u30FC\u30C9\u306E\u8AA4\u5165\u529B\u304C\u591A\u3059\u304E\u307E\u3059\u3002\u753B\u9762\u3092\u9589\u3058\u3001\u65B0\u3057\u3044\u30EA\u30AF\u30A8\u30B9\u30C8\u3092\u958B\u59CB\u3057\u3066\u304F\u3060\u3055\u3044\u3002",
|
|
1950
|
+
otpCode: "\u30A2\u30D7\u30EA\u306E\u8A8D\u8A3C\u30B3\u30FC\u30C9",
|
|
1951
|
+
otpHelp: "AuthLink \u3092\u958B\u304D\u3001\u3053\u306E\u30A2\u30AB\u30A6\u30F3\u30C8\u306E\u73FE\u5728\u306E6\u6841\u30B3\u30FC\u30C9\u3092\u5165\u529B\u3057\u3066\u304F\u3060\u3055\u3044\u3002\u627F\u8A8D\u64CD\u4F5C\u306F\u4E0D\u8981\u3067\u3059\u3002",
|
|
1952
|
+
otpWaiting: "\u73FE\u5728\u306E\u30B3\u30FC\u30C9\u3092\u5165\u529B",
|
|
1953
|
+
otpError: "\u8A8D\u8A3C\u3067\u304D\u307E\u305B\u3093\u3067\u3057\u305F\u3002\u30A2\u30AB\u30A6\u30F3\u30C8\u3092\u78BA\u8A8D\u3057\u3001\u4F7F\u7528\u6E08\u307F\u306A\u3089\u6B21\u306E\u30B3\u30FC\u30C9\u3092\u5F85\u3063\u3066\u304F\u3060\u3055\u3044\u3002\u5931\u6557\u304C\u7D9A\u304F\u5834\u5408\u306F\u6642\u9593\u3092\u304A\u3044\u3066\u518D\u8A66\u884C\u3057\u3066\u304F\u3060\u3055\u3044\u3002",
|
|
1954
|
+
otpSetup: "\u5148\u306B\u30A2\u30D7\u30EA\u306E\u30A2\u30AB\u30A6\u30F3\u30C8\u753B\u9762\u3067\u8A8D\u8A3C\u30B3\u30FC\u30C9\u3092\u6709\u52B9\u306B\u3057\u3066\u304F\u3060\u3055\u3044\u3002"
|
|
1919
1955
|
};
|
|
1920
1956
|
|
|
1921
1957
|
// src/locales/bn.json
|
|
@@ -1924,7 +1960,7 @@ var bn_default = {
|
|
|
1924
1960
|
confirm: "\u09AF\u09BE\u099A\u09BE\u0987\u0995\u09B0\u09A3 \u09A8\u09BF\u09B6\u09CD\u099A\u09BF\u09A4 \u0995\u09B0\u09C1\u09A8",
|
|
1925
1961
|
scan: "AuthLink \u09A6\u09BF\u09AF\u09BC\u09C7 \u09B8\u09CD\u0995\u09CD\u09AF\u09BE\u09A8 \u0995\u09B0\u09C1\u09A8",
|
|
1926
1962
|
code: "\u09AE\u09BF\u09B2\u09BF\u09AF\u09BC\u09C7 \u09A6\u09C7\u0996\u09BE\u09B0 \u0995\u09CB\u09A1",
|
|
1927
|
-
help: "\u0985\u09CD\u09AF\u09BE\u09AA\u09C7
|
|
1963
|
+
help: "\u0985\u09CD\u09AF\u09BE\u09AA\u09C7 \u0985\u09A8\u09C1\u09AE\u09CB\u09A6\u09A8 \u09A6\u09BF\u09A8, \u09A4\u09BE\u09B0\u09AA\u09B0 \u098F\u0996\u09BE\u09A8\u09C7 \u09EC \u09B8\u0982\u0996\u09CD\u09AF\u09BE\u09B0 \u09A8\u09BF\u09B6\u09CD\u099A\u09BF\u09A4\u0995\u09B0\u09A3 \u0995\u09CB\u09A1 \u09B2\u09BF\u0996\u09C1\u09A8\u0964",
|
|
1928
1964
|
waiting: "\u09AB\u09CB\u09A8\u09C7 \u09A8\u09BF\u09B6\u09CD\u099A\u09BF\u09A4\u0995\u09B0\u09A3\u09C7\u09B0 \u0985\u09AA\u09C7\u0995\u09CD\u09B7\u09BE\u09AF\u09BC",
|
|
1929
1965
|
loading: "\u09B8\u0982\u09AF\u09CB\u0997 \u0995\u09B0\u09BE \u09B9\u099A\u09CD\u099B\u09C7",
|
|
1930
1966
|
confirmed: "\u09A8\u09BF\u09B6\u09CD\u099A\u09BF\u09A4 \u09B9\u09AF\u09BC\u09C7\u099B\u09C7",
|
|
@@ -1937,7 +1973,16 @@ var bn_default = {
|
|
|
1937
1973
|
close: "\u09AC\u09A8\u09CD\u09A7 \u0995\u09B0\u09C1\u09A8",
|
|
1938
1974
|
cancel: "\u09AC\u09BE\u09A4\u09BF\u09B2",
|
|
1939
1975
|
autoUpdate: "\u0995\u09CB\u09A1 \u09AA\u09CD\u09B0\u09A4\u09BF \u09E9\u09E6 \u09B8\u09C7\u0995\u09C7\u09A8\u09CD\u09A1\u09C7 \u09B8\u09CD\u09AC\u09AF\u09BC\u0982\u0995\u09CD\u09B0\u09BF\u09AF\u09BC\u09AD\u09BE\u09AC\u09C7 \u09AC\u09A6\u09B2\u09BE\u09AF\u09BC",
|
|
1940
|
-
expiring: "\u0985\u09A8\u09C1\u09B0\u09CB\u09A7\u09C7\u09B0 \u09AE\u09C7\u09AF\u09BC\u09BE\u09A6 \u09B6\u09C0\u0998\u09CD\u09B0\u0987 \u09B6\u09C7\u09B7 \u09B9\u09AC\u09C7"
|
|
1976
|
+
expiring: "\u0985\u09A8\u09C1\u09B0\u09CB\u09A7\u09C7\u09B0 \u09AE\u09C7\u09AF\u09BC\u09BE\u09A6 \u09B6\u09C0\u0998\u09CD\u09B0\u0987 \u09B6\u09C7\u09B7 \u09B9\u09AC\u09C7",
|
|
1977
|
+
confirmationCode: "\u0985\u09CD\u09AF\u09BE\u09AA\u09C7\u09B0 \u09A8\u09BF\u09B6\u09CD\u099A\u09BF\u09A4\u0995\u09B0\u09A3 \u0995\u09CB\u09A1",
|
|
1978
|
+
submitCode: "\u09AF\u09BE\u099A\u09BE\u0987 \u0995\u09B0\u09C1\u09A8",
|
|
1979
|
+
codeError: "\u09AF\u09BE\u099A\u09BE\u0987 \u0995\u09B0\u09BE \u09AF\u09BE\u09AF\u09BC\u09A8\u09BF\u0964 \u0995\u09CB\u09A1 \u0993 \u0985\u09A8\u09C1\u09AE\u09CB\u09A6\u09A8 \u09AA\u09B0\u09C0\u0995\u09CD\u09B7\u09BE \u0995\u09B0\u09C7 \u0986\u09AC\u09BE\u09B0 \u099A\u09C7\u09B7\u09CD\u099F\u09BE \u0995\u09B0\u09C1\u09A8\u0964",
|
|
1980
|
+
codeLocked: "\u0985\u09A8\u09C7\u0995\u09AC\u09BE\u09B0 \u09AD\u09C1\u09B2 \u0995\u09CB\u09A1 \u09A6\u09C7\u0993\u09AF\u09BC\u09BE \u09B9\u09AF\u09BC\u09C7\u099B\u09C7\u0964 \u0989\u0987\u09A8\u09CD\u09A1\u09CB \u09AC\u09A8\u09CD\u09A7 \u0995\u09B0\u09C7 \u09A8\u09A4\u09C1\u09A8 \u0985\u09A8\u09C1\u09B0\u09CB\u09A7 \u09B6\u09C1\u09B0\u09C1 \u0995\u09B0\u09C1\u09A8\u0964",
|
|
1981
|
+
otpCode: "\u0985\u09CD\u09AF\u09BE\u09AA\u09C7\u09B0 \u0995\u09CB\u09A1",
|
|
1982
|
+
otpHelp: "AuthLink \u0996\u09C1\u09B2\u09C7 \u098F\u0987 \u0985\u09CD\u09AF\u09BE\u0995\u09BE\u0989\u09A8\u09CD\u099F\u09C7\u09B0 \u09AC\u09B0\u09CD\u09A4\u09AE\u09BE\u09A8 \u099B\u09AF\u09BC \u0985\u0999\u09CD\u0995\u09C7\u09B0 \u0995\u09CB\u09A1 \u09B2\u09BF\u0996\u09C1\u09A8\u0964 \u0985\u09A8\u09C1\u09B0\u09CB\u09A7 \u0985\u09A8\u09C1\u09AE\u09CB\u09A6\u09A8\u09C7\u09B0 \u09AA\u09CD\u09B0\u09AF\u09BC\u09CB\u099C\u09A8 \u09A8\u09C7\u0987\u0964",
|
|
1983
|
+
otpWaiting: "\u09AC\u09B0\u09CD\u09A4\u09AE\u09BE\u09A8 \u0995\u09CB\u09A1 \u09B2\u09BF\u0996\u09C1\u09A8",
|
|
1984
|
+
otpError: "\u09AF\u09BE\u099A\u09BE\u0987 \u09AC\u09CD\u09AF\u09B0\u09CD\u09A5\u0964 \u0985\u09CD\u09AF\u09BE\u0995\u09BE\u0989\u09A8\u09CD\u099F \u09AA\u09B0\u09C0\u0995\u09CD\u09B7\u09BE \u0995\u09B0\u09C1\u09A8 \u098F\u09AC\u0982 \u09AC\u09CD\u09AF\u09AC\u09B9\u09C3\u09A4 \u0995\u09CB\u09A1 \u09B9\u09B2\u09C7 \u09A8\u09A4\u09C1\u09A8 \u0995\u09CB\u09A1\u09C7\u09B0 \u099C\u09A8\u09CD\u09AF \u0985\u09AA\u09C7\u0995\u09CD\u09B7\u09BE \u0995\u09B0\u09C1\u09A8\u0964 \u09AC\u09BE\u09B0\u09AC\u09BE\u09B0 \u09AC\u09CD\u09AF\u09B0\u09CD\u09A5 \u09B9\u09B2\u09C7 \u09AA\u09B0\u09C7 \u099A\u09C7\u09B7\u09CD\u099F\u09BE \u0995\u09B0\u09C1\u09A8\u0964",
|
|
1985
|
+
otpSetup: "\u09AA\u09CD\u09B0\u09A5\u09AE\u09C7 \u0985\u09CD\u09AF\u09BE\u09AA\u09C7 \u098F\u0987 \u0985\u09CD\u09AF\u09BE\u0995\u09BE\u0989\u09A8\u09CD\u099F\u09C7\u09B0 \u0995\u09BE\u09B0\u09CD\u09A1\u09C7 \u0995\u09CB\u09A1 \u099A\u09BE\u09B2\u09C1 \u0995\u09B0\u09C1\u09A8\u0964"
|
|
1941
1986
|
};
|
|
1942
1987
|
|
|
1943
1988
|
// src/locales/es.json
|
|
@@ -1946,7 +1991,7 @@ var es_default = {
|
|
|
1946
1991
|
confirm: "Confirma la verificaci\xF3n",
|
|
1947
1992
|
scan: "Escanea con AuthLink",
|
|
1948
1993
|
code: "C\xF3digo de comparaci\xF3n",
|
|
1949
|
-
help: "
|
|
1994
|
+
help: "Aprueba en la app e introduce aqu\xED su c\xF3digo de 6 d\xEDgitos.",
|
|
1950
1995
|
waiting: "Esperando la confirmaci\xF3n del tel\xE9fono",
|
|
1951
1996
|
loading: "Conectando",
|
|
1952
1997
|
confirmed: "Confirmado",
|
|
@@ -1959,7 +2004,16 @@ var es_default = {
|
|
|
1959
2004
|
close: "Cerrar",
|
|
1960
2005
|
cancel: "Cancelar",
|
|
1961
2006
|
autoUpdate: "El c\xF3digo se actualiza autom\xE1ticamente cada 30 segundos",
|
|
1962
|
-
expiring: "La solicitud est\xE1 por caducar"
|
|
2007
|
+
expiring: "La solicitud est\xE1 por caducar",
|
|
2008
|
+
confirmationCode: "C\xF3digo de confirmaci\xF3n de la app",
|
|
2009
|
+
submitCode: "Verificar",
|
|
2010
|
+
codeError: "No se pudo verificar. Revisa el c\xF3digo y la aprobaci\xF3n.",
|
|
2011
|
+
codeLocked: "Demasiados c\xF3digos incorrectos. Cierra la ventana e inicia una nueva solicitud.",
|
|
2012
|
+
otpCode: "C\xF3digo de la app",
|
|
2013
|
+
otpHelp: "Abre AuthLink e introduce el c\xF3digo actual de seis d\xEDgitos de esta cuenta. No hace falta aprobar una solicitud.",
|
|
2014
|
+
otpWaiting: "Introduce el c\xF3digo actual",
|
|
2015
|
+
otpError: "No se pudo verificar. Comprueba la cuenta y espera un c\xF3digo nuevo si ya lo usaste. Si fallas varias veces, int\xE9ntalo m\xE1s tarde.",
|
|
2016
|
+
otpSetup: "Activa primero los c\xF3digos en la tarjeta de esta cuenta en la app."
|
|
1963
2017
|
};
|
|
1964
2018
|
|
|
1965
2019
|
// src/locales/fil.json
|
|
@@ -1968,7 +2022,7 @@ var fil_default = {
|
|
|
1968
2022
|
confirm: "Kumpirmahin ang pagpapatunay",
|
|
1969
2023
|
scan: "Mag-scan gamit ang AuthLink",
|
|
1970
2024
|
code: "Code na paghahambingin",
|
|
1971
|
-
help: "
|
|
2025
|
+
help: "Aprubahan sa app, saka ilagay dito ang 6-digit na confirmation code.",
|
|
1972
2026
|
waiting: "Hinihintay ang kumpirmasyon sa telepono",
|
|
1973
2027
|
loading: "Kumokonekta",
|
|
1974
2028
|
confirmed: "Nakumpirma",
|
|
@@ -1981,7 +2035,16 @@ var fil_default = {
|
|
|
1981
2035
|
close: "Isara",
|
|
1982
2036
|
cancel: "Kanselahin",
|
|
1983
2037
|
autoUpdate: "Awtomatikong nagbabago ang code kada 30 segundo",
|
|
1984
|
-
expiring: "Malapit nang mag-expire ang kahilingan"
|
|
2038
|
+
expiring: "Malapit nang mag-expire ang kahilingan",
|
|
2039
|
+
confirmationCode: "Confirmation code ng app",
|
|
2040
|
+
submitCode: "I-verify",
|
|
2041
|
+
codeError: "Hindi ma-verify. Suriin ang code at pag-apruba at subukan muli.",
|
|
2042
|
+
codeLocked: "Masyadong maraming maling code. Isara ang window at magsimula ng bagong request.",
|
|
2043
|
+
otpCode: "Code ng app",
|
|
2044
|
+
otpHelp: "Buksan ang AuthLink at ilagay ang kasalukuyang anim na digit na code ng account na ito. Hindi kailangang aprubahan ang request.",
|
|
2045
|
+
otpWaiting: "Ilagay ang kasalukuyang code",
|
|
2046
|
+
otpError: "Hindi napatunayan. Tingnan ang account at maghintay ng bagong code kung nagamit na. Subukang muli mamaya kung maraming maling pagtatangka.",
|
|
2047
|
+
otpSetup: "Paganahin muna ang mga code sa card ng account na ito sa app."
|
|
1985
2048
|
};
|
|
1986
2049
|
|
|
1987
2050
|
// src/locales/hi.json
|
|
@@ -1990,7 +2053,7 @@ var hi_default = {
|
|
|
1990
2053
|
confirm: "\u0938\u0924\u094D\u092F\u093E\u092A\u0928 \u0915\u0940 \u092A\u0941\u0937\u094D\u091F\u093F \u0915\u0930\u0947\u0902",
|
|
1991
2054
|
scan: "AuthLink \u0938\u0947 \u0938\u094D\u0915\u0948\u0928 \u0915\u0930\u0947\u0902",
|
|
1992
2055
|
code: "\u092E\u093F\u0932\u093E\u0928 \u0915\u094B\u0921",
|
|
1993
|
-
help: "\u0910\u092A \u092E\u0947\u0902 \u0938\
|
|
2056
|
+
help: "\u0910\u092A \u092E\u0947\u0902 \u0938\u094D\u0935\u0940\u0915\u0943\u0924\u093F \u0926\u0947\u0902, \u092B\u093F\u0930 \u092F\u0939\u093E\u0901 6 \u0905\u0902\u0915\u094B\u0902 \u0915\u093E \u092A\u0941\u0937\u094D\u091F\u093F \u0915\u094B\u0921 \u0926\u0930\u094D\u091C \u0915\u0930\u0947\u0902\u0964",
|
|
1994
2057
|
waiting: "\u092B\u093C\u094B\u0928 \u092A\u0930 \u092A\u0941\u0937\u094D\u091F\u093F \u0915\u0940 \u092A\u094D\u0930\u0924\u0940\u0915\u094D\u0937\u093E \u0939\u0948",
|
|
1995
2058
|
loading: "\u0915\u0928\u0947\u0915\u094D\u091F \u0939\u094B \u0930\u0939\u093E \u0939\u0948",
|
|
1996
2059
|
confirmed: "\u092A\u0941\u0937\u094D\u091F\u093F \u0939\u094B \u0917\u0908",
|
|
@@ -2003,7 +2066,16 @@ var hi_default = {
|
|
|
2003
2066
|
close: "\u092C\u0902\u0926 \u0915\u0930\u0947\u0902",
|
|
2004
2067
|
cancel: "\u0930\u0926\u094D\u0926 \u0915\u0930\u0947\u0902",
|
|
2005
2068
|
autoUpdate: "\u0915\u094B\u0921 \u0939\u0930 30 \u0938\u0947\u0915\u0902\u0921 \u092E\u0947\u0902 \u0905\u092A\u0928\u0947 \u0906\u092A \u092C\u0926\u0932\u0924\u093E \u0939\u0948",
|
|
2006
|
-
expiring: "\u0905\u0928\u0941\u0930\u094B\u0927 \u0915\u0940 \u0938\u092E\u092F-\u0938\u0940\u092E\u093E \u0938\u092E\u093E\u092A\u094D\u0924 \u0939\u094B\u0928\u0947 \u0935\u093E\u0932\u0940 \u0939\u0948"
|
|
2069
|
+
expiring: "\u0905\u0928\u0941\u0930\u094B\u0927 \u0915\u0940 \u0938\u092E\u092F-\u0938\u0940\u092E\u093E \u0938\u092E\u093E\u092A\u094D\u0924 \u0939\u094B\u0928\u0947 \u0935\u093E\u0932\u0940 \u0939\u0948",
|
|
2070
|
+
confirmationCode: "\u0910\u092A \u0915\u093E \u092A\u0941\u0937\u094D\u091F\u093F \u0915\u094B\u0921",
|
|
2071
|
+
submitCode: "\u0938\u0924\u094D\u092F\u093E\u092A\u093F\u0924 \u0915\u0930\u0947\u0902",
|
|
2072
|
+
codeError: "\u0938\u0924\u094D\u092F\u093E\u092A\u0928 \u0935\u093F\u092B\u0932 \u0930\u0939\u093E\u0964 \u0915\u094B\u0921 \u0914\u0930 \u0938\u094D\u0935\u0940\u0915\u0943\u0924\u093F \u091C\u093E\u0901\u091A\u0915\u0930 \u092A\u0941\u0928\u0903 \u092A\u094D\u0930\u092F\u093E\u0938 \u0915\u0930\u0947\u0902\u0964",
|
|
2073
|
+
codeLocked: "\u092C\u0939\u0941\u0924 \u0905\u0927\u093F\u0915 \u0917\u0932\u0924 \u0915\u094B\u0921\u0964 \u0935\u093F\u0902\u0921\u094B \u092C\u0902\u0926 \u0915\u0930\u0915\u0947 \u0928\u092F\u093E \u0905\u0928\u0941\u0930\u094B\u0927 \u0936\u0941\u0930\u0942 \u0915\u0930\u0947\u0902\u0964",
|
|
2074
|
+
otpCode: "\u0910\u092A \u0915\u093E \u0915\u094B\u0921",
|
|
2075
|
+
otpHelp: "AuthLink \u0916\u094B\u0932\u0947\u0902 \u0914\u0930 \u0907\u0938 \u0916\u093E\u0924\u0947 \u0915\u093E \u0935\u0930\u094D\u0924\u092E\u093E\u0928 \u091B\u0939 \u0905\u0902\u0915\u094B\u0902 \u0915\u093E \u0915\u094B\u0921 \u0926\u0930\u094D\u091C \u0915\u0930\u0947\u0902\u0964 \u0905\u0928\u0941\u0930\u094B\u0927 \u0938\u094D\u0935\u0940\u0915\u0943\u0924 \u0915\u0930\u0928\u0947 \u0915\u0940 \u0906\u0935\u0936\u094D\u092F\u0915\u0924\u093E \u0928\u0939\u0940\u0902 \u0939\u0948\u0964",
|
|
2076
|
+
otpWaiting: "\u0935\u0930\u094D\u0924\u092E\u093E\u0928 \u0915\u094B\u0921 \u0926\u0930\u094D\u091C \u0915\u0930\u0947\u0902",
|
|
2077
|
+
otpError: "\u0938\u0924\u094D\u092F\u093E\u092A\u0928 \u0905\u0938\u092B\u0932\u0964 \u0916\u093E\u0924\u093E \u091C\u093E\u0901\u091A\u0947\u0902 \u0914\u0930 \u0909\u092A\u092F\u094B\u0917 \u0939\u094B \u091A\u0941\u0915\u093E \u0939\u094B \u0924\u094B \u0928\u090F \u0915\u094B\u0921 \u0915\u0940 \u092A\u094D\u0930\u0924\u0940\u0915\u094D\u0937\u093E \u0915\u0930\u0947\u0902\u0964 \u092C\u093E\u0930-\u092C\u093E\u0930 \u0905\u0938\u092B\u0932 \u0939\u094B\u0928\u0947 \u092A\u0930 \u092C\u093E\u0926 \u092E\u0947\u0902 \u092A\u094D\u0930\u092F\u093E\u0938 \u0915\u0930\u0947\u0902\u0964",
|
|
2078
|
+
otpSetup: "\u092A\u0939\u0932\u0947 \u0910\u092A \u092E\u0947\u0902 \u0907\u0938 \u0916\u093E\u0924\u0947 \u0915\u0947 \u0915\u093E\u0930\u094D\u0921 \u092A\u0930 \u0915\u094B\u0921 \u0938\u0915\u094D\u0937\u092E \u0915\u0930\u0947\u0902\u0964"
|
|
2007
2079
|
};
|
|
2008
2080
|
|
|
2009
2081
|
// src/locales/id.json
|
|
@@ -2012,7 +2084,7 @@ var id_default = {
|
|
|
2012
2084
|
confirm: "Konfirmasi verifikasi",
|
|
2013
2085
|
scan: "Pindai dengan AuthLink",
|
|
2014
2086
|
code: "Kode pencocokan",
|
|
2015
|
-
help: "
|
|
2087
|
+
help: "Setujui di aplikasi, lalu masukkan kode konfirmasi 6 digit di sini.",
|
|
2016
2088
|
waiting: "Menunggu konfirmasi dari ponsel",
|
|
2017
2089
|
loading: "Menghubungkan",
|
|
2018
2090
|
confirmed: "Dikonfirmasi",
|
|
@@ -2025,7 +2097,16 @@ var id_default = {
|
|
|
2025
2097
|
close: "Tutup",
|
|
2026
2098
|
cancel: "Batal",
|
|
2027
2099
|
autoUpdate: "Kode diperbarui otomatis setiap 30 detik",
|
|
2028
|
-
expiring: "Permintaan akan segera kedaluwarsa"
|
|
2100
|
+
expiring: "Permintaan akan segera kedaluwarsa",
|
|
2101
|
+
confirmationCode: "Kode konfirmasi aplikasi",
|
|
2102
|
+
submitCode: "Verifikasi",
|
|
2103
|
+
codeError: "Verifikasi gagal. Periksa kode dan persetujuan, lalu coba lagi.",
|
|
2104
|
+
codeLocked: "Terlalu banyak kode salah. Tutup jendela dan mulai permintaan baru.",
|
|
2105
|
+
otpCode: "Kode aplikasi",
|
|
2106
|
+
otpHelp: "Buka AuthLink dan masukkan kode enam digit terkini untuk akun ini. Tidak perlu menyetujui permintaan.",
|
|
2107
|
+
otpWaiting: "Masukkan kode terkini",
|
|
2108
|
+
otpError: "Verifikasi gagal. Periksa akun dan tunggu kode baru jika sudah digunakan. Setelah beberapa kegagalan, coba lagi nanti.",
|
|
2109
|
+
otpSetup: "Aktifkan kode di kartu akun ini dalam aplikasi terlebih dahulu."
|
|
2029
2110
|
};
|
|
2030
2111
|
|
|
2031
2112
|
// src/locales/ms.json
|
|
@@ -2034,7 +2115,7 @@ var ms_default = {
|
|
|
2034
2115
|
confirm: "Sahkan pengesahan",
|
|
2035
2116
|
scan: "Imbas dengan AuthLink",
|
|
2036
2117
|
code: "Kod padanan",
|
|
2037
|
-
help: "
|
|
2118
|
+
help: "Luluskan dalam aplikasi, kemudian masukkan kod pengesahan 6 digit di sini.",
|
|
2038
2119
|
waiting: "Menunggu pengesahan daripada telefon",
|
|
2039
2120
|
loading: "Sedang menyambung",
|
|
2040
2121
|
confirmed: "Disahkan",
|
|
@@ -2047,7 +2128,16 @@ var ms_default = {
|
|
|
2047
2128
|
close: "Tutup",
|
|
2048
2129
|
cancel: "Batal",
|
|
2049
2130
|
autoUpdate: "Kod dikemas kini secara automatik setiap 30 saat",
|
|
2050
|
-
expiring: "Permintaan akan tamat tempoh tidak lama lagi"
|
|
2131
|
+
expiring: "Permintaan akan tamat tempoh tidak lama lagi",
|
|
2132
|
+
confirmationCode: "Kod pengesahan aplikasi",
|
|
2133
|
+
submitCode: "Sahkan",
|
|
2134
|
+
codeError: "Pengesahan gagal. Semak kod dan kelulusan, kemudian cuba lagi.",
|
|
2135
|
+
codeLocked: "Terlalu banyak kod salah. Tutup tetingkap dan mulakan permintaan baharu.",
|
|
2136
|
+
otpCode: "Kod aplikasi",
|
|
2137
|
+
otpHelp: "Buka AuthLink dan masukkan kod enam digit semasa untuk akaun ini. Tiada kelulusan permintaan diperlukan.",
|
|
2138
|
+
otpWaiting: "Masukkan kod semasa",
|
|
2139
|
+
otpError: "Pengesahan gagal. Semak akaun dan tunggu kod baharu jika sudah digunakan. Selepas beberapa kegagalan, cuba lagi kemudian.",
|
|
2140
|
+
otpSetup: "Aktifkan kod pada kad akaun ini dalam aplikasi dahulu."
|
|
2051
2141
|
};
|
|
2052
2142
|
|
|
2053
2143
|
// src/locales/pt.json
|
|
@@ -2056,7 +2146,7 @@ var pt_default = {
|
|
|
2056
2146
|
confirm: "Confirme a verifica\xE7\xE3o",
|
|
2057
2147
|
scan: "Escaneie com o AuthLink",
|
|
2058
2148
|
code: "C\xF3digo de compara\xE7\xE3o",
|
|
2059
|
-
help: "
|
|
2149
|
+
help: "Aprove no app e digite aqui o c\xF3digo de 6 d\xEDgitos.",
|
|
2060
2150
|
waiting: "Aguardando confirma\xE7\xE3o no celular",
|
|
2061
2151
|
loading: "Conectando",
|
|
2062
2152
|
confirmed: "Confirmado",
|
|
@@ -2069,7 +2159,16 @@ var pt_default = {
|
|
|
2069
2159
|
close: "Fechar",
|
|
2070
2160
|
cancel: "Cancelar",
|
|
2071
2161
|
autoUpdate: "O c\xF3digo \xE9 atualizado automaticamente a cada 30 segundos",
|
|
2072
|
-
expiring: "A solicita\xE7\xE3o est\xE1 prestes a expirar"
|
|
2162
|
+
expiring: "A solicita\xE7\xE3o est\xE1 prestes a expirar",
|
|
2163
|
+
confirmationCode: "C\xF3digo de confirma\xE7\xE3o do app",
|
|
2164
|
+
submitCode: "Verificar",
|
|
2165
|
+
codeError: "N\xE3o foi poss\xEDvel verificar. Confira o c\xF3digo e a aprova\xE7\xE3o.",
|
|
2166
|
+
codeLocked: "Muitos c\xF3digos incorretos. Feche a janela e inicie uma nova solicita\xE7\xE3o.",
|
|
2167
|
+
otpCode: "C\xF3digo do aplicativo",
|
|
2168
|
+
otpHelp: "Abra o AuthLink e digite o c\xF3digo atual de seis d\xEDgitos desta conta. N\xE3o \xE9 necess\xE1rio aprovar uma solicita\xE7\xE3o.",
|
|
2169
|
+
otpWaiting: "Digite o c\xF3digo atual",
|
|
2170
|
+
otpError: "Falha na verifica\xE7\xE3o. Confira a conta e aguarde um novo c\xF3digo se j\xE1 o usou. Ap\xF3s v\xE1rias falhas, tente mais tarde.",
|
|
2171
|
+
otpSetup: "Ative primeiro os c\xF3digos no cart\xE3o desta conta no aplicativo."
|
|
2073
2172
|
};
|
|
2074
2173
|
|
|
2075
2174
|
// src/locales/th.json
|
|
@@ -2078,7 +2177,7 @@ var th_default = {
|
|
|
2078
2177
|
confirm: "\u0E22\u0E37\u0E19\u0E22\u0E31\u0E19\u0E01\u0E32\u0E23\u0E15\u0E23\u0E27\u0E08\u0E2A\u0E2D\u0E1A",
|
|
2079
2178
|
scan: "\u0E2A\u0E41\u0E01\u0E19\u0E14\u0E49\u0E27\u0E22 AuthLink",
|
|
2080
2179
|
code: "\u0E23\u0E2B\u0E31\u0E2A\u0E2A\u0E33\u0E2B\u0E23\u0E31\u0E1A\u0E40\u0E1B\u0E23\u0E35\u0E22\u0E1A\u0E40\u0E17\u0E35\u0E22\u0E1A",
|
|
2081
|
-
help: "\
|
|
2180
|
+
help: "\u0E2D\u0E19\u0E38\u0E21\u0E31\u0E15\u0E34\u0E43\u0E19\u0E41\u0E2D\u0E1B \u0E41\u0E25\u0E49\u0E27\u0E01\u0E23\u0E2D\u0E01\u0E23\u0E2B\u0E31\u0E2A\u0E22\u0E37\u0E19\u0E22\u0E31\u0E19 6 \u0E2B\u0E25\u0E31\u0E01\u0E17\u0E35\u0E48\u0E19\u0E35\u0E48",
|
|
2082
2181
|
waiting: "\u0E01\u0E33\u0E25\u0E31\u0E07\u0E23\u0E2D\u0E01\u0E32\u0E23\u0E22\u0E37\u0E19\u0E22\u0E31\u0E19\u0E08\u0E32\u0E01\u0E42\u0E17\u0E23\u0E28\u0E31\u0E1E\u0E17\u0E4C",
|
|
2083
2182
|
loading: "\u0E01\u0E33\u0E25\u0E31\u0E07\u0E40\u0E0A\u0E37\u0E48\u0E2D\u0E21\u0E15\u0E48\u0E2D",
|
|
2084
2183
|
confirmed: "\u0E22\u0E37\u0E19\u0E22\u0E31\u0E19\u0E41\u0E25\u0E49\u0E27",
|
|
@@ -2091,7 +2190,16 @@ var th_default = {
|
|
|
2091
2190
|
close: "\u0E1B\u0E34\u0E14",
|
|
2092
2191
|
cancel: "\u0E22\u0E01\u0E40\u0E25\u0E34\u0E01",
|
|
2093
2192
|
autoUpdate: "\u0E23\u0E2B\u0E31\u0E2A\u0E08\u0E30\u0E2D\u0E31\u0E1B\u0E40\u0E14\u0E15\u0E2D\u0E31\u0E15\u0E42\u0E19\u0E21\u0E31\u0E15\u0E34\u0E17\u0E38\u0E01 30 \u0E27\u0E34\u0E19\u0E32\u0E17\u0E35",
|
|
2094
|
-
expiring: "\u0E04\u0E33\u0E02\u0E2D\u0E43\u0E01\u0E25\u0E49\u0E2B\u0E21\u0E14\u0E2D\u0E32\u0E22\u0E38"
|
|
2193
|
+
expiring: "\u0E04\u0E33\u0E02\u0E2D\u0E43\u0E01\u0E25\u0E49\u0E2B\u0E21\u0E14\u0E2D\u0E32\u0E22\u0E38",
|
|
2194
|
+
confirmationCode: "\u0E23\u0E2B\u0E31\u0E2A\u0E22\u0E37\u0E19\u0E22\u0E31\u0E19\u0E08\u0E32\u0E01\u0E41\u0E2D\u0E1B",
|
|
2195
|
+
submitCode: "\u0E22\u0E37\u0E19\u0E22\u0E31\u0E19",
|
|
2196
|
+
codeError: "\u0E22\u0E37\u0E19\u0E22\u0E31\u0E19\u0E44\u0E21\u0E48\u0E2A\u0E33\u0E40\u0E23\u0E47\u0E08 \u0E15\u0E23\u0E27\u0E08\u0E2A\u0E2D\u0E1A\u0E23\u0E2B\u0E31\u0E2A\u0E41\u0E25\u0E30\u0E01\u0E32\u0E23\u0E2D\u0E19\u0E38\u0E21\u0E31\u0E15\u0E34\u0E41\u0E25\u0E49\u0E27\u0E25\u0E2D\u0E07\u0E2D\u0E35\u0E01\u0E04\u0E23\u0E31\u0E49\u0E07",
|
|
2197
|
+
codeLocked: "\u0E01\u0E23\u0E2D\u0E01\u0E23\u0E2B\u0E31\u0E2A\u0E1C\u0E34\u0E14\u0E2B\u0E25\u0E32\u0E22\u0E04\u0E23\u0E31\u0E49\u0E07\u0E40\u0E01\u0E34\u0E19\u0E44\u0E1B \u0E42\u0E1B\u0E23\u0E14\u0E1B\u0E34\u0E14\u0E2B\u0E19\u0E49\u0E32\u0E15\u0E48\u0E32\u0E07\u0E41\u0E25\u0E49\u0E27\u0E40\u0E23\u0E34\u0E48\u0E21\u0E04\u0E33\u0E02\u0E2D\u0E43\u0E2B\u0E21\u0E48",
|
|
2198
|
+
otpCode: "\u0E23\u0E2B\u0E31\u0E2A\u0E08\u0E32\u0E01\u0E41\u0E2D\u0E1B",
|
|
2199
|
+
otpHelp: "\u0E40\u0E1B\u0E34\u0E14 AuthLink \u0E41\u0E25\u0E30\u0E01\u0E23\u0E2D\u0E01\u0E23\u0E2B\u0E31\u0E2A\u0E2B\u0E01\u0E2B\u0E25\u0E31\u0E01\u0E1B\u0E31\u0E08\u0E08\u0E38\u0E1A\u0E31\u0E19\u0E02\u0E2D\u0E07\u0E1A\u0E31\u0E0D\u0E0A\u0E35\u0E19\u0E35\u0E49 \u0E44\u0E21\u0E48\u0E15\u0E49\u0E2D\u0E07\u0E2D\u0E19\u0E38\u0E21\u0E31\u0E15\u0E34\u0E04\u0E33\u0E02\u0E2D",
|
|
2200
|
+
otpWaiting: "\u0E01\u0E23\u0E2D\u0E01\u0E23\u0E2B\u0E31\u0E2A\u0E1B\u0E31\u0E08\u0E08\u0E38\u0E1A\u0E31\u0E19",
|
|
2201
|
+
otpError: "\u0E22\u0E37\u0E19\u0E22\u0E31\u0E19\u0E44\u0E21\u0E48\u0E2A\u0E33\u0E40\u0E23\u0E47\u0E08 \u0E42\u0E1B\u0E23\u0E14\u0E15\u0E23\u0E27\u0E08\u0E2A\u0E2D\u0E1A\u0E1A\u0E31\u0E0D\u0E0A\u0E35\u0E41\u0E25\u0E30\u0E23\u0E2D\u0E23\u0E2B\u0E31\u0E2A\u0E43\u0E2B\u0E21\u0E48\u0E2B\u0E32\u0E01\u0E43\u0E0A\u0E49\u0E44\u0E1B\u0E41\u0E25\u0E49\u0E27 \u0E2B\u0E32\u0E01\u0E1C\u0E34\u0E14\u0E2B\u0E25\u0E32\u0E22\u0E04\u0E23\u0E31\u0E49\u0E07\u0E43\u0E2B\u0E49\u0E25\u0E2D\u0E07\u0E43\u0E2B\u0E21\u0E48\u0E20\u0E32\u0E22\u0E2B\u0E25\u0E31\u0E07",
|
|
2202
|
+
otpSetup: "\u0E40\u0E1B\u0E34\u0E14\u0E43\u0E0A\u0E49\u0E23\u0E2B\u0E31\u0E2A\u0E1A\u0E19\u0E01\u0E32\u0E23\u0E4C\u0E14\u0E1A\u0E31\u0E0D\u0E0A\u0E35\u0E19\u0E35\u0E49\u0E43\u0E19\u0E41\u0E2D\u0E1B\u0E01\u0E48\u0E2D\u0E19"
|
|
2095
2203
|
};
|
|
2096
2204
|
|
|
2097
2205
|
// src/locales/vi.json
|
|
@@ -2100,7 +2208,7 @@ var vi_default = {
|
|
|
2100
2208
|
confirm: "X\xE1c nh\u1EADn x\xE1c th\u1EF1c",
|
|
2101
2209
|
scan: "Qu\xE9t b\u1EB1ng AuthLink",
|
|
2102
2210
|
code: "M\xE3 \u0111\u1ED1i chi\u1EBFu",
|
|
2103
|
-
help: "
|
|
2211
|
+
help: "Ph\xEA duy\u1EC7t trong \u1EE9ng d\u1EE5ng r\u1ED3i nh\u1EADp m\xE3 x\xE1c nh\u1EADn 6 ch\u1EEF s\u1ED1 t\u1EA1i \u0111\xE2y.",
|
|
2104
2212
|
waiting: "\u0110ang ch\u1EDD x\xE1c nh\u1EADn t\u1EEB \u0111i\u1EC7n tho\u1EA1i",
|
|
2105
2213
|
loading: "\u0110ang k\u1EBFt n\u1ED1i",
|
|
2106
2214
|
confirmed: "\u0110\xE3 x\xE1c nh\u1EADn",
|
|
@@ -2113,7 +2221,16 @@ var vi_default = {
|
|
|
2113
2221
|
close: "\u0110\xF3ng",
|
|
2114
2222
|
cancel: "H\u1EE7y",
|
|
2115
2223
|
autoUpdate: "M\xE3 t\u1EF1 \u0111\u1ED9ng c\u1EADp nh\u1EADt m\u1ED7i 30 gi\xE2y",
|
|
2116
|
-
expiring: "Y\xEAu c\u1EA7u s\u1EAFp h\u1EBFt h\u1EA1n"
|
|
2224
|
+
expiring: "Y\xEAu c\u1EA7u s\u1EAFp h\u1EBFt h\u1EA1n",
|
|
2225
|
+
confirmationCode: "M\xE3 x\xE1c nh\u1EADn trong \u1EE9ng d\u1EE5ng",
|
|
2226
|
+
submitCode: "X\xE1c minh",
|
|
2227
|
+
codeError: "Kh\xF4ng th\u1EC3 x\xE1c minh. Ki\u1EC3m tra m\xE3 v\xE0 tr\u1EA1ng th\xE1i ph\xEA duy\u1EC7t r\u1ED3i th\u1EED l\u1EA1i.",
|
|
2228
|
+
codeLocked: "Nh\u1EADp sai m\xE3 qu\xE1 nhi\u1EC1u l\u1EA7n. \u0110\xF3ng c\u1EEDa s\u1ED5 v\xE0 t\u1EA1o y\xEAu c\u1EA7u m\u1EDBi.",
|
|
2229
|
+
otpCode: "M\xE3 \u1EE9ng d\u1EE5ng",
|
|
2230
|
+
otpHelp: "M\u1EDF AuthLink v\xE0 nh\u1EADp m\xE3 s\xE1u ch\u1EEF s\u1ED1 hi\u1EC7n t\u1EA1i c\u1EE7a t\xE0i kho\u1EA3n n\xE0y. Kh\xF4ng c\u1EA7n ph\xEA duy\u1EC7t y\xEAu c\u1EA7u.",
|
|
2231
|
+
otpWaiting: "Nh\u1EADp m\xE3 hi\u1EC7n t\u1EA1i",
|
|
2232
|
+
otpError: "X\xE1c minh th\u1EA5t b\u1EA1i. Ki\u1EC3m tra t\xE0i kho\u1EA3n v\xE0 ch\u1EDD m\xE3 m\u1EDBi n\u1EBFu \u0111\xE3 d\xF9ng. N\u1EBFu sai nhi\u1EC1u l\u1EA7n, h\xE3y th\u1EED l\u1EA1i sau.",
|
|
2233
|
+
otpSetup: "Tr\u01B0\u1EDBc ti\xEAn h\xE3y b\u1EADt m\xE3 tr\xEAn th\u1EBB t\xE0i kho\u1EA3n n\xE0y trong \u1EE9ng d\u1EE5ng."
|
|
2117
2234
|
};
|
|
2118
2235
|
|
|
2119
2236
|
// src/i18n.ts
|
|
@@ -2150,7 +2267,7 @@ function widgetView(options) {
|
|
|
2150
2267
|
const locale = resolveLocale(options.locale), variant = resolveVariant(options.variant);
|
|
2151
2268
|
const l = getMessages(locale);
|
|
2152
2269
|
const pending = s.status === "pending", hasQr = pending && (mode === "bind" || Boolean(options.showQr)) && Boolean(options.qr);
|
|
2153
|
-
const status = { idle: l.loading, pending: l.waiting, confirmed: l.confirmed, rejected: l.rejected, expired: l.expired, error: l.error }[s.status];
|
|
2270
|
+
const status = { idle: l.loading, pending: options.passcodeMode ? l.otpWaiting : l.waiting, confirmed: l.confirmed, rejected: l.rejected, expired: l.expired, error: l.error }[s.status];
|
|
2154
2271
|
const expiring = pending && s.secondsRemaining <= 30;
|
|
2155
2272
|
const expiryTime = `00:${String(Math.max(0, Math.ceil(s.secondsRemaining))).padStart(2, "0")}`;
|
|
2156
2273
|
const statusNode = () => node(
|
|
@@ -2179,50 +2296,52 @@ function widgetView(options) {
|
|
|
2179
2296
|
node("img", { class: "authlink-qr", src: options.qr, alt: l.scan, width: 240, height: 240 }),
|
|
2180
2297
|
node("figcaption", { class: "authlink-qr-caption" }, l.scan)
|
|
2181
2298
|
)] : [];
|
|
2182
|
-
const
|
|
2183
|
-
|
|
2184
|
-
"output",
|
|
2185
|
-
{
|
|
2186
|
-
class: "authlink-code",
|
|
2187
|
-
"aria-label": s.code ? `${l.code}: ${s.code.split("").join(" ")}` : l.updating,
|
|
2188
|
-
"aria-live": "polite",
|
|
2189
|
-
"data-testid": "authlink-code"
|
|
2190
|
-
},
|
|
2191
|
-
node("span", { class: "authlink-code-group" }, s.code?.slice(0, 3) ?? "---"),
|
|
2192
|
-
node("span", { class: "authlink-code-group" }, s.code?.slice(3) ?? "---")
|
|
2193
|
-
);
|
|
2194
|
-
const panel = node(
|
|
2195
|
-
"div",
|
|
2196
|
-
{ class: "authlink-code-panel" },
|
|
2197
|
-
node("div", { class: "authlink-code-values" }, node("div", { class: "authlink-code-label" }, l.code), code),
|
|
2299
|
+
const detail = [
|
|
2300
|
+
node("p", { class: "authlink-help" }, options.passcodeMode ? l.otpHelp : l.help),
|
|
2198
2301
|
node(
|
|
2199
|
-
"
|
|
2200
|
-
{
|
|
2201
|
-
|
|
2202
|
-
|
|
2203
|
-
|
|
2204
|
-
|
|
2205
|
-
|
|
2206
|
-
|
|
2207
|
-
|
|
2208
|
-
|
|
2302
|
+
"form",
|
|
2303
|
+
{ class: "authlink-code-form", onSubmit: (event) => {
|
|
2304
|
+
event.preventDefault();
|
|
2305
|
+
const input = event.currentTarget.querySelector("input");
|
|
2306
|
+
if (input) void options.submitCode?.(input.value);
|
|
2307
|
+
} },
|
|
2308
|
+
node("label", { for: "authlink-confirmation-code" }, options.passcodeMode ? l.otpCode : l.confirmationCode),
|
|
2309
|
+
node("input", {
|
|
2310
|
+
id: "authlink-confirmation-code",
|
|
2311
|
+
name: options.passcodeMode ? "passcode" : "confirmationCode",
|
|
2312
|
+
type: "text",
|
|
2313
|
+
inputmode: "numeric",
|
|
2314
|
+
autocomplete: "one-time-code",
|
|
2315
|
+
pattern: "[0-9]{6}",
|
|
2316
|
+
maxlength: 6,
|
|
2317
|
+
minlength: 6,
|
|
2318
|
+
required: true,
|
|
2319
|
+
"data-authlink-focus": "confirmation-code",
|
|
2320
|
+
value: options.inputCode ?? "",
|
|
2321
|
+
onInput: (event) => options.setCode?.(event.target.value)
|
|
2322
|
+
}),
|
|
2323
|
+
node(
|
|
2324
|
+
"button",
|
|
2325
|
+
{ type: "submit", class: "authlink-button", ...s.submitting ? { disabled: true } : {} },
|
|
2326
|
+
s.submitting ? l.loading : l.submitCode
|
|
2327
|
+
)
|
|
2209
2328
|
),
|
|
2210
|
-
node("p", { class: "authlink-
|
|
2211
|
-
|
|
2212
|
-
const detail = [panel, node("p", { class: "authlink-help" }, l.help)];
|
|
2329
|
+
...s.error ? [node("p", { class: "authlink-input-error", role: "alert" }, options.passcodeMode ? s.error.message === "OTP_NOT_CONFIGURED" ? l.otpSetup : l.otpError : l.codeError)] : []
|
|
2330
|
+
];
|
|
2213
2331
|
children.push(node("div", { class: "authlink-body" }, ...qr, node("div", { class: "authlink-details" }, ...detail)));
|
|
2214
2332
|
if (variant === "A") children.push(node("div", { class: "authlink-footer" }, statusNode()));
|
|
2215
2333
|
if (variant === "B") children.push(node("div", { class: "authlink-footer" }, statusNode(), ...cancel()));
|
|
2216
2334
|
if (variant === "C") children.push(node("div", { class: "authlink-footer" }, statusNode(), ...cancel()));
|
|
2217
2335
|
} else {
|
|
2218
2336
|
children.push(statusNode());
|
|
2219
|
-
if (s.
|
|
2337
|
+
if (s.error?.message === "CONFIRMATION_CODE_LOCKED") children.push(node("p", { class: "authlink-input-error", role: "alert" }, l.codeLocked));
|
|
2338
|
+
if (s.status === "error" && s.error?.message !== "CONFIRMATION_CODE_LOCKED") children.push(node("button", {
|
|
2220
2339
|
type: "button",
|
|
2221
2340
|
class: "authlink-button",
|
|
2222
2341
|
"data-authlink-focus": "retry",
|
|
2223
2342
|
onClick: retry
|
|
2224
2343
|
}, l.retry));
|
|
2225
|
-
if (refresh && ["expired", "rejected"].includes(s.status)) children.push(node("button", {
|
|
2344
|
+
if (refresh && ["expired", "rejected", "error"].includes(s.status)) children.push(node("button", {
|
|
2226
2345
|
type: "button",
|
|
2227
2346
|
class: "authlink-button",
|
|
2228
2347
|
"data-authlink-focus": "refresh",
|
|
@@ -2245,7 +2364,7 @@ function element(value, svg = false) {
|
|
|
2245
2364
|
svg ||= value.tag === "svg";
|
|
2246
2365
|
const result = svg ? document.createElementNS("http://www.w3.org/2000/svg", value.tag) : document.createElement(value.tag);
|
|
2247
2366
|
for (const [key, v] of Object.entries(value.props)) {
|
|
2248
|
-
if (key
|
|
2367
|
+
if (key.startsWith("on") && typeof v === "function") result.addEventListener(key.slice(2).toLowerCase(), v);
|
|
2249
2368
|
else if (v !== void 0 && v !== null) result.setAttribute(key, String(v));
|
|
2250
2369
|
}
|
|
2251
2370
|
result.append(...value.children.map((child) => element(child, svg)));
|
|
@@ -2279,6 +2398,8 @@ function openAuthLink(options) {
|
|
|
2279
2398
|
dialog.append(header, content);
|
|
2280
2399
|
let locale = options.locale, variant = resolveVariant(options.variant), snapshot = initialSnapshot(), closed = false;
|
|
2281
2400
|
let abort;
|
|
2401
|
+
let inputCode = "";
|
|
2402
|
+
let submitCode;
|
|
2282
2403
|
const image = qrImage(ticket);
|
|
2283
2404
|
let progressFill, progressFrame, progressDeadline = 0;
|
|
2284
2405
|
const motion = window.matchMedia?.("(prefers-reduced-motion: reduce)");
|
|
@@ -2318,6 +2439,11 @@ function openAuthLink(options) {
|
|
|
2318
2439
|
snapshot,
|
|
2319
2440
|
qr: image,
|
|
2320
2441
|
showQr: options.showQr,
|
|
2442
|
+
inputCode,
|
|
2443
|
+
setCode: (code) => {
|
|
2444
|
+
inputCode = code;
|
|
2445
|
+
},
|
|
2446
|
+
submitCode: (code) => submitCode?.(code) ?? Promise.resolve(),
|
|
2321
2447
|
retry,
|
|
2322
2448
|
refresh: options.onRefresh,
|
|
2323
2449
|
close: () => dispose(true)
|
|
@@ -2336,6 +2462,9 @@ function openAuthLink(options) {
|
|
|
2336
2462
|
oldProgress.setAttribute("aria-label", nextProgress.getAttribute("aria-label"));
|
|
2337
2463
|
nextProgress.replaceWith(oldProgress);
|
|
2338
2464
|
}
|
|
2465
|
+
const oldInput = content.querySelector("input[name=confirmationCode]");
|
|
2466
|
+
const nextInput = next.querySelector("input[name=confirmationCode]");
|
|
2467
|
+
if (oldInput && nextInput) nextInput.replaceWith(oldInput);
|
|
2339
2468
|
content.replaceChildren(next);
|
|
2340
2469
|
progressFill = content.querySelector(".authlink-progress-fill") ?? void 0;
|
|
2341
2470
|
drawProgress();
|
|
@@ -2377,6 +2506,9 @@ function openAuthLink(options) {
|
|
|
2377
2506
|
intervalMs: options.intervalMs,
|
|
2378
2507
|
expectedMode: mode,
|
|
2379
2508
|
signal: abort.signal,
|
|
2509
|
+
onReady: (submit) => {
|
|
2510
|
+
submitCode = submit;
|
|
2511
|
+
},
|
|
2380
2512
|
onCodeTiming: syncProgress,
|
|
2381
2513
|
onUpdate: (value) => {
|
|
2382
2514
|
snapshot = value;
|
|
@@ -2435,11 +2567,196 @@ function openAuthLink(options) {
|
|
|
2435
2567
|
};
|
|
2436
2568
|
}
|
|
2437
2569
|
|
|
2570
|
+
// src/passcode.ts
|
|
2571
|
+
function validateOTPResult(value) {
|
|
2572
|
+
if (!value || typeof value !== "object") throw new AuthLinkError("INVALID_RESPONSE");
|
|
2573
|
+
const result = value;
|
|
2574
|
+
const expiry = typeof result.expiresAt === "string" ? Date.parse(result.expiresAt) : NaN;
|
|
2575
|
+
if (result.status !== "confirmed" || result.authenticationPolicy !== "device-totp.v1" || typeof result.verificationId !== "string" || !/^[A-Za-z0-9_-]{43}$/.test(result.verificationId) || !Number.isFinite(expiry) || expiry <= Date.now() || expiry > Date.now() + 9e4 || "requestId" in result || "state" in result || "businessId" in result) throw new AuthLinkError("INVALID_CONFIRMATION");
|
|
2576
|
+
return result;
|
|
2577
|
+
}
|
|
2578
|
+
function openPasscode(options) {
|
|
2579
|
+
if (typeof document === "undefined" || !document.body) throw new AuthLinkError("BROWSER_REQUIRED");
|
|
2580
|
+
const deadline = Date.parse(options.expiresAt);
|
|
2581
|
+
if (!Number.isFinite(deadline) || deadline <= Date.now() || deadline > Date.now() + 3e5) throw new AuthLinkError("INVALID_EXPIRY");
|
|
2582
|
+
const previousFocus = document.activeElement instanceof HTMLElement ? document.activeElement : null;
|
|
2583
|
+
const dialog = document.createElement("dialog");
|
|
2584
|
+
if (typeof dialog.showModal !== "function") throw new AuthLinkError("DIALOG_UNSUPPORTED");
|
|
2585
|
+
dialog.className = "authlink-dialog";
|
|
2586
|
+
dialog.setAttribute("aria-modal", "true");
|
|
2587
|
+
const header = document.createElement("div");
|
|
2588
|
+
header.className = "authlink-header";
|
|
2589
|
+
const brand = document.createElement("span");
|
|
2590
|
+
brand.className = "authlink-brand";
|
|
2591
|
+
brand.textContent = "AuthLink";
|
|
2592
|
+
const close = document.createElement("button");
|
|
2593
|
+
close.type = "button";
|
|
2594
|
+
close.className = "authlink-close";
|
|
2595
|
+
const icon = document.createElement("span");
|
|
2596
|
+
icon.className = "authlink-close-icon";
|
|
2597
|
+
icon.setAttribute("aria-hidden", "true");
|
|
2598
|
+
close.append(icon);
|
|
2599
|
+
const content = document.createElement("div");
|
|
2600
|
+
content.className = "authlink-modal-content";
|
|
2601
|
+
header.append(brand, close);
|
|
2602
|
+
dialog.append(header, content);
|
|
2603
|
+
let locale = options.locale, variant = resolveVariant(options.variant), closed = false, busy = false, code = "", error;
|
|
2604
|
+
const mode = options.bindingQr ? "bind" : "confirm";
|
|
2605
|
+
let image;
|
|
2606
|
+
if (options.bindingQr) {
|
|
2607
|
+
let payload;
|
|
2608
|
+
try {
|
|
2609
|
+
payload = JSON.parse(options.bindingQr);
|
|
2610
|
+
} catch {
|
|
2611
|
+
throw new AuthLinkError("INVALID_TICKET");
|
|
2612
|
+
}
|
|
2613
|
+
image = qrImage(validateTicket({ requestId: payload.requestId, purpose: "bind", qr: options.bindingQr, pairingCode: "000000", expiresAt: options.expiresAt }, "bind", options.authLinkOrigin));
|
|
2614
|
+
}
|
|
2615
|
+
const abort = new AbortController();
|
|
2616
|
+
let timer;
|
|
2617
|
+
const dispose = (notify) => {
|
|
2618
|
+
if (closed) return;
|
|
2619
|
+
closed = true;
|
|
2620
|
+
abort.abort();
|
|
2621
|
+
clearInterval(timer);
|
|
2622
|
+
dialog.remove();
|
|
2623
|
+
previousFocus?.focus();
|
|
2624
|
+
if (notify) options.onClose?.();
|
|
2625
|
+
};
|
|
2626
|
+
const render = () => {
|
|
2627
|
+
if (closed) return;
|
|
2628
|
+
const l = getMessages(locale);
|
|
2629
|
+
dialog.lang = resolveLocale(locale);
|
|
2630
|
+
dialog.dataset.variant = variant;
|
|
2631
|
+
dialog.dataset.mode = mode;
|
|
2632
|
+
dialog.dataset.hasQr = String(Boolean(image));
|
|
2633
|
+
dialog.setAttribute("aria-label", l[mode]);
|
|
2634
|
+
close.setAttribute("aria-label", l.close);
|
|
2635
|
+
const focused = content.contains(document.activeElement);
|
|
2636
|
+
const remaining = Math.max(0, Math.ceil((deadline - Date.now()) / 1e3));
|
|
2637
|
+
const snapshot = { status: remaining ? "pending" : "expired", code: null, secondsRemaining: remaining, codeSecondsRemaining: remaining, submitting: busy, error: error ?? null };
|
|
2638
|
+
content.replaceChildren(element(widgetView({
|
|
2639
|
+
mode,
|
|
2640
|
+
locale,
|
|
2641
|
+
variant,
|
|
2642
|
+
passcodeMode: true,
|
|
2643
|
+
snapshot,
|
|
2644
|
+
qr: image,
|
|
2645
|
+
showQr: Boolean(image),
|
|
2646
|
+
inputCode: code,
|
|
2647
|
+
setCode: (value) => {
|
|
2648
|
+
code = value;
|
|
2649
|
+
},
|
|
2650
|
+
submitCode: submit,
|
|
2651
|
+
retry: () => {
|
|
2652
|
+
error = void 0;
|
|
2653
|
+
render();
|
|
2654
|
+
},
|
|
2655
|
+
close: () => dispose(true)
|
|
2656
|
+
})));
|
|
2657
|
+
if (focused) content.querySelector("input")?.focus();
|
|
2658
|
+
};
|
|
2659
|
+
const submit = async (value) => {
|
|
2660
|
+
if (closed || busy) return;
|
|
2661
|
+
if (Date.now() >= deadline) {
|
|
2662
|
+
render();
|
|
2663
|
+
return;
|
|
2664
|
+
}
|
|
2665
|
+
if (!/^[0-9]{6}$/.test(value)) {
|
|
2666
|
+
error = new AuthLinkError("PASSCODE_INVALID");
|
|
2667
|
+
render();
|
|
2668
|
+
return;
|
|
2669
|
+
}
|
|
2670
|
+
code = value;
|
|
2671
|
+
busy = true;
|
|
2672
|
+
error = void 0;
|
|
2673
|
+
render();
|
|
2674
|
+
try {
|
|
2675
|
+
const result = validateOTPResult(await options.client.verify(value, abort.signal));
|
|
2676
|
+
if (closed || abort.signal.aborted || Date.now() >= deadline) return;
|
|
2677
|
+
try {
|
|
2678
|
+
await options.onVerified?.(result);
|
|
2679
|
+
} catch {
|
|
2680
|
+
options.onError?.(new AuthLinkError("CALLBACK_FAILED"));
|
|
2681
|
+
}
|
|
2682
|
+
dispose(false);
|
|
2683
|
+
} catch (cause) {
|
|
2684
|
+
if (!closed && !abort.signal.aborted) {
|
|
2685
|
+
error = cause instanceof Error ? cause : new AuthLinkError("NETWORK_ERROR");
|
|
2686
|
+
options.onError?.(error);
|
|
2687
|
+
}
|
|
2688
|
+
} finally {
|
|
2689
|
+
busy = false;
|
|
2690
|
+
render();
|
|
2691
|
+
}
|
|
2692
|
+
};
|
|
2693
|
+
close.addEventListener("click", () => dispose(true));
|
|
2694
|
+
dialog.addEventListener("cancel", (event) => {
|
|
2695
|
+
event.preventDefault();
|
|
2696
|
+
dispose(true);
|
|
2697
|
+
});
|
|
2698
|
+
document.body.append(dialog);
|
|
2699
|
+
render();
|
|
2700
|
+
dialog.showModal();
|
|
2701
|
+
content.querySelector("input")?.focus();
|
|
2702
|
+
timer = setInterval(() => {
|
|
2703
|
+
if (closed) return;
|
|
2704
|
+
if (Date.now() >= deadline) {
|
|
2705
|
+
render();
|
|
2706
|
+
clearInterval(timer);
|
|
2707
|
+
void Promise.resolve(options.onExpired?.()).catch(() => options.onError?.(new AuthLinkError("CALLBACK_FAILED")));
|
|
2708
|
+
}
|
|
2709
|
+
}, 1e3);
|
|
2710
|
+
return {
|
|
2711
|
+
close: () => dispose(true),
|
|
2712
|
+
destroy: () => dispose(false),
|
|
2713
|
+
setLocale: (value) => {
|
|
2714
|
+
locale = value;
|
|
2715
|
+
render();
|
|
2716
|
+
},
|
|
2717
|
+
setVariant: (value) => {
|
|
2718
|
+
variant = resolveVariant(value);
|
|
2719
|
+
render();
|
|
2720
|
+
},
|
|
2721
|
+
retry: () => {
|
|
2722
|
+
error = void 0;
|
|
2723
|
+
render();
|
|
2724
|
+
}
|
|
2725
|
+
};
|
|
2726
|
+
}
|
|
2727
|
+
|
|
2438
2728
|
// src/react.tsx
|
|
2439
2729
|
import { jsx } from "react/jsx-runtime";
|
|
2730
|
+
function AuthLinkPasscode(props) {
|
|
2731
|
+
const latest = useRef(props);
|
|
2732
|
+
latest.current = props;
|
|
2733
|
+
const modal = useRef(void 0);
|
|
2734
|
+
useEffect(() => {
|
|
2735
|
+
const handle = openPasscode({
|
|
2736
|
+
...props,
|
|
2737
|
+
onVerified: (value) => latest.current.onVerified?.(value),
|
|
2738
|
+
onExpired: () => latest.current.onExpired?.(),
|
|
2739
|
+
onClose: () => latest.current.onClose?.(),
|
|
2740
|
+
onError: (value) => latest.current.onError?.(value)
|
|
2741
|
+
});
|
|
2742
|
+
modal.current = handle;
|
|
2743
|
+
return () => {
|
|
2744
|
+
handle.destroy();
|
|
2745
|
+
if (modal.current === handle) modal.current = void 0;
|
|
2746
|
+
};
|
|
2747
|
+
}, [props.client, props.expiresAt, props.bindingQr, props.authLinkOrigin]);
|
|
2748
|
+
useEffect(() => {
|
|
2749
|
+
modal.current?.setLocale(props.locale);
|
|
2750
|
+
}, [props.locale]);
|
|
2751
|
+
useEffect(() => {
|
|
2752
|
+
modal.current?.setVariant(props.variant);
|
|
2753
|
+
}, [props.variant]);
|
|
2754
|
+
return null;
|
|
2755
|
+
}
|
|
2440
2756
|
function useAuthLink(options) {
|
|
2441
2757
|
const latest = useRef(options);
|
|
2442
2758
|
latest.current = options;
|
|
2759
|
+
const submit = useRef(void 0);
|
|
2443
2760
|
const delivered = useRef(/* @__PURE__ */ new Set());
|
|
2444
2761
|
const [snapshot, setSnapshot] = useState(initialSnapshot);
|
|
2445
2762
|
const [attempt, setAttempt] = useState(0);
|
|
@@ -2459,6 +2776,9 @@ function useAuthLink(options) {
|
|
|
2459
2776
|
intervalMs,
|
|
2460
2777
|
expectedMode: mode,
|
|
2461
2778
|
signal: abort.signal,
|
|
2779
|
+
onReady: (fn) => {
|
|
2780
|
+
submit.current = fn;
|
|
2781
|
+
},
|
|
2462
2782
|
onUpdate: setSnapshot,
|
|
2463
2783
|
onConfirmed: (result) => once("confirmed", () => latest.current.onConfirmed?.(result)),
|
|
2464
2784
|
onRejected: (result) => once("rejected", () => latest.current.onRejected?.(result)),
|
|
@@ -2467,7 +2787,7 @@ function useAuthLink(options) {
|
|
|
2467
2787
|
});
|
|
2468
2788
|
return () => abort.abort();
|
|
2469
2789
|
}, [ticket, client, intervalMs, mode, attempt]);
|
|
2470
|
-
return { snapshot, retry };
|
|
2790
|
+
return { snapshot, retry, submitCode: (code) => submit.current?.(code) ?? Promise.resolve() };
|
|
2471
2791
|
}
|
|
2472
2792
|
function Widget(props) {
|
|
2473
2793
|
const latest = useRef(props);
|
|
@@ -2514,6 +2834,7 @@ function AuthLinkConfirm(props) {
|
|
|
2514
2834
|
export {
|
|
2515
2835
|
AuthLinkBind,
|
|
2516
2836
|
AuthLinkConfirm,
|
|
2837
|
+
AuthLinkPasscode,
|
|
2517
2838
|
useAuthLink
|
|
2518
2839
|
};
|
|
2519
2840
|
//# sourceMappingURL=react.js.map
|