@opengis/fastify-table
Version:
core-plugins
134 lines (133 loc) • 4.73 kB
JavaScript
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);
}