@aura-stack/auth 0.4.0 → 0.5.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (149) hide show
  1. package/dist/@types/index.d.ts +6 -2
  2. package/dist/@types/router.d.d.ts +6 -2
  3. package/dist/actions/callback/access-token.cjs +103 -59
  4. package/dist/actions/callback/access-token.d.ts +7 -3
  5. package/dist/actions/callback/access-token.js +3 -3
  6. package/dist/actions/callback/callback.cjs +200 -134
  7. package/dist/actions/callback/callback.d.ts +32 -3
  8. package/dist/actions/callback/callback.js +11 -12
  9. package/dist/actions/callback/userinfo.cjs +103 -70
  10. package/dist/actions/callback/userinfo.d.ts +6 -2
  11. package/dist/actions/callback/userinfo.js +7 -8
  12. package/dist/actions/csrfToken/csrfToken.cjs +7 -15
  13. package/dist/actions/csrfToken/csrfToken.d.ts +3 -1
  14. package/dist/actions/csrfToken/csrfToken.js +7 -8
  15. package/dist/actions/index.cjs +502 -295
  16. package/dist/actions/index.d.ts +5 -2
  17. package/dist/actions/index.js +23 -20
  18. package/dist/actions/session/session.cjs +76 -24
  19. package/dist/actions/session/session.d.ts +3 -1
  20. package/dist/actions/session/session.js +6 -4
  21. package/dist/actions/signIn/authorization-url.cjs +288 -0
  22. package/dist/actions/signIn/authorization-url.d.ts +31 -0
  23. package/dist/actions/signIn/authorization-url.js +16 -0
  24. package/dist/actions/signIn/authorization.cjs +91 -132
  25. package/dist/actions/signIn/authorization.d.ts +17 -16
  26. package/dist/actions/signIn/authorization.js +8 -7
  27. package/dist/actions/signIn/signIn.cjs +319 -191
  28. package/dist/actions/signIn/signIn.d.ts +32 -3
  29. package/dist/actions/signIn/signIn.js +10 -9
  30. package/dist/actions/signOut/signOut.cjs +211 -212
  31. package/dist/actions/signOut/signOut.d.ts +9 -1
  32. package/dist/actions/signOut/signOut.js +9 -10
  33. package/dist/api/createApi.cjs +750 -0
  34. package/dist/api/createApi.d.ts +12 -0
  35. package/dist/api/createApi.js +19 -0
  36. package/dist/api/getSession.cjs +141 -0
  37. package/dist/api/getSession.d.ts +16 -0
  38. package/dist/api/getSession.js +10 -0
  39. package/dist/api/signIn.cjs +549 -0
  40. package/dist/api/signIn.d.ts +26 -0
  41. package/dist/api/signIn.js +15 -0
  42. package/dist/api/signOut.cjs +279 -0
  43. package/dist/api/signOut.d.ts +16 -0
  44. package/dist/api/signOut.js +13 -0
  45. package/dist/assert.cjs +42 -9
  46. package/dist/assert.d.ts +8 -4
  47. package/dist/assert.js +5 -5
  48. package/dist/{chunk-KJBAQZX2.js → chunk-2A5B7GWR.js} +44 -11
  49. package/dist/chunk-2GQLSIJ2.js +40 -0
  50. package/dist/chunk-2IR674WX.js +44 -0
  51. package/dist/chunk-3J5TUH2I.js +50 -0
  52. package/dist/chunk-4RWSYUKX.js +98 -0
  53. package/dist/chunk-5X7JZMEF.js +0 -0
  54. package/dist/{chunk-TZB6MUXN.js → chunk-7BE46WWS.js} +21 -11
  55. package/dist/chunk-7YYXFKLR.js +35 -0
  56. package/dist/chunk-C3A37LQC.js +33 -0
  57. package/dist/chunk-CITNGXDA.js +31 -0
  58. package/dist/chunk-CWX724AG.js +78 -0
  59. package/dist/chunk-D2CSIUKP.js +74 -0
  60. package/dist/{chunk-ICAZ4OVS.js → chunk-FPCVZUVG.js} +2 -2
  61. package/dist/{chunk-XGLBNXL4.js → chunk-GNNBM2WJ.js} +17 -9
  62. package/dist/chunk-JOCGX3RP.js +59 -0
  63. package/dist/chunk-KBXWTD6E.js +94 -0
  64. package/dist/{chunk-XUP6KKNG.js → chunk-LATR3NIV.js} +48 -37
  65. package/dist/chunk-LAYPUDQF.js +39 -0
  66. package/dist/chunk-LX3TJ2TJ.js +294 -0
  67. package/dist/{chunk-6MXFPFR3.js → chunk-NHZBQNRR.js} +19 -19
  68. package/dist/{chunk-TM5IPSNF.js → chunk-PDP3PHB3.js} +33 -19
  69. package/dist/chunk-PHYNROD4.js +47 -0
  70. package/dist/chunk-QQEKY4XP.js +29 -0
  71. package/dist/{chunk-VNCNJKS2.js → chunk-U4RK4LKJ.js} +82 -1
  72. package/dist/{chunk-RRLIF4PQ.js → chunk-U5663F2U.js} +16 -1
  73. package/dist/chunk-UN7X6SU5.js +53 -0
  74. package/dist/chunk-UZQJJD6A.js +100 -0
  75. package/dist/{chunk-NUDITUKX.js → chunk-V6LLEAR4.js} +22 -15
  76. package/dist/{chunk-4MYWAOLG.js → chunk-WHNDRO3N.js} +20 -1
  77. package/dist/{chunk-5W4BRQYG.js → chunk-XY5R3EHH.js} +6 -3
  78. package/dist/client/client.cjs +135 -0
  79. package/dist/client/client.d.ts +85 -0
  80. package/dist/client/client.js +9 -0
  81. package/dist/client/index.cjs +135 -0
  82. package/dist/client/index.d.ts +14 -0
  83. package/dist/client/index.js +10 -0
  84. package/dist/context.cjs +1237 -0
  85. package/dist/context.d.ts +16 -0
  86. package/dist/context.js +28 -0
  87. package/dist/cookie.cjs +33 -2
  88. package/dist/cookie.d.ts +9 -5
  89. package/dist/cookie.js +3 -2
  90. package/dist/createAuth.cjs +2320 -0
  91. package/dist/createAuth.d.ts +12 -0
  92. package/dist/createAuth.js +48 -0
  93. package/dist/env.cjs +24 -2
  94. package/dist/env.d.ts +4 -1
  95. package/dist/env.js +9 -3
  96. package/dist/errors.cjs +17 -0
  97. package/dist/errors.d.ts +13 -3
  98. package/dist/errors.js +5 -1
  99. package/dist/{index-CSyIJmCM.d.ts → index-_aXtxb_s.d.ts} +383 -13
  100. package/dist/index.cjs +2135 -1547
  101. package/dist/index.d.ts +9 -30
  102. package/dist/index.js +46 -119
  103. package/dist/jose.cjs +52 -14
  104. package/dist/jose.d.ts +12 -25
  105. package/dist/jose.js +11 -3
  106. package/dist/logger.cjs +132 -0
  107. package/dist/logger.d.ts +6 -2
  108. package/dist/logger.js +10 -1
  109. package/dist/oauth/atlassian.cjs +57 -0
  110. package/dist/oauth/atlassian.d.ts +12 -0
  111. package/dist/oauth/atlassian.js +6 -0
  112. package/dist/oauth/bitbucket.d.ts +6 -2
  113. package/dist/oauth/discord.d.ts +6 -2
  114. package/dist/oauth/dropbox.cjs +53 -0
  115. package/dist/oauth/dropbox.d.ts +12 -0
  116. package/dist/oauth/dropbox.js +6 -0
  117. package/dist/oauth/figma.d.ts +6 -2
  118. package/dist/oauth/github.d.ts +6 -2
  119. package/dist/oauth/gitlab.d.ts +6 -2
  120. package/dist/oauth/index.cjs +278 -88
  121. package/dist/oauth/index.d.ts +6 -2
  122. package/dist/oauth/index.js +27 -11
  123. package/dist/oauth/mailchimp.d.ts +6 -2
  124. package/dist/oauth/notion.cjs +131 -0
  125. package/dist/oauth/notion.d.ts +12 -0
  126. package/dist/oauth/notion.js +9 -0
  127. package/dist/oauth/pinterest.d.ts +6 -2
  128. package/dist/oauth/spotify.d.ts +6 -2
  129. package/dist/oauth/strava.d.ts +6 -2
  130. package/dist/oauth/twitch.cjs +95 -0
  131. package/dist/oauth/twitch.d.ts +12 -0
  132. package/dist/oauth/twitch.js +7 -0
  133. package/dist/oauth/x.d.ts +6 -2
  134. package/dist/schemas.cjs +84 -51
  135. package/dist/schemas.d.ts +103 -23
  136. package/dist/schemas.js +1 -1
  137. package/dist/secure.cjs +36 -36
  138. package/dist/secure.d.ts +10 -4
  139. package/dist/secure.js +7 -6
  140. package/dist/utils.cjs +109 -3
  141. package/dist/utils.d.ts +15 -4
  142. package/dist/utils.js +11 -4
  143. package/package.json +9 -5
  144. package/dist/chunk-4EKY7655.js +0 -123
  145. package/dist/chunk-7QF22LHP.js +0 -67
  146. package/dist/chunk-ALG3GIV4.js +0 -95
  147. package/dist/chunk-FRJFWTOY.js +0 -70
  148. package/dist/chunk-PHFH2MGS.js +0 -36
  149. package/dist/chunk-QQVSRXGX.js +0 -149
@@ -0,0 +1,279 @@
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/api/signOut.ts
21
+ var signOut_exports = {};
22
+ __export(signOut_exports, {
23
+ signOut: () => signOut
24
+ });
25
+ module.exports = __toCommonJS(signOut_exports);
26
+
27
+ // src/env.ts
28
+ var import_meta = {};
29
+ var env = new Proxy({}, {
30
+ get(_, prop) {
31
+ if (typeof prop !== "string") return void 0;
32
+ const hasProperty = (process2) => {
33
+ return process2 && Object.prototype.hasOwnProperty.call(process2, prop);
34
+ };
35
+ try {
36
+ if (typeof process !== "undefined" && hasProperty(process.env)) {
37
+ return process.env[prop];
38
+ }
39
+ if (typeof import_meta !== "undefined" && hasProperty(import_meta.env)) {
40
+ return import_meta.env[prop];
41
+ }
42
+ if (typeof Deno !== "undefined" && Deno.env?.get) {
43
+ return Deno.env.get(prop);
44
+ }
45
+ if (typeof Bun !== "undefined" && hasProperty(Bun.env)) {
46
+ return Bun.env[prop];
47
+ }
48
+ const globalValue = globalThis[prop];
49
+ return typeof globalValue === "string" ? globalValue : void 0;
50
+ } catch {
51
+ return void 0;
52
+ }
53
+ }
54
+ });
55
+
56
+ // src/cookie.ts
57
+ var import_cookie = require("@aura-stack/router/cookie");
58
+
59
+ // src/errors.ts
60
+ var AuthInternalError = class extends Error {
61
+ type = "AUTH_INTERNAL_ERROR";
62
+ code;
63
+ constructor(code, message, options) {
64
+ super(message, options);
65
+ this.code = code;
66
+ this.name = new.target.name;
67
+ Error.captureStackTrace(this, new.target);
68
+ }
69
+ };
70
+ var AuthSecurityError = class extends Error {
71
+ type = "AUTH_SECURITY_ERROR";
72
+ code;
73
+ constructor(code, message, options) {
74
+ super(message, options);
75
+ this.code = code;
76
+ this.name = new.target.name;
77
+ Error.captureStackTrace(this, new.target);
78
+ }
79
+ };
80
+
81
+ // src/cookie.ts
82
+ var defaultCookieOptions = {
83
+ httpOnly: true,
84
+ sameSite: "lax",
85
+ path: "/",
86
+ maxAge: 60 * 60 * 24 * 15
87
+ };
88
+ var oauthCookieOptions = {
89
+ httpOnly: true,
90
+ maxAge: 5 * 60,
91
+ sameSite: "lax",
92
+ expires: new Date(Date.now() + 5 * 60 * 1e3)
93
+ };
94
+ var expiredCookieAttributes = {
95
+ ...defaultCookieOptions,
96
+ expires: /* @__PURE__ */ new Date(0),
97
+ maxAge: 0,
98
+ secure: true
99
+ };
100
+ var getCookie = (request, cookieName) => {
101
+ const cookies = request instanceof Request ? request.headers.get("Cookie") : request.get("Cookie");
102
+ if (!cookies) {
103
+ throw new AuthInternalError("COOKIE_NOT_FOUND", "No cookies found. There is no active session");
104
+ }
105
+ const value = (0, import_cookie.parse)(cookies)[cookieName];
106
+ if (!value) {
107
+ throw new AuthInternalError("COOKIE_NOT_FOUND", `Cookie "${cookieName}" not found. There is no active session`);
108
+ }
109
+ return value;
110
+ };
111
+
112
+ // src/utils.ts
113
+ var import_router = require("@aura-stack/router");
114
+
115
+ // src/assert.ts
116
+ var import_crypto = require("@aura-stack/jose/crypto");
117
+ var isJWTPayloadWithToken = (payload) => {
118
+ return typeof payload === "object" && payload !== null && "token" in payload && typeof payload?.token === "string";
119
+ };
120
+ var timingSafeEqual = (a, b) => {
121
+ const bufferA = import_crypto.encoder.encode(a);
122
+ const bufferB = import_crypto.encoder.encode(b);
123
+ const len = Math.max(bufferA.length, bufferB.length);
124
+ let diff = 0;
125
+ for (let i = 0; i < len; i++) {
126
+ diff |= (bufferA[i] ?? 0) ^ (bufferB[i] ?? 0);
127
+ }
128
+ return diff === 0 && bufferA.length === bufferB.length;
129
+ };
130
+
131
+ // src/utils.ts
132
+ var equals = (a, b) => {
133
+ if (a === null || b === null || a === void 0 || b === void 0) return false;
134
+ return a === b;
135
+ };
136
+ var getErrorName = (error) => {
137
+ if (error instanceof Error) {
138
+ return error.name;
139
+ }
140
+ return typeof error === "string" ? error : "UnknownError";
141
+ };
142
+
143
+ // src/jose.ts
144
+ var import_jose = require("@aura-stack/jose");
145
+ var import_jose2 = require("@aura-stack/jose/jose");
146
+ var import_crypto2 = require("@aura-stack/jose/crypto");
147
+ var jwtVerificationOptions = {
148
+ algorithms: ["HS256"],
149
+ typ: "JWT"
150
+ };
151
+
152
+ // src/secure.ts
153
+ var verifyCSRF = async (jose, cookie, header) => {
154
+ try {
155
+ const cookiePayload = await jose.verifyJWS(cookie, jwtVerificationOptions);
156
+ const headerPayload = await jose.verifyJWS(header, jwtVerificationOptions);
157
+ if (!isJWTPayloadWithToken(cookiePayload)) {
158
+ throw new AuthSecurityError("CSRF_TOKEN_INVALID", "Cookie payload missing token field.");
159
+ }
160
+ if (!isJWTPayloadWithToken(headerPayload)) {
161
+ throw new AuthSecurityError("CSRF_TOKEN_INVALID", "Header payload missing token field.");
162
+ }
163
+ if (!equals(cookiePayload.token.length, headerPayload.token.length)) {
164
+ throw new AuthSecurityError("CSRF_TOKEN_INVALID", "The CSRF tokens do not match.");
165
+ }
166
+ if (!timingSafeEqual(cookiePayload.token, headerPayload.token)) {
167
+ throw new AuthSecurityError("CSRF_TOKEN_INVALID", "The CSRF tokens do not match.");
168
+ }
169
+ return true;
170
+ } catch {
171
+ throw new AuthSecurityError("CSRF_TOKEN_INVALID", "The CSRF tokens do not match.");
172
+ }
173
+ };
174
+
175
+ // src/headers.ts
176
+ var cacheControl = {
177
+ "Cache-Control": "no-store",
178
+ Pragma: "no-cache",
179
+ Expires: "0",
180
+ Vary: "Cookie"
181
+ };
182
+ var contentSecurityPolicy = {
183
+ "Content-Security-Policy": [
184
+ "default-src 'none'",
185
+ "script-src 'self'",
186
+ "frame-src 'none'",
187
+ "object-src 'none'",
188
+ "frame-ancestors 'none'",
189
+ "base-uri 'none'"
190
+ ].join("; ")
191
+ };
192
+ var secureHeaders = {
193
+ "X-Content-Type-Options": "nosniff",
194
+ "X-Frame-Options": "DENY",
195
+ "Referrer-Policy": "strict-origin-when-cross-origin"
196
+ };
197
+ var secureApiHeaders = {
198
+ ...cacheControl,
199
+ ...contentSecurityPolicy,
200
+ ...secureHeaders
201
+ };
202
+
203
+ // src/api/signOut.ts
204
+ var import_router2 = require("@aura-stack/router");
205
+ var signOut = async ({
206
+ ctx,
207
+ headers: headersInit,
208
+ redirectTo = "/",
209
+ skipCSRFCheck = false
210
+ }) => {
211
+ const headers = new Headers(headersInit);
212
+ const header = headers.get("X-CSRF-Token");
213
+ let session = null;
214
+ let csrfToken = null;
215
+ try {
216
+ session = getCookie(headers, ctx.cookies.sessionToken.name);
217
+ } catch {
218
+ throw new AuthSecurityError("SESSION_TOKEN_MISSING", "The sessionToken is missing.");
219
+ }
220
+ try {
221
+ csrfToken = getCookie(headers, ctx.cookies.csrfToken.name);
222
+ } catch {
223
+ throw new AuthSecurityError("CSRF_TOKEN_MISSING", "The CSRF token is missing.");
224
+ }
225
+ ctx?.logger?.log("SIGN_OUT_ATTEMPT", {
226
+ structuredData: {
227
+ has_session: Boolean(session),
228
+ has_csrf_token: Boolean(csrfToken),
229
+ has_csrf_header: Boolean(header),
230
+ skip_csrf_check: skipCSRFCheck
231
+ }
232
+ });
233
+ if (!session) {
234
+ ctx?.logger?.log("SESSION_TOKEN_MISSING");
235
+ throw new AuthSecurityError("SESSION_TOKEN_MISSING", "The sessionToken is missing.");
236
+ }
237
+ if (!skipCSRFCheck) {
238
+ if (!csrfToken) {
239
+ ctx?.logger?.log("CSRF_TOKEN_MISSING");
240
+ throw new AuthSecurityError("CSRF_TOKEN_MISSING", "The CSRF token is missing.");
241
+ }
242
+ if (!header) {
243
+ ctx?.logger?.log("CSRF_HEADER_MISSING");
244
+ throw new AuthSecurityError("CSRF_HEADER_MISSING", "The CSRF header is missing.");
245
+ }
246
+ try {
247
+ await verifyCSRF(ctx.jose, csrfToken, header);
248
+ } catch (error) {
249
+ ctx?.logger?.log("CSRF_TOKEN_INVALID", { structuredData: { error_type: getErrorName(error) } });
250
+ throw new AuthSecurityError("CSRF_TOKEN_INVALID", "CSRF token verification failed");
251
+ }
252
+ ctx?.logger?.log("SIGN_OUT_CSRF_VERIFIED");
253
+ } else {
254
+ try {
255
+ await ctx.jose.verifyJWS(csrfToken);
256
+ } catch (error) {
257
+ ctx?.logger?.log("CSRF_TOKEN_INVALID", { structuredData: { error_type: getErrorName(error) } });
258
+ throw new AuthSecurityError("CSRF_TOKEN_INVALID", "CSRF token verification failed");
259
+ }
260
+ }
261
+ try {
262
+ await ctx.jose.decodeJWT(session);
263
+ ctx?.logger?.log("SIGN_OUT_SUCCESS");
264
+ } catch (error) {
265
+ ctx?.logger?.log("INVALID_JWT_TOKEN", { structuredData: { error_type: getErrorName(error) } });
266
+ }
267
+ const headersList = new import_router2.HeadersBuilder(secureApiHeaders).setHeader("Location", redirectTo).setCookie(ctx.cookies.csrfToken.name, "", expiredCookieAttributes).setCookie(ctx.cookies.sessionToken.name, "", expiredCookieAttributes).toHeaders();
268
+ return Response.json(
269
+ { redirect: Boolean(redirectTo), url: redirectTo },
270
+ {
271
+ status: 202,
272
+ headers: headersList
273
+ }
274
+ );
275
+ };
276
+ // Annotate the CommonJS export names for ESM import in node:
277
+ 0 && (module.exports = {
278
+ signOut
279
+ });
@@ -0,0 +1,16 @@
1
+ import { F as FunctionAPIContext, i as SignOutAPIOptions } from '../index-_aXtxb_s.js';
2
+ import 'zod';
3
+ import '../schemas.js';
4
+ import 'zod/v4';
5
+ import '@aura-stack/jose';
6
+ import '@aura-stack/jose/jose';
7
+ import '@aura-stack/jose/crypto';
8
+ import '@aura-stack/router/cookie';
9
+ import '../@types/utility.js';
10
+ import 'jose';
11
+ import '@aura-stack/router';
12
+ import 'zod/v4/core';
13
+
14
+ declare const signOut: ({ ctx, headers: headersInit, redirectTo, skipCSRFCheck, }: FunctionAPIContext<SignOutAPIOptions>) => Promise<Response>;
15
+
16
+ export { signOut };
@@ -0,0 +1,13 @@
1
+ import {
2
+ signOut
3
+ } from "../chunk-KBXWTD6E.js";
4
+ import "../chunk-V6LLEAR4.js";
5
+ import "../chunk-UZQJJD6A.js";
6
+ import "../chunk-LX3TJ2TJ.js";
7
+ import "../chunk-XY5R3EHH.js";
8
+ import "../chunk-WHNDRO3N.js";
9
+ import "../chunk-U5663F2U.js";
10
+ import "../chunk-EBAMFRB7.js";
11
+ export {
12
+ signOut
13
+ };
package/dist/assert.cjs CHANGED
@@ -28,20 +28,51 @@ __export(assert_exports, {
28
28
  isTrustedOrigin: () => isTrustedOrigin,
29
29
  isValidURL: () => isValidURL,
30
30
  patternToRegex: () => patternToRegex,
31
- safeEquals: () => safeEquals,
31
+ timingSafeEqual: () => timingSafeEqual,
32
32
  unsafeChars: () => unsafeChars
33
33
  });
34
34
  module.exports = __toCommonJS(assert_exports);
35
35
 
36
36
  // src/utils.ts
37
37
  var import_router = require("@aura-stack/router");
38
+
39
+ // src/env.ts
40
+ var import_meta = {};
41
+ var env = new Proxy({}, {
42
+ get(_, prop) {
43
+ if (typeof prop !== "string") return void 0;
44
+ const hasProperty = (process2) => {
45
+ return process2 && Object.prototype.hasOwnProperty.call(process2, prop);
46
+ };
47
+ try {
48
+ if (typeof process !== "undefined" && hasProperty(process.env)) {
49
+ return process.env[prop];
50
+ }
51
+ if (typeof import_meta !== "undefined" && hasProperty(import_meta.env)) {
52
+ return import_meta.env[prop];
53
+ }
54
+ if (typeof Deno !== "undefined" && Deno.env?.get) {
55
+ return Deno.env.get(prop);
56
+ }
57
+ if (typeof Bun !== "undefined" && hasProperty(Bun.env)) {
58
+ return Bun.env[prop];
59
+ }
60
+ const globalValue = globalThis[prop];
61
+ return typeof globalValue === "string" ? globalValue : void 0;
62
+ } catch {
63
+ return void 0;
64
+ }
65
+ }
66
+ });
67
+
68
+ // src/utils.ts
38
69
  var equals = (a, b) => {
39
70
  if (a === null || b === null || a === void 0 || b === void 0) return false;
40
71
  return a === b;
41
72
  };
42
73
 
43
74
  // src/assert.ts
44
- var import_crypto = require("crypto");
75
+ var import_crypto = require("@aura-stack/jose/crypto");
45
76
  var isFalsy = (value) => {
46
77
  return value === false || value === 0 || value === "" || value === null || value === void 0 || Number.isNaN(value);
47
78
  };
@@ -138,13 +169,15 @@ var isTrustedOrigin = (url, trustedOrigins) => {
138
169
  }
139
170
  return false;
140
171
  };
141
- var safeEquals = (a, b) => {
142
- const bufferA = Buffer.from(a);
143
- const bufferB = Buffer.from(b);
144
- if (bufferA.length !== bufferB.length) {
145
- return false;
172
+ var timingSafeEqual = (a, b) => {
173
+ const bufferA = import_crypto.encoder.encode(a);
174
+ const bufferB = import_crypto.encoder.encode(b);
175
+ const len = Math.max(bufferA.length, bufferB.length);
176
+ let diff = 0;
177
+ for (let i = 0; i < len; i++) {
178
+ diff |= (bufferA[i] ?? 0) ^ (bufferB[i] ?? 0);
146
179
  }
147
- return (0, import_crypto.timingSafeEqual)(bufferA, bufferB);
180
+ return diff === 0 && bufferA.length === bufferB.length;
148
181
  };
149
182
  // Annotate the CommonJS export names for ESM import in node:
150
183
  0 && (module.exports = {
@@ -156,6 +189,6 @@ var safeEquals = (a, b) => {
156
189
  isTrustedOrigin,
157
190
  isValidURL,
158
191
  patternToRegex,
159
- safeEquals,
192
+ timingSafeEqual,
160
193
  unsafeChars
161
194
  });
package/dist/assert.d.ts CHANGED
@@ -1,11 +1,15 @@
1
- import { J as JWTPayloadWithToken } from './index-CSyIJmCM.js';
1
+ import { J as JWTPayloadWithToken } from './index-_aXtxb_s.js';
2
2
  import 'zod';
3
3
  import './schemas.js';
4
- import './jose.js';
4
+ import 'zod/v4';
5
5
  import '@aura-stack/jose';
6
6
  import '@aura-stack/jose/jose';
7
+ import '@aura-stack/jose/crypto';
7
8
  import '@aura-stack/router/cookie';
8
9
  import './@types/utility.js';
10
+ import 'jose';
11
+ import '@aura-stack/router';
12
+ import 'zod/v4/core';
9
13
 
10
14
  declare const isFalsy: (value: unknown) => boolean;
11
15
  declare const isRequest: (value: unknown) => value is Request;
@@ -28,6 +32,6 @@ declare const patternToRegex: (pattern: string) => RegExp | null;
28
32
  * @param trustedOrigins - Array of exact URLs or patterns (e.g. `https://*.example.com`)
29
33
  */
30
34
  declare const isTrustedOrigin: (url: string, trustedOrigins: string[]) => boolean;
31
- declare const safeEquals: (a: string, b: string) => boolean;
35
+ declare const timingSafeEqual: (a: string, b: string) => boolean;
32
36
 
33
- export { isFalsy, isJWTPayloadWithToken, isRelativeURL, isRequest, isSameOrigin, isTrustedOrigin, isValidURL, patternToRegex, safeEquals, unsafeChars };
37
+ export { isFalsy, isJWTPayloadWithToken, isRelativeURL, isRequest, isSameOrigin, isTrustedOrigin, isValidURL, patternToRegex, timingSafeEqual, unsafeChars };
package/dist/assert.js CHANGED
@@ -7,11 +7,11 @@ import {
7
7
  isTrustedOrigin,
8
8
  isValidURL,
9
9
  patternToRegex,
10
- safeEquals,
10
+ timingSafeEqual,
11
11
  unsafeChars
12
- } from "./chunk-4EKY7655.js";
13
- import "./chunk-QQVSRXGX.js";
14
- import "./chunk-RRLIF4PQ.js";
12
+ } from "./chunk-LX3TJ2TJ.js";
13
+ import "./chunk-WHNDRO3N.js";
14
+ import "./chunk-U5663F2U.js";
15
15
  export {
16
16
  isFalsy,
17
17
  isJWTPayloadWithToken,
@@ -21,6 +21,6 @@ export {
21
21
  isTrustedOrigin,
22
22
  isValidURL,
23
23
  patternToRegex,
24
- safeEquals,
24
+ timingSafeEqual,
25
25
  unsafeChars
26
26
  };
@@ -1,23 +1,56 @@
1
1
  // src/schemas.ts
2
- import { object, string, enum as options, number, z, null as nullable } from "zod";
2
+ import { object, string, enum as options, number, z, null as nullable, union, array } from "zod/v4";
3
+ var AuthorizeConfigSchema = z.union([
4
+ string().url(),
5
+ object({
6
+ url: string().url(),
7
+ params: object({
8
+ responseType: options(["code", "token", "id_token", "refresh_token"]).optional(),
9
+ scope: string().optional()
10
+ })
11
+ })
12
+ ]);
13
+ var AccessTokenConfigSchema = z.union([
14
+ string().url(),
15
+ object({
16
+ url: string().url(),
17
+ headers: z.record(string(), string()).optional()
18
+ })
19
+ ]);
20
+ var UserInfoConfigSchema = z.union([
21
+ string().url(),
22
+ object({
23
+ url: string().url(),
24
+ headers: z.record(string(), string()).optional(),
25
+ method: string().optional()
26
+ })
27
+ ]);
3
28
  var OAuthProviderCredentialsSchema = object({
4
29
  id: string(),
5
30
  name: string(),
6
- authorizeURL: string().url(),
7
- accessToken: string().url(),
8
- scope: string(),
9
- userInfo: string().url(),
10
- responseType: options(["code", "token", "id_token"]),
31
+ authorize: AuthorizeConfigSchema.optional(),
32
+ /** @deprecated */
33
+ authorizeURL: string().url().optional(),
34
+ accessToken: AccessTokenConfigSchema,
35
+ /** @deprecated */
36
+ scope: string().optional(),
37
+ userInfo: UserInfoConfigSchema,
38
+ /** @deprecated */
39
+ responseType: options(["code", "token", "id_token", "refresh_token"]).optional(),
11
40
  clientId: string(),
12
41
  clientSecret: string(),
13
42
  profile: z.function().optional()
14
43
  });
15
44
  var OAuthProviderConfigSchema = object({
16
- authorizeURL: string().url(),
17
- accessToken: string().url(),
45
+ authorize: AuthorizeConfigSchema.optional(),
46
+ /** @deprecated */
47
+ authorizeURL: string().url().optional(),
48
+ accessToken: AccessTokenConfigSchema,
49
+ /** @deprecated */
18
50
  scope: string().optional(),
19
- userInfo: string().url(),
20
- responseType: options(["code", "token", "id_token"]),
51
+ userInfo: UserInfoConfigSchema,
52
+ /** @deprecated */
53
+ responseType: options(["code", "token", "id_token", "refresh_token"]).optional(),
21
54
  clientId: string(),
22
55
  clientSecret: string()
23
56
  });
@@ -55,7 +88,7 @@ var OAuthAccessTokenResponse = object({
55
88
  token_type: string().optional(),
56
89
  expires_in: number().optional(),
57
90
  refresh_token: string().optional(),
58
- scope: string().optional().or(nullable())
91
+ scope: union([string().optional().or(nullable()), array(string()).optional()])
59
92
  });
60
93
  var OAuthAccessTokenErrorResponse = object({
61
94
  error: options([
@@ -0,0 +1,40 @@
1
+ import {
2
+ getEnv
3
+ } from "./chunk-WHNDRO3N.js";
4
+
5
+ // src/oauth/twitch.ts
6
+ var twitch = (options) => {
7
+ const clientId = options?.clientId ?? getEnv("TWITCH_CLIENT_ID");
8
+ return {
9
+ id: "twitch",
10
+ name: "Twitch",
11
+ authorize: {
12
+ url: "https://id.twitch.tv/oauth2/authorize",
13
+ params: { scope: "user:read:email", responseType: "code" }
14
+ },
15
+ accessToken: "https://id.twitch.tv/oauth2/token",
16
+ userInfo: {
17
+ url: "https://api.twitch.tv/helix/users",
18
+ headers: {
19
+ "Client-ID": clientId
20
+ }
21
+ },
22
+ profile(profile) {
23
+ const user = profile.data[0];
24
+ if (!user) {
25
+ throw new Error("No user data found in Twitch profile response");
26
+ }
27
+ return {
28
+ sub: user.id,
29
+ name: user.display_name,
30
+ email: user.email,
31
+ picture: user.profile_image_url
32
+ };
33
+ },
34
+ ...options
35
+ };
36
+ };
37
+
38
+ export {
39
+ twitch
40
+ };
@@ -0,0 +1,44 @@
1
+ import {
2
+ createBuiltInOAuthProviders
3
+ } from "./chunk-PDP3PHB3.js";
4
+ import {
5
+ createProxyLogger
6
+ } from "./chunk-U4RK4LKJ.js";
7
+ import {
8
+ createJoseInstance
9
+ } from "./chunk-UZQJJD6A.js";
10
+ import {
11
+ createCookieStore
12
+ } from "./chunk-XY5R3EHH.js";
13
+ import {
14
+ getEnv,
15
+ getEnvArray,
16
+ getEnvBoolean
17
+ } from "./chunk-WHNDRO3N.js";
18
+
19
+ // src/context.ts
20
+ var createContext = (config) => {
21
+ const trustedProxyHeadersEnv = getEnv("TRUSTED_PROXY_HEADERS");
22
+ const useProxyHeaders = trustedProxyHeadersEnv === void 0 ? config?.trustedProxyHeaders ?? false : getEnvBoolean("TRUSTED_PROXY_HEADERS");
23
+ const logger = createProxyLogger(config);
24
+ const cookiePrefix = config?.cookies?.prefix;
25
+ const cookieOverrides = config?.cookies?.overrides ?? {};
26
+ const secureCookieStore = createCookieStore(true, cookiePrefix, cookieOverrides, logger);
27
+ const standardCookieStore = createCookieStore(false, cookiePrefix, cookieOverrides, logger);
28
+ return {
29
+ oauth: createBuiltInOAuthProviders(config?.oauth),
30
+ cookies: standardCookieStore,
31
+ jose: createJoseInstance(config?.secret),
32
+ secret: config?.secret,
33
+ basePath: config?.basePath ?? "/auth",
34
+ trustedProxyHeaders: useProxyHeaders,
35
+ trustedOrigins: getEnvArray("TRUSTED_ORIGINS").length > 0 ? getEnvArray("TRUSTED_ORIGINS") : config?.trustedOrigins,
36
+ logger,
37
+ cookieConfig: { secure: secureCookieStore, standard: standardCookieStore },
38
+ baseURL: config?.baseURL
39
+ };
40
+ };
41
+
42
+ export {
43
+ createContext
44
+ };
@@ -0,0 +1,50 @@
1
+ import {
2
+ createRedirectTo
3
+ } from "./chunk-LATR3NIV.js";
4
+ import {
5
+ signOut
6
+ } from "./chunk-KBXWTD6E.js";
7
+ import {
8
+ getBaseURL
9
+ } from "./chunk-LX3TJ2TJ.js";
10
+
11
+ // src/actions/signOut/signOut.ts
12
+ import { z } from "zod/v4";
13
+ import { createEndpoint, createEndpointConfig } from "@aura-stack/router";
14
+ var config = createEndpointConfig({
15
+ schemas: {
16
+ searchParams: z.object({
17
+ token_type_hint: z.literal("session_token"),
18
+ redirectTo: z.string().optional()
19
+ })
20
+ }
21
+ });
22
+ var signOutAction = createEndpoint(
23
+ "POST",
24
+ "/signOut",
25
+ async (ctx) => {
26
+ const {
27
+ request,
28
+ searchParams: { redirectTo },
29
+ context
30
+ } = ctx;
31
+ const baseURL = getBaseURL(request);
32
+ const location = await createRedirectTo(
33
+ new Request(baseURL, {
34
+ headers: request.headers
35
+ }),
36
+ redirectTo,
37
+ context
38
+ );
39
+ return await signOut({
40
+ ctx: context,
41
+ headers: request.headers,
42
+ redirectTo: location
43
+ });
44
+ },
45
+ config
46
+ );
47
+
48
+ export {
49
+ signOutAction
50
+ };