@aura-stack/auth 0.4.0-rc.4 → 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-DkaLJFn8.d.ts → index-CSyIJmCM.d.ts} +373 -45
- package/dist/index.cjs +1128 -483
- package/dist/index.d.ts +6 -10
- 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
package/dist/actions/index.d.ts
CHANGED
|
@@ -4,10 +4,11 @@ export { sessionAction } from './session/session.js';
|
|
|
4
4
|
export { signOutAction } from './signOut/signOut.js';
|
|
5
5
|
export { csrfTokenAction } from './csrfToken/csrfToken.js';
|
|
6
6
|
import '@aura-stack/router';
|
|
7
|
+
import '../index-CSyIJmCM.js';
|
|
7
8
|
import 'zod';
|
|
8
|
-
import '../index-DkaLJFn8.js';
|
|
9
9
|
import '../schemas.js';
|
|
10
|
-
import '
|
|
10
|
+
import '../jose.js';
|
|
11
11
|
import '@aura-stack/jose';
|
|
12
12
|
import '@aura-stack/jose/jose';
|
|
13
|
+
import '@aura-stack/router/cookie';
|
|
13
14
|
import '../@types/utility.js';
|
package/dist/actions/index.js
CHANGED
|
@@ -1,30 +1,32 @@
|
|
|
1
1
|
import "../chunk-ITQ7352M.js";
|
|
2
|
+
import {
|
|
3
|
+
signInAction
|
|
4
|
+
} from "../chunk-7QF22LHP.js";
|
|
5
|
+
import {
|
|
6
|
+
csrfTokenAction
|
|
7
|
+
} from "../chunk-ICAZ4OVS.js";
|
|
2
8
|
import {
|
|
3
9
|
signOutAction
|
|
4
|
-
} from "../chunk-
|
|
10
|
+
} from "../chunk-ALG3GIV4.js";
|
|
5
11
|
import {
|
|
6
12
|
callbackAction
|
|
7
|
-
} from "../chunk-
|
|
8
|
-
import "../chunk-
|
|
9
|
-
import "../chunk-
|
|
10
|
-
import {
|
|
11
|
-
csrfTokenAction
|
|
12
|
-
} from "../chunk-HT4YLL7N.js";
|
|
13
|
+
} from "../chunk-6MXFPFR3.js";
|
|
14
|
+
import "../chunk-TZB6MUXN.js";
|
|
15
|
+
import "../chunk-XGLBNXL4.js";
|
|
13
16
|
import {
|
|
14
17
|
sessionAction
|
|
15
|
-
} from "../chunk-
|
|
16
|
-
import
|
|
17
|
-
signInAction
|
|
18
|
-
} from "../chunk-3EUWD5BB.js";
|
|
19
|
-
import "../chunk-N4SX7TZT.js";
|
|
20
|
-
import "../chunk-W6LG7BFW.js";
|
|
21
|
-
import "../chunk-STHEPPUZ.js";
|
|
22
|
-
import "../chunk-N2APGLXA.js";
|
|
23
|
-
import "../chunk-CXLATHS5.js";
|
|
24
|
-
import "../chunk-EIL2FPSS.js";
|
|
25
|
-
import "../chunk-RRLIF4PQ.js";
|
|
18
|
+
} from "../chunk-PHFH2MGS.js";
|
|
19
|
+
import "../chunk-XUP6KKNG.js";
|
|
26
20
|
import "../chunk-ZNCZVF6U.js";
|
|
27
|
-
import "../chunk-
|
|
21
|
+
import "../chunk-KJBAQZX2.js";
|
|
22
|
+
import "../chunk-NUDITUKX.js";
|
|
23
|
+
import "../chunk-4EKY7655.js";
|
|
24
|
+
import "../chunk-QQVSRXGX.js";
|
|
25
|
+
import "../chunk-5W4BRQYG.js";
|
|
26
|
+
import "../chunk-EBAMFRB7.js";
|
|
27
|
+
import "../chunk-FRJFWTOY.js";
|
|
28
|
+
import "../chunk-4MYWAOLG.js";
|
|
29
|
+
import "../chunk-RRLIF4PQ.js";
|
|
28
30
|
export {
|
|
29
31
|
callbackAction,
|
|
30
32
|
csrfTokenAction,
|
|
@@ -25,6 +25,34 @@ __export(session_exports, {
|
|
|
25
25
|
module.exports = __toCommonJS(session_exports);
|
|
26
26
|
var import_router2 = require("@aura-stack/router");
|
|
27
27
|
|
|
28
|
+
// src/headers.ts
|
|
29
|
+
var cacheControl = {
|
|
30
|
+
"Cache-Control": "no-store",
|
|
31
|
+
Pragma: "no-cache",
|
|
32
|
+
Expires: "0",
|
|
33
|
+
Vary: "Cookie"
|
|
34
|
+
};
|
|
35
|
+
var contentSecurityPolicy = {
|
|
36
|
+
"Content-Security-Policy": [
|
|
37
|
+
"default-src 'none'",
|
|
38
|
+
"script-src 'self'",
|
|
39
|
+
"frame-src 'none'",
|
|
40
|
+
"object-src 'none'",
|
|
41
|
+
"frame-ancestors 'none'",
|
|
42
|
+
"base-uri 'none'"
|
|
43
|
+
].join("; ")
|
|
44
|
+
};
|
|
45
|
+
var secureHeaders = {
|
|
46
|
+
"X-Content-Type-Options": "nosniff",
|
|
47
|
+
"X-Frame-Options": "DENY",
|
|
48
|
+
"Referrer-Policy": "strict-origin-when-cross-origin"
|
|
49
|
+
};
|
|
50
|
+
var secureApiHeaders = {
|
|
51
|
+
...cacheControl,
|
|
52
|
+
...contentSecurityPolicy,
|
|
53
|
+
...secureHeaders
|
|
54
|
+
};
|
|
55
|
+
|
|
28
56
|
// src/utils.ts
|
|
29
57
|
var import_router = require("@aura-stack/router");
|
|
30
58
|
|
|
@@ -44,13 +72,11 @@ var AuthInternalError = class extends Error {
|
|
|
44
72
|
var toISOString = (date) => {
|
|
45
73
|
return new Date(date).toISOString();
|
|
46
74
|
};
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
Expires: "0",
|
|
53
|
-
Vary: "Cookie"
|
|
75
|
+
var getErrorName = (error) => {
|
|
76
|
+
if (error instanceof Error) {
|
|
77
|
+
return error.name;
|
|
78
|
+
}
|
|
79
|
+
return typeof error === "string" ? error : "UnknownError";
|
|
54
80
|
};
|
|
55
81
|
|
|
56
82
|
// src/cookie.ts
|
|
@@ -70,7 +96,8 @@ var oauthCookieOptions = {
|
|
|
70
96
|
var expiredCookieAttributes = {
|
|
71
97
|
...defaultCookieOptions,
|
|
72
98
|
expires: /* @__PURE__ */ new Date(0),
|
|
73
|
-
maxAge: 0
|
|
99
|
+
maxAge: 0,
|
|
100
|
+
secure: true
|
|
74
101
|
};
|
|
75
102
|
var getCookie = (request, cookieName) => {
|
|
76
103
|
const cookies = request.headers.get("Cookie");
|
|
@@ -88,16 +115,18 @@ var getCookie = (request, cookieName) => {
|
|
|
88
115
|
var sessionAction = (0, import_router2.createEndpoint)("GET", "/session", async (ctx) => {
|
|
89
116
|
const {
|
|
90
117
|
request,
|
|
91
|
-
context: { jose, cookies }
|
|
118
|
+
context: { jose, cookies, logger }
|
|
92
119
|
} = ctx;
|
|
93
120
|
try {
|
|
94
121
|
const session = getCookie(request, cookies.sessionToken.name);
|
|
95
122
|
const decoded = await jose.decodeJWT(session);
|
|
123
|
+
logger?.log("AUTH_SESSION_VALID");
|
|
96
124
|
const { exp, iat, jti, nbf, ...user } = decoded;
|
|
97
|
-
const headers = new Headers(
|
|
125
|
+
const headers = new Headers(secureApiHeaders);
|
|
98
126
|
return Response.json({ user, expires: toISOString(exp * 1e3) }, { headers });
|
|
99
127
|
} catch (error) {
|
|
100
|
-
|
|
128
|
+
logger?.log("AUTH_SESSION_INVALID", { structuredData: { error_type: getErrorName(error) } });
|
|
129
|
+
const headers = new import_router2.HeadersBuilder(secureApiHeaders).setCookie(cookies.sessionToken.name, "", expiredCookieAttributes).toHeaders();
|
|
101
130
|
return Response.json({ authenticated: false, message: "Unauthorized" }, { status: 401, headers });
|
|
102
131
|
}
|
|
103
132
|
});
|
|
@@ -1,7 +1,5 @@
|
|
|
1
1
|
import * as _aura_stack_router from '@aura-stack/router';
|
|
2
2
|
|
|
3
|
-
declare const sessionAction: _aura_stack_router.RouteEndpoint<"GET", "/session", {
|
|
4
|
-
schemas?: _aura_stack_router.EndpointSchemas | undefined;
|
|
5
|
-
}>;
|
|
3
|
+
declare const sessionAction: _aura_stack_router.RouteEndpoint<"GET", "/session", {}>;
|
|
6
4
|
|
|
7
5
|
export { sessionAction };
|
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
import {
|
|
2
2
|
sessionAction
|
|
3
|
-
} from "../../chunk-
|
|
4
|
-
import "../../chunk-
|
|
5
|
-
import "../../chunk-
|
|
6
|
-
import "../../chunk-
|
|
3
|
+
} from "../../chunk-PHFH2MGS.js";
|
|
4
|
+
import "../../chunk-QQVSRXGX.js";
|
|
5
|
+
import "../../chunk-5W4BRQYG.js";
|
|
6
|
+
import "../../chunk-EBAMFRB7.js";
|
|
7
7
|
import "../../chunk-RRLIF4PQ.js";
|
|
8
8
|
export {
|
|
9
9
|
sessionAction
|
|
@@ -23,19 +23,37 @@ __export(authorization_exports, {
|
|
|
23
23
|
createAuthorizationURL: () => createAuthorizationURL,
|
|
24
24
|
createRedirectTo: () => createRedirectTo,
|
|
25
25
|
createRedirectURI: () => createRedirectURI,
|
|
26
|
-
getOriginURL: () => getOriginURL
|
|
26
|
+
getOriginURL: () => getOriginURL,
|
|
27
|
+
getTrustedOrigins: () => getTrustedOrigins
|
|
27
28
|
});
|
|
28
29
|
module.exports = __toCommonJS(authorization_exports);
|
|
29
30
|
|
|
30
|
-
// src/
|
|
31
|
-
var
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
31
|
+
// src/errors.ts
|
|
32
|
+
var AuthInternalError = class extends Error {
|
|
33
|
+
type = "AUTH_INTERNAL_ERROR";
|
|
34
|
+
code;
|
|
35
|
+
constructor(code, message, options2) {
|
|
36
|
+
super(message, options2);
|
|
37
|
+
this.code = code;
|
|
38
|
+
this.name = new.target.name;
|
|
39
|
+
Error.captureStackTrace(this, new.target);
|
|
40
|
+
}
|
|
35
41
|
};
|
|
36
42
|
|
|
37
43
|
// src/schemas.ts
|
|
38
44
|
var import_zod = require("zod");
|
|
45
|
+
var OAuthProviderCredentialsSchema = (0, import_zod.object)({
|
|
46
|
+
id: (0, import_zod.string)(),
|
|
47
|
+
name: (0, import_zod.string)(),
|
|
48
|
+
authorizeURL: (0, import_zod.string)().url(),
|
|
49
|
+
accessToken: (0, import_zod.string)().url(),
|
|
50
|
+
scope: (0, import_zod.string)(),
|
|
51
|
+
userInfo: (0, import_zod.string)().url(),
|
|
52
|
+
responseType: (0, import_zod.enum)(["code", "token", "id_token"]),
|
|
53
|
+
clientId: (0, import_zod.string)(),
|
|
54
|
+
clientSecret: (0, import_zod.string)(),
|
|
55
|
+
profile: import_zod.z.function().optional()
|
|
56
|
+
});
|
|
39
57
|
var OAuthProviderConfigSchema = (0, import_zod.object)({
|
|
40
58
|
authorizeURL: (0, import_zod.string)().url(),
|
|
41
59
|
accessToken: (0, import_zod.string)().url(),
|
|
@@ -102,31 +120,6 @@ var OAuthEnvSchema = (0, import_zod.object)({
|
|
|
102
120
|
clientSecret: import_zod.z.string().min(1, "OAuth Client Secret is required in the environment variables.")
|
|
103
121
|
});
|
|
104
122
|
|
|
105
|
-
// src/errors.ts
|
|
106
|
-
var AuthInternalError = class extends Error {
|
|
107
|
-
type = "AUTH_INTERNAL_ERROR";
|
|
108
|
-
code;
|
|
109
|
-
constructor(code, message, options2) {
|
|
110
|
-
super(message, options2);
|
|
111
|
-
this.code = code;
|
|
112
|
-
this.name = new.target.name;
|
|
113
|
-
Error.captureStackTrace(this, new.target);
|
|
114
|
-
}
|
|
115
|
-
};
|
|
116
|
-
var AuthSecurityError = class extends Error {
|
|
117
|
-
type = "AUTH_SECURITY_ERROR";
|
|
118
|
-
code;
|
|
119
|
-
constructor(code, message, options2) {
|
|
120
|
-
super(message, options2);
|
|
121
|
-
this.code = code;
|
|
122
|
-
this.name = new.target.name;
|
|
123
|
-
Error.captureStackTrace(this, new.target);
|
|
124
|
-
}
|
|
125
|
-
};
|
|
126
|
-
var isAuthSecurityError = (error) => {
|
|
127
|
-
return error instanceof AuthSecurityError;
|
|
128
|
-
};
|
|
129
|
-
|
|
130
123
|
// src/utils.ts
|
|
131
124
|
var import_router = require("@aura-stack/router");
|
|
132
125
|
var toSnakeCase = (str) => {
|
|
@@ -145,133 +138,178 @@ var equals = (a, b) => {
|
|
|
145
138
|
if (a === null || b === null || a === void 0 || b === void 0) return false;
|
|
146
139
|
return a === b;
|
|
147
140
|
};
|
|
148
|
-
var
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
141
|
+
var extractPath = (url) => {
|
|
142
|
+
const pathRegex = /^https?:\/\/[a-zA-Z0-9_\-\.]+(:\d+)?(\/.*)$/;
|
|
143
|
+
const match = url.match(pathRegex);
|
|
144
|
+
return match && match[2] ? match[2] : "/";
|
|
145
|
+
};
|
|
146
|
+
|
|
147
|
+
// src/assert.ts
|
|
148
|
+
var unsafeChars = [
|
|
149
|
+
"<",
|
|
150
|
+
">",
|
|
151
|
+
'"',
|
|
152
|
+
"`",
|
|
153
|
+
" ",
|
|
154
|
+
"\r",
|
|
155
|
+
"\n",
|
|
156
|
+
" ",
|
|
157
|
+
"\\",
|
|
158
|
+
"%2F",
|
|
159
|
+
"%5C",
|
|
160
|
+
"%2f",
|
|
161
|
+
"%5c",
|
|
162
|
+
"\r\n",
|
|
163
|
+
"%0A",
|
|
164
|
+
"%0D",
|
|
165
|
+
"%0a",
|
|
166
|
+
"%0d",
|
|
167
|
+
"..",
|
|
168
|
+
"//",
|
|
169
|
+
"///",
|
|
170
|
+
"...",
|
|
171
|
+
"%20",
|
|
172
|
+
"\0"
|
|
173
|
+
];
|
|
174
|
+
var isValidURL = (value) => {
|
|
175
|
+
if (!new RegExp(/^https?:\/\/[^/]/).test(value)) {
|
|
176
|
+
return false;
|
|
179
177
|
}
|
|
178
|
+
const match = value.match(/^(https?:\/\/)(.*)$/);
|
|
179
|
+
if (!match) return false;
|
|
180
|
+
const rest = match[2];
|
|
181
|
+
for (const char of unsafeChars) {
|
|
182
|
+
if (rest.includes(char)) return false;
|
|
183
|
+
}
|
|
184
|
+
const regex = /^https?:\/\/(?:[a-zA-Z0-9._-]+|localhost|\[[0-9a-fA-F:]+\])(?::\d{1,5})?(?:\/[a-zA-Z0-9._~!$&'()?#*+,;=:@-]*)*\/?$/;
|
|
185
|
+
return regex.test(match[0]);
|
|
180
186
|
};
|
|
181
|
-
var
|
|
187
|
+
var isRelativeURL = (value) => {
|
|
188
|
+
if (value.length > 100) return false;
|
|
189
|
+
for (const char of unsafeChars) {
|
|
190
|
+
if (value.includes(char)) return false;
|
|
191
|
+
}
|
|
192
|
+
const regex = /^\/[a-zA-Z0-9\-_\/.?&=#]*\/?$/;
|
|
193
|
+
return regex.test(value);
|
|
194
|
+
};
|
|
195
|
+
var isSameOrigin = (origin, expected) => {
|
|
196
|
+
const originURL = new URL(origin);
|
|
197
|
+
const expectedURL = new URL(expected);
|
|
198
|
+
return equals(originURL.origin, expectedURL.origin);
|
|
199
|
+
};
|
|
200
|
+
var patternToRegex = (pattern) => {
|
|
182
201
|
try {
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
return
|
|
202
|
+
if (pattern.length > 2048) return null;
|
|
203
|
+
pattern = pattern.replace(/\\/g, "");
|
|
204
|
+
const match = pattern.match(/^(https?):\/\/([a-zA-Z0-9.*-]{1,253})(?::(\d{1,5}|\*))?(?:\/.*)?$/);
|
|
205
|
+
if (!match) return null;
|
|
206
|
+
const [, protocol, host, port] = match;
|
|
207
|
+
const hasWildcard = host.includes("*");
|
|
208
|
+
if (hasWildcard && !host.startsWith("*.")) return null;
|
|
209
|
+
if (hasWildcard && host.slice(2).includes("*")) return null;
|
|
210
|
+
const domain = hasWildcard ? host.slice(2) : host;
|
|
211
|
+
const escapedDomain = domain.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
|
|
212
|
+
const hostRegex = hasWildcard ? `[^.]+\\.${escapedDomain}` : escapedDomain;
|
|
213
|
+
const portRegex = port === "*" ? ":\\d{1,5}" : port ? `:${port}` : "";
|
|
214
|
+
return new RegExp(`^${protocol}:\\/\\/${hostRegex}${portRegex}$`);
|
|
187
215
|
} catch {
|
|
188
|
-
return
|
|
216
|
+
return null;
|
|
189
217
|
}
|
|
190
218
|
};
|
|
191
|
-
var
|
|
192
|
-
if (!
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
message: issue.message
|
|
219
|
+
var isTrustedOrigin = (url, trustedOrigins) => {
|
|
220
|
+
if (!isValidURL(url) || trustedOrigins.length === 0) return false;
|
|
221
|
+
try {
|
|
222
|
+
const urlOrigin = new URL(url).origin;
|
|
223
|
+
for (const pattern of trustedOrigins) {
|
|
224
|
+
const regex = patternToRegex(pattern);
|
|
225
|
+
if (regex?.test(urlOrigin)) return true;
|
|
226
|
+
try {
|
|
227
|
+
if (isValidURL(pattern) && equals(new URL(pattern).origin, urlOrigin)) return true;
|
|
228
|
+
} catch {
|
|
202
229
|
}
|
|
203
|
-
}
|
|
204
|
-
}
|
|
230
|
+
}
|
|
231
|
+
} catch {
|
|
232
|
+
}
|
|
233
|
+
return false;
|
|
205
234
|
};
|
|
206
235
|
|
|
207
236
|
// src/actions/signIn/authorization.ts
|
|
208
|
-
var createAuthorizationURL = (oauthConfig, redirectURI, state, codeChallenge, codeChallengeMethod) => {
|
|
237
|
+
var createAuthorizationURL = (oauthConfig, redirectURI, state, codeChallenge, codeChallengeMethod, logger) => {
|
|
209
238
|
const parsed = OAuthAuthorization.safeParse({ ...oauthConfig, redirectURI, state, codeChallenge, codeChallengeMethod });
|
|
210
239
|
if (!parsed.success) {
|
|
211
|
-
|
|
212
|
-
|
|
240
|
+
logger?.log("INVALID_OAUTH_CONFIGURATION", {
|
|
241
|
+
structuredData: {
|
|
242
|
+
scope: oauthConfig.scope,
|
|
243
|
+
redirect_uri: redirectURI,
|
|
244
|
+
has_state: Boolean(state),
|
|
245
|
+
has_code_challenge: Boolean(codeChallenge),
|
|
246
|
+
code_challenge_method: codeChallengeMethod
|
|
247
|
+
}
|
|
248
|
+
});
|
|
249
|
+
throw new AuthInternalError("INVALID_OAUTH_CONFIGURATION", "The OAuth provider configuration is invalid.");
|
|
213
250
|
}
|
|
214
251
|
const { authorizeURL, ...options2 } = parsed.data;
|
|
215
252
|
const { userInfo, accessToken, clientSecret, ...required } = options2;
|
|
216
253
|
const searchParams = new URLSearchParams(toCastCase(required));
|
|
217
254
|
return `${authorizeURL}?${searchParams}`;
|
|
218
255
|
};
|
|
219
|
-
var
|
|
256
|
+
var getTrustedOrigins = async (request, trustedOrigins) => {
|
|
257
|
+
if (!trustedOrigins) return [];
|
|
258
|
+
const raw = typeof trustedOrigins === "function" ? await trustedOrigins(request) : trustedOrigins;
|
|
259
|
+
return Array.isArray(raw) ? raw : typeof raw === "string" ? [raw] : [];
|
|
260
|
+
};
|
|
261
|
+
var getOriginURL = async (request, context) => {
|
|
220
262
|
const headers = request.headers;
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
263
|
+
let origin = new URL(request.url).origin;
|
|
264
|
+
const trustedOrigins = await getTrustedOrigins(request, context?.trustedOrigins);
|
|
265
|
+
trustedOrigins.push(origin);
|
|
266
|
+
if (context?.trustedProxyHeaders) {
|
|
267
|
+
const protocol = headers.get("Forwarded")?.match(/proto=([^;]+)/i)?.[1] ?? headers.get("X-Forwarded-Proto") ?? "http";
|
|
268
|
+
const host = headers.get("Host") ?? headers.get("Forwarded")?.match(/host=([^;]+)/i)?.[1] ?? headers.get("X-Forwarded-Host") ?? null;
|
|
269
|
+
origin = `${protocol}://${host}`;
|
|
270
|
+
}
|
|
271
|
+
if (!isTrustedOrigin(origin, trustedOrigins)) {
|
|
272
|
+
context?.logger?.log("UNTRUSTED_ORIGIN", { structuredData: { origin } });
|
|
273
|
+
throw new AuthInternalError("UNTRUSTED_ORIGIN", "The constructed origin URL is not trusted.");
|
|
227
274
|
}
|
|
275
|
+
return origin;
|
|
228
276
|
};
|
|
229
|
-
var createRedirectURI = (request, oauth,
|
|
230
|
-
const
|
|
231
|
-
return `${
|
|
277
|
+
var createRedirectURI = async (request, oauth, context) => {
|
|
278
|
+
const origin = await getOriginURL(request, context);
|
|
279
|
+
return `${origin}${context.basePath}/callback/${oauth}`;
|
|
232
280
|
};
|
|
233
|
-
var createRedirectTo = (request, redirectTo,
|
|
281
|
+
var createRedirectTo = async (request, redirectTo, context) => {
|
|
234
282
|
try {
|
|
235
283
|
const headers = request.headers;
|
|
236
|
-
const
|
|
237
|
-
const
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
if (
|
|
241
|
-
|
|
284
|
+
const requestOrigin = await getOriginURL(request, context);
|
|
285
|
+
const origins = await getTrustedOrigins(request, context?.trustedOrigins);
|
|
286
|
+
const validateURL = (url) => {
|
|
287
|
+
if (!isRelativeURL(url) && !isValidURL(url)) return "/";
|
|
288
|
+
if (isRelativeURL(url)) return url;
|
|
289
|
+
if (origins.length > 0) {
|
|
290
|
+
if (isTrustedOrigin(url, origins)) {
|
|
291
|
+
const urlOrigin = new URL(url).origin;
|
|
292
|
+
for (const pattern of origins) {
|
|
293
|
+
const regex = patternToRegex(pattern);
|
|
294
|
+
if (regex?.test(urlOrigin)) {
|
|
295
|
+
return isSameOrigin(url, request.url) ? extractPath(url) : url;
|
|
296
|
+
}
|
|
297
|
+
if (isValidURL(pattern) && equals(new URL(pattern).origin, urlOrigin)) return url;
|
|
298
|
+
}
|
|
299
|
+
}
|
|
300
|
+
context?.logger?.log("OPEN_REDIRECT_ATTACK");
|
|
301
|
+
return "/";
|
|
242
302
|
}
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
throw new AuthSecurityError(
|
|
246
|
-
"POTENTIAL_OPEN_REDIRECT_ATTACK_DETECTED",
|
|
247
|
-
"The redirectTo parameter does not match the hosted origin."
|
|
248
|
-
);
|
|
303
|
+
if (isSameOrigin(url, requestOrigin)) {
|
|
304
|
+
return extractPath(url);
|
|
249
305
|
}
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
if (!isValidURL(referer) || !equals(refererURL.origin, hostedURL.origin)) {
|
|
255
|
-
throw new AuthSecurityError(
|
|
256
|
-
"POTENTIAL_OPEN_REDIRECT_ATTACK_DETECTED",
|
|
257
|
-
"The referer of the request does not match the hosted origin."
|
|
258
|
-
);
|
|
259
|
-
}
|
|
260
|
-
return sanitizeURL(refererURL.pathname);
|
|
261
|
-
}
|
|
262
|
-
if (origin) {
|
|
263
|
-
const originURL = new URL(sanitizeURL(getNormalizedOriginPath(origin)));
|
|
264
|
-
if (!isValidURL(origin) || !equals(originURL.origin, hostedURL.origin)) {
|
|
265
|
-
throw new AuthSecurityError("POTENTIAL_OPEN_REDIRECT_ATTACK_DETECTED", "Invalid origin (potential CSRF).");
|
|
266
|
-
}
|
|
267
|
-
return sanitizeURL(originURL.pathname);
|
|
268
|
-
}
|
|
269
|
-
return "/";
|
|
306
|
+
context?.logger?.log("OPEN_REDIRECT_ATTACK");
|
|
307
|
+
return "/";
|
|
308
|
+
};
|
|
309
|
+
return validateURL(redirectTo ?? headers.get("Referer") ?? headers.get("Origin") ?? "/");
|
|
270
310
|
} catch (error) {
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
}
|
|
274
|
-
throw new AuthSecurityError("POTENTIAL_OPEN_REDIRECT_ATTACK_DETECTED", "Invalid origin (potential CSRF).");
|
|
311
|
+
context?.logger?.log("POTENTIAL_OPEN_REDIRECT_ATTACK_DETECTED");
|
|
312
|
+
return "/";
|
|
275
313
|
}
|
|
276
314
|
};
|
|
277
315
|
// Annotate the CommonJS export names for ESM import in node:
|
|
@@ -279,5 +317,6 @@ var createRedirectTo = (request, redirectTo, trustedProxyHeaders) => {
|
|
|
279
317
|
createAuthorizationURL,
|
|
280
318
|
createRedirectTo,
|
|
281
319
|
createRedirectURI,
|
|
282
|
-
getOriginURL
|
|
320
|
+
getOriginURL,
|
|
321
|
+
getTrustedOrigins
|
|
283
322
|
});
|
|
@@ -1,9 +1,11 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { GlobalContext } from '@aura-stack/router';
|
|
2
|
+
import { h as OAuthProviderCredentials, I as InternalLogger, d as AuthConfig } from '../../index-CSyIJmCM.js';
|
|
2
3
|
import 'zod';
|
|
3
4
|
import '../../schemas.js';
|
|
4
|
-
import '
|
|
5
|
+
import '../../jose.js';
|
|
5
6
|
import '@aura-stack/jose';
|
|
6
7
|
import '@aura-stack/jose/jose';
|
|
8
|
+
import '@aura-stack/router/cookie';
|
|
7
9
|
import '../../@types/utility.js';
|
|
8
10
|
|
|
9
11
|
/**
|
|
@@ -18,26 +20,34 @@ import '../../@types/utility.js';
|
|
|
18
20
|
* @param redirectURI - The redirect URI where the OAuth service will send the user after authorization.
|
|
19
21
|
* @param state - A unique string used to maintain state between the request and callback.
|
|
20
22
|
*/
|
|
21
|
-
declare const createAuthorizationURL: (oauthConfig: OAuthProviderCredentials, redirectURI: string, state: string, codeChallenge: string, codeChallengeMethod: string) => string;
|
|
22
|
-
|
|
23
|
+
declare const createAuthorizationURL: (oauthConfig: OAuthProviderCredentials, redirectURI: string, state: string, codeChallenge: string, codeChallengeMethod: string, logger?: InternalLogger) => string;
|
|
24
|
+
/**
|
|
25
|
+
* Resolves trusted origins from config (array or function).
|
|
26
|
+
*/
|
|
27
|
+
declare const getTrustedOrigins: (request: Request, trustedOrigins: AuthConfig["trustedOrigins"]) => Promise<string[]>;
|
|
28
|
+
declare const getOriginURL: (request: Request, context?: GlobalContext) => Promise<string>;
|
|
23
29
|
/**
|
|
24
30
|
* Creates the redirect URI for the OAuth callback based on the original request URL and the OAuth provider.
|
|
25
31
|
*
|
|
26
32
|
* @param requestURL - the original request URL
|
|
27
33
|
* @param oauth - OAuth provider name
|
|
34
|
+
* @param context - Global context containing configuration and utilities
|
|
28
35
|
* @returns The redirect URI for the OAuth callback.
|
|
29
36
|
*/
|
|
30
|
-
declare const createRedirectURI: (request: Request, oauth: string,
|
|
37
|
+
declare const createRedirectURI: (request: Request, oauth: string, context: GlobalContext) => Promise<string>;
|
|
31
38
|
/**
|
|
32
39
|
* Verifies if the request's origin matches the expected origin. It accepts the redirectTo search
|
|
33
|
-
* parameter for redirection. It checks the
|
|
34
|
-
* the
|
|
35
|
-
*
|
|
40
|
+
* parameter for redirection. It checks the Referer and Origin headers and the request URL against
|
|
41
|
+
* the trusted origins list. If they do not match, it returns "/" to avoid potential open redirect attacks.
|
|
42
|
+
*
|
|
43
|
+
* When `trustedOrigins` is provided, URLs are validated against that list. When not provided,
|
|
44
|
+
* the request's derived origin (from request.url or proxy headers) is used as the only trusted origin.
|
|
36
45
|
*
|
|
37
46
|
* @param request The incoming request object
|
|
38
47
|
* @param redirectTo Optional redirectTo parameter to override the referer
|
|
39
|
-
* @
|
|
48
|
+
* @param context Global context containing configuration and utilities
|
|
49
|
+
* @returns A safe URL to redirect to after authentication, or "/" if the URL is not considered safe.
|
|
40
50
|
*/
|
|
41
|
-
declare const createRedirectTo: (request: Request, redirectTo?: string,
|
|
51
|
+
declare const createRedirectTo: (request: Request, redirectTo?: string, context?: GlobalContext) => Promise<string>;
|
|
42
52
|
|
|
43
|
-
export { createAuthorizationURL, createRedirectTo, createRedirectURI, getOriginURL };
|
|
53
|
+
export { createAuthorizationURL, createRedirectTo, createRedirectURI, getOriginURL, getTrustedOrigins };
|
|
@@ -2,15 +2,17 @@ import {
|
|
|
2
2
|
createAuthorizationURL,
|
|
3
3
|
createRedirectTo,
|
|
4
4
|
createRedirectURI,
|
|
5
|
-
getOriginURL
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
import "../../chunk-
|
|
5
|
+
getOriginURL,
|
|
6
|
+
getTrustedOrigins
|
|
7
|
+
} from "../../chunk-XUP6KKNG.js";
|
|
8
|
+
import "../../chunk-KJBAQZX2.js";
|
|
9
|
+
import "../../chunk-4EKY7655.js";
|
|
10
|
+
import "../../chunk-QQVSRXGX.js";
|
|
9
11
|
import "../../chunk-RRLIF4PQ.js";
|
|
10
|
-
import "../../chunk-YRCB5FLE.js";
|
|
11
12
|
export {
|
|
12
13
|
createAuthorizationURL,
|
|
13
14
|
createRedirectTo,
|
|
14
15
|
createRedirectURI,
|
|
15
|
-
getOriginURL
|
|
16
|
+
getOriginURL,
|
|
17
|
+
getTrustedOrigins
|
|
16
18
|
};
|