@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/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
|
|
@@ -2270,7 +2400,7 @@ function widgetView(options) {
|
|
|
2270
2400
|
const locale = resolveLocale(options.locale), variant = resolveVariant(options.variant);
|
|
2271
2401
|
const l = getMessages(locale);
|
|
2272
2402
|
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];
|
|
2403
|
+
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
2404
|
const expiring = pending && s.secondsRemaining <= 30;
|
|
2275
2405
|
const expiryTime = `00:${String(Math.max(0, Math.ceil(s.secondsRemaining))).padStart(2, "0")}`;
|
|
2276
2406
|
const statusNode = () => node(
|
|
@@ -2299,50 +2429,52 @@ function widgetView(options) {
|
|
|
2299
2429
|
node("img", { class: "authlink-qr", src: options.qr, alt: l.scan, width: 240, height: 240 }),
|
|
2300
2430
|
node("figcaption", { class: "authlink-qr-caption" }, l.scan)
|
|
2301
2431
|
)] : [];
|
|
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),
|
|
2432
|
+
const detail = [
|
|
2433
|
+
node("p", { class: "authlink-help" }, options.passcodeMode ? l.otpHelp : l.help),
|
|
2318
2434
|
node(
|
|
2319
|
-
"
|
|
2320
|
-
{
|
|
2321
|
-
|
|
2322
|
-
|
|
2323
|
-
|
|
2324
|
-
|
|
2325
|
-
|
|
2326
|
-
|
|
2327
|
-
|
|
2328
|
-
|
|
2435
|
+
"form",
|
|
2436
|
+
{ class: "authlink-code-form", onSubmit: (event) => {
|
|
2437
|
+
event.preventDefault();
|
|
2438
|
+
const input = event.currentTarget.querySelector("input");
|
|
2439
|
+
if (input) void options.submitCode?.(input.value);
|
|
2440
|
+
} },
|
|
2441
|
+
node("label", { for: "authlink-confirmation-code" }, options.passcodeMode ? l.otpCode : l.confirmationCode),
|
|
2442
|
+
node("input", {
|
|
2443
|
+
id: "authlink-confirmation-code",
|
|
2444
|
+
name: options.passcodeMode ? "passcode" : "confirmationCode",
|
|
2445
|
+
type: "text",
|
|
2446
|
+
inputmode: "numeric",
|
|
2447
|
+
autocomplete: "one-time-code",
|
|
2448
|
+
pattern: "[0-9]{6}",
|
|
2449
|
+
maxlength: 6,
|
|
2450
|
+
minlength: 6,
|
|
2451
|
+
required: true,
|
|
2452
|
+
"data-authlink-focus": "confirmation-code",
|
|
2453
|
+
value: options.inputCode ?? "",
|
|
2454
|
+
onInput: (event) => options.setCode?.(event.target.value)
|
|
2455
|
+
}),
|
|
2456
|
+
node(
|
|
2457
|
+
"button",
|
|
2458
|
+
{ type: "submit", class: "authlink-button", ...s.submitting ? { disabled: true } : {} },
|
|
2459
|
+
s.submitting ? l.loading : l.submitCode
|
|
2460
|
+
)
|
|
2329
2461
|
),
|
|
2330
|
-
node("p", { class: "authlink-
|
|
2331
|
-
|
|
2332
|
-
const detail = [panel, node("p", { class: "authlink-help" }, l.help)];
|
|
2462
|
+
...s.error ? [node("p", { class: "authlink-input-error", role: "alert" }, options.passcodeMode ? s.error.message === "OTP_NOT_CONFIGURED" ? l.otpSetup : l.otpError : l.codeError)] : []
|
|
2463
|
+
];
|
|
2333
2464
|
children.push(node("div", { class: "authlink-body" }, ...qr, node("div", { class: "authlink-details" }, ...detail)));
|
|
2334
2465
|
if (variant === "A") children.push(node("div", { class: "authlink-footer" }, statusNode()));
|
|
2335
2466
|
if (variant === "B") children.push(node("div", { class: "authlink-footer" }, statusNode(), ...cancel()));
|
|
2336
2467
|
if (variant === "C") children.push(node("div", { class: "authlink-footer" }, statusNode(), ...cancel()));
|
|
2337
2468
|
} else {
|
|
2338
2469
|
children.push(statusNode());
|
|
2339
|
-
if (s.
|
|
2470
|
+
if (s.error?.message === "CONFIRMATION_CODE_LOCKED") children.push(node("p", { class: "authlink-input-error", role: "alert" }, l.codeLocked));
|
|
2471
|
+
if (s.status === "error" && s.error?.message !== "CONFIRMATION_CODE_LOCKED") children.push(node("button", {
|
|
2340
2472
|
type: "button",
|
|
2341
2473
|
class: "authlink-button",
|
|
2342
2474
|
"data-authlink-focus": "retry",
|
|
2343
2475
|
onClick: retry
|
|
2344
2476
|
}, l.retry));
|
|
2345
|
-
if (refresh && ["expired", "rejected"].includes(s.status)) children.push(node("button", {
|
|
2477
|
+
if (refresh && ["expired", "rejected", "error"].includes(s.status)) children.push(node("button", {
|
|
2346
2478
|
type: "button",
|
|
2347
2479
|
class: "authlink-button",
|
|
2348
2480
|
"data-authlink-focus": "refresh",
|
|
@@ -2365,7 +2497,7 @@ function element(value, svg = false) {
|
|
|
2365
2497
|
svg ||= value.tag === "svg";
|
|
2366
2498
|
const result = svg ? document.createElementNS("http://www.w3.org/2000/svg", value.tag) : document.createElement(value.tag);
|
|
2367
2499
|
for (const [key, v] of Object.entries(value.props)) {
|
|
2368
|
-
if (key
|
|
2500
|
+
if (key.startsWith("on") && typeof v === "function") result.addEventListener(key.slice(2).toLowerCase(), v);
|
|
2369
2501
|
else if (v !== void 0 && v !== null) result.setAttribute(key, String(v));
|
|
2370
2502
|
}
|
|
2371
2503
|
result.append(...value.children.map((child) => element(child, svg)));
|
|
@@ -2399,6 +2531,8 @@ function openAuthLink(options) {
|
|
|
2399
2531
|
dialog.append(header, content);
|
|
2400
2532
|
let locale = options.locale, variant = resolveVariant(options.variant), snapshot = initialSnapshot(), closed = false;
|
|
2401
2533
|
let abort;
|
|
2534
|
+
let inputCode = "";
|
|
2535
|
+
let submitCode;
|
|
2402
2536
|
const image = qrImage(ticket);
|
|
2403
2537
|
let progressFill, progressFrame, progressDeadline = 0;
|
|
2404
2538
|
const motion = window.matchMedia?.("(prefers-reduced-motion: reduce)");
|
|
@@ -2438,6 +2572,11 @@ function openAuthLink(options) {
|
|
|
2438
2572
|
snapshot,
|
|
2439
2573
|
qr: image,
|
|
2440
2574
|
showQr: options.showQr,
|
|
2575
|
+
inputCode,
|
|
2576
|
+
setCode: (code) => {
|
|
2577
|
+
inputCode = code;
|
|
2578
|
+
},
|
|
2579
|
+
submitCode: (code) => submitCode?.(code) ?? Promise.resolve(),
|
|
2441
2580
|
retry,
|
|
2442
2581
|
refresh: options.onRefresh,
|
|
2443
2582
|
close: () => dispose(true)
|
|
@@ -2456,6 +2595,9 @@ function openAuthLink(options) {
|
|
|
2456
2595
|
oldProgress.setAttribute("aria-label", nextProgress.getAttribute("aria-label"));
|
|
2457
2596
|
nextProgress.replaceWith(oldProgress);
|
|
2458
2597
|
}
|
|
2598
|
+
const oldInput = content.querySelector("input[name=confirmationCode]");
|
|
2599
|
+
const nextInput = next.querySelector("input[name=confirmationCode]");
|
|
2600
|
+
if (oldInput && nextInput) nextInput.replaceWith(oldInput);
|
|
2459
2601
|
content.replaceChildren(next);
|
|
2460
2602
|
progressFill = content.querySelector(".authlink-progress-fill") ?? void 0;
|
|
2461
2603
|
drawProgress();
|
|
@@ -2497,6 +2639,9 @@ function openAuthLink(options) {
|
|
|
2497
2639
|
intervalMs: options.intervalMs,
|
|
2498
2640
|
expectedMode: mode,
|
|
2499
2641
|
signal: abort.signal,
|
|
2642
|
+
onReady: (submit) => {
|
|
2643
|
+
submitCode = submit;
|
|
2644
|
+
},
|
|
2500
2645
|
onCodeTiming: syncProgress,
|
|
2501
2646
|
onUpdate: (value) => {
|
|
2502
2647
|
snapshot = value;
|
|
@@ -2556,14 +2701,183 @@ function openAuthLink(options) {
|
|
|
2556
2701
|
}
|
|
2557
2702
|
var openAuthLinkBind = (options) => openAuthLink({ ...options, mode: "bind" });
|
|
2558
2703
|
var openAuthLinkConfirm = (options) => openAuthLink({ ...options, mode: "confirm" });
|
|
2704
|
+
|
|
2705
|
+
// src/passcode.ts
|
|
2706
|
+
function validateOTPResult(value) {
|
|
2707
|
+
if (!value || typeof value !== "object") throw new AuthLinkError("INVALID_RESPONSE");
|
|
2708
|
+
const result = value;
|
|
2709
|
+
const expiry = typeof result.expiresAt === "string" ? Date.parse(result.expiresAt) : NaN;
|
|
2710
|
+
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");
|
|
2711
|
+
return result;
|
|
2712
|
+
}
|
|
2713
|
+
function createPasscodeClient(options) {
|
|
2714
|
+
const call = createBackendCall(options);
|
|
2715
|
+
return {
|
|
2716
|
+
async verify(passcode, signal) {
|
|
2717
|
+
if (!/^[0-9]{6}$/.test(passcode)) throw new AuthLinkError("PASSCODE_INVALID");
|
|
2718
|
+
return validateOTPResult(await call("/auth", { passcode }, signal));
|
|
2719
|
+
}
|
|
2720
|
+
};
|
|
2721
|
+
}
|
|
2722
|
+
function openPasscode(options) {
|
|
2723
|
+
if (typeof document === "undefined" || !document.body) throw new AuthLinkError("BROWSER_REQUIRED");
|
|
2724
|
+
const deadline = Date.parse(options.expiresAt);
|
|
2725
|
+
if (!Number.isFinite(deadline) || deadline <= Date.now() || deadline > Date.now() + 3e5) throw new AuthLinkError("INVALID_EXPIRY");
|
|
2726
|
+
const previousFocus = document.activeElement instanceof HTMLElement ? document.activeElement : null;
|
|
2727
|
+
const dialog = document.createElement("dialog");
|
|
2728
|
+
if (typeof dialog.showModal !== "function") throw new AuthLinkError("DIALOG_UNSUPPORTED");
|
|
2729
|
+
dialog.className = "authlink-dialog";
|
|
2730
|
+
dialog.setAttribute("aria-modal", "true");
|
|
2731
|
+
const header = document.createElement("div");
|
|
2732
|
+
header.className = "authlink-header";
|
|
2733
|
+
const brand = document.createElement("span");
|
|
2734
|
+
brand.className = "authlink-brand";
|
|
2735
|
+
brand.textContent = "AuthLink";
|
|
2736
|
+
const close = document.createElement("button");
|
|
2737
|
+
close.type = "button";
|
|
2738
|
+
close.className = "authlink-close";
|
|
2739
|
+
const icon = document.createElement("span");
|
|
2740
|
+
icon.className = "authlink-close-icon";
|
|
2741
|
+
icon.setAttribute("aria-hidden", "true");
|
|
2742
|
+
close.append(icon);
|
|
2743
|
+
const content = document.createElement("div");
|
|
2744
|
+
content.className = "authlink-modal-content";
|
|
2745
|
+
header.append(brand, close);
|
|
2746
|
+
dialog.append(header, content);
|
|
2747
|
+
let locale = options.locale, variant = resolveVariant(options.variant), closed = false, busy = false, code = "", error;
|
|
2748
|
+
const mode = options.bindingQr ? "bind" : "confirm";
|
|
2749
|
+
let image;
|
|
2750
|
+
if (options.bindingQr) {
|
|
2751
|
+
let payload;
|
|
2752
|
+
try {
|
|
2753
|
+
payload = JSON.parse(options.bindingQr);
|
|
2754
|
+
} catch {
|
|
2755
|
+
throw new AuthLinkError("INVALID_TICKET");
|
|
2756
|
+
}
|
|
2757
|
+
image = qrImage(validateTicket({ requestId: payload.requestId, purpose: "bind", qr: options.bindingQr, pairingCode: "000000", expiresAt: options.expiresAt }, "bind", options.authLinkOrigin));
|
|
2758
|
+
}
|
|
2759
|
+
const abort = new AbortController();
|
|
2760
|
+
let timer;
|
|
2761
|
+
const dispose = (notify) => {
|
|
2762
|
+
if (closed) return;
|
|
2763
|
+
closed = true;
|
|
2764
|
+
abort.abort();
|
|
2765
|
+
clearInterval(timer);
|
|
2766
|
+
dialog.remove();
|
|
2767
|
+
previousFocus?.focus();
|
|
2768
|
+
if (notify) options.onClose?.();
|
|
2769
|
+
};
|
|
2770
|
+
const render = () => {
|
|
2771
|
+
if (closed) return;
|
|
2772
|
+
const l = getMessages(locale);
|
|
2773
|
+
dialog.lang = resolveLocale(locale);
|
|
2774
|
+
dialog.dataset.variant = variant;
|
|
2775
|
+
dialog.dataset.mode = mode;
|
|
2776
|
+
dialog.dataset.hasQr = String(Boolean(image));
|
|
2777
|
+
dialog.setAttribute("aria-label", l[mode]);
|
|
2778
|
+
close.setAttribute("aria-label", l.close);
|
|
2779
|
+
const focused = content.contains(document.activeElement);
|
|
2780
|
+
const remaining = Math.max(0, Math.ceil((deadline - Date.now()) / 1e3));
|
|
2781
|
+
const snapshot = { status: remaining ? "pending" : "expired", code: null, secondsRemaining: remaining, codeSecondsRemaining: remaining, submitting: busy, error: error ?? null };
|
|
2782
|
+
content.replaceChildren(element(widgetView({
|
|
2783
|
+
mode,
|
|
2784
|
+
locale,
|
|
2785
|
+
variant,
|
|
2786
|
+
passcodeMode: true,
|
|
2787
|
+
snapshot,
|
|
2788
|
+
qr: image,
|
|
2789
|
+
showQr: Boolean(image),
|
|
2790
|
+
inputCode: code,
|
|
2791
|
+
setCode: (value) => {
|
|
2792
|
+
code = value;
|
|
2793
|
+
},
|
|
2794
|
+
submitCode: submit,
|
|
2795
|
+
retry: () => {
|
|
2796
|
+
error = void 0;
|
|
2797
|
+
render();
|
|
2798
|
+
},
|
|
2799
|
+
close: () => dispose(true)
|
|
2800
|
+
})));
|
|
2801
|
+
if (focused) content.querySelector("input")?.focus();
|
|
2802
|
+
};
|
|
2803
|
+
const submit = async (value) => {
|
|
2804
|
+
if (closed || busy) return;
|
|
2805
|
+
if (Date.now() >= deadline) {
|
|
2806
|
+
render();
|
|
2807
|
+
return;
|
|
2808
|
+
}
|
|
2809
|
+
if (!/^[0-9]{6}$/.test(value)) {
|
|
2810
|
+
error = new AuthLinkError("PASSCODE_INVALID");
|
|
2811
|
+
render();
|
|
2812
|
+
return;
|
|
2813
|
+
}
|
|
2814
|
+
code = value;
|
|
2815
|
+
busy = true;
|
|
2816
|
+
error = void 0;
|
|
2817
|
+
render();
|
|
2818
|
+
try {
|
|
2819
|
+
const result = validateOTPResult(await options.client.verify(value, abort.signal));
|
|
2820
|
+
if (closed || abort.signal.aborted || Date.now() >= deadline) return;
|
|
2821
|
+
try {
|
|
2822
|
+
await options.onVerified?.(result);
|
|
2823
|
+
} catch {
|
|
2824
|
+
options.onError?.(new AuthLinkError("CALLBACK_FAILED"));
|
|
2825
|
+
}
|
|
2826
|
+
dispose(false);
|
|
2827
|
+
} catch (cause) {
|
|
2828
|
+
if (!closed && !abort.signal.aborted) {
|
|
2829
|
+
error = cause instanceof Error ? cause : new AuthLinkError("NETWORK_ERROR");
|
|
2830
|
+
options.onError?.(error);
|
|
2831
|
+
}
|
|
2832
|
+
} finally {
|
|
2833
|
+
busy = false;
|
|
2834
|
+
render();
|
|
2835
|
+
}
|
|
2836
|
+
};
|
|
2837
|
+
close.addEventListener("click", () => dispose(true));
|
|
2838
|
+
dialog.addEventListener("cancel", (event) => {
|
|
2839
|
+
event.preventDefault();
|
|
2840
|
+
dispose(true);
|
|
2841
|
+
});
|
|
2842
|
+
document.body.append(dialog);
|
|
2843
|
+
render();
|
|
2844
|
+
dialog.showModal();
|
|
2845
|
+
content.querySelector("input")?.focus();
|
|
2846
|
+
timer = setInterval(() => {
|
|
2847
|
+
if (closed) return;
|
|
2848
|
+
if (Date.now() >= deadline) {
|
|
2849
|
+
render();
|
|
2850
|
+
clearInterval(timer);
|
|
2851
|
+
void Promise.resolve(options.onExpired?.()).catch(() => options.onError?.(new AuthLinkError("CALLBACK_FAILED")));
|
|
2852
|
+
}
|
|
2853
|
+
}, 1e3);
|
|
2854
|
+
return {
|
|
2855
|
+
close: () => dispose(true),
|
|
2856
|
+
destroy: () => dispose(false),
|
|
2857
|
+
setLocale: (value) => {
|
|
2858
|
+
locale = value;
|
|
2859
|
+
render();
|
|
2860
|
+
},
|
|
2861
|
+
setVariant: (value) => {
|
|
2862
|
+
variant = resolveVariant(value);
|
|
2863
|
+
render();
|
|
2864
|
+
},
|
|
2865
|
+
retry: () => {
|
|
2866
|
+
error = void 0;
|
|
2867
|
+
render();
|
|
2868
|
+
}
|
|
2869
|
+
};
|
|
2870
|
+
}
|
|
2559
2871
|
export {
|
|
2560
2872
|
AuthLinkError,
|
|
2561
2873
|
createAuthLinkClient,
|
|
2874
|
+
createPasscodeClient,
|
|
2562
2875
|
initialSnapshot,
|
|
2563
2876
|
observeRequest,
|
|
2564
2877
|
openAuthLink,
|
|
2565
2878
|
openAuthLinkBind,
|
|
2566
2879
|
openAuthLinkConfirm,
|
|
2880
|
+
openPasscode,
|
|
2567
2881
|
qrImage,
|
|
2568
2882
|
requestKey,
|
|
2569
2883
|
supportedLocales,
|