First part of the action comment refactoring
ref #39 Why did i volunteer for this? It's just a glorified sleeping aid 😴
This commit is contained in:
		| @@ -1,5 +1,5 @@ | ||||
| import * as argon2 from "argon2"; | ||||
| import { IsEmail, IsOptional, IsString } from 'class-validator'; | ||||
| import { IsEmail, IsNotEmpty, IsOptional, IsString } from 'class-validator'; | ||||
| import { getConnectionManager } from 'typeorm'; | ||||
| import { InvalidCredentialsError, PasswordNeededError, UserNotFoundError } from '../../errors/AuthError'; | ||||
| import { UsernameOrEmailNeededError } from '../../errors/UserErrors'; | ||||
| @@ -7,17 +7,41 @@ import { JwtCreator } from '../../jwtcreator'; | ||||
| import { User } from '../entities/User'; | ||||
| import { Auth } from '../responses/ResponseAuth'; | ||||
|  | ||||
| /** | ||||
|  * This class is used to create auth credentials. | ||||
|  * To be a little bit more exact: Is takes in a username/email + password and creates a new access and refresh token for the user. | ||||
|  * It of course checks for user existance, password validity and so on. | ||||
|  */ | ||||
| export class CreateAuth { | ||||
|     /** | ||||
|      * The username of the user that want's to login. | ||||
|      * Either username or email have to be provided. | ||||
|      */ | ||||
|     @IsOptional() | ||||
|     @IsString() | ||||
|     username?: string; | ||||
|     @IsString() | ||||
|     password: string; | ||||
|  | ||||
|     /** | ||||
|      * The email address of the user that want's to login. | ||||
|      * Either username or email have to be provided. | ||||
|      */ | ||||
|     @IsOptional() | ||||
|     @IsEmail() | ||||
|     @IsString() | ||||
|     email?: string; | ||||
|  | ||||
|     /** | ||||
|      * The user's password. | ||||
|      * Will be checked against an argon2 hash. | ||||
|      */ | ||||
|     @IsNotEmpty() | ||||
|     @IsString() | ||||
|     password: string; | ||||
|  | ||||
|  | ||||
|     /** | ||||
|      * Creates a new auth object based on this. | ||||
|      */ | ||||
|     public async toAuth(): Promise<Auth> { | ||||
|         let newAuth: Auth = new Auth(); | ||||
|  | ||||
|   | ||||
| @@ -6,11 +6,23 @@ import { IllegalJWTError, JwtNotProvidedError, RefreshTokenCountInvalidError, Us | ||||
| import { User } from '../entities/User'; | ||||
| import { Logout } from '../responses/ResponseLogout'; | ||||
|  | ||||
| /** | ||||
|  * This class handels a user logging out of the system. | ||||
|  * Of course it check's the user's provided credential (token) before logging him out. | ||||
|  */ | ||||
| export class HandleLogout { | ||||
|     /** | ||||
|      * A stringyfied jwt access token. | ||||
|      * Will get checked for validity. | ||||
|      */ | ||||
|     @IsString() | ||||
|     @IsOptional() | ||||
|     token?: string; | ||||
|  | ||||
|     /** | ||||
|      * Logs the user out. | ||||
|      * This gets achived by increasing the user's refresh token count, thereby invalidateing all currently existing jwts for that user. | ||||
|      */ | ||||
|     public async logout(): Promise<Logout> { | ||||
|         let logout: Logout = new Logout(); | ||||
|         if (!this.token || this.token === undefined) { | ||||
|   | ||||
| @@ -7,6 +7,10 @@ import { RunnerOrganisation } from '../entities/RunnerOrganisation'; | ||||
| import { RunnerTeam } from '../entities/RunnerTeam'; | ||||
| import { CreateRunner } from './CreateRunner'; | ||||
|  | ||||
| /** | ||||
|  * Special class used to import runners from csv files - or json arrays created from csv to be exact. | ||||
|  * Why you ask? Because the past has shown us that a non excel/csv based workflow is too much for most schools. | ||||
|  */ | ||||
| export class ImportRunner { | ||||
|  | ||||
|     /** | ||||
| @@ -18,7 +22,6 @@ export class ImportRunner { | ||||
|  | ||||
|     /** | ||||
|      * The new runner's middle name. | ||||
|      * Optional. | ||||
|      */ | ||||
|     @IsString() | ||||
|     @IsOptional() | ||||
| @@ -32,18 +35,26 @@ export class ImportRunner { | ||||
|     lastname: string; | ||||
|  | ||||
|     /** | ||||
|      * The new runner's class (if not provided otherwise). | ||||
|      * The new runner's team's name (if not provided otherwise). | ||||
|      * The team will automaticly get generated if it doesn't exist in this org yet. | ||||
|      */ | ||||
|     @IsString() | ||||
|     @IsOptional() | ||||
|     team?: string; | ||||
|  | ||||
|     /** | ||||
|      * Just an alias for team, because this is usually only used for importing data from schools. | ||||
|      */ | ||||
|     @IsOptional() | ||||
|     @IsString() | ||||
|     public set class(value: string) { | ||||
|         this.team = value; | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * Creates a CreateRunner object based on this. | ||||
|      * @param groupID Either the id of the new runner's group or the id of the org that the new runner's team is a part of. | ||||
|      */ | ||||
|     public async toCreateRunner(groupID: number): Promise<CreateRunner> { | ||||
|         let newRunner: CreateRunner = new CreateRunner(); | ||||
|  | ||||
| @@ -55,25 +66,28 @@ export class ImportRunner { | ||||
|         return newRunner; | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * Get's the new runners group. | ||||
|      * @param groupID Either the id of the new runner's group or the id of the org that the new runner's team is a part of. | ||||
|      */ | ||||
|     public async getGroup(groupID: number): Promise<RunnerGroup> { | ||||
|         if (this.team === undefined && groupID === undefined) { | ||||
|             throw new RunnerGroupNeededError(); | ||||
|         } | ||||
|  | ||||
|         let team = await getConnectionManager().get().getRepository(RunnerTeam).findOne({ id: groupID }); | ||||
|         if (team) { return team; } | ||||
|  | ||||
|         let org = await getConnectionManager().get().getRepository(RunnerOrganisation).findOne({ id: groupID }); | ||||
|         if (!org) { | ||||
|         let group = await getConnectionManager().get().getRepository(RunnerGroup).findOne({ id: groupID }); | ||||
|         if (group instanceof RunnerTeam) { return group; } | ||||
|         if (!(group instanceof RunnerOrganisation) || !group) { | ||||
|             throw new RunnerOrganisationNotFoundError(); | ||||
|         } | ||||
|         if (this.team === undefined) { return org; } | ||||
|  | ||||
|         team = await getConnectionManager().get().getRepository(RunnerTeam).findOne({ name: this.team, parentGroup: org }); | ||||
|         if (this.team === undefined) { return group; } | ||||
|  | ||||
|         let team = await getConnectionManager().get().getRepository(RunnerTeam).findOne({ name: this.team, parentGroup: org }); | ||||
|         if (!team) { | ||||
|             let newRunnerTeam: RunnerTeam = new RunnerTeam(); | ||||
|             newRunnerTeam.name = this.team; | ||||
|             newRunnerTeam.parentGroup = org; | ||||
|             newRunnerTeam.parentGroup = group; | ||||
|             team = await getConnectionManager().get().getRepository(RunnerTeam).save(newRunnerTeam); | ||||
|         } | ||||
|  | ||||
|   | ||||
| @@ -7,11 +7,23 @@ import { JwtCreator } from "../../jwtcreator"; | ||||
| import { User } from '../entities/User'; | ||||
| import { Auth } from '../responses/ResponseAuth'; | ||||
|  | ||||
| /** | ||||
|  * This class is used to create refreshed auth credentials. | ||||
|  * To be a little bit more exact: Is takes in a refresh token and creates a new access and refresh token for it's user. | ||||
|  * It of course checks for user existance, jwt validity and so on. | ||||
|  */ | ||||
| export class RefreshAuth { | ||||
|     /** | ||||
|      * A stringyfied jwt refresh token. | ||||
|      * Will get checked for validity. | ||||
|      */ | ||||
|     @IsString() | ||||
|     @IsOptional() | ||||
|     token?: string; | ||||
|  | ||||
|     /** | ||||
|      * Creates a new auth object based on this. | ||||
|      */ | ||||
|     public async toAuth(): Promise<Auth> { | ||||
|         let newAuth: Auth = new Auth(); | ||||
|         if (!this.token || this.token === undefined) { | ||||
|   | ||||
| @@ -7,16 +7,21 @@ 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). | ||||
|  */ | ||||
| export class UpdatePermission { | ||||
|  | ||||
|     /** | ||||
|      * The updated runner's id. | ||||
|      * The updated permission's id. | ||||
|      * This shouldn't have changed but it is here in case anyone ever wants to enable id changes (whyever they would want to). | ||||
|      */ | ||||
|     @IsInt() | ||||
|     id: number; | ||||
|  | ||||
|     /** | ||||
|      * The permissions's principal's id. | ||||
|      * The updated permissions's principal. | ||||
|      * Just has to contain the principal's id -everything else won't be checked or changed. | ||||
|      */ | ||||
|     @IsObject() | ||||
|     @IsNotEmpty() | ||||
| @@ -35,7 +40,7 @@ export class UpdatePermission { | ||||
|     action: PermissionAction; | ||||
|  | ||||
|     /** | ||||
|      * Converts a Permission object based on this. | ||||
|      * Updates a provided Permission entity based on this. | ||||
|      */ | ||||
|     public async updatePermission(permission: Permission): Promise<Permission> { | ||||
|         permission.principal = await this.getPrincipal(); | ||||
| @@ -46,7 +51,7 @@ export class UpdatePermission { | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * Manages all the different ways a group can be provided. | ||||
|      * Loads the updated permission's principal based on it's id. | ||||
|      */ | ||||
|     public async getPrincipal(): Promise<Principal> { | ||||
|         if (this.principal === undefined || this.principal === null) { | ||||
|   | ||||
| @@ -7,22 +7,27 @@ import { Runner } from '../entities/Runner'; | ||||
| import { RunnerGroup } from '../entities/RunnerGroup'; | ||||
| import { CreateParticipant } from './CreateParticipant'; | ||||
|  | ||||
| /** | ||||
|  * This class is used to update a Runner entity (via put request). | ||||
|  */ | ||||
| export class UpdateRunner extends CreateParticipant { | ||||
|  | ||||
|     /** | ||||
|      * The updated runner's id. | ||||
|      * This shouldn't have changed but it is here in case anyone ever wants to enable id changes (whyever they would want to). | ||||
|      */ | ||||
|     @IsInt() | ||||
|     id: number; | ||||
|  | ||||
|     /** | ||||
|      * The updated runner's new team/org. | ||||
|      * Just has to contain the group's id -everything else won't be checked or changed. | ||||
|      */ | ||||
|     @IsObject() | ||||
|     group: RunnerGroup; | ||||
|  | ||||
|     /** | ||||
|      * Creates a Runner entity from this. | ||||
|      * Updates a provided Runner entity based on this. | ||||
|      */ | ||||
|     public async updateRunner(runner: Runner): Promise<Runner> { | ||||
|         runner.firstname = this.firstname; | ||||
| @@ -37,7 +42,7 @@ export class UpdateRunner extends CreateParticipant { | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * Manages all the different ways a group can be provided. | ||||
|      * Loads the updated runner's group based on it's id. | ||||
|      */ | ||||
|     public async getGroup(): Promise<RunnerGroup> { | ||||
|         if (this.group === undefined || this.group === null) { | ||||
|   | ||||
| @@ -5,17 +5,21 @@ import { Address } from '../entities/Address'; | ||||
| import { RunnerOrganisation } from '../entities/RunnerOrganisation'; | ||||
| import { CreateRunnerGroup } from './CreateRunnerGroup'; | ||||
|  | ||||
| /** | ||||
|  * This class is used to update a RunnerOrganisation entity (via put request). | ||||
|  */ | ||||
| export class UpdateRunnerOrganisation extends CreateRunnerGroup { | ||||
|  | ||||
|     /** | ||||
|      * The updated orgs's id. | ||||
|      * This shouldn't have changed but it is here in case anyone ever wants to enable id changes (whyever they would want to). | ||||
|      */ | ||||
|     @IsInt() | ||||
|     id: number; | ||||
|  | ||||
|     /** | ||||
|      * The updated organisation's address. | ||||
|      * Must be of type number (address id). | ||||
|      * Just has to contain the address's id - everything else won't be checked or changed. | ||||
|      * Optional. | ||||
|      */ | ||||
|     @IsInt() | ||||
| @@ -23,7 +27,7 @@ export class UpdateRunnerOrganisation extends CreateRunnerGroup { | ||||
|     address?: Address; | ||||
|  | ||||
|     /** | ||||
|      * Get's this org's address from this.address. | ||||
|      * Loads the organisation's address based on it's id. | ||||
|      */ | ||||
|     public async getAddress(): Promise<Address> { | ||||
|         if (this.address === undefined || this.address === null) { | ||||
| @@ -35,7 +39,7 @@ export class UpdateRunnerOrganisation extends CreateRunnerGroup { | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * Creates a RunnerTeam entity from this. | ||||
|      * Updates a provided RunnerOrganisation entity based on this. | ||||
|      */ | ||||
|     public async updateRunnerOrganisation(organisation: RunnerOrganisation): Promise<RunnerOrganisation> { | ||||
|  | ||||
|   | ||||
| @@ -6,21 +6,29 @@ import { RunnerOrganisation } from '../entities/RunnerOrganisation'; | ||||
| import { RunnerTeam } from '../entities/RunnerTeam'; | ||||
| import { CreateRunnerGroup } from './CreateRunnerGroup'; | ||||
|  | ||||
| /** | ||||
|  * This class is used to update a RunnerTeam entity (via put request). | ||||
|  */ | ||||
| export class UpdateRunnerTeam extends CreateRunnerGroup { | ||||
|  | ||||
|     /** | ||||
|      * The updated team's id. | ||||
|      * This shouldn't have changed but it is here in case anyone ever wants to enable id changes (whyever they would want to). | ||||
|      */ | ||||
|     @IsInt() | ||||
|     id: number; | ||||
|  | ||||
|     /** | ||||
|      * The team's parent group (organisation). | ||||
|      * The updated team's parentGroup. | ||||
|      * Just has to contain the organisation's id - everything else won't be checked or changed. | ||||
|      */ | ||||
|     @IsObject() | ||||
|     @IsNotEmpty() | ||||
|     parentGroup: RunnerOrganisation; | ||||
|  | ||||
|     /** | ||||
|      * Loads the updated teams's parentGroup based on it's id. | ||||
|      */ | ||||
|     public async getParent(): Promise<RunnerOrganisation> { | ||||
|         if (this.parentGroup === undefined || this.parentGroup === null) { | ||||
|             throw new RunnerTeamNeedsParentError(); | ||||
| @@ -35,7 +43,7 @@ export class UpdateRunnerTeam extends CreateRunnerGroup { | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * Creates a RunnerTeam entity from this. | ||||
|      * Updates a provided RunnerTeam entity based on this. | ||||
|      */ | ||||
|     public async updateRunnerTeam(team: RunnerTeam): Promise<RunnerTeam> { | ||||
|  | ||||
|   | ||||
| @@ -7,10 +7,14 @@ import { UserGroupNotFoundError } from '../../errors/UserGroupErrors'; | ||||
| import { User } from '../entities/User'; | ||||
| import { UserGroup } from '../entities/UserGroup'; | ||||
|  | ||||
| /** | ||||
|  * This class is used to update a User entity (via put request). | ||||
|  */ | ||||
| export class UpdateUser { | ||||
|  | ||||
|     /** | ||||
|      * The updated users's id. | ||||
|      * The updated user's id. | ||||
|      * This shouldn't have changed but it is here in case anyone ever wants to enable id changes (whyever they would want to). | ||||
|      */ | ||||
|     @IsInt() | ||||
|     id: number; | ||||
| @@ -23,7 +27,6 @@ export class UpdateUser { | ||||
|  | ||||
|     /** | ||||
|      * The updated user's middle name. | ||||
|      * Optinal. | ||||
|      */ | ||||
|     @IsString() | ||||
|     @IsOptional() | ||||
| @@ -54,14 +57,16 @@ export class UpdateUser { | ||||
|  | ||||
|     /** | ||||
|      * The updated user's phone number. | ||||
|      * Optional | ||||
|      * This will be validated against the configured country phone numer syntax (default: international). | ||||
|      */ | ||||
|     @IsPhoneNumber(config.phone_validation_countrycode) | ||||
|     @IsOptional() | ||||
|     phone?: string; | ||||
|  | ||||
|     /** | ||||
|      * The new updated's password. Only provide if you want it updated. | ||||
|      * The new updated's password.  | ||||
|      * Only provide it if you want it updated. | ||||
|      * Changeing the password will invalidate all of the user's jwts. | ||||
|      * This will of course not be saved in plaintext :) | ||||
|      */ | ||||
|     @IsString() | ||||
| @@ -75,15 +80,14 @@ export class UpdateUser { | ||||
|     enabled: boolean = true; | ||||
|  | ||||
|     /** | ||||
|      * The new user's groups' id(s). | ||||
|      * You can provide either one groupId or an array of groupIDs. | ||||
|      * Optional. | ||||
|      * The updated user's groups. | ||||
|      * This just has to contain the group's id - everything else won't be changed. | ||||
|      */ | ||||
|     @IsOptional() | ||||
|     groups?: UserGroup[] | ||||
|  | ||||
|     /** | ||||
|      * Creates a User entity from this. | ||||
|      * Updates a provided User entity based on this. | ||||
|      */ | ||||
|     public async updateUser(user: User): Promise<User> { | ||||
|         user.email = this.email; | ||||
| @@ -107,6 +111,9 @@ export class UpdateUser { | ||||
|         return user; | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * Loads the updated user's groups based on their ids. | ||||
|      */ | ||||
|     public async getGroups() { | ||||
|         if (!this.groups) { return null; } | ||||
|         let groups = new Array<UserGroup>(); | ||||
|   | ||||
		Reference in New Issue
	
	Block a user