| 
						 
							
							
							
						 
					 | 
				
			
			 | 
			 | 
			
				@@ -1,228 +1,228 @@
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				import { Request } from "express";
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				import * as jwt from "jsonwebtoken";
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				import { Body, Delete, Get, JsonController, OnUndefined, Param, Post, QueryParam, Req, UseBefore } from 'routing-controllers';
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				import { OpenAPI, ResponseSchema } from 'routing-controllers-openapi';
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				import { getConnectionManager, Repository } from 'typeorm';
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				import { config } from '../config';
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				import { InvalidCredentialsError, JwtNotProvidedError } from '../errors/AuthError';
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				import { MailSendingError } from '../errors/MailErrors';
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				import { RunnerEmailNeededError, RunnerHasDistanceDonationsError, RunnerNotFoundError, RunnerSelfserviceTimeoutError } from '../errors/RunnerErrors';
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				import { RunnerOrganizationNotFoundError } from '../errors/RunnerOrganizationErrors';
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				import { ScanStationNotFoundError } from '../errors/ScanStationErrors';
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				import { JwtCreator } from '../jwtcreator';
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				import { Mailer } from '../mailer';
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				import ScanAuth from '../middlewares/ScanAuth';
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				import { CreateSelfServiceCitizenRunner } from '../models/actions/create/CreateSelfServiceCitizenRunner';
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				import { CreateSelfServiceRunner } from '../models/actions/create/CreateSelfServiceRunner';
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				import { Runner } from '../models/entities/Runner';
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				import { RunnerGroup } from '../models/entities/RunnerGroup';
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				import { RunnerOrganization } from '../models/entities/RunnerOrganization';
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				import { ScanStation } from '../models/entities/ScanStation';
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				import { ResponseEmpty } from '../models/responses/ResponseEmpty';
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				import { ResponseScanStation } from '../models/responses/ResponseScanStation';
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				import { ResponseSelfServiceOrganisation } from '../models/responses/ResponseSelfServiceOrganisation';
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				import { ResponseSelfServiceRunner } from '../models/responses/ResponseSelfServiceRunner';
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				import { ResponseSelfServiceScan } from '../models/responses/ResponseSelfServiceScan';
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				import { DonationController } from './DonationController';
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				import { RunnerCardController } from './RunnerCardController';
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				import { ScanController } from './ScanController';
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				@JsonController()
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				export class RunnerSelfServiceController {
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
					private runnerRepository: Repository<Runner>;
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
					private orgRepository: Repository<RunnerOrganization>;
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
					private stationRepository: Repository<ScanStation>;
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
					/**
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
					 * Gets the repository of this controller's model/entity.
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
					 */
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
					constructor() {
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
						this.runnerRepository = getConnectionManager().get().getRepository(Runner);
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
						this.orgRepository = getConnectionManager().get().getRepository(RunnerOrganization);
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
						this.stationRepository = getConnectionManager().get().getRepository(ScanStation);
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
					}
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
					@Get('/runners/me/:jwt')
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
					@ResponseSchema(ResponseSelfServiceRunner)
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
					@ResponseSchema(RunnerNotFoundError, { statusCode: 404 })
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
					@OnUndefined(RunnerNotFoundError)
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
					@OpenAPI({ description: 'Lists all information about yourself. <br> Please provide your runner jwt(that code we gave you during registration) for auth. <br> If you lost your jwt/personalized link please use the forgot endpoint.' })
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
					async get(@Param('jwt') token: string) {
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
						return (new ResponseSelfServiceRunner(await this.getRunner(token)));
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
					}
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
					@Delete('/runners/me/:jwt')
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
					@ResponseSchema(ResponseSelfServiceRunner)
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
					@ResponseSchema(RunnerNotFoundError, { statusCode: 404 })
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
					@OnUndefined(RunnerNotFoundError)
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
					@OpenAPI({ description: 'Deletes all information about yourself. <br> Please provide your runner jwt(that code we gave you during registration) for auth. <br> If you lost your jwt/personalized link please use the forgot endpoint.' })
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
					async remove(@Param('jwt') token: string, @QueryParam("force") force: boolean) {
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
						const responseRunner = await this.getRunner(token);
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
						let runner = await this.runnerRepository.findOne({ id: responseRunner.id });
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
						if (!runner) { return null; }
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
						if (!runner) {
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
							throw new RunnerNotFoundError();
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
						}
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
						const runnerDonations = (await this.runnerRepository.findOne({ id: runner.id }, { relations: ["distanceDonations"] })).distanceDonations;
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
						if (runnerDonations.length > 0 && !force) {
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
							throw new RunnerHasDistanceDonationsError();
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
						}
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
						const donationController = new DonationController();
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
						for (let donation of runnerDonations) {
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
							await donationController.remove(donation.id, force);
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
						}
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
						const runnerCards = (await this.runnerRepository.findOne({ id: runner.id }, { relations: ["cards"] })).cards;
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
						const cardController = new RunnerCardController;
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
						for (let card of runnerCards) {
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
							await cardController.remove(card.id, force);
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
						}
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
						const runnerScans = (await this.runnerRepository.findOne({ id: runner.id }, { relations: ["scans"] })).scans;
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
						const scanController = new ScanController;
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
						for (let scan of runnerScans) {
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
							await scanController.remove(scan.id, force);
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
						}
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
						await this.runnerRepository.delete(runner);
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
						return new ResponseSelfServiceRunner(responseRunner);
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
					}
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
					@Get('/runners/me/:jwt/scans')
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
					@ResponseSchema(ResponseSelfServiceScan, { isArray: true })
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
					@ResponseSchema(RunnerNotFoundError, { statusCode: 404 })
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
					@OnUndefined(RunnerNotFoundError)
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
					@OpenAPI({ description: 'Lists all your (runner) scans. <br> Please provide your runner jwt(that code we gave you during registration) for auth. <br> If you lost your jwt/personalized link please contact support.' })
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
					async getScans(@Param('jwt') token: string) {
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
						const scans = (await this.getRunner(token)).scans;
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
						let responseScans = new Array<ResponseSelfServiceScan>()
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
						for (let scan of scans) {
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
							responseScans.push(new ResponseSelfServiceScan(scan));
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
						}
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
						return responseScans;
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
					}
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
					@Get('/stations/me')
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
					@UseBefore(ScanAuth)
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
					@ResponseSchema(ResponseScanStation)
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
					@ResponseSchema(ScanStationNotFoundError, { statusCode: 404 })
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
					@OnUndefined(ScanStationNotFoundError)
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
					@OpenAPI({ description: 'Lists basic information about the station whose token got provided. <br> This includes it\'s associated track.', security: [{ "StationApiToken": [] }] })
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
					async getStationMe(@Req() req: Request) {
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
						let scan = await this.stationRepository.findOne({ id: parseInt(req.headers["station_id"].toString()) }, { relations: ['track'] })
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
						if (!scan) { throw new ScanStationNotFoundError(); }
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
						return scan.toResponse();
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
					}
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
					@Post('/runners/forgot')
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
					@ResponseSchema(RunnerNotFoundError, { statusCode: 404 })
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
					@OnUndefined(ResponseEmpty)
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
					@OpenAPI({ description: 'Use this endpoint to reuqest a new selfservice token/link to be sent to your mail address (rate limited to one mail every 24hrs).' })
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
					async requestNewToken(@QueryParam('mail') mail: string) {
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
						if (!mail) {
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
							throw new RunnerNotFoundError();
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
						}
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
						const runner = await this.runnerRepository.findOne({ email: mail });
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
						if (!runner) { throw new RunnerNotFoundError(); }
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
						if (runner.resetRequestedTimestamp > (Math.floor(Date.now() / 1000) - 60 * 60 * 24)) { throw new RunnerSelfserviceTimeoutError(); }
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
						const token = JwtCreator.createSelfService(runner);
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
						try {
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
							await Mailer.sendSelfserviceForgottenMail(runner.email, token, "en")
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
						} catch (error) {
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
							throw new MailSendingError();
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
						}
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
						runner.resetRequestedTimestamp = Math.floor(Date.now() / 1000);
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
						await this.runnerRepository.save(runner);
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
						return { token };
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
					}
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
					@Post('/runners/register')
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
					@ResponseSchema(ResponseSelfServiceRunner)
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
					@ResponseSchema(RunnerEmailNeededError, { statusCode: 406 })
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
					@OpenAPI({ description: 'Create a new selfservice runner in the citizen org. <br> This endpoint shoud be used to allow "everyday citizen" to register themselves. <br> You have to provide a mail address, b/c the future we\'ll implement email verification.' })
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
					async registerRunner(@Body({ validate: true }) createRunner: CreateSelfServiceCitizenRunner) {
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
						let runner = await createRunner.toEntity();
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
						runner = await this.runnerRepository.save(runner);
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
						let response = new ResponseSelfServiceRunner(await this.runnerRepository.findOne(runner, { relations: ['scans', 'group', 'group.parentGroup', 'scans.track', 'cards', 'distanceDonations', 'distanceDonations.donor', 'distanceDonations.runner', 'distanceDonations.runner.scans', 'distanceDonations.runner.scans.track'] }));
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
						response.token = JwtCreator.createSelfService(runner);
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
						try {
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
							await Mailer.sendSelfserviceWelcomeMail(runner.email, response.token, "en")
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
						} catch (error) {
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
							throw new MailSendingError();
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
						}
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
						return response;
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
					}
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
					@Post('/runners/register/:token')
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
					@ResponseSchema(ResponseSelfServiceRunner)
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
					@ResponseSchema(RunnerOrganizationNotFoundError, { statusCode: 404 })
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
					@OpenAPI({ description: 'Create a new selfservice runner in a provided org. <br> The orgs get provided and authorized via api tokens that can be optained via the /organizations endpoint.' })
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
					async registerOrganizationRunner(@Param('token') token: string, @Body({ validate: true }) createRunner: CreateSelfServiceRunner) {
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
						const org = await this.getOrgansisation(token);
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
						let runner = await createRunner.toEntity(org);
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
						runner = await this.runnerRepository.save(runner);
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
						let response = new ResponseSelfServiceRunner(await this.runnerRepository.findOne(runner, { relations: ['scans', 'group', 'group.parentGroup', 'scans.track', 'cards', 'distanceDonations', 'distanceDonations.donor', 'distanceDonations.runner', 'distanceDonations.runner.scans', 'distanceDonations.runner.scans.track'] }));
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
						response.token = JwtCreator.createSelfService(runner);
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
						try {
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
							await Mailer.sendSelfserviceWelcomeMail(runner.email, response.token, "en")
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
						} catch (error) {
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
							throw new MailSendingError();
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
						}
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
						return response;
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
					}
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
					@Get('/organizations/selfservice/:token')
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
					@ResponseSchema(ResponseSelfServiceOrganisation, { isArray: false })
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
					@ResponseSchema(RunnerOrganizationNotFoundError, { statusCode: 404 })
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
					@OpenAPI({ description: 'Get the basic info and teams for a org.' })
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
					async getSelfserviceOrg(@Param('token') token: string) {
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
						const orgid = (await this.getOrgansisation(token)).id;
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
						const org = await this.orgRepository.findOne({ id: orgid }, { relations: ['teams'] })
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
						return new ResponseSelfServiceOrganisation(<RunnerOrganization>org);
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
					}
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
					/**
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
					 * Get's a runner by a provided jwt token.
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
					 * @param token The runner jwt provided by the runner to identitfy themselves.
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
					 */
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
					private async getRunner(token: string): Promise<Runner> {
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
						if (token == "") { throw new JwtNotProvidedError(); }
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
						let jwtPayload = undefined
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
						try {
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
							jwtPayload = <any>jwt.verify(token, config.jwt_secret);
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
						} catch (error) {
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
							throw new InvalidCredentialsError();
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
						}
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
						const runner = await this.runnerRepository.findOne({ id: jwtPayload["id"] }, { relations: ['scans', 'group', 'group.parentGroup', 'scans.track', 'cards', 'distanceDonations', 'distanceDonations.donor', 'distanceDonations.runner', 'distanceDonations.runner.scans', 'distanceDonations.runner.scans.track'] });
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
						if (!runner) { throw new RunnerNotFoundError() }
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
						return runner;
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
					}
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
					/**
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
					 * Get's a runner org by a provided registration api key.
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
					 * @param token The organization's registration api token.
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
					 */
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
					private async getOrgansisation(token: string): Promise<RunnerGroup> {
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
						token = Buffer.from(token, 'base64').toString('utf8');
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
						const organization = await this.orgRepository.findOne({ key: token });
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
						if (!organization) { throw new RunnerOrganizationNotFoundError; }
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
						return organization;
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
					}
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				import { Request } from "express";
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				import * as jwt from "jsonwebtoken";
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				import { Body, Delete, Get, JsonController, OnUndefined, Param, Post, QueryParam, Req, UseBefore } from 'routing-controllers';
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				import { OpenAPI, ResponseSchema } from 'routing-controllers-openapi';
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				import { getConnectionManager, Repository } from 'typeorm';
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				import { config } from '../config';
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				import { InvalidCredentialsError, JwtNotProvidedError } from '../errors/AuthError';
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				import { MailSendingError } from '../errors/MailErrors';
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				import { RunnerEmailNeededError, RunnerHasDistanceDonationsError, RunnerNotFoundError, RunnerSelfserviceTimeoutError } from '../errors/RunnerErrors';
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				import { RunnerOrganizationNotFoundError } from '../errors/RunnerOrganizationErrors';
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				import { ScanStationNotFoundError } from '../errors/ScanStationErrors';
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				import { JwtCreator } from '../jwtcreator';
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				import { Mailer } from '../mailer';
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				import ScanAuth from '../middlewares/ScanAuth';
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				import { CreateSelfServiceCitizenRunner } from '../models/actions/create/CreateSelfServiceCitizenRunner';
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				import { CreateSelfServiceRunner } from '../models/actions/create/CreateSelfServiceRunner';
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				import { Runner } from '../models/entities/Runner';
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				import { RunnerGroup } from '../models/entities/RunnerGroup';
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				import { RunnerOrganization } from '../models/entities/RunnerOrganization';
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				import { ScanStation } from '../models/entities/ScanStation';
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				import { ResponseEmpty } from '../models/responses/ResponseEmpty';
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				import { ResponseScanStation } from '../models/responses/ResponseScanStation';
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				import { ResponseSelfServiceOrganisation } from '../models/responses/ResponseSelfServiceOrganisation';
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				import { ResponseSelfServiceRunner } from '../models/responses/ResponseSelfServiceRunner';
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				import { ResponseSelfServiceScan } from '../models/responses/ResponseSelfServiceScan';
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				import { DonationController } from './DonationController';
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				import { RunnerCardController } from './RunnerCardController';
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				import { ScanController } from './ScanController';
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				@JsonController()
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				export class RunnerSelfServiceController {
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
					private runnerRepository: Repository<Runner>;
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
					private orgRepository: Repository<RunnerOrganization>;
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
					private stationRepository: Repository<ScanStation>;
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
					/**
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
					 * Gets the repository of this controller's model/entity.
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
					 */
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
					constructor() {
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
						this.runnerRepository = getConnectionManager().get().getRepository(Runner);
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
						this.orgRepository = getConnectionManager().get().getRepository(RunnerOrganization);
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
						this.stationRepository = getConnectionManager().get().getRepository(ScanStation);
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
					}
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
					@Get('/runners/me/:jwt')
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
					@ResponseSchema(ResponseSelfServiceRunner)
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
					@ResponseSchema(RunnerNotFoundError, { statusCode: 404 })
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
					@OnUndefined(RunnerNotFoundError)
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
					@OpenAPI({ description: 'Lists all information about yourself. <br> Please provide your runner jwt(that code we gave you during registration) for auth. <br> If you lost your jwt/personalized link please use the forgot endpoint.' })
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
					async get(@Param('jwt') token: string) {
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
						return (new ResponseSelfServiceRunner(await this.getRunner(token)));
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
					}
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
					@Delete('/runners/me/:jwt')
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
					@ResponseSchema(ResponseSelfServiceRunner)
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
					@ResponseSchema(RunnerNotFoundError, { statusCode: 404 })
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
					@OnUndefined(RunnerNotFoundError)
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
					@OpenAPI({ description: 'Deletes all information about yourself. <br> Please provide your runner jwt(that code we gave you during registration) for auth. <br> If you lost your jwt/personalized link please use the forgot endpoint.' })
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
					async remove(@Param('jwt') token: string, @QueryParam("force") force: boolean) {
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
						const responseRunner = await this.getRunner(token);
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
						let runner = await this.runnerRepository.findOne({ id: responseRunner.id });
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
						if (!runner) { return null; }
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
						if (!runner) {
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
							throw new RunnerNotFoundError();
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
						}
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
						const runnerDonations = (await this.runnerRepository.findOne({ id: runner.id }, { relations: ["distanceDonations"] })).distanceDonations;
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
						if (runnerDonations.length > 0 && !force) {
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
							throw new RunnerHasDistanceDonationsError();
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
						}
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
						const donationController = new DonationController();
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
						for (let donation of runnerDonations) {
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
							await donationController.remove(donation.id, force);
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
						}
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
						const runnerCards = (await this.runnerRepository.findOne({ id: runner.id }, { relations: ["cards"] })).cards;
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
						const cardController = new RunnerCardController;
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
						for (let card of runnerCards) {
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
							await cardController.remove(card.id, force);
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
						}
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
						const runnerScans = (await this.runnerRepository.findOne({ id: runner.id }, { relations: ["scans"] })).scans;
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
						const scanController = new ScanController;
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
						for (let scan of runnerScans) {
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
							await scanController.remove(scan.id, force);
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
						}
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
						await this.runnerRepository.delete(runner);
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
						return new ResponseSelfServiceRunner(responseRunner);
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
					}
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
					@Get('/runners/me/:jwt/scans')
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
					@ResponseSchema(ResponseSelfServiceScan, { isArray: true })
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
					@ResponseSchema(RunnerNotFoundError, { statusCode: 404 })
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
					@OnUndefined(RunnerNotFoundError)
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
					@OpenAPI({ description: 'Lists all your (runner) scans. <br> Please provide your runner jwt(that code we gave you during registration) for auth. <br> If you lost your jwt/personalized link please contact support.' })
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
					async getScans(@Param('jwt') token: string) {
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
						const scans = (await this.getRunner(token)).scans;
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
						let responseScans = new Array<ResponseSelfServiceScan>()
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
						for (let scan of scans) {
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
							responseScans.push(new ResponseSelfServiceScan(scan));
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
						}
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
						return responseScans;
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
					}
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
					@Get('/stations/me')
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
					@UseBefore(ScanAuth)
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
					@ResponseSchema(ResponseScanStation)
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
					@ResponseSchema(ScanStationNotFoundError, { statusCode: 404 })
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
					@OnUndefined(ScanStationNotFoundError)
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
					@OpenAPI({ description: 'Lists basic information about the station whose token got provided. <br> This includes it\'s associated track.', security: [{ "StationApiToken": [] }] })
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
					async getStationMe(@Req() req: Request) {
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
						let scan = await this.stationRepository.findOne({ id: parseInt(req.headers["station_id"].toString()) }, { relations: ['track'] })
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
						if (!scan) { throw new ScanStationNotFoundError(); }
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
						return scan.toResponse();
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
					}
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
					@Post('/runners/forgot')
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
					@ResponseSchema(RunnerNotFoundError, { statusCode: 404 })
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
					@OnUndefined(ResponseEmpty)
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
					@OpenAPI({ description: 'Use this endpoint to reuqest a new selfservice token/link to be sent to your mail address (rate limited to one mail every 24hrs).', parameters: [{ in: "query", name: "locale", schema: { type: "string", enum: ["de", "en"] } }] })
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
					async requestNewToken(@QueryParam('mail') mail: string, @QueryParam("locale") locale: string = "en") {
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
						if (!mail) {
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
							throw new RunnerNotFoundError();
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
						}
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
						const runner = await this.runnerRepository.findOne({ email: mail });
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
						if (!runner) { throw new RunnerNotFoundError(); }
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
						if (runner.resetRequestedTimestamp > (Math.floor(Date.now() / 1000) - 60 * 60 * 24)) { throw new RunnerSelfserviceTimeoutError(); }
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
						const token = JwtCreator.createSelfService(runner);
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
						try {
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
							await Mailer.sendSelfserviceForgottenMail(runner.email, token, locale)
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
						} catch (error) {
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
							throw new MailSendingError();
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
						}
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
						runner.resetRequestedTimestamp = Math.floor(Date.now() / 1000);
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
						await this.runnerRepository.save(runner);
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
						return { token };
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
					}
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
					@Post('/runners/register')
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
					@ResponseSchema(ResponseSelfServiceRunner)
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
					@ResponseSchema(RunnerEmailNeededError, { statusCode: 406 })
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
					@OpenAPI({ description: 'Create a new selfservice runner in the citizen org. <br> This endpoint shoud be used to allow "everyday citizen" to register themselves. <br> You have to provide a mail address, b/c the future we\'ll implement email verification.', parameters: [{ in: "query", name: "locale", schema: { type: "string", enum: ["de", "en"] } }] })
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
					async registerRunner(@Body({ validate: true }) createRunner: CreateSelfServiceCitizenRunner, @QueryParam("locale") locale: string = "en") {
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
						let runner = await createRunner.toEntity();
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
						runner = await this.runnerRepository.save(runner);
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
						let response = new ResponseSelfServiceRunner(await this.runnerRepository.findOne(runner, { relations: ['scans', 'group', 'group.parentGroup', 'scans.track', 'cards', 'distanceDonations', 'distanceDonations.donor', 'distanceDonations.runner', 'distanceDonations.runner.scans', 'distanceDonations.runner.scans.track'] }));
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
						response.token = JwtCreator.createSelfService(runner);
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
						try {
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
							await Mailer.sendSelfserviceWelcomeMail(runner.email, response.token, locale)
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
						} catch (error) {
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
							throw new MailSendingError();
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
						}
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
						return response;
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
					}
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
					@Post('/runners/register/:token')
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
					@ResponseSchema(ResponseSelfServiceRunner)
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
					@ResponseSchema(RunnerOrganizationNotFoundError, { statusCode: 404 })
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
					@OpenAPI({ description: 'Create a new selfservice runner in a provided org. <br> The orgs get provided and authorized via api tokens that can be optained via the /organizations endpoint.', parameters: [{ in: "query", name: "locale", schema: { type: "string", enum: ["de", "en"] } }] })
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
					async registerOrganizationRunner(@Param('token') token: string, @Body({ validate: true }) createRunner: CreateSelfServiceRunner, @QueryParam("locale") locale: string = "en") {
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
						const org = await this.getOrgansisation(token);
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
						let runner = await createRunner.toEntity(org);
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
						runner = await this.runnerRepository.save(runner);
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
						let response = new ResponseSelfServiceRunner(await this.runnerRepository.findOne(runner, { relations: ['scans', 'group', 'group.parentGroup', 'scans.track', 'cards', 'distanceDonations', 'distanceDonations.donor', 'distanceDonations.runner', 'distanceDonations.runner.scans', 'distanceDonations.runner.scans.track'] }));
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
						response.token = JwtCreator.createSelfService(runner);
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
						try {
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
							await Mailer.sendSelfserviceWelcomeMail(runner.email, response.token, locale)
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
						} catch (error) {
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
							throw new MailSendingError();
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
						}
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
						return response;
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
					}
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
					@Get('/organizations/selfservice/:token')
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
					@ResponseSchema(ResponseSelfServiceOrganisation, { isArray: false })
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
					@ResponseSchema(RunnerOrganizationNotFoundError, { statusCode: 404 })
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
					@OpenAPI({ description: 'Get the basic info and teams for a org.' })
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
					async getSelfserviceOrg(@Param('token') token: string) {
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
						const orgid = (await this.getOrgansisation(token)).id;
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
						const org = await this.orgRepository.findOne({ id: orgid }, { relations: ['teams'] })
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
						return new ResponseSelfServiceOrganisation(<RunnerOrganization>org);
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
					}
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
					/**
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
					 * Get's a runner by a provided jwt token.
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
					 * @param token The runner jwt provided by the runner to identitfy themselves.
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
					 */
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
					private async getRunner(token: string): Promise<Runner> {
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
						if (token == "") { throw new JwtNotProvidedError(); }
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
						let jwtPayload = undefined
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
						try {
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
							jwtPayload = <any>jwt.verify(token, config.jwt_secret);
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
						} catch (error) {
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
							throw new InvalidCredentialsError();
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
						}
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
						const runner = await this.runnerRepository.findOne({ id: jwtPayload["id"] }, { relations: ['scans', 'group', 'group.parentGroup', 'scans.track', 'cards', 'distanceDonations', 'distanceDonations.donor', 'distanceDonations.runner', 'distanceDonations.runner.scans', 'distanceDonations.runner.scans.track'] });
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
						if (!runner) { throw new RunnerNotFoundError() }
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
						return runner;
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
					}
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
					/**
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
					 * Get's a runner org by a provided registration api key.
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
					 * @param token The organization's registration api token.
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
					 */
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
					private async getOrgansisation(token: string): Promise<RunnerGroup> {
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
						token = Buffer.from(token, 'base64').toString('utf8');
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
						const organization = await this.orgRepository.findOne({ key: token });
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
						if (!organization) { throw new RunnerOrganizationNotFoundError; }
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
						return organization;
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
					}
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				}
 |