UNPKG

keycloak-typescript

Version:

A user friendly library to use keycloak in nodejs projects

392 lines 18.6 kB
"use strict"; var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) { function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); } return new (P || (P = Promise))(function (resolve, reject) { function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } } function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } } function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); } step((generator = generator.apply(thisArg, _arguments || [])).next()); }); }; Object.defineProperty(exports, "__esModule", { value: true }); // Interfaces const IUserManager_1 = require("./Interfaces/IUserManager"); // Models const UserFields_1 = require("../enums/UserFields"); // Helpers const headers_factory_1 = require("../helpers/headers-factory"); const request_builder_1 = require("../helpers/request-builder"); class UserManager extends IUserManager_1.IUserManager { constructor(url, realmManager, clientManager, allowedUserFields) { super(); this.accessToken = ''; /** * * @param queryParameter * - briefRepresentation: Defines whether brief representations are returned * - email: User's email * - emailVerified: whether the email has been verified * - enabled: User is enabled or not * - firstName * - lastName * @param queryValue * @returns { User[] } */ this.getUsers = (queryParameter, queryValue) => __awaiter(this, void 0, void 0, function* () { const headers = headers_factory_1.HeadersFactory.instance().authorizationHeader(this.accessToken); const apiConfig = { url: `${this.url}?${queryParameter}=${queryValue}&exact=true`, method: 'GET', headers: headers, body: {} }; const response = yield (0, request_builder_1.requestBuilder)(apiConfig); return response.data; }); this.getUserId = (username) => __awaiter(this, void 0, void 0, function* () { const headers = headers_factory_1.HeadersFactory.instance().authorizationHeader(this.accessToken); const apiConfig = { url: `${this.url}?username=${username}&exact=true`, method: 'GET', headers: headers, body: {} }; const response = yield (0, request_builder_1.requestBuilder)(apiConfig); const userId = response.data[0].id; return userId; }); this.get = (userId) => __awaiter(this, void 0, void 0, function* () { var _a; const headers = headers_factory_1.HeadersFactory.instance().authorizationHeader(this.accessToken); const apiConfig = { url: `${this.url}/${userId}`, method: 'GET', headers: headers, body: {} }; const response = yield (0, request_builder_1.requestBuilder)(apiConfig); const user = this.trimUserInfo(response.data); if (this.allowedUserFields.has(UserFields_1.UserFields.CLIENT_ROLES) || this.allowedUserFields.has(UserFields_1.UserFields.REALM_ROLES)) { const rolesResponse = yield this.getRoles(userId); if (rolesResponse) { if (this.allowedUserFields.has(UserFields_1.UserFields.CLIENT_ROLES) && rolesResponse.clientMappings) { user.clientRoles = user.clientRoles ? user.clientRoles : new Map(); rolesResponse.clientMappings = rolesResponse.clientMappings ? new Map(Object.entries(rolesResponse.clientMappings)) : new Map(); rolesResponse.clientMappings.forEach((value, key) => { var _a; (_a = user.clientRoles) === null || _a === void 0 ? void 0 : _a.set(key, []); value.mappings.forEach((roleRepresentation) => { var _a, _b; (_b = (_a = user.clientRoles) === null || _a === void 0 ? void 0 : _a.get(key)) === null || _b === void 0 ? void 0 : _b.push(roleRepresentation.name ? roleRepresentation.name : ''); }); }); } if (this.allowedUserFields.has(UserFields_1.UserFields.REALM_ROLES) || rolesResponse.realmMappings) { user.realmRoles = user.realmRoles ? user.realmRoles : []; (_a = rolesResponse.realmMappings) === null || _a === void 0 ? void 0 : _a.forEach((realmMapping) => { var _a; (_a = user.realmRoles) === null || _a === void 0 ? void 0 : _a.push(realmMapping.name ? realmMapping.name : ''); }); } } } return user; }); this.create = (email, username, enabled, firstName, lastName, password, isTemporaryPassword, verifyEmail, attributes) => __awaiter(this, void 0, void 0, function* () { const headers = headers_factory_1.HeadersFactory.instance().authorizationHeader(this.accessToken); const objectAttributes = JSON.parse(attributes); const apiConfig = { url: this.url, method: 'POST', headers: headers, body: { email: email, username: username, firstName: firstName, lastName: lastName, enabled: enabled, attributes: objectAttributes } }; const response = yield (0, request_builder_1.requestBuilder)(apiConfig); const userID = response.headers.location.split('/').pop(); yield this.resetPassword(userID, password, isTemporaryPassword); if (verifyEmail) yield this.sendVerificationMail(userID); return userID; }); this.resetPassword = (userId, newPassword, isTemporary) => __awaiter(this, void 0, void 0, function* () { const apiConfig = { url: `${this.url}/${userId}/reset-password`, method: 'PUT', headers: headers_factory_1.HeadersFactory.instance().authorizationHeader(this.accessToken), body: { type: 'password', value: newPassword, temporary: isTemporary } }; yield (0, request_builder_1.requestBuilder)(apiConfig); }); this.forgotPassword = (userId) => __awaiter(this, void 0, void 0, function* () { const apiConfig = { url: `${this.url}/${userId}/execute-actions-email`, method: 'PUT', headers: headers_factory_1.HeadersFactory.instance().authorizationHeader(this.accessToken), body: ['UPDATE_PASSWORD'] }; yield (0, request_builder_1.requestBuilder)(apiConfig); }); this.sendVerificationMail = (userId) => __awaiter(this, void 0, void 0, function* () { const apiConfig = { url: `${this.url}/${userId}/send-verify-email`, method: 'PUT', headers: headers_factory_1.HeadersFactory.instance().authorizationHeader(this.accessToken), body: {} }; yield (0, request_builder_1.requestBuilder)(apiConfig); }); this.delete = (userId) => __awaiter(this, void 0, void 0, function* () { const headers = headers_factory_1.HeadersFactory.instance().authorizationHeader(this.accessToken); const apiConfig = { url: `${this.url}/${userId}`, method: 'DELETE', headers: headers, body: {} }; yield (0, request_builder_1.requestBuilder)(apiConfig); }); this.url = url; this.allowedUserFields = new Set(allowedUserFields ? allowedUserFields : UserFields_1.UserFields.getDefaultFields()); this.clientManager = clientManager; this.realmManager = realmManager; } modify(userId, user, isReplaceOperation) { return __awaiter(this, void 0, void 0, function* () { user = !isReplaceOperation ? this.fuseUsers(user, yield this.get(userId)) : user; user.attributes = Object.fromEntries(user.attributes ? user.attributes : []); const headers = headers_factory_1.HeadersFactory.instance().authorizationHeader(this.accessToken); const apiConfig = { url: `${this.url}/${userId}`, method: 'PUT', headers: headers, body: user }; yield (0, request_builder_1.requestBuilder)(apiConfig); //wait for add roles request yield this.modifyRoles(userId, user.realmRoles, user.clientRoles); return user; }); } update(subject, args) { if (args.length > 0) { this.accessToken = args[0]; } } trimUserInfo(user) { return { id: this.allowedUserFields.has(UserFields_1.UserFields.ID) ? user.id : undefined, origin: this.allowedUserFields.has(UserFields_1.UserFields.ORIGIN) ? user.origin : undefined, createdTimestamp: this.allowedUserFields.has(UserFields_1.UserFields.CREATED_TIMESTAMP) ? user.createdTimestamp : undefined, username: this.allowedUserFields.has(UserFields_1.UserFields.USERNAME) ? user.username : undefined, enabled: this.allowedUserFields.has(UserFields_1.UserFields.ENABLED) ? user.enabled : undefined, totp: this.allowedUserFields.has(UserFields_1.UserFields.TOTP) ? user.totp : undefined, emailVerified: this.allowedUserFields.has(UserFields_1.UserFields.EMAIL_VERIFIED) ? user.emailVerified : undefined, firstName: this.allowedUserFields.has(UserFields_1.UserFields.FIRST_NAME) ? user.firstName : undefined, lastName: this.allowedUserFields.has(UserFields_1.UserFields.LAST_NAME) ? user.lastName : undefined, email: this.allowedUserFields.has(UserFields_1.UserFields.EMAIL) ? user.email : undefined, federationLink: this.allowedUserFields.has(UserFields_1.UserFields.FEDERATION_LINK) ? user.federationLink : undefined, serviceAccountClientId: this.allowedUserFields.has(UserFields_1.UserFields.SERVICE_ACCOUNT_CLIENTID) ? user.serviceAccountClientId : undefined, attributes: this.allowedUserFields.has(UserFields_1.UserFields.ATTRIBUTES) ? user.attributes ? new Map(Object.entries(user.attributes)) : undefined : undefined, credentials: this.allowedUserFields.has(UserFields_1.UserFields.CREDENTIALS) ? user.credentials : undefined, disableableCredentialTypes: this.allowedUserFields.has(UserFields_1.UserFields.DISABLE_CREDENTIAL_TYPES) ? user.disableableCredentialTypes : undefined, requiredActions: this.allowedUserFields.has(UserFields_1.UserFields.REQUIRED_ACTIONS) ? user.requiredActions : undefined, federatedIdentities: this.allowedUserFields.has(UserFields_1.UserFields.FEDERATED_ENTITIES) ? user.federatedIdentities : undefined, realmRoles: this.allowedUserFields.has(UserFields_1.UserFields.REALM_ROLES) ? user.realmRoles : undefined, clientRoles: this.allowedUserFields.has(UserFields_1.UserFields.CLIENT_ROLES) ? user.clientRoles ? new Map(user.clientRoles) : undefined : undefined, clientConsents: this.allowedUserFields.has(UserFields_1.UserFields.CLIENT_CONSENTS) ? user.clientConsents : undefined, notBefore: this.allowedUserFields.has(UserFields_1.UserFields.NOT_BEFORE) ? user.notBefore : undefined, applicationRoles: this.allowedUserFields.has(UserFields_1.UserFields.APPLICATION_ROLES) ? user.applicationRoles ? new Map(user.applicationRoles) : undefined : undefined, socialLinks: this.allowedUserFields.has(UserFields_1.UserFields.SOCIAL_LINKS) ? user.socialLinks : undefined, groups: this.allowedUserFields.has(UserFields_1.UserFields.GROUPS) ? user.groups : undefined, access: this.allowedUserFields.has(UserFields_1.UserFields.ACCESS) ? user.access ? new Map(user.access) : undefined : undefined }; } fuseUsers(a, b) { //fuse only types that can be fused ex: append an array to another if (a.attributes && b.attributes) { b.attributes.forEach((value, key) => { if (a.attributes.has(key)) a.attributes.set(key, a.attributes.get(key).concat(value)); else a.attributes.set(key, value); }); } else if (b.attributes) { a.attributes = b.attributes; } a.disableableCredentialTypes = a.disableableCredentialTypes ? b.disableableCredentialTypes ? new Set([ ...a.disableableCredentialTypes, ...b.disableableCredentialTypes ]) : a.disableableCredentialTypes : b.disableableCredentialTypes; a.realmRoles = a.realmRoles ? b.realmRoles ? a.realmRoles.concat(b.realmRoles) : b.realmRoles : a.realmRoles; if (a.clientRoles && b.clientRoles) { b.clientRoles.forEach((value, key) => { if (a.clientRoles.has(key)) a.clientRoles.set(key, a.clientRoles.get(key).concat(value)); else a.clientRoles.set(key, value); }); } else if (b.clientRoles) { a.clientRoles = b.clientRoles; } if (a.applicationRoles && b.applicationRoles) { b.applicationRoles.forEach((value, key) => { if (a.applicationRoles.has(key)) a.applicationRoles.set(key, a.applicationRoles.get(key).concat(value)); else a.applicationRoles.set(key, value); }); } else if (b.applicationRoles) { a.applicationRoles = b.applicationRoles; } a.groups = a.groups ? b.groups ? a.groups.concat(b.groups) : b.groups : a.groups; if (a.access && b.access) { b.access.forEach((value, key) => { if (!a.access.has(key)) a.access.set(key, value); }); } else if (b.access) { a.access = b.access; } return a; } getRoles(userId) { return __awaiter(this, void 0, void 0, function* () { const headers = headers_factory_1.HeadersFactory.instance().authorizationHeader(this.accessToken); const apiConfig = { url: `${this.url}/${userId}/role-mappings`, method: 'GET', headers: headers, body: {} }; const response = yield (0, request_builder_1.requestBuilder)(apiConfig); return response === null || response === void 0 ? void 0 : response.data; }); } modifyRoles(userId, realmRoles, clientRoles) { return __awaiter(this, void 0, void 0, function* () { const headers = headers_factory_1.HeadersFactory.instance().authorizationHeader(this.accessToken); if (realmRoles) { const realmsBody = []; const realmRolesList = yield this.realmManager.getRoles('master', realmRoles); realmRolesList.forEach((role) => { var _a, _b; realmsBody.push({ id: (_a = role.id) !== null && _a !== void 0 ? _a : '', name: (_b = role.name) !== null && _b !== void 0 ? _b : '' }); }); const apiConfig = { url: `${this.url}/${userId}/role-mappings/realm`, method: 'POST', headers: headers, body: realmsBody }; yield (0, request_builder_1.requestBuilder)(apiConfig); } if (clientRoles) { for (const [key, value] of clientRoles) { const clientsBody = []; const clientId = (yield this.clientManager.get('master', key)).id; for (const role of value) { const roleId = (yield this.clientManager.getRole('master', clientId, role)).id; clientsBody.push({ id: roleId ? roleId : '', name: role }); } const apiConfig = { url: `${this.url}/${userId}/role-mappings/clients/${clientId}`, method: 'POST', headers: headers, body: clientsBody }; yield (0, request_builder_1.requestBuilder)(apiConfig); } } }); } } exports.default = UserManager; //# sourceMappingURL=UserManager.js.map