dev env setup
This commit is contained in:
@@ -1,7 +1,13 @@
|
||||
import { PrismaPg } from "@prisma/adapter-pg";
|
||||
import { type Request } from "express";
|
||||
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"
|
||||
>;
|
||||
|
||||
export type SafeClient = Omit<
|
||||
ExtendedClient,
|
||||
@@ -33,9 +39,9 @@ function createExtendedClient(client: PrismaClient) {
|
||||
// });
|
||||
}
|
||||
|
||||
@Injectable()
|
||||
export class DatabaseService {
|
||||
private readonly prismaClient: ExtendedClient;
|
||||
private readonly safeClient: SafeClient;
|
||||
|
||||
public constructor() {
|
||||
const dbUser = process.env["TKD_DB_USER"];
|
||||
@@ -46,17 +52,19 @@ export class DatabaseService {
|
||||
|
||||
const adapter = new PrismaPg({ connectionString });
|
||||
this.prismaClient = createExtendedClient(new PrismaClient({ adapter }));
|
||||
this.safeClient = this.prismaClient as SafeClient;
|
||||
|
||||
// this.prismaClient.$connect();
|
||||
// this.prismaClient.$disconnect();
|
||||
// this.prismaClient.$on();
|
||||
// this.prismaClient.$transaction();
|
||||
}
|
||||
|
||||
public async doRequest<T>(
|
||||
request: (prisma: SafeClient) => Promise<T>,
|
||||
command: (prisma: SafeClient) => Promise<T>,
|
||||
request: Request,
|
||||
): Promise<T> {
|
||||
return await request(this.safeClient);
|
||||
const transaction = (request as any).transaction as SafeClient;
|
||||
return await command(transaction);
|
||||
}
|
||||
|
||||
public async createTransaction(
|
||||
action: (prisma: TransactionClient) => Promise<void>,
|
||||
) {
|
||||
await this.prismaClient.$transaction(action);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,8 @@
|
||||
import { Injectable } from "../infrastructure/di/index.js";
|
||||
|
||||
@Injectable()
|
||||
export class EnvironmentService {
|
||||
public isDev(): boolean {
|
||||
return process.env["NODE_ENV"] !== "production";
|
||||
}
|
||||
}
|
||||
@@ -1,10 +1,10 @@
|
||||
import RoleRepresentation from "@keycloak/keycloak-admin-client/lib/defs/roleRepresentation";
|
||||
import { Injectable } from "../../../infrastructure/di/injectable-decorator";
|
||||
import { Injectable } from "../../../infrastructure/di/injectable-decorator.js";
|
||||
import kcClientConfig from "./nodejs-api.json" with { type: "json" };
|
||||
|
||||
import KeycloakAdminClient from "@keycloak/keycloak-admin-client";
|
||||
import { Claim } from "../../../models/claim";
|
||||
import { User } from "../../../models/user";
|
||||
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";
|
||||
|
||||
@Injectable()
|
||||
export class KeycloakAdmin {
|
||||
@@ -54,7 +54,7 @@ export class KeycloakAdmin {
|
||||
const client = await this.kcAdminClient;
|
||||
const kcUsers = await client.users.find();
|
||||
return kcUsers.map(kcUser => ({
|
||||
id: kcUser.id,
|
||||
id: kcUser.id ?? "", //TODO handle undefined id
|
||||
username: kcUser.username || "",
|
||||
roles: (kcUser.realmRoles || []).map(role => role as Claim),
|
||||
}));
|
||||
|
||||
@@ -2,16 +2,16 @@
|
||||
"clientId": "nodejs-api",
|
||||
"name": "NodejsApi",
|
||||
"description": "",
|
||||
"rootUrl": "https://tkd-api.toni714.de",
|
||||
"adminUrl": "https://tkd-api.toni714.de",
|
||||
"baseUrl": "https://tkd-api.toni714.de",
|
||||
"rootUrl": "http://localhost:3000",
|
||||
"adminUrl": "http://localhost:3000",
|
||||
"baseUrl": "http://localhost:3000",
|
||||
"surrogateAuthRequired": false,
|
||||
"enabled": true,
|
||||
"alwaysDisplayInConsole": false,
|
||||
"clientAuthenticatorType": "client-secret",
|
||||
"secret": "btdeoaq2mgtoa7SpCEL1phLYcw2gGhGp",
|
||||
"redirectUris": ["https://tkd-api.toni714.de/*"],
|
||||
"webOrigins": ["https://tkd-api.toni714.de"],
|
||||
"secret": "devsecret",
|
||||
"redirectUris": ["http://localhost:3000/*"],
|
||||
"webOrigins": ["http://localhost:3000"],
|
||||
"notBefore": 0,
|
||||
"bearerOnly": false,
|
||||
"consentRequired": false,
|
||||
|
||||
@@ -1,10 +1,10 @@
|
||||
{
|
||||
"realm": "taekwondo",
|
||||
"auth-server-url": "https://keycloak.toni714.de:8443",
|
||||
"auth-server-url": "https://localhost:8080",
|
||||
"ssl-required": "external",
|
||||
"resource": "nodejs-api",
|
||||
"credentials": {
|
||||
"secret": "btdeoaq2mgtoa7SpCEL1phLYcw2gGhGp"
|
||||
"secret": "devsecret"
|
||||
},
|
||||
"confidential-port": 0
|
||||
}
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
import express from "express";
|
||||
import { inject, Injectable } from "../infrastructure/di/index.js";
|
||||
import { ErrorStates } from "../infrastructure/errorStates.js";
|
||||
import {
|
||||
@@ -11,16 +12,22 @@ import { DatabaseService } from "./db/prisma.js";
|
||||
export class MembersService {
|
||||
private readonly database = inject(DatabaseService);
|
||||
|
||||
public async getMembers(): Promise<Member[]> {
|
||||
const dbMembers = await this.database.doRequest(prisma =>
|
||||
prisma.member.findMany(),
|
||||
public async getMembers(request: express.Request): Promise<Member[]> {
|
||||
const dbMembers = await this.database.doRequest(
|
||||
async prisma => await prisma.member.findMany(),
|
||||
request,
|
||||
);
|
||||
return dbMembers.map(mapDbMemberToMember);
|
||||
}
|
||||
|
||||
public async getMemberById(memberId: string): Promise<Member> {
|
||||
const member = await this.database.doRequest(prisma =>
|
||||
prisma.member.findFirst({ where: { id: memberId } }),
|
||||
public async getMemberById(
|
||||
memberId: string,
|
||||
request: express.Request,
|
||||
): Promise<Member> {
|
||||
const member = await this.database.doRequest(
|
||||
async prisma =>
|
||||
await prisma.member.findFirst({ where: { id: memberId } }),
|
||||
request,
|
||||
);
|
||||
|
||||
if (!member) {
|
||||
@@ -32,36 +39,51 @@ export class MembersService {
|
||||
return mapDbMemberToMember(member);
|
||||
}
|
||||
|
||||
public async createMember(createArgs: MemberCreateArgs): Promise<Member> {
|
||||
const newMember = await this.database.doRequest(prisma =>
|
||||
prisma.member.create({ data: createArgs }),
|
||||
public async createMember(
|
||||
createArgs: MemberCreateArgs,
|
||||
request: express.Request,
|
||||
): Promise<Member> {
|
||||
const newMember = await this.database.doRequest(
|
||||
async prisma => await prisma.member.create({ data: createArgs }),
|
||||
request,
|
||||
);
|
||||
return mapDbMemberToMember(newMember);
|
||||
}
|
||||
|
||||
public async updateMember(member: Member): Promise<Member> {
|
||||
public async updateMember(
|
||||
member: Member,
|
||||
request: express.Request,
|
||||
): Promise<Member> {
|
||||
const id = member.id;
|
||||
if (!id) {
|
||||
throw new Error("Member id is required for update", {
|
||||
cause: ErrorStates.BAD_REQUEST,
|
||||
});
|
||||
}
|
||||
const modifiedMember = await this.database.doRequest(prisma =>
|
||||
prisma.member.update({
|
||||
data: { ...member, id: id },
|
||||
where: { id: id },
|
||||
}),
|
||||
const modifiedMember = await this.database.doRequest(
|
||||
async prisma =>
|
||||
await prisma.member.update({
|
||||
data: { ...member, id: id },
|
||||
where: { id: id },
|
||||
}),
|
||||
request,
|
||||
);
|
||||
|
||||
return mapDbMemberToMember(modifiedMember);
|
||||
}
|
||||
|
||||
public async scheduleDeletion(memberId: string, cancelDate: Date) {
|
||||
await this.database.doRequest(prisma =>
|
||||
prisma.member.update({
|
||||
where: { id: memberId },
|
||||
data: { kuendigungzum: cancelDate },
|
||||
}),
|
||||
public async scheduleDeletion(
|
||||
memberId: string,
|
||||
cancelDate: Date,
|
||||
request: express.Request,
|
||||
) {
|
||||
await this.database.doRequest(
|
||||
prisma =>
|
||||
prisma.member.update({
|
||||
where: { id: memberId },
|
||||
data: { kuendigungzum: cancelDate },
|
||||
}),
|
||||
request,
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
import { inject } from "../infrastructure/di/index.js";
|
||||
import { Claim } from "../models/claim";
|
||||
import { Topic } from "../models/topic.js";
|
||||
import { User } from "../models/user.js";
|
||||
import { Claim } from "../models/claim.js";
|
||||
import { type User } from "../models/user.js";
|
||||
import { KeycloakAdmin } from "./keycloak/admin/index.js";
|
||||
|
||||
export class UserService {
|
||||
@@ -22,7 +21,7 @@ export class UserService {
|
||||
return await this.keycloakAdmin.getUsers();
|
||||
}
|
||||
|
||||
public async setSubscriptions(token: string, topics: Topic[]) {
|
||||
throw new Error("Method not implemented.");
|
||||
}
|
||||
// public async setSubscriptions(token: string, topics: Topic[]) {
|
||||
// throw new Error("Method not implemented.");
|
||||
// }
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user