diff --git a/src/controllers/AuthController.ts b/src/controllers/AuthController.ts
index 98a9f85..cddb677 100644
--- a/src/controllers/AuthController.ts
+++ b/src/controllers/AuthController.ts
@@ -1,4 +1,4 @@
-import { Body, CookieParam, JsonController, Param, Post, Res } from 'routing-controllers';
+import { Body, CookieParam, JsonController, Param, Post, Req, Res } from 'routing-controllers';
import { OpenAPI, ResponseSchema } from 'routing-controllers-openapi';
import { IllegalJWTError, InvalidCredentialsError, JwtNotProvidedError, PasswordNeededError, RefreshTokenCountInvalidError, UsernameOrEmailNeededError } from '../errors/AuthError';
import { UserNotFoundError } from '../errors/UserErrors';
@@ -22,7 +22,7 @@ export class AuthController {
@ResponseSchema(UsernameOrEmailNeededError)
@ResponseSchema(PasswordNeededError)
@ResponseSchema(InvalidCredentialsError)
- @OpenAPI({ description: 'Create a new access token object' })
+ @OpenAPI({ description: 'Login with your username/email and password.
You will receive: \n * access token (use it as a bearer token) \n * refresh token (will also be sent as a cookie)' })
async login(@Body({ validate: true }) createAuth: CreateAuth, @Res() response: any) {
let auth;
try {
@@ -42,7 +42,7 @@ export class AuthController {
@ResponseSchema(UsernameOrEmailNeededError)
@ResponseSchema(PasswordNeededError)
@ResponseSchema(InvalidCredentialsError)
- @OpenAPI({ description: 'Create a new access token object' })
+ @OpenAPI({ description: 'Logout using your refresh token.
This instantly invalidates all your access and refresh tokens.', security: [{ "RefreshTokenCookie": [] }] })
async logout(@Body({ validate: true }) handleLogout: HandleLogout, @CookieParam("lfk_backend__refresh_token") refresh_token: string, @Res() response: any) {
if (refresh_token && refresh_token.length != 0 && handleLogout.token == undefined) {
handleLogout.token = refresh_token;
@@ -65,11 +65,12 @@ export class AuthController {
@ResponseSchema(IllegalJWTError)
@ResponseSchema(UserNotFoundError)
@ResponseSchema(RefreshTokenCountInvalidError)
- @OpenAPI({ description: 'refresh a access token' })
- async refresh(@Body({ validate: true }) refreshAuth: RefreshAuth, @CookieParam("lfk_backend__refresh_token") refresh_token: string, @Res() response: any) {
+ @OpenAPI({ description: 'Refresh your access and refresh tokens using a valid refresh token.
You will receive: \n * access token (use it as a bearer token) \n * refresh token (will also be sent as a cookie)', security: [{ "RefreshTokenCookie": [] }] })
+ async refresh(@Body({ validate: true }) refreshAuth: RefreshAuth, @CookieParam("lfk_backend__refresh_token") refresh_token: string, @Res() response: any, @Req() req: any) {
if (refresh_token && refresh_token.length != 0 && refreshAuth.token == undefined) {
refreshAuth.token = refresh_token;
}
+ console.log(req.headers)
let auth;
try {
auth = await refreshAuth.toAuth();
@@ -85,7 +86,7 @@ export class AuthController {
@ResponseSchema(Auth)
@ResponseSchema(UserNotFoundError)
@ResponseSchema(UsernameOrEmailNeededError)
- @OpenAPI({ description: "Request a password reset token" })
+ @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}." })
async getResetToken(@Body({ validate: true }) passwordReset: CreateResetToken) {
//This really shouldn't just get returned, but sent via mail or sth like that. But for dev only this is fine.
return { "resetToken": await passwordReset.toResetToken() };
@@ -95,7 +96,7 @@ export class AuthController {
@ResponseSchema(Auth)
@ResponseSchema(UserNotFoundError)
@ResponseSchema(UsernameOrEmailNeededError)
- @OpenAPI({ description: "Reset a user's password" })
+ @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." })
async resetPassword(@Param("token") token: string, @Body({ validate: true }) passwordReset: ResetPassword) {
passwordReset.resetToken = token;
return await passwordReset.resetPassword();
diff --git a/src/controllers/ImportController.ts b/src/controllers/ImportController.ts
index bccdfb3..3390e46 100644
--- a/src/controllers/ImportController.ts
+++ b/src/controllers/ImportController.ts
@@ -10,7 +10,7 @@ import { RunnerController } from './RunnerController';
@Controller()
@Authorized(["RUNNER:IMPORT", "TEAM:IMPORT"])
-@OpenAPI({ security: [{ "AuthToken": [] }] })
+@OpenAPI({ security: [{ "AuthToken": [] }, { "RefreshTokenCookie": [] }] })
export class ImportController {
private runnerController: RunnerController;
@@ -26,7 +26,7 @@ export class ImportController {
@ResponseSchema(ResponseRunner, { isArray: true, statusCode: 200 })
@ResponseSchema(RunnerGroupNotFoundError, { statusCode: 404 })
@ResponseSchema(RunnerGroupNeededError, { statusCode: 406 })
- @OpenAPI({ description: "Create new runners from json and insert them (or their teams) into the provided group" })
+ @OpenAPI({ description: "Create new runners from json and insert them into the provided group.
If teams/classes are provided alongside the runner's name they'll automaticly be created under the provided org and the runners will be inserted into the teams instead." })
async postJSON(@Body({ validate: true, type: ImportRunner }) importRunners: ImportRunner[], @QueryParam("group") groupID: number) {
if (!groupID) { throw new RunnerGroupNeededError(); }
let responseRunners: ResponseRunner[] = new Array();
@@ -41,7 +41,7 @@ export class ImportController {
@ResponseSchema(ResponseRunner, { isArray: true, statusCode: 200 })
@ResponseSchema(RunnerGroupNotFoundError, { statusCode: 404 })
@ResponseSchema(RunnerGroupNeededError, { statusCode: 406 })
- @OpenAPI({ description: "Create new runners from json and insert them (or their teams) into the provided org" })
+ @OpenAPI({ description: "Create new runners from json and insert them into the provided org.
If teams/classes are provided alongside the runner's name they'll automaticly be created under the provided org and the runners will be inserted into the teams instead." })
async postOrgsJSON(@Body({ validate: true, type: ImportRunner }) importRunners: ImportRunner[], @Param('id') id: number) {
return await this.postJSON(importRunners, id)
}
@@ -62,7 +62,7 @@ export class ImportController {
@ResponseSchema(ResponseRunner, { isArray: true, statusCode: 200 })
@ResponseSchema(RunnerGroupNotFoundError, { statusCode: 404 })
@ResponseSchema(RunnerGroupNeededError, { statusCode: 406 })
- @OpenAPI({ description: "Create new runners from csv and insert them (or their teams) into the provided group" })
+ @OpenAPI({ description: "Create new runners from csv and insert them into the provided group.
If teams/classes are provided alongside the runner's name they'll automaticly be created under the provided org and the runners will be inserted into the teams instead." })
async postCSV(@Req() request: any, @QueryParam("group") groupID: number) {
let csvParse = await csv({ delimiter: [",", ";"], trim: true }).fromString(request.rawBody.toString());
let importRunners: ImportRunner[] = new Array();
@@ -84,7 +84,7 @@ export class ImportController {
@ResponseSchema(ResponseRunner, { isArray: true, statusCode: 200 })
@ResponseSchema(RunnerGroupNotFoundError, { statusCode: 404 })
@ResponseSchema(RunnerGroupNeededError, { statusCode: 406 })
- @OpenAPI({ description: "Create new runners from csv and insert them (or their teams) into the provided org" })
+ @OpenAPI({ description: "Create new runners from csv and insert them into the provided org.
If teams/classes are provided alongside the runner's name they'll automaticly be created under the provided org and the runners will be inserted into the teams instead." })
async postOrgsCSV(@Req() request: any, @Param("id") id: number) {
return await this.postCSV(request, id);
}
diff --git a/src/controllers/PermissionController.ts b/src/controllers/PermissionController.ts
index 208fe6f..15ad301 100644
--- a/src/controllers/PermissionController.ts
+++ b/src/controllers/PermissionController.ts
@@ -12,7 +12,7 @@ import { ResponsePrincipal } from '../models/responses/ResponsePrincipal';
@JsonController('/permissions')
-@OpenAPI({ security: [{ "AuthToken": [] }] })
+@OpenAPI({ security: [{ "AuthToken": [] }, { "RefreshTokenCookie": [] }] })
export class PermissionController {
private permissionRepository: Repository;
@@ -26,7 +26,7 @@ export class PermissionController {
@Get()
@Authorized("PERMISSION:GET")
@ResponseSchema(ResponsePermission, { isArray: true })
- @OpenAPI({ description: 'Lists all permissions.' })
+ @OpenAPI({ description: 'Lists all permissions for all users and groups.' })
async getAll() {
let responsePermissions: ResponsePermission[] = new Array();
const permissions = await this.permissionRepository.find({ relations: ['principal'] });
@@ -42,7 +42,7 @@ export class PermissionController {
@ResponseSchema(ResponsePermission)
@ResponseSchema(PermissionNotFoundError, { statusCode: 404 })
@OnUndefined(PermissionNotFoundError)
- @OpenAPI({ description: 'Returns a permissions of a specified id (if it exists)' })
+ @OpenAPI({ description: 'Lists all information about the permission whose id got provided.' })
async getOne(@Param('id') id: number) {
let permission = await this.permissionRepository.findOne({ id: id }, { relations: ['principal'] });
if (!permission) { throw new PermissionNotFoundError(); }
@@ -54,7 +54,7 @@ export class PermissionController {
@Authorized("PERMISSION:CREATE")
@ResponseSchema(ResponsePermission)
@ResponseSchema(PrincipalNotFoundError, { statusCode: 404 })
- @OpenAPI({ description: 'Create a new runnerTeam object (id will be generated automagicly).' })
+ @OpenAPI({ description: 'Create a new permission for a existing principal(user/group).
If a permission with this target, action and prinicpal already exists that permission will be returned instead of creating a new one.' })
async post(@Body({ validate: true }) createPermission: CreatePermission) {
let permission;
try {
@@ -79,7 +79,7 @@ export class PermissionController {
@ResponseSchema(PrincipalNotFoundError, { statusCode: 404 })
@ResponseSchema(PermissionIdsNotMatchingError, { statusCode: 406 })
@ResponseSchema(PermissionNeedsPrincipalError, { statusCode: 406 })
- @OpenAPI({ description: "Update a permission object (id can't be changed)." })
+ @OpenAPI({ description: "Update a permission object.
If updateing the permission object would result in duplicate permission (same target, action and principal) this permission will get deleted and the existing permission will be returned.
Please remember that ids can't be changed." })
async put(@Param('id') id: number, @Body({ validate: true }) permission: UpdatePermission) {
let oldPermission = await this.permissionRepository.findOne({ id: id }, { relations: ['principal'] });
@@ -106,7 +106,7 @@ export class PermissionController {
@ResponseSchema(ResponsePermission)
@ResponseSchema(ResponseEmpty, { statusCode: 204 })
@OnUndefined(204)
- @OpenAPI({ description: 'Delete a specified permission (if it exists).' })
+ @OpenAPI({ description: 'Deletes the permission whose id you provide.
If no permission with this id exists it will just return 204(no content).' })
async remove(@Param("id") id: number, @QueryParam("force") force: boolean) {
let permission = await this.permissionRepository.findOne({ id: id }, { relations: ['principal'] });
if (!permission) { return null; }
diff --git a/src/controllers/RunnerController.ts b/src/controllers/RunnerController.ts
index 12569d0..9eeb916 100644
--- a/src/controllers/RunnerController.ts
+++ b/src/controllers/RunnerController.ts
@@ -10,7 +10,7 @@ import { ResponseEmpty } from '../models/responses/ResponseEmpty';
import { ResponseRunner } from '../models/responses/ResponseRunner';
@JsonController('/runners')
-@OpenAPI({ security: [{ "AuthToken": [] }] })
+@OpenAPI({ security: [{ "AuthToken": [] }, { "RefreshTokenCookie": [] }] })
export class RunnerController {
private runnerRepository: Repository;
@@ -24,7 +24,7 @@ export class RunnerController {
@Get()
@Authorized("RUNNER:GET")
@ResponseSchema(ResponseRunner, { isArray: true })
- @OpenAPI({ description: 'Lists all runners.' })
+ @OpenAPI({ description: 'Lists all runners from all teams/orgs.
This includes the runner\'s group and distance ran.' })
async getAll() {
let responseRunners: ResponseRunner[] = new Array();
const runners = await this.runnerRepository.find({ relations: ['scans', 'group'] });
@@ -39,7 +39,7 @@ export class RunnerController {
@ResponseSchema(ResponseRunner)
@ResponseSchema(RunnerNotFoundError, { statusCode: 404 })
@OnUndefined(RunnerNotFoundError)
- @OpenAPI({ description: 'Returns a runner of a specified id (if it exists)' })
+ @OpenAPI({ description: 'Lists all information about the runner whose id got provided.' })
async getOne(@Param('id') id: number) {
let runner = await this.runnerRepository.findOne({ id: id }, { relations: ['scans', 'group'] })
if (!runner) { throw new RunnerNotFoundError(); }
@@ -51,7 +51,7 @@ export class RunnerController {
@ResponseSchema(ResponseRunner)
@ResponseSchema(RunnerGroupNeededError)
@ResponseSchema(RunnerGroupNotFoundError)
- @OpenAPI({ description: 'Create a new runner object (id will be generated automagicly).' })
+ @OpenAPI({ description: 'Create a new runner.
Please remeber to provide the runner\'s group\'s id.' })
async post(@Body({ validate: true }) createRunner: CreateRunner) {
let runner;
try {
@@ -69,7 +69,7 @@ export class RunnerController {
@ResponseSchema(ResponseRunner)
@ResponseSchema(RunnerNotFoundError, { statusCode: 404 })
@ResponseSchema(RunnerIdsNotMatchingError, { statusCode: 406 })
- @OpenAPI({ description: "Update a runner object (id can't be changed)." })
+ @OpenAPI({ description: "Update the runner whose id you provided.
Please remember that ids can't be changed." })
async put(@Param('id') id: number, @Body({ validate: true }) runner: UpdateRunner) {
let oldRunner = await this.runnerRepository.findOne({ id: id }, { relations: ['group'] });
@@ -90,7 +90,7 @@ export class RunnerController {
@ResponseSchema(ResponseRunner)
@ResponseSchema(ResponseEmpty, { statusCode: 204 })
@OnUndefined(204)
- @OpenAPI({ description: 'Delete a specified runner (if it exists).' })
+ @OpenAPI({ description: 'Delete the runner whose id you provided.
If no runner with this id exists it will just return 204(no content).' })
async remove(@Param("id") id: number, @QueryParam("force") force: boolean) {
let runner = await this.runnerRepository.findOne({ id: id });
if (!runner) { return null; }
diff --git a/src/controllers/RunnerOrganisationController.ts b/src/controllers/RunnerOrganisationController.ts
index fb86cf2..e10d415 100644
--- a/src/controllers/RunnerOrganisationController.ts
+++ b/src/controllers/RunnerOrganisationController.ts
@@ -12,7 +12,7 @@ import { RunnerTeamController } from './RunnerTeamController';
@JsonController('/organisations')
-@OpenAPI({ security: [{ "AuthToken": [] }] })
+@OpenAPI({ security: [{ "AuthToken": [] }, { "RefreshTokenCookie": [] }] })
export class RunnerOrganisationController {
private runnerOrganisationRepository: Repository;
@@ -26,7 +26,7 @@ export class RunnerOrganisationController {
@Get()
@Authorized("ORGANISATION:GET")
@ResponseSchema(ResponseRunnerOrganisation, { isArray: true })
- @OpenAPI({ description: 'Lists all runnerOrganisations.' })
+ @OpenAPI({ description: 'Lists all organisations.
This includes their address, contact and teams (if existing/associated).' })
async getAll() {
let responseTeams: ResponseRunnerOrganisation[] = new Array();
const runners = await this.runnerOrganisationRepository.find({ relations: ['address', 'contact', 'teams'] });
@@ -41,7 +41,7 @@ export class RunnerOrganisationController {
@ResponseSchema(ResponseRunnerOrganisation)
@ResponseSchema(RunnerOrganisationNotFoundError, { statusCode: 404 })
@OnUndefined(RunnerOrganisationNotFoundError)
- @OpenAPI({ description: 'Returns a runnerOrganisation of a specified id (if it exists)' })
+ @OpenAPI({ description: 'Lists all information about the organisation whose id got provided.' })
async getOne(@Param('id') id: number) {
let runnerOrg = await this.runnerOrganisationRepository.findOne({ id: id }, { relations: ['address', 'contact', 'teams'] });
if (!runnerOrg) { throw new RunnerOrganisationNotFoundError(); }
@@ -51,7 +51,7 @@ export class RunnerOrganisationController {
@Post()
@Authorized("ORGANISATION:CREATE")
@ResponseSchema(ResponseRunnerOrganisation)
- @OpenAPI({ description: 'Create a new runnerOrganisation object (id will be generated automagicly).' })
+ @OpenAPI({ description: 'Create a new organsisation.' })
async post(@Body({ validate: true }) createRunnerOrganisation: CreateRunnerOrganisation) {
let runnerOrganisation;
try {
@@ -70,7 +70,7 @@ export class RunnerOrganisationController {
@ResponseSchema(ResponseRunnerOrganisation)
@ResponseSchema(RunnerOrganisationNotFoundError, { statusCode: 404 })
@ResponseSchema(RunnerOrganisationIdsNotMatchingError, { statusCode: 406 })
- @OpenAPI({ description: "Update a runnerOrganisation object (id can't be changed)." })
+ @OpenAPI({ description: "Update the organisation whose id you provided.
Please remember that ids can't be changed." })
async put(@Param('id') id: number, @Body({ validate: true }) updateOrganisation: UpdateRunnerOrganisation) {
let oldRunnerOrganisation = await this.runnerOrganisationRepository.findOne({ id: id });
@@ -94,7 +94,7 @@ export class RunnerOrganisationController {
@ResponseSchema(RunnerOrganisationHasTeamsError, { statusCode: 406 })
@ResponseSchema(RunnerOrganisationHasRunnersError, { statusCode: 406 })
@OnUndefined(204)
- @OpenAPI({ description: 'Delete a specified runnerOrganisation (if it exists).' })
+ @OpenAPI({ description: 'Delete the organsisation whose id you provided.
If the organisation still has runners and/or teams associated this will fail.
To delete the organisation with all associated runners and teams set the force QueryParam to true (cascading deletion might take a while).
If no organisation with this id exists it will just return 204(no content).' })
async remove(@Param("id") id: number, @QueryParam("force") force: boolean) {
let organisation = await this.runnerOrganisationRepository.findOne({ id: id });
if (!organisation) { return null; }
diff --git a/src/controllers/RunnerTeamController.ts b/src/controllers/RunnerTeamController.ts
index 5040e8c..bc99d79 100644
--- a/src/controllers/RunnerTeamController.ts
+++ b/src/controllers/RunnerTeamController.ts
@@ -11,7 +11,7 @@ import { RunnerController } from './RunnerController';
@JsonController('/teams')
-@OpenAPI({ security: [{ "AuthToken": [] }] })
+@OpenAPI({ security: [{ "AuthToken": [] }, { "RefreshTokenCookie": [] }] })
export class RunnerTeamController {
private runnerTeamRepository: Repository;
@@ -25,7 +25,7 @@ export class RunnerTeamController {
@Get()
@Authorized("TEAM:GET")
@ResponseSchema(ResponseRunnerTeam, { isArray: true })
- @OpenAPI({ description: 'Lists all runnerTeams.' })
+ @OpenAPI({ description: 'Lists all teams.
This includes their parent organisation and contact (if existing/associated).' })
async getAll() {
let responseTeams: ResponseRunnerTeam[] = new Array();
const runners = await this.runnerTeamRepository.find({ relations: ['parentGroup', 'contact'] });
@@ -40,7 +40,7 @@ export class RunnerTeamController {
@ResponseSchema(ResponseRunnerTeam)
@ResponseSchema(RunnerTeamNotFoundError, { statusCode: 404 })
@OnUndefined(RunnerTeamNotFoundError)
- @OpenAPI({ description: 'Returns a runnerTeam of a specified id (if it exists)' })
+ @OpenAPI({ description: 'Lists all information about the team whose id got provided.' })
async getOne(@Param('id') id: number) {
let runnerTeam = await this.runnerTeamRepository.findOne({ id: id }, { relations: ['parentGroup', 'contact'] });
if (!runnerTeam) { throw new RunnerTeamNotFoundError(); }
@@ -50,7 +50,7 @@ export class RunnerTeamController {
@Post()
@Authorized("TEAM:CREATE")
@ResponseSchema(ResponseRunnerTeam)
- @OpenAPI({ description: 'Create a new runnerTeam object (id will be generated automagicly).' })
+ @OpenAPI({ description: 'Create a new organsisation.
Please remember to provide it\'s parent group\'s id.' })
async post(@Body({ validate: true }) createRunnerTeam: CreateRunnerTeam) {
let runnerTeam;
try {
@@ -70,7 +70,7 @@ export class RunnerTeamController {
@ResponseSchema(ResponseRunnerTeam)
@ResponseSchema(RunnerTeamNotFoundError, { statusCode: 404 })
@ResponseSchema(RunnerTeamIdsNotMatchingError, { statusCode: 406 })
- @OpenAPI({ description: "Update a runnerTeam object (id can't be changed)." })
+ @OpenAPI({ description: "Update the team whose id you provided.
Please remember that ids can't be changed." })
async put(@Param('id') id: number, @Body({ validate: true }) runnerTeam: UpdateRunnerTeam) {
let oldRunnerTeam = await this.runnerTeamRepository.findOne({ id: id }, { relations: ['parentGroup', 'contact'] });
@@ -93,7 +93,7 @@ export class RunnerTeamController {
@ResponseSchema(ResponseEmpty, { statusCode: 204 })
@ResponseSchema(RunnerTeamHasRunnersError, { statusCode: 406 })
@OnUndefined(204)
- @OpenAPI({ description: 'Delete a specified runnerTeam (if it exists).' })
+ @OpenAPI({ description: 'Delete the team whose id you provided.
If the team still has runners associated this will fail.
To delete the team with all associated runners set the force QueryParam to true (cascading deletion might take a while).
If no team with this id exists it will just return 204(no content).' })
async remove(@Param("id") id: number, @QueryParam("force") force: boolean) {
let team = await this.runnerTeamRepository.findOne({ id: id });
if (!team) { return null; }
diff --git a/src/controllers/StatusController.ts b/src/controllers/StatusController.ts
index 9f83c50..b867429 100644
--- a/src/controllers/StatusController.ts
+++ b/src/controllers/StatusController.ts
@@ -6,7 +6,7 @@ import { getConnection } from 'typeorm';
export class StatusController {
@Get()
- @OpenAPI({ description: "Lists all tracks." })
+ @OpenAPI({ description: "A very basic status/health endpoint that just checks if the database connection is available.
The available information depth will be expanded later." })
get() {
let connection;
try {
diff --git a/src/controllers/TrackController.ts b/src/controllers/TrackController.ts
index d5746ff..1f74193 100644
--- a/src/controllers/TrackController.ts
+++ b/src/controllers/TrackController.ts
@@ -9,7 +9,7 @@ import { ResponseEmpty } from '../models/responses/ResponseEmpty';
import { ResponseTrack } from '../models/responses/ResponseTrack';
@JsonController('/tracks')
-@OpenAPI({ security: [{ "AuthToken": [] }] })
+@OpenAPI({ security: [{ "AuthToken": [] }, { "RefreshTokenCookie": [] }] })
export class TrackController {
private trackRepository: Repository