@arcblock/did-connect-react 3.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.
Files changed (183) hide show
  1. package/LICENSE +13 -0
  2. package/README.md +134 -0
  3. package/lib/Address/index.js +4 -0
  4. package/lib/Avatar/index.js +4 -0
  5. package/lib/Button/index.js +17 -0
  6. package/lib/Connect/assets/locale.js +143 -0
  7. package/lib/Connect/assets/login-bg.png +0 -0
  8. package/lib/Connect/assets/login-slogan.js +9 -0
  9. package/lib/Connect/components/action-button.js +26 -0
  10. package/lib/Connect/components/app-tips.js +132 -0
  11. package/lib/Connect/components/auto-height.js +31 -0
  12. package/lib/Connect/components/back-button.js +24 -0
  13. package/lib/Connect/components/connect-status.js +263 -0
  14. package/lib/Connect/components/did-connect-title.js +126 -0
  15. package/lib/Connect/components/download-tips.js +52 -0
  16. package/lib/Connect/components/loading.js +26 -0
  17. package/lib/Connect/components/login-item/connect-choose-list.js +249 -0
  18. package/lib/Connect/components/login-item/login-method-item.js +129 -0
  19. package/lib/Connect/components/login-item/mobile-login-item.js +114 -0
  20. package/lib/Connect/components/login-item/passkey-login-item.js +44 -0
  21. package/lib/Connect/components/login-item/web-login-item.js +97 -0
  22. package/lib/Connect/components/mask-overlay.js +34 -0
  23. package/lib/Connect/components/refresh-overlay.js +57 -0
  24. package/lib/Connect/components/switch-app.js +70 -0
  25. package/lib/Connect/contexts/state.js +142 -0
  26. package/lib/Connect/fullpage.js +5 -0
  27. package/lib/Connect/hooks/auth-url.js +23 -0
  28. package/lib/Connect/hooks/method-list.js +46 -0
  29. package/lib/Connect/hooks/page-show.js +17 -0
  30. package/lib/Connect/hooks/security.js +27 -0
  31. package/lib/Connect/hooks/token.js +305 -0
  32. package/lib/Connect/hooks/use-apps.js +19 -0
  33. package/lib/Connect/hooks/use-quick-connect.js +97 -0
  34. package/lib/Connect/index.js +498 -0
  35. package/lib/Connect/landing-page.js +5 -0
  36. package/lib/Connect/plugins/email/index.js +62 -0
  37. package/lib/Connect/plugins/email/list-item.js +28 -0
  38. package/lib/Connect/plugins/email/placeholder.js +283 -0
  39. package/lib/Connect/plugins/index.js +4 -0
  40. package/lib/Connect/use-connect.js +164 -0
  41. package/lib/Connect/with-blocklet.js +15 -0
  42. package/lib/Connect/with-bridge-call.js +108 -0
  43. package/lib/Federated/context.js +61 -0
  44. package/lib/Federated/index.js +7 -0
  45. package/lib/Logo/index.js +4 -0
  46. package/lib/OAuth/context.js +234 -0
  47. package/lib/OAuth/guest.svg.js +5 -0
  48. package/lib/OAuth/index.js +7 -0
  49. package/lib/OAuth/passport-switcher.js +114 -0
  50. package/lib/Passkey/actions.js +165 -0
  51. package/lib/Passkey/constants.js +4 -0
  52. package/lib/Passkey/context.js +266 -0
  53. package/lib/Passkey/dialog.js +277 -0
  54. package/lib/Passkey/icon.js +13 -0
  55. package/lib/Passkey/index.js +9 -0
  56. package/lib/Service/index.js +62 -0
  57. package/lib/Session/assets/did-spaces-guide-cover.svg.js +135 -0
  58. package/lib/Session/assets/did-spaces-guide-icon.svg.js +9 -0
  59. package/lib/Session/context.js +5 -0
  60. package/lib/Session/did-spaces-guide.js +136 -0
  61. package/lib/Session/hooks/use-federated.js +64 -0
  62. package/lib/Session/hooks/use-mobile.js +8 -0
  63. package/lib/Session/hooks/use-protected-routes.js +11 -0
  64. package/lib/Session/hooks/use-session-token.js +169 -0
  65. package/lib/Session/hooks/use-verify.js +45 -0
  66. package/lib/Session/index.js +896 -0
  67. package/lib/Session/libs/constants.js +15 -0
  68. package/lib/Session/libs/did-spaces.js +10 -0
  69. package/lib/Session/libs/federated.js +42 -0
  70. package/lib/Session/libs/index.js +15 -0
  71. package/lib/Session/libs/locales.js +161 -0
  72. package/lib/Session/libs/login-mobile.js +55 -0
  73. package/lib/Session/window-focus-aware.js +17 -0
  74. package/lib/SessionManager/index.js +4 -0
  75. package/lib/Storage/engine/cookie.js +21 -0
  76. package/lib/Storage/engine/local-storage.js +36 -0
  77. package/lib/Storage/index.js +23 -0
  78. package/lib/User/index.js +6 -0
  79. package/lib/User/use-did.js +59 -0
  80. package/lib/User/wrap-did.js +13 -0
  81. package/lib/WebWalletSWKeeper/index.js +5 -0
  82. package/lib/constant.js +22 -0
  83. package/lib/error.js +8 -0
  84. package/lib/hooks/use-locale.js +7 -0
  85. package/lib/index.js +33 -0
  86. package/lib/locales/en.js +17 -0
  87. package/lib/locales/index.js +10 -0
  88. package/lib/locales/zh.js +17 -0
  89. package/lib/package.json.js +7 -0
  90. package/lib/types.d.ts +355 -0
  91. package/lib/utils.js +214 -0
  92. package/package.json +84 -0
  93. package/src/Address/index.jsx +2 -0
  94. package/src/Avatar/index.jsx +2 -0
  95. package/src/Button/Button.stories.jsx +7 -0
  96. package/src/Button/index.jsx +21 -0
  97. package/src/Connect/Connect.stories.jsx +34 -0
  98. package/src/Connect/assets/locale.js +145 -0
  99. package/src/Connect/assets/login-bg.png +0 -0
  100. package/src/Connect/assets/login-slogan.js +7 -0
  101. package/src/Connect/components/action-button.jsx +22 -0
  102. package/src/Connect/components/app-tips.jsx +156 -0
  103. package/src/Connect/components/auto-height.jsx +38 -0
  104. package/src/Connect/components/back-button.jsx +23 -0
  105. package/src/Connect/components/connect-status.jsx +259 -0
  106. package/src/Connect/components/did-connect-title.jsx +106 -0
  107. package/src/Connect/components/download-tips.jsx +55 -0
  108. package/src/Connect/components/loading.jsx +25 -0
  109. package/src/Connect/components/login-item/connect-choose-list.jsx +304 -0
  110. package/src/Connect/components/login-item/login-method-item.jsx +118 -0
  111. package/src/Connect/components/login-item/mobile-login-item.jsx +179 -0
  112. package/src/Connect/components/login-item/passkey-login-item.jsx +52 -0
  113. package/src/Connect/components/login-item/web-login-item.jsx +149 -0
  114. package/src/Connect/components/mask-overlay.jsx +32 -0
  115. package/src/Connect/components/refresh-overlay.jsx +52 -0
  116. package/src/Connect/components/switch-app.jsx +69 -0
  117. package/src/Connect/contexts/state.jsx +219 -0
  118. package/src/Connect/fullpage.jsx +3 -0
  119. package/src/Connect/hooks/auth-url.js +31 -0
  120. package/src/Connect/hooks/method-list.js +121 -0
  121. package/src/Connect/hooks/page-show.js +24 -0
  122. package/src/Connect/hooks/security.js +40 -0
  123. package/src/Connect/hooks/token.js +639 -0
  124. package/src/Connect/hooks/use-apps.js +69 -0
  125. package/src/Connect/hooks/use-quick-connect.js +130 -0
  126. package/src/Connect/index.jsx +600 -0
  127. package/src/Connect/landing-page.jsx +3 -0
  128. package/src/Connect/plugins/email/index.jsx +82 -0
  129. package/src/Connect/plugins/email/list-item.jsx +31 -0
  130. package/src/Connect/plugins/email/placeholder.jsx +365 -0
  131. package/src/Connect/plugins/index.js +2 -0
  132. package/src/Connect/use-connect.jsx +321 -0
  133. package/src/Connect/with-blocklet.jsx +26 -0
  134. package/src/Connect/with-bridge-call.jsx +138 -0
  135. package/src/Federated/context.jsx +93 -0
  136. package/src/Federated/index.jsx +1 -0
  137. package/src/Logo/index.jsx +2 -0
  138. package/src/OAuth/context.jsx +346 -0
  139. package/src/OAuth/guest.svg +20 -0
  140. package/src/OAuth/index.jsx +1 -0
  141. package/src/OAuth/passport-switcher.jsx +133 -0
  142. package/src/Passkey/actions.jsx +212 -0
  143. package/src/Passkey/constants.js +2 -0
  144. package/src/Passkey/context.jsx +381 -0
  145. package/src/Passkey/dialog.jsx +391 -0
  146. package/src/Passkey/icon.jsx +10 -0
  147. package/src/Passkey/index.jsx +2 -0
  148. package/src/Service/index.jsx +96 -0
  149. package/src/Session/assets/did-spaces-guide-cover.svg +128 -0
  150. package/src/Session/assets/did-spaces-guide-icon.svg +7 -0
  151. package/src/Session/context.jsx +7 -0
  152. package/src/Session/did-spaces-guide.jsx +173 -0
  153. package/src/Session/hooks/use-federated.js +88 -0
  154. package/src/Session/hooks/use-mobile.jsx +6 -0
  155. package/src/Session/hooks/use-protected-routes.js +16 -0
  156. package/src/Session/hooks/use-session-token.js +365 -0
  157. package/src/Session/hooks/use-verify.jsx +76 -0
  158. package/src/Session/index.jsx +1687 -0
  159. package/src/Session/libs/constants.js +14 -0
  160. package/src/Session/libs/did-spaces.js +38 -0
  161. package/src/Session/libs/federated.js +79 -0
  162. package/src/Session/libs/index.js +5 -0
  163. package/src/Session/libs/locales.js +160 -0
  164. package/src/Session/libs/login-mobile.js +80 -0
  165. package/src/Session/window-focus-aware.jsx +28 -0
  166. package/src/SessionManager/index.jsx +2 -0
  167. package/src/Storage/engine/cookie.js +23 -0
  168. package/src/Storage/engine/local-storage.js +55 -0
  169. package/src/Storage/index.js +25 -0
  170. package/src/User/index.js +4 -0
  171. package/src/User/use-did.js +80 -0
  172. package/src/User/wrap-did.jsx +18 -0
  173. package/src/WebWalletSWKeeper/index.jsx +3 -0
  174. package/src/constant.js +26 -0
  175. package/src/error.js +6 -0
  176. package/src/hooks/use-locale.jsx +6 -0
  177. package/src/index.js +43 -0
  178. package/src/locales/en.jsx +15 -0
  179. package/src/locales/index.jsx +13 -0
  180. package/src/locales/zh.jsx +15 -0
  181. package/src/types.d.ts +355 -0
  182. package/src/utils.js +395 -0
  183. package/vite.config.mjs +29 -0
@@ -0,0 +1,305 @@
1
+ import { useRef as I, useEffect as S } from "react";
2
+ import W from "lodash/get";
3
+ import ue from "js-cookie";
4
+ import B from "lodash/omitBy";
5
+ import M from "lodash/isNil";
6
+ import fe from "lodash/omit";
7
+ import de from "lodash/cloneDeep";
8
+ import { useReactive as H, useCreation as pe, useMemoizedFn as E } from "ahooks";
9
+ import ke from "@arcblock/react-hooks/lib/useInterval";
10
+ import me from "@arcblock/react-hooks/lib/useBrowser";
11
+ import { getVisitorId as he, stringifyQuery as $, isUrl as ge } from "@arcblock/ux/lib/Util";
12
+ import { WsClient as we } from "@arcblock/ws";
13
+ import { sleep as q, getConnectedInfo as be, updateConnectedInfo as Ce, parseNextWorkflow as Q, createAxios as z, decodeConnectUrl as Se, parseTokenFromConnectUrl as xe } from "../../utils.js";
14
+ import V from "../assets/locale.js";
15
+ import Ie from "./security.js";
16
+ import $e from "./page-show.js";
17
+ import { RELAY_SOCKET_PREFIX as G } from "../../constant.js";
18
+ function ve(o) {
19
+ const a = o || window.location.href;
20
+ return new URL(a).host;
21
+ }
22
+ function v(o) {
23
+ const a = {}, d = o || window.location.href;
24
+ if (d) {
25
+ const { hostname: w, protocol: i, port: p } = new URL(d);
26
+ a["x-real-hostname"] = w, a["x-real-port"] = p, a["x-real-protocol"] = i.endsWith(":") ? i.substring(0, i.length - 1) : i;
27
+ }
28
+ return a;
29
+ }
30
+ const R = {};
31
+ function Ue({ action: o, prefix: a, checkFn: d, extraParams: w, baseUrl: i }) {
32
+ const p = `${a}/token?${$(w)}`;
33
+ return R[p] || (R[p] = async function() {
34
+ const k = +/* @__PURE__ */ new Date(), h = await d(p, { headers: v(i) }), g = +/* @__PURE__ */ new Date();
35
+ if (g - k < 500 && await q(500 - (g - k)), h?.data?.token)
36
+ return h.data;
37
+ if (h?.data?.error)
38
+ throw new Error(h.data.error);
39
+ const U = ge(a) ? a : `${i}${a}`;
40
+ throw new Error(`Error generating ${o} QR Code from: ${U}`);
41
+ }), R[p];
42
+ }
43
+ const Ae = () => {
44
+ try {
45
+ const a = new URL(window.location.href).searchParams.get("__connect_url__");
46
+ if (!a)
47
+ return null;
48
+ const d = Se(a);
49
+ return {
50
+ token: xe(d),
51
+ url: d
52
+ };
53
+ } catch (o) {
54
+ return {
55
+ error: o
56
+ };
57
+ }
58
+ }, J = () => W(globalThis, "blocklet.appPid") || W(globalThis, "blocklet.appId") || W(globalThis, "env.appId") || "", ye = () => (W(globalThis, "env.apiPrefix") || "/").replace(/\/$/, "").replace(G, ""), P = (o) => `relay:${J()}:${o}`, Ee = () => window.location.protocol === "https:" ? "wss:" : "ws:", X = (o) => !o || new URL(o).origin === window.location.origin, Y = (o) => ["succeed", "error", "timeout", "busy"].includes(o);
59
+ function Xe({
60
+ action: o,
61
+ checkFn: a,
62
+ checkInterval: d,
63
+ checkTimeout: w,
64
+ extraParams: i,
65
+ locale: p,
66
+ prefix: _,
67
+ tokenKey: k,
68
+ encKey: h,
69
+ onError: g,
70
+ onSuccess: U,
71
+ baseUrl: Z,
72
+ autoConnect: K = !0,
73
+ forceConnected: ee = !0,
74
+ saveConnect: te = !0,
75
+ // FIXME: @zhanghan 将来需要设置为默认 false,仅在需要的时候进行保存 login, switch/role/profile
76
+ useSocket: re = !0,
77
+ provider: ne = "wallet"
78
+ }) {
79
+ const e = H({
80
+ checking: !1,
81
+ loading: !1,
82
+ token: "",
83
+ url: "",
84
+ store: null,
85
+ status: "created",
86
+ error: "",
87
+ checkCount: 0,
88
+ mfaCode: 0,
89
+ appInfo: null,
90
+ memberAppInfo: null,
91
+ connectedDid: "",
92
+ saveConnect: !1,
93
+ inExistingSession: !1,
94
+ nextWorkflow: "",
95
+ baseUrl: Z,
96
+ prefix: `${_}/${o}`,
97
+ extraParams: B(i, M),
98
+ checkFn: a,
99
+ results: {},
100
+ action: o,
101
+ provider: ne,
102
+ reset() {
103
+ this.error = "", this.status = "created";
104
+ }
105
+ }), F = I(null), x = V[p] || V.en, f = pe(() => Ae(), []), oe = Math.ceil(w / d), l = H({
106
+ onSuccessCalled: !1,
107
+ cancelWhenScannedCounter: 0,
108
+ isSocketAvailable: !1
109
+ }), { encryptKey: se, decrypt: A } = Ie(), D = me(), O = he(), c = I(null), m = I(null), b = {
110
+ ...e.extraParams,
111
+ locale: p,
112
+ [k]: e.token || f?.token,
113
+ provider: e.provider
114
+ }, L = async () => {
115
+ if (!(f?.token && f?.token === e.token)) {
116
+ try {
117
+ b[k] && e.status === "created" && await e.checkFn(`${e.prefix}/timeout?${$(b)}`, {
118
+ headers: v(e.baseUrl)
119
+ });
120
+ } catch {
121
+ }
122
+ try {
123
+ e.token && m.current && (await c.current.unsubscribe(P(e.token)), m.current = null);
124
+ } catch {
125
+ }
126
+ }
127
+ }, ae = E((...r) => {
128
+ const t = {
129
+ [h]: se,
130
+ ...e.extraParams,
131
+ locale: p,
132
+ forceConnected: ee,
133
+ // - autoConnect 请求参数用于控制服务端是否给钱包应用发送自动连接通知
134
+ // - 使用 connect 组件时明确传入了 autoConnect = false, 则 autoConnect 请求参数 为 false
135
+ // - 如果 cancelWhenScannedCounter > 0, 说明用户进行过 cancel 操作, 则临时禁用自动连接, autoConnect 请求参数 为 false
136
+ // (避免 "无限自动连接问题")
137
+ // - 如果上次连接设备 (connected_wallet_os) 不是 ios/android, 则禁用自动连接
138
+ autoConnect: K && // 如果是 wallet webview 环境, 不发送通知, 避免 wallet 连续弹出 auth 窗口 2 次 (#341)
139
+ !(D.wallet || D.arcSphere) && !l.cancelWhenScannedCounter && ["ios", "android"].includes(ue.get("connected_wallet_os")),
140
+ provider: e.provider
141
+ };
142
+ O && (t.visitorId = O);
143
+ const n = fe(F.current || {}, ["sourceAppPid", "verbose"]);
144
+ return Object.keys(n).forEach((s) => {
145
+ (!t[s] || s === h && n[s]) && (t[s] = n[s]);
146
+ }), f?.token && !t.sourceToken && (t.sourceToken = f?.token), Ue({
147
+ action: o,
148
+ prefix: e.prefix,
149
+ baseUrl: e.baseUrl,
150
+ checkFn: e.checkFn,
151
+ extraParams: t
152
+ })(...r);
153
+ }), y = E(async (r = !0) => {
154
+ r && L();
155
+ try {
156
+ e.loading = !0, e.token = "", e.url = "", e.store = null, e.extraParams = B(i, M), await q();
157
+ const t = await ae(), n = t.extra || {};
158
+ e.loading = !1, e.token = t.token, e.url = t.url, e.status = "created", e.error = "", e.checkCount = 0, e.appInfo = t.appInfo, e.memberAppInfo = t.memberAppInfo, e.connectedDid = n.connectedDid, e.saveConnect = n.saveConnect;
159
+ } catch (t) {
160
+ e.loading = !1, e.status = "error", e.error = `${x.generateError}: ${t.message}`;
161
+ }
162
+ }), ce = E(() => {
163
+ l.cancelWhenScannedCounter++;
164
+ });
165
+ S(() => {
166
+ l.cancelWhenScannedCounter > 0 && (i.nw ? g(new Error(x.retryForbidden)) : y());
167
+ }, [l.cancelWhenScannedCounter]), S(() => (!(/^((?!chrome|android).)*safari/i.test(globalThis.navigator.userAgent) || Object.hasOwn(globalThis?.blocklet || {}, "DID_CONNECT_DISABLE_SOCKET")) && re && X(e.baseUrl) && J() ? (!c.current || c.current.isConnected() === !1 || c.current.baseUrl !== e.baseUrl) && (c.current = new we(
168
+ `${Ee()}//${ve(e.baseUrl)}${ye()}${G}/relay`,
169
+ {
170
+ longpollerTimeout: 5e3,
171
+ // connection timeout
172
+ heartbeatIntervalMs: 30 * 1e3
173
+ }
174
+ ), c.current.baseUrl = e.baseUrl, c.current.onOpen(() => {
175
+ l.isSocketAvailable = !0;
176
+ }), c.current.connect()) : l.isSocketAvailable && (l.isSocketAvailable = !1), () => {
177
+ c.current && (c.current.disconnect(), c.current = null);
178
+ }), [e.baseUrl]);
179
+ const ie = () => !e.token || e.loading || Y(e.status) ? null : d, j = I(null);
180
+ S(() => {
181
+ j.current = { state: e, params: b };
182
+ }), S(() => () => {
183
+ const { state: r, params: t } = j.current;
184
+ r.status === "created" && t[k] && r.checkFn(`${r.prefix}/timeout?${$(t)}`, {
185
+ headers: v(r.baseUrl)
186
+ });
187
+ }, []);
188
+ const C = E(async (r = !1) => {
189
+ if ((e.checking || document.hidden) && !r || (e.status === "created" && e.checkCount++, l.isSocketAvailable && !r))
190
+ return null;
191
+ try {
192
+ e.checking = !0;
193
+ const t = await e.checkFn(`${e.prefix}/status?${$(b)}`, {
194
+ headers: v(e.baseUrl)
195
+ }), { status: n, error: u, mfaCode: s = 0 } = t.data;
196
+ if (e.store = t.data, e.mfaCode = s, e.checking = !1, e.status === "scanned" && n === "created" || (e.status = n), n === "error" && u) {
197
+ const N = new Error(u);
198
+ throw N.response = t, N;
199
+ }
200
+ return t.data;
201
+ } catch (t) {
202
+ const { response: n } = t;
203
+ if (n?.status) {
204
+ b[k] && e.checkFn(`${e.prefix}/timeout?${$(b)}`, {
205
+ headers: v(e.baseUrl)
206
+ });
207
+ const u = n?.data?.error ? n.data.error : t.message, s = new Error(u);
208
+ s.code = n.status, e.status = "error", e.checking = !1, e.error = u, g(s, e?.store, A);
209
+ } else
210
+ e.status = "error", e.checking = !1, e.error = x.generateError;
211
+ }
212
+ return null;
213
+ }), le = async () => {
214
+ try {
215
+ if (f.error)
216
+ throw f.error;
217
+ e.loading = !0, e.token = f.token, e.url = f.url, e.inExistingSession = !0;
218
+ let r = await C();
219
+ if ((["scanned"].includes(r?.status) || r?.sourceToken === f?.token) && (await y(!1), r = await C()), F.current = r?.extraParams || null, r?.status && !["created"].includes(r?.status))
220
+ throw new Error(`${x.invalidSessionStatus} [${r.status}]`);
221
+ } catch (r) {
222
+ e.status = "error", e.error = r.message, g(r, e?.store, A);
223
+ } finally {
224
+ e.loading = !1;
225
+ }
226
+ };
227
+ S(() => {
228
+ if (!e.token && !e.store && !e.loading && !e.error)
229
+ if (f)
230
+ le();
231
+ else {
232
+ y(!1);
233
+ return;
234
+ }
235
+ if (e.status !== "timeout" && e.checkCount > oe) {
236
+ e.status = "timeout", L();
237
+ return;
238
+ }
239
+ if (e.status === "succeed" && !l.onSuccessCalled) {
240
+ const r = be({
241
+ ...e.store,
242
+ appInfo: e.appInfo,
243
+ memberAppInfo: e.memberAppInfo
244
+ });
245
+ if (X(e.baseUrl) && te && e.saveConnect && e.store.did && Ce(r, !0), e.store) {
246
+ const { nextWorkflow: t } = e.store;
247
+ if (t)
248
+ try {
249
+ const n = Q(t, k);
250
+ e.nextWorkflow = n?.nextWorkflow || t, Object.assign(e, n), e.store = null, e.error = "", e.url = "", e.appInfo = null, e.memberAppInfo = null, e.checkCount = 0, e.status = "scanned", e.results = {
251
+ ...e.results,
252
+ [e.token]: e.store
253
+ }, e.checkFn = z({ baseURL: n.baseUrl, timeout: 8e3 }).get, C();
254
+ } catch (n) {
255
+ console.error(`Invalid nextWorkflow: ${t}`, n), e.status = "error", e.error = `Invalid nextWorkflow: ${t}: ${n.message}`;
256
+ }
257
+ else if (e.nextWorkflow && (e.nextWorkflow = "", e.url = ""), typeof U == "function") {
258
+ const n = Object.values({ ...e.results, [e.token]: e.store });
259
+ l.onSuccessCalled = !0;
260
+ const u = n.length > 1 ? n : n[0], s = de(u);
261
+ U(s, A, {
262
+ sourceAppPid: i?.sourceAppPid,
263
+ ...r
264
+ });
265
+ }
266
+ }
267
+ return;
268
+ }
269
+ if (e.store?.nextWorkflow) {
270
+ const { nextWorkflow: r } = e.store;
271
+ try {
272
+ const t = Q(r, k);
273
+ e.nextWorkflow = t?.nextWorkflow || r, Object.assign(e, t), e.store = null, e.error = "", e.url = "", e.appInfo = null, e.memberAppInfo = null, e.checkCount = 0, e.status = "scanned", e.results = {
274
+ ...e.results,
275
+ [e.token]: e.store
276
+ }, e.checkFn = z({ baseURL: t.baseUrl, timeout: 8e3 }).get, C();
277
+ } catch (t) {
278
+ console.error(`Invalid nextWorkflow: ${r}`, t), e.status = "error", e.error = `Invalid nextWorkflow: ${r}: ${t.message}`;
279
+ }
280
+ }
281
+ });
282
+ const T = I(0);
283
+ return S(() => {
284
+ if (e.token && l.isSocketAvailable && c.current) {
285
+ let r = !1;
286
+ m.current ? m.current.token !== e.token && (c.current.unsubscribe(P(m.current.token)), r = !0) : r = !0, r && (m.current = c.current.subscribe(P(e.token)), T.current = 0, m.current.token = e.token, m.current.on("updated", ({ response: t }) => {
287
+ const n = +new Date(t.updatedAt);
288
+ if (n <= T.current) {
289
+ console.warn("Ignore outdated message", t);
290
+ return;
291
+ }
292
+ T.current = n;
293
+ let { status: u, error: s } = t;
294
+ u === "forbidden" && (s = x.forbidden, u = "error"), e.status = u, e.mfaCode = t.mfaCode || 0, e.store = t, e.error = s, s && g(new Error(s), e?.store, A);
295
+ }));
296
+ }
297
+ }, [e.token, l.isSocketAvailable, c.current]), ke(C, ie()), $e(() => {
298
+ e.token && Y(e.status) === !1 && (e.checking = !1, setTimeout(() => {
299
+ C(!0);
300
+ }, 100));
301
+ }), { state: e, generate: y, cancelWhenScanned: ce };
302
+ }
303
+ export {
304
+ Xe as default
305
+ };
@@ -0,0 +1,19 @@
1
+ import { useCreation as u } from "ahooks";
2
+ import { getFederatedEnabled as m, getMaster as c, getApps as A } from "@arcblock/ux/lib/Util/federated";
3
+ import p from "lodash/isUndefined";
4
+ import { use as P } from "react";
5
+ import { SessionContext as g } from "../../Session/context.js";
6
+ function F({ blocklet: t, action: f, sourceAppPid: r, connectState: i, enableSwitchApp: d }) {
7
+ const s = P(g), n = u(() => d === !0 ? !0 : !(d === !1 || s?.session?.user && !["login", "invite", "connect-to-did-space", "connect-to-did-domain"].includes(f)), [f, s?.session?.user]), o = u(() => {
8
+ if (p(r)) {
9
+ const a = m(t), e = c(t);
10
+ if (a && e?.appPid)
11
+ return e.appPid;
12
+ }
13
+ return r;
14
+ }, [r, t]);
15
+ return { appInfoList: u(() => A(t).filter((e) => n ? !0 : p(r) ? p(i.sourceAppPid) ? s?.session?.user ? e.sourceAppPid === s.session.user.sourceAppPid : e.sourceAppPid === o : e.sourceAppPid === i.sourceAppPid : e.sourceAppPid === r), [n, r, i.sourceAppPid, o, s?.session?.user]), autoGenerateSourceAppPid: o, canSwitchApp: n };
16
+ }
17
+ export {
18
+ F as default
19
+ };
@@ -0,0 +1,97 @@
1
+ import { useCreation as l, useMemoizedFn as E, useReactive as L, useRequest as T } from "ahooks";
2
+ import { joinURL as u } from "ufo";
3
+ import k from "lodash/pick";
4
+ import A from "lodash/unionBy";
5
+ import D from "lodash/sortBy";
6
+ import x from "@arcblock/ux/lib/Toast";
7
+ import { getFederatedEnabled as B, getMaster as C } from "@arcblock/ux/lib/Util/federated";
8
+ import { BLOCKLET_SERVICE_PATH_PREFIX as P } from "../../constant.js";
9
+ import { createAxios as _, logger as m } from "../../utils.js";
10
+ const f = u(P, "/api/user-session");
11
+ function O({
12
+ appPid: y,
13
+ sourceAppPid: U,
14
+ loginAppPid: S,
15
+ autoFetch: w = !0,
16
+ baseUrl: a = "/",
17
+ fetchAll: I = !1
18
+ } = {}) {
19
+ const p = l(() => _(
20
+ {
21
+ baseURL: u(a, f)
22
+ },
23
+ { lazy: !0, lazyTime: 500 }
24
+ ), [a]), h = E(async () => {
25
+ if (!window.blocklet)
26
+ return [];
27
+ let r = [];
28
+ try {
29
+ ({ data: r = [] } = await p.get(""));
30
+ } catch (t) {
31
+ m.error("Failed to get user-sessions", t);
32
+ }
33
+ const s = r.map((t) => ({
34
+ ...t,
35
+ appUrl: a
36
+ })), e = B(), n = C();
37
+ if (I && e && n) {
38
+ let t = [];
39
+ try {
40
+ ({ data: t = [] } = await p.get(u(n.appUrl, f)));
41
+ } catch (c) {
42
+ m.error("Failed to get master user-sessions", c);
43
+ }
44
+ return s.concat(t.map((c) => ({ ...c, appUrl: n.appUrl })));
45
+ }
46
+ return !e || !n ? s.filter((t) => t?.user?.sourceAppPid === null) : s;
47
+ }), i = L({
48
+ loaded: !1,
49
+ loadingId: null
50
+ }), o = T(h, {
51
+ manual: !w,
52
+ onFinally() {
53
+ i.loaded = !0;
54
+ },
55
+ refreshDeps: [a]
56
+ }), F = async (r) => {
57
+ const s = k(r, ["userDid", "visitorId", "passportId", "id"]);
58
+ try {
59
+ i.loadingId = r.id;
60
+ const { data: e } = await p.post(
61
+ "login",
62
+ { ...s, appPid: S },
63
+ {
64
+ baseURL: u(r.appUrl || "/", f)
65
+ }
66
+ );
67
+ return e;
68
+ } catch (e) {
69
+ const n = e.response ? e.response?.data?.error || e.response?.data : e.message;
70
+ throw x.error(n), m.error("Quick login error", e), e;
71
+ } finally {
72
+ i.loadingId = null;
73
+ }
74
+ }, g = l(() => o.data ? o.data.filter((r) => r.status !== "expired") : [], [o.data]), d = l(() => {
75
+ const r = (/* @__PURE__ */ new Date()).getTime(), s = D(g, (e) => r - new Date(e.updatedAt).getTime());
76
+ return A(
77
+ s,
78
+ (e) => [
79
+ e.userDid
80
+ // 暂不以用户角色来做去重的因子
81
+ // x.user.role
82
+ ].join("_")
83
+ );
84
+ }, [g, U, y]), R = l(() => !!(d && d.length > 0), [d]);
85
+ return {
86
+ loadingId: i.loadingId,
87
+ userSessions: d,
88
+ quickLoginEnabled: R,
89
+ loginUserSession: F,
90
+ loading: o.loading,
91
+ loaded: o.loaded,
92
+ refresh: o.refreshAsync
93
+ };
94
+ }
95
+ export {
96
+ O as default
97
+ };