@seamless-auth/react 0.17.0 → 0.18.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +15 -0
- package/README.md +9 -10
- package/dist/AuthProvider.d.ts +6 -3
- package/dist/chunks/shared-D9GCCBrm.js +3 -0
- package/dist/chunks/shared-D9GCCBrm.js.map +1 -0
- package/dist/index.d.ts +2 -2
- package/dist/index.js +1 -1
- package/dist/index.js.map +1 -1
- package/dist/routes.js +1 -1
- package/package.json +2 -2
- package/dist/chunks/shared-DbQnDPUA.js +0 -3
- package/dist/chunks/shared-DbQnDPUA.js.map +0 -1
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,20 @@
|
|
|
1
1
|
# @seamless-auth/react
|
|
2
2
|
|
|
3
|
+
## 0.18.0
|
|
4
|
+
|
|
5
|
+
### Minor Changes
|
|
6
|
+
|
|
7
|
+
- 9847d05: `AuthProvider` is cookie transport only. Its `transport` prop no longer accepts `mode` or `tokenStorage`, and passing `mode: 'bearer'` throws, so in a browser the tokens stay with the server adapter in `httpOnly` cookies and a script on the page can never read them. `basePath`, `fetch` and `trustedOrigins` are unchanged. Native apps that need bearer transport use `@seamless-auth/react-native`, which is unaffected. No first-party template, the admin console or RoxTarget used bearer mode from `@seamless-auth/react`.
|
|
8
|
+
|
|
9
|
+
## 0.17.1
|
|
10
|
+
|
|
11
|
+
### Patch Changes
|
|
12
|
+
|
|
13
|
+
- 782583c: In bearer transport, a request that carries a token no longer follows a redirect to an origin outside `apiHost` and `trustedOrigins`. The client asks `fetch` for `redirect: 'manual'`, follows a redirect to a trusted origin itself (up to five hops, turning a `303`, or a `301` or `302` after a POST, into a GET as `fetch` does), and rejects any other with the new `UntrustedRedirectError` without sending the token on. Where the platform follows redirects regardless, as React Native's `fetch` does, a response that ended on another origin is rejected instead. A caller that sets `redirect` itself keeps that choice, and the final-origin check still applies. Requests without a token, and cookie transport, are unchanged.
|
|
14
|
+
- Updated dependencies [782583c]
|
|
15
|
+
- Updated dependencies [e3cf1f9]
|
|
16
|
+
- @seamless-auth/client@0.7.0
|
|
17
|
+
|
|
3
18
|
## 0.17.0
|
|
4
19
|
|
|
5
20
|
### Minor Changes
|
package/README.md
CHANGED
|
@@ -318,25 +318,24 @@ Custom UIs get the same default through `useAuthClient()`, and can still overrid
|
|
|
318
318
|
|
|
319
319
|
Everything that differs between a browser and another platform sits behind a port on
|
|
320
320
|
`AuthProvider`. A web application configures nothing; the browser implementations are the
|
|
321
|
-
defaults. A
|
|
321
|
+
defaults. A port can be swapped, for example to drive the passkey ceremonies yourself:
|
|
322
322
|
|
|
323
323
|
```tsx
|
|
324
324
|
<AuthProvider
|
|
325
325
|
apiHost={apiHost}
|
|
326
|
-
transport={{
|
|
327
|
-
ports={{ passkeys:
|
|
326
|
+
transport={{ basePath: '/identity', trustedOrigins: ['https://data.example.com'] }}
|
|
327
|
+
ports={{ passkeys: customPasskeys }}
|
|
328
328
|
>
|
|
329
329
|
<App />
|
|
330
330
|
</AuthProvider>
|
|
331
331
|
```
|
|
332
332
|
|
|
333
|
-
- `transport`
|
|
334
|
-
|
|
335
|
-
|
|
336
|
-
|
|
337
|
-
|
|
338
|
-
|
|
339
|
-
theft and revokes the chain.
|
|
333
|
+
- `transport` sets where the adapter is mounted (`basePath`, default `/auth`), the `fetch` to use,
|
|
334
|
+
and the extra origins `authorizedFetch` may reach (`trustedOrigins`). It is always cookie
|
|
335
|
+
transport: the server adapter holds the tokens in `httpOnly` cookies and the browser never sees
|
|
336
|
+
them, so a script on the page can ride the session but not read it. Passing `mode: 'bearer'`
|
|
337
|
+
throws. Native apps that need bearer transport, where the client holds the tokens in a keystore,
|
|
338
|
+
use `@seamless-auth/react-native`.
|
|
340
339
|
- `ports.passkeys` runs the WebAuthn ceremonies (`create`, `get`, and the two support checks).
|
|
341
340
|
`usePasskeySupport()` and every passkey flow go through it.
|
|
342
341
|
- `ports.oauthRedirect` opens the provider. The browser navigates away and the callback route
|
package/dist/AuthProvider.d.ts
CHANGED
|
@@ -63,10 +63,13 @@ interface AuthProviderProps {
|
|
|
63
63
|
*/
|
|
64
64
|
magicLinkRedirectUri?: string;
|
|
65
65
|
/**
|
|
66
|
-
*
|
|
67
|
-
*
|
|
66
|
+
* Where the adapter is mounted, the fetch to use, and the extra origins
|
|
67
|
+
* `authorizedFetch` may reach. Always cookie transport: the server adapter
|
|
68
|
+
* holds the tokens and the browser only HttpOnly cookies, so a script on the
|
|
69
|
+
* page can ride the session but never read it. Bearer transport is for
|
|
70
|
+
* native apps, through `@seamless-auth/react-native`.
|
|
68
71
|
*/
|
|
69
|
-
transport?: Omit<TransportOptions, 'apiHost'>;
|
|
72
|
+
transport?: Omit<TransportOptions, 'apiHost' | 'mode' | 'tokenStorage'>;
|
|
70
73
|
/** Platform ports. Each one left out falls back to the browser's. */
|
|
71
74
|
ports?: Partial<AuthPorts>;
|
|
72
75
|
/**
|
|
@@ -0,0 +1,3 @@
|
|
|
1
|
+
'use client';
|
|
2
|
+
import{createContext as e,useContext as t,useMemo as s,useRef as r,useSyncExternalStore as i,useEffect as o,useState as a}from"react";import{createBrowserOAuthRedirect as n,createBrowserPasskeyPort as c,createAuthSession as u,loadLoginMethods as p,detectPasskeySupport as d}from"@seamless-auth/client";import{jsx as h}from"react/jsx-runtime";const l=e(void 0),k=()=>{const e=t(l);if(!e)throw new Error("useAuth must be used within an AuthProvider");return e},m=({children:e,apiHost:t,autoDetectPreviousSignin:a=!0,magicLinkRedirectUri:p,transport:d,ports:k,initialSession:m})=>{const g=s(()=>({passkeys:k?.passkeys??c(),oauthRedirect:k?.oauthRedirect??n()}),[k?.passkeys,k?.oauthRedirect]);if("bearer"===d?.mode)throw new TypeError("@seamless-auth/react is cookie transport only, so the browser never holds the tokens. Use @seamless-auth/react-native for bearer transport in a native app.");const{basePath:v,fetch:y,trustedOrigins:S}=d??{},b=S?JSON.stringify(S):void 0,f=s(()=>d?{mode:"cookie",basePath:v,fetch:y,trustedOrigins:b?JSON.parse(b):void 0}:void 0,[v,y,b]),w=r(m),P=s(()=>u({apiHost:t,magicLinkRedirectUri:p,transport:f,passkeys:g.passkeys,detectPreviousSignIn:a,initialSession:w.current}),[t,p,f,g.passkeys,a]),R=i(P.subscribe,P.getState,P.getServerState);o(()=>{P.actions.refreshSession({background:void 0!==w.current})},[P]);const O=s(()=>({...R,...P.actions,apiHost:t,magicLinkRedirectUri:p,client:P.client,ports:g}),[R,P,t,p,g]);return h(l.Provider,{value:O,children:e})},g=()=>k().client,v=()=>{const e=g(),[t,s]=a(null),[r,i]=a(!0);return o(()=>{let t=!0;return p(e).then(e=>{t&&(e&&s(e),i(!1))}),()=>{t=!1}},[e]),{loginMethods:t,loading:r}},y=()=>{const{ports:e}=k(),[t,s]=a(!1),[r,i]=a(!0);return o(()=>{let t=!0;return d(e.passkeys).then(e=>{t&&(s(e),i(!1))}),()=>{t=!1}},[e.passkeys]),{passkeySupported:t,loading:r}};export{m as A,g as a,v as b,y as c,k as u};
|
|
3
|
+
//# sourceMappingURL=shared-D9GCCBrm.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"shared-D9GCCBrm.js","sources":["../../src/AuthProvider.tsx","../../src/hooks/useAuthClient.ts","../../src/hooks/useLoginMethods.ts","../../src/hooks/usePasskeySupport.ts"],"sourcesContent":[null,null,null,null],"names":["AuthContext","createContext","undefined","useAuth","context","useContext","Error","AuthProvider","children","apiHost","autoDetectPreviousSignin","magicLinkRedirectUri","transport","ports","providedPorts","initialSession","useMemo","passkeys","createBrowserPasskeyPort","oauthRedirect","createBrowserOAuthRedirect","mode","TypeError","basePath","fetch","fetchImpl","trustedOrigins","trustedOriginsKey","JSON","stringify","stableTransport","parse","initialSessionRef","useRef","session","createAuthSession","detectPreviousSignIn","current","state","useSyncExternalStore","subscribe","getState","getServerState","useEffect","actions","refreshSession","background","value","client","_jsx","Provider","useAuthClient","useLoginMethods","authClient","loginMethods","setLoginMethods","useState","loading","setLoading","active","loadLoginMethods","then","methods","usePasskeySupport","passkeySupported","setPasskeySupported","detectPasskeySupport","supported"],"mappings":";sVA4GA,MAAMA,EAAcC,OAA2CC,GAMlDC,EAAU,KACrB,MAAMC,EAAUC,EAAWL,GAC3B,IAAKI,EACH,MAAM,IAAIE,MAAM,+CAElB,OAAOF,GAgCIG,EAA4C,EACvDC,WACAC,UACAC,4BAA2B,EAC3BC,uBACAC,YACAC,MAAOC,EACPC,qBAKA,MAAMF,EAAQG,EACZ,KAAA,CACEC,SAAUH,GAAeG,UAAYC,IACrCC,cAAeL,GAAeK,eAAiBC,MAEjD,CAACN,GAAeG,SAAUH,GAAeK,gBAM3C,GAA4D,WAAvDP,GAA8CS,KACjD,MAAM,IAAIC,UACR,+JAIJ,MAAMC,SAAEA,EAAUC,MAAOC,EAASC,eAAEA,GAAmBd,GAAa,CAAA,EAE9De,EAAoBD,EAAiBE,KAAKC,UAAUH,QAAkBxB,EACtE4B,EAAkBd,EACtB,IACEJ,EACI,CACES,KAAM,SACNE,WACAC,MAAOC,EACPC,eAAgBC,EACXC,KAAKG,MAAMJ,QACZzB,QAENA,EAEN,CAACqB,EAAUE,EAAWE,IAMlBK,EAAoBC,EAAOlB,GAE3BmB,EAAUlB,EACd,IACEmB,EAAkB,CAChB1B,UACAE,uBACAC,UAAWkB,EACXb,SAAUJ,EAAMI,SAChBmB,qBAAsB1B,EACtBK,eAAgBiB,EAAkBK,UAEtC,CACE5B,EACAE,EACAmB,EACAjB,EAAMI,SACNP,IAOE4B,EAAQC,EACZL,EAAQM,UACRN,EAAQO,SACRP,EAAQQ,gBAcVC,EAAU,KACHT,EAAQU,QAAQC,eAAe,CAClCC,gBAA0C5C,IAA9B8B,EAAkBK,WAE/B,CAACH,IAEJ,MAAMa,EAAQ/B,EACZ,KAAA,IACKsB,KACAJ,EAAQU,QACXnC,UACAE,uBACAqC,OAAQd,EAAQc,OAChBnC,UAEF,CAACyB,EAAOJ,EAASzB,EAASE,EAAsBE,IAGlD,OAAOoC,EAACjD,EAAYkD,SAAQ,CAACH,MAAOA,EAAKvC,SAAGA,KCxPjC2C,EAAgB,IACpBhD,IAAU6C,OCQNI,EAAkB,KAC7B,MAAMC,EAAaF,KACZG,EAAcC,GAAmBC,EAA+B,OAChEC,EAASC,GAAcF,GAAS,GAmBvC,OAjBAb,EAAU,KACR,IAAIgB,GAAS,EAWb,OATKC,EAAiBP,GAAYQ,KAAKC,IAChCH,IAEDG,GACFP,EAAgBO,GAElBJ,GAAW,MAGN,KACLC,GAAS,IAEV,CAACN,IAEG,CAAEC,eAAcG,YCjCZM,EAAoB,KAC/B,MAAMlD,MAAEA,GAAUV,KACX6D,EAAkBC,GAAuBT,GAAS,IAClDC,EAASC,GAAcF,GAAS,GAiBvC,OAfAb,EAAU,KACR,IAAIgB,GAAS,EASb,OAPKO,EAAqBrD,EAAMI,UAAU4C,KAAKM,IACzCR,IACFM,EAAoBE,GACpBT,GAAW,MAIR,KACLC,GAAS,IAEV,CAAC9C,EAAMI,WAEH,CAAE+C,mBAAkBP"}
|
package/dist/index.d.ts
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { AuthContextType, AuthPorts, AuthProvider, useAuth } from './AuthProvider';
|
|
2
2
|
import { createSeamlessAuthClient, CredentialUpdateResult, CreateOrganizationInput, CurrentUserResult, FinishOAuthLoginInput, FinishOAuthLoginResult, LoginInput, LoginMethod, LoginStartResult, MessageResult, OAuthProvider, OAuthProvidersResult, PublicSystemConfigResult, OrganizationMemberInput, OrganizationMemberUpdateInput, OrganizationMembersResult, OrganizationMembershipResult, OrganizationResult, OrganizationSwitchResult, OrganizationsResult, PasskeyLoginData, PasskeyAttachment, PasskeyMetadata, PasskeyRegistrationData, RegisterInput, RegisterPasskeyOptions, SeamlessAuthClient, SeamlessAuthClientOptions, StartOAuthLoginInput, StartOAuthLoginResult, StepUpMethod, StepUpStatus, StepUpPrfData, TotpEnrollmentStartResult, TotpStatus, UpdateOrganizationInput } from '@seamless-auth/client';
|
|
3
|
-
import { getOAuthErrorCode, getPasskeyPolicyErrorCode, getWebAuthnErrorDetail, isUnauthenticated, OAuthErrorCode, PasskeyPolicyErrorCode, SeamlessAuthError, UntrustedOriginError, WebAuthnErrorDetail } from '@seamless-auth/client';
|
|
3
|
+
import { getOAuthErrorCode, getPasskeyPolicyErrorCode, getWebAuthnErrorDetail, isUnauthenticated, OAuthErrorCode, PasskeyPolicyErrorCode, SeamlessAuthError, UntrustedOriginError, UntrustedRedirectError, WebAuthnErrorDetail } from '@seamless-auth/client';
|
|
4
4
|
import type { SeamlessAuthResult } from '@seamless-auth/client';
|
|
5
5
|
import { encodePrfSalt, extractPasskeyPrfResult, isPasskeyPrfSupported, PasskeyPrfInput, PasskeyPrfResult } from '@seamless-auth/client';
|
|
6
6
|
import { useAuthClient } from './hooks/useAuthClient';
|
|
@@ -10,5 +10,5 @@ import { usePasskeySupport } from './hooks/usePasskeySupport';
|
|
|
10
10
|
import { hasScopedRole, roleGrantsAccess } from '@seamless-auth/client';
|
|
11
11
|
import { Credential, Organization, OrganizationMembership, User } from '@seamless-auth/client';
|
|
12
12
|
import type { InitialSession, OAuthRedirectOutcome, OAuthRedirectPort, PasskeyPort, StoredTokens, TokenStoragePort, RefreshSessionOptions, TransportOptions } from '@seamless-auth/client';
|
|
13
|
-
export { AuthProvider, createSeamlessAuthClient, encodePrfSalt, extractPasskeyPrfResult, getOAuthErrorCode, getPasskeyPolicyErrorCode, getWebAuthnErrorDetail, hasNonPasskeyLoginMethod, hasScopedRole, isPasskeyPrfSupported, isUnauthenticated, roleGrantsAccess, SeamlessAuthError, UntrustedOriginError, useAuth, useAuthClient, useAuthorizedFetch, useLoginMethods, usePasskeySupport, };
|
|
13
|
+
export { AuthProvider, createSeamlessAuthClient, encodePrfSalt, extractPasskeyPrfResult, getOAuthErrorCode, getPasskeyPolicyErrorCode, getWebAuthnErrorDetail, hasNonPasskeyLoginMethod, hasScopedRole, isPasskeyPrfSupported, isUnauthenticated, roleGrantsAccess, SeamlessAuthError, UntrustedOriginError, UntrustedRedirectError, useAuth, useAuthClient, useAuthorizedFetch, useLoginMethods, usePasskeySupport, };
|
|
14
14
|
export type { CredentialUpdateResult, AuthContextType, AuthPorts, Credential, CreateOrganizationInput, CurrentUserResult, FinishOAuthLoginInput, FinishOAuthLoginResult, InitialSession, LoginInput, LoginMethod, LoginStartResult, MessageResult, OAuthErrorCode, OAuthProvider, OAuthProvidersResult, OAuthRedirectOutcome, OAuthRedirectPort, Organization, OrganizationMemberInput, OrganizationMembership, OrganizationMemberUpdateInput, OrganizationMembersResult, OrganizationMembershipResult, OrganizationResult, OrganizationSwitchResult, OrganizationsResult, PasskeyLoginData, PasskeyAttachment, PasskeyMetadata, PasskeyPolicyErrorCode, PasskeyPort, PasskeyPrfInput, PasskeyPrfResult, PasskeyRegistrationData, PublicSystemConfigResult, RefreshSessionOptions, RegisterInput, RegisterPasskeyOptions, SeamlessAuthClient, SeamlessAuthClientOptions, SeamlessAuthResult, StartOAuthLoginInput, StartOAuthLoginResult, StepUpMethod, StepUpStatus, StepUpPrfData, StoredTokens, TokenStoragePort, TotpEnrollmentStartResult, TotpStatus, TransportOptions, UpdateOrganizationInput, User, WebAuthnErrorDetail, };
|
package/dist/index.js
CHANGED
|
@@ -1,3 +1,3 @@
|
|
|
1
1
|
'use client';
|
|
2
|
-
import{u as e}from"./chunks/shared-
|
|
2
|
+
import{u as e}from"./chunks/shared-D9GCCBrm.js";export{A as AuthProvider,a as useAuthClient,b as useLoginMethods,c as usePasskeySupport}from"./chunks/shared-D9GCCBrm.js";export{SeamlessAuthError,UntrustedOriginError,UntrustedRedirectError,createSeamlessAuthClient,encodePrfSalt,extractPasskeyPrfResult,getOAuthErrorCode,getPasskeyPolicyErrorCode,getWebAuthnErrorDetail,hasNonPasskeyLoginMethod,hasScopedRole,isPasskeyPrfSupported,isUnauthenticated,roleGrantsAccess}from"@seamless-auth/client";import"react";import"react/jsx-runtime";const r=()=>e().client.authorizedFetch;export{e as useAuth,r as useAuthorizedFetch};
|
|
3
3
|
//# sourceMappingURL=index.js.map
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sources":["../src/hooks/useAuthorizedFetch.ts"],"sourcesContent":[null],"names":["useAuthorizedFetch","useAuth","client","authorizedFetch"],"mappings":";
|
|
1
|
+
{"version":3,"file":"index.js","sources":["../src/hooks/useAuthorizedFetch.ts"],"sourcesContent":[null],"names":["useAuthorizedFetch","useAuth","client","authorizedFetch"],"mappings":";qhBAaO,MAAMA,EAAqB,IAAMC,IAAUC,OAAOC"}
|
package/dist/routes.js
CHANGED
|
@@ -1,3 +1,3 @@
|
|
|
1
1
|
'use client';
|
|
2
|
-
import{jsxs as e,jsx as r,Fragment as o}from"react/jsx-runtime";import{useHref as i,useNavigate as n,useLocation as a,useSearchParams as s,Routes as t,Route as l,Navigate as c}from"react-router-dom";import{u as d,a as _,c as m,b as u}from"./chunks/shared-DbQnDPUA.js";import{useState as g,useEffect as f,useRef as p}from"react";import{fallbackSignInOptions as h,hasFallbackSignInOption as v,OAUTH_CALLBACK_PATH as b,startOAuthSignIn as y,isValidEmail as k,isValidPhoneNumber as x,beginSignIn as w,PASSKEY_SIGN_IN_FAILED as N,registerWithEmail as P,safeReturnPath as M,hasNonPasskeyLoginMethod as T,enrollPasskey as C,isOtpCharacter as O,otpCharacters as B,OTP_LIFETIME_SECONDS as I,formatCountdown as S,OTP_LENGTH as z,verifyOtp as L,requestOtp as q,otpResendFailedMessage as A,magicLinkConfirmationPrompt as D,getMagicLinkConfirmation as R,finishMagicLinkSignIn as E,confirmMagicLinkSignIn as j,completeOAuthCallback as F,MAGIC_LINK_RESEND_COOLDOWN_SECONDS as G,watchMagicLink as V}from"@seamless-auth/client";const U="/login",K="/passkey-login",Y="/verify-phone-otp",W="/verify-email-otp",J="/verify-magiclink",H="/oauth/callback",Z="/register-passkey",Q="/magic-link-sent";function X(e,r){void 0===r&&(r={});var o=r.insertAt;if(e&&"undefined"!=typeof document){var i=document.head||document.getElementsByTagName("head")[0],n=document.createElement("style");n.type="text/css","top"===o&&i.firstChild?i.insertBefore(n,i.firstChild):i.appendChild(n),n.styleSheet?n.styleSheet.cssText=e:n.appendChild(document.createTextNode(e))}}var $="login-module__container___YggDx",ee="login-module__card___Ub-Py",re="login-module__heading___neEqb",oe="login-module__inputGroup___P6qgS",ie="login-module__label___mx5vu",ne="login-module__input___U07lW",ae="login-module__helperText___kDQ4-",se="login-module__error___40zxh",te="login-module__button___0kFBs",le="login-module__submitHint___qOS5Z",ce="login-module__toggle___1JiG1",de="login-module__fallbackCard___HdIk-",_e="login-module__fallbackHeader___-il2v",me="login-module__fallbackDescription___ea5EB",ue="login-module__fallbackActions___AD3ni",ge="login-module__fallbackActionButton___lFgWf",fe="login-module__actionTitle___ycrMp",pe="login-module__actionSubtext___opaIV",he="login-module__linkButton___5lsoe";X(".login-module__container___YggDx{align-items:center;color:var(--seamless-text,#fff);display:flex;justify-content:center}.login-module__card___Ub-Py{background-color:var(--seamless-surface,#1f2937);border-radius:.5rem;box-shadow:0 4px 6px var(--seamless-shadow,rgba(0,0,0,.1));max-width:28rem;padding:2rem;width:100%}.login-module__heading___neEqb{color:var(--seamless-text,#fff);font-size:1.5rem;font-weight:700;margin-bottom:1.5rem;text-align:center}.login-module__message___qSejT{color:var(--seamless-success,#68d391);text-align:center}.login-module__inputGroup___P6qgS{margin-bottom:1rem}.login-module__label___mx5vu{color:var(--seamless-text-muted,#d1d5db);display:block}.login-module__input___U07lW{background-color:var(--seamless-surface-raised,#4b5563);border:1px solid var(--seamless-border,#d1d5db);border-radius:.375rem;margin-top:.25rem;padding:.5rem;width:100%}.login-module__input___U07lW:focus{box-shadow:0 0 0 2px var(--seamless-accent,#3b82f6);outline:none}.login-module__helperText___kDQ4-{color:var(--seamless-text-muted,#9ca3af);font-size:.75rem;margin-top:.5rem}.login-module__error___40zxh{color:var(--seamless-danger,#f87171);font-size:.875rem}.login-module__button___0kFBs{background-color:var(--seamless-accent,#2563eb);border-radius:.375rem;color:var(--seamless-accent-contrast,#fff);cursor:pointer;margin-top:1rem;padding:.5rem;transition:background-color .3s,opacity .3s;width:100%}.login-module__button___0kFBs:hover:not(:disabled){background-color:var(--seamless-accent-hover,#1d4ed8)}.login-module__button___0kFBs:disabled{cursor:not-allowed;opacity:.6}.login-module__submitHint___qOS5Z{color:var(--seamless-text-muted,#9ca3af);font-size:.75rem;margin-top:.5rem;text-align:center}.login-module__toggle___1JiG1{background:none;border:none;color:var(--seamless-accent-soft,#60a5fa);cursor:pointer;font-size:.875rem;margin-top:1.5rem;text-align:center;width:100%}.login-module__underline___gs-RS{text-decoration:underline}.login-module__phoneRow___oeNtq{display:grid;gap:.5rem;grid-template-columns:1fr 3fr;margin-top:.25rem}.login-module__phoneInput___2MPQC,.login-module__select___rRV1O{background-color:var(--seamless-surface-raised,#4b5563);border:1px solid var(--seamless-border,#d1d5db);border-radius:.375rem;padding:.5rem;width:100%}@media (max-width:500px){.login-module__phoneRow___oeNtq{grid-template-columns:1fr}}.login-module__fallbackCard___HdIk-{background:var(--seamless-surface-raised,hsla(0,0%,100%,.04));border:1px solid var(--seamless-border,hsla(0,0%,100%,.08));border-radius:12px;display:flex;flex-direction:column;gap:14px;margin-top:18px;padding:18px}.login-module__fallbackHeader___-il2v{color:var(--seamless-text,#f3f4f6);font-size:.95rem;font-weight:600}.login-module__fallbackDescription___ea5EB{color:var(--seamless-text-muted,#9ca3af);font-size:.85rem;line-height:1.4}.login-module__fallbackActions___AD3ni{display:flex;flex-direction:column;gap:10px}.login-module__fallbackActionButton___lFgWf{background:var(--seamless-surface,rgba(0,0,0,.25));border:1px solid var(--seamless-border,hsla(0,0%,100%,.08));border-radius:8px;cursor:pointer;display:flex;flex-direction:column;padding:12px 14px;text-align:left;transition:all .15s ease}.login-module__fallbackActionButton___lFgWf:hover{background:var(--seamless-surface-hover,hsla(0,0%,100%,.06));border-color:var(--seamless-border,hsla(0,0%,100%,.15))}.login-module__actionTitle___ycrMp{color:var(--seamless-text,#f9fafb);font-size:.9rem;font-weight:500}.login-module__actionSubtext___opaIV{color:var(--seamless-text-muted,#9ca3af);font-size:.75rem;margin-top:2px}.login-module__linkButton___5lsoe{background:none;border:none;color:var(--seamless-accent-soft,#60a5fa);cursor:pointer;font-size:.8rem;margin-top:6px}.login-module__linkButton___5lsoe:hover{text-decoration:underline}");const ve=({identifier:o,onMagicLink:i,onEmailOtp:n,onPhoneOtp:a,onPasskeyRetry:s,loginMethods:t})=>{const l=h(o,t,{emailOtp:Boolean(n),passkeyRetry:Boolean(s)});return v(l)?e("div",{className:de,children:[r("div",{className:_e,children:"Choose a sign-in method"}),r("p",{className:me,children:"Choose another secure sign-in method."}),e("div",{className:ue,children:[l.magicLink&&e("button",{type:"button",className:ge,onClick:i,children:[r("span",{className:fe,children:"Email Magic Link"}),r("span",{className:pe,children:"Send a secure sign-in link to your email"})]}),l.emailOtp&&e("button",{type:"button",className:ge,onClick:n,children:[r("span",{className:fe,children:"Email Code"}),r("span",{className:pe,children:"Receive a one-time code by email"})]}),l.phoneOtp&&e("button",{type:"button",className:ge,onClick:a,children:[r("span",{className:fe,children:"Text Message Code"}),r("span",{className:pe,children:"Receive a one-time code via SMS"})]})]}),l.passkeyRetry&&r("button",{type:"button",className:he,onClick:s,children:"Try passkey anyway"})]}):null},be=()=>{const{listOAuthProviders:o,startOAuthLogin:n,finishOAuthLogin:a,ports:s}=d(),t=i(b),[l,c]=g([]),[_,m]=g("");if(f(()=>{let e=!0;return o().then(({data:r})=>{e&&c(r?.providers??[])}),()=>{e=!1}},[o]),0===l.length)return null;return e("div",{className:ue,children:[l.map(o=>r("button",{type:"button",className:ge,onClick:()=>(async e=>{m("");const r=new URL(t,window.location.origin).toString(),{error:o}=await y({actions:{startOAuthLogin:n,finishOAuthLogin:a},oauthRedirect:s.oauthRedirect},{providerId:e,redirectUri:r});o&&m(o)})(o.id),children:e("span",{className:fe,children:["Continue with ",o.name]})},o.id)),_&&r("p",{className:se,children:_})]})},ye=()=>{const i=n(),{hasSignedInBefore:a,login:s,handlePasskeyLogin:t}=d(),l=_(),{passkeySupported:c}=m(),{loginMethods:p}=u(),[h,v]=g(""),[b,y]=g(""),[M,T]=g("register"),[C,O]=g(""),[B,I]=g(""),[S,z]=g(""),[L,q]=g(!1),[A,D]=g(null);f(()=>{a&&T("login")},[a]);const R=()=>"login"===M?k(h)||x(h):k(b);return r("div",{className:$,children:e("div",{className:ee,children:[r("h2",{className:re,children:"login"===M?"Sign In":"Create Account"}),e(o,{children:[e("form",{onSubmit:async e=>{e.preventDefault(),O(""),q(!1);try{if("login"===M){const e=await w({login:s,handlePasskeyLogin:t},{identifier:h,passkeySupported:c,configuredMethods:p});return"error"===e.kind?void O(e.message):"signed_in"===e.kind?void i("/"):(D(e.loginMethods),q(!0),void(e.passkeyFailed&&O(N)))}"register"===M&&await(async()=>{O("");const{error:e}=await P(l,b);e?O(e):i(W)})()}catch{console.error("Failed to continue sign-in."),O("Failed to continue sign-in. Please try again.")}},children:["login"===M&&e("div",{className:oe,children:[r("label",{htmlFor:"identifier",className:ie,children:"Email Address / Phone Number"}),r("input",{id:"identifier",type:"text",value:h,onChange:e=>{const r=e.target.value;v(r)},autoComplete:"off",placeholder:"Email or Phone Number",className:ne,onBlur:()=>{if(h){const e=k(h)||x(h);z(e?"":"Please enter a valid email or phone number")}},required:!0}),r("p",{className:ae,children:"Phone numbers must include a country code e.g. +1"}),L&&r(ve,{identifier:h,onMagicLink:async()=>{const{error:e}=await l.requestMagicLink();e?O("Failed to send magic link."):i(Q,{state:{identifier:h}})},onEmailOtp:async()=>{const{error:e}=await l.requestLoginEmailOtp();e?O("Failed to send email code."):i(W,{state:{flow:"login"}})},onPhoneOtp:async()=>{const{error:e}=await l.requestLoginPhoneOtp();e?O("Failed to send OTP."):i(Y,{state:{flow:"login"}})},onPasskeyRetry:c?t:void 0,loginMethods:A}),S&&r("p",{className:se,children:S})]}),"register"===M&&e("div",{className:oe,children:[r("label",{htmlFor:"email",className:ie,children:"Email Address"}),r("input",{id:"email",type:"email",value:b,onChange:e=>{const r=e.target.value;y(r)},autoComplete:"off",className:ne,onBlur:()=>{if(b){const e=k(b);I(e?"":"Please enter a valid email")}},required:!0}),B&&r("p",{className:se,children:B})]}),r("button",{type:"submit",className:te,disabled:!R(),"aria-describedby":"seamless-submit-hint",children:"login"===M?"Login":"Register"}),r("p",{id:"seamless-submit-hint",role:"status",className:le,children:"login"===M?h?R()?"Ready to continue.":"This does not look like a complete email or phone number yet.":"Enter your email or phone number to continue.":b?R()?"Ready to continue.":"This does not look like a complete email address yet.":"Enter your email address to continue."}),C&&r("p",{className:se,children:C}),r("button",{type:"button",onClick:()=>T("login"===M?"register":"login"),className:ce,children:"login"===M?"Don't have an account? Create one":"Already have an account? Sign in"})]}),r(be,{})]})]})})};var ke={container:"passKeyLogin-module__container___IUKxF",card:"passKeyLogin-module__card___2sKM1",title:"passKeyLogin-module__title___HZxvc",button:"passKeyLogin-module__button___FvR4I"};X(".passKeyLogin-module__container___IUKxF{align-items:center;color:var(--seamless-text,#fff);display:flex;justify-content:center;padding:1rem}.passKeyLogin-module__card___2sKM1{background-color:var(--seamless-surface,#1f2937);border-radius:1rem;box-shadow:0 4px 20px var(--seamless-shadow,rgba(0,0,0,.4));display:flex;flex-direction:column;gap:1.5rem;max-width:400px;padding:2rem;width:100%}.passKeyLogin-module__title___HZxvc{color:var(--seamless-text,#fff);font-size:1.5rem;font-weight:600;text-align:center}.passKeyLogin-module__button___FvR4I{background-color:var(--seamless-accent,#2563eb);border:1px solid var(--seamless-accent,#3b82f6);border-radius:.5rem;color:var(--seamless-accent-contrast,#fff);cursor:pointer;font-weight:500;padding:.75rem 1rem;text-align:center;transition:background-color .2s ease;width:100%}.passKeyLogin-module__button___FvR4I:hover{background-color:var(--seamless-accent-hover,#1d4ed8)}@media (max-width:480px){.passKeyLogin-module__card___2sKM1{padding:1.25rem}.passKeyLogin-module__button___FvR4I{font-size:1rem}}");const xe=()=>{const o=n(),{handlePasskeyLogin:i}=d(),[a,s]=g("");return r("div",{className:ke.container,children:e("div",{className:ke.card,children:[r("h2",{className:ke.title,children:"Login with Passkey"}),r("button",{onClick:async()=>{s("");const{error:e}=await i();e?s("Passkey sign-in could not be completed. Try another sign-in method."):o("/")},className:ke.button,children:"Use Passkey"}),a&&r("p",{className:ke.error,children:a})]})})};var we="registerPasskey-module__container___jqEh8",Ne="registerPasskey-module__card___MJAyC",Pe="registerPasskey-module__loading___Q4i1x",Me="registerPasskey-module__spinner___V1nhd",Te="registerPasskey-module__supported___ihTih",Ce="registerPasskey-module__title___vn2Qu",Oe="registerPasskey-module__description___AWmO-",Be="registerPasskey-module__button___D3b4B",Ie="registerPasskey-module__message___RiOw-",Se="registerPasskey-module__success___HP5aX",ze="registerPasskey-module__error___hGiqE",Le="registerPasskey-module__skip___1hDyU",qe="registerPasskey-module__secondary___bnOB4";X(".registerPasskey-module__container___jqEh8{align-items:center;color:var(--seamless-text,#fff);display:flex;justify-content:center;padding:1rem}.registerPasskey-module__card___MJAyC{background-color:var(--seamless-surface,#1f2937);border-radius:1rem;box-shadow:0 4px 20px var(--seamless-shadow,rgba(0,0,0,.4));max-width:400px;padding:1.5rem;width:100%}.registerPasskey-module__loading___Q4i1x{align-items:center;background-color:var(--seamless-surface,#f9fafb);border-radius:.75rem;box-shadow:0 2px 8px var(--seamless-shadow,rgba(0,0,0,.1));color:var(--seamless-text,#374151);display:flex;font-weight:500;gap:.75rem;justify-content:center;padding:1.5rem}.registerPasskey-module__spinner___V1nhd{animation:registerPasskey-module__spin___oYcsC 1s linear infinite;border-bottom:2px solid var(--seamless-accent,#3b82f6);border-left:2px solid transparent;border-radius:9999px;border-right:2px solid transparent;border-top:2px solid var(--seamless-accent,#3b82f6);height:1.5rem;width:1.5rem}@keyframes registerPasskey-module__spin___oYcsC{to{transform:rotate(1turn)}}.registerPasskey-module__supported___ihTih{background-color:var(--seamless-surface,#ecfdf5);border-radius:.75rem;box-shadow:0 2px 12px var(--seamless-shadow,rgba(0,0,0,.1));color:var(--seamless-text,#065f46);padding:1.25rem}.registerPasskey-module__title___vn2Qu{font-size:1.125rem;font-weight:600;margin-bottom:.5rem}.registerPasskey-module__description___AWmO-{margin-bottom:1rem}.registerPasskey-module__button___D3b4B{background-color:var(--seamless-accent,#059669);border:none;border-radius:.5rem;color:var(--seamless-accent-contrast,#fff);cursor:pointer;font-weight:500;padding:.75rem 1rem;transition:background-color .2s ease;width:100%}.registerPasskey-module__button___D3b4B:hover{background-color:var(--seamless-accent-hover,#047857)}.registerPasskey-module__message___RiOw-{font-size:.875rem;margin-top:1rem}.registerPasskey-module__success___HP5aX{color:var(--seamless-success,#6ee7b7)}.registerPasskey-module__error___hGiqE{color:var(--seamless-danger,#f87171)}.registerPasskey-module__skip___1hDyU{background:none;border:none;color:var(--seamless-accent-soft,#60a5fa);cursor:pointer;font-size:.875rem;margin-top:1.5rem;text-align:center;width:100%}.registerPasskey-module__skip___1hDyU:disabled{cursor:default;opacity:.6}.registerPasskey-module__secondary___bnOB4{background:none;border:1px solid var(--seamless-accent,#059669);border-radius:.5rem;color:var(--seamless-accent,#059669);cursor:pointer;font-weight:500;margin-top:.75rem;padding:.75rem 1rem;transition:background-color .2s ease;width:100%}.registerPasskey-module__secondary___bnOB4:hover:not(:disabled){background-color:var(--seamless-accent-muted,rgba(5,150,105,.1))}.registerPasskey-module__secondary___bnOB4:disabled{cursor:default;opacity:.6}");const Ae=()=>{const{refreshSession:o}=d(),i=_(),{passkeySupported:s,loading:t}=m(),{loginMethods:l,loading:c}=u(),f=n(),p=M(a().state?.returnTo),[h,v]=g("idle"),[b,y]=g(""),k=T(l),x=async()=>{await o(),f(p)},w=async e=>{v("loading");const{error:r}=await C({client:i,refreshSession:o},e);if(r)return v("error"),void y(r);v("success"),y("Passkey registered successfully."),f(p)};return r("div",{className:we,children:r("div",{className:Ne,children:e("div",t||c?{className:Pe,children:[r("div",{className:Me}),r("span",{children:"Checking for Passkey Support..."})]}:s?{className:Te,children:[r("h2",{className:Ce,children:"Secure Your Account with a Passkey"}),r("p",{className:Oe,children:"Your device supports passkeys! Register one to skip passwords forever."}),r("button",{onClick:()=>w(),disabled:"loading"===h,className:Be,children:"loading"===h?"Registering...":"Register Passkey"}),r("button",{type:"button",onClick:()=>w("cross-platform"),disabled:"loading"===h,className:qe,children:"Use a security key instead"}),b&&r("p",{className:`${Ie} ${"success"===h?Se:ze}`,children:b}),k&&r("button",{type:"button",onClick:x,disabled:"loading"===h,className:Le,children:"Skip for now"})]}:{className:Te,children:[r("h2",{className:Ce,children:"Passkeys are not available here"}),r("p",{className:Oe,children:k?"This device does not support passkeys. You can continue without one and add a passkey later from a device that does.":"This device does not support passkeys, and this application requires one to sign in. Try again from a device or browser that supports them."}),k&&r("button",{type:"button",onClick:x,className:Be,children:"Continue"})]})})})};var De="verifyOTP-module__container___wgoDE",Re="verifyOTP-module__card___3cs2p",Ee="verifyOTP-module__title___fZ-1d",je="verifyOTP-module__subtitle___dGSu3",Fe="verifyOTP-module__error___GEtlG",Ge="verifyOTP-module__success___46TjG",Ve="verifyOTP-module__form___jiGG-",Ue="verifyOTP-module__label___Zq5Mi",Ke="verifyOTP-module__timer___smq-a",Ye="verifyOTP-module__resend___PlmkG",We="verifyOTP-module__button___8pIuO",Je="verifyOTP-module__toggle___wbzVa";X(".verifyOTP-module__container___wgoDE{align-items:center;color:var(--seamless-text,#fff);display:flex;justify-content:center;padding:1rem}.verifyOTP-module__card___3cs2p{background-color:var(--seamless-surface,#1f2937);border-radius:.5rem;box-shadow:0 0 10px var(--seamless-shadow,rgba(0,0,0,.3));max-width:28rem;padding:1.5rem;width:100%}.verifyOTP-module__title___fZ-1d{color:var(--seamless-text,#fff);font-size:1.5rem;font-weight:700;margin-bottom:1rem;text-align:center}.verifyOTP-module__subtitle___dGSu3{color:var(--seamless-text-muted,#9ca3af);font-size:.875rem;margin-bottom:1.5rem;text-align:center}.verifyOTP-module__error___GEtlG{color:var(--seamless-danger,#f87171);margin-bottom:1rem;text-align:center}.verifyOTP-module__success___46TjG{color:var(--seamless-success,#34d399);margin-bottom:.75rem;text-align:center}.verifyOTP-module__form___jiGG-{display:flex;flex-direction:column;gap:1rem}.verifyOTP-module__label___Zq5Mi{color:var(--seamless-text-muted,#d1d5db);display:block;font-size:.875rem;margin-bottom:.25rem}.verifyOTP-module__timer___smq-a{color:var(--seamless-warning,#facc15);font-size:.875rem}.verifyOTP-module__input___yqIXM{background-color:var(--seamless-surface-raised,#374151);border:1px solid var(--seamless-border,#4b5563);border-radius:.375rem;color:var(--seamless-text,#fff);outline:none;padding:.5rem;width:100%}.verifyOTP-module__input___yqIXM:focus{box-shadow:0 0 0 2px var(--seamless-accent,#3b82f6)}.verifyOTP-module__resend___PlmkG{background:none;border:none;color:var(--seamless-accent-soft,#60a5fa);cursor:pointer;font-size:.75rem;margin-top:.25rem;text-decoration:underline}.verifyOTP-module__resend___PlmkG:hover{color:var(--seamless-accent,#3b82f6)}.verifyOTP-module__button___8pIuO{background-color:var(--seamless-accent,#2563eb);border:none;border-radius:.375rem;color:var(--seamless-accent-contrast,#fff);cursor:pointer;padding:.5rem;transition:background-color .2s;width:100%}.verifyOTP-module__button___8pIuO:hover{background-color:var(--seamless-accent-hover,#1d4ed8)}.verifyOTP-module__toggle___wbzVa{background:none;border:none;color:var(--seamless-accent-soft,#60a5fa);cursor:pointer;font-size:.875rem;margin-top:1.5rem;text-align:center;width:100%}");var He="otpInput-module__otpContainer___MUjby",Ze="otpInput-module__otpInput___3YMVm";X(".otpInput-module__otpContainer___MUjby{display:flex;gap:8px;justify-content:center;margin-top:8px}.otpInput-module__otpInput___3YMVm{background:var(--seamless-surface-raised,#374151);border:1px solid var(--seamless-border,#4b5563);border-radius:8px;color:var(--seamless-text,#fff);font-size:1.2rem;height:48px;text-align:center;transition:border-color .15s ease,box-shadow .15s ease;width:42px}.otpInput-module__otpInput___3YMVm:focus{border-color:var(--seamless-accent,#60a5fa);box-shadow:0 0 0 2px var(--seamless-accent,rgba(96,165,250,.25));outline:none}");const Qe=({length:e=6,value:o,inputMode:i="numeric",onChange:n,name:a="otp"})=>{const s=p([]),t=o.split("").concat(Array(e).fill("")).slice(0,e),l=(r,o)=>{const a=B(o,i).slice(0,e),l=[...t];a.forEach((o,i)=>{r+i<e&&(l[r+i]=o)}),n(l.join("")),s.current[Math.min(r+a.length,e-1)]?.focus()};return r("div",{className:He,role:"group","aria-label":"One-time password input",onPaste:e=>{e.preventDefault(),l(0,e.clipboardData.getData("text"))},children:t.map((o,c)=>r("input",{ref:e=>s.current[c]=e,type:"text",inputMode:"numeric"===i?"numeric":"text",autoComplete:"one-time-code",name:`${a}-${c}`,maxLength:1,value:o,className:Ze,onChange:e=>((e,r)=>{if(r.length>1)l(e,r);else if(!r||O(r,i)){const o=[...t];o[e]=r;const i=o.join("");n(i),r&&s.current[e+1]&&s.current[e+1]?.focus()}})(c,e.target.value),onKeyDown:r=>((r,o)=>{if("Backspace"===o.key){o.preventDefault();const e=[...t];t[r]?(e[r]="",n(e.join(""))):r>0&&(e[r-1]="",n(e.join("")),s.current[r-1]?.focus())}"ArrowLeft"===o.key&&r>0&&s.current[r-1]?.focus(),"ArrowRight"===o.key&&r<e-1&&s.current[r+1]?.focus()})(c,r),"aria-label":`Digit ${c+1}`},c))})},Xe=()=>{const o=n(),i=a(),{refreshSession:s}=d(),t="login"===i.state?.flow,[l,c]=g(""),[m,u]=g(null),[p,h]=g(""),[v,b]=g(!1),[y,k]=g(""),[x,w]=g(I),N=_(),P=async()=>{if(m)return;const{next:e,error:r}=await L({client:N,refreshSession:s},{channel:"phone",flow:t?"login":"register",code:l});if(null===r)return"verify_email"===e?(u(!0),void o(W)):void o("/");h(r)},M=async()=>{k(""),await(async()=>{h("");const{error:e}=await q(N,"phone",t?"login":"register");e?h(A("phone")):k("Verification SMS has been resent.")})(),k("Verification SMS has been resent.")};return f(()=>{const e=setInterval(()=>{w(e=>e>0?e-1:0)},1e3);return()=>clearInterval(e)},[]),r("div",{className:De,children:e("div",{className:Re,children:[r("h2",{className:Ee,children:"Verify Your Phone Number"}),r("p",{className:je,children:"Enter the code sent to your phone number."}),p&&r("p",{className:Fe,children:p}),y&&r("p",{className:Ge,children:y}),e("form",{onSubmit:async e=>{if(e.preventDefault(),h(""),l.length===z){b(!0);try{await P()}catch{h("Unexpected error occurred.")}finally{b(!1)}}else h("Please enter a valid code.")},className:Ve,children:[e("div",{children:[e("label",{htmlFor:"phoneCode",className:Ue,children:["Phone Verification Code ",(T=m,!0===T?r("span",{className:"text-green-400 ml-2",children:"✅"}):!1===T?r("span",{className:"text-red-400 ml-2",children:"❌"}):null)," -"," ",e("span",{className:Ke,children:["Code expires in: ",S(x)]})]}),r(Qe,{length:6,value:l,onChange:c}),r("button",{type:"button",onClick:()=>M(),className:Ye,children:"Resend code to phone"})]}),r("button",{type:"submit",className:We,children:v?"Verifying...":"Verify & Continue"}),r("button",{type:"button",onClick:()=>o("/login"),className:Je,children:"Back to login"})]})]})});var T},$e=()=>{const o=n(),i=a(),{refreshSession:s}=d(),t=_(),{passkeySupported:l}=m(),c="login"===i.state?.flow,[u,p]=g(!1),[h,v]=g(""),[b,y]=g(I),[k,x]=g(""),[w,N]=g("");return f(()=>{const e=setInterval(()=>{y(e=>e>0?e-1:0)},1e3);return()=>clearInterval(e)},[]),r("div",{className:De,children:e("div",{className:Re,children:[r("h2",{className:Ee,children:"Verify Your Email"}),r("p",{className:je,children:"We sent you a verification email. Enter the code below."}),k&&r("p",{className:Fe,children:k}),w&&r("p",{className:Ge,children:w}),e("form",{onSubmit:async e=>{if(e.preventDefault(),x(""),h.length===z){p(!0);try{const{next:e,error:r}=await L({client:t,refreshSession:s},{channel:"email",flow:c?"login":"register",code:h,passkeySupported:l});if(null!==r)return void x(r);o("register_passkey"===e?Z:"/")}catch{console.error("Email OTP verification failed."),x("Verification failed.")}finally{p(!1)}}else x("Please enter a valid code.")},className:Ve,children:[e("div",{children:[e("label",{htmlFor:"emailCode",className:Ue,children:["Email Verification Code",e("span",{className:Ke,children:[" ","— Code expires in ",S(b)]})]}),r(Qe,{length:6,value:h,onChange:v,inputMode:"text"}),r("button",{type:"button",onClick:async()=>{x(""),N("");const{error:e}=await q(t,"email",c?"login":"register");e?x(A("email")):N("Verification email has been resent.")},className:Ye,children:"Resend code to email"})]}),r("button",{type:"submit",className:We,disabled:u,children:u?"Verifying...":"Verify & Continue"}),r("button",{type:"button",onClick:()=>o("/login"),className:Je,children:"Back to login"})]})]})})};var er="verifyMagiclink-module__container___qrSXf",rr="verifyMagiclink-module__card___niKgr",or="verifyMagiclink-module__title___SumxD",ir="verifyMagiclink-module__verificationContent___NdsS0",nr="verifyMagiclink-module__spinner___lnW1k",ar="verifyMagiclink-module__successIcon___XjFEM",sr="verifyMagiclink-module__checkIcon___I0JOP",tr="verifyMagiclink-module__prompt___tvPn4",lr="verifyMagiclink-module__helperText___ggTZw",cr="verifyMagiclink-module__actions___6Jf29",dr="verifyMagiclink-module__primaryButton___8DcTo",_r="verifyMagiclink-module__secondaryButton___8n-GU",mr="verifyMagiclink-module__error___tfBn0",ur="verifyMagiclink-module__successText___lO5Qq";X(".verifyMagiclink-module__container___qrSXf{align-items:center;color:var(--seamless-text,#fff);display:flex;justify-content:center;padding:1rem}.verifyMagiclink-module__card___niKgr{background-color:var(--seamless-surface,#1f2937);border-radius:.5rem;box-shadow:0 0 10px var(--seamless-shadow,rgba(0,0,0,.3));max-width:28rem;padding:1.5rem;width:100%}.verifyMagiclink-module__title___SumxD{color:var(--seamless-text,#fff);font-size:1.5rem;font-weight:700;margin-bottom:1rem;text-align:center}.verifyMagiclink-module__verificationContent___NdsS0{align-items:center;display:flex;flex-direction:column;gap:14px;margin:20px 0}.verifyMagiclink-module__spinner___lnW1k{animation:verifyMagiclink-module__spin___2lGzj .9s linear infinite;border:3px solid var(--seamless-border,hsla(0,0%,100%,.15));border-radius:50%;border-top-color:var(--seamless-accent,#60a5fa);height:28px;width:28px}.verifyMagiclink-module__successIcon___XjFEM{align-items:center;background:rgba(16,185,129,.15);border-radius:50%;display:flex;height:36px;justify-content:center;width:36px}.verifyMagiclink-module__checkIcon___I0JOP{animation:verifyMagiclink-module__checkPop___-3qJu .25s ease-out;color:var(--seamless-success,#34d399);height:22px;width:22px}.verifyMagiclink-module__prompt___tvPn4{font-weight:600;line-height:1.4;text-align:center}.verifyMagiclink-module__helperText___ggTZw{color:var(--seamless-text-muted,#9ca3af);font-size:.875rem;line-height:1.4;text-align:center}.verifyMagiclink-module__actions___6Jf29{display:flex;flex-direction:column;gap:.6rem;width:100%}.verifyMagiclink-module__primaryButton___8DcTo{background-color:var(--seamless-accent,#2563eb);border:none;border-radius:.375rem;color:var(--seamless-accent-contrast,#fff);cursor:pointer;font:inherit;font-weight:500;padding:.65rem;width:100%}.verifyMagiclink-module__primaryButton___8DcTo:hover:not(:disabled){background-color:var(--seamless-accent-hover,#1d4ed8)}.verifyMagiclink-module__secondaryButton___8n-GU{background:transparent;border:1px solid var(--seamless-border,#374151);border-radius:.375rem;color:var(--seamless-text,#fff);cursor:pointer;font:inherit;padding:.65rem;width:100%}.verifyMagiclink-module__secondaryButton___8n-GU:hover:not(:disabled){background:var(--seamless-surface-hover,#1f2937)}.verifyMagiclink-module__primaryButton___8DcTo:disabled,.verifyMagiclink-module__secondaryButton___8n-GU:disabled{cursor:not-allowed;opacity:.6}.verifyMagiclink-module__error___tfBn0{color:var(--seamless-danger,#f87171);text-align:center}.verifyMagiclink-module__successText___lO5Qq{color:var(--seamless-success,#34d399);font-size:.9rem}@keyframes verifyMagiclink-module__checkPop___-3qJu{0%{opacity:0;transform:scale(.6)}80%{transform:scale(1.15)}to{opacity:1;transform:scale(1)}}@keyframes verifyMagiclink-module__spin___2lGzj{to{transform:rotate(1turn)}}");const gr=()=>{const[i]=s(),a=n(),t=i.get("token"),[l,c]=g(""),[m,u]=g(null),[h,v]=g(null),[b,y]=g("pending"),[k,x]=g(""),w=_(),{refreshSession:N}=d(),P=p(null);f(()=>{let e=!0,r=null;return(async()=>{if(!t)return e&&c("Missing token for verification."),void console.error("No magic-link token found.");P.current?.token!==t&&(P.current={token:t,result:w.verifyMagicLink(t)});const{error:o}=await P.current.result;if(!e)return;if(o){const e=R(o);return e?void v(e):(console.error("Failed to verify token"),void c("Failed to verify token"))}const i=await E({client:w,refreshSession:N});e&&(u(i),"elsewhere"!==i&&(r=setTimeout(()=>{e&&a("/")},900)))})(),()=>{e=!1,r&&clearTimeout(r)}},[t,w,a,N]);return r("div",h?{className:er,children:e("div",{className:rr,children:[r("h1",{className:or,children:"Confirm this sign-in"}),e("div",{className:ir,children:[("pending"===b||"confirming"===b)&&e(o,{children:[r("p",{className:tr,children:D(h)}),r("p",{className:lr,children:"This link was opened on a different device from the one that asked for it. Only continue if you made that request."}),e("div",{className:cr,children:[r("button",{type:"button",className:dr,disabled:"confirming"===b,onClick:()=>{(async()=>{if(!t||"confirming"===b)return;y("confirming"),x("");const{error:e}=await j({client:w,token:t});if(e)return y("pending"),void x("We could not confirm this sign-in. The link may have expired or already been used.");y("confirmed")})()},children:"Yes, sign in that device"}),r("button",{type:"button",className:_r,disabled:"confirming"===b,onClick:()=>y("declined"),children:"No, this wasn't me"})]}),k&&r("p",{className:mr,role:"alert",children:k})]}),"confirmed"===b&&r("p",{className:ur,role:"status",children:"Sign-in approved. You can return to your other device to continue."}),"declined"===b&&r("p",{className:lr,role:"status",children:"No one has been signed in. You can ignore the email and close this page."})]})]})}:{className:er,children:e("div",{className:rr,children:[r("h1",{className:or,children:"Verifying your login"}),e("div",{className:ir,children:[!m&&!l&&r("div",{className:nr}),m&&r("div",{className:ar,children:r("svg",{viewBox:"0 0 24 24",className:sr,fill:"none",stroke:"currentColor",strokeWidth:"2",children:r("path",{d:"M5 13l4 4L19 7"})})}),!m&&!l&&r("p",{className:lr,children:"Please wait while we securely verify your sign-in link."}),"signed-in"===m&&r("p",{className:ur,children:"Login verified. Redirecting…"}),"elsewhere"===m&&r("p",{className:ur,children:"Login verified. Return to the device where you requested this link to continue."}),l&&r("p",{className:mr,children:l})]})]})})},fr=()=>{const{finishOAuthLogin:i}=d(),a=n(),[t]=s(),[l,c]=g(""),_=p(!1);return f(()=>{_.current||(_.current=!0,F({finishOAuthLogin:i},t,window.location.origin).then(e=>{"error"!==e.kind?"enroll_passkey"!==e.kind?a(e.destination):a(Z,{state:{returnTo:e.returnTo}}):c(e.message)}))},[i,a,t]),e("div",{className:er,children:[r("h2",{className:or,children:l?"Sign-in failed":"Completing sign-in..."}),l&&e(o,{children:[r("p",{children:l}),r("button",{type:"button",onClick:()=>a("/login"),children:"Back to login"})]})]})};var pr="magiclink-module__container___45zcA",hr="magiclink-module__card___Au9oN",vr="magiclink-module__iconWrapper___k5ndr",br="magiclink-module__mailIcon___Pwb7q",yr="magiclink-module__iconRing___bdLvf",kr="magiclink-module__heading___b9cre",xr="magiclink-module__message___kiVFj",wr="magiclink-module__identifier___JtcFM",Nr="magiclink-module__helperText___7Mlfh",Pr="magiclink-module__actions___64I-3",Mr="magiclink-module__secondaryButton___BntAI",Tr="magiclink-module__cooldown___Ib4rm",Cr="magiclink-module__linkButton___maJiv";X(".magiclink-module__container___45zcA{align-items:center;color:var(--seamless-text,#fff);display:flex;justify-content:center}.magiclink-module__card___Au9oN{background-color:var(--seamless-surface,#1f2937);border-radius:.75rem;box-shadow:0 10px 25px var(--seamless-shadow,rgba(0,0,0,.25));max-width:420px;padding:2.5rem 2rem;text-align:center;width:100%}.magiclink-module__iconWrapper___k5ndr{display:flex;justify-content:center;margin-bottom:1.25rem;position:relative}.magiclink-module__mailIcon___Pwb7q{color:var(--seamless-accent-soft,#a5b4fc);height:38px;width:38px;z-index:2}.magiclink-module__iconRing___bdLvf{animation:magiclink-module__pulse___YGm-I 2s infinite;background:rgba(99,102,241,.15);border-radius:50%;height:72px;position:absolute;width:72px}@keyframes magiclink-module__pulse___YGm-I{0%{opacity:.8;transform:scale(.6)}70%{opacity:0;transform:scale(1.4)}to{opacity:0}}.magiclink-module__heading___b9cre{font-size:1.55rem;font-weight:600;margin-bottom:.75rem}.magiclink-module__message___kiVFj{color:var(--seamless-text-muted,#d1d5db);font-size:.95rem;line-height:1.4;margin-bottom:1rem}.magiclink-module__identifier___JtcFM{background:var(--seamless-surface-raised,hsla(0,0%,100%,.05));border-radius:6px;display:inline-block;font-size:1rem;font-weight:600;margin-bottom:1rem;padding:.45rem .6rem}.magiclink-module__helperText___7Mlfh{color:var(--seamless-text-muted,#9ca3af);font-size:.85rem;line-height:1.4;margin-bottom:.6rem}.magiclink-module__actions___64I-3{display:flex;flex-direction:column;gap:.6rem;margin-top:1.6rem}.magiclink-module__secondaryButton___BntAI{background:var(--seamless-surface,#111827);border:1px solid var(--seamless-border,#374151);border-radius:8px;color:var(--seamless-text,#fff);cursor:pointer;font-weight:500;padding:.65rem}.magiclink-module__secondaryButton___BntAI:hover:not(:disabled){background:var(--seamless-surface-hover,#1f2937)}.magiclink-module__secondaryButton___BntAI:disabled{cursor:not-allowed;opacity:.5}.magiclink-module__cooldown___Ib4rm{color:var(--seamless-text-muted,#9ca3af);font-size:.8rem}.magiclink-module__linkButton___maJiv{background:none;border:none;color:var(--seamless-accent-soft,#a5b4fc);cursor:pointer;font-size:.85rem;margin-top:.4rem}.magiclink-module__linkButton___maJiv:hover{text-decoration:underline}");const Or=()=>{const{refreshSession:o}=d(),i=n(),s=a(),t=_(),l=s.state?.identifier,[c,m]=g(G);f(()=>{const e=setInterval(()=>{m(e=>e>0?e-1:0)},1e3);return()=>clearInterval(e)},[]);return f(()=>V({client:t,refreshSession:o,onSignedIn:()=>i("/")}),[t,i,o]),r("div",{className:pr,children:e("div",{className:hr,children:[e("div",{className:vr,children:[r("div",{className:yr}),e("svg",{className:br,viewBox:"0 0 24 24",fill:"none",stroke:"currentColor",strokeWidth:"1.8",children:[r("path",{d:"M4 6h16v12H4z"}),r("path",{d:"m4 6 8 6 8-6"})]})]}),r("h2",{className:kr,children:"Check your email"}),r("p",{className:xr,children:"If an account exists for this address, we sent a secure sign-in link."}),l&&r("div",{className:wr,children:l}),r("p",{className:Nr,children:"Open the email and click the link to finish signing in."}),r("p",{className:Nr,children:"Didn’t receive anything? Check your spam folder or try creating a new account."}),e("div",{className:Pr,children:[r("button",{className:Mr,disabled:c>0,onClick:async()=>{c>0||(await t.requestMagicLink(),m(G))},children:"Resend link"}),c>0&&e("div",{className:Tr,children:["Available in ",c,"s"]}),r("button",{className:Cr,onClick:()=>i("/login"),children:"Change email or phone"})]})]})})},Br=()=>e(t,{children:[r(l,{path:U,element:r(ye,{})}),r(l,{path:K,element:r(xe,{})}),r(l,{path:Y,element:r(Xe,{})}),r(l,{path:W,element:r($e,{})}),r(l,{path:J,element:r(gr,{})}),r(l,{path:H,element:r(fr,{})}),r(l,{path:Z,element:r(Ae,{})}),r(l,{path:Q,element:r(Or,{})}),r(l,{path:"*",element:r(c,{to:U,replace:!0})})]});export{Br as AuthRoutes};
|
|
2
|
+
import{jsxs as e,jsx as r,Fragment as o}from"react/jsx-runtime";import{useHref as i,useNavigate as n,useLocation as a,useSearchParams as s,Routes as t,Route as l,Navigate as c}from"react-router-dom";import{u as d,a as _,c as m,b as u}from"./chunks/shared-D9GCCBrm.js";import{useState as g,useEffect as f,useRef as p}from"react";import{fallbackSignInOptions as h,hasFallbackSignInOption as v,OAUTH_CALLBACK_PATH as b,startOAuthSignIn as y,isValidEmail as k,isValidPhoneNumber as x,beginSignIn as w,PASSKEY_SIGN_IN_FAILED as N,registerWithEmail as P,safeReturnPath as M,hasNonPasskeyLoginMethod as T,enrollPasskey as C,isOtpCharacter as O,otpCharacters as B,OTP_LIFETIME_SECONDS as I,formatCountdown as S,OTP_LENGTH as z,verifyOtp as L,requestOtp as q,otpResendFailedMessage as A,magicLinkConfirmationPrompt as D,getMagicLinkConfirmation as R,finishMagicLinkSignIn as E,confirmMagicLinkSignIn as j,completeOAuthCallback as F,MAGIC_LINK_RESEND_COOLDOWN_SECONDS as G,watchMagicLink as V}from"@seamless-auth/client";const U="/login",K="/passkey-login",Y="/verify-phone-otp",W="/verify-email-otp",J="/verify-magiclink",H="/oauth/callback",Z="/register-passkey",Q="/magic-link-sent";function X(e,r){void 0===r&&(r={});var o=r.insertAt;if(e&&"undefined"!=typeof document){var i=document.head||document.getElementsByTagName("head")[0],n=document.createElement("style");n.type="text/css","top"===o&&i.firstChild?i.insertBefore(n,i.firstChild):i.appendChild(n),n.styleSheet?n.styleSheet.cssText=e:n.appendChild(document.createTextNode(e))}}var $="login-module__container___YggDx",ee="login-module__card___Ub-Py",re="login-module__heading___neEqb",oe="login-module__inputGroup___P6qgS",ie="login-module__label___mx5vu",ne="login-module__input___U07lW",ae="login-module__helperText___kDQ4-",se="login-module__error___40zxh",te="login-module__button___0kFBs",le="login-module__submitHint___qOS5Z",ce="login-module__toggle___1JiG1",de="login-module__fallbackCard___HdIk-",_e="login-module__fallbackHeader___-il2v",me="login-module__fallbackDescription___ea5EB",ue="login-module__fallbackActions___AD3ni",ge="login-module__fallbackActionButton___lFgWf",fe="login-module__actionTitle___ycrMp",pe="login-module__actionSubtext___opaIV",he="login-module__linkButton___5lsoe";X(".login-module__container___YggDx{align-items:center;color:var(--seamless-text,#fff);display:flex;justify-content:center}.login-module__card___Ub-Py{background-color:var(--seamless-surface,#1f2937);border-radius:.5rem;box-shadow:0 4px 6px var(--seamless-shadow,rgba(0,0,0,.1));max-width:28rem;padding:2rem;width:100%}.login-module__heading___neEqb{color:var(--seamless-text,#fff);font-size:1.5rem;font-weight:700;margin-bottom:1.5rem;text-align:center}.login-module__message___qSejT{color:var(--seamless-success,#68d391);text-align:center}.login-module__inputGroup___P6qgS{margin-bottom:1rem}.login-module__label___mx5vu{color:var(--seamless-text-muted,#d1d5db);display:block}.login-module__input___U07lW{background-color:var(--seamless-surface-raised,#4b5563);border:1px solid var(--seamless-border,#d1d5db);border-radius:.375rem;margin-top:.25rem;padding:.5rem;width:100%}.login-module__input___U07lW:focus{box-shadow:0 0 0 2px var(--seamless-accent,#3b82f6);outline:none}.login-module__helperText___kDQ4-{color:var(--seamless-text-muted,#9ca3af);font-size:.75rem;margin-top:.5rem}.login-module__error___40zxh{color:var(--seamless-danger,#f87171);font-size:.875rem}.login-module__button___0kFBs{background-color:var(--seamless-accent,#2563eb);border-radius:.375rem;color:var(--seamless-accent-contrast,#fff);cursor:pointer;margin-top:1rem;padding:.5rem;transition:background-color .3s,opacity .3s;width:100%}.login-module__button___0kFBs:hover:not(:disabled){background-color:var(--seamless-accent-hover,#1d4ed8)}.login-module__button___0kFBs:disabled{cursor:not-allowed;opacity:.6}.login-module__submitHint___qOS5Z{color:var(--seamless-text-muted,#9ca3af);font-size:.75rem;margin-top:.5rem;text-align:center}.login-module__toggle___1JiG1{background:none;border:none;color:var(--seamless-accent-soft,#60a5fa);cursor:pointer;font-size:.875rem;margin-top:1.5rem;text-align:center;width:100%}.login-module__underline___gs-RS{text-decoration:underline}.login-module__phoneRow___oeNtq{display:grid;gap:.5rem;grid-template-columns:1fr 3fr;margin-top:.25rem}.login-module__phoneInput___2MPQC,.login-module__select___rRV1O{background-color:var(--seamless-surface-raised,#4b5563);border:1px solid var(--seamless-border,#d1d5db);border-radius:.375rem;padding:.5rem;width:100%}@media (max-width:500px){.login-module__phoneRow___oeNtq{grid-template-columns:1fr}}.login-module__fallbackCard___HdIk-{background:var(--seamless-surface-raised,hsla(0,0%,100%,.04));border:1px solid var(--seamless-border,hsla(0,0%,100%,.08));border-radius:12px;display:flex;flex-direction:column;gap:14px;margin-top:18px;padding:18px}.login-module__fallbackHeader___-il2v{color:var(--seamless-text,#f3f4f6);font-size:.95rem;font-weight:600}.login-module__fallbackDescription___ea5EB{color:var(--seamless-text-muted,#9ca3af);font-size:.85rem;line-height:1.4}.login-module__fallbackActions___AD3ni{display:flex;flex-direction:column;gap:10px}.login-module__fallbackActionButton___lFgWf{background:var(--seamless-surface,rgba(0,0,0,.25));border:1px solid var(--seamless-border,hsla(0,0%,100%,.08));border-radius:8px;cursor:pointer;display:flex;flex-direction:column;padding:12px 14px;text-align:left;transition:all .15s ease}.login-module__fallbackActionButton___lFgWf:hover{background:var(--seamless-surface-hover,hsla(0,0%,100%,.06));border-color:var(--seamless-border,hsla(0,0%,100%,.15))}.login-module__actionTitle___ycrMp{color:var(--seamless-text,#f9fafb);font-size:.9rem;font-weight:500}.login-module__actionSubtext___opaIV{color:var(--seamless-text-muted,#9ca3af);font-size:.75rem;margin-top:2px}.login-module__linkButton___5lsoe{background:none;border:none;color:var(--seamless-accent-soft,#60a5fa);cursor:pointer;font-size:.8rem;margin-top:6px}.login-module__linkButton___5lsoe:hover{text-decoration:underline}");const ve=({identifier:o,onMagicLink:i,onEmailOtp:n,onPhoneOtp:a,onPasskeyRetry:s,loginMethods:t})=>{const l=h(o,t,{emailOtp:Boolean(n),passkeyRetry:Boolean(s)});return v(l)?e("div",{className:de,children:[r("div",{className:_e,children:"Choose a sign-in method"}),r("p",{className:me,children:"Choose another secure sign-in method."}),e("div",{className:ue,children:[l.magicLink&&e("button",{type:"button",className:ge,onClick:i,children:[r("span",{className:fe,children:"Email Magic Link"}),r("span",{className:pe,children:"Send a secure sign-in link to your email"})]}),l.emailOtp&&e("button",{type:"button",className:ge,onClick:n,children:[r("span",{className:fe,children:"Email Code"}),r("span",{className:pe,children:"Receive a one-time code by email"})]}),l.phoneOtp&&e("button",{type:"button",className:ge,onClick:a,children:[r("span",{className:fe,children:"Text Message Code"}),r("span",{className:pe,children:"Receive a one-time code via SMS"})]})]}),l.passkeyRetry&&r("button",{type:"button",className:he,onClick:s,children:"Try passkey anyway"})]}):null},be=()=>{const{listOAuthProviders:o,startOAuthLogin:n,finishOAuthLogin:a,ports:s}=d(),t=i(b),[l,c]=g([]),[_,m]=g("");if(f(()=>{let e=!0;return o().then(({data:r})=>{e&&c(r?.providers??[])}),()=>{e=!1}},[o]),0===l.length)return null;return e("div",{className:ue,children:[l.map(o=>r("button",{type:"button",className:ge,onClick:()=>(async e=>{m("");const r=new URL(t,window.location.origin).toString(),{error:o}=await y({actions:{startOAuthLogin:n,finishOAuthLogin:a},oauthRedirect:s.oauthRedirect},{providerId:e,redirectUri:r});o&&m(o)})(o.id),children:e("span",{className:fe,children:["Continue with ",o.name]})},o.id)),_&&r("p",{className:se,children:_})]})},ye=()=>{const i=n(),{hasSignedInBefore:a,login:s,handlePasskeyLogin:t}=d(),l=_(),{passkeySupported:c}=m(),{loginMethods:p}=u(),[h,v]=g(""),[b,y]=g(""),[M,T]=g("register"),[C,O]=g(""),[B,I]=g(""),[S,z]=g(""),[L,q]=g(!1),[A,D]=g(null);f(()=>{a&&T("login")},[a]);const R=()=>"login"===M?k(h)||x(h):k(b);return r("div",{className:$,children:e("div",{className:ee,children:[r("h2",{className:re,children:"login"===M?"Sign In":"Create Account"}),e(o,{children:[e("form",{onSubmit:async e=>{e.preventDefault(),O(""),q(!1);try{if("login"===M){const e=await w({login:s,handlePasskeyLogin:t},{identifier:h,passkeySupported:c,configuredMethods:p});return"error"===e.kind?void O(e.message):"signed_in"===e.kind?void i("/"):(D(e.loginMethods),q(!0),void(e.passkeyFailed&&O(N)))}"register"===M&&await(async()=>{O("");const{error:e}=await P(l,b);e?O(e):i(W)})()}catch{console.error("Failed to continue sign-in."),O("Failed to continue sign-in. Please try again.")}},children:["login"===M&&e("div",{className:oe,children:[r("label",{htmlFor:"identifier",className:ie,children:"Email Address / Phone Number"}),r("input",{id:"identifier",type:"text",value:h,onChange:e=>{const r=e.target.value;v(r)},autoComplete:"off",placeholder:"Email or Phone Number",className:ne,onBlur:()=>{if(h){const e=k(h)||x(h);z(e?"":"Please enter a valid email or phone number")}},required:!0}),r("p",{className:ae,children:"Phone numbers must include a country code e.g. +1"}),L&&r(ve,{identifier:h,onMagicLink:async()=>{const{error:e}=await l.requestMagicLink();e?O("Failed to send magic link."):i(Q,{state:{identifier:h}})},onEmailOtp:async()=>{const{error:e}=await l.requestLoginEmailOtp();e?O("Failed to send email code."):i(W,{state:{flow:"login"}})},onPhoneOtp:async()=>{const{error:e}=await l.requestLoginPhoneOtp();e?O("Failed to send OTP."):i(Y,{state:{flow:"login"}})},onPasskeyRetry:c?t:void 0,loginMethods:A}),S&&r("p",{className:se,children:S})]}),"register"===M&&e("div",{className:oe,children:[r("label",{htmlFor:"email",className:ie,children:"Email Address"}),r("input",{id:"email",type:"email",value:b,onChange:e=>{const r=e.target.value;y(r)},autoComplete:"off",className:ne,onBlur:()=>{if(b){const e=k(b);I(e?"":"Please enter a valid email")}},required:!0}),B&&r("p",{className:se,children:B})]}),r("button",{type:"submit",className:te,disabled:!R(),"aria-describedby":"seamless-submit-hint",children:"login"===M?"Login":"Register"}),r("p",{id:"seamless-submit-hint",role:"status",className:le,children:"login"===M?h?R()?"Ready to continue.":"This does not look like a complete email or phone number yet.":"Enter your email or phone number to continue.":b?R()?"Ready to continue.":"This does not look like a complete email address yet.":"Enter your email address to continue."}),C&&r("p",{className:se,children:C}),r("button",{type:"button",onClick:()=>T("login"===M?"register":"login"),className:ce,children:"login"===M?"Don't have an account? Create one":"Already have an account? Sign in"})]}),r(be,{})]})]})})};var ke={container:"passKeyLogin-module__container___IUKxF",card:"passKeyLogin-module__card___2sKM1",title:"passKeyLogin-module__title___HZxvc",button:"passKeyLogin-module__button___FvR4I"};X(".passKeyLogin-module__container___IUKxF{align-items:center;color:var(--seamless-text,#fff);display:flex;justify-content:center;padding:1rem}.passKeyLogin-module__card___2sKM1{background-color:var(--seamless-surface,#1f2937);border-radius:1rem;box-shadow:0 4px 20px var(--seamless-shadow,rgba(0,0,0,.4));display:flex;flex-direction:column;gap:1.5rem;max-width:400px;padding:2rem;width:100%}.passKeyLogin-module__title___HZxvc{color:var(--seamless-text,#fff);font-size:1.5rem;font-weight:600;text-align:center}.passKeyLogin-module__button___FvR4I{background-color:var(--seamless-accent,#2563eb);border:1px solid var(--seamless-accent,#3b82f6);border-radius:.5rem;color:var(--seamless-accent-contrast,#fff);cursor:pointer;font-weight:500;padding:.75rem 1rem;text-align:center;transition:background-color .2s ease;width:100%}.passKeyLogin-module__button___FvR4I:hover{background-color:var(--seamless-accent-hover,#1d4ed8)}@media (max-width:480px){.passKeyLogin-module__card___2sKM1{padding:1.25rem}.passKeyLogin-module__button___FvR4I{font-size:1rem}}");const xe=()=>{const o=n(),{handlePasskeyLogin:i}=d(),[a,s]=g("");return r("div",{className:ke.container,children:e("div",{className:ke.card,children:[r("h2",{className:ke.title,children:"Login with Passkey"}),r("button",{onClick:async()=>{s("");const{error:e}=await i();e?s("Passkey sign-in could not be completed. Try another sign-in method."):o("/")},className:ke.button,children:"Use Passkey"}),a&&r("p",{className:ke.error,children:a})]})})};var we="registerPasskey-module__container___jqEh8",Ne="registerPasskey-module__card___MJAyC",Pe="registerPasskey-module__loading___Q4i1x",Me="registerPasskey-module__spinner___V1nhd",Te="registerPasskey-module__supported___ihTih",Ce="registerPasskey-module__title___vn2Qu",Oe="registerPasskey-module__description___AWmO-",Be="registerPasskey-module__button___D3b4B",Ie="registerPasskey-module__message___RiOw-",Se="registerPasskey-module__success___HP5aX",ze="registerPasskey-module__error___hGiqE",Le="registerPasskey-module__skip___1hDyU",qe="registerPasskey-module__secondary___bnOB4";X(".registerPasskey-module__container___jqEh8{align-items:center;color:var(--seamless-text,#fff);display:flex;justify-content:center;padding:1rem}.registerPasskey-module__card___MJAyC{background-color:var(--seamless-surface,#1f2937);border-radius:1rem;box-shadow:0 4px 20px var(--seamless-shadow,rgba(0,0,0,.4));max-width:400px;padding:1.5rem;width:100%}.registerPasskey-module__loading___Q4i1x{align-items:center;background-color:var(--seamless-surface,#f9fafb);border-radius:.75rem;box-shadow:0 2px 8px var(--seamless-shadow,rgba(0,0,0,.1));color:var(--seamless-text,#374151);display:flex;font-weight:500;gap:.75rem;justify-content:center;padding:1.5rem}.registerPasskey-module__spinner___V1nhd{animation:registerPasskey-module__spin___oYcsC 1s linear infinite;border-bottom:2px solid var(--seamless-accent,#3b82f6);border-left:2px solid transparent;border-radius:9999px;border-right:2px solid transparent;border-top:2px solid var(--seamless-accent,#3b82f6);height:1.5rem;width:1.5rem}@keyframes registerPasskey-module__spin___oYcsC{to{transform:rotate(1turn)}}.registerPasskey-module__supported___ihTih{background-color:var(--seamless-surface,#ecfdf5);border-radius:.75rem;box-shadow:0 2px 12px var(--seamless-shadow,rgba(0,0,0,.1));color:var(--seamless-text,#065f46);padding:1.25rem}.registerPasskey-module__title___vn2Qu{font-size:1.125rem;font-weight:600;margin-bottom:.5rem}.registerPasskey-module__description___AWmO-{margin-bottom:1rem}.registerPasskey-module__button___D3b4B{background-color:var(--seamless-accent,#059669);border:none;border-radius:.5rem;color:var(--seamless-accent-contrast,#fff);cursor:pointer;font-weight:500;padding:.75rem 1rem;transition:background-color .2s ease;width:100%}.registerPasskey-module__button___D3b4B:hover{background-color:var(--seamless-accent-hover,#047857)}.registerPasskey-module__message___RiOw-{font-size:.875rem;margin-top:1rem}.registerPasskey-module__success___HP5aX{color:var(--seamless-success,#6ee7b7)}.registerPasskey-module__error___hGiqE{color:var(--seamless-danger,#f87171)}.registerPasskey-module__skip___1hDyU{background:none;border:none;color:var(--seamless-accent-soft,#60a5fa);cursor:pointer;font-size:.875rem;margin-top:1.5rem;text-align:center;width:100%}.registerPasskey-module__skip___1hDyU:disabled{cursor:default;opacity:.6}.registerPasskey-module__secondary___bnOB4{background:none;border:1px solid var(--seamless-accent,#059669);border-radius:.5rem;color:var(--seamless-accent,#059669);cursor:pointer;font-weight:500;margin-top:.75rem;padding:.75rem 1rem;transition:background-color .2s ease;width:100%}.registerPasskey-module__secondary___bnOB4:hover:not(:disabled){background-color:var(--seamless-accent-muted,rgba(5,150,105,.1))}.registerPasskey-module__secondary___bnOB4:disabled{cursor:default;opacity:.6}");const Ae=()=>{const{refreshSession:o}=d(),i=_(),{passkeySupported:s,loading:t}=m(),{loginMethods:l,loading:c}=u(),f=n(),p=M(a().state?.returnTo),[h,v]=g("idle"),[b,y]=g(""),k=T(l),x=async()=>{await o(),f(p)},w=async e=>{v("loading");const{error:r}=await C({client:i,refreshSession:o},e);if(r)return v("error"),void y(r);v("success"),y("Passkey registered successfully."),f(p)};return r("div",{className:we,children:r("div",{className:Ne,children:e("div",t||c?{className:Pe,children:[r("div",{className:Me}),r("span",{children:"Checking for Passkey Support..."})]}:s?{className:Te,children:[r("h2",{className:Ce,children:"Secure Your Account with a Passkey"}),r("p",{className:Oe,children:"Your device supports passkeys! Register one to skip passwords forever."}),r("button",{onClick:()=>w(),disabled:"loading"===h,className:Be,children:"loading"===h?"Registering...":"Register Passkey"}),r("button",{type:"button",onClick:()=>w("cross-platform"),disabled:"loading"===h,className:qe,children:"Use a security key instead"}),b&&r("p",{className:`${Ie} ${"success"===h?Se:ze}`,children:b}),k&&r("button",{type:"button",onClick:x,disabled:"loading"===h,className:Le,children:"Skip for now"})]}:{className:Te,children:[r("h2",{className:Ce,children:"Passkeys are not available here"}),r("p",{className:Oe,children:k?"This device does not support passkeys. You can continue without one and add a passkey later from a device that does.":"This device does not support passkeys, and this application requires one to sign in. Try again from a device or browser that supports them."}),k&&r("button",{type:"button",onClick:x,className:Be,children:"Continue"})]})})})};var De="verifyOTP-module__container___wgoDE",Re="verifyOTP-module__card___3cs2p",Ee="verifyOTP-module__title___fZ-1d",je="verifyOTP-module__subtitle___dGSu3",Fe="verifyOTP-module__error___GEtlG",Ge="verifyOTP-module__success___46TjG",Ve="verifyOTP-module__form___jiGG-",Ue="verifyOTP-module__label___Zq5Mi",Ke="verifyOTP-module__timer___smq-a",Ye="verifyOTP-module__resend___PlmkG",We="verifyOTP-module__button___8pIuO",Je="verifyOTP-module__toggle___wbzVa";X(".verifyOTP-module__container___wgoDE{align-items:center;color:var(--seamless-text,#fff);display:flex;justify-content:center;padding:1rem}.verifyOTP-module__card___3cs2p{background-color:var(--seamless-surface,#1f2937);border-radius:.5rem;box-shadow:0 0 10px var(--seamless-shadow,rgba(0,0,0,.3));max-width:28rem;padding:1.5rem;width:100%}.verifyOTP-module__title___fZ-1d{color:var(--seamless-text,#fff);font-size:1.5rem;font-weight:700;margin-bottom:1rem;text-align:center}.verifyOTP-module__subtitle___dGSu3{color:var(--seamless-text-muted,#9ca3af);font-size:.875rem;margin-bottom:1.5rem;text-align:center}.verifyOTP-module__error___GEtlG{color:var(--seamless-danger,#f87171);margin-bottom:1rem;text-align:center}.verifyOTP-module__success___46TjG{color:var(--seamless-success,#34d399);margin-bottom:.75rem;text-align:center}.verifyOTP-module__form___jiGG-{display:flex;flex-direction:column;gap:1rem}.verifyOTP-module__label___Zq5Mi{color:var(--seamless-text-muted,#d1d5db);display:block;font-size:.875rem;margin-bottom:.25rem}.verifyOTP-module__timer___smq-a{color:var(--seamless-warning,#facc15);font-size:.875rem}.verifyOTP-module__input___yqIXM{background-color:var(--seamless-surface-raised,#374151);border:1px solid var(--seamless-border,#4b5563);border-radius:.375rem;color:var(--seamless-text,#fff);outline:none;padding:.5rem;width:100%}.verifyOTP-module__input___yqIXM:focus{box-shadow:0 0 0 2px var(--seamless-accent,#3b82f6)}.verifyOTP-module__resend___PlmkG{background:none;border:none;color:var(--seamless-accent-soft,#60a5fa);cursor:pointer;font-size:.75rem;margin-top:.25rem;text-decoration:underline}.verifyOTP-module__resend___PlmkG:hover{color:var(--seamless-accent,#3b82f6)}.verifyOTP-module__button___8pIuO{background-color:var(--seamless-accent,#2563eb);border:none;border-radius:.375rem;color:var(--seamless-accent-contrast,#fff);cursor:pointer;padding:.5rem;transition:background-color .2s;width:100%}.verifyOTP-module__button___8pIuO:hover{background-color:var(--seamless-accent-hover,#1d4ed8)}.verifyOTP-module__toggle___wbzVa{background:none;border:none;color:var(--seamless-accent-soft,#60a5fa);cursor:pointer;font-size:.875rem;margin-top:1.5rem;text-align:center;width:100%}");var He="otpInput-module__otpContainer___MUjby",Ze="otpInput-module__otpInput___3YMVm";X(".otpInput-module__otpContainer___MUjby{display:flex;gap:8px;justify-content:center;margin-top:8px}.otpInput-module__otpInput___3YMVm{background:var(--seamless-surface-raised,#374151);border:1px solid var(--seamless-border,#4b5563);border-radius:8px;color:var(--seamless-text,#fff);font-size:1.2rem;height:48px;text-align:center;transition:border-color .15s ease,box-shadow .15s ease;width:42px}.otpInput-module__otpInput___3YMVm:focus{border-color:var(--seamless-accent,#60a5fa);box-shadow:0 0 0 2px var(--seamless-accent,rgba(96,165,250,.25));outline:none}");const Qe=({length:e=6,value:o,inputMode:i="numeric",onChange:n,name:a="otp"})=>{const s=p([]),t=o.split("").concat(Array(e).fill("")).slice(0,e),l=(r,o)=>{const a=B(o,i).slice(0,e),l=[...t];a.forEach((o,i)=>{r+i<e&&(l[r+i]=o)}),n(l.join("")),s.current[Math.min(r+a.length,e-1)]?.focus()};return r("div",{className:He,role:"group","aria-label":"One-time password input",onPaste:e=>{e.preventDefault(),l(0,e.clipboardData.getData("text"))},children:t.map((o,c)=>r("input",{ref:e=>s.current[c]=e,type:"text",inputMode:"numeric"===i?"numeric":"text",autoComplete:"one-time-code",name:`${a}-${c}`,maxLength:1,value:o,className:Ze,onChange:e=>((e,r)=>{if(r.length>1)l(e,r);else if(!r||O(r,i)){const o=[...t];o[e]=r;const i=o.join("");n(i),r&&s.current[e+1]&&s.current[e+1]?.focus()}})(c,e.target.value),onKeyDown:r=>((r,o)=>{if("Backspace"===o.key){o.preventDefault();const e=[...t];t[r]?(e[r]="",n(e.join(""))):r>0&&(e[r-1]="",n(e.join("")),s.current[r-1]?.focus())}"ArrowLeft"===o.key&&r>0&&s.current[r-1]?.focus(),"ArrowRight"===o.key&&r<e-1&&s.current[r+1]?.focus()})(c,r),"aria-label":`Digit ${c+1}`},c))})},Xe=()=>{const o=n(),i=a(),{refreshSession:s}=d(),t="login"===i.state?.flow,[l,c]=g(""),[m,u]=g(null),[p,h]=g(""),[v,b]=g(!1),[y,k]=g(""),[x,w]=g(I),N=_(),P=async()=>{if(m)return;const{next:e,error:r}=await L({client:N,refreshSession:s},{channel:"phone",flow:t?"login":"register",code:l});if(null===r)return"verify_email"===e?(u(!0),void o(W)):void o("/");h(r)},M=async()=>{k(""),await(async()=>{h("");const{error:e}=await q(N,"phone",t?"login":"register");e?h(A("phone")):k("Verification SMS has been resent.")})(),k("Verification SMS has been resent.")};return f(()=>{const e=setInterval(()=>{w(e=>e>0?e-1:0)},1e3);return()=>clearInterval(e)},[]),r("div",{className:De,children:e("div",{className:Re,children:[r("h2",{className:Ee,children:"Verify Your Phone Number"}),r("p",{className:je,children:"Enter the code sent to your phone number."}),p&&r("p",{className:Fe,children:p}),y&&r("p",{className:Ge,children:y}),e("form",{onSubmit:async e=>{if(e.preventDefault(),h(""),l.length===z){b(!0);try{await P()}catch{h("Unexpected error occurred.")}finally{b(!1)}}else h("Please enter a valid code.")},className:Ve,children:[e("div",{children:[e("label",{htmlFor:"phoneCode",className:Ue,children:["Phone Verification Code ",(T=m,!0===T?r("span",{className:"text-green-400 ml-2",children:"✅"}):!1===T?r("span",{className:"text-red-400 ml-2",children:"❌"}):null)," -"," ",e("span",{className:Ke,children:["Code expires in: ",S(x)]})]}),r(Qe,{length:6,value:l,onChange:c}),r("button",{type:"button",onClick:()=>M(),className:Ye,children:"Resend code to phone"})]}),r("button",{type:"submit",className:We,children:v?"Verifying...":"Verify & Continue"}),r("button",{type:"button",onClick:()=>o("/login"),className:Je,children:"Back to login"})]})]})});var T},$e=()=>{const o=n(),i=a(),{refreshSession:s}=d(),t=_(),{passkeySupported:l}=m(),c="login"===i.state?.flow,[u,p]=g(!1),[h,v]=g(""),[b,y]=g(I),[k,x]=g(""),[w,N]=g("");return f(()=>{const e=setInterval(()=>{y(e=>e>0?e-1:0)},1e3);return()=>clearInterval(e)},[]),r("div",{className:De,children:e("div",{className:Re,children:[r("h2",{className:Ee,children:"Verify Your Email"}),r("p",{className:je,children:"We sent you a verification email. Enter the code below."}),k&&r("p",{className:Fe,children:k}),w&&r("p",{className:Ge,children:w}),e("form",{onSubmit:async e=>{if(e.preventDefault(),x(""),h.length===z){p(!0);try{const{next:e,error:r}=await L({client:t,refreshSession:s},{channel:"email",flow:c?"login":"register",code:h,passkeySupported:l});if(null!==r)return void x(r);o("register_passkey"===e?Z:"/")}catch{console.error("Email OTP verification failed."),x("Verification failed.")}finally{p(!1)}}else x("Please enter a valid code.")},className:Ve,children:[e("div",{children:[e("label",{htmlFor:"emailCode",className:Ue,children:["Email Verification Code",e("span",{className:Ke,children:[" ","— Code expires in ",S(b)]})]}),r(Qe,{length:6,value:h,onChange:v,inputMode:"text"}),r("button",{type:"button",onClick:async()=>{x(""),N("");const{error:e}=await q(t,"email",c?"login":"register");e?x(A("email")):N("Verification email has been resent.")},className:Ye,children:"Resend code to email"})]}),r("button",{type:"submit",className:We,disabled:u,children:u?"Verifying...":"Verify & Continue"}),r("button",{type:"button",onClick:()=>o("/login"),className:Je,children:"Back to login"})]})]})})};var er="verifyMagiclink-module__container___qrSXf",rr="verifyMagiclink-module__card___niKgr",or="verifyMagiclink-module__title___SumxD",ir="verifyMagiclink-module__verificationContent___NdsS0",nr="verifyMagiclink-module__spinner___lnW1k",ar="verifyMagiclink-module__successIcon___XjFEM",sr="verifyMagiclink-module__checkIcon___I0JOP",tr="verifyMagiclink-module__prompt___tvPn4",lr="verifyMagiclink-module__helperText___ggTZw",cr="verifyMagiclink-module__actions___6Jf29",dr="verifyMagiclink-module__primaryButton___8DcTo",_r="verifyMagiclink-module__secondaryButton___8n-GU",mr="verifyMagiclink-module__error___tfBn0",ur="verifyMagiclink-module__successText___lO5Qq";X(".verifyMagiclink-module__container___qrSXf{align-items:center;color:var(--seamless-text,#fff);display:flex;justify-content:center;padding:1rem}.verifyMagiclink-module__card___niKgr{background-color:var(--seamless-surface,#1f2937);border-radius:.5rem;box-shadow:0 0 10px var(--seamless-shadow,rgba(0,0,0,.3));max-width:28rem;padding:1.5rem;width:100%}.verifyMagiclink-module__title___SumxD{color:var(--seamless-text,#fff);font-size:1.5rem;font-weight:700;margin-bottom:1rem;text-align:center}.verifyMagiclink-module__verificationContent___NdsS0{align-items:center;display:flex;flex-direction:column;gap:14px;margin:20px 0}.verifyMagiclink-module__spinner___lnW1k{animation:verifyMagiclink-module__spin___2lGzj .9s linear infinite;border:3px solid var(--seamless-border,hsla(0,0%,100%,.15));border-radius:50%;border-top-color:var(--seamless-accent,#60a5fa);height:28px;width:28px}.verifyMagiclink-module__successIcon___XjFEM{align-items:center;background:rgba(16,185,129,.15);border-radius:50%;display:flex;height:36px;justify-content:center;width:36px}.verifyMagiclink-module__checkIcon___I0JOP{animation:verifyMagiclink-module__checkPop___-3qJu .25s ease-out;color:var(--seamless-success,#34d399);height:22px;width:22px}.verifyMagiclink-module__prompt___tvPn4{font-weight:600;line-height:1.4;text-align:center}.verifyMagiclink-module__helperText___ggTZw{color:var(--seamless-text-muted,#9ca3af);font-size:.875rem;line-height:1.4;text-align:center}.verifyMagiclink-module__actions___6Jf29{display:flex;flex-direction:column;gap:.6rem;width:100%}.verifyMagiclink-module__primaryButton___8DcTo{background-color:var(--seamless-accent,#2563eb);border:none;border-radius:.375rem;color:var(--seamless-accent-contrast,#fff);cursor:pointer;font:inherit;font-weight:500;padding:.65rem;width:100%}.verifyMagiclink-module__primaryButton___8DcTo:hover:not(:disabled){background-color:var(--seamless-accent-hover,#1d4ed8)}.verifyMagiclink-module__secondaryButton___8n-GU{background:transparent;border:1px solid var(--seamless-border,#374151);border-radius:.375rem;color:var(--seamless-text,#fff);cursor:pointer;font:inherit;padding:.65rem;width:100%}.verifyMagiclink-module__secondaryButton___8n-GU:hover:not(:disabled){background:var(--seamless-surface-hover,#1f2937)}.verifyMagiclink-module__primaryButton___8DcTo:disabled,.verifyMagiclink-module__secondaryButton___8n-GU:disabled{cursor:not-allowed;opacity:.6}.verifyMagiclink-module__error___tfBn0{color:var(--seamless-danger,#f87171);text-align:center}.verifyMagiclink-module__successText___lO5Qq{color:var(--seamless-success,#34d399);font-size:.9rem}@keyframes verifyMagiclink-module__checkPop___-3qJu{0%{opacity:0;transform:scale(.6)}80%{transform:scale(1.15)}to{opacity:1;transform:scale(1)}}@keyframes verifyMagiclink-module__spin___2lGzj{to{transform:rotate(1turn)}}");const gr=()=>{const[i]=s(),a=n(),t=i.get("token"),[l,c]=g(""),[m,u]=g(null),[h,v]=g(null),[b,y]=g("pending"),[k,x]=g(""),w=_(),{refreshSession:N}=d(),P=p(null);f(()=>{let e=!0,r=null;return(async()=>{if(!t)return e&&c("Missing token for verification."),void console.error("No magic-link token found.");P.current?.token!==t&&(P.current={token:t,result:w.verifyMagicLink(t)});const{error:o}=await P.current.result;if(!e)return;if(o){const e=R(o);return e?void v(e):(console.error("Failed to verify token"),void c("Failed to verify token"))}const i=await E({client:w,refreshSession:N});e&&(u(i),"elsewhere"!==i&&(r=setTimeout(()=>{e&&a("/")},900)))})(),()=>{e=!1,r&&clearTimeout(r)}},[t,w,a,N]);return r("div",h?{className:er,children:e("div",{className:rr,children:[r("h1",{className:or,children:"Confirm this sign-in"}),e("div",{className:ir,children:[("pending"===b||"confirming"===b)&&e(o,{children:[r("p",{className:tr,children:D(h)}),r("p",{className:lr,children:"This link was opened on a different device from the one that asked for it. Only continue if you made that request."}),e("div",{className:cr,children:[r("button",{type:"button",className:dr,disabled:"confirming"===b,onClick:()=>{(async()=>{if(!t||"confirming"===b)return;y("confirming"),x("");const{error:e}=await j({client:w,token:t});if(e)return y("pending"),void x("We could not confirm this sign-in. The link may have expired or already been used.");y("confirmed")})()},children:"Yes, sign in that device"}),r("button",{type:"button",className:_r,disabled:"confirming"===b,onClick:()=>y("declined"),children:"No, this wasn't me"})]}),k&&r("p",{className:mr,role:"alert",children:k})]}),"confirmed"===b&&r("p",{className:ur,role:"status",children:"Sign-in approved. You can return to your other device to continue."}),"declined"===b&&r("p",{className:lr,role:"status",children:"No one has been signed in. You can ignore the email and close this page."})]})]})}:{className:er,children:e("div",{className:rr,children:[r("h1",{className:or,children:"Verifying your login"}),e("div",{className:ir,children:[!m&&!l&&r("div",{className:nr}),m&&r("div",{className:ar,children:r("svg",{viewBox:"0 0 24 24",className:sr,fill:"none",stroke:"currentColor",strokeWidth:"2",children:r("path",{d:"M5 13l4 4L19 7"})})}),!m&&!l&&r("p",{className:lr,children:"Please wait while we securely verify your sign-in link."}),"signed-in"===m&&r("p",{className:ur,children:"Login verified. Redirecting…"}),"elsewhere"===m&&r("p",{className:ur,children:"Login verified. Return to the device where you requested this link to continue."}),l&&r("p",{className:mr,children:l})]})]})})},fr=()=>{const{finishOAuthLogin:i}=d(),a=n(),[t]=s(),[l,c]=g(""),_=p(!1);return f(()=>{_.current||(_.current=!0,F({finishOAuthLogin:i},t,window.location.origin).then(e=>{"error"!==e.kind?"enroll_passkey"!==e.kind?a(e.destination):a(Z,{state:{returnTo:e.returnTo}}):c(e.message)}))},[i,a,t]),e("div",{className:er,children:[r("h2",{className:or,children:l?"Sign-in failed":"Completing sign-in..."}),l&&e(o,{children:[r("p",{children:l}),r("button",{type:"button",onClick:()=>a("/login"),children:"Back to login"})]})]})};var pr="magiclink-module__container___45zcA",hr="magiclink-module__card___Au9oN",vr="magiclink-module__iconWrapper___k5ndr",br="magiclink-module__mailIcon___Pwb7q",yr="magiclink-module__iconRing___bdLvf",kr="magiclink-module__heading___b9cre",xr="magiclink-module__message___kiVFj",wr="magiclink-module__identifier___JtcFM",Nr="magiclink-module__helperText___7Mlfh",Pr="magiclink-module__actions___64I-3",Mr="magiclink-module__secondaryButton___BntAI",Tr="magiclink-module__cooldown___Ib4rm",Cr="magiclink-module__linkButton___maJiv";X(".magiclink-module__container___45zcA{align-items:center;color:var(--seamless-text,#fff);display:flex;justify-content:center}.magiclink-module__card___Au9oN{background-color:var(--seamless-surface,#1f2937);border-radius:.75rem;box-shadow:0 10px 25px var(--seamless-shadow,rgba(0,0,0,.25));max-width:420px;padding:2.5rem 2rem;text-align:center;width:100%}.magiclink-module__iconWrapper___k5ndr{display:flex;justify-content:center;margin-bottom:1.25rem;position:relative}.magiclink-module__mailIcon___Pwb7q{color:var(--seamless-accent-soft,#a5b4fc);height:38px;width:38px;z-index:2}.magiclink-module__iconRing___bdLvf{animation:magiclink-module__pulse___YGm-I 2s infinite;background:rgba(99,102,241,.15);border-radius:50%;height:72px;position:absolute;width:72px}@keyframes magiclink-module__pulse___YGm-I{0%{opacity:.8;transform:scale(.6)}70%{opacity:0;transform:scale(1.4)}to{opacity:0}}.magiclink-module__heading___b9cre{font-size:1.55rem;font-weight:600;margin-bottom:.75rem}.magiclink-module__message___kiVFj{color:var(--seamless-text-muted,#d1d5db);font-size:.95rem;line-height:1.4;margin-bottom:1rem}.magiclink-module__identifier___JtcFM{background:var(--seamless-surface-raised,hsla(0,0%,100%,.05));border-radius:6px;display:inline-block;font-size:1rem;font-weight:600;margin-bottom:1rem;padding:.45rem .6rem}.magiclink-module__helperText___7Mlfh{color:var(--seamless-text-muted,#9ca3af);font-size:.85rem;line-height:1.4;margin-bottom:.6rem}.magiclink-module__actions___64I-3{display:flex;flex-direction:column;gap:.6rem;margin-top:1.6rem}.magiclink-module__secondaryButton___BntAI{background:var(--seamless-surface,#111827);border:1px solid var(--seamless-border,#374151);border-radius:8px;color:var(--seamless-text,#fff);cursor:pointer;font-weight:500;padding:.65rem}.magiclink-module__secondaryButton___BntAI:hover:not(:disabled){background:var(--seamless-surface-hover,#1f2937)}.magiclink-module__secondaryButton___BntAI:disabled{cursor:not-allowed;opacity:.5}.magiclink-module__cooldown___Ib4rm{color:var(--seamless-text-muted,#9ca3af);font-size:.8rem}.magiclink-module__linkButton___maJiv{background:none;border:none;color:var(--seamless-accent-soft,#a5b4fc);cursor:pointer;font-size:.85rem;margin-top:.4rem}.magiclink-module__linkButton___maJiv:hover{text-decoration:underline}");const Or=()=>{const{refreshSession:o}=d(),i=n(),s=a(),t=_(),l=s.state?.identifier,[c,m]=g(G);f(()=>{const e=setInterval(()=>{m(e=>e>0?e-1:0)},1e3);return()=>clearInterval(e)},[]);return f(()=>V({client:t,refreshSession:o,onSignedIn:()=>i("/")}),[t,i,o]),r("div",{className:pr,children:e("div",{className:hr,children:[e("div",{className:vr,children:[r("div",{className:yr}),e("svg",{className:br,viewBox:"0 0 24 24",fill:"none",stroke:"currentColor",strokeWidth:"1.8",children:[r("path",{d:"M4 6h16v12H4z"}),r("path",{d:"m4 6 8 6 8-6"})]})]}),r("h2",{className:kr,children:"Check your email"}),r("p",{className:xr,children:"If an account exists for this address, we sent a secure sign-in link."}),l&&r("div",{className:wr,children:l}),r("p",{className:Nr,children:"Open the email and click the link to finish signing in."}),r("p",{className:Nr,children:"Didn’t receive anything? Check your spam folder or try creating a new account."}),e("div",{className:Pr,children:[r("button",{className:Mr,disabled:c>0,onClick:async()=>{c>0||(await t.requestMagicLink(),m(G))},children:"Resend link"}),c>0&&e("div",{className:Tr,children:["Available in ",c,"s"]}),r("button",{className:Cr,onClick:()=>i("/login"),children:"Change email or phone"})]})]})})},Br=()=>e(t,{children:[r(l,{path:U,element:r(ye,{})}),r(l,{path:K,element:r(xe,{})}),r(l,{path:Y,element:r(Xe,{})}),r(l,{path:W,element:r($e,{})}),r(l,{path:J,element:r(gr,{})}),r(l,{path:H,element:r(fr,{})}),r(l,{path:Z,element:r(Ae,{})}),r(l,{path:Q,element:r(Or,{})}),r(l,{path:"*",element:r(c,{to:U,replace:!0})})]});export{Br as AuthRoutes};
|
|
3
3
|
//# sourceMappingURL=routes.js.map
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@seamless-auth/react",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.18.0",
|
|
4
4
|
"description": "A drop-in authentication solution for modern React applications.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"exports": {
|
|
@@ -56,7 +56,7 @@
|
|
|
56
56
|
}
|
|
57
57
|
},
|
|
58
58
|
"dependencies": {
|
|
59
|
-
"@seamless-auth/client": "^0.
|
|
59
|
+
"@seamless-auth/client": "^0.7.0",
|
|
60
60
|
"@seamless-auth/types": "^0.28.0",
|
|
61
61
|
"@simplewebauthn/browser": "^13.1.0",
|
|
62
62
|
"libphonenumber-js": "^1.12.7"
|
|
@@ -1,3 +0,0 @@
|
|
|
1
|
-
'use client';
|
|
2
|
-
import{createContext as e,useContext as t,useMemo as s,useRef as r,useSyncExternalStore as i,useEffect as o,useState as n}from"react";import{createBrowserOAuthRedirect as a,createBrowserPasskeyPort as c,createAuthSession as u,loadLoginMethods as d,detectPasskeySupport as p}from"@seamless-auth/client";import{jsx as h}from"react/jsx-runtime";const l=e(void 0),g=()=>{const e=t(l);if(!e)throw new Error("useAuth must be used within an AuthProvider");return e},k=({children:e,apiHost:t,autoDetectPreviousSignin:n=!0,magicLinkRedirectUri:d,transport:p,ports:g,initialSession:k})=>{const m=s(()=>({passkeys:g?.passkeys??c(),oauthRedirect:g?.oauthRedirect??a()}),[g?.passkeys,g?.oauthRedirect]),{mode:S,basePath:v,tokenStorage:y,fetch:f,trustedOrigins:b}=p??{},P=b?JSON.stringify(b):void 0,R=s(()=>p?{mode:S,basePath:v,tokenStorage:y,fetch:f,trustedOrigins:P?JSON.parse(P):void 0}:void 0,[S,v,y,f,P]),O=r(k),w=s(()=>u({apiHost:t,magicLinkRedirectUri:d,transport:R,passkeys:m.passkeys,detectPreviousSignIn:n,initialSession:O.current}),[t,d,R,m.passkeys,n]),A=i(w.subscribe,w.getState,w.getServerState);o(()=>{w.actions.refreshSession({background:void 0!==O.current})},[w]);const H=s(()=>({...A,...w.actions,apiHost:t,magicLinkRedirectUri:d,client:w.client,ports:m}),[A,w,t,d,m]);return h(l.Provider,{value:H,children:e})},m=()=>g().client,S=()=>{const e=m(),[t,s]=n(null),[r,i]=n(!0);return o(()=>{let t=!0;return d(e).then(e=>{t&&(e&&s(e),i(!1))}),()=>{t=!1}},[e]),{loginMethods:t,loading:r}},v=()=>{const{ports:e}=g(),[t,s]=n(!1),[r,i]=n(!0);return o(()=>{let t=!0;return p(e.passkeys).then(e=>{t&&(s(e),i(!1))}),()=>{t=!1}},[e.passkeys]),{passkeySupported:t,loading:r}};export{k as A,m as a,S as b,v as c,g as u};
|
|
3
|
-
//# sourceMappingURL=shared-DbQnDPUA.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"shared-DbQnDPUA.js","sources":["../../src/AuthProvider.tsx","../../src/hooks/useAuthClient.ts","../../src/hooks/useLoginMethods.ts","../../src/hooks/usePasskeySupport.ts"],"sourcesContent":[null,null,null,null],"names":["AuthContext","createContext","undefined","useAuth","context","useContext","Error","AuthProvider","children","apiHost","autoDetectPreviousSignin","magicLinkRedirectUri","transport","ports","providedPorts","initialSession","useMemo","passkeys","createBrowserPasskeyPort","oauthRedirect","createBrowserOAuthRedirect","mode","basePath","tokenStorage","fetch","fetchImpl","trustedOrigins","trustedOriginsKey","JSON","stringify","stableTransport","parse","initialSessionRef","useRef","session","createAuthSession","detectPreviousSignIn","current","state","useSyncExternalStore","subscribe","getState","getServerState","useEffect","actions","refreshSession","background","value","client","_jsx","Provider","useAuthClient","useLoginMethods","authClient","loginMethods","setLoginMethods","useState","loading","setLoading","active","loadLoginMethods","then","methods","usePasskeySupport","passkeySupported","setPasskeySupported","detectPasskeySupport","supported"],"mappings":";sVA4GA,MAAMA,EAAcC,OAA2CC,GAMlDC,EAAU,KACrB,MAAMC,EAAUC,EAAWL,GAC3B,IAAKI,EACH,MAAM,IAAIE,MAAM,+CAElB,OAAOF,GA6BIG,EAA4C,EACvDC,WACAC,UACAC,4BAA2B,EAC3BC,uBACAC,YACAC,MAAOC,EACPC,qBAKA,MAAMF,EAAQG,EACZ,KAAA,CACEC,SAAUH,GAAeG,UAAYC,IACrCC,cAAeL,GAAeK,eAAiBC,MAEjD,CAACN,GAAeG,SAAUH,GAAeK,iBAGrCE,KACJA,EAAIC,SACJA,EAAQC,aACRA,EACAC,MAAOC,EAASC,eAChBA,GACEd,GAAa,CAAA,EAEXe,EAAoBD,EAAiBE,KAAKC,UAAUH,QAAkBxB,EACtE4B,EAAkBd,EACtB,IACEJ,EACI,CACES,OACAC,WACAC,eACAC,MAAOC,EACPC,eAAgBC,EACXC,KAAKG,MAAMJ,QACZzB,QAENA,EAEN,CAACmB,EAAMC,EAAUC,EAAcE,EAAWE,IAMtCK,EAAoBC,EAAOlB,GAE3BmB,EAAUlB,EACd,IACEmB,EAAkB,CAChB1B,UACAE,uBACAC,UAAWkB,EACXb,SAAUJ,EAAMI,SAChBmB,qBAAsB1B,EACtBK,eAAgBiB,EAAkBK,UAEtC,CACE5B,EACAE,EACAmB,EACAjB,EAAMI,SACNP,IAOE4B,EAAQC,EACZL,EAAQM,UACRN,EAAQO,SACRP,EAAQQ,gBAcVC,EAAU,KACHT,EAAQU,QAAQC,eAAe,CAClCC,gBAA0C5C,IAA9B8B,EAAkBK,WAE/B,CAACH,IAEJ,MAAMa,EAAQ/B,EACZ,KAAA,IACKsB,KACAJ,EAAQU,QACXnC,UACAE,uBACAqC,OAAQd,EAAQc,OAChBnC,UAEF,CAACyB,EAAOJ,EAASzB,EAASE,EAAsBE,IAGlD,OAAOoC,EAACjD,EAAYkD,SAAQ,CAACH,MAAOA,EAAKvC,SAAGA,KCnPjC2C,EAAgB,IACpBhD,IAAU6C,OCQNI,EAAkB,KAC7B,MAAMC,EAAaF,KACZG,EAAcC,GAAmBC,EAA+B,OAChEC,EAASC,GAAcF,GAAS,GAmBvC,OAjBAb,EAAU,KACR,IAAIgB,GAAS,EAWb,OATKC,EAAiBP,GAAYQ,KAAKC,IAChCH,IAEDG,GACFP,EAAgBO,GAElBJ,GAAW,MAGN,KACLC,GAAS,IAEV,CAACN,IAEG,CAAEC,eAAcG,YCjCZM,EAAoB,KAC/B,MAAMlD,MAAEA,GAAUV,KACX6D,EAAkBC,GAAuBT,GAAS,IAClDC,EAASC,GAAcF,GAAS,GAiBvC,OAfAb,EAAU,KACR,IAAIgB,GAAS,EASb,OAPKO,EAAqBrD,EAAMI,UAAU4C,KAAKM,IACzCR,IACFM,EAAoBE,GACpBT,GAAW,MAIR,KACLC,GAAS,IAEV,CAAC9C,EAAMI,WAEH,CAAE+C,mBAAkBP"}
|