UNPKG

@ringcentral/sdk

Version:

- [Installation](#installation) - [Getting Started](#getting-started) - [API Calls](#api-calls) - [Advanced SDK Configuration & Polyfills](#advanced-sdk-configuration--polyfills) - [Making telephony calls](#making-telephony-calls) - [Call management using

644 lines 31.8 kB
"use strict"; var __extends = (this && this.__extends) || (function () { var extendStatics = function (d, b) { extendStatics = Object.setPrototypeOf || ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) || function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; }; return extendStatics(d, b); }; return function (d, b) { extendStatics(d, b); function __() { this.constructor = d; } d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __()); }; })(); var __assign = (this && this.__assign) || function () { __assign = Object.assign || function(t) { for (var s, i = 1, n = arguments.length; i < n; i++) { s = arguments[i]; for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p)) t[p] = s[p]; } return t; }; return __assign.apply(this, arguments); }; var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) { 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) : new P(function (resolve) { resolve(result.value); }).then(fulfilled, rejected); } step((generator = generator.apply(thisArg, _arguments || [])).next()); }); }; var __generator = (this && this.__generator) || function (thisArg, body) { var _ = { label: 0, sent: function() { if (t[0] & 1) throw t[1]; return t[1]; }, trys: [], ops: [] }, f, y, t, g; return g = { next: verb(0), "throw": verb(1), "return": verb(2) }, typeof Symbol === "function" && (g[Symbol.iterator] = function() { return this; }), g; function verb(n) { return function (v) { return step([n, v]); }; } function step(op) { if (f) throw new TypeError("Generator is already executing."); while (_) try { if (f = 1, y && (t = op[0] & 2 ? y["return"] : op[0] ? y["throw"] || ((t = y["return"]) && t.call(y), 0) : y.next) && !(t = t.call(y, op[1])).done) return t; if (y = 0, t) op = [op[0] & 2, t.value]; switch (op[0]) { case 0: case 1: t = op; break; case 4: _.label++; return { value: op[1], done: false }; case 5: _.label++; y = op[1]; op = [0]; continue; case 7: op = _.ops.pop(); _.trys.pop(); continue; default: if (!(t = _.trys, t = t.length > 0 && t[t.length - 1]) && (op[0] === 6 || op[0] === 2)) { _ = 0; continue; } if (op[0] === 3 && (!t || (op[1] > t[0] && op[1] < t[3]))) { _.label = op[1]; break; } if (op[0] === 6 && _.label < t[1]) { _.label = t[1]; t = op; break; } if (t && _.label < t[2]) { _.label = t[2]; _.ops.push(op); break; } if (t[2]) _.ops.pop(); _.trys.pop(); continue; } op = body.call(thisArg, _); } catch (e) { op = [6, e]; y = 0; } finally { f = t = 0; } if (op[0] & 5) throw op[1]; return { value: op[0] ? op[1] : void 0, done: true }; } }; var __rest = (this && this.__rest) || function (s, e) { var t = {}; for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p) && e.indexOf(p) < 0) t[p] = s[p]; if (s != null && typeof Object.getOwnPropertySymbols === "function") for (var i = 0, p = Object.getOwnPropertySymbols(s); i < p.length; i++) if (e.indexOf(p[i]) < 0) t[p[i]] = s[p[i]]; return t; }; var __importDefault = (this && this.__importDefault) || function (mod) { return (mod && mod.__esModule) ? mod : { "default": mod }; }; var __importStar = (this && this.__importStar) || function (mod) { if (mod && mod.__esModule) return mod; var result = {}; if (mod != null) for (var k in mod) if (Object.hasOwnProperty.call(mod, k)) result[k] = mod[k]; result["default"] = mod; return result; }; Object.defineProperty(exports, "__esModule", { value: true }); var events_1 = __importDefault(require("events")); var qs = __importStar(require("querystring")); var Auth_1 = __importDefault(require("./Auth")); var Constants = __importStar(require("../core/Constants")); var Client_1 = __importDefault(require("../http/Client")); var delay = function (timeout) { return new Promise(function (resolve, reject) { setTimeout(function () { resolve(null); }, timeout); }); }; var getParts = function (url, separator) { return url.split(separator).reverse()[0]; }; var events; (function (events) { events["beforeLogin"] = "beforeLogin"; events["loginSuccess"] = "loginSuccess"; events["loginError"] = "loginError"; events["beforeRefresh"] = "beforeRefresh"; events["refreshSuccess"] = "refreshSuccess"; events["refreshError"] = "refreshError"; events["beforeLogout"] = "beforeLogout"; events["logoutSuccess"] = "logoutSuccess"; events["logoutError"] = "logoutError"; events["rateLimitError"] = "rateLimitError"; })(events = exports.events || (exports.events = {})); var Platform = /** @class */ (function (_super) { __extends(Platform, _super); function Platform(_a) { var server = _a.server, clientId = _a.clientId, clientSecret = _a.clientSecret, _b = _a.redirectUri, redirectUri = _b === void 0 ? '' : _b, _c = _a.refreshDelayMs, refreshDelayMs = _c === void 0 ? 100 : _c, _d = _a.clearCacheOnRefreshError, clearCacheOnRefreshError = _d === void 0 ? true : _d, _e = _a.appName, appName = _e === void 0 ? '' : _e, _f = _a.appVersion, appVersion = _f === void 0 ? '' : _f, externals = _a.externals, cache = _a.cache, client = _a.client, refreshHandicapMs = _a.refreshHandicapMs, _g = _a.tokenEndpoint, tokenEndpoint = _g === void 0 ? '/restapi/oauth/token' : _g, _h = _a.revokeEndpoint, revokeEndpoint = _h === void 0 ? '/restapi/oauth/revoke' : _h, _j = _a.authorizeEndpoint, authorizeEndpoint = _j === void 0 ? '/restapi/oauth/authorize' : _j, _k = _a.authProxy, authProxy = _k === void 0 ? false : _k, _l = _a.urlPrefix, urlPrefix = _l === void 0 ? '' : _l; var _this = _super.call(this) || this; _this.events = events; _this._server = server; _this._clientId = clientId; _this._clientSecret = clientSecret; _this._redirectUri = redirectUri; _this._refreshDelayMs = refreshDelayMs; _this._clearCacheOnRefreshError = clearCacheOnRefreshError; _this._authProxy = authProxy; _this._urlPrefix = urlPrefix; _this._userAgent = (appName ? appName + (appVersion ? "/" + appVersion : '') + " " : '') + "RCJSSDK/" + Constants.version; _this._externals = externals; _this._cache = cache; _this._client = client; _this._refreshPromise = null; _this._auth = new Auth_1.default({ cache: _this._cache, cacheId: Platform._cacheId, refreshHandicapMs: refreshHandicapMs, }); _this._tokenEndpoint = tokenEndpoint; _this._revokeEndpoint = revokeEndpoint; _this._authorizeEndpoint = authorizeEndpoint; return _this; } Platform.prototype.on = function (event, listener) { return _super.prototype.on.call(this, event, listener); }; Platform.prototype.auth = function () { return this._auth; }; Platform.prototype.createUrl = function (path, options) { if (path === void 0) { path = ''; } if (options === void 0) { options = {}; } var builtUrl = ''; var hasHttp = path.startsWith('http://') || path.startsWith('https://'); if (options.addServer && !hasHttp) builtUrl += this._server; if (this._urlPrefix) builtUrl += this._urlPrefix; builtUrl += path; if (options.addMethod) builtUrl += (path.includes('?') ? '&' : '?') + "_method=" + options.addMethod; return builtUrl; }; Platform.prototype.signUrl = function (path) { return __awaiter(this, void 0, void 0, function () { var _a; return __generator(this, function (_b) { switch (_b.label) { case 0: _a = path + (path.includes('?') ? '&' : '?') + "access_token="; return [4 /*yield*/, this._auth.data()]; case 1: return [2 /*return*/, _a + (_b.sent()).access_token]; } }); }); }; Platform.prototype.loginUrl = function (_a) { var _b = _a === void 0 ? {} : _a, implicit = _b.implicit, state = _b.state, brandId = _b.brandId, display = _b.display, prompt = _b.prompt, uiOptions = _b.uiOptions, uiLocales = _b.uiLocales, localeId = _b.localeId; return this.createUrl(this._authorizeEndpoint + "?" + qs.stringify({ response_type: implicit ? 'token' : 'code', redirect_uri: this._redirectUri, client_id: this._clientId, state: state, brand_id: brandId, display: display, prompt: prompt, ui_options: uiOptions, ui_locales: uiLocales, localeId: localeId, }), { addServer: true }); }; /** * @param {string} url * @return {Object} */ Platform.prototype.parseLoginRedirect = function (url) { var response = (url.startsWith('#') && getParts(url, '#')) || (url.startsWith('?') && getParts(url, '?')) || null; if (!response) throw new Error('Unable to parse response'); var queryString = qs.parse(response); if (!queryString) throw new Error('Unable to parse response'); var error = queryString.error_description || queryString.error; if (error) { var e = new Error(error.toString()); e.error = queryString.error; throw e; } return queryString; }; /** * Convenience method to handle 3-legged OAuth * * Attention! This is an experimental method and it's signature and behavior may change without notice. */ Platform.prototype.loginWindow = function (_a) { var _this = this; var url = _a.url, _b = _a.width, width = _b === void 0 ? 400 : _b, _c = _a.height, height = _c === void 0 ? 600 : _c, _d = _a.origin, origin = _d === void 0 ? window.location.origin : _d, _e = _a.property, property = _e === void 0 ? Constants.authResponseProperty : _e, _f = _a.target, target = _f === void 0 ? '_blank' : _f; return new Promise(function (resolve, reject) { if (typeof window === 'undefined') throw new Error('This method can be used only in browser'); if (!url) throw new Error('Missing mandatory URL parameter'); var dualScreenLeft = window.screenLeft !== undefined ? window.screenLeft : 0; var dualScreenTop = window.screenTop !== undefined ? window.screenTop : 0; var screenWidth = screen.width; var screenHeight = screen.height; var left = screenWidth / 2 - width / 2 + dualScreenLeft; var top = screenHeight / 2 - height / 2 + dualScreenTop; var win = window.open(url, '_blank', target === '_blank' ? "scrollbars=yes, status=yes, width=" + width + ", height=" + height + ", left=" + left + ", top=" + top : ''); if (!win) { throw new Error('Could not open login window. Please allow popups for this site'); } if (win.focus) win.focus(); var eventListener = function (e) { try { if (e.origin !== origin) return; if (!e.data || !e.data[property]) return; // keep waiting win.close(); window.addEventListener('message', eventListener); var loginOptions = _this.parseLoginRedirect(e.data[property]); if (!loginOptions.code && !loginOptions.access_token) throw new Error('No authorization code or token'); resolve(loginOptions); } catch (e) { reject(e); } }; window.addEventListener('message', eventListener, false); }); }; /** * @return {Promise<boolean>} */ Platform.prototype.loggedIn = function () { return __awaiter(this, void 0, void 0, function () { var e_1; return __generator(this, function (_a) { switch (_a.label) { case 0: _a.trys.push([0, 5, , 6]); if (!this._authProxy) return [3 /*break*/, 2]; return [4 /*yield*/, this.get('/restapi/v1.0/client-info')]; case 1: _a.sent(); // we only can determine the status if we actually make request return [3 /*break*/, 4]; case 2: return [4 /*yield*/, this.ensureLoggedIn()]; case 3: _a.sent(); _a.label = 4; case 4: return [2 /*return*/, true]; case 5: e_1 = _a.sent(); return [2 /*return*/, false]; case 6: return [2 /*return*/]; } }); }); }; Platform.prototype.login = function (_a) { if (_a === void 0) { _a = {}; } var username = _a.username, password = _a.password, _b = _a.extension, extension = _b === void 0 ? '' : _b, code = _a.code, access_token_ttl = _a.access_token_ttl, refresh_token_ttl = _a.refresh_token_ttl, access_token = _a.access_token, endpoint_id = _a.endpoint_id, options = __rest(_a, ["username", "password", "extension", "code", "access_token_ttl", "refresh_token_ttl", "access_token", "endpoint_id"]); return __awaiter(this, void 0, void 0, function () { var body, response, json, e_2; return __generator(this, function (_c) { switch (_c.label) { case 0: _c.trys.push([0, 6, , 9]); this.emit(this.events.beforeLogin); body = {}; response = null; json = void 0; if (!access_token) return [3 /*break*/, 1]; //TODO Potentially make a request to /oauth/tokeninfo json = __assign({ access_token: access_token }, options); return [3 /*break*/, 4]; case 1: if (!code) { body.grant_type = 'password'; body.username = username; body.password = password; body.extension = extension; } else if (code) { //@see https://developers.ringcentral.com/legacy-api-reference/index.html#!#RefAuthorizationCodeFlow body.grant_type = 'authorization_code'; body.code = code; body.redirect_uri = this._redirectUri; } if (access_token_ttl) body.access_token_ttl = access_token_ttl; if (refresh_token_ttl) body.refresh_token_ttl = refresh_token_ttl; if (endpoint_id) body.endpoint_id = endpoint_id; return [4 /*yield*/, this._tokenRequest(this._tokenEndpoint, body)]; case 2: response = _c.sent(); return [4 /*yield*/, response.clone().json()]; case 3: json = _c.sent(); _c.label = 4; case 4: return [4 /*yield*/, this._auth.setData(json)]; case 5: _c.sent(); this.emit(this.events.loginSuccess, response); return [2 /*return*/, response]; case 6: e_2 = _c.sent(); if (!this._clearCacheOnRefreshError) return [3 /*break*/, 8]; return [4 /*yield*/, this._cache.clean()]; case 7: _c.sent(); _c.label = 8; case 8: this.emit(this.events.loginError, e_2); throw e_2; case 9: return [2 /*return*/]; } }); }); }; Platform.prototype._refresh = function () { return __awaiter(this, void 0, void 0, function () { var authData, res, json, e_3; return __generator(this, function (_a) { switch (_a.label) { case 0: _a.trys.push([0, 8, , 11]); this.emit(this.events.beforeRefresh); return [4 /*yield*/, delay(this._refreshDelayMs)]; case 1: _a.sent(); return [4 /*yield*/, this.auth().data()]; case 2: authData = _a.sent(); // Perform sanity checks if (!authData.refresh_token) throw new Error('Refresh token is missing'); if (!this._auth.refreshTokenValid()) throw new Error('Refresh token has expired'); return [4 /*yield*/, this._tokenRequest(this._tokenEndpoint, { grant_type: 'refresh_token', refresh_token: authData.refresh_token, access_token_ttl: authData.expires_in + 1, refresh_token_ttl: authData.refresh_token_expires_in + 1, })]; case 3: res = _a.sent(); return [4 /*yield*/, res.clone().json()]; case 4: json = _a.sent(); if (!!json.access_token) return [3 /*break*/, 6]; return [4 /*yield*/, this._client.makeError(new Error('Malformed OAuth response'), res)]; case 5: throw _a.sent(); case 6: return [4 /*yield*/, this._auth.setData(json)]; case 7: _a.sent(); this.emit(this.events.refreshSuccess, res); return [2 /*return*/, res]; case 8: e_3 = _a.sent(); if (!this._clearCacheOnRefreshError) return [3 /*break*/, 10]; return [4 /*yield*/, this._cache.clean()]; case 9: _a.sent(); _a.label = 10; case 10: this.emit(this.events.refreshError, e_3); throw e_3; case 11: return [2 /*return*/]; } }); }); }; Platform.prototype.refresh = function () { return __awaiter(this, void 0, void 0, function () { var _this = this; return __generator(this, function (_a) { if (this._authProxy) { throw new Error('Refresh is not supported in Auth Proxy mode'); } if (!this._refreshPromise) { this._refreshPromise = (function () { return __awaiter(_this, void 0, void 0, function () { var res, e_4; return __generator(this, function (_a) { switch (_a.label) { case 0: _a.trys.push([0, 2, , 3]); return [4 /*yield*/, this._refresh()]; case 1: res = _a.sent(); this._refreshPromise = null; return [2 /*return*/, res]; case 2: e_4 = _a.sent(); this._refreshPromise = null; throw e_4; case 3: return [2 /*return*/]; } }); }); })(); } return [2 /*return*/, this._refreshPromise]; }); }); }; Platform.prototype.logout = function () { return __awaiter(this, void 0, void 0, function () { var res, _a, _b, _c, e_5; return __generator(this, function (_d) { switch (_d.label) { case 0: if (this._authProxy) { throw new Error('Logout is not supported in Auth Proxy mode'); } _d.label = 1; case 1: _d.trys.push([1, 6, , 7]); this.emit(this.events.beforeLogout); res = null; if (!(this._revokeEndpoint && this._clientSecret)) return [3 /*break*/, 4]; _a = this._tokenRequest; _b = [this._revokeEndpoint]; _c = {}; return [4 /*yield*/, this._auth.data()]; case 2: return [4 /*yield*/, _a.apply(this, _b.concat([(_c.token = (_d.sent()).access_token, _c)]))]; case 3: res = _d.sent(); _d.label = 4; case 4: return [4 /*yield*/, this._cache.clean()]; case 5: _d.sent(); this.emit(this.events.logoutSuccess, res); return [2 /*return*/, res]; case 6: e_5 = _d.sent(); this.emit(this.events.logoutError, e_5); throw e_5; case 7: return [2 /*return*/]; } }); }); }; Platform.prototype.inflateRequest = function (request, options) { if (options === void 0) { options = {}; } return __awaiter(this, void 0, void 0, function () { var _a, _b, _c; return __generator(this, function (_d) { switch (_d.label) { case 0: options = options || {}; request.headers.set('X-User-Agent', this._userAgent); if (options.skipAuthCheck) return [2 /*return*/, request]; return [4 /*yield*/, this.ensureLoggedIn()]; case 1: _d.sent(); request.headers.set('Client-Id', this._clientId); if (!!this._authProxy) return [3 /*break*/, 3]; _b = (_a = request.headers).set; _c = ['Authorization']; return [4 /*yield*/, this.authHeader()]; case 2: _b.apply(_a, _c.concat([_d.sent()])); _d.label = 3; case 3: return [2 /*return*/, request]; } }); }); }; Platform.prototype.sendRequest = function (request, options) { if (options === void 0) { options = {}; } return __awaiter(this, void 0, void 0, function () { var e_6, retry, handleRateLimit, response, status_1, retryAfter, defaultRetryAfter; return __generator(this, function (_a) { switch (_a.label) { case 0: _a.trys.push([0, 3, , 7]); return [4 /*yield*/, this.inflateRequest(request, options)]; case 1: request = _a.sent(); return [4 /*yield*/, this._client.sendRequest(request)]; case 2: return [2 /*return*/, _a.sent()]; case 3: e_6 = _a.sent(); retry = options.retry, handleRateLimit = options.handleRateLimit; // Guard is for errors that come from polling if (!e_6.response || retry) throw e_6; response = e_6.response; status_1 = response.status; if ((status_1 !== Client_1.default._unauthorizedStatus && status_1 !== Client_1.default._rateLimitStatus) || this._authProxy) throw e_6; options.retry = true; retryAfter = 0; if (!(status_1 === Client_1.default._unauthorizedStatus)) return [3 /*break*/, 5]; return [4 /*yield*/, this._auth.cancelAccessToken()]; case 4: _a.sent(); _a.label = 5; case 5: if (status_1 === Client_1.default._rateLimitStatus) { defaultRetryAfter = !handleRateLimit || typeof handleRateLimit === 'boolean' ? 60 : handleRateLimit; // FIXME retry-after is custom header, by default, it can't be retrieved. Server should add header: 'Access-Control-Expose-Headers: retry-after'. retryAfter = parseFloat(response.headers.get('retry-after') || defaultRetryAfter) * 1000; e_6.retryAfter = retryAfter; this.emit(this.events.rateLimitError, e_6); if (!options.handleRateLimit) throw e_6; } return [4 /*yield*/, delay(retryAfter)]; case 6: _a.sent(); return [2 /*return*/, this.sendRequest(this._client.createRequest(options), options)]; case 7: return [2 /*return*/]; } }); }); }; Platform.prototype.send = function (options) { if (options === void 0) { options = {}; } //FIXME https://github.com/bitinn/node-fetch/issues/43 options.url = this.createUrl(options.url, { addServer: true }); return this.sendRequest(this._client.createRequest(options), options); }; Platform.prototype.get = function (url, query, options) { return __awaiter(this, void 0, void 0, function () { return __generator(this, function (_a) { return [2 /*return*/, this.send(__assign({ method: 'GET', url: url, query: query }, options))]; }); }); }; Platform.prototype.post = function (url, body, query, options) { return __awaiter(this, void 0, void 0, function () { return __generator(this, function (_a) { return [2 /*return*/, this.send(__assign({ method: 'POST', url: url, query: query, body: body }, options))]; }); }); }; Platform.prototype.put = function (url, body, query, options) { return __awaiter(this, void 0, void 0, function () { return __generator(this, function (_a) { return [2 /*return*/, this.send(__assign({ method: 'PUT', url: url, query: query, body: body }, options))]; }); }); }; Platform.prototype.delete = function (url, query, options) { return __awaiter(this, void 0, void 0, function () { return __generator(this, function (_a) { return [2 /*return*/, this.send(__assign({ method: 'DELETE', url: url, query: query }, options))]; }); }); }; Platform.prototype.ensureLoggedIn = function () { return __awaiter(this, void 0, void 0, function () { return __generator(this, function (_a) { switch (_a.label) { case 0: if (this._authProxy) return [2 /*return*/, null]; return [4 /*yield*/, this._auth.accessTokenValid()]; case 1: if (_a.sent()) return [2 /*return*/, null]; return [4 /*yield*/, this.refresh()]; case 2: _a.sent(); return [2 /*return*/, null]; } }); }); }; Platform.prototype._tokenRequest = function (url, body) { return __awaiter(this, void 0, void 0, function () { return __generator(this, function (_a) { return [2 /*return*/, this.send({ url: url, body: body, skipAuthCheck: true, method: 'POST', headers: { Authorization: this.basicAuthHeader(), 'Content-Type': Client_1.default._urlencodedContentType, }, })]; }); }); }; Platform.prototype.basicAuthHeader = function () { var apiKey = this._clientId + (this._clientSecret ? ":" + this._clientSecret : ''); return "Basic " + (typeof btoa === 'function' ? btoa(apiKey) : Buffer.from(apiKey).toString('base64')); }; Platform.prototype.authHeader = function () { return __awaiter(this, void 0, void 0, function () { var data; return __generator(this, function (_a) { switch (_a.label) { case 0: return [4 /*yield*/, this._auth.data()]; case 1: data = _a.sent(); return [2 /*return*/, (data.token_type || 'Bearer') + (data.access_token ? " " + data.access_token : '')]; } }); }); }; Platform._cacheId = 'platform'; return Platform; }(events_1.default)); exports.default = Platform; var LoginUrlPrompt; (function (LoginUrlPrompt) { LoginUrlPrompt["login"] = "login"; LoginUrlPrompt["sso"] = "sso"; LoginUrlPrompt["consent"] = "consent"; LoginUrlPrompt["none"] = "none"; })(LoginUrlPrompt = exports.LoginUrlPrompt || (exports.LoginUrlPrompt = {})); var LoginUrlDisplay; (function (LoginUrlDisplay) { LoginUrlDisplay["page"] = "page"; LoginUrlDisplay["popup"] = "popup"; LoginUrlDisplay["touch"] = "touch"; LoginUrlDisplay["mobile"] = "mobile"; })(LoginUrlDisplay = exports.LoginUrlDisplay || (exports.LoginUrlDisplay = {})); //# sourceMappingURL=Platform.js.map