From c5178e01814cedaa4402773b10f24d186714c1d2 Mon Sep 17 00:00:00 2001 From: Nicolai Ort Date: Wed, 17 Mar 2021 11:44:54 +0100 Subject: [PATCH 1/5] Added scanstation me endpoint ref #157 --- src/controllers/ScanStationController.ts | 16 +++++++++++++++- 1 file changed, 15 insertions(+), 1 deletion(-) diff --git a/src/controllers/ScanStationController.ts b/src/controllers/ScanStationController.ts index 80aa6e3..30c10d3 100644 --- a/src/controllers/ScanStationController.ts +++ b/src/controllers/ScanStationController.ts @@ -1,8 +1,10 @@ -import { Authorized, Body, Delete, Get, JsonController, OnUndefined, Param, Post, Put, QueryParam } from 'routing-controllers'; +import { Request } from 'express'; +import { Authorized, Body, Delete, Get, JsonController, OnUndefined, Param, Post, Put, QueryParam, Req, UseBefore } from 'routing-controllers'; import { OpenAPI, ResponseSchema } from 'routing-controllers-openapi'; import { getConnectionManager, Repository } from 'typeorm'; import { ScanStationHasScansError, ScanStationIdsNotMatchingError, ScanStationNotFoundError } from '../errors/ScanStationErrors'; import { TrackNotFoundError } from '../errors/TrackErrors'; +import ScanAuth from '../middlewares/ScanAuth'; import { CreateScanStation } from '../models/actions/create/CreateScanStation'; import { UpdateScanStation } from '../models/actions/update/UpdateScanStation'; import { ScanStation } from '../models/entities/ScanStation'; @@ -47,6 +49,18 @@ export class ScanStationController { return scan.toResponse(); } + @Get('/:id/me') + @UseBefore(ScanAuth) + @ResponseSchema(ResponseScanStation) + @ResponseSchema(ScanStationNotFoundError, { statusCode: 404 }) + @OnUndefined(ScanStationNotFoundError) + @OpenAPI({ description: 'Lists basic information about the station whose token got provided.
This includes it\'s associated track.
Just set the ID to 0.', security: [{ "ScanApiToken": [] }] }) + async getMe(@Req() req: Request) { + let scan = await this.stationRepository.findOne({ id: parseInt(req.headers["station_id"].toString()) }, { relations: ['track'] }) + if (!scan) { throw new ScanStationNotFoundError(); } + return scan.toResponse(); + } + @Post() @Authorized("STATION:CREATE") @ResponseSchema(ResponseScanStation) From 8ba7ee1d481e44e686489e237980b21aaaf6071c Mon Sep 17 00:00:00 2001 From: Nicolai Ort Date: Wed, 17 Mar 2021 11:45:40 +0100 Subject: [PATCH 2/5] Now adding station id to headers of request for scan auth ref #157 --- src/middlewares/ScanAuth.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/middlewares/ScanAuth.ts b/src/middlewares/ScanAuth.ts index 2f39bbf..05793f0 100644 --- a/src/middlewares/ScanAuth.ts +++ b/src/middlewares/ScanAuth.ts @@ -62,7 +62,7 @@ const ScanAuth = async (req: Request, res: Response, next: () => void) => { res.status(401).send("Api token invalid."); return; } - + req.headers["station_id"] = station.id.toString(); next(); } } From 757332ed2b3325d8730ef1b284ac6ba40356df93 Mon Sep 17 00:00:00 2001 From: Nicolai Ort Date: Wed, 17 Mar 2021 11:51:31 +0100 Subject: [PATCH 3/5] Added tests for the new endpoint ref #157 --- .../scanstations/scanstations_get.spec.ts | 30 +++++++++++++++++++ 1 file changed, 30 insertions(+) diff --git a/src/tests/scanstations/scanstations_get.spec.ts b/src/tests/scanstations/scanstations_get.spec.ts index 7280c31..9aff25b 100644 --- a/src/tests/scanstations/scanstations_get.spec.ts +++ b/src/tests/scanstations/scanstations_get.spec.ts @@ -56,4 +56,34 @@ describe('adding + getting stations', () => { expect(res.status).toEqual(200); expect(res.headers['content-type']).toContain("application/json"); }); +}); +// --------------- +describe('adding + getting via me endpoint', () => { + let added_track; + let added_station; + it('creating a track should return 200', async () => { + const res1 = await axios.post(base + '/api/tracks', { + "name": "test123", + "distance": 123 + }, axios_config); + added_track = res1.data + expect(res1.status).toEqual(200); + expect(res1.headers['content-type']).toContain("application/json") + }); + it('correct description and track input for station creation return 200', async () => { + const res = await axios.post(base + '/api/stations', { + "track": added_track.id, + "description": "I am but a simple test." + }, axios_config); + added_station = res.data; + expect(res.status).toEqual(200); + expect(res.headers['content-type']).toContain("application/json") + }); + it('correct description and track input for station creation return 200', async () => { + const res = await axios.get(base + '/api/stations/0/me', { headers: { "authorization": "Bearer " + added_station.key } }); + expect(res.status).toEqual(200); + expect(res.headers['content-type']).toContain("application/json") + added_station.key = "Only visible on creation."; + expect(res.data).toEqual(added_station); + }); }); \ No newline at end of file From 2cb7ec7317d8a48364261506facb2c11c7cf895f Mon Sep 17 00:00:00 2001 From: Nicolai Ort Date: Wed, 17 Mar 2021 16:49:19 +0100 Subject: [PATCH 4/5] As requested by @philpp ref #157 --- .../RunnerSelfServiceController.ts | 22 +++++++++++++++++-- src/controllers/ScanStationController.ts | 16 +------------- .../scanstations/scanstations_get.spec.ts | 2 +- 3 files changed, 22 insertions(+), 18 deletions(-) diff --git a/src/controllers/RunnerSelfServiceController.ts b/src/controllers/RunnerSelfServiceController.ts index 28f7493..6a0818f 100644 --- a/src/controllers/RunnerSelfServiceController.ts +++ b/src/controllers/RunnerSelfServiceController.ts @@ -1,5 +1,6 @@ +import { Request } from "express"; import * as jwt from "jsonwebtoken"; -import { Body, Get, JsonController, OnUndefined, Param, Post, QueryParam } from 'routing-controllers'; +import { Body, Get, JsonController, OnUndefined, Param, Post, QueryParam, Req, UseBefore } from 'routing-controllers'; import { OpenAPI, ResponseSchema } from 'routing-controllers-openapi'; import { getConnectionManager, Repository } from 'typeorm'; import { config } from '../config'; @@ -7,23 +8,27 @@ import { InvalidCredentialsError, JwtNotProvidedError } from '../errors/AuthErro import { MailSendingError } from '../errors/MailErrors'; import { RunnerEmailNeededError, RunnerNotFoundError, RunnerSelfserviceTimeoutError } from '../errors/RunnerErrors'; import { RunnerOrganizationNotFoundError } from '../errors/RunnerOrganizationErrors'; +import { ScanStationNotFoundError } from '../errors/ScanStationErrors'; import { JwtCreator } from '../jwtcreator'; import { Mailer } from '../mailer'; +import ScanAuth from '../middlewares/ScanAuth'; import { CreateSelfServiceCitizenRunner } from '../models/actions/create/CreateSelfServiceCitizenRunner'; import { CreateSelfServiceRunner } from '../models/actions/create/CreateSelfServiceRunner'; import { Runner } from '../models/entities/Runner'; import { RunnerGroup } from '../models/entities/RunnerGroup'; import { RunnerOrganization } from '../models/entities/RunnerOrganization'; +import { ScanStation } from '../models/entities/ScanStation'; import { ResponseEmpty } from '../models/responses/ResponseEmpty'; +import { ResponseScanStation } from '../models/responses/ResponseScanStation'; import { ResponseSelfServiceOrganisation } from '../models/responses/ResponseSelfServiceOrganisation'; import { ResponseSelfServiceRunner } from '../models/responses/ResponseSelfServiceRunner'; import { ResponseSelfServiceScan } from '../models/responses/ResponseSelfServiceScan'; - @JsonController() export class RunnerSelfServiceController { private runnerRepository: Repository; private orgRepository: Repository; + private stationRepository: Repository; /** * Gets the repository of this controller's model/entity. @@ -31,6 +36,7 @@ export class RunnerSelfServiceController { constructor() { this.runnerRepository = getConnectionManager().get().getRepository(Runner); this.orgRepository = getConnectionManager().get().getRepository(RunnerOrganization); + this.stationRepository = getConnectionManager().get().getRepository(ScanStation); } @Get('/runners/me/:jwt') @@ -56,6 +62,18 @@ export class RunnerSelfServiceController { return responseScans; } + @Get('/stations/me') + @UseBefore(ScanAuth) + @ResponseSchema(ResponseScanStation) + @ResponseSchema(ScanStationNotFoundError, { statusCode: 404 }) + @OnUndefined(ScanStationNotFoundError) + @OpenAPI({ description: 'Lists basic information about the station whose token got provided.
This includes it\'s associated track.
Just set the ID to 0.', security: [{ "ScanApiToken": [] }] }) + async getStationMe(@Req() req: Request) { + let scan = await this.stationRepository.findOne({ id: parseInt(req.headers["station_id"].toString()) }, { relations: ['track'] }) + if (!scan) { throw new ScanStationNotFoundError(); } + return scan.toResponse(); + } + @Post('/runners/forgot') @ResponseSchema(RunnerNotFoundError, { statusCode: 404 }) @OnUndefined(ResponseEmpty) diff --git a/src/controllers/ScanStationController.ts b/src/controllers/ScanStationController.ts index 30c10d3..80aa6e3 100644 --- a/src/controllers/ScanStationController.ts +++ b/src/controllers/ScanStationController.ts @@ -1,10 +1,8 @@ -import { Request } from 'express'; -import { Authorized, Body, Delete, Get, JsonController, OnUndefined, Param, Post, Put, QueryParam, Req, UseBefore } from 'routing-controllers'; +import { Authorized, Body, Delete, Get, JsonController, OnUndefined, Param, Post, Put, QueryParam } from 'routing-controllers'; import { OpenAPI, ResponseSchema } from 'routing-controllers-openapi'; import { getConnectionManager, Repository } from 'typeorm'; import { ScanStationHasScansError, ScanStationIdsNotMatchingError, ScanStationNotFoundError } from '../errors/ScanStationErrors'; import { TrackNotFoundError } from '../errors/TrackErrors'; -import ScanAuth from '../middlewares/ScanAuth'; import { CreateScanStation } from '../models/actions/create/CreateScanStation'; import { UpdateScanStation } from '../models/actions/update/UpdateScanStation'; import { ScanStation } from '../models/entities/ScanStation'; @@ -49,18 +47,6 @@ export class ScanStationController { return scan.toResponse(); } - @Get('/:id/me') - @UseBefore(ScanAuth) - @ResponseSchema(ResponseScanStation) - @ResponseSchema(ScanStationNotFoundError, { statusCode: 404 }) - @OnUndefined(ScanStationNotFoundError) - @OpenAPI({ description: 'Lists basic information about the station whose token got provided.
This includes it\'s associated track.
Just set the ID to 0.', security: [{ "ScanApiToken": [] }] }) - async getMe(@Req() req: Request) { - let scan = await this.stationRepository.findOne({ id: parseInt(req.headers["station_id"].toString()) }, { relations: ['track'] }) - if (!scan) { throw new ScanStationNotFoundError(); } - return scan.toResponse(); - } - @Post() @Authorized("STATION:CREATE") @ResponseSchema(ResponseScanStation) diff --git a/src/tests/scanstations/scanstations_get.spec.ts b/src/tests/scanstations/scanstations_get.spec.ts index 9aff25b..3cb24ad 100644 --- a/src/tests/scanstations/scanstations_get.spec.ts +++ b/src/tests/scanstations/scanstations_get.spec.ts @@ -80,7 +80,7 @@ describe('adding + getting via me endpoint', () => { expect(res.headers['content-type']).toContain("application/json") }); it('correct description and track input for station creation return 200', async () => { - const res = await axios.get(base + '/api/stations/0/me', { headers: { "authorization": "Bearer " + added_station.key } }); + const res = await axios.get(base + '/api/stations/me', { headers: { "authorization": "Bearer " + added_station.key } }); expect(res.status).toEqual(200); expect(res.headers['content-type']).toContain("application/json") added_station.key = "Only visible on creation."; From 94001a48f1b314e91ea5ec982e5585124f9541b6 Mon Sep 17 00:00:00 2001 From: Nicolai Ort Date: Wed, 17 Mar 2021 16:50:48 +0100 Subject: [PATCH 5/5] Updated description ref #157 --- src/controllers/RunnerSelfServiceController.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/controllers/RunnerSelfServiceController.ts b/src/controllers/RunnerSelfServiceController.ts index 6a0818f..878cf1b 100644 --- a/src/controllers/RunnerSelfServiceController.ts +++ b/src/controllers/RunnerSelfServiceController.ts @@ -67,7 +67,7 @@ export class RunnerSelfServiceController { @ResponseSchema(ResponseScanStation) @ResponseSchema(ScanStationNotFoundError, { statusCode: 404 }) @OnUndefined(ScanStationNotFoundError) - @OpenAPI({ description: 'Lists basic information about the station whose token got provided.
This includes it\'s associated track.
Just set the ID to 0.', security: [{ "ScanApiToken": [] }] }) + @OpenAPI({ description: 'Lists basic information about the station whose token got provided.
This includes it\'s associated track.', security: [{ "ScanApiToken": [] }] }) async getStationMe(@Req() req: Request) { let scan = await this.stationRepository.findOne({ id: parseInt(req.headers["station_id"].toString()) }, { relations: ['track'] }) if (!scan) { throw new ScanStationNotFoundError(); }