Merge pull request 'Runner selfservice info endpoint feature/111-runner_selfservic_info' (#115) from feature/111-runner_selfservic_info into dev
All checks were successful
continuous-integration/drone/push Build is passing
All checks were successful
continuous-integration/drone/push Build is passing
Reviewed-on: #115
This commit is contained in:
commit
1717df113e
49
src/controllers/RunnerSelfServiceController.ts
Normal file
49
src/controllers/RunnerSelfServiceController.ts
Normal file
@ -0,0 +1,49 @@
|
||||
import * as jwt from "jsonwebtoken";
|
||||
import { Get, JsonController, OnUndefined, Param } from 'routing-controllers';
|
||||
import { OpenAPI, ResponseSchema } from 'routing-controllers-openapi';
|
||||
import { getConnectionManager, Repository } from 'typeorm';
|
||||
import { config } from '../config';
|
||||
import { InvalidCredentialsError } from '../errors/AuthError';
|
||||
import { RunnerNotFoundError } from '../errors/RunnerErrors';
|
||||
import { Runner } from '../models/entities/Runner';
|
||||
import { ResponseSelfServiceRunner } from '../models/responses/ResponseSelfServiceRunner';
|
||||
|
||||
|
||||
@JsonController('/runners')
|
||||
export class RunnerSelfServiceController {
|
||||
private runnerRepository: Repository<Runner>;
|
||||
|
||||
/**
|
||||
* Gets the repository of this controller's model/entity.
|
||||
*/
|
||||
constructor() {
|
||||
this.runnerRepository = getConnectionManager().get().getRepository(Runner);
|
||||
}
|
||||
|
||||
@Get('/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 contact support.' })
|
||||
async get(@Param('jwt') token: string) {
|
||||
return (new ResponseSelfServiceRunner(await this.getRunner(token)));
|
||||
}
|
||||
|
||||
/**
|
||||
* 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> {
|
||||
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', 'scans.track', 'cards', 'distanceDonations', 'distanceDonations.donor', 'distanceDonations.runner', 'distanceDonations.runner.scans', 'distanceDonations.runner.scans.track'] });
|
||||
if (!runner) { throw new RunnerNotFoundError() }
|
||||
return runner;
|
||||
}
|
||||
|
||||
}
|
@ -65,7 +65,7 @@ export class Runner extends Participant {
|
||||
*/
|
||||
@IsInt()
|
||||
public get distanceDonationAmount(): number {
|
||||
return this.distanceDonations.reduce((sum, current) => sum + current.amountPerDistance, 0) * this.distance;
|
||||
return this.distanceDonations.reduce((sum, current) => sum + current.amount, 0);
|
||||
}
|
||||
|
||||
/**
|
||||
|
36
src/models/responses/ResponseSelfServiceDonation.ts
Normal file
36
src/models/responses/ResponseSelfServiceDonation.ts
Normal file
@ -0,0 +1,36 @@
|
||||
import { IsInt, IsNotEmpty, IsPositive } from 'class-validator';
|
||||
import { DistanceDonation } from '../entities/DistanceDonation';
|
||||
|
||||
/**
|
||||
* Defines the runner selfservice donation response.
|
||||
* Why? B/C runner's are not allowed to view all information available to admin users.
|
||||
*/
|
||||
export class ResponseSelfServiceDonation {
|
||||
/**
|
||||
* The donation's donor.
|
||||
*/
|
||||
@IsNotEmpty()
|
||||
donor: string;
|
||||
|
||||
/**
|
||||
* The donation's amount in the smalles unit of your currency (default: euro cent).
|
||||
*/
|
||||
@IsInt()
|
||||
amount: number;
|
||||
|
||||
/**
|
||||
* The donation's amount donated per distance.
|
||||
* The amount the donor set to be donated per kilometer that the runner ran.
|
||||
*/
|
||||
@IsInt()
|
||||
@IsPositive()
|
||||
amountPerDistance: number;
|
||||
|
||||
public constructor(donation: DistanceDonation) {
|
||||
if (!donation.donor.middlename) { this.donor = donation.donor.firstname + " " + donation.donor.lastname; }
|
||||
else { this.donor = donation.donor.firstname + " " + donation.donor.middlename + " " + donation.donor.lastname; }
|
||||
|
||||
this.amountPerDistance = donation.amountPerDistance;
|
||||
this.amount = donation.amount;
|
||||
}
|
||||
}
|
75
src/models/responses/ResponseSelfServiceRunner.ts
Normal file
75
src/models/responses/ResponseSelfServiceRunner.ts
Normal file
@ -0,0 +1,75 @@
|
||||
import { IsInt, IsString } from "class-validator";
|
||||
import { DistanceDonation } from '../entities/DistanceDonation';
|
||||
import { Runner } from '../entities/Runner';
|
||||
import { RunnerGroup } from '../entities/RunnerGroup';
|
||||
import { RunnerTeam } from '../entities/RunnerTeam';
|
||||
import { ResponseParticipant } from './ResponseParticipant';
|
||||
import { ResponseSelfServiceDonation } from './ResponseSelfServiceDonation';
|
||||
|
||||
/**
|
||||
* Defines the runner selfservice response.
|
||||
* Why? B/C runner's are not allowed to view all information available to admin users.
|
||||
*/
|
||||
export class ResponseSelfServiceRunner extends ResponseParticipant {
|
||||
|
||||
/**
|
||||
* The runner's currently ran distance in meters.
|
||||
*/
|
||||
@IsInt()
|
||||
distance: number;
|
||||
|
||||
/**
|
||||
* The runner's currently collected donations.
|
||||
*/
|
||||
@IsInt()
|
||||
donationAmount: number;
|
||||
|
||||
/**
|
||||
* The runner's group as a string (mix of org and team).
|
||||
*/
|
||||
@IsString()
|
||||
group: string;
|
||||
|
||||
/**
|
||||
* The runner's associated donations.
|
||||
*/
|
||||
@IsString()
|
||||
donations: ResponseSelfServiceDonation[]
|
||||
|
||||
/**
|
||||
* Creates a ResponseRunner object from a runner.
|
||||
* @param runner The user the response shall be build for.
|
||||
*/
|
||||
public constructor(runner: Runner) {
|
||||
super(runner);
|
||||
this.distance = runner.distance;
|
||||
this.donationAmount = runner.distanceDonationAmount;
|
||||
this.group = this.getTeamString(runner.group);
|
||||
this.donations = this.getDonations(runner.distanceDonations);
|
||||
}
|
||||
|
||||
/**
|
||||
* Parses a runner's group into a string.
|
||||
* If the runner's group is a team: `org name/team name`
|
||||
* If the runner's group is an org: `org name`
|
||||
* @param group The group that shall get parsed to a string.
|
||||
*/
|
||||
private getTeamString(group: RunnerGroup): string {
|
||||
if (group instanceof RunnerTeam) {
|
||||
return group.parentGroup.name + "/" + group.name;
|
||||
}
|
||||
return group.name;
|
||||
}
|
||||
|
||||
/**
|
||||
* Converts all of the runner's donations to ResponseSelfServiceDonations.
|
||||
* @param donations The donations that shall be converted to ResponseSelfServiceDonations.
|
||||
*/
|
||||
private getDonations(donations: DistanceDonation[]): ResponseSelfServiceDonation[] {
|
||||
let responseDonations = new Array<ResponseSelfServiceDonation>();
|
||||
for (let donation of donations) {
|
||||
responseDonations.push(new ResponseSelfServiceDonation(donation));
|
||||
}
|
||||
return responseDonations;
|
||||
}
|
||||
}
|
Loading…
x
Reference in New Issue
Block a user