mailsentry-auth 0.2.1 → 0.2.3

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
@@ -191,7 +191,7 @@ var getAuthPageStepMessage = (step) => {
191
191
 
192
192
  // src/config/step-navigation.ts
193
193
  var EMAIL_SUBMISSION_NAVIGATION = {
194
- ["login-verification" /* LOGIN_VERIFICATION */]: "verification" /* VERIFICATION */,
194
+ ["login-verification" /* LOGIN_VERIFICATION */]: "password" /* PASSWORD */,
195
195
  ["login" /* LOGIN */]: "password" /* PASSWORD */,
196
196
  ["signup" /* SIGNUP */]: "password" /* PASSWORD */
197
197
  };
@@ -216,6 +216,7 @@ var getStepForVerificationSubmission = (success) => {
216
216
 
217
217
  // src/config/form-fields.tsx
218
218
  import { Input as Input2, Checkbox, Button as Button7 } from "antd";
219
+ import { MailOutlined as MailOutlined2 } from "@ant-design/icons";
219
220
 
220
221
  // src/components/auth/password-input-with-strength.tsx
221
222
  import { useState, useEffect, useMemo } from "react";
@@ -564,51 +565,36 @@ var PasswordStep = ({
564
565
 
565
566
  // src/components/auth/verification-step.tsx
566
567
  import { Button as Button4 } from "antd";
567
- import { ArrowLeftOutlined as ArrowLeftOutlined2 } from "@ant-design/icons";
568
- import { Fragment as Fragment3, jsx as jsx9, jsxs as jsxs6 } from "react/jsx-runtime";
568
+ import { Fragment as Fragment3, jsx as jsx9 } from "react/jsx-runtime";
569
569
  var VerificationStep = ({
570
570
  title,
571
571
  description,
572
572
  onSubmit,
573
- onBack,
574
573
  onResendCode,
575
574
  submitButtonText,
576
575
  isLoading = false,
577
576
  codeLength = 5,
578
- showBackButton = true,
579
577
  showResendButton = true,
580
- initialValues
578
+ initialValues,
579
+ email
581
580
  }) => {
582
581
  const handleSubmit = async (values) => {
583
582
  await onSubmit(values.verificationCode);
584
583
  };
585
584
  const fields = [
586
- getVerificationField(codeLength, { disabled: isLoading })
585
+ getVerificationField(codeLength, { disabled: isLoading }, email)
587
586
  ];
588
- const additionalActions = /* @__PURE__ */ jsxs6(Fragment3, { children: [
589
- showResendButton && /* @__PURE__ */ jsx9(
590
- Button4,
591
- {
592
- type: "link",
593
- onClick: onResendCode,
594
- disabled: isLoading,
595
- block: true,
596
- className: "mb-2",
597
- children: "Resend verification code"
598
- }
599
- ),
600
- showBackButton && /* @__PURE__ */ jsx9(
601
- Button4,
602
- {
603
- icon: /* @__PURE__ */ jsx9(ArrowLeftOutlined2, {}),
604
- onClick: onBack,
605
- type: "link",
606
- block: true,
607
- disabled: isLoading,
608
- children: "Back to password"
609
- }
610
- )
611
- ] });
587
+ const additionalActions = /* @__PURE__ */ jsx9(Fragment3, { children: showResendButton && /* @__PURE__ */ jsx9(
588
+ Button4,
589
+ {
590
+ type: "link",
591
+ onClick: onResendCode,
592
+ disabled: isLoading,
593
+ block: true,
594
+ className: "mb-2",
595
+ children: "Resend verification code"
596
+ }
597
+ ) });
612
598
  return /* @__PURE__ */ jsx9(
613
599
  BaseForm,
614
600
  {
@@ -696,24 +682,27 @@ var createPropsFactoryRegistry = ({
696
682
  onGoogleSignIn: handlers.onGoogleSignIn,
697
683
  onForgotPassword: handlers.onForgotPasswordClick
698
684
  }),
699
- ["password" /* PASSWORD */]: () => __spreadProps(__spreadValues({}, baseProps), {
700
- title: state.authIntent === "login" /* LOGIN */ ? "Welcome Back" : "Create Account",
701
- description: state.authIntent === "login" /* LOGIN */ ? "Please enter your password to sign in" : "Please create a password for your account",
702
- submitButtonText: state.authIntent === "login" /* LOGIN */ ? "Sign In" : "Next",
703
- mode: state.authIntent,
704
- email: state.email,
705
- onSubmit: handlers.handlePasswordSubmit,
706
- onBack: handlers.goBackToEmail,
707
- showEmailField: configs.passwordStepConfig.showEmailField,
708
- initialValues: { email: state.email }
709
- }),
685
+ ["password" /* PASSWORD */]: () => {
686
+ const LOGIN_FLOW_ACTIONS = /* @__PURE__ */ new Set(["login" /* LOGIN */, "login-verification" /* LOGIN_VERIFICATION */]);
687
+ const isLoginFlow = LOGIN_FLOW_ACTIONS.has(state.authIntent);
688
+ return __spreadProps(__spreadValues({}, baseProps), {
689
+ title: isLoginFlow ? "Welcome Back" : "Create Account",
690
+ description: isLoginFlow ? "Please enter your password to sign in" : "Please create a password for your account",
691
+ submitButtonText: isLoginFlow ? "Sign In" : "Next",
692
+ mode: isLoginFlow ? "login" /* LOGIN */ : state.authIntent,
693
+ email: state.email,
694
+ onSubmit: handlers.handlePasswordSubmit,
695
+ onBack: handlers.goBackToEmail,
696
+ showEmailField: configs.passwordStepConfig.showEmailField,
697
+ initialValues: { email: state.email }
698
+ });
699
+ },
710
700
  ["verification" /* VERIFICATION */]: () => __spreadProps(__spreadValues({}, baseProps), {
711
701
  title: "Email Verification",
712
702
  description: `Please enter the verification code sent to ${state.email}`,
713
703
  submitButtonText: "Verify Email",
714
704
  email: state.email,
715
705
  onSubmit: handlers.handleVerificationSubmit,
716
- onBack: handlers.goBackToPassword,
717
706
  onResendCode: handlers.handleResendCode,
718
707
  codeLength: configs.verificationStepConfig.codeLength,
719
708
  showResendButton: configs.verificationStepConfig.showResendButton
@@ -746,7 +735,7 @@ var useStepRenderer = () => {
746
735
  // src/components/auth/auth-flow-container.tsx
747
736
  import React3, { useState as useState5 } from "react";
748
737
  import { Steps, Col, Button as Button5, Flex as Flex3, Row, Space as Space4 } from "antd";
749
- import { ArrowLeftOutlined as ArrowLeftOutlined3 } from "@ant-design/icons";
738
+ import { ArrowLeftOutlined as ArrowLeftOutlined2 } from "@ant-design/icons";
750
739
  import Image from "next/image";
751
740
  import { cva } from "class-variance-authority";
752
741
 
@@ -1632,6 +1621,83 @@ LocalStorageUtils.USER_PROFILE_STORAGE_KEY = "user_profile_data";
1632
1621
  LocalStorageUtils.USER_PROFILE_TIMESTAMP_KEY = "user_profile_timestamp";
1633
1622
  LocalStorageUtils.DEFAULT_CACHE_DURATION = 5 * 60 * 1e3;
1634
1623
 
1624
+ // src/services/utils/email-provider-utils.ts
1625
+ var EMAIL_PROVIDERS = [
1626
+ {
1627
+ name: "Gmail",
1628
+ pattern: /@gmail\.com$/i,
1629
+ getUrl: (email, subject) => {
1630
+ const searchQuery = subject ? `subject:${encodeURIComponent(subject)}+in:all` : "in:inbox";
1631
+ return `https://mail.google.com/mail/u/${email}/#search/${searchQuery}`;
1632
+ }
1633
+ },
1634
+ {
1635
+ name: "Outlook",
1636
+ pattern: /@(outlook|hotmail|live)\.com$/i,
1637
+ getUrl: (email, subject) => {
1638
+ if (subject) {
1639
+ return `https://outlook.live.com/mail/0/?search=subject%3A${encodeURIComponent(subject)}`;
1640
+ }
1641
+ return "https://outlook.live.com/mail/0/inbox";
1642
+ }
1643
+ },
1644
+ {
1645
+ name: "Yahoo",
1646
+ pattern: /@yahoo\.(com|co\.uk|ca|fr|de|it|es)$/i,
1647
+ getUrl: (email, subject) => {
1648
+ if (subject) {
1649
+ return `https://mail.yahoo.com/d/search/keyword=${encodeURIComponent(subject)}`;
1650
+ }
1651
+ return "https://mail.yahoo.com/d/folders/1";
1652
+ }
1653
+ },
1654
+ {
1655
+ name: "iCloud",
1656
+ pattern: /@(icloud|me)\.com$/i,
1657
+ getUrl: () => "https://www.icloud.com/mail/"
1658
+ },
1659
+ {
1660
+ name: "ProtonMail",
1661
+ pattern: /@(protonmail|proton\.me)$/i,
1662
+ getUrl: () => "https://mail.proton.me/u/0/inbox"
1663
+ },
1664
+ {
1665
+ name: "Zoho",
1666
+ pattern: /@zoho(mail)?\.com$/i,
1667
+ getUrl: () => "https://mail.zoho.com/zm/"
1668
+ },
1669
+ {
1670
+ name: "AOL",
1671
+ pattern: /@aol\.com$/i,
1672
+ getUrl: () => "https://mail.aol.com/webmail-std/en-us/suite"
1673
+ }
1674
+ ];
1675
+ var EmailProviderUtils = class {
1676
+ /**
1677
+ * Detects email provider from email address
1678
+ */
1679
+ static detectProvider(email) {
1680
+ if (!email) return null;
1681
+ const provider = EMAIL_PROVIDERS.find((p) => p.pattern.test(email));
1682
+ return provider || null;
1683
+ }
1684
+ /**
1685
+ * Generates inbox URL for the given email
1686
+ */
1687
+ static getInboxUrl(email, subject) {
1688
+ const provider = this.detectProvider(email);
1689
+ if (!provider) return null;
1690
+ return provider.getUrl(email, subject);
1691
+ }
1692
+ /**
1693
+ * Gets provider name from email
1694
+ */
1695
+ static getProviderName(email) {
1696
+ const provider = this.detectProvider(email);
1697
+ return (provider == null ? void 0 : provider.name) || null;
1698
+ }
1699
+ };
1700
+
1635
1701
  // src/services/auth/manager/token-manager.ts
1636
1702
  var TokenManager = class {
1637
1703
  constructor(cookieUtils) {
@@ -2134,6 +2200,21 @@ var ExistingUserLoginStrategy = class {
2134
2200
  }
2135
2201
  };
2136
2202
 
2203
+ // src/services/auth/patterns/strategy/login-verification-strategy.ts
2204
+ var LoginVerificationStrategy = class {
2205
+ constructor(authService, tokenManager) {
2206
+ this.authService = authService;
2207
+ this.tokenManager = tokenManager;
2208
+ }
2209
+ async execute(credentials) {
2210
+ const loginResult = await this.authService.login(credentials);
2211
+ return AuthResultFactory.createSuccess(__spreadProps(__spreadValues({}, loginResult.data), {
2212
+ verification_required: true,
2213
+ message: "Please verify your email to continue"
2214
+ }));
2215
+ }
2216
+ };
2217
+
2137
2218
  // src/services/auth/patterns/strategy/login-flow-strategy-factory.ts
2138
2219
  var LoginFlowStrategyFactory = class {
2139
2220
  static createStrategy(action, authService, tokenManager) {
@@ -2146,9 +2227,53 @@ var LoginFlowStrategyFactory = class {
2146
2227
  };
2147
2228
  LoginFlowStrategyFactory.strategies = /* @__PURE__ */ new Map([
2148
2229
  ["signup" /* SIGNUP */, (authService, tokenManager) => new SignupFlowStrategy(authService, tokenManager)],
2149
- ["login" /* LOGIN */, (authService, tokenManager) => new ExistingUserLoginStrategy(authService, tokenManager)]
2230
+ ["login" /* LOGIN */, (authService, tokenManager) => new ExistingUserLoginStrategy(authService, tokenManager)],
2231
+ ["login-verification" /* LOGIN_VERIFICATION */, (authService, tokenManager) => new LoginVerificationStrategy(authService, tokenManager)]
2150
2232
  ]);
2151
2233
 
2234
+ // src/services/auth/patterns/strategy/login-strategy-resolver.ts
2235
+ var StrategyResolutionMode = /* @__PURE__ */ ((StrategyResolutionMode2) => {
2236
+ StrategyResolutionMode2["SKIP_EMAIL_CHECK"] = "SKIP_EMAIL_CHECK";
2237
+ StrategyResolutionMode2["CHECK_EMAIL_EXISTS"] = "CHECK_EMAIL_EXISTS";
2238
+ return StrategyResolutionMode2;
2239
+ })(StrategyResolutionMode || {});
2240
+ var SkipEmailCheckCommand = class {
2241
+ async execute(_email) {
2242
+ return "login" /* LOGIN */;
2243
+ }
2244
+ };
2245
+ var CheckEmailExistsCommand = class {
2246
+ constructor(authService) {
2247
+ this.authService = authService;
2248
+ }
2249
+ async execute(email) {
2250
+ const emailCheck = await this.authService.checkEmailExists(email);
2251
+ return emailCheck.next_action;
2252
+ }
2253
+ };
2254
+ var LoginStrategyResolver = class {
2255
+ constructor(authService) {
2256
+ this.strategies = /* @__PURE__ */ new Map([
2257
+ ["SKIP_EMAIL_CHECK" /* SKIP_EMAIL_CHECK */, new SkipEmailCheckCommand()],
2258
+ ["CHECK_EMAIL_EXISTS" /* CHECK_EMAIL_EXISTS */, new CheckEmailExistsCommand(authService)]
2259
+ ]);
2260
+ }
2261
+ async resolve(email, mode) {
2262
+ const command = this.strategies.get(mode);
2263
+ if (!command) {
2264
+ throw new Error(`No strategy found for mode: ${mode}`);
2265
+ }
2266
+ return await command.execute(email);
2267
+ }
2268
+ /**
2269
+ * Extend resolver with new strategies at runtime
2270
+ * Example: resolver.registerStrategy(StrategyResolutionMode.CUSTOM, customCommand)
2271
+ */
2272
+ registerStrategy(mode, command) {
2273
+ this.strategies.set(mode, command);
2274
+ }
2275
+ };
2276
+
2152
2277
  // src/services/auth/patterns/state/authenticated-state.ts
2153
2278
  var AuthenticatedState = class {
2154
2279
  async getStatus(tokenManager) {
@@ -2288,14 +2413,50 @@ var AuthOrchestrator = class {
2288
2413
  return this.errorHandler.handle(error, "Email check");
2289
2414
  }
2290
2415
  }
2416
+ /**
2417
+ * Handle login strategy based on the result of an email check.
2418
+ * This method implements a strategy pattern to decide which login flow to execute.
2419
+ */
2420
+ async handleLoginStrategy(loginRequest) {
2421
+ try {
2422
+ const { next_action } = await this.authService.checkEmailExists(loginRequest.email);
2423
+ const loginStrategies = {
2424
+ ["login" /* LOGIN */]: () => this.handleLoginFlow(loginRequest),
2425
+ ["signup" /* SIGNUP */]: () => this.handleLoginFlow(loginRequest),
2426
+ ["login-verification" /* LOGIN_VERIFICATION */]: async () => {
2427
+ await this.handleLoginFlow(loginRequest);
2428
+ return AuthResultFactory.createSuccess({
2429
+ roleType: "",
2430
+ accessToken: "",
2431
+ refreshToken: "",
2432
+ isVerifiedEmail: false,
2433
+ profile: {},
2434
+ tokenInfo: { domain: "" },
2435
+ next_action: "login-verification" /* LOGIN_VERIFICATION */,
2436
+ loginRequest
2437
+ });
2438
+ }
2439
+ };
2440
+ const strategy = loginStrategies[next_action];
2441
+ if (strategy) {
2442
+ return await strategy();
2443
+ }
2444
+ throw new Error(`Unknown next action: ${next_action}`);
2445
+ } catch (error) {
2446
+ return this.errorHandler.handle(error, "Login strategy");
2447
+ }
2448
+ }
2291
2449
  /**
2292
2450
  * Handle complete login flow with proper error handling and token management
2451
+ * @param credentials - Login credentials (email and password)
2452
+ * @param mode - Strategy resolution mode (defaults to CHECK_EMAIL_EXISTS)
2293
2453
  */
2294
- async handleLoginFlow(credentials) {
2454
+ async handleLoginFlow(credentials, mode = "CHECK_EMAIL_EXISTS" /* CHECK_EMAIL_EXISTS */) {
2295
2455
  try {
2296
- const emailCheck = await this.authService.checkEmailExists(credentials.email);
2456
+ const strategyResolver = new LoginStrategyResolver(this.authService);
2457
+ const nextAction = await strategyResolver.resolve(credentials.email, mode);
2297
2458
  const strategy = LoginFlowStrategyFactory.createStrategy(
2298
- emailCheck.next_action,
2459
+ nextAction,
2299
2460
  this.authService,
2300
2461
  this.tokenManager
2301
2462
  );
@@ -2871,7 +3032,7 @@ var useAuthFlowModal = () => {
2871
3032
  };
2872
3033
 
2873
3034
  // src/components/auth/auth-flow-container.tsx
2874
- import { jsx as jsx12, jsxs as jsxs7 } from "react/jsx-runtime";
3035
+ import { jsx as jsx12, jsxs as jsxs6 } from "react/jsx-runtime";
2875
3036
  var containerVariants = cva("w-full h-screen p-6 overflow-hidden", {
2876
3037
  variants: {
2877
3038
  layout: {
@@ -2956,17 +3117,30 @@ function AuthFlowContainer({
2956
3117
  await executeAction(
2957
3118
  async () => {
2958
3119
  const loginRequest = { email, password: passwordValue };
2959
- return await authOrchestrator.handleLoginFlow(loginRequest);
3120
+ return await authOrchestrator.handleLoginStrategy(loginRequest);
2960
3121
  },
2961
3122
  {
2962
3123
  onSuccess: (data) => {
3124
+ var _a;
2963
3125
  setAuthData(data);
2964
- if (!data.isVerifiedEmail) {
2965
- const nextStep = getStepForPasswordSubmission(data.isVerifiedEmail);
2966
- stepperActions.goToStep(nextStep);
2967
- return;
2968
- }
2969
- handleSuccess();
3126
+ const actionPipeline = [
3127
+ {
3128
+ condition: () => data.next_action === "login-verification" /* LOGIN_VERIFICATION */,
3129
+ execute: () => stepperActions.goToStep("verification" /* VERIFICATION */)
3130
+ },
3131
+ {
3132
+ condition: () => !data.isVerifiedEmail,
3133
+ execute: () => {
3134
+ const nextStep = getStepForPasswordSubmission(data.isVerifiedEmail);
3135
+ stepperActions.goToStep(nextStep);
3136
+ }
3137
+ },
3138
+ {
3139
+ condition: () => true,
3140
+ execute: () => handleSuccess()
3141
+ }
3142
+ ];
3143
+ (_a = actionPipeline.find((action) => action.condition())) == null ? void 0 : _a.execute();
2970
3144
  },
2971
3145
  onError: (error) => {
2972
3146
  console.error(error);
@@ -2982,7 +3156,7 @@ function AuthFlowContainer({
2982
3156
  {
2983
3157
  onSuccess: (data) => {
2984
3158
  setAuthData(data);
2985
- handlePasswordSubmit(password);
3159
+ handlePasswordSubmitAfterVerification(password);
2986
3160
  setPassword("");
2987
3161
  },
2988
3162
  onError: (error) => {
@@ -2991,6 +3165,23 @@ function AuthFlowContainer({
2991
3165
  }
2992
3166
  );
2993
3167
  };
3168
+ const handlePasswordSubmitAfterVerification = async (passwordValue) => {
3169
+ await executeAction(
3170
+ async () => {
3171
+ const loginRequest = { email, password: passwordValue };
3172
+ return await authOrchestrator.handleLoginFlow(loginRequest, "SKIP_EMAIL_CHECK" /* SKIP_EMAIL_CHECK */);
3173
+ },
3174
+ {
3175
+ onSuccess: (data) => {
3176
+ setAuthData(data);
3177
+ handleSuccess();
3178
+ },
3179
+ onError: (error) => {
3180
+ console.error(error);
3181
+ }
3182
+ }
3183
+ );
3184
+ };
2994
3185
  const handleGoogleSignIn = async (token) => {
2995
3186
  await executeAction(
2996
3187
  async () => {
@@ -3095,8 +3286,8 @@ function AuthFlowContainer({
3095
3286
  onClick: goBackToHome
3096
3287
  };
3097
3288
  }, [stepperState.currentStep, stepperActions, clearAll, goBackToHome]);
3098
- return /* @__PURE__ */ jsxs7(Row, { className: "m-0 h-screen", children: [
3099
- /* @__PURE__ */ jsx12(Col, { xs: 24, lg: showRightSideImage ? 10 : 24, className: "flex flex-col", children: /* @__PURE__ */ jsxs7(
3289
+ return /* @__PURE__ */ jsxs6(Row, { className: "m-0 h-screen", children: [
3290
+ /* @__PURE__ */ jsx12(Col, { xs: 24, lg: showRightSideImage ? 10 : 24, className: "flex flex-col", children: /* @__PURE__ */ jsxs6(
3100
3291
  Flex3,
3101
3292
  {
3102
3293
  vertical: true,
@@ -3107,12 +3298,12 @@ function AuthFlowContainer({
3107
3298
  children: [
3108
3299
  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 }) }),
3109
3300
  /* @__PURE__ */ jsx12(Flex3, { flex: 1, justify: "center", align: "center", className: formContentVariants(), children: /* @__PURE__ */ jsx12(Space4, { direction: "vertical", className: "w-full max-w-[480px]", children: /* @__PURE__ */ jsx12(SelectedComponent, __spreadValues({}, stepProps)) }) }),
3110
- /* @__PURE__ */ jsxs7(Flex3, { align: "center", gap: "small", className: "mt-4", children: [
3301
+ /* @__PURE__ */ jsxs6(Flex3, { align: "center", gap: "small", className: "mt-4", children: [
3111
3302
  /* @__PURE__ */ jsx12(
3112
3303
  Button5,
3113
3304
  {
3114
3305
  type: "text",
3115
- icon: /* @__PURE__ */ jsx12(ArrowLeftOutlined3, {}),
3306
+ icon: /* @__PURE__ */ jsx12(ArrowLeftOutlined2, {}),
3116
3307
  onClick: handleBack,
3117
3308
  disabled: stepperState.isFirstStep
3118
3309
  }
@@ -3148,7 +3339,7 @@ function AuthFlowContainer({
3148
3339
 
3149
3340
  // src/components/auth/auth-flow-modal.tsx
3150
3341
  import { Modal, Spin as Spin2 } from "antd";
3151
- import { Fragment as Fragment4, jsx as jsx13, jsxs as jsxs8 } from "react/jsx-runtime";
3342
+ import { Fragment as Fragment4, jsx as jsx13, jsxs as jsxs7 } from "react/jsx-runtime";
3152
3343
  function AuthFlowModal({
3153
3344
  children,
3154
3345
  variant = "default" /* DEFAULT */,
@@ -3158,7 +3349,7 @@ function AuthFlowModal({
3158
3349
  if (isInitialLoading) {
3159
3350
  return /* @__PURE__ */ jsx13("div", { className: "min-h-screen flex items-center justify-center bg-gray-50", children: /* @__PURE__ */ jsx13(Spin2, { size: "large" }) });
3160
3351
  }
3161
- return /* @__PURE__ */ jsxs8(Fragment4, { children: [
3352
+ return /* @__PURE__ */ jsxs7(Fragment4, { children: [
3162
3353
  isModalOpen ? /* @__PURE__ */ jsx13("div", { className: "min-h-screen flex items-center justify-center bg-gray-50", children: /* @__PURE__ */ jsx13(Spin2, { size: "large" }) }) : children,
3163
3354
  /* @__PURE__ */ jsx13(
3164
3355
  Modal,
@@ -3188,7 +3379,7 @@ var AuthInitializer = ({ children }) => {
3188
3379
  import { useState as useState6, useEffect as useEffect6 } from "react";
3189
3380
  import { Dropdown, Button as Button6 } from "antd";
3190
3381
  import { MailOutlined, CrownOutlined, LogoutOutlined, UserOutlined } from "@ant-design/icons";
3191
- import { jsx as jsx15, jsxs as jsxs9 } from "react/jsx-runtime";
3382
+ import { jsx as jsx15, jsxs as jsxs8 } from "react/jsx-runtime";
3192
3383
  var DefaultUnauthenticated = () => {
3193
3384
  const rootDomain = UrlUtils.getRootDomain(window.location.hostname);
3194
3385
  const baseDomain = rootDomain == null ? void 0 : rootDomain.replace(/^\./, "");
@@ -3220,7 +3411,7 @@ var AuthenticatedState2 = ({ user, onLogout }) => {
3220
3411
  email: {
3221
3412
  key: "email",
3222
3413
  icon: /* @__PURE__ */ jsx15(MailOutlined, {}),
3223
- label: /* @__PURE__ */ jsxs9("div", { children: [
3414
+ label: /* @__PURE__ */ jsxs8("div", { children: [
3224
3415
  /* @__PURE__ */ jsx15("div", { className: "text-xs text-gray-500", children: "Email" }),
3225
3416
  /* @__PURE__ */ jsx15("div", { className: "font-medium", children: ((_a = user.user) == null ? void 0 : _a.email) || "N/A" })
3226
3417
  ] })
@@ -3228,7 +3419,7 @@ var AuthenticatedState2 = ({ user, onLogout }) => {
3228
3419
  role: {
3229
3420
  key: "role",
3230
3421
  icon: /* @__PURE__ */ jsx15(CrownOutlined, {}),
3231
- label: /* @__PURE__ */ jsxs9("div", { children: [
3422
+ label: /* @__PURE__ */ jsxs8("div", { children: [
3232
3423
  /* @__PURE__ */ jsx15("div", { className: "text-xs text-gray-500", children: "Role" }),
3233
3424
  /* @__PURE__ */ jsx15("div", { className: "font-medium", children: ((_c = (_b = user.user) == null ? void 0 : _b.role) == null ? void 0 : _c.name) || "N/A" })
3234
3425
  ] })
@@ -3285,7 +3476,7 @@ var ProfileStateRenderer = () => {
3285
3476
 
3286
3477
  // src/components/demo/cross-tab-demo.tsx
3287
3478
  import { Card, Typography as Typography3, Tag, Space as Space5 } from "antd";
3288
- import { Fragment as Fragment6, jsx as jsx16, jsxs as jsxs10 } from "react/jsx-runtime";
3479
+ import { Fragment as Fragment6, jsx as jsx16, jsxs as jsxs9 } from "react/jsx-runtime";
3289
3480
  var { Title: Title2, Text: Text2, Paragraph: Paragraph2 } = Typography3;
3290
3481
  var CrossTabDemo = () => {
3291
3482
  var _a;
@@ -3297,31 +3488,31 @@ var CrossTabDemo = () => {
3297
3488
  title: "Cross-Tab Authentication Demo",
3298
3489
  className: "w-full max-w-2xl",
3299
3490
  style: { marginTop: "2rem" },
3300
- children: /* @__PURE__ */ jsxs10(Space5, { direction: "vertical", size: "middle", className: "w-full", children: [
3301
- /* @__PURE__ */ jsxs10("div", { children: [
3491
+ children: /* @__PURE__ */ jsxs9(Space5, { direction: "vertical", size: "middle", className: "w-full", children: [
3492
+ /* @__PURE__ */ jsxs9("div", { children: [
3302
3493
  /* @__PURE__ */ jsx16(Title2, { level: 4, children: "Current Status" }),
3303
- /* @__PURE__ */ jsxs10(Space5, { children: [
3494
+ /* @__PURE__ */ jsxs9(Space5, { children: [
3304
3495
  /* @__PURE__ */ jsx16(Text2, { strong: true, children: "Authentication:" }),
3305
3496
  /* @__PURE__ */ jsx16(Tag, { color: isAuthenticated ? "green" : "red", children: isAuthenticated ? "Authenticated" : "Not Authenticated" })
3306
3497
  ] }),
3307
3498
  /* @__PURE__ */ jsx16("br", {}),
3308
- /* @__PURE__ */ jsxs10(Space5, { style: { marginTop: "0.5rem" }, children: [
3499
+ /* @__PURE__ */ jsxs9(Space5, { style: { marginTop: "0.5rem" }, children: [
3309
3500
  /* @__PURE__ */ jsx16(Text2, { strong: true, children: "Current Page:" }),
3310
3501
  /* @__PURE__ */ jsx16(Tag, { color: "blue", children: currentPageType })
3311
3502
  ] }),
3312
- user && /* @__PURE__ */ jsxs10(Fragment6, { children: [
3503
+ user && /* @__PURE__ */ jsxs9(Fragment6, { children: [
3313
3504
  /* @__PURE__ */ jsx16("br", {}),
3314
- /* @__PURE__ */ jsxs10(Space5, { style: { marginTop: "0.5rem" }, children: [
3505
+ /* @__PURE__ */ jsxs9(Space5, { style: { marginTop: "0.5rem" }, children: [
3315
3506
  /* @__PURE__ */ jsx16(Text2, { strong: true, children: "User:" }),
3316
3507
  /* @__PURE__ */ jsx16(Text2, { children: (_a = user.user) == null ? void 0 : _a.email })
3317
3508
  ] })
3318
3509
  ] })
3319
3510
  ] }),
3320
- /* @__PURE__ */ jsxs10("div", { children: [
3511
+ /* @__PURE__ */ jsxs9("div", { children: [
3321
3512
  /* @__PURE__ */ jsx16(Title2, { level: 4, children: "How It Works" }),
3322
3513
  /* @__PURE__ */ jsx16(Paragraph2, { children: "This application now supports enhanced cross-tab authentication handling:" }),
3323
- /* @__PURE__ */ jsxs10("div", { style: { marginLeft: "1rem" }, children: [
3324
- /* @__PURE__ */ jsxs10(Paragraph2, { children: [
3514
+ /* @__PURE__ */ jsxs9("div", { style: { marginLeft: "1rem" }, children: [
3515
+ /* @__PURE__ */ jsxs9(Paragraph2, { children: [
3325
3516
  /* @__PURE__ */ jsx16(Text2, { strong: true, children: "Login Scenario:" }),
3326
3517
  /* @__PURE__ */ jsx16("br", {}),
3327
3518
  "\u2022 Open multiple tabs with some on the login page and others on different pages",
@@ -3330,7 +3521,7 @@ var CrossTabDemo = () => {
3330
3521
  /* @__PURE__ */ jsx16("br", {}),
3331
3522
  "\u2022 Non-login pages will receive the login event but won't redirect (they'll just update their state)"
3332
3523
  ] }),
3333
- /* @__PURE__ */ jsxs10(Paragraph2, { children: [
3524
+ /* @__PURE__ */ jsxs9(Paragraph2, { children: [
3334
3525
  /* @__PURE__ */ jsx16(Text2, { strong: true, children: "Logout Scenario:" }),
3335
3526
  /* @__PURE__ */ jsx16("br", {}),
3336
3527
  "\u2022 When you log out from the dashboard, other dashboard tabs will redirect to the login page",
@@ -3339,9 +3530,9 @@ var CrossTabDemo = () => {
3339
3530
  ] })
3340
3531
  ] })
3341
3532
  ] }),
3342
- /* @__PURE__ */ jsxs10("div", { children: [
3533
+ /* @__PURE__ */ jsxs9("div", { children: [
3343
3534
  /* @__PURE__ */ jsx16(Title2, { level: 4, children: "Test Instructions" }),
3344
- /* @__PURE__ */ jsxs10(Paragraph2, { children: [
3535
+ /* @__PURE__ */ jsxs9(Paragraph2, { children: [
3345
3536
  "1. Open this page in multiple browser tabs",
3346
3537
  /* @__PURE__ */ jsx16("br", {}),
3347
3538
  "2. Navigate to ",
@@ -3396,21 +3587,39 @@ var getPasswordField = (isLogin, disabled = false, options = {}) => ({
3396
3587
  ] : []
3397
3588
  ]
3398
3589
  });
3399
- var getVerificationField = (codeLength = 5, options = {}) => ({
3400
- name: "verificationCode",
3401
- component: /* @__PURE__ */ jsx17(
3402
- Input2,
3403
- __spreadProps(__spreadValues({}, options), {
3404
- placeholder: "Enter verification code",
3405
- maxLength: codeLength,
3406
- size: "large"
3407
- })
3408
- ),
3409
- rules: [
3410
- { required: true, message: "Please enter the verification code!" },
3411
- { len: codeLength, message: `Verification code must be ${codeLength} characters!` }
3412
- ]
3413
- });
3590
+ var getVerificationField = (codeLength = 5, options = {}, email) => {
3591
+ const inboxUrl = EmailProviderUtils.getInboxUrl(email != null ? email : "", "Confirm Your MailSentry Account Registration");
3592
+ const providerName = EmailProviderUtils.getProviderName(email != null ? email : "");
3593
+ const suffix = inboxUrl ? /* @__PURE__ */ jsx17(
3594
+ Button7,
3595
+ {
3596
+ type: "link",
3597
+ icon: /* @__PURE__ */ jsx17(MailOutlined2, {}),
3598
+ href: inboxUrl,
3599
+ target: "_blank",
3600
+ rel: "noopener noreferrer",
3601
+ className: "!p-0 !h-auto",
3602
+ title: `Open ${providerName || "email"}`,
3603
+ children: "Check Email"
3604
+ }
3605
+ ) : void 0;
3606
+ return {
3607
+ name: "verificationCode",
3608
+ component: /* @__PURE__ */ jsx17(
3609
+ Input2,
3610
+ __spreadProps(__spreadValues({}, options), {
3611
+ placeholder: "Enter verification code",
3612
+ maxLength: codeLength,
3613
+ size: "large",
3614
+ suffix
3615
+ })
3616
+ ),
3617
+ rules: [
3618
+ { required: true, message: "Please enter the verification code!" },
3619
+ { len: codeLength, message: `Verification code must be ${codeLength} characters!` }
3620
+ ]
3621
+ };
3622
+ };
3414
3623
  var getTermsCheckboxField = (options = {}) => ({
3415
3624
  name: "acceptTerms",
3416
3625
  component: /* @__PURE__ */ jsx17(Checkbox, __spreadProps(__spreadValues({}, options), { children: "I Accept Terms and Conditions" })),
@@ -3456,6 +3665,7 @@ export {
3456
3665
  CrossTabDemo,
3457
3666
  DevelopmentLogger,
3458
3667
  EMAIL_SUBMISSION_NAVIGATION,
3668
+ EmailProviderUtils,
3459
3669
  EmailStep,
3460
3670
  EndpointBuilder,
3461
3671
  ExistingUserLoginStrategy,
@@ -3467,6 +3677,8 @@ export {
3467
3677
  LocalStorageUtils,
3468
3678
  LoggerFactory,
3469
3679
  LoginFlowStrategyFactory,
3680
+ LoginStrategyResolver,
3681
+ LoginVerificationStrategy,
3470
3682
  MiddlewareConfig,
3471
3683
  NavigationAction,
3472
3684
  NetworkErrorHandler,
@@ -3481,6 +3693,7 @@ export {
3481
3693
  ProfileUIState,
3482
3694
  RoleType,
3483
3695
  SignupFlowStrategy,
3696
+ StrategyResolutionMode,
3484
3697
  TokenManager,
3485
3698
  UnauthenticatedState,
3486
3699
  UrlUtils,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "mailsentry-auth",
3
- "version": "0.2.1",
3
+ "version": "0.2.3",
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",