@aura-stack/auth 0.4.0 → 0.5.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/@types/index.d.ts +6 -2
- package/dist/@types/router.d.d.ts +6 -2
- package/dist/actions/callback/access-token.cjs +103 -59
- package/dist/actions/callback/access-token.d.ts +7 -3
- package/dist/actions/callback/access-token.js +3 -3
- package/dist/actions/callback/callback.cjs +200 -134
- package/dist/actions/callback/callback.d.ts +32 -3
- package/dist/actions/callback/callback.js +11 -12
- package/dist/actions/callback/userinfo.cjs +103 -70
- package/dist/actions/callback/userinfo.d.ts +6 -2
- package/dist/actions/callback/userinfo.js +7 -8
- package/dist/actions/csrfToken/csrfToken.cjs +7 -15
- package/dist/actions/csrfToken/csrfToken.d.ts +3 -1
- package/dist/actions/csrfToken/csrfToken.js +7 -8
- package/dist/actions/index.cjs +502 -295
- package/dist/actions/index.d.ts +5 -2
- package/dist/actions/index.js +23 -20
- package/dist/actions/session/session.cjs +76 -24
- package/dist/actions/session/session.d.ts +3 -1
- package/dist/actions/session/session.js +6 -4
- package/dist/actions/signIn/authorization-url.cjs +288 -0
- package/dist/actions/signIn/authorization-url.d.ts +31 -0
- package/dist/actions/signIn/authorization-url.js +16 -0
- package/dist/actions/signIn/authorization.cjs +91 -132
- package/dist/actions/signIn/authorization.d.ts +17 -16
- package/dist/actions/signIn/authorization.js +8 -7
- package/dist/actions/signIn/signIn.cjs +319 -191
- package/dist/actions/signIn/signIn.d.ts +32 -3
- package/dist/actions/signIn/signIn.js +10 -9
- package/dist/actions/signOut/signOut.cjs +211 -212
- package/dist/actions/signOut/signOut.d.ts +9 -1
- package/dist/actions/signOut/signOut.js +9 -10
- package/dist/api/createApi.cjs +750 -0
- package/dist/api/createApi.d.ts +12 -0
- package/dist/api/createApi.js +19 -0
- package/dist/api/getSession.cjs +141 -0
- package/dist/api/getSession.d.ts +16 -0
- package/dist/api/getSession.js +10 -0
- package/dist/api/signIn.cjs +549 -0
- package/dist/api/signIn.d.ts +26 -0
- package/dist/api/signIn.js +15 -0
- package/dist/api/signOut.cjs +279 -0
- package/dist/api/signOut.d.ts +16 -0
- package/dist/api/signOut.js +13 -0
- package/dist/assert.cjs +42 -9
- package/dist/assert.d.ts +8 -4
- package/dist/assert.js +5 -5
- package/dist/{chunk-KJBAQZX2.js → chunk-2A5B7GWR.js} +44 -11
- package/dist/chunk-2GQLSIJ2.js +40 -0
- package/dist/chunk-2IR674WX.js +44 -0
- package/dist/chunk-3J5TUH2I.js +50 -0
- package/dist/chunk-4RWSYUKX.js +98 -0
- package/dist/chunk-5X7JZMEF.js +0 -0
- package/dist/{chunk-TZB6MUXN.js → chunk-7BE46WWS.js} +21 -11
- package/dist/chunk-7YYXFKLR.js +35 -0
- package/dist/chunk-C3A37LQC.js +33 -0
- package/dist/chunk-CITNGXDA.js +31 -0
- package/dist/chunk-CWX724AG.js +78 -0
- package/dist/chunk-D2CSIUKP.js +74 -0
- package/dist/{chunk-ICAZ4OVS.js → chunk-FPCVZUVG.js} +2 -2
- package/dist/{chunk-XGLBNXL4.js → chunk-GNNBM2WJ.js} +17 -9
- package/dist/chunk-JOCGX3RP.js +59 -0
- package/dist/chunk-KBXWTD6E.js +94 -0
- package/dist/{chunk-XUP6KKNG.js → chunk-LATR3NIV.js} +48 -37
- package/dist/chunk-LAYPUDQF.js +39 -0
- package/dist/chunk-LX3TJ2TJ.js +294 -0
- package/dist/{chunk-6MXFPFR3.js → chunk-NHZBQNRR.js} +19 -19
- package/dist/{chunk-TM5IPSNF.js → chunk-PDP3PHB3.js} +33 -19
- package/dist/chunk-PHYNROD4.js +47 -0
- package/dist/chunk-QQEKY4XP.js +29 -0
- package/dist/{chunk-VNCNJKS2.js → chunk-U4RK4LKJ.js} +82 -1
- package/dist/{chunk-RRLIF4PQ.js → chunk-U5663F2U.js} +16 -1
- package/dist/chunk-UN7X6SU5.js +53 -0
- package/dist/chunk-UZQJJD6A.js +100 -0
- package/dist/{chunk-NUDITUKX.js → chunk-V6LLEAR4.js} +22 -15
- package/dist/{chunk-4MYWAOLG.js → chunk-WHNDRO3N.js} +20 -1
- package/dist/{chunk-5W4BRQYG.js → chunk-XY5R3EHH.js} +6 -3
- package/dist/client/client.cjs +135 -0
- package/dist/client/client.d.ts +85 -0
- package/dist/client/client.js +9 -0
- package/dist/client/index.cjs +135 -0
- package/dist/client/index.d.ts +14 -0
- package/dist/client/index.js +10 -0
- package/dist/context.cjs +1237 -0
- package/dist/context.d.ts +16 -0
- package/dist/context.js +28 -0
- package/dist/cookie.cjs +33 -2
- package/dist/cookie.d.ts +9 -5
- package/dist/cookie.js +3 -2
- package/dist/createAuth.cjs +2320 -0
- package/dist/createAuth.d.ts +12 -0
- package/dist/createAuth.js +48 -0
- package/dist/env.cjs +24 -2
- package/dist/env.d.ts +4 -1
- package/dist/env.js +9 -3
- package/dist/errors.cjs +17 -0
- package/dist/errors.d.ts +13 -3
- package/dist/errors.js +5 -1
- package/dist/{index-CSyIJmCM.d.ts → index-_aXtxb_s.d.ts} +383 -13
- package/dist/index.cjs +2135 -1547
- package/dist/index.d.ts +9 -30
- package/dist/index.js +46 -119
- package/dist/jose.cjs +52 -14
- package/dist/jose.d.ts +12 -25
- package/dist/jose.js +11 -3
- package/dist/logger.cjs +132 -0
- package/dist/logger.d.ts +6 -2
- package/dist/logger.js +10 -1
- package/dist/oauth/atlassian.cjs +57 -0
- package/dist/oauth/atlassian.d.ts +12 -0
- package/dist/oauth/atlassian.js +6 -0
- package/dist/oauth/bitbucket.d.ts +6 -2
- package/dist/oauth/discord.d.ts +6 -2
- package/dist/oauth/dropbox.cjs +53 -0
- package/dist/oauth/dropbox.d.ts +12 -0
- package/dist/oauth/dropbox.js +6 -0
- package/dist/oauth/figma.d.ts +6 -2
- package/dist/oauth/github.d.ts +6 -2
- package/dist/oauth/gitlab.d.ts +6 -2
- package/dist/oauth/index.cjs +278 -88
- package/dist/oauth/index.d.ts +6 -2
- package/dist/oauth/index.js +27 -11
- package/dist/oauth/mailchimp.d.ts +6 -2
- package/dist/oauth/notion.cjs +131 -0
- package/dist/oauth/notion.d.ts +12 -0
- package/dist/oauth/notion.js +9 -0
- package/dist/oauth/pinterest.d.ts +6 -2
- package/dist/oauth/spotify.d.ts +6 -2
- package/dist/oauth/strava.d.ts +6 -2
- package/dist/oauth/twitch.cjs +95 -0
- package/dist/oauth/twitch.d.ts +12 -0
- package/dist/oauth/twitch.js +7 -0
- package/dist/oauth/x.d.ts +6 -2
- package/dist/schemas.cjs +84 -51
- package/dist/schemas.d.ts +103 -23
- package/dist/schemas.js +1 -1
- package/dist/secure.cjs +36 -36
- package/dist/secure.d.ts +10 -4
- package/dist/secure.js +7 -6
- package/dist/utils.cjs +109 -3
- package/dist/utils.d.ts +15 -4
- package/dist/utils.js +11 -4
- package/package.json +9 -5
- package/dist/chunk-4EKY7655.js +0 -123
- package/dist/chunk-7QF22LHP.js +0 -67
- package/dist/chunk-ALG3GIV4.js +0 -95
- package/dist/chunk-FRJFWTOY.js +0 -70
- package/dist/chunk-PHFH2MGS.js +0 -36
- package/dist/chunk-QQVSRXGX.js +0 -149
|
@@ -1,15 +1,16 @@
|
|
|
1
1
|
import {
|
|
2
2
|
signInAction
|
|
3
|
-
} from "../../chunk-
|
|
4
|
-
import "../../chunk-
|
|
5
|
-
import "../../chunk-
|
|
6
|
-
import "../../chunk-
|
|
7
|
-
import "../../chunk-
|
|
8
|
-
import "../../chunk-
|
|
3
|
+
} from "../../chunk-UN7X6SU5.js";
|
|
4
|
+
import "../../chunk-JOCGX3RP.js";
|
|
5
|
+
import "../../chunk-D2CSIUKP.js";
|
|
6
|
+
import "../../chunk-LATR3NIV.js";
|
|
7
|
+
import "../../chunk-V6LLEAR4.js";
|
|
8
|
+
import "../../chunk-2A5B7GWR.js";
|
|
9
|
+
import "../../chunk-UZQJJD6A.js";
|
|
10
|
+
import "../../chunk-LX3TJ2TJ.js";
|
|
11
|
+
import "../../chunk-WHNDRO3N.js";
|
|
12
|
+
import "../../chunk-U5663F2U.js";
|
|
9
13
|
import "../../chunk-EBAMFRB7.js";
|
|
10
|
-
import "../../chunk-FRJFWTOY.js";
|
|
11
|
-
import "../../chunk-4MYWAOLG.js";
|
|
12
|
-
import "../../chunk-RRLIF4PQ.js";
|
|
13
14
|
export {
|
|
14
15
|
signInAction
|
|
15
16
|
};
|
|
@@ -23,8 +23,8 @@ __export(signOut_exports, {
|
|
|
23
23
|
signOutAction: () => signOutAction
|
|
24
24
|
});
|
|
25
25
|
module.exports = __toCommonJS(signOut_exports);
|
|
26
|
-
var
|
|
27
|
-
var
|
|
26
|
+
var import_v4 = require("zod/v4");
|
|
27
|
+
var import_router3 = require("@aura-stack/router");
|
|
28
28
|
|
|
29
29
|
// src/utils.ts
|
|
30
30
|
var import_router = require("@aura-stack/router");
|
|
@@ -33,8 +33,8 @@ var import_router = require("@aura-stack/router");
|
|
|
33
33
|
var AuthInternalError = class extends Error {
|
|
34
34
|
type = "AUTH_INTERNAL_ERROR";
|
|
35
35
|
code;
|
|
36
|
-
constructor(code, message,
|
|
37
|
-
super(message,
|
|
36
|
+
constructor(code, message, options) {
|
|
37
|
+
super(message, options);
|
|
38
38
|
this.code = code;
|
|
39
39
|
this.name = new.target.name;
|
|
40
40
|
Error.captureStackTrace(this, new.target);
|
|
@@ -43,37 +43,49 @@ var AuthInternalError = class extends Error {
|
|
|
43
43
|
var AuthSecurityError = class extends Error {
|
|
44
44
|
type = "AUTH_SECURITY_ERROR";
|
|
45
45
|
code;
|
|
46
|
-
constructor(code, message,
|
|
47
|
-
super(message,
|
|
46
|
+
constructor(code, message, options) {
|
|
47
|
+
super(message, options);
|
|
48
48
|
this.code = code;
|
|
49
49
|
this.name = new.target.name;
|
|
50
50
|
Error.captureStackTrace(this, new.target);
|
|
51
51
|
}
|
|
52
52
|
};
|
|
53
53
|
|
|
54
|
-
// src/
|
|
55
|
-
var
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
54
|
+
// src/env.ts
|
|
55
|
+
var import_meta = {};
|
|
56
|
+
var env = new Proxy({}, {
|
|
57
|
+
get(_, prop) {
|
|
58
|
+
if (typeof prop !== "string") return void 0;
|
|
59
|
+
const hasProperty = (process2) => {
|
|
60
|
+
return process2 && Object.prototype.hasOwnProperty.call(process2, prop);
|
|
61
|
+
};
|
|
62
|
+
try {
|
|
63
|
+
if (typeof process !== "undefined" && hasProperty(process.env)) {
|
|
64
|
+
return process.env[prop];
|
|
65
|
+
}
|
|
66
|
+
if (typeof import_meta !== "undefined" && hasProperty(import_meta.env)) {
|
|
67
|
+
return import_meta.env[prop];
|
|
68
|
+
}
|
|
69
|
+
if (typeof Deno !== "undefined" && Deno.env?.get) {
|
|
70
|
+
return Deno.env.get(prop);
|
|
71
|
+
}
|
|
72
|
+
if (typeof Bun !== "undefined" && hasProperty(Bun.env)) {
|
|
73
|
+
return Bun.env[prop];
|
|
74
|
+
}
|
|
75
|
+
const globalValue = globalThis[prop];
|
|
76
|
+
return typeof globalValue === "string" ? globalValue : void 0;
|
|
77
|
+
} catch {
|
|
78
|
+
return void 0;
|
|
79
|
+
}
|
|
71
80
|
}
|
|
72
|
-
|
|
81
|
+
});
|
|
82
|
+
var getEnv = (key) => {
|
|
83
|
+
const keys = [`AURA_AUTH_${key.toUpperCase()}`, `AURA_${key.toUpperCase()}`, `AUTH_${key.toUpperCase()}`, key.toUpperCase()];
|
|
84
|
+
return env[keys.find((k) => env[k]) ?? ""];
|
|
73
85
|
};
|
|
74
86
|
|
|
75
87
|
// src/assert.ts
|
|
76
|
-
var import_crypto = require("crypto");
|
|
88
|
+
var import_crypto = require("@aura-stack/jose/crypto");
|
|
77
89
|
var unsafeChars = [
|
|
78
90
|
"<",
|
|
79
91
|
">",
|
|
@@ -164,46 +176,74 @@ var isTrustedOrigin = (url, trustedOrigins) => {
|
|
|
164
176
|
}
|
|
165
177
|
return false;
|
|
166
178
|
};
|
|
167
|
-
var
|
|
168
|
-
const bufferA =
|
|
169
|
-
const bufferB =
|
|
170
|
-
|
|
171
|
-
|
|
179
|
+
var timingSafeEqual = (a, b) => {
|
|
180
|
+
const bufferA = import_crypto.encoder.encode(a);
|
|
181
|
+
const bufferB = import_crypto.encoder.encode(b);
|
|
182
|
+
const len = Math.max(bufferA.length, bufferB.length);
|
|
183
|
+
let diff = 0;
|
|
184
|
+
for (let i = 0; i < len; i++) {
|
|
185
|
+
diff |= (bufferA[i] ?? 0) ^ (bufferB[i] ?? 0);
|
|
172
186
|
}
|
|
173
|
-
return
|
|
187
|
+
return diff === 0 && bufferA.length === bufferB.length;
|
|
174
188
|
};
|
|
175
189
|
|
|
176
|
-
// src/
|
|
177
|
-
var
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
}
|
|
194
|
-
if (typeof Bun !== "undefined" && hasProperty(Bun.env)) {
|
|
195
|
-
return Bun.env[prop];
|
|
196
|
-
}
|
|
197
|
-
const globalValue = globalThis[prop];
|
|
198
|
-
return typeof globalValue === "string" ? globalValue : void 0;
|
|
199
|
-
} catch {
|
|
200
|
-
return void 0;
|
|
201
|
-
}
|
|
190
|
+
// src/utils.ts
|
|
191
|
+
var equals = (a, b) => {
|
|
192
|
+
if (a === null || b === null || a === void 0 || b === void 0) return false;
|
|
193
|
+
return a === b;
|
|
194
|
+
};
|
|
195
|
+
var getBaseURL = (request) => {
|
|
196
|
+
const url = new URL(request.url);
|
|
197
|
+
return `${url.origin}${url.pathname}`;
|
|
198
|
+
};
|
|
199
|
+
var extractPath = (url) => {
|
|
200
|
+
const pathRegex = /^https?:\/\/[a-zA-Z0-9_\-\.]+(:\d+)?(\/.*)$/;
|
|
201
|
+
const match = url.match(pathRegex);
|
|
202
|
+
return match && match[2] ? match[2] : "/";
|
|
203
|
+
};
|
|
204
|
+
var getErrorName = (error) => {
|
|
205
|
+
if (error instanceof Error) {
|
|
206
|
+
return error.name;
|
|
202
207
|
}
|
|
203
|
-
|
|
208
|
+
return typeof error === "string" ? error : "UnknownError";
|
|
209
|
+
};
|
|
210
|
+
|
|
211
|
+
// src/cookie.ts
|
|
212
|
+
var import_cookie = require("@aura-stack/router/cookie");
|
|
213
|
+
var defaultCookieOptions = {
|
|
214
|
+
httpOnly: true,
|
|
215
|
+
sameSite: "lax",
|
|
216
|
+
path: "/",
|
|
217
|
+
maxAge: 60 * 60 * 24 * 15
|
|
218
|
+
};
|
|
219
|
+
var oauthCookieOptions = {
|
|
220
|
+
httpOnly: true,
|
|
221
|
+
maxAge: 5 * 60,
|
|
222
|
+
sameSite: "lax",
|
|
223
|
+
expires: new Date(Date.now() + 5 * 60 * 1e3)
|
|
224
|
+
};
|
|
225
|
+
var expiredCookieAttributes = {
|
|
226
|
+
...defaultCookieOptions,
|
|
227
|
+
expires: /* @__PURE__ */ new Date(0),
|
|
228
|
+
maxAge: 0,
|
|
229
|
+
secure: true
|
|
230
|
+
};
|
|
231
|
+
var getCookie = (request, cookieName) => {
|
|
232
|
+
const cookies = request instanceof Request ? request.headers.get("Cookie") : request.get("Cookie");
|
|
233
|
+
if (!cookies) {
|
|
234
|
+
throw new AuthInternalError("COOKIE_NOT_FOUND", "No cookies found. There is no active session");
|
|
235
|
+
}
|
|
236
|
+
const value = (0, import_cookie.parse)(cookies)[cookieName];
|
|
237
|
+
if (!value) {
|
|
238
|
+
throw new AuthInternalError("COOKIE_NOT_FOUND", `Cookie "${cookieName}" not found. There is no active session`);
|
|
239
|
+
}
|
|
240
|
+
return value;
|
|
241
|
+
};
|
|
204
242
|
|
|
205
243
|
// src/jose.ts
|
|
206
244
|
var import_jose = require("@aura-stack/jose");
|
|
245
|
+
var import_jose2 = require("@aura-stack/jose/jose");
|
|
246
|
+
var import_crypto2 = require("@aura-stack/jose/crypto");
|
|
207
247
|
var jwtVerificationOptions = {
|
|
208
248
|
algorithms: ["HS256"],
|
|
209
249
|
typ: "JWT"
|
|
@@ -223,7 +263,7 @@ var verifyCSRF = async (jose, cookie, header) => {
|
|
|
223
263
|
if (!equals(cookiePayload.token.length, headerPayload.token.length)) {
|
|
224
264
|
throw new AuthSecurityError("CSRF_TOKEN_INVALID", "The CSRF tokens do not match.");
|
|
225
265
|
}
|
|
226
|
-
if (!
|
|
266
|
+
if (!timingSafeEqual(cookiePayload.token, headerPayload.token)) {
|
|
227
267
|
throw new AuthSecurityError("CSRF_TOKEN_INVALID", "The CSRF tokens do not match.");
|
|
228
268
|
}
|
|
229
269
|
return true;
|
|
@@ -260,123 +300,117 @@ var secureApiHeaders = {
|
|
|
260
300
|
...secureHeaders
|
|
261
301
|
};
|
|
262
302
|
|
|
263
|
-
// src/
|
|
264
|
-
var
|
|
265
|
-
var
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
}
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
|
|
303
|
+
// src/api/signOut.ts
|
|
304
|
+
var import_router2 = require("@aura-stack/router");
|
|
305
|
+
var signOut = async ({
|
|
306
|
+
ctx,
|
|
307
|
+
headers: headersInit,
|
|
308
|
+
redirectTo = "/",
|
|
309
|
+
skipCSRFCheck = false
|
|
310
|
+
}) => {
|
|
311
|
+
const headers = new Headers(headersInit);
|
|
312
|
+
const header = headers.get("X-CSRF-Token");
|
|
313
|
+
let session = null;
|
|
314
|
+
let csrfToken = null;
|
|
315
|
+
try {
|
|
316
|
+
session = getCookie(headers, ctx.cookies.sessionToken.name);
|
|
317
|
+
} catch {
|
|
318
|
+
throw new AuthSecurityError("SESSION_TOKEN_MISSING", "The sessionToken is missing.");
|
|
319
|
+
}
|
|
320
|
+
try {
|
|
321
|
+
csrfToken = getCookie(headers, ctx.cookies.csrfToken.name);
|
|
322
|
+
} catch {
|
|
323
|
+
throw new AuthSecurityError("CSRF_TOKEN_MISSING", "The CSRF token is missing.");
|
|
324
|
+
}
|
|
325
|
+
ctx?.logger?.log("SIGN_OUT_ATTEMPT", {
|
|
326
|
+
structuredData: {
|
|
327
|
+
has_session: Boolean(session),
|
|
328
|
+
has_csrf_token: Boolean(csrfToken),
|
|
329
|
+
has_csrf_header: Boolean(header),
|
|
330
|
+
skip_csrf_check: skipCSRFCheck
|
|
331
|
+
}
|
|
332
|
+
});
|
|
333
|
+
if (!session) {
|
|
334
|
+
ctx?.logger?.log("SESSION_TOKEN_MISSING");
|
|
335
|
+
throw new AuthSecurityError("SESSION_TOKEN_MISSING", "The sessionToken is missing.");
|
|
336
|
+
}
|
|
337
|
+
if (!skipCSRFCheck) {
|
|
338
|
+
if (!csrfToken) {
|
|
339
|
+
ctx?.logger?.log("CSRF_TOKEN_MISSING");
|
|
340
|
+
throw new AuthSecurityError("CSRF_TOKEN_MISSING", "The CSRF token is missing.");
|
|
341
|
+
}
|
|
342
|
+
if (!header) {
|
|
343
|
+
ctx?.logger?.log("CSRF_HEADER_MISSING");
|
|
344
|
+
throw new AuthSecurityError("CSRF_HEADER_MISSING", "The CSRF header is missing.");
|
|
345
|
+
}
|
|
346
|
+
try {
|
|
347
|
+
await verifyCSRF(ctx.jose, csrfToken, header);
|
|
348
|
+
} catch (error) {
|
|
349
|
+
ctx?.logger?.log("CSRF_TOKEN_INVALID", { structuredData: { error_type: getErrorName(error) } });
|
|
350
|
+
throw new AuthSecurityError("CSRF_TOKEN_INVALID", "CSRF token verification failed");
|
|
351
|
+
}
|
|
352
|
+
ctx?.logger?.log("SIGN_OUT_CSRF_VERIFIED");
|
|
353
|
+
} else {
|
|
354
|
+
try {
|
|
355
|
+
await ctx.jose.verifyJWS(csrfToken);
|
|
356
|
+
} catch (error) {
|
|
357
|
+
ctx?.logger?.log("CSRF_TOKEN_INVALID", { structuredData: { error_type: getErrorName(error) } });
|
|
358
|
+
throw new AuthSecurityError("CSRF_TOKEN_INVALID", "CSRF token verification failed");
|
|
359
|
+
}
|
|
360
|
+
}
|
|
361
|
+
try {
|
|
362
|
+
await ctx.jose.decodeJWT(session);
|
|
363
|
+
ctx?.logger?.log("SIGN_OUT_SUCCESS");
|
|
364
|
+
} catch (error) {
|
|
365
|
+
ctx?.logger?.log("INVALID_JWT_TOKEN", { structuredData: { error_type: getErrorName(error) } });
|
|
366
|
+
}
|
|
367
|
+
const headersList = new import_router2.HeadersBuilder(secureApiHeaders).setHeader("Location", redirectTo).setCookie(ctx.cookies.csrfToken.name, "", expiredCookieAttributes).setCookie(ctx.cookies.sessionToken.name, "", expiredCookieAttributes).toHeaders();
|
|
368
|
+
return Response.json(
|
|
369
|
+
{ redirect: Boolean(redirectTo), url: redirectTo },
|
|
370
|
+
{
|
|
371
|
+
status: 202,
|
|
372
|
+
headers: headersList
|
|
373
|
+
}
|
|
374
|
+
);
|
|
282
375
|
};
|
|
283
376
|
|
|
284
|
-
// src/schemas.ts
|
|
285
|
-
var import_zod = require("zod");
|
|
286
|
-
var OAuthProviderCredentialsSchema = (0, import_zod.object)({
|
|
287
|
-
id: (0, import_zod.string)(),
|
|
288
|
-
name: (0, import_zod.string)(),
|
|
289
|
-
authorizeURL: (0, import_zod.string)().url(),
|
|
290
|
-
accessToken: (0, import_zod.string)().url(),
|
|
291
|
-
scope: (0, import_zod.string)(),
|
|
292
|
-
userInfo: (0, import_zod.string)().url(),
|
|
293
|
-
responseType: (0, import_zod.enum)(["code", "token", "id_token"]),
|
|
294
|
-
clientId: (0, import_zod.string)(),
|
|
295
|
-
clientSecret: (0, import_zod.string)(),
|
|
296
|
-
profile: import_zod.z.function().optional()
|
|
297
|
-
});
|
|
298
|
-
var OAuthProviderConfigSchema = (0, import_zod.object)({
|
|
299
|
-
authorizeURL: (0, import_zod.string)().url(),
|
|
300
|
-
accessToken: (0, import_zod.string)().url(),
|
|
301
|
-
scope: (0, import_zod.string)().optional(),
|
|
302
|
-
userInfo: (0, import_zod.string)().url(),
|
|
303
|
-
responseType: (0, import_zod.enum)(["code", "token", "id_token"]),
|
|
304
|
-
clientId: (0, import_zod.string)(),
|
|
305
|
-
clientSecret: (0, import_zod.string)()
|
|
306
|
-
});
|
|
307
|
-
var OAuthAuthorization = OAuthProviderConfigSchema.extend({
|
|
308
|
-
redirectURI: (0, import_zod.string)(),
|
|
309
|
-
state: (0, import_zod.string)(),
|
|
310
|
-
codeChallenge: (0, import_zod.string)(),
|
|
311
|
-
codeChallengeMethod: (0, import_zod.enum)(["plain", "S256"])
|
|
312
|
-
});
|
|
313
|
-
var OAuthAuthorizationResponse = (0, import_zod.object)({
|
|
314
|
-
state: (0, import_zod.string)({ message: "Missing state parameter in the OAuth authorization response." }),
|
|
315
|
-
code: (0, import_zod.string)({ message: "Missing code parameter in the OAuth authorization response." })
|
|
316
|
-
});
|
|
317
|
-
var OAuthAuthorizationErrorResponse = (0, import_zod.object)({
|
|
318
|
-
error: (0, import_zod.enum)([
|
|
319
|
-
"invalid_request",
|
|
320
|
-
"unauthorized_client",
|
|
321
|
-
"access_denied",
|
|
322
|
-
"unsupported_response_type",
|
|
323
|
-
"invalid_scope",
|
|
324
|
-
"server_error",
|
|
325
|
-
"temporarily_unavailable"
|
|
326
|
-
]),
|
|
327
|
-
error_description: (0, import_zod.string)().optional(),
|
|
328
|
-
error_uri: (0, import_zod.string)().optional(),
|
|
329
|
-
state: (0, import_zod.string)()
|
|
330
|
-
});
|
|
331
|
-
var OAuthAccessToken = OAuthProviderConfigSchema.extend({
|
|
332
|
-
redirectURI: (0, import_zod.string)(),
|
|
333
|
-
code: (0, import_zod.string)(),
|
|
334
|
-
codeVerifier: (0, import_zod.string)().min(43).max(128)
|
|
335
|
-
});
|
|
336
|
-
var OAuthAccessTokenResponse = (0, import_zod.object)({
|
|
337
|
-
access_token: (0, import_zod.string)(),
|
|
338
|
-
token_type: (0, import_zod.string)().optional(),
|
|
339
|
-
expires_in: (0, import_zod.number)().optional(),
|
|
340
|
-
refresh_token: (0, import_zod.string)().optional(),
|
|
341
|
-
scope: (0, import_zod.string)().optional().or((0, import_zod.null)())
|
|
342
|
-
});
|
|
343
|
-
var OAuthAccessTokenErrorResponse = (0, import_zod.object)({
|
|
344
|
-
error: (0, import_zod.enum)([
|
|
345
|
-
"invalid_request",
|
|
346
|
-
"invalid_client",
|
|
347
|
-
"invalid_grant",
|
|
348
|
-
"unauthorized_client",
|
|
349
|
-
"unsupported_grant_type",
|
|
350
|
-
"invalid_scope"
|
|
351
|
-
]),
|
|
352
|
-
error_description: (0, import_zod.string)().optional(),
|
|
353
|
-
error_uri: (0, import_zod.string)().optional()
|
|
354
|
-
});
|
|
355
|
-
var OAuthErrorResponse = (0, import_zod.object)({
|
|
356
|
-
error: (0, import_zod.string)(),
|
|
357
|
-
error_description: (0, import_zod.string)().optional()
|
|
358
|
-
});
|
|
359
|
-
var OAuthEnvSchema = (0, import_zod.object)({
|
|
360
|
-
clientId: import_zod.z.string().min(1, "OAuth Client ID is required in the environment variables."),
|
|
361
|
-
clientSecret: import_zod.z.string().min(1, "OAuth Client Secret is required in the environment variables.")
|
|
362
|
-
});
|
|
363
|
-
|
|
364
377
|
// src/actions/signIn/authorization.ts
|
|
365
378
|
var getTrustedOrigins = async (request, trustedOrigins) => {
|
|
366
379
|
if (!trustedOrigins) return [];
|
|
367
380
|
const raw = typeof trustedOrigins === "function" ? await trustedOrigins(request) : trustedOrigins;
|
|
368
381
|
return Array.isArray(raw) ? raw : typeof raw === "string" ? [raw] : [];
|
|
369
382
|
};
|
|
383
|
+
var getBaseURL2 = async ({
|
|
384
|
+
ctx,
|
|
385
|
+
request,
|
|
386
|
+
headers: headersInit
|
|
387
|
+
}) => {
|
|
388
|
+
const origin = getEnv("BASE_URL") || ctx?.baseURL;
|
|
389
|
+
if (origin && origin !== "/") return origin;
|
|
390
|
+
if (ctx?.trustedProxyHeaders) {
|
|
391
|
+
const headers = headersInit && new Headers(headersInit) || request?.headers;
|
|
392
|
+
const protocol = headers?.get("Forwarded")?.match(/proto=([^;]+)/i)?.[1] ?? headers?.get("X-Forwarded-Proto") ?? "http";
|
|
393
|
+
const host = headers?.get("Host") ?? headers?.get("Forwarded")?.match(/host=([^;]+)/i)?.[1] ?? headers?.get("X-Forwarded-Host") ?? null;
|
|
394
|
+
if (host) return `${protocol}://${host}`;
|
|
395
|
+
throw new AuthInternalError(
|
|
396
|
+
"INVALID_OAUTH_CONFIGURATION",
|
|
397
|
+
"The URL cannot be constructed. Please set the BASE_URL environment variable or provide trusted proxy host headers."
|
|
398
|
+
);
|
|
399
|
+
}
|
|
400
|
+
try {
|
|
401
|
+
return new URL(request?.url ?? "not-found").origin;
|
|
402
|
+
} catch (error) {
|
|
403
|
+
throw new AuthInternalError(
|
|
404
|
+
"INVALID_OAUTH_CONFIGURATION",
|
|
405
|
+
"The URL cannot be constructed. Please set the BASE_URL environment variable or enable trustedProxyHeaders.",
|
|
406
|
+
{ cause: error }
|
|
407
|
+
);
|
|
408
|
+
}
|
|
409
|
+
};
|
|
370
410
|
var getOriginURL = async (request, context) => {
|
|
371
|
-
const headers = request.headers;
|
|
372
|
-
let origin = new URL(request.url).origin;
|
|
373
411
|
const trustedOrigins = await getTrustedOrigins(request, context?.trustedOrigins);
|
|
374
|
-
trustedOrigins.push(origin);
|
|
375
|
-
|
|
376
|
-
const protocol = headers.get("Forwarded")?.match(/proto=([^;]+)/i)?.[1] ?? headers.get("X-Forwarded-Proto") ?? "http";
|
|
377
|
-
const host = headers.get("Host") ?? headers.get("Forwarded")?.match(/host=([^;]+)/i)?.[1] ?? headers.get("X-Forwarded-Host") ?? null;
|
|
378
|
-
origin = `${protocol}://${host}`;
|
|
379
|
-
}
|
|
412
|
+
trustedOrigins.push(new URL(request.url).origin);
|
|
413
|
+
const origin = await getBaseURL2({ request, ctx: context });
|
|
380
414
|
if (!isTrustedOrigin(origin, trustedOrigins)) {
|
|
381
415
|
context?.logger?.log("UNTRUSTED_ORIGIN", { structuredData: { origin } });
|
|
382
416
|
throw new AuthInternalError("UNTRUSTED_ORIGIN", "The constructed origin URL is not trusted.");
|
|
@@ -419,71 +453,36 @@ var createRedirectTo = async (request, redirectTo, context) => {
|
|
|
419
453
|
};
|
|
420
454
|
|
|
421
455
|
// src/actions/signOut/signOut.ts
|
|
422
|
-
var config = (0,
|
|
456
|
+
var config = (0, import_router3.createEndpointConfig)({
|
|
423
457
|
schemas: {
|
|
424
|
-
searchParams:
|
|
425
|
-
token_type_hint:
|
|
426
|
-
redirectTo:
|
|
458
|
+
searchParams: import_v4.z.object({
|
|
459
|
+
token_type_hint: import_v4.z.literal("session_token"),
|
|
460
|
+
redirectTo: import_v4.z.string().optional()
|
|
427
461
|
})
|
|
428
462
|
}
|
|
429
463
|
});
|
|
430
|
-
var signOutAction = (0,
|
|
464
|
+
var signOutAction = (0, import_router3.createEndpoint)(
|
|
431
465
|
"POST",
|
|
432
466
|
"/signOut",
|
|
433
467
|
async (ctx) => {
|
|
434
468
|
const {
|
|
435
469
|
request,
|
|
436
|
-
headers,
|
|
437
470
|
searchParams: { redirectTo },
|
|
438
471
|
context
|
|
439
472
|
} = ctx;
|
|
440
|
-
const { jose, cookies, logger } = context;
|
|
441
|
-
const session = headers.getCookie(cookies.sessionToken.name);
|
|
442
|
-
const csrfToken = headers.getCookie(cookies.csrfToken.name);
|
|
443
|
-
const header = headers.getHeader("X-CSRF-Token");
|
|
444
|
-
logger?.log("SIGN_OUT_ATTEMPT", {
|
|
445
|
-
structuredData: {
|
|
446
|
-
has_session: Boolean(session),
|
|
447
|
-
has_csrf_token: Boolean(csrfToken),
|
|
448
|
-
has_csrf_header: Boolean(header)
|
|
449
|
-
}
|
|
450
|
-
});
|
|
451
|
-
if (!session) {
|
|
452
|
-
logger?.log("SESSION_TOKEN_MISSING");
|
|
453
|
-
throw new AuthSecurityError("SESSION_TOKEN_MISSING", "The sessionToken is missing.");
|
|
454
|
-
}
|
|
455
|
-
if (!csrfToken) {
|
|
456
|
-
logger?.log("CSRF_TOKEN_MISSING");
|
|
457
|
-
throw new AuthSecurityError("CSRF_TOKEN_MISSING", "The CSRF token is missing.");
|
|
458
|
-
}
|
|
459
|
-
if (!header) {
|
|
460
|
-
logger?.log("CSRF_HEADER_MISSING");
|
|
461
|
-
throw new AuthSecurityError("CSRF_HEADER_MISSING", "The CSRF header is missing.");
|
|
462
|
-
}
|
|
463
|
-
try {
|
|
464
|
-
await verifyCSRF(jose, csrfToken, header);
|
|
465
|
-
} catch (error) {
|
|
466
|
-
logger?.log("CSRF_TOKEN_INVALID", { structuredData: { error_type: getErrorName(error) } });
|
|
467
|
-
throw new AuthSecurityError("CSRF_TOKEN_INVALID", "CSRF token verification failed");
|
|
468
|
-
}
|
|
469
|
-
logger?.log("SIGN_OUT_CSRF_VERIFIED");
|
|
470
|
-
try {
|
|
471
|
-
await jose.decodeJWT(session);
|
|
472
|
-
logger?.log("SIGN_OUT_SUCCESS");
|
|
473
|
-
} catch (error) {
|
|
474
|
-
logger?.log("INVALID_JWT_TOKEN", { structuredData: { error_type: getErrorName(error) } });
|
|
475
|
-
}
|
|
476
473
|
const baseURL = getBaseURL(request);
|
|
477
474
|
const location = await createRedirectTo(
|
|
478
475
|
new Request(baseURL, {
|
|
479
|
-
headers: headers
|
|
476
|
+
headers: request.headers
|
|
480
477
|
}),
|
|
481
478
|
redirectTo,
|
|
482
479
|
context
|
|
483
480
|
);
|
|
484
|
-
|
|
485
|
-
|
|
486
|
-
|
|
481
|
+
return await signOut({
|
|
482
|
+
ctx: context,
|
|
483
|
+
headers: request.headers,
|
|
484
|
+
redirectTo: location
|
|
485
|
+
});
|
|
487
486
|
},
|
|
488
487
|
config
|
|
489
488
|
);
|
|
@@ -1,8 +1,16 @@
|
|
|
1
1
|
import * as _aura_stack_router from '@aura-stack/router';
|
|
2
|
+
import { z } from 'zod/v4';
|
|
2
3
|
|
|
3
4
|
/**
|
|
4
5
|
* @see https://datatracker.ietf.org/doc/html/rfc7009
|
|
5
6
|
*/
|
|
6
|
-
declare const signOutAction: _aura_stack_router.RouteEndpoint<"POST", "/signOut", {
|
|
7
|
+
declare const signOutAction: _aura_stack_router.RouteEndpoint<"POST", "/signOut", {
|
|
8
|
+
schemas?: {
|
|
9
|
+
searchParams: z.ZodObject<{
|
|
10
|
+
token_type_hint: z.ZodLiteral<"session_token">;
|
|
11
|
+
redirectTo: z.ZodOptional<z.ZodString>;
|
|
12
|
+
}, z.core.$strip>;
|
|
13
|
+
} | undefined;
|
|
14
|
+
}>;
|
|
7
15
|
|
|
8
16
|
export { signOutAction };
|
|
@@ -1,16 +1,15 @@
|
|
|
1
1
|
import {
|
|
2
2
|
signOutAction
|
|
3
|
-
} from "../../chunk-
|
|
4
|
-
import "../../chunk-
|
|
5
|
-
import "../../chunk-
|
|
6
|
-
import "../../chunk-
|
|
7
|
-
import "../../chunk-
|
|
8
|
-
import "../../chunk-
|
|
9
|
-
import "../../chunk-
|
|
3
|
+
} from "../../chunk-3J5TUH2I.js";
|
|
4
|
+
import "../../chunk-LATR3NIV.js";
|
|
5
|
+
import "../../chunk-KBXWTD6E.js";
|
|
6
|
+
import "../../chunk-V6LLEAR4.js";
|
|
7
|
+
import "../../chunk-UZQJJD6A.js";
|
|
8
|
+
import "../../chunk-LX3TJ2TJ.js";
|
|
9
|
+
import "../../chunk-XY5R3EHH.js";
|
|
10
|
+
import "../../chunk-WHNDRO3N.js";
|
|
11
|
+
import "../../chunk-U5663F2U.js";
|
|
10
12
|
import "../../chunk-EBAMFRB7.js";
|
|
11
|
-
import "../../chunk-FRJFWTOY.js";
|
|
12
|
-
import "../../chunk-4MYWAOLG.js";
|
|
13
|
-
import "../../chunk-RRLIF4PQ.js";
|
|
14
13
|
export {
|
|
15
14
|
signOutAction
|
|
16
15
|
};
|