@aura-stack/auth 0.1.0-rc.1

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 (141) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +42 -0
  3. package/dist/@types/index.cjs +18 -0
  4. package/dist/@types/index.d.cts +9 -0
  5. package/dist/@types/index.d.ts +9 -0
  6. package/dist/@types/index.js +1 -0
  7. package/dist/@types/router.d.cjs +1 -0
  8. package/dist/@types/router.d.d.cts +16 -0
  9. package/dist/@types/router.d.d.ts +16 -0
  10. package/dist/@types/router.d.js +0 -0
  11. package/dist/@types/utility.cjs +18 -0
  12. package/dist/@types/utility.d.cts +6 -0
  13. package/dist/@types/utility.d.ts +6 -0
  14. package/dist/@types/utility.js +1 -0
  15. package/dist/actions/callback/access-token.cjs +170 -0
  16. package/dist/actions/callback/access-token.d.cts +30 -0
  17. package/dist/actions/callback/access-token.d.ts +30 -0
  18. package/dist/actions/callback/access-token.js +8 -0
  19. package/dist/actions/callback/callback.cjs +517 -0
  20. package/dist/actions/callback/callback.d.cts +13 -0
  21. package/dist/actions/callback/callback.d.ts +13 -0
  22. package/dist/actions/callback/callback.js +16 -0
  23. package/dist/actions/callback/userinfo.cjs +165 -0
  24. package/dist/actions/callback/userinfo.d.cts +22 -0
  25. package/dist/actions/callback/userinfo.d.ts +22 -0
  26. package/dist/actions/callback/userinfo.js +10 -0
  27. package/dist/actions/csrfToken/csrfToken.cjs +207 -0
  28. package/dist/actions/csrfToken/csrfToken.d.cts +5 -0
  29. package/dist/actions/csrfToken/csrfToken.d.ts +5 -0
  30. package/dist/actions/csrfToken/csrfToken.js +12 -0
  31. package/dist/actions/index.cjs +864 -0
  32. package/dist/actions/index.d.cts +14 -0
  33. package/dist/actions/index.d.ts +14 -0
  34. package/dist/actions/index.js +34 -0
  35. package/dist/actions/session/session.cjs +191 -0
  36. package/dist/actions/session/session.d.cts +5 -0
  37. package/dist/actions/session/session.d.ts +5 -0
  38. package/dist/actions/session/session.js +11 -0
  39. package/dist/actions/signIn/authorization.cjs +274 -0
  40. package/dist/actions/signIn/authorization.d.cts +45 -0
  41. package/dist/actions/signIn/authorization.d.ts +45 -0
  42. package/dist/actions/signIn/authorization.js +16 -0
  43. package/dist/actions/signIn/signIn.cjs +469 -0
  44. package/dist/actions/signIn/signIn.d.cts +13 -0
  45. package/dist/actions/signIn/signIn.d.ts +13 -0
  46. package/dist/actions/signIn/signIn.js +14 -0
  47. package/dist/actions/signOut/signOut.cjs +490 -0
  48. package/dist/actions/signOut/signOut.d.cts +8 -0
  49. package/dist/actions/signOut/signOut.d.ts +8 -0
  50. package/dist/actions/signOut/signOut.js +15 -0
  51. package/dist/assert.cjs +44 -0
  52. package/dist/assert.d.ts +5 -0
  53. package/dist/assert.js +10 -0
  54. package/dist/chunk-256KIVJL.js +99 -0
  55. package/dist/chunk-42XB3YCW.js +22 -0
  56. package/dist/chunk-6SM22VVJ.js +18 -0
  57. package/dist/chunk-CAKJT3KS.js +92 -0
  58. package/dist/chunk-E3OXBRYF.js +22 -0
  59. package/dist/chunk-EBPE35JT.js +31 -0
  60. package/dist/chunk-FIPU4MLT.js +21 -0
  61. package/dist/chunk-FJUDBLCP.js +59 -0
  62. package/dist/chunk-FKRDCWBF.js +22 -0
  63. package/dist/chunk-GZU3RBTB.js +62 -0
  64. package/dist/chunk-HGJ4TXY4.js +137 -0
  65. package/dist/chunk-HMRKN75I.js +74 -0
  66. package/dist/chunk-IKHPGFCW.js +14 -0
  67. package/dist/chunk-ITQ7352M.js +0 -0
  68. package/dist/chunk-JAPMIE6S.js +10 -0
  69. package/dist/chunk-KRNOMBXQ.js +22 -0
  70. package/dist/chunk-LLR722CL.js +96 -0
  71. package/dist/chunk-PG7UYFG5.js +0 -0
  72. package/dist/chunk-RLT4RFKV.js +45 -0
  73. package/dist/chunk-SJPDVKUS.js +112 -0
  74. package/dist/chunk-SMQO5WD7.js +30 -0
  75. package/dist/chunk-STHEPPUZ.js +11 -0
  76. package/dist/chunk-UJJ7R56J.js +52 -0
  77. package/dist/chunk-VFTYH33W.js +61 -0
  78. package/dist/chunk-X7M4CQTN.js +25 -0
  79. package/dist/chunk-XXJKNKGQ.js +37 -0
  80. package/dist/chunk-ZV4BH47P.js +154 -0
  81. package/dist/cookie.cjs +201 -0
  82. package/dist/cookie.d.ts +95 -0
  83. package/dist/cookie.js +36 -0
  84. package/dist/error.cjs +88 -0
  85. package/dist/error.d.ts +64 -0
  86. package/dist/error.js +16 -0
  87. package/dist/headers.cjs +35 -0
  88. package/dist/headers.d.ts +9 -0
  89. package/dist/headers.js +6 -0
  90. package/dist/index-CGRZ0wrw.d.ts +530 -0
  91. package/dist/index.cjs +1089 -0
  92. package/dist/index.d.ts +43 -0
  93. package/dist/index.js +75 -0
  94. package/dist/jose.cjs +68 -0
  95. package/dist/jose.d.ts +20 -0
  96. package/dist/jose.js +9 -0
  97. package/dist/oauth/bitbucket.cjs +45 -0
  98. package/dist/oauth/bitbucket.d.cts +9 -0
  99. package/dist/oauth/bitbucket.d.ts +9 -0
  100. package/dist/oauth/bitbucket.js +6 -0
  101. package/dist/oauth/discord.cjs +55 -0
  102. package/dist/oauth/discord.d.cts +9 -0
  103. package/dist/oauth/discord.d.ts +9 -0
  104. package/dist/oauth/discord.js +6 -0
  105. package/dist/oauth/figma.cjs +46 -0
  106. package/dist/oauth/figma.d.cts +9 -0
  107. package/dist/oauth/figma.d.ts +9 -0
  108. package/dist/oauth/figma.js +6 -0
  109. package/dist/oauth/github.cjs +38 -0
  110. package/dist/oauth/github.d.cts +9 -0
  111. package/dist/oauth/github.d.ts +9 -0
  112. package/dist/oauth/github.js +6 -0
  113. package/dist/oauth/gitlab.cjs +46 -0
  114. package/dist/oauth/gitlab.d.cts +9 -0
  115. package/dist/oauth/gitlab.d.ts +9 -0
  116. package/dist/oauth/gitlab.js +6 -0
  117. package/dist/oauth/index.cjs +213 -0
  118. package/dist/oauth/index.d.cts +9 -0
  119. package/dist/oauth/index.d.ts +9 -0
  120. package/dist/oauth/index.js +36 -0
  121. package/dist/oauth/spotify.cjs +46 -0
  122. package/dist/oauth/spotify.d.cts +9 -0
  123. package/dist/oauth/spotify.d.ts +9 -0
  124. package/dist/oauth/spotify.js +6 -0
  125. package/dist/oauth/x.cjs +46 -0
  126. package/dist/oauth/x.d.cts +9 -0
  127. package/dist/oauth/x.d.ts +9 -0
  128. package/dist/oauth/x.js +6 -0
  129. package/dist/response.cjs +34 -0
  130. package/dist/response.d.ts +10 -0
  131. package/dist/response.js +6 -0
  132. package/dist/schemas.cjs +105 -0
  133. package/dist/schemas.d.ts +130 -0
  134. package/dist/schemas.js +20 -0
  135. package/dist/secure.cjs +120 -0
  136. package/dist/secure.d.ts +43 -0
  137. package/dist/secure.js +18 -0
  138. package/dist/utils.cjs +141 -0
  139. package/dist/utils.d.ts +45 -0
  140. package/dist/utils.js +23 -0
  141. package/package.json +70 -0
@@ -0,0 +1,130 @@
1
+ import * as zod_v4_core from 'zod/v4/core';
2
+ import * as zod_v4 from 'zod/v4';
3
+
4
+ /**
5
+ * Schema for OAuth Provider Configuration
6
+ */
7
+ declare const OAuthProviderConfigSchema: zod_v4.ZodObject<{
8
+ authorizeURL: zod_v4.ZodURL;
9
+ accessToken: zod_v4.ZodURL;
10
+ scope: zod_v4.ZodOptional<zod_v4.ZodString>;
11
+ userInfo: zod_v4.ZodURL;
12
+ responseType: zod_v4.ZodEnum<{
13
+ code: "code";
14
+ token: "token";
15
+ id_token: "id_token";
16
+ }>;
17
+ clientId: zod_v4.ZodString;
18
+ clientSecret: zod_v4.ZodString;
19
+ }, zod_v4_core.$strip>;
20
+ /**
21
+ * Schema used to create the authorization URL for the OAuth flow and verify the
22
+ * OAuth configuration.
23
+ * @see https://datatracker.ietf.org/doc/html/rfc6749#section-4.1.1
24
+ */
25
+ declare const OAuthAuthorization: zod_v4.ZodObject<{
26
+ authorizeURL: zod_v4.ZodURL;
27
+ accessToken: zod_v4.ZodURL;
28
+ scope: zod_v4.ZodOptional<zod_v4.ZodString>;
29
+ userInfo: zod_v4.ZodURL;
30
+ responseType: zod_v4.ZodEnum<{
31
+ code: "code";
32
+ token: "token";
33
+ id_token: "id_token";
34
+ }>;
35
+ clientId: zod_v4.ZodString;
36
+ clientSecret: zod_v4.ZodString;
37
+ redirectURI: zod_v4.ZodString;
38
+ state: zod_v4.ZodString;
39
+ codeChallenge: zod_v4.ZodString;
40
+ codeChallengeMethod: zod_v4.ZodEnum<{
41
+ plain: "plain";
42
+ S256: "S256";
43
+ }>;
44
+ }, zod_v4_core.$strip>;
45
+ /**
46
+ * Schema used in the callback action to validate the authorization response when the resource owner
47
+ * has granted.
48
+ * @see https://datatracker.ietf.org/doc/html/rfc6749#section-4.1.2
49
+ */
50
+ declare const OAuthAuthorizationResponse: zod_v4.ZodObject<{
51
+ state: zod_v4.ZodString;
52
+ code: zod_v4.ZodString;
53
+ }, zod_v4_core.$strip>;
54
+ /**
55
+ * Schema used in the callback action to validate the authorization error response when the resource owner
56
+ * has denied the authorization request.
57
+ * @see https://datatracker.ietf.org/doc/html/rfc6749#section-4.1.2.1
58
+ */
59
+ declare const OAuthAuthorizationErrorResponse: zod_v4.ZodObject<{
60
+ error: zod_v4.ZodEnum<{
61
+ invalid_request: "invalid_request";
62
+ unauthorized_client: "unauthorized_client";
63
+ access_denied: "access_denied";
64
+ unsupported_response_type: "unsupported_response_type";
65
+ invalid_scope: "invalid_scope";
66
+ server_error: "server_error";
67
+ temporarily_unavailable: "temporarily_unavailable";
68
+ }>;
69
+ error_description: zod_v4.ZodOptional<zod_v4.ZodString>;
70
+ error_uri: zod_v4.ZodOptional<zod_v4.ZodString>;
71
+ state: zod_v4.ZodString;
72
+ }, zod_v4_core.$strip>;
73
+ /**
74
+ * Schema for OAuth Access Token Request and OAuth Configuration
75
+ * @see https://datatracker.ietf.org/doc/html/rfc6749#section-4.1.3
76
+ */
77
+ declare const OAuthAccessToken: zod_v4.ZodObject<{
78
+ authorizeURL: zod_v4.ZodURL;
79
+ accessToken: zod_v4.ZodURL;
80
+ scope: zod_v4.ZodOptional<zod_v4.ZodString>;
81
+ userInfo: zod_v4.ZodURL;
82
+ responseType: zod_v4.ZodEnum<{
83
+ code: "code";
84
+ token: "token";
85
+ id_token: "id_token";
86
+ }>;
87
+ clientId: zod_v4.ZodString;
88
+ clientSecret: zod_v4.ZodString;
89
+ redirectURI: zod_v4.ZodString;
90
+ code: zod_v4.ZodString;
91
+ codeVerifier: zod_v4.ZodString;
92
+ }, zod_v4_core.$strip>;
93
+ /**
94
+ * Schema for OAuth Access Token Response
95
+ * @see https://datatracker.ietf.org/doc/html/rfc6749#section-5.1
96
+ * @see https://datatracker.ietf.org/doc/html/rfc7636#section-4
97
+ */
98
+ declare const OAuthAccessTokenResponse: zod_v4.ZodObject<{
99
+ access_token: zod_v4.ZodString;
100
+ token_type: zod_v4.ZodString;
101
+ expires_in: zod_v4.ZodOptional<zod_v4.ZodNumber>;
102
+ refresh_token: zod_v4.ZodOptional<zod_v4.ZodString>;
103
+ scope: zod_v4.ZodOptional<zod_v4.ZodString>;
104
+ }, zod_v4_core.$strip>;
105
+ /**
106
+ * Schema for OAuth Access Token Error Response
107
+ * @see https://datatracker.ietf.org/doc/html/rfc6749#section-5.2
108
+ */
109
+ declare const OAuthAccessTokenErrorResponse: zod_v4.ZodObject<{
110
+ error: zod_v4.ZodEnum<{
111
+ invalid_request: "invalid_request";
112
+ unauthorized_client: "unauthorized_client";
113
+ invalid_scope: "invalid_scope";
114
+ invalid_client: "invalid_client";
115
+ invalid_grant: "invalid_grant";
116
+ unsupported_grant_type: "unsupported_grant_type";
117
+ }>;
118
+ error_description: zod_v4.ZodOptional<zod_v4.ZodString>;
119
+ error_uri: zod_v4.ZodOptional<zod_v4.ZodString>;
120
+ }, zod_v4_core.$strip>;
121
+ /**
122
+ * @todo: verify if this schema is still needed
123
+ * @deprecated
124
+ */
125
+ declare const OAuthErrorResponse: zod_v4.ZodObject<{
126
+ error: zod_v4.ZodString;
127
+ error_description: zod_v4.ZodOptional<zod_v4.ZodString>;
128
+ }, zod_v4_core.$strip>;
129
+
130
+ export { OAuthAccessToken, OAuthAccessTokenErrorResponse, OAuthAccessTokenResponse, OAuthAuthorization, OAuthAuthorizationErrorResponse, OAuthAuthorizationResponse, OAuthErrorResponse, OAuthProviderConfigSchema };
@@ -0,0 +1,20 @@
1
+ import {
2
+ OAuthAccessToken,
3
+ OAuthAccessTokenErrorResponse,
4
+ OAuthAccessTokenResponse,
5
+ OAuthAuthorization,
6
+ OAuthAuthorizationErrorResponse,
7
+ OAuthAuthorizationResponse,
8
+ OAuthErrorResponse,
9
+ OAuthProviderConfigSchema
10
+ } from "./chunk-HMRKN75I.js";
11
+ export {
12
+ OAuthAccessToken,
13
+ OAuthAccessTokenErrorResponse,
14
+ OAuthAccessTokenResponse,
15
+ OAuthAuthorization,
16
+ OAuthAuthorizationErrorResponse,
17
+ OAuthAuthorizationResponse,
18
+ OAuthErrorResponse,
19
+ OAuthProviderConfigSchema
20
+ };
@@ -0,0 +1,120 @@
1
+ "use strict";
2
+ var __create = Object.create;
3
+ var __defProp = Object.defineProperty;
4
+ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
5
+ var __getOwnPropNames = Object.getOwnPropertyNames;
6
+ var __getProtoOf = Object.getPrototypeOf;
7
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
8
+ var __export = (target, all) => {
9
+ for (var name in all)
10
+ __defProp(target, name, { get: all[name], enumerable: true });
11
+ };
12
+ var __copyProps = (to, from, except, desc) => {
13
+ if (from && typeof from === "object" || typeof from === "function") {
14
+ for (let key of __getOwnPropNames(from))
15
+ if (!__hasOwnProp.call(to, key) && key !== except)
16
+ __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
17
+ }
18
+ return to;
19
+ };
20
+ var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
21
+ // If the importer is in node compatibility mode or this is not an ESM
22
+ // file that has been converted to a CommonJS file using a Babel-
23
+ // compatible transform (i.e. "__esModule" has not been set), then set
24
+ // "default" to the CommonJS "module.exports" for node compatibility.
25
+ isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
26
+ mod
27
+ ));
28
+ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
29
+
30
+ // src/secure.ts
31
+ var secure_exports = {};
32
+ __export(secure_exports, {
33
+ createCSRF: () => createCSRF,
34
+ createDerivedSalt: () => createDerivedSalt,
35
+ createHash: () => createHash,
36
+ createPKCE: () => createPKCE,
37
+ generateSecure: () => generateSecure,
38
+ verifyCSRF: () => verifyCSRF
39
+ });
40
+ module.exports = __toCommonJS(secure_exports);
41
+ var import_node_crypto = __toESM(require("crypto"), 1);
42
+
43
+ // src/utils.ts
44
+ var import_router = require("@aura-stack/router");
45
+
46
+ // src/error.ts
47
+ var AuthError = class extends Error {
48
+ constructor(type, message) {
49
+ super(message);
50
+ this.type = type;
51
+ this.name = "AuthError";
52
+ }
53
+ };
54
+ var InvalidCsrfTokenError = class extends AuthError {
55
+ constructor(message = "The provided CSRF token is invalid or has expired") {
56
+ super("invalid_csrf_token", message);
57
+ this.name = "InvalidCsrfTokenError";
58
+ }
59
+ };
60
+
61
+ // src/utils.ts
62
+ var equals = (a, b) => {
63
+ if (a === null || b === null || a === void 0 || b === void 0) return false;
64
+ return a === b;
65
+ };
66
+
67
+ // src/secure.ts
68
+ var generateSecure = (length = 32) => {
69
+ return import_node_crypto.default.randomBytes(length).toString("base64url");
70
+ };
71
+ var createHash = (data, base = "hex") => {
72
+ return import_node_crypto.default.createHash("sha256").update(data).digest().toString(base);
73
+ };
74
+ var createPKCE = async (verifier) => {
75
+ const codeVerifier = verifier ?? generateSecure(86);
76
+ const codeChallenge = createHash(codeVerifier, "base64url");
77
+ return { codeVerifier, codeChallenge, method: "S256" };
78
+ };
79
+ var createCSRF = async (jose, csrfCookie) => {
80
+ try {
81
+ const token = generateSecure(32);
82
+ if (csrfCookie) {
83
+ await jose.verifyJWS(csrfCookie);
84
+ return csrfCookie;
85
+ }
86
+ return jose.signJWS({ token });
87
+ } catch {
88
+ const token = generateSecure(32);
89
+ return jose.signJWS({ token });
90
+ }
91
+ };
92
+ var verifyCSRF = async (jose, cookie, header) => {
93
+ try {
94
+ const { token: cookieToken } = await jose.verifyJWS(cookie);
95
+ const { token: headerToken } = await jose.verifyJWS(header);
96
+ const cookieBuffer = Buffer.from(cookieToken);
97
+ const headerBuffer = Buffer.from(headerToken);
98
+ if (!equals(headerBuffer.length, cookieBuffer.length)) {
99
+ throw new InvalidCsrfTokenError();
100
+ }
101
+ if (!import_node_crypto.default.timingSafeEqual(cookieBuffer, headerBuffer)) {
102
+ throw new InvalidCsrfTokenError();
103
+ }
104
+ return true;
105
+ } catch {
106
+ throw new InvalidCsrfTokenError();
107
+ }
108
+ };
109
+ var createDerivedSalt = (secret) => {
110
+ return import_node_crypto.default.createHash("sha256").update(secret).update("aura-auth-salt").digest("hex");
111
+ };
112
+ // Annotate the CommonJS export names for ESM import in node:
113
+ 0 && (module.exports = {
114
+ createCSRF,
115
+ createDerivedSalt,
116
+ createHash,
117
+ createPKCE,
118
+ generateSecure,
119
+ verifyCSRF
120
+ });
@@ -0,0 +1,43 @@
1
+ import { A as AuthRuntimeConfig } from './index-CGRZ0wrw.js';
2
+ import 'zod/v4';
3
+ import './jose.js';
4
+ import '@aura-stack/jose/jose';
5
+ import './schemas.js';
6
+ import 'zod/v4/core';
7
+ import '@aura-stack/router';
8
+ import 'cookie';
9
+ import './@types/utility.js';
10
+
11
+ declare const generateSecure: (length?: number) => string;
12
+ declare const createHash: (data: string, base?: "hex" | "base64" | "base64url") => string;
13
+ /**
14
+ * Creates the code challenge flow for PKCE OAuth flow. It generates a code verifier and its corresponding
15
+ * code challenge using SHA-256 hashing.
16
+ * - code_verifier: A cryptographically random string used to mitigate authorization code interception attacks.
17
+ * - code_challenge: A hashed version of the code_verifier sent in the authorization request.
18
+ * - method: The method used to generate the code challenge, typically "S256" for SHA-256.
19
+ *
20
+ * @see https://datatracker.ietf.org/doc/html/rfc7636#section-4.1
21
+ */
22
+ declare const createPKCE: (verifier?: string) => Promise<{
23
+ codeVerifier: string;
24
+ codeChallenge: string;
25
+ method: string;
26
+ }>;
27
+ /**
28
+ * Creates a CSRF token to be used in OAuth flows to prevent cross-site request forgery attacks.
29
+ *
30
+ * @param csrfCookie - Optional existing CSRF cookie to verify and reuse
31
+ * @returns Signed CSRF token
32
+ */
33
+ declare const createCSRF: (jose: AuthRuntimeConfig["jose"], csrfCookie?: string) => Promise<string>;
34
+ declare const verifyCSRF: (jose: AuthRuntimeConfig["jose"], cookie: string, header: string) => Promise<boolean>;
35
+ /**
36
+ * Creates a deterministic derived salt from the provided secret.
37
+ *
38
+ * @param secret the base secret to derive the salt from
39
+ * @returns the derived salt as a hexadecimal string
40
+ */
41
+ declare const createDerivedSalt: (secret: string) => string;
42
+
43
+ export { createCSRF, createDerivedSalt, createHash, createPKCE, generateSecure, verifyCSRF };
package/dist/secure.js ADDED
@@ -0,0 +1,18 @@
1
+ import {
2
+ createCSRF,
3
+ createDerivedSalt,
4
+ createHash,
5
+ createPKCE,
6
+ generateSecure,
7
+ verifyCSRF
8
+ } from "./chunk-GZU3RBTB.js";
9
+ import "./chunk-256KIVJL.js";
10
+ import "./chunk-FJUDBLCP.js";
11
+ export {
12
+ createCSRF,
13
+ createDerivedSalt,
14
+ createHash,
15
+ createPKCE,
16
+ generateSecure,
17
+ verifyCSRF
18
+ };
package/dist/utils.cjs ADDED
@@ -0,0 +1,141 @@
1
+ "use strict";
2
+ var __defProp = Object.defineProperty;
3
+ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
4
+ var __getOwnPropNames = Object.getOwnPropertyNames;
5
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
6
+ var __export = (target, all) => {
7
+ for (var name in all)
8
+ __defProp(target, name, { get: all[name], enumerable: true });
9
+ };
10
+ var __copyProps = (to, from, except, desc) => {
11
+ if (from && typeof from === "object" || typeof from === "function") {
12
+ for (let key of __getOwnPropNames(from))
13
+ if (!__hasOwnProp.call(to, key) && key !== except)
14
+ __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
15
+ }
16
+ return to;
17
+ };
18
+ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
19
+
20
+ // src/utils.ts
21
+ var utils_exports = {};
22
+ __export(utils_exports, {
23
+ equals: () => equals,
24
+ getNormalizedOriginPath: () => getNormalizedOriginPath,
25
+ isValidRelativePath: () => isValidRelativePath,
26
+ onErrorHandler: () => onErrorHandler,
27
+ sanitizeURL: () => sanitizeURL,
28
+ toCastCase: () => toCastCase,
29
+ toISOString: () => toISOString,
30
+ toSnakeCase: () => toSnakeCase,
31
+ toUpperCase: () => toUpperCase
32
+ });
33
+ module.exports = __toCommonJS(utils_exports);
34
+ var import_router = require("@aura-stack/router");
35
+
36
+ // src/error.ts
37
+ var AuthError = class extends Error {
38
+ constructor(type, message) {
39
+ super(message);
40
+ this.type = type;
41
+ this.name = "AuthError";
42
+ }
43
+ };
44
+ var isAuthError = (error) => {
45
+ return error instanceof AuthError;
46
+ };
47
+
48
+ // src/utils.ts
49
+ var toSnakeCase = (str) => {
50
+ return str.replace(/([a-z0-9])([A-Z])/g, "$1_$2").replace(/([A-Z]+)([A-Z][a-z])/g, "$1_$2").toLowerCase().replace(/^_+/, "");
51
+ };
52
+ var toUpperCase = (str) => {
53
+ return str.toUpperCase();
54
+ };
55
+ var toCastCase = (obj, type = "snake") => {
56
+ return Object.entries(obj).reduce((previous, [key, value]) => {
57
+ const newKey = type === "snake" ? toSnakeCase(key) : toUpperCase(key);
58
+ return { ...previous, [newKey]: value };
59
+ }, {});
60
+ };
61
+ var equals = (a, b) => {
62
+ if (a === null || b === null || a === void 0 || b === void 0) return false;
63
+ return a === b;
64
+ };
65
+ var sanitizeURL = (url) => {
66
+ try {
67
+ let decodedURL = decodeURIComponent(url).trim();
68
+ const protocolMatch = decodedURL.match(/^([a-zA-Z][a-zA-Z0-9+.-]*:\/\/)/);
69
+ let protocol = "";
70
+ let rest = decodedURL;
71
+ if (protocolMatch) {
72
+ protocol = protocolMatch[1];
73
+ rest = decodedURL.slice(protocol.length);
74
+ const slashIndex = rest.indexOf("/");
75
+ if (slashIndex === -1) {
76
+ return protocol + rest;
77
+ }
78
+ const domain = rest.slice(0, slashIndex);
79
+ let path = rest.slice(slashIndex).replace(/\/\.\.\//g, "/").replace(/\/\.\.$/, "").replace(/\.{2,}/g, "").replace(/\/{2,}/g, "/");
80
+ if (path !== "/" && path.endsWith("/")) {
81
+ path = path.replace(/\/+$/, "/");
82
+ } else if (path !== "/") {
83
+ path = path.replace(/\/+$/, "");
84
+ }
85
+ return protocol + domain + path;
86
+ }
87
+ let sanitized = decodedURL.replace(/\/\.\.\//g, "/").replace(/\/\.\.$/, "").replace(/\.{2,}/g, "").replace(/\/{2,}/g, "/");
88
+ if (sanitized !== "/" && sanitized.endsWith("/")) {
89
+ sanitized = sanitized.replace(/\/+$/, "/");
90
+ } else if (sanitized !== "/") {
91
+ sanitized = sanitized.replace(/\/+$/, "");
92
+ }
93
+ return sanitized;
94
+ } catch {
95
+ return url.trim();
96
+ }
97
+ };
98
+ var isValidRelativePath = (path) => {
99
+ if (!path || typeof path !== "string") return false;
100
+ if (!path.startsWith("/") || path.includes("://") || path.includes("\r") || path.includes("\n")) return false;
101
+ if (/[\x00-\x1F\x7F]/.test(path) || path.includes("\0")) return false;
102
+ const sanitized = sanitizeURL(path);
103
+ if (sanitized.includes("..")) return false;
104
+ return true;
105
+ };
106
+ var onErrorHandler = (error) => {
107
+ if ((0, import_router.isRouterError)(error)) {
108
+ const { message, status, statusText } = error;
109
+ return Response.json({ error: "invalid_request", error_description: message }, { status, statusText });
110
+ }
111
+ if (isAuthError(error)) {
112
+ const { type, message } = error;
113
+ return Response.json({ error: type, error_description: message }, { status: 400 });
114
+ }
115
+ return Response.json({ error: "server_error", error_description: "An unexpected error occurred" }, { status: 500 });
116
+ };
117
+ var getNormalizedOriginPath = (path) => {
118
+ try {
119
+ const url = new URL(path);
120
+ url.hash = "";
121
+ url.search = "";
122
+ return `${url.origin}${url.pathname}`;
123
+ } catch {
124
+ return sanitizeURL(path);
125
+ }
126
+ };
127
+ var toISOString = (date) => {
128
+ return new Date(date).toISOString();
129
+ };
130
+ // Annotate the CommonJS export names for ESM import in node:
131
+ 0 && (module.exports = {
132
+ equals,
133
+ getNormalizedOriginPath,
134
+ isValidRelativePath,
135
+ onErrorHandler,
136
+ sanitizeURL,
137
+ toCastCase,
138
+ toISOString,
139
+ toSnakeCase,
140
+ toUpperCase
141
+ });
@@ -0,0 +1,45 @@
1
+ import { RouterConfig } from '@aura-stack/router';
2
+
3
+ declare const toSnakeCase: (str: string) => string;
4
+ declare const toUpperCase: (str: string) => string;
5
+ declare const toCastCase: <Obj extends Record<string, any>, 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]; };
6
+ declare const equals: (a: string | number | undefined | null, b: string | number | undefined | null) => boolean;
7
+ /**
8
+ * Sanitizes a URL by removing dangerous patterns that could be used for path traversal
9
+ * or other attacks. This function:
10
+ * - Decodes URL-encoded characters
11
+ * - Removes multiple consecutive slashes (preserving protocol slashes)
12
+ * - Removes path traversal patterns (..)
13
+ * - Removes trailing slashes (except root)
14
+ * - Trims whitespace
15
+ *
16
+ * @param url - The URL or path to sanitize
17
+ * @returns The sanitized URL or path
18
+ */
19
+ declare const sanitizeURL: (url: string) => string;
20
+ /**
21
+ * Validates that a path is a safe relative path to prevent open redirect attacks.
22
+ * A safe relative path must:
23
+ * - Start with '/'
24
+ * - Not contain protocol schemes (://)
25
+ * - Not contain newline characters
26
+ * - Not contain null bytes
27
+ * - Not be an absolute URL
28
+ *
29
+ * @param path - The path to validate
30
+ * @returns true if the path is safe, false otherwise
31
+ */
32
+ declare const isValidRelativePath: (path: string | undefined | null) => boolean;
33
+ declare const onErrorHandler: RouterConfig["onError"];
34
+ /**
35
+ * Extracts and normalizes the origin and pathname from a URL string.
36
+ * Removes query parameters and hash fragments for a clean path.
37
+ * Falls back to the original string if URL parsing fails.
38
+ *
39
+ * @param path - The URL or path string to process
40
+ * @returns The normalized URL with origin and pathname, or the original path
41
+ */
42
+ declare const getNormalizedOriginPath: (path: string) => string;
43
+ declare const toISOString: (date: Date | string | number) => string;
44
+
45
+ export { equals, getNormalizedOriginPath, isValidRelativePath, onErrorHandler, sanitizeURL, toCastCase, toISOString, toSnakeCase, toUpperCase };
package/dist/utils.js ADDED
@@ -0,0 +1,23 @@
1
+ import {
2
+ equals,
3
+ getNormalizedOriginPath,
4
+ isValidRelativePath,
5
+ onErrorHandler,
6
+ sanitizeURL,
7
+ toCastCase,
8
+ toISOString,
9
+ toSnakeCase,
10
+ toUpperCase
11
+ } from "./chunk-256KIVJL.js";
12
+ import "./chunk-FJUDBLCP.js";
13
+ export {
14
+ equals,
15
+ getNormalizedOriginPath,
16
+ isValidRelativePath,
17
+ onErrorHandler,
18
+ sanitizeURL,
19
+ toCastCase,
20
+ toISOString,
21
+ toSnakeCase,
22
+ toUpperCase
23
+ };
package/package.json ADDED
@@ -0,0 +1,70 @@
1
+ {
2
+ "name": "@aura-stack/auth",
3
+ "version": "0.1.0-rc.1",
4
+ "private": false,
5
+ "type": "module",
6
+ "description": "Core auth for @aura-stack/auth",
7
+ "repository": {
8
+ "type": "git",
9
+ "url": "git+https://github.com/aura-stack-ts/auth"
10
+ },
11
+ "publishConfig": {
12
+ "access": "public",
13
+ "registry": "https://registry.npmjs.org/@aura-stack/auth"
14
+ },
15
+ "files": [
16
+ "dist"
17
+ ],
18
+ "exports": {
19
+ ".": {
20
+ "types": "./dist/index.d.ts",
21
+ "import": "./dist/index.js",
22
+ "require": "./dist/index.cjs"
23
+ },
24
+ "./oauth/*": {
25
+ "types": "./dist/oauth/*.d.ts",
26
+ "import": "./dist/oauth/*.js",
27
+ "require": "./dist/oauth/*.cjs"
28
+ },
29
+ "./types": {
30
+ "types": "./dist/@types/index.d.ts",
31
+ "import": "./dist/@types/index.js",
32
+ "require": "./dist/@types/index.cjs"
33
+ }
34
+ },
35
+ "keywords": [
36
+ "auth",
37
+ "session",
38
+ "authentication"
39
+ ],
40
+ "author": "Aura Stack <aurastackjs@gmail.com> | Hernan Alvarado <halvaradop.dev@gmail.com>",
41
+ "homepage": "https://aura-stack-auth.vercel.app",
42
+ "bugs": {
43
+ "url": "https://github.com/aura-stack-ts/auth/issues"
44
+ },
45
+ "license": "MIT",
46
+ "dependencies": {
47
+ "@aura-stack/router": "^0.4.0",
48
+ "cookie": "^1.0.2",
49
+ "dotenv": "^17.2.3",
50
+ "zod": "^4.1.12",
51
+ "@aura-stack/jose": "0.1.0-rc.1"
52
+ },
53
+ "devDependencies": {
54
+ "@aura-stack/tsconfig": "0.0.0",
55
+ "@aura-stack/tsup-config": "0.0.0"
56
+ },
57
+ "scripts": {
58
+ "dev": "tsup --watch",
59
+ "build": "tsup",
60
+ "test": "vitest --run",
61
+ "test:watch": "vitest",
62
+ "test:coverage": "vitest --run --coverage",
63
+ "format": "prettier --write . --cache --cache-location .cache/.prettiercache",
64
+ "format:check": "prettier --check . --cache --cache-location .cache/.prettiercache",
65
+ "type-check": "tsc --noEmit",
66
+ "clean": "rm -rf dist",
67
+ "clean:cts": "rm -rf dist/*.cts",
68
+ "prepublish": "pnpm clean:cts"
69
+ }
70
+ }