@opengis/fastify-table 2.5.18 → 2.5.21
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/dist/server/plugins/auth/funcs/getQuery.d.ts.map +1 -1
- package/dist/server/plugins/auth/funcs/getQuery.js +1 -1
- package/dist/server/plugins/crud/funcs/dataUpdate.d.ts.map +1 -1
- package/dist/server/plugins/crud/funcs/dataUpdate.js +2 -1
- package/dist/server/plugins/crud/funcs/utils/getInsertQuery.d.ts.map +1 -1
- package/dist/server/plugins/crud/funcs/utils/getInsertQuery.js +2 -1
- package/dist/server/plugins/crud/funcs/utils/nullif.d.ts +3 -0
- package/dist/server/plugins/crud/funcs/utils/nullif.d.ts.map +1 -0
- package/dist/server/plugins/crud/funcs/utils/nullif.js +10 -0
- package/dist/server/plugins/file/uploadMultiPart.d.ts.map +1 -1
- package/dist/server/plugins/file/uploadMultiPart.js +4 -1
- package/dist/server/plugins/policy/funcs/checkPolicy.d.ts.map +1 -1
- package/dist/server/plugins/policy/funcs/checkPolicy.js +2 -16
- package/dist/server/plugins/policy/funcs/checkTraversal.d.ts +2 -0
- package/dist/server/plugins/policy/funcs/checkTraversal.d.ts.map +1 -0
- package/dist/server/plugins/policy/funcs/checkTraversal.js +22 -0
- package/dist/server/plugins/policy/index.d.ts.map +1 -1
- package/dist/server/plugins/policy/index.js +3 -1
- package/dist/server/plugins/table/funcs/getSelect.js +3 -3
- package/dist/server/plugins/upload/startUpload.d.ts.map +1 -1
- package/dist/server/plugins/upload/startUpload.js +12 -3
- package/dist/server/plugins/usercls/index.d.ts +1 -2
- package/dist/server/plugins/usercls/index.d.ts.map +1 -1
- package/dist/server/plugins/usercls/index.js +29 -21
- package/dist/server/routes/file/controllers/resize.d.ts +4 -1
- package/dist/server/routes/file/controllers/resize.d.ts.map +1 -1
- package/dist/server/routes/file/controllers/resize.js +14 -1
- package/dist/server/routes/table/controllers/cardData.js +3 -3
- package/dist/server/routes/table/controllers/suggest.d.ts.map +1 -1
- package/dist/server/routes/table/controllers/suggest.js +17 -1
- package/dist/server/routes/table/functions/getData.d.ts.map +1 -1
- package/dist/server/routes/table/functions/getData.js +7 -6
- package/dist/server/routes/usercls/controllers/addUserCls.d.ts +8 -1
- package/dist/server/routes/usercls/controllers/addUserCls.d.ts.map +1 -1
- package/dist/server/routes/usercls/controllers/addUserCls.js +3 -5
- package/dist/server/routes/usercls/controllers/getUserCls.d.ts.map +1 -1
- package/dist/server/routes/usercls/controllers/getUserCls.js +18 -2
- package/package.json +99 -99
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"getQuery.d.ts","sourceRoot":"","sources":["../../../../../server/plugins/auth/funcs/getQuery.ts"],"names":[],"mappings":"AA6BA,OAAO,EAAE,UAAU,EAAE,MAAM,wBAAwB,CAAC;AAGpD,wBAA8B,QAAQ,CAAC,EACrC,EAAE,EACF,IAAI,GACL,EAAE;IACD,EAAE,EAAE,UAAU,CAAC;IACf,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,CAAC;CAC3B,
|
|
1
|
+
{"version":3,"file":"getQuery.d.ts","sourceRoot":"","sources":["../../../../../server/plugins/auth/funcs/getQuery.ts"],"names":[],"mappings":"AA6BA,OAAO,EAAE,UAAU,EAAE,MAAM,wBAAwB,CAAC;AAGpD,wBAA8B,QAAQ,CAAC,EACrC,EAAE,EACF,IAAI,GACL,EAAE;IACD,EAAE,EAAE,UAAU,CAAC;IACf,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,CAAC;CAC3B,gBAoIA"}
|
|
@@ -124,5 +124,5 @@ export default async function getQuery({ pg, data, }) {
|
|
|
124
124
|
.query(`select * from admin.users where uid =(select uid from admin.users_social_auth
|
|
125
125
|
where ${id ? "social_auth_id=$1" : "email=$1"} limit 1)`, [id || email])
|
|
126
126
|
.then((el) => el.rows?.[0] || {});
|
|
127
|
-
return result;
|
|
127
|
+
return { ...result, isNewUser: !(userId || socialUserId) };
|
|
128
128
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"dataUpdate.d.ts","sourceRoot":"","sources":["../../../../../server/plugins/crud/funcs/dataUpdate.ts"],"names":[],"mappings":"AAWA,OAAO,EAAE,UAAU,EAAE,MAAM,wBAAwB,CAAC;
|
|
1
|
+
{"version":3,"file":"dataUpdate.d.ts","sourceRoot":"","sources":["../../../../../server/plugins/crud/funcs/dataUpdate.ts"],"names":[],"mappings":"AAWA,OAAO,EAAE,UAAU,EAAE,MAAM,wBAAwB,CAAC;AAiBpD,wBAA8B,UAAU,CAAC,EACvC,KAAK,EAAE,MAAM,EACb,SAAS,EACT,OAAO,EACP,EAAE,EACF,IAAI,EACJ,EAAE,EAAE,GAAG,EACP,GAAG,EACH,GAAU,GACX,EAAE;IACD,KAAK,EAAE,MAAM,CAAC;IACd,SAAS,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,CAAC;IAChC,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,EAAE,EAAE,MAAM,GAAG,MAAM,CAAC;IACpB,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,CAAC;IAC1B,EAAE,CAAC,EAAE,UAAU,CAAC;IAChB,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,GAAG,CAAC,EAAE,OAAO,CAAC;CACf,gBAwPA"}
|
|
@@ -8,6 +8,7 @@ import extraData from "../../extra/extraData.js";
|
|
|
8
8
|
import logChanges from "./utils/logChanges.js";
|
|
9
9
|
import logger from "../../logger/getLogger.js";
|
|
10
10
|
import getInsertQuery from "./utils/getInsertQuery.js";
|
|
11
|
+
import nullif from "./utils/nullif.js";
|
|
11
12
|
const rclient = getRedis();
|
|
12
13
|
const srids = {};
|
|
13
14
|
function assignValue(key, i, srid = 4326, columnType = "text") {
|
|
@@ -64,7 +65,7 @@ export default async function dataUpdate({ table: table1, tokenData, referer, id
|
|
|
64
65
|
["string", "number"].includes(typeof data[el])) {
|
|
65
66
|
Object.assign(data, { [el]: data[el].split(",") });
|
|
66
67
|
}
|
|
67
|
-
return [el, data[el]
|
|
68
|
+
return [el, nullif(data[el])]; // ensure '' on number does not throw
|
|
68
69
|
})
|
|
69
70
|
.map((el) => typeof el[1] === "object" && types[el[0]]?.includes?.("json") && el[1]
|
|
70
71
|
? JSON.stringify(el[1])
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"getInsertQuery.d.ts","sourceRoot":"","sources":["../../../../../../server/plugins/crud/funcs/utils/getInsertQuery.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,UAAU,EAAE,MAAM,2BAA2B,CAAC;
|
|
1
|
+
{"version":3,"file":"getInsertQuery.d.ts","sourceRoot":"","sources":["../../../../../../server/plugins/crud/funcs/utils/getInsertQuery.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,UAAU,EAAE,MAAM,2BAA2B,CAAC;AAM5D,wBAA8B,cAAc,CAAC,EAC3C,EAAE,EACF,KAAK,EACL,IAAI,EACJ,EAAE,EACF,GAAG,GACJ,EAAE;IACD,EAAE,CAAC,EAAE,UAAU,CAAC;IAChB,KAAK,EAAE,MAAM,CAAC;IACd,IAAI,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,CAAC;IAC3B,EAAE,CAAC,EAAE,MAAM,GAAG,MAAM,CAAC;IACrB,GAAG,CAAC,EAAE,MAAM,CAAC;CACd;;;;;UA+EA"}
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import getMeta from "../../../pg/funcs/getMeta.js";
|
|
2
|
+
import nullif from "./nullif.js";
|
|
2
3
|
export default async function getInsertQuery({ pg, table, data, id, uid, }) {
|
|
3
4
|
if (!pg?.pk || !data) {
|
|
4
5
|
return null;
|
|
@@ -54,7 +55,7 @@ export default async function getInsertQuery({ pg, table, data, id, uid, }) {
|
|
|
54
55
|
typeof el[1]?.[0] === "object" ||
|
|
55
56
|
types[el[0]] === "json")
|
|
56
57
|
? JSON.stringify(el[1])
|
|
57
|
-
: el[1]),
|
|
58
|
+
: nullif(el[1])),
|
|
58
59
|
];
|
|
59
60
|
const keys = filterData.map((el) => el[0]);
|
|
60
61
|
return { insertQuery, args, keys, systemColumns };
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"nullif.d.ts","sourceRoot":"","sources":["../../../../../../server/plugins/crud/funcs/utils/nullif.ts"],"names":[],"mappings":"AAAA,QAAA,MAAM,MAAM,GAAI,KAAK,GAAG,QAQvB,CAAC;AAEF,eAAe,MAAM,CAAC"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"uploadMultiPart.d.ts","sourceRoot":"","sources":["../../../../server/plugins/file/uploadMultiPart.ts"],"names":[],"mappings":"AA6BA,MAAM,WAAW,KAAK;IACpB,gBAAgB,CAAC,EAAE,MAAM,CAAC;IAC1B,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,gBAAgB,CAAC,EAAE,MAAM,CAAC;IAC1B,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,MAAM,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,CAAC;IAC7B,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,IAAI,CAAC,EAAE,MAAM,CAAC;CACf;AA2CD,wBAAsB,gBAAgB,CAAC,QAAQ,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,mBAkBvE;AAED,wBAAsB,gBAAgB,CACpC,EACE,IAAI,EAAE,QAAQ,EACd,MAA2C,EAC3C,MAAM,GACP,EAAE;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,MAAM,CAAC,EAAE,MAAM,CAAC;IAAC,MAAM,EAAE,MAAM,CAAA;CAAE,EACpD,MAAM,MAAW,mBA+BlB;AAED,wBAAsB,eAAe,CACnC,GAAG,EAAE,GAAG,EACR,EACE,UAAU,EACV,GAAG,EACH,MAAM,EACN,gBAAwB,GACzB,GAAE;IACD,UAAU,CAAC,EAAE,MAAM,EAAE,CAAC;IACtB,GAAG,CAAC,EAAE,OAAO,CAAC;IACd,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,gBAAgB,CAAC,EAAE,OAAO,CAAC;CACvB,GACL,OAAO,CAAC,KAAK,CAAC,
|
|
1
|
+
{"version":3,"file":"uploadMultiPart.d.ts","sourceRoot":"","sources":["../../../../server/plugins/file/uploadMultiPart.ts"],"names":[],"mappings":"AA6BA,MAAM,WAAW,KAAK;IACpB,gBAAgB,CAAC,EAAE,MAAM,CAAC;IAC1B,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,gBAAgB,CAAC,EAAE,MAAM,CAAC;IAC1B,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,MAAM,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,CAAC;IAC7B,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,IAAI,CAAC,EAAE,MAAM,CAAC;CACf;AA2CD,wBAAsB,gBAAgB,CAAC,QAAQ,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,mBAkBvE;AAED,wBAAsB,gBAAgB,CACpC,EACE,IAAI,EAAE,QAAQ,EACd,MAA2C,EAC3C,MAAM,GACP,EAAE;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,MAAM,CAAC,EAAE,MAAM,CAAC;IAAC,MAAM,EAAE,MAAM,CAAA;CAAE,EACpD,MAAM,MAAW,mBA+BlB;AAED,wBAAsB,eAAe,CACnC,GAAG,EAAE,GAAG,EACR,EACE,UAAU,EACV,GAAG,EACH,MAAM,EACN,gBAAwB,GACzB,GAAE;IACD,UAAU,CAAC,EAAE,MAAM,EAAE,CAAC;IACtB,GAAG,CAAC,EAAE,OAAO,CAAC;IACd,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,gBAAgB,CAAC,EAAE,OAAO,CAAC;CACvB,GACL,OAAO,CAAC,KAAK,CAAC,CAwHhB;AAED,eAAe,eAAe,CAAC"}
|
|
@@ -90,6 +90,10 @@ export async function uploadMultiPart(req, { extensions, raw, subdir, originalFi
|
|
|
90
90
|
if (extensions && !extensions.includes(ext)) {
|
|
91
91
|
throw new BadRequestError("file extension is not allowed");
|
|
92
92
|
}
|
|
93
|
+
const dir = subdir != null ? subdir : req.params?.["*"] || "uploads";
|
|
94
|
+
if (dir.replace(/%2e/g, ".").replace(/%2E/g, ".").includes("..")) {
|
|
95
|
+
throw new ConflictError("path traversal is not allowed");
|
|
96
|
+
}
|
|
93
97
|
// ! check extension by core list if custom not provided - from filename
|
|
94
98
|
if (!extensions && !allowedExtensions.includes(ext.substring(1))) {
|
|
95
99
|
throw new BadRequestError("file extension is not allowed");
|
|
@@ -119,7 +123,6 @@ export async function uploadMultiPart(req, { extensions, raw, subdir, originalFi
|
|
|
119
123
|
if (fileExtension !== nameExt) {
|
|
120
124
|
throw new ConflictError("file type spoofing attempt detected");
|
|
121
125
|
}
|
|
122
|
-
const dir = subdir != null ? subdir : req.params?.["*"] || "uploads";
|
|
123
126
|
const yearMonthDay = subdir != null ? "" : new Date().toISOString().split("T")[0];
|
|
124
127
|
const dbname = req.pg?.options?.database || req.pg?.database || config.pg?.database; // request / config params / default config params
|
|
125
128
|
const rootDir = config.root || `/data/local/${dbname || ""}`;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"checkPolicy.d.ts","sourceRoot":"","sources":["../../../../../server/plugins/policy/funcs/checkPolicy.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAEV,eAAe,EAEhB,MAAM,wBAAwB,CAAC;AAKhC,MAAM,CAAC,OAAO,UAAU,WAAW,CAAC,GAAG,EAAE,eAAe,EAAE,GAAG,CAAC,EAAE,GAAG,
|
|
1
|
+
{"version":3,"file":"checkPolicy.d.ts","sourceRoot":"","sources":["../../../../../server/plugins/policy/funcs/checkPolicy.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAEV,eAAe,EAEhB,MAAM,wBAAwB,CAAC;AAKhC,MAAM,CAAC,OAAO,UAAU,WAAW,CAAC,GAAG,EAAE,eAAe,EAAE,GAAG,CAAC,EAAE,GAAG,QAkIlE"}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { config, logger } from "../../../../utils.js";
|
|
2
|
-
import {
|
|
2
|
+
import { ForbiddenError } from "../../../../errors.js";
|
|
3
3
|
export default function checkPolicy(req, jwt) {
|
|
4
4
|
const { originalUrl: path, hostname, query, params, headers, method, routeOptions, } = req;
|
|
5
5
|
const user = req.user || req.session?.passport?.user;
|
|
@@ -12,7 +12,7 @@ export default function checkPolicy(req, jwt) {
|
|
|
12
12
|
hostname.startsWith("admin");
|
|
13
13
|
const { role, referer, policy = [], } = (routeOptions?.config || {});
|
|
14
14
|
// role=admin|regular
|
|
15
|
-
const isRole = (role && (!user?.user_type || !
|
|
15
|
+
const isRole = (role && (!user?.user_type || !user?.user_type?.includes?.(role))) ||
|
|
16
16
|
(policy.includes("admin") && !user?.user_type?.includes?.("admin"));
|
|
17
17
|
const allowExtPublic = [".png", ".jpg", ".svg"];
|
|
18
18
|
const ext = path.toLowerCase().substr(-4);
|
|
@@ -47,20 +47,6 @@ export default function checkPolicy(req, jwt) {
|
|
|
47
47
|
});
|
|
48
48
|
throw ForbiddenError("access restricted: 0");
|
|
49
49
|
}
|
|
50
|
-
// ! file injection
|
|
51
|
-
if (JSON.stringify(params || {})?.includes("../") ||
|
|
52
|
-
JSON.stringify(query || {})?.includes("../") ||
|
|
53
|
-
path?.includes("../")) {
|
|
54
|
-
logger.file("injection/file", {
|
|
55
|
-
path,
|
|
56
|
-
method,
|
|
57
|
-
params,
|
|
58
|
-
query,
|
|
59
|
-
body,
|
|
60
|
-
uid: user?.uid,
|
|
61
|
-
});
|
|
62
|
-
throw ConflictError("access restricted: 1");
|
|
63
|
-
}
|
|
64
50
|
// ! invalid file extension
|
|
65
51
|
if (path.includes("files/") && allowExtPublic.includes(ext)) {
|
|
66
52
|
return null;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"checkTraversal.d.ts","sourceRoot":"","sources":["../../../../../server/plugins/policy/funcs/checkTraversal.ts"],"names":[],"mappings":"AAUA,MAAM,CAAC,OAAO,UAAU,cAAc,CAAC,OAAO,EAAE,GAAG,QAgBlD"}
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
import { logger } from "../../../../utils.js";
|
|
2
|
+
import { ConflictError } from "../../../../errors.js";
|
|
3
|
+
const decodeTraversal = (str) => str
|
|
4
|
+
.replace(/%2e/g, ".")
|
|
5
|
+
.replace(/%2E/g, ".")
|
|
6
|
+
.replace(/%2f/g, "/")
|
|
7
|
+
.replace(/%2F/g, "/");
|
|
8
|
+
export default function checkTraversal(request) {
|
|
9
|
+
const { method, originalUrl, query, params, user } = request;
|
|
10
|
+
if (decodeTraversal(JSON.stringify(params || {})).includes("../") ||
|
|
11
|
+
decodeTraversal(JSON.stringify(query || {})).includes("../") ||
|
|
12
|
+
decodeTraversal(originalUrl).includes("../")) {
|
|
13
|
+
logger.file("injection/file", {
|
|
14
|
+
path: originalUrl,
|
|
15
|
+
method,
|
|
16
|
+
params,
|
|
17
|
+
query,
|
|
18
|
+
uid: user?.uid,
|
|
19
|
+
});
|
|
20
|
+
throw ConflictError("path traversal detected");
|
|
21
|
+
}
|
|
22
|
+
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../server/plugins/policy/index.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../server/plugins/policy/index.ts"],"names":[],"mappings":"AAOA,iBAAS,MAAM,CAAC,OAAO,EAAE,GAAG,QA+B3B;AAED,eAAe,MAAM,CAAC"}
|
|
@@ -1,9 +1,11 @@
|
|
|
1
1
|
import config from "../../../config.js";
|
|
2
2
|
import checkPolicy from "./funcs/checkPolicy.js";
|
|
3
|
+
import checkTraversal from "./funcs/checkTraversal.js";
|
|
3
4
|
import checkPermissions from "./funcs/checkPermissions.js";
|
|
4
5
|
import checkJWT from "./funcs/checkJWT.js";
|
|
5
6
|
function plugin(fastify) {
|
|
6
|
-
fastify.addHook("preHandler", async (request
|
|
7
|
+
fastify.addHook("preHandler", async (request) => {
|
|
8
|
+
checkTraversal(request);
|
|
7
9
|
// ! skip locally, skip tests
|
|
8
10
|
if ((process.env.local === "true" || process.env.NODE_ENV === "test") &&
|
|
9
11
|
!config.debugAuth &&
|
|
@@ -12,10 +12,10 @@ export default async function getSelect(name, pg = pgClients.client, nocache = f
|
|
|
12
12
|
return loadCls[name];
|
|
13
13
|
}
|
|
14
14
|
const clsDataGIT = await getTemplate(["cls", "select"], name);
|
|
15
|
-
const { type } = pg.pk?.["admin.user_cls"]
|
|
15
|
+
const { type } = pg.pk?.["admin.user_cls"]
|
|
16
16
|
? await pg
|
|
17
|
-
.query("select type from admin.user_cls where parent is null and name=$1 union all select type from admin.cls where parent is null and name=$1 limit 1", [name])
|
|
18
|
-
.then((
|
|
17
|
+
.query("select type from admin.user_cls where parent is null and name=$1 and type<>'sql' union all select type from admin.cls where parent is null and name=$1 and type<>'sql' limit 1", [name])
|
|
18
|
+
.then((r) => r.rows?.[0] || {})
|
|
19
19
|
: {};
|
|
20
20
|
const clsDataDB = sqls[type || ""]
|
|
21
21
|
? await pg
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"startUpload.d.ts","sourceRoot":"","sources":["../../../../server/plugins/upload/startUpload.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"startUpload.d.ts","sourceRoot":"","sources":["../../../../server/plugins/upload/startUpload.ts"],"names":[],"mappings":"AAyBA,wBAA8B,WAAW,CAAC,EACxC,IAAI,EACJ,EAAE,EACF,QAAQ,EACR,IAAI,EACJ,MAAM,EACN,gBAAwB,GACzB,EAAE;IACD,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,EAAE,CAAC,EAAE,MAAM,CAAC;IACZ,QAAQ,EAAE,MAAM,CAAC;IACjB,IAAI,EAAE,MAAM,CAAC;IACb,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,gBAAgB,CAAC,EAAE,OAAO,CAAC;CAC5B,gBA2GA"}
|
|
@@ -4,20 +4,29 @@ import { mkdir, writeFile } from "node:fs/promises";
|
|
|
4
4
|
import config from "../../../config.js";
|
|
5
5
|
import getUploadStatus from "./getUploadStatus.js";
|
|
6
6
|
import { prefix, fileDir, metaDir, uploadChunkDirectory, fetchTimeoutMs, } from "./index.js";
|
|
7
|
+
import { all } from "../file/utils/allowedExtensions.js";
|
|
7
8
|
import mimes from "../file/providers/mime/mimes.js";
|
|
8
9
|
import { startUpload as startUploadS3 } from "./s3.js";
|
|
9
|
-
import { BadRequestError, NotImplementedError } from "../../../errors.js";
|
|
10
|
+
import { BadRequestError, ForbiddenError, NotImplementedError, } from "../../../errors.js";
|
|
10
11
|
const { chunkSize = 5242880 } = config;
|
|
11
12
|
export default async function startUpload({ host, id, fileName, size, subdir, originalFilename = false, }) {
|
|
12
|
-
if (subdir &&
|
|
13
|
+
if (subdir &&
|
|
14
|
+
(typeof subdir !== "string" ||
|
|
15
|
+
subdir.replace(/%2e/g, ".").replace(/%2E/g, ".").includes(".."))) {
|
|
13
16
|
throw BadRequestError("invalid params: subdir");
|
|
14
17
|
}
|
|
15
18
|
if (originalFilename) {
|
|
16
19
|
throw NotImplementedError("currently not supported");
|
|
17
20
|
}
|
|
21
|
+
if (!fileName) {
|
|
22
|
+
throw BadRequestError("not enough params: fileName");
|
|
23
|
+
}
|
|
24
|
+
const extension = path.extname(fileName).substring(1);
|
|
25
|
+
if (!all.includes(extension)) {
|
|
26
|
+
throw ForbiddenError("file extension is not allowed");
|
|
27
|
+
}
|
|
18
28
|
if (!host) {
|
|
19
29
|
const id1 = id || randomUUID();
|
|
20
|
-
const extension = path.extname(fileName).substring(1);
|
|
21
30
|
const yearMonthDay = subdir ? "" : new Date().toISOString().split("T")[0];
|
|
22
31
|
const relativeDirpath = path
|
|
23
32
|
.join(uploadChunkDirectory, subdir || "", yearMonthDay || "")
|
|
@@ -29,12 +29,11 @@ export declare function editUserCls({ name, alias, description, data, }: {
|
|
|
29
29
|
alias?: string[];
|
|
30
30
|
data: string | Record<string, any>[];
|
|
31
31
|
}, pg?: any): Promise<string>;
|
|
32
|
-
export declare function getUserClsList({ name, search, sql, custom,
|
|
32
|
+
export declare function getUserClsList({ name, search, sql, custom, }: {
|
|
33
33
|
name?: string;
|
|
34
34
|
search?: string;
|
|
35
35
|
sql?: any;
|
|
36
36
|
custom?: string;
|
|
37
|
-
type?: string;
|
|
38
37
|
}, pg?: any): Promise<any>;
|
|
39
38
|
export declare function getUserCls(name: string, pg?: any): Promise<{
|
|
40
39
|
type: any;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../server/plugins/usercls/index.ts"],"names":[],"mappings":"AAMA,wBAAsB,YAAY,CAChC,EACE,IAAI,EACJ,WAAW,EACX,KAAK,EACL,KAAK,EACL,GAAG,EACH,IAAS,GACV,EAAE;IACD,IAAI,EAAE,MAAM,CAAC;IACb,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,KAAK,CAAC,EAAE,MAAM,EAAE,CAAC;IACjB,KAAK,EAAE,MAAM,CAAC;IACd,GAAG,EAAE,MAAM,CAAC;IACZ,IAAI,EAAE;QACJ,EAAE,CAAC,EAAE,MAAM,GAAG,MAAM,CAAC;QACrB,IAAI,EAAE,MAAM,CAAC;QACb,WAAW,CAAC,EAAE,MAAM,CAAC;QACrB,KAAK,CAAC,EAAE,MAAM,CAAC;QACf,IAAI,CAAC,EAAE,MAAM,CAAC;QACd,MAAM,CAAC,EAAE,OAAO,CAAC;KAClB,EAAE,CAAC;CACL,EACD,EAAE,MAAmB,mBA8EtB;AAED,wBAAsB,aAAa,CACjC,EAAE,IAAI,EAAE,IAAI,EAAE,EAAE;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,IAAI,CAAC,EAAE,MAAM,CAAA;CAAE,EAC/C,EAAE,MAAmB,mBAgBtB;AAED,wBAAsB,UAAU,CAC9B,EACE,IAAI,EACJ,KAAK,EACL,IAAI,EACJ,WAAW,GACZ,EAAE;IACD,IAAI,EAAE,MAAM,CAAC;IACb,KAAK,CAAC,EAAE,MAAM,EAAE,CAAC;IACjB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,IAAI,EAAE,MAAM,GAAG,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,EAAE,CAAC;CACtC,EACD,EAAE,MAAmB,
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../server/plugins/usercls/index.ts"],"names":[],"mappings":"AAMA,wBAAsB,YAAY,CAChC,EACE,IAAI,EACJ,WAAW,EACX,KAAK,EACL,KAAK,EACL,GAAG,EACH,IAAS,GACV,EAAE;IACD,IAAI,EAAE,MAAM,CAAC;IACb,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,KAAK,CAAC,EAAE,MAAM,EAAE,CAAC;IACjB,KAAK,EAAE,MAAM,CAAC;IACd,GAAG,EAAE,MAAM,CAAC;IACZ,IAAI,EAAE;QACJ,EAAE,CAAC,EAAE,MAAM,GAAG,MAAM,CAAC;QACrB,IAAI,EAAE,MAAM,CAAC;QACb,WAAW,CAAC,EAAE,MAAM,CAAC;QACrB,KAAK,CAAC,EAAE,MAAM,CAAC;QACf,IAAI,CAAC,EAAE,MAAM,CAAC;QACd,MAAM,CAAC,EAAE,OAAO,CAAC;KAClB,EAAE,CAAC;CACL,EACD,EAAE,MAAmB,mBA8EtB;AAED,wBAAsB,aAAa,CACjC,EAAE,IAAI,EAAE,IAAI,EAAE,EAAE;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,IAAI,CAAC,EAAE,MAAM,CAAA;CAAE,EAC/C,EAAE,MAAmB,mBAgBtB;AAED,wBAAsB,UAAU,CAC9B,EACE,IAAI,EACJ,KAAK,EACL,IAAI,EACJ,WAAW,GACZ,EAAE;IACD,IAAI,EAAE,MAAM,CAAC;IACb,KAAK,CAAC,EAAE,MAAM,EAAE,CAAC;IACjB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,IAAI,EAAE,MAAM,GAAG,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,EAAE,CAAC;CACtC,EACD,EAAE,MAAmB,mBAwDtB;AAED,wBAAsB,WAAW,CAC/B,EACE,IAAI,EACJ,KAAK,EACL,WAAW,EACX,IAAI,GACL,EAAE;IACD,IAAI,EAAE,MAAM,CAAC;IACb,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,KAAK,CAAC,EAAE,MAAM,EAAE,CAAC;IACjB,IAAI,EAAE,MAAM,GAAG,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,EAAE,CAAC;CACtC,EACD,EAAE,MAAmB,mBAKtB;AAED,wBAAsB,cAAc,CAClC,EACE,IAAI,EACJ,MAAM,EACN,GAAG,EACH,MAAM,GACP,EAAE;IACD,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,GAAG,CAAC,EAAE,GAAG,CAAC;IACV,MAAM,CAAC,EAAE,MAAM,CAAC;CAEjB,EACD,EAAE,MAAmB,gBA0DtB;AAED,wBAAsB,UAAU,CAAC,IAAI,EAAE,MAAM,EAAE,EAAE,MAAmB;;;;;UAuBnE;;AAED,wBAAoB"}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { NotFoundError } from "../../../errors.js";
|
|
1
|
+
import { ForbiddenError, NotFoundError } from "../../../errors.js";
|
|
2
2
|
import pgClients from "../pg/pgClients.js";
|
|
3
3
|
import dataInsert from "../crud/funcs/dataInsert.js";
|
|
4
4
|
import dataUpdate from "../crud/funcs/dataUpdate.js";
|
|
@@ -8,10 +8,10 @@ export async function addCustomCls({ name, description, alias, table, uid, data
|
|
|
8
8
|
}
|
|
9
9
|
const codes = await pg
|
|
10
10
|
.query(`select array_agg(code) from ${table}`)
|
|
11
|
-
.then((
|
|
11
|
+
.then((r) => r.rows?.[0]?.array_agg || []);
|
|
12
12
|
const ids = await pg
|
|
13
13
|
.query(`select json_object_agg(code, id) from ${table}`)
|
|
14
|
-
.then((
|
|
14
|
+
.then((r) => r.rows?.[0]?.json_object_agg || {});
|
|
15
15
|
const client = await pg.connect();
|
|
16
16
|
try {
|
|
17
17
|
await client.query("BEGIN");
|
|
@@ -88,6 +88,7 @@ export async function addUserCls({ name, alias, data, description, }, pg = pgCli
|
|
|
88
88
|
try {
|
|
89
89
|
await client.query("begin");
|
|
90
90
|
if (type === "sql") {
|
|
91
|
+
throw ForbiddenError("access restricted: creation of custom selects is not allowed");
|
|
91
92
|
await dataInsert({
|
|
92
93
|
pg: client,
|
|
93
94
|
table: "admin.user_cls",
|
|
@@ -126,23 +127,29 @@ export async function editUserCls({ name, alias, description, data, }, pg = pgCl
|
|
|
126
127
|
await addUserCls({ name, alias, description, data }, pg);
|
|
127
128
|
return "ok";
|
|
128
129
|
}
|
|
129
|
-
export async function getUserClsList({ name, search, sql, custom,
|
|
130
|
-
const args = [
|
|
131
|
-
const
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
name
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
130
|
+
export async function getUserClsList({ name, search, sql, custom, }, pg = pgClients.client) {
|
|
131
|
+
const args = [];
|
|
132
|
+
const where = [];
|
|
133
|
+
if (name) {
|
|
134
|
+
args.push(name.split(","));
|
|
135
|
+
where.push(`name=any($${args.length}::text[])`);
|
|
136
|
+
}
|
|
137
|
+
if (search) {
|
|
138
|
+
args.push(`%${search}%`);
|
|
139
|
+
where.push(`( name ilike $${args.length} or name in (select parent from admin.user_cls where name ilike $${args.length}) )`);
|
|
140
|
+
}
|
|
141
|
+
// const typeStr = type ? { cls: "json", select: "sql" }[type] : null;
|
|
142
|
+
const typeStr = "json";
|
|
143
|
+
if (typeStr) {
|
|
144
|
+
args.push(typeStr);
|
|
145
|
+
where.push(`type=$${args.length}`);
|
|
146
|
+
}
|
|
147
|
+
const whereQuery = where.join(" and ") || "1=1";
|
|
148
|
+
console.log(name, search, whereQuery);
|
|
142
149
|
const customQuery = `select true as custom, name, type, description, alias, case when type = 'sql' then 1 else (select count(*) from admin.user_cls where parent=t.name limit 1) end as count
|
|
143
|
-
from admin.user_cls t where parent is null and ${
|
|
150
|
+
from admin.user_cls t where parent is null and ${whereQuery}`;
|
|
144
151
|
const gitQuery = `select false as custom, name, type, null as description, null as alias, case when type = 'sql' then 1 else (select count(*) from admin.cls where parent=t.name limit 1) end as count
|
|
145
|
-
from admin.cls t where parent is null and ${
|
|
152
|
+
from admin.cls t where parent is null and ${whereQuery.replace(/admin.user_cls/g, "admin.cls")}`;
|
|
146
153
|
const q = [
|
|
147
154
|
custom !== "0" ? customQuery : null,
|
|
148
155
|
custom !== "1" ? gitQuery : null,
|
|
@@ -152,7 +159,7 @@ export async function getUserClsList({ name, search, sql, custom, type, }, pg =
|
|
|
152
159
|
.concat(" order by name");
|
|
153
160
|
if (sql)
|
|
154
161
|
return q;
|
|
155
|
-
const rows = await pg.query(q, args).then((
|
|
162
|
+
const rows = await pg.query(q, args).then((r) => r.rows || []);
|
|
156
163
|
const customRows = rows.filter((row) => row.custom);
|
|
157
164
|
const customClsNames = customRows.map((row) => row.name);
|
|
158
165
|
const filteredRows = rows.filter((row) => !customClsNames.includes(row.name));
|
|
@@ -161,14 +168,15 @@ export async function getUserClsList({ name, search, sql, custom, type, }, pg =
|
|
|
161
168
|
export async function getUserCls(name, pg = pgClients.client) {
|
|
162
169
|
const { type, data, description, alias } = await pg
|
|
163
170
|
.query("select type, data, description, alias from admin.user_cls where parent is null and name=$1", [name])
|
|
164
|
-
.then((
|
|
171
|
+
.then((r) => r.rows?.[0] || {});
|
|
165
172
|
if (type === "sql") {
|
|
173
|
+
throw ForbiddenError("custom selects not allowed");
|
|
166
174
|
return { type, data, description, alias };
|
|
167
175
|
}
|
|
168
176
|
if (type === "json") {
|
|
169
177
|
const options = await pg
|
|
170
178
|
.query(`select json_agg(json_build_object('id', code, 'text', name, 'icon', icon, 'color', color)) from admin.user_cls where parent=$1`, [name])
|
|
171
|
-
.then((
|
|
179
|
+
.then((r) => r.rows?.[0]?.json_agg || []);
|
|
172
180
|
return { type, data: options, description, alias };
|
|
173
181
|
}
|
|
174
182
|
return null;
|
|
@@ -13,5 +13,8 @@ export default function resize({ query, }: {
|
|
|
13
13
|
format?: string;
|
|
14
14
|
noimage?: any;
|
|
15
15
|
};
|
|
16
|
-
}, reply: FastifyReply): Promise<
|
|
16
|
+
}, reply: FastifyReply): Promise<import("fastify").FastifyError & {
|
|
17
|
+
code: "NOT_FOUND_ERROR";
|
|
18
|
+
statusCode: 404;
|
|
19
|
+
}>;
|
|
17
20
|
//# sourceMappingURL=resize.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"resize.d.ts","sourceRoot":"","sources":["../../../../../server/routes/file/controllers/resize.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,SAAS,CAAC;AA0C5C;;GAEG;AAEH,wBAA8B,MAAM,CAClC,EACE,KAAK,GACN,EAAE;IACD,KAAK,EAAE;QACL,QAAQ,EAAE,MAAM,CAAC;QACjB,OAAO,CAAC,EAAE,MAAM,GAAG,MAAM,CAAC;QAC1B,IAAI,EAAE,MAAM,CAAC;QACb,CAAC,CAAC,EAAE,MAAM,CAAC;QACX,CAAC,CAAC,EAAE,MAAM,CAAC;QACX,OAAO,CAAC,EAAE,GAAG,CAAC;QACd,MAAM,CAAC,EAAE,MAAM,CAAC;QAChB,OAAO,CAAC,EAAE,GAAG,CAAC;KACf,CAAC;CACH,EACD,KAAK,EAAE,YAAY
|
|
1
|
+
{"version":3,"file":"resize.d.ts","sourceRoot":"","sources":["../../../../../server/routes/file/controllers/resize.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,SAAS,CAAC;AA0C5C;;GAEG;AAEH,wBAA8B,MAAM,CAClC,EACE,KAAK,GACN,EAAE;IACD,KAAK,EAAE;QACL,QAAQ,EAAE,MAAM,CAAC;QACjB,OAAO,CAAC,EAAE,MAAM,GAAG,MAAM,CAAC;QAC1B,IAAI,EAAE,MAAM,CAAC;QACb,CAAC,CAAC,EAAE,MAAM,CAAC;QACX,CAAC,CAAC,EAAE,MAAM,CAAC;QACX,OAAO,CAAC,EAAE,GAAG,CAAC;QACd,MAAM,CAAC,EAAE,MAAM,CAAC;QAChB,OAAO,CAAC,EAAE,GAAG,CAAC;KACf,CAAC;CACH,EACD,KAAK,EAAE,YAAY;;;GAyJpB"}
|
|
@@ -8,7 +8,7 @@ isFileExists, getFolder, } from "../../../../utils.js";
|
|
|
8
8
|
import grpc from "../../../plugins/grpc/grpc.js";
|
|
9
9
|
import getMimeType from "../../../plugins/file/providers/mime/index.js";
|
|
10
10
|
import { mkdir } from "node:fs/promises";
|
|
11
|
-
import { BadRequestError } from "../../../../errors.js";
|
|
11
|
+
import { BadRequestError, NotFoundError } from "../../../../errors.js";
|
|
12
12
|
const defaultWidth = 400;
|
|
13
13
|
const defaultHeight = 240;
|
|
14
14
|
const maxWidth = 2000;
|
|
@@ -38,6 +38,19 @@ export default async function resize({ query, }, reply) {
|
|
|
38
38
|
if (!mimeType) {
|
|
39
39
|
throw BadRequestError("invalid query params: filepath");
|
|
40
40
|
}
|
|
41
|
+
// svg не підтримується
|
|
42
|
+
if (mimeType === "image/svg+xml") {
|
|
43
|
+
const fileData = await downloadFile(filepath, { buffer: true });
|
|
44
|
+
if (!fileData?.length) {
|
|
45
|
+
return NotFoundError(`Файл не знайдено - ${filepath}`);
|
|
46
|
+
}
|
|
47
|
+
return reply
|
|
48
|
+
.headers({
|
|
49
|
+
"Content-Type": "image/svg+xml",
|
|
50
|
+
"Cache-control": "max-age=604800",
|
|
51
|
+
})
|
|
52
|
+
.send(fileData);
|
|
53
|
+
}
|
|
41
54
|
const resizePath1 = size
|
|
42
55
|
? filepath.replace(basename, `${size}_resized_${basename}`)
|
|
43
56
|
: filepath.replace(basename, `${w || defaultWidth}_${h || (w ? "" : defaultHeight)}_resized_${basename}`);
|
|
@@ -1,6 +1,5 @@
|
|
|
1
1
|
/* eslint-disable no-param-reassign */
|
|
2
2
|
import path from "node:path";
|
|
3
|
-
import config from "../../../../config.js";
|
|
4
3
|
import { handlebars, handlebarsSync } from "../../../helpers/index.js";
|
|
5
4
|
import getAccess from "../../../plugins/crud/funcs/getAccess.js";
|
|
6
5
|
import setToken from "../../../plugins/crud/funcs/setToken.js";
|
|
@@ -80,8 +79,9 @@ export default async function getCardData(req, reply) {
|
|
|
80
79
|
}
|
|
81
80
|
// tokens result
|
|
82
81
|
const tokens = {};
|
|
83
|
-
if (
|
|
84
|
-
|
|
82
|
+
if (
|
|
83
|
+
// !config.security?.disableToken &&
|
|
84
|
+
index?.tokens &&
|
|
85
85
|
typeof index?.tokens === "object" &&
|
|
86
86
|
!Array.isArray(index?.tokens)) {
|
|
87
87
|
Object.keys(index.tokens || {})
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"suggest.d.ts","sourceRoot":"","sources":["../../../../../server/routes/table/controllers/suggest.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,MAAM,wBAAwB,CAAC;
|
|
1
|
+
{"version":3,"file":"suggest.d.ts","sourceRoot":"","sources":["../../../../../server/routes/table/controllers/suggest.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,MAAM,wBAAwB,CAAC;AAyBpD,wBAAsB,kBAAkB,CAAC,EACvC,KAAK,EACL,QAAQ,EACR,MAAM,EACN,UAAU,EACV,QAAQ,EACR,UAAU,EACV,GAAG,EACH,EAAqB,GACtB,EAAE;IACD,KAAK,EAAE,MAAM,CAAC;IACd,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,MAAM,EAAE,GAAG,CAAC;IACZ,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,QAAQ,CAAC,EAAE,GAAG,CAAC;IACf,UAAU,CAAC,EAAE,OAAO,CAAC;IACrB,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,EAAE,CAAC,EAAE,UAAU,CAAC;CACjB;;;;;UAwFA;AAED,wBAA8B,OAAO,CAAC,GAAG,EAAE,GAAG,gBAoa7C"}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import path from "node:path";
|
|
2
2
|
import { existsSync, readFileSync } from "node:fs";
|
|
3
|
-
import { config, getPGAsync, getTemplate, getSelectMeta, getMeta, applyHook, getSelectVal, logger, getSelect, metaFormat, getColumnCLS, pgClients, getFilter, } from "../../../../utils.js";
|
|
3
|
+
import { config, getPGAsync, getTemplate, getSelectMeta, getMeta, applyHook, getSelectVal, logger, getSelect, metaFormat, getColumnCLS, pgClients, getFilter, getUserClsList, } from "../../../../utils.js";
|
|
4
4
|
import { BadRequestError, NotFoundError } from "../../../../errors.js";
|
|
5
5
|
const defaultLimit = 50;
|
|
6
6
|
export async function getTableColumnMeta({ table, template, column, selectName, filtered, startsWith, key, pg = pgClients.client, }) {
|
|
@@ -91,6 +91,22 @@ export default async function suggest(req) {
|
|
|
91
91
|
table,
|
|
92
92
|
})) || {}
|
|
93
93
|
: {};
|
|
94
|
+
if (params.data === "list" &&
|
|
95
|
+
(user?.user_type === "admin" || process.platform === "win32")) {
|
|
96
|
+
const cls = await getTemplate("cls", "list");
|
|
97
|
+
const select = await getTemplate("select", "list");
|
|
98
|
+
const custom = await getUserClsList({ custom: "1" }).then((r) => (r || []).reduce((acc, curr) => ({
|
|
99
|
+
...acc,
|
|
100
|
+
[curr.name]: curr.type,
|
|
101
|
+
}), {}));
|
|
102
|
+
return {
|
|
103
|
+
git: (cls || []).concat(select || []).reduce((acc, curr) => ({
|
|
104
|
+
...acc,
|
|
105
|
+
[curr[0]]: curr[2],
|
|
106
|
+
}), {}),
|
|
107
|
+
custom,
|
|
108
|
+
};
|
|
109
|
+
}
|
|
94
110
|
const body = await getTemplate("table", table);
|
|
95
111
|
const tableName = hookBody?.table || body?.table || table;
|
|
96
112
|
if (query.limit && query.limit < 0) {
|
|
@@ -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;AAwFzD,wBAA8B,OAAO,CACnC,EACE,EAAqB,EACrB,MAAM,EACN,KAAK,EACL,EAAE,EACF,OAAY,EACZ,KAAU,EACV,IAAS,EACT,YAAY,EACZ,YAAY,EACZ,KAAY,EACZ,UAAU,EACV,OAAO,EAAE,YAAY,EACrB,WAAW,EAAE,gBAAgB,EAC7B,OAAO,EAAE,YAAY,EACrB,QAAgB,GACjB,EAAE;IACD,EAAE,CAAC,EAAE,UAAU,CAAC;IAChB,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,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,CAAC;IAC9B,KAAK,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,CAAC;IAC5B,IAAI,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,CAAC;IAC3B,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,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;IACnB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,OAAO,CAAC,EAAE,MAAM,EAAE,CAAC;IACnB,QAAQ,CAAC,EAAE,OAAO,CAAC;CACpB,EACD,KAAK,CAAC,EAAE,YAAY,EACpB,MAAM,CAAC,EAAE,GAAG,
|
|
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;AAwFzD,wBAA8B,OAAO,CACnC,EACE,EAAqB,EACrB,MAAM,EACN,KAAK,EACL,EAAE,EACF,OAAY,EACZ,KAAU,EACV,IAAS,EACT,YAAY,EACZ,YAAY,EACZ,KAAY,EACZ,UAAU,EACV,OAAO,EAAE,YAAY,EACrB,WAAW,EAAE,gBAAgB,EAC7B,OAAO,EAAE,YAAY,EACrB,QAAgB,GACjB,EAAE;IACD,EAAE,CAAC,EAAE,UAAU,CAAC;IAChB,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,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,CAAC;IAC9B,KAAK,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,CAAC;IAC5B,IAAI,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,CAAC;IAC3B,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,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;IACnB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,OAAO,CAAC,EAAE,MAAM,EAAE,CAAC;IACnB,QAAQ,CAAC,EAAE,OAAO,CAAC;CACpB,EACD,KAAK,CAAC,EAAE,YAAY,EACpB,MAAM,CAAC,EAAE,GAAG,gBAw4Bb"}
|
|
@@ -209,14 +209,14 @@ export default async function dataAPI({ pg = pgClients.client, params, table, id
|
|
|
209
209
|
!el.inline &&
|
|
210
210
|
el?.sql?.replace &&
|
|
211
211
|
!(isExport && el.export === false))
|
|
212
|
-
.map((el, i) => ` left join lateral (${el.sql
|
|
212
|
+
.map((el, i) => ` left join lateral (${el.sql}) ${el.name || `t${i}`} on 1=1 `)
|
|
213
213
|
?.join("") || "";
|
|
214
214
|
const cardSqlFiltered = objectId
|
|
215
215
|
? cardSql?.filter?.((el) => !el?.disabled && el?.name && el?.sql?.replace) || []
|
|
216
216
|
: [];
|
|
217
217
|
const cardSqlTable = cardSqlFiltered.length
|
|
218
218
|
? cardSqlFiltered
|
|
219
|
-
.map((el, i) => ` left join lateral (${el.sql
|
|
219
|
+
.map((el, i) => ` left join lateral (${el.sql}) ct${i} on 1=1 `)
|
|
220
220
|
.join("\n") || ""
|
|
221
221
|
: "";
|
|
222
222
|
const sqlInline = loadTable?.sql
|
|
@@ -385,7 +385,7 @@ export default async function dataAPI({ pg = pgClients.client, params, table, id
|
|
|
385
385
|
timeArr.push(Date.now());
|
|
386
386
|
if (uid &&
|
|
387
387
|
rows.length &&
|
|
388
|
-
!config.security?.disableToken &&
|
|
388
|
+
// !config.security?.disableToken &&
|
|
389
389
|
(editable ||
|
|
390
390
|
(tokenData?.actions || actionsParam)?.includes("edit") ||
|
|
391
391
|
actions.includes("edit") ||
|
|
@@ -507,8 +507,9 @@ export default async function dataAPI({ pg = pgClients.client, params, table, id
|
|
|
507
507
|
const tokens = {};
|
|
508
508
|
if (template && objectId) {
|
|
509
509
|
// tokens result
|
|
510
|
-
if (
|
|
511
|
-
|
|
510
|
+
if (
|
|
511
|
+
// !config.security?.disableToken &&
|
|
512
|
+
index?.tokens &&
|
|
512
513
|
typeof index?.tokens === "object" &&
|
|
513
514
|
!Array.isArray(index?.tokens)) {
|
|
514
515
|
Object.keys(index.tokens || {})
|
|
@@ -682,7 +683,7 @@ export default async function dataAPI({ pg = pgClients.client, params, table, id
|
|
|
682
683
|
});
|
|
683
684
|
}
|
|
684
685
|
if (uid &&
|
|
685
|
-
!config.security?.disableToken &&
|
|
686
|
+
// !config.security?.disableToken &&
|
|
686
687
|
actions.includes("add") &&
|
|
687
688
|
!objectId) {
|
|
688
689
|
const addTokens = setToken({
|
|
@@ -1,2 +1,9 @@
|
|
|
1
|
-
export default function addUserClsApi({ pg, body, user }: any
|
|
1
|
+
export default function addUserClsApi({ pg, body, user, }: any): Promise<{
|
|
2
|
+
type?: any;
|
|
3
|
+
data?: any;
|
|
4
|
+
description?: any;
|
|
5
|
+
alias?: any;
|
|
6
|
+
time: number;
|
|
7
|
+
name: any;
|
|
8
|
+
}>;
|
|
2
9
|
//# sourceMappingURL=addUserCls.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"addUserCls.d.ts","sourceRoot":"","sources":["../../../../../server/routes/usercls/controllers/addUserCls.ts"],"names":[],"mappings":"AAWA,wBAA8B,aAAa,
|
|
1
|
+
{"version":3,"file":"addUserCls.d.ts","sourceRoot":"","sources":["../../../../../server/routes/usercls/controllers/addUserCls.ts"],"names":[],"mappings":"AAWA,wBAA8B,aAAa,CAAC,EAC1C,EAAqB,EACrB,IAAI,EACJ,IAAI,GACL,EAAE,GAAG;;;;;;;GAkCL"}
|
|
@@ -2,7 +2,7 @@ import { UnauthorizedError } from "../../../../errors.js";
|
|
|
2
2
|
import pgClients from "../../../plugins/pg/pgClients.js";
|
|
3
3
|
import getSelectMeta from "../../../plugins/table/funcs/getSelectMeta.js";
|
|
4
4
|
import { addUserCls, addCustomCls, editUserCls, getUserCls, } from "../../../plugins/usercls/index.js";
|
|
5
|
-
export default async function addUserClsApi({ pg = pgClients.client, body, user }
|
|
5
|
+
export default async function addUserClsApi({ pg = pgClients.client, body, user, }) {
|
|
6
6
|
const { name, description, alias, data, table } = body;
|
|
7
7
|
const t1 = Date.now();
|
|
8
8
|
if (!user?.uid) {
|
|
@@ -10,9 +10,7 @@ export default async function addUserClsApi({ pg = pgClients.client, body, user
|
|
|
10
10
|
}
|
|
11
11
|
if (table) {
|
|
12
12
|
await addCustomCls({ name, description, alias, table, uid: user.uid, data }, pg);
|
|
13
|
-
return
|
|
14
|
-
.status(200)
|
|
15
|
-
.send({ time: Date.now() - t1, name, type: "custom" });
|
|
13
|
+
return { time: Date.now() - t1, name, type: "custom" };
|
|
16
14
|
}
|
|
17
15
|
const exists = await getUserCls(name, pg);
|
|
18
16
|
if (exists) {
|
|
@@ -28,5 +26,5 @@ export default async function addUserClsApi({ pg = pgClients.client, body, user
|
|
|
28
26
|
nocache: 1,
|
|
29
27
|
});
|
|
30
28
|
const result = await getUserCls(name, pg);
|
|
31
|
-
return
|
|
29
|
+
return { time: Date.now() - t1, name, ...result };
|
|
32
30
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"getUserCls.d.ts","sourceRoot":"","sources":["../../../../../server/routes/usercls/controllers/getUserCls.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"getUserCls.d.ts","sourceRoot":"","sources":["../../../../../server/routes/usercls/controllers/getUserCls.ts"],"names":[],"mappings":"AAaA,wBAA8B,iBAAiB,CAAC,EAC9C,KAAK,EACL,IAAI,EACJ,EAAqB,GACtB,EAAE,GAAG,gBA2CL"}
|
|
@@ -2,6 +2,8 @@ import config from "../../../../config.js";
|
|
|
2
2
|
import { UnauthorizedError } from "../../../../errors.js";
|
|
3
3
|
import pgClients from "../../../plugins/pg/pgClients.js";
|
|
4
4
|
import { getUserClsList } from "../../../plugins/usercls/index.js";
|
|
5
|
+
const customQueryCount = "select count(*)from admin.user_cls t where parent is null and type<>'sql'";
|
|
6
|
+
const gitQueryCount = "select count(*)from admin.cls t where parent is null";
|
|
5
7
|
// query.name = cls1,cls2,cls3
|
|
6
8
|
// query.search = substring of cls name
|
|
7
9
|
// data[idx].count - should not depend on either query.name or query.search
|
|
@@ -16,11 +18,25 @@ export default async function getUserClsListApi({ query, user, pg = pgClients.cl
|
|
|
16
18
|
const result = await getUserClsList({
|
|
17
19
|
name: query.name,
|
|
18
20
|
search: query.search,
|
|
19
|
-
type: query.type,
|
|
21
|
+
// type: query.type,
|
|
20
22
|
custom: query.custom,
|
|
21
23
|
sql: query.sql,
|
|
22
24
|
}, pg);
|
|
23
25
|
if (query.sql)
|
|
24
26
|
return result;
|
|
25
|
-
|
|
27
|
+
const promises = [
|
|
28
|
+
query.custom === "0" || !query.custom
|
|
29
|
+
? pg.query(gitQueryCount).then((r) => r.rows?.[0]?.count || 0)
|
|
30
|
+
: null,
|
|
31
|
+
query.custom === "1" || !query.custom
|
|
32
|
+
? pg.query(customQueryCount).then((r) => r.rows?.[0]?.count || 0)
|
|
33
|
+
: null,
|
|
34
|
+
];
|
|
35
|
+
const total = await Promise.all(promises).then((r) => r.reduce((a, b) => +a + +b, 0));
|
|
36
|
+
return {
|
|
37
|
+
time: Date.now() - t1,
|
|
38
|
+
total,
|
|
39
|
+
filtered: result.length,
|
|
40
|
+
data: result,
|
|
41
|
+
};
|
|
26
42
|
}
|
package/package.json
CHANGED
|
@@ -1,99 +1,99 @@
|
|
|
1
|
-
{
|
|
2
|
-
"name": "@opengis/fastify-table",
|
|
3
|
-
"version": "2.5.
|
|
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
|
-
"./errors.js": "./dist/errors.js",
|
|
19
|
-
"./utils.js": "./dist/utils.js",
|
|
20
|
-
"./package.json": "./package.json"
|
|
21
|
-
},
|
|
22
|
-
"files": [
|
|
23
|
-
"dist/*"
|
|
24
|
-
],
|
|
25
|
-
"scripts": {
|
|
26
|
-
"dump": "bun ./script/dump.ts",
|
|
27
|
-
"migrate": "bun ./script/migrate.ts",
|
|
28
|
-
"dump1": "bun ./dist/script/dump.js",
|
|
29
|
-
"migrate1": "bun ./dist/script/migrate.js",
|
|
30
|
-
"prepublishOnly": "npm run build",
|
|
31
|
-
"clean": "tsc -b --clean",
|
|
32
|
-
"build": "tsc -b --clean && tsc && copyfiles server/plugins/grpc/utils/*.proto dist && copyfiles server/migrations/*.sql dist && copyfiles server/templates/**/*.html dist && copyfiles server/templates/**/*.hbs dist && copyfiles script/* dist && copyfiles -u 2 module/core/*/* dist/module/core",
|
|
33
|
-
"prod": "NODE_ENV=production bun dist/server",
|
|
34
|
-
"patch": "npm version patch && git push && npm publish",
|
|
35
|
-
"minor": "npm version minor && git push && npm publish",
|
|
36
|
-
"major": "npm version major && git push && npm publish",
|
|
37
|
-
"lint": "eslint . --ext .vue,.js,.jsx,.cjs,.mjs,.ts,.tsx,.cts,.mts --fix --ignore-path .gitignore",
|
|
38
|
-
"test": "npx vitest run",
|
|
39
|
-
"compress": "node compress.js",
|
|
40
|
-
"dev1": "bun --hot dist/server",
|
|
41
|
-
"dev": "NODE_ENV=development bun start",
|
|
42
|
-
"start": "LOG_LEVEL=trace bun server",
|
|
43
|
-
"start1": "npx tsx server"
|
|
44
|
-
},
|
|
45
|
-
"dependencies": {
|
|
46
|
-
"@aws-sdk/client-s3": "3.1079.0",
|
|
47
|
-
"@aws-sdk/lib-storage": "3.1079.0",
|
|
48
|
-
"@fastify/cookie": "11.0.2",
|
|
49
|
-
"@fastify/http-proxy": "11.5.0",
|
|
50
|
-
"@fastify/multipart": "10.0.0",
|
|
51
|
-
"@fastify/passport": "3.0.2",
|
|
52
|
-
"@fastify/rate-limit": "11.1.0",
|
|
53
|
-
"@fastify/session": "11.1.1",
|
|
54
|
-
"@grpc/grpc-js": "1.14.4",
|
|
55
|
-
"@grpc/proto-loader": "0.8.1",
|
|
56
|
-
"apache-crypt": "1.2.6",
|
|
57
|
-
"dotenv": "17.4.2",
|
|
58
|
-
"fastify": "5.9.0",
|
|
59
|
-
"fastify-plugin": "6.0.0",
|
|
60
|
-
"fastify-session-redis-store": "7.1.2",
|
|
61
|
-
"file-type": "^22.0.1",
|
|
62
|
-
"handlebars": "4.7.9",
|
|
63
|
-
"image-size": "2.0.2",
|
|
64
|
-
"ioredis": "5.11.1",
|
|
65
|
-
"js-yaml": "5.2.1",
|
|
66
|
-
"markdown-it": "14.3.0",
|
|
67
|
-
"minio": "^8.0.7",
|
|
68
|
-
"nodemailer": "9.0.3",
|
|
69
|
-
"otplib": "13.4.1",
|
|
70
|
-
"pg": "8.22.0",
|
|
71
|
-
"pino": "10.3.1",
|
|
72
|
-
"pino-abstract-transport": "3.0.0",
|
|
73
|
-
"promised-handlebars": "2.0.1",
|
|
74
|
-
"qrcode": "1.5.4",
|
|
75
|
-
"sharp": "0.35.3",
|
|
76
|
-
"uglify-js": "3.19.3",
|
|
77
|
-
"undici": "8.6.0"
|
|
78
|
-
},
|
|
79
|
-
"devDependencies": {
|
|
80
|
-
"@stylistic/eslint-plugin": "^5.10.0",
|
|
81
|
-
"@types/bun": "^1.3.5",
|
|
82
|
-
"@types/js-yaml": "^4.0.9",
|
|
83
|
-
"@types/markdown-it": "^14.1.2",
|
|
84
|
-
"@types/node": "^26.1.0",
|
|
85
|
-
"@types/nodemailer": "^8.0.1",
|
|
86
|
-
"@types/passport": "^1.0.17",
|
|
87
|
-
"@types/passport-local": "^1.0.38",
|
|
88
|
-
"@types/pg": "^8.20.0",
|
|
89
|
-
"@types/qrcode": "^1.5.6",
|
|
90
|
-
"copyfiles": "^2.4.1",
|
|
91
|
-
"eslint": "^10.6.0",
|
|
92
|
-
"eslint-stylistic-airbnb": "^3.2.0",
|
|
93
|
-
"ts-migrate": "^0.1.35",
|
|
94
|
-
"typescript": "^6.0.2",
|
|
95
|
-
"vitest": "^4.1.2"
|
|
96
|
-
},
|
|
97
|
-
"author": "Softpro",
|
|
98
|
-
"license": "ISC"
|
|
99
|
-
}
|
|
1
|
+
{
|
|
2
|
+
"name": "@opengis/fastify-table",
|
|
3
|
+
"version": "2.5.21",
|
|
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
|
+
"./errors.js": "./dist/errors.js",
|
|
19
|
+
"./utils.js": "./dist/utils.js",
|
|
20
|
+
"./package.json": "./package.json"
|
|
21
|
+
},
|
|
22
|
+
"files": [
|
|
23
|
+
"dist/*"
|
|
24
|
+
],
|
|
25
|
+
"scripts": {
|
|
26
|
+
"dump": "bun ./script/dump.ts",
|
|
27
|
+
"migrate": "bun ./script/migrate.ts",
|
|
28
|
+
"dump1": "bun ./dist/script/dump.js",
|
|
29
|
+
"migrate1": "bun ./dist/script/migrate.js",
|
|
30
|
+
"prepublishOnly": "npm run build",
|
|
31
|
+
"clean": "tsc -b --clean",
|
|
32
|
+
"build": "tsc -b --clean && tsc && copyfiles server/plugins/grpc/utils/*.proto dist && copyfiles server/migrations/*.sql dist && copyfiles server/templates/**/*.html dist && copyfiles server/templates/**/*.hbs dist && copyfiles script/* dist && copyfiles -u 2 module/core/*/* dist/module/core",
|
|
33
|
+
"prod": "NODE_ENV=production bun dist/server",
|
|
34
|
+
"patch": "npm version patch && git push && npm publish",
|
|
35
|
+
"minor": "npm version minor && git push && npm publish",
|
|
36
|
+
"major": "npm version major && git push && npm publish",
|
|
37
|
+
"lint": "eslint . --ext .vue,.js,.jsx,.cjs,.mjs,.ts,.tsx,.cts,.mts --fix --ignore-path .gitignore",
|
|
38
|
+
"test": "npx vitest run",
|
|
39
|
+
"compress": "node compress.js",
|
|
40
|
+
"dev1": "bun --hot dist/server",
|
|
41
|
+
"dev": "NODE_ENV=development bun start",
|
|
42
|
+
"start": "LOG_LEVEL=trace bun server",
|
|
43
|
+
"start1": "npx tsx server"
|
|
44
|
+
},
|
|
45
|
+
"dependencies": {
|
|
46
|
+
"@aws-sdk/client-s3": "3.1079.0",
|
|
47
|
+
"@aws-sdk/lib-storage": "3.1079.0",
|
|
48
|
+
"@fastify/cookie": "11.0.2",
|
|
49
|
+
"@fastify/http-proxy": "11.5.0",
|
|
50
|
+
"@fastify/multipart": "10.0.0",
|
|
51
|
+
"@fastify/passport": "3.0.2",
|
|
52
|
+
"@fastify/rate-limit": "11.1.0",
|
|
53
|
+
"@fastify/session": "11.1.1",
|
|
54
|
+
"@grpc/grpc-js": "1.14.4",
|
|
55
|
+
"@grpc/proto-loader": "0.8.1",
|
|
56
|
+
"apache-crypt": "1.2.6",
|
|
57
|
+
"dotenv": "17.4.2",
|
|
58
|
+
"fastify": "5.9.0",
|
|
59
|
+
"fastify-plugin": "6.0.0",
|
|
60
|
+
"fastify-session-redis-store": "7.1.2",
|
|
61
|
+
"file-type": "^22.0.1",
|
|
62
|
+
"handlebars": "4.7.9",
|
|
63
|
+
"image-size": "2.0.2",
|
|
64
|
+
"ioredis": "5.11.1",
|
|
65
|
+
"js-yaml": "5.2.1",
|
|
66
|
+
"markdown-it": "14.3.0",
|
|
67
|
+
"minio": "^8.0.7",
|
|
68
|
+
"nodemailer": "9.0.3",
|
|
69
|
+
"otplib": "13.4.1",
|
|
70
|
+
"pg": "8.22.0",
|
|
71
|
+
"pino": "10.3.1",
|
|
72
|
+
"pino-abstract-transport": "3.0.0",
|
|
73
|
+
"promised-handlebars": "2.0.1",
|
|
74
|
+
"qrcode": "1.5.4",
|
|
75
|
+
"sharp": "0.35.3",
|
|
76
|
+
"uglify-js": "3.19.3",
|
|
77
|
+
"undici": "8.6.0"
|
|
78
|
+
},
|
|
79
|
+
"devDependencies": {
|
|
80
|
+
"@stylistic/eslint-plugin": "^5.10.0",
|
|
81
|
+
"@types/bun": "^1.3.5",
|
|
82
|
+
"@types/js-yaml": "^4.0.9",
|
|
83
|
+
"@types/markdown-it": "^14.1.2",
|
|
84
|
+
"@types/node": "^26.1.0",
|
|
85
|
+
"@types/nodemailer": "^8.0.1",
|
|
86
|
+
"@types/passport": "^1.0.17",
|
|
87
|
+
"@types/passport-local": "^1.0.38",
|
|
88
|
+
"@types/pg": "^8.20.0",
|
|
89
|
+
"@types/qrcode": "^1.5.6",
|
|
90
|
+
"copyfiles": "^2.4.1",
|
|
91
|
+
"eslint": "^10.6.0",
|
|
92
|
+
"eslint-stylistic-airbnb": "^3.2.0",
|
|
93
|
+
"ts-migrate": "^0.1.35",
|
|
94
|
+
"typescript": "^6.0.2",
|
|
95
|
+
"vitest": "^4.1.2"
|
|
96
|
+
},
|
|
97
|
+
"author": "Softpro",
|
|
98
|
+
"license": "ISC"
|
|
99
|
+
}
|