@opengis/fastify-table 2.4.9 → 2.4.11
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/config.d.ts.map +1 -1
- package/dist/config.js +6 -6
- package/dist/server/plugins/grpc/grpc.d.ts.map +1 -1
- package/dist/server/plugins/grpc/grpc.js +11 -0
- package/dist/server/plugins/grpc/utils/convertp.proto +7 -0
- package/dist/server/routes/auth/controllers/2factor/providers/totp.d.ts +6 -2
- package/dist/server/routes/auth/controllers/2factor/providers/totp.d.ts.map +1 -1
- package/dist/server/routes/auth/controllers/2factor/providers/totp.js +13 -6
- package/dist/server/routes/util/controllers/api.check.d.ts +2 -0
- package/dist/server/routes/util/controllers/api.check.d.ts.map +1 -0
- package/dist/server/routes/util/controllers/api.check.js +36 -0
- package/dist/server/routes/util/controllers/api.list.js +1 -1
- package/dist/server/routes/util/index.d.ts.map +1 -1
- package/dist/server/routes/util/index.js +2 -0
- package/package.json +1 -1
package/dist/config.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"config.d.ts","sourceRoot":"","sources":["../config.ts"],"names":[],"mappings":"AAWA,QAAA,MAAM,MAAM,KAA8D,CAAC;
|
|
1
|
+
{"version":3,"file":"config.d.ts","sourceRoot":"","sources":["../config.ts"],"names":[],"mappings":"AAWA,QAAA,MAAM,MAAM,KAA8D,CAAC;AAiD3E,eAAe,MAAM,CAAC"}
|
package/dist/config.js
CHANGED
|
@@ -12,21 +12,21 @@ Object.assign(config, {
|
|
|
12
12
|
env: process.env.NODE_ENV,
|
|
13
13
|
port: config.port || process.env.PORT,
|
|
14
14
|
});
|
|
15
|
-
if (existsSync(`.env.local`)) {
|
|
16
|
-
dotenv.config({ path: `.env.local` }); // ! load .env.local
|
|
17
|
-
}
|
|
18
15
|
// example: bun server kamianske
|
|
19
16
|
if (process.cwd().split("\\").pop() &&
|
|
20
17
|
process.cwd().split("\\").pop() === "fastify-table" &&
|
|
21
18
|
process.argv[2] &&
|
|
22
19
|
existsSync(`.env.${process.argv[2]}`)) {
|
|
23
|
-
dotenv.config({ path: `.env.${process.argv[2]}
|
|
20
|
+
dotenv.config({ path: `.env.${process.argv[2]}`, override: true }); // ! for debug only
|
|
24
21
|
}
|
|
25
22
|
if (process.env?.NODE_ENV && existsSync(`.env.${process.env.NODE_ENV}`)) {
|
|
26
|
-
dotenv.config({ path: `.env.${process.env.NODE_ENV}
|
|
23
|
+
dotenv.config({ path: `.env.${process.env.NODE_ENV}`, override: true }); // ! load .env.{{production}} etc.
|
|
27
24
|
}
|
|
28
25
|
if (process.env?.NODE_ENV && existsSync(`.env.${process.env.NODE_ENV}.local`)) {
|
|
29
|
-
dotenv.config({ path: `.env.${process.env.NODE_ENV}.local
|
|
26
|
+
dotenv.config({ path: `.env.${process.env.NODE_ENV}.local`, override: true }); // ! load .env.{{production}}.local etc.
|
|
27
|
+
}
|
|
28
|
+
if (existsSync(`.env.local`)) {
|
|
29
|
+
dotenv.config({ path: `.env.local`, override: true }); // ! load .env.local
|
|
30
30
|
}
|
|
31
31
|
function loadEnvConfig() {
|
|
32
32
|
if (config.trace) {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"grpc.d.ts","sourceRoot":"","sources":["../../../../server/plugins/grpc/grpc.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"grpc.d.ts","sourceRoot":"","sources":["../../../../server/plugins/grpc/grpc.ts"],"names":[],"mappings":"AAyIA,QAAA,MAAM,OAAO,WAIX,CAAC;AAEH,eAAe,OAAO,CAAC"}
|
|
@@ -66,6 +66,16 @@ if (convertServerAddress) {
|
|
|
66
66
|
}
|
|
67
67
|
});
|
|
68
68
|
}
|
|
69
|
+
const checkHealth = convertServerAddress
|
|
70
|
+
? () => new Promise((resolve, reject) => {
|
|
71
|
+
convertClient.healthCheck({}, (err) => {
|
|
72
|
+
if (err && err.message !== "12 UNIMPLEMENTED: Method not found!") {
|
|
73
|
+
return reject(err);
|
|
74
|
+
}
|
|
75
|
+
resolve({ status: "ok" });
|
|
76
|
+
});
|
|
77
|
+
})
|
|
78
|
+
: () => Promise.resolve();
|
|
69
79
|
const wrapGrpcCall = (methodName) => async (data) => new Promise((res, rej) => {
|
|
70
80
|
if (!convertServerAddress) {
|
|
71
81
|
logger.file("grpc/convert", {
|
|
@@ -98,6 +108,7 @@ const grpcMethods = methodNames.reduce((acc, name) => {
|
|
|
98
108
|
}, {});
|
|
99
109
|
const getGRPC = () => ({
|
|
100
110
|
...grpcMethods,
|
|
111
|
+
checkHealth,
|
|
101
112
|
convertServerAddress,
|
|
102
113
|
});
|
|
103
114
|
export default getGRPC;
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
syntax = "proto3";
|
|
2
2
|
|
|
3
3
|
service Convert {
|
|
4
|
+
rpc HealthCheck (Empty) returns (HealthResponse);
|
|
4
5
|
rpc csvToXls(csvToXlsParams) returns (FileBase64) {}
|
|
5
6
|
rpc jsonToXls(jsonToXlsParams) returns (FileBase64) {}
|
|
6
7
|
rpc pdfMerge(pdfMergeParams) returns (FileBase64) {}
|
|
@@ -20,6 +21,12 @@ service Convert {
|
|
|
20
21
|
rpc geojsonToGpkg(geojsonToShpParams) returns (FileBase64) {}
|
|
21
22
|
}
|
|
22
23
|
|
|
24
|
+
message Empty {}
|
|
25
|
+
|
|
26
|
+
message HealthResponse {
|
|
27
|
+
string status = 1;
|
|
28
|
+
}
|
|
29
|
+
|
|
23
30
|
message jsonToYamlIn {
|
|
24
31
|
string json = 1;
|
|
25
32
|
}
|
|
@@ -9,8 +9,12 @@ interface ICode {
|
|
|
9
9
|
pg: ExtendedPG;
|
|
10
10
|
enable?: boolean;
|
|
11
11
|
}
|
|
12
|
-
declare const enableSecret: ({ uid, pg }: ISecret) => Promise<
|
|
13
|
-
|
|
12
|
+
declare const enableSecret: ({ uid, pg }: ISecret) => Promise<{
|
|
13
|
+
rowCount: any;
|
|
14
|
+
}>;
|
|
15
|
+
declare const deleteSecret: ({ uid, pg }: ISecret) => Promise<{
|
|
16
|
+
rowCount: any;
|
|
17
|
+
}>;
|
|
14
18
|
declare const getSecret: ({ uid, pg }: ISecret) => Promise<{
|
|
15
19
|
secret: any;
|
|
16
20
|
enabled: any;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"totp.d.ts","sourceRoot":"","sources":["../../../../../../../server/routes/auth/controllers/2factor/providers/totp.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,MAAM,8BAA8B,CAAC;AAW1D,UAAU,OAAO;IACf,GAAG,EAAE,MAAM,CAAC;IACZ,EAAE,EAAE,UAAU,CAAC;CAChB;AAED,UAAU,KAAK;IACb,GAAG,EAAE,MAAM,CAAC;IACZ,IAAI,EAAE,MAAM,CAAC;IACb,EAAE,EAAE,UAAU,CAAC;IACf,MAAM,CAAC,EAAE,OAAO,CAAC;CAClB;AAuBD,QAAA,MAAM,YAAY,GAAU,aAAa,OAAO
|
|
1
|
+
{"version":3,"file":"totp.d.ts","sourceRoot":"","sources":["../../../../../../../server/routes/auth/controllers/2factor/providers/totp.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,MAAM,8BAA8B,CAAC;AAW1D,UAAU,OAAO;IACf,GAAG,EAAE,MAAM,CAAC;IACZ,EAAE,EAAE,UAAU,CAAC;CAChB;AAED,UAAU,KAAK;IACb,GAAG,EAAE,MAAM,CAAC;IACZ,IAAI,EAAE,MAAM,CAAC;IACb,EAAE,EAAE,UAAU,CAAC;IACf,MAAM,CAAC,EAAE,OAAO,CAAC;CAClB;AAuBD,QAAA,MAAM,YAAY,GAAU,aAAa,OAAO;;EAQ/C,CAAC;AAEF,QAAA,MAAM,YAAY,GAAU,aAAa,OAAO;;EAQ/C,CAAC;AAEF,QAAA,MAAM,SAAS,GAAU,aAAa,OAAO;;;;EAc5C,CAAC;AAuBF,QAAA,MAAM,QAAQ,GAAU,aAAa,OAAO;;;;;;;;;;;;EA0D3C,CAAC;AAEF,QAAA,MAAM,MAAM,GAAU,0BAA0B,KAAK;;;EAmBpD,CAAC;AAKF,QAAA,MAAM,MAAM,GAAU,2BAA2B,KAAK,iBAqBrD,CAAC;AAEF,OAAO,EAAE,QAAQ,EAAE,MAAM,EAAE,MAAM,EAAE,SAAS,EAAE,YAAY,EAAE,YAAY,EAAE,CAAC;;AAE3E,wBAAoB"}
|
|
@@ -11,17 +11,23 @@ const getOTP = (id, secret) => {
|
|
|
11
11
|
return `otpauth://totp/${issuer}:${encodeURIComponent(id.toString())}?secret=${secret}&period=30&digits=6&algorithm=SHA1&issuer=${encodeURIComponent(issuer)}`;
|
|
12
12
|
};
|
|
13
13
|
const enableSecret = async ({ uid, pg }) => {
|
|
14
|
-
|
|
14
|
+
const rowCount = await pg
|
|
15
|
+
.query("update admin.users_social_auth set enabled=true where uid = $1 and social_auth_type = $2", [uid, TYPE])
|
|
16
|
+
.then((r) => r.rowCount);
|
|
17
|
+
return { rowCount };
|
|
15
18
|
};
|
|
16
19
|
const deleteSecret = async ({ uid, pg }) => {
|
|
17
|
-
|
|
20
|
+
const rowCount = await pg
|
|
21
|
+
.query("delete from admin.users_social_auth where uid=$1 and social_auth_type = $2", [uid, TYPE])
|
|
22
|
+
.then((r) => r.rowCount);
|
|
23
|
+
return { rowCount };
|
|
18
24
|
};
|
|
19
25
|
const getSecret = async ({ uid, pg }) => {
|
|
20
26
|
const { social_auth_code: secret, enabled, recoveryCodes, } = await pg
|
|
21
27
|
.query(`select social_auth_code, enabled, social_auth_obj->'codesArray' as "recoveryCodes"
|
|
22
28
|
from admin.users_social_auth
|
|
23
29
|
where uid = $1 and social_auth_type = $2`, [uid, TYPE])
|
|
24
|
-
.then((
|
|
30
|
+
.then((r) => r.rows?.[0] || {});
|
|
25
31
|
return { secret, enabled, recoveryCodes };
|
|
26
32
|
};
|
|
27
33
|
const addSecret = async ({ uid, secret, pg, recoveryCodes, otp }) => {
|
|
@@ -33,7 +39,7 @@ const updateSecret = async ({ uid, pg, secret, recoveryCodes, otp }) => {
|
|
|
33
39
|
.query(`update admin.users_social_auth
|
|
34
40
|
set social_auth_code=$3, social_auth_obj=$4::json, social_auth_url=$5
|
|
35
41
|
where uid = $1 and social_auth_type = $2`, [uid, TYPE, secret, { codesArray: recoveryCodes }, otp])
|
|
36
|
-
.then((
|
|
42
|
+
.then((r) => r.rows?.[0] || {});
|
|
37
43
|
return result;
|
|
38
44
|
};
|
|
39
45
|
// return a new secret until it's enabled
|
|
@@ -51,7 +57,7 @@ const generate = async ({ uid, pg }) => {
|
|
|
51
57
|
];
|
|
52
58
|
const userData = await pg
|
|
53
59
|
.query(`select social_auth_id as code, coalesce(login,email) as login, email from admin.users where uid=$1`, [uid])
|
|
54
|
-
.then((
|
|
60
|
+
.then((r) => r.rows?.[0] || {});
|
|
55
61
|
const { sufix } = config.auth?.["2fa"] || {};
|
|
56
62
|
if (sufix && !userData[sufix]) {
|
|
57
63
|
console.warn("⚠️ 2fa prefix not found at userData");
|
|
@@ -90,7 +96,8 @@ const verify = async ({ uid, code: token, pg }) => {
|
|
|
90
96
|
if (!secret) {
|
|
91
97
|
throw new BadRequestError("Включіть двофакторну аутентифікацію");
|
|
92
98
|
}
|
|
93
|
-
const
|
|
99
|
+
const { valid } = await authenticator.verify({ token, secret });
|
|
100
|
+
const isValid = valid ||
|
|
94
101
|
recoveryCodes.reduce((result, recoveryCode) => result || recoveryCode === token, false);
|
|
95
102
|
if (!isValid) {
|
|
96
103
|
throw new ForbiddenError("Невірний код");
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"api.check.d.ts","sourceRoot":"","sources":["../../../../../server/routes/util/controllers/api.check.ts"],"names":[],"mappings":"AAqCA,wBAA8B,QAAQ,iBAkBrC"}
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
import { HeadBucketCommand } from "@aws-sdk/client-s3";
|
|
2
|
+
import config from "../../../../config.js";
|
|
3
|
+
import grpc from "../../../plugins/grpc/grpc.js";
|
|
4
|
+
import pgClients from "../../../plugins/pg/pgClients.js";
|
|
5
|
+
import getRedis from "../../../plugins/redis/funcs/getRedis.js";
|
|
6
|
+
import s3Client from "../../../plugins/file/providers/s3/client.js";
|
|
7
|
+
import { applyHook } from "../../../../utils.js";
|
|
8
|
+
const timeoutPromise = async (name, promise) => {
|
|
9
|
+
if (!promise) {
|
|
10
|
+
return Promise.resolve({ [name]: "not configured" });
|
|
11
|
+
}
|
|
12
|
+
return Promise.race([
|
|
13
|
+
promise.then(() => ({ [name]: "ok" })).catch(() => ({ [name]: "error" })),
|
|
14
|
+
new Promise((resolve) => setTimeout(() => resolve({ [name]: "timeout" }), timeoutMs)),
|
|
15
|
+
]);
|
|
16
|
+
};
|
|
17
|
+
const { checkHealth, convertServerAddress } = grpc();
|
|
18
|
+
const redisClient = getRedis();
|
|
19
|
+
const timeoutMs = 300;
|
|
20
|
+
const bucketParams = new HeadBucketCommand({
|
|
21
|
+
Bucket: config.s3?.containerName || "work",
|
|
22
|
+
});
|
|
23
|
+
/*addHook("afterApiCheck", async (result: Record<string, string>) => {
|
|
24
|
+
return { ...result, mapnik: "not configured" };
|
|
25
|
+
});*/
|
|
26
|
+
export default async function apiCheck() {
|
|
27
|
+
const timeStart = Date.now();
|
|
28
|
+
const res = await Promise.all([
|
|
29
|
+
timeoutPromise("redis", redisClient ? redisClient.ping() : undefined),
|
|
30
|
+
timeoutPromise("pg", pgClients.client ? pgClients.client.query("select 1") : undefined),
|
|
31
|
+
timeoutPromise("convert", convertServerAddress ? checkHealth() : undefined),
|
|
32
|
+
timeoutPromise("s3", s3Client ? s3Client.send(bucketParams) : undefined),
|
|
33
|
+
]).then((result) => result.reduce((acc, curr) => ({ ...acc, ...curr }), {}));
|
|
34
|
+
const hootData = await applyHook("afterApiCheck", res);
|
|
35
|
+
return { time: Date.now() - timeStart, ...res, ...(hootData || {}) };
|
|
36
|
+
}
|
|
@@ -49,7 +49,7 @@ export default function apiListService({ includeTags: queryIncludeTags, excludeT
|
|
|
49
49
|
const markdownStr = toMarkdownTable(filteredRoutes3, Array.isArray(columns) ? columns : columns.split("|"));
|
|
50
50
|
return {
|
|
51
51
|
headers: {
|
|
52
|
-
"Content-Type": "text/markdown",
|
|
52
|
+
"Content-Type": "text/markdown; charset=utf-8",
|
|
53
53
|
},
|
|
54
54
|
data: markdownStr,
|
|
55
55
|
};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../server/routes/util/index.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../server/routes/util/index.ts"],"names":[],"mappings":"AAYA,iBAAS,MAAM,CAAC,GAAG,EAAE,GAAG,EAAE,GAAG,GAAE,GAAQ,QAoCtC;AAED,eAAe,MAAM,CAAC"}
|
|
@@ -4,9 +4,11 @@ import statusMonitor from "./controllers/status.monitor.js";
|
|
|
4
4
|
import userTokens from "./controllers/user.tokens.js";
|
|
5
5
|
import codeGenerator from "./controllers/code.generator.js";
|
|
6
6
|
import dependencies from "./controllers/dependencies.js";
|
|
7
|
+
import apiCheck from "./controllers/api.check.js";
|
|
7
8
|
const tags = ["core", "util"];
|
|
8
9
|
function plugin(app, opt = {}) {
|
|
9
10
|
app.get("/next-id", { config: { tags, policy: "L0" } }, nextId);
|
|
11
|
+
app.get("/check", { config: { tags, role: "admin" } }, apiCheck);
|
|
10
12
|
app.get("/status-monitor", { config: { tags, role: "admin" } }, statusMonitor);
|
|
11
13
|
app.get("/user-tokens/:token", { config: { tags, role: "admin|regular" } }, userTokens);
|
|
12
14
|
app.get("/code-gen/:token/:column/:id?", { config: { tags, role: "admin|regular" } }, codeGenerator);
|