respond-framework
Version:
create as fast you think
88 lines (85 loc) • 2.62 kB
JavaScript
"use strict";
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.callMethod = callMethod;
exports.getIdentity = getIdentity;
exports.makeRequest = makeRequest;
exports.permitted = permitted;
var _jwt = require("../../helpers/jwt.js");
var _secretMock = require("../secret.mock.js");
function makeRequest(req, context = {}) {
this.body = req.body;
this.req = req;
this.context = context;
const {
table,
method,
args
} = req.body;
const perms = this.permissions;
if (!this[method]) return {
error: 'method-absent',
params: {
table,
method
}
};
this.identity = this.getIdentity(this.config, req.body, perms);
if (this.permitted(perms, method, this.identity)) return this.callMethod(method, args);
const allowed = perms[method];
const roles = this.identity?.roles ?? [];
const params = {
table,
method,
roles,
allowed
};
return {
error: 'denied',
params
};
}
async function callMethod(method, args) {
if (this.beforeRequest) {
const ret = await self.beforeRequest(this.body);
if (ret) return ret;
}
const res = await this[method](...args); // eg db.user.findOne(id)
if (this.afterRequest) {
const ret = await this.afterRequest(this.body, res);
if (ret) return ret;
}
return res;
}
function permitted(perms, method, identity) {
if (!perms) return true;
const allowed = perms[method];
if (!allowed) return false;
const isPublic = allowed.length === 0;
if (isPublic) return true;
if (!identity?.roles) return false;
return allowed.find(ar => identity.roles.find(r => r === ar));
}
function getIdentity(config, body, perms) {
const {
token,
method,
userId,
adminUserId
} = body;
const identity = _jwt.default.verify(token, config.secret ?? _secretMock.default);
const mask = isMasquerading(perms, method, identity, adminUserId, userId);
return mask ? {
id: userId,
roles: ['user']
} : identity; // replace admin user that came from token with masqueraded user
}
function isMasquerading(perms, method, identity, adminUserId, userId) {
if (!adminUserId) return false; // when adminUserId is present, it means calls are coming from admin panel
if (!userId) return false; // no userId to masquerade with
if (userId === adminUserId) return false; // no need to masquerade when making calls as self
if (!identity?.roles.includes('admin')) return false; // verify user is in fact admin based on token
if (perms?.[method]?.includes('admin')) return false; // no need to masquerade when making standard admin calls
return true;
}