mulguard 1.1.2 → 1.1.4
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/core/auth/oauth-providers.d.ts +175 -49
- package/dist/core/auth/oauth-state-store-redis.d.ts +25 -0
- package/dist/core/index.d.ts +1 -0
- package/dist/core/mulguard/auth-handlers.d.ts +100 -0
- package/dist/core/mulguard/defaults.d.ts +58 -0
- package/dist/core/mulguard/index.d.ts +9 -0
- package/dist/core/mulguard/oauth-handler.d.ts +93 -0
- package/dist/core/mulguard/session-manager.d.ts +94 -0
- package/dist/core/security/index.d.ts +113 -9
- package/dist/core/security/validation.d.ts +231 -33
- package/dist/core/types/auth.d.ts +234 -75
- package/dist/core/types/errors.d.ts +174 -18
- package/dist/core/types/index.d.ts +397 -333
- package/dist/core/utils/logger.d.ts +112 -8
- package/dist/handlers/route.d.ts +59 -5
- package/dist/index/index.js +1 -1
- package/dist/index/index.mjs +1579 -1213
- package/dist/mulguard.d.ts +76 -1
- package/dist/server/helpers.d.ts +3 -3
- package/dist/server/utils.d.ts +3 -3
- package/package.json +1 -1
package/dist/index/index.mjs
CHANGED
|
@@ -1,53 +1,53 @@
|
|
|
1
|
-
var
|
|
2
|
-
var
|
|
3
|
-
var
|
|
4
|
-
import { A as
|
|
5
|
-
import { a as
|
|
6
|
-
import { v as
|
|
7
|
-
import { c as
|
|
8
|
-
import { NextResponse as
|
|
9
|
-
const
|
|
1
|
+
var ne = Object.defineProperty;
|
|
2
|
+
var se = (e, r, t) => r in e ? ne(e, r, { enumerable: !0, configurable: !0, writable: !0, value: t }) : e[r] = t;
|
|
3
|
+
var U = (e, r, t) => se(e, typeof r != "symbol" ? r + "" : r, t);
|
|
4
|
+
import { A as m, d as ie, e as oe, c as ae, g as ce } from "../actions-DeCfLtHA.mjs";
|
|
5
|
+
import { a as ft, s as dt, b as ht, v as gt } from "../actions-DeCfLtHA.mjs";
|
|
6
|
+
import { v as N } from "../oauth-state-LE-qeq-K.mjs";
|
|
7
|
+
import { c as pt, p as mt, k as Et, n as yt, m as kt, j as vt, l as St, e as Rt, g as At, b as Ot, i as Tt, a as It, o as _t, f as Pt, h as Ct, r as bt, d as Ut, s as Nt } from "../oauth-state-LE-qeq-K.mjs";
|
|
8
|
+
import { NextResponse as E } from "next/server";
|
|
9
|
+
const x = typeof globalThis == "object" && "crypto" in globalThis ? globalThis.crypto : void 0;
|
|
10
10
|
/*! noble-hashes - MIT License (c) 2022 Paul Miller (paulmillr.com) */
|
|
11
|
-
function
|
|
12
|
-
if (
|
|
13
|
-
return
|
|
14
|
-
if (
|
|
15
|
-
return Uint8Array.from(
|
|
11
|
+
function ue(e = 32) {
|
|
12
|
+
if (x && typeof x.getRandomValues == "function")
|
|
13
|
+
return x.getRandomValues(new Uint8Array(e));
|
|
14
|
+
if (x && typeof x.randomBytes == "function")
|
|
15
|
+
return Uint8Array.from(x.randomBytes(e));
|
|
16
16
|
throw new Error("crypto.getRandomValues must be defined");
|
|
17
17
|
}
|
|
18
|
-
class
|
|
19
|
-
constructor(
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
this.config =
|
|
18
|
+
class le {
|
|
19
|
+
constructor(r) {
|
|
20
|
+
U(this, "attempts", /* @__PURE__ */ new Map());
|
|
21
|
+
U(this, "config");
|
|
22
|
+
this.config = r;
|
|
23
23
|
}
|
|
24
24
|
/**
|
|
25
25
|
* Check if request is allowed
|
|
26
26
|
*/
|
|
27
|
-
check(
|
|
28
|
-
const
|
|
29
|
-
return !
|
|
27
|
+
check(r) {
|
|
28
|
+
const t = Date.now(), n = this.attempts.get(r);
|
|
29
|
+
return !n || n.resetAt < t ? (this.attempts.set(r, {
|
|
30
30
|
count: 1,
|
|
31
|
-
resetAt:
|
|
31
|
+
resetAt: t + this.config.windowMs
|
|
32
32
|
}), {
|
|
33
33
|
allowed: !0,
|
|
34
34
|
remaining: this.config.maxAttempts - 1,
|
|
35
|
-
resetAt: new Date(
|
|
36
|
-
}) :
|
|
35
|
+
resetAt: new Date(t + this.config.windowMs)
|
|
36
|
+
}) : n.count >= this.config.maxAttempts ? {
|
|
37
37
|
allowed: !1,
|
|
38
38
|
remaining: 0,
|
|
39
|
-
resetAt: new Date(
|
|
40
|
-
} : (
|
|
39
|
+
resetAt: new Date(n.resetAt)
|
|
40
|
+
} : (n.count++, {
|
|
41
41
|
allowed: !0,
|
|
42
|
-
remaining: this.config.maxAttempts -
|
|
43
|
-
resetAt: new Date(
|
|
42
|
+
remaining: this.config.maxAttempts - n.count,
|
|
43
|
+
resetAt: new Date(n.resetAt)
|
|
44
44
|
});
|
|
45
45
|
}
|
|
46
46
|
/**
|
|
47
47
|
* Reset rate limit for a key
|
|
48
48
|
*/
|
|
49
|
-
reset(
|
|
50
|
-
this.attempts.delete(
|
|
49
|
+
reset(r) {
|
|
50
|
+
this.attempts.delete(r);
|
|
51
51
|
}
|
|
52
52
|
/**
|
|
53
53
|
* Clear all rate limits
|
|
@@ -56,10 +56,10 @@ class Z {
|
|
|
56
56
|
this.attempts.clear();
|
|
57
57
|
}
|
|
58
58
|
}
|
|
59
|
-
function
|
|
60
|
-
return new
|
|
59
|
+
function Or(e) {
|
|
60
|
+
return new le(e);
|
|
61
61
|
}
|
|
62
|
-
const
|
|
62
|
+
const fe = {
|
|
63
63
|
"X-Content-Type-Options": "nosniff",
|
|
64
64
|
"X-Frame-Options": "DENY",
|
|
65
65
|
"X-XSS-Protection": "1; mode=block",
|
|
@@ -68,163 +68,203 @@ const ee = {
|
|
|
68
68
|
"Referrer-Policy": "strict-origin-when-cross-origin",
|
|
69
69
|
"Permissions-Policy": "geolocation=(), microphone=(), camera=()"
|
|
70
70
|
};
|
|
71
|
-
function
|
|
71
|
+
function H(e) {
|
|
72
72
|
return {
|
|
73
|
-
...
|
|
74
|
-
...
|
|
73
|
+
...fe,
|
|
74
|
+
...e
|
|
75
75
|
};
|
|
76
76
|
}
|
|
77
|
-
function
|
|
78
|
-
const
|
|
79
|
-
for (const [
|
|
80
|
-
|
|
77
|
+
function Tr(e, r) {
|
|
78
|
+
const t = H(r);
|
|
79
|
+
for (const [n, s] of Object.entries(t))
|
|
80
|
+
s && e.set(n, s);
|
|
81
81
|
}
|
|
82
|
-
|
|
83
|
-
|
|
82
|
+
const de = /^[^\s@]+@[^\s@]+\.[^\s@]+$/, he = 254;
|
|
83
|
+
function G(e) {
|
|
84
|
+
var t;
|
|
85
|
+
if (typeof e != "string" || !e)
|
|
84
86
|
return { valid: !1, error: "Email is required" };
|
|
85
|
-
const
|
|
86
|
-
return
|
|
87
|
+
const r = e.trim().toLowerCase();
|
|
88
|
+
return de.test(r) ? r.length > he ? { valid: !1, error: "Email is too long" } : r.includes("..") || r.startsWith(".") || r.endsWith(".") ? { valid: !1, error: "Invalid email format" } : (t = r.split("@")[1]) != null && t.includes("..") ? { valid: !1, error: "Invalid email format" } : { valid: !0, sanitized: r } : { valid: !1, error: "Invalid email format" };
|
|
87
89
|
}
|
|
88
|
-
function
|
|
89
|
-
|
|
90
|
+
function K(e) {
|
|
91
|
+
return e.valid === !0 && e.sanitized !== void 0;
|
|
92
|
+
}
|
|
93
|
+
const ge = /* @__PURE__ */ new Set([
|
|
94
|
+
"password",
|
|
95
|
+
"12345678",
|
|
96
|
+
"qwerty",
|
|
97
|
+
"abc123",
|
|
98
|
+
"password123",
|
|
99
|
+
"123456789",
|
|
100
|
+
"1234567890",
|
|
101
|
+
"letmein",
|
|
102
|
+
"welcome",
|
|
103
|
+
"monkey",
|
|
104
|
+
"dragon",
|
|
105
|
+
"master",
|
|
106
|
+
"sunshine",
|
|
107
|
+
"princess",
|
|
108
|
+
"football",
|
|
109
|
+
"admin",
|
|
110
|
+
"root",
|
|
111
|
+
"test",
|
|
112
|
+
"guest",
|
|
113
|
+
"user"
|
|
114
|
+
]), we = /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, pe = 8, me = 128;
|
|
115
|
+
function Ir(e, r = pe) {
|
|
116
|
+
if (typeof e != "string" || !e)
|
|
90
117
|
return { valid: !1, error: "Password is required" };
|
|
91
|
-
if (
|
|
92
|
-
return { valid: !1, error: `Password must be at least ${
|
|
93
|
-
if (
|
|
118
|
+
if (e.length < r)
|
|
119
|
+
return { valid: !1, error: `Password must be at least ${r} characters` };
|
|
120
|
+
if (e.length > me)
|
|
94
121
|
return { valid: !1, error: "Password is too long" };
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
"12345678",
|
|
98
|
-
"qwerty",
|
|
99
|
-
"abc123",
|
|
100
|
-
"password123",
|
|
101
|
-
"123456789",
|
|
102
|
-
"1234567890",
|
|
103
|
-
"letmein",
|
|
104
|
-
"welcome",
|
|
105
|
-
"monkey",
|
|
106
|
-
"dragon",
|
|
107
|
-
"master",
|
|
108
|
-
"sunshine",
|
|
109
|
-
"princess",
|
|
110
|
-
"football"
|
|
111
|
-
].includes(r.toLowerCase()))
|
|
122
|
+
const t = e.toLowerCase();
|
|
123
|
+
if (ge.has(t))
|
|
112
124
|
return { valid: !1, error: "Password is too common" };
|
|
113
|
-
if (/(.)\1{3,}/.test(
|
|
125
|
+
if (/(.)\1{3,}/.test(e))
|
|
114
126
|
return { valid: !1, error: "Password contains too many repeated characters" };
|
|
115
|
-
if (
|
|
127
|
+
if (we.test(e))
|
|
116
128
|
return { valid: !1, error: "Password contains sequential characters" };
|
|
117
|
-
|
|
118
|
-
return
|
|
129
|
+
const n = Ee(e);
|
|
130
|
+
return { valid: !0, sanitized: e, strength: n };
|
|
119
131
|
}
|
|
120
|
-
function
|
|
121
|
-
|
|
132
|
+
function Ee(e) {
|
|
133
|
+
let r = 0;
|
|
134
|
+
return e.length >= 12 ? r += 2 : e.length >= 8 && (r += 1), /[a-z]/.test(e) && (r += 1), /[A-Z]/.test(e) && (r += 1), /[0-9]/.test(e) && (r += 1), /[^a-zA-Z0-9]/.test(e) && (r += 1), r >= 5 ? "strong" : r >= 3 ? "medium" : "weak";
|
|
135
|
+
}
|
|
136
|
+
function _r(e) {
|
|
137
|
+
return e.valid === !0 && e.sanitized !== void 0;
|
|
138
|
+
}
|
|
139
|
+
const ye = 100;
|
|
140
|
+
function Pr(e) {
|
|
141
|
+
if (typeof e != "string" || !e)
|
|
122
142
|
return { valid: !1, error: "Name is required" };
|
|
123
|
-
const
|
|
124
|
-
|
|
143
|
+
const r = e.trim();
|
|
144
|
+
if (r.length < 1)
|
|
145
|
+
return { valid: !1, error: "Name cannot be empty" };
|
|
146
|
+
if (r.length > ye)
|
|
147
|
+
return { valid: !1, error: "Name is too long" };
|
|
148
|
+
const t = r.replace(/[<>"']/g, "");
|
|
149
|
+
return t.length === 0 ? { valid: !1, error: "Name contains only invalid characters" } : { valid: !0, sanitized: t };
|
|
125
150
|
}
|
|
126
|
-
function
|
|
127
|
-
|
|
151
|
+
function Cr(e) {
|
|
152
|
+
return e.valid === !0 && e.sanitized !== void 0;
|
|
153
|
+
}
|
|
154
|
+
const ke = /* @__PURE__ */ new Set(["http:", "https:"]);
|
|
155
|
+
function br(e) {
|
|
156
|
+
if (typeof e != "string" || !e)
|
|
128
157
|
return { valid: !1, error: "URL is required" };
|
|
129
158
|
try {
|
|
130
|
-
const
|
|
131
|
-
return
|
|
159
|
+
const r = new URL(e);
|
|
160
|
+
return ke.has(r.protocol) ? { valid: !0, sanitized: e } : { valid: !1, error: "URL must use http or https protocol" };
|
|
132
161
|
} catch {
|
|
133
162
|
return { valid: !1, error: "Invalid URL format" };
|
|
134
163
|
}
|
|
135
164
|
}
|
|
136
|
-
function
|
|
137
|
-
return
|
|
165
|
+
function Ur(e) {
|
|
166
|
+
return e.valid === !0 && e.sanitized !== void 0;
|
|
167
|
+
}
|
|
168
|
+
const ve = 16, Se = 512, Re = /^[A-Za-z0-9_-]+$/;
|
|
169
|
+
function Nr(e, r = ve) {
|
|
170
|
+
return typeof e != "string" || !e ? { valid: !1, error: "Token is required" } : e.length < r ? { valid: !1, error: "Token is too short" } : e.length > Se ? { valid: !1, error: "Token is too long" } : Re.test(e) ? /(.)\1{10,}/.test(e) ? { valid: !1, error: "Token contains suspicious pattern" } : { valid: !0, sanitized: e } : { valid: !1, error: "Invalid token format" };
|
|
138
171
|
}
|
|
139
|
-
function
|
|
140
|
-
|
|
141
|
-
|
|
172
|
+
function Fr(e) {
|
|
173
|
+
return e.valid === !0 && e.sanitized !== void 0;
|
|
174
|
+
}
|
|
175
|
+
const Ae = 1e3;
|
|
176
|
+
function X(e, r) {
|
|
177
|
+
const { maxLength: t = Ae, allowHtml: n = !1, required: s = !0 } = r ?? {};
|
|
178
|
+
if (s && (typeof e != "string" || !e || e.trim().length === 0))
|
|
142
179
|
return { valid: !1, error: "Input is required" };
|
|
143
|
-
if (
|
|
180
|
+
if (typeof e != "string" || !e)
|
|
144
181
|
return { valid: !0, sanitized: "" };
|
|
145
|
-
let
|
|
146
|
-
return
|
|
182
|
+
let i = e.trim();
|
|
183
|
+
return i.length > t ? { valid: !1, error: `Input must be less than ${t} characters` } : (n || (i = i.replace(/</g, "<").replace(/>/g, ">").replace(/"/g, """).replace(/'/g, "'").replace(/\//g, "/")), i = i.replace(/[\x00-\x1F\x7F]/g, ""), { valid: !0, sanitized: i });
|
|
184
|
+
}
|
|
185
|
+
function xr(e) {
|
|
186
|
+
return e.valid === !0 && e.sanitized !== void 0;
|
|
147
187
|
}
|
|
148
|
-
class
|
|
188
|
+
class Oe {
|
|
149
189
|
constructor() {
|
|
150
|
-
|
|
190
|
+
U(this, "tokens", /* @__PURE__ */ new Map());
|
|
151
191
|
}
|
|
152
|
-
get(
|
|
153
|
-
const
|
|
154
|
-
return
|
|
192
|
+
get(r) {
|
|
193
|
+
const t = this.tokens.get(r);
|
|
194
|
+
return t ? t.expiresAt < Date.now() ? (this.delete(r), null) : t.value : null;
|
|
155
195
|
}
|
|
156
|
-
set(
|
|
157
|
-
this.tokens.set(
|
|
158
|
-
value:
|
|
159
|
-
expiresAt: Date.now() +
|
|
196
|
+
set(r, t, n = 36e5) {
|
|
197
|
+
this.tokens.set(r, {
|
|
198
|
+
value: t,
|
|
199
|
+
expiresAt: Date.now() + n
|
|
160
200
|
});
|
|
161
201
|
}
|
|
162
|
-
delete(
|
|
163
|
-
this.tokens.delete(
|
|
202
|
+
delete(r) {
|
|
203
|
+
this.tokens.delete(r);
|
|
164
204
|
}
|
|
165
205
|
clear() {
|
|
166
206
|
this.tokens.clear();
|
|
167
207
|
}
|
|
168
208
|
}
|
|
169
|
-
class
|
|
170
|
-
constructor(
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
this.store =
|
|
209
|
+
class Te {
|
|
210
|
+
constructor(r, t = 32) {
|
|
211
|
+
U(this, "store");
|
|
212
|
+
U(this, "tokenLength");
|
|
213
|
+
this.store = r || new Oe(), this.tokenLength = t;
|
|
174
214
|
}
|
|
175
215
|
/**
|
|
176
216
|
* Generate CSRF token
|
|
177
217
|
*/
|
|
178
|
-
generateToken(
|
|
179
|
-
const
|
|
180
|
-
return this.store.set(
|
|
218
|
+
generateToken(r, t) {
|
|
219
|
+
const n = Y(this.tokenLength);
|
|
220
|
+
return this.store.set(r, n, t), n;
|
|
181
221
|
}
|
|
182
222
|
/**
|
|
183
223
|
* Validate CSRF token
|
|
184
224
|
*/
|
|
185
|
-
validateToken(
|
|
186
|
-
const
|
|
187
|
-
if (!
|
|
225
|
+
validateToken(r, t) {
|
|
226
|
+
const n = this.store.get(r);
|
|
227
|
+
if (!n)
|
|
188
228
|
return !1;
|
|
189
|
-
const
|
|
190
|
-
return
|
|
229
|
+
const s = Q(t, n);
|
|
230
|
+
return s && this.store.delete(r), s;
|
|
191
231
|
}
|
|
192
232
|
/**
|
|
193
233
|
* Get stored token without validating
|
|
194
234
|
*/
|
|
195
|
-
getToken(
|
|
196
|
-
return this.store.get(
|
|
235
|
+
getToken(r) {
|
|
236
|
+
return this.store.get(r);
|
|
197
237
|
}
|
|
198
238
|
/**
|
|
199
239
|
* Delete token
|
|
200
240
|
*/
|
|
201
|
-
deleteToken(
|
|
202
|
-
this.store.delete(
|
|
241
|
+
deleteToken(r) {
|
|
242
|
+
this.store.delete(r);
|
|
203
243
|
}
|
|
204
244
|
}
|
|
205
|
-
function
|
|
206
|
-
return new
|
|
245
|
+
function Dr(e) {
|
|
246
|
+
return new Te(e);
|
|
207
247
|
}
|
|
208
|
-
function
|
|
209
|
-
if (typeof
|
|
248
|
+
function Ie(e) {
|
|
249
|
+
if (typeof e != "string")
|
|
210
250
|
return "";
|
|
211
|
-
const
|
|
251
|
+
const r = {
|
|
212
252
|
"&": "&",
|
|
213
253
|
"<": "<",
|
|
214
254
|
">": ">",
|
|
215
255
|
'"': """,
|
|
216
256
|
"'": "'"
|
|
217
257
|
};
|
|
218
|
-
return
|
|
258
|
+
return e.replace(/[&<>"']/g, (t) => r[t] || t);
|
|
219
259
|
}
|
|
220
|
-
function
|
|
221
|
-
return typeof
|
|
260
|
+
function Lr(e) {
|
|
261
|
+
return typeof e != "string" ? "" : e.replace(/<script\b[^<]*(?:(?!<\/script>)<[^<]*)*<\/script>/gi, "").replace(/on\w+\s*=\s*["'][^"']*["']/gi, "").replace(/javascript:/gi, "");
|
|
222
262
|
}
|
|
223
|
-
function
|
|
224
|
-
return typeof
|
|
263
|
+
function Mr(e) {
|
|
264
|
+
return typeof e != "string" ? "" : Ie(e.trim());
|
|
225
265
|
}
|
|
226
|
-
function
|
|
227
|
-
return typeof
|
|
266
|
+
function Vr(e) {
|
|
267
|
+
return typeof e != "string" ? !1 : [
|
|
228
268
|
/<script/i,
|
|
229
269
|
/javascript:/i,
|
|
230
270
|
/on\w+\s*=/i,
|
|
@@ -235,88 +275,95 @@ function Pe(r) {
|
|
|
235
275
|
/<meta/i,
|
|
236
276
|
/expression\s*\(/i,
|
|
237
277
|
/vbscript:/i
|
|
238
|
-
].some((
|
|
278
|
+
].some((t) => t.test(e));
|
|
239
279
|
}
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
280
|
+
const J = 32;
|
|
281
|
+
function Y(e = J) {
|
|
282
|
+
if (e < 1 || e > 256)
|
|
283
|
+
throw new Error("Token length must be between 1 and 256 bytes");
|
|
284
|
+
const r = ue(e);
|
|
285
|
+
return Buffer.from(r).toString("base64url");
|
|
243
286
|
}
|
|
244
|
-
function
|
|
245
|
-
return
|
|
287
|
+
function _e() {
|
|
288
|
+
return Y(J);
|
|
246
289
|
}
|
|
247
|
-
function
|
|
248
|
-
if (
|
|
290
|
+
function Q(e, r) {
|
|
291
|
+
if (typeof e != "string" || typeof r != "string" || !e || !r || e.length !== r.length)
|
|
249
292
|
return !1;
|
|
250
|
-
let
|
|
251
|
-
for (let
|
|
252
|
-
|
|
253
|
-
return
|
|
293
|
+
let t = 0;
|
|
294
|
+
for (let n = 0; n < e.length; n++)
|
|
295
|
+
t |= e.charCodeAt(n) ^ r.charCodeAt(n);
|
|
296
|
+
return t === 0;
|
|
254
297
|
}
|
|
255
|
-
function
|
|
256
|
-
return
|
|
298
|
+
function jr(e, r) {
|
|
299
|
+
return Q(e, r);
|
|
257
300
|
}
|
|
258
|
-
function
|
|
259
|
-
return
|
|
301
|
+
function zr(e) {
|
|
302
|
+
return typeof e != "string" ? "" : e.trim().replace(/[<>]/g, "");
|
|
260
303
|
}
|
|
261
|
-
|
|
262
|
-
|
|
304
|
+
const Pe = /^[^\s@]+@[^\s@]+\.[^\s@]+$/;
|
|
305
|
+
function $r(e) {
|
|
306
|
+
return typeof e == "string" && Pe.test(e);
|
|
263
307
|
}
|
|
264
|
-
function
|
|
265
|
-
return
|
|
308
|
+
function Ce(e) {
|
|
309
|
+
return !e.success && !!e.error;
|
|
266
310
|
}
|
|
267
|
-
function
|
|
268
|
-
return
|
|
311
|
+
function Wr(e) {
|
|
312
|
+
return e.requires2FA === !0 || e.errorCode === m.TWO_FA_REQUIRED;
|
|
269
313
|
}
|
|
270
|
-
function
|
|
271
|
-
return r
|
|
314
|
+
function qr(e, r) {
|
|
315
|
+
return e.error ? e.error : r || "Authentication failed";
|
|
272
316
|
}
|
|
273
|
-
function
|
|
274
|
-
return
|
|
317
|
+
function Br(e) {
|
|
318
|
+
return e.errorCode;
|
|
275
319
|
}
|
|
276
|
-
function
|
|
277
|
-
return
|
|
320
|
+
function Hr(e) {
|
|
321
|
+
return e.success === !0 && !!e.user;
|
|
278
322
|
}
|
|
279
|
-
function
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
|
|
323
|
+
function Gr(e, r) {
|
|
324
|
+
return e.errorCode === r;
|
|
325
|
+
}
|
|
326
|
+
function Kr(e) {
|
|
327
|
+
if (!Ce(e)) return !1;
|
|
328
|
+
const r = [
|
|
329
|
+
m.NETWORK_ERROR,
|
|
330
|
+
m.RATE_LIMITED,
|
|
331
|
+
m.UNKNOWN_ERROR
|
|
285
332
|
];
|
|
286
|
-
return
|
|
333
|
+
return e.errorCode ? r.includes(e.errorCode) : !1;
|
|
287
334
|
}
|
|
288
|
-
function
|
|
289
|
-
if (
|
|
290
|
-
switch (
|
|
291
|
-
case
|
|
335
|
+
function Xr(e) {
|
|
336
|
+
if (e.error) return e.error;
|
|
337
|
+
switch (e.errorCode) {
|
|
338
|
+
case m.INVALID_CREDENTIALS:
|
|
292
339
|
return "Invalid email or password. Please try again.";
|
|
293
|
-
case
|
|
340
|
+
case m.ACCOUNT_LOCKED:
|
|
294
341
|
return "Your account has been temporarily locked. Please try again later.";
|
|
295
|
-
case
|
|
342
|
+
case m.ACCOUNT_INACTIVE:
|
|
296
343
|
return "Your account is inactive. Please contact support.";
|
|
297
|
-
case
|
|
344
|
+
case m.TWO_FA_REQUIRED:
|
|
298
345
|
return "Two-factor authentication is required. Please enter your code.";
|
|
299
|
-
case
|
|
346
|
+
case m.INVALID_TWO_FA_CODE:
|
|
300
347
|
return "Invalid two-factor authentication code. Please try again.";
|
|
301
|
-
case
|
|
348
|
+
case m.SESSION_EXPIRED:
|
|
302
349
|
return "Your session has expired. Please sign in again.";
|
|
303
|
-
case
|
|
350
|
+
case m.UNAUTHORIZED:
|
|
304
351
|
return "You are not authorized to perform this action.";
|
|
305
|
-
case
|
|
352
|
+
case m.NETWORK_ERROR:
|
|
306
353
|
return "Network error. Please check your connection and try again.";
|
|
307
|
-
case
|
|
354
|
+
case m.VALIDATION_ERROR:
|
|
308
355
|
return "Please check your input and try again.";
|
|
309
|
-
case
|
|
356
|
+
case m.RATE_LIMITED:
|
|
310
357
|
return "Too many attempts. Please try again later.";
|
|
311
|
-
case
|
|
358
|
+
case m.UNKNOWN_ERROR:
|
|
312
359
|
default:
|
|
313
360
|
return "An unexpected error occurred. Please try again.";
|
|
314
361
|
}
|
|
315
362
|
}
|
|
316
|
-
async function
|
|
317
|
-
return
|
|
363
|
+
async function Jr(e, r, t) {
|
|
364
|
+
return e.signIn(r, t);
|
|
318
365
|
}
|
|
319
|
-
const
|
|
366
|
+
const Z = {
|
|
320
367
|
google: {
|
|
321
368
|
authorizationUrl: "https://accounts.google.com/o/oauth2/v2/auth",
|
|
322
369
|
tokenUrl: "https://oauth2.googleapis.com/token",
|
|
@@ -346,254 +393,424 @@ const ae = {
|
|
|
346
393
|
defaultScopes: ["email", "public_profile"]
|
|
347
394
|
}
|
|
348
395
|
};
|
|
349
|
-
function
|
|
350
|
-
return
|
|
351
|
-
}
|
|
352
|
-
function
|
|
353
|
-
|
|
354
|
-
|
|
355
|
-
|
|
356
|
-
const
|
|
357
|
-
|
|
358
|
-
|
|
396
|
+
function j(e) {
|
|
397
|
+
return Z[e] ?? null;
|
|
398
|
+
}
|
|
399
|
+
function Yr(e) {
|
|
400
|
+
return e in Z;
|
|
401
|
+
}
|
|
402
|
+
function be(e, r, t, n) {
|
|
403
|
+
const s = j(e);
|
|
404
|
+
if (!s)
|
|
405
|
+
throw new Error(`Unknown OAuth provider: ${e}`);
|
|
406
|
+
if (!r.clientId)
|
|
407
|
+
throw new Error(`OAuth provider "${e}" is missing clientId`);
|
|
408
|
+
const i = r.redirectUri ?? `${t}/api/auth/callback/${e}`, o = r.scopes ?? s.defaultScopes, a = new URLSearchParams({
|
|
409
|
+
client_id: r.clientId,
|
|
410
|
+
redirect_uri: i,
|
|
359
411
|
response_type: "code",
|
|
360
|
-
scope:
|
|
361
|
-
state:
|
|
362
|
-
...o.defaultParams,
|
|
363
|
-
...e.params
|
|
412
|
+
scope: Array.isArray(o) ? o.join(" ") : String(o),
|
|
413
|
+
state: n
|
|
364
414
|
});
|
|
365
|
-
|
|
366
|
-
|
|
367
|
-
|
|
368
|
-
|
|
369
|
-
|
|
370
|
-
|
|
371
|
-
|
|
372
|
-
|
|
373
|
-
|
|
374
|
-
|
|
415
|
+
if (s.defaultParams)
|
|
416
|
+
for (const [l, f] of Object.entries(s.defaultParams))
|
|
417
|
+
a.append(l, f);
|
|
418
|
+
if (r.params)
|
|
419
|
+
for (const [l, f] of Object.entries(r.params))
|
|
420
|
+
a.set(l, f);
|
|
421
|
+
return `${s.authorizationUrl}?${a.toString()}`;
|
|
422
|
+
}
|
|
423
|
+
async function Ue(e, r, t, n) {
|
|
424
|
+
const s = j(e);
|
|
425
|
+
if (!s)
|
|
426
|
+
throw new Error(`Unknown OAuth provider: ${e}`);
|
|
427
|
+
if (!t || typeof t != "string")
|
|
428
|
+
throw new Error("Authorization code is required");
|
|
429
|
+
if (!r.clientId)
|
|
430
|
+
throw new Error(`OAuth provider "${e}" is missing clientId`);
|
|
431
|
+
const i = new URLSearchParams({
|
|
432
|
+
client_id: r.clientId,
|
|
433
|
+
code: t,
|
|
434
|
+
redirect_uri: n,
|
|
375
435
|
grant_type: "authorization_code"
|
|
376
436
|
});
|
|
377
|
-
|
|
378
|
-
|
|
379
|
-
|
|
380
|
-
|
|
381
|
-
|
|
382
|
-
|
|
383
|
-
|
|
384
|
-
|
|
385
|
-
|
|
386
|
-
|
|
387
|
-
|
|
388
|
-
|
|
437
|
+
r.clientSecret && i.append("client_secret", r.clientSecret);
|
|
438
|
+
try {
|
|
439
|
+
const o = await fetch(s.tokenUrl, {
|
|
440
|
+
method: "POST",
|
|
441
|
+
headers: {
|
|
442
|
+
"Content-Type": "application/x-www-form-urlencoded",
|
|
443
|
+
Accept: "application/json"
|
|
444
|
+
},
|
|
445
|
+
body: i.toString()
|
|
446
|
+
});
|
|
447
|
+
if (!o.ok) {
|
|
448
|
+
const l = await o.text();
|
|
449
|
+
let f = `Failed to exchange code for tokens: ${l}`;
|
|
450
|
+
try {
|
|
451
|
+
const w = JSON.parse(l);
|
|
452
|
+
f = w.error_description ?? w.error ?? f;
|
|
453
|
+
} catch {
|
|
454
|
+
}
|
|
455
|
+
throw new Error(f);
|
|
456
|
+
}
|
|
457
|
+
const a = await o.json();
|
|
458
|
+
if (!Ne(a))
|
|
459
|
+
throw new Error("Invalid token exchange response format");
|
|
460
|
+
return a;
|
|
461
|
+
} catch (o) {
|
|
462
|
+
throw o instanceof Error ? o : new Error(`OAuth token exchange failed: ${String(o)}`);
|
|
389
463
|
}
|
|
390
|
-
return await c.json();
|
|
391
464
|
}
|
|
392
|
-
|
|
393
|
-
|
|
394
|
-
|
|
395
|
-
|
|
396
|
-
|
|
397
|
-
|
|
398
|
-
|
|
399
|
-
|
|
400
|
-
|
|
465
|
+
function Ne(e) {
|
|
466
|
+
return typeof e == "object" && e !== null && "access_token" in e && typeof e.access_token == "string";
|
|
467
|
+
}
|
|
468
|
+
async function Fe(e, r) {
|
|
469
|
+
const t = j(e);
|
|
470
|
+
if (!t)
|
|
471
|
+
throw new Error(`Unknown OAuth provider: ${e}`);
|
|
472
|
+
if (!r || typeof r != "string")
|
|
473
|
+
throw new Error("Access token is required");
|
|
474
|
+
try {
|
|
475
|
+
const n = await fetch(t.userInfoUrl, {
|
|
476
|
+
headers: {
|
|
477
|
+
Authorization: `Bearer ${r}`,
|
|
478
|
+
Accept: "application/json"
|
|
479
|
+
}
|
|
480
|
+
});
|
|
481
|
+
if (!n.ok) {
|
|
482
|
+
const i = await n.text();
|
|
483
|
+
let o = `Failed to fetch user info: ${i}`;
|
|
484
|
+
try {
|
|
485
|
+
const a = JSON.parse(i);
|
|
486
|
+
o = a.error_description ?? a.error ?? o;
|
|
487
|
+
} catch {
|
|
488
|
+
}
|
|
489
|
+
throw new Error(o);
|
|
401
490
|
}
|
|
402
|
-
|
|
403
|
-
|
|
404
|
-
|
|
405
|
-
throw new Error(`
|
|
491
|
+
const s = await n.json();
|
|
492
|
+
return xe(e, s, r);
|
|
493
|
+
} catch (n) {
|
|
494
|
+
throw n instanceof Error ? n : new Error(`OAuth user info retrieval failed: ${String(n)}`);
|
|
406
495
|
}
|
|
407
|
-
|
|
408
|
-
|
|
496
|
+
}
|
|
497
|
+
async function xe(e, r, t) {
|
|
498
|
+
switch (e) {
|
|
409
499
|
case "google":
|
|
410
|
-
return
|
|
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
|
|
417
|
-
};
|
|
500
|
+
return De(r);
|
|
418
501
|
case "github":
|
|
419
|
-
|
|
420
|
-
if (!k) {
|
|
421
|
-
const A = await (await fetch("https://api.github.com/user/emails", {
|
|
422
|
-
headers: { Authorization: `Bearer ${e}` }
|
|
423
|
-
})).json();
|
|
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 };
|
|
425
|
-
}
|
|
426
|
-
return {
|
|
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
|
|
433
|
-
};
|
|
502
|
+
return await Le(r, t);
|
|
434
503
|
case "apple":
|
|
435
|
-
return
|
|
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
|
|
441
|
-
};
|
|
504
|
+
return Me(r);
|
|
442
505
|
case "facebook":
|
|
443
|
-
return
|
|
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
|
|
450
|
-
};
|
|
506
|
+
return Ve(r);
|
|
451
507
|
default:
|
|
452
|
-
return
|
|
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
|
|
459
|
-
};
|
|
508
|
+
return je(r);
|
|
460
509
|
}
|
|
461
510
|
}
|
|
462
|
-
|
|
511
|
+
function De(e) {
|
|
512
|
+
return {
|
|
513
|
+
id: String(e.sub ?? e.id ?? ""),
|
|
514
|
+
email: String(e.email ?? ""),
|
|
515
|
+
name: String(e.name ?? ""),
|
|
516
|
+
avatar: typeof e.picture == "string" ? e.picture : void 0,
|
|
517
|
+
emailVerified: !!e.email_verified,
|
|
518
|
+
rawProfile: e
|
|
519
|
+
};
|
|
520
|
+
}
|
|
521
|
+
async function Le(e, r) {
|
|
522
|
+
let t = typeof e.email == "string" ? e.email : void 0, n = { ...e };
|
|
523
|
+
if (!t)
|
|
524
|
+
try {
|
|
525
|
+
const s = await fetch("https://api.github.com/user/emails", {
|
|
526
|
+
headers: { Authorization: `Bearer ${r}` }
|
|
527
|
+
});
|
|
528
|
+
if (s.ok) {
|
|
529
|
+
const i = await s.json(), o = i.find((a) => a.primary) ?? i[0];
|
|
530
|
+
t = (o == null ? void 0 : o.email) ?? `${String(e.login ?? "user")}@users.noreply.github.com`, n = { ...e, emails: i };
|
|
531
|
+
} else
|
|
532
|
+
t = `${String(e.login ?? "user")}@users.noreply.github.com`;
|
|
533
|
+
} catch {
|
|
534
|
+
t = `${String(e.login ?? "user")}@users.noreply.github.com`;
|
|
535
|
+
}
|
|
536
|
+
return {
|
|
537
|
+
id: String(e.id ?? ""),
|
|
538
|
+
email: t ?? "",
|
|
539
|
+
name: String(e.name ?? e.login ?? ""),
|
|
540
|
+
avatar: typeof e.avatar_url == "string" ? e.avatar_url : void 0,
|
|
541
|
+
emailVerified: !!t,
|
|
542
|
+
rawProfile: n
|
|
543
|
+
};
|
|
544
|
+
}
|
|
545
|
+
function Me(e) {
|
|
546
|
+
const r = e.name, t = r ? `${r.firstName ?? ""} ${r.lastName ?? ""}`.trim() : "";
|
|
547
|
+
return {
|
|
548
|
+
id: String(e.sub ?? ""),
|
|
549
|
+
email: String(e.email ?? ""),
|
|
550
|
+
name: t,
|
|
551
|
+
emailVerified: !!e.email_verified,
|
|
552
|
+
rawProfile: e
|
|
553
|
+
};
|
|
554
|
+
}
|
|
555
|
+
function Ve(e) {
|
|
556
|
+
var t;
|
|
557
|
+
const r = e.picture;
|
|
558
|
+
return {
|
|
559
|
+
id: String(e.id ?? ""),
|
|
560
|
+
email: String(e.email ?? ""),
|
|
561
|
+
name: String(e.name ?? ""),
|
|
562
|
+
avatar: (t = r == null ? void 0 : r.data) == null ? void 0 : t.url,
|
|
563
|
+
emailVerified: !0,
|
|
564
|
+
rawProfile: e
|
|
565
|
+
};
|
|
566
|
+
}
|
|
567
|
+
function je(e) {
|
|
568
|
+
return {
|
|
569
|
+
id: String(e.id ?? e.sub ?? ""),
|
|
570
|
+
email: String(e.email ?? ""),
|
|
571
|
+
name: String(e.name ?? e.display_name ?? e.username ?? ""),
|
|
572
|
+
avatar: typeof e.avatar == "string" ? e.avatar : typeof e.picture == "string" ? e.picture : typeof e.avatar_url == "string" ? e.avatar_url : void 0,
|
|
573
|
+
emailVerified: !!(e.email_verified ?? e.emailVerified ?? !1),
|
|
574
|
+
rawProfile: e
|
|
575
|
+
};
|
|
576
|
+
}
|
|
577
|
+
function Qr(e) {
|
|
578
|
+
return typeof e == "object" && e !== null && "clientId" in e && typeof e.clientId == "string";
|
|
579
|
+
}
|
|
580
|
+
class ze {
|
|
463
581
|
constructor() {
|
|
464
|
-
|
|
582
|
+
U(this, "states", /* @__PURE__ */ new Map());
|
|
465
583
|
}
|
|
466
|
-
set(
|
|
467
|
-
this.states.set(
|
|
584
|
+
set(r, t, n) {
|
|
585
|
+
this.states.set(r, t), this.cleanup();
|
|
468
586
|
}
|
|
469
|
-
get(
|
|
470
|
-
const
|
|
471
|
-
return
|
|
587
|
+
get(r) {
|
|
588
|
+
const t = this.states.get(r);
|
|
589
|
+
return t ? t.expiresAt < Date.now() ? (this.delete(r), null) : t : null;
|
|
472
590
|
}
|
|
473
|
-
delete(
|
|
474
|
-
this.states.delete(
|
|
591
|
+
delete(r) {
|
|
592
|
+
this.states.delete(r);
|
|
475
593
|
}
|
|
476
594
|
cleanup() {
|
|
477
|
-
const
|
|
478
|
-
for (const [
|
|
479
|
-
|
|
595
|
+
const r = Date.now();
|
|
596
|
+
for (const [t, n] of this.states.entries())
|
|
597
|
+
n.expiresAt < r && this.states.delete(t);
|
|
480
598
|
}
|
|
481
599
|
}
|
|
482
|
-
function
|
|
483
|
-
return new
|
|
600
|
+
function $e() {
|
|
601
|
+
return new ze();
|
|
602
|
+
}
|
|
603
|
+
function Zr(e, r = "mulguard:oauth:state:") {
|
|
604
|
+
const t = (s) => `${r}${s}`, n = async (s) => {
|
|
605
|
+
const i = t(s);
|
|
606
|
+
await e.del(i);
|
|
607
|
+
};
|
|
608
|
+
return {
|
|
609
|
+
async set(s, i, o) {
|
|
610
|
+
const a = t(s), l = JSON.stringify(i);
|
|
611
|
+
await e.set(a, l, "EX", Math.floor(o / 1e3));
|
|
612
|
+
},
|
|
613
|
+
async get(s) {
|
|
614
|
+
const i = t(s), o = await e.get(i);
|
|
615
|
+
if (!o)
|
|
616
|
+
return null;
|
|
617
|
+
try {
|
|
618
|
+
const a = JSON.parse(o);
|
|
619
|
+
return a.expiresAt < Date.now() ? (await n(s), null) : a;
|
|
620
|
+
} catch {
|
|
621
|
+
return await n(s), null;
|
|
622
|
+
}
|
|
623
|
+
},
|
|
624
|
+
async delete(s) {
|
|
625
|
+
await n(s);
|
|
626
|
+
},
|
|
627
|
+
async cleanup() {
|
|
628
|
+
try {
|
|
629
|
+
const s = await e.keys(`${r}*`), i = Date.now();
|
|
630
|
+
for (const o of s) {
|
|
631
|
+
const a = await e.get(o);
|
|
632
|
+
if (a)
|
|
633
|
+
try {
|
|
634
|
+
JSON.parse(a).expiresAt < i && await e.del(o);
|
|
635
|
+
} catch {
|
|
636
|
+
await e.del(o);
|
|
637
|
+
}
|
|
638
|
+
}
|
|
639
|
+
} catch (s) {
|
|
640
|
+
console.warn("[Mulguard] OAuth state cleanup warning:", s);
|
|
641
|
+
}
|
|
642
|
+
}
|
|
643
|
+
};
|
|
644
|
+
}
|
|
645
|
+
function D(e) {
|
|
646
|
+
return e.success === !0 && e.user !== void 0 && e.session !== void 0;
|
|
484
647
|
}
|
|
485
|
-
|
|
486
|
-
|
|
648
|
+
var ee = /* @__PURE__ */ ((e) => (e[e.DEBUG = 0] = "DEBUG", e[e.INFO = 1] = "INFO", e[e.WARN = 2] = "WARN", e[e.ERROR = 3] = "ERROR", e))(ee || {});
|
|
649
|
+
const We = process.env.NODE_ENV === "development" ? 0 : 1;
|
|
650
|
+
function qe(e = {}) {
|
|
651
|
+
const {
|
|
652
|
+
enabled: r = process.env.NODE_ENV === "development",
|
|
653
|
+
level: t = We,
|
|
654
|
+
context: n,
|
|
655
|
+
formatter: s = Be
|
|
656
|
+
} = e, i = (a) => r && a >= t, o = (a, l, f, w) => ({
|
|
657
|
+
level: a,
|
|
658
|
+
message: l,
|
|
659
|
+
timestamp: /* @__PURE__ */ new Date(),
|
|
660
|
+
context: n,
|
|
661
|
+
data: f ? He(f) : void 0,
|
|
662
|
+
error: w
|
|
663
|
+
});
|
|
487
664
|
return {
|
|
488
|
-
debug:
|
|
489
|
-
|
|
490
|
-
|
|
665
|
+
debug: (a, l) => {
|
|
666
|
+
if (i(
|
|
667
|
+
0
|
|
668
|
+
/* DEBUG */
|
|
669
|
+
)) {
|
|
670
|
+
const f = o(0, a, l);
|
|
671
|
+
console.debug(s(f));
|
|
672
|
+
}
|
|
491
673
|
},
|
|
492
|
-
info:
|
|
493
|
-
|
|
494
|
-
|
|
674
|
+
info: (a, l) => {
|
|
675
|
+
if (i(
|
|
676
|
+
1
|
|
677
|
+
/* INFO */
|
|
678
|
+
)) {
|
|
679
|
+
const f = o(1, a, l);
|
|
680
|
+
console.info(s(f));
|
|
681
|
+
}
|
|
495
682
|
},
|
|
496
|
-
warn:
|
|
497
|
-
|
|
498
|
-
|
|
683
|
+
warn: (a, l) => {
|
|
684
|
+
if (i(
|
|
685
|
+
2
|
|
686
|
+
/* WARN */
|
|
687
|
+
)) {
|
|
688
|
+
const f = o(2, a, l);
|
|
689
|
+
console.warn(s(f));
|
|
690
|
+
}
|
|
499
691
|
},
|
|
500
|
-
error:
|
|
501
|
-
|
|
502
|
-
|
|
692
|
+
error: (a, l) => {
|
|
693
|
+
if (i(
|
|
694
|
+
3
|
|
695
|
+
/* ERROR */
|
|
696
|
+
)) {
|
|
697
|
+
const f = l instanceof Error ? l : void 0, w = l instanceof Error ? void 0 : l, g = o(3, a, w, f);
|
|
698
|
+
console.error(s(g)), f && console.error(f);
|
|
699
|
+
}
|
|
503
700
|
}
|
|
504
701
|
};
|
|
505
702
|
}
|
|
506
|
-
|
|
507
|
-
|
|
703
|
+
function Be(e) {
|
|
704
|
+
const r = e.timestamp.toISOString(), t = ee[e.level], n = e.context ? `[${e.context}]` : "", s = e.data ? ` ${JSON.stringify(e.data)}` : "";
|
|
705
|
+
return `${r} [${t}]${n} ${e.message}${s}`;
|
|
706
|
+
}
|
|
707
|
+
function He(e) {
|
|
708
|
+
const r = /* @__PURE__ */ new Set(["password", "token", "secret", "key", "accessToken", "refreshToken"]), t = {};
|
|
709
|
+
for (const [n, s] of Object.entries(e))
|
|
710
|
+
if (r.has(n.toLowerCase()))
|
|
711
|
+
t[n] = "***REDACTED***";
|
|
712
|
+
else if (typeof s == "string" && n.toLowerCase().includes("email")) {
|
|
713
|
+
const i = s.split("@");
|
|
714
|
+
if (i.length === 2 && i[0]) {
|
|
715
|
+
const o = i[0].substring(0, 3) + "***@" + i[1];
|
|
716
|
+
t[n] = o;
|
|
717
|
+
} else
|
|
718
|
+
t[n] = s;
|
|
719
|
+
} else
|
|
720
|
+
t[n] = s;
|
|
721
|
+
return t;
|
|
722
|
+
}
|
|
723
|
+
const I = qe();
|
|
724
|
+
function Ge(e, r, t, n = {}) {
|
|
508
725
|
const {
|
|
509
|
-
enabled:
|
|
510
|
-
maxRetries:
|
|
511
|
-
retryDelay:
|
|
726
|
+
enabled: s = !0,
|
|
727
|
+
maxRetries: i = 1,
|
|
728
|
+
retryDelay: o = 1e3,
|
|
512
729
|
rateLimit: a = 3,
|
|
513
|
-
autoSignOutOnFailure:
|
|
514
|
-
redirectToLogin:
|
|
515
|
-
autoRedirectOnFailure:
|
|
516
|
-
} =
|
|
730
|
+
autoSignOutOnFailure: l = !0,
|
|
731
|
+
redirectToLogin: f = "/login",
|
|
732
|
+
autoRedirectOnFailure: w = !0
|
|
733
|
+
} = n;
|
|
517
734
|
let g = null, A = !1;
|
|
518
|
-
const
|
|
519
|
-
let
|
|
520
|
-
const
|
|
521
|
-
function
|
|
522
|
-
const
|
|
523
|
-
if (
|
|
524
|
-
if (
|
|
735
|
+
const S = [], v = [], y = 60 * 1e3;
|
|
736
|
+
let h = 0, T = !1, _ = null;
|
|
737
|
+
const L = 2, M = 60 * 1e3;
|
|
738
|
+
function c() {
|
|
739
|
+
const k = Date.now();
|
|
740
|
+
if (T && _) {
|
|
741
|
+
if (k < _)
|
|
525
742
|
return !1;
|
|
526
|
-
|
|
743
|
+
T = !1, _ = null, h = 0;
|
|
527
744
|
}
|
|
528
|
-
for (;
|
|
529
|
-
const
|
|
530
|
-
if (
|
|
531
|
-
|
|
745
|
+
for (; v.length > 0; ) {
|
|
746
|
+
const p = v[0];
|
|
747
|
+
if (p !== void 0 && p < k - y)
|
|
748
|
+
v.shift();
|
|
532
749
|
else
|
|
533
750
|
break;
|
|
534
751
|
}
|
|
535
|
-
return
|
|
536
|
-
}
|
|
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"));
|
|
752
|
+
return v.length >= a ? !1 : (v.push(k), !0);
|
|
539
753
|
}
|
|
540
754
|
function u() {
|
|
541
|
-
T = 0,
|
|
755
|
+
h++, h >= L && (T = !0, _ = Date.now() + M, process.env.NODE_ENV === "development" && console.warn("[TokenRefreshManager] Circuit breaker opened - too many consecutive failures"));
|
|
542
756
|
}
|
|
543
|
-
|
|
544
|
-
|
|
757
|
+
function d() {
|
|
758
|
+
h = 0, T = !1, _ = null;
|
|
759
|
+
}
|
|
760
|
+
async function R(k = 1) {
|
|
761
|
+
if (!s)
|
|
545
762
|
return null;
|
|
546
|
-
if (!
|
|
763
|
+
if (!c())
|
|
547
764
|
throw new Error("Rate limit exceeded for token refresh");
|
|
548
765
|
try {
|
|
549
|
-
const
|
|
550
|
-
if (
|
|
551
|
-
return
|
|
552
|
-
if (
|
|
553
|
-
return await
|
|
766
|
+
const p = await e();
|
|
767
|
+
if (p)
|
|
768
|
+
return d(), P(p), n.onTokenRefreshed && await Promise.resolve(n.onTokenRefreshed(p)), p;
|
|
769
|
+
if (u(), k < i)
|
|
770
|
+
return await $(o * k), R(k + 1);
|
|
554
771
|
throw new Error("Token refresh failed: refresh function returned null");
|
|
555
|
-
} catch (
|
|
556
|
-
if (
|
|
557
|
-
return await
|
|
558
|
-
throw
|
|
772
|
+
} catch (p) {
|
|
773
|
+
if (u(), k < i && C(p))
|
|
774
|
+
return await $(o * k), R(k + 1);
|
|
775
|
+
throw p;
|
|
559
776
|
}
|
|
560
777
|
}
|
|
561
|
-
function
|
|
562
|
-
if (
|
|
563
|
-
const
|
|
564
|
-
if (
|
|
778
|
+
function C(k) {
|
|
779
|
+
if (k instanceof Error) {
|
|
780
|
+
const p = k.message.toLowerCase();
|
|
781
|
+
if (p.includes("rate limit") || p.includes("too many requests") || p.includes("429") || p.includes("limit:") || p.includes("requests per minute") || p.includes("token_blacklisted") || p.includes("blacklisted") || p.includes("invalid") || p.includes("401") || p.includes("unauthorized") || p.includes("session has been revoked") || p.includes("session expired"))
|
|
565
782
|
return !1;
|
|
566
|
-
if (
|
|
783
|
+
if (p.includes("network") || p.includes("fetch") || p.includes("timeout"))
|
|
567
784
|
return !0;
|
|
568
785
|
}
|
|
569
786
|
return !1;
|
|
570
787
|
}
|
|
571
|
-
function
|
|
572
|
-
const
|
|
573
|
-
|
|
574
|
-
for (const { resolve:
|
|
575
|
-
|
|
788
|
+
function P(k) {
|
|
789
|
+
const p = [...S];
|
|
790
|
+
S.length = 0;
|
|
791
|
+
for (const { resolve: b } of p)
|
|
792
|
+
b(k);
|
|
576
793
|
}
|
|
577
|
-
function
|
|
578
|
-
const
|
|
579
|
-
|
|
580
|
-
for (const { reject:
|
|
581
|
-
|
|
794
|
+
function z(k) {
|
|
795
|
+
const p = [...S];
|
|
796
|
+
S.length = 0;
|
|
797
|
+
for (const { reject: b } of p)
|
|
798
|
+
b(k);
|
|
582
799
|
}
|
|
583
|
-
function
|
|
584
|
-
return new Promise((
|
|
800
|
+
function $(k) {
|
|
801
|
+
return new Promise((p) => setTimeout(p, k));
|
|
585
802
|
}
|
|
586
|
-
async function
|
|
803
|
+
async function W(k) {
|
|
587
804
|
try {
|
|
588
|
-
if (
|
|
589
|
-
let
|
|
590
|
-
if (
|
|
591
|
-
const
|
|
592
|
-
|
|
805
|
+
if (n.onTokenRefreshFailed && await Promise.resolve(n.onTokenRefreshFailed(k)), l && (await t(), await r(), w && typeof window < "u")) {
|
|
806
|
+
let p = !0;
|
|
807
|
+
if (n.onBeforeRedirect && (p = await Promise.resolve(n.onBeforeRedirect(k))), p) {
|
|
808
|
+
const b = new URL(f, window.location.origin);
|
|
809
|
+
b.searchParams.set("reason", "session_expired"), b.searchParams.set("redirect", window.location.pathname + window.location.search), window.location.href = b.toString();
|
|
593
810
|
}
|
|
594
811
|
}
|
|
595
|
-
} catch (
|
|
596
|
-
process.env.NODE_ENV === "development" && console.error("[TokenRefreshManager] Error in handleRefreshFailure:",
|
|
812
|
+
} catch (p) {
|
|
813
|
+
process.env.NODE_ENV === "development" && console.error("[TokenRefreshManager] Error in handleRefreshFailure:", p);
|
|
597
814
|
}
|
|
598
815
|
}
|
|
599
816
|
return {
|
|
@@ -601,9 +818,9 @@ function he(r, e, s, t = {}) {
|
|
|
601
818
|
* Refresh token with single refresh queue
|
|
602
819
|
*/
|
|
603
820
|
async refreshToken() {
|
|
604
|
-
return
|
|
605
|
-
throw A = !1, g = null,
|
|
606
|
-
}),
|
|
821
|
+
return s ? g || (A = !0, g = R().then((k) => (A = !1, g = null, k)).catch((k) => {
|
|
822
|
+
throw A = !1, g = null, z(k), W(k).catch(() => {
|
|
823
|
+
}), k;
|
|
607
824
|
}), g) : null;
|
|
608
825
|
},
|
|
609
826
|
/**
|
|
@@ -616,38 +833,38 @@ function he(r, e, s, t = {}) {
|
|
|
616
833
|
* Wait for current refresh to complete
|
|
617
834
|
*/
|
|
618
835
|
async waitForRefresh() {
|
|
619
|
-
return g ? new Promise((
|
|
620
|
-
|
|
836
|
+
return g ? new Promise((k, p) => {
|
|
837
|
+
S.push({ resolve: k, reject: p });
|
|
621
838
|
}) : null;
|
|
622
839
|
},
|
|
623
840
|
/**
|
|
624
841
|
* Clear state
|
|
625
842
|
*/
|
|
626
843
|
clear() {
|
|
627
|
-
g = null, A = !1,
|
|
844
|
+
g = null, A = !1, v.length = 0, d(), z(new Error("Token refresh manager cleared"));
|
|
628
845
|
},
|
|
629
846
|
/**
|
|
630
847
|
* Handle token refresh failure
|
|
631
848
|
*/
|
|
632
|
-
async handleRefreshFailure(
|
|
633
|
-
return
|
|
849
|
+
async handleRefreshFailure(k) {
|
|
850
|
+
return W(k);
|
|
634
851
|
}
|
|
635
852
|
};
|
|
636
853
|
}
|
|
637
|
-
function
|
|
638
|
-
const
|
|
854
|
+
function Ke() {
|
|
855
|
+
const e = process.env.NODE_ENV === "production";
|
|
639
856
|
return {
|
|
640
857
|
cookieName: "__mulguard_session",
|
|
641
858
|
expiresIn: 60 * 60 * 24 * 7,
|
|
642
859
|
// 7 days
|
|
643
860
|
httpOnly: !0,
|
|
644
|
-
secure:
|
|
861
|
+
secure: e,
|
|
645
862
|
// HTTPS only in production
|
|
646
863
|
sameSite: "lax",
|
|
647
864
|
path: "/"
|
|
648
865
|
};
|
|
649
866
|
}
|
|
650
|
-
function
|
|
867
|
+
function Xe() {
|
|
651
868
|
return {
|
|
652
869
|
enabled: !0,
|
|
653
870
|
refreshThreshold: 300,
|
|
@@ -662,394 +879,568 @@ function me() {
|
|
|
662
879
|
autoRedirectOnFailure: !0
|
|
663
880
|
};
|
|
664
881
|
}
|
|
665
|
-
function
|
|
666
|
-
|
|
667
|
-
|
|
668
|
-
|
|
669
|
-
|
|
670
|
-
|
|
671
|
-
|
|
672
|
-
|
|
673
|
-
|
|
674
|
-
|
|
675
|
-
|
|
882
|
+
function Je() {
|
|
883
|
+
return process.env.NEXT_PUBLIC_URL ?? (process.env.VERCEL_URL ? `https://${process.env.VERCEL_URL}` : "http://localhost:3000");
|
|
884
|
+
}
|
|
885
|
+
function Ye(e) {
|
|
886
|
+
const { sessionConfig: r, cacheTtl: t, getSessionAction: n, onSessionExpired: s, onError: i } = e, o = r.cookieName ?? "__mulguard_session";
|
|
887
|
+
let a = null;
|
|
888
|
+
const l = async () => {
|
|
889
|
+
const y = Date.now();
|
|
890
|
+
if (a && y - a.timestamp < t)
|
|
891
|
+
return a.session;
|
|
892
|
+
if (n)
|
|
893
|
+
try {
|
|
894
|
+
const h = await n();
|
|
895
|
+
if (h && N(h))
|
|
896
|
+
return a = { session: h, timestamp: y }, h;
|
|
897
|
+
h && !N(h) && (await w(), a = null);
|
|
898
|
+
} catch (h) {
|
|
899
|
+
I.debug("getSession error", { error: h }), i && await i(h instanceof Error ? h : new Error(String(h)), "getSession"), a = null;
|
|
900
|
+
}
|
|
901
|
+
try {
|
|
902
|
+
const h = await ce(o);
|
|
903
|
+
if (h)
|
|
904
|
+
try {
|
|
905
|
+
const T = JSON.parse(h);
|
|
906
|
+
if (N(T))
|
|
907
|
+
return T.expiresAt && new Date(T.expiresAt) < /* @__PURE__ */ new Date() ? (s && await s(T), await w(), a = null, null) : (a = { session: T, timestamp: y }, T);
|
|
908
|
+
await w(), a = null;
|
|
909
|
+
} catch {
|
|
910
|
+
await w(), a = null;
|
|
911
|
+
}
|
|
912
|
+
} catch (h) {
|
|
913
|
+
const T = h instanceof Error ? h.message : String(h);
|
|
914
|
+
!T.includes("request scope") && !T.includes("cookies") && (I.warn("getSession cookie error", { error: h }), i && await i(
|
|
915
|
+
h instanceof Error ? h : new Error(String(h)),
|
|
916
|
+
"getSession.cookie"
|
|
917
|
+
));
|
|
918
|
+
}
|
|
919
|
+
return null;
|
|
920
|
+
}, f = async (y) => {
|
|
921
|
+
if (!N(y))
|
|
922
|
+
return {
|
|
923
|
+
success: !1,
|
|
924
|
+
error: "Invalid session structure"
|
|
925
|
+
};
|
|
926
|
+
try {
|
|
927
|
+
const h = typeof y == "object" && "token" in y ? String(y.token) : JSON.stringify(y), T = oe(o, h, r), _ = await ae(T);
|
|
928
|
+
return _.success && (a = { session: y, timestamp: Date.now() }), _;
|
|
929
|
+
} catch (h) {
|
|
930
|
+
const T = h instanceof Error ? h.message : "Failed to set session";
|
|
931
|
+
return I.error("setSession error", { error: h }), i && await i(h instanceof Error ? h : new Error(String(h)), "setSession"), {
|
|
932
|
+
success: !1,
|
|
933
|
+
error: T
|
|
934
|
+
};
|
|
935
|
+
}
|
|
936
|
+
}, w = async () => {
|
|
937
|
+
try {
|
|
938
|
+
await ie(o, {
|
|
939
|
+
path: r.path,
|
|
940
|
+
domain: r.domain
|
|
941
|
+
}), a = null;
|
|
942
|
+
} catch (y) {
|
|
943
|
+
I.warn("clearSessionCookie error", { error: y });
|
|
944
|
+
}
|
|
945
|
+
}, g = async () => {
|
|
946
|
+
const y = await l();
|
|
947
|
+
return y != null && y.accessToken && typeof y.accessToken == "string" ? y.accessToken : null;
|
|
948
|
+
};
|
|
949
|
+
return {
|
|
950
|
+
getSession: l,
|
|
951
|
+
setSession: f,
|
|
952
|
+
clearSessionCookie: w,
|
|
953
|
+
getAccessToken: g,
|
|
954
|
+
getRefreshToken: async () => {
|
|
955
|
+
const y = await l();
|
|
956
|
+
return y != null && y.refreshToken && typeof y.refreshToken == "string" ? y.refreshToken : null;
|
|
957
|
+
},
|
|
958
|
+
hasValidTokens: async () => !!await g(),
|
|
959
|
+
clearCache: () => {
|
|
960
|
+
a = null;
|
|
961
|
+
},
|
|
962
|
+
getSessionConfig: () => ({ cookieName: o, config: r })
|
|
963
|
+
};
|
|
964
|
+
}
|
|
965
|
+
function Qe(e) {
|
|
966
|
+
return async (r) => {
|
|
967
|
+
try {
|
|
968
|
+
if (!r || typeof r != "object")
|
|
969
|
+
return {
|
|
970
|
+
success: !1,
|
|
971
|
+
error: "Invalid credentials",
|
|
972
|
+
errorCode: m.VALIDATION_ERROR
|
|
973
|
+
};
|
|
974
|
+
if (!r.email || typeof r.email != "string")
|
|
975
|
+
return {
|
|
976
|
+
success: !1,
|
|
977
|
+
error: "Email is required",
|
|
978
|
+
errorCode: m.VALIDATION_ERROR
|
|
979
|
+
};
|
|
980
|
+
const t = G(r.email);
|
|
981
|
+
if (!K(t))
|
|
982
|
+
return {
|
|
983
|
+
success: !1,
|
|
984
|
+
error: t.error ?? "Invalid email format",
|
|
985
|
+
errorCode: m.VALIDATION_ERROR
|
|
986
|
+
};
|
|
987
|
+
if (!r.password || typeof r.password != "string")
|
|
988
|
+
return {
|
|
989
|
+
success: !1,
|
|
990
|
+
error: "Password is required",
|
|
991
|
+
errorCode: m.VALIDATION_ERROR
|
|
992
|
+
};
|
|
993
|
+
if (r.password.length > 128)
|
|
994
|
+
return {
|
|
995
|
+
success: !1,
|
|
996
|
+
error: "Invalid credentials",
|
|
997
|
+
errorCode: m.VALIDATION_ERROR
|
|
998
|
+
};
|
|
999
|
+
const n = {
|
|
1000
|
+
email: t.sanitized,
|
|
1001
|
+
password: r.password
|
|
1002
|
+
// Don't sanitize password (needed for hashing)
|
|
1003
|
+
}, s = await e.actions.signIn.email(n);
|
|
1004
|
+
if (D(s)) {
|
|
1005
|
+
const i = await e.saveSessionAfterAuth(s);
|
|
1006
|
+
!i.success && i.warning && I.warn("Session save warning", { warning: i.warning });
|
|
1007
|
+
}
|
|
1008
|
+
return s.success ? I.info("Sign in successful", {
|
|
1009
|
+
email: n.email.substring(0, 3) + "***"
|
|
1010
|
+
}) : I.warn("Sign in failed", {
|
|
1011
|
+
email: n.email.substring(0, 3) + "***",
|
|
1012
|
+
errorCode: s.errorCode
|
|
1013
|
+
}), s;
|
|
1014
|
+
} catch (t) {
|
|
1015
|
+
const n = t instanceof Error ? t.message : "Sign in failed";
|
|
1016
|
+
return I.error("Sign in error", { error: n, context: "signIn.email" }), e.onError && await e.onError(
|
|
1017
|
+
t instanceof Error ? t : new Error(String(t)),
|
|
1018
|
+
"signIn.email"
|
|
1019
|
+
), {
|
|
1020
|
+
success: !1,
|
|
1021
|
+
error: "Sign in failed. Please try again.",
|
|
1022
|
+
errorCode: m.UNKNOWN_ERROR
|
|
1023
|
+
};
|
|
1024
|
+
}
|
|
1025
|
+
};
|
|
1026
|
+
}
|
|
1027
|
+
function Ze(e, r) {
|
|
1028
|
+
return async (t) => {
|
|
1029
|
+
if (!t || typeof t != "string")
|
|
1030
|
+
throw new Error("Provider is required");
|
|
1031
|
+
const n = X(t, {
|
|
1032
|
+
maxLength: 50,
|
|
1033
|
+
allowHtml: !1,
|
|
1034
|
+
required: !0
|
|
1035
|
+
});
|
|
1036
|
+
if (!n.valid || !n.sanitized)
|
|
1037
|
+
throw new Error("Invalid provider");
|
|
1038
|
+
const s = n.sanitized.toLowerCase();
|
|
1039
|
+
if (!e.actions.signIn.oauth)
|
|
1040
|
+
throw new Error(
|
|
1041
|
+
"OAuth sign in is not configured. Either provide oauth action in signIn, or configure providers.oauth in config."
|
|
1042
|
+
);
|
|
1043
|
+
const i = await e.actions.signIn.oauth(s);
|
|
1044
|
+
return await r(i.state, s), I.info("OAuth sign in initiated", { provider: s }), i;
|
|
1045
|
+
};
|
|
1046
|
+
}
|
|
1047
|
+
function er(e) {
|
|
1048
|
+
return async (r, t) => {
|
|
1049
|
+
if (!r || typeof r != "string")
|
|
1050
|
+
return {
|
|
1051
|
+
success: !1,
|
|
1052
|
+
error: "Email is required",
|
|
1053
|
+
errorCode: m.VALIDATION_ERROR
|
|
1054
|
+
};
|
|
1055
|
+
const n = G(r);
|
|
1056
|
+
if (!K(n))
|
|
1057
|
+
return {
|
|
1058
|
+
success: !1,
|
|
1059
|
+
error: n.error ?? "Invalid email format",
|
|
1060
|
+
errorCode: m.VALIDATION_ERROR
|
|
1061
|
+
};
|
|
1062
|
+
if (t !== void 0 && (typeof t != "string" || t.length < 4 || t.length > 10))
|
|
1063
|
+
return {
|
|
1064
|
+
success: !1,
|
|
1065
|
+
error: "Invalid OTP code format",
|
|
1066
|
+
errorCode: m.VALIDATION_ERROR
|
|
1067
|
+
};
|
|
1068
|
+
if (!e.actions.signIn.otp)
|
|
1069
|
+
return {
|
|
1070
|
+
success: !1,
|
|
1071
|
+
error: "OTP sign in is not configured",
|
|
1072
|
+
errorCode: m.VALIDATION_ERROR
|
|
1073
|
+
};
|
|
1074
|
+
try {
|
|
1075
|
+
const s = await e.actions.signIn.otp(n.sanitized, t);
|
|
1076
|
+
if (D(s)) {
|
|
1077
|
+
const i = await e.saveSessionAfterAuth(s);
|
|
1078
|
+
!i.success && i.warning && I.warn("Session save warning", { warning: i.warning });
|
|
1079
|
+
}
|
|
1080
|
+
return s.success ? I.info("OTP sign in successful", {
|
|
1081
|
+
email: n.sanitized.substring(0, 3) + "***"
|
|
1082
|
+
}) : I.warn("OTP sign in failed", {
|
|
1083
|
+
email: n.sanitized.substring(0, 3) + "***"
|
|
1084
|
+
}), s;
|
|
1085
|
+
} catch (s) {
|
|
1086
|
+
return I.error("OTP sign in error", {
|
|
1087
|
+
error: s instanceof Error ? s.message : "Unknown error",
|
|
1088
|
+
context: "signIn.otp"
|
|
1089
|
+
}), e.onError && await e.onError(
|
|
1090
|
+
s instanceof Error ? s : new Error(String(s)),
|
|
1091
|
+
"signIn.otp"
|
|
1092
|
+
), {
|
|
1093
|
+
success: !1,
|
|
1094
|
+
error: "OTP sign in failed. Please try again.",
|
|
1095
|
+
errorCode: m.UNKNOWN_ERROR
|
|
1096
|
+
};
|
|
1097
|
+
}
|
|
1098
|
+
};
|
|
1099
|
+
}
|
|
1100
|
+
function rr(e) {
|
|
1101
|
+
return async (r) => {
|
|
1102
|
+
if (!e.actions.signIn.passkey)
|
|
1103
|
+
throw new Error("PassKey sign in is not configured. Provide passkey action in signIn.");
|
|
1104
|
+
try {
|
|
1105
|
+
const t = await e.actions.signIn.passkey(r);
|
|
1106
|
+
if (D(t)) {
|
|
1107
|
+
const n = await e.saveSessionAfterAuth(t);
|
|
1108
|
+
!n.success && n.warning && I.warn("Session save warning", { warning: n.warning });
|
|
1109
|
+
}
|
|
1110
|
+
return t;
|
|
1111
|
+
} catch (t) {
|
|
1112
|
+
return e.onError && await e.onError(
|
|
1113
|
+
t instanceof Error ? t : new Error(String(t)),
|
|
1114
|
+
"signIn.passkey"
|
|
1115
|
+
), {
|
|
1116
|
+
success: !1,
|
|
1117
|
+
error: t instanceof Error ? t.message : "PassKey sign in failed"
|
|
1118
|
+
};
|
|
1119
|
+
}
|
|
1120
|
+
};
|
|
1121
|
+
}
|
|
1122
|
+
function tr(e, r) {
|
|
1123
|
+
const t = Qe(e), n = Ze(e, r), s = er(e), i = rr(e);
|
|
1124
|
+
return Object.assign(async (l, f) => {
|
|
1125
|
+
if (!l || typeof l != "string")
|
|
1126
|
+
throw new Error("Provider is required");
|
|
1127
|
+
const w = X(l, {
|
|
1128
|
+
maxLength: 50,
|
|
1129
|
+
allowHtml: !1,
|
|
1130
|
+
required: !0
|
|
1131
|
+
});
|
|
1132
|
+
if (!w.valid || !w.sanitized)
|
|
1133
|
+
throw new Error("Invalid provider");
|
|
1134
|
+
const g = w.sanitized.toLowerCase();
|
|
1135
|
+
if (g === "google" || g === "github" || g === "apple" || g === "facebook" || typeof g == "string" && !["credentials", "otp", "passkey"].includes(g))
|
|
1136
|
+
return n(g);
|
|
1137
|
+
if (g === "credentials")
|
|
1138
|
+
return !f || !("email" in f) || !("password" in f) ? {
|
|
1139
|
+
success: !1,
|
|
1140
|
+
error: "Credentials are required",
|
|
1141
|
+
errorCode: m.VALIDATION_ERROR
|
|
1142
|
+
} : t(f);
|
|
1143
|
+
if (g === "otp") {
|
|
1144
|
+
if (!f || !("email" in f))
|
|
1145
|
+
return {
|
|
1146
|
+
success: !1,
|
|
1147
|
+
error: "Email is required",
|
|
1148
|
+
errorCode: m.VALIDATION_ERROR
|
|
1149
|
+
};
|
|
1150
|
+
const A = f;
|
|
1151
|
+
return s(A.email, A.code);
|
|
1152
|
+
}
|
|
1153
|
+
return g === "passkey" ? i(f) : {
|
|
1154
|
+
success: !1,
|
|
1155
|
+
error: "Invalid provider",
|
|
1156
|
+
errorCode: m.VALIDATION_ERROR
|
|
1157
|
+
};
|
|
1158
|
+
}, {
|
|
1159
|
+
email: t,
|
|
1160
|
+
oauth: e.actions.signIn.oauth ? n : void 0,
|
|
1161
|
+
passkey: e.actions.signIn.passkey ? i : void 0,
|
|
1162
|
+
otp: e.actions.signIn.otp ? s : void 0
|
|
1163
|
+
});
|
|
1164
|
+
}
|
|
1165
|
+
function nr(e) {
|
|
1166
|
+
return async (r) => {
|
|
1167
|
+
if (!e.actions.signUp)
|
|
1168
|
+
throw new Error("Sign up is not configured. Provide signUp action in config.");
|
|
1169
|
+
try {
|
|
1170
|
+
const t = await e.actions.signUp(r);
|
|
1171
|
+
if (D(t)) {
|
|
1172
|
+
const n = await e.saveSessionAfterAuth(t);
|
|
1173
|
+
!n.success && n.warning && I.warn("Session save warning", { warning: n.warning });
|
|
1174
|
+
}
|
|
1175
|
+
return t;
|
|
1176
|
+
} catch (t) {
|
|
1177
|
+
return e.onError && await e.onError(
|
|
1178
|
+
t instanceof Error ? t : new Error(String(t)),
|
|
1179
|
+
"signUp"
|
|
1180
|
+
), {
|
|
1181
|
+
success: !1,
|
|
1182
|
+
error: t instanceof Error ? t.message : "Sign up failed"
|
|
1183
|
+
};
|
|
1184
|
+
}
|
|
1185
|
+
};
|
|
1186
|
+
}
|
|
1187
|
+
function sr(e, r) {
|
|
1188
|
+
return async (t, n, s) => {
|
|
1189
|
+
const i = e.oauthProviders[t];
|
|
676
1190
|
if (!i)
|
|
677
|
-
throw new Error(`OAuth provider "${n}" is not configured. Add it to providers.oauth in config.`);
|
|
678
|
-
if (!i.clientId)
|
|
679
|
-
throw new Error(`OAuth provider "${n}" is missing clientId`);
|
|
680
|
-
const u = ne();
|
|
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)
|
|
685
1191
|
return {
|
|
686
1192
|
success: !1,
|
|
687
|
-
error: `OAuth provider "${
|
|
688
|
-
errorCode:
|
|
1193
|
+
error: `OAuth provider "${t}" is not configured`,
|
|
1194
|
+
errorCode: m.VALIDATION_ERROR
|
|
689
1195
|
};
|
|
690
1196
|
try {
|
|
691
|
-
const
|
|
692
|
-
id:
|
|
693
|
-
email:
|
|
694
|
-
name:
|
|
695
|
-
avatar:
|
|
696
|
-
emailVerified:
|
|
697
|
-
|
|
698
|
-
|
|
699
|
-
|
|
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
|
|
1197
|
+
const o = i.redirectUri ?? `${e.baseUrl}/api/auth/callback/${t}`, a = await Ue(t, i, n, o), l = await Fe(t, a.access_token), f = {
|
|
1198
|
+
id: l.id,
|
|
1199
|
+
email: l.email,
|
|
1200
|
+
name: l.name,
|
|
1201
|
+
avatar: l.avatar,
|
|
1202
|
+
emailVerified: l.emailVerified,
|
|
1203
|
+
provider: t,
|
|
1204
|
+
accessToken: a.access_token,
|
|
1205
|
+
refreshToken: a.refresh_token,
|
|
704
1206
|
tokens: {
|
|
705
|
-
access_token:
|
|
706
|
-
refresh_token:
|
|
707
|
-
expires_in:
|
|
708
|
-
token_type:
|
|
709
|
-
id_token:
|
|
1207
|
+
access_token: a.access_token,
|
|
1208
|
+
refresh_token: a.refresh_token,
|
|
1209
|
+
expires_in: a.expires_in,
|
|
1210
|
+
token_type: a.token_type,
|
|
1211
|
+
id_token: a.id_token
|
|
710
1212
|
},
|
|
711
|
-
|
|
712
|
-
rawProfile: E.rawProfile
|
|
1213
|
+
rawProfile: l.rawProfile
|
|
713
1214
|
};
|
|
714
|
-
if (
|
|
715
|
-
const
|
|
716
|
-
|
|
1215
|
+
if (e.callbacks.onOAuthUser) {
|
|
1216
|
+
const w = await q(
|
|
1217
|
+
e.callbacks.onOAuthUser,
|
|
1218
|
+
[f, t],
|
|
1219
|
+
e.onError
|
|
1220
|
+
);
|
|
1221
|
+
if (!w)
|
|
717
1222
|
return {
|
|
718
1223
|
success: !1,
|
|
719
1224
|
error: "Failed to create or retrieve user",
|
|
720
|
-
errorCode:
|
|
1225
|
+
errorCode: m.VALIDATION_ERROR
|
|
721
1226
|
};
|
|
722
|
-
const
|
|
723
|
-
|
|
724
|
-
|
|
725
|
-
|
|
726
|
-
|
|
727
|
-
|
|
728
|
-
emailVerified: h.emailVerified
|
|
729
|
-
},
|
|
730
|
-
expiresAt: new Date(Date.now() + 7 * 24 * 60 * 60 * 1e3),
|
|
731
|
-
accessToken: S.access_token,
|
|
732
|
-
refreshToken: S.refresh_token,
|
|
733
|
-
tokenType: "Bearer",
|
|
734
|
-
expiresIn: S.expires_in
|
|
735
|
-
};
|
|
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 };
|
|
1227
|
+
const g = e.createSession(w, f, a);
|
|
1228
|
+
return await e.saveSession(g), e.callbacks.onSignIn && await q(
|
|
1229
|
+
e.callbacks.onSignIn,
|
|
1230
|
+
[g.user, g],
|
|
1231
|
+
e.onError
|
|
1232
|
+
), { success: !0, user: g.user, session: g };
|
|
737
1233
|
}
|
|
738
1234
|
return {
|
|
739
1235
|
success: !1,
|
|
740
1236
|
error: "OAuth user callback not implemented. Provide onOAuthUser callback or implement oauthCallback action.",
|
|
741
|
-
errorCode:
|
|
1237
|
+
errorCode: m.VALIDATION_ERROR
|
|
742
1238
|
};
|
|
743
|
-
} catch (
|
|
744
|
-
return
|
|
1239
|
+
} catch (o) {
|
|
1240
|
+
return I.error("OAuth callback failed", { provider: t, error: o }), {
|
|
745
1241
|
success: !1,
|
|
746
|
-
error:
|
|
747
|
-
errorCode:
|
|
1242
|
+
error: o instanceof Error ? o.message : "OAuth callback failed",
|
|
1243
|
+
errorCode: m.NETWORK_ERROR
|
|
748
1244
|
};
|
|
749
1245
|
}
|
|
750
|
-
}
|
|
751
|
-
|
|
752
|
-
|
|
753
|
-
|
|
754
|
-
|
|
755
|
-
|
|
756
|
-
|
|
757
|
-
|
|
758
|
-
|
|
759
|
-
|
|
760
|
-
|
|
761
|
-
|
|
762
|
-
|
|
1246
|
+
};
|
|
1247
|
+
}
|
|
1248
|
+
async function q(e, r, t) {
|
|
1249
|
+
if (e)
|
|
1250
|
+
try {
|
|
1251
|
+
return await e(...r);
|
|
1252
|
+
} catch (n) {
|
|
1253
|
+
throw t && await t(
|
|
1254
|
+
n instanceof Error ? n : new Error(String(n)),
|
|
1255
|
+
"callback"
|
|
1256
|
+
), n;
|
|
1257
|
+
}
|
|
1258
|
+
}
|
|
1259
|
+
function ir(e, r, t, n) {
|
|
1260
|
+
if (Object.keys(e).length !== 0)
|
|
1261
|
+
return async (s) => {
|
|
1262
|
+
const i = e[s];
|
|
1263
|
+
if (!i)
|
|
1264
|
+
throw new Error(`OAuth provider "${s}" is not configured. Add it to providers.oauth in config.`);
|
|
1265
|
+
if (!i.clientId)
|
|
1266
|
+
throw new Error(`OAuth provider "${s}" is missing clientId`);
|
|
1267
|
+
const o = t();
|
|
1268
|
+
return { url: n(s, i, r, o), state: o };
|
|
1269
|
+
};
|
|
1270
|
+
}
|
|
1271
|
+
function et(e) {
|
|
1272
|
+
var L, M;
|
|
1273
|
+
const r = {
|
|
1274
|
+
...Ke(),
|
|
1275
|
+
...e.session
|
|
1276
|
+
}, t = e.actions, n = e.callbacks || {}, s = ((L = e.providers) == null ? void 0 : L.oauth) || {}, i = Je(), o = {
|
|
1277
|
+
...Xe(),
|
|
1278
|
+
...e.tokenRefresh
|
|
1279
|
+
}, a = ((M = e.session) == null ? void 0 : M.cacheTtl) ?? e.sessionCacheTtl ?? 5e3, l = e.oauthStateStore || $e(), f = { ...t }, w = async (c, u) => {
|
|
1280
|
+
const d = {
|
|
1281
|
+
provider: u,
|
|
763
1282
|
expiresAt: Date.now() + 6e5
|
|
764
1283
|
// 10 minutes
|
|
765
1284
|
};
|
|
766
|
-
await Promise.resolve(
|
|
767
|
-
},
|
|
768
|
-
const
|
|
769
|
-
return
|
|
770
|
-
},
|
|
771
|
-
|
|
772
|
-
|
|
773
|
-
|
|
774
|
-
|
|
1285
|
+
await Promise.resolve(l.set(c, d, 10 * 60 * 1e3)), l.cleanup && await Promise.resolve(l.cleanup());
|
|
1286
|
+
}, g = async (c, u) => {
|
|
1287
|
+
const d = await Promise.resolve(l.get(c));
|
|
1288
|
+
return d ? d.expiresAt < Date.now() ? (await Promise.resolve(l.delete(c)), !1) : d.provider !== u ? !1 : (await Promise.resolve(l.delete(c)), !0) : !1;
|
|
1289
|
+
}, A = ir(
|
|
1290
|
+
s,
|
|
1291
|
+
i,
|
|
1292
|
+
_e,
|
|
1293
|
+
be
|
|
1294
|
+
);
|
|
1295
|
+
if (A && !f.signIn.oauth) {
|
|
1296
|
+
const c = f.signIn;
|
|
1297
|
+
f.signIn = {
|
|
1298
|
+
...c,
|
|
1299
|
+
oauth: async (u) => {
|
|
1300
|
+
const d = await A(u);
|
|
1301
|
+
return await w(d.state, u), d;
|
|
1302
|
+
}
|
|
1303
|
+
};
|
|
1304
|
+
}
|
|
1305
|
+
if (!f.signIn || !f.signIn.email)
|
|
1306
|
+
throw new Error("mulguard: signIn.email action is required");
|
|
1307
|
+
const S = async (c, ...u) => {
|
|
1308
|
+
if (c)
|
|
1309
|
+
try {
|
|
1310
|
+
return await c(...u);
|
|
1311
|
+
} catch (d) {
|
|
1312
|
+
throw n.onError && await n.onError(d instanceof Error ? d : new Error(String(d)), "callback"), d;
|
|
1313
|
+
}
|
|
1314
|
+
}, v = Ye({
|
|
1315
|
+
sessionConfig: r,
|
|
1316
|
+
cacheTtl: a,
|
|
1317
|
+
getSessionAction: t.getSession,
|
|
1318
|
+
onSessionExpired: n.onSessionExpired,
|
|
1319
|
+
onError: n.onError
|
|
1320
|
+
}), y = async (c) => {
|
|
1321
|
+
if (!D(c) || !c.session)
|
|
775
1322
|
return { success: !0 };
|
|
776
|
-
const
|
|
777
|
-
return
|
|
778
|
-
}, T = async () => {
|
|
779
|
-
const n = e.cookieName || "__mulguard_session";
|
|
780
|
-
await J(n, {
|
|
781
|
-
path: e.path,
|
|
782
|
-
domain: e.domain
|
|
783
|
-
});
|
|
1323
|
+
const u = await v.setSession(c.session);
|
|
1324
|
+
return c.user && n.onSignIn && await S(n.onSignIn, c.user, c.session), u;
|
|
784
1325
|
};
|
|
785
|
-
|
|
786
|
-
|
|
1326
|
+
if (Object.keys(s).length > 0 && !f.oauthCallback) {
|
|
1327
|
+
const c = sr(
|
|
1328
|
+
{
|
|
1329
|
+
oauthProviders: s,
|
|
1330
|
+
baseUrl: i,
|
|
1331
|
+
callbacks: n,
|
|
1332
|
+
createSession: (u, d, R) => ({
|
|
1333
|
+
user: {
|
|
1334
|
+
...u,
|
|
1335
|
+
avatar: d.avatar,
|
|
1336
|
+
emailVerified: d.emailVerified
|
|
1337
|
+
},
|
|
1338
|
+
expiresAt: new Date(Date.now() + (r.expiresIn || 604800) * 1e3),
|
|
1339
|
+
accessToken: R.access_token,
|
|
1340
|
+
refreshToken: R.refresh_token,
|
|
1341
|
+
tokenType: "Bearer",
|
|
1342
|
+
expiresIn: R.expires_in
|
|
1343
|
+
}),
|
|
1344
|
+
saveSession: async (u) => {
|
|
1345
|
+
await v.setSession(u);
|
|
1346
|
+
},
|
|
1347
|
+
onError: n.onError
|
|
1348
|
+
}
|
|
1349
|
+
);
|
|
1350
|
+
f.oauthCallback = c;
|
|
1351
|
+
}
|
|
1352
|
+
const h = tr(
|
|
1353
|
+
{
|
|
1354
|
+
actions: f,
|
|
1355
|
+
callbacks: n,
|
|
1356
|
+
saveSessionAfterAuth: y,
|
|
1357
|
+
onError: n.onError
|
|
1358
|
+
},
|
|
1359
|
+
w
|
|
1360
|
+
), T = nr({
|
|
1361
|
+
actions: f,
|
|
1362
|
+
callbacks: n,
|
|
1363
|
+
saveSessionAfterAuth: y,
|
|
1364
|
+
onError: n.onError
|
|
1365
|
+
}), _ = {
|
|
787
1366
|
/**
|
|
788
1367
|
* Get current session
|
|
789
1368
|
* Uses custom getSession action if provided, otherwise falls back to reading from cookie
|
|
790
|
-
* ✅ IMPROVEMENT: Added session caching for better performance
|
|
791
1369
|
*/
|
|
792
1370
|
async getSession() {
|
|
793
|
-
|
|
794
|
-
if (m && n - m.timestamp < k)
|
|
795
|
-
return m.session;
|
|
796
|
-
if (s.getSession)
|
|
797
|
-
try {
|
|
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;
|
|
804
|
-
}
|
|
805
|
-
try {
|
|
806
|
-
const i = e.cookieName || "__mulguard_session", u = await G(i);
|
|
807
|
-
if (u)
|
|
808
|
-
try {
|
|
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;
|
|
813
|
-
} catch {
|
|
814
|
-
await T(), m = null;
|
|
815
|
-
}
|
|
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"));
|
|
819
|
-
}
|
|
820
|
-
return null;
|
|
1371
|
+
return await v.getSession();
|
|
821
1372
|
},
|
|
822
1373
|
/**
|
|
823
1374
|
* Get access token from current session
|
|
824
1375
|
*/
|
|
825
1376
|
async getAccessToken() {
|
|
826
|
-
|
|
827
|
-
return n != null && n.accessToken && typeof n.accessToken == "string" ? n.accessToken : null;
|
|
1377
|
+
return await v.getAccessToken();
|
|
828
1378
|
},
|
|
829
1379
|
/**
|
|
830
1380
|
* Get refresh token from current session
|
|
831
1381
|
*/
|
|
832
1382
|
async getRefreshToken() {
|
|
833
|
-
|
|
834
|
-
return n != null && n.refreshToken && typeof n.refreshToken == "string" ? n.refreshToken : null;
|
|
1383
|
+
return await v.getRefreshToken();
|
|
835
1384
|
},
|
|
836
1385
|
/**
|
|
837
1386
|
* Check if session has valid tokens
|
|
838
1387
|
*/
|
|
839
1388
|
async hasValidTokens() {
|
|
840
|
-
return
|
|
1389
|
+
return await v.hasValidTokens();
|
|
841
1390
|
},
|
|
842
1391
|
/**
|
|
843
1392
|
* Unified sign in method - supports both unified and direct method calls
|
|
844
|
-
* ✅ IMPROVEMENT: Single unified logic for all sign-in methods
|
|
845
1393
|
*/
|
|
846
|
-
signIn:
|
|
847
|
-
const n = async (E) => {
|
|
848
|
-
try {
|
|
849
|
-
if (!E || typeof E != "object")
|
|
850
|
-
return {
|
|
851
|
-
success: !1,
|
|
852
|
-
error: "Invalid credentials",
|
|
853
|
-
errorCode: y.VALIDATION_ERROR
|
|
854
|
-
};
|
|
855
|
-
if (!E.email || typeof E.email != "string")
|
|
856
|
-
return {
|
|
857
|
-
success: !1,
|
|
858
|
-
error: "Email is required",
|
|
859
|
-
errorCode: y.VALIDATION_ERROR
|
|
860
|
-
};
|
|
861
|
-
const h = M(E.email);
|
|
862
|
-
if (!h.valid)
|
|
863
|
-
return {
|
|
864
|
-
success: !1,
|
|
865
|
-
error: h.error || "Invalid email format",
|
|
866
|
-
errorCode: y.VALIDATION_ERROR
|
|
867
|
-
};
|
|
868
|
-
if (!E.password || typeof E.password != "string")
|
|
869
|
-
return {
|
|
870
|
-
success: !1,
|
|
871
|
-
error: "Password is required",
|
|
872
|
-
errorCode: y.VALIDATION_ERROR
|
|
873
|
-
};
|
|
874
|
-
if (E.password.length > 128)
|
|
875
|
-
return {
|
|
876
|
-
success: !1,
|
|
877
|
-
error: "Invalid credentials",
|
|
878
|
-
errorCode: y.VALIDATION_ERROR
|
|
879
|
-
};
|
|
880
|
-
const v = {
|
|
881
|
-
email: h.sanitized,
|
|
882
|
-
password: E.password
|
|
883
|
-
// Don't sanitize password (needed for hashing)
|
|
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;
|
|
886
|
-
} catch (h) {
|
|
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"), {
|
|
889
|
-
success: !1,
|
|
890
|
-
error: "Sign in failed. Please try again.",
|
|
891
|
-
errorCode: y.UNKNOWN_ERROR
|
|
892
|
-
};
|
|
893
|
-
}
|
|
894
|
-
}, i = async (E) => {
|
|
895
|
-
if (!E || typeof E != "string")
|
|
896
|
-
throw new Error("Provider is required");
|
|
897
|
-
const h = z(E, { maxLength: 50, allowHtml: !1, required: !0 });
|
|
898
|
-
if (!h.valid || !h.sanitized)
|
|
899
|
-
throw new Error("Invalid provider");
|
|
900
|
-
const v = h.sanitized.toLowerCase();
|
|
901
|
-
if (!a.signIn.oauth)
|
|
902
|
-
throw new Error(
|
|
903
|
-
"OAuth sign in is not configured. Either provide oauth action in signIn, or configure providers.oauth in config."
|
|
904
|
-
);
|
|
905
|
-
const l = await a.signIn.oauth(v);
|
|
906
|
-
return await A(l.state, v), P.info("OAuth sign in initiated", { provider: v }), l;
|
|
907
|
-
}, u = async (E) => {
|
|
908
|
-
if (!a.signIn.passkey)
|
|
909
|
-
throw new Error("PassKey sign in is not configured. Provide passkey action in signIn.");
|
|
910
|
-
try {
|
|
911
|
-
const h = await a.signIn.passkey(E);
|
|
912
|
-
return h.success && h.session && await U(h), h;
|
|
913
|
-
} catch (h) {
|
|
914
|
-
return t.onError && await g(t.onError, h instanceof Error ? h : new Error(String(h)), "signIn.passkey"), {
|
|
915
|
-
success: !1,
|
|
916
|
-
error: h instanceof Error ? h.message : "PassKey sign in failed"
|
|
917
|
-
};
|
|
918
|
-
}
|
|
919
|
-
}, p = async (E, h) => {
|
|
920
|
-
if (!E || typeof E != "string")
|
|
921
|
-
return {
|
|
922
|
-
success: !1,
|
|
923
|
-
error: "Email is required",
|
|
924
|
-
errorCode: y.VALIDATION_ERROR
|
|
925
|
-
};
|
|
926
|
-
const v = M(E);
|
|
927
|
-
if (!v.valid)
|
|
928
|
-
return {
|
|
929
|
-
success: !1,
|
|
930
|
-
error: v.error || "Invalid email format",
|
|
931
|
-
errorCode: y.VALIDATION_ERROR
|
|
932
|
-
};
|
|
933
|
-
if (h !== void 0 && (typeof h != "string" || h.length < 4 || h.length > 10))
|
|
934
|
-
return {
|
|
935
|
-
success: !1,
|
|
936
|
-
error: "Invalid OTP code format",
|
|
937
|
-
errorCode: y.VALIDATION_ERROR
|
|
938
|
-
};
|
|
939
|
-
if (!a.signIn.otp)
|
|
940
|
-
return {
|
|
941
|
-
success: !1,
|
|
942
|
-
error: "OTP sign in is not configured",
|
|
943
|
-
errorCode: y.VALIDATION_ERROR
|
|
944
|
-
};
|
|
945
|
-
try {
|
|
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;
|
|
948
|
-
} catch (l) {
|
|
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"), {
|
|
950
|
-
success: !1,
|
|
951
|
-
error: "OTP sign in failed. Please try again.",
|
|
952
|
-
errorCode: y.UNKNOWN_ERROR
|
|
953
|
-
};
|
|
954
|
-
}
|
|
955
|
-
}, S = Object.assign(
|
|
956
|
-
async (E, h) => {
|
|
957
|
-
if (!E || typeof E != "string")
|
|
958
|
-
throw new Error("Provider is required");
|
|
959
|
-
const v = z(E, { maxLength: 50, allowHtml: !1, required: !0 });
|
|
960
|
-
if (!v.valid || !v.sanitized)
|
|
961
|
-
throw new Error("Invalid provider");
|
|
962
|
-
const l = v.sanitized.toLowerCase();
|
|
963
|
-
if (l === "google" || l === "github" || l === "apple" || l === "facebook" || typeof l == "string" && !["credentials", "otp", "passkey"].includes(l))
|
|
964
|
-
return i(l);
|
|
965
|
-
if (l === "credentials")
|
|
966
|
-
return !h || !("email" in h) || !("password" in h) ? {
|
|
967
|
-
success: !1,
|
|
968
|
-
error: "Credentials are required",
|
|
969
|
-
errorCode: y.VALIDATION_ERROR
|
|
970
|
-
} : n(h);
|
|
971
|
-
if (l === "otp") {
|
|
972
|
-
if (!h || !("email" in h))
|
|
973
|
-
return {
|
|
974
|
-
success: !1,
|
|
975
|
-
error: "Email is required",
|
|
976
|
-
errorCode: y.VALIDATION_ERROR
|
|
977
|
-
};
|
|
978
|
-
const w = h;
|
|
979
|
-
return p(w.email, w.code);
|
|
980
|
-
}
|
|
981
|
-
return l === "passkey" ? u(h) : {
|
|
982
|
-
success: !1,
|
|
983
|
-
error: "Invalid provider",
|
|
984
|
-
errorCode: y.VALIDATION_ERROR
|
|
985
|
-
};
|
|
986
|
-
},
|
|
987
|
-
{
|
|
988
|
-
email: n,
|
|
989
|
-
oauth: a.signIn.oauth ? i : void 0,
|
|
990
|
-
passkey: a.signIn.passkey ? u : void 0,
|
|
991
|
-
otp: a.signIn.otp ? p : void 0
|
|
992
|
-
}
|
|
993
|
-
);
|
|
994
|
-
return O = S, S;
|
|
995
|
-
})(),
|
|
1394
|
+
signIn: h,
|
|
996
1395
|
/**
|
|
997
1396
|
* Sign up new user
|
|
998
1397
|
*/
|
|
999
|
-
async signUp(
|
|
1000
|
-
if (!
|
|
1398
|
+
async signUp(c) {
|
|
1399
|
+
if (!T)
|
|
1001
1400
|
throw new Error("Sign up is not configured. Provide signUp action in config.");
|
|
1002
|
-
|
|
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"), {
|
|
1007
|
-
success: !1,
|
|
1008
|
-
error: i instanceof Error ? i.message : "Sign up failed"
|
|
1009
|
-
};
|
|
1010
|
-
}
|
|
1401
|
+
return await T(c);
|
|
1011
1402
|
},
|
|
1012
1403
|
/**
|
|
1013
1404
|
* Sign out
|
|
1014
1405
|
*/
|
|
1015
1406
|
async signOut() {
|
|
1016
1407
|
try {
|
|
1017
|
-
const
|
|
1018
|
-
return
|
|
1019
|
-
} catch (
|
|
1020
|
-
return await
|
|
1408
|
+
const c = await this.getSession(), u = c == null ? void 0 : c.user;
|
|
1409
|
+
return t.signOut && await t.signOut(), await v.clearSessionCookie(), v.clearCache(), u && n.onSignOut && await S(n.onSignOut, u), { success: !0 };
|
|
1410
|
+
} catch (c) {
|
|
1411
|
+
return await v.clearSessionCookie(), v.clearCache(), n.onError && await S(n.onError, c instanceof Error ? c : new Error(String(c)), "signOut"), {
|
|
1021
1412
|
success: !1,
|
|
1022
|
-
error:
|
|
1413
|
+
error: c instanceof Error ? c.message : "Sign out failed"
|
|
1023
1414
|
};
|
|
1024
1415
|
}
|
|
1025
1416
|
},
|
|
1026
1417
|
/**
|
|
1027
1418
|
* Request password reset
|
|
1028
1419
|
*/
|
|
1029
|
-
async resetPassword(
|
|
1030
|
-
if (!
|
|
1420
|
+
async resetPassword(c) {
|
|
1421
|
+
if (!t.resetPassword)
|
|
1031
1422
|
throw new Error("Password reset is not configured. Provide resetPassword action in config.");
|
|
1032
1423
|
try {
|
|
1033
|
-
return await
|
|
1034
|
-
} catch (
|
|
1035
|
-
return
|
|
1424
|
+
return await t.resetPassword(c);
|
|
1425
|
+
} catch (u) {
|
|
1426
|
+
return n.onError && await S(n.onError, u instanceof Error ? u : new Error(String(u)), "resetPassword"), {
|
|
1036
1427
|
success: !1,
|
|
1037
|
-
error:
|
|
1428
|
+
error: u instanceof Error ? u.message : "Password reset failed"
|
|
1038
1429
|
};
|
|
1039
1430
|
}
|
|
1040
1431
|
},
|
|
1041
1432
|
/**
|
|
1042
1433
|
* Verify email address
|
|
1043
1434
|
*/
|
|
1044
|
-
async verifyEmail(
|
|
1045
|
-
if (!
|
|
1435
|
+
async verifyEmail(c) {
|
|
1436
|
+
if (!t.verifyEmail)
|
|
1046
1437
|
throw new Error("Email verification is not configured. Provide verifyEmail action in config.");
|
|
1047
1438
|
try {
|
|
1048
|
-
return await
|
|
1049
|
-
} catch (
|
|
1050
|
-
return
|
|
1439
|
+
return await t.verifyEmail(c);
|
|
1440
|
+
} catch (u) {
|
|
1441
|
+
return n.onError && await S(n.onError, u instanceof Error ? u : new Error(String(u)), "verifyEmail"), {
|
|
1051
1442
|
success: !1,
|
|
1052
|
-
error:
|
|
1443
|
+
error: u instanceof Error ? u.message : "Email verification failed"
|
|
1053
1444
|
};
|
|
1054
1445
|
}
|
|
1055
1446
|
},
|
|
@@ -1058,73 +1449,73 @@ function Me(r) {
|
|
|
1058
1449
|
* Executes custom refreshSession action with improved error handling and callbacks
|
|
1059
1450
|
*/
|
|
1060
1451
|
async refreshSession() {
|
|
1061
|
-
if (!
|
|
1452
|
+
if (!t.refreshSession)
|
|
1062
1453
|
return this.getSession();
|
|
1063
1454
|
try {
|
|
1064
|
-
const
|
|
1065
|
-
if (
|
|
1066
|
-
if (await
|
|
1067
|
-
const
|
|
1068
|
-
if (
|
|
1069
|
-
if (await
|
|
1070
|
-
const
|
|
1071
|
-
|
|
1455
|
+
const c = await t.refreshSession();
|
|
1456
|
+
if (c && N(c)) {
|
|
1457
|
+
if (await v.setSession(c), n.onSessionUpdate) {
|
|
1458
|
+
const u = await S(n.onSessionUpdate, c);
|
|
1459
|
+
if (u && N(u)) {
|
|
1460
|
+
if (await v.setSession(u), n.onTokenRefresh) {
|
|
1461
|
+
const d = await this.getSession();
|
|
1462
|
+
d && await S(n.onTokenRefresh, d, u);
|
|
1072
1463
|
}
|
|
1073
|
-
return
|
|
1464
|
+
return u;
|
|
1074
1465
|
}
|
|
1075
1466
|
}
|
|
1076
|
-
if (
|
|
1077
|
-
const
|
|
1078
|
-
|
|
1467
|
+
if (n.onTokenRefresh) {
|
|
1468
|
+
const u = await this.getSession();
|
|
1469
|
+
u && await S(n.onTokenRefresh, u, c);
|
|
1079
1470
|
}
|
|
1080
|
-
return
|
|
1081
|
-
} else if (
|
|
1082
|
-
return await
|
|
1471
|
+
return c;
|
|
1472
|
+
} else if (c && !N(c))
|
|
1473
|
+
return await v.clearSessionCookie(), v.clearCache(), null;
|
|
1083
1474
|
return null;
|
|
1084
|
-
} catch (
|
|
1085
|
-
return await
|
|
1475
|
+
} catch (c) {
|
|
1476
|
+
return await v.clearSessionCookie(), v.clearCache(), n.onError && await S(n.onError, c instanceof Error ? c : new Error(String(c)), "refreshSession"), null;
|
|
1086
1477
|
}
|
|
1087
1478
|
},
|
|
1088
1479
|
/**
|
|
1089
1480
|
* OAuth callback handler
|
|
1090
1481
|
* ✅ Auto-generated if providers.oauth is configured in config
|
|
1091
1482
|
*/
|
|
1092
|
-
async oauthCallback(
|
|
1093
|
-
if (!
|
|
1483
|
+
async oauthCallback(c, u, d) {
|
|
1484
|
+
if (!f.oauthCallback)
|
|
1094
1485
|
throw new Error(
|
|
1095
1486
|
"OAuth callback is not configured. Either provide oauthCallback action, or configure providers.oauth in config."
|
|
1096
1487
|
);
|
|
1097
|
-
if (!
|
|
1488
|
+
if (!u || !d)
|
|
1098
1489
|
return {
|
|
1099
1490
|
success: !1,
|
|
1100
|
-
error: "Missing required OAuth parameters (
|
|
1101
|
-
errorCode:
|
|
1491
|
+
error: "Missing required OAuth parameters (code or state)",
|
|
1492
|
+
errorCode: m.VALIDATION_ERROR
|
|
1102
1493
|
};
|
|
1103
|
-
|
|
1494
|
+
let R = c;
|
|
1495
|
+
if (!R) {
|
|
1496
|
+
const P = await Promise.resolve(l.get(d));
|
|
1497
|
+
if (P && P.provider)
|
|
1498
|
+
R = P.provider;
|
|
1499
|
+
else
|
|
1500
|
+
return {
|
|
1501
|
+
success: !1,
|
|
1502
|
+
error: "Provider is required and could not be extracted from state",
|
|
1503
|
+
errorCode: m.VALIDATION_ERROR
|
|
1504
|
+
};
|
|
1505
|
+
}
|
|
1506
|
+
if (!await g(d, R))
|
|
1104
1507
|
return {
|
|
1105
1508
|
success: !1,
|
|
1106
1509
|
error: "Invalid or expired state parameter",
|
|
1107
|
-
errorCode:
|
|
1510
|
+
errorCode: m.VALIDATION_ERROR
|
|
1108
1511
|
};
|
|
1109
1512
|
try {
|
|
1110
|
-
|
|
1111
|
-
|
|
1112
|
-
|
|
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
|
|
1116
|
-
}), t.onError && await g(
|
|
1117
|
-
t.onError,
|
|
1118
|
-
new Error(S.warning || S.error || "Failed to save session cookie"),
|
|
1119
|
-
"oauthCallback.setSession"
|
|
1120
|
-
));
|
|
1121
|
-
}
|
|
1122
|
-
return R;
|
|
1123
|
-
} catch (R) {
|
|
1124
|
-
return t.onError && await g(t.onError, R instanceof Error ? R : new Error(String(R)), "oauthCallback"), {
|
|
1513
|
+
return await f.oauthCallback(R, u, d);
|
|
1514
|
+
} catch (P) {
|
|
1515
|
+
return n.onError && await S(n.onError, P instanceof Error ? P : new Error(String(P)), "oauthCallback"), {
|
|
1125
1516
|
success: !1,
|
|
1126
|
-
error:
|
|
1127
|
-
errorCode:
|
|
1517
|
+
error: P instanceof Error ? P.message : "OAuth callback failed",
|
|
1518
|
+
errorCode: m.NETWORK_ERROR
|
|
1128
1519
|
};
|
|
1129
1520
|
}
|
|
1130
1521
|
},
|
|
@@ -1132,28 +1523,28 @@ function Me(r) {
|
|
|
1132
1523
|
* Verify 2FA code after initial sign in
|
|
1133
1524
|
* Used when signIn returns requires2FA: true
|
|
1134
1525
|
*/
|
|
1135
|
-
async verify2FA(
|
|
1136
|
-
if (!
|
|
1526
|
+
async verify2FA(c, u) {
|
|
1527
|
+
if (!t.verify2FA)
|
|
1137
1528
|
throw new Error("2FA verification is not configured. Provide verify2FA action in config.");
|
|
1138
1529
|
try {
|
|
1139
|
-
const
|
|
1140
|
-
if (
|
|
1141
|
-
const
|
|
1142
|
-
|
|
1143
|
-
error:
|
|
1144
|
-
warning:
|
|
1145
|
-
}),
|
|
1146
|
-
|
|
1147
|
-
new Error(
|
|
1530
|
+
const d = await t.verify2FA(c);
|
|
1531
|
+
if (d.success && d.session && !(u != null && u.skipCookieSave)) {
|
|
1532
|
+
const R = await y(d);
|
|
1533
|
+
R.success || (process.env.NODE_ENV === "development" && I.debug("Failed to save session cookie after verify2FA", {
|
|
1534
|
+
error: R.error,
|
|
1535
|
+
warning: R.warning
|
|
1536
|
+
}), n.onError && await S(
|
|
1537
|
+
n.onError,
|
|
1538
|
+
new Error(R.warning || R.error || "Failed to save session cookie"),
|
|
1148
1539
|
"verify2FA.setSession"
|
|
1149
1540
|
));
|
|
1150
1541
|
}
|
|
1151
|
-
return
|
|
1152
|
-
} catch (
|
|
1153
|
-
return
|
|
1542
|
+
return d;
|
|
1543
|
+
} catch (d) {
|
|
1544
|
+
return n.onError && await S(n.onError, d instanceof Error ? d : new Error(String(d)), "verify2FA"), {
|
|
1154
1545
|
success: !1,
|
|
1155
|
-
error:
|
|
1156
|
-
errorCode:
|
|
1546
|
+
error: d instanceof Error ? d.message : "2FA verification failed",
|
|
1547
|
+
errorCode: m.TWO_FA_REQUIRED
|
|
1157
1548
|
};
|
|
1158
1549
|
}
|
|
1159
1550
|
},
|
|
@@ -1161,11 +1552,8 @@ function Me(r) {
|
|
|
1161
1552
|
* Set session directly
|
|
1162
1553
|
* Useful for Server Actions that need to save session manually
|
|
1163
1554
|
*/
|
|
1164
|
-
async setSession(
|
|
1165
|
-
return
|
|
1166
|
-
success: !1,
|
|
1167
|
-
error: "Invalid session structure"
|
|
1168
|
-
};
|
|
1555
|
+
async setSession(c) {
|
|
1556
|
+
return await v.setSession(c);
|
|
1169
1557
|
},
|
|
1170
1558
|
/**
|
|
1171
1559
|
* Internal method to get session config for Server Actions
|
|
@@ -1173,584 +1561,562 @@ function Me(r) {
|
|
|
1173
1561
|
* @internal
|
|
1174
1562
|
*/
|
|
1175
1563
|
_getSessionConfig() {
|
|
1176
|
-
return
|
|
1177
|
-
cookieName: e.cookieName || "__mulguard_session",
|
|
1178
|
-
config: e
|
|
1179
|
-
};
|
|
1564
|
+
return v.getSessionConfig();
|
|
1180
1565
|
},
|
|
1181
1566
|
_getCallbacks() {
|
|
1182
|
-
return
|
|
1567
|
+
return n;
|
|
1183
1568
|
},
|
|
1184
1569
|
/**
|
|
1185
1570
|
* PassKey methods
|
|
1186
1571
|
*/
|
|
1187
|
-
passkey:
|
|
1188
|
-
register:
|
|
1189
|
-
authenticate: async (
|
|
1190
|
-
var
|
|
1191
|
-
if (!((
|
|
1572
|
+
passkey: t.passkey ? {
|
|
1573
|
+
register: t.passkey.register,
|
|
1574
|
+
authenticate: async (c) => {
|
|
1575
|
+
var u;
|
|
1576
|
+
if (!((u = t.passkey) != null && u.authenticate))
|
|
1192
1577
|
throw new Error("PassKey authenticate is not configured.");
|
|
1193
1578
|
try {
|
|
1194
|
-
const
|
|
1195
|
-
return
|
|
1196
|
-
} catch (
|
|
1197
|
-
return
|
|
1579
|
+
const d = await t.passkey.authenticate(c);
|
|
1580
|
+
return d.success && d.session && await y(d), d;
|
|
1581
|
+
} catch (d) {
|
|
1582
|
+
return n.onError && await S(n.onError, d instanceof Error ? d : new Error(String(d)), "passkey.authenticate"), {
|
|
1198
1583
|
success: !1,
|
|
1199
|
-
error:
|
|
1584
|
+
error: d instanceof Error ? d.message : "PassKey authentication failed"
|
|
1200
1585
|
};
|
|
1201
1586
|
}
|
|
1202
1587
|
},
|
|
1203
|
-
list:
|
|
1204
|
-
|
|
1588
|
+
list: t.passkey.list ? async () => {
|
|
1589
|
+
var u;
|
|
1590
|
+
if (!((u = t.passkey) != null && u.list))
|
|
1591
|
+
throw new Error("PassKey list is not configured.");
|
|
1592
|
+
return [...await t.passkey.list()];
|
|
1593
|
+
} : void 0,
|
|
1594
|
+
remove: t.passkey.remove
|
|
1205
1595
|
} : void 0,
|
|
1206
1596
|
/**
|
|
1207
1597
|
* Two-Factor Authentication methods
|
|
1208
1598
|
*/
|
|
1209
|
-
twoFactor:
|
|
1210
|
-
enable:
|
|
1211
|
-
verify:
|
|
1212
|
-
disable:
|
|
1213
|
-
generateBackupCodes:
|
|
1214
|
-
isEnabled:
|
|
1215
|
-
verify2FA: async (
|
|
1216
|
-
var
|
|
1217
|
-
const
|
|
1218
|
-
if (!
|
|
1599
|
+
twoFactor: t.twoFactor ? {
|
|
1600
|
+
enable: t.twoFactor.enable,
|
|
1601
|
+
verify: t.twoFactor.verify,
|
|
1602
|
+
disable: t.twoFactor.disable,
|
|
1603
|
+
generateBackupCodes: t.twoFactor.generateBackupCodes,
|
|
1604
|
+
isEnabled: t.twoFactor.isEnabled,
|
|
1605
|
+
verify2FA: async (c) => {
|
|
1606
|
+
var d;
|
|
1607
|
+
const u = ((d = t.twoFactor) == null ? void 0 : d.verify2FA) || t.verify2FA;
|
|
1608
|
+
if (!u)
|
|
1219
1609
|
throw new Error("2FA verification is not configured. Provide verify2FA action in config.");
|
|
1220
1610
|
try {
|
|
1221
|
-
const
|
|
1222
|
-
if (
|
|
1223
|
-
const
|
|
1224
|
-
|
|
1225
|
-
error:
|
|
1226
|
-
warning:
|
|
1227
|
-
}),
|
|
1228
|
-
|
|
1229
|
-
new Error(
|
|
1611
|
+
const R = await u(c);
|
|
1612
|
+
if (R.success && R.session) {
|
|
1613
|
+
const C = await y(R);
|
|
1614
|
+
C.success || (process.env.NODE_ENV === "development" && I.debug("Failed to save session cookie after twoFactor.verify2FA", {
|
|
1615
|
+
error: C.error,
|
|
1616
|
+
warning: C.warning
|
|
1617
|
+
}), n.onError && await S(
|
|
1618
|
+
n.onError,
|
|
1619
|
+
new Error(C.warning || C.error || "Failed to save session cookie"),
|
|
1230
1620
|
"twoFactor.verify2FA.setSession"
|
|
1231
1621
|
));
|
|
1232
1622
|
}
|
|
1233
|
-
return
|
|
1234
|
-
} catch (
|
|
1235
|
-
return
|
|
1623
|
+
return R;
|
|
1624
|
+
} catch (R) {
|
|
1625
|
+
return n.onError && await S(n.onError, R instanceof Error ? R : new Error(String(R)), "twoFactor.verify2FA"), {
|
|
1236
1626
|
success: !1,
|
|
1237
|
-
error:
|
|
1238
|
-
errorCode:
|
|
1627
|
+
error: R instanceof Error ? R.message : "2FA verification failed",
|
|
1628
|
+
errorCode: m.UNKNOWN_ERROR
|
|
1239
1629
|
};
|
|
1240
1630
|
}
|
|
1241
1631
|
}
|
|
1242
1632
|
} : void 0,
|
|
1243
1633
|
/**
|
|
1244
1634
|
* Sign in methods - alias for signIn (for backward compatibility)
|
|
1245
|
-
* ✅ IMPROVEMENT: Uses unified signIn logic
|
|
1246
1635
|
*/
|
|
1247
1636
|
signInMethods: {
|
|
1248
|
-
email: (
|
|
1249
|
-
oauth: (
|
|
1250
|
-
var
|
|
1251
|
-
return ((
|
|
1252
|
-
},
|
|
1253
|
-
passkey: (n) => {
|
|
1254
|
-
var i;
|
|
1255
|
-
return ((i = O.passkey) == null ? void 0 : i.call(O, n)) || Promise.reject(new Error("Passkey not configured"));
|
|
1637
|
+
email: (c) => h.email(c),
|
|
1638
|
+
oauth: (c) => {
|
|
1639
|
+
var u;
|
|
1640
|
+
return ((u = h.oauth) == null ? void 0 : u.call(h, c)) || Promise.reject(new Error("OAuth not configured"));
|
|
1256
1641
|
},
|
|
1257
|
-
|
|
1642
|
+
passkey: (c) => {
|
|
1258
1643
|
var u;
|
|
1259
|
-
return ((u =
|
|
1644
|
+
return ((u = h.passkey) == null ? void 0 : u.call(h, c)) || Promise.reject(new Error("Passkey not configured"));
|
|
1645
|
+
},
|
|
1646
|
+
otp: (c, u) => {
|
|
1647
|
+
var d;
|
|
1648
|
+
return ((d = h.otp) == null ? void 0 : d.call(h, c, u)) || Promise.reject(new Error("OTP not configured"));
|
|
1260
1649
|
}
|
|
1261
1650
|
}
|
|
1262
1651
|
};
|
|
1263
|
-
if (
|
|
1264
|
-
const
|
|
1265
|
-
async () => await
|
|
1266
|
-
async () => await
|
|
1652
|
+
if (t.refreshSession) {
|
|
1653
|
+
const c = Ge(
|
|
1654
|
+
async () => await _.refreshSession(),
|
|
1655
|
+
async () => await _.signOut(),
|
|
1267
1656
|
async () => {
|
|
1268
|
-
await
|
|
1657
|
+
await v.clearSessionCookie(), v.clearCache();
|
|
1269
1658
|
},
|
|
1270
1659
|
{
|
|
1271
|
-
...
|
|
1272
|
-
onTokenRefreshed:
|
|
1273
|
-
onTokenRefreshFailed:
|
|
1274
|
-
onBeforeRedirect:
|
|
1660
|
+
...o,
|
|
1661
|
+
onTokenRefreshed: o.onTokenRefreshed,
|
|
1662
|
+
onTokenRefreshFailed: o.onTokenRefreshFailed,
|
|
1663
|
+
onBeforeRedirect: o.onBeforeRedirect
|
|
1275
1664
|
}
|
|
1276
1665
|
);
|
|
1277
|
-
|
|
1666
|
+
_._tokenRefreshManager = c, _._getTokenRefreshManager = () => c;
|
|
1278
1667
|
}
|
|
1279
|
-
return
|
|
1668
|
+
return _;
|
|
1280
1669
|
}
|
|
1281
|
-
function
|
|
1670
|
+
function rt(e) {
|
|
1282
1671
|
return {
|
|
1283
|
-
GET: async (
|
|
1284
|
-
POST: async (
|
|
1672
|
+
GET: async (r) => B(r, e, "GET"),
|
|
1673
|
+
POST: async (r) => B(r, e, "POST")
|
|
1285
1674
|
};
|
|
1286
1675
|
}
|
|
1287
|
-
async function
|
|
1288
|
-
const
|
|
1676
|
+
async function B(e, r, t) {
|
|
1677
|
+
const n = new URL(e.url), s = or(n.pathname), i = s.split("/").filter(Boolean);
|
|
1289
1678
|
try {
|
|
1290
|
-
|
|
1291
|
-
|
|
1292
|
-
|
|
1293
|
-
|
|
1294
|
-
|
|
1295
|
-
if (o === "/providers")
|
|
1296
|
-
return f.json({
|
|
1297
|
-
providers: {
|
|
1298
|
-
email: !!e.signIn.email,
|
|
1299
|
-
oauth: !!e.signIn.oauth,
|
|
1300
|
-
passkey: !!e.signIn.passkey
|
|
1301
|
-
}
|
|
1302
|
-
});
|
|
1303
|
-
if (o.startsWith("/oauth/callback") || d[0] === "oauth" && d[1] === "callback") {
|
|
1304
|
-
if (!e.oauthCallback)
|
|
1305
|
-
return f.redirect(new URL("/login?error=oauth_not_configured", r.url));
|
|
1306
|
-
const c = d[2] || t.searchParams.get("provider"), a = t.searchParams.get("code"), m = t.searchParams.get("state");
|
|
1307
|
-
if (!c || !a || !m)
|
|
1308
|
-
return f.redirect(new URL("/login?error=oauth_missing_params", r.url));
|
|
1309
|
-
try {
|
|
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));
|
|
1314
|
-
} else
|
|
1315
|
-
return f.redirect(
|
|
1316
|
-
new URL(`/login?error=${encodeURIComponent(k.error || "oauth_failed")}`, r.url)
|
|
1317
|
-
);
|
|
1318
|
-
} catch (k) {
|
|
1319
|
-
return f.redirect(
|
|
1320
|
-
new URL(
|
|
1321
|
-
`/login?error=${encodeURIComponent(k instanceof Error ? k.message : "oauth_error")}`,
|
|
1322
|
-
r.url
|
|
1323
|
-
)
|
|
1324
|
-
);
|
|
1325
|
-
}
|
|
1326
|
-
}
|
|
1327
|
-
return f.json(
|
|
1328
|
-
{ error: "Not found" },
|
|
1329
|
-
{ status: 404 }
|
|
1330
|
-
);
|
|
1331
|
-
}
|
|
1332
|
-
if (s === "POST") {
|
|
1333
|
-
const c = await r.json().catch(() => ({}));
|
|
1334
|
-
if (o === "/sign-in" || d[0] === "sign-in") {
|
|
1335
|
-
if (c.provider === "email" && c.email && c.password) {
|
|
1336
|
-
const a = await e.signIn.email({
|
|
1337
|
-
email: c.email,
|
|
1338
|
-
password: c.password
|
|
1339
|
-
});
|
|
1340
|
-
return f.json(a);
|
|
1341
|
-
}
|
|
1342
|
-
if (c.provider === "oauth" && c.providerName) {
|
|
1343
|
-
if (!e.signIn.oauth)
|
|
1344
|
-
return f.json(
|
|
1345
|
-
{ success: !1, error: "OAuth is not configured" },
|
|
1346
|
-
{ status: 400 }
|
|
1347
|
-
);
|
|
1348
|
-
const a = await e.signIn.oauth(c.providerName);
|
|
1349
|
-
return f.json(a);
|
|
1350
|
-
}
|
|
1351
|
-
if (c.provider === "passkey") {
|
|
1352
|
-
if (!e.signIn.passkey)
|
|
1353
|
-
return f.json(
|
|
1354
|
-
{ success: !1, error: "PassKey is not configured" },
|
|
1355
|
-
{ status: 400 }
|
|
1356
|
-
);
|
|
1357
|
-
const a = await e.signIn.passkey(c.options);
|
|
1358
|
-
return f.json(a);
|
|
1359
|
-
}
|
|
1360
|
-
return f.json(
|
|
1361
|
-
{ success: !1, error: "Invalid sign in request" },
|
|
1362
|
-
{ status: 400 }
|
|
1363
|
-
);
|
|
1364
|
-
}
|
|
1365
|
-
if (o === "/sign-up" || d[0] === "sign-up") {
|
|
1366
|
-
if (!e.signUp)
|
|
1367
|
-
return f.json(
|
|
1368
|
-
{ success: !1, error: "Sign up is not configured" },
|
|
1369
|
-
{ status: 400 }
|
|
1370
|
-
);
|
|
1371
|
-
const a = await e.signUp(c);
|
|
1372
|
-
return f.json(a);
|
|
1373
|
-
}
|
|
1374
|
-
if (o === "/sign-out" || d[0] === "sign-out") {
|
|
1375
|
-
const a = await e.signOut();
|
|
1376
|
-
return f.json(a);
|
|
1377
|
-
}
|
|
1378
|
-
if (o === "/reset-password" || d[0] === "reset-password") {
|
|
1379
|
-
if (!e.resetPassword)
|
|
1380
|
-
return f.json(
|
|
1381
|
-
{ success: !1, error: "Password reset is not configured" },
|
|
1382
|
-
{ status: 400 }
|
|
1383
|
-
);
|
|
1384
|
-
const a = await e.resetPassword(c.email);
|
|
1385
|
-
return f.json(a);
|
|
1386
|
-
}
|
|
1387
|
-
if (o === "/verify-email" || d[0] === "verify-email") {
|
|
1388
|
-
if (!e.verifyEmail)
|
|
1389
|
-
return f.json(
|
|
1390
|
-
{ success: !1, error: "Email verification is not configured" },
|
|
1391
|
-
{ status: 400 }
|
|
1392
|
-
);
|
|
1393
|
-
const a = await e.verifyEmail(c.token);
|
|
1394
|
-
return f.json(a);
|
|
1395
|
-
}
|
|
1396
|
-
if (o === "/refresh" || d[0] === "refresh") {
|
|
1397
|
-
if (!e.refreshSession) {
|
|
1398
|
-
const m = await e.getSession();
|
|
1399
|
-
return f.json({ session: m });
|
|
1400
|
-
}
|
|
1401
|
-
const a = await e.refreshSession();
|
|
1402
|
-
return f.json({ session: a });
|
|
1403
|
-
}
|
|
1404
|
-
if (o.startsWith("/oauth/callback") || d[0] === "oauth" && d[1] === "callback") {
|
|
1405
|
-
if (!e.oauthCallback)
|
|
1406
|
-
return f.json(
|
|
1407
|
-
{ success: !1, error: "OAuth callback is not configured" },
|
|
1408
|
-
{ status: 400 }
|
|
1409
|
-
);
|
|
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)
|
|
1412
|
-
return f.json(
|
|
1413
|
-
{
|
|
1414
|
-
success: !1,
|
|
1415
|
-
error: "Missing required OAuth parameters. Provider, code, and state are required."
|
|
1416
|
-
},
|
|
1417
|
-
{ status: 400 }
|
|
1418
|
-
);
|
|
1419
|
-
const I = await e.oauthCallback(a, m, k);
|
|
1420
|
-
return f.json(I);
|
|
1421
|
-
}
|
|
1422
|
-
if (o.startsWith("/passkey")) {
|
|
1423
|
-
if (!e.passkey)
|
|
1424
|
-
return f.json(
|
|
1425
|
-
{ success: !1, error: "PassKey is not configured" },
|
|
1426
|
-
{ status: 400 }
|
|
1427
|
-
);
|
|
1428
|
-
if (d[1] === "register" && e.passkey.register) {
|
|
1429
|
-
const a = await e.passkey.register(c.options);
|
|
1430
|
-
return f.json(a);
|
|
1431
|
-
}
|
|
1432
|
-
if (d[1] === "list" && e.passkey.list) {
|
|
1433
|
-
const a = await e.passkey.list();
|
|
1434
|
-
return f.json(a);
|
|
1435
|
-
}
|
|
1436
|
-
if (d[1] === "remove" && e.passkey.remove) {
|
|
1437
|
-
const a = await e.passkey.remove(c.passkeyId);
|
|
1438
|
-
return f.json(a);
|
|
1439
|
-
}
|
|
1440
|
-
}
|
|
1441
|
-
if (o === "/verify-2fa" || d[0] === "verify-2fa") {
|
|
1442
|
-
if (!e.verify2FA)
|
|
1443
|
-
return f.json(
|
|
1444
|
-
{ success: !1, error: "2FA verification is not configured" },
|
|
1445
|
-
{ status: 400 }
|
|
1446
|
-
);
|
|
1447
|
-
if (!c.email || !c.userId || !c.code)
|
|
1448
|
-
return f.json(
|
|
1449
|
-
{
|
|
1450
|
-
success: !1,
|
|
1451
|
-
error: "Missing required parameters. Email, userId, and code are required."
|
|
1452
|
-
},
|
|
1453
|
-
{ status: 400 }
|
|
1454
|
-
);
|
|
1455
|
-
const a = await e.verify2FA({
|
|
1456
|
-
email: c.email,
|
|
1457
|
-
userId: c.userId,
|
|
1458
|
-
code: c.code
|
|
1459
|
-
});
|
|
1460
|
-
return f.json(a);
|
|
1461
|
-
}
|
|
1462
|
-
if (o.startsWith("/two-factor")) {
|
|
1463
|
-
if (!e.twoFactor)
|
|
1464
|
-
return f.json(
|
|
1465
|
-
{ success: !1, error: "Two-Factor Authentication is not configured" },
|
|
1466
|
-
{ status: 400 }
|
|
1467
|
-
);
|
|
1468
|
-
if (d[1] === "enable" && e.twoFactor.enable) {
|
|
1469
|
-
const a = await e.twoFactor.enable();
|
|
1470
|
-
return f.json(a);
|
|
1471
|
-
}
|
|
1472
|
-
if (d[1] === "verify" && e.twoFactor.verify) {
|
|
1473
|
-
const a = await e.twoFactor.verify(c.code);
|
|
1474
|
-
return f.json(a);
|
|
1475
|
-
}
|
|
1476
|
-
if (d[1] === "disable" && e.twoFactor.disable) {
|
|
1477
|
-
const a = await e.twoFactor.disable();
|
|
1478
|
-
return f.json(a);
|
|
1479
|
-
}
|
|
1480
|
-
if (d[1] === "backup-codes" && e.twoFactor.generateBackupCodes) {
|
|
1481
|
-
const a = await e.twoFactor.generateBackupCodes();
|
|
1482
|
-
return f.json(a);
|
|
1483
|
-
}
|
|
1484
|
-
if (d[1] === "is-enabled" && e.twoFactor.isEnabled) {
|
|
1485
|
-
const a = await e.twoFactor.isEnabled();
|
|
1486
|
-
return f.json({ enabled: a });
|
|
1487
|
-
}
|
|
1488
|
-
}
|
|
1489
|
-
return f.json(
|
|
1490
|
-
{ error: "Not found" },
|
|
1491
|
-
{ status: 404 }
|
|
1492
|
-
);
|
|
1493
|
-
}
|
|
1494
|
-
return f.json(
|
|
1495
|
-
{ error: "Method not allowed" },
|
|
1496
|
-
{ status: 405 }
|
|
1497
|
-
);
|
|
1498
|
-
} catch (c) {
|
|
1499
|
-
return f.json(
|
|
1500
|
-
{
|
|
1501
|
-
success: !1,
|
|
1502
|
-
error: c instanceof Error ? c.message : "Request failed"
|
|
1503
|
-
},
|
|
1504
|
-
{ status: 500 }
|
|
1679
|
+
return t === "GET" ? await ar(e, r, s, i, n) : t === "POST" ? await cr(e, r, s, i, n) : O("Method not allowed", 405);
|
|
1680
|
+
} catch (o) {
|
|
1681
|
+
return O(
|
|
1682
|
+
o instanceof Error ? o.message : "Request failed",
|
|
1683
|
+
500
|
|
1505
1684
|
);
|
|
1506
1685
|
}
|
|
1507
1686
|
}
|
|
1508
|
-
function
|
|
1509
|
-
return
|
|
1510
|
-
|
|
1687
|
+
function or(e) {
|
|
1688
|
+
return e.replace(/^\/api\/auth/, "") || "/session";
|
|
1689
|
+
}
|
|
1690
|
+
async function ar(e, r, t, n, s) {
|
|
1691
|
+
if (t === "/session" || t === "/") {
|
|
1692
|
+
const i = await r.getSession();
|
|
1693
|
+
return E.json({ session: i });
|
|
1694
|
+
}
|
|
1695
|
+
return t === "/providers" ? E.json({
|
|
1696
|
+
providers: {
|
|
1697
|
+
email: !!r.signIn.email,
|
|
1698
|
+
oauth: !!r.signIn.oauth,
|
|
1699
|
+
passkey: !!r.signIn.passkey
|
|
1700
|
+
}
|
|
1701
|
+
}) : re(t, n) ? await te(e, r, t, n, s, "GET") : O("Not found", 404);
|
|
1702
|
+
}
|
|
1703
|
+
async function cr(e, r, t, n, s) {
|
|
1704
|
+
const i = await ur(e);
|
|
1705
|
+
return t === "/sign-in" || n[0] === "sign-in" ? await fr(r, i) : t === "/sign-up" || n[0] === "sign-up" ? await dr(r, i) : t === "/sign-out" || n[0] === "sign-out" ? await hr(r) : t === "/reset-password" || n[0] === "reset-password" ? await gr(r, i) : t === "/verify-email" || n[0] === "verify-email" ? await wr(r, i) : t === "/refresh" || n[0] === "refresh" ? await pr(r) : re(t, n) ? await te(e, r, t, n, s, "POST", i) : t.startsWith("/passkey") ? await Er(r, t, n, i) : t === "/verify-2fa" || n[0] === "verify-2fa" ? await mr(r, i) : t.startsWith("/two-factor") ? await yr(r, n, i) : O("Not found", 404);
|
|
1706
|
+
}
|
|
1707
|
+
async function ur(e) {
|
|
1708
|
+
try {
|
|
1709
|
+
return await e.json();
|
|
1710
|
+
} catch {
|
|
1711
|
+
return {};
|
|
1712
|
+
}
|
|
1713
|
+
}
|
|
1714
|
+
function re(e, r) {
|
|
1715
|
+
return e === "/callback" || e.startsWith("/oauth/callback") || r[0] === "oauth" && r[1] === "callback" || r[0] === "callback";
|
|
1716
|
+
}
|
|
1717
|
+
async function te(e, r, t, n, s, i, o) {
|
|
1718
|
+
if (!r.oauthCallback)
|
|
1719
|
+
return i === "GET" ? V(e.url, "oauth_not_configured") : O("OAuth callback is not configured", 400);
|
|
1720
|
+
const a = lr(n, s, o), l = (o == null ? void 0 : o.code) ?? s.searchParams.get("code"), f = (o == null ? void 0 : o.state) ?? s.searchParams.get("state");
|
|
1721
|
+
if (!l || !f)
|
|
1722
|
+
return i === "GET" ? V(e.url, "oauth_missing_params") : O("Missing required OAuth parameters. Code and state are required.", 400);
|
|
1723
|
+
try {
|
|
1724
|
+
const w = await r.oauthCallback(a ?? "", l, f);
|
|
1725
|
+
return i === "GET" ? w.success ? kr(e.url, s.searchParams.get("callbackUrl")) : V(e.url, w.error ?? "oauth_failed") : E.json(w);
|
|
1726
|
+
} catch (w) {
|
|
1727
|
+
return i === "GET" ? V(e.url, w instanceof Error ? w.message : "oauth_error") : O(w instanceof Error ? w.message : "OAuth callback failed", 500);
|
|
1728
|
+
}
|
|
1729
|
+
}
|
|
1730
|
+
function lr(e, r, t) {
|
|
1731
|
+
return t != null && t.provider ? t.provider : e[0] === "callback" && e[1] ? e[1] : e[0] === "oauth" && e[1] === "callback" && e[2] ? e[2] : r.searchParams.get("provider");
|
|
1732
|
+
}
|
|
1733
|
+
async function fr(e, r) {
|
|
1734
|
+
if (r.provider === "email" && r.email && r.password) {
|
|
1735
|
+
const t = {
|
|
1736
|
+
email: r.email,
|
|
1737
|
+
password: r.password
|
|
1738
|
+
}, n = await e.signIn.email(t);
|
|
1739
|
+
return E.json(n);
|
|
1740
|
+
}
|
|
1741
|
+
if (r.provider === "oauth" && r.providerName) {
|
|
1742
|
+
if (!e.signIn.oauth)
|
|
1743
|
+
return O("OAuth is not configured", 400);
|
|
1744
|
+
const t = await e.signIn.oauth(r.providerName);
|
|
1745
|
+
return E.json(t);
|
|
1746
|
+
}
|
|
1747
|
+
if (r.provider === "passkey") {
|
|
1748
|
+
if (!e.signIn.passkey)
|
|
1749
|
+
return O("PassKey is not configured", 400);
|
|
1750
|
+
const t = await e.signIn.passkey(r.options);
|
|
1751
|
+
return E.json(t);
|
|
1752
|
+
}
|
|
1753
|
+
return O("Invalid sign in request", 400);
|
|
1754
|
+
}
|
|
1755
|
+
async function dr(e, r) {
|
|
1756
|
+
if (!e.signUp)
|
|
1757
|
+
return O("Sign up is not configured", 400);
|
|
1758
|
+
const t = await e.signUp(r);
|
|
1759
|
+
return E.json(t);
|
|
1760
|
+
}
|
|
1761
|
+
async function hr(e) {
|
|
1762
|
+
const r = await e.signOut();
|
|
1763
|
+
return E.json(r);
|
|
1764
|
+
}
|
|
1765
|
+
async function gr(e, r) {
|
|
1766
|
+
if (!e.resetPassword)
|
|
1767
|
+
return O("Password reset is not configured", 400);
|
|
1768
|
+
if (!r.email || typeof r.email != "string")
|
|
1769
|
+
return O("Email is required", 400);
|
|
1770
|
+
const t = await e.resetPassword(r.email);
|
|
1771
|
+
return E.json(t);
|
|
1772
|
+
}
|
|
1773
|
+
async function wr(e, r) {
|
|
1774
|
+
if (!e.verifyEmail)
|
|
1775
|
+
return O("Email verification is not configured", 400);
|
|
1776
|
+
if (!r.token || typeof r.token != "string")
|
|
1777
|
+
return O("Token is required", 400);
|
|
1778
|
+
const t = await e.verifyEmail(r.token);
|
|
1779
|
+
return E.json(t);
|
|
1780
|
+
}
|
|
1781
|
+
async function pr(e) {
|
|
1782
|
+
if (!e.refreshSession) {
|
|
1783
|
+
const t = await e.getSession();
|
|
1784
|
+
return E.json({ session: t });
|
|
1785
|
+
}
|
|
1786
|
+
const r = await e.refreshSession();
|
|
1787
|
+
return E.json({ session: r });
|
|
1788
|
+
}
|
|
1789
|
+
async function mr(e, r) {
|
|
1790
|
+
if (!e.verify2FA)
|
|
1791
|
+
return O("2FA verification is not configured", 400);
|
|
1792
|
+
if (!r.email || !r.userId || !r.code)
|
|
1793
|
+
return O("Missing required parameters. Email, userId, and code are required.", 400);
|
|
1794
|
+
const t = {
|
|
1795
|
+
email: r.email,
|
|
1796
|
+
userId: r.userId,
|
|
1797
|
+
code: r.code
|
|
1798
|
+
}, n = await e.verify2FA(t);
|
|
1799
|
+
return E.json(n);
|
|
1800
|
+
}
|
|
1801
|
+
async function Er(e, r, t, n) {
|
|
1802
|
+
if (!e.passkey)
|
|
1803
|
+
return O("PassKey is not configured", 400);
|
|
1804
|
+
const s = t[1];
|
|
1805
|
+
if (s === "register" && e.passkey.register) {
|
|
1806
|
+
const i = await e.passkey.register(n.options);
|
|
1807
|
+
return E.json(i);
|
|
1808
|
+
}
|
|
1809
|
+
if (s === "list" && e.passkey.list) {
|
|
1810
|
+
const i = await e.passkey.list();
|
|
1811
|
+
return E.json(i);
|
|
1812
|
+
}
|
|
1813
|
+
if (s === "remove" && e.passkey.remove) {
|
|
1814
|
+
if (!n.passkeyId || typeof n.passkeyId != "string")
|
|
1815
|
+
return O("Passkey ID is required", 400);
|
|
1816
|
+
const i = await e.passkey.remove(n.passkeyId);
|
|
1817
|
+
return E.json(i);
|
|
1818
|
+
}
|
|
1819
|
+
return O("Invalid Passkey request", 400);
|
|
1820
|
+
}
|
|
1821
|
+
async function yr(e, r, t) {
|
|
1822
|
+
if (!e.twoFactor)
|
|
1823
|
+
return O("Two-Factor Authentication is not configured", 400);
|
|
1824
|
+
const n = r[1];
|
|
1825
|
+
if (n === "enable" && e.twoFactor.enable) {
|
|
1826
|
+
const s = await e.twoFactor.enable();
|
|
1827
|
+
return E.json(s);
|
|
1828
|
+
}
|
|
1829
|
+
if (n === "verify" && e.twoFactor.verify) {
|
|
1830
|
+
if (!t.code || typeof t.code != "string")
|
|
1831
|
+
return O("Code is required", 400);
|
|
1832
|
+
const s = await e.twoFactor.verify(t.code);
|
|
1833
|
+
return E.json(s);
|
|
1834
|
+
}
|
|
1835
|
+
if (n === "disable" && e.twoFactor.disable) {
|
|
1836
|
+
const s = await e.twoFactor.disable();
|
|
1837
|
+
return E.json(s);
|
|
1838
|
+
}
|
|
1839
|
+
if (n === "backup-codes" && e.twoFactor.generateBackupCodes) {
|
|
1840
|
+
const s = await e.twoFactor.generateBackupCodes();
|
|
1841
|
+
return E.json(s);
|
|
1842
|
+
}
|
|
1843
|
+
if (n === "is-enabled" && e.twoFactor.isEnabled) {
|
|
1844
|
+
const s = await e.twoFactor.isEnabled();
|
|
1845
|
+
return E.json({ enabled: s });
|
|
1846
|
+
}
|
|
1847
|
+
return O("Invalid two-factor request", 400);
|
|
1848
|
+
}
|
|
1849
|
+
function O(e, r) {
|
|
1850
|
+
return E.json(
|
|
1851
|
+
{
|
|
1852
|
+
success: !1,
|
|
1853
|
+
error: e
|
|
1854
|
+
},
|
|
1855
|
+
{ status: r }
|
|
1856
|
+
);
|
|
1857
|
+
}
|
|
1858
|
+
function V(e, r) {
|
|
1859
|
+
return E.redirect(new URL(`/login?error=${encodeURIComponent(r)}`, e));
|
|
1860
|
+
}
|
|
1861
|
+
function kr(e, r) {
|
|
1862
|
+
const t = r ?? "/";
|
|
1863
|
+
return E.redirect(new URL(t, e));
|
|
1864
|
+
}
|
|
1865
|
+
function tt(e) {
|
|
1866
|
+
return async (r) => {
|
|
1867
|
+
const { method: t, nextUrl: n } = r, i = n.pathname.replace(/^\/api\/auth/, "") || "/";
|
|
1511
1868
|
try {
|
|
1512
|
-
let
|
|
1513
|
-
if (
|
|
1869
|
+
let o;
|
|
1870
|
+
if (t !== "GET" && t !== "HEAD")
|
|
1514
1871
|
try {
|
|
1515
|
-
|
|
1872
|
+
o = await r.json();
|
|
1516
1873
|
} catch {
|
|
1517
1874
|
}
|
|
1518
|
-
const a = Object.fromEntries(
|
|
1519
|
-
`${process.env.NEXT_PUBLIC_API_URL || ""}/api/auth${
|
|
1875
|
+
const a = Object.fromEntries(n.searchParams.entries()), l = await fetch(
|
|
1876
|
+
`${process.env.NEXT_PUBLIC_API_URL || ""}/api/auth${i}${Object.keys(a).length > 0 ? `?${new URLSearchParams(a).toString()}` : ""}`,
|
|
1520
1877
|
{
|
|
1521
|
-
method:
|
|
1878
|
+
method: t,
|
|
1522
1879
|
headers: {
|
|
1523
1880
|
"Content-Type": "application/json",
|
|
1524
|
-
...Object.fromEntries(
|
|
1881
|
+
...Object.fromEntries(r.headers.entries())
|
|
1525
1882
|
},
|
|
1526
|
-
body:
|
|
1883
|
+
body: o ? JSON.stringify(o) : void 0
|
|
1527
1884
|
}
|
|
1528
|
-
),
|
|
1529
|
-
return
|
|
1530
|
-
status:
|
|
1885
|
+
), f = await l.json();
|
|
1886
|
+
return E.json(f, {
|
|
1887
|
+
status: l.status,
|
|
1531
1888
|
headers: {
|
|
1532
|
-
...Object.fromEntries(
|
|
1889
|
+
...Object.fromEntries(l.headers.entries())
|
|
1533
1890
|
}
|
|
1534
1891
|
});
|
|
1535
|
-
} catch (
|
|
1536
|
-
return console.error("API handler error:",
|
|
1892
|
+
} catch (o) {
|
|
1893
|
+
return console.error("API handler error:", o), E.json(
|
|
1537
1894
|
{
|
|
1538
1895
|
success: !1,
|
|
1539
|
-
error:
|
|
1896
|
+
error: o instanceof Error ? o.message : "Internal server error"
|
|
1540
1897
|
},
|
|
1541
1898
|
{ status: 500 }
|
|
1542
1899
|
);
|
|
1543
1900
|
}
|
|
1544
1901
|
};
|
|
1545
1902
|
}
|
|
1546
|
-
function
|
|
1547
|
-
return async (
|
|
1548
|
-
const { searchParams:
|
|
1549
|
-
if (!
|
|
1550
|
-
return
|
|
1551
|
-
new URL("/login?error=oauth_missing_params",
|
|
1903
|
+
function nt(e) {
|
|
1904
|
+
return async (r) => {
|
|
1905
|
+
const { searchParams: t } = r.nextUrl, n = t.get("provider"), s = t.get("code"), i = t.get("state");
|
|
1906
|
+
if (!n || !s || !i)
|
|
1907
|
+
return E.redirect(
|
|
1908
|
+
new URL("/login?error=oauth_missing_params", r.url)
|
|
1552
1909
|
);
|
|
1553
1910
|
try {
|
|
1554
|
-
if (!
|
|
1555
|
-
return
|
|
1556
|
-
new URL("/login?error=oauth_not_configured",
|
|
1911
|
+
if (!e.oauthCallback)
|
|
1912
|
+
return E.redirect(
|
|
1913
|
+
new URL("/login?error=oauth_not_configured", r.url)
|
|
1557
1914
|
);
|
|
1558
|
-
const
|
|
1559
|
-
if (
|
|
1560
|
-
const a =
|
|
1561
|
-
return
|
|
1915
|
+
const o = await e.oauthCallback(n, s, i);
|
|
1916
|
+
if (o.success) {
|
|
1917
|
+
const a = t.get("callbackUrl") || "/";
|
|
1918
|
+
return E.redirect(new URL(a, r.url));
|
|
1562
1919
|
} else {
|
|
1563
|
-
const a =
|
|
1564
|
-
return
|
|
1565
|
-
new URL(`/login?error=${a}`,
|
|
1920
|
+
const a = o.errorCode ? `${encodeURIComponent(o.error || "oauth_failed")}&code=${o.errorCode}` : encodeURIComponent(o.error || "oauth_failed");
|
|
1921
|
+
return E.redirect(
|
|
1922
|
+
new URL(`/login?error=${a}`, r.url)
|
|
1566
1923
|
);
|
|
1567
1924
|
}
|
|
1568
|
-
} catch (
|
|
1569
|
-
return process.env.NODE_ENV === "development" && console.error("[Mulguard] OAuth callback error:",
|
|
1925
|
+
} catch (o) {
|
|
1926
|
+
return process.env.NODE_ENV === "development" && console.error("[Mulguard] OAuth callback error:", o), E.redirect(
|
|
1570
1927
|
new URL(
|
|
1571
|
-
`/login?error=${encodeURIComponent(
|
|
1572
|
-
|
|
1928
|
+
`/login?error=${encodeURIComponent(o instanceof Error ? o.message : "oauth_error")}`,
|
|
1929
|
+
r.url
|
|
1573
1930
|
)
|
|
1574
1931
|
);
|
|
1575
1932
|
}
|
|
1576
1933
|
};
|
|
1577
1934
|
}
|
|
1578
|
-
function
|
|
1579
|
-
const
|
|
1935
|
+
function F(e, r) {
|
|
1936
|
+
const t = H({
|
|
1580
1937
|
// Customize headers if needed
|
|
1581
1938
|
"X-Frame-Options": "SAMEORIGIN"
|
|
1582
1939
|
// Allow same-origin framing
|
|
1583
1940
|
});
|
|
1584
|
-
for (const [
|
|
1585
|
-
|
|
1586
|
-
return
|
|
1941
|
+
for (const [n, s] of Object.entries(t))
|
|
1942
|
+
s && typeof s == "string" && r.headers.set(n, s);
|
|
1943
|
+
return r;
|
|
1587
1944
|
}
|
|
1588
|
-
function
|
|
1589
|
-
return async (
|
|
1590
|
-
const
|
|
1591
|
-
return
|
|
1945
|
+
function st() {
|
|
1946
|
+
return async (e) => {
|
|
1947
|
+
const r = E.next();
|
|
1948
|
+
return F(e, r);
|
|
1592
1949
|
};
|
|
1593
1950
|
}
|
|
1594
|
-
function
|
|
1951
|
+
function it(e, r = {}) {
|
|
1595
1952
|
const {
|
|
1596
|
-
protectedRoutes:
|
|
1597
|
-
publicRoutes:
|
|
1598
|
-
redirectTo:
|
|
1599
|
-
redirectIfAuthenticated:
|
|
1600
|
-
} =
|
|
1601
|
-
return async (
|
|
1602
|
-
const { pathname: a } =
|
|
1603
|
-
let
|
|
1953
|
+
protectedRoutes: t = [],
|
|
1954
|
+
publicRoutes: n = [],
|
|
1955
|
+
redirectTo: s = "/login",
|
|
1956
|
+
redirectIfAuthenticated: i
|
|
1957
|
+
} = r;
|
|
1958
|
+
return async (o) => {
|
|
1959
|
+
const { pathname: a } = o.nextUrl, l = t.some((g) => a.startsWith(g));
|
|
1960
|
+
let f = null;
|
|
1604
1961
|
try {
|
|
1605
|
-
|
|
1962
|
+
f = await e.getSession();
|
|
1606
1963
|
} catch (g) {
|
|
1607
1964
|
console.error("Middleware: Failed to get session:", g);
|
|
1608
1965
|
}
|
|
1609
|
-
if (
|
|
1610
|
-
const g =
|
|
1611
|
-
return g.pathname =
|
|
1966
|
+
if (l && !f) {
|
|
1967
|
+
const g = o.nextUrl.clone();
|
|
1968
|
+
return g.pathname = s, g.searchParams.set("callbackUrl", a), E.redirect(g);
|
|
1612
1969
|
}
|
|
1613
|
-
if (
|
|
1614
|
-
const A =
|
|
1615
|
-
A.pathname =
|
|
1616
|
-
const
|
|
1617
|
-
return
|
|
1970
|
+
if (i && f && (a.startsWith("/login") || a.startsWith("/register"))) {
|
|
1971
|
+
const A = o.nextUrl.clone();
|
|
1972
|
+
A.pathname = i;
|
|
1973
|
+
const S = E.redirect(A);
|
|
1974
|
+
return F(o, S);
|
|
1618
1975
|
}
|
|
1619
|
-
const
|
|
1620
|
-
return
|
|
1976
|
+
const w = E.next();
|
|
1977
|
+
return F(o, w);
|
|
1621
1978
|
};
|
|
1622
1979
|
}
|
|
1623
|
-
async function
|
|
1624
|
-
var
|
|
1980
|
+
async function ot(e, r) {
|
|
1981
|
+
var t;
|
|
1625
1982
|
try {
|
|
1626
|
-
const
|
|
1627
|
-
return
|
|
1983
|
+
const n = await e.getSession();
|
|
1984
|
+
return n ? ((t = n.user.roles) == null ? void 0 : t.includes(r)) ?? !1 : !1;
|
|
1628
1985
|
} catch {
|
|
1629
1986
|
return !1;
|
|
1630
1987
|
}
|
|
1631
1988
|
}
|
|
1632
|
-
function
|
|
1989
|
+
function at(e) {
|
|
1633
1990
|
const {
|
|
1634
|
-
auth:
|
|
1635
|
-
protectedRoutes:
|
|
1636
|
-
publicRoutes:
|
|
1637
|
-
redirectTo:
|
|
1638
|
-
redirectIfAuthenticated:
|
|
1639
|
-
apiPrefix:
|
|
1640
|
-
} =
|
|
1991
|
+
auth: r,
|
|
1992
|
+
protectedRoutes: t = [],
|
|
1993
|
+
publicRoutes: n = [],
|
|
1994
|
+
redirectTo: s = "/login",
|
|
1995
|
+
redirectIfAuthenticated: i,
|
|
1996
|
+
apiPrefix: o = "/api/auth"
|
|
1997
|
+
} = e;
|
|
1641
1998
|
return async (a) => {
|
|
1642
|
-
const { pathname:
|
|
1643
|
-
if (
|
|
1644
|
-
const A =
|
|
1645
|
-
return
|
|
1999
|
+
const { pathname: l } = a.nextUrl;
|
|
2000
|
+
if (l.startsWith(o)) {
|
|
2001
|
+
const A = E.next();
|
|
2002
|
+
return F(a, A);
|
|
1646
2003
|
}
|
|
1647
|
-
const
|
|
1648
|
-
let
|
|
1649
|
-
if (
|
|
2004
|
+
const f = t.some((A) => l.startsWith(A));
|
|
2005
|
+
let w = null;
|
|
2006
|
+
if (f || i)
|
|
1650
2007
|
try {
|
|
1651
|
-
|
|
2008
|
+
w = await r.getSession();
|
|
1652
2009
|
} catch (A) {
|
|
1653
2010
|
console.error("Middleware: Failed to get session:", A);
|
|
1654
2011
|
}
|
|
1655
|
-
if (
|
|
2012
|
+
if (f && !w) {
|
|
1656
2013
|
const A = a.nextUrl.clone();
|
|
1657
|
-
A.pathname =
|
|
1658
|
-
const
|
|
1659
|
-
return
|
|
2014
|
+
A.pathname = s, A.searchParams.set("callbackUrl", l);
|
|
2015
|
+
const S = E.redirect(A);
|
|
2016
|
+
return F(a, S);
|
|
1660
2017
|
}
|
|
1661
|
-
if (
|
|
1662
|
-
const
|
|
1663
|
-
|
|
1664
|
-
const
|
|
1665
|
-
return
|
|
2018
|
+
if (i && w && (l.startsWith("/login") || l.startsWith("/register"))) {
|
|
2019
|
+
const S = a.nextUrl.clone();
|
|
2020
|
+
S.pathname = i;
|
|
2021
|
+
const v = E.redirect(S);
|
|
2022
|
+
return F(a, v);
|
|
1666
2023
|
}
|
|
1667
|
-
const g =
|
|
1668
|
-
return
|
|
2024
|
+
const g = E.next();
|
|
2025
|
+
return F(a, g);
|
|
1669
2026
|
};
|
|
1670
2027
|
}
|
|
1671
|
-
async function
|
|
1672
|
-
var
|
|
2028
|
+
async function ct(e, r) {
|
|
2029
|
+
var t;
|
|
1673
2030
|
try {
|
|
1674
|
-
const
|
|
1675
|
-
return
|
|
2031
|
+
const n = await e.getSession();
|
|
2032
|
+
return n ? ((t = n.user.roles) == null ? void 0 : t.includes(r)) ?? !1 : !1;
|
|
1676
2033
|
} catch {
|
|
1677
2034
|
return !1;
|
|
1678
2035
|
}
|
|
1679
2036
|
}
|
|
1680
2037
|
export {
|
|
1681
|
-
|
|
1682
|
-
|
|
1683
|
-
|
|
1684
|
-
|
|
1685
|
-
|
|
1686
|
-
|
|
1687
|
-
|
|
1688
|
-
|
|
1689
|
-
|
|
1690
|
-
|
|
1691
|
-
|
|
1692
|
-
|
|
1693
|
-
|
|
1694
|
-
|
|
1695
|
-
|
|
1696
|
-
|
|
1697
|
-
|
|
1698
|
-
|
|
1699
|
-
|
|
1700
|
-
|
|
1701
|
-
|
|
1702
|
-
|
|
1703
|
-
|
|
1704
|
-
|
|
1705
|
-
|
|
1706
|
-
|
|
1707
|
-
|
|
1708
|
-
|
|
1709
|
-
|
|
1710
|
-
|
|
1711
|
-
|
|
1712
|
-
|
|
1713
|
-
|
|
1714
|
-
|
|
1715
|
-
|
|
1716
|
-
|
|
1717
|
-
|
|
1718
|
-
|
|
1719
|
-
|
|
1720
|
-
|
|
1721
|
-
|
|
1722
|
-
|
|
1723
|
-
|
|
1724
|
-
|
|
1725
|
-
|
|
1726
|
-
|
|
1727
|
-
|
|
1728
|
-
|
|
1729
|
-
|
|
1730
|
-
|
|
1731
|
-
|
|
1732
|
-
|
|
1733
|
-
|
|
1734
|
-
|
|
1735
|
-
|
|
1736
|
-
|
|
1737
|
-
|
|
1738
|
-
|
|
1739
|
-
|
|
1740
|
-
|
|
1741
|
-
|
|
1742
|
-
|
|
1743
|
-
|
|
1744
|
-
|
|
1745
|
-
|
|
1746
|
-
|
|
1747
|
-
|
|
1748
|
-
|
|
1749
|
-
|
|
1750
|
-
|
|
1751
|
-
|
|
1752
|
-
|
|
1753
|
-
|
|
1754
|
-
|
|
1755
|
-
|
|
2038
|
+
Te as CSRFProtection,
|
|
2039
|
+
fe as DEFAULT_SECURITY_HEADERS,
|
|
2040
|
+
Oe as MemoryCSRFStore,
|
|
2041
|
+
ze as MemoryOAuthStateStore,
|
|
2042
|
+
le as RateLimiter,
|
|
2043
|
+
Tr as applySecurityHeaders,
|
|
2044
|
+
oe as buildCookieOptions,
|
|
2045
|
+
be as buildOAuthAuthorizationUrl,
|
|
2046
|
+
ot as checkRole,
|
|
2047
|
+
ct as checkRoleProxy,
|
|
2048
|
+
Vr as containsXSSPattern,
|
|
2049
|
+
tt as createApiHandler,
|
|
2050
|
+
it as createAuthMiddleware,
|
|
2051
|
+
Dr as createCSRFProtection,
|
|
2052
|
+
$e as createMemoryOAuthStateStore,
|
|
2053
|
+
nt as createOAuthCallbackHandler,
|
|
2054
|
+
at as createProxyMiddleware,
|
|
2055
|
+
Or as createRateLimiter,
|
|
2056
|
+
Zr as createRedisOAuthStateStore,
|
|
2057
|
+
st as createSecurityMiddleware,
|
|
2058
|
+
pt as createServerAuthMiddleware,
|
|
2059
|
+
mt as createServerHelpers,
|
|
2060
|
+
Et as createServerUtils,
|
|
2061
|
+
yt as createSessionManager,
|
|
2062
|
+
ie as deleteCookie,
|
|
2063
|
+
kt as deleteOAuthStateCookie,
|
|
2064
|
+
Ie as escapeHTML,
|
|
2065
|
+
Ue as exchangeOAuthCode,
|
|
2066
|
+
_e as generateCSRFToken,
|
|
2067
|
+
Y as generateToken,
|
|
2068
|
+
ce as getCookie,
|
|
2069
|
+
vt as getCurrentUser,
|
|
2070
|
+
Br as getErrorCode,
|
|
2071
|
+
qr as getErrorMessage,
|
|
2072
|
+
St as getOAuthStateCookie,
|
|
2073
|
+
Fe as getOAuthUserInfo,
|
|
2074
|
+
j as getProviderMetadata,
|
|
2075
|
+
H as getSecurityHeaders,
|
|
2076
|
+
Rt as getServerSession,
|
|
2077
|
+
At as getSessionTimeUntilExpiry,
|
|
2078
|
+
Xr as getUserFriendlyError,
|
|
2079
|
+
Gr as hasErrorCode,
|
|
2080
|
+
Ce as isAuthError,
|
|
2081
|
+
Hr as isAuthSuccess,
|
|
2082
|
+
Qr as isOAuthProviderConfig,
|
|
2083
|
+
Kr as isRetryableError,
|
|
2084
|
+
Ot as isSessionExpiredNullable,
|
|
2085
|
+
Tt as isSessionExpiringSoon,
|
|
2086
|
+
It as isSessionValid,
|
|
2087
|
+
Yr as isSupportedProvider,
|
|
2088
|
+
Wr as isTwoFactorRequired,
|
|
2089
|
+
jr as isValidCSRFToken,
|
|
2090
|
+
$r as isValidEmail,
|
|
2091
|
+
xr as isValidInput,
|
|
2092
|
+
Cr as isValidName,
|
|
2093
|
+
_r as isValidPassword,
|
|
2094
|
+
Fr as isValidToken,
|
|
2095
|
+
Ur as isValidURL,
|
|
2096
|
+
et as mulguard,
|
|
2097
|
+
_t as refreshSession,
|
|
2098
|
+
Pt as requireAuth,
|
|
2099
|
+
Ct as requireRole,
|
|
2100
|
+
bt as requireServerAuthMiddleware,
|
|
2101
|
+
Ut as requireServerRoleMiddleware,
|
|
2102
|
+
Lr as sanitizeHTML,
|
|
2103
|
+
zr as sanitizeInput,
|
|
2104
|
+
Mr as sanitizeUserInput,
|
|
2105
|
+
ae as setCookie,
|
|
2106
|
+
Jr as signIn,
|
|
2107
|
+
ft as signInEmailAction,
|
|
2108
|
+
dt as signOutAction,
|
|
2109
|
+
ht as signUpAction,
|
|
2110
|
+
Nt as storeOAuthStateCookie,
|
|
2111
|
+
rt as toNextJsHandler,
|
|
2112
|
+
G as validateAndSanitizeEmail,
|
|
2113
|
+
X as validateAndSanitizeInput,
|
|
2114
|
+
Pr as validateAndSanitizeName,
|
|
2115
|
+
Ir as validateAndSanitizePassword,
|
|
2116
|
+
Q as validateCSRFToken,
|
|
2117
|
+
N as validateSessionStructure,
|
|
2118
|
+
Nr as validateToken,
|
|
2119
|
+
br as validateURL,
|
|
2120
|
+
gt as verify2FAAction,
|
|
2121
|
+
F as withSecurityHeaders
|
|
1756
2122
|
};
|