From 2d3a5f09ab316bae4432c964f38723e603c730eb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fredrik=20Adel=C3=B6w?= Date: Thu, 6 Oct 2022 11:54:08 +0200 Subject: [PATCH] json MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Fredrik Adelöw --- .changeset/rare-cougars-cross.md | 16 ++++++++++++++++ docs/plugins/call-existing-api.md | 2 +- .../src/middleware/notFoundHandler.test.ts | 2 +- .../src/middleware/notFoundHandler.ts | 2 +- .../middleware/requestLoggingHandler.test.ts | 4 ++-- .../src/middleware/statusCheckHandler.ts | 2 +- .../src/service/router.ts | 2 +- plugins/airbrake-backend/src/service/router.ts | 2 +- .../badges-backend/src/service/router.test.ts | 2 +- plugins/badges-backend/src/service/router.ts | 3 +-- .../src/service/createRouter.ts | 2 +- .../src/service/router.ts | 2 +- plugins/graphql-backend/src/service/router.ts | 2 +- plugins/periskop-backend/src/service/router.ts | 2 +- .../permission-backend/src/service/router.ts | 2 +- plugins/rollbar-backend/src/service/router.ts | 12 ++++++------ plugins/search-backend/src/service/router.ts | 2 +- .../src/service/router.ts | 18 +++++++++--------- 18 files changed, 47 insertions(+), 32 deletions(-) create mode 100644 .changeset/rare-cougars-cross.md diff --git a/.changeset/rare-cougars-cross.md b/.changeset/rare-cougars-cross.md new file mode 100644 index 0000000000..3bfb31ae3d --- /dev/null +++ b/.changeset/rare-cougars-cross.md @@ -0,0 +1,16 @@ +--- +'@backstage/backend-common': patch +'@backstage/cli': patch +'@backstage/plugin-airbrake-backend': patch +'@backstage/plugin-badges-backend': patch +'@backstage/plugin-catalog-backend': patch +'@backstage/plugin-graphql-backend': patch +'@backstage/plugin-periskop-backend': patch +'@backstage/plugin-permission-backend': patch +'@backstage/plugin-rollbar-backend': patch +'@backstage/plugin-search-backend': patch +'@backstage/plugin-tech-insights-backend': patch +'@backstage/plugin-user-settings-backend': patch +--- + +Use `response.json` rather than `response.send` where appropriate, as outlined in `SECURITY.md` diff --git a/docs/plugins/call-existing-api.md b/docs/plugins/call-existing-api.md index 5dbf7988c9..e91506623b 100644 --- a/docs/plugins/call-existing-api.md +++ b/docs/plugins/call-existing-api.md @@ -132,7 +132,7 @@ router.use('/summary', async (req, res) => { ]).then(async ([frobs, flerps, thunk]) => { return computeAggregate(await frobs.json(), await flerps.json(), thunk); }); - res.status(200).send(agg); + res.status(200).json(agg); }); ``` diff --git a/packages/backend-common/src/middleware/notFoundHandler.test.ts b/packages/backend-common/src/middleware/notFoundHandler.test.ts index b0dea8ef62..b49e275a69 100644 --- a/packages/backend-common/src/middleware/notFoundHandler.test.ts +++ b/packages/backend-common/src/middleware/notFoundHandler.test.ts @@ -21,7 +21,7 @@ import { notFoundHandler } from './notFoundHandler'; describe('notFoundHandler', () => { it('handles only missing routes', async () => { const app = express(); - app.use('/exists', (_, res) => res.status(200).send()); + app.use('/exists', (_, res) => res.status(200).end()); app.use(notFoundHandler()); const existsResponse = await request(app).get('/exists'); diff --git a/packages/backend-common/src/middleware/notFoundHandler.ts b/packages/backend-common/src/middleware/notFoundHandler.ts index 53a548c0ad..2d8b0ef3d0 100644 --- a/packages/backend-common/src/middleware/notFoundHandler.ts +++ b/packages/backend-common/src/middleware/notFoundHandler.ts @@ -28,6 +28,6 @@ import { NextFunction, Request, RequestHandler, Response } from 'express'; export function notFoundHandler(): RequestHandler { /* eslint-disable @typescript-eslint/no-unused-vars */ return (_request: Request, response: Response, _next: NextFunction) => { - response.status(404).send(); + response.status(404).end(); }; } diff --git a/packages/backend-common/src/middleware/requestLoggingHandler.test.ts b/packages/backend-common/src/middleware/requestLoggingHandler.test.ts index c95e59f80b..ed24f2050b 100644 --- a/packages/backend-common/src/middleware/requestLoggingHandler.test.ts +++ b/packages/backend-common/src/middleware/requestLoggingHandler.test.ts @@ -26,8 +26,8 @@ describe('requestLoggingHandler', () => { const app = express(); app.use(requestLoggingHandler(logger)); - app.use('/exists1', (_, res) => res.status(200).send()); - app.use('/exists2', (_, res) => res.status(201).send()); + app.use('/exists1', (_, res) => res.status(200).end()); + app.use('/exists2', (_, res) => res.status(201).end()); const r = request(app); await r.get('/exists1'); diff --git a/packages/backend-common/src/middleware/statusCheckHandler.ts b/packages/backend-common/src/middleware/statusCheckHandler.ts index 4655d610fe..4bd1a701c3 100644 --- a/packages/backend-common/src/middleware/statusCheckHandler.ts +++ b/packages/backend-common/src/middleware/statusCheckHandler.ts @@ -55,7 +55,7 @@ export async function statusCheckHandler( return async (_request: Request, response: Response, next: NextFunction) => { try { const status = await statusCheck(); - response.status(200).header('').send(status); + response.status(200).json(status); } catch (err) { next(err); } diff --git a/packages/cli/templates/default-backend-plugin/src/service/router.ts b/packages/cli/templates/default-backend-plugin/src/service/router.ts index 9ceaa47627..5912a87584 100644 --- a/packages/cli/templates/default-backend-plugin/src/service/router.ts +++ b/packages/cli/templates/default-backend-plugin/src/service/router.ts @@ -33,7 +33,7 @@ export async function createRouter( router.get('/health', (_, response) => { logger.info('PONG!'); - response.send({ status: 'ok' }); + response.json({ status: 'ok' }); }); router.use(errorHandler()); return router; diff --git a/plugins/airbrake-backend/src/service/router.ts b/plugins/airbrake-backend/src/service/router.ts index b870eb5c13..5dc0b44a9b 100644 --- a/plugins/airbrake-backend/src/service/router.ts +++ b/plugins/airbrake-backend/src/service/router.ts @@ -79,7 +79,7 @@ export async function createRouter( router.get('/health', (_, response) => { logger.info('PONG!'); - response.send({ status: 'ok' }); + response.json({ status: 'ok' }); }); router.use( diff --git a/plugins/badges-backend/src/service/router.test.ts b/plugins/badges-backend/src/service/router.test.ts index 5fc809906f..9dc60ea1b5 100644 --- a/plugins/badges-backend/src/service/router.test.ts +++ b/plugins/badges-backend/src/service/router.test.ts @@ -114,7 +114,7 @@ describe('createRouter', () => { ); expect(response.status).toEqual(200); - expect(response.text).toEqual(JSON.stringify([badge], null, 2)); + expect(response.body).toEqual([badge]); expect(catalog.getEntityByRef).toHaveBeenCalledTimes(1); expect(catalog.getEntityByRef).toHaveBeenCalledWith( diff --git a/plugins/badges-backend/src/service/router.ts b/plugins/badges-backend/src/service/router.ts index 2006b45dc4..e5caa5cd2a 100644 --- a/plugins/badges-backend/src/service/router.ts +++ b/plugins/badges-backend/src/service/router.ts @@ -78,8 +78,7 @@ export async function createRouter( specs.push(badge); } - res.setHeader('Content-Type', 'application/json'); - res.status(200).send(JSON.stringify(specs, null, 2)); + res.status(200).json(specs); }); router.get( diff --git a/plugins/catalog-backend/src/service/createRouter.ts b/plugins/catalog-backend/src/service/createRouter.ts index 639893dcc1..0002231bab 100644 --- a/plugins/catalog-backend/src/service/createRouter.ts +++ b/plugins/catalog-backend/src/service/createRouter.ts @@ -98,7 +98,7 @@ export async function createRouter( ); await refreshService.refresh(refreshOptions); - res.status(200).send(); + res.status(200).end(); }); } diff --git a/plugins/example-todo-list-backend/src/service/router.ts b/plugins/example-todo-list-backend/src/service/router.ts index 2973b6eab6..a1ae98eac9 100644 --- a/plugins/example-todo-list-backend/src/service/router.ts +++ b/plugins/example-todo-list-backend/src/service/router.ts @@ -51,7 +51,7 @@ export async function createRouter( router.get('/health', (_, response) => { logger.info('PONG!'); - response.send({ status: 'ok' }); + response.json({ status: 'ok' }); }); router.get('/todos', async (_req, res) => { diff --git a/plugins/graphql-backend/src/service/router.ts b/plugins/graphql-backend/src/service/router.ts index 773eebd608..aa83b51beb 100644 --- a/plugins/graphql-backend/src/service/router.ts +++ b/plugins/graphql-backend/src/service/router.ts @@ -58,7 +58,7 @@ export async function createRouter( const router = Router(); router.get('/health', (_, response) => { - response.send({ status: 'ok' }); + response.json({ status: 'ok' }); }); const apolloMiddleware = server.getMiddleware({ path: '/' }); diff --git a/plugins/periskop-backend/src/service/router.ts b/plugins/periskop-backend/src/service/router.ts index 4f8ae12c31..38a43c5050 100644 --- a/plugins/periskop-backend/src/service/router.ts +++ b/plugins/periskop-backend/src/service/router.ts @@ -43,7 +43,7 @@ export async function createRouter( router.get('/health', (_, response) => { logger.info('PONG!'); - response.send({ status: 'ok' }); + response.json({ status: 'ok' }); }); router.get('/:locationName/:serviceName', async (request, response) => { diff --git a/plugins/permission-backend/src/service/router.ts b/plugins/permission-backend/src/service/router.ts index 684cdebefd..b7e77fdba9 100644 --- a/plugins/permission-backend/src/service/router.ts +++ b/plugins/permission-backend/src/service/router.ts @@ -179,7 +179,7 @@ export async function createRouter( router.use(express.json()); router.get('/health', (_, response) => { - response.send({ status: 'ok' }); + response.json({ status: 'ok' }); }); router.post( diff --git a/plugins/rollbar-backend/src/service/router.ts b/plugins/rollbar-backend/src/service/router.ts index a5646fdf06..36ae5581a5 100644 --- a/plugins/rollbar-backend/src/service/router.ts +++ b/plugins/rollbar-backend/src/service/router.ts @@ -48,40 +48,40 @@ export async function createRouter( router.get('/projects', async (_req, res) => { const projects = await rollbarApi.getAllProjects(); - res.status(200).header('').send(projects); + res.status(200).json(projects); }); router.get('/projects/:id', async (req, res) => { const { id } = req.params; const projects = await rollbarApi.getProject(id); - res.status(200).send(projects); + res.status(200).json(projects); }); router.get('/projects/:id/items', async (req, res) => { const { id } = req.params; const projects = await rollbarApi.getProjectItems(id); - res.status(200).send(projects); + res.status(200).json(projects); }); router.get('/projects/:id/top_active_items', async (req, res) => { const { id } = req.params; const query = req.query; const items = await rollbarApi.getTopActiveItems(id, query as any); - res.status(200).send(items); + res.status(200).json(items); }); router.get('/projects/:id/occurance_counts', async (req, res) => { const { id } = req.params; const query = req.query; const items = await rollbarApi.getOccuranceCounts(id, query as any); - res.status(200).send(items); + res.status(200).json(items); }); router.get('/projects/:id/activated_item_counts', async (req, res) => { const { id } = req.params; const query = req.query; const items = await rollbarApi.getActivatedCounts(id, query as any); - res.status(200).send(items); + res.status(200).json(items); }); } diff --git a/plugins/search-backend/src/service/router.ts b/plugins/search-backend/src/service/router.ts index 5ad4d4969b..0100c35e1d 100644 --- a/plugins/search-backend/src/service/router.ts +++ b/plugins/search-backend/src/service/router.ts @@ -173,7 +173,7 @@ export async function createRouter( try { const resultSet = await engine?.query(query, { token }); - res.send(filterResultSet(toSearchResults(resultSet))); + res.json(filterResultSet(toSearchResults(resultSet))); } catch (error) { if (error.name === 'MissingIndexError') { // re-throw and let the default error handler middleware captures it and serializes it with the right response code on the standard form diff --git a/plugins/tech-insights-backend/src/service/router.ts b/plugins/tech-insights-backend/src/service/router.ts index 0df7080db5..6dba290422 100644 --- a/plugins/tech-insights-backend/src/service/router.ts +++ b/plugins/tech-insights-backend/src/service/router.ts @@ -87,7 +87,7 @@ export async function createRouter< if (factChecker) { logger.info('Fact checker configured. Enabling fact checking endpoints.'); router.get('/checks', async (_req, res) => { - return res.send(await factChecker.getChecks()); + return res.json(await factChecker.getChecks()); }); router.post('/checks/run/:namespace/:kind/:name', async (req, res) => { @@ -95,7 +95,7 @@ export async function createRouter< const { checks }: { checks: string[] } = req.body; const entityTriplet = stringifyEntityRef({ namespace, kind, name }); const checkResult = await factChecker.runChecks(entityTriplet, checks); - return res.send(checkResult); + return res.json(checkResult); }); router.post('/checks/run', async (req, res) => { @@ -113,7 +113,7 @@ export async function createRouter< }; }); const results = await Promise.all(tasks); - return res.send(results); + return res.json(results); }); } else { logger.info( @@ -123,7 +123,7 @@ export async function createRouter< router.get('/fact-schemas', async (req, res) => { const ids = req.query.ids as string[]; - return res.send(await techInsightsStore.getLatestSchemas(ids)); + return res.json(await techInsightsStore.getLatestSchemas(ids)); }); /** @@ -136,10 +136,10 @@ export async function createRouter< if (!req.query.ids) { return res .status(422) - .send({ error: 'Failed to parse ids from request' }); + .json({ error: 'Failed to parse ids from request' }); } const ids = [req.query.ids].flat() as string[]; - return res.send( + return res.json( await techInsightsStore.getLatestFactsByIds( ids, stringifyEntityRef({ namespace, kind, name }), @@ -157,20 +157,20 @@ export async function createRouter< if (!req.query.ids) { return res .status(422) - .send({ error: 'Failed to parse ids from request' }); + .json({ error: 'Failed to parse ids from request' }); } const ids = [req.query.ids].flat() as string[]; const startDatetime = DateTime.fromISO(req.query.startDatetime as string); const endDatetime = DateTime.fromISO(req.query.endDatetime as string); if (!startDatetime.isValid || !endDatetime.isValid) { - return res.status(422).send({ + return res.status(422).json({ message: 'Failed to parse datetime from request', field: !startDatetime.isValid ? 'startDateTime' : 'endDateTime', value: !startDatetime.isValid ? startDatetime : endDatetime, }); } const entityTriplet = stringifyEntityRef({ namespace, kind, name }); - return res.send( + return res.json( await techInsightsStore.getFactsBetweenTimestampsByIds( ids, entityTriplet,