diff --git a/package.json b/package.json
index 952b62a..b7fe5e6 100644
--- a/package.json
+++ b/package.json
@@ -22,11 +22,11 @@
],
"license": "CC-BY-NC-SA-4.0",
"dependencies": {
- "argon2": "^0.27.0",
+ "argon2": "^0.27.1",
"body-parser": "^1.19.0",
"class-transformer": "^0.3.1",
"class-validator": "^0.12.2",
- "class-validator-jsonschema": "^2.0.3",
+ "class-validator-jsonschema": "^2.1.0",
"consola": "^2.15.0",
"cookie": "^0.4.1",
"cookie-parser": "^1.4.5",
@@ -39,33 +39,34 @@
"pg": "^8.5.1",
"reflect-metadata": "^0.1.13",
"routing-controllers": "^0.9.0-alpha.6",
- "routing-controllers-openapi": "^2.1.0",
+ "routing-controllers-openapi": "^2.2.0",
"sqlite3": "5.0.0",
"typeorm": "^0.2.29",
"typeorm-routing-controllers-extensions": "^0.2.0",
"typeorm-seeding": "^1.6.1",
- "uuid": "^8.3.1",
+ "uuid": "^8.3.2",
"validator": "^13.5.2"
},
"devDependencies": {
- "@odit/license-exporter": "^0.0.8",
- "@types/cors": "^2.8.8",
+ "@odit/license-exporter": "^0.0.9",
+ "@types/cors": "^2.8.9",
"@types/csvtojson": "^1.1.5",
"@types/express": "^4.17.9",
"@types/jest": "^26.0.16",
"@types/jsonwebtoken": "^8.5.0",
- "@types/node": "^14.14.9",
+ "@types/node": "^14.14.20",
"@types/uuid": "^8.3.0",
- "axios": "^0.21.0",
+ "axios": "^0.21.1",
"cp-cli": "^2.0.0",
"jest": "^26.6.3",
- "nodemon": "^2.0.6",
- "rimraf": "^2.7.1",
- "start-server-and-test": "^1.11.6",
+ "nodemon": "^2.0.7",
+ "release-it": "^14.2.2",
+ "rimraf": "^3.0.2",
+ "start-server-and-test": "^1.11.7",
"ts-jest": "^26.4.4",
- "ts-node": "^9.0.0",
- "typedoc": "^0.19.2",
- "typescript": "^4.1.2"
+ "ts-node": "^9.1.1",
+ "typedoc": "^0.20.14",
+ "typescript": "^4.1.3"
},
"scripts": {
"dev": "nodemon src/app.ts",
@@ -76,7 +77,21 @@
"test:ci": "start-server-and-test dev http://localhost:4010/api/docs/openapi.json test",
"seed": "ts-node ./node_modules/typeorm/cli.js schema:sync && ts-node ./node_modules/typeorm-seeding/dist/cli.js seed",
"openapi:export": "ts-node scripts/openapi_export.ts",
- "licenses:export": "license-exporter --md"
+ "licenses:export": "license-exporter --md",
+ "release": "release-it"
+ },
+ "release-it": {
+ "git": {
+ "requireCleanWorkingDir": false,
+ "requireBranch": "main",
+ "push": false,
+ "tag": true,
+ "tagName": "v${version}",
+ "tagAnnotation": "v${version}"
+ },
+ "npm": {
+ "publish": false
+ }
},
"nodemonConfig": {
"ignore": [
diff --git a/scripts/openapi_export.ts b/scripts/openapi_export.ts
index b72a369..83fd879 100644
--- a/scripts/openapi_export.ts
+++ b/scripts/openapi_export.ts
@@ -3,7 +3,7 @@ import consola from "consola";
import fs from "fs";
import "reflect-metadata";
import { createExpressServer, getMetadataArgsStorage } from "routing-controllers";
-import { routingControllersToSpec } from 'routing-controllers-openapi';
+import { generateSpec } from '../src/apispec';
import { config } from '../src/config';
import authchecker from "../src/middlewares/authchecker";
import { ErrorHandler } from '../src/middlewares/ErrorHandler';
@@ -24,46 +24,7 @@ const schemas = validationMetadatasToSchemas({
});
//Spec creation based on the previously created schemas
-const spec = routingControllersToSpec(
- storage,
- {
- routePrefix: "/api"
- },
- {
- components: {
- schemas,
- "securitySchemes": {
- "AuthToken": {
- "type": "http",
- "scheme": "bearer",
- "bearerFormat": "JWT",
- description: "A JWT based access token. Use /api/auth/login or /api/auth/refresh to get one."
- },
- "RefreshTokenCookie": {
- "type": "apiKey",
- "in": "cookie",
- "name": "lfk_backend__refresh_token",
- description: "A cookie containing a JWT based refreh token. Attention: Doesn't work in swagger-ui. Use /api/auth/login or /api/auth/refresh to get one."
- },
- "StatsApiToken": {
- "type": "http",
- "scheme": "bearer",
- description: "Api token that can be obtained by creating a new stats client (post to /api/statsclients). Only valid for obtaining stats."
- },
- "StationApiToken": {
- "type": "http",
- "scheme": "bearer",
- description: "Api token that can be obtained by creating a new scan station (post to /api/stations). Only valid for creating scans."
- }
- }
- },
- info: {
- description: "The the backend API for the LfK! runner system.",
- title: "LfK! Backend API",
- version: "0.0.8",
- },
- }
-);
+const spec = generateSpec(storage, schemas);
try {
fs.writeFileSync("./openapi.json", JSON.stringify(spec), { encoding: "utf-8" });
diff --git a/src/apispec.ts b/src/apispec.ts
new file mode 100644
index 0000000..f0a6d85
--- /dev/null
+++ b/src/apispec.ts
@@ -0,0 +1,50 @@
+import { MetadataArgsStorage } from 'routing-controllers';
+import { routingControllersToSpec } from 'routing-controllers-openapi';
+
+/**
+ * This function generates a the openapi spec from route metadata and type schemas.
+ * @param storage MetadataArgsStorage object generated by routing-controllers.
+ * @param schemas MetadataArgsStorage object generated by class-validator-jsonschema.
+ */
+export function generateSpec(storage: MetadataArgsStorage, schemas) {
+ return routingControllersToSpec(
+ storage,
+ {
+ routePrefix: "/api"
+ },
+ {
+ components: {
+ schemas,
+ "securitySchemes": {
+ "AuthToken": {
+ "type": "http",
+ "scheme": "bearer",
+ "bearerFormat": "JWT",
+ description: "A JWT based access token. Use /api/auth/login or /api/auth/refresh to get one."
+ },
+ "RefreshTokenCookie": {
+ "type": "apiKey",
+ "in": "cookie",
+ "name": "lfk_backend__refresh_token",
+ description: "A cookie containing a JWT based refreh token. Attention: Doesn't work in swagger-ui. Use /api/auth/login or /api/auth/refresh to get one."
+ },
+ "StatsApiToken": {
+ "type": "http",
+ "scheme": "bearer",
+ description: "Api token that can be obtained by creating a new stats client (post to /api/statsclients). Only valid for obtaining stats."
+ },
+ "StationApiToken": {
+ "type": "http",
+ "scheme": "bearer",
+ description: "Api token that can be obtained by creating a new scan station (post to /api/stations). Only valid for creating scans."
+ }
+ }
+ },
+ info: {
+ description: "The the backend API for the LfK! runner system.",
+ title: "LfK! Backend API",
+ version: process.env.npm_package_version
+ },
+ }
+ );
+}
\ No newline at end of file
diff --git a/src/controllers/AuthController.ts b/src/controllers/AuthController.ts
index 9672de5..507ac38 100644
--- a/src/controllers/AuthController.ts
+++ b/src/controllers/AuthController.ts
@@ -2,12 +2,12 @@ import { Body, CookieParam, JsonController, Param, Post, Req, Res } from 'routin
import { OpenAPI, ResponseSchema } from 'routing-controllers-openapi';
import { IllegalJWTError, InvalidCredentialsError, JwtNotProvidedError, PasswordNeededError, RefreshTokenCountInvalidError, UsernameOrEmailNeededError } from '../errors/AuthError';
import { UserNotFoundError } from '../errors/UserErrors';
-import { CreateAuth } from '../models/actions/CreateAuth';
-import { CreateResetToken } from '../models/actions/CreateResetToken';
+import { CreateAuth } from '../models/actions/create/CreateAuth';
+import { CreateResetToken } from '../models/actions/create/CreateResetToken';
import { HandleLogout } from '../models/actions/HandleLogout';
import { RefreshAuth } from '../models/actions/RefreshAuth';
import { ResetPassword } from '../models/actions/ResetPassword';
-import { Auth } from '../models/responses/ResponseAuth';
+import { ResponseAuth } from '../models/responses/ResponseAuth';
import { Logout } from '../models/responses/ResponseLogout';
@JsonController('/auth')
@@ -16,7 +16,7 @@ export class AuthController {
}
@Post("/login")
- @ResponseSchema(Auth)
+ @ResponseSchema(ResponseAuth)
@ResponseSchema(InvalidCredentialsError)
@ResponseSchema(UserNotFoundError)
@ResponseSchema(UsernameOrEmailNeededError)
@@ -60,7 +60,7 @@ export class AuthController {
}
@Post("/refresh")
- @ResponseSchema(Auth)
+ @ResponseSchema(ResponseAuth)
@ResponseSchema(JwtNotProvidedError)
@ResponseSchema(IllegalJWTError)
@ResponseSchema(UserNotFoundError)
@@ -82,7 +82,7 @@ export class AuthController {
}
@Post("/reset")
- @ResponseSchema(Auth)
+ @ResponseSchema(ResponseAuth)
@ResponseSchema(UserNotFoundError)
@ResponseSchema(UsernameOrEmailNeededError)
@OpenAPI({ description: "Request a password reset token.
This will provide you with a reset token that you can use by posting to /api/auth/reset/{token}." })
@@ -92,7 +92,7 @@ export class AuthController {
}
@Post("/reset/:token")
- @ResponseSchema(Auth)
+ @ResponseSchema(ResponseAuth)
@ResponseSchema(UserNotFoundError)
@ResponseSchema(UsernameOrEmailNeededError)
@OpenAPI({ description: "Reset a user's utilising a valid password reset token.
This will set the user's password to the one you provided in the body.
To get a reset token post to /api/auth/reset with your username." })
diff --git a/src/controllers/DonorController.ts b/src/controllers/DonorController.ts
index 54a5ba4..f6b8527 100644
--- a/src/controllers/DonorController.ts
+++ b/src/controllers/DonorController.ts
@@ -2,8 +2,8 @@ import { Authorized, Body, Delete, Get, JsonController, OnUndefined, Param, Post
import { OpenAPI, ResponseSchema } from 'routing-controllers-openapi';
import { getConnectionManager, Repository } from 'typeorm';
import { DonorIdsNotMatchingError, DonorNotFoundError } from '../errors/DonorErrors';
-import { CreateDonor } from '../models/actions/CreateDonor';
-import { UpdateDonor } from '../models/actions/UpdateDonor';
+import { CreateDonor } from '../models/actions/create/CreateDonor';
+import { UpdateDonor } from '../models/actions/update/UpdateDonor';
import { Donor } from '../models/entities/Donor';
import { ResponseDonor } from '../models/responses/ResponseDonor';
import { ResponseEmpty } from '../models/responses/ResponseEmpty';
@@ -52,7 +52,7 @@ export class DonorController {
async post(@Body({ validate: true }) createRunner: CreateDonor) {
let donor;
try {
- donor = await createRunner.toDonor();
+ donor = await createRunner.toEntity();
} catch (error) {
throw error;
}
@@ -78,7 +78,7 @@ export class DonorController {
throw new DonorIdsNotMatchingError();
}
- await this.donorRepository.save(await donor.updateDonor(oldDonor));
+ await this.donorRepository.save(await donor.update(oldDonor));
return new ResponseDonor(await this.donorRepository.findOne({ id: id }));
}
diff --git a/src/controllers/PermissionController.ts b/src/controllers/PermissionController.ts
index 15ad301..e123e81 100644
--- a/src/controllers/PermissionController.ts
+++ b/src/controllers/PermissionController.ts
@@ -3,8 +3,8 @@ import { OpenAPI, ResponseSchema } from 'routing-controllers-openapi';
import { getConnectionManager, Repository } from 'typeorm';
import { PermissionIdsNotMatchingError, PermissionNeedsPrincipalError, PermissionNotFoundError } from '../errors/PermissionErrors';
import { PrincipalNotFoundError } from '../errors/PrincipalErrors';
-import { CreatePermission } from '../models/actions/CreatePermission';
-import { UpdatePermission } from '../models/actions/UpdatePermission';
+import { CreatePermission } from '../models/actions/create/CreatePermission';
+import { UpdatePermission } from '../models/actions/update/UpdatePermission';
import { Permission } from '../models/entities/Permission';
import { ResponseEmpty } from '../models/responses/ResponseEmpty';
import { ResponsePermission } from '../models/responses/ResponsePermission';
@@ -58,7 +58,7 @@ export class PermissionController {
async post(@Body({ validate: true }) createPermission: CreatePermission) {
let permission;
try {
- permission = await createPermission.toPermission();
+ permission = await createPermission.toEntity();
} catch (error) {
throw error;
}
@@ -96,7 +96,7 @@ export class PermissionController {
return new ResponsePermission(existingPermission);
}
- await this.permissionRepository.save(await permission.updatePermission(oldPermission));
+ await this.permissionRepository.save(await permission.update(oldPermission));
return new ResponsePermission(await this.permissionRepository.findOne({ id: permission.id }, { relations: ['principal'] }));
}
diff --git a/src/controllers/RunnerCardController.ts b/src/controllers/RunnerCardController.ts
index 1366bed..ae74e86 100644
--- a/src/controllers/RunnerCardController.ts
+++ b/src/controllers/RunnerCardController.ts
@@ -3,8 +3,8 @@ import { OpenAPI, ResponseSchema } from 'routing-controllers-openapi';
import { getConnectionManager, Repository } from 'typeorm';
import { RunnerCardHasScansError, RunnerCardIdsNotMatchingError, RunnerCardNotFoundError } from '../errors/RunnerCardErrors';
import { RunnerNotFoundError } from '../errors/RunnerErrors';
-import { CreateRunnerCard } from '../models/actions/CreateRunnerCard';
-import { UpdateRunnerCard } from '../models/actions/UpdateRunnerCard';
+import { CreateRunnerCard } from '../models/actions/create/CreateRunnerCard';
+import { UpdateRunnerCard } from '../models/actions/update/UpdateRunnerCard';
import { RunnerCard } from '../models/entities/RunnerCard';
import { ResponseEmpty } from '../models/responses/ResponseEmpty';
import { ResponseRunnerCard } from '../models/responses/ResponseRunnerCard';
diff --git a/src/controllers/RunnerController.ts b/src/controllers/RunnerController.ts
index 4e74330..2d83a02 100644
--- a/src/controllers/RunnerController.ts
+++ b/src/controllers/RunnerController.ts
@@ -3,8 +3,8 @@ import { OpenAPI, ResponseSchema } from 'routing-controllers-openapi';
import { getConnectionManager, Repository } from 'typeorm';
import { RunnerGroupNeededError, RunnerIdsNotMatchingError, RunnerNotFoundError } from '../errors/RunnerErrors';
import { RunnerGroupNotFoundError } from '../errors/RunnerGroupErrors';
-import { CreateRunner } from '../models/actions/CreateRunner';
-import { UpdateRunner } from '../models/actions/UpdateRunner';
+import { CreateRunner } from '../models/actions/create/CreateRunner';
+import { UpdateRunner } from '../models/actions/update/UpdateRunner';
import { Runner } from '../models/entities/Runner';
import { ResponseEmpty } from '../models/responses/ResponseEmpty';
import { ResponseRunner } from '../models/responses/ResponseRunner';
@@ -57,7 +57,7 @@ export class RunnerController {
async post(@Body({ validate: true }) createRunner: CreateRunner) {
let runner;
try {
- runner = await createRunner.toRunner();
+ runner = await createRunner.toEntity();
} catch (error) {
throw error;
}
@@ -83,7 +83,7 @@ export class RunnerController {
throw new RunnerIdsNotMatchingError();
}
- await this.runnerRepository.save(await runner.updateRunner(oldRunner));
+ await this.runnerRepository.save(await runner.update(oldRunner));
return new ResponseRunner(await this.runnerRepository.findOne({ id: id }, { relations: ['scans', 'group', 'scans.track', 'cards'] }));
}
diff --git a/src/controllers/RunnerOrganisationController.ts b/src/controllers/RunnerOrganisationController.ts
index e10d415..15c12ff 100644
--- a/src/controllers/RunnerOrganisationController.ts
+++ b/src/controllers/RunnerOrganisationController.ts
@@ -2,8 +2,8 @@ import { Authorized, Body, Delete, Get, JsonController, OnUndefined, Param, Post
import { OpenAPI, ResponseSchema } from 'routing-controllers-openapi';
import { getConnectionManager, Repository } from 'typeorm';
import { RunnerOrganisationHasRunnersError, RunnerOrganisationHasTeamsError, RunnerOrganisationIdsNotMatchingError, RunnerOrganisationNotFoundError } from '../errors/RunnerOrganisationErrors';
-import { CreateRunnerOrganisation } from '../models/actions/CreateRunnerOrganisation';
-import { UpdateRunnerOrganisation } from '../models/actions/UpdateRunnerOrganisation';
+import { CreateRunnerOrganisation } from '../models/actions/create/CreateRunnerOrganisation';
+import { UpdateRunnerOrganisation } from '../models/actions/update/UpdateRunnerOrganisation';
import { RunnerOrganisation } from '../models/entities/RunnerOrganisation';
import { ResponseEmpty } from '../models/responses/ResponseEmpty';
import { ResponseRunnerOrganisation } from '../models/responses/ResponseRunnerOrganisation';
@@ -55,7 +55,7 @@ export class RunnerOrganisationController {
async post(@Body({ validate: true }) createRunnerOrganisation: CreateRunnerOrganisation) {
let runnerOrganisation;
try {
- runnerOrganisation = await createRunnerOrganisation.toRunnerOrganisation();
+ runnerOrganisation = await createRunnerOrganisation.toEntity();
} catch (error) {
throw error;
}
@@ -82,7 +82,7 @@ export class RunnerOrganisationController {
throw new RunnerOrganisationIdsNotMatchingError();
}
- await this.runnerOrganisationRepository.save(await updateOrganisation.updateRunnerOrganisation(oldRunnerOrganisation));
+ await this.runnerOrganisationRepository.save(await updateOrganisation.update(oldRunnerOrganisation));
return new ResponseRunnerOrganisation(await this.runnerOrganisationRepository.findOne(id, { relations: ['address', 'contact', 'teams'] }));
}
diff --git a/src/controllers/RunnerTeamController.ts b/src/controllers/RunnerTeamController.ts
index bc99d79..5b97f2b 100644
--- a/src/controllers/RunnerTeamController.ts
+++ b/src/controllers/RunnerTeamController.ts
@@ -2,8 +2,8 @@ import { Authorized, Body, Delete, Get, JsonController, OnUndefined, Param, Post
import { OpenAPI, ResponseSchema } from 'routing-controllers-openapi';
import { getConnectionManager, Repository } from 'typeorm';
import { RunnerTeamHasRunnersError, RunnerTeamIdsNotMatchingError, RunnerTeamNotFoundError } from '../errors/RunnerTeamErrors';
-import { CreateRunnerTeam } from '../models/actions/CreateRunnerTeam';
-import { UpdateRunnerTeam } from '../models/actions/UpdateRunnerTeam';
+import { CreateRunnerTeam } from '../models/actions/create/CreateRunnerTeam';
+import { UpdateRunnerTeam } from '../models/actions/update/UpdateRunnerTeam';
import { RunnerTeam } from '../models/entities/RunnerTeam';
import { ResponseEmpty } from '../models/responses/ResponseEmpty';
import { ResponseRunnerTeam } from '../models/responses/ResponseRunnerTeam';
@@ -54,7 +54,7 @@ export class RunnerTeamController {
async post(@Body({ validate: true }) createRunnerTeam: CreateRunnerTeam) {
let runnerTeam;
try {
- runnerTeam = await createRunnerTeam.toRunnerTeam();
+ runnerTeam = await createRunnerTeam.toEntity();
} catch (error) {
throw error;
}
@@ -82,7 +82,7 @@ export class RunnerTeamController {
throw new RunnerTeamIdsNotMatchingError();
}
- await this.runnerTeamRepository.save(await runnerTeam.updateRunnerTeam(oldRunnerTeam));
+ await this.runnerTeamRepository.save(await runnerTeam.update(oldRunnerTeam));
return new ResponseRunnerTeam(await this.runnerTeamRepository.findOne({ id: runnerTeam.id }, { relations: ['parentGroup', 'contact'] }));
}
diff --git a/src/controllers/ScanController.ts b/src/controllers/ScanController.ts
index 46c7ba1..0de844c 100644
--- a/src/controllers/ScanController.ts
+++ b/src/controllers/ScanController.ts
@@ -5,10 +5,10 @@ import { RunnerNotFoundError } from '../errors/RunnerErrors';
import { ScanIdsNotMatchingError, ScanNotFoundError } from '../errors/ScanErrors';
import { ScanStationNotFoundError } from '../errors/ScanStationErrors';
import ScanAuth from '../middlewares/ScanAuth';
-import { CreateScan } from '../models/actions/CreateScan';
-import { CreateTrackScan } from '../models/actions/CreateTrackScan';
-import { UpdateScan } from '../models/actions/UpdateScan';
-import { UpdateTrackScan } from '../models/actions/UpdateTrackScan';
+import { CreateScan } from '../models/actions/create/CreateScan';
+import { CreateTrackScan } from '../models/actions/create/CreateTrackScan';
+import { UpdateScan } from '../models/actions/update/UpdateScan';
+import { UpdateTrackScan } from '../models/actions/update/UpdateTrackScan';
import { Scan } from '../models/entities/Scan';
import { TrackScan } from '../models/entities/TrackScan';
import { ResponseEmpty } from '../models/responses/ResponseEmpty';
@@ -62,7 +62,7 @@ export class ScanController {
@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": [] }] })
async post(@Body({ validate: true }) createScan: CreateScan) {
- let scan = await createScan.toScan();
+ let scan = await createScan.toEntity();
scan = await this.scanRepository.save(scan);
return (await this.scanRepository.findOne({ id: scan.id }, { relations: ['runner', 'track', 'runner.scans', 'runner.scans.track', 'card', 'station'] })).toResponse();
}
@@ -73,7 +73,7 @@ export class ScanController {
@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) {
- let scan = await createScan.toScan();
+ 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.scans.track', 'card', 'station'] })).toResponse();
}
@@ -96,7 +96,7 @@ export class ScanController {
throw new ScanIdsNotMatchingError();
}
- await this.scanRepository.save(await scan.updateScan(oldScan));
+ await this.scanRepository.save(await scan.update(oldScan));
return (await this.scanRepository.findOne({ id: id }, { relations: ['runner', 'track', 'runner.scans', 'runner.scans.track', 'card', 'station'] })).toResponse();
}
@@ -119,7 +119,7 @@ export class ScanController {
throw new ScanIdsNotMatchingError();
}
- await this.trackScanRepository.save(await scan.updateScan(oldScan));
+ await this.trackScanRepository.save(await scan.update(oldScan));
return (await this.scanRepository.findOne({ id: id }, { relations: ['runner', 'track', 'runner.scans', 'runner.scans.track', 'card', 'station'] })).toResponse();
}
diff --git a/src/controllers/ScanStationController.ts b/src/controllers/ScanStationController.ts
index df85d0e..80aa6e3 100644
--- a/src/controllers/ScanStationController.ts
+++ b/src/controllers/ScanStationController.ts
@@ -3,8 +3,8 @@ 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 { CreateScanStation } from '../models/actions/CreateScanStation';
-import { UpdateScanStation } from '../models/actions/UpdateScanStation';
+import { CreateScanStation } from '../models/actions/create/CreateScanStation';
+import { UpdateScanStation } from '../models/actions/update/UpdateScanStation';
import { ScanStation } from '../models/entities/ScanStation';
import { ResponseEmpty } from '../models/responses/ResponseEmpty';
import { ResponseScanStation } from '../models/responses/ResponseScanStation';
@@ -77,7 +77,7 @@ export class ScanStationController {
throw new ScanStationIdsNotMatchingError();
}
- await this.stationRepository.save(await station.updateStation(oldStation));
+ await this.stationRepository.save(await station.update(oldStation));
return (await this.stationRepository.findOne({ id: id }, { relations: ['track'] })).toResponse();
}
diff --git a/src/controllers/StatsClientController.ts b/src/controllers/StatsClientController.ts
index 1aa46a2..4716909 100644
--- a/src/controllers/StatsClientController.ts
+++ b/src/controllers/StatsClientController.ts
@@ -1,9 +1,9 @@
-import { Authorized, Body, Delete, Get, JsonController, OnUndefined, Param, Post } from 'routing-controllers';
+import { Authorized, Body, Delete, Get, JsonController, OnUndefined, Param, Post, QueryParam } from 'routing-controllers';
import { OpenAPI, ResponseSchema } from 'routing-controllers-openapi';
import { getConnectionManager, Repository } from 'typeorm';
import { StatsClientNotFoundError } from '../errors/StatsClientErrors';
import { TrackNotFoundError } from "../errors/TrackErrors";
-import { CreateStatsClient } from '../models/actions/CreateStatsClient';
+import { CreateStatsClient } from '../models/actions/create/CreateStatsClient';
import { StatsClient } from '../models/entities/StatsClient';
import { ResponseEmpty } from '../models/responses/ResponseEmpty';
import { ResponseStatsClient } from '../models/responses/ResponseStatsClient';
@@ -53,7 +53,7 @@ export class StatsClientController {
@Body({ validate: true })
client: CreateStatsClient
) {
- let newClient = await this.clientRepository.save(await client.toStatsClient());
+ let newClient = await this.clientRepository.save(await client.toEntity());
let responseClient = new ResponseStatsClient(newClient);
responseClient.key = newClient.cleartextkey;
return responseClient;
@@ -65,7 +65,7 @@ export class StatsClientController {
@ResponseSchema(ResponseEmpty, { statusCode: 204 })
@OnUndefined(204)
@OpenAPI({ description: "Delete the stats client whose id you provided.
If no client with this id exists it will just return 204(no content)." })
- async remove(@Param("id") id: number) {
+ async remove(@Param("id") id: number, @QueryParam("force") force: boolean) {
let client = await this.clientRepository.findOne({ id: id });
if (!client) { return null; }
diff --git a/src/controllers/TrackController.ts b/src/controllers/TrackController.ts
index 42feb7c..6ea2907 100644
--- a/src/controllers/TrackController.ts
+++ b/src/controllers/TrackController.ts
@@ -2,8 +2,8 @@ import { Authorized, Body, Delete, Get, JsonController, OnUndefined, Param, Post
import { OpenAPI, ResponseSchema } from 'routing-controllers-openapi';
import { getConnectionManager, Repository } from 'typeorm';
import { TrackHasScanStationsError, TrackIdsNotMatchingError, TrackLapTimeCantBeNegativeError, TrackNotFoundError } from "../errors/TrackErrors";
-import { CreateTrack } from '../models/actions/CreateTrack';
-import { UpdateTrack } from '../models/actions/UpdateTrack';
+import { CreateTrack } from '../models/actions/create/CreateTrack';
+import { UpdateTrack } from '../models/actions/update/UpdateTrack';
import { Track } from '../models/entities/Track';
import { ResponseEmpty } from '../models/responses/ResponseEmpty';
import { ResponseTrack } from '../models/responses/ResponseTrack';
@@ -55,7 +55,7 @@ export class TrackController {
@Body({ validate: true })
track: CreateTrack
) {
- return new ResponseTrack(await this.trackRepository.save(track.toTrack()));
+ return new ResponseTrack(await this.trackRepository.save(await track.toEntity()));
}
@Put('/:id')
@@ -75,7 +75,7 @@ export class TrackController {
if (oldTrack.id != updateTrack.id) {
throw new TrackIdsNotMatchingError();
}
- await this.trackRepository.save(await updateTrack.updateTrack(oldTrack));
+ await this.trackRepository.save(await updateTrack.update(oldTrack));
return new ResponseTrack(await this.trackRepository.findOne({ id: id }));
}
diff --git a/src/controllers/UserController.ts b/src/controllers/UserController.ts
index c528572..57083db 100644
--- a/src/controllers/UserController.ts
+++ b/src/controllers/UserController.ts
@@ -3,8 +3,8 @@ import { OpenAPI, ResponseSchema } from 'routing-controllers-openapi';
import { getConnectionManager, Repository } from 'typeorm';
import { UserIdsNotMatchingError, UserNotFoundError } from '../errors/UserErrors';
import { UserGroupNotFoundError } from '../errors/UserGroupErrors';
-import { CreateUser } from '../models/actions/CreateUser';
-import { UpdateUser } from '../models/actions/UpdateUser';
+import { CreateUser } from '../models/actions/create/CreateUser';
+import { UpdateUser } from '../models/actions/update/UpdateUser';
import { User } from '../models/entities/User';
import { ResponseEmpty } from '../models/responses/ResponseEmpty';
import { ResponseUser } from '../models/responses/ResponseUser';
@@ -56,7 +56,7 @@ export class UserController {
async post(@Body({ validate: true }) createUser: CreateUser) {
let user;
try {
- user = await createUser.toUser();
+ user = await createUser.toEntity();
} catch (error) {
throw error;
}
@@ -81,7 +81,7 @@ export class UserController {
if (oldUser.id != updateUser.id) {
throw new UserIdsNotMatchingError();
}
- await this.userRepository.save(await updateUser.updateUser(oldUser));
+ await this.userRepository.save(await updateUser.update(oldUser));
return new ResponseUser(await this.userRepository.findOne({ id: id }, { relations: ['permissions', 'groups'] }));
}
diff --git a/src/controllers/UserGroupController.ts b/src/controllers/UserGroupController.ts
index 160a99e..18a901d 100644
--- a/src/controllers/UserGroupController.ts
+++ b/src/controllers/UserGroupController.ts
@@ -3,7 +3,8 @@ import { OpenAPI, ResponseSchema } from 'routing-controllers-openapi';
import { getConnectionManager, Repository } from 'typeorm';
import { EntityFromBody } from 'typeorm-routing-controllers-extensions';
import { UserGroupIdsNotMatchingError, UserGroupNotFoundError } from '../errors/UserGroupErrors';
-import { CreateUserGroup } from '../models/actions/CreateUserGroup';
+import { CreateUserGroup } from '../models/actions/create/CreateUserGroup';
+import { UpdateUserGroup } from '../models/actions/update/UpdateUserGroup';
import { UserGroup } from '../models/entities/UserGroup';
import { ResponseEmpty } from '../models/responses/ResponseEmpty';
import { ResponseUserGroup } from '../models/responses/ResponseUserGroup';
@@ -48,7 +49,7 @@ export class UserGroupController {
async post(@Body({ validate: true }) createUserGroup: CreateUserGroup) {
let userGroup;
try {
- userGroup = await createUserGroup.toUserGroup();
+ userGroup = await createUserGroup.toEntity();
} catch (error) {
throw error;
}
@@ -62,19 +63,19 @@ export class UserGroupController {
@ResponseSchema(UserGroupNotFoundError, { statusCode: 404 })
@ResponseSchema(UserGroupIdsNotMatchingError, { statusCode: 406 })
@OpenAPI({ description: "Update the group whose id you provided.
To change the permissions granted to the group please use /api/permissions instead.
Please remember that ids can't be changed." })
- async put(@Param('id') id: number, @EntityFromBody() userGroup: UserGroup) {
- let oldUserGroup = await this.userGroupsRepository.findOne({ id: id }, { relations: ["permissions"] });
+ async put(@Param('id') id: number, @EntityFromBody() updateGroup: UpdateUserGroup) {
+ let oldGroup = await this.userGroupsRepository.findOne({ id: id });
- if (!oldUserGroup) {
- throw new UserGroupNotFoundError()
+ if (!oldGroup) {
+ throw new UserGroupNotFoundError();
}
- if (oldUserGroup.id != userGroup.id) {
+ if (oldGroup.id != updateGroup.id) {
throw new UserGroupIdsNotMatchingError();
}
+ await this.userGroupsRepository.save(await updateGroup.update(oldGroup));
- await this.userGroupsRepository.save(userGroup);
- return userGroup;
+ return (await this.userGroupsRepository.findOne({ id: id }, { relations: ['permissions', 'groups'] })).toResponse();
}
@Delete('/:id')
diff --git a/src/errors/AddressErrors.ts b/src/errors/AddressErrors.ts
index 18cf624..27f2e5f 100644
--- a/src/errors/AddressErrors.ts
+++ b/src/errors/AddressErrors.ts
@@ -9,11 +9,11 @@ export class AddressWrongTypeError extends NotAcceptableError {
name = "AddressWrongTypeError"
@IsString()
- message = "The address must be an existing adress's id. \n You provided a object of another type."
+ message = "The address must be an existing address's id. \n You provided a object of another type."
}
/**
- * Error to throw, when a non-existant address get's loaded.
+ * Error to throw, when a non-existent address get's loaded.
*/
export class AddressNotFoundError extends NotFoundError {
@IsString()
diff --git a/src/errors/AuthError.ts b/src/errors/AuthError.ts
index 848ce78..6e3cd9d 100644
--- a/src/errors/AuthError.ts
+++ b/src/errors/AuthError.ts
@@ -118,7 +118,7 @@ export class RefreshTokenCountInvalidError extends NotAcceptableError {
}
/**
- * Error to throw when someone tryes to reset a user's password more than once in 15 minutes.
+ * Error to throw when someone tries to reset a user's password more than once in 15 minutes.
*/
export class ResetAlreadyRequestedError extends NotAcceptableError {
@IsString()
diff --git a/src/errors/GroupContactErrors.ts b/src/errors/GroupContactErrors.ts
index 7dc19e8..92fd4a2 100644
--- a/src/errors/GroupContactErrors.ts
+++ b/src/errors/GroupContactErrors.ts
@@ -13,7 +13,7 @@ export class GroupContactWrongTypeError extends NotAcceptableError {
}
/**
- * Error to throw, when a non-existant groupContact get's loaded.
+ * Error to throw, when a non-existent groupContact get's loaded.
*/
export class GroupContactNotFoundError extends NotFoundError {
@IsString()
diff --git a/src/errors/PrincipalErrors.ts b/src/errors/PrincipalErrors.ts
index d519dc7..bd7677c 100644
--- a/src/errors/PrincipalErrors.ts
+++ b/src/errors/PrincipalErrors.ts
@@ -13,12 +13,12 @@ export class PrincipalNotFoundError extends NotFoundError {
}
/**
- * Error to throw, when a provided runnerOrganisation doesn't belong to the accepted types.
+ * Error to throw, when a provided runner organization doesn't belong to the accepted types.
*/
export class PrincipalWrongTypeError extends NotAcceptableError {
@IsString()
name = "PrincipalWrongTypeError"
@IsString()
- message = "The princial must have an existing principal's id. \n You provided a object of another type."
+ message = "The principal must have an existing principal's id. \n You provided a object of another type."
}
diff --git a/src/errors/RunnerCardErrors.ts b/src/errors/RunnerCardErrors.ts
index 63c3485..7976dc9 100644
--- a/src/errors/RunnerCardErrors.ts
+++ b/src/errors/RunnerCardErrors.ts
@@ -32,12 +32,12 @@ export class RunnerCardHasScansError extends NotAcceptableError {
name = "RunnerCardHasScansError"
@IsString()
- message = "This card still has scans associated with it. \n If you want to delete this card with all it's scans add `?force` to your query. \n Otherwise please consider just diableing it."
+ message = "This card still has scans associated with it. \n If you want to delete this card with all it's scans add `?force` to your query. \n Otherwise please consider just disabling it."
}
/**
* Error to throw when a card's id is too big to generate a ean-13 barcode for it.
- * This error should never reach a enduser.
+ * This error should never reach a end user.
*/
export class RunnerCardIdOutOfRangeError extends Error {
@IsString()
diff --git a/src/errors/RunnerErrors.ts b/src/errors/RunnerErrors.ts
index 6ef12c5..b60a70d 100644
--- a/src/errors/RunnerErrors.ts
+++ b/src/errors/RunnerErrors.ts
@@ -32,5 +32,5 @@ export class RunnerGroupNeededError extends NotAcceptableError {
name = "RunnerGroupNeededError"
@IsString()
- message = "Runner's need to be part of one group (team or organisiation)! \n You provided neither."
+ message = "Runner's need to be part of one group (team or organisation)! \n You provided neither."
}
\ No newline at end of file
diff --git a/src/errors/RunnerOrganisationErrors.ts b/src/errors/RunnerOrganisationErrors.ts
index b004acf..081fbf0 100644
--- a/src/errors/RunnerOrganisationErrors.ts
+++ b/src/errors/RunnerOrganisationErrors.ts
@@ -13,7 +13,7 @@ export class RunnerOrganisationNotFoundError extends NotFoundError {
}
/**
- * Error to throw when two runner organisations' ids don't match.
+ * Error to throw when two runner organisation's ids don't match.
* Usually occurs when a user tries to change a runner organisation's id.
*/
export class RunnerOrganisationIdsNotMatchingError extends NotAcceptableError {
diff --git a/src/errors/ScanStationErrors.ts b/src/errors/ScanStationErrors.ts
index c013cf5..3b01f5e 100644
--- a/src/errors/ScanStationErrors.ts
+++ b/src/errors/ScanStationErrors.ts
@@ -2,7 +2,7 @@ import { IsString } from 'class-validator';
import { NotAcceptableError, NotFoundError } from 'routing-controllers';
/**
- * Error to throw, when a non-existant scan station get's loaded.
+ * Error to throw, when a non-existent scan station get's loaded.
*/
export class ScanStationNotFoundError extends NotFoundError {
@IsString()
diff --git a/src/errors/StatsClientErrors.ts b/src/errors/StatsClientErrors.ts
index ab7f1ef..68a088d 100644
--- a/src/errors/StatsClientErrors.ts
+++ b/src/errors/StatsClientErrors.ts
@@ -2,7 +2,7 @@ import { IsString } from 'class-validator';
import { NotAcceptableError, NotFoundError } from 'routing-controllers';
/**
- * Error to throw, when a non-existant stats client get's loaded.
+ * Error to throw, when a non-existent stats client get's loaded.
*/
export class StatsClientNotFoundError extends NotFoundError {
@IsString()
diff --git a/src/errors/UserGroupErrors.ts b/src/errors/UserGroupErrors.ts
index 7edd6fd..07f4224 100644
--- a/src/errors/UserGroupErrors.ts
+++ b/src/errors/UserGroupErrors.ts
@@ -2,7 +2,7 @@ import { IsString } from 'class-validator';
import { NotAcceptableError, NotFoundError } from 'routing-controllers';
/**
- * Error to throw when no groupname is set.
+ * Error to throw when no group name is set.
*/
export class GroupNameNeededError extends NotFoundError {
@IsString()
@@ -13,7 +13,7 @@ export class GroupNameNeededError extends NotFoundError {
}
/**
- * Error to throw when a usergroup couldn't be found.
+ * Error to throw when a user group couldn't be found.
*/
export class UserGroupNotFoundError extends NotFoundError {
@IsString()
@@ -24,13 +24,13 @@ export class UserGroupNotFoundError extends NotFoundError {
}
/**
- * Error to throw when two usergroups' ids don't match.
- * Usually occurs when a user tries to change a usergroups's id.
+ * Error to throw when two user groups' ids don't match.
+ * Usually occurs when a user tries to change a user groups's id.
*/
export class UserGroupIdsNotMatchingError extends NotAcceptableError {
@IsString()
name = "UserGroupIdsNotMatchingError"
@IsString()
- message = "The ids don't match!! \n If you wanted to change a usergroup's id: This isn't allowed!"
+ message = "The ids don't match!! \n If you wanted to change a user group's id: This isn't allowed!"
}
\ No newline at end of file
diff --git a/src/loaders/openapi.ts b/src/loaders/openapi.ts
index 7d8acfe..0f3a49d 100644
--- a/src/loaders/openapi.ts
+++ b/src/loaders/openapi.ts
@@ -2,7 +2,7 @@ import { validationMetadatasToSchemas } from "class-validator-jsonschema";
import express, { Application } from "express";
import path from 'path';
import { getMetadataArgsStorage } from "routing-controllers";
-import { routingControllersToSpec } from "routing-controllers-openapi";
+import { generateSpec } from '../apispec';
/**
* Loader for everything openapi related - from creating the schema to serving it via a static route and swaggerUiExpress.
@@ -15,46 +15,7 @@ export default async (app: Application) => {
});
//Spec creation based on the previously created schemas
- const spec = routingControllersToSpec(
- storage,
- {
- routePrefix: "/api"
- },
- {
- components: {
- schemas,
- "securitySchemes": {
- "AuthToken": {
- "type": "http",
- "scheme": "bearer",
- "bearerFormat": "JWT",
- description: "A JWT based access token. Use /api/auth/login or /api/auth/refresh to get one."
- },
- "RefreshTokenCookie": {
- "type": "apiKey",
- "in": "cookie",
- "name": "lfk_backend__refresh_token",
- description: "A cookie containing a JWT based refreh token. Attention: Doesn't work in swagger-ui. Use /api/auth/login or /api/auth/refresh to get one."
- },
- "StatsApiToken": {
- "type": "http",
- "scheme": "bearer",
- description: "Api token that can be obtained by creating a new stats client (post to /api/statsclients). Only valid for obtaining stats."
- },
- "StationApiToken": {
- "type": "http",
- "scheme": "bearer",
- description: "Api token that can be obtained by creating a new scan station (post to /api/stations). Only valid for creating scans."
- }
- }
- },
- info: {
- description: "The the backend API for the LfK! runner system.",
- title: "LfK! Backend API",
- version: "0.0.8",
- },
- }
- );
+ const spec = generateSpec(storage, schemas);
app.get(["/api/docs/openapi.json", "/api/docs/swagger.json"], (req, res) => {
res.json(spec);
});
diff --git a/src/middlewares/RawBody.ts b/src/middlewares/RawBody.ts
index 57efefa..52f6664 100644
--- a/src/middlewares/RawBody.ts
+++ b/src/middlewares/RawBody.ts
@@ -1,8 +1,8 @@
import { Request, Response } from 'express';
/**
- * Custom express middleware that appends the raw body to the request obeject.
- * Mainly used for parsing csvs from boddies.
+ * Custom express middleware that appends the raw body to the request object.
+ * Mainly used for parsing csvs from bodies.
*/
const RawBodyMiddleware = (req: Request, res: Response, next: () => void) => {
diff --git a/src/middlewares/ScanAuth.ts b/src/middlewares/ScanAuth.ts
index 7b16420..2f39bbf 100644
--- a/src/middlewares/ScanAuth.ts
+++ b/src/middlewares/ScanAuth.ts
@@ -5,8 +5,9 @@ import { ScanStation } from '../models/entities/ScanStation';
import authchecker from './authchecker';
/**
- * This middleware handels the authentification of scan station api tokens.
- * The tokens have to be provided via Bearer auth header.
+ * This middleware handles the authentication of scan station api tokens.
+ * The tokens have to be provided via Bearer authorization header.
+ * You have to manually use this middleware via @UseBefore(ScanAuth) instead of using @Authorized().
* @param req Express request object.
* @param res Express response object.
* @param next Next function to call on success.
@@ -31,7 +32,7 @@ const ScanAuth = async (req: Request, res: Response, next: () => void) => {
}
finally {
if (prefix == "" || prefix == undefined || prefix == null) {
- res.status(401).send("Api token non-existant or invalid syntax.");
+ res.status(401).send("Api token non-existent or invalid syntax.");
return;
}
}
@@ -45,7 +46,7 @@ const ScanAuth = async (req: Request, res: Response, next: () => void) => {
}
finally {
if (user_authorized == false) {
- res.status(401).send("Api token non-existant or invalid syntax.");
+ res.status(401).send("Api token non-existent or invalid syntax.");
return;
}
else {
diff --git a/src/middlewares/StatsAuth.ts b/src/middlewares/StatsAuth.ts
index 990206b..a6928be 100644
--- a/src/middlewares/StatsAuth.ts
+++ b/src/middlewares/StatsAuth.ts
@@ -5,8 +5,9 @@ import { StatsClient } from '../models/entities/StatsClient';
import authchecker from './authchecker';
/**
- * This middleware handels the authentification of stats client api tokens.
- * The tokens have to be provided via Bearer auth header.
+ * This middleware handles the authentication of stats client api tokens.
+ * The tokens have to be provided via Bearer authorization header.
+ * You have to manually use this middleware via @UseBefore(StatsAuth) instead of using @Authorized().
* @param req Express request object.
* @param res Express response object.
* @param next Next function to call on success.
diff --git a/src/middlewares/authchecker.ts b/src/middlewares/authchecker.ts
index 61ca231..45294d9 100644
--- a/src/middlewares/authchecker.ts
+++ b/src/middlewares/authchecker.ts
@@ -8,7 +8,7 @@ import { JwtCreator, JwtUser } from '../jwtcreator';
import { User } from '../models/entities/User';
/**
- * Handels authorisation verification via jwt's for all api endpoints using the @Authorized decorator.
+ * Handles authentication via jwt's (Bearer authorization header) for all api endpoints using the @Authorized decorator.
* @param action Routing-Controllers action object that provides request and response objects among other stuff.
* @param permissions The permissions that the endpoint using @Authorized requires.
*/
@@ -43,7 +43,7 @@ const authchecker = async (action: Action, permissions: string[] | string) => {
}
/**
- * Handels soft-refreshing of access-tokens.
+ * Handles soft-refreshing of access-tokens.
* @param action Routing-Controllers action object that provides request and response objects among other stuff.
*/
const refresh = async (action: Action) => {
diff --git a/src/models/actions/ImportRunner.ts b/src/models/actions/ImportRunner.ts
index 3155b0e..b399d90 100644
--- a/src/models/actions/ImportRunner.ts
+++ b/src/models/actions/ImportRunner.ts
@@ -5,7 +5,7 @@ import { RunnerOrganisationNotFoundError } from '../../errors/RunnerOrganisation
import { RunnerGroup } from '../entities/RunnerGroup';
import { RunnerOrganisation } from '../entities/RunnerOrganisation';
import { RunnerTeam } from '../entities/RunnerTeam';
-import { CreateRunner } from './CreateRunner';
+import { CreateRunner } from './create/CreateRunner';
/**
* Special class used to import runners from csv files - or json arrays created from csv to be exact.
diff --git a/src/models/actions/RefreshAuth.ts b/src/models/actions/RefreshAuth.ts
index bcc4fbb..20e8abf 100644
--- a/src/models/actions/RefreshAuth.ts
+++ b/src/models/actions/RefreshAuth.ts
@@ -5,7 +5,7 @@ import { config } from '../../config';
import { IllegalJWTError, JwtNotProvidedError, RefreshTokenCountInvalidError, UserDisabledError, UserNotFoundError } from '../../errors/AuthError';
import { JwtCreator } from "../../jwtcreator";
import { User } from '../entities/User';
-import { Auth } from '../responses/ResponseAuth';
+import { ResponseAuth } from '../responses/ResponseAuth';
/**
* This class is used to create refreshed auth credentials.
@@ -24,8 +24,8 @@ export class RefreshAuth {
/**
* Creates a new auth object based on this.
*/
- public async toAuth(): Promise {
- let newAuth: Auth = new Auth();
+ public async toAuth(): Promise {
+ let newAuth: ResponseAuth = new ResponseAuth();
if (!this.token || this.token === undefined) {
throw new JwtNotProvidedError()
}
diff --git a/src/models/actions/CreateAddress.ts b/src/models/actions/create/CreateAddress.ts
similarity index 91%
rename from src/models/actions/CreateAddress.ts
rename to src/models/actions/create/CreateAddress.ts
index 66ee9bd..c399bb8 100644
--- a/src/models/actions/CreateAddress.ts
+++ b/src/models/actions/create/CreateAddress.ts
@@ -1,6 +1,6 @@
import { IsNotEmpty, IsOptional, IsPostalCode, IsString } from 'class-validator';
-import { config } from '../../config';
-import { Address } from '../entities/Address';
+import { config } from '../../../config';
+import { Address } from '../../entities/Address';
/**
* This classed is used to create a new Address entity from a json body (post request).
@@ -56,7 +56,7 @@ export class CreateAddress {
/**
* Creates a new Address entity from this.
*/
- public toAddress(): Address {
+ public async toEntity(): Promise {
let newAddress: Address = new Address();
newAddress.address1 = this.address1;
diff --git a/src/models/actions/CreateAuth.ts b/src/models/actions/create/CreateAuth.ts
similarity index 86%
rename from src/models/actions/CreateAuth.ts
rename to src/models/actions/create/CreateAuth.ts
index 6b22d7d..d9b96b7 100644
--- a/src/models/actions/CreateAuth.ts
+++ b/src/models/actions/create/CreateAuth.ts
@@ -1,11 +1,11 @@
import * as argon2 from "argon2";
import { IsEmail, IsNotEmpty, IsOptional, IsString } from 'class-validator';
import { getConnectionManager } from 'typeorm';
-import { InvalidCredentialsError, PasswordNeededError, UserDisabledError, UserNotFoundError } from '../../errors/AuthError';
-import { UsernameOrEmailNeededError } from '../../errors/UserErrors';
-import { JwtCreator } from '../../jwtcreator';
-import { User } from '../entities/User';
-import { Auth } from '../responses/ResponseAuth';
+import { InvalidCredentialsError, PasswordNeededError, UserDisabledError, UserNotFoundError } from '../../../errors/AuthError';
+import { UsernameOrEmailNeededError } from '../../../errors/UserErrors';
+import { JwtCreator } from '../../../jwtcreator';
+import { User } from '../../entities/User';
+import { ResponseAuth } from '../../responses/ResponseAuth';
/**
* This class is used to create auth credentials based on user credentials provided in a json body (post request).
@@ -42,8 +42,8 @@ export class CreateAuth {
/**
* Creates a new auth object based on this.
*/
- public async toAuth(): Promise {
- let newAuth: Auth = new Auth();
+ public async toAuth(): Promise {
+ let newAuth: ResponseAuth = new ResponseAuth();
if (this.email === undefined && this.username === undefined) {
throw new UsernameOrEmailNeededError();
diff --git a/src/models/actions/CreateDonor.ts b/src/models/actions/create/CreateDonor.ts
similarity index 85%
rename from src/models/actions/CreateDonor.ts
rename to src/models/actions/create/CreateDonor.ts
index 25a631c..791461a 100644
--- a/src/models/actions/CreateDonor.ts
+++ b/src/models/actions/create/CreateDonor.ts
@@ -1,6 +1,6 @@
import { IsBoolean, IsOptional } from 'class-validator';
-import { DonorReceiptAddressNeededError } from '../../errors/DonorErrors';
-import { Donor } from '../entities/Donor';
+import { DonorReceiptAddressNeededError } from '../../../errors/DonorErrors';
+import { Donor } from '../../entities/Donor';
import { CreateParticipant } from './CreateParticipant';
/**
@@ -18,7 +18,7 @@ export class CreateDonor extends CreateParticipant {
/**
* Creates a new Donor entity from this.
*/
- public async toDonor(): Promise {
+ public async toEntity(): Promise {
let newDonor: Donor = new Donor();
newDonor.firstname = this.firstname;
diff --git a/src/models/actions/CreateGroupContact.ts b/src/models/actions/create/CreateGroupContact.ts
similarity index 87%
rename from src/models/actions/CreateGroupContact.ts
rename to src/models/actions/create/CreateGroupContact.ts
index 915f897..c6e10a8 100644
--- a/src/models/actions/CreateGroupContact.ts
+++ b/src/models/actions/create/CreateGroupContact.ts
@@ -1,85 +1,85 @@
-import { IsEmail, IsInt, IsNotEmpty, IsOptional, IsPhoneNumber, IsString } from 'class-validator';
-import { getConnectionManager } from 'typeorm';
-import { config } from '../../config';
-import { AddressNotFoundError, AddressWrongTypeError } from '../../errors/AddressErrors';
-import { Address } from '../entities/Address';
-import { GroupContact } from '../entities/GroupContact';
-
-/**
- * This classed is used to create a new Group entity from a json body (post request).
- */
-export class CreateGroupContact {
- /**
- * The new contact's first name.
- */
- @IsNotEmpty()
- @IsString()
- firstname: string;
-
- /**
- * The new contact's middle name.
- */
- @IsOptional()
- @IsString()
- middlename?: string;
-
- /**
- * The new contact's last name.
- */
- @IsNotEmpty()
- @IsString()
- lastname: string;
-
- /**
- * The new contact's address.
- * Must be the address's id.
- */
- @IsInt()
- @IsOptional()
- address?: number;
-
- /**
- * The contact's phone number.
- * This will be validated against the configured country phone numer syntax (default: international).
- */
- @IsOptional()
- @IsPhoneNumber(config.phone_validation_countrycode)
- phone?: string;
-
- /**
- * The contact's email address.
- */
- @IsOptional()
- @IsEmail()
- email?: string;
-
- /**
- * Gets the new contact's address by it's id.
- */
- public async getAddress(): Promise {
- if (this.address === undefined || this.address === null) {
- return null;
- }
- if (!isNaN(this.address)) {
- let address = await getConnectionManager().get().getRepository(Address).findOne({ id: this.address });
- if (!address) { throw new AddressNotFoundError; }
- return address;
- }
-
- throw new AddressWrongTypeError;
- }
-
- /**
- * Creates a new Address entity from this.
- */
- public async toGroupContact(): Promise {
- let contact: GroupContact = new GroupContact();
- contact.firstname = this.firstname;
- contact.middlename = this.middlename;
- contact.lastname = this.lastname;
- contact.email = this.email;
- contact.phone = this.phone;
- contact.address = await this.getAddress();
- return null;
- }
+import { IsEmail, IsInt, IsNotEmpty, IsOptional, IsPhoneNumber, IsString } from 'class-validator';
+import { getConnectionManager } from 'typeorm';
+import { config } from '../../../config';
+import { AddressNotFoundError, AddressWrongTypeError } from '../../../errors/AddressErrors';
+import { Address } from '../../entities/Address';
+import { GroupContact } from '../../entities/GroupContact';
+
+/**
+ * This classed is used to create a new Group entity from a json body (post request).
+ */
+export class CreateGroupContact {
+ /**
+ * The new contact's first name.
+ */
+ @IsNotEmpty()
+ @IsString()
+ firstname: string;
+
+ /**
+ * The new contact's middle name.
+ */
+ @IsOptional()
+ @IsString()
+ middlename?: string;
+
+ /**
+ * The new contact's last name.
+ */
+ @IsNotEmpty()
+ @IsString()
+ lastname: string;
+
+ /**
+ * The new contact's address.
+ * Must be the address's id.
+ */
+ @IsInt()
+ @IsOptional()
+ address?: number;
+
+ /**
+ * The contact's phone number.
+ * This will be validated against the configured country phone numer syntax (default: international).
+ */
+ @IsOptional()
+ @IsPhoneNumber(config.phone_validation_countrycode)
+ phone?: string;
+
+ /**
+ * The contact's email address.
+ */
+ @IsOptional()
+ @IsEmail()
+ email?: string;
+
+ /**
+ * Gets the new contact's address by it's id.
+ */
+ public async getAddress(): Promise {
+ if (this.address === undefined || this.address === null) {
+ return null;
+ }
+ if (!isNaN(this.address)) {
+ let address = await getConnectionManager().get().getRepository(Address).findOne({ id: this.address });
+ if (!address) { throw new AddressNotFoundError; }
+ return address;
+ }
+
+ throw new AddressWrongTypeError;
+ }
+
+ /**
+ * Creates a new Address entity from this.
+ */
+ public async toEntity(): Promise {
+ let contact: GroupContact = new GroupContact();
+ contact.firstname = this.firstname;
+ contact.middlename = this.middlename;
+ contact.lastname = this.lastname;
+ contact.email = this.email;
+ contact.phone = this.phone;
+ contact.address = await this.getAddress();
+ return null;
+ }
}
\ No newline at end of file
diff --git a/src/models/actions/CreateParticipant.ts b/src/models/actions/create/CreateParticipant.ts
similarity index 90%
rename from src/models/actions/CreateParticipant.ts
rename to src/models/actions/create/CreateParticipant.ts
index 165bddb..17e7c56 100644
--- a/src/models/actions/CreateParticipant.ts
+++ b/src/models/actions/create/CreateParticipant.ts
@@ -1,72 +1,72 @@
-import { IsEmail, IsInt, IsNotEmpty, IsOptional, IsPhoneNumber, IsString } from 'class-validator';
-import { getConnectionManager } from 'typeorm';
-import { config } from '../../config';
-import { AddressNotFoundError, AddressWrongTypeError } from '../../errors/AddressErrors';
-import { Address } from '../entities/Address';
-
-/**
- * This classed is used to create a new Participant entity from a json body (post request).
- */
-export abstract class CreateParticipant {
- /**
- * The new participant's first name.
- */
- @IsString()
- @IsNotEmpty()
- firstname: string;
-
- /**
- * The new participant's middle name.
- */
- @IsString()
- @IsOptional()
- middlename?: string;
-
- /**
- * The new participant's last name.
- */
- @IsString()
- @IsNotEmpty()
- lastname: string;
-
- /**
- * The new participant's phone number.
- * This will be validated against the configured country phone numer syntax (default: international).
- */
- @IsString()
- @IsOptional()
- @IsPhoneNumber(config.phone_validation_countrycode)
- phone?: string;
-
- /**
- * The new participant's e-mail address.
- */
- @IsString()
- @IsOptional()
- @IsEmail()
- email?: string;
-
- /**
- * The new participant's address.
- * Must be of type number (address id).
- */
- @IsInt()
- @IsOptional()
- address?: number;
-
- /**
- * Gets the new participant's address by it's address.
- */
- public async getAddress(): Promise {
- if (this.address === undefined || this.address === null) {
- return null;
- }
- if (!isNaN(this.address)) {
- let address = await getConnectionManager().get().getRepository(Address).findOne({ id: this.address });
- if (!address) { throw new AddressNotFoundError; }
- return address;
- }
-
- throw new AddressWrongTypeError;
- }
+import { IsEmail, IsInt, IsNotEmpty, IsOptional, IsPhoneNumber, IsString } from 'class-validator';
+import { getConnectionManager } from 'typeorm';
+import { config } from '../../../config';
+import { AddressNotFoundError, AddressWrongTypeError } from '../../../errors/AddressErrors';
+import { Address } from '../../entities/Address';
+
+/**
+ * This classed is used to create a new Participant entity from a json body (post request).
+ */
+export abstract class CreateParticipant {
+ /**
+ * The new participant's first name.
+ */
+ @IsString()
+ @IsNotEmpty()
+ firstname: string;
+
+ /**
+ * The new participant's middle name.
+ */
+ @IsString()
+ @IsOptional()
+ middlename?: string;
+
+ /**
+ * The new participant's last name.
+ */
+ @IsString()
+ @IsNotEmpty()
+ lastname: string;
+
+ /**
+ * The new participant's phone number.
+ * This will be validated against the configured country phone numer syntax (default: international).
+ */
+ @IsString()
+ @IsOptional()
+ @IsPhoneNumber(config.phone_validation_countrycode)
+ phone?: string;
+
+ /**
+ * The new participant's e-mail address.
+ */
+ @IsString()
+ @IsOptional()
+ @IsEmail()
+ email?: string;
+
+ /**
+ * The new participant's address.
+ * Must be of type number (address id).
+ */
+ @IsInt()
+ @IsOptional()
+ address?: number;
+
+ /**
+ * Gets the new participant's address by it's address.
+ */
+ public async getAddress(): Promise {
+ if (this.address === undefined || this.address === null) {
+ return null;
+ }
+ if (!isNaN(this.address)) {
+ let address = await getConnectionManager().get().getRepository(Address).findOne({ id: this.address });
+ if (!address) { throw new AddressNotFoundError; }
+ return address;
+ }
+
+ throw new AddressWrongTypeError;
+ }
}
\ No newline at end of file
diff --git a/src/models/actions/CreatePermission.ts b/src/models/actions/create/CreatePermission.ts
similarity index 77%
rename from src/models/actions/CreatePermission.ts
rename to src/models/actions/create/CreatePermission.ts
index 5ee9582..e59a186 100644
--- a/src/models/actions/CreatePermission.ts
+++ b/src/models/actions/create/CreatePermission.ts
@@ -4,11 +4,11 @@ import {
IsNotEmpty
} from "class-validator";
import { getConnectionManager } from 'typeorm';
-import { PrincipalNotFoundError } from '../../errors/PrincipalErrors';
-import { Permission } from '../entities/Permission';
-import { Principal } from '../entities/Principal';
-import { PermissionAction } from '../enums/PermissionAction';
-import { PermissionTarget } from '../enums/PermissionTargets';
+import { PrincipalNotFoundError } from '../../../errors/PrincipalErrors';
+import { Permission } from '../../entities/Permission';
+import { Principal } from '../../entities/Principal';
+import { PermissionAction } from '../../enums/PermissionAction';
+import { PermissionTarget } from '../../enums/PermissionTargets';
/**
* This classed is used to create a new Permission entity from a json body (post request).
@@ -39,7 +39,7 @@ export class CreatePermission {
/**
* Creates a new Permission entity from this.
*/
- public async toPermission(): Promise {
+ public async toEntity(): Promise {
let newPermission: Permission = new Permission();
newPermission.principal = await this.getPrincipal();
diff --git a/src/models/actions/CreateResetToken.ts b/src/models/actions/create/CreateResetToken.ts
similarity index 88%
rename from src/models/actions/CreateResetToken.ts
rename to src/models/actions/create/CreateResetToken.ts
index dcf22f1..81f430a 100644
--- a/src/models/actions/CreateResetToken.ts
+++ b/src/models/actions/create/CreateResetToken.ts
@@ -1,9 +1,9 @@
import { IsEmail, IsOptional, IsString } from 'class-validator';
import { getConnectionManager } from 'typeorm';
-import { ResetAlreadyRequestedError, UserDisabledError, UserNotFoundError } from '../../errors/AuthError';
-import { UsernameOrEmailNeededError } from '../../errors/UserErrors';
-import { JwtCreator } from '../../jwtcreator';
-import { User } from '../entities/User';
+import { ResetAlreadyRequestedError, UserDisabledError, UserNotFoundError } from '../../../errors/AuthError';
+import { UsernameOrEmailNeededError } from '../../../errors/UserErrors';
+import { JwtCreator } from '../../../jwtcreator';
+import { User } from '../../entities/User';
/**
* This calss is used to create password reset tokens for users.
diff --git a/src/models/actions/CreateRunner.ts b/src/models/actions/create/CreateRunner.ts
similarity index 77%
rename from src/models/actions/CreateRunner.ts
rename to src/models/actions/create/CreateRunner.ts
index ab2cc1f..2286fdf 100644
--- a/src/models/actions/CreateRunner.ts
+++ b/src/models/actions/create/CreateRunner.ts
@@ -1,10 +1,10 @@
import { IsInt } from 'class-validator';
import { getConnectionManager } from 'typeorm';
-import { RunnerGroupNotFoundError } from '../../errors/RunnerGroupErrors';
-import { RunnerOrganisationWrongTypeError } from '../../errors/RunnerOrganisationErrors';
-import { RunnerTeamNeedsParentError } from '../../errors/RunnerTeamErrors';
-import { Runner } from '../entities/Runner';
-import { RunnerGroup } from '../entities/RunnerGroup';
+import { RunnerGroupNotFoundError } from '../../../errors/RunnerGroupErrors';
+import { RunnerOrganisationWrongTypeError } from '../../../errors/RunnerOrganisationErrors';
+import { RunnerTeamNeedsParentError } from '../../../errors/RunnerTeamErrors';
+import { Runner } from '../../entities/Runner';
+import { RunnerGroup } from '../../entities/RunnerGroup';
import { CreateParticipant } from './CreateParticipant';
/**
@@ -21,7 +21,7 @@ export class CreateRunner extends CreateParticipant {
/**
* Creates a new Runner entity from this.
*/
- public async toRunner(): Promise {
+ public async toEntity(): Promise {
let newRunner: Runner = new Runner();
newRunner.firstname = this.firstname;
diff --git a/src/models/actions/CreateRunnerCard.ts b/src/models/actions/create/CreateRunnerCard.ts
similarity index 86%
rename from src/models/actions/CreateRunnerCard.ts
rename to src/models/actions/create/CreateRunnerCard.ts
index 2baf1e9..b661e6f 100644
--- a/src/models/actions/CreateRunnerCard.ts
+++ b/src/models/actions/create/CreateRunnerCard.ts
@@ -1,8 +1,8 @@
import { IsBoolean, IsInt, IsOptional } from 'class-validator';
import { getConnection } from 'typeorm';
-import { RunnerNotFoundError } from '../../errors/RunnerErrors';
-import { Runner } from '../entities/Runner';
-import { RunnerCard } from '../entities/RunnerCard';
+import { RunnerNotFoundError } from '../../../errors/RunnerErrors';
+import { Runner } from '../../entities/Runner';
+import { RunnerCard } from '../../entities/RunnerCard';
/**
* This classed is used to create a new RunnerCard entity from a json body (post request).
diff --git a/src/models/actions/CreateRunnerGroup.ts b/src/models/actions/create/CreateRunnerGroup.ts
similarity index 91%
rename from src/models/actions/CreateRunnerGroup.ts
rename to src/models/actions/create/CreateRunnerGroup.ts
index 9f4c803..0b62024 100644
--- a/src/models/actions/CreateRunnerGroup.ts
+++ b/src/models/actions/create/CreateRunnerGroup.ts
@@ -1,7 +1,7 @@
import { IsInt, IsNotEmpty, IsOptional, IsString } from 'class-validator';
import { getConnectionManager } from 'typeorm';
-import { GroupContactNotFoundError, GroupContactWrongTypeError } from '../../errors/GroupContactErrors';
-import { GroupContact } from '../entities/GroupContact';
+import { GroupContactNotFoundError, GroupContactWrongTypeError } from '../../../errors/GroupContactErrors';
+import { GroupContact } from '../../entities/GroupContact';
/**
* This classed is used to create a new RunnerGroup entity from a json body (post request).
diff --git a/src/models/actions/CreateRunnerOrganisation.ts b/src/models/actions/create/CreateRunnerOrganisation.ts
similarity index 87%
rename from src/models/actions/CreateRunnerOrganisation.ts
rename to src/models/actions/create/CreateRunnerOrganisation.ts
index a0733de..04edf93 100644
--- a/src/models/actions/CreateRunnerOrganisation.ts
+++ b/src/models/actions/create/CreateRunnerOrganisation.ts
@@ -1,8 +1,8 @@
import { IsInt, IsOptional } from 'class-validator';
import { getConnectionManager } from 'typeorm';
-import { AddressNotFoundError, AddressWrongTypeError } from '../../errors/AddressErrors';
-import { Address } from '../entities/Address';
-import { RunnerOrganisation } from '../entities/RunnerOrganisation';
+import { AddressNotFoundError, AddressWrongTypeError } from '../../../errors/AddressErrors';
+import { Address } from '../../entities/Address';
+import { RunnerOrganisation } from '../../entities/RunnerOrganisation';
import { CreateRunnerGroup } from './CreateRunnerGroup';
/**
@@ -36,7 +36,7 @@ export class CreateRunnerOrganisation extends CreateRunnerGroup {
/**
* Creates a new RunnerOrganisation entity from this.
*/
- public async toRunnerOrganisation(): Promise {
+ public async toEntity(): Promise {
let newRunnerOrganisation: RunnerOrganisation = new RunnerOrganisation();
newRunnerOrganisation.name = this.name;
diff --git a/src/models/actions/CreateRunnerTeam.ts b/src/models/actions/create/CreateRunnerTeam.ts
similarity index 81%
rename from src/models/actions/CreateRunnerTeam.ts
rename to src/models/actions/create/CreateRunnerTeam.ts
index 30a27b3..fc5c310 100644
--- a/src/models/actions/CreateRunnerTeam.ts
+++ b/src/models/actions/create/CreateRunnerTeam.ts
@@ -1,9 +1,9 @@
import { IsInt, IsNotEmpty } from 'class-validator';
import { getConnectionManager } from 'typeorm';
-import { RunnerOrganisationNotFoundError, RunnerOrganisationWrongTypeError } from '../../errors/RunnerOrganisationErrors';
-import { RunnerTeamNeedsParentError } from '../../errors/RunnerTeamErrors';
-import { RunnerOrganisation } from '../entities/RunnerOrganisation';
-import { RunnerTeam } from '../entities/RunnerTeam';
+import { RunnerOrganisationNotFoundError, RunnerOrganisationWrongTypeError } from '../../../errors/RunnerOrganisationErrors';
+import { RunnerTeamNeedsParentError } from '../../../errors/RunnerTeamErrors';
+import { RunnerOrganisation } from '../../entities/RunnerOrganisation';
+import { RunnerTeam } from '../../entities/RunnerTeam';
import { CreateRunnerGroup } from './CreateRunnerGroup';
/**
@@ -37,7 +37,7 @@ export class CreateRunnerTeam extends CreateRunnerGroup {
/**
* Creates a new RunnerTeam entity from this.
*/
- public async toRunnerTeam(): Promise {
+ public async toEntity(): Promise {
let newRunnerTeam: RunnerTeam = new RunnerTeam();
newRunnerTeam.name = this.name;
diff --git a/src/models/actions/CreateScan.ts b/src/models/actions/create/CreateScan.ts
similarity index 87%
rename from src/models/actions/CreateScan.ts
rename to src/models/actions/create/CreateScan.ts
index e0d0efc..496b8a0 100644
--- a/src/models/actions/CreateScan.ts
+++ b/src/models/actions/create/CreateScan.ts
@@ -1,8 +1,8 @@
import { IsBoolean, IsInt, IsOptional, IsPositive } from 'class-validator';
import { getConnection } from 'typeorm';
-import { RunnerNotFoundError } from '../../errors/RunnerErrors';
-import { Runner } from '../entities/Runner';
-import { Scan } from '../entities/Scan';
+import { RunnerNotFoundError } from '../../../errors/RunnerErrors';
+import { Runner } from '../../entities/Runner';
+import { Scan } from '../../entities/Scan';
/**
* This class is used to create a new Scan entity from a json body (post request).
@@ -36,7 +36,7 @@ export abstract class CreateScan {
/**
* Creates a new Scan entity from this.
*/
- public async toScan(): Promise {
+ public async toEntity(): Promise {
let newScan = new Scan();
newScan.distance = this.distance;
diff --git a/src/models/actions/CreateScanStation.ts b/src/models/actions/create/CreateScanStation.ts
similarity index 91%
rename from src/models/actions/CreateScanStation.ts
rename to src/models/actions/create/CreateScanStation.ts
index 5d93b7c..0804b9f 100644
--- a/src/models/actions/CreateScanStation.ts
+++ b/src/models/actions/create/CreateScanStation.ts
@@ -3,9 +3,9 @@ import { IsBoolean, IsInt, IsOptional, IsPositive, IsString } from 'class-valida
import crypto from 'crypto';
import { getConnection } from 'typeorm';
import * as uuid from 'uuid';
-import { TrackNotFoundError } from '../../errors/TrackErrors';
-import { ScanStation } from '../entities/ScanStation';
-import { Track } from '../entities/Track';
+import { TrackNotFoundError } from '../../../errors/TrackErrors';
+import { ScanStation } from '../../entities/ScanStation';
+import { Track } from '../../entities/Track';
/**
* This class is used to create a new StatsClient entity from a json body (post request).
diff --git a/src/models/actions/CreateStatsClient.ts b/src/models/actions/create/CreateStatsClient.ts
similarity index 89%
rename from src/models/actions/CreateStatsClient.ts
rename to src/models/actions/create/CreateStatsClient.ts
index 40172e5..0f666fc 100644
--- a/src/models/actions/CreateStatsClient.ts
+++ b/src/models/actions/create/CreateStatsClient.ts
@@ -2,7 +2,7 @@ import * as argon2 from "argon2";
import { IsOptional, IsString } from 'class-validator';
import crypto from 'crypto';
import * as uuid from 'uuid';
-import { StatsClient } from '../entities/StatsClient';
+import { StatsClient } from '../../entities/StatsClient';
/**
* This classed is used to create a new StatsClient entity from a json body (post request).
@@ -18,7 +18,7 @@ export class CreateStatsClient {
/**
* Converts this to a StatsClient entity.
*/
- public async toStatsClient(): Promise {
+ public async toEntity(): Promise {
let newClient: StatsClient = new StatsClient();
newClient.description = this.description;
diff --git a/src/models/actions/CreateTrack.ts b/src/models/actions/create/CreateTrack.ts
similarity index 86%
rename from src/models/actions/CreateTrack.ts
rename to src/models/actions/create/CreateTrack.ts
index fdeae71..8c0db34 100644
--- a/src/models/actions/CreateTrack.ts
+++ b/src/models/actions/create/CreateTrack.ts
@@ -1,6 +1,6 @@
import { IsInt, IsNotEmpty, IsOptional, IsPositive, IsString } from 'class-validator';
-import { TrackLapTimeCantBeNegativeError } from '../../errors/TrackErrors';
-import { Track } from '../entities/Track';
+import { TrackLapTimeCantBeNegativeError } from '../../../errors/TrackErrors';
+import { Track } from '../../entities/Track';
/**
* This classed is used to create a new Track entity from a json body (post request).
@@ -31,7 +31,7 @@ export class CreateTrack {
/**
* Creates a new Track entity from this.
*/
- public toTrack(): Track {
+ public toEntity(): Track {
let newTrack: Track = new Track();
newTrack.name = this.name;
diff --git a/src/models/actions/CreateTrackScan.ts b/src/models/actions/create/CreateTrackScan.ts
similarity index 83%
rename from src/models/actions/CreateTrackScan.ts
rename to src/models/actions/create/CreateTrackScan.ts
index 51078c4..db63cf2 100644
--- a/src/models/actions/CreateTrackScan.ts
+++ b/src/models/actions/create/CreateTrackScan.ts
@@ -1,11 +1,11 @@
import { IsInt, IsPositive } from 'class-validator';
import { getConnection } from 'typeorm';
-import { RunnerCardNotFoundError } from '../../errors/RunnerCardErrors';
-import { RunnerNotFoundError } from '../../errors/RunnerErrors';
-import { ScanStationNotFoundError } from '../../errors/ScanStationErrors';
-import { RunnerCard } from '../entities/RunnerCard';
-import { ScanStation } from '../entities/ScanStation';
-import { TrackScan } from '../entities/TrackScan';
+import { RunnerCardNotFoundError } from '../../../errors/RunnerCardErrors';
+import { RunnerNotFoundError } from '../../../errors/RunnerErrors';
+import { ScanStationNotFoundError } from '../../../errors/ScanStationErrors';
+import { RunnerCard } from '../../entities/RunnerCard';
+import { ScanStation } from '../../entities/ScanStation';
+import { TrackScan } from '../../entities/TrackScan';
/**
* This classed is used to create a new Scan entity from a json body (post request).
@@ -30,7 +30,7 @@ export class CreateTrackScan {
/**
* Creates a new Track entity from this.
*/
- public async toScan(): Promise {
+ public async toEntity(): Promise {
let newScan: TrackScan = new TrackScan();
newScan.station = await this.getStation();
diff --git a/src/models/actions/CreateUser.ts b/src/models/actions/create/CreateUser.ts
similarity index 87%
rename from src/models/actions/CreateUser.ts
rename to src/models/actions/create/CreateUser.ts
index ad0f905..a5f20c2 100644
--- a/src/models/actions/CreateUser.ts
+++ b/src/models/actions/create/CreateUser.ts
@@ -1,132 +1,132 @@
-import * as argon2 from "argon2";
-import { IsBoolean, IsEmail, IsOptional, IsPhoneNumber, IsString, IsUrl } from 'class-validator';
-import { getConnectionManager } from 'typeorm';
-import * as uuid from 'uuid';
-import { config } from '../../config';
-import { UsernameOrEmailNeededError } from '../../errors/UserErrors';
-import { UserGroupNotFoundError } from '../../errors/UserGroupErrors';
-import { User } from '../entities/User';
-import { UserGroup } from '../entities/UserGroup';
-
-/**
- * This classed is used to create a new User entity from a json body (post request).
- */
-export class CreateUser {
- /**
- * The new user's first name.
- */
- @IsString()
- firstname: string;
-
- /**
- * The new user's middle name.
- */
- @IsString()
- @IsOptional()
- middlename?: string;
-
- /**
- * The new user's last name.
- */
- @IsString()
- lastname: string;
-
- /**
- * The new user's username.
- * You have to provide at least one of: {email, username}.
- */
- @IsOptional()
- @IsString()
- username?: string;
-
- /**
- * The new user's email address.
- * You have to provide at least one of: {email, username}.
- */
- @IsEmail()
- @IsString()
- @IsOptional()
- email?: string;
-
- /**
- * The new user's phone number.
- * This will be validated against the configured country phone numer syntax (default: international).
- */
- @IsPhoneNumber(config.phone_validation_countrycode)
- @IsOptional()
- phone?: string;
-
- /**
- * The new user's password.
- * This will of course not be saved in plaintext :)
- */
- @IsString()
- password: string;
-
- /**
- * Will the new user be enabled from the start?
- * Default: true
- */
- @IsBoolean()
- @IsOptional()
- enabled?: boolean = true;
-
- /**
- * The new user's groups' id(s).
- * You can provide either one groupId or an array of groupIDs.
- */
- @IsOptional()
- groups?: number[] | number
-
- /**
- * The user's profile pic (or rather a url pointing to it).
- */
- @IsString()
- @IsUrl()
- @IsOptional()
- profilePic?: string;
-
- /**
- * Converts this to a User entity.
- */
- public async toUser(): Promise {
- let newUser: User = new User();
-
- if (this.email === undefined && this.username === undefined) {
- throw new UsernameOrEmailNeededError();
- }
-
- newUser.email = this.email
- newUser.username = this.username
- newUser.firstname = this.firstname
- newUser.middlename = this.middlename
- newUser.lastname = this.lastname
- newUser.uuid = uuid.v4()
- newUser.phone = this.phone
- newUser.password = await argon2.hash(this.password + newUser.uuid);
- newUser.groups = await this.getGroups();
- newUser.enabled = this.enabled;
-
- if (!this.profilePic) { newUser.profilePic = `https://dev.lauf-fuer-kaya.de/lfk-logo.png`; }
- else { newUser.profilePic = this.profilePic; }
-
- return newUser;
- }
-
- /**
- * Get's all groups for this user by their id's;
- */
- public async getGroups() {
- if (!this.groups) { return null; }
- let groups = new Array();
- if (!Array.isArray(this.groups)) {
- this.groups = [this.groups]
- }
- for (let group of this.groups) {
- let found = await getConnectionManager().get().getRepository(UserGroup).findOne({ id: group });
- if (!found) { throw new UserGroupNotFoundError(); }
- groups.push(found);
- }
- return groups;
- }
+import * as argon2 from "argon2";
+import { IsBoolean, IsEmail, IsOptional, IsPhoneNumber, IsString, IsUrl } from 'class-validator';
+import { getConnectionManager } from 'typeorm';
+import * as uuid from 'uuid';
+import { config } from '../../../config';
+import { UsernameOrEmailNeededError } from '../../../errors/UserErrors';
+import { UserGroupNotFoundError } from '../../../errors/UserGroupErrors';
+import { User } from '../../entities/User';
+import { UserGroup } from '../../entities/UserGroup';
+
+/**
+ * This classed is used to create a new User entity from a json body (post request).
+ */
+export class CreateUser {
+ /**
+ * The new user's first name.
+ */
+ @IsString()
+ firstname: string;
+
+ /**
+ * The new user's middle name.
+ */
+ @IsString()
+ @IsOptional()
+ middlename?: string;
+
+ /**
+ * The new user's last name.
+ */
+ @IsString()
+ lastname: string;
+
+ /**
+ * The new user's username.
+ * You have to provide at least one of: {email, username}.
+ */
+ @IsOptional()
+ @IsString()
+ username?: string;
+
+ /**
+ * The new user's email address.
+ * You have to provide at least one of: {email, username}.
+ */
+ @IsEmail()
+ @IsString()
+ @IsOptional()
+ email?: string;
+
+ /**
+ * The new user's phone number.
+ * This will be validated against the configured country phone numer syntax (default: international).
+ */
+ @IsPhoneNumber(config.phone_validation_countrycode)
+ @IsOptional()
+ phone?: string;
+
+ /**
+ * The new user's password.
+ * This will of course not be saved in plaintext :)
+ */
+ @IsString()
+ password: string;
+
+ /**
+ * Will the new user be enabled from the start?
+ * Default: true
+ */
+ @IsBoolean()
+ @IsOptional()
+ enabled?: boolean = true;
+
+ /**
+ * The new user's groups' id(s).
+ * You can provide either one groupId or an array of groupIDs.
+ */
+ @IsOptional()
+ groups?: number[] | number
+
+ /**
+ * The user's profile pic (or rather a url pointing to it).
+ */
+ @IsString()
+ @IsUrl()
+ @IsOptional()
+ profilePic?: string;
+
+ /**
+ * Converts this to a User entity.
+ */
+ public async toEntity(): Promise {
+ let newUser: User = new User();
+
+ if (this.email === undefined && this.username === undefined) {
+ throw new UsernameOrEmailNeededError();
+ }
+
+ newUser.email = this.email
+ newUser.username = this.username
+ newUser.firstname = this.firstname
+ newUser.middlename = this.middlename
+ newUser.lastname = this.lastname
+ newUser.uuid = uuid.v4()
+ newUser.phone = this.phone
+ newUser.password = await argon2.hash(this.password + newUser.uuid);
+ newUser.groups = await this.getGroups();
+ newUser.enabled = this.enabled;
+
+ if (!this.profilePic) { newUser.profilePic = `https://dev.lauf-fuer-kaya.de/lfk-logo.png`; }
+ else { newUser.profilePic = this.profilePic; }
+
+ return newUser;
+ }
+
+ /**
+ * Get's all groups for this user by their id's;
+ */
+ public async getGroups() {
+ if (!this.groups) { return null; }
+ let groups = new Array();
+ if (!Array.isArray(this.groups)) {
+ this.groups = [this.groups]
+ }
+ for (let group of this.groups) {
+ let found = await getConnectionManager().get().getRepository(UserGroup).findOne({ id: group });
+ if (!found) { throw new UserGroupNotFoundError(); }
+ groups.push(found);
+ }
+ return groups;
+ }
}
\ No newline at end of file
diff --git a/src/models/actions/CreateUserGroup.ts b/src/models/actions/create/CreateUserGroup.ts
similarity index 86%
rename from src/models/actions/CreateUserGroup.ts
rename to src/models/actions/create/CreateUserGroup.ts
index 50ad15d..aa5a862 100644
--- a/src/models/actions/CreateUserGroup.ts
+++ b/src/models/actions/create/CreateUserGroup.ts
@@ -1,5 +1,5 @@
import { IsOptional, IsString } from 'class-validator';
-import { UserGroup } from '../entities/UserGroup';
+import { UserGroup } from '../../entities/UserGroup';
/**
* This classed is used to create a new UserGroup entity from a json body (post request).
@@ -22,7 +22,7 @@ export class CreateUserGroup {
/**
* Creates a new UserGroup entity from this.
*/
- public async toUserGroup(): Promise {
+ public async toEntity(): Promise {
let newUserGroup: UserGroup = new UserGroup();
newUserGroup.name = this.name;
diff --git a/src/models/actions/UpdateDonor.ts b/src/models/actions/update/UpdateDonor.ts
similarity index 81%
rename from src/models/actions/UpdateDonor.ts
rename to src/models/actions/update/UpdateDonor.ts
index b7139c8..8c77ff1 100644
--- a/src/models/actions/UpdateDonor.ts
+++ b/src/models/actions/update/UpdateDonor.ts
@@ -1,7 +1,7 @@
import { IsBoolean, IsInt, IsOptional } from 'class-validator';
-import { DonorReceiptAddressNeededError } from '../../errors/DonorErrors';
-import { Donor } from '../entities/Donor';
-import { CreateParticipant } from './CreateParticipant';
+import { DonorReceiptAddressNeededError } from '../../../errors/DonorErrors';
+import { Donor } from '../../entities/Donor';
+import { CreateParticipant } from '../create/CreateParticipant';
/**
* This class is used to update a Donor entity (via put request).
@@ -26,7 +26,7 @@ export class UpdateDonor extends CreateParticipant {
/**
* Updates a provided Donor entity based on this.
*/
- public async updateDonor(donor: Donor): Promise {
+ public async update(donor: Donor): Promise {
donor.firstname = this.firstname;
donor.middlename = this.middlename;
donor.lastname = this.lastname;
diff --git a/src/models/actions/UpdatePermission.ts b/src/models/actions/update/UpdatePermission.ts
similarity index 80%
rename from src/models/actions/UpdatePermission.ts
rename to src/models/actions/update/UpdatePermission.ts
index 5241a1b..e591e20 100644
--- a/src/models/actions/UpdatePermission.ts
+++ b/src/models/actions/update/UpdatePermission.ts
@@ -1,11 +1,11 @@
import { IsInt, IsNotEmpty, IsObject } from 'class-validator';
import { getConnectionManager } from 'typeorm';
-import { PermissionNeedsPrincipalError } from '../../errors/PermissionErrors';
-import { PrincipalNotFoundError, PrincipalWrongTypeError } from '../../errors/PrincipalErrors';
-import { Permission } from '../entities/Permission';
-import { Principal } from '../entities/Principal';
-import { PermissionAction } from '../enums/PermissionAction';
-import { PermissionTarget } from '../enums/PermissionTargets';
+import { PermissionNeedsPrincipalError } from '../../../errors/PermissionErrors';
+import { PrincipalNotFoundError, PrincipalWrongTypeError } from '../../../errors/PrincipalErrors';
+import { Permission } from '../../entities/Permission';
+import { Principal } from '../../entities/Principal';
+import { PermissionAction } from '../../enums/PermissionAction';
+import { PermissionTarget } from '../../enums/PermissionTargets';
/**
* This class is used to update a Permission entity (via put request).
@@ -42,7 +42,7 @@ export class UpdatePermission {
/**
* Updates a provided Permission entity based on this.
*/
- public async updatePermission(permission: Permission): Promise {
+ public async update(permission: Permission): Promise {
permission.principal = await this.getPrincipal();
permission.target = this.target;
permission.action = this.action;
diff --git a/src/models/actions/UpdateRunner.ts b/src/models/actions/update/UpdateRunner.ts
similarity index 76%
rename from src/models/actions/UpdateRunner.ts
rename to src/models/actions/update/UpdateRunner.ts
index abc71e0..29a2423 100644
--- a/src/models/actions/UpdateRunner.ts
+++ b/src/models/actions/update/UpdateRunner.ts
@@ -1,11 +1,11 @@
import { IsInt, IsObject } from 'class-validator';
import { getConnectionManager } from 'typeorm';
-import { RunnerGroupNotFoundError } from '../../errors/RunnerGroupErrors';
-import { RunnerOrganisationWrongTypeError } from '../../errors/RunnerOrganisationErrors';
-import { RunnerTeamNeedsParentError } from '../../errors/RunnerTeamErrors';
-import { Runner } from '../entities/Runner';
-import { RunnerGroup } from '../entities/RunnerGroup';
-import { CreateParticipant } from './CreateParticipant';
+import { RunnerGroupNotFoundError } from '../../../errors/RunnerGroupErrors';
+import { RunnerOrganisationWrongTypeError } from '../../../errors/RunnerOrganisationErrors';
+import { RunnerTeamNeedsParentError } from '../../../errors/RunnerTeamErrors';
+import { Runner } from '../../entities/Runner';
+import { RunnerGroup } from '../../entities/RunnerGroup';
+import { CreateParticipant } from '../create/CreateParticipant';
/**
* This class is used to update a Runner entity (via put request).
@@ -29,7 +29,7 @@ export class UpdateRunner extends CreateParticipant {
/**
* Updates a provided Runner entity based on this.
*/
- public async updateRunner(runner: Runner): Promise {
+ public async update(runner: Runner): Promise {
runner.firstname = this.firstname;
runner.middlename = this.middlename;
runner.lastname = this.lastname;
diff --git a/src/models/actions/UpdateRunnerCard.ts b/src/models/actions/update/UpdateRunnerCard.ts
similarity index 87%
rename from src/models/actions/UpdateRunnerCard.ts
rename to src/models/actions/update/UpdateRunnerCard.ts
index 2ee34ab..51f70bf 100644
--- a/src/models/actions/UpdateRunnerCard.ts
+++ b/src/models/actions/update/UpdateRunnerCard.ts
@@ -1,8 +1,8 @@
import { IsBoolean, IsInt, IsOptional, IsPositive } from 'class-validator';
import { getConnection } from 'typeorm';
-import { RunnerNotFoundError } from '../../errors/RunnerErrors';
-import { Runner } from '../entities/Runner';
-import { RunnerCard } from '../entities/RunnerCard';
+import { RunnerNotFoundError } from '../../../errors/RunnerErrors';
+import { Runner } from '../../entities/Runner';
+import { RunnerCard } from '../../entities/RunnerCard';
/**
* This class is used to update a RunnerCard entity (via put request).
diff --git a/src/models/actions/UpdateRunnerOrganisation.ts b/src/models/actions/update/UpdateRunnerOrganisation.ts
similarity index 79%
rename from src/models/actions/UpdateRunnerOrganisation.ts
rename to src/models/actions/update/UpdateRunnerOrganisation.ts
index 9a2cafa..7270923 100644
--- a/src/models/actions/UpdateRunnerOrganisation.ts
+++ b/src/models/actions/update/UpdateRunnerOrganisation.ts
@@ -1,9 +1,9 @@
import { IsInt, IsOptional } from 'class-validator';
import { getConnectionManager } from 'typeorm';
-import { AddressNotFoundError } from '../../errors/AddressErrors';
-import { Address } from '../entities/Address';
-import { RunnerOrganisation } from '../entities/RunnerOrganisation';
-import { CreateRunnerGroup } from './CreateRunnerGroup';
+import { AddressNotFoundError } from '../../../errors/AddressErrors';
+import { Address } from '../../entities/Address';
+import { RunnerOrganisation } from '../../entities/RunnerOrganisation';
+import { CreateRunnerGroup } from '../create/CreateRunnerGroup';
/**
* This class is used to update a RunnerOrganisation entity (via put request).
@@ -41,7 +41,7 @@ export class UpdateRunnerOrganisation extends CreateRunnerGroup {
/**
* Updates a provided RunnerOrganisation entity based on this.
*/
- public async updateRunnerOrganisation(organisation: RunnerOrganisation): Promise {
+ public async update(organisation: RunnerOrganisation): Promise {
organisation.name = this.name;
organisation.contact = await this.getContact();
diff --git a/src/models/actions/UpdateRunnerTeam.ts b/src/models/actions/update/UpdateRunnerTeam.ts
similarity index 80%
rename from src/models/actions/UpdateRunnerTeam.ts
rename to src/models/actions/update/UpdateRunnerTeam.ts
index 756d7df..d7e435d 100644
--- a/src/models/actions/UpdateRunnerTeam.ts
+++ b/src/models/actions/update/UpdateRunnerTeam.ts
@@ -1,10 +1,10 @@
import { IsInt, IsNotEmpty, IsObject } from 'class-validator';
import { getConnectionManager } from 'typeorm';
-import { RunnerOrganisationNotFoundError, RunnerOrganisationWrongTypeError } from '../../errors/RunnerOrganisationErrors';
-import { RunnerTeamNeedsParentError } from '../../errors/RunnerTeamErrors';
-import { RunnerOrganisation } from '../entities/RunnerOrganisation';
-import { RunnerTeam } from '../entities/RunnerTeam';
-import { CreateRunnerGroup } from './CreateRunnerGroup';
+import { RunnerOrganisationNotFoundError, RunnerOrganisationWrongTypeError } from '../../../errors/RunnerOrganisationErrors';
+import { RunnerTeamNeedsParentError } from '../../../errors/RunnerTeamErrors';
+import { RunnerOrganisation } from '../../entities/RunnerOrganisation';
+import { RunnerTeam } from '../../entities/RunnerTeam';
+import { CreateRunnerGroup } from '../create/CreateRunnerGroup';
/**
* This class is used to update a RunnerTeam entity (via put request).
@@ -45,7 +45,7 @@ export class UpdateRunnerTeam extends CreateRunnerGroup {
/**
* Updates a provided RunnerTeam entity based on this.
*/
- public async updateRunnerTeam(team: RunnerTeam): Promise {
+ public async update(team: RunnerTeam): Promise {
team.name = this.name;
team.parentGroup = await this.getParent();
diff --git a/src/models/actions/UpdateScan.ts b/src/models/actions/update/UpdateScan.ts
similarity index 87%
rename from src/models/actions/UpdateScan.ts
rename to src/models/actions/update/UpdateScan.ts
index 00b375e..a0d6633 100644
--- a/src/models/actions/UpdateScan.ts
+++ b/src/models/actions/update/UpdateScan.ts
@@ -1,8 +1,8 @@
import { IsBoolean, IsInt, IsOptional, IsPositive } from 'class-validator';
import { getConnection } from 'typeorm';
-import { RunnerNotFoundError } from '../../errors/RunnerErrors';
-import { Runner } from '../entities/Runner';
-import { Scan } from '../entities/Scan';
+import { RunnerNotFoundError } from '../../../errors/RunnerErrors';
+import { Runner } from '../../entities/Runner';
+import { Scan } from '../../entities/Scan';
/**
* This class is used to update a Scan entity (via put request)
@@ -41,7 +41,7 @@ export abstract class UpdateScan {
* Update a Scan entity based on this.
* @param scan The scan that shall be updated.
*/
- public async updateScan(scan: Scan): Promise {
+ public async update(scan: Scan): Promise {
scan.distance = this.distance;
scan.valid = this.valid;
scan.runner = await this.getRunner();
diff --git a/src/models/actions/UpdateScanStation.ts b/src/models/actions/update/UpdateScanStation.ts
similarity index 86%
rename from src/models/actions/UpdateScanStation.ts
rename to src/models/actions/update/UpdateScanStation.ts
index a8ebc6a..b7557e3 100644
--- a/src/models/actions/UpdateScanStation.ts
+++ b/src/models/actions/update/UpdateScanStation.ts
@@ -1,5 +1,5 @@
import { IsBoolean, IsInt, IsOptional, IsString } from 'class-validator';
-import { ScanStation } from '../entities/ScanStation';
+import { ScanStation } from '../../entities/ScanStation';
/**
* This class is used to update a ScanStation entity (via put request)
@@ -30,7 +30,7 @@ export class UpdateScanStation {
* Update a ScanStation entity based on this.
* @param station The station that shall be updated.
*/
- public async updateStation(station: ScanStation): Promise {
+ public async update(station: ScanStation): Promise {
station.description = this.description;
station.enabled = this.enabled;
diff --git a/src/models/actions/UpdateTrack.ts b/src/models/actions/update/UpdateTrack.ts
similarity index 86%
rename from src/models/actions/UpdateTrack.ts
rename to src/models/actions/update/UpdateTrack.ts
index bc64d54..409a356 100644
--- a/src/models/actions/UpdateTrack.ts
+++ b/src/models/actions/update/UpdateTrack.ts
@@ -1,6 +1,6 @@
import { IsInt, IsNotEmpty, IsOptional, IsPositive, IsString } from 'class-validator';
-import { TrackLapTimeCantBeNegativeError } from '../../errors/TrackErrors';
-import { Track } from '../entities/Track';
+import { TrackLapTimeCantBeNegativeError } from '../../../errors/TrackErrors';
+import { Track } from '../../entities/Track';
/**
* This class is used to update a Track entity (via put request).
@@ -37,7 +37,7 @@ export class UpdateTrack {
* Update a Track entity based on this.
* @param track The track that shall be updated.
*/
- public updateTrack(track: Track): Track {
+ public async update(track: Track): Promise