@seamless-auth/vue 0.0.0-stage → 0.2.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.
@@ -0,0 +1,51 @@
1
+ import { type LoginMethod } from '@seamless-auth/client';
2
+ import { type PropType } from 'vue';
3
+ /** The other ways to sign in, offered when a passkey is not the way in. */
4
+ export declare const SaFallbackOptions: import("vue").DefineComponent<import("vue").ExtractPropTypes<{
5
+ identifier: {
6
+ type: StringConstructor;
7
+ required: true;
8
+ };
9
+ /** Null while the methods are unknown; the options then stay permissive. */
10
+ loginMethods: {
11
+ type: PropType<LoginMethod[] | null>;
12
+ default: null;
13
+ };
14
+ offerEmailOtp: {
15
+ type: BooleanConstructor;
16
+ default: boolean;
17
+ };
18
+ offerPasskeyRetry: {
19
+ type: BooleanConstructor;
20
+ default: boolean;
21
+ };
22
+ }>, () => import("vue").VNode<import("vue").RendererNode, import("vue").RendererElement, {
23
+ [key: string]: any;
24
+ }> | null, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, ("magicLink" | "emailOtp" | "phoneOtp" | "passkeyRetry")[], "magicLink" | "emailOtp" | "phoneOtp" | "passkeyRetry", import("vue").PublicProps, Readonly<import("vue").ExtractPropTypes<{
25
+ identifier: {
26
+ type: StringConstructor;
27
+ required: true;
28
+ };
29
+ /** Null while the methods are unknown; the options then stay permissive. */
30
+ loginMethods: {
31
+ type: PropType<LoginMethod[] | null>;
32
+ default: null;
33
+ };
34
+ offerEmailOtp: {
35
+ type: BooleanConstructor;
36
+ default: boolean;
37
+ };
38
+ offerPasskeyRetry: {
39
+ type: BooleanConstructor;
40
+ default: boolean;
41
+ };
42
+ }>> & Readonly<{
43
+ onMagicLink?: ((...args: any[]) => any) | undefined;
44
+ onEmailOtp?: ((...args: any[]) => any) | undefined;
45
+ onPhoneOtp?: ((...args: any[]) => any) | undefined;
46
+ onPasskeyRetry?: ((...args: any[]) => any) | undefined;
47
+ }>, {
48
+ loginMethods: ("passkey" | "magic_link" | "email_otp" | "phone_otp" | "oauth")[] | null;
49
+ offerEmailOtp: boolean;
50
+ offerPasskeyRetry: boolean;
51
+ }, {}, {}, {}, string, import("vue").ComponentProvideOptions, true, {}, any>;
@@ -0,0 +1,4 @@
1
+ /** Sign in with an email or phone number, or create an account with an email. */
2
+ export declare const SaLogin: import("vue").DefineComponent<{}, () => import("vue").VNode<import("vue").RendererNode, import("vue").RendererElement, {
3
+ [key: string]: any;
4
+ }>, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {}, string, import("vue").PublicProps, Readonly<{}> & Readonly<{}>, {}, {}, {}, {}, string, import("vue").ComponentProvideOptions, true, {}, any>;
@@ -0,0 +1,8 @@
1
+ /**
2
+ * Waits for an emailed link to be used, then signs this tab in. A link opened
3
+ * in another tab of this browser reports back at once; one opened on another
4
+ * device is picked up by polling.
5
+ */
6
+ export declare const SaMagicLinkSent: import("vue").DefineComponent<{}, () => import("vue").VNode<import("vue").RendererNode, import("vue").RendererElement, {
7
+ [key: string]: any;
8
+ }>, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {}, string, import("vue").PublicProps, Readonly<{}> & Readonly<{}>, {}, {}, {}, {}, string, import("vue").ComponentProvideOptions, true, {}, any>;
@@ -0,0 +1,4 @@
1
+ /** The OAuth redirect URI. Finishes a provider sign-in. */
2
+ export declare const SaOAuthCallback: import("vue").DefineComponent<{}, () => import("vue").VNode<import("vue").RendererNode, import("vue").RendererElement, {
3
+ [key: string]: any;
4
+ }>, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {}, string, import("vue").PublicProps, Readonly<{}> & Readonly<{}>, {}, {}, {}, {}, string, import("vue").ComponentProvideOptions, true, {}, any>;
@@ -0,0 +1,24 @@
1
+ /** A button per OAuth provider the instance has enabled. Renders nothing without one. */
2
+ export declare const SaOAuthProviderButtons: import("vue").DefineComponent<import("vue").ExtractPropTypes<{
3
+ /**
4
+ * The redirect URI to register with providers. Defaults to the bundled
5
+ * callback screen.
6
+ */
7
+ redirectUri: {
8
+ type: StringConstructor;
9
+ default: undefined;
10
+ };
11
+ }>, () => import("vue").VNode<import("vue").RendererNode, import("vue").RendererElement, {
12
+ [key: string]: any;
13
+ }> | null, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {}, string, import("vue").PublicProps, Readonly<import("vue").ExtractPropTypes<{
14
+ /**
15
+ * The redirect URI to register with providers. Defaults to the bundled
16
+ * callback screen.
17
+ */
18
+ redirectUri: {
19
+ type: StringConstructor;
20
+ default: undefined;
21
+ };
22
+ }>> & Readonly<{}>, {
23
+ redirectUri: string;
24
+ }, {}, {}, {}, string, import("vue").ComponentProvideOptions, true, {}, any>;
@@ -0,0 +1,47 @@
1
+ import { type OtpInputMode } from '@seamless-auth/client';
2
+ import { type PropType } from 'vue';
3
+ /** One box per character of a one-time code. Bind the code with `v-model`. */
4
+ export declare const SaOtpInput: import("vue").DefineComponent<import("vue").ExtractPropTypes<{
5
+ modelValue: {
6
+ type: StringConstructor;
7
+ default: string;
8
+ };
9
+ length: {
10
+ type: NumberConstructor;
11
+ default: number;
12
+ };
13
+ mode: {
14
+ type: PropType<OtpInputMode>;
15
+ default: string;
16
+ };
17
+ name: {
18
+ type: StringConstructor;
19
+ default: string;
20
+ };
21
+ }>, () => import("vue").VNode<import("vue").RendererNode, import("vue").RendererElement, {
22
+ [key: string]: any;
23
+ }>, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, "update:modelValue"[], "update:modelValue", import("vue").PublicProps, Readonly<import("vue").ExtractPropTypes<{
24
+ modelValue: {
25
+ type: StringConstructor;
26
+ default: string;
27
+ };
28
+ length: {
29
+ type: NumberConstructor;
30
+ default: number;
31
+ };
32
+ mode: {
33
+ type: PropType<OtpInputMode>;
34
+ default: string;
35
+ };
36
+ name: {
37
+ type: StringConstructor;
38
+ default: string;
39
+ };
40
+ }>> & Readonly<{
41
+ "onUpdate:modelValue"?: ((...args: any[]) => any) | undefined;
42
+ }>, {
43
+ name: string;
44
+ mode: OtpInputMode;
45
+ length: number;
46
+ modelValue: string;
47
+ }, {}, {}, {}, string, import("vue").ComponentProvideOptions, true, {}, any>;
@@ -0,0 +1,4 @@
1
+ /** Sign in with a passkey alone, without an identifier first. */
2
+ export declare const SaPasskeyLogin: import("vue").DefineComponent<{}, () => import("vue").VNode<import("vue").RendererNode, import("vue").RendererElement, {
3
+ [key: string]: any;
4
+ }>, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {}, string, import("vue").PublicProps, Readonly<{}> & Readonly<{}>, {}, {}, {}, {}, string, import("vue").ComponentProvideOptions, true, {}, any>;
@@ -0,0 +1,8 @@
1
+ /**
2
+ * Offers passkey enrolment to a user who has just signed in. The session
3
+ * already exists by the time this renders, so a passkey is an addition to it,
4
+ * which is what makes leaving without one a legitimate way to finish.
5
+ */
6
+ export declare const SaRegisterPasskey: import("vue").DefineComponent<{}, () => import("vue").VNode<import("vue").RendererNode, import("vue").RendererElement, {
7
+ [key: string]: any;
8
+ }>, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {}, string, import("vue").PublicProps, Readonly<{}> & Readonly<{}>, {}, {}, {}, {}, string, import("vue").ComponentProvideOptions, true, {}, any>;
@@ -0,0 +1,9 @@
1
+ /**
2
+ * Where an emailed magic link lands. Verifies the link once, tells the tab that
3
+ * asked for it, and signs this tab in too when the link was opened in the same
4
+ * browser. Opened on another device, the link is held and the screen asks
5
+ * whether to sign the requesting device in.
6
+ */
7
+ export declare const SaVerifyMagicLink: import("vue").DefineComponent<{}, () => import("vue").VNode<import("vue").RendererNode, import("vue").RendererElement, {
8
+ [key: string]: any;
9
+ }>, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {}, string, import("vue").PublicProps, Readonly<{}> & Readonly<{}>, {}, {}, {}, {}, string, import("vue").ComponentProvideOptions, true, {}, any>;
@@ -0,0 +1,22 @@
1
+ import { type OtpChannel } from '@seamless-auth/client';
2
+ import { type PropType } from 'vue';
3
+ /**
4
+ * Checks a one-time code sent by email or text message. The previous screen's
5
+ * navigation state says whether this is a sign-in (`flow: 'login'`) or a
6
+ * registration.
7
+ */
8
+ export declare const SaVerifyOtp: import("vue").DefineComponent<import("vue").ExtractPropTypes<{
9
+ channel: {
10
+ type: PropType<OtpChannel>;
11
+ default: string;
12
+ };
13
+ }>, () => import("vue").VNode<import("vue").RendererNode, import("vue").RendererElement, {
14
+ [key: string]: any;
15
+ }>, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {}, string, import("vue").PublicProps, Readonly<import("vue").ExtractPropTypes<{
16
+ channel: {
17
+ type: PropType<OtpChannel>;
18
+ default: string;
19
+ };
20
+ }>> & Readonly<{}>, {
21
+ channel: OtpChannel;
22
+ }, {}, {}, {}, string, import("vue").ComponentProvideOptions, true, {}, any>;
@@ -0,0 +1,31 @@
1
+ import type { NavigationGuardWithThis, RouteLocationRaw } from 'vue-router';
2
+ export interface RequireAuthOptions {
3
+ /** Where to send someone who is signed out. Defaults to the configured `loginPath`. */
4
+ redirectTo?: RouteLocationRaw;
5
+ /**
6
+ * Roles the user needs, matched the way the auth API matches them (scoped
7
+ * roles such as `org:admin` included). Any one of a list is enough.
8
+ */
9
+ roles?: string | string[];
10
+ /** Where to send a signed-in user without the role. Left out, navigation is refused. */
11
+ forbiddenRedirectTo?: RouteLocationRaw;
12
+ }
13
+ /** A guard for `beforeEnter`, or to call from `router.beforeEach`. */
14
+ export type SeamlessAuthGuard = NavigationGuardWithThis<undefined>;
15
+ /**
16
+ * Admits a signed-in user. Waits for the session to be read first, so a page
17
+ * load on a protected route is not bounced to the login screen while the
18
+ * session is still loading.
19
+ */
20
+ export declare function requireAuth(options?: RequireAuthOptions): SeamlessAuthGuard;
21
+ /**
22
+ * Admits someone who is signed out, and sends a signed-in user to the
23
+ * configured `signedInPath`. For the screens that start a sign-in.
24
+ */
25
+ export declare function requireGuest(options?: {
26
+ redirectTo?: RouteLocationRaw;
27
+ }): SeamlessAuthGuard;
28
+ /** `requireAuth()` with its defaults. */
29
+ export declare const authGuard: SeamlessAuthGuard;
30
+ /** `requireGuest()` with its defaults. */
31
+ export declare const guestGuard: SeamlessAuthGuard;
@@ -0,0 +1,18 @@
1
+ export { SaAuthLayout } from './components/AuthLayout';
2
+ export { SaFallbackOptions } from './components/FallbackOptions';
3
+ export { SaLogin } from './components/Login';
4
+ export { SaMagicLinkSent } from './components/MagicLinkSent';
5
+ export { SaOAuthCallback } from './components/OAuthCallback';
6
+ export { SaOAuthProviderButtons } from './components/OAuthProviderButtons';
7
+ export { SaOtpInput } from './components/OtpInput';
8
+ export { SaPasskeyLogin } from './components/PasskeyLogin';
9
+ export { SaRegisterPasskey } from './components/RegisterPasskey';
10
+ export { SaVerifyMagicLink } from './components/VerifyMagicLink';
11
+ export { SaVerifyOtp } from './components/VerifyOtp';
12
+ export { authGuard, guestGuard, requireAuth, requireGuest } from './guards';
13
+ export type { RequireAuthOptions, SeamlessAuthGuard } from './guards';
14
+ export { useAuthNavigation } from './navigation';
15
+ export { authRouteName, authRoutePaths } from './paths';
16
+ export type { AuthScreen } from './paths';
17
+ export { createSeamlessAuthRoutes } from './routes';
18
+ export type { SeamlessAuthRoutesOptions } from './routes';
@@ -0,0 +1,27 @@
1
+ import { type AuthScreen } from './paths';
2
+ /**
3
+ * How a bundled screen moves. Screens are named routes, so they reach each
4
+ * other by name wherever the application mounted them. Call it in `setup`.
5
+ */
6
+ export declare function useAuthNavigation(): {
7
+ /** Another bundled screen, with optional navigation state. */
8
+ toScreen: (screen: AuthScreen, state?: Record<string, string>) => Promise<void | import("vue-router").NavigationFailure | undefined>;
9
+ /** Where the application wants a signed-in user, or an in-app path. */
10
+ toApp: (path?: string) => Promise<void | import("vue-router").NavigationFailure | undefined>;
11
+ /**
12
+ * A path as the browser sees it, such as the destination an OAuth sign-in
13
+ * returns. The router's base is part of it, and the router adds its base
14
+ * again, so it is taken off first.
15
+ */
16
+ toLocation: (browserPath: string) => Promise<void | import("vue-router").NavigationFailure | undefined>;
17
+ /** Navigation state the previous screen handed over. */
18
+ state: <T extends object>() => Partial<T>;
19
+ /** A screen's absolute URL, for a redirect URI. Honours the router's base. */
20
+ absoluteUrl: (screen: AuthScreen) => string;
21
+ /**
22
+ * Drops the query from the current URL in place. For screens whose query is
23
+ * a one-time secret (a magic link token, an OAuth code), so it does not stay
24
+ * in history or travel in a Referer.
25
+ */
26
+ dropQuery: () => Promise<void | import("vue-router").NavigationFailure | undefined>;
27
+ };
@@ -0,0 +1,20 @@
1
+ /**
2
+ * The bundled screens, by key. Each is a named route (`seamless-auth-<key>`),
3
+ * so the screens reach each other by name and work under any base path.
4
+ *
5
+ * Two paths are set by contracts outside this package: `verifyMagicLink` is the
6
+ * URL the auth API builds when it emails a magic link, and `oauthCallback` is
7
+ * registered with OAuth providers as an allowed redirect URI.
8
+ */
9
+ export declare const authRoutePaths: {
10
+ readonly login: "login";
11
+ readonly passkeyLogin: "passkey-login";
12
+ readonly verifyPhoneOtp: "verify-phone-otp";
13
+ readonly verifyEmailOtp: "verify-email-otp";
14
+ readonly verifyMagicLink: "verify-magiclink";
15
+ readonly oauthCallback: "oauth/callback";
16
+ readonly registerPasskey: "register-passkey";
17
+ readonly magicLinkSent: "magic-link-sent";
18
+ };
19
+ export type AuthScreen = keyof typeof authRoutePaths;
20
+ export declare const authRouteName: (screen: AuthScreen) => string;
@@ -0,0 +1,15 @@
1
+ import type { RouteRecordRaw } from 'vue-router';
2
+ export interface SeamlessAuthRoutesOptions {
3
+ /** The path the screens are mounted under. Defaults to `/`. */
4
+ basePath?: string;
5
+ }
6
+ /**
7
+ * The bundled sign-in screens as named routes, to spread into the router's
8
+ * routes. There is no catch-all among them, so they never swallow the
9
+ * application's own unknown paths:
10
+ *
11
+ * ```ts
12
+ * createRouter({ history: createWebHistory(), routes: [...appRoutes, ...createSeamlessAuthRoutes()] })
13
+ * ```
14
+ */
15
+ export declare function createSeamlessAuthRoutes(options?: SeamlessAuthRoutesOptions): RouteRecordRaw[];
package/dist/router.js ADDED
@@ -0,0 +1,2 @@
1
+ import{defineComponent as e,onMounted as a,h as n,computed as t,ref as s,watch as i,onBeforeUnmount as r}from"vue";import{u as o}from"./chunks/shared-C2_q4dvU.js";import{fallbackSignInOptions as l,hasFallbackSignInOption as u,startOAuthSignIn as c,isValidEmail as d,isValidPhoneNumber as p,registerWithEmail as m,beginSignIn as v,PASSKEY_SIGN_IN_FAILED as h,MAGIC_LINK_RESEND_COOLDOWN_SECONDS as g,watchMagicLink as f,completeOAuthCallback as y,isOtpCharacter as b,otpCharacters as k,hasNonPasskeyLoginMethod as w,enrollPasskey as x,safeReturnPath as S,getMagicLinkConfirmation as P,magicLinkConfirmationPrompt as L,finishMagicLinkSignIn as C,confirmMagicLinkSignIn as O,OTP_LIFETIME_SECONDS as R,formatCountdown as A,OTP_LENGTH as M,verifyOtp as E,requestOtp as T,otpResendFailedMessage as V}from"@seamless-auth/client";import{useRouter as I,useRoute as $}from"vue-router";const q="seamless-auth-styles";const B=e({name:"SaAuthLayout",props:{card:{type:Boolean,default:!0}},setup(e,{slots:t}){const{styles:s}=o();return a(()=>{s.inject&&function(e){if("undefined"==typeof document||document.getElementById(q))return;const a=document.createElement("style");a.id=q,e&&(a.nonce=e),a.textContent="/*\n * Styles for the bundled Seamless Auth screens of the Angular and Vue bindings\n * (and those that follow). One file, so the screens look the same in every\n * framework. Theme them with the same --seamless-* custom properties the React\n * screens read, or override the .sa-* classes. Every rule is scoped under\n * .sa-auth.\n */\n\n.sa-auth {\n display: flex;\n align-items: center;\n justify-content: center;\n color: var(--seamless-text, white);\n font-family: inherit;\n}\n\n.sa-auth *,\n.sa-auth *::before,\n.sa-auth *::after {\n box-sizing: border-box;\n}\n\n.sa-auth .sa-card {\n background-color: var(--seamless-surface, #1f2937);\n padding: 2rem;\n border-radius: 0.5rem;\n box-shadow: 0 4px 6px var(--seamless-shadow, rgba(0, 0, 0, 0.1));\n width: 100%;\n max-width: 28rem;\n}\n\n.sa-auth .sa-heading {\n font-size: 1.5rem;\n font-weight: bold;\n margin: 0 0 1.5rem;\n text-align: center;\n color: var(--seamless-text, white);\n}\n\n.sa-auth .sa-subtitle,\n.sa-auth .sa-description {\n color: var(--seamless-text-muted, #d1d5db);\n text-align: center;\n margin: 0 0 1rem;\n}\n\n.sa-auth .sa-input-group {\n margin-bottom: 1rem;\n}\n\n.sa-auth .sa-label {\n display: block;\n color: var(--seamless-text-muted, #d1d5db);\n}\n\n.sa-auth .sa-input {\n width: 100%;\n padding: 0.5rem;\n color: inherit;\n background-color: var(--seamless-surface-raised, #4b5563);\n border: 1px solid var(--seamless-border, #d1d5db);\n border-radius: 0.375rem;\n margin-top: 0.25rem;\n}\n\n.sa-auth .sa-input:focus,\n.sa-auth .sa-otp-input:focus {\n outline: none;\n box-shadow: 0 0 0 2px var(--seamless-accent, #3b82f6);\n}\n\n.sa-auth .sa-helper-text {\n font-size: 0.75rem;\n color: var(--seamless-text-muted, #9ca3af);\n margin-top: 0.5rem;\n}\n\n.sa-auth .sa-error {\n color: var(--seamless-danger, #f87171);\n font-size: 0.875rem;\n}\n\n.sa-auth .sa-success {\n color: var(--seamless-success, #68d391);\n font-size: 0.875rem;\n}\n\n.sa-auth .sa-button {\n width: 100%;\n border: none;\n background-color: var(--seamless-accent, #2563eb);\n color: var(--seamless-accent-contrast, white);\n padding: 0.5rem;\n border-radius: 0.375rem;\n transition:\n background-color 0.3s,\n opacity 0.3s;\n cursor: pointer;\n margin-top: 1rem;\n font: inherit;\n}\n\n.sa-auth .sa-button:hover:not(:disabled) {\n background-color: var(--seamless-accent-hover, #1d4ed8);\n}\n\n.sa-auth .sa-button:disabled {\n opacity: 0.6;\n cursor: not-allowed;\n}\n\n.sa-auth .sa-secondary {\n width: 100%;\n margin-top: 0.75rem;\n padding: 0.5rem;\n border-radius: 0.375rem;\n background: transparent;\n color: var(--seamless-text, white);\n border: 1px solid var(--seamless-border, #d1d5db);\n cursor: pointer;\n font: inherit;\n}\n\n.sa-auth .sa-submit-hint {\n font-size: 0.75rem;\n color: var(--seamless-text-muted, #9ca3af);\n margin-top: 0.5rem;\n text-align: center;\n}\n\n.sa-auth .sa-link {\n margin-top: 1rem;\n width: 100%;\n font-size: 0.875rem;\n color: var(--seamless-accent-soft, #60a5fa);\n text-align: center;\n background: none;\n border: none;\n cursor: pointer;\n font-family: inherit;\n}\n\n.sa-auth .sa-link:disabled {\n opacity: 0.6;\n cursor: not-allowed;\n}\n\n.sa-auth .sa-fallback {\n margin-top: 18px;\n padding: 18px;\n border-radius: 12px;\n background: var(--seamless-surface-raised, rgba(255, 255, 255, 0.04));\n border: 1px solid var(--seamless-border, rgba(255, 255, 255, 0.08));\n display: flex;\n flex-direction: column;\n gap: 14px;\n}\n\n.sa-auth .sa-fallback-header {\n font-weight: 600;\n}\n\n.sa-auth .sa-fallback-description {\n margin: 0;\n font-size: 0.875rem;\n color: var(--seamless-text-muted, #9ca3af);\n}\n\n.sa-auth .sa-actions {\n display: flex;\n flex-direction: column;\n gap: 10px;\n margin-top: 1rem;\n}\n\n.sa-auth .sa-action {\n display: flex;\n flex-direction: column;\n align-items: flex-start;\n gap: 2px;\n width: 100%;\n padding: 12px 14px;\n border-radius: 10px;\n background: var(--seamless-surface, rgba(255, 255, 255, 0.02));\n border: 1px solid var(--seamless-border, rgba(255, 255, 255, 0.12));\n color: var(--seamless-text, white);\n cursor: pointer;\n text-align: left;\n font: inherit;\n}\n\n.sa-auth .sa-action:hover {\n border-color: var(--seamless-accent, #3b82f6);\n}\n\n.sa-auth .sa-action-title {\n font-weight: 600;\n}\n\n.sa-auth .sa-action-subtext {\n font-size: 0.8rem;\n color: var(--seamless-text-muted, #9ca3af);\n}\n\n.sa-auth .sa-otp {\n display: flex;\n gap: 0.5rem;\n justify-content: center;\n margin: 0.75rem 0;\n}\n\n.sa-auth .sa-otp-input {\n width: 2.75rem;\n height: 3rem;\n text-align: center;\n font-size: 1.25rem;\n color: inherit;\n background-color: var(--seamless-surface-raised, #4b5563);\n border: 1px solid var(--seamless-border, #d1d5db);\n border-radius: 0.375rem;\n}\n\n.sa-auth .sa-timer {\n font-size: 0.75rem;\n color: var(--seamless-warning, #facc15);\n}\n\n.sa-auth .sa-identifier {\n margin: 0.75rem auto;\n padding: 0.25rem 0.75rem;\n width: fit-content;\n border-radius: 999px;\n background: var(--seamless-surface-raised, #4b5563);\n}\n\n.sa-auth .sa-center {\n text-align: center;\n}\n\n.sa-auth .sa-spinner {\n width: 2rem;\n height: 2rem;\n margin: 1rem auto;\n border: 3px solid var(--seamless-border, rgba(255, 255, 255, 0.2));\n border-top-color: var(--seamless-accent, #3b82f6);\n border-radius: 50%;\n animation: sa-spin 0.9s linear infinite;\n}\n\n@keyframes sa-spin {\n to {\n transform: rotate(360deg);\n }\n}\n\n@media (prefers-reduced-motion: reduce) {\n .sa-auth .sa-spinner {\n animation: none;\n }\n}\n",document.head.prepend(a)}(s.nonce)}),()=>n("div",{class:"sa-auth"},[n("div",{class:e.card?"sa-card":"sa-center"},t.default?.())])}}),z=(e,a,t)=>n("button",{type:"button",class:"sa-action",onClick:t},[n("span",{class:"sa-action-title"},e),n("span",{class:"sa-action-subtext"},a)]),U=e({name:"SaFallbackOptions",props:{identifier:{type:String,required:!0},loginMethods:{type:Array,default:null},offerEmailOtp:{type:Boolean,default:!0},offerPasskeyRetry:{type:Boolean,default:!1}},emits:["magicLink","emailOtp","phoneOtp","passkeyRetry"],setup(e,{emit:a}){const s=t(()=>l(e.identifier,e.loginMethods,{emailOtp:e.offerEmailOtp,passkeyRetry:e.offerPasskeyRetry}));return()=>{const e=s.value;return u(e)?n("div",{class:"sa-fallback"},[n("div",{class:"sa-fallback-header"},"Choose a sign-in method"),n("p",{class:"sa-fallback-description"},"Choose another secure sign-in method."),n("div",{class:"sa-actions"},[e.magicLink&&z("Email Magic Link","Send a secure sign-in link to your email",()=>a("magicLink")),e.emailOtp&&z("Email Code","Receive a one-time code by email",()=>a("emailOtp")),e.phoneOtp&&z("Text Message Code","Receive a one-time code via SMS",()=>a("phoneOtp"))]),e.passkeyRetry&&n("button",{type:"button",class:"sa-link",onClick:()=>a("passkeyRetry")},"Try passkey anyway")]):null}}}),D={login:"login",passkeyLogin:"passkey-login",verifyPhoneOtp:"verify-phone-otp",verifyEmailOtp:"verify-email-otp",verifyMagicLink:"verify-magiclink",oauthCallback:"oauth/callback",registerPasskey:"register-passkey",magicLinkSent:"magic-link-sent"},Y=e=>`seamless-auth-${e}`;function F(){const e=I(),a=o();return{toScreen:(a,n)=>e.push({name:Y(a),state:n}),toApp:n=>e.push(n??a.signedInPath),toLocation:a=>{const n=e.options.history.base.replace(/\/+$/,""),t=n&&(a===n||a.startsWith(`${n}/`))?a.slice(n.length)||"/":a;return e.push(t)},state:()=>{const a=e.options.history.state;return a&&"object"==typeof a?a:{}},absoluteUrl:a=>new URL(e.resolve({name:Y(a)}).href,window.location.origin).toString(),dropQuery:()=>e.replace({...e.currentRoute.value,query:{},hash:""})}}const j=e({name:"SaOAuthProviderButtons",props:{redirectUri:{type:String,default:void 0}},setup(e){const t=o(),i=F(),r=s([]),l=s("");a(async()=>{const{data:e}=await t.listOAuthProviders();r.value=e?.providers??[]});return()=>0===r.value.length?null:n("div",{class:"sa-actions"},[...r.value.map(a=>n("button",{key:a.id,type:"button",class:"sa-action",onClick:()=>(async a=>{l.value="";const n=await c({actions:t,oauthRedirect:t.ports.oauthRedirect},{providerId:a,redirectUri:e.redirectUri??i.absoluteUrl("oauthCallback")});n.error&&(l.value=n.error)})(a.id)},[n("span",{class:"sa-action-title"},`Continue with ${a.name}`)])),l.value&&n("p",{class:"sa-error"},l.value)])}}),N=e=>e.target.value,_=e({name:"SaLogin",setup(){const e=o(),r=F(),l=s(e.hasSignedInBefore.value?"login":"register");i(e.hasSignedInBefore,e=>{e&&(l.value="login")});const u=s(""),c=s(""),g=s(""),f=s(""),y=s(""),b=s(!1),k=s(null),w=s(!1),x=t(()=>"login"===l.value?d(u.value)||p(u.value):d(c.value)),S=t(()=>"login"===l.value?u.value?x.value?"Ready to continue.":"This does not look like a complete email or phone number yet.":"Enter your email or phone number to continue.":c.value?x.value?"Ready to continue.":"This does not look like a complete email address yet.":"Enter your email address to continue.");a(()=>{e.loadLoginMethods(),e.checkPasskeySupport()});const P=()=>{u.value&&(g.value=d(u.value)||p(u.value)?"":"Please enter a valid email or phone number")},L=()=>{c.value&&(f.value=d(c.value)?"":"Please enter a valid email")},C=async a=>{if(a.preventDefault(),x.value&&!w.value){y.value="",b.value=!1,w.value=!0;try{if("register"===l.value){const{error:a}=await m(e.client,c.value);return a?void(y.value=a):void await r.toScreen("verifyEmailOtp")}const[a,n]=await Promise.all([e.checkPasskeySupport(),e.loadLoginMethods()]),t=await v(e,{identifier:u.value,passkeySupported:a,configuredMethods:n});if("error"===t.kind)return void(y.value=t.message);if("signed_in"===t.kind)return void await r.toApp();k.value=t.loginMethods,b.value=!0,t.passkeyFailed&&(y.value=h)}catch{y.value="Failed to continue sign-in. Please try again."}finally{w.value=!1}}},O=async()=>{y.value="";const{error:a}=await e.handlePasskeyLogin();a?y.value=h:await r.toApp()},R=async()=>{const{error:a}=await e.client.requestMagicLink();a?y.value="Failed to send magic link.":await r.toScreen("magicLinkSent",{identifier:u.value})},A=async()=>{const{error:a}=await e.client.requestLoginEmailOtp();a?y.value="Failed to send email code.":await r.toScreen("verifyEmailOtp",{flow:"login"})},M=async()=>{const{error:a}=await e.client.requestLoginPhoneOtp();a?y.value="Failed to send OTP.":await r.toScreen("verifyPhoneOtp",{flow:"login"})};return()=>n(B,null,()=>[n("h2",{class:"sa-heading"},"login"===l.value?"Sign In":"Create Account"),n("form",{onSubmit:C},["login"===l.value?n("div",{class:"sa-input-group"},[n("label",{for:"identifier",class:"sa-label"},"Email Address / Phone Number"),n("input",{id:"identifier",type:"text",class:"sa-input",autocomplete:"off",placeholder:"Email or Phone Number",required:!0,value:u.value,onInput:e=>{u.value=N(e)},onBlur:P}),n("p",{class:"sa-helper-text"},"Phone numbers must include a country code e.g. +1"),b.value&&n(U,{identifier:u.value,loginMethods:k.value,offerPasskeyRetry:e.passkeySupported.value,onMagicLink:R,onEmailOtp:A,onPhoneOtp:M,onPasskeyRetry:O}),g.value&&n("p",{class:"sa-error"},g.value)]):n("div",{class:"sa-input-group"},[n("label",{for:"email",class:"sa-label"},"Email Address"),n("input",{id:"email",type:"email",class:"sa-input",autocomplete:"off",required:!0,value:c.value,onInput:e=>{c.value=N(e)},onBlur:L}),f.value&&n("p",{class:"sa-error"},f.value)]),n("button",{type:"submit",class:"sa-button",disabled:!x.value||w.value,"aria-describedby":"seamless-submit-hint"},"login"===l.value?"Login":"Register"),n("p",{id:"seamless-submit-hint",role:"status",class:"sa-submit-hint"},S.value),y.value&&n("p",{class:"sa-error"},y.value),n("button",{type:"button",class:"sa-link",onClick:()=>{l.value="login"===l.value?"register":"login"}},"login"===l.value?"Don't have an account? Create one":"Already have an account? Sign in")]),n(j)])}}),Q=e({name:"SaMagicLinkSent",setup(){const e=o(),t=F(),i=t.state().identifier,l=s(g);let u,c;a(()=>{u=setInterval(()=>{l.value=Math.max(0,l.value-1)},1e3),c=f({client:e.client,refreshSession:e.refreshSession,onSignedIn:()=>{t.toApp()}})}),r(()=>{clearInterval(u),c?.()});const d=async()=>{l.value>0||(await e.client.requestMagicLink(),l.value=g)};return()=>n(B,null,()=>[n("div",{class:"sa-center"},[n("h2",{class:"sa-heading"},"Check your email"),n("p",{class:"sa-description"},"If an account exists for this address, we sent a secure sign-in link."),i&&n("div",{class:"sa-identifier"},i),n("p",{class:"sa-helper-text"},"Open the email and click the link to finish signing in."),n("p",{class:"sa-helper-text"},"Didn't receive anything? Check your spam folder or try creating a new account.")]),n("div",{class:"sa-actions"},[n("button",{type:"button",class:"sa-secondary",disabled:l.value>0,onClick:d},"Resend link"),l.value>0&&n("div",{class:"sa-helper-text sa-center"},`Available in ${l.value}s`),n("button",{type:"button",class:"sa-link",onClick:()=>t.toScreen("login")},"Change email or phone")])])}}),W=e({name:"SaOAuthCallback",setup(){const e=o(),t=F(),i=$(),r=s("");return a(async()=>{const a=new URLSearchParams;for(const e of["code","state"]){const n=i.query[e];"string"==typeof n&&a.set(e,n)}t.dropQuery();const n=await y(e,a,window.location.origin);"error"!==n.kind?"enroll_passkey"!==n.kind?await t.toLocation(n.destination):await t.toScreen("registerPasskey",{returnTo:n.returnTo}):r.value=n.message}),()=>n(B,{card:!1},()=>[n("h2",{class:"sa-heading"},r.value?"Sign-in failed":"Completing sign-in..."),r.value&&[n("p",r.value),n("button",{type:"button",class:"sa-link",onClick:()=>t.toScreen("login")},"Back to login")]])}}),K=e({name:"SaOtpInput",props:{modelValue:{type:String,default:""},length:{type:Number,default:6},mode:{type:String,default:"numeric"},name:{type:String,default:"otp"}},emits:["update:modelValue"],setup(e,{emit:a}){const s=[],i=t(()=>Array.from({length:e.length},(a,n)=>e.modelValue[n]??"")),r=e=>s[e]?.focus(),o=e=>a("update:modelValue",e.join("")),l=(a,n)=>{const t=k(n,e.mode).slice(0,e.length),s=[...i.value];t.forEach((e,n)=>{a+n<s.length&&(s[a+n]=e)}),o(s),r(Math.min(a+t.length,e.length-1))},u=e=>{e.preventDefault(),l(0,e.clipboardData?.getData("text")??"")};return()=>n("div",{class:"sa-otp",role:"group","aria-label":"One-time password input",onPaste:u},i.value.map((a,t)=>n("input",{key:t,ref:e=>{s[t]=e},class:"sa-otp-input",type:"text",inputmode:"numeric"===e.mode?"numeric":"text",autocomplete:"one-time-code",name:`${e.name}-${t}`,maxlength:1,value:a,"aria-label":`Digit ${t+1}`,onInput:a=>((a,n)=>{const t=n.target,s=t.value;if(s.length>1)return void l(a,s);if(s&&!b(s,e.mode))return void(t.value=i.value[a]);const u=[...i.value];u[a]=s,o(u),s&&r(a+1)})(t,a),onKeydown:a=>((a,n)=>{if("Backspace"===n.key){n.preventDefault();const e=[...i.value];e[a]?(e[a]="",o(e)):a>0&&(e[a-1]="",o(e),r(a-1))}"ArrowLeft"===n.key&&a>0&&r(a-1),"ArrowRight"===n.key&&a<e.length-1&&r(a+1)})(t,a)})))}}),G=e({name:"SaPasskeyLogin",setup(){const e=o(),a=F(),t=s(""),i=async()=>{t.value="";(await e.handlePasskeyLogin()).error?t.value="Passkey sign-in could not be completed. Try another sign-in method.":await a.toApp()};return()=>n(B,null,()=>[n("h2",{class:"sa-heading"},"Login with Passkey"),n("button",{type:"button",class:"sa-button",onClick:i},"Use Passkey"),t.value&&n("p",{class:"sa-error"},t.value)])}}),H=e({name:"SaRegisterPasskey",setup(){const e=o(),i=F(),r=i.state().returnTo,l=()=>void 0===r?i.toApp():i.toLocation(S(r)),u=s("idle"),c=s(""),d=t(()=>w(e.loginMethods.value));a(()=>{e.checkPasskeySupport(),e.loadLoginMethods()});const p=async a=>{u.value="loading";const{error:n}=await x({client:e.client,refreshSession:e.refreshSession},a);if(n)return u.value="error",void(c.value=n);u.value="success",c.value="Passkey registered successfully.",await l()},m=async()=>{await e.refreshSession(),await l()},v=()=>"loading"===u.value;return()=>n(B,null,()=>e.passkeySupportLoading.value||e.loginMethodsLoading.value?n("div",{class:"sa-center"},[n("div",{class:"sa-spinner","aria-hidden":"true"}),n("span","Checking for Passkey Support...")]):e.passkeySupported.value?[n("h2",{class:"sa-heading"},"Secure Your Account with a Passkey"),n("p",{class:"sa-description"},"Your device supports passkeys! Register one to skip passwords forever."),n("button",{type:"button",class:"sa-button",disabled:v(),onClick:()=>p()},v()?"Registering...":"Register Passkey"),n("button",{type:"button",class:"sa-secondary",disabled:v(),onClick:()=>p("cross-platform")},"Use a security key instead"),c.value&&n("p",{class:"success"===u.value?"sa-success":"sa-error",role:"status"},c.value),d.value&&n("button",{type:"button",class:"sa-link",disabled:v(),onClick:m},"Skip for now")]:[n("h2",{class:"sa-heading"},"Passkeys are not available here"),n("p",{class:"sa-description"},d.value?"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."),d.value&&n("button",{type:"button",class:"sa-button",onClick:m},"Continue")])}}),J=e({name:"SaVerifyMagicLink",setup(){const e=o(),t=F(),i=$().query.token,l="string"==typeof i?i:null,u=s(null),c=s(""),d=s(""),p=s("pending"),m=s("");let v,h=!0;r(()=>{h=!1,clearTimeout(v)}),a(async()=>{if(!l)return void(c.value="Missing token for verification.");t.dropQuery();const a=await e.client.verifyMagicLink(l);if(!h)return;if(a.error){const e=P(a.error);return e?void(d.value=L(e)):void(c.value="Failed to verify token")}const n=await C({client:e.client,refreshSession:e.refreshSession});h&&(u.value=n,"signed-in"===n&&(v=setTimeout(()=>{t.toApp()},900)))});const g=()=>{const a="pending"===p.value||"confirming"===p.value;return[n("div",{class:"sa-center"},[n("h1",{class:"sa-heading"},"Confirm this sign-in"),a&&[n("p",{class:"sa-description"},d.value),n("p",{class:"sa-helper-text"},"This link was opened on a different device from the one that asked for it. Only continue if you made that request.")],"confirmed"===p.value&&n("p",{class:"sa-success",role:"status"},"Sign-in approved. You can return to your other device to continue."),"declined"===p.value&&n("p",{class:"sa-helper-text",role:"status"},"No one has been signed in. You can ignore the email and close this page.")]),a&&n("div",{class:"sa-actions"},[n("button",{type:"button",class:"sa-button",disabled:"confirming"===p.value,onClick:()=>{(async()=>{if(!l||"confirming"===p.value)return;p.value="confirming",m.value="";const a=await O({client:e.client,token:l});h&&(a.error?(p.value="pending",m.value="We could not confirm this sign-in. The link may have expired or already been used."):p.value="confirmed")})()}},"Yes, sign in that device"),n("button",{type:"button",class:"sa-secondary",disabled:"confirming"===p.value,onClick:()=>{p.value="declined"}},"No, this wasn't me")]),a&&m.value&&n("p",{class:"sa-error",role:"alert"},m.value)]};return()=>n(B,null,()=>d.value?g():n("div",{class:"sa-center"},[n("h1",{class:"sa-heading"},"Verifying your login"),!u.value&&!c.value&&[n("div",{class:"sa-spinner","aria-hidden":"true"}),n("p",{class:"sa-helper-text"},"Please wait while we securely verify your sign-in link.")],"signed-in"===u.value&&n("p",{class:"sa-success",role:"status"},"Login verified. Redirecting..."),"elsewhere"===u.value&&n("p",{class:"sa-success",role:"status"},"Login verified. Return to the device where you requested this link to continue."),c.value&&n("p",{class:"sa-error",role:"alert"},c.value)]))}}),X={email:{title:"Verify Your Email",subtitle:"We sent you a verification email. Enter the code below.",label:"Email Verification Code",resend:"Resend code to email",resent:"Verification email has been resent."},phone:{title:"Verify Your Phone Number",subtitle:"Enter the code sent to your phone number.",label:"Phone Verification Code",resend:"Resend code to phone",resent:"Verification SMS has been resent."}},Z=e({name:"SaVerifyOtp",props:{channel:{type:String,default:"email"}},setup(e){const i=o(),l=F(),u="login"===l.state().flow?"login":"register",c=t(()=>X[e.channel]),d=s(""),p=s(""),m=s(""),v=s(!1),h=s(R);let g;a(()=>{"email"===e.channel&&i.checkPasskeySupport(),g=setInterval(()=>{h.value=Math.max(0,h.value-1)},1e3)}),r(()=>clearInterval(g));const f=async()=>{p.value="",m.value="";(await T(i.client,e.channel,u)).error?p.value=V(e.channel):m.value=c.value.resent},y=async a=>{if(a.preventDefault(),!v.value){p.value="",v.value=!0;try{const a="email"===e.channel&&await i.checkPasskeySupport(),n=await E({client:i.client,refreshSession:i.refreshSession},{channel:e.channel,flow:u,code:d.value,passkeySupported:a});if(null!==n.error)return void(p.value=n.error);"register_passkey"===n.next?await l.toScreen("registerPasskey"):"verify_email"===n.next?await l.toScreen("verifyEmailOtp"):await l.toApp()}catch{p.value="Verification failed."}finally{v.value=!1}}};return()=>n(B,null,()=>[n("h2",{class:"sa-heading"},c.value.title),n("p",{class:"sa-subtitle"},c.value.subtitle),p.value&&n("p",{class:"sa-error"},p.value),m.value&&n("p",{class:"sa-success"},m.value),n("form",{onSubmit:y},[n("div",[n("span",{class:"sa-label"},[`${c.value.label} `,n("span",{class:"sa-timer"},`(code expires in ${A(h.value)})`)]),n(K,{modelValue:d.value,"onUpdate:modelValue":e=>{d.value=e},length:M,mode:"email"===e.channel?"text":"numeric"}),n("button",{type:"button",class:"sa-link",onClick:f},c.value.resend)]),n("button",{type:"submit",class:"sa-button",disabled:v.value},v.value?"Verifying...":"Verify & Continue"),n("button",{type:"button",class:"sa-link",onClick:()=>l.toScreen("login")},"Back to login")])])}});function ee(e={}){return async()=>{const a=o(),n=await a.whenSettled();return n.loading||!n.isAuthenticated?e.redirectTo??a.loginPath:!(void 0!==e.roles&&!a.hasScopedRole(e.roles))||(e.forbiddenRedirectTo??!1)}}function ae(e={}){return async()=>{const a=o(),n=await a.whenSettled();return!!n.loading||(!n.isAuthenticated||(e.redirectTo??a.signedInPath))}}const ne=ee(),te=ae();function se(e={}){const a=`/${(e.basePath??"/").replace(/^\/+|\/+$/g,"")}`,n=e=>`${"/"===a?"":a}/${D[e]}`,t=(e,a,t)=>({path:n(e),name:Y(e),component:a,...t?{props:t}:{}});return[t("login",_),t("passkeyLogin",G),t("verifyEmailOtp",Z,{channel:"email"}),t("verifyPhoneOtp",Z,{channel:"phone"}),t("magicLinkSent",Q),t("verifyMagicLink",J),t("oauthCallback",W),t("registerPasskey",H)]}export{B as SaAuthLayout,U as SaFallbackOptions,_ as SaLogin,Q as SaMagicLinkSent,W as SaOAuthCallback,j as SaOAuthProviderButtons,K as SaOtpInput,G as SaPasskeyLogin,H as SaRegisterPasskey,J as SaVerifyMagicLink,Z as SaVerifyOtp,ne as authGuard,Y as authRouteName,D as authRoutePaths,se as createSeamlessAuthRoutes,te as guestGuard,ee as requireAuth,ae as requireGuest,F as useAuthNavigation};
2
+ //# sourceMappingURL=router.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"router.js","sources":["../src/router/components/AuthLayout.ts","../../../resources/styles/seamless-auth.css","../src/router/components/FallbackOptions.ts","../src/router/paths.ts","../src/router/navigation.ts","../src/router/components/OAuthProviderButtons.ts","../src/router/components/Login.ts","../src/router/components/MagicLinkSent.ts","../src/router/components/OAuthCallback.ts","../src/router/components/OtpInput.ts","../src/router/components/PasskeyLogin.ts","../src/router/components/RegisterPasskey.ts","../src/router/components/VerifyMagicLink.ts","../src/router/components/VerifyOtp.ts","../src/router/guards.ts","../src/router/routes.ts"],"sourcesContent":[null,"/*\n * Styles for the bundled Seamless Auth screens of the Angular and Vue bindings\n * (and those that follow). One file, so the screens look the same in every\n * framework. Theme them with the same --seamless-* custom properties the React\n * screens read, or override the .sa-* classes. Every rule is scoped under\n * .sa-auth.\n */\n\n.sa-auth {\n display: flex;\n align-items: center;\n justify-content: center;\n color: var(--seamless-text, white);\n font-family: inherit;\n}\n\n.sa-auth *,\n.sa-auth *::before,\n.sa-auth *::after {\n box-sizing: border-box;\n}\n\n.sa-auth .sa-card {\n background-color: var(--seamless-surface, #1f2937);\n padding: 2rem;\n border-radius: 0.5rem;\n box-shadow: 0 4px 6px var(--seamless-shadow, rgba(0, 0, 0, 0.1));\n width: 100%;\n max-width: 28rem;\n}\n\n.sa-auth .sa-heading {\n font-size: 1.5rem;\n font-weight: bold;\n margin: 0 0 1.5rem;\n text-align: center;\n color: var(--seamless-text, white);\n}\n\n.sa-auth .sa-subtitle,\n.sa-auth .sa-description {\n color: var(--seamless-text-muted, #d1d5db);\n text-align: center;\n margin: 0 0 1rem;\n}\n\n.sa-auth .sa-input-group {\n margin-bottom: 1rem;\n}\n\n.sa-auth .sa-label {\n display: block;\n color: var(--seamless-text-muted, #d1d5db);\n}\n\n.sa-auth .sa-input {\n width: 100%;\n padding: 0.5rem;\n color: inherit;\n background-color: var(--seamless-surface-raised, #4b5563);\n border: 1px solid var(--seamless-border, #d1d5db);\n border-radius: 0.375rem;\n margin-top: 0.25rem;\n}\n\n.sa-auth .sa-input:focus,\n.sa-auth .sa-otp-input:focus {\n outline: none;\n box-shadow: 0 0 0 2px var(--seamless-accent, #3b82f6);\n}\n\n.sa-auth .sa-helper-text {\n font-size: 0.75rem;\n color: var(--seamless-text-muted, #9ca3af);\n margin-top: 0.5rem;\n}\n\n.sa-auth .sa-error {\n color: var(--seamless-danger, #f87171);\n font-size: 0.875rem;\n}\n\n.sa-auth .sa-success {\n color: var(--seamless-success, #68d391);\n font-size: 0.875rem;\n}\n\n.sa-auth .sa-button {\n width: 100%;\n border: none;\n background-color: var(--seamless-accent, #2563eb);\n color: var(--seamless-accent-contrast, white);\n padding: 0.5rem;\n border-radius: 0.375rem;\n transition:\n background-color 0.3s,\n opacity 0.3s;\n cursor: pointer;\n margin-top: 1rem;\n font: inherit;\n}\n\n.sa-auth .sa-button:hover:not(:disabled) {\n background-color: var(--seamless-accent-hover, #1d4ed8);\n}\n\n.sa-auth .sa-button:disabled {\n opacity: 0.6;\n cursor: not-allowed;\n}\n\n.sa-auth .sa-secondary {\n width: 100%;\n margin-top: 0.75rem;\n padding: 0.5rem;\n border-radius: 0.375rem;\n background: transparent;\n color: var(--seamless-text, white);\n border: 1px solid var(--seamless-border, #d1d5db);\n cursor: pointer;\n font: inherit;\n}\n\n.sa-auth .sa-submit-hint {\n font-size: 0.75rem;\n color: var(--seamless-text-muted, #9ca3af);\n margin-top: 0.5rem;\n text-align: center;\n}\n\n.sa-auth .sa-link {\n margin-top: 1rem;\n width: 100%;\n font-size: 0.875rem;\n color: var(--seamless-accent-soft, #60a5fa);\n text-align: center;\n background: none;\n border: none;\n cursor: pointer;\n font-family: inherit;\n}\n\n.sa-auth .sa-link:disabled {\n opacity: 0.6;\n cursor: not-allowed;\n}\n\n.sa-auth .sa-fallback {\n margin-top: 18px;\n padding: 18px;\n border-radius: 12px;\n background: var(--seamless-surface-raised, rgba(255, 255, 255, 0.04));\n border: 1px solid var(--seamless-border, rgba(255, 255, 255, 0.08));\n display: flex;\n flex-direction: column;\n gap: 14px;\n}\n\n.sa-auth .sa-fallback-header {\n font-weight: 600;\n}\n\n.sa-auth .sa-fallback-description {\n margin: 0;\n font-size: 0.875rem;\n color: var(--seamless-text-muted, #9ca3af);\n}\n\n.sa-auth .sa-actions {\n display: flex;\n flex-direction: column;\n gap: 10px;\n margin-top: 1rem;\n}\n\n.sa-auth .sa-action {\n display: flex;\n flex-direction: column;\n align-items: flex-start;\n gap: 2px;\n width: 100%;\n padding: 12px 14px;\n border-radius: 10px;\n background: var(--seamless-surface, rgba(255, 255, 255, 0.02));\n border: 1px solid var(--seamless-border, rgba(255, 255, 255, 0.12));\n color: var(--seamless-text, white);\n cursor: pointer;\n text-align: left;\n font: inherit;\n}\n\n.sa-auth .sa-action:hover {\n border-color: var(--seamless-accent, #3b82f6);\n}\n\n.sa-auth .sa-action-title {\n font-weight: 600;\n}\n\n.sa-auth .sa-action-subtext {\n font-size: 0.8rem;\n color: var(--seamless-text-muted, #9ca3af);\n}\n\n.sa-auth .sa-otp {\n display: flex;\n gap: 0.5rem;\n justify-content: center;\n margin: 0.75rem 0;\n}\n\n.sa-auth .sa-otp-input {\n width: 2.75rem;\n height: 3rem;\n text-align: center;\n font-size: 1.25rem;\n color: inherit;\n background-color: var(--seamless-surface-raised, #4b5563);\n border: 1px solid var(--seamless-border, #d1d5db);\n border-radius: 0.375rem;\n}\n\n.sa-auth .sa-timer {\n font-size: 0.75rem;\n color: var(--seamless-warning, #facc15);\n}\n\n.sa-auth .sa-identifier {\n margin: 0.75rem auto;\n padding: 0.25rem 0.75rem;\n width: fit-content;\n border-radius: 999px;\n background: var(--seamless-surface-raised, #4b5563);\n}\n\n.sa-auth .sa-center {\n text-align: center;\n}\n\n.sa-auth .sa-spinner {\n width: 2rem;\n height: 2rem;\n margin: 1rem auto;\n border: 3px solid var(--seamless-border, rgba(255, 255, 255, 0.2));\n border-top-color: var(--seamless-accent, #3b82f6);\n border-radius: 50%;\n animation: sa-spin 0.9s linear infinite;\n}\n\n@keyframes sa-spin {\n to {\n transform: rotate(360deg);\n }\n}\n\n@media (prefers-reduced-motion: reduce) {\n .sa-auth .sa-spinner {\n animation: none;\n }\n}\n",null,null,null,null,null,null,null,null,null,null,null,null,null,null],"names":["STYLE_ID","SaAuthLayout","defineComponent","name","props","card","type","Boolean","default","setup","slots","styles","options","useSeamlessAuth","onMounted","inject","nonce","document","getElementById","style","createElement","id","textContent","head","prepend","installStyles","h","class","action","title","subtext","onClick","SaFallbackOptions","identifier","String","required","loginMethods","Array","offerEmailOtp","offerPasskeyRetry","emits","emit","computed","fallbackSignInOptions","emailOtp","passkeyRetry","offered","value","hasFallbackSignInOption","magicLink","phoneOtp","authRoutePaths","login","passkeyLogin","verifyPhoneOtp","verifyEmailOtp","verifyMagicLink","oauthCallback","registerPasskey","magicLinkSent","authRouteName","screen","useAuthNavigation","router","useRouter","auth","toScreen","state","push","toApp","path","signedInPath","toLocation","browserPath","base","history","replace","inApp","startsWith","slice","length","absoluteUrl","URL","resolve","href","window","location","origin","toString","dropQuery","currentRoute","query","hash","SaOAuthProviderButtons","redirectUri","undefined","navigation","providers","ref","error","async","data","listOAuthProviders","map","provider","key","providerId","result","startOAuthSignIn","actions","oauthRedirect","ports","select","valueOf","event","target","SaLogin","mode","hasSignedInBefore","watch","seen","email","identifierError","emailError","formError","showFallbackOptions","submitting","canSubmit","isValidEmail","isValidPhoneNumber","submitHint","loadLoginMethods","checkPasskeySupport","validateIdentifier","validateEmail","submit","preventDefault","registerWithEmail","client","passkeySupported","configuredMethods","Promise","all","step","beginSignIn","kind","message","passkeyFailed","PASSKEY_SIGN_IN_FAILED","retryPasskey","handlePasskeyLogin","sendMagicLink","requestMagicLink","sendEmailOtp","requestLoginEmailOtp","flow","sendPhoneOtp","requestLoginPhoneOtp","onSubmit","for","autocomplete","placeholder","onInput","onBlur","onMagicLink","onEmailOtp","onPhoneOtp","onPasskeyRetry","disabled","role","SaMagicLinkSent","cooldown","MAGIC_LINK_RESEND_COOLDOWN_SECONDS","timer","stopWatching","setInterval","Math","max","watchMagicLink","refreshSession","onSignedIn","onBeforeUnmount","clearInterval","resend","SaOAuthCallback","route","useRoute","params","URLSearchParams","set","outcome","completeOAuthCallback","destination","returnTo","SaOtpInput","modelValue","Number","boxes","chars","from","_","i","focus","index","write","next","join","fill","input","incoming","otpCharacters","forEach","char","offset","min","onPaste","clipboardData","getData","el","inputmode","maxlength","box","typed","isOtpCharacter","onKeydown","SaPasskeyLogin","signIn","SaRegisterPasskey","finish","safeReturnPath","status","canSkip","hasNonPasskeyLoginMethod","register","attachment","enrollPasskey","finishWithoutPasskey","busy","passkeySupportLoading","loginMethodsLoading","SaVerifyMagicLink","tokenParam","token","prompt","decision","confirmError","redirect","active","clearTimeout","held","getMagicLinkConfirmation","magicLinkConfirmationPrompt","finishMagicLinkSignIn","setTimeout","renderConfirmation","asking","confirmMagicLinkSignIn","confirm","COPY","subtitle","label","resent","phone","SaVerifyOtp","channel","copy","code","resendMessage","loading","secondsLeft","OTP_LIFETIME_SECONDS","requestOtp","otpResendFailedMessage","verifyOtp","formatCountdown","OTP_LENGTH","requireAuth","whenSettled","isAuthenticated","redirectTo","loginPath","roles","hasScopedRole","forbiddenRedirectTo","requireGuest","authGuard","guestGuard","createSeamlessAuthRoutes","basePath","pathOf","component"],"mappings":"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"}