@auth-link/web 2.0.0 → 3.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 +21 -0
- package/README.md +120 -129
- package/dist/index.js +203 -658
- package/dist/index.js.map +4 -4
- package/dist/react.js +227 -584
- package/dist/react.js.map +4 -4
- package/dist/types/core.d.ts +4 -38
- package/dist/types/index.d.ts +3 -7
- package/dist/types/modal.d.ts +3 -19
- package/dist/types/react.d.ts +4 -15
- package/dist/types/types.d.ts +35 -59
- package/dist/types/view.d.ts +6 -10
- package/dist/types/vue.d.ts +5 -16
- package/dist/vue.js +231 -626
- package/dist/vue.js.map +4 -4
- package/docs/README.en.md +41 -44
- package/docs/README.ja.md +41 -44
- package/docs/README.zh-CN.md +41 -44
- package/examples/react-client.tsx +9 -21
- package/examples/vue-client.vue +9 -26
- package/package.json +2 -2
- package/dist/types/passcode.d.ts +0 -28
package/docs/README.en.md
CHANGED
|
@@ -1,66 +1,63 @@
|
|
|
1
|
-
# AuthLink Web
|
|
1
|
+
# AuthLink Web 3.0
|
|
2
2
|
|
|
3
3
|
[English](README.en.md) · [简体中文](README.zh-CN.md) · [日本語](README.ja.md)
|
|
4
4
|
|
|
5
|
-
##
|
|
6
|
-
|
|
7
|
-
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.
|
|
8
|
-
|
|
9
|
-
## Direct rotating-code verification
|
|
10
|
-
|
|
11
|
-
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.
|
|
12
|
-
|
|
13
|
-
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.
|
|
5
|
+
## Install and use
|
|
14
6
|
|
|
15
7
|
```sh
|
|
16
|
-
npm install @auth-link/web@^
|
|
8
|
+
npm install @auth-link/web@^3.0.0
|
|
17
9
|
```
|
|
18
10
|
|
|
11
|
+
Same minimal responsive layout and 13 languages, Simplified Chinese by default. First enrollment shows a QR and a six-digit input; daily verification shows only the input. The SDK makes no HTTP requests, creates no authorization requests and never polls. There is no baseUrl, csrfToken, accessToken or fetch configuration.
|
|
12
|
+
|
|
19
13
|
```ts
|
|
20
|
-
import {
|
|
14
|
+
import { openVerify, openBind } from '@auth-link/web';
|
|
21
15
|
import '@auth-link/web/styles.css';
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
16
|
+
|
|
17
|
+
openVerify({
|
|
18
|
+
submit: async (passcode, { signal }) => {
|
|
19
|
+
const result = await cmsApi.verifyAuthLink({ passcode }, { signal });
|
|
20
|
+
if (!result.success) throw new Error(result.message || 'VERIFICATION_FAILED');
|
|
21
|
+
},
|
|
22
|
+
onSuccess: () => refreshPage(),
|
|
23
|
+
});
|
|
24
|
+
|
|
25
|
+
// First enrollment only; the CMS creates the binding ticket first.
|
|
26
|
+
openBind({
|
|
27
|
+
qr: ticket.qr,
|
|
28
|
+
expiresAt: ticket.expiresAt,
|
|
29
|
+
authLinkOrigin: 'https://api.getauthlink.com',
|
|
30
|
+
submit: async (passcode, { signal }) => {
|
|
31
|
+
await cmsApi.completeBinding({ passcode }, { signal });
|
|
32
|
+
// This wrapper must throw on HTTP AND business failure.
|
|
33
|
+
},
|
|
34
|
+
onSuccess: () => refreshAccounts(),
|
|
35
|
+
onRefresh: ({ signal }) => cmsApi.createBinding({ signal }),
|
|
28
36
|
});
|
|
29
|
-
// modal.setLocale('en'); modal.destroy();
|
|
30
37
|
```
|
|
31
38
|
|
|
32
|
-
The
|
|
39
|
+
The cmsApi functions above belong to your application, not this package. Reuse the CMS request wrapper for authentication, CSRF, CORS and business errors. Cookie authentication still requires your existing CSRF protection. Tenant API keys remain on the CMS server.
|
|
33
40
|
|
|
34
|
-
##
|
|
41
|
+
## Submit contract
|
|
35
42
|
|
|
36
|
-
|
|
43
|
+
`submit(passcode, { signal }): Promise<void>` receives the six digits as a string, preserving leading zeros. Resolve only after CMS verification AND the business operation succeed; throw on HTTP or business failure, including HTTP 200 with success=false. A returned JSON object is not inspected. Do not return {success:false}; throw instead. No verificationId or AuthLink receipt must be exposed to the SDK. CMS validates the receipt and stores verificationId with its business transaction.
|
|
37
44
|
|
|
38
|
-
|
|
45
|
+
The SDK blocks duplicate submissions. Failed codes remain editable for explicit retry. Closing/unmounting or action expiry aborts signal; forward it to your request layer. Cancellation cannot undo server work. Keep the original pending action and idempotency key for ambiguous outcomes. Never interpret a timeout as a failed business transaction.
|
|
39
46
|
|
|
40
|
-
|
|
47
|
+
Success closes the prompt and calls onSuccess without arguments. onSuccess only updates UI, never authorizes server work. An onSuccess failure does not reopen or resubmit the operation. onError receives the original Error. close() calls onClose; destroy() cleans up silently. retry() clears errors without network activity. setLocale(locale) changes language while retaining input.
|
|
41
48
|
|
|
42
|
-
|
|
49
|
+
## Time and binding refresh
|
|
43
50
|
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
```
|
|
50
|
-
```vue
|
|
51
|
-
<script setup>
|
|
52
|
-
import { AuthLinkPasscode } from '@auth-link/web/vue';
|
|
53
|
-
</script>
|
|
54
|
-
<template>
|
|
55
|
-
<AuthLinkPasscode :client="client" :expires-at="pending.expiresAt"
|
|
56
|
-
locale="zh-CN" @verified="updateUI" />
|
|
57
|
-
</template>
|
|
58
|
-
```
|
|
51
|
+
openVerify requires only submit; expiresAt is an optional CMS action deadline. There is no artificial five-minute SDK limit. It is NOT a countdown for the App's current code, whose generation time the browser does not know. The App code and receipt remain valid for at most one minute.
|
|
52
|
+
|
|
53
|
+
openBind additionally requires qr (JSON payload, not SVG/URL) and expiresAt returned by CMS. The binding QR lasts up to 60 minutes from creation; scanning and retrying do not extend it. authLinkOrigin optionally checks the expected AuthLink API origin. QR generation is local. onRefresh({signal}) is optional, returns Promise<{qr,expiresAt}>, and runs only when the user clicks refresh after expiry. The CMS owns replacement requests. A failed refresh stays expired and can be retried.
|
|
54
|
+
|
|
55
|
+
## React and Vue
|
|
59
56
|
|
|
60
|
-
|
|
57
|
+
Import AuthLinkVerify / AuthLinkBind from @auth-link/web/react or @auth-link/web/vue. Options match the JavaScript API; Vue emits success, close, error, expired. onRefresh remains a function prop that returns a ticket. Components render no dialog during SSR and abort browser work on unmount. Unmount the component on success/close/expiry before preparing another operation. React supports updated callback references without resetting the form.
|
|
61
58
|
|
|
62
|
-
|
|
59
|
+
See [React example](../examples/react-client.tsx) and [Vue example](../examples/vue-client.vue). Explicitly import @auth-link/web/styles.css. React 18.2+/19, Vue 3.3+, ESM and TypeScript are supported; the development toolchain requires Node 22.13+.
|
|
63
60
|
|
|
64
|
-
|
|
61
|
+
## Migrate from 2.x
|
|
65
62
|
|
|
66
|
-
|
|
63
|
+
Remove createAuthLinkClient, createPasscodeClient, openPasscode, openAuthLink*, observeRequest, Ticket/Consume, AuthLinkPasscode, AuthLinkConfirm and useAuthLink. Replace client.verify with submit(code,{signal}); onVerified/onConfirmed with onSuccess(). Use openBind({qr,expiresAt,submit}) for initial enrollment and openVerify({submit}) for daily checks. Remove HTTP/token settings and legacy result/polling code. Move all network/authentication handling to the CMS wrapper. Go SDK and AuthLink server APIs do not change.
|
package/docs/README.ja.md
CHANGED
|
@@ -1,66 +1,63 @@
|
|
|
1
|
-
# AuthLink Web
|
|
1
|
+
# AuthLink Web 3.0
|
|
2
2
|
|
|
3
3
|
[English](README.en.md) · [简体中文](README.zh-CN.md) · [日本語](README.ja.md)
|
|
4
4
|
|
|
5
|
-
##
|
|
6
|
-
|
|
7
|
-
すべてのダイアログはシンプルレイアウトに統一されました。variant オプション・プロパティ、modal.setVariant() の呼び出し、DialogVariant 型のインポートを削除してください。言語切り替えと認証コールバックは変更ありません。
|
|
8
|
-
|
|
9
|
-
## 認証コードを直接検証
|
|
10
|
-
|
|
11
|
-
アプリに6桁の認証コードを直接表示します。通常の検証では、毎回の承認、認証用requestId、businessId、ポーリングは不要です。初回はQRで端末を確認し、サイトで現在のコードを検証して連携を完了します。
|
|
12
|
-
|
|
13
|
-
画面を開く前にCMSサーバーでセッションの唯一の保留中操作を原子的に確保します。別タブから上書きさせません。ユーザーはサーバーのセッションから取得し、CSRF、業務権限、元のフォームを確認します。コードを検証し、verificationIdと元の操作を原子的に確定してから成功を返します。onVerifiedは表示更新専用です。
|
|
5
|
+
## インストールと使い方
|
|
14
6
|
|
|
15
7
|
```sh
|
|
16
|
-
npm install @auth-link/web@^
|
|
8
|
+
npm install @auth-link/web@^3.0.0
|
|
17
9
|
```
|
|
18
10
|
|
|
11
|
+
従来のシンプルなレスポンシブ画面と13言語を維持します。既定は簡体字中国語です。初回連携はQRコードと6桁入力、通常認証は入力のみです。SDKはHTTP通信、操作ごとの認証リクエスト作成、ポーリングを行いません。baseUrl、csrfToken、accessToken、fetchの設定は不要です。
|
|
12
|
+
|
|
19
13
|
```ts
|
|
20
|
-
import {
|
|
14
|
+
import { openVerify, openBind } from '@auth-link/web';
|
|
21
15
|
import '@auth-link/web/styles.css';
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
16
|
+
|
|
17
|
+
openVerify({
|
|
18
|
+
submit: async (passcode, { signal }) => {
|
|
19
|
+
const result = await cmsApi.verifyAuthLink({ passcode }, { signal });
|
|
20
|
+
if (!result.success) throw new Error(result.message || 'VERIFICATION_FAILED');
|
|
21
|
+
},
|
|
22
|
+
onSuccess: () => refreshPage(),
|
|
23
|
+
});
|
|
24
|
+
|
|
25
|
+
// First enrollment only; the CMS creates the binding ticket first.
|
|
26
|
+
openBind({
|
|
27
|
+
qr: ticket.qr,
|
|
28
|
+
expiresAt: ticket.expiresAt,
|
|
29
|
+
authLinkOrigin: 'https://api.getauthlink.com',
|
|
30
|
+
submit: async (passcode, { signal }) => {
|
|
31
|
+
await cmsApi.completeBinding({ passcode }, { signal });
|
|
32
|
+
// This wrapper must throw on HTTP AND business failure.
|
|
33
|
+
},
|
|
34
|
+
onSuccess: () => refreshAccounts(),
|
|
35
|
+
onRefresh: ({ signal }) => cmsApi.createBinding({ signal }),
|
|
28
36
|
});
|
|
29
|
-
// modal.setLocale('en'); modal.destroy();
|
|
30
37
|
```
|
|
31
38
|
|
|
32
|
-
|
|
39
|
+
cmsApi はサイト側の既存リクエスト処理です。認証、CSRF、CORS、業務エラーはCMS側で処理してください。Cookie認証では既存のCSRF対策を維持し、テナントAPIキーはサーバーにのみ保存します。
|
|
33
40
|
|
|
34
|
-
##
|
|
41
|
+
## submit の契約
|
|
35
42
|
|
|
36
|
-
|
|
43
|
+
`submit(passcode, { signal }): Promise<void>` は先頭ゼロを含む6桁の文字列を受け取ります。CMSがコード検証と業務処理を完了してから正常終了し、HTTPまたは業務エラーでは例外を投げます。HTTP 200でもsuccess=falseなら例外が必要です。SDKは戻り値JSONを判定しません。return {success:false} は失敗通知になりません。AuthLinkの検証結果やverificationIdをブラウザーへ返す必要はなく、CMSが検証して業務トランザクションに保存します。
|
|
37
44
|
|
|
38
|
-
|
|
45
|
+
二重送信を防ぎ、エラー後は明示的に再送できます。閉じる、アンマウント、CMS操作の期限切れでsignalがキャンセルされるため、リクエスト層へ渡してください。ブラウザーの中止はサーバー処理の取り消しではありません。結果不明の場合は元の操作、コード、冪等キーを維持し、別の業務操作を作成しないでください。
|
|
39
46
|
|
|
40
|
-
|
|
47
|
+
成功時は画面を閉じて引数なしのonSuccessを呼びます。onSuccessは表示更新専用です。その失敗で業務を再送しません。onErrorは元のErrorを受け取り、close()はonCloseを通知、destroy()は通知せず終了します。retry()はエラーを消すだけです。setLocale(locale)は入力を維持して言語を切り替えます。
|
|
41
48
|
|
|
42
|
-
|
|
49
|
+
## 期限とQR更新
|
|
43
50
|
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
```
|
|
50
|
-
```vue
|
|
51
|
-
<script setup>
|
|
52
|
-
import { AuthLinkPasscode } from '@auth-link/web/vue';
|
|
53
|
-
</script>
|
|
54
|
-
<template>
|
|
55
|
-
<AuthLinkPasscode :client="client" :expires-at="pending.expiresAt"
|
|
56
|
-
locale="zh-CN" @verified="updateUI" />
|
|
57
|
-
</template>
|
|
58
|
-
```
|
|
51
|
+
openVerifyはsubmitのみ必須で、expiresAtはCMS操作の任意の期限です。SDK側の5分制限はありません。Appの現在のコード生成時刻はブラウザーから分からないため、1分のカウントダウンを仮定しません。Appコードと検証検証結果は引き続き最長1分です。
|
|
52
|
+
|
|
53
|
+
openBindはCMSが返したqr(画像URLではなくJSON)とexpiresAtも必要です。QRは作成から最長60分で、スキャンや再試行では延長しません。authLinkOriginは任意のAuthLink APIオリジン照合です。QR描画はローカルのみです。onRefresh({signal})はPromise<{qr,expiresAt}>を返し、期限切れ後に利用者が更新を選んだ場合のみ実行します。新規リクエストはCMSが管理し、更新失敗時は期限切れのまま再試行できます。
|
|
54
|
+
|
|
55
|
+
## React / Vue
|
|
59
56
|
|
|
60
|
-
|
|
57
|
+
@auth-link/web/react または @auth-link/web/vue からAuthLinkVerify / AuthLinkBindをインポートします。JavaScriptと同じオプションで、Vueはsuccess、close、error、expiredを通知します。onRefreshはチケットを返す関数propです。SSRでは画面を開かず、アンマウント時に中止します。成功・終了後は親側でアンマウントし、次の操作を準備してください。Reactはコールバック更新で入力をリセットしません。
|
|
61
58
|
|
|
62
|
-
|
|
59
|
+
[React例](../examples/react-client.tsx)、[Vue例](../examples/vue-client.vue)。@auth-link/web/styles.cssを明示的に読み込みます。React 18.2+/19、Vue 3.3+、ESM、TypeScriptに対応し、開発にはNode 22.13+が必要です。
|
|
63
60
|
|
|
64
|
-
|
|
61
|
+
## 2.xからの移行
|
|
65
62
|
|
|
66
|
-
|
|
63
|
+
createAuthLinkClient、createPasscodeClient、openPasscode、openAuthLink*、observeRequest、Ticket/Consume、AuthLinkPasscode、AuthLinkConfirm、useAuthLinkは削除されました。client.verifyをsubmit(code,{signal})、onVerified/onConfirmedをonSuccess()へ変更します。初回はopenBind({qr,expiresAt,submit})、通常はopenVerify({submit})です。HTTPやToken設定をCMSの通信層に移します。Go SDKとAuthLinkサーバーAPIの変更は不要です。
|
package/docs/README.zh-CN.md
CHANGED
|
@@ -1,66 +1,63 @@
|
|
|
1
|
-
# AuthLink Web
|
|
1
|
+
# AuthLink Web 3.0
|
|
2
2
|
|
|
3
3
|
[English](README.en.md) · [简体中文](README.zh-CN.md) · [日本語](README.ja.md)
|
|
4
4
|
|
|
5
|
-
##
|
|
6
|
-
|
|
7
|
-
所有弹窗统一使用极简布局。请删除 variant 参数或组件属性、modal.setVariant() 调用和 DialogVariant 类型导入。语言切换与验证回调保持不变。
|
|
8
|
-
|
|
9
|
-
## 直接验证动态码
|
|
10
|
-
|
|
11
|
-
App 直接显示六位动态码。日常验证不需要逐次批准、授权 requestId、businessId 或轮询。首次绑定仍需扫码验证设备,在网站输入 App 当前动态码后才完成绑定。
|
|
12
|
-
|
|
13
|
-
打开弹窗前,CMS 后台必须为会话原子保留唯一且不可变的待办。其他标签页不能覆盖它。用户来自服务端会话,后台检查 CSRF、业务权限和原表单,验证动态码后将 verificationId 与原操作原子提交,再返回成功。onVerified 只更新界面。
|
|
5
|
+
## 安装与使用
|
|
14
6
|
|
|
15
7
|
```sh
|
|
16
|
-
npm install @auth-link/web@^
|
|
8
|
+
npm install @auth-link/web@^3.0.0
|
|
17
9
|
```
|
|
18
10
|
|
|
11
|
+
保留原有极简响应式布局和 13 种语言,默认简体中文。首次绑定显示二维码和六位码输入框,日常验证仅显示输入框。SDK 不发送 HTTP 请求、不创建逐次授权请求、不轮询,无需配置 baseUrl、csrfToken、accessToken 或 fetch。
|
|
12
|
+
|
|
19
13
|
```ts
|
|
20
|
-
import {
|
|
14
|
+
import { openVerify, openBind } from '@auth-link/web';
|
|
21
15
|
import '@auth-link/web/styles.css';
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
16
|
+
|
|
17
|
+
openVerify({
|
|
18
|
+
submit: async (passcode, { signal }) => {
|
|
19
|
+
const result = await cmsApi.verifyAuthLink({ passcode }, { signal });
|
|
20
|
+
if (!result.success) throw new Error(result.message || 'VERIFICATION_FAILED');
|
|
21
|
+
},
|
|
22
|
+
onSuccess: () => refreshPage(),
|
|
23
|
+
});
|
|
24
|
+
|
|
25
|
+
// First enrollment only; the CMS creates the binding ticket first.
|
|
26
|
+
openBind({
|
|
27
|
+
qr: ticket.qr,
|
|
28
|
+
expiresAt: ticket.expiresAt,
|
|
29
|
+
authLinkOrigin: 'https://api.getauthlink.com',
|
|
30
|
+
submit: async (passcode, { signal }) => {
|
|
31
|
+
await cmsApi.completeBinding({ passcode }, { signal });
|
|
32
|
+
// This wrapper must throw on HTTP AND business failure.
|
|
33
|
+
},
|
|
34
|
+
onSuccess: () => refreshAccounts(),
|
|
35
|
+
onRefresh: ({ signal }) => cmsApi.createBinding({ signal }),
|
|
28
36
|
});
|
|
29
|
-
// modal.setLocale('en'); modal.destroy();
|
|
30
37
|
```
|
|
31
38
|
|
|
32
|
-
|
|
39
|
+
示例中的 cmsApi 是 CMS 自己的请求封装,不是本 SDK 提供的方法。复用已有登录态、CSRF、跨域和错误处理;Cookie 模式仍需 CMS 原有的 CSRF 保护。租户密钥只保存在 CMS 服务端。
|
|
33
40
|
|
|
34
|
-
##
|
|
41
|
+
## submit 返回什么
|
|
35
42
|
|
|
36
|
-
|
|
43
|
+
`submit(passcode, { signal }): Promise<void>` 接收六位数字字符串,保留前导零。只有 CMS 校验验证码并完成业务后才能正常结束;HTTP 或业务失败必须抛错,包括 HTTP 200 但 success=false。SDK 不检查返回 JSON,不能用 return {success:false} 代替抛错。前端不必返回 AuthLink 回执或 verificationId;由 CMS 后台核验并与业务事务一起保存。
|
|
37
44
|
|
|
38
|
-
|
|
45
|
+
SDK 防止重复提交,失败保留输入供用户主动重试。关闭、卸载或业务待办过期会取消 signal,请传给请求层。取消前端等待不能撤销后台已完成的操作;网络结果不明确时保留原待办、原验证码及原幂等键重试,不要另建业务操作。
|
|
39
46
|
|
|
40
|
-
|
|
47
|
+
成功时关闭弹窗并调用无参数 onSuccess,回调只更新页面,不负责后台放行。页面更新失败不会重新打开或重复提交。onError 接收原 Error;close() 触发 onClose,destroy() 静默清理。retry() 只清除错误,setLocale(locale) 保留输入切换语言,二者都不会自动发送请求。
|
|
41
48
|
|
|
42
|
-
|
|
49
|
+
## 有效期与二维码刷新
|
|
43
50
|
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
```
|
|
50
|
-
```vue
|
|
51
|
-
<script setup>
|
|
52
|
-
import { AuthLinkPasscode } from '@auth-link/web/vue';
|
|
53
|
-
</script>
|
|
54
|
-
<template>
|
|
55
|
-
<AuthLinkPasscode :client="client" :expires-at="pending.expiresAt"
|
|
56
|
-
locale="zh-CN" @verified="updateUI" />
|
|
57
|
-
</template>
|
|
58
|
-
```
|
|
51
|
+
openVerify 只要求 submit。expiresAt 可选,表示 CMS 当前业务待办的截止时间,SDK 不再强制五分钟上限。网页不知道 App 当前码何时生成,因此不伪造一分钟验证码倒计时;App 的数字码和服务端回执仍最多有效一分钟。
|
|
52
|
+
|
|
53
|
+
openBind 还要求 CMS 返回的 qr(二维码 JSON 内容,不是图片或 URL)和 expiresAt。二维码从创建起最多有效 60 分钟,扫码和重试不延长。authLinkOrigin 可选,仅核对 AuthLink API 来源。二维码在本地生成。onRefresh({signal}) 可选,返回 Promise<{qr,expiresAt}>;仅过期后用户主动点击重新获取时执行,由 CMS 创建替换请求。刷新失败保持过期状态,可再次重试。
|
|
54
|
+
|
|
55
|
+
## React 与 Vue
|
|
59
56
|
|
|
60
|
-
|
|
57
|
+
从 @auth-link/web/react 或 @auth-link/web/vue 导入 AuthLinkVerify / AuthLinkBind,参数与 JavaScript 一致。Vue 发出 success、close、error、expired 事件;onRefresh 是返回新二维码的函数属性。SSR 不打开弹窗,卸载时自动取消等待。成功、关闭或过期后由父组件卸载,再准备新操作;React 更新回调引用不会清空输入。
|
|
61
58
|
|
|
62
|
-
|
|
59
|
+
参见 [React 示例](../examples/react-client.tsx)、[Vue 示例](../examples/vue-client.vue)。显式导入 @auth-link/web/styles.css。支持 React 18.2+/19、Vue 3.3+、ESM 和 TypeScript,开发工具链要求 Node 22.13+。
|
|
63
60
|
|
|
64
|
-
|
|
61
|
+
## 从 2.x 升级
|
|
65
62
|
|
|
66
|
-
|
|
63
|
+
移除 createAuthLinkClient、createPasscodeClient、openPasscode、openAuthLink*、observeRequest、Ticket/Consume、AuthLinkPasscode、AuthLinkConfirm 和 useAuthLink。client.verify 改为 submit(code,{signal});onVerified/onConfirmed 改为无参数 onSuccess。首次绑定使用 openBind({qr,expiresAt,submit}),日常验证使用 openVerify({submit})。删除 SDK 的 HTTP/Token 配置及旧审批流程,网络鉴权交给 CMS 请求层。Go SDK 和 AuthLink 服务端接口无需调整。
|
|
@@ -1,24 +1,12 @@
|
|
|
1
1
|
"use client";
|
|
2
|
-
import {
|
|
3
|
-
import type {
|
|
4
|
-
|
|
5
|
-
//
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
// that backend slot before allowing another operation to start.
|
|
9
|
-
export function AuthLinkPanel({ client, pending, onVerified, onClose }: {
|
|
10
|
-
client: PasscodeClient;
|
|
11
|
-
pending: { expiresAt: string; bindingQr?: string };
|
|
12
|
-
onVerified: (result: OTPVerification) => void;
|
|
13
|
-
onClose: () => void;
|
|
2
|
+
import { AuthLinkVerify, AuthLinkBind } from '@auth-link/web/react';
|
|
3
|
+
import type { Submit, BindingTicket } from '@auth-link/web';
|
|
4
|
+
// Import '@auth-link/web/styles.css' once in the app entry.
|
|
5
|
+
// The CMS prepares its pending action before rendering this component.
|
|
6
|
+
export function AuthLinkPanel({ submit, binding, onSuccess, onClose }: {
|
|
7
|
+
submit: Submit; binding?: BindingTicket; onSuccess: () => void; onClose: () => void;
|
|
14
8
|
}) {
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
<
|
|
18
|
-
bindingQr={pending.bindingQr} authLinkOrigin="https://api.getauthlink.com"
|
|
19
|
-
locale="en" onVerified={onVerified} onClose={onClose}
|
|
20
|
-
onExpired={() => setMessage('Expired; start a new action')}
|
|
21
|
-
onError={error => setMessage(error.message)} />
|
|
22
|
-
<p role="status">{message}</p>
|
|
23
|
-
</>;
|
|
9
|
+
return binding
|
|
10
|
+
? <AuthLinkBind {...binding} submit={submit} onSuccess={onSuccess} onClose={onClose} />
|
|
11
|
+
: <AuthLinkVerify submit={submit} onSuccess={onSuccess} onClose={onClose} />;
|
|
24
12
|
}
|
package/examples/vue-client.vue
CHANGED
|
@@ -1,31 +1,14 @@
|
|
|
1
1
|
<script setup lang="ts">
|
|
2
|
-
import {
|
|
3
|
-
import {
|
|
4
|
-
import type { OTPVerification } from '@auth-link/web';
|
|
5
|
-
import { AuthLinkPasscode } from '@auth-link/web/vue';
|
|
2
|
+
import { AuthLinkVerify, AuthLinkBind } from '@auth-link/web/vue';
|
|
3
|
+
import type { Submit, BindingTicket } from '@auth-link/web';
|
|
6
4
|
import '@auth-link/web/styles.css';
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
const props = defineProps<{
|
|
11
|
-
csrf: string;
|
|
12
|
-
pending: { expiresAt: string; bindingQr?: string };
|
|
13
|
-
}>();
|
|
14
|
-
const emit = defineEmits<{
|
|
15
|
-
verified: [result: OTPVerification];
|
|
16
|
-
close: [];
|
|
17
|
-
}>();
|
|
18
|
-
const message = ref('');
|
|
19
|
-
const client = markRaw(createPasscodeClient({ baseUrl: '/api', csrfToken: () => props.csrf }));
|
|
20
|
-
function verified(result: OTPVerification) { emit('verified', result); }
|
|
21
|
-
function showError(error: Error) { message.value = error.message; }
|
|
22
|
-
// The parent cancels its backend slot before preparing another action.
|
|
5
|
+
// The CMS request wrapper owns authentication, CSRF and business errors.
|
|
6
|
+
defineProps<{ submit: Submit; binding?: BindingTicket }>();
|
|
7
|
+
const emit = defineEmits<{ success: []; close: [] }>();
|
|
23
8
|
</script>
|
|
24
|
-
|
|
25
9
|
<template>
|
|
26
|
-
<
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
@
|
|
30
|
-
<p role="status">{{ message }}</p>
|
|
10
|
+
<AuthLinkBind v-if="binding" v-bind="binding" :submit="submit"
|
|
11
|
+
@success="emit('success')" @close="emit('close')" />
|
|
12
|
+
<AuthLinkVerify v-else :submit="submit"
|
|
13
|
+
@success="emit('success')" @close="emit('close')" />
|
|
31
14
|
</template>
|
package/package.json
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@auth-link/web",
|
|
3
|
-
"version": "
|
|
3
|
+
"version": "3.0.0",
|
|
4
4
|
"private": false,
|
|
5
|
-
"description": "
|
|
5
|
+
"description": "Callback-driven AuthLink binding and six-digit verification dialogs. No HTTP client; JavaScript, React, Vue and 13 languages.",
|
|
6
6
|
"type": "module",
|
|
7
7
|
"license": "MIT",
|
|
8
8
|
"files": [
|
package/dist/types/passcode.d.ts
DELETED
|
@@ -1,28 +0,0 @@
|
|
|
1
|
-
import type { ClientOptions } from './core.js';
|
|
2
|
-
import type { AuthLinkModal } from './modal.js';
|
|
3
|
-
import type { Locale } from './types.js';
|
|
4
|
-
export interface OTPVerification {
|
|
5
|
-
status: 'confirmed';
|
|
6
|
-
verificationId: string;
|
|
7
|
-
authenticationPolicy: 'device-totp.v1';
|
|
8
|
-
expiresAt: string;
|
|
9
|
-
}
|
|
10
|
-
export interface PasscodeClient {
|
|
11
|
-
verify(passcode: string, signal: AbortSignal): Promise<OTPVerification>;
|
|
12
|
-
}
|
|
13
|
-
export interface PasscodeOptions {
|
|
14
|
-
client: PasscodeClient;
|
|
15
|
-
/** The CMS's single pending action deadline, not a TOTP time step. */
|
|
16
|
-
expiresAt: string;
|
|
17
|
-
locale?: Locale;
|
|
18
|
-
/** First-time enrollment only. Ordinary verification has no QR or request ID. */
|
|
19
|
-
bindingQr?: string;
|
|
20
|
-
authLinkOrigin?: string;
|
|
21
|
-
onVerified?: (result: OTPVerification) => void | Promise<void>;
|
|
22
|
-
onClose?: () => void;
|
|
23
|
-
onExpired?: () => void | Promise<void>;
|
|
24
|
-
onError?: (error: Error) => void;
|
|
25
|
-
}
|
|
26
|
-
export declare function createPasscodeClient(options: ClientOptions): PasscodeClient;
|
|
27
|
-
/** A session-scoped passcode prompt. No request creation, request ID or polling. */
|
|
28
|
-
export declare function openPasscode(options: PasscodeOptions): AuthLinkModal;
|