@opengis/admin 0.3.41 → 0.3.43
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/README.md +97 -97
- package/config.js +4 -4
- package/dist/{add-page-DmhwcAMY.js → add-page-D7DejR6f.js} +1 -1
- package/dist/{admin-interface-5dHYgR-t.js → admin-interface-D1ILPfFS.js} +2 -2
- package/dist/{admin-view-C7JteOit.js → admin-view-BV5GiUFB.js} +1 -1
- package/dist/admin.js +1 -1
- package/dist/admin.umd.cjs +68 -68
- package/dist/assets/logo.svg +41 -41
- package/dist/{card-view-Cey1LE5b.js → card-view-DnHFSCxY.js} +1 -1
- package/dist/{edit-page-C-cpKJC2.js → edit-page-BfW1ystC.js} +1 -1
- package/dist/{import-file-B53vJ2ve.js → import-file-dlOWa1-N.js} +20272 -19862
- package/dist/{profile-page-BqYeCCjU.js → profile-page-BHl9qGJX.js} +1 -1
- package/dist/style.css +1 -1
- package/module/settings/card/admin.accounts.table/index.yml +7 -7
- package/module/settings/card/admin.accounts.table/rules.hbs +18 -18
- package/module/settings/card/admin.accounts.table/users.hbs +13 -13
- package/module/settings/card/admin.routes.table/groups.hbs +11 -11
- package/module/settings/card/admin.routes.table/users.hbs +16 -16
- package/module/settings/cls/core.actions.json +17 -17
- package/module/settings/cls/core.scope.json +13 -13
- package/module/settings/cls/properties.site_status.json +13 -13
- package/module/settings/cls/properties.widget_status.json +13 -13
- package/module/settings/cls/users.user_type.json +13 -13
- package/module/settings/cls/yes_no.json +11 -11
- package/module/settings/form/admin.accounts.form.json +13 -13
- package/module/settings/form/admin.properties.form.json +15 -15
- package/module/settings/form/admin.roles.form.json +21 -21
- package/module/settings/form/admin.user_properties.form.json +15 -15
- package/module/settings/form/admin.user_roles_card.form.json +13 -13
- package/module/settings/interface/admin.properties.json +4 -4
- package/module/settings/interface/admin.roles.json +4 -4
- package/module/settings/interface/admin.routes.json +4 -4
- package/module/settings/interface/admin.users.json +4 -4
- package/module/settings/select/core.routes.sql +1 -1
- package/module/settings/select/core.user_mentioned.sql +1 -1
- package/module/settings/select/core.user_uid.sql +1 -1
- package/module/settings/table/admin.properties.table.json +39 -39
- package/module/settings/table/admin.user_properties.table.json +34 -34
- package/package.json +4 -4
- package/server/helpers/core/badge.js +16 -16
- package/server/helpers/core/buttonHelper.js +21 -21
- package/server/helpers/core/coalesce.js +7 -7
- package/server/helpers/core/select.js +48 -48
- package/server/helpers/core/token.js +18 -18
- package/server/helpers/list/buttonHelper.js +21 -21
- package/server/helpers/list/utils/button.js +5 -5
- package/server/helpers/temp/contentList.js +58 -58
- package/server/helpers/temp/ifCond.js +101 -101
- package/server/helpers/utils/button.js +5 -5
- package/server/helpers/utils/mdToHTML.js +17 -17
- package/server/plugins/access/index.mjs +6 -6
- package/server/plugins/adminHook.js +81 -81
- package/server/plugins/cron.js +10 -10
- package/server/plugins/docs.js +28 -28
- package/server/plugins/hook.js +5 -13
- package/server/routes/access/controllers/access.group.js +29 -29
- package/server/routes/access/controllers/access.group.post.js +54 -54
- package/server/routes/access/index.mjs +11 -11
- package/server/routes/access/schema.mjs +67 -67
- package/server/routes/calendar/controllers/calendar.data.js +125 -125
- package/server/routes/calendar/index.mjs +7 -7
- package/server/routes/calendar/schema.js +21 -21
- package/server/routes/data/controllers/cardTabData.js +49 -49
- package/server/routes/data/controllers/funcs/getFilterSQL/index.js +92 -92
- package/server/routes/data/controllers/funcs/getFilterSQL/util/formatValue.js +170 -170
- package/server/routes/data/controllers/funcs/getFilterSQL/util/getCustomQuery.js +13 -13
- package/server/routes/data/controllers/funcs/getFilterSQL/util/getFilterQuery.js +64 -64
- package/server/routes/data/controllers/funcs/getFilterSQL/util/getOptimizedQuery.js +12 -12
- package/server/routes/data/controllers/funcs/getFilterSQL/util/getTableSql.js +34 -34
- package/server/routes/data/controllers/tableDataId.js +27 -27
- package/server/routes/data/controllers/tokenInfo.js +9 -9
- package/server/routes/data/controllers/utils/assignTokens.js +30 -30
- package/server/routes/data/controllers/utils/conditions.js +20 -20
- package/server/routes/data/controllers/utils/getColumns.js +8 -8
- package/server/routes/data/index.mjs +20 -20
- package/server/routes/data/schema.js +54 -54
- package/server/routes/notifications/controllers/readNotifications.js +18 -18
- package/server/routes/notifications/controllers/testEmail.js +35 -35
- package/server/routes/notifications/controllers/userNotifications.js +53 -53
- package/server/routes/notifications/hook/onWidgetSet.js +56 -56
- package/server/routes/notifications/index.mjs +26 -26
- package/server/routes/notifications/schema.js +16 -16
- package/server/routes/print/controllers/cardPrint.js +135 -135
- package/server/routes/properties/schema.js +10 -10
- package/server/routes/report/controllers/data.js +76 -76
- package/server/routes/report/controllers/list.js +18 -18
- package/server/routes/report/index.mjs +7 -7
- package/server/routes/report/utils/formatValue.js +179 -179
- package/server/routes/root.mjs +3 -3
- package/server/routes/templates/controllers/getTemplate.js +44 -44
- package/server/routes/templates/schema.js +8 -8
- package/server/routes/user/controllers/user.cls.id.js +14 -14
- package/server/routes/user/controllers/user.cls.js +72 -72
- package/server/routes/user/controllers/user.info.js +17 -17
- package/server/routes/user/schema.js +14 -14
- package/server/routes/util/controllers/code.generator.js +89 -89
- package/server/routes/widget/controllers/widget.del.js +80 -80
- package/server/routes/widget/controllers/widget.set.js +93 -93
- package/server/routes/widget/hook/onWidgetSet.js +12 -12
- package/server/routes/widget/index.mjs +16 -16
- package/server/routes/widget/schema.js +12 -12
- package/server/templates/cls/itree.recrzone_category.json +73 -73
- package/server/templates/cls/test.json +9 -9
- package/server/templates/form/admin.user_cls.data.form.json +49 -49
- package/server/templates/form/admin.user_group_rel.form.json +21 -21
- package/server/templates/form/form-user-pass.json +10 -10
- package/server/templates/form/form-user_group.json +39 -39
- package/server/templates/form/form-users.json +156 -156
- package/server/templates/form/user_group_access.form.json +22 -22
- package/server/templates/select/account_id.json +2 -2
- package/server/templates/table/gis.dataset.table.json +43 -43
- package/server/templates/table/management.user_group.table.json +112 -112
- package/server/templates/table/management.users.table.json +126 -126
- package/server/utils/addNotification.js +21 -21
- 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);
|
package/server/plugins/cron.js
CHANGED
@@ -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
|
}
|
package/server/plugins/docs.js
CHANGED
@@ -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;
|
package/server/plugins/hook.js
CHANGED
@@ -119,33 +119,25 @@ export default async function plugin(fastify) {
|
|
119
119
|
?.map((el) => ({ name: el[0], module: path.basename(path.dirname(path.dirname(el[1]))), type: { 'json': 'cls', 'sql': 'select' }[el[2]] }))
|
120
120
|
if (!cls?.length) return;
|
121
121
|
|
122
|
-
const dupes = cls.filter((el, idx, arr) => arr.map((item) => item.name).indexOf(el.name) !== idx);
|
123
|
-
//console.log('cls insert skip dupes', dupes.map((el) => el.name));
|
124
|
-
|
125
122
|
try {
|
126
123
|
const hashes = await rclient.hgetall('cls-insert-hashes').then(obj => Object.keys(obj));
|
127
|
-
const
|
124
|
+
const dbdata = await client.query(`select json_object_agg(name, hash) from admin.cls where parent is null`).then(el => el.rows?.[0]?.json_object_agg || {});
|
125
|
+
const names = Object.keys(dbdata);
|
128
126
|
const qHashes = await Promise.all(cls.filter((el, idx, arr) => arr.map((item) => item.name).indexOf(el.name) === idx).map(async (el) => {
|
129
127
|
const { name, module, type } = el;
|
130
128
|
const loadTemplate = await getTemplate(type, name);
|
131
129
|
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');
|
130
|
+
el.dbhash = dbdata[name];
|
139
131
|
|
140
132
|
// check for changes by redis hash / dropped from db / changed at git project
|
141
133
|
el.update = !hashes.includes(el.hash) || !names.includes(name) || el.hash !== el.dbhash;
|
142
134
|
|
143
135
|
if (type === 'select' && (loadTemplate?.sql || loadTemplate) && el.update) {
|
144
|
-
clsQuery.push(`insert into admin.cls(name,type,data,module) values('${name}','sql','${(loadTemplate?.sql || loadTemplate)?.replace(/'/g, "''")}', '${module?.replace(/'/g, "''")}')`);
|
136
|
+
clsQuery.push(`insert into admin.cls(name,type,data,module,hash) values('${name}','sql','${(loadTemplate?.sql || loadTemplate)?.replace(/'/g, "''")}', '${module?.replace(/'/g, "''")}','${el.hash}')`);
|
145
137
|
console.log(name, type, 'insert fresh select');
|
146
138
|
return el.hash;
|
147
139
|
} else if (type === 'cls' && loadTemplate?.length && el.update) {
|
148
|
-
clsQuery.push(`insert into admin.cls(name,type, module) values('${name}','json', '${module?.replace(/'/g, "''")}');
|
140
|
+
clsQuery.push(`insert into admin.cls(name,type, module,hash) values('${name}','json', '${module?.replace(/'/g, "''")}','${el.hash}');
|
149
141
|
insert into admin.cls(code,name,parent,icon,data)
|
150
142
|
select value->>'id',value->>'text','${name}',value->>'icon',value->>'data'
|
151
143
|
from json_array_elements('${JSON.stringify(loadTemplate).replace(/'/g, "''")}'::json)`);
|
@@ -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
|
+
}
|
@@ -1,68 +1,68 @@
|
|
1
|
-
export default null;
|
2
|
-
export { accessGroupSchema, accessGroupPostSchema, accessInterfaceSchema }
|
3
|
-
|
4
|
-
const accessGroupSchema = {
|
5
|
-
params: {
|
6
|
-
type: 'object',
|
7
|
-
properties: {
|
8
|
-
id: { type: 'string', pattern: '^([\\d\\w._-]+)$' },
|
9
|
-
},
|
10
|
-
required: ['id'],
|
11
|
-
},
|
12
|
-
};
|
13
|
-
|
14
|
-
const accessInterfaceSchema = {
|
15
|
-
params: {
|
16
|
-
type: 'object',
|
17
|
-
properties: {
|
18
|
-
name: { type: 'string', pattern: '^([\\d\\w._-]+)$' },
|
19
|
-
},
|
20
|
-
required: ['name'],
|
21
|
-
},
|
22
|
-
};
|
23
|
-
|
24
|
-
const accessGroupPostSchema = {
|
25
|
-
params: {
|
26
|
-
type: 'object',
|
27
|
-
properties: {
|
28
|
-
id: { type: 'string', pattern: '^([\\d\\w._-]+)$' },
|
29
|
-
},
|
30
|
-
required: ['id'],
|
31
|
-
},
|
32
|
-
body: {
|
33
|
-
type: 'object',
|
34
|
-
properties: {
|
35
|
-
users: {
|
36
|
-
type: 'array',
|
37
|
-
items: {
|
38
|
-
type: 'object',
|
39
|
-
properties: {
|
40
|
-
id: {
|
41
|
-
type: 'string',
|
42
|
-
pattern: '^([\\d\\w._-]+)$',
|
43
|
-
},
|
44
|
-
},
|
45
|
-
},
|
46
|
-
},
|
47
|
-
routes: {
|
48
|
-
type: 'array',
|
49
|
-
/*items: {
|
50
|
-
type: 'object',
|
51
|
-
properties: {
|
52
|
-
path: {
|
53
|
-
type: 'string',
|
54
|
-
pattern: '^([\\d\\w._-]+)$',
|
55
|
-
},
|
56
|
-
actions: {
|
57
|
-
type: 'array',
|
58
|
-
items: {
|
59
|
-
type: 'string',
|
60
|
-
enum: ['get', 'add', 'edit', 'del'],
|
61
|
-
},
|
62
|
-
},
|
63
|
-
},
|
64
|
-
},*/
|
65
|
-
},
|
66
|
-
},
|
67
|
-
},
|
1
|
+
export default null;
|
2
|
+
export { accessGroupSchema, accessGroupPostSchema, accessInterfaceSchema }
|
3
|
+
|
4
|
+
const accessGroupSchema = {
|
5
|
+
params: {
|
6
|
+
type: 'object',
|
7
|
+
properties: {
|
8
|
+
id: { type: 'string', pattern: '^([\\d\\w._-]+)$' },
|
9
|
+
},
|
10
|
+
required: ['id'],
|
11
|
+
},
|
12
|
+
};
|
13
|
+
|
14
|
+
const accessInterfaceSchema = {
|
15
|
+
params: {
|
16
|
+
type: 'object',
|
17
|
+
properties: {
|
18
|
+
name: { type: 'string', pattern: '^([\\d\\w._-]+)$' },
|
19
|
+
},
|
20
|
+
required: ['name'],
|
21
|
+
},
|
22
|
+
};
|
23
|
+
|
24
|
+
const accessGroupPostSchema = {
|
25
|
+
params: {
|
26
|
+
type: 'object',
|
27
|
+
properties: {
|
28
|
+
id: { type: 'string', pattern: '^([\\d\\w._-]+)$' },
|
29
|
+
},
|
30
|
+
required: ['id'],
|
31
|
+
},
|
32
|
+
body: {
|
33
|
+
type: 'object',
|
34
|
+
properties: {
|
35
|
+
users: {
|
36
|
+
type: 'array',
|
37
|
+
items: {
|
38
|
+
type: 'object',
|
39
|
+
properties: {
|
40
|
+
id: {
|
41
|
+
type: 'string',
|
42
|
+
pattern: '^([\\d\\w._-]+)$',
|
43
|
+
},
|
44
|
+
},
|
45
|
+
},
|
46
|
+
},
|
47
|
+
routes: {
|
48
|
+
type: 'array',
|
49
|
+
/*items: {
|
50
|
+
type: 'object',
|
51
|
+
properties: {
|
52
|
+
path: {
|
53
|
+
type: 'string',
|
54
|
+
pattern: '^([\\d\\w._-]+)$',
|
55
|
+
},
|
56
|
+
actions: {
|
57
|
+
type: 'array',
|
58
|
+
items: {
|
59
|
+
type: 'string',
|
60
|
+
enum: ['get', 'add', 'edit', 'del'],
|
61
|
+
},
|
62
|
+
},
|
63
|
+
},
|
64
|
+
},*/
|
65
|
+
},
|
66
|
+
},
|
67
|
+
},
|
68
68
|
};
|