UNPKG

@becomes/cms-cloud-client

Version:

SDK for accessing BCMS Cloud API

213 lines (212 loc) 7.72 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.BCMSCloudSdk = void 0; const queue_1 = require("@banez/queue"); const types_1 = require("@banez/queue/types"); const axios_1 = require("axios"); const handlers_1 = require("./handlers"); const buffer_1 = require("buffer"); class BCMSCloudSdk { apiOrigin; storage; store; throwable; router; disableSocket; accessTokenRaw = null; accessToken = null; auth = new handlers_1.AuthHandler(this); user = new handlers_1.UserHandler(this); org = new handlers_1.OrgHandler(this); instanceAdditionalFile = new handlers_1.InstanceAdditionalFileHandler(this); instanceDep = new handlers_1.InstanceDepHandler(this); instanceDomain = new handlers_1.InstanceDomainHandler(this); instanceEnv = new handlers_1.InstanceEnvHandler(this); instanceFje = new handlers_1.InstanceFjeHandler(this); instance = new handlers_1.InstanceHandler(this); instancePlugin = new handlers_1.InstancePluginHandler(this); instanceProxyConfig = new handlers_1.InstanceProxyConfigHandler(this); media = new handlers_1.MediaHandler(this); invitation = new handlers_1.InvitationHandler(this); feature = new handlers_1.FeatureHandler(this); limit = new handlers_1.LimitHandler(this); shim = new handlers_1.ShimHandler(this); admin = new handlers_1.AdminHandler(this); socket = new handlers_1.SocketHandler(this, '/api/v2/socket'); refreshQueue = (0, queue_1.createQueue)(); constructor(apiOrigin, storage, store, throwable, router, disableSocket) { this.apiOrigin = apiOrigin; this.storage = storage; this.store = store; this.throwable = throwable; this.router = router; this.disableSocket = disableSocket; this.accessTokenRaw = storage.get('at'); if (this.accessTokenRaw) { this.accessToken = this.unpackAccessToken(this.accessTokenRaw); } this.storage.subscribe('at', (value, type) => { if (type === 'set') { this.accessTokenRaw = value; if (this.accessTokenRaw) { this.accessToken = this.unpackAccessToken(this.accessTokenRaw); } } else { this.accessTokenRaw = null; this.accessToken = null; } }); } unpackAccessToken(at) { const atParts = at.split('.'); if (atParts.length === 3) { return { header: JSON.parse(buffer_1.Buffer.from(atParts[0], 'base64').toString()), payload: JSON.parse(buffer_1.Buffer.from(atParts[1], 'base64').toString()), signature: atParts[2], }; } return null; } async clearAndLogout() { this.accessToken = null; this.accessTokenRaw = null; await this.storage.clear(); for (const _key in this.store) { const key = _key; this.store[key].remove(this.store[key].items().map((e) => e._id)); } } /** * Will try to refresh the Access Token. If Access Token * is still valid, it will not be refreshed. */ async refreshAccessToken(force) { const result = await this.refreshQueue({ name: 'refresh', handler: async () => { if (!force) { let refresh = true; if (this.accessToken) { if (this.accessToken.payload.iat + this.accessToken.payload.exp > Date.now() + 1000) { refresh = false; } } else { this.accessTokenRaw = this.storage.get('at'); if (this.accessTokenRaw) { this.accessToken = this.unpackAccessToken(this.accessTokenRaw); if (this.accessToken && this.accessToken.payload.iat + this.accessToken.payload.exp > Date.now()) { refresh = false; } } } if (!refresh) { return true; } } const refreshToken = this.storage.get('rt'); if (!refreshToken) { return false; } try { const res = await this.send({ url: '/v2/auth/refresh-access', doNotAuth: true, method: 'POST', data: { token: this.storage.get('rt'), }, }); this.accessToken = this.unpackAccessToken(res.token); await this.storage.set('at', res.token); return true; } catch (error) { // eslint-disable-next-line no-console console.error(error); await this.clearAndLogout(); return false; } }, }).wait; if (result instanceof types_1.QueueError) { throw result.error; } return result.data; } /** * Check if User is logged in. If this method returns `false`, * called to protected resources will fail and User will be * redirected to defined login path. */ async isLoggedIn() { const result = await this.refreshAccessToken(); if (!this.disableSocket && this.socket && result && !this.socket.connected() && this.accessTokenRaw) { await this.socket.connect(); } return result; } async send(conf) { if (!conf.headers) { conf.headers = {}; } if (!conf.doNotAuth) { const loggedIn = await this.isLoggedIn(); conf.headers.Authorization = `Bearer ${this.accessTokenRaw}`; if (!loggedIn || !this.accessTokenRaw) { throw { status: 401, message: 'Not logged in.', }; } } if (this.socket.id()) { if (!conf.headers) { conf.headers = {}; } conf.headers['X-Bcms-Sid'] = this.socket.id(); } conf.url = `${this.apiOrigin}/api${conf.url}`; try { conf.maxBodyLength = 100000000; const response = await (0, axios_1.default)(conf); return response.data; } catch (error) { const err = error; if (err.response) { if (err.response.data && err.response.data.message) { throw { status: err.response.status, code: err.response.data.code, message: err.response.data.message, }; } else { throw { status: err.response.status, code: '-1', message: err.message, }; } } else { throw { status: -1, code: '-1', message: err.message, }; } } } } exports.BCMSCloudSdk = BCMSCloudSdk;