UNPKG

@opengis/fastify-table

Version:

core-plugins

141 lines (140 loc) 4.65 kB
import { config, logger } from "../../../../utils.js"; import block from "../sqlInjection.js"; export default function checkPolicy(req, reply) { const { originalUrl: path, hostname, query, params, headers, method, routeOptions, unittest, // legacy } = req; const user = req.user || req.session?.passport?.user; // ! skip locally, skip tests if ((config.local || unittest || process.env.NODE_ENV === "test") && user?.user_type !== "viewer") { return null; } // ! skip non-API Requests, handle with vite/vike const isApi = routeOptions.method && routeOptions.url && typeof routeOptions.handler === "function" && routeOptions.url !== "*"; if (!isApi) { return null; } const body = req.body ? JSON.stringify(req?.body || {}).substring(30) : undefined; const isAdmin = process.env.NODE_ENV === "admin" || hostname.split(":").shift() === config.adminDomain || config.admin || hostname.startsWith("admin"); const { role, referer, policy = [], allowSql, } = (routeOptions?.config || {}); // role=admin|regular const isRole = (role && (!user?.user_type || !role?.includes?.(user?.user_type))) || (policy.includes("admin") && user?.user_type !== "admin"); const allowExtPublic = [".png", ".jpg", ".svg"]; const ext = path.toLowerCase().substr(-4); const isPublic = Array.isArray(policy) ? policy.includes("public") : policy === "L0"; const requireUser = Array.isArray(policy) ? policy.includes("user") : ["L1", "L2", "L3"].includes(policy); const requireReferer = Array.isArray(policy) ? policy.includes("referer") : referer; if (method !== "GET" && user?.user_type === "viewer") { logger.file("policy/role", { path, method, userRole: user.user_type, }); return reply.status(403).send({ error: "access restricted: 0", code: 403 }); } // ! role if (isRole) { logger.file("policy/role", { role, userRole: user?.user_type || "none", path, method, params, query, body, uid: user?.uid, }); return reply.status(403).send({ error: "access restricted: 0", code: 403 }); } // ! file injection if (JSON.stringify(params || {})?.includes("../") || JSON.stringify(query || {})?.includes("../") || path?.includes("../")) { logger.file("injection/file", { path, method, params, query, body, uid: user?.uid, }); return reply.status(409).send({ error: "access restricted: 1", code: 409 }); } // ! invalid file extension if (path.includes("files/") && allowExtPublic.includes(ext)) { return null; } // ! sql injection const stopWords = block.filter((el) => path.includes(el) || JSON.stringify(req.body || {}).includes(el)); if (stopWords?.length && !allowSql) { logger.file("injection/sql", { path, method, params, query, body, stopWords, uid: user?.uid, }); return reply.status(409).send({ error: "access restricted: 2", code: 409 }); } // ! user required, but not logged in if (requireUser && !user) { logger.file("policy/user", { path, method, params, query, body, }); return reply.status(401).send({ error: "access restricted: 3", code: 401 }); } // ! referer if (requireReferer && !headers?.referer?.includes?.(hostname)) { logger.file("policy/referer", { path, method, params, query, body, uid: user?.uid, }); return reply.status(403).send({ error: "access restricted: 4", code: 403 }); } // ! public / token if (isPublic || config.debug) { return null; } // ! block any API for admin panel (without authorization) if (isAdmin && !req.url?.includes?.("/assets") && !config.debug && !user?.uid) { logger.file("policy/api", { path, method, params, query, body, message: "access restricted: 6", uid: user?.uid, }); return reply.status(403).send({ error: "access restricted: 6", code: 403 }); } return null; }