@opengis/admin 0.1.90 → 0.1.92

Sign up to get free protection for your applications and to get access to all the features.
Files changed (147) hide show
  1. package/README.md +29 -29
  2. package/config.js +4 -4
  3. package/dist/{IconChevronDown--nil1nCv.js → IconChevronDown-KI0JSsHM.js} +1 -1
  4. package/dist/{add-page-CX6beoja.js → add-page-BCXXk3_G.js} +1 -1
  5. package/dist/{admin-interface-B60KBtCX.js → admin-interface-DeVqzwQ5.js} +4 -4
  6. package/dist/{admin-view-xk2cy8Wu.js → admin-view-ueou40jT.js} +3 -3
  7. package/dist/admin.js +1 -1
  8. package/dist/admin.umd.cjs +42 -42
  9. package/dist/assets/logo.svg +41 -41
  10. package/dist/card-page-Cs-WOWvI.js +364 -0
  11. package/dist/{card-view-BVJP0k1Z.js → card-view-Ct56P9CD.js} +1 -1
  12. package/dist/{edit-page-PYxyXpVG.js → edit-page-WUjuzYcQ.js} +1 -1
  13. package/dist/{import-file-BBuEJJur.js → import-file-Cobra4kl.js} +17248 -17620
  14. package/dist/style.css +1 -1
  15. package/module/settings/card/admin.roles.table/access.hbs +27 -27
  16. package/module/settings/card/admin.roles.table/general_info.hbs +16 -16
  17. package/module/settings/card/admin.roles.table/index.yml +14 -14
  18. package/module/settings/card/admin.roles.table/users.hbs +27 -27
  19. package/module/settings/card/admin.routes.table/general_info.hbs +40 -40
  20. package/module/settings/card/admin.routes.table/index.yml +8 -8
  21. package/module/settings/card/admin.routes.table/users.hbs +33 -33
  22. package/module/settings/card/admin.users.table/general_info.hbs +25 -25
  23. package/module/settings/card/admin.users.table/index.yml +12 -12
  24. package/module/settings/card/admin.users.table/logs.hbs +30 -30
  25. package/module/settings/card/admin.users.table/user_roles.hbs +24 -24
  26. package/module/settings/cls/core.actions.json +17 -17
  27. package/module/settings/cls/core.scope.json +13 -13
  28. package/module/settings/cls/properties.site_status.json +13 -13
  29. package/module/settings/cls/properties.widget_status.json +13 -13
  30. package/module/settings/cls/users.user_type.json +13 -13
  31. package/module/settings/form/admin.access.form.json +36 -36
  32. package/module/settings/form/admin.custom_column.form.json +71 -71
  33. package/module/settings/form/admin.properties.form.json +15 -15
  34. package/module/settings/form/admin.roles.form.json +19 -19
  35. package/module/settings/form/admin.routes.form.json +25 -25
  36. package/module/settings/form/admin.user_properties.form.json +15 -15
  37. package/module/settings/form/admin.user_roles.form.json +21 -21
  38. package/module/settings/form/admin.users.form.json +153 -153
  39. package/module/settings/form/user.user_roles.form.json +13 -13
  40. package/module/settings/interface/admin.properties.json +4 -4
  41. package/module/settings/interface/admin.roles.json +4 -4
  42. package/module/settings/interface/admin.routes.json +4 -4
  43. package/module/settings/interface/admin.users.json +4 -4
  44. package/module/settings/menu.json +50 -50
  45. package/module/settings/select/core.roles.json +2 -2
  46. package/module/settings/select/core.routes.sql +1 -1
  47. package/module/settings/select/core.user_mentioned.sql +1 -1
  48. package/module/settings/select/core.user_uid.sql +1 -1
  49. package/module/settings/table/admin.access.table.json +83 -83
  50. package/module/settings/table/admin.custom_column.table.json +99 -99
  51. package/module/settings/table/admin.properties.table.json +39 -39
  52. package/module/settings/table/admin.roles.table.json +64 -64
  53. package/module/settings/table/admin.routes.table.json +68 -68
  54. package/module/settings/table/admin.user_properties.table.json +34 -34
  55. package/module/settings/table/admin.user_roles.table.json +72 -72
  56. package/module/settings/table/admin.users.table.json +121 -121
  57. package/package.json +81 -81
  58. package/plugin.js +29 -29
  59. package/server/helpers/controllers/badge.js +11 -11
  60. package/server/helpers/controllers/hb.js +2 -2
  61. package/server/helpers/controllers/map.js +2 -2
  62. package/server/helpers/controllers/mls.js +2 -2
  63. package/server/helpers/controllers/token.js +16 -16
  64. package/server/helpers/controllers/vue.js +2 -2
  65. package/server/helpers/index.mjs +29 -29
  66. package/server/helpers/list/buttonHelper.js +10 -10
  67. package/server/helpers/list/descriptionList.js +34 -34
  68. package/server/helpers/list/tableList.js +65 -65
  69. package/server/helpers/list/utils/button.js +5 -5
  70. package/server/plugins/access/funcs/getAdminAccess.js +14 -14
  71. package/server/plugins/access/index.mjs +6 -6
  72. package/server/plugins/adminHook.js +81 -81
  73. package/server/plugins/cron.js +10 -10
  74. package/server/plugins/docs.js +28 -28
  75. package/server/plugins/hook.js +226 -226
  76. package/server/plugins/vite.js +71 -71
  77. package/server/routes/access/controllers/access.group.js +29 -29
  78. package/server/routes/access/controllers/access.group.post.js +43 -43
  79. package/server/routes/access/index.mjs +63 -63
  80. package/server/routes/calendar/controllers/calendar.data.js +87 -87
  81. package/server/routes/calendar/index.mjs +7 -7
  82. package/server/routes/calendar/schema.js +21 -21
  83. package/server/routes/data/controllers/cardData.js +89 -89
  84. package/server/routes/data/controllers/cardTabData.js +49 -49
  85. package/server/routes/data/controllers/funcs/getFilterSQL/index.js +92 -92
  86. package/server/routes/data/controllers/funcs/getFilterSQL/util/formatValue.js +170 -170
  87. package/server/routes/data/controllers/funcs/getFilterSQL/util/getCustomQuery.js +13 -13
  88. package/server/routes/data/controllers/funcs/getFilterSQL/util/getFilterQuery.js +64 -64
  89. package/server/routes/data/controllers/funcs/getFilterSQL/util/getOptimizedQuery.js +12 -12
  90. package/server/routes/data/controllers/funcs/getFilterSQL/util/getTableSql.js +34 -34
  91. package/server/routes/data/controllers/tableData.js +20 -20
  92. package/server/routes/data/controllers/tableDataId.js +27 -27
  93. package/server/routes/data/controllers/tableFilter.js +67 -67
  94. package/server/routes/data/controllers/tokenInfo.js +9 -9
  95. package/server/routes/data/controllers/utils/assignTokens.js +30 -30
  96. package/server/routes/data/controllers/utils/conditions.js +20 -20
  97. package/server/routes/data/controllers/utils/getColumns.js +8 -8
  98. package/server/routes/data/index.mjs +17 -17
  99. package/server/routes/data/schema.js +54 -54
  100. package/server/routes/menu/controllers/getMenu.js +67 -67
  101. package/server/routes/menu/index.mjs +5 -5
  102. package/server/routes/notifications/controllers/readNotifications.js +27 -27
  103. package/server/routes/notifications/controllers/testEmail.js +35 -35
  104. package/server/routes/notifications/controllers/userNotifications.js +53 -53
  105. package/server/routes/notifications/funcs/addNotification.js +21 -21
  106. package/server/routes/notifications/funcs/sendNotification.js +105 -105
  107. package/server/routes/notifications/hook/onWidgetSet.js +57 -57
  108. package/server/routes/notifications/index.mjs +27 -27
  109. package/server/routes/notifications/schema.js +16 -16
  110. package/server/routes/properties/controllers/admin.properties.get.js +29 -29
  111. package/server/routes/properties/controllers/user.properties.get.js +30 -30
  112. package/server/routes/properties/controllers/user.properties.post.js +30 -30
  113. package/server/routes/properties/funcs/getSettings.js +56 -56
  114. package/server/routes/properties/funcs/setSettings.js +44 -44
  115. package/server/routes/properties/funcs/utils/dataInsert.js +26 -26
  116. package/server/routes/properties/index.mjs +14 -14
  117. package/server/routes/properties/schema.js +10 -10
  118. package/server/routes/root.mjs +3 -3
  119. package/server/routes/templates/controllers/getTemplate.js +26 -26
  120. package/server/routes/templates/index.mjs +16 -16
  121. package/server/routes/templates/schema.js +8 -8
  122. package/server/routes/user/controllers/user.cls.id.js +14 -14
  123. package/server/routes/user/controllers/user.cls.js +71 -71
  124. package/server/routes/user/controllers/user.cls.post.js +52 -52
  125. package/server/routes/user/controllers/user.info.js +17 -17
  126. package/server/routes/user/schema.js +14 -14
  127. package/server/routes/widget/controllers/utils/historyFormat.js +75 -75
  128. package/server/routes/widget/controllers/utils/obj2db.js +13 -13
  129. package/server/routes/widget/controllers/widget.del.js +41 -41
  130. package/server/routes/widget/controllers/widget.get.js +96 -96
  131. package/server/routes/widget/controllers/widget.set.js +76 -76
  132. package/server/routes/widget/index.mjs +11 -11
  133. package/server/routes/widget/schema.js +12 -12
  134. package/server/templates/cls/itree.recrzone_category.json +73 -73
  135. package/server/templates/cls/test.json +9 -9
  136. package/server/templates/form/admin.user_cls.data.form.json +49 -49
  137. package/server/templates/form/admin.user_group_rel.form.json +21 -21
  138. package/server/templates/form/cp_building.form.json +32 -32
  139. package/server/templates/form/form-user-pass.json +10 -10
  140. package/server/templates/form/form-user_group.json +39 -39
  141. package/server/templates/form/form-users.json +156 -156
  142. package/server/templates/form/user_group_access.form.json +22 -22
  143. package/server/templates/select/account_id.json +2 -2
  144. package/server/templates/table/gis.dataset.table.json +43 -43
  145. package/server/templates/table/management.user_group.table.json +112 -112
  146. package/server/templates/table/management.users.table.json +126 -126
  147. package/utils.js +29 -29
@@ -1,27 +1,27 @@
1
- export default async function readNotifications({
2
- pg, params = {}, query = {}, session = {},
3
- }) {
4
- const { uid } = session.passport?.user || {};
5
-
6
- if (!uid) {
7
- return { message: 'access restricted', status: 403 };
8
- }
9
-
10
-
11
- const { userId } = await pg.query('select uid as "userId" from admin.users where $1 in (uid,login) limit 1', [uid])
12
- .then((res) => res.rows?.[0] || {});
13
-
14
- if (!userId) {
15
- return { message: 'access restricted: 2', status: 403 };
16
- }
17
-
18
- const q = `update crm.notifications set read=true where read is not true
19
- and ${params?.id ? 'notification_id=$2' : '1=1'} and addressee_id=$1`;
20
-
21
- if (query.sql) return q;
22
-
23
- const { rowCount = 0 } = await pg.query(q, [userId, params?.id].filter((el) => el));
24
-
25
- return { message: `${rowCount} unread notifications marked as read`, status: 200 };
26
-
27
- }
1
+ export default async function readNotifications({
2
+ pg, params = {}, query = {}, session = {},
3
+ }) {
4
+ const { uid } = session.passport?.user || {};
5
+
6
+ if (!uid) {
7
+ return { message: 'access restricted', status: 403 };
8
+ }
9
+
10
+
11
+ const { userId } = await pg.query('select uid as "userId" from admin.users where $1 in (uid,login) limit 1', [uid])
12
+ .then((res) => res.rows?.[0] || {});
13
+
14
+ if (!userId) {
15
+ return { message: 'access restricted: 2', status: 403 };
16
+ }
17
+
18
+ const q = `update crm.notifications set read=true where read is not true
19
+ and ${params?.id ? 'notification_id=$2' : '1=1'} and addressee_id=$1`;
20
+
21
+ if (query.sql) return q;
22
+
23
+ const { rowCount = 0 } = await pg.query(q, [userId, params?.id].filter((el) => el));
24
+
25
+ return { message: `${rowCount} unread notifications marked as read`, status: 200 };
26
+
27
+ }
@@ -1,35 +1,35 @@
1
- import config from '../../../../config.js';
2
-
3
- import sendNotification from '../funcs/sendNotification.js';
4
-
5
- export default async function testNotification({
6
- pg, query = {}, session = {},
7
- }) {
8
- const { local } = config || {};
9
-
10
- if (!session?.passport?.user?.user_type?.includes('admin') && !local) {
11
- return { message: 'Forbidden', status: 403 };
12
- }
13
-
14
- const date = new Date().toISOString().split('T')[0];
15
- if (!query.to) {
16
- return { message: 'param to is required', status: 400 };
17
- }
18
-
19
- const {
20
- to, template, table, id, nocache,
21
- } = query;
22
-
23
- const data = await sendNotification({
24
- pg,
25
- to,
26
- template,
27
- title: `Test Softpro ${date}`,
28
- table,
29
- nocache,
30
- id,
31
- message: `Test mail Softpro ${date} Lorem Ipsum Lorem Ipsum`,
32
- });
33
-
34
- return { message: data || 'ok' };
35
- }
1
+ import config from '../../../../config.js';
2
+
3
+ import sendNotification from '../funcs/sendNotification.js';
4
+
5
+ export default async function testNotification({
6
+ pg, query = {}, session = {},
7
+ }) {
8
+ const { local } = config || {};
9
+
10
+ if (!session?.passport?.user?.user_type?.includes('admin') && !local) {
11
+ return { message: 'Forbidden', status: 403 };
12
+ }
13
+
14
+ const date = new Date().toISOString().split('T')[0];
15
+ if (!query.to) {
16
+ return { message: 'param to is required', status: 400 };
17
+ }
18
+
19
+ const {
20
+ to, template, table, id, nocache,
21
+ } = query;
22
+
23
+ const data = await sendNotification({
24
+ pg,
25
+ to,
26
+ template,
27
+ title: `Test Softpro ${date}`,
28
+ table,
29
+ nocache,
30
+ id,
31
+ message: `Test mail Softpro ${date} Lorem Ipsum Lorem Ipsum`,
32
+ });
33
+
34
+ return { message: data || 'ok' };
35
+ }
@@ -1,53 +1,53 @@
1
- // for example only
2
- /*
3
- const res = await dataInsert({
4
- pg,
5
- table: 'crm.notifications',
6
- data: {
7
- subject: 'notif title',
8
- body: 'notif body',
9
- link: 'http://localhost:3000/api/notification',
10
- addressee_id: userId,
11
- author_id: userId,
12
- },
13
- });
14
- */
15
-
16
- import { getSelectVal } from '@opengis/fastify-table/utils.js';
17
-
18
- const maxLimit = 100;
19
-
20
- export default async function userNotifications({
21
- pg, query = {}, session = {},
22
- }) {
23
- const time = Date.now();
24
-
25
- const { uid } = session.passport?.user || {};
26
-
27
- if (!uid) {
28
- return { message: 'access restricted', status: 403 };
29
- }
30
-
31
- const limit = Math.min(maxLimit, +(query.limit || 5));
32
- const offset = query.page && query.page > 0 ? (query.page - 1) * limit : 0;
33
-
34
- const q = `select notification_id as id, subject, body, cdate,
35
- author_id, read, link, entity_id, (select avatar from admin.users where uid=a.author_id limit 1) as avatar from crm.notifications a where addressee_id=$1 order by cdate desc limit $2 offset $3`;
36
-
37
- if (query.sql) return q;
38
-
39
- const { rows = [] } = await pg.query(q, [uid, limit, offset]);
40
-
41
- const values = rows.map((el) => el.author_id)
42
- ?.filter((el, idx, arr) => el && arr.indexOf(el) === idx);
43
-
44
- if (values?.length) {
45
- const vals = await getSelectVal({ name: 'core.user_mentioned', values });
46
- rows.forEach((row) => {
47
- Object.assign(row, { author: vals?.[row.author_id] });
48
- });
49
- }
50
-
51
- return { time: Date.now() - time, total: rows?.length, rows };
52
-
53
- }
1
+ // for example only
2
+ /*
3
+ const res = await dataInsert({
4
+ pg,
5
+ table: 'crm.notifications',
6
+ data: {
7
+ subject: 'notif title',
8
+ body: 'notif body',
9
+ link: 'http://localhost:3000/api/notification',
10
+ addressee_id: userId,
11
+ author_id: userId,
12
+ },
13
+ });
14
+ */
15
+
16
+ import { getSelectVal } from '@opengis/fastify-table/utils.js';
17
+
18
+ const maxLimit = 100;
19
+
20
+ export default async function userNotifications({
21
+ pg, query = {}, session = {},
22
+ }) {
23
+ const time = Date.now();
24
+
25
+ const { uid } = session.passport?.user || {};
26
+
27
+ if (!uid) {
28
+ return { message: 'access restricted', status: 403 };
29
+ }
30
+
31
+ const limit = Math.min(maxLimit, +(query.limit || 5));
32
+ const offset = query.page && query.page > 0 ? (query.page - 1) * limit : 0;
33
+
34
+ const q = `select notification_id as id, subject, body, cdate,
35
+ author_id, read, link, entity_id, (select avatar from admin.users where uid=a.author_id limit 1) as avatar from crm.notifications a where addressee_id=$1 order by cdate desc limit $2 offset $3`;
36
+
37
+ if (query.sql) return q;
38
+
39
+ const { rows = [] } = await pg.query(q, [uid, limit, offset]);
40
+
41
+ const values = rows.map((el) => el.author_id)
42
+ ?.filter((el, idx, arr) => el && arr.indexOf(el) === idx);
43
+
44
+ if (values?.length) {
45
+ const vals = await getSelectVal({ name: 'core.user_mentioned', values });
46
+ rows.forEach((row) => {
47
+ Object.assign(row, { author: vals?.[row.author_id] });
48
+ });
49
+ }
50
+
51
+ return { time: Date.now() - time, total: rows?.length, rows };
52
+
53
+ }
@@ -1,21 +1,21 @@
1
- import { dataInsert } from '@opengis/fastify-table/utils.js';
2
-
3
- export default async function addNotification({
4
- pg, session = {}, subject, body, link, uid, entity,
5
- }) {
6
- const { uid: author } = session.passport?.user || {};
7
- const res = await dataInsert({
8
- pg,
9
- table: 'crm.notifications',
10
- data: {
11
- subject,
12
- body,
13
- link,
14
- addressee_id: uid,
15
- author_id: author,
16
- entity_id: entity,
17
- uid: author,
18
- },
19
- });
20
- return res?.rows?.[0] || {};
21
- }
1
+ import { dataInsert } from '@opengis/fastify-table/utils.js';
2
+
3
+ export default async function addNotification({
4
+ pg, session = {}, subject, body, link, uid, entity,
5
+ }) {
6
+ const { uid: author } = session.passport?.user || {};
7
+ const res = await dataInsert({
8
+ pg,
9
+ table: 'crm.notifications',
10
+ data: {
11
+ subject,
12
+ body,
13
+ link,
14
+ addressee_id: uid,
15
+ author_id: author,
16
+ entity_id: entity,
17
+ uid: author,
18
+ },
19
+ });
20
+ return res?.rows?.[0] || {};
21
+ }
@@ -1,105 +1,105 @@
1
- // eslint-disable-next-line max-len, no-control-regex
2
- const emailReg = /(?:[a-z0-9!#$%&'*+/=?^_`{|}~-]+(?:\.[a-z0-9!#$%&'*+/=?^_`{|}~-]+)*|"(?:[\x01-\x08\x0b\x0c\x0e-\x1f\x21\x23-\x5b\x5d-\x7f]|\\[\x01-\x09\x0b\x0c\x0e-\x7f])*")@(?:(?:[a-z0-9](?:[a-z0-9-]*[a-z0-9])?\.)+[a-z0-9](?:[a-z0-9-]*[a-z0-9])?|\[(?:(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.){3}(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?|[a-z0-9-]*[a-z0-9]:(?:[\x01-\x08\x0b\x0c\x0e-\x1f\x21-\x5a\x53-\x7f]|\\[\x01-\x09\x0b\x0c\x0e-\x7f])+)\])/g;
3
-
4
- import sendEmail from './utils/sendEmail.js';
5
-
6
- import { handlebars, pgClients, getTemplate, getRedis, logger } from '@opengis/fastify-table/utils.js';
7
-
8
- async function generateNotificationContent({
9
- pg, table, template, id, message, data: data1,
10
- }) {
11
- if (template) {
12
- const data = table && id ? await pg.one(`select * from ${table} where ${pg.pk[table]}=$1`, [id]) : data1;
13
- // console.log(data);
14
- const body = await getTemplate('pt', template);
15
- // console.log(body);
16
- const html = handlebars.compile(body || template || 'template not found')(data || {});
17
- // console.log(html);
18
- return html;
19
- }
20
- return message;
21
- }
22
-
23
- // to do: refactor fastify-file to remove funcs completely
24
- export default async function notification({
25
- pg = pgClients.client,
26
- provider = ['email'],
27
- from,
28
- to,
29
- template,
30
- table,
31
- message,
32
- title,
33
- file,
34
- data,
35
- id,
36
- nocache,
37
- }) {
38
- const rclient = getRedis();
39
-
40
- if (!pg) throw new Error('need pg');
41
-
42
- if (pg?.readonly) {
43
- return null;
44
- }
45
-
46
- const keyTo = `${pg.options?.database}:mail:${provider[0]}:${to || ''}${id || ''}${table || ''}${title || ''}`;
47
- const uniqueTo = await rclient.setnx(keyTo, 1);
48
- logger.info('notification/sent', { keyTo, send: uniqueTo, nocache });
49
-
50
- if (!uniqueTo && !nocache) {
51
- return `already sent: ${keyTo}`;
52
- }
53
- await rclient.expire(keyTo, 1000 * 600);
54
-
55
- if (!to.length) {
56
- return null;
57
- }
58
-
59
- if (!(Array.isArray(provider) && provider.length)) {
60
- return 'notification provider - must be array and not empty';
61
- }
62
-
63
- try {
64
- const html = await generateNotificationContent({
65
- pg, table, template, id, message, data,
66
- });
67
-
68
- // return html;
69
-
70
- if (provider.includes('email')) {
71
- const files = Array.isArray(file) ? file : [file];
72
- const attachments = files?.length && false ? await Promise.all(files?.filter((el) => el).map(async (el) => {
73
- /* const content = await downloadFile(el, { buffer: true }); // ?
74
- return {
75
- filename: el.split('/').pop(),
76
- encoding: 'base64',
77
- content,
78
- }; */
79
- })) : [];
80
-
81
- const toEmail = Array.isArray(to) ? to.map((emails) => emails.match(emailReg)?.join(',')) : to;
82
-
83
- const result = await sendEmail({
84
- attachments,
85
- html,
86
- subject: title,
87
- from,
88
- to: toEmail,
89
- });
90
-
91
- logger.info('notification', {
92
- provider, title, to: toEmail, from, result, len: message?.length, files,
93
- });
94
-
95
- return result;
96
- }
97
- return null;
98
- }
99
- catch (err) {
100
- logger.info('notification/error', {
101
- provider, from, to, err: err.toString(),
102
- });
103
- throw err;
104
- }
105
- }
1
+ // eslint-disable-next-line max-len, no-control-regex
2
+ const emailReg = /(?:[a-z0-9!#$%&'*+/=?^_`{|}~-]+(?:\.[a-z0-9!#$%&'*+/=?^_`{|}~-]+)*|"(?:[\x01-\x08\x0b\x0c\x0e-\x1f\x21\x23-\x5b\x5d-\x7f]|\\[\x01-\x09\x0b\x0c\x0e-\x7f])*")@(?:(?:[a-z0-9](?:[a-z0-9-]*[a-z0-9])?\.)+[a-z0-9](?:[a-z0-9-]*[a-z0-9])?|\[(?:(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.){3}(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?|[a-z0-9-]*[a-z0-9]:(?:[\x01-\x08\x0b\x0c\x0e-\x1f\x21-\x5a\x53-\x7f]|\\[\x01-\x09\x0b\x0c\x0e-\x7f])+)\])/g;
3
+
4
+ import sendEmail from './utils/sendEmail.js';
5
+
6
+ import { handlebars, pgClients, getTemplate, getRedis, logger } from '@opengis/fastify-table/utils.js';
7
+
8
+ async function generateNotificationContent({
9
+ pg, table, template, id, message, data: data1,
10
+ }) {
11
+ if (template) {
12
+ const data = table && id ? await pg.one(`select * from ${table} where ${pg.pk[table]}=$1`, [id]) : data1;
13
+ // console.log(data);
14
+ const body = await getTemplate('pt', template);
15
+ // console.log(body);
16
+ const html = handlebars.compile(body || template || 'template not found')(data || {});
17
+ // console.log(html);
18
+ return html;
19
+ }
20
+ return message;
21
+ }
22
+
23
+ // to do: refactor fastify-file to remove funcs completely
24
+ export default async function notification({
25
+ pg = pgClients.client,
26
+ provider = ['email'],
27
+ from,
28
+ to,
29
+ template,
30
+ table,
31
+ message,
32
+ title,
33
+ file,
34
+ data,
35
+ id,
36
+ nocache,
37
+ }) {
38
+ const rclient = getRedis();
39
+
40
+ if (!pg) throw new Error('need pg');
41
+
42
+ if (pg?.readonly) {
43
+ return null;
44
+ }
45
+
46
+ const keyTo = `${pg.options?.database}:mail:${provider[0]}:${to || ''}${id || ''}${table || ''}${title || ''}`;
47
+ const uniqueTo = await rclient.setnx(keyTo, 1);
48
+ logger.info('notification/sent', { keyTo, send: uniqueTo, nocache });
49
+
50
+ if (!uniqueTo && !nocache) {
51
+ return `already sent: ${keyTo}`;
52
+ }
53
+ await rclient.expire(keyTo, 1000 * 600);
54
+
55
+ if (!to.length) {
56
+ return null;
57
+ }
58
+
59
+ if (!(Array.isArray(provider) && provider.length)) {
60
+ return 'notification provider - must be array and not empty';
61
+ }
62
+
63
+ try {
64
+ const html = await generateNotificationContent({
65
+ pg, table, template, id, message, data,
66
+ });
67
+
68
+ // return html;
69
+
70
+ if (provider.includes('email')) {
71
+ const files = Array.isArray(file) ? file : [file];
72
+ const attachments = files?.length && false ? await Promise.all(files?.filter((el) => el).map(async (el) => {
73
+ /* const content = await downloadFile(el, { buffer: true }); // ?
74
+ return {
75
+ filename: el.split('/').pop(),
76
+ encoding: 'base64',
77
+ content,
78
+ }; */
79
+ })) : [];
80
+
81
+ const toEmail = Array.isArray(to) ? to.map((emails) => emails.match(emailReg)?.join(',')) : to;
82
+
83
+ const result = await sendEmail({
84
+ attachments,
85
+ html,
86
+ subject: title,
87
+ from,
88
+ to: toEmail,
89
+ });
90
+
91
+ logger.info('notification', {
92
+ provider, title, to: toEmail, from, result, len: message?.length, files,
93
+ });
94
+
95
+ return result;
96
+ }
97
+ return null;
98
+ }
99
+ catch (err) {
100
+ logger.info('notification/error', {
101
+ provider, from, to, err: err.toString(),
102
+ });
103
+ throw err;
104
+ }
105
+ }
@@ -1,57 +1,57 @@
1
- /* eslint-disable camelcase */
2
- import { config, pgClients, getSelect } from '@opengis/fastify-table/utils.js';
3
-
4
- import { addNotification, sendNotification } from '../../../../utils.js';
5
-
6
- function sequence(arr, data, fn) {
7
- return arr.reduce((promise, row) => promise.then(() => fn({
8
- ...data, ...row,
9
- })), Promise.resolve());
10
- }
11
-
12
- export default async function onWidgetSet({ pg = pgClients?.client, link, session, log, type, payload: data = {} }) {
13
- const values = data.body?.match(/\B@[a-zA-z0-9а-яА-яіїІЇєЄ]+ [a-zA-z0-9а-яА-яіїІЇєЄ]+/g)
14
- ?.filter((el, idx, arr) => el?.replace && arr.indexOf(el) === idx)
15
- ?.map((el) => el.replace(/@/g, ''));
16
-
17
- if (type !== 'comment' || !values?.length) {
18
- return null;
19
- }
20
-
21
- const { sql } = await getSelect('core.user_mentioned');
22
-
23
- const { rows = [] } = await pg.query(`with data (id,name,email) as (${sql})
24
- select id, name, email from data where name = any($1)`, [values]);
25
-
26
- if (!rows?.length) {
27
- return null;
28
- }
29
-
30
- const message = `${data.body?.substring(0, 50)}...`;
31
- const subject = 'You were mentioned';
32
-
33
- await sequence(rows, {}, async ({ id, name, email }) => {
34
- const res = await addNotification({
35
- pg, session, subject, entity: data.entity_id, body: message, link, uid: id,
36
- });
37
- try {
38
- const res1 = await sendNotification({
39
- pg,
40
- log,
41
- to: email,
42
- // template,
43
- message,
44
- title: subject,
45
- data,
46
- nocache: 1,
47
- });
48
- if (config.local) console.info('comment notification', name, id, email, res1);
49
- await pg.query('update crm.notifications set sent=true where notification_id=$1', [res?.notification_id]);
50
- }
51
- catch (err) {
52
- console.error('comment notification send error', err.toString());
53
- }
54
- });
55
- console.log('comment notification add', rows);
56
- return null;
57
- }
1
+ /* eslint-disable camelcase */
2
+ import { config, pgClients, getSelect } from '@opengis/fastify-table/utils.js';
3
+
4
+ import { addNotification, sendNotification } from '../../../../utils.js';
5
+
6
+ function sequence(arr, data, fn) {
7
+ return arr.reduce((promise, row) => promise.then(() => fn({
8
+ ...data, ...row,
9
+ })), Promise.resolve());
10
+ }
11
+
12
+ export default async function onWidgetSet({ pg = pgClients?.client, link, session, log, type, payload: data = {} }) {
13
+ const values = data.body?.match(/\B@[a-zA-z0-9а-яА-яіїІЇєЄ]+ [a-zA-z0-9а-яА-яіїІЇєЄ]+/g)
14
+ ?.filter((el, idx, arr) => el?.replace && arr.indexOf(el) === idx)
15
+ ?.map((el) => el.replace(/@/g, ''));
16
+
17
+ if (type !== 'comment' || !values?.length) {
18
+ return null;
19
+ }
20
+
21
+ const { sql } = await getSelect('core.user_mentioned');
22
+
23
+ const { rows = [] } = await pg.query(`with data (id,name,email) as (${sql})
24
+ select id, name, email from data where name = any($1)`, [values]);
25
+
26
+ if (!rows?.length) {
27
+ return null;
28
+ }
29
+
30
+ const message = `${data.body?.substring(0, 50)}...`;
31
+ const subject = 'You were mentioned';
32
+
33
+ await sequence(rows, {}, async ({ id, name, email }) => {
34
+ const res = await addNotification({
35
+ pg, session, subject, entity: data.entity_id, body: message, link, uid: id,
36
+ });
37
+ try {
38
+ const res1 = await sendNotification({
39
+ pg,
40
+ log,
41
+ to: email,
42
+ // template,
43
+ message,
44
+ title: subject,
45
+ data,
46
+ nocache: 1,
47
+ });
48
+ if (config.local) console.info('comment notification', name, id, email, res1);
49
+ await pg.query('update crm.notifications set sent=true where notification_id=$1', [res?.notification_id]);
50
+ }
51
+ catch (err) {
52
+ console.error('comment notification send error', err.toString());
53
+ }
54
+ });
55
+ console.log('comment notification add', rows);
56
+ return null;
57
+ }
@@ -1,27 +1,27 @@
1
- import { config, addHook } from '@opengis/fastify-table/utils.js';
2
-
3
- // api
4
- import testEmail from './controllers/testEmail.js';
5
- import readNotifications from './controllers/readNotifications.js'; // mark as read
6
- import userNotifications from './controllers/userNotifications.js'; // check all, backend pagination
7
-
8
- // hook
9
- import onWidgetSet from './hook/onWidgetSet.js'; // send notification on comment
10
-
11
- // funcs
12
- // import addNotification from '../notifications/funcs/addNotification.js'; // add to db
13
- // import notification from '../notifications/funcs/sendNotification.js'; // send notification
14
-
15
- import { notificationSchema, emailSchema } from './schema.js';
16
-
17
- export default async function route(fastify) {
18
- const prefix = config.prefix || '/api';
19
-
20
- // fastify.decorate('addNotification', addNotification);
21
- // fastify.decorate('notification', notification);
22
-
23
- fastify.get(`${prefix}/test-email`, { config: { policy: ['user'] }, schema: emailSchema }, testEmail);
24
- fastify.get(`/notification`, { config: { policy: ['user'] }, schema: notificationSchema }, userNotifications);
25
- fastify.get(`/notification-read/:id?`, { config: { policy: ['user'] }, schema: notificationSchema }, readNotifications);
26
- addHook('onWidgetSet', onWidgetSet);
27
- }
1
+ import { config, addHook } from '@opengis/fastify-table/utils.js';
2
+
3
+ // api
4
+ import testEmail from './controllers/testEmail.js';
5
+ import readNotifications from './controllers/readNotifications.js'; // mark as read
6
+ import userNotifications from './controllers/userNotifications.js'; // check all, backend pagination
7
+
8
+ // hook
9
+ import onWidgetSet from './hook/onWidgetSet.js'; // send notification on comment
10
+
11
+ // funcs
12
+ // import addNotification from '../notifications/funcs/addNotification.js'; // add to db
13
+ // import notification from '../notifications/funcs/sendNotification.js'; // send notification
14
+
15
+ import { notificationSchema, emailSchema } from './schema.js';
16
+
17
+ export default async function route(fastify) {
18
+ const prefix = config.prefix || '/api';
19
+
20
+ // fastify.decorate('addNotification', addNotification);
21
+ // fastify.decorate('notification', notification);
22
+
23
+ fastify.get(`${prefix}/test-email`, { config: { policy: ['user'] }, schema: emailSchema }, testEmail);
24
+ fastify.get(`/notification`, { config: { policy: ['user'] }, schema: notificationSchema }, userNotifications);
25
+ fastify.get(`/notification-read/:id?`, { config: { policy: ['user'] }, schema: notificationSchema }, readNotifications);
26
+ addHook('onWidgetSet', onWidgetSet);
27
+ }