import legacy frontend & fix dependency issues

This commit is contained in:
tw-blue
2025-12-07 12:51:57 +01:00
parent 91ac875a32
commit cd6cfec7f3
52 changed files with 3963 additions and 267 deletions
@@ -13,10 +13,10 @@ import {
SuccessResponse,
} from "@tsoa/runtime";
import express from "express";
import { Claim } from "../dtos/claim.js";
import type { Member, MemberCreateArgs } from "../dtos/member.js";
import { inject } from "../infrastructure/di/index.js";
import { ErrorStates } from "../infrastructure/errorStates.js";
import { Claim } from "../models/claim.js";
import type { Member, MemberCreateArgs } from "../models/member.js";
import { KC_SECURITY_NAME } from "../services/keycloak/user/index.js";
import { MembersService } from "../services/membersService.js";
@@ -9,9 +9,9 @@ import {
Security,
SuccessResponse,
} from "@tsoa/runtime";
import { Claim } from "../dtos/claim.js";
import { type User } from "../dtos/user.js";
import { inject } from "../infrastructure/di/index.js";
import { Claim } from "../models/claim.js";
import { type User } from "../models/user.js";
import { KC_SECURITY_NAME } from "../services/keycloak/user/index.js";
import { UserService } from "../services/userService.js";
@@ -1,20 +1,20 @@
import { type MemberModel as DbMember } from "../generated/prisma/models.js";
export interface Member {
id?: string | null;
vorname?: string | null;
nachname?: string | null;
geburtsdatum?: Date | null;
geburtsort?: string | null;
geschlecht?: string | null;
passnummer?: string | null;
uvertrag?: boolean | null;
verein?: boolean | null;
graduierung?: string | null;
letztePruefung?: Date | null;
kontakt?: string | null;
kuendigungzum?: Date | null;
loeschenam?: string | null;
id: string | null;
vorname: string | null;
nachname: string | null;
geburtsdatum: Date | null;
geburtsort: string | null;
geschlecht: string | null;
passnummer: string | null;
uvertrag: boolean | null;
verein: boolean | null;
graduierung: string | null;
letztePruefung: Date | null;
kontakt: string | null;
kuendigungzum: Date | null;
loeschenam: Date | null;
}
export type MemberCreateArgs = Omit<Member, "id" | "loeschenam">;
@@ -34,5 +34,6 @@ export function mapDbMemberToMember(dbMember: DbMember): Member {
passnummer: dbMember.passnummer,
uvertrag: dbMember.uvertrag,
verein: dbMember.verein,
loeschenam: new Date(), //TODO
};
}
+2 -1
View File
@@ -14,7 +14,6 @@ const app = express();
app.use(sessionHandler);
app.use(keycloak.middleware());
// console.log("not using", keycloak.middleware);
app.use(express.urlencoded({ extended: true }));
app.use(express.json());
@@ -25,6 +24,8 @@ app.use(
"https://tcc-1-ev-intern.web.app",
"http://localhost:4200",
"https://localhost:4200",
"http://localhost:3000",
"http://localhost:8080",
],
//TODO reevaluate
}),
+24 -7
View File
@@ -8,8 +8,11 @@ function promisifyMiddleware(
response?: Response,
): Promise<any> {
return new Promise((resolve, reject) => {
middleware(request, response || ({} as any), (result: any) => {
result instanceof Error ? reject(result) : resolve(result);
middleware(request, response || ({} as any), (next_result: any) => {
console.dir(next_result);
next_result instanceof Error
? reject(next_result)
: resolve(next_result);
});
});
}
@@ -20,10 +23,15 @@ async function doKeycloakAuth(
response?: Response,
): Promise<any> {
if (roles && roles.length > 0) {
return await promisifyMiddleware(
request,
keycloak.enforcer(roles?.map(role => `realm:${role}`)),
const grant = await keycloak.getGrant(request, response ?? ({} as any));
const allowed = roles.every(role =>
grant.access_token?.hasRealmRole(role),
);
if (allowed) {
return Promise.resolve();
} else {
return Promise.reject(httpError(403, "Forbidden"));
}
} else {
return await promisifyMiddleware(request, keycloak.protect(), response);
}
@@ -35,12 +43,21 @@ export async function expressAuthentication(
roles?: string[],
response?: Response,
): Promise<any> {
if (request.method === "OPTIONS") {
return Promise.resolve();
}
switch (securityName) {
case KC_SECURITY_NAME:
return doKeycloakAuth(request, roles, response);
return await doKeycloakAuth(request, roles, response);
case undefined:
return Promise.resolve();
default:
return Promise.reject("Unknown security name");
return Promise.reject(httpError(400, "Unknown security name"));
}
}
function httpError(status: number, message: string) {
const err: any = new Error(message);
err.status = status;
return err;
}
+6 -11
View File
@@ -4,10 +4,10 @@ import { PrismaClient } from "../../generated/prisma/client.js";
import { Injectable } from "../../infrastructure/di/injectable-decorator.js";
type ExtendedClient = ReturnType<typeof createExtendedClient>;
type TransactionClient = Omit<
ExtendedClient,
"$connect" | "$disconnect" | "$on" | "$transaction" | "$extends"
>;
// type TransactionClient = Omit<
// ExtendedClient,
// "$connect" | "$disconnect" | "$on" | "$transaction" | "$extends"
// >;
export type SafeClient = Omit<
ExtendedClient,
@@ -58,13 +58,8 @@ export class DatabaseService {
command: (prisma: SafeClient) => Promise<T>,
request: Request,
): Promise<T> {
const transaction = (request as any).transaction as SafeClient;
const transaction =
(request as any).transaction ?? (this.prismaClient as SafeClient);
return await command(transaction);
}
public async createTransaction(
action: (prisma: TransactionClient) => Promise<void>,
) {
await this.prismaClient.$transaction(action);
}
}
@@ -3,8 +3,8 @@ import kcClientConfig from "./nodejs-api.json" with { type: "json" };
import KeycloakAdminClient from "@keycloak/keycloak-admin-client";
import type RoleRepresentation from "@keycloak/keycloak-admin-client/lib/defs/roleRepresentation.js";
import { Claim } from "../../../models/claim.js";
import { type User } from "../../../models/user.js";
import { Claim } from "../../../dtos/claim.js";
import { type User } from "../../../dtos/user.js";
@Injectable()
export class KeycloakAdmin {
@@ -1,10 +1,8 @@
{
"realm": "taekwondo",
"auth-server-url": "https://localhost:8080",
"ssl-required": "external",
"resource": "nodejs-api",
"credentials": {
"secret": "devsecret"
},
"confidential-port": 0
"realm": "taekwondo",
"auth-server-url": "http://localhost:8080/",
"ssl-required": "external",
"resource": "angular-frontend",
"public-client": true,
"confidential-port": 0
}
+7 -3
View File
@@ -1,11 +1,11 @@
import express from "express";
import { inject, Injectable } from "../infrastructure/di/index.js";
import { ErrorStates } from "../infrastructure/errorStates.js";
import {
type Member,
type MemberCreateArgs,
mapDbMemberToMember,
} from "../models/member.js";
} from "../dtos/member.js";
import { inject, Injectable } from "../infrastructure/di/index.js";
import { ErrorStates } from "../infrastructure/errorStates.js";
import { DatabaseService } from "./db/prisma.js";
@Injectable()
@@ -43,6 +43,10 @@ export class MembersService {
createArgs: MemberCreateArgs,
request: express.Request,
): Promise<Member> {
const x: MemberCreateArgs = {
...createArgs,
geburtsdatum: createArgs.geburtsdatum ?? null,
};
const newMember = await this.database.doRequest(
async prisma => await prisma.member.create({ data: createArgs }),
request,
+2 -2
View File
@@ -1,6 +1,6 @@
import { Claim } from "../dtos/claim.js";
import { type User } from "../dtos/user.js";
import { inject } from "../infrastructure/di/index.js";
import { Claim } from "../models/claim.js";
import { type User } from "../models/user.js";
import { KeycloakAdmin } from "./keycloak/admin/index.js";
export class UserService {