From 4e3601587377eef8706bf101e17ca40b963639f4 Mon Sep 17 00:00:00 2001 From: Hugo Renard Date: Wed, 9 Feb 2022 16:35:37 +0100 Subject: [PATCH] init app --- .editorconfig | 16 + .gitignore | 28 ++ .rcappsconfig | 20 + .vscode/extensions.json | 11 + README.md | 22 +- ScimApp.ts | 56 +++ UserEndpoint.ts | 225 ++++++++++ UsersEndpoint.ts | 176 ++++++++ app.json | 16 + docker-compose.yml | 55 +++ icon.png | Bin 0 -> 2664 bytes package-lock.json | 947 ++++++++++++++++++++++++++++++++++++++++ package.json | 11 + rest.ts | 43 ++ scim.ts | 16 + tsconfig.json | 15 + tslint.json | 14 + 17 files changed, 1670 insertions(+), 1 deletion(-) create mode 100644 .editorconfig create mode 100644 .gitignore create mode 100644 .rcappsconfig create mode 100644 .vscode/extensions.json create mode 100644 ScimApp.ts create mode 100644 UserEndpoint.ts create mode 100644 UsersEndpoint.ts create mode 100644 app.json create mode 100644 docker-compose.yml create mode 100644 icon.png create mode 100644 package-lock.json create mode 100644 package.json create mode 100644 rest.ts create mode 100644 scim.ts create mode 100644 tsconfig.json create mode 100644 tslint.json diff --git a/.editorconfig b/.editorconfig new file mode 100644 index 0000000..a1166f2 --- /dev/null +++ b/.editorconfig @@ -0,0 +1,16 @@ +# EditorConfig is awesome: http://EditorConfig.org + +# top-most EditorConfig file +root = true + +# Unix-style newlines with a newline ending every file +[*] +indent_style = space +indent_size = 4 +charset = utf-8 +end_of_line = lf +insert_final_newline = true +trim_trailing_whitespace = true + +[*.md] +trim_trailing_whitespace = false diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..a461715 --- /dev/null +++ b/.gitignore @@ -0,0 +1,28 @@ +# ignore modules pulled in from npm +node_modules/ + +# rc-apps package output +dist/ + +# JetBrains IDEs +out/ +.idea/ +.idea_modules/ + +# macOS +.DS_Store +.AppleDouble +.LSOverride +._* +.DocumentRevisions-V100 +.fseventsd +.Spotlight-V100 +.TemporaryItems +.Trashes +.VolumeIcon.icns +.com.apple.timemachine.donotpresent +.AppleDB +.AppleDesktop +Network Trash Folder +Temporary Items +.apdisk diff --git a/.rcappsconfig b/.rcappsconfig new file mode 100644 index 0000000..96e6c5d --- /dev/null +++ b/.rcappsconfig @@ -0,0 +1,20 @@ +{ + "url": "http://localhost:3000", + "username": "", + "password": "", + "ignoredFiles": [ + "**/README.md", + "**/docker-compose.yml", + "**/package-lock.json", + "**/package.json", + "**/tslint.json", + "**/tsconfig.json", + "**/*.js", + "**/*.js.map", + "**/*.d.ts", + "**/*.spec.ts", + "**/*.test.ts", + "**/dist/**", + "**/.*" + ] +} \ No newline at end of file diff --git a/.vscode/extensions.json b/.vscode/extensions.json new file mode 100644 index 0000000..b1e1592 --- /dev/null +++ b/.vscode/extensions.json @@ -0,0 +1,11 @@ + { + "recommendations": [ + "EditorConfig.editorconfig", + "eamodio.gitlens", + "eg2.vscode-npm-script", + "wayou.vscode-todo-highlight", + "minhthai.vscode-todo-parser", + "ms-vscode.vscode-typescript-tslint-plugin", + "rbbit.typescript-hero" + ] +} diff --git a/README.md b/README.md index 35079bf..a0f14c4 100644 --- a/README.md +++ b/README.md @@ -1,2 +1,22 @@ -# rocketchat-scim +# SCIM +SCIM Service Provider +## Getting Started +Now that you have generated a blank default Rocket.Chat App, what are you supposed to do next? +Start developing! Open up your favorite editor, our recommended one is Visual Studio code, +and start working on your App. Once you have something ready to test, you can either +package it up and manually deploy it to your test instance or you can use the CLI to do so. +Here are some commands to get started: +- `rc-apps package`: this command will generate a packaged app file (zip) which can be installed **if** it compiles with TypeScript +- `rc-apps deploy`: this will do what `package` does but will then ask you for your server url, username, and password to deploy it for you + +## Documentation +Here are some links to examples and documentation: +- [Rocket.Chat Apps TypeScript Definitions Documentation](https://rocketchat.github.io/Rocket.Chat.Apps-engine/) +- [Rocket.Chat Apps TypeScript Definitions Repository](https://github.com/RocketChat/Rocket.Chat.Apps-engine) +- [Example Rocket.Chat Apps](https://github.com/graywolf336/RocketChatApps) +- Community Forums + - [App Requests](https://forums.rocket.chat/c/rocket-chat-apps/requests) + - [App Guides](https://forums.rocket.chat/c/rocket-chat-apps/guides) + - [Top View of Both Categories](https://forums.rocket.chat/c/rocket-chat-apps) +- [#rocketchat-apps on Open.Rocket.Chat](https://open.rocket.chat/channel/rocketchat-apps) diff --git a/ScimApp.ts b/ScimApp.ts new file mode 100644 index 0000000..3ab3e2f --- /dev/null +++ b/ScimApp.ts @@ -0,0 +1,56 @@ +import { + IAppAccessors, + IConfigurationExtend, + ILogger, +} from "@rocket.chat/apps-engine/definition/accessors"; +import { + ApiSecurity, + ApiVisibility, +} from "@rocket.chat/apps-engine/definition/api"; +import { App } from "@rocket.chat/apps-engine/definition/App"; +import { IAppInfo } from "@rocket.chat/apps-engine/definition/metadata"; +import { SettingType } from "@rocket.chat/apps-engine/definition/settings"; + +import { UserEndpoint } from "./UserEndpoint"; +import { UsersEndpoint } from "./UsersEndpoint"; + +export class ScimApp extends App { + constructor(info: IAppInfo, logger: ILogger, accessors: IAppAccessors) { + super(info, logger, accessors); + } + + public async extendConfiguration(configuration: IConfigurationExtend) { + configuration.api.provideApi({ + visibility: ApiVisibility.PUBLIC, + security: ApiSecurity.UNSECURE, + endpoints: [new UsersEndpoint(this), new UserEndpoint(this)], + }); + + configuration.settings.provideSetting({ + id: "rc-user-id", + type: SettingType.STRING, + packageValue: "", + required: true, + public: false, + i18nLabel: "Rocket.Chat User ID", + }); + + configuration.settings.provideSetting({ + id: "rc-token", + type: SettingType.STRING, + packageValue: "", + required: true, + public: false, + i18nLabel: "Rocket.Chat Token", + }); + } + + // public async onSettingUpdated( + // setting: ISetting, + // configurationModify: IConfigurationModify, + // read: IRead, + // http: IHttp + // ): Promise { + // this.con + // } +} diff --git a/UserEndpoint.ts b/UserEndpoint.ts new file mode 100644 index 0000000..f45bd2f --- /dev/null +++ b/UserEndpoint.ts @@ -0,0 +1,225 @@ +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"; +const crypto = require("crypto"); + +export class UserEndpoint extends ApiEndpoint { + public path = "Users/:id"; + // private http: IHttp; + // private authHeaders: { [key: string]: string }; + + // constructor(app: IApp) { + // super(app); + // } + + // private async updateState(http: IHttp, read: IRead) { + // this.http = http; + // this.authHeaders = { + // "X-User-Id": await read + // .getEnvironmentReader() + // .getSettings() + // .getValueById("rc-user-id"), + // "X-Auth-Token": await read + // .getEnvironmentReader() + // .getSettings() + // .getValueById("rc-token"), + // }; + // } + + 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 scimToRC(user: ISCIMUser): IUser { + // return { + // email: user.emails[0].value, + // name: user.displayName, + // password: "P@ssw0rd", + // username: user.userName, + // verified: true, + // }; + // } + + private scimToUserUpdate(userId: string, user: ISCIMUser): IUserUpdate { + return { + userId, + data: { + email: user.emails[0].value, + name: user.displayName, + username: user.userName, + active: user.active, + verified: true, + customFields: { + scimExternalId: user.externalId, + }, + }, + }; + } + + private rcToSCIM(user: IUser): ISCIMUser { + return { + id: user._id, + externalId: "", + emails: [ + { type: "work", primary: true, value: user.emails[0].address }, + ], + displayName: user.name, + userName: user.username, + active: user.active === undefined ? true : user.active, + }; + } + + public async get( + request: IApiRequest, + endpoint: IApiEndpointInfo, + read: IRead, + modify: IModify, + http: IHttp, + persis: IPersistence + ): Promise { + let user: ISCIMUser; + try { + const response = await http.get( + `http://localhost:3000/api/v1/users.info?userId=` + + request.params.id, + { + 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); + // user = this.rcToSCIM(o.user); + user = this.rcToSCIM(o.user); + } catch (e) { + return { + headers: { + "Content-Type": "application/json+scim", + }, + status: HttpStatusCode.BAD_REQUEST, + content: { message: e.message }, + }; + } + return { + headers: { + "Content-Type": "application/json+scim", + }, + status: HttpStatusCode.FOUND, + content: user, + }; + } + + public async put( + request: IApiRequest, + endpoint: IApiEndpointInfo, + read: IRead, + modify: IModify, + http: IHttp, + persis: IPersistence + ): Promise { + let user: ISCIMUser; + try { + const response = await http.post( + "http://localhost:3000/api/v1/users.update", + { + headers: { + ...(await this.getAuthHeaders(read)), + "Content-Type": "application/json", + }, + content: JSON.stringify( + this.scimToUserUpdate( + request.params.id, + request.content + ) + ), + } + ); + if (!response.content) throw new Error("Empty response"); + const o = JSON.parse(response.content); + if (!o.success) throw new Error(o.error); + user = this.rcToSCIM(o.user); + } catch (e) { + return { + headers: { + "Content-Type": "application/json+scim", + }, + status: HttpStatusCode.BAD_REQUEST, + content: { message: e.message }, + }; + } + return { + headers: { + "Content-Type": "application/json+scim", + }, + status: HttpStatusCode.FOUND, + content: user, + }; + } + + public async delete( + request: IApiRequest, + endpoint: IApiEndpointInfo, + read: IRead, + modify: IModify, + http: IHttp, + persis: IPersistence + ): Promise { + let d: IUserDelete = { + userId: request.params.id, + confirmRelinquish: true, + }; + try { + const response = await http.post( + "http://localhost:3000/api/v1/users.delete", + { + headers: { + ...(await this.getAuthHeaders(read)), + "Content-Type": "application/json", + }, + content: JSON.stringify(d), + } + ); + if (!response.content) throw new Error("Empty response"); + const o = JSON.parse(response.content); + if (!o.success) throw new Error(o.error); + } catch (e) { + return { + headers: { + "Content-Type": "application/json+scim", + }, + status: HttpStatusCode.BAD_REQUEST, + content: { message: e.message }, + }; + } + return { + headers: { + "Content-Type": "application/json+scim", + }, + status: HttpStatusCode.NO_CONTENT, + }; + } +} diff --git a/UsersEndpoint.ts b/UsersEndpoint.ts new file mode 100644 index 0000000..646924e --- /dev/null +++ b/UsersEndpoint.ts @@ -0,0 +1,176 @@ +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"; +const crypto = require("crypto"); + +export class UsersEndpoint extends ApiEndpoint { + public path = "Users"; + // private http: IHttp; + // private authHeaders: { [key: string]: string }; + + // constructor(app: IApp) { + // super(app); + // } + + // private async updateState(http: IHttp, read: IRead) { + // this.http = http; + // this.authHeaders = { + // "X-User-Id": await read + // .getEnvironmentReader() + // .getSettings() + // .getValueById("rc-user-id"), + // "X-Auth-Token": await read + // .getEnvironmentReader() + // .getSettings() + // .getValueById("rc-token"), + // }; + // } + + 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 scimToRC(user: ISCIMUser): IUser { + // return { + // email: user.emails[0].value, + // name: user.displayName, + // password: "P@ssw0rd", + // username: user.userName, + // verified: true, + // }; + // } + + private scimToUserCreate(user: ISCIMUser): 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 + } + }; + } + + private rcToSCIM(user: IUser): ISCIMUser { + return { + id: user._id, + externalId: "", + emails: [ + { type: "work", primary: true, value: user.emails[0].address }, + ], + displayName: user.name, + userName: user.username, + active: user.active === undefined ? true : user.active, + }; + } + + public async get( + request: IApiRequest, + endpoint: IApiEndpointInfo, + read: IRead, + modify: IModify, + http: IHttp, + persis: IPersistence + ): Promise { + let users: Array = []; + try { + const response = await http.get( + `http://localhost:3000/api/v1/users.list?query={"type": {"$eq": "user"}}`, + { + 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); + // user = this.rcToSCIM(o.user); + users = o.users.map(this.rcToSCIM); + } catch (e) { + return { + headers: { + "Content-Type": "application/json+scim", + }, + status: HttpStatusCode.BAD_REQUEST, + content: { message: e.message }, + }; + } + return { + headers: { + "Content-Type": "application/json+scim", + }, + status: HttpStatusCode.FOUND, + content: users, + }; + } + + 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(request.content) + ), + } + ); + if (!response.content) throw new Error("Empty response"); + const o = JSON.parse(response.content); + if (!o.success) throw new Error(o.error); + // user = this.rcToSCIM(o.user); + user = this.rcToSCIM(o.user); + } catch (e) { + return { + headers: { + "Content-Type": "application/json+scim", + }, + status: HttpStatusCode.BAD_REQUEST, + content: { message: e.message }, + }; + } + return { + headers: { + "Content-Type": "application/json+scim", + }, + status: HttpStatusCode.CREATED, + content: user, + }; + } +} diff --git a/app.json b/app.json new file mode 100644 index 0000000..cac08c0 --- /dev/null +++ b/app.json @@ -0,0 +1,16 @@ +{ + "id": "53fd430f-3924-4c6c-8774-b23fabfeb0e5", + "version": "0.0.1", + "requiredApiVersion": "^1.19.0", + "iconFile": "icon.png", + "author": { + "name": "IndieHosters", + "homepage": "https://indiehosters.net/", + "support": "https://lab.libreho.st/libre.sh/scim/rocketchat-scim/-/issues" + }, + "name": "SCIM", + "nameSlug": "scim", + "classFile": "ScimApp.ts", + "description": "SCIM Service Provider", + "implements": [] +} \ No newline at end of file diff --git a/docker-compose.yml b/docker-compose.yml new file mode 100644 index 0000000..ef458a9 --- /dev/null +++ b/docker-compose.yml @@ -0,0 +1,55 @@ +version: "3" + +services: + rocketchat: + image: registry.rocket.chat/rocketchat/rocket.chat:latest + command: > + bash -c + "for i in `seq 1 30`; do + node main.js && + s=$$? && break || s=$$?; + echo \"Tried $$i times. Waiting 5 secs...\"; + sleep 5; + done; (exit $$s)" + restart: unless-stopped + volumes: + - uploads:/app/uploads + environment: + - PORT=3000 + - ROOT_URL=http://localhost:3000 + - MONGO_URL=mongodb://mongo:27017/rocketchat + - MONGO_OPLOG_URL=mongodb://mongo:27017/local + # - ADMIN_USERNAME=test + # - ADMIN_PASS=test + # - ADMIN_EMAIL=test@example.com + depends_on: + - mongo + ports: + - 3000:3000 + + mongo: + image: mongo:4.0 + restart: unless-stopped + volumes: + - db:/data/db + command: mongod --smallfiles --oplogSize 128 --replSet rs0 --storageEngine=mmapv1 + + mongo-init-replica: + image: mongo:4.0 + command: > + bash -c + "for i in `seq 1 30`; do + mongo mongo/rocketchat --eval \" + rs.initiate({ + _id: 'rs0', + members: [ { _id: 0, host: 'localhost:27017' } ]})\" && + s=$$? && break || s=$$?; + echo \"Tried $$i times. Waiting 5 secs...\"; + sleep 5; + done; (exit $$s)" + depends_on: + - mongo + +volumes: + uploads: + db: diff --git a/icon.png b/icon.png new file mode 100644 index 0000000000000000000000000000000000000000..a7c0cc49a64bd06d47e4e0b507d26338e8d92582 GIT binary patch literal 2664 zcmb_e`#Tf*AD=pMYn+ZtM3jmWDVHv!9U+xlwwaa7zS2yVgfYyq%AMmlk|ozzUo6A4 z#$hhUMnVkBvgVT8Xo@Ct+t_#Khwp!IKF{-h-p})TKkwJ;ef!~)e#6}vsC+;f00025 zU3CNl0K4D-fZU%y?Uo@Ab$3_GobC-*sFTb~rBVa}fyd)PAW&&(>Ez_3fq_ALdwcGE z{yAA#>A}^TkpO^d=RYQwcT!bXhW)taXb+7k`o`<`;a%C)9UiDV8))=Xx3k{D*>0O8 zBWKr`%h^%K?`E$>7xwRi5FY$q5Ly7DKjCk8!LO*YsH_AKi(MIXug4N}jrcr=9U>ubakd7-MZWs2ycy9&SIF@l5bKyzr7mk#Vn3zENjE24Z}1z3!Xy6O09Tg3<1yW z@LPLxp3Hr79w5BbULhZV>^9zs9i+*VjDox;<{<(7`c6&}9>x1FEM zR#Wi@=-A?ZsHD8*NC7r1qb_XT-MaiSf2?=mBiGSgOG=s?lwWZVz4aSW!Ce{-LevJ% zCWe^JH2rWY?i?qMLU6E9lgZrfm#cMx<<`W+XVVZ`HSqy2Yeo6}SK8@`6DW>5jVR-z zG<=}U(H20qt#KxolIr;i&3QhN%ouO{5)wO1m zOtEQ{+(3U4s>PDa85wocvYLnTuS5Zw+6=JCEsy4Qa&iKYO*Z2hrdZK@rQk?9g>SeM zQD39xpnvc5hbXuPLGTI3-}qg;<+$8iYh@BV0IRUgjcjZf7gd?7R7@CIkkM3$^_iRe zILx1l=%V~p<;X{S6Xn<`e?)u2?aEBhVlN0V_KK5y|MOlAEVmtM?JBwhqH2CqT=(%F_lZM_Td}2k0ej!TXb~4XVsb1=~Cale+$@7Z;kqaZ!@YCZ-MUzIT=q zE8T>gbJvkK(bkB`RS!s>cc&S%vy+J~)Dp^ZQ@f!v##Hv19<-&b*4mE6dfvOW8!In$ z<;-)8xJcn~YVsE=WhY02M;8jzZ{9C~eS#tF-yMm&^oPi-or0_XxAC(5v2 zlIYU~sBQzeLMe)Afm`}7dn$<#UpFI_AeqK4X0JnpMfhW+mSN_%9F(5<7D@J>{5j}N$k0*(y-gN z!cx8@ejb<6+75t$p>*z3W?HlcK{^_LTo2;a^Z_$}+$59H8#K*Mmf&O=#_G0P8?%Dn zMXzJ?|JnZ)vw;ys^k+M|{#rXc({{tZe8dy}aqHYqE{qVm!d3kyF|dz(A^y#Bg*mf( z!l9-f6zL0X>R*i`7&3cLvYNu+;T{@k65^|3Ze5^v8@z~`e2}cLaYv<|3BB@1EvmG zgLNCsY4zJ!fOkKJvCmJ4{iqY19QhgiD*N3`pY>k!f-63nxz#k5YGCr0Snp}Wd$-ZT zrHl8vvXQ-E(J9}D)Cn*f@>D1bh=fN|vwWBgg{dqMo;>*|T#Yus<$BXHh8-qn`=yuK0Fa2-4{s2nc zUKtg9@x1sZxJyNICDOCI{yaGycrxSs`RBGP;%@~FAy;Lmp-u=9!8VRf5%+LA)BU~N z?d(L1VUNz0V1~M1N}PvZI2u0j;hKmRh}jgTqe_VvK9MX2!0TCS~bchtXq573xY zO}&q*Ek(U2W**+#cc%r(xbAPC(0%CRa&f7q06CZXg*92MOK7gk&nY`_QO7PL<79zfDA}zhnyDjq<3WRDQvM68UXf zJjYJI%Cg0dy}Rzkiwjb3E4Dy-M9A~3j(T25#U9-=spZ+yTdjyu&zwqBg*=r88RC!$ zJ{+yY2sH~^9=1hmntgYXDRdE$Z40i>PiJS6B?lh@(eQy9s$JtiB)-#VnLA@2{r~|T z*@0_1%lF3;kBapEvQ;k!QPo7RcAa6jPp09u!AXO7#EyeHdn5hlE)8$ka7td*>h(us zQ5rB0scB~l?dDf;@%N>}QwN=@NT0LF4St_jWSujHkC-(1HU(yv-fDje+Qb?TF;go? zc-!ZKR5oX{W6f+pv4f!8oJ?4HS3ACH-u0~M%~`*zQ!|T#6JfC)n;kXL(C@T6xKxzb zzehN=NhNmaV%7&(Yvb3ExOoK<9*Bv0kU+t^d_x@6FWTeuEEUBfG&VNN?Z@HUD1a+( zz!(;&Oj3Foe)14m^Jk8-B3eF)wu^B~E}-Ti1@`Oz;Zy6+H2;Nv)!)*(cDcCevW*w< SfQ*0mt~t3o)?WV4=6.9.0" + } + }, + "node_modules/@babel/helper-validator-identifier": { + "version": "7.16.7", + "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.16.7.tgz", + "integrity": "sha512-hsEnFemeiW4D08A5gUAZxLBTXpZ39P+a+DGDsHw1yxqyQ/jzFEnxf5uTEGp+3bzAbNOxU1paTgYS4ECU/IgfDw==", + "dev": true, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/highlight": { + "version": "7.16.10", + "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.16.10.tgz", + "integrity": "sha512-5FnTQLSLswEj6IkgVw5KusNUUFY9ZGqe/TRFnP/BKYHYgfh7tc+C7mwiy95/yNP7Dh9x580Vv8r7u7ZfTBFxdw==", + "dev": true, + "dependencies": { + "@babel/helper-validator-identifier": "^7.16.7", + "chalk": "^2.0.0", + "js-tokens": "^4.0.0" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@rocket.chat/apps-engine": { + "version": "1.30.0", + "resolved": "https://registry.npmjs.org/@rocket.chat/apps-engine/-/apps-engine-1.30.0.tgz", + "integrity": "sha512-04X4nQPgZEz9w4b/8zCyW+EVixfzdrugW4u6YUYnB4tc9lDALawSvhz88XlDGvKwbsUKFfSx6ejdhASwSssPcA==", + "dev": true, + "dependencies": { + "adm-zip": "^0.4.9", + "cryptiles": "^4.1.3", + "lodash.clonedeep": "^4.5.0", + "semver": "^5.5.0", + "stack-trace": "0.0.10", + "uuid": "^3.2.1" + } + }, + "node_modules/@types/node": { + "version": "14.14.6", + "resolved": "https://registry.npmjs.org/@types/node/-/node-14.14.6.tgz", + "integrity": "sha512-6QlRuqsQ/Ox/aJEQWBEJG7A9+u7oSYl3mem/K8IzxXG/kAGbV1YPD9Bg9Zw3vyxC/YP+zONKwy8hGkSt1jxFMw==", + "dev": true + }, + "node_modules/adm-zip": { + "version": "0.4.16", + "resolved": "https://registry.npmjs.org/adm-zip/-/adm-zip-0.4.16.tgz", + "integrity": "sha512-TFi4HBKSGfIKsK5YCkKaaFG2m4PEDyViZmEwof3MTIgzimHLto6muaHVpbrljdIvIrFZzEq/p4nafOeLcYegrg==", + "dev": true, + "engines": { + "node": ">=0.3.0" + } + }, + "node_modules/ansi-styles": { + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", + "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", + "dev": true, + "dependencies": { + "color-convert": "^1.9.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/argparse": { + "version": "1.0.10", + "resolved": "https://registry.npmjs.org/argparse/-/argparse-1.0.10.tgz", + "integrity": "sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg==", + "dev": true, + "dependencies": { + "sprintf-js": "~1.0.2" + } + }, + "node_modules/balanced-match": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz", + "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==", + "dev": true + }, + "node_modules/boom": { + "version": "7.3.0", + "resolved": "https://registry.npmjs.org/boom/-/boom-7.3.0.tgz", + "integrity": "sha512-Swpoyi2t5+GhOEGw8rEsKvTxFLIDiiKoUc2gsoV6Lyr43LHBIzch3k2MvYUs8RTROrIkVJ3Al0TkaOGjnb+B6A==", + "deprecated": "This module has moved and is now available at @hapi/boom. Please update your dependencies as this version is no longer maintained an may contain bugs and security issues.", + "dev": true, + "dependencies": { + "hoek": "6.x.x" + } + }, + "node_modules/brace-expansion": { + "version": "1.1.11", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", + "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", + "dev": true, + "dependencies": { + "balanced-match": "^1.0.0", + "concat-map": "0.0.1" + } + }, + "node_modules/builtin-modules": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/builtin-modules/-/builtin-modules-1.1.1.tgz", + "integrity": "sha1-Jw8HbFpywC9bZaR9+Uxf46J4iS8=", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/chalk": { + "version": "2.4.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", + "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", + "dev": true, + "dependencies": { + "ansi-styles": "^3.2.1", + "escape-string-regexp": "^1.0.5", + "supports-color": "^5.3.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/color-convert": { + "version": "1.9.3", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", + "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==", + "dev": true, + "dependencies": { + "color-name": "1.1.3" + } + }, + "node_modules/color-name": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", + "integrity": "sha1-p9BVi9icQveV3UIyj3QIMcpTvCU=", + "dev": true + }, + "node_modules/commander": { + "version": "2.20.3", + "resolved": "https://registry.npmjs.org/commander/-/commander-2.20.3.tgz", + "integrity": "sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ==", + "dev": true + }, + "node_modules/concat-map": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", + "integrity": "sha1-2Klr13/Wjfd5OnMDajug1UBdR3s=", + "dev": true + }, + "node_modules/cryptiles": { + "version": "4.1.3", + "resolved": "https://registry.npmjs.org/cryptiles/-/cryptiles-4.1.3.tgz", + "integrity": "sha512-gT9nyTMSUC1JnziQpPbxKGBbUg8VL7Zn2NB4E1cJYvuXdElHrwxrV9bmltZGDzet45zSDGyYceueke1TjynGzw==", + "deprecated": "This module has moved and is now available at @hapi/cryptiles. Please update your dependencies as this version is no longer maintained an may contain bugs and security issues.", + "dev": true, + "dependencies": { + "boom": "7.x.x" + } + }, + "node_modules/diff": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/diff/-/diff-4.0.2.tgz", + "integrity": "sha512-58lmxKSA4BNyLz+HHMUzlOEpg09FV+ev6ZMe3vJihgdxzgcwZ8VoEEPmALCZG9LmqfVoNMMKpttIYTVG6uDY7A==", + "dev": true, + "engines": { + "node": ">=0.3.1" + } + }, + "node_modules/escape-string-regexp": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", + "integrity": "sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ=", + "dev": true, + "engines": { + "node": ">=0.8.0" + } + }, + "node_modules/esprima": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/esprima/-/esprima-4.0.1.tgz", + "integrity": "sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A==", + "dev": true, + "bin": { + "esparse": "bin/esparse.js", + "esvalidate": "bin/esvalidate.js" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/fs.realpath": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", + "integrity": "sha1-FQStJSMVjKpA20onh8sBQRmU6k8=", + "dev": true + }, + "node_modules/function-bind": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.1.tgz", + "integrity": "sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A==", + "dev": true + }, + "node_modules/glob": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.0.tgz", + "integrity": "sha512-lmLf6gtyrPq8tTjSmrO94wBeQbFR3HbLHbuyD69wuyQkImp2hWqMGB47OX65FBkPffO641IP9jWa1z4ivqG26Q==", + "dev": true, + "dependencies": { + "fs.realpath": "^1.0.0", + "inflight": "^1.0.4", + "inherits": "2", + "minimatch": "^3.0.4", + "once": "^1.3.0", + "path-is-absolute": "^1.0.0" + }, + "engines": { + "node": "*" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/has": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/has/-/has-1.0.3.tgz", + "integrity": "sha512-f2dvO0VU6Oej7RkWJGrehjbzMAjFp5/VKPp5tTpWIV4JHHZK1/BxbFRtf/siA2SWTe09caDmVtYYzWEIbBS4zw==", + "dev": true, + "dependencies": { + "function-bind": "^1.1.1" + }, + "engines": { + "node": ">= 0.4.0" + } + }, + "node_modules/has-flag": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", + "integrity": "sha1-tdRU3CGZriJWmfNGfloH87lVuv0=", + "dev": true, + "engines": { + "node": ">=4" + } + }, + "node_modules/hoek": { + "version": "6.1.3", + "resolved": "https://registry.npmjs.org/hoek/-/hoek-6.1.3.tgz", + "integrity": "sha512-YXXAAhmF9zpQbC7LEcREFtXfGq5K1fmd+4PHkBq8NUqmzW3G+Dq10bI/i0KucLRwss3YYFQ0fSfoxBZYiGUqtQ==", + "deprecated": "This module has moved and is now available at @hapi/hoek. Please update your dependencies as this version is no longer maintained an may contain bugs and security issues.", + "dev": true + }, + "node_modules/inflight": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", + "integrity": "sha1-Sb1jMdfQLQwJvJEKEHW6gWW1bfk=", + "dev": true, + "dependencies": { + "once": "^1.3.0", + "wrappy": "1" + } + }, + "node_modules/inherits": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", + "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==", + "dev": true + }, + "node_modules/is-core-module": { + "version": "2.8.1", + "resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.8.1.tgz", + "integrity": "sha512-SdNCUs284hr40hFTFP6l0IfZ/RSrMXF3qgoRHd3/79unUTvrFO/JoXwkGm+5J/Oe3E/b5GsnG330uUNgRpu1PA==", + "dev": true, + "dependencies": { + "has": "^1.0.3" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/js-tokens": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz", + "integrity": "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==", + "dev": true + }, + "node_modules/js-yaml": { + "version": "3.14.1", + "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.14.1.tgz", + "integrity": "sha512-okMH7OXXJ7YrN9Ok3/SXrnu4iX9yOk+25nqX4imS2npuvTYDmo/QEZoqwZkYaIDk3jVvBOTOIEgEhaLOynBS9g==", + "dev": true, + "dependencies": { + "argparse": "^1.0.7", + "esprima": "^4.0.0" + }, + "bin": { + "js-yaml": "bin/js-yaml.js" + } + }, + "node_modules/lodash.clonedeep": { + "version": "4.5.0", + "resolved": "https://registry.npmjs.org/lodash.clonedeep/-/lodash.clonedeep-4.5.0.tgz", + "integrity": "sha1-4j8/nE+Pvd6HJSnBBxhXoIblzO8=", + "dev": true + }, + "node_modules/minimatch": { + "version": "3.0.5", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.0.5.tgz", + "integrity": "sha512-tUpxzX0VAzJHjLu0xUfFv1gwVp9ba3IOuRAVH2EGuRW8a5emA2FlACLqiT/lDVtS1W+TGNwqz3sWaNyLgDJWuw==", + "dev": true, + "dependencies": { + "brace-expansion": "^1.1.7" + }, + "engines": { + "node": "*" + } + }, + "node_modules/minimist": { + "version": "1.2.5", + "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.5.tgz", + "integrity": "sha512-FM9nNUYrRBAELZQT3xeZQ7fmMOBg6nWNmJKTcgsJeaLstP/UODVpGsr5OhXhhXg6f+qtJ8uiZ+PUxkDWcgIXLw==", + "dev": true + }, + "node_modules/mkdirp": { + "version": "0.5.5", + "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.5.tgz", + "integrity": "sha512-NKmAlESf6jMGym1++R0Ra7wvhV+wFW63FaSOFPwRahvea0gMUcGUhVeAg/0BC0wiv9ih5NYPB1Wn1UEI1/L+xQ==", + "dev": true, + "dependencies": { + "minimist": "^1.2.5" + }, + "bin": { + "mkdirp": "bin/cmd.js" + } + }, + "node_modules/once": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", + "integrity": "sha1-WDsap3WWHUsROsF9nFC6753Xa9E=", + "dev": true, + "dependencies": { + "wrappy": "1" + } + }, + "node_modules/path-is-absolute": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz", + "integrity": "sha1-F0uSaHNVNP+8es5r9TpanhtcX18=", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/path-parse": { + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.7.tgz", + "integrity": "sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==", + "dev": true + }, + "node_modules/resolve": { + "version": "1.22.0", + "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.22.0.tgz", + "integrity": "sha512-Hhtrw0nLeSrFQ7phPp4OOcVjLPIeMnRlr5mcnVuMe7M/7eBn98A3hmFRLoFo3DLZkivSYwhRUJTyPyWAk56WLw==", + "dev": true, + "dependencies": { + "is-core-module": "^2.8.1", + "path-parse": "^1.0.7", + "supports-preserve-symlinks-flag": "^1.0.0" + }, + "bin": { + "resolve": "bin/resolve" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/scimmy": { + "version": "0.10.0", + "resolved": "https://registry.npmjs.org/scimmy/-/scimmy-0.10.0.tgz", + "integrity": "sha512-QYCwrXJnWet4ZIiruCKcks8rddO8IqIIBr4NgXUnE+l1sFEC6emCR3LyqENy/9eVe8lVaLetMho1oJ3YNHpNaA==", + "engines": { + "node": ">=16" + } + }, + "node_modules/semver": { + "version": "5.7.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", + "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==", + "dev": true, + "bin": { + "semver": "bin/semver" + } + }, + "node_modules/sprintf-js": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.0.3.tgz", + "integrity": "sha1-BOaSb2YolTVPPdAVIDYzuFcpfiw=", + "dev": true + }, + "node_modules/stack-trace": { + "version": "0.0.10", + "resolved": "https://registry.npmjs.org/stack-trace/-/stack-trace-0.0.10.tgz", + "integrity": "sha1-VHxws0fo0ytOEI6hoqFZ5f3eGcA=", + "dev": true, + "engines": { + "node": "*" + } + }, + "node_modules/supports-color": { + "version": "5.5.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", + "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", + "dev": true, + "dependencies": { + "has-flag": "^3.0.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/supports-preserve-symlinks-flag": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/supports-preserve-symlinks-flag/-/supports-preserve-symlinks-flag-1.0.0.tgz", + "integrity": "sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w==", + "dev": true, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/tslib": { + "version": "1.14.1", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.14.1.tgz", + "integrity": "sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg==", + "dev": true + }, + "node_modules/tslint": { + "version": "5.20.1", + "resolved": "https://registry.npmjs.org/tslint/-/tslint-5.20.1.tgz", + "integrity": "sha512-EcMxhzCFt8k+/UP5r8waCf/lzmeSyVlqxqMEDQE7rWYiQky8KpIBz1JAoYXfROHrPZ1XXd43q8yQnULOLiBRQg==", + "dev": true, + "dependencies": { + "@babel/code-frame": "^7.0.0", + "builtin-modules": "^1.1.1", + "chalk": "^2.3.0", + "commander": "^2.12.1", + "diff": "^4.0.1", + "glob": "^7.1.1", + "js-yaml": "^3.13.1", + "minimatch": "^3.0.4", + "mkdirp": "^0.5.1", + "resolve": "^1.3.2", + "semver": "^5.3.0", + "tslib": "^1.8.0", + "tsutils": "^2.29.0" + }, + "bin": { + "tslint": "bin/tslint" + }, + "engines": { + "node": ">=4.8.0" + }, + "peerDependencies": { + "typescript": ">=2.3.0-dev || >=2.4.0-dev || >=2.5.0-dev || >=2.6.0-dev || >=2.7.0-dev || >=2.8.0-dev || >=2.9.0-dev || >=3.0.0-dev || >= 3.1.0-dev || >= 3.2.0-dev" + } + }, + "node_modules/tsutils": { + "version": "2.29.0", + "resolved": "https://registry.npmjs.org/tsutils/-/tsutils-2.29.0.tgz", + "integrity": "sha512-g5JVHCIJwzfISaXpXE1qvNalca5Jwob6FjI4AoPlqMusJ6ftFE7IkkFoMhVLRgK+4Kx3gkzb8UZK5t5yTTvEmA==", + "dev": true, + "dependencies": { + "tslib": "^1.8.1" + }, + "peerDependencies": { + "typescript": ">=2.1.0 || >=2.1.0-dev || >=2.2.0-dev || >=2.3.0-dev || >=2.4.0-dev || >=2.5.0-dev || >=2.6.0-dev || >=2.7.0-dev || >=2.8.0-dev || >=2.9.0-dev || >= 3.0.0-dev || >= 3.1.0-dev" + } + }, + "node_modules/typescript": { + "version": "4.5.5", + "resolved": "https://registry.npmjs.org/typescript/-/typescript-4.5.5.tgz", + "integrity": "sha512-TCTIul70LyWe6IJWT8QSYeA54WQe8EjQFU4wY52Fasj5UKx88LNYKCgBEHcOMOrFF1rKGbD8v/xcNWVUq9SymA==", + "dev": true, + "bin": { + "tsc": "bin/tsc", + "tsserver": "bin/tsserver" + }, + "engines": { + "node": ">=4.2.0" + } + }, + "node_modules/uuid": { + "version": "3.4.0", + "resolved": "https://registry.npmjs.org/uuid/-/uuid-3.4.0.tgz", + "integrity": "sha512-HjSDRw6gZE5JMggctHBcjVak08+KEVhSIiDzFnT9S9aegmp85S/bReBVTb4QTFaRNptJ9kuYaNhnbNEOkbKb/A==", + "deprecated": "Please upgrade to version 7 or higher. Older versions may use Math.random() in certain circumstances, which is known to be problematic. See https://v8.dev/blog/math-random for details.", + "dev": true, + "bin": { + "uuid": "bin/uuid" + } + }, + "node_modules/wrappy": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", + "integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8=", + "dev": true + } + }, + "dependencies": { + "@babel/code-frame": { + "version": "7.16.7", + "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.16.7.tgz", + "integrity": "sha512-iAXqUn8IIeBTNd72xsFlgaXHkMBMt6y4HJp1tIaK465CWLT/fG1aqB7ykr95gHHmlBdGbFeWWfyB4NJJ0nmeIg==", + "dev": true, + "requires": { + "@babel/highlight": "^7.16.7" + } + }, + "@babel/helper-validator-identifier": { + "version": "7.16.7", + "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.16.7.tgz", + "integrity": "sha512-hsEnFemeiW4D08A5gUAZxLBTXpZ39P+a+DGDsHw1yxqyQ/jzFEnxf5uTEGp+3bzAbNOxU1paTgYS4ECU/IgfDw==", + "dev": true + }, + "@babel/highlight": { + "version": "7.16.10", + "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.16.10.tgz", + "integrity": "sha512-5FnTQLSLswEj6IkgVw5KusNUUFY9ZGqe/TRFnP/BKYHYgfh7tc+C7mwiy95/yNP7Dh9x580Vv8r7u7ZfTBFxdw==", + "dev": true, + "requires": { + "@babel/helper-validator-identifier": "^7.16.7", + "chalk": "^2.0.0", + "js-tokens": "^4.0.0" + } + }, + "@rocket.chat/apps-engine": { + "version": "1.30.0", + "resolved": "https://registry.npmjs.org/@rocket.chat/apps-engine/-/apps-engine-1.30.0.tgz", + "integrity": "sha512-04X4nQPgZEz9w4b/8zCyW+EVixfzdrugW4u6YUYnB4tc9lDALawSvhz88XlDGvKwbsUKFfSx6ejdhASwSssPcA==", + "dev": true, + "requires": { + "adm-zip": "^0.4.9", + "cryptiles": "^4.1.3", + "lodash.clonedeep": "^4.5.0", + "semver": "^5.5.0", + "stack-trace": "0.0.10", + "uuid": "^3.2.1" + } + }, + "@types/node": { + "version": "14.14.6", + "resolved": "https://registry.npmjs.org/@types/node/-/node-14.14.6.tgz", + "integrity": "sha512-6QlRuqsQ/Ox/aJEQWBEJG7A9+u7oSYl3mem/K8IzxXG/kAGbV1YPD9Bg9Zw3vyxC/YP+zONKwy8hGkSt1jxFMw==", + "dev": true + }, + "adm-zip": { + "version": "0.4.16", + "resolved": "https://registry.npmjs.org/adm-zip/-/adm-zip-0.4.16.tgz", + "integrity": "sha512-TFi4HBKSGfIKsK5YCkKaaFG2m4PEDyViZmEwof3MTIgzimHLto6muaHVpbrljdIvIrFZzEq/p4nafOeLcYegrg==", + "dev": true + }, + "ansi-styles": { + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", + "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", + "dev": true, + "requires": { + "color-convert": "^1.9.0" + } + }, + "argparse": { + "version": "1.0.10", + "resolved": "https://registry.npmjs.org/argparse/-/argparse-1.0.10.tgz", + "integrity": "sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg==", + "dev": true, + "requires": { + "sprintf-js": "~1.0.2" + } + }, + "balanced-match": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz", + "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==", + "dev": true + }, + "boom": { + "version": "7.3.0", + "resolved": "https://registry.npmjs.org/boom/-/boom-7.3.0.tgz", + "integrity": "sha512-Swpoyi2t5+GhOEGw8rEsKvTxFLIDiiKoUc2gsoV6Lyr43LHBIzch3k2MvYUs8RTROrIkVJ3Al0TkaOGjnb+B6A==", + "dev": true, + "requires": { + "hoek": "6.x.x" + } + }, + "brace-expansion": { + "version": "1.1.11", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", + "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", + "dev": true, + "requires": { + "balanced-match": "^1.0.0", + "concat-map": "0.0.1" + } + }, + "builtin-modules": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/builtin-modules/-/builtin-modules-1.1.1.tgz", + "integrity": "sha1-Jw8HbFpywC9bZaR9+Uxf46J4iS8=", + "dev": true + }, + "chalk": { + "version": "2.4.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", + "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", + "dev": true, + "requires": { + "ansi-styles": "^3.2.1", + "escape-string-regexp": "^1.0.5", + "supports-color": "^5.3.0" + } + }, + "color-convert": { + "version": "1.9.3", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", + "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==", + "dev": true, + "requires": { + "color-name": "1.1.3" + } + }, + "color-name": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", + "integrity": "sha1-p9BVi9icQveV3UIyj3QIMcpTvCU=", + "dev": true + }, + "commander": { + "version": "2.20.3", + "resolved": "https://registry.npmjs.org/commander/-/commander-2.20.3.tgz", + "integrity": "sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ==", + "dev": true + }, + "concat-map": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", + "integrity": "sha1-2Klr13/Wjfd5OnMDajug1UBdR3s=", + "dev": true + }, + "cryptiles": { + "version": "4.1.3", + "resolved": "https://registry.npmjs.org/cryptiles/-/cryptiles-4.1.3.tgz", + "integrity": "sha512-gT9nyTMSUC1JnziQpPbxKGBbUg8VL7Zn2NB4E1cJYvuXdElHrwxrV9bmltZGDzet45zSDGyYceueke1TjynGzw==", + "dev": true, + "requires": { + "boom": "7.x.x" + } + }, + "diff": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/diff/-/diff-4.0.2.tgz", + "integrity": "sha512-58lmxKSA4BNyLz+HHMUzlOEpg09FV+ev6ZMe3vJihgdxzgcwZ8VoEEPmALCZG9LmqfVoNMMKpttIYTVG6uDY7A==", + "dev": true + }, + "escape-string-regexp": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", + "integrity": "sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ=", + "dev": true + }, + "esprima": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/esprima/-/esprima-4.0.1.tgz", + "integrity": "sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A==", + "dev": true + }, + "fs.realpath": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", + "integrity": "sha1-FQStJSMVjKpA20onh8sBQRmU6k8=", + "dev": true + }, + "function-bind": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.1.tgz", + "integrity": "sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A==", + "dev": true + }, + "glob": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.0.tgz", + "integrity": "sha512-lmLf6gtyrPq8tTjSmrO94wBeQbFR3HbLHbuyD69wuyQkImp2hWqMGB47OX65FBkPffO641IP9jWa1z4ivqG26Q==", + "dev": true, + "requires": { + "fs.realpath": "^1.0.0", + "inflight": "^1.0.4", + "inherits": "2", + "minimatch": "^3.0.4", + "once": "^1.3.0", + "path-is-absolute": "^1.0.0" + } + }, + "has": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/has/-/has-1.0.3.tgz", + "integrity": "sha512-f2dvO0VU6Oej7RkWJGrehjbzMAjFp5/VKPp5tTpWIV4JHHZK1/BxbFRtf/siA2SWTe09caDmVtYYzWEIbBS4zw==", + "dev": true, + "requires": { + "function-bind": "^1.1.1" + } + }, + "has-flag": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", + "integrity": "sha1-tdRU3CGZriJWmfNGfloH87lVuv0=", + "dev": true + }, + "hoek": { + "version": "6.1.3", + "resolved": "https://registry.npmjs.org/hoek/-/hoek-6.1.3.tgz", + "integrity": "sha512-YXXAAhmF9zpQbC7LEcREFtXfGq5K1fmd+4PHkBq8NUqmzW3G+Dq10bI/i0KucLRwss3YYFQ0fSfoxBZYiGUqtQ==", + "dev": true + }, + "inflight": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", + "integrity": "sha1-Sb1jMdfQLQwJvJEKEHW6gWW1bfk=", + "dev": true, + "requires": { + "once": "^1.3.0", + "wrappy": "1" + } + }, + "inherits": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", + "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==", + "dev": true + }, + "is-core-module": { + "version": "2.8.1", + "resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.8.1.tgz", + "integrity": "sha512-SdNCUs284hr40hFTFP6l0IfZ/RSrMXF3qgoRHd3/79unUTvrFO/JoXwkGm+5J/Oe3E/b5GsnG330uUNgRpu1PA==", + "dev": true, + "requires": { + "has": "^1.0.3" + } + }, + "js-tokens": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz", + "integrity": "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==", + "dev": true + }, + "js-yaml": { + "version": "3.14.1", + "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.14.1.tgz", + "integrity": "sha512-okMH7OXXJ7YrN9Ok3/SXrnu4iX9yOk+25nqX4imS2npuvTYDmo/QEZoqwZkYaIDk3jVvBOTOIEgEhaLOynBS9g==", + "dev": true, + "requires": { + "argparse": "^1.0.7", + "esprima": "^4.0.0" + } + }, + "lodash.clonedeep": { + "version": "4.5.0", + "resolved": "https://registry.npmjs.org/lodash.clonedeep/-/lodash.clonedeep-4.5.0.tgz", + "integrity": "sha1-4j8/nE+Pvd6HJSnBBxhXoIblzO8=", + "dev": true + }, + "minimatch": { + "version": "3.0.5", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.0.5.tgz", + "integrity": "sha512-tUpxzX0VAzJHjLu0xUfFv1gwVp9ba3IOuRAVH2EGuRW8a5emA2FlACLqiT/lDVtS1W+TGNwqz3sWaNyLgDJWuw==", + "dev": true, + "requires": { + "brace-expansion": "^1.1.7" + } + }, + "minimist": { + "version": "1.2.5", + "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.5.tgz", + "integrity": "sha512-FM9nNUYrRBAELZQT3xeZQ7fmMOBg6nWNmJKTcgsJeaLstP/UODVpGsr5OhXhhXg6f+qtJ8uiZ+PUxkDWcgIXLw==", + "dev": true + }, + "mkdirp": { + "version": "0.5.5", + "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.5.tgz", + "integrity": "sha512-NKmAlESf6jMGym1++R0Ra7wvhV+wFW63FaSOFPwRahvea0gMUcGUhVeAg/0BC0wiv9ih5NYPB1Wn1UEI1/L+xQ==", + "dev": true, + "requires": { + "minimist": "^1.2.5" + } + }, + "once": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", + "integrity": "sha1-WDsap3WWHUsROsF9nFC6753Xa9E=", + "dev": true, + "requires": { + "wrappy": "1" + } + }, + "path-is-absolute": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz", + "integrity": "sha1-F0uSaHNVNP+8es5r9TpanhtcX18=", + "dev": true + }, + "path-parse": { + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.7.tgz", + "integrity": "sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==", + "dev": true + }, + "resolve": { + "version": "1.22.0", + "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.22.0.tgz", + "integrity": "sha512-Hhtrw0nLeSrFQ7phPp4OOcVjLPIeMnRlr5mcnVuMe7M/7eBn98A3hmFRLoFo3DLZkivSYwhRUJTyPyWAk56WLw==", + "dev": true, + "requires": { + "is-core-module": "^2.8.1", + "path-parse": "^1.0.7", + "supports-preserve-symlinks-flag": "^1.0.0" + } + }, + "scimmy": { + "version": "0.10.0", + "resolved": "https://registry.npmjs.org/scimmy/-/scimmy-0.10.0.tgz", + "integrity": "sha512-QYCwrXJnWet4ZIiruCKcks8rddO8IqIIBr4NgXUnE+l1sFEC6emCR3LyqENy/9eVe8lVaLetMho1oJ3YNHpNaA==" + }, + "semver": { + "version": "5.7.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", + "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==", + "dev": true + }, + "sprintf-js": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.0.3.tgz", + "integrity": "sha1-BOaSb2YolTVPPdAVIDYzuFcpfiw=", + "dev": true + }, + "stack-trace": { + "version": "0.0.10", + "resolved": "https://registry.npmjs.org/stack-trace/-/stack-trace-0.0.10.tgz", + "integrity": "sha1-VHxws0fo0ytOEI6hoqFZ5f3eGcA=", + "dev": true + }, + "supports-color": { + "version": "5.5.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", + "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", + "dev": true, + "requires": { + "has-flag": "^3.0.0" + } + }, + "supports-preserve-symlinks-flag": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/supports-preserve-symlinks-flag/-/supports-preserve-symlinks-flag-1.0.0.tgz", + "integrity": "sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w==", + "dev": true + }, + "tslib": { + "version": "1.14.1", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.14.1.tgz", + "integrity": "sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg==", + "dev": true + }, + "tslint": { + "version": "5.20.1", + "resolved": "https://registry.npmjs.org/tslint/-/tslint-5.20.1.tgz", + "integrity": "sha512-EcMxhzCFt8k+/UP5r8waCf/lzmeSyVlqxqMEDQE7rWYiQky8KpIBz1JAoYXfROHrPZ1XXd43q8yQnULOLiBRQg==", + "dev": true, + "requires": { + "@babel/code-frame": "^7.0.0", + "builtin-modules": "^1.1.1", + "chalk": "^2.3.0", + "commander": "^2.12.1", + "diff": "^4.0.1", + "glob": "^7.1.1", + "js-yaml": "^3.13.1", + "minimatch": "^3.0.4", + "mkdirp": "^0.5.1", + "resolve": "^1.3.2", + "semver": "^5.3.0", + "tslib": "^1.8.0", + "tsutils": "^2.29.0" + } + }, + "tsutils": { + "version": "2.29.0", + "resolved": "https://registry.npmjs.org/tsutils/-/tsutils-2.29.0.tgz", + "integrity": "sha512-g5JVHCIJwzfISaXpXE1qvNalca5Jwob6FjI4AoPlqMusJ6ftFE7IkkFoMhVLRgK+4Kx3gkzb8UZK5t5yTTvEmA==", + "dev": true, + "requires": { + "tslib": "^1.8.1" + } + }, + "typescript": { + "version": "4.5.5", + "resolved": "https://registry.npmjs.org/typescript/-/typescript-4.5.5.tgz", + "integrity": "sha512-TCTIul70LyWe6IJWT8QSYeA54WQe8EjQFU4wY52Fasj5UKx88LNYKCgBEHcOMOrFF1rKGbD8v/xcNWVUq9SymA==", + "dev": true + }, + "uuid": { + "version": "3.4.0", + "resolved": "https://registry.npmjs.org/uuid/-/uuid-3.4.0.tgz", + "integrity": "sha512-HjSDRw6gZE5JMggctHBcjVak08+KEVhSIiDzFnT9S9aegmp85S/bReBVTb4QTFaRNptJ9kuYaNhnbNEOkbKb/A==", + "dev": true + }, + "wrappy": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", + "integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8=", + "dev": true + } + } +} diff --git a/package.json b/package.json new file mode 100644 index 0000000..a32d10c --- /dev/null +++ b/package.json @@ -0,0 +1,11 @@ +{ + "devDependencies": { + "@rocket.chat/apps-engine": "^1.19.0", + "@types/node": "14.14.6", + "tslint": "^5.10.0", + "typescript": "^4.0.5" + }, + "dependencies": { + "scimmy": "^0.10.0" + } +} diff --git a/rest.ts b/rest.ts new file mode 100644 index 0000000..c18c9db --- /dev/null +++ b/rest.ts @@ -0,0 +1,43 @@ +interface IUserCreate { + email: string; + name: string; + password: string; + username: string; + active?: boolean; + roles?: Array; + joinDefaultChannels?: boolean; + requirePasswordChange?: boolean; + sendWelcomeEmail?: boolean; + verified?: boolean; + customFields?: any; +} + +interface IUserUpdate { + userId: string; + data: { + email?: string; + name?: string; + password?: string; + username?: string; + active?: boolean; + roles?: Array; + joinDefaultChannels?: boolean; + requirePasswordChange?: boolean; + sendWelcomeEmail?: boolean; + verified?: boolean; + customFields?: any; + }; +} + +interface IUserDelete { + userId: string; + confirmRelinquish?: boolean; +} + +interface IUser { + _id: string; + emails: Array<{ address: string; verified: boolean }>; + name: string; + username: string; + active?: boolean; +} diff --git a/scim.ts b/scim.ts new file mode 100644 index 0000000..7dd3c48 --- /dev/null +++ b/scim.ts @@ -0,0 +1,16 @@ +interface ISCIMUser { + id: string; + externalId: string; + userName: string; + name?: { + familyName: string; + givenName: string; + }; + displayName: string; + active: boolean; + emails: Array<{ + value: string; + type: string; + primary: boolean; + }>; +} \ No newline at end of file diff --git a/tsconfig.json b/tsconfig.json new file mode 100644 index 0000000..bc202c6 --- /dev/null +++ b/tsconfig.json @@ -0,0 +1,15 @@ +{ + "compilerOptions": { + "target": "ES2017", + "module": "CommonJS", + "moduleResolution": "Node", + "declaration": false, + "noImplicitAny": false, + "removeComments": true, + "strictNullChecks": true, + "noImplicitReturns": true, + "emitDecoratorMetadata": true, + "experimentalDecorators": true + }, + "include": ["**/*.ts"] +} diff --git a/tslint.json b/tslint.json new file mode 100644 index 0000000..8db60f5 --- /dev/null +++ b/tslint.json @@ -0,0 +1,14 @@ +{ + "extends": "tslint:recommended", + "rules": { + "array-type": [true, "generic"], + "member-access": true, + "no-console": [false], + "no-duplicate-variable": true, + "object-literal-sort-keys": false, + "max-line-length": [true, { + "limit": 160, + "ignore-pattern": "^import | *export .*? {" + }] + } +}