@opengis/fastify-table
Version:
core-plugins
131 lines (130 loc) • 4.7 kB
JavaScript
import { applyHook, getAccess, getTemplate, checkXSS, checkSQL, dataInsert, getToken, config, pgClients, logger, validateData, } from "../../../../utils.js";
export default async function insert(req, reply) {
const { pg = pgClients.client, user = {}, params = {}, body = {}, headers = {}, } = req || {};
if (!user) {
return reply.status(403).send({ error: "access restricted", code: 403 });
}
const hookData = (await applyHook("preInsert", {
pg,
table: params?.table,
user,
body,
}));
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: params.table,
mode: "a",
json: 1,
});
const { form, table: add } = hookData ||
tokenData ||
(config.security?.disableToken || config.local || config.auth?.disable
? req.params
: {});
const { actions = [] } = (await getAccess({ table: add, form, 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("add") && !config.local && !tokenData) {
return reply
.status(403)
.send({ error: "access restricted: actions", code: 403 });
}
if (!add) {
return reply.status(400).send({ error: "table is required", code: 400 });
}
const loadTemplate = await getTemplate("table", add);
const { table } = loadTemplate || hookData || tokenData || req.params || {};
if (!table) {
return reply.status(404).send({ error: "table not found", code: 404 });
}
const formData = form || loadTemplate?.form
? (await getTemplate("form", form || loadTemplate?.form)) || {}
: {};
const schema = formData?.schema || formData;
const xssCheck = checkXSS({ body, schema });
if (xssCheck.error && formData?.xssCheck !== false) {
logger.file("injection/xss", {
table,
form: form || loadTemplate?.form,
body,
uid: user?.uid,
msg: xssCheck.error,
});
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 (![add, table].includes("admin.users")) {
Object.assign(body, { uid: user?.uid, editor_id: user?.uid });
}
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 dataInsert({
pg,
id: params?.id || body.id,
table: loadTemplate?.table || table,
data: body,
uid: user?.uid,
tokenData,
referer,
});
if (!res) {
return reply.status(400).send({ error: "nothing added", code: 400 });
}
// admin.custom_column
await applyHook("afterInsert", {
pg,
table,
token: params?.table,
body,
payload: res,
user,
});
const pk = pg.pk?.[loadTemplate?.table || table];
return reply
.status(200)
.send({ id: res?.rows?.[0]?.[pk], rows: res.rows, extra: res.extra });
}