@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.mjs
CHANGED
|
@@ -83,6 +83,7 @@ var STORAGE_PREFIX = "nihplod_sso_";
|
|
|
83
83
|
var TOKEN_KEY = "token";
|
|
84
84
|
var VERIFIER_KEY_PREFIX = "pkce_verifier_";
|
|
85
85
|
var STATE_KEY = "oauth_state";
|
|
86
|
+
var NONCE_KEY = "oidc_nonce";
|
|
86
87
|
var RETURN_URL_KEY = "return_url";
|
|
87
88
|
var LOGOUT_STATE_KEY = "logout_state";
|
|
88
89
|
function buildKey(base, clientId) {
|
|
@@ -165,6 +166,15 @@ function getOAuthState(clientId) {
|
|
|
165
166
|
function removeOAuthState(clientId) {
|
|
166
167
|
_transient.remove(buildKey(STATE_KEY, clientId));
|
|
167
168
|
}
|
|
169
|
+
function saveOAuthNonce(nonce, clientId) {
|
|
170
|
+
_transient.set(buildKey(NONCE_KEY, clientId), nonce);
|
|
171
|
+
}
|
|
172
|
+
function getOAuthNonce(clientId) {
|
|
173
|
+
return _transient.get(buildKey(NONCE_KEY, clientId));
|
|
174
|
+
}
|
|
175
|
+
function removeOAuthNonce(clientId) {
|
|
176
|
+
_transient.remove(buildKey(NONCE_KEY, clientId));
|
|
177
|
+
}
|
|
168
178
|
function saveLogoutState(state, clientId) {
|
|
169
179
|
_transient.set(buildKey(LOGOUT_STATE_KEY, clientId), state);
|
|
170
180
|
}
|
|
@@ -187,6 +197,7 @@ function clearAllSsoData(clientId) {
|
|
|
187
197
|
if (clientId) {
|
|
188
198
|
removeTokenData(clientId);
|
|
189
199
|
removeOAuthState(clientId);
|
|
200
|
+
removeOAuthNonce(clientId);
|
|
190
201
|
removeReturnUrl(clientId);
|
|
191
202
|
removeLogoutState(clientId);
|
|
192
203
|
removePkceVerifier(clientId);
|
|
@@ -195,6 +206,7 @@ function clearAllSsoData(clientId) {
|
|
|
195
206
|
}
|
|
196
207
|
removeTokenData();
|
|
197
208
|
removeOAuthState();
|
|
209
|
+
removeOAuthNonce();
|
|
198
210
|
removeReturnUrl();
|
|
199
211
|
removeLogoutState();
|
|
200
212
|
const prefix = STORAGE_PREFIX + VERIFIER_KEY_PREFIX;
|
|
@@ -280,18 +292,21 @@ function normalizeIssuer(url) {
|
|
|
280
292
|
var cachedJwks = null;
|
|
281
293
|
var cachedDiscovery = null;
|
|
282
294
|
var JWKS_CACHE_TTL_MS = 5 * 60 * 1e3;
|
|
295
|
+
var FETCH_TIMEOUT_MS = 1e4;
|
|
283
296
|
async function fetchDiscoveryDoc(baseUrl) {
|
|
284
297
|
const now = Date.now();
|
|
285
298
|
if (cachedDiscovery && cachedDiscovery.baseUrl === baseUrl && now - cachedDiscovery.fetchedAt < JWKS_CACHE_TTL_MS) {
|
|
286
299
|
return cachedDiscovery.doc;
|
|
287
300
|
}
|
|
288
301
|
try {
|
|
289
|
-
const res = await fetch(`${baseUrl}/api/oauth/.well-known/openid-configuration
|
|
290
|
-
|
|
302
|
+
const res = await fetch(`${baseUrl}/api/oauth/.well-known/openid-configuration`, {
|
|
303
|
+
signal: AbortSignal.timeout(FETCH_TIMEOUT_MS)
|
|
304
|
+
});
|
|
305
|
+
if (!res.ok) return null;
|
|
306
|
+
const doc = await res.json();
|
|
291
307
|
cachedDiscovery = { baseUrl, doc, fetchedAt: now };
|
|
292
308
|
return doc;
|
|
293
309
|
} catch {
|
|
294
|
-
cachedDiscovery = { baseUrl, doc: null, fetchedAt: now };
|
|
295
310
|
return null;
|
|
296
311
|
}
|
|
297
312
|
}
|
|
@@ -303,7 +318,10 @@ async function fetchJwks(baseUrl, options = {}) {
|
|
|
303
318
|
const discovery = await fetchDiscoveryDoc(baseUrl);
|
|
304
319
|
const jwksUri = discovery?.jwks_uri || `${baseUrl}/api/oauth/jwks`;
|
|
305
320
|
try {
|
|
306
|
-
const res = await fetch(jwksUri,
|
|
321
|
+
const res = await fetch(jwksUri, {
|
|
322
|
+
signal: AbortSignal.timeout(FETCH_TIMEOUT_MS),
|
|
323
|
+
...options.forceRefresh ? { cache: "no-cache" } : {}
|
|
324
|
+
});
|
|
307
325
|
if (!res.ok) return null;
|
|
308
326
|
const jwks = await res.json();
|
|
309
327
|
cachedJwks = { baseUrl, jwks, fetchedAt: now };
|
|
@@ -350,7 +368,7 @@ async function computeAtHash(accessToken) {
|
|
|
350
368
|
return btoa(binary).replace(/\+/g, "-").replace(/\//g, "_").replace(/=+$/, "");
|
|
351
369
|
}
|
|
352
370
|
async function validateIdToken(idToken, accessToken, expectedIssuer, expectedClientId, options = {}) {
|
|
353
|
-
const { rejectHs256WhenRs256Available = true } = options;
|
|
371
|
+
const { rejectHs256WhenRs256Available = true, expectedNonce } = options;
|
|
354
372
|
const header = decodeJwtHeader(idToken);
|
|
355
373
|
if (!header) {
|
|
356
374
|
throw new SsoError("id_token_invalid", "ID Token \u683C\u5F0F\u9519\u8BEF");
|
|
@@ -440,6 +458,12 @@ async function validateIdToken(idToken, accessToken, expectedIssuer, expectedCli
|
|
|
440
458
|
throw new SsoError("id_token_at_hash_mismatch", "ID Token at_hash \u4E0D\u5339\u914D");
|
|
441
459
|
}
|
|
442
460
|
}
|
|
461
|
+
if (expectedNonce !== void 0) {
|
|
462
|
+
const tokenNonce = typeof payload.nonce === "string" ? payload.nonce : "";
|
|
463
|
+
if (!tokenNonce || !timingSafeEqualString(expectedNonce, tokenNonce)) {
|
|
464
|
+
throw new SsoError("id_token_nonce_mismatch", "ID Token nonce \u4E0D\u5339\u914D");
|
|
465
|
+
}
|
|
466
|
+
}
|
|
443
467
|
return { sub: payload.sub };
|
|
444
468
|
}
|
|
445
469
|
|
|
@@ -454,6 +478,7 @@ var _SsoClient = class _SsoClient {
|
|
|
454
478
|
if (!config.ssoBaseUrl) throw new SsoError("invalid_config", "ssoBaseUrl \u4E0D\u80FD\u4E3A\u7A7A");
|
|
455
479
|
const base = config.ssoBaseUrl.replace(/\/+$/, "");
|
|
456
480
|
this.config = { ...config, ssoBaseUrl: base };
|
|
481
|
+
this._serverBase = (config.serverBaseUrl ?? base).replace(/\/+$/, "");
|
|
457
482
|
}
|
|
458
483
|
// ============================================
|
|
459
484
|
// 内部方法
|
|
@@ -469,7 +494,7 @@ var _SsoClient = class _SsoClient {
|
|
|
469
494
|
if (this._discovery && now - this._discoveryFetchedAt < _SsoClient.DISCOVERY_TTL_MS) {
|
|
470
495
|
return this._discovery;
|
|
471
496
|
}
|
|
472
|
-
const url = `${this.
|
|
497
|
+
const url = `${this._serverBase}/api/oauth/.well-known/openid-configuration`;
|
|
473
498
|
try {
|
|
474
499
|
const controller = new AbortController();
|
|
475
500
|
const timeoutId = setTimeout(
|
|
@@ -500,14 +525,16 @@ var _SsoClient = class _SsoClient {
|
|
|
500
525
|
if (d) return d.authorization_endpoint;
|
|
501
526
|
return `${this.config.ssoBaseUrl}/api/oauth/authorize`;
|
|
502
527
|
}
|
|
503
|
-
/** 获取 token 端点 URL
|
|
528
|
+
/** 获取 token 端点 URL(服务器间调用:serverBaseUrl 直连优先,其次 Discovery,回退默认) */
|
|
504
529
|
async _getTokenEndpoint() {
|
|
530
|
+
if (this.config.serverBaseUrl) return `${this._serverBase}/api/oauth/token`;
|
|
505
531
|
const d = await this._getDiscovery();
|
|
506
532
|
if (d) return d.token_endpoint;
|
|
507
533
|
return `${this.config.ssoBaseUrl}/api/oauth/token`;
|
|
508
534
|
}
|
|
509
|
-
/** 获取 userinfo 端点 URL
|
|
535
|
+
/** 获取 userinfo 端点 URL(服务器间调用:serverBaseUrl 直连优先,其次 Discovery,回退默认) */
|
|
510
536
|
async _getUserinfoEndpoint() {
|
|
537
|
+
if (this.config.serverBaseUrl) return `${this._serverBase}/api/oauth/userinfo`;
|
|
511
538
|
const d = await this._getDiscovery();
|
|
512
539
|
if (d) return d.userinfo_endpoint;
|
|
513
540
|
return `${this.config.ssoBaseUrl}/api/oauth/userinfo`;
|
|
@@ -543,8 +570,10 @@ var _SsoClient = class _SsoClient {
|
|
|
543
570
|
const verifier = generateCodeVerifier();
|
|
544
571
|
const challenge = await generateCodeChallenge(verifier);
|
|
545
572
|
const state = generateState();
|
|
573
|
+
const nonce = generateState();
|
|
546
574
|
savePkceVerifier(this.config.clientId, verifier);
|
|
547
575
|
saveOAuthState(state, this.config.clientId);
|
|
576
|
+
saveOAuthNonce(nonce, this.config.clientId);
|
|
548
577
|
if (returnUrl) {
|
|
549
578
|
this._saveReturnUrlIfTrusted(returnUrl);
|
|
550
579
|
}
|
|
@@ -555,6 +584,7 @@ var _SsoClient = class _SsoClient {
|
|
|
555
584
|
params.set("redirect_uri", this.config.redirectUri);
|
|
556
585
|
params.set("scope", this.config.scopes || "openid profile");
|
|
557
586
|
params.set("state", state);
|
|
587
|
+
params.set("nonce", nonce);
|
|
558
588
|
params.set("code_challenge", challenge);
|
|
559
589
|
params.set("code_challenge_method", "S256");
|
|
560
590
|
window.location.href = `${authorizeEndpoint}?${params.toString()}`;
|
|
@@ -572,8 +602,10 @@ var _SsoClient = class _SsoClient {
|
|
|
572
602
|
const verifier = generateCodeVerifier();
|
|
573
603
|
const challenge = await generateCodeChallenge(verifier);
|
|
574
604
|
const state = generateState();
|
|
605
|
+
const nonce = generateState();
|
|
575
606
|
savePkceVerifier(this.config.clientId, verifier);
|
|
576
607
|
saveOAuthState(state, this.config.clientId);
|
|
608
|
+
saveOAuthNonce(nonce, this.config.clientId);
|
|
577
609
|
if (returnUrl) this._saveReturnUrlIfTrusted(returnUrl);
|
|
578
610
|
const authorizeEndpoint = await this._getAuthorizeEndpoint();
|
|
579
611
|
const params = new URLSearchParams();
|
|
@@ -582,6 +614,7 @@ var _SsoClient = class _SsoClient {
|
|
|
582
614
|
params.set("redirect_uri", this.config.redirectUri);
|
|
583
615
|
params.set("scope", this.config.scopes || "openid profile");
|
|
584
616
|
params.set("state", state);
|
|
617
|
+
params.set("nonce", nonce);
|
|
585
618
|
params.set("code_challenge", challenge);
|
|
586
619
|
params.set("code_challenge_method", "S256");
|
|
587
620
|
return `${authorizeEndpoint}?${params.toString()}`;
|
|
@@ -623,9 +656,11 @@ var _SsoClient = class _SsoClient {
|
|
|
623
656
|
const verifier = generateCodeVerifier();
|
|
624
657
|
const challenge = await generateCodeChallenge(verifier);
|
|
625
658
|
const state = generateState();
|
|
659
|
+
const nonce = generateState();
|
|
626
660
|
const popupNonce = generateState();
|
|
627
661
|
savePkceVerifier(this.config.clientId, verifier);
|
|
628
662
|
saveOAuthState(state, this.config.clientId);
|
|
663
|
+
saveOAuthNonce(nonce, this.config.clientId);
|
|
629
664
|
savePkceVerifier(`${this.config.clientId}_popup_nonce`, popupNonce);
|
|
630
665
|
if (options.returnUrl) {
|
|
631
666
|
this._saveReturnUrlIfTrusted(options.returnUrl);
|
|
@@ -637,6 +672,7 @@ var _SsoClient = class _SsoClient {
|
|
|
637
672
|
params.set("redirect_uri", this.config.redirectUri);
|
|
638
673
|
params.set("scope", this.config.scopes || "openid profile");
|
|
639
674
|
params.set("state", state);
|
|
675
|
+
params.set("nonce", nonce);
|
|
640
676
|
params.set("code_challenge", challenge);
|
|
641
677
|
params.set("code_challenge_method", "S256");
|
|
642
678
|
params.set("popup_nonce", popupNonce);
|
|
@@ -661,6 +697,7 @@ var _SsoClient = class _SsoClient {
|
|
|
661
697
|
if (!popup) {
|
|
662
698
|
removePkceVerifier(this.config.clientId);
|
|
663
699
|
removeOAuthState(this.config.clientId);
|
|
700
|
+
removeOAuthNonce(this.config.clientId);
|
|
664
701
|
removePkceVerifier(`${this.config.clientId}_popup_nonce`);
|
|
665
702
|
throw new SsoError(
|
|
666
703
|
"popup_blocked",
|
|
@@ -680,6 +717,13 @@ var _SsoClient = class _SsoClient {
|
|
|
680
717
|
const savedNonce = getPkceVerifier(`${this.config.clientId}_popup_nonce`);
|
|
681
718
|
if (!savedNonce || !timingSafeEqualString(event.data.nonce ?? "", savedNonce)) return;
|
|
682
719
|
removePkceVerifier(`${this.config.clientId}_popup_nonce`);
|
|
720
|
+
try {
|
|
721
|
+
event.source?.postMessage(
|
|
722
|
+
{ type: "nihplod_sso_popup_ack", nonce: savedNonce },
|
|
723
|
+
event.origin
|
|
724
|
+
);
|
|
725
|
+
} catch {
|
|
726
|
+
}
|
|
683
727
|
completed = true;
|
|
684
728
|
cleanup();
|
|
685
729
|
if (popup && !popup.closed) {
|
|
@@ -711,6 +755,7 @@ var _SsoClient = class _SsoClient {
|
|
|
711
755
|
} catch (err) {
|
|
712
756
|
removePkceVerifier(this.config.clientId);
|
|
713
757
|
removeOAuthState(this.config.clientId);
|
|
758
|
+
removeOAuthNonce(this.config.clientId);
|
|
714
759
|
removePkceVerifier(`${this.config.clientId}_popup_nonce`);
|
|
715
760
|
throw err;
|
|
716
761
|
}
|
|
@@ -730,6 +775,7 @@ var _SsoClient = class _SsoClient {
|
|
|
730
775
|
const error = params.get("error");
|
|
731
776
|
if (error) {
|
|
732
777
|
removeOAuthState(this.config.clientId);
|
|
778
|
+
removeOAuthNonce(this.config.clientId);
|
|
733
779
|
removePkceVerifier(this.config.clientId);
|
|
734
780
|
const desc = params.get("error_description") || error;
|
|
735
781
|
throw new SsoError(mapOAuthErrorToSsoCode(error), `\u6388\u6743\u5931\u8D25: ${desc}`);
|
|
@@ -738,18 +784,21 @@ var _SsoClient = class _SsoClient {
|
|
|
738
784
|
const returnedState = params.get("state");
|
|
739
785
|
if (!code) {
|
|
740
786
|
removeOAuthState(this.config.clientId);
|
|
787
|
+
removeOAuthNonce(this.config.clientId);
|
|
741
788
|
removePkceVerifier(this.config.clientId);
|
|
742
789
|
throw new SsoError("token_request_failed", "\u56DE\u8C03 URL \u4E2D\u7F3A\u5C11 authorization code");
|
|
743
790
|
}
|
|
744
791
|
const savedState = getOAuthState(this.config.clientId);
|
|
745
792
|
if (!savedState || !timingSafeEqualString(savedState, returnedState ?? "")) {
|
|
746
793
|
removeOAuthState(this.config.clientId);
|
|
794
|
+
removeOAuthNonce(this.config.clientId);
|
|
747
795
|
removePkceVerifier(this.config.clientId);
|
|
748
796
|
throw new SsoError(
|
|
749
797
|
"state_mismatch",
|
|
750
798
|
"State \u53C2\u6570\u4E0D\u5339\u914D\uFF0C\u53EF\u80FD\u5B58\u5728 CSRF \u653B\u51FB"
|
|
751
799
|
);
|
|
752
800
|
}
|
|
801
|
+
const expectedNonce = getOAuthNonce(this.config.clientId) ?? void 0;
|
|
753
802
|
const verifier = getPkceVerifier(this.config.clientId);
|
|
754
803
|
if (!verifier) {
|
|
755
804
|
throw new SsoError(
|
|
@@ -796,7 +845,8 @@ var _SsoClient = class _SsoClient {
|
|
|
796
845
|
data.id_token,
|
|
797
846
|
data.access_token,
|
|
798
847
|
this.config.ssoBaseUrl,
|
|
799
|
-
this.config.clientId
|
|
848
|
+
this.config.clientId,
|
|
849
|
+
{ expectedNonce }
|
|
800
850
|
);
|
|
801
851
|
} catch (err) {
|
|
802
852
|
removeTokenData(this.config.clientId);
|
|
@@ -804,6 +854,7 @@ var _SsoClient = class _SsoClient {
|
|
|
804
854
|
}
|
|
805
855
|
}
|
|
806
856
|
removeOAuthState(this.config.clientId);
|
|
857
|
+
removeOAuthNonce(this.config.clientId);
|
|
807
858
|
removePkceVerifier(this.config.clientId);
|
|
808
859
|
const now = Date.now();
|
|
809
860
|
const tokenData = {
|
|
@@ -984,8 +1035,8 @@ var _SsoClient = class _SsoClient {
|
|
|
984
1035
|
clearAllSsoData(this.config.clientId);
|
|
985
1036
|
if (refreshToken && this.config.clientId) {
|
|
986
1037
|
try {
|
|
987
|
-
const discovery = await this._getDiscovery();
|
|
988
|
-
const revokeUrl = discovery?.revocation_endpoint || `${this.config.ssoBaseUrl}/api/oauth/revoke`;
|
|
1038
|
+
const discovery = this.config.serverBaseUrl ? null : await this._getDiscovery();
|
|
1039
|
+
const revokeUrl = this.config.serverBaseUrl ? `${this._serverBase}/api/oauth/revoke` : discovery?.revocation_endpoint || `${this.config.ssoBaseUrl}/api/oauth/revoke`;
|
|
989
1040
|
const revokeBody = new URLSearchParams({
|
|
990
1041
|
token: refreshToken,
|
|
991
1042
|
token_type_hint: "refresh_token",
|
|
@@ -1155,7 +1206,9 @@ function SsoProvider({
|
|
|
1155
1206
|
setError(
|
|
1156
1207
|
err instanceof SsoError ? err : new SsoError("userinfo_failed", err instanceof Error ? err.message : String(err))
|
|
1157
1208
|
);
|
|
1158
|
-
|
|
1209
|
+
if (err instanceof SsoError && (err.code === "not_authenticated" || err.code === "session_expired")) {
|
|
1210
|
+
removeTokenData(client.config.clientId);
|
|
1211
|
+
}
|
|
1159
1212
|
} finally {
|
|
1160
1213
|
setIsLoading(false);
|
|
1161
1214
|
}
|
|
@@ -1392,6 +1445,7 @@ function CallbackPage({ onSuccess, onError, renderError } = {}) {
|
|
|
1392
1445
|
const { client, refreshUser } = useSso();
|
|
1393
1446
|
const [error, setError] = useState3(null);
|
|
1394
1447
|
const [processing, setProcessing] = useState3(true);
|
|
1448
|
+
const [awaitingManualClose, setAwaitingManualClose] = useState3(false);
|
|
1395
1449
|
const onSuccessRef = useRef3(onSuccess);
|
|
1396
1450
|
const onErrorRef = useRef3(onError);
|
|
1397
1451
|
useEffect3(() => {
|
|
@@ -1406,12 +1460,38 @@ function CallbackPage({ onSuccess, onError, renderError } = {}) {
|
|
|
1406
1460
|
targetOrigin = window.opener.location.origin;
|
|
1407
1461
|
} catch {
|
|
1408
1462
|
}
|
|
1409
|
-
|
|
1410
|
-
|
|
1411
|
-
|
|
1412
|
-
|
|
1463
|
+
const message = {
|
|
1464
|
+
type: "nihplod_sso_popup_callback",
|
|
1465
|
+
callbackUrl: window.location.href,
|
|
1466
|
+
nonce: nonce || void 0
|
|
1467
|
+
};
|
|
1468
|
+
let acked = false;
|
|
1469
|
+
const send = () => {
|
|
1470
|
+
if (acked || !window.opener || window.opener.closed) return;
|
|
1471
|
+
window.opener.postMessage(message, targetOrigin);
|
|
1472
|
+
};
|
|
1473
|
+
send();
|
|
1474
|
+
const resendTimer = setInterval(send, 500);
|
|
1475
|
+
const ackTimeout = setTimeout(() => {
|
|
1476
|
+
if (acked) return;
|
|
1477
|
+
clearInterval(resendTimer);
|
|
1478
|
+
setAwaitingManualClose(true);
|
|
1479
|
+
}, 1e4);
|
|
1480
|
+
const handleAck = (event) => {
|
|
1481
|
+
if (event.origin !== targetOrigin) return;
|
|
1482
|
+
if (!event.data || event.data.type !== "nihplod_sso_popup_ack") return;
|
|
1483
|
+
if (nonce && event.data.nonce !== nonce) return;
|
|
1484
|
+
acked = true;
|
|
1485
|
+
clearInterval(resendTimer);
|
|
1486
|
+
clearTimeout(ackTimeout);
|
|
1487
|
+
};
|
|
1488
|
+
window.addEventListener("message", handleAck);
|
|
1413
1489
|
Promise.resolve().then(() => setProcessing(false));
|
|
1414
|
-
return
|
|
1490
|
+
return () => {
|
|
1491
|
+
clearInterval(resendTimer);
|
|
1492
|
+
clearTimeout(ackTimeout);
|
|
1493
|
+
window.removeEventListener("message", handleAck);
|
|
1494
|
+
};
|
|
1415
1495
|
}
|
|
1416
1496
|
let cancelled = false;
|
|
1417
1497
|
async function handleCallback() {
|
|
@@ -1450,6 +1530,21 @@ function CallbackPage({ onSuccess, onError, renderError } = {}) {
|
|
|
1450
1530
|
if (renderError) return React3.createElement(React3.Fragment, null, renderError(error));
|
|
1451
1531
|
return React3.createElement(DefaultCallbackError, { error });
|
|
1452
1532
|
}
|
|
1533
|
+
if (awaitingManualClose) {
|
|
1534
|
+
return React3.createElement(
|
|
1535
|
+
"div",
|
|
1536
|
+
{
|
|
1537
|
+
style: {
|
|
1538
|
+
display: "flex",
|
|
1539
|
+
alignItems: "center",
|
|
1540
|
+
justifyContent: "center",
|
|
1541
|
+
minHeight: "100vh",
|
|
1542
|
+
fontFamily: "system-ui, sans-serif"
|
|
1543
|
+
}
|
|
1544
|
+
},
|
|
1545
|
+
React3.createElement("p", null, "\u767B\u5F55\u5DF2\u5B8C\u6210\uFF0C\u8BF7\u624B\u52A8\u5173\u95ED\u6B64\u7A97\u53E3")
|
|
1546
|
+
);
|
|
1547
|
+
}
|
|
1453
1548
|
if (processing) {
|
|
1454
1549
|
return React3.createElement(
|
|
1455
1550
|
"div",
|