mailsentry-auth 0.2.7 → 0.2.9

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
@@ -41,13 +41,6 @@ var HttpMethod = /* @__PURE__ */ ((HttpMethod2) => {
41
41
  return HttpMethod2;
42
42
  })(HttpMethod || {});
43
43
 
44
- // src/types/components/auth-flow.ts
45
- var AuthFlowVariant = /* @__PURE__ */ ((AuthFlowVariant2) => {
46
- AuthFlowVariant2["DEFAULT"] = "default";
47
- AuthFlowVariant2["WITH_IMAGE"] = "with_image";
48
- return AuthFlowVariant2;
49
- })(AuthFlowVariant || {});
50
-
51
44
  // src/types/components/profile.ts
52
45
  var ProfileUIState = /* @__PURE__ */ ((ProfileUIState2) => {
53
46
  ProfileUIState2["LOADING"] = "LOADING";
@@ -78,6 +71,12 @@ var RoleType = /* @__PURE__ */ ((RoleType2) => {
78
71
  RoleType2["ADMIN"] = "ADMIN";
79
72
  return RoleType2;
80
73
  })(RoleType || {});
74
+ var UserType = /* @__PURE__ */ ((UserType2) => {
75
+ UserType2["AUTHENTICATED"] = "AUTHENTICATED";
76
+ UserType2["PUBLIC"] = "PUBLIC";
77
+ UserType2["GUEST"] = "GUEST";
78
+ return UserType2;
79
+ })(UserType || {});
81
80
 
82
81
  // src/types/event-bus/event-bus.interface.ts
83
82
  var BaseEventBus = class {
@@ -91,11 +90,12 @@ var AuthEventType = /* @__PURE__ */ ((AuthEventType3) => {
91
90
  AuthEventType3["SignInRequiredModal"] = "auth.signin_required_modal";
92
91
  return AuthEventType3;
93
92
  })(AuthEventType || {});
94
- var PageType = /* @__PURE__ */ ((PageType4) => {
95
- PageType4["LOGIN"] = "/login";
96
- PageType4["DASHBOARD"] = "dashboard";
97
- PageType4["HOME"] = "/";
98
- return PageType4;
93
+ var PageType = /* @__PURE__ */ ((PageType3) => {
94
+ PageType3["LOGIN"] = "/login";
95
+ PageType3["DASHBOARD"] = "dashboard";
96
+ PageType3["HOME"] = "/";
97
+ PageType3["EXCLUDED"] = "excluded";
98
+ return PageType3;
99
99
  })(PageType || {});
100
100
  var NavigationAction = /* @__PURE__ */ ((NavigationAction2) => {
101
101
  NavigationAction2["NONE"] = "none";
@@ -126,6 +126,12 @@ var CrossTabBehaviorConfig = {
126
126
  ["auth.logged_out" /* LoggedOut */]: { action: "none" /* NONE */ },
127
127
  ["auth.email_verified" /* EmailVerified */]: { action: "none" /* NONE */ },
128
128
  ["auth.signin_required_modal" /* SignInRequiredModal */]: { action: "none" /* NONE */ }
129
+ },
130
+ ["excluded" /* EXCLUDED */]: {
131
+ ["auth.logged_in" /* LoggedIn */]: { action: "none" /* NONE */ },
132
+ ["auth.logged_out" /* LoggedOut */]: { action: "none" /* NONE */ },
133
+ ["auth.email_verified" /* EmailVerified */]: { action: "none" /* NONE */ },
134
+ ["auth.signin_required_modal" /* SignInRequiredModal */]: { action: "none" /* NONE */ }
129
135
  }
130
136
  };
131
137
 
@@ -772,10 +778,10 @@ var useStepRenderer = () => {
772
778
 
773
779
  // src/components/auth/auth-flow-container.tsx
774
780
  import React5, { useState as useState7 } from "react";
775
- import { Steps, Col, Button as Button5, Flex as Flex3, Row, Space as Space4 } from "antd";
781
+ import { Steps, Col, Button as Button5, Flex as Flex3, Row, Space as Space4, message } from "antd";
776
782
  import { ArrowLeftOutlined as ArrowLeftOutlined2 } from "@ant-design/icons";
777
- import Image from "next/image";
778
783
  import { cva } from "class-variance-authority";
784
+ import Image from "next/image";
779
785
 
780
786
  // src/hooks/useAuthActionHandler.ts
781
787
  import { useState as useState4, useCallback as useCallback2 } from "react";
@@ -803,8 +809,8 @@ var useAuthActionHandler = () => {
803
809
  const clearAll = useCallback2(() => {
804
810
  setState((prev) => __spreadProps(__spreadValues({}, prev), { error: null, success: null }));
805
811
  }, []);
806
- const setSuccess = useCallback2((message) => {
807
- setState((prev) => __spreadProps(__spreadValues({}, prev), { success: message, error: null }));
812
+ const setSuccess = useCallback2((message2) => {
813
+ setState((prev) => __spreadProps(__spreadValues({}, prev), { success: message2, error: null }));
808
814
  }, []);
809
815
  const setError = useCallback2((error) => {
810
816
  setState((prev) => __spreadProps(__spreadValues({}, prev), { error, success: null }));
@@ -1133,6 +1139,13 @@ var MiddlewareConfig = class {
1133
1139
  { hostPattern: null, pathPattern: this.CONSTANTS.LOGIN_PATH }
1134
1140
  ]);
1135
1141
  }
1142
+ /**
1143
+ * Get reload exclusion rules (routes that shouldn't auto-reload on login)
1144
+ * Format: "host:path" or "path"
1145
+ */
1146
+ static getReloadExclusionRules() {
1147
+ return this.parseRules(process.env.NEXT_PUBLIC_RELOAD_EXCLUSION_ROUTES, []);
1148
+ }
1136
1149
  /**
1137
1150
  * Generic parser for environment variables containing rule lists
1138
1151
  */
@@ -1613,7 +1626,11 @@ var CrossTabBehaviorHandler = class {
1613
1626
  if (typeof window === "undefined") return "/" /* HOME */;
1614
1627
  try {
1615
1628
  const pathname = window.location.pathname;
1629
+ const search = window.location.search;
1616
1630
  const subdomain = UrlUtils.getSubdomain(window.location.hostname);
1631
+ if (this.isReloadExcluded(pathname, search, subdomain)) {
1632
+ return "excluded" /* EXCLUDED */;
1633
+ }
1617
1634
  const pageTypeMatchers = {
1618
1635
  ["/login" /* LOGIN */]: pathname === MiddlewareConfig.CONSTANTS.LOGIN_PATH,
1619
1636
  ["dashboard" /* DASHBOARD */]: subdomain === MiddlewareConfig.CONSTANTS.DASHBOARD_SUBDOMAIN
@@ -1624,6 +1641,22 @@ var CrossTabBehaviorHandler = class {
1624
1641
  return "dashboard" /* DASHBOARD */;
1625
1642
  }
1626
1643
  }
1644
+ /**
1645
+ * Check if current route is excluded from automatic reload
1646
+ */
1647
+ static isReloadExcluded(pathname, search, subdomain) {
1648
+ return MiddlewareConfig.getReloadExclusionRules().some((rule) => {
1649
+ const hostMatch = !rule.hostPattern || subdomain === rule.hostPattern;
1650
+ if (!hostMatch) return false;
1651
+ const [patternPath, patternParam] = rule.pathPattern.split("?");
1652
+ const isPathMatch = patternPath === "*" || pathname === patternPath || pathname.startsWith(patternPath);
1653
+ if (!isPathMatch) return false;
1654
+ if (patternParam) {
1655
+ return new URLSearchParams(search).has(patternParam);
1656
+ }
1657
+ return true;
1658
+ });
1659
+ }
1627
1660
  /**
1628
1661
  * Get the action configuration for current route and event
1629
1662
  */
@@ -1828,6 +1861,33 @@ var TokenManager = class {
1828
1861
  }
1829
1862
  };
1830
1863
 
1864
+ // src/services/api/api-error-mapper.ts
1865
+ var API_ERROR_CODES = {
1866
+ // Auth Errors
1867
+ 5207: "The password you entered is incorrect. Please try again.",
1868
+ 5070: "Password must be strong. Please use a stronger password."
1869
+ };
1870
+ function getErrorMessage(code, defaultMessage = "An unexpected error occurred") {
1871
+ const numericCode = Number(code);
1872
+ return API_ERROR_CODES[numericCode] || defaultMessage;
1873
+ }
1874
+ function parseNestedApiError(data) {
1875
+ if (!data || typeof data !== "object") {
1876
+ return null;
1877
+ }
1878
+ const errorData = data;
1879
+ if (errorData.message && typeof errorData.message === "object" && "statusCode" in errorData.message) {
1880
+ const customCode = errorData.message.statusCode;
1881
+ const technicalMessage = errorData.message.message;
1882
+ return {
1883
+ code: customCode,
1884
+ message: getErrorMessage(customCode, technicalMessage),
1885
+ originalError: errorData
1886
+ };
1887
+ }
1888
+ return null;
1889
+ }
1890
+
1831
1891
  // src/services/api/base-service.ts
1832
1892
  var HttpClient = class {
1833
1893
  constructor(config2) {
@@ -1898,12 +1958,13 @@ var HttpClient = class {
1898
1958
  }
1899
1959
  };
1900
1960
  var ApiError = class extends Error {
1901
- constructor(message, status, statusText, apiError) {
1902
- super(message);
1903
- this.name = "ApiError";
1961
+ constructor(message2, status, statusText, apiError) {
1962
+ super(message2);
1963
+ this.message = message2;
1904
1964
  this.status = status;
1905
1965
  this.statusText = statusText;
1906
1966
  this.apiError = apiError;
1967
+ this.name = "ApiError";
1907
1968
  }
1908
1969
  };
1909
1970
  var BaseService = class {
@@ -1947,16 +2008,21 @@ var BaseService = class {
1947
2008
  */
1948
2009
  createApiErrorFromResponse(response) {
1949
2010
  const parsedError = this.tryParseApiErrorResponse(response.data);
1950
- if (parsedError) {
1951
- return parsedError;
1952
- }
1953
- return this.createGenericApiError(response);
2011
+ return parsedError || this.createGenericApiError(response);
1954
2012
  }
1955
2013
  /**
1956
2014
  * Try to parse API error response from response data
1957
2015
  */
1958
2016
  tryParseApiErrorResponse(data) {
1959
2017
  try {
2018
+ const nestedError = parseNestedApiError(data);
2019
+ if (nestedError) {
2020
+ return {
2021
+ message: nestedError.message,
2022
+ error: "ApiError",
2023
+ statusCode: nestedError.code
2024
+ };
2025
+ }
1960
2026
  const responseData = data;
1961
2027
  if (this.isValidApiErrorResponse(responseData)) {
1962
2028
  return __spreadValues({
@@ -1987,62 +2053,46 @@ var BaseService = class {
1987
2053
  };
1988
2054
  }
1989
2055
  /**
1990
- * GET request
2056
+ * Helper method for common request logic
1991
2057
  */
1992
- async get(endpoint, headers) {
2058
+ async executeRequest(method, endpoint, body, headers) {
1993
2059
  const response = await this.httpClient.request(endpoint, {
1994
- method: "GET" /* GET */,
2060
+ method,
1995
2061
  url: endpoint,
1996
- headers
2062
+ headers,
2063
+ body
1997
2064
  });
1998
2065
  return this.handleResponse(response);
1999
2066
  }
2067
+ /**
2068
+ * GET request
2069
+ */
2070
+ async get(endpoint, headers) {
2071
+ return this.executeRequest("GET" /* GET */, endpoint, void 0, headers);
2072
+ }
2000
2073
  /**
2001
2074
  * POST request
2002
2075
  */
2003
2076
  async post(endpoint, body, headers) {
2004
- const response = await this.httpClient.request(endpoint, {
2005
- method: "POST" /* POST */,
2006
- url: endpoint,
2007
- headers,
2008
- body
2009
- });
2010
- return this.handleResponse(response);
2077
+ return this.executeRequest("POST" /* POST */, endpoint, body, headers);
2011
2078
  }
2012
2079
  /**
2013
2080
  * PUT request
2014
2081
  */
2015
2082
  async put(endpoint, body, headers) {
2016
- const response = await this.httpClient.request(endpoint, {
2017
- method: "PUT" /* PUT */,
2018
- url: endpoint,
2019
- headers,
2020
- body
2021
- });
2022
- return this.handleResponse(response);
2083
+ return this.executeRequest("PUT" /* PUT */, endpoint, body, headers);
2023
2084
  }
2024
2085
  /**
2025
2086
  * DELETE request
2026
2087
  */
2027
2088
  async delete(endpoint, headers) {
2028
- const response = await this.httpClient.request(endpoint, {
2029
- method: "DELETE" /* DELETE */,
2030
- url: endpoint,
2031
- headers
2032
- });
2033
- return this.handleResponse(response);
2089
+ return this.executeRequest("DELETE" /* DELETE */, endpoint, void 0, headers);
2034
2090
  }
2035
2091
  /**
2036
2092
  * PATCH request
2037
2093
  */
2038
2094
  async patch(endpoint, body, headers) {
2039
- const response = await this.httpClient.request(endpoint, {
2040
- method: "PATCH" /* PATCH */,
2041
- url: endpoint,
2042
- headers,
2043
- body
2044
- });
2045
- return this.handleResponse(response);
2095
+ return this.executeRequest("PATCH" /* PATCH */, endpoint, body, headers);
2046
2096
  }
2047
2097
  };
2048
2098
 
@@ -2203,14 +2253,14 @@ var AuthResultFactory = class {
2203
2253
 
2204
2254
  // src/services/auth/patterns/logger/development-logger.ts
2205
2255
  var DevelopmentLogger = class {
2206
- log(message, data) {
2207
- console.log(message, data);
2256
+ log(message2, data) {
2257
+ console.log(message2, data);
2208
2258
  }
2209
- warn(message, data) {
2210
- console.warn(message, data);
2259
+ warn(message2, data) {
2260
+ console.warn(message2, data);
2211
2261
  }
2212
- error(message, data) {
2213
- console.error(message, data);
2262
+ error(message2, data) {
2263
+ console.error(message2, data);
2214
2264
  }
2215
2265
  };
2216
2266
 
@@ -2445,14 +2495,19 @@ var BaseErrorHandler = class {
2445
2495
  }
2446
2496
  };
2447
2497
 
2448
- // src/services/auth/patterns/chain/validation-error-handler.ts
2449
- var ValidationErrorHandler = class extends BaseErrorHandler {
2498
+ // src/services/auth/patterns/chain/api-error-handler.ts
2499
+ var ApiErrorHandler = class extends BaseErrorHandler {
2450
2500
  canHandle(error) {
2451
- return error instanceof Error && error.message.includes("validation");
2501
+ return error instanceof ApiError;
2452
2502
  }
2453
2503
  handleError(error, context) {
2454
- console.error(`${context} validation error:`, error);
2455
- return AuthResultFactory.createFailure(error);
2504
+ const apiError = error;
2505
+ console.error(`${context} API error:`, {
2506
+ message: apiError.message,
2507
+ status: apiError.status,
2508
+ code: apiError.apiError.statusCode
2509
+ });
2510
+ return AuthResultFactory.createFailure(apiError.message);
2456
2511
  }
2457
2512
  };
2458
2513
 
@@ -2467,17 +2522,6 @@ var NetworkErrorHandler = class extends BaseErrorHandler {
2467
2522
  }
2468
2523
  };
2469
2524
 
2470
- // src/services/auth/patterns/chain/generic-error-handler.ts
2471
- var GenericErrorHandler = class extends BaseErrorHandler {
2472
- canHandle() {
2473
- return true;
2474
- }
2475
- handleError(error, context) {
2476
- console.error(`${context} error:`, error);
2477
- return AuthResultFactory.createFailure(error);
2478
- }
2479
- };
2480
-
2481
2525
  // src/services/auth/auth-orchestrator.ts
2482
2526
  var AuthOrchestrator = class {
2483
2527
  constructor(authService, tokenManager) {
@@ -2492,11 +2536,10 @@ var AuthOrchestrator = class {
2492
2536
  * Setup Chain of Responsibility for error handling
2493
2537
  */
2494
2538
  setupErrorHandlerChain() {
2495
- const validationHandler = new ValidationErrorHandler();
2539
+ const apiHandler = new ApiErrorHandler();
2496
2540
  const networkHandler = new NetworkErrorHandler();
2497
- const genericHandler = new GenericErrorHandler();
2498
- validationHandler.setNext(networkHandler).setNext(genericHandler);
2499
- return validationHandler;
2541
+ apiHandler.setNext(networkHandler);
2542
+ return apiHandler;
2500
2543
  }
2501
2544
  /**
2502
2545
  * Validate that cookies are supported in the current environment
@@ -2605,7 +2648,7 @@ var AuthOrchestrator = class {
2605
2648
  if (isVerified) {
2606
2649
  return AuthResultFactory.createSuccess({ isVerified: true });
2607
2650
  }
2608
- return AuthResultFactory.createFailure("Email verification failed");
2651
+ return AuthResultFactory.createFailure("Your verification code is wrong");
2609
2652
  } catch (error) {
2610
2653
  return this.errorHandler.handle(error, "Email verification");
2611
2654
  }
@@ -2804,7 +2847,7 @@ function useSignInRequiredParams() {
2804
2847
  }
2805
2848
 
2806
2849
  // src/hooks/use-user.ts
2807
- import { useEffect as useEffect6 } from "react";
2850
+ import { useEffect as useEffect6, useMemo as useMemo6 } from "react";
2808
2851
 
2809
2852
  // src/store/user-store.ts
2810
2853
  import { create } from "zustand";
@@ -3054,12 +3097,19 @@ var useUserActions = () => {
3054
3097
  return userSelectors.useActions();
3055
3098
  };
3056
3099
  var useAuth = () => {
3057
- const isAuthenticated = userSelectors.useIsAuthenticated();
3058
- const isLoading = userSelectors.useIsLoading();
3059
- const error = userSelectors.useError();
3060
- const user = userSelectors.useUser();
3100
+ const { isAuthenticated, isLoading, error, user } = userSelectors.useUserState();
3101
+ const userType = useMemo6(() => {
3102
+ if (isAuthenticated) return "AUTHENTICATED" /* AUTHENTICATED */;
3103
+ if (isPublicUser(user == null ? void 0 : user.user)) return "PUBLIC" /* PUBLIC */;
3104
+ return "GUEST" /* GUEST */;
3105
+ }, [isAuthenticated, user]);
3061
3106
  return {
3062
- isAuthenticated,
3107
+ authStatus: {
3108
+ type: userType,
3109
+ isAuthenticated,
3110
+ isPublic: userType === "PUBLIC" /* PUBLIC */,
3111
+ isGuest: userType === "GUEST" /* GUEST */
3112
+ },
3063
3113
  isLoading,
3064
3114
  error,
3065
3115
  user
@@ -3200,12 +3250,11 @@ import { jsx as jsx12, jsxs as jsxs6 } from "react/jsx-runtime";
3200
3250
  var containerVariants = cva("w-full h-screen p-6 overflow-hidden", {
3201
3251
  variants: {
3202
3252
  layout: {
3203
- withImage: "",
3204
- fullWidth: "max-w-[600px] mx-auto"
3253
+ withImage: ""
3205
3254
  }
3206
3255
  },
3207
3256
  defaultVariants: {
3208
- layout: "fullWidth"
3257
+ layout: "withImage"
3209
3258
  }
3210
3259
  });
3211
3260
  var formContentVariants = cva("overflow-auto w-full", {
@@ -3228,11 +3277,8 @@ var imageContainerVariants = cva("h-screen overflow-hidden relative", {
3228
3277
  gradient: "purple"
3229
3278
  }
3230
3279
  });
3231
- function AuthFlowContainer({
3232
- variant = "default" /* DEFAULT */,
3233
- backgroundImage
3234
- }) {
3235
- const showRightSideImage = variant === "with_image" /* WITH_IMAGE */ && !!backgroundImage;
3280
+ function AuthFlowContainer({}) {
3281
+ const backgroundImage = process.env.NEXT_PUBLIC_AUTH_BACKGROUND_IMAGE || "";
3236
3282
  const authOrchestrator = AuthOrchestratorFactory.create();
3237
3283
  const eventBus = useSharedEventBus();
3238
3284
  const { state: actionState, executeAction, clearAll } = useAuthActionHandler();
@@ -3271,6 +3317,7 @@ function AuthFlowContainer({
3271
3317
  stepperActions.goToStep(nextStep);
3272
3318
  },
3273
3319
  onError: (error) => {
3320
+ message.error(error);
3274
3321
  console.error(error);
3275
3322
  }
3276
3323
  }
@@ -3310,6 +3357,7 @@ function AuthFlowContainer({
3310
3357
  (_a = actionPipeline.find((action) => action.condition())) == null ? void 0 : _a.execute();
3311
3358
  },
3312
3359
  onError: (error) => {
3360
+ message.error(error);
3313
3361
  console.error(error);
3314
3362
  }
3315
3363
  }
@@ -3327,6 +3375,7 @@ function AuthFlowContainer({
3327
3375
  setPassword("");
3328
3376
  },
3329
3377
  onError: (error) => {
3378
+ message.error(error);
3330
3379
  console.error(error);
3331
3380
  }
3332
3381
  }
@@ -3345,6 +3394,7 @@ function AuthFlowContainer({
3345
3394
  handleSuccess();
3346
3395
  },
3347
3396
  onError: (error) => {
3397
+ message.error(error);
3348
3398
  console.error(error);
3349
3399
  }
3350
3400
  }
@@ -3362,6 +3412,7 @@ function AuthFlowContainer({
3362
3412
  handleSuccess();
3363
3413
  },
3364
3414
  onError: (error) => {
3415
+ message.error(error);
3365
3416
  console.error(error);
3366
3417
  }
3367
3418
  }
@@ -3376,6 +3427,7 @@ function AuthFlowContainer({
3376
3427
  onSuccess: () => {
3377
3428
  },
3378
3429
  onError: (error) => {
3430
+ message.error(error);
3379
3431
  console.error(error);
3380
3432
  }
3381
3433
  }
@@ -3413,6 +3465,7 @@ function AuthFlowContainer({
3413
3465
  onSuccess: () => {
3414
3466
  },
3415
3467
  onError: (error) => {
3468
+ message.error(error);
3416
3469
  console.error(error);
3417
3470
  }
3418
3471
  }
@@ -3485,13 +3538,13 @@ function AuthFlowContainer({
3485
3538
  };
3486
3539
  }, [stepperState.currentStep, stepperActions, clearAll, goBackToHome]);
3487
3540
  return /* @__PURE__ */ jsxs6(Row, { className: "m-0 h-screen", children: [
3488
- /* @__PURE__ */ jsx12(Col, { xs: 24, lg: showRightSideImage ? 10 : 24, className: "flex flex-col", children: /* @__PURE__ */ jsxs6(
3541
+ /* @__PURE__ */ jsx12(Col, { xs: 24, lg: 10, className: "flex flex-col", children: /* @__PURE__ */ jsxs6(
3489
3542
  Flex3,
3490
3543
  {
3491
3544
  vertical: true,
3492
3545
  justify: "space-between",
3493
3546
  className: containerVariants({
3494
- layout: showRightSideImage ? "withImage" : "fullWidth"
3547
+ layout: "withImage"
3495
3548
  }),
3496
3549
  children: [
3497
3550
  config2.showBackToHome && /* @__PURE__ */ jsx12(Flex3, { justify: "flex-start", children: /* @__PURE__ */ jsx12(Button5, { onClick: topButton.onClick, shape: "round", size: "large", type: "primary", ghost: true, children: topButton.label }) }),
@@ -3522,7 +3575,7 @@ function AuthFlowContainer({
3522
3575
  ]
3523
3576
  }
3524
3577
  ) }),
3525
- showRightSideImage && /* @__PURE__ */ jsx12(Col, { xs: 0, lg: 14, className: imageContainerVariants(), children: /* @__PURE__ */ jsx12(Flex3, { justify: "center", align: "center", className: "absolute top-0 left-0 w-full h-full p-10", children: /* @__PURE__ */ jsx12(Space4, { className: "relative w-full h-full", children: /* @__PURE__ */ jsx12(
3578
+ /* @__PURE__ */ jsx12(Col, { xs: 0, lg: 14, className: imageContainerVariants(), children: /* @__PURE__ */ jsx12(Flex3, { justify: "center", align: "center", className: "absolute top-0 left-0 w-full h-full p-10", children: /* @__PURE__ */ jsx12(Space4, { className: "relative w-full h-full", children: backgroundImage && /* @__PURE__ */ jsx12(
3526
3579
  Image,
3527
3580
  {
3528
3581
  src: backgroundImage,
@@ -3538,17 +3591,14 @@ function AuthFlowContainer({
3538
3591
  // src/components/auth/auth-flow-modal.tsx
3539
3592
  import { Modal, Spin as Spin2 } from "antd";
3540
3593
  import { Fragment as Fragment4, jsx as jsx13, jsxs as jsxs7 } from "react/jsx-runtime";
3541
- function AuthFlowModal({
3542
- children,
3543
- variant = "default" /* DEFAULT */,
3544
- backgroundImage
3545
- }) {
3594
+ function AuthFlowModal({ children }) {
3546
3595
  const { isModalOpen, isInitialLoading } = useAuthFlowModal();
3547
3596
  if (isInitialLoading) {
3548
3597
  return /* @__PURE__ */ jsx13("div", { className: "min-h-screen flex items-center justify-center bg-gray-50", children: /* @__PURE__ */ jsx13(Spin2, { size: "large" }) });
3549
3598
  }
3550
3599
  return /* @__PURE__ */ jsxs7(Fragment4, { children: [
3551
- isModalOpen ? /* @__PURE__ */ jsx13("div", { className: "min-h-screen flex items-center justify-center bg-gray-50", children: /* @__PURE__ */ jsx13(Spin2, { size: "large" }) }) : children,
3600
+ isModalOpen ? /* @__PURE__ */ jsx13("div", { className: isModalOpen ? "hidden" : "", children }) : children,
3601
+ isModalOpen ? /* @__PURE__ */ jsx13("div", { className: "fixed inset-0 z-[999] min-h-screen flex items-center justify-center bg-gray-50", children: /* @__PURE__ */ jsx13(Spin2, { size: "large" }) }) : null,
3552
3602
  /* @__PURE__ */ jsx13(
3553
3603
  Modal,
3554
3604
  {
@@ -3560,7 +3610,8 @@ function AuthFlowModal({
3560
3610
  maskClosable: false,
3561
3611
  closable: false,
3562
3612
  className: "auth-flow-modal",
3563
- children: /* @__PURE__ */ jsx13(AuthFlowContainer, { variant, backgroundImage })
3613
+ zIndex: 1e3,
3614
+ children: /* @__PURE__ */ jsx13(AuthFlowContainer, {})
3564
3615
  }
3565
3616
  )
3566
3617
  ] });
@@ -3576,7 +3627,7 @@ var AuthInitializer = ({ children }) => {
3576
3627
  // src/components/profile/profile-state-renderer.tsx
3577
3628
  import { useState as useState8, useEffect as useEffect8 } from "react";
3578
3629
  import { Dropdown, Button as Button6 } from "antd";
3579
- import { MailOutlined, CrownOutlined, LogoutOutlined, UserOutlined } from "@ant-design/icons";
3630
+ import { MailOutlined, CrownOutlined, LogoutOutlined, UserOutlined, DashboardOutlined } from "@ant-design/icons";
3580
3631
  import { jsx as jsx15, jsxs as jsxs8 } from "react/jsx-runtime";
3581
3632
  var DefaultUnauthenticated = () => {
3582
3633
  const rootDomain = UrlUtils.getRootDomain(window.location.hostname);
@@ -3587,7 +3638,8 @@ var DefaultUnauthenticated = () => {
3587
3638
  var UNAUTHENTICATED_COMPONENT_MAP = {
3588
3639
  ["dashboard" /* DASHBOARD */]: DefaultUnauthenticated,
3589
3640
  ["/login" /* LOGIN */]: DefaultUnauthenticated,
3590
- ["/" /* HOME */]: DefaultUnauthenticated
3641
+ ["/" /* HOME */]: DefaultUnauthenticated,
3642
+ ["excluded" /* EXCLUDED */]: DefaultUnauthenticated
3591
3643
  };
3592
3644
  var useUnauthenticatedStrategy = () => {
3593
3645
  const [pageType, setPageType] = useState8("/" /* HOME */);
@@ -3622,6 +3674,11 @@ var AuthenticatedState2 = ({ user, onLogout }) => {
3622
3674
  /* @__PURE__ */ jsx15("div", { className: "font-medium", children: ((_c = (_b = user.user) == null ? void 0 : _b.role) == null ? void 0 : _c.name) || "N/A" })
3623
3675
  ] })
3624
3676
  },
3677
+ dashboard: {
3678
+ key: "dashboard",
3679
+ icon: /* @__PURE__ */ jsx15(DashboardOutlined, {}),
3680
+ label: /* @__PURE__ */ jsx15("a", { href: UrlUtils.getDashboardUrl(window.location), children: "Go to Dashboard" })
3681
+ },
3625
3682
  divider: {
3626
3683
  type: "divider"
3627
3684
  },
@@ -3633,7 +3690,7 @@ var AuthenticatedState2 = ({ user, onLogout }) => {
3633
3690
  }
3634
3691
  };
3635
3692
  const userInfoMenu = {
3636
- items: isPublic ? [menuItems.role, menuItems.divider] : [menuItems.email, menuItems.role, menuItems.divider, menuItems.logout]
3693
+ items: isPublic ? [menuItems.role, menuItems.divider] : [menuItems.email, menuItems.role, menuItems.divider, menuItems.dashboard, menuItems.logout]
3637
3694
  };
3638
3695
  return /* @__PURE__ */ jsx15(Dropdown, { menu: userInfoMenu, placement: "bottom", trigger: ["click"], children: /* @__PURE__ */ jsx15(Button6, { type: "primary", shape: "circle", size: "large", icon: /* @__PURE__ */ jsx15(UserOutlined, {}) }) });
3639
3696
  };
@@ -3654,7 +3711,8 @@ var getComponentProps = (state, user, callbacks) => {
3654
3711
  }
3655
3712
  };
3656
3713
  var ProfileStateRenderer = () => {
3657
- const { user, isLoading, isAuthenticated } = useAuth();
3714
+ const { user, isLoading, authStatus } = useAuth();
3715
+ const { isAuthenticated } = authStatus;
3658
3716
  const logout = useLogout();
3659
3717
  const currentState = resolveState(isLoading, isAuthenticated, user);
3660
3718
  const componentProps = getComponentProps(currentState, user, {
@@ -3678,7 +3736,8 @@ import { Fragment as Fragment6, jsx as jsx16, jsxs as jsxs9 } from "react/jsx-ru
3678
3736
  var { Title: Title3, Text: Text2, Paragraph: Paragraph2 } = Typography4;
3679
3737
  var CrossTabDemo = () => {
3680
3738
  var _a;
3681
- const { isAuthenticated, user } = useAuth();
3739
+ const { authStatus, user } = useAuth();
3740
+ const { isAuthenticated } = authStatus;
3682
3741
  const currentPageType = CrossTabBehaviorHandler.getCurrentPageType();
3683
3742
  return /* @__PURE__ */ jsx16(
3684
3743
  Card,
@@ -3839,11 +3898,11 @@ var getForgotPasswordField = (options = {}) => ({
3839
3898
  export {
3840
3899
  AUTH_ENDPOINTS,
3841
3900
  AlertDisplay,
3901
+ ApiErrorHandler,
3842
3902
  AuthEventType,
3843
3903
  AuthFlowContainer,
3844
3904
  AuthFlowModal,
3845
3905
  AuthFlowStep,
3846
- AuthFlowVariant,
3847
3906
  AuthInitializer,
3848
3907
  AuthOrchestrator,
3849
3908
  AuthOrchestratorFactory,
@@ -3869,7 +3928,6 @@ export {
3869
3928
  ExistingUserLoginStrategy,
3870
3929
  FormFields,
3871
3930
  FormHeader,
3872
- GenericErrorHandler,
3873
3931
  HttpClient,
3874
3932
  HttpMethod,
3875
3933
  LocalStorageUtils,
@@ -3897,8 +3955,8 @@ export {
3897
3955
  UrlCleanupHandler,
3898
3956
  UrlUtils,
3899
3957
  UserStorageManager,
3958
+ UserType,
3900
3959
  VERIFICATION_SUBMISSION_NAVIGATION,
3901
- ValidationErrorHandler,
3902
3960
  VerificationStep,
3903
3961
  config,
3904
3962
  createAuthSteps,
@@ -32,6 +32,13 @@ var MiddlewareConfig = class {
32
32
  { hostPattern: null, pathPattern: this.CONSTANTS.LOGIN_PATH }
33
33
  ]);
34
34
  }
35
+ /**
36
+ * Get reload exclusion rules (routes that shouldn't auto-reload on login)
37
+ * Format: "host:path" or "path"
38
+ */
39
+ static getReloadExclusionRules() {
40
+ return this.parseRules(process.env.NEXT_PUBLIC_RELOAD_EXCLUSION_ROUTES, []);
41
+ }
35
42
  /**
36
43
  * Generic parser for environment variables containing rule lists
37
44
  */
@@ -30,6 +30,13 @@ var MiddlewareConfig = class {
30
30
  { hostPattern: null, pathPattern: this.CONSTANTS.LOGIN_PATH }
31
31
  ]);
32
32
  }
33
+ /**
34
+ * Get reload exclusion rules (routes that shouldn't auto-reload on login)
35
+ * Format: "host:path" or "path"
36
+ */
37
+ static getReloadExclusionRules() {
38
+ return this.parseRules(process.env.NEXT_PUBLIC_RELOAD_EXCLUSION_ROUTES, []);
39
+ }
33
40
  /**
34
41
  * Generic parser for environment variables containing rule lists
35
42
  */
@@ -30,6 +30,13 @@ var MiddlewareConfig = class {
30
30
  { hostPattern: null, pathPattern: this.CONSTANTS.LOGIN_PATH }
31
31
  ]);
32
32
  }
33
+ /**
34
+ * Get reload exclusion rules (routes that shouldn't auto-reload on login)
35
+ * Format: "host:path" or "path"
36
+ */
37
+ static getReloadExclusionRules() {
38
+ return this.parseRules(process.env.NEXT_PUBLIC_RELOAD_EXCLUSION_ROUTES, []);
39
+ }
33
40
  /**
34
41
  * Generic parser for environment variables containing rule lists
35
42
  */
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "mailsentry-auth",
3
- "version": "0.2.7",
3
+ "version": "0.2.9",
4
4
  "description": "Next.js 15 authentication package with multi-step auth flow, cross-tab sync, and Zustand state management",
5
5
  "main": "./dist/index.js",
6
6
  "module": "./dist/index.mjs",