mulguard 1.0.1

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.
Files changed (66) hide show
  1. package/README.md +368 -0
  2. package/dist/actions-CExpv_dD.js +1 -0
  3. package/dist/actions-DeCfLtHA.mjs +184 -0
  4. package/dist/client/hooks.d.ts +122 -0
  5. package/dist/client/index.d.ts +5 -0
  6. package/dist/client/index.js +1 -0
  7. package/dist/client/index.mjs +476 -0
  8. package/dist/client/provider.d.ts +25 -0
  9. package/dist/client/server-actions-helper.d.ts +22 -0
  10. package/dist/components/AccountPicker.d.ts +11 -0
  11. package/dist/components/OAuthButton.d.ts +11 -0
  12. package/dist/components/PassKeyButton.d.ts +11 -0
  13. package/dist/components/PassKeyRegister.d.ts +10 -0
  14. package/dist/components/TwoFactorSetup.d.ts +8 -0
  15. package/dist/components/TwoFactorVerify.d.ts +9 -0
  16. package/dist/core/account-picker/encryption.d.ts +22 -0
  17. package/dist/core/account-picker/index.d.ts +22 -0
  18. package/dist/core/auth/index.d.ts +40 -0
  19. package/dist/core/auth/oauth-providers.d.ts +69 -0
  20. package/dist/core/auth/oauth-state-store.d.ts +44 -0
  21. package/dist/core/auth/oauth.d.ts +20 -0
  22. package/dist/core/auth/passkey.d.ts +35 -0
  23. package/dist/core/auth/password.d.ts +22 -0
  24. package/dist/core/auth/signin-unified.d.ts +33 -0
  25. package/dist/core/auth/two-factor.d.ts +28 -0
  26. package/dist/core/client/index.d.ts +132 -0
  27. package/dist/core/client/token-refresh-manager.d.ts +48 -0
  28. package/dist/core/index.d.ts +10 -0
  29. package/dist/core/security/csrf.d.ts +46 -0
  30. package/dist/core/security/headers.d.ts +24 -0
  31. package/dist/core/security/index.d.ts +28 -0
  32. package/dist/core/security/rate-limit.d.ts +39 -0
  33. package/dist/core/security/validation.d.ts +53 -0
  34. package/dist/core/security/xss.d.ts +20 -0
  35. package/dist/core/session/index.d.ts +35 -0
  36. package/dist/core/types/auth.d.ts +131 -0
  37. package/dist/core/types/errors.d.ts +44 -0
  38. package/dist/core/types/index.d.ts +369 -0
  39. package/dist/core/utils/auth-helpers.d.ts +136 -0
  40. package/dist/core/utils/logger.d.ts +17 -0
  41. package/dist/handlers/api.d.ts +10 -0
  42. package/dist/handlers/route.d.ts +22 -0
  43. package/dist/index/index.js +1 -0
  44. package/dist/index/index.mjs +1633 -0
  45. package/dist/index.d.ts +21 -0
  46. package/dist/middleware/index.d.ts +28 -0
  47. package/dist/middleware/proxy.d.ts +53 -0
  48. package/dist/middleware/security.d.ts +9 -0
  49. package/dist/mulguard.d.ts +263 -0
  50. package/dist/oauth-state-CzIWQq3s.js +1 -0
  51. package/dist/oauth-state-LE-qeq-K.mjs +282 -0
  52. package/dist/server/actions.d.ts +86 -0
  53. package/dist/server/auth.d.ts +65 -0
  54. package/dist/server/cookies.d.ts +42 -0
  55. package/dist/server/helpers.d.ts +10 -0
  56. package/dist/server/index.d.ts +14 -0
  57. package/dist/server/index.js +1 -0
  58. package/dist/server/index.mjs +31 -0
  59. package/dist/server/middleware.d.ts +39 -0
  60. package/dist/server/oauth-state.d.ts +24 -0
  61. package/dist/server/session-helpers.d.ts +26 -0
  62. package/dist/server/session.d.ts +28 -0
  63. package/dist/server/utils.d.ts +10 -0
  64. package/dist/signin-unified-BS2gxaG1.mjs +30 -0
  65. package/dist/signin-unified-Cw41EFkc.js +1 -0
  66. package/package.json +73 -0
@@ -0,0 +1,1633 @@
1
+ var B = Object.defineProperty;
2
+ var H = (r, e, n) => e in r ? B(r, e, { enumerable: !0, configurable: !0, writable: !0, value: n }) : r[e] = n;
3
+ var C = (r, e, n) => H(r, typeof e != "symbol" ? e + "" : e, n);
4
+ import { A as E, e as q, c as K, g as X, d as Y } from "../actions-DeCfLtHA.mjs";
5
+ import { a as Je, s as Qe, b as Ze, v as er } from "../actions-DeCfLtHA.mjs";
6
+ import { s as tr } from "../signin-unified-BS2gxaG1.mjs";
7
+ import { v as F } from "../oauth-state-LE-qeq-K.mjs";
8
+ import { c as nr, p as or, k as ir, n as ar, m as cr, j as lr, l as ur, e as fr, g as dr, b as hr, i as gr, a as wr, o as pr, f as mr, h as yr, r as Er, d as kr, s as vr } from "../oauth-state-LE-qeq-K.mjs";
9
+ import { NextResponse as u } from "next/server";
10
+ const x = typeof globalThis == "object" && "crypto" in globalThis ? globalThis.crypto : void 0;
11
+ /*! noble-hashes - MIT License (c) 2022 Paul Miller (paulmillr.com) */
12
+ function G(r = 32) {
13
+ if (x && typeof x.getRandomValues == "function")
14
+ return x.getRandomValues(new Uint8Array(r));
15
+ if (x && typeof x.randomBytes == "function")
16
+ return Uint8Array.from(x.randomBytes(r));
17
+ throw new Error("crypto.getRandomValues must be defined");
18
+ }
19
+ class J {
20
+ constructor(e) {
21
+ C(this, "attempts", /* @__PURE__ */ new Map());
22
+ C(this, "config");
23
+ this.config = e;
24
+ }
25
+ /**
26
+ * Check if request is allowed
27
+ */
28
+ check(e) {
29
+ const n = Date.now(), t = this.attempts.get(e);
30
+ return !t || t.resetAt < n ? (this.attempts.set(e, {
31
+ count: 1,
32
+ resetAt: n + this.config.windowMs
33
+ }), {
34
+ allowed: !0,
35
+ remaining: this.config.maxAttempts - 1,
36
+ resetAt: new Date(n + this.config.windowMs)
37
+ }) : t.count >= this.config.maxAttempts ? {
38
+ allowed: !1,
39
+ remaining: 0,
40
+ resetAt: new Date(t.resetAt)
41
+ } : (t.count++, {
42
+ allowed: !0,
43
+ remaining: this.config.maxAttempts - t.count,
44
+ resetAt: new Date(t.resetAt)
45
+ });
46
+ }
47
+ /**
48
+ * Reset rate limit for a key
49
+ */
50
+ reset(e) {
51
+ this.attempts.delete(e);
52
+ }
53
+ /**
54
+ * Clear all rate limits
55
+ */
56
+ clear() {
57
+ this.attempts.clear();
58
+ }
59
+ }
60
+ function Ee(r) {
61
+ return new J(r);
62
+ }
63
+ const Q = {
64
+ "X-Content-Type-Options": "nosniff",
65
+ "X-Frame-Options": "DENY",
66
+ "X-XSS-Protection": "1; mode=block",
67
+ "Strict-Transport-Security": "max-age=31536000; includeSubDomains",
68
+ "Content-Security-Policy": "default-src 'self'; script-src 'self' 'unsafe-inline' 'unsafe-eval'; style-src 'self' 'unsafe-inline';",
69
+ "Referrer-Policy": "strict-origin-when-cross-origin",
70
+ "Permissions-Policy": "geolocation=(), microphone=(), camera=()"
71
+ };
72
+ function z(r) {
73
+ return {
74
+ ...Q,
75
+ ...r
76
+ };
77
+ }
78
+ function ke(r, e) {
79
+ const n = z(e);
80
+ for (const [t, i] of Object.entries(n))
81
+ i && r.set(t, i);
82
+ }
83
+ function ve(r) {
84
+ if (!r || typeof r != "string")
85
+ return { valid: !1, error: "Email is required" };
86
+ const e = r.trim().toLowerCase();
87
+ return /^[^\s@]+@[^\s@]+\.[^\s@]+$/.test(e) ? e.length > 254 ? { valid: !1, error: "Email is too long" } : e.includes("..") || e.startsWith(".") || e.endsWith(".") ? { valid: !1, error: "Invalid email format" } : { valid: !0, sanitized: e } : { valid: !1, error: "Invalid email format" };
88
+ }
89
+ function Re(r, e = 8) {
90
+ if (!r || typeof r != "string")
91
+ return { valid: !1, error: "Password is required" };
92
+ if (r.length < e)
93
+ return { valid: !1, error: `Password must be at least ${e} characters` };
94
+ if (r.length > 128)
95
+ return { valid: !1, error: "Password is too long" };
96
+ if ([
97
+ "password",
98
+ "12345678",
99
+ "qwerty",
100
+ "abc123",
101
+ "password123",
102
+ "123456789",
103
+ "1234567890",
104
+ "letmein",
105
+ "welcome",
106
+ "monkey",
107
+ "dragon",
108
+ "master",
109
+ "sunshine",
110
+ "princess",
111
+ "football"
112
+ ].includes(r.toLowerCase()))
113
+ return { valid: !1, error: "Password is too common" };
114
+ if (/(.)\1{3,}/.test(r))
115
+ return { valid: !1, error: "Password contains too many repeated characters" };
116
+ if (/012|123|234|345|456|567|678|789|abc|bcd|cde|def|efg|fgh|ghi|hij|ijk|jkl|klm|lmn|mno|nop|opq|pqr|qrs|rst|stu|tuv|uvw|vwx|wxy|xyz/i.test(r))
117
+ return { valid: !1, error: "Password contains sequential characters" };
118
+ let t = "weak", i = 0;
119
+ return r.length >= 12 ? i += 2 : r.length >= 8 && (i += 1), /[a-z]/.test(r) && (i += 1), /[A-Z]/.test(r) && (i += 1), /[0-9]/.test(r) && (i += 1), /[^a-zA-Z0-9]/.test(r) && (i += 1), i >= 5 ? t = "strong" : i >= 3 && (t = "medium"), { valid: !0, strength: t };
120
+ }
121
+ function Se(r) {
122
+ if (!r || typeof r != "string")
123
+ return { valid: !1, error: "Name is required" };
124
+ const e = r.trim();
125
+ return e.length < 1 ? { valid: !1, error: "Name cannot be empty" } : e.length > 100 ? { valid: !1, error: "Name is too long" } : { valid: !0, sanitized: e.replace(/[<>\"']/g, "") };
126
+ }
127
+ function Ae(r) {
128
+ if (!r || typeof r != "string")
129
+ return { valid: !1, error: "URL is required" };
130
+ try {
131
+ const e = new URL(r);
132
+ return ["http:", "https:"].includes(e.protocol) ? { valid: !0 } : { valid: !1, error: "URL must use http or https protocol" };
133
+ } catch {
134
+ return { valid: !1, error: "Invalid URL format" };
135
+ }
136
+ }
137
+ function be(r, e = 16) {
138
+ return !r || typeof r != "string" ? { valid: !1, error: "Token is required" } : r.length < e ? { valid: !1, error: "Token is too short" } : r.length > 512 ? { valid: !1, error: "Token is too long" } : /^[A-Za-z0-9_-]+$/.test(r) ? /(.)\1{10,}/.test(r) ? { valid: !1, error: "Token contains suspicious pattern" } : { valid: !0 } : { valid: !1, error: "Invalid token format" };
139
+ }
140
+ function Oe(r, e) {
141
+ const { maxLength: n = 1e3, allowHtml: t = !1, required: i = !0 } = e || {};
142
+ if (i && (!r || typeof r != "string" || r.trim().length === 0))
143
+ return { valid: !1, error: "Input is required" };
144
+ if (!r || typeof r != "string")
145
+ return { valid: !0, sanitized: "" };
146
+ let f = r.trim();
147
+ return f.length > n ? { valid: !1, error: `Input must be less than ${n} characters` } : (t || (f = f.replace(/</g, "&lt;").replace(/>/g, "&gt;").replace(/"/g, "&quot;").replace(/'/g, "&#x27;").replace(/\//g, "&#x2F;")), f = f.replace(/[\x00-\x1F\x7F]/g, ""), { valid: !0, sanitized: f });
148
+ }
149
+ class Z {
150
+ constructor() {
151
+ C(this, "tokens", /* @__PURE__ */ new Map());
152
+ }
153
+ get(e) {
154
+ const n = this.tokens.get(e);
155
+ return n ? n.expiresAt < Date.now() ? (this.delete(e), null) : n.value : null;
156
+ }
157
+ set(e, n, t = 36e5) {
158
+ this.tokens.set(e, {
159
+ value: n,
160
+ expiresAt: Date.now() + t
161
+ });
162
+ }
163
+ delete(e) {
164
+ this.tokens.delete(e);
165
+ }
166
+ clear() {
167
+ this.tokens.clear();
168
+ }
169
+ }
170
+ class ee {
171
+ constructor(e, n = 32) {
172
+ C(this, "store");
173
+ C(this, "tokenLength");
174
+ this.store = e || new Z(), this.tokenLength = n;
175
+ }
176
+ /**
177
+ * Generate CSRF token
178
+ */
179
+ generateToken(e, n) {
180
+ const t = W(this.tokenLength);
181
+ return this.store.set(e, t, n), t;
182
+ }
183
+ /**
184
+ * Validate CSRF token
185
+ */
186
+ validateToken(e, n) {
187
+ const t = this.store.get(e);
188
+ if (!t)
189
+ return !1;
190
+ const i = se(n, t);
191
+ return i && this.store.delete(e), i;
192
+ }
193
+ /**
194
+ * Get stored token without validating
195
+ */
196
+ getToken(e) {
197
+ return this.store.get(e);
198
+ }
199
+ /**
200
+ * Delete token
201
+ */
202
+ deleteToken(e) {
203
+ this.store.delete(e);
204
+ }
205
+ }
206
+ function _e(r) {
207
+ return new ee(r);
208
+ }
209
+ function re(r) {
210
+ if (typeof r != "string")
211
+ return "";
212
+ const e = {
213
+ "&": "&amp;",
214
+ "<": "&lt;",
215
+ ">": "&gt;",
216
+ '"': "&quot;",
217
+ "'": "&#039;"
218
+ };
219
+ return r.replace(/[&<>"']/g, (n) => e[n] || n);
220
+ }
221
+ function Ie(r) {
222
+ return typeof r != "string" ? "" : r.replace(/<script\b[^<]*(?:(?!<\/script>)<[^<]*)*<\/script>/gi, "").replace(/on\w+\s*=\s*["'][^"']*["']/gi, "").replace(/javascript:/gi, "");
223
+ }
224
+ function Te(r) {
225
+ return typeof r != "string" ? "" : re(r.trim());
226
+ }
227
+ function Pe(r) {
228
+ return typeof r != "string" ? !1 : [
229
+ /<script/i,
230
+ /javascript:/i,
231
+ /on\w+\s*=/i,
232
+ /<iframe/i,
233
+ /<object/i,
234
+ /<embed/i,
235
+ /<link/i,
236
+ /<meta/i,
237
+ /expression\s*\(/i,
238
+ /vbscript:/i
239
+ ].some((n) => n.test(r));
240
+ }
241
+ function W(r = 32) {
242
+ const e = G(r);
243
+ return Buffer.from(e).toString("base64url");
244
+ }
245
+ function te() {
246
+ return W(32);
247
+ }
248
+ function se(r, e) {
249
+ if (!r || !e || r.length !== e.length)
250
+ return !1;
251
+ let n = 0;
252
+ for (let t = 0; t < r.length; t++)
253
+ n |= r.charCodeAt(t) ^ e.charCodeAt(t);
254
+ return n === 0;
255
+ }
256
+ function Ue(r) {
257
+ return r.trim().replace(/[<>]/g, "");
258
+ }
259
+ function Ce(r) {
260
+ return /^[^\s@]+@[^\s@]+\.[^\s@]+$/.test(r);
261
+ }
262
+ function ne(r) {
263
+ return !r.success && !!r.error;
264
+ }
265
+ function Fe(r) {
266
+ return r.requires2FA === !0 || r.errorCode === E.TWO_FA_REQUIRED;
267
+ }
268
+ function Ne(r, e) {
269
+ return r.error ? r.error : e || "Authentication failed";
270
+ }
271
+ function xe(r) {
272
+ return r.errorCode;
273
+ }
274
+ function je(r) {
275
+ return r.success === !0 && !!r.user;
276
+ }
277
+ function De(r, e) {
278
+ return r.errorCode === e;
279
+ }
280
+ function Le(r) {
281
+ if (!ne(r)) return !1;
282
+ const e = [
283
+ E.NETWORK_ERROR,
284
+ E.RATE_LIMITED,
285
+ E.UNKNOWN_ERROR
286
+ ];
287
+ return r.errorCode ? e.includes(r.errorCode) : !1;
288
+ }
289
+ function $e(r) {
290
+ if (r.error) return r.error;
291
+ switch (r.errorCode) {
292
+ case E.INVALID_CREDENTIALS:
293
+ return "Invalid email or password. Please try again.";
294
+ case E.ACCOUNT_LOCKED:
295
+ return "Your account has been temporarily locked. Please try again later.";
296
+ case E.ACCOUNT_INACTIVE:
297
+ return "Your account is inactive. Please contact support.";
298
+ case E.TWO_FA_REQUIRED:
299
+ return "Two-factor authentication is required. Please enter your code.";
300
+ case E.INVALID_TWO_FA_CODE:
301
+ return "Invalid two-factor authentication code. Please try again.";
302
+ case E.SESSION_EXPIRED:
303
+ return "Your session has expired. Please sign in again.";
304
+ case E.UNAUTHORIZED:
305
+ return "You are not authorized to perform this action.";
306
+ case E.NETWORK_ERROR:
307
+ return "Network error. Please check your connection and try again.";
308
+ case E.VALIDATION_ERROR:
309
+ return "Please check your input and try again.";
310
+ case E.RATE_LIMITED:
311
+ return "Too many attempts. Please try again later.";
312
+ case E.UNKNOWN_ERROR:
313
+ default:
314
+ return "An unexpected error occurred. Please try again.";
315
+ }
316
+ }
317
+ const oe = {
318
+ google: {
319
+ authorizationUrl: "https://accounts.google.com/o/oauth2/v2/auth",
320
+ tokenUrl: "https://oauth2.googleapis.com/token",
321
+ userInfoUrl: "https://www.googleapis.com/oauth2/v2/userinfo",
322
+ defaultScopes: ["openid", "profile", "email"]
323
+ },
324
+ github: {
325
+ authorizationUrl: "https://github.com/login/oauth/authorize",
326
+ tokenUrl: "https://github.com/login/oauth/access_token",
327
+ userInfoUrl: "https://api.github.com/user",
328
+ defaultScopes: ["user:email"]
329
+ },
330
+ apple: {
331
+ authorizationUrl: "https://appleid.apple.com/auth/authorize",
332
+ tokenUrl: "https://appleid.apple.com/auth/token",
333
+ userInfoUrl: "https://appleid.apple.com/auth/userinfo",
334
+ defaultScopes: ["name", "email"],
335
+ defaultParams: {
336
+ response_mode: "form_post",
337
+ response_type: "code id_token"
338
+ }
339
+ },
340
+ facebook: {
341
+ authorizationUrl: "https://www.facebook.com/v18.0/dialog/oauth",
342
+ tokenUrl: "https://graph.facebook.com/v18.0/oauth/access_token",
343
+ userInfoUrl: "https://graph.facebook.com/v18.0/me?fields=id,name,email,picture",
344
+ defaultScopes: ["email", "public_profile"]
345
+ }
346
+ };
347
+ function $(r) {
348
+ return oe[r] || null;
349
+ }
350
+ function ie(r, e, n, t) {
351
+ const i = $(r);
352
+ if (!i)
353
+ throw new Error(`Unknown OAuth provider: ${r}`);
354
+ const f = e.redirectUri || `${n}/api/auth/callback/${r}`, l = e.scopes || i.defaultScopes, a = new URLSearchParams({
355
+ client_id: e.clientId,
356
+ redirect_uri: f,
357
+ response_type: "code",
358
+ scope: l.join(" "),
359
+ state: t,
360
+ ...i.defaultParams,
361
+ ...e.params
362
+ });
363
+ return `${i.authorizationUrl}?${a.toString()}`;
364
+ }
365
+ async function ae(r, e, n, t) {
366
+ const i = $(r);
367
+ if (!i)
368
+ throw new Error(`Unknown OAuth provider: ${r}`);
369
+ const f = new URLSearchParams({
370
+ client_id: e.clientId,
371
+ code: n,
372
+ redirect_uri: t,
373
+ grant_type: "authorization_code"
374
+ });
375
+ e.clientSecret && f.append("client_secret", e.clientSecret);
376
+ const l = await fetch(i.tokenUrl, {
377
+ method: "POST",
378
+ headers: {
379
+ "Content-Type": "application/x-www-form-urlencoded",
380
+ Accept: "application/json"
381
+ },
382
+ body: f.toString()
383
+ });
384
+ if (!l.ok) {
385
+ const a = await l.text();
386
+ throw new Error(`Failed to exchange code for tokens: ${a}`);
387
+ }
388
+ return await l.json();
389
+ }
390
+ async function ce(r, e) {
391
+ var f, l, a, h;
392
+ const n = $(r);
393
+ if (!n)
394
+ throw new Error(`Unknown OAuth provider: ${r}`);
395
+ const t = await fetch(n.userInfoUrl, {
396
+ headers: {
397
+ Authorization: `Bearer ${e}`,
398
+ Accept: "application/json"
399
+ }
400
+ });
401
+ if (!t.ok) {
402
+ const m = await t.text();
403
+ throw new Error(`Failed to fetch user info: ${m}`);
404
+ }
405
+ const i = await t.json();
406
+ switch (r) {
407
+ case "google":
408
+ return {
409
+ id: i.sub || i.id,
410
+ email: i.email,
411
+ name: i.name,
412
+ avatar: i.picture,
413
+ emailVerified: i.email_verified
414
+ };
415
+ case "github":
416
+ let m = i.email;
417
+ if (!m) {
418
+ const d = await (await fetch("https://api.github.com/user/emails", {
419
+ headers: { Authorization: `Bearer ${e}` }
420
+ })).json();
421
+ m = ((f = d.find((k) => k.primary)) == null ? void 0 : f.email) || ((l = d[0]) == null ? void 0 : l.email) || `${i.login}@users.noreply.github.com`;
422
+ }
423
+ return {
424
+ id: String(i.id),
425
+ email: m,
426
+ name: i.name || i.login,
427
+ avatar: i.avatar_url,
428
+ emailVerified: !!m
429
+ };
430
+ case "apple":
431
+ return {
432
+ id: i.sub,
433
+ email: i.email,
434
+ name: i.name ? `${i.name.firstName} ${i.name.lastName}` : "",
435
+ emailVerified: i.email_verified
436
+ };
437
+ case "facebook":
438
+ return {
439
+ id: i.id,
440
+ email: i.email,
441
+ name: i.name,
442
+ avatar: (h = (a = i.picture) == null ? void 0 : a.data) == null ? void 0 : h.url,
443
+ emailVerified: !0
444
+ };
445
+ default:
446
+ return {
447
+ id: String(i.id || i.sub),
448
+ email: i.email,
449
+ name: i.name || i.display_name || i.username,
450
+ avatar: i.avatar || i.picture || i.avatar_url,
451
+ emailVerified: i.email_verified || i.emailVerified || !1
452
+ };
453
+ }
454
+ }
455
+ class le {
456
+ constructor() {
457
+ C(this, "states", /* @__PURE__ */ new Map());
458
+ }
459
+ set(e, n, t) {
460
+ this.states.set(e, n), this.cleanup();
461
+ }
462
+ get(e) {
463
+ const n = this.states.get(e);
464
+ return n ? n.expiresAt < Date.now() ? (this.delete(e), null) : n : null;
465
+ }
466
+ delete(e) {
467
+ this.states.delete(e);
468
+ }
469
+ cleanup() {
470
+ const e = Date.now();
471
+ for (const [n, t] of this.states.entries())
472
+ t.expiresAt < e && this.states.delete(n);
473
+ }
474
+ }
475
+ function ue() {
476
+ return new le();
477
+ }
478
+ function fe(r = process.env.NODE_ENV === "development") {
479
+ const e = "[Mulguard]";
480
+ return {
481
+ debug: r ? (n, t) => {
482
+ t !== void 0 ? console.debug(`${e} ${n}`, t) : console.debug(`${e} ${n}`);
483
+ } : () => {
484
+ },
485
+ info: r ? (n, t) => {
486
+ t !== void 0 ? console.info(`${e} ${n}`, t) : console.info(`${e} ${n}`);
487
+ } : () => {
488
+ },
489
+ warn: r ? (n, t) => {
490
+ t !== void 0 ? console.warn(`${e} ${n}`, t) : console.warn(`${e} ${n}`);
491
+ } : () => {
492
+ },
493
+ error: r ? (n, t) => {
494
+ t !== void 0 ? console.error(`${e} ${n}`, t) : console.error(`${e} ${n}`);
495
+ } : () => {
496
+ }
497
+ };
498
+ }
499
+ const j = fe();
500
+ function de(r, e, n, t = {}) {
501
+ const {
502
+ enabled: i = !0,
503
+ maxRetries: f = 1,
504
+ retryDelay: l = 1e3,
505
+ rateLimit: a = 3,
506
+ autoSignOutOnFailure: h = !0,
507
+ redirectToLogin: m = "/login",
508
+ autoRedirectOnFailure: v = !0
509
+ } = t;
510
+ let d = null, k = !1;
511
+ const R = [], S = [], _ = 60 * 1e3;
512
+ let A = 0, b = !1, T = null;
513
+ const L = 2, o = 60 * 1e3;
514
+ function s() {
515
+ const p = Date.now();
516
+ if (b && T) {
517
+ if (p < T)
518
+ return !1;
519
+ b = !1, T = null, A = 0;
520
+ }
521
+ for (; S.length > 0; ) {
522
+ const g = S[0];
523
+ if (g !== void 0 && g < p - _)
524
+ S.shift();
525
+ else
526
+ break;
527
+ }
528
+ return S.length >= a ? !1 : (S.push(p), !0);
529
+ }
530
+ function c() {
531
+ A++, A >= L && (b = !0, T = Date.now() + o, process.env.NODE_ENV === "development" && console.warn("[TokenRefreshManager] Circuit breaker opened - too many consecutive failures"));
532
+ }
533
+ function w() {
534
+ A = 0, b = !1, T = null;
535
+ }
536
+ async function y(p = 1) {
537
+ if (!i)
538
+ return null;
539
+ if (!s())
540
+ throw new Error("Rate limit exceeded for token refresh");
541
+ try {
542
+ const g = await r();
543
+ if (g)
544
+ return w(), D(g), t.onTokenRefreshed && await Promise.resolve(t.onTokenRefreshed(g)), g;
545
+ if (c(), p < f)
546
+ return await I(l * p), y(p + 1);
547
+ throw new Error("Token refresh failed: refresh function returned null");
548
+ } catch (g) {
549
+ if (c(), p < f && O(g))
550
+ return await I(l * p), y(p + 1);
551
+ throw g;
552
+ }
553
+ }
554
+ function O(p) {
555
+ if (p instanceof Error) {
556
+ const g = p.message.toLowerCase();
557
+ if (g.includes("rate limit") || g.includes("too many requests") || g.includes("429") || g.includes("limit:") || g.includes("requests per minute") || g.includes("token_blacklisted") || g.includes("blacklisted") || g.includes("invalid") || g.includes("401") || g.includes("unauthorized") || g.includes("session has been revoked") || g.includes("session expired"))
558
+ return !1;
559
+ if (g.includes("network") || g.includes("fetch") || g.includes("timeout"))
560
+ return !0;
561
+ }
562
+ return !1;
563
+ }
564
+ function D(p) {
565
+ const g = [...R];
566
+ R.length = 0;
567
+ for (const { resolve: U } of g)
568
+ U(p);
569
+ }
570
+ function P(p) {
571
+ const g = [...R];
572
+ R.length = 0;
573
+ for (const { reject: U } of g)
574
+ U(p);
575
+ }
576
+ function I(p) {
577
+ return new Promise((g) => setTimeout(g, p));
578
+ }
579
+ async function M(p) {
580
+ try {
581
+ if (t.onTokenRefreshFailed && await Promise.resolve(t.onTokenRefreshFailed(p)), h && (await n(), await e(), v && typeof window < "u")) {
582
+ let g = !0;
583
+ if (t.onBeforeRedirect && (g = await Promise.resolve(t.onBeforeRedirect(p))), g) {
584
+ const U = new URL(m, window.location.origin);
585
+ U.searchParams.set("reason", "session_expired"), U.searchParams.set("redirect", window.location.pathname + window.location.search), window.location.href = U.toString();
586
+ }
587
+ }
588
+ } catch (g) {
589
+ process.env.NODE_ENV === "development" && console.error("[TokenRefreshManager] Error in handleRefreshFailure:", g);
590
+ }
591
+ }
592
+ return {
593
+ /**
594
+ * Refresh token with single refresh queue
595
+ */
596
+ async refreshToken() {
597
+ return i ? d || (k = !0, d = y().then((p) => (k = !1, d = null, p)).catch((p) => {
598
+ throw k = !1, d = null, P(p), M(p).catch(() => {
599
+ }), p;
600
+ }), d) : null;
601
+ },
602
+ /**
603
+ * Check if refresh is in progress
604
+ */
605
+ isRefreshing() {
606
+ return k;
607
+ },
608
+ /**
609
+ * Wait for current refresh to complete
610
+ */
611
+ async waitForRefresh() {
612
+ return d ? new Promise((p, g) => {
613
+ R.push({ resolve: p, reject: g });
614
+ }) : null;
615
+ },
616
+ /**
617
+ * Clear state
618
+ */
619
+ clear() {
620
+ d = null, k = !1, S.length = 0, w(), P(new Error("Token refresh manager cleared"));
621
+ },
622
+ /**
623
+ * Handle token refresh failure
624
+ */
625
+ async handleRefreshFailure(p) {
626
+ return M(p);
627
+ }
628
+ };
629
+ }
630
+ function he() {
631
+ const r = process.env.NODE_ENV === "production";
632
+ return {
633
+ cookieName: "__mulguard_session",
634
+ expiresIn: 60 * 60 * 24 * 7,
635
+ // 7 days
636
+ httpOnly: !0,
637
+ secure: r,
638
+ // HTTPS only in production
639
+ sameSite: "lax",
640
+ path: "/"
641
+ };
642
+ }
643
+ function ge() {
644
+ return {
645
+ enabled: !0,
646
+ refreshThreshold: 300,
647
+ // 5 minutes before expiration
648
+ maxRetries: 0,
649
+ // No retries for blacklisted tokens
650
+ retryDelay: 1e3,
651
+ rateLimit: 1,
652
+ // 1 attempt per minute to prevent loops
653
+ autoSignOutOnFailure: !0,
654
+ redirectToLogin: "/login",
655
+ autoRedirectOnFailure: !0
656
+ };
657
+ }
658
+ function Me(r) {
659
+ var T, L;
660
+ const e = {
661
+ ...he(),
662
+ ...r.session
663
+ }, n = r.actions, t = r.callbacks || {}, i = ((T = r.providers) == null ? void 0 : T.oauth) || {}, f = process.env.NEXT_PUBLIC_URL || (process.env.VERCEL_URL ? `https://${process.env.VERCEL_URL}` : "http://localhost:3000"), l = {
664
+ ...ge(),
665
+ ...r.tokenRefresh
666
+ }, a = { ...n };
667
+ if (Object.keys(i).length > 0 && !a.signIn.oauth && (a.signIn.oauth = async (o) => {
668
+ const s = i[o];
669
+ if (!s)
670
+ throw new Error(`OAuth provider "${o}" is not configured. Add it to providers.oauth in config.`);
671
+ if (!s.clientId)
672
+ throw new Error(`OAuth provider "${o}" is missing clientId`);
673
+ const c = te();
674
+ return { url: ie(o, s, f, c), state: c };
675
+ }), Object.keys(i).length > 0 && !a.oauthCallback && (a.oauthCallback = async (o, s, c) => {
676
+ const w = i[o];
677
+ if (!w)
678
+ return {
679
+ success: !1,
680
+ error: `OAuth provider "${o}" is not configured`,
681
+ errorCode: E.VALIDATION_ERROR
682
+ };
683
+ try {
684
+ const y = w.redirectUri || `${f}/api/auth/callback/${o}`, O = await ae(o, w, s, y), D = await ce(o, O.access_token);
685
+ if (t.onOAuthUser) {
686
+ const P = await d(t.onOAuthUser, D, o);
687
+ if (!P)
688
+ return {
689
+ success: !1,
690
+ error: "Failed to create or retrieve user",
691
+ errorCode: E.VALIDATION_ERROR
692
+ };
693
+ const I = {
694
+ user: {
695
+ id: P.id,
696
+ email: P.email,
697
+ name: P.name,
698
+ avatar: D.avatar,
699
+ emailVerified: D.emailVerified
700
+ },
701
+ expiresAt: new Date(Date.now() + 7 * 24 * 60 * 60 * 1e3),
702
+ accessToken: O.access_token,
703
+ refreshToken: O.refresh_token,
704
+ tokenType: "Bearer",
705
+ expiresIn: O.expires_in
706
+ };
707
+ return await S(I), h = { session: I, timestamp: Date.now() }, t.onSignIn && await d(t.onSignIn, I.user, I), { success: !0, user: I.user, session: I };
708
+ }
709
+ return {
710
+ success: !1,
711
+ error: "OAuth user callback not implemented. Provide onOAuthUser callback or implement oauthCallback action.",
712
+ errorCode: E.VALIDATION_ERROR
713
+ };
714
+ } catch (y) {
715
+ return j.error("OAuth callback failed", { provider: o, error: y }), {
716
+ success: !1,
717
+ error: y instanceof Error ? y.message : "OAuth callback failed",
718
+ errorCode: E.NETWORK_ERROR
719
+ };
720
+ }
721
+ }), !a.signIn || !a.signIn.email)
722
+ throw new Error("mulguard: signIn.email action is required");
723
+ let h = null;
724
+ const m = ((L = r.session) == null ? void 0 : L.cacheTtl) ?? r.sessionCacheTtl ?? 5e3, v = r.oauthStateStore || ue(), d = async (o, ...s) => {
725
+ if (o)
726
+ try {
727
+ return await o(...s);
728
+ } catch (c) {
729
+ throw t.onError && await t.onError(c instanceof Error ? c : new Error(String(c)), "callback"), c;
730
+ }
731
+ }, k = async (o, s) => {
732
+ const c = {
733
+ provider: s,
734
+ expiresAt: Date.now() + 6e5
735
+ // 10 minutes
736
+ };
737
+ await Promise.resolve(v.set(o, c, 10 * 60 * 1e3)), v.cleanup && await Promise.resolve(v.cleanup());
738
+ }, R = async (o, s) => {
739
+ const c = await Promise.resolve(v.get(o));
740
+ return c ? c.expiresAt < Date.now() ? (await Promise.resolve(v.delete(o)), !1) : c.provider !== s ? !1 : (await Promise.resolve(v.delete(o)), !0) : !1;
741
+ }, S = async (o) => {
742
+ const s = e.cookieName || "__mulguard_session", c = typeof o == "object" && "token" in o ? String(o.token) : JSON.stringify(o), w = q(s, c, e);
743
+ return await K(w);
744
+ }, _ = async (o) => {
745
+ if (!o.success || !o.session)
746
+ return { success: !0 };
747
+ const s = await S(o.session);
748
+ return h = { session: o.session, timestamp: Date.now() }, o.user && t.onSignIn && await d(t.onSignIn, o.user, o.session), s;
749
+ }, A = async () => {
750
+ const o = e.cookieName || "__mulguard_session";
751
+ await Y(o, {
752
+ path: e.path,
753
+ domain: e.domain
754
+ });
755
+ }, b = {
756
+ /**
757
+ * Get current session
758
+ * Uses custom getSession action if provided, otherwise falls back to reading from cookie
759
+ * ✅ IMPROVEMENT: Added session caching for better performance
760
+ */
761
+ async getSession() {
762
+ const o = Date.now();
763
+ if (h && o - h.timestamp < m)
764
+ return h.session;
765
+ if (n.getSession)
766
+ try {
767
+ const s = await n.getSession();
768
+ if (s && F(s))
769
+ return h = { session: s, timestamp: o }, s;
770
+ s && !F(s) && (await A(), h = null);
771
+ } catch (s) {
772
+ j.debug("getSession error", { error: s }), t.onError && await d(t.onError, s instanceof Error ? s : new Error(String(s)), "getSession"), h = null;
773
+ }
774
+ try {
775
+ const s = e.cookieName || "__mulguard_session", c = await X(s);
776
+ if (c)
777
+ try {
778
+ const w = JSON.parse(c);
779
+ if (F(w))
780
+ return w.expiresAt && new Date(w.expiresAt) < /* @__PURE__ */ new Date() ? (t.onSessionExpired && await d(t.onSessionExpired, w), await A(), h = null, null) : (h = { session: w, timestamp: o }, w);
781
+ await A(), h = null;
782
+ } catch {
783
+ await A(), h = null;
784
+ }
785
+ } catch (s) {
786
+ const c = s instanceof Error ? s.message : String(s);
787
+ !c.includes("request scope") && !c.includes("cookies") && (j.warn("getSession cookie error", { error: s }), t.onError && await d(t.onError, s instanceof Error ? s : new Error(String(s)), "getSession.cookie"));
788
+ }
789
+ return null;
790
+ },
791
+ /**
792
+ * Get access token from current session
793
+ */
794
+ async getAccessToken() {
795
+ const o = await this.getSession();
796
+ return o != null && o.accessToken && typeof o.accessToken == "string" ? o.accessToken : null;
797
+ },
798
+ /**
799
+ * Get refresh token from current session
800
+ */
801
+ async getRefreshToken() {
802
+ const o = await this.getSession();
803
+ return o != null && o.refreshToken && typeof o.refreshToken == "string" ? o.refreshToken : null;
804
+ },
805
+ /**
806
+ * Check if session has valid tokens
807
+ */
808
+ async hasValidTokens() {
809
+ return !!await this.getAccessToken();
810
+ },
811
+ /**
812
+ * Sign in methods - uses custom actions from config
813
+ */
814
+ signIn: {
815
+ /**
816
+ * Sign in with email/password
817
+ */
818
+ async email(o) {
819
+ try {
820
+ const s = await a.signIn.email(o);
821
+ return s.success && s.session && await _(s), s;
822
+ } catch (s) {
823
+ return t.onError && await d(t.onError, s instanceof Error ? s : new Error(String(s)), "signIn.email"), {
824
+ success: !1,
825
+ error: s instanceof Error ? s.message : "Sign in failed"
826
+ };
827
+ }
828
+ },
829
+ /**
830
+ * Initiate OAuth sign in
831
+ * ✅ Auto-generated if providers.oauth is configured in config
832
+ */
833
+ async oauth(o) {
834
+ if (!a.signIn.oauth)
835
+ throw new Error(
836
+ "OAuth sign in is not configured. Either provide oauth action in signIn, or configure providers.oauth in config."
837
+ );
838
+ const s = await a.signIn.oauth(o);
839
+ return await k(s.state, o), s;
840
+ },
841
+ /**
842
+ * Sign in with PassKey
843
+ */
844
+ async passkey(o) {
845
+ if (!a.signIn.passkey)
846
+ throw new Error("PassKey sign in is not configured. Provide passkey action in signIn.");
847
+ try {
848
+ const s = await a.signIn.passkey(o);
849
+ return s.success && s.session && await _(s), s;
850
+ } catch (s) {
851
+ return t.onError && await d(t.onError, s instanceof Error ? s : new Error(String(s)), "signIn.passkey"), {
852
+ success: !1,
853
+ error: s instanceof Error ? s.message : "PassKey sign in failed"
854
+ };
855
+ }
856
+ },
857
+ /**
858
+ * Sign in with OTP
859
+ */
860
+ async otp(o, s) {
861
+ if (!a.signIn.otp)
862
+ throw new Error("OTP sign in is not configured. Provide otp action in signIn.");
863
+ try {
864
+ const c = await a.signIn.otp(o, s);
865
+ return c.success && c.session && await _(c), c;
866
+ } catch (c) {
867
+ return t.onError && await d(t.onError, c instanceof Error ? c : new Error(String(c)), "signIn.otp"), {
868
+ success: !1,
869
+ error: c instanceof Error ? c.message : "OTP sign in failed"
870
+ };
871
+ }
872
+ }
873
+ },
874
+ /**
875
+ * Sign in methods - alias for signIn (for backward compatibility)
876
+ */
877
+ signInMethods: {
878
+ email: (o) => b.signIn.email(o),
879
+ oauth: (o) => {
880
+ var s, c;
881
+ return ((c = (s = b.signIn).oauth) == null ? void 0 : c.call(s, o)) || Promise.reject(new Error("OAuth not configured"));
882
+ },
883
+ passkey: (o) => {
884
+ var s, c;
885
+ return ((c = (s = b.signIn).passkey) == null ? void 0 : c.call(s, o)) || Promise.reject(new Error("Passkey not configured"));
886
+ },
887
+ otp: (o, s) => {
888
+ var c, w;
889
+ return ((w = (c = b.signIn).otp) == null ? void 0 : w.call(c, o, s)) || Promise.reject(new Error("OTP not configured"));
890
+ }
891
+ },
892
+ /**
893
+ * Sign up new user
894
+ */
895
+ async signUp(o) {
896
+ if (!a.signUp)
897
+ throw new Error("Sign up is not configured. Provide signUp action in config.");
898
+ try {
899
+ const s = await a.signUp(o);
900
+ return s.success && s.session && await _(s), s;
901
+ } catch (s) {
902
+ return t.onError && await d(t.onError, s instanceof Error ? s : new Error(String(s)), "signUp"), {
903
+ success: !1,
904
+ error: s instanceof Error ? s.message : "Sign up failed"
905
+ };
906
+ }
907
+ },
908
+ /**
909
+ * Sign out
910
+ */
911
+ async signOut() {
912
+ try {
913
+ const o = await this.getSession(), s = o == null ? void 0 : o.user;
914
+ return n.signOut && await n.signOut(), await A(), h = null, s && t.onSignOut && await d(t.onSignOut, s), { success: !0 };
915
+ } catch (o) {
916
+ return await A(), t.onError && await d(t.onError, o instanceof Error ? o : new Error(String(o)), "signOut"), {
917
+ success: !1,
918
+ error: o instanceof Error ? o.message : "Sign out failed"
919
+ };
920
+ }
921
+ },
922
+ /**
923
+ * Request password reset
924
+ */
925
+ async resetPassword(o) {
926
+ if (!n.resetPassword)
927
+ throw new Error("Password reset is not configured. Provide resetPassword action in config.");
928
+ try {
929
+ return await n.resetPassword(o);
930
+ } catch (s) {
931
+ return t.onError && await d(t.onError, s instanceof Error ? s : new Error(String(s)), "resetPassword"), {
932
+ success: !1,
933
+ error: s instanceof Error ? s.message : "Password reset failed"
934
+ };
935
+ }
936
+ },
937
+ /**
938
+ * Verify email address
939
+ */
940
+ async verifyEmail(o) {
941
+ if (!n.verifyEmail)
942
+ throw new Error("Email verification is not configured. Provide verifyEmail action in config.");
943
+ try {
944
+ return await n.verifyEmail(o);
945
+ } catch (s) {
946
+ return t.onError && await d(t.onError, s instanceof Error ? s : new Error(String(s)), "verifyEmail"), {
947
+ success: !1,
948
+ error: s instanceof Error ? s.message : "Email verification failed"
949
+ };
950
+ }
951
+ },
952
+ /**
953
+ * Refresh session
954
+ * Executes custom refreshSession action with improved error handling and callbacks
955
+ */
956
+ async refreshSession() {
957
+ if (!n.refreshSession)
958
+ return this.getSession();
959
+ try {
960
+ const o = await n.refreshSession();
961
+ if (o && F(o)) {
962
+ if (await S(o), h = { session: o, timestamp: Date.now() }, t.onSessionUpdate) {
963
+ const s = await d(t.onSessionUpdate, o);
964
+ if (s && F(s)) {
965
+ if (await S(s), t.onTokenRefresh) {
966
+ const c = await this.getSession();
967
+ c && await d(t.onTokenRefresh, c, s);
968
+ }
969
+ return s;
970
+ }
971
+ }
972
+ if (t.onTokenRefresh) {
973
+ const s = await this.getSession();
974
+ s && await d(t.onTokenRefresh, s, o);
975
+ }
976
+ return o;
977
+ } else if (o && !F(o))
978
+ return await A(), null;
979
+ return null;
980
+ } catch (o) {
981
+ return await A(), t.onError && await d(t.onError, o instanceof Error ? o : new Error(String(o)), "refreshSession"), null;
982
+ }
983
+ },
984
+ /**
985
+ * OAuth callback handler
986
+ * ✅ Auto-generated if providers.oauth is configured in config
987
+ */
988
+ async oauthCallback(o, s, c) {
989
+ if (!a.oauthCallback)
990
+ throw new Error(
991
+ "OAuth callback is not configured. Either provide oauthCallback action, or configure providers.oauth in config."
992
+ );
993
+ if (!o || !s || !c)
994
+ return {
995
+ success: !1,
996
+ error: "Missing required OAuth parameters (provider, code, or state)",
997
+ errorCode: E.VALIDATION_ERROR
998
+ };
999
+ if (!await R(c, o))
1000
+ return {
1001
+ success: !1,
1002
+ error: "Invalid or expired state parameter",
1003
+ errorCode: E.VALIDATION_ERROR
1004
+ };
1005
+ try {
1006
+ const y = await a.oauthCallback(o, s, c);
1007
+ if (y.success && y.session) {
1008
+ const O = await _(y);
1009
+ O.success || (process.env.NODE_ENV === "development" && j.debug("Failed to save session cookie after oauthCallback", {
1010
+ error: O.error,
1011
+ warning: O.warning
1012
+ }), t.onError && await d(
1013
+ t.onError,
1014
+ new Error(O.warning || O.error || "Failed to save session cookie"),
1015
+ "oauthCallback.setSession"
1016
+ ));
1017
+ }
1018
+ return y;
1019
+ } catch (y) {
1020
+ return t.onError && await d(t.onError, y instanceof Error ? y : new Error(String(y)), "oauthCallback"), {
1021
+ success: !1,
1022
+ error: y instanceof Error ? y.message : "OAuth callback failed",
1023
+ errorCode: E.NETWORK_ERROR
1024
+ };
1025
+ }
1026
+ },
1027
+ /**
1028
+ * Verify 2FA code after initial sign in
1029
+ * Used when signIn returns requires2FA: true
1030
+ */
1031
+ async verify2FA(o, s) {
1032
+ if (!n.verify2FA)
1033
+ throw new Error("2FA verification is not configured. Provide verify2FA action in config.");
1034
+ try {
1035
+ const c = await n.verify2FA(o);
1036
+ if (c.success && c.session && !(s != null && s.skipCookieSave)) {
1037
+ const w = await _(c);
1038
+ w.success || (process.env.NODE_ENV === "development" && j.debug("Failed to save session cookie after verify2FA", {
1039
+ error: w.error,
1040
+ warning: w.warning
1041
+ }), t.onError && await d(
1042
+ t.onError,
1043
+ new Error(w.warning || w.error || "Failed to save session cookie"),
1044
+ "verify2FA.setSession"
1045
+ ));
1046
+ }
1047
+ return c;
1048
+ } catch (c) {
1049
+ return t.onError && await d(t.onError, c instanceof Error ? c : new Error(String(c)), "verify2FA"), {
1050
+ success: !1,
1051
+ error: c instanceof Error ? c.message : "2FA verification failed",
1052
+ errorCode: E.TWO_FA_REQUIRED
1053
+ };
1054
+ }
1055
+ },
1056
+ /**
1057
+ * Set session directly
1058
+ * Useful for Server Actions that need to save session manually
1059
+ */
1060
+ async setSession(o) {
1061
+ return F(o) ? await S(o) : {
1062
+ success: !1,
1063
+ error: "Invalid session structure"
1064
+ };
1065
+ },
1066
+ /**
1067
+ * Internal method to get session config for Server Actions
1068
+ * Used by verify2FAAction to save session cookie directly
1069
+ * @internal
1070
+ */
1071
+ _getSessionConfig() {
1072
+ return {
1073
+ cookieName: e.cookieName || "__mulguard_session",
1074
+ config: e
1075
+ };
1076
+ },
1077
+ _getCallbacks() {
1078
+ return t;
1079
+ },
1080
+ /**
1081
+ * PassKey methods
1082
+ */
1083
+ passkey: n.passkey ? {
1084
+ register: n.passkey.register,
1085
+ authenticate: async (o) => {
1086
+ var s;
1087
+ if (!((s = n.passkey) != null && s.authenticate))
1088
+ throw new Error("PassKey authenticate is not configured.");
1089
+ try {
1090
+ const c = await n.passkey.authenticate(o);
1091
+ return c.success && c.session && await _(c), c;
1092
+ } catch (c) {
1093
+ return t.onError && await d(t.onError, c instanceof Error ? c : new Error(String(c)), "passkey.authenticate"), {
1094
+ success: !1,
1095
+ error: c instanceof Error ? c.message : "PassKey authentication failed"
1096
+ };
1097
+ }
1098
+ },
1099
+ list: n.passkey.list,
1100
+ remove: n.passkey.remove
1101
+ } : void 0,
1102
+ /**
1103
+ * Two-Factor Authentication methods
1104
+ */
1105
+ twoFactor: n.twoFactor ? {
1106
+ enable: n.twoFactor.enable,
1107
+ verify: n.twoFactor.verify,
1108
+ disable: n.twoFactor.disable,
1109
+ generateBackupCodes: n.twoFactor.generateBackupCodes,
1110
+ isEnabled: n.twoFactor.isEnabled,
1111
+ verify2FA: async (o) => {
1112
+ var c;
1113
+ const s = ((c = n.twoFactor) == null ? void 0 : c.verify2FA) || n.verify2FA;
1114
+ if (!s)
1115
+ throw new Error("2FA verification is not configured. Provide verify2FA action in config.");
1116
+ try {
1117
+ const w = await s(o);
1118
+ if (w.success && w.session) {
1119
+ const y = await _(w);
1120
+ y.success || (process.env.NODE_ENV === "development" && j.debug("Failed to save session cookie after twoFactor.verify2FA", {
1121
+ error: y.error,
1122
+ warning: y.warning
1123
+ }), t.onError && await d(
1124
+ t.onError,
1125
+ new Error(y.warning || y.error || "Failed to save session cookie"),
1126
+ "twoFactor.verify2FA.setSession"
1127
+ ));
1128
+ }
1129
+ return w;
1130
+ } catch (w) {
1131
+ return t.onError && await d(t.onError, w instanceof Error ? w : new Error(String(w)), "twoFactor.verify2FA"), {
1132
+ success: !1,
1133
+ error: w instanceof Error ? w.message : "2FA verification failed",
1134
+ errorCode: E.UNKNOWN_ERROR
1135
+ };
1136
+ }
1137
+ }
1138
+ } : void 0
1139
+ };
1140
+ if (n.refreshSession) {
1141
+ const o = de(
1142
+ async () => await b.refreshSession(),
1143
+ async () => await b.signOut(),
1144
+ async () => {
1145
+ await A();
1146
+ },
1147
+ {
1148
+ ...l,
1149
+ onTokenRefreshed: l.onTokenRefreshed,
1150
+ onTokenRefreshFailed: l.onTokenRefreshFailed,
1151
+ onBeforeRedirect: l.onBeforeRedirect
1152
+ }
1153
+ );
1154
+ b._tokenRefreshManager = o, b._getTokenRefreshManager = () => o;
1155
+ }
1156
+ return b;
1157
+ }
1158
+ function Ve(r) {
1159
+ return {
1160
+ GET: async (e) => V(e, r, "GET"),
1161
+ POST: async (e) => V(e, r, "POST")
1162
+ };
1163
+ }
1164
+ async function V(r, e, n) {
1165
+ const t = new URL(r.url), i = t.pathname.replace(/^\/api\/auth/, "") || "/session", f = i.split("/").filter(Boolean);
1166
+ try {
1167
+ if (n === "GET") {
1168
+ if (i === "/session" || i === "/") {
1169
+ const l = await e.getSession();
1170
+ return u.json({ session: l });
1171
+ }
1172
+ if (i === "/providers")
1173
+ return u.json({
1174
+ providers: {
1175
+ email: !!e.signIn.email,
1176
+ oauth: !!e.signIn.oauth,
1177
+ passkey: !!e.signIn.passkey
1178
+ }
1179
+ });
1180
+ if (i.startsWith("/oauth/callback") || f[0] === "oauth" && f[1] === "callback") {
1181
+ if (!e.oauthCallback)
1182
+ return u.redirect(new URL("/login?error=oauth_not_configured", r.url));
1183
+ const l = f[2] || t.searchParams.get("provider"), a = t.searchParams.get("code"), h = t.searchParams.get("state");
1184
+ if (!l || !a || !h)
1185
+ return u.redirect(new URL("/login?error=oauth_missing_params", r.url));
1186
+ try {
1187
+ const m = await e.oauthCallback(l, a, h);
1188
+ if (m.success) {
1189
+ const v = t.searchParams.get("callbackUrl") || "/";
1190
+ return u.redirect(new URL(v, r.url));
1191
+ } else
1192
+ return u.redirect(
1193
+ new URL(`/login?error=${encodeURIComponent(m.error || "oauth_failed")}`, r.url)
1194
+ );
1195
+ } catch (m) {
1196
+ return u.redirect(
1197
+ new URL(
1198
+ `/login?error=${encodeURIComponent(m instanceof Error ? m.message : "oauth_error")}`,
1199
+ r.url
1200
+ )
1201
+ );
1202
+ }
1203
+ }
1204
+ return u.json(
1205
+ { error: "Not found" },
1206
+ { status: 404 }
1207
+ );
1208
+ }
1209
+ if (n === "POST") {
1210
+ const l = await r.json().catch(() => ({}));
1211
+ if (i === "/sign-in" || f[0] === "sign-in") {
1212
+ if (l.provider === "email" && l.email && l.password) {
1213
+ const a = await e.signIn.email({
1214
+ email: l.email,
1215
+ password: l.password
1216
+ });
1217
+ return u.json(a);
1218
+ }
1219
+ if (l.provider === "oauth" && l.providerName) {
1220
+ if (!e.signIn.oauth)
1221
+ return u.json(
1222
+ { success: !1, error: "OAuth is not configured" },
1223
+ { status: 400 }
1224
+ );
1225
+ const a = await e.signIn.oauth(l.providerName);
1226
+ return u.json(a);
1227
+ }
1228
+ if (l.provider === "passkey") {
1229
+ if (!e.signIn.passkey)
1230
+ return u.json(
1231
+ { success: !1, error: "PassKey is not configured" },
1232
+ { status: 400 }
1233
+ );
1234
+ const a = await e.signIn.passkey(l.options);
1235
+ return u.json(a);
1236
+ }
1237
+ return u.json(
1238
+ { success: !1, error: "Invalid sign in request" },
1239
+ { status: 400 }
1240
+ );
1241
+ }
1242
+ if (i === "/sign-up" || f[0] === "sign-up") {
1243
+ if (!e.signUp)
1244
+ return u.json(
1245
+ { success: !1, error: "Sign up is not configured" },
1246
+ { status: 400 }
1247
+ );
1248
+ const a = await e.signUp(l);
1249
+ return u.json(a);
1250
+ }
1251
+ if (i === "/sign-out" || f[0] === "sign-out") {
1252
+ const a = await e.signOut();
1253
+ return u.json(a);
1254
+ }
1255
+ if (i === "/reset-password" || f[0] === "reset-password") {
1256
+ if (!e.resetPassword)
1257
+ return u.json(
1258
+ { success: !1, error: "Password reset is not configured" },
1259
+ { status: 400 }
1260
+ );
1261
+ const a = await e.resetPassword(l.email);
1262
+ return u.json(a);
1263
+ }
1264
+ if (i === "/verify-email" || f[0] === "verify-email") {
1265
+ if (!e.verifyEmail)
1266
+ return u.json(
1267
+ { success: !1, error: "Email verification is not configured" },
1268
+ { status: 400 }
1269
+ );
1270
+ const a = await e.verifyEmail(l.token);
1271
+ return u.json(a);
1272
+ }
1273
+ if (i === "/refresh" || f[0] === "refresh") {
1274
+ if (!e.refreshSession) {
1275
+ const h = await e.getSession();
1276
+ return u.json({ session: h });
1277
+ }
1278
+ const a = await e.refreshSession();
1279
+ return u.json({ session: a });
1280
+ }
1281
+ if (i.startsWith("/oauth/callback") || f[0] === "oauth" && f[1] === "callback") {
1282
+ if (!e.oauthCallback)
1283
+ return u.json(
1284
+ { success: !1, error: "OAuth callback is not configured" },
1285
+ { status: 400 }
1286
+ );
1287
+ const a = l.provider || f[2] || t.searchParams.get("provider"), h = l.code || t.searchParams.get("code"), m = l.state || t.searchParams.get("state");
1288
+ if (!a || !h || !m)
1289
+ return u.json(
1290
+ {
1291
+ success: !1,
1292
+ error: "Missing required OAuth parameters. Provider, code, and state are required."
1293
+ },
1294
+ { status: 400 }
1295
+ );
1296
+ const v = await e.oauthCallback(a, h, m);
1297
+ return u.json(v);
1298
+ }
1299
+ if (i.startsWith("/passkey")) {
1300
+ if (!e.passkey)
1301
+ return u.json(
1302
+ { success: !1, error: "PassKey is not configured" },
1303
+ { status: 400 }
1304
+ );
1305
+ if (f[1] === "register" && e.passkey.register) {
1306
+ const a = await e.passkey.register(l.options);
1307
+ return u.json(a);
1308
+ }
1309
+ if (f[1] === "list" && e.passkey.list) {
1310
+ const a = await e.passkey.list();
1311
+ return u.json(a);
1312
+ }
1313
+ if (f[1] === "remove" && e.passkey.remove) {
1314
+ const a = await e.passkey.remove(l.passkeyId);
1315
+ return u.json(a);
1316
+ }
1317
+ }
1318
+ if (i === "/verify-2fa" || f[0] === "verify-2fa") {
1319
+ if (!e.verify2FA)
1320
+ return u.json(
1321
+ { success: !1, error: "2FA verification is not configured" },
1322
+ { status: 400 }
1323
+ );
1324
+ if (!l.email || !l.userId || !l.code)
1325
+ return u.json(
1326
+ {
1327
+ success: !1,
1328
+ error: "Missing required parameters. Email, userId, and code are required."
1329
+ },
1330
+ { status: 400 }
1331
+ );
1332
+ const a = await e.verify2FA({
1333
+ email: l.email,
1334
+ userId: l.userId,
1335
+ code: l.code
1336
+ });
1337
+ return u.json(a);
1338
+ }
1339
+ if (i.startsWith("/two-factor")) {
1340
+ if (!e.twoFactor)
1341
+ return u.json(
1342
+ { success: !1, error: "Two-Factor Authentication is not configured" },
1343
+ { status: 400 }
1344
+ );
1345
+ if (f[1] === "enable" && e.twoFactor.enable) {
1346
+ const a = await e.twoFactor.enable();
1347
+ return u.json(a);
1348
+ }
1349
+ if (f[1] === "verify" && e.twoFactor.verify) {
1350
+ const a = await e.twoFactor.verify(l.code);
1351
+ return u.json(a);
1352
+ }
1353
+ if (f[1] === "disable" && e.twoFactor.disable) {
1354
+ const a = await e.twoFactor.disable();
1355
+ return u.json(a);
1356
+ }
1357
+ if (f[1] === "backup-codes" && e.twoFactor.generateBackupCodes) {
1358
+ const a = await e.twoFactor.generateBackupCodes();
1359
+ return u.json(a);
1360
+ }
1361
+ if (f[1] === "is-enabled" && e.twoFactor.isEnabled) {
1362
+ const a = await e.twoFactor.isEnabled();
1363
+ return u.json({ enabled: a });
1364
+ }
1365
+ }
1366
+ return u.json(
1367
+ { error: "Not found" },
1368
+ { status: 404 }
1369
+ );
1370
+ }
1371
+ return u.json(
1372
+ { error: "Method not allowed" },
1373
+ { status: 405 }
1374
+ );
1375
+ } catch (l) {
1376
+ return u.json(
1377
+ {
1378
+ success: !1,
1379
+ error: l instanceof Error ? l.message : "Request failed"
1380
+ },
1381
+ { status: 500 }
1382
+ );
1383
+ }
1384
+ }
1385
+ function ze(r) {
1386
+ return async (e) => {
1387
+ const { method: n, nextUrl: t } = e, f = t.pathname.replace(/^\/api\/auth/, "") || "/";
1388
+ try {
1389
+ let l;
1390
+ if (n !== "GET" && n !== "HEAD")
1391
+ try {
1392
+ l = await e.json();
1393
+ } catch {
1394
+ }
1395
+ const a = Object.fromEntries(t.searchParams.entries()), h = await fetch(
1396
+ `${process.env.NEXT_PUBLIC_API_URL || ""}/api/auth${f}${Object.keys(a).length > 0 ? `?${new URLSearchParams(a).toString()}` : ""}`,
1397
+ {
1398
+ method: n,
1399
+ headers: {
1400
+ "Content-Type": "application/json",
1401
+ ...Object.fromEntries(e.headers.entries())
1402
+ },
1403
+ body: l ? JSON.stringify(l) : void 0
1404
+ }
1405
+ ), m = await h.json();
1406
+ return u.json(m, {
1407
+ status: h.status,
1408
+ headers: {
1409
+ ...Object.fromEntries(h.headers.entries())
1410
+ }
1411
+ });
1412
+ } catch (l) {
1413
+ return console.error("API handler error:", l), u.json(
1414
+ {
1415
+ success: !1,
1416
+ error: l instanceof Error ? l.message : "Internal server error"
1417
+ },
1418
+ { status: 500 }
1419
+ );
1420
+ }
1421
+ };
1422
+ }
1423
+ function We(r) {
1424
+ return async (e) => {
1425
+ const { searchParams: n } = e.nextUrl, t = n.get("provider"), i = n.get("code"), f = n.get("state");
1426
+ if (!t || !i || !f)
1427
+ return u.redirect(
1428
+ new URL("/login?error=oauth_missing_params", e.url)
1429
+ );
1430
+ try {
1431
+ if (!r.oauthCallback)
1432
+ return u.redirect(
1433
+ new URL("/login?error=oauth_not_configured", e.url)
1434
+ );
1435
+ const l = await r.oauthCallback(t, i, f);
1436
+ if (l.success) {
1437
+ const a = n.get("callbackUrl") || "/";
1438
+ return u.redirect(new URL(a, e.url));
1439
+ } else {
1440
+ const a = l.errorCode ? `${encodeURIComponent(l.error || "oauth_failed")}&code=${l.errorCode}` : encodeURIComponent(l.error || "oauth_failed");
1441
+ return u.redirect(
1442
+ new URL(`/login?error=${a}`, e.url)
1443
+ );
1444
+ }
1445
+ } catch (l) {
1446
+ return process.env.NODE_ENV === "development" && console.error("[Mulguard] OAuth callback error:", l), u.redirect(
1447
+ new URL(
1448
+ `/login?error=${encodeURIComponent(l instanceof Error ? l.message : "oauth_error")}`,
1449
+ e.url
1450
+ )
1451
+ );
1452
+ }
1453
+ };
1454
+ }
1455
+ function N(r, e) {
1456
+ const n = z({
1457
+ // Customize headers if needed
1458
+ "X-Frame-Options": "SAMEORIGIN"
1459
+ // Allow same-origin framing
1460
+ });
1461
+ for (const [t, i] of Object.entries(n))
1462
+ i && typeof i == "string" && e.headers.set(t, i);
1463
+ return e;
1464
+ }
1465
+ function Be() {
1466
+ return async (r) => {
1467
+ const e = u.next();
1468
+ return N(r, e);
1469
+ };
1470
+ }
1471
+ function He(r, e = {}) {
1472
+ const {
1473
+ protectedRoutes: n = [],
1474
+ publicRoutes: t = [],
1475
+ redirectTo: i = "/login",
1476
+ redirectIfAuthenticated: f
1477
+ } = e;
1478
+ return async (l) => {
1479
+ const { pathname: a } = l.nextUrl, h = n.some((d) => a.startsWith(d));
1480
+ let m = null;
1481
+ try {
1482
+ m = await r.getSession();
1483
+ } catch (d) {
1484
+ console.error("Middleware: Failed to get session:", d);
1485
+ }
1486
+ if (h && !m) {
1487
+ const d = l.nextUrl.clone();
1488
+ return d.pathname = i, d.searchParams.set("callbackUrl", a), u.redirect(d);
1489
+ }
1490
+ if (f && m && (a.startsWith("/login") || a.startsWith("/register"))) {
1491
+ const k = l.nextUrl.clone();
1492
+ k.pathname = f;
1493
+ const R = u.redirect(k);
1494
+ return N(l, R);
1495
+ }
1496
+ const v = u.next();
1497
+ return N(l, v);
1498
+ };
1499
+ }
1500
+ async function qe(r, e) {
1501
+ var n;
1502
+ try {
1503
+ const t = await r.getSession();
1504
+ return t ? ((n = t.user.roles) == null ? void 0 : n.includes(e)) ?? !1 : !1;
1505
+ } catch {
1506
+ return !1;
1507
+ }
1508
+ }
1509
+ function Ke(r) {
1510
+ const {
1511
+ auth: e,
1512
+ protectedRoutes: n = [],
1513
+ publicRoutes: t = [],
1514
+ redirectTo: i = "/login",
1515
+ redirectIfAuthenticated: f,
1516
+ apiPrefix: l = "/api/auth"
1517
+ } = r;
1518
+ return async (a) => {
1519
+ const { pathname: h } = a.nextUrl;
1520
+ if (h.startsWith(l)) {
1521
+ const k = u.next();
1522
+ return N(a, k);
1523
+ }
1524
+ const m = n.some((k) => h.startsWith(k));
1525
+ let v = null;
1526
+ if (m || f)
1527
+ try {
1528
+ v = await e.getSession();
1529
+ } catch (k) {
1530
+ console.error("Middleware: Failed to get session:", k);
1531
+ }
1532
+ if (m && !v) {
1533
+ const k = a.nextUrl.clone();
1534
+ k.pathname = i, k.searchParams.set("callbackUrl", h);
1535
+ const R = u.redirect(k);
1536
+ return N(a, R);
1537
+ }
1538
+ if (f && v && (h.startsWith("/login") || h.startsWith("/register"))) {
1539
+ const R = a.nextUrl.clone();
1540
+ R.pathname = f;
1541
+ const S = u.redirect(R);
1542
+ return N(a, S);
1543
+ }
1544
+ const d = u.next();
1545
+ return N(a, d);
1546
+ };
1547
+ }
1548
+ async function Xe(r, e) {
1549
+ var n;
1550
+ try {
1551
+ const t = await r.getSession();
1552
+ return t ? ((n = t.user.roles) == null ? void 0 : n.includes(e)) ?? !1 : !1;
1553
+ } catch {
1554
+ return !1;
1555
+ }
1556
+ }
1557
+ export {
1558
+ ee as CSRFProtection,
1559
+ Q as DEFAULT_SECURITY_HEADERS,
1560
+ Z as MemoryCSRFStore,
1561
+ le as MemoryOAuthStateStore,
1562
+ J as RateLimiter,
1563
+ ke as applySecurityHeaders,
1564
+ q as buildCookieOptions,
1565
+ ie as buildOAuthAuthorizationUrl,
1566
+ qe as checkRole,
1567
+ Xe as checkRoleProxy,
1568
+ Pe as containsXSSPattern,
1569
+ ze as createApiHandler,
1570
+ He as createAuthMiddleware,
1571
+ _e as createCSRFProtection,
1572
+ ue as createMemoryOAuthStateStore,
1573
+ We as createOAuthCallbackHandler,
1574
+ Ke as createProxyMiddleware,
1575
+ Ee as createRateLimiter,
1576
+ Be as createSecurityMiddleware,
1577
+ nr as createServerAuthMiddleware,
1578
+ or as createServerHelpers,
1579
+ ir as createServerUtils,
1580
+ ar as createSessionManager,
1581
+ Y as deleteCookie,
1582
+ cr as deleteOAuthStateCookie,
1583
+ re as escapeHTML,
1584
+ ae as exchangeOAuthCode,
1585
+ te as generateCSRFToken,
1586
+ W as generateToken,
1587
+ X as getCookie,
1588
+ lr as getCurrentUser,
1589
+ xe as getErrorCode,
1590
+ Ne as getErrorMessage,
1591
+ ur as getOAuthStateCookie,
1592
+ ce as getOAuthUserInfo,
1593
+ $ as getProviderMetadata,
1594
+ z as getSecurityHeaders,
1595
+ fr as getServerSession,
1596
+ dr as getSessionTimeUntilExpiry,
1597
+ $e as getUserFriendlyError,
1598
+ De as hasErrorCode,
1599
+ ne as isAuthError,
1600
+ je as isAuthSuccess,
1601
+ Le as isRetryableError,
1602
+ hr as isSessionExpiredNullable,
1603
+ gr as isSessionExpiringSoon,
1604
+ wr as isSessionValid,
1605
+ Fe as isTwoFactorRequired,
1606
+ Ce as isValidEmail,
1607
+ Me as mulguard,
1608
+ pr as refreshSession,
1609
+ mr as requireAuth,
1610
+ yr as requireRole,
1611
+ Er as requireServerAuthMiddleware,
1612
+ kr as requireServerRoleMiddleware,
1613
+ Ie as sanitizeHTML,
1614
+ Ue as sanitizeInput,
1615
+ Te as sanitizeUserInput,
1616
+ K as setCookie,
1617
+ tr as signIn,
1618
+ Je as signInEmailAction,
1619
+ Qe as signOutAction,
1620
+ Ze as signUpAction,
1621
+ vr as storeOAuthStateCookie,
1622
+ Ve as toNextJsHandler,
1623
+ ve as validateAndSanitizeEmail,
1624
+ Oe as validateAndSanitizeInput,
1625
+ Se as validateAndSanitizeName,
1626
+ Re as validateAndSanitizePassword,
1627
+ se as validateCSRFToken,
1628
+ F as validateSessionStructure,
1629
+ be as validateToken,
1630
+ Ae as validateURL,
1631
+ er as verify2FAAction,
1632
+ N as withSecurityHeaders
1633
+ };