@aura-stack/auth 0.4.0-rc.5 → 0.4.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.
- package/dist/@types/index.d.ts +4 -3
- package/dist/@types/router.d.cjs +0 -17
- package/dist/@types/router.d.d.ts +3 -2
- package/dist/@types/router.d.js +0 -1
- package/dist/actions/callback/access-token.cjs +40 -25
- package/dist/actions/callback/access-token.d.ts +4 -3
- package/dist/actions/callback/access-token.js +3 -4
- package/dist/actions/callback/callback.cjs +287 -77
- package/dist/actions/callback/callback.d.ts +5 -26
- package/dist/actions/callback/callback.js +13 -10
- package/dist/actions/callback/userinfo.cjs +68 -7
- package/dist/actions/callback/userinfo.d.ts +4 -3
- package/dist/actions/callback/userinfo.js +8 -6
- package/dist/actions/csrfToken/csrfToken.cjs +63 -4
- package/dist/actions/csrfToken/csrfToken.d.ts +1 -3
- package/dist/actions/csrfToken/csrfToken.js +8 -6
- package/dist/actions/index.cjs +400 -175
- package/dist/actions/index.d.ts +3 -2
- package/dist/actions/index.js +21 -19
- package/dist/actions/session/session.cjs +40 -11
- package/dist/actions/session/session.d.ts +1 -3
- package/dist/actions/session/session.js +4 -4
- package/dist/actions/signIn/authorization.cjs +171 -132
- package/dist/actions/signIn/authorization.d.ts +21 -11
- package/dist/actions/signIn/authorization.js +8 -6
- package/dist/actions/signIn/signIn.cjs +220 -113
- package/dist/actions/signIn/signIn.d.ts +5 -25
- package/dist/actions/signIn/signIn.js +9 -7
- package/dist/actions/signOut/signOut.cjs +268 -119
- package/dist/actions/signOut/signOut.d.ts +1 -9
- package/dist/actions/signOut/signOut.js +10 -8
- package/dist/assert.cjs +117 -5
- package/dist/assert.d.ts +22 -3
- package/dist/assert.js +17 -3
- package/dist/chunk-4EKY7655.js +123 -0
- package/dist/chunk-4MYWAOLG.js +31 -0
- package/dist/chunk-4YHJ4IEQ.js +25 -0
- package/dist/chunk-54CZPKR4.js +25 -0
- package/dist/chunk-5LZ7TOM3.js +25 -0
- package/dist/{chunk-W6LG7BFW.js → chunk-5W4BRQYG.js} +24 -20
- package/dist/chunk-6MXFPFR3.js +143 -0
- package/dist/{chunk-3EUWD5BB.js → chunk-7QF22LHP.js} +13 -9
- package/dist/chunk-ALG3GIV4.js +95 -0
- package/dist/chunk-E6G5YCI6.js +25 -0
- package/dist/chunk-EBAMFRB7.js +34 -0
- package/dist/chunk-EEE7UM5T.js +25 -0
- package/dist/{chunk-TLE4PXY3.js → chunk-FRJFWTOY.js} +38 -7
- package/dist/chunk-FW4W3REU.js +25 -0
- package/dist/{chunk-HT4YLL7N.js → chunk-ICAZ4OVS.js} +10 -8
- package/dist/chunk-IPKO6UQN.js +25 -0
- package/dist/{chunk-YRCB5FLE.js → chunk-KJBAQZX2.js} +13 -0
- package/dist/chunk-KMMAZFSJ.js +25 -0
- package/dist/chunk-LDU7A2JE.js +25 -0
- package/dist/{chunk-N2APGLXA.js → chunk-NUDITUKX.js} +18 -16
- package/dist/chunk-OVHNRULD.js +33 -0
- package/dist/{chunk-JVFTCTTE.js → chunk-PHFH2MGS.js} +12 -9
- package/dist/chunk-QQVSRXGX.js +149 -0
- package/dist/chunk-TM5IPSNF.js +113 -0
- package/dist/{chunk-GA2SMTJO.js → chunk-TZB6MUXN.js} +33 -13
- package/dist/chunk-VNCNJKS2.js +267 -0
- package/dist/{chunk-IVET23KF.js → chunk-XGLBNXL4.js} +31 -14
- package/dist/chunk-XUP6KKNG.js +106 -0
- package/dist/cookie.cjs +24 -20
- package/dist/cookie.d.ts +4 -3
- package/dist/cookie.js +1 -1
- package/dist/env.cjs +56 -0
- package/dist/env.d.ts +7 -0
- package/dist/env.js +6 -0
- package/dist/errors.d.ts +4 -3
- package/dist/headers.cjs +28 -2
- package/dist/headers.d.ts +25 -1
- package/dist/headers.js +9 -3
- package/dist/{index-B8jeIElf.d.ts → index-CSyIJmCM.d.ts} +373 -45
- package/dist/index.cjs +1128 -483
- package/dist/index.d.ts +7 -67
- package/dist/index.js +83 -42
- package/dist/jose.cjs +62 -25
- package/dist/jose.d.ts +7 -5
- package/dist/jose.js +8 -6
- package/dist/logger.cjs +292 -0
- package/dist/logger.d.ts +8 -0
- package/dist/logger.js +8 -0
- package/dist/oauth/bitbucket.cjs +19 -15
- package/dist/oauth/bitbucket.d.ts +3 -2
- package/dist/oauth/bitbucket.js +1 -1
- package/dist/oauth/discord.cjs +27 -24
- package/dist/oauth/discord.d.ts +3 -2
- package/dist/oauth/discord.js +1 -1
- package/dist/oauth/figma.cjs +19 -16
- package/dist/oauth/figma.d.ts +3 -2
- package/dist/oauth/figma.js +1 -1
- package/dist/oauth/github.cjs +19 -8
- package/dist/oauth/github.d.ts +3 -2
- package/dist/oauth/github.js +1 -1
- package/dist/oauth/gitlab.cjs +19 -16
- package/dist/oauth/gitlab.d.ts +3 -2
- package/dist/oauth/gitlab.js +1 -1
- package/dist/oauth/index.cjs +266 -166
- package/dist/oauth/index.d.ts +3 -2
- package/dist/oauth/index.js +22 -21
- package/dist/oauth/mailchimp.cjs +19 -16
- package/dist/oauth/mailchimp.d.ts +3 -2
- package/dist/oauth/mailchimp.js +1 -1
- package/dist/oauth/pinterest.cjs +19 -16
- package/dist/oauth/pinterest.d.ts +3 -2
- package/dist/oauth/pinterest.js +1 -1
- package/dist/oauth/spotify.cjs +19 -16
- package/dist/oauth/spotify.d.ts +3 -2
- package/dist/oauth/spotify.js +1 -1
- package/dist/oauth/strava.cjs +19 -16
- package/dist/oauth/strava.d.ts +3 -2
- package/dist/oauth/strava.js +1 -1
- package/dist/oauth/x.cjs +19 -16
- package/dist/oauth/x.d.ts +3 -2
- package/dist/oauth/x.js +1 -1
- package/dist/schemas.cjs +16 -2
- package/dist/schemas.d.ts +17 -1
- package/dist/schemas.js +5 -3
- package/dist/secure.cjs +58 -16
- package/dist/secure.d.ts +4 -10
- package/dist/secure.js +5 -5
- package/dist/utils.cjs +94 -87
- package/dist/utils.d.ts +9 -39
- package/dist/utils.js +11 -9
- package/package.json +3 -4
- package/dist/chunk-42XB3YCW.js +0 -22
- package/dist/chunk-6R2YZ4AC.js +0 -22
- package/dist/chunk-A3N4PVAT.js +0 -70
- package/dist/chunk-B737EUJV.js +0 -22
- package/dist/chunk-CXLATHS5.js +0 -143
- package/dist/chunk-DIVDFNAP.js +0 -0
- package/dist/chunk-E3OXBRYF.js +0 -22
- package/dist/chunk-EIL2FPSS.js +0 -22
- package/dist/chunk-EMKJA2GJ.js +0 -89
- package/dist/chunk-FIPU4MLT.js +0 -21
- package/dist/chunk-FKRDCWBF.js +0 -22
- package/dist/chunk-HP34YGGJ.js +0 -22
- package/dist/chunk-IKHPGFCW.js +0 -14
- package/dist/chunk-IUYZQTJV.js +0 -30
- package/dist/chunk-KRNOMBXQ.js +0 -22
- package/dist/chunk-KSWLO5ZU.js +0 -102
- package/dist/chunk-N4SX7TZT.js +0 -96
- package/dist/chunk-STHEPPUZ.js +0 -11
|
@@ -43,6 +43,26 @@ var cacheControl = {
|
|
|
43
43
|
Expires: "0",
|
|
44
44
|
Vary: "Cookie"
|
|
45
45
|
};
|
|
46
|
+
var contentSecurityPolicy = {
|
|
47
|
+
"Content-Security-Policy": [
|
|
48
|
+
"default-src 'none'",
|
|
49
|
+
"script-src 'self'",
|
|
50
|
+
"frame-src 'none'",
|
|
51
|
+
"object-src 'none'",
|
|
52
|
+
"frame-ancestors 'none'",
|
|
53
|
+
"base-uri 'none'"
|
|
54
|
+
].join("; ")
|
|
55
|
+
};
|
|
56
|
+
var secureHeaders = {
|
|
57
|
+
"X-Content-Type-Options": "nosniff",
|
|
58
|
+
"X-Frame-Options": "DENY",
|
|
59
|
+
"Referrer-Policy": "strict-origin-when-cross-origin"
|
|
60
|
+
};
|
|
61
|
+
var secureApiHeaders = {
|
|
62
|
+
...cacheControl,
|
|
63
|
+
...contentSecurityPolicy,
|
|
64
|
+
...secureHeaders
|
|
65
|
+
};
|
|
46
66
|
|
|
47
67
|
// src/secure.ts
|
|
48
68
|
var import_crypto = __toESM(require("crypto"), 1);
|
|
@@ -71,9 +91,6 @@ var AuthSecurityError = class extends Error {
|
|
|
71
91
|
Error.captureStackTrace(this, new.target);
|
|
72
92
|
}
|
|
73
93
|
};
|
|
74
|
-
var isAuthSecurityError = (error) => {
|
|
75
|
-
return error instanceof AuthSecurityError;
|
|
76
|
-
};
|
|
77
94
|
|
|
78
95
|
// src/utils.ts
|
|
79
96
|
var toSnakeCase = (str) => {
|
|
@@ -92,71 +109,132 @@ var equals = (a, b) => {
|
|
|
92
109
|
if (a === null || b === null || a === void 0 || b === void 0) return false;
|
|
93
110
|
return a === b;
|
|
94
111
|
};
|
|
95
|
-
var
|
|
112
|
+
var extractPath = (url) => {
|
|
113
|
+
const pathRegex = /^https?:\/\/[a-zA-Z0-9_\-\.]+(:\d+)?(\/.*)$/;
|
|
114
|
+
const match = url.match(pathRegex);
|
|
115
|
+
return match && match[2] ? match[2] : "/";
|
|
116
|
+
};
|
|
117
|
+
|
|
118
|
+
// src/assert.ts
|
|
119
|
+
var unsafeChars = [
|
|
120
|
+
"<",
|
|
121
|
+
">",
|
|
122
|
+
'"',
|
|
123
|
+
"`",
|
|
124
|
+
" ",
|
|
125
|
+
"\r",
|
|
126
|
+
"\n",
|
|
127
|
+
" ",
|
|
128
|
+
"\\",
|
|
129
|
+
"%2F",
|
|
130
|
+
"%5C",
|
|
131
|
+
"%2f",
|
|
132
|
+
"%5c",
|
|
133
|
+
"\r\n",
|
|
134
|
+
"%0A",
|
|
135
|
+
"%0D",
|
|
136
|
+
"%0a",
|
|
137
|
+
"%0d",
|
|
138
|
+
"..",
|
|
139
|
+
"//",
|
|
140
|
+
"///",
|
|
141
|
+
"...",
|
|
142
|
+
"%20",
|
|
143
|
+
"\0"
|
|
144
|
+
];
|
|
145
|
+
var isValidURL = (value) => {
|
|
146
|
+
if (!new RegExp(/^https?:\/\/[^/]/).test(value)) {
|
|
147
|
+
return false;
|
|
148
|
+
}
|
|
149
|
+
const match = value.match(/^(https?:\/\/)(.*)$/);
|
|
150
|
+
if (!match) return false;
|
|
151
|
+
const rest = match[2];
|
|
152
|
+
for (const char of unsafeChars) {
|
|
153
|
+
if (rest.includes(char)) return false;
|
|
154
|
+
}
|
|
155
|
+
const regex = /^https?:\/\/(?:[a-zA-Z0-9._-]+|localhost|\[[0-9a-fA-F:]+\])(?::\d{1,5})?(?:\/[a-zA-Z0-9._~!$&'()?#*+,;=:@-]*)*\/?$/;
|
|
156
|
+
return regex.test(match[0]);
|
|
157
|
+
};
|
|
158
|
+
var isRelativeURL = (value) => {
|
|
159
|
+
if (value.length > 100) return false;
|
|
160
|
+
for (const char of unsafeChars) {
|
|
161
|
+
if (value.includes(char)) return false;
|
|
162
|
+
}
|
|
163
|
+
const regex = /^\/[a-zA-Z0-9\-_\/.?&=#]*\/?$/;
|
|
164
|
+
return regex.test(value);
|
|
165
|
+
};
|
|
166
|
+
var isSameOrigin = (origin, expected) => {
|
|
167
|
+
const originURL = new URL(origin);
|
|
168
|
+
const expectedURL = new URL(expected);
|
|
169
|
+
return equals(originURL.origin, expectedURL.origin);
|
|
170
|
+
};
|
|
171
|
+
var patternToRegex = (pattern) => {
|
|
96
172
|
try {
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
if (path !== "/" && path.endsWith("/")) {
|
|
111
|
-
path = path.replace(/\/+$/, "/");
|
|
112
|
-
} else if (path !== "/") {
|
|
113
|
-
path = path.replace(/\/+$/, "");
|
|
114
|
-
}
|
|
115
|
-
return protocol + domain + path;
|
|
116
|
-
}
|
|
117
|
-
let sanitized = decodedURL.replace(/\/\.\.\//g, "/").replace(/\/\.\.$/, "").replace(/\.{2,}/g, "").replace(/\/{2,}/g, "/");
|
|
118
|
-
if (sanitized !== "/" && sanitized.endsWith("/")) {
|
|
119
|
-
sanitized = sanitized.replace(/\/+$/, "/");
|
|
120
|
-
} else if (sanitized !== "/") {
|
|
121
|
-
sanitized = sanitized.replace(/\/+$/, "");
|
|
122
|
-
}
|
|
123
|
-
return sanitized;
|
|
173
|
+
if (pattern.length > 2048) return null;
|
|
174
|
+
pattern = pattern.replace(/\\/g, "");
|
|
175
|
+
const match = pattern.match(/^(https?):\/\/([a-zA-Z0-9.*-]{1,253})(?::(\d{1,5}|\*))?(?:\/.*)?$/);
|
|
176
|
+
if (!match) return null;
|
|
177
|
+
const [, protocol, host, port] = match;
|
|
178
|
+
const hasWildcard = host.includes("*");
|
|
179
|
+
if (hasWildcard && !host.startsWith("*.")) return null;
|
|
180
|
+
if (hasWildcard && host.slice(2).includes("*")) return null;
|
|
181
|
+
const domain = hasWildcard ? host.slice(2) : host;
|
|
182
|
+
const escapedDomain = domain.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
|
|
183
|
+
const hostRegex = hasWildcard ? `[^.]+\\.${escapedDomain}` : escapedDomain;
|
|
184
|
+
const portRegex = port === "*" ? ":\\d{1,5}" : port ? `:${port}` : "";
|
|
185
|
+
return new RegExp(`^${protocol}:\\/\\/${hostRegex}${portRegex}$`);
|
|
124
186
|
} catch {
|
|
125
|
-
return
|
|
187
|
+
return null;
|
|
126
188
|
}
|
|
127
189
|
};
|
|
128
|
-
var
|
|
190
|
+
var isTrustedOrigin = (url, trustedOrigins) => {
|
|
191
|
+
if (!isValidURL(url) || trustedOrigins.length === 0) return false;
|
|
129
192
|
try {
|
|
130
|
-
const
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
193
|
+
const urlOrigin = new URL(url).origin;
|
|
194
|
+
for (const pattern of trustedOrigins) {
|
|
195
|
+
const regex = patternToRegex(pattern);
|
|
196
|
+
if (regex?.test(urlOrigin)) return true;
|
|
197
|
+
try {
|
|
198
|
+
if (isValidURL(pattern) && equals(new URL(pattern).origin, urlOrigin)) return true;
|
|
199
|
+
} catch {
|
|
200
|
+
}
|
|
201
|
+
}
|
|
134
202
|
} catch {
|
|
135
|
-
return sanitizeURL(path);
|
|
136
203
|
}
|
|
204
|
+
return false;
|
|
137
205
|
};
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
[key]: {
|
|
147
|
-
code: issue.code,
|
|
148
|
-
message: issue.message
|
|
149
|
-
}
|
|
206
|
+
|
|
207
|
+
// src/env.ts
|
|
208
|
+
var import_meta = {};
|
|
209
|
+
var env = new Proxy({}, {
|
|
210
|
+
get(_, prop) {
|
|
211
|
+
if (typeof prop !== "string") return void 0;
|
|
212
|
+
const hasProperty = (process2) => {
|
|
213
|
+
return process2 && Object.prototype.hasOwnProperty.call(process2, prop);
|
|
150
214
|
};
|
|
151
|
-
|
|
152
|
-
|
|
215
|
+
try {
|
|
216
|
+
if (typeof process !== "undefined" && hasProperty(process.env)) {
|
|
217
|
+
return process.env[prop];
|
|
218
|
+
}
|
|
219
|
+
if (typeof import_meta !== "undefined" && hasProperty(import_meta.env)) {
|
|
220
|
+
return import_meta.env[prop];
|
|
221
|
+
}
|
|
222
|
+
if (typeof Deno !== "undefined" && Deno.env?.get) {
|
|
223
|
+
return Deno.env.get(prop);
|
|
224
|
+
}
|
|
225
|
+
if (typeof Bun !== "undefined" && hasProperty(Bun.env)) {
|
|
226
|
+
return Bun.env[prop];
|
|
227
|
+
}
|
|
228
|
+
const globalValue = globalThis[prop];
|
|
229
|
+
return typeof globalValue === "string" ? globalValue : void 0;
|
|
230
|
+
} catch {
|
|
231
|
+
return void 0;
|
|
232
|
+
}
|
|
233
|
+
}
|
|
234
|
+
});
|
|
153
235
|
|
|
154
|
-
// src/
|
|
155
|
-
var
|
|
156
|
-
if (value.includes("\r\n") || value.includes("\n") || value.includes("\r")) return false;
|
|
157
|
-
const regex = /^https?:\/\/(?:[a-zA-Z0-9._-]+|localhost|\[[0-9a-fA-F:]+\])(?::\d{1,5})?(?:\/[a-zA-Z0-9._~!$&'()*+,;=:@-]*)*\/?$/;
|
|
158
|
-
return regex.test(value);
|
|
159
|
-
};
|
|
236
|
+
// src/jose.ts
|
|
237
|
+
var import_jose = require("@aura-stack/jose");
|
|
160
238
|
|
|
161
239
|
// src/secure.ts
|
|
162
240
|
var generateSecure = (length = 32) => {
|
|
@@ -166,13 +244,29 @@ var createHash = (data, base = "hex") => {
|
|
|
166
244
|
return import_crypto.default.createHash("sha256").update(data).digest().toString(base);
|
|
167
245
|
};
|
|
168
246
|
var createPKCE = async (verifier) => {
|
|
169
|
-
const
|
|
247
|
+
const byteLength = verifier ? void 0 : Math.floor(Math.random() * (96 - 32 + 1) + 32);
|
|
248
|
+
const codeVerifier = verifier ?? generateSecure(byteLength ?? 64);
|
|
249
|
+
if (codeVerifier.length < 43 || codeVerifier.length > 128) {
|
|
250
|
+
throw new AuthSecurityError("PKCE_VERIFIER_INVALID", "The code verifier must be between 43 and 128 characters in length.");
|
|
251
|
+
}
|
|
170
252
|
const codeChallenge = createHash(codeVerifier, "base64url");
|
|
171
253
|
return { codeVerifier, codeChallenge, method: "S256" };
|
|
172
254
|
};
|
|
173
255
|
|
|
174
256
|
// src/schemas.ts
|
|
175
257
|
var import_zod = require("zod");
|
|
258
|
+
var OAuthProviderCredentialsSchema = (0, import_zod.object)({
|
|
259
|
+
id: (0, import_zod.string)(),
|
|
260
|
+
name: (0, import_zod.string)(),
|
|
261
|
+
authorizeURL: (0, import_zod.string)().url(),
|
|
262
|
+
accessToken: (0, import_zod.string)().url(),
|
|
263
|
+
scope: (0, import_zod.string)(),
|
|
264
|
+
userInfo: (0, import_zod.string)().url(),
|
|
265
|
+
responseType: (0, import_zod.enum)(["code", "token", "id_token"]),
|
|
266
|
+
clientId: (0, import_zod.string)(),
|
|
267
|
+
clientSecret: (0, import_zod.string)(),
|
|
268
|
+
profile: import_zod.z.function().optional()
|
|
269
|
+
});
|
|
176
270
|
var OAuthProviderConfigSchema = (0, import_zod.object)({
|
|
177
271
|
authorizeURL: (0, import_zod.string)().url(),
|
|
178
272
|
accessToken: (0, import_zod.string)().url(),
|
|
@@ -240,73 +334,82 @@ var OAuthEnvSchema = (0, import_zod.object)({
|
|
|
240
334
|
});
|
|
241
335
|
|
|
242
336
|
// src/actions/signIn/authorization.ts
|
|
243
|
-
var createAuthorizationURL = (oauthConfig, redirectURI, state, codeChallenge, codeChallengeMethod) => {
|
|
337
|
+
var createAuthorizationURL = (oauthConfig, redirectURI, state, codeChallenge, codeChallengeMethod, logger) => {
|
|
244
338
|
const parsed = OAuthAuthorization.safeParse({ ...oauthConfig, redirectURI, state, codeChallenge, codeChallengeMethod });
|
|
245
339
|
if (!parsed.success) {
|
|
246
|
-
|
|
247
|
-
|
|
340
|
+
logger?.log("INVALID_OAUTH_CONFIGURATION", {
|
|
341
|
+
structuredData: {
|
|
342
|
+
scope: oauthConfig.scope,
|
|
343
|
+
redirect_uri: redirectURI,
|
|
344
|
+
has_state: Boolean(state),
|
|
345
|
+
has_code_challenge: Boolean(codeChallenge),
|
|
346
|
+
code_challenge_method: codeChallengeMethod
|
|
347
|
+
}
|
|
348
|
+
});
|
|
349
|
+
throw new AuthInternalError("INVALID_OAUTH_CONFIGURATION", "The OAuth provider configuration is invalid.");
|
|
248
350
|
}
|
|
249
351
|
const { authorizeURL, ...options2 } = parsed.data;
|
|
250
352
|
const { userInfo, accessToken, clientSecret, ...required } = options2;
|
|
251
353
|
const searchParams = new URLSearchParams(toCastCase(required));
|
|
252
354
|
return `${authorizeURL}?${searchParams}`;
|
|
253
355
|
};
|
|
254
|
-
var
|
|
356
|
+
var getTrustedOrigins = async (request, trustedOrigins) => {
|
|
357
|
+
if (!trustedOrigins) return [];
|
|
358
|
+
const raw = typeof trustedOrigins === "function" ? await trustedOrigins(request) : trustedOrigins;
|
|
359
|
+
return Array.isArray(raw) ? raw : typeof raw === "string" ? [raw] : [];
|
|
360
|
+
};
|
|
361
|
+
var getOriginURL = async (request, context) => {
|
|
255
362
|
const headers = request.headers;
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
363
|
+
let origin = new URL(request.url).origin;
|
|
364
|
+
const trustedOrigins = await getTrustedOrigins(request, context?.trustedOrigins);
|
|
365
|
+
trustedOrigins.push(origin);
|
|
366
|
+
if (context?.trustedProxyHeaders) {
|
|
367
|
+
const protocol = headers.get("Forwarded")?.match(/proto=([^;]+)/i)?.[1] ?? headers.get("X-Forwarded-Proto") ?? "http";
|
|
368
|
+
const host = headers.get("Host") ?? headers.get("Forwarded")?.match(/host=([^;]+)/i)?.[1] ?? headers.get("X-Forwarded-Host") ?? null;
|
|
369
|
+
origin = `${protocol}://${host}`;
|
|
370
|
+
}
|
|
371
|
+
if (!isTrustedOrigin(origin, trustedOrigins)) {
|
|
372
|
+
context?.logger?.log("UNTRUSTED_ORIGIN", { structuredData: { origin } });
|
|
373
|
+
throw new AuthInternalError("UNTRUSTED_ORIGIN", "The constructed origin URL is not trusted.");
|
|
262
374
|
}
|
|
375
|
+
return origin;
|
|
263
376
|
};
|
|
264
|
-
var createRedirectURI = (request, oauth,
|
|
265
|
-
const
|
|
266
|
-
return `${
|
|
377
|
+
var createRedirectURI = async (request, oauth, context) => {
|
|
378
|
+
const origin = await getOriginURL(request, context);
|
|
379
|
+
return `${origin}${context.basePath}/callback/${oauth}`;
|
|
267
380
|
};
|
|
268
|
-
var createRedirectTo = (request, redirectTo,
|
|
381
|
+
var createRedirectTo = async (request, redirectTo, context) => {
|
|
269
382
|
try {
|
|
270
383
|
const headers = request.headers;
|
|
271
|
-
const
|
|
272
|
-
const
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
if (
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
if (!isValidURL(referer) || !equals(refererURL.origin, hostedURL.origin)) {
|
|
290
|
-
throw new AuthSecurityError(
|
|
291
|
-
"POTENTIAL_OPEN_REDIRECT_ATTACK_DETECTED",
|
|
292
|
-
"The referer of the request does not match the hosted origin."
|
|
293
|
-
);
|
|
384
|
+
const requestOrigin = await getOriginURL(request, context);
|
|
385
|
+
const origins = await getTrustedOrigins(request, context?.trustedOrigins);
|
|
386
|
+
const validateURL = (url) => {
|
|
387
|
+
if (!isRelativeURL(url) && !isValidURL(url)) return "/";
|
|
388
|
+
if (isRelativeURL(url)) return url;
|
|
389
|
+
if (origins.length > 0) {
|
|
390
|
+
if (isTrustedOrigin(url, origins)) {
|
|
391
|
+
const urlOrigin = new URL(url).origin;
|
|
392
|
+
for (const pattern of origins) {
|
|
393
|
+
const regex = patternToRegex(pattern);
|
|
394
|
+
if (regex?.test(urlOrigin)) {
|
|
395
|
+
return isSameOrigin(url, request.url) ? extractPath(url) : url;
|
|
396
|
+
}
|
|
397
|
+
if (isValidURL(pattern) && equals(new URL(pattern).origin, urlOrigin)) return url;
|
|
398
|
+
}
|
|
399
|
+
}
|
|
400
|
+
context?.logger?.log("OPEN_REDIRECT_ATTACK");
|
|
401
|
+
return "/";
|
|
294
402
|
}
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
if (origin) {
|
|
298
|
-
const originURL = new URL(sanitizeURL(getNormalizedOriginPath(origin)));
|
|
299
|
-
if (!isValidURL(origin) || !equals(originURL.origin, hostedURL.origin)) {
|
|
300
|
-
throw new AuthSecurityError("POTENTIAL_OPEN_REDIRECT_ATTACK_DETECTED", "Invalid origin (potential CSRF).");
|
|
403
|
+
if (isSameOrigin(url, requestOrigin)) {
|
|
404
|
+
return extractPath(url);
|
|
301
405
|
}
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
|
|
406
|
+
context?.logger?.log("OPEN_REDIRECT_ATTACK");
|
|
407
|
+
return "/";
|
|
408
|
+
};
|
|
409
|
+
return validateURL(redirectTo ?? headers.get("Referer") ?? headers.get("Origin") ?? "/");
|
|
305
410
|
} catch (error) {
|
|
306
|
-
|
|
307
|
-
|
|
308
|
-
}
|
|
309
|
-
throw new AuthSecurityError("POTENTIAL_OPEN_REDIRECT_ATTACK_DETECTED", "Invalid origin (potential CSRF).");
|
|
411
|
+
context?.logger?.log("POTENTIAL_OPEN_REDIRECT_ATTACK_DETECTED");
|
|
412
|
+
return "/";
|
|
310
413
|
}
|
|
311
414
|
};
|
|
312
415
|
|
|
@@ -335,13 +438,17 @@ var signInAction = (oauth) => {
|
|
|
335
438
|
request,
|
|
336
439
|
params: { oauth: oauth2 },
|
|
337
440
|
searchParams: { redirectTo },
|
|
338
|
-
context
|
|
441
|
+
context
|
|
339
442
|
} = ctx;
|
|
443
|
+
const { oauth: providers, cookies, logger } = context;
|
|
340
444
|
const state = generateSecure();
|
|
341
|
-
const redirectURI = createRedirectURI(request, oauth2,
|
|
342
|
-
const redirectToValue = createRedirectTo(request, redirectTo,
|
|
445
|
+
const redirectURI = await createRedirectURI(request, oauth2, context);
|
|
446
|
+
const redirectToValue = await createRedirectTo(request, redirectTo, context);
|
|
343
447
|
const { codeVerifier, codeChallenge, method } = await createPKCE();
|
|
344
|
-
const authorization = createAuthorizationURL(providers[oauth2], redirectURI, state, codeChallenge, method);
|
|
448
|
+
const authorization = createAuthorizationURL(providers[oauth2], redirectURI, state, codeChallenge, method, logger);
|
|
449
|
+
logger?.log("SIGN_IN_INITIATED", {
|
|
450
|
+
structuredData: { oauth_provider: oauth2, code_challenge_method: method }
|
|
451
|
+
});
|
|
345
452
|
const headers = new import_router2.HeadersBuilder(cacheControl).setHeader("Location", authorization).setCookie(cookies.state.name, state, cookies.state.attributes).setCookie(cookies.redirectURI.name, redirectURI, cookies.redirectURI.attributes).setCookie(cookies.redirectTo.name, redirectToValue, cookies.redirectTo.attributes).setCookie(cookies.codeVerifier.name, codeVerifier, cookies.codeVerifier.attributes).toHeaders();
|
|
346
453
|
return Response.json(
|
|
347
454
|
{ oauth: oauth2 },
|
|
@@ -1,33 +1,13 @@
|
|
|
1
1
|
import * as _aura_stack_router from '@aura-stack/router';
|
|
2
|
-
import {
|
|
3
|
-
import
|
|
2
|
+
import { k as OAuthProviderRecord } from '../../index-CSyIJmCM.js';
|
|
3
|
+
import 'zod';
|
|
4
4
|
import '../../schemas.js';
|
|
5
|
-
import '
|
|
5
|
+
import '../../jose.js';
|
|
6
6
|
import '@aura-stack/jose';
|
|
7
7
|
import '@aura-stack/jose/jose';
|
|
8
|
+
import '@aura-stack/router/cookie';
|
|
8
9
|
import '../../@types/utility.js';
|
|
9
10
|
|
|
10
|
-
declare const signInAction: (oauth: OAuthProviderRecord) => _aura_stack_router.RouteEndpoint<"GET", "/signIn/:oauth", {
|
|
11
|
-
schemas?: {
|
|
12
|
-
params: z.ZodObject<{
|
|
13
|
-
oauth: z.ZodEnum<{
|
|
14
|
-
[x: string & Record<never, never>]: string & Record<never, never>;
|
|
15
|
-
github: "github";
|
|
16
|
-
bitbucket: "bitbucket";
|
|
17
|
-
figma: "figma";
|
|
18
|
-
discord: "discord";
|
|
19
|
-
gitlab: "gitlab";
|
|
20
|
-
spotify: "spotify";
|
|
21
|
-
x: "x";
|
|
22
|
-
strava: "strava";
|
|
23
|
-
mailchimp: "mailchimp";
|
|
24
|
-
pinterest: "pinterest";
|
|
25
|
-
}>;
|
|
26
|
-
}, z.core.$strip>;
|
|
27
|
-
searchParams: z.ZodObject<{
|
|
28
|
-
redirectTo: z.ZodOptional<z.ZodString>;
|
|
29
|
-
}, z.core.$strip>;
|
|
30
|
-
} | undefined;
|
|
31
|
-
}>;
|
|
11
|
+
declare const signInAction: (oauth: OAuthProviderRecord) => _aura_stack_router.RouteEndpoint<"GET", "/signIn/:oauth", {}>;
|
|
32
12
|
|
|
33
13
|
export { signInAction };
|
|
@@ -1,13 +1,15 @@
|
|
|
1
1
|
import {
|
|
2
2
|
signInAction
|
|
3
|
-
} from "../../chunk-
|
|
4
|
-
import "../../chunk-
|
|
5
|
-
import "../../chunk-
|
|
6
|
-
import "../../chunk-
|
|
7
|
-
import "../../chunk-
|
|
8
|
-
import "../../chunk-
|
|
3
|
+
} from "../../chunk-7QF22LHP.js";
|
|
4
|
+
import "../../chunk-XUP6KKNG.js";
|
|
5
|
+
import "../../chunk-KJBAQZX2.js";
|
|
6
|
+
import "../../chunk-NUDITUKX.js";
|
|
7
|
+
import "../../chunk-4EKY7655.js";
|
|
8
|
+
import "../../chunk-QQVSRXGX.js";
|
|
9
|
+
import "../../chunk-EBAMFRB7.js";
|
|
10
|
+
import "../../chunk-FRJFWTOY.js";
|
|
11
|
+
import "../../chunk-4MYWAOLG.js";
|
|
9
12
|
import "../../chunk-RRLIF4PQ.js";
|
|
10
|
-
import "../../chunk-YRCB5FLE.js";
|
|
11
13
|
export {
|
|
12
14
|
signInAction
|
|
13
15
|
};
|