api keycloak setup

This commit is contained in:
tw-blue
2025-11-29 17:58:02 +01:00
parent a9fb52fd4d
commit d6e7de09a4
27 changed files with 548 additions and 68 deletions
@@ -0,0 +1,74 @@
import RoleRepresentation from "@keycloak/keycloak-admin-client/lib/defs/roleRepresentation";
import { Injectable } from "../../../infrastructure/di/injectable-decorator";
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";
@Injectable()
export class KeycloakAdmin {
private readonly kcAdminClient: Promise<KeycloakAdminClient>;
constructor() {
this.kcAdminClient = new Promise(async resolve => {
const client = new KeycloakAdminClient({
baseUrl: kcClientConfig.baseUrl,
realmName: "taekwondo",
});
await client.auth({
...kcClientConfig,
grantType: "client_credentials",
});
resolve(client);
});
}
public async addRoleToUser(uid: string, roleName: string): Promise<void> {
const client = await this.kcAdminClient;
const role = await this.getRole(roleName);
if (!role.id || !role.name) {
throw new Error(`Role ${roleName} is missing id or name`);
}
await client.users.addRealmRoleMappings({
id: uid,
roles: [{ id: role.id, name: role.name }],
});
}
public async removeRoleFromUser(uid: string, claim: Claim): Promise<void> {
const client = await this.kcAdminClient;
const role = await this.getRole(claim);
if (!role.id || !role.name) {
throw new Error(`Role ${claim} is missing id or name`);
}
await client.users.delRealmRoleMappings({
id: uid,
roles: [{ id: role.id, name: role.name }],
});
}
public async getUsers(): Promise<User[]> {
const client = await this.kcAdminClient;
const kcUsers = await client.users.find();
return kcUsers.map(kcUser => ({
id: kcUser.id,
username: kcUser.username || "",
roles: (kcUser.realmRoles || []).map(role => role as Claim),
}));
}
private async getRole(name: string): Promise<RoleRepresentation> {
const client = await this.kcAdminClient;
const role = await client.roles.findOneByName({
name: name,
realm: "taekwondo",
});
if (!role) {
throw new Error(`Role ${name} not found`);
}
return role;
}
}