@aura-stack/auth 0.1.0 → 0.2.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 (99) hide show
  1. package/dist/@types/index.d.ts +3 -4
  2. package/dist/@types/router.d.d.ts +3 -4
  3. package/dist/@types/utility.d.ts +1 -5
  4. package/dist/actions/callback/access-token.cjs +51 -41
  5. package/dist/actions/callback/access-token.d.ts +3 -4
  6. package/dist/actions/callback/access-token.js +4 -3
  7. package/dist/actions/callback/callback.cjs +115 -210
  8. package/dist/actions/callback/callback.d.ts +3 -4
  9. package/dist/actions/callback/callback.js +9 -10
  10. package/dist/actions/callback/userinfo.cjs +35 -22
  11. package/dist/actions/callback/userinfo.d.ts +3 -4
  12. package/dist/actions/callback/userinfo.js +6 -5
  13. package/dist/actions/csrfToken/csrfToken.cjs +34 -103
  14. package/dist/actions/csrfToken/csrfToken.js +6 -6
  15. package/dist/actions/index.cjs +234 -391
  16. package/dist/actions/index.d.ts +3 -4
  17. package/dist/actions/index.js +16 -17
  18. package/dist/actions/session/session.cjs +25 -109
  19. package/dist/actions/session/session.js +4 -5
  20. package/dist/actions/signIn/authorization.cjs +64 -55
  21. package/dist/actions/signIn/authorization.d.ts +3 -4
  22. package/dist/actions/signIn/authorization.js +5 -5
  23. package/dist/actions/signIn/signIn.cjs +84 -206
  24. package/dist/actions/signIn/signIn.d.ts +3 -4
  25. package/dist/actions/signIn/signIn.js +7 -9
  26. package/dist/actions/signOut/signOut.cjs +88 -234
  27. package/dist/actions/signOut/signOut.js +8 -9
  28. package/dist/assert.cjs +5 -0
  29. package/dist/assert.d.ts +9 -1
  30. package/dist/assert.js +3 -1
  31. package/dist/chunk-2RXNXMCZ.js +55 -0
  32. package/dist/{chunk-UJJ7R56J.js → chunk-4V4JNXVF.js} +13 -10
  33. package/dist/chunk-6R2YZ4AC.js +22 -0
  34. package/dist/{chunk-VFTYH33W.js → chunk-7H3OR6UU.js} +29 -9
  35. package/dist/{chunk-256KIVJL.js → chunk-CXLATHS5.js} +53 -9
  36. package/dist/{chunk-6SM22VVJ.js → chunk-EIL2FPSS.js} +5 -1
  37. package/dist/chunk-IMICRJ5U.js +197 -0
  38. package/dist/{chunk-EBPE35JT.js → chunk-IUYZQTJV.js} +0 -1
  39. package/dist/{chunk-GZU3RBTB.js → chunk-N2APGLXA.js} +19 -10
  40. package/dist/chunk-NEVKX6K2.js +70 -0
  41. package/dist/{chunk-XXJKNKGQ.js → chunk-PTJUYB33.js} +9 -13
  42. package/dist/chunk-QDO2KSRJ.js +35 -0
  43. package/dist/{chunk-CAKJT3KS.js → chunk-QEZL7EYN.js} +21 -17
  44. package/dist/chunk-RRLIF4PQ.js +55 -0
  45. package/dist/chunk-TLE4PXY3.js +39 -0
  46. package/dist/chunk-UEH3LVON.js +97 -0
  47. package/dist/{chunk-HMRKN75I.js → chunk-WD7AUHQ5.js} +12 -7
  48. package/dist/{chunk-RLT4RFKV.js → chunk-ZLR3LI6X.js} +19 -9
  49. package/dist/cookie.cjs +140 -99
  50. package/dist/cookie.d.ts +33 -43
  51. package/dist/cookie.js +10 -17
  52. package/dist/errors.cjs +85 -0
  53. package/dist/errors.d.ts +48 -0
  54. package/dist/errors.js +18 -0
  55. package/dist/{index-DpfbvTZ_.d.ts → index-EqsoyjrF.d.ts} +139 -57
  56. package/dist/index.cjs +427 -389
  57. package/dist/index.d.ts +4 -5
  58. package/dist/index.js +37 -26
  59. package/dist/jose.cjs +23 -12
  60. package/dist/jose.d.ts +4 -1
  61. package/dist/jose.js +5 -4
  62. package/dist/oauth/bitbucket.d.ts +3 -4
  63. package/dist/oauth/discord.cjs +0 -1
  64. package/dist/oauth/discord.d.ts +3 -4
  65. package/dist/oauth/discord.js +1 -1
  66. package/dist/oauth/figma.d.ts +3 -4
  67. package/dist/oauth/github.d.ts +3 -4
  68. package/dist/oauth/gitlab.d.ts +3 -4
  69. package/dist/oauth/index.cjs +132 -6
  70. package/dist/oauth/index.d.ts +3 -4
  71. package/dist/oauth/index.js +12 -5
  72. package/dist/oauth/spotify.d.ts +3 -4
  73. package/dist/{response.cjs → oauth/strava.cjs} +21 -9
  74. package/dist/oauth/strava.d.ts +6 -0
  75. package/dist/oauth/strava.js +6 -0
  76. package/dist/oauth/x.d.ts +3 -4
  77. package/dist/schemas.cjs +11 -5
  78. package/dist/schemas.d.ts +70 -67
  79. package/dist/schemas.js +3 -1
  80. package/dist/secure.cjs +27 -19
  81. package/dist/secure.d.ts +3 -4
  82. package/dist/secure.js +4 -3
  83. package/dist/utils.cjs +90 -15
  84. package/dist/utils.d.ts +11 -2
  85. package/dist/utils.js +8 -4
  86. package/package.json +5 -6
  87. package/dist/chunk-FJUDBLCP.js +0 -59
  88. package/dist/chunk-HGJ4TXY4.js +0 -137
  89. package/dist/chunk-JAPMIE6S.js +0 -10
  90. package/dist/chunk-LLR722CL.js +0 -96
  91. package/dist/chunk-SJPDVKUS.js +0 -112
  92. package/dist/chunk-SMQO5WD7.js +0 -30
  93. package/dist/chunk-UTDLUEEG.js +0 -31
  94. package/dist/chunk-ZV4BH47P.js +0 -154
  95. package/dist/error.cjs +0 -88
  96. package/dist/error.d.ts +0 -62
  97. package/dist/error.js +0 -16
  98. package/dist/response.d.ts +0 -10
  99. package/dist/response.js +0 -6
@@ -1,7 +1,6 @@
1
1
  import 'zod/v4';
2
- import '@aura-stack/jose/jose';
3
2
  import '../schemas.js';
4
- import 'cookie';
3
+ import '@aura-stack/router/cookie';
4
+ import '@aura-stack/jose/jose';
5
+ export { i as APIErrorMap, V as AccessTokenError, d as AuthConfig, e as AuthInstance, b as AuthInternalErrorCode, A as AuthRuntimeConfig, c as AuthSecurityErrorCode, T as AuthorizationError, C as CookieConfig, P as CookieName, a as CookieStoreConfig, M as CookieStrategyAttributes, E as ErrorType, K as HostCookie, J as JWTPayloadWithToken, z as JWTStandardClaims, f as JoseInstance, Y as OAuthEnv, Q as OAuthError, O as OAuthProvider, g as OAuthProviderConfig, h as OAuthProviderCredentials, R as RouterGlobalContext, H as SecureCookie, S as Session, L as StandardCookie, W as TokenRevocationError, U as User } from '../index-EqsoyjrF.js';
5
6
  export { LiteralUnion, Prettify } from './utility.js';
6
- export { y as AccessTokenError, c as AuthConfig, d as AuthInstance, A as AuthRuntimeConfig, w as AuthorizationError, C as CookieConfig, a as CookieConfigInternal, b as CookieName, u as CookieStrategyOptions, E as ErrorType, H as HostCookie, q as JWTStandardClaims, J as JoseInstance, v as OAuthError, O as OAuthProvider, e as OAuthProviderConfig, f as OAuthProviderCredentials, R as RouterGlobalContext, r as SecureCookie, S as Session, t as StandardCookie, T as TokenRevocationError, U as User } from '../index-DpfbvTZ_.js';
7
- import 'zod/v4/core';
@@ -1,9 +1,8 @@
1
- import { R as RouterGlobalContext } from '../index-DpfbvTZ_.js';
1
+ import { R as RouterGlobalContext } from '../index-EqsoyjrF.js';
2
2
  import 'zod/v4';
3
- import '@aura-stack/jose/jose';
4
3
  import '../schemas.js';
5
- import 'zod/v4/core';
6
- import 'cookie';
4
+ import '@aura-stack/router/cookie';
5
+ import '@aura-stack/jose/jose';
7
6
  import './utility.js';
8
7
 
9
8
  declare module "@aura-stack/router" {
@@ -1,10 +1,6 @@
1
1
  type Prettify<T> = {
2
2
  [K in keyof T]: T[K];
3
- } & {
4
- __aura_auth_prettify_brand?: never;
5
- };
6
- type LiteralUnion<T extends U, U = string> = (T | (U & Record<never, never>)) & {
7
- __aura_auth_literal_union_brand?: never;
8
3
  };
4
+ type LiteralUnion<T extends U, U = string> = T | (U & Record<never, never>);
9
5
 
10
6
  export type { LiteralUnion, Prettify };
@@ -24,52 +24,57 @@ __export(access_token_exports, {
24
24
  });
25
25
  module.exports = __toCommonJS(access_token_exports);
26
26
 
27
- // src/error.ts
28
- var AuthError = class extends Error {
29
- constructor(type, message) {
30
- super(message);
31
- this.type = type;
32
- this.name = "AuthError";
27
+ // src/utils.ts
28
+ var import_router = require("@aura-stack/router");
29
+
30
+ // src/errors.ts
31
+ var OAuthProtocolError = class extends Error {
32
+ type = "OAUTH_PROTOCOL_ERROR";
33
+ error;
34
+ errorURI;
35
+ constructor(error, description, errorURI, options2) {
36
+ super(description, options2);
37
+ this.error = error;
38
+ this.errorURI = errorURI;
39
+ this.name = new.target.name;
40
+ Error.captureStackTrace(this, new.target);
33
41
  }
34
42
  };
35
- var isAuthError = (error) => {
36
- return error instanceof AuthError;
37
- };
38
- var throwAuthError = (error, message) => {
39
- if (error instanceof Error) {
40
- if (isAuthError(error)) {
41
- throw error;
42
- }
43
- throw new AuthError("invalid_request", error.message ?? message);
43
+ var AuthInternalError = class extends Error {
44
+ type = "AUTH_INTERNAL_ERROR";
45
+ code;
46
+ constructor(code, message, options2) {
47
+ super(message, options2);
48
+ this.code = code;
49
+ this.name = new.target.name;
50
+ Error.captureStackTrace(this, new.target);
44
51
  }
45
52
  };
46
- var ERROR_RESPONSE = {
47
- AUTHORIZATION: {
48
- INVALID_REQUEST: "invalid_request",
49
- UNAUTHORIZED_CLIENT: "unauthorized_client",
50
- ACCESS_DENIED: "access_denied",
51
- UNSUPPORTED_RESPONSE_TYPE: "unsupported_response_type",
52
- INVALID_SCOPE: "invalid_scope",
53
- SERVER_ERROR: "server_error",
54
- TEMPORARILY_UNAVAILABLE: "temporarily_unavailable"
55
- },
56
- ACCESS_TOKEN: {
57
- INVALID_REQUEST: "invalid_request",
58
- INVALID_CLIENT: "invalid_client",
59
- INVALID_GRANT: "invalid_grant",
60
- UNAUTHORIZED_CLIENT: "unauthorized_client",
61
- UNSUPPORTED_GRANT_TYPE: "unsupported_grant_type",
62
- INVALID_SCOPE: "invalid_scope"
53
+
54
+ // src/utils.ts
55
+ var formatZodError = (error) => {
56
+ if (!error.issues || error.issues.length === 0) {
57
+ return {};
63
58
  }
59
+ return error.issues.reduce((previous, issue) => {
60
+ const key = issue.path.join(".");
61
+ return {
62
+ ...previous,
63
+ [key]: {
64
+ code: issue.code,
65
+ message: issue.message
66
+ }
67
+ };
68
+ }, {});
64
69
  };
65
70
 
66
71
  // src/schemas.ts
67
72
  var import_v4 = require("zod/v4");
68
73
  var OAuthProviderConfigSchema = (0, import_v4.object)({
69
- authorizeURL: (0, import_v4.url)(),
70
- accessToken: (0, import_v4.url)(),
74
+ authorizeURL: (0, import_v4.httpUrl)(),
75
+ accessToken: (0, import_v4.httpUrl)(),
71
76
  scope: (0, import_v4.string)().optional(),
72
- userInfo: (0, import_v4.url)(),
77
+ userInfo: (0, import_v4.httpUrl)(),
73
78
  responseType: (0, import_v4.enum)(["code", "token", "id_token"]),
74
79
  clientId: (0, import_v4.string)(),
75
80
  clientSecret: (0, import_v4.string)()
@@ -81,8 +86,8 @@ var OAuthAuthorization = OAuthProviderConfigSchema.extend({
81
86
  codeChallengeMethod: (0, import_v4.enum)(["plain", "S256"])
82
87
  });
83
88
  var OAuthAuthorizationResponse = (0, import_v4.object)({
84
- state: (0, import_v4.string)(),
85
- code: (0, import_v4.string)()
89
+ state: (0, import_v4.string)("Missing state parameter in the OAuth authorization response."),
90
+ code: (0, import_v4.string)("Missing code parameter in the OAuth authorization response.")
86
91
  });
87
92
  var OAuthAuthorizationErrorResponse = (0, import_v4.object)({
88
93
  error: (0, import_v4.enum)([
@@ -126,12 +131,17 @@ var OAuthErrorResponse = (0, import_v4.object)({
126
131
  error: (0, import_v4.string)(),
127
132
  error_description: (0, import_v4.string)().optional()
128
133
  });
134
+ var OAuthEnvSchema = (0, import_v4.object)({
135
+ clientId: import_v4.z.string().min(1, "OAuth Client ID is required in the environment variables."),
136
+ clientSecret: import_v4.z.string().min(1, "OAuth Client Secret is required in the environment variables.")
137
+ });
129
138
 
130
139
  // src/actions/callback/access-token.ts
131
140
  var createAccessToken = async (oauthConfig, redirectURI, code, codeVerifier) => {
132
141
  const parsed = OAuthAccessToken.safeParse({ ...oauthConfig, redirectURI, code, codeVerifier });
133
142
  if (!parsed.success) {
134
- throw new AuthError(ERROR_RESPONSE.ACCESS_TOKEN.INVALID_REQUEST, "Invalid OAuth configuration");
143
+ const msg = JSON.stringify(formatZodError(parsed.error), null, 2);
144
+ throw new AuthInternalError("INVALID_OAUTH_CONFIGURATION", msg);
135
145
  }
136
146
  const { accessToken, clientId, clientSecret, code: codeParsed, redirectURI: redirectParsed } = parsed.data;
137
147
  try {
@@ -155,13 +165,13 @@ var createAccessToken = async (oauthConfig, redirectURI, code, codeVerifier) =>
155
165
  if (!token.success) {
156
166
  const { success, data } = OAuthAccessTokenErrorResponse.safeParse(json);
157
167
  if (!success) {
158
- throw new AuthError(ERROR_RESPONSE.ACCESS_TOKEN.INVALID_GRANT, "Invalid access token response format");
168
+ throw new OAuthProtocolError("INVALID_REQUEST", "Invalid access token response format");
159
169
  }
160
- throw new AuthError(data.error, data?.error_description ?? "Failed to retrieve access token");
170
+ throw new OAuthProtocolError(data.error, data?.error_description ?? "Failed to retrieve access token");
161
171
  }
162
172
  return token.data;
163
173
  } catch (error) {
164
- throw throwAuthError(error, "Failed to create access token");
174
+ throw error;
165
175
  }
166
176
  };
167
177
  // Annotate the CommonJS export names for ESM import in node:
@@ -1,9 +1,8 @@
1
- import { f as OAuthProviderCredentials } from '../../index-DpfbvTZ_.js';
1
+ import { h as OAuthProviderCredentials } from '../../index-EqsoyjrF.js';
2
2
  import 'zod/v4';
3
- import '@aura-stack/jose/jose';
4
3
  import '../../schemas.js';
5
- import 'zod/v4/core';
6
- import 'cookie';
4
+ import '@aura-stack/router/cookie';
5
+ import '@aura-stack/jose/jose';
7
6
  import '../../@types/utility.js';
8
7
 
9
8
  /**
@@ -1,8 +1,9 @@
1
1
  import {
2
2
  createAccessToken
3
- } from "../../chunk-UJJ7R56J.js";
4
- import "../../chunk-FJUDBLCP.js";
5
- import "../../chunk-HMRKN75I.js";
3
+ } from "../../chunk-4V4JNXVF.js";
4
+ import "../../chunk-WD7AUHQ5.js";
5
+ import "../../chunk-CXLATHS5.js";
6
+ import "../../chunk-RRLIF4PQ.js";
6
7
  export {
7
8
  createAccessToken
8
9
  };
@@ -42,53 +42,54 @@ var import_node_crypto = __toESM(require("crypto"), 1);
42
42
  // src/utils.ts
43
43
  var import_router = require("@aura-stack/router");
44
44
 
45
- // src/error.ts
46
- var AuthError = class extends Error {
47
- constructor(type, message) {
48
- super(message);
49
- this.type = type;
50
- this.name = "AuthError";
45
+ // src/errors.ts
46
+ var OAuthProtocolError = class extends Error {
47
+ type = "OAUTH_PROTOCOL_ERROR";
48
+ error;
49
+ errorURI;
50
+ constructor(error, description, errorURI, options2) {
51
+ super(description, options2);
52
+ this.error = error;
53
+ this.errorURI = errorURI;
54
+ this.name = new.target.name;
55
+ Error.captureStackTrace(this, new.target);
51
56
  }
52
57
  };
53
- var isAuthError = (error) => {
54
- return error instanceof AuthError;
55
- };
56
- var throwAuthError = (error, message) => {
57
- if (error instanceof Error) {
58
- if (isAuthError(error)) {
59
- throw error;
60
- }
61
- throw new AuthError("invalid_request", error.message ?? message);
58
+ var AuthInternalError = class extends Error {
59
+ type = "AUTH_INTERNAL_ERROR";
60
+ code;
61
+ constructor(code, message, options2) {
62
+ super(message, options2);
63
+ this.code = code;
64
+ this.name = new.target.name;
65
+ Error.captureStackTrace(this, new.target);
62
66
  }
63
67
  };
64
- var ERROR_RESPONSE = {
65
- AUTHORIZATION: {
66
- INVALID_REQUEST: "invalid_request",
67
- UNAUTHORIZED_CLIENT: "unauthorized_client",
68
- ACCESS_DENIED: "access_denied",
69
- UNSUPPORTED_RESPONSE_TYPE: "unsupported_response_type",
70
- INVALID_SCOPE: "invalid_scope",
71
- SERVER_ERROR: "server_error",
72
- TEMPORARILY_UNAVAILABLE: "temporarily_unavailable"
73
- },
74
- ACCESS_TOKEN: {
75
- INVALID_REQUEST: "invalid_request",
76
- INVALID_CLIENT: "invalid_client",
77
- INVALID_GRANT: "invalid_grant",
78
- UNAUTHORIZED_CLIENT: "unauthorized_client",
79
- UNSUPPORTED_GRANT_TYPE: "unsupported_grant_type",
80
- INVALID_SCOPE: "invalid_scope"
68
+ var AuthSecurityError = class extends Error {
69
+ type = "AUTH_SECURITY_ERROR";
70
+ code;
71
+ constructor(code, message, options2) {
72
+ super(message, options2);
73
+ this.code = code;
74
+ this.name = new.target.name;
75
+ Error.captureStackTrace(this, new.target);
81
76
  }
82
77
  };
78
+ var isNativeError = (error) => {
79
+ return error instanceof Error;
80
+ };
81
+ var isOAuthProtocolError = (error) => {
82
+ return error instanceof OAuthProtocolError;
83
+ };
83
84
 
84
85
  // src/utils.ts
85
86
  var equals = (a, b) => {
86
87
  if (a === null || b === null || a === void 0 || b === void 0) return false;
87
88
  return a === b;
88
89
  };
89
- var sanitizeURL = (url2) => {
90
+ var sanitizeURL = (url) => {
90
91
  try {
91
- let decodedURL = decodeURIComponent(url2).trim();
92
+ let decodedURL = decodeURIComponent(url).trim();
92
93
  const protocolMatch = decodedURL.match(/^([a-zA-Z][a-zA-Z0-9+.-]*:\/\/)/);
93
94
  let protocol = "";
94
95
  let rest = decodedURL;
@@ -116,7 +117,7 @@ var sanitizeURL = (url2) => {
116
117
  }
117
118
  return sanitized;
118
119
  } catch {
119
- return url2.trim();
120
+ return url.trim();
120
121
  }
121
122
  };
122
123
  var isValidRelativePath = (path) => {
@@ -127,6 +128,21 @@ var isValidRelativePath = (path) => {
127
128
  if (sanitized.includes("..")) return false;
128
129
  return true;
129
130
  };
131
+ var formatZodError = (error) => {
132
+ if (!error.issues || error.issues.length === 0) {
133
+ return {};
134
+ }
135
+ return error.issues.reduce((previous, issue) => {
136
+ const key = issue.path.join(".");
137
+ return {
138
+ ...previous,
139
+ [key]: {
140
+ code: issue.code,
141
+ message: issue.message
142
+ }
143
+ };
144
+ }, {});
145
+ };
130
146
 
131
147
  // src/secure.ts
132
148
  var generateSecure = (length = 32) => {
@@ -157,10 +173,10 @@ var cacheControl = {
157
173
  // src/schemas.ts
158
174
  var import_v4 = require("zod/v4");
159
175
  var OAuthProviderConfigSchema = (0, import_v4.object)({
160
- authorizeURL: (0, import_v4.url)(),
161
- accessToken: (0, import_v4.url)(),
176
+ authorizeURL: (0, import_v4.httpUrl)(),
177
+ accessToken: (0, import_v4.httpUrl)(),
162
178
  scope: (0, import_v4.string)().optional(),
163
- userInfo: (0, import_v4.url)(),
179
+ userInfo: (0, import_v4.httpUrl)(),
164
180
  responseType: (0, import_v4.enum)(["code", "token", "id_token"]),
165
181
  clientId: (0, import_v4.string)(),
166
182
  clientSecret: (0, import_v4.string)()
@@ -172,8 +188,8 @@ var OAuthAuthorization = OAuthProviderConfigSchema.extend({
172
188
  codeChallengeMethod: (0, import_v4.enum)(["plain", "S256"])
173
189
  });
174
190
  var OAuthAuthorizationResponse = (0, import_v4.object)({
175
- state: (0, import_v4.string)(),
176
- code: (0, import_v4.string)()
191
+ state: (0, import_v4.string)("Missing state parameter in the OAuth authorization response."),
192
+ code: (0, import_v4.string)("Missing code parameter in the OAuth authorization response.")
177
193
  });
178
194
  var OAuthAuthorizationErrorResponse = (0, import_v4.object)({
179
195
  error: (0, import_v4.enum)([
@@ -217,6 +233,10 @@ var OAuthErrorResponse = (0, import_v4.object)({
217
233
  error: (0, import_v4.string)(),
218
234
  error_description: (0, import_v4.string)().optional()
219
235
  });
236
+ var OAuthEnvSchema = (0, import_v4.object)({
237
+ clientId: import_v4.z.string().min(1, "OAuth Client ID is required in the environment variables."),
238
+ clientSecret: import_v4.z.string().min(1, "OAuth Client Secret is required in the environment variables.")
239
+ });
220
240
 
221
241
  // src/actions/callback/userinfo.ts
222
242
  var getDefaultUserInfo = (profile) => {
@@ -241,18 +261,20 @@ var getUserInfo = async (oauthConfig, accessToken) => {
241
261
  const json = await response.json();
242
262
  const { success, data } = OAuthErrorResponse.safeParse(json);
243
263
  if (success) {
244
- throw new AuthError(data.error, data?.error_description ?? "An error occurred while fetching user information.");
264
+ throw new OAuthProtocolError(
265
+ data.error,
266
+ data?.error_description ?? "An error occurred while fetching user information."
267
+ );
245
268
  }
246
269
  return oauthConfig?.profile ? oauthConfig.profile(json) : getDefaultUserInfo(json);
247
270
  } catch (error) {
248
- throw throwAuthError(error, "Failed to retrieve userinfo");
249
- }
250
- };
251
-
252
- // src/response.ts
253
- var AuraResponse = class extends Response {
254
- static json(body, init) {
255
- return Response.json(body, init);
271
+ if (isOAuthProtocolError(error)) {
272
+ throw error;
273
+ }
274
+ if (isNativeError(error)) {
275
+ throw new OAuthProtocolError("invalid_request", error.message, "", { cause: error });
276
+ }
277
+ throw new OAuthProtocolError("invalid_request", "Failed to fetch user information.", "", { cause: error });
256
278
  }
257
279
  };
258
280
 
@@ -260,7 +282,8 @@ var AuraResponse = class extends Response {
260
282
  var createAccessToken = async (oauthConfig, redirectURI, code, codeVerifier) => {
261
283
  const parsed = OAuthAccessToken.safeParse({ ...oauthConfig, redirectURI, code, codeVerifier });
262
284
  if (!parsed.success) {
263
- throw new AuthError(ERROR_RESPONSE.ACCESS_TOKEN.INVALID_REQUEST, "Invalid OAuth configuration");
285
+ const msg = JSON.stringify(formatZodError(parsed.error), null, 2);
286
+ throw new AuthInternalError("INVALID_OAUTH_CONFIGURATION", msg);
264
287
  }
265
288
  const { accessToken, clientId, clientSecret, code: codeParsed, redirectURI: redirectParsed } = parsed.data;
266
289
  try {
@@ -284,137 +307,53 @@ var createAccessToken = async (oauthConfig, redirectURI, code, codeVerifier) =>
284
307
  if (!token.success) {
285
308
  const { success, data } = OAuthAccessTokenErrorResponse.safeParse(json);
286
309
  if (!success) {
287
- throw new AuthError(ERROR_RESPONSE.ACCESS_TOKEN.INVALID_GRANT, "Invalid access token response format");
310
+ throw new OAuthProtocolError("INVALID_REQUEST", "Invalid access token response format");
288
311
  }
289
- throw new AuthError(data.error, data?.error_description ?? "Failed to retrieve access token");
312
+ throw new OAuthProtocolError(data.error, data?.error_description ?? "Failed to retrieve access token");
290
313
  }
291
314
  return token.data;
292
315
  } catch (error) {
293
- throw throwAuthError(error, "Failed to create access token");
316
+ throw error;
294
317
  }
295
318
  };
296
319
 
297
320
  // src/cookie.ts
298
- var import_cookie = require("cookie");
299
-
300
- // src/assert.ts
301
- var isRequest = (value) => {
302
- return typeof Request !== "undefined" && value instanceof Request;
303
- };
304
-
305
- // src/cookie.ts
306
- var import_cookie2 = require("cookie");
307
- var COOKIE_NAME = "aura-auth";
321
+ var import_cookie = require("@aura-stack/router/cookie");
308
322
  var defaultCookieOptions = {
309
323
  httpOnly: true,
310
324
  sameSite: "lax",
311
325
  path: "/",
312
326
  maxAge: 60 * 60 * 24 * 15
313
327
  };
314
- var defaultStandardCookieConfig = {
315
- secure: false,
328
+ var oauthCookieOptions = {
316
329
  httpOnly: true,
317
- prefix: ""
318
- };
319
- var defaultSecureCookieConfig = {
320
- secure: true,
321
- prefix: "__Secure-"
322
- };
323
- var defaultHostCookieConfig = {
324
- secure: true,
325
- prefix: "__Host-",
326
- path: "/",
327
- domain: void 0
330
+ maxAge: 5 * 60,
331
+ sameSite: "lax",
332
+ expires: new Date(Date.now() + 5 * 60 * 1e3)
328
333
  };
329
- var expiredCookieOptions = {
334
+ var expiredCookieAttributes = {
330
335
  ...defaultCookieOptions,
331
336
  expires: /* @__PURE__ */ new Date(0),
332
337
  maxAge: 0
333
338
  };
334
- var defineDefaultCookieOptions = (options2) => {
335
- return {
336
- name: options2?.name ?? COOKIE_NAME,
337
- prefix: options2?.prefix ?? (options2?.secure ? "__Secure-" : ""),
338
- ...defaultCookieOptions,
339
- ...options2
340
- };
341
- };
342
- var setCookie = (cookieName, value, options2) => {
343
- const { prefix, name } = defineDefaultCookieOptions(options2);
344
- const cookieNameWithPrefix = `${prefix}${name}.${cookieName}`;
345
- return (0, import_cookie.serialize)(cookieNameWithPrefix, value, {
346
- ...defaultCookieOptions,
347
- ...options2
348
- });
349
- };
350
- var getCookie = (petition, cookie, options2, optional = false) => {
351
- const cookies = isRequest(petition) ? petition.headers.get("Cookie") : petition.headers.getSetCookie().join("; ");
339
+ var getCookie = (request, cookieName) => {
340
+ const cookies = request.headers.get("Cookie");
352
341
  if (!cookies) {
353
- if (optional) {
354
- return "";
355
- }
356
- throw new AuthError("invalid_request", "No cookies found. There is no active session");
342
+ throw new AuthInternalError("COOKIE_NOT_FOUND", "No cookies found. There is no active session");
357
343
  }
358
- const { name, prefix } = defineDefaultCookieOptions(options2);
359
- const parsedCookies = (0, import_cookie.parse)(cookies);
360
- const value = parsedCookies[`${prefix}${name}.${cookie}`];
361
- if (value === void 0) {
362
- if (optional) {
363
- return "";
364
- }
365
- throw new AuthError("invalid_request", `Cookie "${cookie}" not found. There is no active session`);
344
+ const value = (0, import_cookie.parse)(cookies)[cookieName];
345
+ if (!value) {
346
+ throw new AuthInternalError("COOKIE_NOT_FOUND", `Cookie "${cookieName}" not found. There is no active session`);
366
347
  }
367
348
  return value;
368
349
  };
369
- var createSessionCookie = async (session, cookieOptions, jose) => {
350
+ var createSessionCookie = async (jose, session) => {
370
351
  try {
371
352
  const encoded = await jose.encodeJWT(session);
372
- return setCookie("sessionToken", encoded, cookieOptions);
353
+ return encoded;
373
354
  } catch (error) {
374
- throw new AuthError("server_error", "Failed to create session cookie", { cause: error });
375
- }
376
- };
377
- var secureCookieOptions = (request, cookieOptions, trustedProxyHeaders) => {
378
- const name = cookieOptions.name ?? COOKIE_NAME;
379
- 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://");
380
- if (!cookieOptions.options?.httpOnly) {
381
- console.warn(
382
- "[WARNING]: Cookie is configured without HttpOnly. This allows JavaScript access via document.cookie and increases XSS risk."
383
- );
384
- }
385
- if (cookieOptions.options?.domain === "*") {
386
- console.warn("[WARNING]: Cookie 'Domain' is set to '*', which is insecure. Avoid wildcard domains.");
355
+ throw new AuthInternalError("INVALID_JWT_TOKEN", "Failed to create session cookie", { cause: error });
387
356
  }
388
- if (!isSecure) {
389
- const options2 = cookieOptions.options;
390
- if (options2?.secure) {
391
- console.warn(
392
- "[WARNING]: The 'Secure' attribute will be disabled for this cookie. Serve over HTTPS to enforce Secure cookies."
393
- );
394
- }
395
- if (options2?.sameSite == "none") {
396
- console.warn("[WARNING]: SameSite=None without a secure connection can be blocked by browsers.");
397
- }
398
- if (process.env.NODE_ENV === "production") {
399
- console.warn("[WARNING]: In production, ensure cookies are served over HTTPS to maintain security.");
400
- }
401
- return {
402
- ...defaultCookieOptions,
403
- ...cookieOptions.options,
404
- sameSite: options2?.sameSite === "none" ? "lax" : options2?.sameSite ?? "lax",
405
- ...defaultStandardCookieConfig,
406
- name
407
- };
408
- }
409
- return cookieOptions.strategy === "host" ? {
410
- ...defaultCookieOptions,
411
- ...cookieOptions.options,
412
- ...defaultHostCookieConfig,
413
- name
414
- } : { ...defaultCookieOptions, ...cookieOptions.options, ...defaultSecureCookieConfig, name };
415
- };
416
- var expireCookie = (name, options2) => {
417
- return setCookie(name, "", { ...options2, ...expiredCookieOptions });
418
357
  };
419
358
 
420
359
  // src/actions/callback/callback.ts
@@ -423,7 +362,7 @@ var callbackConfig = (oauth) => {
423
362
  schemas: {
424
363
  searchParams: OAuthAuthorizationResponse,
425
364
  params: import_zod.default.object({
426
- oauth: import_zod.default.enum(Object.keys(oauth))
365
+ oauth: import_zod.default.enum(Object.keys(oauth), "The OAuth provider is not supported or invalid.")
427
366
  })
428
367
  },
429
368
  middlewares: [
@@ -431,7 +370,7 @@ var callbackConfig = (oauth) => {
431
370
  const response = OAuthAuthorizationErrorResponse.safeParse(ctx.searchParams);
432
371
  if (response.success) {
433
372
  const { error, error_description } = response.data;
434
- throw new AuthError(error, error_description ?? "OAuth Authorization Error");
373
+ throw new OAuthProtocolError(error, error_description ?? "OAuth Authorization Error");
435
374
  }
436
375
  return ctx;
437
376
  }
@@ -447,66 +386,32 @@ var callbackAction = (oauth) => {
447
386
  request,
448
387
  params: { oauth: oauth2 },
449
388
  searchParams: { code, state },
450
- context: { oauth: providers, cookies, jose, trustedProxyHeaders }
389
+ context: { oauth: providers, cookies, jose }
451
390
  } = ctx;
452
- try {
453
- const oauthConfig = providers[oauth2];
454
- const cookieOptions = secureCookieOptions(request, cookies, trustedProxyHeaders);
455
- const cookieState = getCookie(request, "state", cookieOptions);
456
- const cookieRedirectTo = getCookie(request, "redirect_to", cookieOptions);
457
- const cookieRedirectURI = getCookie(request, "redirect_uri", cookieOptions);
458
- const codeVerifier = getCookie(request, "code_verifier", cookieOptions);
459
- if (!equals(cookieState, state)) {
460
- throw new AuthError(ERROR_RESPONSE.ACCESS_TOKEN.INVALID_REQUEST, "Mismatching state");
461
- }
462
- const accessToken = await createAccessToken(oauthConfig, cookieRedirectURI, code, codeVerifier);
463
- const sanitized = sanitizeURL(cookieRedirectTo);
464
- if (!isValidRelativePath(sanitized)) {
465
- throw new AuthError(
466
- ERROR_RESPONSE.ACCESS_TOKEN.INVALID_REQUEST,
467
- "Invalid redirect path. Potential open redirect attack detected."
468
- );
469
- }
470
- const headers = new Headers(cacheControl);
471
- headers.set("Location", sanitized);
472
- const userInfo = await getUserInfo(oauthConfig, accessToken.access_token);
473
- const sessionCookie = await createSessionCookie(userInfo, cookieOptions, jose);
474
- const csrfToken = await createCSRF(jose);
475
- const csrfCookie = setCookie(
476
- "csrfToken",
477
- csrfToken,
478
- secureCookieOptions(
479
- request,
480
- {
481
- ...cookies,
482
- strategy: "host"
483
- },
484
- trustedProxyHeaders
485
- )
391
+ const oauthConfig = providers[oauth2];
392
+ const cookieState = getCookie(request, cookies.state.name);
393
+ const cookieRedirectTo = getCookie(request, cookies.redirect_to.name);
394
+ const cookieRedirectURI = getCookie(request, cookies.redirect_uri.name);
395
+ const codeVerifier = getCookie(request, cookies.code_verifier.name);
396
+ if (!equals(cookieState, state)) {
397
+ throw new AuthSecurityError(
398
+ "MISMATCHING_STATE",
399
+ "The provided state passed in the OAuth response does not match the stored state."
486
400
  );
487
- headers.set("Set-Cookie", sessionCookie);
488
- headers.append("Set-Cookie", expireCookie("state", cookieOptions));
489
- headers.append("Set-Cookie", expireCookie("redirect_uri", cookieOptions));
490
- headers.append("Set-Cookie", expireCookie("redirect_to", cookieOptions));
491
- headers.append("Set-Cookie", expireCookie("code_verifier", cookieOptions));
492
- headers.append("Set-Cookie", csrfCookie);
493
- return Response.json({ oauth: oauth2 }, { status: 302, headers });
494
- } catch (error) {
495
- if (isAuthError(error)) {
496
- const { type, message } = error;
497
- return AuraResponse.json(
498
- { error: type, error_description: message },
499
- { status: import_router2.statusCode.BAD_REQUEST }
500
- );
501
- }
502
- return AuraResponse.json(
503
- {
504
- error: ERROR_RESPONSE.ACCESS_TOKEN.INVALID_CLIENT,
505
- error_description: "An unexpected error occurred"
506
- },
507
- { status: import_router2.statusCode.INTERNAL_SERVER_ERROR }
401
+ }
402
+ const accessToken = await createAccessToken(oauthConfig, cookieRedirectURI, code, codeVerifier);
403
+ const sanitized = sanitizeURL(cookieRedirectTo);
404
+ if (!isValidRelativePath(sanitized)) {
405
+ throw new AuthSecurityError(
406
+ "POTENTIAL_OPEN_REDIRECT_ATTACK_DETECTED",
407
+ "Invalid redirect path. Potential open redirect attack detected."
508
408
  );
509
409
  }
410
+ const userInfo = await getUserInfo(oauthConfig, accessToken.access_token);
411
+ const sessionCookie = await createSessionCookie(jose, userInfo);
412
+ const csrfToken = await createCSRF(jose);
413
+ const headers = new import_router2.HeadersBuilder(cacheControl).setHeader("Location", sanitized).setCookie(cookies.sessionToken.name, sessionCookie, cookies.sessionToken.attributes).setCookie(cookies.csrfToken.name, csrfToken, cookies.csrfToken.attributes).setCookie(cookies.state.name, "", expiredCookieAttributes).setCookie(cookies.redirect_uri.name, "", expiredCookieAttributes).setCookie(cookies.redirect_to.name, "", expiredCookieAttributes).setCookie(cookies.code_verifier.name, "", expiredCookieAttributes).toHeaders();
414
+ return Response.json({ oauth: oauth2 }, { status: 302, headers });
510
415
  },
511
416
  callbackConfig(oauth)
512
417
  );