@arcblock/did-connect-react 3.4.14 → 3.5.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.
Files changed (208) hide show
  1. package/dist/standalone/did-connect-react.css +1 -0
  2. package/dist/standalone/index.js +133700 -0
  3. package/lib/Connect/components/login-item/connect-choose-list.js +111 -111
  4. package/lib/Connect/components/login-item/connect-provider-list.js +180 -180
  5. package/lib/Connect/components/login-item/mobile-login-item.js +56 -56
  6. package/lib/Connect/components/login-item/passkey-login-item.js +27 -29
  7. package/lib/Connect/components/login-item/web-login-item.js +31 -29
  8. package/lib/Connect/connect.js +202 -197
  9. package/lib/Connect/contexts/state.js +19 -17
  10. package/lib/Connect/hooks/provider-list.js +33 -33
  11. package/lib/Connect/plugins/email/list-item.js +14 -14
  12. package/lib/Connect/plugins/email/placeholder.js +77 -76
  13. package/lib/package.json.js +1 -1
  14. package/package.json +14 -9
  15. package/.aigne/doc-smith/config.yaml +0 -85
  16. package/.aigne/doc-smith/history.yaml +0 -6
  17. package/.aigne/doc-smith/output/structure-plan.json +0 -204
  18. package/.aigne/doc-smith/translation-cache.yaml +0 -11
  19. package/.aigne/doc-smith/upload-cache.yaml +0 -213
  20. package/docs/_sidebar.md +0 -18
  21. package/docs/advanced-authentication-methods.ja.md +0 -261
  22. package/docs/advanced-authentication-methods.md +0 -261
  23. package/docs/advanced-authentication-methods.zh-TW.md +0 -261
  24. package/docs/advanced-authentication-methods.zh.md +0 -261
  25. package/docs/advanced-utilities.ja.md +0 -132
  26. package/docs/advanced-utilities.md +0 -132
  27. package/docs/advanced-utilities.zh-TW.md +0 -132
  28. package/docs/advanced-utilities.zh.md +0 -132
  29. package/docs/advanced.ja.md +0 -95
  30. package/docs/advanced.md +0 -95
  31. package/docs/advanced.zh-TW.md +0 -95
  32. package/docs/advanced.zh.md +0 -95
  33. package/docs/api-reference.ja.md +0 -178
  34. package/docs/api-reference.md +0 -178
  35. package/docs/api-reference.zh-TW.md +0 -178
  36. package/docs/api-reference.zh.md +0 -178
  37. package/docs/assets/diagram/core-components-session-provider-01.ja.jpg +0 -0
  38. package/docs/assets/diagram/core-components-session-provider-01.jpg +0 -0
  39. package/docs/assets/diagram/core-components-session-provider-01.zh-TW.jpg +0 -0
  40. package/docs/assets/diagram/core-components-session-provider-01.zh.jpg +0 -0
  41. package/docs/assets/diagram/did-connect-diagram-0.ja.jpg +0 -0
  42. package/docs/assets/diagram/did-connect-diagram-0.jpg +0 -0
  43. package/docs/assets/diagram/did-connect-diagram-0.zh-TW.jpg +0 -0
  44. package/docs/assets/diagram/did-connect-diagram-0.zh.jpg +0 -0
  45. package/docs/assets/diagram/overview-01.ja.jpg +0 -0
  46. package/docs/assets/diagram/overview-01.jpg +0 -0
  47. package/docs/assets/diagram/overview-01.zh-TW.jpg +0 -0
  48. package/docs/assets/diagram/overview-01.zh.jpg +0 -0
  49. package/docs/assets/diagram/use-connect-diagram-0.ja.jpg +0 -0
  50. package/docs/assets/diagram/use-connect-diagram-0.jpg +0 -0
  51. package/docs/assets/diagram/use-connect-diagram-0.zh-TW.jpg +0 -0
  52. package/docs/assets/diagram/use-connect-diagram-0.zh.jpg +0 -0
  53. package/docs/core-components-did-connect.ja.md +0 -166
  54. package/docs/core-components-did-connect.md +0 -166
  55. package/docs/core-components-did-connect.zh-TW.md +0 -166
  56. package/docs/core-components-did-connect.zh.md +0 -166
  57. package/docs/core-components-session-provider.ja.md +0 -197
  58. package/docs/core-components-session-provider.md +0 -197
  59. package/docs/core-components-session-provider.zh-TW.md +0 -197
  60. package/docs/core-components-session-provider.zh.md +0 -197
  61. package/docs/core-components.ja.md +0 -16
  62. package/docs/core-components.md +0 -16
  63. package/docs/core-components.zh-TW.md +0 -16
  64. package/docs/core-components.zh.md +0 -16
  65. package/docs/getting-started.ja.md +0 -138
  66. package/docs/getting-started.md +0 -138
  67. package/docs/getting-started.zh-TW.md +0 -138
  68. package/docs/getting-started.zh.md +0 -138
  69. package/docs/hooks-use-connect.ja.md +0 -178
  70. package/docs/hooks-use-connect.md +0 -178
  71. package/docs/hooks-use-connect.zh-TW.md +0 -178
  72. package/docs/hooks-use-connect.zh.md +0 -178
  73. package/docs/hooks-use-did.ja.md +0 -107
  74. package/docs/hooks-use-did.md +0 -107
  75. package/docs/hooks-use-did.zh-TW.md +0 -107
  76. package/docs/hooks-use-did.zh.md +0 -107
  77. package/docs/hooks-use-oauth-passkey.ja.md +0 -188
  78. package/docs/hooks-use-oauth-passkey.md +0 -188
  79. package/docs/hooks-use-oauth-passkey.zh-TW.md +0 -188
  80. package/docs/hooks-use-oauth-passkey.zh.md +0 -188
  81. package/docs/hooks.ja.md +0 -23
  82. package/docs/hooks.md +0 -23
  83. package/docs/hooks.zh-TW.md +0 -23
  84. package/docs/hooks.zh.md +0 -23
  85. package/docs/overview.ja.md +0 -119
  86. package/docs/overview.md +0 -119
  87. package/docs/overview.zh-TW.md +0 -119
  88. package/docs/overview.zh.md +0 -119
  89. package/docs/ui-components-address.ja.md +0 -121
  90. package/docs/ui-components-address.md +0 -121
  91. package/docs/ui-components-address.zh-TW.md +0 -121
  92. package/docs/ui-components-address.zh.md +0 -121
  93. package/docs/ui-components-avatar.ja.md +0 -65
  94. package/docs/ui-components-avatar.md +0 -65
  95. package/docs/ui-components-avatar.zh-TW.md +0 -65
  96. package/docs/ui-components-avatar.zh.md +0 -65
  97. package/docs/ui-components-button.ja.md +0 -99
  98. package/docs/ui-components-button.md +0 -99
  99. package/docs/ui-components-button.zh-TW.md +0 -99
  100. package/docs/ui-components-button.zh.md +0 -99
  101. package/docs/ui-components-logo.ja.md +0 -52
  102. package/docs/ui-components-logo.md +0 -52
  103. package/docs/ui-components-logo.zh-TW.md +0 -52
  104. package/docs/ui-components-logo.zh.md +0 -52
  105. package/docs/ui-components.ja.md +0 -57
  106. package/docs/ui-components.md +0 -57
  107. package/docs/ui-components.zh-TW.md +0 -57
  108. package/docs/ui-components.zh.md +0 -57
  109. package/glossary.md +0 -1
  110. package/src/Address/index.jsx +0 -2
  111. package/src/Avatar/index.jsx +0 -2
  112. package/src/Button/Button.stories.jsx +0 -7
  113. package/src/Button/index.jsx +0 -21
  114. package/src/Connect/Connect.stories.jsx +0 -34
  115. package/src/Connect/assets/locale.js +0 -149
  116. package/src/Connect/assets/login-bg.png +0 -0
  117. package/src/Connect/assets/login-slogan.js +0 -7
  118. package/src/Connect/components/action-button.jsx +0 -22
  119. package/src/Connect/components/app-tips.jsx +0 -156
  120. package/src/Connect/components/auto-height.jsx +0 -38
  121. package/src/Connect/components/back-button.jsx +0 -24
  122. package/src/Connect/components/connect-status.jsx +0 -259
  123. package/src/Connect/components/did-connect-title.jsx +0 -107
  124. package/src/Connect/components/download-tips.jsx +0 -55
  125. package/src/Connect/components/loading.jsx +0 -25
  126. package/src/Connect/components/login-item/connect-choose-list.jsx +0 -317
  127. package/src/Connect/components/login-item/connect-provider-list.jsx +0 -462
  128. package/src/Connect/components/login-item/login-method-item.jsx +0 -139
  129. package/src/Connect/components/login-item/mobile-login-item.jsx +0 -181
  130. package/src/Connect/components/login-item/passkey-login-item.jsx +0 -54
  131. package/src/Connect/components/login-item/wallet-login-options.jsx +0 -129
  132. package/src/Connect/components/login-item/web-login-item.jsx +0 -157
  133. package/src/Connect/components/mask-overlay.jsx +0 -32
  134. package/src/Connect/components/refresh-overlay.jsx +0 -52
  135. package/src/Connect/components/switch-app.jsx +0 -69
  136. package/src/Connect/connect.jsx +0 -617
  137. package/src/Connect/contexts/state.jsx +0 -234
  138. package/src/Connect/fallback-connect.jsx +0 -47
  139. package/src/Connect/fullpage.jsx +0 -3
  140. package/src/Connect/hooks/auth-url.js +0 -31
  141. package/src/Connect/hooks/method-list.js +0 -121
  142. package/src/Connect/hooks/page-show.js +0 -24
  143. package/src/Connect/hooks/provider-list.js +0 -165
  144. package/src/Connect/hooks/security.js +0 -40
  145. package/src/Connect/hooks/token.js +0 -627
  146. package/src/Connect/hooks/use-apps.js +0 -69
  147. package/src/Connect/hooks/use-quick-connect.js +0 -119
  148. package/src/Connect/index.jsx +0 -21
  149. package/src/Connect/landing-page.jsx +0 -3
  150. package/src/Connect/plugins/email/index.jsx +0 -85
  151. package/src/Connect/plugins/email/list-item.jsx +0 -34
  152. package/src/Connect/plugins/email/placeholder.jsx +0 -365
  153. package/src/Connect/plugins/index.js +0 -2
  154. package/src/Connect/use-connect.jsx +0 -321
  155. package/src/Connect/with-blocklet.jsx +0 -26
  156. package/src/Connect/with-bridge-call.jsx +0 -138
  157. package/src/Federated/context.jsx +0 -93
  158. package/src/Federated/index.jsx +0 -1
  159. package/src/Logo/index.jsx +0 -2
  160. package/src/OAuth/bind-conflict-alert.jsx +0 -37
  161. package/src/OAuth/context.jsx +0 -407
  162. package/src/OAuth/guest.svg +0 -20
  163. package/src/OAuth/index.jsx +0 -1
  164. package/src/OAuth/passport-switcher.jsx +0 -2
  165. package/src/Passkey/actions.jsx +0 -217
  166. package/src/Passkey/constants.js +0 -2
  167. package/src/Passkey/context.jsx +0 -395
  168. package/src/Passkey/dialog.jsx +0 -401
  169. package/src/Passkey/icon.jsx +0 -10
  170. package/src/Passkey/index.jsx +0 -2
  171. package/src/Service/index.jsx +0 -96
  172. package/src/Session/assets/did-spaces-guide-cover.svg +0 -1
  173. package/src/Session/assets/did-spaces-guide-icon.svg +0 -7
  174. package/src/Session/context.jsx +0 -7
  175. package/src/Session/did-spaces-guide.jsx +0 -173
  176. package/src/Session/handler.jsx +0 -98
  177. package/src/Session/hooks/use-federated.js +0 -91
  178. package/src/Session/hooks/use-mobile.jsx +0 -6
  179. package/src/Session/hooks/use-protected-routes.js +0 -16
  180. package/src/Session/hooks/use-session-token.js +0 -400
  181. package/src/Session/hooks/use-verify.jsx +0 -76
  182. package/src/Session/index.jsx +0 -1789
  183. package/src/Session/libs/constants.js +0 -17
  184. package/src/Session/libs/did-spaces.js +0 -38
  185. package/src/Session/libs/federated.js +0 -82
  186. package/src/Session/libs/index.js +0 -5
  187. package/src/Session/libs/locales.js +0 -160
  188. package/src/Session/libs/login-mobile.js +0 -80
  189. package/src/Session/window-focus-aware.jsx +0 -28
  190. package/src/SessionManager/index.jsx +0 -2
  191. package/src/Storage/engine/cookie.js +0 -25
  192. package/src/Storage/engine/local-storage.js +0 -57
  193. package/src/Storage/index.js +0 -25
  194. package/src/User/index.js +0 -4
  195. package/src/User/use-did.js +0 -80
  196. package/src/User/wrap-did.jsx +0 -18
  197. package/src/WebWalletSWKeeper/index.jsx +0 -3
  198. package/src/components/PassportSwitcher.jsx +0 -160
  199. package/src/constant.js +0 -27
  200. package/src/error.js +0 -6
  201. package/src/hooks/use-locale.jsx +0 -6
  202. package/src/index.js +0 -32
  203. package/src/locales/en.jsx +0 -15
  204. package/src/locales/index.jsx +0 -13
  205. package/src/locales/zh.jsx +0 -15
  206. package/src/types.d.ts +0 -355
  207. package/src/utils.js +0 -413
  208. package/vite.config.mjs +0 -29
@@ -1,395 +0,0 @@
1
- import PropTypes from 'prop-types';
2
- import isUndefined from 'lodash/isUndefined';
3
- import { createContext, use } from 'react';
4
- import Toast from '@arcblock/ux/lib/Toast';
5
- import { useCreation, useMemoizedFn, useReactive } from 'ahooks';
6
- import noop from 'lodash/noop';
7
- import { joinURL } from 'ufo';
8
- import { translate } from '@arcblock/ux/lib/Locale/util';
9
- import { BLOCKLET_SERVICE_PATH_PREFIX } from '@arcblock/ux/lib/Util/constant';
10
- import { getFederatedEnabled, getMaster, getBlockletData } from '@arcblock/ux/lib/Util/federated';
11
- import { startAuthentication, startRegistration } from '@simplewebauthn/browser';
12
-
13
- import { getApiErrorMessage, getWebAuthnErrorMessage, createAxios, logger } from '../utils';
14
- import { PassportSwitcher, parseResponse } from '../components/PassportSwitcher';
15
- import defaultTranslations from '../Connect/assets/locale';
16
-
17
- const PasskeyContext = createContext({});
18
- const { Provider, Consumer: PasskeyConsumer } = PasskeyContext;
19
-
20
- const translations = {
21
- zh: {
22
- ...defaultTranslations.zh,
23
- cancel: '取消',
24
- usePasskey: '使用 Passkey',
25
- createPasskey: '新建 Passkey',
26
- creatingPasskey: '创建 Passkey...',
27
- connectPasskey: '绑定 Passkey',
28
- nonePasskey: '未配置 Passkey 方式',
29
- connectPasskeySucceed: 'Passkey 绑定成功',
30
- disconnectPasskeySucceed: 'Passkey 解绑成功',
31
- verifyPasskeyFailed: 'Passkey 验证失败',
32
- connectPasskeyFailed: 'Passkey 绑定失败',
33
- disconnectPasskeyFailed: 'Passkey 解绑失败',
34
- createPasskeyDesc1: 'Passkey 是一种密码替代品,使用指纹、面部识别、设备密码或 PIN 验证您的身份。',
35
- createPasskeyDesc2: 'Passkey 可以用于登录、验证,作为您账户简单且安全的替代方案。',
36
- emailPlaceholder: '请输入邮箱以作为备用',
37
- verifyButton: '验证邮箱',
38
- sendCodeButton: '获取验证码',
39
- codeSentMessage: '我们已向 {email} 发送验证码,验证码将在 30 分钟内有效,请检查您的邮箱或垃圾邮件文件夹。',
40
- codeSentSuccess: '验证码发送成功',
41
- noPassports: '没有可更换的通行证',
42
- cancelAuth: '取消授权',
43
- emailInvalid: '邮箱格式不正确',
44
- webauthn: {
45
- error: {
46
- canceled: '身份验证已被取消',
47
- security: '身份验证过程中出现安全错误',
48
- notSupported: '当前浏览器不支持 Passkey 身份验证',
49
- aborted: '身份验证已被中止',
50
- },
51
- },
52
- },
53
- en: {
54
- ...defaultTranslations.en,
55
- cancel: 'Cancel',
56
- usePasskey: 'Use Existing Passkey',
57
- createPasskey: 'Create New Passkey',
58
- creatingPasskey: 'Creating Passkey...',
59
- connectPasskey: 'Connect Passkey',
60
- nonePasskey: 'Passkey is not configured',
61
- connectPasskeySucceed: 'Passkey add succeed',
62
- disconnectPasskeySucceed: 'Passkey remove succeed',
63
- verifyPasskeyFailed: 'Passkey verify failed',
64
- connectPasskeyFailed: 'Passkey add failed',
65
- disconnectPasskeyFailed: 'Passkey remove failed',
66
- createPasskeyDesc1:
67
- 'Passkeys are a password replacement that validates your identity using touch, facial recognition, a device password, or a PIN.',
68
- createPasskeyDesc2:
69
- 'Passkeys can be used for sign-in, verification as a simple and secure alternative to your account.',
70
- emailPlaceholder: 'Enter your email address',
71
- verifyButton: 'Verify Email',
72
- sendCodeButton: 'Get Verify Code',
73
- codeSentMessage:
74
- 'We just sent a verification code to {email}, the code will be valid for 30 minutes, please check your inbox or spam folder.',
75
- codeSentSuccess: 'Verification code sent successfully',
76
- noPassports: 'No passports to switch',
77
- cancelAuth: 'Cancel authentication',
78
- emailInvalid: 'Invalid email address',
79
- webauthn: {
80
- error: {
81
- canceled: 'Authentication was canceled',
82
- security: 'A security error occurred during authentication',
83
- notSupported: 'This browser does not support passkey authentication',
84
- aborted: 'Authentication was aborted',
85
- },
86
- },
87
- },
88
- };
89
-
90
- function PasskeyProvider({
91
- children,
92
- locale = 'en',
93
- onAddPasskey = noop,
94
- onRemovePasskey = noop,
95
- onSwitchPassport = noop,
96
- session = null,
97
- }) {
98
- const prefix = joinURL(window.env?.apiPrefix || BLOCKLET_SERVICE_PATH_PREFIX, '/api/passkey');
99
-
100
- const state = useReactive({
101
- baseUrl: '/',
102
- session: undefined,
103
- connecting: false,
104
- disconnecting: false,
105
- targetAppPid: undefined,
106
- });
107
-
108
- const switchState = useReactive({
109
- open: false,
110
- currentUser: null,
111
- passports: [],
112
- selectedPassport: undefined,
113
- reset() {
114
- switchState.open = false;
115
- switchState.currentUser = null;
116
- switchState.passports = [];
117
- switchState.selectedPassport = undefined;
118
- },
119
- });
120
-
121
- const passkeyState = useReactive({
122
- user: null,
123
- loading: false,
124
- creating: false,
125
- verifying: false,
126
- creatingStatus: '',
127
- verifyingStatus: '',
128
- error: '',
129
- email: '',
130
- code: '',
131
- verified: !(window?.blocklet?.settings?.kyc?.email || false),
132
- sent: false,
133
- openDialog: false,
134
- get status() {
135
- // eslint-disable-next-line react/no-this-in-sfc
136
- if (this.creating || this.verifying) {
137
- return 'scanned';
138
- }
139
- // eslint-disable-next-line react/no-this-in-sfc
140
- if (this.creatingStatus === 'succeed' || this.verifyingStatus === 'succeed') {
141
- return 'succeed';
142
- }
143
- // eslint-disable-next-line react/no-this-in-sfc
144
- if (this.creatingStatus === 'error' || this.verifyingStatus === 'error') {
145
- return 'error';
146
- }
147
- return '';
148
- },
149
- reset() {
150
- passkeyState.creating = false;
151
- passkeyState.verifying = false;
152
- passkeyState.creatingStatus = '';
153
- passkeyState.verifyingStatus = '';
154
- passkeyState.error = '';
155
- },
156
- });
157
-
158
- const t = useMemoizedFn((key, data = {}) => {
159
- return translate(translations, key, locale, 'en', data);
160
- });
161
-
162
- const api = useCreation(() => {
163
- return createAxios({ baseURL: joinURL(state.baseUrl, prefix), sessionTokenKey: '__sst', timeout: 60 * 1000 });
164
- }, [state.baseUrl, prefix]);
165
-
166
- const getBlocklet = useMemoizedFn(async () => {
167
- if (state.baseUrl === '/') {
168
- return window.blocklet;
169
- }
170
- try {
171
- const url = new URL(state.baseUrl);
172
- if (url.host === window.location.host) {
173
- return window.blocklet;
174
- }
175
- // eslint-disable-next-line no-empty
176
- } catch {}
177
-
178
- const blocklet = await getBlockletData(state.baseUrl);
179
- return blocklet;
180
- });
181
-
182
- const componentId = window?.blocklet?.componentId;
183
-
184
- const setBaseUrl = (value) => {
185
- state.baseUrl = value || '/';
186
- };
187
- const setTargetAppPid = (value) => {
188
- state.targetAppPid = value;
189
- };
190
-
191
- const createPasskey = useMemoizedFn(async (params) => {
192
- const { data: options } = await api.get('/register', { params });
193
- console.warn('passkey.create.options', options);
194
-
195
- try {
196
- // NOTE: should set useAutoRegister to false to make passkey work in safari
197
- const response = await startRegistration({ optionsJSON: options, useAutoRegister: false });
198
- console.warn('passkey.create.response', response);
199
-
200
- const { data: result } = await api.post('/register', response, { params: { challenge: options.challenge } });
201
- console.warn('passkey.create.result', result);
202
-
203
- if (!result.verified) {
204
- throw new Error(t('createPasskeyFailed'));
205
- }
206
-
207
- return result;
208
- } catch (err) {
209
- // Check if this is a WebAuthn specific error
210
- console.error('passkey.create.error', err);
211
- if (err.name) {
212
- throw new Error(getWebAuthnErrorMessage(err, t('createPasskeyFailed'), t));
213
- }
214
- throw err;
215
- }
216
- });
217
-
218
- const verifyPasskey = useMemoizedFn(async (params) => {
219
- const { data: options } = await api.get('/auth', { params });
220
- console.warn('passkey.auth.options', options);
221
-
222
- try {
223
- const response = await startAuthentication({ optionsJSON: options });
224
- console.warn('passkey.auth.response', response);
225
-
226
- // FIXME: @zhanghan 这里只是临时的方案,完整的方案需要优化后端的逻辑后,前端一起改动才行
227
- const { data: result } = await api.post('/auth', response, {
228
- params: { challenge: options.challenge, targetAppPid: state.targetAppPid },
229
- });
230
- console.warn('passkey.auth.result', result);
231
-
232
- if (!result.verified) {
233
- throw new Error(t('verifyPasskeyFailed'));
234
- }
235
-
236
- return result;
237
- } catch (err) {
238
- // Check if this is a WebAuthn specific error
239
- console.error('passkey.auth.error', err);
240
- if (err.name) {
241
- throw new Error(getWebAuthnErrorMessage(err, t('verifyPasskeyFailed'), t));
242
- }
243
- throw err;
244
- }
245
- });
246
-
247
- // eslint-disable-next-line consistent-return
248
- const connectPasskey = async (extraParams) => {
249
- state.connecting = true;
250
-
251
- try {
252
- const result = await createPasskey({
253
- ...extraParams,
254
- locale,
255
- componentId,
256
- });
257
- Toast.success(t('connectPasskeySucceed'));
258
- onAddPasskey(result);
259
- return result;
260
- } catch (err) {
261
- logger.error('Failed to connect passkey', err);
262
- Toast.error(getApiErrorMessage(err, t('connectPasskeyFailed')));
263
- } finally {
264
- state.connecting = false;
265
- }
266
- };
267
-
268
- const disconnectPasskey = async ({ session: userSession, connectedAccount }) => {
269
- state.session = userSession;
270
- state.disconnecting = true;
271
-
272
- try {
273
- const result = await verifyPasskey({
274
- action: 'disconnect',
275
- locale,
276
- componentId,
277
- sourceAppPid: userSession?.user?.sourceAppPid,
278
- credentialId: connectedAccount.id,
279
- });
280
-
281
- Toast.success(t('disconnectPasskeySucceed'));
282
- onRemovePasskey(result);
283
- } catch (err) {
284
- logger.error('Failed to disconnect passkey', err);
285
- Toast.error(getApiErrorMessage(err, t('disconnectPasskeyFailed')));
286
- } finally {
287
- state.disconnecting = false;
288
- }
289
- };
290
-
291
- const switchPassport = async (user = {}) => {
292
- try {
293
- const { data: passports } = await api.get('/passports');
294
- if (passports.length) {
295
- switchState.open = true;
296
- switchState.currentUser = user;
297
- switchState.passports = passports || [];
298
- } else {
299
- Toast.error(t('noPassports'));
300
- }
301
- } catch (err) {
302
- Toast.error(err.message || t('getPassportFailed'));
303
- }
304
- };
305
-
306
- const handleSwitchPassport = useMemoizedFn((...args) => {
307
- switchState.reset();
308
- onSwitchPassport(...args);
309
- });
310
-
311
- const loginPasskey = useMemoizedFn(async ({ action = 'login', ...extraParams } = {}) => {
312
- const backupBaseUrl = state.baseUrl;
313
- if (extraParams?.sourceAppPid === window.blocklet?.appPid) {
314
- state.baseUrl = window.blocklet?.appUrl || '/';
315
- } else if (extraParams?.sourceAppPid) {
316
- const blocklet = await getBlocklet();
317
- const federatedEnabled = getFederatedEnabled(blocklet);
318
- const master = getMaster(blocklet);
319
- if (federatedEnabled && master?.appPid && extraParams?.sourceAppPid === master?.appPid) {
320
- state.baseUrl = master.appUrl;
321
- }
322
- }
323
-
324
- try {
325
- const params = {
326
- ...extraParams,
327
- action,
328
- locale,
329
- componentId,
330
- };
331
- if (isUndefined(params.inviter) && window.localStorage.getItem('inviter')) {
332
- params.inviter = window.localStorage.getItem('inviter');
333
- }
334
-
335
- const result = parseResponse(await verifyPasskey(params));
336
- result.provider = 'passkey';
337
-
338
- return result;
339
- } catch (err) {
340
- // Use the WebAuthn specific error handler if the error has a name property (WebAuthn errors do)
341
- console.error('passkey.login.error', err);
342
- const errMsg = getWebAuthnErrorMessage(err, t('verifyPasskeyFailed'), t);
343
- state.baseUrl = backupBaseUrl;
344
- throw new Error(errMsg);
345
- }
346
- });
347
- const logoutPasskey = useMemoizedFn(() => {});
348
-
349
- return (
350
- <Provider
351
- value={{
352
- api,
353
- locale,
354
- connectPasskey,
355
- disconnectPasskey,
356
- createPasskey,
357
- verifyPasskey,
358
- loginPasskey,
359
- logoutPasskey,
360
- switchPassport,
361
- baseUrl: state.baseUrl,
362
- setBaseUrl,
363
- setTargetAppPid,
364
- passkeyState,
365
- disconnecting: state.disconnecting,
366
- connecting: state.connecting,
367
- t,
368
- }}>
369
- {children}
370
- <PassportSwitcher
371
- api={api}
372
- locale={locale}
373
- switchState={switchState}
374
- onSwitchPassport={handleSwitchPassport}
375
- session={session}
376
- />
377
- </Provider>
378
- );
379
- }
380
-
381
- function usePasskey() {
382
- const context = use(PasskeyContext);
383
- return context;
384
- }
385
-
386
- PasskeyProvider.propTypes = {
387
- children: PropTypes.node.isRequired,
388
- locale: PropTypes.string,
389
- onAddPasskey: PropTypes.func,
390
- onRemovePasskey: PropTypes.func,
391
- onSwitchPassport: PropTypes.func,
392
- session: PropTypes.object,
393
- };
394
-
395
- export { PasskeyContext, PasskeyConsumer, PasskeyProvider, usePasskey };