@opengis/fastify-table 1.1.61 → 1.1.63

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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@opengis/fastify-table",
3
- "version": "1.1.61",
3
+ "version": "1.1.63",
4
4
  "type": "module",
5
5
  "description": "core-plugins",
6
6
  "main": "index.js",
@@ -2,10 +2,11 @@ import getRedis from '../../redis/funcs/getRedis.js';
2
2
 
3
3
  // import { getRedis } from '../../../../utils.js';
4
4
 
5
- export default async function getOpt(token, funcs) {
6
- const rclient = getRedis({ db: 0, funcs });
5
+ export default async function getOpt(token, uid = 0) {
6
+ const rclient = getRedis({ db: 0 });
7
7
 
8
- const key = `opt:${token}`;
8
+ const key = `opt:${uid}:${token}`;
9
+ // console.log(key);
9
10
  const data = await rclient.get(key);
10
11
  if (!data) return null;
11
12
  return JSON.parse(data);
@@ -16,14 +16,16 @@ const keys = {
16
16
  };
17
17
 
18
18
  async function getToken({
19
- uid, token, mode = 'r', json,
19
+ uid, token, json,
20
20
  }) {
21
- if (mode === 'r') return token;
21
+ const mode = 'w';
22
+ // if (mode === 'r') return token;
22
23
 
23
24
  const rclient = getRedis({ db: 0 });
24
25
 
25
26
  const key = sprintf(keys[mode], config?.pg?.database, uid?.toString());
26
27
  const id = await rclient.hget(key, token);
28
+ // console.log(key, token);
27
29
  return json && id?.[0] === '{' ? JSON.parse(id) : id;
28
30
  }
29
31
 
@@ -1,4 +1,6 @@
1
- import { createHash } from 'crypto';
1
+ import { createHash, randomUUID } from 'crypto';
2
+
3
+ const random = randomUUID();
2
4
 
3
5
  import getRedis from '../../redis/funcs/getRedis.js';
4
6
 
@@ -8,12 +10,12 @@ function md5(string) {
8
10
  return createHash('md5').update(string).digest('hex');
9
11
  }
10
12
 
11
- export default async function setOpt(params) {
12
- const token = Buffer.from(md5(typeof params === 'object' ? JSON.stringify(params) : params), 'hex').toString('base64').replace(/[+-=]+/g, '');
13
+ export default function setOpt(params, uid = 0) {
14
+ const token = Buffer.from(md5(typeof params === 'object' ? JSON.stringify(params) : params) + random, 'hex').toString('base64').replace(/[+-=]+/g, '');
13
15
  // const token = md5(params);
14
- const key = `opt:${token}`;
16
+ const key = `opt:${uid}:${token}`;
15
17
 
16
- const rclient = getRedis({ db: 0, funcs: params.funcs });
17
- await rclient.set(key, JSON.stringify(params), 'EX', 60 * 60);
18
+ const rclient = getRedis({ db: 0 });
19
+ rclient.set(key, JSON.stringify(params), 'EX', 60 * 60);
18
20
  return token;
19
21
  }
@@ -4,6 +4,8 @@ import config from '../../../../config.js';
4
4
 
5
5
  import getRedis from '../../redis/funcs/getRedis.js';
6
6
 
7
+ const rclient = getRedis({ db: 0 });
8
+
7
9
  // import { config, getRedis } from '../../../../utils.js';
8
10
 
9
11
  const generateCodes = (ids, userToken) => {
@@ -19,36 +21,22 @@ const generateCodes = (ids, userToken) => {
19
21
  };
20
22
 
21
23
  function setToken({
22
- ids: idsOrigin, mode = 'r', uid, array,
24
+ ids: idsOrigin, uid, array,
23
25
  }) {
24
- const rclient2 = getRedis({ db: 0 });
25
26
  // const rclient5 = getRedis({ db: 0, funcs });
26
27
 
27
28
  if (!uid) return { user: 'empty' };
28
29
  if (!Object.keys(idsOrigin).length) return { ids: 'empty' };
29
30
 
30
31
  const ids = idsOrigin.map((el) => (typeof el === 'object' ? JSON.stringify(el) : el));
31
- // update/delete
32
-
33
- if (mode === 'r') return null;
34
32
 
35
33
  // TODO generate salt
36
34
  const { codes, obj } = generateCodes(ids, uid);
37
35
 
38
36
  if (!Object.keys(codes).length) return { ids: 'empty' };
39
37
 
40
- rclient2.hmset(`${config.pg.database}:token:${{
41
- e: 'exec', r: 'view', w: 'edit', a: 'add',
42
- }[mode]}:${uid}`, codes);
43
- // console.log(codes);
44
- // log token for debug. add extra data - uid, mode, date
45
- /* const dt = new Date().toISOString();
46
- const codesLog = Object.keys(codes).reduce((acc, key) => {
47
- acc[key] = `{"referer": "${referer}" ,"uid":"${uid}","mode":"${mode}","date":"${dt}",${codes[key].substr(1)}`;
48
- return acc;
49
- }, {});
50
- rclient5.hmset(`${config.pg.database}:token:edit`, codesLog); // 'EX', 64800 */
51
-
38
+ rclient.hmset(`${config.pg.database}:token:edit:${uid}`, codes);
39
+ // console.log(`${config.pg.database}:token:edit:${uid}`, idsOrigin, Object.values(obj));
52
40
  // TODO дополнительно писать в hset token -> uid
53
41
  return array ? Object.values(obj) : obj;
54
42
  }
@@ -6,6 +6,7 @@ export default async function insert(req) {
6
6
  const {
7
7
  user, params = {}, body = {},
8
8
  } = req || {};
9
+ if (!user) return { message: 'access restricted', status: 403 };
9
10
  const hookData = await applyHook('preInsert', { table: params?.table, user });
10
11
  if (hookData?.message && hookData?.status) {
11
12
  return { message: hookData?.message, status: hookData?.status };
@@ -1,31 +1,40 @@
1
1
  import {
2
- config, getAccess, getTemplate, getMeta, setToken, applyHook,
2
+ config, getAccess, getTemplate, getMeta, setToken, applyHook, getToken,
3
3
  } from '../../../../utils.js';
4
4
 
5
5
  export default async function tableAPI(req) {
6
6
  const {
7
- pg, params, user, query = {},
7
+ pg, params, user = {}, query = {},
8
8
  } = req;
9
+ const tokenData = await getToken({ token: params?.table, uid: user.uid, json: 1 }) || {};
10
+
9
11
  const hookData = await applyHook('preTable', {
10
- table: params?.table, id: params?.id, user,
12
+ table: params?.table, id: params?.id, ...tokenData || {}, user,
11
13
  });
12
14
 
13
15
  if (hookData?.message && hookData?.status) {
14
16
  return { message: hookData?.message, status: hookData?.status };
15
17
  }
18
+ const tableName1 = hookData?.table || tokenData.table || params.table;
16
19
 
17
- if (!params?.id && !hookData?.id) {
18
- return { message: 'not enough params', status: 400 };
19
- }
20
- const tableName = hookData?.table || params.table;
21
- const loadTable = await getTemplate('table', tableName) || {};
22
- if (!loadTable || (pg.pk?.[tableName])) {
20
+ const loadTable = await getTemplate('table', tableName1) || {};
21
+ if (!loadTable && !pg.pk?.[tokenData.table]) {
23
22
  return { message: 'not found', status: 404 };
24
23
  }
25
24
 
25
+ const { table, /* columns, */ form } = loadTable;
26
+
27
+ const tableName = table || hookData?.table || tokenData.table || params.table;
28
+
29
+ const id = hookData?.id || tokenData.id || params.id;
30
+
31
+ if (!tableName && !id) {
32
+ return { message: 'not enough params', status: 400 };
33
+ }
34
+
26
35
  const { actions = [], query: accessQuery } = await getAccess({
27
- table: hookData?.table || params.table,
28
- id: hookData?.id || params?.id,
36
+ table: tableName,
37
+ id,
29
38
  user,
30
39
  }) || {};
31
40
 
@@ -33,9 +42,7 @@ export default async function tableAPI(req) {
33
42
  return { message: 'access restricted', status: 403 };
34
43
  }
35
44
 
36
- const { table, /* columns, */ form } = loadTable;
37
-
38
- const { pk, columns: dbColumns = [] } = await getMeta(table || hookData?.table || params.table);
45
+ const { pk, columns: dbColumns = [] } = await getMeta(tableName);
39
46
  if (!pk) return { message: `table not found: ${table}`, status: 404 };
40
47
 
41
48
  // const cols = columns.map((el) => el.name || el).join(',');
@@ -45,17 +52,17 @@ export default async function tableAPI(req) {
45
52
  // skip non-existing columns
46
53
  const columnList = dbColumns.map((el) => el.name || el).join(',');
47
54
 
48
- const { fields = [] } = !loadTable?.table ? await pg.query(`select * from ${table || hookData?.table || params.table} limit 0`) : {};
55
+ const { fields = [] } = !loadTable?.table ? await pg.query(`select * from ${tableName} limit 0`) : {};
49
56
  const cols = loadTable?.table
50
57
  ? Object.keys(schema || {}).filter((col) => columnList.includes(col) && !extraKeys.includes(col))?.map((col) => (col?.includes('geom') ? `st_asgeojson(${col})::json as "${col}"` : `"${col}"`))?.join(',')
51
58
  : fields.map((el) => (el?.name?.includes('geom') ? `st_asgeojson(${el.name})::json as "${el.name}"` : `"${el?.name}"`)).join(',');
52
59
  const where = [`"${pk}" = $1`, loadTable.query, accessQuery].filter((el) => el);
53
60
  const geom = columnList.includes('geom') ? ',st_asgeojson(geom)::json as geom' : '';
54
- const q = `select "${pk}" as id, ${cols || '*'} ${geom} from ${table || hookData?.table || params.table} t where ${where.join(' and ') || 'true'} limit 1`;
61
+ const q = `select "${pk}" as id, ${cols || '*'} ${geom} from ${tableName} t where ${where.join(' and ') || 'true'} limit 1`;
55
62
 
56
63
  if (query?.sql === '1') return q;
57
64
 
58
- const data = await pg.query(q, [hookData?.id || params.id]).then(el => el.rows[0]);
65
+ const data = await pg.query(q, [id]).then(el => el.rows[0]);
59
66
  if (!data) return { message: 'not found', status: 404 };
60
67
 
61
68
  if (extraKeys?.length) {
@@ -66,16 +73,14 @@ export default async function tableAPI(req) {
66
73
  }));
67
74
  }
68
75
  if (user.uid) {
69
- const [token] = setToken({
70
- ids: [JSON.stringify({ id: params?.id, table: params.table || loadTable.table, form: loadTable.form })],
71
- mode: 'w',
76
+ data.token = tokenData?.table ? params.table : setToken({
77
+ ids: [JSON.stringify({ id, table: tableName, form: loadTable.form })],
72
78
  uid: user.uid,
73
79
  array: 1,
74
- });
75
- data.token = token;
80
+ })[0];
76
81
  }
77
82
  const res = await applyHook('afterTable', {
78
- table: loadTable?.table, payload: [data], user,
83
+ table: tableName, payload: [data], user,
79
84
  });
80
85
  return res || data || {};
81
86
  }
@@ -5,6 +5,7 @@ import config from '../../../../config.js';
5
5
 
6
6
  export default async function update(req) {
7
7
  const { user, params = {}, body = {} } = req;
8
+ if (!user) return { message: 'access restricted', status: 403 };
8
9
  const hookData = await applyHook('preUpdate', {
9
10
  table: params?.table, id: params?.id, user,
10
11
  });
@@ -33,7 +34,7 @@ export default async function update(req) {
33
34
  }
34
35
 
35
36
  const loadTemplate = await getTemplate('table', edit);
36
- const { table } = loadTemplate || hookData || params || {};
37
+ const { table } = loadTemplate || hookData || tokenData || params || {};
37
38
 
38
39
  const uid = user?.uid;
39
40
 
@@ -56,7 +57,7 @@ export default async function update(req) {
56
57
  });
57
58
 
58
59
  // form DataTable
59
- const extraKeys = Object.keys(formData)?.filter((key) => formData?.[key]?.type === 'DataTable' && formData?.[key]?.table && formData?.[key]?.parent_id && body[key].length);
60
+ const extraKeys = formData ? Object.keys(formData)?.filter((key) => formData?.[key]?.type === 'DataTable' && formData?.[key]?.table && formData?.[key]?.parent_id && body[key].length) : [];
60
61
  if (extraKeys?.length) {
61
62
  res.extra = {};
62
63
  await Promise.all(extraKeys?.map(async (key) => {
@@ -1,6 +1,7 @@
1
1
  import update from './controllers/update.js';
2
2
  import insert from './controllers/insert.js';
3
3
  import deleteCrud from './controllers/deleteCrud.js';
4
+ import table from './controllers/table.js';
4
5
 
5
6
  const tableSchema = {
6
7
  params: {
@@ -14,6 +15,7 @@ async function plugin(fastify, config = {}) {
14
15
  fastify.put(`${prefix}/table/:table/:id?`, { schema: tableSchema }, update);
15
16
  fastify.delete(`${prefix}/table/:table/:id?`, { schema: tableSchema }, deleteCrud);
16
17
  fastify.post(`${prefix}/table/:table?`, { schema: tableSchema }, insert);
18
+ fastify.get(`${prefix}/table/:table/:id?`, { schema: tableSchema }, table);
17
19
  }
18
20
 
19
21
  export default plugin;
@@ -128,21 +128,10 @@ export default async function dataAPI(req) {
128
128
  if (user.uid && actions.includes('add')) {
129
129
  const addTokens = setToken({
130
130
  ids: [JSON.stringify({ table: hookData?.table || params.table, form: loadTable.form })],
131
- mode: 'a',
132
131
  uid,
133
132
  array: 1,
134
133
  });
135
134
  Object.assign(res, { addToken: addTokens[0] });
136
-
137
- /* rows.forEach((row) => {
138
- const editTokens = setToken({
139
- ids: [JSON.stringify({ id: row.id, table: loadTable.table, form: loadTable.form })],
140
- mode: 'w',
141
- uid: config?.auth?.disable ? '1' : uid,
142
- array: 1,
143
- });
144
- Object.assign(row, { token: editTokens[0] });
145
- }); */
146
135
  }
147
136
 
148
137
  const result = await applyHook('afterData', {
@@ -1,6 +1,6 @@
1
1
  import suggest from './controllers/suggest.js';
2
2
  import data from './controllers/data.js';
3
- import table from './controllers/table.js';
3
+
4
4
  import card from './controllers/card.js';
5
5
  import search from './controllers/search.js';
6
6
  import filter from './controllers/filter.js';
@@ -16,7 +16,7 @@ async function plugin(fastify, config = {}) {
16
16
  const prefix = config.prefix || '/api';
17
17
  fastify.get(`${prefix}/suggest/:data`, { schema: suggestSchema }, suggest);
18
18
  fastify.get(`${prefix}/data/:table/:id?`, { schema: tableSchema }, data); // vs.crm.data.api с node
19
- fastify.get(`${prefix}/table/:table/:id?`, { schema: tableSchema }, table);
19
+
20
20
  fastify.get(`${prefix}/card/:table/:id`, { schema: tableSchema }, card);
21
21
  fastify.get(`${prefix}/search`, { schema: searchSchema }, search);
22
22