mailsentry-auth 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.mjs ADDED
@@ -0,0 +1,2996 @@
1
+ "use client";
2
+ var __defProp = Object.defineProperty;
3
+ var __defProps = Object.defineProperties;
4
+ var __getOwnPropDescs = Object.getOwnPropertyDescriptors;
5
+ var __getOwnPropSymbols = Object.getOwnPropertySymbols;
6
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
7
+ var __propIsEnum = Object.prototype.propertyIsEnumerable;
8
+ var __defNormalProp = (obj, key, value) => key in obj ? __defProp(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
9
+ var __spreadValues = (a, b) => {
10
+ for (var prop in b || (b = {}))
11
+ if (__hasOwnProp.call(b, prop))
12
+ __defNormalProp(a, prop, b[prop]);
13
+ if (__getOwnPropSymbols)
14
+ for (var prop of __getOwnPropSymbols(b)) {
15
+ if (__propIsEnum.call(b, prop))
16
+ __defNormalProp(a, prop, b[prop]);
17
+ }
18
+ return a;
19
+ };
20
+ var __spreadProps = (a, b) => __defProps(a, __getOwnPropDescs(b));
21
+ var __objRest = (source, exclude) => {
22
+ var target = {};
23
+ for (var prop in source)
24
+ if (__hasOwnProp.call(source, prop) && exclude.indexOf(prop) < 0)
25
+ target[prop] = source[prop];
26
+ if (source != null && __getOwnPropSymbols)
27
+ for (var prop of __getOwnPropSymbols(source)) {
28
+ if (exclude.indexOf(prop) < 0 && __propIsEnum.call(source, prop))
29
+ target[prop] = source[prop];
30
+ }
31
+ return target;
32
+ };
33
+
34
+ // src/types/http/http-types.ts
35
+ var HttpMethod = /* @__PURE__ */ ((HttpMethod2) => {
36
+ HttpMethod2["GET"] = "GET";
37
+ HttpMethod2["POST"] = "POST";
38
+ HttpMethod2["PUT"] = "PUT";
39
+ HttpMethod2["DELETE"] = "DELETE";
40
+ HttpMethod2["PATCH"] = "PATCH";
41
+ return HttpMethod2;
42
+ })(HttpMethod || {});
43
+
44
+ // src/types/components/profile.ts
45
+ var ProfileUIState = /* @__PURE__ */ ((ProfileUIState2) => {
46
+ ProfileUIState2["LOADING"] = "LOADING";
47
+ ProfileUIState2["UNAUTHENTICATED"] = "UNAUTHENTICATED";
48
+ ProfileUIState2["AUTHENTICATED"] = "AUTHENTICATED";
49
+ return ProfileUIState2;
50
+ })(ProfileUIState || {});
51
+
52
+ // src/types/auth/auth-stepper-enums.ts
53
+ var AuthFlowStep = /* @__PURE__ */ ((AuthFlowStep2) => {
54
+ AuthFlowStep2["EMAIL"] = "email";
55
+ AuthFlowStep2["PASSWORD"] = "password";
56
+ AuthFlowStep2["VERIFICATION"] = "verification";
57
+ return AuthFlowStep2;
58
+ })(AuthFlowStep || {});
59
+ var NextAction = /* @__PURE__ */ ((NextAction2) => {
60
+ NextAction2["LOGIN"] = "login";
61
+ NextAction2["SIGNUP"] = "signup";
62
+ NextAction2["LOGIN_VERIFICATION"] = "login-verification";
63
+ return NextAction2;
64
+ })(NextAction || {});
65
+
66
+ // src/types/auth/auth-types.ts
67
+ var RoleType = /* @__PURE__ */ ((RoleType2) => {
68
+ RoleType2["USER"] = "USER";
69
+ RoleType2["ADMIN"] = "ADMIN";
70
+ return RoleType2;
71
+ })(RoleType || {});
72
+
73
+ // src/types/event-bus/event-bus.interface.ts
74
+ var BaseEventBus = class {
75
+ };
76
+
77
+ // src/types/event-bus/events.ts
78
+ var AuthEventType = /* @__PURE__ */ ((AuthEventType3) => {
79
+ AuthEventType3["LoggedIn"] = "auth.logged_in";
80
+ AuthEventType3["LoggedOut"] = "auth.logged_out";
81
+ AuthEventType3["EmailVerified"] = "auth.email_verified";
82
+ AuthEventType3["SignInRequiredModal"] = "auth.signin_required_modal";
83
+ return AuthEventType3;
84
+ })(AuthEventType || {});
85
+ var PageType = /* @__PURE__ */ ((PageType3) => {
86
+ PageType3["LOGIN"] = "/login";
87
+ PageType3["DASHBOARD"] = "/dashboard";
88
+ PageType3["HOME"] = "/";
89
+ return PageType3;
90
+ })(PageType || {});
91
+ var NavigationAction = /* @__PURE__ */ ((NavigationAction2) => {
92
+ NavigationAction2["NONE"] = "none";
93
+ NavigationAction2["REDIRECT"] = "redirect";
94
+ NavigationAction2["MODAL"] = "modal";
95
+ return NavigationAction2;
96
+ })(NavigationAction || {});
97
+ var PageTypePatterns = {
98
+ ["/login" /* LOGIN */]: "/login" /* LOGIN */,
99
+ ["/dashboard" /* DASHBOARD */]: "/dashboard" /* DASHBOARD */,
100
+ ["/" /* HOME */]: "/" /* HOME */
101
+ };
102
+ var CrossTabBehaviorConfig = {
103
+ ["/login" /* LOGIN */]: {
104
+ ["auth.logged_in" /* LoggedIn */]: { action: "redirect" /* REDIRECT */, target: "/dashboard" /* DASHBOARD */ },
105
+ ["auth.logged_out" /* LoggedOut */]: { action: "none" /* NONE */ },
106
+ ["auth.email_verified" /* EmailVerified */]: { action: "none" /* NONE */ },
107
+ ["auth.signin_required_modal" /* SignInRequiredModal */]: { action: "none" /* NONE */ }
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 */ }
114
+ },
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 */ },
119
+ ["auth.signin_required_modal" /* SignInRequiredModal */]: { action: "none" /* NONE */ }
120
+ }
121
+ };
122
+
123
+ // src/config/channels.ts
124
+ var Channel = /* @__PURE__ */ ((Channel2) => {
125
+ Channel2["AUTH"] = "auth-event-channel";
126
+ return Channel2;
127
+ })(Channel || {});
128
+
129
+ // src/config/auth-steps.tsx
130
+ import {
131
+ MailOutlined,
132
+ LockOutlined,
133
+ CheckCircleOutlined
134
+ } from "@ant-design/icons";
135
+ import { jsx } from "react/jsx-runtime";
136
+ var createAuthSteps = (options) => {
137
+ const { authIntent = "login" /* LOGIN */, nextAction } = options || {};
138
+ return [
139
+ {
140
+ id: "email" /* EMAIL */,
141
+ title: "Email",
142
+ description: "Enter your email",
143
+ icon: /* @__PURE__ */ jsx(MailOutlined, {})
144
+ },
145
+ {
146
+ id: "password" /* PASSWORD */,
147
+ title: authIntent === "login" /* LOGIN */ ? "Sign In" : "Sign Up",
148
+ description: authIntent === "login" /* LOGIN */ ? "Enter password" : "Create password",
149
+ icon: /* @__PURE__ */ jsx(LockOutlined, {})
150
+ },
151
+ {
152
+ id: "verification" /* VERIFICATION */,
153
+ title: "Verification",
154
+ description: "Verify email",
155
+ icon: /* @__PURE__ */ jsx(CheckCircleOutlined, {}),
156
+ disabled: authIntent === "login" /* LOGIN */ || nextAction === "login" /* LOGIN */
157
+ }
158
+ ];
159
+ };
160
+ var getStepProgressMessage = (step) => {
161
+ const messages = {
162
+ ["email" /* EMAIL */]: "Starting...",
163
+ ["password" /* PASSWORD */]: "Authenticating...",
164
+ ["verification" /* VERIFICATION */]: "Verifying..."
165
+ };
166
+ return messages[step] || "Processing...";
167
+ };
168
+ var getAuthPageStepMessage = (step) => {
169
+ const messages = {
170
+ ["email" /* EMAIL */]: "Checking...",
171
+ ["password" /* PASSWORD */]: "Authenticating...",
172
+ ["verification" /* VERIFICATION */]: "Verifying..."
173
+ };
174
+ return messages[step] || "Processing...";
175
+ };
176
+
177
+ // src/config/step-navigation.ts
178
+ var EMAIL_SUBMISSION_NAVIGATION = {
179
+ ["login-verification" /* LOGIN_VERIFICATION */]: "verification" /* VERIFICATION */,
180
+ ["login" /* LOGIN */]: "password" /* PASSWORD */,
181
+ ["signup" /* SIGNUP */]: "password" /* PASSWORD */
182
+ };
183
+ var PASSWORD_SUBMISSION_NAVIGATION = {
184
+ VERIFIED: "verification" /* VERIFICATION */,
185
+ UNVERIFIED: "verification" /* VERIFICATION */
186
+ };
187
+ var VERIFICATION_SUBMISSION_NAVIGATION = {
188
+ SUCCESS: "verification" /* VERIFICATION */,
189
+ ERROR: "verification" /* VERIFICATION */
190
+ // Stay on verification step on error
191
+ };
192
+ var getStepForEmailSubmission = (nextAction) => {
193
+ return EMAIL_SUBMISSION_NAVIGATION[nextAction] || "password" /* PASSWORD */;
194
+ };
195
+ var getStepForPasswordSubmission = (isVerified) => {
196
+ return isVerified ? PASSWORD_SUBMISSION_NAVIGATION.VERIFIED : PASSWORD_SUBMISSION_NAVIGATION.UNVERIFIED;
197
+ };
198
+ var getStepForVerificationSubmission = (success) => {
199
+ return success ? VERIFICATION_SUBMISSION_NAVIGATION.SUCCESS : VERIFICATION_SUBMISSION_NAVIGATION.ERROR;
200
+ };
201
+
202
+ // src/config/form-fields.tsx
203
+ import { Input } from "antd";
204
+ import { MailOutlined as MailOutlined2, LockOutlined as LockOutlined2, CheckCircleOutlined as CheckCircleOutlined2 } from "@ant-design/icons";
205
+ import { jsx as jsx2 } from "react/jsx-runtime";
206
+ var getEmailField = (options = {}) => ({
207
+ name: "email",
208
+ label: "Email",
209
+ component: /* @__PURE__ */ jsx2(
210
+ Input,
211
+ __spreadProps(__spreadValues({}, options), {
212
+ prefix: /* @__PURE__ */ jsx2(MailOutlined2, {}),
213
+ placeholder: "Email",
214
+ size: "large"
215
+ })
216
+ ),
217
+ rules: !options.readOnly ? [
218
+ { required: true, message: "Please enter your email!" },
219
+ { type: "email", message: "Please enter a valid email!" }
220
+ ] : void 0
221
+ });
222
+ var getPasswordField = (isLogin, disabled = false, options = {}) => ({
223
+ name: "password",
224
+ label: isLogin ? "Password" : "Create a Password",
225
+ component: /* @__PURE__ */ jsx2(
226
+ Input.Password,
227
+ __spreadProps(__spreadValues({}, options), {
228
+ prefix: /* @__PURE__ */ jsx2(LockOutlined2, {}),
229
+ placeholder: isLogin ? "Enter your password" : "Create a password",
230
+ disabled,
231
+ size: "large"
232
+ })
233
+ ),
234
+ rules: [
235
+ { required: true, message: "Please enter your password!" }
236
+ ]
237
+ });
238
+ var getVerificationField = (codeLength = 5, options = {}) => ({
239
+ name: "verificationCode",
240
+ component: /* @__PURE__ */ jsx2(
241
+ Input,
242
+ __spreadProps(__spreadValues({}, options), {
243
+ prefix: /* @__PURE__ */ jsx2(CheckCircleOutlined2, {}),
244
+ placeholder: "Enter verification code",
245
+ maxLength: codeLength,
246
+ size: "large"
247
+ })
248
+ ),
249
+ rules: [
250
+ { required: true, message: "Please enter the verification code!" },
251
+ { len: codeLength, message: `Verification code must be ${codeLength} characters!` }
252
+ ]
253
+ });
254
+
255
+ // src/config/middleware.ts
256
+ var MiddlewareConfig = class {
257
+ };
258
+ // Protected routes
259
+ MiddlewareConfig.PROTECTED_ROUTES = {
260
+ DASHBOARD: "/"
261
+ };
262
+ // Auth routes
263
+ MiddlewareConfig.AUTH_ROUTES = {
264
+ LOGIN: "/login"
265
+ };
266
+ // HTTP methods to process
267
+ MiddlewareConfig.ALLOWED_METHODS = ["GET", "HEAD"];
268
+ // Query parameters
269
+ MiddlewareConfig.QUERY_PARAMS = {
270
+ LOGIN_REQUIRED: "sign_in_required",
271
+ AUTH_CHECKED: "auth_checked"
272
+ };
273
+ // Query parameter values
274
+ MiddlewareConfig.QUERY_VALUES = {
275
+ LOGIN_REQUIRED: "true",
276
+ AUTH_CHECKED: "1"
277
+ };
278
+ var middlewareMatcher = [
279
+ "/((?!api|_next/static|_next/image|_next/webpack-hmr|favicon.ico|.*\\.(?:svg|png|jpg|jpeg|gif|webp|ico|css|js)$).*)",
280
+ "/login"
281
+ ];
282
+ var config = {
283
+ matcher: middlewareMatcher
284
+ };
285
+
286
+ // src/store/user-store.ts
287
+ import { create } from "zustand";
288
+ import { devtools, subscribeWithSelector } from "zustand/middleware";
289
+ import { immer } from "zustand/middleware/immer";
290
+ import { useShallow } from "zustand/react/shallow";
291
+
292
+ // node_modules/.pnpm/js-cookie@3.0.5/node_modules/js-cookie/dist/js.cookie.mjs
293
+ function assign(target) {
294
+ for (var i = 1; i < arguments.length; i++) {
295
+ var source = arguments[i];
296
+ for (var key in source) {
297
+ target[key] = source[key];
298
+ }
299
+ }
300
+ return target;
301
+ }
302
+ var defaultConverter = {
303
+ read: function(value) {
304
+ if (value[0] === '"') {
305
+ value = value.slice(1, -1);
306
+ }
307
+ return value.replace(/(%[\dA-F]{2})+/gi, decodeURIComponent);
308
+ },
309
+ write: function(value) {
310
+ return encodeURIComponent(value).replace(
311
+ /%(2[346BF]|3[AC-F]|40|5[BDE]|60|7[BCD])/g,
312
+ decodeURIComponent
313
+ );
314
+ }
315
+ };
316
+ function init(converter, defaultAttributes) {
317
+ function set(name, value, attributes) {
318
+ if (typeof document === "undefined") {
319
+ return;
320
+ }
321
+ attributes = assign({}, defaultAttributes, attributes);
322
+ if (typeof attributes.expires === "number") {
323
+ attributes.expires = new Date(Date.now() + attributes.expires * 864e5);
324
+ }
325
+ if (attributes.expires) {
326
+ attributes.expires = attributes.expires.toUTCString();
327
+ }
328
+ name = encodeURIComponent(name).replace(/%(2[346B]|5E|60|7C)/g, decodeURIComponent).replace(/[()]/g, escape);
329
+ var stringifiedAttributes = "";
330
+ for (var attributeName in attributes) {
331
+ if (!attributes[attributeName]) {
332
+ continue;
333
+ }
334
+ stringifiedAttributes += "; " + attributeName;
335
+ if (attributes[attributeName] === true) {
336
+ continue;
337
+ }
338
+ stringifiedAttributes += "=" + attributes[attributeName].split(";")[0];
339
+ }
340
+ return document.cookie = name + "=" + converter.write(value, name) + stringifiedAttributes;
341
+ }
342
+ function get(name) {
343
+ if (typeof document === "undefined" || arguments.length && !name) {
344
+ return;
345
+ }
346
+ var cookies = document.cookie ? document.cookie.split("; ") : [];
347
+ var jar = {};
348
+ for (var i = 0; i < cookies.length; i++) {
349
+ var parts = cookies[i].split("=");
350
+ var value = parts.slice(1).join("=");
351
+ try {
352
+ var found = decodeURIComponent(parts[0]);
353
+ jar[found] = converter.read(value, found);
354
+ if (name === found) {
355
+ break;
356
+ }
357
+ } catch (e) {
358
+ }
359
+ }
360
+ return name ? jar[name] : jar;
361
+ }
362
+ return Object.create(
363
+ {
364
+ set,
365
+ get,
366
+ remove: function(name, attributes) {
367
+ set(
368
+ name,
369
+ "",
370
+ assign({}, attributes, {
371
+ expires: -1
372
+ })
373
+ );
374
+ },
375
+ withAttributes: function(attributes) {
376
+ return init(this.converter, assign({}, this.attributes, attributes));
377
+ },
378
+ withConverter: function(converter2) {
379
+ return init(assign({}, this.converter, converter2), this.attributes);
380
+ }
381
+ },
382
+ {
383
+ attributes: { value: Object.freeze(defaultAttributes) },
384
+ converter: { value: Object.freeze(converter) }
385
+ }
386
+ );
387
+ }
388
+ var api = init(defaultConverter, { path: "/" });
389
+
390
+ // src/services/utils/cookie-utils.ts
391
+ var _CookieUtils = class _CookieUtils {
392
+ /**
393
+ * Get the access token cookie key from environment variables
394
+ */
395
+ static getAccessTokenKey() {
396
+ return process.env.AUTH_ACCESS_TOKEN_KEY || "auth_access_token";
397
+ }
398
+ /**
399
+ * Get the refresh token cookie key from environment variables
400
+ */
401
+ static getRefreshTokenKey() {
402
+ return process.env.AUTH_REFRESH_TOKEN_KEY || "auth_refresh_token";
403
+ }
404
+ // Use current domain in development
405
+ /**
406
+ * Get root domain for subdomain support
407
+ */
408
+ static getRootDomain() {
409
+ if (typeof window === "undefined") return void 0;
410
+ const hostname = window.location.hostname;
411
+ if (hostname === "localhost" || hostname === "127.0.0.1") {
412
+ return void 0;
413
+ }
414
+ if (/^\d+\.\d+\.\d+\.\d+$/.test(hostname)) {
415
+ return void 0;
416
+ }
417
+ const parts = hostname.split(".");
418
+ if (parts.length >= 2) {
419
+ return `.${parts.slice(-2).join(".")}`;
420
+ }
421
+ return void 0;
422
+ }
423
+ /**
424
+ * Get common cookie options
425
+ */
426
+ static getCookieOptions() {
427
+ return {
428
+ path: "/",
429
+ sameSite: "strict",
430
+ secure: process.env.NODE_ENV === "production",
431
+ // Only secure in production
432
+ domain: this.COOKIE_DOMAIN
433
+ // Support subdomains
434
+ };
435
+ }
436
+ /**
437
+ * Check if running on client side
438
+ */
439
+ static isClientSide() {
440
+ return typeof window !== "undefined";
441
+ }
442
+ /**
443
+ * Check if running on server side
444
+ */
445
+ static isServerSide() {
446
+ return typeof window === "undefined";
447
+ }
448
+ /**
449
+ * Dynamically import server action for server-side operations
450
+ */
451
+ static async getServerTokens() {
452
+ try {
453
+ const { getAuthTokens } = await import("mailsentry-auth/server");
454
+ return await getAuthTokens();
455
+ } catch (error) {
456
+ console.error("Failed to get server tokens:", error);
457
+ return { accessToken: null, refreshToken: null };
458
+ }
459
+ }
460
+ /**
461
+ * Set access token in cookie (client-side only)
462
+ */
463
+ static setAccessToken(token) {
464
+ if (this.isServerSide()) {
465
+ console.warn("setAccessToken called on server side - use server actions instead");
466
+ return;
467
+ }
468
+ const options = this.getCookieOptions();
469
+ api.set(this.getAccessTokenKey(), token, options);
470
+ }
471
+ /**
472
+ * Set refresh token in cookie (client-side only)
473
+ */
474
+ static setRefreshToken(token) {
475
+ if (this.isServerSide()) {
476
+ console.warn("setRefreshToken called on server side - use server actions instead");
477
+ return;
478
+ }
479
+ const options = this.getCookieOptions();
480
+ api.set(this.getRefreshTokenKey(), token, options);
481
+ }
482
+ /**
483
+ * Get access token - automatically handles client/server side
484
+ */
485
+ static async getAccessToken() {
486
+ if (this.isClientSide()) {
487
+ return api.get(this.getAccessTokenKey()) || null;
488
+ } else {
489
+ const { accessToken } = await this.getServerTokens();
490
+ return accessToken;
491
+ }
492
+ }
493
+ /**
494
+ * Get refresh token - automatically handles client/server side
495
+ */
496
+ static async getRefreshToken() {
497
+ if (this.isClientSide()) {
498
+ return api.get(this.getRefreshTokenKey()) || null;
499
+ } else {
500
+ const { refreshToken } = await this.getServerTokens();
501
+ return refreshToken;
502
+ }
503
+ }
504
+ /**
505
+ * Get both tokens - automatically handles client/server side
506
+ */
507
+ static async getTokens() {
508
+ if (this.isClientSide()) {
509
+ return {
510
+ accessToken: api.get(this.getAccessTokenKey()) || null,
511
+ refreshToken: api.get(this.getRefreshTokenKey()) || null
512
+ };
513
+ } else {
514
+ return await this.getServerTokens();
515
+ }
516
+ }
517
+ /**
518
+ * Clear all authentication cookies (client-side only)
519
+ */
520
+ static clearAuthCookies() {
521
+ if (this.isServerSide()) {
522
+ console.warn("clearAuthCookies called on server side - use server actions instead");
523
+ return;
524
+ }
525
+ const removeOptions = {
526
+ path: "/",
527
+ domain: this.COOKIE_DOMAIN
528
+ };
529
+ api.remove(this.getAccessTokenKey(), removeOptions);
530
+ api.remove(this.getRefreshTokenKey(), removeOptions);
531
+ }
532
+ /**
533
+ * Check if cookies are supported/enabled (client-side only)
534
+ */
535
+ static areCookiesEnabled() {
536
+ if (this.isServerSide()) {
537
+ console.warn("areCookiesEnabled called on server side - not applicable");
538
+ return false;
539
+ }
540
+ try {
541
+ const testKey = "test_cookie_support";
542
+ const testOptions = this.getCookieOptions();
543
+ api.set(testKey, "test", testOptions);
544
+ const value = api.get(testKey);
545
+ api.remove(testKey, {
546
+ path: "/",
547
+ domain: this.COOKIE_DOMAIN
548
+ });
549
+ return value === "test";
550
+ } catch (e) {
551
+ return false;
552
+ }
553
+ }
554
+ /**
555
+ * Get all authentication cookies - automatically handles client/server side
556
+ */
557
+ static async getAllAuthCookies() {
558
+ if (this.isClientSide()) {
559
+ return {
560
+ accessToken: api.get(this.getAccessTokenKey()) || "",
561
+ refreshToken: api.get(this.getRefreshTokenKey()) || ""
562
+ };
563
+ } else {
564
+ const { accessToken, refreshToken } = await this.getServerTokens();
565
+ return {
566
+ accessToken: accessToken || "",
567
+ refreshToken: refreshToken || ""
568
+ };
569
+ }
570
+ }
571
+ /**
572
+ * Set multiple tokens at once (client-side only)
573
+ */
574
+ static setTokens(accessToken, refreshToken) {
575
+ if (this.isServerSide()) {
576
+ console.warn("setTokens called on server side - use server actions instead");
577
+ return;
578
+ }
579
+ this.setAccessToken(accessToken);
580
+ this.setRefreshToken(refreshToken);
581
+ }
582
+ /**
583
+ * Check if user has valid tokens - automatically handles client/server side
584
+ */
585
+ static async hasValidTokens() {
586
+ const tokens = await this.getTokens();
587
+ return !!(tokens.accessToken && tokens.refreshToken);
588
+ }
589
+ /**
590
+ * Get current domain information for debugging
591
+ */
592
+ static getDomainInfo() {
593
+ if (this.isServerSide()) {
594
+ return {
595
+ error: "Server-side rendering - no domain info available",
596
+ environment: process.env.NODE_ENV || "unknown",
597
+ recommendation: "Use server actions for server-side cookie access"
598
+ };
599
+ }
600
+ return {
601
+ hostname: window.location.hostname,
602
+ domain: this.COOKIE_DOMAIN || "current domain",
603
+ environment: process.env.NODE_ENV || "unknown",
604
+ protocol: window.location.protocol
605
+ };
606
+ }
607
+ };
608
+ // Domain configuration
609
+ _CookieUtils.COOKIE_DOMAIN = process.env.NODE_ENV === "production" ? _CookieUtils.getRootDomain() : void 0;
610
+ var CookieUtils = _CookieUtils;
611
+
612
+ // src/services/utils/localstorage-utils.ts
613
+ var LocalStorageUtils = class {
614
+ // 5 minutes
615
+ /**
616
+ * Check if localStorage is available
617
+ */
618
+ static isAvailable() {
619
+ try {
620
+ if (typeof window === "undefined") return false;
621
+ localStorage.setItem("test", "test");
622
+ localStorage.removeItem("test");
623
+ return true;
624
+ } catch (e) {
625
+ return false;
626
+ }
627
+ }
628
+ /**
629
+ * Save user profile to localStorage with timestamp
630
+ */
631
+ static saveUserProfile(userProfile) {
632
+ if (!this.isAvailable() || !userProfile) return false;
633
+ try {
634
+ localStorage.setItem(this.USER_PROFILE_STORAGE_KEY, JSON.stringify(userProfile));
635
+ localStorage.setItem(this.USER_PROFILE_TIMESTAMP_KEY, Date.now().toString());
636
+ return true;
637
+ } catch (e) {
638
+ return false;
639
+ }
640
+ }
641
+ /**
642
+ * Get user profile from localStorage with cache validation
643
+ */
644
+ static getUserProfile(cacheDuration = this.DEFAULT_CACHE_DURATION) {
645
+ if (!this.isAvailable()) return null;
646
+ try {
647
+ const userProfileData = localStorage.getItem(this.USER_PROFILE_STORAGE_KEY);
648
+ const timestamp = localStorage.getItem(this.USER_PROFILE_TIMESTAMP_KEY);
649
+ if (!userProfileData || !timestamp) return null;
650
+ const cacheAge = Date.now() - parseInt(timestamp);
651
+ if (cacheAge >= cacheDuration) {
652
+ this.clearUserProfile();
653
+ return null;
654
+ }
655
+ return JSON.parse(userProfileData);
656
+ } catch (e) {
657
+ this.clearUserProfile();
658
+ return null;
659
+ }
660
+ }
661
+ /**
662
+ * Clear user profile data from localStorage
663
+ */
664
+ static clearUserProfile() {
665
+ if (!this.isAvailable()) return false;
666
+ try {
667
+ localStorage.removeItem(this.USER_PROFILE_STORAGE_KEY);
668
+ localStorage.removeItem(this.USER_PROFILE_TIMESTAMP_KEY);
669
+ return true;
670
+ } catch (e) {
671
+ return false;
672
+ }
673
+ }
674
+ /**
675
+ * Check if cached user profile is still valid
676
+ */
677
+ static isCacheValid(cacheDuration = this.DEFAULT_CACHE_DURATION) {
678
+ if (!this.isAvailable()) return false;
679
+ try {
680
+ const timestamp = localStorage.getItem(this.USER_PROFILE_TIMESTAMP_KEY);
681
+ if (!timestamp) return false;
682
+ const cacheAge = Date.now() - parseInt(timestamp);
683
+ return cacheAge < cacheDuration;
684
+ } catch (e) {
685
+ return false;
686
+ }
687
+ }
688
+ };
689
+ LocalStorageUtils.USER_PROFILE_STORAGE_KEY = "user_profile_data";
690
+ LocalStorageUtils.USER_PROFILE_TIMESTAMP_KEY = "user_profile_timestamp";
691
+ LocalStorageUtils.DEFAULT_CACHE_DURATION = 5 * 60 * 1e3;
692
+
693
+ // src/services/utils/event-bus.ts
694
+ var REGISTRY_KEY = "__bc_event_buses__";
695
+ function getRegistry() {
696
+ const g = globalThis;
697
+ if (!g[REGISTRY_KEY]) {
698
+ g[REGISTRY_KEY] = /* @__PURE__ */ new Map();
699
+ }
700
+ return g[REGISTRY_KEY];
701
+ }
702
+ function isBroadcastChannelSupported() {
703
+ return typeof window !== "undefined" && "BroadcastChannel" in window && typeof BroadcastChannel === "function";
704
+ }
705
+ var BroadcastChannelEventBus = class _BroadcastChannelEventBus {
706
+ constructor(name) {
707
+ this.listeners = /* @__PURE__ */ new Set();
708
+ this.name = name;
709
+ if (isBroadcastChannelSupported()) {
710
+ try {
711
+ this.channel = new BroadcastChannel(name);
712
+ this.channel.onmessage = (ev) => this.emit(ev.data);
713
+ } catch (error) {
714
+ console.warn("Failed to create BroadcastChannel:", error);
715
+ }
716
+ }
717
+ }
718
+ static getInstance(name) {
719
+ const registry = getRegistry();
720
+ let bus = registry.get(name);
721
+ if (!bus) {
722
+ bus = new _BroadcastChannelEventBus(name);
723
+ registry.set(name, bus);
724
+ }
725
+ return bus;
726
+ }
727
+ publish(event) {
728
+ var _a;
729
+ this.emit(event);
730
+ (_a = this.channel) == null ? void 0 : _a.postMessage(event);
731
+ }
732
+ subscribe(handler) {
733
+ this.listeners.add(handler);
734
+ return { unsubscribe: () => this.listeners.delete(handler) };
735
+ }
736
+ emit(e) {
737
+ for (const h of this.listeners) h(e);
738
+ }
739
+ close() {
740
+ var _a;
741
+ (_a = this.channel) == null ? void 0 : _a.close();
742
+ this.listeners.clear();
743
+ getRegistry().delete(this.name);
744
+ }
745
+ };
746
+
747
+ // src/services/utils/cross-tab-behavior-handler.ts
748
+ var CrossTabBehaviorHandler = class {
749
+ /**
750
+ * Get current page type based on pathname using pattern matching
751
+ */
752
+ static getCurrentPageType() {
753
+ var _a, _b;
754
+ 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 */;
759
+ }
760
+ /**
761
+ * Get the action configuration for current route and event
762
+ */
763
+ static getAction(currentPageType, eventType) {
764
+ var _a, _b;
765
+ return (_b = (_a = CrossTabBehaviorConfig[currentPageType]) == null ? void 0 : _a[eventType]) != null ? _b : { action: "none" /* NONE */ };
766
+ }
767
+ /**
768
+ * Check if current route requires redirect for given event
769
+ */
770
+ static shouldRedirect(currentPageType, eventType) {
771
+ const action = this.getAction(currentPageType, eventType);
772
+ return action.action === "redirect" /* REDIRECT */ ? action.target : null;
773
+ }
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
+ };
782
+
783
+ // src/services/auth/manager/token-manager.ts
784
+ var TokenManager = class {
785
+ constructor(cookieUtils) {
786
+ this.cookieUtils = cookieUtils;
787
+ }
788
+ saveTokens(accessToken, refreshToken) {
789
+ if (refreshToken) {
790
+ this.cookieUtils.setTokens(accessToken, refreshToken);
791
+ } else {
792
+ this.cookieUtils.setAccessToken(accessToken);
793
+ }
794
+ }
795
+ clearTokens() {
796
+ this.cookieUtils.clearAuthCookies();
797
+ }
798
+ async getAccessToken() {
799
+ return await this.cookieUtils.getAccessToken();
800
+ }
801
+ async getRefreshToken() {
802
+ return await this.cookieUtils.getRefreshToken();
803
+ }
804
+ /**
805
+ * Get all stored tokens for debugging or validation
806
+ */
807
+ async getAllTokens() {
808
+ return await this.cookieUtils.getAllAuthCookies();
809
+ }
810
+ /**
811
+ * Check if cookies are supported in the current environment
812
+ */
813
+ areCookiesSupported() {
814
+ return this.cookieUtils.areCookiesEnabled();
815
+ }
816
+ /**
817
+ * Get domain information for debugging
818
+ */
819
+ getDomainInfo() {
820
+ return this.cookieUtils.getDomainInfo();
821
+ }
822
+ };
823
+
824
+ // src/services/api/base-service.ts
825
+ var HttpClient = class {
826
+ constructor(config2) {
827
+ this.config = config2;
828
+ }
829
+ /**
830
+ * Execute HTTP request
831
+ */
832
+ async request(endpoint, options) {
833
+ try {
834
+ const url = `${this.config.baseURL}${endpoint}`;
835
+ const fetchOptions = {
836
+ method: options.method,
837
+ headers: await this.buildHeaders(options.headers),
838
+ body: options.body ? JSON.stringify(options.body) : void 0
839
+ };
840
+ const response = await this.executeWithTimeout(
841
+ fetch(url, fetchOptions),
842
+ options.timeout || this.config.timeout || 3e4
843
+ );
844
+ const httpResponse = {
845
+ data: await response.json(),
846
+ status: response.status,
847
+ statusText: response.statusText,
848
+ headers: response.headers,
849
+ ok: response.ok
850
+ };
851
+ return httpResponse;
852
+ } catch (error) {
853
+ const httpError = {
854
+ name: "HttpError",
855
+ message: error instanceof Error ? error.message : "Unknown error",
856
+ status: error instanceof Response ? error.status : void 0,
857
+ statusText: error instanceof Response ? error.statusText : void 0,
858
+ response: error
859
+ };
860
+ throw httpError;
861
+ }
862
+ }
863
+ /**
864
+ * Build headers with defaults including multiple API keys and Bearer token
865
+ */
866
+ async buildHeaders(customHeaders) {
867
+ var _a, _b;
868
+ const defaultHeaders = {
869
+ "Content-Type": "application/json"
870
+ };
871
+ if (this.config.origin) {
872
+ defaultHeaders["Origin"] = this.config.origin;
873
+ }
874
+ if (this.config.apiKeys) {
875
+ Object.assign(defaultHeaders, this.config.apiKeys);
876
+ }
877
+ const accessToken = await ((_b = (_a = this.config).getAccessToken) == null ? void 0 : _b.call(_a));
878
+ if (accessToken) {
879
+ defaultHeaders["authorization"] = `Bearer ${accessToken}`;
880
+ }
881
+ return __spreadValues(__spreadValues({}, defaultHeaders), customHeaders);
882
+ }
883
+ /**
884
+ * Execute request with timeout
885
+ */
886
+ async executeWithTimeout(promise, timeoutMs) {
887
+ const timeoutPromise = new Promise((_, reject) => {
888
+ setTimeout(() => reject(new Error(`Request timeout after ${timeoutMs}ms`)), timeoutMs);
889
+ });
890
+ return Promise.race([promise, timeoutPromise]);
891
+ }
892
+ };
893
+ var ApiError = class extends Error {
894
+ constructor(message2, status, statusText, apiError) {
895
+ super(message2);
896
+ this.name = "ApiError";
897
+ this.status = status;
898
+ this.statusText = statusText;
899
+ this.apiError = apiError;
900
+ }
901
+ };
902
+ var BaseService = class {
903
+ constructor(httpClient, tokenManager) {
904
+ this.tokenManager = tokenManager || new TokenManager(CookieUtils);
905
+ this.httpClient = httpClient || this.createDefaultHttpClient();
906
+ }
907
+ /**
908
+ * Create default HTTP client with configuration
909
+ */
910
+ createDefaultHttpClient() {
911
+ const config2 = {
912
+ baseURL: process.env.NEXT_PUBLIC_API_BASE_URL || "",
913
+ apiKeys: {
914
+ "x-api-key": process.env.NEXT_PUBLIC_API_KEY || ""
915
+ },
916
+ timeout: 3e4,
917
+ retries: 3,
918
+ origin: process.env.NEXT_PUBLIC_API_ORIGIN || "",
919
+ getAccessToken: async () => await this.tokenManager.getAccessToken()
920
+ };
921
+ return new HttpClient(config2);
922
+ }
923
+ /**
924
+ * Handle HTTP response and throw structured error if needed
925
+ */
926
+ handleResponse(response) {
927
+ if (response.ok) {
928
+ return response.data;
929
+ }
930
+ const apiError = this.createApiErrorFromResponse(response);
931
+ throw new ApiError(
932
+ apiError.message,
933
+ response.status,
934
+ response.statusText,
935
+ apiError
936
+ );
937
+ }
938
+ /**
939
+ * Create API error from HTTP response following Single Responsibility Principle
940
+ */
941
+ createApiErrorFromResponse(response) {
942
+ const parsedError = this.tryParseApiErrorResponse(response.data);
943
+ if (parsedError) {
944
+ return parsedError;
945
+ }
946
+ return this.createGenericApiError(response);
947
+ }
948
+ /**
949
+ * Try to parse API error response from response data
950
+ */
951
+ tryParseApiErrorResponse(data) {
952
+ try {
953
+ const responseData = data;
954
+ if (this.isValidApiErrorResponse(responseData)) {
955
+ return __spreadValues({
956
+ message: String(responseData.message),
957
+ error: String(responseData.error),
958
+ statusCode: Number(responseData.statusCode)
959
+ }, responseData);
960
+ }
961
+ return null;
962
+ } catch (e) {
963
+ return null;
964
+ }
965
+ }
966
+ /**
967
+ * Check if response data has valid API error structure
968
+ */
969
+ isValidApiErrorResponse(data) {
970
+ return data && typeof data === "object" && "message" in data && "error" in data && "statusCode" in data;
971
+ }
972
+ /**
973
+ * Create generic API error as fallback
974
+ */
975
+ createGenericApiError(response) {
976
+ return {
977
+ message: response.statusText || "Unknown error",
978
+ error: "HTTP Error",
979
+ statusCode: response.status
980
+ };
981
+ }
982
+ /**
983
+ * GET request
984
+ */
985
+ async get(endpoint, headers) {
986
+ const response = await this.httpClient.request(endpoint, {
987
+ method: "GET" /* GET */,
988
+ url: endpoint,
989
+ headers
990
+ });
991
+ return this.handleResponse(response);
992
+ }
993
+ /**
994
+ * POST request
995
+ */
996
+ async post(endpoint, body, headers) {
997
+ const response = await this.httpClient.request(endpoint, {
998
+ method: "POST" /* POST */,
999
+ url: endpoint,
1000
+ headers,
1001
+ body
1002
+ });
1003
+ return this.handleResponse(response);
1004
+ }
1005
+ /**
1006
+ * PUT request
1007
+ */
1008
+ async put(endpoint, body, headers) {
1009
+ const response = await this.httpClient.request(endpoint, {
1010
+ method: "PUT" /* PUT */,
1011
+ url: endpoint,
1012
+ headers,
1013
+ body
1014
+ });
1015
+ return this.handleResponse(response);
1016
+ }
1017
+ /**
1018
+ * DELETE request
1019
+ */
1020
+ async delete(endpoint, headers) {
1021
+ const response = await this.httpClient.request(endpoint, {
1022
+ method: "DELETE" /* DELETE */,
1023
+ url: endpoint,
1024
+ headers
1025
+ });
1026
+ return this.handleResponse(response);
1027
+ }
1028
+ /**
1029
+ * PATCH request
1030
+ */
1031
+ async patch(endpoint, body, headers) {
1032
+ const response = await this.httpClient.request(endpoint, {
1033
+ method: "PATCH" /* PATCH */,
1034
+ url: endpoint,
1035
+ headers,
1036
+ body
1037
+ });
1038
+ return this.handleResponse(response);
1039
+ }
1040
+ };
1041
+
1042
+ // src/services/api/endpoints.ts
1043
+ var AUTH_ENDPOINTS = {
1044
+ // Email existence check
1045
+ CHECK_EMAIL_EXISTS: (email) => `/auth/user/exist-email/${encodeURIComponent(email)}`,
1046
+ // User authentication
1047
+ LOGIN: "/auth/user/login",
1048
+ VERIFY_EMAIL: "/auth/user/verify",
1049
+ // User profile
1050
+ GET_USER_PROFILE: "/auth/user/profile",
1051
+ // User logout
1052
+ LOGOUT: "/auth/logout"
1053
+ };
1054
+ var EndpointBuilder = class {
1055
+ };
1056
+ EndpointBuilder.auth = AUTH_ENDPOINTS;
1057
+
1058
+ // src/services/api/auth-service.ts
1059
+ var AuthService = class extends BaseService {
1060
+ /**
1061
+ * Check if an email exists in the system
1062
+ */
1063
+ async checkEmailExists(email) {
1064
+ const endpoint = AUTH_ENDPOINTS.CHECK_EMAIL_EXISTS(email);
1065
+ return this.get(endpoint);
1066
+ }
1067
+ /**
1068
+ * Login with email and password
1069
+ */
1070
+ async login(credentials) {
1071
+ const endpoint = AUTH_ENDPOINTS.LOGIN;
1072
+ return this.post(endpoint, credentials);
1073
+ }
1074
+ /**
1075
+ * Verify email with verification code
1076
+ */
1077
+ async verifyEmail(verification) {
1078
+ const endpoint = AUTH_ENDPOINTS.VERIFY_EMAIL;
1079
+ return this.post(endpoint, verification);
1080
+ }
1081
+ /**
1082
+ * Get user profile
1083
+ */
1084
+ async getUserProfile() {
1085
+ const endpoint = AUTH_ENDPOINTS.GET_USER_PROFILE;
1086
+ return this.get(endpoint);
1087
+ }
1088
+ /**
1089
+ * Logout user
1090
+ */
1091
+ async logout() {
1092
+ const endpoint = AUTH_ENDPOINTS.LOGOUT;
1093
+ return this.post(endpoint);
1094
+ }
1095
+ };
1096
+
1097
+ // src/services/auth/manager/user-storage-manager.ts
1098
+ var UserStorageManager = class {
1099
+ constructor(storageUtils) {
1100
+ this.storageUtils = storageUtils;
1101
+ }
1102
+ /**
1103
+ * Save user profile data to storage
1104
+ */
1105
+ saveUserProfile(userProfile) {
1106
+ return this.storageUtils.saveUserProfile(userProfile);
1107
+ }
1108
+ /**
1109
+ * Get user profile data from storage
1110
+ */
1111
+ getUserProfile(cacheDuration) {
1112
+ return this.storageUtils.getUserProfile(cacheDuration);
1113
+ }
1114
+ /**
1115
+ * Clear user profile data from storage
1116
+ */
1117
+ clearUserProfile() {
1118
+ return this.storageUtils.clearUserProfile();
1119
+ }
1120
+ /**
1121
+ * Check if cached user profile is still valid
1122
+ */
1123
+ isCacheValid(cacheDuration) {
1124
+ return this.storageUtils.isCacheValid(cacheDuration);
1125
+ }
1126
+ /**
1127
+ * Get user profile with automatic cache validation
1128
+ * Returns null if cache is expired or invalid
1129
+ */
1130
+ getValidUserProfile(cacheDuration) {
1131
+ if (!this.isCacheValid(cacheDuration)) {
1132
+ return null;
1133
+ }
1134
+ return this.getUserProfile(cacheDuration);
1135
+ }
1136
+ };
1137
+
1138
+ // src/services/auth/patterns/command/auth-result-factory.ts
1139
+ var AuthResultFactory = class {
1140
+ /**
1141
+ * Creates a successful authentication result
1142
+ */
1143
+ static createSuccess(message2, data) {
1144
+ return {
1145
+ success: true,
1146
+ data,
1147
+ message: message2
1148
+ };
1149
+ }
1150
+ /**
1151
+ * Creates a failed authentication result
1152
+ */
1153
+ static createFailure(message2, error) {
1154
+ const errorMessage = error instanceof Error ? error.message : typeof error === "string" ? error : error ? String(error) : "Authentication failed";
1155
+ return {
1156
+ success: false,
1157
+ error: errorMessage,
1158
+ message: message2
1159
+ };
1160
+ }
1161
+ };
1162
+
1163
+ // src/services/auth/patterns/logger/development-logger.ts
1164
+ var DevelopmentLogger = class {
1165
+ log(message2, data) {
1166
+ console.log(message2, data);
1167
+ }
1168
+ warn(message2, data) {
1169
+ console.warn(message2, data);
1170
+ }
1171
+ error(message2, data) {
1172
+ console.error(message2, data);
1173
+ }
1174
+ };
1175
+
1176
+ // src/services/auth/patterns/logger/production-logger.ts
1177
+ var ProductionLogger = class {
1178
+ log(_message, _data) {
1179
+ }
1180
+ warn(_message, _data) {
1181
+ }
1182
+ error(_message, _data) {
1183
+ }
1184
+ };
1185
+
1186
+ // src/services/auth/patterns/logger/logger-factory.ts
1187
+ var LoggerFactory = class {
1188
+ static create(environment) {
1189
+ const env = environment || process.env.NODE_ENV || "development";
1190
+ const loggerFactory = this.loggers.get(env) || this.loggers.get("development");
1191
+ return loggerFactory();
1192
+ }
1193
+ };
1194
+ LoggerFactory.loggers = /* @__PURE__ */ new Map([
1195
+ ["development", () => new DevelopmentLogger()],
1196
+ ["production", () => new ProductionLogger()],
1197
+ ["test", () => new DevelopmentLogger()]
1198
+ ]);
1199
+
1200
+ // src/services/auth/patterns/strategy/signup-flow-strategy.ts
1201
+ var SignupFlowStrategy = class {
1202
+ constructor(authService, tokenManager) {
1203
+ this.authService = authService;
1204
+ this.tokenManager = tokenManager;
1205
+ }
1206
+ async execute(credentials) {
1207
+ const loginResult = await this.authService.login(credentials);
1208
+ if (!loginResult.data.isVerifiedEmail) {
1209
+ return AuthResultFactory.createFailure("Email verification required");
1210
+ }
1211
+ return this.handleSuccessfulAuthentication(loginResult);
1212
+ }
1213
+ async handleSuccessfulAuthentication(loginResult) {
1214
+ if (loginResult.data.accessToken) {
1215
+ this.tokenManager.saveTokens(
1216
+ loginResult.data.accessToken,
1217
+ loginResult.data.refreshToken
1218
+ );
1219
+ LoggerFactory.create("development").log("Tokens saved successfully:", {
1220
+ hasAccessToken: !!loginResult.data.accessToken,
1221
+ hasRefreshToken: !!loginResult.data.refreshToken,
1222
+ domainInfo: this.tokenManager.getDomainInfo()
1223
+ });
1224
+ const profile = await this.authService.getUserProfile();
1225
+ return AuthResultFactory.createSuccess("Login successful", __spreadProps(__spreadValues({}, loginResult.data), {
1226
+ profile: profile.data,
1227
+ tokenInfo: {
1228
+ domain: this.tokenManager.getDomainInfo().domain
1229
+ }
1230
+ }));
1231
+ }
1232
+ return AuthResultFactory.createFailure("Authentication failed - no access token received");
1233
+ }
1234
+ };
1235
+
1236
+ // src/services/auth/patterns/strategy/existing-user-login-strategy.ts
1237
+ var ExistingUserLoginStrategy = class {
1238
+ constructor(authService, tokenManager) {
1239
+ this.authService = authService;
1240
+ this.tokenManager = tokenManager;
1241
+ }
1242
+ async execute(credentials) {
1243
+ const loginResult = await this.authService.login(credentials);
1244
+ return this.handleSuccessfulAuthentication(loginResult);
1245
+ }
1246
+ async handleSuccessfulAuthentication(loginResult) {
1247
+ if (loginResult.data.accessToken) {
1248
+ this.tokenManager.saveTokens(
1249
+ loginResult.data.accessToken,
1250
+ loginResult.data.refreshToken
1251
+ );
1252
+ LoggerFactory.create("development").log("Tokens saved successfully:", {
1253
+ hasAccessToken: !!loginResult.data.accessToken,
1254
+ hasRefreshToken: !!loginResult.data.refreshToken,
1255
+ domainInfo: this.tokenManager.getDomainInfo()
1256
+ });
1257
+ const profile = await this.authService.getUserProfile();
1258
+ return AuthResultFactory.createSuccess("Login successful", __spreadProps(__spreadValues({}, loginResult.data), {
1259
+ profile: profile.data,
1260
+ tokenInfo: {
1261
+ domain: this.tokenManager.getDomainInfo().domain
1262
+ }
1263
+ }));
1264
+ }
1265
+ return AuthResultFactory.createFailure("Authentication failed - no access token received");
1266
+ }
1267
+ };
1268
+
1269
+ // src/services/auth/patterns/strategy/login-flow-strategy-factory.ts
1270
+ var LoginFlowStrategyFactory = class {
1271
+ static createStrategy(action, authService, tokenManager) {
1272
+ const strategyFactory = this.strategies.get(action);
1273
+ if (!strategyFactory) {
1274
+ throw new Error(`No strategy found for action: ${action}`);
1275
+ }
1276
+ return strategyFactory(authService, tokenManager);
1277
+ }
1278
+ };
1279
+ LoginFlowStrategyFactory.strategies = /* @__PURE__ */ new Map([
1280
+ ["signup" /* SIGNUP */, (authService, tokenManager) => new SignupFlowStrategy(authService, tokenManager)],
1281
+ ["login" /* LOGIN */, (authService, tokenManager) => new ExistingUserLoginStrategy(authService, tokenManager)]
1282
+ ]);
1283
+
1284
+ // src/services/auth/patterns/state/authenticated-state.ts
1285
+ var AuthenticatedState = class {
1286
+ async getStatus(tokenManager) {
1287
+ const authStatus = await this.buildAuthStatus(tokenManager, true);
1288
+ return AuthResultFactory.createSuccess("User is authenticated", authStatus);
1289
+ }
1290
+ async buildAuthStatus(tokenManager, isAuthenticated) {
1291
+ return {
1292
+ isAuthenticated,
1293
+ hasAccessToken: !!await tokenManager.getAccessToken(),
1294
+ hasRefreshToken: !!await tokenManager.getRefreshToken(),
1295
+ cookiesSupported: tokenManager.areCookiesSupported(),
1296
+ domainInfo: tokenManager.getDomainInfo()
1297
+ };
1298
+ }
1299
+ };
1300
+
1301
+ // src/services/auth/patterns/state/unauthenticated-state.ts
1302
+ var UnauthenticatedState = class {
1303
+ async getStatus(tokenManager) {
1304
+ const authStatus = await this.buildAuthStatus(tokenManager, false);
1305
+ return AuthResultFactory.createFailure("User is not authenticated", authStatus);
1306
+ }
1307
+ async buildAuthStatus(tokenManager, isAuthenticated) {
1308
+ return {
1309
+ isAuthenticated,
1310
+ hasAccessToken: !!await tokenManager.getAccessToken(),
1311
+ hasRefreshToken: !!await tokenManager.getRefreshToken(),
1312
+ cookiesSupported: tokenManager.areCookiesSupported(),
1313
+ domainInfo: tokenManager.getDomainInfo()
1314
+ };
1315
+ }
1316
+ };
1317
+
1318
+ // src/services/auth/patterns/state/authentication-status-context.ts
1319
+ var AuthenticationStatusContext = class {
1320
+ static async getStatus(tokenManager) {
1321
+ const isAuthenticated = !!await tokenManager.getAccessToken();
1322
+ const state = this.states.get(isAuthenticated) || new UnauthenticatedState();
1323
+ return await state.getStatus(tokenManager);
1324
+ }
1325
+ };
1326
+ AuthenticationStatusContext.states = /* @__PURE__ */ new Map([
1327
+ [true, new AuthenticatedState()],
1328
+ [false, new UnauthenticatedState()]
1329
+ ]);
1330
+
1331
+ // src/services/auth/patterns/chain/base-error-handler.ts
1332
+ var BaseErrorHandler = class {
1333
+ setNext(handler) {
1334
+ this.nextHandler = handler;
1335
+ return handler;
1336
+ }
1337
+ handle(error, context) {
1338
+ if (this.canHandle(error)) {
1339
+ return this.handleError(error, context);
1340
+ }
1341
+ if (this.nextHandler) {
1342
+ return this.nextHandler.handle(error, context);
1343
+ }
1344
+ return AuthResultFactory.createFailure(`${context} failed with unknown error`, error);
1345
+ }
1346
+ };
1347
+
1348
+ // src/services/auth/patterns/chain/validation-error-handler.ts
1349
+ var ValidationErrorHandler = class extends BaseErrorHandler {
1350
+ canHandle(error) {
1351
+ return error instanceof Error && error.message.includes("validation");
1352
+ }
1353
+ handleError(error, context) {
1354
+ console.error(`${context} validation error:`, error);
1355
+ return AuthResultFactory.createFailure(`${context} validation failed`, error);
1356
+ }
1357
+ };
1358
+
1359
+ // src/services/auth/patterns/chain/network-error-handler.ts
1360
+ var NetworkErrorHandler = class extends BaseErrorHandler {
1361
+ canHandle(error) {
1362
+ return error instanceof Error && (error.message.includes("network") || error.message.includes("fetch") || error.message.includes("timeout"));
1363
+ }
1364
+ handleError(error, context) {
1365
+ console.error(`${context} network error:`, error);
1366
+ return AuthResultFactory.createFailure(`${context} network error`, error);
1367
+ }
1368
+ };
1369
+
1370
+ // src/services/auth/patterns/chain/generic-error-handler.ts
1371
+ var GenericErrorHandler = class extends BaseErrorHandler {
1372
+ canHandle(_error) {
1373
+ return true;
1374
+ }
1375
+ handleError(error, context) {
1376
+ console.error(`${context} error:`, error);
1377
+ return AuthResultFactory.createFailure(`${context} failed`, error);
1378
+ }
1379
+ };
1380
+
1381
+ // src/services/auth/auth-orchestrator.ts
1382
+ var AuthOrchestrator = class {
1383
+ constructor(authService, eventBus, tokenManager) {
1384
+ this.authService = authService;
1385
+ this.eventBus = eventBus;
1386
+ this.tokenManager = tokenManager || new TokenManager(CookieUtils);
1387
+ this.userStorageManager = new UserStorageManager(LocalStorageUtils);
1388
+ this.logger = LoggerFactory.create();
1389
+ this.errorHandler = this.setupErrorHandlerChain();
1390
+ this.validateCookieSupport();
1391
+ }
1392
+ /**
1393
+ * Setup Chain of Responsibility for error handling
1394
+ */
1395
+ setupErrorHandlerChain() {
1396
+ const validationHandler = new ValidationErrorHandler();
1397
+ const networkHandler = new NetworkErrorHandler();
1398
+ const genericHandler = new GenericErrorHandler();
1399
+ validationHandler.setNext(networkHandler).setNext(genericHandler);
1400
+ return validationHandler;
1401
+ }
1402
+ /**
1403
+ * Validate that cookies are supported in the current environment
1404
+ */
1405
+ validateCookieSupport() {
1406
+ if (!this.tokenManager.areCookiesSupported()) {
1407
+ this.logger.warn("Cookies are not supported in this environment. Authentication may not work properly.");
1408
+ }
1409
+ }
1410
+ /**
1411
+ * Handle email check to determine if user exists and what action to take
1412
+ */
1413
+ async handleEmailCheck(email) {
1414
+ try {
1415
+ const emailCheck = await this.authService.checkEmailExists(email);
1416
+ const message2 = {
1417
+ ["signup" /* SIGNUP */]: "Welcome! Please create your account.",
1418
+ ["login" /* LOGIN */]: "Welcome back! Please enter your password.",
1419
+ ["login-verification" /* LOGIN_VERIFICATION */]: "Please verify your email."
1420
+ }[emailCheck.next_action];
1421
+ if (!message2) {
1422
+ throw new Error("Invalid next action");
1423
+ }
1424
+ return AuthResultFactory.createSuccess(message2, emailCheck);
1425
+ } catch (error) {
1426
+ return this.errorHandler.handle(error, "Email check");
1427
+ }
1428
+ }
1429
+ /**
1430
+ * Handle complete login flow with proper error handling and token management
1431
+ */
1432
+ async handleLoginFlow(credentials) {
1433
+ try {
1434
+ const emailCheck = await this.authService.checkEmailExists(credentials.email);
1435
+ const strategy = LoginFlowStrategyFactory.createStrategy(
1436
+ emailCheck.next_action,
1437
+ this.authService,
1438
+ this.tokenManager
1439
+ );
1440
+ const result = await strategy.execute(credentials);
1441
+ if (result.success) {
1442
+ const currentPageType = CrossTabBehaviorHandler.getCurrentPageType();
1443
+ this.eventBus.publish({
1444
+ type: "auth.logged_in" /* LoggedIn */,
1445
+ userId: String(result.data.profile.user._id),
1446
+ sourcePageType: currentPageType
1447
+ });
1448
+ }
1449
+ return result;
1450
+ } catch (error) {
1451
+ return this.errorHandler.handle(error, "Login flow");
1452
+ }
1453
+ }
1454
+ /**
1455
+ * Handle email verification flow
1456
+ */
1457
+ async handleEmailVerification(email, code) {
1458
+ var _a;
1459
+ try {
1460
+ const verificationRequest = { email, code };
1461
+ const verificationResult = await this.authService.verifyEmail(verificationRequest);
1462
+ const isVerified = verificationResult === true || ((_a = verificationResult == null ? void 0 : verificationResult.data) == null ? void 0 : _a.isVerified);
1463
+ if (isVerified) {
1464
+ this.eventBus.publish({ type: "auth.email_verified" /* EmailVerified */, email });
1465
+ return AuthResultFactory.createSuccess("Email verified successfully", { isVerified: true });
1466
+ }
1467
+ return AuthResultFactory.createFailure("Email verification failed", "Email verification failed");
1468
+ } catch (error) {
1469
+ return this.errorHandler.handle(error, "Email verification");
1470
+ }
1471
+ }
1472
+ /**
1473
+ * Handle logout flow
1474
+ */
1475
+ async handleLogout() {
1476
+ let tokenInfo = {};
1477
+ try {
1478
+ tokenInfo = await this.tokenManager.getAllTokens();
1479
+ await this.authService.logout();
1480
+ return AuthResultFactory.createSuccess("Logout successful", {
1481
+ clearedTokens: Object.keys(tokenInfo).filter((key) => tokenInfo[key])
1482
+ });
1483
+ } catch (error) {
1484
+ return this.errorHandler.handle(error, "Logout");
1485
+ } finally {
1486
+ this.tokenManager.clearTokens();
1487
+ this.userStorageManager.clearUserProfile();
1488
+ const currentPageType = CrossTabBehaviorHandler.getCurrentPageType();
1489
+ this.eventBus.publish({
1490
+ type: "auth.logged_out" /* LoggedOut */,
1491
+ sourcePageType: currentPageType
1492
+ });
1493
+ this.logger.log("Logout cleanup completed:", {
1494
+ clearedTokens: Object.keys(tokenInfo).filter((key) => tokenInfo[key]),
1495
+ domainInfo: this.tokenManager.getDomainInfo()
1496
+ });
1497
+ }
1498
+ }
1499
+ /**
1500
+ * Check current authentication status using State Pattern
1501
+ */
1502
+ async checkAuthenticationStatus() {
1503
+ try {
1504
+ return AuthenticationStatusContext.getStatus(this.tokenManager);
1505
+ } catch (error) {
1506
+ return this.errorHandler.handle(error, "Authentication status check");
1507
+ }
1508
+ }
1509
+ /**
1510
+ * Get user profile data
1511
+ */
1512
+ async getUserProfileData() {
1513
+ try {
1514
+ const hasAccessToken = !!await this.tokenManager.getAccessToken();
1515
+ if (!hasAccessToken) {
1516
+ return AuthResultFactory.createFailure("User not authenticated");
1517
+ }
1518
+ const profile = await this.authService.getUserProfile();
1519
+ return AuthResultFactory.createSuccess("Profile retrieved successfully", profile.data);
1520
+ } catch (error) {
1521
+ return this.errorHandler.handle(error, "Get user profile");
1522
+ }
1523
+ }
1524
+ /**
1525
+ * Get detailed token information
1526
+ */
1527
+ async getTokenInfo() {
1528
+ try {
1529
+ const accessToken = await this.tokenManager.getAccessToken();
1530
+ const refreshToken = await this.tokenManager.getRefreshToken();
1531
+ const allTokens = await this.tokenManager.getAllTokens();
1532
+ const domainInfo = this.tokenManager.getDomainInfo();
1533
+ const cookiesSupported = this.tokenManager.areCookiesSupported();
1534
+ const tokenInfo = {
1535
+ hasAccessToken: !!accessToken,
1536
+ hasRefreshToken: !!refreshToken,
1537
+ cookiesSupported,
1538
+ domainInfo,
1539
+ tokenCount: Object.keys(allTokens).filter((key) => allTokens[key]).length,
1540
+ environment: process.env.NODE_ENV || "unknown"
1541
+ };
1542
+ return AuthResultFactory.createSuccess("Token information retrieved", tokenInfo);
1543
+ } catch (error) {
1544
+ return this.errorHandler.handle(error, "Get token info");
1545
+ }
1546
+ }
1547
+ };
1548
+ var AuthOrchestratorFactory = class {
1549
+ /**
1550
+ * Create AuthOrchestrator with default dependencies
1551
+ */
1552
+ static create() {
1553
+ const authService = new AuthService();
1554
+ const eventBus = BroadcastChannelEventBus.getInstance("auth-event-channel" /* AUTH */);
1555
+ return new AuthOrchestrator(authService, eventBus);
1556
+ }
1557
+ /**
1558
+ * Create AuthOrchestrator with custom dependencies
1559
+ */
1560
+ static createWithDependencies(authService, eventBus, tokenManager) {
1561
+ return new AuthOrchestrator(authService, eventBus, tokenManager);
1562
+ }
1563
+ };
1564
+
1565
+ // src/store/user-store.ts
1566
+ var ERROR_MESSAGES = {
1567
+ UNEXPECTED_ERROR: "An unexpected error occurred"
1568
+ };
1569
+ var useUserStore = create()(
1570
+ devtools(
1571
+ subscribeWithSelector(
1572
+ immer((set, get) => {
1573
+ const authOrchestrator = AuthOrchestratorFactory.create();
1574
+ const userStorageManager = new UserStorageManager(LocalStorageUtils);
1575
+ return {
1576
+ // Initial state
1577
+ user: null,
1578
+ isLoading: false,
1579
+ error: null,
1580
+ isAuthenticated: false,
1581
+ // Dependencies
1582
+ _authOrchestrator: authOrchestrator,
1583
+ _userStorageManager: userStorageManager,
1584
+ // Actions
1585
+ setUser: (user) => {
1586
+ const { _userStorageManager } = get();
1587
+ if (user) {
1588
+ _userStorageManager.saveUserProfile(user);
1589
+ } else {
1590
+ _userStorageManager.clearUserProfile();
1591
+ }
1592
+ set((state) => {
1593
+ state.user = user;
1594
+ state.isAuthenticated = !!user;
1595
+ state.error = null;
1596
+ });
1597
+ },
1598
+ setLoading: (loading) => {
1599
+ set((state) => {
1600
+ state.isLoading = loading;
1601
+ });
1602
+ },
1603
+ setError: (error) => {
1604
+ set((state) => {
1605
+ state.error = error;
1606
+ state.isLoading = false;
1607
+ });
1608
+ },
1609
+ clearUser: async () => {
1610
+ const { _authOrchestrator } = get();
1611
+ set((state) => {
1612
+ state.isLoading = true;
1613
+ });
1614
+ try {
1615
+ await _authOrchestrator.handleLogout();
1616
+ } catch (error) {
1617
+ console.error("Error during logout cleanup:", error);
1618
+ } finally {
1619
+ set((state) => {
1620
+ state.user = null;
1621
+ state.isLoading = false;
1622
+ state.error = null;
1623
+ state.isAuthenticated = false;
1624
+ });
1625
+ }
1626
+ },
1627
+ refreshUser: async (forceRefresh = false) => {
1628
+ const { _authOrchestrator, _userStorageManager } = get();
1629
+ const cachedUser = !forceRefresh ? _userStorageManager.getValidUserProfile() : null;
1630
+ if (cachedUser) {
1631
+ set((state) => {
1632
+ state.user = cachedUser;
1633
+ state.isAuthenticated = true;
1634
+ state.isLoading = false;
1635
+ state.error = null;
1636
+ });
1637
+ return;
1638
+ }
1639
+ set((state) => {
1640
+ state.isLoading = true;
1641
+ state.error = null;
1642
+ });
1643
+ try {
1644
+ const result = await _authOrchestrator.getUserProfileData();
1645
+ if (result.success) {
1646
+ const userProfile = result.data;
1647
+ _userStorageManager.saveUserProfile(userProfile);
1648
+ set((state) => {
1649
+ state.user = userProfile;
1650
+ state.isAuthenticated = true;
1651
+ state.isLoading = false;
1652
+ state.error = null;
1653
+ });
1654
+ } else {
1655
+ set((state) => {
1656
+ state.user = null;
1657
+ state.isAuthenticated = false;
1658
+ state.isLoading = false;
1659
+ state.error = result.error;
1660
+ });
1661
+ }
1662
+ } catch (error) {
1663
+ const errorMessage = error instanceof Error ? error.message : ERROR_MESSAGES.UNEXPECTED_ERROR;
1664
+ set((state) => {
1665
+ state.user = null;
1666
+ state.isAuthenticated = false;
1667
+ state.isLoading = false;
1668
+ state.error = errorMessage;
1669
+ });
1670
+ }
1671
+ }
1672
+ };
1673
+ })
1674
+ ),
1675
+ {
1676
+ name: "user-store",
1677
+ // Only serialize state for devtools, not the internal dependencies
1678
+ serialize: {
1679
+ options: {
1680
+ map: (state) => ({
1681
+ user: state.user,
1682
+ isLoading: state.isLoading,
1683
+ error: state.error,
1684
+ isAuthenticated: state.isAuthenticated
1685
+ })
1686
+ }
1687
+ }
1688
+ }
1689
+ )
1690
+ );
1691
+ var userSelectors = {
1692
+ // User data selectors (single values don't need shallow comparison)
1693
+ useUser: () => useUserStore((state) => state.user),
1694
+ useIsAuthenticated: () => useUserStore((state) => state.isAuthenticated),
1695
+ useIsLoading: () => useUserStore((state) => state.isLoading),
1696
+ useError: () => useUserStore((state) => state.error),
1697
+ // Combined selectors for common use cases (using useShallow to prevent unnecessary re-renders)
1698
+ useUserState: () => useUserStore(
1699
+ useShallow((state) => ({
1700
+ user: state.user,
1701
+ isAuthenticated: state.isAuthenticated,
1702
+ isLoading: state.isLoading,
1703
+ error: state.error
1704
+ }))
1705
+ ),
1706
+ // Actions selectors (using useShallow for stable object reference)
1707
+ useActions: () => useUserStore(
1708
+ useShallow((state) => ({
1709
+ setUser: state.setUser,
1710
+ setLoading: state.setLoading,
1711
+ setError: state.setError,
1712
+ clearUser: state.clearUser,
1713
+ refreshUser: state.refreshUser
1714
+ }))
1715
+ )
1716
+ };
1717
+
1718
+ // src/components/auth/auth-flow-container.tsx
1719
+ import { useState as useState4 } from "react";
1720
+ import { Steps, Row, Col, Button as Button5, Image, Typography as Typography2, Spin as Spin2, message, Space as Space2, Flex as Flex3 } from "antd";
1721
+ import { ArrowLeftOutlined as ArrowLeftOutlined3 } from "@ant-design/icons";
1722
+
1723
+ // src/hooks/useAuthActionHandler.ts
1724
+ import { useState, useCallback } from "react";
1725
+ var useAuthActionHandler = () => {
1726
+ const [state, setState] = useState({
1727
+ isLoading: false,
1728
+ error: null,
1729
+ success: null
1730
+ });
1731
+ const transformError = useCallback((error) => {
1732
+ if (error instanceof Error) {
1733
+ return error.message;
1734
+ }
1735
+ if (typeof error === "string") {
1736
+ return error;
1737
+ }
1738
+ return "An unexpected error occurred";
1739
+ }, []);
1740
+ const clearError = useCallback(() => {
1741
+ setState((prev) => __spreadProps(__spreadValues({}, prev), { error: null }));
1742
+ }, []);
1743
+ const clearSuccess = useCallback(() => {
1744
+ setState((prev) => __spreadProps(__spreadValues({}, prev), { success: null }));
1745
+ }, []);
1746
+ const clearAll = useCallback(() => {
1747
+ setState((prev) => __spreadProps(__spreadValues({}, prev), { error: null, success: null }));
1748
+ }, []);
1749
+ const setSuccess = useCallback((message2) => {
1750
+ setState((prev) => __spreadProps(__spreadValues({}, prev), { success: message2, error: null }));
1751
+ }, []);
1752
+ const setError = useCallback((error) => {
1753
+ setState((prev) => __spreadProps(__spreadValues({}, prev), { error, success: null }));
1754
+ }, []);
1755
+ const executeAction = useCallback(async (action, options = {}) => {
1756
+ const {
1757
+ clearStatesBeforeAction = true,
1758
+ preserveSuccessOnError = false,
1759
+ onSuccess,
1760
+ onError
1761
+ } = options;
1762
+ if (clearStatesBeforeAction) {
1763
+ setState((prev) => __spreadProps(__spreadValues({}, prev), {
1764
+ isLoading: true,
1765
+ error: null,
1766
+ success: preserveSuccessOnError ? prev.success : null
1767
+ }));
1768
+ } else {
1769
+ setState((prev) => __spreadProps(__spreadValues({}, prev), { isLoading: true }));
1770
+ }
1771
+ try {
1772
+ const result = await action();
1773
+ if (result.success) {
1774
+ const successMessage = result.message || "";
1775
+ setState((prev) => __spreadProps(__spreadValues({}, prev), {
1776
+ isLoading: false,
1777
+ error: null,
1778
+ success: successMessage
1779
+ }));
1780
+ onSuccess == null ? void 0 : onSuccess(result.data, successMessage, result);
1781
+ return result;
1782
+ } else {
1783
+ const errorMessage = result.message || "Action failed";
1784
+ setState((prev) => __spreadProps(__spreadValues({}, prev), {
1785
+ isLoading: false,
1786
+ error: errorMessage,
1787
+ success: preserveSuccessOnError ? prev.success : null
1788
+ }));
1789
+ onError == null ? void 0 : onError(errorMessage);
1790
+ return null;
1791
+ }
1792
+ } catch (error) {
1793
+ const errorMessage = transformError(error);
1794
+ setState((prev) => __spreadProps(__spreadValues({}, prev), {
1795
+ isLoading: false,
1796
+ error: errorMessage,
1797
+ success: preserveSuccessOnError ? prev.success : null
1798
+ }));
1799
+ onError == null ? void 0 : onError(errorMessage);
1800
+ return null;
1801
+ }
1802
+ }, [transformError]);
1803
+ return {
1804
+ state,
1805
+ executeAction,
1806
+ clearError,
1807
+ clearSuccess,
1808
+ clearAll,
1809
+ setSuccess,
1810
+ setError
1811
+ };
1812
+ };
1813
+
1814
+ // src/hooks/useStepper.ts
1815
+ import { useState as useState2, useCallback as useCallback2, useMemo } from "react";
1816
+ var useStepper = (config2) => {
1817
+ const { steps, initialStep } = config2;
1818
+ if (!steps || steps.length === 0) {
1819
+ throw new Error("useStepper: steps array cannot be empty");
1820
+ }
1821
+ const firstStepId = initialStep || steps[0].id;
1822
+ const [currentStep, setCurrentStep] = useState2(firstStepId);
1823
+ const currentStepIndex = useMemo(() => {
1824
+ return steps.findIndex((step) => step.id === currentStep);
1825
+ }, [steps, currentStep]);
1826
+ const isFirstStep = useMemo(() => currentStepIndex === 0, [currentStepIndex]);
1827
+ const isLastStep = useMemo(() => currentStepIndex === steps.length - 1, [currentStepIndex, steps.length]);
1828
+ const progress = useMemo(() => {
1829
+ return steps.length > 0 ? (currentStepIndex + 1) / steps.length : 0;
1830
+ }, [currentStepIndex, steps.length]);
1831
+ const getStepIndex = useCallback2((step) => {
1832
+ return steps.findIndex((s) => s.id === step);
1833
+ }, [steps]);
1834
+ const getStepByIndex = useCallback2((index) => {
1835
+ return steps[index];
1836
+ }, [steps]);
1837
+ const isStepValid = useCallback2((step) => {
1838
+ const stepIndex = getStepIndex(step);
1839
+ if (stepIndex === -1) return false;
1840
+ const stepConfig = steps[stepIndex];
1841
+ return !stepConfig.disabled;
1842
+ }, [steps, getStepIndex]);
1843
+ const getProgressPercentage = useCallback2(() => {
1844
+ return Math.round(progress * 100);
1845
+ }, [progress]);
1846
+ const goToStep = useCallback2((step) => {
1847
+ const stepIndex = getStepIndex(step);
1848
+ if (stepIndex === -1) {
1849
+ console.warn(`useStepper: Step not found: ${step}`);
1850
+ return;
1851
+ }
1852
+ setCurrentStep(step);
1853
+ }, [getStepIndex]);
1854
+ const goToNext = useCallback2(() => {
1855
+ if (isLastStep) {
1856
+ console.warn("useStepper: Already at the last step");
1857
+ return;
1858
+ }
1859
+ const nextIndex = currentStepIndex + 1;
1860
+ const nextStep = getStepByIndex(nextIndex);
1861
+ if (nextStep) {
1862
+ setCurrentStep(nextStep.id);
1863
+ }
1864
+ }, [isLastStep, currentStepIndex, getStepByIndex]);
1865
+ const goToPrevious = useCallback2(() => {
1866
+ if (isFirstStep) {
1867
+ console.warn("useStepper: Already at the first step");
1868
+ return;
1869
+ }
1870
+ const prevIndex = currentStepIndex - 1;
1871
+ const prevStep = getStepByIndex(prevIndex);
1872
+ if (prevStep) {
1873
+ setCurrentStep(prevStep.id);
1874
+ }
1875
+ }, [isFirstStep, currentStepIndex, getStepByIndex]);
1876
+ const goToIndex = useCallback2((index) => {
1877
+ const step = getStepByIndex(index);
1878
+ if (step) {
1879
+ goToStep(step.id);
1880
+ } else {
1881
+ console.warn(`useStepper: Invalid step index: ${index}`);
1882
+ }
1883
+ }, [getStepByIndex, goToStep]);
1884
+ const reset = useCallback2(() => {
1885
+ setCurrentStep(firstStepId);
1886
+ }, [firstStepId]);
1887
+ return {
1888
+ state: {
1889
+ currentStep,
1890
+ currentStepIndex,
1891
+ steps,
1892
+ isFirstStep,
1893
+ isLastStep,
1894
+ progress
1895
+ },
1896
+ actions: {
1897
+ goToStep,
1898
+ goToNext,
1899
+ goToPrevious,
1900
+ goToIndex,
1901
+ reset
1902
+ },
1903
+ helpers: {
1904
+ getStepIndex,
1905
+ getStepByIndex,
1906
+ isStepValid,
1907
+ getProgressPercentage
1908
+ }
1909
+ };
1910
+ };
1911
+
1912
+ // src/hooks/useStepRegistry.ts
1913
+ import { useMemo as useMemo2 } from "react";
1914
+
1915
+ // src/components/auth/step-renderer.tsx
1916
+ import React from "react";
1917
+
1918
+ // src/components/auth/email-step.tsx
1919
+ import { Button as Button2, Divider, Flex as Flex2 } from "antd";
1920
+ import { GoogleOutlined } from "@ant-design/icons";
1921
+
1922
+ // src/components/auth/base-form.tsx
1923
+ import { Form as Form2, Button, Spin, Space } from "antd";
1924
+
1925
+ // src/components/auth/alert-display.tsx
1926
+ import { Alert } from "antd";
1927
+ import { Fragment, jsx as jsx3, jsxs } from "react/jsx-runtime";
1928
+ var AlertDisplay = ({ error, success }) => {
1929
+ if (!error && !success) return null;
1930
+ return /* @__PURE__ */ jsxs(Fragment, { children: [
1931
+ error ? /* @__PURE__ */ jsx3(Alert, { message: error, type: "error", showIcon: true, className: "mb-6" }) : null,
1932
+ success ? /* @__PURE__ */ jsx3(Alert, { message: success, type: "success", showIcon: true, className: "mb-6" }) : null
1933
+ ] });
1934
+ };
1935
+
1936
+ // src/components/auth/form-header.tsx
1937
+ import { Flex, Typography } from "antd";
1938
+ import { jsx as jsx4, jsxs as jsxs2 } from "react/jsx-runtime";
1939
+ var { Title, Paragraph } = Typography;
1940
+ var FormHeader = ({ title, description }) => /* @__PURE__ */ jsxs2(Flex, { vertical: true, align: "center", className: "mb-6", children: [
1941
+ /* @__PURE__ */ jsx4(Title, { level: 2, className: "mb-2", children: title }),
1942
+ description && /* @__PURE__ */ jsx4(Paragraph, { className: "text-gray-600 text-center", children: description })
1943
+ ] });
1944
+
1945
+ // src/components/auth/form-fields.tsx
1946
+ import { Form } from "antd";
1947
+ import { jsx as jsx5 } from "react/jsx-runtime";
1948
+ var FormFields = ({ fields }) => fields.map((_a) => {
1949
+ var _b = _a, { component } = _b, formItemProps = __objRest(_b, ["component"]);
1950
+ return /* @__PURE__ */ jsx5(Form.Item, __spreadProps(__spreadValues({}, formItemProps), { children: component }), formItemProps.name);
1951
+ });
1952
+
1953
+ // src/components/auth/base-form.tsx
1954
+ import { jsx as jsx6, jsxs as jsxs3 } from "react/jsx-runtime";
1955
+ var BaseForm = ({
1956
+ title,
1957
+ description,
1958
+ fields,
1959
+ submitButtonText,
1960
+ onSubmit,
1961
+ isLoading = false,
1962
+ error,
1963
+ success,
1964
+ form,
1965
+ additionalActions,
1966
+ showAlerts = true,
1967
+ initialValues
1968
+ }) => {
1969
+ const [formInstance] = Form2.useForm();
1970
+ const activeForm = form || formInstance;
1971
+ const handleSubmit = async (values) => {
1972
+ try {
1973
+ await onSubmit(values);
1974
+ } catch (error2) {
1975
+ console.error("Form submission error:", error2);
1976
+ }
1977
+ };
1978
+ return /* @__PURE__ */ jsxs3(Space, { direction: "vertical", size: "large", className: "w-full max-w-md", children: [
1979
+ /* @__PURE__ */ jsx6(FormHeader, { title, description }),
1980
+ showAlerts && /* @__PURE__ */ jsx6(AlertDisplay, { error, success }),
1981
+ /* @__PURE__ */ jsx6(Spin, { spinning: isLoading, tip: "Processing...", children: /* @__PURE__ */ jsxs3(
1982
+ Form2,
1983
+ {
1984
+ form: activeForm,
1985
+ onFinish: handleSubmit,
1986
+ layout: "vertical",
1987
+ size: "large",
1988
+ initialValues,
1989
+ className: "w-full",
1990
+ children: [
1991
+ /* @__PURE__ */ jsx6(FormFields, { fields }),
1992
+ /* @__PURE__ */ jsx6(Form2.Item, { children: /* @__PURE__ */ jsx6(
1993
+ Button,
1994
+ {
1995
+ type: "primary",
1996
+ htmlType: "submit",
1997
+ loading: isLoading,
1998
+ block: true,
1999
+ size: "large",
2000
+ children: submitButtonText
2001
+ }
2002
+ ) }),
2003
+ additionalActions
2004
+ ]
2005
+ }
2006
+ ) })
2007
+ ] });
2008
+ };
2009
+
2010
+ // src/components/auth/email-step.tsx
2011
+ import { Fragment as Fragment2, jsx as jsx7, jsxs as jsxs4 } from "react/jsx-runtime";
2012
+ var EmailStep = ({
2013
+ title,
2014
+ description,
2015
+ onSubmit,
2016
+ onGoogleSignIn,
2017
+ onForgotPassword,
2018
+ isLoading = false,
2019
+ error,
2020
+ success,
2021
+ showGoogleButton = true,
2022
+ showForgotPassword = true,
2023
+ initialValues
2024
+ }) => {
2025
+ const handleSubmit = async (values) => {
2026
+ await onSubmit(values.email);
2027
+ };
2028
+ const fields = [getEmailField({ disabled: isLoading })];
2029
+ const additionalActions = /* @__PURE__ */ jsxs4(Fragment2, { children: [
2030
+ showGoogleButton && /* @__PURE__ */ jsxs4(Fragment2, { children: [
2031
+ /* @__PURE__ */ jsx7(Divider, { children: "OR" }),
2032
+ /* @__PURE__ */ jsx7(
2033
+ Button2,
2034
+ {
2035
+ icon: /* @__PURE__ */ jsx7(GoogleOutlined, {}),
2036
+ onClick: onGoogleSignIn,
2037
+ block: true,
2038
+ size: "large",
2039
+ className: "mb-4",
2040
+ disabled: isLoading,
2041
+ children: "Sign-in with Google"
2042
+ }
2043
+ )
2044
+ ] }),
2045
+ showForgotPassword && /* @__PURE__ */ jsx7(Flex2, { justify: "end", children: /* @__PURE__ */ jsx7(
2046
+ Button2,
2047
+ {
2048
+ type: "link",
2049
+ className: "px-0",
2050
+ onClick: onForgotPassword,
2051
+ disabled: isLoading,
2052
+ children: "Forgot Password ?"
2053
+ }
2054
+ ) })
2055
+ ] });
2056
+ return /* @__PURE__ */ jsx7(
2057
+ BaseForm,
2058
+ {
2059
+ title,
2060
+ description,
2061
+ fields,
2062
+ submitButtonText: "Next",
2063
+ onSubmit: handleSubmit,
2064
+ isLoading,
2065
+ error,
2066
+ success,
2067
+ additionalActions,
2068
+ initialValues
2069
+ }
2070
+ );
2071
+ };
2072
+
2073
+ // src/components/auth/password-step.tsx
2074
+ import { Button as Button3 } from "antd";
2075
+ import { ArrowLeftOutlined } from "@ant-design/icons";
2076
+ import { jsx as jsx8 } from "react/jsx-runtime";
2077
+ var PasswordStep = ({
2078
+ title,
2079
+ description,
2080
+ mode,
2081
+ email,
2082
+ onSubmit,
2083
+ onBack,
2084
+ isLoading = false,
2085
+ error,
2086
+ success,
2087
+ showEmailField = true,
2088
+ showBackButton = true,
2089
+ submitButtonText,
2090
+ initialValues
2091
+ }) => {
2092
+ const handleSubmit = async (values) => {
2093
+ await onSubmit(values.password);
2094
+ };
2095
+ const fields = [];
2096
+ if (showEmailField) {
2097
+ fields.push(getEmailField({ readOnly: true, value: email }));
2098
+ }
2099
+ fields.push(getPasswordField(mode === "login" /* LOGIN */, isLoading));
2100
+ const additionalActions = showBackButton ? /* @__PURE__ */ jsx8(
2101
+ Button3,
2102
+ {
2103
+ icon: /* @__PURE__ */ jsx8(ArrowLeftOutlined, {}),
2104
+ onClick: onBack,
2105
+ type: "link",
2106
+ block: true,
2107
+ disabled: isLoading,
2108
+ children: "Use different email"
2109
+ }
2110
+ ) : null;
2111
+ return /* @__PURE__ */ jsx8(
2112
+ BaseForm,
2113
+ {
2114
+ title,
2115
+ description,
2116
+ fields,
2117
+ submitButtonText,
2118
+ onSubmit: handleSubmit,
2119
+ isLoading,
2120
+ error,
2121
+ success,
2122
+ additionalActions,
2123
+ initialValues
2124
+ }
2125
+ );
2126
+ };
2127
+
2128
+ // src/components/auth/verification-step.tsx
2129
+ import { Button as Button4 } from "antd";
2130
+ import { ArrowLeftOutlined as ArrowLeftOutlined2 } from "@ant-design/icons";
2131
+ import { Fragment as Fragment3, jsx as jsx9, jsxs as jsxs5 } from "react/jsx-runtime";
2132
+ var VerificationStep = ({
2133
+ title,
2134
+ description,
2135
+ onSubmit,
2136
+ onBack,
2137
+ onResendCode,
2138
+ submitButtonText,
2139
+ isLoading = false,
2140
+ error,
2141
+ success,
2142
+ codeLength = 5,
2143
+ showBackButton = true,
2144
+ showResendButton = true,
2145
+ initialValues
2146
+ }) => {
2147
+ const handleSubmit = async (values) => {
2148
+ await onSubmit(values.verificationCode);
2149
+ };
2150
+ const fields = [
2151
+ getVerificationField(codeLength, { disabled: isLoading })
2152
+ ];
2153
+ const additionalActions = /* @__PURE__ */ jsxs5(Fragment3, { children: [
2154
+ showResendButton && /* @__PURE__ */ jsx9(
2155
+ Button4,
2156
+ {
2157
+ type: "link",
2158
+ onClick: onResendCode,
2159
+ disabled: isLoading,
2160
+ block: true,
2161
+ className: "mb-2",
2162
+ children: "Resend verification code"
2163
+ }
2164
+ ),
2165
+ showBackButton && /* @__PURE__ */ jsx9(
2166
+ Button4,
2167
+ {
2168
+ icon: /* @__PURE__ */ jsx9(ArrowLeftOutlined2, {}),
2169
+ onClick: onBack,
2170
+ type: "link",
2171
+ block: true,
2172
+ disabled: isLoading,
2173
+ children: "Back to password"
2174
+ }
2175
+ )
2176
+ ] });
2177
+ return /* @__PURE__ */ jsx9(
2178
+ BaseForm,
2179
+ {
2180
+ title,
2181
+ description,
2182
+ fields,
2183
+ submitButtonText,
2184
+ onSubmit: handleSubmit,
2185
+ isLoading,
2186
+ error,
2187
+ success,
2188
+ additionalActions,
2189
+ initialValues
2190
+ }
2191
+ );
2192
+ };
2193
+
2194
+ // src/components/auth/step-renderer.tsx
2195
+ var getEmailStepComponent = EmailStep;
2196
+ var getPasswordStepComponent = PasswordStep;
2197
+ var getVerificationStepComponent = VerificationStep;
2198
+ var createStepRegistry = () => ({
2199
+ ["email" /* EMAIL */]: getEmailStepComponent,
2200
+ ["password" /* PASSWORD */]: getPasswordStepComponent,
2201
+ ["verification" /* VERIFICATION */]: getVerificationStepComponent
2202
+ });
2203
+ var createPropsFactoryRegistry = ({
2204
+ baseProps,
2205
+ handlers,
2206
+ state,
2207
+ configs
2208
+ }) => ({
2209
+ ["email" /* EMAIL */]: () => __spreadProps(__spreadValues({}, baseProps), {
2210
+ title: "Sign In/Sign Up",
2211
+ description: "If you are an existing user, you will be signed in to your account. If you are a new user, an account will be created for you.",
2212
+ submitButtonText: "Continue",
2213
+ onSubmit: handlers.handleEmailSubmit,
2214
+ onGoogleSignIn: handlers.onGoogleSignIn,
2215
+ onForgotPassword: handlers.onForgotPassword,
2216
+ showGoogleButton: configs.emailStepConfig.showGoogleButton,
2217
+ showForgotPassword: configs.emailStepConfig.showForgotPassword
2218
+ }),
2219
+ ["password" /* PASSWORD */]: () => __spreadProps(__spreadValues({}, baseProps), {
2220
+ title: state.authIntent === "login" /* LOGIN */ ? "Welcome Back" : "Create Account",
2221
+ description: state.authIntent === "login" /* LOGIN */ ? "Please enter your password to sign in" : "Please create a password for your account",
2222
+ submitButtonText: state.authIntent === "login" /* LOGIN */ ? "Sign In" : "Create Account",
2223
+ mode: state.authIntent,
2224
+ email: state.email,
2225
+ onSubmit: handlers.handlePasswordSubmit,
2226
+ onBack: handlers.goBackToEmail,
2227
+ showEmailField: configs.passwordStepConfig.showEmailField
2228
+ }),
2229
+ ["verification" /* VERIFICATION */]: () => __spreadProps(__spreadValues({}, baseProps), {
2230
+ title: "Email Verification",
2231
+ description: `Please enter the verification code sent to ${state.email}`,
2232
+ submitButtonText: "Verify Email",
2233
+ email: state.email,
2234
+ onSubmit: handlers.handleVerificationSubmit,
2235
+ onBack: handlers.goBackToPassword,
2236
+ onResendCode: handlers.handleResendCode,
2237
+ codeLength: configs.verificationStepConfig.codeLength,
2238
+ showResendButton: configs.verificationStepConfig.showResendButton
2239
+ })
2240
+ });
2241
+ var useStepRenderer = () => {
2242
+ const registry = React.useMemo(() => createStepRegistry(), []);
2243
+ const getStepComponent = React.useCallback((step) => {
2244
+ return registry[step] || null;
2245
+ }, [registry]);
2246
+ return { getStepComponent };
2247
+ };
2248
+
2249
+ // src/hooks/useStepRegistry.ts
2250
+ function useStepRegistry({
2251
+ baseProps: actionState,
2252
+ handlers,
2253
+ state,
2254
+ configs,
2255
+ getStepComponent,
2256
+ stepperState
2257
+ }) {
2258
+ const baseProps = useMemo2(
2259
+ () => ({
2260
+ isLoading: actionState.isLoading,
2261
+ error: actionState.error,
2262
+ success: actionState.success
2263
+ }),
2264
+ [actionState]
2265
+ );
2266
+ const registryParams = useMemo2(
2267
+ () => ({ baseProps, handlers, state, configs }),
2268
+ [baseProps, handlers, state, configs]
2269
+ );
2270
+ const propsFactoryRegistry = useMemo2(
2271
+ () => createPropsFactoryRegistry(registryParams),
2272
+ [registryParams]
2273
+ );
2274
+ const currentStep = stepperState.currentStep;
2275
+ const SelectedComponent = getStepComponent(currentStep);
2276
+ const stepProps = useMemo2(() => {
2277
+ const factory = propsFactoryRegistry[currentStep];
2278
+ if (!factory) {
2279
+ console.warn(`No props factory found for step: ${currentStep}`);
2280
+ return baseProps;
2281
+ }
2282
+ return factory();
2283
+ }, [propsFactoryRegistry, currentStep, baseProps]);
2284
+ return { SelectedComponent, stepProps };
2285
+ }
2286
+
2287
+ // src/hooks/useAuthEventBus.ts
2288
+ import { useEffect } from "react";
2289
+
2290
+ // src/hooks/useSharedEventBus.ts
2291
+ import { useMemo as useMemo3 } from "react";
2292
+ function useSharedEventBus() {
2293
+ return useMemo3(() => BroadcastChannelEventBus.getInstance("auth-event-channel" /* AUTH */), []);
2294
+ }
2295
+
2296
+ // src/hooks/useAuthEventBus.ts
2297
+ var useAuthEventBus = ({ onLoggedOut, onLoggedIn } = {}) => {
2298
+ const eventBus = useSharedEventBus();
2299
+ useEffect(() => {
2300
+ const handleEvent = (e) => {
2301
+ var _a;
2302
+ const currentPageType = CrossTabBehaviorHandler.getCurrentPageType();
2303
+ const eventHandlers = {
2304
+ ["auth.logged_out" /* LoggedOut */]: onLoggedOut,
2305
+ ["auth.logged_in" /* LoggedIn */]: onLoggedIn,
2306
+ ["auth.email_verified" /* EmailVerified */]: void 0,
2307
+ ["auth.signin_required_modal" /* SignInRequiredModal */]: void 0
2308
+ };
2309
+ const handler = eventHandlers[e.type];
2310
+ const action = CrossTabBehaviorHandler.getAction(currentPageType, e.type);
2311
+ const actionHandlers = {
2312
+ ["redirect" /* REDIRECT */]: () => {
2313
+ const target = CrossTabBehaviorHandler.shouldRedirect(currentPageType, e.type);
2314
+ if (target) {
2315
+ window.location.replace(target);
2316
+ }
2317
+ },
2318
+ ["modal" /* MODAL */]: () => {
2319
+ if (e.type === "auth.logged_in" /* LoggedIn */) {
2320
+ window.location.replace(window.location.href);
2321
+ }
2322
+ },
2323
+ ["none" /* NONE */]: () => {
2324
+ }
2325
+ };
2326
+ (_a = actionHandlers[action.action]) == null ? void 0 : _a.call(actionHandlers);
2327
+ handler == null ? void 0 : handler();
2328
+ };
2329
+ const subscription = eventBus.subscribe(handleEvent);
2330
+ return () => {
2331
+ subscription.unsubscribe();
2332
+ };
2333
+ }, [eventBus, onLoggedOut, onLoggedIn]);
2334
+ };
2335
+
2336
+ // src/hooks/useSignInRequiredParams.ts
2337
+ import { useEffect as useEffect2 } from "react";
2338
+ import { useSearchParams } from "next/navigation";
2339
+ function useSignInRequiredParams() {
2340
+ const searchParams = useSearchParams();
2341
+ const eventBus = useSharedEventBus();
2342
+ useEffect2(() => {
2343
+ const signInRequired = searchParams.get(MiddlewareConfig.QUERY_PARAMS.LOGIN_REQUIRED);
2344
+ const authChecked = searchParams.get(MiddlewareConfig.QUERY_PARAMS.AUTH_CHECKED);
2345
+ if (signInRequired === MiddlewareConfig.QUERY_VALUES.LOGIN_REQUIRED && authChecked === MiddlewareConfig.QUERY_VALUES.AUTH_CHECKED) {
2346
+ const currentPageType = CrossTabBehaviorHandler.getCurrentPageType();
2347
+ eventBus.publish({
2348
+ type: "auth.signin_required_modal" /* SignInRequiredModal */,
2349
+ sourcePageType: currentPageType
2350
+ });
2351
+ }
2352
+ }, [eventBus, searchParams]);
2353
+ }
2354
+
2355
+ // src/hooks/use-user.ts
2356
+ import { useEffect as useEffect3 } from "react";
2357
+ var useUser = () => {
2358
+ const userState = userSelectors.useUserState();
2359
+ const actions = userSelectors.useActions();
2360
+ return __spreadValues(__spreadValues({}, userState), actions);
2361
+ };
2362
+ var useUserData = () => {
2363
+ return userSelectors.useUserState();
2364
+ };
2365
+ var useUserActions = () => {
2366
+ return userSelectors.useActions();
2367
+ };
2368
+ var useAuth = () => {
2369
+ const isAuthenticated = userSelectors.useIsAuthenticated();
2370
+ const isLoading = userSelectors.useIsLoading();
2371
+ const error = userSelectors.useError();
2372
+ const user = userSelectors.useUser();
2373
+ return {
2374
+ isAuthenticated,
2375
+ isLoading,
2376
+ error,
2377
+ user
2378
+ };
2379
+ };
2380
+ var useAuthInitializer = () => {
2381
+ const { refreshUser } = useUserActions();
2382
+ const { isLoading } = useUserData();
2383
+ useEffect3(() => {
2384
+ const initializeUser = async () => {
2385
+ if (!isLoading) {
2386
+ try {
2387
+ await refreshUser();
2388
+ } catch (error) {
2389
+ console.error("Failed to initialize user:", error);
2390
+ }
2391
+ }
2392
+ };
2393
+ initializeUser();
2394
+ }, []);
2395
+ useAuthEventBus({
2396
+ onLoggedOut: () => {
2397
+ refreshUser(true).catch(console.error);
2398
+ },
2399
+ onLoggedIn: () => {
2400
+ refreshUser(true).catch(console.error);
2401
+ }
2402
+ });
2403
+ return useUser();
2404
+ };
2405
+ var useIsAuthenticated = () => {
2406
+ return userSelectors.useIsAuthenticated();
2407
+ };
2408
+ var useUserLoading = () => {
2409
+ return userSelectors.useIsLoading();
2410
+ };
2411
+ var useUserError = () => {
2412
+ return userSelectors.useError();
2413
+ };
2414
+ var useUserProfile = () => {
2415
+ return userSelectors.useUser();
2416
+ };
2417
+ var useLogout = () => {
2418
+ const { clearUser } = useUserActions();
2419
+ const logout = async () => {
2420
+ try {
2421
+ await clearUser();
2422
+ } catch (error) {
2423
+ console.error("Logout error:", error);
2424
+ throw error;
2425
+ }
2426
+ };
2427
+ return logout;
2428
+ };
2429
+ var useRefreshUser = () => {
2430
+ const { refreshUser } = useUserActions();
2431
+ const refresh = async (force = false) => {
2432
+ try {
2433
+ await refreshUser(force);
2434
+ } catch (error) {
2435
+ console.error("Refresh user error:", error);
2436
+ throw error;
2437
+ }
2438
+ };
2439
+ return refresh;
2440
+ };
2441
+
2442
+ // src/hooks/useAuthFlowModal.ts
2443
+ import { useState as useState3, useEffect as useEffect4 } from "react";
2444
+ var useAuthFlowModal = () => {
2445
+ const [isModalOpen, setIsModalOpen] = useState3(false);
2446
+ const [isInitialLoading, setIsInitialLoading] = useState3(true);
2447
+ const eventBus = useSharedEventBus();
2448
+ const { isLoading: userLoading } = useUserData();
2449
+ useEffect4(() => {
2450
+ const handleAuthEvent = (event) => {
2451
+ if (event.type === "auth.signin_required_modal" /* SignInRequiredModal */) {
2452
+ setIsModalOpen(true);
2453
+ setIsInitialLoading(false);
2454
+ }
2455
+ };
2456
+ const subscription = eventBus.subscribe(handleAuthEvent);
2457
+ return () => {
2458
+ subscription.unsubscribe();
2459
+ };
2460
+ }, [eventBus]);
2461
+ useEffect4(() => {
2462
+ if (!userLoading) {
2463
+ const timer = setTimeout(() => {
2464
+ setIsInitialLoading(false);
2465
+ }, 0);
2466
+ return () => clearTimeout(timer);
2467
+ }
2468
+ }, [userLoading]);
2469
+ const openModal = () => {
2470
+ setIsModalOpen(true);
2471
+ setIsInitialLoading(false);
2472
+ };
2473
+ return {
2474
+ isModalOpen,
2475
+ isInitialLoading,
2476
+ openModal
2477
+ };
2478
+ };
2479
+
2480
+ // src/components/auth/auth-flow-container.tsx
2481
+ import { jsx as jsx10, jsxs as jsxs6 } from "react/jsx-runtime";
2482
+ var { Text } = Typography2;
2483
+ var AuthFlowContainer = () => {
2484
+ const authOrchestrator = AuthOrchestratorFactory.create();
2485
+ const { state: actionState, executeAction, clearAll } = useAuthActionHandler();
2486
+ const { getStepComponent } = useStepRenderer();
2487
+ const [email, setEmail] = useState4("");
2488
+ const [authIntent, setAuthIntent] = useState4("login" /* LOGIN */);
2489
+ const [authData, setAuthData] = useState4(null);
2490
+ const config2 = {
2491
+ showSteps: true,
2492
+ showProgressImage: true,
2493
+ showBackToHome: true,
2494
+ backgroundImage: "/api/placeholder/800/600",
2495
+ useAuthPageMessages: true,
2496
+ emailStepConfig: {
2497
+ showGoogleButton: false,
2498
+ showForgotPassword: false
2499
+ },
2500
+ passwordStepConfig: {
2501
+ showEmailField: true
2502
+ },
2503
+ verificationStepConfig: {
2504
+ codeLength: 5,
2505
+ showResendButton: false
2506
+ }
2507
+ };
2508
+ const stepperConfig = {
2509
+ steps: createAuthSteps({ authIntent }),
2510
+ initialStep: "email" /* EMAIL */
2511
+ };
2512
+ const { state: stepperState, actions: stepperActions } = useStepper(stepperConfig);
2513
+ const handleEmailSubmit = async (emailValue) => {
2514
+ await executeAction(
2515
+ async () => {
2516
+ return await authOrchestrator.handleEmailCheck(emailValue);
2517
+ },
2518
+ {
2519
+ onSuccess: (data) => {
2520
+ setEmail(emailValue);
2521
+ setAuthIntent(data.next_action);
2522
+ const nextStep = getStepForEmailSubmission(data.next_action);
2523
+ stepperActions.goToStep(nextStep);
2524
+ },
2525
+ onError: (error) => {
2526
+ message.error(error);
2527
+ }
2528
+ }
2529
+ );
2530
+ };
2531
+ const handlePasswordSubmit = async (password) => {
2532
+ await executeAction(
2533
+ async () => {
2534
+ const loginRequest = { email, password };
2535
+ return await authOrchestrator.handleLoginFlow(loginRequest);
2536
+ },
2537
+ {
2538
+ onSuccess: (data) => {
2539
+ setAuthData(data);
2540
+ if (!data.isVerifiedEmail) {
2541
+ const nextStep = getStepForPasswordSubmission(data.isVerifiedEmail);
2542
+ stepperActions.goToStep(nextStep);
2543
+ }
2544
+ },
2545
+ onError: (error) => {
2546
+ message.error(error);
2547
+ }
2548
+ }
2549
+ );
2550
+ };
2551
+ const handleVerificationSubmit = async (code) => {
2552
+ await executeAction(
2553
+ async () => {
2554
+ return await authOrchestrator.handleEmailVerification(email, code);
2555
+ },
2556
+ {
2557
+ onSuccess: (data) => {
2558
+ setAuthData(data);
2559
+ handleSuccess();
2560
+ },
2561
+ onError: (error) => {
2562
+ message.error(error);
2563
+ }
2564
+ }
2565
+ );
2566
+ };
2567
+ const handleSuccess = () => {
2568
+ message.success("Authentication successful!");
2569
+ };
2570
+ const goBackToEmail = () => {
2571
+ stepperActions.goToStep("email" /* EMAIL */);
2572
+ setEmail("");
2573
+ clearAll();
2574
+ };
2575
+ const goBackToPassword = () => {
2576
+ stepperActions.goToStep("password" /* PASSWORD */);
2577
+ clearAll();
2578
+ };
2579
+ const goBackToHome = () => {
2580
+ window.location.href = "/";
2581
+ };
2582
+ const getCurrentStepMessage = () => {
2583
+ return config2.useAuthPageMessages ? getAuthPageStepMessage(stepperState.currentStep) : getStepProgressMessage(stepperState.currentStep);
2584
+ };
2585
+ const { SelectedComponent, stepProps } = useStepRegistry({
2586
+ baseProps: __spreadProps(__spreadValues({}, actionState), {
2587
+ error: actionState.error || void 0,
2588
+ success: actionState.success || void 0
2589
+ }),
2590
+ handlers: {
2591
+ handleEmailSubmit,
2592
+ handlePasswordSubmit,
2593
+ handleVerificationSubmit,
2594
+ handleResendCode: () => {
2595
+ },
2596
+ goBackToEmail,
2597
+ goBackToPassword,
2598
+ onGoogleSignIn: () => {
2599
+ },
2600
+ onForgotPassword: () => {
2601
+ }
2602
+ },
2603
+ state: { email, authIntent, authData },
2604
+ configs: {
2605
+ emailStepConfig: config2.emailStepConfig,
2606
+ passwordStepConfig: config2.passwordStepConfig,
2607
+ verificationStepConfig: config2.verificationStepConfig
2608
+ },
2609
+ getStepComponent,
2610
+ stepperState
2611
+ });
2612
+ return /* @__PURE__ */ jsx10("div", { className: "min-h-screen bg-gray-50", children: /* @__PURE__ */ jsxs6(Row, { className: "min-h-screen", children: [
2613
+ /* @__PURE__ */ jsx10(
2614
+ Col,
2615
+ {
2616
+ xs: 24,
2617
+ lg: config2.showProgressImage ? 12 : 24,
2618
+ className: "flex items-center justify-center p-8",
2619
+ children: /* @__PURE__ */ jsxs6(Space2, { direction: "vertical", size: "large", className: "w-full max-w-md", children: [
2620
+ config2.showBackToHome && /* @__PURE__ */ jsx10(
2621
+ Button5,
2622
+ {
2623
+ type: "link",
2624
+ icon: /* @__PURE__ */ jsx10(ArrowLeftOutlined3, {}),
2625
+ className: "px-0",
2626
+ onClick: goBackToHome,
2627
+ children: "Back to Home"
2628
+ }
2629
+ ),
2630
+ config2.showSteps && /* @__PURE__ */ jsx10(
2631
+ Steps,
2632
+ {
2633
+ current: stepperState.currentStepIndex,
2634
+ size: "small",
2635
+ responsive: false,
2636
+ items: stepperState.steps.map((step) => ({
2637
+ title: step.title,
2638
+ description: step.description,
2639
+ icon: step.icon,
2640
+ disabled: step.disabled || false
2641
+ }))
2642
+ }
2643
+ ),
2644
+ /* @__PURE__ */ jsx10(
2645
+ Spin2,
2646
+ {
2647
+ spinning: actionState.isLoading,
2648
+ tip: getCurrentStepMessage(),
2649
+ children: /* @__PURE__ */ jsx10(SelectedComponent, __spreadValues({}, stepProps))
2650
+ }
2651
+ )
2652
+ ] })
2653
+ }
2654
+ ),
2655
+ config2.showProgressImage && /* @__PURE__ */ jsxs6(
2656
+ Col,
2657
+ {
2658
+ xs: 0,
2659
+ lg: 12,
2660
+ className: "relative bg-gradient-to-br from-blue-500 to-purple-600 flex items-center justify-center",
2661
+ children: [
2662
+ /* @__PURE__ */ jsx10("div", { className: "absolute inset-0 bg-black bg-opacity-20" }),
2663
+ /* @__PURE__ */ jsx10(
2664
+ Image,
2665
+ {
2666
+ src: config2.backgroundImage,
2667
+ alt: "Authentication",
2668
+ className: "absolute inset-0 object-cover",
2669
+ preview: false,
2670
+ fallback: "data:image/svg+xml;base64,PHN2ZyB3aWR0aD0iODAwIiBoZWlnaHQ9IjYwMCIgdmlld0JveD0iMCAwIDgwMCA2MDAiIGZpbGw9Im5vbmUiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyI+CjxyZWN0IHdpZHRoPSI4MDAiIGhlaWdodD0iNjAwIiBmaWxsPSIjRjNGNEY2Ii8+CjxwYXRoIGQ9Ik0wIDMwMEg4MDBWNDAwSDBWMzAwWiIgZmlsbD0iI0U1RTdFQiIvPgo8Y2lyY2xlIGN4PSI0MDAiIGN5PSIzMDAiIHI9IjEwMCIgZmlsbD0iI0QxRDVGRiIvPgo8L3N2Zz4K"
2671
+ }
2672
+ ),
2673
+ /* @__PURE__ */ jsx10(Flex3, { vertical: true, align: "center", className: "relative z-10 text-white", children: /* @__PURE__ */ jsxs6("div", { className: "w-32 h-32 mb-4 relative", children: [
2674
+ /* @__PURE__ */ jsxs6("svg", { className: "w-full h-full transform -rotate-90", viewBox: "0 0 120 120", children: [
2675
+ /* @__PURE__ */ jsx10(
2676
+ "circle",
2677
+ {
2678
+ cx: "60",
2679
+ cy: "60",
2680
+ r: "54",
2681
+ fill: "none",
2682
+ stroke: "rgba(255,255,255,0.3)",
2683
+ strokeWidth: "8"
2684
+ }
2685
+ ),
2686
+ /* @__PURE__ */ jsx10(
2687
+ "circle",
2688
+ {
2689
+ cx: "60",
2690
+ cy: "60",
2691
+ r: "54",
2692
+ fill: "none",
2693
+ stroke: "white",
2694
+ strokeWidth: "8",
2695
+ strokeDasharray: `${2 * Math.PI * 54}`,
2696
+ strokeDashoffset: `${2 * Math.PI * 54 * (1 - stepperState.progress)}`,
2697
+ strokeLinecap: "round",
2698
+ className: "transition-all duration-500"
2699
+ }
2700
+ )
2701
+ ] }),
2702
+ /* @__PURE__ */ jsx10(Flex3, { align: "center", justify: "center", className: "absolute inset-0", children: /* @__PURE__ */ jsxs6(Text, { className: "text-2xl font-bold text-white", children: [
2703
+ Math.round(stepperState.progress * 100),
2704
+ "%"
2705
+ ] }) })
2706
+ ] }) })
2707
+ ]
2708
+ }
2709
+ )
2710
+ ] }) });
2711
+ };
2712
+
2713
+ // src/components/auth/auth-flow-modal.tsx
2714
+ import { Modal, Spin as Spin3 } from "antd";
2715
+ import { Fragment as Fragment4, jsx as jsx11, jsxs as jsxs7 } from "react/jsx-runtime";
2716
+ var AuthFlowModal = ({ children }) => {
2717
+ const { isModalOpen, isInitialLoading } = useAuthFlowModal();
2718
+ if (isInitialLoading) {
2719
+ return /* @__PURE__ */ jsx11("div", { className: "min-h-screen flex items-center justify-center bg-gray-50", children: /* @__PURE__ */ jsx11(Spin3, { size: "large" }) });
2720
+ }
2721
+ return /* @__PURE__ */ jsxs7(Fragment4, { children: [
2722
+ isModalOpen ? /* @__PURE__ */ jsx11("div", { className: "min-h-screen flex items-center justify-center bg-gray-50", children: /* @__PURE__ */ jsx11(Spin3, { size: "large" }) }) : children,
2723
+ /* @__PURE__ */ jsx11(
2724
+ Modal,
2725
+ {
2726
+ title: "Sign In Required",
2727
+ open: isModalOpen,
2728
+ footer: null,
2729
+ width: 800,
2730
+ centered: true,
2731
+ destroyOnHidden: true,
2732
+ maskClosable: false,
2733
+ className: "auth-flow-modal",
2734
+ children: /* @__PURE__ */ jsx11(AuthFlowContainer, {})
2735
+ }
2736
+ )
2737
+ ] });
2738
+ };
2739
+
2740
+ // src/components/auth/auth-initializer.tsx
2741
+ import { Fragment as Fragment5, jsx as jsx12 } from "react/jsx-runtime";
2742
+ var AuthInitializer = ({ children }) => {
2743
+ useAuthInitializer();
2744
+ return /* @__PURE__ */ jsx12(Fragment5, { children });
2745
+ };
2746
+
2747
+ // src/components/profile/profile-state-renderer.tsx
2748
+ import { Dropdown, Button as Button6 } from "antd";
2749
+ import { MailOutlined as MailOutlined3, CrownOutlined, LogoutOutlined, UserOutlined } from "@ant-design/icons";
2750
+ import Link from "next/link";
2751
+ import { jsx as jsx13, jsxs as jsxs8 } from "react/jsx-runtime";
2752
+ var LoadingState = () => /* @__PURE__ */ jsx13("div", { className: "min-h-screen flex items-center justify-center", children: /* @__PURE__ */ jsx13("div", { className: "text-center", children: /* @__PURE__ */ jsx13("div", { className: "animate-spin rounded-full h-8 w-8 border-b-2 border-blue-600 mx-auto mb-4" }) }) });
2753
+ var UnauthenticatedState2 = () => /* @__PURE__ */ jsx13(Link, { href: "/login", children: /* @__PURE__ */ jsx13(Button6, { type: "primary", shape: "circle", size: "large", icon: /* @__PURE__ */ jsx13(UserOutlined, {}) }) });
2754
+ var AuthenticatedState2 = ({ user, onLogout }) => {
2755
+ var _a, _b, _c;
2756
+ const userInfoMenu = {
2757
+ items: [
2758
+ {
2759
+ key: "email",
2760
+ icon: /* @__PURE__ */ jsx13(MailOutlined3, {}),
2761
+ label: /* @__PURE__ */ jsxs8("div", { children: [
2762
+ /* @__PURE__ */ jsx13("div", { className: "text-xs text-gray-500", children: "Email" }),
2763
+ /* @__PURE__ */ jsx13("div", { className: "font-medium", children: ((_a = user.user) == null ? void 0 : _a.email) || "N/A" })
2764
+ ] })
2765
+ },
2766
+ {
2767
+ key: "role",
2768
+ icon: /* @__PURE__ */ jsx13(CrownOutlined, {}),
2769
+ label: /* @__PURE__ */ jsxs8("div", { children: [
2770
+ /* @__PURE__ */ jsx13("div", { className: "text-xs text-gray-500", children: "Role" }),
2771
+ /* @__PURE__ */ jsx13("div", { className: "font-medium", children: ((_c = (_b = user.user) == null ? void 0 : _b.role) == null ? void 0 : _c.name) || "N/A" })
2772
+ ] })
2773
+ },
2774
+ {
2775
+ type: "divider"
2776
+ },
2777
+ {
2778
+ key: "logout",
2779
+ icon: /* @__PURE__ */ jsx13(LogoutOutlined, {}),
2780
+ label: "Logout",
2781
+ onClick: onLogout
2782
+ }
2783
+ ]
2784
+ };
2785
+ return /* @__PURE__ */ jsx13(Dropdown, { menu: userInfoMenu, placement: "bottom", trigger: ["click"], children: /* @__PURE__ */ jsx13(Button6, { type: "primary", shape: "circle", size: "large", icon: /* @__PURE__ */ jsx13(UserOutlined, {}) }) });
2786
+ };
2787
+ var resolveState = (isLoading, isAuthenticated, user) => {
2788
+ if (isLoading) return "LOADING" /* LOADING */;
2789
+ if (!isAuthenticated || !user) return "UNAUTHENTICATED" /* UNAUTHENTICATED */;
2790
+ return "AUTHENTICATED" /* AUTHENTICATED */;
2791
+ };
2792
+ var getComponentProps = (state, user, callbacks) => {
2793
+ switch (state) {
2794
+ case "AUTHENTICATED" /* AUTHENTICATED */:
2795
+ return {
2796
+ user,
2797
+ onLogout: callbacks.onLogout
2798
+ };
2799
+ default:
2800
+ return {};
2801
+ }
2802
+ };
2803
+ var ProfileStateRenderer = () => {
2804
+ const { user, isLoading, isAuthenticated } = useAuth();
2805
+ const logout = useLogout();
2806
+ const currentState = resolveState(isLoading, isAuthenticated, user);
2807
+ const componentProps = getComponentProps(currentState, user, {
2808
+ onLogout: logout
2809
+ });
2810
+ switch (currentState) {
2811
+ case "LOADING" /* LOADING */:
2812
+ return /* @__PURE__ */ jsx13(LoadingState, {});
2813
+ case "UNAUTHENTICATED" /* UNAUTHENTICATED */:
2814
+ return /* @__PURE__ */ jsx13(UnauthenticatedState2, {});
2815
+ case "AUTHENTICATED" /* AUTHENTICATED */:
2816
+ return /* @__PURE__ */ jsx13(AuthenticatedState2, __spreadValues({}, componentProps));
2817
+ default:
2818
+ return /* @__PURE__ */ jsx13(LoadingState, {});
2819
+ }
2820
+ };
2821
+
2822
+ // src/components/demo/cross-tab-demo.tsx
2823
+ import { Card, Typography as Typography3, Tag, Space as Space3 } from "antd";
2824
+ import { Fragment as Fragment6, jsx as jsx14, jsxs as jsxs9 } from "react/jsx-runtime";
2825
+ var { Title: Title2, Text: Text2, Paragraph: Paragraph2 } = Typography3;
2826
+ var CrossTabDemo = () => {
2827
+ var _a;
2828
+ const { isAuthenticated, user } = useAuth();
2829
+ const currentPageType = CrossTabBehaviorHandler.getCurrentPageType();
2830
+ return /* @__PURE__ */ jsx14(
2831
+ Card,
2832
+ {
2833
+ title: "Cross-Tab Authentication Demo",
2834
+ className: "w-full max-w-2xl",
2835
+ style: { marginTop: "2rem" },
2836
+ children: /* @__PURE__ */ jsxs9(Space3, { direction: "vertical", size: "middle", className: "w-full", children: [
2837
+ /* @__PURE__ */ jsxs9("div", { children: [
2838
+ /* @__PURE__ */ jsx14(Title2, { level: 4, children: "Current Status" }),
2839
+ /* @__PURE__ */ jsxs9(Space3, { children: [
2840
+ /* @__PURE__ */ jsx14(Text2, { strong: true, children: "Authentication:" }),
2841
+ /* @__PURE__ */ jsx14(Tag, { color: isAuthenticated ? "green" : "red", children: isAuthenticated ? "Authenticated" : "Not Authenticated" })
2842
+ ] }),
2843
+ /* @__PURE__ */ jsx14("br", {}),
2844
+ /* @__PURE__ */ jsxs9(Space3, { style: { marginTop: "0.5rem" }, children: [
2845
+ /* @__PURE__ */ jsx14(Text2, { strong: true, children: "Current Page:" }),
2846
+ /* @__PURE__ */ jsx14(Tag, { color: "blue", children: currentPageType })
2847
+ ] }),
2848
+ user && /* @__PURE__ */ jsxs9(Fragment6, { children: [
2849
+ /* @__PURE__ */ jsx14("br", {}),
2850
+ /* @__PURE__ */ jsxs9(Space3, { style: { marginTop: "0.5rem" }, children: [
2851
+ /* @__PURE__ */ jsx14(Text2, { strong: true, children: "User:" }),
2852
+ /* @__PURE__ */ jsx14(Text2, { children: (_a = user.user) == null ? void 0 : _a.email })
2853
+ ] })
2854
+ ] })
2855
+ ] }),
2856
+ /* @__PURE__ */ jsxs9("div", { children: [
2857
+ /* @__PURE__ */ jsx14(Title2, { level: 4, children: "How It Works" }),
2858
+ /* @__PURE__ */ jsx14(Paragraph2, { children: "This application now supports enhanced cross-tab authentication handling:" }),
2859
+ /* @__PURE__ */ jsxs9("div", { style: { marginLeft: "1rem" }, children: [
2860
+ /* @__PURE__ */ jsxs9(Paragraph2, { children: [
2861
+ /* @__PURE__ */ jsx14(Text2, { strong: true, children: "Login Scenario:" }),
2862
+ /* @__PURE__ */ jsx14("br", {}),
2863
+ "\u2022 Open multiple tabs with some on the login page and others on different pages",
2864
+ /* @__PURE__ */ jsx14("br", {}),
2865
+ "\u2022 When you log in from one tab, other login tabs will automatically redirect to the dashboard",
2866
+ /* @__PURE__ */ jsx14("br", {}),
2867
+ "\u2022 Non-login pages will receive the login event but won't redirect (they'll just update their state)"
2868
+ ] }),
2869
+ /* @__PURE__ */ jsxs9(Paragraph2, { children: [
2870
+ /* @__PURE__ */ jsx14(Text2, { strong: true, children: "Logout Scenario:" }),
2871
+ /* @__PURE__ */ jsx14("br", {}),
2872
+ "\u2022 When you log out from the dashboard, other dashboard tabs will redirect to the login page",
2873
+ /* @__PURE__ */ jsx14("br", {}),
2874
+ "\u2022 Other pages will receive the logout event and update their authentication state"
2875
+ ] })
2876
+ ] })
2877
+ ] }),
2878
+ /* @__PURE__ */ jsxs9("div", { children: [
2879
+ /* @__PURE__ */ jsx14(Title2, { level: 4, children: "Test Instructions" }),
2880
+ /* @__PURE__ */ jsxs9(Paragraph2, { children: [
2881
+ "1. Open this page in multiple browser tabs",
2882
+ /* @__PURE__ */ jsx14("br", {}),
2883
+ "2. Navigate to ",
2884
+ /* @__PURE__ */ jsx14(Text2, { code: true, children: "/login" }),
2885
+ " in some tabs and ",
2886
+ /* @__PURE__ */ jsx14(Text2, { code: true, children: "/dashboard" }),
2887
+ " in others",
2888
+ /* @__PURE__ */ jsx14("br", {}),
2889
+ "3. Log in from one tab and observe the automatic redirects in other tabs",
2890
+ /* @__PURE__ */ jsx14("br", {}),
2891
+ "4. Log out from the dashboard and see how other tabs react"
2892
+ ] })
2893
+ ] })
2894
+ ] })
2895
+ }
2896
+ );
2897
+ };
2898
+ export {
2899
+ AUTH_ENDPOINTS,
2900
+ AlertDisplay,
2901
+ AuthEventType,
2902
+ AuthFlowContainer,
2903
+ AuthFlowModal,
2904
+ AuthFlowStep,
2905
+ AuthInitializer,
2906
+ AuthOrchestrator,
2907
+ AuthOrchestratorFactory,
2908
+ AuthResultFactory,
2909
+ AuthService,
2910
+ AuthenticatedState,
2911
+ AuthenticationStatusContext,
2912
+ BaseErrorHandler,
2913
+ BaseEventBus,
2914
+ BaseForm,
2915
+ BaseService,
2916
+ BroadcastChannelEventBus,
2917
+ Channel,
2918
+ CookieUtils,
2919
+ CrossTabBehaviorConfig,
2920
+ CrossTabBehaviorHandler,
2921
+ CrossTabDemo,
2922
+ DevelopmentLogger,
2923
+ EMAIL_SUBMISSION_NAVIGATION,
2924
+ EmailStep,
2925
+ EndpointBuilder,
2926
+ ExistingUserLoginStrategy,
2927
+ FormFields,
2928
+ FormHeader,
2929
+ GenericErrorHandler,
2930
+ HttpClient,
2931
+ HttpMethod,
2932
+ LocalStorageUtils,
2933
+ LoggerFactory,
2934
+ LoginFlowStrategyFactory,
2935
+ MiddlewareConfig,
2936
+ NavigationAction,
2937
+ NetworkErrorHandler,
2938
+ NextAction,
2939
+ PASSWORD_SUBMISSION_NAVIGATION,
2940
+ PageType,
2941
+ PageTypePatterns,
2942
+ PasswordStep,
2943
+ ProductionLogger,
2944
+ ProfileStateRenderer,
2945
+ ProfileUIState,
2946
+ RoleType,
2947
+ SignupFlowStrategy,
2948
+ TokenManager,
2949
+ UnauthenticatedState,
2950
+ UserStorageManager,
2951
+ VERIFICATION_SUBMISSION_NAVIGATION,
2952
+ ValidationErrorHandler,
2953
+ VerificationStep,
2954
+ config,
2955
+ createAuthSteps,
2956
+ createPropsFactoryRegistry,
2957
+ createStepRegistry,
2958
+ getAuthPageStepMessage,
2959
+ getEmailField,
2960
+ getEmailStepComponent,
2961
+ getPasswordField,
2962
+ getPasswordStepComponent,
2963
+ getStepForEmailSubmission,
2964
+ getStepForPasswordSubmission,
2965
+ getStepForVerificationSubmission,
2966
+ getStepProgressMessage,
2967
+ getVerificationField,
2968
+ getVerificationStepComponent,
2969
+ middlewareMatcher,
2970
+ useAuth,
2971
+ useAuthActionHandler,
2972
+ useAuthEventBus,
2973
+ useAuthFlowModal,
2974
+ useAuthInitializer,
2975
+ useIsAuthenticated,
2976
+ useLogout,
2977
+ useRefreshUser,
2978
+ useSharedEventBus,
2979
+ useSignInRequiredParams,
2980
+ useStepRegistry,
2981
+ useStepRenderer,
2982
+ useStepper,
2983
+ useUser,
2984
+ useUserActions,
2985
+ useUserData,
2986
+ useUserError,
2987
+ useUserLoading,
2988
+ useUserProfile,
2989
+ useUserStore,
2990
+ userSelectors
2991
+ };
2992
+ /*! Bundled license information:
2993
+
2994
+ js-cookie/dist/js.cookie.mjs:
2995
+ (*! js-cookie v3.0.5 | MIT *)
2996
+ */