@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.
- package/LICENSE +13 -0
- package/README.md +134 -0
- package/lib/Address/index.js +4 -0
- package/lib/Avatar/index.js +4 -0
- package/lib/Button/index.js +17 -0
- package/lib/Connect/assets/locale.js +143 -0
- package/lib/Connect/assets/login-bg.png +0 -0
- package/lib/Connect/assets/login-slogan.js +9 -0
- package/lib/Connect/components/action-button.js +26 -0
- package/lib/Connect/components/app-tips.js +132 -0
- package/lib/Connect/components/auto-height.js +31 -0
- package/lib/Connect/components/back-button.js +24 -0
- package/lib/Connect/components/connect-status.js +263 -0
- package/lib/Connect/components/did-connect-title.js +126 -0
- package/lib/Connect/components/download-tips.js +52 -0
- package/lib/Connect/components/loading.js +26 -0
- package/lib/Connect/components/login-item/connect-choose-list.js +249 -0
- package/lib/Connect/components/login-item/login-method-item.js +129 -0
- package/lib/Connect/components/login-item/mobile-login-item.js +114 -0
- package/lib/Connect/components/login-item/passkey-login-item.js +44 -0
- package/lib/Connect/components/login-item/web-login-item.js +97 -0
- package/lib/Connect/components/mask-overlay.js +34 -0
- package/lib/Connect/components/refresh-overlay.js +57 -0
- package/lib/Connect/components/switch-app.js +70 -0
- package/lib/Connect/contexts/state.js +142 -0
- package/lib/Connect/fullpage.js +5 -0
- package/lib/Connect/hooks/auth-url.js +23 -0
- package/lib/Connect/hooks/method-list.js +46 -0
- package/lib/Connect/hooks/page-show.js +17 -0
- package/lib/Connect/hooks/security.js +27 -0
- package/lib/Connect/hooks/token.js +305 -0
- package/lib/Connect/hooks/use-apps.js +19 -0
- package/lib/Connect/hooks/use-quick-connect.js +97 -0
- package/lib/Connect/index.js +498 -0
- package/lib/Connect/landing-page.js +5 -0
- package/lib/Connect/plugins/email/index.js +62 -0
- package/lib/Connect/plugins/email/list-item.js +28 -0
- package/lib/Connect/plugins/email/placeholder.js +283 -0
- package/lib/Connect/plugins/index.js +4 -0
- package/lib/Connect/use-connect.js +164 -0
- package/lib/Connect/with-blocklet.js +15 -0
- package/lib/Connect/with-bridge-call.js +108 -0
- package/lib/Federated/context.js +61 -0
- package/lib/Federated/index.js +7 -0
- package/lib/Logo/index.js +4 -0
- package/lib/OAuth/context.js +234 -0
- package/lib/OAuth/guest.svg.js +5 -0
- package/lib/OAuth/index.js +7 -0
- package/lib/OAuth/passport-switcher.js +114 -0
- package/lib/Passkey/actions.js +165 -0
- package/lib/Passkey/constants.js +4 -0
- package/lib/Passkey/context.js +266 -0
- package/lib/Passkey/dialog.js +277 -0
- package/lib/Passkey/icon.js +13 -0
- package/lib/Passkey/index.js +9 -0
- package/lib/Service/index.js +62 -0
- package/lib/Session/assets/did-spaces-guide-cover.svg.js +135 -0
- package/lib/Session/assets/did-spaces-guide-icon.svg.js +9 -0
- package/lib/Session/context.js +5 -0
- package/lib/Session/did-spaces-guide.js +136 -0
- package/lib/Session/hooks/use-federated.js +64 -0
- package/lib/Session/hooks/use-mobile.js +8 -0
- package/lib/Session/hooks/use-protected-routes.js +11 -0
- package/lib/Session/hooks/use-session-token.js +169 -0
- package/lib/Session/hooks/use-verify.js +45 -0
- package/lib/Session/index.js +896 -0
- package/lib/Session/libs/constants.js +15 -0
- package/lib/Session/libs/did-spaces.js +10 -0
- package/lib/Session/libs/federated.js +42 -0
- package/lib/Session/libs/index.js +15 -0
- package/lib/Session/libs/locales.js +161 -0
- package/lib/Session/libs/login-mobile.js +55 -0
- package/lib/Session/window-focus-aware.js +17 -0
- package/lib/SessionManager/index.js +4 -0
- package/lib/Storage/engine/cookie.js +21 -0
- package/lib/Storage/engine/local-storage.js +36 -0
- package/lib/Storage/index.js +23 -0
- package/lib/User/index.js +6 -0
- package/lib/User/use-did.js +59 -0
- package/lib/User/wrap-did.js +13 -0
- package/lib/WebWalletSWKeeper/index.js +5 -0
- package/lib/constant.js +22 -0
- package/lib/error.js +8 -0
- package/lib/hooks/use-locale.js +7 -0
- package/lib/index.js +33 -0
- package/lib/locales/en.js +17 -0
- package/lib/locales/index.js +10 -0
- package/lib/locales/zh.js +17 -0
- package/lib/package.json.js +7 -0
- package/lib/types.d.ts +355 -0
- package/lib/utils.js +214 -0
- package/package.json +84 -0
- package/src/Address/index.jsx +2 -0
- package/src/Avatar/index.jsx +2 -0
- package/src/Button/Button.stories.jsx +7 -0
- package/src/Button/index.jsx +21 -0
- package/src/Connect/Connect.stories.jsx +34 -0
- package/src/Connect/assets/locale.js +145 -0
- package/src/Connect/assets/login-bg.png +0 -0
- package/src/Connect/assets/login-slogan.js +7 -0
- package/src/Connect/components/action-button.jsx +22 -0
- package/src/Connect/components/app-tips.jsx +156 -0
- package/src/Connect/components/auto-height.jsx +38 -0
- package/src/Connect/components/back-button.jsx +23 -0
- package/src/Connect/components/connect-status.jsx +259 -0
- package/src/Connect/components/did-connect-title.jsx +106 -0
- package/src/Connect/components/download-tips.jsx +55 -0
- package/src/Connect/components/loading.jsx +25 -0
- package/src/Connect/components/login-item/connect-choose-list.jsx +304 -0
- package/src/Connect/components/login-item/login-method-item.jsx +118 -0
- package/src/Connect/components/login-item/mobile-login-item.jsx +179 -0
- package/src/Connect/components/login-item/passkey-login-item.jsx +52 -0
- package/src/Connect/components/login-item/web-login-item.jsx +149 -0
- package/src/Connect/components/mask-overlay.jsx +32 -0
- package/src/Connect/components/refresh-overlay.jsx +52 -0
- package/src/Connect/components/switch-app.jsx +69 -0
- package/src/Connect/contexts/state.jsx +219 -0
- package/src/Connect/fullpage.jsx +3 -0
- package/src/Connect/hooks/auth-url.js +31 -0
- package/src/Connect/hooks/method-list.js +121 -0
- package/src/Connect/hooks/page-show.js +24 -0
- package/src/Connect/hooks/security.js +40 -0
- package/src/Connect/hooks/token.js +639 -0
- package/src/Connect/hooks/use-apps.js +69 -0
- package/src/Connect/hooks/use-quick-connect.js +130 -0
- package/src/Connect/index.jsx +600 -0
- package/src/Connect/landing-page.jsx +3 -0
- package/src/Connect/plugins/email/index.jsx +82 -0
- package/src/Connect/plugins/email/list-item.jsx +31 -0
- package/src/Connect/plugins/email/placeholder.jsx +365 -0
- package/src/Connect/plugins/index.js +2 -0
- package/src/Connect/use-connect.jsx +321 -0
- package/src/Connect/with-blocklet.jsx +26 -0
- package/src/Connect/with-bridge-call.jsx +138 -0
- package/src/Federated/context.jsx +93 -0
- package/src/Federated/index.jsx +1 -0
- package/src/Logo/index.jsx +2 -0
- package/src/OAuth/context.jsx +346 -0
- package/src/OAuth/guest.svg +20 -0
- package/src/OAuth/index.jsx +1 -0
- package/src/OAuth/passport-switcher.jsx +133 -0
- package/src/Passkey/actions.jsx +212 -0
- package/src/Passkey/constants.js +2 -0
- package/src/Passkey/context.jsx +381 -0
- package/src/Passkey/dialog.jsx +391 -0
- package/src/Passkey/icon.jsx +10 -0
- package/src/Passkey/index.jsx +2 -0
- package/src/Service/index.jsx +96 -0
- package/src/Session/assets/did-spaces-guide-cover.svg +128 -0
- package/src/Session/assets/did-spaces-guide-icon.svg +7 -0
- package/src/Session/context.jsx +7 -0
- package/src/Session/did-spaces-guide.jsx +173 -0
- package/src/Session/hooks/use-federated.js +88 -0
- package/src/Session/hooks/use-mobile.jsx +6 -0
- package/src/Session/hooks/use-protected-routes.js +16 -0
- package/src/Session/hooks/use-session-token.js +365 -0
- package/src/Session/hooks/use-verify.jsx +76 -0
- package/src/Session/index.jsx +1687 -0
- package/src/Session/libs/constants.js +14 -0
- package/src/Session/libs/did-spaces.js +38 -0
- package/src/Session/libs/federated.js +79 -0
- package/src/Session/libs/index.js +5 -0
- package/src/Session/libs/locales.js +160 -0
- package/src/Session/libs/login-mobile.js +80 -0
- package/src/Session/window-focus-aware.jsx +28 -0
- package/src/SessionManager/index.jsx +2 -0
- package/src/Storage/engine/cookie.js +23 -0
- package/src/Storage/engine/local-storage.js +55 -0
- package/src/Storage/index.js +25 -0
- package/src/User/index.js +4 -0
- package/src/User/use-did.js +80 -0
- package/src/User/wrap-did.jsx +18 -0
- package/src/WebWalletSWKeeper/index.jsx +3 -0
- package/src/constant.js +26 -0
- package/src/error.js +6 -0
- package/src/hooks/use-locale.jsx +6 -0
- package/src/index.js +43 -0
- package/src/locales/en.jsx +15 -0
- package/src/locales/index.jsx +13 -0
- package/src/locales/zh.jsx +15 -0
- package/src/types.d.ts +355 -0
- package/src/utils.js +395 -0
- 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
|
+
};
|