openvibers/openvibe.events Commits

Answer an unknown API path with a problem document, not 403 HTML (#196)

OP OpenVibers committed 12 days ago · 2dfc97586e · 2 files, +8 −4

The vhost refused every /api/ path it does not list with a 403 text/html page before the app saw it, so an API client asking for /api/no-such did not get the problem document the app's 404 promises. The refusal block now answers application/problem+json with events.not_found and still never proxies the host-local API. The vhost test asserts the block and that it keeps the API off the public vhost.

Changes

ddiff --git a/deploy/nginx/openvibe.events.conf b/deploy/nginx/openvibe.events.conf
iindex 9c0b72b..704a970 100644
---- a/deploy/nginx/openvibe.events.conf
++++ b/deploy/nginx/openvibe.events.conf
@@@ -132,10 +132,11 @@ server {
proxy_set_header X-Forwarded-Proto $scheme;
}
-- # ── Everything else under /api/: host-local only (see header) ──
++ # ── Everything else under /api/: a problem document, never a page; the API stays host-local ──
location /api/ {
-- return 403;
-- # To expose it (token-guarded) to off-host services instead:
++ default_type application/problem+json;
++ return 404 '{"type":"about:blank","title":"Not Found","status":404,"code":"events.not_found","detail":"No such route on openvibe.events."}';
++ # To expose the API (token-guarded) to off-host services instead:
# proxy_pass http://127.0.0.1:4300;
# proxy_http_version 1.1;
# proxy_set_header Host $host;
ddiff --git a/test/home.test.js b/test/home.test.js
iindex 89d304d..04be041 100644
---- a/test/home.test.js
++++ b/test/home.test.js
@@@ -266,7 +266,10 @@ t('deploy/nginx/openvibe.events.conf is the API and product origin, with no redi
assert.ok(conf.includes(loc), `${loc} is proxied`);
}
assert.ok(conf.includes('location ~ ^/api/v1/(events|subscriptions|checkpoints)(/|$)'), 'the token-guarded API block');
-- assert.ok(conf.includes('location /api/ {'), 'the /api/ refusal block');
++ const apiBlock = conf.slice(conf.indexOf('location /api/ {'), conf.indexOf('\n }', conf.indexOf('location /api/ {')));
++ assert.ok(apiBlock.includes('default_type application/problem+json;'), 'an unknown API path answers a problem document');
++ assert.ok(/return 404 /.test(apiBlock), 'with a 404');
++ assert.ok(!/^\s*proxy_pass/m.test(apiBlock), 'the API stays host-local');
assert.ok(conf.includes('proxy_buffering off;'), 'SSE is not buffered');
assert.ok(conf.includes('proxy_read_timeout 1h;'), 'SSE keeps its long read timeout');
const refusals = [conf.indexOf('location ~* ^/metrics(/|$) { return 404; }'), conf.indexOf('location ~* ^/internal(/|$) { return 404; }')];