diff --git a/lib/RealTimeAPI.d.ts b/lib/RealTimeAPI.d.ts index a2143d8..40e504d 100644 --- a/lib/RealTimeAPI.d.ts +++ b/lib/RealTimeAPI.d.ts @@ -47,4 +47,20 @@ export declare class RealTimeAPI { * keepAlive, Ping and Pong to the Rocket.Chat Server to Keep the Connection Alive. */ keepAlive(): void; + /** + * Login with Username and Password + */ + login(username: string, password: string): Observable; + /** + * Login with Authentication Token + */ + loginWithAuthToken(authToken: string): Observable; + /** + * Login with OAuth, with Client Token and Client Secret + */ + loginWithOAuth(credToken: string, credSecret: string): Observable; + /** + * getLoginObservable + */ + getLoginObservable(id: string): Observable; } diff --git a/lib/RealTimeAPI.js b/lib/RealTimeAPI.js index 87a58ed..78bc466 100644 --- a/lib/RealTimeAPI.js +++ b/lib/RealTimeAPI.js @@ -4,6 +4,8 @@ */ Object.defineProperty(exports, "__esModule", { value: true }); var rxjs_1 = require("rxjs"); +var uuid_1 = require("uuid"); +var crypto_js_1 = require("crypto-js"); var RealTimeAPI = (function () { function RealTimeAPI(param) { switch (typeof param) { @@ -81,6 +83,75 @@ var RealTimeAPI = (function () { var _this = this; this.getObservableFilteredByMessageType("ping").subscribe(function (message) { return _this.sendMessage({ msg: "pong" }); }); }; + /** + * Login with Username and Password + */ + RealTimeAPI.prototype.login = function (username, password) { + var id = uuid_1.v1(); + this.sendMessage({ + "msg": "method", + "method": "login", + "id": id, + "params": [ + { + "user": { "username": username }, + "password": { + "digest": crypto_js_1.SHA256(password).toString(), + "algorithm": "sha-256" + } + } + ] + }); + return this.getLoginObservable(id); + }; + /** + * Login with Authentication Token + */ + RealTimeAPI.prototype.loginWithAuthToken = function (authToken) { + var id = uuid_1.v1(); + this.sendMessage({ + "msg": "method", + "method": "login", + "id": id, + "params": [ + { "resume": authToken } + ] + }); + return this.getLoginObservable(id); + }; + /** + * Login with OAuth, with Client Token and Client Secret + */ + RealTimeAPI.prototype.loginWithOAuth = function (credToken, credSecret) { + var id = uuid_1.v1(); + this.sendMessage({ + "msg": "method", + "method": "login", + "id": id, + "params": [ + { + "oauth": { + "credentialToken": credToken, + "credentialSecret": credSecret + } + } + ] + }); + return this.getLoginObservable(id); + }; + /** + * getLoginObservable + */ + RealTimeAPI.prototype.getLoginObservable = function (id) { + var resultObservable = this.getObservableFilteredByID(id); + var resultId; + resultObservable.subscribe(function (message) { + if ((message.id === id && message.msg === "result" && !message.error)) + resultId = message.result.id; + }); + var addedObservable = this.getObservable().buffer(resultObservable).find(function (obj) { return obj.find(function (msg) { return msg.id === resultId && resultId !== undefined; }) !== undefined; }).map(function (obj) { return obj[0]; }); + return rxjs_1.Observable.merge(resultObservable, addedObservable); + }; return RealTimeAPI; }()); exports.RealTimeAPI = RealTimeAPI; diff --git a/lib/RealTimeAPI.js.map b/lib/RealTimeAPI.js.map index fd701b7..5e9d337 100644 --- a/lib/RealTimeAPI.js.map +++ b/lib/RealTimeAPI.js.map @@ -1 +1 @@ -{"version":3,"file":"RealTimeAPI.js","sourceRoot":"","sources":["../src/RealTimeAPI.ts"],"names":[],"mappings":"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"} \ No newline at end of file +{"version":3,"file":"RealTimeAPI.js","sourceRoot":"","sources":["../src/RealTimeAPI.ts"],"names":[],"mappings":"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"} \ No newline at end of file diff --git a/package-lock.json b/package-lock.json index ebf3d74..88bab63 100644 --- a/package-lock.json +++ b/package-lock.json @@ -3,6 +3,29 @@ "version": "0.0.1", "lockfileVersion": 1, "dependencies": { + "@types/crypto-js": { + "version": "3.1.33", + "resolved": "https://registry.npmjs.org/@types/crypto-js/-/crypto-js-3.1.33.tgz", + "integrity": "sha1-fmyRYDUz4M2fJ5qEBam543mIDF0=", + "dev": true + }, + "@types/node": { + "version": "8.0.1", + "resolved": "https://registry.npmjs.org/@types/node/-/node-8.0.1.tgz", + "integrity": "sha512-bys2VRs6H7HP8S26aHgPWSiSX7q81TToe5HSSvl5bQjoSElQ2SwbGw2p6/DSDb7Vr0oKhewFao9ZuTn8DSag9Q==", + "dev": true + }, + "@types/uuid": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/@types/uuid/-/uuid-3.0.0.tgz", + "integrity": "sha512-CGaBAcUB4o+YTaUBZ2VfBc7PcIZXwHflZs4FDtr5Kk7MpAl0PVfH7W/VqoHH+OAG41d9YSCV8eWDfz/KKqVm+A==", + "dev": true + }, + "crypto-js": { + "version": "3.1.9-1", + "resolved": "https://registry.npmjs.org/crypto-js/-/crypto-js-3.1.9-1.tgz", + "integrity": "sha1-/aGedh/Ad+Af+/3G6f38WeiAbNg=" + }, "rxjs": { "version": "5.4.1", "resolved": "https://registry.npmjs.org/rxjs/-/rxjs-5.4.1.tgz", @@ -18,6 +41,11 @@ "resolved": "https://registry.npmjs.org/typescript/-/typescript-2.3.4.tgz", "integrity": "sha1-PTgyGCgjHkNPKHUUlZw3qCtin0I=", "dev": true + }, + "uuid": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/uuid/-/uuid-3.1.0.tgz", + "integrity": "sha512-DIWtzUkw04M4k3bf1IcpS2tngXEL26YUD2M0tMDUpnUrz2hgzUBlD55a4FjdLGPvfHxS6uluGWvaVEqgBcVa+g==" } } } diff --git a/package.json b/package.json index 653ff03..dcc94a2 100644 --- a/package.json +++ b/package.json @@ -11,9 +11,13 @@ "author": "Viraj Trivedi ", "license": "MIT", "dependencies": { - "rxjs": "^5.4.1" + "crypto-js": "^3.1.9-1", + "rxjs": "^5.4.1", + "uuid": "^3.1.0" }, "devDependencies": { + "@types/crypto-js": "^3.1.33", + "@types/uuid": "^3.0.0", "typescript": "^2.3.4" }, "bugs": { diff --git a/src/RealTimeAPI.ts b/src/RealTimeAPI.ts index 4ed8413..f832d8f 100644 --- a/src/RealTimeAPI.ts +++ b/src/RealTimeAPI.ts @@ -4,6 +4,8 @@ import { Observable } from "rxjs"; import { WebSocketSubject } from 'rxjs/observable/dom/WebSocketSubject'; +import { v1 as uuid } from "uuid"; +import { SHA256 } from "crypto-js"; export class RealTimeAPI { public url: string; @@ -97,4 +99,80 @@ export class RealTimeAPI { message => this.sendMessage({ msg: "pong" }) ); } + + /** + * Login with Username and Password + */ + public login(username: string, password: string) { + let id = uuid(); + this.sendMessage({ + "msg": "method", + "method": "login", + "id": id, + "params": [ + { + "user": { "username": username }, + "password": { + "digest": SHA256(password).toString(), + "algorithm": "sha-256" + } + } + ] + }); + return this.getLoginObservable(id); + } + + /** + * Login with Authentication Token + */ + public loginWithAuthToken(authToken: string) { + let id = uuid(); + this.sendMessage({ + "msg": "method", + "method": "login", + "id": id, + "params": [ + { "resume": authToken } + ] + }); + return this.getLoginObservable(id); + } + + /** + * Login with OAuth, with Client Token and Client Secret + */ + public loginWithOAuth(credToken: string, credSecret: string) { + let id = uuid(); + this.sendMessage({ + "msg": "method", + "method": "login", + "id": id, + "params": [ + { + "oauth": { + "credentialToken": credToken, + "credentialSecret": credSecret + } + } + ] + }); + return this.getLoginObservable(id); + } + + /** + * getLoginObservable + */ + public getLoginObservable(id: string) { + let resultObservable = this.getObservableFilteredByID(id); + let resultId: string; + resultObservable.subscribe( + (message: any) => { + if ((message.id === id && message.msg === "result" && !message.error)) + resultId = message.result.id; + } + ); + + let addedObservable = this.getObservable().buffer(resultObservable).find(obj => obj.find(msg => msg.id === resultId && resultId !== undefined) !== undefined).map(obj => obj[0]); + return Observable.merge(resultObservable, addedObservable); + } } \ No newline at end of file diff --git a/yarn.lock b/yarn.lock index 560467e..c0cf536 100644 --- a/yarn.lock +++ b/yarn.lock @@ -2,6 +2,24 @@ # yarn lockfile v1 +"@types/crypto-js@^3.1.33": + version "3.1.33" + resolved "https://registry.yarnpkg.com/@types/crypto-js/-/crypto-js-3.1.33.tgz#7e6c91603533e0cd9f279a8405a9b9e379880c5d" + +"@types/node@*": + version "8.0.1" + resolved "https://registry.yarnpkg.com/@types/node/-/node-8.0.1.tgz#89c271e0c3b9ebb6a3756dd601336970b6228b77" + +"@types/uuid@^3.0.0": + version "3.0.0" + resolved "https://registry.yarnpkg.com/@types/uuid/-/uuid-3.0.0.tgz#be93b14bcf97f59c079a9e58754960b5efd946c3" + dependencies: + "@types/node" "*" + +crypto-js@^3.1.9-1: + version "3.1.9-1" + resolved "https://registry.yarnpkg.com/crypto-js/-/crypto-js-3.1.9-1.tgz#fda19e761fc077e01ffbfdc6e9fdfc59e8806cd8" + rxjs@^5.4.1: version "5.4.1" resolved "https://registry.yarnpkg.com/rxjs/-/rxjs-5.4.1.tgz#b62f757f279445d265a18a58fb0a70dc90e91626" @@ -15,3 +33,7 @@ symbol-observable@^1.0.1: typescript@^2.3.4: version "2.3.4" resolved "https://registry.yarnpkg.com/typescript/-/typescript-2.3.4.tgz#3d38321828231e434f287514959c37a82b629f42" + +uuid@^3.1.0: + version "3.1.0" + resolved "https://registry.yarnpkg.com/uuid/-/uuid-3.1.0.tgz#3dd3d3e790abc24d7b0d3a034ffababe28ebbc04"