Compare commits

..

8 Commits

Author SHA1 Message Date
2e271bcd52 fix: add .created_via to ResponseParticipant constructor 2025-03-28 18:24:53 +01:00
ebde8c6ffd ci: move to gitea workflows 2025-03-28 18:07:10 +01:00
a3639dd89b feat: created_via for tracking how runners got into the system (#212)
close #211

squash merge please:)

Reviewed-on: #212
2025-03-28 17:05:10 +00:00
0a43f1bb5b build: docker "AS" casing 2025-03-28 17:41:20 +01:00
8c6fdb2239 refactor(RunnerController.remove): only load necessary relations 2025-03-28 12:01:15 +01:00
c0d5af5d7a refactor(RunnerTeamController.remove): only load necessary relations 2025-03-28 12:00:55 +01:00
4008a5ee72 chore(release): 1.2.1
Some checks failed
ci/woodpecker/push/build Pipeline failed
2024-12-11 22:23:58 +01:00
07bf28b144 refactor: allow selfservice link every 30s
Some checks failed
ci/woodpecker/push/build Pipeline failed
2024-12-11 22:22:54 +01:00
13 changed files with 58 additions and 58 deletions

View File

@@ -0,0 +1,33 @@
name: Build release images
on:
push:
tags:
- "*.*.*"
jobs:
build-container:
runs-on: ubuntu-latest
steps:
- name: Checkout
uses: actions/checkout@v4
- name: Set up Node.js
uses: actions/setup-node@v4
with:
node-version: 19
- run: npm i -g pnpm@8 && pnpm i
- run: pnpm licenses:export
- name: Login to registry
uses: docker/login-action@v3
with:
registry: registry.odit.services
username: ${{ vars.REGISTRY_USERNAME }}
password: ${{ secrets.REGISTRY_PASSWORD }}
- name: Set up Docker Buildx
uses: docker/setup-buildx-action@v3
- name: Build and push
uses: docker/build-push-action@v6
with:
push: true
tags: |
${{ vars.REGISTRY }}/lfk/backend:${{ github.ref_name }}
platforms: linux/amd64,linux/arm64

View File

@@ -1,33 +0,0 @@
steps:
- name: build latest
image: woodpeckerci/plugin-docker-buildx
settings:
repo: registry.odit.services/lfk/backend
tags:
- latest
registry: registry.odit.services
platforms: linux/amd64,linux/arm64
cache_from: registry.odit.services/lfk/backend:dev
username:
from_secret: odit-registry-builder-username
password:
from_secret: odit-registry-builder-password
when:
branch: main
- name: build dev
image: woodpeckerci/plugin-docker-buildx
settings:
repo: registry.odit.services/lfk/backend
tags:
- dev
registry: registry.odit.services
platforms: linux/amd64,linux/arm64
cache_from: registry.odit.services/lfk/backend:dev
username:
from_secret: odit-registry-builder-username
password:
from_secret: odit-registry-builder-password
when:
branch: dev
when:
event: push

View File

@@ -1,17 +0,0 @@
steps:
- name: build tag
image: woodpeckerci/plugin-docker-buildx
settings:
repo: registry.odit.services/lfk/backend
tags:
- "${CI_COMMIT_TAG}"
registry: registry.odit.services
platforms: linux/amd64,linux/arm64
cache_from: registry.odit.services/lfk/backend:dev
username:
from_secret: odit-registry-builder-username
password:
from_secret: odit-registry-builder-password
when:
event:
- tag

View File

@@ -1,5 +1,5 @@
# Typescript Build # Typescript Build
FROM registry.odit.services/hub/library/node:21.1.0-alpine3.18 as build FROM registry.odit.services/hub/library/node:21.1.0-alpine3.18 AS build
ARG NPM_REGISTRY_URL=https://registry.npmjs.org ARG NPM_REGISTRY_URL=https://registry.npmjs.org
WORKDIR /app WORKDIR /app
@@ -14,7 +14,7 @@ RUN pnpm run build \
&& pnpm i --production --prefer-offline && pnpm i --production --prefer-offline
# final image # final image
FROM registry.odit.services/hub/library/node:21.1.0-alpine3.18 as final FROM registry.odit.services/hub/library/node:21.1.0-alpine3.18 AS final
WORKDIR /app WORKDIR /app
COPY --from=build /app/package.json /app/package.json COPY --from=build /app/package.json /app/package.json
COPY --from=build /app/ormconfig.js /app/ormconfig.js COPY --from=build /app/ormconfig.js /app/ormconfig.js

View File

@@ -1,6 +1,6 @@
{ {
"name": "@odit/lfk-backend", "name": "@odit/lfk-backend",
"version": "1.2.0", "version": "1.2.1",
"main": "src/app.ts", "main": "src/app.ts",
"repository": "https://git.odit.services/lfk/backend", "repository": "https://git.odit.services/lfk/backend",
"engines": { "engines": {

View File

@@ -132,7 +132,7 @@ export class RunnerController {
async remove(@Param("id") id: number, @QueryParam("force") force: boolean) { async remove(@Param("id") id: number, @QueryParam("force") force: boolean) {
let runner = await this.runnerRepository.findOne({ id: id }); let runner = await this.runnerRepository.findOne({ id: id });
if (!runner) { return null; } if (!runner) { return null; }
const responseRunner = await this.runnerRepository.findOne(runner, { relations: ['scans', 'group', 'group.parentGroup', 'scans.track', 'cards'] }); const responseRunner = await this.runnerRepository.findOne(runner);
if (!runner) { if (!runner) {
throw new RunnerNotFoundError(); throw new RunnerNotFoundError();

View File

@@ -127,7 +127,7 @@ export class RunnerSelfServiceController {
const runner = await this.runnerRepository.findOne({ email: mail }); const runner = await this.runnerRepository.findOne({ email: mail });
if (!runner) { throw new RunnerNotFoundError(); } if (!runner) { throw new RunnerNotFoundError(); }
if (runner.resetRequestedTimestamp > (Math.floor(Date.now() / 1000) - 60 * 15)) { throw new RunnerSelfserviceTimeoutError(); } if (runner.resetRequestedTimestamp > (Math.floor(Date.now() / 1000) - 30)) { throw new RunnerSelfserviceTimeoutError(); }
const token = JwtCreator.createSelfService(runner); const token = JwtCreator.createSelfService(runner);
try { try {

View File

@@ -119,7 +119,7 @@ export class RunnerTeamController {
async remove(@Param("id") id: number, @QueryParam("force") force: boolean) { async remove(@Param("id") id: number, @QueryParam("force") force: boolean) {
let team = await this.runnerTeamRepository.findOne({ id: id }); let team = await this.runnerTeamRepository.findOne({ id: id });
if (!team) { return null; } if (!team) { return null; }
let runnerTeam = await this.runnerTeamRepository.findOne(team, { relations: ['parentGroup', 'contact', 'runners'] }); let runnerTeam = await this.runnerTeamRepository.findOne(team, { relations: ['runners'] });
if (!force) { if (!force) {
if (runnerTeam.runners.length != 0) { if (runnerTeam.runners.length != 0) {

View File

@@ -47,14 +47,14 @@ export class RunnerEmailNeededError extends NotAcceptableError {
} }
/** /**
* Error to throw when a runner already requested a new selfservice link in the last 24hrs. * Error to throw when a runner already requested a new selfservice link in the last 30s.
*/ */
export class RunnerSelfserviceTimeoutError extends NotAcceptableError { export class RunnerSelfserviceTimeoutError extends NotAcceptableError {
@IsString() @IsString()
name = "RunnerSelfserviceTimeoutError" name = "RunnerSelfserviceTimeoutError"
@IsString() @IsString()
message = "You can only reqest a new token every 24hrs." message = "You can only reqest a new token every 30s."
} }
/** /**

View File

@@ -26,6 +26,7 @@ export class CreateSelfServiceCitizenRunner extends CreateParticipant {
public async toEntity(): Promise<Runner> { public async toEntity(): Promise<Runner> {
let newRunner: Runner = new Runner(); let newRunner: Runner = new Runner();
newRunner.created_via = "selfservice";
newRunner.firstname = this.firstname; newRunner.firstname = this.firstname;
newRunner.middlename = this.middlename; newRunner.middlename = this.middlename;
newRunner.lastname = this.lastname; newRunner.lastname = this.lastname;

View File

@@ -28,6 +28,7 @@ export class CreateSelfServiceRunner extends CreateParticipant {
public async toEntity(group: RunnerGroup): Promise<Runner> { public async toEntity(group: RunnerGroup): Promise<Runner> {
let newRunner: Runner = new Runner(); let newRunner: Runner = new Runner();
newRunner.created_via = "selfservice";
newRunner.firstname = this.firstname; newRunner.firstname = this.firstname;
newRunner.middlename = this.middlename; newRunner.middlename = this.middlename;
newRunner.lastname = this.lastname; newRunner.lastname = this.lastname;

View File

@@ -75,6 +75,14 @@ export abstract class Participant {
@IsEmail() @IsEmail()
email?: string; email?: string;
/**
* how the participant got into the system
*/
@Column({ nullable: true, default: "backend" })
@IsOptional()
@IsEmail()
created_via?: string;
/** /**
* Turns this entity into it's response class. * Turns this entity into it's response class.
*/ */

View File

@@ -50,6 +50,12 @@ export abstract class ResponseParticipant implements IResponse {
@IsString() @IsString()
email?: string; email?: string;
/**
* how the participant got into the system
*/
@IsString()
created_via?: string;
/** /**
* The participant's address. * The participant's address.
*/ */
@@ -64,6 +70,7 @@ export abstract class ResponseParticipant implements IResponse {
public constructor(participant: Participant) { public constructor(participant: Participant) {
this.id = participant.id; this.id = participant.id;
this.firstname = participant.firstname; this.firstname = participant.firstname;
this.created_via = participant.created_via;
this.middlename = participant.middlename; this.middlename = participant.middlename;
this.lastname = participant.lastname; this.lastname = participant.lastname;
this.phone = participant.phone; this.phone = participant.phone;