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; 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 { 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 { 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 { 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 { 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; } }