@edgespark/web 0.0.4 → 0.0.5
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/auth/styles/styles.css +59 -2
- package/dist/auth/local-dev.d.ts +5 -0
- package/dist/auth-ui/ManagedAuthUI.d.ts +7 -0
- package/dist/auth-ui/config.d.ts +5 -0
- package/dist/auth-ui/types.d.ts +7 -0
- package/dist/index.cjs +32 -17
- package/dist/index.es.js +709 -604
- package/package.json +1 -1
package/auth/styles/styles.css
CHANGED
|
@@ -96,6 +96,40 @@
|
|
|
96
96
|
gap: 8px;
|
|
97
97
|
}
|
|
98
98
|
|
|
99
|
+
.edgespark-auth__tabs {
|
|
100
|
+
display: grid;
|
|
101
|
+
grid-template-columns: repeat(2, minmax(0, 1fr));
|
|
102
|
+
gap: 4px;
|
|
103
|
+
min-height: 44px;
|
|
104
|
+
padding: 4px;
|
|
105
|
+
border: 1px solid var(--edgespark-auth-border);
|
|
106
|
+
border-radius: var(--edgespark-auth-radius-control);
|
|
107
|
+
background: var(--edgespark-auth-bg-muted);
|
|
108
|
+
}
|
|
109
|
+
|
|
110
|
+
.edgespark-auth__tab {
|
|
111
|
+
min-width: 0;
|
|
112
|
+
border: 0;
|
|
113
|
+
border-radius: calc(var(--edgespark-auth-radius-control) - 4px);
|
|
114
|
+
background: transparent;
|
|
115
|
+
color: var(--edgespark-auth-text-muted);
|
|
116
|
+
cursor: pointer;
|
|
117
|
+
font: inherit;
|
|
118
|
+
font-size: 0.92rem;
|
|
119
|
+
font-weight: 600;
|
|
120
|
+
}
|
|
121
|
+
|
|
122
|
+
.edgespark-auth__tab--active {
|
|
123
|
+
background: var(--edgespark-auth-bg);
|
|
124
|
+
color: var(--edgespark-auth-text);
|
|
125
|
+
box-shadow: 0 1px 2px rgba(15, 23, 42, 0.08);
|
|
126
|
+
}
|
|
127
|
+
|
|
128
|
+
.edgespark-auth__tab:disabled {
|
|
129
|
+
cursor: not-allowed;
|
|
130
|
+
opacity: 0.6;
|
|
131
|
+
}
|
|
132
|
+
|
|
99
133
|
.edgespark-auth__label {
|
|
100
134
|
font-size: 0.9rem;
|
|
101
135
|
font-weight: 600;
|
|
@@ -119,7 +153,8 @@
|
|
|
119
153
|
}
|
|
120
154
|
|
|
121
155
|
.edgespark-auth__button,
|
|
122
|
-
.edgespark-auth__link
|
|
156
|
+
.edgespark-auth__link,
|
|
157
|
+
.edgespark-auth__text-action {
|
|
123
158
|
font: inherit;
|
|
124
159
|
}
|
|
125
160
|
|
|
@@ -136,7 +171,8 @@
|
|
|
136
171
|
}
|
|
137
172
|
|
|
138
173
|
.edgespark-auth__button:disabled,
|
|
139
|
-
.edgespark-auth__link:disabled
|
|
174
|
+
.edgespark-auth__link:disabled,
|
|
175
|
+
.edgespark-auth__text-action:disabled {
|
|
140
176
|
cursor: not-allowed;
|
|
141
177
|
opacity: 0.6;
|
|
142
178
|
}
|
|
@@ -174,6 +210,27 @@
|
|
|
174
210
|
cursor: pointer;
|
|
175
211
|
}
|
|
176
212
|
|
|
213
|
+
.edgespark-auth__text-action {
|
|
214
|
+
justify-self: center;
|
|
215
|
+
padding: 2px 4px;
|
|
216
|
+
border: 0;
|
|
217
|
+
background: transparent;
|
|
218
|
+
color: var(--edgespark-auth-primary);
|
|
219
|
+
cursor: pointer;
|
|
220
|
+
font-size: 0.95rem;
|
|
221
|
+
font-weight: 600;
|
|
222
|
+
line-height: 1.4;
|
|
223
|
+
}
|
|
224
|
+
|
|
225
|
+
.edgespark-auth__text-action:hover:not(:disabled) {
|
|
226
|
+
color: var(--edgespark-auth-primary-hover);
|
|
227
|
+
}
|
|
228
|
+
|
|
229
|
+
.edgespark-auth__text-action:disabled {
|
|
230
|
+
color: var(--edgespark-auth-text-muted);
|
|
231
|
+
opacity: 1;
|
|
232
|
+
}
|
|
233
|
+
|
|
177
234
|
.edgespark-auth__divider {
|
|
178
235
|
position: relative;
|
|
179
236
|
text-align: center;
|
package/dist/auth/local-dev.d.ts
CHANGED
|
@@ -29,3 +29,8 @@ export declare function autoVerifyLocalDev(email: string): Promise<boolean>;
|
|
|
29
29
|
* Returns the OTP string or null if not available.
|
|
30
30
|
*/
|
|
31
31
|
export declare function fetchOtpLocalDev(email: string): Promise<string | null>;
|
|
32
|
+
/**
|
|
33
|
+
* Fetch the pending OTP for email sign-in in local dev.
|
|
34
|
+
* Returns the OTP string or null if not available.
|
|
35
|
+
*/
|
|
36
|
+
export declare function fetchSignInOtpLocalDev(email: string): Promise<string | null>;
|
|
@@ -52,6 +52,9 @@ export declare class ManagedAuthUI implements MountedAuthUI {
|
|
|
52
52
|
private bindDOM;
|
|
53
53
|
private switchView;
|
|
54
54
|
private handleSignIn;
|
|
55
|
+
private handleEmailOtpSignIn;
|
|
56
|
+
private sendSignInOtp;
|
|
57
|
+
private resendSignInCode;
|
|
55
58
|
private handleSignUp;
|
|
56
59
|
private handleOAuthSignIn;
|
|
57
60
|
private handleForgotPassword;
|
|
@@ -85,6 +88,10 @@ export declare class ManagedAuthUI implements MountedAuthUI {
|
|
|
85
88
|
private scheduleFocusRestore;
|
|
86
89
|
private clearFocusRestoreTimer;
|
|
87
90
|
private passwordResetEndpoints;
|
|
91
|
+
private emailOtpSignInEndpoints;
|
|
92
|
+
private resolveInitialSignInMethod;
|
|
93
|
+
private setSignInMethod;
|
|
94
|
+
private canUseEmailOtpSignIn;
|
|
88
95
|
private extractRedirectURL;
|
|
89
96
|
private extractUser;
|
|
90
97
|
private canUsePasswordResetEmailOtp;
|
package/dist/auth-ui/config.d.ts
CHANGED
|
@@ -19,9 +19,13 @@ interface ProviderEmailPassword {
|
|
|
19
19
|
requirePasswordResetEmailVerification?: boolean;
|
|
20
20
|
};
|
|
21
21
|
}
|
|
22
|
+
interface ProviderEmailOtp {
|
|
23
|
+
enabled?: boolean;
|
|
24
|
+
}
|
|
22
25
|
interface AuthConfigResponse {
|
|
23
26
|
disableSignUp?: boolean;
|
|
24
27
|
providerEmailPassword?: ProviderEmailPassword;
|
|
28
|
+
providerEmailOtp?: ProviderEmailOtp;
|
|
25
29
|
providerGoogle?: OAuthProviderBlock;
|
|
26
30
|
providerApple?: OAuthProviderBlock;
|
|
27
31
|
providerMicrosoft?: OAuthProviderBlock;
|
|
@@ -32,6 +36,7 @@ interface AuthConfigResponse {
|
|
|
32
36
|
export interface NormalizedAuthUIConfig {
|
|
33
37
|
disableSignUp: boolean;
|
|
34
38
|
emailPasswordEnabled: boolean;
|
|
39
|
+
emailOtpSignInEnabled: boolean;
|
|
35
40
|
minPasswordLength: number;
|
|
36
41
|
requireEmailVerification: boolean;
|
|
37
42
|
passwordResetEmailOtpEnabled: boolean;
|
package/dist/auth-ui/types.d.ts
CHANGED
|
@@ -40,7 +40,14 @@ export interface AuthUILabels {
|
|
|
40
40
|
subtitle: string;
|
|
41
41
|
emailLabel: string;
|
|
42
42
|
passwordLabel: string;
|
|
43
|
+
codeLabel?: string;
|
|
43
44
|
submitButton: string;
|
|
45
|
+
sendCodeButton?: string;
|
|
46
|
+
verifyCodeButton?: string;
|
|
47
|
+
resendCodeButton?: string;
|
|
48
|
+
resendCountdown?: string;
|
|
49
|
+
passwordTab?: string;
|
|
50
|
+
codeTab?: string;
|
|
44
51
|
forgotPassword: string;
|
|
45
52
|
switchToSignUp: string;
|
|
46
53
|
signUpPrompt: string;
|
package/dist/index.cjs
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
"use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const qe=require("better-auth/client");class K extends Error{constructor(e,i){super(i),this.name="EdgeSparkError",this.code=e}}class g extends K{constructor(e){super("CONFIG_ERROR",e),this.name="EdgeSparkConfigError"}}class be extends K{constructor(e){super("RUNTIME_ERROR",e),this.name="EdgeSparkRuntimeError"}}class _ extends K{constructor(e,i){super((i==null?void 0:i.code)??"AUTH_ERROR",e),this.name="EdgeSparkAuthError",this.cause=i==null?void 0:i.cause,this.status=i==null?void 0:i.status}}function ye(t,e="Authentication failed.",i){if(t instanceof _)return t;if(typeof t=="object"&&t!==null){const s=t;return new _(s.message||e,{code:s.code??i,status:s.status,cause:t})}return typeof t=="string"?new _(t,{code:i}):new _(e,{code:i,cause:t})}function $e(){if(typeof window>"u"||typeof document>"u")throw new be("@edgespark/web is browser-only. Create the client from a real browser runtime.")}function ae(){return $e(),window.location.origin}function Ke(t){return t instanceof URL?t:typeof t=="string"?new URL(t,window.location.href):new URL(t.url,window.location.href)}function We(t){if(t.origin!==ae())throw new g(`Cross-origin requests are not supported by this SDK. Received ${t.origin}, expected ${ae()}.`)}function Ye(){return{async fetch(t,e){const i=Ke(t);return We(i),fetch(t,{...e,credentials:"include"})}}}const Be="/api/_es/auth",Je="edgespark-auth-session",Oe="__edgespark_auth_sync__",W="__edgespark_auth_pending_sign_in__",Me=Symbol("edgespark.notifyAuthTabs"),Xe=10*60*1e3,Ze=new Set(["signOut","revokeSession","revokeSessions","revokeOtherSessions"]),Qe=new Map([["changeEmail","changeEmail() is not currently supported by EdgeSpark platform auth. Use authUI.mount() or other supported client.auth flows instead of wiring raw /api/_es/auth/* routes manually."],["deleteUser","deleteUser() is not currently supported by EdgeSpark platform auth. Handle account removal through your own app flow until the platform enables this capability."],["deleteUserCallback","deleteUserCallback() is not currently supported by EdgeSpark platform auth. Handle account removal through your own app flow until the platform enables this capability."]]);class et{constructor(e){this.value=e}deref(){return this.value}}const _e=globalThis.WeakRef,Pe=globalThis.FinalizationRegistry;let Y,Ae=!1;const M=new Map,J=Pe?new Pe(t=>{M.delete(t)}):null;function De(t){return qe.createAuthClient({baseURL:ae(),basePath:Be,...t!=null&&t.disableDefaultRedirectPlugin?{disableDefaultFetchPlugins:!0}:{},fetchOptions:{credentials:"include"}})}function O(t){var e,i;return(i=(e=t.$store)==null?void 0:e.atoms)==null?void 0:i.session}function tt(t){return JSON.stringify({source:t,timestamp:Date.now()})}function st(t){if(typeof t!="string")return null;try{const e=JSON.parse(t);return e&&typeof e=="object"?e:null}catch{return null}}function it(t){return t.join(".")}function nt(t){const e=it(t),i=Qe.get(e);return i?new _(i,{code:"UNSUPPORTED_AUTH_METHOD"}):null}async function le(t){var e;try{return await((e=O(t))==null?void 0:e.get().refetch()),!0}catch{return!1}}function Ne(){return Y===void 0&&(Y=typeof BroadcastChannel<"u"?new BroadcastChannel(Je):null),Y}function Le(t){const e=st(t);if(e)for(const[i,s]of M){if(i===e.source)continue;const n=s.deref();if(!n){M.delete(i);continue}le(n)}}function rt(){var t;Ae||(Ae=!0,(t=Ne())==null||t.addEventListener("message",e=>{Le(e.data)}),typeof window<"u"&&window.addEventListener("storage",e=>{e.key!==Oe||e.newValue===null||Le(e.newValue)}))}function ot(t,e){_e?M.set(t,new _e(e)):(M.clear(),M.set(t,new et(e))),J==null||J.register(e,t),rt()}function $(t){const e=tt(t),i=Ne();let s=!1;if(i)try{i.postMessage(e),s=!0}catch{}if(!s)try{window.localStorage.setItem(Oe,e)}catch{}}function X(t){if(!(typeof window>"u"))try{window.sessionStorage.setItem(W,JSON.stringify({path:t,createdAt:Date.now()}))}catch{}}function B(){if(!(typeof window>"u"))try{window.sessionStorage.removeItem(W)}catch{}}function at(t){return!!(t!=null&&t.session&&(t!=null&&t.user))}function w(t){return t instanceof Date?t.toISOString():t===null||typeof t=="string"||typeof t=="number"||typeof t=="boolean"?t:t==null?null:String(t)}function lt(t){return t?JSON.stringify({session:{createdAt:w(t.session.createdAt),expiresAt:w(t.session.expiresAt),id:w(t.session.id),impersonatedBy:w(t.session.impersonatedBy),ipAddress:w(t.session.ipAddress),token:w(t.session.token),updatedAt:w(t.session.updatedAt),userAgent:w(t.session.userAgent),userId:w(t.session.userId)},user:{banExpires:w(t.user.banExpires),banReason:w(t.user.banReason),banned:w(t.user.banned),createdAt:w(t.user.createdAt),email:w(t.user.email),emailVerified:w(t.user.emailVerified),id:w(t.user.id),image:w(t.user.image),lastLoginAt:w(t.user.lastLoginAt),name:w(t.user.name),role:w(t.user.role),updatedAt:w(t.user.updatedAt)}}):"__null__"}function Ve(){if(typeof window>"u")return null;try{const t=window.sessionStorage.getItem(W);if(!t)return null;const e=JSON.parse(t);return!e||typeof e!="object"||typeof e.createdAt!="number"||Date.now()-e.createdAt>Xe?null:{createdAt:e.createdAt}}catch{return null}}function Te(){if(!Ve())return!1;try{window.sessionStorage.removeItem(W)}catch{}return!0}function dt(){return Ve()!==null}function ct(t){if(!(t&&typeof t=="object")||"error"in t&&t.error)return!1;const e="data"in t?t.data:t;return e&&typeof e=="object"?"token"in e&&typeof e.token=="string"&&e.token.length>0?!0:"session"in e&&"user"in e&&!!e.session&&!!e.user:!1}function ut(t){if(!(t&&typeof t=="object")||"error"in t&&t.error)return!1;const e="data"in t?t.data:t;return e&&typeof e=="object"?"url"in e&&typeof e.url=="string":!1}function ht(t){if(k(t)||!(t&&typeof t=="object"))return!1;const e="data"in t?t.data:t;return e&&typeof e=="object"?"user"in e&&!!e.user&&"token"in e&&e.token===null&&!("url"in e):!1}function mt(t,e){if(t.length!==1||t[0]!=="changePassword")return!1;const[i]=e;return!!(i&&typeof i=="object"&&"revokeOtherSessions"in i&&i.revokeOtherSessions===!0)}function k(t){return!!(t&&typeof t=="object"&&"error"in t&&t.error)}function ft(t){if(k(t)||!(t&&typeof t=="object"))return!1;const e="data"in t?t.data:t;return e&&typeof e=="object"?"message"in e&&e.message==="User deleted":!1}function gt(t){return!!(t&&(typeof t=="object"||typeof t=="function")&&"then"in t&&typeof t.then=="function")}function Z(t){return ye(t,"Failed to load the current session.","SESSION_LOOKUP_FAILED")}async function wt(t){var i,s;let e=null;try{await((i=O(t))==null?void 0:i.get().refetch())}catch(n){e=n}finally{(s=t[Me])==null||s.call(t)}if(e)throw e}function pt(){const t=De(),e=`${Date.now()}-${Math.random().toString(36).slice(2)}`;ot(e,t);const i=2,s=500;let n=null,o=!1,u;const f=a=>(u=a,a),p=()=>{var h;const a=(h=O(t))==null?void 0:h.get();return a!=null&&a.error&&!a.data&&u!==void 0?u:(a==null?void 0:a.data)??u??null},L=()=>o?Promise.resolve(p()):(n||(n=(async()=>{var l,m,T;let a=!1,h=null;try{for(let A=0;A<=i;A++){let c=null;try{c=await t.getSession()}catch(I){h=I}const E=((l=O(t))==null?void 0:l.get().data)??null;if((m=c==null?void 0:c.data)!=null&&m.session&&((T=c.data)!=null&&T.user))return o=!0,Te()&&$(e),f(c.data);if(E!=null&&E.session&&(E!=null&&E.user))return o=!0,Te()&&$(e),f(E);if(c!=null&&c.error?h=c.error:c&&(a=!0),c&&!c.error&&dt()&&A<i){await new Promise(I=>setTimeout(I,s));continue}if(c&&!c.error){const I=p();return o=!0,f(I)}A<i&&await new Promise(I=>setTimeout(I,s))}if(!a)throw n=null,new _("Failed to load the current session.",{code:"SESSION_LOOKUP_FAILED",cause:h});const v=p();return o=!0,f(v)}catch(v){throw n=null,Z(v)}})()),n);L().catch(()=>{});const y=async()=>{var a,h;try{const l=await t.getSession();if((a=l.data)!=null&&a.session&&((h=l.data)!=null&&h.user))return l.data;throw l.error?Z(l.error):new _("No authenticated session is available.",{code:"UNAUTHENTICATED"})}catch(l){throw Z(l)}},b=async()=>{await le(t),$(e)},P=async()=>{var l;const a=await le(t),h=((l=O(t))==null?void 0:l.get().data)??null;at(h)?(B(),$(e)):a||$(e)},d=a=>{let h=!1,l=!1,m;const T=c=>{const E=lt(c);E!==m&&(m=E,a(c))};L().then(c=>{h||(l=!0,T(f(c)))}).catch(()=>{h||(l=!0)});const v=O(t);if(!v)return()=>{h=!0};const A=v.subscribe(c=>{if(h||!l||c.error&&!c.data)return;const E=c.data??null;T(f(E))});return()=>{h=!0,A()}},S=async(a,h,l)=>{const m=a[0],T=a.length>=2&&m==="emailOtp"&&a[1]==="verifyEmail",v=a.length>=2&&m==="emailOtp"&&a[1]==="resetPassword",A=a.length>=2&&m==="resetPassword"&&a[1]==="emailOtp",c=a.length>=2&&m==="oneTap"&&a[1]==="callback";return a.length===1&&(m==="deleteUser"||m==="deleteUserCallback")?(B(),ft(l)&&await b(),l):a.length===1&&m&&Ze.has(m)?(B(),k(l)||await b(),l):mt(a,h)&&!k(l)?(B(),await b(),l):(v||A)&&!k(l)?(B(),await b(),l):a.length===1&&m==="changeEmail"&&!k(l)?(await b(),l):((m==="signIn"||m==="signUp"||T||c)&&ct(l)?(B(),await b()):(m==="signIn"||m==="signUp")&&ut(l)||m==="signUp"&&ht(l)?X(a):m==="verifyEmail"&&!k(l)&&(X(a),await P()),l)},R=new WeakMap,D=(a,h)=>{if(!a||typeof a!="object"&&typeof a!="function")return a;const l=R.get(a);if(l)return l;const m=new Proxy(a,{get(T,v,A){if(h.length===0){if(v==="requireSession")return y;if(v==="onSessionChange")return d;if(v===Me)return()=>{$(e)}}const c=Reflect.get(T,v,A);return typeof v!="string"?c:D(c,[...h,v])},apply(T,v,A){const c=nt(h);if(c)throw c;const E=Reflect.apply(T,v,A);return gt(E)?Promise.resolve(E).then(I=>S(h,A,I)):E}});return R.set(a,m),m};return D(t,[])}function bt(){return De({disableDefaultRedirectPlugin:!0})}const He="/api/_es/dev";function yt(){if(typeof document>"u")return!1;const t=document.querySelector('meta[name="edgespark-local-dev"]');return(t==null?void 0:t.getAttribute("content"))==="true"}async function vt(t){const e=typeof window<"u"?window.location.origin:"";if(!e)return!1;const i=await fetch(`${e}${He}/auto-verify?email=${encodeURIComponent(t)}`,{credentials:"include"});return i.ok?(await i.json()).verified===!0:!1}async function Et(t){const e=typeof window<"u"?window.location.origin:"";if(!e)return null;try{const i=await fetch(`${e}${He}/pending-otp?email=${encodeURIComponent(t)}`,{credentials:"include"});return i.ok?(await i.json()).otp??null:null}catch{return null}}function St(t){const e=(()=>{if(t instanceof URL)return t;const i=t.trim();if(!i)throw new g("redirectTo must not be an empty string.");try{return new URL(i,window.location.href)}catch{throw new g(`redirectTo must be a valid relative path or URL. Received: ${JSON.stringify(t)}`)}})();if(e.protocol!=="http:"&&e.protocol!=="https:")throw new g(`redirectTo must resolve to an http(s) URL. Received protocol: ${e.protocol}`);return e}function _t(t,e){return e?{common:{...t.common,...e.common},signIn:{...t.signIn,...e.signIn},signUp:{...t.signUp,...e.signUp},verifyEmail:{...t.verifyEmail,...e.verifyEmail},forgotPassword:{...t.forgotPassword,...e.forgotPassword},resetPassword:{...t.resetPassword,...e.resetPassword},oauth:{...t.oauth,...e.oauth},errors:{...t.errors,...e.errors}}:t}const H={common:{loading:"Loading sign-in…",redirecting:"Redirecting…",backToSignIn:"Back to sign in"},signIn:{title:"Welcome back",subtitle:"Sign in to continue",emailLabel:"Email",passwordLabel:"Password",submitButton:"Sign in",forgotPassword:"Forgot password?",switchToSignUp:"Create an account",signUpPrompt:"Don’t have an account?"},signUp:{title:"Create your account",subtitle:"Start with your name, email, and password",nameLabel:"Name",emailLabel:"Email",passwordLabel:"Password",confirmPasswordLabel:"Confirm password",submitButton:"Create account",switchToSignIn:"Sign in",signInPrompt:"Already have an account?"},verifyEmail:{title:"Verify your email",subtitle:"Finish account setup from the verification email we sent.",sentToLabel:"Sent to",resendButton:"Resend verification email",resendCountdown:"Resend in {seconds}s",changeEmailButton:"Use a different email"},forgotPassword:{title:"Reset your password",subtitle:"Enter your email and we will send a reset code.",emailLabel:"Email",submitButton:"Send reset code"},resetPassword:{title:"Set a new password",subtitle:"Use the code from your email to finish resetting your password.",codeLabel:"Verification code",newPasswordLabel:"New password",confirmPasswordLabel:"Confirm password",submitButton:"Update password",resendCodeButton:"Resend code",resendCountdown:"Resend in {seconds}s"},oauth:{dividerText:"or",continueWith:"Continue with"},errors:{invalidEmail:"Enter a valid email address.",requiredField:"This field is required.",passwordTooShort:"Password must be at least {min} characters.",passwordMismatch:"Passwords do not match.",invalidCode:"Enter the 6-digit verification code.",generic:"Something went wrong. Please try again."}},x={common:{loading:"加载中…",redirecting:"跳转中…",backToSignIn:"返回登录"},signIn:{title:"欢迎回来",subtitle:"登录以继续",emailLabel:"邮箱",passwordLabel:"密码",submitButton:"登录",forgotPassword:"忘记密码?",switchToSignUp:"立即注册",signUpPrompt:"没有账号?"},signUp:{title:"创建账号",subtitle:"填写姓名、邮箱和密码开始使用",nameLabel:"姓名",emailLabel:"邮箱",passwordLabel:"密码",confirmPasswordLabel:"确认密码",submitButton:"注册",switchToSignIn:"去登录",signInPrompt:"已有账号?"},verifyEmail:{title:"验证邮箱",subtitle:"请查收邮件并点击验证链接",sentToLabel:"已发送至",resendButton:"重新发送验证邮件",resendCountdown:"{seconds}秒后可重发",changeEmailButton:"更换邮箱"},forgotPassword:{title:"重置密码",subtitle:"输入邮箱以接收重置验证码",emailLabel:"邮箱",submitButton:"发送重置码"},resetPassword:{title:"设置新密码",subtitle:"使用邮件中的验证码完成密码重置",codeLabel:"验证码",newPasswordLabel:"新密码",confirmPasswordLabel:"确认密码",submitButton:"更新密码",resendCodeButton:"重新发送",resendCountdown:"{seconds}秒后可重发"},oauth:{dividerText:"或",continueWith:"使用"},errors:{invalidEmail:"请输入有效的邮箱地址",requiredField:"此项为必填",passwordTooShort:"密码至少需要 {min} 个字符",passwordMismatch:"两次密码输入不一致",invalidCode:"请输入 6 位验证码",generic:"出现错误,请稍后重试"}},de={common:{loading:"サインインを読み込み中…",redirecting:"リダイレクト中…",backToSignIn:"サインインに戻る"},signIn:{title:"おかえりなさい",subtitle:"サインインして続行",emailLabel:"メールアドレス",passwordLabel:"パスワード",submitButton:"サインイン",forgotPassword:"パスワードをお忘れですか?",switchToSignUp:"アカウントを作成",signUpPrompt:"アカウントをお持ちでない方"},signUp:{title:"アカウントを作成",subtitle:"名前、メールアドレス、パスワードを入力してください",nameLabel:"名前",emailLabel:"メールアドレス",passwordLabel:"パスワード",confirmPasswordLabel:"パスワード(確認)",submitButton:"アカウント作成",switchToSignIn:"サインイン",signInPrompt:"既にアカウントをお持ちですか?"},verifyEmail:{title:"メールアドレスを確認",subtitle:"送信した確認メールからアカウント設定を完了してください",sentToLabel:"送信先",resendButton:"確認メールを再送信",resendCountdown:"{seconds}秒後に再送信可能",changeEmailButton:"別のメールアドレスを使用"},forgotPassword:{title:"パスワードをリセット",subtitle:"メールアドレスを入力するとリセットコードをお送りします",emailLabel:"メールアドレス",submitButton:"リセットコードを送信"},resetPassword:{title:"新しいパスワードを設定",subtitle:"メールで届いた認証コードを使ってパスワードをリセットしてください",codeLabel:"認証コード",newPasswordLabel:"新しいパスワード",confirmPasswordLabel:"パスワード(確認)",submitButton:"パスワードを更新",resendCodeButton:"コードを再送信",resendCountdown:"{seconds}秒後に再送信可能"},oauth:{dividerText:"または",continueWith:"で続行"},errors:{invalidEmail:"有効なメールアドレスを入力してください",requiredField:"この項目は必須です",passwordTooShort:"パスワードは {min} 文字以上で入力してください",passwordMismatch:"パスワードが一致しません",invalidCode:"6桁の認証コードを入力してください",generic:"エラーが発生しました。もう一度お試しください"}},ce={common:{loading:"로그인 로딩 중…",redirecting:"리디렉션 중…",backToSignIn:"로그인으로 돌아가기"},signIn:{title:"다시 오신 것을 환영합니다",subtitle:"로그인하여 계속하기",emailLabel:"이메일",passwordLabel:"비밀번호",submitButton:"로그인",forgotPassword:"비밀번호를 잊으셨나요?",switchToSignUp:"계정 만들기",signUpPrompt:"계정이 없으신가요?"},signUp:{title:"계정 만들기",subtitle:"이름, 이메일, 비밀번호를 입력해 주세요",nameLabel:"이름",emailLabel:"이메일",passwordLabel:"비밀번호",confirmPasswordLabel:"비밀번호 확인",submitButton:"계정 생성",switchToSignIn:"로그인",signInPrompt:"이미 계정이 있으신가요?"},verifyEmail:{title:"이메일 인증",subtitle:"발송된 인증 이메일에서 계정 설정을 완료해 주세요",sentToLabel:"발송 대상",resendButton:"인증 이메일 재발송",resendCountdown:"{seconds}초 후 재발송 가능",changeEmailButton:"다른 이메일 사용"},forgotPassword:{title:"비밀번호 재설정",subtitle:"이메일을 입력하시면 재설정 코드를 보내드립니다",emailLabel:"이메일",submitButton:"재설정 코드 발송"},resetPassword:{title:"새 비밀번호 설정",subtitle:"이메일로 받은 인증 코드를 사용하여 비밀번호를 재설정하세요",codeLabel:"인증 코드",newPasswordLabel:"새 비밀번호",confirmPasswordLabel:"비밀번호 확인",submitButton:"비밀번호 변경",resendCodeButton:"코드 재발송",resendCountdown:"{seconds}초 후 재발송 가능"},oauth:{dividerText:"또는",continueWith:"으로 계속"},errors:{invalidEmail:"올바른 이메일 주소를 입력해 주세요",requiredField:"필수 입력 항목입니다",passwordTooShort:"비밀번호는 최소 {min}자 이상이어야 합니다",passwordMismatch:"비밀번호가 일치하지 않습니다",invalidCode:"6자리 인증 코드를 입력해 주세요",generic:"문제가 발생했습니다. 다시 시도해 주세요"}},q={common:{loading:"Cargando inicio de sesión…",redirecting:"Redirigiendo…",backToSignIn:"Volver a iniciar sesión"},signIn:{title:"Bienvenido de nuevo",subtitle:"Inicia sesión para continuar",emailLabel:"Correo electrónico",passwordLabel:"Contraseña",submitButton:"Iniciar sesión",forgotPassword:"¿Olvidaste tu contraseña?",switchToSignUp:"Crear una cuenta",signUpPrompt:"¿No tienes cuenta?"},signUp:{title:"Crea tu cuenta",subtitle:"Empieza con tu nombre, correo y contraseña",nameLabel:"Nombre",emailLabel:"Correo electrónico",passwordLabel:"Contraseña",confirmPasswordLabel:"Confirmar contraseña",submitButton:"Crear cuenta",switchToSignIn:"Iniciar sesión",signInPrompt:"¿Ya tienes una cuenta?"},verifyEmail:{title:"Verifica tu correo",subtitle:"Completa la configuración desde el correo de verificación que te enviamos.",sentToLabel:"Enviado a",resendButton:"Reenviar correo de verificación",resendCountdown:"Reenviar en {seconds}s",changeEmailButton:"Usar otro correo"},forgotPassword:{title:"Restablecer contraseña",subtitle:"Ingresa tu correo y te enviaremos un código de restablecimiento.",emailLabel:"Correo electrónico",submitButton:"Enviar código"},resetPassword:{title:"Establece una nueva contraseña",subtitle:"Usa el código de tu correo para completar el restablecimiento.",codeLabel:"Código de verificación",newPasswordLabel:"Nueva contraseña",confirmPasswordLabel:"Confirmar contraseña",submitButton:"Actualizar contraseña",resendCodeButton:"Reenviar código",resendCountdown:"Reenviar en {seconds}s"},oauth:{dividerText:"o",continueWith:"Continuar con"},errors:{invalidEmail:"Ingresa una dirección de correo válida.",requiredField:"Este campo es obligatorio.",passwordTooShort:"La contraseña debe tener al menos {min} caracteres.",passwordMismatch:"Las contraseñas no coinciden.",invalidCode:"Ingresa el código de verificación de 6 dígitos.",generic:"Algo salió mal. Por favor, inténtalo de nuevo."}},ue={common:{loading:"Carregando login…",redirecting:"Redirecionando…",backToSignIn:"Voltar para o login"},signIn:{title:"Bem-vindo de volta",subtitle:"Faça login para continuar",emailLabel:"E-mail",passwordLabel:"Senha",submitButton:"Entrar",forgotPassword:"Esqueceu a senha?",switchToSignUp:"Criar uma conta",signUpPrompt:"Não tem uma conta?"},signUp:{title:"Crie sua conta",subtitle:"Comece com seu nome, e-mail e senha",nameLabel:"Nome",emailLabel:"E-mail",passwordLabel:"Senha",confirmPasswordLabel:"Confirmar senha",submitButton:"Criar conta",switchToSignIn:"Entrar",signInPrompt:"Já tem uma conta?"},verifyEmail:{title:"Verifique seu e-mail",subtitle:"Conclua a configuração a partir do e-mail de verificação que enviamos.",sentToLabel:"Enviado para",resendButton:"Reenviar e-mail de verificação",resendCountdown:"Reenviar em {seconds}s",changeEmailButton:"Usar outro e-mail"},forgotPassword:{title:"Redefinir senha",subtitle:"Informe seu e-mail e enviaremos um código de redefinição.",emailLabel:"E-mail",submitButton:"Enviar código"},resetPassword:{title:"Defina uma nova senha",subtitle:"Use o código recebido por e-mail para concluir a redefinição.",codeLabel:"Código de verificação",newPasswordLabel:"Nova senha",confirmPasswordLabel:"Confirmar senha",submitButton:"Atualizar senha",resendCodeButton:"Reenviar código",resendCountdown:"Reenviar em {seconds}s"},oauth:{dividerText:"ou",continueWith:"Continuar com"},errors:{invalidEmail:"Insira um endereço de e-mail válido.",requiredField:"Este campo é obrigatório.",passwordTooShort:"A senha deve ter pelo menos {min} caracteres.",passwordMismatch:"As senhas não coincidem.",invalidCode:"Insira o código de verificação de 6 dígitos.",generic:"Algo deu errado. Por favor, tente novamente."}},he={common:{loading:"Chargement de la connexion…",redirecting:"Redirection…",backToSignIn:"Retour à la connexion"},signIn:{title:"Bon retour",subtitle:"Connectez-vous pour continuer",emailLabel:"Adresse e-mail",passwordLabel:"Mot de passe",submitButton:"Se connecter",forgotPassword:"Mot de passe oublié ?",switchToSignUp:"Créer un compte",signUpPrompt:"Vous n’avez pas de compte ?"},signUp:{title:"Créez votre compte",subtitle:"Commencez par votre nom, e-mail et mot de passe",nameLabel:"Nom",emailLabel:"Adresse e-mail",passwordLabel:"Mot de passe",confirmPasswordLabel:"Confirmer le mot de passe",submitButton:"Créer le compte",switchToSignIn:"Se connecter",signInPrompt:"Vous avez déjà un compte ?"},verifyEmail:{title:"Vérifiez votre e-mail",subtitle:"Finalisez la création de votre compte depuis l’e-mail de vérification envoyé.",sentToLabel:"Envoyé à",resendButton:"Renvoyer l’e-mail de vérification",resendCountdown:"Renvoyer dans {seconds}s",changeEmailButton:"Utiliser un autre e-mail"},forgotPassword:{title:"Réinitialiser le mot de passe",subtitle:"Saisissez votre e-mail pour recevoir un code de réinitialisation.",emailLabel:"Adresse e-mail",submitButton:"Envoyer le code"},resetPassword:{title:"Définir un nouveau mot de passe",subtitle:"Utilisez le code reçu par e-mail pour réinitialiser votre mot de passe.",codeLabel:"Code de vérification",newPasswordLabel:"Nouveau mot de passe",confirmPasswordLabel:"Confirmer le mot de passe",submitButton:"Mettre à jour le mot de passe",resendCodeButton:"Renvoyer le code",resendCountdown:"Renvoyer dans {seconds}s"},oauth:{dividerText:"ou",continueWith:"Continuer avec"},errors:{invalidEmail:"Veuillez saisir une adresse e-mail valide.",requiredField:"Ce champ est requis.",passwordTooShort:"Le mot de passe doit contenir au moins {min} caractères.",passwordMismatch:"Les mots de passe ne correspondent pas.",invalidCode:"Saisissez le code de vérification à 6 chiffres.",generic:"Une erreur est survenue. Veuillez réessayer."}},me={common:{loading:"Anmeldung wird geladen…",redirecting:"Weiterleitung…",backToSignIn:"Zurück zur Anmeldung"},signIn:{title:"Willkommen zurück",subtitle:"Melden Sie sich an, um fortzufahren",emailLabel:"E-Mail-Adresse",passwordLabel:"Passwort",submitButton:"Anmelden",forgotPassword:"Passwort vergessen?",switchToSignUp:"Konto erstellen",signUpPrompt:"Noch kein Konto?"},signUp:{title:"Konto erstellen",subtitle:"Geben Sie Ihren Namen, Ihre E-Mail und ein Passwort ein",nameLabel:"Name",emailLabel:"E-Mail-Adresse",passwordLabel:"Passwort",confirmPasswordLabel:"Passwort bestätigen",submitButton:"Konto erstellen",switchToSignIn:"Anmelden",signInPrompt:"Bereits ein Konto?"},verifyEmail:{title:"E-Mail bestätigen",subtitle:"Schließen Sie die Einrichtung über die Bestätigungs-E-Mail ab, die wir Ihnen gesendet haben.",sentToLabel:"Gesendet an",resendButton:"Bestätigungs-E-Mail erneut senden",resendCountdown:"Erneut senden in {seconds}s",changeEmailButton:"Andere E-Mail verwenden"},forgotPassword:{title:"Passwort zurücksetzen",subtitle:"Geben Sie Ihre E-Mail ein und wir senden Ihnen einen Zurücksetzungscode.",emailLabel:"E-Mail-Adresse",submitButton:"Code senden"},resetPassword:{title:"Neues Passwort festlegen",subtitle:"Verwenden Sie den Code aus der E-Mail, um Ihr Passwort zurückzusetzen.",codeLabel:"Bestätigungscode",newPasswordLabel:"Neues Passwort",confirmPasswordLabel:"Passwort bestätigen",submitButton:"Passwort aktualisieren",resendCodeButton:"Code erneut senden",resendCountdown:"Erneut senden in {seconds}s"},oauth:{dividerText:"oder",continueWith:"Weiter mit"},errors:{invalidEmail:"Bitte geben Sie eine gültige E-Mail-Adresse ein.",requiredField:"Dieses Feld ist erforderlich.",passwordTooShort:"Das Passwort muss mindestens {min} Zeichen lang sein.",passwordMismatch:"Die Passwörter stimmen nicht überein.",invalidCode:"Geben Sie den 6-stelligen Bestätigungscode ein.",generic:"Etwas ist schiefgelaufen. Bitte versuchen Sie es erneut."}},fe={common:{loading:"Caricamento accesso…",redirecting:"Reindirizzamento…",backToSignIn:"Torna all’accesso"},signIn:{title:"Bentornato",subtitle:"Accedi per continuare",emailLabel:"Indirizzo e-mail",passwordLabel:"Password",submitButton:"Accedi",forgotPassword:"Password dimenticata?",switchToSignUp:"Crea un account",signUpPrompt:"Non hai un account?"},signUp:{title:"Crea il tuo account",subtitle:"Inserisci nome, e-mail e password per iniziare",nameLabel:"Nome",emailLabel:"Indirizzo e-mail",passwordLabel:"Password",confirmPasswordLabel:"Conferma password",submitButton:"Crea account",switchToSignIn:"Accedi",signInPrompt:"Hai già un account?"},verifyEmail:{title:"Verifica la tua e-mail",subtitle:"Completa la configurazione dall’e-mail di verifica che ti abbiamo inviato.",sentToLabel:"Inviata a",resendButton:"Reinvia e-mail di verifica",resendCountdown:"Reinvia tra {seconds}s",changeEmailButton:"Usa un’altra e-mail"},forgotPassword:{title:"Reimposta la password",subtitle:"Inserisci la tua e-mail e ti invieremo un codice di reimpostazione.",emailLabel:"Indirizzo e-mail",submitButton:"Invia codice"},resetPassword:{title:"Imposta una nuova password",subtitle:"Usa il codice ricevuto via e-mail per reimpostare la password.",codeLabel:"Codice di verifica",newPasswordLabel:"Nuova password",confirmPasswordLabel:"Conferma password",submitButton:"Aggiorna password",resendCodeButton:"Reinvia codice",resendCountdown:"Reinvia tra {seconds}s"},oauth:{dividerText:"oppure",continueWith:"Continua con"},errors:{invalidEmail:"Inserisci un indirizzo e-mail valido.",requiredField:"Questo campo è obbligatorio.",passwordTooShort:"La password deve contenere almeno {min} caratteri.",passwordMismatch:"Le password non corrispondono.",invalidCode:"Inserisci il codice di verifica a 6 cifre.",generic:"Qualcosa è andato storto. Riprova."}},ge={common:{loading:"Загрузка входа…",redirecting:"Перенаправление…",backToSignIn:"Вернуться ко входу"},signIn:{title:"С возвращением",subtitle:"Войдите, чтобы продолжить",emailLabel:"Электронная почта",passwordLabel:"Пароль",submitButton:"Войти",forgotPassword:"Забыли пароль?",switchToSignUp:"Создать аккаунт",signUpPrompt:"Нет аккаунта?"},signUp:{title:"Создание аккаунта",subtitle:"Укажите имя, электронную почту и пароль",nameLabel:"Имя",emailLabel:"Электронная почта",passwordLabel:"Пароль",confirmPasswordLabel:"Подтвердите пароль",submitButton:"Создать аккаунт",switchToSignIn:"Войти",signInPrompt:"Уже есть аккаунт?"},verifyEmail:{title:"Подтвердите почту",subtitle:"Завершите настройку через письмо с подтверждением, которое мы отправили.",sentToLabel:"Отправлено на",resendButton:"Отправить повторно",resendCountdown:"Повторная отправка через {seconds}с",changeEmailButton:"Использовать другую почту"},forgotPassword:{title:"Сброс пароля",subtitle:"Введите электронную почту, и мы отправим код для сброса.",emailLabel:"Электронная почта",submitButton:"Отправить код"},resetPassword:{title:"Установите новый пароль",subtitle:"Используйте код из письма для завершения сброса пароля.",codeLabel:"Код подтверждения",newPasswordLabel:"Новый пароль",confirmPasswordLabel:"Подтвердите пароль",submitButton:"Обновить пароль",resendCodeButton:"Отправить код повторно",resendCountdown:"Повторная отправка через {seconds}с"},oauth:{dividerText:"или",continueWith:"Продолжить через"},errors:{invalidEmail:"Введите корректный адрес электронной почты.",requiredField:"Это поле обязательно.",passwordTooShort:"Пароль должен содержать не менее {min} символов.",passwordMismatch:"Пароли не совпадают.",invalidCode:"Введите 6-значный код подтверждения.",generic:"Произошла ошибка. Пожалуйста, попробуйте снова."}},we={common:{loading:"جارٍ تحميل تسجيل الدخول…",redirecting:"جارٍ إعادة التوجيه…",backToSignIn:"العودة إلى تسجيل الدخول"},signIn:{title:"مرحبًا بعودتك",subtitle:"سجّل الدخول للمتابعة",emailLabel:"البريد الإلكتروني",passwordLabel:"كلمة المرور",submitButton:"تسجيل الدخول",forgotPassword:"هل نسيت كلمة المرور؟",switchToSignUp:"إنشاء حساب",signUpPrompt:"ليس لديك حساب؟"},signUp:{title:"أنشئ حسابك",subtitle:"ابدأ بإدخال اسمك وبريدك الإلكتروني وكلمة المرور",nameLabel:"الاسم",emailLabel:"البريد الإلكتروني",passwordLabel:"كلمة المرور",confirmPasswordLabel:"تأكيد كلمة المرور",submitButton:"إنشاء الحساب",switchToSignIn:"تسجيل الدخول",signInPrompt:"لديك حساب بالفعل؟"},verifyEmail:{title:"تحقّق من بريدك الإلكتروني",subtitle:"أكمل إعداد حسابك من رسالة التحقّق التي أرسلناها.",sentToLabel:"أُرسل إلى",resendButton:"إعادة إرسال رسالة التحقّق",resendCountdown:"إعادة الإرسال خلال {seconds} ثانية",changeEmailButton:"استخدام بريد إلكتروني آخر"},forgotPassword:{title:"إعادة تعيين كلمة المرور",subtitle:"أدخل بريدك الإلكتروني وسنرسل لك رمز إعادة التعيين.",emailLabel:"البريد الإلكتروني",submitButton:"إرسال رمز إعادة التعيين"},resetPassword:{title:"تعيين كلمة مرور جديدة",subtitle:"استخدم الرمز المرسل إلى بريدك لإكمال إعادة تعيين كلمة المرور.",codeLabel:"رمز التحقّق",newPasswordLabel:"كلمة المرور الجديدة",confirmPasswordLabel:"تأكيد كلمة المرور",submitButton:"تحديث كلمة المرور",resendCodeButton:"إعادة إرسال الرمز",resendCountdown:"إعادة الإرسال خلال {seconds} ثانية"},oauth:{dividerText:"أو",continueWith:"المتابعة باستخدام"},errors:{invalidEmail:"يرجى إدخال عنوان بريد إلكتروني صالح.",requiredField:"هذا الحقل مطلوب.",passwordTooShort:"يجب أن تتكوّن كلمة المرور من {min} حرفًا على الأقل.",passwordMismatch:"كلمتا المرور غير متطابقتين.",invalidCode:"يرجى إدخال رمز التحقّق المكوّن من 6 أرقام.",generic:"حدث خطأ. يرجى المحاولة مرة أخرى."}},pe={common:{loading:"सधाइन की जुलातीअ लोड हो रही है…",redirecting:"रीडायरेक्ट हो रहا है…",backToSignIn:"साइन इन पर वापस जाएँ"},signIn:{title:"वापसी आपका स्वागत है",subtitle:"जारी रखने के लिए साइन इन करें",emailLabel:"ईमेल",passwordLabel:"पासवर्ड",submitButton:"साइन इन",forgotPassword:"पासवर्ड भूल गए?",switchToSignUp:"खाता बनाएँ",signUpPrompt:"खाता नहीं है?"},signUp:{title:"अपना खाता बनाएँ",subtitle:"अपना नाम, ईमेल और पासवर्ड दर्ज करें",nameLabel:"नाम",emailLabel:"ईमेल",passwordLabel:"पासवर्ड",confirmPasswordLabel:"पासवर्ड की पुष्टि",submitButton:"खाता बनाएँ",switchToSignIn:"साइन इन",signInPrompt:"पहले से खाता है?"},verifyEmail:{title:"अपना ईमेल सत्यापित करें",subtitle:"हमने जो सत्यापन ईमेल भेजा है उससे सेटअप पूरा करें।",sentToLabel:"भेजा गया",resendButton:"सत्यापन ईमेल फिर से भेजें",resendCountdown:"{seconds} सेकंड में फिर से भेजें",changeEmailButton:"दूसरा ईमेल इस्तेमाल करें"},forgotPassword:{title:"पासवर्ड रीसेट करें",subtitle:"अपना ईमेल दर्ज करें और हम रीसेट कोड भेजेंगे।",emailLabel:"ईमेल",submitButton:"रीसेट कोड भेजें"},resetPassword:{title:"नया पासवर्ड सेट करें",subtitle:"पासवर्ड रीसेट पूरा करने के लिए ईमेल में प्राप्त कोड का उपयोग करें।",codeLabel:"सत्यापन कोड",newPasswordLabel:"नया पासवर्ड",confirmPasswordLabel:"पासवर्ड की पुष्टि",submitButton:"पासवर्ड अपडेट करें",resendCodeButton:"कोड फिर से भेजें",resendCountdown:"{seconds} सेकंड में फिर से भेजें"},oauth:{dividerText:"या",continueWith:"से जारी रखें"},errors:{invalidEmail:"कृपया एक वैध ईमेल पता दर्ज करें।",requiredField:"यह फ़ील्ड आवश्यक है।",passwordTooShort:"पासवर्ड कम से कम {min} अक्षरों का होना चाहिए।",passwordMismatch:"पासवर्ड मेल नहीं खाते।",invalidCode:"कृपया 6 अंकों का सत्यापन कोड दर्ज करें।",generic:"कुछ गलत हो गई। कृपया फिर से प्रयास करें।"}},Ie={en:H,"en-US":H,zh:x,"zh-CN":x,"zh-TW":x,ja:de,"ja-JP":de,ko:ce,"ko-KR":ce,es:q,"es-ES":q,"es-MX":q,pt:ue,"pt-BR":ue,fr:he,"fr-FR":he,de:me,"de-DE":me,it:fe,"it-IT":fe,ru:ge,"ru-RU":ge,ar:we,"ar-SA":we,hi:pe,"hi-IN":pe};function Fe(){if(typeof navigator>"u")return H;const t=navigator.languages??[navigator.language];for(const e of t){const i=Ie[e]??Ie[e.split("-")[0]];if(i)return i}return H}const ve={LIGHT:"light",DARK:"dark"},Ee=ve.LIGHT,Ge=ve.DARK,Se=[Ee,Ge],ze=Ee,je={BACKGROUND:"--edgespark-auth-bg",BACKGROUND_MUTED:"--edgespark-auth-bg-muted",CARD_BACKGROUND:"--edgespark-auth-card-bg",BORDER:"--edgespark-auth-border",TEXT:"--edgespark-auth-text",TEXT_MUTED:"--edgespark-auth-text-muted",DIVIDER_BACKGROUND:"--edgespark-auth-divider-bg",PRIMARY:"--edgespark-auth-primary",PRIMARY_HOVER:"--edgespark-auth-primary-hover",PRIMARY_CONTRAST:"--edgespark-auth-primary-contrast",ERROR:"--edgespark-auth-error",INFO:"--edgespark-auth-info",CARD_RADIUS:"--edgespark-auth-radius-card",CONTROL_RADIUS:"--edgespark-auth-radius-control",SHADOW:"--edgespark-auth-shadow",FONT:"--edgespark-auth-font",MODAL_BACKDROP:"--edgespark-auth-modal-backdrop",MODAL_CARD_BACKGROUND:"--edgespark-auth-modal-card-bg",MODAL_SHADOW:"--edgespark-auth-modal-shadow"},xe=Object.values(je);function Pt(t){return typeof t=="string"&&Se.includes(t)}function At(t){return xe.includes(t)}function Lt(t){var e;return{theme:(t==null?void 0:t.theme)??ze,className:((e=t==null?void 0:t.className)==null?void 0:e.trim())??"",variables:{...(t==null?void 0:t.variables)??{}}}}function Q(t,e="Authentication failed."){return ye(t,e)}async function V(t){var i,s;const e=await t.getSession();if(e.error)throw new _(e.error.message||"Failed to load the current session.",{code:e.error.code??"SESSION_LOOKUP_FAILED",status:e.error.status,cause:e.error});return(i=e.data)!=null&&i.user&&((s=e.data)!=null&&s.session)?{user:e.data.user,session:e.data}:{user:null,session:null}}const Tt="data-edgespark-auth",It="data-edgespark-auth-theme",r="edgespark-auth",ee="es_auth_completion",F="es_auth_email",te="oauth",N="verify-sign-in",C="verify-sign-up",Re=200,se=2,Rt={"&":"&","<":"<",">":">",'"':""","'":"'"},ie={google:"Google",apple:"Apple",microsoft:"Microsoft",github:"GitHub",gitlab:"GitLab",discord:"Discord"};function U(t){return"redirectTo"in t}function ne(t){return"onSuccess"in t&&!("redirectTo"in t)}function re(t){return!t||typeof t!="string"?!1:/^[^\s@]+@[^\s@]+\.[^\s@]+$/.test(t.trim())}function Ct(t){return/^\d{6}$/.test(t.trim())}function Ut(t){return t==="email"||t==="name"||t==="password"||t==="confirmPassword"||t==="code"||t==="newPassword"}function kt(t){return!!(t.error||t.errorDescription)}class $t{constructor(e,i,s,n,o){this.container=e,this.auth=i,this.options=s,this.loadConfig=n,this.runtimeOptions=o,this.state={view:"loading",busy:!0,busyLabel:void 0,error:null,notice:null,email:"",name:"",password:"",confirmPassword:"",code:"",newPassword:""},this.destroyed=!1,this.terminalActionInProgress=!1,this.config=null,this.countdownUntil=null,this.countdownTimer=null,this.pendingFocusSnapshot=null,this.focusRestoreTimer=null,this.verificationCompletionAction=null;const u=Lt(s.appearance);this.labels=_t(Fe(),s.labels),this.root=document.createElement("div"),this.root.className=u.className?`${r} ${u.className}`:r,this.root.setAttribute(Tt,""),this.root.setAttribute(It,u.theme);for(const[f,p]of Object.entries(u.variables))p!==void 0&&this.root.style.setProperty(f,p);e.appendChild(this.root),this.render(),this.initialize()}destroy(){this.destroyed||(this.destroyed=!0,this.clearCountdown(),this.clearFocusRestoreTimer(),this.root.remove())}async initialize(){const e=this.consumeManagedReturnContext();try{const[i,s]=await Promise.allSettled([this.loadConfig(),this.readMountSession(e)]);if(this.destroyed)return;if(s.status==="rejected"){if(e.marker&&!kt(e)&&U(this.options)){this.redirectAfterManagedReturnLookupFailure();return}}else{const o=s.value;if(o.user&&o.session){switch(e.marker){case te:case N:await this.completeAuth("sign-in",o);return;case C:await this.completeAuth("sign-up",o);return;default:break}this.handleExistingSessionOnMount();return}}if(i.status==="rejected")throw s.status==="rejected"?s.reason:i.reason;if(this.config=i.value,this.handleSessionlessManagedReturn(e))return;if(s.status==="rejected")throw s.reason;const n=s.value;this.state.view="sign-in",this.state.busy=!1,this.state.busyLabel=void 0,this.render()}catch(i){this.handleError(i,"Failed to load the authentication UI.")}}redirectAfterManagedReturnLookupFailure(){U(this.options)&&this.navigateToRedirect()}navigateToRedirect(){U(this.options)&&(this.terminalActionInProgress=!0,this.state.busy=!0,this.state.busyLabel=this.labels.common.redirecting,this.state.error=null,this.state.notice=null,this.render(),window.location.assign(St(this.options.redirectTo).toString()))}async readMountSession(e){if(!e.marker)return V(this.auth);let i=null;for(let s=0;s<=se;s++){try{const n=await V(this.auth);if(n.user&&n.session)return n}catch(n){i=n}s<se&&await new Promise(n=>setTimeout(n,Re))}if(i)throw i;return{user:null,session:null}}render(){if(this.destroyed)return;const e=this.captureFocusSnapshot();if(e&&(this.pendingFocusSnapshot=e),!this.config){this.root.innerHTML=this.renderLoading();return}this.root.innerHTML=`
|
|
1
|
+
"use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const Ke=require("better-auth/client");class W extends Error{constructor(e,s){super(s),this.name="EdgeSparkError",this.code=e}}class p extends W{constructor(e){super("CONFIG_ERROR",e),this.name="EdgeSparkConfigError"}}class be extends W{constructor(e){super("RUNTIME_ERROR",e),this.name="EdgeSparkRuntimeError"}}class I extends W{constructor(e,s){super((s==null?void 0:s.code)??"AUTH_ERROR",e),this.name="EdgeSparkAuthError",this.cause=s==null?void 0:s.cause,this.status=s==null?void 0:s.status}}function ve(t,e="Authentication failed.",s){if(t instanceof I)return t;if(typeof t=="object"&&t!==null){const i=t;return new I(i.message||e,{code:i.code??s,status:i.status,cause:t})}return typeof t=="string"?new I(t,{code:s}):new I(e,{code:s,cause:t})}function Be(){if(typeof window>"u"||typeof document>"u")throw new be("@edgespark/web is browser-only. Create the client from a real browser runtime.")}function ae(){return Be(),window.location.origin}function We(t){return t instanceof URL?t:typeof t=="string"?new URL(t,window.location.href):new URL(t.url,window.location.href)}function Ye(t){if(t.origin!==ae())throw new p(`Cross-origin requests are not supported by this SDK. Received ${t.origin}, expected ${ae()}.`)}function Je(){return{async fetch(t,e){const s=We(t);return Ye(s),fetch(t,{...e,credentials:"include"})}}}const Me="/api/_es/auth",Xe="edgespark-auth-session",De="__edgespark_auth_sync__",Y="__edgespark_auth_pending_sign_in__",Ne=Symbol("edgespark.notifyAuthTabs"),Ze=10*60*1e3,Qe=new Set(["signOut","revokeSession","revokeSessions","revokeOtherSessions"]),et=new Map([["changeEmail","changeEmail() is not currently supported by EdgeSpark platform auth. Use authUI.mount() or other supported client.auth flows instead of wiring raw /api/_es/auth/* routes manually."],["deleteUser","deleteUser() is not currently supported by EdgeSpark platform auth. Handle account removal through your own app flow until the platform enables this capability."],["deleteUserCallback","deleteUserCallback() is not currently supported by EdgeSpark platform auth. Handle account removal through your own app flow until the platform enables this capability."]]);class tt{constructor(e){this.value=e}deref(){return this.value}}const Ie=globalThis.WeakRef,Pe=globalThis.FinalizationRegistry;let J,Ae=!1;const M=new Map,X=Pe?new Pe(t=>{M.delete(t)}):null;function Ve(t){return Ke.createAuthClient({baseURL:ae(),basePath:Me,...t!=null&&t.disableDefaultRedirectPlugin?{disableDefaultFetchPlugins:!0}:{},fetchOptions:{credentials:"include"}})}function B(t){var e,s;return(s=(e=t.$store)==null?void 0:e.atoms)==null?void 0:s.session}function st(t){return JSON.stringify({source:t,timestamp:Date.now()})}function it(t){if(typeof t!="string")return null;try{const e=JSON.parse(t);return e&&typeof e=="object"?e:null}catch{return null}}function nt(t){return t.join(".")}function rt(t){const e=nt(t),s=et.get(e);return s?new I(s,{code:"UNSUPPORTED_AUTH_METHOD"}):null}async function le(t){var e;try{return await((e=B(t))==null?void 0:e.get().refetch()),!0}catch{return!1}}function He(){return J===void 0&&(J=typeof BroadcastChannel<"u"?new BroadcastChannel(Xe):null),J}function Le(t){const e=it(t);if(e)for(const[s,i]of M){if(s===e.source)continue;const n=i.deref();if(!n){M.delete(s);continue}le(n)}}function ot(){var t;Ae||(Ae=!0,(t=He())==null||t.addEventListener("message",e=>{Le(e.data)}),typeof window<"u"&&window.addEventListener("storage",e=>{e.key!==De||e.newValue===null||Le(e.newValue)}))}function at(t,e){Ie?M.set(t,new Ie(e)):(M.clear(),M.set(t,new tt(e))),X==null||X.register(e,t),ot()}function k(t){const e=st(t),s=He();let i=!1;if(s)try{s.postMessage(e),i=!0}catch{}if(!i)try{window.localStorage.setItem(De,e)}catch{}}function Z(t){if(!(typeof window>"u"))try{window.sessionStorage.setItem(Y,JSON.stringify({path:t,createdAt:Date.now()}))}catch{}}function O(){if(!(typeof window>"u"))try{window.sessionStorage.removeItem(Y)}catch{}}function lt(t){return!!(t!=null&&t.session&&(t!=null&&t.user))}function v(t){return t instanceof Date?t.toISOString():t===null||typeof t=="string"||typeof t=="number"||typeof t=="boolean"?t:t==null?null:String(t)}function dt(t){return t?JSON.stringify({session:{createdAt:v(t.session.createdAt),expiresAt:v(t.session.expiresAt),id:v(t.session.id),impersonatedBy:v(t.session.impersonatedBy),ipAddress:v(t.session.ipAddress),token:v(t.session.token),updatedAt:v(t.session.updatedAt),userAgent:v(t.session.userAgent),userId:v(t.session.userId)},user:{banExpires:v(t.user.banExpires),banReason:v(t.user.banReason),banned:v(t.user.banned),createdAt:v(t.user.createdAt),email:v(t.user.email),emailVerified:v(t.user.emailVerified),id:v(t.user.id),image:v(t.user.image),lastLoginAt:v(t.user.lastLoginAt),name:v(t.user.name),role:v(t.user.role),updatedAt:v(t.user.updatedAt)}}):"__null__"}function Fe(){if(typeof window>"u")return null;try{const t=window.sessionStorage.getItem(Y);if(!t)return null;const e=JSON.parse(t);return!e||typeof e!="object"||typeof e.createdAt!="number"||Date.now()-e.createdAt>Ze?null:{createdAt:e.createdAt}}catch{return null}}function Te(){if(!Fe())return!1;try{window.sessionStorage.removeItem(Y)}catch{}return!0}function ct(){return Fe()!==null}function ut(t){if(!(t&&typeof t=="object")||"error"in t&&t.error)return!1;const e="data"in t?t.data:t;return e&&typeof e=="object"?"token"in e&&typeof e.token=="string"&&e.token.length>0?!0:"session"in e&&"user"in e&&!!e.session&&!!e.user:!1}function ht(t){if(!(t&&typeof t=="object")||"error"in t&&t.error)return!1;const e="data"in t?t.data:t;return e&&typeof e=="object"?"url"in e&&typeof e.url=="string":!1}function mt(t){if($(t)||!(t&&typeof t=="object"))return!1;const e="data"in t?t.data:t;return e&&typeof e=="object"?"user"in e&&!!e.user&&"token"in e&&e.token===null&&!("url"in e):!1}function ft(t,e){if(t.length!==1||t[0]!=="changePassword")return!1;const[s]=e;return!!(s&&typeof s=="object"&&"revokeOtherSessions"in s&&s.revokeOtherSessions===!0)}function $(t){return!!(t&&typeof t=="object"&&"error"in t&&t.error)}function gt(t){if($(t)||!(t&&typeof t=="object"))return!1;const e="data"in t?t.data:t;return e&&typeof e=="object"?"message"in e&&e.message==="User deleted":!1}function pt(t){return!!(t&&(typeof t=="object"||typeof t=="function")&&"then"in t&&typeof t.then=="function")}function Q(t){return ve(t,"Failed to load the current session.","SESSION_LOOKUP_FAILED")}async function wt(t){var s,i;let e=null;try{await((s=B(t))==null?void 0:s.get().refetch())}catch(n){e=n}finally{(i=t[Ne])==null||i.call(t)}if(e)throw e}function bt(){const t=Ve(),e=`${Date.now()}-${Math.random().toString(36).slice(2)}`;at(e,t);const s=2,i=500;let n=null,o=!1,c;const h=a=>(c=a,a),w=()=>{var m;const a=(m=B(t))==null?void 0:m.get();return a!=null&&a.error&&!a.data&&c!==void 0?c:(a==null?void 0:a.data)??c??null},_=()=>o?Promise.resolve(w()):(n||(n=(async()=>{var d,f,T;let a=!1,m=null;try{for(let A=0;A<=s;A++){let u=null;try{u=await t.getSession()}catch(R){m=R}const S=((d=B(t))==null?void 0:d.get().data)??null;if((f=u==null?void 0:u.data)!=null&&f.session&&((T=u.data)!=null&&T.user))return o=!0,Te()&&k(e),h(u.data);if(S!=null&&S.session&&(S!=null&&S.user))return o=!0,Te()&&k(e),h(S);if(u!=null&&u.error?m=u.error:u&&(a=!0),u&&!u.error&&ct()&&A<s){await new Promise(R=>setTimeout(R,i));continue}if(u&&!u.error){const R=w();return o=!0,h(R)}A<s&&await new Promise(R=>setTimeout(R,i))}if(!a)throw n=null,new I("Failed to load the current session.",{code:"SESSION_LOOKUP_FAILED",cause:m});const y=w();return o=!0,h(y)}catch(y){throw n=null,Q(y)}})()),n);_().catch(()=>{});const b=async()=>{var a,m;try{const d=await t.getSession();if((a=d.data)!=null&&a.session&&((m=d.data)!=null&&m.user))return d.data;throw d.error?Q(d.error):new I("No authenticated session is available.",{code:"UNAUTHENTICATED"})}catch(d){throw Q(d)}},g=async()=>{await le(t),k(e)},E=async()=>{var d;const a=await le(t),m=((d=B(t))==null?void 0:d.get().data)??null;lt(m)?(O(),k(e)):a||k(e)},l=a=>{let m=!1,d=!1,f;const T=u=>{const S=dt(u);S!==f&&(f=S,a(u))};_().then(u=>{m||(d=!0,T(h(u)))}).catch(()=>{m||(d=!0)});const y=B(t);if(!y)return()=>{m=!0};const A=y.subscribe(u=>{if(m||!d||u.error&&!u.data)return;const S=u.data??null;T(h(S))});return()=>{m=!0,A()}},P=async(a,m,d)=>{const f=a[0],T=a.length>=2&&f==="emailOtp"&&a[1]==="verifyEmail",y=a.length>=2&&f==="emailOtp"&&a[1]==="resetPassword",A=a.length>=2&&f==="resetPassword"&&a[1]==="emailOtp",u=a.length>=2&&f==="oneTap"&&a[1]==="callback";return a.length===1&&(f==="deleteUser"||f==="deleteUserCallback")?(O(),gt(d)&&await g(),d):a.length===1&&f&&Qe.has(f)?(O(),$(d)||await g(),d):ft(a,m)&&!$(d)?(O(),await g(),d):(y||A)&&!$(d)?(O(),await g(),d):a.length===1&&f==="changeEmail"&&!$(d)?(await g(),d):((f==="signIn"||f==="signUp"||T||u)&&ut(d)?(O(),await g()):(f==="signIn"||f==="signUp")&&ht(d)||f==="signUp"&&mt(d)?Z(a):f==="verifyEmail"&&!$(d)&&(Z(a),await E()),d)},L=new WeakMap,D=(a,m)=>{if(!a||typeof a!="object"&&typeof a!="function")return a;const d=L.get(a);if(d)return d;const f=new Proxy(a,{get(T,y,A){if(m.length===0){if(y==="requireSession")return b;if(y==="onSessionChange")return l;if(y===Ne)return()=>{k(e)}}const u=Reflect.get(T,y,A);return typeof y!="string"?u:D(u,[...m,y])},apply(T,y,A){const u=rt(m);if(u)throw u;const S=Reflect.apply(T,y,A);return pt(S)?Promise.resolve(S).then(R=>P(m,A,R)):S}});return L.set(a,f),f};return D(t,[])}function vt(){return Ve({disableDefaultRedirectPlugin:!0})}const ye="/api/_es/dev";function yt(){if(typeof document>"u")return!1;const t=document.querySelector('meta[name="edgespark-local-dev"]');return(t==null?void 0:t.getAttribute("content"))==="true"}async function Et(t){const e=typeof window<"u"?window.location.origin:"";if(!e)return!1;const s=await fetch(`${e}${ye}/auto-verify?email=${encodeURIComponent(t)}`,{credentials:"include"});return s.ok?(await s.json()).verified===!0:!1}async function St(t){const e=typeof window<"u"?window.location.origin:"";if(!e)return null;try{const s=await fetch(`${e}${ye}/pending-otp?email=${encodeURIComponent(t)}`,{credentials:"include"});return s.ok?(await s.json()).otp??null:null}catch{return null}}async function _t(t){const e=typeof window<"u"?window.location.origin:"";if(!e)return null;try{const s=await fetch(`${e}${ye}/pending-sign-in-otp?email=${encodeURIComponent(t)}`,{credentials:"include"});return s.ok?(await s.json()).otp??null:null}catch{return null}}function It(t){const e=(()=>{if(t instanceof URL)return t;const s=t.trim();if(!s)throw new p("redirectTo must not be an empty string.");try{return new URL(s,window.location.href)}catch{throw new p(`redirectTo must be a valid relative path or URL. Received: ${JSON.stringify(t)}`)}})();if(e.protocol!=="http:"&&e.protocol!=="https:")throw new p(`redirectTo must resolve to an http(s) URL. Received protocol: ${e.protocol}`);return e}function Pt(t,e){return e?{common:{...t.common,...e.common},signIn:{...t.signIn,...e.signIn},signUp:{...t.signUp,...e.signUp},verifyEmail:{...t.verifyEmail,...e.verifyEmail},forgotPassword:{...t.forgotPassword,...e.forgotPassword},resetPassword:{...t.resetPassword,...e.resetPassword},oauth:{...t.oauth,...e.oauth},errors:{...t.errors,...e.errors}}:t}const H={common:{loading:"Loading sign-in…",redirecting:"Redirecting…",backToSignIn:"Back to sign in"},signIn:{title:"Welcome back",subtitle:"Sign in to continue",emailLabel:"Email",passwordLabel:"Password",submitButton:"Sign in",resendCodeButton:"Resend code",resendCountdown:"Resend in {seconds}s",forgotPassword:"Forgot password?",switchToSignUp:"Create an account",signUpPrompt:"Don’t have an account?"},signUp:{title:"Create your account",subtitle:"Start with your name, email, and password",nameLabel:"Name",emailLabel:"Email",passwordLabel:"Password",confirmPasswordLabel:"Confirm password",submitButton:"Create account",switchToSignIn:"Sign in",signInPrompt:"Already have an account?"},verifyEmail:{title:"Verify your email",subtitle:"Finish account setup from the verification email we sent.",sentToLabel:"Sent to",resendButton:"Resend verification email",resendCountdown:"Resend in {seconds}s",changeEmailButton:"Use a different email"},forgotPassword:{title:"Reset your password",subtitle:"Enter your email and we will send a reset code.",emailLabel:"Email",submitButton:"Send reset code"},resetPassword:{title:"Set a new password",subtitle:"Use the code from your email to finish resetting your password.",codeLabel:"Verification code",newPasswordLabel:"New password",confirmPasswordLabel:"Confirm password",submitButton:"Update password",resendCodeButton:"Resend code",resendCountdown:"Resend in {seconds}s"},oauth:{dividerText:"or",continueWith:"Continue with"},errors:{invalidEmail:"Enter a valid email address.",requiredField:"This field is required.",passwordTooShort:"Password must be at least {min} characters.",passwordMismatch:"Passwords do not match.",invalidCode:"Enter the 6-digit verification code.",generic:"Something went wrong. Please try again."}},q={common:{loading:"加载中…",redirecting:"跳转中…",backToSignIn:"返回登录"},signIn:{title:"欢迎回来",subtitle:"登录以继续",emailLabel:"邮箱",passwordLabel:"密码",submitButton:"登录",forgotPassword:"忘记密码?",switchToSignUp:"立即注册",signUpPrompt:"没有账号?"},signUp:{title:"创建账号",subtitle:"填写姓名、邮箱和密码开始使用",nameLabel:"姓名",emailLabel:"邮箱",passwordLabel:"密码",confirmPasswordLabel:"确认密码",submitButton:"注册",switchToSignIn:"去登录",signInPrompt:"已有账号?"},verifyEmail:{title:"验证邮箱",subtitle:"请查收邮件并点击验证链接",sentToLabel:"已发送至",resendButton:"重新发送验证邮件",resendCountdown:"{seconds}秒后可重发",changeEmailButton:"更换邮箱"},forgotPassword:{title:"重置密码",subtitle:"输入邮箱以接收重置验证码",emailLabel:"邮箱",submitButton:"发送重置码"},resetPassword:{title:"设置新密码",subtitle:"使用邮件中的验证码完成密码重置",codeLabel:"验证码",newPasswordLabel:"新密码",confirmPasswordLabel:"确认密码",submitButton:"更新密码",resendCodeButton:"重新发送",resendCountdown:"{seconds}秒后可重发"},oauth:{dividerText:"或",continueWith:"使用"},errors:{invalidEmail:"请输入有效的邮箱地址",requiredField:"此项为必填",passwordTooShort:"密码至少需要 {min} 个字符",passwordMismatch:"两次密码输入不一致",invalidCode:"请输入 6 位验证码",generic:"出现错误,请稍后重试"}},de={common:{loading:"サインインを読み込み中…",redirecting:"リダイレクト中…",backToSignIn:"サインインに戻る"},signIn:{title:"おかえりなさい",subtitle:"サインインして続行",emailLabel:"メールアドレス",passwordLabel:"パスワード",submitButton:"サインイン",forgotPassword:"パスワードをお忘れですか?",switchToSignUp:"アカウントを作成",signUpPrompt:"アカウントをお持ちでない方"},signUp:{title:"アカウントを作成",subtitle:"名前、メールアドレス、パスワードを入力してください",nameLabel:"名前",emailLabel:"メールアドレス",passwordLabel:"パスワード",confirmPasswordLabel:"パスワード(確認)",submitButton:"アカウント作成",switchToSignIn:"サインイン",signInPrompt:"既にアカウントをお持ちですか?"},verifyEmail:{title:"メールアドレスを確認",subtitle:"送信した確認メールからアカウント設定を完了してください",sentToLabel:"送信先",resendButton:"確認メールを再送信",resendCountdown:"{seconds}秒後に再送信可能",changeEmailButton:"別のメールアドレスを使用"},forgotPassword:{title:"パスワードをリセット",subtitle:"メールアドレスを入力するとリセットコードをお送りします",emailLabel:"メールアドレス",submitButton:"リセットコードを送信"},resetPassword:{title:"新しいパスワードを設定",subtitle:"メールで届いた認証コードを使ってパスワードをリセットしてください",codeLabel:"認証コード",newPasswordLabel:"新しいパスワード",confirmPasswordLabel:"パスワード(確認)",submitButton:"パスワードを更新",resendCodeButton:"コードを再送信",resendCountdown:"{seconds}秒後に再送信可能"},oauth:{dividerText:"または",continueWith:"で続行"},errors:{invalidEmail:"有効なメールアドレスを入力してください",requiredField:"この項目は必須です",passwordTooShort:"パスワードは {min} 文字以上で入力してください",passwordMismatch:"パスワードが一致しません",invalidCode:"6桁の認証コードを入力してください",generic:"エラーが発生しました。もう一度お試しください"}},ce={common:{loading:"로그인 로딩 중…",redirecting:"리디렉션 중…",backToSignIn:"로그인으로 돌아가기"},signIn:{title:"다시 오신 것을 환영합니다",subtitle:"로그인하여 계속하기",emailLabel:"이메일",passwordLabel:"비밀번호",submitButton:"로그인",forgotPassword:"비밀번호를 잊으셨나요?",switchToSignUp:"계정 만들기",signUpPrompt:"계정이 없으신가요?"},signUp:{title:"계정 만들기",subtitle:"이름, 이메일, 비밀번호를 입력해 주세요",nameLabel:"이름",emailLabel:"이메일",passwordLabel:"비밀번호",confirmPasswordLabel:"비밀번호 확인",submitButton:"계정 생성",switchToSignIn:"로그인",signInPrompt:"이미 계정이 있으신가요?"},verifyEmail:{title:"이메일 인증",subtitle:"발송된 인증 이메일에서 계정 설정을 완료해 주세요",sentToLabel:"발송 대상",resendButton:"인증 이메일 재발송",resendCountdown:"{seconds}초 후 재발송 가능",changeEmailButton:"다른 이메일 사용"},forgotPassword:{title:"비밀번호 재설정",subtitle:"이메일을 입력하시면 재설정 코드를 보내드립니다",emailLabel:"이메일",submitButton:"재설정 코드 발송"},resetPassword:{title:"새 비밀번호 설정",subtitle:"이메일로 받은 인증 코드를 사용하여 비밀번호를 재설정하세요",codeLabel:"인증 코드",newPasswordLabel:"새 비밀번호",confirmPasswordLabel:"비밀번호 확인",submitButton:"비밀번호 변경",resendCodeButton:"코드 재발송",resendCountdown:"{seconds}초 후 재발송 가능"},oauth:{dividerText:"또는",continueWith:"으로 계속"},errors:{invalidEmail:"올바른 이메일 주소를 입력해 주세요",requiredField:"필수 입력 항목입니다",passwordTooShort:"비밀번호는 최소 {min}자 이상이어야 합니다",passwordMismatch:"비밀번호가 일치하지 않습니다",invalidCode:"6자리 인증 코드를 입력해 주세요",generic:"문제가 발생했습니다. 다시 시도해 주세요"}},K={common:{loading:"Cargando inicio de sesión…",redirecting:"Redirigiendo…",backToSignIn:"Volver a iniciar sesión"},signIn:{title:"Bienvenido de nuevo",subtitle:"Inicia sesión para continuar",emailLabel:"Correo electrónico",passwordLabel:"Contraseña",submitButton:"Iniciar sesión",forgotPassword:"¿Olvidaste tu contraseña?",switchToSignUp:"Crear una cuenta",signUpPrompt:"¿No tienes cuenta?"},signUp:{title:"Crea tu cuenta",subtitle:"Empieza con tu nombre, correo y contraseña",nameLabel:"Nombre",emailLabel:"Correo electrónico",passwordLabel:"Contraseña",confirmPasswordLabel:"Confirmar contraseña",submitButton:"Crear cuenta",switchToSignIn:"Iniciar sesión",signInPrompt:"¿Ya tienes una cuenta?"},verifyEmail:{title:"Verifica tu correo",subtitle:"Completa la configuración desde el correo de verificación que te enviamos.",sentToLabel:"Enviado a",resendButton:"Reenviar correo de verificación",resendCountdown:"Reenviar en {seconds}s",changeEmailButton:"Usar otro correo"},forgotPassword:{title:"Restablecer contraseña",subtitle:"Ingresa tu correo y te enviaremos un código de restablecimiento.",emailLabel:"Correo electrónico",submitButton:"Enviar código"},resetPassword:{title:"Establece una nueva contraseña",subtitle:"Usa el código de tu correo para completar el restablecimiento.",codeLabel:"Código de verificación",newPasswordLabel:"Nueva contraseña",confirmPasswordLabel:"Confirmar contraseña",submitButton:"Actualizar contraseña",resendCodeButton:"Reenviar código",resendCountdown:"Reenviar en {seconds}s"},oauth:{dividerText:"o",continueWith:"Continuar con"},errors:{invalidEmail:"Ingresa una dirección de correo válida.",requiredField:"Este campo es obligatorio.",passwordTooShort:"La contraseña debe tener al menos {min} caracteres.",passwordMismatch:"Las contraseñas no coinciden.",invalidCode:"Ingresa el código de verificación de 6 dígitos.",generic:"Algo salió mal. Por favor, inténtalo de nuevo."}},ue={common:{loading:"Carregando login…",redirecting:"Redirecionando…",backToSignIn:"Voltar para o login"},signIn:{title:"Bem-vindo de volta",subtitle:"Faça login para continuar",emailLabel:"E-mail",passwordLabel:"Senha",submitButton:"Entrar",forgotPassword:"Esqueceu a senha?",switchToSignUp:"Criar uma conta",signUpPrompt:"Não tem uma conta?"},signUp:{title:"Crie sua conta",subtitle:"Comece com seu nome, e-mail e senha",nameLabel:"Nome",emailLabel:"E-mail",passwordLabel:"Senha",confirmPasswordLabel:"Confirmar senha",submitButton:"Criar conta",switchToSignIn:"Entrar",signInPrompt:"Já tem uma conta?"},verifyEmail:{title:"Verifique seu e-mail",subtitle:"Conclua a configuração a partir do e-mail de verificação que enviamos.",sentToLabel:"Enviado para",resendButton:"Reenviar e-mail de verificação",resendCountdown:"Reenviar em {seconds}s",changeEmailButton:"Usar outro e-mail"},forgotPassword:{title:"Redefinir senha",subtitle:"Informe seu e-mail e enviaremos um código de redefinição.",emailLabel:"E-mail",submitButton:"Enviar código"},resetPassword:{title:"Defina uma nova senha",subtitle:"Use o código recebido por e-mail para concluir a redefinição.",codeLabel:"Código de verificação",newPasswordLabel:"Nova senha",confirmPasswordLabel:"Confirmar senha",submitButton:"Atualizar senha",resendCodeButton:"Reenviar código",resendCountdown:"Reenviar em {seconds}s"},oauth:{dividerText:"ou",continueWith:"Continuar com"},errors:{invalidEmail:"Insira um endereço de e-mail válido.",requiredField:"Este campo é obrigatório.",passwordTooShort:"A senha deve ter pelo menos {min} caracteres.",passwordMismatch:"As senhas não coincidem.",invalidCode:"Insira o código de verificação de 6 dígitos.",generic:"Algo deu errado. Por favor, tente novamente."}},he={common:{loading:"Chargement de la connexion…",redirecting:"Redirection…",backToSignIn:"Retour à la connexion"},signIn:{title:"Bon retour",subtitle:"Connectez-vous pour continuer",emailLabel:"Adresse e-mail",passwordLabel:"Mot de passe",submitButton:"Se connecter",forgotPassword:"Mot de passe oublié ?",switchToSignUp:"Créer un compte",signUpPrompt:"Vous n’avez pas de compte ?"},signUp:{title:"Créez votre compte",subtitle:"Commencez par votre nom, e-mail et mot de passe",nameLabel:"Nom",emailLabel:"Adresse e-mail",passwordLabel:"Mot de passe",confirmPasswordLabel:"Confirmer le mot de passe",submitButton:"Créer le compte",switchToSignIn:"Se connecter",signInPrompt:"Vous avez déjà un compte ?"},verifyEmail:{title:"Vérifiez votre e-mail",subtitle:"Finalisez la création de votre compte depuis l’e-mail de vérification envoyé.",sentToLabel:"Envoyé à",resendButton:"Renvoyer l’e-mail de vérification",resendCountdown:"Renvoyer dans {seconds}s",changeEmailButton:"Utiliser un autre e-mail"},forgotPassword:{title:"Réinitialiser le mot de passe",subtitle:"Saisissez votre e-mail pour recevoir un code de réinitialisation.",emailLabel:"Adresse e-mail",submitButton:"Envoyer le code"},resetPassword:{title:"Définir un nouveau mot de passe",subtitle:"Utilisez le code reçu par e-mail pour réinitialiser votre mot de passe.",codeLabel:"Code de vérification",newPasswordLabel:"Nouveau mot de passe",confirmPasswordLabel:"Confirmer le mot de passe",submitButton:"Mettre à jour le mot de passe",resendCodeButton:"Renvoyer le code",resendCountdown:"Renvoyer dans {seconds}s"},oauth:{dividerText:"ou",continueWith:"Continuer avec"},errors:{invalidEmail:"Veuillez saisir une adresse e-mail valide.",requiredField:"Ce champ est requis.",passwordTooShort:"Le mot de passe doit contenir au moins {min} caractères.",passwordMismatch:"Les mots de passe ne correspondent pas.",invalidCode:"Saisissez le code de vérification à 6 chiffres.",generic:"Une erreur est survenue. Veuillez réessayer."}},me={common:{loading:"Anmeldung wird geladen…",redirecting:"Weiterleitung…",backToSignIn:"Zurück zur Anmeldung"},signIn:{title:"Willkommen zurück",subtitle:"Melden Sie sich an, um fortzufahren",emailLabel:"E-Mail-Adresse",passwordLabel:"Passwort",submitButton:"Anmelden",forgotPassword:"Passwort vergessen?",switchToSignUp:"Konto erstellen",signUpPrompt:"Noch kein Konto?"},signUp:{title:"Konto erstellen",subtitle:"Geben Sie Ihren Namen, Ihre E-Mail und ein Passwort ein",nameLabel:"Name",emailLabel:"E-Mail-Adresse",passwordLabel:"Passwort",confirmPasswordLabel:"Passwort bestätigen",submitButton:"Konto erstellen",switchToSignIn:"Anmelden",signInPrompt:"Bereits ein Konto?"},verifyEmail:{title:"E-Mail bestätigen",subtitle:"Schließen Sie die Einrichtung über die Bestätigungs-E-Mail ab, die wir Ihnen gesendet haben.",sentToLabel:"Gesendet an",resendButton:"Bestätigungs-E-Mail erneut senden",resendCountdown:"Erneut senden in {seconds}s",changeEmailButton:"Andere E-Mail verwenden"},forgotPassword:{title:"Passwort zurücksetzen",subtitle:"Geben Sie Ihre E-Mail ein und wir senden Ihnen einen Zurücksetzungscode.",emailLabel:"E-Mail-Adresse",submitButton:"Code senden"},resetPassword:{title:"Neues Passwort festlegen",subtitle:"Verwenden Sie den Code aus der E-Mail, um Ihr Passwort zurückzusetzen.",codeLabel:"Bestätigungscode",newPasswordLabel:"Neues Passwort",confirmPasswordLabel:"Passwort bestätigen",submitButton:"Passwort aktualisieren",resendCodeButton:"Code erneut senden",resendCountdown:"Erneut senden in {seconds}s"},oauth:{dividerText:"oder",continueWith:"Weiter mit"},errors:{invalidEmail:"Bitte geben Sie eine gültige E-Mail-Adresse ein.",requiredField:"Dieses Feld ist erforderlich.",passwordTooShort:"Das Passwort muss mindestens {min} Zeichen lang sein.",passwordMismatch:"Die Passwörter stimmen nicht überein.",invalidCode:"Geben Sie den 6-stelligen Bestätigungscode ein.",generic:"Etwas ist schiefgelaufen. Bitte versuchen Sie es erneut."}},fe={common:{loading:"Caricamento accesso…",redirecting:"Reindirizzamento…",backToSignIn:"Torna all’accesso"},signIn:{title:"Bentornato",subtitle:"Accedi per continuare",emailLabel:"Indirizzo e-mail",passwordLabel:"Password",submitButton:"Accedi",forgotPassword:"Password dimenticata?",switchToSignUp:"Crea un account",signUpPrompt:"Non hai un account?"},signUp:{title:"Crea il tuo account",subtitle:"Inserisci nome, e-mail e password per iniziare",nameLabel:"Nome",emailLabel:"Indirizzo e-mail",passwordLabel:"Password",confirmPasswordLabel:"Conferma password",submitButton:"Crea account",switchToSignIn:"Accedi",signInPrompt:"Hai già un account?"},verifyEmail:{title:"Verifica la tua e-mail",subtitle:"Completa la configurazione dall’e-mail di verifica che ti abbiamo inviato.",sentToLabel:"Inviata a",resendButton:"Reinvia e-mail di verifica",resendCountdown:"Reinvia tra {seconds}s",changeEmailButton:"Usa un’altra e-mail"},forgotPassword:{title:"Reimposta la password",subtitle:"Inserisci la tua e-mail e ti invieremo un codice di reimpostazione.",emailLabel:"Indirizzo e-mail",submitButton:"Invia codice"},resetPassword:{title:"Imposta una nuova password",subtitle:"Usa il codice ricevuto via e-mail per reimpostare la password.",codeLabel:"Codice di verifica",newPasswordLabel:"Nuova password",confirmPasswordLabel:"Conferma password",submitButton:"Aggiorna password",resendCodeButton:"Reinvia codice",resendCountdown:"Reinvia tra {seconds}s"},oauth:{dividerText:"oppure",continueWith:"Continua con"},errors:{invalidEmail:"Inserisci un indirizzo e-mail valido.",requiredField:"Questo campo è obbligatorio.",passwordTooShort:"La password deve contenere almeno {min} caratteri.",passwordMismatch:"Le password non corrispondono.",invalidCode:"Inserisci il codice di verifica a 6 cifre.",generic:"Qualcosa è andato storto. Riprova."}},ge={common:{loading:"Загрузка входа…",redirecting:"Перенаправление…",backToSignIn:"Вернуться ко входу"},signIn:{title:"С возвращением",subtitle:"Войдите, чтобы продолжить",emailLabel:"Электронная почта",passwordLabel:"Пароль",submitButton:"Войти",forgotPassword:"Забыли пароль?",switchToSignUp:"Создать аккаунт",signUpPrompt:"Нет аккаунта?"},signUp:{title:"Создание аккаунта",subtitle:"Укажите имя, электронную почту и пароль",nameLabel:"Имя",emailLabel:"Электронная почта",passwordLabel:"Пароль",confirmPasswordLabel:"Подтвердите пароль",submitButton:"Создать аккаунт",switchToSignIn:"Войти",signInPrompt:"Уже есть аккаунт?"},verifyEmail:{title:"Подтвердите почту",subtitle:"Завершите настройку через письмо с подтверждением, которое мы отправили.",sentToLabel:"Отправлено на",resendButton:"Отправить повторно",resendCountdown:"Повторная отправка через {seconds}с",changeEmailButton:"Использовать другую почту"},forgotPassword:{title:"Сброс пароля",subtitle:"Введите электронную почту, и мы отправим код для сброса.",emailLabel:"Электронная почта",submitButton:"Отправить код"},resetPassword:{title:"Установите новый пароль",subtitle:"Используйте код из письма для завершения сброса пароля.",codeLabel:"Код подтверждения",newPasswordLabel:"Новый пароль",confirmPasswordLabel:"Подтвердите пароль",submitButton:"Обновить пароль",resendCodeButton:"Отправить код повторно",resendCountdown:"Повторная отправка через {seconds}с"},oauth:{dividerText:"или",continueWith:"Продолжить через"},errors:{invalidEmail:"Введите корректный адрес электронной почты.",requiredField:"Это поле обязательно.",passwordTooShort:"Пароль должен содержать не менее {min} символов.",passwordMismatch:"Пароли не совпадают.",invalidCode:"Введите 6-значный код подтверждения.",generic:"Произошла ошибка. Пожалуйста, попробуйте снова."}},pe={common:{loading:"جارٍ تحميل تسجيل الدخول…",redirecting:"جارٍ إعادة التوجيه…",backToSignIn:"العودة إلى تسجيل الدخول"},signIn:{title:"مرحبًا بعودتك",subtitle:"سجّل الدخول للمتابعة",emailLabel:"البريد الإلكتروني",passwordLabel:"كلمة المرور",submitButton:"تسجيل الدخول",forgotPassword:"هل نسيت كلمة المرور؟",switchToSignUp:"إنشاء حساب",signUpPrompt:"ليس لديك حساب؟"},signUp:{title:"أنشئ حسابك",subtitle:"ابدأ بإدخال اسمك وبريدك الإلكتروني وكلمة المرور",nameLabel:"الاسم",emailLabel:"البريد الإلكتروني",passwordLabel:"كلمة المرور",confirmPasswordLabel:"تأكيد كلمة المرور",submitButton:"إنشاء الحساب",switchToSignIn:"تسجيل الدخول",signInPrompt:"لديك حساب بالفعل؟"},verifyEmail:{title:"تحقّق من بريدك الإلكتروني",subtitle:"أكمل إعداد حسابك من رسالة التحقّق التي أرسلناها.",sentToLabel:"أُرسل إلى",resendButton:"إعادة إرسال رسالة التحقّق",resendCountdown:"إعادة الإرسال خلال {seconds} ثانية",changeEmailButton:"استخدام بريد إلكتروني آخر"},forgotPassword:{title:"إعادة تعيين كلمة المرور",subtitle:"أدخل بريدك الإلكتروني وسنرسل لك رمز إعادة التعيين.",emailLabel:"البريد الإلكتروني",submitButton:"إرسال رمز إعادة التعيين"},resetPassword:{title:"تعيين كلمة مرور جديدة",subtitle:"استخدم الرمز المرسل إلى بريدك لإكمال إعادة تعيين كلمة المرور.",codeLabel:"رمز التحقّق",newPasswordLabel:"كلمة المرور الجديدة",confirmPasswordLabel:"تأكيد كلمة المرور",submitButton:"تحديث كلمة المرور",resendCodeButton:"إعادة إرسال الرمز",resendCountdown:"إعادة الإرسال خلال {seconds} ثانية"},oauth:{dividerText:"أو",continueWith:"المتابعة باستخدام"},errors:{invalidEmail:"يرجى إدخال عنوان بريد إلكتروني صالح.",requiredField:"هذا الحقل مطلوب.",passwordTooShort:"يجب أن تتكوّن كلمة المرور من {min} حرفًا على الأقل.",passwordMismatch:"كلمتا المرور غير متطابقتين.",invalidCode:"يرجى إدخال رمز التحقّق المكوّن من 6 أرقام.",generic:"حدث خطأ. يرجى المحاولة مرة أخرى."}},we={common:{loading:"सधाइन की जुलातीअ लोड हो रही है…",redirecting:"रीडायरेक्ट हो रहا है…",backToSignIn:"साइन इन पर वापस जाएँ"},signIn:{title:"वापसी आपका स्वागत है",subtitle:"जारी रखने के लिए साइन इन करें",emailLabel:"ईमेल",passwordLabel:"पासवर्ड",submitButton:"साइन इन",forgotPassword:"पासवर्ड भूल गए?",switchToSignUp:"खाता बनाएँ",signUpPrompt:"खाता नहीं है?"},signUp:{title:"अपना खाता बनाएँ",subtitle:"अपना नाम, ईमेल और पासवर्ड दर्ज करें",nameLabel:"नाम",emailLabel:"ईमेल",passwordLabel:"पासवर्ड",confirmPasswordLabel:"पासवर्ड की पुष्टि",submitButton:"खाता बनाएँ",switchToSignIn:"साइन इन",signInPrompt:"पहले से खाता है?"},verifyEmail:{title:"अपना ईमेल सत्यापित करें",subtitle:"हमने जो सत्यापन ईमेल भेजा है उससे सेटअप पूरा करें।",sentToLabel:"भेजा गया",resendButton:"सत्यापन ईमेल फिर से भेजें",resendCountdown:"{seconds} सेकंड में फिर से भेजें",changeEmailButton:"दूसरा ईमेल इस्तेमाल करें"},forgotPassword:{title:"पासवर्ड रीसेट करें",subtitle:"अपना ईमेल दर्ज करें और हम रीसेट कोड भेजेंगे।",emailLabel:"ईमेल",submitButton:"रीसेट कोड भेजें"},resetPassword:{title:"नया पासवर्ड सेट करें",subtitle:"पासवर्ड रीसेट पूरा करने के लिए ईमेल में प्राप्त कोड का उपयोग करें।",codeLabel:"सत्यापन कोड",newPasswordLabel:"नया पासवर्ड",confirmPasswordLabel:"पासवर्ड की पुष्टि",submitButton:"पासवर्ड अपडेट करें",resendCodeButton:"कोड फिर से भेजें",resendCountdown:"{seconds} सेकंड में फिर से भेजें"},oauth:{dividerText:"या",continueWith:"से जारी रखें"},errors:{invalidEmail:"कृपया एक वैध ईमेल पता दर्ज करें।",requiredField:"यह फ़ील्ड आवश्यक है।",passwordTooShort:"पासवर्ड कम से कम {min} अक्षरों का होना चाहिए।",passwordMismatch:"पासवर्ड मेल नहीं खाते।",invalidCode:"कृपया 6 अंकों का सत्यापन कोड दर्ज करें।",generic:"कुछ गलत हो गई। कृपया फिर से प्रयास करें।"}},Re={en:H,"en-US":H,zh:q,"zh-CN":q,"zh-TW":q,ja:de,"ja-JP":de,ko:ce,"ko-KR":ce,es:K,"es-ES":K,"es-MX":K,pt:ue,"pt-BR":ue,fr:he,"fr-FR":he,de:me,"de-DE":me,it:fe,"it-IT":fe,ru:ge,"ru-RU":ge,ar:pe,"ar-SA":pe,hi:we,"hi-IN":we};function Ge(){if(typeof navigator>"u")return H;const t=navigator.languages??[navigator.language];for(const e of t){const s=Re[e]??Re[e.split("-")[0]];if(s)return s}return H}const Ee={LIGHT:"light",DARK:"dark"},Se=Ee.LIGHT,ze=Ee.DARK,_e=[Se,ze],xe=Se,je={BACKGROUND:"--edgespark-auth-bg",BACKGROUND_MUTED:"--edgespark-auth-bg-muted",CARD_BACKGROUND:"--edgespark-auth-card-bg",BORDER:"--edgespark-auth-border",TEXT:"--edgespark-auth-text",TEXT_MUTED:"--edgespark-auth-text-muted",DIVIDER_BACKGROUND:"--edgespark-auth-divider-bg",PRIMARY:"--edgespark-auth-primary",PRIMARY_HOVER:"--edgespark-auth-primary-hover",PRIMARY_CONTRAST:"--edgespark-auth-primary-contrast",ERROR:"--edgespark-auth-error",INFO:"--edgespark-auth-info",CARD_RADIUS:"--edgespark-auth-radius-card",CONTROL_RADIUS:"--edgespark-auth-radius-control",SHADOW:"--edgespark-auth-shadow",FONT:"--edgespark-auth-font",MODAL_BACKDROP:"--edgespark-auth-modal-backdrop",MODAL_CARD_BACKGROUND:"--edgespark-auth-modal-card-bg",MODAL_SHADOW:"--edgespark-auth-modal-shadow"},qe=Object.values(je);function At(t){return typeof t=="string"&&_e.includes(t)}function Lt(t){return qe.includes(t)}function Tt(t){var e;return{theme:(t==null?void 0:t.theme)??xe,className:((e=t==null?void 0:t.className)==null?void 0:e.trim())??"",variables:{...(t==null?void 0:t.variables)??{}}}}function ee(t,e="Authentication failed."){return ve(t,e)}async function V(t){var s,i;const e=await t.getSession();if(e.error)throw new I(e.error.message||"Failed to load the current session.",{code:e.error.code??"SESSION_LOOKUP_FAILED",status:e.error.status,cause:e.error});return(s=e.data)!=null&&s.user&&((i=e.data)!=null&&i.session)?{user:e.data.user,session:e.data}:{user:null,session:null}}const Rt="data-edgespark-auth",Ct="data-edgespark-auth-theme",r="edgespark-auth",te="es_auth_completion",F="es_auth_email",se="oauth",N="verify-sign-in",C="verify-sign-up",Ce=200,ie=2,Ut={"&":"&","<":"<",">":">",'"':""","'":"'"},ne={google:"Google",apple:"Apple",microsoft:"Microsoft",github:"GitHub",gitlab:"GitLab",discord:"Discord"};function U(t){return"redirectTo"in t}function re(t){return"onSuccess"in t&&!("redirectTo"in t)}function G(t){return!t||typeof t!="string"?!1:/^[^\s@]+@[^\s@]+\.[^\s@]+$/.test(t.trim())}function Ue(t){return/^\d{6}$/.test(t.trim())}function $t(t){return t==="email"||t==="name"||t==="password"||t==="confirmPassword"||t==="code"||t==="newPassword"}function kt(t){return!!(t.error||t.errorDescription)}class Ot{constructor(e,s,i,n,o){this.container=e,this.auth=s,this.options=i,this.loadConfig=n,this.runtimeOptions=o,this.state={view:"loading",busy:!0,busyLabel:void 0,error:null,notice:null,email:"",name:"",password:"",confirmPassword:"",code:"",newPassword:"",signInMethod:"password",signInOtpSent:!1},this.destroyed=!1,this.terminalActionInProgress=!1,this.config=null,this.countdownUntil=null,this.countdownTimer=null,this.pendingFocusSnapshot=null,this.focusRestoreTimer=null,this.verificationCompletionAction=null;const c=Tt(i.appearance);this.labels=Pt(Ge(),i.labels),this.root=document.createElement("div"),this.root.className=c.className?`${r} ${c.className}`:r,this.root.setAttribute(Rt,""),this.root.setAttribute(Ct,c.theme);for(const[h,w]of Object.entries(c.variables))w!==void 0&&this.root.style.setProperty(h,w);e.appendChild(this.root),this.render(),this.initialize()}destroy(){this.destroyed||(this.destroyed=!0,this.clearCountdown(),this.clearFocusRestoreTimer(),this.root.remove())}async initialize(){const e=this.consumeManagedReturnContext();try{const[s,i]=await Promise.allSettled([this.loadConfig(),this.readMountSession(e)]);if(this.destroyed)return;if(i.status==="rejected"){if(e.marker&&!kt(e)&&U(this.options)){this.redirectAfterManagedReturnLookupFailure();return}}else{const o=i.value;if(o.user&&o.session){switch(e.marker){case se:case N:await this.completeAuth("sign-in",o);return;case C:await this.completeAuth("sign-up",o);return;default:break}this.handleExistingSessionOnMount();return}}if(s.status==="rejected")throw i.status==="rejected"?i.reason:s.reason;if(this.config=s.value,this.state.signInMethod=this.resolveInitialSignInMethod(),this.handleSessionlessManagedReturn(e))return;if(i.status==="rejected")throw i.reason;const n=i.value;this.state.view="sign-in",this.state.busy=!1,this.state.busyLabel=void 0,this.render()}catch(s){this.handleError(s,"Failed to load the authentication UI.")}}redirectAfterManagedReturnLookupFailure(){U(this.options)&&this.navigateToRedirect()}navigateToRedirect(){U(this.options)&&(this.terminalActionInProgress=!0,this.state.busy=!0,this.state.busyLabel=this.labels.common.redirecting,this.state.error=null,this.state.notice=null,this.render(),window.location.assign(It(this.options.redirectTo).toString()))}async readMountSession(e){if(!e.marker)return V(this.auth);let s=null;for(let i=0;i<=ie;i++){try{const n=await V(this.auth);if(n.user&&n.session)return n}catch(n){s=n}i<ie&&await new Promise(n=>setTimeout(n,Ce))}if(s)throw s;return{user:null,session:null}}render(){if(this.destroyed)return;const e=this.captureFocusSnapshot();if(e&&(this.pendingFocusSnapshot=e),!this.config){this.root.innerHTML=this.renderLoading();return}this.root.innerHTML=`
|
|
2
2
|
<div class="${r}__shell">
|
|
3
3
|
${this.renderDevModeBanner()}
|
|
4
4
|
<div class="${r}__card">
|
|
@@ -12,36 +12,51 @@
|
|
|
12
12
|
${e||`<div class="${r}__status ${r}__status--info">${this.escape(this.labels.common.loading)}</div>`}
|
|
13
13
|
</div>
|
|
14
14
|
</div>
|
|
15
|
-
`}renderDevModeBanner(){var e;return(e=this.config)!=null&&e.isLocalDev?`<div class="${r}__dev-banner">Local dev mode — emails are mocked, OAuth uses test identities</div>`:""}renderStatus(){const e=[];return this.state.error&&e.push(`<div class="${r}__status ${r}__status--error">${this.escape(this.state.error)}</div>`),this.state.notice&&e.push(`<div class="${r}__status ${r}__status--info">${this.escape(this.state.notice)}</div>`),this.state.busy&&this.state.busyLabel&&e.push(`<div class="${r}__status ${r}__status--muted">${this.escape(this.state.busyLabel)}</div>`),e.join("")}renderCurrentView(){switch(this.state.view){case"sign-in":return this.renderSignInView();case"sign-up":return this.renderSignUpView();case"verify-email":return this.renderVerifyEmailView();case"forgot-password":return this.renderForgotPasswordView();case"reset-password":return this.renderResetPasswordView();case"loading":default:return`<p class="${r}__copy">${this.escape(this.labels.common.loading)}</p>`}}renderSignInView(){var
|
|
15
|
+
`}renderDevModeBanner(){var e;return(e=this.config)!=null&&e.isLocalDev?`<div class="${r}__dev-banner">Local dev mode — emails are mocked, OAuth uses test identities</div>`:""}renderStatus(){const e=[];return this.state.error&&e.push(`<div class="${r}__status ${r}__status--error">${this.escape(this.state.error)}</div>`),this.state.notice&&e.push(`<div class="${r}__status ${r}__status--info">${this.escape(this.state.notice)}</div>`),this.state.busy&&this.state.busyLabel&&e.push(`<div class="${r}__status ${r}__status--muted">${this.escape(this.state.busyLabel)}</div>`),e.join("")}renderCurrentView(){switch(this.state.view){case"sign-in":return this.renderSignInView();case"sign-up":return this.renderSignUpView();case"verify-email":return this.renderVerifyEmailView();case"forgot-password":return this.renderForgotPasswordView();case"reset-password":return this.renderResetPasswordView();case"loading":default:return`<p class="${r}__copy">${this.escape(this.labels.common.loading)}</p>`}}renderSignInView(){var b,g,E,l;const e=this.renderOAuthProviders(),s=!!((b=this.config)!=null&&b.emailPasswordEnabled),i=!!((g=this.config)!=null&&g.emailOtpSignInEnabled),n=s||i,o=s&&i,c=i&&!s?"otp":this.state.signInMethod,h=c==="otp",w=h?this.state.signInOtpSent?this.labels.signIn.verifyCodeButton??"Verify code":this.labels.signIn.sendCodeButton??"Send code":this.labels.signIn.submitButton,_=this.countdownText(this.labels.signIn.resendCodeButton??"Resend code",this.labels.signIn.resendCountdown??"Resend in {seconds}s");return`
|
|
16
16
|
<section class="${r}__section">
|
|
17
17
|
<header class="${r}__header">
|
|
18
18
|
<h1 class="${r}__title">${this.escape(this.labels.signIn.title)}</h1>
|
|
19
19
|
<p class="${r}__copy">${this.escape(this.labels.signIn.subtitle)}</p>
|
|
20
20
|
</header>
|
|
21
21
|
${e}
|
|
22
|
-
${e&&
|
|
23
|
-
${
|
|
22
|
+
${e&&n?`<div class="${r}__divider"><span>${this.escape(this.labels.oauth.dividerText)}</span></div>`:""}
|
|
23
|
+
${n?`
|
|
24
|
+
${o?`
|
|
25
|
+
<div class="${r}__tabs" role="tablist" aria-label="Sign-in method">
|
|
26
|
+
<button class="${r}__tab ${c==="password"?`${r}__tab--active`:""}" type="button" data-action="sign-in-method" data-method="password" ${this.state.busy?"disabled":""}>
|
|
27
|
+
${this.escape(this.labels.signIn.passwordTab??"Password")}
|
|
28
|
+
</button>
|
|
29
|
+
<button class="${r}__tab ${c==="otp"?`${r}__tab--active`:""}" type="button" data-action="sign-in-method" data-method="otp" ${this.state.busy?"disabled":""}>
|
|
30
|
+
${this.escape(this.labels.signIn.codeTab??"Code")}
|
|
31
|
+
</button>
|
|
32
|
+
</div>
|
|
33
|
+
`:""}
|
|
24
34
|
<form class="${r}__form" data-view="sign-in" novalidate>
|
|
25
35
|
${this.renderInput("email",this.labels.signIn.emailLabel,"email",this.state.email,"email")}
|
|
26
|
-
${this.renderInput("password",this.labels.signIn.passwordLabel,"password",this.state.password,"current-password")}
|
|
36
|
+
${h?this.state.signInOtpSent?this.renderInput("code",this.labels.signIn.codeLabel??"Code","text",this.state.code,"one-time-code"):"":this.renderInput("password",this.labels.signIn.passwordLabel,"password",this.state.password,"current-password")}
|
|
27
37
|
<button class="${r}__button ${r}__button--primary" type="submit" ${this.state.busy?"disabled":""}>
|
|
28
|
-
${this.escape(
|
|
38
|
+
${this.escape(w)}
|
|
29
39
|
</button>
|
|
30
40
|
</form>
|
|
41
|
+
${h&&this.state.signInOtpSent?`
|
|
42
|
+
<button class="${r}__text-action" type="button" data-action="resend-sign-in-code" ${this.state.busy||this.isCountdownActive()?"disabled":""}>
|
|
43
|
+
${this.escape(_)}
|
|
44
|
+
</button>
|
|
45
|
+
`:""}
|
|
31
46
|
<div class="${r}__actions">
|
|
32
|
-
${this.canUsePasswordResetEmailOtp()?`
|
|
47
|
+
${!h&&this.canUsePasswordResetEmailOtp()?`
|
|
33
48
|
<button class="${r}__link" type="button" data-action="forgot-password" ${this.state.busy?"disabled":""}>
|
|
34
49
|
${this.escape(this.labels.signIn.forgotPassword)}
|
|
35
50
|
</button>
|
|
36
51
|
`:""}
|
|
37
|
-
${(
|
|
52
|
+
${!((E=this.config)!=null&&E.disableSignUp)&&((l=this.config)!=null&&l.emailPasswordEnabled)?`
|
|
38
53
|
<p class="${r}__meta">
|
|
39
54
|
${this.escape(this.labels.signIn.signUpPrompt)}
|
|
40
55
|
<button class="${r}__link" type="button" data-action="switch-sign-up" ${this.state.busy?"disabled":""}>
|
|
41
56
|
${this.escape(this.labels.signIn.switchToSignUp)}
|
|
42
57
|
</button>
|
|
43
58
|
</p>
|
|
44
|
-
|
|
59
|
+
`:""}
|
|
45
60
|
</div>
|
|
46
61
|
`:""}
|
|
47
62
|
</section>
|
|
@@ -125,24 +140,24 @@
|
|
|
125
140
|
${this.escape(this.labels.common.backToSignIn)}
|
|
126
141
|
</button>
|
|
127
142
|
</section>
|
|
128
|
-
`}renderOAuthProviders(){var
|
|
143
|
+
`}renderOAuthProviders(){var s;const e=((s=this.config)==null?void 0:s.oauthProviders)??[];return e.length===0?"":`
|
|
129
144
|
<div class="${r}__stack">
|
|
130
|
-
${e.map(
|
|
131
|
-
<button class="${r}__button ${r}__button--secondary" type="button" data-action="oauth" data-provider="${
|
|
132
|
-
${this.escape(`${this.labels.oauth.continueWith} ${
|
|
145
|
+
${e.map(i=>`
|
|
146
|
+
<button class="${r}__button ${r}__button--secondary" type="button" data-action="oauth" data-provider="${i}" ${this.state.busy?"disabled":""}>
|
|
147
|
+
${this.escape(`${this.labels.oauth.continueWith} ${ne[i]}`)}
|
|
133
148
|
</button>
|
|
134
149
|
`).join("")}
|
|
135
150
|
</div>
|
|
136
|
-
`}renderInput(e,i,
|
|
151
|
+
`}renderInput(e,s,i,n,o){return`
|
|
137
152
|
<label class="${r}__field">
|
|
138
|
-
<span class="${r}__label">${this.escape(
|
|
153
|
+
<span class="${r}__label">${this.escape(s)}</span>
|
|
139
154
|
<input
|
|
140
155
|
class="${r}__input"
|
|
141
156
|
name="${this.escape(e)}"
|
|
142
|
-
type="${this.escape(
|
|
157
|
+
type="${this.escape(i)}"
|
|
143
158
|
value="${this.escape(n)}"
|
|
144
159
|
autocomplete="${this.escape(o)}"
|
|
145
160
|
${this.state.busy?"disabled":""}
|
|
146
161
|
/>
|
|
147
162
|
</label>
|
|
148
|
-
`}bindDOM(){this.root.querySelectorAll("form[data-view]").forEach(n=>{n.addEventListener("submit",o=>{o.preventDefault();const u=n.dataset.view;u==="sign-in"&&this.handleSignIn(),u==="sign-up"&&this.handleSignUp(),u==="forgot-password"&&this.handleForgotPassword(),u==="reset-password"&&this.handleResetPassword()})}),this.root.querySelectorAll("input[name]").forEach(n=>{n.addEventListener("input",()=>{Ut(n.name)&&(this.state[n.name]=n.value)})}),this.root.querySelectorAll("[data-action]").forEach(n=>{n.addEventListener("click",()=>{const o=n.dataset.action;o==="switch-sign-up"&&this.switchView("sign-up"),o==="switch-sign-in"&&this.switchView("sign-in"),o==="forgot-password"&&this.switchView("forgot-password"),o==="resend-verification"&&this.resendVerificationEmail(),o==="use-different-email"&&this.switchView(this.verificationCompletionAction==="sign-in"?"sign-in":"sign-up"),o==="resend-reset-code"&&this.resendResetCode(),o==="oauth"&&this.handleOAuthSignIn(n.dataset.provider)})})}switchView(e){this.clearCountdown(),e!=="verify-email"&&(this.verificationCompletionAction=null),this.state.view=e,this.state.error=null,this.state.notice=null,this.state.busy=!1,this.state.busyLabel=void 0,this.terminalActionInProgress=!1,this.render()}async handleSignIn(){if(!re(this.state.email)){this.failValidation(this.labels.errors.invalidEmail);return}if(!this.state.password){this.failValidation(this.labels.errors.requiredField);return}await this.runAction("Signing in…",async()=>{const e=await this.auth.signIn.email({email:this.state.email.trim(),password:this.state.password,callbackURL:this.getManagedReturnURL(N,this.state.email.trim())});if(e.error)throw e.error;await this.completeAuth("sign-in")})}async handleSignUp(){var e,i;if(!this.state.name.trim()){this.failValidation(this.labels.errors.requiredField);return}if(!re(this.state.email)){this.failValidation(this.labels.errors.invalidEmail);return}if(!this.state.password){this.failValidation(this.labels.errors.requiredField);return}if(this.state.password.length<(((e=this.config)==null?void 0:e.minPasswordLength)??8)){this.failValidation(this.labels.errors.passwordTooShort.replace("{min}",String(((i=this.config)==null?void 0:i.minPasswordLength)??8)));return}if(this.state.password!==this.state.confirmPassword){this.failValidation(this.labels.errors.passwordMismatch);return}await this.runAction("Creating account…",async()=>{var n;const s=await this.auth.signUp.email({name:this.state.name.trim(),email:this.state.email.trim(),password:this.state.password,callbackURL:this.getManagedReturnURL(C,this.state.email.trim())});if(s.error)throw s.error;if((n=this.config)!=null&&n.requireEmailVerification){if(this.config.isLocalDev&&await this.tryDevAutoVerify("sign-up",s.data))return;this.verificationCompletionAction="sign-up",this.state.view="verify-email",this.state.notice=this.config.isLocalDev?"Dev mode: auto-verify didn’t complete. Click resend to retry.":"Check your inbox to verify your email address.",this.startCountdown();return}await this.completeAuth("sign-up",await this.resolveAuthCompletionData(s.data))})}async handleOAuthSignIn(e){await this.runAction(`Redirecting to ${ie[e]}…`,async()=>{const i=await this.auth.signIn.social({provider:e,callbackURL:this.getManagedReturnURL("oauth"),errorCallbackURL:this.getManagedReturnURL("oauth")});if(i.error)throw i.error;const s=this.extractRedirectURL(i.data);if(!s)throw new g(`OAuth sign-in did not return a redirect URL for provider "${e}".`);this.terminalActionInProgress=!0,this.state.busy=!0,this.state.busyLabel=`Opening ${ie[e]}…`,this.state.error=null,this.state.notice=null,this.render(),window.location.assign(s)})}async handleForgotPassword(){if(!this.canUsePasswordResetEmailOtp()){this.handleError(new g("Password reset via email OTP is not enabled for this project."));return}if(!re(this.state.email)){this.failValidation(this.labels.errors.invalidEmail);return}await this.runAction("Sending reset code…",async()=>{var i;const e=await this.passwordResetEndpoints().forgetPassword.emailOtp({email:this.state.email.trim()});if(e.error)throw e.error;if(this.state.view="reset-password",(i=this.config)!=null&&i.isLocalDev){this.state.busyLabel="Dev mode: fetching reset code…",this.render();const s=await Et(this.state.email.trim());s?(this.state.code=s,this.state.notice=`Dev mode: reset code auto-filled (${s})`):this.state.notice="Dev mode: could not retrieve reset code — check server logs"}else this.state.notice=`We sent a reset code to ${this.state.email.trim()}.`;this.startCountdown()})}async resendResetCode(){this.isCountdownActive()||await this.handleForgotPassword()}async handleResetPassword(){var e,i;if(!this.canUsePasswordResetEmailOtp()){this.handleError(new g("Password reset via email OTP is not enabled for this project."));return}if(!Ct(this.state.code)){this.failValidation(this.labels.errors.invalidCode);return}if(!this.state.newPassword){this.failValidation(this.labels.errors.requiredField);return}if(this.state.newPassword.length<(((e=this.config)==null?void 0:e.minPasswordLength)??8)){this.failValidation(this.labels.errors.passwordTooShort.replace("{min}",String(((i=this.config)==null?void 0:i.minPasswordLength)??8)));return}if(this.state.newPassword!==this.state.confirmPassword){this.failValidation(this.labels.errors.passwordMismatch);return}await this.runAction("Updating password…",async()=>{const s=await this.passwordResetEndpoints().emailOtp.resetPassword({email:this.state.email.trim(),otp:this.state.code.trim(),password:this.state.newPassword});if(s.error)throw s.error;await this.completePasswordReset()})}async resendVerificationEmail(){var e;if((e=this.config)!=null&&e.isLocalDev){if(this.isCountdownActive())return;await this.runAction("Dev mode: retrying auto-verify…",async()=>{const i=this.verificationCompletionAction??"sign-in";if(!await this.tryDevAutoVerify(i))throw new Error("Dev auto-verify did not complete. Check the edgespark dev logs and try again.")});return}await this.sendVerificationEmail(!1)}async tryDevAutoVerify(e,i){const s=this.state.email.trim();try{return this.state.busyLabel="Dev mode: auto-verifying email…",this.render(),await vt(s)?(this.state.notice="Dev mode: email verification auto-completed",await this.completeAuth(e,await this.resolveAuthCompletionData(i)),!0):(console.warn("[edgespark] Dev auto-verify returned false — falling through"),!1)}catch(n){return console.warn("[edgespark] Dev auto-verify failed:",n),!1}}async sendVerificationEmail(e){!e&&this.isCountdownActive()||await this.runAction("Sending verification email…",async()=>{const i=await this.auth.sendVerificationEmail({email:this.state.email.trim(),callbackURL:this.getManagedReturnURL(this.verificationCompletionAction==="sign-up"?C:N,this.state.email.trim())});if(i.error)throw i.error;this.handleVerificationEmailSent(this.state.email.trim(),!0)})}async completeAuth(e,i){const s=await this.retryAuthCompletionDataIfNeeded(i??await this.resolveAuthCompletionData());if(this.destroyed)return;if(!s.user||!s.session){if(this.destroyed)return;if(s.lookupError&&U(this.options)){this.navigateToRedirect();return}if(e==="sign-in")throw s.lookupError??new be("Managed sign-in completed without an authenticated session.");this.state.view="sign-in",this.state.password="",this.state.confirmPassword="",this.state.error=null,this.state.busy=!1,this.state.busyLabel=void 0,this.state.notice="Account created. Sign in to continue.",this.render();return}const n={action:e,user:s.user,session:s.session};if(await this.syncPublicSessionBestEffort(),!this.destroyed){if(U(this.options)){this.invokeRedirectModeSuccessHook(n),this.navigateToRedirect();return}if(ne(this.options)){this.options.onSuccess(n),this.terminalActionInProgress=!0;return}}}async retryAuthCompletionDataIfNeeded(e){if(e.session)return e;let i=e.lookupError;for(let s=0;s<se;s++){await new Promise(n=>setTimeout(n,Re));try{const n=await V(this.auth);if(n.user&&n.session)return{user:n.user,session:n.session}}catch(n){i=n}}return{...e,lookupError:i??e.lookupError}}async syncPublicSessionBestEffort(){var e,i;try{await((i=(e=this.runtimeOptions)==null?void 0:e.syncPublicSession)==null?void 0:i.call(e))}catch{}}async resolveAuthCompletionData(e){try{const i=await V(this.auth),s=this.extractUser(e);return{user:i.user??s,session:i.session}}catch(i){return{user:this.extractUser(e),session:null,lookupError:i}}}async completePasswordReset(){const e={action:"password-reset",user:null,session:null};if(await this.syncPublicSessionBestEffort(),!this.destroyed){if(ne(this.options)){this.clearCountdown(),this.options.onSuccess(e),this.terminalActionInProgress=!0;return}this.invokeRedirectModeSuccessHook(e),this.clearCountdown(),this.state.view="sign-in",this.state.password="",this.state.confirmPassword="",this.state.newPassword="",this.state.code="",this.state.busy=!1,this.state.busyLabel=void 0,this.state.error=null,this.state.notice="Password updated. Sign in with your new password.",this.render()}}handleExistingSessionOnMount(){if(U(this.options)){this.navigateToRedirect();return}if(ne(this.options))throw this.state.view="sign-in",this.state.busy=!1,this.state.busyLabel=void 0,this.state.notice=null,new g("authUI.mount(container, { onSuccess }) cannot run while a session already exists. Check es.auth.getSession() before mounting controlled auth UI.")}async runAction(e,i){this.state.busy=!0,this.state.busyLabel=e,this.state.error=null,this.state.notice=null,this.render();try{await i()}catch(s){if(this.maybeHandleVerificationRequired(s))return;this.handleError(s);return}!this.destroyed&&!this.terminalActionInProgress&&(this.state.busy=!1,this.state.busyLabel=void 0,this.render())}maybeHandleVerificationRequired(e){return Q(e).code!=="EMAIL_NOT_VERIFIED"?!1:(this.verificationCompletionAction="sign-in",this.state.view="verify-email",this.state.busy=!1,this.state.busyLabel=void 0,this.state.error=null,this.state.notice=`Verify your email to finish signing in as ${this.state.email.trim()}.`,this.render(),this.sendVerificationEmail(!0),!0)}handleVerificationEmailSent(e,i){this.state.notice=i?`We sent another verification email to ${e}.`:`We sent a verification email to ${e}.`,this.startCountdown()}invokeRedirectModeSuccessHook(e){var i,s;if(!(!U(this.options)||!this.options.onSuccess))try{this.options.onSuccess(e)}catch(n){const o=Q(n,"Post-auth callback failed.");try{(s=(i=this.options).onError)==null||s.call(i,o)}catch{}}}handleError(e,i){var n,o;const s=Q(e,i);this.state.busy=!1,this.state.busyLabel=void 0,this.state.error=s.message,this.render(),(o=(n=this.options).onError)==null||o.call(n,s)}failValidation(e){this.state.error=e,this.state.notice=null,this.render()}getManagedReturnURL(e,i){if(!e)return window.location.href;const s=new URL(window.location.href);return s.searchParams.set(ee,e),i?s.searchParams.set(F,i):s.searchParams.delete(F),s.toString()}consumeManagedReturnContext(){const e=new URL(window.location.href),i=e.searchParams.get(ee),s=i===te||i===N||i===C?i:null,n=e.searchParams.get(F),o=s?e.searchParams.get("error"):null,u=s?e.searchParams.get("error_description"):null;return(s||n)&&(e.searchParams.delete(ee),e.searchParams.delete(F),s&&(e.searchParams.delete("error"),e.searchParams.delete("error_description")),window.history.replaceState(null,"",e.toString())),{marker:s,email:n,error:o,errorDescription:u}}startCountdown(e=60){this.countdownUntil=Date.now()+e*1e3,this.countdownTimer&&window.clearInterval(this.countdownTimer),this.countdownTimer=window.setInterval(()=>{if(!this.isCountdownActive()){this.countdownTimer&&(window.clearInterval(this.countdownTimer),this.countdownTimer=null),this.render();return}this.render()},1e3)}clearCountdown(){this.countdownUntil=null,this.countdownTimer&&(window.clearInterval(this.countdownTimer),this.countdownTimer=null)}captureFocusSnapshot(){const e=document.activeElement;return!(e instanceof HTMLInputElement)||!this.root.contains(e)||!e.name?null:{name:e.name,type:e.type,selectionStart:e.selectionStart,selectionEnd:e.selectionEnd}}scheduleFocusRestore(){this.pendingFocusSnapshot&&(this.clearFocusRestoreTimer(),this.focusRestoreTimer=window.setTimeout(()=>{if(this.focusRestoreTimer=null,this.destroyed||!this.pendingFocusSnapshot)return;const e=this.pendingFocusSnapshot,i=`input[name="${this.escape(e.name)}"][type="${this.escape(e.type)}"]`,s=this.root.querySelector(i);if(!(!s||s.disabled)){if(s.focus(),e.selectionStart!==null&&e.selectionEnd!==null)try{s.setSelectionRange(e.selectionStart,e.selectionEnd)}catch{const n=s.value.length;s.setSelectionRange(n,n)}this.pendingFocusSnapshot=null}},0))}clearFocusRestoreTimer(){this.focusRestoreTimer!==null&&(window.clearTimeout(this.focusRestoreTimer),this.focusRestoreTimer=null)}passwordResetEndpoints(){return this.auth}extractRedirectURL(e){if(!e||typeof e!="object")return null;const i=e;return i.redirect&&typeof i.url=="string"&&i.url.length>0?i.url:null}extractUser(e){if(!e||typeof e!="object")return null;const i=e;return i.user&&typeof i.user=="object"?i.user:null}canUsePasswordResetEmailOtp(){var e;return!!((e=this.config)!=null&&e.passwordResetEmailOtpEnabled)}handleSessionlessManagedReturn(e){return e.email&&(this.state.email=e.email),e.marker===C&&!e.error?(this.verificationCompletionAction=null,this.clearCountdown(),this.state.view="sign-in",this.state.password="",this.state.confirmPassword="",this.state.error=null,this.state.busy=!1,this.state.busyLabel=void 0,this.state.notice="Account created. Sign in to continue.",this.render(),!0):e.marker===N||e.marker===C?(this.verificationCompletionAction=e.marker===C?"sign-up":"sign-in",this.state.view="verify-email",this.state.busy=!1,this.state.busyLabel=void 0,this.state.notice=null,e.error||e.errorDescription?this.handleError(new _(e.errorDescription??"Verification failed. Request a new verification email and try again.",{code:e.error??"VERIFY_EMAIL_ERROR"})):this.render(),!0):e.marker===te&&(e.error||e.errorDescription)?(this.state.view="sign-in",this.state.busy=!1,this.state.busyLabel=void 0,this.state.notice=null,this.handleError(new _(e.errorDescription??"OAuth sign-in failed.",{code:e.error??"OAUTH_ERROR"})),!0):!1}isCountdownActive(){return this.getCountdownSecondsRemaining()>0}getCountdownSecondsRemaining(){return this.countdownUntil?Math.max(0,Math.ceil((this.countdownUntil-Date.now())/1e3)):0}countdownText(e,i){const s=this.getCountdownSecondsRemaining();return s<=0?e:i.replace("{seconds}",String(s))}escape(e){return e.replace(/[&<>"']/g,i=>Rt[i])}}function Bt(t){return"data"in t&&t.data?t.data:t}const Ot=[{id:"google",key:"providerGoogle"},{id:"apple",key:"providerApple"},{id:"microsoft",key:"providerMicrosoft"},{id:"github",key:"providerGithub"},{id:"gitlab",key:"providerGitlab"},{id:"discord",key:"providerDiscord"}],Ce=2,Mt=500;async function Dt(){const t=`${window.location.origin}${Be}/config`;let e;for(let i=0;i<=Ce;i++)try{const s=await fetch(t,{method:"GET",credentials:"include"});if(!s.ok)throw new g(`Failed to load auth config: HTTP ${s.status}`);const n=await s.json(),o=Bt(n);return Nt(o,yt())}catch(s){e=s,i<Ce&&await new Promise(n=>setTimeout(n,Mt))}throw e}let G=null;async function Ue(){return G||(G=Dt().catch(t=>{throw G=null,t})),G}function Nt(t,e=!1){var o,u,f,p,L,y,b,P;const i=Ot.filter(({key:d})=>{const S=t[d];return typeof S=="object"&&S!==null&&"enabled"in S&&!!S.enabled}).map(({id:d})=>d),s=t.providerGoogle,n=s!=null&&s.enabled&&typeof((o=s.config)==null?void 0:o.clientId)=="string"?s.config.clientId:null;return{disableSignUp:!!t.disableSignUp,emailPasswordEnabled:!!((u=t.providerEmailPassword)!=null&&u.enabled),minPasswordLength:((p=(f=t.providerEmailPassword)==null?void 0:f.config)==null?void 0:p.minPasswordLength)??8,requireEmailVerification:!!((y=(L=t.providerEmailPassword)==null?void 0:L.config)!=null&&y.requireEmailVerification),passwordResetEmailOtpEnabled:!!((P=(b=t.providerEmailPassword)==null?void 0:b.config)!=null&&P.requirePasswordResetEmailVerification),oauthProviders:i,googleClientId:n,isLocalDev:e}}const Vt="https://accounts.google.com/gsi/client",ke="data-edgespark-gsi";let z=null;function oe(){var t,e;return(e=(t=window.google)==null?void 0:t.accounts)==null?void 0:e.id}function Ht(){if(typeof window>"u")return Promise.reject(new Error("Google Identity Services is unavailable outside the browser."));const t=oe();return t?Promise.resolve(t):(z||(z=new Promise((e,i)=>{const s=document.querySelector(`script[${ke}]`);if(s){const o=oe();if(o){e(o);return}s.remove()}const n=document.createElement("script");n.src=Vt,n.async=!0,n.defer=!0,n.setAttribute(ke,""),n.addEventListener("load",()=>{const o=oe();o?e(o):(n.remove(),i(new Error("Google Identity Services loaded but did not expose google.accounts.id.")))},{once:!0}),n.addEventListener("error",()=>{n.remove(),i(new Error("Failed to load Google Identity Services."))},{once:!0}),document.head.appendChild(n)}).catch(e=>{throw z=null,e})),z)}function Ft(){return{cancel:()=>{}}}function Gt(t){let e=null;return function(s){if(typeof window>"u")return console.error("[edgespark] promptGoogleOneTap() requires a browser environment."),Ft();if(e)return console.warn("[edgespark] promptGoogleOneTap() is already in flight; returning the existing handle. Call cancel() on the original before re-prompting."),e;let n=!1,o=null;const u=()=>{n||(n=!0,e===f&&(e=null))},f={cancel(){if(!n&&(u(),o))try{o.cancel()}catch{}}},p=()=>{var b;if(!n){u();try{(b=s==null?void 0:s.onUnavailable)==null||b.call(s)}catch(P){console.error("[edgespark] onUnavailable threw:",P)}}},L=(b,P)=>{var S;if(n)return;u();const d=ye(b,P);try{(S=s==null?void 0:s.onError)==null||S.call(s,d)}catch(R){console.error("[edgespark] onError threw:",R)}},y=(b,P)=>{var d;if(!n){u();try{(d=s==null?void 0:s.onSuccess)==null||d.call(s,{action:"sign-in",user:b,session:P})}catch(S){console.error("[edgespark] onSuccess threw:",S)}}};return e=f,(async()=>{let b;try{b=await t.loadConfig()}catch(d){L(d,"Failed to load auth config for Google One Tap.");return}if(n)return;if(b.isLocalDev){console.error("[edgespark] promptGoogleOneTap() is disabled in local dev mode — Google Identity Services cannot run against mock OAuth."),u();return}const P=b.googleClientId;if(!P){console.error("[edgespark] promptGoogleOneTap() called but Google is not configured. Set `providerGoogle` in `auth-config.yaml` with resolvable credentials."),u();return}try{o=await Ht()}catch(d){console.warn("[edgespark] Google Identity Services failed to load; treating as unavailable.",d),p();return}if(!n){o.initialize({client_id:P,callback:d=>{n||typeof(d==null?void 0:d.credential)!="string"||d.credential.length===0||zt(d.credential,t,{emitSuccess:y,emitError:L,isDone:()=>n})},cancel_on_tap_outside:!1,use_fedcm_for_prompt:!0,context:"signin"});try{o.prompt(d=>{var S,R,D,a;if(!n){if((S=d.isDismissedMoment)!=null&&S.call(d)){const h=(R=d.getDismissedReason)==null?void 0:R.call(d);if(h==="credential_returned"||h==="cancel_called")return;p();return}((D=d.isNotDisplayed)!=null&&D.call(d)||(a=d.isSkippedMoment)!=null&&a.call(d))&&p()}})}catch(d){L(d,"Failed to prompt Google One Tap.")}}})(),f}}async function zt(t,e,i){var L;const{emitSuccess:s,emitError:n,isDone:o}=i,u=e.authClient;if(!((L=u.oneTap)!=null&&L.callback)){n(new _("Google One Tap endpoint not registered. Update the EdgeSpark sidecar.",{code:"ONE_TAP_UNAVAILABLE"}),"Google One Tap endpoint not registered.");return}try{const y=await u.oneTap.callback({idToken:t});if(o())return;if(y.error){n(new _(y.error.message??"Google One Tap sign-in failed.",{code:y.error.code??"ONE_TAP_FAILED",status:y.error.status,cause:y.error}),"Google One Tap sign-in failed.");return}}catch(y){if(o())return;n(y,"Google One Tap sign-in failed.");return}let f=null,p=null;try{const y=await V(e.authClient);if(o())return;f=y.user,p=y.session}catch(y){if(o())return;n(y,"Sign-in succeeded but session lookup failed.");return}if(!f||!p){n(new _("Google One Tap completed without an authenticated session.",{code:"ONE_TAP_NO_SESSION"}),"Google One Tap completed without an authenticated session.");return}s(f,p)}const j=new WeakMap;function jt(t){if(!t)throw new g("authUI.mount(container, options) requires either { redirectTo } or { onSuccess }.");const e="redirectTo"in t,i="onSuccess"in t&&typeof t.onSuccess=="function";if(!e&&!i)throw new g("authUI.mount(container, options) requires either { redirectTo } or { onSuccess }.");if("redirectTo"in t){const s=t.redirectTo;if(!(typeof s=="string"||s instanceof URL))throw new g("authUI.mount(container, options) expected redirectTo to be a string or URL.")}if("onSuccess"in t&&t.onSuccess!==void 0&&typeof t.onSuccess!="function")throw new g("authUI.mount(container, options) expected onSuccess to be a function.");if("onError"in t&&t.onError!==void 0&&typeof t.onError!="function")throw new g("authUI.mount(container, options) expected onError to be a function.");if("appearance"in t&&t.appearance!==void 0){const s=t.appearance;if(!s||typeof s!="object"||Array.isArray(s))throw new g("authUI.mount(container, options) expected appearance to be an object.");if("theme"in s&&s.theme!==void 0&&!Pt(s.theme))throw new g(`authUI.mount(container, options) expected appearance.theme to be one of: ${Se.join(", ")}.`);if("className"in s&&s.className!==void 0&&typeof s.className!="string")throw new g("authUI.mount(container, options) expected appearance.className to be a string.");if("variables"in s&&s.variables!==void 0){if(!s.variables||typeof s.variables!="object"||Array.isArray(s.variables))throw new g("authUI.mount(container, options) expected appearance.variables to be an object.");for(const[n,o]of Object.entries(s.variables)){if(!At(n))throw new g(`authUI.mount(container, options) received unsupported appearance.variables key "${n}".`);if(o!==void 0&&typeof o!="string")throw new g(`authUI.mount(container, options) expected appearance.variables["${n}"] to be a string.`)}}}}function xt(t){if(!(t instanceof HTMLElement))throw new g("authUI.mount(container, options) requires a real HTMLElement container.")}function qt(t,e){const i=Gt({authClient:e.publicAuthClient,loadConfig:Ue});return{mount(s,n){var p;jt(n),xt(s),(p=j.get(s))==null||p.destroy();const o=new $t(s,t,n,Ue,e),u=o.destroy.bind(o),f={destroy(){u(),j.get(s)===f&&j.delete(s)}};return j.set(s,f),f},promptGoogleOneTap:i}}function Kt(){$e();const t=pt(),e=bt(),i=Ye(),s=qt(e,{syncPublicSession:async()=>{await wt(t)},publicAuthClient:t});return{auth:t,api:i,authUI:s}}exports.AUTH_UI_APPEARANCE_VARIABLE=je;exports.AUTH_UI_APPEARANCE_VARIABLE_NAMES=xe;exports.AUTH_UI_DEFAULT_THEME=ze;exports.AUTH_UI_THEME=ve;exports.AUTH_UI_THEMES=Se;exports.AUTH_UI_THEME_DARK=Ge;exports.AUTH_UI_THEME_LIGHT=Ee;exports.EdgeSparkAuthError=_;exports.EdgeSparkConfigError=g;exports.EdgeSparkError=K;exports.EdgeSparkRuntimeError=be;exports.ar=we;exports.createEdgeSpark=Kt;exports.de=me;exports.detectLocale=Fe;exports.enUS=H;exports.es=q;exports.fr=he;exports.hi=pe;exports.it=fe;exports.ja=de;exports.ko=ce;exports.ptBR=ue;exports.ru=ge;exports.zhCN=x;
|
|
163
|
+
`}bindDOM(){this.root.querySelectorAll("form[data-view]").forEach(n=>{n.addEventListener("submit",o=>{o.preventDefault();const c=n.dataset.view;c==="sign-in"&&this.handleSignIn(),c==="sign-up"&&this.handleSignUp(),c==="forgot-password"&&this.handleForgotPassword(),c==="reset-password"&&this.handleResetPassword()})}),this.root.querySelectorAll("input[name]").forEach(n=>{n.addEventListener("input",()=>{$t(n.name)&&(this.state[n.name]=n.value,n.name==="email"&&this.state.signInOtpSent&&(this.state.signInOtpSent=!1,this.state.code="",this.clearCountdown()))})}),this.root.querySelectorAll("[data-action]").forEach(n=>{n.addEventListener("click",()=>{const o=n.dataset.action;o==="switch-sign-up"&&this.switchView("sign-up"),o==="switch-sign-in"&&this.switchView("sign-in"),o==="forgot-password"&&this.switchView("forgot-password"),o==="resend-verification"&&this.resendVerificationEmail(),o==="use-different-email"&&this.switchView(this.verificationCompletionAction==="sign-in"?"sign-in":"sign-up"),o==="sign-in-method"&&this.setSignInMethod(n.dataset.method==="otp"?"otp":"password"),o==="resend-sign-in-code"&&this.resendSignInCode(),o==="resend-reset-code"&&this.resendResetCode(),o==="oauth"&&this.handleOAuthSignIn(n.dataset.provider)})})}switchView(e){this.clearCountdown(),e!=="verify-email"&&(this.verificationCompletionAction=null),this.state.view=e,this.state.error=null,this.state.notice=null,this.state.busy=!1,this.state.busyLabel=void 0,this.terminalActionInProgress=!1,this.render()}async handleSignIn(){var s,i;if(((s=this.config)!=null&&s.emailOtpSignInEnabled&&!((i=this.config)!=null&&i.emailPasswordEnabled)?"otp":this.state.signInMethod)==="otp"){await this.handleEmailOtpSignIn();return}if(!G(this.state.email)){this.failValidation(this.labels.errors.invalidEmail);return}if(!this.state.password){this.failValidation(this.labels.errors.requiredField);return}await this.runAction("Signing in…",async()=>{const n=await this.auth.signIn.email({email:this.state.email.trim(),password:this.state.password,callbackURL:this.getManagedReturnURL(N,this.state.email.trim())});if(n.error)throw n.error;await this.completeAuth("sign-in")})}async handleEmailOtpSignIn(){if(!this.canUseEmailOtpSignIn()){this.handleError(new p("Email OTP sign-in is not enabled for this project."));return}if(!G(this.state.email)){this.failValidation(this.labels.errors.invalidEmail);return}if(!this.state.signInOtpSent){await this.sendSignInOtp();return}if(!Ue(this.state.code)){this.failValidation(this.labels.errors.invalidCode);return}await this.runAction("Signing in...",async()=>{const e=await this.emailOtpSignInEndpoints().signIn.emailOtp({email:this.state.email.trim(),otp:this.state.code.trim()});if(e.error)throw e.error;await this.completeAuth("sign-in",await this.resolveAuthCompletionData(e.data))})}async sendSignInOtp(e=!1){await this.runAction("Sending sign-in code...",async()=>{var i;const s=await this.emailOtpSignInEndpoints().emailOtp.sendVerificationOtp({email:this.state.email.trim(),type:"sign-in"});if(s.error)throw s.error;if(this.state.signInOtpSent=!0,this.state.code="",(i=this.config)!=null&&i.isLocalDev){this.state.busyLabel="Dev mode: fetching sign-in code...",this.render();const n=await _t(this.state.email.trim());n?(this.state.code=n,this.state.notice=`Dev mode: sign-in code auto-filled (${n})`):this.state.notice="Dev mode: could not retrieve sign-in code — check server logs"}else this.state.notice=e?`We sent another sign-in code to ${this.state.email.trim()}.`:`We sent a sign-in code to ${this.state.email.trim()}.`;this.startCountdown()})}async resendSignInCode(){this.isCountdownActive()||await this.sendSignInOtp(!0)}async handleSignUp(){var e,s;if(!this.state.name.trim()){this.failValidation(this.labels.errors.requiredField);return}if(!G(this.state.email)){this.failValidation(this.labels.errors.invalidEmail);return}if(!this.state.password){this.failValidation(this.labels.errors.requiredField);return}if(this.state.password.length<(((e=this.config)==null?void 0:e.minPasswordLength)??8)){this.failValidation(this.labels.errors.passwordTooShort.replace("{min}",String(((s=this.config)==null?void 0:s.minPasswordLength)??8)));return}if(this.state.password!==this.state.confirmPassword){this.failValidation(this.labels.errors.passwordMismatch);return}await this.runAction("Creating account…",async()=>{var n;const i=await this.auth.signUp.email({name:this.state.name.trim(),email:this.state.email.trim(),password:this.state.password,callbackURL:this.getManagedReturnURL(C,this.state.email.trim())});if(i.error)throw i.error;if((n=this.config)!=null&&n.requireEmailVerification){if(this.config.isLocalDev&&await this.tryDevAutoVerify("sign-up",i.data))return;this.verificationCompletionAction="sign-up",this.state.view="verify-email",this.state.notice=this.config.isLocalDev?"Dev mode: auto-verify didn’t complete. Click resend to retry.":"Check your inbox to verify your email address.",this.startCountdown();return}await this.completeAuth("sign-up",await this.resolveAuthCompletionData(i.data))})}async handleOAuthSignIn(e){await this.runAction(`Redirecting to ${ne[e]}…`,async()=>{const s=await this.auth.signIn.social({provider:e,callbackURL:this.getManagedReturnURL("oauth"),errorCallbackURL:this.getManagedReturnURL("oauth")});if(s.error)throw s.error;const i=this.extractRedirectURL(s.data);if(!i)throw new p(`OAuth sign-in did not return a redirect URL for provider "${e}".`);this.terminalActionInProgress=!0,this.state.busy=!0,this.state.busyLabel=`Opening ${ne[e]}…`,this.state.error=null,this.state.notice=null,this.render(),window.location.assign(i)})}async handleForgotPassword(){if(!this.canUsePasswordResetEmailOtp()){this.handleError(new p("Password reset via email OTP is not enabled for this project."));return}if(!G(this.state.email)){this.failValidation(this.labels.errors.invalidEmail);return}await this.runAction("Sending reset code…",async()=>{var s;const e=await this.passwordResetEndpoints().forgetPassword.emailOtp({email:this.state.email.trim()});if(e.error)throw e.error;if(this.state.view="reset-password",(s=this.config)!=null&&s.isLocalDev){this.state.busyLabel="Dev mode: fetching reset code…",this.render();const i=await St(this.state.email.trim());i?(this.state.code=i,this.state.notice=`Dev mode: reset code auto-filled (${i})`):this.state.notice="Dev mode: could not retrieve reset code — check server logs"}else this.state.notice=`We sent a reset code to ${this.state.email.trim()}.`;this.startCountdown()})}async resendResetCode(){this.isCountdownActive()||await this.handleForgotPassword()}async handleResetPassword(){var e,s;if(!this.canUsePasswordResetEmailOtp()){this.handleError(new p("Password reset via email OTP is not enabled for this project."));return}if(!Ue(this.state.code)){this.failValidation(this.labels.errors.invalidCode);return}if(!this.state.newPassword){this.failValidation(this.labels.errors.requiredField);return}if(this.state.newPassword.length<(((e=this.config)==null?void 0:e.minPasswordLength)??8)){this.failValidation(this.labels.errors.passwordTooShort.replace("{min}",String(((s=this.config)==null?void 0:s.minPasswordLength)??8)));return}if(this.state.newPassword!==this.state.confirmPassword){this.failValidation(this.labels.errors.passwordMismatch);return}await this.runAction("Updating password…",async()=>{const i=await this.passwordResetEndpoints().emailOtp.resetPassword({email:this.state.email.trim(),otp:this.state.code.trim(),password:this.state.newPassword});if(i.error)throw i.error;await this.completePasswordReset()})}async resendVerificationEmail(){var e;if((e=this.config)!=null&&e.isLocalDev){if(this.isCountdownActive())return;await this.runAction("Dev mode: retrying auto-verify…",async()=>{const s=this.verificationCompletionAction??"sign-in";if(!await this.tryDevAutoVerify(s))throw new Error("Dev auto-verify did not complete. Check the edgespark dev logs and try again.")});return}await this.sendVerificationEmail(!1)}async tryDevAutoVerify(e,s){const i=this.state.email.trim();try{return this.state.busyLabel="Dev mode: auto-verifying email…",this.render(),await Et(i)?(this.state.notice="Dev mode: email verification auto-completed",await this.completeAuth(e,await this.resolveAuthCompletionData(s)),!0):(console.warn("[edgespark] Dev auto-verify returned false — falling through"),!1)}catch(n){return console.warn("[edgespark] Dev auto-verify failed:",n),!1}}async sendVerificationEmail(e){!e&&this.isCountdownActive()||await this.runAction("Sending verification email…",async()=>{const s=await this.auth.sendVerificationEmail({email:this.state.email.trim(),callbackURL:this.getManagedReturnURL(this.verificationCompletionAction==="sign-up"?C:N,this.state.email.trim())});if(s.error)throw s.error;this.handleVerificationEmailSent(this.state.email.trim(),!0)})}async completeAuth(e,s){const i=await this.retryAuthCompletionDataIfNeeded(s??await this.resolveAuthCompletionData());if(this.destroyed)return;if(!i.user||!i.session){if(this.destroyed)return;if(i.lookupError&&U(this.options)){this.navigateToRedirect();return}if(e==="sign-in")throw i.lookupError??new be("Managed sign-in completed without an authenticated session.");this.state.view="sign-in",this.state.password="",this.state.confirmPassword="",this.state.error=null,this.state.busy=!1,this.state.busyLabel=void 0,this.state.notice="Account created. Sign in to continue.",this.render();return}const n={action:e,user:i.user,session:i.session};if(await this.syncPublicSessionBestEffort(),!this.destroyed){if(U(this.options)){this.invokeRedirectModeSuccessHook(n),this.navigateToRedirect();return}if(re(this.options)){this.options.onSuccess(n),this.terminalActionInProgress=!0;return}}}async retryAuthCompletionDataIfNeeded(e){if(e.session)return e;let s=e.lookupError;for(let i=0;i<ie;i++){await new Promise(n=>setTimeout(n,Ce));try{const n=await V(this.auth);if(n.user&&n.session)return{user:n.user,session:n.session}}catch(n){s=n}}return{...e,lookupError:s??e.lookupError}}async syncPublicSessionBestEffort(){var e,s;try{await((s=(e=this.runtimeOptions)==null?void 0:e.syncPublicSession)==null?void 0:s.call(e))}catch{}}async resolveAuthCompletionData(e){try{const s=await V(this.auth),i=this.extractUser(e);return{user:s.user??i,session:s.session}}catch(s){return{user:this.extractUser(e),session:null,lookupError:s}}}async completePasswordReset(){const e={action:"password-reset",user:null,session:null};if(await this.syncPublicSessionBestEffort(),!this.destroyed){if(re(this.options)){this.clearCountdown(),this.options.onSuccess(e),this.terminalActionInProgress=!0;return}this.invokeRedirectModeSuccessHook(e),this.clearCountdown(),this.state.view="sign-in",this.state.password="",this.state.confirmPassword="",this.state.newPassword="",this.state.code="",this.state.busy=!1,this.state.busyLabel=void 0,this.state.error=null,this.state.notice="Password updated. Sign in with your new password.",this.render()}}handleExistingSessionOnMount(){if(U(this.options)){this.navigateToRedirect();return}if(re(this.options))throw this.state.view="sign-in",this.state.busy=!1,this.state.busyLabel=void 0,this.state.notice=null,new p("authUI.mount(container, { onSuccess }) cannot run while a session already exists. Check es.auth.getSession() before mounting controlled auth UI.")}async runAction(e,s){this.state.busy=!0,this.state.busyLabel=e,this.state.error=null,this.state.notice=null,this.render();try{await s()}catch(i){if(this.maybeHandleVerificationRequired(i))return;this.handleError(i);return}!this.destroyed&&!this.terminalActionInProgress&&(this.state.busy=!1,this.state.busyLabel=void 0,this.render())}maybeHandleVerificationRequired(e){return ee(e).code!=="EMAIL_NOT_VERIFIED"?!1:(this.verificationCompletionAction="sign-in",this.state.view="verify-email",this.state.busy=!1,this.state.busyLabel=void 0,this.state.error=null,this.state.notice=`Verify your email to finish signing in as ${this.state.email.trim()}.`,this.render(),this.sendVerificationEmail(!0),!0)}handleVerificationEmailSent(e,s){this.state.notice=s?`We sent another verification email to ${e}.`:`We sent a verification email to ${e}.`,this.startCountdown()}invokeRedirectModeSuccessHook(e){var s,i;if(!(!U(this.options)||!this.options.onSuccess))try{this.options.onSuccess(e)}catch(n){const o=ee(n,"Post-auth callback failed.");try{(i=(s=this.options).onError)==null||i.call(s,o)}catch{}}}handleError(e,s){var n,o;const i=ee(e,s);this.state.busy=!1,this.state.busyLabel=void 0,this.state.error=i.message,this.render(),(o=(n=this.options).onError)==null||o.call(n,i)}failValidation(e){this.state.error=e,this.state.notice=null,this.render()}getManagedReturnURL(e,s){if(!e)return window.location.href;const i=new URL(window.location.href);return i.searchParams.set(te,e),s?i.searchParams.set(F,s):i.searchParams.delete(F),i.toString()}consumeManagedReturnContext(){const e=new URL(window.location.href),s=e.searchParams.get(te),i=s===se||s===N||s===C?s:null,n=e.searchParams.get(F),o=i?e.searchParams.get("error"):null,c=i?e.searchParams.get("error_description"):null;return(i||n)&&(e.searchParams.delete(te),e.searchParams.delete(F),i&&(e.searchParams.delete("error"),e.searchParams.delete("error_description")),window.history.replaceState(null,"",e.toString())),{marker:i,email:n,error:o,errorDescription:c}}startCountdown(e=60){this.countdownUntil=Date.now()+e*1e3,this.countdownTimer&&window.clearInterval(this.countdownTimer),this.countdownTimer=window.setInterval(()=>{if(!this.isCountdownActive()){this.countdownTimer&&(window.clearInterval(this.countdownTimer),this.countdownTimer=null),this.render();return}this.render()},1e3)}clearCountdown(){this.countdownUntil=null,this.countdownTimer&&(window.clearInterval(this.countdownTimer),this.countdownTimer=null)}captureFocusSnapshot(){const e=document.activeElement;return!(e instanceof HTMLInputElement)||!this.root.contains(e)||!e.name?null:{name:e.name,type:e.type,selectionStart:e.selectionStart,selectionEnd:e.selectionEnd}}scheduleFocusRestore(){this.pendingFocusSnapshot&&(this.clearFocusRestoreTimer(),this.focusRestoreTimer=window.setTimeout(()=>{if(this.focusRestoreTimer=null,this.destroyed||!this.pendingFocusSnapshot)return;const e=this.pendingFocusSnapshot,s=`input[name="${this.escape(e.name)}"][type="${this.escape(e.type)}"]`,i=this.root.querySelector(s);if(!(!i||i.disabled)){if(i.focus(),e.selectionStart!==null&&e.selectionEnd!==null)try{i.setSelectionRange(e.selectionStart,e.selectionEnd)}catch{const n=i.value.length;i.setSelectionRange(n,n)}this.pendingFocusSnapshot=null}},0))}clearFocusRestoreTimer(){this.focusRestoreTimer!==null&&(window.clearTimeout(this.focusRestoreTimer),this.focusRestoreTimer=null)}passwordResetEndpoints(){return this.auth}emailOtpSignInEndpoints(){return this.auth}resolveInitialSignInMethod(){var e,s;return(e=this.config)!=null&&e.emailPasswordEnabled?"password":(s=this.config)!=null&&s.emailOtpSignInEnabled?"otp":"password"}setSignInMethod(e){this.state.signInMethod!==e&&(this.state.signInMethod=e,this.state.signInOtpSent=!1,this.state.code="",this.state.error=null,this.state.notice=null,this.render())}canUseEmailOtpSignIn(){var e;return!!((e=this.config)!=null&&e.emailOtpSignInEnabled)}extractRedirectURL(e){if(!e||typeof e!="object")return null;const s=e;return s.redirect&&typeof s.url=="string"&&s.url.length>0?s.url:null}extractUser(e){if(!e||typeof e!="object")return null;const s=e;return s.user&&typeof s.user=="object"?s.user:null}canUsePasswordResetEmailOtp(){var e;return!!((e=this.config)!=null&&e.passwordResetEmailOtpEnabled)}handleSessionlessManagedReturn(e){return e.email&&(this.state.email=e.email),e.marker===C&&!e.error?(this.verificationCompletionAction=null,this.clearCountdown(),this.state.view="sign-in",this.state.password="",this.state.confirmPassword="",this.state.error=null,this.state.busy=!1,this.state.busyLabel=void 0,this.state.notice="Account created. Sign in to continue.",this.render(),!0):e.marker===N||e.marker===C?(this.verificationCompletionAction=e.marker===C?"sign-up":"sign-in",this.state.view="verify-email",this.state.busy=!1,this.state.busyLabel=void 0,this.state.notice=null,e.error||e.errorDescription?this.handleError(new I(e.errorDescription??"Verification failed. Request a new verification email and try again.",{code:e.error??"VERIFY_EMAIL_ERROR"})):this.render(),!0):e.marker===se&&(e.error||e.errorDescription)?(this.state.view="sign-in",this.state.busy=!1,this.state.busyLabel=void 0,this.state.notice=null,this.handleError(new I(e.errorDescription??"OAuth sign-in failed.",{code:e.error??"OAUTH_ERROR"})),!0):!1}isCountdownActive(){return this.getCountdownSecondsRemaining()>0}getCountdownSecondsRemaining(){return this.countdownUntil?Math.max(0,Math.ceil((this.countdownUntil-Date.now())/1e3)):0}countdownText(e,s){const i=this.getCountdownSecondsRemaining();return i<=0?e:s.replace("{seconds}",String(i))}escape(e){return e.replace(/[&<>"']/g,s=>Ut[s])}}function Bt(t){return"data"in t&&t.data?t.data:t}const Mt=[{id:"google",key:"providerGoogle"},{id:"apple",key:"providerApple"},{id:"microsoft",key:"providerMicrosoft"},{id:"github",key:"providerGithub"},{id:"gitlab",key:"providerGitlab"},{id:"discord",key:"providerDiscord"}],$e=2,Dt=500;async function Nt(){const t=`${window.location.origin}${Me}/config`;let e;for(let s=0;s<=$e;s++)try{const i=await fetch(t,{method:"GET",credentials:"include"});if(!i.ok)throw new p(`Failed to load auth config: HTTP ${i.status}`);const n=await i.json(),o=Bt(n);return Vt(o,yt())}catch(i){e=i,s<$e&&await new Promise(n=>setTimeout(n,Dt))}throw e}let z=null;async function ke(){return z||(z=Nt().catch(t=>{throw z=null,t})),z}function Vt(t,e=!1){var o,c,h,w,_,b,g,E,l;const s=Mt.filter(({key:P})=>{const L=t[P];return typeof L=="object"&&L!==null&&"enabled"in L&&!!L.enabled}).map(({id:P})=>P),i=t.providerGoogle,n=i!=null&&i.enabled&&typeof((o=i.config)==null?void 0:o.clientId)=="string"?i.config.clientId:null;return{disableSignUp:!!t.disableSignUp,emailPasswordEnabled:!!((c=t.providerEmailPassword)!=null&&c.enabled),emailOtpSignInEnabled:!!((h=t.providerEmailOtp)!=null&&h.enabled),minPasswordLength:((_=(w=t.providerEmailPassword)==null?void 0:w.config)==null?void 0:_.minPasswordLength)??8,requireEmailVerification:!!((g=(b=t.providerEmailPassword)==null?void 0:b.config)!=null&&g.requireEmailVerification),passwordResetEmailOtpEnabled:!!((l=(E=t.providerEmailPassword)==null?void 0:E.config)!=null&&l.requirePasswordResetEmailVerification),oauthProviders:s,googleClientId:n,isLocalDev:e}}const Ht="https://accounts.google.com/gsi/client",Oe="data-edgespark-gsi";let x=null;function oe(){var t,e;return(e=(t=window.google)==null?void 0:t.accounts)==null?void 0:e.id}function Ft(){if(typeof window>"u")return Promise.reject(new Error("Google Identity Services is unavailable outside the browser."));const t=oe();return t?Promise.resolve(t):(x||(x=new Promise((e,s)=>{const i=document.querySelector(`script[${Oe}]`);if(i){const o=oe();if(o){e(o);return}i.remove()}const n=document.createElement("script");n.src=Ht,n.async=!0,n.defer=!0,n.setAttribute(Oe,""),n.addEventListener("load",()=>{const o=oe();o?e(o):(n.remove(),s(new Error("Google Identity Services loaded but did not expose google.accounts.id.")))},{once:!0}),n.addEventListener("error",()=>{n.remove(),s(new Error("Failed to load Google Identity Services."))},{once:!0}),document.head.appendChild(n)}).catch(e=>{throw x=null,e})),x)}function Gt(){return{cancel:()=>{}}}function zt(t){let e=null;return function(i){if(typeof window>"u")return console.error("[edgespark] promptGoogleOneTap() requires a browser environment."),Gt();if(e)return console.warn("[edgespark] promptGoogleOneTap() is already in flight; returning the existing handle. Call cancel() on the original before re-prompting."),e;let n=!1,o=null;const c=()=>{n||(n=!0,e===h&&(e=null))},h={cancel(){if(!n&&(c(),o))try{o.cancel()}catch{}}},w=()=>{var g;if(!n){c();try{(g=i==null?void 0:i.onUnavailable)==null||g.call(i)}catch(E){console.error("[edgespark] onUnavailable threw:",E)}}},_=(g,E)=>{var P;if(n)return;c();const l=ve(g,E);try{(P=i==null?void 0:i.onError)==null||P.call(i,l)}catch(L){console.error("[edgespark] onError threw:",L)}},b=(g,E)=>{var l;if(!n){c();try{(l=i==null?void 0:i.onSuccess)==null||l.call(i,{action:"sign-in",user:g,session:E})}catch(P){console.error("[edgespark] onSuccess threw:",P)}}};return e=h,(async()=>{let g;try{g=await t.loadConfig()}catch(l){_(l,"Failed to load auth config for Google One Tap.");return}if(n)return;if(g.isLocalDev){console.error("[edgespark] promptGoogleOneTap() is disabled in local dev mode — Google Identity Services cannot run against mock OAuth."),c();return}const E=g.googleClientId;if(!E){console.error("[edgespark] promptGoogleOneTap() called but Google is not configured. Set `providerGoogle` in `auth-config.yaml` with resolvable credentials."),c();return}try{o=await Ft()}catch(l){console.warn("[edgespark] Google Identity Services failed to load; treating as unavailable.",l),w();return}if(!n){o.initialize({client_id:E,callback:l=>{n||typeof(l==null?void 0:l.credential)!="string"||l.credential.length===0||xt(l.credential,t,{emitSuccess:b,emitError:_,isDone:()=>n})},cancel_on_tap_outside:!1,use_fedcm_for_prompt:!0,context:"signin"});try{o.prompt(l=>{var P,L,D,a;if(!n){if((P=l.isDismissedMoment)!=null&&P.call(l)){const m=(L=l.getDismissedReason)==null?void 0:L.call(l);if(m==="credential_returned"||m==="cancel_called")return;w();return}((D=l.isNotDisplayed)!=null&&D.call(l)||(a=l.isSkippedMoment)!=null&&a.call(l))&&w()}})}catch(l){_(l,"Failed to prompt Google One Tap.")}}})(),h}}async function xt(t,e,s){var _;const{emitSuccess:i,emitError:n,isDone:o}=s,c=e.authClient;if(!((_=c.oneTap)!=null&&_.callback)){n(new I("Google One Tap endpoint not registered. Update the EdgeSpark sidecar.",{code:"ONE_TAP_UNAVAILABLE"}),"Google One Tap endpoint not registered.");return}try{const b=await c.oneTap.callback({idToken:t});if(o())return;if(b.error){n(new I(b.error.message??"Google One Tap sign-in failed.",{code:b.error.code??"ONE_TAP_FAILED",status:b.error.status,cause:b.error}),"Google One Tap sign-in failed.");return}}catch(b){if(o())return;n(b,"Google One Tap sign-in failed.");return}let h=null,w=null;try{const b=await V(e.authClient);if(o())return;h=b.user,w=b.session}catch(b){if(o())return;n(b,"Sign-in succeeded but session lookup failed.");return}if(!h||!w){n(new I("Google One Tap completed without an authenticated session.",{code:"ONE_TAP_NO_SESSION"}),"Google One Tap completed without an authenticated session.");return}i(h,w)}const j=new WeakMap;function jt(t){if(!t)throw new p("authUI.mount(container, options) requires either { redirectTo } or { onSuccess }.");const e="redirectTo"in t,s="onSuccess"in t&&typeof t.onSuccess=="function";if(!e&&!s)throw new p("authUI.mount(container, options) requires either { redirectTo } or { onSuccess }.");if("redirectTo"in t){const i=t.redirectTo;if(!(typeof i=="string"||i instanceof URL))throw new p("authUI.mount(container, options) expected redirectTo to be a string or URL.")}if("onSuccess"in t&&t.onSuccess!==void 0&&typeof t.onSuccess!="function")throw new p("authUI.mount(container, options) expected onSuccess to be a function.");if("onError"in t&&t.onError!==void 0&&typeof t.onError!="function")throw new p("authUI.mount(container, options) expected onError to be a function.");if("appearance"in t&&t.appearance!==void 0){const i=t.appearance;if(!i||typeof i!="object"||Array.isArray(i))throw new p("authUI.mount(container, options) expected appearance to be an object.");if("theme"in i&&i.theme!==void 0&&!At(i.theme))throw new p(`authUI.mount(container, options) expected appearance.theme to be one of: ${_e.join(", ")}.`);if("className"in i&&i.className!==void 0&&typeof i.className!="string")throw new p("authUI.mount(container, options) expected appearance.className to be a string.");if("variables"in i&&i.variables!==void 0){if(!i.variables||typeof i.variables!="object"||Array.isArray(i.variables))throw new p("authUI.mount(container, options) expected appearance.variables to be an object.");for(const[n,o]of Object.entries(i.variables)){if(!Lt(n))throw new p(`authUI.mount(container, options) received unsupported appearance.variables key "${n}".`);if(o!==void 0&&typeof o!="string")throw new p(`authUI.mount(container, options) expected appearance.variables["${n}"] to be a string.`)}}}}function qt(t){if(!(t instanceof HTMLElement))throw new p("authUI.mount(container, options) requires a real HTMLElement container.")}function Kt(t,e){const s=zt({authClient:e.publicAuthClient,loadConfig:ke});return{mount(i,n){var w;jt(n),qt(i),(w=j.get(i))==null||w.destroy();const o=new Ot(i,t,n,ke,e),c=o.destroy.bind(o),h={destroy(){c(),j.get(i)===h&&j.delete(i)}};return j.set(i,h),h},promptGoogleOneTap:s}}function Wt(){Be();const t=bt(),e=vt(),s=Je(),i=Kt(e,{syncPublicSession:async()=>{await wt(t)},publicAuthClient:t});return{auth:t,api:s,authUI:i}}exports.AUTH_UI_APPEARANCE_VARIABLE=je;exports.AUTH_UI_APPEARANCE_VARIABLE_NAMES=qe;exports.AUTH_UI_DEFAULT_THEME=xe;exports.AUTH_UI_THEME=Ee;exports.AUTH_UI_THEMES=_e;exports.AUTH_UI_THEME_DARK=ze;exports.AUTH_UI_THEME_LIGHT=Se;exports.EdgeSparkAuthError=I;exports.EdgeSparkConfigError=p;exports.EdgeSparkError=W;exports.EdgeSparkRuntimeError=be;exports.ar=pe;exports.createEdgeSpark=Wt;exports.de=me;exports.detectLocale=Ge;exports.enUS=H;exports.es=K;exports.fr=he;exports.hi=we;exports.it=fe;exports.ja=de;exports.ko=ce;exports.ptBR=ue;exports.ru=ge;exports.zhCN=q;
|