import { HttpStatusCode, IHttp, IModify, IPersistence, IRead, } from "@rocket.chat/apps-engine/definition/accessors"; import { ApiEndpoint, IApiEndpointInfo, IApiRequest, IApiResponse, } from "@rocket.chat/apps-engine/definition/api"; import crypto = require("crypto"); import { SCIMError, SCIMErrorType } from "./scim/Error"; import { SCIMListResponse } from "./scim/ListResponse"; import { SCIMUser } from "./scim/User"; export class UsersEndpoint extends ApiEndpoint { public path = "Users"; public async get( request: IApiRequest, endpoint: IApiEndpointInfo, read: IRead, modify: IModify, http: IHttp, persis: IPersistence ): Promise { const list = new SCIMListResponse(); try { const response = await http.get( `http://localhost:3000/api/v1/users.list?query={"type":{"$eq":"user"}}&fields={"createdAt":1}`, { headers: { ...(await this.getAuthHeaders(read)), "Content-Type": "application/json", }, } ); if (!response.content) { throw new Error("Empty response"); } const o = JSON.parse(response.content); if (!o.success) { throw new Error(o.error); } list.Resources = o.users.map(SCIMUser.fromRC); list.totalResults = o.total; } catch (e) { const err = new SCIMError(); err.scimType = SCIMErrorType.INVALID_VALUE; err.detail = e.message; err.status = "400"; return err.toApiResponse(); } return { headers: { "Content-Type": "application/scim+json", }, status: HttpStatusCode.OK, content: list, }; } public async post( request: IApiRequest, endpoint: IApiEndpointInfo, read: IRead, modify: IModify, http: IHttp, persis: IPersistence ): Promise { let user = request.content; try { const response = await http.post( `http://localhost:3000/api/v1/users.create`, { headers: { ...(await this.getAuthHeaders(read)), "Content-Type": "application/json", }, content: JSON.stringify( this.scimToUserCreate(SCIMUser.fromPlain(user)) ), } ); if (!response.content) { throw new Error("Empty response"); } const o = JSON.parse(response.content); if (!o.success) { throw new Error(o.error); } user = SCIMUser.fromRC(o.user); } catch (e) { const err = new SCIMError(); err.scimType = SCIMErrorType.INVALID_VALUE; err.detail = e.message; err.status = "400"; return err.toApiResponse(); } return { headers: { "Content-Type": "application/scim+json", }, status: HttpStatusCode.CREATED, content: user, }; } private async getAuthHeaders( read: IRead ): Promise<{ [key: string]: string }> { return { "X-User-Id": await read .getEnvironmentReader() .getSettings() .getValueById("rc-user-id"), "X-Auth-Token": await read .getEnvironmentReader() .getSettings() .getValueById("rc-token"), }; } private scimToUserCreate(user: SCIMUser): IUserCreate { return { email: user.emails[0].value, name: user.displayName, username: user.userName, password: crypto.randomBytes(64).toString("base64").slice(0, 64), verified: true, customFields: { scimExternalId: user.externalId, }, }; } }