@auth-link/web 0.0.5 → 2.0.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 +27 -0
- package/README.md +111 -759
- package/dist/index.js +466 -178
- package/dist/index.js.map +3 -3
- package/dist/react.js +466 -177
- package/dist/react.js.map +3 -3
- package/dist/styles.css +11 -49
- 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 +3 -3
- package/dist/types/passcode.d.ts +28 -0
- package/dist/types/react.d.ts +5 -1
- package/dist/types/types.d.ts +2 -4
- package/dist/types/view.d.ts +5 -4
- package/dist/types/vue.d.ts +5 -1
- package/dist/vue.js +479 -176
- package/dist/vue.js.map +3 -3
- package/docs/README.en.md +39 -255
- package/docs/README.ja.md +39 -255
- package/docs/README.zh-CN.md +39 -255
- package/examples/react-client.tsx +16 -34
- package/examples/vue-client.vue +22 -46
- package/package.json +2 -2
package/dist/index.js
CHANGED
|
@@ -1673,10 +1673,9 @@ function validateTicket(value, expectedMode, trustedOrigin) {
|
|
|
1673
1673
|
}
|
|
1674
1674
|
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");
|
|
1675
1675
|
const displayCode = m.displayCode === void 0 ? void 0 : validateDisplayCode(m.displayCode);
|
|
1676
|
-
if (m.purpose === "confirm" && !displayCode) fail("DYNAMIC_CODE_REQUIRED");
|
|
1677
1676
|
const expiry = Date.parse(String(m.expiresAt));
|
|
1678
1677
|
const now = displayCode ? Date.parse(displayCode.serverTime) : Date.now();
|
|
1679
|
-
if (!Number.isFinite(expiry) || expiry > now +
|
|
1678
|
+
if (!Number.isFinite(expiry) || expiry > now + 36e4) fail("INVALID_EXPIRY");
|
|
1680
1679
|
return {
|
|
1681
1680
|
requestId: m.requestId,
|
|
1682
1681
|
purpose: m.purpose,
|
|
@@ -1728,7 +1727,7 @@ async function limitedJson(response) {
|
|
|
1728
1727
|
return fail("INVALID_RESPONSE");
|
|
1729
1728
|
}
|
|
1730
1729
|
}
|
|
1731
|
-
function
|
|
1730
|
+
function createBackendCall(options) {
|
|
1732
1731
|
if ("apiKey" in options || "secret" in options) fail("SERVER_SECRET_FORBIDDEN");
|
|
1733
1732
|
const base = options.baseUrl ?? "/api/authlink";
|
|
1734
1733
|
const allowedOrigins = new Set(options.allowedBackendOrigins ?? []);
|
|
@@ -1793,7 +1792,15 @@ function createAuthLinkClient(options) {
|
|
|
1793
1792
|
headers,
|
|
1794
1793
|
body: JSON.stringify(body)
|
|
1795
1794
|
});
|
|
1796
|
-
if (!response.ok)
|
|
1795
|
+
if (!response.ok) {
|
|
1796
|
+
let code = "";
|
|
1797
|
+
try {
|
|
1798
|
+
code = String(object(await limitedJson(response)).code ?? "").replace(/^AUTHLINK_/, "");
|
|
1799
|
+
} catch {
|
|
1800
|
+
}
|
|
1801
|
+
if (["CONFIRMATION_CODE_INVALID", "CONFIRMATION_CODE_LOCKED", "APPROVAL_REQUIRED", "REQUEST_EXPIRED", "PASSCODE_INVALID", "PASSCODE_USED", "PASSCODE_LOCKED", "OTP_NOT_CONFIGURED"].includes(code)) fail(code);
|
|
1802
|
+
fail(response.status === 401 || response.status === 403 ? "CMS_UNAUTHORIZED" : "CMS_REQUEST_FAILED");
|
|
1803
|
+
}
|
|
1797
1804
|
return await limitedJson(response);
|
|
1798
1805
|
} catch (error) {
|
|
1799
1806
|
if (error instanceof AuthLinkError) throw error;
|
|
@@ -1804,14 +1811,19 @@ function createAuthLinkClient(options) {
|
|
|
1804
1811
|
signal?.removeEventListener("abort", cancel);
|
|
1805
1812
|
}
|
|
1806
1813
|
};
|
|
1814
|
+
return call;
|
|
1815
|
+
}
|
|
1816
|
+
function createAuthLinkClient(options) {
|
|
1817
|
+
const call = createBackendCall(options);
|
|
1807
1818
|
return {
|
|
1808
1819
|
async create(mode, { idempotencyKey, signal }) {
|
|
1809
1820
|
if (!["bind", "confirm"].includes(mode) || !token.test(idempotencyKey)) fail("INVALID_CREATE_OPTIONS");
|
|
1810
1821
|
return validateTicket(await call("/requests", { purpose: mode }, signal, idempotencyKey), mode, options.authLinkOrigin);
|
|
1811
1822
|
},
|
|
1812
|
-
async result(ticket, signal) {
|
|
1823
|
+
async result(ticket, signal, confirmationCode) {
|
|
1813
1824
|
if (!token.test(ticket.requestId)) fail("INVALID_TICKET");
|
|
1814
|
-
|
|
1825
|
+
if (typeof confirmationCode !== "string" || !/^[0-9]{6}$/.test(confirmationCode)) fail("CONFIRMATION_CODE_REQUIRED");
|
|
1826
|
+
return await call(`/requests/${ticket.requestId}/result`, { confirmationCode }, signal);
|
|
1815
1827
|
}
|
|
1816
1828
|
};
|
|
1817
1829
|
}
|
|
@@ -1833,116 +1845,117 @@ function abortable(promise, signal) {
|
|
|
1833
1845
|
}
|
|
1834
1846
|
async function observeRequest(input, options) {
|
|
1835
1847
|
const { client, signal, onUpdate } = options;
|
|
1836
|
-
const interval = options.intervalMs ?? 1500;
|
|
1837
1848
|
let ticket;
|
|
1838
1849
|
try {
|
|
1839
|
-
if (interval < 250 || interval > 1e4 || !Number.isFinite(interval)) fail("INVALID_INTERVAL");
|
|
1840
1850
|
ticket = validateTicket(input, options.expectedMode);
|
|
1841
1851
|
} catch (error) {
|
|
1842
|
-
if (!signal.aborted)
|
|
1843
|
-
const e = error instanceof Error ? error : new AuthLinkError("INVALID_TICKET");
|
|
1844
|
-
onUpdate({ ...initialSnapshot(), status: "error", error: e });
|
|
1845
|
-
options.onError?.(e);
|
|
1846
|
-
}
|
|
1852
|
+
if (!signal.aborted) options.onError?.(error);
|
|
1847
1853
|
return;
|
|
1848
1854
|
}
|
|
1849
|
-
let frame = ticket.displayCode;
|
|
1850
|
-
let serverAnchor = frame ? Date.parse(frame.serverTime) : Date.now();
|
|
1851
|
-
let monotonicAnchor = performance.now();
|
|
1852
|
-
const serverNow = () => serverAnchor + performance.now() - monotonicAnchor;
|
|
1853
1855
|
const expiry = Date.parse(ticket.expiresAt);
|
|
1854
|
-
|
|
1856
|
+
const deadline = performance.now() + Math.max(0, expiry - Date.now());
|
|
1857
|
+
let ended = false, busy = false;
|
|
1858
|
+
let done;
|
|
1859
|
+
const finished = new Promise((resolve) => {
|
|
1860
|
+
done = resolve;
|
|
1861
|
+
});
|
|
1855
1862
|
const controller = new AbortController();
|
|
1856
|
-
const cancel = () =>
|
|
1857
|
-
|
|
1858
|
-
|
|
1859
|
-
|
|
1860
|
-
const update = (value) => {
|
|
1861
|
-
if (signal.aborted) return;
|
|
1862
|
-
if (JSON.stringify(value) !== JSON.stringify(last)) {
|
|
1863
|
-
last = value;
|
|
1864
|
-
onUpdate(value);
|
|
1865
|
-
}
|
|
1863
|
+
const cancel = () => {
|
|
1864
|
+
ended = true;
|
|
1865
|
+
controller.abort();
|
|
1866
|
+
done();
|
|
1866
1867
|
};
|
|
1868
|
+
signal.addEventListener("abort", cancel, { once: true });
|
|
1869
|
+
let snapshot = initialSnapshot();
|
|
1870
|
+
const remaining = () => Math.max(0, (deadline - performance.now()) / 1e3);
|
|
1867
1871
|
const tick = () => {
|
|
1868
1872
|
if (ended || signal.aborted) return;
|
|
1869
|
-
|
|
1870
|
-
|
|
1871
|
-
controller.abort(
|
|
1873
|
+
if (remaining() <= 0) {
|
|
1874
|
+
ended = true;
|
|
1875
|
+
controller.abort();
|
|
1876
|
+
onUpdate({ ...snapshot, status: "expired", code: null, submitting: false });
|
|
1877
|
+
void Promise.resolve().then(() => options.onExpired?.()).catch(() => options.onError?.(new AuthLinkError("CALLBACK_FAILED")));
|
|
1878
|
+
done();
|
|
1872
1879
|
return;
|
|
1873
1880
|
}
|
|
1874
|
-
|
|
1875
|
-
|
|
1876
|
-
update({
|
|
1881
|
+
snapshot = {
|
|
1882
|
+
...snapshot,
|
|
1877
1883
|
status: "pending",
|
|
1878
|
-
code:
|
|
1879
|
-
secondsRemaining: Math.
|
|
1880
|
-
codeSecondsRemaining: Math.ceil(
|
|
1881
|
-
|
|
1882
|
-
}
|
|
1884
|
+
code: ticket.pairingCode,
|
|
1885
|
+
secondsRemaining: Math.ceil(remaining()),
|
|
1886
|
+
codeSecondsRemaining: Math.ceil(remaining()),
|
|
1887
|
+
submitting: busy
|
|
1888
|
+
};
|
|
1889
|
+
onUpdate(snapshot);
|
|
1883
1890
|
};
|
|
1884
|
-
const
|
|
1885
|
-
|
|
1886
|
-
if (
|
|
1887
|
-
|
|
1888
|
-
|
|
1889
|
-
|
|
1890
|
-
let effect = void 0;
|
|
1891
|
-
if (status === "confirmed") effect = options.onConfirmed?.(result);
|
|
1892
|
-
else if (status === "rejected") effect = options.onRejected?.({ status: "rejected", code: "REJECTED", requestId: ticket.requestId, purpose: ticket.purpose });
|
|
1893
|
-
else if (status === "expired") effect = options.onExpired?.();
|
|
1894
|
-
else options.onError?.(error);
|
|
1895
|
-
void Promise.resolve(effect).catch(() => {
|
|
1896
|
-
if (!signal.aborted) options.onError?.(new AuthLinkError("CALLBACK_FAILED"));
|
|
1897
|
-
});
|
|
1898
|
-
} catch {
|
|
1899
|
-
if (status !== "error") options.onError?.(new AuthLinkError("CALLBACK_FAILED"));
|
|
1891
|
+
const submit = async (confirmationCode) => {
|
|
1892
|
+
if (ended || signal.aborted || busy) return;
|
|
1893
|
+
if (!/^[0-9]{6}$/.test(confirmationCode)) {
|
|
1894
|
+
snapshot = { ...snapshot, error: new AuthLinkError("CONFIRMATION_CODE_REQUIRED") };
|
|
1895
|
+
tick();
|
|
1896
|
+
return;
|
|
1900
1897
|
}
|
|
1901
|
-
|
|
1902
|
-
|
|
1898
|
+
if (remaining() <= 0) {
|
|
1899
|
+
tick();
|
|
1900
|
+
return;
|
|
1901
|
+
}
|
|
1902
|
+
busy = true;
|
|
1903
|
+
snapshot = { ...snapshot, error: null };
|
|
1903
1904
|
tick();
|
|
1904
|
-
|
|
1905
|
-
controller.signal.
|
|
1906
|
-
|
|
1907
|
-
controller.signal.throwIfAborted();
|
|
1905
|
+
try {
|
|
1906
|
+
const value = object(await abortable(client.result(ticket, controller.signal, confirmationCode), controller.signal));
|
|
1907
|
+
if (ended || signal.aborted) return;
|
|
1908
1908
|
if (value.requestId !== ticket.requestId) fail("REQUEST_MISMATCH");
|
|
1909
1909
|
if (value.status === "confirmed") {
|
|
1910
|
-
if (!token.test(String(value.verificationId)) ||
|
|
1911
|
-
|
|
1912
|
-
|
|
1913
|
-
|
|
1914
|
-
|
|
1915
|
-
|
|
1916
|
-
|
|
1917
|
-
}
|
|
1918
|
-
if (!["new", "pending", "approved", "consumed"].includes(String(value.status))) fail("INVALID_RESPONSE");
|
|
1919
|
-
if (value.displayCode !== void 0) {
|
|
1920
|
-
const nextFrame = validateDisplayCode(value.displayCode);
|
|
1921
|
-
const nextExpiry = Date.parse(nextFrame.validUntil);
|
|
1922
|
-
const currentExpiry = frame ? Date.parse(frame.validUntil) : 0;
|
|
1923
|
-
if (!frame || nextExpiry > currentExpiry) {
|
|
1924
|
-
serverAnchor = Math.max(serverNow(), Date.parse(nextFrame.serverTime));
|
|
1925
|
-
monotonicAnchor = performance.now();
|
|
1910
|
+
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");
|
|
1911
|
+
ended = true;
|
|
1912
|
+
onUpdate({ ...snapshot, status: "confirmed", code: null, submitting: false });
|
|
1913
|
+
try {
|
|
1914
|
+
await options.onConfirmed?.(value);
|
|
1915
|
+
} catch {
|
|
1916
|
+
options.onError?.(new AuthLinkError("CALLBACK_FAILED"));
|
|
1926
1917
|
}
|
|
1927
|
-
|
|
1918
|
+
done();
|
|
1919
|
+
} else if (value.status === "rejected" || value.status === "expired") {
|
|
1920
|
+
ended = true;
|
|
1921
|
+
onUpdate({ ...snapshot, status: value.status, code: null, submitting: false });
|
|
1922
|
+
try {
|
|
1923
|
+
if (value.status === "rejected") await options.onRejected?.({ status: "rejected", code: "REJECTED", requestId: ticket.requestId, purpose: ticket.purpose });
|
|
1924
|
+
else await options.onExpired?.();
|
|
1925
|
+
} catch {
|
|
1926
|
+
options.onError?.(new AuthLinkError("CALLBACK_FAILED"));
|
|
1927
|
+
} finally {
|
|
1928
|
+
done();
|
|
1929
|
+
}
|
|
1930
|
+
} else {
|
|
1931
|
+
fail("CONFIRMATION_NOT_READY");
|
|
1928
1932
|
}
|
|
1929
|
-
|
|
1930
|
-
|
|
1931
|
-
|
|
1932
|
-
|
|
1933
|
-
|
|
1934
|
-
|
|
1935
|
-
|
|
1936
|
-
|
|
1933
|
+
} catch (error) {
|
|
1934
|
+
if (!ended && !signal.aborted) {
|
|
1935
|
+
const raw = error instanceof Error ? error : new AuthLinkError("NETWORK_ERROR");
|
|
1936
|
+
const code = raw.message.replace(/^AUTHLINK_/, "");
|
|
1937
|
+
const failure = ["CONFIRMATION_CODE_LOCKED", "CONFIRMATION_CODE_INVALID", "APPROVAL_REQUIRED", "REQUEST_EXPIRED"].includes(code) ? new AuthLinkError(code) : raw;
|
|
1938
|
+
snapshot = { ...snapshot, error: failure };
|
|
1939
|
+
if (code === "CONFIRMATION_CODE_LOCKED" || code === "REQUEST_EXPIRED") {
|
|
1940
|
+
ended = true;
|
|
1941
|
+
onUpdate({ ...snapshot, code: null, submitting: false, status: code === "REQUEST_EXPIRED" ? "expired" : "error" });
|
|
1942
|
+
if (code === "REQUEST_EXPIRED") void Promise.resolve().then(() => options.onExpired?.()).catch(() => options.onError?.(new AuthLinkError("CALLBACK_FAILED")));
|
|
1943
|
+
else options.onError?.(failure);
|
|
1944
|
+
done();
|
|
1945
|
+
} else options.onError?.(failure);
|
|
1937
1946
|
}
|
|
1947
|
+
} finally {
|
|
1948
|
+
busy = false;
|
|
1949
|
+
tick();
|
|
1938
1950
|
}
|
|
1939
|
-
}
|
|
1940
|
-
|
|
1941
|
-
|
|
1942
|
-
|
|
1943
|
-
|
|
1951
|
+
};
|
|
1952
|
+
tick();
|
|
1953
|
+
options.onReady?.(submit);
|
|
1954
|
+
const timer = setInterval(tick, 1e3);
|
|
1955
|
+
if (signal.aborted) cancel();
|
|
1956
|
+
try {
|
|
1957
|
+
await finished;
|
|
1944
1958
|
} finally {
|
|
1945
|
-
ended = true;
|
|
1946
1959
|
clearInterval(timer);
|
|
1947
1960
|
controller.abort();
|
|
1948
1961
|
signal.removeEventListener("abort", cancel);
|
|
@@ -1954,8 +1967,8 @@ var en_default = {
|
|
|
1954
1967
|
bind: "Bind your phone",
|
|
1955
1968
|
confirm: "Confirm verification",
|
|
1956
1969
|
scan: "Scan with AuthLink",
|
|
1957
|
-
code: "Matching
|
|
1958
|
-
help: "
|
|
1970
|
+
code: "Matching digits",
|
|
1971
|
+
help: "Approve in the App, then enter its 6-digit confirmation code here.",
|
|
1959
1972
|
waiting: "Waiting for your phone",
|
|
1960
1973
|
loading: "Connecting",
|
|
1961
1974
|
confirmed: "Confirmed",
|
|
@@ -1968,7 +1981,16 @@ var en_default = {
|
|
|
1968
1981
|
close: "Close",
|
|
1969
1982
|
cancel: "Cancel",
|
|
1970
1983
|
autoUpdate: "Code updates automatically every 30 seconds",
|
|
1971
|
-
expiring: "Request expiring soon"
|
|
1984
|
+
expiring: "Request expiring soon",
|
|
1985
|
+
confirmationCode: "App confirmation code",
|
|
1986
|
+
submitCode: "Verify",
|
|
1987
|
+
codeError: "The code could not be verified. Check the code and approval, then retry.",
|
|
1988
|
+
codeLocked: "Too many incorrect codes. Close this window and start a new request.",
|
|
1989
|
+
otpCode: "App verification code",
|
|
1990
|
+
otpHelp: "Open AuthLink and enter this account\u2019s current six-digit code. No approval is needed.",
|
|
1991
|
+
otpWaiting: "Enter the current code",
|
|
1992
|
+
otpError: "Verification failed. Check the account; wait for a new code if already used. After repeated failures, try again later.",
|
|
1993
|
+
otpSetup: "Enable verification codes on this account\u2019s card in the app first."
|
|
1972
1994
|
};
|
|
1973
1995
|
|
|
1974
1996
|
// src/locales/zh-CN.json
|
|
@@ -1976,8 +1998,8 @@ var zh_CN_default = {
|
|
|
1976
1998
|
bind: "\u7ED1\u5B9A\u624B\u673A",
|
|
1977
1999
|
confirm: "\u786E\u8BA4\u8EAB\u4EFD\u9A8C\u8BC1",
|
|
1978
2000
|
scan: "\u4F7F\u7528 AuthLink \u626B\u63CF\u4E8C\u7EF4\u7801",
|
|
1979
|
-
code: "\
|
|
1980
|
-
help: "\
|
|
2001
|
+
code: "\u6838\u5BF9\u6570\u5B57",
|
|
2002
|
+
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",
|
|
1981
2003
|
waiting: "\u7B49\u5F85\u624B\u673A\u786E\u8BA4",
|
|
1982
2004
|
loading: "\u6B63\u5728\u8FDE\u63A5",
|
|
1983
2005
|
confirmed: "\u5DF2\u786E\u8BA4",
|
|
@@ -1990,7 +2012,16 @@ var zh_CN_default = {
|
|
|
1990
2012
|
close: "\u5173\u95ED",
|
|
1991
2013
|
cancel: "\u53D6\u6D88",
|
|
1992
2014
|
autoUpdate: "\u6838\u5BF9\u7801\u6BCF 30 \u79D2\u81EA\u52A8\u66F4\u65B0",
|
|
1993
|
-
expiring: "\u8BF7\u6C42\u5373\u5C06\u8FC7\u671F"
|
|
2015
|
+
expiring: "\u8BF7\u6C42\u5373\u5C06\u8FC7\u671F",
|
|
2016
|
+
confirmationCode: "App \u786E\u8BA4\u7801",
|
|
2017
|
+
submitCode: "\u63D0\u4EA4\u9A8C\u8BC1",
|
|
2018
|
+
codeError: "\u9A8C\u8BC1\u672A\u901A\u8FC7\uFF0C\u8BF7\u68C0\u67E5\u786E\u8BA4\u7801\u548C\u624B\u673A\u6279\u51C6\u72B6\u6001\u540E\u91CD\u8BD5\u3002",
|
|
2019
|
+
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",
|
|
2020
|
+
otpCode: "App \u52A8\u6001\u7801",
|
|
2021
|
+
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",
|
|
2022
|
+
otpWaiting: "\u8BF7\u8F93\u5165\u5F53\u524D\u52A8\u6001\u7801",
|
|
2023
|
+
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",
|
|
2024
|
+
otpSetup: "\u8BF7\u5148\u5728 App \u7684\u8D26\u53F7\u5361\u7247\u4E2D\u542F\u7528\u52A8\u6001\u7801\u3002"
|
|
1994
2025
|
};
|
|
1995
2026
|
|
|
1996
2027
|
// src/locales/zh-TW.json
|
|
@@ -1998,8 +2029,8 @@ var zh_TW_default = {
|
|
|
1998
2029
|
bind: "\u7D81\u5B9A\u624B\u6A5F",
|
|
1999
2030
|
confirm: "\u78BA\u8A8D\u8EAB\u5206\u9A57\u8B49",
|
|
2000
2031
|
scan: "\u4F7F\u7528 AuthLink \u6383\u63CF QR \u78BC",
|
|
2001
|
-
code: "\
|
|
2002
|
-
help: "\
|
|
2032
|
+
code: "\u6838\u5C0D\u6578\u5B57",
|
|
2033
|
+
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",
|
|
2003
2034
|
waiting: "\u7B49\u5F85\u624B\u6A5F\u78BA\u8A8D",
|
|
2004
2035
|
loading: "\u6B63\u5728\u9023\u7DDA",
|
|
2005
2036
|
confirmed: "\u5DF2\u78BA\u8A8D",
|
|
@@ -2012,7 +2043,16 @@ var zh_TW_default = {
|
|
|
2012
2043
|
close: "\u95DC\u9589",
|
|
2013
2044
|
cancel: "\u53D6\u6D88",
|
|
2014
2045
|
autoUpdate: "\u6838\u5C0D\u78BC\u6BCF 30 \u79D2\u81EA\u52D5\u66F4\u65B0",
|
|
2015
|
-
expiring: "\u8ACB\u6C42\u5373\u5C07\u5230\u671F"
|
|
2046
|
+
expiring: "\u8ACB\u6C42\u5373\u5C07\u5230\u671F",
|
|
2047
|
+
confirmationCode: "App \u78BA\u8A8D\u78BC",
|
|
2048
|
+
submitCode: "\u63D0\u4EA4\u9A57\u8B49",
|
|
2049
|
+
codeError: "\u9A57\u8B49\u672A\u901A\u904E\uFF0C\u8ACB\u6AA2\u67E5\u78BA\u8A8D\u78BC\u53CA\u624B\u6A5F\u6279\u51C6\u72C0\u614B\u5F8C\u91CD\u8A66\u3002",
|
|
2050
|
+
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",
|
|
2051
|
+
otpCode: "App \u52D5\u614B\u78BC",
|
|
2052
|
+
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",
|
|
2053
|
+
otpWaiting: "\u8ACB\u8F38\u5165\u76EE\u524D\u7684\u52D5\u614B\u78BC",
|
|
2054
|
+
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",
|
|
2055
|
+
otpSetup: "\u8ACB\u5148\u5728 App \u7684\u5E33\u865F\u5361\u7247\u4E2D\u555F\u7528\u52D5\u614B\u78BC\u3002"
|
|
2016
2056
|
};
|
|
2017
2057
|
|
|
2018
2058
|
// src/locales/ja.json
|
|
@@ -2020,8 +2060,8 @@ var ja_default = {
|
|
|
2020
2060
|
bind: "\u30B9\u30DE\u30FC\u30C8\u30D5\u30A9\u30F3\u3092\u767B\u9332",
|
|
2021
2061
|
confirm: "\u672C\u4EBA\u78BA\u8A8D",
|
|
2022
2062
|
scan: "AuthLink \u3067 QR \u30B3\u30FC\u30C9\u3092\u30B9\u30AD\u30E3\u30F3",
|
|
2023
|
-
code: "\u7167\u5408\
|
|
2024
|
-
help: "\
|
|
2063
|
+
code: "\u7167\u5408\u7528\u306E\u6570\u5B57",
|
|
2064
|
+
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",
|
|
2025
2065
|
waiting: "\u30B9\u30DE\u30FC\u30C8\u30D5\u30A9\u30F3\u306E\u78BA\u8A8D\u3092\u5F85\u3063\u3066\u3044\u307E\u3059",
|
|
2026
2066
|
loading: "\u63A5\u7D9A\u4E2D",
|
|
2027
2067
|
confirmed: "\u78BA\u8A8D\u6E08\u307F",
|
|
@@ -2034,7 +2074,16 @@ var ja_default = {
|
|
|
2034
2074
|
close: "\u9589\u3058\u308B",
|
|
2035
2075
|
cancel: "\u30AD\u30E3\u30F3\u30BB\u30EB",
|
|
2036
2076
|
autoUpdate: "\u7167\u5408\u30B3\u30FC\u30C9\u306F30\u79D2\u3054\u3068\u306B\u81EA\u52D5\u66F4\u65B0",
|
|
2037
|
-
expiring: "\u30EA\u30AF\u30A8\u30B9\u30C8\u306E\u6709\u52B9\u671F\u9650\u304C\u307E\u3082\u306A\u304F\u5207\u308C\u307E\u3059"
|
|
2077
|
+
expiring: "\u30EA\u30AF\u30A8\u30B9\u30C8\u306E\u6709\u52B9\u671F\u9650\u304C\u307E\u3082\u306A\u304F\u5207\u308C\u307E\u3059",
|
|
2078
|
+
confirmationCode: "App \u306E\u78BA\u8A8D\u30B3\u30FC\u30C9",
|
|
2079
|
+
submitCode: "\u78BA\u8A8D\u3059\u308B",
|
|
2080
|
+
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",
|
|
2081
|
+
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",
|
|
2082
|
+
otpCode: "\u30A2\u30D7\u30EA\u306E\u8A8D\u8A3C\u30B3\u30FC\u30C9",
|
|
2083
|
+
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",
|
|
2084
|
+
otpWaiting: "\u73FE\u5728\u306E\u30B3\u30FC\u30C9\u3092\u5165\u529B",
|
|
2085
|
+
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",
|
|
2086
|
+
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"
|
|
2038
2087
|
};
|
|
2039
2088
|
|
|
2040
2089
|
// src/locales/bn.json
|
|
@@ -2043,7 +2092,7 @@ var bn_default = {
|
|
|
2043
2092
|
confirm: "\u09AF\u09BE\u099A\u09BE\u0987\u0995\u09B0\u09A3 \u09A8\u09BF\u09B6\u09CD\u099A\u09BF\u09A4 \u0995\u09B0\u09C1\u09A8",
|
|
2044
2093
|
scan: "AuthLink \u09A6\u09BF\u09AF\u09BC\u09C7 \u09B8\u09CD\u0995\u09CD\u09AF\u09BE\u09A8 \u0995\u09B0\u09C1\u09A8",
|
|
2045
2094
|
code: "\u09AE\u09BF\u09B2\u09BF\u09AF\u09BC\u09C7 \u09A6\u09C7\u0996\u09BE\u09B0 \u0995\u09CB\u09A1",
|
|
2046
|
-
help: "\u0985\u09CD\u09AF\u09BE\u09AA\u09C7
|
|
2095
|
+
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",
|
|
2047
2096
|
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",
|
|
2048
2097
|
loading: "\u09B8\u0982\u09AF\u09CB\u0997 \u0995\u09B0\u09BE \u09B9\u099A\u09CD\u099B\u09C7",
|
|
2049
2098
|
confirmed: "\u09A8\u09BF\u09B6\u09CD\u099A\u09BF\u09A4 \u09B9\u09AF\u09BC\u09C7\u099B\u09C7",
|
|
@@ -2056,7 +2105,16 @@ var bn_default = {
|
|
|
2056
2105
|
close: "\u09AC\u09A8\u09CD\u09A7 \u0995\u09B0\u09C1\u09A8",
|
|
2057
2106
|
cancel: "\u09AC\u09BE\u09A4\u09BF\u09B2",
|
|
2058
2107
|
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",
|
|
2059
|
-
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"
|
|
2108
|
+
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",
|
|
2109
|
+
confirmationCode: "\u0985\u09CD\u09AF\u09BE\u09AA\u09C7\u09B0 \u09A8\u09BF\u09B6\u09CD\u099A\u09BF\u09A4\u0995\u09B0\u09A3 \u0995\u09CB\u09A1",
|
|
2110
|
+
submitCode: "\u09AF\u09BE\u099A\u09BE\u0987 \u0995\u09B0\u09C1\u09A8",
|
|
2111
|
+
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",
|
|
2112
|
+
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",
|
|
2113
|
+
otpCode: "\u0985\u09CD\u09AF\u09BE\u09AA\u09C7\u09B0 \u0995\u09CB\u09A1",
|
|
2114
|
+
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",
|
|
2115
|
+
otpWaiting: "\u09AC\u09B0\u09CD\u09A4\u09AE\u09BE\u09A8 \u0995\u09CB\u09A1 \u09B2\u09BF\u0996\u09C1\u09A8",
|
|
2116
|
+
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",
|
|
2117
|
+
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"
|
|
2060
2118
|
};
|
|
2061
2119
|
|
|
2062
2120
|
// src/locales/es.json
|
|
@@ -2065,7 +2123,7 @@ var es_default = {
|
|
|
2065
2123
|
confirm: "Confirma la verificaci\xF3n",
|
|
2066
2124
|
scan: "Escanea con AuthLink",
|
|
2067
2125
|
code: "C\xF3digo de comparaci\xF3n",
|
|
2068
|
-
help: "
|
|
2126
|
+
help: "Aprueba en la app e introduce aqu\xED su c\xF3digo de 6 d\xEDgitos.",
|
|
2069
2127
|
waiting: "Esperando la confirmaci\xF3n del tel\xE9fono",
|
|
2070
2128
|
loading: "Conectando",
|
|
2071
2129
|
confirmed: "Confirmado",
|
|
@@ -2078,7 +2136,16 @@ var es_default = {
|
|
|
2078
2136
|
close: "Cerrar",
|
|
2079
2137
|
cancel: "Cancelar",
|
|
2080
2138
|
autoUpdate: "El c\xF3digo se actualiza autom\xE1ticamente cada 30 segundos",
|
|
2081
|
-
expiring: "La solicitud est\xE1 por caducar"
|
|
2139
|
+
expiring: "La solicitud est\xE1 por caducar",
|
|
2140
|
+
confirmationCode: "C\xF3digo de confirmaci\xF3n de la app",
|
|
2141
|
+
submitCode: "Verificar",
|
|
2142
|
+
codeError: "No se pudo verificar. Revisa el c\xF3digo y la aprobaci\xF3n.",
|
|
2143
|
+
codeLocked: "Demasiados c\xF3digos incorrectos. Cierra la ventana e inicia una nueva solicitud.",
|
|
2144
|
+
otpCode: "C\xF3digo de la app",
|
|
2145
|
+
otpHelp: "Abre AuthLink e introduce el c\xF3digo actual de seis d\xEDgitos de esta cuenta. No hace falta aprobar una solicitud.",
|
|
2146
|
+
otpWaiting: "Introduce el c\xF3digo actual",
|
|
2147
|
+
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.",
|
|
2148
|
+
otpSetup: "Activa primero los c\xF3digos en la tarjeta de esta cuenta en la app."
|
|
2082
2149
|
};
|
|
2083
2150
|
|
|
2084
2151
|
// src/locales/fil.json
|
|
@@ -2087,7 +2154,7 @@ var fil_default = {
|
|
|
2087
2154
|
confirm: "Kumpirmahin ang pagpapatunay",
|
|
2088
2155
|
scan: "Mag-scan gamit ang AuthLink",
|
|
2089
2156
|
code: "Code na paghahambingin",
|
|
2090
|
-
help: "
|
|
2157
|
+
help: "Aprubahan sa app, saka ilagay dito ang 6-digit na confirmation code.",
|
|
2091
2158
|
waiting: "Hinihintay ang kumpirmasyon sa telepono",
|
|
2092
2159
|
loading: "Kumokonekta",
|
|
2093
2160
|
confirmed: "Nakumpirma",
|
|
@@ -2100,7 +2167,16 @@ var fil_default = {
|
|
|
2100
2167
|
close: "Isara",
|
|
2101
2168
|
cancel: "Kanselahin",
|
|
2102
2169
|
autoUpdate: "Awtomatikong nagbabago ang code kada 30 segundo",
|
|
2103
|
-
expiring: "Malapit nang mag-expire ang kahilingan"
|
|
2170
|
+
expiring: "Malapit nang mag-expire ang kahilingan",
|
|
2171
|
+
confirmationCode: "Confirmation code ng app",
|
|
2172
|
+
submitCode: "I-verify",
|
|
2173
|
+
codeError: "Hindi ma-verify. Suriin ang code at pag-apruba at subukan muli.",
|
|
2174
|
+
codeLocked: "Masyadong maraming maling code. Isara ang window at magsimula ng bagong request.",
|
|
2175
|
+
otpCode: "Code ng app",
|
|
2176
|
+
otpHelp: "Buksan ang AuthLink at ilagay ang kasalukuyang anim na digit na code ng account na ito. Hindi kailangang aprubahan ang request.",
|
|
2177
|
+
otpWaiting: "Ilagay ang kasalukuyang code",
|
|
2178
|
+
otpError: "Hindi napatunayan. Tingnan ang account at maghintay ng bagong code kung nagamit na. Subukang muli mamaya kung maraming maling pagtatangka.",
|
|
2179
|
+
otpSetup: "Paganahin muna ang mga code sa card ng account na ito sa app."
|
|
2104
2180
|
};
|
|
2105
2181
|
|
|
2106
2182
|
// src/locales/hi.json
|
|
@@ -2109,7 +2185,7 @@ var hi_default = {
|
|
|
2109
2185
|
confirm: "\u0938\u0924\u094D\u092F\u093E\u092A\u0928 \u0915\u0940 \u092A\u0941\u0937\u094D\u091F\u093F \u0915\u0930\u0947\u0902",
|
|
2110
2186
|
scan: "AuthLink \u0938\u0947 \u0938\u094D\u0915\u0948\u0928 \u0915\u0930\u0947\u0902",
|
|
2111
2187
|
code: "\u092E\u093F\u0932\u093E\u0928 \u0915\u094B\u0921",
|
|
2112
|
-
help: "\u0910\u092A \u092E\u0947\u0902 \u0938\
|
|
2188
|
+
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",
|
|
2113
2189
|
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",
|
|
2114
2190
|
loading: "\u0915\u0928\u0947\u0915\u094D\u091F \u0939\u094B \u0930\u0939\u093E \u0939\u0948",
|
|
2115
2191
|
confirmed: "\u092A\u0941\u0937\u094D\u091F\u093F \u0939\u094B \u0917\u0908",
|
|
@@ -2122,7 +2198,16 @@ var hi_default = {
|
|
|
2122
2198
|
close: "\u092C\u0902\u0926 \u0915\u0930\u0947\u0902",
|
|
2123
2199
|
cancel: "\u0930\u0926\u094D\u0926 \u0915\u0930\u0947\u0902",
|
|
2124
2200
|
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",
|
|
2125
|
-
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"
|
|
2201
|
+
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",
|
|
2202
|
+
confirmationCode: "\u0910\u092A \u0915\u093E \u092A\u0941\u0937\u094D\u091F\u093F \u0915\u094B\u0921",
|
|
2203
|
+
submitCode: "\u0938\u0924\u094D\u092F\u093E\u092A\u093F\u0924 \u0915\u0930\u0947\u0902",
|
|
2204
|
+
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",
|
|
2205
|
+
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",
|
|
2206
|
+
otpCode: "\u0910\u092A \u0915\u093E \u0915\u094B\u0921",
|
|
2207
|
+
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",
|
|
2208
|
+
otpWaiting: "\u0935\u0930\u094D\u0924\u092E\u093E\u0928 \u0915\u094B\u0921 \u0926\u0930\u094D\u091C \u0915\u0930\u0947\u0902",
|
|
2209
|
+
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",
|
|
2210
|
+
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"
|
|
2126
2211
|
};
|
|
2127
2212
|
|
|
2128
2213
|
// src/locales/id.json
|
|
@@ -2131,7 +2216,7 @@ var id_default = {
|
|
|
2131
2216
|
confirm: "Konfirmasi verifikasi",
|
|
2132
2217
|
scan: "Pindai dengan AuthLink",
|
|
2133
2218
|
code: "Kode pencocokan",
|
|
2134
|
-
help: "
|
|
2219
|
+
help: "Setujui di aplikasi, lalu masukkan kode konfirmasi 6 digit di sini.",
|
|
2135
2220
|
waiting: "Menunggu konfirmasi dari ponsel",
|
|
2136
2221
|
loading: "Menghubungkan",
|
|
2137
2222
|
confirmed: "Dikonfirmasi",
|
|
@@ -2144,7 +2229,16 @@ var id_default = {
|
|
|
2144
2229
|
close: "Tutup",
|
|
2145
2230
|
cancel: "Batal",
|
|
2146
2231
|
autoUpdate: "Kode diperbarui otomatis setiap 30 detik",
|
|
2147
|
-
expiring: "Permintaan akan segera kedaluwarsa"
|
|
2232
|
+
expiring: "Permintaan akan segera kedaluwarsa",
|
|
2233
|
+
confirmationCode: "Kode konfirmasi aplikasi",
|
|
2234
|
+
submitCode: "Verifikasi",
|
|
2235
|
+
codeError: "Verifikasi gagal. Periksa kode dan persetujuan, lalu coba lagi.",
|
|
2236
|
+
codeLocked: "Terlalu banyak kode salah. Tutup jendela dan mulai permintaan baru.",
|
|
2237
|
+
otpCode: "Kode aplikasi",
|
|
2238
|
+
otpHelp: "Buka AuthLink dan masukkan kode enam digit terkini untuk akun ini. Tidak perlu menyetujui permintaan.",
|
|
2239
|
+
otpWaiting: "Masukkan kode terkini",
|
|
2240
|
+
otpError: "Verifikasi gagal. Periksa akun dan tunggu kode baru jika sudah digunakan. Setelah beberapa kegagalan, coba lagi nanti.",
|
|
2241
|
+
otpSetup: "Aktifkan kode di kartu akun ini dalam aplikasi terlebih dahulu."
|
|
2148
2242
|
};
|
|
2149
2243
|
|
|
2150
2244
|
// src/locales/ms.json
|
|
@@ -2153,7 +2247,7 @@ var ms_default = {
|
|
|
2153
2247
|
confirm: "Sahkan pengesahan",
|
|
2154
2248
|
scan: "Imbas dengan AuthLink",
|
|
2155
2249
|
code: "Kod padanan",
|
|
2156
|
-
help: "
|
|
2250
|
+
help: "Luluskan dalam aplikasi, kemudian masukkan kod pengesahan 6 digit di sini.",
|
|
2157
2251
|
waiting: "Menunggu pengesahan daripada telefon",
|
|
2158
2252
|
loading: "Sedang menyambung",
|
|
2159
2253
|
confirmed: "Disahkan",
|
|
@@ -2166,7 +2260,16 @@ var ms_default = {
|
|
|
2166
2260
|
close: "Tutup",
|
|
2167
2261
|
cancel: "Batal",
|
|
2168
2262
|
autoUpdate: "Kod dikemas kini secara automatik setiap 30 saat",
|
|
2169
|
-
expiring: "Permintaan akan tamat tempoh tidak lama lagi"
|
|
2263
|
+
expiring: "Permintaan akan tamat tempoh tidak lama lagi",
|
|
2264
|
+
confirmationCode: "Kod pengesahan aplikasi",
|
|
2265
|
+
submitCode: "Sahkan",
|
|
2266
|
+
codeError: "Pengesahan gagal. Semak kod dan kelulusan, kemudian cuba lagi.",
|
|
2267
|
+
codeLocked: "Terlalu banyak kod salah. Tutup tetingkap dan mulakan permintaan baharu.",
|
|
2268
|
+
otpCode: "Kod aplikasi",
|
|
2269
|
+
otpHelp: "Buka AuthLink dan masukkan kod enam digit semasa untuk akaun ini. Tiada kelulusan permintaan diperlukan.",
|
|
2270
|
+
otpWaiting: "Masukkan kod semasa",
|
|
2271
|
+
otpError: "Pengesahan gagal. Semak akaun dan tunggu kod baharu jika sudah digunakan. Selepas beberapa kegagalan, cuba lagi kemudian.",
|
|
2272
|
+
otpSetup: "Aktifkan kod pada kad akaun ini dalam aplikasi dahulu."
|
|
2170
2273
|
};
|
|
2171
2274
|
|
|
2172
2275
|
// src/locales/pt.json
|
|
@@ -2175,7 +2278,7 @@ var pt_default = {
|
|
|
2175
2278
|
confirm: "Confirme a verifica\xE7\xE3o",
|
|
2176
2279
|
scan: "Escaneie com o AuthLink",
|
|
2177
2280
|
code: "C\xF3digo de compara\xE7\xE3o",
|
|
2178
|
-
help: "
|
|
2281
|
+
help: "Aprove no app e digite aqui o c\xF3digo de 6 d\xEDgitos.",
|
|
2179
2282
|
waiting: "Aguardando confirma\xE7\xE3o no celular",
|
|
2180
2283
|
loading: "Conectando",
|
|
2181
2284
|
confirmed: "Confirmado",
|
|
@@ -2188,7 +2291,16 @@ var pt_default = {
|
|
|
2188
2291
|
close: "Fechar",
|
|
2189
2292
|
cancel: "Cancelar",
|
|
2190
2293
|
autoUpdate: "O c\xF3digo \xE9 atualizado automaticamente a cada 30 segundos",
|
|
2191
|
-
expiring: "A solicita\xE7\xE3o est\xE1 prestes a expirar"
|
|
2294
|
+
expiring: "A solicita\xE7\xE3o est\xE1 prestes a expirar",
|
|
2295
|
+
confirmationCode: "C\xF3digo de confirma\xE7\xE3o do app",
|
|
2296
|
+
submitCode: "Verificar",
|
|
2297
|
+
codeError: "N\xE3o foi poss\xEDvel verificar. Confira o c\xF3digo e a aprova\xE7\xE3o.",
|
|
2298
|
+
codeLocked: "Muitos c\xF3digos incorretos. Feche a janela e inicie uma nova solicita\xE7\xE3o.",
|
|
2299
|
+
otpCode: "C\xF3digo do aplicativo",
|
|
2300
|
+
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.",
|
|
2301
|
+
otpWaiting: "Digite o c\xF3digo atual",
|
|
2302
|
+
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.",
|
|
2303
|
+
otpSetup: "Ative primeiro os c\xF3digos no cart\xE3o desta conta no aplicativo."
|
|
2192
2304
|
};
|
|
2193
2305
|
|
|
2194
2306
|
// src/locales/th.json
|
|
@@ -2197,7 +2309,7 @@ var th_default = {
|
|
|
2197
2309
|
confirm: "\u0E22\u0E37\u0E19\u0E22\u0E31\u0E19\u0E01\u0E32\u0E23\u0E15\u0E23\u0E27\u0E08\u0E2A\u0E2D\u0E1A",
|
|
2198
2310
|
scan: "\u0E2A\u0E41\u0E01\u0E19\u0E14\u0E49\u0E27\u0E22 AuthLink",
|
|
2199
2311
|
code: "\u0E23\u0E2B\u0E31\u0E2A\u0E2A\u0E33\u0E2B\u0E23\u0E31\u0E1A\u0E40\u0E1B\u0E23\u0E35\u0E22\u0E1A\u0E40\u0E17\u0E35\u0E22\u0E1A",
|
|
2200
|
-
help: "\
|
|
2312
|
+
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",
|
|
2201
2313
|
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",
|
|
2202
2314
|
loading: "\u0E01\u0E33\u0E25\u0E31\u0E07\u0E40\u0E0A\u0E37\u0E48\u0E2D\u0E21\u0E15\u0E48\u0E2D",
|
|
2203
2315
|
confirmed: "\u0E22\u0E37\u0E19\u0E22\u0E31\u0E19\u0E41\u0E25\u0E49\u0E27",
|
|
@@ -2210,7 +2322,16 @@ var th_default = {
|
|
|
2210
2322
|
close: "\u0E1B\u0E34\u0E14",
|
|
2211
2323
|
cancel: "\u0E22\u0E01\u0E40\u0E25\u0E34\u0E01",
|
|
2212
2324
|
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",
|
|
2213
|
-
expiring: "\u0E04\u0E33\u0E02\u0E2D\u0E43\u0E01\u0E25\u0E49\u0E2B\u0E21\u0E14\u0E2D\u0E32\u0E22\u0E38"
|
|
2325
|
+
expiring: "\u0E04\u0E33\u0E02\u0E2D\u0E43\u0E01\u0E25\u0E49\u0E2B\u0E21\u0E14\u0E2D\u0E32\u0E22\u0E38",
|
|
2326
|
+
confirmationCode: "\u0E23\u0E2B\u0E31\u0E2A\u0E22\u0E37\u0E19\u0E22\u0E31\u0E19\u0E08\u0E32\u0E01\u0E41\u0E2D\u0E1B",
|
|
2327
|
+
submitCode: "\u0E22\u0E37\u0E19\u0E22\u0E31\u0E19",
|
|
2328
|
+
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",
|
|
2329
|
+
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",
|
|
2330
|
+
otpCode: "\u0E23\u0E2B\u0E31\u0E2A\u0E08\u0E32\u0E01\u0E41\u0E2D\u0E1B",
|
|
2331
|
+
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",
|
|
2332
|
+
otpWaiting: "\u0E01\u0E23\u0E2D\u0E01\u0E23\u0E2B\u0E31\u0E2A\u0E1B\u0E31\u0E08\u0E08\u0E38\u0E1A\u0E31\u0E19",
|
|
2333
|
+
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",
|
|
2334
|
+
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"
|
|
2214
2335
|
};
|
|
2215
2336
|
|
|
2216
2337
|
// src/locales/vi.json
|
|
@@ -2219,7 +2340,7 @@ var vi_default = {
|
|
|
2219
2340
|
confirm: "X\xE1c nh\u1EADn x\xE1c th\u1EF1c",
|
|
2220
2341
|
scan: "Qu\xE9t b\u1EB1ng AuthLink",
|
|
2221
2342
|
code: "M\xE3 \u0111\u1ED1i chi\u1EBFu",
|
|
2222
|
-
help: "
|
|
2343
|
+
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.",
|
|
2223
2344
|
waiting: "\u0110ang ch\u1EDD x\xE1c nh\u1EADn t\u1EEB \u0111i\u1EC7n tho\u1EA1i",
|
|
2224
2345
|
loading: "\u0110ang k\u1EBFt n\u1ED1i",
|
|
2225
2346
|
confirmed: "\u0110\xE3 x\xE1c nh\u1EADn",
|
|
@@ -2232,7 +2353,16 @@ var vi_default = {
|
|
|
2232
2353
|
close: "\u0110\xF3ng",
|
|
2233
2354
|
cancel: "H\u1EE7y",
|
|
2234
2355
|
autoUpdate: "M\xE3 t\u1EF1 \u0111\u1ED9ng c\u1EADp nh\u1EADt m\u1ED7i 30 gi\xE2y",
|
|
2235
|
-
expiring: "Y\xEAu c\u1EA7u s\u1EAFp h\u1EBFt h\u1EA1n"
|
|
2356
|
+
expiring: "Y\xEAu c\u1EA7u s\u1EAFp h\u1EBFt h\u1EA1n",
|
|
2357
|
+
confirmationCode: "M\xE3 x\xE1c nh\u1EADn trong \u1EE9ng d\u1EE5ng",
|
|
2358
|
+
submitCode: "X\xE1c minh",
|
|
2359
|
+
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.",
|
|
2360
|
+
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.",
|
|
2361
|
+
otpCode: "M\xE3 \u1EE9ng d\u1EE5ng",
|
|
2362
|
+
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.",
|
|
2363
|
+
otpWaiting: "Nh\u1EADp m\xE3 hi\u1EC7n t\u1EA1i",
|
|
2364
|
+
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.",
|
|
2365
|
+
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."
|
|
2236
2366
|
};
|
|
2237
2367
|
|
|
2238
2368
|
// src/i18n.ts
|
|
@@ -2262,15 +2392,12 @@ function getMessages(locale) {
|
|
|
2262
2392
|
|
|
2263
2393
|
// src/view.ts
|
|
2264
2394
|
var node = (tag, props, ...children) => ({ tag, props, children });
|
|
2265
|
-
function resolveVariant(variant) {
|
|
2266
|
-
return variant === "B" || variant === "C" ? variant : "A";
|
|
2267
|
-
}
|
|
2268
2395
|
function widgetView(options) {
|
|
2269
2396
|
const { snapshot: s, mode, retry, refresh } = options;
|
|
2270
|
-
const locale = resolveLocale(options.locale)
|
|
2397
|
+
const locale = resolveLocale(options.locale);
|
|
2271
2398
|
const l = getMessages(locale);
|
|
2272
2399
|
const pending = s.status === "pending", hasQr = pending && (mode === "bind" || Boolean(options.showQr)) && Boolean(options.qr);
|
|
2273
|
-
const status = { idle: l.loading, pending: l.waiting, confirmed: l.confirmed, rejected: l.rejected, expired: l.expired, error: l.error }[s.status];
|
|
2400
|
+
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];
|
|
2274
2401
|
const expiring = pending && s.secondsRemaining <= 30;
|
|
2275
2402
|
const expiryTime = `00:${String(Math.max(0, Math.ceil(s.secondsRemaining))).padStart(2, "0")}`;
|
|
2276
2403
|
const statusNode = () => node(
|
|
@@ -2284,12 +2411,6 @@ function widgetView(options) {
|
|
|
2284
2411
|
expiring ? l.expiring : status,
|
|
2285
2412
|
...expiring ? [node("span", { class: "authlink-expiry", "aria-hidden": "true" }, ` \xB7 ${expiryTime}`)] : []
|
|
2286
2413
|
);
|
|
2287
|
-
const cancel = () => options.close ? [node("button", {
|
|
2288
|
-
type: "button",
|
|
2289
|
-
class: "authlink-cancel",
|
|
2290
|
-
"data-authlink-focus": "cancel",
|
|
2291
|
-
onClick: options.close
|
|
2292
|
-
}, l.cancel)] : [];
|
|
2293
2414
|
const children = [node("h3", { class: "authlink-title" }, l[mode])];
|
|
2294
2415
|
if (hasQr) children.push(node("p", { class: "authlink-subtitle" }, l.scan));
|
|
2295
2416
|
if (pending) {
|
|
@@ -2299,50 +2420,50 @@ function widgetView(options) {
|
|
|
2299
2420
|
node("img", { class: "authlink-qr", src: options.qr, alt: l.scan, width: 240, height: 240 }),
|
|
2300
2421
|
node("figcaption", { class: "authlink-qr-caption" }, l.scan)
|
|
2301
2422
|
)] : [];
|
|
2302
|
-
const
|
|
2303
|
-
|
|
2304
|
-
"output",
|
|
2305
|
-
{
|
|
2306
|
-
class: "authlink-code",
|
|
2307
|
-
"aria-label": s.code ? `${l.code}: ${s.code.split("").join(" ")}` : l.updating,
|
|
2308
|
-
"aria-live": "polite",
|
|
2309
|
-
"data-testid": "authlink-code"
|
|
2310
|
-
},
|
|
2311
|
-
node("span", { class: "authlink-code-group" }, s.code?.slice(0, 3) ?? "---"),
|
|
2312
|
-
node("span", { class: "authlink-code-group" }, s.code?.slice(3) ?? "---")
|
|
2313
|
-
);
|
|
2314
|
-
const panel = node(
|
|
2315
|
-
"div",
|
|
2316
|
-
{ class: "authlink-code-panel" },
|
|
2317
|
-
node("div", { class: "authlink-code-values" }, node("div", { class: "authlink-code-label" }, l.code), code),
|
|
2423
|
+
const detail = [
|
|
2424
|
+
node("p", { class: "authlink-help" }, options.passcodeMode ? l.otpHelp : l.help),
|
|
2318
2425
|
node(
|
|
2319
|
-
"
|
|
2320
|
-
{
|
|
2321
|
-
|
|
2322
|
-
|
|
2323
|
-
|
|
2324
|
-
|
|
2325
|
-
|
|
2326
|
-
|
|
2327
|
-
|
|
2328
|
-
|
|
2426
|
+
"form",
|
|
2427
|
+
{ class: "authlink-code-form", onSubmit: (event) => {
|
|
2428
|
+
event.preventDefault();
|
|
2429
|
+
const input = event.currentTarget.querySelector("input");
|
|
2430
|
+
if (input) void options.submitCode?.(input.value);
|
|
2431
|
+
} },
|
|
2432
|
+
node("label", { for: "authlink-confirmation-code" }, options.passcodeMode ? l.otpCode : l.confirmationCode),
|
|
2433
|
+
node("input", {
|
|
2434
|
+
id: "authlink-confirmation-code",
|
|
2435
|
+
name: options.passcodeMode ? "passcode" : "confirmationCode",
|
|
2436
|
+
type: "text",
|
|
2437
|
+
inputmode: "numeric",
|
|
2438
|
+
autocomplete: "one-time-code",
|
|
2439
|
+
pattern: "[0-9]{6}",
|
|
2440
|
+
maxlength: 6,
|
|
2441
|
+
minlength: 6,
|
|
2442
|
+
required: true,
|
|
2443
|
+
"data-authlink-focus": "confirmation-code",
|
|
2444
|
+
value: options.inputCode ?? "",
|
|
2445
|
+
onInput: (event) => options.setCode?.(event.target.value)
|
|
2446
|
+
}),
|
|
2447
|
+
node(
|
|
2448
|
+
"button",
|
|
2449
|
+
{ type: "submit", class: "authlink-button", ...s.submitting ? { disabled: true } : {} },
|
|
2450
|
+
s.submitting ? l.loading : l.submitCode
|
|
2451
|
+
)
|
|
2329
2452
|
),
|
|
2330
|
-
node("p", { class: "authlink-
|
|
2331
|
-
|
|
2332
|
-
const detail = [panel, node("p", { class: "authlink-help" }, l.help)];
|
|
2453
|
+
...s.error ? [node("p", { class: "authlink-input-error", role: "alert" }, options.passcodeMode ? s.error.message === "OTP_NOT_CONFIGURED" ? l.otpSetup : l.otpError : l.codeError)] : []
|
|
2454
|
+
];
|
|
2333
2455
|
children.push(node("div", { class: "authlink-body" }, ...qr, node("div", { class: "authlink-details" }, ...detail)));
|
|
2334
|
-
|
|
2335
|
-
if (variant === "B") children.push(node("div", { class: "authlink-footer" }, statusNode(), ...cancel()));
|
|
2336
|
-
if (variant === "C") children.push(node("div", { class: "authlink-footer" }, statusNode(), ...cancel()));
|
|
2456
|
+
children.push(node("div", { class: "authlink-footer" }, statusNode()));
|
|
2337
2457
|
} else {
|
|
2338
2458
|
children.push(statusNode());
|
|
2339
|
-
if (s.
|
|
2459
|
+
if (s.error?.message === "CONFIRMATION_CODE_LOCKED") children.push(node("p", { class: "authlink-input-error", role: "alert" }, l.codeLocked));
|
|
2460
|
+
if (s.status === "error" && s.error?.message !== "CONFIRMATION_CODE_LOCKED") children.push(node("button", {
|
|
2340
2461
|
type: "button",
|
|
2341
2462
|
class: "authlink-button",
|
|
2342
2463
|
"data-authlink-focus": "retry",
|
|
2343
2464
|
onClick: retry
|
|
2344
2465
|
}, l.retry));
|
|
2345
|
-
if (refresh && ["expired", "rejected"].includes(s.status)) children.push(node("button", {
|
|
2466
|
+
if (refresh && ["expired", "rejected", "error"].includes(s.status)) children.push(node("button", {
|
|
2346
2467
|
type: "button",
|
|
2347
2468
|
class: "authlink-button",
|
|
2348
2469
|
"data-authlink-focus": "refresh",
|
|
@@ -2353,7 +2474,6 @@ function widgetView(options) {
|
|
|
2353
2474
|
lang: locale,
|
|
2354
2475
|
class: `authlink-widget ${options.className ?? ""}`.trim(),
|
|
2355
2476
|
"data-status": s.status,
|
|
2356
|
-
"data-variant": variant,
|
|
2357
2477
|
"data-has-qr": String(hasQr),
|
|
2358
2478
|
"aria-label": l[mode]
|
|
2359
2479
|
}, ...children);
|
|
@@ -2365,7 +2485,7 @@ function element(value, svg = false) {
|
|
|
2365
2485
|
svg ||= value.tag === "svg";
|
|
2366
2486
|
const result = svg ? document.createElementNS("http://www.w3.org/2000/svg", value.tag) : document.createElement(value.tag);
|
|
2367
2487
|
for (const [key, v] of Object.entries(value.props)) {
|
|
2368
|
-
if (key
|
|
2488
|
+
if (key.startsWith("on") && typeof v === "function") result.addEventListener(key.slice(2).toLowerCase(), v);
|
|
2369
2489
|
else if (v !== void 0 && v !== null) result.setAttribute(key, String(v));
|
|
2370
2490
|
}
|
|
2371
2491
|
result.append(...value.children.map((child) => element(child, svg)));
|
|
@@ -2397,8 +2517,10 @@ function openAuthLink(options) {
|
|
|
2397
2517
|
content.className = "authlink-modal-content";
|
|
2398
2518
|
header.append(brand, closeButton);
|
|
2399
2519
|
dialog.append(header, content);
|
|
2400
|
-
let locale = options.locale,
|
|
2520
|
+
let locale = options.locale, snapshot = initialSnapshot(), closed = false;
|
|
2401
2521
|
let abort;
|
|
2522
|
+
let inputCode = "";
|
|
2523
|
+
let submitCode;
|
|
2402
2524
|
const image = qrImage(ticket);
|
|
2403
2525
|
let progressFill, progressFrame, progressDeadline = 0;
|
|
2404
2526
|
const motion = window.matchMedia?.("(prefers-reduced-motion: reduce)");
|
|
@@ -2425,7 +2547,6 @@ function openAuthLink(options) {
|
|
|
2425
2547
|
const language = resolveLocale(locale), messages2 = getMessages(language);
|
|
2426
2548
|
dialog.lang = language;
|
|
2427
2549
|
dialog.setAttribute("aria-label", messages2[mode]);
|
|
2428
|
-
dialog.dataset.variant = variant;
|
|
2429
2550
|
dialog.dataset.mode = mode;
|
|
2430
2551
|
dialog.dataset.hasQr = String(snapshot.status === "pending" && (mode === "bind" || Boolean(options.showQr)));
|
|
2431
2552
|
closeButton.setAttribute("aria-label", messages2.close);
|
|
@@ -2434,13 +2555,16 @@ function openAuthLink(options) {
|
|
|
2434
2555
|
const next = element(widgetView({
|
|
2435
2556
|
mode,
|
|
2436
2557
|
locale,
|
|
2437
|
-
variant,
|
|
2438
2558
|
snapshot,
|
|
2439
2559
|
qr: image,
|
|
2440
2560
|
showQr: options.showQr,
|
|
2561
|
+
inputCode,
|
|
2562
|
+
setCode: (code) => {
|
|
2563
|
+
inputCode = code;
|
|
2564
|
+
},
|
|
2565
|
+
submitCode: (code) => submitCode?.(code) ?? Promise.resolve(),
|
|
2441
2566
|
retry,
|
|
2442
|
-
refresh: options.onRefresh
|
|
2443
|
-
close: () => dispose(true)
|
|
2567
|
+
refresh: options.onRefresh
|
|
2444
2568
|
}));
|
|
2445
2569
|
const oldCode = content.querySelector(".authlink-code");
|
|
2446
2570
|
const nextCode = next.querySelector(".authlink-code");
|
|
@@ -2456,6 +2580,9 @@ function openAuthLink(options) {
|
|
|
2456
2580
|
oldProgress.setAttribute("aria-label", nextProgress.getAttribute("aria-label"));
|
|
2457
2581
|
nextProgress.replaceWith(oldProgress);
|
|
2458
2582
|
}
|
|
2583
|
+
const oldInput = content.querySelector("input[name=confirmationCode]");
|
|
2584
|
+
const nextInput = next.querySelector("input[name=confirmationCode]");
|
|
2585
|
+
if (oldInput && nextInput) nextInput.replaceWith(oldInput);
|
|
2459
2586
|
content.replaceChildren(next);
|
|
2460
2587
|
progressFill = content.querySelector(".authlink-progress-fill") ?? void 0;
|
|
2461
2588
|
drawProgress();
|
|
@@ -2497,6 +2624,9 @@ function openAuthLink(options) {
|
|
|
2497
2624
|
intervalMs: options.intervalMs,
|
|
2498
2625
|
expectedMode: mode,
|
|
2499
2626
|
signal: abort.signal,
|
|
2627
|
+
onReady: (submit) => {
|
|
2628
|
+
submitCode = submit;
|
|
2629
|
+
},
|
|
2500
2630
|
onCodeTiming: syncProgress,
|
|
2501
2631
|
onUpdate: (value) => {
|
|
2502
2632
|
snapshot = value;
|
|
@@ -2547,23 +2677,181 @@ function openAuthLink(options) {
|
|
|
2547
2677
|
locale = value;
|
|
2548
2678
|
render();
|
|
2549
2679
|
},
|
|
2550
|
-
setVariant: (value) => {
|
|
2551
|
-
variant = resolveVariant(value);
|
|
2552
|
-
render();
|
|
2553
|
-
},
|
|
2554
2680
|
retry
|
|
2555
2681
|
};
|
|
2556
2682
|
}
|
|
2557
2683
|
var openAuthLinkBind = (options) => openAuthLink({ ...options, mode: "bind" });
|
|
2558
2684
|
var openAuthLinkConfirm = (options) => openAuthLink({ ...options, mode: "confirm" });
|
|
2685
|
+
|
|
2686
|
+
// src/passcode.ts
|
|
2687
|
+
function validateOTPResult(value) {
|
|
2688
|
+
if (!value || typeof value !== "object") throw new AuthLinkError("INVALID_RESPONSE");
|
|
2689
|
+
const result = value;
|
|
2690
|
+
const expiry = typeof result.expiresAt === "string" ? Date.parse(result.expiresAt) : NaN;
|
|
2691
|
+
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");
|
|
2692
|
+
return result;
|
|
2693
|
+
}
|
|
2694
|
+
function createPasscodeClient(options) {
|
|
2695
|
+
const call = createBackendCall(options);
|
|
2696
|
+
return {
|
|
2697
|
+
async verify(passcode, signal) {
|
|
2698
|
+
if (!/^[0-9]{6}$/.test(passcode)) throw new AuthLinkError("PASSCODE_INVALID");
|
|
2699
|
+
return validateOTPResult(await call("/auth", { passcode }, signal));
|
|
2700
|
+
}
|
|
2701
|
+
};
|
|
2702
|
+
}
|
|
2703
|
+
function openPasscode(options) {
|
|
2704
|
+
if (typeof document === "undefined" || !document.body) throw new AuthLinkError("BROWSER_REQUIRED");
|
|
2705
|
+
const deadline = Date.parse(options.expiresAt);
|
|
2706
|
+
if (!Number.isFinite(deadline) || deadline <= Date.now() || deadline > Date.now() + 3e5) throw new AuthLinkError("INVALID_EXPIRY");
|
|
2707
|
+
const previousFocus = document.activeElement instanceof HTMLElement ? document.activeElement : null;
|
|
2708
|
+
const dialog = document.createElement("dialog");
|
|
2709
|
+
if (typeof dialog.showModal !== "function") throw new AuthLinkError("DIALOG_UNSUPPORTED");
|
|
2710
|
+
dialog.className = "authlink-dialog";
|
|
2711
|
+
dialog.setAttribute("aria-modal", "true");
|
|
2712
|
+
const header = document.createElement("div");
|
|
2713
|
+
header.className = "authlink-header";
|
|
2714
|
+
const brand = document.createElement("span");
|
|
2715
|
+
brand.className = "authlink-brand";
|
|
2716
|
+
brand.textContent = "AuthLink";
|
|
2717
|
+
const close = document.createElement("button");
|
|
2718
|
+
close.type = "button";
|
|
2719
|
+
close.className = "authlink-close";
|
|
2720
|
+
const icon = document.createElement("span");
|
|
2721
|
+
icon.className = "authlink-close-icon";
|
|
2722
|
+
icon.setAttribute("aria-hidden", "true");
|
|
2723
|
+
close.append(icon);
|
|
2724
|
+
const content = document.createElement("div");
|
|
2725
|
+
content.className = "authlink-modal-content";
|
|
2726
|
+
header.append(brand, close);
|
|
2727
|
+
dialog.append(header, content);
|
|
2728
|
+
let locale = options.locale, closed = false, busy = false, code = "", error;
|
|
2729
|
+
const mode = options.bindingQr ? "bind" : "confirm";
|
|
2730
|
+
let image;
|
|
2731
|
+
if (options.bindingQr) {
|
|
2732
|
+
let payload;
|
|
2733
|
+
try {
|
|
2734
|
+
payload = JSON.parse(options.bindingQr);
|
|
2735
|
+
} catch {
|
|
2736
|
+
throw new AuthLinkError("INVALID_TICKET");
|
|
2737
|
+
}
|
|
2738
|
+
image = qrImage(validateTicket({ requestId: payload.requestId, purpose: "bind", qr: options.bindingQr, pairingCode: "000000", expiresAt: options.expiresAt }, "bind", options.authLinkOrigin));
|
|
2739
|
+
}
|
|
2740
|
+
const abort = new AbortController();
|
|
2741
|
+
let timer;
|
|
2742
|
+
const dispose = (notify) => {
|
|
2743
|
+
if (closed) return;
|
|
2744
|
+
closed = true;
|
|
2745
|
+
abort.abort();
|
|
2746
|
+
clearInterval(timer);
|
|
2747
|
+
dialog.remove();
|
|
2748
|
+
previousFocus?.focus();
|
|
2749
|
+
if (notify) options.onClose?.();
|
|
2750
|
+
};
|
|
2751
|
+
const render = () => {
|
|
2752
|
+
if (closed) return;
|
|
2753
|
+
const l = getMessages(locale);
|
|
2754
|
+
dialog.lang = resolveLocale(locale);
|
|
2755
|
+
dialog.dataset.mode = mode;
|
|
2756
|
+
dialog.dataset.hasQr = String(Boolean(image));
|
|
2757
|
+
dialog.setAttribute("aria-label", l[mode]);
|
|
2758
|
+
close.setAttribute("aria-label", l.close);
|
|
2759
|
+
const focused = content.contains(document.activeElement);
|
|
2760
|
+
const remaining = Math.max(0, Math.ceil((deadline - Date.now()) / 1e3));
|
|
2761
|
+
const snapshot = { status: remaining ? "pending" : "expired", code: null, secondsRemaining: remaining, codeSecondsRemaining: remaining, submitting: busy, error: error ?? null };
|
|
2762
|
+
content.replaceChildren(element(widgetView({
|
|
2763
|
+
mode,
|
|
2764
|
+
locale,
|
|
2765
|
+
passcodeMode: true,
|
|
2766
|
+
snapshot,
|
|
2767
|
+
qr: image,
|
|
2768
|
+
showQr: Boolean(image),
|
|
2769
|
+
inputCode: code,
|
|
2770
|
+
setCode: (value) => {
|
|
2771
|
+
code = value;
|
|
2772
|
+
},
|
|
2773
|
+
submitCode: submit,
|
|
2774
|
+
retry: () => {
|
|
2775
|
+
error = void 0;
|
|
2776
|
+
render();
|
|
2777
|
+
}
|
|
2778
|
+
})));
|
|
2779
|
+
if (focused) content.querySelector("input")?.focus();
|
|
2780
|
+
};
|
|
2781
|
+
const submit = async (value) => {
|
|
2782
|
+
if (closed || busy) return;
|
|
2783
|
+
if (Date.now() >= deadline) {
|
|
2784
|
+
render();
|
|
2785
|
+
return;
|
|
2786
|
+
}
|
|
2787
|
+
if (!/^[0-9]{6}$/.test(value)) {
|
|
2788
|
+
error = new AuthLinkError("PASSCODE_INVALID");
|
|
2789
|
+
render();
|
|
2790
|
+
return;
|
|
2791
|
+
}
|
|
2792
|
+
code = value;
|
|
2793
|
+
busy = true;
|
|
2794
|
+
error = void 0;
|
|
2795
|
+
render();
|
|
2796
|
+
try {
|
|
2797
|
+
const result = validateOTPResult(await options.client.verify(value, abort.signal));
|
|
2798
|
+
if (closed || abort.signal.aborted || Date.now() >= deadline) return;
|
|
2799
|
+
try {
|
|
2800
|
+
await options.onVerified?.(result);
|
|
2801
|
+
} catch {
|
|
2802
|
+
options.onError?.(new AuthLinkError("CALLBACK_FAILED"));
|
|
2803
|
+
}
|
|
2804
|
+
dispose(false);
|
|
2805
|
+
} catch (cause) {
|
|
2806
|
+
if (!closed && !abort.signal.aborted) {
|
|
2807
|
+
error = cause instanceof Error ? cause : new AuthLinkError("NETWORK_ERROR");
|
|
2808
|
+
options.onError?.(error);
|
|
2809
|
+
}
|
|
2810
|
+
} finally {
|
|
2811
|
+
busy = false;
|
|
2812
|
+
render();
|
|
2813
|
+
}
|
|
2814
|
+
};
|
|
2815
|
+
close.addEventListener("click", () => dispose(true));
|
|
2816
|
+
dialog.addEventListener("cancel", (event) => {
|
|
2817
|
+
event.preventDefault();
|
|
2818
|
+
dispose(true);
|
|
2819
|
+
});
|
|
2820
|
+
document.body.append(dialog);
|
|
2821
|
+
render();
|
|
2822
|
+
dialog.showModal();
|
|
2823
|
+
content.querySelector("input")?.focus();
|
|
2824
|
+
timer = setInterval(() => {
|
|
2825
|
+
if (closed) return;
|
|
2826
|
+
if (Date.now() >= deadline) {
|
|
2827
|
+
render();
|
|
2828
|
+
clearInterval(timer);
|
|
2829
|
+
void Promise.resolve(options.onExpired?.()).catch(() => options.onError?.(new AuthLinkError("CALLBACK_FAILED")));
|
|
2830
|
+
}
|
|
2831
|
+
}, 1e3);
|
|
2832
|
+
return {
|
|
2833
|
+
close: () => dispose(true),
|
|
2834
|
+
destroy: () => dispose(false),
|
|
2835
|
+
setLocale: (value) => {
|
|
2836
|
+
locale = value;
|
|
2837
|
+
render();
|
|
2838
|
+
},
|
|
2839
|
+
retry: () => {
|
|
2840
|
+
error = void 0;
|
|
2841
|
+
render();
|
|
2842
|
+
}
|
|
2843
|
+
};
|
|
2844
|
+
}
|
|
2559
2845
|
export {
|
|
2560
2846
|
AuthLinkError,
|
|
2561
2847
|
createAuthLinkClient,
|
|
2848
|
+
createPasscodeClient,
|
|
2562
2849
|
initialSnapshot,
|
|
2563
2850
|
observeRequest,
|
|
2564
2851
|
openAuthLink,
|
|
2565
2852
|
openAuthLinkBind,
|
|
2566
2853
|
openAuthLinkConfirm,
|
|
2854
|
+
openPasscode,
|
|
2567
2855
|
qrImage,
|
|
2568
2856
|
requestKey,
|
|
2569
2857
|
supportedLocales,
|