@opengis/fastify-table 2.4.1 → 2.4.2
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 +86 -86
- package/dist/functions.js +20 -20
- package/dist/module/core/cls/constraint_action.json +9 -9
- package/dist/module/core/cls/constraint_matchtype.json +5 -5
- package/dist/module/core/cls/constraint_type_full.json +17 -17
- package/dist/module/core/cls/core.user_type.json +13 -13
- package/dist/module/core/pt/schemaItem.pt.hbs +17 -17
- package/dist/script/adduser +14 -14
- package/dist/script/dump.js +48 -48
- package/dist/script/dump.ts +216 -216
- package/dist/script/migrate.ts +41 -41
- package/dist/server/helpers/core/badge.js +1 -1
- package/dist/server/helpers/list/descriptionList.js +8 -8
- package/dist/server/helpers/list/tableList.js +4 -4
- package/dist/server/helpers/list/utils/button.js +1 -1
- package/dist/server/helpers/list/utils/buttonDel.js +3 -3
- package/dist/server/helpers/list/utils/buttonEdit.js +3 -3
- package/dist/server/helpers/utils/button.js +1 -1
- package/dist/server/helpers/utils/buttonAdd.js +15 -15
- package/dist/server/helpers/utils/buttonDel.js +11 -11
- package/dist/server/helpers/utils/buttonEdit.js +3 -3
- package/dist/server/migrations/0.sql +99 -99
- package/dist/server/migrations/cls.sql +105 -105
- package/dist/server/migrations/context.sql +136 -136
- package/dist/server/migrations/oauth.sql +79 -79
- package/dist/server/migrations/properties.sql +115 -115
- package/dist/server/migrations/roles.sql +195 -195
- package/dist/server/migrations/template.sql +43 -43
- package/dist/server/migrations/users.sql +151 -151
- package/dist/server/plugins/access/funcs/getUserPermissions.js +7 -7
- package/dist/server/plugins/auth/funcs/authorizeUser.js +4 -4
- package/dist/server/plugins/auth/funcs/getQuery.js +20 -20
- package/dist/server/plugins/crud/funcs/dataUpdate.js +7 -7
- package/dist/server/plugins/crud/funcs/getAccess.js +14 -14
- package/dist/server/plugins/crud/funcs/utils/getInsertQuery.js +6 -6
- package/dist/server/plugins/crud/funcs/utils/logChanges.js +18 -18
- package/dist/server/plugins/grpc/utils/convertp.proto +136 -136
- package/dist/server/plugins/grpc/utils/htmlTemplate.js +10 -10
- package/dist/server/plugins/grpc/utils/office2pdf.proto +13 -13
- package/dist/server/plugins/metric/loggerSystem.js +1 -1
- package/dist/server/plugins/pg/funcs/autoIndex.js +5 -5
- package/dist/server/plugins/pg/funcs/getMeta.js +10 -10
- package/dist/server/plugins/pg/funcs/init.js +36 -36
- package/dist/server/plugins/sqlite/funcs/init.js +22 -22
- package/dist/server/plugins/table/funcs/getFilterSQL/util/getCustomQuery.js +1 -1
- package/dist/server/plugins/table/funcs/getSelect.js +1 -1
- package/dist/server/plugins/table/funcs/gisIRColumn.js +3 -3
- package/dist/server/plugins/usercls/index.js +2 -2
- package/dist/server/routes/access/controllers/access.group.js +6 -6
- package/dist/server/routes/access/controllers/access.group.post.js +5 -5
- package/dist/server/routes/access/controllers/access.interface.js +14 -14
- package/dist/server/routes/access/controllers/access.user.js +6 -6
- package/dist/server/routes/auth/controllers/2factor/providers/totp.js +5 -5
- package/dist/server/routes/auth/controllers/2factor/qrcode.js +1 -1
- package/dist/server/routes/auth/controllers/2factor/recovery.js +1 -1
- package/dist/server/routes/auth/controllers/2factor/verify.js +1 -1
- package/dist/server/routes/auth/controllers/core/getUserInfo.js +33 -33
- package/dist/server/routes/auth/controllers/core/passwordRecovery.js +1 -1
- package/dist/server/routes/auth/controllers/core/registration.js +2 -2
- package/dist/server/routes/auth/controllers/page/login2faTemplate.js +1 -1
- package/dist/server/routes/file/controllers/resizeAll.js +6 -6
- package/dist/server/routes/grpc/controllers/file2geojson.js +13 -13
- package/dist/server/routes/menu/controllers/getMenu.js +9 -9
- package/dist/server/routes/notifications/controllers/readNotifications.js +4 -4
- package/dist/server/routes/notifications/controllers/userNotifications.js +3 -3
- package/dist/server/routes/table/controllers/card.js +1 -1
- package/dist/server/routes/table/controllers/filter.js +6 -6
- package/dist/server/routes/table/controllers/form.js +1 -1
- package/dist/server/routes/table/controllers/getFormByTable.js +6 -6
- package/dist/server/routes/table/controllers/suggest.js +3 -3
- package/dist/server/routes/table/controllers/tableData.js +2 -2
- package/dist/server/routes/table/controllers/tableInfo.js +10 -10
- package/dist/server/routes/table/functions/getData.js +13 -13
- package/dist/server/routes/widget/controllers/widget.get.js +33 -33
- package/dist/server/routes/widget/controllers/widget.set.js +3 -3
- package/dist/server/templates/page/2factor-recovery.html +101 -101
- package/dist/server/templates/page/2factor.html +140 -140
- package/dist/server/templates/page/login.html +90 -90
- package/dist/server/templates/page/loginEuSign.html +123 -123
- package/dist/server/templates/pt/recovery-codes-email-template.hbs +12 -12
- package/dist/server/templates/pt/recovery-password-email-template.html +20 -20
- package/package.json +98 -98
|
@@ -1,19 +1,19 @@
|
|
|
1
1
|
// import { type ExtendedRequest } from "../../../types/core.js";
|
|
2
2
|
import { pgClients, metaFormat, getAdminAccess } from "../../../../utils.js";
|
|
3
|
-
const q = `select a.route_id as id, coalesce(b.user_uid, d.user_uid) as user_uid, coalesce(d.actions, b.actions, array['view']) as actions, b.scope, c.role_id
|
|
4
|
-
from admin.routes a
|
|
5
|
-
left join admin.role_access b on
|
|
6
|
-
a.route_id=b.route_id
|
|
7
|
-
left join admin.roles c on
|
|
8
|
-
b.role_id=c.role_id
|
|
9
|
-
and c.enabled
|
|
10
|
-
left join admin.user_roles d on
|
|
11
|
-
c.role_id=d.role_id
|
|
12
|
-
and ( case when
|
|
13
|
-
d.expiration is not null
|
|
14
|
-
then d.expiration > CURRENT_DATE
|
|
15
|
-
else 1=1
|
|
16
|
-
end )
|
|
3
|
+
const q = `select a.route_id as id, coalesce(b.user_uid, d.user_uid) as user_uid, coalesce(d.actions, b.actions, array['view']) as actions, b.scope, c.role_id
|
|
4
|
+
from admin.routes a
|
|
5
|
+
left join admin.role_access b on
|
|
6
|
+
a.route_id=b.route_id
|
|
7
|
+
left join admin.roles c on
|
|
8
|
+
b.role_id=c.role_id
|
|
9
|
+
and c.enabled
|
|
10
|
+
left join admin.user_roles d on
|
|
11
|
+
c.role_id=d.role_id
|
|
12
|
+
and ( case when
|
|
13
|
+
d.expiration is not null
|
|
14
|
+
then d.expiration > CURRENT_DATE
|
|
15
|
+
else 1=1
|
|
16
|
+
end )
|
|
17
17
|
where $1 in (a.route_id, a.alias, a.table_name) and coalesce(b.user_uid, d.user_uid) is not null`;
|
|
18
18
|
export default async function accessInterface(req, reply) {
|
|
19
19
|
const { pg = pgClients.client, params = {}, user = {}, unittest } = req;
|
|
@@ -6,18 +6,18 @@ export default async function accessUser(req) {
|
|
|
6
6
|
}
|
|
7
7
|
const { pg = pgClients.client } = req;
|
|
8
8
|
const routes = await pg
|
|
9
|
-
.query(`select a.route_id as path, b.actions from admin.routes a
|
|
10
|
-
left join admin.role_access b on a.route_id=b.route_id
|
|
9
|
+
.query(`select a.route_id as path, b.actions from admin.routes a
|
|
10
|
+
left join admin.role_access b on a.route_id=b.route_id
|
|
11
11
|
where b.user_uid=$1`, [req.params.id])
|
|
12
12
|
.then((el) => el.rows || []);
|
|
13
13
|
const resources = await pg
|
|
14
|
-
.query(`select resource_id, actions from admin.role_access
|
|
14
|
+
.query(`select resource_id, actions from admin.role_access
|
|
15
15
|
where resource_id is not null and user_uid=$1`, [req.params.id])
|
|
16
16
|
.then((el) => el.rows || []);
|
|
17
17
|
const user = await pg
|
|
18
|
-
.query(`select user_uid as id, user_name as name, access_granted,
|
|
19
|
-
b.cdate as user_created, b.last_activity_date as last_activity from admin.user_roles a
|
|
20
|
-
left join admin.users b on a.user_uid=b.uid
|
|
18
|
+
.query(`select user_uid as id, user_name as name, access_granted,
|
|
19
|
+
b.cdate as user_created, b.last_activity_date as last_activity from admin.user_roles a
|
|
20
|
+
left join admin.users b on a.user_uid=b.uid
|
|
21
21
|
where a.user_uid=$1`, [req.params.id])
|
|
22
22
|
.then((el) => el.rows?.[0]);
|
|
23
23
|
return { routes, resources, user };
|
|
@@ -18,20 +18,20 @@ const deleteSecret = async ({ uid, pg }) => {
|
|
|
18
18
|
};
|
|
19
19
|
const getSecret = async ({ uid, pg }) => {
|
|
20
20
|
const { social_auth_code: secret, enabled, recoveryCodes, } = await pg
|
|
21
|
-
.query(`select social_auth_code, enabled, social_auth_obj->'codesArray' as "recoveryCodes"
|
|
22
|
-
from admin.users_social_auth
|
|
21
|
+
.query(`select social_auth_code, enabled, social_auth_obj->'codesArray' as "recoveryCodes"
|
|
22
|
+
from admin.users_social_auth
|
|
23
23
|
where uid = $1 and social_auth_type = $2`, [uid, TYPE])
|
|
24
24
|
.then((el) => el.rows?.[0] || {});
|
|
25
25
|
return { secret, enabled, recoveryCodes };
|
|
26
26
|
};
|
|
27
27
|
const addSecret = async ({ uid, secret, pg, recoveryCodes, otp }) => {
|
|
28
|
-
await pg.query(`insert into admin.users_social_auth(uid, social_auth_code, social_auth_type, social_auth_obj, social_auth_url, enabled)
|
|
28
|
+
await pg.query(`insert into admin.users_social_auth(uid, social_auth_code, social_auth_type, social_auth_obj, social_auth_url, enabled)
|
|
29
29
|
values($1, $2, $3, $4::json, $5, false)`, [uid, secret, TYPE, { codesArray: recoveryCodes }, otp]);
|
|
30
30
|
};
|
|
31
31
|
const updateSecret = async ({ uid, pg, secret, recoveryCodes, otp }) => {
|
|
32
32
|
const result = await pg
|
|
33
|
-
.query(`update admin.users_social_auth
|
|
34
|
-
set social_auth_code=$3, social_auth_obj=$4::json, social_auth_url=$5
|
|
33
|
+
.query(`update admin.users_social_auth
|
|
34
|
+
set social_auth_code=$3, social_auth_obj=$4::json, social_auth_url=$5
|
|
35
35
|
where uid = $1 and social_auth_type = $2`, [uid, TYPE, secret, { codesArray: recoveryCodes }, otp])
|
|
36
36
|
.then((el) => el.rows?.[0] || {});
|
|
37
37
|
return result;
|
|
@@ -24,7 +24,7 @@ export default async function qrCode(req, reply) {
|
|
|
24
24
|
const { enabled, secret } = await getSecret({ pg, uid });
|
|
25
25
|
const { otp } = secret
|
|
26
26
|
? await pg
|
|
27
|
-
.query(`select social_auth_url as otp from admin.users_social_auth
|
|
27
|
+
.query(`select social_auth_url as otp from admin.users_social_auth
|
|
28
28
|
where uid=$1 and social_auth_type=$2`, [uid, "TOTP"])
|
|
29
29
|
?.then((el) => el.rows?.[0] || {})
|
|
30
30
|
: await generate({ uid, pg });
|
|
@@ -48,7 +48,7 @@ export default async function recovery(req, reply) {
|
|
|
48
48
|
const pt = customPt ||
|
|
49
49
|
(await readFile(path.join(dirname, `../../../../../templates/pt/${template}.html`), "utf8"));
|
|
50
50
|
const recoveryCodes = await pg
|
|
51
|
-
.query(`select social_auth_obj->'codesArray' as "recoveryCodes" from admin.users_social_auth
|
|
51
|
+
.query(`select social_auth_obj->'codesArray' as "recoveryCodes" from admin.users_social_auth
|
|
52
52
|
where uid = $1 and social_auth_type = $2`, [uid, "TOTP"])
|
|
53
53
|
.then((el) => el.rows?.[0]?.recoveryCodes || []);
|
|
54
54
|
if (!recoveryCodes?.length) {
|
|
@@ -48,7 +48,7 @@ export default async function verifyFunction(req, reply) {
|
|
|
48
48
|
req.session.secondFactorPassed = true;
|
|
49
49
|
if (!enabled && email) {
|
|
50
50
|
const { recoveryCodes } = await pg
|
|
51
|
-
.query(`select social_auth_obj->'codesArray' as "recoveryCodes"
|
|
51
|
+
.query(`select social_auth_obj->'codesArray' as "recoveryCodes"
|
|
52
52
|
from admin.users_social_auth where uid=$1 and social_auth_type='TOTP'`, [uid])
|
|
53
53
|
?.then((el) => el.rows?.[0] || {});
|
|
54
54
|
const customPt = await getTemplate("pt", template);
|
|
@@ -5,31 +5,31 @@ import applyHook from "../../../../plugins/hook/applyHook.js";
|
|
|
5
5
|
import getRedis from "../../../../plugins/redis/funcs/getRedis.js";
|
|
6
6
|
import getUserPermissions from "../../../../plugins/access/funcs/getUserPermissions.js";
|
|
7
7
|
const rclient2 = getRedis({ db: 2 });
|
|
8
|
-
const q = `select
|
|
9
|
-
|
|
10
|
-
a.route_id as id,
|
|
11
|
-
/* coalesce(d.actions, array['view', 'edit','add','del']) as role_actions,
|
|
12
|
-
coalesce(b.actions, array['view']) as interface_actions, */
|
|
13
|
-
array_intersect(coalesce(b.actions, array['view']), coalesce(d.actions, array['view', 'edit','add','del'])) as actions,
|
|
14
|
-
b.scope,
|
|
15
|
-
c.role_id,
|
|
16
|
-
c.name as role_name
|
|
17
|
-
|
|
18
|
-
from admin.routes a
|
|
19
|
-
left join admin.role_access b on
|
|
20
|
-
a.route_id=b.route_id
|
|
21
|
-
left join admin.roles c on
|
|
22
|
-
b.role_id=c.role_id
|
|
23
|
-
and c.enabled
|
|
24
|
-
left join admin.user_roles d on
|
|
25
|
-
c.role_id=d.role_id
|
|
26
|
-
and (
|
|
27
|
-
case when
|
|
28
|
-
d.expiration is not null
|
|
29
|
-
then d.expiration > CURRENT_DATE
|
|
30
|
-
else 1=1
|
|
31
|
-
end
|
|
32
|
-
)
|
|
8
|
+
const q = `select
|
|
9
|
+
|
|
10
|
+
a.route_id as id,
|
|
11
|
+
/* coalesce(d.actions, array['view', 'edit','add','del']) as role_actions,
|
|
12
|
+
coalesce(b.actions, array['view']) as interface_actions, */
|
|
13
|
+
array_intersect(coalesce(b.actions, array['view']), coalesce(d.actions, array['view', 'edit','add','del'])) as actions,
|
|
14
|
+
b.scope,
|
|
15
|
+
c.role_id,
|
|
16
|
+
c.name as role_name
|
|
17
|
+
|
|
18
|
+
from admin.routes a
|
|
19
|
+
left join admin.role_access b on
|
|
20
|
+
a.route_id=b.route_id
|
|
21
|
+
left join admin.roles c on
|
|
22
|
+
b.role_id=c.role_id
|
|
23
|
+
and c.enabled
|
|
24
|
+
left join admin.user_roles d on
|
|
25
|
+
c.role_id=d.role_id
|
|
26
|
+
and (
|
|
27
|
+
case when
|
|
28
|
+
d.expiration is not null
|
|
29
|
+
then d.expiration > CURRENT_DATE
|
|
30
|
+
else 1=1
|
|
31
|
+
end
|
|
32
|
+
)
|
|
33
33
|
where $1 in (b.user_uid, d.user_uid)`;
|
|
34
34
|
export default async function getUserInfo(req) {
|
|
35
35
|
const { pg = pgClients.client, user, session, cookies } = req;
|
|
@@ -53,14 +53,14 @@ export default async function getUserInfo(req) {
|
|
|
53
53
|
: config.settingKeys || ["site", "map", "admin"];
|
|
54
54
|
const settings = pg?.pk?.["admin.properties"]
|
|
55
55
|
? await pg
|
|
56
|
-
.query(`select
|
|
57
|
-
property_key as key,
|
|
58
|
-
case
|
|
59
|
-
when property_text is not null then to_jsonb(property_text)
|
|
60
|
-
when property_int is not null then to_jsonb(property_int)
|
|
61
|
-
when property_json is not null then property_json::jsonb
|
|
62
|
-
end as val
|
|
63
|
-
from admin.properties
|
|
56
|
+
.query(`select
|
|
57
|
+
property_key as key,
|
|
58
|
+
case
|
|
59
|
+
when property_text is not null then to_jsonb(property_text)
|
|
60
|
+
when property_int is not null then to_jsonb(property_int)
|
|
61
|
+
when property_json is not null then property_json::jsonb
|
|
62
|
+
end as val
|
|
63
|
+
from admin.properties
|
|
64
64
|
where property_key like any($1)`, [settingKeys.map((key) => `${key}%`)])
|
|
65
65
|
.then((el) => el.rows.reduce((p, { key, val }) => {
|
|
66
66
|
const [k1, k2] = key.split(".");
|
|
@@ -78,7 +78,7 @@ export default async function passwordRecovery(req, reply) {
|
|
|
78
78
|
if (config.pg) {
|
|
79
79
|
await pg.query(q, [code, body.email]);
|
|
80
80
|
}
|
|
81
|
-
const userQuery = `select coalesce(sur_name,'')|| coalesce(' '||user_name,'')||coalesce(' '||father_name,'') as user
|
|
81
|
+
const userQuery = `select coalesce(sur_name,'')|| coalesce(' '||user_name,'')||coalesce(' '||father_name,'') as user
|
|
82
82
|
from admin.users where $1 in (login,email) limit 1`;
|
|
83
83
|
const userName = config.pg
|
|
84
84
|
? await pg
|
|
@@ -84,8 +84,8 @@ export default async function registration(req, reply) {
|
|
|
84
84
|
const { uid } = await pg
|
|
85
85
|
.query(q3, [login])
|
|
86
86
|
.then((el) => el.rows?.[0] || {});
|
|
87
|
-
await pg.query(`insert into admin.users (uid, login, password, user_name, sur_name, father_name, email,phone, enabled, user_personal_code )
|
|
88
|
-
select contact_id, $4, $3, first_name, last_name, middle_name, $2, phone, true, md5(random()::text)
|
|
87
|
+
await pg.query(`insert into admin.users (uid, login, password, user_name, sur_name, father_name, email,phone, enabled, user_personal_code )
|
|
88
|
+
select contact_id, $4, $3, first_name, last_name, middle_name, $2, phone, true, md5(random()::text)
|
|
89
89
|
from crm_acc.crm_contact where contact_id = $1 and contact_id not in (select uid from admin.users)`, [uid, email, password, login]);
|
|
90
90
|
}
|
|
91
91
|
else {
|
|
@@ -37,7 +37,7 @@ export default async function loginTemplate(req, reply) {
|
|
|
37
37
|
const { enabled, secret } = config.pg ? await getSecret({ pg, uid }) : {};
|
|
38
38
|
const { otp, recoveryCodes, key } = secret && pg?.pk?.["admin.users_social_auth"]
|
|
39
39
|
? await pg
|
|
40
|
-
.query(`select social_auth_obj->'codesArray' as "recoveryCodes", enabled, social_auth_url as otp
|
|
40
|
+
.query(`select social_auth_obj->'codesArray' as "recoveryCodes", enabled, social_auth_url as otp
|
|
41
41
|
from admin.users_social_auth where uid=$1 and social_auth_type='TOTP'`, [uid])
|
|
42
42
|
?.then((el) => el.rows?.[0] || {})
|
|
43
43
|
: await generate({ uid, pg });
|
|
@@ -69,9 +69,9 @@ export default async function resizeAll(req, reply) {
|
|
|
69
69
|
const { pg = pgClients.client, query = {} } = req;
|
|
70
70
|
const { nocache, filepath, quality = 80, limit, sql, w = 2048 } = query;
|
|
71
71
|
if (nocache) {
|
|
72
|
-
const clearQ = `update crm.files set resized=null
|
|
73
|
-
where ext=any($1)
|
|
74
|
-
and ${filepath ? "file_path=$2" : "1=1"}
|
|
72
|
+
const clearQ = `update crm.files set resized=null
|
|
73
|
+
where ext=any($1)
|
|
74
|
+
and ${filepath ? "file_path=$2" : "1=1"}
|
|
75
75
|
and resized is not null`;
|
|
76
76
|
if (sql)
|
|
77
77
|
return clearQ;
|
|
@@ -79,9 +79,9 @@ export default async function resizeAll(req, reply) {
|
|
|
79
79
|
return reply.status(200).send({ msg: "clear cache success", rowCount });
|
|
80
80
|
}
|
|
81
81
|
const resizeQuality = Math.min(quality, 100);
|
|
82
|
-
const q = `select file_id as id, file_path as relpath from crm.files
|
|
83
|
-
where ext=any($1)
|
|
84
|
-
and ${filepath ? "file_path=$2" : "1=1"}
|
|
82
|
+
const q = `select file_id as id, file_path as relpath from crm.files
|
|
83
|
+
where ext=any($1)
|
|
84
|
+
and ${filepath ? "file_path=$2" : "1=1"}
|
|
85
85
|
and resized is null ${limit ? `limit ${limit}` : ""}`;
|
|
86
86
|
if (sql)
|
|
87
87
|
return q;
|
|
@@ -23,19 +23,19 @@ export default async function file2geojson({ pg = pgClients.client, body = {}, }
|
|
|
23
23
|
const JsonArr = JsonData?.features
|
|
24
24
|
? JsonData
|
|
25
25
|
: { type: "FeatureCollection", features: [JsonData] };
|
|
26
|
-
const { rows = [] } = await pg.query(`
|
|
27
|
-
select
|
|
28
|
-
features->>'type' as type,
|
|
29
|
-
features->'properties' as properties,
|
|
30
|
-
st_asgeojson(st_transform(st_setsrid(st_geomfromgeojson(features->>'geometry'),$2),4326))::json as geometry
|
|
31
|
-
from (
|
|
32
|
-
select d->>'type' as type,d->>'name' as name,json_array_elements(d->'features') as features
|
|
33
|
-
from (
|
|
34
|
-
select json_array_elements(case when json_typeof(d)='array' then d else json_build_array(d) end)d
|
|
35
|
-
from (
|
|
36
|
-
select ($1)::json as d
|
|
37
|
-
)q
|
|
38
|
-
)q
|
|
26
|
+
const { rows = [] } = await pg.query(`
|
|
27
|
+
select
|
|
28
|
+
features->>'type' as type,
|
|
29
|
+
features->'properties' as properties,
|
|
30
|
+
st_asgeojson(st_transform(st_setsrid(st_geomfromgeojson(features->>'geometry'),$2),4326))::json as geometry
|
|
31
|
+
from (
|
|
32
|
+
select d->>'type' as type,d->>'name' as name,json_array_elements(d->'features') as features
|
|
33
|
+
from (
|
|
34
|
+
select json_array_elements(case when json_typeof(d)='array' then d else json_build_array(d) end)d
|
|
35
|
+
from (
|
|
36
|
+
select ($1)::json as d
|
|
37
|
+
)q
|
|
38
|
+
)q
|
|
39
39
|
)q`, [JSON.stringify(JsonArr).replace(/'/g, "''"), srid]);
|
|
40
40
|
return [{ features: [rows.slice(0, 1)] }];
|
|
41
41
|
}
|
|
@@ -75,15 +75,15 @@ export default async function adminMenu({ user = {}, session, pg = pgClients.cli
|
|
|
75
75
|
user.user_type !== "viewer" &&
|
|
76
76
|
pg.pk?.["admin.role_access"]) {
|
|
77
77
|
const { type, gl = [], routes = [], } = await pg
|
|
78
|
-
.query(`select user_type as type, b.gl,routes from admin.users a
|
|
79
|
-
left join lateral (
|
|
80
|
-
select array_agg(role_id) as gl from admin.user_roles
|
|
81
|
-
where user_uid=a.uid
|
|
82
|
-
and role_id in ( select role_id from admin.roles where enabled)
|
|
83
|
-
)b on 1=1
|
|
84
|
-
left join lateral (
|
|
85
|
-
select array_agg(route_id) as routes from admin.role_access where role_id=any(b.gl)
|
|
86
|
-
)r on 1=1
|
|
78
|
+
.query(`select user_type as type, b.gl,routes from admin.users a
|
|
79
|
+
left join lateral (
|
|
80
|
+
select array_agg(role_id) as gl from admin.user_roles
|
|
81
|
+
where user_uid=a.uid
|
|
82
|
+
and role_id in ( select role_id from admin.roles where enabled)
|
|
83
|
+
)b on 1=1
|
|
84
|
+
left join lateral (
|
|
85
|
+
select array_agg(route_id) as routes from admin.role_access where role_id=any(b.gl)
|
|
86
|
+
)r on 1=1
|
|
87
87
|
where uid=$1`, [user.uid])
|
|
88
88
|
.then((el) => el.rows[0] || {});
|
|
89
89
|
/* const { interfaces = [] } = await pg.query(`select array_agg(route_id) as interfaces from admin.role_access
|
|
@@ -7,10 +7,10 @@ export default async function readNotifications(req) {
|
|
|
7
7
|
}
|
|
8
8
|
const ids = pg && pg.pk?.["crm.notifications"]
|
|
9
9
|
? await pg
|
|
10
|
-
.query(`update crm.notifications
|
|
11
|
-
set read=true
|
|
12
|
-
where read is not true
|
|
13
|
-
and addressee_id=$1
|
|
10
|
+
.query(`update crm.notifications
|
|
11
|
+
set read=true
|
|
12
|
+
where read is not true
|
|
13
|
+
and addressee_id=$1
|
|
14
14
|
and ${params.id ? "notification_id=$2" : "1=1"} returning notification_id`, [user.uid, params?.id].filter(Boolean))
|
|
15
15
|
.then((el) => el.rows?.map((row) => row.notification_id) || [])
|
|
16
16
|
: [];
|
|
@@ -2,9 +2,9 @@ import pgClients from "../../../plugins/pg/pgClients.js";
|
|
|
2
2
|
import getSelectVal from "../../../plugins/table/funcs/metaFormat/getSelectVal.js";
|
|
3
3
|
import { UnauthorizedError } from "../../../../errors.js";
|
|
4
4
|
const maxLimit = 100;
|
|
5
|
-
const q = `select notification_id as id, subject, body, created_at,
|
|
6
|
-
author_id, read, link, entity_id, (select avatar from admin.users where uid=a.author_id limit 1) as avatar
|
|
7
|
-
from crm.notifications a
|
|
5
|
+
const q = `select notification_id as id, subject, body, created_at,
|
|
6
|
+
author_id, read, link, entity_id, (select avatar from admin.users where uid=a.author_id limit 1) as avatar
|
|
7
|
+
from crm.notifications a
|
|
8
8
|
where addressee_id=$1 order by created_at desc limit $2 offset $3`;
|
|
9
9
|
export default async function userNotifications(req) {
|
|
10
10
|
const { pg = pgClients.client, query, user, } = req;
|
|
@@ -57,7 +57,7 @@ export default async function card(req, reply) {
|
|
|
57
57
|
: "";
|
|
58
58
|
const q = `select ${pk ? `"${pk}" as id,` : ""} ${dbColumns.find((el) => el.name === "geom" && pg.pgType[el.dataTypeID] === "geometry")
|
|
59
59
|
? "st_asgeojson(geom)::json as geom,"
|
|
60
|
-
: ""} ${cols || "*"} ${cardColumns} from ${table} t ${sqlTable} ${cardSqlTable}
|
|
60
|
+
: ""} ${cols || "*"} ${cardColumns} from ${table} t ${sqlTable} ${cardSqlTable}
|
|
61
61
|
where ${where.join(" and ") || "true"} limit 1`;
|
|
62
62
|
if (query.sql === "1") {
|
|
63
63
|
return q;
|
|
@@ -153,12 +153,12 @@ export default async function filterAPI(req, reply, iscalled) {
|
|
|
153
153
|
fields?.find?.((item) => item?.name === el.name))
|
|
154
154
|
.map(async (el) => {
|
|
155
155
|
const data = await pg
|
|
156
|
-
.queryCache(`select array[
|
|
157
|
-
min(${el.name}),
|
|
158
|
-
percentile_disc(0.25) within group (order by ${el.name}),
|
|
159
|
-
percentile_disc(0.5) within group (order by ${el.name}),
|
|
160
|
-
percentile_disc(0.75) within group (order by ${el.name}),
|
|
161
|
-
max(${el.name})
|
|
156
|
+
.queryCache(`select array[
|
|
157
|
+
min(${el.name}),
|
|
158
|
+
percentile_disc(0.25) within group (order by ${el.name}),
|
|
159
|
+
percentile_disc(0.5) within group (order by ${el.name}),
|
|
160
|
+
percentile_disc(0.75) within group (order by ${el.name}),
|
|
161
|
+
max(${el.name})
|
|
162
162
|
] as range from ${table} where ${tableQuery || "1=1"}`, { table })
|
|
163
163
|
.then((res) => {
|
|
164
164
|
if (res.timeout) {
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { NotFoundError } from "../../../../errors.js";
|
|
2
2
|
import { applyHook, getTemplate, pgClients } from "../../../../utils.js";
|
|
3
|
-
const q = `select property_key as key, property_json as json, property_int as int,
|
|
3
|
+
const q = `select property_key as key, property_json as json, property_int as int,
|
|
4
4
|
property_text as text from admin.properties where 1=1`;
|
|
5
5
|
async function getSettings({ pg }) {
|
|
6
6
|
const rows = pg?.pk?.["admin.properties"]
|
|
@@ -9,12 +9,12 @@ import getTemplate from "../../../plugins/table/funcs/getTemplate.js";
|
|
|
9
9
|
import getEditData from "../../crud/controllers/table.js";
|
|
10
10
|
import formatSchema from "./utils/formatSchema.js";
|
|
11
11
|
import { ForbiddenError, NotFoundError, UnauthorizedError, } from "../../../../errors.js";
|
|
12
|
-
const q = `select
|
|
13
|
-
property_key as key,
|
|
14
|
-
property_json as json,
|
|
15
|
-
property_int as int,
|
|
16
|
-
property_text as text
|
|
17
|
-
from admin.properties
|
|
12
|
+
const q = `select
|
|
13
|
+
property_key as key,
|
|
14
|
+
property_json as json,
|
|
15
|
+
property_int as int,
|
|
16
|
+
property_text as text
|
|
17
|
+
from admin.properties
|
|
18
18
|
where 1=1`;
|
|
19
19
|
export default async function getForm({ pg = pgClients.client, params, user = {}, query = {}, method, }, reply) {
|
|
20
20
|
const time = Date.now();
|
|
@@ -254,9 +254,9 @@ export default async function suggest(req) {
|
|
|
254
254
|
.filter(Boolean)
|
|
255
255
|
.join(" and ") || "true";
|
|
256
256
|
const sqlSuggest = tableName && column
|
|
257
|
-
? `${meta.original}
|
|
258
|
-
WHERE EXISTS ( SELECT 1 FROM ${tableName} o WHERE o.${column} IS NOT DISTINCT FROM c.id ) and ${val || "true"} and ${search || "true"}
|
|
259
|
-
${meta.original.toLowerCase().includes("order by") ? "" : "order by 2"}
|
|
257
|
+
? `${meta.original}
|
|
258
|
+
WHERE EXISTS ( SELECT 1 FROM ${tableName} o WHERE o.${column} IS NOT DISTINCT FROM c.id ) and ${val || "true"} and ${search || "true"}
|
|
259
|
+
${meta.original.toLowerCase().includes("order by") ? "" : "order by 2"}
|
|
260
260
|
LIMIT ${Math.min(query.limit || meta.limit || limit, limit)}`
|
|
261
261
|
.replace(/{{parent}}/gi, parent)
|
|
262
262
|
.replace(/{{uid}}/g, user?.uid || "0")
|
|
@@ -3,8 +3,8 @@ import getData from "../functions/getData.js";
|
|
|
3
3
|
export default async function tableData(req, reply, called) {
|
|
4
4
|
const { user, params, headers, query, pg = pgClients.client } = req;
|
|
5
5
|
// це можна від користувача
|
|
6
|
-
const q = `select attr,
|
|
7
|
-
(select rule_values from admin.account_grants where account_id in (select account_id from admin.account_users where user_uid=$2) and rule_id=r.rule_id limit 1)
|
|
6
|
+
const q = `select attr,
|
|
7
|
+
(select rule_values from admin.account_grants where account_id in (select account_id from admin.account_users where user_uid=$2) and rule_id=r.rule_id limit 1)
|
|
8
8
|
from admin.rules r where (select route_id from admin.routes where $1 in (alias,table_name)) = any(routes)`;
|
|
9
9
|
const { rows = [] } = pg?.pk?.["admin.rules"] && pg?.pk?.["admin.account_grants"] && user?.uid
|
|
10
10
|
? await pg.query(q, [params.table, user.uid])
|
|
@@ -59,21 +59,21 @@ export default async function tableInfo({ pg = pgClients.client, params, query =
|
|
|
59
59
|
if (!metaInfoCols.length) {
|
|
60
60
|
throw BadRequestError("invalid meta info: columns not found");
|
|
61
61
|
}
|
|
62
|
-
const q = `select ${pk ? `"${pk}" as id,` : ""}
|
|
63
|
-
${metaInfoCols.join(",")}
|
|
64
|
-
from (select * from ${table} where ${sqlTable ? "true" : where.join(" and ") || "true"}) t
|
|
65
|
-
${sqlTable}
|
|
66
|
-
${cardSqlTable}
|
|
67
|
-
where ${where.join(" and ") || "true"}
|
|
62
|
+
const q = `select ${pk ? `"${pk}" as id,` : ""}
|
|
63
|
+
${metaInfoCols.join(",")}
|
|
64
|
+
from (select * from ${table} where ${sqlTable ? "true" : where.join(" and ") || "true"}) t
|
|
65
|
+
${sqlTable}
|
|
66
|
+
${cardSqlTable}
|
|
67
|
+
where ${where.join(" and ") || "true"}
|
|
68
68
|
limit 1`.replace(/{{uid}}/g, uid);
|
|
69
69
|
if (query.sql === "1") {
|
|
70
70
|
return q;
|
|
71
71
|
}
|
|
72
72
|
const { rows } = await pg.query(q, [params.id]);
|
|
73
|
-
const qCount = `select
|
|
74
|
-
count(*)::int as total,
|
|
75
|
-
count(*) FILTER(WHERE ${[interfaceQuery].filter((el) => el).join(" and ") || "true"})::int as filtered
|
|
76
|
-
from ${table} t ${sqlTable}
|
|
73
|
+
const qCount = `select
|
|
74
|
+
count(*)::int as total,
|
|
75
|
+
count(*) FILTER(WHERE ${[interfaceQuery].filter((el) => el).join(" and ") || "true"})::int as filtered
|
|
76
|
+
from ${table} t ${sqlTable}
|
|
77
77
|
where ${[loadTable.query].filter((el) => el).join(" and ") || "true"} `.replace(/{{uid}}/g, uid);
|
|
78
78
|
const { total, filtered } = params.id
|
|
79
79
|
? rows.length
|
|
@@ -333,24 +333,24 @@ export default async function dataAPI({ pg = pgClients.client, params, table, id
|
|
|
333
333
|
]
|
|
334
334
|
.filter(Boolean)
|
|
335
335
|
.filter((el) => checkQuery(el));
|
|
336
|
-
const q = `select ${pk ? `"${pk}" as id,` : ""}
|
|
336
|
+
const q = `select ${pk ? `"${pk}" as id,` : ""}
|
|
337
337
|
${objectId || query?.key
|
|
338
338
|
? "*"
|
|
339
|
-
: columnsParam || sqlColumns || cols || "*"}
|
|
340
|
-
${metaCols}
|
|
339
|
+
: columnsParam || sqlColumns || cols || "*"}
|
|
340
|
+
${metaCols}
|
|
341
341
|
${dbColumns.filter((el) => pg.pgType?.[el.dataTypeID] === "geometry").length && !columnsParam
|
|
342
342
|
? `,${dbColumns
|
|
343
343
|
.filter((el) => pg.pgType?.[el.dataTypeID] === "geometry")
|
|
344
344
|
.map((el) => `st_asgeojson("${el.name.replace(/'/g, "''")}")::json as "${el.name.replace(/'/g, "''")}"`)
|
|
345
345
|
.join(",")}`
|
|
346
|
-
: ""}
|
|
346
|
+
: ""}
|
|
347
347
|
from (select * ${sql
|
|
348
348
|
?.filter((el) => el.inline && !(isExport && el.export === false))
|
|
349
349
|
.map((el) => `,(${el.sql})`)
|
|
350
|
-
.join("") || ""} from ${viewSql ? `(${viewSql})` : table1} t ${sqlTable} ) t
|
|
351
|
-
|
|
352
|
-
${objectId ? cardSqlTable : ""}
|
|
353
|
-
where ${where.join(" and ") || "true"}
|
|
350
|
+
.join("") || ""} from ${viewSql ? `(${viewSql})` : table1} t ${sqlTable} ) t
|
|
351
|
+
|
|
352
|
+
${objectId ? cardSqlTable : ""}
|
|
353
|
+
where ${where.join(" and ") || "true"}
|
|
354
354
|
${order} ${offset} limit ${limit}`.replace(/{{uid}}/g, uid);
|
|
355
355
|
if (config.trace)
|
|
356
356
|
console.log(q);
|
|
@@ -415,18 +415,18 @@ export default async function dataAPI({ pg = pgClients.client, params, table, id
|
|
|
415
415
|
type: pg.pgType?.[el.dataTypeID],
|
|
416
416
|
}))
|
|
417
417
|
.filter((el) => ["numeric", "double precision"].includes(el.type) && aggColumns[el.name]);
|
|
418
|
-
const qCount = `select
|
|
419
|
-
count(*)::int as total,
|
|
420
|
-
count(*) FILTER(WHERE ${filterWhere.join(" and ") || "true"})::int as filtered
|
|
418
|
+
const qCount = `select
|
|
419
|
+
count(*)::int as total,
|
|
420
|
+
count(*) FILTER(WHERE ${filterWhere.join(" and ") || "true"})::int as filtered
|
|
421
421
|
${aggregates.length
|
|
422
422
|
? `,${aggregates
|
|
423
423
|
.map((el) => `${aggColumns[el.name]}(${el.name}) FILTER(WHERE ${filterWhere.join(" and ") || "true"}) as ${el.name}`)
|
|
424
424
|
.join(",")}`
|
|
425
|
-
: ""}
|
|
425
|
+
: ""}
|
|
426
426
|
from (select * ${sql
|
|
427
427
|
?.filter((el) => el.inline)
|
|
428
428
|
.map((el) => `,(${el.sql})`)
|
|
429
|
-
.join("") || ""} from ${viewSql ? `(${viewSql})` : table1} t ${sqlTable})t
|
|
429
|
+
.join("") || ""} from ${viewSql ? `(${viewSql})` : table1} t ${sqlTable})t
|
|
430
430
|
where ${[loadTable?.query, tokenData?.query, accessQuery, contextQuery]
|
|
431
431
|
.filter(Boolean)
|
|
432
432
|
.filter((el) => checkQuery(el))
|
|
@@ -39,49 +39,49 @@ export default async function widgetGet({ pg = pgClients.client, user = {}, para
|
|
|
39
39
|
}
|
|
40
40
|
const sqls = {
|
|
41
41
|
comment: pg.pk["admin.users"]
|
|
42
|
-
? `select communication_id, entity_id, body, subject, c.cdate, c.uid,
|
|
43
|
-
${username} as username, u.login, u.avatar
|
|
44
|
-
from crm.communications c
|
|
45
|
-
left join admin.users u on u.uid=c.uid
|
|
42
|
+
? `select communication_id, entity_id, body, subject, c.cdate, c.uid,
|
|
43
|
+
${username} as username, u.login, u.avatar
|
|
44
|
+
from crm.communications c
|
|
45
|
+
left join admin.users u on u.uid=c.uid
|
|
46
46
|
where entity_id=$1 order by cdate desc`
|
|
47
47
|
: "select communication_id, entity_id, body, subject, cdate, uid from crm.communications where entity_id=$1 order by cdate desc",
|
|
48
|
-
history: `SELECT change_id, entity_id, entity_type, change_type, change_date, a.change_user_id, a.uid, a.cdate, b.json_agg as changes,
|
|
49
|
-
${username} as username, u.login, u.avatar
|
|
50
|
-
FROM log.table_changes a
|
|
51
|
-
left join admin.users u on a.change_user_id = u.uid
|
|
52
|
-
left join lateral(
|
|
53
|
-
select json_agg(row_to_json(q)) from (
|
|
54
|
-
select change_data_id, entity_key, value_new, value_old from log.table_changes_data
|
|
55
|
-
where change_id=a.change_id
|
|
56
|
-
)q
|
|
57
|
-
)b on 1=1
|
|
58
|
-
where a.change_type != 'INSERT' and b.json_agg is not null and (entity_id=$1 or entity_id in (
|
|
59
|
-
select communication_id from crm.communications where entity_id=$1
|
|
60
|
-
union all select checklist_id from crm.checklists where entity_id=$1
|
|
61
|
-
union all select file_id from crm.files where entity_id=$1)
|
|
62
|
-
)
|
|
48
|
+
history: `SELECT change_id, entity_id, entity_type, change_type, change_date, a.change_user_id, a.uid, a.cdate, b.json_agg as changes,
|
|
49
|
+
${username} as username, u.login, u.avatar
|
|
50
|
+
FROM log.table_changes a
|
|
51
|
+
left join admin.users u on a.change_user_id = u.uid
|
|
52
|
+
left join lateral(
|
|
53
|
+
select json_agg(row_to_json(q)) from (
|
|
54
|
+
select change_data_id, entity_key, value_new, value_old from log.table_changes_data
|
|
55
|
+
where change_id=a.change_id
|
|
56
|
+
)q
|
|
57
|
+
)b on 1=1
|
|
58
|
+
where a.change_type != 'INSERT' and b.json_agg is not null and (entity_id=$1 or entity_id in (
|
|
59
|
+
select communication_id from crm.communications where entity_id=$1
|
|
60
|
+
union all select checklist_id from crm.checklists where entity_id=$1
|
|
61
|
+
union all select file_id from crm.files where entity_id=$1)
|
|
62
|
+
)
|
|
63
63
|
order by cdate desc limit 100`,
|
|
64
64
|
checklist: pg.pk["admin.users"]
|
|
65
|
-
? `SELECT checklist_id, entity_id, subject, is_done, done_date, c.uid, c.cdate, ${username} as username, u.login, u.avatar
|
|
66
|
-
FROM crm.checklists c
|
|
67
|
-
left join admin.users u on u.uid=c.uid
|
|
65
|
+
? `SELECT checklist_id, entity_id, subject, is_done, done_date, c.uid, c.cdate, ${username} as username, u.login, u.avatar
|
|
66
|
+
FROM crm.checklists c
|
|
67
|
+
left join admin.users u on u.uid=c.uid
|
|
68
68
|
where entity_id=$1 order by cdate desc`
|
|
69
69
|
: "SELECT checklist_id, entity_id, subject, is_done, done_date, uid, cdate FROM crm.checklists where entity_id=$1 order by cdate desc",
|
|
70
70
|
file: pg.pk["admin.users"]
|
|
71
|
-
? `SELECT file_id, entity_id, entity_type, file_path, uploaded_name, ext, size, c.uid, c.cdate, file_type, c.ismain,
|
|
72
|
-
${username} as username, u.login, isverified, u.avatar, u.uid as author, file_status
|
|
73
|
-
FROM crm.files c
|
|
74
|
-
left join admin.users u on u.uid=c.uid
|
|
71
|
+
? `SELECT file_id, entity_id, entity_type, file_path, uploaded_name, ext, size, c.uid, c.cdate, file_type, c.ismain,
|
|
72
|
+
${username} as username, u.login, isverified, u.avatar, u.uid as author, file_status
|
|
73
|
+
FROM crm.files c
|
|
74
|
+
left join admin.users u on u.uid=c.uid
|
|
75
75
|
where entity_id=$1 and file_status<>3 order by cdate desc`
|
|
76
|
-
: `SELECT file_id, entity_id, entity_type, file_path, uploaded_name, ext, size, uid, cdate, file_type, ismain,
|
|
76
|
+
: `SELECT file_id, entity_id, entity_type, file_path, uploaded_name, ext, size, uid, cdate, file_type, ismain,
|
|
77
77
|
isverified, uid as author, file_status FROM crm.files c where entity_id=$1 and file_status<>3 order by cdate desc`,
|
|
78
78
|
gallery: pg.pk["admin.users"]
|
|
79
|
-
? `SELECT file_id, entity_id, entity_type, file_path, uploaded_name, ext, size, c.uid, c.cdate, file_type, c.ismain,
|
|
80
|
-
${username} as username, u.login, u.avatar, isverified, u.avatar, c.uid as author, file_status
|
|
81
|
-
FROM crm.files c
|
|
82
|
-
left join admin.users u on u.uid=c.uid
|
|
79
|
+
? `SELECT file_id, entity_id, entity_type, file_path, uploaded_name, ext, size, c.uid, c.cdate, file_type, c.ismain,
|
|
80
|
+
${username} as username, u.login, u.avatar, isverified, u.avatar, c.uid as author, file_status
|
|
81
|
+
FROM crm.files c
|
|
82
|
+
left join admin.users u on u.uid=c.uid
|
|
83
83
|
where entity_id=$1 and file_status<>3 and ext = any($2) order by cdate desc`
|
|
84
|
-
: `SELECT file_id, entity_id, entity_type, file_path, uploaded_name, ext, size, c.uid, c.cdate, file_type, ismain,
|
|
84
|
+
: `SELECT file_id, entity_id, entity_type, file_path, uploaded_name, ext, size, c.uid, c.cdate, file_type, ismain,
|
|
85
85
|
isverified, uid as author, file_status FROM crm.files c where entity_id=$1 and file_status<>3 and ext = any($2) order by cdate desc`,
|
|
86
86
|
reaction: "SELECT count(*), reaction_type FROM crm.reactions c where entity_id=$1 group by reaction_type",
|
|
87
87
|
};
|
|
@@ -127,7 +127,7 @@ export default async function widgetGet({ pg = pgClients.client, user = {}, para
|
|
|
127
127
|
}
|
|
128
128
|
const cdateColumn = columns.find((col) => ["cdate", "created_at"].includes(col.name))?.name;
|
|
129
129
|
const editorDateColumn = columns.find((col) => ["editor_date", "updated_at"].includes(col.name))?.name;
|
|
130
|
-
const q1 = `select ${username} as author, u.login ${cdateColumn ? `,a.${cdateColumn} as cdate` : ""} ${editorDateColumn ? `,a.${editorDateColumn} as editor_date` : ""} from ${tableName} a
|
|
130
|
+
const q1 = `select ${username} as author, u.login ${cdateColumn ? `,a.${cdateColumn} as cdate` : ""} ${editorDateColumn ? `,a.${editorDateColumn} as editor_date` : ""} from ${tableName} a
|
|
131
131
|
left join admin.users u on a.${authorIdColumn}=u.uid where a.${pk}=$1 limit 1`;
|
|
132
132
|
const data = pg.pk["admin.users"] && pk && tableName
|
|
133
133
|
? await pg
|