@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.
Files changed (149) hide show
  1. package/dist/@types/index.d.ts +6 -2
  2. package/dist/@types/router.d.d.ts +6 -2
  3. package/dist/actions/callback/access-token.cjs +103 -59
  4. package/dist/actions/callback/access-token.d.ts +7 -3
  5. package/dist/actions/callback/access-token.js +3 -3
  6. package/dist/actions/callback/callback.cjs +200 -134
  7. package/dist/actions/callback/callback.d.ts +32 -3
  8. package/dist/actions/callback/callback.js +11 -12
  9. package/dist/actions/callback/userinfo.cjs +103 -70
  10. package/dist/actions/callback/userinfo.d.ts +6 -2
  11. package/dist/actions/callback/userinfo.js +7 -8
  12. package/dist/actions/csrfToken/csrfToken.cjs +7 -15
  13. package/dist/actions/csrfToken/csrfToken.d.ts +3 -1
  14. package/dist/actions/csrfToken/csrfToken.js +7 -8
  15. package/dist/actions/index.cjs +502 -295
  16. package/dist/actions/index.d.ts +5 -2
  17. package/dist/actions/index.js +23 -20
  18. package/dist/actions/session/session.cjs +76 -24
  19. package/dist/actions/session/session.d.ts +3 -1
  20. package/dist/actions/session/session.js +6 -4
  21. package/dist/actions/signIn/authorization-url.cjs +288 -0
  22. package/dist/actions/signIn/authorization-url.d.ts +31 -0
  23. package/dist/actions/signIn/authorization-url.js +16 -0
  24. package/dist/actions/signIn/authorization.cjs +91 -132
  25. package/dist/actions/signIn/authorization.d.ts +17 -16
  26. package/dist/actions/signIn/authorization.js +8 -7
  27. package/dist/actions/signIn/signIn.cjs +319 -191
  28. package/dist/actions/signIn/signIn.d.ts +32 -3
  29. package/dist/actions/signIn/signIn.js +10 -9
  30. package/dist/actions/signOut/signOut.cjs +211 -212
  31. package/dist/actions/signOut/signOut.d.ts +9 -1
  32. package/dist/actions/signOut/signOut.js +9 -10
  33. package/dist/api/createApi.cjs +750 -0
  34. package/dist/api/createApi.d.ts +12 -0
  35. package/dist/api/createApi.js +19 -0
  36. package/dist/api/getSession.cjs +141 -0
  37. package/dist/api/getSession.d.ts +16 -0
  38. package/dist/api/getSession.js +10 -0
  39. package/dist/api/signIn.cjs +549 -0
  40. package/dist/api/signIn.d.ts +26 -0
  41. package/dist/api/signIn.js +15 -0
  42. package/dist/api/signOut.cjs +279 -0
  43. package/dist/api/signOut.d.ts +16 -0
  44. package/dist/api/signOut.js +13 -0
  45. package/dist/assert.cjs +42 -9
  46. package/dist/assert.d.ts +8 -4
  47. package/dist/assert.js +5 -5
  48. package/dist/{chunk-KJBAQZX2.js → chunk-2A5B7GWR.js} +44 -11
  49. package/dist/chunk-2GQLSIJ2.js +40 -0
  50. package/dist/chunk-2IR674WX.js +44 -0
  51. package/dist/chunk-3J5TUH2I.js +50 -0
  52. package/dist/chunk-4RWSYUKX.js +98 -0
  53. package/dist/chunk-5X7JZMEF.js +0 -0
  54. package/dist/{chunk-TZB6MUXN.js → chunk-7BE46WWS.js} +21 -11
  55. package/dist/chunk-7YYXFKLR.js +35 -0
  56. package/dist/chunk-C3A37LQC.js +33 -0
  57. package/dist/chunk-CITNGXDA.js +31 -0
  58. package/dist/chunk-CWX724AG.js +78 -0
  59. package/dist/chunk-D2CSIUKP.js +74 -0
  60. package/dist/{chunk-ICAZ4OVS.js → chunk-FPCVZUVG.js} +2 -2
  61. package/dist/{chunk-XGLBNXL4.js → chunk-GNNBM2WJ.js} +17 -9
  62. package/dist/chunk-JOCGX3RP.js +59 -0
  63. package/dist/chunk-KBXWTD6E.js +94 -0
  64. package/dist/{chunk-XUP6KKNG.js → chunk-LATR3NIV.js} +48 -37
  65. package/dist/chunk-LAYPUDQF.js +39 -0
  66. package/dist/chunk-LX3TJ2TJ.js +294 -0
  67. package/dist/{chunk-6MXFPFR3.js → chunk-NHZBQNRR.js} +19 -19
  68. package/dist/{chunk-TM5IPSNF.js → chunk-PDP3PHB3.js} +33 -19
  69. package/dist/chunk-PHYNROD4.js +47 -0
  70. package/dist/chunk-QQEKY4XP.js +29 -0
  71. package/dist/{chunk-VNCNJKS2.js → chunk-U4RK4LKJ.js} +82 -1
  72. package/dist/{chunk-RRLIF4PQ.js → chunk-U5663F2U.js} +16 -1
  73. package/dist/chunk-UN7X6SU5.js +53 -0
  74. package/dist/chunk-UZQJJD6A.js +100 -0
  75. package/dist/{chunk-NUDITUKX.js → chunk-V6LLEAR4.js} +22 -15
  76. package/dist/{chunk-4MYWAOLG.js → chunk-WHNDRO3N.js} +20 -1
  77. package/dist/{chunk-5W4BRQYG.js → chunk-XY5R3EHH.js} +6 -3
  78. package/dist/client/client.cjs +135 -0
  79. package/dist/client/client.d.ts +85 -0
  80. package/dist/client/client.js +9 -0
  81. package/dist/client/index.cjs +135 -0
  82. package/dist/client/index.d.ts +14 -0
  83. package/dist/client/index.js +10 -0
  84. package/dist/context.cjs +1237 -0
  85. package/dist/context.d.ts +16 -0
  86. package/dist/context.js +28 -0
  87. package/dist/cookie.cjs +33 -2
  88. package/dist/cookie.d.ts +9 -5
  89. package/dist/cookie.js +3 -2
  90. package/dist/createAuth.cjs +2320 -0
  91. package/dist/createAuth.d.ts +12 -0
  92. package/dist/createAuth.js +48 -0
  93. package/dist/env.cjs +24 -2
  94. package/dist/env.d.ts +4 -1
  95. package/dist/env.js +9 -3
  96. package/dist/errors.cjs +17 -0
  97. package/dist/errors.d.ts +13 -3
  98. package/dist/errors.js +5 -1
  99. package/dist/{index-CSyIJmCM.d.ts → index-_aXtxb_s.d.ts} +383 -13
  100. package/dist/index.cjs +2135 -1547
  101. package/dist/index.d.ts +9 -30
  102. package/dist/index.js +46 -119
  103. package/dist/jose.cjs +52 -14
  104. package/dist/jose.d.ts +12 -25
  105. package/dist/jose.js +11 -3
  106. package/dist/logger.cjs +132 -0
  107. package/dist/logger.d.ts +6 -2
  108. package/dist/logger.js +10 -1
  109. package/dist/oauth/atlassian.cjs +57 -0
  110. package/dist/oauth/atlassian.d.ts +12 -0
  111. package/dist/oauth/atlassian.js +6 -0
  112. package/dist/oauth/bitbucket.d.ts +6 -2
  113. package/dist/oauth/discord.d.ts +6 -2
  114. package/dist/oauth/dropbox.cjs +53 -0
  115. package/dist/oauth/dropbox.d.ts +12 -0
  116. package/dist/oauth/dropbox.js +6 -0
  117. package/dist/oauth/figma.d.ts +6 -2
  118. package/dist/oauth/github.d.ts +6 -2
  119. package/dist/oauth/gitlab.d.ts +6 -2
  120. package/dist/oauth/index.cjs +278 -88
  121. package/dist/oauth/index.d.ts +6 -2
  122. package/dist/oauth/index.js +27 -11
  123. package/dist/oauth/mailchimp.d.ts +6 -2
  124. package/dist/oauth/notion.cjs +131 -0
  125. package/dist/oauth/notion.d.ts +12 -0
  126. package/dist/oauth/notion.js +9 -0
  127. package/dist/oauth/pinterest.d.ts +6 -2
  128. package/dist/oauth/spotify.d.ts +6 -2
  129. package/dist/oauth/strava.d.ts +6 -2
  130. package/dist/oauth/twitch.cjs +95 -0
  131. package/dist/oauth/twitch.d.ts +12 -0
  132. package/dist/oauth/twitch.js +7 -0
  133. package/dist/oauth/x.d.ts +6 -2
  134. package/dist/schemas.cjs +84 -51
  135. package/dist/schemas.d.ts +103 -23
  136. package/dist/schemas.js +1 -1
  137. package/dist/secure.cjs +36 -36
  138. package/dist/secure.d.ts +10 -4
  139. package/dist/secure.js +7 -6
  140. package/dist/utils.cjs +109 -3
  141. package/dist/utils.d.ts +15 -4
  142. package/dist/utils.js +11 -4
  143. package/package.json +9 -5
  144. package/dist/chunk-4EKY7655.js +0 -123
  145. package/dist/chunk-7QF22LHP.js +0 -67
  146. package/dist/chunk-ALG3GIV4.js +0 -95
  147. package/dist/chunk-FRJFWTOY.js +0 -70
  148. package/dist/chunk-PHFH2MGS.js +0 -36
  149. package/dist/chunk-QQVSRXGX.js +0 -149
@@ -1,9 +1,7 @@
1
1
  "use strict";
2
- var __create = Object.create;
3
2
  var __defProp = Object.defineProperty;
4
3
  var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
5
4
  var __getOwnPropNames = Object.getOwnPropertyNames;
6
- var __getProtoOf = Object.getPrototypeOf;
7
5
  var __hasOwnProp = Object.prototype.hasOwnProperty;
8
6
  var __export = (target, all) => {
9
7
  for (var name in all)
@@ -17,14 +15,6 @@ var __copyProps = (to, from, except, desc) => {
17
15
  }
18
16
  return to;
19
17
  };
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
18
  var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
29
19
 
30
20
  // src/actions/index.ts
@@ -39,8 +29,7 @@ __export(actions_exports, {
39
29
  module.exports = __toCommonJS(actions_exports);
40
30
 
41
31
  // src/actions/signIn/signIn.ts
42
- var import_zod2 = require("zod");
43
- var import_router2 = require("@aura-stack/router");
32
+ var import_v42 = require("zod/v4");
44
33
 
45
34
  // src/headers.ts
46
35
  var cacheControl = {
@@ -70,12 +59,6 @@ var secureApiHeaders = {
70
59
  ...secureHeaders
71
60
  };
72
61
 
73
- // src/secure.ts
74
- var import_crypto2 = __toESM(require("crypto"), 1);
75
-
76
- // src/utils.ts
77
- var import_router = require("@aura-stack/router");
78
-
79
62
  // src/errors.ts
80
63
  var OAuthProtocolError = class extends Error {
81
64
  type = "OAUTH_PROTOCOL_ERROR";
@@ -116,44 +99,160 @@ var isOAuthProtocolError = (error) => {
116
99
  return error instanceof OAuthProtocolError;
117
100
  };
118
101
 
102
+ // src/api/signIn.ts
103
+ var import_router2 = require("@aura-stack/router");
104
+
105
+ // src/schemas.ts
106
+ var import_v4 = require("zod/v4");
107
+ var AuthorizeConfigSchema = import_v4.z.union([
108
+ (0, import_v4.string)().url(),
109
+ (0, import_v4.object)({
110
+ url: (0, import_v4.string)().url(),
111
+ params: (0, import_v4.object)({
112
+ responseType: (0, import_v4.enum)(["code", "token", "id_token", "refresh_token"]).optional(),
113
+ scope: (0, import_v4.string)().optional()
114
+ })
115
+ })
116
+ ]);
117
+ var AccessTokenConfigSchema = import_v4.z.union([
118
+ (0, import_v4.string)().url(),
119
+ (0, import_v4.object)({
120
+ url: (0, import_v4.string)().url(),
121
+ headers: import_v4.z.record((0, import_v4.string)(), (0, import_v4.string)()).optional()
122
+ })
123
+ ]);
124
+ var UserInfoConfigSchema = import_v4.z.union([
125
+ (0, import_v4.string)().url(),
126
+ (0, import_v4.object)({
127
+ url: (0, import_v4.string)().url(),
128
+ headers: import_v4.z.record((0, import_v4.string)(), (0, import_v4.string)()).optional(),
129
+ method: (0, import_v4.string)().optional()
130
+ })
131
+ ]);
132
+ var OAuthProviderCredentialsSchema = (0, import_v4.object)({
133
+ id: (0, import_v4.string)(),
134
+ name: (0, import_v4.string)(),
135
+ authorize: AuthorizeConfigSchema.optional(),
136
+ /** @deprecated */
137
+ authorizeURL: (0, import_v4.string)().url().optional(),
138
+ accessToken: AccessTokenConfigSchema,
139
+ /** @deprecated */
140
+ scope: (0, import_v4.string)().optional(),
141
+ userInfo: UserInfoConfigSchema,
142
+ /** @deprecated */
143
+ responseType: (0, import_v4.enum)(["code", "token", "id_token", "refresh_token"]).optional(),
144
+ clientId: (0, import_v4.string)(),
145
+ clientSecret: (0, import_v4.string)(),
146
+ profile: import_v4.z.function().optional()
147
+ });
148
+ var OAuthProviderConfigSchema = (0, import_v4.object)({
149
+ authorize: AuthorizeConfigSchema.optional(),
150
+ /** @deprecated */
151
+ authorizeURL: (0, import_v4.string)().url().optional(),
152
+ accessToken: AccessTokenConfigSchema,
153
+ /** @deprecated */
154
+ scope: (0, import_v4.string)().optional(),
155
+ userInfo: UserInfoConfigSchema,
156
+ /** @deprecated */
157
+ responseType: (0, import_v4.enum)(["code", "token", "id_token", "refresh_token"]).optional(),
158
+ clientId: (0, import_v4.string)(),
159
+ clientSecret: (0, import_v4.string)()
160
+ });
161
+ var OAuthAuthorization = OAuthProviderConfigSchema.extend({
162
+ redirectURI: (0, import_v4.string)(),
163
+ state: (0, import_v4.string)(),
164
+ codeChallenge: (0, import_v4.string)(),
165
+ codeChallengeMethod: (0, import_v4.enum)(["plain", "S256"])
166
+ });
167
+ var OAuthAuthorizationResponse = (0, import_v4.object)({
168
+ state: (0, import_v4.string)({ message: "Missing state parameter in the OAuth authorization response." }),
169
+ code: (0, import_v4.string)({ message: "Missing code parameter in the OAuth authorization response." })
170
+ });
171
+ var OAuthAuthorizationErrorResponse = (0, import_v4.object)({
172
+ error: (0, import_v4.enum)([
173
+ "invalid_request",
174
+ "unauthorized_client",
175
+ "access_denied",
176
+ "unsupported_response_type",
177
+ "invalid_scope",
178
+ "server_error",
179
+ "temporarily_unavailable"
180
+ ]),
181
+ error_description: (0, import_v4.string)().optional(),
182
+ error_uri: (0, import_v4.string)().optional(),
183
+ state: (0, import_v4.string)()
184
+ });
185
+ var OAuthAccessToken = OAuthProviderConfigSchema.extend({
186
+ redirectURI: (0, import_v4.string)(),
187
+ code: (0, import_v4.string)(),
188
+ codeVerifier: (0, import_v4.string)().min(43).max(128)
189
+ });
190
+ var OAuthAccessTokenResponse = (0, import_v4.object)({
191
+ access_token: (0, import_v4.string)(),
192
+ token_type: (0, import_v4.string)().optional(),
193
+ expires_in: (0, import_v4.number)().optional(),
194
+ refresh_token: (0, import_v4.string)().optional(),
195
+ scope: (0, import_v4.union)([(0, import_v4.string)().optional().or((0, import_v4.null)()), (0, import_v4.array)((0, import_v4.string)()).optional()])
196
+ });
197
+ var OAuthAccessTokenErrorResponse = (0, import_v4.object)({
198
+ error: (0, import_v4.enum)([
199
+ "invalid_request",
200
+ "invalid_client",
201
+ "invalid_grant",
202
+ "unauthorized_client",
203
+ "unsupported_grant_type",
204
+ "invalid_scope"
205
+ ]),
206
+ error_description: (0, import_v4.string)().optional(),
207
+ error_uri: (0, import_v4.string)().optional()
208
+ });
209
+ var OAuthErrorResponse = (0, import_v4.object)({
210
+ error: (0, import_v4.string)(),
211
+ error_description: (0, import_v4.string)().optional()
212
+ });
213
+ var OAuthEnvSchema = (0, import_v4.object)({
214
+ clientId: import_v4.z.string().min(1, "OAuth Client ID is required in the environment variables."),
215
+ clientSecret: import_v4.z.string().min(1, "OAuth Client Secret is required in the environment variables.")
216
+ });
217
+
119
218
  // src/utils.ts
120
- var toSnakeCase = (str) => {
121
- return str.replace(/([a-z0-9])([A-Z])/g, "$1_$2").replace(/([A-Z]+)([A-Z][a-z])/g, "$1_$2").toLowerCase().replace(/^_+/, "");
122
- };
123
- var toUpperCase = (str) => {
124
- return str.toUpperCase();
125
- };
126
- var toCastCase = (obj, type = "snake") => {
127
- return Object.entries(obj).reduce((previous, [key, value]) => {
128
- const newKey = type === "snake" ? toSnakeCase(key) : toUpperCase(key);
129
- return { ...previous, [newKey]: value };
130
- }, {});
131
- };
132
- var equals = (a, b) => {
133
- if (a === null || b === null || a === void 0 || b === void 0) return false;
134
- return a === b;
135
- };
136
- var getBaseURL = (request) => {
137
- const url = new URL(request.url);
138
- return `${url.origin}${url.pathname}`;
139
- };
140
- var toISOString = (date) => {
141
- return new Date(date).toISOString();
142
- };
143
- var extractPath = (url) => {
144
- const pathRegex = /^https?:\/\/[a-zA-Z0-9_\-\.]+(:\d+)?(\/.*)$/;
145
- const match = url.match(pathRegex);
146
- return match && match[2] ? match[2] : "/";
147
- };
148
- var getErrorName = (error) => {
149
- if (error instanceof Error) {
150
- return error.name;
219
+ var import_router = require("@aura-stack/router");
220
+
221
+ // src/env.ts
222
+ var import_meta = {};
223
+ var env = new Proxy({}, {
224
+ get(_, prop) {
225
+ if (typeof prop !== "string") return void 0;
226
+ const hasProperty = (process2) => {
227
+ return process2 && Object.prototype.hasOwnProperty.call(process2, prop);
228
+ };
229
+ try {
230
+ if (typeof process !== "undefined" && hasProperty(process.env)) {
231
+ return process.env[prop];
232
+ }
233
+ if (typeof import_meta !== "undefined" && hasProperty(import_meta.env)) {
234
+ return import_meta.env[prop];
235
+ }
236
+ if (typeof Deno !== "undefined" && Deno.env?.get) {
237
+ return Deno.env.get(prop);
238
+ }
239
+ if (typeof Bun !== "undefined" && hasProperty(Bun.env)) {
240
+ return Bun.env[prop];
241
+ }
242
+ const globalValue = globalThis[prop];
243
+ return typeof globalValue === "string" ? globalValue : void 0;
244
+ } catch {
245
+ return void 0;
246
+ }
151
247
  }
152
- return typeof error === "string" ? error : "UnknownError";
248
+ });
249
+ var getEnv = (key) => {
250
+ const keys = [`AURA_AUTH_${key.toUpperCase()}`, `AURA_${key.toUpperCase()}`, `AUTH_${key.toUpperCase()}`, key.toUpperCase()];
251
+ return env[keys.find((k) => env[k]) ?? ""];
153
252
  };
154
253
 
155
254
  // src/assert.ts
156
- var import_crypto = require("crypto");
255
+ var import_crypto = require("@aura-stack/jose/crypto");
157
256
  var unsafeChars = [
158
257
  "<",
159
258
  ">",
@@ -244,46 +343,46 @@ var isTrustedOrigin = (url, trustedOrigins) => {
244
343
  }
245
344
  return false;
246
345
  };
247
- var safeEquals = (a, b) => {
248
- const bufferA = Buffer.from(a);
249
- const bufferB = Buffer.from(b);
250
- if (bufferA.length !== bufferB.length) {
251
- return false;
346
+ var timingSafeEqual = (a, b) => {
347
+ const bufferA = import_crypto.encoder.encode(a);
348
+ const bufferB = import_crypto.encoder.encode(b);
349
+ const len = Math.max(bufferA.length, bufferB.length);
350
+ let diff = 0;
351
+ for (let i = 0; i < len; i++) {
352
+ diff |= (bufferA[i] ?? 0) ^ (bufferB[i] ?? 0);
252
353
  }
253
- return (0, import_crypto.timingSafeEqual)(bufferA, bufferB);
354
+ return diff === 0 && bufferA.length === bufferB.length;
254
355
  };
255
356
 
256
- // src/env.ts
257
- var import_meta = {};
258
- var env = new Proxy({}, {
259
- get(_, prop) {
260
- if (typeof prop !== "string") return void 0;
261
- const hasProperty = (process2) => {
262
- return process2 && Object.prototype.hasOwnProperty.call(process2, prop);
263
- };
264
- try {
265
- if (typeof process !== "undefined" && hasProperty(process.env)) {
266
- return process.env[prop];
267
- }
268
- if (typeof import_meta !== "undefined" && hasProperty(import_meta.env)) {
269
- return import_meta.env[prop];
270
- }
271
- if (typeof Deno !== "undefined" && Deno.env?.get) {
272
- return Deno.env.get(prop);
273
- }
274
- if (typeof Bun !== "undefined" && hasProperty(Bun.env)) {
275
- return Bun.env[prop];
276
- }
277
- const globalValue = globalThis[prop];
278
- return typeof globalValue === "string" ? globalValue : void 0;
279
- } catch {
280
- return void 0;
281
- }
357
+ // src/utils.ts
358
+ var AURA_AUTH_VERSION = "0.4.0";
359
+ var equals = (a, b) => {
360
+ if (a === null || b === null || a === void 0 || b === void 0) return false;
361
+ return a === b;
362
+ };
363
+ var getBaseURL = (request) => {
364
+ const url = new URL(request.url);
365
+ return `${url.origin}${url.pathname}`;
366
+ };
367
+ var toISOString = (date) => {
368
+ return new Date(date).toISOString();
369
+ };
370
+ var extractPath = (url) => {
371
+ const pathRegex = /^https?:\/\/[a-zA-Z0-9_\-\.]+(:\d+)?(\/.*)$/;
372
+ const match = url.match(pathRegex);
373
+ return match && match[2] ? match[2] : "/";
374
+ };
375
+ var getErrorName = (error) => {
376
+ if (error instanceof Error) {
377
+ return error.name;
282
378
  }
283
- });
379
+ return typeof error === "string" ? error : "UnknownError";
380
+ };
284
381
 
285
382
  // src/jose.ts
286
383
  var import_jose = require("@aura-stack/jose");
384
+ var import_jose2 = require("@aura-stack/jose/jose");
385
+ var import_crypto2 = require("@aura-stack/jose/crypto");
287
386
  var jwtVerificationOptions = {
288
387
  algorithms: ["HS256"],
289
388
  typ: "JWT"
@@ -291,10 +390,15 @@ var jwtVerificationOptions = {
291
390
 
292
391
  // src/secure.ts
293
392
  var generateSecure = (length = 32) => {
294
- return import_crypto2.default.randomBytes(length).toString("base64url");
393
+ return import_jose2.base64url.encode((0, import_crypto2.getRandomBytes)(length));
394
+ };
395
+ var createSecretValue = (length = 32) => {
396
+ return import_jose2.base64url.encode((0, import_crypto2.getRandomBytes)(length));
295
397
  };
296
- var createHash = (data, base = "hex") => {
297
- return import_crypto2.default.createHash("sha256").update(data).digest().toString(base);
398
+ var createHash = async (data) => {
399
+ const subtle = (0, import_crypto2.getSubtleCrypto)();
400
+ const digest = await subtle.digest("SHA-256", import_crypto2.encoder.encode(data));
401
+ return import_jose2.base64url.encode(new Uint8Array(digest));
298
402
  };
299
403
  var createPKCE = async (verifier) => {
300
404
  const byteLength = verifier ? void 0 : Math.floor(Math.random() * (96 - 32 + 1) + 32);
@@ -302,7 +406,7 @@ var createPKCE = async (verifier) => {
302
406
  if (codeVerifier.length < 43 || codeVerifier.length > 128) {
303
407
  throw new AuthSecurityError("PKCE_VERIFIER_INVALID", "The code verifier must be between 43 and 128 characters in length.");
304
408
  }
305
- const codeChallenge = createHash(codeVerifier, "base64url");
409
+ const codeChallenge = await createHash(codeVerifier);
306
410
  return { codeVerifier, codeChallenge, method: "S256" };
307
411
  };
308
412
  var createCSRF = async (jose, csrfCookie) => {
@@ -331,7 +435,7 @@ var verifyCSRF = async (jose, cookie, header) => {
331
435
  if (!equals(cookiePayload.token.length, headerPayload.token.length)) {
332
436
  throw new AuthSecurityError("CSRF_TOKEN_INVALID", "The CSRF tokens do not match.");
333
437
  }
334
- if (!safeEquals(cookiePayload.token, headerPayload.token)) {
438
+ if (!timingSafeEqual(cookiePayload.token, headerPayload.token)) {
335
439
  throw new AuthSecurityError("CSRF_TOKEN_INVALID", "The CSRF tokens do not match.");
336
440
  }
337
441
  return true;
@@ -340,121 +444,101 @@ var verifyCSRF = async (jose, cookie, header) => {
340
444
  }
341
445
  };
342
446
 
343
- // src/schemas.ts
344
- var import_zod = require("zod");
345
- var OAuthProviderCredentialsSchema = (0, import_zod.object)({
346
- id: (0, import_zod.string)(),
347
- name: (0, import_zod.string)(),
348
- authorizeURL: (0, import_zod.string)().url(),
349
- accessToken: (0, import_zod.string)().url(),
350
- scope: (0, import_zod.string)(),
351
- userInfo: (0, import_zod.string)().url(),
352
- responseType: (0, import_zod.enum)(["code", "token", "id_token"]),
353
- clientId: (0, import_zod.string)(),
354
- clientSecret: (0, import_zod.string)(),
355
- profile: import_zod.z.function().optional()
356
- });
357
- var OAuthProviderConfigSchema = (0, import_zod.object)({
358
- authorizeURL: (0, import_zod.string)().url(),
359
- accessToken: (0, import_zod.string)().url(),
360
- scope: (0, import_zod.string)().optional(),
361
- userInfo: (0, import_zod.string)().url(),
362
- responseType: (0, import_zod.enum)(["code", "token", "id_token"]),
363
- clientId: (0, import_zod.string)(),
364
- clientSecret: (0, import_zod.string)()
365
- });
366
- var OAuthAuthorization = OAuthProviderConfigSchema.extend({
367
- redirectURI: (0, import_zod.string)(),
368
- state: (0, import_zod.string)(),
369
- codeChallenge: (0, import_zod.string)(),
370
- codeChallengeMethod: (0, import_zod.enum)(["plain", "S256"])
371
- });
372
- var OAuthAuthorizationResponse = (0, import_zod.object)({
373
- state: (0, import_zod.string)({ message: "Missing state parameter in the OAuth authorization response." }),
374
- code: (0, import_zod.string)({ message: "Missing code parameter in the OAuth authorization response." })
375
- });
376
- var OAuthAuthorizationErrorResponse = (0, import_zod.object)({
377
- error: (0, import_zod.enum)([
378
- "invalid_request",
379
- "unauthorized_client",
380
- "access_denied",
381
- "unsupported_response_type",
382
- "invalid_scope",
383
- "server_error",
384
- "temporarily_unavailable"
385
- ]),
386
- error_description: (0, import_zod.string)().optional(),
387
- error_uri: (0, import_zod.string)().optional(),
388
- state: (0, import_zod.string)()
389
- });
390
- var OAuthAccessToken = OAuthProviderConfigSchema.extend({
391
- redirectURI: (0, import_zod.string)(),
392
- code: (0, import_zod.string)(),
393
- codeVerifier: (0, import_zod.string)().min(43).max(128)
394
- });
395
- var OAuthAccessTokenResponse = (0, import_zod.object)({
396
- access_token: (0, import_zod.string)(),
397
- token_type: (0, import_zod.string)().optional(),
398
- expires_in: (0, import_zod.number)().optional(),
399
- refresh_token: (0, import_zod.string)().optional(),
400
- scope: (0, import_zod.string)().optional().or((0, import_zod.null)())
401
- });
402
- var OAuthAccessTokenErrorResponse = (0, import_zod.object)({
403
- error: (0, import_zod.enum)([
404
- "invalid_request",
405
- "invalid_client",
406
- "invalid_grant",
407
- "unauthorized_client",
408
- "unsupported_grant_type",
409
- "invalid_scope"
410
- ]),
411
- error_description: (0, import_zod.string)().optional(),
412
- error_uri: (0, import_zod.string)().optional()
413
- });
414
- var OAuthErrorResponse = (0, import_zod.object)({
415
- error: (0, import_zod.string)(),
416
- error_description: (0, import_zod.string)().optional()
417
- });
418
- var OAuthEnvSchema = (0, import_zod.object)({
419
- clientId: import_zod.z.string().min(1, "OAuth Client ID is required in the environment variables."),
420
- clientSecret: import_zod.z.string().min(1, "OAuth Client Secret is required in the environment variables.")
421
- });
422
-
423
- // src/actions/signIn/authorization.ts
424
- var createAuthorizationURL = (oauthConfig, redirectURI, state, codeChallenge, codeChallengeMethod, logger) => {
425
- const parsed = OAuthAuthorization.safeParse({ ...oauthConfig, redirectURI, state, codeChallenge, codeChallengeMethod });
447
+ // src/actions/signIn/authorization-url.ts
448
+ var setSearchParams = (url, params) => {
449
+ for (const [key, value] of Object.entries(params)) {
450
+ if (value !== void 0 && value !== "") {
451
+ url.searchParams.set(key, value);
452
+ }
453
+ }
454
+ };
455
+ var buildAuthorizationURL = (oauth, redirect_uri, state, code_challenge, code_challenge_method) => {
456
+ const authorizeConfig = oauth.authorize;
457
+ const baseURL = typeof authorizeConfig === "string" ? authorizeConfig : authorizeConfig?.url ?? oauth.authorizeURL;
458
+ if (!baseURL) {
459
+ throw new AuthInternalError("INVALID_OAUTH_CONFIGURATION", "Missing authorization URL in OAuth provider configuration.");
460
+ }
461
+ const url = new URL(baseURL);
462
+ const authorizeParams = typeof authorizeConfig === "string" ? void 0 : authorizeConfig?.params;
463
+ setSearchParams(url, {
464
+ response_type: authorizeParams?.responseType ?? oauth.responseType ?? "code",
465
+ client_id: oauth.clientId,
466
+ redirect_uri,
467
+ state,
468
+ code_challenge,
469
+ code_challenge_method,
470
+ scope: authorizeParams?.scope ?? oauth.scope,
471
+ prompt: authorizeParams?.prompt,
472
+ response_mode: authorizeParams?.responseMode,
473
+ login_hint: authorizeParams?.loginHint,
474
+ nonce: authorizeParams?.nonce,
475
+ display: authorizeParams?.display,
476
+ audience: authorizeParams?.audience
477
+ });
478
+ return url.toString();
479
+ };
480
+ var createAuthorizationURL = async (oauth, redirectURI, ctx) => {
481
+ const state = createSecretValue();
482
+ const { codeVerifier, codeChallenge, method } = await createPKCE();
483
+ const authorization = buildAuthorizationURL(oauth, redirectURI, state, codeChallenge, method);
484
+ const parsed = OAuthAuthorization.safeParse({ ...oauth, redirectURI, state, codeChallenge, codeChallengeMethod: method });
426
485
  if (!parsed.success) {
427
- logger?.log("INVALID_OAUTH_CONFIGURATION", {
486
+ ctx?.logger?.log("INVALID_OAUTH_CONFIGURATION", {
428
487
  structuredData: {
429
- scope: oauthConfig.scope,
488
+ scope: oauth?.scope ?? "",
430
489
  redirect_uri: redirectURI,
431
490
  has_state: Boolean(state),
432
491
  has_code_challenge: Boolean(codeChallenge),
433
- code_challenge_method: codeChallengeMethod
492
+ code_challenge_method: method
434
493
  }
435
494
  });
436
495
  throw new AuthInternalError("INVALID_OAUTH_CONFIGURATION", "The OAuth provider configuration is invalid.");
437
496
  }
438
- const { authorizeURL, ...options2 } = parsed.data;
439
- const { userInfo, accessToken, clientSecret, ...required } = options2;
440
- const searchParams = new URLSearchParams(toCastCase(required));
441
- return `${authorizeURL}?${searchParams}`;
497
+ return {
498
+ authorization,
499
+ state,
500
+ codeVerifier,
501
+ method
502
+ };
442
503
  };
504
+
505
+ // src/actions/signIn/authorization.ts
443
506
  var getTrustedOrigins = async (request, trustedOrigins) => {
444
507
  if (!trustedOrigins) return [];
445
508
  const raw = typeof trustedOrigins === "function" ? await trustedOrigins(request) : trustedOrigins;
446
509
  return Array.isArray(raw) ? raw : typeof raw === "string" ? [raw] : [];
447
510
  };
511
+ var getBaseURL2 = async ({
512
+ ctx,
513
+ request,
514
+ headers: headersInit
515
+ }) => {
516
+ const origin = getEnv("BASE_URL") || ctx?.baseURL;
517
+ if (origin && origin !== "/") return origin;
518
+ if (ctx?.trustedProxyHeaders) {
519
+ const headers = headersInit && new Headers(headersInit) || request?.headers;
520
+ const protocol = headers?.get("Forwarded")?.match(/proto=([^;]+)/i)?.[1] ?? headers?.get("X-Forwarded-Proto") ?? "http";
521
+ const host = headers?.get("Host") ?? headers?.get("Forwarded")?.match(/host=([^;]+)/i)?.[1] ?? headers?.get("X-Forwarded-Host") ?? null;
522
+ if (host) return `${protocol}://${host}`;
523
+ throw new AuthInternalError(
524
+ "INVALID_OAUTH_CONFIGURATION",
525
+ "The URL cannot be constructed. Please set the BASE_URL environment variable or provide trusted proxy host headers."
526
+ );
527
+ }
528
+ try {
529
+ return new URL(request?.url ?? "not-found").origin;
530
+ } catch (error) {
531
+ throw new AuthInternalError(
532
+ "INVALID_OAUTH_CONFIGURATION",
533
+ "The URL cannot be constructed. Please set the BASE_URL environment variable or enable trustedProxyHeaders.",
534
+ { cause: error }
535
+ );
536
+ }
537
+ };
448
538
  var getOriginURL = async (request, context) => {
449
- const headers = request.headers;
450
- let origin = new URL(request.url).origin;
451
539
  const trustedOrigins = await getTrustedOrigins(request, context?.trustedOrigins);
452
- trustedOrigins.push(origin);
453
- if (context?.trustedProxyHeaders) {
454
- const protocol = headers.get("Forwarded")?.match(/proto=([^;]+)/i)?.[1] ?? headers.get("X-Forwarded-Proto") ?? "http";
455
- const host = headers.get("Host") ?? headers.get("Forwarded")?.match(/host=([^;]+)/i)?.[1] ?? headers.get("X-Forwarded-Host") ?? null;
456
- origin = `${protocol}://${host}`;
457
- }
540
+ trustedOrigins.push(new URL(request.url).origin);
541
+ const origin = await getBaseURL2({ request, ctx: context });
458
542
  if (!isTrustedOrigin(origin, trustedOrigins)) {
459
543
  context?.logger?.log("UNTRUSTED_ORIGIN", { structuredData: { origin } });
460
544
  throw new AuthInternalError("UNTRUSTED_ORIGIN", "The constructed origin URL is not trusted.");
@@ -465,6 +549,17 @@ var createRedirectURI = async (request, oauth, context) => {
465
549
  const origin = await getOriginURL(request, context);
466
550
  return `${origin}${context.basePath}/callback/${oauth}`;
467
551
  };
552
+ var createSignInURL = async ({
553
+ request,
554
+ oauth,
555
+ ctx,
556
+ redirectTo
557
+ }) => {
558
+ const origin = await getOriginURL(request, ctx);
559
+ const searchParams = new URLSearchParams();
560
+ if (redirectTo !== void 0) searchParams.set("redirectTo", String(redirectTo));
561
+ return `${origin}${ctx.basePath}/signIn/${oauth}?${searchParams.toString()}`;
562
+ };
468
563
  var createRedirectTo = async (request, redirectTo, context) => {
469
564
  try {
470
565
  const headers = request.headers;
@@ -500,58 +595,93 @@ var createRedirectTo = async (request, redirectTo, context) => {
500
595
  }
501
596
  };
502
597
 
598
+ // src/api/signIn.ts
599
+ var signIn = async (oauth, {
600
+ ctx,
601
+ headers: headersInit,
602
+ redirectTo = "/",
603
+ redirect,
604
+ request: requestInit
605
+ }) => {
606
+ const headers = new Headers(headersInit);
607
+ const provider = ctx.oauth[oauth];
608
+ if (!provider) {
609
+ throw new AuthInternalError("INVALID_OAUTH_CONFIGURATION", `The OAuth provider "${oauth}" is not configured.`);
610
+ }
611
+ let request = requestInit;
612
+ if (!request) {
613
+ const origin = await getBaseURL2({ ctx, headers });
614
+ const url = `${origin}${ctx.basePath}/signIn/${oauth}`;
615
+ request = new Request(url, { headers });
616
+ }
617
+ if (redirect === false) {
618
+ const signInURL = await createSignInURL({ request, oauth, ctx, redirectTo });
619
+ return { redirect: false, signInURL };
620
+ }
621
+ const redirectURI = await createRedirectURI(request, oauth, ctx);
622
+ const redirectToValue = await createRedirectTo(request, redirectTo, ctx);
623
+ const { authorization, state, codeVerifier } = await createAuthorizationURL(provider, redirectURI, ctx);
624
+ ctx?.logger?.log("SIGN_IN_INITIATED", {
625
+ structuredData: { oauth_provider: oauth }
626
+ });
627
+ const headersList = new import_router2.HeadersBuilder(cacheControl).setHeader("Location", authorization).setCookie(ctx.cookies.state.name, state, ctx.cookies.state.attributes).setCookie(ctx.cookies.redirectURI.name, redirectURI, ctx.cookies.redirectURI.attributes).setCookie(ctx.cookies.redirectTo.name, redirectToValue, ctx.cookies.redirectTo.attributes).setCookie(ctx.cookies.codeVerifier.name, codeVerifier, ctx.cookies.codeVerifier.attributes).toHeaders();
628
+ return Response.json(
629
+ { redirect: redirect ?? true, signInURL: authorization },
630
+ {
631
+ status: redirect ?? true ? 302 : 200,
632
+ headers: headersList
633
+ }
634
+ );
635
+ };
636
+
503
637
  // src/actions/signIn/signIn.ts
638
+ var import_router3 = require("@aura-stack/router");
504
639
  var signInConfig = (oauth) => {
505
- return (0, import_router2.createEndpointConfig)("/signIn/:oauth", {
640
+ return (0, import_router3.createEndpointConfig)("/signIn/:oauth", {
506
641
  schemas: {
507
- params: import_zod2.z.object({
508
- oauth: import_zod2.z.enum(
642
+ params: import_v42.z.object({
643
+ oauth: import_v42.z.enum(
509
644
  Object.keys(oauth),
510
645
  "The OAuth provider is not supported or invalid."
511
646
  )
512
647
  }),
513
- searchParams: import_zod2.z.object({
514
- redirectTo: import_zod2.z.string().optional()
648
+ searchParams: import_v42.z.object({
649
+ redirect: import_v42.z.stringbool().optional().default(true),
650
+ redirectTo: import_v42.z.string().optional()
515
651
  })
516
652
  }
517
653
  });
518
654
  };
519
655
  var signInAction = (oauth) => {
520
- return (0, import_router2.createEndpoint)(
656
+ return (0, import_router3.createEndpoint)(
521
657
  "GET",
522
658
  "/signIn/:oauth",
523
659
  async (ctx) => {
524
660
  const {
525
661
  request,
526
662
  params: { oauth: oauth2 },
527
- searchParams: { redirectTo },
663
+ searchParams: { redirectTo, redirect },
528
664
  context
529
665
  } = ctx;
530
- const { oauth: providers, cookies, logger } = context;
531
- const state = generateSecure();
532
- const redirectURI = await createRedirectURI(request, oauth2, context);
533
- const redirectToValue = await createRedirectTo(request, redirectTo, context);
534
- const { codeVerifier, codeChallenge, method } = await createPKCE();
535
- const authorization = createAuthorizationURL(providers[oauth2], redirectURI, state, codeChallenge, method, logger);
536
- logger?.log("SIGN_IN_INITIATED", {
537
- structuredData: { oauth_provider: oauth2, code_challenge_method: method }
666
+ const signInResult = await signIn(oauth2, {
667
+ ctx: context,
668
+ headers: request.headers,
669
+ redirect,
670
+ redirectTo,
671
+ request
538
672
  });
539
- const headers = new import_router2.HeadersBuilder(cacheControl).setHeader("Location", authorization).setCookie(cookies.state.name, state, cookies.state.attributes).setCookie(cookies.redirectURI.name, redirectURI, cookies.redirectURI.attributes).setCookie(cookies.redirectTo.name, redirectToValue, cookies.redirectTo.attributes).setCookie(cookies.codeVerifier.name, codeVerifier, cookies.codeVerifier.attributes).toHeaders();
540
- return Response.json(
541
- { oauth: oauth2 },
542
- {
543
- status: 302,
544
- headers
545
- }
546
- );
673
+ if (!redirect) {
674
+ return Response.json(signInResult, { status: 200 });
675
+ }
676
+ return signInResult;
547
677
  },
548
678
  signInConfig(oauth)
549
679
  );
550
680
  };
551
681
 
552
682
  // src/actions/callback/callback.ts
553
- var import_zod3 = require("zod");
554
- var import_router3 = require("@aura-stack/router");
683
+ var import_v43 = require("zod/v4");
684
+ var import_router4 = require("@aura-stack/router");
555
685
 
556
686
  // src/request.ts
557
687
  var fetchAsync = async (url, options2 = {}, timeout = 5e3) => {
@@ -575,18 +705,23 @@ var getDefaultUserInfo = (profile) => {
575
705
  };
576
706
  };
577
707
  var getUserInfo = async (oauthConfig, accessToken, logger) => {
578
- const userinfoEndpoint = oauthConfig.userInfo;
708
+ const userInfoConfig = oauthConfig.userInfo;
709
+ const userinfoURL = typeof userInfoConfig === "string" ? userInfoConfig : userInfoConfig.url;
710
+ const extraHeaders = typeof userInfoConfig === "string" ? void 0 : userInfoConfig.headers;
711
+ const method = typeof userInfoConfig === "string" ? "GET" : (userInfoConfig.method ?? "GET").toUpperCase();
579
712
  try {
580
713
  logger?.log("OAUTH_USERINFO_REQUEST_INITIATED", {
581
714
  structuredData: {
582
- endpoint: userinfoEndpoint
715
+ endpoint: userinfoURL
583
716
  }
584
717
  });
585
- const response = await fetchAsync(userinfoEndpoint, {
586
- method: "GET",
718
+ const response = await fetchAsync(userinfoURL, {
719
+ method,
587
720
  headers: {
721
+ "User-Agent": `Aura Auth/${AURA_AUTH_VERSION}`,
588
722
  Accept: "application/json",
589
- Authorization: `Bearer ${accessToken}`
723
+ Authorization: `Bearer ${accessToken}`,
724
+ ...extraHeaders ?? {}
590
725
  }
591
726
  });
592
727
  if (!response.ok) {
@@ -623,31 +758,42 @@ var getUserInfo = async (oauthConfig, accessToken, logger) => {
623
758
 
624
759
  // src/actions/callback/access-token.ts
625
760
  var createAccessToken = async (oauthConfig, redirectURI, code, codeVerifier, logger) => {
626
- const parsed = OAuthAccessToken.safeParse({ ...oauthConfig, redirectURI, code, codeVerifier });
627
- if (!parsed.success) {
628
- logger?.log("INVALID_OAUTH_CONFIGURATION");
761
+ const { accessToken, clientId, clientSecret } = oauthConfig;
762
+ if (!clientId || !clientSecret || !redirectURI || !code || !codeVerifier || !accessToken) {
763
+ logger?.log("INVALID_OAUTH_CONFIGURATION", {
764
+ structuredData: {
765
+ has_client_id: Boolean(clientId),
766
+ has_client_secret: Boolean(clientSecret),
767
+ has_access_token: Boolean(accessToken),
768
+ has_redirect_uri: Boolean(redirectURI),
769
+ has_code: Boolean(code),
770
+ has_code_verifier: Boolean(codeVerifier)
771
+ }
772
+ });
629
773
  throw new AuthInternalError("INVALID_OAUTH_CONFIGURATION", "The OAuth provider configuration is invalid.");
630
774
  }
631
- const { accessToken, clientId, clientSecret, code: codeParsed, redirectURI: redirectParsed } = parsed.data;
775
+ const tokenURL = typeof accessToken === "string" ? accessToken : accessToken.url;
776
+ const extraHeaders = typeof accessToken === "string" ? void 0 : accessToken.headers;
632
777
  try {
633
778
  logger?.log("OAUTH_ACCESS_TOKEN_REQUEST_INITIATED", {
634
779
  structuredData: {
635
780
  has_client_id: Boolean(clientId),
636
- redirect_uri: redirectParsed,
781
+ redirect_uri: redirectURI,
637
782
  grant_type: "authorization_code"
638
783
  }
639
784
  });
640
- const response = await fetchAsync(accessToken, {
785
+ const response = await fetchAsync(tokenURL, {
641
786
  method: "POST",
642
787
  headers: {
788
+ ...extraHeaders ?? {},
643
789
  Accept: "application/json",
644
790
  "Content-Type": "application/x-www-form-urlencoded"
645
791
  },
646
792
  body: new URLSearchParams({
647
793
  client_id: clientId,
648
794
  client_secret: clientSecret,
649
- code: codeParsed,
650
- redirect_uri: redirectParsed,
795
+ code,
796
+ redirect_uri: redirectURI,
651
797
  grant_type: "authorization_code",
652
798
  code_verifier: codeVerifier
653
799
  }).toString()
@@ -707,7 +853,7 @@ var expiredCookieAttributes = {
707
853
  secure: true
708
854
  };
709
855
  var getCookie = (request, cookieName) => {
710
- const cookies = request.headers.get("Cookie");
856
+ const cookies = request instanceof Request ? request.headers.get("Cookie") : request.get("Cookie");
711
857
  if (!cookies) {
712
858
  throw new AuthInternalError("COOKIE_NOT_FOUND", "No cookies found. There is no active session");
713
859
  }
@@ -728,20 +874,20 @@ var createSessionCookie = async (jose, session) => {
728
874
 
729
875
  // src/actions/callback/callback.ts
730
876
  var callbackConfig = (oauth) => {
731
- return (0, import_router3.createEndpointConfig)("/callback/:oauth", {
877
+ return (0, import_router4.createEndpointConfig)("/callback/:oauth", {
732
878
  schemas: {
733
- params: import_zod3.z.object({
734
- oauth: import_zod3.z.enum(
879
+ params: import_v43.z.object({
880
+ oauth: import_v43.z.enum(
735
881
  Object.keys(oauth),
736
882
  "The OAuth provider is not supported or invalid."
737
883
  )
738
884
  }),
739
- searchParams: import_zod3.z.object({
740
- code: import_zod3.z.string("Missing code parameter in the OAuth authorization response."),
741
- state: import_zod3.z.string("Missing state parameter in the OAuth authorization response.")
885
+ searchParams: import_v43.z.object({
886
+ code: import_v43.z.string("Missing code parameter in the OAuth authorization response."),
887
+ state: import_v43.z.string("Missing state parameter in the OAuth authorization response.")
742
888
  })
743
889
  },
744
- middlewares: [
890
+ use: [
745
891
  (ctx) => {
746
892
  const {
747
893
  searchParams,
@@ -767,7 +913,7 @@ var callbackConfig = (oauth) => {
767
913
  });
768
914
  };
769
915
  var callbackAction = (oauth) => {
770
- return (0, import_router3.createEndpoint)(
916
+ return (0, import_router4.createEndpoint)(
771
917
  "GET",
772
918
  "/callback/:oauth",
773
919
  async (ctx) => {
@@ -783,7 +929,7 @@ var callbackAction = (oauth) => {
783
929
  const codeVerifier = getCookie(request, cookies.codeVerifier.name);
784
930
  const cookieRedirectTo = getCookie(request, cookies.redirectTo.name);
785
931
  const cookieRedirectURI = getCookie(request, cookies.redirectURI.name);
786
- if (!safeEquals(cookieState, state)) {
932
+ if (!timingSafeEqual(cookieState, state)) {
787
933
  logger?.log("MISMATCHING_STATE", {
788
934
  structuredData: {
789
935
  oauth_provider: oauth2
@@ -822,7 +968,7 @@ var callbackAction = (oauth) => {
822
968
  provider: oauth2
823
969
  }
824
970
  });
825
- const headers = new import_router3.HeadersBuilder(cacheControl).setHeader("Location", cookieRedirectTo).setCookie(cookies.sessionToken.name, sessionCookie, cookies.sessionToken.attributes).setCookie(cookies.csrfToken.name, csrfToken, cookies.csrfToken.attributes).setCookie(cookies.state.name, "", expiredCookieAttributes).setCookie(cookies.redirectURI.name, "", expiredCookieAttributes).setCookie(cookies.redirectTo.name, "", expiredCookieAttributes).setCookie(cookies.codeVerifier.name, "", expiredCookieAttributes).toHeaders();
971
+ const headers = new import_router4.HeadersBuilder(cacheControl).setHeader("Location", cookieRedirectTo).setCookie(cookies.sessionToken.name, sessionCookie, cookies.sessionToken.attributes).setCookie(cookies.csrfToken.name, csrfToken, cookies.csrfToken.attributes).setCookie(cookies.state.name, "", expiredCookieAttributes).setCookie(cookies.redirectURI.name, "", expiredCookieAttributes).setCookie(cookies.redirectTo.name, "", expiredCookieAttributes).setCookie(cookies.codeVerifier.name, "", expiredCookieAttributes).toHeaders();
826
972
  return Response.json({ oauth: oauth2 }, { status: 302, headers });
827
973
  },
828
974
  callbackConfig(oauth)
@@ -830,100 +976,161 @@ var callbackAction = (oauth) => {
830
976
  };
831
977
 
832
978
  // src/actions/session/session.ts
833
- var import_router4 = require("@aura-stack/router");
834
- var sessionAction = (0, import_router4.createEndpoint)("GET", "/session", async (ctx) => {
979
+ var import_router5 = require("@aura-stack/router");
980
+
981
+ // src/api/getSession.ts
982
+ var getSession = async ({ ctx, headers }) => {
983
+ try {
984
+ const session = getCookie(new Headers(headers), ctx.cookies.sessionToken.name);
985
+ const decoded = await ctx.jose.decodeJWT(session);
986
+ ctx?.logger?.log("AUTH_SESSION_VALID");
987
+ const { exp, iat, jti, nbf, aud, iss, ...user } = decoded;
988
+ return {
989
+ session: {
990
+ user,
991
+ expires: toISOString(exp * 1e3)
992
+ },
993
+ authenticated: true
994
+ };
995
+ } catch (error) {
996
+ ctx?.logger?.log("AUTH_SESSION_INVALID", { structuredData: { error_type: getErrorName(error) } });
997
+ return { session: null, authenticated: false };
998
+ }
999
+ };
1000
+
1001
+ // src/actions/session/session.ts
1002
+ var sessionAction = (0, import_router5.createEndpoint)("GET", "/session", async (ctx) => {
835
1003
  const {
836
1004
  request,
837
- context: { jose, cookies, logger }
1005
+ context: { cookies }
838
1006
  } = ctx;
839
1007
  try {
840
- const session = getCookie(request, cookies.sessionToken.name);
841
- const decoded = await jose.decodeJWT(session);
842
- logger?.log("AUTH_SESSION_VALID");
843
- const { exp, iat, jti, nbf, ...user } = decoded;
844
- const headers = new Headers(secureApiHeaders);
845
- return Response.json({ user, expires: toISOString(exp * 1e3) }, { headers });
1008
+ const session = await getSession({ ctx: ctx.context, headers: request.headers });
1009
+ if (!session.authenticated) {
1010
+ throw new AuthInternalError("INVALID_JWT_TOKEN", "Session not authenticated");
1011
+ }
1012
+ return Response.json(session, { headers: secureApiHeaders });
846
1013
  } catch (error) {
847
- logger?.log("AUTH_SESSION_INVALID", { structuredData: { error_type: getErrorName(error) } });
848
- const headers = new import_router4.HeadersBuilder(secureApiHeaders).setCookie(cookies.sessionToken.name, "", expiredCookieAttributes).toHeaders();
849
- return Response.json({ authenticated: false, message: "Unauthorized" }, { status: 401, headers });
1014
+ const headers = new import_router5.HeadersBuilder(secureApiHeaders).setCookie(cookies.sessionToken.name, "", expiredCookieAttributes).toHeaders();
1015
+ return Response.json({ session: null, authenticated: false }, { status: 401, headers });
850
1016
  }
851
1017
  });
852
1018
 
853
1019
  // src/actions/signOut/signOut.ts
854
- var import_zod4 = require("zod");
855
- var import_router5 = require("@aura-stack/router");
856
- var config = (0, import_router5.createEndpointConfig)({
857
- schemas: {
858
- searchParams: import_zod4.z.object({
859
- token_type_hint: import_zod4.z.literal("session_token"),
860
- redirectTo: import_zod4.z.string().optional()
861
- })
1020
+ var import_v44 = require("zod/v4");
1021
+ var import_router7 = require("@aura-stack/router");
1022
+
1023
+ // src/api/signOut.ts
1024
+ var import_router6 = require("@aura-stack/router");
1025
+ var signOut = async ({
1026
+ ctx,
1027
+ headers: headersInit,
1028
+ redirectTo = "/",
1029
+ skipCSRFCheck = false
1030
+ }) => {
1031
+ const headers = new Headers(headersInit);
1032
+ const header = headers.get("X-CSRF-Token");
1033
+ let session = null;
1034
+ let csrfToken = null;
1035
+ try {
1036
+ session = getCookie(headers, ctx.cookies.sessionToken.name);
1037
+ } catch {
1038
+ throw new AuthSecurityError("SESSION_TOKEN_MISSING", "The sessionToken is missing.");
862
1039
  }
863
- });
864
- var signOutAction = (0, import_router5.createEndpoint)(
865
- "POST",
866
- "/signOut",
867
- async (ctx) => {
868
- const {
869
- request,
870
- headers,
871
- searchParams: { redirectTo },
872
- context
873
- } = ctx;
874
- const { jose, cookies, logger } = context;
875
- const session = headers.getCookie(cookies.sessionToken.name);
876
- const csrfToken = headers.getCookie(cookies.csrfToken.name);
877
- const header = headers.getHeader("X-CSRF-Token");
878
- logger?.log("SIGN_OUT_ATTEMPT", {
879
- structuredData: {
880
- has_session: Boolean(session),
881
- has_csrf_token: Boolean(csrfToken),
882
- has_csrf_header: Boolean(header)
883
- }
884
- });
885
- if (!session) {
886
- logger?.log("SESSION_TOKEN_MISSING");
887
- throw new AuthSecurityError("SESSION_TOKEN_MISSING", "The sessionToken is missing.");
1040
+ try {
1041
+ csrfToken = getCookie(headers, ctx.cookies.csrfToken.name);
1042
+ } catch {
1043
+ throw new AuthSecurityError("CSRF_TOKEN_MISSING", "The CSRF token is missing.");
1044
+ }
1045
+ ctx?.logger?.log("SIGN_OUT_ATTEMPT", {
1046
+ structuredData: {
1047
+ has_session: Boolean(session),
1048
+ has_csrf_token: Boolean(csrfToken),
1049
+ has_csrf_header: Boolean(header),
1050
+ skip_csrf_check: skipCSRFCheck
888
1051
  }
1052
+ });
1053
+ if (!session) {
1054
+ ctx?.logger?.log("SESSION_TOKEN_MISSING");
1055
+ throw new AuthSecurityError("SESSION_TOKEN_MISSING", "The sessionToken is missing.");
1056
+ }
1057
+ if (!skipCSRFCheck) {
889
1058
  if (!csrfToken) {
890
- logger?.log("CSRF_TOKEN_MISSING");
1059
+ ctx?.logger?.log("CSRF_TOKEN_MISSING");
891
1060
  throw new AuthSecurityError("CSRF_TOKEN_MISSING", "The CSRF token is missing.");
892
1061
  }
893
1062
  if (!header) {
894
- logger?.log("CSRF_HEADER_MISSING");
1063
+ ctx?.logger?.log("CSRF_HEADER_MISSING");
895
1064
  throw new AuthSecurityError("CSRF_HEADER_MISSING", "The CSRF header is missing.");
896
1065
  }
897
1066
  try {
898
- await verifyCSRF(jose, csrfToken, header);
1067
+ await verifyCSRF(ctx.jose, csrfToken, header);
899
1068
  } catch (error) {
900
- logger?.log("CSRF_TOKEN_INVALID", { structuredData: { error_type: getErrorName(error) } });
1069
+ ctx?.logger?.log("CSRF_TOKEN_INVALID", { structuredData: { error_type: getErrorName(error) } });
901
1070
  throw new AuthSecurityError("CSRF_TOKEN_INVALID", "CSRF token verification failed");
902
1071
  }
903
- logger?.log("SIGN_OUT_CSRF_VERIFIED");
1072
+ ctx?.logger?.log("SIGN_OUT_CSRF_VERIFIED");
1073
+ } else {
904
1074
  try {
905
- await jose.decodeJWT(session);
906
- logger?.log("SIGN_OUT_SUCCESS");
1075
+ await ctx.jose.verifyJWS(csrfToken);
907
1076
  } catch (error) {
908
- logger?.log("INVALID_JWT_TOKEN", { structuredData: { error_type: getErrorName(error) } });
1077
+ ctx?.logger?.log("CSRF_TOKEN_INVALID", { structuredData: { error_type: getErrorName(error) } });
1078
+ throw new AuthSecurityError("CSRF_TOKEN_INVALID", "CSRF token verification failed");
1079
+ }
1080
+ }
1081
+ try {
1082
+ await ctx.jose.decodeJWT(session);
1083
+ ctx?.logger?.log("SIGN_OUT_SUCCESS");
1084
+ } catch (error) {
1085
+ ctx?.logger?.log("INVALID_JWT_TOKEN", { structuredData: { error_type: getErrorName(error) } });
1086
+ }
1087
+ const headersList = new import_router6.HeadersBuilder(secureApiHeaders).setHeader("Location", redirectTo).setCookie(ctx.cookies.csrfToken.name, "", expiredCookieAttributes).setCookie(ctx.cookies.sessionToken.name, "", expiredCookieAttributes).toHeaders();
1088
+ return Response.json(
1089
+ { redirect: Boolean(redirectTo), url: redirectTo },
1090
+ {
1091
+ status: 202,
1092
+ headers: headersList
909
1093
  }
1094
+ );
1095
+ };
1096
+
1097
+ // src/actions/signOut/signOut.ts
1098
+ var config = (0, import_router7.createEndpointConfig)({
1099
+ schemas: {
1100
+ searchParams: import_v44.z.object({
1101
+ token_type_hint: import_v44.z.literal("session_token"),
1102
+ redirectTo: import_v44.z.string().optional()
1103
+ })
1104
+ }
1105
+ });
1106
+ var signOutAction = (0, import_router7.createEndpoint)(
1107
+ "POST",
1108
+ "/signOut",
1109
+ async (ctx) => {
1110
+ const {
1111
+ request,
1112
+ searchParams: { redirectTo },
1113
+ context
1114
+ } = ctx;
910
1115
  const baseURL = getBaseURL(request);
911
1116
  const location = await createRedirectTo(
912
1117
  new Request(baseURL, {
913
- headers: headers.toHeaders()
1118
+ headers: request.headers
914
1119
  }),
915
1120
  redirectTo,
916
1121
  context
917
1122
  );
918
- logger?.log("SIGN_OUT_REDIRECT", { structuredData: { location } });
919
- const headersList = new import_router5.HeadersBuilder(secureApiHeaders).setHeader("Location", location).setCookie(cookies.csrfToken.name, "", expiredCookieAttributes).setCookie(cookies.sessionToken.name, "", expiredCookieAttributes).toHeaders();
920
- return Response.json({ message: "Signed out successfully" }, { status: import_router5.statusCode.ACCEPTED, headers: headersList });
1123
+ return await signOut({
1124
+ ctx: context,
1125
+ headers: request.headers,
1126
+ redirectTo: location
1127
+ });
921
1128
  },
922
1129
  config
923
1130
  );
924
1131
 
925
1132
  // src/actions/csrfToken/csrfToken.ts
926
- var import_router6 = require("@aura-stack/router");
1133
+ var import_router8 = require("@aura-stack/router");
927
1134
  var getCSRFToken = (request, cookieName) => {
928
1135
  try {
929
1136
  return getCookie(request, cookieName);
@@ -931,7 +1138,7 @@ var getCSRFToken = (request, cookieName) => {
931
1138
  return void 0;
932
1139
  }
933
1140
  };
934
- var csrfTokenAction = (0, import_router6.createEndpoint)("GET", "/csrfToken", async (ctx) => {
1141
+ var csrfTokenAction = (0, import_router8.createEndpoint)("GET", "/csrfToken", async (ctx) => {
935
1142
  const {
936
1143
  request,
937
1144
  context: { jose, cookies, logger }