@luminaryworks/auth-react 0.4.5 → 0.6.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/README.md +14 -0
- package/dist/index.css +229 -4
- package/dist/index.css.map +1 -1
- package/dist/index.d.ts +197 -7
- package/dist/index.js +757 -14
- package/dist/index.js.map +1 -1
- package/dist/style.css +229 -4
- package/dist/style.css.map +1 -1
- package/package.json +4 -3
package/README.md
CHANGED
|
@@ -43,6 +43,16 @@ Override layout via `className` / `style` on the root.
|
|
|
43
43
|
// socialProviders: "auto" | ["google","github"] | []
|
|
44
44
|
/>
|
|
45
45
|
|
|
46
|
+
// Desktop / mobile native shell — Google/GitHub in the system browser (RFC 8252)
|
|
47
|
+
<HeadlessLoginPanel
|
|
48
|
+
config={idpConfig}
|
|
49
|
+
productName="VistaRemote"
|
|
50
|
+
mode="external"
|
|
51
|
+
openExternalUrl={(url) => window.nativeShell.openExternal(url)}
|
|
52
|
+
// Password Headless stays in-app; social/SSO open the OS browser.
|
|
53
|
+
// Register redirect_uri as http://127.0.0.1:<port>/auth/callback or app://…
|
|
54
|
+
/>
|
|
55
|
+
|
|
46
56
|
// Admin / internal console — hide Experience social connectors
|
|
47
57
|
<HeadlessLoginPanel
|
|
48
58
|
config={idpConfig}
|
|
@@ -54,11 +64,15 @@ Override layout via `className` / `style` on the root.
|
|
|
54
64
|
|
|
55
65
|
| Prop | Default | Notes |
|
|
56
66
|
|------|---------|--------|
|
|
67
|
+
| `mode` | `"popup"` | `"redirect"` SPA full-page; `"external"` system browser for social/SSO (needs `openExternalUrl`) |
|
|
68
|
+
| `openExternalUrl` | — | Required for `mode="external"`. Electron: `shell.openExternal`; RN: Custom Tabs / ASWebAuthenticationSession |
|
|
57
69
|
| `showSocialConnectors` | `true` | `false` skips fetch and hides divider + social buttons |
|
|
58
70
|
| `socialProviders` | `"auto"` | allowlist, or `[]` (same effect as `showSocialConnectors={false}`) |
|
|
59
71
|
| `experienceAdapter` | catalog default | optional custom `LoginExperienceAdapter`; otherwise `config.iamProvider` |
|
|
60
72
|
| `config.iamProvider` | `logto` | `logto` Headless; `oidc` / `zitadel` Hosted Redirect |
|
|
61
73
|
|
|
74
|
+
**Desktop callback:** Logto redirects the *system browser* to your loopback `redirect_uri`. The native shell must detect that request, focus the app window onto the same URL (so PKCE `localStorage` matches), and show Chrome a “you can close this tab” page. See VistaRemote Electron `serve-renderer-static` + Viewer preload.
|
|
75
|
+
|
|
62
76
|
IdP hosted `/sign-in` social row layout: `node scripts/apply-branding.mjs` (customCss wrap). Enable connectors: `ensure-sign-in-experience.mjs` + `verify-social-direct-signin.mjs`.
|
|
63
77
|
|
|
64
78
|
### Login experience adapters
|
package/dist/index.css
CHANGED
|
@@ -48,9 +48,58 @@
|
|
|
48
48
|
display: grid;
|
|
49
49
|
gap: 10px;
|
|
50
50
|
}
|
|
51
|
+
.HeadlessLoginPanel_module_channelTabs {
|
|
52
|
+
display: grid;
|
|
53
|
+
grid-template-columns: 1fr 1fr;
|
|
54
|
+
gap: 6px;
|
|
55
|
+
margin-bottom: 2px;
|
|
56
|
+
}
|
|
57
|
+
.HeadlessLoginPanel_module_channelTab {
|
|
58
|
+
border: 1px solid #c9d5de;
|
|
59
|
+
border-radius: 10px;
|
|
60
|
+
padding: 8px 10px;
|
|
61
|
+
font-size: 13px;
|
|
62
|
+
font-weight: 650;
|
|
63
|
+
cursor: pointer;
|
|
64
|
+
color: #4b5c68;
|
|
65
|
+
background: #f7fafc;
|
|
66
|
+
}
|
|
67
|
+
.HeadlessLoginPanel_module_channelTab:disabled {
|
|
68
|
+
opacity: 0.65;
|
|
69
|
+
cursor: not-allowed;
|
|
70
|
+
}
|
|
71
|
+
.HeadlessLoginPanel_module_channelTabActive {
|
|
72
|
+
color: var(--lw-auth-theme-deep);
|
|
73
|
+
border-color: var(--lw-auth-theme);
|
|
74
|
+
background: color-mix(in srgb, var(--lw-auth-theme) 10%, #fff);
|
|
75
|
+
}
|
|
76
|
+
.HeadlessLoginPanel_module_codeRow {
|
|
77
|
+
display: grid;
|
|
78
|
+
grid-template-columns: 1fr auto;
|
|
79
|
+
gap: 8px;
|
|
80
|
+
align-items: stretch;
|
|
81
|
+
}
|
|
82
|
+
.HeadlessLoginPanel_module_codeInput {
|
|
83
|
+
min-width: 0;
|
|
84
|
+
}
|
|
85
|
+
.HeadlessLoginPanel_module_secondaryBtn {
|
|
86
|
+
border: 1px solid #b7c9d4;
|
|
87
|
+
border-radius: 10px;
|
|
88
|
+
padding: 0 12px;
|
|
89
|
+
font-size: 13px;
|
|
90
|
+
font-weight: 650;
|
|
91
|
+
cursor: pointer;
|
|
92
|
+
color: #14212b;
|
|
93
|
+
background: #fff;
|
|
94
|
+
white-space: nowrap;
|
|
95
|
+
}
|
|
96
|
+
.HeadlessLoginPanel_module_secondaryBtn:disabled {
|
|
97
|
+
opacity: 0.65;
|
|
98
|
+
cursor: not-allowed;
|
|
99
|
+
}
|
|
51
100
|
.HeadlessLoginPanel_module_socialStack {
|
|
52
|
-
display:
|
|
53
|
-
|
|
101
|
+
display: grid;
|
|
102
|
+
grid-template-columns: repeat(2, minmax(0, 1fr));
|
|
54
103
|
gap: 10px;
|
|
55
104
|
font-size: 12px;
|
|
56
105
|
}
|
|
@@ -128,8 +177,8 @@
|
|
|
128
177
|
cursor: not-allowed;
|
|
129
178
|
}
|
|
130
179
|
.HeadlessLoginPanel_module_socialBtn {
|
|
131
|
-
|
|
132
|
-
min-width:
|
|
180
|
+
width: 100%;
|
|
181
|
+
min-width: 0;
|
|
133
182
|
display: flex;
|
|
134
183
|
align-items: center;
|
|
135
184
|
justify-content: center;
|
|
@@ -201,6 +250,13 @@
|
|
|
201
250
|
color: #6b7c87;
|
|
202
251
|
line-height: 1.45;
|
|
203
252
|
}
|
|
253
|
+
.HeadlessLoginPanel_module_domainsHint {
|
|
254
|
+
margin: -2px 0 0;
|
|
255
|
+
font-size: 12px;
|
|
256
|
+
line-height: 1.45;
|
|
257
|
+
color: #4b5c68;
|
|
258
|
+
word-break: break-word;
|
|
259
|
+
}
|
|
204
260
|
.HeadlessLoginPanel_module_switchMode {
|
|
205
261
|
margin: 12px 0 0;
|
|
206
262
|
text-align: center;
|
|
@@ -236,4 +292,173 @@
|
|
|
236
292
|
gap: 8px;
|
|
237
293
|
justify-content: center;
|
|
238
294
|
}
|
|
295
|
+
|
|
296
|
+
/* src/LoginLanguageSwitcher.module.scss */
|
|
297
|
+
.LoginLanguageSwitcher_module_switch {
|
|
298
|
+
position: relative;
|
|
299
|
+
display: inline-flex;
|
|
300
|
+
}
|
|
301
|
+
.LoginLanguageSwitcher_module_trigger {
|
|
302
|
+
display: inline-flex;
|
|
303
|
+
align-items: center;
|
|
304
|
+
gap: 6px;
|
|
305
|
+
height: 32px;
|
|
306
|
+
padding: 0 10px 0 8px;
|
|
307
|
+
border: 1px solid rgba(15, 23, 42, 0.12);
|
|
308
|
+
border-radius: 999px;
|
|
309
|
+
background: rgba(255, 255, 255, 0.86);
|
|
310
|
+
color: #243044;
|
|
311
|
+
font: inherit;
|
|
312
|
+
font-size: 13px;
|
|
313
|
+
line-height: 1;
|
|
314
|
+
cursor: pointer;
|
|
315
|
+
backdrop-filter: blur(8px);
|
|
316
|
+
}
|
|
317
|
+
.LoginLanguageSwitcher_module_trigger:hover,
|
|
318
|
+
.LoginLanguageSwitcher_module_trigger[aria-expanded=true] {
|
|
319
|
+
border-color: var(--lw-login-accent, #1677ff);
|
|
320
|
+
color: #0f172a;
|
|
321
|
+
}
|
|
322
|
+
.LoginLanguageSwitcher_module_icon {
|
|
323
|
+
width: 14px;
|
|
324
|
+
height: 14px;
|
|
325
|
+
display: block;
|
|
326
|
+
}
|
|
327
|
+
.LoginLanguageSwitcher_module_caret {
|
|
328
|
+
width: 10px;
|
|
329
|
+
height: 10px;
|
|
330
|
+
opacity: 0.65;
|
|
331
|
+
}
|
|
332
|
+
.LoginLanguageSwitcher_module_menu {
|
|
333
|
+
position: absolute;
|
|
334
|
+
top: calc(100% + 6px);
|
|
335
|
+
right: 0;
|
|
336
|
+
z-index: 20;
|
|
337
|
+
min-width: 168px;
|
|
338
|
+
margin: 0;
|
|
339
|
+
padding: 6px;
|
|
340
|
+
list-style: none;
|
|
341
|
+
border-radius: 12px;
|
|
342
|
+
background: #fff;
|
|
343
|
+
box-shadow: 0 12px 40px rgba(15, 23, 42, 0.16);
|
|
344
|
+
}
|
|
345
|
+
.LoginLanguageSwitcher_module_item {
|
|
346
|
+
display: block;
|
|
347
|
+
width: 100%;
|
|
348
|
+
border: 0;
|
|
349
|
+
border-radius: 8px;
|
|
350
|
+
padding: 8px 10px;
|
|
351
|
+
background: transparent;
|
|
352
|
+
color: #1f2937;
|
|
353
|
+
font: inherit;
|
|
354
|
+
font-size: 14px;
|
|
355
|
+
text-align: left;
|
|
356
|
+
cursor: pointer;
|
|
357
|
+
}
|
|
358
|
+
.LoginLanguageSwitcher_module_item:hover {
|
|
359
|
+
background: #f3f6fb;
|
|
360
|
+
}
|
|
361
|
+
.LoginLanguageSwitcher_module_itemActive {
|
|
362
|
+
background: color-mix(in srgb, var(--lw-login-accent, #1677ff) 14%, #fff);
|
|
363
|
+
color: var(--lw-login-accent, #1677ff);
|
|
364
|
+
font-weight: 650;
|
|
365
|
+
}
|
|
366
|
+
.LoginLanguageSwitcher_module_onDark {
|
|
367
|
+
border-color: rgba(255, 255, 255, 0.22);
|
|
368
|
+
background: rgba(15, 23, 42, 0.28);
|
|
369
|
+
color: rgba(255, 255, 255, 0.92);
|
|
370
|
+
}
|
|
371
|
+
.LoginLanguageSwitcher_module_onDark:hover,
|
|
372
|
+
.LoginLanguageSwitcher_module_onDark[aria-expanded=true] {
|
|
373
|
+
border-color: rgba(255, 255, 255, 0.55);
|
|
374
|
+
color: #fff;
|
|
375
|
+
}
|
|
376
|
+
|
|
377
|
+
/* src/LoginCanvas.module.scss */
|
|
378
|
+
.LoginCanvas_module_canvas {
|
|
379
|
+
--lw-login-accent: #1677ff;
|
|
380
|
+
position: relative;
|
|
381
|
+
min-height: 100dvh;
|
|
382
|
+
display: grid;
|
|
383
|
+
place-items: center;
|
|
384
|
+
padding: 56px 20px 24px;
|
|
385
|
+
overflow: hidden;
|
|
386
|
+
background:
|
|
387
|
+
radial-gradient(
|
|
388
|
+
900px 480px at 8% -8%,
|
|
389
|
+
color-mix(in srgb, var(--lw-login-accent) 28%, transparent),
|
|
390
|
+
transparent 58%),
|
|
391
|
+
radial-gradient(
|
|
392
|
+
720px 420px at 100% 12%,
|
|
393
|
+
color-mix(in srgb, var(--lw-login-accent) 16%, transparent),
|
|
394
|
+
transparent 52%),
|
|
395
|
+
linear-gradient(
|
|
396
|
+
165deg,
|
|
397
|
+
var(--lw-login-bg-a, #f4f7fb) 0%,
|
|
398
|
+
var(--lw-login-bg-b, #e7eef6) 100%);
|
|
399
|
+
color: var(--lw-login-ink, #122033);
|
|
400
|
+
}
|
|
401
|
+
.LoginCanvas_module_canvas[data-tone=console] {
|
|
402
|
+
--lw-login-accent: #7eb6ff;
|
|
403
|
+
--lw-login-bg-a: #0e1726;
|
|
404
|
+
--lw-login-bg-b: #1a2740;
|
|
405
|
+
--lw-login-ink: #e8eef8;
|
|
406
|
+
--lw-login-grid: rgba(255, 255, 255, 0.05);
|
|
407
|
+
}
|
|
408
|
+
.LoginCanvas_module_canvas[data-tone=vista] {
|
|
409
|
+
--lw-login-accent: #1677ff;
|
|
410
|
+
--lw-login-bg-a: #f4f7fb;
|
|
411
|
+
--lw-login-bg-b: #dde7f0;
|
|
412
|
+
--lw-login-grid: rgba(11, 18, 32, 0.045);
|
|
413
|
+
}
|
|
414
|
+
.LoginCanvas_module_canvas[data-tone=data] {
|
|
415
|
+
--lw-login-accent: #5aa2ff;
|
|
416
|
+
--lw-login-bg-a: #070b14;
|
|
417
|
+
--lw-login-bg-b: #12203a;
|
|
418
|
+
--lw-login-ink: #e8eefc;
|
|
419
|
+
--lw-login-grid: rgba(255, 255, 255, 0.045);
|
|
420
|
+
}
|
|
421
|
+
.LoginCanvas_module_canvas[data-tone=edu] {
|
|
422
|
+
--lw-login-accent: #f59e0b;
|
|
423
|
+
--lw-login-bg-a: #fff7ed;
|
|
424
|
+
--lw-login-bg-b: #e0e7ff;
|
|
425
|
+
--lw-login-grid: rgba(67, 56, 202, 0.06);
|
|
426
|
+
}
|
|
427
|
+
.LoginCanvas_module_grid {
|
|
428
|
+
position: absolute;
|
|
429
|
+
inset: 0;
|
|
430
|
+
pointer-events: none;
|
|
431
|
+
background-image:
|
|
432
|
+
linear-gradient(var(--lw-login-grid, rgba(15, 23, 42, 0.04)) 1px, transparent 1px),
|
|
433
|
+
linear-gradient(
|
|
434
|
+
90deg,
|
|
435
|
+
var(--lw-login-grid, rgba(15, 23, 42, 0.04)) 1px,
|
|
436
|
+
transparent 1px);
|
|
437
|
+
background-size: 48px 48px;
|
|
438
|
+
mask-image:
|
|
439
|
+
radial-gradient(
|
|
440
|
+
ellipse at center,
|
|
441
|
+
#000 18%,
|
|
442
|
+
transparent 74%);
|
|
443
|
+
}
|
|
444
|
+
.LoginCanvas_module_lang {
|
|
445
|
+
position: fixed;
|
|
446
|
+
top: 14px;
|
|
447
|
+
right: 16px;
|
|
448
|
+
z-index: 5;
|
|
449
|
+
}
|
|
450
|
+
.LoginCanvas_module_decor {
|
|
451
|
+
position: absolute;
|
|
452
|
+
inset: 0;
|
|
453
|
+
pointer-events: none;
|
|
454
|
+
z-index: 0;
|
|
455
|
+
}
|
|
456
|
+
.LoginCanvas_module_slot {
|
|
457
|
+
position: relative;
|
|
458
|
+
z-index: 1;
|
|
459
|
+
width: min(440px, 100%);
|
|
460
|
+
}
|
|
461
|
+
.LoginCanvas_module_slotFill {
|
|
462
|
+
width: min(1120px, 100%);
|
|
463
|
+
}
|
|
239
464
|
/*# sourceMappingURL=index.css.map */
|
package/dist/index.css.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/HeadlessLoginPanel.module.scss"],"sourcesContent":["$ink: #14212b;\n$muted: #4b5c68;\n$hint: #6b7c87;\n$brand: #3d6f8f;\n$brand-deep: #15485c;\n$brand-mid: #1f6f8b;\n$border: #c9d5de;\n$border-soft: #b7c9d4;\n$line: #d5e0e7;\n$divider: #90a0ab;\n$surface: #f7fafc;\n$fallback-bg: #e8eef2;\n$danger: #b42318;\n$footer-line: #e4ebf0;\n$radius-lg: 16px;\n$radius-md: 10px;\n$radius-sm: 4px;\n\n.panel {\n --lw-auth-theme: #1677ff;\n --lw-auth-theme-deep: color-mix(in srgb, var(--lw-auth-theme) 72%, #000);\n width: min(100%, 400px);\n padding: 28px 28px 22px;\n border-radius: $radius-lg;\n background: rgba(255, 255, 255, 0.96);\n color: $ink;\n box-shadow: 0 24px 64px rgba(15, 23, 42, 0.28);\n font-family: \"Segoe UI\", \"PingFang SC\", \"Noto Sans SC\", sans-serif;\n}\n\n.brand {\n display: flex;\n gap: 14px;\n align-items: center;\n margin-bottom: 12px;\n}\n\n.logo {\n border-radius: 12px;\n display: block;\n}\n\n.product {\n margin: 0;\n font-size: 13px;\n font-weight: 650;\n letter-spacing: 0.04em;\n text-transform: uppercase;\n color: var(--lw-auth-theme);\n}\n\n.title {\n margin: 2px 0 0;\n font-size: 22px;\n font-weight: 700;\n line-height: 1.25;\n}\n\n.subtitle {\n margin: 0 0 18px;\n font-size: 14px;\n line-height: 1.5;\n color: $muted;\n}\n\n.form {\n display: grid;\n gap: 10px;\n}\n\n.socialStack {\n display: flex;\n flex-wrap: wrap;\n gap: 10px;\n font-size: 12px;\n}\n\n.input {\n width: 100%;\n box-sizing: border-box;\n border: 1px solid $border;\n border-radius: $radius-md;\n padding: 10px 12px;\n font-size: 14px;\n outline: none;\n background: $surface;\n\n &:focus {\n border-color: var(--lw-auth-theme);\n }\n\n &:disabled {\n opacity: 0.65;\n cursor: not-allowed;\n }\n}\n\n.passwordField {\n position: relative;\n display: flex;\n align-items: center;\n}\n\n.passwordInput {\n padding-right: 42px;\n}\n\n.passwordToggle {\n position: absolute;\n right: 4px;\n top: 50%;\n transform: translateY(-50%);\n z-index: 1;\n display: inline-flex;\n align-items: center;\n justify-content: center;\n width: 36px;\n height: 36px;\n border: none;\n border-radius: $radius-sm;\n padding: 0;\n color: #5a6b76;\n background: transparent;\n cursor: pointer;\n\n &:hover:not(:disabled) {\n color: var(--lw-auth-theme);\n background: color-mix(in srgb, var(--lw-auth-theme) 12%, transparent);\n }\n\n &:focus-visible {\n outline: 2px solid var(--lw-auth-theme);\n outline-offset: 1px;\n }\n\n &:disabled {\n opacity: 0.65;\n cursor: not-allowed;\n }\n}\n\n.primaryBtn {\n border: none;\n border-radius: $radius-md;\n padding: 11px 14px;\n font-size: 14px;\n font-weight: 650;\n cursor: pointer;\n color: #fff;\n background: linear-gradient(135deg, var(--lw-auth-theme) 0%, var(--lw-auth-theme-deep) 100%);\n\n &:disabled {\n opacity: 0.65;\n cursor: not-allowed;\n }\n}\n\n.socialBtn {\n flex: 1 1 calc(50% - 5px);\n min-width: min(140px, 100%);\n display: flex;\n align-items: center;\n justify-content: center;\n gap: 8px;\n border: 1px solid $border-soft;\n border-radius: $radius-md;\n padding: 11px 10px;\n font-size: 14px;\n font-weight: 650;\n cursor: pointer;\n color: $ink;\n background: #fff;\n\n &:disabled {\n opacity: 0.65;\n cursor: not-allowed;\n }\n}\n\n.socialLogo {\n flex-shrink: 0;\n display: block;\n}\n\n.logoFallback {\n width: 18px;\n height: 18px;\n border-radius: $radius-sm;\n background: color-mix(in srgb, var(--lw-auth-theme) 14%, #fff);\n color: var(--lw-auth-theme-deep);\n font-size: 11px;\n font-weight: 700;\n display: inline-flex;\n align-items: center;\n justify-content: center;\n flex-shrink: 0;\n}\n\n.cancelBtn {\n margin-top: 10px;\n width: 100%;\n border: none;\n background: transparent;\n color: #5a6b76;\n font-size: 13px;\n cursor: pointer;\n padding: 8px;\n\n &:disabled {\n opacity: 0.65;\n cursor: not-allowed;\n }\n}\n\n.divider {\n display: flex;\n align-items: center;\n gap: 10px;\n margin: 14px 0;\n color: $divider;\n}\n\n.dividerLine {\n flex: 1;\n height: 1px;\n background: $line;\n}\n\n.dividerText {\n font-size: 12px;\n text-transform: uppercase;\n letter-spacing: 0.08em;\n}\n\n.hint {\n margin: 10px 0 0;\n font-size: 12px;\n color: $hint;\n line-height: 1.45;\n}\n\n.switchMode {\n margin: 12px 0 0;\n text-align: center;\n}\n\n.switchModeBtn {\n border: none;\n background: transparent;\n color: var(--lw-auth-theme);\n font-size: 13px;\n font-weight: 650;\n cursor: pointer;\n padding: 4px 8px;\n text-decoration: underline;\n text-underline-offset: 3px;\n\n &:disabled {\n opacity: 0.65;\n cursor: not-allowed;\n }\n}\n\n.error {\n margin: 12px 0 0;\n font-size: 13px;\n color: $danger;\n line-height: 1.4;\n}\n\n.footer {\n margin-top: 18px;\n padding-top: 12px;\n border-top: 1px solid $footer-line;\n font-size: 12px;\n color: $hint;\n display: flex;\n gap: 8px;\n justify-content: center;\n}\n"],"mappings":"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","names":["panel","brand","logo","product","title","subtitle","form","socialStack","input","passwordField","passwordInput","passwordToggle","primaryBtn","socialBtn","socialLogo","logoFallback","cancelBtn","divider","dividerLine","dividerText","hint","switchMode","switchModeBtn","error","footer"]}
|
|
1
|
+
{"version":3,"sources":["../src/HeadlessLoginPanel.module.scss","../src/LoginLanguageSwitcher.module.scss","../src/LoginCanvas.module.scss"],"sourcesContent":["$ink: #14212b;\n$muted: #4b5c68;\n$hint: #6b7c87;\n$brand: #3d6f8f;\n$brand-deep: #15485c;\n$brand-mid: #1f6f8b;\n$border: #c9d5de;\n$border-soft: #b7c9d4;\n$line: #d5e0e7;\n$divider: #90a0ab;\n$surface: #f7fafc;\n$fallback-bg: #e8eef2;\n$danger: #b42318;\n$footer-line: #e4ebf0;\n$radius-lg: 16px;\n$radius-md: 10px;\n$radius-sm: 4px;\n\n.panel {\n --lw-auth-theme: #1677ff;\n --lw-auth-theme-deep: color-mix(in srgb, var(--lw-auth-theme) 72%, #000);\n width: min(100%, 400px);\n padding: 28px 28px 22px;\n border-radius: $radius-lg;\n background: rgba(255, 255, 255, 0.96);\n color: $ink;\n box-shadow: 0 24px 64px rgba(15, 23, 42, 0.28);\n font-family: \"Segoe UI\", \"PingFang SC\", \"Noto Sans SC\", sans-serif;\n}\n\n.brand {\n display: flex;\n gap: 14px;\n align-items: center;\n margin-bottom: 12px;\n}\n\n.logo {\n border-radius: 12px;\n display: block;\n}\n\n.product {\n margin: 0;\n font-size: 13px;\n font-weight: 650;\n letter-spacing: 0.04em;\n text-transform: uppercase;\n color: var(--lw-auth-theme);\n}\n\n.title {\n margin: 2px 0 0;\n font-size: 22px;\n font-weight: 700;\n line-height: 1.25;\n}\n\n.subtitle {\n margin: 0 0 18px;\n font-size: 14px;\n line-height: 1.5;\n color: $muted;\n}\n\n.form {\n display: grid;\n gap: 10px;\n}\n\n.channelTabs {\n display: grid;\n grid-template-columns: 1fr 1fr;\n gap: 6px;\n margin-bottom: 2px;\n}\n\n.channelTab {\n border: 1px solid $border;\n border-radius: $radius-md;\n padding: 8px 10px;\n font-size: 13px;\n font-weight: 650;\n cursor: pointer;\n color: $muted;\n background: $surface;\n\n &:disabled {\n opacity: 0.65;\n cursor: not-allowed;\n }\n}\n\n.channelTabActive {\n color: var(--lw-auth-theme-deep);\n border-color: var(--lw-auth-theme);\n background: color-mix(in srgb, var(--lw-auth-theme) 10%, #fff);\n}\n\n.codeRow {\n display: grid;\n grid-template-columns: 1fr auto;\n gap: 8px;\n align-items: stretch;\n}\n\n.codeInput {\n min-width: 0;\n}\n\n.secondaryBtn {\n border: 1px solid $border-soft;\n border-radius: $radius-md;\n padding: 0 12px;\n font-size: 13px;\n font-weight: 650;\n cursor: pointer;\n color: $ink;\n background: #fff;\n white-space: nowrap;\n\n &:disabled {\n opacity: 0.65;\n cursor: not-allowed;\n }\n}\n\n.socialStack {\n display: grid;\n grid-template-columns: repeat(2, minmax(0, 1fr));\n gap: 10px;\n font-size: 12px;\n}\n\n.input {\n width: 100%;\n box-sizing: border-box;\n border: 1px solid $border;\n border-radius: $radius-md;\n padding: 10px 12px;\n font-size: 14px;\n outline: none;\n background: $surface;\n\n &:focus {\n border-color: var(--lw-auth-theme);\n }\n\n &:disabled {\n opacity: 0.65;\n cursor: not-allowed;\n }\n}\n\n.passwordField {\n position: relative;\n display: flex;\n align-items: center;\n}\n\n.passwordInput {\n padding-right: 42px;\n}\n\n.passwordToggle {\n position: absolute;\n right: 4px;\n top: 50%;\n transform: translateY(-50%);\n z-index: 1;\n display: inline-flex;\n align-items: center;\n justify-content: center;\n width: 36px;\n height: 36px;\n border: none;\n border-radius: $radius-sm;\n padding: 0;\n color: #5a6b76;\n background: transparent;\n cursor: pointer;\n\n &:hover:not(:disabled) {\n color: var(--lw-auth-theme);\n background: color-mix(in srgb, var(--lw-auth-theme) 12%, transparent);\n }\n\n &:focus-visible {\n outline: 2px solid var(--lw-auth-theme);\n outline-offset: 1px;\n }\n\n &:disabled {\n opacity: 0.65;\n cursor: not-allowed;\n }\n}\n\n.primaryBtn {\n border: none;\n border-radius: $radius-md;\n padding: 11px 14px;\n font-size: 14px;\n font-weight: 650;\n cursor: pointer;\n color: #fff;\n background: linear-gradient(135deg, var(--lw-auth-theme) 0%, var(--lw-auth-theme-deep) 100%);\n\n &:disabled {\n opacity: 0.65;\n cursor: not-allowed;\n }\n}\n\n.socialBtn {\n width: 100%;\n min-width: 0;\n display: flex;\n align-items: center;\n justify-content: center;\n gap: 8px;\n border: 1px solid $border-soft;\n border-radius: $radius-md;\n padding: 11px 10px;\n font-size: 14px;\n font-weight: 650;\n cursor: pointer;\n color: $ink;\n background: #fff;\n\n &:disabled {\n opacity: 0.65;\n cursor: not-allowed;\n }\n}\n\n.socialLogo {\n flex-shrink: 0;\n display: block;\n}\n\n.logoFallback {\n width: 18px;\n height: 18px;\n border-radius: $radius-sm;\n background: color-mix(in srgb, var(--lw-auth-theme) 14%, #fff);\n color: var(--lw-auth-theme-deep);\n font-size: 11px;\n font-weight: 700;\n display: inline-flex;\n align-items: center;\n justify-content: center;\n flex-shrink: 0;\n}\n\n.cancelBtn {\n margin-top: 10px;\n width: 100%;\n border: none;\n background: transparent;\n color: #5a6b76;\n font-size: 13px;\n cursor: pointer;\n padding: 8px;\n\n &:disabled {\n opacity: 0.65;\n cursor: not-allowed;\n }\n}\n\n.divider {\n display: flex;\n align-items: center;\n gap: 10px;\n margin: 14px 0;\n color: $divider;\n}\n\n.dividerLine {\n flex: 1;\n height: 1px;\n background: $line;\n}\n\n.dividerText {\n font-size: 12px;\n text-transform: uppercase;\n letter-spacing: 0.08em;\n}\n\n.hint {\n margin: 10px 0 0;\n font-size: 12px;\n color: $hint;\n line-height: 1.45;\n}\n\n.domainsHint {\n margin: -2px 0 0;\n font-size: 12px;\n line-height: 1.45;\n color: $muted;\n word-break: break-word;\n}\n\n.switchMode {\n margin: 12px 0 0;\n text-align: center;\n}\n\n.switchModeBtn {\n border: none;\n background: transparent;\n color: var(--lw-auth-theme);\n font-size: 13px;\n font-weight: 650;\n cursor: pointer;\n padding: 4px 8px;\n text-decoration: underline;\n text-underline-offset: 3px;\n\n &:disabled {\n opacity: 0.65;\n cursor: not-allowed;\n }\n}\n\n.error {\n margin: 12px 0 0;\n font-size: 13px;\n color: $danger;\n line-height: 1.4;\n}\n\n.footer {\n margin-top: 18px;\n padding-top: 12px;\n border-top: 1px solid $footer-line;\n font-size: 12px;\n color: $hint;\n display: flex;\n gap: 8px;\n justify-content: center;\n}\n",".switch {\n position: relative;\n display: inline-flex;\n}\n\n.trigger {\n display: inline-flex;\n align-items: center;\n gap: 6px;\n height: 32px;\n padding: 0 10px 0 8px;\n border: 1px solid rgba(15, 23, 42, 0.12);\n border-radius: 999px;\n background: rgba(255, 255, 255, 0.86);\n color: #243044;\n font: inherit;\n font-size: 13px;\n line-height: 1;\n cursor: pointer;\n backdrop-filter: blur(8px);\n\n &:hover,\n &[aria-expanded=\"true\"] {\n border-color: var(--lw-login-accent, #1677ff);\n color: #0f172a;\n }\n}\n\n.icon {\n width: 14px;\n height: 14px;\n display: block;\n}\n\n.caret {\n width: 10px;\n height: 10px;\n opacity: 0.65;\n}\n\n.menu {\n position: absolute;\n top: calc(100% + 6px);\n right: 0;\n z-index: 20;\n min-width: 168px;\n margin: 0;\n padding: 6px;\n list-style: none;\n border-radius: 12px;\n background: #fff;\n box-shadow: 0 12px 40px rgba(15, 23, 42, 0.16);\n}\n\n.item {\n display: block;\n width: 100%;\n border: 0;\n border-radius: 8px;\n padding: 8px 10px;\n background: transparent;\n color: #1f2937;\n font: inherit;\n font-size: 14px;\n text-align: left;\n cursor: pointer;\n\n &:hover {\n background: #f3f6fb;\n }\n}\n\n.itemActive {\n background: color-mix(in srgb, var(--lw-login-accent, #1677ff) 14%, #fff);\n color: var(--lw-login-accent, #1677ff);\n font-weight: 650;\n}\n\n.onDark {\n border-color: rgba(255, 255, 255, 0.22);\n background: rgba(15, 23, 42, 0.28);\n color: rgba(255, 255, 255, 0.92);\n\n &:hover,\n &[aria-expanded=\"true\"] {\n border-color: rgba(255, 255, 255, 0.55);\n color: #fff;\n }\n}\n",".canvas {\n --lw-login-accent: #1677ff;\n position: relative;\n min-height: 100dvh;\n display: grid;\n place-items: center;\n padding: 56px 20px 24px;\n overflow: hidden;\n background:\n radial-gradient(900px 480px at 8% -8%, color-mix(in srgb, var(--lw-login-accent) 28%, transparent), transparent 58%),\n radial-gradient(720px 420px at 100% 12%, color-mix(in srgb, var(--lw-login-accent) 16%, transparent), transparent 52%),\n linear-gradient(165deg, var(--lw-login-bg-a, #f4f7fb) 0%, var(--lw-login-bg-b, #e7eef6) 100%);\n color: var(--lw-login-ink, #122033);\n}\n\n.canvas[data-tone=\"console\"] {\n --lw-login-accent: #7eb6ff;\n --lw-login-bg-a: #0e1726;\n --lw-login-bg-b: #1a2740;\n --lw-login-ink: #e8eef8;\n --lw-login-grid: rgba(255, 255, 255, 0.05);\n}\n\n.canvas[data-tone=\"vista\"] {\n --lw-login-accent: #1677ff;\n --lw-login-bg-a: #f4f7fb;\n --lw-login-bg-b: #dde7f0;\n --lw-login-grid: rgba(11, 18, 32, 0.045);\n}\n\n.canvas[data-tone=\"data\"] {\n --lw-login-accent: #5aa2ff;\n --lw-login-bg-a: #070b14;\n --lw-login-bg-b: #12203a;\n --lw-login-ink: #e8eefc;\n --lw-login-grid: rgba(255, 255, 255, 0.045);\n}\n\n.canvas[data-tone=\"edu\"] {\n --lw-login-accent: #f59e0b;\n --lw-login-bg-a: #fff7ed;\n --lw-login-bg-b: #e0e7ff;\n --lw-login-grid: rgba(67, 56, 202, 0.06);\n}\n\n.grid {\n position: absolute;\n inset: 0;\n pointer-events: none;\n background-image:\n linear-gradient(var(--lw-login-grid, rgba(15, 23, 42, 0.04)) 1px, transparent 1px),\n linear-gradient(90deg, var(--lw-login-grid, rgba(15, 23, 42, 0.04)) 1px, transparent 1px);\n background-size: 48px 48px;\n mask-image: radial-gradient(ellipse at center, #000 18%, transparent 74%);\n}\n\n.lang {\n position: fixed;\n top: 14px;\n right: 16px;\n z-index: 5;\n}\n\n.decor {\n position: absolute;\n inset: 0;\n pointer-events: none;\n z-index: 0;\n}\n\n.slot {\n position: relative;\n z-index: 1;\n width: min(440px, 100%);\n}\n\n.slotFill {\n width: min(1120px, 100%);\n}\n"],"mappings":";AAkBA,CAAAA;AACE,mBAAA;AACA,wBAAA,UAAA,GAAA,IAAA,EAAA,IAAA,iBAAA,GAAA,EAAA;AACA,SAAA,IAAA,IAAA,EAAA;AACA,WAAA,KAAA,KAAA;AACA,iBATU;AAUV,cAAA,KAAA,GAAA,EAAA,GAAA,EAAA,GAAA,EAAA;AACA,SAzBI;AA0BJ,cAAA,EAAA,KAAA,KAAA,KAAA,EAAA,EAAA,EAAA,EAAA,EAAA,EAAA;AACA;IAAA,UAAA;IAAA,aAAA;IAAA,cAAA;IAAA;;AAGF,CAAAC;AACE,WAAA;AACA,OAAA;AACA,eAAA;AACA,iBAAA;;AAGF,CAAAC;AACE,iBAAA;AACA,WAAA;;AAGF,CAAAC;AACE,UAAA;AACA,aAAA;AACA,eAAA;AACA,kBAAA;AACA,kBAAA;AACA,SAAA,IAAA;;AAGF,CAAAC;AACE,UAAA,IAAA,EAAA;AACA,aAAA;AACA,eAAA;AACA,eAAA;;AAGF,CAAAC;AACE,UAAA,EAAA,EAAA;AACA,aAAA;AACA,eAAA;AACA,SA7DM;;AAgER,CAAAC;AACE,WAAA;AACA,OAAA;;AAGF,CAAAC;AACE,WAAA;AACA,yBAAA,IAAA;AACA,OAAA;AACA,iBAAA;;AAGF,CAAAC;AACE,UAAA,IAAA,MAAA;AACA,iBAhEU;AAiEV,WAAA,IAAA;AACA,aAAA;AACA,eAAA;AACA,UAAA;AACA,SAnFM;AAoFN,cA3EQ;;AA6ER,CAVFA,oCAUE;AACE,WAAA;AACA,UAAA;;AAIJ,CAAAC;AACE,SAAA,IAAA;AACA,gBAAA,IAAA;AACA,cAAA,UAAA,GAAA,IAAA,EAAA,IAAA,iBAAA,GAAA,EAAA;;AAGF,CAAAC;AACE,WAAA;AACA,yBAAA,IAAA;AACA,OAAA;AACA,eAAA;;AAGF,CAAAC;AACE,aAAA;;AAGF,CAAAC;AACE,UAAA,IAAA,MAAA;AACA,iBAjGU;AAkGV,WAAA,EAAA;AACA,aAAA;AACA,eAAA;AACA,UAAA;AACA,SArHI;AAsHJ,cAAA;AACA,eAAA;;AAEA,CAXFA,sCAWE;AACE,WAAA;AACA,UAAA;;AAIJ,CAAAC;AACE,WAAA;AACA,yBAAA,OAAA,CAAA,EAAA,OAAA,CAAA,EAAA;AACA,OAAA;AACA,aAAA;;AAGF,CAAAC;AACE,SAAA;AACA,cAAA;AACA,UAAA,IAAA,MAAA;AACA,iBA3HU;AA4HV,WAAA,KAAA;AACA,aAAA;AACA,WAAA;AACA,cApIQ;;AAsIR,CAVFA,+BAUE;AACE,gBAAA,IAAA;;AAGF,CAdFA,+BAcE;AACE,WAAA;AACA,UAAA;;AAIJ,CAAAC;AACE,YAAA;AACA,WAAA;AACA,eAAA;;AAGF,CAAAC;AACE,iBAAA;;AAGF,CAAAC;AACE,YAAA;AACA,SAAA;AACA,OAAA;AACA,aAAA,WAAA;AACA,WAAA;AACA,WAAA;AACA,eAAA;AACA,mBAAA;AACA,SAAA;AACA,UAAA;AACA,UAAA;AACA,iBAhKU;AAiKV,WAAA;AACA,SAAA;AACA,cAAA;AACA,UAAA;;AAEA,CAlBFA,wCAkBE,MAAA,KAAA;AACE,SAAA,IAAA;AACA,cAAA,UAAA,GAAA,IAAA,EAAA,IAAA,iBAAA,GAAA,EAAA;;AAGF,CAvBFA,wCAuBE;AACE,WAAA,IAAA,MAAA,IAAA;AACA,kBAAA;;AAGF,CA5BFA,wCA4BE;AACE,WAAA;AACA,UAAA;;AAIJ,CAAAC;AACE,UAAA;AACA,iBAzLU;AA0LV,WAAA,KAAA;AACA,aAAA;AACA,eAAA;AACA,UAAA;AACA,SAAA;AACA;IAAA;MAAA,MAAA;MAAA,IAAA,iBAAA,EAAA;MAAA,IAAA,sBAAA;;AAEA,CAVFA,oCAUE;AACE,WAAA;AACA,UAAA;;AAIJ,CAAAC;AACE,SAAA;AACA,aAAA;AACA,WAAA;AACA,eAAA;AACA,mBAAA;AACA,OAAA;AACA,UAAA,IAAA,MAAA;AACA,iBA/MU;AAgNV,WAAA,KAAA;AACA,aAAA;AACA,eAAA;AACA,UAAA;AACA,SAnOI;AAoOJ,cAAA;;AAEA,CAhBFA,mCAgBE;AACE,WAAA;AACA,UAAA;;AAIJ,CAAAC;AACE,eAAA;AACA,WAAA;;AAGF,CAAAC;AACE,SAAA;AACA,UAAA;AACA,iBApOU;AAqOV,cAAA,UAAA,GAAA,IAAA,EAAA,IAAA,iBAAA,GAAA,EAAA;AACA,SAAA,IAAA;AACA,aAAA;AACA,eAAA;AACA,WAAA;AACA,eAAA;AACA,mBAAA;AACA,eAAA;;AAGF,CAAAC;AACE,cAAA;AACA,SAAA;AACA,UAAA;AACA,cAAA;AACA,SAAA;AACA,aAAA;AACA,UAAA;AACA,WAAA;;AAEA,CAVFA,mCAUE;AACE,WAAA;AACA,UAAA;;AAIJ,CAAAC;AACE,WAAA;AACA,eAAA;AACA,OAAA;AACA,UAAA,KAAA;AACA,SA3QQ;;AA8QV,CAAAC;AACE,QAAA;AACA,UAAA;AACA,cAlRK;;AAqRP,CAAAC;AACE,aAAA;AACA,kBAAA;AACA,kBAAA;;AAGF,CAAAC;AACE,UAAA,KAAA,EAAA;AACA,aAAA;AACA,SApSK;AAqSL,eAAA;;AAGF,CAAAC;AACE,UAAA,KAAA,EAAA;AACA,aAAA;AACA,eAAA;AACA,SA7SM;AA8SN,cAAA;;AAGF,CAAAC;AACE,UAAA,KAAA,EAAA;AACA,cAAA;;AAGF,CAAAC;AACE,UAAA;AACA,cAAA;AACA,SAAA,IAAA;AACA,aAAA;AACA,eAAA;AACA,UAAA;AACA,WAAA,IAAA;AACA,mBAAA;AACA,yBAAA;;AAEA,CAXFA,uCAWE;AACE,WAAA;AACA,UAAA;;AAIJ,CAAAC;AACE,UAAA,KAAA,EAAA;AACA,aAAA;AACA,SA/TO;AAgUP,eAAA;;AAGF,CAAAC;AACE,cAAA;AACA,eAAA;AACA,cAAA,IAAA,MAAA;AACA,aAAA;AACA,SAlVK;AAmVL,WAAA;AACA,OAAA;AACA,mBAAA;;;;ACvVF,CAAAC;AACE,YAAA;AACA,WAAA;;AAGF,CAAAC;AACE,WAAA;AACA,eAAA;AACA,OAAA;AACA,UAAA;AACA,WAAA,EAAA,KAAA,EAAA;AACA,UAAA,IAAA,MAAA,KAAA,EAAA,EAAA,EAAA,EAAA,EAAA,EAAA;AACA,iBAAA;AACA,cAAA,KAAA,GAAA,EAAA,GAAA,EAAA,GAAA,EAAA;AACA,SAAA;AACA,QAAA;AACA,aAAA;AACA,eAAA;AACA,UAAA;AACA,mBAAA,KAAA;;AAEA,CAhBFA,oCAgBE;AAAA,CAhBFA,oCAgBE,CAAA;AAEE,gBAAA,IAAA,iBAAA,EAAA;AACA,SAAA;;AAIJ,CAAAC;AACE,SAAA;AACA,UAAA;AACA,WAAA;;AAGF,CAAAC;AACE,SAAA;AACA,UAAA;AACA,WAAA;;AAGF,CAAAC;AACE,YAAA;AACA,OAAA,KAAA,KAAA,EAAA;AACA,SAAA;AACA,WAAA;AACA,aAAA;AACA,UAAA;AACA,WAAA;AACA,cAAA;AACA,iBAAA;AACA,cAAA;AACA,cAAA,EAAA,KAAA,KAAA,KAAA,EAAA,EAAA,EAAA,EAAA,EAAA,EAAA;;AAGF,CAAAC;AACE,WAAA;AACA,SAAA;AACA,UAAA;AACA,iBAAA;AACA,WAAA,IAAA;AACA,cAAA;AACA,SAAA;AACA,QAAA;AACA,aAAA;AACA,cAAA;AACA,UAAA;;AAEA,CAbFA,iCAaE;AACE,cAAA;;AAIJ,CAAAC;AACE,cAAA,UAAA,GAAA,IAAA,EAAA,IAAA,iBAAA,EAAA,SAAA,GAAA,EAAA;AACA,SAAA,IAAA,iBAAA,EAAA;AACA,eAAA;;AAGF,CAAAC;AACE,gBAAA,KAAA,GAAA,EAAA,GAAA,EAAA,GAAA,EAAA;AACA,cAAA,KAAA,EAAA,EAAA,EAAA,EAAA,EAAA,EAAA;AACA,SAAA,KAAA,GAAA,EAAA,GAAA,EAAA,GAAA,EAAA;;AAEA,CALFA,mCAKE;AAAA,CALFA,mCAKE,CAAA;AAEE,gBAAA,KAAA,GAAA,EAAA,GAAA,EAAA,GAAA,EAAA;AACA,SAAA;;;;ACtFJ,CAAAC;AACE,qBAAA;AACA,YAAA;AACA,cAAA;AACA,WAAA;AACA,eAAA;AACA,WAAA,KAAA,KAAA;AACA,YAAA;AACA;IACE;MAAA,MAAA,MAAA,GAAA,GAAA,GAAA;MAAA,UAAA,GAAA,IAAA,EAAA,IAAA,mBAAA,GAAA,EAAA,YAAA;MAAA,YAAA,IAAA;IAAA;MAAA,MAAA,MAAA,GAAA,KAAA,GAAA;MAAA,UAAA,GAAA,IAAA,EAAA,IAAA,mBAAA,GAAA,EAAA,YAAA;MAAA,YAAA,IAAA;IAAA;MAAA,MAAA;MAAA,IAAA,eAAA,EAAA,SAAA,EAAA;MAAA,IAAA,eAAA,EAAA,SAAA;AAGF,SAAA,IAAA,cAAA,EAAA;;AAGF,CAfAA,yBAeA,CAAA;AACE,qBAAA;AACA,mBAAA;AACA,mBAAA;AACA,kBAAA;AACA,mBAAA,KAAA,GAAA,EAAA,GAAA,EAAA,GAAA,EAAA;;AAGF,CAvBAA,yBAuBA,CAAA;AACE,qBAAA;AACA,mBAAA;AACA,mBAAA;AACA,mBAAA,KAAA,EAAA,EAAA,EAAA,EAAA,EAAA,EAAA;;AAGF,CA9BAA,yBA8BA,CAAA;AACE,qBAAA;AACA,mBAAA;AACA,mBAAA;AACA,kBAAA;AACA,mBAAA,KAAA,GAAA,EAAA,GAAA,EAAA,GAAA,EAAA;;AAGF,CAtCAA,yBAsCA,CAAA;AACE,qBAAA;AACA,mBAAA;AACA,mBAAA;AACA,mBAAA,KAAA,EAAA,EAAA,EAAA,EAAA,GAAA,EAAA;;AAGF,CAAAC;AACE,YAAA;AACA,SAAA;AACA,kBAAA;AACA;IACE,gBAAA,IAAA,eAAA,EAAA,KAAA,EAAA,EAAA,EAAA,EAAA,EAAA,EAAA,OAAA,GAAA,EAAA,YAAA,IAAA;IAAA;MAAA,KAAA;MAAA,IAAA,eAAA,EAAA,KAAA,EAAA,EAAA,EAAA,EAAA,EAAA,EAAA,OAAA,GAAA;MAAA,YAAA;AAEF,mBAAA,KAAA;AACA;IAAA;MAAA,QAAA,GAAA,MAAA;MAAA,KAAA,GAAA;MAAA,YAAA;;AAGF,CAAAC;AACE,YAAA;AACA,OAAA;AACA,SAAA;AACA,WAAA;;AAGF,CAAAC;AACE,YAAA;AACA,SAAA;AACA,kBAAA;AACA,WAAA;;AAGF,CAAAC;AACE,YAAA;AACA,WAAA;AACA,SAAA,IAAA,KAAA,EAAA;;AAGF,CAAAC;AACE,SAAA,IAAA,MAAA,EAAA;;","names":["panel","brand","logo","product","title","subtitle","form","channelTabs","channelTab","channelTabActive","codeRow","codeInput","secondaryBtn","socialStack","input","passwordField","passwordInput","passwordToggle","primaryBtn","socialBtn","socialLogo","logoFallback","cancelBtn","divider","dividerLine","dividerText","hint","domainsHint","switchMode","switchModeBtn","error","footer","switch","trigger","icon","caret","menu","item","itemActive","onDark","canvas","grid","lang","decor","slot","slotFill"]}
|
package/dist/index.d.ts
CHANGED
|
@@ -100,6 +100,8 @@ declare const LOGIN_EXPERIENCE_CAPABILITIES: {
|
|
|
100
100
|
readonly passwordSignIn: "password-sign-in";
|
|
101
101
|
/** Username + password self-register via Experience (Logto NewPasswordIdentity). */
|
|
102
102
|
readonly passwordSignUp: "password-sign-up";
|
|
103
|
+
/** Email + verification code + password self-register. */
|
|
104
|
+
readonly emailCodeSignUp: "email-code-sign-up";
|
|
103
105
|
readonly socialConnectors: "social-connectors";
|
|
104
106
|
readonly socialDirectSignIn: "social-direct-sign-in";
|
|
105
107
|
};
|
|
@@ -126,8 +128,42 @@ interface ExperiencePasswordSignInResult {
|
|
|
126
128
|
raw?: unknown;
|
|
127
129
|
}
|
|
128
130
|
/** Same OIDC bootstrap fields as sign-in; username must match Logto username rules. */
|
|
129
|
-
type ExperiencePasswordSignUpInput = ExperiencePasswordSignInInput
|
|
131
|
+
type ExperiencePasswordSignUpInput = ExperiencePasswordSignInInput & {
|
|
132
|
+
/** Optional CAPTCHA token for Logto bot protection (Turnstile / reCAPTCHA). */
|
|
133
|
+
captchaToken?: string;
|
|
134
|
+
};
|
|
130
135
|
type ExperiencePasswordSignUpResult = ExperiencePasswordSignInResult;
|
|
136
|
+
interface ExperienceEmailSignUpSendCodeInput {
|
|
137
|
+
apiBase: string;
|
|
138
|
+
email: string;
|
|
139
|
+
/** @deprecated alias of email */
|
|
140
|
+
identifier?: string;
|
|
141
|
+
captchaToken?: string;
|
|
142
|
+
issuer?: string;
|
|
143
|
+
clientId?: string;
|
|
144
|
+
redirectUri?: string;
|
|
145
|
+
audience?: string;
|
|
146
|
+
scopes?: string;
|
|
147
|
+
returnUrl?: string;
|
|
148
|
+
}
|
|
149
|
+
interface ExperienceEmailSignUpSendCodeResult {
|
|
150
|
+
verificationId: string;
|
|
151
|
+
}
|
|
152
|
+
interface ExperienceEmailSignUpCompleteInput {
|
|
153
|
+
apiBase: string;
|
|
154
|
+
email: string;
|
|
155
|
+
password: string;
|
|
156
|
+
code: string;
|
|
157
|
+
verificationId: string;
|
|
158
|
+
identifier?: string;
|
|
159
|
+
captchaToken?: string;
|
|
160
|
+
issuer?: string;
|
|
161
|
+
clientId?: string;
|
|
162
|
+
redirectUri?: string;
|
|
163
|
+
audience?: string;
|
|
164
|
+
scopes?: string;
|
|
165
|
+
returnUrl?: string;
|
|
166
|
+
}
|
|
131
167
|
interface ExperienceSocialConnector {
|
|
132
168
|
id: string;
|
|
133
169
|
target: string;
|
|
@@ -158,6 +194,8 @@ interface LoginExperienceAdapter {
|
|
|
158
194
|
* Email/phone sign-up needs verification codes — not covered by this method.
|
|
159
195
|
*/
|
|
160
196
|
experiencePasswordSignUp?(input: ExperiencePasswordSignUpInput): Promise<ExperiencePasswordSignUpResult>;
|
|
197
|
+
sendRegisterEmailCode?(input: ExperienceEmailSignUpSendCodeInput): Promise<ExperienceEmailSignUpSendCodeResult>;
|
|
198
|
+
experienceEmailPasswordSignUp?(input: ExperienceEmailSignUpCompleteInput): Promise<ExperiencePasswordSignUpResult>;
|
|
161
199
|
fetchSocialConnectors?(input: FetchSocialConnectorsInput): Promise<ExperienceSocialConnector[]>;
|
|
162
200
|
createSocialSignInRequest?(target: string): SocialSignInRequest;
|
|
163
201
|
}
|
|
@@ -180,6 +218,76 @@ declare function resolveLoginExperienceAdapter(adapter?: LoginExperienceAdapter
|
|
|
180
218
|
/** `VITE_IAM_PROVIDER` / `IAM_PROVIDER` / older `IDP_MODE`. */
|
|
181
219
|
declare function resolveLoginExperienceProviderFromEnv(env?: Record<string, string | undefined>): LoginExperienceProvider;
|
|
182
220
|
|
|
221
|
+
/**
|
|
222
|
+
* Self-register email policy for early ToC / hosted SaaS.
|
|
223
|
+
*
|
|
224
|
+
* Why allowlist: disposable / game / temporary mailboxes drive bot farms and
|
|
225
|
+
* verification-email cost. Early stage: only well-known consumer providers.
|
|
226
|
+
* Enterprise / private: set mode `off` or extend allowlist with corporate domains.
|
|
227
|
+
*/
|
|
228
|
+
/** Popular consumer inboxes (CN + global). Lowercase host only. */
|
|
229
|
+
declare const DEFAULT_REGISTER_EMAIL_ALLOWLIST: readonly string[];
|
|
230
|
+
/** Common disposable / throwaway hosts (used when mode is blocklist or as extra deny). */
|
|
231
|
+
declare const DEFAULT_DISPOSABLE_EMAIL_BLOCKLIST: readonly string[];
|
|
232
|
+
type RegisterEmailMode = "allowlist" | "blocklist" | "off";
|
|
233
|
+
interface RegisterEmailPolicy {
|
|
234
|
+
mode: RegisterEmailMode;
|
|
235
|
+
allowlist: readonly string[];
|
|
236
|
+
blocklist: readonly string[];
|
|
237
|
+
}
|
|
238
|
+
interface RegisterEmailPolicyInput {
|
|
239
|
+
mode?: string | null;
|
|
240
|
+
allowlist?: string | readonly string[] | null;
|
|
241
|
+
blocklist?: string | readonly string[] | null;
|
|
242
|
+
}
|
|
243
|
+
declare function normalizeRegisterEmailMode(raw: string | null | undefined): RegisterEmailMode;
|
|
244
|
+
declare function resolveRegisterEmailPolicy(input?: RegisterEmailPolicyInput): RegisterEmailPolicy;
|
|
245
|
+
/** Read VITE_/PUBLIC_/AUTH_REGISTER_* from a static env map (bundler-safe). */
|
|
246
|
+
declare function readRegisterEmailPolicyFromEnv(env?: Record<string, string | undefined>): RegisterEmailPolicy;
|
|
247
|
+
declare function emailDomain(email: string): string | null;
|
|
248
|
+
declare function isValidEmailShape(email: string): boolean;
|
|
249
|
+
type RegisterEmailDecision = {
|
|
250
|
+
ok: true;
|
|
251
|
+
domain: string;
|
|
252
|
+
} | {
|
|
253
|
+
ok: false;
|
|
254
|
+
reason: "invalid" | "not_allowed" | "disposable";
|
|
255
|
+
domain?: string;
|
|
256
|
+
};
|
|
257
|
+
/**
|
|
258
|
+
* Enforce register email policy. `off` still rejects disposable hosts when
|
|
259
|
+
* `blocklist` is non-empty (defense in depth); pass `blocklist: []` to disable.
|
|
260
|
+
*/
|
|
261
|
+
declare function evaluateRegisterEmail(email: string, policy?: RegisterEmailPolicy): RegisterEmailDecision;
|
|
262
|
+
declare function registerEmailRejectionMessage(decision: RegisterEmailDecision): string;
|
|
263
|
+
/**
|
|
264
|
+
* Human-readable domain list for the register form (allowlist mode only).
|
|
265
|
+
* Returns null when domains are not restricted to an allowlist.
|
|
266
|
+
*/
|
|
267
|
+
declare function formatAllowedEmailDomains(policy: RegisterEmailPolicy, options?: {
|
|
268
|
+
max?: number;
|
|
269
|
+
}): string | null;
|
|
270
|
+
/** Short policy note under the email field on the register form. */
|
|
271
|
+
declare function registerEmailDomainsHint(policy: RegisterEmailPolicy, labels?: {
|
|
272
|
+
allowedDomainsPrefix?: string;
|
|
273
|
+
allowedDomainsOpen?: string;
|
|
274
|
+
allowedDomainsBlocklist?: string;
|
|
275
|
+
}): string | null;
|
|
276
|
+
/** Public policy document from Auth Gateway `GET /api/register-policy`. */
|
|
277
|
+
interface PublicRegisterPolicyResponse {
|
|
278
|
+
mode?: string;
|
|
279
|
+
allowlist?: string[];
|
|
280
|
+
blocklist?: string[];
|
|
281
|
+
ipDailyLimit?: number;
|
|
282
|
+
codeHourlyLimit?: number;
|
|
283
|
+
enabled?: boolean;
|
|
284
|
+
}
|
|
285
|
+
/**
|
|
286
|
+
* Fetch live register policy from Auth Gateway (or any host that serves `/api/register-policy`).
|
|
287
|
+
* Falls back to built-in defaults when the endpoint is missing.
|
|
288
|
+
*/
|
|
289
|
+
declare function fetchRegisterEmailPolicy(apiBase: string, init?: RequestInit): Promise<RegisterEmailPolicy>;
|
|
290
|
+
|
|
183
291
|
/**
|
|
184
292
|
* Logto Experience API (Headless) adapter.
|
|
185
293
|
* Prefer same-origin Experience base (SPA proxies /api/experience) so cookies
|
|
@@ -198,12 +306,15 @@ declare function createLogtoDirectSignInRequest(directSignIn: string): SocialSig
|
|
|
198
306
|
declare class LogtoExperienceAdapter implements LoginExperienceAdapter {
|
|
199
307
|
readonly provider = "logto";
|
|
200
308
|
readonly capabilities: readonly LoginExperienceCapability[];
|
|
309
|
+
emailPolicy: RegisterEmailPolicy;
|
|
201
310
|
experiencePasswordSignIn(input: ExperiencePasswordSignInInput): Promise<ExperiencePasswordSignInResult>;
|
|
202
311
|
/**
|
|
203
312
|
* Register with username + password via NewPasswordIdentity.
|
|
204
313
|
* Email/phone self-register requires verification codes — use social or invite instead.
|
|
205
314
|
*/
|
|
206
315
|
experiencePasswordSignUp(input: ExperiencePasswordSignUpInput): Promise<ExperiencePasswordSignUpResult>;
|
|
316
|
+
sendRegisterEmailCode(input: ExperienceEmailSignUpSendCodeInput): Promise<ExperienceEmailSignUpSendCodeResult>;
|
|
317
|
+
experienceEmailPasswordSignUp(input: ExperienceEmailSignUpCompleteInput): Promise<ExperiencePasswordSignUpResult>;
|
|
207
318
|
fetchSocialConnectors(input: FetchSocialConnectorsInput): Promise<ExperienceSocialConnector[]>;
|
|
208
319
|
createSocialSignInRequest(target: string): SocialSignInRequest;
|
|
209
320
|
}
|
|
@@ -340,6 +451,23 @@ interface HeadlessLoginLabels {
|
|
|
340
451
|
passwordMismatch?: string;
|
|
341
452
|
registerTitle?: string;
|
|
342
453
|
registerSubtitle?: string;
|
|
454
|
+
registerWithEmail?: string;
|
|
455
|
+
registerWithUsername?: string;
|
|
456
|
+
emailPlaceholder?: string;
|
|
457
|
+
verificationCodePlaceholder?: string;
|
|
458
|
+
sendCode?: string;
|
|
459
|
+
resendCode?: string;
|
|
460
|
+
/** Prefix before the allowlisted domain list, e.g. "Allowed email domains". */
|
|
461
|
+
allowedDomainsPrefix?: string;
|
|
462
|
+
/** Shown when mode is off / unrestricted (aside from disposable blocklist). */
|
|
463
|
+
allowedDomainsOpen?: string;
|
|
464
|
+
/** Shown when only disposable domains are blocked. */
|
|
465
|
+
allowedDomainsBlocklist?: string;
|
|
466
|
+
/**
|
|
467
|
+
* Desktop/mobile system-browser social login: tell the user to finish in the browser
|
|
468
|
+
* and return to the app (loopback / deep link callback).
|
|
469
|
+
*/
|
|
470
|
+
waitingExternalBrowser?: string;
|
|
343
471
|
}
|
|
344
472
|
interface HeadlessLoginPanelProps {
|
|
345
473
|
config: Partial<LuminaryIdpConfig>;
|
|
@@ -349,9 +477,19 @@ interface HeadlessLoginPanelProps {
|
|
|
349
477
|
productName: string;
|
|
350
478
|
logoSrc?: string;
|
|
351
479
|
labels?: HeadlessLoginLabels;
|
|
480
|
+
/**
|
|
481
|
+
* Card copy locale (`en` | `zh-CN` | `zh-TW` | `es`, plus `zh` → zh-CN).
|
|
482
|
+
* Explicit `labels` still override individual keys.
|
|
483
|
+
*/
|
|
484
|
+
locale?: string;
|
|
352
485
|
returnUrl?: string;
|
|
353
|
-
/** Prefer popup (default) for reauth;
|
|
354
|
-
mode?: "popup" | "redirect";
|
|
486
|
+
/** Prefer popup (default) for reauth; redirect for full-page SPA; external for desktop/mobile system browser (RFC 8252). */
|
|
487
|
+
mode?: "popup" | "redirect" | "external";
|
|
488
|
+
/**
|
|
489
|
+
* Open an authorize URL in the OS browser / Custom Tabs / ASWebAuthenticationSession.
|
|
490
|
+
* Required when `mode="external"` (Google / GitHub / hosted SSO). Password Headless stays in-app.
|
|
491
|
+
*/
|
|
492
|
+
openExternalUrl?: (url: string) => void | Promise<void>;
|
|
355
493
|
/**
|
|
356
494
|
* Show Experience social connectors (Google / GitHub / …).
|
|
357
495
|
* Default `true`. Set `false` for admin / internal consoles that only allow
|
|
@@ -361,11 +499,26 @@ interface HeadlessLoginPanelProps {
|
|
|
361
499
|
*/
|
|
362
500
|
showSocialConnectors?: boolean;
|
|
363
501
|
/**
|
|
364
|
-
* Show self-register switch + register form
|
|
502
|
+
* Show self-register switch + register form.
|
|
365
503
|
* Default `true` for end-user product logins. Set `false` for admin / ops consoles.
|
|
366
|
-
* Hosted OIDC adapters without passwordSignUp hide register automatically.
|
|
367
504
|
*/
|
|
368
505
|
showRegister?: boolean;
|
|
506
|
+
/**
|
|
507
|
+
* Email domain policy for self-register.
|
|
508
|
+
* If omitted, the panel loads `GET {experienceApiBase}/api/register-policy` when available,
|
|
509
|
+
* otherwise uses built-in consumer allowlist defaults.
|
|
510
|
+
*/
|
|
511
|
+
registerEmailPolicy?: RegisterEmailPolicy;
|
|
512
|
+
/**
|
|
513
|
+
* When true (default), fetch live policy from Auth Gateway `/api/register-policy`.
|
|
514
|
+
* Set false to use only `registerEmailPolicy` / built-in defaults (e.g. local auth-dev-proxy).
|
|
515
|
+
*/
|
|
516
|
+
fetchRegisterPolicy?: boolean;
|
|
517
|
+
/**
|
|
518
|
+
* Optional CAPTCHA token provider (Cloudflare Turnstile / reCAPTCHA).
|
|
519
|
+
* Token is sent as `captchaToken` on Experience Register init when Logto bot protection is on.
|
|
520
|
+
*/
|
|
521
|
+
getCaptchaToken?: () => Promise<string | undefined>;
|
|
369
522
|
/**
|
|
370
523
|
* Social providers (when `showSocialConnectors` is not `false`):
|
|
371
524
|
* - omit / `"auto"` — load enabled connectors from IdP (google, github, x, …)
|
|
@@ -393,7 +546,7 @@ interface HeadlessLoginPanelProps {
|
|
|
393
546
|
}
|
|
394
547
|
/** Shared default accent for product login panels (shared/brand --lw-primary). */
|
|
395
548
|
declare const DEFAULT_LOGIN_THEME_COLOR = "#1677ff";
|
|
396
|
-
declare function HeadlessLoginPanel({ config, experienceAdapter: experienceAdapterProp, productName, logoSrc, labels: labelsProp, returnUrl, mode, showSocialConnectors, showRegister, socialProviders, showCancel, onCancel, onOidcSession, onExperienceRedirect, footer, className, style, themeColor, }: HeadlessLoginPanelProps): react.JSX.Element;
|
|
549
|
+
declare function HeadlessLoginPanel({ config, experienceAdapter: experienceAdapterProp, productName, logoSrc, labels: labelsProp, locale, returnUrl, mode, openExternalUrl, showSocialConnectors, showRegister, registerEmailPolicy: registerEmailPolicyProp, fetchRegisterPolicy, getCaptchaToken, socialProviders, showCancel, onCancel, onOidcSession, onExperienceRedirect, footer, className, style, themeColor, }: HeadlessLoginPanelProps): react.JSX.Element;
|
|
397
550
|
|
|
398
551
|
interface ReauthOverlayProps {
|
|
399
552
|
config: Partial<LuminaryIdpConfig>;
|
|
@@ -436,6 +589,43 @@ declare function useAuthGate(): AuthGateContextValue;
|
|
|
436
589
|
/** Optional hook — returns null outside provider (for shared API helpers). */
|
|
437
590
|
declare function useAuthGateOptional(): AuthGateContextValue | null;
|
|
438
591
|
|
|
592
|
+
/** Locales shipped with the shared login card. Products may pass a wider menu. */
|
|
593
|
+
type LoginLocale = "en" | "zh-CN" | "zh-TW" | "es";
|
|
594
|
+
interface LoginLocaleOption {
|
|
595
|
+
code: string;
|
|
596
|
+
label: string;
|
|
597
|
+
short: string;
|
|
598
|
+
}
|
|
599
|
+
declare const DEFAULT_LOGIN_LOCALES: readonly LoginLocaleOption[];
|
|
600
|
+
/** Normalize product locale tags (`zh`, `zh-Hans`) onto the card dictionary. */
|
|
601
|
+
declare function normalizeLoginLocale(locale: string | undefined): LoginLocale;
|
|
602
|
+
/** Card copy for a locale. English is the panel default, so `en` returns `{}`. */
|
|
603
|
+
declare function loginLabels(locale: string | undefined): HeadlessLoginLabels;
|
|
604
|
+
|
|
605
|
+
interface LoginLanguageSwitcherProps {
|
|
606
|
+
locale: string;
|
|
607
|
+
onChange: (locale: string) => void;
|
|
608
|
+
locales?: readonly LoginLocaleOption[];
|
|
609
|
+
/** Accessible name, e.g. "Language" / "语言". */
|
|
610
|
+
label?: string;
|
|
611
|
+
variant?: "default" | "onDark";
|
|
612
|
+
}
|
|
613
|
+
declare function LoginLanguageSwitcher({ locale, onChange, locales, label, variant, }: LoginLanguageSwitcherProps): react.JSX.Element;
|
|
614
|
+
|
|
615
|
+
type LoginCanvasTone = "console" | "vista" | "data" | "edu";
|
|
616
|
+
interface LoginCanvasProps {
|
|
617
|
+
tone: LoginCanvasTone;
|
|
618
|
+
locale: string;
|
|
619
|
+
onLocaleChange: (locale: string) => void;
|
|
620
|
+
locales?: readonly LoginLocaleOption[];
|
|
621
|
+
languageLabel?: string;
|
|
622
|
+
/** Full-width slot for split layouts (hero + card). Default centers a single card. */
|
|
623
|
+
fill?: boolean;
|
|
624
|
+
decor?: ReactNode;
|
|
625
|
+
children: ReactNode;
|
|
626
|
+
}
|
|
627
|
+
declare function LoginCanvas({ tone, locale, onLocaleChange, locales, languageLabel, fill, decor, children, }: LoginCanvasProps): react.JSX.Element;
|
|
628
|
+
|
|
439
629
|
interface PostLoginPathOptions {
|
|
440
630
|
/** sessionStorage key (product-scoped), e.g. `dv:postLoginPath` */
|
|
441
631
|
storageKey: string;
|
|
@@ -456,4 +646,4 @@ declare function createPostLoginPathHelpers(options: PostLoginPathOptions): {
|
|
|
456
646
|
isUnsafeReturnPath: (path: string) => boolean;
|
|
457
647
|
};
|
|
458
648
|
|
|
459
|
-
export { type AuthGateConfig, type AuthGatePhase, AuthGateProvider, type AuthGateProviderProps, type AuthGateSnapshot, DEFAULT_LOGIN_THEME_COLOR, type ExperienceIdentifierType, type ExperiencePasswordSignInInput, type ExperiencePasswordSignInResult, type ExperiencePasswordSignUpInput, type ExperiencePasswordSignUpResult, type ExperienceSocialConnector, type FetchSocialConnectorsInput, type HeadlessLoginLabels, HeadlessLoginPanel, type HeadlessLoginPanelProps, HostedOidcExperienceAdapter, LOGIN_EXPERIENCE_CAPABILITIES, type LoginExperienceAdapter, type LoginExperienceCapability, type LoginExperienceProvider, LogtoExperienceAdapter, LuminaryAuthProvider, type LuminaryAuthProviderProps, type LuminaryAuthSession, type LuminaryIdpConfig, type PostLoginPathOptions, ReauthOverlay, type ReauthOverlayProps, type SignInOptions, type SocialProviderTarget, type SocialSignInRequest, type UnauthorizedDisposition, authGate, clearStoredSession, createLoginExperienceAdapter, createLogtoDirectSignInRequest, createPostLoginPathHelpers, createUserManager, experiencePasswordSignIn, fetchSocialConnectors, getCurrentUser, getStoredAccessToken, handleSignInCallback, handleSignInPopupCallback, isIdpConfigured, isLogtoRegisterUsername, isOidcPopupWindow, prepareSignInRequestUrl, readIdpConfigFromEnv, resetUserManager, resolveExperienceApiBase, resolveIssuer, resolveLoginExperienceAdapter, resolveLoginExperienceProviderFromEnv, sameOriginAuthorizeUrl, signInPopup, signInRedirect, signOutRedirect, useAuthGate, useAuthGateOptional, useLuminaryAuth, withAuthGateRetry };
|
|
649
|
+
export { type AuthGateConfig, type AuthGatePhase, AuthGateProvider, type AuthGateProviderProps, type AuthGateSnapshot, DEFAULT_DISPOSABLE_EMAIL_BLOCKLIST, DEFAULT_LOGIN_LOCALES, DEFAULT_LOGIN_THEME_COLOR, DEFAULT_REGISTER_EMAIL_ALLOWLIST, type ExperienceEmailSignUpCompleteInput, type ExperienceEmailSignUpSendCodeInput, type ExperienceEmailSignUpSendCodeResult, type ExperienceIdentifierType, type ExperiencePasswordSignInInput, type ExperiencePasswordSignInResult, type ExperiencePasswordSignUpInput, type ExperiencePasswordSignUpResult, type ExperienceSocialConnector, type FetchSocialConnectorsInput, type HeadlessLoginLabels, HeadlessLoginPanel, type HeadlessLoginPanelProps, HostedOidcExperienceAdapter, LOGIN_EXPERIENCE_CAPABILITIES, LoginCanvas, type LoginCanvasProps, type LoginCanvasTone, type LoginExperienceAdapter, type LoginExperienceCapability, type LoginExperienceProvider, LoginLanguageSwitcher, type LoginLanguageSwitcherProps, type LoginLocale, type LoginLocaleOption, LogtoExperienceAdapter, LuminaryAuthProvider, type LuminaryAuthProviderProps, type LuminaryAuthSession, type LuminaryIdpConfig, type PostLoginPathOptions, type PublicRegisterPolicyResponse, ReauthOverlay, type ReauthOverlayProps, type RegisterEmailDecision, type RegisterEmailMode, type RegisterEmailPolicy, type RegisterEmailPolicyInput, type SignInOptions, type SocialProviderTarget, type SocialSignInRequest, type UnauthorizedDisposition, authGate, clearStoredSession, createLoginExperienceAdapter, createLogtoDirectSignInRequest, createPostLoginPathHelpers, createUserManager, emailDomain, evaluateRegisterEmail, experiencePasswordSignIn, fetchRegisterEmailPolicy, fetchSocialConnectors, formatAllowedEmailDomains, getCurrentUser, getStoredAccessToken, handleSignInCallback, handleSignInPopupCallback, isIdpConfigured, isLogtoRegisterUsername, isOidcPopupWindow, isValidEmailShape, loginLabels, normalizeLoginLocale, normalizeRegisterEmailMode, prepareSignInRequestUrl, readIdpConfigFromEnv, readRegisterEmailPolicyFromEnv, registerEmailDomainsHint, registerEmailRejectionMessage, resetUserManager, resolveExperienceApiBase, resolveIssuer, resolveLoginExperienceAdapter, resolveLoginExperienceProviderFromEnv, resolveRegisterEmailPolicy, sameOriginAuthorizeUrl, signInPopup, signInRedirect, signOutRedirect, useAuthGate, useAuthGateOptional, useLuminaryAuth, withAuthGateRetry };
|