@opengis/fastify-table
Version:
core-plugins
125 lines (105 loc) • 5.07 kB
JavaScript
import { config, logger } from '../../../../utils.js';
import block from '../sqlInjection.js';
const { skipCheckPolicyRoutes = [] } = config;
const skipCheckPolicy = (path) => skipCheckPolicyRoutes.find(el => path.includes(el));
/**
* Middleware func
*
* @type function
* @alias checkPolicy
* @summary Функція дозволяє налаштувати доступ до сайту або API для адмін. та публічної частини веб-ресурсу
* @param {String} path - назва апі
* @returns {object|null} Returns object
*/
export default function checkPolicy(req, reply) {
const {
originalUrl: path, hostname, query, params, headers, method, session, routeOptions, unittest,
} = req;
const body = JSON.stringify(req?.body || {}).substring(30);
const isAdmin = process.env.NODE_ENV === 'admin' || hostname.split(':').shift() === config.adminDomain || config.admin || hostname.startsWith('admin');
const user = req.user || session?.passport?.user;
const isUser = config?.debug || !!user;
const isServer = process.argv[2];
const { policy = [] } = routeOptions?.config || {};
/*= == 0.Check superadmin access === */
if (policy.includes('admin') && user?.user_type !== 'admin' && !config.auth?.disable) {
logger.file('policy/access', {
path, method, params, query, body, message: 'access restricted: not admin', uid: user?.uid,
});
return reply.status(403).send('access restricted: 0');
}
/*= == 1.File injection === */
if (JSON.stringify(params || {})?.includes('../') || JSON.stringify(query || {})?.includes('../') || path?.includes('../')) {
logger.file('injection/file', {
path, method, params, query, body, message: 'access restricted: 1', uid: user?.uid,
});
return reply.status(403).send('access restricted: 1');
}
/* === 1.1 File === */
const allowExtPublic = ['.png', '.jpg', '.svg'];
const ext = path.toLowerCase().substr(-4);
if (path.includes('files/') && allowExtPublic.includes(ext)) return null;
/* === 2.SQL Injection policy: no-sql === */
if (!policy.includes('no-sql')) {
// skip polyline param - data filter (geometry bounds)
const stopWords = block.filter((el) => path.replace(query.polyline, '').includes(el));
if (stopWords?.length) {
logger.file('injection/sql', {
path, method, params, query, body, stopWords, message: 'access restricted: 2', uid: user?.uid,
});
return reply.status(403).send('access restricted: 2');
}
}
/* policy: skip if not API */
const isApi = ['/files/', '/api/', '/api-user/', '/logger', '/file/'].filter((el) => path.includes(el)).length;
if (!isApi) {
return null;
}
const validToken = (req.ip === '193.239.152.181' || req.ip === '127.0.0.1' || req.ip?.startsWith?.('192.168.') || config.debug)
&& req.headers?.token
&& config.auth?.tokens?.includes?.(headers.token);
if (validToken && !req?.user?.uid) {
req.user = { uid: req.headers?.uid, user_type: (req.ip === '193.239.152.181' || config.debug) ? 'admin' : 'regular' };
}
/* === policy: public === */
if (policy.includes('public') || skipCheckPolicy(path) || !config.pg || config.auth?.disable || config.local || config.debug || unittest) {
return null;
}
/* === 0. policy: unauthorized access from admin URL === */
if (!validToken && !user?.uid && isAdmin && !policy.includes('public')) {
logger.file('policy/unauthorized', {
path, method, params, query, body, token: headers?.token, userId: headers?.uid, ip: req.ip, headers, message: 'unauthorized',
});
return reply.status(401).send('unauthorized');
}
/* === 3. policy: user === */
if (!validToken && !user && policy.includes('user') && !skipCheckPolicy(path)) {
logger.file('policy/user', {
path, method, params, query, body, message: 'access restricted: 3',
});
return reply.status(403).send('access restricted: 3');
}
/* === 4. policy: referer === */
if (!validToken && !headers?.referer?.includes?.(hostname) && policy.includes('referer')) {
logger.file('policy/referer', {
path, method, params, query, body, message: 'access restricted: 4', uid: user?.uid,
});
return reply.status(403).send('access restricted: 4');
}
/* === 5. policy: site auth === */
if (!validToken && !policy.includes('site') && !isAdmin) {
logger.file('policy/site', {
path, method, params, query, body, message: 'access restricted: 5', uid: user?.uid,
});
return reply.status(403).send('access restricted: 5');
}
/* === 6. base policy: block non-public api w/ out authorization === */
if (!validToken && isAdmin && !isUser && isServer) {
logger.file('policy/api', {
path, method, params, query, body, message: 'access restricted: 6', uid: user?.uid,
});
return reply.status(403).send('access restricted: 6');
}
// console.log(headers);
return null;
}