@opengis/admin 0.3.40 → 0.3.41

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.
Files changed (115) hide show
  1. package/README.md +97 -97
  2. package/config.js +4 -4
  3. package/dist/{add-page-0tbU2ZNu.js → add-page-DmhwcAMY.js} +1 -1
  4. package/dist/{admin-interface-Ce34jSGd.js → admin-interface-5dHYgR-t.js} +2 -2
  5. package/dist/{admin-view-BATaA4bq.js → admin-view-C7JteOit.js} +1 -1
  6. package/dist/admin.js +1 -1
  7. package/dist/admin.umd.cjs +50 -50
  8. package/dist/assets/logo.svg +41 -41
  9. package/dist/{card-view-BFDfT9LI.js → card-view-Cey1LE5b.js} +1 -1
  10. package/dist/{edit-page-BTccecZF.js → edit-page-C-cpKJC2.js} +1 -1
  11. package/dist/{import-file-D7kmC9pj.js → import-file-B53vJ2ve.js} +5910 -5929
  12. package/dist/{profile-page-wPxhrzAG.js → profile-page-BqYeCCjU.js} +1 -1
  13. package/dist/style.css +1 -1
  14. package/module/settings/card/admin.accounts.table/index.yml +7 -7
  15. package/module/settings/card/admin.accounts.table/rules.hbs +18 -18
  16. package/module/settings/card/admin.accounts.table/users.hbs +13 -13
  17. package/module/settings/card/admin.routes.table/groups.hbs +11 -11
  18. package/module/settings/card/admin.routes.table/users.hbs +16 -16
  19. package/module/settings/cls/core.actions.json +17 -17
  20. package/module/settings/cls/core.scope.json +13 -13
  21. package/module/settings/cls/properties.site_status.json +13 -13
  22. package/module/settings/cls/properties.widget_status.json +13 -13
  23. package/module/settings/cls/users.user_type.json +13 -13
  24. package/module/settings/cls/yes_no.json +11 -11
  25. package/module/settings/form/admin.accounts.form.json +13 -13
  26. package/module/settings/form/admin.properties.form.json +15 -15
  27. package/module/settings/form/admin.roles.form.json +21 -21
  28. package/module/settings/form/admin.user_properties.form.json +15 -15
  29. package/module/settings/form/admin.user_roles_card.form.json +13 -13
  30. package/module/settings/interface/admin.properties.json +4 -4
  31. package/module/settings/interface/admin.roles.json +4 -4
  32. package/module/settings/interface/admin.routes.json +4 -4
  33. package/module/settings/interface/admin.users.json +4 -4
  34. package/module/settings/select/core.routes.sql +1 -1
  35. package/module/settings/select/core.user_mentioned.sql +1 -1
  36. package/module/settings/select/core.user_uid.sql +1 -1
  37. package/module/settings/table/admin.properties.table.json +39 -39
  38. package/module/settings/table/admin.user_properties.table.json +34 -34
  39. package/package.json +2 -2
  40. package/server/helpers/core/badge.js +16 -16
  41. package/server/helpers/core/buttonHelper.js +21 -21
  42. package/server/helpers/core/coalesce.js +7 -7
  43. package/server/helpers/core/select.js +48 -48
  44. package/server/helpers/core/token.js +18 -18
  45. package/server/helpers/list/buttonHelper.js +21 -21
  46. package/server/helpers/list/utils/button.js +5 -5
  47. package/server/helpers/temp/contentList.js +58 -58
  48. package/server/helpers/temp/ifCond.js +101 -101
  49. package/server/helpers/utils/button.js +5 -5
  50. package/server/helpers/utils/mdToHTML.js +17 -17
  51. package/server/plugins/access/index.mjs +6 -6
  52. package/server/plugins/adminHook.js +81 -81
  53. package/server/plugins/cron.js +10 -10
  54. package/server/plugins/docs.js +28 -28
  55. package/server/plugins/hook.js +31 -9
  56. package/server/routes/access/controllers/access.group.js +29 -29
  57. package/server/routes/access/controllers/access.group.post.js +54 -54
  58. package/server/routes/access/index.mjs +11 -11
  59. package/server/routes/access/schema.mjs +67 -67
  60. package/server/routes/calendar/controllers/calendar.data.js +125 -125
  61. package/server/routes/calendar/index.mjs +7 -7
  62. package/server/routes/calendar/schema.js +21 -21
  63. package/server/routes/data/controllers/cardTabData.js +49 -49
  64. package/server/routes/data/controllers/funcs/getFilterSQL/index.js +92 -92
  65. package/server/routes/data/controllers/funcs/getFilterSQL/util/formatValue.js +170 -170
  66. package/server/routes/data/controllers/funcs/getFilterSQL/util/getCustomQuery.js +13 -13
  67. package/server/routes/data/controllers/funcs/getFilterSQL/util/getFilterQuery.js +64 -64
  68. package/server/routes/data/controllers/funcs/getFilterSQL/util/getOptimizedQuery.js +12 -12
  69. package/server/routes/data/controllers/funcs/getFilterSQL/util/getTableSql.js +34 -34
  70. package/server/routes/data/controllers/tableDataId.js +27 -27
  71. package/server/routes/data/controllers/tokenInfo.js +9 -9
  72. package/server/routes/data/controllers/utils/assignTokens.js +30 -30
  73. package/server/routes/data/controllers/utils/conditions.js +20 -20
  74. package/server/routes/data/controllers/utils/getColumns.js +8 -8
  75. package/server/routes/data/index.mjs +20 -20
  76. package/server/routes/data/schema.js +54 -54
  77. package/server/routes/notifications/controllers/readNotifications.js +18 -18
  78. package/server/routes/notifications/controllers/testEmail.js +35 -35
  79. package/server/routes/notifications/controllers/userNotifications.js +53 -53
  80. package/server/routes/notifications/hook/onWidgetSet.js +56 -56
  81. package/server/routes/notifications/index.mjs +26 -26
  82. package/server/routes/notifications/schema.js +16 -16
  83. package/server/routes/print/controllers/cardPrint.js +135 -135
  84. package/server/routes/properties/schema.js +10 -10
  85. package/server/routes/report/controllers/data.js +76 -76
  86. package/server/routes/report/controllers/list.js +18 -18
  87. package/server/routes/report/index.mjs +7 -7
  88. package/server/routes/report/utils/formatValue.js +179 -179
  89. package/server/routes/root.mjs +3 -3
  90. package/server/routes/templates/controllers/getTemplate.js +44 -44
  91. package/server/routes/templates/schema.js +8 -8
  92. package/server/routes/user/controllers/user.cls.id.js +14 -14
  93. package/server/routes/user/controllers/user.cls.js +72 -72
  94. package/server/routes/user/controllers/user.info.js +17 -17
  95. package/server/routes/user/schema.js +14 -14
  96. package/server/routes/util/controllers/code.generator.js +89 -89
  97. package/server/routes/widget/controllers/widget.del.js +80 -80
  98. package/server/routes/widget/controllers/widget.set.js +93 -93
  99. package/server/routes/widget/hook/onWidgetSet.js +12 -12
  100. package/server/routes/widget/index.mjs +16 -16
  101. package/server/routes/widget/schema.js +12 -12
  102. package/server/templates/cls/itree.recrzone_category.json +73 -73
  103. package/server/templates/cls/test.json +9 -9
  104. package/server/templates/form/admin.user_cls.data.form.json +49 -49
  105. package/server/templates/form/admin.user_group_rel.form.json +21 -21
  106. package/server/templates/form/form-user-pass.json +10 -10
  107. package/server/templates/form/form-user_group.json +39 -39
  108. package/server/templates/form/form-users.json +156 -156
  109. package/server/templates/form/user_group_access.form.json +22 -22
  110. package/server/templates/select/account_id.json +2 -2
  111. package/server/templates/table/gis.dataset.table.json +43 -43
  112. package/server/templates/table/management.user_group.table.json +112 -112
  113. package/server/templates/table/management.users.table.json +126 -126
  114. package/server/utils/addNotification.js +21 -21
  115. package/server/utils/sendNotification.js +89 -89
@@ -1,6 +1,6 @@
1
- import getAdminAccess from './funcs/getAdminAccess.js';
2
-
3
- async function plugin(fastify) {
4
- // fastify.decorate('getAdminAccess', getAdminAccess);
5
- }
6
- export default plugin;
1
+ import getAdminAccess from './funcs/getAdminAccess.js';
2
+
3
+ async function plugin(fastify) {
4
+ // fastify.decorate('getAdminAccess', getAdminAccess);
5
+ }
6
+ export default plugin;
@@ -1,81 +1,81 @@
1
- import fp from 'fastify-plugin';
2
- import fs from 'node:fs';
3
-
4
- import config from '../../config.js';
5
-
6
- // to export the decorators to the outer scope
7
-
8
- async function plugin(fastify) {
9
- fastify.decorate('config', config);
10
-
11
- // preSerialization
12
- fastify.addHook('preSerialization', async (req, reply, payload) => {
13
- if (req.url.includes('/suggest/') && !req.query.json) {
14
- return payload?.data;
15
- }
16
- if (payload?.redirect) {
17
- return reply.redirect(payload.redirect);
18
- }
19
- if (reply.sent) {
20
- return null;
21
- }
22
-
23
- if ([200, 400, 403, 409, 404, 500].includes(payload.status)) {
24
- reply.status(payload.status);
25
- }
26
- /* if (payload.headers) {
27
- reply.headers(payload.headers);
28
- } */
29
- if (payload?.buffer) {
30
- return payload.buffer;
31
- }
32
- if (payload?.file) {
33
- // const buffer = await readFile(payload.file);
34
- // return reply.send(buffer);
35
- const stream = fs.createReadStream(payload.file);
36
- return stream;
37
- // return reply.send(stream);
38
- }
39
-
40
- if (payload?.message) {
41
- return payload.message;
42
- }
43
- return payload;
44
- });
45
-
46
- // preValidation
47
- fastify.addHook('preValidation', async (req) => {
48
- const parseRawBody = ['POST', 'PUT'].includes(req.method) && req.body && typeof req.body === 'string'
49
- && req.body.trim(/\r\n/g).startsWith('{')
50
- && req.body.trim(/\r\n/g).endsWith('}');
51
- if (parseRawBody) {
52
- try {
53
- req.body = JSON.parse(req.body || '{}');
54
- }
55
- catch (err) {
56
- // throw new Error('invalid body');
57
- // return { error: 'invalid body', status: 400 };
58
- }
59
- }
60
- });
61
-
62
- // allow upload file
63
- const kIsMultipart = Symbol.for('[FastifyMultipart.isMultipart]');
64
- fastify.addContentTypeParser('multipart', (request, _, done) => {
65
- request[kIsMultipart] = true;
66
- done(null);
67
- });
68
-
69
- // parse Body
70
- function contentParser(req, body, done) {
71
- const parseBody = decodeURIComponent(body.toString()).split('&').reduce((acc, el) => {
72
- const [key, val] = el.split('=');
73
- return { ...acc, [key]: val };
74
- }, {});
75
- done(null, parseBody);
76
- }
77
-
78
- fastify.addContentTypeParser('application/x-www-form-urlencoded', { parseAs: 'buffer' }, contentParser);
79
- }
80
-
81
- export default fp(plugin);
1
+ import fp from 'fastify-plugin';
2
+ import fs from 'node:fs';
3
+
4
+ import config from '../../config.js';
5
+
6
+ // to export the decorators to the outer scope
7
+
8
+ async function plugin(fastify) {
9
+ fastify.decorate('config', config);
10
+
11
+ // preSerialization
12
+ fastify.addHook('preSerialization', async (req, reply, payload) => {
13
+ if (req.url.includes('/suggest/') && !req.query.json) {
14
+ return payload?.data;
15
+ }
16
+ if (payload?.redirect) {
17
+ return reply.redirect(payload.redirect);
18
+ }
19
+ if (reply.sent) {
20
+ return null;
21
+ }
22
+
23
+ if ([200, 400, 403, 409, 404, 500].includes(payload.status)) {
24
+ reply.status(payload.status);
25
+ }
26
+ /* if (payload.headers) {
27
+ reply.headers(payload.headers);
28
+ } */
29
+ if (payload?.buffer) {
30
+ return payload.buffer;
31
+ }
32
+ if (payload?.file) {
33
+ // const buffer = await readFile(payload.file);
34
+ // return reply.send(buffer);
35
+ const stream = fs.createReadStream(payload.file);
36
+ return stream;
37
+ // return reply.send(stream);
38
+ }
39
+
40
+ if (payload?.message) {
41
+ return payload.message;
42
+ }
43
+ return payload;
44
+ });
45
+
46
+ // preValidation
47
+ fastify.addHook('preValidation', async (req) => {
48
+ const parseRawBody = ['POST', 'PUT'].includes(req.method) && req.body && typeof req.body === 'string'
49
+ && req.body.trim(/\r\n/g).startsWith('{')
50
+ && req.body.trim(/\r\n/g).endsWith('}');
51
+ if (parseRawBody) {
52
+ try {
53
+ req.body = JSON.parse(req.body || '{}');
54
+ }
55
+ catch (err) {
56
+ // throw new Error('invalid body');
57
+ // return { error: 'invalid body', status: 400 };
58
+ }
59
+ }
60
+ });
61
+
62
+ // allow upload file
63
+ const kIsMultipart = Symbol.for('[FastifyMultipart.isMultipart]');
64
+ fastify.addContentTypeParser('multipart', (request, _, done) => {
65
+ request[kIsMultipart] = true;
66
+ done(null);
67
+ });
68
+
69
+ // parse Body
70
+ function contentParser(req, body, done) {
71
+ const parseBody = decodeURIComponent(body.toString()).split('&').reduce((acc, el) => {
72
+ const [key, val] = el.split('=');
73
+ return { ...acc, [key]: val };
74
+ }, {});
75
+ done(null, parseBody);
76
+ }
77
+
78
+ fastify.addContentTypeParser('application/x-www-form-urlencoded', { parseAs: 'buffer' }, contentParser);
79
+ }
80
+
81
+ export default fp(plugin);
@@ -1,11 +1,11 @@
1
- //import { addCron } from '@opengis/fastify-table/utils.js';
2
-
3
- async function deleteOldNotifications({ pg }) {
4
- const { rowCount } = pg?.pk?.['crm.notifications'] ? await pg.query('delete from crm.notifications where CURRENT_DATE - \'14 days\'::interval > cdate') : {};
5
- return { rowCount };
6
- }
7
-
8
- export default async function cron(fastify) {
9
- // addCron(deleteOldNotifications, 60 * 60 * 24, fastify);
10
- // addCron(deleteOldNotifications, 60 * 1, fastify); // debug
1
+ //import { addCron } from '@opengis/fastify-table/utils.js';
2
+
3
+ async function deleteOldNotifications({ pg }) {
4
+ const { rowCount } = pg?.pk?.['crm.notifications'] ? await pg.query('delete from crm.notifications where CURRENT_DATE - \'14 days\'::interval > cdate') : {};
5
+ return { rowCount };
6
+ }
7
+
8
+ export default async function cron(fastify) {
9
+ // addCron(deleteOldNotifications, 60 * 60 * 24, fastify);
10
+ // addCron(deleteOldNotifications, 60 * 1, fastify); // debug
11
11
  }
@@ -1,28 +1,28 @@
1
- 'use strict'
2
-
3
- import path, { dirname } from 'path';
4
- import { fileURLToPath } from 'url';
5
- import fs from 'fs';
6
-
7
- const dir = dirname(fileURLToPath(import.meta.url));
8
- const root = `${dir}/../../`;
9
-
10
-
11
- async function plugin(fastify, opts) {
12
- fastify.get('/docs*', async (req, reply) => {
13
- if (!fs.existsSync(path.join(root, 'docs/.vitepress/dist/'))) {
14
- return reply.status(404).send('docs not exists');
15
- }
16
- const { params } = req;
17
- const url = params['*']
18
- const filePath = url && url[url.length - 1] !== '/' ? path.join(root, 'docs/.vitepress/dist/', url) : path.join(root, 'docs/.vitepress/dist/', url, 'index.html')
19
- const ext = path.extname(filePath);
20
- const mime = {
21
- '.js': 'text/javascript', '.css': 'text/css', '.woff2': 'application/font-woff', '.png': 'image/png', '.svg': 'image/svg+xml', '.jpg': 'image/jpg'
22
- }[ext];
23
- const stream = fs.createReadStream(filePath);
24
- return mime ? reply.type(mime).send(stream) : stream;
25
-
26
- })
27
- }
28
- export default plugin;
1
+ 'use strict'
2
+
3
+ import path, { dirname } from 'path';
4
+ import { fileURLToPath } from 'url';
5
+ import fs from 'fs';
6
+
7
+ const dir = dirname(fileURLToPath(import.meta.url));
8
+ const root = `${dir}/../../`;
9
+
10
+
11
+ async function plugin(fastify, opts) {
12
+ fastify.get('/docs*', async (req, reply) => {
13
+ if (!fs.existsSync(path.join(root, 'docs/.vitepress/dist/'))) {
14
+ return reply.status(404).send('docs not exists');
15
+ }
16
+ const { params } = req;
17
+ const url = params['*']
18
+ const filePath = url && url[url.length - 1] !== '/' ? path.join(root, 'docs/.vitepress/dist/', url) : path.join(root, 'docs/.vitepress/dist/', url, 'index.html')
19
+ const ext = path.extname(filePath);
20
+ const mime = {
21
+ '.js': 'text/javascript', '.css': 'text/css', '.woff2': 'application/font-woff', '.png': 'image/png', '.svg': 'image/svg+xml', '.jpg': 'image/jpg'
22
+ }[ext];
23
+ const stream = fs.createReadStream(filePath);
24
+ return mime ? reply.type(mime).send(stream) : stream;
25
+
26
+ })
27
+ }
28
+ export default plugin;
@@ -1,6 +1,6 @@
1
1
  import path from 'node:path';
2
2
  import { createHash } from 'node:crypto';
3
- import { readFileSync } from 'node:fs';
3
+ import { readFileSync, writeFileSync } from 'node:fs';
4
4
 
5
5
  import {
6
6
  getTemplatePath, addHook, getToken, getTemplate, config, pgClients, initPG, getRedis, logger,
@@ -12,6 +12,9 @@ import printTemplates from '../routes/print/controllers/printTemplates.js';
12
12
  const { client } = pgClients;
13
13
 
14
14
  const rclient = getRedis();
15
+ const cwd = process.cwd();
16
+
17
+ const logDir = path.join(cwd, 'log/migration');
15
18
 
16
19
  export default async function plugin(fastify) {
17
20
  const user1 = config?.auth?.disable || process.env.NODE_ENV !== 'admin' ? { uid: '1' } : null;
@@ -121,28 +124,47 @@ export default async function plugin(fastify) {
121
124
 
122
125
  try {
123
126
  const hashes = await rclient.hgetall('cls-insert-hashes').then(obj => Object.keys(obj));
124
- const names = await pgClients.client.query(`select array_agg(name) from admin.cls where parent is null`).then(el => el.rows?.[0]?.array_agg || []);
127
+ const names = await client.query(`select array_agg(name) from admin.cls where parent is null`).then(el => el.rows?.[0]?.array_agg || []);
125
128
  const qHashes = await Promise.all(cls.filter((el, idx, arr) => arr.map((item) => item.name).indexOf(el.name) === idx).map(async (el) => {
126
129
  const { name, module, type } = el;
127
130
  const loadTemplate = await getTemplate(type, name);
128
- const hash = createHash('md5').update(type === 'cls' ? JSON.stringify(loadTemplate) : (loadTemplate?.sql || loadTemplate)).digest('hex');
129
- if (type === 'select' && (!hashes.includes(hash) || !names.includes(name))) {
131
+ el.hash = createHash('md5').update(type === 'cls' ? JSON.stringify(loadTemplate) : (loadTemplate?.sql || loadTemplate)).digest('hex');
132
+
133
+ const q = {
134
+ cls: `select json_agg(row_to_json(q)) as data from (select code as id, name as text from admin.cls where parent=$1)q`,
135
+ select: `select data from admin.cls where name=$1 and type='sql'`
136
+ }[type];
137
+ const dbdata = q ? await client.query(q, [name]).then(el => el.rows?.[0]?.data) : null;
138
+ el.dbhash = createHash('md5').update(type === 'cls' ? JSON.stringify(dbdata) : (dbdata)).digest('hex');
139
+
140
+ // check for changes by redis hash / dropped from db / changed at git project
141
+ el.update = !hashes.includes(el.hash) || !names.includes(name) || el.hash !== el.dbhash;
142
+
143
+ if (type === 'select' && (loadTemplate?.sql || loadTemplate) && el.update) {
130
144
  clsQuery.push(`insert into admin.cls(name,type,data,module) values('${name}','sql','${(loadTemplate?.sql || loadTemplate)?.replace(/'/g, "''")}', '${module?.replace(/'/g, "''")}')`);
131
- return hash;
132
- } else if (type === 'cls' && loadTemplate?.length && (!hashes.includes(hash) || !names.includes(name))) {
145
+ console.log(name, type, 'insert fresh select');
146
+ return el.hash;
147
+ } else if (type === 'cls' && loadTemplate?.length && el.update) {
133
148
  clsQuery.push(`insert into admin.cls(name,type, module) values('${name}','json', '${module?.replace(/'/g, "''")}');
134
149
  insert into admin.cls(code,name,parent,icon,data)
135
150
  select value->>'id',value->>'text','${name}',value->>'icon',value->>'data'
136
151
  from json_array_elements('${JSON.stringify(loadTemplate).replace(/'/g, "''")}'::json)`);
137
- return hash;
138
- } else if (hashes.includes(hash)) {
152
+ console.log(name, type, 'insert fresh cls');
153
+ return el.hash;
154
+ } else if (hashes.includes(el.hash)) {
139
155
  console.log(name, type, names.includes(name) ? 'skip equal hash' : 'insert missing cls');
156
+ return el.hash;
140
157
  } else {
141
158
  console.log(name, type, 'empty');
159
+ return el.hash;
142
160
  }
143
161
  }));
144
162
 
145
- const { rowCount = 0 } = await client.query('delete from admin.cls where $1::text[] && array[name,parent]', [cls.map(el => el.name)]);
163
+ // debug
164
+ writeFileSync(path.join(logDir, `${path.basename(cwd)}-${client.options?.database}-cls.sql`), clsQuery.filter((el) => el).join(';'));
165
+ writeFileSync(path.join(logDir, `${path.basename(cwd)}-${client.options?.database}-cls.json`), JSON.stringify(cls));
166
+
167
+ const { rowCount = 0 } = await client.query('delete from admin.cls where $1::text[] && array[name,parent]', [cls.filter(el => el.update).map(el => el.name)]);
146
168
  console.log('admin/hook old cls deleted', rowCount);
147
169
  if (clsQuery.filter((el) => el).length) {
148
170
  console.log('admin/hook cls sql start', clsQuery?.length);
@@ -1,30 +1,30 @@
1
- import { pgClients } from '@opengis/fastify-table/utils.js';
2
-
3
- import { getAdminAccess } from '../../../../utils.js';
4
-
5
- export default async function accessGroup({
6
- pg = pgClients.client, params = {}, session = {},
7
- }) {
8
- const { user = {} } = session?.passport || {};
9
-
10
- if (!params?.id) {
11
- return { message: 'not enough params: id', status: 400 };
12
- }
13
-
14
- // restrict access - admin only
15
- const check = await getAdminAccess({
16
- id: params.id, user,
17
- });
18
- if (check) return check;
19
-
20
- const { rows: routes = [] } = await pg.query(`select a.route_id as path, b.actions from admin.routes a
21
- left join admin.role_access b on a.route_id=b.route_id
22
- where b.role_id=$1`, [params.id]);
23
-
24
- const { rows: users = [] } = await pg.query(`select user_uid as id, user_name as name, access_granted,
25
- b.cdate as user_created, b.last_activity_date as last_activity from admin.user_roles a
26
- left join admin.users b on a.user_uid=b.uid
27
- where a.role_id=$1`, [params.id]);
28
-
29
- return { routes, users };
1
+ import { pgClients } from '@opengis/fastify-table/utils.js';
2
+
3
+ import { getAdminAccess } from '../../../../utils.js';
4
+
5
+ export default async function accessGroup({
6
+ pg = pgClients.client, params = {}, session = {},
7
+ }) {
8
+ const { user = {} } = session?.passport || {};
9
+
10
+ if (!params?.id) {
11
+ return { message: 'not enough params: id', status: 400 };
12
+ }
13
+
14
+ // restrict access - admin only
15
+ const check = await getAdminAccess({
16
+ id: params.id, user,
17
+ });
18
+ if (check) return check;
19
+
20
+ const { rows: routes = [] } = await pg.query(`select a.route_id as path, b.actions from admin.routes a
21
+ left join admin.role_access b on a.route_id=b.route_id
22
+ where b.role_id=$1`, [params.id]);
23
+
24
+ const { rows: users = [] } = await pg.query(`select user_uid as id, user_name as name, access_granted,
25
+ b.cdate as user_created, b.last_activity_date as last_activity from admin.user_roles a
26
+ left join admin.users b on a.user_uid=b.uid
27
+ where a.role_id=$1`, [params.id]);
28
+
29
+ return { routes, users };
30
30
  }
@@ -1,55 +1,55 @@
1
- import { pgClients } from '@opengis/fastify-table/utils.js';
2
-
3
- import { getAdminAccess } from '../../../../utils.js';
4
- import accessGroup from './access.group.js';
5
-
6
- export default async function accessGroupPost({
7
- pg = pgClients.client, params = {}, session = {}, body = {},
8
- }) {
9
- const { id } = params;
10
- const { user } = session?.passport || {};
11
- if (!user) return { status: 403, message: 'access restricted' }
12
-
13
- // restrict access - admin only
14
- const check = await getAdminAccess({ id, user });
15
- if (check) return check;
16
-
17
- const { users = [], routes = [] } = body;
18
-
19
- if (!routes?.length) {
20
- // return { message: 'not enough params: users / routes', status: 400 };
21
- await pg.query(`delete from admin.role_access where role_id=$1`, [id]);
22
-
23
- if (!users?.length) {
24
- return { message: { id, routes }, status: 200 };
25
- }
26
- }
27
-
28
- if (routes?.length) {
29
- const { routesDB = [] } = await pg.query('select array_agg(route_id) as "routesDB" from admin.routes where enabled')
30
- .then((res1) => res1.rows?.[0] || {});
31
- await pg.query(`delete from admin.role_access where role_id=$1;`, [id]);
32
-
33
-
34
- const q = `insert into admin.role_access(role_id,route_id,actions) values ($1,$2,$3)`;
35
- await Promise.all(routes.filter(el => routesDB.includes(el.path) && el.actions).map(el => pg.query(q, [id, el.path, el.actions])))
36
-
37
- const { rows } = await pg.query(`select a.route_id as path, b.actions as actions from admin.routes a
38
- left join admin.role_access b on a.route_id=b.route_id
39
- where b.role_id=$1`, [id]);
40
-
41
- if (!users?.length) {
42
- return { message: { id, routes: rows }, status: 200 };
43
- }
44
- }
45
-
46
- const q = `delete from admin.user_roles where role_id='${id.replace(/'/g, "''")}';
47
- insert into admin.user_roles(role_id,user_uid,access_granted)
48
- values ${users.filter((el) => el?.id).map((el) => `('${id.replace(/'/g, "''")}','${el.id.replace(/'/g, "''")}','${uid?.replace(/'/g, "''")}')`)}`;
49
-
50
- await pg.query(q);
51
-
52
- const res = await accessGroup({ pg, params, session });
53
-
54
- return res;
1
+ import { pgClients } from '@opengis/fastify-table/utils.js';
2
+
3
+ import { getAdminAccess } from '../../../../utils.js';
4
+ import accessGroup from './access.group.js';
5
+
6
+ export default async function accessGroupPost({
7
+ pg = pgClients.client, params = {}, session = {}, body = {},
8
+ }) {
9
+ const { id } = params;
10
+ const { user } = session?.passport || {};
11
+ if (!user) return { status: 403, message: 'access restricted' }
12
+
13
+ // restrict access - admin only
14
+ const check = await getAdminAccess({ id, user });
15
+ if (check) return check;
16
+
17
+ const { users = [], routes = [] } = body;
18
+
19
+ if (!routes?.length) {
20
+ // return { message: 'not enough params: users / routes', status: 400 };
21
+ await pg.query(`delete from admin.role_access where role_id=$1`, [id]);
22
+
23
+ if (!users?.length) {
24
+ return { message: { id, routes }, status: 200 };
25
+ }
26
+ }
27
+
28
+ if (routes?.length) {
29
+ const { routesDB = [] } = await pg.query('select array_agg(route_id) as "routesDB" from admin.routes where enabled')
30
+ .then((res1) => res1.rows?.[0] || {});
31
+ await pg.query(`delete from admin.role_access where role_id=$1;`, [id]);
32
+
33
+
34
+ const q = `insert into admin.role_access(role_id,route_id,actions) values ($1,$2,$3)`;
35
+ await Promise.all(routes.filter(el => routesDB.includes(el.path) && el.actions).map(el => pg.query(q, [id, el.path, el.actions])))
36
+
37
+ const { rows } = await pg.query(`select a.route_id as path, b.actions as actions from admin.routes a
38
+ left join admin.role_access b on a.route_id=b.route_id
39
+ where b.role_id=$1`, [id]);
40
+
41
+ if (!users?.length) {
42
+ return { message: { id, routes: rows }, status: 200 };
43
+ }
44
+ }
45
+
46
+ const q = `delete from admin.user_roles where role_id='${id.replace(/'/g, "''")}';
47
+ insert into admin.user_roles(role_id,user_uid,access_granted)
48
+ values ${users.filter((el) => el?.id).map((el) => `('${id.replace(/'/g, "''")}','${el.id.replace(/'/g, "''")}','${uid?.replace(/'/g, "''")}')`)}`;
49
+
50
+ await pg.query(q);
51
+
52
+ const res = await accessGroup({ pg, params, session });
53
+
54
+ return res;
55
55
  }
@@ -1,11 +1,11 @@
1
- import accessGroup from "./controllers/access.group.js";
2
- import accessGroupPost from "./controllers/access.group.post.js";
3
- import accessInterface from "./controllers/access.interface.js";
4
-
5
- import { accessGroupPostSchema, accessGroupSchema, accessInterfaceSchema } from "./schema.mjs";
6
-
7
- export default async function route(fastify) {
8
- fastify.get('/access-group/:id', { schema: accessGroupSchema }, accessGroup);
9
- fastify.post('/access-group/:id', { schema: accessGroupPostSchema }, accessGroupPost);
10
- fastify.get('/access-interface/:name', { schema: accessInterfaceSchema }, accessInterface);
11
- }
1
+ import accessGroup from "./controllers/access.group.js";
2
+ import accessGroupPost from "./controllers/access.group.post.js";
3
+ import accessInterface from "./controllers/access.interface.js";
4
+
5
+ import { accessGroupPostSchema, accessGroupSchema, accessInterfaceSchema } from "./schema.mjs";
6
+
7
+ export default async function route(fastify) {
8
+ fastify.get('/access-group/:id', { schema: accessGroupSchema }, accessGroup);
9
+ fastify.post('/access-group/:id', { schema: accessGroupPostSchema }, accessGroupPost);
10
+ fastify.get('/access-interface/:name', { schema: accessInterfaceSchema }, accessInterface);
11
+ }