@authon/js 0.1.13 → 0.1.14
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 +100 -0
- package/dist/{index.mjs → index.cjs} +36 -43
- package/dist/index.cjs.map +1 -0
- package/dist/index.js +6 -69
- package/dist/index.js.map +1 -0
- package/package.json +33 -13
- /package/dist/{index.d.mts → index.d.cts} +0 -0
package/README.md
ADDED
|
@@ -0,0 +1,100 @@
|
|
|
1
|
+
# @authon/js
|
|
2
|
+
|
|
3
|
+
Core browser SDK for [Authon](https://authon.dev) — ShadowDOM login modal, OAuth flows, and session management.
|
|
4
|
+
|
|
5
|
+
## Install
|
|
6
|
+
|
|
7
|
+
```bash
|
|
8
|
+
npm install @authon/js
|
|
9
|
+
# or
|
|
10
|
+
pnpm add @authon/js
|
|
11
|
+
```
|
|
12
|
+
|
|
13
|
+
## Quick Start
|
|
14
|
+
|
|
15
|
+
```ts
|
|
16
|
+
import { Authon } from '@authon/js';
|
|
17
|
+
|
|
18
|
+
const authon = new Authon('pk_live_...');
|
|
19
|
+
|
|
20
|
+
// Open the sign-in modal
|
|
21
|
+
await authon.openSignIn();
|
|
22
|
+
|
|
23
|
+
// Listen for auth events
|
|
24
|
+
authon.on('signedIn', (user) => {
|
|
25
|
+
console.log('Signed in:', user.email);
|
|
26
|
+
});
|
|
27
|
+
|
|
28
|
+
authon.on('signedOut', () => {
|
|
29
|
+
console.log('Signed out');
|
|
30
|
+
});
|
|
31
|
+
|
|
32
|
+
// Email/password sign-in
|
|
33
|
+
const user = await authon.signInWithEmail('user@example.com', 'password');
|
|
34
|
+
|
|
35
|
+
// OAuth sign-in (opens popup)
|
|
36
|
+
await authon.signInWithOAuth('google');
|
|
37
|
+
|
|
38
|
+
// Get current user and token
|
|
39
|
+
const currentUser = authon.getUser();
|
|
40
|
+
const token = authon.getToken();
|
|
41
|
+
|
|
42
|
+
// Sign out
|
|
43
|
+
await authon.signOut();
|
|
44
|
+
```
|
|
45
|
+
|
|
46
|
+
## Configuration
|
|
47
|
+
|
|
48
|
+
```ts
|
|
49
|
+
const authon = new Authon('pk_live_...', {
|
|
50
|
+
apiUrl: 'https://api.authon.dev', // Custom API URL
|
|
51
|
+
mode: 'popup', // 'popup' | 'embedded'
|
|
52
|
+
theme: 'auto', // 'light' | 'dark' | 'auto'
|
|
53
|
+
locale: 'en', // Locale for the modal UI
|
|
54
|
+
containerId: 'auth-container', // Container element ID (embedded mode)
|
|
55
|
+
appearance: { // Custom branding overrides
|
|
56
|
+
primaryColorStart: '#7c3aed',
|
|
57
|
+
primaryColorEnd: '#4f46e5',
|
|
58
|
+
borderRadius: 12,
|
|
59
|
+
brandName: 'My App',
|
|
60
|
+
},
|
|
61
|
+
});
|
|
62
|
+
```
|
|
63
|
+
|
|
64
|
+
## API Reference
|
|
65
|
+
|
|
66
|
+
### `Authon` class
|
|
67
|
+
|
|
68
|
+
| Method | Returns | Description |
|
|
69
|
+
|--------|---------|-------------|
|
|
70
|
+
| `openSignIn()` | `Promise<void>` | Open the sign-in modal |
|
|
71
|
+
| `openSignUp()` | `Promise<void>` | Open the sign-up modal |
|
|
72
|
+
| `signInWithEmail(email, password)` | `Promise<AuthonUser>` | Sign in with email/password |
|
|
73
|
+
| `signUpWithEmail(email, password, meta?)` | `Promise<AuthonUser>` | Register with email/password |
|
|
74
|
+
| `signInWithOAuth(provider)` | `Promise<void>` | Start OAuth flow in popup window |
|
|
75
|
+
| `signOut()` | `Promise<void>` | Sign out and clear session |
|
|
76
|
+
| `getUser()` | `AuthonUser \| null` | Get current user |
|
|
77
|
+
| `getToken()` | `string \| null` | Get current access token |
|
|
78
|
+
| `on(event, listener)` | `() => void` | Subscribe to events (returns unsubscribe fn) |
|
|
79
|
+
| `destroy()` | `void` | Clean up resources |
|
|
80
|
+
|
|
81
|
+
### Events
|
|
82
|
+
|
|
83
|
+
| Event | Payload | Description |
|
|
84
|
+
|-------|---------|-------------|
|
|
85
|
+
| `signedIn` | `AuthonUser` | User signed in |
|
|
86
|
+
| `signedOut` | none | User signed out |
|
|
87
|
+
| `tokenRefreshed` | `string` | Access token was refreshed |
|
|
88
|
+
| `error` | `Error` | An error occurred |
|
|
89
|
+
|
|
90
|
+
## ShadowDOM Modal
|
|
91
|
+
|
|
92
|
+
The login modal renders inside a ShadowRoot, preventing CSS conflicts with your application. Branding (colors, logo, border radius, custom CSS) is fetched from your Authon project settings and can be overridden via the `appearance` config.
|
|
93
|
+
|
|
94
|
+
## Documentation
|
|
95
|
+
|
|
96
|
+
[authon.dev/docs](https://authon.dev/docs)
|
|
97
|
+
|
|
98
|
+
## License
|
|
99
|
+
|
|
100
|
+
[MIT](../../LICENSE)
|
|
@@ -1,43 +1,35 @@
|
|
|
1
|
-
|
|
2
|
-
var
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
discord: "Discord",
|
|
10
|
-
x: "X",
|
|
11
|
-
line: "LINE",
|
|
12
|
-
microsoft: "Microsoft"
|
|
1
|
+
"use strict";
|
|
2
|
+
var __defProp = Object.defineProperty;
|
|
3
|
+
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
4
|
+
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
5
|
+
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
6
|
+
var __export = (target, all) => {
|
|
7
|
+
for (var name in all)
|
|
8
|
+
__defProp(target, name, { get: all[name], enumerable: true });
|
|
13
9
|
};
|
|
14
|
-
var
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
discord: { bg: "#5865F2", text: "#ffffff" },
|
|
22
|
-
x: { bg: "#000000", text: "#ffffff" },
|
|
23
|
-
line: { bg: "#06C755", text: "#ffffff" },
|
|
24
|
-
microsoft: { bg: "#ffffff", text: "#1f1f1f" }
|
|
25
|
-
};
|
|
26
|
-
var DEFAULT_BRANDING = {
|
|
27
|
-
primaryColorStart: "#7c3aed",
|
|
28
|
-
primaryColorEnd: "#4f46e5",
|
|
29
|
-
lightBg: "#ffffff",
|
|
30
|
-
lightText: "#111827",
|
|
31
|
-
darkBg: "#0f172a",
|
|
32
|
-
darkText: "#f1f5f9",
|
|
33
|
-
borderRadius: 12,
|
|
34
|
-
showEmailPassword: true,
|
|
35
|
-
showDivider: true,
|
|
36
|
-
showSecuredBy: true,
|
|
37
|
-
locale: "en"
|
|
10
|
+
var __copyProps = (to, from, except, desc) => {
|
|
11
|
+
if (from && typeof from === "object" || typeof from === "function") {
|
|
12
|
+
for (let key of __getOwnPropNames(from))
|
|
13
|
+
if (!__hasOwnProp.call(to, key) && key !== except)
|
|
14
|
+
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
|
15
|
+
}
|
|
16
|
+
return to;
|
|
38
17
|
};
|
|
18
|
+
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
|
19
|
+
|
|
20
|
+
// src/index.ts
|
|
21
|
+
var index_exports = {};
|
|
22
|
+
__export(index_exports, {
|
|
23
|
+
Authon: () => Authon,
|
|
24
|
+
getProviderButtonConfig: () => getProviderButtonConfig
|
|
25
|
+
});
|
|
26
|
+
module.exports = __toCommonJS(index_exports);
|
|
27
|
+
|
|
28
|
+
// src/modal.ts
|
|
29
|
+
var import_shared2 = require("@authon/shared");
|
|
39
30
|
|
|
40
31
|
// src/providers.ts
|
|
32
|
+
var import_shared = require("@authon/shared");
|
|
41
33
|
var PROVIDER_ICONS = {
|
|
42
34
|
google: `<svg viewBox="0 0 24 24" width="20" height="20"><path fill="#4285F4" d="M22.56 12.25c0-.78-.07-1.53-.2-2.25H12v4.26h5.92a5.06 5.06 0 01-2.2 3.32v2.77h3.57c2.08-1.92 3.28-4.74 3.28-8.1z"/><path fill="#34A853" d="M12 23c2.97 0 5.46-.98 7.28-2.66l-3.57-2.77c-.98.66-2.23 1.06-3.71 1.06-2.86 0-5.29-1.93-6.16-4.53H2.18v2.84C3.99 20.53 7.7 23 12 23z"/><path fill="#FBBC05" d="M5.84 14.09c-.22-.66-.35-1.36-.35-2.09s.13-1.43.35-2.09V7.07H2.18C1.43 8.55 1 10.22 1 12s.43 3.45 1.18 4.93l2.85-2.22.81-.62z"/><path fill="#EA4335" d="M12 5.38c1.62 0 3.06.56 4.21 1.64l3.15-3.15C17.45 2.09 14.97 1 12 1 7.7 1 3.99 3.47 2.18 7.07l3.66 2.84c.87-2.6 3.3-4.53 6.16-4.53z"/></svg>`,
|
|
43
35
|
apple: `<svg viewBox="0 0 24 24" width="20" height="20" fill="currentColor"><path d="M17.05 20.28c-.98.95-2.05.88-3.08.4-1.09-.5-2.08-.48-3.24 0-1.44.62-2.2.44-3.06-.4C2.79 15.25 3.51 7.59 9.05 7.31c1.35.07 2.29.74 3.08.8 1.18-.24 2.31-.93 3.57-.84 1.51.12 2.65.72 3.4 1.8-3.12 1.87-2.38 5.98.48 7.13-.57 1.5-1.31 2.99-2.54 4.09zM12.03 7.25c-.15-2.23 1.66-4.07 3.74-4.25.29 2.58-2.34 4.5-3.74 4.25z"/></svg>`,
|
|
@@ -51,10 +43,10 @@ var PROVIDER_ICONS = {
|
|
|
51
43
|
microsoft: `<svg viewBox="0 0 24 24" width="20" height="20"><rect fill="#F25022" x="1" y="1" width="10" height="10"/><rect fill="#7FBA00" x="13" y="1" width="10" height="10"/><rect fill="#00A4EF" x="1" y="13" width="10" height="10"/><rect fill="#FFB900" x="13" y="13" width="10" height="10"/></svg>`
|
|
52
44
|
};
|
|
53
45
|
function getProviderButtonConfig(provider) {
|
|
54
|
-
const colors = PROVIDER_COLORS[provider];
|
|
46
|
+
const colors = import_shared.PROVIDER_COLORS[provider];
|
|
55
47
|
return {
|
|
56
48
|
provider,
|
|
57
|
-
label: `Continue with ${PROVIDER_DISPLAY_NAMES[provider]}`,
|
|
49
|
+
label: `Continue with ${import_shared.PROVIDER_DISPLAY_NAMES[provider]}`,
|
|
58
50
|
bgColor: colors.bg,
|
|
59
51
|
textColor: colors.text,
|
|
60
52
|
iconSvg: PROVIDER_ICONS[provider]
|
|
@@ -78,7 +70,7 @@ var ModalRenderer = class {
|
|
|
78
70
|
constructor(options) {
|
|
79
71
|
this.mode = options.mode;
|
|
80
72
|
this.theme = options.theme || "auto";
|
|
81
|
-
this.branding = { ...DEFAULT_BRANDING, ...options.branding };
|
|
73
|
+
this.branding = { ...import_shared2.DEFAULT_BRANDING, ...options.branding };
|
|
82
74
|
this.onProviderClick = options.onProviderClick;
|
|
83
75
|
this.onEmailSubmit = options.onEmailSubmit;
|
|
84
76
|
this.onClose = options.onClose;
|
|
@@ -90,7 +82,7 @@ var ModalRenderer = class {
|
|
|
90
82
|
this.enabledProviders = providers;
|
|
91
83
|
}
|
|
92
84
|
setBranding(branding) {
|
|
93
|
-
this.branding = { ...DEFAULT_BRANDING, ...branding };
|
|
85
|
+
this.branding = { ...import_shared2.DEFAULT_BRANDING, ...branding };
|
|
94
86
|
}
|
|
95
87
|
open(view = "signIn") {
|
|
96
88
|
if (this.shadowRoot && this.hostElement) {
|
|
@@ -168,7 +160,6 @@ var ModalRenderer = class {
|
|
|
168
160
|
switchView(view) {
|
|
169
161
|
if (!this.shadowRoot || view === this.currentView) return;
|
|
170
162
|
this.currentView = view;
|
|
171
|
-
const isSignUp = view === "signUp";
|
|
172
163
|
const inner = this.shadowRoot.getElementById("modal-inner");
|
|
173
164
|
if (!inner) return;
|
|
174
165
|
inner.style.opacity = "0";
|
|
@@ -821,7 +812,9 @@ var Authon = class {
|
|
|
821
812
|
return `API ${path}: ${res.status}`;
|
|
822
813
|
}
|
|
823
814
|
};
|
|
824
|
-
export
|
|
815
|
+
// Annotate the CommonJS export names for ESM import in node:
|
|
816
|
+
0 && (module.exports = {
|
|
825
817
|
Authon,
|
|
826
818
|
getProviderButtonConfig
|
|
827
|
-
};
|
|
819
|
+
});
|
|
820
|
+
//# sourceMappingURL=index.cjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/index.ts","../src/modal.ts","../src/providers.ts","../src/session.ts","../src/authon.ts"],"sourcesContent":["export { Authon } from './authon';\nexport type { AuthonConfig, AuthonEvents, AuthonEventType } from './types';\nexport { getProviderButtonConfig } from './providers';\nexport type { ProviderButtonConfig } from './providers';\n","import type { BrandingConfig, OAuthProviderType } from '@authon/shared';\nimport { DEFAULT_BRANDING } from '@authon/shared';\nimport { getProviderButtonConfig } from './providers';\n\nexport class ModalRenderer {\n private shadowRoot: ShadowRoot | null = null;\n private hostElement: HTMLDivElement | null = null;\n private containerElement: HTMLElement | null = null;\n private mode: 'popup' | 'embedded';\n private theme: 'light' | 'dark' | 'auto';\n private branding: BrandingConfig;\n private enabledProviders: OAuthProviderType[] = [];\n private currentView: 'signIn' | 'signUp' = 'signIn';\n private onProviderClick: (provider: OAuthProviderType) => void;\n private onEmailSubmit: (email: string, password: string, isSignUp: boolean) => void;\n private onClose: () => void;\n private escHandler: ((e: KeyboardEvent) => void) | null = null;\n\n constructor(options: {\n mode: 'popup' | 'embedded';\n theme?: 'light' | 'dark' | 'auto';\n containerId?: string;\n branding?: BrandingConfig;\n onProviderClick: (provider: OAuthProviderType) => void;\n onEmailSubmit: (email: string, password: string, isSignUp: boolean) => void;\n onClose: () => void;\n }) {\n this.mode = options.mode;\n this.theme = options.theme || 'auto';\n this.branding = { ...DEFAULT_BRANDING, ...options.branding };\n this.onProviderClick = options.onProviderClick;\n this.onEmailSubmit = options.onEmailSubmit;\n this.onClose = options.onClose;\n\n if (options.mode === 'embedded' && options.containerId) {\n this.containerElement = document.getElementById(options.containerId);\n }\n }\n\n setProviders(providers: OAuthProviderType[]): void {\n this.enabledProviders = providers;\n }\n\n setBranding(branding: BrandingConfig): void {\n this.branding = { ...DEFAULT_BRANDING, ...branding };\n }\n\n open(view: 'signIn' | 'signUp' = 'signIn'): void {\n if (this.shadowRoot && this.hostElement) {\n // Modal already open — smooth in-place view switch\n this.switchView(view);\n } else {\n this.currentView = view;\n this.render(view);\n }\n }\n\n close(): void {\n if (this.escHandler) {\n document.removeEventListener('keydown', this.escHandler);\n this.escHandler = null;\n }\n if (this.hostElement) {\n this.hostElement.remove();\n this.hostElement = null;\n this.shadowRoot = null;\n }\n if (this.containerElement) {\n this.containerElement.innerHTML = '';\n }\n }\n\n showError(message: string): void {\n if (!this.shadowRoot) return;\n this.clearError();\n const errorEl = this.shadowRoot.getElementById('email-form');\n if (errorEl) {\n const errDiv = document.createElement('div');\n errDiv.id = 'authon-error-msg';\n errDiv.className = 'error-msg';\n errDiv.textContent = message;\n errorEl.appendChild(errDiv);\n }\n }\n\n showBanner(message: string, type: 'error' | 'warning' = 'error'): void {\n if (!this.shadowRoot) return;\n this.clearBanner();\n const inner = this.shadowRoot.getElementById('modal-inner');\n if (!inner) return;\n const banner = document.createElement('div');\n banner.id = 'authon-banner';\n banner.className = type === 'warning' ? 'banner-warning' : 'error-msg';\n banner.textContent = message;\n inner.insertBefore(banner, inner.firstChild);\n }\n\n clearBanner(): void {\n if (!this.shadowRoot) return;\n this.shadowRoot.getElementById('authon-banner')?.remove();\n }\n\n clearError(): void {\n if (!this.shadowRoot) return;\n this.shadowRoot.getElementById('authon-error-msg')?.remove();\n }\n\n showLoading(): void {\n if (!this.shadowRoot) return;\n this.hideLoading();\n const overlay = document.createElement('div');\n overlay.id = 'authon-loading-overlay';\n overlay.innerHTML = `\n <div class=\"loading-spinner\">\n <div class=\"loading-ring\"></div>\n <div class=\"loading-ring\"></div>\n <div class=\"loading-ring\"></div>\n </div>\n <div class=\"loading-text\">Signing in<span class=\"loading-dots\"><span></span><span></span><span></span></span></div>\n `;\n this.shadowRoot.querySelector('.modal-container')?.appendChild(overlay);\n }\n\n hideLoading(): void {\n if (!this.shadowRoot) return;\n this.shadowRoot.getElementById('authon-loading-overlay')?.remove();\n }\n\n // ── Smooth view switch (no flicker) ──\n\n private switchView(view: 'signIn' | 'signUp'): void {\n if (!this.shadowRoot || view === this.currentView) return;\n this.currentView = view;\n\n const inner = this.shadowRoot.getElementById('modal-inner');\n if (!inner) return;\n\n // Cross-fade: fade out → update → fade in\n inner.style.opacity = '0';\n inner.style.transform = 'translateY(-4px)';\n\n setTimeout(() => {\n inner.innerHTML = this.buildInnerContent(view);\n this.attachInnerEvents(view);\n // Trigger reflow, then animate in\n void inner.offsetHeight;\n inner.style.opacity = '1';\n inner.style.transform = 'translateY(0)';\n }, 140);\n }\n\n // ── Render ──\n\n private render(view: 'signIn' | 'signUp'): void {\n const host = document.createElement('div');\n host.setAttribute('data-authon-modal', '');\n this.hostElement = host;\n\n if (this.mode === 'popup') {\n document.body.appendChild(host);\n } else if (this.containerElement) {\n this.containerElement.appendChild(host);\n }\n\n this.shadowRoot = host.attachShadow({ mode: 'open' });\n this.shadowRoot.innerHTML = this.buildShell(view);\n this.attachInnerEvents(view);\n this.attachShellEvents();\n }\n\n // ── HTML builders ──\n\n /** Shell = style + backdrop + modal-container (stable across view switches) */\n private buildShell(view: 'signIn' | 'signUp'): string {\n const popupWrapper =\n this.mode === 'popup'\n ? `<div class=\"backdrop\" id=\"backdrop\"></div>`\n : '';\n\n return `\n <style>${this.buildCSS()}</style>\n ${popupWrapper}\n <div class=\"modal-container\" role=\"dialog\" aria-modal=\"true\">\n <div id=\"modal-inner\" class=\"modal-inner\">\n ${this.buildInnerContent(view)}\n </div>\n </div>\n `;\n }\n\n /** Inner content = everything inside the modal that changes per view */\n private buildInnerContent(view: 'signIn' | 'signUp'): string {\n const b = this.branding;\n const isSignUp = view === 'signUp';\n const title = isSignUp ? 'Create your account' : 'Welcome back';\n const subtitle = isSignUp ? 'Already have an account?' : \"Don't have an account?\";\n const subtitleLink = isSignUp ? 'Sign in' : 'Sign up';\n\n const dark = this.isDark();\n\n // SignUp view: hide providers, show only email form\n const showProviders = !isSignUp;\n\n const providerButtons = showProviders\n ? this.enabledProviders\n .filter((p) => !b.hiddenProviders?.includes(p))\n .map((p) => {\n const config = getProviderButtonConfig(p);\n const isWhiteBg = config.bgColor === '#ffffff';\n const btnBg = dark && isWhiteBg ? '#f8fafc' : config.bgColor;\n const btnBorder = isWhiteBg ? (dark ? '#475569' : '#e5e7eb') : config.bgColor;\n return `<button class=\"provider-btn\" data-provider=\"${p}\" style=\"background:${btnBg};color:${config.textColor};border:1px solid ${btnBorder}\">\n <span class=\"provider-icon\">${config.iconSvg}</span>\n <span>${config.label}</span>\n </button>`;\n })\n .join('')\n : '';\n\n const divider =\n showProviders && b.showDivider !== false && b.showEmailPassword !== false\n ? `<div class=\"divider\"><span>or</span></div>`\n : '';\n\n const emailForm =\n b.showEmailPassword !== false\n ? `<form class=\"email-form\" id=\"email-form\">\n <input type=\"email\" placeholder=\"Email address\" name=\"email\" required class=\"input\" autocomplete=\"email\" />\n <input type=\"password\" placeholder=\"Password\" name=\"password\" required class=\"input\" autocomplete=\"${isSignUp ? 'new-password' : 'current-password'}\" />\n ${isSignUp ? '<p class=\"password-hint\">Must contain uppercase, lowercase, and a number (min 8 chars)</p>' : ''}\n <button type=\"submit\" class=\"submit-btn\">${isSignUp ? 'Sign up' : 'Sign in'}</button>\n </form>`\n : '';\n\n const footer =\n b.termsUrl || b.privacyUrl\n ? `<div class=\"footer\">\n ${b.termsUrl ? `<a href=\"${b.termsUrl}\" target=\"_blank\">Terms of Service</a>` : ''}\n ${b.termsUrl && b.privacyUrl ? ' · ' : ''}\n ${b.privacyUrl ? `<a href=\"${b.privacyUrl}\" target=\"_blank\">Privacy Policy</a>` : ''}\n </div>`\n : '';\n\n const titleHtml = isSignUp\n ? `<div class=\"title-row\">\n <button class=\"back-btn\" id=\"back-btn\" type=\"button\" aria-label=\"Back to sign in\">\n <svg width=\"20\" height=\"20\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\"><path d=\"M19 12H5\"/><path d=\"m12 19-7-7 7-7\"/></svg>\n </button>\n <h2 class=\"title\">${title}</h2>\n </div>`\n : `<h2 class=\"title\">${title}</h2>`;\n\n return `\n ${b.logoDataUrl ? `<img src=\"${b.logoDataUrl}\" alt=\"Logo\" class=\"logo\" />` : ''}\n ${titleHtml}\n ${b.brandName ? `<p class=\"brand-name\">${b.brandName}</p>` : ''}\n ${showProviders ? `<div class=\"providers\">${providerButtons}</div>` : ''}\n ${divider}\n ${emailForm}\n <p class=\"switch-view\">${subtitle} <a href=\"#\" id=\"switch-link\">${subtitleLink}</a></p>\n ${footer}\n ${b.showSecuredBy !== false ? `<div class=\"secured-by\">Secured by <a href=\"https://authon.dev\" target=\"_blank\" rel=\"noopener noreferrer\" class=\"secured-link\">Authon</a></div>` : ''}\n `;\n }\n\n private isDark(): boolean {\n if (this.theme === 'dark') return true;\n if (this.theme === 'light') return false;\n return typeof window !== 'undefined' && window.matchMedia('(prefers-color-scheme: dark)').matches;\n }\n\n private buildCSS(): string {\n const b = this.branding;\n const dark = this.isDark();\n const bg = dark ? (b.darkBg || '#0f172a') : (b.lightBg || '#ffffff');\n const text = dark ? (b.darkText || '#f1f5f9') : (b.lightText || '#111827');\n const mutedText = dark ? '#94a3b8' : '#6b7280';\n const dimText = dark ? '#64748b' : '#9ca3af';\n const borderColor = dark ? '#334155' : '#d1d5db';\n const dividerColor = dark ? '#334155' : '#e5e7eb';\n const inputBg = dark ? '#1e293b' : '#ffffff';\n\n return `\n :host {\n --authon-primary-start: ${b.primaryColorStart || '#7c3aed'};\n --authon-primary-end: ${b.primaryColorEnd || '#4f46e5'};\n --authon-bg: ${bg};\n --authon-text: ${text};\n --authon-muted: ${mutedText};\n --authon-dim: ${dimText};\n --authon-border: ${borderColor};\n --authon-divider: ${dividerColor};\n --authon-input-bg: ${inputBg};\n --authon-radius: ${b.borderRadius ?? 12}px;\n --authon-font: 'Inter', -apple-system, BlinkMacSystemFont, 'Segoe UI', sans-serif;\n font-family: var(--authon-font);\n color: var(--authon-text);\n }\n * { box-sizing: border-box; margin: 0; padding: 0; }\n .backdrop {\n position: fixed; inset: 0; z-index: 99998;\n background: rgba(0,0,0,${dark ? '0.7' : '0.5'}); backdrop-filter: blur(4px);\n animation: fadeIn 0.2s ease;\n }\n .modal-container {\n ${this.mode === 'popup' ? 'position: fixed; top: 50%; left: 50%; transform: translate(-50%, -50%); z-index: 99999; max-height: 90vh; overflow-y: auto;' : ''}\n background: var(--authon-bg);\n color: var(--authon-text);\n border: 1px solid var(--authon-border);\n border-radius: var(--authon-radius);\n padding: 32px;\n width: 400px; max-width: 100%;\n position: ${this.mode === 'popup' ? 'fixed' : 'relative'};\n ${this.mode === 'popup' ? `box-shadow: 0 25px 50px -12px rgba(0,0,0,${dark ? '0.5' : '0.25'}); animation: slideIn 0.3s ease;` : ''}\n }\n .modal-inner {\n transition: opacity 0.14s ease, transform 0.14s ease;\n }\n .logo { display: block; margin: 0 auto 16px; max-height: 48px; }\n .title-row { display: flex; align-items: center; position: relative; margin-bottom: 8px; }\n .title-row .title { flex: 1; margin-bottom: 0; }\n .back-btn {\n position: absolute; left: 0; top: 50%; transform: translateY(-50%);\n background: none; border: none; color: var(--authon-muted);\n cursor: pointer; padding: 4px; border-radius: 6px; display: flex; align-items: center; justify-content: center;\n transition: color 0.15s, background 0.15s;\n }\n .back-btn:hover { color: var(--authon-text); background: var(--authon-divider); }\n .password-hint { font-size: 11px; color: var(--authon-dim); margin: -4px 0 2px; }\n .title { text-align: center; font-size: 24px; font-weight: 700; margin-bottom: 8px; color: var(--authon-text); }\n .brand-name { text-align: center; font-size: 14px; color: var(--authon-muted); margin-bottom: 24px; }\n .providers { display: flex; flex-direction: column; gap: 8px; margin-bottom: 16px; }\n .provider-btn {\n display: flex; align-items: center; gap: 12px;\n width: 100%; padding: 10px 16px; border-radius: calc(var(--authon-radius) * 0.67);\n font-size: 14px; font-weight: 500; cursor: pointer;\n transition: opacity 0.15s, transform 0.1s;\n font-family: var(--authon-font);\n }\n .provider-btn:hover { opacity: 0.9; }\n .provider-btn:active { transform: scale(0.98); }\n .provider-icon { display: flex; align-items: center; flex-shrink: 0; }\n .divider {\n display: flex; align-items: center; gap: 12px;\n margin: 16px 0; color: var(--authon-dim); font-size: 13px;\n }\n .divider::before, .divider::after {\n content: ''; flex: 1; height: 1px; background: var(--authon-divider);\n }\n .email-form { display: flex; flex-direction: column; gap: 10px; }\n .input {\n width: 100%; padding: 10px 14px;\n background: var(--authon-input-bg);\n color: var(--authon-text);\n border: 1px solid var(--authon-border); border-radius: calc(var(--authon-radius) * 0.5);\n font-size: 14px; font-family: var(--authon-font);\n outline: none; transition: border-color 0.15s;\n }\n .input::placeholder { color: var(--authon-dim); }\n .input:focus { border-color: var(--authon-primary-start); box-shadow: 0 0 0 3px rgba(124,58,237,0.15); }\n .submit-btn {\n width: 100%; padding: 10px;\n background: linear-gradient(135deg, var(--authon-primary-start), var(--authon-primary-end));\n color: #fff; border: none; border-radius: calc(var(--authon-radius) * 0.5);\n font-size: 14px; font-weight: 600; cursor: pointer;\n font-family: var(--authon-font); transition: opacity 0.15s;\n }\n .submit-btn:hover { opacity: 0.9; }\n .submit-btn:disabled { opacity: 0.6; cursor: not-allowed; }\n .error-msg {\n margin-top: 8px; padding: 8px 12px;\n background: rgba(239,68,68,0.1); border: 1px solid rgba(239,68,68,0.3);\n border-radius: calc(var(--authon-radius) * 0.33);\n font-size: 13px; color: #ef4444; text-align: center;\n animation: fadeIn 0.15s ease;\n }\n .banner-warning {\n margin-bottom: 16px; padding: 10px 14px;\n background: rgba(245,158,11,0.1); border: 1px solid rgba(245,158,11,0.3);\n border-radius: calc(var(--authon-radius) * 0.33);\n font-size: 13px; color: #f59e0b; text-align: center;\n animation: fadeIn 0.15s ease;\n }\n .switch-view { text-align: center; margin-top: 16px; font-size: 13px; color: var(--authon-muted); }\n .switch-view a { color: var(--authon-primary-start); text-decoration: none; font-weight: 500; }\n .switch-view a:hover { text-decoration: underline; }\n .footer { text-align: center; margin-top: 12px; font-size: 12px; color: var(--authon-dim); }\n .footer a { color: var(--authon-dim); text-decoration: none; }\n .footer a:hover { text-decoration: underline; }\n .secured-by {\n text-align: center; margin-top: 16px;\n font-size: 11px; color: var(--authon-dim);\n }\n .secured-link { font-weight: 600; color: var(--authon-muted); text-decoration: none; }\n .secured-link:hover { text-decoration: underline; }\n /* Loading overlay */\n #authon-loading-overlay {\n position: absolute; inset: 0; z-index: 10;\n background: ${dark ? 'rgba(15,23,42,0.92)' : 'rgba(255,255,255,0.92)'};\n backdrop-filter: blur(2px);\n border-radius: var(--authon-radius);\n display: flex; flex-direction: column; align-items: center; justify-content: center; gap: 20px;\n animation: fadeIn 0.15s ease;\n }\n .loading-spinner { position: relative; width: 48px; height: 48px; }\n .loading-ring {\n position: absolute; inset: 0;\n border: 2.5px solid transparent; border-top-color: var(--authon-primary-start);\n border-radius: 50%; animation: spin 1s cubic-bezier(.55,.15,.45,.85) infinite;\n }\n .loading-ring:nth-child(2) {\n inset: 5px; border-top-color: transparent; border-right-color: var(--authon-primary-end);\n animation-duration: 1.2s; animation-direction: reverse; opacity: .7;\n }\n .loading-ring:nth-child(3) {\n inset: 10px; border-top-color: transparent; border-bottom-color: var(--authon-primary-start);\n animation-duration: .8s; opacity: .4;\n }\n .loading-text { font-size: 14px; font-weight: 500; color: var(--authon-muted); }\n .loading-dots { display: inline-flex; gap: 2px; margin-left: 2px; }\n .loading-dots span {\n width: 3px; height: 3px; border-radius: 50%;\n background: var(--authon-muted); animation: blink 1.4s infinite both;\n }\n .loading-dots span:nth-child(2) { animation-delay: .2s; }\n .loading-dots span:nth-child(3) { animation-delay: .4s; }\n @keyframes spin { to { transform: rotate(360deg); } }\n @keyframes blink { 0%,80%,100% { opacity: .2; } 40% { opacity: 1; } }\n @keyframes fadeIn { from { opacity: 0; } to { opacity: 1; } }\n @keyframes slideIn { from { opacity: 0; transform: translate(-50%, -48%); } to { opacity: 1; transform: translate(-50%, -50%); } }\n ${b.customCss || ''}\n `;\n }\n\n // ── Event binding ──\n\n /** Attach events to shell elements (backdrop, ESC) — called once */\n private attachShellEvents(): void {\n if (!this.shadowRoot) return;\n\n const backdrop = this.shadowRoot.getElementById('backdrop');\n if (backdrop) {\n backdrop.addEventListener('click', () => this.onClose());\n }\n\n if (this.escHandler) {\n document.removeEventListener('keydown', this.escHandler);\n }\n if (this.mode === 'popup') {\n this.escHandler = (e: KeyboardEvent) => {\n if (e.key === 'Escape') this.onClose();\n };\n document.addEventListener('keydown', this.escHandler);\n }\n }\n\n /** Attach events to inner content (buttons, form, switch link) — called on each view */\n private attachInnerEvents(view: 'signIn' | 'signUp'): void {\n if (!this.shadowRoot) return;\n\n // Provider buttons\n this.shadowRoot.querySelectorAll('.provider-btn').forEach((btn) => {\n btn.addEventListener('click', () => {\n const provider = (btn as HTMLElement).dataset.provider as OAuthProviderType;\n this.onProviderClick(provider);\n });\n });\n\n // Email form\n const form = this.shadowRoot.getElementById('email-form') as HTMLFormElement | null;\n if (form) {\n form.addEventListener('submit', (e) => {\n e.preventDefault();\n const formData = new FormData(form);\n this.onEmailSubmit(\n formData.get('email') as string,\n formData.get('password') as string,\n view === 'signUp',\n );\n });\n }\n\n // Back button (signUp → signIn)\n const backBtn = this.shadowRoot.getElementById('back-btn');\n if (backBtn) {\n backBtn.addEventListener('click', () => {\n this.open('signIn');\n });\n }\n\n // Switch view link\n const switchLink = this.shadowRoot.getElementById('switch-link');\n if (switchLink) {\n switchLink.addEventListener('click', (e) => {\n e.preventDefault();\n this.open(view === 'signIn' ? 'signUp' : 'signIn');\n });\n }\n }\n}\n","import { PROVIDER_COLORS, PROVIDER_DISPLAY_NAMES, type OAuthProviderType } from '@authon/shared';\n\nexport interface ProviderButtonConfig {\n provider: OAuthProviderType;\n label: string;\n bgColor: string;\n textColor: string;\n iconSvg: string;\n}\n\nconst PROVIDER_ICONS: Record<OAuthProviderType, string> = {\n google: `<svg viewBox=\"0 0 24 24\" width=\"20\" height=\"20\"><path fill=\"#4285F4\" d=\"M22.56 12.25c0-.78-.07-1.53-.2-2.25H12v4.26h5.92a5.06 5.06 0 01-2.2 3.32v2.77h3.57c2.08-1.92 3.28-4.74 3.28-8.1z\"/><path fill=\"#34A853\" d=\"M12 23c2.97 0 5.46-.98 7.28-2.66l-3.57-2.77c-.98.66-2.23 1.06-3.71 1.06-2.86 0-5.29-1.93-6.16-4.53H2.18v2.84C3.99 20.53 7.7 23 12 23z\"/><path fill=\"#FBBC05\" d=\"M5.84 14.09c-.22-.66-.35-1.36-.35-2.09s.13-1.43.35-2.09V7.07H2.18C1.43 8.55 1 10.22 1 12s.43 3.45 1.18 4.93l2.85-2.22.81-.62z\"/><path fill=\"#EA4335\" d=\"M12 5.38c1.62 0 3.06.56 4.21 1.64l3.15-3.15C17.45 2.09 14.97 1 12 1 7.7 1 3.99 3.47 2.18 7.07l3.66 2.84c.87-2.6 3.3-4.53 6.16-4.53z\"/></svg>`,\n apple: `<svg viewBox=\"0 0 24 24\" width=\"20\" height=\"20\" fill=\"currentColor\"><path d=\"M17.05 20.28c-.98.95-2.05.88-3.08.4-1.09-.5-2.08-.48-3.24 0-1.44.62-2.2.44-3.06-.4C2.79 15.25 3.51 7.59 9.05 7.31c1.35.07 2.29.74 3.08.8 1.18-.24 2.31-.93 3.57-.84 1.51.12 2.65.72 3.4 1.8-3.12 1.87-2.38 5.98.48 7.13-.57 1.5-1.31 2.99-2.54 4.09zM12.03 7.25c-.15-2.23 1.66-4.07 3.74-4.25.29 2.58-2.34 4.5-3.74 4.25z\"/></svg>`,\n kakao: `<svg viewBox=\"0 0 24 24\" width=\"20\" height=\"20\"><path fill=\"#191919\" d=\"M12 3C6.48 3 2 6.36 2 10.43c0 2.62 1.75 4.93 4.37 6.23l-1.12 4.14c-.1.36.31.65.62.44l4.93-3.26c.39.04.79.06 1.2.06 5.52 0 10-3.36 10-7.61C22 6.36 17.52 3 12 3z\"/></svg>`,\n naver: `<svg viewBox=\"0 0 24 24\" width=\"20\" height=\"20\"><path fill=\"#fff\" d=\"M16.27 3H7.73A4.73 4.73 0 003 7.73v8.54A4.73 4.73 0 007.73 21h8.54A4.73 4.73 0 0021 16.27V7.73A4.73 4.73 0 0016.27 3zm-1.84 12.44h-2.1l-2.86-4.15v4.15H7.38V8.56h2.1l2.86 4.15V8.56h2.09v6.88z\"/></svg>`,\n facebook: `<svg viewBox=\"0 0 24 24\" width=\"20\" height=\"20\"><path fill=\"#fff\" d=\"M24 12.07C24 5.41 18.63 0 12 0S0 5.4 0 12.07C0 18.1 4.39 23.1 10.13 24v-8.44H7.08v-3.49h3.04V9.41c0-3.02 1.8-4.7 4.54-4.7 1.31 0 2.68.24 2.68.24v2.97h-1.5c-1.5 0-1.96.93-1.96 1.89v2.26h3.33l-.53 3.49h-2.8V24C19.62 23.1 24 18.1 24 12.07z\"/></svg>`,\n github: `<svg viewBox=\"0 0 24 24\" width=\"20\" height=\"20\" fill=\"#fff\"><path d=\"M12 0C5.37 0 0 5.37 0 12c0 5.31 3.435 9.795 8.205 11.385.6.105.825-.255.825-.57 0-.285-.015-1.23-.015-2.235-3.015.555-3.795-.735-4.035-1.41-.135-.345-.72-1.41-1.23-1.695-.42-.225-1.02-.78-.015-.795.945-.015 1.62.87 1.845 1.23 1.08 1.815 2.805 1.305 3.495.99.105-.78.42-1.305.765-1.605-2.67-.3-5.46-1.335-5.46-5.925 0-1.305.465-2.385 1.23-3.225-.12-.3-.54-1.53.12-3.18 0 0 1.005-.315 3.3 1.23.96-.27 1.98-.405 3-.405s2.04.135 3 .405c2.295-1.56 3.3-1.23 3.3-1.23.66 1.65.24 2.88.12 3.18.765.84 1.23 1.905 1.23 3.225 0 4.605-2.805 5.625-5.475 5.925.435.375.81 1.095.81 2.22 0 1.605-.015 2.895-.015 3.3 0 .315.225.69.825.57A12.02 12.02 0 0024 12c0-6.63-5.37-12-12-12z\"/></svg>`,\n discord: `<svg viewBox=\"0 0 24 24\" width=\"20\" height=\"20\" fill=\"#fff\"><path d=\"M20.32 4.37a19.8 19.8 0 00-4.89-1.52.07.07 0 00-.08.04c-.21.38-.44.87-.61 1.26a18.27 18.27 0 00-5.49 0 12.64 12.64 0 00-.62-1.26.07.07 0 00-.08-.04 19.74 19.74 0 00-4.89 1.52.07.07 0 00-.03.03C1.11 8.39.34 12.28.73 16.12a.08.08 0 00.03.06 19.9 19.9 0 005.99 3.03.08.08 0 00.08-.03c.46-.63.87-1.3 1.22-2a.08.08 0 00-.04-.11 13.1 13.1 0 01-1.87-.9.08.08 0 01-.01-.13c.13-.09.25-.19.37-.29a.07.07 0 01.08-.01c3.93 1.8 8.18 1.8 12.07 0a.07.07 0 01.08 0c.12.1.25.2.37.3a.08.08 0 01-.01.12c-.6.35-1.22.65-1.87.9a.08.08 0 00-.04.1c.36.7.77 1.37 1.22 2a.08.08 0 00.08.03 19.83 19.83 0 006-3.03.08.08 0 00.03-.05c.47-4.87-.78-9.09-3.3-12.84a.06.06 0 00-.03-.03zM8.02 13.62c-1.11 0-2.03-1.02-2.03-2.28 0-1.26.9-2.28 2.03-2.28 1.14 0 2.04 1.03 2.03 2.28 0 1.26-.9 2.28-2.03 2.28zm7.5 0c-1.11 0-2.03-1.02-2.03-2.28 0-1.26.9-2.28 2.03-2.28 1.14 0 2.04 1.03 2.03 2.28 0 1.26-.89 2.28-2.03 2.28z\"/></svg>`,\n x: `<svg viewBox=\"0 0 24 24\" width=\"20\" height=\"20\" fill=\"#fff\"><path d=\"M18.244 2.25h3.308l-7.227 8.26 8.502 11.24H16.17l-5.214-6.817L4.99 21.75H1.68l7.73-8.835L1.254 2.25H8.08l4.713 6.231zm-1.161 17.52h1.833L7.084 4.126H5.117z\"/></svg>`,\n line: `<svg viewBox=\"0 0 24 24\" width=\"20\" height=\"20\" fill=\"#fff\"><path d=\"M19.365 9.863c.349 0 .63.285.63.631 0 .345-.281.63-.63.63H17.61v1.125h1.755c.349 0 .63.283.63.63 0 .344-.281.629-.63.629h-2.386c-.345 0-.627-.285-.627-.629V8.108c0-.345.282-.63.63-.63h2.386c.346 0 .627.285.627.63 0 .349-.281.63-.63.63H17.61v1.125h1.755zm-3.855 3.016c0 .27-.174.51-.432.596-.064.021-.133.031-.199.031-.211 0-.391-.09-.51-.25l-2.443-3.317v2.94c0 .344-.279.629-.631.629-.346 0-.626-.285-.626-.629V8.108c0-.27.173-.51.43-.595.06-.023.136-.033.194-.033.195 0 .375.104.495.254l2.462 3.33V8.108c0-.345.282-.63.63-.63.345 0 .63.285.63.63v4.771zm-5.741 0c0 .344-.282.629-.631.629-.345 0-.627-.285-.627-.629V8.108c0-.345.282-.63.63-.63.346 0 .628.285.628.63v4.771zm-2.466.629H4.917c-.345 0-.63-.285-.63-.629V8.108c0-.345.285-.63.63-.63.348 0 .63.285.63.63v4.141h1.756c.348 0 .629.283.629.63 0 .344-.282.629-.629.629M24 10.314C24 4.943 18.615.572 12 .572S0 4.943 0 10.314c0 4.811 4.27 8.842 10.035 9.608.391.082.923.258 1.058.59.12.301.079.766.038 1.08l-.164 1.02c-.045.301-.24 1.186 1.049.645 1.291-.539 6.916-4.078 9.436-6.975C23.176 14.393 24 12.458 24 10.314\"/></svg>`,\n microsoft: `<svg viewBox=\"0 0 24 24\" width=\"20\" height=\"20\"><rect fill=\"#F25022\" x=\"1\" y=\"1\" width=\"10\" height=\"10\"/><rect fill=\"#7FBA00\" x=\"13\" y=\"1\" width=\"10\" height=\"10\"/><rect fill=\"#00A4EF\" x=\"1\" y=\"13\" width=\"10\" height=\"10\"/><rect fill=\"#FFB900\" x=\"13\" y=\"13\" width=\"10\" height=\"10\"/></svg>`,\n};\n\nexport function getProviderButtonConfig(provider: OAuthProviderType): ProviderButtonConfig {\n const colors = PROVIDER_COLORS[provider];\n return {\n provider,\n label: `Continue with ${PROVIDER_DISPLAY_NAMES[provider]}`,\n bgColor: colors.bg,\n textColor: colors.text,\n iconSvg: PROVIDER_ICONS[provider],\n };\n}\n","import type { AuthonUser, AuthTokens } from '@authon/shared';\n\nexport class SessionManager {\n private accessToken: string | null = null;\n private refreshToken: string | null = null;\n private user: AuthonUser | null = null;\n private refreshTimer: ReturnType<typeof setTimeout> | null = null;\n private apiUrl: string;\n private publishableKey: string;\n\n constructor(publishableKey: string, apiUrl: string) {\n this.publishableKey = publishableKey;\n this.apiUrl = apiUrl;\n }\n\n getToken(): string | null {\n return this.accessToken;\n }\n\n getUser(): AuthonUser | null {\n return this.user;\n }\n\n setSession(tokens: AuthTokens): void {\n this.accessToken = tokens.accessToken;\n this.refreshToken = tokens.refreshToken;\n this.user = tokens.user;\n if (tokens.expiresIn && tokens.expiresIn > 0) {\n this.scheduleRefresh(tokens.expiresIn);\n }\n }\n\n clearSession(): void {\n this.accessToken = null;\n this.refreshToken = null;\n this.user = null;\n if (this.refreshTimer) {\n clearTimeout(this.refreshTimer);\n this.refreshTimer = null;\n }\n }\n\n private scheduleRefresh(expiresIn: number): void {\n if (this.refreshTimer) clearTimeout(this.refreshTimer);\n // Refresh 60 seconds before expiry\n const refreshIn = Math.max((expiresIn - 60) * 1000, 30000);\n this.refreshTimer = setTimeout(() => this.refresh(), refreshIn);\n }\n\n async refresh(): Promise<AuthTokens | null> {\n if (!this.refreshToken) {\n this.clearSession();\n return null;\n }\n try {\n const res = await fetch(`${this.apiUrl}/v1/auth/token/refresh`, {\n method: 'POST',\n headers: {\n 'Content-Type': 'application/json',\n 'x-api-key': this.publishableKey,\n },\n credentials: 'include',\n body: JSON.stringify({ refreshToken: this.refreshToken }),\n });\n if (!res.ok) {\n this.clearSession();\n return null;\n }\n const tokens: AuthTokens = await res.json();\n this.setSession(tokens);\n return tokens;\n } catch {\n this.clearSession();\n return null;\n }\n }\n\n async signOut(): Promise<void> {\n try {\n await fetch(`${this.apiUrl}/v1/auth/signout`, {\n method: 'POST',\n headers: {\n 'Content-Type': 'application/json',\n 'x-api-key': this.publishableKey,\n ...(this.accessToken ? { Authorization: `Bearer ${this.accessToken}` } : {}),\n },\n credentials: 'include',\n });\n } catch {\n // ignore\n }\n this.clearSession();\n }\n\n destroy(): void {\n this.clearSession();\n }\n}\n","import type { AuthonUser, AuthTokens, BrandingConfig, OAuthProviderType } from '@authon/shared';\nimport type { AuthonConfig, AuthonEventType, AuthonEvents } from './types';\nimport { ModalRenderer } from './modal';\nimport { SessionManager } from './session';\n\nexport class Authon {\n private publishableKey: string;\n private config: Required<Omit<AuthonConfig, 'containerId' | 'appearance'>> & {\n containerId?: string;\n appearance?: Partial<BrandingConfig>;\n };\n private session: SessionManager;\n private modal: ModalRenderer | null = null;\n private listeners: Map<string, Set<(...args: unknown[]) => void>> = new Map();\n private branding: BrandingConfig | null = null;\n private providers: OAuthProviderType[] = [];\n private initialized = false;\n\n constructor(publishableKey: string, config?: AuthonConfig) {\n this.publishableKey = publishableKey;\n this.config = {\n apiUrl: config?.apiUrl || 'https://api.authon.dev',\n mode: config?.mode || 'popup',\n theme: config?.theme || 'auto',\n locale: config?.locale || 'en',\n containerId: config?.containerId,\n appearance: config?.appearance,\n };\n this.session = new SessionManager(publishableKey, this.config.apiUrl);\n }\n\n // ── Public API ──\n\n async openSignIn(): Promise<void> {\n await this.ensureInitialized();\n this.getModal().open('signIn');\n }\n\n async openSignUp(): Promise<void> {\n await this.ensureInitialized();\n this.getModal().open('signUp');\n }\n\n async signInWithOAuth(provider: OAuthProviderType): Promise<void> {\n await this.ensureInitialized();\n await this.startOAuthFlow(provider);\n }\n\n async signInWithEmail(email: string, password: string): Promise<AuthonUser> {\n const tokens = await this.apiPost<AuthTokens>('/v1/auth/signin', { email, password });\n this.session.setSession(tokens);\n this.emit('signedIn', tokens.user);\n return tokens.user;\n }\n\n async signUpWithEmail(\n email: string,\n password: string,\n meta?: { displayName?: string },\n ): Promise<AuthonUser> {\n const tokens = await this.apiPost<AuthTokens>('/v1/auth/signup', {\n email,\n password,\n ...meta,\n });\n this.session.setSession(tokens);\n this.emit('signedIn', tokens.user);\n return tokens.user;\n }\n\n async signOut(): Promise<void> {\n await this.session.signOut();\n this.emit('signedOut');\n }\n\n getUser(): AuthonUser | null {\n return this.session.getUser();\n }\n\n getToken(): string | null {\n return this.session.getToken();\n }\n\n on<K extends AuthonEventType>(event: K, listener: AuthonEvents[K]): () => void {\n if (!this.listeners.has(event)) this.listeners.set(event, new Set());\n const set = this.listeners.get(event)!;\n set.add(listener as (...args: unknown[]) => void);\n return () => set.delete(listener as (...args: unknown[]) => void);\n }\n\n destroy(): void {\n this.modal?.close();\n this.session.destroy();\n this.listeners.clear();\n }\n\n // ── Internal ──\n\n private emit(event: string, ...args: unknown[]): void {\n this.listeners.get(event)?.forEach((fn) => fn(...args));\n }\n\n private async ensureInitialized(): Promise<void> {\n if (this.initialized) return;\n try {\n const [branding, providersRes] = await Promise.all([\n this.apiGet<BrandingConfig>('/v1/auth/branding'),\n this.apiGet<{ providers: OAuthProviderType[] }>('/v1/auth/providers'),\n ]);\n this.branding = { ...branding, ...this.config.appearance };\n this.providers = providersRes.providers;\n this.initialized = true;\n } catch (err) {\n this.emit('error', err instanceof Error ? err : new Error(String(err)));\n throw err;\n }\n }\n\n private getModal(): ModalRenderer {\n if (!this.modal) {\n this.modal = new ModalRenderer({\n mode: this.config.mode,\n theme: this.config.theme,\n containerId: this.config.containerId,\n branding: this.branding || undefined,\n onProviderClick: (provider) => this.startOAuthFlow(provider),\n onEmailSubmit: (email, password, isSignUp) => {\n this.modal?.clearError();\n const promise = isSignUp\n ? this.signUpWithEmail(email, password)\n : this.signInWithEmail(email, password);\n promise\n .then(() => this.modal?.close())\n .catch((err) => {\n const msg = err instanceof Error ? err.message : String(err);\n this.modal?.showError(msg || 'Authentication failed');\n this.emit('error', err instanceof Error ? err : new Error(msg));\n });\n },\n onClose: () => this.modal?.close(),\n });\n }\n if (this.branding) this.modal.setBranding(this.branding);\n this.modal.setProviders(this.providers);\n return this.modal;\n }\n\n private async startOAuthFlow(provider: OAuthProviderType): Promise<void> {\n try {\n const redirectUri = `${this.config.apiUrl}/v1/auth/oauth/redirect`;\n const { url, state } = await this.apiGet<{ url: string; state: string }>(\n `/v1/auth/oauth/${provider}/url?redirectUri=${encodeURIComponent(redirectUri)}`,\n );\n\n this.modal?.showLoading();\n\n // Open popup\n const width = 500;\n const height = 700;\n const left = window.screenX + (window.outerWidth - width) / 2;\n const top = window.screenY + (window.outerHeight - height) / 2;\n const popup = window.open(\n url,\n 'authon-oauth',\n `width=${width},height=${height},left=${left},top=${top},toolbar=no,menubar=no`,\n );\n\n if (!popup || popup.closed) {\n this.modal?.hideLoading();\n this.modal?.showBanner(\n 'Pop-up blocked. Please allow pop-ups for this site and try again.',\n 'warning',\n );\n this.emit('error', new Error('Popup was blocked by the browser'));\n return;\n }\n\n let resolved = false;\n let cleaned = false;\n\n const resolve = (tokens: AuthTokens) => {\n if (resolved) return;\n resolved = true;\n cleanup();\n try { if (!popup.closed) popup.close(); } catch { /* ignore */ }\n this.session.setSession(tokens);\n this.modal?.close();\n this.emit('signedIn', tokens.user);\n };\n\n const handleError = (msg: string) => {\n if (resolved) return;\n cleanup();\n this.modal?.hideLoading();\n this.modal?.showError(msg);\n this.emit('error', new Error(msg));\n };\n\n const cleanup = () => {\n if (cleaned) return;\n cleaned = true;\n window.removeEventListener('message', messageHandler);\n if (apiPollTimer) clearInterval(apiPollTimer);\n if (closePollTimer) clearInterval(closePollTimer);\n if (maxTimer) clearTimeout(maxTimer);\n };\n\n // 1. postMessage handler (fast path — Chrome/Firefox)\n const messageHandler = (e: MessageEvent) => {\n if (e.data?.type !== 'authon-oauth-callback') return;\n if (e.data.tokens) {\n resolve(e.data.tokens as AuthTokens);\n }\n };\n window.addEventListener('message', messageHandler);\n\n // 2. API polling (Safari fallback — window.opener severed by COOP)\n const apiPollTimer = setInterval(async () => {\n if (resolved || cleaned) return;\n try {\n const result = await this.apiGet<{ status: string; accessToken?: string; refreshToken?: string; expiresIn?: number; user?: AuthonUser; message?: string }>(\n `/v1/auth/oauth/poll?state=${encodeURIComponent(state)}`,\n );\n if (result.status === 'completed' && result.accessToken) {\n resolve({\n accessToken: result.accessToken,\n refreshToken: result.refreshToken!,\n expiresIn: result.expiresIn!,\n user: result.user!,\n });\n } else if (result.status === 'error') {\n handleError(result.message || 'Authentication failed');\n }\n } catch {\n // Network error — keep polling\n }\n }, 1500);\n\n // 3. Popup close detection\n const closePollTimer = setInterval(() => {\n if (resolved || cleaned) return;\n try {\n if (popup.closed) {\n clearInterval(closePollTimer);\n // Give polling a few more seconds to pick up the result\n setTimeout(() => {\n if (resolved || cleaned) return;\n cleanup();\n this.modal?.hideLoading();\n }, 3000);\n }\n } catch {\n // Cross-origin access error — popup still open\n }\n }, 500);\n\n // 4. Max timeout (3 minutes)\n const maxTimer = setTimeout(() => {\n if (resolved || cleaned) return;\n cleanup();\n this.modal?.hideLoading();\n }, 180_000);\n } catch (err) {\n this.modal?.hideLoading();\n this.emit('error', err instanceof Error ? err : new Error(String(err)));\n }\n }\n\n private async apiGet<T>(path: string): Promise<T> {\n const res = await fetch(`${this.config.apiUrl}${path}`, {\n headers: { 'x-api-key': this.publishableKey },\n credentials: 'include',\n });\n if (!res.ok) throw new Error(await this.parseApiError(res, path));\n return res.json();\n }\n\n private async apiPost<T>(path: string, body?: unknown): Promise<T> {\n const res = await fetch(`${this.config.apiUrl}${path}`, {\n method: 'POST',\n headers: {\n 'Content-Type': 'application/json',\n 'x-api-key': this.publishableKey,\n },\n credentials: 'include',\n body: body ? JSON.stringify(body) : undefined,\n });\n if (!res.ok) throw new Error(await this.parseApiError(res, path));\n return res.json();\n }\n\n private async parseApiError(res: Response, path: string): Promise<string> {\n try {\n const body = await res.json();\n if (Array.isArray(body.message) && body.message.length > 0) {\n return body.message[0];\n }\n if (typeof body.message === 'string' && body.message !== 'Bad Request') {\n return body.message;\n }\n } catch { /* ignore */ }\n return `API ${path}: ${res.status}`;\n }\n}\n"],"mappings":"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","names":["import_shared"]}
|
package/dist/index.js
CHANGED
|
@@ -1,70 +1,8 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
4
|
-
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
5
|
-
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
6
|
-
var __export = (target, all) => {
|
|
7
|
-
for (var name in all)
|
|
8
|
-
__defProp(target, name, { get: all[name], enumerable: true });
|
|
9
|
-
};
|
|
10
|
-
var __copyProps = (to, from, except, desc) => {
|
|
11
|
-
if (from && typeof from === "object" || typeof from === "function") {
|
|
12
|
-
for (let key of __getOwnPropNames(from))
|
|
13
|
-
if (!__hasOwnProp.call(to, key) && key !== except)
|
|
14
|
-
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
|
15
|
-
}
|
|
16
|
-
return to;
|
|
17
|
-
};
|
|
18
|
-
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
|
19
|
-
|
|
20
|
-
// src/index.ts
|
|
21
|
-
var index_exports = {};
|
|
22
|
-
__export(index_exports, {
|
|
23
|
-
Authon: () => Authon,
|
|
24
|
-
getProviderButtonConfig: () => getProviderButtonConfig
|
|
25
|
-
});
|
|
26
|
-
module.exports = __toCommonJS(index_exports);
|
|
27
|
-
|
|
28
|
-
// ../shared/dist/index.mjs
|
|
29
|
-
var PROVIDER_DISPLAY_NAMES = {
|
|
30
|
-
google: "Google",
|
|
31
|
-
apple: "Apple",
|
|
32
|
-
kakao: "Kakao",
|
|
33
|
-
naver: "Naver",
|
|
34
|
-
facebook: "Facebook",
|
|
35
|
-
github: "GitHub",
|
|
36
|
-
discord: "Discord",
|
|
37
|
-
x: "X",
|
|
38
|
-
line: "LINE",
|
|
39
|
-
microsoft: "Microsoft"
|
|
40
|
-
};
|
|
41
|
-
var PROVIDER_COLORS = {
|
|
42
|
-
google: { bg: "#ffffff", text: "#1f1f1f" },
|
|
43
|
-
apple: { bg: "#000000", text: "#ffffff" },
|
|
44
|
-
kakao: { bg: "#FEE500", text: "#191919" },
|
|
45
|
-
naver: { bg: "#03C75A", text: "#ffffff" },
|
|
46
|
-
facebook: { bg: "#1877F2", text: "#ffffff" },
|
|
47
|
-
github: { bg: "#24292e", text: "#ffffff" },
|
|
48
|
-
discord: { bg: "#5865F2", text: "#ffffff" },
|
|
49
|
-
x: { bg: "#000000", text: "#ffffff" },
|
|
50
|
-
line: { bg: "#06C755", text: "#ffffff" },
|
|
51
|
-
microsoft: { bg: "#ffffff", text: "#1f1f1f" }
|
|
52
|
-
};
|
|
53
|
-
var DEFAULT_BRANDING = {
|
|
54
|
-
primaryColorStart: "#7c3aed",
|
|
55
|
-
primaryColorEnd: "#4f46e5",
|
|
56
|
-
lightBg: "#ffffff",
|
|
57
|
-
lightText: "#111827",
|
|
58
|
-
darkBg: "#0f172a",
|
|
59
|
-
darkText: "#f1f5f9",
|
|
60
|
-
borderRadius: 12,
|
|
61
|
-
showEmailPassword: true,
|
|
62
|
-
showDivider: true,
|
|
63
|
-
showSecuredBy: true,
|
|
64
|
-
locale: "en"
|
|
65
|
-
};
|
|
1
|
+
// src/modal.ts
|
|
2
|
+
import { DEFAULT_BRANDING } from "@authon/shared";
|
|
66
3
|
|
|
67
4
|
// src/providers.ts
|
|
5
|
+
import { PROVIDER_COLORS, PROVIDER_DISPLAY_NAMES } from "@authon/shared";
|
|
68
6
|
var PROVIDER_ICONS = {
|
|
69
7
|
google: `<svg viewBox="0 0 24 24" width="20" height="20"><path fill="#4285F4" d="M22.56 12.25c0-.78-.07-1.53-.2-2.25H12v4.26h5.92a5.06 5.06 0 01-2.2 3.32v2.77h3.57c2.08-1.92 3.28-4.74 3.28-8.1z"/><path fill="#34A853" d="M12 23c2.97 0 5.46-.98 7.28-2.66l-3.57-2.77c-.98.66-2.23 1.06-3.71 1.06-2.86 0-5.29-1.93-6.16-4.53H2.18v2.84C3.99 20.53 7.7 23 12 23z"/><path fill="#FBBC05" d="M5.84 14.09c-.22-.66-.35-1.36-.35-2.09s.13-1.43.35-2.09V7.07H2.18C1.43 8.55 1 10.22 1 12s.43 3.45 1.18 4.93l2.85-2.22.81-.62z"/><path fill="#EA4335" d="M12 5.38c1.62 0 3.06.56 4.21 1.64l3.15-3.15C17.45 2.09 14.97 1 12 1 7.7 1 3.99 3.47 2.18 7.07l3.66 2.84c.87-2.6 3.3-4.53 6.16-4.53z"/></svg>`,
|
|
70
8
|
apple: `<svg viewBox="0 0 24 24" width="20" height="20" fill="currentColor"><path d="M17.05 20.28c-.98.95-2.05.88-3.08.4-1.09-.5-2.08-.48-3.24 0-1.44.62-2.2.44-3.06-.4C2.79 15.25 3.51 7.59 9.05 7.31c1.35.07 2.29.74 3.08.8 1.18-.24 2.31-.93 3.57-.84 1.51.12 2.65.72 3.4 1.8-3.12 1.87-2.38 5.98.48 7.13-.57 1.5-1.31 2.99-2.54 4.09zM12.03 7.25c-.15-2.23 1.66-4.07 3.74-4.25.29 2.58-2.34 4.5-3.74 4.25z"/></svg>`,
|
|
@@ -195,7 +133,6 @@ var ModalRenderer = class {
|
|
|
195
133
|
switchView(view) {
|
|
196
134
|
if (!this.shadowRoot || view === this.currentView) return;
|
|
197
135
|
this.currentView = view;
|
|
198
|
-
const isSignUp = view === "signUp";
|
|
199
136
|
const inner = this.shadowRoot.getElementById("modal-inner");
|
|
200
137
|
if (!inner) return;
|
|
201
138
|
inner.style.opacity = "0";
|
|
@@ -848,8 +785,8 @@ var Authon = class {
|
|
|
848
785
|
return `API ${path}: ${res.status}`;
|
|
849
786
|
}
|
|
850
787
|
};
|
|
851
|
-
|
|
852
|
-
0 && (module.exports = {
|
|
788
|
+
export {
|
|
853
789
|
Authon,
|
|
854
790
|
getProviderButtonConfig
|
|
855
|
-
}
|
|
791
|
+
};
|
|
792
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/modal.ts","../src/providers.ts","../src/session.ts","../src/authon.ts"],"sourcesContent":["import type { BrandingConfig, OAuthProviderType } from '@authon/shared';\nimport { DEFAULT_BRANDING } from '@authon/shared';\nimport { getProviderButtonConfig } from './providers';\n\nexport class ModalRenderer {\n private shadowRoot: ShadowRoot | null = null;\n private hostElement: HTMLDivElement | null = null;\n private containerElement: HTMLElement | null = null;\n private mode: 'popup' | 'embedded';\n private theme: 'light' | 'dark' | 'auto';\n private branding: BrandingConfig;\n private enabledProviders: OAuthProviderType[] = [];\n private currentView: 'signIn' | 'signUp' = 'signIn';\n private onProviderClick: (provider: OAuthProviderType) => void;\n private onEmailSubmit: (email: string, password: string, isSignUp: boolean) => void;\n private onClose: () => void;\n private escHandler: ((e: KeyboardEvent) => void) | null = null;\n\n constructor(options: {\n mode: 'popup' | 'embedded';\n theme?: 'light' | 'dark' | 'auto';\n containerId?: string;\n branding?: BrandingConfig;\n onProviderClick: (provider: OAuthProviderType) => void;\n onEmailSubmit: (email: string, password: string, isSignUp: boolean) => void;\n onClose: () => void;\n }) {\n this.mode = options.mode;\n this.theme = options.theme || 'auto';\n this.branding = { ...DEFAULT_BRANDING, ...options.branding };\n this.onProviderClick = options.onProviderClick;\n this.onEmailSubmit = options.onEmailSubmit;\n this.onClose = options.onClose;\n\n if (options.mode === 'embedded' && options.containerId) {\n this.containerElement = document.getElementById(options.containerId);\n }\n }\n\n setProviders(providers: OAuthProviderType[]): void {\n this.enabledProviders = providers;\n }\n\n setBranding(branding: BrandingConfig): void {\n this.branding = { ...DEFAULT_BRANDING, ...branding };\n }\n\n open(view: 'signIn' | 'signUp' = 'signIn'): void {\n if (this.shadowRoot && this.hostElement) {\n // Modal already open — smooth in-place view switch\n this.switchView(view);\n } else {\n this.currentView = view;\n this.render(view);\n }\n }\n\n close(): void {\n if (this.escHandler) {\n document.removeEventListener('keydown', this.escHandler);\n this.escHandler = null;\n }\n if (this.hostElement) {\n this.hostElement.remove();\n this.hostElement = null;\n this.shadowRoot = null;\n }\n if (this.containerElement) {\n this.containerElement.innerHTML = '';\n }\n }\n\n showError(message: string): void {\n if (!this.shadowRoot) return;\n this.clearError();\n const errorEl = this.shadowRoot.getElementById('email-form');\n if (errorEl) {\n const errDiv = document.createElement('div');\n errDiv.id = 'authon-error-msg';\n errDiv.className = 'error-msg';\n errDiv.textContent = message;\n errorEl.appendChild(errDiv);\n }\n }\n\n showBanner(message: string, type: 'error' | 'warning' = 'error'): void {\n if (!this.shadowRoot) return;\n this.clearBanner();\n const inner = this.shadowRoot.getElementById('modal-inner');\n if (!inner) return;\n const banner = document.createElement('div');\n banner.id = 'authon-banner';\n banner.className = type === 'warning' ? 'banner-warning' : 'error-msg';\n banner.textContent = message;\n inner.insertBefore(banner, inner.firstChild);\n }\n\n clearBanner(): void {\n if (!this.shadowRoot) return;\n this.shadowRoot.getElementById('authon-banner')?.remove();\n }\n\n clearError(): void {\n if (!this.shadowRoot) return;\n this.shadowRoot.getElementById('authon-error-msg')?.remove();\n }\n\n showLoading(): void {\n if (!this.shadowRoot) return;\n this.hideLoading();\n const overlay = document.createElement('div');\n overlay.id = 'authon-loading-overlay';\n overlay.innerHTML = `\n <div class=\"loading-spinner\">\n <div class=\"loading-ring\"></div>\n <div class=\"loading-ring\"></div>\n <div class=\"loading-ring\"></div>\n </div>\n <div class=\"loading-text\">Signing in<span class=\"loading-dots\"><span></span><span></span><span></span></span></div>\n `;\n this.shadowRoot.querySelector('.modal-container')?.appendChild(overlay);\n }\n\n hideLoading(): void {\n if (!this.shadowRoot) return;\n this.shadowRoot.getElementById('authon-loading-overlay')?.remove();\n }\n\n // ── Smooth view switch (no flicker) ──\n\n private switchView(view: 'signIn' | 'signUp'): void {\n if (!this.shadowRoot || view === this.currentView) return;\n this.currentView = view;\n\n const inner = this.shadowRoot.getElementById('modal-inner');\n if (!inner) return;\n\n // Cross-fade: fade out → update → fade in\n inner.style.opacity = '0';\n inner.style.transform = 'translateY(-4px)';\n\n setTimeout(() => {\n inner.innerHTML = this.buildInnerContent(view);\n this.attachInnerEvents(view);\n // Trigger reflow, then animate in\n void inner.offsetHeight;\n inner.style.opacity = '1';\n inner.style.transform = 'translateY(0)';\n }, 140);\n }\n\n // ── Render ──\n\n private render(view: 'signIn' | 'signUp'): void {\n const host = document.createElement('div');\n host.setAttribute('data-authon-modal', '');\n this.hostElement = host;\n\n if (this.mode === 'popup') {\n document.body.appendChild(host);\n } else if (this.containerElement) {\n this.containerElement.appendChild(host);\n }\n\n this.shadowRoot = host.attachShadow({ mode: 'open' });\n this.shadowRoot.innerHTML = this.buildShell(view);\n this.attachInnerEvents(view);\n this.attachShellEvents();\n }\n\n // ── HTML builders ──\n\n /** Shell = style + backdrop + modal-container (stable across view switches) */\n private buildShell(view: 'signIn' | 'signUp'): string {\n const popupWrapper =\n this.mode === 'popup'\n ? `<div class=\"backdrop\" id=\"backdrop\"></div>`\n : '';\n\n return `\n <style>${this.buildCSS()}</style>\n ${popupWrapper}\n <div class=\"modal-container\" role=\"dialog\" aria-modal=\"true\">\n <div id=\"modal-inner\" class=\"modal-inner\">\n ${this.buildInnerContent(view)}\n </div>\n </div>\n `;\n }\n\n /** Inner content = everything inside the modal that changes per view */\n private buildInnerContent(view: 'signIn' | 'signUp'): string {\n const b = this.branding;\n const isSignUp = view === 'signUp';\n const title = isSignUp ? 'Create your account' : 'Welcome back';\n const subtitle = isSignUp ? 'Already have an account?' : \"Don't have an account?\";\n const subtitleLink = isSignUp ? 'Sign in' : 'Sign up';\n\n const dark = this.isDark();\n\n // SignUp view: hide providers, show only email form\n const showProviders = !isSignUp;\n\n const providerButtons = showProviders\n ? this.enabledProviders\n .filter((p) => !b.hiddenProviders?.includes(p))\n .map((p) => {\n const config = getProviderButtonConfig(p);\n const isWhiteBg = config.bgColor === '#ffffff';\n const btnBg = dark && isWhiteBg ? '#f8fafc' : config.bgColor;\n const btnBorder = isWhiteBg ? (dark ? '#475569' : '#e5e7eb') : config.bgColor;\n return `<button class=\"provider-btn\" data-provider=\"${p}\" style=\"background:${btnBg};color:${config.textColor};border:1px solid ${btnBorder}\">\n <span class=\"provider-icon\">${config.iconSvg}</span>\n <span>${config.label}</span>\n </button>`;\n })\n .join('')\n : '';\n\n const divider =\n showProviders && b.showDivider !== false && b.showEmailPassword !== false\n ? `<div class=\"divider\"><span>or</span></div>`\n : '';\n\n const emailForm =\n b.showEmailPassword !== false\n ? `<form class=\"email-form\" id=\"email-form\">\n <input type=\"email\" placeholder=\"Email address\" name=\"email\" required class=\"input\" autocomplete=\"email\" />\n <input type=\"password\" placeholder=\"Password\" name=\"password\" required class=\"input\" autocomplete=\"${isSignUp ? 'new-password' : 'current-password'}\" />\n ${isSignUp ? '<p class=\"password-hint\">Must contain uppercase, lowercase, and a number (min 8 chars)</p>' : ''}\n <button type=\"submit\" class=\"submit-btn\">${isSignUp ? 'Sign up' : 'Sign in'}</button>\n </form>`\n : '';\n\n const footer =\n b.termsUrl || b.privacyUrl\n ? `<div class=\"footer\">\n ${b.termsUrl ? `<a href=\"${b.termsUrl}\" target=\"_blank\">Terms of Service</a>` : ''}\n ${b.termsUrl && b.privacyUrl ? ' · ' : ''}\n ${b.privacyUrl ? `<a href=\"${b.privacyUrl}\" target=\"_blank\">Privacy Policy</a>` : ''}\n </div>`\n : '';\n\n const titleHtml = isSignUp\n ? `<div class=\"title-row\">\n <button class=\"back-btn\" id=\"back-btn\" type=\"button\" aria-label=\"Back to sign in\">\n <svg width=\"20\" height=\"20\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\"><path d=\"M19 12H5\"/><path d=\"m12 19-7-7 7-7\"/></svg>\n </button>\n <h2 class=\"title\">${title}</h2>\n </div>`\n : `<h2 class=\"title\">${title}</h2>`;\n\n return `\n ${b.logoDataUrl ? `<img src=\"${b.logoDataUrl}\" alt=\"Logo\" class=\"logo\" />` : ''}\n ${titleHtml}\n ${b.brandName ? `<p class=\"brand-name\">${b.brandName}</p>` : ''}\n ${showProviders ? `<div class=\"providers\">${providerButtons}</div>` : ''}\n ${divider}\n ${emailForm}\n <p class=\"switch-view\">${subtitle} <a href=\"#\" id=\"switch-link\">${subtitleLink}</a></p>\n ${footer}\n ${b.showSecuredBy !== false ? `<div class=\"secured-by\">Secured by <a href=\"https://authon.dev\" target=\"_blank\" rel=\"noopener noreferrer\" class=\"secured-link\">Authon</a></div>` : ''}\n `;\n }\n\n private isDark(): boolean {\n if (this.theme === 'dark') return true;\n if (this.theme === 'light') return false;\n return typeof window !== 'undefined' && window.matchMedia('(prefers-color-scheme: dark)').matches;\n }\n\n private buildCSS(): string {\n const b = this.branding;\n const dark = this.isDark();\n const bg = dark ? (b.darkBg || '#0f172a') : (b.lightBg || '#ffffff');\n const text = dark ? (b.darkText || '#f1f5f9') : (b.lightText || '#111827');\n const mutedText = dark ? '#94a3b8' : '#6b7280';\n const dimText = dark ? '#64748b' : '#9ca3af';\n const borderColor = dark ? '#334155' : '#d1d5db';\n const dividerColor = dark ? '#334155' : '#e5e7eb';\n const inputBg = dark ? '#1e293b' : '#ffffff';\n\n return `\n :host {\n --authon-primary-start: ${b.primaryColorStart || '#7c3aed'};\n --authon-primary-end: ${b.primaryColorEnd || '#4f46e5'};\n --authon-bg: ${bg};\n --authon-text: ${text};\n --authon-muted: ${mutedText};\n --authon-dim: ${dimText};\n --authon-border: ${borderColor};\n --authon-divider: ${dividerColor};\n --authon-input-bg: ${inputBg};\n --authon-radius: ${b.borderRadius ?? 12}px;\n --authon-font: 'Inter', -apple-system, BlinkMacSystemFont, 'Segoe UI', sans-serif;\n font-family: var(--authon-font);\n color: var(--authon-text);\n }\n * { box-sizing: border-box; margin: 0; padding: 0; }\n .backdrop {\n position: fixed; inset: 0; z-index: 99998;\n background: rgba(0,0,0,${dark ? '0.7' : '0.5'}); backdrop-filter: blur(4px);\n animation: fadeIn 0.2s ease;\n }\n .modal-container {\n ${this.mode === 'popup' ? 'position: fixed; top: 50%; left: 50%; transform: translate(-50%, -50%); z-index: 99999; max-height: 90vh; overflow-y: auto;' : ''}\n background: var(--authon-bg);\n color: var(--authon-text);\n border: 1px solid var(--authon-border);\n border-radius: var(--authon-radius);\n padding: 32px;\n width: 400px; max-width: 100%;\n position: ${this.mode === 'popup' ? 'fixed' : 'relative'};\n ${this.mode === 'popup' ? `box-shadow: 0 25px 50px -12px rgba(0,0,0,${dark ? '0.5' : '0.25'}); animation: slideIn 0.3s ease;` : ''}\n }\n .modal-inner {\n transition: opacity 0.14s ease, transform 0.14s ease;\n }\n .logo { display: block; margin: 0 auto 16px; max-height: 48px; }\n .title-row { display: flex; align-items: center; position: relative; margin-bottom: 8px; }\n .title-row .title { flex: 1; margin-bottom: 0; }\n .back-btn {\n position: absolute; left: 0; top: 50%; transform: translateY(-50%);\n background: none; border: none; color: var(--authon-muted);\n cursor: pointer; padding: 4px; border-radius: 6px; display: flex; align-items: center; justify-content: center;\n transition: color 0.15s, background 0.15s;\n }\n .back-btn:hover { color: var(--authon-text); background: var(--authon-divider); }\n .password-hint { font-size: 11px; color: var(--authon-dim); margin: -4px 0 2px; }\n .title { text-align: center; font-size: 24px; font-weight: 700; margin-bottom: 8px; color: var(--authon-text); }\n .brand-name { text-align: center; font-size: 14px; color: var(--authon-muted); margin-bottom: 24px; }\n .providers { display: flex; flex-direction: column; gap: 8px; margin-bottom: 16px; }\n .provider-btn {\n display: flex; align-items: center; gap: 12px;\n width: 100%; padding: 10px 16px; border-radius: calc(var(--authon-radius) * 0.67);\n font-size: 14px; font-weight: 500; cursor: pointer;\n transition: opacity 0.15s, transform 0.1s;\n font-family: var(--authon-font);\n }\n .provider-btn:hover { opacity: 0.9; }\n .provider-btn:active { transform: scale(0.98); }\n .provider-icon { display: flex; align-items: center; flex-shrink: 0; }\n .divider {\n display: flex; align-items: center; gap: 12px;\n margin: 16px 0; color: var(--authon-dim); font-size: 13px;\n }\n .divider::before, .divider::after {\n content: ''; flex: 1; height: 1px; background: var(--authon-divider);\n }\n .email-form { display: flex; flex-direction: column; gap: 10px; }\n .input {\n width: 100%; padding: 10px 14px;\n background: var(--authon-input-bg);\n color: var(--authon-text);\n border: 1px solid var(--authon-border); border-radius: calc(var(--authon-radius) * 0.5);\n font-size: 14px; font-family: var(--authon-font);\n outline: none; transition: border-color 0.15s;\n }\n .input::placeholder { color: var(--authon-dim); }\n .input:focus { border-color: var(--authon-primary-start); box-shadow: 0 0 0 3px rgba(124,58,237,0.15); }\n .submit-btn {\n width: 100%; padding: 10px;\n background: linear-gradient(135deg, var(--authon-primary-start), var(--authon-primary-end));\n color: #fff; border: none; border-radius: calc(var(--authon-radius) * 0.5);\n font-size: 14px; font-weight: 600; cursor: pointer;\n font-family: var(--authon-font); transition: opacity 0.15s;\n }\n .submit-btn:hover { opacity: 0.9; }\n .submit-btn:disabled { opacity: 0.6; cursor: not-allowed; }\n .error-msg {\n margin-top: 8px; padding: 8px 12px;\n background: rgba(239,68,68,0.1); border: 1px solid rgba(239,68,68,0.3);\n border-radius: calc(var(--authon-radius) * 0.33);\n font-size: 13px; color: #ef4444; text-align: center;\n animation: fadeIn 0.15s ease;\n }\n .banner-warning {\n margin-bottom: 16px; padding: 10px 14px;\n background: rgba(245,158,11,0.1); border: 1px solid rgba(245,158,11,0.3);\n border-radius: calc(var(--authon-radius) * 0.33);\n font-size: 13px; color: #f59e0b; text-align: center;\n animation: fadeIn 0.15s ease;\n }\n .switch-view { text-align: center; margin-top: 16px; font-size: 13px; color: var(--authon-muted); }\n .switch-view a { color: var(--authon-primary-start); text-decoration: none; font-weight: 500; }\n .switch-view a:hover { text-decoration: underline; }\n .footer { text-align: center; margin-top: 12px; font-size: 12px; color: var(--authon-dim); }\n .footer a { color: var(--authon-dim); text-decoration: none; }\n .footer a:hover { text-decoration: underline; }\n .secured-by {\n text-align: center; margin-top: 16px;\n font-size: 11px; color: var(--authon-dim);\n }\n .secured-link { font-weight: 600; color: var(--authon-muted); text-decoration: none; }\n .secured-link:hover { text-decoration: underline; }\n /* Loading overlay */\n #authon-loading-overlay {\n position: absolute; inset: 0; z-index: 10;\n background: ${dark ? 'rgba(15,23,42,0.92)' : 'rgba(255,255,255,0.92)'};\n backdrop-filter: blur(2px);\n border-radius: var(--authon-radius);\n display: flex; flex-direction: column; align-items: center; justify-content: center; gap: 20px;\n animation: fadeIn 0.15s ease;\n }\n .loading-spinner { position: relative; width: 48px; height: 48px; }\n .loading-ring {\n position: absolute; inset: 0;\n border: 2.5px solid transparent; border-top-color: var(--authon-primary-start);\n border-radius: 50%; animation: spin 1s cubic-bezier(.55,.15,.45,.85) infinite;\n }\n .loading-ring:nth-child(2) {\n inset: 5px; border-top-color: transparent; border-right-color: var(--authon-primary-end);\n animation-duration: 1.2s; animation-direction: reverse; opacity: .7;\n }\n .loading-ring:nth-child(3) {\n inset: 10px; border-top-color: transparent; border-bottom-color: var(--authon-primary-start);\n animation-duration: .8s; opacity: .4;\n }\n .loading-text { font-size: 14px; font-weight: 500; color: var(--authon-muted); }\n .loading-dots { display: inline-flex; gap: 2px; margin-left: 2px; }\n .loading-dots span {\n width: 3px; height: 3px; border-radius: 50%;\n background: var(--authon-muted); animation: blink 1.4s infinite both;\n }\n .loading-dots span:nth-child(2) { animation-delay: .2s; }\n .loading-dots span:nth-child(3) { animation-delay: .4s; }\n @keyframes spin { to { transform: rotate(360deg); } }\n @keyframes blink { 0%,80%,100% { opacity: .2; } 40% { opacity: 1; } }\n @keyframes fadeIn { from { opacity: 0; } to { opacity: 1; } }\n @keyframes slideIn { from { opacity: 0; transform: translate(-50%, -48%); } to { opacity: 1; transform: translate(-50%, -50%); } }\n ${b.customCss || ''}\n `;\n }\n\n // ── Event binding ──\n\n /** Attach events to shell elements (backdrop, ESC) — called once */\n private attachShellEvents(): void {\n if (!this.shadowRoot) return;\n\n const backdrop = this.shadowRoot.getElementById('backdrop');\n if (backdrop) {\n backdrop.addEventListener('click', () => this.onClose());\n }\n\n if (this.escHandler) {\n document.removeEventListener('keydown', this.escHandler);\n }\n if (this.mode === 'popup') {\n this.escHandler = (e: KeyboardEvent) => {\n if (e.key === 'Escape') this.onClose();\n };\n document.addEventListener('keydown', this.escHandler);\n }\n }\n\n /** Attach events to inner content (buttons, form, switch link) — called on each view */\n private attachInnerEvents(view: 'signIn' | 'signUp'): void {\n if (!this.shadowRoot) return;\n\n // Provider buttons\n this.shadowRoot.querySelectorAll('.provider-btn').forEach((btn) => {\n btn.addEventListener('click', () => {\n const provider = (btn as HTMLElement).dataset.provider as OAuthProviderType;\n this.onProviderClick(provider);\n });\n });\n\n // Email form\n const form = this.shadowRoot.getElementById('email-form') as HTMLFormElement | null;\n if (form) {\n form.addEventListener('submit', (e) => {\n e.preventDefault();\n const formData = new FormData(form);\n this.onEmailSubmit(\n formData.get('email') as string,\n formData.get('password') as string,\n view === 'signUp',\n );\n });\n }\n\n // Back button (signUp → signIn)\n const backBtn = this.shadowRoot.getElementById('back-btn');\n if (backBtn) {\n backBtn.addEventListener('click', () => {\n this.open('signIn');\n });\n }\n\n // Switch view link\n const switchLink = this.shadowRoot.getElementById('switch-link');\n if (switchLink) {\n switchLink.addEventListener('click', (e) => {\n e.preventDefault();\n this.open(view === 'signIn' ? 'signUp' : 'signIn');\n });\n }\n }\n}\n","import { PROVIDER_COLORS, PROVIDER_DISPLAY_NAMES, type OAuthProviderType } from '@authon/shared';\n\nexport interface ProviderButtonConfig {\n provider: OAuthProviderType;\n label: string;\n bgColor: string;\n textColor: string;\n iconSvg: string;\n}\n\nconst PROVIDER_ICONS: Record<OAuthProviderType, string> = {\n google: `<svg viewBox=\"0 0 24 24\" width=\"20\" height=\"20\"><path fill=\"#4285F4\" d=\"M22.56 12.25c0-.78-.07-1.53-.2-2.25H12v4.26h5.92a5.06 5.06 0 01-2.2 3.32v2.77h3.57c2.08-1.92 3.28-4.74 3.28-8.1z\"/><path fill=\"#34A853\" d=\"M12 23c2.97 0 5.46-.98 7.28-2.66l-3.57-2.77c-.98.66-2.23 1.06-3.71 1.06-2.86 0-5.29-1.93-6.16-4.53H2.18v2.84C3.99 20.53 7.7 23 12 23z\"/><path fill=\"#FBBC05\" d=\"M5.84 14.09c-.22-.66-.35-1.36-.35-2.09s.13-1.43.35-2.09V7.07H2.18C1.43 8.55 1 10.22 1 12s.43 3.45 1.18 4.93l2.85-2.22.81-.62z\"/><path fill=\"#EA4335\" d=\"M12 5.38c1.62 0 3.06.56 4.21 1.64l3.15-3.15C17.45 2.09 14.97 1 12 1 7.7 1 3.99 3.47 2.18 7.07l3.66 2.84c.87-2.6 3.3-4.53 6.16-4.53z\"/></svg>`,\n apple: `<svg viewBox=\"0 0 24 24\" width=\"20\" height=\"20\" fill=\"currentColor\"><path d=\"M17.05 20.28c-.98.95-2.05.88-3.08.4-1.09-.5-2.08-.48-3.24 0-1.44.62-2.2.44-3.06-.4C2.79 15.25 3.51 7.59 9.05 7.31c1.35.07 2.29.74 3.08.8 1.18-.24 2.31-.93 3.57-.84 1.51.12 2.65.72 3.4 1.8-3.12 1.87-2.38 5.98.48 7.13-.57 1.5-1.31 2.99-2.54 4.09zM12.03 7.25c-.15-2.23 1.66-4.07 3.74-4.25.29 2.58-2.34 4.5-3.74 4.25z\"/></svg>`,\n kakao: `<svg viewBox=\"0 0 24 24\" width=\"20\" height=\"20\"><path fill=\"#191919\" d=\"M12 3C6.48 3 2 6.36 2 10.43c0 2.62 1.75 4.93 4.37 6.23l-1.12 4.14c-.1.36.31.65.62.44l4.93-3.26c.39.04.79.06 1.2.06 5.52 0 10-3.36 10-7.61C22 6.36 17.52 3 12 3z\"/></svg>`,\n naver: `<svg viewBox=\"0 0 24 24\" width=\"20\" height=\"20\"><path fill=\"#fff\" d=\"M16.27 3H7.73A4.73 4.73 0 003 7.73v8.54A4.73 4.73 0 007.73 21h8.54A4.73 4.73 0 0021 16.27V7.73A4.73 4.73 0 0016.27 3zm-1.84 12.44h-2.1l-2.86-4.15v4.15H7.38V8.56h2.1l2.86 4.15V8.56h2.09v6.88z\"/></svg>`,\n facebook: `<svg viewBox=\"0 0 24 24\" width=\"20\" height=\"20\"><path fill=\"#fff\" d=\"M24 12.07C24 5.41 18.63 0 12 0S0 5.4 0 12.07C0 18.1 4.39 23.1 10.13 24v-8.44H7.08v-3.49h3.04V9.41c0-3.02 1.8-4.7 4.54-4.7 1.31 0 2.68.24 2.68.24v2.97h-1.5c-1.5 0-1.96.93-1.96 1.89v2.26h3.33l-.53 3.49h-2.8V24C19.62 23.1 24 18.1 24 12.07z\"/></svg>`,\n github: `<svg viewBox=\"0 0 24 24\" width=\"20\" height=\"20\" fill=\"#fff\"><path d=\"M12 0C5.37 0 0 5.37 0 12c0 5.31 3.435 9.795 8.205 11.385.6.105.825-.255.825-.57 0-.285-.015-1.23-.015-2.235-3.015.555-3.795-.735-4.035-1.41-.135-.345-.72-1.41-1.23-1.695-.42-.225-1.02-.78-.015-.795.945-.015 1.62.87 1.845 1.23 1.08 1.815 2.805 1.305 3.495.99.105-.78.42-1.305.765-1.605-2.67-.3-5.46-1.335-5.46-5.925 0-1.305.465-2.385 1.23-3.225-.12-.3-.54-1.53.12-3.18 0 0 1.005-.315 3.3 1.23.96-.27 1.98-.405 3-.405s2.04.135 3 .405c2.295-1.56 3.3-1.23 3.3-1.23.66 1.65.24 2.88.12 3.18.765.84 1.23 1.905 1.23 3.225 0 4.605-2.805 5.625-5.475 5.925.435.375.81 1.095.81 2.22 0 1.605-.015 2.895-.015 3.3 0 .315.225.69.825.57A12.02 12.02 0 0024 12c0-6.63-5.37-12-12-12z\"/></svg>`,\n discord: `<svg viewBox=\"0 0 24 24\" width=\"20\" height=\"20\" fill=\"#fff\"><path d=\"M20.32 4.37a19.8 19.8 0 00-4.89-1.52.07.07 0 00-.08.04c-.21.38-.44.87-.61 1.26a18.27 18.27 0 00-5.49 0 12.64 12.64 0 00-.62-1.26.07.07 0 00-.08-.04 19.74 19.74 0 00-4.89 1.52.07.07 0 00-.03.03C1.11 8.39.34 12.28.73 16.12a.08.08 0 00.03.06 19.9 19.9 0 005.99 3.03.08.08 0 00.08-.03c.46-.63.87-1.3 1.22-2a.08.08 0 00-.04-.11 13.1 13.1 0 01-1.87-.9.08.08 0 01-.01-.13c.13-.09.25-.19.37-.29a.07.07 0 01.08-.01c3.93 1.8 8.18 1.8 12.07 0a.07.07 0 01.08 0c.12.1.25.2.37.3a.08.08 0 01-.01.12c-.6.35-1.22.65-1.87.9a.08.08 0 00-.04.1c.36.7.77 1.37 1.22 2a.08.08 0 00.08.03 19.83 19.83 0 006-3.03.08.08 0 00.03-.05c.47-4.87-.78-9.09-3.3-12.84a.06.06 0 00-.03-.03zM8.02 13.62c-1.11 0-2.03-1.02-2.03-2.28 0-1.26.9-2.28 2.03-2.28 1.14 0 2.04 1.03 2.03 2.28 0 1.26-.9 2.28-2.03 2.28zm7.5 0c-1.11 0-2.03-1.02-2.03-2.28 0-1.26.9-2.28 2.03-2.28 1.14 0 2.04 1.03 2.03 2.28 0 1.26-.89 2.28-2.03 2.28z\"/></svg>`,\n x: `<svg viewBox=\"0 0 24 24\" width=\"20\" height=\"20\" fill=\"#fff\"><path d=\"M18.244 2.25h3.308l-7.227 8.26 8.502 11.24H16.17l-5.214-6.817L4.99 21.75H1.68l7.73-8.835L1.254 2.25H8.08l4.713 6.231zm-1.161 17.52h1.833L7.084 4.126H5.117z\"/></svg>`,\n line: `<svg viewBox=\"0 0 24 24\" width=\"20\" height=\"20\" fill=\"#fff\"><path d=\"M19.365 9.863c.349 0 .63.285.63.631 0 .345-.281.63-.63.63H17.61v1.125h1.755c.349 0 .63.283.63.63 0 .344-.281.629-.63.629h-2.386c-.345 0-.627-.285-.627-.629V8.108c0-.345.282-.63.63-.63h2.386c.346 0 .627.285.627.63 0 .349-.281.63-.63.63H17.61v1.125h1.755zm-3.855 3.016c0 .27-.174.51-.432.596-.064.021-.133.031-.199.031-.211 0-.391-.09-.51-.25l-2.443-3.317v2.94c0 .344-.279.629-.631.629-.346 0-.626-.285-.626-.629V8.108c0-.27.173-.51.43-.595.06-.023.136-.033.194-.033.195 0 .375.104.495.254l2.462 3.33V8.108c0-.345.282-.63.63-.63.345 0 .63.285.63.63v4.771zm-5.741 0c0 .344-.282.629-.631.629-.345 0-.627-.285-.627-.629V8.108c0-.345.282-.63.63-.63.346 0 .628.285.628.63v4.771zm-2.466.629H4.917c-.345 0-.63-.285-.63-.629V8.108c0-.345.285-.63.63-.63.348 0 .63.285.63.63v4.141h1.756c.348 0 .629.283.629.63 0 .344-.282.629-.629.629M24 10.314C24 4.943 18.615.572 12 .572S0 4.943 0 10.314c0 4.811 4.27 8.842 10.035 9.608.391.082.923.258 1.058.59.12.301.079.766.038 1.08l-.164 1.02c-.045.301-.24 1.186 1.049.645 1.291-.539 6.916-4.078 9.436-6.975C23.176 14.393 24 12.458 24 10.314\"/></svg>`,\n microsoft: `<svg viewBox=\"0 0 24 24\" width=\"20\" height=\"20\"><rect fill=\"#F25022\" x=\"1\" y=\"1\" width=\"10\" height=\"10\"/><rect fill=\"#7FBA00\" x=\"13\" y=\"1\" width=\"10\" height=\"10\"/><rect fill=\"#00A4EF\" x=\"1\" y=\"13\" width=\"10\" height=\"10\"/><rect fill=\"#FFB900\" x=\"13\" y=\"13\" width=\"10\" height=\"10\"/></svg>`,\n};\n\nexport function getProviderButtonConfig(provider: OAuthProviderType): ProviderButtonConfig {\n const colors = PROVIDER_COLORS[provider];\n return {\n provider,\n label: `Continue with ${PROVIDER_DISPLAY_NAMES[provider]}`,\n bgColor: colors.bg,\n textColor: colors.text,\n iconSvg: PROVIDER_ICONS[provider],\n };\n}\n","import type { AuthonUser, AuthTokens } from '@authon/shared';\n\nexport class SessionManager {\n private accessToken: string | null = null;\n private refreshToken: string | null = null;\n private user: AuthonUser | null = null;\n private refreshTimer: ReturnType<typeof setTimeout> | null = null;\n private apiUrl: string;\n private publishableKey: string;\n\n constructor(publishableKey: string, apiUrl: string) {\n this.publishableKey = publishableKey;\n this.apiUrl = apiUrl;\n }\n\n getToken(): string | null {\n return this.accessToken;\n }\n\n getUser(): AuthonUser | null {\n return this.user;\n }\n\n setSession(tokens: AuthTokens): void {\n this.accessToken = tokens.accessToken;\n this.refreshToken = tokens.refreshToken;\n this.user = tokens.user;\n if (tokens.expiresIn && tokens.expiresIn > 0) {\n this.scheduleRefresh(tokens.expiresIn);\n }\n }\n\n clearSession(): void {\n this.accessToken = null;\n this.refreshToken = null;\n this.user = null;\n if (this.refreshTimer) {\n clearTimeout(this.refreshTimer);\n this.refreshTimer = null;\n }\n }\n\n private scheduleRefresh(expiresIn: number): void {\n if (this.refreshTimer) clearTimeout(this.refreshTimer);\n // Refresh 60 seconds before expiry\n const refreshIn = Math.max((expiresIn - 60) * 1000, 30000);\n this.refreshTimer = setTimeout(() => this.refresh(), refreshIn);\n }\n\n async refresh(): Promise<AuthTokens | null> {\n if (!this.refreshToken) {\n this.clearSession();\n return null;\n }\n try {\n const res = await fetch(`${this.apiUrl}/v1/auth/token/refresh`, {\n method: 'POST',\n headers: {\n 'Content-Type': 'application/json',\n 'x-api-key': this.publishableKey,\n },\n credentials: 'include',\n body: JSON.stringify({ refreshToken: this.refreshToken }),\n });\n if (!res.ok) {\n this.clearSession();\n return null;\n }\n const tokens: AuthTokens = await res.json();\n this.setSession(tokens);\n return tokens;\n } catch {\n this.clearSession();\n return null;\n }\n }\n\n async signOut(): Promise<void> {\n try {\n await fetch(`${this.apiUrl}/v1/auth/signout`, {\n method: 'POST',\n headers: {\n 'Content-Type': 'application/json',\n 'x-api-key': this.publishableKey,\n ...(this.accessToken ? { Authorization: `Bearer ${this.accessToken}` } : {}),\n },\n credentials: 'include',\n });\n } catch {\n // ignore\n }\n this.clearSession();\n }\n\n destroy(): void {\n this.clearSession();\n }\n}\n","import type { AuthonUser, AuthTokens, BrandingConfig, OAuthProviderType } from '@authon/shared';\nimport type { AuthonConfig, AuthonEventType, AuthonEvents } from './types';\nimport { ModalRenderer } from './modal';\nimport { SessionManager } from './session';\n\nexport class Authon {\n private publishableKey: string;\n private config: Required<Omit<AuthonConfig, 'containerId' | 'appearance'>> & {\n containerId?: string;\n appearance?: Partial<BrandingConfig>;\n };\n private session: SessionManager;\n private modal: ModalRenderer | null = null;\n private listeners: Map<string, Set<(...args: unknown[]) => void>> = new Map();\n private branding: BrandingConfig | null = null;\n private providers: OAuthProviderType[] = [];\n private initialized = false;\n\n constructor(publishableKey: string, config?: AuthonConfig) {\n this.publishableKey = publishableKey;\n this.config = {\n apiUrl: config?.apiUrl || 'https://api.authon.dev',\n mode: config?.mode || 'popup',\n theme: config?.theme || 'auto',\n locale: config?.locale || 'en',\n containerId: config?.containerId,\n appearance: config?.appearance,\n };\n this.session = new SessionManager(publishableKey, this.config.apiUrl);\n }\n\n // ── Public API ──\n\n async openSignIn(): Promise<void> {\n await this.ensureInitialized();\n this.getModal().open('signIn');\n }\n\n async openSignUp(): Promise<void> {\n await this.ensureInitialized();\n this.getModal().open('signUp');\n }\n\n async signInWithOAuth(provider: OAuthProviderType): Promise<void> {\n await this.ensureInitialized();\n await this.startOAuthFlow(provider);\n }\n\n async signInWithEmail(email: string, password: string): Promise<AuthonUser> {\n const tokens = await this.apiPost<AuthTokens>('/v1/auth/signin', { email, password });\n this.session.setSession(tokens);\n this.emit('signedIn', tokens.user);\n return tokens.user;\n }\n\n async signUpWithEmail(\n email: string,\n password: string,\n meta?: { displayName?: string },\n ): Promise<AuthonUser> {\n const tokens = await this.apiPost<AuthTokens>('/v1/auth/signup', {\n email,\n password,\n ...meta,\n });\n this.session.setSession(tokens);\n this.emit('signedIn', tokens.user);\n return tokens.user;\n }\n\n async signOut(): Promise<void> {\n await this.session.signOut();\n this.emit('signedOut');\n }\n\n getUser(): AuthonUser | null {\n return this.session.getUser();\n }\n\n getToken(): string | null {\n return this.session.getToken();\n }\n\n on<K extends AuthonEventType>(event: K, listener: AuthonEvents[K]): () => void {\n if (!this.listeners.has(event)) this.listeners.set(event, new Set());\n const set = this.listeners.get(event)!;\n set.add(listener as (...args: unknown[]) => void);\n return () => set.delete(listener as (...args: unknown[]) => void);\n }\n\n destroy(): void {\n this.modal?.close();\n this.session.destroy();\n this.listeners.clear();\n }\n\n // ── Internal ──\n\n private emit(event: string, ...args: unknown[]): void {\n this.listeners.get(event)?.forEach((fn) => fn(...args));\n }\n\n private async ensureInitialized(): Promise<void> {\n if (this.initialized) return;\n try {\n const [branding, providersRes] = await Promise.all([\n this.apiGet<BrandingConfig>('/v1/auth/branding'),\n this.apiGet<{ providers: OAuthProviderType[] }>('/v1/auth/providers'),\n ]);\n this.branding = { ...branding, ...this.config.appearance };\n this.providers = providersRes.providers;\n this.initialized = true;\n } catch (err) {\n this.emit('error', err instanceof Error ? err : new Error(String(err)));\n throw err;\n }\n }\n\n private getModal(): ModalRenderer {\n if (!this.modal) {\n this.modal = new ModalRenderer({\n mode: this.config.mode,\n theme: this.config.theme,\n containerId: this.config.containerId,\n branding: this.branding || undefined,\n onProviderClick: (provider) => this.startOAuthFlow(provider),\n onEmailSubmit: (email, password, isSignUp) => {\n this.modal?.clearError();\n const promise = isSignUp\n ? this.signUpWithEmail(email, password)\n : this.signInWithEmail(email, password);\n promise\n .then(() => this.modal?.close())\n .catch((err) => {\n const msg = err instanceof Error ? err.message : String(err);\n this.modal?.showError(msg || 'Authentication failed');\n this.emit('error', err instanceof Error ? err : new Error(msg));\n });\n },\n onClose: () => this.modal?.close(),\n });\n }\n if (this.branding) this.modal.setBranding(this.branding);\n this.modal.setProviders(this.providers);\n return this.modal;\n }\n\n private async startOAuthFlow(provider: OAuthProviderType): Promise<void> {\n try {\n const redirectUri = `${this.config.apiUrl}/v1/auth/oauth/redirect`;\n const { url, state } = await this.apiGet<{ url: string; state: string }>(\n `/v1/auth/oauth/${provider}/url?redirectUri=${encodeURIComponent(redirectUri)}`,\n );\n\n this.modal?.showLoading();\n\n // Open popup\n const width = 500;\n const height = 700;\n const left = window.screenX + (window.outerWidth - width) / 2;\n const top = window.screenY + (window.outerHeight - height) / 2;\n const popup = window.open(\n url,\n 'authon-oauth',\n `width=${width},height=${height},left=${left},top=${top},toolbar=no,menubar=no`,\n );\n\n if (!popup || popup.closed) {\n this.modal?.hideLoading();\n this.modal?.showBanner(\n 'Pop-up blocked. Please allow pop-ups for this site and try again.',\n 'warning',\n );\n this.emit('error', new Error('Popup was blocked by the browser'));\n return;\n }\n\n let resolved = false;\n let cleaned = false;\n\n const resolve = (tokens: AuthTokens) => {\n if (resolved) return;\n resolved = true;\n cleanup();\n try { if (!popup.closed) popup.close(); } catch { /* ignore */ }\n this.session.setSession(tokens);\n this.modal?.close();\n this.emit('signedIn', tokens.user);\n };\n\n const handleError = (msg: string) => {\n if (resolved) return;\n cleanup();\n this.modal?.hideLoading();\n this.modal?.showError(msg);\n this.emit('error', new Error(msg));\n };\n\n const cleanup = () => {\n if (cleaned) return;\n cleaned = true;\n window.removeEventListener('message', messageHandler);\n if (apiPollTimer) clearInterval(apiPollTimer);\n if (closePollTimer) clearInterval(closePollTimer);\n if (maxTimer) clearTimeout(maxTimer);\n };\n\n // 1. postMessage handler (fast path — Chrome/Firefox)\n const messageHandler = (e: MessageEvent) => {\n if (e.data?.type !== 'authon-oauth-callback') return;\n if (e.data.tokens) {\n resolve(e.data.tokens as AuthTokens);\n }\n };\n window.addEventListener('message', messageHandler);\n\n // 2. API polling (Safari fallback — window.opener severed by COOP)\n const apiPollTimer = setInterval(async () => {\n if (resolved || cleaned) return;\n try {\n const result = await this.apiGet<{ status: string; accessToken?: string; refreshToken?: string; expiresIn?: number; user?: AuthonUser; message?: string }>(\n `/v1/auth/oauth/poll?state=${encodeURIComponent(state)}`,\n );\n if (result.status === 'completed' && result.accessToken) {\n resolve({\n accessToken: result.accessToken,\n refreshToken: result.refreshToken!,\n expiresIn: result.expiresIn!,\n user: result.user!,\n });\n } else if (result.status === 'error') {\n handleError(result.message || 'Authentication failed');\n }\n } catch {\n // Network error — keep polling\n }\n }, 1500);\n\n // 3. Popup close detection\n const closePollTimer = setInterval(() => {\n if (resolved || cleaned) return;\n try {\n if (popup.closed) {\n clearInterval(closePollTimer);\n // Give polling a few more seconds to pick up the result\n setTimeout(() => {\n if (resolved || cleaned) return;\n cleanup();\n this.modal?.hideLoading();\n }, 3000);\n }\n } catch {\n // Cross-origin access error — popup still open\n }\n }, 500);\n\n // 4. Max timeout (3 minutes)\n const maxTimer = setTimeout(() => {\n if (resolved || cleaned) return;\n cleanup();\n this.modal?.hideLoading();\n }, 180_000);\n } catch (err) {\n this.modal?.hideLoading();\n this.emit('error', err instanceof Error ? err : new Error(String(err)));\n }\n }\n\n private async apiGet<T>(path: string): Promise<T> {\n const res = await fetch(`${this.config.apiUrl}${path}`, {\n headers: { 'x-api-key': this.publishableKey },\n credentials: 'include',\n });\n if (!res.ok) throw new Error(await this.parseApiError(res, path));\n return res.json();\n }\n\n private async apiPost<T>(path: string, body?: unknown): Promise<T> {\n const res = await fetch(`${this.config.apiUrl}${path}`, {\n method: 'POST',\n headers: {\n 'Content-Type': 'application/json',\n 'x-api-key': this.publishableKey,\n },\n credentials: 'include',\n body: body ? JSON.stringify(body) : undefined,\n });\n if (!res.ok) throw new Error(await this.parseApiError(res, path));\n return res.json();\n }\n\n private async parseApiError(res: Response, path: string): Promise<string> {\n try {\n const body = await res.json();\n if (Array.isArray(body.message) && body.message.length > 0) {\n return body.message[0];\n }\n if (typeof body.message === 'string' && body.message !== 'Bad Request') {\n return body.message;\n }\n } catch { /* ignore */ }\n return `API ${path}: ${res.status}`;\n }\n}\n"],"mappings":"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","names":[]}
|
package/package.json
CHANGED
|
@@ -1,28 +1,48 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@authon/js",
|
|
3
|
-
"version": "0.1.
|
|
4
|
-
"description": "Authon core SDK — ShadowDOM login modal
|
|
5
|
-
"
|
|
6
|
-
"
|
|
3
|
+
"version": "0.1.14",
|
|
4
|
+
"description": "Authon core browser SDK — ShadowDOM login modal, OAuth, session management",
|
|
5
|
+
"type": "module",
|
|
6
|
+
"main": "./dist/index.cjs",
|
|
7
|
+
"module": "./dist/index.js",
|
|
7
8
|
"types": "./dist/index.d.ts",
|
|
8
9
|
"exports": {
|
|
9
10
|
".": {
|
|
10
11
|
"types": "./dist/index.d.ts",
|
|
11
|
-
"import": "./dist/index.
|
|
12
|
-
"require": "./dist/index.
|
|
12
|
+
"import": "./dist/index.js",
|
|
13
|
+
"require": "./dist/index.cjs"
|
|
13
14
|
}
|
|
14
15
|
},
|
|
16
|
+
"files": [
|
|
17
|
+
"dist"
|
|
18
|
+
],
|
|
15
19
|
"scripts": {
|
|
16
20
|
"build": "tsup",
|
|
17
21
|
"dev": "tsup --watch"
|
|
18
22
|
},
|
|
19
|
-
"
|
|
20
|
-
|
|
21
|
-
"
|
|
22
|
-
"
|
|
23
|
+
"license": "MIT",
|
|
24
|
+
"repository": {
|
|
25
|
+
"type": "git",
|
|
26
|
+
"url": "https://github.com/mikusnuz/authon-sdk.git",
|
|
27
|
+
"directory": "packages/js"
|
|
23
28
|
},
|
|
24
|
-
"
|
|
25
|
-
|
|
29
|
+
"homepage": "https://github.com/mikusnuz/authon-sdk/tree/main/packages/js",
|
|
30
|
+
"publishConfig": {
|
|
31
|
+
"access": "public"
|
|
32
|
+
},
|
|
33
|
+
"keywords": [
|
|
34
|
+
"authon",
|
|
35
|
+
"auth",
|
|
36
|
+
"authentication",
|
|
37
|
+
"login",
|
|
38
|
+
"oauth",
|
|
39
|
+
"sdk"
|
|
26
40
|
],
|
|
27
|
-
"
|
|
41
|
+
"dependencies": {
|
|
42
|
+
"@authon/shared": "workspace:*"
|
|
43
|
+
},
|
|
44
|
+
"devDependencies": {
|
|
45
|
+
"tsup": "^8.0.0",
|
|
46
|
+
"typescript": "^5.9.3"
|
|
47
|
+
}
|
|
28
48
|
}
|
|
File without changes
|