@auth-link/web 1.1.0 → 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 +7 -0
- package/README.md +33 -21
- package/dist/index.js +6 -32
- package/dist/index.js.map +2 -2
- package/dist/react.js +6 -38
- package/dist/react.js.map +2 -2
- package/dist/styles.css +5 -49
- package/dist/types/modal.d.ts +1 -3
- package/dist/types/passcode.d.ts +1 -2
- package/dist/types/react.d.ts +1 -1
- package/dist/types/types.d.ts +0 -3
- package/dist/types/view.d.ts +1 -4
- package/dist/types/vue.d.ts +1 -1
- package/dist/vue.js +7 -37
- package/dist/vue.js.map +2 -2
- package/docs/README.en.md +12 -8
- package/docs/README.ja.md +12 -8
- package/docs/README.zh-CN.md +12 -8
- package/examples/react-client.tsx +1 -1
- package/examples/vue-client.vue +1 -1
- package/package.json +2 -2
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,12 @@
|
|
|
1
1
|
# Changelog
|
|
2
2
|
|
|
3
|
+
## 2.0.0 — 2026-11-13
|
|
4
|
+
|
|
5
|
+
- Use the responsive minimal layout for every JavaScript, React and Vue binding/verification dialog.
|
|
6
|
+
- **Breaking:** remove the variant option/prop, modal.setVariant() and DialogVariant type. Remove these from integrations when upgrading from 1.x.
|
|
7
|
+
- Remove split/compact layouts and their CSS; keep the existing minimal layout, language switching and verification behavior.
|
|
8
|
+
|
|
9
|
+
|
|
3
10
|
## 1.1.0 — 2026-11-13
|
|
4
11
|
|
|
5
12
|
- Add openPasscode, createPasscodeClient and React/Vue AuthLinkPasscode components for direct six-digit rotating-code verification.
|
package/README.md
CHANGED
|
@@ -4,6 +4,10 @@
|
|
|
4
4
|
|
|
5
5
|
## English
|
|
6
6
|
|
|
7
|
+
### Upgrading from 1.x
|
|
8
|
+
|
|
9
|
+
All dialogs now use the minimal layout. Remove the variant option/prop, modal.setVariant() calls and DialogVariant type imports. Language switching and verification callbacks are unchanged.
|
|
10
|
+
|
|
7
11
|
### Direct rotating-code verification
|
|
8
12
|
|
|
9
13
|
The app directly displays a six-digit rotating code. No per-action approval, authorization requestId, businessId or polling is required. First-time enrollment still scans a QR and verifies the phone; entering its current code on the website completes binding.
|
|
@@ -11,7 +15,7 @@ The app directly displays a six-digit rotating code. No per-action approval, aut
|
|
|
11
15
|
The CMS backend must reserve one immutable pending action per session before opening the prompt. Another tab cannot replace it. Obtain the user from the server session and check CSRF and business permissions. Verify the passcode on the server and atomically commit verificationId with the saved operation before returning success. onVerified only updates the UI.
|
|
12
16
|
|
|
13
17
|
```sh
|
|
14
|
-
npm install @auth-link/web@^
|
|
18
|
+
npm install @auth-link/web@^2.0.0
|
|
15
19
|
```
|
|
16
20
|
|
|
17
21
|
```ts
|
|
@@ -19,31 +23,31 @@ import { openPasscode, createPasscodeClient } from '@auth-link/web';
|
|
|
19
23
|
import '@auth-link/web/styles.css';
|
|
20
24
|
const client = createPasscodeClient({ baseUrl: '/api', csrfToken: () => csrfToken });
|
|
21
25
|
const modal = openPasscode({
|
|
22
|
-
client, expiresAt: pending.expiresAt, locale: 'zh-CN',
|
|
26
|
+
client, expiresAt: pending.expiresAt, locale: 'zh-CN',
|
|
23
27
|
// First-time enrollment only:
|
|
24
28
|
// bindingQr: pending.bindingQr, authLinkOrigin: 'https://api.getauthlink.com',
|
|
25
29
|
onVerified: result => updateUI(result.verificationId),
|
|
26
30
|
});
|
|
27
|
-
// modal.setLocale('en'); modal.
|
|
31
|
+
// modal.setLocale('en'); modal.destroy();
|
|
28
32
|
```
|
|
29
33
|
|
|
30
34
|
The default client posts only {passcode} to POST /api/auth with current CMS credentials and CSRF. To submit a form at the same time, supply your own client.verify callback and send {form,passcode} to your CMS. The CMS checks the form against its saved snapshot; never send tenant keys or passcode seeds to the browser.
|
|
31
35
|
|
|
32
36
|
### Options and callbacks
|
|
33
37
|
|
|
34
|
-
Required: client.verify(passcode, signal) and expiresAt (the pending CMS action deadline). Optional: locale,
|
|
38
|
+
Required: client.verify(passcode, signal) and expiresAt (the pending CMS action deadline). Optional: locale, bindingQr and authLinkOrigin for first enrollment only, onVerified, onError, onClose, onExpired. Success contains status, verificationId, authenticationPolicy and expiresAt; it has no requestId or businessId.
|
|
35
39
|
|
|
36
40
|
Cookie authentication requires CSRF. Bearer authentication uses accessToken with credentials=omit. For a cross-origin CMS explicitly set allowedBackendOrigins. Bare HTTPS origins are required outside loopback development.
|
|
37
41
|
|
|
38
42
|
### React and Vue
|
|
39
43
|
|
|
40
|
-
The React component takes the same options. Vue emits verified, error, close and expired. Keep client references stable. Thirteen languages remain supported; Simplified Chinese is the default.
|
|
44
|
+
The React component takes the same options. Vue emits verified, error, close and expired. Keep client references stable. Thirteen languages remain supported; Simplified Chinese is the default. All dialogs use one responsive minimal layout.
|
|
41
45
|
|
|
42
46
|
```tsx
|
|
43
47
|
import { AuthLinkPasscode } from '@auth-link/web/react';
|
|
44
48
|
// Keep client stable (for example with useMemo).
|
|
45
49
|
<AuthLinkPasscode client={client} expiresAt={pending.expiresAt}
|
|
46
|
-
locale="zh-CN"
|
|
50
|
+
locale="zh-CN" onVerified={updateUI} />
|
|
47
51
|
```
|
|
48
52
|
```vue
|
|
49
53
|
<script setup>
|
|
@@ -51,7 +55,7 @@ import { AuthLinkPasscode } from '@auth-link/web/vue';
|
|
|
51
55
|
</script>
|
|
52
56
|
<template>
|
|
53
57
|
<AuthLinkPasscode :client="client" :expires-at="pending.expiresAt"
|
|
54
|
-
locale="zh-CN"
|
|
58
|
+
locale="zh-CN" @verified="updateUI" />
|
|
55
59
|
</template>
|
|
56
60
|
```
|
|
57
61
|
|
|
@@ -67,6 +71,10 @@ The older openAuthLink / Ticket / Consume workflow remains available for the ear
|
|
|
67
71
|
|
|
68
72
|
## 简体中文
|
|
69
73
|
|
|
74
|
+
### 从 1.x 升级
|
|
75
|
+
|
|
76
|
+
所有弹窗统一使用极简布局。请删除 variant 参数或组件属性、modal.setVariant() 调用和 DialogVariant 类型导入。语言切换与验证回调保持不变。
|
|
77
|
+
|
|
70
78
|
### 直接验证动态码
|
|
71
79
|
|
|
72
80
|
App 直接显示六位动态码。日常验证不需要逐次批准、授权 requestId、businessId 或轮询。首次绑定仍需扫码验证设备,在网站输入 App 当前动态码后才完成绑定。
|
|
@@ -74,7 +82,7 @@ App 直接显示六位动态码。日常验证不需要逐次批准、授权 req
|
|
|
74
82
|
打开弹窗前,CMS 后台必须为会话原子保留唯一且不可变的待办。其他标签页不能覆盖它。用户来自服务端会话,后台检查 CSRF、业务权限和原表单,验证动态码后将 verificationId 与原操作原子提交,再返回成功。onVerified 只更新界面。
|
|
75
83
|
|
|
76
84
|
```sh
|
|
77
|
-
npm install @auth-link/web@^
|
|
85
|
+
npm install @auth-link/web@^2.0.0
|
|
78
86
|
```
|
|
79
87
|
|
|
80
88
|
```ts
|
|
@@ -82,31 +90,31 @@ import { openPasscode, createPasscodeClient } from '@auth-link/web';
|
|
|
82
90
|
import '@auth-link/web/styles.css';
|
|
83
91
|
const client = createPasscodeClient({ baseUrl: '/api', csrfToken: () => csrfToken });
|
|
84
92
|
const modal = openPasscode({
|
|
85
|
-
client, expiresAt: pending.expiresAt, locale: 'zh-CN',
|
|
93
|
+
client, expiresAt: pending.expiresAt, locale: 'zh-CN',
|
|
86
94
|
// First-time enrollment only:
|
|
87
95
|
// bindingQr: pending.bindingQr, authLinkOrigin: 'https://api.getauthlink.com',
|
|
88
96
|
onVerified: result => updateUI(result.verificationId),
|
|
89
97
|
});
|
|
90
|
-
// modal.setLocale('en'); modal.
|
|
98
|
+
// modal.setLocale('en'); modal.destroy();
|
|
91
99
|
```
|
|
92
100
|
|
|
93
101
|
默认客户端向 CMS 的 POST /api/auth 提交 {passcode},携带当前会话与 CSRF。要随表单提交,可自行实现 client.verify,向 CMS 发送 {form,passcode};后台核对原保存快照。租户密钥与动态码密钥不能进入浏览器。
|
|
94
102
|
|
|
95
103
|
### 选项与回调
|
|
96
104
|
|
|
97
|
-
必填:client.verify(passcode, signal)、expiresAt(CMS 待办截止时间)。可选:locale
|
|
105
|
+
必填:client.verify(passcode, signal)、expiresAt(CMS 待办截止时间)。可选:locale、仅首次绑定使用的 bindingQr 与 authLinkOrigin、onVerified、onError、onClose、onExpired。成功结果含 status、verificationId、authenticationPolicy、expiresAt,不含 requestId 或 businessId。
|
|
98
106
|
|
|
99
107
|
Cookie 模式必须配置 CSRF。Bearer 模式配置 accessToken 且 credentials=omit。跨域 CMS 必须显式配置 allowedBackendOrigins;回环开发之外使用 HTTPS。
|
|
100
108
|
|
|
101
109
|
### React 与 Vue
|
|
102
110
|
|
|
103
|
-
React 组件使用相同选项,Vue 发出 verified、error、close、expired 事件。client 引用需保持稳定。支持 13
|
|
111
|
+
React 组件使用相同选项,Vue 发出 verified、error、close、expired 事件。client 引用需保持稳定。支持 13 种语言,默认简体中文;统一使用响应式极简布局。
|
|
104
112
|
|
|
105
113
|
```tsx
|
|
106
114
|
import { AuthLinkPasscode } from '@auth-link/web/react';
|
|
107
115
|
// Keep client stable (for example with useMemo).
|
|
108
116
|
<AuthLinkPasscode client={client} expiresAt={pending.expiresAt}
|
|
109
|
-
locale="zh-CN"
|
|
117
|
+
locale="zh-CN" onVerified={updateUI} />
|
|
110
118
|
```
|
|
111
119
|
```vue
|
|
112
120
|
<script setup>
|
|
@@ -114,7 +122,7 @@ import { AuthLinkPasscode } from '@auth-link/web/vue';
|
|
|
114
122
|
</script>
|
|
115
123
|
<template>
|
|
116
124
|
<AuthLinkPasscode :client="client" :expires-at="pending.expiresAt"
|
|
117
|
-
locale="zh-CN"
|
|
125
|
+
locale="zh-CN" @verified="updateUI" />
|
|
118
126
|
</template>
|
|
119
127
|
```
|
|
120
128
|
|
|
@@ -130,6 +138,10 @@ destroy() 中止浏览器请求并清理计时器,不触发关闭回调;clos
|
|
|
130
138
|
|
|
131
139
|
## 日本語
|
|
132
140
|
|
|
141
|
+
### 1.x からの更新
|
|
142
|
+
|
|
143
|
+
すべてのダイアログはシンプルレイアウトに統一されました。variant オプション・プロパティ、modal.setVariant() の呼び出し、DialogVariant 型のインポートを削除してください。言語切り替えと認証コールバックは変更ありません。
|
|
144
|
+
|
|
133
145
|
### 認証コードを直接検証
|
|
134
146
|
|
|
135
147
|
アプリに6桁の認証コードを直接表示します。通常の検証では、毎回の承認、認証用requestId、businessId、ポーリングは不要です。初回はQRで端末を確認し、サイトで現在のコードを検証して連携を完了します。
|
|
@@ -137,7 +149,7 @@ destroy() 中止浏览器请求并清理计时器,不触发关闭回调;clos
|
|
|
137
149
|
画面を開く前にCMSサーバーでセッションの唯一の保留中操作を原子的に確保します。別タブから上書きさせません。ユーザーはサーバーのセッションから取得し、CSRF、業務権限、元のフォームを確認します。コードを検証し、verificationIdと元の操作を原子的に確定してから成功を返します。onVerifiedは表示更新専用です。
|
|
138
150
|
|
|
139
151
|
```sh
|
|
140
|
-
npm install @auth-link/web@^
|
|
152
|
+
npm install @auth-link/web@^2.0.0
|
|
141
153
|
```
|
|
142
154
|
|
|
143
155
|
```ts
|
|
@@ -145,31 +157,31 @@ import { openPasscode, createPasscodeClient } from '@auth-link/web';
|
|
|
145
157
|
import '@auth-link/web/styles.css';
|
|
146
158
|
const client = createPasscodeClient({ baseUrl: '/api', csrfToken: () => csrfToken });
|
|
147
159
|
const modal = openPasscode({
|
|
148
|
-
client, expiresAt: pending.expiresAt, locale: 'zh-CN',
|
|
160
|
+
client, expiresAt: pending.expiresAt, locale: 'zh-CN',
|
|
149
161
|
// First-time enrollment only:
|
|
150
162
|
// bindingQr: pending.bindingQr, authLinkOrigin: 'https://api.getauthlink.com',
|
|
151
163
|
onVerified: result => updateUI(result.verificationId),
|
|
152
164
|
});
|
|
153
|
-
// modal.setLocale('en'); modal.
|
|
165
|
+
// modal.setLocale('en'); modal.destroy();
|
|
154
166
|
```
|
|
155
167
|
|
|
156
168
|
標準クライアントは現在の認証情報とCSRFを付け、CMSのPOST /api/authへ{passcode}を送信します。フォームも送る場合はclient.verifyで{form,passcode}をCMSへ送信し、サーバーで保存済み内容と照合します。テナントキーやコード生成用秘密はブラウザーへ渡しません。
|
|
157
169
|
|
|
158
170
|
### オプションとコールバック
|
|
159
171
|
|
|
160
|
-
必須はclient.verify(passcode, signal)とexpiresAt(CMS操作の期限)です。任意でlocale
|
|
172
|
+
必須はclient.verify(passcode, signal)とexpiresAt(CMS操作の期限)です。任意でlocale、初回用bindingQrとauthLinkOrigin、onVerified、onError、onClose、onExpiredを指定します。成功結果はstatus、verificationId、authenticationPolicy、expiresAtを含み、requestIdやbusinessIdは含みません。
|
|
161
173
|
|
|
162
174
|
Cookie認証ではCSRFが必須です。Bearer認証はaccessTokenとcredentials=omitを使います。別オリジンのCMSはallowedBackendOriginsを明示し、ループバック開発以外ではHTTPSを使います。
|
|
163
175
|
|
|
164
176
|
### ReactとVue
|
|
165
177
|
|
|
166
|
-
Reactは同じオプションを使い、Vueはverified、error、close、expiredイベントを発行します。clientの参照を安定させてください。13
|
|
178
|
+
Reactは同じオプションを使い、Vueはverified、error、close、expiredイベントを発行します。clientの参照を安定させてください。13言語に対応し、既定は簡体字中国語です。すべてのダイアログはレスポンシブなシンプルレイアウトを使用します。
|
|
167
179
|
|
|
168
180
|
```tsx
|
|
169
181
|
import { AuthLinkPasscode } from '@auth-link/web/react';
|
|
170
182
|
// Keep client stable (for example with useMemo).
|
|
171
183
|
<AuthLinkPasscode client={client} expiresAt={pending.expiresAt}
|
|
172
|
-
locale="zh-CN"
|
|
184
|
+
locale="zh-CN" onVerified={updateUI} />
|
|
173
185
|
```
|
|
174
186
|
```vue
|
|
175
187
|
<script setup>
|
|
@@ -177,7 +189,7 @@ import { AuthLinkPasscode } from '@auth-link/web/vue';
|
|
|
177
189
|
</script>
|
|
178
190
|
<template>
|
|
179
191
|
<AuthLinkPasscode :client="client" :expires-at="pending.expiresAt"
|
|
180
|
-
locale="zh-CN"
|
|
192
|
+
locale="zh-CN" @verified="updateUI" />
|
|
181
193
|
</template>
|
|
182
194
|
```
|
|
183
195
|
|
package/dist/index.js
CHANGED
|
@@ -2392,12 +2392,9 @@ function getMessages(locale) {
|
|
|
2392
2392
|
|
|
2393
2393
|
// src/view.ts
|
|
2394
2394
|
var node = (tag, props, ...children) => ({ tag, props, children });
|
|
2395
|
-
function resolveVariant(variant) {
|
|
2396
|
-
return variant === "B" || variant === "C" ? variant : "A";
|
|
2397
|
-
}
|
|
2398
2395
|
function widgetView(options) {
|
|
2399
2396
|
const { snapshot: s, mode, retry, refresh } = options;
|
|
2400
|
-
const locale = resolveLocale(options.locale)
|
|
2397
|
+
const locale = resolveLocale(options.locale);
|
|
2401
2398
|
const l = getMessages(locale);
|
|
2402
2399
|
const pending = s.status === "pending", hasQr = pending && (mode === "bind" || Boolean(options.showQr)) && Boolean(options.qr);
|
|
2403
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];
|
|
@@ -2414,12 +2411,6 @@ function widgetView(options) {
|
|
|
2414
2411
|
expiring ? l.expiring : status,
|
|
2415
2412
|
...expiring ? [node("span", { class: "authlink-expiry", "aria-hidden": "true" }, ` \xB7 ${expiryTime}`)] : []
|
|
2416
2413
|
);
|
|
2417
|
-
const cancel = () => options.close ? [node("button", {
|
|
2418
|
-
type: "button",
|
|
2419
|
-
class: "authlink-cancel",
|
|
2420
|
-
"data-authlink-focus": "cancel",
|
|
2421
|
-
onClick: options.close
|
|
2422
|
-
}, l.cancel)] : [];
|
|
2423
2414
|
const children = [node("h3", { class: "authlink-title" }, l[mode])];
|
|
2424
2415
|
if (hasQr) children.push(node("p", { class: "authlink-subtitle" }, l.scan));
|
|
2425
2416
|
if (pending) {
|
|
@@ -2462,9 +2453,7 @@ function widgetView(options) {
|
|
|
2462
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)] : []
|
|
2463
2454
|
];
|
|
2464
2455
|
children.push(node("div", { class: "authlink-body" }, ...qr, node("div", { class: "authlink-details" }, ...detail)));
|
|
2465
|
-
|
|
2466
|
-
if (variant === "B") children.push(node("div", { class: "authlink-footer" }, statusNode(), ...cancel()));
|
|
2467
|
-
if (variant === "C") children.push(node("div", { class: "authlink-footer" }, statusNode(), ...cancel()));
|
|
2456
|
+
children.push(node("div", { class: "authlink-footer" }, statusNode()));
|
|
2468
2457
|
} else {
|
|
2469
2458
|
children.push(statusNode());
|
|
2470
2459
|
if (s.error?.message === "CONFIRMATION_CODE_LOCKED") children.push(node("p", { class: "authlink-input-error", role: "alert" }, l.codeLocked));
|
|
@@ -2485,7 +2474,6 @@ function widgetView(options) {
|
|
|
2485
2474
|
lang: locale,
|
|
2486
2475
|
class: `authlink-widget ${options.className ?? ""}`.trim(),
|
|
2487
2476
|
"data-status": s.status,
|
|
2488
|
-
"data-variant": variant,
|
|
2489
2477
|
"data-has-qr": String(hasQr),
|
|
2490
2478
|
"aria-label": l[mode]
|
|
2491
2479
|
}, ...children);
|
|
@@ -2529,7 +2517,7 @@ function openAuthLink(options) {
|
|
|
2529
2517
|
content.className = "authlink-modal-content";
|
|
2530
2518
|
header.append(brand, closeButton);
|
|
2531
2519
|
dialog.append(header, content);
|
|
2532
|
-
let locale = options.locale,
|
|
2520
|
+
let locale = options.locale, snapshot = initialSnapshot(), closed = false;
|
|
2533
2521
|
let abort;
|
|
2534
2522
|
let inputCode = "";
|
|
2535
2523
|
let submitCode;
|
|
@@ -2559,7 +2547,6 @@ function openAuthLink(options) {
|
|
|
2559
2547
|
const language = resolveLocale(locale), messages2 = getMessages(language);
|
|
2560
2548
|
dialog.lang = language;
|
|
2561
2549
|
dialog.setAttribute("aria-label", messages2[mode]);
|
|
2562
|
-
dialog.dataset.variant = variant;
|
|
2563
2550
|
dialog.dataset.mode = mode;
|
|
2564
2551
|
dialog.dataset.hasQr = String(snapshot.status === "pending" && (mode === "bind" || Boolean(options.showQr)));
|
|
2565
2552
|
closeButton.setAttribute("aria-label", messages2.close);
|
|
@@ -2568,7 +2555,6 @@ function openAuthLink(options) {
|
|
|
2568
2555
|
const next = element(widgetView({
|
|
2569
2556
|
mode,
|
|
2570
2557
|
locale,
|
|
2571
|
-
variant,
|
|
2572
2558
|
snapshot,
|
|
2573
2559
|
qr: image,
|
|
2574
2560
|
showQr: options.showQr,
|
|
@@ -2578,8 +2564,7 @@ function openAuthLink(options) {
|
|
|
2578
2564
|
},
|
|
2579
2565
|
submitCode: (code) => submitCode?.(code) ?? Promise.resolve(),
|
|
2580
2566
|
retry,
|
|
2581
|
-
refresh: options.onRefresh
|
|
2582
|
-
close: () => dispose(true)
|
|
2567
|
+
refresh: options.onRefresh
|
|
2583
2568
|
}));
|
|
2584
2569
|
const oldCode = content.querySelector(".authlink-code");
|
|
2585
2570
|
const nextCode = next.querySelector(".authlink-code");
|
|
@@ -2692,10 +2677,6 @@ function openAuthLink(options) {
|
|
|
2692
2677
|
locale = value;
|
|
2693
2678
|
render();
|
|
2694
2679
|
},
|
|
2695
|
-
setVariant: (value) => {
|
|
2696
|
-
variant = resolveVariant(value);
|
|
2697
|
-
render();
|
|
2698
|
-
},
|
|
2699
2680
|
retry
|
|
2700
2681
|
};
|
|
2701
2682
|
}
|
|
@@ -2744,7 +2725,7 @@ function openPasscode(options) {
|
|
|
2744
2725
|
content.className = "authlink-modal-content";
|
|
2745
2726
|
header.append(brand, close);
|
|
2746
2727
|
dialog.append(header, content);
|
|
2747
|
-
let locale = options.locale,
|
|
2728
|
+
let locale = options.locale, closed = false, busy = false, code = "", error;
|
|
2748
2729
|
const mode = options.bindingQr ? "bind" : "confirm";
|
|
2749
2730
|
let image;
|
|
2750
2731
|
if (options.bindingQr) {
|
|
@@ -2771,7 +2752,6 @@ function openPasscode(options) {
|
|
|
2771
2752
|
if (closed) return;
|
|
2772
2753
|
const l = getMessages(locale);
|
|
2773
2754
|
dialog.lang = resolveLocale(locale);
|
|
2774
|
-
dialog.dataset.variant = variant;
|
|
2775
2755
|
dialog.dataset.mode = mode;
|
|
2776
2756
|
dialog.dataset.hasQr = String(Boolean(image));
|
|
2777
2757
|
dialog.setAttribute("aria-label", l[mode]);
|
|
@@ -2782,7 +2762,6 @@ function openPasscode(options) {
|
|
|
2782
2762
|
content.replaceChildren(element(widgetView({
|
|
2783
2763
|
mode,
|
|
2784
2764
|
locale,
|
|
2785
|
-
variant,
|
|
2786
2765
|
passcodeMode: true,
|
|
2787
2766
|
snapshot,
|
|
2788
2767
|
qr: image,
|
|
@@ -2795,8 +2774,7 @@ function openPasscode(options) {
|
|
|
2795
2774
|
retry: () => {
|
|
2796
2775
|
error = void 0;
|
|
2797
2776
|
render();
|
|
2798
|
-
}
|
|
2799
|
-
close: () => dispose(true)
|
|
2777
|
+
}
|
|
2800
2778
|
})));
|
|
2801
2779
|
if (focused) content.querySelector("input")?.focus();
|
|
2802
2780
|
};
|
|
@@ -2858,10 +2836,6 @@ function openPasscode(options) {
|
|
|
2858
2836
|
locale = value;
|
|
2859
2837
|
render();
|
|
2860
2838
|
},
|
|
2861
|
-
setVariant: (value) => {
|
|
2862
|
-
variant = resolveVariant(value);
|
|
2863
|
-
render();
|
|
2864
|
-
},
|
|
2865
2839
|
retry: () => {
|
|
2866
2840
|
error = void 0;
|
|
2867
2841
|
render();
|