/** @module utils */
const { TokenFactory } = require('./classes/users/Token.js');
const TokenController = require('./controllers/TokenController.js');
/** Default permissions for users */
const defaultUserPermissions = {
'permission.inference.spine': 'true',
'permission.search.book': 'true',
'permission.search.ocr': 'true',
'permission.contribute.edition': 'true',
'permission.contribute.verify.get': 'true',
'permission.contribute.verify.submit': 'true',
};
/**
* Checks if the user has the required permissions to access the endpoint
*
* @param {string[]} permissions
* @param {any} req
* @param {any} res
* @param {boolean} sendResponse If true, send a response if the user is not authorized
* @returns {Promise<boolean>}
*/
async function authorize(permissions = [], req, res, sendResponse = true) {
const tokenString = req.headers['authorization'];
if (!tokenString) {
if (sendResponse) res.status(401).send({ message: 'Missing token' });
return false;
}
const tokenDbRecord = await new TokenController().byTokenString(tokenString);
if (!tokenDbRecord) {
if (sendResponse) res.status(401).send({ message: 'Invalid token' });
return false;
}
const token = await new TokenFactory().load(tokenDbRecord).create();
const user = await token.getUser();
if (!user) {
if (sendResponse) res.status(401).send({ message: 'Invalid token' });
return false;
}
req.user = user;
for (const permission of permissions) {
let userPermission = await user.getMeta('permission.' + permission);
if (!userPermission) {
userPermission = defaultUserPermissions['permission.' + permission];
}
if (userPermission !== 'true') {
if (sendResponse) res.status(403).send({ message: 'Insufficient permissions' });
return false;
}
}
return true;
}
/**
* Split a text using more than one separator
*
* @param {string} text
* @param {string[]} separators
* @returns {string[]}
*/
function split(text, separators) {
const result = [];
let current = '';
for (const char of text) {
if (separators.includes(char)) {
if (current) {
result.push(current);
current = '';
}
} else {
current += char;
}
}
if (current) {
result.push(current);
}
return result;
}
/**
* Create terms used in the database from text
*
* @param {string} text
* @returns {string[]}
*/
function createTerms(text) {
const words = split(text, [' ', ',', '.', '!', '?', ';', ':', '(', ')', '[', ']', '{', '}', '<', '>', '\n', '\t', '-', '_']);
const result = [];
for (const word of words) {
const len = word.length;
// Iterate through each possible substring
for (let i = 0; i < len; i++) {
for (let j = i + 1; j <= len; j++) {
const substring = word.substring(i, j).toLowerCase();
result.push(substring);
}
}
}
return result;
}
/**
* Generate a temporary image path
*
* @returns {string} path
*/
function generateTempImagePath() {
return process.env.STORAGE_PATH + `/temp/${Date.now()}-${Math.floor(Math.random() * 100000)}.jpg`;
}
module.exports = {
defaultUserPermissions,
authorize,
createTerms,
generateTempImagePath,
};