@becomes/cms
Version:
Simple CMS for building APIs.
132 lines • 5.52 kB
JavaScript
;
Object.defineProperty(exports, "__esModule", { value: true });
exports.APISecurity = void 0;
var crypto = require("crypto");
var purple_cheetah_1 = require("purple-cheetah");
var key_cash_service_1 = require("./key-cash.service");
var APISecurity = (function () {
function APISecurity() {
}
APISecurity.sign = function (config) {
var data = {
key: config.key.id,
timestamp: Date.now(),
nonce: crypto.randomBytes(16).toString('hex').substring(0, 6),
signature: '',
};
var payloadAsString = '';
if (typeof config.payload === 'object') {
payloadAsString = Buffer.from(encodeURIComponent(JSON.stringify(config.payload))).toString('base64');
}
else {
payloadAsString = '' + config.payload;
}
var hmac = crypto.createHmac('sha256', config.key.secret);
hmac.update(data.nonce + data.timestamp + data.key + payloadAsString);
data.signature = hmac.digest('hex');
return data;
};
APISecurity.verify = function (data, payload, requestMethod, path, skipAccess) {
path = path.split('?')[0];
if (typeof data.key === 'undefined') {
throw new Error("Missing property 'key'.");
}
if (typeof data.nonce === 'undefined') {
throw new Error("Missing property 'nonce'.");
}
if (typeof data.timestamp === 'undefined') {
throw new Error("Missing property 'timestamp'.");
}
else {
if (typeof data.timestamp === 'string') {
data.timestamp = parseInt(data.timestamp, 10);
}
}
if (typeof data.signature === 'undefined') {
throw new Error("Missing property 'signature'.");
}
if (purple_cheetah_1.StringUtility.isIdValid(data.key) === false) {
throw new Error("Invalid 'key' value was provided.");
}
var key = key_cash_service_1.KeyCashService.findById(data.key);
if (key === null) {
throw new Error("Invalid 'key' was provided.");
}
if (key.blocked === true) {
throw new Error('This Key is blocked.');
}
var payloadAsString = '';
if (typeof payload === 'object') {
payloadAsString = Buffer.from(encodeURIComponent(JSON.stringify(payload))).toString('base64');
}
else {
payloadAsString = '' + payload;
}
if (data.timestamp < Date.now() - 60000 ||
data.timestamp > Date.now() + 3000) {
throw new Error('Timestamp out of range.');
}
var hmac = crypto.createHmac('sha256', key.secret);
hmac.update(data.nonce + data.timestamp + data.key + payloadAsString);
var signature = hmac.digest('hex');
if (signature !== data.signature) {
throw new Error('Invalid signature.');
}
if (skipAccess && skipAccess === true) {
return;
}
if (APISecurity.verifyAccess(key, requestMethod, path) === false) {
throw new Error("Key is not allowed to access this resource.");
}
};
APISecurity.verifyAccess = function (key, method, path) {
if (path.startsWith('/function')) {
var p_1 = path.replace('/function/', '');
if (key.access.functions.find(function (e) { return e.name === p_1; }) && method === 'POST') {
return true;
}
}
else if (path.startsWith('/template')) {
var parts_1 = path.split('/');
if (parts_1.length > 1) {
if (parts_1.length === 3) {
if (parts_1[2] === 'all' && method === 'GET') {
var templateAccess = key.access.templates.find(function (e) {
return e.methods.find(function (m) { return m === 'GET_ALL'; });
});
if (templateAccess) {
return true;
}
}
else if (method === 'GET') {
var templateAccess = key.access.templates.find(function (e) { return e._id === parts_1[2]; });
if (templateAccess) {
if (templateAccess.methods.find(function (e) { return e === method; })) {
return true;
}
}
}
}
else if (parts_1.length > 2 && parts_1[3] === 'entry') {
var templateAccess = key.access.templates.find(function (e) { return e._id === parts_1[2]; });
if (templateAccess) {
if (parts_1.length === 5 && parts_1[4] === 'all') {
if (templateAccess.entry.methods.find(function (e) { return e === 'GET_ALL'; })) {
return true;
}
}
else {
if (templateAccess.entry.methods.find(function (e) { return e === method; })) {
return true;
}
}
}
}
}
}
return false;
};
return APISecurity;
}());
exports.APISecurity = APISecurity;
//# sourceMappingURL=api-security.js.map