@opengis/fastify-table 1.1.55 → 1.1.57

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (260) hide show
  1. package/README.md +26 -26
  2. package/config.js +10 -10
  3. package/index.js +27 -14
  4. package/package.json +10 -6
  5. package/server/migrations/log.sql +80 -80
  6. package/{cron → server/plugins/cron}/funcs/addCron.js +15 -19
  7. package/server/plugins/cron/index.js +6 -0
  8. package/{crud → server/plugins/crud}/funcs/dataDelete.js +3 -1
  9. package/{crud → server/plugins/crud}/funcs/dataInsert.js +3 -0
  10. package/{crud → server/plugins/crud}/funcs/dataUpdate.js +3 -1
  11. package/{crud → server/plugins/crud}/funcs/getAccess.js +5 -3
  12. package/{crud → server/plugins/crud}/funcs/getOpt.js +2 -0
  13. package/{crud → server/plugins/crud}/funcs/getToken.js +30 -27
  14. package/{crud → server/plugins/crud}/funcs/isFileExists.js +13 -13
  15. package/{crud → server/plugins/crud}/funcs/setOpt.js +3 -0
  16. package/{crud → server/plugins/crud}/funcs/setToken.js +4 -1
  17. package/{crud → server/plugins/crud}/funcs/utils/getFolder.js +2 -1
  18. package/{crud → server/plugins/crud}/funcs/utils/logChanges.js +2 -2
  19. package/server/plugins/crud/index.js +23 -0
  20. package/{hook → server/plugins/hook}/funcs/addHook.js +1 -1
  21. package/{hook → server/plugins/hook}/funcs/applyHook.js +2 -2
  22. package/{cron/controllers/utils/cronList.js → server/plugins/hook/hookList.js} +1 -1
  23. package/server/plugins/hook/index.js +8 -0
  24. package/{logger → server/plugins/logger}/createFileStream.js +2 -2
  25. package/{logger → server/plugins/logger}/getLogger.js +1 -1
  26. package/{migration → server/plugins/migration/funcs}/exec.migrations.js +1 -1
  27. package/server/plugins/migration/index.js +7 -0
  28. package/{pg → server/plugins/pg}/funcs/getPG.js +3 -3
  29. package/{pg → server/plugins/pg}/funcs/getPGAsync.js +3 -3
  30. package/{pg → server/plugins/pg}/funcs/init.js +2 -4
  31. package/{pg → server/plugins/pg}/index.js +5 -14
  32. package/{pg → server/plugins/pg}/pgClients.js +2 -1
  33. package/{policy → server/plugins/policy}/funcs/checkPolicy.js +1 -1
  34. package/{crud/controllers/utils → server/plugins/policy/funcs}/checkXSS.js +1 -4
  35. package/{policy → server/plugins/policy}/index.js +0 -2
  36. package/{policy/funcs → server/plugins/policy}/sqlInjection.js +1 -1
  37. package/{crud/controllers/utils → server/plugins/policy}/xssInjection.js +72 -72
  38. package/{redis → server/plugins/redis}/funcs/getRedis.js +24 -23
  39. package/{redis → server/plugins/redis}/funcs/redisClients.js +1 -0
  40. package/{redis → server/plugins/redis}/index.js +2 -6
  41. package/{table → server/plugins/table}/funcs/getFilterSQL/index.js +3 -1
  42. package/{table/controllers/utils → server/plugins/table/funcs}/getSelectMeta.js +1 -10
  43. package/{table/controllers/utils → server/plugins/table/funcs}/getTemplate.js +2 -1
  44. package/{table/controllers/utils → server/plugins/table/funcs}/getTemplatePath.js +3 -3
  45. package/{table/controllers/utils → server/plugins/table/funcs}/getTemplates.js +2 -1
  46. package/{table/controllers/utils → server/plugins/table/funcs}/gisIRColumn.js +4 -7
  47. package/{table → server/plugins/table}/funcs/metaFormat/getSelectVal.js +4 -2
  48. package/{table → server/plugins/table}/funcs/metaFormat/index.js +3 -1
  49. package/server/plugins/table/index.js +13 -0
  50. package/{util → server/plugins/util/funcs}/eventStream.js +1 -0
  51. package/server/plugins/util/index.js +7 -0
  52. package/{cron → server/routes/cron}/controllers/cronApi.js +22 -22
  53. package/{cron → server/routes/cron}/index.js +5 -3
  54. package/{crud → server/routes/crud}/controllers/deleteCrud.js +2 -2
  55. package/{crud → server/routes/crud}/controllers/insert.js +5 -3
  56. package/{crud → server/routes/crud}/controllers/update.js +3 -3
  57. package/server/routes/crud/index.js +19 -0
  58. package/{util → server/routes/logger}/controllers/logger.file.js +5 -5
  59. package/{util → server/routes/logger}/controllers/utils/checkUserAccess.js +1 -1
  60. package/{util → server/routes/logger}/controllers/utils/getRootDir.js +4 -3
  61. package/server/routes/logger/index.js +15 -0
  62. package/{util → server/routes/properties}/controllers/properties.add.js +19 -20
  63. package/server/routes/properties/controllers/properties.get.js +17 -0
  64. package/{util → server/routes/properties}/index.js +5 -8
  65. package/{table → server/routes/table}/controllers/card.js +3 -5
  66. package/{table → server/routes/table}/controllers/data.js +4 -10
  67. package/{table → server/routes/table}/controllers/filter.js +3 -4
  68. package/{table → server/routes/table}/controllers/form.js +1 -1
  69. package/{table → server/routes/table}/controllers/search.js +15 -17
  70. package/{table → server/routes/table}/controllers/suggest.js +15 -10
  71. package/{table → server/routes/table}/controllers/table.js +5 -7
  72. package/{table → server/routes/table}/index.js +1 -10
  73. package/{table → server/routes/table}/schema.js +1 -1
  74. package/{util → server/routes/util}/controllers/next.id.js +4 -4
  75. package/server/routes/util/index.js +11 -0
  76. package/utils.js +58 -50
  77. package/.eslintrc.cjs +0 -44
  78. package/.gitlab-ci.yml +0 -18
  79. package/Changelog.md +0 -352
  80. package/cron/schema.js +0 -8
  81. package/crud/index.js +0 -31
  82. package/crud/schema.js +0 -11
  83. package/docs/.vitepress/abbr.mjs +0 -26
  84. package/docs/.vitepress/config.mjs +0 -127
  85. package/docs/.vitepress/navigation.mjs +0 -82
  86. package/docs/.vitepress/theme/Layout.vue +0 -17
  87. package/docs/.vitepress/theme/components/NavigationLinks.vue +0 -102
  88. package/docs/.vitepress/theme/components/Panzoom.vue +0 -169
  89. package/docs/.vitepress/theme/index.mjs +0 -15
  90. package/docs/.vitepress/theme/style.scss +0 -163
  91. package/docs/abbr.json +0 -4
  92. package/docs/api/cron/cronApi.md +0 -56
  93. package/docs/api/crud/deleteCrud.md +0 -58
  94. package/docs/api/crud/insert.md +0 -82
  95. package/docs/api/crud/update.md +0 -85
  96. package/docs/api/index.md +0 -47
  97. package/docs/api/notification/testEmail.md +0 -91
  98. package/docs/api/table/card.md +0 -73
  99. package/docs/api/table/data.md +0 -134
  100. package/docs/api/table/export.md +0 -60
  101. package/docs/api/table/filter.md +0 -104
  102. package/docs/api/table/form.md +0 -126
  103. package/docs/api/table/search.md +0 -123
  104. package/docs/api/table/suggest.md +0 -156
  105. package/docs/api/table/table.md +0 -107
  106. package/docs/api/user/user.cls.id.md +0 -77
  107. package/docs/api/user/user.cls.md +0 -49
  108. package/docs/api/user/user.cls.post.md +0 -62
  109. package/docs/api/user/user.info.md +0 -37
  110. package/docs/api/utils/logger.file.md +0 -61
  111. package/docs/api/utils/next.id.md +0 -34
  112. package/docs/api/utils/properties.add.md +0 -127
  113. package/docs/api/utils/properties.get.md +0 -73
  114. package/docs/api/utils/status.monitor.md +0 -36
  115. package/docs/api/widget/widget.del.md +0 -76
  116. package/docs/api/widget/widget.get.md +0 -233
  117. package/docs/api/widget/widget.set.md +0 -88
  118. package/docs/db/admin.md +0 -947
  119. package/docs/db/crm.md +0 -564
  120. package/docs/db/index.md +0 -9
  121. package/docs/db/log.md +0 -204
  122. package/docs/hook/card/afterCard.md +0 -20
  123. package/docs/hook/card/preCard.md +0 -25
  124. package/docs/hook/data/afterData.md +0 -26
  125. package/docs/hook/data/preData.md +0 -26
  126. package/docs/hook/deleteCrud/afterDelete.md +0 -21
  127. package/docs/hook/deleteCrud/preDelete.md +0 -26
  128. package/docs/hook/form/afterForm.md +0 -19
  129. package/docs/hook/form/preForm.md +0 -26
  130. package/docs/hook/getTemplate/afterTemplate.md +0 -24
  131. package/docs/hook/getTemplate/preTemplate.md +0 -29
  132. package/docs/hook/index.md +0 -45
  133. package/docs/hook/insert/afterInsert.md +0 -41
  134. package/docs/hook/insert/preInsert.md +0 -25
  135. package/docs/hook/table/afterTable.md +0 -20
  136. package/docs/hook/table/preTable.md +0 -25
  137. package/docs/hook/update/afterUpdate.md +0 -41
  138. package/docs/hook/update/preUpdate.md +0 -25
  139. package/docs/index.md +0 -42
  140. package/docs/public/fastify-dark.svg +0 -4
  141. package/docs/public/fastify.svg +0 -1
  142. package/docs/public/logo-short-dark.svg +0 -12
  143. package/docs/public/logo-short.svg +0 -11
  144. package/docs/public/logo.svg +0 -19
  145. package/docs/readme/index.md +0 -121
  146. package/docs/templates/card.md +0 -83
  147. package/docs/templates/cls.md +0 -29
  148. package/docs/templates/filters.md +0 -91
  149. package/docs/templates/forms.md +0 -139
  150. package/docs/templates/image.png +0 -0
  151. package/docs/templates/index.md +0 -28
  152. package/docs/templates/select.md +0 -90
  153. package/docs/templates/table.md +0 -162
  154. package/docs/utils/cron/addCron.md +0 -29
  155. package/docs/utils/crud/dataInsert.md +0 -52
  156. package/docs/utils/crud/dataUpdate.md +0 -53
  157. package/docs/utils/crud/getOpt.md +0 -34
  158. package/docs/utils/crud/isFileExists.md +0 -38
  159. package/docs/utils/crud/setOpt.md +0 -38
  160. package/docs/utils/hook/addHook.md +0 -74
  161. package/docs/utils/hook/applyHook.md +0 -64
  162. package/docs/utils/index.md +0 -48
  163. package/docs/utils/notification/addNotification.md +0 -28
  164. package/docs/utils/notification/notification.md +0 -41
  165. package/docs/utils/pg/autoIndex.md +0 -22
  166. package/docs/utils/pg/getMeta.md +0 -59
  167. package/docs/utils/pg/getPG.md +0 -34
  168. package/docs/utils/pg/init.md +0 -30
  169. package/docs/utils/pg/pg.md +0 -70
  170. package/docs/utils/redis/getRedis.md +0 -36
  171. package/docs/utils/redis/rclient.md +0 -74
  172. package/docs/utils/table/getForm.md +0 -69
  173. package/docs/utils/table/getMeta.md +0 -56
  174. package/docs/utils/table/getSelect.md +0 -39
  175. package/docs/utils/table/getSelectMeta.md +0 -47
  176. package/docs/utils/table/getTable.md +0 -78
  177. package/helper.js +0 -30
  178. package/module/core/select/core.user_mentioned.sql +0 -2
  179. package/module/test/cls/itree.composition.json +0 -26
  180. package/module/test/table/test.rest_zone.table.json +0 -266
  181. package/notification/controllers/readNotifications.js +0 -27
  182. package/notification/controllers/testEmail.js +0 -46
  183. package/notification/controllers/userNotifications.js +0 -61
  184. package/notification/controllers/utils/pin-m-ty-media-record-outline+303070.png +0 -0
  185. package/notification/funcs/addNotification.js +0 -21
  186. package/notification/funcs/sendNotification.js +0 -112
  187. package/notification/funcs/utils/sendEmail.js +0 -39
  188. package/notification/index.js +0 -18
  189. package/notification/schema.js +0 -10
  190. package/server.js +0 -26
  191. package/table/controllers/utils/getTemplate_old.js +0 -28
  192. package/test/api/applyHook.test.js +0 -95
  193. package/test/api/crud.test.js +0 -89
  194. package/test/api/crud.xss.test.js +0 -80
  195. package/test/api/notification.test.js +0 -48
  196. package/test/api/suggest.test.js +0 -66
  197. package/test/api/table.test.js +0 -134
  198. package/test/api/user.test.js +0 -85
  199. package/test/api/widget.test.js +0 -117
  200. package/test/config.example +0 -18
  201. package/test/funcs/pg.test.js +0 -34
  202. package/test/funcs/redis.test.js +0 -19
  203. package/test/helper/formatDate.test.js +0 -62
  204. package/test/templates/cls/itree.quality_condition.json +0 -20
  205. package/test/templates/cls/itree.recommend copy.json +0 -26
  206. package/test/templates/cls/itree.recommend.json +0 -26
  207. package/test/templates/cls/itree.type_plant.json +0 -65
  208. package/test/templates/cls/test.json +0 -10
  209. package/test/templates/form/cp_building.form.json +0 -33
  210. package/test/templates/select/account_id.json +0 -4
  211. package/test/templates/select/account_id.sql +0 -1
  212. package/test/templates/select/atu.nsdi.ato_level.json +0 -4
  213. package/test/templates/select/atu.nsdi.ato_level.sql +0 -11
  214. package/test/templates/select/contact_id.sql +0 -1
  215. package/test/templates/select/storage.data.json +0 -3
  216. package/test/templates/select/storage.data.sql +0 -1
  217. package/test/templates/select/test.storage.data.json +0 -4
  218. package/test/templates/select/test.storage.data.sql +0 -1
  219. package/test/templates/select/test.suggest.ato_new.json +0 -4
  220. package/test/templates/select/test.suggest.ato_new.sql +0 -26
  221. package/test/templates/select/test.suggest.data.json +0 -5
  222. package/test/templates/select/test.suggest.data.sql +0 -1
  223. package/test/templates/select/test.suggest.parent.sql +0 -2
  224. package/test/templates/table/gis.dataset.table.json +0 -21
  225. package/test/templates/table/green_space.table.json +0 -383
  226. package/test/templates/table/service.json +0 -18
  227. package/user/controllers/user.cls.id.js +0 -14
  228. package/user/controllers/user.cls.js +0 -71
  229. package/user/controllers/user.cls.post.js +0 -52
  230. package/user/controllers/user.info.js +0 -17
  231. package/user/index.js +0 -17
  232. package/user/schema.js +0 -17
  233. package/util/controllers/properties.get.js +0 -17
  234. package/util/schema.js +0 -19
  235. package/widget/controllers/utils/historyFormat.js +0 -76
  236. package/widget/controllers/utils/obj2db.js +0 -13
  237. package/widget/controllers/widget.del.js +0 -41
  238. package/widget/controllers/widget.get.js +0 -96
  239. package/widget/controllers/widget.set.js +0 -74
  240. package/widget/index.js +0 -40
  241. /package/{hook/funcs/hookList.js → server/plugins/cron/cronList.js} +0 -0
  242. /package/{logger → server/plugins/logger}/getHooks.js +0 -0
  243. /package/{logger → server/plugins/logger}/labels.js +0 -0
  244. /package/{logger → server/plugins/logger}/logger.test.api.js +0 -0
  245. /package/{logger → server/plugins/logger}/serializers.js +0 -0
  246. /package/{pg → server/plugins/pg}/funcs/autoIndex.js +0 -0
  247. /package/{pg → server/plugins/pg}/funcs/getMeta.js +0 -0
  248. /package/{pg → server/plugins/pg}/funcs/pgClients.js +0 -0
  249. /package/{redis → server/plugins/redis}/client.js +0 -0
  250. /package/{table/controllers/utils → server/plugins/table/funcs}/addTemplateDir.js +0 -0
  251. /package/{table → server/plugins/table}/funcs/getFilterSQL/util/formatValue.js +0 -0
  252. /package/{table → server/plugins/table}/funcs/getFilterSQL/util/getCustomQuery.js +0 -0
  253. /package/{table → server/plugins/table}/funcs/getFilterSQL/util/getFilterQuery.js +0 -0
  254. /package/{table → server/plugins/table}/funcs/getFilterSQL/util/getOptimizedQuery.js +0 -0
  255. /package/{table → server/plugins/table}/funcs/getFilterSQL/util/getTableSql.js +0 -0
  256. /package/{table/controllers/utils → server/plugins/table/funcs}/getSelect.js +0 -0
  257. /package/{table/controllers/utils → server/plugins/table/funcs}/loadTemplate.js +0 -0
  258. /package/{table/controllers/utils → server/plugins/table/funcs}/loadTemplatePath.js +0 -0
  259. /package/{table/controllers/utils → server/plugins/table/funcs}/userTemplateDir.js +0 -0
  260. /package/{util → server/routes/util}/controllers/status.monitor.js +0 -0
@@ -1,39 +0,0 @@
1
- import nodemailer from 'nodemailer';
2
-
3
- import config from '../../../config.js';
4
-
5
- /**
6
- * Надсилає поваідомлення на пошту
7
- *
8
- * @type function
9
- * @alias sendEmail
10
- * @summary Функція здійснює розсилку по email
11
- */
12
-
13
- export default async function sendEmail({
14
- to, from, subject, html, attachments,
15
- }) {
16
- if (!to?.length) {
17
- throw new Error('empty to list');
18
- }
19
-
20
- const { mailSetting = {} } = config;
21
-
22
- /*= == check service and setting === */
23
- if (!mailSetting.service) {
24
- throw new Error('service is not defined in config');
25
- }
26
-
27
- Object.assign(mailSetting, { rejectUnauthorized: false });
28
-
29
- if (mailSetting.port === 465) {
30
- Object.assign(mailSetting, { secure: true });
31
- }
32
-
33
- const transport = nodemailer.createTransport(mailSetting);
34
-
35
- const result = await transport.sendMail({
36
- from: from || mailSetting.from, to, subject, html, attachments,
37
- });
38
- return result;
39
- }
@@ -1,18 +0,0 @@
1
- // api
2
- import testEmail from './controllers/testEmail.js';
3
- // funcs
4
- import addNotification from './funcs/addNotification.js'; // add to db
5
- import notification from './funcs/sendNotification.js'; // send notification
6
-
7
- import emailSchema from './schema.js'
8
-
9
- async function plugin(fastify, config = {}) {
10
- const prefix = config.prefix || '/api';
11
-
12
- fastify.get(`${prefix}/test-email`, { config: { policy: ['user'] }, schema: emailSchema }, testEmail);
13
-
14
- fastify.decorate('addNotification', addNotification);
15
- fastify.decorate('notification', notification);
16
- }
17
-
18
- export default plugin;
@@ -1,10 +0,0 @@
1
- const emailSchema = {
2
- quertstring: {
3
- to: { type: 'string', pattern: '^((?!\\.)[\\w\\-_.]*[^.])(@\\w+)(\\.\\w+(\\.\\w+)?[^.\\W])$' },
4
- },
5
- };
6
-
7
- export {
8
- emailSchema,
9
- };
10
- export default null;
package/server.js DELETED
@@ -1,26 +0,0 @@
1
- // This file contains code that we reuse
2
- // between our tests.
3
- import Fastify from 'fastify';
4
- import config from './config.js';
5
- import appService from './index.js';
6
- import logger from './logger/getLogger.js';
7
- import loggerTest from './logger/logger.test.api.js';
8
-
9
- const app = Fastify({ logger });
10
- app.register(appService, config);
11
-
12
- app.get('/logger-test', {
13
- schema: {
14
- querystring: {
15
- name: { type: 'string' },
16
- excitement: { type: 'integer' },
17
- },
18
- },
19
- }, loggerTest);
20
-
21
- app.listen({ host: '0.0.0.0', port: process.env.PORT || 3000 }, (err) => {
22
- if (err) {
23
- app.log.error(err);
24
- process.exit(1);
25
- }
26
- });
@@ -1,28 +0,0 @@
1
- import { readFile } from 'fs/promises';
2
- import fs from 'fs';
3
- import path from 'path';
4
- import config from '../../../config.js';
5
-
6
- const loadTemplate = {};
7
-
8
- export default async function getTemplateDir(type, name) {
9
- if (!type) return null;
10
- if (!name) return null;
11
-
12
- const cwd = process.cwd();
13
- const typeDir = path.join(cwd, (config.templateDir || 'server/templates'), type);
14
-
15
- if (!loadTemplate[type]) {
16
- const typeList = fs.existsSync(typeDir) ? fs.readdirSync(typeDir) : [];
17
- loadTemplate[type] = typeList;
18
- }
19
-
20
- const fullname = loadTemplate[type].find((el) => path.parse(el).name === name);
21
- const ext = fullname ? path.extname(fullname)?.slice(1) : null;
22
- if (!ext) return null;
23
-
24
- const sql = loadTemplate[type].includes(`${name}.sql`) ? await readFile(path.join(typeDir, `${name}.sql`), 'utf-8') : null;
25
- const data = loadTemplate[type].includes(`${name}.json`) ? JSON.parse(await readFile(path.join(typeDir, `${name}.json`), 'utf-8')) : await readFile(path.join(typeDir, `${name}.${ext}`), 'utf-8');
26
- if (sql) return { sql };
27
- return data;
28
- }
@@ -1,95 +0,0 @@
1
- import { test } from 'node:test';
2
- import assert from 'node:assert';
3
- import path from 'node:path';
4
- import pgClients from '../../pg/pgClients.js';
5
- import init from '../../pg/funcs/init.js';
6
-
7
- import build from '../../helper.js';
8
- import config from '../config.js';
9
-
10
- import { addTemplateDir, addHook } from '../../utils.js';
11
-
12
- const prefix = config.prefix || '/api';
13
- const table = 'gis.dataset.table';
14
-
15
- test('applyHook to API data/table', async (t) => {
16
- const app = await build(t);
17
- const cwd = process.cwd();
18
- await init(pgClients.client);
19
- addTemplateDir(path.join(cwd, 'test/templates'));
20
-
21
- addHook('preData', async ({ table: table1 }) => {
22
- if (table1 === `${table}1`) {
23
- return { message: 'access restricted by hook', status: 403 };
24
- }
25
- return null;
26
- });
27
- addHook('preTable', async ({ table: table1 }) => {
28
- if (table1 === `${table}1`) {
29
- return { message: 'access restricted by hook', status: 403 };
30
- }
31
- return null;
32
- });
33
-
34
- addHook('afterData', async ({ res }) => {
35
- Object.assign(res, { test: '1' });
36
- });
37
- addHook('afterTable', async ({ rows = [] }) => {
38
- Object.assign(rows[0], { count: 1 });
39
- });
40
-
41
- await t.test('GET /data (preData ok)', async () => {
42
- const res = await app.inject({
43
- method: 'GET',
44
- url: `${prefix}/data/${table}`,
45
- });
46
- const json = res.json();
47
- assert.ok(json?.time, 'api error');
48
- });
49
- await t.test('GET /data (preData message)', async () => {
50
- const res = await app.inject({
51
- method: 'GET',
52
- url: `${prefix}/data/${table}1`,
53
- });
54
- const json = res.json();
55
- assert.ok(json.message === 'access restricted by hook', 'preData hook error');
56
- });
57
-
58
- await t.test('GET /data (afterData)', async () => {
59
- const res = await app.inject({
60
- method: 'GET',
61
- url: `${prefix}/data/${table}`,
62
- });
63
- const json = res.json();
64
- assert.ok(json?.test === '1', 'afterData hook error');
65
- });
66
-
67
- const { id = '1' } = pgClients.client?.pk['gis.dataset']
68
- ? await pgClients.client.query('select dataset_id as id from gis.dataset limit 1')
69
- .then((res) => res.rows?.[0] || {}) : {};
70
- await t.test('GET /table/:id (preTable ok)', async () => {
71
- const res = await app.inject({
72
- method: 'GET',
73
- url: `${prefix}/table/${table}1/${id}`,
74
- });
75
- const json = res.json();
76
- assert.ok(json.message === 'access restricted by hook', 'preTable hook error');
77
- });
78
- await t.test('GET /table/:id (preTable message)', async () => {
79
- const res = await app.inject({
80
- method: 'GET',
81
- url: `${prefix}/table/${table}1/${id}`,
82
- });
83
- const json = res.json();
84
- assert.ok(json.message === 'access restricted by hook', 'preTable hook error');
85
- });
86
-
87
- await t.test('GET /table/:id (afterTable)', async () => {
88
- const res = await app.inject({
89
- method: 'GET',
90
- url: `${prefix}/table/${table}/${id}`,
91
- });
92
- const json = res.json();
93
- assert.equal(json?.count, 1);
94
- });
95
- });
@@ -1,89 +0,0 @@
1
- import { test } from 'node:test';
2
- import assert from 'node:assert';
3
-
4
- import build from '../../helper.js';
5
-
6
- import config from '../config.js';
7
- import pgClients from '../../pg/pgClients.js';
8
-
9
- const mapId = '5400000';
10
-
11
- test('api crud', async (t) => {
12
- const app = await build(t);
13
- assert.ok(111);
14
- return;
15
- const prefix = config.prefix || '/api';
16
-
17
- // delete old test data before test
18
- const { rowCount } = await pgClients.client.query('delete from gis.map where map_id=$1', [mapId]);
19
- console.log(rowCount);
20
-
21
- app.addHook('onRequest', async (req) => {
22
- req.session = { passport: { user: { uid: '1' } } };
23
- req.user = req.session.passport.user;
24
- req.uid = req.user.uid;
25
- });
26
-
27
- await t.test('POST /insert', async () => {
28
- const res = await app.inject({
29
- method: 'POST',
30
- url: `${prefix}/table/test.gis.map.table`,
31
- body: {
32
- alias: 'testMap',
33
- map_id: mapId,
34
- ord: 1,
35
- enabled: false,
36
- tags: ['unit', 'test'],
37
- },
38
- });
39
- assert.ok(res.json().rows ? res.json().rows[0]?.map_id : res.json().map_id, res.json().status);
40
- assert.ok(111);
41
- });
42
-
43
- await t.test('POST /properties/:id', async () => {
44
- const res = await app.inject({
45
- method: 'POST',
46
- url: `${prefix}/properties/${mapId}`,
47
- body: {
48
- custom_alias: 'testMap',
49
- custom_ord: 5,
50
- },
51
- });
52
- assert.ok(res.json().message?.rows?.length, res.json().status);
53
- });
54
-
55
- await t.test('GET /properties/:id', async () => {
56
- const res = await app.inject({
57
- method: 'GET',
58
- url: `${prefix}/properties/${mapId}`,
59
- });
60
- assert.ok(res.json().message?.custom_alias, res.json().status);
61
- });
62
-
63
- await t.test('PUT /update', async () => {
64
- const res = await app.inject({
65
- method: 'PUT',
66
- url: `${prefix}/table/test.gis.map.table/${mapId}`,
67
- body: {
68
- editor_id: '11',
69
- alias: 'testMapEdit',
70
- map_id: mapId,
71
- ord: 2,
72
- enabled: true,
73
- tags: ['unittest'],
74
- },
75
- });
76
- // console.log(res);
77
- assert.ok((res.json().rows ? res.json().rows[0]?.editor_id : res.json().editor_id) === '11', res.json().status);
78
- assert.ok(11);
79
- });
80
-
81
- await t.test('DELETE /delete', async () => {
82
- const res = await app.inject({
83
- method: 'DELETE',
84
- url: `${prefix}/table/test.gis.map.table/${mapId}`,
85
- });
86
-
87
- assert.ok(res.json().msg?.map_id === mapId, res.json().status);
88
- });
89
- });
@@ -1,80 +0,0 @@
1
- import { test } from 'node:test';
2
- import assert from 'node:assert';
3
-
4
- import build from '../../helper.js';
5
-
6
- import setToken from '../../crud/funcs/setToken.js';
7
- import getToken from '../../crud/funcs/getToken.js';
8
- import addHook from '../../hook/funcs/addHook.js';
9
- import config from '../config.js';
10
- import pgClients from '../../pg/pgClients.js';
11
-
12
- addHook('preInsert', async ({ table }) => getToken({
13
- mode: 'a', token: table, uid: '1', json: 1,
14
- }));
15
-
16
- addHook('preUpdate', async ({ table }) => getToken({
17
- mode: 'w', token: table, uid: '1', json: 1,
18
- }));
19
-
20
- addHook('preDelete', async ({ table }) => getToken({
21
- mode: 'w', token: table, uid: '1', json: 1,
22
- }));
23
-
24
- test('api crud xss', async (t) => {
25
- const app = await build(t);
26
- const session = { passport: { user: { uid: '1', user_type: 'admin' } } };
27
- app.addHook('onRequest', async (req) => {
28
- req.session = session;
29
- req.user = session.passport.user;
30
- });
31
-
32
- const id = 'test';
33
- const prefix = config.prefix || '/api';
34
-
35
- await t.test('POST /insert', async () => {
36
- const addTokens = setToken({
37
- ids: [JSON.stringify({ table: 'test.rest_zone.table', form: 'rest_zone.form' })],
38
- mode: 'a',
39
- uid: 1,
40
- array: 1,
41
- });
42
- assert.ok(addTokens.length, 'invalid token');
43
- const res = await app.inject({
44
- method: 'POST',
45
- url: `${prefix}/table/${addTokens[0]}`,
46
- body: { rz_id: 'test', composition: '<a onClick="alert("XSS Injection")">xss injection</a>' },
47
- });
48
- assert.equal(res?.json()?.status || res?.statusCode, 409);
49
- });
50
-
51
- const editTokens = setToken({
52
- ids: [JSON.stringify({ id, table: 'test.rest_zone.table', form: 'rest_zone.form' })],
53
- mode: 'w',
54
- uid: 1,
55
- array: 1,
56
- });
57
-
58
- await t.test('PUT /update', async () => {
59
- const res = await app.inject({
60
- method: 'PUT',
61
- url: `${prefix}/table/${editTokens[0]}`,
62
- body: { editor_id: '11', composition: '<a onClick="alert("XSS Injection")">xss injection</a>' },
63
- });
64
- assert.equal(res.json()?.status || res?.statusCode, 409);
65
- });
66
- await t.test('DELETE /delete', async () => {
67
- const res = await app.inject({
68
- method: 'DELETE',
69
- url: `${prefix}/table/${editTokens[0]}`,
70
- });
71
- assert.equal(res?.json()?.status || res?.statusCode, 200);
72
- });
73
-
74
- // after
75
- await t.test('clean up', async () => {
76
- const { rowCount } = await pgClients.client.query('delete from itree.rest_zones where composition::text ilike \'%xss injection%\'');
77
- const { rowCount: testRows } = await pgClients.client.query('delete from itree.rest_zones where rz_id=\'test\'');
78
- console.log('clean up', rowCount, testRows);
79
- });
80
- });
@@ -1,48 +0,0 @@
1
- import { test } from 'node:test';
2
- import assert from 'node:assert';
3
-
4
- import build from '../../helper.js';
5
- import config from '../config.js';
6
-
7
- import { getSelect, initPG, pgClients } from '../../utils.js';
8
-
9
- const session = { passport: { user: { uid: config.testUser?.uid || '1' } } };
10
- const { uid } = session.passport.user;
11
-
12
- test('api && funcs notification', async (t) => {
13
- const app = await build(t);
14
- const { client: pg } = pgClients;
15
- await initPG(pg);
16
-
17
- app.addHook('onRequest', async (req) => {
18
- req.session = session;
19
- });
20
-
21
- const notificationIds = await pgClients.client.query(`insert into crm.notifications(addressee_id,entity_id,author_id,subject,body,link)
22
- values($1,$1,$1,$1,$1,$1), ($1,$1,$1,$1,$1,$1) returning notification_id as "notificationId"`, [uid])
23
- .then((res) => res.rows?.map((el) => el.notificationId) || {});
24
-
25
- if (!notificationIds?.length) {
26
- assert.ok(0, 'insert notification error');
27
- }
28
-
29
- const { sql } = await getSelect('core.user_mentioned');
30
- const { name } = await pg.query(`with data (id,name,email) as (${sql})
31
- select name from data where id = $1`, [uid]).then((res) => res.rows?.[0] || {});
32
- if (name) {
33
- await t.test('GET Email Notification via HOOK at POST /widget/comment/:id', async () => {
34
- const res = await app.inject({
35
- method: 'POST',
36
- url: `/api/widget/comment/${notificationIds[0]}`,
37
- body: { body: `@${name}`, entity_id: uid },
38
- });
39
- assert.equal(res.statusCode, 200);
40
- assert.equal(res.json().rowCount, 1);
41
- });
42
- }
43
-
44
- await t.test('clean up', async () => {
45
- const { rowCount = 0 } = await pg.query('delete from crm.notifications where entity_id=$1', [uid]);
46
- console.log('clean up', rowCount);
47
- });
48
- });
@@ -1,66 +0,0 @@
1
- import { test } from 'node:test';
2
- import assert from 'node:assert';
3
-
4
- import build from '../../helper.js';
5
-
6
- test('api suggest', async (t) => {
7
- const app = await build(t);
8
-
9
- await t.test('GET /suggest', async () => {
10
- const res = await app.inject({
11
- method: 'GET',
12
- url: '/api/suggest/test.storage.data',
13
- });
14
- const rep = JSON.parse(res?.body);
15
- // console.log(rep);
16
- assert.equal(res?.statusCode, 200);
17
- assert.ok(rep?.count);
18
- });
19
-
20
- await t.test('GET /suggest key query', async () => {
21
- const key = 'rest_zone';
22
- const res = await app.inject({
23
- method: 'GET',
24
- url: `/api/suggest/test.storage.data?key=${key}`,
25
- });
26
- const rep = JSON.parse(res?.body);
27
- // console.log(rep);
28
- assert.equal(res?.statusCode, 200);
29
- assert.ok(rep?.count);
30
- });
31
-
32
- await t.test('GET /suggest key searchColumn', async () => {
33
- const key = 'site.rest_zone.table';
34
- const res = await app.inject({
35
- method: 'GET',
36
- url: `/api/suggest/test.storage.data?key=${key}`,
37
- });
38
- const rep = JSON.parse(res?.body);
39
- // console.log(rep);
40
- assert.equal(res?.statusCode, 200);
41
- assert.ok(rep?.count);
42
- });
43
- /*
44
- await t.test('GET /suggest інша db', async () => {
45
- const res = await app.inject({
46
- method: 'GET',
47
- url: '/api/suggest/test.suggest.data',
48
- });
49
- const rep = JSON.parse(res?.body);
50
- // console.log(rep);
51
- assert.equal(res?.statusCode, 200);
52
- assert.ok(rep?.count);
53
- }); */
54
-
55
- await t.test('GET /suggest parent', async () => {
56
- const parent = '1';
57
- const res = await app.inject({
58
- method: 'GET',
59
- url: `/api/suggest/test.suggest.parent?parent=${parent}`,
60
- });
61
- const rep = JSON.parse(res?.body);
62
- // console.log(rep);
63
- assert.equal(res?.statusCode, 200);
64
- assert.ok(rep?.count);
65
- });
66
- });
@@ -1,134 +0,0 @@
1
- import { test } from 'node:test';
2
- import assert from 'node:assert';
3
- import pgClients from '../../pg/pgClients.js';
4
- import init from '../../pg/funcs/init.js';
5
-
6
- import build from '../../helper.js';
7
- import config from '../config.js';
8
- import { getTemplate } from '../../utils.js';
9
-
10
- const table = 'test.rest_zone.table';
11
-
12
- test('api table', async (t) => {
13
- const app = await build(t);
14
-
15
- const session = { passport: { user: { uid: '1', user_type: 'admin' } } };
16
- app.addHook('onRequest', async (req) => {
17
- req.session = session;
18
- req.user = session.passport.user;
19
- });
20
-
21
- await init(pgClients.client);
22
-
23
- const body = await getTemplate('table', table);
24
- assert.equal(body?.table, 'itree.rest_zones');
25
- assert.ok(pgClients.client?.pk?.[body?.table], 'invalid db - skip filter unit test');
26
-
27
- if (pgClients.client?.pk?.[body?.table]) {
28
- const custom = body?.filterCustom?.[0] || {};
29
- assert.ok(custom.name && custom.sql, 'invalid test template - empty filterCustom');
30
- const state = body?.filterState?.[0] || {};
31
- assert.ok(state.name && state.sql, 'invalid test template - empty filterState');
32
-
33
- await t.test('GET /data (filter + custom + state + sql)', async () => {
34
- const res = await app.inject({
35
- method: 'GET',
36
- url: `${config.prefix || '/api'}/data/${table}`,
37
- query: {
38
- custom: custom.name,
39
- state: state.name,
40
- filter: 'balancer~1;composition=1',
41
- sql: 1,
42
- },
43
- });
44
- assert.ok(res.body?.includes(custom.sql), 'filterCustom not ok');
45
- assert.ok(res.body?.includes(state.sql), 'filterState not ok');
46
- assert.ok(res.body?.includes('balancer::text ilike \'%1%\' and \'{1}\'::text[] && composition::text[]'), 'filter not ok');
47
- });
48
- }
49
-
50
- const bbox = '20.276526313524393 40.6651677831094,35.27752631352439 50.66616778310941';
51
- const { count = 0 } = pgClients.client?.pk[body?.table] ? await pgClients.client.query(`select count(*) from itree.rest_zones
52
- where verif and '{1}'::text[] && composition::text[] and geom && 'box(${bbox})'::box2d`).then((res) => res.rows[0] || {}) : {};
53
-
54
- await t.test('GET /data (meta bbox / cls)', async () => {
55
- const res = await app.inject({
56
- method: 'GET',
57
- url: `${config.prefix || '/api'}/data/${table}`,
58
- query: { bbox, filter: 'composition=1' },
59
- });
60
- const json = res.json();
61
- const res1 = await app.inject({
62
- method: 'GET',
63
- url: `${config.prefix || '/api'}/data/${table}`,
64
- query: { bbox, sql: 1 },
65
- });
66
- const { body: sql } = res1;
67
- assert.ok(sql?.includes(bbox), 'meta bbox sql - not ok');
68
- assert.ok(json?.rows?.length && +count >= json?.rows?.length, 'meta bbox - not ok');
69
- assert.ok(json?.rows?.length ? json?.rows?.[0]?.composition_text : true, 'meta cls - not ok');
70
- });
71
-
72
- const polyline = 'wfvkH_jsvCoKvj@oKfiB?fw@?nd@?nK?nK~WgEfE?wQfw@gEfE?vQwQvj@wQvcAoKvQoKnKgEnd@_cBgw@wj@fEwj@nKg^vQg^oK?vQgEnKgpAvj@?vcAfEf^fEf^?vj@vQvj@vQgE~Wvj@?~p@gE~iAfEnK?~iA_XnvA?nd@fEf^~p@~bBvQ?nd@wQ?vQfEf^fEnK?vQ?vj@oKfEoKfEvQnd@nKvj@?vQfEvQgEf^gEf^?vQfEvQfEvQfE~W?fE?fE?~W?f^?nd@?nK?nKfEfEg^oKwj@nK_X~W~p@~WvQnKoKn}@wQvj@oK~Wg^vcAgEnK?~Wfw@vgD~p@oKfpAvQnd@nKoKvQoKvQ?fE?fEnKvj@wQvQ?fEod@fw@~Wn}@fEn}@_Xv|A_jA~fEwQwQ_XoKwQoKoKoKoKoKg^gE_XgEoKg^gEgEgE?gEfEgEfEgEf^_XoKwQ?gEgEoK?wQ?gE~WoKoKoKwQfEgEnK_X?gEgE?oKfEoKoKgE_XgEgEwQfEoKod@_Xgw@gEoKgE_Xg^wQoKg^_XnvAgE?gEvQgE?od@fpA?vQ?f^oKvcAwj@oKg^?wQn}@gEf^oK?w|AnKgE??nKwj@gEgEg^oKwQoKoK?gEwQoaD?oKod@oKod@gEod@wQo}@oKfEf^gEfEgpAnd@_XfEgE?wQnKo}@_q@?gEgEwj@?oK?oK?_X?oKfEoK?oKfEoK?oK?oK?gEfEoKwQfEoK?gEwQwj@nKo}@nKwQ~Wod@nKoKfEgw@ovAgEwQgE??oKoKgEoKgEgEwQ?oKfEoKnKwQfEwQoK?g^fE?wQfEg^fEod@gE??fEoKvQ?nKoKnKgEfEgEgE?g^nK_q@nKod@?oKoKoK~Wgw@fEoKnd@fE?_XfEoKfEwQfEoKfEwQfEoKvQ?fEfE?vj@gE~W~WvQvQwj@vQvQf^o}@nKvQ?_XgEg^gEg^nKod@?wQgEgEgE?oK_XgEoK?oKgEoKgE_XoKg^oKg^oKod@?gEfEoKvQgEnK?nKfE?_Xnd@gw@fEwQf^wj@fEwQnd@w|A?gEgEgEgEwQfEoKfEgEnKoKnKwQfEgE?oKfEoKnKgEnKwQ_XwQnKwcAod@wQvQod@~Wgw@nKgw@oKg^f^ovAgEwQ?_X?od@gEwj@gEwQvQg^fEoKnKoKvQnK~WfEnKvQ~Wod@f^wj@~WoKnKg^~W?vQgE~WoKnKoK~WoKfEwQvQwQfEgEnKwQnKwQvQwQnKoKnKgEnKgEnKgEvQnKnK?fE?fE?~WwQnKgEnKgEfE?fE?nK?fE?fE?vQgEfE?nKfEfE?fE?vQ?~W?~WgEfEgEnKgEnKwQfEnKnKfE?wj@?o}@g^o}@_Xod@?gEf^_X?o}@?wQ~W?~WgE~WgEfE?f^gEf^oK~Wg^nKgE?oK~WwQ?od@nK_XfEwQnKoKfEgEfE~W?f^f^fEfEfEnKfEnK?gEf^vQfEnK?~WnKvQnK?vQf^nKfEfEgE~WnKfEnK?fEgEfE?nK?fEfEfEgEnK?nKgEnK?nKfEf^?vQgEvQ?nd@gEnKo}@vQgE~WgEf^gE'; // UA26040270000047749
73
-
74
- const { count1 } = await pgClients.client.query('select count(*) as count1 from itree.rest_zones where verif and ST_Contains(ST_MakePolygon(ST_LineFromEncodedPolyline($1)),geom)', [polyline])
75
- .then((res) => res.rows[0] || {});
76
- await t.test('GET /data (meta polyline)', async () => {
77
- const res = await app.inject({
78
- method: 'GET',
79
- url: `${config.prefix || '/api'}/data/${table}`,
80
- query: { polyline },
81
- });
82
- const json = res.json();
83
- assert.ok(json?.rows?.length === +count1, 'meta bbox (polyline) - not ok');
84
- });
85
-
86
- /* await t.test('GET /suggest', async () => {
87
- const res = await app.inject({
88
- method: 'GET',
89
- url: '/api/suggest/test.storage.data',
90
- });
91
- // console.log(res?.body);
92
- const rep = JSON.parse(res?.body);
93
- // console.log(rep.total);
94
- assert.ok(rep.total);
95
- }); */
96
- /* await t.test('GET /data', async () => {
97
- const res = await app.inject({
98
- method: 'GET',
99
- url: '/api/data/test.dataset.table',
100
- });
101
- // console.log(res);
102
- const rep = JSON.parse(res?.body);
103
- // console.log(rep.total);
104
- assert.ok(rep.total);
105
- }); */
106
- /* await t.test('GET /search', async () => {
107
- const res = await app.inject({
108
- method: 'GET',
109
- url: '/api/search?table=test.dataset.table&key=0',
110
- });
111
- const rep = JSON.parse(res?.body);
112
- assert.ok(rep.total);
113
- }); */
114
- await t.test('GET /form', async () => {
115
- const res = await app.inject({
116
- method: 'GET',
117
- url: '/api/form/test.dataset.form',
118
- });
119
- // console.log(res);
120
- const rep = JSON.parse(res?.body);
121
- // console.log(rep.total);
122
- assert.ok(rep);
123
- });
124
- await t.test('GET /filter', async () => {
125
- const res = await app.inject({
126
- method: 'GET',
127
- url: '/api/filter/test.dataset.table',
128
- });
129
- // console.log(res);
130
- const rep = JSON.parse(res?.body);
131
- // console.log(rep.total);
132
- assert.ok(rep);
133
- });
134
- });