@aura-stack/auth 0.4.0-rc.5 → 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 (201) hide show
  1. package/dist/@types/index.d.ts +8 -3
  2. package/dist/@types/router.d.cjs +0 -17
  3. package/dist/@types/router.d.d.ts +7 -2
  4. package/dist/@types/router.d.js +0 -1
  5. package/dist/actions/callback/access-token.cjs +130 -71
  6. package/dist/actions/callback/access-token.d.ts +9 -4
  7. package/dist/actions/callback/access-token.js +3 -4
  8. package/dist/actions/callback/callback.cjs +428 -152
  9. package/dist/actions/callback/callback.d.ts +11 -3
  10. package/dist/actions/callback/callback.js +12 -10
  11. package/dist/actions/callback/userinfo.cjs +159 -65
  12. package/dist/actions/callback/userinfo.d.ts +8 -3
  13. package/dist/actions/callback/userinfo.js +7 -6
  14. package/dist/actions/csrfToken/csrfToken.cjs +70 -19
  15. package/dist/actions/csrfToken/csrfToken.js +8 -7
  16. package/dist/actions/index.cjs +780 -348
  17. package/dist/actions/index.d.ts +6 -2
  18. package/dist/actions/index.js +23 -18
  19. package/dist/actions/session/session.cjs +107 -26
  20. package/dist/actions/session/session.js +7 -5
  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 +209 -211
  25. package/dist/actions/signIn/authorization.d.ts +32 -21
  26. package/dist/actions/signIn/authorization.js +12 -9
  27. package/dist/actions/signIn/signIn.cjs +470 -235
  28. package/dist/actions/signIn/signIn.d.ts +12 -3
  29. package/dist/actions/signIn/signIn.js +11 -8
  30. package/dist/actions/signOut/signOut.cjs +376 -228
  31. package/dist/actions/signOut/signOut.d.ts +1 -1
  32. package/dist/actions/signOut/signOut.js +10 -9
  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 +150 -5
  46. package/dist/assert.d.ts +26 -3
  47. package/dist/assert.js +17 -3
  48. package/dist/{chunk-YRCB5FLE.js → chunk-2A5B7GWR.js} +52 -6
  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-4YHJ4IEQ.js +25 -0
  54. package/dist/chunk-54CZPKR4.js +25 -0
  55. package/dist/chunk-5LZ7TOM3.js +25 -0
  56. package/dist/chunk-7BE46WWS.js +88 -0
  57. package/dist/chunk-7YYXFKLR.js +35 -0
  58. package/dist/chunk-C3A37LQC.js +33 -0
  59. package/dist/chunk-CITNGXDA.js +31 -0
  60. package/dist/chunk-CWX724AG.js +78 -0
  61. package/dist/chunk-D2CSIUKP.js +74 -0
  62. package/dist/chunk-E6G5YCI6.js +25 -0
  63. package/dist/chunk-EBAMFRB7.js +34 -0
  64. package/dist/chunk-EEE7UM5T.js +25 -0
  65. package/dist/{chunk-HT4YLL7N.js → chunk-FPCVZUVG.js} +10 -8
  66. package/dist/chunk-FW4W3REU.js +25 -0
  67. package/dist/chunk-GNNBM2WJ.js +83 -0
  68. package/dist/chunk-IPKO6UQN.js +25 -0
  69. package/dist/chunk-JOCGX3RP.js +59 -0
  70. package/dist/chunk-KBXWTD6E.js +94 -0
  71. package/dist/chunk-KMMAZFSJ.js +25 -0
  72. package/dist/chunk-LATR3NIV.js +117 -0
  73. package/dist/chunk-LAYPUDQF.js +39 -0
  74. package/dist/chunk-LDU7A2JE.js +25 -0
  75. package/dist/chunk-LX3TJ2TJ.js +294 -0
  76. package/dist/chunk-NHZBQNRR.js +143 -0
  77. package/dist/chunk-OVHNRULD.js +33 -0
  78. package/dist/chunk-PDP3PHB3.js +127 -0
  79. package/dist/chunk-PHYNROD4.js +47 -0
  80. package/dist/chunk-QQEKY4XP.js +29 -0
  81. package/dist/chunk-U4RK4LKJ.js +348 -0
  82. package/dist/{chunk-RRLIF4PQ.js → chunk-U5663F2U.js} +16 -1
  83. package/dist/chunk-UN7X6SU5.js +53 -0
  84. package/dist/chunk-UZQJJD6A.js +100 -0
  85. package/dist/chunk-V6LLEAR4.js +80 -0
  86. package/dist/chunk-WHNDRO3N.js +50 -0
  87. package/dist/{chunk-W6LG7BFW.js → chunk-XY5R3EHH.js} +30 -23
  88. package/dist/client/client.cjs +135 -0
  89. package/dist/client/client.d.ts +85 -0
  90. package/dist/client/client.js +9 -0
  91. package/dist/client/index.cjs +135 -0
  92. package/dist/client/index.d.ts +14 -0
  93. package/dist/client/index.js +10 -0
  94. package/dist/context.cjs +1237 -0
  95. package/dist/context.d.ts +16 -0
  96. package/dist/context.js +28 -0
  97. package/dist/cookie.cjs +57 -22
  98. package/dist/cookie.d.ts +11 -6
  99. package/dist/cookie.js +3 -2
  100. package/dist/createAuth.cjs +2320 -0
  101. package/dist/createAuth.d.ts +12 -0
  102. package/dist/createAuth.js +48 -0
  103. package/dist/env.cjs +78 -0
  104. package/dist/env.d.ts +10 -0
  105. package/dist/env.js +12 -0
  106. package/dist/errors.cjs +17 -0
  107. package/dist/errors.d.ts +15 -4
  108. package/dist/errors.js +5 -1
  109. package/dist/headers.cjs +28 -2
  110. package/dist/headers.d.ts +25 -1
  111. package/dist/headers.js +9 -3
  112. package/dist/index-_aXtxb_s.d.ts +1377 -0
  113. package/dist/index.cjs +1843 -610
  114. package/dist/index.d.ts +11 -92
  115. package/dist/index.js +53 -85
  116. package/dist/jose.cjs +113 -38
  117. package/dist/jose.d.ts +12 -23
  118. package/dist/jose.js +17 -7
  119. package/dist/logger.cjs +424 -0
  120. package/dist/logger.d.ts +12 -0
  121. package/dist/logger.js +17 -0
  122. package/dist/oauth/atlassian.cjs +57 -0
  123. package/dist/oauth/atlassian.d.ts +12 -0
  124. package/dist/oauth/atlassian.js +6 -0
  125. package/dist/oauth/bitbucket.cjs +19 -15
  126. package/dist/oauth/bitbucket.d.ts +7 -2
  127. package/dist/oauth/bitbucket.js +1 -1
  128. package/dist/oauth/discord.cjs +27 -24
  129. package/dist/oauth/discord.d.ts +7 -2
  130. package/dist/oauth/discord.js +1 -1
  131. package/dist/oauth/dropbox.cjs +53 -0
  132. package/dist/oauth/dropbox.d.ts +12 -0
  133. package/dist/oauth/dropbox.js +6 -0
  134. package/dist/oauth/figma.cjs +19 -16
  135. package/dist/oauth/figma.d.ts +7 -2
  136. package/dist/oauth/figma.js +1 -1
  137. package/dist/oauth/github.cjs +19 -8
  138. package/dist/oauth/github.d.ts +7 -2
  139. package/dist/oauth/github.js +1 -1
  140. package/dist/oauth/gitlab.cjs +19 -16
  141. package/dist/oauth/gitlab.d.ts +7 -2
  142. package/dist/oauth/gitlab.js +1 -1
  143. package/dist/oauth/index.cjs +529 -239
  144. package/dist/oauth/index.d.ts +7 -2
  145. package/dist/oauth/index.js +39 -22
  146. package/dist/oauth/mailchimp.cjs +19 -16
  147. package/dist/oauth/mailchimp.d.ts +7 -2
  148. package/dist/oauth/mailchimp.js +1 -1
  149. package/dist/oauth/notion.cjs +131 -0
  150. package/dist/oauth/notion.d.ts +12 -0
  151. package/dist/oauth/notion.js +9 -0
  152. package/dist/oauth/pinterest.cjs +19 -16
  153. package/dist/oauth/pinterest.d.ts +7 -2
  154. package/dist/oauth/pinterest.js +1 -1
  155. package/dist/oauth/spotify.cjs +19 -16
  156. package/dist/oauth/spotify.d.ts +7 -2
  157. package/dist/oauth/spotify.js +1 -1
  158. package/dist/oauth/strava.cjs +19 -16
  159. package/dist/oauth/strava.d.ts +7 -2
  160. package/dist/oauth/strava.js +1 -1
  161. package/dist/oauth/twitch.cjs +95 -0
  162. package/dist/oauth/twitch.d.ts +12 -0
  163. package/dist/oauth/twitch.js +7 -0
  164. package/dist/oauth/x.cjs +19 -16
  165. package/dist/oauth/x.d.ts +7 -2
  166. package/dist/oauth/x.js +1 -1
  167. package/dist/schemas.cjs +89 -42
  168. package/dist/schemas.d.ts +114 -18
  169. package/dist/schemas.js +5 -3
  170. package/dist/secure.cjs +73 -31
  171. package/dist/secure.d.ts +11 -11
  172. package/dist/secure.js +7 -6
  173. package/dist/utils.cjs +203 -90
  174. package/dist/utils.d.ts +21 -40
  175. package/dist/utils.js +21 -12
  176. package/package.json +9 -6
  177. package/dist/chunk-3EUWD5BB.js +0 -63
  178. package/dist/chunk-42XB3YCW.js +0 -22
  179. package/dist/chunk-6R2YZ4AC.js +0 -22
  180. package/dist/chunk-A3N4PVAT.js +0 -70
  181. package/dist/chunk-B737EUJV.js +0 -22
  182. package/dist/chunk-CXLATHS5.js +0 -143
  183. package/dist/chunk-E3OXBRYF.js +0 -22
  184. package/dist/chunk-EIL2FPSS.js +0 -22
  185. package/dist/chunk-EMKJA2GJ.js +0 -89
  186. package/dist/chunk-FIPU4MLT.js +0 -21
  187. package/dist/chunk-FKRDCWBF.js +0 -22
  188. package/dist/chunk-GA2SMTJO.js +0 -58
  189. package/dist/chunk-HP34YGGJ.js +0 -22
  190. package/dist/chunk-IKHPGFCW.js +0 -14
  191. package/dist/chunk-IUYZQTJV.js +0 -30
  192. package/dist/chunk-IVET23KF.js +0 -58
  193. package/dist/chunk-JVFTCTTE.js +0 -33
  194. package/dist/chunk-KRNOMBXQ.js +0 -22
  195. package/dist/chunk-KSWLO5ZU.js +0 -102
  196. package/dist/chunk-N2APGLXA.js +0 -71
  197. package/dist/chunk-N4SX7TZT.js +0 -96
  198. package/dist/chunk-STHEPPUZ.js +0 -11
  199. package/dist/chunk-TLE4PXY3.js +0 -39
  200. package/dist/index-B8jeIElf.d.ts +0 -679
  201. /package/dist/{chunk-DIVDFNAP.js → chunk-5X7JZMEF.js} +0 -0
package/dist/secure.js CHANGED
@@ -1,19 +1,20 @@
1
1
  import {
2
2
  createCSRF,
3
- createDerivedSalt,
4
3
  createHash,
5
4
  createPKCE,
5
+ createSecretValue,
6
6
  generateSecure,
7
7
  verifyCSRF
8
- } from "./chunk-N2APGLXA.js";
9
- import "./chunk-CXLATHS5.js";
10
- import "./chunk-EIL2FPSS.js";
11
- import "./chunk-RRLIF4PQ.js";
8
+ } from "./chunk-V6LLEAR4.js";
9
+ import "./chunk-UZQJJD6A.js";
10
+ import "./chunk-LX3TJ2TJ.js";
11
+ import "./chunk-WHNDRO3N.js";
12
+ import "./chunk-U5663F2U.js";
12
13
  export {
13
14
  createCSRF,
14
- createDerivedSalt,
15
15
  createHash,
16
16
  createPKCE,
17
+ createSecretValue,
17
18
  generateSecure,
18
19
  verifyCSRF
19
20
  };
package/dist/utils.cjs CHANGED
@@ -20,17 +20,21 @@ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: tru
20
20
  // src/utils.ts
21
21
  var utils_exports = {};
22
22
  __export(utils_exports, {
23
+ AURA_AUTH_VERSION: () => AURA_AUTH_VERSION,
24
+ createBasicAuthHeader: () => createBasicAuthHeader,
25
+ createErrorHandler: () => createErrorHandler,
26
+ createStructuredData: () => createStructuredData,
23
27
  equals: () => equals,
28
+ extractPath: () => extractPath,
24
29
  formatZodError: () => formatZodError,
25
- getNormalizedOriginPath: () => getNormalizedOriginPath,
26
- isValidRelativePath: () => isValidRelativePath,
27
- onErrorHandler: () => onErrorHandler,
28
- sanitizeURL: () => sanitizeURL,
30
+ getBaseURL: () => getBaseURL,
31
+ getErrorName: () => getErrorName,
29
32
  toCastCase: () => toCastCase,
30
33
  toISOString: () => toISOString,
31
34
  toSnakeCase: () => toSnakeCase,
32
35
  toUpperCase: () => toUpperCase,
33
- useSecureCookies: () => useSecureCookies
36
+ useSecureCookies: () => useSecureCookies,
37
+ validateRedirectTo: () => validateRedirectTo
34
38
  });
35
39
  module.exports = __toCommonJS(utils_exports);
36
40
  var import_router = require("@aura-stack/router");
@@ -78,7 +82,91 @@ var isAuthSecurityError = (error) => {
78
82
  return error instanceof AuthSecurityError;
79
83
  };
80
84
 
85
+ // src/env.ts
86
+ var import_meta = {};
87
+ var env = new Proxy({}, {
88
+ get(_, prop) {
89
+ if (typeof prop !== "string") return void 0;
90
+ const hasProperty = (process2) => {
91
+ return process2 && Object.prototype.hasOwnProperty.call(process2, prop);
92
+ };
93
+ try {
94
+ if (typeof process !== "undefined" && hasProperty(process.env)) {
95
+ return process.env[prop];
96
+ }
97
+ if (typeof import_meta !== "undefined" && hasProperty(import_meta.env)) {
98
+ return import_meta.env[prop];
99
+ }
100
+ if (typeof Deno !== "undefined" && Deno.env?.get) {
101
+ return Deno.env.get(prop);
102
+ }
103
+ if (typeof Bun !== "undefined" && hasProperty(Bun.env)) {
104
+ return Bun.env[prop];
105
+ }
106
+ const globalValue = globalThis[prop];
107
+ return typeof globalValue === "string" ? globalValue : void 0;
108
+ } catch {
109
+ return void 0;
110
+ }
111
+ }
112
+ });
113
+ var getEnv = (key) => {
114
+ const keys = [`AURA_AUTH_${key.toUpperCase()}`, `AURA_${key.toUpperCase()}`, `AUTH_${key.toUpperCase()}`, key.toUpperCase()];
115
+ return env[keys.find((k) => env[k]) ?? ""];
116
+ };
117
+
118
+ // src/assert.ts
119
+ var import_crypto = require("@aura-stack/jose/crypto");
120
+ var unsafeChars = [
121
+ "<",
122
+ ">",
123
+ '"',
124
+ "`",
125
+ " ",
126
+ "\r",
127
+ "\n",
128
+ " ",
129
+ "\\",
130
+ "%2F",
131
+ "%5C",
132
+ "%2f",
133
+ "%5c",
134
+ "\r\n",
135
+ "%0A",
136
+ "%0D",
137
+ "%0a",
138
+ "%0d",
139
+ "..",
140
+ "//",
141
+ "///",
142
+ "...",
143
+ "%20",
144
+ "\0"
145
+ ];
146
+ var isValidURL = (value) => {
147
+ if (!new RegExp(/^https?:\/\/[^/]/).test(value)) {
148
+ return false;
149
+ }
150
+ const match = value.match(/^(https?:\/\/)(.*)$/);
151
+ if (!match) return false;
152
+ const rest = match[2];
153
+ for (const char of unsafeChars) {
154
+ if (rest.includes(char)) return false;
155
+ }
156
+ const regex = /^https?:\/\/(?:[a-zA-Z0-9._-]+|localhost|\[[0-9a-fA-F:]+\])(?::\d{1,5})?(?:\/[a-zA-Z0-9._~!$&'()?#*+,;=:@-]*)*\/?$/;
157
+ return regex.test(match[0]);
158
+ };
159
+ var isRelativeURL = (value) => {
160
+ if (value.length > 100) return false;
161
+ for (const char of unsafeChars) {
162
+ if (value.includes(char)) return false;
163
+ }
164
+ const regex = /^\/[a-zA-Z0-9\-_\/.?&=#]*\/?$/;
165
+ return regex.test(value);
166
+ };
167
+
81
168
  // src/utils.ts
169
+ var AURA_AUTH_VERSION = "0.4.0";
82
170
  var toSnakeCase = (str) => {
83
171
  return str.replace(/([a-z0-9])([A-Z])/g, "$1_$2").replace(/([A-Z]+)([A-Z][a-z])/g, "$1_$2").toLowerCase().replace(/^_+/, "");
84
172
  };
@@ -95,95 +183,85 @@ var equals = (a, b) => {
95
183
  if (a === null || b === null || a === void 0 || b === void 0) return false;
96
184
  return a === b;
97
185
  };
98
- var sanitizeURL = (url) => {
99
- try {
100
- let decodedURL = decodeURIComponent(url).trim();
101
- const protocolMatch = decodedURL.match(/^([a-zA-Z][a-zA-Z0-9+.-]*:\/\/)/);
102
- let protocol = "";
103
- let rest = decodedURL;
104
- if (protocolMatch) {
105
- protocol = protocolMatch[1];
106
- rest = decodedURL.slice(protocol.length);
107
- const slashIndex = rest.indexOf("/");
108
- if (slashIndex === -1) {
109
- return protocol + rest;
110
- }
111
- const domain = rest.slice(0, slashIndex);
112
- let path = rest.slice(slashIndex).replace(/\/\.\.\//g, "/").replace(/\/\.\.$/, "").replace(/\.{2,}/g, "").replace(/\/{2,}/g, "/");
113
- if (path !== "/" && path.endsWith("/")) {
114
- path = path.replace(/\/+$/, "/");
115
- } else if (path !== "/") {
116
- path = path.replace(/\/+$/, "");
117
- }
118
- return protocol + domain + path;
186
+ var createErrorHandler = (logger) => {
187
+ return (error) => {
188
+ if ((0, import_router.isRouterError)(error)) {
189
+ const { message, status, statusText } = error;
190
+ logger?.log("ROUTER_INTERNAL_ERROR");
191
+ return Response.json({ type: "ROUTER_ERROR", code: "ROUTER_INTERNAL_ERROR", message }, { status, statusText });
119
192
  }
120
- let sanitized = decodedURL.replace(/\/\.\.\//g, "/").replace(/\/\.\.$/, "").replace(/\.{2,}/g, "").replace(/\/{2,}/g, "/");
121
- if (sanitized !== "/" && sanitized.endsWith("/")) {
122
- sanitized = sanitized.replace(/\/+$/, "/");
123
- } else if (sanitized !== "/") {
124
- sanitized = sanitized.replace(/\/+$/, "");
193
+ if ((0, import_router.isInvalidZodSchemaError)(error)) {
194
+ logger?.log("INVALID_REQUEST");
195
+ return Response.json({ type: "ROUTER_ERROR", code: "INVALID_REQUEST", message: error.errors }, { status: 422 });
125
196
  }
126
- return sanitized;
127
- } catch {
128
- return url.trim();
129
- }
130
- };
131
- var isValidRelativePath = (path) => {
132
- if (!path || typeof path !== "string") return false;
133
- if (!path.startsWith("/") || path.includes("://") || path.includes("\r") || path.includes("\n")) return false;
134
- if (/[\x00-\x1F\x7F]/.test(path) || path.includes("\0")) return false;
135
- const sanitized = sanitizeURL(path);
136
- if (sanitized.includes("..")) return false;
137
- return true;
138
- };
139
- var onErrorHandler = (error) => {
140
- if ((0, import_router.isRouterError)(error)) {
141
- const { message, status, statusText } = error;
142
- return Response.json({ type: "ROUTER_ERROR", code: "ROUTER_INTERNAL_ERROR", message }, { status, statusText });
143
- }
144
- if ((0, import_router.isInvalidZodSchemaError)(error)) {
145
- return Response.json({ type: "ROUTER_ERROR", code: "INVALID_REQUEST", message: error.errors }, { status: 422 });
146
- }
147
- if (isOAuthProtocolError(error)) {
148
- const { error: errorCode, message, type, errorURI } = error;
149
- return Response.json(
150
- {
151
- type,
152
- error: errorCode,
153
- error_description: message,
154
- error_uri: errorURI
155
- },
156
- { status: 400 }
157
- );
158
- }
159
- if (isAuthInternalError(error) || isAuthSecurityError(error)) {
160
- const { type, code, message } = error;
197
+ if (isOAuthProtocolError(error)) {
198
+ const { error: errorCode, message, type, errorURI } = error;
199
+ logger?.log("OAUTH_PROTOCOL_ERROR", {
200
+ structuredData: {
201
+ error: errorCode,
202
+ error_description: message,
203
+ error_uri: errorURI ?? ""
204
+ }
205
+ });
206
+ return Response.json(
207
+ {
208
+ type,
209
+ message
210
+ },
211
+ { status: 400 }
212
+ );
213
+ }
214
+ if (isAuthInternalError(error)) {
215
+ const { type, code, message } = error;
216
+ logger?.log("INVALID_OAUTH_CONFIGURATION", {
217
+ structuredData: {
218
+ error: code,
219
+ error_description: message
220
+ }
221
+ });
222
+ return Response.json(
223
+ {
224
+ type,
225
+ message
226
+ },
227
+ { status: 400 }
228
+ );
229
+ }
230
+ if (isAuthSecurityError(error)) {
231
+ const { type, code, message } = error;
232
+ logger?.log("INVALID_OAUTH_CONFIGURATION", {
233
+ structuredData: {
234
+ error: code,
235
+ error_description: message
236
+ }
237
+ });
238
+ return Response.json(
239
+ {
240
+ type,
241
+ code,
242
+ message
243
+ },
244
+ { status: 400 }
245
+ );
246
+ }
247
+ logger?.log("SERVER_ERROR");
161
248
  return Response.json(
162
- {
163
- type,
164
- code,
165
- message
166
- },
167
- { status: 400 }
249
+ { type: "SERVER_ERROR", code: "SERVER_ERROR", message: "An unexpected error occurred" },
250
+ { status: 500 }
168
251
  );
169
- }
170
- return Response.json({ type: "SERVER_ERROR", code: "server_error", message: "An unexpected error occurred" }, { status: 500 });
171
- };
172
- var getNormalizedOriginPath = (path) => {
173
- try {
174
- const url = new URL(path);
175
- url.hash = "";
176
- url.search = "";
177
- return `${url.origin}${url.pathname}`;
178
- } catch {
179
- return sanitizeURL(path);
180
- }
252
+ };
253
+ };
254
+ var getBaseURL = (request) => {
255
+ const url = new URL(request.url);
256
+ return `${url.origin}${url.pathname}`;
181
257
  };
182
258
  var toISOString = (date) => {
183
259
  return new Date(date).toISOString();
184
260
  };
185
261
  var useSecureCookies = (request, trustedProxyHeaders) => {
186
- return trustedProxyHeaders ? request.url.startsWith("https://") || request.headers.get("X-Forwarded-Proto") === "https" || (request.headers.get("Forwarded")?.includes("proto=https") ?? false) : request.url.startsWith("https://");
262
+ const headers = request instanceof Headers ? request : request.headers;
263
+ const url = request instanceof Headers ? null : request.url;
264
+ return trustedProxyHeaders ? url?.startsWith("https://") || headers.get("X-Forwarded-Proto") === "https" || (headers.get("Forwarded")?.includes("proto=https") ?? false) : url?.startsWith("https://") ?? false;
187
265
  };
188
266
  var formatZodError = (error) => {
189
267
  if (!error.issues || error.issues.length === 0) {
@@ -200,17 +278,52 @@ var formatZodError = (error) => {
200
278
  };
201
279
  }, {});
202
280
  };
281
+ var extractPath = (url) => {
282
+ const pathRegex = /^https?:\/\/[a-zA-Z0-9_\-\.]+(:\d+)?(\/.*)$/;
283
+ const match = url.match(pathRegex);
284
+ return match && match[2] ? match[2] : "/";
285
+ };
286
+ var createStructuredData = (data, sdID = "metadata") => {
287
+ const entries = Object.entries(data);
288
+ if (entries.length === 0) return `[${sdID}]`;
289
+ const values = entries.map(([key, value]) => `${key}="${String(value).replace(/(["\\\]])/g, "\\$1")}"`).join(" ");
290
+ return `[${sdID} ${values}]`;
291
+ };
292
+ var getErrorName = (error) => {
293
+ if (error instanceof Error) {
294
+ return error.name;
295
+ }
296
+ return typeof error === "string" ? error : "UnknownError";
297
+ };
298
+ var createBasicAuthHeader = (username, password) => {
299
+ const getUsername = getEnv(username.toUpperCase()) ?? username;
300
+ const getPassword = getEnv(password.toUpperCase()) ?? password;
301
+ if (!getUsername || !getPassword) {
302
+ throw new AuthInternalError("INVALID_OAUTH_CONFIGURATION", "Missing client credentials for OAuth provider configuration.");
303
+ }
304
+ const credentials = `${getUsername}:${getPassword}`;
305
+ return `Basic ${btoa(credentials)}`;
306
+ };
307
+ var validateRedirectTo = (url) => {
308
+ if (!isRelativeURL(url) && !isValidURL(url)) return "/";
309
+ if (isRelativeURL(url)) return url;
310
+ return "/";
311
+ };
203
312
  // Annotate the CommonJS export names for ESM import in node:
204
313
  0 && (module.exports = {
314
+ AURA_AUTH_VERSION,
315
+ createBasicAuthHeader,
316
+ createErrorHandler,
317
+ createStructuredData,
205
318
  equals,
319
+ extractPath,
206
320
  formatZodError,
207
- getNormalizedOriginPath,
208
- isValidRelativePath,
209
- onErrorHandler,
210
- sanitizeURL,
321
+ getBaseURL,
322
+ getErrorName,
211
323
  toCastCase,
212
324
  toISOString,
213
325
  toSnakeCase,
214
326
  toUpperCase,
215
- useSecureCookies
327
+ useSecureCookies,
328
+ validateRedirectTo
216
329
  });
package/dist/utils.d.ts CHANGED
@@ -1,54 +1,35 @@
1
1
  import { RouterConfig } from '@aura-stack/router';
2
- import { i as APIErrorMap } from './index-B8jeIElf.js';
3
2
  import { ZodError } from 'zod';
3
+ import { a as InternalLogger, f as APIErrorMap } from './index-_aXtxb_s.js';
4
4
  import './schemas.js';
5
- import '@aura-stack/router/cookie';
5
+ import 'zod/v4';
6
6
  import '@aura-stack/jose';
7
7
  import '@aura-stack/jose/jose';
8
+ import '@aura-stack/jose/crypto';
9
+ import '@aura-stack/router/cookie';
8
10
  import './@types/utility.js';
11
+ import 'jose';
12
+ import 'zod/v4/core';
9
13
 
14
+ declare const AURA_AUTH_VERSION = "0.4.0";
10
15
  declare const toSnakeCase: (str: string) => string;
11
16
  declare const toUpperCase: (str: string) => string;
12
17
  declare const toCastCase: <Obj extends Record<string, string>, Type extends "snake" | "upper">(obj: Obj, type?: Type) => Type extends "snake" ? { [K in keyof Obj as `${string & K}`]: Obj[K]; } : { [K in keyof Obj as Uppercase<string & K>]: Obj[K]; };
13
18
  declare const equals: (a: string | number | undefined | null, b: string | number | undefined | null) => boolean;
14
- /**
15
- * Sanitizes a URL by removing dangerous patterns that could be used for path traversal
16
- * or other attacks. This function:
17
- * - Decodes URL-encoded characters
18
- * - Removes multiple consecutive slashes (preserving protocol slashes)
19
- * - Removes path traversal patterns (..)
20
- * - Removes trailing slashes (except root)
21
- * - Trims whitespace
22
- *
23
- * @param url - The URL or path to sanitize
24
- * @returns The sanitized URL or path
25
- */
26
- declare const sanitizeURL: (url: string) => string;
27
- /**
28
- * Validates that a path is a safe relative path to prevent open redirect attacks.
29
- * A safe relative path must:
30
- * - Start with '/'
31
- * - Not contain protocol schemes (://)
32
- * - Not contain newline characters
33
- * - Not contain null bytes
34
- * - Not be an absolute URL
35
- *
36
- * @param path - The path to validate
37
- * @returns true if the path is safe, false otherwise
38
- */
39
- declare const isValidRelativePath: (path: string | undefined | null) => boolean;
40
- declare const onErrorHandler: RouterConfig["onError"];
41
- /**
42
- * Extracts and normalizes the origin and pathname from a URL string.
43
- * Removes query parameters and hash fragments for a clean path.
44
- * Falls back to the original string if URL parsing fails.
45
- *
46
- * @param path - The URL or path string to process
47
- * @returns The normalized URL with origin and pathname, or the original path
48
- */
49
- declare const getNormalizedOriginPath: (path: string) => string;
19
+ declare const createErrorHandler: (logger?: InternalLogger) => RouterConfig["onError"];
20
+ declare const getBaseURL: (request: Request) => string;
50
21
  declare const toISOString: (date: Date | string | number) => string;
51
- declare const useSecureCookies: (request: Request, trustedProxyHeaders: boolean) => boolean;
22
+ declare const useSecureCookies: (request: Request | Headers, trustedProxyHeaders: boolean) => boolean;
52
23
  declare const formatZodError: <T extends Record<string, unknown> = Record<string, unknown>>(error: ZodError<T>) => APIErrorMap;
24
+ declare const extractPath: (url: string) => string;
25
+ declare const createStructuredData: (data: Record<string, string | number | boolean>, sdID?: string) => string;
26
+ declare const getErrorName: (error: unknown) => string;
27
+ declare const createBasicAuthHeader: (username: string, password: string) => string;
28
+ /**
29
+ * Validates and sanitizes redirect URLs to prevent open redirect attacks.
30
+ * Only relative URLs (starting with /) are allowed; absolute URLs are
31
+ * rejected and replaced with "/" to enforce same-origin redirects.
32
+ */
33
+ declare const validateRedirectTo: (url: string) => string;
53
34
 
54
- export { equals, formatZodError, getNormalizedOriginPath, isValidRelativePath, onErrorHandler, sanitizeURL, toCastCase, toISOString, toSnakeCase, toUpperCase, useSecureCookies };
35
+ export { AURA_AUTH_VERSION, createBasicAuthHeader, createErrorHandler, createStructuredData, equals, extractPath, formatZodError, getBaseURL, getErrorName, toCastCase, toISOString, toSnakeCase, toUpperCase, useSecureCookies, validateRedirectTo };
package/dist/utils.js CHANGED
@@ -1,27 +1,36 @@
1
1
  import {
2
+ AURA_AUTH_VERSION,
3
+ createBasicAuthHeader,
4
+ createErrorHandler,
5
+ createStructuredData,
2
6
  equals,
7
+ extractPath,
3
8
  formatZodError,
4
- getNormalizedOriginPath,
5
- isValidRelativePath,
6
- onErrorHandler,
7
- sanitizeURL,
9
+ getBaseURL,
10
+ getErrorName,
8
11
  toCastCase,
9
12
  toISOString,
10
13
  toSnakeCase,
11
14
  toUpperCase,
12
- useSecureCookies
13
- } from "./chunk-CXLATHS5.js";
14
- import "./chunk-RRLIF4PQ.js";
15
+ useSecureCookies,
16
+ validateRedirectTo
17
+ } from "./chunk-LX3TJ2TJ.js";
18
+ import "./chunk-WHNDRO3N.js";
19
+ import "./chunk-U5663F2U.js";
15
20
  export {
21
+ AURA_AUTH_VERSION,
22
+ createBasicAuthHeader,
23
+ createErrorHandler,
24
+ createStructuredData,
16
25
  equals,
26
+ extractPath,
17
27
  formatZodError,
18
- getNormalizedOriginPath,
19
- isValidRelativePath,
20
- onErrorHandler,
21
- sanitizeURL,
28
+ getBaseURL,
29
+ getErrorName,
22
30
  toCastCase,
23
31
  toISOString,
24
32
  toSnakeCase,
25
33
  toUpperCase,
26
- useSecureCookies
34
+ useSecureCookies,
35
+ validateRedirectTo
27
36
  };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@aura-stack/auth",
3
- "version": "0.4.0-rc.5",
3
+ "version": "0.5.0",
4
4
  "private": false,
5
5
  "type": "module",
6
6
  "description": "Core auth for @aura-stack/auth",
@@ -30,6 +30,11 @@
30
30
  "types": "./dist/@types/index.d.ts",
31
31
  "import": "./dist/@types/index.js",
32
32
  "require": "./dist/@types/index.cjs"
33
+ },
34
+ "./client": {
35
+ "types": "./dist/client/index.d.ts",
36
+ "import": "./dist/client/index.js",
37
+ "require": "./dist/client/index.cjs"
33
38
  }
34
39
  },
35
40
  "keywords": [
@@ -44,13 +49,11 @@
44
49
  },
45
50
  "license": "MIT",
46
51
  "dependencies": {
47
- "@aura-stack/router": "0.6.0-rc.1",
48
- "dotenv": "^17.2.3",
49
- "zod": "^4.3.5",
50
- "@aura-stack/jose": "0.2.0"
52
+ "@aura-stack/router": "^0.6.0",
53
+ "zod": "4.3.5",
54
+ "@aura-stack/jose": "0.4.0"
51
55
  },
52
56
  "devDependencies": {
53
- "@types/node": "^24.9.2",
54
57
  "typescript": "^5.9.2",
55
58
  "@aura-stack/tsconfig": "0.0.0",
56
59
  "@aura-stack/tsup-config": "0.0.0"
@@ -1,63 +0,0 @@
1
- import {
2
- createAuthorizationURL,
3
- createRedirectTo,
4
- createRedirectURI
5
- } from "./chunk-N4SX7TZT.js";
6
- import {
7
- cacheControl
8
- } from "./chunk-STHEPPUZ.js";
9
- import {
10
- createPKCE,
11
- generateSecure
12
- } from "./chunk-N2APGLXA.js";
13
-
14
- // src/actions/signIn/signIn.ts
15
- import { z } from "zod";
16
- import { createEndpoint, createEndpointConfig, HeadersBuilder } from "@aura-stack/router";
17
- var signInConfig = (oauth) => {
18
- return createEndpointConfig("/signIn/:oauth", {
19
- schemas: {
20
- params: z.object({
21
- oauth: z.enum(
22
- Object.keys(oauth),
23
- "The OAuth provider is not supported or invalid."
24
- )
25
- }),
26
- searchParams: z.object({
27
- redirectTo: z.string().optional()
28
- })
29
- }
30
- });
31
- };
32
- var signInAction = (oauth) => {
33
- return createEndpoint(
34
- "GET",
35
- "/signIn/:oauth",
36
- async (ctx) => {
37
- const {
38
- request,
39
- params: { oauth: oauth2 },
40
- searchParams: { redirectTo },
41
- context: { oauth: providers, cookies, trustedProxyHeaders, basePath }
42
- } = ctx;
43
- const state = generateSecure();
44
- const redirectURI = createRedirectURI(request, oauth2, basePath, trustedProxyHeaders);
45
- const redirectToValue = createRedirectTo(request, redirectTo, trustedProxyHeaders);
46
- const { codeVerifier, codeChallenge, method } = await createPKCE();
47
- const authorization = createAuthorizationURL(providers[oauth2], redirectURI, state, codeChallenge, method);
48
- const headers = new 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();
49
- return Response.json(
50
- { oauth: oauth2 },
51
- {
52
- status: 302,
53
- headers
54
- }
55
- );
56
- },
57
- signInConfig(oauth)
58
- );
59
- };
60
-
61
- export {
62
- signInAction
63
- };
@@ -1,22 +0,0 @@
1
- // src/oauth/x.ts
2
- var x = {
3
- id: "x",
4
- name: "X",
5
- authorizeURL: "https://x.com/i/oauth2/authorize",
6
- accessToken: "https://api.x.com/2/oauth2/token",
7
- userInfo: "https://api.x.com/2/users/me?user.fields=profile_image_url",
8
- scope: "users.read users.email tweet.read offline.access",
9
- responseType: "code",
10
- profile({ data }) {
11
- return {
12
- sub: data.id,
13
- name: data.name,
14
- image: data.profile_image_url,
15
- email: ""
16
- };
17
- }
18
- };
19
-
20
- export {
21
- x
22
- };
@@ -1,22 +0,0 @@
1
- // src/oauth/strava.ts
2
- var strava = {
3
- id: "strava",
4
- name: "Strava",
5
- authorizeURL: "https://www.strava.com/oauth/authorize",
6
- accessToken: "https://www.strava.com/oauth/token",
7
- userInfo: "https://www.strava.com/api/v3/athlete",
8
- scope: "read",
9
- responseType: "code",
10
- profile(profile) {
11
- return {
12
- sub: profile.id.toString(),
13
- name: `${profile.firstname} ${profile.lastname}`,
14
- image: profile.profile,
15
- email: ""
16
- };
17
- }
18
- };
19
-
20
- export {
21
- strava
22
- };