@aura-stack/auth 0.1.0 → 0.2.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.
- package/dist/@types/index.d.ts +5 -5
- package/dist/@types/router.d.d.ts +5 -5
- package/dist/@types/utility.d.ts +1 -5
- package/dist/actions/callback/access-token.cjs +95 -74
- package/dist/actions/callback/access-token.d.ts +7 -7
- package/dist/actions/callback/access-token.js +5 -3
- package/dist/actions/callback/callback.cjs +171 -249
- package/dist/actions/callback/callback.d.ts +6 -6
- package/dist/actions/callback/callback.js +10 -10
- package/dist/actions/callback/userinfo.cjs +81 -57
- package/dist/actions/callback/userinfo.d.ts +5 -5
- package/dist/actions/callback/userinfo.js +7 -5
- package/dist/actions/csrfToken/csrfToken.cjs +36 -105
- package/dist/actions/csrfToken/csrfToken.js +6 -6
- package/dist/actions/index.cjs +309 -444
- package/dist/actions/index.d.ts +5 -5
- package/dist/actions/index.js +19 -19
- package/dist/actions/session/session.cjs +25 -109
- package/dist/actions/session/session.js +4 -5
- package/dist/actions/signIn/authorization.cjs +96 -87
- package/dist/actions/signIn/authorization.d.ts +5 -5
- package/dist/actions/signIn/authorization.js +5 -5
- package/dist/actions/signIn/signIn.cjs +133 -242
- package/dist/actions/signIn/signIn.d.ts +6 -6
- package/dist/actions/signIn/signIn.js +8 -9
- package/dist/actions/signOut/signOut.cjs +136 -282
- package/dist/actions/signOut/signOut.js +8 -9
- package/dist/assert.cjs +5 -0
- package/dist/assert.d.ts +10 -1
- package/dist/assert.js +3 -1
- package/dist/chunk-3EUWD5BB.js +63 -0
- package/dist/chunk-6R2YZ4AC.js +22 -0
- package/dist/chunk-A3N4PVAT.js +70 -0
- package/dist/chunk-B737EUJV.js +22 -0
- package/dist/{chunk-256KIVJL.js → chunk-CXLATHS5.js} +53 -9
- package/dist/{chunk-6SM22VVJ.js → chunk-EIL2FPSS.js} +5 -1
- package/dist/{chunk-VFTYH33W.js → chunk-EMKJA2GJ.js} +36 -8
- package/dist/{chunk-UJJ7R56J.js → chunk-GA2SMTJO.js} +16 -10
- package/dist/chunk-HP34YGGJ.js +22 -0
- package/dist/chunk-HT4YLL7N.js +35 -0
- package/dist/{chunk-EBPE35JT.js → chunk-IUYZQTJV.js} +0 -1
- package/dist/{chunk-RLT4RFKV.js → chunk-IVET23KF.js} +21 -8
- package/dist/{chunk-XXJKNKGQ.js → chunk-JVFTCTTE.js} +9 -13
- package/dist/chunk-KSWLO5ZU.js +102 -0
- package/dist/{chunk-GZU3RBTB.js → chunk-N2APGLXA.js} +19 -10
- package/dist/{chunk-CAKJT3KS.js → chunk-N4SX7TZT.js} +21 -17
- package/dist/chunk-RRLIF4PQ.js +55 -0
- package/dist/chunk-TLE4PXY3.js +39 -0
- package/dist/chunk-W6LG7BFW.js +197 -0
- package/dist/{chunk-HMRKN75I.js → chunk-YRCB5FLE.js} +14 -9
- package/dist/chunk-ZNCZVF6U.js +14 -0
- package/dist/cookie.cjs +140 -99
- package/dist/cookie.d.ts +35 -44
- package/dist/cookie.js +10 -17
- package/dist/errors.cjs +85 -0
- package/dist/errors.d.ts +49 -0
- package/dist/errors.js +18 -0
- package/dist/{index-DpfbvTZ_.d.ts → index-DkaLJFn8.d.ts} +192 -61
- package/dist/index.cjs +543 -443
- package/dist/index.d.ts +6 -6
- package/dist/index.js +42 -28
- package/dist/jose.cjs +25 -14
- package/dist/jose.d.ts +4 -1
- package/dist/jose.js +5 -4
- package/dist/oauth/bitbucket.d.ts +5 -5
- package/dist/oauth/discord.cjs +0 -1
- package/dist/oauth/discord.d.ts +5 -5
- package/dist/oauth/discord.js +1 -1
- package/dist/oauth/figma.d.ts +5 -5
- package/dist/oauth/github.d.ts +5 -5
- package/dist/oauth/gitlab.d.ts +5 -5
- package/dist/oauth/index.cjs +176 -6
- package/dist/oauth/index.d.ts +5 -5
- package/dist/oauth/index.js +19 -4
- package/dist/oauth/mailchimp.cjs +46 -0
- package/dist/oauth/mailchimp.d.ts +7 -0
- package/dist/oauth/mailchimp.js +6 -0
- package/dist/oauth/pinterest.cjs +46 -0
- package/dist/oauth/pinterest.d.ts +7 -0
- package/dist/oauth/pinterest.js +6 -0
- package/dist/oauth/spotify.d.ts +5 -5
- package/dist/oauth/strava.cjs +46 -0
- package/dist/oauth/strava.d.ts +7 -0
- package/dist/oauth/strava.js +6 -0
- package/dist/oauth/x.d.ts +5 -5
- package/dist/{response.cjs → request.cjs} +14 -10
- package/dist/request.d.ts +13 -0
- package/dist/request.js +6 -0
- package/dist/schemas.cjs +43 -37
- package/dist/schemas.d.ts +67 -64
- package/dist/schemas.js +3 -1
- package/dist/secure.cjs +32 -24
- package/dist/secure.d.ts +5 -5
- package/dist/secure.js +4 -3
- package/dist/utils.cjs +90 -15
- package/dist/utils.d.ts +11 -2
- package/dist/utils.js +8 -4
- package/package.json +8 -7
- package/dist/chunk-FJUDBLCP.js +0 -59
- package/dist/chunk-HGJ4TXY4.js +0 -137
- package/dist/chunk-JAPMIE6S.js +0 -10
- package/dist/chunk-LLR722CL.js +0 -96
- package/dist/chunk-SJPDVKUS.js +0 -112
- package/dist/chunk-SMQO5WD7.js +0 -30
- package/dist/chunk-UTDLUEEG.js +0 -31
- package/dist/chunk-ZV4BH47P.js +0 -154
- package/dist/error.cjs +0 -88
- package/dist/error.d.ts +0 -62
- package/dist/error.js +0 -16
- package/dist/response.d.ts +0 -10
- package/dist/response.js +0 -6
|
@@ -33,62 +33,63 @@ __export(callback_exports, {
|
|
|
33
33
|
callbackAction: () => callbackAction
|
|
34
34
|
});
|
|
35
35
|
module.exports = __toCommonJS(callback_exports);
|
|
36
|
-
var
|
|
36
|
+
var import_zod2 = require("zod");
|
|
37
37
|
var import_router2 = require("@aura-stack/router");
|
|
38
38
|
|
|
39
39
|
// src/secure.ts
|
|
40
|
-
var
|
|
40
|
+
var import_crypto = __toESM(require("crypto"), 1);
|
|
41
41
|
|
|
42
42
|
// src/utils.ts
|
|
43
43
|
var import_router = require("@aura-stack/router");
|
|
44
44
|
|
|
45
|
-
// src/
|
|
46
|
-
var
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
45
|
+
// src/errors.ts
|
|
46
|
+
var OAuthProtocolError = class extends Error {
|
|
47
|
+
type = "OAUTH_PROTOCOL_ERROR";
|
|
48
|
+
error;
|
|
49
|
+
errorURI;
|
|
50
|
+
constructor(error, description, errorURI, options2) {
|
|
51
|
+
super(description, options2);
|
|
52
|
+
this.error = error;
|
|
53
|
+
this.errorURI = errorURI;
|
|
54
|
+
this.name = new.target.name;
|
|
55
|
+
Error.captureStackTrace(this, new.target);
|
|
51
56
|
}
|
|
52
57
|
};
|
|
53
|
-
var
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
throw new AuthError("invalid_request", error.message ?? message);
|
|
58
|
+
var AuthInternalError = class extends Error {
|
|
59
|
+
type = "AUTH_INTERNAL_ERROR";
|
|
60
|
+
code;
|
|
61
|
+
constructor(code, message, options2) {
|
|
62
|
+
super(message, options2);
|
|
63
|
+
this.code = code;
|
|
64
|
+
this.name = new.target.name;
|
|
65
|
+
Error.captureStackTrace(this, new.target);
|
|
62
66
|
}
|
|
63
67
|
};
|
|
64
|
-
var
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
TEMPORARILY_UNAVAILABLE: "temporarily_unavailable"
|
|
73
|
-
},
|
|
74
|
-
ACCESS_TOKEN: {
|
|
75
|
-
INVALID_REQUEST: "invalid_request",
|
|
76
|
-
INVALID_CLIENT: "invalid_client",
|
|
77
|
-
INVALID_GRANT: "invalid_grant",
|
|
78
|
-
UNAUTHORIZED_CLIENT: "unauthorized_client",
|
|
79
|
-
UNSUPPORTED_GRANT_TYPE: "unsupported_grant_type",
|
|
80
|
-
INVALID_SCOPE: "invalid_scope"
|
|
68
|
+
var AuthSecurityError = class extends Error {
|
|
69
|
+
type = "AUTH_SECURITY_ERROR";
|
|
70
|
+
code;
|
|
71
|
+
constructor(code, message, options2) {
|
|
72
|
+
super(message, options2);
|
|
73
|
+
this.code = code;
|
|
74
|
+
this.name = new.target.name;
|
|
75
|
+
Error.captureStackTrace(this, new.target);
|
|
81
76
|
}
|
|
82
77
|
};
|
|
78
|
+
var isNativeError = (error) => {
|
|
79
|
+
return error instanceof Error;
|
|
80
|
+
};
|
|
81
|
+
var isOAuthProtocolError = (error) => {
|
|
82
|
+
return error instanceof OAuthProtocolError;
|
|
83
|
+
};
|
|
83
84
|
|
|
84
85
|
// src/utils.ts
|
|
85
86
|
var equals = (a, b) => {
|
|
86
87
|
if (a === null || b === null || a === void 0 || b === void 0) return false;
|
|
87
88
|
return a === b;
|
|
88
89
|
};
|
|
89
|
-
var sanitizeURL = (
|
|
90
|
+
var sanitizeURL = (url) => {
|
|
90
91
|
try {
|
|
91
|
-
let decodedURL = decodeURIComponent(
|
|
92
|
+
let decodedURL = decodeURIComponent(url).trim();
|
|
92
93
|
const protocolMatch = decodedURL.match(/^([a-zA-Z][a-zA-Z0-9+.-]*:\/\/)/);
|
|
93
94
|
let protocol = "";
|
|
94
95
|
let rest = decodedURL;
|
|
@@ -116,7 +117,7 @@ var sanitizeURL = (url2) => {
|
|
|
116
117
|
}
|
|
117
118
|
return sanitized;
|
|
118
119
|
} catch {
|
|
119
|
-
return
|
|
120
|
+
return url.trim();
|
|
120
121
|
}
|
|
121
122
|
};
|
|
122
123
|
var isValidRelativePath = (path) => {
|
|
@@ -127,10 +128,25 @@ var isValidRelativePath = (path) => {
|
|
|
127
128
|
if (sanitized.includes("..")) return false;
|
|
128
129
|
return true;
|
|
129
130
|
};
|
|
131
|
+
var formatZodError = (error) => {
|
|
132
|
+
if (!error.issues || error.issues.length === 0) {
|
|
133
|
+
return {};
|
|
134
|
+
}
|
|
135
|
+
return error.issues.reduce((previous, issue) => {
|
|
136
|
+
const key = issue.path.join(".");
|
|
137
|
+
return {
|
|
138
|
+
...previous,
|
|
139
|
+
[key]: {
|
|
140
|
+
code: issue.code,
|
|
141
|
+
message: issue.message
|
|
142
|
+
}
|
|
143
|
+
};
|
|
144
|
+
}, {});
|
|
145
|
+
};
|
|
130
146
|
|
|
131
147
|
// src/secure.ts
|
|
132
148
|
var generateSecure = (length = 32) => {
|
|
133
|
-
return
|
|
149
|
+
return import_crypto.default.randomBytes(length).toString("base64url");
|
|
134
150
|
};
|
|
135
151
|
var createCSRF = async (jose, csrfCookie) => {
|
|
136
152
|
try {
|
|
@@ -154,29 +170,40 @@ var cacheControl = {
|
|
|
154
170
|
Vary: "Cookie"
|
|
155
171
|
};
|
|
156
172
|
|
|
173
|
+
// src/request.ts
|
|
174
|
+
var fetchAsync = async (url, options2 = {}, timeout = 5e3) => {
|
|
175
|
+
const controller = new AbortController();
|
|
176
|
+
const timeoutId = setTimeout(() => controller.abort(), timeout);
|
|
177
|
+
const response = await fetch(url, {
|
|
178
|
+
...options2,
|
|
179
|
+
signal: controller.signal
|
|
180
|
+
}).finally(() => clearTimeout(timeoutId));
|
|
181
|
+
return response;
|
|
182
|
+
};
|
|
183
|
+
|
|
157
184
|
// src/schemas.ts
|
|
158
|
-
var
|
|
159
|
-
var OAuthProviderConfigSchema = (0,
|
|
160
|
-
authorizeURL: (0,
|
|
161
|
-
accessToken: (0,
|
|
162
|
-
scope: (0,
|
|
163
|
-
userInfo: (0,
|
|
164
|
-
responseType: (0,
|
|
165
|
-
clientId: (0,
|
|
166
|
-
clientSecret: (0,
|
|
185
|
+
var import_zod = require("zod");
|
|
186
|
+
var OAuthProviderConfigSchema = (0, import_zod.object)({
|
|
187
|
+
authorizeURL: (0, import_zod.string)().url(),
|
|
188
|
+
accessToken: (0, import_zod.string)().url(),
|
|
189
|
+
scope: (0, import_zod.string)().optional(),
|
|
190
|
+
userInfo: (0, import_zod.string)().url(),
|
|
191
|
+
responseType: (0, import_zod.enum)(["code", "token", "id_token"]),
|
|
192
|
+
clientId: (0, import_zod.string)(),
|
|
193
|
+
clientSecret: (0, import_zod.string)()
|
|
167
194
|
});
|
|
168
195
|
var OAuthAuthorization = OAuthProviderConfigSchema.extend({
|
|
169
|
-
redirectURI: (0,
|
|
170
|
-
state: (0,
|
|
171
|
-
codeChallenge: (0,
|
|
172
|
-
codeChallengeMethod: (0,
|
|
196
|
+
redirectURI: (0, import_zod.string)(),
|
|
197
|
+
state: (0, import_zod.string)(),
|
|
198
|
+
codeChallenge: (0, import_zod.string)(),
|
|
199
|
+
codeChallengeMethod: (0, import_zod.enum)(["plain", "S256"])
|
|
173
200
|
});
|
|
174
|
-
var OAuthAuthorizationResponse = (0,
|
|
175
|
-
state: (0,
|
|
176
|
-
code: (0,
|
|
201
|
+
var OAuthAuthorizationResponse = (0, import_zod.object)({
|
|
202
|
+
state: (0, import_zod.string)({ message: "Missing state parameter in the OAuth authorization response." }),
|
|
203
|
+
code: (0, import_zod.string)({ message: "Missing code parameter in the OAuth authorization response." })
|
|
177
204
|
});
|
|
178
|
-
var OAuthAuthorizationErrorResponse = (0,
|
|
179
|
-
error: (0,
|
|
205
|
+
var OAuthAuthorizationErrorResponse = (0, import_zod.object)({
|
|
206
|
+
error: (0, import_zod.enum)([
|
|
180
207
|
"invalid_request",
|
|
181
208
|
"unauthorized_client",
|
|
182
209
|
"access_denied",
|
|
@@ -185,24 +212,24 @@ var OAuthAuthorizationErrorResponse = (0, import_v4.object)({
|
|
|
185
212
|
"server_error",
|
|
186
213
|
"temporarily_unavailable"
|
|
187
214
|
]),
|
|
188
|
-
error_description: (0,
|
|
189
|
-
error_uri: (0,
|
|
190
|
-
state: (0,
|
|
215
|
+
error_description: (0, import_zod.string)().optional(),
|
|
216
|
+
error_uri: (0, import_zod.string)().optional(),
|
|
217
|
+
state: (0, import_zod.string)()
|
|
191
218
|
});
|
|
192
219
|
var OAuthAccessToken = OAuthProviderConfigSchema.extend({
|
|
193
|
-
redirectURI: (0,
|
|
194
|
-
code: (0,
|
|
195
|
-
codeVerifier: (0,
|
|
220
|
+
redirectURI: (0, import_zod.string)(),
|
|
221
|
+
code: (0, import_zod.string)(),
|
|
222
|
+
codeVerifier: (0, import_zod.string)().min(43).max(128)
|
|
196
223
|
});
|
|
197
|
-
var OAuthAccessTokenResponse = (0,
|
|
198
|
-
access_token: (0,
|
|
199
|
-
token_type: (0,
|
|
200
|
-
expires_in: (0,
|
|
201
|
-
refresh_token: (0,
|
|
202
|
-
scope: (0,
|
|
224
|
+
var OAuthAccessTokenResponse = (0, import_zod.object)({
|
|
225
|
+
access_token: (0, import_zod.string)(),
|
|
226
|
+
token_type: (0, import_zod.string)().optional(),
|
|
227
|
+
expires_in: (0, import_zod.number)().optional(),
|
|
228
|
+
refresh_token: (0, import_zod.string)().optional(),
|
|
229
|
+
scope: (0, import_zod.string)().optional().or((0, import_zod.null)())
|
|
203
230
|
});
|
|
204
|
-
var OAuthAccessTokenErrorResponse = (0,
|
|
205
|
-
error: (0,
|
|
231
|
+
var OAuthAccessTokenErrorResponse = (0, import_zod.object)({
|
|
232
|
+
error: (0, import_zod.enum)([
|
|
206
233
|
"invalid_request",
|
|
207
234
|
"invalid_client",
|
|
208
235
|
"invalid_grant",
|
|
@@ -210,12 +237,16 @@ var OAuthAccessTokenErrorResponse = (0, import_v4.object)({
|
|
|
210
237
|
"unsupported_grant_type",
|
|
211
238
|
"invalid_scope"
|
|
212
239
|
]),
|
|
213
|
-
error_description: (0,
|
|
214
|
-
error_uri: (0,
|
|
240
|
+
error_description: (0, import_zod.string)().optional(),
|
|
241
|
+
error_uri: (0, import_zod.string)().optional()
|
|
242
|
+
});
|
|
243
|
+
var OAuthErrorResponse = (0, import_zod.object)({
|
|
244
|
+
error: (0, import_zod.string)(),
|
|
245
|
+
error_description: (0, import_zod.string)().optional()
|
|
215
246
|
});
|
|
216
|
-
var
|
|
217
|
-
|
|
218
|
-
|
|
247
|
+
var OAuthEnvSchema = (0, import_zod.object)({
|
|
248
|
+
clientId: import_zod.z.string().min(1, "OAuth Client ID is required in the environment variables."),
|
|
249
|
+
clientSecret: import_zod.z.string().min(1, "OAuth Client Secret is required in the environment variables.")
|
|
219
250
|
});
|
|
220
251
|
|
|
221
252
|
// src/actions/callback/userinfo.ts
|
|
@@ -231,7 +262,7 @@ var getDefaultUserInfo = (profile) => {
|
|
|
231
262
|
var getUserInfo = async (oauthConfig, accessToken) => {
|
|
232
263
|
const userinfoEndpoint = oauthConfig.userInfo;
|
|
233
264
|
try {
|
|
234
|
-
const response = await
|
|
265
|
+
const response = await fetchAsync(userinfoEndpoint, {
|
|
235
266
|
method: "GET",
|
|
236
267
|
headers: {
|
|
237
268
|
Accept: "application/json",
|
|
@@ -241,18 +272,20 @@ var getUserInfo = async (oauthConfig, accessToken) => {
|
|
|
241
272
|
const json = await response.json();
|
|
242
273
|
const { success, data } = OAuthErrorResponse.safeParse(json);
|
|
243
274
|
if (success) {
|
|
244
|
-
throw new
|
|
275
|
+
throw new OAuthProtocolError(
|
|
276
|
+
data.error,
|
|
277
|
+
data?.error_description ?? "An error occurred while fetching user information."
|
|
278
|
+
);
|
|
245
279
|
}
|
|
246
280
|
return oauthConfig?.profile ? oauthConfig.profile(json) : getDefaultUserInfo(json);
|
|
247
281
|
} catch (error) {
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
}
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
return Response.json(body, init);
|
|
282
|
+
if (isOAuthProtocolError(error)) {
|
|
283
|
+
throw error;
|
|
284
|
+
}
|
|
285
|
+
if (isNativeError(error)) {
|
|
286
|
+
throw new OAuthProtocolError("invalid_request", error.message, "", { cause: error });
|
|
287
|
+
}
|
|
288
|
+
throw new OAuthProtocolError("invalid_request", "Failed to fetch user information.", "", { cause: error });
|
|
256
289
|
}
|
|
257
290
|
};
|
|
258
291
|
|
|
@@ -260,11 +293,12 @@ var AuraResponse = class extends Response {
|
|
|
260
293
|
var createAccessToken = async (oauthConfig, redirectURI, code, codeVerifier) => {
|
|
261
294
|
const parsed = OAuthAccessToken.safeParse({ ...oauthConfig, redirectURI, code, codeVerifier });
|
|
262
295
|
if (!parsed.success) {
|
|
263
|
-
|
|
296
|
+
const msg = JSON.stringify(formatZodError(parsed.error), null, 2);
|
|
297
|
+
throw new AuthInternalError("INVALID_OAUTH_CONFIGURATION", msg);
|
|
264
298
|
}
|
|
265
299
|
const { accessToken, clientId, clientSecret, code: codeParsed, redirectURI: redirectParsed } = parsed.data;
|
|
266
300
|
try {
|
|
267
|
-
const response = await
|
|
301
|
+
const response = await fetchAsync(accessToken, {
|
|
268
302
|
method: "POST",
|
|
269
303
|
headers: {
|
|
270
304
|
Accept: "application/json",
|
|
@@ -284,146 +318,68 @@ var createAccessToken = async (oauthConfig, redirectURI, code, codeVerifier) =>
|
|
|
284
318
|
if (!token.success) {
|
|
285
319
|
const { success, data } = OAuthAccessTokenErrorResponse.safeParse(json);
|
|
286
320
|
if (!success) {
|
|
287
|
-
throw new
|
|
321
|
+
throw new OAuthProtocolError("INVALID_REQUEST", "Invalid access token response format");
|
|
288
322
|
}
|
|
289
|
-
throw new
|
|
323
|
+
throw new OAuthProtocolError(data.error, data?.error_description ?? "Failed to retrieve access token");
|
|
290
324
|
}
|
|
291
325
|
return token.data;
|
|
292
326
|
} catch (error) {
|
|
293
|
-
throw
|
|
327
|
+
throw error;
|
|
294
328
|
}
|
|
295
329
|
};
|
|
296
330
|
|
|
297
331
|
// src/cookie.ts
|
|
298
|
-
var import_cookie = require("cookie");
|
|
299
|
-
|
|
300
|
-
// src/assert.ts
|
|
301
|
-
var isRequest = (value) => {
|
|
302
|
-
return typeof Request !== "undefined" && value instanceof Request;
|
|
303
|
-
};
|
|
304
|
-
|
|
305
|
-
// src/cookie.ts
|
|
306
|
-
var import_cookie2 = require("cookie");
|
|
307
|
-
var COOKIE_NAME = "aura-auth";
|
|
332
|
+
var import_cookie = require("@aura-stack/router/cookie");
|
|
308
333
|
var defaultCookieOptions = {
|
|
309
334
|
httpOnly: true,
|
|
310
335
|
sameSite: "lax",
|
|
311
336
|
path: "/",
|
|
312
337
|
maxAge: 60 * 60 * 24 * 15
|
|
313
338
|
};
|
|
314
|
-
var
|
|
315
|
-
secure: false,
|
|
339
|
+
var oauthCookieOptions = {
|
|
316
340
|
httpOnly: true,
|
|
317
|
-
|
|
318
|
-
|
|
319
|
-
|
|
320
|
-
secure: true,
|
|
321
|
-
prefix: "__Secure-"
|
|
322
|
-
};
|
|
323
|
-
var defaultHostCookieConfig = {
|
|
324
|
-
secure: true,
|
|
325
|
-
prefix: "__Host-",
|
|
326
|
-
path: "/",
|
|
327
|
-
domain: void 0
|
|
341
|
+
maxAge: 5 * 60,
|
|
342
|
+
sameSite: "lax",
|
|
343
|
+
expires: new Date(Date.now() + 5 * 60 * 1e3)
|
|
328
344
|
};
|
|
329
|
-
var
|
|
345
|
+
var expiredCookieAttributes = {
|
|
330
346
|
...defaultCookieOptions,
|
|
331
347
|
expires: /* @__PURE__ */ new Date(0),
|
|
332
348
|
maxAge: 0
|
|
333
349
|
};
|
|
334
|
-
var
|
|
335
|
-
|
|
336
|
-
name: options2?.name ?? COOKIE_NAME,
|
|
337
|
-
prefix: options2?.prefix ?? (options2?.secure ? "__Secure-" : ""),
|
|
338
|
-
...defaultCookieOptions,
|
|
339
|
-
...options2
|
|
340
|
-
};
|
|
341
|
-
};
|
|
342
|
-
var setCookie = (cookieName, value, options2) => {
|
|
343
|
-
const { prefix, name } = defineDefaultCookieOptions(options2);
|
|
344
|
-
const cookieNameWithPrefix = `${prefix}${name}.${cookieName}`;
|
|
345
|
-
return (0, import_cookie.serialize)(cookieNameWithPrefix, value, {
|
|
346
|
-
...defaultCookieOptions,
|
|
347
|
-
...options2
|
|
348
|
-
});
|
|
349
|
-
};
|
|
350
|
-
var getCookie = (petition, cookie, options2, optional = false) => {
|
|
351
|
-
const cookies = isRequest(petition) ? petition.headers.get("Cookie") : petition.headers.getSetCookie().join("; ");
|
|
350
|
+
var getCookie = (request, cookieName) => {
|
|
351
|
+
const cookies = request.headers.get("Cookie");
|
|
352
352
|
if (!cookies) {
|
|
353
|
-
|
|
354
|
-
return "";
|
|
355
|
-
}
|
|
356
|
-
throw new AuthError("invalid_request", "No cookies found. There is no active session");
|
|
353
|
+
throw new AuthInternalError("COOKIE_NOT_FOUND", "No cookies found. There is no active session");
|
|
357
354
|
}
|
|
358
|
-
const
|
|
359
|
-
|
|
360
|
-
|
|
361
|
-
if (value === void 0) {
|
|
362
|
-
if (optional) {
|
|
363
|
-
return "";
|
|
364
|
-
}
|
|
365
|
-
throw new AuthError("invalid_request", `Cookie "${cookie}" not found. There is no active session`);
|
|
355
|
+
const value = (0, import_cookie.parse)(cookies)[cookieName];
|
|
356
|
+
if (!value) {
|
|
357
|
+
throw new AuthInternalError("COOKIE_NOT_FOUND", `Cookie "${cookieName}" not found. There is no active session`);
|
|
366
358
|
}
|
|
367
359
|
return value;
|
|
368
360
|
};
|
|
369
|
-
var createSessionCookie = async (
|
|
361
|
+
var createSessionCookie = async (jose, session) => {
|
|
370
362
|
try {
|
|
371
363
|
const encoded = await jose.encodeJWT(session);
|
|
372
|
-
return
|
|
364
|
+
return encoded;
|
|
373
365
|
} catch (error) {
|
|
374
|
-
throw new
|
|
366
|
+
throw new AuthInternalError("INVALID_JWT_TOKEN", "Failed to create session cookie", { cause: error });
|
|
375
367
|
}
|
|
376
368
|
};
|
|
377
|
-
var secureCookieOptions = (request, cookieOptions, trustedProxyHeaders) => {
|
|
378
|
-
const name = cookieOptions.name ?? COOKIE_NAME;
|
|
379
|
-
const isSecure = trustedProxyHeaders ? request.url.startsWith("https://") || request.headers.get("X-Forwarded-Proto") === "https" || request.headers.get("Forwarded")?.includes("proto=https") : request.url.startsWith("https://");
|
|
380
|
-
if (!cookieOptions.options?.httpOnly) {
|
|
381
|
-
console.warn(
|
|
382
|
-
"[WARNING]: Cookie is configured without HttpOnly. This allows JavaScript access via document.cookie and increases XSS risk."
|
|
383
|
-
);
|
|
384
|
-
}
|
|
385
|
-
if (cookieOptions.options?.domain === "*") {
|
|
386
|
-
console.warn("[WARNING]: Cookie 'Domain' is set to '*', which is insecure. Avoid wildcard domains.");
|
|
387
|
-
}
|
|
388
|
-
if (!isSecure) {
|
|
389
|
-
const options2 = cookieOptions.options;
|
|
390
|
-
if (options2?.secure) {
|
|
391
|
-
console.warn(
|
|
392
|
-
"[WARNING]: The 'Secure' attribute will be disabled for this cookie. Serve over HTTPS to enforce Secure cookies."
|
|
393
|
-
);
|
|
394
|
-
}
|
|
395
|
-
if (options2?.sameSite == "none") {
|
|
396
|
-
console.warn("[WARNING]: SameSite=None without a secure connection can be blocked by browsers.");
|
|
397
|
-
}
|
|
398
|
-
if (process.env.NODE_ENV === "production") {
|
|
399
|
-
console.warn("[WARNING]: In production, ensure cookies are served over HTTPS to maintain security.");
|
|
400
|
-
}
|
|
401
|
-
return {
|
|
402
|
-
...defaultCookieOptions,
|
|
403
|
-
...cookieOptions.options,
|
|
404
|
-
sameSite: options2?.sameSite === "none" ? "lax" : options2?.sameSite ?? "lax",
|
|
405
|
-
...defaultStandardCookieConfig,
|
|
406
|
-
name
|
|
407
|
-
};
|
|
408
|
-
}
|
|
409
|
-
return cookieOptions.strategy === "host" ? {
|
|
410
|
-
...defaultCookieOptions,
|
|
411
|
-
...cookieOptions.options,
|
|
412
|
-
...defaultHostCookieConfig,
|
|
413
|
-
name
|
|
414
|
-
} : { ...defaultCookieOptions, ...cookieOptions.options, ...defaultSecureCookieConfig, name };
|
|
415
|
-
};
|
|
416
|
-
var expireCookie = (name, options2) => {
|
|
417
|
-
return setCookie(name, "", { ...options2, ...expiredCookieOptions });
|
|
418
|
-
};
|
|
419
369
|
|
|
420
370
|
// src/actions/callback/callback.ts
|
|
421
371
|
var callbackConfig = (oauth) => {
|
|
422
372
|
return (0, import_router2.createEndpointConfig)("/callback/:oauth", {
|
|
423
373
|
schemas: {
|
|
424
|
-
|
|
425
|
-
|
|
426
|
-
|
|
374
|
+
params: import_zod2.z.object({
|
|
375
|
+
oauth: import_zod2.z.enum(
|
|
376
|
+
Object.keys(oauth),
|
|
377
|
+
"The OAuth provider is not supported or invalid."
|
|
378
|
+
)
|
|
379
|
+
}),
|
|
380
|
+
searchParams: import_zod2.z.object({
|
|
381
|
+
code: import_zod2.z.string("Missing code parameter in the OAuth authorization response."),
|
|
382
|
+
state: import_zod2.z.string("Missing state parameter in the OAuth authorization response.")
|
|
427
383
|
})
|
|
428
384
|
},
|
|
429
385
|
middlewares: [
|
|
@@ -431,7 +387,7 @@ var callbackConfig = (oauth) => {
|
|
|
431
387
|
const response = OAuthAuthorizationErrorResponse.safeParse(ctx.searchParams);
|
|
432
388
|
if (response.success) {
|
|
433
389
|
const { error, error_description } = response.data;
|
|
434
|
-
throw new
|
|
390
|
+
throw new OAuthProtocolError(error, error_description ?? "OAuth Authorization Error");
|
|
435
391
|
}
|
|
436
392
|
return ctx;
|
|
437
393
|
}
|
|
@@ -447,66 +403,32 @@ var callbackAction = (oauth) => {
|
|
|
447
403
|
request,
|
|
448
404
|
params: { oauth: oauth2 },
|
|
449
405
|
searchParams: { code, state },
|
|
450
|
-
context: { oauth: providers, cookies, jose
|
|
406
|
+
context: { oauth: providers, cookies, jose }
|
|
451
407
|
} = ctx;
|
|
452
|
-
|
|
453
|
-
|
|
454
|
-
|
|
455
|
-
|
|
456
|
-
|
|
457
|
-
|
|
458
|
-
|
|
459
|
-
|
|
460
|
-
|
|
461
|
-
}
|
|
462
|
-
const accessToken = await createAccessToken(oauthConfig, cookieRedirectURI, code, codeVerifier);
|
|
463
|
-
const sanitized = sanitizeURL(cookieRedirectTo);
|
|
464
|
-
if (!isValidRelativePath(sanitized)) {
|
|
465
|
-
throw new AuthError(
|
|
466
|
-
ERROR_RESPONSE.ACCESS_TOKEN.INVALID_REQUEST,
|
|
467
|
-
"Invalid redirect path. Potential open redirect attack detected."
|
|
468
|
-
);
|
|
469
|
-
}
|
|
470
|
-
const headers = new Headers(cacheControl);
|
|
471
|
-
headers.set("Location", sanitized);
|
|
472
|
-
const userInfo = await getUserInfo(oauthConfig, accessToken.access_token);
|
|
473
|
-
const sessionCookie = await createSessionCookie(userInfo, cookieOptions, jose);
|
|
474
|
-
const csrfToken = await createCSRF(jose);
|
|
475
|
-
const csrfCookie = setCookie(
|
|
476
|
-
"csrfToken",
|
|
477
|
-
csrfToken,
|
|
478
|
-
secureCookieOptions(
|
|
479
|
-
request,
|
|
480
|
-
{
|
|
481
|
-
...cookies,
|
|
482
|
-
strategy: "host"
|
|
483
|
-
},
|
|
484
|
-
trustedProxyHeaders
|
|
485
|
-
)
|
|
408
|
+
const oauthConfig = providers[oauth2];
|
|
409
|
+
const cookieState = getCookie(request, cookies.state.name);
|
|
410
|
+
const cookieRedirectTo = getCookie(request, cookies.redirectTo.name);
|
|
411
|
+
const cookieRedirectURI = getCookie(request, cookies.redirectURI.name);
|
|
412
|
+
const codeVerifier = getCookie(request, cookies.codeVerifier.name);
|
|
413
|
+
if (!equals(cookieState, state)) {
|
|
414
|
+
throw new AuthSecurityError(
|
|
415
|
+
"MISMATCHING_STATE",
|
|
416
|
+
"The provided state passed in the OAuth response does not match the stored state."
|
|
486
417
|
);
|
|
487
|
-
|
|
488
|
-
|
|
489
|
-
|
|
490
|
-
|
|
491
|
-
|
|
492
|
-
|
|
493
|
-
|
|
494
|
-
} catch (error) {
|
|
495
|
-
if (isAuthError(error)) {
|
|
496
|
-
const { type, message } = error;
|
|
497
|
-
return AuraResponse.json(
|
|
498
|
-
{ error: type, error_description: message },
|
|
499
|
-
{ status: import_router2.statusCode.BAD_REQUEST }
|
|
500
|
-
);
|
|
501
|
-
}
|
|
502
|
-
return AuraResponse.json(
|
|
503
|
-
{
|
|
504
|
-
error: ERROR_RESPONSE.ACCESS_TOKEN.INVALID_CLIENT,
|
|
505
|
-
error_description: "An unexpected error occurred"
|
|
506
|
-
},
|
|
507
|
-
{ status: import_router2.statusCode.INTERNAL_SERVER_ERROR }
|
|
418
|
+
}
|
|
419
|
+
const accessToken = await createAccessToken(oauthConfig, cookieRedirectURI, code, codeVerifier);
|
|
420
|
+
const sanitized = sanitizeURL(cookieRedirectTo);
|
|
421
|
+
if (!isValidRelativePath(sanitized)) {
|
|
422
|
+
throw new AuthSecurityError(
|
|
423
|
+
"POTENTIAL_OPEN_REDIRECT_ATTACK_DETECTED",
|
|
424
|
+
"Invalid redirect path. Potential open redirect attack detected."
|
|
508
425
|
);
|
|
509
426
|
}
|
|
427
|
+
const userInfo = await getUserInfo(oauthConfig, accessToken.access_token);
|
|
428
|
+
const sessionCookie = await createSessionCookie(jose, userInfo);
|
|
429
|
+
const csrfToken = await createCSRF(jose);
|
|
430
|
+
const headers = new import_router2.HeadersBuilder(cacheControl).setHeader("Location", sanitized).setCookie(cookies.sessionToken.name, sessionCookie, cookies.sessionToken.attributes).setCookie(cookies.csrfToken.name, csrfToken, cookies.csrfToken.attributes).setCookie(cookies.state.name, "", expiredCookieAttributes).setCookie(cookies.redirectURI.name, "", expiredCookieAttributes).setCookie(cookies.redirectTo.name, "", expiredCookieAttributes).setCookie(cookies.codeVerifier.name, "", expiredCookieAttributes).toHeaders();
|
|
431
|
+
return Response.json({ oauth: oauth2 }, { status: 302, headers });
|
|
510
432
|
},
|
|
511
433
|
callbackConfig(oauth)
|
|
512
434
|
);
|
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
import * as _aura_stack_router from '@aura-stack/router';
|
|
2
|
-
import {
|
|
3
|
-
import 'zod
|
|
4
|
-
import '@aura-stack/jose/jose';
|
|
2
|
+
import { j as OAuthProviderRecord } from '../../index-DkaLJFn8.js';
|
|
3
|
+
import 'zod';
|
|
5
4
|
import '../../schemas.js';
|
|
6
|
-
import '
|
|
7
|
-
import '
|
|
5
|
+
import '@aura-stack/router/cookie';
|
|
6
|
+
import '@aura-stack/jose';
|
|
7
|
+
import '@aura-stack/jose/jose';
|
|
8
8
|
import '../../@types/utility.js';
|
|
9
9
|
|
|
10
|
-
declare const callbackAction: (oauth:
|
|
10
|
+
declare const callbackAction: (oauth: OAuthProviderRecord) => _aura_stack_router.RouteEndpoint<"GET", "/callback/:oauth", {}>;
|
|
11
11
|
|
|
12
12
|
export { callbackAction };
|
|
@@ -1,16 +1,16 @@
|
|
|
1
1
|
import {
|
|
2
2
|
callbackAction
|
|
3
|
-
} from "../../chunk-
|
|
4
|
-
import "../../chunk-
|
|
5
|
-
import "../../chunk-
|
|
6
|
-
import "../../chunk-
|
|
7
|
-
import "../../chunk-6SM22VVJ.js";
|
|
3
|
+
} from "../../chunk-KSWLO5ZU.js";
|
|
4
|
+
import "../../chunk-GA2SMTJO.js";
|
|
5
|
+
import "../../chunk-IVET23KF.js";
|
|
6
|
+
import "../../chunk-W6LG7BFW.js";
|
|
8
7
|
import "../../chunk-STHEPPUZ.js";
|
|
9
|
-
import "../../chunk-
|
|
10
|
-
import "../../chunk-
|
|
11
|
-
import "../../chunk-
|
|
12
|
-
import "../../chunk-
|
|
13
|
-
import "../../chunk-
|
|
8
|
+
import "../../chunk-N2APGLXA.js";
|
|
9
|
+
import "../../chunk-CXLATHS5.js";
|
|
10
|
+
import "../../chunk-EIL2FPSS.js";
|
|
11
|
+
import "../../chunk-RRLIF4PQ.js";
|
|
12
|
+
import "../../chunk-ZNCZVF6U.js";
|
|
13
|
+
import "../../chunk-YRCB5FLE.js";
|
|
14
14
|
export {
|
|
15
15
|
callbackAction
|
|
16
16
|
};
|