@opengis/fastify-table 1.1.49 → 1.1.50
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/.gitlab-ci.yml +18 -0
- package/README.md +26 -26
- package/config.js +10 -10
- package/cron/controllers/cronApi.js +22 -22
- package/cron/controllers/utils/cronList.js +1 -1
- package/cron/index.js +10 -10
- package/crud/controllers/deleteCrud.js +9 -4
- package/crud/controllers/insert.js +8 -7
- package/crud/controllers/update.js +13 -10
- package/crud/controllers/utils/xssInjection.js +72 -72
- package/crud/funcs/getAccess.js +12 -24
- package/crud/funcs/getToken.js +27 -27
- package/crud/funcs/isFileExists.js +13 -13
- package/crud/funcs/setToken.js +53 -53
- package/package.json +7 -6
- package/redis/funcs/getRedis.js +23 -23
- package/server/migrations/log.sql +80 -80
- package/table/controllers/data.js +41 -25
- package/table/controllers/table.js +26 -22
- package/table/index.js +3 -50
- package/table/schema.js +54 -0
- package/test/config.example +18 -18
- package/test/funcs/pg.test.js +34 -34
- package/test/funcs/redis.test.js +19 -19
- package/test/templates/cls/test.json +9 -9
- package/test/templates/form/cp_building.form.json +32 -32
- package/test/templates/select/account_id.json +3 -3
- package/test/templates/select/storage.data.json +2 -2
- package/test/templates/table/gis.dataset.table.json +20 -20
- package/util/controllers/next.id.js +4 -4
- package/util/controllers/properties.get.js +19 -19
- package/util/index.js +23 -23
package/.gitlab-ci.yml
ADDED
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
stages:
|
|
2
|
+
- pull
|
|
3
|
+
|
|
4
|
+
latest-253:
|
|
5
|
+
stage: pull
|
|
6
|
+
tags:
|
|
7
|
+
- cdn
|
|
8
|
+
variables:
|
|
9
|
+
GIT_STRATEGY: none
|
|
10
|
+
script:
|
|
11
|
+
- cd /data/softpro/docs/fastify-table && git reset --hard && git pull origin main
|
|
12
|
+
- npm install
|
|
13
|
+
- npm run docs:build
|
|
14
|
+
- rm -rf /data/softpro/apidocs/fastify-table || true
|
|
15
|
+
- mkdir -p /data/softpro/apidocs/fastify-table || true
|
|
16
|
+
- cp -R ./docs/.vitepress/dist/* /data/softpro/apidocs/fastify-table
|
|
17
|
+
only:
|
|
18
|
+
- main
|
package/README.md
CHANGED
|
@@ -1,26 +1,26 @@
|
|
|
1
|
-
# fastify-table
|
|
2
|
-
|
|
3
|
-
[](https://www.npmjs.com/package/@opengis/fastify-table)
|
|
4
|
-
[](http://standardjs.com/)
|
|
5
|
-
|
|
6
|
-
It standardizes the entire form building process, while taking care of everything from rendering to validation and processing:
|
|
7
|
-
|
|
8
|
-
- pg
|
|
9
|
-
- redis
|
|
10
|
-
- crud
|
|
11
|
-
|
|
12
|
-
## Install
|
|
13
|
-
|
|
14
|
-
```bash
|
|
15
|
-
npm i @opengis/fastify-table
|
|
16
|
-
```
|
|
17
|
-
|
|
18
|
-
## Usage
|
|
19
|
-
|
|
20
|
-
```js
|
|
21
|
-
fastify.register(import('@opengis/fastify-table'), config);
|
|
22
|
-
```
|
|
23
|
-
|
|
24
|
-
## Documenation
|
|
25
|
-
|
|
26
|
-
For a detailed understanding fastify-table, its features, and how to use them, refer to our [Documentation](https://apidocs.softpro.ua/gis.storage/).
|
|
1
|
+
# fastify-table
|
|
2
|
+
|
|
3
|
+
[](https://www.npmjs.com/package/@opengis/fastify-table)
|
|
4
|
+
[](http://standardjs.com/)
|
|
5
|
+
|
|
6
|
+
It standardizes the entire form building process, while taking care of everything from rendering to validation and processing:
|
|
7
|
+
|
|
8
|
+
- pg
|
|
9
|
+
- redis
|
|
10
|
+
- crud
|
|
11
|
+
|
|
12
|
+
## Install
|
|
13
|
+
|
|
14
|
+
```bash
|
|
15
|
+
npm i @opengis/fastify-table
|
|
16
|
+
```
|
|
17
|
+
|
|
18
|
+
## Usage
|
|
19
|
+
|
|
20
|
+
```js
|
|
21
|
+
fastify.register(import('@opengis/fastify-table'), config);
|
|
22
|
+
```
|
|
23
|
+
|
|
24
|
+
## Documenation
|
|
25
|
+
|
|
26
|
+
For a detailed understanding fastify-table, its features, and how to use them, refer to our [Documentation](https://apidocs.softpro.ua/gis.storage/).
|
package/config.js
CHANGED
|
@@ -1,10 +1,10 @@
|
|
|
1
|
-
import fs from 'fs';
|
|
2
|
-
|
|
3
|
-
const fileName = ['config.json', '/data/local/config.json'].find(el => (fs.existsSync(el) ? el : null));
|
|
4
|
-
const config = fileName ? JSON.parse(fs.readFileSync(fileName)) : {};
|
|
5
|
-
|
|
6
|
-
Object.assign(config, {
|
|
7
|
-
allTemplates: config?.allTemplates || {},
|
|
8
|
-
});
|
|
9
|
-
|
|
10
|
-
export default config;
|
|
1
|
+
import fs from 'fs';
|
|
2
|
+
|
|
3
|
+
const fileName = ['config.json', '/data/local/config.json'].find(el => (fs.existsSync(el) ? el : null));
|
|
4
|
+
const config = fileName ? JSON.parse(fs.readFileSync(fileName)) : {};
|
|
5
|
+
|
|
6
|
+
Object.assign(config, {
|
|
7
|
+
allTemplates: config?.allTemplates || {},
|
|
8
|
+
});
|
|
9
|
+
|
|
10
|
+
export default config;
|
|
@@ -1,22 +1,22 @@
|
|
|
1
|
-
import cronList from './utils/cronList.js';
|
|
2
|
-
|
|
3
|
-
export default async function cronApi(req) {
|
|
4
|
-
const {
|
|
5
|
-
params = {}, user = {}, hostname,
|
|
6
|
-
} = req;
|
|
7
|
-
|
|
8
|
-
if ((!user.uid || !user.user_type?.includes('admin')) && !hostname?.includes('localhost')) {
|
|
9
|
-
return { message: 'access restricted', status: 403 };
|
|
10
|
-
}
|
|
11
|
-
|
|
12
|
-
if (params.name === 'list') {
|
|
13
|
-
return { data: Object.keys(cronList || {}) };
|
|
14
|
-
}
|
|
15
|
-
|
|
16
|
-
if (!cronList[params.name]) {
|
|
17
|
-
return { message: `cron not found: ${params.name}`, status: 404 };
|
|
18
|
-
}
|
|
19
|
-
|
|
20
|
-
const result = await cronList[params.name](req);
|
|
21
|
-
return result;
|
|
22
|
-
}
|
|
1
|
+
import cronList from './utils/cronList.js';
|
|
2
|
+
|
|
3
|
+
export default async function cronApi(req) {
|
|
4
|
+
const {
|
|
5
|
+
params = {}, user = {}, hostname,
|
|
6
|
+
} = req;
|
|
7
|
+
|
|
8
|
+
if ((!user.uid || !user.user_type?.includes('admin')) && !hostname?.includes('localhost')) {
|
|
9
|
+
return { message: 'access restricted', status: 403 };
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
if (params.name === 'list') {
|
|
13
|
+
return { data: Object.keys(cronList || {}) };
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
if (!cronList[params.name]) {
|
|
17
|
+
return { message: `cron not found: ${params.name}`, status: 404 };
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
const result = await cronList[params.name](req);
|
|
21
|
+
return result;
|
|
22
|
+
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
export default {};
|
|
1
|
+
export default {};
|
package/cron/index.js
CHANGED
|
@@ -1,10 +1,10 @@
|
|
|
1
|
-
import cronApi from './controllers/cronApi.js';
|
|
2
|
-
import addCron from './funcs/addCron.js';
|
|
3
|
-
|
|
4
|
-
async function plugin(fastify, config = {}) {
|
|
5
|
-
const prefix = config.prefix || '/api';
|
|
6
|
-
fastify.decorate('addCron', addCron);
|
|
7
|
-
fastify.get(`${prefix}/cron/:name`, {}, cronApi);
|
|
8
|
-
}
|
|
9
|
-
|
|
10
|
-
export default plugin;
|
|
1
|
+
import cronApi from './controllers/cronApi.js';
|
|
2
|
+
import addCron from './funcs/addCron.js';
|
|
3
|
+
|
|
4
|
+
async function plugin(fastify, config = {}) {
|
|
5
|
+
const prefix = config.prefix || '/api';
|
|
6
|
+
fastify.decorate('addCron', addCron);
|
|
7
|
+
fastify.get(`${prefix}/cron/:name`, {}, cronApi);
|
|
8
|
+
}
|
|
9
|
+
|
|
10
|
+
export default plugin;
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import {
|
|
2
|
-
dataDelete, getTemplate, getAccess, applyHook,
|
|
2
|
+
dataDelete, getTemplate, getAccess, applyHook, getToken, config,
|
|
3
3
|
} from '../../utils.js';
|
|
4
4
|
|
|
5
5
|
export default async function deleteCrud(req) {
|
|
@@ -11,13 +11,18 @@ export default async function deleteCrud(req) {
|
|
|
11
11
|
return { message: hookData?.message, status: hookData?.status };
|
|
12
12
|
}
|
|
13
13
|
|
|
14
|
-
const
|
|
15
|
-
|
|
14
|
+
const tokenData = await getToken({
|
|
15
|
+
uid: user.uid, token: params.table, mode: 'w', json: 1,
|
|
16
|
+
});
|
|
17
|
+
|
|
18
|
+
const { table: del, id } = hookData || tokenData || (config.auth?.disable ? req.params : {});
|
|
19
|
+
const { actions = [] } = await getAccess({ table: del, id, user }) || {};
|
|
16
20
|
|
|
17
|
-
if (!actions.includes('del')
|
|
21
|
+
if (!actions.includes('del')) {
|
|
18
22
|
return { message: 'access restricted', status: 403 };
|
|
19
23
|
}
|
|
20
24
|
const loadTemplate = await getTemplate('table', del);
|
|
25
|
+
|
|
21
26
|
const { table } = loadTemplate || hookData || req.params || {};
|
|
22
27
|
|
|
23
28
|
if (!table) return { status: 404, message: 'table is required' };
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import {
|
|
2
|
-
applyHook, getAccess, getTemplate, checkXSS, dataInsert,
|
|
2
|
+
applyHook, getAccess, getTemplate, checkXSS, dataInsert, getToken, config,
|
|
3
3
|
} from '../../utils.js';
|
|
4
4
|
|
|
5
5
|
export default async function insert(req) {
|
|
@@ -10,21 +10,22 @@ export default async function insert(req) {
|
|
|
10
10
|
if (hookData?.message && hookData?.status) {
|
|
11
11
|
return { message: hookData?.message, status: hookData?.status };
|
|
12
12
|
}
|
|
13
|
+
const tokenData = await getToken({
|
|
14
|
+
uid: user.uid, token: params.table, mode: 'a', json: 1,
|
|
15
|
+
});
|
|
13
16
|
|
|
14
|
-
const { form, table: add } = hookData || req.params
|
|
17
|
+
const { form, table: add } = hookData || tokenData || (config.auth?.disable ? req.params : {});
|
|
15
18
|
|
|
16
19
|
const { actions = [] } = await getAccess({ table: add, user }) || {};
|
|
17
20
|
|
|
18
|
-
if (!actions.includes('
|
|
19
|
-
return { message: 'access restricted', status: 403 };
|
|
20
|
-
}
|
|
21
|
+
if (!actions.includes('add')) return { message: 'access restricted', status: 403 };
|
|
21
22
|
|
|
22
23
|
if (!add) {
|
|
23
24
|
return { message: 'table is required', status: 400 };
|
|
24
25
|
}
|
|
25
26
|
|
|
26
27
|
const loadTemplate = await getTemplate('table', add);
|
|
27
|
-
const { table
|
|
28
|
+
const { table } = loadTemplate || hookData || req.params || {};
|
|
28
29
|
if (!table) {
|
|
29
30
|
return { message: 'table not found', status: 404 };
|
|
30
31
|
}
|
|
@@ -38,7 +39,7 @@ export default async function insert(req) {
|
|
|
38
39
|
return { message: 'Дані містять заборонені символи. Приберіть їх та спробуйте ще раз', status: 409 };
|
|
39
40
|
}
|
|
40
41
|
|
|
41
|
-
const uid =
|
|
42
|
+
const uid = user?.uid;
|
|
42
43
|
if ((add || table) !== 'admin.users') {
|
|
43
44
|
Object.assign(body, { uid, editor_id: uid });
|
|
44
45
|
}
|
|
@@ -1,23 +1,26 @@
|
|
|
1
1
|
import {
|
|
2
|
-
pgClients, applyHook, getAccess, getTemplate, checkXSS, dataInsert, dataUpdate,
|
|
2
|
+
pgClients, applyHook, getAccess, getTemplate, checkXSS, dataInsert, dataUpdate, logger, getToken,
|
|
3
3
|
} from '../../utils.js';
|
|
4
|
+
import config from '../../config.js';
|
|
4
5
|
|
|
5
6
|
export default async function update(req) {
|
|
6
|
-
const {
|
|
7
|
-
user, params = {}, body = {},
|
|
8
|
-
} = req || {};
|
|
7
|
+
const { user, params = {}, body = {} } = req;
|
|
9
8
|
const hookData = await applyHook('preUpdate', {
|
|
10
9
|
table: params?.table, id: params?.id, user,
|
|
11
10
|
});
|
|
11
|
+
|
|
12
12
|
if (hookData?.message && hookData?.status) {
|
|
13
13
|
return { message: hookData?.message, status: hookData?.status };
|
|
14
14
|
}
|
|
15
|
+
const tokenData = await getToken({
|
|
16
|
+
uid: user.uid, token: body.token || params.table, mode: 'w', json: 1,
|
|
17
|
+
});
|
|
15
18
|
|
|
16
|
-
const { form, table: edit, id } = hookData ||
|
|
19
|
+
const { form, table: edit, id } = hookData || tokenData || (config.auth?.disable ? params : {});
|
|
17
20
|
|
|
18
|
-
const { actions = []
|
|
21
|
+
const { actions = [] } = await getAccess({ table: edit, id, user }) || {};
|
|
19
22
|
|
|
20
|
-
if (!actions.includes('edit')
|
|
23
|
+
if (!actions.includes('edit')) {
|
|
21
24
|
return { message: 'access restricted', status: 403 };
|
|
22
25
|
}
|
|
23
26
|
|
|
@@ -30,16 +33,16 @@ export default async function update(req) {
|
|
|
30
33
|
}
|
|
31
34
|
|
|
32
35
|
const loadTemplate = await getTemplate('table', edit);
|
|
33
|
-
const { table
|
|
36
|
+
const { table } = loadTemplate || hookData || params || {};
|
|
34
37
|
|
|
35
|
-
const uid =
|
|
38
|
+
const uid = user?.uid;
|
|
36
39
|
|
|
37
40
|
const formData = form || loadTemplate?.form ? await getTemplate('form', form || loadTemplate?.form) : {};
|
|
38
41
|
|
|
39
42
|
const xssCheck = checkXSS({ body, schema: formData?.schema || formData });
|
|
40
43
|
|
|
41
44
|
if (xssCheck.error && formData?.xssCheck !== false) {
|
|
42
|
-
|
|
45
|
+
logger.warn({ name: 'injection/xss', msg: xssCheck.error, table }, req);
|
|
43
46
|
return { message: 'Дані містять заборонені символи. Приберіть їх та спробуйте ще раз', status: 409 };
|
|
44
47
|
}
|
|
45
48
|
|
|
@@ -1,72 +1,72 @@
|
|
|
1
|
-
const xssInjection = [
|
|
2
|
-
'onkeypress=',
|
|
3
|
-
'onkeyup=',
|
|
4
|
-
'ondblclick=',
|
|
5
|
-
'onerror=',
|
|
6
|
-
'onmouseover=',
|
|
7
|
-
'<meta',
|
|
8
|
-
'<script',
|
|
9
|
-
'vascript:',
|
|
10
|
-
'onkeydown=',
|
|
11
|
-
'onmousedown=',
|
|
12
|
-
'onmouseenter=',
|
|
13
|
-
'onmouseleave=',
|
|
14
|
-
'onmousemove=',
|
|
15
|
-
'onmouseout=',
|
|
16
|
-
'onmouseup=',
|
|
17
|
-
'onmousewheel=',
|
|
18
|
-
'onpaste=',
|
|
19
|
-
'onscroll=',
|
|
20
|
-
'onwheel=',
|
|
21
|
-
'javascript:',
|
|
22
|
-
'\\x',
|
|
23
|
-
'eval(',
|
|
24
|
-
'onmouseover=',
|
|
25
|
-
'action=',
|
|
26
|
-
'xlink:',
|
|
27
|
-
'allowscriptaccess',
|
|
28
|
-
'href=',
|
|
29
|
-
'behavior:',
|
|
30
|
-
'onreadystatechange=',
|
|
31
|
-
'onstart=',
|
|
32
|
-
'offline=',
|
|
33
|
-
'onabort=',
|
|
34
|
-
'onafterprint=',
|
|
35
|
-
'onbeforeonload=',
|
|
36
|
-
'onbeforeprint=',
|
|
37
|
-
'onblur=',
|
|
38
|
-
'oncanplay=',
|
|
39
|
-
'oncanplaythrough=',
|
|
40
|
-
'onchange=',
|
|
41
|
-
'onclick=',
|
|
42
|
-
'oncontextmenu=',
|
|
43
|
-
'ondblclick=',
|
|
44
|
-
'ondrag=',
|
|
45
|
-
'ondragend=',
|
|
46
|
-
'ondragenter=',
|
|
47
|
-
'ondragleave=',
|
|
48
|
-
'ondragover=',
|
|
49
|
-
'ondragstart=',
|
|
50
|
-
'ondrop=',
|
|
51
|
-
'ondurationchange=',
|
|
52
|
-
'onemptied=',
|
|
53
|
-
'onended=',
|
|
54
|
-
'onerror=',
|
|
55
|
-
'onfocus=',
|
|
56
|
-
'onformchange=',
|
|
57
|
-
'onforminput=',
|
|
58
|
-
'onhaschange=',
|
|
59
|
-
'oninput=',
|
|
60
|
-
'oninvalid=',
|
|
61
|
-
'onkeydown=',
|
|
62
|
-
'onkeypress=',
|
|
63
|
-
'onkeyup=',
|
|
64
|
-
'onload=',
|
|
65
|
-
'onloadeddata=',
|
|
66
|
-
'onloadedmetadata=',
|
|
67
|
-
'onloadstart=',
|
|
68
|
-
'alert(',
|
|
69
|
-
'script:',
|
|
70
|
-
];
|
|
71
|
-
|
|
72
|
-
export default xssInjection;
|
|
1
|
+
const xssInjection = [
|
|
2
|
+
'onkeypress=',
|
|
3
|
+
'onkeyup=',
|
|
4
|
+
'ondblclick=',
|
|
5
|
+
'onerror=',
|
|
6
|
+
'onmouseover=',
|
|
7
|
+
'<meta',
|
|
8
|
+
'<script',
|
|
9
|
+
'vascript:',
|
|
10
|
+
'onkeydown=',
|
|
11
|
+
'onmousedown=',
|
|
12
|
+
'onmouseenter=',
|
|
13
|
+
'onmouseleave=',
|
|
14
|
+
'onmousemove=',
|
|
15
|
+
'onmouseout=',
|
|
16
|
+
'onmouseup=',
|
|
17
|
+
'onmousewheel=',
|
|
18
|
+
'onpaste=',
|
|
19
|
+
'onscroll=',
|
|
20
|
+
'onwheel=',
|
|
21
|
+
'javascript:',
|
|
22
|
+
'\\x',
|
|
23
|
+
'eval(',
|
|
24
|
+
'onmouseover=',
|
|
25
|
+
'action=',
|
|
26
|
+
'xlink:',
|
|
27
|
+
'allowscriptaccess',
|
|
28
|
+
'href=',
|
|
29
|
+
'behavior:',
|
|
30
|
+
'onreadystatechange=',
|
|
31
|
+
'onstart=',
|
|
32
|
+
'offline=',
|
|
33
|
+
'onabort=',
|
|
34
|
+
'onafterprint=',
|
|
35
|
+
'onbeforeonload=',
|
|
36
|
+
'onbeforeprint=',
|
|
37
|
+
'onblur=',
|
|
38
|
+
'oncanplay=',
|
|
39
|
+
'oncanplaythrough=',
|
|
40
|
+
'onchange=',
|
|
41
|
+
'onclick=',
|
|
42
|
+
'oncontextmenu=',
|
|
43
|
+
'ondblclick=',
|
|
44
|
+
'ondrag=',
|
|
45
|
+
'ondragend=',
|
|
46
|
+
'ondragenter=',
|
|
47
|
+
'ondragleave=',
|
|
48
|
+
'ondragover=',
|
|
49
|
+
'ondragstart=',
|
|
50
|
+
'ondrop=',
|
|
51
|
+
'ondurationchange=',
|
|
52
|
+
'onemptied=',
|
|
53
|
+
'onended=',
|
|
54
|
+
'onerror=',
|
|
55
|
+
'onfocus=',
|
|
56
|
+
'onformchange=',
|
|
57
|
+
'onforminput=',
|
|
58
|
+
'onhaschange=',
|
|
59
|
+
'oninput=',
|
|
60
|
+
'oninvalid=',
|
|
61
|
+
'onkeydown=',
|
|
62
|
+
'onkeypress=',
|
|
63
|
+
'onkeyup=',
|
|
64
|
+
'onload=',
|
|
65
|
+
'onloadeddata=',
|
|
66
|
+
'onloadedmetadata=',
|
|
67
|
+
'onloadstart=',
|
|
68
|
+
'alert(',
|
|
69
|
+
'script:',
|
|
70
|
+
];
|
|
71
|
+
|
|
72
|
+
export default xssInjection;
|
package/crud/funcs/getAccess.js
CHANGED
|
@@ -1,7 +1,8 @@
|
|
|
1
|
-
import getMeta from '../../pg/funcs/getMeta.js';
|
|
1
|
+
// import getMeta from '../../pg/funcs/getMeta.js';
|
|
2
2
|
import getTemplate from '../../table/controllers/utils/getTemplate.js';
|
|
3
3
|
import config from '../../config.js';
|
|
4
4
|
import pgClients from '../../pg/pgClients.js';
|
|
5
|
+
import applyHook from '../../hook/funcs/applyHook.js';
|
|
5
6
|
|
|
6
7
|
const q = `select a.route_id as id, coalesce(b.actions,array['get']) as actions, b.scope
|
|
7
8
|
from admin.routes a
|
|
@@ -19,38 +20,25 @@ left join admin.user_roles d on
|
|
|
19
20
|
end )
|
|
20
21
|
where $1 in (a.route_id, a.alias) and $2 in (b.user_uid, d.user_uid)`;
|
|
21
22
|
|
|
22
|
-
export default async function getAccess({ table,
|
|
23
|
-
|
|
24
|
-
const { uid, user_type: userType } = user || {};
|
|
23
|
+
export default async function getAccess({ table, user = {} }) {
|
|
24
|
+
if (!table) return null;
|
|
25
25
|
|
|
26
|
-
|
|
26
|
+
const hookData = await applyHook('getAccess', { table, user });
|
|
27
|
+
if (hookData) return hookData;
|
|
27
28
|
|
|
29
|
+
const { uid } = user;
|
|
28
30
|
const body = await getTemplate('table', table) || {};
|
|
29
31
|
|
|
30
|
-
|
|
31
|
-
|
|
32
|
+
// console.log(user?.type);
|
|
33
|
+
if (config.auth?.disable || user?.type === 'admin' || body?.public || body.access === 'public' || (body.access === 'user' && user.uid)) {
|
|
34
|
+
return { actions: ['get'].concat(user.uid ? body.actions || body.action_default || [] : []), query: '1=1' };
|
|
32
35
|
}
|
|
33
36
|
|
|
34
37
|
if (!uid || !body?.table) return null;
|
|
35
38
|
|
|
36
|
-
const { scope
|
|
37
|
-
|
|
38
|
-
const { columns = [] } = await getMeta({ table: body?.table });
|
|
39
|
-
|
|
40
|
-
const query = userType?.includes('admin') ? '1=1' : {
|
|
41
|
-
my: `uid='${uid}'`,
|
|
42
|
-
responsible: columns.map((el) => el?.name || el).includes('responsible_id')
|
|
43
|
-
? `responsible_id='${uid}'`
|
|
44
|
-
: `uid='${uid}'`,
|
|
45
|
-
all: '1=1',
|
|
46
|
-
}[scope];
|
|
47
|
-
|
|
48
|
-
const { my } = pg.pk?.[body?.table] && id
|
|
49
|
-
? await pg.query(`select uid=$1 as my from ${body?.table} where ${pg.pk?.[body?.table]}=$2`, [uid, id])
|
|
50
|
-
.then((res) => res.rows?.[0] || {})
|
|
51
|
-
: {};
|
|
39
|
+
const { scope, actions = [] } = await pgClients.client.query(q, [table, uid]).then((res) => res.rows?.[0] || {});
|
|
52
40
|
|
|
53
41
|
return {
|
|
54
|
-
scope, actions, query
|
|
42
|
+
scope, actions, query: scope === 'my' ? `uid='${uid}` : null,
|
|
55
43
|
};
|
|
56
44
|
}
|
package/crud/funcs/getToken.js
CHANGED
|
@@ -1,27 +1,27 @@
|
|
|
1
|
-
import getRedis from '../../redis/funcs/getRedis.js';
|
|
2
|
-
import config from '../../config.js';
|
|
3
|
-
|
|
4
|
-
function sprintf(str, ...args) {
|
|
5
|
-
return str.replace(/%s/g, () => args.shift());
|
|
6
|
-
}
|
|
7
|
-
|
|
8
|
-
const keys = {
|
|
9
|
-
r: '%s:token:view:%s',
|
|
10
|
-
a: '%s:token:add:%s',
|
|
11
|
-
w: '%s:token:edit:%s',
|
|
12
|
-
e: '%s:token:exec:%s',
|
|
13
|
-
};
|
|
14
|
-
|
|
15
|
-
async function getToken({
|
|
16
|
-
uid, token, mode = 'r', json,
|
|
17
|
-
}) {
|
|
18
|
-
if (mode === 'r') return token;
|
|
19
|
-
|
|
20
|
-
const rclient = getRedis({ db: 0 });
|
|
21
|
-
|
|
22
|
-
const key = sprintf(keys[mode], config?.pg?.database, uid?.toString());
|
|
23
|
-
const id = await rclient.hget(key, token);
|
|
24
|
-
return json && id?.[0] === '{' ? JSON.parse(id) : id;
|
|
25
|
-
}
|
|
26
|
-
|
|
27
|
-
export default getToken;
|
|
1
|
+
import getRedis from '../../redis/funcs/getRedis.js';
|
|
2
|
+
import config from '../../config.js';
|
|
3
|
+
|
|
4
|
+
function sprintf(str, ...args) {
|
|
5
|
+
return str.replace(/%s/g, () => args.shift());
|
|
6
|
+
}
|
|
7
|
+
|
|
8
|
+
const keys = {
|
|
9
|
+
r: '%s:token:view:%s',
|
|
10
|
+
a: '%s:token:add:%s',
|
|
11
|
+
w: '%s:token:edit:%s',
|
|
12
|
+
e: '%s:token:exec:%s',
|
|
13
|
+
};
|
|
14
|
+
|
|
15
|
+
async function getToken({
|
|
16
|
+
uid, token, mode = 'r', json,
|
|
17
|
+
}) {
|
|
18
|
+
if (mode === 'r') return token;
|
|
19
|
+
|
|
20
|
+
const rclient = getRedis({ db: 0 });
|
|
21
|
+
|
|
22
|
+
const key = sprintf(keys[mode], config?.pg?.database, uid?.toString());
|
|
23
|
+
const id = await rclient.hget(key, token);
|
|
24
|
+
return json && id?.[0] === '{' ? JSON.parse(id) : id;
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
export default getToken;
|
|
@@ -1,13 +1,13 @@
|
|
|
1
|
-
import { access } from 'fs/promises';
|
|
2
|
-
|
|
3
|
-
const isFileExists = async (filepath) => {
|
|
4
|
-
try {
|
|
5
|
-
await access(filepath);
|
|
6
|
-
return true;
|
|
7
|
-
}
|
|
8
|
-
catch (err) {
|
|
9
|
-
return false;
|
|
10
|
-
}
|
|
11
|
-
};
|
|
12
|
-
|
|
13
|
-
export default isFileExists;
|
|
1
|
+
import { access } from 'fs/promises';
|
|
2
|
+
|
|
3
|
+
const isFileExists = async (filepath) => {
|
|
4
|
+
try {
|
|
5
|
+
await access(filepath);
|
|
6
|
+
return true;
|
|
7
|
+
}
|
|
8
|
+
catch (err) {
|
|
9
|
+
return false;
|
|
10
|
+
}
|
|
11
|
+
};
|
|
12
|
+
|
|
13
|
+
export default isFileExists;
|