@aura-stack/auth 0.1.0-rc.8 → 0.1.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.
Files changed (116) hide show
  1. package/dist/@types/index.cjs +15 -15
  2. package/dist/@types/index.d.ts +7 -31
  3. package/dist/@types/index.js +1 -1
  4. package/dist/@types/router.d.cjs +1 -1
  5. package/dist/@types/router.d.d.ts +7 -7
  6. package/dist/@types/utility.cjs +15 -15
  7. package/dist/@types/utility.d.ts +6 -6
  8. package/dist/@types/utility.js +1 -1
  9. package/dist/actions/callback/access-token.cjs +143 -143
  10. package/dist/actions/callback/access-token.d.ts +15 -20
  11. package/dist/actions/callback/access-token.js +8 -4
  12. package/dist/actions/callback/callback.cjs +437 -455
  13. package/dist/actions/callback/callback.d.ts +10 -12
  14. package/dist/actions/callback/callback.js +16 -12
  15. package/dist/actions/callback/userinfo.cjs +131 -134
  16. package/dist/actions/callback/userinfo.d.ts +9 -9
  17. package/dist/actions/callback/userinfo.js +10 -6
  18. package/dist/actions/csrfToken/csrfToken.cjs +162 -171
  19. package/dist/actions/csrfToken/csrfToken.d.ts +3 -3
  20. package/dist/actions/csrfToken/csrfToken.js +12 -8
  21. package/dist/actions/index.cjs +746 -773
  22. package/dist/actions/index.d.ts +13 -13
  23. package/dist/actions/index.js +34 -18
  24. package/dist/actions/session/session.cjs +149 -155
  25. package/dist/actions/session/session.d.ts +3 -3
  26. package/dist/actions/session/session.js +11 -7
  27. package/dist/actions/signIn/authorization.cjs +231 -249
  28. package/dist/actions/signIn/authorization.d.ts +12 -18
  29. package/dist/actions/signIn/authorization.js +16 -6
  30. package/dist/actions/signIn/signIn.cjs +396 -423
  31. package/dist/actions/signIn/signIn.d.ts +10 -10
  32. package/dist/actions/signIn/signIn.js +14 -10
  33. package/dist/actions/signOut/signOut.cjs +417 -440
  34. package/dist/actions/signOut/signOut.d.ts +3 -3
  35. package/dist/actions/signOut/signOut.js +15 -11
  36. package/dist/assert.cjs +35 -36
  37. package/dist/assert.d.ts +4 -4
  38. package/dist/assert.js +10 -2
  39. package/dist/chunk-256KIVJL.js +85 -96
  40. package/dist/chunk-42XB3YCW.js +19 -17
  41. package/dist/chunk-6SM22VVJ.js +13 -10
  42. package/dist/chunk-CAKJT3KS.js +84 -69
  43. package/dist/chunk-E3OXBRYF.js +19 -17
  44. package/dist/chunk-EBPE35JT.js +28 -26
  45. package/dist/chunk-FIPU4MLT.js +18 -16
  46. package/dist/chunk-FJUDBLCP.js +50 -43
  47. package/dist/chunk-FKRDCWBF.js +19 -17
  48. package/dist/chunk-GZU3RBTB.js +51 -40
  49. package/dist/chunk-HGJ4TXY4.js +132 -100
  50. package/dist/chunk-HMRKN75I.js +63 -63
  51. package/dist/chunk-IKHPGFCW.js +11 -9
  52. package/dist/chunk-JAPMIE6S.js +7 -5
  53. package/dist/chunk-KRNOMBXQ.js +19 -17
  54. package/dist/chunk-LLR722CL.js +91 -70
  55. package/dist/chunk-RLT4RFKV.js +39 -30
  56. package/dist/chunk-SJPDVKUS.js +107 -88
  57. package/dist/chunk-SMQO5WD7.js +26 -16
  58. package/dist/chunk-STHEPPUZ.js +8 -6
  59. package/dist/chunk-UJJ7R56J.js +47 -37
  60. package/dist/chunk-UTDLUEEG.js +27 -21
  61. package/dist/chunk-VFTYH33W.js +54 -37
  62. package/dist/chunk-XXJKNKGQ.js +33 -23
  63. package/dist/chunk-ZV4BH47P.js +132 -134
  64. package/dist/cookie.cjs +169 -175
  65. package/dist/cookie.d.ts +23 -51
  66. package/dist/cookie.js +34 -34
  67. package/dist/error.cjs +75 -75
  68. package/dist/error.d.ts +30 -30
  69. package/dist/error.js +15 -8
  70. package/dist/headers.cjs +28 -28
  71. package/dist/headers.d.ts +2 -2
  72. package/dist/headers.js +6 -2
  73. package/dist/index-DpfbvTZ_.d.ts +249 -298
  74. package/dist/index.cjs +936 -969
  75. package/dist/index.d.ts +10 -31
  76. package/dist/index.js +70 -50
  77. package/dist/jose.cjs +61 -64
  78. package/dist/jose.d.ts +8 -8
  79. package/dist/jose.js +9 -5
  80. package/dist/oauth/bitbucket.cjs +38 -38
  81. package/dist/oauth/bitbucket.d.ts +7 -7
  82. package/dist/oauth/bitbucket.js +6 -2
  83. package/dist/oauth/discord.cjs +48 -48
  84. package/dist/oauth/discord.d.ts +7 -7
  85. package/dist/oauth/discord.js +6 -2
  86. package/dist/oauth/figma.cjs +39 -39
  87. package/dist/oauth/figma.d.ts +7 -7
  88. package/dist/oauth/figma.js +6 -2
  89. package/dist/oauth/github.cjs +31 -31
  90. package/dist/oauth/github.d.ts +7 -7
  91. package/dist/oauth/github.js +6 -2
  92. package/dist/oauth/gitlab.cjs +39 -39
  93. package/dist/oauth/gitlab.d.ts +7 -7
  94. package/dist/oauth/gitlab.js +6 -2
  95. package/dist/oauth/index.cjs +180 -180
  96. package/dist/oauth/index.d.ts +7 -26
  97. package/dist/oauth/index.js +36 -9
  98. package/dist/oauth/spotify.cjs +39 -39
  99. package/dist/oauth/spotify.d.ts +7 -7
  100. package/dist/oauth/spotify.js +6 -2
  101. package/dist/oauth/x.cjs +39 -39
  102. package/dist/oauth/x.d.ts +7 -7
  103. package/dist/oauth/x.js +6 -2
  104. package/dist/response.cjs +27 -27
  105. package/dist/response.d.ts +2 -2
  106. package/dist/response.js +6 -2
  107. package/dist/schemas.cjs +91 -91
  108. package/dist/schemas.d.ts +93 -126
  109. package/dist/schemas.js +18 -18
  110. package/dist/secure.cjs +95 -98
  111. package/dist/secure.d.ts +17 -17
  112. package/dist/secure.js +18 -4
  113. package/dist/utils.cjs +119 -132
  114. package/dist/utils.d.ts +11 -26
  115. package/dist/utils.js +21 -21
  116. package/package.json +2 -2
@@ -1,891 +1,864 @@
1
- "use strict"
2
- var __create = Object.create
3
- var __defProp = Object.defineProperty
4
- var __getOwnPropDesc = Object.getOwnPropertyDescriptor
5
- var __getOwnPropNames = Object.getOwnPropertyNames
6
- var __getProtoOf = Object.getPrototypeOf
7
- var __hasOwnProp = Object.prototype.hasOwnProperty
1
+ "use strict";
2
+ var __create = Object.create;
3
+ var __defProp = Object.defineProperty;
4
+ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
5
+ var __getOwnPropNames = Object.getOwnPropertyNames;
6
+ var __getProtoOf = Object.getPrototypeOf;
7
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
8
8
  var __export = (target, all) => {
9
- for (var name in all) __defProp(target, name, { get: all[name], enumerable: true })
10
- }
9
+ for (var name in all)
10
+ __defProp(target, name, { get: all[name], enumerable: true });
11
+ };
11
12
  var __copyProps = (to, from, except, desc) => {
12
- if ((from && typeof from === "object") || typeof from === "function") {
13
- for (let key of __getOwnPropNames(from))
14
- if (!__hasOwnProp.call(to, key) && key !== except)
15
- __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable })
16
- }
17
- return to
18
- }
19
- var __toESM = (mod, isNodeMode, target) => (
20
- (target = mod != null ? __create(__getProtoOf(mod)) : {}),
21
- __copyProps(
22
- // If the importer is in node compatibility mode or this is not an ESM
23
- // file that has been converted to a CommonJS file using a Babel-
24
- // compatible transform (i.e. "__esModule" has not been set), then set
25
- // "default" to the CommonJS "module.exports" for node compatibility.
26
- isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
27
- mod
28
- )
29
- )
30
- var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod)
13
+ if (from && typeof from === "object" || typeof from === "function") {
14
+ for (let key of __getOwnPropNames(from))
15
+ if (!__hasOwnProp.call(to, key) && key !== except)
16
+ __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
17
+ }
18
+ return to;
19
+ };
20
+ var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
21
+ // If the importer is in node compatibility mode or this is not an ESM
22
+ // file that has been converted to a CommonJS file using a Babel-
23
+ // compatible transform (i.e. "__esModule" has not been set), then set
24
+ // "default" to the CommonJS "module.exports" for node compatibility.
25
+ isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
26
+ mod
27
+ ));
28
+ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
31
29
 
32
30
  // src/actions/index.ts
33
- var actions_exports = {}
31
+ var actions_exports = {};
34
32
  __export(actions_exports, {
35
- callbackAction: () => callbackAction,
36
- csrfTokenAction: () => csrfTokenAction,
37
- sessionAction: () => sessionAction,
38
- signInAction: () => signInAction,
39
- signOutAction: () => signOutAction,
40
- })
41
- module.exports = __toCommonJS(actions_exports)
33
+ callbackAction: () => callbackAction,
34
+ csrfTokenAction: () => csrfTokenAction,
35
+ sessionAction: () => sessionAction,
36
+ signInAction: () => signInAction,
37
+ signOutAction: () => signOutAction
38
+ });
39
+ module.exports = __toCommonJS(actions_exports);
42
40
 
43
41
  // src/actions/signIn/signIn.ts
44
- var import_zod = __toESM(require("zod"), 1)
45
- var import_router2 = require("@aura-stack/router")
42
+ var import_zod = __toESM(require("zod"), 1);
43
+ var import_router2 = require("@aura-stack/router");
46
44
 
47
45
  // src/response.ts
48
46
  var AuraResponse = class extends Response {
49
- static json(body, init) {
50
- return Response.json(body, init)
51
- }
52
- }
47
+ static json(body, init) {
48
+ return Response.json(body, init);
49
+ }
50
+ };
53
51
 
54
52
  // src/secure.ts
55
- var import_node_crypto = __toESM(require("crypto"), 1)
53
+ var import_node_crypto = __toESM(require("crypto"), 1);
56
54
 
57
55
  // src/utils.ts
58
- var import_router = require("@aura-stack/router")
56
+ var import_router = require("@aura-stack/router");
59
57
 
60
58
  // src/error.ts
61
59
  var AuthError = class extends Error {
62
- constructor(type, message) {
63
- super(message)
64
- this.type = type
65
- this.name = "AuthError"
66
- }
67
- }
60
+ constructor(type, message) {
61
+ super(message);
62
+ this.type = type;
63
+ this.name = "AuthError";
64
+ }
65
+ };
68
66
  var InvalidCsrfTokenError = class extends AuthError {
69
- constructor(message = "The provided CSRF token is invalid or has expired") {
70
- super("invalid_csrf_token", message)
71
- this.name = "InvalidCsrfTokenError"
72
- }
73
- }
67
+ constructor(message = "The provided CSRF token is invalid or has expired") {
68
+ super("invalid_csrf_token", message);
69
+ this.name = "InvalidCsrfTokenError";
70
+ }
71
+ };
74
72
  var InvalidRedirectToError = class extends AuthError {
75
- constructor(message = "The redirectTo parameter does not match the hosted origin.") {
76
- super("invalid_redirect_to", message)
77
- this.name = "InvalidRedirectToError"
78
- }
79
- }
73
+ constructor(message = "The redirectTo parameter does not match the hosted origin.") {
74
+ super("invalid_redirect_to", message);
75
+ this.name = "InvalidRedirectToError";
76
+ }
77
+ };
80
78
  var isAuthError = (error) => {
81
- return error instanceof AuthError
82
- }
79
+ return error instanceof AuthError;
80
+ };
83
81
  var throwAuthError = (error, message) => {
84
- if (error instanceof Error) {
85
- if (isAuthError(error)) {
86
- throw error
87
- }
88
- throw new AuthError("invalid_request", error.message ?? message)
82
+ if (error instanceof Error) {
83
+ if (isAuthError(error)) {
84
+ throw error;
89
85
  }
90
- }
86
+ throw new AuthError("invalid_request", error.message ?? message);
87
+ }
88
+ };
91
89
  var ERROR_RESPONSE = {
92
- AUTHORIZATION: {
93
- INVALID_REQUEST: "invalid_request",
94
- UNAUTHORIZED_CLIENT: "unauthorized_client",
95
- ACCESS_DENIED: "access_denied",
96
- UNSUPPORTED_RESPONSE_TYPE: "unsupported_response_type",
97
- INVALID_SCOPE: "invalid_scope",
98
- SERVER_ERROR: "server_error",
99
- TEMPORARILY_UNAVAILABLE: "temporarily_unavailable",
100
- },
101
- ACCESS_TOKEN: {
102
- INVALID_REQUEST: "invalid_request",
103
- INVALID_CLIENT: "invalid_client",
104
- INVALID_GRANT: "invalid_grant",
105
- UNAUTHORIZED_CLIENT: "unauthorized_client",
106
- UNSUPPORTED_GRANT_TYPE: "unsupported_grant_type",
107
- INVALID_SCOPE: "invalid_scope",
108
- },
109
- }
90
+ AUTHORIZATION: {
91
+ INVALID_REQUEST: "invalid_request",
92
+ UNAUTHORIZED_CLIENT: "unauthorized_client",
93
+ ACCESS_DENIED: "access_denied",
94
+ UNSUPPORTED_RESPONSE_TYPE: "unsupported_response_type",
95
+ INVALID_SCOPE: "invalid_scope",
96
+ SERVER_ERROR: "server_error",
97
+ TEMPORARILY_UNAVAILABLE: "temporarily_unavailable"
98
+ },
99
+ ACCESS_TOKEN: {
100
+ INVALID_REQUEST: "invalid_request",
101
+ INVALID_CLIENT: "invalid_client",
102
+ INVALID_GRANT: "invalid_grant",
103
+ UNAUTHORIZED_CLIENT: "unauthorized_client",
104
+ UNSUPPORTED_GRANT_TYPE: "unsupported_grant_type",
105
+ INVALID_SCOPE: "invalid_scope"
106
+ }
107
+ };
110
108
 
111
109
  // src/utils.ts
112
110
  var toSnakeCase = (str) => {
113
- return str
114
- .replace(/([a-z0-9])([A-Z])/g, "$1_$2")
115
- .replace(/([A-Z]+)([A-Z][a-z])/g, "$1_$2")
116
- .toLowerCase()
117
- .replace(/^_+/, "")
118
- }
111
+ return str.replace(/([a-z0-9])([A-Z])/g, "$1_$2").replace(/([A-Z]+)([A-Z][a-z])/g, "$1_$2").toLowerCase().replace(/^_+/, "");
112
+ };
119
113
  var toUpperCase = (str) => {
120
- return str.toUpperCase()
121
- }
114
+ return str.toUpperCase();
115
+ };
122
116
  var toCastCase = (obj, type = "snake") => {
123
- return Object.entries(obj).reduce((previous, [key, value]) => {
124
- const newKey = type === "snake" ? toSnakeCase(key) : toUpperCase(key)
125
- return { ...previous, [newKey]: value }
126
- }, {})
127
- }
117
+ return Object.entries(obj).reduce((previous, [key, value]) => {
118
+ const newKey = type === "snake" ? toSnakeCase(key) : toUpperCase(key);
119
+ return { ...previous, [newKey]: value };
120
+ }, {});
121
+ };
128
122
  var equals = (a, b) => {
129
- if (a === null || b === null || a === void 0 || b === void 0) return false
130
- return a === b
131
- }
123
+ if (a === null || b === null || a === void 0 || b === void 0) return false;
124
+ return a === b;
125
+ };
132
126
  var sanitizeURL = (url2) => {
133
- try {
134
- let decodedURL = decodeURIComponent(url2).trim()
135
- const protocolMatch = decodedURL.match(/^([a-zA-Z][a-zA-Z0-9+.-]*:\/\/)/)
136
- let protocol = ""
137
- let rest = decodedURL
138
- if (protocolMatch) {
139
- protocol = protocolMatch[1]
140
- rest = decodedURL.slice(protocol.length)
141
- const slashIndex = rest.indexOf("/")
142
- if (slashIndex === -1) {
143
- return protocol + rest
144
- }
145
- const domain = rest.slice(0, slashIndex)
146
- let path = rest
147
- .slice(slashIndex)
148
- .replace(/\/\.\.\//g, "/")
149
- .replace(/\/\.\.$/, "")
150
- .replace(/\.{2,}/g, "")
151
- .replace(/\/{2,}/g, "/")
152
- if (path !== "/" && path.endsWith("/")) {
153
- path = path.replace(/\/+$/, "/")
154
- } else if (path !== "/") {
155
- path = path.replace(/\/+$/, "")
156
- }
157
- return protocol + domain + path
158
- }
159
- let sanitized = decodedURL
160
- .replace(/\/\.\.\//g, "/")
161
- .replace(/\/\.\.$/, "")
162
- .replace(/\.{2,}/g, "")
163
- .replace(/\/{2,}/g, "/")
164
- if (sanitized !== "/" && sanitized.endsWith("/")) {
165
- sanitized = sanitized.replace(/\/+$/, "/")
166
- } else if (sanitized !== "/") {
167
- sanitized = sanitized.replace(/\/+$/, "")
168
- }
169
- return sanitized
170
- } catch {
171
- return url2.trim()
127
+ try {
128
+ let decodedURL = decodeURIComponent(url2).trim();
129
+ const protocolMatch = decodedURL.match(/^([a-zA-Z][a-zA-Z0-9+.-]*:\/\/)/);
130
+ let protocol = "";
131
+ let rest = decodedURL;
132
+ if (protocolMatch) {
133
+ protocol = protocolMatch[1];
134
+ rest = decodedURL.slice(protocol.length);
135
+ const slashIndex = rest.indexOf("/");
136
+ if (slashIndex === -1) {
137
+ return protocol + rest;
138
+ }
139
+ const domain = rest.slice(0, slashIndex);
140
+ let path = rest.slice(slashIndex).replace(/\/\.\.\//g, "/").replace(/\/\.\.$/, "").replace(/\.{2,}/g, "").replace(/\/{2,}/g, "/");
141
+ if (path !== "/" && path.endsWith("/")) {
142
+ path = path.replace(/\/+$/, "/");
143
+ } else if (path !== "/") {
144
+ path = path.replace(/\/+$/, "");
145
+ }
146
+ return protocol + domain + path;
147
+ }
148
+ let sanitized = decodedURL.replace(/\/\.\.\//g, "/").replace(/\/\.\.$/, "").replace(/\.{2,}/g, "").replace(/\/{2,}/g, "/");
149
+ if (sanitized !== "/" && sanitized.endsWith("/")) {
150
+ sanitized = sanitized.replace(/\/+$/, "/");
151
+ } else if (sanitized !== "/") {
152
+ sanitized = sanitized.replace(/\/+$/, "");
172
153
  }
173
- }
154
+ return sanitized;
155
+ } catch {
156
+ return url2.trim();
157
+ }
158
+ };
174
159
  var isValidRelativePath = (path) => {
175
- if (!path || typeof path !== "string") return false
176
- if (!path.startsWith("/") || path.includes("://") || path.includes("\r") || path.includes("\n")) return false
177
- if (/[\x00-\x1F\x7F]/.test(path) || path.includes("\0")) return false
178
- const sanitized = sanitizeURL(path)
179
- if (sanitized.includes("..")) return false
180
- return true
181
- }
160
+ if (!path || typeof path !== "string") return false;
161
+ if (!path.startsWith("/") || path.includes("://") || path.includes("\r") || path.includes("\n")) return false;
162
+ if (/[\x00-\x1F\x7F]/.test(path) || path.includes("\0")) return false;
163
+ const sanitized = sanitizeURL(path);
164
+ if (sanitized.includes("..")) return false;
165
+ return true;
166
+ };
182
167
  var getNormalizedOriginPath = (path) => {
183
- try {
184
- const url2 = new URL(path)
185
- url2.hash = ""
186
- url2.search = ""
187
- return `${url2.origin}${url2.pathname}`
188
- } catch {
189
- return sanitizeURL(path)
190
- }
191
- }
168
+ try {
169
+ const url2 = new URL(path);
170
+ url2.hash = "";
171
+ url2.search = "";
172
+ return `${url2.origin}${url2.pathname}`;
173
+ } catch {
174
+ return sanitizeURL(path);
175
+ }
176
+ };
192
177
  var toISOString = (date) => {
193
- return new Date(date).toISOString()
194
- }
178
+ return new Date(date).toISOString();
179
+ };
195
180
 
196
181
  // src/secure.ts
197
182
  var generateSecure = (length = 32) => {
198
- return import_node_crypto.default.randomBytes(length).toString("base64url")
199
- }
183
+ return import_node_crypto.default.randomBytes(length).toString("base64url");
184
+ };
200
185
  var createHash = (data, base = "hex") => {
201
- return import_node_crypto.default.createHash("sha256").update(data).digest().toString(base)
202
- }
186
+ return import_node_crypto.default.createHash("sha256").update(data).digest().toString(base);
187
+ };
203
188
  var createPKCE = async (verifier) => {
204
- const codeVerifier = verifier ?? generateSecure(86)
205
- const codeChallenge = createHash(codeVerifier, "base64url")
206
- return { codeVerifier, codeChallenge, method: "S256" }
207
- }
189
+ const codeVerifier = verifier ?? generateSecure(86);
190
+ const codeChallenge = createHash(codeVerifier, "base64url");
191
+ return { codeVerifier, codeChallenge, method: "S256" };
192
+ };
208
193
  var createCSRF = async (jose, csrfCookie) => {
209
- try {
210
- const token = generateSecure(32)
211
- if (csrfCookie) {
212
- await jose.verifyJWS(csrfCookie)
213
- return csrfCookie
214
- }
215
- return jose.signJWS({ token })
216
- } catch {
217
- const token = generateSecure(32)
218
- return jose.signJWS({ token })
194
+ try {
195
+ const token = generateSecure(32);
196
+ if (csrfCookie) {
197
+ await jose.verifyJWS(csrfCookie);
198
+ return csrfCookie;
219
199
  }
220
- }
200
+ return jose.signJWS({ token });
201
+ } catch {
202
+ const token = generateSecure(32);
203
+ return jose.signJWS({ token });
204
+ }
205
+ };
221
206
  var verifyCSRF = async (jose, cookie, header) => {
222
- try {
223
- const { token: cookieToken } = await jose.verifyJWS(cookie)
224
- const { token: headerToken } = await jose.verifyJWS(header)
225
- const cookieBuffer = Buffer.from(cookieToken)
226
- const headerBuffer = Buffer.from(headerToken)
227
- if (!equals(headerBuffer.length, cookieBuffer.length)) {
228
- throw new InvalidCsrfTokenError()
229
- }
230
- if (!import_node_crypto.default.timingSafeEqual(cookieBuffer, headerBuffer)) {
231
- throw new InvalidCsrfTokenError()
232
- }
233
- return true
234
- } catch {
235
- throw new InvalidCsrfTokenError()
207
+ try {
208
+ const { token: cookieToken } = await jose.verifyJWS(cookie);
209
+ const { token: headerToken } = await jose.verifyJWS(header);
210
+ const cookieBuffer = Buffer.from(cookieToken);
211
+ const headerBuffer = Buffer.from(headerToken);
212
+ if (!equals(headerBuffer.length, cookieBuffer.length)) {
213
+ throw new InvalidCsrfTokenError();
214
+ }
215
+ if (!import_node_crypto.default.timingSafeEqual(cookieBuffer, headerBuffer)) {
216
+ throw new InvalidCsrfTokenError();
236
217
  }
237
- }
218
+ return true;
219
+ } catch {
220
+ throw new InvalidCsrfTokenError();
221
+ }
222
+ };
238
223
 
239
224
  // src/cookie.ts
240
- var import_cookie = require("cookie")
225
+ var import_cookie = require("cookie");
241
226
 
242
227
  // src/assert.ts
243
228
  var isRequest = (value) => {
244
- return typeof Request !== "undefined" && value instanceof Request
245
- }
229
+ return typeof Request !== "undefined" && value instanceof Request;
230
+ };
246
231
  var isValidURL = (value) => {
247
- if (value.includes("\r\n") || value.includes("\n") || value.includes("\r")) return false
248
- const regex =
249
- /^https?:\/\/(?:[a-zA-Z0-9._-]+|localhost|\[[0-9a-fA-F:]+\])(?::\d{1,5})?(?:\/[a-zA-Z0-9._~!$&'()*+,;=:@-]*)*\/?$/
250
- return regex.test(value)
251
- }
232
+ if (value.includes("\r\n") || value.includes("\n") || value.includes("\r")) return false;
233
+ const regex = /^https?:\/\/(?:[a-zA-Z0-9._-]+|localhost|\[[0-9a-fA-F:]+\])(?::\d{1,5})?(?:\/[a-zA-Z0-9._~!$&'()*+,;=:@-]*)*\/?$/;
234
+ return regex.test(value);
235
+ };
252
236
 
253
237
  // src/cookie.ts
254
- var import_cookie2 = require("cookie")
255
- var COOKIE_NAME = "aura-auth"
238
+ var import_cookie2 = require("cookie");
239
+ var COOKIE_NAME = "aura-auth";
256
240
  var defaultCookieOptions = {
257
- httpOnly: true,
258
- sameSite: "lax",
259
- path: "/",
260
- maxAge: 60 * 60 * 24 * 15,
261
- }
241
+ httpOnly: true,
242
+ sameSite: "lax",
243
+ path: "/",
244
+ maxAge: 60 * 60 * 24 * 15
245
+ };
262
246
  var defaultStandardCookieConfig = {
263
- secure: false,
264
- httpOnly: true,
265
- prefix: "",
266
- }
247
+ secure: false,
248
+ httpOnly: true,
249
+ prefix: ""
250
+ };
267
251
  var defaultSecureCookieConfig = {
268
- secure: true,
269
- prefix: "__Secure-",
270
- }
252
+ secure: true,
253
+ prefix: "__Secure-"
254
+ };
271
255
  var defaultHostCookieConfig = {
272
- secure: true,
273
- prefix: "__Host-",
274
- path: "/",
275
- domain: void 0,
276
- }
256
+ secure: true,
257
+ prefix: "__Host-",
258
+ path: "/",
259
+ domain: void 0
260
+ };
277
261
  var expiredCookieOptions = {
278
- ...defaultCookieOptions,
279
- expires: /* @__PURE__ */ new Date(0),
280
- maxAge: 0,
281
- }
262
+ ...defaultCookieOptions,
263
+ expires: /* @__PURE__ */ new Date(0),
264
+ maxAge: 0
265
+ };
282
266
  var defineDefaultCookieOptions = (options2) => {
283
- return {
284
- name: options2?.name ?? COOKIE_NAME,
285
- prefix: options2?.prefix ?? (options2?.secure ? "__Secure-" : ""),
286
- ...defaultCookieOptions,
287
- ...options2,
288
- }
289
- }
267
+ return {
268
+ name: options2?.name ?? COOKIE_NAME,
269
+ prefix: options2?.prefix ?? (options2?.secure ? "__Secure-" : ""),
270
+ ...defaultCookieOptions,
271
+ ...options2
272
+ };
273
+ };
290
274
  var setCookie = (cookieName, value, options2) => {
291
- const { prefix, name } = defineDefaultCookieOptions(options2)
292
- const cookieNameWithPrefix = `${prefix}${name}.${cookieName}`
293
- return (0, import_cookie.serialize)(cookieNameWithPrefix, value, {
294
- ...defaultCookieOptions,
295
- ...options2,
296
- })
297
- }
275
+ const { prefix, name } = defineDefaultCookieOptions(options2);
276
+ const cookieNameWithPrefix = `${prefix}${name}.${cookieName}`;
277
+ return (0, import_cookie.serialize)(cookieNameWithPrefix, value, {
278
+ ...defaultCookieOptions,
279
+ ...options2
280
+ });
281
+ };
298
282
  var getCookie = (petition, cookie, options2, optional = false) => {
299
- const cookies = isRequest(petition) ? petition.headers.get("Cookie") : petition.headers.getSetCookie().join("; ")
300
- if (!cookies) {
301
- if (optional) {
302
- return ""
303
- }
304
- throw new AuthError("invalid_request", "No cookies found. There is no active session")
283
+ const cookies = isRequest(petition) ? petition.headers.get("Cookie") : petition.headers.getSetCookie().join("; ");
284
+ if (!cookies) {
285
+ if (optional) {
286
+ return "";
305
287
  }
306
- const { name, prefix } = defineDefaultCookieOptions(options2)
307
- const parsedCookies = (0, import_cookie.parse)(cookies)
308
- const value = parsedCookies[`${prefix}${name}.${cookie}`]
309
- if (value === void 0) {
310
- if (optional) {
311
- return ""
312
- }
313
- throw new AuthError("invalid_request", `Cookie "${cookie}" not found. There is no active session`)
288
+ throw new AuthError("invalid_request", "No cookies found. There is no active session");
289
+ }
290
+ const { name, prefix } = defineDefaultCookieOptions(options2);
291
+ const parsedCookies = (0, import_cookie.parse)(cookies);
292
+ const value = parsedCookies[`${prefix}${name}.${cookie}`];
293
+ if (value === void 0) {
294
+ if (optional) {
295
+ return "";
314
296
  }
315
- return value
316
- }
297
+ throw new AuthError("invalid_request", `Cookie "${cookie}" not found. There is no active session`);
298
+ }
299
+ return value;
300
+ };
317
301
  var createSessionCookie = async (session, cookieOptions, jose) => {
318
- try {
319
- const encoded = await jose.encodeJWT(session)
320
- return setCookie("sessionToken", encoded, cookieOptions)
321
- } catch (error) {
322
- throw new AuthError("server_error", "Failed to create session cookie", { cause: error })
323
- }
324
- }
302
+ try {
303
+ const encoded = await jose.encodeJWT(session);
304
+ return setCookie("sessionToken", encoded, cookieOptions);
305
+ } catch (error) {
306
+ throw new AuthError("server_error", "Failed to create session cookie", { cause: error });
307
+ }
308
+ };
325
309
  var secureCookieOptions = (request, cookieOptions, trustedProxyHeaders) => {
326
- const name = cookieOptions.name ?? COOKIE_NAME
327
- const isSecure = trustedProxyHeaders
328
- ? request.url.startsWith("https://") ||
329
- request.headers.get("X-Forwarded-Proto") === "https" ||
330
- request.headers.get("Forwarded")?.includes("proto=https")
331
- : request.url.startsWith("https://")
332
- if (!cookieOptions.options?.httpOnly) {
333
- console.warn(
334
- "[WARNING]: Cookie is configured without HttpOnly. This allows JavaScript access via document.cookie and increases XSS risk."
335
- )
310
+ const name = cookieOptions.name ?? COOKIE_NAME;
311
+ const isSecure = trustedProxyHeaders ? request.url.startsWith("https://") || request.headers.get("X-Forwarded-Proto") === "https" || request.headers.get("Forwarded")?.includes("proto=https") : request.url.startsWith("https://");
312
+ if (!cookieOptions.options?.httpOnly) {
313
+ console.warn(
314
+ "[WARNING]: Cookie is configured without HttpOnly. This allows JavaScript access via document.cookie and increases XSS risk."
315
+ );
316
+ }
317
+ if (cookieOptions.options?.domain === "*") {
318
+ console.warn("[WARNING]: Cookie 'Domain' is set to '*', which is insecure. Avoid wildcard domains.");
319
+ }
320
+ if (!isSecure) {
321
+ const options2 = cookieOptions.options;
322
+ if (options2?.secure) {
323
+ console.warn(
324
+ "[WARNING]: The 'Secure' attribute will be disabled for this cookie. Serve over HTTPS to enforce Secure cookies."
325
+ );
336
326
  }
337
- if (cookieOptions.options?.domain === "*") {
338
- console.warn("[WARNING]: Cookie 'Domain' is set to '*', which is insecure. Avoid wildcard domains.")
327
+ if (options2?.sameSite == "none") {
328
+ console.warn("[WARNING]: SameSite=None without a secure connection can be blocked by browsers.");
339
329
  }
340
- if (!isSecure) {
341
- const options2 = cookieOptions.options
342
- if (options2?.secure) {
343
- console.warn(
344
- "[WARNING]: The 'Secure' attribute will be disabled for this cookie. Serve over HTTPS to enforce Secure cookies."
345
- )
346
- }
347
- if (options2?.sameSite == "none") {
348
- console.warn("[WARNING]: SameSite=None without a secure connection can be blocked by browsers.")
349
- }
350
- if (process.env.NODE_ENV === "production") {
351
- console.warn("[WARNING]: In production, ensure cookies are served over HTTPS to maintain security.")
352
- }
353
- return {
354
- ...defaultCookieOptions,
355
- ...cookieOptions.options,
356
- sameSite: options2?.sameSite === "none" ? "lax" : (options2?.sameSite ?? "lax"),
357
- ...defaultStandardCookieConfig,
358
- name,
359
- }
330
+ if (process.env.NODE_ENV === "production") {
331
+ console.warn("[WARNING]: In production, ensure cookies are served over HTTPS to maintain security.");
360
332
  }
361
- return cookieOptions.strategy === "host"
362
- ? {
363
- ...defaultCookieOptions,
364
- ...cookieOptions.options,
365
- ...defaultHostCookieConfig,
366
- name,
367
- }
368
- : { ...defaultCookieOptions, ...cookieOptions.options, ...defaultSecureCookieConfig, name }
369
- }
333
+ return {
334
+ ...defaultCookieOptions,
335
+ ...cookieOptions.options,
336
+ sameSite: options2?.sameSite === "none" ? "lax" : options2?.sameSite ?? "lax",
337
+ ...defaultStandardCookieConfig,
338
+ name
339
+ };
340
+ }
341
+ return cookieOptions.strategy === "host" ? {
342
+ ...defaultCookieOptions,
343
+ ...cookieOptions.options,
344
+ ...defaultHostCookieConfig,
345
+ name
346
+ } : { ...defaultCookieOptions, ...cookieOptions.options, ...defaultSecureCookieConfig, name };
347
+ };
370
348
  var expireCookie = (name, options2) => {
371
- return setCookie(name, "", { ...options2, ...expiredCookieOptions })
372
- }
349
+ return setCookie(name, "", { ...options2, ...expiredCookieOptions });
350
+ };
373
351
  var oauthCookie = (options2) => {
374
- return {
375
- ...options2,
376
- secure: options2.secure,
377
- httpOnly: options2.httpOnly,
378
- maxAge: 5 * 60,
379
- expires: new Date(Date.now() + 5 * 60 * 1e3),
380
- }
381
- }
352
+ return {
353
+ ...options2,
354
+ secure: options2.secure,
355
+ httpOnly: options2.httpOnly,
356
+ maxAge: 5 * 60,
357
+ expires: new Date(Date.now() + 5 * 60 * 1e3)
358
+ };
359
+ };
382
360
 
383
361
  // src/schemas.ts
384
- var import_v4 = require("zod/v4")
362
+ var import_v4 = require("zod/v4");
385
363
  var OAuthProviderConfigSchema = (0, import_v4.object)({
386
- authorizeURL: (0, import_v4.url)(),
387
- accessToken: (0, import_v4.url)(),
388
- scope: (0, import_v4.string)().optional(),
389
- userInfo: (0, import_v4.url)(),
390
- responseType: (0, import_v4.enum)(["code", "token", "id_token"]),
391
- clientId: (0, import_v4.string)(),
392
- clientSecret: (0, import_v4.string)(),
393
- })
364
+ authorizeURL: (0, import_v4.url)(),
365
+ accessToken: (0, import_v4.url)(),
366
+ scope: (0, import_v4.string)().optional(),
367
+ userInfo: (0, import_v4.url)(),
368
+ responseType: (0, import_v4.enum)(["code", "token", "id_token"]),
369
+ clientId: (0, import_v4.string)(),
370
+ clientSecret: (0, import_v4.string)()
371
+ });
394
372
  var OAuthAuthorization = OAuthProviderConfigSchema.extend({
395
- redirectURI: (0, import_v4.string)(),
396
- state: (0, import_v4.string)(),
397
- codeChallenge: (0, import_v4.string)(),
398
- codeChallengeMethod: (0, import_v4.enum)(["plain", "S256"]),
399
- })
373
+ redirectURI: (0, import_v4.string)(),
374
+ state: (0, import_v4.string)(),
375
+ codeChallenge: (0, import_v4.string)(),
376
+ codeChallengeMethod: (0, import_v4.enum)(["plain", "S256"])
377
+ });
400
378
  var OAuthAuthorizationResponse = (0, import_v4.object)({
401
- state: (0, import_v4.string)(),
402
- code: (0, import_v4.string)(),
403
- })
379
+ state: (0, import_v4.string)(),
380
+ code: (0, import_v4.string)()
381
+ });
404
382
  var OAuthAuthorizationErrorResponse = (0, import_v4.object)({
405
- error: (0, import_v4.enum)([
406
- "invalid_request",
407
- "unauthorized_client",
408
- "access_denied",
409
- "unsupported_response_type",
410
- "invalid_scope",
411
- "server_error",
412
- "temporarily_unavailable",
413
- ]),
414
- error_description: (0, import_v4.string)().optional(),
415
- error_uri: (0, import_v4.string)().optional(),
416
- state: (0, import_v4.string)(),
417
- })
383
+ error: (0, import_v4.enum)([
384
+ "invalid_request",
385
+ "unauthorized_client",
386
+ "access_denied",
387
+ "unsupported_response_type",
388
+ "invalid_scope",
389
+ "server_error",
390
+ "temporarily_unavailable"
391
+ ]),
392
+ error_description: (0, import_v4.string)().optional(),
393
+ error_uri: (0, import_v4.string)().optional(),
394
+ state: (0, import_v4.string)()
395
+ });
418
396
  var OAuthAccessToken = OAuthProviderConfigSchema.extend({
419
- redirectURI: (0, import_v4.string)(),
420
- code: (0, import_v4.string)(),
421
- codeVerifier: (0, import_v4.string)().min(43).max(128),
422
- })
397
+ redirectURI: (0, import_v4.string)(),
398
+ code: (0, import_v4.string)(),
399
+ codeVerifier: (0, import_v4.string)().min(43).max(128)
400
+ });
423
401
  var OAuthAccessTokenResponse = (0, import_v4.object)({
424
- access_token: (0, import_v4.string)(),
425
- token_type: (0, import_v4.string)(),
426
- expires_in: (0, import_v4.number)().optional(),
427
- refresh_token: (0, import_v4.string)().optional(),
428
- scope: (0, import_v4.string)().optional(),
429
- })
402
+ access_token: (0, import_v4.string)(),
403
+ token_type: (0, import_v4.string)(),
404
+ expires_in: (0, import_v4.number)().optional(),
405
+ refresh_token: (0, import_v4.string)().optional(),
406
+ scope: (0, import_v4.string)().optional()
407
+ });
430
408
  var OAuthAccessTokenErrorResponse = (0, import_v4.object)({
431
- error: (0, import_v4.enum)([
432
- "invalid_request",
433
- "invalid_client",
434
- "invalid_grant",
435
- "unauthorized_client",
436
- "unsupported_grant_type",
437
- "invalid_scope",
438
- ]),
439
- error_description: (0, import_v4.string)().optional(),
440
- error_uri: (0, import_v4.string)().optional(),
441
- })
409
+ error: (0, import_v4.enum)([
410
+ "invalid_request",
411
+ "invalid_client",
412
+ "invalid_grant",
413
+ "unauthorized_client",
414
+ "unsupported_grant_type",
415
+ "invalid_scope"
416
+ ]),
417
+ error_description: (0, import_v4.string)().optional(),
418
+ error_uri: (0, import_v4.string)().optional()
419
+ });
442
420
  var OAuthErrorResponse = (0, import_v4.object)({
443
- error: (0, import_v4.string)(),
444
- error_description: (0, import_v4.string)().optional(),
445
- })
421
+ error: (0, import_v4.string)(),
422
+ error_description: (0, import_v4.string)().optional()
423
+ });
446
424
 
447
425
  // src/actions/signIn/authorization.ts
448
426
  var createAuthorizationURL = (oauthConfig, redirectURI, state, codeChallenge, codeChallengeMethod) => {
449
- const parsed = OAuthAuthorization.safeParse({ ...oauthConfig, redirectURI, state, codeChallenge, codeChallengeMethod })
450
- if (!parsed.success) {
451
- throw new AuthError(ERROR_RESPONSE.AUTHORIZATION.SERVER_ERROR, "Invalid OAuth configuration")
452
- }
453
- const { authorizeURL, ...options2 } = parsed.data
454
- const { userInfo, accessToken, clientSecret, ...required } = options2
455
- const searchParams = new URLSearchParams(toCastCase(required))
456
- return `${authorizeURL}?${searchParams}`
457
- }
427
+ const parsed = OAuthAuthorization.safeParse({ ...oauthConfig, redirectURI, state, codeChallenge, codeChallengeMethod });
428
+ if (!parsed.success) {
429
+ throw new AuthError(ERROR_RESPONSE.AUTHORIZATION.SERVER_ERROR, "Invalid OAuth configuration");
430
+ }
431
+ const { authorizeURL, ...options2 } = parsed.data;
432
+ const { userInfo, accessToken, clientSecret, ...required } = options2;
433
+ const searchParams = new URLSearchParams(toCastCase(required));
434
+ return `${authorizeURL}?${searchParams}`;
435
+ };
458
436
  var getOriginURL = (request, trustedProxyHeaders) => {
459
- const headers = request.headers
460
- if (trustedProxyHeaders) {
461
- const protocol = headers.get("X-Forwarded-Proto") ?? headers.get("Forwarded")?.match(/proto=([^;]+)/i)?.[1] ?? "http"
462
- const host =
463
- headers.get("X-Forwarded-Host") ??
464
- headers.get("Host") ??
465
- headers.get("Forwarded")?.match(/host=([^;]+)/i)?.[1] ??
466
- null
467
- return new URL(`${protocol}://${host}${getNormalizedOriginPath(new URL(request.url).pathname)}`)
468
- } else {
469
- return new URL(getNormalizedOriginPath(request.url))
470
- }
471
- }
437
+ const headers = request.headers;
438
+ if (trustedProxyHeaders) {
439
+ const protocol = headers.get("X-Forwarded-Proto") ?? headers.get("Forwarded")?.match(/proto=([^;]+)/i)?.[1] ?? "http";
440
+ const host = headers.get("X-Forwarded-Host") ?? headers.get("Host") ?? headers.get("Forwarded")?.match(/host=([^;]+)/i)?.[1] ?? null;
441
+ return new URL(`${protocol}://${host}${getNormalizedOriginPath(new URL(request.url).pathname)}`);
442
+ } else {
443
+ return new URL(getNormalizedOriginPath(request.url));
444
+ }
445
+ };
472
446
  var createRedirectURI = (request, oauth, basePath, trustedProxyHeaders) => {
473
- const url2 = getOriginURL(request, trustedProxyHeaders)
474
- return `${url2.origin}${basePath}/callback/${oauth}`
475
- }
447
+ const url2 = getOriginURL(request, trustedProxyHeaders);
448
+ return `${url2.origin}${basePath}/callback/${oauth}`;
449
+ };
476
450
  var createRedirectTo = (request, redirectTo, trustedProxyHeaders) => {
477
- try {
478
- const headers = request.headers
479
- const origin = headers.get("Origin")
480
- const referer = headers.get("Referer")
481
- let hostedURL = getOriginURL(request, trustedProxyHeaders)
482
- if (redirectTo) {
483
- if (redirectTo.startsWith("/")) {
484
- return sanitizeURL(redirectTo)
485
- }
486
- const redirectToURL = new URL(sanitizeURL(getNormalizedOriginPath(redirectTo)))
487
- if (!isValidURL(redirectTo) || !equals(redirectToURL.origin, hostedURL.origin)) {
488
- throw new InvalidRedirectToError()
489
- }
490
- return sanitizeURL(redirectToURL.pathname)
491
- }
492
- if (referer) {
493
- const refererURL = new URL(sanitizeURL(referer))
494
- if (!isValidURL(referer) || !equals(refererURL.origin, hostedURL.origin)) {
495
- throw new AuthError(
496
- ERROR_RESPONSE.AUTHORIZATION.INVALID_REQUEST,
497
- "The referer of the request does not match the hosted origin."
498
- )
499
- }
500
- return sanitizeURL(refererURL.pathname)
501
- }
502
- if (origin) {
503
- const originURL = new URL(sanitizeURL(getNormalizedOriginPath(origin)))
504
- if (!isValidURL(origin) || !equals(originURL.origin, hostedURL.origin)) {
505
- throw new AuthError(ERROR_RESPONSE.AUTHORIZATION.INVALID_REQUEST, "Invalid origin (potential CSRF).")
506
- }
507
- return sanitizeURL(originURL.pathname)
508
- }
509
- return "/"
510
- } catch (error) {
511
- if (isAuthError(error)) {
512
- throw error
513
- }
514
- throw new AuthError(ERROR_RESPONSE.AUTHORIZATION.INVALID_REQUEST, "Invalid origin (potential CSRF).")
451
+ try {
452
+ const headers = request.headers;
453
+ const origin = headers.get("Origin");
454
+ const referer = headers.get("Referer");
455
+ let hostedURL = getOriginURL(request, trustedProxyHeaders);
456
+ if (redirectTo) {
457
+ if (redirectTo.startsWith("/")) {
458
+ return sanitizeURL(redirectTo);
459
+ }
460
+ const redirectToURL = new URL(sanitizeURL(getNormalizedOriginPath(redirectTo)));
461
+ if (!isValidURL(redirectTo) || !equals(redirectToURL.origin, hostedURL.origin)) {
462
+ throw new InvalidRedirectToError();
463
+ }
464
+ return sanitizeURL(redirectToURL.pathname);
465
+ }
466
+ if (referer) {
467
+ const refererURL = new URL(sanitizeURL(referer));
468
+ if (!isValidURL(referer) || !equals(refererURL.origin, hostedURL.origin)) {
469
+ throw new AuthError(
470
+ ERROR_RESPONSE.AUTHORIZATION.INVALID_REQUEST,
471
+ "The referer of the request does not match the hosted origin."
472
+ );
473
+ }
474
+ return sanitizeURL(refererURL.pathname);
475
+ }
476
+ if (origin) {
477
+ const originURL = new URL(sanitizeURL(getNormalizedOriginPath(origin)));
478
+ if (!isValidURL(origin) || !equals(originURL.origin, hostedURL.origin)) {
479
+ throw new AuthError(ERROR_RESPONSE.AUTHORIZATION.INVALID_REQUEST, "Invalid origin (potential CSRF).");
480
+ }
481
+ return sanitizeURL(originURL.pathname);
482
+ }
483
+ return "/";
484
+ } catch (error) {
485
+ if (isAuthError(error)) {
486
+ throw error;
515
487
  }
516
- }
488
+ throw new AuthError(ERROR_RESPONSE.AUTHORIZATION.INVALID_REQUEST, "Invalid origin (potential CSRF).");
489
+ }
490
+ };
517
491
 
518
492
  // src/actions/signIn/signIn.ts
519
493
  var signInConfig = (oauth) => {
520
- return (0, import_router2.createEndpointConfig)("/signIn/:oauth", {
521
- schemas: {
522
- params: import_zod.default.object({
523
- oauth: import_zod.default.enum(Object.keys(oauth)),
524
- redirectTo: import_zod.default.string().optional(),
525
- }),
526
- },
527
- })
528
- }
494
+ return (0, import_router2.createEndpointConfig)("/signIn/:oauth", {
495
+ schemas: {
496
+ params: import_zod.default.object({
497
+ oauth: import_zod.default.enum(Object.keys(oauth)),
498
+ redirectTo: import_zod.default.string().optional()
499
+ })
500
+ }
501
+ });
502
+ };
529
503
  var signInAction = (oauth) => {
530
- return (0, import_router2.createEndpoint)(
531
- "GET",
532
- "/signIn/:oauth",
533
- async (ctx) => {
534
- const {
535
- request,
536
- params: { oauth: oauth2, redirectTo },
537
- context: { oauth: providers, cookies, trustedProxyHeaders, basePath },
538
- } = ctx
539
- try {
540
- const cookieOptions = secureCookieOptions(request, cookies, trustedProxyHeaders)
541
- const state = generateSecure()
542
- const redirectURI = createRedirectURI(request, oauth2, basePath, trustedProxyHeaders)
543
- const stateCookie = setCookie("state", state, oauthCookie(cookieOptions))
544
- const redirectURICookie = setCookie("redirect_uri", redirectURI, oauthCookie(cookieOptions))
545
- const redirectToCookie = setCookie(
546
- "redirect_to",
547
- createRedirectTo(request, redirectTo, trustedProxyHeaders),
548
- oauthCookie(cookieOptions)
549
- )
550
- const { codeVerifier, codeChallenge, method } = await createPKCE()
551
- const codeVerifierCookie = setCookie("code_verifier", codeVerifier, oauthCookie(cookieOptions))
552
- const authorization = createAuthorizationURL(providers[oauth2], redirectURI, state, codeChallenge, method)
553
- const headers = new Headers()
554
- headers.set("Location", authorization)
555
- headers.append("Set-Cookie", stateCookie)
556
- headers.append("Set-Cookie", redirectURICookie)
557
- headers.append("Set-Cookie", redirectToCookie)
558
- headers.append("Set-Cookie", codeVerifierCookie)
559
- return Response.json(
560
- { oauth: oauth2 },
561
- {
562
- status: 302,
563
- headers,
564
- }
565
- )
566
- } catch (error) {
567
- if (isAuthError(error)) {
568
- const { type, message } = error
569
- return AuraResponse.json(
570
- { error: type, error_description: message },
571
- { status: import_router2.statusCode.BAD_REQUEST }
572
- )
573
- }
574
- return AuraResponse.json(
575
- {
576
- error: ERROR_RESPONSE.AUTHORIZATION.SERVER_ERROR,
577
- error_description: "An unexpected error occurred",
578
- },
579
- { status: import_router2.statusCode.INTERNAL_SERVER_ERROR }
580
- )
581
- }
582
- },
583
- signInConfig(oauth)
584
- )
585
- }
504
+ return (0, import_router2.createEndpoint)(
505
+ "GET",
506
+ "/signIn/:oauth",
507
+ async (ctx) => {
508
+ const {
509
+ request,
510
+ params: { oauth: oauth2, redirectTo },
511
+ context: { oauth: providers, cookies, trustedProxyHeaders, basePath }
512
+ } = ctx;
513
+ try {
514
+ const cookieOptions = secureCookieOptions(request, cookies, trustedProxyHeaders);
515
+ const state = generateSecure();
516
+ const redirectURI = createRedirectURI(request, oauth2, basePath, trustedProxyHeaders);
517
+ const stateCookie = setCookie("state", state, oauthCookie(cookieOptions));
518
+ const redirectURICookie = setCookie("redirect_uri", redirectURI, oauthCookie(cookieOptions));
519
+ const redirectToCookie = setCookie(
520
+ "redirect_to",
521
+ createRedirectTo(request, redirectTo, trustedProxyHeaders),
522
+ oauthCookie(cookieOptions)
523
+ );
524
+ const { codeVerifier, codeChallenge, method } = await createPKCE();
525
+ const codeVerifierCookie = setCookie("code_verifier", codeVerifier, oauthCookie(cookieOptions));
526
+ const authorization = createAuthorizationURL(providers[oauth2], redirectURI, state, codeChallenge, method);
527
+ const headers = new Headers();
528
+ headers.set("Location", authorization);
529
+ headers.append("Set-Cookie", stateCookie);
530
+ headers.append("Set-Cookie", redirectURICookie);
531
+ headers.append("Set-Cookie", redirectToCookie);
532
+ headers.append("Set-Cookie", codeVerifierCookie);
533
+ return Response.json(
534
+ { oauth: oauth2 },
535
+ {
536
+ status: 302,
537
+ headers
538
+ }
539
+ );
540
+ } catch (error) {
541
+ if (isAuthError(error)) {
542
+ const { type, message } = error;
543
+ return AuraResponse.json(
544
+ { error: type, error_description: message },
545
+ { status: import_router2.statusCode.BAD_REQUEST }
546
+ );
547
+ }
548
+ return AuraResponse.json(
549
+ {
550
+ error: ERROR_RESPONSE.AUTHORIZATION.SERVER_ERROR,
551
+ error_description: "An unexpected error occurred"
552
+ },
553
+ { status: import_router2.statusCode.INTERNAL_SERVER_ERROR }
554
+ );
555
+ }
556
+ },
557
+ signInConfig(oauth)
558
+ );
559
+ };
586
560
 
587
561
  // src/actions/callback/callback.ts
588
- var import_zod2 = __toESM(require("zod"), 1)
589
- var import_router3 = require("@aura-stack/router")
562
+ var import_zod2 = __toESM(require("zod"), 1);
563
+ var import_router3 = require("@aura-stack/router");
590
564
 
591
565
  // src/headers.ts
592
566
  var cacheControl = {
593
- "Cache-Control": "no-store",
594
- Pragma: "no-cache",
595
- Expires: "0",
596
- Vary: "Cookie",
597
- }
567
+ "Cache-Control": "no-store",
568
+ Pragma: "no-cache",
569
+ Expires: "0",
570
+ Vary: "Cookie"
571
+ };
598
572
 
599
573
  // src/actions/callback/userinfo.ts
600
574
  var getDefaultUserInfo = (profile) => {
601
- const sub = generateSecure(16)
602
- return {
603
- sub: profile?.id ?? profile?.sub ?? sub,
604
- email: profile?.email,
605
- name: profile?.name ?? profile?.username ?? profile?.nickname,
606
- image: profile?.image ?? profile?.picture,
607
- }
608
- }
575
+ const sub = generateSecure(16);
576
+ return {
577
+ sub: profile?.id ?? profile?.sub ?? sub,
578
+ email: profile?.email,
579
+ name: profile?.name ?? profile?.username ?? profile?.nickname,
580
+ image: profile?.image ?? profile?.picture
581
+ };
582
+ };
609
583
  var getUserInfo = async (oauthConfig, accessToken) => {
610
- const userinfoEndpoint = oauthConfig.userInfo
611
- try {
612
- const response = await fetch(userinfoEndpoint, {
613
- method: "GET",
614
- headers: {
615
- Accept: "application/json",
616
- Authorization: `Bearer ${accessToken}`,
617
- },
618
- })
619
- const json = await response.json()
620
- const { success, data } = OAuthErrorResponse.safeParse(json)
621
- if (success) {
622
- throw new AuthError(data.error, data?.error_description ?? "An error occurred while fetching user information.")
623
- }
624
- return oauthConfig?.profile ? oauthConfig.profile(json) : getDefaultUserInfo(json)
625
- } catch (error) {
626
- throw throwAuthError(error, "Failed to retrieve userinfo")
584
+ const userinfoEndpoint = oauthConfig.userInfo;
585
+ try {
586
+ const response = await fetch(userinfoEndpoint, {
587
+ method: "GET",
588
+ headers: {
589
+ Accept: "application/json",
590
+ Authorization: `Bearer ${accessToken}`
591
+ }
592
+ });
593
+ const json = await response.json();
594
+ const { success, data } = OAuthErrorResponse.safeParse(json);
595
+ if (success) {
596
+ throw new AuthError(data.error, data?.error_description ?? "An error occurred while fetching user information.");
627
597
  }
628
- }
598
+ return oauthConfig?.profile ? oauthConfig.profile(json) : getDefaultUserInfo(json);
599
+ } catch (error) {
600
+ throw throwAuthError(error, "Failed to retrieve userinfo");
601
+ }
602
+ };
629
603
 
630
604
  // src/actions/callback/access-token.ts
631
605
  var createAccessToken = async (oauthConfig, redirectURI, code, codeVerifier) => {
632
- const parsed = OAuthAccessToken.safeParse({ ...oauthConfig, redirectURI, code, codeVerifier })
633
- if (!parsed.success) {
634
- throw new AuthError(ERROR_RESPONSE.ACCESS_TOKEN.INVALID_REQUEST, "Invalid OAuth configuration")
606
+ const parsed = OAuthAccessToken.safeParse({ ...oauthConfig, redirectURI, code, codeVerifier });
607
+ if (!parsed.success) {
608
+ throw new AuthError(ERROR_RESPONSE.ACCESS_TOKEN.INVALID_REQUEST, "Invalid OAuth configuration");
609
+ }
610
+ const { accessToken, clientId, clientSecret, code: codeParsed, redirectURI: redirectParsed } = parsed.data;
611
+ try {
612
+ const response = await fetch(accessToken, {
613
+ method: "POST",
614
+ headers: {
615
+ Accept: "application/json",
616
+ "Content-Type": "application/x-www-form-urlencoded"
617
+ },
618
+ body: new URLSearchParams({
619
+ client_id: clientId,
620
+ client_secret: clientSecret,
621
+ code: codeParsed,
622
+ redirect_uri: redirectParsed,
623
+ grant_type: "authorization_code",
624
+ code_verifier: codeVerifier
625
+ }).toString()
626
+ });
627
+ const json = await response.json();
628
+ const token = OAuthAccessTokenResponse.safeParse(json);
629
+ if (!token.success) {
630
+ const { success, data } = OAuthAccessTokenErrorResponse.safeParse(json);
631
+ if (!success) {
632
+ throw new AuthError(ERROR_RESPONSE.ACCESS_TOKEN.INVALID_GRANT, "Invalid access token response format");
633
+ }
634
+ throw new AuthError(data.error, data?.error_description ?? "Failed to retrieve access token");
635
635
  }
636
- const { accessToken, clientId, clientSecret, code: codeParsed, redirectURI: redirectParsed } = parsed.data
637
- try {
638
- const response = await fetch(accessToken, {
639
- method: "POST",
640
- headers: {
641
- Accept: "application/json",
642
- "Content-Type": "application/x-www-form-urlencoded",
643
- },
644
- body: new URLSearchParams({
645
- client_id: clientId,
646
- client_secret: clientSecret,
647
- code: codeParsed,
648
- redirect_uri: redirectParsed,
649
- grant_type: "authorization_code",
650
- code_verifier: codeVerifier,
651
- }).toString(),
652
- })
653
- const json = await response.json()
654
- const token = OAuthAccessTokenResponse.safeParse(json)
655
- if (!token.success) {
656
- const { success, data } = OAuthAccessTokenErrorResponse.safeParse(json)
657
- if (!success) {
658
- throw new AuthError(ERROR_RESPONSE.ACCESS_TOKEN.INVALID_GRANT, "Invalid access token response format")
659
- }
660
- throw new AuthError(data.error, data?.error_description ?? "Failed to retrieve access token")
661
- }
662
- return token.data
663
- } catch (error) {
664
- throw throwAuthError(error, "Failed to create access token")
665
- }
666
- }
636
+ return token.data;
637
+ } catch (error) {
638
+ throw throwAuthError(error, "Failed to create access token");
639
+ }
640
+ };
667
641
 
668
642
  // src/actions/callback/callback.ts
669
643
  var callbackConfig = (oauth) => {
670
- return (0, import_router3.createEndpointConfig)("/callback/:oauth", {
671
- schemas: {
672
- searchParams: OAuthAuthorizationResponse,
673
- params: import_zod2.default.object({
674
- oauth: import_zod2.default.enum(Object.keys(oauth)),
675
- }),
676
- },
677
- middlewares: [
678
- (ctx) => {
679
- const response = OAuthAuthorizationErrorResponse.safeParse(ctx.searchParams)
680
- if (response.success) {
681
- const { error, error_description } = response.data
682
- throw new AuthError(error, error_description ?? "OAuth Authorization Error")
683
- }
684
- return ctx
685
- },
686
- ],
687
- })
688
- }
644
+ return (0, import_router3.createEndpointConfig)("/callback/:oauth", {
645
+ schemas: {
646
+ searchParams: OAuthAuthorizationResponse,
647
+ params: import_zod2.default.object({
648
+ oauth: import_zod2.default.enum(Object.keys(oauth))
649
+ })
650
+ },
651
+ middlewares: [
652
+ (ctx) => {
653
+ const response = OAuthAuthorizationErrorResponse.safeParse(ctx.searchParams);
654
+ if (response.success) {
655
+ const { error, error_description } = response.data;
656
+ throw new AuthError(error, error_description ?? "OAuth Authorization Error");
657
+ }
658
+ return ctx;
659
+ }
660
+ ]
661
+ });
662
+ };
689
663
  var callbackAction = (oauth) => {
690
- return (0, import_router3.createEndpoint)(
691
- "GET",
692
- "/callback/:oauth",
693
- async (ctx) => {
694
- const {
695
- request,
696
- params: { oauth: oauth2 },
697
- searchParams: { code, state },
698
- context: { oauth: providers, cookies, jose, trustedProxyHeaders },
699
- } = ctx
700
- try {
701
- const oauthConfig = providers[oauth2]
702
- const cookieOptions = secureCookieOptions(request, cookies, trustedProxyHeaders)
703
- const cookieState = getCookie(request, "state", cookieOptions)
704
- const cookieRedirectTo = getCookie(request, "redirect_to", cookieOptions)
705
- const cookieRedirectURI = getCookie(request, "redirect_uri", cookieOptions)
706
- const codeVerifier = getCookie(request, "code_verifier", cookieOptions)
707
- if (!equals(cookieState, state)) {
708
- throw new AuthError(ERROR_RESPONSE.ACCESS_TOKEN.INVALID_REQUEST, "Mismatching state")
709
- }
710
- const accessToken = await createAccessToken(oauthConfig, cookieRedirectURI, code, codeVerifier)
711
- const sanitized = sanitizeURL(cookieRedirectTo)
712
- if (!isValidRelativePath(sanitized)) {
713
- throw new AuthError(
714
- ERROR_RESPONSE.ACCESS_TOKEN.INVALID_REQUEST,
715
- "Invalid redirect path. Potential open redirect attack detected."
716
- )
717
- }
718
- const headers = new Headers(cacheControl)
719
- headers.set("Location", sanitized)
720
- const userInfo = await getUserInfo(oauthConfig, accessToken.access_token)
721
- const sessionCookie = await createSessionCookie(userInfo, cookieOptions, jose)
722
- const csrfToken = await createCSRF(jose)
723
- const csrfCookie = setCookie(
724
- "csrfToken",
725
- csrfToken,
726
- secureCookieOptions(
727
- request,
728
- {
729
- ...cookies,
730
- strategy: "host",
731
- },
732
- trustedProxyHeaders
733
- )
734
- )
735
- headers.set("Set-Cookie", sessionCookie)
736
- headers.append("Set-Cookie", expireCookie("state", cookieOptions))
737
- headers.append("Set-Cookie", expireCookie("redirect_uri", cookieOptions))
738
- headers.append("Set-Cookie", expireCookie("redirect_to", cookieOptions))
739
- headers.append("Set-Cookie", expireCookie("code_verifier", cookieOptions))
740
- headers.append("Set-Cookie", csrfCookie)
741
- return Response.json({ oauth: oauth2 }, { status: 302, headers })
742
- } catch (error) {
743
- if (isAuthError(error)) {
744
- const { type, message } = error
745
- return AuraResponse.json(
746
- { error: type, error_description: message },
747
- { status: import_router3.statusCode.BAD_REQUEST }
748
- )
749
- }
750
- return AuraResponse.json(
751
- {
752
- error: ERROR_RESPONSE.ACCESS_TOKEN.INVALID_CLIENT,
753
- error_description: "An unexpected error occurred",
754
- },
755
- { status: import_router3.statusCode.INTERNAL_SERVER_ERROR }
756
- )
757
- }
758
- },
759
- callbackConfig(oauth)
760
- )
761
- }
664
+ return (0, import_router3.createEndpoint)(
665
+ "GET",
666
+ "/callback/:oauth",
667
+ async (ctx) => {
668
+ const {
669
+ request,
670
+ params: { oauth: oauth2 },
671
+ searchParams: { code, state },
672
+ context: { oauth: providers, cookies, jose, trustedProxyHeaders }
673
+ } = ctx;
674
+ try {
675
+ const oauthConfig = providers[oauth2];
676
+ const cookieOptions = secureCookieOptions(request, cookies, trustedProxyHeaders);
677
+ const cookieState = getCookie(request, "state", cookieOptions);
678
+ const cookieRedirectTo = getCookie(request, "redirect_to", cookieOptions);
679
+ const cookieRedirectURI = getCookie(request, "redirect_uri", cookieOptions);
680
+ const codeVerifier = getCookie(request, "code_verifier", cookieOptions);
681
+ if (!equals(cookieState, state)) {
682
+ throw new AuthError(ERROR_RESPONSE.ACCESS_TOKEN.INVALID_REQUEST, "Mismatching state");
683
+ }
684
+ const accessToken = await createAccessToken(oauthConfig, cookieRedirectURI, code, codeVerifier);
685
+ const sanitized = sanitizeURL(cookieRedirectTo);
686
+ if (!isValidRelativePath(sanitized)) {
687
+ throw new AuthError(
688
+ ERROR_RESPONSE.ACCESS_TOKEN.INVALID_REQUEST,
689
+ "Invalid redirect path. Potential open redirect attack detected."
690
+ );
691
+ }
692
+ const headers = new Headers(cacheControl);
693
+ headers.set("Location", sanitized);
694
+ const userInfo = await getUserInfo(oauthConfig, accessToken.access_token);
695
+ const sessionCookie = await createSessionCookie(userInfo, cookieOptions, jose);
696
+ const csrfToken = await createCSRF(jose);
697
+ const csrfCookie = setCookie(
698
+ "csrfToken",
699
+ csrfToken,
700
+ secureCookieOptions(
701
+ request,
702
+ {
703
+ ...cookies,
704
+ strategy: "host"
705
+ },
706
+ trustedProxyHeaders
707
+ )
708
+ );
709
+ headers.set("Set-Cookie", sessionCookie);
710
+ headers.append("Set-Cookie", expireCookie("state", cookieOptions));
711
+ headers.append("Set-Cookie", expireCookie("redirect_uri", cookieOptions));
712
+ headers.append("Set-Cookie", expireCookie("redirect_to", cookieOptions));
713
+ headers.append("Set-Cookie", expireCookie("code_verifier", cookieOptions));
714
+ headers.append("Set-Cookie", csrfCookie);
715
+ return Response.json({ oauth: oauth2 }, { status: 302, headers });
716
+ } catch (error) {
717
+ if (isAuthError(error)) {
718
+ const { type, message } = error;
719
+ return AuraResponse.json(
720
+ { error: type, error_description: message },
721
+ { status: import_router3.statusCode.BAD_REQUEST }
722
+ );
723
+ }
724
+ return AuraResponse.json(
725
+ {
726
+ error: ERROR_RESPONSE.ACCESS_TOKEN.INVALID_CLIENT,
727
+ error_description: "An unexpected error occurred"
728
+ },
729
+ { status: import_router3.statusCode.INTERNAL_SERVER_ERROR }
730
+ );
731
+ }
732
+ },
733
+ callbackConfig(oauth)
734
+ );
735
+ };
762
736
 
763
737
  // src/actions/session/session.ts
764
- var import_router4 = require("@aura-stack/router")
738
+ var import_router4 = require("@aura-stack/router");
765
739
  var sessionAction = (0, import_router4.createEndpoint)("GET", "/session", async (ctx) => {
766
- const {
767
- request,
768
- context: { cookies, jose, trustedProxyHeaders },
769
- } = ctx
770
- const cookieOptions = secureCookieOptions(request, cookies, trustedProxyHeaders)
771
- try {
772
- const session = getCookie(request, "sessionToken", cookieOptions)
773
- const decoded = await jose.decodeJWT(session)
774
- const { exp, iat, jti, nbf, ...user } = decoded
775
- const headers = new Headers(cacheControl)
776
- return Response.json({ user, expires: toISOString(exp * 1e3) }, { headers })
777
- } catch {
778
- const headers = new Headers(cacheControl)
779
- const sessionCookie = expireCookie("sessionToken", cookieOptions)
780
- headers.set("Set-Cookie", sessionCookie)
781
- return Response.json({ authenticated: false, message: "Unauthorized" }, { status: 401, headers })
782
- }
783
- })
740
+ const {
741
+ request,
742
+ context: { cookies, jose, trustedProxyHeaders }
743
+ } = ctx;
744
+ const cookieOptions = secureCookieOptions(request, cookies, trustedProxyHeaders);
745
+ try {
746
+ const session = getCookie(request, "sessionToken", cookieOptions);
747
+ const decoded = await jose.decodeJWT(session);
748
+ const { exp, iat, jti, nbf, ...user } = decoded;
749
+ const headers = new Headers(cacheControl);
750
+ return Response.json({ user, expires: toISOString(exp * 1e3) }, { headers });
751
+ } catch {
752
+ const headers = new Headers(cacheControl);
753
+ const sessionCookie = expireCookie("sessionToken", cookieOptions);
754
+ headers.set("Set-Cookie", sessionCookie);
755
+ return Response.json({ authenticated: false, message: "Unauthorized" }, { status: 401, headers });
756
+ }
757
+ });
784
758
 
785
759
  // src/actions/signOut/signOut.ts
786
- var import_zod3 = __toESM(require("zod"), 1)
787
- var import_router5 = require("@aura-stack/router")
760
+ var import_zod3 = __toESM(require("zod"), 1);
761
+ var import_router5 = require("@aura-stack/router");
788
762
  var config = (0, import_router5.createEndpointConfig)({
789
- schemas: {
790
- searchParams: import_zod3.default.object({
791
- token_type_hint: import_zod3.default.literal("session_token"),
792
- redirectTo: import_zod3.default.string().optional(),
793
- }),
794
- },
795
- })
763
+ schemas: {
764
+ searchParams: import_zod3.default.object({
765
+ token_type_hint: import_zod3.default.literal("session_token"),
766
+ redirectTo: import_zod3.default.string().optional()
767
+ })
768
+ }
769
+ });
796
770
  var signOutAction = (0, import_router5.createEndpoint)(
797
- "POST",
798
- "/signOut",
799
- async (ctx) => {
800
- const {
801
- request,
802
- headers,
803
- searchParams: { redirectTo },
804
- context: { cookies, jose, trustedProxyHeaders },
805
- } = ctx
806
- try {
807
- const cookiesOptions = secureCookieOptions(request, cookies, trustedProxyHeaders)
808
- const session = getCookie(request, "sessionToken", cookiesOptions)
809
- const csrfToken = getCookie(request, "csrfToken", {
810
- ...cookiesOptions,
811
- prefix: cookiesOptions.secure ? "__Host-" : "",
812
- })
813
- const header = headers.get("X-CSRF-Token")
814
- if (!header || !session || !csrfToken) {
815
- throw new Error("Missing CSRF token or session token")
816
- }
817
- await verifyCSRF(jose, csrfToken, header)
818
- await jose.decodeJWT(session)
819
- const normalizedOriginPath = getNormalizedOriginPath(request.url)
820
- const location = createRedirectTo(
821
- new Request(normalizedOriginPath, {
822
- headers,
823
- }),
824
- redirectTo
825
- )
826
- const responseHeaders = new Headers(cacheControl)
827
- responseHeaders.append("Set-Cookie", expireCookie("sessionToken", cookiesOptions))
828
- responseHeaders.append(
829
- "Set-Cookie",
830
- expireCookie("csrfToken", { ...cookiesOptions, prefix: cookiesOptions.secure ? "__Host-" : "" })
831
- )
832
- responseHeaders.append("Location", location)
833
- return Response.json(
834
- { message: "Signed out successfully" },
835
- { status: import_router5.statusCode.ACCEPTED, headers: responseHeaders }
836
- )
837
- } catch (error) {
838
- if (error instanceof InvalidCsrfTokenError) {
839
- return AuraResponse.json(
840
- {
841
- error: "invalid_csrf_token",
842
- error_description: "The provided CSRF token is invalid or has expired",
843
- },
844
- { status: import_router5.statusCode.UNAUTHORIZED }
845
- )
846
- }
847
- if (error instanceof InvalidRedirectToError) {
848
- const { type, message } = error
849
- return AuraResponse.json(
850
- {
851
- error: type,
852
- error_description: message,
853
- },
854
- { status: import_router5.statusCode.BAD_REQUEST }
855
- )
856
- }
857
- return AuraResponse.json(
858
- {
859
- error: "invalid_session_token",
860
- error_description: "The provided sessionToken is invalid or has already expired",
861
- },
862
- { status: import_router5.statusCode.UNAUTHORIZED }
863
- )
864
- }
865
- },
866
- config
867
- )
771
+ "POST",
772
+ "/signOut",
773
+ async (ctx) => {
774
+ const {
775
+ request,
776
+ headers,
777
+ searchParams: { redirectTo },
778
+ context: { cookies, jose, trustedProxyHeaders }
779
+ } = ctx;
780
+ try {
781
+ const cookiesOptions = secureCookieOptions(request, cookies, trustedProxyHeaders);
782
+ const session = getCookie(request, "sessionToken", cookiesOptions);
783
+ const csrfToken = getCookie(request, "csrfToken", {
784
+ ...cookiesOptions,
785
+ prefix: cookiesOptions.secure ? "__Host-" : ""
786
+ });
787
+ const header = headers.get("X-CSRF-Token");
788
+ if (!header || !session || !csrfToken) {
789
+ throw new Error("Missing CSRF token or session token");
790
+ }
791
+ await verifyCSRF(jose, csrfToken, header);
792
+ await jose.decodeJWT(session);
793
+ const normalizedOriginPath = getNormalizedOriginPath(request.url);
794
+ const location = createRedirectTo(
795
+ new Request(normalizedOriginPath, {
796
+ headers
797
+ }),
798
+ redirectTo
799
+ );
800
+ const responseHeaders = new Headers(cacheControl);
801
+ responseHeaders.append("Set-Cookie", expireCookie("sessionToken", cookiesOptions));
802
+ responseHeaders.append(
803
+ "Set-Cookie",
804
+ expireCookie("csrfToken", { ...cookiesOptions, prefix: cookiesOptions.secure ? "__Host-" : "" })
805
+ );
806
+ responseHeaders.append("Location", location);
807
+ return Response.json(
808
+ { message: "Signed out successfully" },
809
+ { status: import_router5.statusCode.ACCEPTED, headers: responseHeaders }
810
+ );
811
+ } catch (error) {
812
+ if (error instanceof InvalidCsrfTokenError) {
813
+ return AuraResponse.json(
814
+ {
815
+ error: "invalid_csrf_token",
816
+ error_description: "The provided CSRF token is invalid or has expired"
817
+ },
818
+ { status: import_router5.statusCode.UNAUTHORIZED }
819
+ );
820
+ }
821
+ if (error instanceof InvalidRedirectToError) {
822
+ const { type, message } = error;
823
+ return AuraResponse.json(
824
+ {
825
+ error: type,
826
+ error_description: message
827
+ },
828
+ { status: import_router5.statusCode.BAD_REQUEST }
829
+ );
830
+ }
831
+ return AuraResponse.json(
832
+ {
833
+ error: "invalid_session_token",
834
+ error_description: "The provided sessionToken is invalid or has already expired"
835
+ },
836
+ { status: import_router5.statusCode.UNAUTHORIZED }
837
+ );
838
+ }
839
+ },
840
+ config
841
+ );
868
842
 
869
843
  // src/actions/csrfToken/csrfToken.ts
870
- var import_router6 = require("@aura-stack/router")
844
+ var import_router6 = require("@aura-stack/router");
871
845
  var csrfTokenAction = (0, import_router6.createEndpoint)("GET", "/csrfToken", async (ctx) => {
872
- const {
873
- request,
874
- context: { cookies, jose, trustedProxyHeaders },
875
- } = ctx
876
- const cookieOptions = secureCookieOptions(request, { ...cookies, strategy: "host" }, trustedProxyHeaders)
877
- const existingCSRFToken = getCookie(request, "csrfToken", cookieOptions, true)
878
- const csrfToken = await createCSRF(jose, existingCSRFToken)
879
- const headers = new Headers(cacheControl)
880
- headers.set("Set-Cookie", setCookie("csrfToken", csrfToken, cookieOptions))
881
- return Response.json({ csrfToken }, { headers })
882
- })
846
+ const {
847
+ request,
848
+ context: { cookies, jose, trustedProxyHeaders }
849
+ } = ctx;
850
+ const cookieOptions = secureCookieOptions(request, { ...cookies, strategy: "host" }, trustedProxyHeaders);
851
+ const existingCSRFToken = getCookie(request, "csrfToken", cookieOptions, true);
852
+ const csrfToken = await createCSRF(jose, existingCSRFToken);
853
+ const headers = new Headers(cacheControl);
854
+ headers.set("Set-Cookie", setCookie("csrfToken", csrfToken, cookieOptions));
855
+ return Response.json({ csrfToken }, { headers });
856
+ });
883
857
  // Annotate the CommonJS export names for ESM import in node:
884
- 0 &&
885
- (module.exports = {
886
- callbackAction,
887
- csrfTokenAction,
888
- sessionAction,
889
- signInAction,
890
- signOutAction,
891
- })
858
+ 0 && (module.exports = {
859
+ callbackAction,
860
+ csrfTokenAction,
861
+ sessionAction,
862
+ signInAction,
863
+ signOutAction
864
+ });