@opengis/admin 0.3.20 → 0.3.22

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/admin",
3
- "version": "0.3.20",
3
+ "version": "0.3.22",
4
4
  "description": "This project Softpro Admin",
5
5
  "main": "dist/admin.js",
6
6
  "type": "module",
@@ -119,27 +119,28 @@ export default async function plugin(fastify) {
119
119
 
120
120
  try {
121
121
  const hashes = await rclient.hgetall('cls-insert-hashes').then(obj => Object.keys(obj));
122
+ const names = await pgClients.client.query(`select array_agg(name) from admin.cls where parent is null`).then(el => el.rows?.[0]?.array_agg || []);
122
123
  const qHashes = await Promise.all(cls.filter((el, idx, arr) => arr.map((item) => item.name).indexOf(el.name) === idx).map(async (el) => {
123
124
  const { name, module, type } = el;
124
125
  const loadTemplate = await getTemplate(type, name);
125
126
  const hash = createHash('md5').update(type === 'cls' ? JSON.stringify(loadTemplate) : (loadTemplate?.sql || loadTemplate)).digest('hex');
126
- if (type === 'select' && !hashes.includes(hash)) {
127
+ if (type === 'select' && (!hashes.includes(hash) || !names.includes(name))) {
127
128
  clsQuery.push(`insert into admin.cls(name,type,data,module) values('${name}','sql','${(loadTemplate?.sql || loadTemplate)?.replace(/'/g, "''")}', '${module?.replace(/'/g, "''")}')`);
128
129
  return hash;
129
- } else if (type === 'cls' && loadTemplate?.length && !hashes.includes(hash)) {
130
+ } else if (type === 'cls' && loadTemplate?.length && (!hashes.includes(hash) || !names.includes(name))) {
130
131
  clsQuery.push(`insert into admin.cls(name,type, module) values('${name}','json', '${module?.replace(/'/g, "''")}');
131
132
  insert into admin.cls(code,name,parent,icon,data)
132
133
  select value->>'id',value->>'text','${name}',value->>'icon',value->>'data'
133
134
  from json_array_elements('${JSON.stringify(loadTemplate).replace(/'/g, "''")}'::json)`);
134
135
  return hash;
135
136
  } else if (hashes.includes(hash)) {
136
- console.log(name, type, 'skip equal hash');
137
+ console.log(name, type, names.includes(name) ? 'skip equal hash' : 'insert missing cls');
137
138
  } else {
138
139
  console.log(name, type, 'empty');
139
140
  }
140
141
  }));
141
142
 
142
- const { rowCount = 0 } = await client.query('delete from admin.cls where name = any($1::text[]) or parent = any($1::text[])', [cls.map(el => el.name)]);
143
+ const { rowCount = 0 } = await client.query('delete from admin.cls where not name = any($1::text[]) and (case when type = \'json\' then parent = any($1::text[]) else parent is null end)', [cls.map(el => el.name)]);
143
144
  console.log('admin/hook old cls deleted', rowCount);
144
145
  if (clsQuery.filter((el) => el).length) {
145
146
  console.log('admin/hook cls sql start', clsQuery?.length);
@@ -1,3 +1,11 @@
1
+ import { isFileExists } from "@opengis/fastify-file/utils.js";
2
+
3
+ async function checkAccess(pg, objectid, id) {
4
+ const { uid, filepath } = await pg.query(`select uid, file_path as filepath from crm.files where entity_id=$1 and file_id=$2`, [objectid, id])
5
+ .then(el => el.rows?.[0] || {});
6
+ return { uid, exists: filepath ? await isFileExists(filepath) : null };
7
+ }
8
+
1
9
  /**
2
10
  * Дістає CRM дані для vue хешує ідентифікатори, підтягує селекти
3
11
  *
@@ -21,21 +29,29 @@ import { pgClients, logChanges } from "@opengis/fastify-table/utils.js";
21
29
 
22
30
  export default async function widgetDel({
23
31
  pg = pgClients.client, params = {}, session = {},
24
- }) {
32
+ }, reply) {
25
33
  const { user = {} } = session.passport || {};
26
34
  if (!user.uid) return { error: 'access restricted', status: 403 };
27
35
  const { type, objectid, id } = params;
28
36
 
29
37
  if (!objectid) return { error: 'id required', status: 400 };
30
38
 
39
+ // force delete db entry if file not exists
40
+ const { exists, uid } = ['file', 'gallery'].includes(type) ? await checkAccess(pg, objectid, id) : null;
41
+
42
+ if (exists && !user?.user_type?.includes?.('admin') && uid && user?.uid !== uid) {
43
+ return reply.status(403).send('access restricted: file exists, not an author');
44
+ }
45
+
31
46
  const sqls = {
32
47
  comment: 'delete from crm.communications where entity_id=$1 and uid=$2 and communication_id=$3',
33
48
  checklist: 'delete from crm.checklists where entity_id=$1 and uid=$2 and checklist_id=$3',
34
- file: 'update crm.files set file_status=3 where entity_id=$1 and uid=$2 and file_id=$3 returning uploaded_name',
35
- gallery: 'update crm.files set file_status=3 where entity_id=$1 and uid=$2 and file_id=$3 returning uploaded_name',
49
+ file: `update crm.files set file_status=3 where entity_id=$1 and ${!exists || user?.user_type?.includes?.('admin') ? '$2=$2' : 'uid=$2'} and file_id=$3 returning uploaded_name`,
50
+ gallery: `update crm.files set file_status=3 where entity_id=$1 and ${!exists || user?.user_type?.includes?.('admin') ? '$2=$2' : 'uid=$2'} and file_id=$3 returning uploaded_name`,
36
51
  };
37
52
  const sql = sqls[type];
38
- if (!sql) return { error: 'type not valid', status: 401 };
53
+ // console.log(sql);
54
+ if (!sql) return reply.status(400).send('type not valid');
39
55
 
40
56
  const { rows = [] } = await pg.query(sql, [objectid, user.uid, id]);
41
57
  const table = { comment: 'crm.communications', checklist: 'crm.checklists', file: 'crm.files', gallery: 'crm.files' }[type];