UNPKG

@opengis/fastify-table

Version:

core-plugins

134 lines (133 loc) 4.73 kB
import { pgClients, applyHook, getAccess, getTemplate, checkXSS, checkSQL, dataUpdate, logger, getToken, validateData, } from "../../../../utils.js"; import config from "../../../../config.js"; import insert from "./insert.js"; export default async function update(req, reply) { const { pg = pgClients.client, user, params = {}, body = {}, headers = {}, unittest, } = req; if (!user) { return reply.status(403).send({ error: "access restricted", code: 403 }); } const hookData = (await applyHook("preUpdate", { pg, table: params?.table, id: params?.id, user, })); if (hookData?.message && hookData?.status) { const response = hookData.status >= 400 ? { error: hookData.message, code: hookData.status } : hookData.message; return reply.status(hookData.status).send(response); } const { referer } = headers; const tokenData = await getToken({ uid: user.uid, token: body.token || params.id || params.table, mode: "w", json: 1, }); const { form, table: edit, id, } = hookData || tokenData || (config.security?.disableToken || config.local || config.auth?.disable ? params : {}); const { actions = [] } = (await getAccess({ table: edit, form, id, user, }, pg)) || {}; if (!tokenData && !config.local && !config.security?.disableToken && !config.auth?.disable) { return reply.status(400).send({ error: "invalid token", code: 400 }); } if (!actions.includes("edit") && !config.local && !tokenData) { return reply .status(403) .send({ error: "access restricted: actions", code: 403 }); } if (!edit) { return reply.status(400).send({ error: "table is required", code: 400 }); } if (!id && tokenData?.table) { return insert(req, reply); } if (!id) { return reply.status(400).send({ error: "id is required", code: 400 }); } const loadTemplate = await getTemplate("table", edit); const { table } = loadTemplate || hookData || tokenData || params || {}; const uid = user?.uid; const formData = form || loadTemplate?.form ? await getTemplate("form", form || loadTemplate?.form) : {}; const schema = formData?.schema || formData; // skip non-present fields in form schema if (!unittest && !tokenData?.ignoreCheck && headers["content-type"] === "application/json") { Object.keys(body || {}) .filter((key) => !Object.keys(schema || {}).includes(key)) .forEach((key) => delete body[key]); } const xssCheck = checkXSS({ body, schema }); if (xssCheck.error && formData?.xssCheck !== false) { logger.file("injection/xss", { msg: xssCheck.error, table }, req); return reply.status(409).send({ error: "Дані містять заборонені символи. Приберіть їх та спробуйте ще раз", code: 409, }); } const fieldCheck = validateData({ body, schema }); if (fieldCheck.error) { logger.file("injection/formdata", { table, form: form || loadTemplate?.form, uid: user?.uid, ...fieldCheck, }); return reply.status(409).send({ error: "Дані не пройшли валідацію. Приберіть некоректні дані та спробуйте ще раз", code: 409, }); } const sqlCheck = checkSQL({ body, schema }); if (sqlCheck.error) { logger.file("injection/sql", { table, form: form || loadTemplate?.form, uid: user?.uid, ...sqlCheck, }); return reply.status(409).send({ error: "Дані містять заборонені sql символи. Приберіть їх та спробуйте ще раз", code: 409, }); } if (tokenData?.obj) { const objData = tokenData.obj?.split("#").reduce((p, el) => ({ ...p, [el.split("=")[0] || ""]: el.split("=")[1], }), {}) || {}; Object.assign(body, objData); } const res = await dataUpdate({ pg, table: loadTemplate?.table || table, id, data: body, uid, tokenData, referer, }); // admin.custom_column await applyHook("afterUpdate", { pg, table: params?.table, body, payload: res, user, }); return reply.status(200).send(res); }