mailsentry-auth 0.1.1 → 0.1.4

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/dist/index.js CHANGED
@@ -83,8 +83,8 @@ var AuthEventType = /* @__PURE__ */ ((AuthEventType3) => {
83
83
  return AuthEventType3;
84
84
  })(AuthEventType || {});
85
85
  var PageType = /* @__PURE__ */ ((PageType3) => {
86
- PageType3["LOGIN"] = "/login";
87
- PageType3["DASHBOARD"] = "/dashboard";
86
+ PageType3["LOGIN"] = "login";
87
+ PageType3["DASHBOARD"] = "dashboard";
88
88
  PageType3["HOME"] = "/";
89
89
  return PageType3;
90
90
  })(PageType || {});
@@ -92,30 +92,30 @@ var NavigationAction = /* @__PURE__ */ ((NavigationAction2) => {
92
92
  NavigationAction2["NONE"] = "none";
93
93
  NavigationAction2["REDIRECT"] = "redirect";
94
94
  NavigationAction2["MODAL"] = "modal";
95
+ NavigationAction2["CURRENT"] = "current";
95
96
  return NavigationAction2;
96
97
  })(NavigationAction || {});
97
98
  var PageTypePatterns = {
98
- ["/login" /* LOGIN */]: "/login" /* LOGIN */,
99
- ["/dashboard" /* DASHBOARD */]: "/dashboard" /* DASHBOARD */,
100
- ["/" /* HOME */]: "/" /* HOME */
99
+ ["login" /* LOGIN */]: "login" /* LOGIN */,
100
+ ["dashboard" /* DASHBOARD */]: "dashboard" /* DASHBOARD */
101
101
  };
102
102
  var CrossTabBehaviorConfig = {
103
- ["/login" /* LOGIN */]: {
104
- ["auth.logged_in" /* LoggedIn */]: { action: "redirect" /* REDIRECT */, target: "/dashboard" /* DASHBOARD */ },
103
+ ["login" /* LOGIN */]: {
104
+ ["auth.logged_in" /* LoggedIn */]: { action: "redirect" /* REDIRECT */, target: "dashboard" /* DASHBOARD */ },
105
105
  ["auth.logged_out" /* LoggedOut */]: { action: "none" /* NONE */ },
106
106
  ["auth.email_verified" /* EmailVerified */]: { action: "none" /* NONE */ },
107
107
  ["auth.signin_required_modal" /* SignInRequiredModal */]: { action: "none" /* NONE */ }
108
108
  },
109
- ["/dashboard" /* DASHBOARD */]: {
110
- ["auth.logged_in" /* LoggedIn */]: { action: "modal" /* MODAL */ },
111
- ["auth.logged_out" /* LoggedOut */]: { action: "redirect" /* REDIRECT */, target: "/dashboard" /* DASHBOARD */ },
112
- ["auth.email_verified" /* EmailVerified */]: { action: "modal" /* MODAL */ },
113
- ["auth.signin_required_modal" /* SignInRequiredModal */]: { action: "none" /* NONE */ }
109
+ ["dashboard" /* DASHBOARD */]: {
110
+ ["auth.logged_in" /* LoggedIn */]: { action: "current" /* CURRENT */ },
111
+ ["auth.logged_out" /* LoggedOut */]: { action: "current" /* CURRENT */ },
112
+ ["auth.email_verified" /* EmailVerified */]: { action: "current" /* CURRENT */ },
113
+ ["auth.signin_required_modal" /* SignInRequiredModal */]: { action: "current" /* CURRENT */ }
114
114
  },
115
115
  ["/" /* HOME */]: {
116
- ["auth.logged_in" /* LoggedIn */]: { action: "modal" /* MODAL */ },
117
- ["auth.logged_out" /* LoggedOut */]: { action: "redirect" /* REDIRECT */, target: "/" /* HOME */ },
118
- ["auth.email_verified" /* EmailVerified */]: { action: "modal" /* MODAL */ },
116
+ ["auth.logged_in" /* LoggedIn */]: { action: "none" /* NONE */ },
117
+ ["auth.logged_out" /* LoggedOut */]: { action: "none" /* NONE */ },
118
+ ["auth.email_verified" /* EmailVerified */]: { action: "none" /* NONE */ },
119
119
  ["auth.signin_required_modal" /* SignInRequiredModal */]: { action: "none" /* NONE */ }
120
120
  }
121
121
  };
@@ -254,13 +254,32 @@ var getVerificationField = (codeLength = 5, options = {}) => ({
254
254
 
255
255
  // src/config/middleware.ts
256
256
  var MiddlewareConfig = class {
257
+ /**
258
+ * Get the base domain from environment or use default
259
+ */
260
+ static getBaseDomain() {
261
+ return process.env.NEXT_PUBLIC_BASE_DOMAIN || "cutly.io";
262
+ }
263
+ /**
264
+ * Get the protocol based on environment
265
+ */
266
+ static getProtocol() {
267
+ return process.env.NODE_ENV === "production" ? "https" : "http";
268
+ }
269
+ /**
270
+ * Get the dashboard subdomain URL
271
+ */
272
+ static getDashboardUrl(path = "") {
273
+ return `${this.getProtocol()}://${this.SUBDOMAINS.DASHBOARD}.${this.getBaseDomain()}${path}`;
274
+ }
257
275
  };
258
- // Protected routes
259
- MiddlewareConfig.PROTECTED_ROUTES = {
260
- DASHBOARD: "/"
276
+ // Subdomain configuration
277
+ MiddlewareConfig.SUBDOMAINS = {
278
+ DASHBOARD: "dashboard"
261
279
  };
262
- // Auth routes
263
- MiddlewareConfig.AUTH_ROUTES = {
280
+ // Routes
281
+ MiddlewareConfig.ROUTES = {
282
+ ROOT: "/",
264
283
  LOGIN: "/login"
265
284
  };
266
285
  // HTTP methods to process
@@ -268,7 +287,8 @@ MiddlewareConfig.ALLOWED_METHODS = ["GET", "HEAD"];
268
287
  // Query parameters
269
288
  MiddlewareConfig.QUERY_PARAMS = {
270
289
  LOGIN_REQUIRED: "sign_in_required",
271
- AUTH_CHECKED: "auth_checked"
290
+ AUTH_CHECKED: "auth_checked",
291
+ REDIRECT_URL: "redirect_url"
272
292
  };
273
293
  // Query parameter values
274
294
  MiddlewareConfig.QUERY_VALUES = {
@@ -276,8 +296,7 @@ MiddlewareConfig.QUERY_VALUES = {
276
296
  AUTH_CHECKED: "1"
277
297
  };
278
298
  var middlewareMatcher = [
279
- "/((?!api|_next/static|_next/image|_next/webpack-hmr|favicon.ico|.*\\.(?:svg|png|jpg|jpeg|gif|webp|ico|css|js)$).*)",
280
- "/login"
299
+ "/((?!api|_next/static|_next/image|_next/webpack-hmr|favicon.ico|.*\\.(?:svg|png|jpg|jpeg|gif|webp|ico|css|js)$).*)"
281
300
  ];
282
301
  var config = {
283
302
  matcher: middlewareMatcher
@@ -401,12 +420,18 @@ var _CookieUtils = class _CookieUtils {
401
420
  static getRefreshTokenKey() {
402
421
  return process.env.AUTH_REFRESH_TOKEN_KEY || "auth_refresh_token";
403
422
  }
404
- // Use current domain in development
405
423
  /**
406
424
  * Get root domain for subdomain support
425
+ * Must match the domain used by backend when setting cookies
407
426
  */
408
427
  static getRootDomain() {
409
- if (typeof window === "undefined") return void 0;
428
+ if (typeof window === "undefined") {
429
+ const baseDomain = process.env.NEXT_PUBLIC_BASE_DOMAIN;
430
+ if (baseDomain && process.env.NODE_ENV === "production") {
431
+ return `.${baseDomain}`;
432
+ }
433
+ return void 0;
434
+ }
410
435
  const hostname = window.location.hostname;
411
436
  if (hostname === "localhost" || hostname === "127.0.0.1") {
412
437
  return void 0;
@@ -420,13 +445,15 @@ var _CookieUtils = class _CookieUtils {
420
445
  }
421
446
  return void 0;
422
447
  }
448
+ // Use current domain in development
423
449
  /**
424
450
  * Get common cookie options
425
451
  */
426
452
  static getCookieOptions() {
427
453
  return {
428
454
  path: "/",
429
- sameSite: "strict",
455
+ sameSite: "lax",
456
+ // Changed from 'strict' to 'lax' for cross-subdomain
430
457
  secure: process.env.NODE_ENV === "production",
431
458
  // Only secure in production
432
459
  domain: this.COOKIE_DOMAIN
@@ -516,18 +543,26 @@ var _CookieUtils = class _CookieUtils {
516
543
  }
517
544
  /**
518
545
  * Clear all authentication cookies (client-side only)
546
+ * Clears cookies from both current domain and root domain
519
547
  */
520
548
  static clearAuthCookies() {
521
549
  if (this.isServerSide()) {
522
550
  console.warn("clearAuthCookies called on server side - use server actions instead");
523
551
  return;
524
552
  }
525
- const removeOptions = {
553
+ const accessKey = this.getAccessTokenKey();
554
+ const refreshKey = this.getRefreshTokenKey();
555
+ const rootDomainOptions = {
526
556
  path: "/",
527
557
  domain: this.COOKIE_DOMAIN
528
558
  };
529
- api.remove(this.getAccessTokenKey(), removeOptions);
530
- api.remove(this.getRefreshTokenKey(), removeOptions);
559
+ api.remove(accessKey, rootDomainOptions);
560
+ api.remove(refreshKey, rootDomainOptions);
561
+ const currentDomainOptions = {
562
+ path: "/"
563
+ };
564
+ api.remove(accessKey, currentDomainOptions);
565
+ api.remove(refreshKey, currentDomainOptions);
531
566
  }
532
567
  /**
533
568
  * Check if cookies are supported/enabled (client-side only)
@@ -594,18 +629,21 @@ var _CookieUtils = class _CookieUtils {
594
629
  return {
595
630
  error: "Server-side rendering - no domain info available",
596
631
  environment: process.env.NODE_ENV || "unknown",
632
+ cookieDomain: this.COOKIE_DOMAIN || "undefined",
633
+ baseDomain: process.env.NEXT_PUBLIC_BASE_DOMAIN || "undefined",
597
634
  recommendation: "Use server actions for server-side cookie access"
598
635
  };
599
636
  }
600
637
  return {
601
638
  hostname: window.location.hostname,
602
- domain: this.COOKIE_DOMAIN || "current domain",
639
+ cookieDomain: this.COOKIE_DOMAIN || "current domain",
603
640
  environment: process.env.NODE_ENV || "unknown",
604
- protocol: window.location.protocol
641
+ protocol: window.location.protocol,
642
+ sameSite: "lax"
605
643
  };
606
644
  }
607
645
  };
608
- // Domain configuration
646
+ // Domain configuration - computed once
609
647
  _CookieUtils.COOKIE_DOMAIN = process.env.NODE_ENV === "production" ? _CookieUtils.getRootDomain() : void 0;
610
648
  var CookieUtils = _CookieUtils;
611
649
 
@@ -744,18 +782,53 @@ var BroadcastChannelEventBus = class _BroadcastChannelEventBus {
744
782
  }
745
783
  };
746
784
 
785
+ // src/services/utils/url-utils.ts
786
+ var UrlUtils = class {
787
+ /**
788
+ * Extract subdomain from hostname or URL
789
+ * Example: "dashboard.cutly.io" -> "dashboard"
790
+ * Example: "dashboard.localhost" -> "dashboard"
791
+ */
792
+ static getSubdomain(url) {
793
+ try {
794
+ const domain = new URL(`http://${url}`).hostname;
795
+ const parts = domain.split(".");
796
+ if (parts.length < 2 || domain === "localhost" || /^\d{1,3}(\.\d{1,3}){3}/.test(domain) || domain.startsWith(MiddlewareConfig.getBaseDomain())) {
797
+ return null;
798
+ }
799
+ return parts[0] || null;
800
+ } catch (e) {
801
+ return null;
802
+ }
803
+ }
804
+ /**
805
+ * Check if URL has auth-related query parameters
806
+ */
807
+ static hasAuthParams(url) {
808
+ return url.includes(MiddlewareConfig.QUERY_PARAMS.AUTH_CHECKED);
809
+ }
810
+ };
811
+
747
812
  // src/services/utils/cross-tab-behavior-handler.ts
748
813
  var CrossTabBehaviorHandler = class {
749
814
  /**
750
- * Get current page type based on pathname using pattern matching
815
+ * Get current page type using object lookup pattern
751
816
  */
752
817
  static getCurrentPageType() {
753
- var _a, _b;
818
+ var _a;
754
819
  if (typeof window === "undefined") return "/" /* HOME */;
755
- const pathname = window.location.pathname;
756
- return (_b = (_a = Object.entries(PageTypePatterns).find(
757
- ([pattern]) => pathname.includes(pattern)
758
- )) == null ? void 0 : _a[1]) != null ? _b : "/" /* HOME */;
820
+ try {
821
+ const pathname = window.location.pathname;
822
+ const subdomain = UrlUtils.getSubdomain(window.location.hostname);
823
+ const pageTypeMatchers = {
824
+ ["login" /* LOGIN */]: pathname === MiddlewareConfig.ROUTES.LOGIN,
825
+ ["dashboard" /* DASHBOARD */]: subdomain === MiddlewareConfig.SUBDOMAINS.DASHBOARD
826
+ };
827
+ const matchedPageType = (_a = Object.entries(pageTypeMatchers).find(([, matches]) => matches)) == null ? void 0 : _a[0];
828
+ return matchedPageType != null ? matchedPageType : "dashboard" /* DASHBOARD */;
829
+ } catch (e) {
830
+ return "dashboard" /* DASHBOARD */;
831
+ }
759
832
  }
760
833
  /**
761
834
  * Get the action configuration for current route and event
@@ -766,18 +839,12 @@ var CrossTabBehaviorHandler = class {
766
839
  }
767
840
  /**
768
841
  * Check if current route requires redirect for given event
842
+ * Returns PageType to redirect to, or null if no redirect needed
769
843
  */
770
844
  static shouldRedirect(currentPageType, eventType) {
771
845
  const action = this.getAction(currentPageType, eventType);
772
846
  return action.action === "redirect" /* REDIRECT */ ? action.target : null;
773
847
  }
774
- /**
775
- * Check if current route should show modal for given event
776
- */
777
- static shouldShowModal(currentPageType, eventType) {
778
- const action = this.getAction(currentPageType, eventType);
779
- return action.action === "modal" /* MODAL */;
780
- }
781
848
  };
782
849
 
783
850
  // src/services/auth/manager/token-manager.ts
@@ -2315,6 +2382,13 @@ var useAuthEventBus = ({ onLoggedOut, onLoggedIn } = {}) => {
2315
2382
  window.location.replace(target);
2316
2383
  }
2317
2384
  },
2385
+ ["current" /* CURRENT */]: () => {
2386
+ const isAuthAction = e.type === "auth.logged_in" /* LoggedIn */ || e.type === "auth.logged_out" /* LoggedOut */;
2387
+ const hasParams = UrlUtils.hasAuthParams(window.location.href);
2388
+ if (isAuthAction || !hasParams) {
2389
+ window.location.reload();
2390
+ }
2391
+ },
2318
2392
  ["modal" /* MODAL */]: () => {
2319
2393
  if (e.type === "auth.logged_in" /* LoggedIn */) {
2320
2394
  window.location.replace(window.location.href);
@@ -2988,7 +3062,8 @@ var CrossTabDemo = () => {
2988
3062
 
2989
3063
 
2990
3064
 
2991
- exports.AUTH_ENDPOINTS = AUTH_ENDPOINTS; exports.AlertDisplay = AlertDisplay; exports.AuthEventType = AuthEventType; exports.AuthFlowContainer = AuthFlowContainer; exports.AuthFlowModal = AuthFlowModal; exports.AuthFlowStep = AuthFlowStep; exports.AuthInitializer = AuthInitializer; exports.AuthOrchestrator = AuthOrchestrator; exports.AuthOrchestratorFactory = AuthOrchestratorFactory; exports.AuthResultFactory = AuthResultFactory; exports.AuthService = AuthService; exports.AuthenticatedState = AuthenticatedState; exports.AuthenticationStatusContext = AuthenticationStatusContext; exports.BaseErrorHandler = BaseErrorHandler; exports.BaseEventBus = BaseEventBus; exports.BaseForm = BaseForm; exports.BaseService = BaseService; exports.BroadcastChannelEventBus = BroadcastChannelEventBus; exports.Channel = Channel; exports.CookieUtils = CookieUtils; exports.CrossTabBehaviorConfig = CrossTabBehaviorConfig; exports.CrossTabBehaviorHandler = CrossTabBehaviorHandler; exports.CrossTabDemo = CrossTabDemo; exports.DevelopmentLogger = DevelopmentLogger; exports.EMAIL_SUBMISSION_NAVIGATION = EMAIL_SUBMISSION_NAVIGATION; exports.EmailStep = EmailStep; exports.EndpointBuilder = EndpointBuilder; exports.ExistingUserLoginStrategy = ExistingUserLoginStrategy; exports.FormFields = FormFields; exports.FormHeader = FormHeader; exports.GenericErrorHandler = GenericErrorHandler; exports.HttpClient = HttpClient; exports.HttpMethod = HttpMethod; exports.LocalStorageUtils = LocalStorageUtils; exports.LoggerFactory = LoggerFactory; exports.LoginFlowStrategyFactory = LoginFlowStrategyFactory; exports.MiddlewareConfig = MiddlewareConfig; exports.NavigationAction = NavigationAction; exports.NetworkErrorHandler = NetworkErrorHandler; exports.NextAction = NextAction; exports.PASSWORD_SUBMISSION_NAVIGATION = PASSWORD_SUBMISSION_NAVIGATION; exports.PageType = PageType; exports.PageTypePatterns = PageTypePatterns; exports.PasswordStep = PasswordStep; exports.ProductionLogger = ProductionLogger; exports.ProfileStateRenderer = ProfileStateRenderer; exports.ProfileUIState = ProfileUIState; exports.RoleType = RoleType; exports.SignupFlowStrategy = SignupFlowStrategy; exports.TokenManager = TokenManager; exports.UnauthenticatedState = UnauthenticatedState; exports.UserStorageManager = UserStorageManager; exports.VERIFICATION_SUBMISSION_NAVIGATION = VERIFICATION_SUBMISSION_NAVIGATION; exports.ValidationErrorHandler = ValidationErrorHandler; exports.VerificationStep = VerificationStep; exports.config = config; exports.createAuthSteps = createAuthSteps; exports.createPropsFactoryRegistry = createPropsFactoryRegistry; exports.createStepRegistry = createStepRegistry; exports.getAuthPageStepMessage = getAuthPageStepMessage; exports.getEmailField = getEmailField; exports.getEmailStepComponent = getEmailStepComponent; exports.getPasswordField = getPasswordField; exports.getPasswordStepComponent = getPasswordStepComponent; exports.getStepForEmailSubmission = getStepForEmailSubmission; exports.getStepForPasswordSubmission = getStepForPasswordSubmission; exports.getStepForVerificationSubmission = getStepForVerificationSubmission; exports.getStepProgressMessage = getStepProgressMessage; exports.getVerificationField = getVerificationField; exports.getVerificationStepComponent = getVerificationStepComponent; exports.middlewareMatcher = middlewareMatcher; exports.useAuth = useAuth; exports.useAuthActionHandler = useAuthActionHandler; exports.useAuthEventBus = useAuthEventBus; exports.useAuthFlowModal = useAuthFlowModal; exports.useAuthInitializer = useAuthInitializer; exports.useIsAuthenticated = useIsAuthenticated; exports.useLogout = useLogout; exports.useRefreshUser = useRefreshUser; exports.useSharedEventBus = useSharedEventBus; exports.useSignInRequiredParams = useSignInRequiredParams; exports.useStepRegistry = useStepRegistry; exports.useStepRenderer = useStepRenderer; exports.useStepper = useStepper; exports.useUser = useUser; exports.useUserActions = useUserActions; exports.useUserData = useUserData; exports.useUserError = useUserError; exports.useUserLoading = useUserLoading; exports.useUserProfile = useUserProfile; exports.useUserStore = useUserStore; exports.userSelectors = userSelectors;
3065
+
3066
+ exports.AUTH_ENDPOINTS = AUTH_ENDPOINTS; exports.AlertDisplay = AlertDisplay; exports.AuthEventType = AuthEventType; exports.AuthFlowContainer = AuthFlowContainer; exports.AuthFlowModal = AuthFlowModal; exports.AuthFlowStep = AuthFlowStep; exports.AuthInitializer = AuthInitializer; exports.AuthOrchestrator = AuthOrchestrator; exports.AuthOrchestratorFactory = AuthOrchestratorFactory; exports.AuthResultFactory = AuthResultFactory; exports.AuthService = AuthService; exports.AuthenticatedState = AuthenticatedState; exports.AuthenticationStatusContext = AuthenticationStatusContext; exports.BaseErrorHandler = BaseErrorHandler; exports.BaseEventBus = BaseEventBus; exports.BaseForm = BaseForm; exports.BaseService = BaseService; exports.BroadcastChannelEventBus = BroadcastChannelEventBus; exports.Channel = Channel; exports.CookieUtils = CookieUtils; exports.CrossTabBehaviorConfig = CrossTabBehaviorConfig; exports.CrossTabBehaviorHandler = CrossTabBehaviorHandler; exports.CrossTabDemo = CrossTabDemo; exports.DevelopmentLogger = DevelopmentLogger; exports.EMAIL_SUBMISSION_NAVIGATION = EMAIL_SUBMISSION_NAVIGATION; exports.EmailStep = EmailStep; exports.EndpointBuilder = EndpointBuilder; exports.ExistingUserLoginStrategy = ExistingUserLoginStrategy; exports.FormFields = FormFields; exports.FormHeader = FormHeader; exports.GenericErrorHandler = GenericErrorHandler; exports.HttpClient = HttpClient; exports.HttpMethod = HttpMethod; exports.LocalStorageUtils = LocalStorageUtils; exports.LoggerFactory = LoggerFactory; exports.LoginFlowStrategyFactory = LoginFlowStrategyFactory; exports.MiddlewareConfig = MiddlewareConfig; exports.NavigationAction = NavigationAction; exports.NetworkErrorHandler = NetworkErrorHandler; exports.NextAction = NextAction; exports.PASSWORD_SUBMISSION_NAVIGATION = PASSWORD_SUBMISSION_NAVIGATION; exports.PageType = PageType; exports.PageTypePatterns = PageTypePatterns; exports.PasswordStep = PasswordStep; exports.ProductionLogger = ProductionLogger; exports.ProfileStateRenderer = ProfileStateRenderer; exports.ProfileUIState = ProfileUIState; exports.RoleType = RoleType; exports.SignupFlowStrategy = SignupFlowStrategy; exports.TokenManager = TokenManager; exports.UnauthenticatedState = UnauthenticatedState; exports.UrlUtils = UrlUtils; exports.UserStorageManager = UserStorageManager; exports.VERIFICATION_SUBMISSION_NAVIGATION = VERIFICATION_SUBMISSION_NAVIGATION; exports.ValidationErrorHandler = ValidationErrorHandler; exports.VerificationStep = VerificationStep; exports.config = config; exports.createAuthSteps = createAuthSteps; exports.createPropsFactoryRegistry = createPropsFactoryRegistry; exports.createStepRegistry = createStepRegistry; exports.getAuthPageStepMessage = getAuthPageStepMessage; exports.getEmailField = getEmailField; exports.getEmailStepComponent = getEmailStepComponent; exports.getPasswordField = getPasswordField; exports.getPasswordStepComponent = getPasswordStepComponent; exports.getStepForEmailSubmission = getStepForEmailSubmission; exports.getStepForPasswordSubmission = getStepForPasswordSubmission; exports.getStepForVerificationSubmission = getStepForVerificationSubmission; exports.getStepProgressMessage = getStepProgressMessage; exports.getVerificationField = getVerificationField; exports.getVerificationStepComponent = getVerificationStepComponent; exports.middlewareMatcher = middlewareMatcher; exports.useAuth = useAuth; exports.useAuthActionHandler = useAuthActionHandler; exports.useAuthEventBus = useAuthEventBus; exports.useAuthFlowModal = useAuthFlowModal; exports.useAuthInitializer = useAuthInitializer; exports.useIsAuthenticated = useIsAuthenticated; exports.useLogout = useLogout; exports.useRefreshUser = useRefreshUser; exports.useSharedEventBus = useSharedEventBus; exports.useSignInRequiredParams = useSignInRequiredParams; exports.useStepRegistry = useStepRegistry; exports.useStepRenderer = useStepRenderer; exports.useStepper = useStepper; exports.useUser = useUser; exports.useUserActions = useUserActions; exports.useUserData = useUserData; exports.useUserError = useUserError; exports.useUserLoading = useUserLoading; exports.useUserProfile = useUserProfile; exports.useUserStore = useUserStore; exports.userSelectors = userSelectors;
2992
3067
  /*! Bundled license information:
2993
3068
 
2994
3069
  js-cookie/dist/js.cookie.mjs:
package/dist/index.mjs CHANGED
@@ -83,8 +83,8 @@ var AuthEventType = /* @__PURE__ */ ((AuthEventType3) => {
83
83
  return AuthEventType3;
84
84
  })(AuthEventType || {});
85
85
  var PageType = /* @__PURE__ */ ((PageType3) => {
86
- PageType3["LOGIN"] = "/login";
87
- PageType3["DASHBOARD"] = "/dashboard";
86
+ PageType3["LOGIN"] = "login";
87
+ PageType3["DASHBOARD"] = "dashboard";
88
88
  PageType3["HOME"] = "/";
89
89
  return PageType3;
90
90
  })(PageType || {});
@@ -92,30 +92,30 @@ var NavigationAction = /* @__PURE__ */ ((NavigationAction2) => {
92
92
  NavigationAction2["NONE"] = "none";
93
93
  NavigationAction2["REDIRECT"] = "redirect";
94
94
  NavigationAction2["MODAL"] = "modal";
95
+ NavigationAction2["CURRENT"] = "current";
95
96
  return NavigationAction2;
96
97
  })(NavigationAction || {});
97
98
  var PageTypePatterns = {
98
- ["/login" /* LOGIN */]: "/login" /* LOGIN */,
99
- ["/dashboard" /* DASHBOARD */]: "/dashboard" /* DASHBOARD */,
100
- ["/" /* HOME */]: "/" /* HOME */
99
+ ["login" /* LOGIN */]: "login" /* LOGIN */,
100
+ ["dashboard" /* DASHBOARD */]: "dashboard" /* DASHBOARD */
101
101
  };
102
102
  var CrossTabBehaviorConfig = {
103
- ["/login" /* LOGIN */]: {
104
- ["auth.logged_in" /* LoggedIn */]: { action: "redirect" /* REDIRECT */, target: "/dashboard" /* DASHBOARD */ },
103
+ ["login" /* LOGIN */]: {
104
+ ["auth.logged_in" /* LoggedIn */]: { action: "redirect" /* REDIRECT */, target: "dashboard" /* DASHBOARD */ },
105
105
  ["auth.logged_out" /* LoggedOut */]: { action: "none" /* NONE */ },
106
106
  ["auth.email_verified" /* EmailVerified */]: { action: "none" /* NONE */ },
107
107
  ["auth.signin_required_modal" /* SignInRequiredModal */]: { action: "none" /* NONE */ }
108
108
  },
109
- ["/dashboard" /* DASHBOARD */]: {
110
- ["auth.logged_in" /* LoggedIn */]: { action: "modal" /* MODAL */ },
111
- ["auth.logged_out" /* LoggedOut */]: { action: "redirect" /* REDIRECT */, target: "/dashboard" /* DASHBOARD */ },
112
- ["auth.email_verified" /* EmailVerified */]: { action: "modal" /* MODAL */ },
113
- ["auth.signin_required_modal" /* SignInRequiredModal */]: { action: "none" /* NONE */ }
109
+ ["dashboard" /* DASHBOARD */]: {
110
+ ["auth.logged_in" /* LoggedIn */]: { action: "current" /* CURRENT */ },
111
+ ["auth.logged_out" /* LoggedOut */]: { action: "current" /* CURRENT */ },
112
+ ["auth.email_verified" /* EmailVerified */]: { action: "current" /* CURRENT */ },
113
+ ["auth.signin_required_modal" /* SignInRequiredModal */]: { action: "current" /* CURRENT */ }
114
114
  },
115
115
  ["/" /* HOME */]: {
116
- ["auth.logged_in" /* LoggedIn */]: { action: "modal" /* MODAL */ },
117
- ["auth.logged_out" /* LoggedOut */]: { action: "redirect" /* REDIRECT */, target: "/" /* HOME */ },
118
- ["auth.email_verified" /* EmailVerified */]: { action: "modal" /* MODAL */ },
116
+ ["auth.logged_in" /* LoggedIn */]: { action: "none" /* NONE */ },
117
+ ["auth.logged_out" /* LoggedOut */]: { action: "none" /* NONE */ },
118
+ ["auth.email_verified" /* EmailVerified */]: { action: "none" /* NONE */ },
119
119
  ["auth.signin_required_modal" /* SignInRequiredModal */]: { action: "none" /* NONE */ }
120
120
  }
121
121
  };
@@ -254,13 +254,32 @@ var getVerificationField = (codeLength = 5, options = {}) => ({
254
254
 
255
255
  // src/config/middleware.ts
256
256
  var MiddlewareConfig = class {
257
+ /**
258
+ * Get the base domain from environment or use default
259
+ */
260
+ static getBaseDomain() {
261
+ return process.env.NEXT_PUBLIC_BASE_DOMAIN || "cutly.io";
262
+ }
263
+ /**
264
+ * Get the protocol based on environment
265
+ */
266
+ static getProtocol() {
267
+ return process.env.NODE_ENV === "production" ? "https" : "http";
268
+ }
269
+ /**
270
+ * Get the dashboard subdomain URL
271
+ */
272
+ static getDashboardUrl(path = "") {
273
+ return `${this.getProtocol()}://${this.SUBDOMAINS.DASHBOARD}.${this.getBaseDomain()}${path}`;
274
+ }
257
275
  };
258
- // Protected routes
259
- MiddlewareConfig.PROTECTED_ROUTES = {
260
- DASHBOARD: "/"
276
+ // Subdomain configuration
277
+ MiddlewareConfig.SUBDOMAINS = {
278
+ DASHBOARD: "dashboard"
261
279
  };
262
- // Auth routes
263
- MiddlewareConfig.AUTH_ROUTES = {
280
+ // Routes
281
+ MiddlewareConfig.ROUTES = {
282
+ ROOT: "/",
264
283
  LOGIN: "/login"
265
284
  };
266
285
  // HTTP methods to process
@@ -268,7 +287,8 @@ MiddlewareConfig.ALLOWED_METHODS = ["GET", "HEAD"];
268
287
  // Query parameters
269
288
  MiddlewareConfig.QUERY_PARAMS = {
270
289
  LOGIN_REQUIRED: "sign_in_required",
271
- AUTH_CHECKED: "auth_checked"
290
+ AUTH_CHECKED: "auth_checked",
291
+ REDIRECT_URL: "redirect_url"
272
292
  };
273
293
  // Query parameter values
274
294
  MiddlewareConfig.QUERY_VALUES = {
@@ -276,8 +296,7 @@ MiddlewareConfig.QUERY_VALUES = {
276
296
  AUTH_CHECKED: "1"
277
297
  };
278
298
  var middlewareMatcher = [
279
- "/((?!api|_next/static|_next/image|_next/webpack-hmr|favicon.ico|.*\\.(?:svg|png|jpg|jpeg|gif|webp|ico|css|js)$).*)",
280
- "/login"
299
+ "/((?!api|_next/static|_next/image|_next/webpack-hmr|favicon.ico|.*\\.(?:svg|png|jpg|jpeg|gif|webp|ico|css|js)$).*)"
281
300
  ];
282
301
  var config = {
283
302
  matcher: middlewareMatcher
@@ -401,12 +420,18 @@ var _CookieUtils = class _CookieUtils {
401
420
  static getRefreshTokenKey() {
402
421
  return process.env.AUTH_REFRESH_TOKEN_KEY || "auth_refresh_token";
403
422
  }
404
- // Use current domain in development
405
423
  /**
406
424
  * Get root domain for subdomain support
425
+ * Must match the domain used by backend when setting cookies
407
426
  */
408
427
  static getRootDomain() {
409
- if (typeof window === "undefined") return void 0;
428
+ if (typeof window === "undefined") {
429
+ const baseDomain = process.env.NEXT_PUBLIC_BASE_DOMAIN;
430
+ if (baseDomain && process.env.NODE_ENV === "production") {
431
+ return `.${baseDomain}`;
432
+ }
433
+ return void 0;
434
+ }
410
435
  const hostname = window.location.hostname;
411
436
  if (hostname === "localhost" || hostname === "127.0.0.1") {
412
437
  return void 0;
@@ -420,13 +445,15 @@ var _CookieUtils = class _CookieUtils {
420
445
  }
421
446
  return void 0;
422
447
  }
448
+ // Use current domain in development
423
449
  /**
424
450
  * Get common cookie options
425
451
  */
426
452
  static getCookieOptions() {
427
453
  return {
428
454
  path: "/",
429
- sameSite: "strict",
455
+ sameSite: "lax",
456
+ // Changed from 'strict' to 'lax' for cross-subdomain
430
457
  secure: process.env.NODE_ENV === "production",
431
458
  // Only secure in production
432
459
  domain: this.COOKIE_DOMAIN
@@ -516,18 +543,26 @@ var _CookieUtils = class _CookieUtils {
516
543
  }
517
544
  /**
518
545
  * Clear all authentication cookies (client-side only)
546
+ * Clears cookies from both current domain and root domain
519
547
  */
520
548
  static clearAuthCookies() {
521
549
  if (this.isServerSide()) {
522
550
  console.warn("clearAuthCookies called on server side - use server actions instead");
523
551
  return;
524
552
  }
525
- const removeOptions = {
553
+ const accessKey = this.getAccessTokenKey();
554
+ const refreshKey = this.getRefreshTokenKey();
555
+ const rootDomainOptions = {
526
556
  path: "/",
527
557
  domain: this.COOKIE_DOMAIN
528
558
  };
529
- api.remove(this.getAccessTokenKey(), removeOptions);
530
- api.remove(this.getRefreshTokenKey(), removeOptions);
559
+ api.remove(accessKey, rootDomainOptions);
560
+ api.remove(refreshKey, rootDomainOptions);
561
+ const currentDomainOptions = {
562
+ path: "/"
563
+ };
564
+ api.remove(accessKey, currentDomainOptions);
565
+ api.remove(refreshKey, currentDomainOptions);
531
566
  }
532
567
  /**
533
568
  * Check if cookies are supported/enabled (client-side only)
@@ -594,18 +629,21 @@ var _CookieUtils = class _CookieUtils {
594
629
  return {
595
630
  error: "Server-side rendering - no domain info available",
596
631
  environment: process.env.NODE_ENV || "unknown",
632
+ cookieDomain: this.COOKIE_DOMAIN || "undefined",
633
+ baseDomain: process.env.NEXT_PUBLIC_BASE_DOMAIN || "undefined",
597
634
  recommendation: "Use server actions for server-side cookie access"
598
635
  };
599
636
  }
600
637
  return {
601
638
  hostname: window.location.hostname,
602
- domain: this.COOKIE_DOMAIN || "current domain",
639
+ cookieDomain: this.COOKIE_DOMAIN || "current domain",
603
640
  environment: process.env.NODE_ENV || "unknown",
604
- protocol: window.location.protocol
641
+ protocol: window.location.protocol,
642
+ sameSite: "lax"
605
643
  };
606
644
  }
607
645
  };
608
- // Domain configuration
646
+ // Domain configuration - computed once
609
647
  _CookieUtils.COOKIE_DOMAIN = process.env.NODE_ENV === "production" ? _CookieUtils.getRootDomain() : void 0;
610
648
  var CookieUtils = _CookieUtils;
611
649
 
@@ -744,18 +782,53 @@ var BroadcastChannelEventBus = class _BroadcastChannelEventBus {
744
782
  }
745
783
  };
746
784
 
785
+ // src/services/utils/url-utils.ts
786
+ var UrlUtils = class {
787
+ /**
788
+ * Extract subdomain from hostname or URL
789
+ * Example: "dashboard.cutly.io" -> "dashboard"
790
+ * Example: "dashboard.localhost" -> "dashboard"
791
+ */
792
+ static getSubdomain(url) {
793
+ try {
794
+ const domain = new URL(`http://${url}`).hostname;
795
+ const parts = domain.split(".");
796
+ if (parts.length < 2 || domain === "localhost" || /^\d{1,3}(\.\d{1,3}){3}/.test(domain) || domain.startsWith(MiddlewareConfig.getBaseDomain())) {
797
+ return null;
798
+ }
799
+ return parts[0] || null;
800
+ } catch (e) {
801
+ return null;
802
+ }
803
+ }
804
+ /**
805
+ * Check if URL has auth-related query parameters
806
+ */
807
+ static hasAuthParams(url) {
808
+ return url.includes(MiddlewareConfig.QUERY_PARAMS.AUTH_CHECKED);
809
+ }
810
+ };
811
+
747
812
  // src/services/utils/cross-tab-behavior-handler.ts
748
813
  var CrossTabBehaviorHandler = class {
749
814
  /**
750
- * Get current page type based on pathname using pattern matching
815
+ * Get current page type using object lookup pattern
751
816
  */
752
817
  static getCurrentPageType() {
753
- var _a, _b;
818
+ var _a;
754
819
  if (typeof window === "undefined") return "/" /* HOME */;
755
- const pathname = window.location.pathname;
756
- return (_b = (_a = Object.entries(PageTypePatterns).find(
757
- ([pattern]) => pathname.includes(pattern)
758
- )) == null ? void 0 : _a[1]) != null ? _b : "/" /* HOME */;
820
+ try {
821
+ const pathname = window.location.pathname;
822
+ const subdomain = UrlUtils.getSubdomain(window.location.hostname);
823
+ const pageTypeMatchers = {
824
+ ["login" /* LOGIN */]: pathname === MiddlewareConfig.ROUTES.LOGIN,
825
+ ["dashboard" /* DASHBOARD */]: subdomain === MiddlewareConfig.SUBDOMAINS.DASHBOARD
826
+ };
827
+ const matchedPageType = (_a = Object.entries(pageTypeMatchers).find(([, matches]) => matches)) == null ? void 0 : _a[0];
828
+ return matchedPageType != null ? matchedPageType : "dashboard" /* DASHBOARD */;
829
+ } catch (e) {
830
+ return "dashboard" /* DASHBOARD */;
831
+ }
759
832
  }
760
833
  /**
761
834
  * Get the action configuration for current route and event
@@ -766,18 +839,12 @@ var CrossTabBehaviorHandler = class {
766
839
  }
767
840
  /**
768
841
  * Check if current route requires redirect for given event
842
+ * Returns PageType to redirect to, or null if no redirect needed
769
843
  */
770
844
  static shouldRedirect(currentPageType, eventType) {
771
845
  const action = this.getAction(currentPageType, eventType);
772
846
  return action.action === "redirect" /* REDIRECT */ ? action.target : null;
773
847
  }
774
- /**
775
- * Check if current route should show modal for given event
776
- */
777
- static shouldShowModal(currentPageType, eventType) {
778
- const action = this.getAction(currentPageType, eventType);
779
- return action.action === "modal" /* MODAL */;
780
- }
781
848
  };
782
849
 
783
850
  // src/services/auth/manager/token-manager.ts
@@ -2315,6 +2382,13 @@ var useAuthEventBus = ({ onLoggedOut, onLoggedIn } = {}) => {
2315
2382
  window.location.replace(target);
2316
2383
  }
2317
2384
  },
2385
+ ["current" /* CURRENT */]: () => {
2386
+ const isAuthAction = e.type === "auth.logged_in" /* LoggedIn */ || e.type === "auth.logged_out" /* LoggedOut */;
2387
+ const hasParams = UrlUtils.hasAuthParams(window.location.href);
2388
+ if (isAuthAction || !hasParams) {
2389
+ window.location.reload();
2390
+ }
2391
+ },
2318
2392
  ["modal" /* MODAL */]: () => {
2319
2393
  if (e.type === "auth.logged_in" /* LoggedIn */) {
2320
2394
  window.location.replace(window.location.href);
@@ -2947,6 +3021,7 @@ export {
2947
3021
  SignupFlowStrategy,
2948
3022
  TokenManager,
2949
3023
  UnauthenticatedState,
3024
+ UrlUtils,
2950
3025
  UserStorageManager,
2951
3026
  VERIFICATION_SUBMISSION_NAVIGATION,
2952
3027
  ValidationErrorHandler,
@@ -1,27 +1,22 @@
1
1
  import { NextRequest, NextResponse } from 'next/server';
2
2
 
3
3
  /**
4
- * Middleware matcher patterns - exported separately for static analysis
5
- * Pattern includes:
6
- * - / (home route and all other routes for authentication protection)
7
- * - /login route (for authenticated user redirection)
8
- * Excludes: API routes, Next.js internals, static assets, and file extensions
4
+ * Middleware matcher patterns
5
+ * Matches all routes except API routes, Next.js internals, and static assets
9
6
  */
10
- declare const middlewareMatcher: readonly ["/((?!api|_next/static|_next/image|_next/webpack-hmr|favicon.ico|.*\\.(?:svg|png|jpg|jpeg|gif|webp|ico|css|js)$).*)", "/login"];
7
+ declare const middlewareMatcher: readonly ["/((?!api|_next/static|_next/image|_next/webpack-hmr|favicon.ico|.*\\.(?:svg|png|jpg|jpeg|gif|webp|ico|css|js)$).*)"];
11
8
  /**
12
- * Middleware configuration - runs on all routes (including home) and login page
9
+ * Middleware configuration
13
10
  */
14
11
  declare const config: {
15
- matcher: readonly ["/((?!api|_next/static|_next/image|_next/webpack-hmr|favicon.ico|.*\\.(?:svg|png|jpg|jpeg|gif|webp|ico|css|js)$).*)", "/login"];
12
+ matcher: readonly ["/((?!api|_next/static|_next/image|_next/webpack-hmr|favicon.ico|.*\\.(?:svg|png|jpg|jpeg|gif|webp|ico|css|js)$).*)"];
16
13
  };
17
14
 
18
15
  /**
19
- * Authentication middleware entry point
16
+ * Authentication middleware for subdomain-based routing
20
17
  * Chain order:
21
18
  * 1. MethodFilterHandler - filters HTTP methods (GET/HEAD only)
22
- * 2. RouteProtectionHandler - identifies protected routes
23
- * 3. LoginRedirectHandler - redirects authenticated users away from login
24
- * 4. AuthenticationHandler - validates JWT and handles query parameter cleanup
19
+ * 2. AuthenticationHandler - validates JWT and adds login params if needed
25
20
  */
26
21
  declare function middleware(req: NextRequest): Promise<NextResponse>;
27
22