75 lines
2.5 KiB
TypeScript
75 lines
2.5 KiB
TypeScript
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;
|
|
}
|
|
}
|