@opengis/fastify-table 1.1.77 → 1.1.78

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@opengis/fastify-table",
3
- "version": "1.1.77",
3
+ "version": "1.1.78",
4
4
  "type": "module",
5
5
  "description": "core-plugins",
6
6
  "main": "index.js",
@@ -14,14 +14,18 @@ export default async function dataInsert({
14
14
  if (!columns) return null;
15
15
 
16
16
  const names = columns.map((el) => el.name);
17
+
18
+ Object.assign(data, { uid, editor_id: uid });
19
+ const systemColumns = ['cdate', 'editor_date'].filter((el) => names.includes(el)).map((el) => [el, 'now()']);
20
+
17
21
  const filterData = Object.keys(data)
18
- .filter((el) => data[el] && names.includes(el)).map((el) => [el, data[el]]);
22
+ .filter((el) => !['cdate', 'editor_date'].includes(el) && data[el] && names.includes(el)).map((el) => [el, data[el]]);
19
23
 
20
24
  const insertQuery = `insert into ${table}
21
25
 
22
- ( ${filterData?.map((key) => `"${key[0]}"`).join(',')})
26
+ ( ${filterData?.map((key) => `"${key[0]}"`).concat(systemColumns.map((el) => el[0])).join(',')})
23
27
 
24
- values (${filterData?.map((key, i) => (key[0] === 'geom' ? `st_setsrid(st_geomfromgeojson($${i + 1}::json),4326)` : `$${i + 1}`)).join(',')})
28
+ values (${filterData?.map((key, i) => (key[0] === 'geom' ? `st_setsrid(st_geomfromgeojson($${i + 1}::json),4326)` : `$${i + 1}`)).concat(systemColumns.map((el) => el[1])).join(',')})
25
29
 
26
30
  returning *`;
27
31
 
@@ -16,11 +16,11 @@ export default async function dataUpdate({
16
16
  const { columns, pk } = await getMeta(table);
17
17
 
18
18
  const names = columns?.map((el) => el.name);
19
- Object.assign(data, { editor_id: uid });
19
+
20
20
  const filterData = Object.keys(data)
21
- .filter((el) => (/* typeof data[el] === 'boolean' ? true : data[el] && */ names?.includes(el) && el !== 'editor_date'));
21
+ .filter((el) => (/* typeof data[el] === 'boolean' ? true : data[el] && */ names?.includes(el) && !['editor_date', 'editor_id'].includes(el)));
22
22
 
23
- const editorDate = names?.includes('editor_date') ? 'editor_date=now(),' : '';
23
+ const systemColumns = [['editor_date', 'now()'], ['editor_id', `'${uid.replace(/'/g, "''")}'`]].filter((el) => names.includes(el[0])).map((el) => `${el[0]} = ${el[1]}`).join(',');
24
24
 
25
25
  const filterValue = filterData.map((el) => [el, data[el]]).map((el) => (typeof el[1] === 'object' && el[1] && (!Array.isArray(el[1]) || typeof el[1]?.[0] === 'object') ? JSON.stringify(el[1]) : el[1]));
26
26
 
@@ -34,7 +34,7 @@ export default async function dataUpdate({
34
34
  Object.assign(srids, srids1);
35
35
  }
36
36
 
37
- const updateQuery = `UPDATE ${table} SET ${editorDate} ${filterData
37
+ const updateQuery = `UPDATE ${table} SET ${systemColumns}, ${filterData
38
38
  ?.map((key, i) => (key?.includes('geom') && key !== 'geom' ? `"${key}"=st_setsrid(st_geomfromgeojson($${i + 2}::json),${srids[table]?.[key] || 4326})` : undefined)
39
39
  || (key === 'geom' ? `"${key}"=st_setsrid(st_geomfromgeojson($${i + 2}::json),4326)` : `"${key}"=$${i + 2}`))
40
40
  .join(',')}
@@ -13,7 +13,7 @@ function checkXSS({ body, schema = {} }) {
13
13
  // escape arrows on non-RTE
14
14
  Object.keys(body)
15
15
  .filter((key) => ['<', '>'].find((el) => body[key]?.includes?.(el))
16
- && !['Summernote', 'Tiny', 'Ace'].includes(schema?.[key]?.type))
16
+ && !['Summernote', 'Tiny', 'Ace', 'Texteditor'].includes(schema?.[key]?.type))
17
17
  ?.forEach((key) => {
18
18
  Object.assign(body, { [key]: body[key].replace(/</g, '&lt;').replace(/>/g, '&gt;') });
19
19
  });
@@ -34,8 +34,9 @@ export default async function insert(req) {
34
34
  }
35
35
 
36
36
  const formData = form || loadTemplate?.form ? (await getTemplate('form', form || loadTemplate?.form) || {}) : {};
37
+ const schema = formData?.schema || formData;
37
38
 
38
- const xssCheck = checkXSS({ body, schema: formData?.schema || formData });
39
+ const xssCheck = checkXSS({ body, schema });
39
40
 
40
41
  if (xssCheck.error && formData?.xssCheck !== false) {
41
42
  req.log.warn({ name: 'injection/xss', msg: xssCheck.error, table }, req);
@@ -60,14 +61,14 @@ export default async function insert(req) {
60
61
  table, body, payload: res, user,
61
62
  });
62
63
  // form DataTable
63
- const extraKeys = Object.keys(formData)?.filter((key) => formData?.[key]?.type === 'DataTable' && formData?.[key]?.table && formData?.[key]?.parent_id && body[key].length);
64
+ const extraKeys = Object.keys(schema || {})?.filter((key) => schema?.[key]?.type === 'DataTable' && schema?.[key]?.table && schema?.[key]?.parent_id && body[key].length);
64
65
  if (extraKeys?.length) {
65
66
  res.extra = {};
66
67
  await Promise.all(extraKeys?.map(async (key) => {
67
- const objId = body[formData[key].parent_id] || req.body?.id;
68
+ const objId = body[schema[key].parent_id] || req.body?.id || res?.rows?.[0]?.[schema[key].parent_id];
68
69
  const extraRows = await Promise.all(body[key].map(async (row) => {
69
70
  const extraRes = await dataInsert({
70
- table: formData[key].table, data: { ...row, [formData[key].parent_id]: objId }, uid: user?.uid,
71
+ table: schema[key].table, data: { ...row, [schema[key].parent_id]: objId }, uid: user?.uid,
71
72
  });
72
73
  return extraRes?.rows?.[0];
73
74
  }));
@@ -47,7 +47,9 @@ export default async function tableAPI(req) {
47
47
  if (!pk) return { message: `table not found: ${table}`, status: 404 };
48
48
 
49
49
  // const cols = columns.map((el) => el.name || el).join(',');
50
- const schema = await getTemplate('form', hookData?.form || form) || {};
50
+ const formName = hookData?.form || tokenData?.form || form;
51
+ const formData = await getTemplate('form', formName) || {};
52
+ const schema = formData?.schema || formData;
51
53
  // skip DataTable from another table
52
54
  const extraKeys = Object.keys(schema)?.filter((key) => schema[key]?.type === 'DataTable' && schema[key]?.table && schema[key]?.parent_id && schema[key]?.colModel?.length);
53
55
  // skip non-existing columns
@@ -69,11 +71,13 @@ export default async function tableAPI(req) {
69
71
  if (extraKeys?.length) {
70
72
  await Promise.all(extraKeys?.map(async (key) => {
71
73
  const { colModel, table: extraTable, parent_id: parentId } = schema[key];
72
- const { rows: extraRows } = await pg.query(`select ${parentId} as parent, ${colModel.map((col) => col.name).join(',')} from ${extraTable} a where ${parentId}=$1`, [hookData?.id || params?.id]);
74
+ const q1 = `select ${parentId} as parent, ${colModel.map((col) => col.name || col.key).join(',')} from ${extraTable} a where ${parentId}=$1`;
75
+ // console.log(tableName, formName, q1);
76
+ const { rows: extraRows } = await pg.query(q1, [hookData?.id || tokenData?.id || params?.id]);
73
77
  Object.assign(data, { [key]: extraRows });
74
78
  }));
75
79
  }
76
- if (user.uid) {
80
+ if (user?.uid) {
77
81
  data.token = tokenData?.table ? params.table : setToken({
78
82
  ids: [JSON.stringify({ id, table: tableName, form: loadTable.form })],
79
83
  uid: user.uid,
@@ -43,8 +43,9 @@ export default async function update(req) {
43
43
  const uid = user?.uid;
44
44
 
45
45
  const formData = form || loadTemplate?.form ? await getTemplate('form', form || loadTemplate?.form) : {};
46
+ const schema = formData?.schema || formData;
46
47
 
47
- const xssCheck = checkXSS({ body, schema: formData?.schema || formData });
48
+ const xssCheck = checkXSS({ body, schema });
48
49
 
49
50
  if (xssCheck.error && formData?.xssCheck !== false) {
50
51
  logger.warn({ name: 'injection/xss', msg: xssCheck.error, table }, req);
@@ -61,16 +62,16 @@ export default async function update(req) {
61
62
  });
62
63
 
63
64
  // form DataTable
64
- const extraKeys = formData ? Object.keys(formData)?.filter((key) => formData?.[key]?.type === 'DataTable' && formData?.[key]?.table && formData?.[key]?.parent_id && body[key].length) : [];
65
+ const extraKeys = Object.keys(schema || {})?.filter((key) => schema?.[key]?.type === 'DataTable' && schema?.[key]?.table && schema?.[key]?.parent_id && body[key].length);
65
66
  if (extraKeys?.length) {
66
67
  res.extra = {};
67
68
  await Promise.all(extraKeys?.map(async (key) => {
68
- const objId = body[formData[key].parent_id] || body?.id;
69
+ const objId = body[schema[key].parent_id] || body?.id || res?.[schema[key]?.parent_id];
69
70
  // delete old extra data
70
- await pgClients.client.query(`delete from ${formData[key].table} where ${formData[key].parent_id}=$1`, [objId]); // rewrite?
71
+ await pgClients.client.query(`delete from ${schema[key].table} where ${schema[key].parent_id}=$1`, [objId]); // rewrite?
71
72
  // insert new extra data
72
73
  const extraRows = await Promise.all(body[key].map(async (row) => {
73
- const extraRes = await dataInsert({ table: formData[key].table, data: { ...row, [formData[key].parent_id]: objId }, uid });
74
+ const extraRes = await dataInsert({ table: schema[key].table, data: { ...row, [schema[key].parent_id]: objId }, uid });
74
75
  return extraRes?.rows?.[0];
75
76
  }));
76
77
  Object.assign(res.extra, { [key]: extraRows.filter((el) => el) });