mulguard 1.1.1 → 1.1.2
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/README.md +34 -0
- package/dist/core/auth/oauth-providers.d.ts +2 -0
- package/dist/core/types/index.d.ts +29 -0
- package/dist/index/index.js +1 -1
- package/dist/index/index.mjs +328 -301
- package/package.json +1 -1
package/dist/index/index.mjs
CHANGED
|
@@ -4,7 +4,7 @@ var F = (r, e, s) => K(r, typeof e != "symbol" ? e + "" : e, s);
|
|
|
4
4
|
import { A as y, e as X, c as Y, g as G, d as J } from "../actions-DeCfLtHA.mjs";
|
|
5
5
|
import { a as Qe, s as Ze, b as er, v as rr } from "../actions-DeCfLtHA.mjs";
|
|
6
6
|
import { v as x } from "../oauth-state-LE-qeq-K.mjs";
|
|
7
|
-
import { c as sr, p as nr, k as or, n as ir, m as ar, j as cr, l as lr, e as ur, g as fr, b as dr, i as gr, a as hr, o as wr, f as
|
|
7
|
+
import { c as sr, p as nr, k as or, n as ir, m as ar, j as cr, l as lr, e as ur, g as fr, b as dr, i as gr, a as hr, o as wr, f as mr, h as pr, r as yr, d as Er, s as kr } from "../oauth-state-LE-qeq-K.mjs";
|
|
8
8
|
import { NextResponse as f } from "next/server";
|
|
9
9
|
const j = typeof globalThis == "object" && "crypto" in globalThis ? globalThis.crypto : void 0;
|
|
10
10
|
/*! noble-hashes - MIT License (c) 2022 Paul Miller (paulmillr.com) */
|
|
@@ -76,8 +76,8 @@ function q(r) {
|
|
|
76
76
|
}
|
|
77
77
|
function Re(r, e) {
|
|
78
78
|
const s = q(e);
|
|
79
|
-
for (const [t,
|
|
80
|
-
|
|
79
|
+
for (const [t, o] of Object.entries(s))
|
|
80
|
+
o && r.set(t, o);
|
|
81
81
|
}
|
|
82
82
|
function M(r) {
|
|
83
83
|
if (!r || typeof r != "string")
|
|
@@ -114,8 +114,8 @@ function Ae(r, e = 8) {
|
|
|
114
114
|
return { valid: !1, error: "Password contains too many repeated characters" };
|
|
115
115
|
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))
|
|
116
116
|
return { valid: !1, error: "Password contains sequential characters" };
|
|
117
|
-
let t = "weak",
|
|
118
|
-
return r.length >= 12 ?
|
|
117
|
+
let t = "weak", o = 0;
|
|
118
|
+
return r.length >= 12 ? o += 2 : r.length >= 8 && (o += 1), /[a-z]/.test(r) && (o += 1), /[A-Z]/.test(r) && (o += 1), /[0-9]/.test(r) && (o += 1), /[^a-zA-Z0-9]/.test(r) && (o += 1), o >= 5 ? t = "strong" : o >= 3 && (t = "medium"), { valid: !0, strength: t };
|
|
119
119
|
}
|
|
120
120
|
function Se(r) {
|
|
121
121
|
if (!r || typeof r != "string")
|
|
@@ -133,12 +133,12 @@ function Ie(r) {
|
|
|
133
133
|
return { valid: !1, error: "Invalid URL format" };
|
|
134
134
|
}
|
|
135
135
|
}
|
|
136
|
-
function
|
|
136
|
+
function _e(r, e = 16) {
|
|
137
137
|
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" };
|
|
138
138
|
}
|
|
139
139
|
function z(r, e) {
|
|
140
|
-
const { maxLength: s = 1e3, allowHtml: t = !1, required:
|
|
141
|
-
if (
|
|
140
|
+
const { maxLength: s = 1e3, allowHtml: t = !1, required: o = !0 } = e || {};
|
|
141
|
+
if (o && (!r || typeof r != "string" || r.trim().length === 0))
|
|
142
142
|
return { valid: !1, error: "Input is required" };
|
|
143
143
|
if (!r || typeof r != "string")
|
|
144
144
|
return { valid: !0, sanitized: "" };
|
|
@@ -186,8 +186,8 @@ class te {
|
|
|
186
186
|
const t = this.store.get(e);
|
|
187
187
|
if (!t)
|
|
188
188
|
return !1;
|
|
189
|
-
const
|
|
190
|
-
return
|
|
189
|
+
const o = oe(s, t);
|
|
190
|
+
return o && this.store.delete(e), o;
|
|
191
191
|
}
|
|
192
192
|
/**
|
|
193
193
|
* Get stored token without validating
|
|
@@ -202,7 +202,7 @@ class te {
|
|
|
202
202
|
this.store.delete(e);
|
|
203
203
|
}
|
|
204
204
|
}
|
|
205
|
-
function
|
|
205
|
+
function Oe(r) {
|
|
206
206
|
return new te(r);
|
|
207
207
|
}
|
|
208
208
|
function se(r) {
|
|
@@ -217,10 +217,10 @@ function se(r) {
|
|
|
217
217
|
};
|
|
218
218
|
return r.replace(/[&<>"']/g, (s) => e[s] || s);
|
|
219
219
|
}
|
|
220
|
-
function
|
|
220
|
+
function be(r) {
|
|
221
221
|
return typeof r != "string" ? "" : r.replace(/<script\b[^<]*(?:(?!<\/script>)<[^<]*)*<\/script>/gi, "").replace(/on\w+\s*=\s*["'][^"']*["']/gi, "").replace(/javascript:/gi, "");
|
|
222
222
|
}
|
|
223
|
-
function
|
|
223
|
+
function Te(r) {
|
|
224
224
|
return typeof r != "string" ? "" : se(r.trim());
|
|
225
225
|
}
|
|
226
226
|
function Pe(r) {
|
|
@@ -350,23 +350,23 @@ function $(r) {
|
|
|
350
350
|
return ae[r] || null;
|
|
351
351
|
}
|
|
352
352
|
function ce(r, e, s, t) {
|
|
353
|
-
const
|
|
354
|
-
if (!
|
|
353
|
+
const o = $(r);
|
|
354
|
+
if (!o)
|
|
355
355
|
throw new Error(`Unknown OAuth provider: ${r}`);
|
|
356
|
-
const d = e.redirectUri || `${s}/api/auth/callback/${r}`, c = e.scopes ||
|
|
356
|
+
const d = e.redirectUri || `${s}/api/auth/callback/${r}`, c = e.scopes || o.defaultScopes, a = new URLSearchParams({
|
|
357
357
|
client_id: e.clientId,
|
|
358
358
|
redirect_uri: d,
|
|
359
359
|
response_type: "code",
|
|
360
360
|
scope: c.join(" "),
|
|
361
361
|
state: t,
|
|
362
|
-
...
|
|
362
|
+
...o.defaultParams,
|
|
363
363
|
...e.params
|
|
364
364
|
});
|
|
365
|
-
return `${
|
|
365
|
+
return `${o.authorizationUrl}?${a.toString()}`;
|
|
366
366
|
}
|
|
367
367
|
async function le(r, e, s, t) {
|
|
368
|
-
const
|
|
369
|
-
if (!
|
|
368
|
+
const o = $(r);
|
|
369
|
+
if (!o)
|
|
370
370
|
throw new Error(`Unknown OAuth provider: ${r}`);
|
|
371
371
|
const d = new URLSearchParams({
|
|
372
372
|
client_id: e.clientId,
|
|
@@ -375,7 +375,7 @@ async function le(r, e, s, t) {
|
|
|
375
375
|
grant_type: "authorization_code"
|
|
376
376
|
});
|
|
377
377
|
e.clientSecret && d.append("client_secret", e.clientSecret);
|
|
378
|
-
const c = await fetch(
|
|
378
|
+
const c = await fetch(o.tokenUrl, {
|
|
379
379
|
method: "POST",
|
|
380
380
|
headers: {
|
|
381
381
|
"Content-Type": "application/x-www-form-urlencoded",
|
|
@@ -390,7 +390,7 @@ async function le(r, e, s, t) {
|
|
|
390
390
|
return await c.json();
|
|
391
391
|
}
|
|
392
392
|
async function ue(r, e) {
|
|
393
|
-
var d, c, a,
|
|
393
|
+
var d, c, a, m;
|
|
394
394
|
const s = $(r);
|
|
395
395
|
if (!s)
|
|
396
396
|
throw new Error(`Unknown OAuth provider: ${r}`);
|
|
@@ -401,56 +401,61 @@ async function ue(r, e) {
|
|
|
401
401
|
}
|
|
402
402
|
});
|
|
403
403
|
if (!t.ok) {
|
|
404
|
-
const
|
|
405
|
-
throw new Error(`Failed to fetch user info: ${
|
|
404
|
+
const k = await t.text();
|
|
405
|
+
throw new Error(`Failed to fetch user info: ${k}`);
|
|
406
406
|
}
|
|
407
|
-
const
|
|
407
|
+
const o = await t.json();
|
|
408
408
|
switch (r) {
|
|
409
409
|
case "google":
|
|
410
410
|
return {
|
|
411
|
-
id:
|
|
412
|
-
email:
|
|
413
|
-
name:
|
|
414
|
-
avatar:
|
|
415
|
-
emailVerified:
|
|
411
|
+
id: o.sub || o.id,
|
|
412
|
+
email: o.email,
|
|
413
|
+
name: o.name,
|
|
414
|
+
avatar: o.picture,
|
|
415
|
+
emailVerified: o.email_verified,
|
|
416
|
+
rawProfile: o
|
|
416
417
|
};
|
|
417
418
|
case "github":
|
|
418
|
-
let
|
|
419
|
-
if (!
|
|
420
|
-
const
|
|
419
|
+
let k = o.email, I = { ...o };
|
|
420
|
+
if (!k) {
|
|
421
|
+
const A = await (await fetch("https://api.github.com/user/emails", {
|
|
421
422
|
headers: { Authorization: `Bearer ${e}` }
|
|
422
423
|
})).json();
|
|
423
|
-
|
|
424
|
+
k = ((d = A.find((_) => _.primary)) == null ? void 0 : d.email) || ((c = A[0]) == null ? void 0 : c.email) || `${o.login}@users.noreply.github.com`, I = { ...o, emails: A };
|
|
424
425
|
}
|
|
425
426
|
return {
|
|
426
|
-
id: String(
|
|
427
|
-
email:
|
|
428
|
-
name:
|
|
429
|
-
avatar:
|
|
430
|
-
emailVerified: !!
|
|
427
|
+
id: String(o.id),
|
|
428
|
+
email: k,
|
|
429
|
+
name: o.name || o.login,
|
|
430
|
+
avatar: o.avatar_url,
|
|
431
|
+
emailVerified: !!k,
|
|
432
|
+
rawProfile: I
|
|
431
433
|
};
|
|
432
434
|
case "apple":
|
|
433
435
|
return {
|
|
434
|
-
id:
|
|
435
|
-
email:
|
|
436
|
-
name:
|
|
437
|
-
emailVerified:
|
|
436
|
+
id: o.sub,
|
|
437
|
+
email: o.email,
|
|
438
|
+
name: o.name ? `${o.name.firstName} ${o.name.lastName}` : "",
|
|
439
|
+
emailVerified: o.email_verified,
|
|
440
|
+
rawProfile: o
|
|
438
441
|
};
|
|
439
442
|
case "facebook":
|
|
440
443
|
return {
|
|
441
|
-
id:
|
|
442
|
-
email:
|
|
443
|
-
name:
|
|
444
|
-
avatar: (
|
|
445
|
-
emailVerified: !0
|
|
444
|
+
id: o.id,
|
|
445
|
+
email: o.email,
|
|
446
|
+
name: o.name,
|
|
447
|
+
avatar: (m = (a = o.picture) == null ? void 0 : a.data) == null ? void 0 : m.url,
|
|
448
|
+
emailVerified: !0,
|
|
449
|
+
rawProfile: o
|
|
446
450
|
};
|
|
447
451
|
default:
|
|
448
452
|
return {
|
|
449
|
-
id: String(
|
|
450
|
-
email:
|
|
451
|
-
name:
|
|
452
|
-
avatar:
|
|
453
|
-
emailVerified:
|
|
453
|
+
id: String(o.id || o.sub),
|
|
454
|
+
email: o.email,
|
|
455
|
+
name: o.name || o.display_name || o.username,
|
|
456
|
+
avatar: o.avatar || o.picture || o.avatar_url,
|
|
457
|
+
emailVerified: o.email_verified || o.emailVerified || !1,
|
|
458
|
+
rawProfile: o
|
|
454
459
|
};
|
|
455
460
|
}
|
|
456
461
|
}
|
|
@@ -501,55 +506,55 @@ function ge(r = process.env.NODE_ENV === "development") {
|
|
|
501
506
|
const P = ge();
|
|
502
507
|
function he(r, e, s, t = {}) {
|
|
503
508
|
const {
|
|
504
|
-
enabled:
|
|
509
|
+
enabled: o = !0,
|
|
505
510
|
maxRetries: d = 1,
|
|
506
511
|
retryDelay: c = 1e3,
|
|
507
512
|
rateLimit: a = 3,
|
|
508
|
-
autoSignOutOnFailure:
|
|
509
|
-
redirectToLogin:
|
|
510
|
-
autoRedirectOnFailure:
|
|
513
|
+
autoSignOutOnFailure: m = !0,
|
|
514
|
+
redirectToLogin: k = "/login",
|
|
515
|
+
autoRedirectOnFailure: I = !0
|
|
511
516
|
} = t;
|
|
512
517
|
let g = null, A = !1;
|
|
513
|
-
const
|
|
514
|
-
let
|
|
518
|
+
const _ = [], b = [], U = 60 * 1e3;
|
|
519
|
+
let T = 0, O = !1, C = null;
|
|
515
520
|
const D = 2, V = 60 * 1e3;
|
|
516
521
|
function n() {
|
|
517
522
|
const l = Date.now();
|
|
518
|
-
if (
|
|
523
|
+
if (O && C) {
|
|
519
524
|
if (l < C)
|
|
520
525
|
return !1;
|
|
521
|
-
|
|
526
|
+
O = !1, C = null, T = 0;
|
|
522
527
|
}
|
|
523
|
-
for (;
|
|
524
|
-
const w =
|
|
528
|
+
for (; b.length > 0; ) {
|
|
529
|
+
const w = b[0];
|
|
525
530
|
if (w !== void 0 && w < l - U)
|
|
526
|
-
|
|
531
|
+
b.shift();
|
|
527
532
|
else
|
|
528
533
|
break;
|
|
529
534
|
}
|
|
530
|
-
return
|
|
535
|
+
return b.length >= a ? !1 : (b.push(l), !0);
|
|
531
536
|
}
|
|
532
|
-
function
|
|
533
|
-
|
|
537
|
+
function i() {
|
|
538
|
+
T++, T >= D && (O = !0, C = Date.now() + V, process.env.NODE_ENV === "development" && console.warn("[TokenRefreshManager] Circuit breaker opened - too many consecutive failures"));
|
|
534
539
|
}
|
|
535
540
|
function u() {
|
|
536
|
-
|
|
541
|
+
T = 0, O = !1, C = null;
|
|
537
542
|
}
|
|
538
|
-
async function
|
|
539
|
-
if (!
|
|
543
|
+
async function p(l = 1) {
|
|
544
|
+
if (!o)
|
|
540
545
|
return null;
|
|
541
546
|
if (!n())
|
|
542
547
|
throw new Error("Rate limit exceeded for token refresh");
|
|
543
548
|
try {
|
|
544
549
|
const w = await r();
|
|
545
550
|
if (w)
|
|
546
|
-
return u(),
|
|
547
|
-
if (
|
|
548
|
-
return await h(c * l),
|
|
551
|
+
return u(), S(w), t.onTokenRefreshed && await Promise.resolve(t.onTokenRefreshed(w)), w;
|
|
552
|
+
if (i(), l < d)
|
|
553
|
+
return await h(c * l), p(l + 1);
|
|
549
554
|
throw new Error("Token refresh failed: refresh function returned null");
|
|
550
555
|
} catch (w) {
|
|
551
|
-
if (
|
|
552
|
-
return await h(c * l),
|
|
556
|
+
if (i(), l < d && R(w))
|
|
557
|
+
return await h(c * l), p(l + 1);
|
|
553
558
|
throw w;
|
|
554
559
|
}
|
|
555
560
|
}
|
|
@@ -563,27 +568,27 @@ function he(r, e, s, t = {}) {
|
|
|
563
568
|
}
|
|
564
569
|
return !1;
|
|
565
570
|
}
|
|
566
|
-
function
|
|
567
|
-
const w = [...
|
|
568
|
-
|
|
571
|
+
function S(l) {
|
|
572
|
+
const w = [..._];
|
|
573
|
+
_.length = 0;
|
|
569
574
|
for (const { resolve: N } of w)
|
|
570
575
|
N(l);
|
|
571
576
|
}
|
|
572
577
|
function E(l) {
|
|
573
|
-
const w = [...
|
|
574
|
-
|
|
578
|
+
const w = [..._];
|
|
579
|
+
_.length = 0;
|
|
575
580
|
for (const { reject: N } of w)
|
|
576
581
|
N(l);
|
|
577
582
|
}
|
|
578
583
|
function h(l) {
|
|
579
584
|
return new Promise((w) => setTimeout(w, l));
|
|
580
585
|
}
|
|
581
|
-
async function
|
|
586
|
+
async function v(l) {
|
|
582
587
|
try {
|
|
583
|
-
if (t.onTokenRefreshFailed && await Promise.resolve(t.onTokenRefreshFailed(l)),
|
|
588
|
+
if (t.onTokenRefreshFailed && await Promise.resolve(t.onTokenRefreshFailed(l)), m && (await s(), await e(), I && typeof window < "u")) {
|
|
584
589
|
let w = !0;
|
|
585
590
|
if (t.onBeforeRedirect && (w = await Promise.resolve(t.onBeforeRedirect(l))), w) {
|
|
586
|
-
const N = new URL(
|
|
591
|
+
const N = new URL(k, window.location.origin);
|
|
587
592
|
N.searchParams.set("reason", "session_expired"), N.searchParams.set("redirect", window.location.pathname + window.location.search), window.location.href = N.toString();
|
|
588
593
|
}
|
|
589
594
|
}
|
|
@@ -596,8 +601,8 @@ function he(r, e, s, t = {}) {
|
|
|
596
601
|
* Refresh token with single refresh queue
|
|
597
602
|
*/
|
|
598
603
|
async refreshToken() {
|
|
599
|
-
return
|
|
600
|
-
throw A = !1, g = null, E(l),
|
|
604
|
+
return o ? g || (A = !0, g = p().then((l) => (A = !1, g = null, l)).catch((l) => {
|
|
605
|
+
throw A = !1, g = null, E(l), v(l).catch(() => {
|
|
601
606
|
}), l;
|
|
602
607
|
}), g) : null;
|
|
603
608
|
},
|
|
@@ -612,20 +617,20 @@ function he(r, e, s, t = {}) {
|
|
|
612
617
|
*/
|
|
613
618
|
async waitForRefresh() {
|
|
614
619
|
return g ? new Promise((l, w) => {
|
|
615
|
-
|
|
620
|
+
_.push({ resolve: l, reject: w });
|
|
616
621
|
}) : null;
|
|
617
622
|
},
|
|
618
623
|
/**
|
|
619
624
|
* Clear state
|
|
620
625
|
*/
|
|
621
626
|
clear() {
|
|
622
|
-
g = null, A = !1,
|
|
627
|
+
g = null, A = !1, b.length = 0, u(), E(new Error("Token refresh manager cleared"));
|
|
623
628
|
},
|
|
624
629
|
/**
|
|
625
630
|
* Handle token refresh failure
|
|
626
631
|
*/
|
|
627
632
|
async handleRefreshFailure(l) {
|
|
628
|
-
return
|
|
633
|
+
return v(l);
|
|
629
634
|
}
|
|
630
635
|
};
|
|
631
636
|
}
|
|
@@ -642,7 +647,7 @@ function we() {
|
|
|
642
647
|
path: "/"
|
|
643
648
|
};
|
|
644
649
|
}
|
|
645
|
-
function
|
|
650
|
+
function me() {
|
|
646
651
|
return {
|
|
647
652
|
enabled: !0,
|
|
648
653
|
refreshThreshold: 300,
|
|
@@ -662,51 +667,73 @@ function Me(r) {
|
|
|
662
667
|
const e = {
|
|
663
668
|
...we(),
|
|
664
669
|
...r.session
|
|
665
|
-
}, s = r.actions, t = r.callbacks || {},
|
|
666
|
-
...
|
|
670
|
+
}, s = r.actions, t = r.callbacks || {}, o = ((D = r.providers) == null ? void 0 : D.oauth) || {}, d = process.env.NEXT_PUBLIC_URL || (process.env.VERCEL_URL ? `https://${process.env.VERCEL_URL}` : "http://localhost:3000"), c = {
|
|
671
|
+
...me(),
|
|
667
672
|
...r.tokenRefresh
|
|
668
673
|
}, a = { ...s };
|
|
669
|
-
if (Object.keys(
|
|
670
|
-
const
|
|
671
|
-
if (!
|
|
674
|
+
if (Object.keys(o).length > 0 && !a.signIn.oauth && (a.signIn.oauth = async (n) => {
|
|
675
|
+
const i = o[n];
|
|
676
|
+
if (!i)
|
|
672
677
|
throw new Error(`OAuth provider "${n}" is not configured. Add it to providers.oauth in config.`);
|
|
673
|
-
if (!
|
|
678
|
+
if (!i.clientId)
|
|
674
679
|
throw new Error(`OAuth provider "${n}" is missing clientId`);
|
|
675
680
|
const u = ne();
|
|
676
|
-
return { url: ce(n,
|
|
677
|
-
}), Object.keys(
|
|
678
|
-
const
|
|
679
|
-
if (!
|
|
681
|
+
return { url: ce(n, i, d, u), state: u };
|
|
682
|
+
}), Object.keys(o).length > 0 && !a.oauthCallback && (a.oauthCallback = async (n, i, u) => {
|
|
683
|
+
const p = o[n];
|
|
684
|
+
if (!p)
|
|
680
685
|
return {
|
|
681
686
|
success: !1,
|
|
682
687
|
error: `OAuth provider "${n}" is not configured`,
|
|
683
688
|
errorCode: y.VALIDATION_ERROR
|
|
684
689
|
};
|
|
685
690
|
try {
|
|
686
|
-
const R =
|
|
691
|
+
const R = p.redirectUri || `${d}/api/auth/callback/${n}`, S = await le(n, p, i, R), E = await ue(n, S.access_token), h = {
|
|
692
|
+
id: E.id,
|
|
693
|
+
email: E.email,
|
|
694
|
+
name: E.name,
|
|
695
|
+
avatar: E.avatar,
|
|
696
|
+
emailVerified: E.emailVerified,
|
|
697
|
+
// ✅ NEW: Add provider information
|
|
698
|
+
provider: n,
|
|
699
|
+
// ✅ NEW: Add access token (required for backend API integration)
|
|
700
|
+
accessToken: S.access_token,
|
|
701
|
+
// ✅ NEW: Add refresh token (optional, for token refresh)
|
|
702
|
+
refreshToken: S.refresh_token,
|
|
703
|
+
// ✅ NEW: Add complete tokens object
|
|
704
|
+
tokens: {
|
|
705
|
+
access_token: S.access_token,
|
|
706
|
+
refresh_token: S.refresh_token,
|
|
707
|
+
expires_in: S.expires_in,
|
|
708
|
+
token_type: S.token_type,
|
|
709
|
+
id_token: S.id_token
|
|
710
|
+
},
|
|
711
|
+
// ✅ NEW: Add raw profile data (for advanced use cases)
|
|
712
|
+
rawProfile: E.rawProfile
|
|
713
|
+
};
|
|
687
714
|
if (t.onOAuthUser) {
|
|
688
|
-
const
|
|
689
|
-
if (!
|
|
715
|
+
const v = await g(t.onOAuthUser, h, n);
|
|
716
|
+
if (!v)
|
|
690
717
|
return {
|
|
691
718
|
success: !1,
|
|
692
719
|
error: "Failed to create or retrieve user",
|
|
693
720
|
errorCode: y.VALIDATION_ERROR
|
|
694
721
|
};
|
|
695
|
-
const
|
|
722
|
+
const l = {
|
|
696
723
|
user: {
|
|
697
|
-
id:
|
|
698
|
-
email:
|
|
699
|
-
name:
|
|
700
|
-
avatar:
|
|
701
|
-
emailVerified:
|
|
724
|
+
id: v.id,
|
|
725
|
+
email: v.email,
|
|
726
|
+
name: v.name,
|
|
727
|
+
avatar: h.avatar,
|
|
728
|
+
emailVerified: h.emailVerified
|
|
702
729
|
},
|
|
703
730
|
expiresAt: new Date(Date.now() + 7 * 24 * 60 * 60 * 1e3),
|
|
704
|
-
accessToken:
|
|
705
|
-
refreshToken:
|
|
731
|
+
accessToken: S.access_token,
|
|
732
|
+
refreshToken: S.refresh_token,
|
|
706
733
|
tokenType: "Bearer",
|
|
707
|
-
expiresIn:
|
|
734
|
+
expiresIn: S.expires_in
|
|
708
735
|
};
|
|
709
|
-
return await
|
|
736
|
+
return await b(l), m = { session: l, timestamp: Date.now() }, t.onSignIn && await g(t.onSignIn, l.user, l), { success: !0, user: l.user, session: l };
|
|
710
737
|
}
|
|
711
738
|
return {
|
|
712
739
|
success: !1,
|
|
@@ -722,40 +749,40 @@ function Me(r) {
|
|
|
722
749
|
}
|
|
723
750
|
}), !a.signIn || !a.signIn.email)
|
|
724
751
|
throw new Error("mulguard: signIn.email action is required");
|
|
725
|
-
let
|
|
726
|
-
const
|
|
752
|
+
let m = null;
|
|
753
|
+
const k = ((V = r.session) == null ? void 0 : V.cacheTtl) ?? r.sessionCacheTtl ?? 5e3, I = r.oauthStateStore || de(), g = async (n, ...i) => {
|
|
727
754
|
if (n)
|
|
728
755
|
try {
|
|
729
|
-
return await n(...
|
|
756
|
+
return await n(...i);
|
|
730
757
|
} catch (u) {
|
|
731
758
|
throw t.onError && await t.onError(u instanceof Error ? u : new Error(String(u)), "callback"), u;
|
|
732
759
|
}
|
|
733
|
-
}, A = async (n,
|
|
760
|
+
}, A = async (n, i) => {
|
|
734
761
|
const u = {
|
|
735
|
-
provider:
|
|
762
|
+
provider: i,
|
|
736
763
|
expiresAt: Date.now() + 6e5
|
|
737
764
|
// 10 minutes
|
|
738
765
|
};
|
|
739
|
-
await Promise.resolve(
|
|
740
|
-
},
|
|
741
|
-
const u = await Promise.resolve(
|
|
742
|
-
return u ? u.expiresAt < Date.now() ? (await Promise.resolve(
|
|
743
|
-
},
|
|
744
|
-
const
|
|
745
|
-
return await Y(
|
|
766
|
+
await Promise.resolve(I.set(n, u, 10 * 60 * 1e3)), I.cleanup && await Promise.resolve(I.cleanup());
|
|
767
|
+
}, _ = async (n, i) => {
|
|
768
|
+
const u = await Promise.resolve(I.get(n));
|
|
769
|
+
return u ? u.expiresAt < Date.now() ? (await Promise.resolve(I.delete(n)), !1) : u.provider !== i ? !1 : (await Promise.resolve(I.delete(n)), !0) : !1;
|
|
770
|
+
}, b = async (n) => {
|
|
771
|
+
const i = e.cookieName || "__mulguard_session", u = typeof n == "object" && "token" in n ? String(n.token) : JSON.stringify(n), p = X(i, u, e);
|
|
772
|
+
return await Y(p);
|
|
746
773
|
}, U = async (n) => {
|
|
747
774
|
if (!n.success || !n.session)
|
|
748
775
|
return { success: !0 };
|
|
749
|
-
const
|
|
750
|
-
return
|
|
751
|
-
},
|
|
776
|
+
const i = await b(n.session);
|
|
777
|
+
return m = { session: n.session, timestamp: Date.now() }, n.user && t.onSignIn && await g(t.onSignIn, n.user, n.session), i;
|
|
778
|
+
}, T = async () => {
|
|
752
779
|
const n = e.cookieName || "__mulguard_session";
|
|
753
780
|
await J(n, {
|
|
754
781
|
path: e.path,
|
|
755
782
|
domain: e.domain
|
|
756
783
|
});
|
|
757
784
|
};
|
|
758
|
-
let
|
|
785
|
+
let O = null;
|
|
759
786
|
const C = {
|
|
760
787
|
/**
|
|
761
788
|
* Get current session
|
|
@@ -764,31 +791,31 @@ function Me(r) {
|
|
|
764
791
|
*/
|
|
765
792
|
async getSession() {
|
|
766
793
|
const n = Date.now();
|
|
767
|
-
if (
|
|
768
|
-
return
|
|
794
|
+
if (m && n - m.timestamp < k)
|
|
795
|
+
return m.session;
|
|
769
796
|
if (s.getSession)
|
|
770
797
|
try {
|
|
771
|
-
const
|
|
772
|
-
if (
|
|
773
|
-
return
|
|
774
|
-
|
|
775
|
-
} catch (
|
|
776
|
-
P.debug("getSession error", { error:
|
|
798
|
+
const i = await s.getSession();
|
|
799
|
+
if (i && x(i))
|
|
800
|
+
return m = { session: i, timestamp: n }, i;
|
|
801
|
+
i && !x(i) && (await T(), m = null);
|
|
802
|
+
} catch (i) {
|
|
803
|
+
P.debug("getSession error", { error: i }), t.onError && await g(t.onError, i instanceof Error ? i : new Error(String(i)), "getSession"), m = null;
|
|
777
804
|
}
|
|
778
805
|
try {
|
|
779
|
-
const
|
|
806
|
+
const i = e.cookieName || "__mulguard_session", u = await G(i);
|
|
780
807
|
if (u)
|
|
781
808
|
try {
|
|
782
|
-
const
|
|
783
|
-
if (x(
|
|
784
|
-
return
|
|
785
|
-
await
|
|
809
|
+
const p = JSON.parse(u);
|
|
810
|
+
if (x(p))
|
|
811
|
+
return p.expiresAt && new Date(p.expiresAt) < /* @__PURE__ */ new Date() ? (t.onSessionExpired && await g(t.onSessionExpired, p), await T(), m = null, null) : (m = { session: p, timestamp: n }, p);
|
|
812
|
+
await T(), m = null;
|
|
786
813
|
} catch {
|
|
787
|
-
await
|
|
814
|
+
await T(), m = null;
|
|
788
815
|
}
|
|
789
|
-
} catch (
|
|
790
|
-
const u =
|
|
791
|
-
!u.includes("request scope") && !u.includes("cookies") && (P.warn("getSession cookie error", { error:
|
|
816
|
+
} catch (i) {
|
|
817
|
+
const u = i instanceof Error ? i.message : String(i);
|
|
818
|
+
!u.includes("request scope") && !u.includes("cookies") && (P.warn("getSession cookie error", { error: i }), t.onError && await g(t.onError, i instanceof Error ? i : new Error(String(i)), "getSession.cookie"));
|
|
792
819
|
}
|
|
793
820
|
return null;
|
|
794
821
|
},
|
|
@@ -850,33 +877,33 @@ function Me(r) {
|
|
|
850
877
|
error: "Invalid credentials",
|
|
851
878
|
errorCode: y.VALIDATION_ERROR
|
|
852
879
|
};
|
|
853
|
-
const
|
|
880
|
+
const v = {
|
|
854
881
|
email: h.sanitized,
|
|
855
882
|
password: E.password
|
|
856
883
|
// Don't sanitize password (needed for hashing)
|
|
857
|
-
}, l = await a.signIn.email(
|
|
858
|
-
return l.success && l.session && await U(l), l.success ? P.info("Sign in successful", { email:
|
|
884
|
+
}, l = await a.signIn.email(v);
|
|
885
|
+
return l.success && l.session && await U(l), l.success ? P.info("Sign in successful", { email: v.email.substring(0, 3) + "***" }) : P.warn("Sign in failed", { email: v.email.substring(0, 3) + "***", errorCode: l.errorCode }), l;
|
|
859
886
|
} catch (h) {
|
|
860
|
-
const
|
|
861
|
-
return P.error("Sign in error", { error:
|
|
887
|
+
const v = h instanceof Error ? h.message : "Sign in failed";
|
|
888
|
+
return P.error("Sign in error", { error: v, context: "signIn.email" }), t.onError && await g(t.onError, h instanceof Error ? h : new Error(String(h)), "signIn.email"), {
|
|
862
889
|
success: !1,
|
|
863
890
|
error: "Sign in failed. Please try again.",
|
|
864
891
|
errorCode: y.UNKNOWN_ERROR
|
|
865
892
|
};
|
|
866
893
|
}
|
|
867
|
-
},
|
|
894
|
+
}, i = async (E) => {
|
|
868
895
|
if (!E || typeof E != "string")
|
|
869
896
|
throw new Error("Provider is required");
|
|
870
897
|
const h = z(E, { maxLength: 50, allowHtml: !1, required: !0 });
|
|
871
898
|
if (!h.valid || !h.sanitized)
|
|
872
899
|
throw new Error("Invalid provider");
|
|
873
|
-
const
|
|
900
|
+
const v = h.sanitized.toLowerCase();
|
|
874
901
|
if (!a.signIn.oauth)
|
|
875
902
|
throw new Error(
|
|
876
903
|
"OAuth sign in is not configured. Either provide oauth action in signIn, or configure providers.oauth in config."
|
|
877
904
|
);
|
|
878
|
-
const l = await a.signIn.oauth(
|
|
879
|
-
return await A(l.state,
|
|
905
|
+
const l = await a.signIn.oauth(v);
|
|
906
|
+
return await A(l.state, v), P.info("OAuth sign in initiated", { provider: v }), l;
|
|
880
907
|
}, u = async (E) => {
|
|
881
908
|
if (!a.signIn.passkey)
|
|
882
909
|
throw new Error("PassKey sign in is not configured. Provide passkey action in signIn.");
|
|
@@ -889,18 +916,18 @@ function Me(r) {
|
|
|
889
916
|
error: h instanceof Error ? h.message : "PassKey sign in failed"
|
|
890
917
|
};
|
|
891
918
|
}
|
|
892
|
-
},
|
|
919
|
+
}, p = async (E, h) => {
|
|
893
920
|
if (!E || typeof E != "string")
|
|
894
921
|
return {
|
|
895
922
|
success: !1,
|
|
896
923
|
error: "Email is required",
|
|
897
924
|
errorCode: y.VALIDATION_ERROR
|
|
898
925
|
};
|
|
899
|
-
const
|
|
900
|
-
if (!
|
|
926
|
+
const v = M(E);
|
|
927
|
+
if (!v.valid)
|
|
901
928
|
return {
|
|
902
929
|
success: !1,
|
|
903
|
-
error:
|
|
930
|
+
error: v.error || "Invalid email format",
|
|
904
931
|
errorCode: y.VALIDATION_ERROR
|
|
905
932
|
};
|
|
906
933
|
if (h !== void 0 && (typeof h != "string" || h.length < 4 || h.length > 10))
|
|
@@ -916,8 +943,8 @@ function Me(r) {
|
|
|
916
943
|
errorCode: y.VALIDATION_ERROR
|
|
917
944
|
};
|
|
918
945
|
try {
|
|
919
|
-
const l = await a.signIn.otp(
|
|
920
|
-
return l.success && l.session && await U(l), l.success ? P.info("OTP sign in successful", { email:
|
|
946
|
+
const l = await a.signIn.otp(v.sanitized, h);
|
|
947
|
+
return l.success && l.session && await U(l), l.success ? P.info("OTP sign in successful", { email: v.sanitized.substring(0, 3) + "***" }) : P.warn("OTP sign in failed", { email: v.sanitized.substring(0, 3) + "***" }), l;
|
|
921
948
|
} catch (l) {
|
|
922
949
|
return P.error("OTP sign in error", { error: l instanceof Error ? l.message : "Unknown error", context: "signIn.otp" }), t.onError && await g(t.onError, l instanceof Error ? l : new Error(String(l)), "signIn.otp"), {
|
|
923
950
|
success: !1,
|
|
@@ -925,16 +952,16 @@ function Me(r) {
|
|
|
925
952
|
errorCode: y.UNKNOWN_ERROR
|
|
926
953
|
};
|
|
927
954
|
}
|
|
928
|
-
},
|
|
955
|
+
}, S = Object.assign(
|
|
929
956
|
async (E, h) => {
|
|
930
957
|
if (!E || typeof E != "string")
|
|
931
958
|
throw new Error("Provider is required");
|
|
932
|
-
const
|
|
933
|
-
if (!
|
|
959
|
+
const v = z(E, { maxLength: 50, allowHtml: !1, required: !0 });
|
|
960
|
+
if (!v.valid || !v.sanitized)
|
|
934
961
|
throw new Error("Invalid provider");
|
|
935
|
-
const l =
|
|
962
|
+
const l = v.sanitized.toLowerCase();
|
|
936
963
|
if (l === "google" || l === "github" || l === "apple" || l === "facebook" || typeof l == "string" && !["credentials", "otp", "passkey"].includes(l))
|
|
937
|
-
return
|
|
964
|
+
return i(l);
|
|
938
965
|
if (l === "credentials")
|
|
939
966
|
return !h || !("email" in h) || !("password" in h) ? {
|
|
940
967
|
success: !1,
|
|
@@ -949,7 +976,7 @@ function Me(r) {
|
|
|
949
976
|
errorCode: y.VALIDATION_ERROR
|
|
950
977
|
};
|
|
951
978
|
const w = h;
|
|
952
|
-
return
|
|
979
|
+
return p(w.email, w.code);
|
|
953
980
|
}
|
|
954
981
|
return l === "passkey" ? u(h) : {
|
|
955
982
|
success: !1,
|
|
@@ -959,12 +986,12 @@ function Me(r) {
|
|
|
959
986
|
},
|
|
960
987
|
{
|
|
961
988
|
email: n,
|
|
962
|
-
oauth: a.signIn.oauth ?
|
|
989
|
+
oauth: a.signIn.oauth ? i : void 0,
|
|
963
990
|
passkey: a.signIn.passkey ? u : void 0,
|
|
964
|
-
otp: a.signIn.otp ?
|
|
991
|
+
otp: a.signIn.otp ? p : void 0
|
|
965
992
|
}
|
|
966
993
|
);
|
|
967
|
-
return
|
|
994
|
+
return O = S, S;
|
|
968
995
|
})(),
|
|
969
996
|
/**
|
|
970
997
|
* Sign up new user
|
|
@@ -973,12 +1000,12 @@ function Me(r) {
|
|
|
973
1000
|
if (!a.signUp)
|
|
974
1001
|
throw new Error("Sign up is not configured. Provide signUp action in config.");
|
|
975
1002
|
try {
|
|
976
|
-
const
|
|
977
|
-
return
|
|
978
|
-
} catch (
|
|
979
|
-
return t.onError && await g(t.onError,
|
|
1003
|
+
const i = await a.signUp(n);
|
|
1004
|
+
return i.success && i.session && await U(i), i;
|
|
1005
|
+
} catch (i) {
|
|
1006
|
+
return t.onError && await g(t.onError, i instanceof Error ? i : new Error(String(i)), "signUp"), {
|
|
980
1007
|
success: !1,
|
|
981
|
-
error:
|
|
1008
|
+
error: i instanceof Error ? i.message : "Sign up failed"
|
|
982
1009
|
};
|
|
983
1010
|
}
|
|
984
1011
|
},
|
|
@@ -987,10 +1014,10 @@ function Me(r) {
|
|
|
987
1014
|
*/
|
|
988
1015
|
async signOut() {
|
|
989
1016
|
try {
|
|
990
|
-
const n = await this.getSession(),
|
|
991
|
-
return s.signOut && await s.signOut(), await
|
|
1017
|
+
const n = await this.getSession(), i = n == null ? void 0 : n.user;
|
|
1018
|
+
return s.signOut && await s.signOut(), await T(), m = null, i && t.onSignOut && await g(t.onSignOut, i), { success: !0 };
|
|
992
1019
|
} catch (n) {
|
|
993
|
-
return await
|
|
1020
|
+
return await T(), t.onError && await g(t.onError, n instanceof Error ? n : new Error(String(n)), "signOut"), {
|
|
994
1021
|
success: !1,
|
|
995
1022
|
error: n instanceof Error ? n.message : "Sign out failed"
|
|
996
1023
|
};
|
|
@@ -1004,10 +1031,10 @@ function Me(r) {
|
|
|
1004
1031
|
throw new Error("Password reset is not configured. Provide resetPassword action in config.");
|
|
1005
1032
|
try {
|
|
1006
1033
|
return await s.resetPassword(n);
|
|
1007
|
-
} catch (
|
|
1008
|
-
return t.onError && await g(t.onError,
|
|
1034
|
+
} catch (i) {
|
|
1035
|
+
return t.onError && await g(t.onError, i instanceof Error ? i : new Error(String(i)), "resetPassword"), {
|
|
1009
1036
|
success: !1,
|
|
1010
|
-
error:
|
|
1037
|
+
error: i instanceof Error ? i.message : "Password reset failed"
|
|
1011
1038
|
};
|
|
1012
1039
|
}
|
|
1013
1040
|
},
|
|
@@ -1019,10 +1046,10 @@ function Me(r) {
|
|
|
1019
1046
|
throw new Error("Email verification is not configured. Provide verifyEmail action in config.");
|
|
1020
1047
|
try {
|
|
1021
1048
|
return await s.verifyEmail(n);
|
|
1022
|
-
} catch (
|
|
1023
|
-
return t.onError && await g(t.onError,
|
|
1049
|
+
} catch (i) {
|
|
1050
|
+
return t.onError && await g(t.onError, i instanceof Error ? i : new Error(String(i)), "verifyEmail"), {
|
|
1024
1051
|
success: !1,
|
|
1025
|
-
error:
|
|
1052
|
+
error: i instanceof Error ? i.message : "Email verification failed"
|
|
1026
1053
|
};
|
|
1027
1054
|
}
|
|
1028
1055
|
},
|
|
@@ -1036,59 +1063,59 @@ function Me(r) {
|
|
|
1036
1063
|
try {
|
|
1037
1064
|
const n = await s.refreshSession();
|
|
1038
1065
|
if (n && x(n)) {
|
|
1039
|
-
if (await
|
|
1040
|
-
const
|
|
1041
|
-
if (
|
|
1042
|
-
if (await
|
|
1066
|
+
if (await b(n), m = { session: n, timestamp: Date.now() }, t.onSessionUpdate) {
|
|
1067
|
+
const i = await g(t.onSessionUpdate, n);
|
|
1068
|
+
if (i && x(i)) {
|
|
1069
|
+
if (await b(i), t.onTokenRefresh) {
|
|
1043
1070
|
const u = await this.getSession();
|
|
1044
|
-
u && await g(t.onTokenRefresh, u,
|
|
1071
|
+
u && await g(t.onTokenRefresh, u, i);
|
|
1045
1072
|
}
|
|
1046
|
-
return
|
|
1073
|
+
return i;
|
|
1047
1074
|
}
|
|
1048
1075
|
}
|
|
1049
1076
|
if (t.onTokenRefresh) {
|
|
1050
|
-
const
|
|
1051
|
-
|
|
1077
|
+
const i = await this.getSession();
|
|
1078
|
+
i && await g(t.onTokenRefresh, i, n);
|
|
1052
1079
|
}
|
|
1053
1080
|
return n;
|
|
1054
1081
|
} else if (n && !x(n))
|
|
1055
|
-
return await
|
|
1082
|
+
return await T(), null;
|
|
1056
1083
|
return null;
|
|
1057
1084
|
} catch (n) {
|
|
1058
|
-
return await
|
|
1085
|
+
return await T(), t.onError && await g(t.onError, n instanceof Error ? n : new Error(String(n)), "refreshSession"), null;
|
|
1059
1086
|
}
|
|
1060
1087
|
},
|
|
1061
1088
|
/**
|
|
1062
1089
|
* OAuth callback handler
|
|
1063
1090
|
* ✅ Auto-generated if providers.oauth is configured in config
|
|
1064
1091
|
*/
|
|
1065
|
-
async oauthCallback(n,
|
|
1092
|
+
async oauthCallback(n, i, u) {
|
|
1066
1093
|
if (!a.oauthCallback)
|
|
1067
1094
|
throw new Error(
|
|
1068
1095
|
"OAuth callback is not configured. Either provide oauthCallback action, or configure providers.oauth in config."
|
|
1069
1096
|
);
|
|
1070
|
-
if (!n || !
|
|
1097
|
+
if (!n || !i || !u)
|
|
1071
1098
|
return {
|
|
1072
1099
|
success: !1,
|
|
1073
1100
|
error: "Missing required OAuth parameters (provider, code, or state)",
|
|
1074
1101
|
errorCode: y.VALIDATION_ERROR
|
|
1075
1102
|
};
|
|
1076
|
-
if (!await
|
|
1103
|
+
if (!await _(u, n))
|
|
1077
1104
|
return {
|
|
1078
1105
|
success: !1,
|
|
1079
1106
|
error: "Invalid or expired state parameter",
|
|
1080
1107
|
errorCode: y.VALIDATION_ERROR
|
|
1081
1108
|
};
|
|
1082
1109
|
try {
|
|
1083
|
-
const R = await a.oauthCallback(n,
|
|
1110
|
+
const R = await a.oauthCallback(n, i, u);
|
|
1084
1111
|
if (R.success && R.session) {
|
|
1085
|
-
const
|
|
1086
|
-
|
|
1087
|
-
error:
|
|
1088
|
-
warning:
|
|
1112
|
+
const S = await U(R);
|
|
1113
|
+
S.success || (process.env.NODE_ENV === "development" && P.debug("Failed to save session cookie after oauthCallback", {
|
|
1114
|
+
error: S.error,
|
|
1115
|
+
warning: S.warning
|
|
1089
1116
|
}), t.onError && await g(
|
|
1090
1117
|
t.onError,
|
|
1091
|
-
new Error(
|
|
1118
|
+
new Error(S.warning || S.error || "Failed to save session cookie"),
|
|
1092
1119
|
"oauthCallback.setSession"
|
|
1093
1120
|
));
|
|
1094
1121
|
}
|
|
@@ -1105,19 +1132,19 @@ function Me(r) {
|
|
|
1105
1132
|
* Verify 2FA code after initial sign in
|
|
1106
1133
|
* Used when signIn returns requires2FA: true
|
|
1107
1134
|
*/
|
|
1108
|
-
async verify2FA(n,
|
|
1135
|
+
async verify2FA(n, i) {
|
|
1109
1136
|
if (!s.verify2FA)
|
|
1110
1137
|
throw new Error("2FA verification is not configured. Provide verify2FA action in config.");
|
|
1111
1138
|
try {
|
|
1112
1139
|
const u = await s.verify2FA(n);
|
|
1113
|
-
if (u.success && u.session && !(
|
|
1114
|
-
const
|
|
1115
|
-
|
|
1116
|
-
error:
|
|
1117
|
-
warning:
|
|
1140
|
+
if (u.success && u.session && !(i != null && i.skipCookieSave)) {
|
|
1141
|
+
const p = await U(u);
|
|
1142
|
+
p.success || (process.env.NODE_ENV === "development" && P.debug("Failed to save session cookie after verify2FA", {
|
|
1143
|
+
error: p.error,
|
|
1144
|
+
warning: p.warning
|
|
1118
1145
|
}), t.onError && await g(
|
|
1119
1146
|
t.onError,
|
|
1120
|
-
new Error(
|
|
1147
|
+
new Error(p.warning || p.error || "Failed to save session cookie"),
|
|
1121
1148
|
"verify2FA.setSession"
|
|
1122
1149
|
));
|
|
1123
1150
|
}
|
|
@@ -1135,7 +1162,7 @@ function Me(r) {
|
|
|
1135
1162
|
* Useful for Server Actions that need to save session manually
|
|
1136
1163
|
*/
|
|
1137
1164
|
async setSession(n) {
|
|
1138
|
-
return x(n) ? await
|
|
1165
|
+
return x(n) ? await b(n) : {
|
|
1139
1166
|
success: !1,
|
|
1140
1167
|
error: "Invalid session structure"
|
|
1141
1168
|
};
|
|
@@ -1160,8 +1187,8 @@ function Me(r) {
|
|
|
1160
1187
|
passkey: s.passkey ? {
|
|
1161
1188
|
register: s.passkey.register,
|
|
1162
1189
|
authenticate: async (n) => {
|
|
1163
|
-
var
|
|
1164
|
-
if (!((
|
|
1190
|
+
var i;
|
|
1191
|
+
if (!((i = s.passkey) != null && i.authenticate))
|
|
1165
1192
|
throw new Error("PassKey authenticate is not configured.");
|
|
1166
1193
|
try {
|
|
1167
1194
|
const u = await s.passkey.authenticate(n);
|
|
@@ -1187,13 +1214,13 @@ function Me(r) {
|
|
|
1187
1214
|
isEnabled: s.twoFactor.isEnabled,
|
|
1188
1215
|
verify2FA: async (n) => {
|
|
1189
1216
|
var u;
|
|
1190
|
-
const
|
|
1191
|
-
if (!
|
|
1217
|
+
const i = ((u = s.twoFactor) == null ? void 0 : u.verify2FA) || s.verify2FA;
|
|
1218
|
+
if (!i)
|
|
1192
1219
|
throw new Error("2FA verification is not configured. Provide verify2FA action in config.");
|
|
1193
1220
|
try {
|
|
1194
|
-
const
|
|
1195
|
-
if (
|
|
1196
|
-
const R = await U(
|
|
1221
|
+
const p = await i(n);
|
|
1222
|
+
if (p.success && p.session) {
|
|
1223
|
+
const R = await U(p);
|
|
1197
1224
|
R.success || (process.env.NODE_ENV === "development" && P.debug("Failed to save session cookie after twoFactor.verify2FA", {
|
|
1198
1225
|
error: R.error,
|
|
1199
1226
|
warning: R.warning
|
|
@@ -1203,11 +1230,11 @@ function Me(r) {
|
|
|
1203
1230
|
"twoFactor.verify2FA.setSession"
|
|
1204
1231
|
));
|
|
1205
1232
|
}
|
|
1206
|
-
return
|
|
1207
|
-
} catch (
|
|
1208
|
-
return t.onError && await g(t.onError,
|
|
1233
|
+
return p;
|
|
1234
|
+
} catch (p) {
|
|
1235
|
+
return t.onError && await g(t.onError, p instanceof Error ? p : new Error(String(p)), "twoFactor.verify2FA"), {
|
|
1209
1236
|
success: !1,
|
|
1210
|
-
error:
|
|
1237
|
+
error: p instanceof Error ? p.message : "2FA verification failed",
|
|
1211
1238
|
errorCode: y.UNKNOWN_ERROR
|
|
1212
1239
|
};
|
|
1213
1240
|
}
|
|
@@ -1218,18 +1245,18 @@ function Me(r) {
|
|
|
1218
1245
|
* ✅ IMPROVEMENT: Uses unified signIn logic
|
|
1219
1246
|
*/
|
|
1220
1247
|
signInMethods: {
|
|
1221
|
-
email: (n) =>
|
|
1248
|
+
email: (n) => O.email(n),
|
|
1222
1249
|
oauth: (n) => {
|
|
1223
|
-
var
|
|
1224
|
-
return ((
|
|
1250
|
+
var i;
|
|
1251
|
+
return ((i = O.oauth) == null ? void 0 : i.call(O, n)) || Promise.reject(new Error("OAuth not configured"));
|
|
1225
1252
|
},
|
|
1226
1253
|
passkey: (n) => {
|
|
1227
|
-
var
|
|
1228
|
-
return ((
|
|
1254
|
+
var i;
|
|
1255
|
+
return ((i = O.passkey) == null ? void 0 : i.call(O, n)) || Promise.reject(new Error("Passkey not configured"));
|
|
1229
1256
|
},
|
|
1230
|
-
otp: (n,
|
|
1257
|
+
otp: (n, i) => {
|
|
1231
1258
|
var u;
|
|
1232
|
-
return ((u =
|
|
1259
|
+
return ((u = O.otp) == null ? void 0 : u.call(O, n, i)) || Promise.reject(new Error("OTP not configured"));
|
|
1233
1260
|
}
|
|
1234
1261
|
}
|
|
1235
1262
|
};
|
|
@@ -1238,7 +1265,7 @@ function Me(r) {
|
|
|
1238
1265
|
async () => await C.refreshSession(),
|
|
1239
1266
|
async () => await C.signOut(),
|
|
1240
1267
|
async () => {
|
|
1241
|
-
await
|
|
1268
|
+
await T();
|
|
1242
1269
|
},
|
|
1243
1270
|
{
|
|
1244
1271
|
...c,
|
|
@@ -1258,14 +1285,14 @@ function ze(r) {
|
|
|
1258
1285
|
};
|
|
1259
1286
|
}
|
|
1260
1287
|
async function W(r, e, s) {
|
|
1261
|
-
const t = new URL(r.url),
|
|
1288
|
+
const t = new URL(r.url), o = t.pathname.replace(/^\/api\/auth/, "") || "/session", d = o.split("/").filter(Boolean);
|
|
1262
1289
|
try {
|
|
1263
1290
|
if (s === "GET") {
|
|
1264
|
-
if (
|
|
1291
|
+
if (o === "/session" || o === "/") {
|
|
1265
1292
|
const c = await e.getSession();
|
|
1266
1293
|
return f.json({ session: c });
|
|
1267
1294
|
}
|
|
1268
|
-
if (
|
|
1295
|
+
if (o === "/providers")
|
|
1269
1296
|
return f.json({
|
|
1270
1297
|
providers: {
|
|
1271
1298
|
email: !!e.signIn.email,
|
|
@@ -1273,25 +1300,25 @@ async function W(r, e, s) {
|
|
|
1273
1300
|
passkey: !!e.signIn.passkey
|
|
1274
1301
|
}
|
|
1275
1302
|
});
|
|
1276
|
-
if (
|
|
1303
|
+
if (o.startsWith("/oauth/callback") || d[0] === "oauth" && d[1] === "callback") {
|
|
1277
1304
|
if (!e.oauthCallback)
|
|
1278
1305
|
return f.redirect(new URL("/login?error=oauth_not_configured", r.url));
|
|
1279
|
-
const c = d[2] || t.searchParams.get("provider"), a = t.searchParams.get("code"),
|
|
1280
|
-
if (!c || !a || !
|
|
1306
|
+
const c = d[2] || t.searchParams.get("provider"), a = t.searchParams.get("code"), m = t.searchParams.get("state");
|
|
1307
|
+
if (!c || !a || !m)
|
|
1281
1308
|
return f.redirect(new URL("/login?error=oauth_missing_params", r.url));
|
|
1282
1309
|
try {
|
|
1283
|
-
const
|
|
1284
|
-
if (
|
|
1285
|
-
const
|
|
1286
|
-
return f.redirect(new URL(
|
|
1310
|
+
const k = await e.oauthCallback(c, a, m);
|
|
1311
|
+
if (k.success) {
|
|
1312
|
+
const I = t.searchParams.get("callbackUrl") || "/";
|
|
1313
|
+
return f.redirect(new URL(I, r.url));
|
|
1287
1314
|
} else
|
|
1288
1315
|
return f.redirect(
|
|
1289
|
-
new URL(`/login?error=${encodeURIComponent(
|
|
1316
|
+
new URL(`/login?error=${encodeURIComponent(k.error || "oauth_failed")}`, r.url)
|
|
1290
1317
|
);
|
|
1291
|
-
} catch (
|
|
1318
|
+
} catch (k) {
|
|
1292
1319
|
return f.redirect(
|
|
1293
1320
|
new URL(
|
|
1294
|
-
`/login?error=${encodeURIComponent(
|
|
1321
|
+
`/login?error=${encodeURIComponent(k instanceof Error ? k.message : "oauth_error")}`,
|
|
1295
1322
|
r.url
|
|
1296
1323
|
)
|
|
1297
1324
|
);
|
|
@@ -1304,7 +1331,7 @@ async function W(r, e, s) {
|
|
|
1304
1331
|
}
|
|
1305
1332
|
if (s === "POST") {
|
|
1306
1333
|
const c = await r.json().catch(() => ({}));
|
|
1307
|
-
if (
|
|
1334
|
+
if (o === "/sign-in" || d[0] === "sign-in") {
|
|
1308
1335
|
if (c.provider === "email" && c.email && c.password) {
|
|
1309
1336
|
const a = await e.signIn.email({
|
|
1310
1337
|
email: c.email,
|
|
@@ -1335,7 +1362,7 @@ async function W(r, e, s) {
|
|
|
1335
1362
|
{ status: 400 }
|
|
1336
1363
|
);
|
|
1337
1364
|
}
|
|
1338
|
-
if (
|
|
1365
|
+
if (o === "/sign-up" || d[0] === "sign-up") {
|
|
1339
1366
|
if (!e.signUp)
|
|
1340
1367
|
return f.json(
|
|
1341
1368
|
{ success: !1, error: "Sign up is not configured" },
|
|
@@ -1344,11 +1371,11 @@ async function W(r, e, s) {
|
|
|
1344
1371
|
const a = await e.signUp(c);
|
|
1345
1372
|
return f.json(a);
|
|
1346
1373
|
}
|
|
1347
|
-
if (
|
|
1374
|
+
if (o === "/sign-out" || d[0] === "sign-out") {
|
|
1348
1375
|
const a = await e.signOut();
|
|
1349
1376
|
return f.json(a);
|
|
1350
1377
|
}
|
|
1351
|
-
if (
|
|
1378
|
+
if (o === "/reset-password" || d[0] === "reset-password") {
|
|
1352
1379
|
if (!e.resetPassword)
|
|
1353
1380
|
return f.json(
|
|
1354
1381
|
{ success: !1, error: "Password reset is not configured" },
|
|
@@ -1357,7 +1384,7 @@ async function W(r, e, s) {
|
|
|
1357
1384
|
const a = await e.resetPassword(c.email);
|
|
1358
1385
|
return f.json(a);
|
|
1359
1386
|
}
|
|
1360
|
-
if (
|
|
1387
|
+
if (o === "/verify-email" || d[0] === "verify-email") {
|
|
1361
1388
|
if (!e.verifyEmail)
|
|
1362
1389
|
return f.json(
|
|
1363
1390
|
{ success: !1, error: "Email verification is not configured" },
|
|
@@ -1366,22 +1393,22 @@ async function W(r, e, s) {
|
|
|
1366
1393
|
const a = await e.verifyEmail(c.token);
|
|
1367
1394
|
return f.json(a);
|
|
1368
1395
|
}
|
|
1369
|
-
if (
|
|
1396
|
+
if (o === "/refresh" || d[0] === "refresh") {
|
|
1370
1397
|
if (!e.refreshSession) {
|
|
1371
|
-
const
|
|
1372
|
-
return f.json({ session:
|
|
1398
|
+
const m = await e.getSession();
|
|
1399
|
+
return f.json({ session: m });
|
|
1373
1400
|
}
|
|
1374
1401
|
const a = await e.refreshSession();
|
|
1375
1402
|
return f.json({ session: a });
|
|
1376
1403
|
}
|
|
1377
|
-
if (
|
|
1404
|
+
if (o.startsWith("/oauth/callback") || d[0] === "oauth" && d[1] === "callback") {
|
|
1378
1405
|
if (!e.oauthCallback)
|
|
1379
1406
|
return f.json(
|
|
1380
1407
|
{ success: !1, error: "OAuth callback is not configured" },
|
|
1381
1408
|
{ status: 400 }
|
|
1382
1409
|
);
|
|
1383
|
-
const a = c.provider || d[2] || t.searchParams.get("provider"),
|
|
1384
|
-
if (!a || !
|
|
1410
|
+
const a = c.provider || d[2] || t.searchParams.get("provider"), m = c.code || t.searchParams.get("code"), k = c.state || t.searchParams.get("state");
|
|
1411
|
+
if (!a || !m || !k)
|
|
1385
1412
|
return f.json(
|
|
1386
1413
|
{
|
|
1387
1414
|
success: !1,
|
|
@@ -1389,10 +1416,10 @@ async function W(r, e, s) {
|
|
|
1389
1416
|
},
|
|
1390
1417
|
{ status: 400 }
|
|
1391
1418
|
);
|
|
1392
|
-
const
|
|
1393
|
-
return f.json(
|
|
1419
|
+
const I = await e.oauthCallback(a, m, k);
|
|
1420
|
+
return f.json(I);
|
|
1394
1421
|
}
|
|
1395
|
-
if (
|
|
1422
|
+
if (o.startsWith("/passkey")) {
|
|
1396
1423
|
if (!e.passkey)
|
|
1397
1424
|
return f.json(
|
|
1398
1425
|
{ success: !1, error: "PassKey is not configured" },
|
|
@@ -1411,7 +1438,7 @@ async function W(r, e, s) {
|
|
|
1411
1438
|
return f.json(a);
|
|
1412
1439
|
}
|
|
1413
1440
|
}
|
|
1414
|
-
if (
|
|
1441
|
+
if (o === "/verify-2fa" || d[0] === "verify-2fa") {
|
|
1415
1442
|
if (!e.verify2FA)
|
|
1416
1443
|
return f.json(
|
|
1417
1444
|
{ success: !1, error: "2FA verification is not configured" },
|
|
@@ -1432,7 +1459,7 @@ async function W(r, e, s) {
|
|
|
1432
1459
|
});
|
|
1433
1460
|
return f.json(a);
|
|
1434
1461
|
}
|
|
1435
|
-
if (
|
|
1462
|
+
if (o.startsWith("/two-factor")) {
|
|
1436
1463
|
if (!e.twoFactor)
|
|
1437
1464
|
return f.json(
|
|
1438
1465
|
{ success: !1, error: "Two-Factor Authentication is not configured" },
|
|
@@ -1488,7 +1515,7 @@ function We(r) {
|
|
|
1488
1515
|
c = await e.json();
|
|
1489
1516
|
} catch {
|
|
1490
1517
|
}
|
|
1491
|
-
const a = Object.fromEntries(t.searchParams.entries()),
|
|
1518
|
+
const a = Object.fromEntries(t.searchParams.entries()), m = await fetch(
|
|
1492
1519
|
`${process.env.NEXT_PUBLIC_API_URL || ""}/api/auth${d}${Object.keys(a).length > 0 ? `?${new URLSearchParams(a).toString()}` : ""}`,
|
|
1493
1520
|
{
|
|
1494
1521
|
method: s,
|
|
@@ -1498,11 +1525,11 @@ function We(r) {
|
|
|
1498
1525
|
},
|
|
1499
1526
|
body: c ? JSON.stringify(c) : void 0
|
|
1500
1527
|
}
|
|
1501
|
-
),
|
|
1502
|
-
return f.json(
|
|
1503
|
-
status:
|
|
1528
|
+
), k = await m.json();
|
|
1529
|
+
return f.json(k, {
|
|
1530
|
+
status: m.status,
|
|
1504
1531
|
headers: {
|
|
1505
|
-
...Object.fromEntries(
|
|
1532
|
+
...Object.fromEntries(m.headers.entries())
|
|
1506
1533
|
}
|
|
1507
1534
|
});
|
|
1508
1535
|
} catch (c) {
|
|
@@ -1518,8 +1545,8 @@ function We(r) {
|
|
|
1518
1545
|
}
|
|
1519
1546
|
function qe(r) {
|
|
1520
1547
|
return async (e) => {
|
|
1521
|
-
const { searchParams: s } = e.nextUrl, t = s.get("provider"),
|
|
1522
|
-
if (!t || !
|
|
1548
|
+
const { searchParams: s } = e.nextUrl, t = s.get("provider"), o = s.get("code"), d = s.get("state");
|
|
1549
|
+
if (!t || !o || !d)
|
|
1523
1550
|
return f.redirect(
|
|
1524
1551
|
new URL("/login?error=oauth_missing_params", e.url)
|
|
1525
1552
|
);
|
|
@@ -1528,7 +1555,7 @@ function qe(r) {
|
|
|
1528
1555
|
return f.redirect(
|
|
1529
1556
|
new URL("/login?error=oauth_not_configured", e.url)
|
|
1530
1557
|
);
|
|
1531
|
-
const c = await r.oauthCallback(t,
|
|
1558
|
+
const c = await r.oauthCallback(t, o, d);
|
|
1532
1559
|
if (c.success) {
|
|
1533
1560
|
const a = s.get("callbackUrl") || "/";
|
|
1534
1561
|
return f.redirect(new URL(a, e.url));
|
|
@@ -1554,8 +1581,8 @@ function L(r, e) {
|
|
|
1554
1581
|
"X-Frame-Options": "SAMEORIGIN"
|
|
1555
1582
|
// Allow same-origin framing
|
|
1556
1583
|
});
|
|
1557
|
-
for (const [t,
|
|
1558
|
-
|
|
1584
|
+
for (const [t, o] of Object.entries(s))
|
|
1585
|
+
o && typeof o == "string" && e.headers.set(t, o);
|
|
1559
1586
|
return e;
|
|
1560
1587
|
}
|
|
1561
1588
|
function Be() {
|
|
@@ -1568,29 +1595,29 @@ function He(r, e = {}) {
|
|
|
1568
1595
|
const {
|
|
1569
1596
|
protectedRoutes: s = [],
|
|
1570
1597
|
publicRoutes: t = [],
|
|
1571
|
-
redirectTo:
|
|
1598
|
+
redirectTo: o = "/login",
|
|
1572
1599
|
redirectIfAuthenticated: d
|
|
1573
1600
|
} = e;
|
|
1574
1601
|
return async (c) => {
|
|
1575
|
-
const { pathname: a } = c.nextUrl,
|
|
1576
|
-
let
|
|
1602
|
+
const { pathname: a } = c.nextUrl, m = s.some((g) => a.startsWith(g));
|
|
1603
|
+
let k = null;
|
|
1577
1604
|
try {
|
|
1578
|
-
|
|
1605
|
+
k = await r.getSession();
|
|
1579
1606
|
} catch (g) {
|
|
1580
1607
|
console.error("Middleware: Failed to get session:", g);
|
|
1581
1608
|
}
|
|
1582
|
-
if (
|
|
1609
|
+
if (m && !k) {
|
|
1583
1610
|
const g = c.nextUrl.clone();
|
|
1584
|
-
return g.pathname =
|
|
1611
|
+
return g.pathname = o, g.searchParams.set("callbackUrl", a), f.redirect(g);
|
|
1585
1612
|
}
|
|
1586
|
-
if (d &&
|
|
1613
|
+
if (d && k && (a.startsWith("/login") || a.startsWith("/register"))) {
|
|
1587
1614
|
const A = c.nextUrl.clone();
|
|
1588
1615
|
A.pathname = d;
|
|
1589
|
-
const
|
|
1590
|
-
return L(c,
|
|
1616
|
+
const _ = f.redirect(A);
|
|
1617
|
+
return L(c, _);
|
|
1591
1618
|
}
|
|
1592
|
-
const
|
|
1593
|
-
return L(c,
|
|
1619
|
+
const I = f.next();
|
|
1620
|
+
return L(c, I);
|
|
1594
1621
|
};
|
|
1595
1622
|
}
|
|
1596
1623
|
async function Ke(r, e) {
|
|
@@ -1607,35 +1634,35 @@ function Xe(r) {
|
|
|
1607
1634
|
auth: e,
|
|
1608
1635
|
protectedRoutes: s = [],
|
|
1609
1636
|
publicRoutes: t = [],
|
|
1610
|
-
redirectTo:
|
|
1637
|
+
redirectTo: o = "/login",
|
|
1611
1638
|
redirectIfAuthenticated: d,
|
|
1612
1639
|
apiPrefix: c = "/api/auth"
|
|
1613
1640
|
} = r;
|
|
1614
1641
|
return async (a) => {
|
|
1615
|
-
const { pathname:
|
|
1616
|
-
if (
|
|
1642
|
+
const { pathname: m } = a.nextUrl;
|
|
1643
|
+
if (m.startsWith(c)) {
|
|
1617
1644
|
const A = f.next();
|
|
1618
1645
|
return L(a, A);
|
|
1619
1646
|
}
|
|
1620
|
-
const
|
|
1621
|
-
let
|
|
1622
|
-
if (
|
|
1647
|
+
const k = s.some((A) => m.startsWith(A));
|
|
1648
|
+
let I = null;
|
|
1649
|
+
if (k || d)
|
|
1623
1650
|
try {
|
|
1624
|
-
|
|
1651
|
+
I = await e.getSession();
|
|
1625
1652
|
} catch (A) {
|
|
1626
1653
|
console.error("Middleware: Failed to get session:", A);
|
|
1627
1654
|
}
|
|
1628
|
-
if (
|
|
1655
|
+
if (k && !I) {
|
|
1629
1656
|
const A = a.nextUrl.clone();
|
|
1630
|
-
A.pathname =
|
|
1631
|
-
const
|
|
1632
|
-
return L(a,
|
|
1657
|
+
A.pathname = o, A.searchParams.set("callbackUrl", m);
|
|
1658
|
+
const _ = f.redirect(A);
|
|
1659
|
+
return L(a, _);
|
|
1633
1660
|
}
|
|
1634
|
-
if (d &&
|
|
1635
|
-
const
|
|
1636
|
-
|
|
1637
|
-
const
|
|
1638
|
-
return L(a,
|
|
1661
|
+
if (d && I && (m.startsWith("/login") || m.startsWith("/register"))) {
|
|
1662
|
+
const _ = a.nextUrl.clone();
|
|
1663
|
+
_.pathname = d;
|
|
1664
|
+
const b = f.redirect(_);
|
|
1665
|
+
return L(a, b);
|
|
1639
1666
|
}
|
|
1640
1667
|
const g = f.next();
|
|
1641
1668
|
return L(a, g);
|
|
@@ -1664,7 +1691,7 @@ export {
|
|
|
1664
1691
|
Pe as containsXSSPattern,
|
|
1665
1692
|
We as createApiHandler,
|
|
1666
1693
|
He as createAuthMiddleware,
|
|
1667
|
-
|
|
1694
|
+
Oe as createCSRFProtection,
|
|
1668
1695
|
de as createMemoryOAuthStateStore,
|
|
1669
1696
|
qe as createOAuthCallbackHandler,
|
|
1670
1697
|
Xe as createProxyMiddleware,
|
|
@@ -1702,13 +1729,13 @@ export {
|
|
|
1702
1729
|
Ue as isValidEmail,
|
|
1703
1730
|
Me as mulguard,
|
|
1704
1731
|
wr as refreshSession,
|
|
1705
|
-
|
|
1706
|
-
|
|
1732
|
+
mr as requireAuth,
|
|
1733
|
+
pr as requireRole,
|
|
1707
1734
|
yr as requireServerAuthMiddleware,
|
|
1708
1735
|
Er as requireServerRoleMiddleware,
|
|
1709
|
-
|
|
1736
|
+
be as sanitizeHTML,
|
|
1710
1737
|
Ce as sanitizeInput,
|
|
1711
|
-
|
|
1738
|
+
Te as sanitizeUserInput,
|
|
1712
1739
|
Y as setCookie,
|
|
1713
1740
|
$e as signIn,
|
|
1714
1741
|
Qe as signInEmailAction,
|
|
@@ -1722,7 +1749,7 @@ export {
|
|
|
1722
1749
|
Ae as validateAndSanitizePassword,
|
|
1723
1750
|
oe as validateCSRFToken,
|
|
1724
1751
|
x as validateSessionStructure,
|
|
1725
|
-
|
|
1752
|
+
_e as validateToken,
|
|
1726
1753
|
Ie as validateURL,
|
|
1727
1754
|
rr as verify2FAAction,
|
|
1728
1755
|
L as withSecurityHeaders
|