@arcblock/did-connect-core 4.1.53 → 4.1.54
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/dist/ui/i18n.d.ts.map +1 -1
- package/dist/ui/i18n.js +32 -4
- package/dist/ui/i18n.js.map +1 -1
- package/dist/ui/index.bundle.js +300 -148
- package/dist/ui/login-dialog.d.ts.map +1 -1
- package/dist/ui/login-dialog.js +4 -0
- package/dist/ui/login-dialog.js.map +1 -1
- package/dist/ui/login-page.d.ts +4 -0
- package/dist/ui/login-page.d.ts.map +1 -1
- package/dist/ui/login-page.js +227 -138
- package/dist/ui/login-page.js.map +1 -1
- package/dist/ui/styles.d.ts.map +1 -1
- package/dist/ui/styles.js +36 -21
- package/dist/ui/styles.js.map +1 -1
- package/package.json +1 -1
package/dist/ui/index.bundle.js
CHANGED
|
@@ -381,12 +381,19 @@ var messages = {
|
|
|
381
381
|
emailExplanation: "We will send you a verification code. No password needed.",
|
|
382
382
|
otherMethods: "Other ways to sign in",
|
|
383
383
|
passkeyCreateAccount: "Create an account with Passkey",
|
|
384
|
-
lastUsed: "Last used
|
|
384
|
+
lastUsed: "Last used",
|
|
385
385
|
passkeyExplanation: "Create a new account using your fingerprint, face, or device unlock. Your device will ask you to save a Passkey. Already have an account? Go back to sign in.",
|
|
386
386
|
continueWith: "Continue with {provider}",
|
|
387
387
|
oauthWaiting: "Continue in the {provider} window",
|
|
388
388
|
oauthIncomplete: "Sign-in is not complete. Reopen the window or choose another method.",
|
|
389
389
|
oauthReopen: "Reopen window",
|
|
390
|
+
oauthUnconfirmed: "We could not confirm sign-in. Reload this page to check your session before trying again.",
|
|
391
|
+
oauthCheckSession: "Reload and check sign-in",
|
|
392
|
+
oauthCancelled: "Stopped waiting for sign-in. If the provider window is still open, close it before retrying.",
|
|
393
|
+
oauthDenied: "Authorization was declined. Try again or choose another sign-in method.",
|
|
394
|
+
oauthBlocked: "Your browser blocked the sign-in window. Reopen it or continue on this page.",
|
|
395
|
+
oauthTimedOut: "Sign-in timed out. Reopen the window to start again.",
|
|
396
|
+
oauthFailed: "We could not complete sign-in. Try again or choose another method.",
|
|
390
397
|
oauthFullPage: "Continue on this page",
|
|
391
398
|
emailEdit: "Change email",
|
|
392
399
|
emailCooldown: "Resend in {seconds}s",
|
|
@@ -447,12 +454,19 @@ var messages = {
|
|
|
447
454
|
emailExplanation: "\u6211\u4EEC\u4F1A\u53D1\u9001\u9A8C\u8BC1\u7801\uFF0C\u65E0\u9700\u5BC6\u7801\u3002",
|
|
448
455
|
otherMethods: "\u5176\u4ED6\u767B\u5F55\u65B9\u5F0F",
|
|
449
456
|
passkeyCreateAccount: "\u4F7F\u7528 Passkey \u521B\u5EFA\u8D26\u6237",
|
|
450
|
-
lastUsed: "\u4E0A\u6B21\u4F7F\u7528
|
|
457
|
+
lastUsed: "\u4E0A\u6B21\u4F7F\u7528",
|
|
451
458
|
passkeyExplanation: "\u4F7F\u7528\u6307\u7EB9\u3001\u9762\u5BB9\u6216\u8BBE\u5907\u89E3\u9501\u65B9\u5F0F\u521B\u5EFA\u65B0\u8D26\u6237\uFF0C\u65E0\u9700\u5BC6\u7801\u3002\u8BBE\u5907\u4F1A\u63D0\u793A\u4FDD\u5B58 Passkey\u3002\u5DF2\u6709\u8D26\u6237\uFF1F\u8BF7\u8FD4\u56DE\u767B\u5F55\u3002",
|
|
452
459
|
continueWith: "\u4F7F\u7528 {provider} \u7EE7\u7EED",
|
|
453
460
|
oauthWaiting: "\u8BF7\u5728 {provider} \u7A97\u53E3\u4E2D\u7EE7\u7EED",
|
|
454
461
|
oauthIncomplete: "\u767B\u5F55\u5C1A\u672A\u5B8C\u6210\u3002\u60A8\u53EF\u4EE5\u91CD\u65B0\u6253\u5F00\u7A97\u53E3\u6216\u9009\u62E9\u5176\u4ED6\u65B9\u5F0F\u3002",
|
|
455
462
|
oauthReopen: "\u91CD\u65B0\u6253\u5F00\u7A97\u53E3",
|
|
463
|
+
oauthUnconfirmed: "\u6682\u65F6\u65E0\u6CD5\u786E\u8BA4\u767B\u5F55\u7ED3\u679C\u3002\u8BF7\u5148\u91CD\u65B0\u52A0\u8F7D\u9875\u9762\u68C0\u67E5\u767B\u5F55\u72B6\u6001\uFF0C\u518D\u51B3\u5B9A\u662F\u5426\u91CD\u8BD5\u3002",
|
|
464
|
+
oauthCheckSession: "\u91CD\u65B0\u52A0\u8F7D\u5E76\u68C0\u67E5\u767B\u5F55\u72B6\u6001",
|
|
465
|
+
oauthCancelled: "\u5DF2\u505C\u6B62\u7B49\u5F85\u767B\u5F55\u3002\u82E5\u6388\u6743\u7A97\u53E3\u4ECD\u7136\u6253\u5F00\uFF0C\u8BF7\u5173\u95ED\u540E\u518D\u91CD\u8BD5\u3002",
|
|
466
|
+
oauthDenied: "\u60A8\u672A\u540C\u610F\u6388\u6743\u3002\u53EF\u4EE5\u91CD\u8BD5\u6216\u9009\u62E9\u5176\u4ED6\u767B\u5F55\u65B9\u5F0F\u3002",
|
|
467
|
+
oauthBlocked: "\u6D4F\u89C8\u5668\u62E6\u622A\u4E86\u767B\u5F55\u7A97\u53E3\u3002\u8BF7\u91CD\u65B0\u6253\u5F00\uFF0C\u6216\u5728\u5F53\u524D\u9875\u9762\u7EE7\u7EED\u3002",
|
|
468
|
+
oauthTimedOut: "\u767B\u5F55\u7B49\u5F85\u5DF2\u8D85\u65F6\u3002\u8BF7\u91CD\u65B0\u6253\u5F00\u7A97\u53E3\u518D\u8BD5\u3002",
|
|
469
|
+
oauthFailed: "\u672A\u80FD\u5B8C\u6210\u767B\u5F55\u3002\u8BF7\u91CD\u8BD5\u6216\u9009\u62E9\u5176\u4ED6\u65B9\u5F0F\u3002",
|
|
456
470
|
oauthFullPage: "\u5728\u5F53\u524D\u9875\u9762\u7EE7\u7EED",
|
|
457
471
|
emailEdit: "\u4FEE\u6539\u90AE\u7BB1",
|
|
458
472
|
emailCooldown: "{seconds} \u79D2\u540E\u91CD\u53D1",
|
|
@@ -513,12 +527,19 @@ var messages = {
|
|
|
513
527
|
emailExplanation: "\u6211\u5011\u6703\u50B3\u9001\u9A57\u8B49\u78BC\uFF0C\u7121\u9700\u5BC6\u78BC\u3002",
|
|
514
528
|
otherMethods: "\u5176\u4ED6\u767B\u5165\u65B9\u5F0F",
|
|
515
529
|
passkeyCreateAccount: "\u4F7F\u7528 Passkey \u5EFA\u7ACB\u5E33\u6236",
|
|
516
|
-
lastUsed: "\u4E0A\u6B21\u4F7F\u7528
|
|
530
|
+
lastUsed: "\u4E0A\u6B21\u4F7F\u7528",
|
|
517
531
|
passkeyExplanation: "\u4F7F\u7528\u6307\u7D0B\u3001\u9762\u5BB9\u6216\u88DD\u7F6E\u89E3\u9396\u65B9\u5F0F\u5EFA\u7ACB\u65B0\u5E33\u6236\uFF0C\u7121\u9700\u5BC6\u78BC\u3002\u88DD\u7F6E\u6703\u63D0\u793A\u5132\u5B58 Passkey\u3002\u5DF2\u6709\u5E33\u6236\uFF1F\u8ACB\u8FD4\u56DE\u767B\u5165\u3002",
|
|
518
532
|
continueWith: "\u4F7F\u7528 {provider} \u7E7C\u7E8C",
|
|
519
533
|
oauthWaiting: "\u8ACB\u5728 {provider} \u8996\u7A97\u4E2D\u7E7C\u7E8C",
|
|
520
534
|
oauthIncomplete: "\u767B\u5165\u5C1A\u672A\u5B8C\u6210\u3002\u60A8\u53EF\u4EE5\u91CD\u65B0\u958B\u555F\u8996\u7A97\u6216\u9078\u64C7\u5176\u4ED6\u65B9\u5F0F\u3002",
|
|
521
535
|
oauthReopen: "\u91CD\u65B0\u958B\u555F\u8996\u7A97",
|
|
536
|
+
oauthUnconfirmed: "\u66AB\u6642\u7121\u6CD5\u78BA\u8A8D\u767B\u5165\u7D50\u679C\u3002\u8ACB\u5148\u91CD\u65B0\u8F09\u5165\u9801\u9762\u6AA2\u67E5\u767B\u5165\u72C0\u614B\uFF0C\u518D\u6C7A\u5B9A\u662F\u5426\u91CD\u8A66\u3002",
|
|
537
|
+
oauthCheckSession: "\u91CD\u65B0\u8F09\u5165\u4E26\u6AA2\u67E5\u767B\u5165\u72C0\u614B",
|
|
538
|
+
oauthCancelled: "\u5DF2\u505C\u6B62\u7B49\u5F85\u767B\u5165\u3002\u82E5\u6388\u6B0A\u8996\u7A97\u4ECD\u7136\u958B\u555F\uFF0C\u8ACB\u95DC\u9589\u5F8C\u518D\u91CD\u8A66\u3002",
|
|
539
|
+
oauthDenied: "\u60A8\u672A\u540C\u610F\u6388\u6B0A\u3002\u53EF\u4EE5\u91CD\u8A66\u6216\u9078\u64C7\u5176\u4ED6\u767B\u5165\u65B9\u5F0F\u3002",
|
|
540
|
+
oauthBlocked: "\u700F\u89BD\u5668\u5C01\u9396\u4E86\u767B\u5165\u8996\u7A97\u3002\u8ACB\u91CD\u65B0\u958B\u555F\uFF0C\u6216\u5728\u76EE\u524D\u9801\u9762\u7E7C\u7E8C\u3002",
|
|
541
|
+
oauthTimedOut: "\u767B\u5165\u7B49\u5F85\u5DF2\u903E\u6642\u3002\u8ACB\u91CD\u65B0\u958B\u555F\u8996\u7A97\u518D\u8A66\u3002",
|
|
542
|
+
oauthFailed: "\u672A\u80FD\u5B8C\u6210\u767B\u5165\u3002\u8ACB\u91CD\u8A66\u6216\u9078\u64C7\u5176\u4ED6\u65B9\u5F0F\u3002",
|
|
522
543
|
oauthFullPage: "\u5728\u76EE\u524D\u9801\u9762\u7E7C\u7E8C",
|
|
523
544
|
emailEdit: "\u4FEE\u6539\u96FB\u5B50\u90F5\u4EF6",
|
|
524
545
|
emailCooldown: "{seconds} \u79D2\u5F8C\u91CD\u65B0\u50B3\u9001",
|
|
@@ -579,12 +600,19 @@ var messages = {
|
|
|
579
600
|
emailExplanation: "\u78BA\u8A8D\u30B3\u30FC\u30C9\u3092\u9001\u4FE1\u3057\u307E\u3059\u3002\u30D1\u30B9\u30EF\u30FC\u30C9\u306F\u4E0D\u8981\u3067\u3059\u3002",
|
|
580
601
|
otherMethods: "\u4ED6\u306E\u30ED\u30B0\u30A4\u30F3\u65B9\u6CD5",
|
|
581
602
|
passkeyCreateAccount: "Passkey \u3067\u30A2\u30AB\u30A6\u30F3\u30C8\u3092\u4F5C\u6210",
|
|
582
|
-
lastUsed: "\u524D\u56DE\
|
|
603
|
+
lastUsed: "\u524D\u56DE\u4F7F\u7528",
|
|
583
604
|
passkeyExplanation: "\u6307\u7D0B\u3001\u9854\u8A8D\u8A3C\u3001\u307E\u305F\u306F\u30C7\u30D0\u30A4\u30B9\u306E\u30ED\u30C3\u30AF\u89E3\u9664\u3067\u65B0\u3057\u3044\u30A2\u30AB\u30A6\u30F3\u30C8\u3092\u4F5C\u6210\u3057\u307E\u3059\u3002\u30D1\u30B9\u30EF\u30FC\u30C9\u306F\u4E0D\u8981\u3067\u3059\u3002\u30C7\u30D0\u30A4\u30B9\u304C Passkey \u306E\u4FDD\u5B58\u3092\u6C42\u3081\u307E\u3059\u3002\u30A2\u30AB\u30A6\u30F3\u30C8\u3092\u304A\u6301\u3061\u3067\u3059\u304B\uFF1F\u30ED\u30B0\u30A4\u30F3\u306B\u623B\u3063\u3066\u304F\u3060\u3055\u3044\u3002",
|
|
584
605
|
continueWith: "{provider} \u3067\u7D9A\u3051\u308B",
|
|
585
606
|
oauthWaiting: "{provider} \u306E\u30A6\u30A3\u30F3\u30C9\u30A6\u3067\u7D9A\u3051\u3066\u304F\u3060\u3055\u3044",
|
|
586
607
|
oauthIncomplete: "\u30ED\u30B0\u30A4\u30F3\u306F\u307E\u3060\u5B8C\u4E86\u3057\u3066\u3044\u307E\u305B\u3093\u3002\u30A6\u30A3\u30F3\u30C9\u30A6\u3092\u958B\u304D\u76F4\u3059\u304B\u3001\u5225\u306E\u65B9\u6CD5\u3092\u9078\u3093\u3067\u304F\u3060\u3055\u3044\u3002",
|
|
587
608
|
oauthReopen: "\u30A6\u30A3\u30F3\u30C9\u30A6\u3092\u958B\u304D\u76F4\u3059",
|
|
609
|
+
oauthUnconfirmed: "\u30ED\u30B0\u30A4\u30F3\u7D50\u679C\u3092\u78BA\u8A8D\u3067\u304D\u307E\u305B\u3093\u3067\u3057\u305F\u3002\u518D\u8A66\u884C\u306E\u524D\u306B\u30DA\u30FC\u30B8\u3092\u518D\u8AAD\u307F\u8FBC\u307F\u3057\u3066\u72B6\u614B\u3092\u78BA\u8A8D\u3057\u3066\u304F\u3060\u3055\u3044\u3002",
|
|
610
|
+
oauthCheckSession: "\u518D\u8AAD\u307F\u8FBC\u307F\u3057\u3066\u30ED\u30B0\u30A4\u30F3\u3092\u78BA\u8A8D",
|
|
611
|
+
oauthCancelled: "\u30ED\u30B0\u30A4\u30F3\u306E\u5F85\u6A5F\u3092\u7D42\u4E86\u3057\u307E\u3057\u305F\u3002\u8A8D\u8A3C\u30A6\u30A3\u30F3\u30C9\u30A6\u304C\u958B\u3044\u3066\u3044\u308B\u5834\u5408\u306F\u3001\u9589\u3058\u3066\u304B\u3089\u518D\u8A66\u884C\u3057\u3066\u304F\u3060\u3055\u3044\u3002",
|
|
612
|
+
oauthDenied: "\u8A8D\u8A3C\u304C\u8A31\u53EF\u3055\u308C\u307E\u305B\u3093\u3067\u3057\u305F\u3002\u518D\u8A66\u884C\u3059\u308B\u304B\u3001\u5225\u306E\u65B9\u6CD5\u3092\u9078\u3093\u3067\u304F\u3060\u3055\u3044\u3002",
|
|
613
|
+
oauthBlocked: "\u30D6\u30E9\u30A6\u30B6\u304C\u30ED\u30B0\u30A4\u30F3\u753B\u9762\u3092\u30D6\u30ED\u30C3\u30AF\u3057\u307E\u3057\u305F\u3002\u958B\u304D\u76F4\u3059\u304B\u3001\u3053\u306E\u30DA\u30FC\u30B8\u3067\u7D9A\u3051\u3066\u304F\u3060\u3055\u3044\u3002",
|
|
614
|
+
oauthTimedOut: "\u30ED\u30B0\u30A4\u30F3\u304C\u30BF\u30A4\u30E0\u30A2\u30A6\u30C8\u3057\u307E\u3057\u305F\u3002\u30A6\u30A3\u30F3\u30C9\u30A6\u3092\u958B\u304D\u76F4\u3057\u3066\u304F\u3060\u3055\u3044\u3002",
|
|
615
|
+
oauthFailed: "\u30ED\u30B0\u30A4\u30F3\u3092\u5B8C\u4E86\u3067\u304D\u307E\u305B\u3093\u3067\u3057\u305F\u3002\u518D\u8A66\u884C\u3059\u308B\u304B\u3001\u5225\u306E\u65B9\u6CD5\u3092\u9078\u3093\u3067\u304F\u3060\u3055\u3044\u3002",
|
|
588
616
|
oauthFullPage: "\u3053\u306E\u30DA\u30FC\u30B8\u3067\u7D9A\u3051\u308B",
|
|
589
617
|
emailEdit: "\u30E1\u30FC\u30EB\u30A2\u30C9\u30EC\u30B9\u3092\u5909\u66F4",
|
|
590
618
|
emailCooldown: "{seconds} \u79D2\u5F8C\u306B\u518D\u9001\u4FE1",
|
|
@@ -2980,28 +3008,41 @@ h1 {
|
|
|
2980
3008
|
border-color: var(--border-strong);
|
|
2981
3009
|
}
|
|
2982
3010
|
.locale-trigger svg { width: 14px; height: 14px; flex-shrink: 0; }
|
|
3011
|
+
/* One compact menu surface; rows are choices, not nested pill buttons. */
|
|
2983
3012
|
.locale-menu {
|
|
2984
|
-
display: none;
|
|
2985
|
-
|
|
2986
|
-
|
|
2987
|
-
|
|
2988
|
-
margin-top: 4px;
|
|
3013
|
+
display: none; position: absolute; top: calc(100% + 6px); right: 0; z-index: 4;
|
|
3014
|
+
min-width: 144px; width: max-content; max-width: min(240px,calc(100vw - 64px));
|
|
3015
|
+
padding: 4px; background: var(--bg-card); border: 1px solid var(--border);
|
|
3016
|
+
border-radius: 10px; box-shadow: var(--shadow-lg);
|
|
2989
3017
|
}
|
|
2990
|
-
.locale-switcher.open .locale-menu {
|
|
2991
|
-
|
|
3018
|
+
.locale-switcher.open .locale-menu { display: flex; flex-direction: column; }
|
|
3019
|
+
.locale-menu .locale-btn {
|
|
3020
|
+
width: 100%; min-height: 36px; height: auto; padding: 7px 10px; gap: 8px;
|
|
3021
|
+
border: 0; border-radius: 6px; background: transparent; text-align: left;
|
|
3022
|
+
font-size: 13px; line-height: 1.4; overflow-wrap: anywhere;
|
|
2992
3023
|
}
|
|
2993
|
-
.locale-btn
|
|
2994
|
-
|
|
2995
|
-
|
|
2996
|
-
}
|
|
2997
|
-
.
|
|
3024
|
+
.locale-menu .locale-btn:hover, .locale-menu .locale-btn:focus-visible { background: var(--bg-hover); color: var(--text); }
|
|
3025
|
+
.locale-menu .locale-btn[aria-checked="true"] { color: var(--text); font-weight: 600; }
|
|
3026
|
+
.locale-check { width: 14px; flex: 0 0 14px; font-size: 12px; line-height: 1; }
|
|
3027
|
+
@media (pointer: coarse) { .locale-menu .locale-btn { min-height: 44px; } }
|
|
3028
|
+
.has-last-used { flex-wrap: wrap; }
|
|
3029
|
+
.last-used { display: inline-block; font-size: 11px; font-weight: 400; line-height: 1.4;
|
|
3030
|
+
padding: 2px 6px; border: 1px solid currentColor; border-radius: 4px; opacity: .72; white-space: nowrap; }
|
|
2998
3031
|
.card { position: relative; }
|
|
2999
3032
|
|
|
3000
3033
|
/* Long localized method labels remain readable on narrow screens. */
|
|
3001
3034
|
.methods-grid { grid-template-columns: 1fr; }
|
|
3002
3035
|
.method-btn { min-height: 48px; white-space: normal; }
|
|
3003
3036
|
.passkey-alt { min-height: 44px; font-weight: 600; }
|
|
3004
|
-
.oauth-recovery { font-size: 14px; line-height: 1.5; margin: 12px 0;
|
|
3037
|
+
.oauth-recovery { font-size: 14px; line-height: 1.5; margin: 12px 0; padding: 12px;
|
|
3038
|
+
border: 1px solid var(--border); border-radius: var(--radius); color: var(--text-secondary); text-align: left; }
|
|
3039
|
+
.oauth-recovery p { margin: 0 0 8px; overflow-wrap: anywhere; }
|
|
3040
|
+
.oauth-recovery-actions { display: flex; flex-wrap: wrap; gap: 4px 12px; align-items: center; }
|
|
3041
|
+
.oauth-recovery-actions button, .oauth-recovery-actions a { font: inherit; font-size: 13px; min-height: 44px;
|
|
3042
|
+
display: inline-flex; align-items: center; padding: 4px 0; color: var(--text); border: 0; background: none; cursor: pointer; text-decoration: underline; text-underline-offset: 3px; }
|
|
3043
|
+
.oauth-recovery-actions[hidden], .oauth-recovery-actions [hidden] { display: none; }
|
|
3044
|
+
.oauth-recovery-actions :focus-visible { outline: 2px solid var(--blue); outline-offset: 3px; }
|
|
3045
|
+
|
|
3005
3046
|
@media (max-width: 480px) { .card { padding: 24px 20px; width: 100%; box-sizing: border-box; } h1 { font-size: 24px; } }
|
|
3006
3047
|
|
|
3007
3048
|
.passkey-create-entry { display: flex; justify-content: center; align-items: center; width: 100%; box-sizing: border-box; border: 1px solid var(--border); border-radius: var(--radius); background: var(--bg-surface); color: var(--text); padding: 10px 14px; }
|
|
@@ -3014,11 +3055,7 @@ h1 {
|
|
|
3014
3055
|
.card-modal .locale-switcher { min-width: 0; max-width: 100%; }
|
|
3015
3056
|
.card-modal .locale-trigger { max-width: 100%; height: 36px; }
|
|
3016
3057
|
.locale-label { min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
|
|
3017
|
-
.card-modal .locale-menu {
|
|
3018
|
-
width: max-content; max-width: min(260px,calc(100vw - 80px)); padding: 6px;
|
|
3019
|
-
background: var(--bg-card); border: 1px solid var(--border-strong); border-radius: 10px; box-shadow: var(--shadow-lg); }
|
|
3020
|
-
.card-modal .locale-menu .locale-btn { min-height: 40px; height: auto; text-align: left; border-radius: 6px; }
|
|
3021
|
-
.card-modal .locale-menu .locale-btn span { overflow-wrap: anywhere; }
|
|
3058
|
+
.card-modal .locale-menu { left: 0; right: auto; }
|
|
3022
3059
|
|
|
3023
3060
|
.card { padding: 52px 24px 24px; box-sizing: border-box; }
|
|
3024
3061
|
.card-modal { width: 100%; }
|
|
@@ -3027,7 +3064,13 @@ h1 {
|
|
|
3027
3064
|
.card.card-modal, :host([data-theme="light"]) .card.card-modal { box-shadow: none; }
|
|
3028
3065
|
/* A translateY entrance expands an auto scroller by 4px until it finishes. */
|
|
3029
3066
|
.card-modal[data-view] { animation: none; }
|
|
3030
|
-
|
|
3067
|
+
/* Sub-step navigation shares the close button's center line in both modes. */
|
|
3068
|
+
.back-btn { top: 8px; left: 24px; height: 44px; max-width: calc(100% - 160px); line-height: 1.4; text-align: left; }
|
|
3069
|
+
.back-btn:focus-visible { outline: 2px solid var(--blue); outline-offset: 2px; border-radius: 4px; }
|
|
3070
|
+
.card-modal .back-btn { position: absolute; top: 8px; left: 24px; margin: 0; }
|
|
3071
|
+
.card-modal:has(.back-btn) .card-tools { left: auto; right: 64px; max-width: calc(100% - 160px); }
|
|
3072
|
+
.passkey-creating > .home-link { display: none; }
|
|
3073
|
+
@media (max-width:480px) { .back-btn, .card-modal .back-btn { left: 18px; } }
|
|
3031
3074
|
.card-modal h1 { display: block; overflow: visible; -webkit-line-clamp: unset; line-clamp: unset; line-height: 1.4; padding-block: 2px; }
|
|
3032
3075
|
.card-modal h1[tabindex="-1"]:focus { outline: none; }
|
|
3033
3076
|
.card-modal h1, .card-modal h2, .card-modal .subtitle, .card-modal .status { overflow-wrap: anywhere; }
|
|
@@ -3474,6 +3517,8 @@ var LoginPage = class {
|
|
|
3474
3517
|
}
|
|
3475
3518
|
/** Locale sits on the card's top-right row, level with Back / Cancel. */
|
|
3476
3519
|
renderCardTools(card) {
|
|
3520
|
+
if (!(this.options.showLocaleSelector ?? this.options.mode !== "dialog"))
|
|
3521
|
+
return;
|
|
3477
3522
|
const tools = document.createElement("div");
|
|
3478
3523
|
tools.className = "card-tools";
|
|
3479
3524
|
this.renderLocaleSwitcher(tools);
|
|
@@ -3531,6 +3576,8 @@ var LoginPage = class {
|
|
|
3531
3576
|
trigger.addEventListener("click", (event) => {
|
|
3532
3577
|
event.stopPropagation();
|
|
3533
3578
|
setOpen(menu.hidden);
|
|
3579
|
+
if (!menu.hidden)
|
|
3580
|
+
menu.querySelector('[aria-checked="true"]')?.focus();
|
|
3534
3581
|
});
|
|
3535
3582
|
for (const item of locales) {
|
|
3536
3583
|
const checked = item.code === current.code;
|
|
@@ -3540,12 +3587,13 @@ var LoginPage = class {
|
|
|
3540
3587
|
btn.setAttribute("role", "menuitemradio");
|
|
3541
3588
|
btn.setAttribute("aria-checked", checked ? "true" : "false");
|
|
3542
3589
|
btn.dataset.locale = item.code;
|
|
3590
|
+
btn.tabIndex = -1;
|
|
3543
3591
|
btn.title = item.label;
|
|
3544
|
-
|
|
3592
|
+
{
|
|
3545
3593
|
const mark = document.createElement("span");
|
|
3546
3594
|
mark.className = "locale-check";
|
|
3547
3595
|
mark.setAttribute("aria-hidden", "true");
|
|
3548
|
-
mark.textContent = "\u2713";
|
|
3596
|
+
mark.textContent = checked ? "\u2713" : "";
|
|
3549
3597
|
btn.appendChild(mark);
|
|
3550
3598
|
}
|
|
3551
3599
|
const label = document.createElement("span");
|
|
@@ -3557,6 +3605,24 @@ var LoginPage = class {
|
|
|
3557
3605
|
});
|
|
3558
3606
|
menu.appendChild(btn);
|
|
3559
3607
|
}
|
|
3608
|
+
wrapper.addEventListener("keydown", (event) => {
|
|
3609
|
+
const items = [...menu.querySelectorAll(".locale-btn")];
|
|
3610
|
+
const active = this.shadow?.activeElement ?? document.activeElement;
|
|
3611
|
+
const index = items.indexOf(active);
|
|
3612
|
+
if (event.key === "Escape") {
|
|
3613
|
+
event.preventDefault();
|
|
3614
|
+
event.stopPropagation();
|
|
3615
|
+
setOpen(false);
|
|
3616
|
+
trigger.focus();
|
|
3617
|
+
} else if (event.key === "Tab")
|
|
3618
|
+
setOpen(false);
|
|
3619
|
+
else if (["ArrowDown", "ArrowUp", "Home", "End"].includes(event.key)) {
|
|
3620
|
+
event.preventDefault();
|
|
3621
|
+
setOpen(true);
|
|
3622
|
+
const next = event.key === "Home" ? 0 : event.key === "End" ? items.length - 1 : index < 0 ? event.key === "ArrowUp" ? items.length - 1 : 0 : (index + (event.key === "ArrowUp" ? -1 : 1) + items.length) % items.length;
|
|
3623
|
+
items[next]?.focus();
|
|
3624
|
+
}
|
|
3625
|
+
});
|
|
3560
3626
|
const onOutsideClick = (event) => {
|
|
3561
3627
|
const path = event.composedPath();
|
|
3562
3628
|
if (path.includes(wrapper))
|
|
@@ -3607,25 +3673,25 @@ var LoginPage = class {
|
|
|
3607
3673
|
break;
|
|
3608
3674
|
}
|
|
3609
3675
|
}
|
|
3676
|
+
/** Keep recognition next to the action, without a second page subtitle. */
|
|
3677
|
+
markLastUsed(button, method, locale) {
|
|
3678
|
+
if (!this.options.preferenceKey)
|
|
3679
|
+
return;
|
|
3680
|
+
try {
|
|
3681
|
+
if (localStorage.getItem(`did-login-method:${this.options.preferenceKey}`) !== method)
|
|
3682
|
+
return;
|
|
3683
|
+
const hint = document.createElement("span");
|
|
3684
|
+
hint.className = "last-used";
|
|
3685
|
+
hint.textContent = t("lastUsed", locale);
|
|
3686
|
+
button.classList.add("has-last-used");
|
|
3687
|
+
button.appendChild(hint);
|
|
3688
|
+
} catch {
|
|
3689
|
+
}
|
|
3690
|
+
}
|
|
3610
3691
|
renderMethodsView(card, locale, methods) {
|
|
3611
3692
|
if (this.options.mode !== "dialog")
|
|
3612
3693
|
this.renderHomeLink(card, locale);
|
|
3613
3694
|
this.renderBrandHeader(card, locale);
|
|
3614
|
-
if (this.options.preferenceKey) {
|
|
3615
|
-
try {
|
|
3616
|
-
const last = localStorage.getItem(`did-login-method:${this.options.preferenceKey}`);
|
|
3617
|
-
const labels = { passkey: "Passkey", oauth: "OAuth", email: t("emailButton", locale), "did-connect": "DID Wallet" };
|
|
3618
|
-
const provider = last?.startsWith("oauth:") ? this.options.oauthProviders?.find((p) => p.enabled && `oauth:${p.id}` === last) : void 0;
|
|
3619
|
-
const label = provider?.name ?? (last ? labels[last] : void 0);
|
|
3620
|
-
if (last && label && (methods.includes(last) || provider && methods.includes("oauth"))) {
|
|
3621
|
-
const hint = document.createElement("p");
|
|
3622
|
-
hint.className = "subtitle";
|
|
3623
|
-
hint.textContent = t("lastUsed", locale, { method: label });
|
|
3624
|
-
card.appendChild(hint);
|
|
3625
|
-
}
|
|
3626
|
-
} catch {
|
|
3627
|
-
}
|
|
3628
|
-
}
|
|
3629
3695
|
const requestedPasskey = this.options.methods.includes("passkey");
|
|
3630
3696
|
if (requestedPasskey && !methods.includes("passkey")) {
|
|
3631
3697
|
const warn = document.createElement("div");
|
|
@@ -3895,11 +3961,12 @@ var LoginPage = class {
|
|
|
3895
3961
|
}
|
|
3896
3962
|
});
|
|
3897
3963
|
}
|
|
3898
|
-
renderBackButton(parent, locale) {
|
|
3964
|
+
renderBackButton(parent, locale, onBack = () => this.switchView("methods")) {
|
|
3899
3965
|
const btn = document.createElement("button");
|
|
3966
|
+
btn.type = "button";
|
|
3900
3967
|
btn.className = "back-btn";
|
|
3901
3968
|
btn.innerHTML = `${ICON_BACK_ARROW} ${escapeHtml(t("back", locale))}`;
|
|
3902
|
-
btn.addEventListener("click",
|
|
3969
|
+
btn.addEventListener("click", onBack);
|
|
3903
3970
|
parent.appendChild(btn);
|
|
3904
3971
|
}
|
|
3905
3972
|
/**
|
|
@@ -4107,11 +4174,8 @@ var LoginPage = class {
|
|
|
4107
4174
|
createBtn.id = "passkey-btn";
|
|
4108
4175
|
createBtn.innerHTML = `${ICON_PASSKEY} ${escapeHtml(t("passkeyCreate", locale))}`;
|
|
4109
4176
|
section.appendChild(createBtn);
|
|
4110
|
-
|
|
4111
|
-
|
|
4112
|
-
backLink.className = "passkey-alt";
|
|
4113
|
-
backLink.textContent = t("passkeyBackToSignIn", locale);
|
|
4114
|
-
section.appendChild(backLink);
|
|
4177
|
+
parent.querySelector(".back-btn")?.remove();
|
|
4178
|
+
this.renderBackButton(parent, locale, () => renderSignInState());
|
|
4115
4179
|
const doCreate = async () => {
|
|
4116
4180
|
if (createBtn.disabled)
|
|
4117
4181
|
return;
|
|
@@ -4141,7 +4205,6 @@ var LoginPage = class {
|
|
|
4141
4205
|
if (e.key === "Enter")
|
|
4142
4206
|
doCreate();
|
|
4143
4207
|
});
|
|
4144
|
-
backLink.addEventListener("click", () => renderSignInState());
|
|
4145
4208
|
createBtn.focus();
|
|
4146
4209
|
};
|
|
4147
4210
|
const doSignIn = async () => {
|
|
@@ -4176,6 +4239,7 @@ var LoginPage = class {
|
|
|
4176
4239
|
};
|
|
4177
4240
|
const renderSignInState = () => {
|
|
4178
4241
|
this.cardEl?.classList.remove("passkey-creating");
|
|
4242
|
+
parent.querySelector(".back-btn")?.remove();
|
|
4179
4243
|
this.abort?.abort();
|
|
4180
4244
|
this.generation++;
|
|
4181
4245
|
const heading = this.cardEl?.querySelector("h1");
|
|
@@ -4187,6 +4251,7 @@ var LoginPage = class {
|
|
|
4187
4251
|
signInBtn.className = this.cardEl?.classList.contains("social-first") ? "btn btn-secondary" : "btn";
|
|
4188
4252
|
signInBtn.id = "passkey-btn";
|
|
4189
4253
|
signInBtn.innerHTML = `${ICON_PASSKEY} ${escapeHtml(t("passkeySignIn", locale))}`;
|
|
4254
|
+
this.markLastUsed(signInBtn, "passkey", locale);
|
|
4190
4255
|
section.appendChild(signInBtn);
|
|
4191
4256
|
signInBtn.addEventListener("click", () => doSignIn());
|
|
4192
4257
|
const createLink = document.createElement("button");
|
|
@@ -4208,159 +4273,240 @@ var LoginPage = class {
|
|
|
4208
4273
|
startOAuthPopup(providerId, btn) {
|
|
4209
4274
|
this.oauthCleanup?.();
|
|
4210
4275
|
const epoch = this.generation;
|
|
4276
|
+
const locale = this.options.locale;
|
|
4211
4277
|
const servicePrefix = this.config.servicePrefix ?? "/.well-known/service";
|
|
4212
4278
|
const oauthBase = this.options.masterOAuthOrigin ? `${this.options.masterOAuthOrigin}${servicePrefix}` : servicePrefix;
|
|
4213
4279
|
const oauthOrigin = new URL(oauthBase, window.location.href).origin;
|
|
4214
|
-
|
|
4215
|
-
|
|
4216
|
-
|
|
4217
|
-
|
|
4218
|
-
|
|
4219
|
-
|
|
4220
|
-
|
|
4221
|
-
|
|
4222
|
-
|
|
4223
|
-
return;
|
|
4280
|
+
let returnUrl = window.location.href;
|
|
4281
|
+
if (this.options.mode !== "dialog" && window.location.pathname === `${servicePrefix}/login`) {
|
|
4282
|
+
const requested = new URLSearchParams(window.location.search).get("return_to");
|
|
4283
|
+
try {
|
|
4284
|
+
const target = new URL(requested || "/", window.location.origin);
|
|
4285
|
+
returnUrl = target.origin === window.location.origin && !/^\/[/\\]/.test(target.pathname) ? target.href : `${window.location.origin}/`;
|
|
4286
|
+
} catch {
|
|
4287
|
+
returnUrl = `${window.location.origin}/`;
|
|
4288
|
+
}
|
|
4224
4289
|
}
|
|
4290
|
+
const loginUrl = `${oauthBase}/api/oauth/${encodeURIComponent(providerId)}/login?returnUrl=${encodeURIComponent(returnUrl)}`;
|
|
4291
|
+
const provider = this.options.oauthProviders?.find((p) => p.id === providerId)?.name ?? providerId;
|
|
4225
4292
|
const originalHTML = btn.innerHTML;
|
|
4226
|
-
|
|
4227
|
-
|
|
4228
|
-
|
|
4293
|
+
let popup = null;
|
|
4294
|
+
let settled = false;
|
|
4295
|
+
let exchanging = false;
|
|
4296
|
+
let probing = false;
|
|
4297
|
+
let pollTimer;
|
|
4298
|
+
let sessionTimer;
|
|
4299
|
+
let abandonTimer;
|
|
4300
|
+
const current = () => !settled && this.mounted && epoch === this.generation;
|
|
4301
|
+
const locked = [];
|
|
4302
|
+
const lockMethods = () => {
|
|
4303
|
+
for (const button of this.cardEl?.querySelectorAll(".method-btn, .passkey-create-entry, #passkey-btn, .locale-trigger, .locale-btn") ?? []) {
|
|
4304
|
+
locked.push({ button, disabled: button.disabled });
|
|
4305
|
+
button.disabled = true;
|
|
4306
|
+
}
|
|
4307
|
+
};
|
|
4229
4308
|
const recovery = document.createElement("div");
|
|
4230
4309
|
recovery.className = "oauth-recovery";
|
|
4231
4310
|
recovery.setAttribute("role", "status");
|
|
4232
4311
|
const hint = document.createElement("p");
|
|
4233
|
-
|
|
4312
|
+
const actions = document.createElement("div");
|
|
4313
|
+
actions.className = "oauth-recovery-actions";
|
|
4314
|
+
const reopen = document.createElement("button");
|
|
4315
|
+
reopen.type = "button";
|
|
4316
|
+
reopen.className = "oauth-retry";
|
|
4317
|
+
reopen.textContent = t("oauthReopen", locale);
|
|
4318
|
+
reopen.hidden = true;
|
|
4319
|
+
reopen.onclick = () => {
|
|
4320
|
+
this.select("oauth");
|
|
4321
|
+
this.activeProvider = providerId;
|
|
4322
|
+
this.startOAuthPopup(providerId, btn);
|
|
4323
|
+
};
|
|
4234
4324
|
const fullPage = document.createElement("a");
|
|
4235
4325
|
fullPage.href = loginUrl;
|
|
4236
|
-
fullPage.textContent = t("oauthFullPage",
|
|
4237
|
-
fullPage.addEventListener("click", () => {
|
|
4326
|
+
fullPage.textContent = t("oauthFullPage", locale);
|
|
4327
|
+
fullPage.addEventListener("click", (event) => {
|
|
4328
|
+
const reconcile = recovery.dataset.state === "oauthUnconfirmed";
|
|
4329
|
+
if (exchanging && !settled) {
|
|
4330
|
+
event.preventDefault();
|
|
4331
|
+
return;
|
|
4332
|
+
}
|
|
4333
|
+
if (reconcile)
|
|
4334
|
+
event.preventDefault();
|
|
4238
4335
|
this.options.onBeforeRedirect?.();
|
|
4239
4336
|
this.oauthCleanup?.();
|
|
4337
|
+
if (reconcile)
|
|
4338
|
+
window.location.reload();
|
|
4240
4339
|
});
|
|
4241
|
-
|
|
4242
|
-
|
|
4340
|
+
const cancel = document.createElement("button");
|
|
4341
|
+
cancel.type = "button";
|
|
4342
|
+
cancel.className = "oauth-cancel";
|
|
4343
|
+
cancel.textContent = t("cancel", locale);
|
|
4344
|
+
actions.append(reopen, fullPage, cancel);
|
|
4345
|
+
recovery.append(hint, actions);
|
|
4243
4346
|
btn.parentElement?.after(recovery);
|
|
4244
|
-
const
|
|
4245
|
-
recovery.hidden = false;
|
|
4246
|
-
this.emit("incomplete");
|
|
4347
|
+
const restoreButton = () => {
|
|
4247
4348
|
btn.innerHTML = originalHTML;
|
|
4248
4349
|
btn.disabled = false;
|
|
4249
4350
|
btn.classList.remove("oauth-btn-loading");
|
|
4250
4351
|
};
|
|
4251
|
-
|
|
4252
|
-
|
|
4352
|
+
const closePopup = () => {
|
|
4353
|
+
try {
|
|
4354
|
+
popup?.close();
|
|
4355
|
+
} catch {
|
|
4356
|
+
}
|
|
4357
|
+
};
|
|
4358
|
+
const cleanup = () => {
|
|
4359
|
+
settled = true;
|
|
4360
|
+
clearInterval(pollTimer);
|
|
4361
|
+
clearInterval(sessionTimer);
|
|
4362
|
+
clearTimeout(abandonTimer);
|
|
4363
|
+
window.removeEventListener("message", onMessage);
|
|
4364
|
+
for (const item of locked.splice(0))
|
|
4365
|
+
item.button.disabled = item.disabled;
|
|
4366
|
+
restoreButton();
|
|
4367
|
+
};
|
|
4368
|
+
const showRecovery = (key) => {
|
|
4369
|
+
hint.textContent = t(key, locale, { provider });
|
|
4370
|
+
recovery.dataset.state = key;
|
|
4371
|
+
actions.hidden = false;
|
|
4372
|
+
reopen.hidden = false;
|
|
4373
|
+
cancel.hidden = true;
|
|
4374
|
+
restoreButton();
|
|
4375
|
+
};
|
|
4376
|
+
const fail = (key) => {
|
|
4377
|
+
if (!current())
|
|
4378
|
+
return;
|
|
4379
|
+
cleanup();
|
|
4380
|
+
closePopup();
|
|
4381
|
+
showRecovery(key);
|
|
4382
|
+
this.emit("incomplete");
|
|
4383
|
+
};
|
|
4253
4384
|
const succeed = () => {
|
|
4254
|
-
if (
|
|
4385
|
+
if (!current())
|
|
4255
4386
|
return;
|
|
4256
|
-
settled = true;
|
|
4257
4387
|
cleanup();
|
|
4258
|
-
|
|
4388
|
+
closePopup();
|
|
4389
|
+
recovery.remove();
|
|
4390
|
+
btn.textContent = t("success", locale);
|
|
4391
|
+
btn.disabled = true;
|
|
4259
4392
|
this.handleSuccess();
|
|
4260
4393
|
};
|
|
4261
|
-
|
|
4262
|
-
if (
|
|
4394
|
+
cancel.onclick = () => {
|
|
4395
|
+
if (exchanging)
|
|
4263
4396
|
return;
|
|
4264
|
-
|
|
4397
|
+
fail("oauthCancelled");
|
|
4398
|
+
btn.focus();
|
|
4399
|
+
};
|
|
4400
|
+
const onMessage = async (event) => {
|
|
4401
|
+
if (event.origin !== oauthOrigin || event.source !== popup || !popup)
|
|
4265
4402
|
return;
|
|
4266
|
-
if (
|
|
4403
|
+
if (!event.data || event.data.type !== "authorization_response" || !current() || exchanging)
|
|
4267
4404
|
return;
|
|
4268
|
-
|
|
4269
|
-
|
|
4270
|
-
pollTimer = void 0;
|
|
4271
|
-
}
|
|
4272
|
-
try {
|
|
4273
|
-
popup.close();
|
|
4274
|
-
} catch {
|
|
4275
|
-
}
|
|
4405
|
+
clearInterval(pollTimer);
|
|
4406
|
+
clearInterval(sessionTimer);
|
|
4276
4407
|
if (event.data.error) {
|
|
4277
|
-
|
|
4278
|
-
cleanup();
|
|
4408
|
+
fail(event.data.error === "access_denied" ? "oauthDenied" : event.data.error === "cancelled" ? "oauthCancelled" : "oauthFailed");
|
|
4279
4409
|
return;
|
|
4280
4410
|
}
|
|
4281
4411
|
const { code, state } = event.data.response ?? event.data;
|
|
4282
|
-
if (!code) {
|
|
4283
|
-
|
|
4284
|
-
cleanup();
|
|
4412
|
+
if (typeof code !== "string" || !code || typeof state !== "string" || !state) {
|
|
4413
|
+
fail("oauthFailed");
|
|
4285
4414
|
return;
|
|
4286
4415
|
}
|
|
4287
|
-
|
|
4416
|
+
exchanging = true;
|
|
4417
|
+
lockMethods();
|
|
4418
|
+
actions.hidden = true;
|
|
4419
|
+
closePopup();
|
|
4420
|
+
hint.textContent = t("verifying", locale);
|
|
4421
|
+
btn.textContent = t("verifying", locale);
|
|
4288
4422
|
btn.disabled = true;
|
|
4289
4423
|
try {
|
|
4290
4424
|
const oauthBody = { provider: providerId, code, state };
|
|
4291
4425
|
if (this.options.invitationId)
|
|
4292
4426
|
oauthBody.invitationId = this.options.invitationId;
|
|
4293
|
-
await this.http.post(`${servicePrefix}/api/oauth/login`, oauthBody);
|
|
4427
|
+
await this.http.post(`${servicePrefix}/api/oauth/login`, oauthBody, { signal: this.abort?.signal });
|
|
4294
4428
|
succeed();
|
|
4295
|
-
} catch (
|
|
4296
|
-
if (
|
|
4429
|
+
} catch (err) {
|
|
4430
|
+
if (!current())
|
|
4297
4431
|
return;
|
|
4298
|
-
const
|
|
4299
|
-
const
|
|
4300
|
-
if (
|
|
4301
|
-
settled = true;
|
|
4432
|
+
const code2 = err instanceof Error && "code" in err ? String(err.code) : "";
|
|
4433
|
+
const message = err instanceof Error ? err.message : "";
|
|
4434
|
+
if (code2 === "FORBIDDEN" || code2 === "registration_closed" || message === "registration_closed") {
|
|
4302
4435
|
cleanup();
|
|
4303
|
-
|
|
4304
|
-
|
|
4305
|
-
|
|
4306
|
-
|
|
4436
|
+
recovery.remove();
|
|
4437
|
+
this.showFullError(friendlyError(err, locale));
|
|
4438
|
+
} else
|
|
4439
|
+
fail("oauthFailed");
|
|
4307
4440
|
}
|
|
4308
4441
|
};
|
|
4309
|
-
|
|
4442
|
+
this.oauthCleanup = () => {
|
|
4443
|
+
cleanup();
|
|
4444
|
+
recovery.remove();
|
|
4445
|
+
closePopup();
|
|
4446
|
+
};
|
|
4447
|
+
window.addEventListener("message", onMessage);
|
|
4448
|
+
try {
|
|
4449
|
+
popup = window.open(loginUrl, "oauth-login:popup", `left=${window.screenX + (window.innerWidth - 500) / 2},top=${window.screenY + (window.innerHeight - 620) / 2},width=500,height=620,resizable,scrollbars=yes,status=1,popup`);
|
|
4450
|
+
} catch {
|
|
4451
|
+
}
|
|
4452
|
+
if (!popup) {
|
|
4453
|
+
fail("oauthBlocked");
|
|
4454
|
+
return;
|
|
4455
|
+
}
|
|
4456
|
+
hint.textContent = t("oauthWaiting", locale, { provider });
|
|
4457
|
+
btn.textContent = t("oauthWaiting", locale, { provider });
|
|
4458
|
+
btn.disabled = true;
|
|
4459
|
+
btn.classList.add("oauth-btn-loading");
|
|
4460
|
+
const checkSession = async () => {
|
|
4461
|
+
if (!current() || exchanging || probing)
|
|
4462
|
+
return;
|
|
4463
|
+
probing = true;
|
|
4464
|
+
try {
|
|
4465
|
+
const session = await this.http.get(`${servicePrefix}/api/did/session`);
|
|
4466
|
+
if (current() && !exchanging && session?.authenticated === true)
|
|
4467
|
+
succeed();
|
|
4468
|
+
} catch {
|
|
4469
|
+
} finally {
|
|
4470
|
+
probing = false;
|
|
4471
|
+
}
|
|
4472
|
+
};
|
|
4473
|
+
pollTimer = setInterval(() => {
|
|
4310
4474
|
let closed = false;
|
|
4311
4475
|
try {
|
|
4312
|
-
closed = popup
|
|
4476
|
+
closed = !!popup?.closed;
|
|
4313
4477
|
} catch {
|
|
4314
4478
|
return;
|
|
4315
4479
|
}
|
|
4316
|
-
if (!closed)
|
|
4480
|
+
if (!closed || !current())
|
|
4317
4481
|
return;
|
|
4318
|
-
|
|
4319
|
-
|
|
4320
|
-
|
|
4321
|
-
|
|
4322
|
-
|
|
4323
|
-
|
|
4324
|
-
|
|
4325
|
-
if (session?.authenticated)
|
|
4326
|
-
succeed();
|
|
4327
|
-
}).catch(() => {
|
|
4328
|
-
});
|
|
4329
|
-
};
|
|
4330
|
-
checkSession();
|
|
4331
|
-
sessionPollTimer = setInterval(checkSession, 500);
|
|
4482
|
+
clearInterval(pollTimer);
|
|
4483
|
+
showRecovery("oauthIncomplete");
|
|
4484
|
+
cancel.hidden = false;
|
|
4485
|
+
void checkSession();
|
|
4486
|
+
sessionTimer = setInterval(() => {
|
|
4487
|
+
void checkSession();
|
|
4488
|
+
}, 2e3);
|
|
4332
4489
|
}, 500);
|
|
4333
|
-
|
|
4334
|
-
if (
|
|
4490
|
+
abandonTimer = setTimeout(() => {
|
|
4491
|
+
if (!current())
|
|
4492
|
+
return;
|
|
4493
|
+
if (!exchanging) {
|
|
4494
|
+
fail("oauthTimedOut");
|
|
4335
4495
|
return;
|
|
4336
|
-
cleanup();
|
|
4337
|
-
restore();
|
|
4338
|
-
}, 5 * 60 * 1e3);
|
|
4339
|
-
const cleanup = () => {
|
|
4340
|
-
settled = true;
|
|
4341
|
-
btn.innerHTML = originalHTML;
|
|
4342
|
-
btn.disabled = false;
|
|
4343
|
-
btn.classList.remove("oauth-btn-loading");
|
|
4344
|
-
if (pollTimer !== void 0) {
|
|
4345
|
-
clearInterval(pollTimer);
|
|
4346
|
-
pollTimer = void 0;
|
|
4347
|
-
}
|
|
4348
|
-
if (sessionPollTimer !== void 0) {
|
|
4349
|
-
clearInterval(sessionPollTimer);
|
|
4350
|
-
sessionPollTimer = void 0;
|
|
4351
4496
|
}
|
|
4352
|
-
|
|
4353
|
-
window.removeEventListener("message", onMessage);
|
|
4354
|
-
};
|
|
4355
|
-
this.oauthCleanup = () => {
|
|
4497
|
+
this.abort?.abort();
|
|
4356
4498
|
cleanup();
|
|
4357
|
-
|
|
4358
|
-
|
|
4359
|
-
|
|
4360
|
-
|
|
4361
|
-
|
|
4362
|
-
|
|
4363
|
-
|
|
4499
|
+
closePopup();
|
|
4500
|
+
lockMethods();
|
|
4501
|
+
hint.textContent = t("oauthUnconfirmed", locale);
|
|
4502
|
+
recovery.dataset.state = "oauthUnconfirmed";
|
|
4503
|
+
actions.hidden = false;
|
|
4504
|
+
reopen.hidden = true;
|
|
4505
|
+
cancel.hidden = true;
|
|
4506
|
+
fullPage.href = window.location.href;
|
|
4507
|
+
fullPage.textContent = t("oauthCheckSession", locale);
|
|
4508
|
+
this.emit("incomplete");
|
|
4509
|
+
}, 5 * 60 * 1e3);
|
|
4364
4510
|
}
|
|
4365
4511
|
// (removed dead code: renderEmailButton — email now renders through renderSecondaryGrid)
|
|
4366
4512
|
/**
|
|
@@ -4383,6 +4529,7 @@ var LoginPage = class {
|
|
|
4383
4529
|
btn.dataset.provider = provider.id;
|
|
4384
4530
|
const icon = getOAuthIcon(provider.id);
|
|
4385
4531
|
btn.innerHTML = `${icon} ${escapeHtml(t("continueWith", locale, { provider: provider.name }))}`;
|
|
4532
|
+
this.markLastUsed(btn, `oauth:${provider.id}`, locale);
|
|
4386
4533
|
grid.appendChild(btn);
|
|
4387
4534
|
btn.addEventListener("click", () => {
|
|
4388
4535
|
this.select("oauth");
|
|
@@ -4396,6 +4543,7 @@ var LoginPage = class {
|
|
|
4396
4543
|
btn.className = "method-btn";
|
|
4397
4544
|
btn.id = "email-btn";
|
|
4398
4545
|
btn.innerHTML = `${ICON_EMAIL} ${escapeHtml(t("emailButton", locale))}`;
|
|
4546
|
+
this.markLastUsed(btn, "email", locale);
|
|
4399
4547
|
grid.appendChild(btn);
|
|
4400
4548
|
btn.addEventListener("click", () => {
|
|
4401
4549
|
this.select("email");
|
|
@@ -4408,6 +4556,7 @@ var LoginPage = class {
|
|
|
4408
4556
|
btn.id = "did-wallet-btn";
|
|
4409
4557
|
const walletLabel = grid.children.length > 0 ? t("didWalletButtonShort", locale) : t("didWalletButton", locale);
|
|
4410
4558
|
btn.innerHTML = `${ICON_DID_WALLET} ${escapeHtml(walletLabel)}`;
|
|
4559
|
+
this.markLastUsed(btn, "did-connect", locale);
|
|
4411
4560
|
grid.appendChild(btn);
|
|
4412
4561
|
btn.addEventListener("click", () => {
|
|
4413
4562
|
this.select("did-connect");
|
|
@@ -4710,6 +4859,9 @@ var LoginDialog = class {
|
|
|
4710
4859
|
mount() {
|
|
4711
4860
|
if (this.dialog)
|
|
4712
4861
|
return;
|
|
4862
|
+
const hostLocale = document.documentElement.lang;
|
|
4863
|
+
if (hostLocale)
|
|
4864
|
+
this.options.locale = hostLocale;
|
|
4713
4865
|
let focused = document.activeElement;
|
|
4714
4866
|
while (focused?.shadowRoot?.activeElement)
|
|
4715
4867
|
focused = focused.shadowRoot.activeElement;
|