mulguard 1.1.1 → 1.1.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +34 -0
- package/dist/core/auth/oauth-providers.d.ts +175 -47
- 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 +399 -306
- 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 +1540 -1190
- 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 lt, s as ft, b as dt, v as ht } from "../actions-DeCfLtHA.mjs";
|
|
6
|
+
import { v as N } from "../oauth-state-LE-qeq-K.mjs";
|
|
7
|
+
import { c as wt, p as pt, k as mt, n as Et, m as yt, j as kt, l as vt, e as St, g as Rt, b as At, i as Tt, a as It, o as Ot, f as _t, h as Pt, r as Ct, d as bt, s as Ut } 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 Tr(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 Ir(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 Or(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 Te {
|
|
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 Ie {
|
|
210
|
+
constructor(r, t = 32) {
|
|
211
|
+
U(this, "store");
|
|
212
|
+
U(this, "tokenLength");
|
|
213
|
+
this.store = r || new Te(), 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 Ie(e);
|
|
207
247
|
}
|
|
208
|
-
function
|
|
209
|
-
if (typeof
|
|
248
|
+
function Oe(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 Vr(e) {
|
|
264
|
+
return typeof e != "string" ? "" : Oe(e.trim());
|
|
225
265
|
}
|
|
226
|
-
function
|
|
227
|
-
return typeof
|
|
266
|
+
function Mr(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,249 +393,382 @@ 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
|
-
...i.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 [f, l] of Object.entries(s.defaultParams))
|
|
417
|
+
a.append(f, l);
|
|
418
|
+
if (r.params)
|
|
419
|
+
for (const [f, l] of Object.entries(r.params))
|
|
420
|
+
a.set(f, l);
|
|
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 f = await o.text();
|
|
449
|
+
let l = `Failed to exchange code for tokens: ${f}`;
|
|
450
|
+
try {
|
|
451
|
+
const w = JSON.parse(f);
|
|
452
|
+
l = w.error_description ?? w.error ?? l;
|
|
453
|
+
} catch {
|
|
454
|
+
}
|
|
455
|
+
throw new Error(l);
|
|
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: i.sub || i.id,
|
|
412
|
-
email: i.email,
|
|
413
|
-
name: i.name,
|
|
414
|
-
avatar: i.picture,
|
|
415
|
-
emailVerified: i.email_verified
|
|
416
|
-
};
|
|
500
|
+
return De(r);
|
|
417
501
|
case "github":
|
|
418
|
-
|
|
419
|
-
if (!v) {
|
|
420
|
-
const g = await (await fetch("https://api.github.com/user/emails", {
|
|
421
|
-
headers: { Authorization: `Bearer ${e}` }
|
|
422
|
-
})).json();
|
|
423
|
-
v = ((d = g.find((A) => A.primary)) == null ? void 0 : d.email) || ((c = g[0]) == null ? void 0 : c.email) || `${i.login}@users.noreply.github.com`;
|
|
424
|
-
}
|
|
425
|
-
return {
|
|
426
|
-
id: String(i.id),
|
|
427
|
-
email: v,
|
|
428
|
-
name: i.name || i.login,
|
|
429
|
-
avatar: i.avatar_url,
|
|
430
|
-
emailVerified: !!v
|
|
431
|
-
};
|
|
502
|
+
return await Le(r, t);
|
|
432
503
|
case "apple":
|
|
433
|
-
return
|
|
434
|
-
id: i.sub,
|
|
435
|
-
email: i.email,
|
|
436
|
-
name: i.name ? `${i.name.firstName} ${i.name.lastName}` : "",
|
|
437
|
-
emailVerified: i.email_verified
|
|
438
|
-
};
|
|
504
|
+
return Ve(r);
|
|
439
505
|
case "facebook":
|
|
440
|
-
return
|
|
441
|
-
id: i.id,
|
|
442
|
-
email: i.email,
|
|
443
|
-
name: i.name,
|
|
444
|
-
avatar: (p = (a = i.picture) == null ? void 0 : a.data) == null ? void 0 : p.url,
|
|
445
|
-
emailVerified: !0
|
|
446
|
-
};
|
|
506
|
+
return Me(r);
|
|
447
507
|
default:
|
|
448
|
-
return
|
|
449
|
-
id: String(i.id || i.sub),
|
|
450
|
-
email: i.email,
|
|
451
|
-
name: i.name || i.display_name || i.username,
|
|
452
|
-
avatar: i.avatar || i.picture || i.avatar_url,
|
|
453
|
-
emailVerified: i.email_verified || i.emailVerified || !1
|
|
454
|
-
};
|
|
508
|
+
return je(r);
|
|
455
509
|
}
|
|
456
510
|
}
|
|
457
|
-
|
|
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 Ve(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 Me(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 {
|
|
458
581
|
constructor() {
|
|
459
|
-
|
|
582
|
+
U(this, "states", /* @__PURE__ */ new Map());
|
|
460
583
|
}
|
|
461
|
-
set(
|
|
462
|
-
this.states.set(
|
|
584
|
+
set(r, t, n) {
|
|
585
|
+
this.states.set(r, t), this.cleanup();
|
|
463
586
|
}
|
|
464
|
-
get(
|
|
465
|
-
const
|
|
466
|
-
return
|
|
587
|
+
get(r) {
|
|
588
|
+
const t = this.states.get(r);
|
|
589
|
+
return t ? t.expiresAt < Date.now() ? (this.delete(r), null) : t : null;
|
|
467
590
|
}
|
|
468
|
-
delete(
|
|
469
|
-
this.states.delete(
|
|
591
|
+
delete(r) {
|
|
592
|
+
this.states.delete(r);
|
|
470
593
|
}
|
|
471
594
|
cleanup() {
|
|
472
|
-
const
|
|
473
|
-
for (const [
|
|
474
|
-
|
|
595
|
+
const r = Date.now();
|
|
596
|
+
for (const [t, n] of this.states.entries())
|
|
597
|
+
n.expiresAt < r && this.states.delete(t);
|
|
475
598
|
}
|
|
476
599
|
}
|
|
477
|
-
function
|
|
478
|
-
return new
|
|
600
|
+
function $e() {
|
|
601
|
+
return new ze();
|
|
479
602
|
}
|
|
480
|
-
function
|
|
481
|
-
|
|
603
|
+
function D(e) {
|
|
604
|
+
return e.success === !0 && e.user !== void 0 && e.session !== void 0;
|
|
605
|
+
}
|
|
606
|
+
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 || {});
|
|
607
|
+
const We = process.env.NODE_ENV === "development" ? 0 : 1;
|
|
608
|
+
function qe(e = {}) {
|
|
609
|
+
const {
|
|
610
|
+
enabled: r = process.env.NODE_ENV === "development",
|
|
611
|
+
level: t = We,
|
|
612
|
+
context: n,
|
|
613
|
+
formatter: s = Be
|
|
614
|
+
} = e, i = (a) => r && a >= t, o = (a, f, l, w) => ({
|
|
615
|
+
level: a,
|
|
616
|
+
message: f,
|
|
617
|
+
timestamp: /* @__PURE__ */ new Date(),
|
|
618
|
+
context: n,
|
|
619
|
+
data: l ? He(l) : void 0,
|
|
620
|
+
error: w
|
|
621
|
+
});
|
|
482
622
|
return {
|
|
483
|
-
debug:
|
|
484
|
-
|
|
485
|
-
|
|
623
|
+
debug: (a, f) => {
|
|
624
|
+
if (i(
|
|
625
|
+
0
|
|
626
|
+
/* DEBUG */
|
|
627
|
+
)) {
|
|
628
|
+
const l = o(0, a, f);
|
|
629
|
+
console.debug(s(l));
|
|
630
|
+
}
|
|
486
631
|
},
|
|
487
|
-
info:
|
|
488
|
-
|
|
489
|
-
|
|
632
|
+
info: (a, f) => {
|
|
633
|
+
if (i(
|
|
634
|
+
1
|
|
635
|
+
/* INFO */
|
|
636
|
+
)) {
|
|
637
|
+
const l = o(1, a, f);
|
|
638
|
+
console.info(s(l));
|
|
639
|
+
}
|
|
490
640
|
},
|
|
491
|
-
warn:
|
|
492
|
-
|
|
493
|
-
|
|
641
|
+
warn: (a, f) => {
|
|
642
|
+
if (i(
|
|
643
|
+
2
|
|
644
|
+
/* WARN */
|
|
645
|
+
)) {
|
|
646
|
+
const l = o(2, a, f);
|
|
647
|
+
console.warn(s(l));
|
|
648
|
+
}
|
|
494
649
|
},
|
|
495
|
-
error:
|
|
496
|
-
|
|
497
|
-
|
|
650
|
+
error: (a, f) => {
|
|
651
|
+
if (i(
|
|
652
|
+
3
|
|
653
|
+
/* ERROR */
|
|
654
|
+
)) {
|
|
655
|
+
const l = f instanceof Error ? f : void 0, w = f instanceof Error ? void 0 : f, g = o(3, a, w, l);
|
|
656
|
+
console.error(s(g)), l && console.error(l);
|
|
657
|
+
}
|
|
498
658
|
}
|
|
499
659
|
};
|
|
500
660
|
}
|
|
501
|
-
|
|
502
|
-
|
|
661
|
+
function Be(e) {
|
|
662
|
+
const r = e.timestamp.toISOString(), t = ee[e.level], n = e.context ? `[${e.context}]` : "", s = e.data ? ` ${JSON.stringify(e.data)}` : "";
|
|
663
|
+
return `${r} [${t}]${n} ${e.message}${s}`;
|
|
664
|
+
}
|
|
665
|
+
function He(e) {
|
|
666
|
+
const r = /* @__PURE__ */ new Set(["password", "token", "secret", "key", "accessToken", "refreshToken"]), t = {};
|
|
667
|
+
for (const [n, s] of Object.entries(e))
|
|
668
|
+
if (r.has(n.toLowerCase()))
|
|
669
|
+
t[n] = "***REDACTED***";
|
|
670
|
+
else if (typeof s == "string" && n.toLowerCase().includes("email")) {
|
|
671
|
+
const i = s.split("@");
|
|
672
|
+
if (i.length === 2 && i[0]) {
|
|
673
|
+
const o = i[0].substring(0, 3) + "***@" + i[1];
|
|
674
|
+
t[n] = o;
|
|
675
|
+
} else
|
|
676
|
+
t[n] = s;
|
|
677
|
+
} else
|
|
678
|
+
t[n] = s;
|
|
679
|
+
return t;
|
|
680
|
+
}
|
|
681
|
+
const O = qe();
|
|
682
|
+
function Ge(e, r, t, n = {}) {
|
|
503
683
|
const {
|
|
504
|
-
enabled:
|
|
505
|
-
maxRetries:
|
|
506
|
-
retryDelay:
|
|
684
|
+
enabled: s = !0,
|
|
685
|
+
maxRetries: i = 1,
|
|
686
|
+
retryDelay: o = 1e3,
|
|
507
687
|
rateLimit: a = 3,
|
|
508
|
-
autoSignOutOnFailure:
|
|
509
|
-
redirectToLogin:
|
|
510
|
-
autoRedirectOnFailure:
|
|
511
|
-
} =
|
|
688
|
+
autoSignOutOnFailure: f = !0,
|
|
689
|
+
redirectToLogin: l = "/login",
|
|
690
|
+
autoRedirectOnFailure: w = !0
|
|
691
|
+
} = n;
|
|
512
692
|
let g = null, A = !1;
|
|
513
|
-
const
|
|
514
|
-
let
|
|
515
|
-
const
|
|
516
|
-
function
|
|
517
|
-
const
|
|
518
|
-
if (I &&
|
|
519
|
-
if (
|
|
693
|
+
const S = [], v = [], y = 60 * 1e3;
|
|
694
|
+
let h = 0, I = !1, _ = null;
|
|
695
|
+
const L = 2, V = 60 * 1e3;
|
|
696
|
+
function c() {
|
|
697
|
+
const k = Date.now();
|
|
698
|
+
if (I && _) {
|
|
699
|
+
if (k < _)
|
|
520
700
|
return !1;
|
|
521
|
-
I = !1,
|
|
701
|
+
I = !1, _ = null, h = 0;
|
|
522
702
|
}
|
|
523
|
-
for (;
|
|
524
|
-
const
|
|
525
|
-
if (
|
|
526
|
-
|
|
703
|
+
for (; v.length > 0; ) {
|
|
704
|
+
const p = v[0];
|
|
705
|
+
if (p !== void 0 && p < k - y)
|
|
706
|
+
v.shift();
|
|
527
707
|
else
|
|
528
708
|
break;
|
|
529
709
|
}
|
|
530
|
-
return
|
|
531
|
-
}
|
|
532
|
-
function o() {
|
|
533
|
-
_++, _ >= D && (I = !0, C = Date.now() + V, process.env.NODE_ENV === "development" && console.warn("[TokenRefreshManager] Circuit breaker opened - too many consecutive failures"));
|
|
710
|
+
return v.length >= a ? !1 : (v.push(k), !0);
|
|
534
711
|
}
|
|
535
712
|
function u() {
|
|
536
|
-
|
|
713
|
+
h++, h >= L && (I = !0, _ = Date.now() + V, process.env.NODE_ENV === "development" && console.warn("[TokenRefreshManager] Circuit breaker opened - too many consecutive failures"));
|
|
537
714
|
}
|
|
538
|
-
|
|
539
|
-
|
|
715
|
+
function d() {
|
|
716
|
+
h = 0, I = !1, _ = null;
|
|
717
|
+
}
|
|
718
|
+
async function R(k = 1) {
|
|
719
|
+
if (!s)
|
|
540
720
|
return null;
|
|
541
|
-
if (!
|
|
721
|
+
if (!c())
|
|
542
722
|
throw new Error("Rate limit exceeded for token refresh");
|
|
543
723
|
try {
|
|
544
|
-
const
|
|
545
|
-
if (
|
|
546
|
-
return
|
|
547
|
-
if (
|
|
548
|
-
return await
|
|
724
|
+
const p = await e();
|
|
725
|
+
if (p)
|
|
726
|
+
return d(), P(p), n.onTokenRefreshed && await Promise.resolve(n.onTokenRefreshed(p)), p;
|
|
727
|
+
if (u(), k < i)
|
|
728
|
+
return await $(o * k), R(k + 1);
|
|
549
729
|
throw new Error("Token refresh failed: refresh function returned null");
|
|
550
|
-
} catch (
|
|
551
|
-
if (
|
|
552
|
-
return await
|
|
553
|
-
throw
|
|
730
|
+
} catch (p) {
|
|
731
|
+
if (u(), k < i && C(p))
|
|
732
|
+
return await $(o * k), R(k + 1);
|
|
733
|
+
throw p;
|
|
554
734
|
}
|
|
555
735
|
}
|
|
556
|
-
function
|
|
557
|
-
if (
|
|
558
|
-
const
|
|
559
|
-
if (
|
|
736
|
+
function C(k) {
|
|
737
|
+
if (k instanceof Error) {
|
|
738
|
+
const p = k.message.toLowerCase();
|
|
739
|
+
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"))
|
|
560
740
|
return !1;
|
|
561
|
-
if (
|
|
741
|
+
if (p.includes("network") || p.includes("fetch") || p.includes("timeout"))
|
|
562
742
|
return !0;
|
|
563
743
|
}
|
|
564
744
|
return !1;
|
|
565
745
|
}
|
|
566
|
-
function
|
|
567
|
-
const
|
|
568
|
-
|
|
569
|
-
for (const { resolve:
|
|
570
|
-
|
|
746
|
+
function P(k) {
|
|
747
|
+
const p = [...S];
|
|
748
|
+
S.length = 0;
|
|
749
|
+
for (const { resolve: b } of p)
|
|
750
|
+
b(k);
|
|
571
751
|
}
|
|
572
|
-
function
|
|
573
|
-
const
|
|
574
|
-
|
|
575
|
-
for (const { reject:
|
|
576
|
-
|
|
752
|
+
function z(k) {
|
|
753
|
+
const p = [...S];
|
|
754
|
+
S.length = 0;
|
|
755
|
+
for (const { reject: b } of p)
|
|
756
|
+
b(k);
|
|
577
757
|
}
|
|
578
|
-
function
|
|
579
|
-
return new Promise((
|
|
758
|
+
function $(k) {
|
|
759
|
+
return new Promise((p) => setTimeout(p, k));
|
|
580
760
|
}
|
|
581
|
-
async function k
|
|
761
|
+
async function W(k) {
|
|
582
762
|
try {
|
|
583
|
-
if (
|
|
584
|
-
let
|
|
585
|
-
if (
|
|
586
|
-
const
|
|
587
|
-
|
|
763
|
+
if (n.onTokenRefreshFailed && await Promise.resolve(n.onTokenRefreshFailed(k)), f && (await t(), await r(), w && typeof window < "u")) {
|
|
764
|
+
let p = !0;
|
|
765
|
+
if (n.onBeforeRedirect && (p = await Promise.resolve(n.onBeforeRedirect(k))), p) {
|
|
766
|
+
const b = new URL(l, window.location.origin);
|
|
767
|
+
b.searchParams.set("reason", "session_expired"), b.searchParams.set("redirect", window.location.pathname + window.location.search), window.location.href = b.toString();
|
|
588
768
|
}
|
|
589
769
|
}
|
|
590
|
-
} catch (
|
|
591
|
-
process.env.NODE_ENV === "development" && console.error("[TokenRefreshManager] Error in handleRefreshFailure:",
|
|
770
|
+
} catch (p) {
|
|
771
|
+
process.env.NODE_ENV === "development" && console.error("[TokenRefreshManager] Error in handleRefreshFailure:", p);
|
|
592
772
|
}
|
|
593
773
|
}
|
|
594
774
|
return {
|
|
@@ -596,9 +776,9 @@ function he(r, e, s, t = {}) {
|
|
|
596
776
|
* Refresh token with single refresh queue
|
|
597
777
|
*/
|
|
598
778
|
async refreshToken() {
|
|
599
|
-
return
|
|
600
|
-
throw A = !1, g = null,
|
|
601
|
-
}),
|
|
779
|
+
return s ? g || (A = !0, g = R().then((k) => (A = !1, g = null, k)).catch((k) => {
|
|
780
|
+
throw A = !1, g = null, z(k), W(k).catch(() => {
|
|
781
|
+
}), k;
|
|
602
782
|
}), g) : null;
|
|
603
783
|
},
|
|
604
784
|
/**
|
|
@@ -611,38 +791,38 @@ function he(r, e, s, t = {}) {
|
|
|
611
791
|
* Wait for current refresh to complete
|
|
612
792
|
*/
|
|
613
793
|
async waitForRefresh() {
|
|
614
|
-
return g ? new Promise((
|
|
615
|
-
|
|
794
|
+
return g ? new Promise((k, p) => {
|
|
795
|
+
S.push({ resolve: k, reject: p });
|
|
616
796
|
}) : null;
|
|
617
797
|
},
|
|
618
798
|
/**
|
|
619
799
|
* Clear state
|
|
620
800
|
*/
|
|
621
801
|
clear() {
|
|
622
|
-
g = null, A = !1,
|
|
802
|
+
g = null, A = !1, v.length = 0, d(), z(new Error("Token refresh manager cleared"));
|
|
623
803
|
},
|
|
624
804
|
/**
|
|
625
805
|
* Handle token refresh failure
|
|
626
806
|
*/
|
|
627
|
-
async handleRefreshFailure(
|
|
628
|
-
return k
|
|
807
|
+
async handleRefreshFailure(k) {
|
|
808
|
+
return W(k);
|
|
629
809
|
}
|
|
630
810
|
};
|
|
631
811
|
}
|
|
632
|
-
function
|
|
633
|
-
const
|
|
812
|
+
function Ke() {
|
|
813
|
+
const e = process.env.NODE_ENV === "production";
|
|
634
814
|
return {
|
|
635
815
|
cookieName: "__mulguard_session",
|
|
636
816
|
expiresIn: 60 * 60 * 24 * 7,
|
|
637
817
|
// 7 days
|
|
638
818
|
httpOnly: !0,
|
|
639
|
-
secure:
|
|
819
|
+
secure: e,
|
|
640
820
|
// HTTPS only in production
|
|
641
821
|
sameSite: "lax",
|
|
642
822
|
path: "/"
|
|
643
823
|
};
|
|
644
824
|
}
|
|
645
|
-
function
|
|
825
|
+
function Xe() {
|
|
646
826
|
return {
|
|
647
827
|
enabled: !0,
|
|
648
828
|
refreshThreshold: 300,
|
|
@@ -657,372 +837,568 @@ function pe() {
|
|
|
657
837
|
autoRedirectOnFailure: !0
|
|
658
838
|
};
|
|
659
839
|
}
|
|
660
|
-
function
|
|
661
|
-
|
|
662
|
-
|
|
663
|
-
|
|
664
|
-
|
|
665
|
-
|
|
666
|
-
|
|
667
|
-
|
|
668
|
-
|
|
669
|
-
|
|
670
|
-
|
|
671
|
-
|
|
672
|
-
|
|
673
|
-
|
|
674
|
-
|
|
675
|
-
|
|
676
|
-
|
|
677
|
-
|
|
678
|
-
|
|
679
|
-
|
|
840
|
+
function Je() {
|
|
841
|
+
return process.env.NEXT_PUBLIC_URL ?? (process.env.VERCEL_URL ? `https://${process.env.VERCEL_URL}` : "http://localhost:3000");
|
|
842
|
+
}
|
|
843
|
+
function Ye(e) {
|
|
844
|
+
const { sessionConfig: r, cacheTtl: t, getSessionAction: n, onSessionExpired: s, onError: i } = e, o = r.cookieName ?? "__mulguard_session";
|
|
845
|
+
let a = null;
|
|
846
|
+
const f = async () => {
|
|
847
|
+
const y = Date.now();
|
|
848
|
+
if (a && y - a.timestamp < t)
|
|
849
|
+
return a.session;
|
|
850
|
+
if (n)
|
|
851
|
+
try {
|
|
852
|
+
const h = await n();
|
|
853
|
+
if (h && N(h))
|
|
854
|
+
return a = { session: h, timestamp: y }, h;
|
|
855
|
+
h && !N(h) && (await w(), a = null);
|
|
856
|
+
} catch (h) {
|
|
857
|
+
O.debug("getSession error", { error: h }), i && await i(h instanceof Error ? h : new Error(String(h)), "getSession"), a = null;
|
|
858
|
+
}
|
|
859
|
+
try {
|
|
860
|
+
const h = await ce(o);
|
|
861
|
+
if (h)
|
|
862
|
+
try {
|
|
863
|
+
const I = JSON.parse(h);
|
|
864
|
+
if (N(I))
|
|
865
|
+
return I.expiresAt && new Date(I.expiresAt) < /* @__PURE__ */ new Date() ? (s && await s(I), await w(), a = null, null) : (a = { session: I, timestamp: y }, I);
|
|
866
|
+
await w(), a = null;
|
|
867
|
+
} catch {
|
|
868
|
+
await w(), a = null;
|
|
869
|
+
}
|
|
870
|
+
} catch (h) {
|
|
871
|
+
const I = h instanceof Error ? h.message : String(h);
|
|
872
|
+
!I.includes("request scope") && !I.includes("cookies") && (O.warn("getSession cookie error", { error: h }), i && await i(
|
|
873
|
+
h instanceof Error ? h : new Error(String(h)),
|
|
874
|
+
"getSession.cookie"
|
|
875
|
+
));
|
|
876
|
+
}
|
|
877
|
+
return null;
|
|
878
|
+
}, l = async (y) => {
|
|
879
|
+
if (!N(y))
|
|
880
|
+
return {
|
|
881
|
+
success: !1,
|
|
882
|
+
error: "Invalid session structure"
|
|
883
|
+
};
|
|
884
|
+
try {
|
|
885
|
+
const h = typeof y == "object" && "token" in y ? String(y.token) : JSON.stringify(y), I = oe(o, h, r), _ = await ae(I);
|
|
886
|
+
return _.success && (a = { session: y, timestamp: Date.now() }), _;
|
|
887
|
+
} catch (h) {
|
|
888
|
+
const I = h instanceof Error ? h.message : "Failed to set session";
|
|
889
|
+
return O.error("setSession error", { error: h }), i && await i(h instanceof Error ? h : new Error(String(h)), "setSession"), {
|
|
890
|
+
success: !1,
|
|
891
|
+
error: I
|
|
892
|
+
};
|
|
893
|
+
}
|
|
894
|
+
}, w = async () => {
|
|
895
|
+
try {
|
|
896
|
+
await ie(o, {
|
|
897
|
+
path: r.path,
|
|
898
|
+
domain: r.domain
|
|
899
|
+
}), a = null;
|
|
900
|
+
} catch (y) {
|
|
901
|
+
O.warn("clearSessionCookie error", { error: y });
|
|
902
|
+
}
|
|
903
|
+
}, g = async () => {
|
|
904
|
+
const y = await f();
|
|
905
|
+
return y != null && y.accessToken && typeof y.accessToken == "string" ? y.accessToken : null;
|
|
906
|
+
};
|
|
907
|
+
return {
|
|
908
|
+
getSession: f,
|
|
909
|
+
setSession: l,
|
|
910
|
+
clearSessionCookie: w,
|
|
911
|
+
getAccessToken: g,
|
|
912
|
+
getRefreshToken: async () => {
|
|
913
|
+
const y = await f();
|
|
914
|
+
return y != null && y.refreshToken && typeof y.refreshToken == "string" ? y.refreshToken : null;
|
|
915
|
+
},
|
|
916
|
+
hasValidTokens: async () => !!await g(),
|
|
917
|
+
clearCache: () => {
|
|
918
|
+
a = null;
|
|
919
|
+
},
|
|
920
|
+
getSessionConfig: () => ({ cookieName: o, config: r })
|
|
921
|
+
};
|
|
922
|
+
}
|
|
923
|
+
function Qe(e) {
|
|
924
|
+
return async (r) => {
|
|
925
|
+
try {
|
|
926
|
+
if (!r || typeof r != "object")
|
|
927
|
+
return {
|
|
928
|
+
success: !1,
|
|
929
|
+
error: "Invalid credentials",
|
|
930
|
+
errorCode: m.VALIDATION_ERROR
|
|
931
|
+
};
|
|
932
|
+
if (!r.email || typeof r.email != "string")
|
|
933
|
+
return {
|
|
934
|
+
success: !1,
|
|
935
|
+
error: "Email is required",
|
|
936
|
+
errorCode: m.VALIDATION_ERROR
|
|
937
|
+
};
|
|
938
|
+
const t = G(r.email);
|
|
939
|
+
if (!K(t))
|
|
940
|
+
return {
|
|
941
|
+
success: !1,
|
|
942
|
+
error: t.error ?? "Invalid email format",
|
|
943
|
+
errorCode: m.VALIDATION_ERROR
|
|
944
|
+
};
|
|
945
|
+
if (!r.password || typeof r.password != "string")
|
|
946
|
+
return {
|
|
947
|
+
success: !1,
|
|
948
|
+
error: "Password is required",
|
|
949
|
+
errorCode: m.VALIDATION_ERROR
|
|
950
|
+
};
|
|
951
|
+
if (r.password.length > 128)
|
|
952
|
+
return {
|
|
953
|
+
success: !1,
|
|
954
|
+
error: "Invalid credentials",
|
|
955
|
+
errorCode: m.VALIDATION_ERROR
|
|
956
|
+
};
|
|
957
|
+
const n = {
|
|
958
|
+
email: t.sanitized,
|
|
959
|
+
password: r.password
|
|
960
|
+
// Don't sanitize password (needed for hashing)
|
|
961
|
+
}, s = await e.actions.signIn.email(n);
|
|
962
|
+
if (D(s)) {
|
|
963
|
+
const i = await e.saveSessionAfterAuth(s);
|
|
964
|
+
!i.success && i.warning && O.warn("Session save warning", { warning: i.warning });
|
|
965
|
+
}
|
|
966
|
+
return s.success ? O.info("Sign in successful", {
|
|
967
|
+
email: n.email.substring(0, 3) + "***"
|
|
968
|
+
}) : O.warn("Sign in failed", {
|
|
969
|
+
email: n.email.substring(0, 3) + "***",
|
|
970
|
+
errorCode: s.errorCode
|
|
971
|
+
}), s;
|
|
972
|
+
} catch (t) {
|
|
973
|
+
const n = t instanceof Error ? t.message : "Sign in failed";
|
|
974
|
+
return O.error("Sign in error", { error: n, context: "signIn.email" }), e.onError && await e.onError(
|
|
975
|
+
t instanceof Error ? t : new Error(String(t)),
|
|
976
|
+
"signIn.email"
|
|
977
|
+
), {
|
|
978
|
+
success: !1,
|
|
979
|
+
error: "Sign in failed. Please try again.",
|
|
980
|
+
errorCode: m.UNKNOWN_ERROR
|
|
981
|
+
};
|
|
982
|
+
}
|
|
983
|
+
};
|
|
984
|
+
}
|
|
985
|
+
function Ze(e, r) {
|
|
986
|
+
return async (t) => {
|
|
987
|
+
if (!t || typeof t != "string")
|
|
988
|
+
throw new Error("Provider is required");
|
|
989
|
+
const n = X(t, {
|
|
990
|
+
maxLength: 50,
|
|
991
|
+
allowHtml: !1,
|
|
992
|
+
required: !0
|
|
993
|
+
});
|
|
994
|
+
if (!n.valid || !n.sanitized)
|
|
995
|
+
throw new Error("Invalid provider");
|
|
996
|
+
const s = n.sanitized.toLowerCase();
|
|
997
|
+
if (!e.actions.signIn.oauth)
|
|
998
|
+
throw new Error(
|
|
999
|
+
"OAuth sign in is not configured. Either provide oauth action in signIn, or configure providers.oauth in config."
|
|
1000
|
+
);
|
|
1001
|
+
const i = await e.actions.signIn.oauth(s);
|
|
1002
|
+
return await r(i.state, s), O.info("OAuth sign in initiated", { provider: s }), i;
|
|
1003
|
+
};
|
|
1004
|
+
}
|
|
1005
|
+
function er(e) {
|
|
1006
|
+
return async (r, t) => {
|
|
1007
|
+
if (!r || typeof r != "string")
|
|
1008
|
+
return {
|
|
1009
|
+
success: !1,
|
|
1010
|
+
error: "Email is required",
|
|
1011
|
+
errorCode: m.VALIDATION_ERROR
|
|
1012
|
+
};
|
|
1013
|
+
const n = G(r);
|
|
1014
|
+
if (!K(n))
|
|
1015
|
+
return {
|
|
1016
|
+
success: !1,
|
|
1017
|
+
error: n.error ?? "Invalid email format",
|
|
1018
|
+
errorCode: m.VALIDATION_ERROR
|
|
1019
|
+
};
|
|
1020
|
+
if (t !== void 0 && (typeof t != "string" || t.length < 4 || t.length > 10))
|
|
1021
|
+
return {
|
|
1022
|
+
success: !1,
|
|
1023
|
+
error: "Invalid OTP code format",
|
|
1024
|
+
errorCode: m.VALIDATION_ERROR
|
|
1025
|
+
};
|
|
1026
|
+
if (!e.actions.signIn.otp)
|
|
1027
|
+
return {
|
|
1028
|
+
success: !1,
|
|
1029
|
+
error: "OTP sign in is not configured",
|
|
1030
|
+
errorCode: m.VALIDATION_ERROR
|
|
1031
|
+
};
|
|
1032
|
+
try {
|
|
1033
|
+
const s = await e.actions.signIn.otp(n.sanitized, t);
|
|
1034
|
+
if (D(s)) {
|
|
1035
|
+
const i = await e.saveSessionAfterAuth(s);
|
|
1036
|
+
!i.success && i.warning && O.warn("Session save warning", { warning: i.warning });
|
|
1037
|
+
}
|
|
1038
|
+
return s.success ? O.info("OTP sign in successful", {
|
|
1039
|
+
email: n.sanitized.substring(0, 3) + "***"
|
|
1040
|
+
}) : O.warn("OTP sign in failed", {
|
|
1041
|
+
email: n.sanitized.substring(0, 3) + "***"
|
|
1042
|
+
}), s;
|
|
1043
|
+
} catch (s) {
|
|
1044
|
+
return O.error("OTP sign in error", {
|
|
1045
|
+
error: s instanceof Error ? s.message : "Unknown error",
|
|
1046
|
+
context: "signIn.otp"
|
|
1047
|
+
}), e.onError && await e.onError(
|
|
1048
|
+
s instanceof Error ? s : new Error(String(s)),
|
|
1049
|
+
"signIn.otp"
|
|
1050
|
+
), {
|
|
1051
|
+
success: !1,
|
|
1052
|
+
error: "OTP sign in failed. Please try again.",
|
|
1053
|
+
errorCode: m.UNKNOWN_ERROR
|
|
1054
|
+
};
|
|
1055
|
+
}
|
|
1056
|
+
};
|
|
1057
|
+
}
|
|
1058
|
+
function rr(e) {
|
|
1059
|
+
return async (r) => {
|
|
1060
|
+
if (!e.actions.signIn.passkey)
|
|
1061
|
+
throw new Error("PassKey sign in is not configured. Provide passkey action in signIn.");
|
|
1062
|
+
try {
|
|
1063
|
+
const t = await e.actions.signIn.passkey(r);
|
|
1064
|
+
if (D(t)) {
|
|
1065
|
+
const n = await e.saveSessionAfterAuth(t);
|
|
1066
|
+
!n.success && n.warning && O.warn("Session save warning", { warning: n.warning });
|
|
1067
|
+
}
|
|
1068
|
+
return t;
|
|
1069
|
+
} catch (t) {
|
|
1070
|
+
return e.onError && await e.onError(
|
|
1071
|
+
t instanceof Error ? t : new Error(String(t)),
|
|
1072
|
+
"signIn.passkey"
|
|
1073
|
+
), {
|
|
1074
|
+
success: !1,
|
|
1075
|
+
error: t instanceof Error ? t.message : "PassKey sign in failed"
|
|
1076
|
+
};
|
|
1077
|
+
}
|
|
1078
|
+
};
|
|
1079
|
+
}
|
|
1080
|
+
function tr(e, r) {
|
|
1081
|
+
const t = Qe(e), n = Ze(e, r), s = er(e), i = rr(e);
|
|
1082
|
+
return Object.assign(async (f, l) => {
|
|
1083
|
+
if (!f || typeof f != "string")
|
|
1084
|
+
throw new Error("Provider is required");
|
|
1085
|
+
const w = X(f, {
|
|
1086
|
+
maxLength: 50,
|
|
1087
|
+
allowHtml: !1,
|
|
1088
|
+
required: !0
|
|
1089
|
+
});
|
|
1090
|
+
if (!w.valid || !w.sanitized)
|
|
1091
|
+
throw new Error("Invalid provider");
|
|
1092
|
+
const g = w.sanitized.toLowerCase();
|
|
1093
|
+
if (g === "google" || g === "github" || g === "apple" || g === "facebook" || typeof g == "string" && !["credentials", "otp", "passkey"].includes(g))
|
|
1094
|
+
return n(g);
|
|
1095
|
+
if (g === "credentials")
|
|
1096
|
+
return !l || !("email" in l) || !("password" in l) ? {
|
|
1097
|
+
success: !1,
|
|
1098
|
+
error: "Credentials are required",
|
|
1099
|
+
errorCode: m.VALIDATION_ERROR
|
|
1100
|
+
} : t(l);
|
|
1101
|
+
if (g === "otp") {
|
|
1102
|
+
if (!l || !("email" in l))
|
|
1103
|
+
return {
|
|
1104
|
+
success: !1,
|
|
1105
|
+
error: "Email is required",
|
|
1106
|
+
errorCode: m.VALIDATION_ERROR
|
|
1107
|
+
};
|
|
1108
|
+
const A = l;
|
|
1109
|
+
return s(A.email, A.code);
|
|
1110
|
+
}
|
|
1111
|
+
return g === "passkey" ? i(l) : {
|
|
1112
|
+
success: !1,
|
|
1113
|
+
error: "Invalid provider",
|
|
1114
|
+
errorCode: m.VALIDATION_ERROR
|
|
1115
|
+
};
|
|
1116
|
+
}, {
|
|
1117
|
+
email: t,
|
|
1118
|
+
oauth: e.actions.signIn.oauth ? n : void 0,
|
|
1119
|
+
passkey: e.actions.signIn.passkey ? i : void 0,
|
|
1120
|
+
otp: e.actions.signIn.otp ? s : void 0
|
|
1121
|
+
});
|
|
1122
|
+
}
|
|
1123
|
+
function nr(e) {
|
|
1124
|
+
return async (r) => {
|
|
1125
|
+
if (!e.actions.signUp)
|
|
1126
|
+
throw new Error("Sign up is not configured. Provide signUp action in config.");
|
|
1127
|
+
try {
|
|
1128
|
+
const t = await e.actions.signUp(r);
|
|
1129
|
+
if (D(t)) {
|
|
1130
|
+
const n = await e.saveSessionAfterAuth(t);
|
|
1131
|
+
!n.success && n.warning && O.warn("Session save warning", { warning: n.warning });
|
|
1132
|
+
}
|
|
1133
|
+
return t;
|
|
1134
|
+
} catch (t) {
|
|
1135
|
+
return e.onError && await e.onError(
|
|
1136
|
+
t instanceof Error ? t : new Error(String(t)),
|
|
1137
|
+
"signUp"
|
|
1138
|
+
), {
|
|
1139
|
+
success: !1,
|
|
1140
|
+
error: t instanceof Error ? t.message : "Sign up failed"
|
|
1141
|
+
};
|
|
1142
|
+
}
|
|
1143
|
+
};
|
|
1144
|
+
}
|
|
1145
|
+
function sr(e, r) {
|
|
1146
|
+
return async (t, n, s) => {
|
|
1147
|
+
const i = e.oauthProviders[t];
|
|
1148
|
+
if (!i)
|
|
680
1149
|
return {
|
|
681
1150
|
success: !1,
|
|
682
|
-
error: `OAuth provider "${
|
|
683
|
-
errorCode:
|
|
1151
|
+
error: `OAuth provider "${t}" is not configured`,
|
|
1152
|
+
errorCode: m.VALIDATION_ERROR
|
|
684
1153
|
};
|
|
685
1154
|
try {
|
|
686
|
-
const
|
|
687
|
-
|
|
688
|
-
|
|
689
|
-
|
|
1155
|
+
const o = i.redirectUri ?? `${e.baseUrl}/api/auth/callback/${t}`, a = await Ue(t, i, n, o), f = await Fe(t, a.access_token), l = {
|
|
1156
|
+
id: f.id,
|
|
1157
|
+
email: f.email,
|
|
1158
|
+
name: f.name,
|
|
1159
|
+
avatar: f.avatar,
|
|
1160
|
+
emailVerified: f.emailVerified,
|
|
1161
|
+
provider: t,
|
|
1162
|
+
accessToken: a.access_token,
|
|
1163
|
+
refreshToken: a.refresh_token,
|
|
1164
|
+
tokens: {
|
|
1165
|
+
access_token: a.access_token,
|
|
1166
|
+
refresh_token: a.refresh_token,
|
|
1167
|
+
expires_in: a.expires_in,
|
|
1168
|
+
token_type: a.token_type,
|
|
1169
|
+
id_token: a.id_token
|
|
1170
|
+
},
|
|
1171
|
+
rawProfile: f.rawProfile
|
|
1172
|
+
};
|
|
1173
|
+
if (e.callbacks.onOAuthUser) {
|
|
1174
|
+
const w = await q(
|
|
1175
|
+
e.callbacks.onOAuthUser,
|
|
1176
|
+
[l, t],
|
|
1177
|
+
e.onError
|
|
1178
|
+
);
|
|
1179
|
+
if (!w)
|
|
690
1180
|
return {
|
|
691
1181
|
success: !1,
|
|
692
1182
|
error: "Failed to create or retrieve user",
|
|
693
|
-
errorCode:
|
|
1183
|
+
errorCode: m.VALIDATION_ERROR
|
|
694
1184
|
};
|
|
695
|
-
const
|
|
696
|
-
|
|
697
|
-
|
|
698
|
-
|
|
699
|
-
|
|
700
|
-
|
|
701
|
-
emailVerified: E.emailVerified
|
|
702
|
-
},
|
|
703
|
-
expiresAt: new Date(Date.now() + 7 * 24 * 60 * 60 * 1e3),
|
|
704
|
-
accessToken: O.access_token,
|
|
705
|
-
refreshToken: O.refresh_token,
|
|
706
|
-
tokenType: "Bearer",
|
|
707
|
-
expiresIn: O.expires_in
|
|
708
|
-
};
|
|
709
|
-
return await T(k), p = { session: k, timestamp: Date.now() }, t.onSignIn && await g(t.onSignIn, k.user, k), { success: !0, user: k.user, session: k };
|
|
1185
|
+
const g = e.createSession(w, l, a);
|
|
1186
|
+
return await e.saveSession(g), e.callbacks.onSignIn && await q(
|
|
1187
|
+
e.callbacks.onSignIn,
|
|
1188
|
+
[g.user, g],
|
|
1189
|
+
e.onError
|
|
1190
|
+
), { success: !0, user: g.user, session: g };
|
|
710
1191
|
}
|
|
711
1192
|
return {
|
|
712
1193
|
success: !1,
|
|
713
1194
|
error: "OAuth user callback not implemented. Provide onOAuthUser callback or implement oauthCallback action.",
|
|
714
|
-
errorCode:
|
|
1195
|
+
errorCode: m.VALIDATION_ERROR
|
|
715
1196
|
};
|
|
716
|
-
} catch (
|
|
717
|
-
return
|
|
1197
|
+
} catch (o) {
|
|
1198
|
+
return O.error("OAuth callback failed", { provider: t, error: o }), {
|
|
718
1199
|
success: !1,
|
|
719
|
-
error:
|
|
720
|
-
errorCode:
|
|
1200
|
+
error: o instanceof Error ? o.message : "OAuth callback failed",
|
|
1201
|
+
errorCode: m.NETWORK_ERROR
|
|
721
1202
|
};
|
|
722
1203
|
}
|
|
723
|
-
}
|
|
724
|
-
|
|
725
|
-
|
|
726
|
-
|
|
727
|
-
|
|
728
|
-
|
|
729
|
-
|
|
730
|
-
|
|
731
|
-
|
|
732
|
-
|
|
733
|
-
|
|
734
|
-
|
|
735
|
-
|
|
1204
|
+
};
|
|
1205
|
+
}
|
|
1206
|
+
async function q(e, r, t) {
|
|
1207
|
+
if (e)
|
|
1208
|
+
try {
|
|
1209
|
+
return await e(...r);
|
|
1210
|
+
} catch (n) {
|
|
1211
|
+
throw t && await t(
|
|
1212
|
+
n instanceof Error ? n : new Error(String(n)),
|
|
1213
|
+
"callback"
|
|
1214
|
+
), n;
|
|
1215
|
+
}
|
|
1216
|
+
}
|
|
1217
|
+
function ir(e, r, t, n) {
|
|
1218
|
+
if (Object.keys(e).length !== 0)
|
|
1219
|
+
return async (s) => {
|
|
1220
|
+
const i = e[s];
|
|
1221
|
+
if (!i)
|
|
1222
|
+
throw new Error(`OAuth provider "${s}" is not configured. Add it to providers.oauth in config.`);
|
|
1223
|
+
if (!i.clientId)
|
|
1224
|
+
throw new Error(`OAuth provider "${s}" is missing clientId`);
|
|
1225
|
+
const o = t();
|
|
1226
|
+
return { url: n(s, i, r, o), state: o };
|
|
1227
|
+
};
|
|
1228
|
+
}
|
|
1229
|
+
function Zr(e) {
|
|
1230
|
+
var L, V;
|
|
1231
|
+
const r = {
|
|
1232
|
+
...Ke(),
|
|
1233
|
+
...e.session
|
|
1234
|
+
}, t = e.actions, n = e.callbacks || {}, s = ((L = e.providers) == null ? void 0 : L.oauth) || {}, i = Je(), o = {
|
|
1235
|
+
...Xe(),
|
|
1236
|
+
...e.tokenRefresh
|
|
1237
|
+
}, a = ((V = e.session) == null ? void 0 : V.cacheTtl) ?? e.sessionCacheTtl ?? 5e3, f = e.oauthStateStore || $e(), l = { ...t }, w = async (c, u) => {
|
|
1238
|
+
const d = {
|
|
1239
|
+
provider: u,
|
|
736
1240
|
expiresAt: Date.now() + 6e5
|
|
737
1241
|
// 10 minutes
|
|
738
1242
|
};
|
|
739
|
-
await Promise.resolve(
|
|
740
|
-
},
|
|
741
|
-
const
|
|
742
|
-
return
|
|
743
|
-
},
|
|
744
|
-
|
|
745
|
-
|
|
746
|
-
|
|
747
|
-
|
|
1243
|
+
await Promise.resolve(f.set(c, d, 10 * 60 * 1e3)), f.cleanup && await Promise.resolve(f.cleanup());
|
|
1244
|
+
}, g = async (c, u) => {
|
|
1245
|
+
const d = await Promise.resolve(f.get(c));
|
|
1246
|
+
return d ? d.expiresAt < Date.now() ? (await Promise.resolve(f.delete(c)), !1) : d.provider !== u ? !1 : (await Promise.resolve(f.delete(c)), !0) : !1;
|
|
1247
|
+
}, A = ir(
|
|
1248
|
+
s,
|
|
1249
|
+
i,
|
|
1250
|
+
_e,
|
|
1251
|
+
be
|
|
1252
|
+
);
|
|
1253
|
+
if (A && !l.signIn.oauth) {
|
|
1254
|
+
const c = l.signIn;
|
|
1255
|
+
l.signIn = {
|
|
1256
|
+
...c,
|
|
1257
|
+
oauth: async (u) => {
|
|
1258
|
+
const d = await A(u);
|
|
1259
|
+
return await w(d.state, u), d;
|
|
1260
|
+
}
|
|
1261
|
+
};
|
|
1262
|
+
}
|
|
1263
|
+
if (!l.signIn || !l.signIn.email)
|
|
1264
|
+
throw new Error("mulguard: signIn.email action is required");
|
|
1265
|
+
const S = async (c, ...u) => {
|
|
1266
|
+
if (c)
|
|
1267
|
+
try {
|
|
1268
|
+
return await c(...u);
|
|
1269
|
+
} catch (d) {
|
|
1270
|
+
throw n.onError && await n.onError(d instanceof Error ? d : new Error(String(d)), "callback"), d;
|
|
1271
|
+
}
|
|
1272
|
+
}, v = Ye({
|
|
1273
|
+
sessionConfig: r,
|
|
1274
|
+
cacheTtl: a,
|
|
1275
|
+
getSessionAction: t.getSession,
|
|
1276
|
+
onSessionExpired: n.onSessionExpired,
|
|
1277
|
+
onError: n.onError
|
|
1278
|
+
}), y = async (c) => {
|
|
1279
|
+
if (!D(c) || !c.session)
|
|
748
1280
|
return { success: !0 };
|
|
749
|
-
const
|
|
750
|
-
return
|
|
751
|
-
}, _ = async () => {
|
|
752
|
-
const n = e.cookieName || "__mulguard_session";
|
|
753
|
-
await J(n, {
|
|
754
|
-
path: e.path,
|
|
755
|
-
domain: e.domain
|
|
756
|
-
});
|
|
1281
|
+
const u = await v.setSession(c.session);
|
|
1282
|
+
return c.user && n.onSignIn && await S(n.onSignIn, c.user, c.session), u;
|
|
757
1283
|
};
|
|
758
|
-
|
|
759
|
-
|
|
1284
|
+
if (Object.keys(s).length > 0 && !l.oauthCallback) {
|
|
1285
|
+
const c = sr(
|
|
1286
|
+
{
|
|
1287
|
+
oauthProviders: s,
|
|
1288
|
+
baseUrl: i,
|
|
1289
|
+
callbacks: n,
|
|
1290
|
+
createSession: (u, d, R) => ({
|
|
1291
|
+
user: {
|
|
1292
|
+
...u,
|
|
1293
|
+
avatar: d.avatar,
|
|
1294
|
+
emailVerified: d.emailVerified
|
|
1295
|
+
},
|
|
1296
|
+
expiresAt: new Date(Date.now() + (r.expiresIn || 604800) * 1e3),
|
|
1297
|
+
accessToken: R.access_token,
|
|
1298
|
+
refreshToken: R.refresh_token,
|
|
1299
|
+
tokenType: "Bearer",
|
|
1300
|
+
expiresIn: R.expires_in
|
|
1301
|
+
}),
|
|
1302
|
+
saveSession: async (u) => {
|
|
1303
|
+
await v.setSession(u);
|
|
1304
|
+
},
|
|
1305
|
+
onError: n.onError
|
|
1306
|
+
}
|
|
1307
|
+
);
|
|
1308
|
+
l.oauthCallback = c;
|
|
1309
|
+
}
|
|
1310
|
+
const h = tr(
|
|
1311
|
+
{
|
|
1312
|
+
actions: l,
|
|
1313
|
+
callbacks: n,
|
|
1314
|
+
saveSessionAfterAuth: y,
|
|
1315
|
+
onError: n.onError
|
|
1316
|
+
},
|
|
1317
|
+
w
|
|
1318
|
+
), I = nr({
|
|
1319
|
+
actions: l,
|
|
1320
|
+
callbacks: n,
|
|
1321
|
+
saveSessionAfterAuth: y,
|
|
1322
|
+
onError: n.onError
|
|
1323
|
+
}), _ = {
|
|
760
1324
|
/**
|
|
761
1325
|
* Get current session
|
|
762
1326
|
* Uses custom getSession action if provided, otherwise falls back to reading from cookie
|
|
763
|
-
* ✅ IMPROVEMENT: Added session caching for better performance
|
|
764
1327
|
*/
|
|
765
1328
|
async getSession() {
|
|
766
|
-
|
|
767
|
-
if (p && n - p.timestamp < v)
|
|
768
|
-
return p.session;
|
|
769
|
-
if (s.getSession)
|
|
770
|
-
try {
|
|
771
|
-
const o = await s.getSession();
|
|
772
|
-
if (o && x(o))
|
|
773
|
-
return p = { session: o, timestamp: n }, o;
|
|
774
|
-
o && !x(o) && (await _(), p = null);
|
|
775
|
-
} catch (o) {
|
|
776
|
-
P.debug("getSession error", { error: o }), t.onError && await g(t.onError, o instanceof Error ? o : new Error(String(o)), "getSession"), p = null;
|
|
777
|
-
}
|
|
778
|
-
try {
|
|
779
|
-
const o = e.cookieName || "__mulguard_session", u = await G(o);
|
|
780
|
-
if (u)
|
|
781
|
-
try {
|
|
782
|
-
const m = JSON.parse(u);
|
|
783
|
-
if (x(m))
|
|
784
|
-
return m.expiresAt && new Date(m.expiresAt) < /* @__PURE__ */ new Date() ? (t.onSessionExpired && await g(t.onSessionExpired, m), await _(), p = null, null) : (p = { session: m, timestamp: n }, m);
|
|
785
|
-
await _(), p = null;
|
|
786
|
-
} catch {
|
|
787
|
-
await _(), p = null;
|
|
788
|
-
}
|
|
789
|
-
} catch (o) {
|
|
790
|
-
const u = o instanceof Error ? o.message : String(o);
|
|
791
|
-
!u.includes("request scope") && !u.includes("cookies") && (P.warn("getSession cookie error", { error: o }), t.onError && await g(t.onError, o instanceof Error ? o : new Error(String(o)), "getSession.cookie"));
|
|
792
|
-
}
|
|
793
|
-
return null;
|
|
1329
|
+
return await v.getSession();
|
|
794
1330
|
},
|
|
795
1331
|
/**
|
|
796
1332
|
* Get access token from current session
|
|
797
1333
|
*/
|
|
798
1334
|
async getAccessToken() {
|
|
799
|
-
|
|
800
|
-
return n != null && n.accessToken && typeof n.accessToken == "string" ? n.accessToken : null;
|
|
1335
|
+
return await v.getAccessToken();
|
|
801
1336
|
},
|
|
802
1337
|
/**
|
|
803
1338
|
* Get refresh token from current session
|
|
804
1339
|
*/
|
|
805
1340
|
async getRefreshToken() {
|
|
806
|
-
|
|
807
|
-
return n != null && n.refreshToken && typeof n.refreshToken == "string" ? n.refreshToken : null;
|
|
1341
|
+
return await v.getRefreshToken();
|
|
808
1342
|
},
|
|
809
1343
|
/**
|
|
810
1344
|
* Check if session has valid tokens
|
|
811
1345
|
*/
|
|
812
1346
|
async hasValidTokens() {
|
|
813
|
-
return
|
|
1347
|
+
return await v.hasValidTokens();
|
|
814
1348
|
},
|
|
815
1349
|
/**
|
|
816
1350
|
* Unified sign in method - supports both unified and direct method calls
|
|
817
|
-
* ✅ IMPROVEMENT: Single unified logic for all sign-in methods
|
|
818
1351
|
*/
|
|
819
|
-
signIn:
|
|
820
|
-
const n = async (E) => {
|
|
821
|
-
try {
|
|
822
|
-
if (!E || typeof E != "object")
|
|
823
|
-
return {
|
|
824
|
-
success: !1,
|
|
825
|
-
error: "Invalid credentials",
|
|
826
|
-
errorCode: y.VALIDATION_ERROR
|
|
827
|
-
};
|
|
828
|
-
if (!E.email || typeof E.email != "string")
|
|
829
|
-
return {
|
|
830
|
-
success: !1,
|
|
831
|
-
error: "Email is required",
|
|
832
|
-
errorCode: y.VALIDATION_ERROR
|
|
833
|
-
};
|
|
834
|
-
const h = M(E.email);
|
|
835
|
-
if (!h.valid)
|
|
836
|
-
return {
|
|
837
|
-
success: !1,
|
|
838
|
-
error: h.error || "Invalid email format",
|
|
839
|
-
errorCode: y.VALIDATION_ERROR
|
|
840
|
-
};
|
|
841
|
-
if (!E.password || typeof E.password != "string")
|
|
842
|
-
return {
|
|
843
|
-
success: !1,
|
|
844
|
-
error: "Password is required",
|
|
845
|
-
errorCode: y.VALIDATION_ERROR
|
|
846
|
-
};
|
|
847
|
-
if (E.password.length > 128)
|
|
848
|
-
return {
|
|
849
|
-
success: !1,
|
|
850
|
-
error: "Invalid credentials",
|
|
851
|
-
errorCode: y.VALIDATION_ERROR
|
|
852
|
-
};
|
|
853
|
-
const k = {
|
|
854
|
-
email: h.sanitized,
|
|
855
|
-
password: E.password
|
|
856
|
-
// Don't sanitize password (needed for hashing)
|
|
857
|
-
}, l = await a.signIn.email(k);
|
|
858
|
-
return l.success && l.session && await U(l), l.success ? P.info("Sign in successful", { email: k.email.substring(0, 3) + "***" }) : P.warn("Sign in failed", { email: k.email.substring(0, 3) + "***", errorCode: l.errorCode }), l;
|
|
859
|
-
} catch (h) {
|
|
860
|
-
const k = h instanceof Error ? h.message : "Sign in failed";
|
|
861
|
-
return P.error("Sign in error", { error: k, context: "signIn.email" }), t.onError && await g(t.onError, h instanceof Error ? h : new Error(String(h)), "signIn.email"), {
|
|
862
|
-
success: !1,
|
|
863
|
-
error: "Sign in failed. Please try again.",
|
|
864
|
-
errorCode: y.UNKNOWN_ERROR
|
|
865
|
-
};
|
|
866
|
-
}
|
|
867
|
-
}, o = async (E) => {
|
|
868
|
-
if (!E || typeof E != "string")
|
|
869
|
-
throw new Error("Provider is required");
|
|
870
|
-
const h = z(E, { maxLength: 50, allowHtml: !1, required: !0 });
|
|
871
|
-
if (!h.valid || !h.sanitized)
|
|
872
|
-
throw new Error("Invalid provider");
|
|
873
|
-
const k = h.sanitized.toLowerCase();
|
|
874
|
-
if (!a.signIn.oauth)
|
|
875
|
-
throw new Error(
|
|
876
|
-
"OAuth sign in is not configured. Either provide oauth action in signIn, or configure providers.oauth in config."
|
|
877
|
-
);
|
|
878
|
-
const l = await a.signIn.oauth(k);
|
|
879
|
-
return await A(l.state, k), P.info("OAuth sign in initiated", { provider: k }), l;
|
|
880
|
-
}, u = async (E) => {
|
|
881
|
-
if (!a.signIn.passkey)
|
|
882
|
-
throw new Error("PassKey sign in is not configured. Provide passkey action in signIn.");
|
|
883
|
-
try {
|
|
884
|
-
const h = await a.signIn.passkey(E);
|
|
885
|
-
return h.success && h.session && await U(h), h;
|
|
886
|
-
} catch (h) {
|
|
887
|
-
return t.onError && await g(t.onError, h instanceof Error ? h : new Error(String(h)), "signIn.passkey"), {
|
|
888
|
-
success: !1,
|
|
889
|
-
error: h instanceof Error ? h.message : "PassKey sign in failed"
|
|
890
|
-
};
|
|
891
|
-
}
|
|
892
|
-
}, m = async (E, h) => {
|
|
893
|
-
if (!E || typeof E != "string")
|
|
894
|
-
return {
|
|
895
|
-
success: !1,
|
|
896
|
-
error: "Email is required",
|
|
897
|
-
errorCode: y.VALIDATION_ERROR
|
|
898
|
-
};
|
|
899
|
-
const k = M(E);
|
|
900
|
-
if (!k.valid)
|
|
901
|
-
return {
|
|
902
|
-
success: !1,
|
|
903
|
-
error: k.error || "Invalid email format",
|
|
904
|
-
errorCode: y.VALIDATION_ERROR
|
|
905
|
-
};
|
|
906
|
-
if (h !== void 0 && (typeof h != "string" || h.length < 4 || h.length > 10))
|
|
907
|
-
return {
|
|
908
|
-
success: !1,
|
|
909
|
-
error: "Invalid OTP code format",
|
|
910
|
-
errorCode: y.VALIDATION_ERROR
|
|
911
|
-
};
|
|
912
|
-
if (!a.signIn.otp)
|
|
913
|
-
return {
|
|
914
|
-
success: !1,
|
|
915
|
-
error: "OTP sign in is not configured",
|
|
916
|
-
errorCode: y.VALIDATION_ERROR
|
|
917
|
-
};
|
|
918
|
-
try {
|
|
919
|
-
const l = await a.signIn.otp(k.sanitized, h);
|
|
920
|
-
return l.success && l.session && await U(l), l.success ? P.info("OTP sign in successful", { email: k.sanitized.substring(0, 3) + "***" }) : P.warn("OTP sign in failed", { email: k.sanitized.substring(0, 3) + "***" }), l;
|
|
921
|
-
} catch (l) {
|
|
922
|
-
return P.error("OTP sign in error", { error: l instanceof Error ? l.message : "Unknown error", context: "signIn.otp" }), t.onError && await g(t.onError, l instanceof Error ? l : new Error(String(l)), "signIn.otp"), {
|
|
923
|
-
success: !1,
|
|
924
|
-
error: "OTP sign in failed. Please try again.",
|
|
925
|
-
errorCode: y.UNKNOWN_ERROR
|
|
926
|
-
};
|
|
927
|
-
}
|
|
928
|
-
}, O = Object.assign(
|
|
929
|
-
async (E, h) => {
|
|
930
|
-
if (!E || typeof E != "string")
|
|
931
|
-
throw new Error("Provider is required");
|
|
932
|
-
const k = z(E, { maxLength: 50, allowHtml: !1, required: !0 });
|
|
933
|
-
if (!k.valid || !k.sanitized)
|
|
934
|
-
throw new Error("Invalid provider");
|
|
935
|
-
const l = k.sanitized.toLowerCase();
|
|
936
|
-
if (l === "google" || l === "github" || l === "apple" || l === "facebook" || typeof l == "string" && !["credentials", "otp", "passkey"].includes(l))
|
|
937
|
-
return o(l);
|
|
938
|
-
if (l === "credentials")
|
|
939
|
-
return !h || !("email" in h) || !("password" in h) ? {
|
|
940
|
-
success: !1,
|
|
941
|
-
error: "Credentials are required",
|
|
942
|
-
errorCode: y.VALIDATION_ERROR
|
|
943
|
-
} : n(h);
|
|
944
|
-
if (l === "otp") {
|
|
945
|
-
if (!h || !("email" in h))
|
|
946
|
-
return {
|
|
947
|
-
success: !1,
|
|
948
|
-
error: "Email is required",
|
|
949
|
-
errorCode: y.VALIDATION_ERROR
|
|
950
|
-
};
|
|
951
|
-
const w = h;
|
|
952
|
-
return m(w.email, w.code);
|
|
953
|
-
}
|
|
954
|
-
return l === "passkey" ? u(h) : {
|
|
955
|
-
success: !1,
|
|
956
|
-
error: "Invalid provider",
|
|
957
|
-
errorCode: y.VALIDATION_ERROR
|
|
958
|
-
};
|
|
959
|
-
},
|
|
960
|
-
{
|
|
961
|
-
email: n,
|
|
962
|
-
oauth: a.signIn.oauth ? o : void 0,
|
|
963
|
-
passkey: a.signIn.passkey ? u : void 0,
|
|
964
|
-
otp: a.signIn.otp ? m : void 0
|
|
965
|
-
}
|
|
966
|
-
);
|
|
967
|
-
return I = O, O;
|
|
968
|
-
})(),
|
|
1352
|
+
signIn: h,
|
|
969
1353
|
/**
|
|
970
1354
|
* Sign up new user
|
|
971
1355
|
*/
|
|
972
|
-
async signUp(
|
|
973
|
-
if (!
|
|
1356
|
+
async signUp(c) {
|
|
1357
|
+
if (!I)
|
|
974
1358
|
throw new Error("Sign up is not configured. Provide signUp action in config.");
|
|
975
|
-
|
|
976
|
-
const o = await a.signUp(n);
|
|
977
|
-
return o.success && o.session && await U(o), o;
|
|
978
|
-
} catch (o) {
|
|
979
|
-
return t.onError && await g(t.onError, o instanceof Error ? o : new Error(String(o)), "signUp"), {
|
|
980
|
-
success: !1,
|
|
981
|
-
error: o instanceof Error ? o.message : "Sign up failed"
|
|
982
|
-
};
|
|
983
|
-
}
|
|
1359
|
+
return await I(c);
|
|
984
1360
|
},
|
|
985
1361
|
/**
|
|
986
1362
|
* Sign out
|
|
987
1363
|
*/
|
|
988
1364
|
async signOut() {
|
|
989
1365
|
try {
|
|
990
|
-
const
|
|
991
|
-
return
|
|
992
|
-
} catch (
|
|
993
|
-
return await
|
|
1366
|
+
const c = await this.getSession(), u = c == null ? void 0 : c.user;
|
|
1367
|
+
return t.signOut && await t.signOut(), await v.clearSessionCookie(), v.clearCache(), u && n.onSignOut && await S(n.onSignOut, u), { success: !0 };
|
|
1368
|
+
} catch (c) {
|
|
1369
|
+
return await v.clearSessionCookie(), v.clearCache(), n.onError && await S(n.onError, c instanceof Error ? c : new Error(String(c)), "signOut"), {
|
|
994
1370
|
success: !1,
|
|
995
|
-
error:
|
|
1371
|
+
error: c instanceof Error ? c.message : "Sign out failed"
|
|
996
1372
|
};
|
|
997
1373
|
}
|
|
998
1374
|
},
|
|
999
1375
|
/**
|
|
1000
1376
|
* Request password reset
|
|
1001
1377
|
*/
|
|
1002
|
-
async resetPassword(
|
|
1003
|
-
if (!
|
|
1378
|
+
async resetPassword(c) {
|
|
1379
|
+
if (!t.resetPassword)
|
|
1004
1380
|
throw new Error("Password reset is not configured. Provide resetPassword action in config.");
|
|
1005
1381
|
try {
|
|
1006
|
-
return await
|
|
1007
|
-
} catch (
|
|
1008
|
-
return
|
|
1382
|
+
return await t.resetPassword(c);
|
|
1383
|
+
} catch (u) {
|
|
1384
|
+
return n.onError && await S(n.onError, u instanceof Error ? u : new Error(String(u)), "resetPassword"), {
|
|
1009
1385
|
success: !1,
|
|
1010
|
-
error:
|
|
1386
|
+
error: u instanceof Error ? u.message : "Password reset failed"
|
|
1011
1387
|
};
|
|
1012
1388
|
}
|
|
1013
1389
|
},
|
|
1014
1390
|
/**
|
|
1015
1391
|
* Verify email address
|
|
1016
1392
|
*/
|
|
1017
|
-
async verifyEmail(
|
|
1018
|
-
if (!
|
|
1393
|
+
async verifyEmail(c) {
|
|
1394
|
+
if (!t.verifyEmail)
|
|
1019
1395
|
throw new Error("Email verification is not configured. Provide verifyEmail action in config.");
|
|
1020
1396
|
try {
|
|
1021
|
-
return await
|
|
1022
|
-
} catch (
|
|
1023
|
-
return
|
|
1397
|
+
return await t.verifyEmail(c);
|
|
1398
|
+
} catch (u) {
|
|
1399
|
+
return n.onError && await S(n.onError, u instanceof Error ? u : new Error(String(u)), "verifyEmail"), {
|
|
1024
1400
|
success: !1,
|
|
1025
|
-
error:
|
|
1401
|
+
error: u instanceof Error ? u.message : "Email verification failed"
|
|
1026
1402
|
};
|
|
1027
1403
|
}
|
|
1028
1404
|
},
|
|
@@ -1031,73 +1407,73 @@ function Me(r) {
|
|
|
1031
1407
|
* Executes custom refreshSession action with improved error handling and callbacks
|
|
1032
1408
|
*/
|
|
1033
1409
|
async refreshSession() {
|
|
1034
|
-
if (!
|
|
1410
|
+
if (!t.refreshSession)
|
|
1035
1411
|
return this.getSession();
|
|
1036
1412
|
try {
|
|
1037
|
-
const
|
|
1038
|
-
if (
|
|
1039
|
-
if (await
|
|
1040
|
-
const
|
|
1041
|
-
if (
|
|
1042
|
-
if (await
|
|
1043
|
-
const
|
|
1044
|
-
|
|
1413
|
+
const c = await t.refreshSession();
|
|
1414
|
+
if (c && N(c)) {
|
|
1415
|
+
if (await v.setSession(c), n.onSessionUpdate) {
|
|
1416
|
+
const u = await S(n.onSessionUpdate, c);
|
|
1417
|
+
if (u && N(u)) {
|
|
1418
|
+
if (await v.setSession(u), n.onTokenRefresh) {
|
|
1419
|
+
const d = await this.getSession();
|
|
1420
|
+
d && await S(n.onTokenRefresh, d, u);
|
|
1045
1421
|
}
|
|
1046
|
-
return
|
|
1422
|
+
return u;
|
|
1047
1423
|
}
|
|
1048
1424
|
}
|
|
1049
|
-
if (
|
|
1050
|
-
const
|
|
1051
|
-
|
|
1425
|
+
if (n.onTokenRefresh) {
|
|
1426
|
+
const u = await this.getSession();
|
|
1427
|
+
u && await S(n.onTokenRefresh, u, c);
|
|
1052
1428
|
}
|
|
1053
|
-
return
|
|
1054
|
-
} else if (
|
|
1055
|
-
return await
|
|
1429
|
+
return c;
|
|
1430
|
+
} else if (c && !N(c))
|
|
1431
|
+
return await v.clearSessionCookie(), v.clearCache(), null;
|
|
1056
1432
|
return null;
|
|
1057
|
-
} catch (
|
|
1058
|
-
return await
|
|
1433
|
+
} catch (c) {
|
|
1434
|
+
return await v.clearSessionCookie(), v.clearCache(), n.onError && await S(n.onError, c instanceof Error ? c : new Error(String(c)), "refreshSession"), null;
|
|
1059
1435
|
}
|
|
1060
1436
|
},
|
|
1061
1437
|
/**
|
|
1062
1438
|
* OAuth callback handler
|
|
1063
1439
|
* ✅ Auto-generated if providers.oauth is configured in config
|
|
1064
1440
|
*/
|
|
1065
|
-
async oauthCallback(
|
|
1066
|
-
if (!
|
|
1441
|
+
async oauthCallback(c, u, d) {
|
|
1442
|
+
if (!l.oauthCallback)
|
|
1067
1443
|
throw new Error(
|
|
1068
1444
|
"OAuth callback is not configured. Either provide oauthCallback action, or configure providers.oauth in config."
|
|
1069
1445
|
);
|
|
1070
|
-
if (!
|
|
1446
|
+
if (!u || !d)
|
|
1071
1447
|
return {
|
|
1072
1448
|
success: !1,
|
|
1073
|
-
error: "Missing required OAuth parameters (
|
|
1074
|
-
errorCode:
|
|
1449
|
+
error: "Missing required OAuth parameters (code or state)",
|
|
1450
|
+
errorCode: m.VALIDATION_ERROR
|
|
1075
1451
|
};
|
|
1076
|
-
|
|
1452
|
+
let R = c;
|
|
1453
|
+
if (!R) {
|
|
1454
|
+
const P = await Promise.resolve(f.get(d));
|
|
1455
|
+
if (P && P.provider)
|
|
1456
|
+
R = P.provider;
|
|
1457
|
+
else
|
|
1458
|
+
return {
|
|
1459
|
+
success: !1,
|
|
1460
|
+
error: "Provider is required and could not be extracted from state",
|
|
1461
|
+
errorCode: m.VALIDATION_ERROR
|
|
1462
|
+
};
|
|
1463
|
+
}
|
|
1464
|
+
if (!await g(d, R))
|
|
1077
1465
|
return {
|
|
1078
1466
|
success: !1,
|
|
1079
1467
|
error: "Invalid or expired state parameter",
|
|
1080
|
-
errorCode:
|
|
1468
|
+
errorCode: m.VALIDATION_ERROR
|
|
1081
1469
|
};
|
|
1082
1470
|
try {
|
|
1083
|
-
|
|
1084
|
-
|
|
1085
|
-
|
|
1086
|
-
O.success || (process.env.NODE_ENV === "development" && P.debug("Failed to save session cookie after oauthCallback", {
|
|
1087
|
-
error: O.error,
|
|
1088
|
-
warning: O.warning
|
|
1089
|
-
}), t.onError && await g(
|
|
1090
|
-
t.onError,
|
|
1091
|
-
new Error(O.warning || O.error || "Failed to save session cookie"),
|
|
1092
|
-
"oauthCallback.setSession"
|
|
1093
|
-
));
|
|
1094
|
-
}
|
|
1095
|
-
return R;
|
|
1096
|
-
} catch (R) {
|
|
1097
|
-
return t.onError && await g(t.onError, R instanceof Error ? R : new Error(String(R)), "oauthCallback"), {
|
|
1471
|
+
return await l.oauthCallback(R, u, d);
|
|
1472
|
+
} catch (P) {
|
|
1473
|
+
return n.onError && await S(n.onError, P instanceof Error ? P : new Error(String(P)), "oauthCallback"), {
|
|
1098
1474
|
success: !1,
|
|
1099
|
-
error:
|
|
1100
|
-
errorCode:
|
|
1475
|
+
error: P instanceof Error ? P.message : "OAuth callback failed",
|
|
1476
|
+
errorCode: m.NETWORK_ERROR
|
|
1101
1477
|
};
|
|
1102
1478
|
}
|
|
1103
1479
|
},
|
|
@@ -1105,28 +1481,28 @@ function Me(r) {
|
|
|
1105
1481
|
* Verify 2FA code after initial sign in
|
|
1106
1482
|
* Used when signIn returns requires2FA: true
|
|
1107
1483
|
*/
|
|
1108
|
-
async verify2FA(
|
|
1109
|
-
if (!
|
|
1484
|
+
async verify2FA(c, u) {
|
|
1485
|
+
if (!t.verify2FA)
|
|
1110
1486
|
throw new Error("2FA verification is not configured. Provide verify2FA action in config.");
|
|
1111
1487
|
try {
|
|
1112
|
-
const
|
|
1113
|
-
if (
|
|
1114
|
-
const
|
|
1115
|
-
|
|
1116
|
-
error:
|
|
1117
|
-
warning:
|
|
1118
|
-
}),
|
|
1119
|
-
|
|
1120
|
-
new Error(
|
|
1488
|
+
const d = await t.verify2FA(c);
|
|
1489
|
+
if (d.success && d.session && !(u != null && u.skipCookieSave)) {
|
|
1490
|
+
const R = await y(d);
|
|
1491
|
+
R.success || (process.env.NODE_ENV === "development" && O.debug("Failed to save session cookie after verify2FA", {
|
|
1492
|
+
error: R.error,
|
|
1493
|
+
warning: R.warning
|
|
1494
|
+
}), n.onError && await S(
|
|
1495
|
+
n.onError,
|
|
1496
|
+
new Error(R.warning || R.error || "Failed to save session cookie"),
|
|
1121
1497
|
"verify2FA.setSession"
|
|
1122
1498
|
));
|
|
1123
1499
|
}
|
|
1124
|
-
return
|
|
1125
|
-
} catch (
|
|
1126
|
-
return
|
|
1500
|
+
return d;
|
|
1501
|
+
} catch (d) {
|
|
1502
|
+
return n.onError && await S(n.onError, d instanceof Error ? d : new Error(String(d)), "verify2FA"), {
|
|
1127
1503
|
success: !1,
|
|
1128
|
-
error:
|
|
1129
|
-
errorCode:
|
|
1504
|
+
error: d instanceof Error ? d.message : "2FA verification failed",
|
|
1505
|
+
errorCode: m.TWO_FA_REQUIRED
|
|
1130
1506
|
};
|
|
1131
1507
|
}
|
|
1132
1508
|
},
|
|
@@ -1134,11 +1510,8 @@ function Me(r) {
|
|
|
1134
1510
|
* Set session directly
|
|
1135
1511
|
* Useful for Server Actions that need to save session manually
|
|
1136
1512
|
*/
|
|
1137
|
-
async setSession(
|
|
1138
|
-
return
|
|
1139
|
-
success: !1,
|
|
1140
|
-
error: "Invalid session structure"
|
|
1141
|
-
};
|
|
1513
|
+
async setSession(c) {
|
|
1514
|
+
return await v.setSession(c);
|
|
1142
1515
|
},
|
|
1143
1516
|
/**
|
|
1144
1517
|
* Internal method to get session config for Server Actions
|
|
@@ -1146,584 +1519,561 @@ function Me(r) {
|
|
|
1146
1519
|
* @internal
|
|
1147
1520
|
*/
|
|
1148
1521
|
_getSessionConfig() {
|
|
1149
|
-
return
|
|
1150
|
-
cookieName: e.cookieName || "__mulguard_session",
|
|
1151
|
-
config: e
|
|
1152
|
-
};
|
|
1522
|
+
return v.getSessionConfig();
|
|
1153
1523
|
},
|
|
1154
1524
|
_getCallbacks() {
|
|
1155
|
-
return
|
|
1525
|
+
return n;
|
|
1156
1526
|
},
|
|
1157
1527
|
/**
|
|
1158
1528
|
* PassKey methods
|
|
1159
1529
|
*/
|
|
1160
|
-
passkey:
|
|
1161
|
-
register:
|
|
1162
|
-
authenticate: async (
|
|
1163
|
-
var
|
|
1164
|
-
if (!((
|
|
1530
|
+
passkey: t.passkey ? {
|
|
1531
|
+
register: t.passkey.register,
|
|
1532
|
+
authenticate: async (c) => {
|
|
1533
|
+
var u;
|
|
1534
|
+
if (!((u = t.passkey) != null && u.authenticate))
|
|
1165
1535
|
throw new Error("PassKey authenticate is not configured.");
|
|
1166
1536
|
try {
|
|
1167
|
-
const
|
|
1168
|
-
return
|
|
1169
|
-
} catch (
|
|
1170
|
-
return
|
|
1537
|
+
const d = await t.passkey.authenticate(c);
|
|
1538
|
+
return d.success && d.session && await y(d), d;
|
|
1539
|
+
} catch (d) {
|
|
1540
|
+
return n.onError && await S(n.onError, d instanceof Error ? d : new Error(String(d)), "passkey.authenticate"), {
|
|
1171
1541
|
success: !1,
|
|
1172
|
-
error:
|
|
1542
|
+
error: d instanceof Error ? d.message : "PassKey authentication failed"
|
|
1173
1543
|
};
|
|
1174
1544
|
}
|
|
1175
1545
|
},
|
|
1176
|
-
list:
|
|
1177
|
-
|
|
1546
|
+
list: t.passkey.list ? async () => {
|
|
1547
|
+
var u;
|
|
1548
|
+
if (!((u = t.passkey) != null && u.list))
|
|
1549
|
+
throw new Error("PassKey list is not configured.");
|
|
1550
|
+
return [...await t.passkey.list()];
|
|
1551
|
+
} : void 0,
|
|
1552
|
+
remove: t.passkey.remove
|
|
1178
1553
|
} : void 0,
|
|
1179
1554
|
/**
|
|
1180
1555
|
* Two-Factor Authentication methods
|
|
1181
1556
|
*/
|
|
1182
|
-
twoFactor:
|
|
1183
|
-
enable:
|
|
1184
|
-
verify:
|
|
1185
|
-
disable:
|
|
1186
|
-
generateBackupCodes:
|
|
1187
|
-
isEnabled:
|
|
1188
|
-
verify2FA: async (
|
|
1189
|
-
var
|
|
1190
|
-
const
|
|
1191
|
-
if (!
|
|
1557
|
+
twoFactor: t.twoFactor ? {
|
|
1558
|
+
enable: t.twoFactor.enable,
|
|
1559
|
+
verify: t.twoFactor.verify,
|
|
1560
|
+
disable: t.twoFactor.disable,
|
|
1561
|
+
generateBackupCodes: t.twoFactor.generateBackupCodes,
|
|
1562
|
+
isEnabled: t.twoFactor.isEnabled,
|
|
1563
|
+
verify2FA: async (c) => {
|
|
1564
|
+
var d;
|
|
1565
|
+
const u = ((d = t.twoFactor) == null ? void 0 : d.verify2FA) || t.verify2FA;
|
|
1566
|
+
if (!u)
|
|
1192
1567
|
throw new Error("2FA verification is not configured. Provide verify2FA action in config.");
|
|
1193
1568
|
try {
|
|
1194
|
-
const
|
|
1195
|
-
if (
|
|
1196
|
-
const
|
|
1197
|
-
|
|
1198
|
-
error:
|
|
1199
|
-
warning:
|
|
1200
|
-
}),
|
|
1201
|
-
|
|
1202
|
-
new Error(
|
|
1569
|
+
const R = await u(c);
|
|
1570
|
+
if (R.success && R.session) {
|
|
1571
|
+
const C = await y(R);
|
|
1572
|
+
C.success || (process.env.NODE_ENV === "development" && O.debug("Failed to save session cookie after twoFactor.verify2FA", {
|
|
1573
|
+
error: C.error,
|
|
1574
|
+
warning: C.warning
|
|
1575
|
+
}), n.onError && await S(
|
|
1576
|
+
n.onError,
|
|
1577
|
+
new Error(C.warning || C.error || "Failed to save session cookie"),
|
|
1203
1578
|
"twoFactor.verify2FA.setSession"
|
|
1204
1579
|
));
|
|
1205
1580
|
}
|
|
1206
|
-
return
|
|
1207
|
-
} catch (
|
|
1208
|
-
return
|
|
1581
|
+
return R;
|
|
1582
|
+
} catch (R) {
|
|
1583
|
+
return n.onError && await S(n.onError, R instanceof Error ? R : new Error(String(R)), "twoFactor.verify2FA"), {
|
|
1209
1584
|
success: !1,
|
|
1210
|
-
error:
|
|
1211
|
-
errorCode:
|
|
1585
|
+
error: R instanceof Error ? R.message : "2FA verification failed",
|
|
1586
|
+
errorCode: m.UNKNOWN_ERROR
|
|
1212
1587
|
};
|
|
1213
1588
|
}
|
|
1214
1589
|
}
|
|
1215
1590
|
} : void 0,
|
|
1216
1591
|
/**
|
|
1217
1592
|
* Sign in methods - alias for signIn (for backward compatibility)
|
|
1218
|
-
* ✅ IMPROVEMENT: Uses unified signIn logic
|
|
1219
1593
|
*/
|
|
1220
1594
|
signInMethods: {
|
|
1221
|
-
email: (
|
|
1222
|
-
oauth: (
|
|
1223
|
-
var
|
|
1224
|
-
return ((
|
|
1225
|
-
},
|
|
1226
|
-
passkey: (n) => {
|
|
1227
|
-
var o;
|
|
1228
|
-
return ((o = I.passkey) == null ? void 0 : o.call(I, n)) || Promise.reject(new Error("Passkey not configured"));
|
|
1595
|
+
email: (c) => h.email(c),
|
|
1596
|
+
oauth: (c) => {
|
|
1597
|
+
var u;
|
|
1598
|
+
return ((u = h.oauth) == null ? void 0 : u.call(h, c)) || Promise.reject(new Error("OAuth not configured"));
|
|
1229
1599
|
},
|
|
1230
|
-
|
|
1600
|
+
passkey: (c) => {
|
|
1231
1601
|
var u;
|
|
1232
|
-
return ((u =
|
|
1602
|
+
return ((u = h.passkey) == null ? void 0 : u.call(h, c)) || Promise.reject(new Error("Passkey not configured"));
|
|
1603
|
+
},
|
|
1604
|
+
otp: (c, u) => {
|
|
1605
|
+
var d;
|
|
1606
|
+
return ((d = h.otp) == null ? void 0 : d.call(h, c, u)) || Promise.reject(new Error("OTP not configured"));
|
|
1233
1607
|
}
|
|
1234
1608
|
}
|
|
1235
1609
|
};
|
|
1236
|
-
if (
|
|
1237
|
-
const
|
|
1238
|
-
async () => await
|
|
1239
|
-
async () => await
|
|
1610
|
+
if (t.refreshSession) {
|
|
1611
|
+
const c = Ge(
|
|
1612
|
+
async () => await _.refreshSession(),
|
|
1613
|
+
async () => await _.signOut(),
|
|
1240
1614
|
async () => {
|
|
1241
|
-
await
|
|
1615
|
+
await v.clearSessionCookie(), v.clearCache();
|
|
1242
1616
|
},
|
|
1243
1617
|
{
|
|
1244
|
-
...
|
|
1245
|
-
onTokenRefreshed:
|
|
1246
|
-
onTokenRefreshFailed:
|
|
1247
|
-
onBeforeRedirect:
|
|
1618
|
+
...o,
|
|
1619
|
+
onTokenRefreshed: o.onTokenRefreshed,
|
|
1620
|
+
onTokenRefreshFailed: o.onTokenRefreshFailed,
|
|
1621
|
+
onBeforeRedirect: o.onBeforeRedirect
|
|
1248
1622
|
}
|
|
1249
1623
|
);
|
|
1250
|
-
|
|
1624
|
+
_._tokenRefreshManager = c, _._getTokenRefreshManager = () => c;
|
|
1251
1625
|
}
|
|
1252
|
-
return
|
|
1626
|
+
return _;
|
|
1253
1627
|
}
|
|
1254
|
-
function
|
|
1628
|
+
function et(e) {
|
|
1255
1629
|
return {
|
|
1256
|
-
GET: async (
|
|
1257
|
-
POST: async (
|
|
1630
|
+
GET: async (r) => B(r, e, "GET"),
|
|
1631
|
+
POST: async (r) => B(r, e, "POST")
|
|
1258
1632
|
};
|
|
1259
1633
|
}
|
|
1260
|
-
async function
|
|
1261
|
-
const
|
|
1634
|
+
async function B(e, r, t) {
|
|
1635
|
+
const n = new URL(e.url), s = or(n.pathname), i = s.split("/").filter(Boolean);
|
|
1262
1636
|
try {
|
|
1263
|
-
|
|
1264
|
-
|
|
1265
|
-
|
|
1266
|
-
|
|
1267
|
-
|
|
1268
|
-
if (i === "/providers")
|
|
1269
|
-
return f.json({
|
|
1270
|
-
providers: {
|
|
1271
|
-
email: !!e.signIn.email,
|
|
1272
|
-
oauth: !!e.signIn.oauth,
|
|
1273
|
-
passkey: !!e.signIn.passkey
|
|
1274
|
-
}
|
|
1275
|
-
});
|
|
1276
|
-
if (i.startsWith("/oauth/callback") || d[0] === "oauth" && d[1] === "callback") {
|
|
1277
|
-
if (!e.oauthCallback)
|
|
1278
|
-
return f.redirect(new URL("/login?error=oauth_not_configured", r.url));
|
|
1279
|
-
const c = d[2] || t.searchParams.get("provider"), a = t.searchParams.get("code"), p = t.searchParams.get("state");
|
|
1280
|
-
if (!c || !a || !p)
|
|
1281
|
-
return f.redirect(new URL("/login?error=oauth_missing_params", r.url));
|
|
1282
|
-
try {
|
|
1283
|
-
const v = await e.oauthCallback(c, a, p);
|
|
1284
|
-
if (v.success) {
|
|
1285
|
-
const S = t.searchParams.get("callbackUrl") || "/";
|
|
1286
|
-
return f.redirect(new URL(S, r.url));
|
|
1287
|
-
} else
|
|
1288
|
-
return f.redirect(
|
|
1289
|
-
new URL(`/login?error=${encodeURIComponent(v.error || "oauth_failed")}`, r.url)
|
|
1290
|
-
);
|
|
1291
|
-
} catch (v) {
|
|
1292
|
-
return f.redirect(
|
|
1293
|
-
new URL(
|
|
1294
|
-
`/login?error=${encodeURIComponent(v instanceof Error ? v.message : "oauth_error")}`,
|
|
1295
|
-
r.url
|
|
1296
|
-
)
|
|
1297
|
-
);
|
|
1298
|
-
}
|
|
1299
|
-
}
|
|
1300
|
-
return f.json(
|
|
1301
|
-
{ error: "Not found" },
|
|
1302
|
-
{ status: 404 }
|
|
1303
|
-
);
|
|
1304
|
-
}
|
|
1305
|
-
if (s === "POST") {
|
|
1306
|
-
const c = await r.json().catch(() => ({}));
|
|
1307
|
-
if (i === "/sign-in" || d[0] === "sign-in") {
|
|
1308
|
-
if (c.provider === "email" && c.email && c.password) {
|
|
1309
|
-
const a = await e.signIn.email({
|
|
1310
|
-
email: c.email,
|
|
1311
|
-
password: c.password
|
|
1312
|
-
});
|
|
1313
|
-
return f.json(a);
|
|
1314
|
-
}
|
|
1315
|
-
if (c.provider === "oauth" && c.providerName) {
|
|
1316
|
-
if (!e.signIn.oauth)
|
|
1317
|
-
return f.json(
|
|
1318
|
-
{ success: !1, error: "OAuth is not configured" },
|
|
1319
|
-
{ status: 400 }
|
|
1320
|
-
);
|
|
1321
|
-
const a = await e.signIn.oauth(c.providerName);
|
|
1322
|
-
return f.json(a);
|
|
1323
|
-
}
|
|
1324
|
-
if (c.provider === "passkey") {
|
|
1325
|
-
if (!e.signIn.passkey)
|
|
1326
|
-
return f.json(
|
|
1327
|
-
{ success: !1, error: "PassKey is not configured" },
|
|
1328
|
-
{ status: 400 }
|
|
1329
|
-
);
|
|
1330
|
-
const a = await e.signIn.passkey(c.options);
|
|
1331
|
-
return f.json(a);
|
|
1332
|
-
}
|
|
1333
|
-
return f.json(
|
|
1334
|
-
{ success: !1, error: "Invalid sign in request" },
|
|
1335
|
-
{ status: 400 }
|
|
1336
|
-
);
|
|
1337
|
-
}
|
|
1338
|
-
if (i === "/sign-up" || d[0] === "sign-up") {
|
|
1339
|
-
if (!e.signUp)
|
|
1340
|
-
return f.json(
|
|
1341
|
-
{ success: !1, error: "Sign up is not configured" },
|
|
1342
|
-
{ status: 400 }
|
|
1343
|
-
);
|
|
1344
|
-
const a = await e.signUp(c);
|
|
1345
|
-
return f.json(a);
|
|
1346
|
-
}
|
|
1347
|
-
if (i === "/sign-out" || d[0] === "sign-out") {
|
|
1348
|
-
const a = await e.signOut();
|
|
1349
|
-
return f.json(a);
|
|
1350
|
-
}
|
|
1351
|
-
if (i === "/reset-password" || d[0] === "reset-password") {
|
|
1352
|
-
if (!e.resetPassword)
|
|
1353
|
-
return f.json(
|
|
1354
|
-
{ success: !1, error: "Password reset is not configured" },
|
|
1355
|
-
{ status: 400 }
|
|
1356
|
-
);
|
|
1357
|
-
const a = await e.resetPassword(c.email);
|
|
1358
|
-
return f.json(a);
|
|
1359
|
-
}
|
|
1360
|
-
if (i === "/verify-email" || d[0] === "verify-email") {
|
|
1361
|
-
if (!e.verifyEmail)
|
|
1362
|
-
return f.json(
|
|
1363
|
-
{ success: !1, error: "Email verification is not configured" },
|
|
1364
|
-
{ status: 400 }
|
|
1365
|
-
);
|
|
1366
|
-
const a = await e.verifyEmail(c.token);
|
|
1367
|
-
return f.json(a);
|
|
1368
|
-
}
|
|
1369
|
-
if (i === "/refresh" || d[0] === "refresh") {
|
|
1370
|
-
if (!e.refreshSession) {
|
|
1371
|
-
const p = await e.getSession();
|
|
1372
|
-
return f.json({ session: p });
|
|
1373
|
-
}
|
|
1374
|
-
const a = await e.refreshSession();
|
|
1375
|
-
return f.json({ session: a });
|
|
1376
|
-
}
|
|
1377
|
-
if (i.startsWith("/oauth/callback") || d[0] === "oauth" && d[1] === "callback") {
|
|
1378
|
-
if (!e.oauthCallback)
|
|
1379
|
-
return f.json(
|
|
1380
|
-
{ success: !1, error: "OAuth callback is not configured" },
|
|
1381
|
-
{ status: 400 }
|
|
1382
|
-
);
|
|
1383
|
-
const a = c.provider || d[2] || t.searchParams.get("provider"), p = c.code || t.searchParams.get("code"), v = c.state || t.searchParams.get("state");
|
|
1384
|
-
if (!a || !p || !v)
|
|
1385
|
-
return f.json(
|
|
1386
|
-
{
|
|
1387
|
-
success: !1,
|
|
1388
|
-
error: "Missing required OAuth parameters. Provider, code, and state are required."
|
|
1389
|
-
},
|
|
1390
|
-
{ status: 400 }
|
|
1391
|
-
);
|
|
1392
|
-
const S = await e.oauthCallback(a, p, v);
|
|
1393
|
-
return f.json(S);
|
|
1394
|
-
}
|
|
1395
|
-
if (i.startsWith("/passkey")) {
|
|
1396
|
-
if (!e.passkey)
|
|
1397
|
-
return f.json(
|
|
1398
|
-
{ success: !1, error: "PassKey is not configured" },
|
|
1399
|
-
{ status: 400 }
|
|
1400
|
-
);
|
|
1401
|
-
if (d[1] === "register" && e.passkey.register) {
|
|
1402
|
-
const a = await e.passkey.register(c.options);
|
|
1403
|
-
return f.json(a);
|
|
1404
|
-
}
|
|
1405
|
-
if (d[1] === "list" && e.passkey.list) {
|
|
1406
|
-
const a = await e.passkey.list();
|
|
1407
|
-
return f.json(a);
|
|
1408
|
-
}
|
|
1409
|
-
if (d[1] === "remove" && e.passkey.remove) {
|
|
1410
|
-
const a = await e.passkey.remove(c.passkeyId);
|
|
1411
|
-
return f.json(a);
|
|
1412
|
-
}
|
|
1413
|
-
}
|
|
1414
|
-
if (i === "/verify-2fa" || d[0] === "verify-2fa") {
|
|
1415
|
-
if (!e.verify2FA)
|
|
1416
|
-
return f.json(
|
|
1417
|
-
{ success: !1, error: "2FA verification is not configured" },
|
|
1418
|
-
{ status: 400 }
|
|
1419
|
-
);
|
|
1420
|
-
if (!c.email || !c.userId || !c.code)
|
|
1421
|
-
return f.json(
|
|
1422
|
-
{
|
|
1423
|
-
success: !1,
|
|
1424
|
-
error: "Missing required parameters. Email, userId, and code are required."
|
|
1425
|
-
},
|
|
1426
|
-
{ status: 400 }
|
|
1427
|
-
);
|
|
1428
|
-
const a = await e.verify2FA({
|
|
1429
|
-
email: c.email,
|
|
1430
|
-
userId: c.userId,
|
|
1431
|
-
code: c.code
|
|
1432
|
-
});
|
|
1433
|
-
return f.json(a);
|
|
1434
|
-
}
|
|
1435
|
-
if (i.startsWith("/two-factor")) {
|
|
1436
|
-
if (!e.twoFactor)
|
|
1437
|
-
return f.json(
|
|
1438
|
-
{ success: !1, error: "Two-Factor Authentication is not configured" },
|
|
1439
|
-
{ status: 400 }
|
|
1440
|
-
);
|
|
1441
|
-
if (d[1] === "enable" && e.twoFactor.enable) {
|
|
1442
|
-
const a = await e.twoFactor.enable();
|
|
1443
|
-
return f.json(a);
|
|
1444
|
-
}
|
|
1445
|
-
if (d[1] === "verify" && e.twoFactor.verify) {
|
|
1446
|
-
const a = await e.twoFactor.verify(c.code);
|
|
1447
|
-
return f.json(a);
|
|
1448
|
-
}
|
|
1449
|
-
if (d[1] === "disable" && e.twoFactor.disable) {
|
|
1450
|
-
const a = await e.twoFactor.disable();
|
|
1451
|
-
return f.json(a);
|
|
1452
|
-
}
|
|
1453
|
-
if (d[1] === "backup-codes" && e.twoFactor.generateBackupCodes) {
|
|
1454
|
-
const a = await e.twoFactor.generateBackupCodes();
|
|
1455
|
-
return f.json(a);
|
|
1456
|
-
}
|
|
1457
|
-
if (d[1] === "is-enabled" && e.twoFactor.isEnabled) {
|
|
1458
|
-
const a = await e.twoFactor.isEnabled();
|
|
1459
|
-
return f.json({ enabled: a });
|
|
1460
|
-
}
|
|
1461
|
-
}
|
|
1462
|
-
return f.json(
|
|
1463
|
-
{ error: "Not found" },
|
|
1464
|
-
{ status: 404 }
|
|
1465
|
-
);
|
|
1466
|
-
}
|
|
1467
|
-
return f.json(
|
|
1468
|
-
{ error: "Method not allowed" },
|
|
1469
|
-
{ status: 405 }
|
|
1470
|
-
);
|
|
1471
|
-
} catch (c) {
|
|
1472
|
-
return f.json(
|
|
1473
|
-
{
|
|
1474
|
-
success: !1,
|
|
1475
|
-
error: c instanceof Error ? c.message : "Request failed"
|
|
1476
|
-
},
|
|
1477
|
-
{ status: 500 }
|
|
1637
|
+
return t === "GET" ? await ar(e, r, s, i, n) : t === "POST" ? await cr(e, r, s, i, n) : T("Method not allowed", 405);
|
|
1638
|
+
} catch (o) {
|
|
1639
|
+
return T(
|
|
1640
|
+
o instanceof Error ? o.message : "Request failed",
|
|
1641
|
+
500
|
|
1478
1642
|
);
|
|
1479
1643
|
}
|
|
1480
1644
|
}
|
|
1481
|
-
function
|
|
1482
|
-
return
|
|
1483
|
-
|
|
1645
|
+
function or(e) {
|
|
1646
|
+
return e.replace(/^\/api\/auth/, "") || "/session";
|
|
1647
|
+
}
|
|
1648
|
+
async function ar(e, r, t, n, s) {
|
|
1649
|
+
if (t === "/session" || t === "/") {
|
|
1650
|
+
const i = await r.getSession();
|
|
1651
|
+
return E.json({ session: i });
|
|
1652
|
+
}
|
|
1653
|
+
return t === "/providers" ? E.json({
|
|
1654
|
+
providers: {
|
|
1655
|
+
email: !!r.signIn.email,
|
|
1656
|
+
oauth: !!r.signIn.oauth,
|
|
1657
|
+
passkey: !!r.signIn.passkey
|
|
1658
|
+
}
|
|
1659
|
+
}) : re(t, n) ? await te(e, r, t, n, s, "GET") : T("Not found", 404);
|
|
1660
|
+
}
|
|
1661
|
+
async function cr(e, r, t, n, s) {
|
|
1662
|
+
const i = await ur(e);
|
|
1663
|
+
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) : T("Not found", 404);
|
|
1664
|
+
}
|
|
1665
|
+
async function ur(e) {
|
|
1666
|
+
try {
|
|
1667
|
+
return await e.json();
|
|
1668
|
+
} catch {
|
|
1669
|
+
return {};
|
|
1670
|
+
}
|
|
1671
|
+
}
|
|
1672
|
+
function re(e, r) {
|
|
1673
|
+
return e === "/callback" || e.startsWith("/oauth/callback") || r[0] === "oauth" && r[1] === "callback" || r[0] === "callback";
|
|
1674
|
+
}
|
|
1675
|
+
async function te(e, r, t, n, s, i, o) {
|
|
1676
|
+
if (!r.oauthCallback)
|
|
1677
|
+
return i === "GET" ? M(e.url, "oauth_not_configured") : T("OAuth callback is not configured", 400);
|
|
1678
|
+
const a = lr(n, s, o), f = (o == null ? void 0 : o.code) ?? s.searchParams.get("code"), l = (o == null ? void 0 : o.state) ?? s.searchParams.get("state");
|
|
1679
|
+
if (!f || !l)
|
|
1680
|
+
return i === "GET" ? M(e.url, "oauth_missing_params") : T("Missing required OAuth parameters. Code and state are required.", 400);
|
|
1681
|
+
try {
|
|
1682
|
+
const w = await r.oauthCallback(a ?? "", f, l);
|
|
1683
|
+
return i === "GET" ? w.success ? kr(e.url, s.searchParams.get("callbackUrl")) : M(e.url, w.error ?? "oauth_failed") : E.json(w);
|
|
1684
|
+
} catch (w) {
|
|
1685
|
+
return i === "GET" ? M(e.url, w instanceof Error ? w.message : "oauth_error") : T(w instanceof Error ? w.message : "OAuth callback failed", 500);
|
|
1686
|
+
}
|
|
1687
|
+
}
|
|
1688
|
+
function lr(e, r, t) {
|
|
1689
|
+
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");
|
|
1690
|
+
}
|
|
1691
|
+
async function fr(e, r) {
|
|
1692
|
+
if (r.provider === "email" && r.email && r.password) {
|
|
1693
|
+
const t = {
|
|
1694
|
+
email: r.email,
|
|
1695
|
+
password: r.password
|
|
1696
|
+
}, n = await e.signIn.email(t);
|
|
1697
|
+
return E.json(n);
|
|
1698
|
+
}
|
|
1699
|
+
if (r.provider === "oauth" && r.providerName) {
|
|
1700
|
+
if (!e.signIn.oauth)
|
|
1701
|
+
return T("OAuth is not configured", 400);
|
|
1702
|
+
const t = await e.signIn.oauth(r.providerName);
|
|
1703
|
+
return E.json(t);
|
|
1704
|
+
}
|
|
1705
|
+
if (r.provider === "passkey") {
|
|
1706
|
+
if (!e.signIn.passkey)
|
|
1707
|
+
return T("PassKey is not configured", 400);
|
|
1708
|
+
const t = await e.signIn.passkey(r.options);
|
|
1709
|
+
return E.json(t);
|
|
1710
|
+
}
|
|
1711
|
+
return T("Invalid sign in request", 400);
|
|
1712
|
+
}
|
|
1713
|
+
async function dr(e, r) {
|
|
1714
|
+
if (!e.signUp)
|
|
1715
|
+
return T("Sign up is not configured", 400);
|
|
1716
|
+
const t = await e.signUp(r);
|
|
1717
|
+
return E.json(t);
|
|
1718
|
+
}
|
|
1719
|
+
async function hr(e) {
|
|
1720
|
+
const r = await e.signOut();
|
|
1721
|
+
return E.json(r);
|
|
1722
|
+
}
|
|
1723
|
+
async function gr(e, r) {
|
|
1724
|
+
if (!e.resetPassword)
|
|
1725
|
+
return T("Password reset is not configured", 400);
|
|
1726
|
+
if (!r.email || typeof r.email != "string")
|
|
1727
|
+
return T("Email is required", 400);
|
|
1728
|
+
const t = await e.resetPassword(r.email);
|
|
1729
|
+
return E.json(t);
|
|
1730
|
+
}
|
|
1731
|
+
async function wr(e, r) {
|
|
1732
|
+
if (!e.verifyEmail)
|
|
1733
|
+
return T("Email verification is not configured", 400);
|
|
1734
|
+
if (!r.token || typeof r.token != "string")
|
|
1735
|
+
return T("Token is required", 400);
|
|
1736
|
+
const t = await e.verifyEmail(r.token);
|
|
1737
|
+
return E.json(t);
|
|
1738
|
+
}
|
|
1739
|
+
async function pr(e) {
|
|
1740
|
+
if (!e.refreshSession) {
|
|
1741
|
+
const t = await e.getSession();
|
|
1742
|
+
return E.json({ session: t });
|
|
1743
|
+
}
|
|
1744
|
+
const r = await e.refreshSession();
|
|
1745
|
+
return E.json({ session: r });
|
|
1746
|
+
}
|
|
1747
|
+
async function mr(e, r) {
|
|
1748
|
+
if (!e.verify2FA)
|
|
1749
|
+
return T("2FA verification is not configured", 400);
|
|
1750
|
+
if (!r.email || !r.userId || !r.code)
|
|
1751
|
+
return T("Missing required parameters. Email, userId, and code are required.", 400);
|
|
1752
|
+
const t = {
|
|
1753
|
+
email: r.email,
|
|
1754
|
+
userId: r.userId,
|
|
1755
|
+
code: r.code
|
|
1756
|
+
}, n = await e.verify2FA(t);
|
|
1757
|
+
return E.json(n);
|
|
1758
|
+
}
|
|
1759
|
+
async function Er(e, r, t, n) {
|
|
1760
|
+
if (!e.passkey)
|
|
1761
|
+
return T("PassKey is not configured", 400);
|
|
1762
|
+
const s = t[1];
|
|
1763
|
+
if (s === "register" && e.passkey.register) {
|
|
1764
|
+
const i = await e.passkey.register(n.options);
|
|
1765
|
+
return E.json(i);
|
|
1766
|
+
}
|
|
1767
|
+
if (s === "list" && e.passkey.list) {
|
|
1768
|
+
const i = await e.passkey.list();
|
|
1769
|
+
return E.json(i);
|
|
1770
|
+
}
|
|
1771
|
+
if (s === "remove" && e.passkey.remove) {
|
|
1772
|
+
if (!n.passkeyId || typeof n.passkeyId != "string")
|
|
1773
|
+
return T("Passkey ID is required", 400);
|
|
1774
|
+
const i = await e.passkey.remove(n.passkeyId);
|
|
1775
|
+
return E.json(i);
|
|
1776
|
+
}
|
|
1777
|
+
return T("Invalid Passkey request", 400);
|
|
1778
|
+
}
|
|
1779
|
+
async function yr(e, r, t) {
|
|
1780
|
+
if (!e.twoFactor)
|
|
1781
|
+
return T("Two-Factor Authentication is not configured", 400);
|
|
1782
|
+
const n = r[1];
|
|
1783
|
+
if (n === "enable" && e.twoFactor.enable) {
|
|
1784
|
+
const s = await e.twoFactor.enable();
|
|
1785
|
+
return E.json(s);
|
|
1786
|
+
}
|
|
1787
|
+
if (n === "verify" && e.twoFactor.verify) {
|
|
1788
|
+
if (!t.code || typeof t.code != "string")
|
|
1789
|
+
return T("Code is required", 400);
|
|
1790
|
+
const s = await e.twoFactor.verify(t.code);
|
|
1791
|
+
return E.json(s);
|
|
1792
|
+
}
|
|
1793
|
+
if (n === "disable" && e.twoFactor.disable) {
|
|
1794
|
+
const s = await e.twoFactor.disable();
|
|
1795
|
+
return E.json(s);
|
|
1796
|
+
}
|
|
1797
|
+
if (n === "backup-codes" && e.twoFactor.generateBackupCodes) {
|
|
1798
|
+
const s = await e.twoFactor.generateBackupCodes();
|
|
1799
|
+
return E.json(s);
|
|
1800
|
+
}
|
|
1801
|
+
if (n === "is-enabled" && e.twoFactor.isEnabled) {
|
|
1802
|
+
const s = await e.twoFactor.isEnabled();
|
|
1803
|
+
return E.json({ enabled: s });
|
|
1804
|
+
}
|
|
1805
|
+
return T("Invalid two-factor request", 400);
|
|
1806
|
+
}
|
|
1807
|
+
function T(e, r) {
|
|
1808
|
+
return E.json(
|
|
1809
|
+
{
|
|
1810
|
+
success: !1,
|
|
1811
|
+
error: e
|
|
1812
|
+
},
|
|
1813
|
+
{ status: r }
|
|
1814
|
+
);
|
|
1815
|
+
}
|
|
1816
|
+
function M(e, r) {
|
|
1817
|
+
return E.redirect(new URL(`/login?error=${encodeURIComponent(r)}`, e));
|
|
1818
|
+
}
|
|
1819
|
+
function kr(e, r) {
|
|
1820
|
+
const t = r ?? "/";
|
|
1821
|
+
return E.redirect(new URL(t, e));
|
|
1822
|
+
}
|
|
1823
|
+
function rt(e) {
|
|
1824
|
+
return async (r) => {
|
|
1825
|
+
const { method: t, nextUrl: n } = r, i = n.pathname.replace(/^\/api\/auth/, "") || "/";
|
|
1484
1826
|
try {
|
|
1485
|
-
let
|
|
1486
|
-
if (
|
|
1827
|
+
let o;
|
|
1828
|
+
if (t !== "GET" && t !== "HEAD")
|
|
1487
1829
|
try {
|
|
1488
|
-
|
|
1830
|
+
o = await r.json();
|
|
1489
1831
|
} catch {
|
|
1490
1832
|
}
|
|
1491
|
-
const a = Object.fromEntries(
|
|
1492
|
-
`${process.env.NEXT_PUBLIC_API_URL || ""}/api/auth${
|
|
1833
|
+
const a = Object.fromEntries(n.searchParams.entries()), f = await fetch(
|
|
1834
|
+
`${process.env.NEXT_PUBLIC_API_URL || ""}/api/auth${i}${Object.keys(a).length > 0 ? `?${new URLSearchParams(a).toString()}` : ""}`,
|
|
1493
1835
|
{
|
|
1494
|
-
method:
|
|
1836
|
+
method: t,
|
|
1495
1837
|
headers: {
|
|
1496
1838
|
"Content-Type": "application/json",
|
|
1497
|
-
...Object.fromEntries(
|
|
1839
|
+
...Object.fromEntries(r.headers.entries())
|
|
1498
1840
|
},
|
|
1499
|
-
body:
|
|
1841
|
+
body: o ? JSON.stringify(o) : void 0
|
|
1500
1842
|
}
|
|
1501
|
-
),
|
|
1502
|
-
return
|
|
1503
|
-
status:
|
|
1843
|
+
), l = await f.json();
|
|
1844
|
+
return E.json(l, {
|
|
1845
|
+
status: f.status,
|
|
1504
1846
|
headers: {
|
|
1505
|
-
...Object.fromEntries(
|
|
1847
|
+
...Object.fromEntries(f.headers.entries())
|
|
1506
1848
|
}
|
|
1507
1849
|
});
|
|
1508
|
-
} catch (
|
|
1509
|
-
return console.error("API handler error:",
|
|
1850
|
+
} catch (o) {
|
|
1851
|
+
return console.error("API handler error:", o), E.json(
|
|
1510
1852
|
{
|
|
1511
1853
|
success: !1,
|
|
1512
|
-
error:
|
|
1854
|
+
error: o instanceof Error ? o.message : "Internal server error"
|
|
1513
1855
|
},
|
|
1514
1856
|
{ status: 500 }
|
|
1515
1857
|
);
|
|
1516
1858
|
}
|
|
1517
1859
|
};
|
|
1518
1860
|
}
|
|
1519
|
-
function
|
|
1520
|
-
return async (
|
|
1521
|
-
const { searchParams:
|
|
1522
|
-
if (!
|
|
1523
|
-
return
|
|
1524
|
-
new URL("/login?error=oauth_missing_params",
|
|
1861
|
+
function tt(e) {
|
|
1862
|
+
return async (r) => {
|
|
1863
|
+
const { searchParams: t } = r.nextUrl, n = t.get("provider"), s = t.get("code"), i = t.get("state");
|
|
1864
|
+
if (!n || !s || !i)
|
|
1865
|
+
return E.redirect(
|
|
1866
|
+
new URL("/login?error=oauth_missing_params", r.url)
|
|
1525
1867
|
);
|
|
1526
1868
|
try {
|
|
1527
|
-
if (!
|
|
1528
|
-
return
|
|
1529
|
-
new URL("/login?error=oauth_not_configured",
|
|
1869
|
+
if (!e.oauthCallback)
|
|
1870
|
+
return E.redirect(
|
|
1871
|
+
new URL("/login?error=oauth_not_configured", r.url)
|
|
1530
1872
|
);
|
|
1531
|
-
const
|
|
1532
|
-
if (
|
|
1533
|
-
const a =
|
|
1534
|
-
return
|
|
1873
|
+
const o = await e.oauthCallback(n, s, i);
|
|
1874
|
+
if (o.success) {
|
|
1875
|
+
const a = t.get("callbackUrl") || "/";
|
|
1876
|
+
return E.redirect(new URL(a, r.url));
|
|
1535
1877
|
} else {
|
|
1536
|
-
const a =
|
|
1537
|
-
return
|
|
1538
|
-
new URL(`/login?error=${a}`,
|
|
1878
|
+
const a = o.errorCode ? `${encodeURIComponent(o.error || "oauth_failed")}&code=${o.errorCode}` : encodeURIComponent(o.error || "oauth_failed");
|
|
1879
|
+
return E.redirect(
|
|
1880
|
+
new URL(`/login?error=${a}`, r.url)
|
|
1539
1881
|
);
|
|
1540
1882
|
}
|
|
1541
|
-
} catch (
|
|
1542
|
-
return process.env.NODE_ENV === "development" && console.error("[Mulguard] OAuth callback error:",
|
|
1883
|
+
} catch (o) {
|
|
1884
|
+
return process.env.NODE_ENV === "development" && console.error("[Mulguard] OAuth callback error:", o), E.redirect(
|
|
1543
1885
|
new URL(
|
|
1544
|
-
`/login?error=${encodeURIComponent(
|
|
1545
|
-
|
|
1886
|
+
`/login?error=${encodeURIComponent(o instanceof Error ? o.message : "oauth_error")}`,
|
|
1887
|
+
r.url
|
|
1546
1888
|
)
|
|
1547
1889
|
);
|
|
1548
1890
|
}
|
|
1549
1891
|
};
|
|
1550
1892
|
}
|
|
1551
|
-
function
|
|
1552
|
-
const
|
|
1893
|
+
function F(e, r) {
|
|
1894
|
+
const t = H({
|
|
1553
1895
|
// Customize headers if needed
|
|
1554
1896
|
"X-Frame-Options": "SAMEORIGIN"
|
|
1555
1897
|
// Allow same-origin framing
|
|
1556
1898
|
});
|
|
1557
|
-
for (const [
|
|
1558
|
-
|
|
1559
|
-
return
|
|
1899
|
+
for (const [n, s] of Object.entries(t))
|
|
1900
|
+
s && typeof s == "string" && r.headers.set(n, s);
|
|
1901
|
+
return r;
|
|
1560
1902
|
}
|
|
1561
|
-
function
|
|
1562
|
-
return async (
|
|
1563
|
-
const
|
|
1564
|
-
return
|
|
1903
|
+
function nt() {
|
|
1904
|
+
return async (e) => {
|
|
1905
|
+
const r = E.next();
|
|
1906
|
+
return F(e, r);
|
|
1565
1907
|
};
|
|
1566
1908
|
}
|
|
1567
|
-
function
|
|
1909
|
+
function st(e, r = {}) {
|
|
1568
1910
|
const {
|
|
1569
|
-
protectedRoutes:
|
|
1570
|
-
publicRoutes:
|
|
1571
|
-
redirectTo:
|
|
1572
|
-
redirectIfAuthenticated:
|
|
1573
|
-
} =
|
|
1574
|
-
return async (
|
|
1575
|
-
const { pathname: a } =
|
|
1576
|
-
let
|
|
1911
|
+
protectedRoutes: t = [],
|
|
1912
|
+
publicRoutes: n = [],
|
|
1913
|
+
redirectTo: s = "/login",
|
|
1914
|
+
redirectIfAuthenticated: i
|
|
1915
|
+
} = r;
|
|
1916
|
+
return async (o) => {
|
|
1917
|
+
const { pathname: a } = o.nextUrl, f = t.some((g) => a.startsWith(g));
|
|
1918
|
+
let l = null;
|
|
1577
1919
|
try {
|
|
1578
|
-
|
|
1920
|
+
l = await e.getSession();
|
|
1579
1921
|
} catch (g) {
|
|
1580
1922
|
console.error("Middleware: Failed to get session:", g);
|
|
1581
1923
|
}
|
|
1582
|
-
if (
|
|
1583
|
-
const g =
|
|
1584
|
-
return g.pathname =
|
|
1924
|
+
if (f && !l) {
|
|
1925
|
+
const g = o.nextUrl.clone();
|
|
1926
|
+
return g.pathname = s, g.searchParams.set("callbackUrl", a), E.redirect(g);
|
|
1585
1927
|
}
|
|
1586
|
-
if (
|
|
1587
|
-
const A =
|
|
1588
|
-
A.pathname =
|
|
1589
|
-
const
|
|
1590
|
-
return
|
|
1928
|
+
if (i && l && (a.startsWith("/login") || a.startsWith("/register"))) {
|
|
1929
|
+
const A = o.nextUrl.clone();
|
|
1930
|
+
A.pathname = i;
|
|
1931
|
+
const S = E.redirect(A);
|
|
1932
|
+
return F(o, S);
|
|
1591
1933
|
}
|
|
1592
|
-
const
|
|
1593
|
-
return
|
|
1934
|
+
const w = E.next();
|
|
1935
|
+
return F(o, w);
|
|
1594
1936
|
};
|
|
1595
1937
|
}
|
|
1596
|
-
async function
|
|
1597
|
-
var
|
|
1938
|
+
async function it(e, r) {
|
|
1939
|
+
var t;
|
|
1598
1940
|
try {
|
|
1599
|
-
const
|
|
1600
|
-
return
|
|
1941
|
+
const n = await e.getSession();
|
|
1942
|
+
return n ? ((t = n.user.roles) == null ? void 0 : t.includes(r)) ?? !1 : !1;
|
|
1601
1943
|
} catch {
|
|
1602
1944
|
return !1;
|
|
1603
1945
|
}
|
|
1604
1946
|
}
|
|
1605
|
-
function
|
|
1947
|
+
function ot(e) {
|
|
1606
1948
|
const {
|
|
1607
|
-
auth:
|
|
1608
|
-
protectedRoutes:
|
|
1609
|
-
publicRoutes:
|
|
1610
|
-
redirectTo:
|
|
1611
|
-
redirectIfAuthenticated:
|
|
1612
|
-
apiPrefix:
|
|
1613
|
-
} =
|
|
1949
|
+
auth: r,
|
|
1950
|
+
protectedRoutes: t = [],
|
|
1951
|
+
publicRoutes: n = [],
|
|
1952
|
+
redirectTo: s = "/login",
|
|
1953
|
+
redirectIfAuthenticated: i,
|
|
1954
|
+
apiPrefix: o = "/api/auth"
|
|
1955
|
+
} = e;
|
|
1614
1956
|
return async (a) => {
|
|
1615
|
-
const { pathname:
|
|
1616
|
-
if (
|
|
1617
|
-
const A =
|
|
1618
|
-
return
|
|
1957
|
+
const { pathname: f } = a.nextUrl;
|
|
1958
|
+
if (f.startsWith(o)) {
|
|
1959
|
+
const A = E.next();
|
|
1960
|
+
return F(a, A);
|
|
1619
1961
|
}
|
|
1620
|
-
const
|
|
1621
|
-
let
|
|
1622
|
-
if (
|
|
1962
|
+
const l = t.some((A) => f.startsWith(A));
|
|
1963
|
+
let w = null;
|
|
1964
|
+
if (l || i)
|
|
1623
1965
|
try {
|
|
1624
|
-
|
|
1966
|
+
w = await r.getSession();
|
|
1625
1967
|
} catch (A) {
|
|
1626
1968
|
console.error("Middleware: Failed to get session:", A);
|
|
1627
1969
|
}
|
|
1628
|
-
if (
|
|
1970
|
+
if (l && !w) {
|
|
1629
1971
|
const A = a.nextUrl.clone();
|
|
1630
|
-
A.pathname =
|
|
1631
|
-
const
|
|
1632
|
-
return
|
|
1972
|
+
A.pathname = s, A.searchParams.set("callbackUrl", f);
|
|
1973
|
+
const S = E.redirect(A);
|
|
1974
|
+
return F(a, S);
|
|
1633
1975
|
}
|
|
1634
|
-
if (
|
|
1635
|
-
const
|
|
1636
|
-
|
|
1637
|
-
const
|
|
1638
|
-
return
|
|
1976
|
+
if (i && w && (f.startsWith("/login") || f.startsWith("/register"))) {
|
|
1977
|
+
const S = a.nextUrl.clone();
|
|
1978
|
+
S.pathname = i;
|
|
1979
|
+
const v = E.redirect(S);
|
|
1980
|
+
return F(a, v);
|
|
1639
1981
|
}
|
|
1640
|
-
const g =
|
|
1641
|
-
return
|
|
1982
|
+
const g = E.next();
|
|
1983
|
+
return F(a, g);
|
|
1642
1984
|
};
|
|
1643
1985
|
}
|
|
1644
|
-
async function
|
|
1645
|
-
var
|
|
1986
|
+
async function at(e, r) {
|
|
1987
|
+
var t;
|
|
1646
1988
|
try {
|
|
1647
|
-
const
|
|
1648
|
-
return
|
|
1989
|
+
const n = await e.getSession();
|
|
1990
|
+
return n ? ((t = n.user.roles) == null ? void 0 : t.includes(r)) ?? !1 : !1;
|
|
1649
1991
|
} catch {
|
|
1650
1992
|
return !1;
|
|
1651
1993
|
}
|
|
1652
1994
|
}
|
|
1653
1995
|
export {
|
|
1654
|
-
|
|
1655
|
-
|
|
1656
|
-
|
|
1657
|
-
|
|
1658
|
-
|
|
1659
|
-
|
|
1660
|
-
|
|
1661
|
-
|
|
1662
|
-
|
|
1663
|
-
|
|
1664
|
-
|
|
1665
|
-
|
|
1666
|
-
|
|
1667
|
-
|
|
1668
|
-
|
|
1669
|
-
|
|
1670
|
-
|
|
1671
|
-
|
|
1672
|
-
|
|
1673
|
-
|
|
1674
|
-
|
|
1675
|
-
|
|
1676
|
-
|
|
1677
|
-
|
|
1678
|
-
|
|
1679
|
-
|
|
1680
|
-
|
|
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
|
-
|
|
1996
|
+
Ie as CSRFProtection,
|
|
1997
|
+
fe as DEFAULT_SECURITY_HEADERS,
|
|
1998
|
+
Te as MemoryCSRFStore,
|
|
1999
|
+
ze as MemoryOAuthStateStore,
|
|
2000
|
+
le as RateLimiter,
|
|
2001
|
+
Ir as applySecurityHeaders,
|
|
2002
|
+
oe as buildCookieOptions,
|
|
2003
|
+
be as buildOAuthAuthorizationUrl,
|
|
2004
|
+
it as checkRole,
|
|
2005
|
+
at as checkRoleProxy,
|
|
2006
|
+
Mr as containsXSSPattern,
|
|
2007
|
+
rt as createApiHandler,
|
|
2008
|
+
st as createAuthMiddleware,
|
|
2009
|
+
Dr as createCSRFProtection,
|
|
2010
|
+
$e as createMemoryOAuthStateStore,
|
|
2011
|
+
tt as createOAuthCallbackHandler,
|
|
2012
|
+
ot as createProxyMiddleware,
|
|
2013
|
+
Tr as createRateLimiter,
|
|
2014
|
+
nt as createSecurityMiddleware,
|
|
2015
|
+
wt as createServerAuthMiddleware,
|
|
2016
|
+
pt as createServerHelpers,
|
|
2017
|
+
mt as createServerUtils,
|
|
2018
|
+
Et as createSessionManager,
|
|
2019
|
+
ie as deleteCookie,
|
|
2020
|
+
yt as deleteOAuthStateCookie,
|
|
2021
|
+
Oe as escapeHTML,
|
|
2022
|
+
Ue as exchangeOAuthCode,
|
|
2023
|
+
_e as generateCSRFToken,
|
|
2024
|
+
Y as generateToken,
|
|
2025
|
+
ce as getCookie,
|
|
2026
|
+
kt as getCurrentUser,
|
|
2027
|
+
Br as getErrorCode,
|
|
2028
|
+
qr as getErrorMessage,
|
|
2029
|
+
vt as getOAuthStateCookie,
|
|
2030
|
+
Fe as getOAuthUserInfo,
|
|
2031
|
+
j as getProviderMetadata,
|
|
2032
|
+
H as getSecurityHeaders,
|
|
2033
|
+
St as getServerSession,
|
|
2034
|
+
Rt as getSessionTimeUntilExpiry,
|
|
2035
|
+
Xr as getUserFriendlyError,
|
|
2036
|
+
Gr as hasErrorCode,
|
|
2037
|
+
Ce as isAuthError,
|
|
2038
|
+
Hr as isAuthSuccess,
|
|
2039
|
+
Qr as isOAuthProviderConfig,
|
|
2040
|
+
Kr as isRetryableError,
|
|
2041
|
+
At as isSessionExpiredNullable,
|
|
2042
|
+
Tt as isSessionExpiringSoon,
|
|
2043
|
+
It as isSessionValid,
|
|
2044
|
+
Yr as isSupportedProvider,
|
|
2045
|
+
Wr as isTwoFactorRequired,
|
|
2046
|
+
jr as isValidCSRFToken,
|
|
2047
|
+
$r as isValidEmail,
|
|
2048
|
+
xr as isValidInput,
|
|
2049
|
+
Cr as isValidName,
|
|
2050
|
+
_r as isValidPassword,
|
|
2051
|
+
Fr as isValidToken,
|
|
2052
|
+
Ur as isValidURL,
|
|
2053
|
+
Zr as mulguard,
|
|
2054
|
+
Ot as refreshSession,
|
|
2055
|
+
_t as requireAuth,
|
|
2056
|
+
Pt as requireRole,
|
|
2057
|
+
Ct as requireServerAuthMiddleware,
|
|
2058
|
+
bt as requireServerRoleMiddleware,
|
|
2059
|
+
Lr as sanitizeHTML,
|
|
2060
|
+
zr as sanitizeInput,
|
|
2061
|
+
Vr as sanitizeUserInput,
|
|
2062
|
+
ae as setCookie,
|
|
2063
|
+
Jr as signIn,
|
|
2064
|
+
lt as signInEmailAction,
|
|
2065
|
+
ft as signOutAction,
|
|
2066
|
+
dt as signUpAction,
|
|
2067
|
+
Ut as storeOAuthStateCookie,
|
|
2068
|
+
et as toNextJsHandler,
|
|
2069
|
+
G as validateAndSanitizeEmail,
|
|
2070
|
+
X as validateAndSanitizeInput,
|
|
2071
|
+
Pr as validateAndSanitizeName,
|
|
2072
|
+
Or as validateAndSanitizePassword,
|
|
2073
|
+
Q as validateCSRFToken,
|
|
2074
|
+
N as validateSessionStructure,
|
|
2075
|
+
Nr as validateToken,
|
|
2076
|
+
br as validateURL,
|
|
2077
|
+
ht as verify2FAAction,
|
|
2078
|
+
F as withSecurityHeaders
|
|
1729
2079
|
};
|