@nihplod/sso-sdk 1.2.1 → 1.3.1
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/README.md +445 -441
- package/dist/index.d.mts +15 -4
- package/dist/index.d.ts +15 -4
- package/dist/index.js +62 -11
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +62 -11
- package/dist/index.mjs.map +1 -1
- package/dist/next/index.d.mts +27 -2
- package/dist/next/index.d.ts +27 -2
- package/dist/next/index.js +118 -41
- package/dist/next/index.js.map +1 -1
- package/dist/next/index.mjs +117 -41
- package/dist/next/index.mjs.map +1 -1
- package/dist/react/index.d.mts +15 -4
- package/dist/react/index.d.ts +15 -4
- package/dist/react/index.js +112 -17
- package/dist/react/index.js.map +1 -1
- package/dist/react/index.mjs +112 -17
- package/dist/react/index.mjs.map +1 -1
- package/package.json +1 -1
package/dist/react/index.js
CHANGED
|
@@ -117,6 +117,7 @@ var STORAGE_PREFIX = "nihplod_sso_";
|
|
|
117
117
|
var TOKEN_KEY = "token";
|
|
118
118
|
var VERIFIER_KEY_PREFIX = "pkce_verifier_";
|
|
119
119
|
var STATE_KEY = "oauth_state";
|
|
120
|
+
var NONCE_KEY = "oidc_nonce";
|
|
120
121
|
var RETURN_URL_KEY = "return_url";
|
|
121
122
|
var LOGOUT_STATE_KEY = "logout_state";
|
|
122
123
|
function buildKey(base, clientId) {
|
|
@@ -199,6 +200,15 @@ function getOAuthState(clientId) {
|
|
|
199
200
|
function removeOAuthState(clientId) {
|
|
200
201
|
_transient.remove(buildKey(STATE_KEY, clientId));
|
|
201
202
|
}
|
|
203
|
+
function saveOAuthNonce(nonce, clientId) {
|
|
204
|
+
_transient.set(buildKey(NONCE_KEY, clientId), nonce);
|
|
205
|
+
}
|
|
206
|
+
function getOAuthNonce(clientId) {
|
|
207
|
+
return _transient.get(buildKey(NONCE_KEY, clientId));
|
|
208
|
+
}
|
|
209
|
+
function removeOAuthNonce(clientId) {
|
|
210
|
+
_transient.remove(buildKey(NONCE_KEY, clientId));
|
|
211
|
+
}
|
|
202
212
|
function saveLogoutState(state, clientId) {
|
|
203
213
|
_transient.set(buildKey(LOGOUT_STATE_KEY, clientId), state);
|
|
204
214
|
}
|
|
@@ -221,6 +231,7 @@ function clearAllSsoData(clientId) {
|
|
|
221
231
|
if (clientId) {
|
|
222
232
|
removeTokenData(clientId);
|
|
223
233
|
removeOAuthState(clientId);
|
|
234
|
+
removeOAuthNonce(clientId);
|
|
224
235
|
removeReturnUrl(clientId);
|
|
225
236
|
removeLogoutState(clientId);
|
|
226
237
|
removePkceVerifier(clientId);
|
|
@@ -229,6 +240,7 @@ function clearAllSsoData(clientId) {
|
|
|
229
240
|
}
|
|
230
241
|
removeTokenData();
|
|
231
242
|
removeOAuthState();
|
|
243
|
+
removeOAuthNonce();
|
|
232
244
|
removeReturnUrl();
|
|
233
245
|
removeLogoutState();
|
|
234
246
|
const prefix = STORAGE_PREFIX + VERIFIER_KEY_PREFIX;
|
|
@@ -314,18 +326,21 @@ function normalizeIssuer(url) {
|
|
|
314
326
|
var cachedJwks = null;
|
|
315
327
|
var cachedDiscovery = null;
|
|
316
328
|
var JWKS_CACHE_TTL_MS = 5 * 60 * 1e3;
|
|
329
|
+
var FETCH_TIMEOUT_MS = 1e4;
|
|
317
330
|
async function fetchDiscoveryDoc(baseUrl) {
|
|
318
331
|
const now = Date.now();
|
|
319
332
|
if (cachedDiscovery && cachedDiscovery.baseUrl === baseUrl && now - cachedDiscovery.fetchedAt < JWKS_CACHE_TTL_MS) {
|
|
320
333
|
return cachedDiscovery.doc;
|
|
321
334
|
}
|
|
322
335
|
try {
|
|
323
|
-
const res = await fetch(`${baseUrl}/api/oauth/.well-known/openid-configuration
|
|
324
|
-
|
|
336
|
+
const res = await fetch(`${baseUrl}/api/oauth/.well-known/openid-configuration`, {
|
|
337
|
+
signal: AbortSignal.timeout(FETCH_TIMEOUT_MS)
|
|
338
|
+
});
|
|
339
|
+
if (!res.ok) return null;
|
|
340
|
+
const doc = await res.json();
|
|
325
341
|
cachedDiscovery = { baseUrl, doc, fetchedAt: now };
|
|
326
342
|
return doc;
|
|
327
343
|
} catch {
|
|
328
|
-
cachedDiscovery = { baseUrl, doc: null, fetchedAt: now };
|
|
329
344
|
return null;
|
|
330
345
|
}
|
|
331
346
|
}
|
|
@@ -337,7 +352,10 @@ async function fetchJwks(baseUrl, options = {}) {
|
|
|
337
352
|
const discovery = await fetchDiscoveryDoc(baseUrl);
|
|
338
353
|
const jwksUri = discovery?.jwks_uri || `${baseUrl}/api/oauth/jwks`;
|
|
339
354
|
try {
|
|
340
|
-
const res = await fetch(jwksUri,
|
|
355
|
+
const res = await fetch(jwksUri, {
|
|
356
|
+
signal: AbortSignal.timeout(FETCH_TIMEOUT_MS),
|
|
357
|
+
...options.forceRefresh ? { cache: "no-cache" } : {}
|
|
358
|
+
});
|
|
341
359
|
if (!res.ok) return null;
|
|
342
360
|
const jwks = await res.json();
|
|
343
361
|
cachedJwks = { baseUrl, jwks, fetchedAt: now };
|
|
@@ -384,7 +402,7 @@ async function computeAtHash(accessToken) {
|
|
|
384
402
|
return btoa(binary).replace(/\+/g, "-").replace(/\//g, "_").replace(/=+$/, "");
|
|
385
403
|
}
|
|
386
404
|
async function validateIdToken(idToken, accessToken, expectedIssuer, expectedClientId, options = {}) {
|
|
387
|
-
const { rejectHs256WhenRs256Available = true } = options;
|
|
405
|
+
const { rejectHs256WhenRs256Available = true, expectedNonce } = options;
|
|
388
406
|
const header = decodeJwtHeader(idToken);
|
|
389
407
|
if (!header) {
|
|
390
408
|
throw new SsoError("id_token_invalid", "ID Token \u683C\u5F0F\u9519\u8BEF");
|
|
@@ -474,6 +492,12 @@ async function validateIdToken(idToken, accessToken, expectedIssuer, expectedCli
|
|
|
474
492
|
throw new SsoError("id_token_at_hash_mismatch", "ID Token at_hash \u4E0D\u5339\u914D");
|
|
475
493
|
}
|
|
476
494
|
}
|
|
495
|
+
if (expectedNonce !== void 0) {
|
|
496
|
+
const tokenNonce = typeof payload.nonce === "string" ? payload.nonce : "";
|
|
497
|
+
if (!tokenNonce || !timingSafeEqualString(expectedNonce, tokenNonce)) {
|
|
498
|
+
throw new SsoError("id_token_nonce_mismatch", "ID Token nonce \u4E0D\u5339\u914D");
|
|
499
|
+
}
|
|
500
|
+
}
|
|
477
501
|
return { sub: payload.sub };
|
|
478
502
|
}
|
|
479
503
|
|
|
@@ -488,6 +512,7 @@ var _SsoClient = class _SsoClient {
|
|
|
488
512
|
if (!config.ssoBaseUrl) throw new SsoError("invalid_config", "ssoBaseUrl \u4E0D\u80FD\u4E3A\u7A7A");
|
|
489
513
|
const base = config.ssoBaseUrl.replace(/\/+$/, "");
|
|
490
514
|
this.config = { ...config, ssoBaseUrl: base };
|
|
515
|
+
this._serverBase = (config.serverBaseUrl ?? base).replace(/\/+$/, "");
|
|
491
516
|
}
|
|
492
517
|
// ============================================
|
|
493
518
|
// 内部方法
|
|
@@ -503,7 +528,7 @@ var _SsoClient = class _SsoClient {
|
|
|
503
528
|
if (this._discovery && now - this._discoveryFetchedAt < _SsoClient.DISCOVERY_TTL_MS) {
|
|
504
529
|
return this._discovery;
|
|
505
530
|
}
|
|
506
|
-
const url = `${this.
|
|
531
|
+
const url = `${this._serverBase}/api/oauth/.well-known/openid-configuration`;
|
|
507
532
|
try {
|
|
508
533
|
const controller = new AbortController();
|
|
509
534
|
const timeoutId = setTimeout(
|
|
@@ -534,14 +559,16 @@ var _SsoClient = class _SsoClient {
|
|
|
534
559
|
if (d) return d.authorization_endpoint;
|
|
535
560
|
return `${this.config.ssoBaseUrl}/api/oauth/authorize`;
|
|
536
561
|
}
|
|
537
|
-
/** 获取 token 端点 URL
|
|
562
|
+
/** 获取 token 端点 URL(服务器间调用:serverBaseUrl 直连优先,其次 Discovery,回退默认) */
|
|
538
563
|
async _getTokenEndpoint() {
|
|
564
|
+
if (this.config.serverBaseUrl) return `${this._serverBase}/api/oauth/token`;
|
|
539
565
|
const d = await this._getDiscovery();
|
|
540
566
|
if (d) return d.token_endpoint;
|
|
541
567
|
return `${this.config.ssoBaseUrl}/api/oauth/token`;
|
|
542
568
|
}
|
|
543
|
-
/** 获取 userinfo 端点 URL
|
|
569
|
+
/** 获取 userinfo 端点 URL(服务器间调用:serverBaseUrl 直连优先,其次 Discovery,回退默认) */
|
|
544
570
|
async _getUserinfoEndpoint() {
|
|
571
|
+
if (this.config.serverBaseUrl) return `${this._serverBase}/api/oauth/userinfo`;
|
|
545
572
|
const d = await this._getDiscovery();
|
|
546
573
|
if (d) return d.userinfo_endpoint;
|
|
547
574
|
return `${this.config.ssoBaseUrl}/api/oauth/userinfo`;
|
|
@@ -577,8 +604,10 @@ var _SsoClient = class _SsoClient {
|
|
|
577
604
|
const verifier = generateCodeVerifier();
|
|
578
605
|
const challenge = await generateCodeChallenge(verifier);
|
|
579
606
|
const state = generateState();
|
|
607
|
+
const nonce = generateState();
|
|
580
608
|
savePkceVerifier(this.config.clientId, verifier);
|
|
581
609
|
saveOAuthState(state, this.config.clientId);
|
|
610
|
+
saveOAuthNonce(nonce, this.config.clientId);
|
|
582
611
|
if (returnUrl) {
|
|
583
612
|
this._saveReturnUrlIfTrusted(returnUrl);
|
|
584
613
|
}
|
|
@@ -589,6 +618,7 @@ var _SsoClient = class _SsoClient {
|
|
|
589
618
|
params.set("redirect_uri", this.config.redirectUri);
|
|
590
619
|
params.set("scope", this.config.scopes || "openid profile");
|
|
591
620
|
params.set("state", state);
|
|
621
|
+
params.set("nonce", nonce);
|
|
592
622
|
params.set("code_challenge", challenge);
|
|
593
623
|
params.set("code_challenge_method", "S256");
|
|
594
624
|
window.location.href = `${authorizeEndpoint}?${params.toString()}`;
|
|
@@ -606,8 +636,10 @@ var _SsoClient = class _SsoClient {
|
|
|
606
636
|
const verifier = generateCodeVerifier();
|
|
607
637
|
const challenge = await generateCodeChallenge(verifier);
|
|
608
638
|
const state = generateState();
|
|
639
|
+
const nonce = generateState();
|
|
609
640
|
savePkceVerifier(this.config.clientId, verifier);
|
|
610
641
|
saveOAuthState(state, this.config.clientId);
|
|
642
|
+
saveOAuthNonce(nonce, this.config.clientId);
|
|
611
643
|
if (returnUrl) this._saveReturnUrlIfTrusted(returnUrl);
|
|
612
644
|
const authorizeEndpoint = await this._getAuthorizeEndpoint();
|
|
613
645
|
const params = new URLSearchParams();
|
|
@@ -616,6 +648,7 @@ var _SsoClient = class _SsoClient {
|
|
|
616
648
|
params.set("redirect_uri", this.config.redirectUri);
|
|
617
649
|
params.set("scope", this.config.scopes || "openid profile");
|
|
618
650
|
params.set("state", state);
|
|
651
|
+
params.set("nonce", nonce);
|
|
619
652
|
params.set("code_challenge", challenge);
|
|
620
653
|
params.set("code_challenge_method", "S256");
|
|
621
654
|
return `${authorizeEndpoint}?${params.toString()}`;
|
|
@@ -657,9 +690,11 @@ var _SsoClient = class _SsoClient {
|
|
|
657
690
|
const verifier = generateCodeVerifier();
|
|
658
691
|
const challenge = await generateCodeChallenge(verifier);
|
|
659
692
|
const state = generateState();
|
|
693
|
+
const nonce = generateState();
|
|
660
694
|
const popupNonce = generateState();
|
|
661
695
|
savePkceVerifier(this.config.clientId, verifier);
|
|
662
696
|
saveOAuthState(state, this.config.clientId);
|
|
697
|
+
saveOAuthNonce(nonce, this.config.clientId);
|
|
663
698
|
savePkceVerifier(`${this.config.clientId}_popup_nonce`, popupNonce);
|
|
664
699
|
if (options.returnUrl) {
|
|
665
700
|
this._saveReturnUrlIfTrusted(options.returnUrl);
|
|
@@ -671,6 +706,7 @@ var _SsoClient = class _SsoClient {
|
|
|
671
706
|
params.set("redirect_uri", this.config.redirectUri);
|
|
672
707
|
params.set("scope", this.config.scopes || "openid profile");
|
|
673
708
|
params.set("state", state);
|
|
709
|
+
params.set("nonce", nonce);
|
|
674
710
|
params.set("code_challenge", challenge);
|
|
675
711
|
params.set("code_challenge_method", "S256");
|
|
676
712
|
params.set("popup_nonce", popupNonce);
|
|
@@ -695,6 +731,7 @@ var _SsoClient = class _SsoClient {
|
|
|
695
731
|
if (!popup) {
|
|
696
732
|
removePkceVerifier(this.config.clientId);
|
|
697
733
|
removeOAuthState(this.config.clientId);
|
|
734
|
+
removeOAuthNonce(this.config.clientId);
|
|
698
735
|
removePkceVerifier(`${this.config.clientId}_popup_nonce`);
|
|
699
736
|
throw new SsoError(
|
|
700
737
|
"popup_blocked",
|
|
@@ -714,6 +751,13 @@ var _SsoClient = class _SsoClient {
|
|
|
714
751
|
const savedNonce = getPkceVerifier(`${this.config.clientId}_popup_nonce`);
|
|
715
752
|
if (!savedNonce || !timingSafeEqualString(event.data.nonce ?? "", savedNonce)) return;
|
|
716
753
|
removePkceVerifier(`${this.config.clientId}_popup_nonce`);
|
|
754
|
+
try {
|
|
755
|
+
event.source?.postMessage(
|
|
756
|
+
{ type: "nihplod_sso_popup_ack", nonce: savedNonce },
|
|
757
|
+
event.origin
|
|
758
|
+
);
|
|
759
|
+
} catch {
|
|
760
|
+
}
|
|
717
761
|
completed = true;
|
|
718
762
|
cleanup();
|
|
719
763
|
if (popup && !popup.closed) {
|
|
@@ -745,6 +789,7 @@ var _SsoClient = class _SsoClient {
|
|
|
745
789
|
} catch (err) {
|
|
746
790
|
removePkceVerifier(this.config.clientId);
|
|
747
791
|
removeOAuthState(this.config.clientId);
|
|
792
|
+
removeOAuthNonce(this.config.clientId);
|
|
748
793
|
removePkceVerifier(`${this.config.clientId}_popup_nonce`);
|
|
749
794
|
throw err;
|
|
750
795
|
}
|
|
@@ -764,6 +809,7 @@ var _SsoClient = class _SsoClient {
|
|
|
764
809
|
const error = params.get("error");
|
|
765
810
|
if (error) {
|
|
766
811
|
removeOAuthState(this.config.clientId);
|
|
812
|
+
removeOAuthNonce(this.config.clientId);
|
|
767
813
|
removePkceVerifier(this.config.clientId);
|
|
768
814
|
const desc = params.get("error_description") || error;
|
|
769
815
|
throw new SsoError(mapOAuthErrorToSsoCode(error), `\u6388\u6743\u5931\u8D25: ${desc}`);
|
|
@@ -772,18 +818,21 @@ var _SsoClient = class _SsoClient {
|
|
|
772
818
|
const returnedState = params.get("state");
|
|
773
819
|
if (!code) {
|
|
774
820
|
removeOAuthState(this.config.clientId);
|
|
821
|
+
removeOAuthNonce(this.config.clientId);
|
|
775
822
|
removePkceVerifier(this.config.clientId);
|
|
776
823
|
throw new SsoError("token_request_failed", "\u56DE\u8C03 URL \u4E2D\u7F3A\u5C11 authorization code");
|
|
777
824
|
}
|
|
778
825
|
const savedState = getOAuthState(this.config.clientId);
|
|
779
826
|
if (!savedState || !timingSafeEqualString(savedState, returnedState ?? "")) {
|
|
780
827
|
removeOAuthState(this.config.clientId);
|
|
828
|
+
removeOAuthNonce(this.config.clientId);
|
|
781
829
|
removePkceVerifier(this.config.clientId);
|
|
782
830
|
throw new SsoError(
|
|
783
831
|
"state_mismatch",
|
|
784
832
|
"State \u53C2\u6570\u4E0D\u5339\u914D\uFF0C\u53EF\u80FD\u5B58\u5728 CSRF \u653B\u51FB"
|
|
785
833
|
);
|
|
786
834
|
}
|
|
835
|
+
const expectedNonce = getOAuthNonce(this.config.clientId) ?? void 0;
|
|
787
836
|
const verifier = getPkceVerifier(this.config.clientId);
|
|
788
837
|
if (!verifier) {
|
|
789
838
|
throw new SsoError(
|
|
@@ -830,7 +879,8 @@ var _SsoClient = class _SsoClient {
|
|
|
830
879
|
data.id_token,
|
|
831
880
|
data.access_token,
|
|
832
881
|
this.config.ssoBaseUrl,
|
|
833
|
-
this.config.clientId
|
|
882
|
+
this.config.clientId,
|
|
883
|
+
{ expectedNonce }
|
|
834
884
|
);
|
|
835
885
|
} catch (err) {
|
|
836
886
|
removeTokenData(this.config.clientId);
|
|
@@ -838,6 +888,7 @@ var _SsoClient = class _SsoClient {
|
|
|
838
888
|
}
|
|
839
889
|
}
|
|
840
890
|
removeOAuthState(this.config.clientId);
|
|
891
|
+
removeOAuthNonce(this.config.clientId);
|
|
841
892
|
removePkceVerifier(this.config.clientId);
|
|
842
893
|
const now = Date.now();
|
|
843
894
|
const tokenData = {
|
|
@@ -1018,8 +1069,8 @@ var _SsoClient = class _SsoClient {
|
|
|
1018
1069
|
clearAllSsoData(this.config.clientId);
|
|
1019
1070
|
if (refreshToken && this.config.clientId) {
|
|
1020
1071
|
try {
|
|
1021
|
-
const discovery = await this._getDiscovery();
|
|
1022
|
-
const revokeUrl = discovery?.revocation_endpoint || `${this.config.ssoBaseUrl}/api/oauth/revoke`;
|
|
1072
|
+
const discovery = this.config.serverBaseUrl ? null : await this._getDiscovery();
|
|
1073
|
+
const revokeUrl = this.config.serverBaseUrl ? `${this._serverBase}/api/oauth/revoke` : discovery?.revocation_endpoint || `${this.config.ssoBaseUrl}/api/oauth/revoke`;
|
|
1023
1074
|
const revokeBody = new URLSearchParams({
|
|
1024
1075
|
token: refreshToken,
|
|
1025
1076
|
token_type_hint: "refresh_token",
|
|
@@ -1189,7 +1240,9 @@ function SsoProvider({
|
|
|
1189
1240
|
setError(
|
|
1190
1241
|
err instanceof SsoError ? err : new SsoError("userinfo_failed", err instanceof Error ? err.message : String(err))
|
|
1191
1242
|
);
|
|
1192
|
-
|
|
1243
|
+
if (err instanceof SsoError && (err.code === "not_authenticated" || err.code === "session_expired")) {
|
|
1244
|
+
removeTokenData(client.config.clientId);
|
|
1245
|
+
}
|
|
1193
1246
|
} finally {
|
|
1194
1247
|
setIsLoading(false);
|
|
1195
1248
|
}
|
|
@@ -1426,6 +1479,7 @@ function CallbackPage({ onSuccess, onError, renderError } = {}) {
|
|
|
1426
1479
|
const { client, refreshUser } = useSso();
|
|
1427
1480
|
const [error, setError] = (0, import_react3.useState)(null);
|
|
1428
1481
|
const [processing, setProcessing] = (0, import_react3.useState)(true);
|
|
1482
|
+
const [awaitingManualClose, setAwaitingManualClose] = (0, import_react3.useState)(false);
|
|
1429
1483
|
const onSuccessRef = (0, import_react3.useRef)(onSuccess);
|
|
1430
1484
|
const onErrorRef = (0, import_react3.useRef)(onError);
|
|
1431
1485
|
(0, import_react3.useEffect)(() => {
|
|
@@ -1440,12 +1494,38 @@ function CallbackPage({ onSuccess, onError, renderError } = {}) {
|
|
|
1440
1494
|
targetOrigin = window.opener.location.origin;
|
|
1441
1495
|
} catch {
|
|
1442
1496
|
}
|
|
1443
|
-
|
|
1444
|
-
|
|
1445
|
-
|
|
1446
|
-
|
|
1497
|
+
const message = {
|
|
1498
|
+
type: "nihplod_sso_popup_callback",
|
|
1499
|
+
callbackUrl: window.location.href,
|
|
1500
|
+
nonce: nonce || void 0
|
|
1501
|
+
};
|
|
1502
|
+
let acked = false;
|
|
1503
|
+
const send = () => {
|
|
1504
|
+
if (acked || !window.opener || window.opener.closed) return;
|
|
1505
|
+
window.opener.postMessage(message, targetOrigin);
|
|
1506
|
+
};
|
|
1507
|
+
send();
|
|
1508
|
+
const resendTimer = setInterval(send, 500);
|
|
1509
|
+
const ackTimeout = setTimeout(() => {
|
|
1510
|
+
if (acked) return;
|
|
1511
|
+
clearInterval(resendTimer);
|
|
1512
|
+
setAwaitingManualClose(true);
|
|
1513
|
+
}, 1e4);
|
|
1514
|
+
const handleAck = (event) => {
|
|
1515
|
+
if (event.origin !== targetOrigin) return;
|
|
1516
|
+
if (!event.data || event.data.type !== "nihplod_sso_popup_ack") return;
|
|
1517
|
+
if (nonce && event.data.nonce !== nonce) return;
|
|
1518
|
+
acked = true;
|
|
1519
|
+
clearInterval(resendTimer);
|
|
1520
|
+
clearTimeout(ackTimeout);
|
|
1521
|
+
};
|
|
1522
|
+
window.addEventListener("message", handleAck);
|
|
1447
1523
|
Promise.resolve().then(() => setProcessing(false));
|
|
1448
|
-
return
|
|
1524
|
+
return () => {
|
|
1525
|
+
clearInterval(resendTimer);
|
|
1526
|
+
clearTimeout(ackTimeout);
|
|
1527
|
+
window.removeEventListener("message", handleAck);
|
|
1528
|
+
};
|
|
1449
1529
|
}
|
|
1450
1530
|
let cancelled = false;
|
|
1451
1531
|
async function handleCallback() {
|
|
@@ -1484,6 +1564,21 @@ function CallbackPage({ onSuccess, onError, renderError } = {}) {
|
|
|
1484
1564
|
if (renderError) return import_react3.default.createElement(import_react3.default.Fragment, null, renderError(error));
|
|
1485
1565
|
return import_react3.default.createElement(DefaultCallbackError, { error });
|
|
1486
1566
|
}
|
|
1567
|
+
if (awaitingManualClose) {
|
|
1568
|
+
return import_react3.default.createElement(
|
|
1569
|
+
"div",
|
|
1570
|
+
{
|
|
1571
|
+
style: {
|
|
1572
|
+
display: "flex",
|
|
1573
|
+
alignItems: "center",
|
|
1574
|
+
justifyContent: "center",
|
|
1575
|
+
minHeight: "100vh",
|
|
1576
|
+
fontFamily: "system-ui, sans-serif"
|
|
1577
|
+
}
|
|
1578
|
+
},
|
|
1579
|
+
import_react3.default.createElement("p", null, "\u767B\u5F55\u5DF2\u5B8C\u6210\uFF0C\u8BF7\u624B\u52A8\u5173\u95ED\u6B64\u7A97\u53E3")
|
|
1580
|
+
);
|
|
1581
|
+
}
|
|
1487
1582
|
if (processing) {
|
|
1488
1583
|
return import_react3.default.createElement(
|
|
1489
1584
|
"div",
|