mailsentry-auth 0.1.4 → 0.1.6

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.mjs CHANGED
@@ -83,34 +83,33 @@ var AuthEventType = /* @__PURE__ */ ((AuthEventType3) => {
83
83
  return AuthEventType3;
84
84
  })(AuthEventType || {});
85
85
  var PageType = /* @__PURE__ */ ((PageType3) => {
86
- PageType3["LOGIN"] = "login";
86
+ PageType3["LOGIN"] = "/login";
87
87
  PageType3["DASHBOARD"] = "dashboard";
88
88
  PageType3["HOME"] = "/";
89
89
  return PageType3;
90
90
  })(PageType || {});
91
91
  var NavigationAction = /* @__PURE__ */ ((NavigationAction2) => {
92
92
  NavigationAction2["NONE"] = "none";
93
- NavigationAction2["REDIRECT"] = "redirect";
94
- NavigationAction2["MODAL"] = "modal";
95
- NavigationAction2["CURRENT"] = "current";
93
+ NavigationAction2["RELOAD"] = "reload";
96
94
  return NavigationAction2;
97
95
  })(NavigationAction || {});
98
96
  var PageTypePatterns = {
99
- ["login" /* LOGIN */]: "login" /* LOGIN */,
100
- ["dashboard" /* DASHBOARD */]: "dashboard" /* DASHBOARD */
97
+ ["/login" /* LOGIN */]: "/login" /* LOGIN */,
98
+ ["dashboard" /* DASHBOARD */]: "dashboard" /* DASHBOARD */,
99
+ ["/" /* HOME */]: "/" /* HOME */
101
100
  };
102
101
  var CrossTabBehaviorConfig = {
103
- ["login" /* LOGIN */]: {
104
- ["auth.logged_in" /* LoggedIn */]: { action: "redirect" /* REDIRECT */, target: "dashboard" /* DASHBOARD */ },
105
- ["auth.logged_out" /* LoggedOut */]: { action: "none" /* NONE */ },
102
+ ["/login" /* LOGIN */]: {
103
+ ["auth.logged_in" /* LoggedIn */]: { action: "reload" /* RELOAD */ },
104
+ ["auth.logged_out" /* LoggedOut */]: { action: "reload" /* RELOAD */ },
106
105
  ["auth.email_verified" /* EmailVerified */]: { action: "none" /* NONE */ },
107
106
  ["auth.signin_required_modal" /* SignInRequiredModal */]: { action: "none" /* NONE */ }
108
107
  },
109
108
  ["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 */ }
109
+ ["auth.logged_in" /* LoggedIn */]: { action: "reload" /* RELOAD */ },
110
+ ["auth.logged_out" /* LoggedOut */]: { action: "reload" /* RELOAD */ },
111
+ ["auth.email_verified" /* EmailVerified */]: { action: "reload" /* RELOAD */ },
112
+ ["auth.signin_required_modal" /* SignInRequiredModal */]: { action: "none" /* NONE */ }
114
113
  },
115
114
  ["/" /* HOME */]: {
116
115
  ["auth.logged_in" /* LoggedIn */]: { action: "none" /* NONE */ },
@@ -253,12 +252,12 @@ var getVerificationField = (codeLength = 5, options = {}) => ({
253
252
  });
254
253
 
255
254
  // src/config/middleware.ts
256
- var MiddlewareConfig = class {
255
+ var _MiddlewareConfig = class _MiddlewareConfig {
257
256
  /**
258
257
  * Get the base domain from environment or use default
259
258
  */
260
259
  static getBaseDomain() {
261
- return process.env.NEXT_PUBLIC_BASE_DOMAIN || "cutly.io";
260
+ return process.env.NEXT_PUBLIC_BASE_DOMAIN;
262
261
  }
263
262
  /**
264
263
  * Get the protocol based on environment
@@ -266,35 +265,44 @@ var MiddlewareConfig = class {
266
265
  static getProtocol() {
267
266
  return process.env.NODE_ENV === "production" ? "https" : "http";
268
267
  }
269
- /**
270
- * Get the dashboard subdomain URL
271
- */
272
- static getDashboardUrl(path = "") {
273
- return `${this.getProtocol()}://${this.SUBDOMAINS.DASHBOARD}.${this.getBaseDomain()}${path}`;
274
- }
275
268
  };
276
- // Subdomain configuration
277
- MiddlewareConfig.SUBDOMAINS = {
278
- DASHBOARD: "dashboard"
279
- };
280
- // Routes
281
- MiddlewareConfig.ROUTES = {
282
- ROOT: "/",
283
- LOGIN: "/login"
269
+ // Common constants
270
+ _MiddlewareConfig.CONSTANTS = {
271
+ LOGIN_PATH: "/login",
272
+ DASHBOARD_SUBDOMAIN: "dashboard",
273
+ PUBLIC_PATH: "/public",
274
+ PUBLIC_API_PATH: "/api/public"
275
+ };
276
+ // Route Protection Configuration
277
+ // PATTERNS_TO_PROTECT: Routes that require authentication (whitelist approach recommended for security)
278
+ // PATTERNS_TO_EXCLUDE: Routes to explicitly exclude from protection (e.g., login page, public assets)
279
+ _MiddlewareConfig.PROTECTED_ROUTES = {
280
+ // Routes that MUST be protected
281
+ INCLUDE: [
282
+ "/"
283
+ // Protect everything by default (since dashboard.cutly.io/ is the root)
284
+ ],
285
+ // Routes that should NEVER be protected (public)
286
+ EXCLUDE: [
287
+ _MiddlewareConfig.CONSTANTS.LOGIN_PATH,
288
+ _MiddlewareConfig.CONSTANTS.PUBLIC_PATH,
289
+ _MiddlewareConfig.CONSTANTS.PUBLIC_API_PATH
290
+ ]
284
291
  };
285
292
  // HTTP methods to process
286
- MiddlewareConfig.ALLOWED_METHODS = ["GET", "HEAD"];
293
+ _MiddlewareConfig.ALLOWED_METHODS = ["GET", "HEAD"];
287
294
  // Query parameters
288
- MiddlewareConfig.QUERY_PARAMS = {
295
+ _MiddlewareConfig.QUERY_PARAMS = {
289
296
  LOGIN_REQUIRED: "sign_in_required",
290
297
  AUTH_CHECKED: "auth_checked",
291
298
  REDIRECT_URL: "redirect_url"
292
299
  };
293
300
  // Query parameter values
294
- MiddlewareConfig.QUERY_VALUES = {
301
+ _MiddlewareConfig.QUERY_VALUES = {
295
302
  LOGIN_REQUIRED: "true",
296
303
  AUTH_CHECKED: "1"
297
304
  };
305
+ var MiddlewareConfig = _MiddlewareConfig;
298
306
  var middlewareMatcher = [
299
307
  "/((?!api|_next/static|_next/image|_next/webpack-hmr|favicon.ico|.*\\.(?:svg|png|jpg|jpeg|gif|webp|ico|css|js)$).*)"
300
308
  ];
@@ -406,19 +414,55 @@ function init(converter, defaultAttributes) {
406
414
  }
407
415
  var api = init(defaultConverter, { path: "/" });
408
416
 
417
+ // src/services/utils/url-utils.ts
418
+ var UrlUtils = class {
419
+ /**
420
+ * Extract subdomain from hostname
421
+ * Example: "dashboard.cutly.io" -> "dashboard"
422
+ */
423
+ static getSubdomain(hostname) {
424
+ if (!hostname || /^\d{1,3}(\.\d{1,3}){3}/.test(hostname) || hostname.startsWith(MiddlewareConfig.getBaseDomain())) {
425
+ return null;
426
+ }
427
+ const parts = hostname.split(".");
428
+ return parts.length >= 2 ? parts[0] : null;
429
+ }
430
+ /**
431
+ * Get root domain for cookie scope
432
+ * Example: "dashboard.cutly.io" -> ".cutly.io"
433
+ * Example: "cutly.io" -> ".cutly.io"
434
+ */
435
+ static getRootDomain(hostname) {
436
+ if (!hostname || /^\d+\.\d+\.\d+\.\d+$/.test(hostname)) {
437
+ return null;
438
+ }
439
+ const parts = hostname.split(".");
440
+ if (parts.length >= 2) {
441
+ return `.${parts.slice(-2).join(".")}`;
442
+ }
443
+ return null;
444
+ }
445
+ /**
446
+ * Check if URL has auth-related query parameters
447
+ */
448
+ static hasAuthParams(url) {
449
+ return url.includes(MiddlewareConfig.QUERY_PARAMS.AUTH_CHECKED);
450
+ }
451
+ };
452
+
409
453
  // src/services/utils/cookie-utils.ts
410
454
  var _CookieUtils = class _CookieUtils {
411
455
  /**
412
- * Get the access token cookie key from environment variables
456
+ * Get the access token cookie key
413
457
  */
414
458
  static getAccessTokenKey() {
415
- return process.env.AUTH_ACCESS_TOKEN_KEY || "auth_access_token";
459
+ return "auth_access_token";
416
460
  }
417
461
  /**
418
- * Get the refresh token cookie key from environment variables
462
+ * Get the refresh token cookie key
419
463
  */
420
464
  static getRefreshTokenKey() {
421
- return process.env.AUTH_REFRESH_TOKEN_KEY || "auth_refresh_token";
465
+ return "auth_refresh_token";
422
466
  }
423
467
  /**
424
468
  * Get root domain for subdomain support
@@ -426,26 +470,10 @@ var _CookieUtils = class _CookieUtils {
426
470
  */
427
471
  static getRootDomain() {
428
472
  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
- }
435
- const hostname = window.location.hostname;
436
- if (hostname === "localhost" || hostname === "127.0.0.1") {
437
- return void 0;
438
- }
439
- if (/^\d+\.\d+\.\d+\.\d+$/.test(hostname)) {
440
473
  return void 0;
441
474
  }
442
- const parts = hostname.split(".");
443
- if (parts.length >= 2) {
444
- return `.${parts.slice(-2).join(".")}`;
445
- }
446
- return void 0;
475
+ return UrlUtils.getRootDomain(window.location.hostname) || void 0;
447
476
  }
448
- // Use current domain in development
449
477
  /**
450
478
  * Get common cookie options
451
479
  */
@@ -644,7 +672,7 @@ var _CookieUtils = class _CookieUtils {
644
672
  }
645
673
  };
646
674
  // Domain configuration - computed once
647
- _CookieUtils.COOKIE_DOMAIN = process.env.NODE_ENV === "production" ? _CookieUtils.getRootDomain() : void 0;
675
+ _CookieUtils.COOKIE_DOMAIN = _CookieUtils.getRootDomain();
648
676
  var CookieUtils = _CookieUtils;
649
677
 
650
678
  // src/services/utils/localstorage-utils.ts
@@ -782,33 +810,6 @@ var BroadcastChannelEventBus = class _BroadcastChannelEventBus {
782
810
  }
783
811
  };
784
812
 
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
-
812
813
  // src/services/utils/cross-tab-behavior-handler.ts
813
814
  var CrossTabBehaviorHandler = class {
814
815
  /**
@@ -821,8 +822,8 @@ var CrossTabBehaviorHandler = class {
821
822
  const pathname = window.location.pathname;
822
823
  const subdomain = UrlUtils.getSubdomain(window.location.hostname);
823
824
  const pageTypeMatchers = {
824
- ["login" /* LOGIN */]: pathname === MiddlewareConfig.ROUTES.LOGIN,
825
- ["dashboard" /* DASHBOARD */]: subdomain === MiddlewareConfig.SUBDOMAINS.DASHBOARD
825
+ ["/login" /* LOGIN */]: pathname === MiddlewareConfig.CONSTANTS.LOGIN_PATH,
826
+ ["dashboard" /* DASHBOARD */]: subdomain === MiddlewareConfig.CONSTANTS.DASHBOARD_SUBDOMAIN
826
827
  };
827
828
  const matchedPageType = (_a = Object.entries(pageTypeMatchers).find(([, matches]) => matches)) == null ? void 0 : _a[0];
828
829
  return matchedPageType != null ? matchedPageType : "dashboard" /* DASHBOARD */;
@@ -837,14 +838,6 @@ var CrossTabBehaviorHandler = class {
837
838
  var _a, _b;
838
839
  return (_b = (_a = CrossTabBehaviorConfig[currentPageType]) == null ? void 0 : _a[eventType]) != null ? _b : { action: "none" /* NONE */ };
839
840
  }
840
- /**
841
- * Check if current route requires redirect for given event
842
- * Returns PageType to redirect to, or null if no redirect needed
843
- */
844
- static shouldRedirect(currentPageType, eventType) {
845
- const action = this.getAction(currentPageType, eventType);
846
- return action.action === "redirect" /* REDIRECT */ ? action.target : null;
847
- }
848
841
  };
849
842
 
850
843
  // src/services/auth/manager/token-manager.ts
@@ -2376,23 +2369,8 @@ var useAuthEventBus = ({ onLoggedOut, onLoggedIn } = {}) => {
2376
2369
  const handler = eventHandlers[e.type];
2377
2370
  const action = CrossTabBehaviorHandler.getAction(currentPageType, e.type);
2378
2371
  const actionHandlers = {
2379
- ["redirect" /* REDIRECT */]: () => {
2380
- const target = CrossTabBehaviorHandler.shouldRedirect(currentPageType, e.type);
2381
- if (target) {
2382
- window.location.replace(target);
2383
- }
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
- },
2392
- ["modal" /* MODAL */]: () => {
2393
- if (e.type === "auth.logged_in" /* LoggedIn */) {
2394
- window.location.replace(window.location.href);
2395
- }
2372
+ ["reload" /* RELOAD */]: () => {
2373
+ window.location.replace(window.location.href);
2396
2374
  },
2397
2375
  ["none" /* NONE */]: () => {
2398
2376
  }
@@ -22,12 +22,12 @@ var __spreadProps = (a, b) => __defProps(a, __getOwnPropDescs(b));
22
22
  import { NextResponse } from "next/server";
23
23
 
24
24
  // src/config/middleware.ts
25
- var MiddlewareConfig = class {
25
+ var _MiddlewareConfig = class _MiddlewareConfig {
26
26
  /**
27
27
  * Get the base domain from environment or use default
28
28
  */
29
29
  static getBaseDomain() {
30
- return process.env.NEXT_PUBLIC_BASE_DOMAIN || "cutly.io";
30
+ return process.env.NEXT_PUBLIC_BASE_DOMAIN;
31
31
  }
32
32
  /**
33
33
  * Get the protocol based on environment
@@ -35,35 +35,44 @@ var MiddlewareConfig = class {
35
35
  static getProtocol() {
36
36
  return process.env.NODE_ENV === "production" ? "https" : "http";
37
37
  }
38
- /**
39
- * Get the dashboard subdomain URL
40
- */
41
- static getDashboardUrl(path = "") {
42
- return `${this.getProtocol()}://${this.SUBDOMAINS.DASHBOARD}.${this.getBaseDomain()}${path}`;
43
- }
44
38
  };
45
- // Subdomain configuration
46
- MiddlewareConfig.SUBDOMAINS = {
47
- DASHBOARD: "dashboard"
39
+ // Common constants
40
+ _MiddlewareConfig.CONSTANTS = {
41
+ LOGIN_PATH: "/login",
42
+ DASHBOARD_SUBDOMAIN: "dashboard",
43
+ PUBLIC_PATH: "/public",
44
+ PUBLIC_API_PATH: "/api/public"
48
45
  };
49
- // Routes
50
- MiddlewareConfig.ROUTES = {
51
- ROOT: "/",
52
- LOGIN: "/login"
46
+ // Route Protection Configuration
47
+ // PATTERNS_TO_PROTECT: Routes that require authentication (whitelist approach recommended for security)
48
+ // PATTERNS_TO_EXCLUDE: Routes to explicitly exclude from protection (e.g., login page, public assets)
49
+ _MiddlewareConfig.PROTECTED_ROUTES = {
50
+ // Routes that MUST be protected
51
+ INCLUDE: [
52
+ "/"
53
+ // Protect everything by default (since dashboard.cutly.io/ is the root)
54
+ ],
55
+ // Routes that should NEVER be protected (public)
56
+ EXCLUDE: [
57
+ _MiddlewareConfig.CONSTANTS.LOGIN_PATH,
58
+ _MiddlewareConfig.CONSTANTS.PUBLIC_PATH,
59
+ _MiddlewareConfig.CONSTANTS.PUBLIC_API_PATH
60
+ ]
53
61
  };
54
62
  // HTTP methods to process
55
- MiddlewareConfig.ALLOWED_METHODS = ["GET", "HEAD"];
63
+ _MiddlewareConfig.ALLOWED_METHODS = ["GET", "HEAD"];
56
64
  // Query parameters
57
- MiddlewareConfig.QUERY_PARAMS = {
65
+ _MiddlewareConfig.QUERY_PARAMS = {
58
66
  LOGIN_REQUIRED: "sign_in_required",
59
67
  AUTH_CHECKED: "auth_checked",
60
68
  REDIRECT_URL: "redirect_url"
61
69
  };
62
70
  // Query parameter values
63
- MiddlewareConfig.QUERY_VALUES = {
71
+ _MiddlewareConfig.QUERY_VALUES = {
64
72
  LOGIN_REQUIRED: "true",
65
73
  AUTH_CHECKED: "1"
66
74
  };
75
+ var MiddlewareConfig = _MiddlewareConfig;
67
76
  var middlewareMatcher = [
68
77
  "/((?!api|_next/static|_next/image|_next/webpack-hmr|favicon.ico|.*\\.(?:svg|png|jpg|jpeg|gif|webp|ico|css|js)$).*)"
69
78
  ];
@@ -73,18 +82,56 @@ var config = {
73
82
 
74
83
  // src/services/utils/cookie-utils.ts
75
84
  import Cookies from "js-cookie";
85
+
86
+ // src/services/utils/url-utils.ts
87
+ var UrlUtils = class {
88
+ /**
89
+ * Extract subdomain from hostname
90
+ * Example: "dashboard.cutly.io" -> "dashboard"
91
+ */
92
+ static getSubdomain(hostname) {
93
+ if (!hostname || /^\d{1,3}(\.\d{1,3}){3}/.test(hostname) || hostname.startsWith(MiddlewareConfig.getBaseDomain())) {
94
+ return null;
95
+ }
96
+ const parts = hostname.split(".");
97
+ return parts.length >= 2 ? parts[0] : null;
98
+ }
99
+ /**
100
+ * Get root domain for cookie scope
101
+ * Example: "dashboard.cutly.io" -> ".cutly.io"
102
+ * Example: "cutly.io" -> ".cutly.io"
103
+ */
104
+ static getRootDomain(hostname) {
105
+ if (!hostname || /^\d+\.\d+\.\d+\.\d+$/.test(hostname)) {
106
+ return null;
107
+ }
108
+ const parts = hostname.split(".");
109
+ if (parts.length >= 2) {
110
+ return `.${parts.slice(-2).join(".")}`;
111
+ }
112
+ return null;
113
+ }
114
+ /**
115
+ * Check if URL has auth-related query parameters
116
+ */
117
+ static hasAuthParams(url) {
118
+ return url.includes(MiddlewareConfig.QUERY_PARAMS.AUTH_CHECKED);
119
+ }
120
+ };
121
+
122
+ // src/services/utils/cookie-utils.ts
76
123
  var _CookieUtils = class _CookieUtils {
77
124
  /**
78
- * Get the access token cookie key from environment variables
125
+ * Get the access token cookie key
79
126
  */
80
127
  static getAccessTokenKey() {
81
- return process.env.AUTH_ACCESS_TOKEN_KEY || "auth_access_token";
128
+ return "auth_access_token";
82
129
  }
83
130
  /**
84
- * Get the refresh token cookie key from environment variables
131
+ * Get the refresh token cookie key
85
132
  */
86
133
  static getRefreshTokenKey() {
87
- return process.env.AUTH_REFRESH_TOKEN_KEY || "auth_refresh_token";
134
+ return "auth_refresh_token";
88
135
  }
89
136
  /**
90
137
  * Get root domain for subdomain support
@@ -92,26 +139,10 @@ var _CookieUtils = class _CookieUtils {
92
139
  */
93
140
  static getRootDomain() {
94
141
  if (typeof window === "undefined") {
95
- const baseDomain = process.env.NEXT_PUBLIC_BASE_DOMAIN;
96
- if (baseDomain && process.env.NODE_ENV === "production") {
97
- return `.${baseDomain}`;
98
- }
99
142
  return void 0;
100
143
  }
101
- const hostname = window.location.hostname;
102
- if (hostname === "localhost" || hostname === "127.0.0.1") {
103
- return void 0;
104
- }
105
- if (/^\d+\.\d+\.\d+\.\d+$/.test(hostname)) {
106
- return void 0;
107
- }
108
- const parts = hostname.split(".");
109
- if (parts.length >= 2) {
110
- return `.${parts.slice(-2).join(".")}`;
111
- }
112
- return void 0;
144
+ return UrlUtils.getRootDomain(window.location.hostname) || void 0;
113
145
  }
114
- // Use current domain in development
115
146
  /**
116
147
  * Get common cookie options
117
148
  */
@@ -310,7 +341,7 @@ var _CookieUtils = class _CookieUtils {
310
341
  }
311
342
  };
312
343
  // Domain configuration - computed once
313
- _CookieUtils.COOKIE_DOMAIN = process.env.NODE_ENV === "production" ? _CookieUtils.getRootDomain() : void 0;
344
+ _CookieUtils.COOKIE_DOMAIN = _CookieUtils.getRootDomain();
314
345
  var CookieUtils = _CookieUtils;
315
346
 
316
347
  // src/services/utils/localstorage-utils.ts
@@ -394,32 +425,33 @@ LocalStorageUtils.USER_PROFILE_STORAGE_KEY = "user_profile_data";
394
425
  LocalStorageUtils.USER_PROFILE_TIMESTAMP_KEY = "user_profile_timestamp";
395
426
  LocalStorageUtils.DEFAULT_CACHE_DURATION = 5 * 60 * 1e3;
396
427
 
397
- // src/services/utils/url-utils.ts
398
- var UrlUtils = class {
399
- /**
400
- * Extract subdomain from hostname or URL
401
- * Example: "dashboard.cutly.io" -> "dashboard"
402
- * Example: "dashboard.localhost" -> "dashboard"
403
- */
404
- static getSubdomain(url) {
405
- try {
406
- const domain = new URL(`http://${url}`).hostname;
407
- const parts = domain.split(".");
408
- if (parts.length < 2 || domain === "localhost" || /^\d{1,3}(\.\d{1,3}){3}/.test(domain) || domain.startsWith(MiddlewareConfig.getBaseDomain())) {
409
- return null;
410
- }
411
- return parts[0] || null;
412
- } catch (e) {
413
- return null;
414
- }
415
- }
416
- /**
417
- * Check if URL has auth-related query parameters
418
- */
419
- static hasAuthParams(url) {
420
- return url.includes(MiddlewareConfig.QUERY_PARAMS.AUTH_CHECKED);
421
- }
428
+ // src/config/auth-steps.tsx
429
+ import React2 from "react";
430
+ import {
431
+ MailOutlined,
432
+ LockOutlined,
433
+ CheckCircleOutlined
434
+ } from "@ant-design/icons";
435
+
436
+ // src/config/step-navigation.ts
437
+ var EMAIL_SUBMISSION_NAVIGATION = {
438
+ ["login-verification" /* LOGIN_VERIFICATION */]: "verification" /* VERIFICATION */,
439
+ ["login" /* LOGIN */]: "password" /* PASSWORD */,
440
+ ["signup" /* SIGNUP */]: "password" /* PASSWORD */
441
+ };
442
+ var PASSWORD_SUBMISSION_NAVIGATION = {
443
+ VERIFIED: "verification" /* VERIFICATION */,
444
+ UNVERIFIED: "verification" /* VERIFICATION */
422
445
  };
446
+ var VERIFICATION_SUBMISSION_NAVIGATION = {
447
+ SUCCESS: "verification" /* VERIFICATION */,
448
+ ERROR: "verification" /* VERIFICATION */
449
+ // Stay on verification step on error
450
+ };
451
+
452
+ // src/config/form-fields.tsx
453
+ import { Input } from "antd";
454
+ import { MailOutlined as MailOutlined2, LockOutlined as LockOutlined2, CheckCircleOutlined as CheckCircleOutlined2 } from "@ant-design/icons";
423
455
 
424
456
  // src/services/api/endpoints.ts
425
457
  var AUTH_ENDPOINTS = {
@@ -633,10 +665,19 @@ AuthenticationStatusContext.states = /* @__PURE__ */ new Map([
633
665
  // src/middlewares/handlers/base-middleware-handler.ts
634
666
  var BaseMiddlewareHandler = class {
635
667
  /**
636
- * Check if current request is on dashboard subdomain
668
+ * Check if current route requires authentication
669
+ * Uses inclusive (PROTECTED_ROUTES.INCLUDE) and exclusive (PROTECTED_ROUTES.EXCLUDE) lists
637
670
  */
638
- isDashboardSubdomain(hostname) {
639
- return UrlUtils.getSubdomain(hostname) === MiddlewareConfig.SUBDOMAINS.DASHBOARD;
671
+ requiresAuthentication(pathname) {
672
+ const isExcluded = MiddlewareConfig.PROTECTED_ROUTES.EXCLUDE.some(
673
+ (route) => pathname.startsWith(route) || pathname === route
674
+ );
675
+ if (isExcluded) {
676
+ return false;
677
+ }
678
+ return MiddlewareConfig.PROTECTED_ROUTES.INCLUDE.some(
679
+ (route) => pathname.startsWith(route) || pathname === route
680
+ );
640
681
  }
641
682
  /**
642
683
  * Check if user has both access and refresh tokens
@@ -647,11 +688,12 @@ var BaseMiddlewareHandler = class {
647
688
  }
648
689
  /**
649
690
  * Get authentication cookie keys from environment variables
691
+ * Now uses CookieUtils for consistent retrieval
650
692
  */
651
693
  getAuthCookieKeys() {
652
694
  return {
653
- accessTokenKey: process.env.AUTH_ACCESS_TOKEN_KEY || "",
654
- refreshTokenKey: process.env.AUTH_REFRESH_TOKEN_KEY || ""
695
+ accessTokenKey: CookieUtils.getAccessTokenKey(),
696
+ refreshTokenKey: CookieUtils.getRefreshTokenKey()
655
697
  };
656
698
  }
657
699
  /**
@@ -752,8 +794,8 @@ var MethodFilterHandler = class extends BaseMiddlewareHandler {
752
794
  // src/middlewares/handlers/authentication-handler.ts
753
795
  var AuthenticationHandler = class extends BaseMiddlewareHandler {
754
796
  async handle(context) {
755
- const { cookies, hostname } = context;
756
- if (!this.isDashboardSubdomain(hostname)) {
797
+ const { cookies, pathname } = context;
798
+ if (!this.requiresAuthentication(pathname)) {
757
799
  return this.continue();
758
800
  }
759
801
  const hasAuthCookies = this.hasAuthenticationCookies(cookies);
@@ -0,0 +1,86 @@
1
+ /**
2
+ * Cookie utility for managing authentication tokens with automatic SSR and client-side support
3
+ * Automatically chooses the right method based on environment
4
+ */
5
+ declare class CookieUtils {
6
+ /**
7
+ * Get the access token cookie key
8
+ */
9
+ static getAccessTokenKey(): string;
10
+ /**
11
+ * Get the refresh token cookie key
12
+ */
13
+ static getRefreshTokenKey(): string;
14
+ /**
15
+ * Get root domain for subdomain support
16
+ * Must match the domain used by backend when setting cookies
17
+ */
18
+ private static getRootDomain;
19
+ private static readonly COOKIE_DOMAIN;
20
+ /**
21
+ * Get common cookie options
22
+ */
23
+ private static getCookieOptions;
24
+ /**
25
+ * Check if running on client side
26
+ */
27
+ private static isClientSide;
28
+ /**
29
+ * Check if running on server side
30
+ */
31
+ private static isServerSide;
32
+ /**
33
+ * Dynamically import server action for server-side operations
34
+ */
35
+ private static getServerTokens;
36
+ /**
37
+ * Set access token in cookie (client-side only)
38
+ */
39
+ static setAccessToken(token: string): void;
40
+ /**
41
+ * Set refresh token in cookie (client-side only)
42
+ */
43
+ static setRefreshToken(token: string): void;
44
+ /**
45
+ * Get access token - automatically handles client/server side
46
+ */
47
+ static getAccessToken(): Promise<string | null>;
48
+ /**
49
+ * Get refresh token - automatically handles client/server side
50
+ */
51
+ static getRefreshToken(): Promise<string | null>;
52
+ /**
53
+ * Get both tokens - automatically handles client/server side
54
+ */
55
+ static getTokens(): Promise<{
56
+ accessToken: string | null;
57
+ refreshToken: string | null;
58
+ }>;
59
+ /**
60
+ * Clear all authentication cookies (client-side only)
61
+ * Clears cookies from both current domain and root domain
62
+ */
63
+ static clearAuthCookies(): void;
64
+ /**
65
+ * Check if cookies are supported/enabled (client-side only)
66
+ */
67
+ static areCookiesEnabled(): boolean;
68
+ /**
69
+ * Get all authentication cookies - automatically handles client/server side
70
+ */
71
+ static getAllAuthCookies(): Promise<Record<string, string>>;
72
+ /**
73
+ * Set multiple tokens at once (client-side only)
74
+ */
75
+ static setTokens(accessToken: string, refreshToken: string): void;
76
+ /**
77
+ * Check if user has valid tokens - automatically handles client/server side
78
+ */
79
+ static hasValidTokens(): Promise<boolean>;
80
+ /**
81
+ * Get current domain information for debugging
82
+ */
83
+ static getDomainInfo(): Record<string, string>;
84
+ }
85
+
86
+ export { CookieUtils };