@opengis/fastify-table 2.0.43 → 2.0.45

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.
@@ -6,6 +6,7 @@ ALTER TABLE admin.users add column if not exists uid text NOT NULL DEFAULT next_
6
6
  ALTER TABLE admin.users DROP CONSTRAINT if exists admin_user_uid_pkey cascade;
7
7
  ALTER TABLE admin.users DROP CONSTRAINT if exists user_pk cascade;
8
8
  ALTER TABLE admin.users DROP CONSTRAINT if exists admin_user_user_rnokpp;
9
+ ALTER TABLE admin.users DROP CONSTRAINT if exists admin_user_type_check;
9
10
 
10
11
  ALTER TABLE admin.users add column if not exists login text;
11
12
  ALTER TABLE admin.users add column if not exists password text NOT NULL DEFAULT ''::text;
@@ -32,6 +33,11 @@ ALTER TABLE admin.users add column if not exists twofa boolean not null DEFAULT
32
33
  ALTER TABLE admin.users add CONSTRAINT admin_user_uid_pkey PRIMARY KEY (uid);
33
34
  ALTER TABLE admin.users add CONSTRAINT admin_user_user_rnokpp UNIQUE (user_rnokpp);
34
35
 
36
+ update admin.users set user_type='regular' where user_type not in ('viewer', 'regular','admin','superadmin');
37
+ ALTER TABLE admin.users add constraint admin_user_type_check CHECK (user_type=any(array['viewer', 'regular','admin','superadmin']));
38
+ insert into admin.users (uid,login,password,user_type,enabled)values('viewer','viewer','viewer','viewer', false) on conflict (uid) do update set enabled=excluded.enabled;
39
+ -- update admin.users set enabled=true where uid='viewer';
40
+
35
41
  COMMENT ON TABLE admin.users IS 'Користувачі';
36
42
 
37
43
  COMMENT ON COLUMN admin.users.uid IS 'ID користувача';
@@ -1 +1 @@
1
- {"version":3,"file":"getAccess.d.ts","sourceRoot":"","sources":["../../../../../server/plugins/crud/funcs/getAccess.ts"],"names":[],"mappings":"AAsBA;;;;;;;;;GASG;AAEH,wBAA8B,SAAS,CACrC,EAAE,KAAK,EAAE,IAAI,EAAE,IAAS,EAAE,EAAE,GAAG,EAC/B,EAAE,MAAmB,sBAmEtB"}
1
+ {"version":3,"file":"getAccess.d.ts","sourceRoot":"","sources":["../../../../../server/plugins/crud/funcs/getAccess.ts"],"names":[],"mappings":"AAsBA;;;;;;;;;GASG;AAEH,wBAA8B,SAAS,CACrC,EAAE,KAAK,EAAE,IAAI,EAAE,IAAS,EAAE,EAAE,GAAG,EAC/B,EAAE,MAAmB,sBAuEtB"}
@@ -37,6 +37,9 @@ export default async function getAccess({ table, form, user = {} }, pg = pgClien
37
37
  if (userType === "superadmin") {
38
38
  return { actions: allActions, query: "1=1" };
39
39
  }
40
+ if (userType === "viewer") {
41
+ return { actions: ["view"], query: "1=1" };
42
+ }
40
43
  const body = await getTemplate("table", table);
41
44
  const tableActions = !body && form
42
45
  ? allActions // if db table and form => full access (token)
@@ -1 +1 @@
1
- {"version":3,"file":"checkPolicy.d.ts","sourceRoot":"","sources":["../../../../../server/plugins/policy/funcs/checkPolicy.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,SAAS,CAAC;AAE5C,OAAO,KAAK,EAEV,eAAe,EAEhB,MAAM,wBAAwB,CAAC;AAKhC,MAAM,CAAC,OAAO,UAAU,WAAW,CAAC,GAAG,EAAE,eAAe,EAAE,KAAK,EAAE,YAAY,oSAiK5E"}
1
+ {"version":3,"file":"checkPolicy.d.ts","sourceRoot":"","sources":["../../../../../server/plugins/policy/funcs/checkPolicy.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,SAAS,CAAC;AAE5C,OAAO,KAAK,EAEV,eAAe,EAEhB,MAAM,wBAAwB,CAAC;AAKhC,MAAM,CAAC,OAAO,UAAU,WAAW,CAAC,GAAG,EAAE,eAAe,EAAE,KAAK,EAAE,YAAY,oSA6K5E"}
@@ -3,8 +3,10 @@ import block from "../sqlInjection.js";
3
3
  export default function checkPolicy(req, reply) {
4
4
  const { originalUrl: path, hostname, query, params, headers, method, routeOptions, unittest, // legacy
5
5
  } = req;
6
+ const user = req.user || req.session?.passport?.user;
6
7
  // ! skip locally, skip tests
7
- if (config.local || unittest || process.env.NODE_ENV === "test") {
8
+ if ((config.local || unittest || process.env.NODE_ENV === "test") &&
9
+ user?.user_type !== "viewer") {
8
10
  return null;
9
11
  }
10
12
  // ! skip non-API Requests
@@ -19,8 +21,6 @@ export default function checkPolicy(req, reply) {
19
21
  hostname.split(":").shift() === config.adminDomain ||
20
22
  config.admin ||
21
23
  hostname.startsWith("admin");
22
- const user = req.user || req.session?.passport?.user;
23
- // const isServer = process.argv[2];
24
24
  const { role, referer, policy = [], } = (routeOptions?.config || {});
25
25
  const isRole = (role && user?.user_type !== role) ||
26
26
  (policy.includes("admin") && user?.user_type !== "admin");
@@ -35,9 +35,19 @@ export default function checkPolicy(req, reply) {
35
35
  const requireReferer = Array.isArray(policy)
36
36
  ? policy.includes("referer")
37
37
  : referer;
38
+ if (method !== "GET" && user?.user_type === "viewer") {
39
+ logger.file("policy/role", {
40
+ path,
41
+ method,
42
+ userRole: user.user_type,
43
+ });
44
+ return reply.status(403).send("access restricted: 0");
45
+ }
38
46
  // ! role
39
47
  if (isRole) {
40
48
  logger.file("policy/role", {
49
+ role,
50
+ userRole: user?.user_type || "none",
41
51
  path,
42
52
  method,
43
53
  params,
@@ -1 +1 @@
1
- {"version":3,"file":"formatValue.d.ts","sourceRoot":"","sources":["../../../../../../../server/plugins/table/funcs/getFilterSQL/util/formatValue.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,8BAA8B,CAAC;AAK/D,MAAM,CAAC,OAAO,UAAU,WAAW,CAAC,EAClC,EAAE,EACF,KAAK,EACL,MAAW,EACX,IAAI,EACJ,KAAK,EACL,UAAU,EACV,GAAO,EACP,QAAQ,GACT,EAAE;IACD,EAAE,EAAE,UAAU,CAAC;IACf,KAAK,EAAE,MAAM,CAAC;IACd,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,CAAC;IAC5B,IAAI,EAAE,MAAM,GAAG,SAAS,CAAC;IACzB,KAAK,EAAE,MAAM,CAAC;IACd,UAAU,EAAE,MAAM,CAAC;IACnB,GAAG,CAAC,EAAE,MAAM,GAAG,MAAM,CAAC;IACtB,QAAQ,CAAC,EAAE,GAAG,CAAC;CAChB,OAyLA"}
1
+ {"version":3,"file":"formatValue.d.ts","sourceRoot":"","sources":["../../../../../../../server/plugins/table/funcs/getFilterSQL/util/formatValue.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,8BAA8B,CAAC;AAe/D,MAAM,CAAC,OAAO,UAAU,WAAW,CAAC,EAClC,EAAE,EACF,KAAK,EACL,MAAW,EACX,IAAI,EACJ,KAAK,EACL,UAAU,EACV,GAAO,EACP,QAAQ,GACT,EAAE;IACD,EAAE,EAAE,UAAU,CAAC;IACf,KAAK,EAAE,MAAM,CAAC;IACd,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,CAAC;IAC5B,IAAI,EAAE,MAAM,GAAG,SAAS,CAAC;IACzB,KAAK,EAAE,MAAM,CAAC;IACd,UAAU,EAAE,MAAM,CAAC;IACnB,GAAG,CAAC,EAAE,MAAM,GAAG,MAAM,CAAC;IACtB,QAAQ,CAAC,EAAE,GAAG,CAAC;CAChB,OAmLA"}
@@ -1,5 +1,14 @@
1
1
  import applyHookSync from "../../../../hook/applyHookSync.js";
2
2
  import getRangeQuery from "./getRangeQuery.js";
3
+ const selectFilterTypes = [
4
+ "check",
5
+ "autocomplete",
6
+ "tags",
7
+ "avatar",
8
+ "radio",
9
+ "select",
10
+ "button",
11
+ ];
3
12
  export default function formatValue({ pg, table, filter = {}, name, value, dataTypeID, uid = 1, optimize, }) {
4
13
  const { extra, sql, select, strict, options /* default: defaultValue, */ } = filter;
5
14
  const pk = pg?.pk && table ? pg.pk[table] : undefined;
@@ -33,7 +42,7 @@ export default function formatValue({ pg, table, filter = {}, name, value, dataT
33
42
  !value ||
34
43
  (!dataTypeID && !extra && !sql && !options) ||
35
44
  extra?.input?.toLowerCase?.() === "datatable" ||
36
- (!["check", "autocomplete", "tags", "avatar", "radio"].includes(filterType) &&
45
+ (!selectFilterTypes.includes(filterType) &&
37
46
  options?.find?.((el) => el?.sql))) {
38
47
  return {};
39
48
  }
@@ -105,11 +114,11 @@ export default function formatValue({ pg, table, filter = {}, name, value, dataT
105
114
  return { op: "between", query };
106
115
  }
107
116
  /* select query - from admin.cls / filter options */
108
- if (["check", "autocomplete", "tags", "avatar", "radio", "select"].includes(filterType)) {
117
+ if (selectFilterTypes.includes(filterType)) {
109
118
  // multiple checks with predefined query
110
119
  if (options?.find?.((el) => el?.sql)) {
111
120
  const query = options
112
- .filter((el) => value.split(",").includes(el.id))
121
+ .filter((el) => value.split(",").includes(el.id?.toString?.()))
113
122
  .map((el) => el.sql || "false")
114
123
  .join(" and ") || "false";
115
124
  return { op: "=", query };
@@ -1 +1 @@
1
- {"version":3,"file":"getMenu.d.ts","sourceRoot":"","sources":["../../../../../server/routes/menu/controllers/getMenu.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,SAAS,CAAC;AAC5C,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,wBAAwB,CAAC;AA4CzD,wBAA8B,SAAS,CACrC,EACE,IAAS,EACT,OAAO,EACP,EAAqB,GACtB,EAAE;IACD,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,CAAC;IAC1B,OAAO,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,CAAC;IAC9B,EAAE,EAAE,UAAU,CAAC;CAChB,EACD,KAAK,EAAE,YAAY,GAAG,IAAI;;;;;;;;;;;;GAuG3B"}
1
+ {"version":3,"file":"getMenu.d.ts","sourceRoot":"","sources":["../../../../../server/routes/menu/controllers/getMenu.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,SAAS,CAAC;AAC5C,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,wBAAwB,CAAC;AA4CzD,wBAA8B,SAAS,CACrC,EACE,IAAS,EACT,OAAO,EACP,EAAqB,GACtB,EAAE;IACD,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,CAAC;IAC1B,OAAO,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,CAAC;IAC9B,EAAE,EAAE,UAAU,CAAC;CAChB,EACD,KAAK,EAAE,YAAY,GAAG,IAAI;;;;;;;;;;;;GAwG3B"}
@@ -66,6 +66,7 @@ export default async function adminMenu({ user = {}, session, pg = pgClients.cli
66
66
  user?.uid &&
67
67
  !user.user_type?.includes?.("admin") &&
68
68
  !user.type?.includes?.("admin") &&
69
+ user.user_type !== "viewer" &&
69
70
  pg.pk?.["admin.role_access"]) {
70
71
  const { type, gl = [], routes = [], } = await pg
71
72
  .query(`select user_type as type, b.gl,routes from admin.users a
@@ -1 +1 @@
1
- {"version":3,"file":"getData.d.ts","sourceRoot":"","sources":["../../../../../server/routes/table/functions/getData.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,SAAS,CAAC;AAC5C,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,wBAAwB,CAAC;AA4DzD,wBAA8B,OAAO,CACnC,EACE,EAAqB,EACrB,MAAM,EACN,KAAK,EACL,EAAE,EACF,OAAY,EACZ,KAAU,EACV,IAAS,EACT,YAAY,EACZ,KAAY,EACZ,UAAU,EACV,OAAO,EAAE,YAAY,GACtB,EAAE;IACD,EAAE,EAAE,UAAU,CAAC;IACf,MAAM,CAAC,EAAE;QAAE,EAAE,CAAC,EAAE,MAAM,CAAC;QAAC,KAAK,CAAC,EAAE,MAAM,CAAC;QAAC,KAAK,EAAE,MAAM,CAAA;KAAE,CAAC;IACxD,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,EAAE,CAAC,EAAE,MAAM,CAAC;IACZ,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,CAAC;IAC7B,KAAK,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,CAAC;IAC5B,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,CAAC;IAC1B,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,KAAK,CAAC,EAAE,OAAO,CAAC;IAChB,UAAU,CAAC,EAAE,GAAG,EAAE,CAAC;IACnB,OAAO,CAAC,EAAE,MAAM,EAAE,CAAC;CACpB,EACD,KAAK,EAAE,YAAY,EACnB,MAAM,CAAC,EAAE,GAAG,gBAkzBb"}
1
+ {"version":3,"file":"getData.d.ts","sourceRoot":"","sources":["../../../../../server/routes/table/functions/getData.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,SAAS,CAAC;AAC5C,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,wBAAwB,CAAC;AA4DzD,wBAA8B,OAAO,CACnC,EACE,EAAqB,EACrB,MAAM,EACN,KAAK,EACL,EAAE,EACF,OAAY,EACZ,KAAU,EACV,IAAS,EACT,YAAY,EACZ,KAAY,EACZ,UAAU,EACV,OAAO,EAAE,YAAY,GACtB,EAAE;IACD,EAAE,EAAE,UAAU,CAAC;IACf,MAAM,CAAC,EAAE;QAAE,EAAE,CAAC,EAAE,MAAM,CAAC;QAAC,KAAK,CAAC,EAAE,MAAM,CAAC;QAAC,KAAK,EAAE,MAAM,CAAA;KAAE,CAAC;IACxD,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,EAAE,CAAC,EAAE,MAAM,CAAC;IACZ,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,CAAC;IAC7B,KAAK,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,CAAC;IAC5B,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,CAAC;IAC1B,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,KAAK,CAAC,EAAE,OAAO,CAAC;IAChB,UAAU,CAAC,EAAE,GAAG,EAAE,CAAC;IACnB,OAAO,CAAC,EAAE,MAAM,EAAE,CAAC;CACpB,EACD,KAAK,EAAE,YAAY,EACnB,MAAM,CAAC,EAAE,GAAG,gBAgzBb"}
@@ -48,11 +48,10 @@ export default async function dataAPI({ pg = pgClients.client, params, table, id
48
48
  if (!paramsTable) {
49
49
  return { message: "not enough params: table", status: 400 };
50
50
  }
51
- const paramsId = params?.id || id;
52
51
  const hookData = (await applyHook("preData", {
53
52
  pg,
54
53
  table: paramsTable,
55
- id: paramsId,
54
+ id: params?.id || id,
56
55
  user,
57
56
  }));
58
57
  if (hookData?.message && hookData?.status) {
@@ -108,10 +107,10 @@ export default async function dataAPI({ pg = pgClients.client, params, table, id
108
107
  !(called && pkey)) {
109
108
  return reply.status(404).send("template not found");
110
109
  }
111
- const id1 = tokenData?.id || hookData?.id || paramsId;
110
+ const objectId = tokenData?.id || hookData?.id || params?.id || id;
112
111
  const { actions = [], query: accessQuery } = (await getAccess({
113
112
  table: templateName,
114
- id: id1,
113
+ id: objectId,
115
114
  user,
116
115
  }, pg));
117
116
  if (!actions.includes("view") && !config?.local && !called) {
@@ -130,7 +129,6 @@ export default async function dataAPI({ pg = pgClients.client, params, table, id
130
129
  // console.warn('invalid filters in template: filter_list / filterList');
131
130
  // logger.file('crud/warning', { msg: 'invalid filters', template: templateName });
132
131
  }
133
- const objectId = tokenData?.id || hookData?.id || paramsId;
134
132
  const { list: filters = [] } = objectId
135
133
  ? {}
136
134
  : (await getFilter({
@@ -166,7 +164,7 @@ export default async function dataAPI({ pg = pgClients.client, params, table, id
166
164
  (!el.sql.includes("{{uid}}") || uid))
167
165
  .map((el, i) => ` left join lateral (${el.sql.replace("{{uid}}", uid)}) ${el.name || `t${i}`} on 1=1 `)
168
166
  ?.join("") || "";
169
- const cardSqlFiltered = hookData?.id || paramsId
167
+ const cardSqlFiltered = objectId
170
168
  ? cardSql?.filter?.((el) => !el?.disabled && el?.name && el?.sql?.replace) || []
171
169
  : [];
172
170
  const cardSqlTable = cardSqlFiltered.length
@@ -191,11 +189,11 @@ export default async function dataAPI({ pg = pgClients.client, params, table, id
191
189
  ?.filter((el) => !cols.includes(el))
192
190
  .join(",")}`
193
191
  : "";
194
- if (paramsId && columnList.includes(paramsId)) {
192
+ if (objectId && columnList.includes(objectId)) {
195
193
  return gisIRColumn({
196
194
  pg,
197
195
  layer: paramsTable,
198
- column: paramsId,
196
+ column: objectId,
199
197
  sql: query.sql,
200
198
  filter: query.filter,
201
199
  search: query.search,
@@ -269,7 +267,7 @@ export default async function dataAPI({ pg = pgClients.client, params, table, id
269
267
  ? await handlebars.compile(params?.query)({ user, uid })
270
268
  : undefined;
271
269
  const where = [
272
- id1 ? ` "${pk}" = $1` : null,
270
+ objectId ? ` "${pk}" = $1` : null,
273
271
  keyQuery,
274
272
  loadTable?.query,
275
273
  tokenData?.query,
@@ -285,7 +283,7 @@ export default async function dataAPI({ pg = pgClients.client, params, table, id
285
283
  .filter(Boolean)
286
284
  .filter((el) => checkQuery(el));
287
285
  const q = `select ${pk ? `"${pk}" as id,` : ""}
288
- ${paramsId || query.key ? "*" : sqlColumns || cols || "*"}
286
+ ${objectId || query.key ? "*" : sqlColumns || cols || "*"}
289
287
  ${metaCols}
290
288
 
291
289
  ${dbColumns.filter((el) => pg.pgType?.[el.dataTypeID] === "geometry").length
@@ -299,7 +297,7 @@ export default async function dataAPI({ pg = pgClients.client, params, table, id
299
297
  .map((el) => `,(${el.sql})`)
300
298
  .join("") || ""} from ${table1} t ${sqlTable} ) t
301
299
 
302
- ${paramsId ? cardSqlTable : ""}
300
+ ${objectId ? cardSqlTable : ""}
303
301
  where ${where.join(" and ") || "true"}
304
302
  ${order} ${offset} limit ${limit}`.replace(/{{uid}}/g, uid);
305
303
  if (config.trace)
@@ -308,7 +306,8 @@ export default async function dataAPI({ pg = pgClients.client, params, table, id
308
306
  return q;
309
307
  }
310
308
  const { rows = [] } = await pg
311
- .query(q, (id1 ? [id1] : null) || (query.key && loadTable.key ? [query.key] : []))
309
+ .query(q, (objectId ? [objectId] : null) ||
310
+ (query.key && loadTable.key ? [query.key] : []))
312
311
  .catch((err) => {
313
312
  console.error(err.toString());
314
313
  throw err;
@@ -382,7 +381,7 @@ export default async function dataAPI({ pg = pgClients.client, params, table, id
382
381
  if (query.sql === "2") {
383
382
  return qCount;
384
383
  }
385
- const counts = keyQuery || id1
384
+ const counts = keyQuery || objectId
386
385
  ? { total: rows.length, filtered: rows.length }
387
386
  : await pg
388
387
  .queryCache?.(qCount, {
@@ -428,6 +427,7 @@ export default async function dataAPI({ pg = pgClients.client, params, table, id
428
427
  .filter((key) => index?.tokens[key]?.public ||
429
428
  actions?.includes?.("edit") ||
430
429
  actions?.includes?.("add") ||
430
+ user?.user_type === "viewer" ||
431
431
  !index?.tokens[key]?.table)
432
432
  .forEach((key) => {
433
433
  const item = index?.tokens[key];
@@ -437,7 +437,7 @@ export default async function dataAPI({ pg = pgClients.client, params, table, id
437
437
  item[el] = handlebarsSync.compile(item[el])({
438
438
  user,
439
439
  uid,
440
- id,
440
+ id: objectId,
441
441
  data: rows[0],
442
442
  });
443
443
  });
@@ -469,7 +469,7 @@ export default async function dataAPI({ pg = pgClients.client, params, table, id
469
469
  .map(async (el) => {
470
470
  const filtered1 = el.items.filter((item) => item.count?.toLowerCase?.().includes("select"));
471
471
  const data = await Promise.all(filtered1.map(async (item) => pg
472
- .query(item.count.replace(/{{id}}/g, paramsId))
472
+ .query(item.count.replace(/{{id}}/g, objectId))
473
473
  .then((item1) => item1.rows[0] || {})));
474
474
  filtered1.forEach((el1, i) => {
475
475
  // el1.title = data[i].title;
@@ -479,9 +479,9 @@ export default async function dataAPI({ pg = pgClients.client, params, table, id
479
479
  .map((item) => item.component ? components[item.component] : null)
480
480
  .filter((item) => item)
481
481
  .join(" union all ");
482
- const counts1 = q1 && id
482
+ const counts1 = q1 && objectId
483
483
  ? await pg
484
- .query(q1, [id1])
484
+ .query(q1, [objectId])
485
485
  .then((e) => e.rows.reduce((acc, curr) => Object.assign(acc, { [curr.component]: curr.count }), {}))
486
486
  : {};
487
487
  el.items
@@ -498,7 +498,7 @@ export default async function dataAPI({ pg = pgClients.client, params, table, id
498
498
  data: rows[0],
499
499
  user,
500
500
  uid,
501
- id: id1,
501
+ id: objectId,
502
502
  });
503
503
  const { rows: sqlData } = await pg.query(q2);
504
504
  data[el.name] = sqlData;
@@ -528,7 +528,7 @@ export default async function dataAPI({ pg = pgClients.client, params, table, id
528
528
  const name = el[0].substring(0, el[0].lastIndexOf("."));
529
529
  logger.file("handlebars/error", {
530
530
  table,
531
- id: paramsId,
531
+ id: objectId,
532
532
  error: err.toString(),
533
533
  stack: err.stack,
534
534
  });
@@ -602,7 +602,7 @@ export default async function dataAPI({ pg = pgClients.client, params, table, id
602
602
  const result = await applyHook("afterData", {
603
603
  pg,
604
604
  table: loadTable?.table || tokenData?.table,
605
- id: id1,
605
+ id: objectId,
606
606
  template: templateName,
607
607
  payload: res,
608
608
  user,
package/package.json CHANGED
@@ -1,88 +1,88 @@
1
- {
2
- "name": "@opengis/fastify-table",
3
- "version": "2.0.43",
4
- "type": "module",
5
- "description": "core-plugins",
6
- "keywords": [
7
- "fastify",
8
- "table",
9
- "crud",
10
- "auth",
11
- "pg",
12
- "backend"
13
- ],
14
- "main": "dist/index.js",
15
- "exports": {
16
- ".": "./dist/index.js",
17
- "./index.js": "./dist/index.js",
18
- "./utils.js": "./dist/utils.js"
19
- },
20
- "files": [
21
- "dist/*"
22
- ],
23
- "scripts": {
24
- "prepublishOnly": "npm run build",
25
- "clean": "tsc -b --clean",
26
- "build": "tsc -b --clean && tsc && copyfiles server/plugins/grpc/utils/*.proto dist && copyfiles server/migrations/*.sql dist && copyfiles server/templates/**/*.html dist",
27
- "prod": "NODE_ENV=production bun dist/server",
28
- "patch": "npm version patch && git push && npm publish",
29
- "lint": "eslint . --ext .vue,.js,.jsx,.cjs,.mjs,.ts,.tsx,.cts,.mts --fix --ignore-path .gitignore",
30
- "test": "bun test",
31
- "compress": "node compress.js",
32
- "dev1": "bun --hot dist/server",
33
- "dev": "NODE_ENV=production bun start",
34
- "start": "bun server"
35
- },
36
- "dependencies": {
37
- "@aws-sdk/client-s3": "3.879.0",
38
- "@aws-sdk/lib-storage": "3.879.0",
39
- "@fastify/cookie": "11.0.2",
40
- "@fastify/http-proxy": "11.1.2",
41
- "@fastify/multipart": "9.0.3",
42
- "@fastify/passport": "3.0.2",
43
- "@fastify/rate-limit": "10.3.0",
44
- "@fastify/session": "11.1.0",
45
- "@grpc/grpc-js": "1.10.11",
46
- "@grpc/proto-loader": "0.7.15",
47
- "apache-crypt": "1.2.6",
48
- "better-sqlite3": "12.2.0",
49
- "dotenv": "16.5.0",
50
- "fastify": "5.3.3",
51
- "fastify-plugin": "5.0.1",
52
- "fastify-session-redis-store": "7.1.2",
53
- "handlebars": "4.7.8",
54
- "image-size": "1.2.0",
55
- "ioredis": "5.3.2",
56
- "js-yaml": "4.1.0",
57
- "markdown-it": "14.1.0",
58
- "nodemailer": "7.0.6",
59
- "otplib": "12.0.1",
60
- "pg": "8.11.6",
61
- "pino": "9.5.0",
62
- "pino-abstract-transport": "2.0.0",
63
- "promised-handlebars": "2.0.1",
64
- "qrcode": "1.5.4",
65
- "uglify-js": "3.19.3",
66
- "undici": "7.16.0"
67
- },
68
- "devDependencies": {
69
- "@types/better-sqlite3": "^7.6.13",
70
- "@types/bun": "^1.2.21",
71
- "@types/js-yaml": "^4.0.9",
72
- "@types/markdown-it": "^14.1.2",
73
- "@types/node": "^24.3.1",
74
- "@types/nodemailer": "^7.0.1",
75
- "@types/passport": "^1.0.17",
76
- "@types/passport-local": "^1.0.38",
77
- "@types/pg": "^8.15.5",
78
- "@types/qrcode": "^1.5.5",
79
- "copyfiles": "^2.4.1",
80
- "eslint": "^9.35.0",
81
- "eslint-config-airbnb-extended": "^2.3.1",
82
- "ts-migrate": "^0.1.35",
83
- "typescript": "^5.9.2",
84
- "vitest": "^3.2.4"
85
- },
86
- "author": "Softpro",
87
- "license": "ISC"
88
- }
1
+ {
2
+ "name": "@opengis/fastify-table",
3
+ "version": "2.0.45",
4
+ "type": "module",
5
+ "description": "core-plugins",
6
+ "keywords": [
7
+ "fastify",
8
+ "table",
9
+ "crud",
10
+ "auth",
11
+ "pg",
12
+ "backend"
13
+ ],
14
+ "main": "dist/index.js",
15
+ "exports": {
16
+ ".": "./dist/index.js",
17
+ "./index.js": "./dist/index.js",
18
+ "./utils.js": "./dist/utils.js"
19
+ },
20
+ "files": [
21
+ "dist/*"
22
+ ],
23
+ "scripts": {
24
+ "prepublishOnly": "npm run build",
25
+ "clean": "tsc -b --clean",
26
+ "build": "tsc -b --clean && tsc && copyfiles server/plugins/grpc/utils/*.proto dist && copyfiles server/migrations/*.sql dist && copyfiles server/templates/**/*.html dist",
27
+ "prod": "NODE_ENV=production bun dist/server",
28
+ "patch": "npm version patch && git push && npm publish",
29
+ "lint": "eslint . --ext .vue,.js,.jsx,.cjs,.mjs,.ts,.tsx,.cts,.mts --fix --ignore-path .gitignore",
30
+ "test": "bun test",
31
+ "compress": "node compress.js",
32
+ "dev1": "bun --hot dist/server",
33
+ "dev": "NODE_ENV=production bun start",
34
+ "start": "bun server"
35
+ },
36
+ "dependencies": {
37
+ "@aws-sdk/client-s3": "3.879.0",
38
+ "@aws-sdk/lib-storage": "3.879.0",
39
+ "@fastify/cookie": "11.0.2",
40
+ "@fastify/http-proxy": "11.1.2",
41
+ "@fastify/multipart": "9.0.3",
42
+ "@fastify/passport": "3.0.2",
43
+ "@fastify/rate-limit": "10.3.0",
44
+ "@fastify/session": "11.1.0",
45
+ "@grpc/grpc-js": "1.10.11",
46
+ "@grpc/proto-loader": "0.7.15",
47
+ "apache-crypt": "1.2.6",
48
+ "better-sqlite3": "12.2.0",
49
+ "dotenv": "16.5.0",
50
+ "fastify": "5.3.3",
51
+ "fastify-plugin": "5.0.1",
52
+ "fastify-session-redis-store": "7.1.2",
53
+ "handlebars": "4.7.8",
54
+ "image-size": "1.2.0",
55
+ "ioredis": "5.3.2",
56
+ "js-yaml": "4.1.0",
57
+ "markdown-it": "14.1.0",
58
+ "nodemailer": "7.0.6",
59
+ "otplib": "12.0.1",
60
+ "pg": "8.11.6",
61
+ "pino": "9.5.0",
62
+ "pino-abstract-transport": "2.0.0",
63
+ "promised-handlebars": "2.0.1",
64
+ "qrcode": "1.5.4",
65
+ "uglify-js": "3.19.3",
66
+ "undici": "7.16.0"
67
+ },
68
+ "devDependencies": {
69
+ "@types/better-sqlite3": "^7.6.13",
70
+ "@types/bun": "^1.2.21",
71
+ "@types/js-yaml": "^4.0.9",
72
+ "@types/markdown-it": "^14.1.2",
73
+ "@types/node": "^24.3.1",
74
+ "@types/nodemailer": "^7.0.1",
75
+ "@types/passport": "^1.0.17",
76
+ "@types/passport-local": "^1.0.38",
77
+ "@types/pg": "^8.15.5",
78
+ "@types/qrcode": "^1.5.5",
79
+ "copyfiles": "^2.4.1",
80
+ "eslint": "^9.35.0",
81
+ "eslint-config-airbnb-extended": "^2.3.1",
82
+ "ts-migrate": "^0.1.35",
83
+ "typescript": "^5.9.2",
84
+ "vitest": "^3.2.4"
85
+ },
86
+ "author": "Softpro",
87
+ "license": "ISC"
88
+ }
@@ -1,137 +0,0 @@
1
- syntax = "proto3";
2
-
3
- service Convert {
4
- rpc csvToXls(csvToXlsParams) returns (FileBase64) {}
5
- rpc jsonToXls(jsonToXlsParams) returns (FileBase64) {}
6
- rpc pdfMerge(pdfMergeParams) returns (FileBase64) {}
7
- rpc htmlToPdf(htmlToPdfParams) returns (FileBase64) {}
8
- rpc excelToJson(excelToJsonParams) returns (FileBase64) {}
9
- rpc xmlToJson(xmlToJsonParams) returns (FileBase64) {}
10
- rpc htmlToDoc(htmlToDocParams) returns (FileBase64) {}
11
- rpc htmlToImage(htmlToImageParams) returns (FileBase64) {}
12
- rpc geojsonToShp(geojsonToShpParams) returns (FileBase64) {}
13
- rpc shpToGeojson(shpToGeojsonParams) returns (FileBase64) {}
14
- rpc docToPDF(docToPDFParams) returns (FileBase64) {}
15
- rpc mergeImages(mergeImagesIn) returns (FileBase64) {}
16
- rpc resizeImage(resizeImageIn) returns (FileBase64) {}
17
- rpc jsonToYaml(jsonToYamlIn) returns (FileBase64) {}
18
- rpc yamlToJson(yamlToJsonIn) returns (FileBase64) {}
19
- rpc log(log_in) returns (log_out) {}
20
- rpc geojsonToGpkg(geojsonToShpParams) returns (FileBase64) {}
21
- }
22
-
23
- message jsonToYamlIn {
24
- string json = 1;
25
- }
26
-
27
- message yamlToJsonIn {
28
- string yaml = 1;
29
- }
30
-
31
- message resizeImageIn {
32
- string base64 = 1;
33
- uint64 width = 2;
34
- uint64 height = 3;
35
- uint32 quality = 4;
36
- uint32 subsampling = 5;
37
- }
38
-
39
- message pdfToImgIn {
40
- string pdfPath = 1;
41
- string imgPath = 2;
42
- }
43
-
44
- message pdfToImgOut {
45
- string imgPath = 1;
46
- }
47
-
48
- message log_in {
49
- uint32 rows = 1;
50
- string level = 2;
51
- }
52
-
53
- message log_out {
54
- repeated string logs = 1;
55
- }
56
-
57
- enum mergeImageFormat {
58
- VERTICAL = 0;
59
- HORIZONTAL = 1;
60
- OVERLAY = 2;
61
- }
62
-
63
- message imageMeta {
64
- string base64 = 1;
65
- mergeImageFormat mergeFormat = 2;
66
- }
67
-
68
- message mergeImagesIn {
69
- repeated string images = 1;
70
- repeated imageMeta imagesMeta = 2;
71
- string background = 3;
72
- string mergeFormat = 4;
73
- }
74
-
75
- message docToPDFParams {
76
- string base64 = 1;
77
- string to = 2;
78
- string ext = 3;
79
- }
80
-
81
- message shpToGeojsonParams {
82
- string base64 = 1;
83
- }
84
-
85
- message geojsonToShpParams {
86
- string geojson = 1;
87
- string proj = 2;
88
- }
89
-
90
- message xmlToJsonParams {
91
- string xml = 1;
92
- }
93
-
94
- message jsonToXlsParams {
95
- string json = 1;
96
- string header = 2;
97
- string subheader = 3;
98
- string colmodel = 4;
99
- }
100
-
101
- message csvToXlsParams {
102
- string csv = 1;
103
- string header = 2;
104
- string subheader = 3;
105
- string separator = 4;
106
- }
107
-
108
- message excelToJsonParams {
109
- string base64 = 1;
110
- string type = 2;
111
- string delimiter = 3;
112
- string encoding = 4;
113
- }
114
-
115
- message htmlToPdfParams {
116
- string html = 1;
117
- string pdfPageConfig = 2;
118
- }
119
-
120
- message pdfMergeParams {
121
- repeated string mergeFiles = 1;
122
- }
123
-
124
- message htmlToImageParams {
125
- string html = 1;
126
- string format = 2;
127
- uint64 width = 3;
128
- uint64 height = 4;
129
- }
130
-
131
- message htmlToDocParams {
132
- string html = 1;
133
- }
134
-
135
- message FileBase64 {
136
- string result = 1;
137
- }
@@ -1,14 +0,0 @@
1
- syntax = "proto3";
2
-
3
- service OfficeConverterService {
4
- rpc OfficeToPdf(OfficeToPdfRequest) returns (OfficeToPdfResponse) {}
5
- }
6
-
7
- message OfficeToPdfRequest {
8
- string file = 1;
9
- string ext = 2;
10
- }
11
-
12
- message OfficeToPdfResponse {
13
- string file = 1;
14
- }
@@ -1,7 +0,0 @@
1
- import hookList from "../hookList.js";
2
- export default function addHook(name, fn) {
3
- if (!hookList[name]) {
4
- hookList[name] = [];
5
- }
6
- hookList[name].push(fn);
7
- }
@@ -1,25 +0,0 @@
1
- /* eslint-disable no-console */
2
- import config from "../../../../config.js";
3
- import hookList from "../hookList.js";
4
- export default async function applyHook(name, data) {
5
- const { trace } = config;
6
- if (trace)
7
- console.log("applyHook", name);
8
- if (!hookList[name]?.length)
9
- return null;
10
- const result = {};
11
- await Promise.all(hookList[name].map(async (hook) => {
12
- const hookData = await hook({ ...data, config });
13
- if (hookData) {
14
- if (trace)
15
- console.log("applyHook", name, hookData);
16
- Object.assign(result, hookData);
17
- }
18
- })).catch((err) => {
19
- console.error("applyHook", name, err.toString());
20
- });
21
- if (Object.keys(result).length) {
22
- return result;
23
- }
24
- return null;
25
- }
@@ -1,7 +0,0 @@
1
- import hookList from "../hookList.js";
2
- export default function applyHookSync(name, data) {
3
- if (!hookList[name]?.length)
4
- return null;
5
- const hookData = hookList[name].map((hook) => hook(data))[0];
6
- return hookData;
7
- }
@@ -1,7 +0,0 @@
1
- // import addHook from './funcs/addHook.js';
2
- // import applyHook from './funcs/applyHook.js';
3
- async function plugin() {
4
- // fastify.decorate('addHook', addHook);
5
- // fastify.decorate('applyHook', applyHook);
6
- }
7
- export default plugin;
@@ -1,22 +0,0 @@
1
- import config from "../../../../../config.js";
2
- const { accessToken = "0NWcGQxKRP8AsRxD" } = config.auth || {};
3
- /**
4
- *
5
- * @summary check user access to logger interface - per admin user type or user group
6
- * @returns {Object} message, status
7
- */
8
- export default function checkUserAccess({ user = {}, token, }) {
9
- if (token && token === accessToken) {
10
- return { message: "access granted", status: 200 };
11
- }
12
- // console.log(user);
13
- if (!user.user_type?.includes?.("admin") &&
14
- !config?.local &&
15
- !config.auth?.disable) {
16
- return { message: "access restricted", status: 403 };
17
- }
18
- /* if (!['admin', 'superadmin']?.includes(user.user_type) && count === '0') {
19
- return { message: 'access restricted', status: 403 };
20
- } */
21
- return { message: "access granted", status: 200 };
22
- }
@@ -1,25 +0,0 @@
1
- /* eslint-disable no-console */
2
- import fs from "node:fs";
3
- import path from "node:path";
4
- import config from "../../../../../config.js";
5
- // import { existsSync } from 'fs';
6
- let logDir = null;
7
- export default function getRootDir() {
8
- // absolute / relative path
9
- if (logDir)
10
- return logDir;
11
- const file = ["config.json", "/data/local/config.json"].find((el) => fs.existsSync(el) ? el : null);
12
- const root = file === "config.json" ? process.cwd() : "/data/local";
13
- logDir = config.logDir || path.join(root, config.log?.dir || "log");
14
- console.log({ logDir });
15
- return logDir;
16
- // windows debug support
17
- /* const customLogDir = process.cwd().includes(':') ? 'c:/data/local' : '/data/local';
18
- // docker default path
19
- if (existsSync(customLogDir)) {
20
- return path.join(customLogDir, config.folder || '', 'log');
21
- }
22
-
23
- // non-docker default path
24
- return path.join(config.root || '/data/local', config.folder || '', 'log'); */
25
- }