@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.
- package/dist/@types/index.d.ts +6 -2
- package/dist/@types/router.d.d.ts +6 -2
- package/dist/actions/callback/access-token.cjs +103 -59
- package/dist/actions/callback/access-token.d.ts +7 -3
- package/dist/actions/callback/access-token.js +3 -3
- package/dist/actions/callback/callback.cjs +200 -134
- package/dist/actions/callback/callback.d.ts +32 -3
- package/dist/actions/callback/callback.js +11 -12
- package/dist/actions/callback/userinfo.cjs +103 -70
- package/dist/actions/callback/userinfo.d.ts +6 -2
- package/dist/actions/callback/userinfo.js +7 -8
- package/dist/actions/csrfToken/csrfToken.cjs +7 -15
- package/dist/actions/csrfToken/csrfToken.d.ts +3 -1
- package/dist/actions/csrfToken/csrfToken.js +7 -8
- package/dist/actions/index.cjs +502 -295
- package/dist/actions/index.d.ts +5 -2
- package/dist/actions/index.js +23 -20
- package/dist/actions/session/session.cjs +76 -24
- package/dist/actions/session/session.d.ts +3 -1
- package/dist/actions/session/session.js +6 -4
- package/dist/actions/signIn/authorization-url.cjs +288 -0
- package/dist/actions/signIn/authorization-url.d.ts +31 -0
- package/dist/actions/signIn/authorization-url.js +16 -0
- package/dist/actions/signIn/authorization.cjs +91 -132
- package/dist/actions/signIn/authorization.d.ts +17 -16
- package/dist/actions/signIn/authorization.js +8 -7
- package/dist/actions/signIn/signIn.cjs +319 -191
- package/dist/actions/signIn/signIn.d.ts +32 -3
- package/dist/actions/signIn/signIn.js +10 -9
- package/dist/actions/signOut/signOut.cjs +211 -212
- package/dist/actions/signOut/signOut.d.ts +9 -1
- package/dist/actions/signOut/signOut.js +9 -10
- package/dist/api/createApi.cjs +750 -0
- package/dist/api/createApi.d.ts +12 -0
- package/dist/api/createApi.js +19 -0
- package/dist/api/getSession.cjs +141 -0
- package/dist/api/getSession.d.ts +16 -0
- package/dist/api/getSession.js +10 -0
- package/dist/api/signIn.cjs +549 -0
- package/dist/api/signIn.d.ts +26 -0
- package/dist/api/signIn.js +15 -0
- package/dist/api/signOut.cjs +279 -0
- package/dist/api/signOut.d.ts +16 -0
- package/dist/api/signOut.js +13 -0
- package/dist/assert.cjs +42 -9
- package/dist/assert.d.ts +8 -4
- package/dist/assert.js +5 -5
- package/dist/{chunk-KJBAQZX2.js → chunk-2A5B7GWR.js} +44 -11
- package/dist/chunk-2GQLSIJ2.js +40 -0
- package/dist/chunk-2IR674WX.js +44 -0
- package/dist/chunk-3J5TUH2I.js +50 -0
- package/dist/chunk-4RWSYUKX.js +98 -0
- package/dist/chunk-5X7JZMEF.js +0 -0
- package/dist/{chunk-TZB6MUXN.js → chunk-7BE46WWS.js} +21 -11
- package/dist/chunk-7YYXFKLR.js +35 -0
- package/dist/chunk-C3A37LQC.js +33 -0
- package/dist/chunk-CITNGXDA.js +31 -0
- package/dist/chunk-CWX724AG.js +78 -0
- package/dist/chunk-D2CSIUKP.js +74 -0
- package/dist/{chunk-ICAZ4OVS.js → chunk-FPCVZUVG.js} +2 -2
- package/dist/{chunk-XGLBNXL4.js → chunk-GNNBM2WJ.js} +17 -9
- package/dist/chunk-JOCGX3RP.js +59 -0
- package/dist/chunk-KBXWTD6E.js +94 -0
- package/dist/{chunk-XUP6KKNG.js → chunk-LATR3NIV.js} +48 -37
- package/dist/chunk-LAYPUDQF.js +39 -0
- package/dist/chunk-LX3TJ2TJ.js +294 -0
- package/dist/{chunk-6MXFPFR3.js → chunk-NHZBQNRR.js} +19 -19
- package/dist/{chunk-TM5IPSNF.js → chunk-PDP3PHB3.js} +33 -19
- package/dist/chunk-PHYNROD4.js +47 -0
- package/dist/chunk-QQEKY4XP.js +29 -0
- package/dist/{chunk-VNCNJKS2.js → chunk-U4RK4LKJ.js} +82 -1
- package/dist/{chunk-RRLIF4PQ.js → chunk-U5663F2U.js} +16 -1
- package/dist/chunk-UN7X6SU5.js +53 -0
- package/dist/chunk-UZQJJD6A.js +100 -0
- package/dist/{chunk-NUDITUKX.js → chunk-V6LLEAR4.js} +22 -15
- package/dist/{chunk-4MYWAOLG.js → chunk-WHNDRO3N.js} +20 -1
- package/dist/{chunk-5W4BRQYG.js → chunk-XY5R3EHH.js} +6 -3
- package/dist/client/client.cjs +135 -0
- package/dist/client/client.d.ts +85 -0
- package/dist/client/client.js +9 -0
- package/dist/client/index.cjs +135 -0
- package/dist/client/index.d.ts +14 -0
- package/dist/client/index.js +10 -0
- package/dist/context.cjs +1237 -0
- package/dist/context.d.ts +16 -0
- package/dist/context.js +28 -0
- package/dist/cookie.cjs +33 -2
- package/dist/cookie.d.ts +9 -5
- package/dist/cookie.js +3 -2
- package/dist/createAuth.cjs +2320 -0
- package/dist/createAuth.d.ts +12 -0
- package/dist/createAuth.js +48 -0
- package/dist/env.cjs +24 -2
- package/dist/env.d.ts +4 -1
- package/dist/env.js +9 -3
- package/dist/errors.cjs +17 -0
- package/dist/errors.d.ts +13 -3
- package/dist/errors.js +5 -1
- package/dist/{index-CSyIJmCM.d.ts → index-_aXtxb_s.d.ts} +383 -13
- package/dist/index.cjs +2135 -1547
- package/dist/index.d.ts +9 -30
- package/dist/index.js +46 -119
- package/dist/jose.cjs +52 -14
- package/dist/jose.d.ts +12 -25
- package/dist/jose.js +11 -3
- package/dist/logger.cjs +132 -0
- package/dist/logger.d.ts +6 -2
- package/dist/logger.js +10 -1
- package/dist/oauth/atlassian.cjs +57 -0
- package/dist/oauth/atlassian.d.ts +12 -0
- package/dist/oauth/atlassian.js +6 -0
- package/dist/oauth/bitbucket.d.ts +6 -2
- package/dist/oauth/discord.d.ts +6 -2
- package/dist/oauth/dropbox.cjs +53 -0
- package/dist/oauth/dropbox.d.ts +12 -0
- package/dist/oauth/dropbox.js +6 -0
- package/dist/oauth/figma.d.ts +6 -2
- package/dist/oauth/github.d.ts +6 -2
- package/dist/oauth/gitlab.d.ts +6 -2
- package/dist/oauth/index.cjs +278 -88
- package/dist/oauth/index.d.ts +6 -2
- package/dist/oauth/index.js +27 -11
- package/dist/oauth/mailchimp.d.ts +6 -2
- package/dist/oauth/notion.cjs +131 -0
- package/dist/oauth/notion.d.ts +12 -0
- package/dist/oauth/notion.js +9 -0
- package/dist/oauth/pinterest.d.ts +6 -2
- package/dist/oauth/spotify.d.ts +6 -2
- package/dist/oauth/strava.d.ts +6 -2
- package/dist/oauth/twitch.cjs +95 -0
- package/dist/oauth/twitch.d.ts +12 -0
- package/dist/oauth/twitch.js +7 -0
- package/dist/oauth/x.d.ts +6 -2
- package/dist/schemas.cjs +84 -51
- package/dist/schemas.d.ts +103 -23
- package/dist/schemas.js +1 -1
- package/dist/secure.cjs +36 -36
- package/dist/secure.d.ts +10 -4
- package/dist/secure.js +7 -6
- package/dist/utils.cjs +109 -3
- package/dist/utils.d.ts +15 -4
- package/dist/utils.js +11 -4
- package/package.json +9 -5
- package/dist/chunk-4EKY7655.js +0 -123
- package/dist/chunk-7QF22LHP.js +0 -67
- package/dist/chunk-ALG3GIV4.js +0 -95
- package/dist/chunk-FRJFWTOY.js +0 -70
- package/dist/chunk-PHFH2MGS.js +0 -36
- package/dist/chunk-QQVSRXGX.js +0 -149
package/dist/actions/index.cjs
CHANGED
|
@@ -1,9 +1,7 @@
|
|
|
1
1
|
"use strict";
|
|
2
|
-
var __create = Object.create;
|
|
3
2
|
var __defProp = Object.defineProperty;
|
|
4
3
|
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
5
4
|
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
6
|
-
var __getProtoOf = Object.getPrototypeOf;
|
|
7
5
|
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
8
6
|
var __export = (target, all) => {
|
|
9
7
|
for (var name in all)
|
|
@@ -17,14 +15,6 @@ var __copyProps = (to, from, except, desc) => {
|
|
|
17
15
|
}
|
|
18
16
|
return to;
|
|
19
17
|
};
|
|
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
18
|
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
|
29
19
|
|
|
30
20
|
// src/actions/index.ts
|
|
@@ -39,8 +29,7 @@ __export(actions_exports, {
|
|
|
39
29
|
module.exports = __toCommonJS(actions_exports);
|
|
40
30
|
|
|
41
31
|
// src/actions/signIn/signIn.ts
|
|
42
|
-
var
|
|
43
|
-
var import_router2 = require("@aura-stack/router");
|
|
32
|
+
var import_v42 = require("zod/v4");
|
|
44
33
|
|
|
45
34
|
// src/headers.ts
|
|
46
35
|
var cacheControl = {
|
|
@@ -70,12 +59,6 @@ var secureApiHeaders = {
|
|
|
70
59
|
...secureHeaders
|
|
71
60
|
};
|
|
72
61
|
|
|
73
|
-
// src/secure.ts
|
|
74
|
-
var import_crypto2 = __toESM(require("crypto"), 1);
|
|
75
|
-
|
|
76
|
-
// src/utils.ts
|
|
77
|
-
var import_router = require("@aura-stack/router");
|
|
78
|
-
|
|
79
62
|
// src/errors.ts
|
|
80
63
|
var OAuthProtocolError = class extends Error {
|
|
81
64
|
type = "OAUTH_PROTOCOL_ERROR";
|
|
@@ -116,44 +99,160 @@ var isOAuthProtocolError = (error) => {
|
|
|
116
99
|
return error instanceof OAuthProtocolError;
|
|
117
100
|
};
|
|
118
101
|
|
|
102
|
+
// src/api/signIn.ts
|
|
103
|
+
var import_router2 = require("@aura-stack/router");
|
|
104
|
+
|
|
105
|
+
// src/schemas.ts
|
|
106
|
+
var import_v4 = require("zod/v4");
|
|
107
|
+
var AuthorizeConfigSchema = import_v4.z.union([
|
|
108
|
+
(0, import_v4.string)().url(),
|
|
109
|
+
(0, import_v4.object)({
|
|
110
|
+
url: (0, import_v4.string)().url(),
|
|
111
|
+
params: (0, import_v4.object)({
|
|
112
|
+
responseType: (0, import_v4.enum)(["code", "token", "id_token", "refresh_token"]).optional(),
|
|
113
|
+
scope: (0, import_v4.string)().optional()
|
|
114
|
+
})
|
|
115
|
+
})
|
|
116
|
+
]);
|
|
117
|
+
var AccessTokenConfigSchema = import_v4.z.union([
|
|
118
|
+
(0, import_v4.string)().url(),
|
|
119
|
+
(0, import_v4.object)({
|
|
120
|
+
url: (0, import_v4.string)().url(),
|
|
121
|
+
headers: import_v4.z.record((0, import_v4.string)(), (0, import_v4.string)()).optional()
|
|
122
|
+
})
|
|
123
|
+
]);
|
|
124
|
+
var UserInfoConfigSchema = import_v4.z.union([
|
|
125
|
+
(0, import_v4.string)().url(),
|
|
126
|
+
(0, import_v4.object)({
|
|
127
|
+
url: (0, import_v4.string)().url(),
|
|
128
|
+
headers: import_v4.z.record((0, import_v4.string)(), (0, import_v4.string)()).optional(),
|
|
129
|
+
method: (0, import_v4.string)().optional()
|
|
130
|
+
})
|
|
131
|
+
]);
|
|
132
|
+
var OAuthProviderCredentialsSchema = (0, import_v4.object)({
|
|
133
|
+
id: (0, import_v4.string)(),
|
|
134
|
+
name: (0, import_v4.string)(),
|
|
135
|
+
authorize: AuthorizeConfigSchema.optional(),
|
|
136
|
+
/** @deprecated */
|
|
137
|
+
authorizeURL: (0, import_v4.string)().url().optional(),
|
|
138
|
+
accessToken: AccessTokenConfigSchema,
|
|
139
|
+
/** @deprecated */
|
|
140
|
+
scope: (0, import_v4.string)().optional(),
|
|
141
|
+
userInfo: UserInfoConfigSchema,
|
|
142
|
+
/** @deprecated */
|
|
143
|
+
responseType: (0, import_v4.enum)(["code", "token", "id_token", "refresh_token"]).optional(),
|
|
144
|
+
clientId: (0, import_v4.string)(),
|
|
145
|
+
clientSecret: (0, import_v4.string)(),
|
|
146
|
+
profile: import_v4.z.function().optional()
|
|
147
|
+
});
|
|
148
|
+
var OAuthProviderConfigSchema = (0, import_v4.object)({
|
|
149
|
+
authorize: AuthorizeConfigSchema.optional(),
|
|
150
|
+
/** @deprecated */
|
|
151
|
+
authorizeURL: (0, import_v4.string)().url().optional(),
|
|
152
|
+
accessToken: AccessTokenConfigSchema,
|
|
153
|
+
/** @deprecated */
|
|
154
|
+
scope: (0, import_v4.string)().optional(),
|
|
155
|
+
userInfo: UserInfoConfigSchema,
|
|
156
|
+
/** @deprecated */
|
|
157
|
+
responseType: (0, import_v4.enum)(["code", "token", "id_token", "refresh_token"]).optional(),
|
|
158
|
+
clientId: (0, import_v4.string)(),
|
|
159
|
+
clientSecret: (0, import_v4.string)()
|
|
160
|
+
});
|
|
161
|
+
var OAuthAuthorization = OAuthProviderConfigSchema.extend({
|
|
162
|
+
redirectURI: (0, import_v4.string)(),
|
|
163
|
+
state: (0, import_v4.string)(),
|
|
164
|
+
codeChallenge: (0, import_v4.string)(),
|
|
165
|
+
codeChallengeMethod: (0, import_v4.enum)(["plain", "S256"])
|
|
166
|
+
});
|
|
167
|
+
var OAuthAuthorizationResponse = (0, import_v4.object)({
|
|
168
|
+
state: (0, import_v4.string)({ message: "Missing state parameter in the OAuth authorization response." }),
|
|
169
|
+
code: (0, import_v4.string)({ message: "Missing code parameter in the OAuth authorization response." })
|
|
170
|
+
});
|
|
171
|
+
var OAuthAuthorizationErrorResponse = (0, import_v4.object)({
|
|
172
|
+
error: (0, import_v4.enum)([
|
|
173
|
+
"invalid_request",
|
|
174
|
+
"unauthorized_client",
|
|
175
|
+
"access_denied",
|
|
176
|
+
"unsupported_response_type",
|
|
177
|
+
"invalid_scope",
|
|
178
|
+
"server_error",
|
|
179
|
+
"temporarily_unavailable"
|
|
180
|
+
]),
|
|
181
|
+
error_description: (0, import_v4.string)().optional(),
|
|
182
|
+
error_uri: (0, import_v4.string)().optional(),
|
|
183
|
+
state: (0, import_v4.string)()
|
|
184
|
+
});
|
|
185
|
+
var OAuthAccessToken = OAuthProviderConfigSchema.extend({
|
|
186
|
+
redirectURI: (0, import_v4.string)(),
|
|
187
|
+
code: (0, import_v4.string)(),
|
|
188
|
+
codeVerifier: (0, import_v4.string)().min(43).max(128)
|
|
189
|
+
});
|
|
190
|
+
var OAuthAccessTokenResponse = (0, import_v4.object)({
|
|
191
|
+
access_token: (0, import_v4.string)(),
|
|
192
|
+
token_type: (0, import_v4.string)().optional(),
|
|
193
|
+
expires_in: (0, import_v4.number)().optional(),
|
|
194
|
+
refresh_token: (0, import_v4.string)().optional(),
|
|
195
|
+
scope: (0, import_v4.union)([(0, import_v4.string)().optional().or((0, import_v4.null)()), (0, import_v4.array)((0, import_v4.string)()).optional()])
|
|
196
|
+
});
|
|
197
|
+
var OAuthAccessTokenErrorResponse = (0, import_v4.object)({
|
|
198
|
+
error: (0, import_v4.enum)([
|
|
199
|
+
"invalid_request",
|
|
200
|
+
"invalid_client",
|
|
201
|
+
"invalid_grant",
|
|
202
|
+
"unauthorized_client",
|
|
203
|
+
"unsupported_grant_type",
|
|
204
|
+
"invalid_scope"
|
|
205
|
+
]),
|
|
206
|
+
error_description: (0, import_v4.string)().optional(),
|
|
207
|
+
error_uri: (0, import_v4.string)().optional()
|
|
208
|
+
});
|
|
209
|
+
var OAuthErrorResponse = (0, import_v4.object)({
|
|
210
|
+
error: (0, import_v4.string)(),
|
|
211
|
+
error_description: (0, import_v4.string)().optional()
|
|
212
|
+
});
|
|
213
|
+
var OAuthEnvSchema = (0, import_v4.object)({
|
|
214
|
+
clientId: import_v4.z.string().min(1, "OAuth Client ID is required in the environment variables."),
|
|
215
|
+
clientSecret: import_v4.z.string().min(1, "OAuth Client Secret is required in the environment variables.")
|
|
216
|
+
});
|
|
217
|
+
|
|
119
218
|
// src/utils.ts
|
|
120
|
-
var
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
var
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
}
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
}
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
}
|
|
148
|
-
var getErrorName = (error) => {
|
|
149
|
-
if (error instanceof Error) {
|
|
150
|
-
return error.name;
|
|
219
|
+
var import_router = require("@aura-stack/router");
|
|
220
|
+
|
|
221
|
+
// src/env.ts
|
|
222
|
+
var import_meta = {};
|
|
223
|
+
var env = new Proxy({}, {
|
|
224
|
+
get(_, prop) {
|
|
225
|
+
if (typeof prop !== "string") return void 0;
|
|
226
|
+
const hasProperty = (process2) => {
|
|
227
|
+
return process2 && Object.prototype.hasOwnProperty.call(process2, prop);
|
|
228
|
+
};
|
|
229
|
+
try {
|
|
230
|
+
if (typeof process !== "undefined" && hasProperty(process.env)) {
|
|
231
|
+
return process.env[prop];
|
|
232
|
+
}
|
|
233
|
+
if (typeof import_meta !== "undefined" && hasProperty(import_meta.env)) {
|
|
234
|
+
return import_meta.env[prop];
|
|
235
|
+
}
|
|
236
|
+
if (typeof Deno !== "undefined" && Deno.env?.get) {
|
|
237
|
+
return Deno.env.get(prop);
|
|
238
|
+
}
|
|
239
|
+
if (typeof Bun !== "undefined" && hasProperty(Bun.env)) {
|
|
240
|
+
return Bun.env[prop];
|
|
241
|
+
}
|
|
242
|
+
const globalValue = globalThis[prop];
|
|
243
|
+
return typeof globalValue === "string" ? globalValue : void 0;
|
|
244
|
+
} catch {
|
|
245
|
+
return void 0;
|
|
246
|
+
}
|
|
151
247
|
}
|
|
152
|
-
|
|
248
|
+
});
|
|
249
|
+
var getEnv = (key) => {
|
|
250
|
+
const keys = [`AURA_AUTH_${key.toUpperCase()}`, `AURA_${key.toUpperCase()}`, `AUTH_${key.toUpperCase()}`, key.toUpperCase()];
|
|
251
|
+
return env[keys.find((k) => env[k]) ?? ""];
|
|
153
252
|
};
|
|
154
253
|
|
|
155
254
|
// src/assert.ts
|
|
156
|
-
var import_crypto = require("crypto");
|
|
255
|
+
var import_crypto = require("@aura-stack/jose/crypto");
|
|
157
256
|
var unsafeChars = [
|
|
158
257
|
"<",
|
|
159
258
|
">",
|
|
@@ -244,46 +343,46 @@ var isTrustedOrigin = (url, trustedOrigins) => {
|
|
|
244
343
|
}
|
|
245
344
|
return false;
|
|
246
345
|
};
|
|
247
|
-
var
|
|
248
|
-
const bufferA =
|
|
249
|
-
const bufferB =
|
|
250
|
-
|
|
251
|
-
|
|
346
|
+
var timingSafeEqual = (a, b) => {
|
|
347
|
+
const bufferA = import_crypto.encoder.encode(a);
|
|
348
|
+
const bufferB = import_crypto.encoder.encode(b);
|
|
349
|
+
const len = Math.max(bufferA.length, bufferB.length);
|
|
350
|
+
let diff = 0;
|
|
351
|
+
for (let i = 0; i < len; i++) {
|
|
352
|
+
diff |= (bufferA[i] ?? 0) ^ (bufferB[i] ?? 0);
|
|
252
353
|
}
|
|
253
|
-
return
|
|
354
|
+
return diff === 0 && bufferA.length === bufferB.length;
|
|
254
355
|
};
|
|
255
356
|
|
|
256
|
-
// src/
|
|
257
|
-
var
|
|
258
|
-
var
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
const globalValue = globalThis[prop];
|
|
278
|
-
return typeof globalValue === "string" ? globalValue : void 0;
|
|
279
|
-
} catch {
|
|
280
|
-
return void 0;
|
|
281
|
-
}
|
|
357
|
+
// src/utils.ts
|
|
358
|
+
var AURA_AUTH_VERSION = "0.4.0";
|
|
359
|
+
var equals = (a, b) => {
|
|
360
|
+
if (a === null || b === null || a === void 0 || b === void 0) return false;
|
|
361
|
+
return a === b;
|
|
362
|
+
};
|
|
363
|
+
var getBaseURL = (request) => {
|
|
364
|
+
const url = new URL(request.url);
|
|
365
|
+
return `${url.origin}${url.pathname}`;
|
|
366
|
+
};
|
|
367
|
+
var toISOString = (date) => {
|
|
368
|
+
return new Date(date).toISOString();
|
|
369
|
+
};
|
|
370
|
+
var extractPath = (url) => {
|
|
371
|
+
const pathRegex = /^https?:\/\/[a-zA-Z0-9_\-\.]+(:\d+)?(\/.*)$/;
|
|
372
|
+
const match = url.match(pathRegex);
|
|
373
|
+
return match && match[2] ? match[2] : "/";
|
|
374
|
+
};
|
|
375
|
+
var getErrorName = (error) => {
|
|
376
|
+
if (error instanceof Error) {
|
|
377
|
+
return error.name;
|
|
282
378
|
}
|
|
283
|
-
|
|
379
|
+
return typeof error === "string" ? error : "UnknownError";
|
|
380
|
+
};
|
|
284
381
|
|
|
285
382
|
// src/jose.ts
|
|
286
383
|
var import_jose = require("@aura-stack/jose");
|
|
384
|
+
var import_jose2 = require("@aura-stack/jose/jose");
|
|
385
|
+
var import_crypto2 = require("@aura-stack/jose/crypto");
|
|
287
386
|
var jwtVerificationOptions = {
|
|
288
387
|
algorithms: ["HS256"],
|
|
289
388
|
typ: "JWT"
|
|
@@ -291,10 +390,15 @@ var jwtVerificationOptions = {
|
|
|
291
390
|
|
|
292
391
|
// src/secure.ts
|
|
293
392
|
var generateSecure = (length = 32) => {
|
|
294
|
-
return
|
|
393
|
+
return import_jose2.base64url.encode((0, import_crypto2.getRandomBytes)(length));
|
|
394
|
+
};
|
|
395
|
+
var createSecretValue = (length = 32) => {
|
|
396
|
+
return import_jose2.base64url.encode((0, import_crypto2.getRandomBytes)(length));
|
|
295
397
|
};
|
|
296
|
-
var createHash = (data
|
|
297
|
-
|
|
398
|
+
var createHash = async (data) => {
|
|
399
|
+
const subtle = (0, import_crypto2.getSubtleCrypto)();
|
|
400
|
+
const digest = await subtle.digest("SHA-256", import_crypto2.encoder.encode(data));
|
|
401
|
+
return import_jose2.base64url.encode(new Uint8Array(digest));
|
|
298
402
|
};
|
|
299
403
|
var createPKCE = async (verifier) => {
|
|
300
404
|
const byteLength = verifier ? void 0 : Math.floor(Math.random() * (96 - 32 + 1) + 32);
|
|
@@ -302,7 +406,7 @@ var createPKCE = async (verifier) => {
|
|
|
302
406
|
if (codeVerifier.length < 43 || codeVerifier.length > 128) {
|
|
303
407
|
throw new AuthSecurityError("PKCE_VERIFIER_INVALID", "The code verifier must be between 43 and 128 characters in length.");
|
|
304
408
|
}
|
|
305
|
-
const codeChallenge = createHash(codeVerifier
|
|
409
|
+
const codeChallenge = await createHash(codeVerifier);
|
|
306
410
|
return { codeVerifier, codeChallenge, method: "S256" };
|
|
307
411
|
};
|
|
308
412
|
var createCSRF = async (jose, csrfCookie) => {
|
|
@@ -331,7 +435,7 @@ var verifyCSRF = async (jose, cookie, header) => {
|
|
|
331
435
|
if (!equals(cookiePayload.token.length, headerPayload.token.length)) {
|
|
332
436
|
throw new AuthSecurityError("CSRF_TOKEN_INVALID", "The CSRF tokens do not match.");
|
|
333
437
|
}
|
|
334
|
-
if (!
|
|
438
|
+
if (!timingSafeEqual(cookiePayload.token, headerPayload.token)) {
|
|
335
439
|
throw new AuthSecurityError("CSRF_TOKEN_INVALID", "The CSRF tokens do not match.");
|
|
336
440
|
}
|
|
337
441
|
return true;
|
|
@@ -340,121 +444,101 @@ var verifyCSRF = async (jose, cookie, header) => {
|
|
|
340
444
|
}
|
|
341
445
|
};
|
|
342
446
|
|
|
343
|
-
// src/
|
|
344
|
-
var
|
|
345
|
-
|
|
346
|
-
|
|
347
|
-
|
|
348
|
-
|
|
349
|
-
|
|
350
|
-
|
|
351
|
-
|
|
352
|
-
|
|
353
|
-
|
|
354
|
-
|
|
355
|
-
|
|
356
|
-
}
|
|
357
|
-
|
|
358
|
-
|
|
359
|
-
|
|
360
|
-
|
|
361
|
-
|
|
362
|
-
|
|
363
|
-
|
|
364
|
-
|
|
365
|
-
|
|
366
|
-
|
|
367
|
-
|
|
368
|
-
|
|
369
|
-
|
|
370
|
-
|
|
371
|
-
|
|
372
|
-
|
|
373
|
-
|
|
374
|
-
|
|
375
|
-
}
|
|
376
|
-
var
|
|
377
|
-
|
|
378
|
-
|
|
379
|
-
|
|
380
|
-
|
|
381
|
-
"unsupported_response_type",
|
|
382
|
-
"invalid_scope",
|
|
383
|
-
"server_error",
|
|
384
|
-
"temporarily_unavailable"
|
|
385
|
-
]),
|
|
386
|
-
error_description: (0, import_zod.string)().optional(),
|
|
387
|
-
error_uri: (0, import_zod.string)().optional(),
|
|
388
|
-
state: (0, import_zod.string)()
|
|
389
|
-
});
|
|
390
|
-
var OAuthAccessToken = OAuthProviderConfigSchema.extend({
|
|
391
|
-
redirectURI: (0, import_zod.string)(),
|
|
392
|
-
code: (0, import_zod.string)(),
|
|
393
|
-
codeVerifier: (0, import_zod.string)().min(43).max(128)
|
|
394
|
-
});
|
|
395
|
-
var OAuthAccessTokenResponse = (0, import_zod.object)({
|
|
396
|
-
access_token: (0, import_zod.string)(),
|
|
397
|
-
token_type: (0, import_zod.string)().optional(),
|
|
398
|
-
expires_in: (0, import_zod.number)().optional(),
|
|
399
|
-
refresh_token: (0, import_zod.string)().optional(),
|
|
400
|
-
scope: (0, import_zod.string)().optional().or((0, import_zod.null)())
|
|
401
|
-
});
|
|
402
|
-
var OAuthAccessTokenErrorResponse = (0, import_zod.object)({
|
|
403
|
-
error: (0, import_zod.enum)([
|
|
404
|
-
"invalid_request",
|
|
405
|
-
"invalid_client",
|
|
406
|
-
"invalid_grant",
|
|
407
|
-
"unauthorized_client",
|
|
408
|
-
"unsupported_grant_type",
|
|
409
|
-
"invalid_scope"
|
|
410
|
-
]),
|
|
411
|
-
error_description: (0, import_zod.string)().optional(),
|
|
412
|
-
error_uri: (0, import_zod.string)().optional()
|
|
413
|
-
});
|
|
414
|
-
var OAuthErrorResponse = (0, import_zod.object)({
|
|
415
|
-
error: (0, import_zod.string)(),
|
|
416
|
-
error_description: (0, import_zod.string)().optional()
|
|
417
|
-
});
|
|
418
|
-
var OAuthEnvSchema = (0, import_zod.object)({
|
|
419
|
-
clientId: import_zod.z.string().min(1, "OAuth Client ID is required in the environment variables."),
|
|
420
|
-
clientSecret: import_zod.z.string().min(1, "OAuth Client Secret is required in the environment variables.")
|
|
421
|
-
});
|
|
422
|
-
|
|
423
|
-
// src/actions/signIn/authorization.ts
|
|
424
|
-
var createAuthorizationURL = (oauthConfig, redirectURI, state, codeChallenge, codeChallengeMethod, logger) => {
|
|
425
|
-
const parsed = OAuthAuthorization.safeParse({ ...oauthConfig, redirectURI, state, codeChallenge, codeChallengeMethod });
|
|
447
|
+
// src/actions/signIn/authorization-url.ts
|
|
448
|
+
var setSearchParams = (url, params) => {
|
|
449
|
+
for (const [key, value] of Object.entries(params)) {
|
|
450
|
+
if (value !== void 0 && value !== "") {
|
|
451
|
+
url.searchParams.set(key, value);
|
|
452
|
+
}
|
|
453
|
+
}
|
|
454
|
+
};
|
|
455
|
+
var buildAuthorizationURL = (oauth, redirect_uri, state, code_challenge, code_challenge_method) => {
|
|
456
|
+
const authorizeConfig = oauth.authorize;
|
|
457
|
+
const baseURL = typeof authorizeConfig === "string" ? authorizeConfig : authorizeConfig?.url ?? oauth.authorizeURL;
|
|
458
|
+
if (!baseURL) {
|
|
459
|
+
throw new AuthInternalError("INVALID_OAUTH_CONFIGURATION", "Missing authorization URL in OAuth provider configuration.");
|
|
460
|
+
}
|
|
461
|
+
const url = new URL(baseURL);
|
|
462
|
+
const authorizeParams = typeof authorizeConfig === "string" ? void 0 : authorizeConfig?.params;
|
|
463
|
+
setSearchParams(url, {
|
|
464
|
+
response_type: authorizeParams?.responseType ?? oauth.responseType ?? "code",
|
|
465
|
+
client_id: oauth.clientId,
|
|
466
|
+
redirect_uri,
|
|
467
|
+
state,
|
|
468
|
+
code_challenge,
|
|
469
|
+
code_challenge_method,
|
|
470
|
+
scope: authorizeParams?.scope ?? oauth.scope,
|
|
471
|
+
prompt: authorizeParams?.prompt,
|
|
472
|
+
response_mode: authorizeParams?.responseMode,
|
|
473
|
+
login_hint: authorizeParams?.loginHint,
|
|
474
|
+
nonce: authorizeParams?.nonce,
|
|
475
|
+
display: authorizeParams?.display,
|
|
476
|
+
audience: authorizeParams?.audience
|
|
477
|
+
});
|
|
478
|
+
return url.toString();
|
|
479
|
+
};
|
|
480
|
+
var createAuthorizationURL = async (oauth, redirectURI, ctx) => {
|
|
481
|
+
const state = createSecretValue();
|
|
482
|
+
const { codeVerifier, codeChallenge, method } = await createPKCE();
|
|
483
|
+
const authorization = buildAuthorizationURL(oauth, redirectURI, state, codeChallenge, method);
|
|
484
|
+
const parsed = OAuthAuthorization.safeParse({ ...oauth, redirectURI, state, codeChallenge, codeChallengeMethod: method });
|
|
426
485
|
if (!parsed.success) {
|
|
427
|
-
logger?.log("INVALID_OAUTH_CONFIGURATION", {
|
|
486
|
+
ctx?.logger?.log("INVALID_OAUTH_CONFIGURATION", {
|
|
428
487
|
structuredData: {
|
|
429
|
-
scope:
|
|
488
|
+
scope: oauth?.scope ?? "",
|
|
430
489
|
redirect_uri: redirectURI,
|
|
431
490
|
has_state: Boolean(state),
|
|
432
491
|
has_code_challenge: Boolean(codeChallenge),
|
|
433
|
-
code_challenge_method:
|
|
492
|
+
code_challenge_method: method
|
|
434
493
|
}
|
|
435
494
|
});
|
|
436
495
|
throw new AuthInternalError("INVALID_OAUTH_CONFIGURATION", "The OAuth provider configuration is invalid.");
|
|
437
496
|
}
|
|
438
|
-
|
|
439
|
-
|
|
440
|
-
|
|
441
|
-
|
|
497
|
+
return {
|
|
498
|
+
authorization,
|
|
499
|
+
state,
|
|
500
|
+
codeVerifier,
|
|
501
|
+
method
|
|
502
|
+
};
|
|
442
503
|
};
|
|
504
|
+
|
|
505
|
+
// src/actions/signIn/authorization.ts
|
|
443
506
|
var getTrustedOrigins = async (request, trustedOrigins) => {
|
|
444
507
|
if (!trustedOrigins) return [];
|
|
445
508
|
const raw = typeof trustedOrigins === "function" ? await trustedOrigins(request) : trustedOrigins;
|
|
446
509
|
return Array.isArray(raw) ? raw : typeof raw === "string" ? [raw] : [];
|
|
447
510
|
};
|
|
511
|
+
var getBaseURL2 = async ({
|
|
512
|
+
ctx,
|
|
513
|
+
request,
|
|
514
|
+
headers: headersInit
|
|
515
|
+
}) => {
|
|
516
|
+
const origin = getEnv("BASE_URL") || ctx?.baseURL;
|
|
517
|
+
if (origin && origin !== "/") return origin;
|
|
518
|
+
if (ctx?.trustedProxyHeaders) {
|
|
519
|
+
const headers = headersInit && new Headers(headersInit) || request?.headers;
|
|
520
|
+
const protocol = headers?.get("Forwarded")?.match(/proto=([^;]+)/i)?.[1] ?? headers?.get("X-Forwarded-Proto") ?? "http";
|
|
521
|
+
const host = headers?.get("Host") ?? headers?.get("Forwarded")?.match(/host=([^;]+)/i)?.[1] ?? headers?.get("X-Forwarded-Host") ?? null;
|
|
522
|
+
if (host) return `${protocol}://${host}`;
|
|
523
|
+
throw new AuthInternalError(
|
|
524
|
+
"INVALID_OAUTH_CONFIGURATION",
|
|
525
|
+
"The URL cannot be constructed. Please set the BASE_URL environment variable or provide trusted proxy host headers."
|
|
526
|
+
);
|
|
527
|
+
}
|
|
528
|
+
try {
|
|
529
|
+
return new URL(request?.url ?? "not-found").origin;
|
|
530
|
+
} catch (error) {
|
|
531
|
+
throw new AuthInternalError(
|
|
532
|
+
"INVALID_OAUTH_CONFIGURATION",
|
|
533
|
+
"The URL cannot be constructed. Please set the BASE_URL environment variable or enable trustedProxyHeaders.",
|
|
534
|
+
{ cause: error }
|
|
535
|
+
);
|
|
536
|
+
}
|
|
537
|
+
};
|
|
448
538
|
var getOriginURL = async (request, context) => {
|
|
449
|
-
const headers = request.headers;
|
|
450
|
-
let origin = new URL(request.url).origin;
|
|
451
539
|
const trustedOrigins = await getTrustedOrigins(request, context?.trustedOrigins);
|
|
452
|
-
trustedOrigins.push(origin);
|
|
453
|
-
|
|
454
|
-
const protocol = headers.get("Forwarded")?.match(/proto=([^;]+)/i)?.[1] ?? headers.get("X-Forwarded-Proto") ?? "http";
|
|
455
|
-
const host = headers.get("Host") ?? headers.get("Forwarded")?.match(/host=([^;]+)/i)?.[1] ?? headers.get("X-Forwarded-Host") ?? null;
|
|
456
|
-
origin = `${protocol}://${host}`;
|
|
457
|
-
}
|
|
540
|
+
trustedOrigins.push(new URL(request.url).origin);
|
|
541
|
+
const origin = await getBaseURL2({ request, ctx: context });
|
|
458
542
|
if (!isTrustedOrigin(origin, trustedOrigins)) {
|
|
459
543
|
context?.logger?.log("UNTRUSTED_ORIGIN", { structuredData: { origin } });
|
|
460
544
|
throw new AuthInternalError("UNTRUSTED_ORIGIN", "The constructed origin URL is not trusted.");
|
|
@@ -465,6 +549,17 @@ var createRedirectURI = async (request, oauth, context) => {
|
|
|
465
549
|
const origin = await getOriginURL(request, context);
|
|
466
550
|
return `${origin}${context.basePath}/callback/${oauth}`;
|
|
467
551
|
};
|
|
552
|
+
var createSignInURL = async ({
|
|
553
|
+
request,
|
|
554
|
+
oauth,
|
|
555
|
+
ctx,
|
|
556
|
+
redirectTo
|
|
557
|
+
}) => {
|
|
558
|
+
const origin = await getOriginURL(request, ctx);
|
|
559
|
+
const searchParams = new URLSearchParams();
|
|
560
|
+
if (redirectTo !== void 0) searchParams.set("redirectTo", String(redirectTo));
|
|
561
|
+
return `${origin}${ctx.basePath}/signIn/${oauth}?${searchParams.toString()}`;
|
|
562
|
+
};
|
|
468
563
|
var createRedirectTo = async (request, redirectTo, context) => {
|
|
469
564
|
try {
|
|
470
565
|
const headers = request.headers;
|
|
@@ -500,58 +595,93 @@ var createRedirectTo = async (request, redirectTo, context) => {
|
|
|
500
595
|
}
|
|
501
596
|
};
|
|
502
597
|
|
|
598
|
+
// src/api/signIn.ts
|
|
599
|
+
var signIn = async (oauth, {
|
|
600
|
+
ctx,
|
|
601
|
+
headers: headersInit,
|
|
602
|
+
redirectTo = "/",
|
|
603
|
+
redirect,
|
|
604
|
+
request: requestInit
|
|
605
|
+
}) => {
|
|
606
|
+
const headers = new Headers(headersInit);
|
|
607
|
+
const provider = ctx.oauth[oauth];
|
|
608
|
+
if (!provider) {
|
|
609
|
+
throw new AuthInternalError("INVALID_OAUTH_CONFIGURATION", `The OAuth provider "${oauth}" is not configured.`);
|
|
610
|
+
}
|
|
611
|
+
let request = requestInit;
|
|
612
|
+
if (!request) {
|
|
613
|
+
const origin = await getBaseURL2({ ctx, headers });
|
|
614
|
+
const url = `${origin}${ctx.basePath}/signIn/${oauth}`;
|
|
615
|
+
request = new Request(url, { headers });
|
|
616
|
+
}
|
|
617
|
+
if (redirect === false) {
|
|
618
|
+
const signInURL = await createSignInURL({ request, oauth, ctx, redirectTo });
|
|
619
|
+
return { redirect: false, signInURL };
|
|
620
|
+
}
|
|
621
|
+
const redirectURI = await createRedirectURI(request, oauth, ctx);
|
|
622
|
+
const redirectToValue = await createRedirectTo(request, redirectTo, ctx);
|
|
623
|
+
const { authorization, state, codeVerifier } = await createAuthorizationURL(provider, redirectURI, ctx);
|
|
624
|
+
ctx?.logger?.log("SIGN_IN_INITIATED", {
|
|
625
|
+
structuredData: { oauth_provider: oauth }
|
|
626
|
+
});
|
|
627
|
+
const headersList = new import_router2.HeadersBuilder(cacheControl).setHeader("Location", authorization).setCookie(ctx.cookies.state.name, state, ctx.cookies.state.attributes).setCookie(ctx.cookies.redirectURI.name, redirectURI, ctx.cookies.redirectURI.attributes).setCookie(ctx.cookies.redirectTo.name, redirectToValue, ctx.cookies.redirectTo.attributes).setCookie(ctx.cookies.codeVerifier.name, codeVerifier, ctx.cookies.codeVerifier.attributes).toHeaders();
|
|
628
|
+
return Response.json(
|
|
629
|
+
{ redirect: redirect ?? true, signInURL: authorization },
|
|
630
|
+
{
|
|
631
|
+
status: redirect ?? true ? 302 : 200,
|
|
632
|
+
headers: headersList
|
|
633
|
+
}
|
|
634
|
+
);
|
|
635
|
+
};
|
|
636
|
+
|
|
503
637
|
// src/actions/signIn/signIn.ts
|
|
638
|
+
var import_router3 = require("@aura-stack/router");
|
|
504
639
|
var signInConfig = (oauth) => {
|
|
505
|
-
return (0,
|
|
640
|
+
return (0, import_router3.createEndpointConfig)("/signIn/:oauth", {
|
|
506
641
|
schemas: {
|
|
507
|
-
params:
|
|
508
|
-
oauth:
|
|
642
|
+
params: import_v42.z.object({
|
|
643
|
+
oauth: import_v42.z.enum(
|
|
509
644
|
Object.keys(oauth),
|
|
510
645
|
"The OAuth provider is not supported or invalid."
|
|
511
646
|
)
|
|
512
647
|
}),
|
|
513
|
-
searchParams:
|
|
514
|
-
|
|
648
|
+
searchParams: import_v42.z.object({
|
|
649
|
+
redirect: import_v42.z.stringbool().optional().default(true),
|
|
650
|
+
redirectTo: import_v42.z.string().optional()
|
|
515
651
|
})
|
|
516
652
|
}
|
|
517
653
|
});
|
|
518
654
|
};
|
|
519
655
|
var signInAction = (oauth) => {
|
|
520
|
-
return (0,
|
|
656
|
+
return (0, import_router3.createEndpoint)(
|
|
521
657
|
"GET",
|
|
522
658
|
"/signIn/:oauth",
|
|
523
659
|
async (ctx) => {
|
|
524
660
|
const {
|
|
525
661
|
request,
|
|
526
662
|
params: { oauth: oauth2 },
|
|
527
|
-
searchParams: { redirectTo },
|
|
663
|
+
searchParams: { redirectTo, redirect },
|
|
528
664
|
context
|
|
529
665
|
} = ctx;
|
|
530
|
-
const
|
|
531
|
-
|
|
532
|
-
|
|
533
|
-
|
|
534
|
-
|
|
535
|
-
|
|
536
|
-
logger?.log("SIGN_IN_INITIATED", {
|
|
537
|
-
structuredData: { oauth_provider: oauth2, code_challenge_method: method }
|
|
666
|
+
const signInResult = await signIn(oauth2, {
|
|
667
|
+
ctx: context,
|
|
668
|
+
headers: request.headers,
|
|
669
|
+
redirect,
|
|
670
|
+
redirectTo,
|
|
671
|
+
request
|
|
538
672
|
});
|
|
539
|
-
|
|
540
|
-
|
|
541
|
-
|
|
542
|
-
|
|
543
|
-
status: 302,
|
|
544
|
-
headers
|
|
545
|
-
}
|
|
546
|
-
);
|
|
673
|
+
if (!redirect) {
|
|
674
|
+
return Response.json(signInResult, { status: 200 });
|
|
675
|
+
}
|
|
676
|
+
return signInResult;
|
|
547
677
|
},
|
|
548
678
|
signInConfig(oauth)
|
|
549
679
|
);
|
|
550
680
|
};
|
|
551
681
|
|
|
552
682
|
// src/actions/callback/callback.ts
|
|
553
|
-
var
|
|
554
|
-
var
|
|
683
|
+
var import_v43 = require("zod/v4");
|
|
684
|
+
var import_router4 = require("@aura-stack/router");
|
|
555
685
|
|
|
556
686
|
// src/request.ts
|
|
557
687
|
var fetchAsync = async (url, options2 = {}, timeout = 5e3) => {
|
|
@@ -575,18 +705,23 @@ var getDefaultUserInfo = (profile) => {
|
|
|
575
705
|
};
|
|
576
706
|
};
|
|
577
707
|
var getUserInfo = async (oauthConfig, accessToken, logger) => {
|
|
578
|
-
const
|
|
708
|
+
const userInfoConfig = oauthConfig.userInfo;
|
|
709
|
+
const userinfoURL = typeof userInfoConfig === "string" ? userInfoConfig : userInfoConfig.url;
|
|
710
|
+
const extraHeaders = typeof userInfoConfig === "string" ? void 0 : userInfoConfig.headers;
|
|
711
|
+
const method = typeof userInfoConfig === "string" ? "GET" : (userInfoConfig.method ?? "GET").toUpperCase();
|
|
579
712
|
try {
|
|
580
713
|
logger?.log("OAUTH_USERINFO_REQUEST_INITIATED", {
|
|
581
714
|
structuredData: {
|
|
582
|
-
endpoint:
|
|
715
|
+
endpoint: userinfoURL
|
|
583
716
|
}
|
|
584
717
|
});
|
|
585
|
-
const response = await fetchAsync(
|
|
586
|
-
method
|
|
718
|
+
const response = await fetchAsync(userinfoURL, {
|
|
719
|
+
method,
|
|
587
720
|
headers: {
|
|
721
|
+
"User-Agent": `Aura Auth/${AURA_AUTH_VERSION}`,
|
|
588
722
|
Accept: "application/json",
|
|
589
|
-
Authorization: `Bearer ${accessToken}
|
|
723
|
+
Authorization: `Bearer ${accessToken}`,
|
|
724
|
+
...extraHeaders ?? {}
|
|
590
725
|
}
|
|
591
726
|
});
|
|
592
727
|
if (!response.ok) {
|
|
@@ -623,31 +758,42 @@ var getUserInfo = async (oauthConfig, accessToken, logger) => {
|
|
|
623
758
|
|
|
624
759
|
// src/actions/callback/access-token.ts
|
|
625
760
|
var createAccessToken = async (oauthConfig, redirectURI, code, codeVerifier, logger) => {
|
|
626
|
-
const
|
|
627
|
-
if (!
|
|
628
|
-
logger?.log("INVALID_OAUTH_CONFIGURATION"
|
|
761
|
+
const { accessToken, clientId, clientSecret } = oauthConfig;
|
|
762
|
+
if (!clientId || !clientSecret || !redirectURI || !code || !codeVerifier || !accessToken) {
|
|
763
|
+
logger?.log("INVALID_OAUTH_CONFIGURATION", {
|
|
764
|
+
structuredData: {
|
|
765
|
+
has_client_id: Boolean(clientId),
|
|
766
|
+
has_client_secret: Boolean(clientSecret),
|
|
767
|
+
has_access_token: Boolean(accessToken),
|
|
768
|
+
has_redirect_uri: Boolean(redirectURI),
|
|
769
|
+
has_code: Boolean(code),
|
|
770
|
+
has_code_verifier: Boolean(codeVerifier)
|
|
771
|
+
}
|
|
772
|
+
});
|
|
629
773
|
throw new AuthInternalError("INVALID_OAUTH_CONFIGURATION", "The OAuth provider configuration is invalid.");
|
|
630
774
|
}
|
|
631
|
-
const
|
|
775
|
+
const tokenURL = typeof accessToken === "string" ? accessToken : accessToken.url;
|
|
776
|
+
const extraHeaders = typeof accessToken === "string" ? void 0 : accessToken.headers;
|
|
632
777
|
try {
|
|
633
778
|
logger?.log("OAUTH_ACCESS_TOKEN_REQUEST_INITIATED", {
|
|
634
779
|
structuredData: {
|
|
635
780
|
has_client_id: Boolean(clientId),
|
|
636
|
-
redirect_uri:
|
|
781
|
+
redirect_uri: redirectURI,
|
|
637
782
|
grant_type: "authorization_code"
|
|
638
783
|
}
|
|
639
784
|
});
|
|
640
|
-
const response = await fetchAsync(
|
|
785
|
+
const response = await fetchAsync(tokenURL, {
|
|
641
786
|
method: "POST",
|
|
642
787
|
headers: {
|
|
788
|
+
...extraHeaders ?? {},
|
|
643
789
|
Accept: "application/json",
|
|
644
790
|
"Content-Type": "application/x-www-form-urlencoded"
|
|
645
791
|
},
|
|
646
792
|
body: new URLSearchParams({
|
|
647
793
|
client_id: clientId,
|
|
648
794
|
client_secret: clientSecret,
|
|
649
|
-
code
|
|
650
|
-
redirect_uri:
|
|
795
|
+
code,
|
|
796
|
+
redirect_uri: redirectURI,
|
|
651
797
|
grant_type: "authorization_code",
|
|
652
798
|
code_verifier: codeVerifier
|
|
653
799
|
}).toString()
|
|
@@ -707,7 +853,7 @@ var expiredCookieAttributes = {
|
|
|
707
853
|
secure: true
|
|
708
854
|
};
|
|
709
855
|
var getCookie = (request, cookieName) => {
|
|
710
|
-
const cookies = request.headers.get("Cookie");
|
|
856
|
+
const cookies = request instanceof Request ? request.headers.get("Cookie") : request.get("Cookie");
|
|
711
857
|
if (!cookies) {
|
|
712
858
|
throw new AuthInternalError("COOKIE_NOT_FOUND", "No cookies found. There is no active session");
|
|
713
859
|
}
|
|
@@ -728,20 +874,20 @@ var createSessionCookie = async (jose, session) => {
|
|
|
728
874
|
|
|
729
875
|
// src/actions/callback/callback.ts
|
|
730
876
|
var callbackConfig = (oauth) => {
|
|
731
|
-
return (0,
|
|
877
|
+
return (0, import_router4.createEndpointConfig)("/callback/:oauth", {
|
|
732
878
|
schemas: {
|
|
733
|
-
params:
|
|
734
|
-
oauth:
|
|
879
|
+
params: import_v43.z.object({
|
|
880
|
+
oauth: import_v43.z.enum(
|
|
735
881
|
Object.keys(oauth),
|
|
736
882
|
"The OAuth provider is not supported or invalid."
|
|
737
883
|
)
|
|
738
884
|
}),
|
|
739
|
-
searchParams:
|
|
740
|
-
code:
|
|
741
|
-
state:
|
|
885
|
+
searchParams: import_v43.z.object({
|
|
886
|
+
code: import_v43.z.string("Missing code parameter in the OAuth authorization response."),
|
|
887
|
+
state: import_v43.z.string("Missing state parameter in the OAuth authorization response.")
|
|
742
888
|
})
|
|
743
889
|
},
|
|
744
|
-
|
|
890
|
+
use: [
|
|
745
891
|
(ctx) => {
|
|
746
892
|
const {
|
|
747
893
|
searchParams,
|
|
@@ -767,7 +913,7 @@ var callbackConfig = (oauth) => {
|
|
|
767
913
|
});
|
|
768
914
|
};
|
|
769
915
|
var callbackAction = (oauth) => {
|
|
770
|
-
return (0,
|
|
916
|
+
return (0, import_router4.createEndpoint)(
|
|
771
917
|
"GET",
|
|
772
918
|
"/callback/:oauth",
|
|
773
919
|
async (ctx) => {
|
|
@@ -783,7 +929,7 @@ var callbackAction = (oauth) => {
|
|
|
783
929
|
const codeVerifier = getCookie(request, cookies.codeVerifier.name);
|
|
784
930
|
const cookieRedirectTo = getCookie(request, cookies.redirectTo.name);
|
|
785
931
|
const cookieRedirectURI = getCookie(request, cookies.redirectURI.name);
|
|
786
|
-
if (!
|
|
932
|
+
if (!timingSafeEqual(cookieState, state)) {
|
|
787
933
|
logger?.log("MISMATCHING_STATE", {
|
|
788
934
|
structuredData: {
|
|
789
935
|
oauth_provider: oauth2
|
|
@@ -822,7 +968,7 @@ var callbackAction = (oauth) => {
|
|
|
822
968
|
provider: oauth2
|
|
823
969
|
}
|
|
824
970
|
});
|
|
825
|
-
const headers = new
|
|
971
|
+
const headers = new import_router4.HeadersBuilder(cacheControl).setHeader("Location", cookieRedirectTo).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();
|
|
826
972
|
return Response.json({ oauth: oauth2 }, { status: 302, headers });
|
|
827
973
|
},
|
|
828
974
|
callbackConfig(oauth)
|
|
@@ -830,100 +976,161 @@ var callbackAction = (oauth) => {
|
|
|
830
976
|
};
|
|
831
977
|
|
|
832
978
|
// src/actions/session/session.ts
|
|
833
|
-
var
|
|
834
|
-
|
|
979
|
+
var import_router5 = require("@aura-stack/router");
|
|
980
|
+
|
|
981
|
+
// src/api/getSession.ts
|
|
982
|
+
var getSession = async ({ ctx, headers }) => {
|
|
983
|
+
try {
|
|
984
|
+
const session = getCookie(new Headers(headers), ctx.cookies.sessionToken.name);
|
|
985
|
+
const decoded = await ctx.jose.decodeJWT(session);
|
|
986
|
+
ctx?.logger?.log("AUTH_SESSION_VALID");
|
|
987
|
+
const { exp, iat, jti, nbf, aud, iss, ...user } = decoded;
|
|
988
|
+
return {
|
|
989
|
+
session: {
|
|
990
|
+
user,
|
|
991
|
+
expires: toISOString(exp * 1e3)
|
|
992
|
+
},
|
|
993
|
+
authenticated: true
|
|
994
|
+
};
|
|
995
|
+
} catch (error) {
|
|
996
|
+
ctx?.logger?.log("AUTH_SESSION_INVALID", { structuredData: { error_type: getErrorName(error) } });
|
|
997
|
+
return { session: null, authenticated: false };
|
|
998
|
+
}
|
|
999
|
+
};
|
|
1000
|
+
|
|
1001
|
+
// src/actions/session/session.ts
|
|
1002
|
+
var sessionAction = (0, import_router5.createEndpoint)("GET", "/session", async (ctx) => {
|
|
835
1003
|
const {
|
|
836
1004
|
request,
|
|
837
|
-
context: {
|
|
1005
|
+
context: { cookies }
|
|
838
1006
|
} = ctx;
|
|
839
1007
|
try {
|
|
840
|
-
const session =
|
|
841
|
-
|
|
842
|
-
|
|
843
|
-
|
|
844
|
-
|
|
845
|
-
return Response.json({ user, expires: toISOString(exp * 1e3) }, { headers });
|
|
1008
|
+
const session = await getSession({ ctx: ctx.context, headers: request.headers });
|
|
1009
|
+
if (!session.authenticated) {
|
|
1010
|
+
throw new AuthInternalError("INVALID_JWT_TOKEN", "Session not authenticated");
|
|
1011
|
+
}
|
|
1012
|
+
return Response.json(session, { headers: secureApiHeaders });
|
|
846
1013
|
} catch (error) {
|
|
847
|
-
|
|
848
|
-
|
|
849
|
-
return Response.json({ authenticated: false, message: "Unauthorized" }, { status: 401, headers });
|
|
1014
|
+
const headers = new import_router5.HeadersBuilder(secureApiHeaders).setCookie(cookies.sessionToken.name, "", expiredCookieAttributes).toHeaders();
|
|
1015
|
+
return Response.json({ session: null, authenticated: false }, { status: 401, headers });
|
|
850
1016
|
}
|
|
851
1017
|
});
|
|
852
1018
|
|
|
853
1019
|
// src/actions/signOut/signOut.ts
|
|
854
|
-
var
|
|
855
|
-
var
|
|
856
|
-
|
|
857
|
-
|
|
858
|
-
|
|
859
|
-
|
|
860
|
-
|
|
861
|
-
|
|
1020
|
+
var import_v44 = require("zod/v4");
|
|
1021
|
+
var import_router7 = require("@aura-stack/router");
|
|
1022
|
+
|
|
1023
|
+
// src/api/signOut.ts
|
|
1024
|
+
var import_router6 = require("@aura-stack/router");
|
|
1025
|
+
var signOut = async ({
|
|
1026
|
+
ctx,
|
|
1027
|
+
headers: headersInit,
|
|
1028
|
+
redirectTo = "/",
|
|
1029
|
+
skipCSRFCheck = false
|
|
1030
|
+
}) => {
|
|
1031
|
+
const headers = new Headers(headersInit);
|
|
1032
|
+
const header = headers.get("X-CSRF-Token");
|
|
1033
|
+
let session = null;
|
|
1034
|
+
let csrfToken = null;
|
|
1035
|
+
try {
|
|
1036
|
+
session = getCookie(headers, ctx.cookies.sessionToken.name);
|
|
1037
|
+
} catch {
|
|
1038
|
+
throw new AuthSecurityError("SESSION_TOKEN_MISSING", "The sessionToken is missing.");
|
|
862
1039
|
}
|
|
863
|
-
|
|
864
|
-
|
|
865
|
-
|
|
866
|
-
|
|
867
|
-
|
|
868
|
-
|
|
869
|
-
|
|
870
|
-
|
|
871
|
-
|
|
872
|
-
|
|
873
|
-
|
|
874
|
-
const { jose, cookies, logger } = context;
|
|
875
|
-
const session = headers.getCookie(cookies.sessionToken.name);
|
|
876
|
-
const csrfToken = headers.getCookie(cookies.csrfToken.name);
|
|
877
|
-
const header = headers.getHeader("X-CSRF-Token");
|
|
878
|
-
logger?.log("SIGN_OUT_ATTEMPT", {
|
|
879
|
-
structuredData: {
|
|
880
|
-
has_session: Boolean(session),
|
|
881
|
-
has_csrf_token: Boolean(csrfToken),
|
|
882
|
-
has_csrf_header: Boolean(header)
|
|
883
|
-
}
|
|
884
|
-
});
|
|
885
|
-
if (!session) {
|
|
886
|
-
logger?.log("SESSION_TOKEN_MISSING");
|
|
887
|
-
throw new AuthSecurityError("SESSION_TOKEN_MISSING", "The sessionToken is missing.");
|
|
1040
|
+
try {
|
|
1041
|
+
csrfToken = getCookie(headers, ctx.cookies.csrfToken.name);
|
|
1042
|
+
} catch {
|
|
1043
|
+
throw new AuthSecurityError("CSRF_TOKEN_MISSING", "The CSRF token is missing.");
|
|
1044
|
+
}
|
|
1045
|
+
ctx?.logger?.log("SIGN_OUT_ATTEMPT", {
|
|
1046
|
+
structuredData: {
|
|
1047
|
+
has_session: Boolean(session),
|
|
1048
|
+
has_csrf_token: Boolean(csrfToken),
|
|
1049
|
+
has_csrf_header: Boolean(header),
|
|
1050
|
+
skip_csrf_check: skipCSRFCheck
|
|
888
1051
|
}
|
|
1052
|
+
});
|
|
1053
|
+
if (!session) {
|
|
1054
|
+
ctx?.logger?.log("SESSION_TOKEN_MISSING");
|
|
1055
|
+
throw new AuthSecurityError("SESSION_TOKEN_MISSING", "The sessionToken is missing.");
|
|
1056
|
+
}
|
|
1057
|
+
if (!skipCSRFCheck) {
|
|
889
1058
|
if (!csrfToken) {
|
|
890
|
-
logger?.log("CSRF_TOKEN_MISSING");
|
|
1059
|
+
ctx?.logger?.log("CSRF_TOKEN_MISSING");
|
|
891
1060
|
throw new AuthSecurityError("CSRF_TOKEN_MISSING", "The CSRF token is missing.");
|
|
892
1061
|
}
|
|
893
1062
|
if (!header) {
|
|
894
|
-
logger?.log("CSRF_HEADER_MISSING");
|
|
1063
|
+
ctx?.logger?.log("CSRF_HEADER_MISSING");
|
|
895
1064
|
throw new AuthSecurityError("CSRF_HEADER_MISSING", "The CSRF header is missing.");
|
|
896
1065
|
}
|
|
897
1066
|
try {
|
|
898
|
-
await verifyCSRF(jose, csrfToken, header);
|
|
1067
|
+
await verifyCSRF(ctx.jose, csrfToken, header);
|
|
899
1068
|
} catch (error) {
|
|
900
|
-
logger?.log("CSRF_TOKEN_INVALID", { structuredData: { error_type: getErrorName(error) } });
|
|
1069
|
+
ctx?.logger?.log("CSRF_TOKEN_INVALID", { structuredData: { error_type: getErrorName(error) } });
|
|
901
1070
|
throw new AuthSecurityError("CSRF_TOKEN_INVALID", "CSRF token verification failed");
|
|
902
1071
|
}
|
|
903
|
-
logger?.log("SIGN_OUT_CSRF_VERIFIED");
|
|
1072
|
+
ctx?.logger?.log("SIGN_OUT_CSRF_VERIFIED");
|
|
1073
|
+
} else {
|
|
904
1074
|
try {
|
|
905
|
-
await jose.
|
|
906
|
-
logger?.log("SIGN_OUT_SUCCESS");
|
|
1075
|
+
await ctx.jose.verifyJWS(csrfToken);
|
|
907
1076
|
} catch (error) {
|
|
908
|
-
logger?.log("
|
|
1077
|
+
ctx?.logger?.log("CSRF_TOKEN_INVALID", { structuredData: { error_type: getErrorName(error) } });
|
|
1078
|
+
throw new AuthSecurityError("CSRF_TOKEN_INVALID", "CSRF token verification failed");
|
|
1079
|
+
}
|
|
1080
|
+
}
|
|
1081
|
+
try {
|
|
1082
|
+
await ctx.jose.decodeJWT(session);
|
|
1083
|
+
ctx?.logger?.log("SIGN_OUT_SUCCESS");
|
|
1084
|
+
} catch (error) {
|
|
1085
|
+
ctx?.logger?.log("INVALID_JWT_TOKEN", { structuredData: { error_type: getErrorName(error) } });
|
|
1086
|
+
}
|
|
1087
|
+
const headersList = new import_router6.HeadersBuilder(secureApiHeaders).setHeader("Location", redirectTo).setCookie(ctx.cookies.csrfToken.name, "", expiredCookieAttributes).setCookie(ctx.cookies.sessionToken.name, "", expiredCookieAttributes).toHeaders();
|
|
1088
|
+
return Response.json(
|
|
1089
|
+
{ redirect: Boolean(redirectTo), url: redirectTo },
|
|
1090
|
+
{
|
|
1091
|
+
status: 202,
|
|
1092
|
+
headers: headersList
|
|
909
1093
|
}
|
|
1094
|
+
);
|
|
1095
|
+
};
|
|
1096
|
+
|
|
1097
|
+
// src/actions/signOut/signOut.ts
|
|
1098
|
+
var config = (0, import_router7.createEndpointConfig)({
|
|
1099
|
+
schemas: {
|
|
1100
|
+
searchParams: import_v44.z.object({
|
|
1101
|
+
token_type_hint: import_v44.z.literal("session_token"),
|
|
1102
|
+
redirectTo: import_v44.z.string().optional()
|
|
1103
|
+
})
|
|
1104
|
+
}
|
|
1105
|
+
});
|
|
1106
|
+
var signOutAction = (0, import_router7.createEndpoint)(
|
|
1107
|
+
"POST",
|
|
1108
|
+
"/signOut",
|
|
1109
|
+
async (ctx) => {
|
|
1110
|
+
const {
|
|
1111
|
+
request,
|
|
1112
|
+
searchParams: { redirectTo },
|
|
1113
|
+
context
|
|
1114
|
+
} = ctx;
|
|
910
1115
|
const baseURL = getBaseURL(request);
|
|
911
1116
|
const location = await createRedirectTo(
|
|
912
1117
|
new Request(baseURL, {
|
|
913
|
-
headers: headers
|
|
1118
|
+
headers: request.headers
|
|
914
1119
|
}),
|
|
915
1120
|
redirectTo,
|
|
916
1121
|
context
|
|
917
1122
|
);
|
|
918
|
-
|
|
919
|
-
|
|
920
|
-
|
|
1123
|
+
return await signOut({
|
|
1124
|
+
ctx: context,
|
|
1125
|
+
headers: request.headers,
|
|
1126
|
+
redirectTo: location
|
|
1127
|
+
});
|
|
921
1128
|
},
|
|
922
1129
|
config
|
|
923
1130
|
);
|
|
924
1131
|
|
|
925
1132
|
// src/actions/csrfToken/csrfToken.ts
|
|
926
|
-
var
|
|
1133
|
+
var import_router8 = require("@aura-stack/router");
|
|
927
1134
|
var getCSRFToken = (request, cookieName) => {
|
|
928
1135
|
try {
|
|
929
1136
|
return getCookie(request, cookieName);
|
|
@@ -931,7 +1138,7 @@ var getCSRFToken = (request, cookieName) => {
|
|
|
931
1138
|
return void 0;
|
|
932
1139
|
}
|
|
933
1140
|
};
|
|
934
|
-
var csrfTokenAction = (0,
|
|
1141
|
+
var csrfTokenAction = (0, import_router8.createEndpoint)("GET", "/csrfToken", async (ctx) => {
|
|
935
1142
|
const {
|
|
936
1143
|
request,
|
|
937
1144
|
context: { jose, cookies, logger }
|