openvibers/openvibe.network Commits
Return 404 for removed account merge admin path (#792)
Changes
@@@ -1017,6 +1017,8 @@ app.use('/api/admin/grants', requireAuth, require('./identity/grants-admin').rouapp.use('/api/admin/themes', requireAuth, requireAdmin, require('./themes/routes').reviewRouter());// Operator parity checklist (WS-D task 5): where each operator job is done now, with each service's readiness.app.use('/api/admin/operator-checklist', requireAuth, requireAdmin, require('./admin/operator-checklist').router({ statusRows: () => require('./status/routes').rows(ecosystem) }));++// The account merge endpoint is gone. Hide its former staff path before the broad admin guard so callers get 404.++app.use('/api/admin/account-merges', (_req, res) => res.status(404).json({ error: 'Not found' }));app.use('/api/admin', createAdminRoutes(db, notificationService, emailService, requireAuth));// Analytics admin API@@@ -114,7 +114,7 @@ assert.match(read('public/js/my/core.js'), /hash === 'delete' \? 'accounts' : ha// The banner reads GET /deletion on every page; that read must not spend the 20-a-minute write budget.const index = read('server/index.js');assert.match(index, /skip: \(req\) => req\.method === 'GET' && req\.path === '\/deletion'/, 'GET /deletion is not rate-limited with the writes it feeds');--assert.doesNotMatch(index, /account-merges|account-merge/, 'account merge routes and their limiter are removed');++assert.doesNotMatch(index, /mergeRouters|startsWith\('\/merge'\)/, 'account merge routers and their limiter are removed');// ── /login?reauth=1 always asks for the password ────────────────────────────const login = read('public/js/login.js');@@@ -62,6 +62,8 @@ const { ACCOUNT_HUB_PATHS } = require('../server/not-found');assert.strictEqual(r.status, 404, 'HEAD of an unknown path: 404');r = await get('/api/nope', { method: 'DELETE' });assert.strictEqual(r.status, 404, 'DELETE /api/nope: 404');++ r = await get('/api/admin/account-merges', { method: 'POST', headers: { 'content-type': 'application/json' }, body: '{}' });++ assert.strictEqual(r.status, 404, 'removed account merge admin route: 404 before the admin guard');console.log('unknown paths: all checks passed');} catch (err) {
@@ -1017,6 +1017,8 @@ app.use('/api/admin/grants', requireAuth, require('./identity/grants-admin').rou
@@ -1017,6 +1017,8 @@ app.use('/api/admin/grants', requireAuth, require('./identity/grants-admin').rou
app.use('/api/admin/themes', requireAuth, requireAdmin, require('./themes/routes').reviewRouter());
app.use('/api/admin/themes', requireAuth, requireAdmin, require('./themes/routes').reviewRouter());
// Operator parity checklist (WS-D task 5): where each operator job is done now, with each service's readiness.
// Operator parity checklist (WS-D task 5): where each operator job is done now, with each service's readiness.
app.use('/api/admin/operator-checklist', requireAuth, requireAdmin, require('./admin/operator-checklist').router({ statusRows: () => require('./status/routes').rows(ecosystem) }));
app.use('/api/admin/operator-checklist', requireAuth, requireAdmin, require('./admin/operator-checklist').router({ statusRows: () => require('./status/routes').rows(ecosystem) }));
+// The account merge endpoint is gone. Hide its former staff path before the broad admin guard so callers get 404.
+app.use('/api/admin/account-merges', (_req, res) => res.status(404).json({ error: 'Not found' }));
app.use('/api/admin', createAdminRoutes(db, notificationService, emailService, requireAuth));
app.use('/api/admin', createAdminRoutes(db, notificationService, emailService, requireAuth));
// Analytics admin API
// Analytics admin API
@@ -114,7 +114,7 @@ assert.match(read('public/js/my/core.js'), /hash === 'delete' \? 'accounts' : ha
@@ -114,7 +114,7 @@ assert.match(read('public/js/my/core.js'), /hash === 'delete' \? 'accounts' : ha
// The banner reads GET /deletion on every page; that read must not spend the 20-a-minute write budget.
// The banner reads GET /deletion on every page; that read must not spend the 20-a-minute write budget.
const index = read('server/index.js');
const index = read('server/index.js');
assert.match(index, /skip: \(req\) => req\.method === 'GET' && req\.path === '\/deletion'/, 'GET /deletion is not rate-limited with the writes it feeds');
assert.match(index, /skip: \(req\) => req\.method === 'GET' && req\.path === '\/deletion'/, 'GET /deletion is not rate-limited with the writes it feeds');
-assert.doesNotMatch(index, /account-merges|account-merge/, 'account merge routes and their limiter are removed');
+assert.doesNotMatch(index, /mergeRouters|startsWith\('\/merge'\)/, 'account merge routers and their limiter are removed');
// ── /login?reauth=1 always asks for the password ────────────────────────────
// ── /login?reauth=1 always asks for the password ────────────────────────────
const login = read('public/js/login.js');
const login = read('public/js/login.js');
@@ -62,6 +62,8 @@ const { ACCOUNT_HUB_PATHS } = require('../server/not-found');
@@ -62,6 +62,8 @@ const { ACCOUNT_HUB_PATHS } = require('../server/not-found');
assert.strictEqual(r.status, 404, 'HEAD of an unknown path: 404');
assert.strictEqual(r.status, 404, 'HEAD of an unknown path: 404');
r = await get('/api/nope', { method: 'DELETE' });
r = await get('/api/nope', { method: 'DELETE' });
assert.strictEqual(r.status, 404, 'DELETE /api/nope: 404');
assert.strictEqual(r.status, 404, 'DELETE /api/nope: 404');
+ r = await get('/api/admin/account-merges', { method: 'POST', headers: { 'content-type': 'application/json' }, body: '{}' });
+ assert.strictEqual(r.status, 404, 'removed account merge admin route: 404 before the admin guard');
console.log('unknown paths: all checks passed');
console.log('unknown paths: all checks passed');
} catch (err) {
} catch (err) {