@becomes/cms-cloud-client
Version:
SDK for accessing BCMS Cloud API
213 lines (212 loc) • 7.72 kB
JavaScript
"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;