diff --git a/src/controllers/RunnerSelfServiceController.ts b/src/controllers/RunnerSelfServiceController.ts
index 878cf1b..03e0ec3 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.', security: [{ "ScanApiToken": [] }] })
+ @OpenAPI({ description: 'Lists basic information about the station whose token got provided.
This includes it\'s associated track.', security: [{ "StationApiToken": [] }] })
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(); }
@@ -77,7 +77,7 @@ export class RunnerSelfServiceController {
@Post('/runners/forgot')
@ResponseSchema(RunnerNotFoundError, { statusCode: 404 })
@OnUndefined(ResponseEmpty)
- @OpenAPI({ description: 'TODO' })
+ @OpenAPI({ description: 'Use this endpoint to reuqest a new selfservice token/link to be sent to your mail address (rate limited to one mail every 24hrs).' })
async requestNewToken(@QueryParam('mail') mail: string) {
if (!mail) {
throw new RunnerNotFoundError();
diff --git a/src/controllers/ScanController.ts b/src/controllers/ScanController.ts
index b223689..210cde1 100644
--- a/src/controllers/ScanController.ts
+++ b/src/controllers/ScanController.ts
@@ -1,4 +1,5 @@
-import { Authorized, Body, Delete, Get, JsonController, OnUndefined, Param, Post, Put, QueryParam, UseBefore } 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 { RunnerNotFoundError } from '../errors/RunnerErrors';
@@ -14,7 +15,6 @@ import { TrackScan } from '../models/entities/TrackScan';
import { ResponseEmpty } from '../models/responses/ResponseEmpty';
import { ResponseScan } from '../models/responses/ResponseScan';
import { ResponseTrackScan } from '../models/responses/ResponseTrackScan';
-
@JsonController('/scans')
@OpenAPI({ security: [{ "AuthToken": [] }, { "RefreshTokenCookie": [] }] })
export class ScanController {
@@ -60,7 +60,7 @@ export class ScanController {
@UseBefore(ScanAuth)
@ResponseSchema(ResponseScan)
@ResponseSchema(RunnerNotFoundError, { statusCode: 404 })
- @OpenAPI({ description: 'Create a new scan (not track scan - use /scans/trackscans instead).
Please rmemember to provide the scan\'s runner\'s id and distance.', security: [{ "ScanApiToken": [] }, { "AuthToken": [] }, { "RefreshTokenCookie": [] }] })
+ @OpenAPI({ description: 'Create a new scan (not track scan - use /scans/trackscans instead).
Please rmemember to provide the scan\'s runner\'s id and distance.', security: [{ "StationApiToken": [] }, { "AuthToken": [] }, { "RefreshTokenCookie": [] }] })
async post(@Body({ validate: true }) createScan: CreateScan) {
let scan = await createScan.toEntity();
scan = await this.scanRepository.save(scan);
@@ -71,8 +71,12 @@ export class ScanController {
@UseBefore(ScanAuth)
@ResponseSchema(ResponseTrackScan)
@ResponseSchema(RunnerNotFoundError, { statusCode: 404 })
- @OpenAPI({ description: 'Create a new track scan (for "normal" scans use /scans instead).
Please remember that to provide the scan\'s card\'s station\'s id.', security: [{ "ScanApiToken": [] }, { "AuthToken": [] }, { "RefreshTokenCookie": [] }] })
- async postTrackScans(@Body({ validate: true }) createScan: CreateTrackScan) {
+ @OpenAPI({ description: 'Create a new track scan (for "normal" scans use /scans instead).
Please remember that to provide the scan\'s card\'s station\'s id.', security: [{ "StationApiToken": [] }, { "AuthToken": [] }, { "RefreshTokenCookie": [] }] })
+ async postTrackScans(@Body({ validate: true }) createScan: CreateTrackScan, @Req() req: Request) {
+ const station_id = req.headers["station_id"];
+ if (station_id) {
+ createScan.station = parseInt(station_id.toString());
+ }
let scan = await createScan.toEntity();
scan = await this.trackScanRepository.save(scan);
return (await this.scanRepository.findOne({ id: scan.id }, { relations: ['runner', 'track', 'runner.scans', 'runner.group', 'runner.scans.track', 'card', 'station'] })).toResponse();
diff --git a/src/models/actions/create/CreateTrackScan.ts b/src/models/actions/create/CreateTrackScan.ts
index 578497f..80ad4d6 100644
--- a/src/models/actions/create/CreateTrackScan.ts
+++ b/src/models/actions/create/CreateTrackScan.ts
@@ -1,4 +1,5 @@
-import { IsInt, IsPositive } from 'class-validator';
+import { IsInt, IsOptional, IsPositive } from 'class-validator';
+import { BadRequestError } from 'routing-controllers';
import { getConnection } from 'typeorm';
import { RunnerCardNotFoundError } from '../../../errors/RunnerCardErrors';
import { RunnerNotFoundError } from '../../../errors/RunnerErrors';
@@ -22,10 +23,12 @@ export class CreateTrackScan {
/**
* The scanning station's id that created the scan.
* Mainly used for logging and traceing back scans (or errors).
+ * You don't have to provide the station if you're authenticateing via a scanstation token (The server takes care of it for you).
*/
@IsInt()
@IsPositive()
- station: number;
+ @IsOptional()
+ station?: number;
/**
* Creates a new Track entity from this.
@@ -44,12 +47,15 @@ export class CreateTrackScan {
}
newScan.timestamp = Math.round(new Date().getTime() / 1000);
- newScan.lapTime = await this.getLaptime(newScan)
- newScan.valid = await this.validateScan(newScan);
+ newScan = await this.validateScan(newScan);
return newScan;
}
+ /**
+ * Get's a runnerCard entity via the provided id.
+ * @returns The runnerCard whom's id you provided.
+ */
public async getCard(): Promise {
const track = await getConnection().getRepository(RunnerCard).findOne({ id: this.card }, { relations: ["runner"] });
if (!track) {
@@ -58,7 +64,14 @@ export class CreateTrackScan {
return track;
}
+ /**
+ * Get's a scanstation entity via the provided id.
+ * @returns The scanstation whom's id you provided.
+ */
public async getStation(): Promise {
+ if (!this.station) {
+ throw new BadRequestError("You are missing the station's id!")
+ }
const station = await getConnection().getRepository(ScanStation).findOne({ id: this.station }, { relations: ["track"] });
if (!station) {
throw new ScanStationNotFoundError();
@@ -66,15 +79,22 @@ export class CreateTrackScan {
return station;
}
- public validateScan(scan: TrackScan): boolean {
- return (scan.lapTime > scan.track.minimumLapTime);
- }
-
- public async getLaptime(scan: TrackScan): Promise {
+ /**
+ * Validates the scan and sets it's lap time;
+ * @param scan The scan you want to validate
+ * @returns The validated scan with it's laptime set.
+ */
+ public async validateScan(scan: TrackScan): Promise {
const scans = await getConnection().getRepository(TrackScan).find({ where: { runner: scan.runner, valid: true }, relations: ["track"] });
- if (scans.length == 0) { return 0; }
-
- const newestScan = scans[scans.length - 1];
- return (scan.timestamp - newestScan.timestamp);
+ if (scans.length == 0) {
+ scan.lapTime = 0;
+ scan.valid = true;
+ }
+ else {
+ const newestScan = scans[scans.length - 1];
+ scan.lapTime = scan.timestamp - newestScan.timestamp;
+ scan.valid = (scan.lapTime > scan.track.minimumLapTime);
+ }
+ return scan;
}
}
\ No newline at end of file