@wbce-d9/api 12.5.10 → 12.5.11
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/app.js
CHANGED
|
@@ -109,6 +109,7 @@ export default async function createApp() {
|
|
|
109
109
|
if (env['HSTS_ENABLED']) {
|
|
110
110
|
app.use(helmet.hsts(getConfigFromEnv('HSTS_', ['HSTS_ENABLED'])));
|
|
111
111
|
}
|
|
112
|
+
app.use(helmet.crossOriginOpenerPolicy({ policy: env['CROSS_ORIGIN_OPENER_POLICY'] }));
|
|
112
113
|
await emitter.emitInit('app.before', { app });
|
|
113
114
|
await emitter.emitInit('middlewares.before', { app });
|
|
114
115
|
app.use(expressLogger);
|
|
@@ -254,6 +254,9 @@ CORS_CREDENTIALS=true
|
|
|
254
254
|
# Value for the Access-Control-Max-Age header [18000]
|
|
255
255
|
CORS_MAX_AGE=18000
|
|
256
256
|
|
|
257
|
+
# Value for the Cross-Origin-Opener-Policy header: same-origin, same-origin-allow-popups or unsafe-none ["same-origin"]
|
|
258
|
+
# CROSS_ORIGIN_OPENER_POLICY="same-origin"
|
|
259
|
+
|
|
257
260
|
####################################################################################################
|
|
258
261
|
### Argon2
|
|
259
262
|
|
package/dist/env.js
CHANGED
|
@@ -63,6 +63,7 @@ const allowedEnvironmentVars = [
|
|
|
63
63
|
'IMPORT_IP_DENY_LIST',
|
|
64
64
|
'CONTENT_SECURITY_POLICY_.+',
|
|
65
65
|
'HSTS_.+',
|
|
66
|
+
'CROSS_ORIGIN_OPENER_POLICY',
|
|
66
67
|
// hashing
|
|
67
68
|
'HASH_.+',
|
|
68
69
|
'X_POWERED_BY_ENABLED',
|
|
@@ -283,6 +284,7 @@ const defaults = {
|
|
|
283
284
|
IP_TRUST_PROXY: true,
|
|
284
285
|
IP_CUSTOM_HEADER: false,
|
|
285
286
|
IMPORT_IP_DENY_LIST: ['0.0.0.0', '169.254.169.254'],
|
|
287
|
+
CROSS_ORIGIN_OPENER_POLICY: 'same-origin',
|
|
286
288
|
SERVE_APP: true,
|
|
287
289
|
SERVE_GRAPHQL: true,
|
|
288
290
|
RELATIONAL_BATCH_SIZE: 25000,
|
|
@@ -4,7 +4,9 @@ export default defineOperationApi({
|
|
|
4
4
|
handler: ({ filter }, { data }) => {
|
|
5
5
|
const errors = validatePayload(filter, data, { requireAll: true });
|
|
6
6
|
if (errors.length > 0) {
|
|
7
|
-
|
|
7
|
+
// Joi errors hold the validated data ($env, $accountability…) in _original, details[].context and in some
|
|
8
|
+
// messages: only keep the path and type, both derived from the filter, as webhook flows can return them
|
|
9
|
+
throw errors.flatMap((error) => error.details.map(({ path, type }) => ({ path, type })));
|
|
8
10
|
}
|
|
9
11
|
else {
|
|
10
12
|
return null;
|
|
@@ -1,9 +1,13 @@
|
|
|
1
1
|
import { toArray } from '@wbce-d9/utils';
|
|
2
|
+
import { URL } from 'url';
|
|
2
3
|
import env from '../env.js';
|
|
3
4
|
import isUrlAllowed from './is-url-allowed.js';
|
|
4
|
-
|
|
5
|
+
// Sentinel origin that never resolves (RFC 6761): relative paths keep it,
|
|
6
|
+
// anything pointing elsewhere (`//x`, `/\x`, `https://x`) does not.
|
|
7
|
+
const RELATIVE_BASE = 'https://relative.invalid';
|
|
8
|
+
function isUrlValid(url, base) {
|
|
5
9
|
try {
|
|
6
|
-
new URL(
|
|
10
|
+
new URL(url, base);
|
|
7
11
|
return true;
|
|
8
12
|
}
|
|
9
13
|
catch (err) {
|
|
@@ -18,25 +22,20 @@ export function isRedirectAllowedOnLogin(redirect, provider) {
|
|
|
18
22
|
return true; // empty redirect
|
|
19
23
|
if (typeof redirect !== 'string')
|
|
20
24
|
return false; // invalid type
|
|
21
|
-
const publicUrl = env['PUBLIC_URL'];
|
|
22
25
|
if (!isUrlValid(redirect)) {
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
return true;
|
|
26
|
-
}
|
|
27
|
-
// domain without protocol `//example.com/test`
|
|
28
|
-
return false;
|
|
26
|
+
// relative path like `/admin/test`, allowed unless it resolves to another origin
|
|
27
|
+
return isUrlValid(redirect, RELATIVE_BASE) && new URL(redirect, RELATIVE_BASE).origin === RELATIVE_BASE;
|
|
29
28
|
}
|
|
30
|
-
const { protocol: redirectProtocol,
|
|
29
|
+
const { protocol: redirectProtocol, host: redirectHost } = new URL(redirect);
|
|
30
|
+
const publicUrl = env['PUBLIC_URL'];
|
|
31
31
|
const envKey = `AUTH_${provider.toUpperCase()}_REDIRECT_ALLOW_LIST`;
|
|
32
32
|
if (envKey in env) {
|
|
33
33
|
if (isUrlAllowed(redirect, [...toArray(env[envKey]), publicUrl]))
|
|
34
34
|
return true;
|
|
35
35
|
}
|
|
36
|
-
if (!isUrlValid(publicUrl))
|
|
36
|
+
if (!isUrlValid(publicUrl))
|
|
37
37
|
return false;
|
|
38
|
-
}
|
|
39
38
|
// allow redirects to the defined PUBLIC_URL
|
|
40
|
-
const { protocol: publicProtocol,
|
|
41
|
-
return
|
|
39
|
+
const { protocol: publicProtocol, host: publicHost } = new URL(publicUrl);
|
|
40
|
+
return redirectProtocol === publicProtocol && redirectHost === publicHost;
|
|
42
41
|
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@wbce-d9/api",
|
|
3
|
-
"version": "12.5.
|
|
3
|
+
"version": "12.5.11",
|
|
4
4
|
"description": "Directus is a real-time API and App dashboard for managing SQL database content",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"keywords": [
|
|
@@ -144,17 +144,17 @@
|
|
|
144
144
|
"tsx": "3.12.6",
|
|
145
145
|
"uuid-validate": "0.0.3",
|
|
146
146
|
"@wbce-d9/constants": "10.0.0",
|
|
147
|
+
"@wbce-d9/app": "11.0.0",
|
|
147
148
|
"@wbce-d9/exceptions": "10.0.0",
|
|
148
|
-
"@wbce-d9/extensions-sdk": "10.0.4",
|
|
149
|
-
"@wbce-d9/schema": "10.0.0",
|
|
150
149
|
"@wbce-d9/specs": "9.26.5",
|
|
150
|
+
"@wbce-d9/schema": "10.0.0",
|
|
151
151
|
"@wbce-d9/storage": "10.0.0",
|
|
152
|
-
"@wbce-d9/storage-driver-azure": "10.0.3",
|
|
153
|
-
"@wbce-d9/storage-driver-cloudinary": "10.0.4",
|
|
154
|
-
"@wbce-d9/app": "11.0.0",
|
|
155
152
|
"@wbce-d9/storage-driver-gcs": "10.0.3",
|
|
153
|
+
"@wbce-d9/storage-driver-cloudinary": "10.0.4",
|
|
154
|
+
"@wbce-d9/storage-driver-azure": "10.0.3",
|
|
156
155
|
"@wbce-d9/storage-driver-local": "10.0.3",
|
|
157
156
|
"@wbce-d9/storage-driver-s3": "10.0.3",
|
|
157
|
+
"@wbce-d9/extensions-sdk": "10.0.4",
|
|
158
158
|
"@wbce-d9/update-check": "10.0.4",
|
|
159
159
|
"@wbce-d9/utils": "10.0.3"
|
|
160
160
|
},
|