@wxn0brp/db 0.0.5 → 0.0.6
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/README.md +3 -0
- package/dist/cjs/CollectionManager.d.ts +43 -0
- package/dist/cjs/CollectionManager.js +59 -0
- package/dist/cjs/action.d.ts +71 -0
- package/dist/cjs/action.js +199 -0
- package/dist/cjs/database.d.ts +77 -0
- package/dist/cjs/database.js +118 -0
- package/dist/cjs/executor.d.ts +28 -0
- package/{executor.js → dist/cjs/executor.js} +47 -54
- package/dist/cjs/file/find.d.ts +11 -0
- package/dist/cjs/file/find.js +80 -0
- package/dist/cjs/file/index.d.ts +3 -0
- package/dist/cjs/file/index.js +25 -0
- package/dist/cjs/file/remove.d.ts +7 -0
- package/dist/cjs/file/remove.js +61 -0
- package/dist/cjs/file/update.d.ts +7 -0
- package/dist/cjs/file/update.js +68 -0
- package/dist/cjs/file/utils.d.ts +8 -0
- package/dist/cjs/file/utils.js +23 -0
- package/dist/cjs/format.d.ts +18 -0
- package/dist/cjs/format.js +36 -0
- package/dist/cjs/gen.d.ts +5 -0
- package/dist/cjs/gen.js +78 -0
- package/dist/cjs/graph.d.ts +47 -0
- package/dist/cjs/graph.js +90 -0
- package/{index.d.ts → dist/cjs/index.d.ts} +2 -2
- package/dist/cjs/index.js +18 -0
- package/dist/cjs/relation.d.ts +64 -0
- package/{relation.js → dist/cjs/relation.js} +26 -45
- package/dist/cjs/remote/client/database.d.ts +71 -0
- package/dist/cjs/remote/client/database.js +145 -0
- package/dist/cjs/remote/client/function.d.ts +5 -0
- package/dist/cjs/remote/client/function.js +32 -0
- package/dist/cjs/remote/client/graph.d.ts +54 -0
- package/dist/cjs/remote/client/graph.js +93 -0
- package/dist/cjs/remote/client/remote.d.ts +16 -0
- package/dist/cjs/remote/client/remote.js +2 -0
- package/dist/cjs/remote/server/auth.d.ts +31 -0
- package/dist/cjs/remote/server/auth.js +99 -0
- package/dist/cjs/remote/server/db.d.ts +2 -0
- package/dist/cjs/remote/server/db.js +223 -0
- package/dist/cjs/remote/server/function.d.ts +2 -0
- package/dist/cjs/remote/server/function.js +89 -0
- package/dist/cjs/remote/server/graph.d.ts +2 -0
- package/dist/cjs/remote/server/graph.js +145 -0
- package/dist/cjs/remote/server/index.d.ts +1 -0
- package/dist/cjs/remote/server/index.js +66 -0
- package/dist/cjs/remote/server/initDataBases.d.ts +1 -0
- package/dist/cjs/remote/server/initDataBases.js +25 -0
- package/dist/cjs/remote/server/pathUtils.d.ts +1 -0
- package/dist/cjs/remote/server/pathUtils.js +12 -0
- package/dist/cjs/remote/server/secret.d.ts +1 -0
- package/dist/cjs/remote/server/secret.js +25 -0
- package/dist/cjs/remote/serverMgmt/index.d.ts +1 -0
- package/dist/cjs/remote/serverMgmt/index.js +87 -0
- package/dist/cjs/types/Id.d.ts +3 -0
- package/dist/cjs/types/Id.js +2 -0
- package/dist/cjs/types/arg.d.ts +6 -0
- package/dist/cjs/types/arg.js +2 -0
- package/dist/cjs/types/data.d.ts +4 -0
- package/dist/cjs/types/data.js +2 -0
- package/dist/cjs/types/options.d.ts +12 -0
- package/dist/cjs/types/options.js +2 -0
- package/dist/cjs/types/searchOpts.d.ts +61 -0
- package/dist/cjs/types/searchOpts.js +8 -0
- package/dist/cjs/types/types.d.ts +6 -0
- package/dist/cjs/types/types.js +2 -0
- package/dist/cjs/utils/hasFields.d.ts +8 -0
- package/dist/cjs/utils/hasFields.js +22 -0
- package/dist/cjs/utils/hasFieldsAdvanced.d.ts +5 -0
- package/dist/cjs/utils/hasFieldsAdvanced.js +182 -0
- package/dist/cjs/utils/updateFindObject.d.ts +11 -0
- package/dist/cjs/utils/updateFindObject.js +32 -0
- package/dist/cjs/utils/updateObject.d.ts +8 -0
- package/dist/cjs/utils/updateObject.js +18 -0
- package/dist/esm/CollectionManager.d.ts +43 -0
- package/dist/esm/CollectionManager.js +57 -0
- package/dist/esm/action.d.ts +71 -0
- package/dist/esm/action.js +194 -0
- package/dist/esm/database.d.ts +77 -0
- package/dist/esm/database.js +113 -0
- package/dist/esm/executor.d.ts +28 -0
- package/dist/esm/executor.js +45 -0
- package/dist/esm/file/find.d.ts +11 -0
- package/dist/esm/file/find.js +73 -0
- package/dist/esm/file/index.d.ts +3 -0
- package/{file → dist/esm/file}/index.js +1 -1
- package/dist/esm/file/remove.d.ts +7 -0
- package/dist/esm/file/remove.js +56 -0
- package/dist/esm/file/update.d.ts +7 -0
- package/dist/esm/file/update.js +63 -0
- package/dist/esm/file/utils.d.ts +8 -0
- package/{file → dist/esm/file}/utils.js +3 -11
- package/dist/esm/format.d.ts +18 -0
- package/{format.js → dist/esm/format.js} +29 -29
- package/dist/esm/gen.d.ts +5 -0
- package/dist/esm/gen.js +75 -0
- package/dist/esm/graph.d.ts +47 -0
- package/dist/esm/graph.js +85 -0
- package/dist/esm/index.d.ts +7 -0
- package/{index.js → dist/esm/index.js} +1 -9
- package/dist/esm/relation.d.ts +64 -0
- package/dist/esm/relation.js +65 -0
- package/dist/esm/remote/client/database.d.ts +71 -0
- package/dist/esm/remote/client/database.js +140 -0
- package/dist/esm/remote/client/function.d.ts +5 -0
- package/dist/esm/remote/client/function.js +30 -0
- package/dist/esm/remote/client/graph.d.ts +54 -0
- package/dist/esm/remote/client/graph.js +88 -0
- package/dist/esm/remote/client/remote.d.ts +16 -0
- package/dist/esm/remote/client/remote.js +1 -0
- package/dist/esm/remote/server/auth.d.ts +31 -0
- package/{remote → dist/esm/remote}/server/auth.js +31 -44
- package/dist/esm/remote/server/db.d.ts +2 -0
- package/dist/esm/remote/server/db.js +218 -0
- package/dist/esm/remote/server/function.d.ts +2 -0
- package/dist/esm/remote/server/function.js +87 -0
- package/dist/esm/remote/server/graph.d.ts +2 -0
- package/{remote → dist/esm/remote}/server/graph.js +62 -55
- package/dist/esm/remote/server/gui/css/main.css +130 -0
- package/dist/esm/remote/server/gui/css/scrool.css +81 -0
- package/dist/esm/remote/server/gui/css/style.css +61 -0
- package/dist/esm/remote/server/gui/favicon.svg +12 -0
- package/dist/esm/remote/server/gui/html/data.html +15 -0
- package/dist/esm/remote/server/gui/html/main.html +46 -0
- package/dist/esm/remote/server/gui/html/nav.html +25 -0
- package/dist/esm/remote/server/gui/html/popup.html +51 -0
- package/dist/esm/remote/server/gui/index.html +49 -0
- package/dist/esm/remote/server/gui/js/api.js +166 -0
- package/dist/esm/remote/server/gui/js/index.js +17 -0
- package/dist/esm/remote/server/gui/js/loadHTML.js +16 -0
- package/dist/esm/remote/server/gui/js/popUp.js +72 -0
- package/dist/esm/remote/server/gui/js/queryApi.js +51 -0
- package/dist/esm/remote/server/gui/js/queryDb.js +79 -0
- package/dist/esm/remote/server/gui/js/queryGraph.js +144 -0
- package/dist/esm/remote/server/gui/js/render.js +64 -0
- package/dist/esm/remote/server/gui/js/templates.js +31 -0
- package/dist/esm/remote/server/gui/js/utils.js +36 -0
- package/dist/esm/remote/server/gui/js/vars.js +9 -0
- package/dist/esm/remote/server/gui/libs/core.js +176 -0
- package/dist/esm/remote/server/gui/libs/d3.v7.min.js +2 -0
- package/dist/esm/remote/server/gui/libs/handlebars.min.js +29 -0
- package/dist/esm/remote/server/gui/libs/json5.min.js +1 -0
- package/dist/esm/remote/server/index.d.ts +1 -0
- package/dist/esm/remote/server/index.js +61 -0
- package/dist/esm/remote/server/initDataBases.d.ts +1 -0
- package/dist/esm/remote/server/initDataBases.js +20 -0
- package/dist/esm/remote/server/pathUtils.d.ts +1 -0
- package/{remote → dist/esm/remote}/server/pathUtils.js +2 -3
- package/dist/esm/remote/server/secret.d.ts +1 -0
- package/{remote → dist/esm/remote}/server/secret.js +3 -7
- package/dist/esm/remote/serverMgmt/index.d.ts +1 -0
- package/{remote → dist/esm/remote}/serverMgmt/index.js +27 -31
- package/dist/esm/types/Id.d.ts +3 -0
- package/dist/esm/types/Id.js +1 -0
- package/dist/esm/types/arg.d.ts +6 -0
- package/dist/esm/types/arg.js +1 -0
- package/dist/esm/types/data.d.ts +4 -0
- package/dist/esm/types/data.js +1 -0
- package/dist/esm/types/options.d.ts +12 -0
- package/dist/esm/types/options.js +1 -0
- package/dist/esm/types/searchOpts.d.ts +61 -0
- package/dist/esm/types/searchOpts.js +7 -0
- package/dist/esm/types/types.d.ts +6 -0
- package/dist/esm/types/types.js +1 -0
- package/dist/esm/utils/hasFields.d.ts +8 -0
- package/{utils → dist/esm/utils}/hasFields.js +4 -4
- package/dist/esm/utils/hasFieldsAdvanced.d.ts +5 -0
- package/dist/esm/utils/hasFieldsAdvanced.js +176 -0
- package/dist/esm/utils/updateFindObject.d.ts +11 -0
- package/{utils → dist/esm/utils}/updateFindObject.js +11 -16
- package/dist/esm/utils/updateObject.d.ts +8 -0
- package/{utils → dist/esm/utils}/updateObject.js +4 -4
- package/package.json +55 -36
- package/CollectionManager.js +0 -119
- package/action.js +0 -258
- package/database.d.ts +0 -44
- package/database.js +0 -203
- package/docs/database.md +0 -140
- package/docs/graph.md +0 -86
- package/docs/relation.md +0 -51
- package/docs/remote.md +0 -30
- package/docs/remote_server.md +0 -35
- package/docs/search_opts.md +0 -227
- package/file/find.js +0 -89
- package/file/remove.js +0 -74
- package/file/update.js +0 -83
- package/gen.d.ts +0 -1
- package/gen.js +0 -97
- package/graph.d.ts +0 -27
- package/graph.js +0 -140
- package/relation.d.ts +0 -23
- package/remote/client/database.d.ts +0 -41
- package/remote/client/database.js +0 -228
- package/remote/client/graph.d.ts +0 -31
- package/remote/client/graph.js +0 -148
- package/remote/server/db.js +0 -197
- package/remote/server/function.js +0 -43
- package/remote/server/index.js +0 -63
- package/remote/server/initDataBases.js +0 -20
- package/test/hasFieldsAdvanced.test.js +0 -70
- package/utils/hasFieldsAdvanced.js +0 -184
- /package/{remote → dist/cjs/remote}/server/gui/css/main.css +0 -0
- /package/{remote → dist/cjs/remote}/server/gui/css/scrool.css +0 -0
- /package/{remote → dist/cjs/remote}/server/gui/css/style.css +0 -0
- /package/{remote → dist/cjs/remote}/server/gui/favicon.svg +0 -0
- /package/{remote → dist/cjs/remote}/server/gui/html/data.html +0 -0
- /package/{remote → dist/cjs/remote}/server/gui/html/main.html +0 -0
- /package/{remote → dist/cjs/remote}/server/gui/html/nav.html +0 -0
- /package/{remote → dist/cjs/remote}/server/gui/html/popup.html +0 -0
- /package/{remote → dist/cjs/remote}/server/gui/index.html +0 -0
- /package/{remote → dist/cjs/remote}/server/gui/js/api.js +0 -0
- /package/{remote → dist/cjs/remote}/server/gui/js/index.js +0 -0
- /package/{remote → dist/cjs/remote}/server/gui/js/loadHTML.js +0 -0
- /package/{remote → dist/cjs/remote}/server/gui/js/popUp.js +0 -0
- /package/{remote → dist/cjs/remote}/server/gui/js/queryApi.js +0 -0
- /package/{remote → dist/cjs/remote}/server/gui/js/queryDb.js +0 -0
- /package/{remote → dist/cjs/remote}/server/gui/js/queryGraph.js +0 -0
- /package/{remote → dist/cjs/remote}/server/gui/js/render.js +0 -0
- /package/{remote → dist/cjs/remote}/server/gui/js/templates.js +0 -0
- /package/{remote → dist/cjs/remote}/server/gui/js/utils.js +0 -0
- /package/{remote → dist/cjs/remote}/server/gui/js/vars.js +0 -0
- /package/{remote → dist/cjs/remote}/server/gui/libs/core.js +0 -0
- /package/{remote → dist/cjs/remote}/server/gui/libs/d3.v7.min.js +0 -0
- /package/{remote → dist/cjs/remote}/server/gui/libs/handlebars.min.js +0 -0
- /package/{remote → dist/cjs/remote}/server/gui/libs/json5.min.js +0 -0
|
@@ -0,0 +1,88 @@
|
|
|
1
|
+
import got from "got";
|
|
2
|
+
/**
|
|
3
|
+
* A class representing a graph database.
|
|
4
|
+
* Uses a remote database.
|
|
5
|
+
* @class
|
|
6
|
+
*/
|
|
7
|
+
class GraphRemote {
|
|
8
|
+
remote;
|
|
9
|
+
/**
|
|
10
|
+
* Create a new database instance.
|
|
11
|
+
*/
|
|
12
|
+
constructor(remote) {
|
|
13
|
+
this.remote = remote;
|
|
14
|
+
}
|
|
15
|
+
/**
|
|
16
|
+
* Make a request to the remote database.
|
|
17
|
+
*/
|
|
18
|
+
async _request(type, data) {
|
|
19
|
+
data.db = this.remote.name;
|
|
20
|
+
const res = await got.post(this.remote.url + "/db/graph/" + type, {
|
|
21
|
+
// @ts-ignore
|
|
22
|
+
body: data,
|
|
23
|
+
headers: {
|
|
24
|
+
"Authorization": this.remote.auth
|
|
25
|
+
},
|
|
26
|
+
json: true,
|
|
27
|
+
responseType: "json"
|
|
28
|
+
});
|
|
29
|
+
if (res.body.err)
|
|
30
|
+
throw new Error(res.body.msg);
|
|
31
|
+
return res.body.result;
|
|
32
|
+
}
|
|
33
|
+
/**
|
|
34
|
+
* Adds an edge between two nodes.
|
|
35
|
+
*/
|
|
36
|
+
async add(collection, nodeA, nodeB) {
|
|
37
|
+
return await this._request("add", { collection, nodeA, nodeB });
|
|
38
|
+
}
|
|
39
|
+
/**
|
|
40
|
+
* Removes an edge between two nodes.
|
|
41
|
+
*/
|
|
42
|
+
async remove(collection, nodeA, nodeB) {
|
|
43
|
+
return await this._request("remove", { collection, nodeA, nodeB });
|
|
44
|
+
}
|
|
45
|
+
/**
|
|
46
|
+
* Finds all edges with either node equal to `node`.
|
|
47
|
+
*/
|
|
48
|
+
async find(collection, node) {
|
|
49
|
+
return await this._request("find", { collection, node });
|
|
50
|
+
}
|
|
51
|
+
/**
|
|
52
|
+
* Finds one edge with either node equal to `nodeA` and the other equal to `nodeB`.
|
|
53
|
+
*/
|
|
54
|
+
async findOne(collection, nodeA, nodeB) {
|
|
55
|
+
return await this._request("findOne", { collection, nodeA, nodeB });
|
|
56
|
+
}
|
|
57
|
+
/**
|
|
58
|
+
* Get all edges in the collection.
|
|
59
|
+
*/
|
|
60
|
+
async getAll(collection) {
|
|
61
|
+
return await this._request("getAll", { collection });
|
|
62
|
+
}
|
|
63
|
+
/**
|
|
64
|
+
* Get the names of all available databases.
|
|
65
|
+
*/
|
|
66
|
+
async getCollections() {
|
|
67
|
+
return await this._request("getCollections", {});
|
|
68
|
+
}
|
|
69
|
+
/**
|
|
70
|
+
* Check and create the specified collection if it doesn't exist.
|
|
71
|
+
*/
|
|
72
|
+
async checkCollection(collection) {
|
|
73
|
+
return await this._request("checkCollection", { collection });
|
|
74
|
+
}
|
|
75
|
+
/**
|
|
76
|
+
* Check if a collection exists.
|
|
77
|
+
*/
|
|
78
|
+
async issetCollection(collection) {
|
|
79
|
+
return await this._request("issetCollection", { collection });
|
|
80
|
+
}
|
|
81
|
+
/**
|
|
82
|
+
* Remove the specified collection.
|
|
83
|
+
*/
|
|
84
|
+
removeCollection(collection) {
|
|
85
|
+
return this._request("removeCollection", { collection });
|
|
86
|
+
}
|
|
87
|
+
}
|
|
88
|
+
export default GraphRemote;
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
export interface Remote {
|
|
2
|
+
name: string;
|
|
3
|
+
url: string;
|
|
4
|
+
auth: string;
|
|
5
|
+
}
|
|
6
|
+
export interface RequestData {
|
|
7
|
+
collection?: string;
|
|
8
|
+
db?: string;
|
|
9
|
+
keys?: string[];
|
|
10
|
+
[key: string]: any;
|
|
11
|
+
}
|
|
12
|
+
export interface findOptsRemote {
|
|
13
|
+
select?: string[];
|
|
14
|
+
exclude?: string[];
|
|
15
|
+
transform?: string;
|
|
16
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
export declare function authMiddleware(req: any, res: any, next: any): Promise<any>;
|
|
2
|
+
export declare function loginFunction(login: any, password: any): Promise<{
|
|
3
|
+
err: boolean;
|
|
4
|
+
msg: string;
|
|
5
|
+
token?: undefined;
|
|
6
|
+
} | {
|
|
7
|
+
err: boolean;
|
|
8
|
+
token: string;
|
|
9
|
+
msg?: undefined;
|
|
10
|
+
}>;
|
|
11
|
+
export declare function generateToken(payload: any): Promise<string>;
|
|
12
|
+
export declare function removeToken(token: any): Promise<any>;
|
|
13
|
+
export declare function addUserAccess(login: any, password: any): Promise<{
|
|
14
|
+
err: boolean;
|
|
15
|
+
msg: string;
|
|
16
|
+
user?: undefined;
|
|
17
|
+
} | {
|
|
18
|
+
err: boolean;
|
|
19
|
+
user: any;
|
|
20
|
+
msg?: undefined;
|
|
21
|
+
}>;
|
|
22
|
+
export declare function checkUserAccess(login: any, password: any): Promise<{
|
|
23
|
+
err: boolean;
|
|
24
|
+
msg: string;
|
|
25
|
+
user?: undefined;
|
|
26
|
+
} | {
|
|
27
|
+
err: boolean;
|
|
28
|
+
user: any;
|
|
29
|
+
msg?: undefined;
|
|
30
|
+
}>;
|
|
31
|
+
export declare function removeUser(idOrLogin: any): Promise<any>;
|
|
@@ -2,99 +2,86 @@ import jwt from "jwt-simple";
|
|
|
2
2
|
import NodeCache from "node-cache";
|
|
3
3
|
import getSecret from "./secret.js";
|
|
4
4
|
import crypto from "crypto";
|
|
5
|
-
|
|
6
|
-
const TOKEN_CACHE_TTL = process.env.TOKEN_CACHE_TTL || 900; // 15 minutes
|
|
5
|
+
const TOKEN_CACHE_TTL = parseInt(process.env.TOKEN_CACHE_TTL) || 900; // 15 minutes
|
|
7
6
|
const cache = new NodeCache({ stdTTL: TOKEN_CACHE_TTL, checkperiod: TOKEN_CACHE_TTL });
|
|
8
7
|
const secret = getSecret();
|
|
9
|
-
|
|
10
|
-
export async function authMiddleware(req, res, next){
|
|
8
|
+
export async function authMiddleware(req, res, next) {
|
|
11
9
|
const token = req.headers["authorization"];
|
|
12
|
-
if(!token){
|
|
10
|
+
if (!token) {
|
|
13
11
|
return res.status(401).json({ err: true, msg: "Access denied. No token provided." });
|
|
14
12
|
}
|
|
15
|
-
|
|
16
|
-
if(cache.has(token)){
|
|
13
|
+
if (cache.has(token)) {
|
|
17
14
|
req.user = cache.get(token);
|
|
18
15
|
return next();
|
|
19
16
|
}
|
|
20
|
-
|
|
21
|
-
try{
|
|
17
|
+
try {
|
|
22
18
|
const user = jwt.decode(token, secret);
|
|
23
|
-
if(!user || !user._id){
|
|
19
|
+
if (!user || !user._id) {
|
|
24
20
|
return res.status(401).json({ err: true, msg: "Invalid token." });
|
|
25
21
|
}
|
|
26
|
-
|
|
27
22
|
const tokenD = await global.db.findOne("token", { token });
|
|
28
|
-
if(!tokenD){
|
|
23
|
+
if (!tokenD) {
|
|
29
24
|
return res.status(401).json({ err: true, msg: "Invalid token." });
|
|
30
25
|
}
|
|
31
|
-
|
|
32
26
|
const userD = await global.db.findOne("user", { _id: user._id });
|
|
33
|
-
if(!userD){
|
|
27
|
+
if (!userD) {
|
|
34
28
|
return res.status(401).json({ err: true, msg: "Invalid token." });
|
|
35
29
|
}
|
|
36
|
-
|
|
37
30
|
req.user = user;
|
|
38
31
|
cache.set(token, user);
|
|
39
32
|
next();
|
|
40
|
-
}
|
|
33
|
+
}
|
|
34
|
+
catch (err) {
|
|
41
35
|
res.status(400).json({ err: true, msg: "An error occurred during authentication." });
|
|
42
36
|
}
|
|
43
37
|
}
|
|
44
|
-
|
|
45
|
-
export async function loginFunction(login, password){
|
|
38
|
+
export async function loginFunction(login, password) {
|
|
46
39
|
const { err, user } = await checkUserAccess(login, password);
|
|
47
|
-
if(err){
|
|
40
|
+
if (err) {
|
|
48
41
|
return { err: true, msg: "Invalid login or password." };
|
|
49
42
|
}
|
|
50
|
-
|
|
51
43
|
const token = await generateToken({ _id: user._id });
|
|
52
44
|
cache.set(token, user);
|
|
53
45
|
return { err: false, token };
|
|
54
46
|
}
|
|
55
|
-
|
|
56
|
-
export async function generateToken(payload){
|
|
47
|
+
export async function generateToken(payload) {
|
|
57
48
|
const token = jwt.encode(payload, secret);
|
|
58
49
|
await global.db.add("token", { token }, false);
|
|
59
50
|
return token;
|
|
60
51
|
}
|
|
61
|
-
|
|
62
|
-
export async function removeToken(token){
|
|
52
|
+
export async function removeToken(token) {
|
|
63
53
|
return await global.db.removeOne("token", { token });
|
|
64
54
|
}
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
if(login.length < 3 || login.length > 10)
|
|
69
|
-
|
|
70
|
-
|
|
55
|
+
export async function addUserAccess(login, password) {
|
|
56
|
+
if (!/^[a-zA-Z0-9]+$/.test(login))
|
|
57
|
+
return { err: true, msg: "Login can only contain letters and numbers." };
|
|
58
|
+
if (login.length < 3 || login.length > 10)
|
|
59
|
+
return { err: true, msg: "Login must be between 3 and 10 characters." };
|
|
60
|
+
if (password.length < 8 || password.length > 300)
|
|
61
|
+
return { err: true, msg: "Password must be between 8 and 300 characters." };
|
|
71
62
|
const userExists = await global.db.findOne("user", { login });
|
|
72
|
-
if(userExists)
|
|
73
|
-
|
|
63
|
+
if (userExists)
|
|
64
|
+
return { err: true, msg: "Login already exists." };
|
|
74
65
|
password = generateHash(password);
|
|
75
|
-
|
|
76
66
|
const user = await global.db.add("user", {
|
|
77
67
|
login,
|
|
78
68
|
password
|
|
79
69
|
});
|
|
80
70
|
return { err: false, user };
|
|
81
71
|
}
|
|
82
|
-
|
|
83
|
-
export async function checkUserAccess(login, password){
|
|
72
|
+
export async function checkUserAccess(login, password) {
|
|
84
73
|
const user = await global.db.findOne("user", { login });
|
|
85
|
-
if(!user)
|
|
86
|
-
|
|
74
|
+
if (!user)
|
|
75
|
+
return { err: true, msg: "Invalid login or password." };
|
|
87
76
|
const hash = generateHash(password);
|
|
88
|
-
if(hash !== user.password)
|
|
89
|
-
|
|
77
|
+
if (hash !== user.password)
|
|
78
|
+
return { err: true, msg: "Invalid login or password." };
|
|
90
79
|
delete user.password;
|
|
91
80
|
return { err: false, user };
|
|
92
81
|
}
|
|
93
|
-
|
|
94
|
-
export async function removeUser(idOrLogin){
|
|
82
|
+
export async function removeUser(idOrLogin) {
|
|
95
83
|
return await global.db.removeOne("user", { $or: [{ _id: idOrLogin }, { login: idOrLogin }] });
|
|
96
84
|
}
|
|
97
|
-
|
|
98
|
-
function generateHash(password){
|
|
85
|
+
function generateHash(password) {
|
|
99
86
|
return crypto.createHash("sha256").update(password).digest("hex");
|
|
100
|
-
}
|
|
87
|
+
}
|
|
@@ -0,0 +1,218 @@
|
|
|
1
|
+
import { Router } from "express";
|
|
2
|
+
import deserializeFunctions from "./function.js";
|
|
3
|
+
import { isPathSafe } from "./pathUtils.js";
|
|
4
|
+
const router = Router();
|
|
5
|
+
router.use((req, res, next) => {
|
|
6
|
+
if (req.dbType == "database")
|
|
7
|
+
return next();
|
|
8
|
+
return res.status(400).json({ err: true, msg: "Invalid data center type." });
|
|
9
|
+
});
|
|
10
|
+
router.post("/getCollections", async (req, res) => {
|
|
11
|
+
try {
|
|
12
|
+
const db = req.dataCenter;
|
|
13
|
+
const result = await db.getCollections();
|
|
14
|
+
res.json({ err: false, result });
|
|
15
|
+
}
|
|
16
|
+
catch (err) {
|
|
17
|
+
console.error(err);
|
|
18
|
+
res.status(500).json({ err: true, msg: err.message });
|
|
19
|
+
}
|
|
20
|
+
});
|
|
21
|
+
router.post("/checkCollection", async (req, res) => {
|
|
22
|
+
const { collection } = req.body;
|
|
23
|
+
if (!collection)
|
|
24
|
+
return res.status(400).json({ err: true, msg: "collection is required" });
|
|
25
|
+
if (!isPathSafe(global.baseDir, collection))
|
|
26
|
+
return res.status(400).json({ err: true, msg: "invalid collection" });
|
|
27
|
+
try {
|
|
28
|
+
const db = req.dataCenter;
|
|
29
|
+
await db.checkCollection(collection);
|
|
30
|
+
res.json({ err: false, result: true });
|
|
31
|
+
}
|
|
32
|
+
catch (err) {
|
|
33
|
+
console.error(err);
|
|
34
|
+
res.status(500).json({ err: true, msg: err.message });
|
|
35
|
+
}
|
|
36
|
+
});
|
|
37
|
+
router.post("/issetCollection", async (req, res) => {
|
|
38
|
+
const { collection } = req.body;
|
|
39
|
+
if (!collection)
|
|
40
|
+
return res.status(400).json({ err: true, msg: "collection is required" });
|
|
41
|
+
if (!isPathSafe(global.baseDir, collection))
|
|
42
|
+
return res.status(400).json({ err: true, msg: "invalid collection" });
|
|
43
|
+
try {
|
|
44
|
+
const db = req.dataCenter;
|
|
45
|
+
const result = await db.issetCollection(collection);
|
|
46
|
+
res.json({ err: false, result });
|
|
47
|
+
}
|
|
48
|
+
catch (err) {
|
|
49
|
+
console.error(err);
|
|
50
|
+
res.status(500).json({ err: true, msg: err.message });
|
|
51
|
+
}
|
|
52
|
+
});
|
|
53
|
+
router.post("/add", async (req, res) => {
|
|
54
|
+
const { collection, data } = req.body;
|
|
55
|
+
if (!collection || !data)
|
|
56
|
+
return res.status(400).json({ err: true, msg: "collection & data is required" });
|
|
57
|
+
if (!isPathSafe(global.baseDir, collection))
|
|
58
|
+
return res.status(400).json({ err: true, msg: "invalid collection" });
|
|
59
|
+
try {
|
|
60
|
+
const db = req.dataCenter;
|
|
61
|
+
const result = await db.add(collection, data, req.body.id_gen || true);
|
|
62
|
+
res.json({ err: false, result });
|
|
63
|
+
}
|
|
64
|
+
catch (err) {
|
|
65
|
+
console.error(err);
|
|
66
|
+
res.status(500).json({ err: true, msg: err.message });
|
|
67
|
+
}
|
|
68
|
+
});
|
|
69
|
+
router.post("/find", async (req, res) => {
|
|
70
|
+
const { collection, search, context, options, findOpts, keys } = req.body;
|
|
71
|
+
if (!collection || !search)
|
|
72
|
+
return res.status(400).json({ err: true, msg: "collection & search is required" });
|
|
73
|
+
if (!isPathSafe(global.baseDir, collection))
|
|
74
|
+
return res.status(400).json({ err: true, msg: "invalid collection" });
|
|
75
|
+
if (keys && !Array.isArray(keys))
|
|
76
|
+
return res.status(400).json({ err: true, msg: "keys must be an array" });
|
|
77
|
+
try {
|
|
78
|
+
const data = deserializeFunctions({ search, context, options, findOpts }, keys || []);
|
|
79
|
+
const db = req.dataCenter;
|
|
80
|
+
const result = await db.find(collection, data.search, data.context || {}, data.options || {}, data.findOpts || {});
|
|
81
|
+
res.json({ err: false, result });
|
|
82
|
+
}
|
|
83
|
+
catch (err) {
|
|
84
|
+
console.error(err);
|
|
85
|
+
res.status(500).json({ err: true, msg: err.message });
|
|
86
|
+
}
|
|
87
|
+
});
|
|
88
|
+
router.post("/findOne", async (req, res) => {
|
|
89
|
+
const { collection, search, context, findOpts, keys } = req.body;
|
|
90
|
+
if (!collection || !search)
|
|
91
|
+
return res.status(400).json({ err: true, msg: "collection & search is required" });
|
|
92
|
+
if (!isPathSafe(global.baseDir, collection))
|
|
93
|
+
return res.status(400).json({ err: true, msg: "invalid collection" });
|
|
94
|
+
if (keys && !Array.isArray(keys))
|
|
95
|
+
return res.status(400).json({ err: true, msg: "keys must be an array" });
|
|
96
|
+
try {
|
|
97
|
+
const data = deserializeFunctions({ search, context, findOpts }, keys || []);
|
|
98
|
+
const db = req.dataCenter;
|
|
99
|
+
const result = await db.findOne(collection, data.search, data.context || {}, data.findOpts || {});
|
|
100
|
+
res.json({ err: false, result });
|
|
101
|
+
}
|
|
102
|
+
catch (err) {
|
|
103
|
+
console.error(err);
|
|
104
|
+
res.status(500).json({ err: true, msg: err.message });
|
|
105
|
+
}
|
|
106
|
+
});
|
|
107
|
+
router.post("/update", async (req, res) => {
|
|
108
|
+
const { collection, search, arg, context, keys } = req.body;
|
|
109
|
+
if (!collection || !search || !arg)
|
|
110
|
+
return res.status(400).json({ err: true, msg: "collection & search & arg is required" });
|
|
111
|
+
if (!isPathSafe(global.baseDir, collection))
|
|
112
|
+
return res.status(400).json({ err: true, msg: "invalid collection" });
|
|
113
|
+
if (keys && !Array.isArray(keys))
|
|
114
|
+
return res.status(400).json({ err: true, msg: "keys must be an array" });
|
|
115
|
+
try {
|
|
116
|
+
const data = deserializeFunctions({ search, arg, context }, keys || []);
|
|
117
|
+
const db = req.dataCenter;
|
|
118
|
+
const result = await db.update(collection, data.search, data.arg, data.context || {});
|
|
119
|
+
res.json({ err: false, result });
|
|
120
|
+
}
|
|
121
|
+
catch (err) {
|
|
122
|
+
console.error(err);
|
|
123
|
+
res.status(500).json({ err: true, msg: err.message });
|
|
124
|
+
}
|
|
125
|
+
});
|
|
126
|
+
router.post("/updateOne", async (req, res) => {
|
|
127
|
+
const { collection, search, arg, context, keys } = req.body;
|
|
128
|
+
if (!collection || !search || !arg)
|
|
129
|
+
return res.status(400).json({ err: true, msg: "collection & search & arg is required" });
|
|
130
|
+
if (!isPathSafe(global.baseDir, collection))
|
|
131
|
+
return res.status(400).json({ err: true, msg: "invalid collection" });
|
|
132
|
+
if (keys && !Array.isArray(keys))
|
|
133
|
+
return res.status(400).json({ err: true, msg: "keys must be an array" });
|
|
134
|
+
try {
|
|
135
|
+
const data = deserializeFunctions({ search, arg, context }, keys || []);
|
|
136
|
+
const db = req.dataCenter;
|
|
137
|
+
const result = await db.updateOne(collection, data.search, data.arg, data.context || {});
|
|
138
|
+
res.json({ err: false, result });
|
|
139
|
+
}
|
|
140
|
+
catch (err) {
|
|
141
|
+
console.error(err);
|
|
142
|
+
res.status(500).json({ err: true, msg: err.message });
|
|
143
|
+
}
|
|
144
|
+
});
|
|
145
|
+
router.post("/remove", async (req, res) => {
|
|
146
|
+
const { collection, search, context, keys } = req.body;
|
|
147
|
+
if (!collection || !search)
|
|
148
|
+
return res.status(400).json({ err: true, msg: "collection & search is required" });
|
|
149
|
+
if (!isPathSafe(global.baseDir, collection))
|
|
150
|
+
return res.status(400).json({ err: true, msg: "invalid collection" });
|
|
151
|
+
if (keys && !Array.isArray(keys))
|
|
152
|
+
return res.status(400).json({ err: true, msg: "keys must be an array" });
|
|
153
|
+
try {
|
|
154
|
+
const data = deserializeFunctions({ search, context }, keys || []);
|
|
155
|
+
const db = req.dataCenter;
|
|
156
|
+
const result = await db.remove(collection, data.search, data.context || {});
|
|
157
|
+
res.json({ err: false, result });
|
|
158
|
+
}
|
|
159
|
+
catch (err) {
|
|
160
|
+
console.error(err);
|
|
161
|
+
res.status(500).json({ err: true, msg: err.message });
|
|
162
|
+
}
|
|
163
|
+
});
|
|
164
|
+
router.post("/removeOne", async (req, res) => {
|
|
165
|
+
const { collection, search, context, keys } = req.body;
|
|
166
|
+
if (!collection || !search)
|
|
167
|
+
return res.status(400).json({ err: true, msg: "collection & search is required" });
|
|
168
|
+
if (!isPathSafe(global.baseDir, collection))
|
|
169
|
+
return res.status(400).json({ err: true, msg: "invalid collection" });
|
|
170
|
+
if (keys && !Array.isArray(keys))
|
|
171
|
+
return res.status(400).json({ err: true, msg: "keys must be an array" });
|
|
172
|
+
try {
|
|
173
|
+
const data = deserializeFunctions({ search, context }, keys || []);
|
|
174
|
+
const db = req.dataCenter;
|
|
175
|
+
const result = await db.removeOne(collection, data.search, data.context || {});
|
|
176
|
+
res.json({ err: false, result });
|
|
177
|
+
}
|
|
178
|
+
catch (err) {
|
|
179
|
+
console.error(err);
|
|
180
|
+
res.status(500).json({ err: true, msg: err.message });
|
|
181
|
+
}
|
|
182
|
+
});
|
|
183
|
+
router.post("/updateOneOrAdd", async (req, res) => {
|
|
184
|
+
const { collection, search, arg, add_arg, context, id_gen, keys } = req.body;
|
|
185
|
+
if (!collection || !search || !arg)
|
|
186
|
+
return res.status(400).json({ err: true, msg: "collection & search & arg is required" });
|
|
187
|
+
if (!isPathSafe(global.baseDir, collection))
|
|
188
|
+
return res.status(400).json({ err: true, msg: "invalid collection" });
|
|
189
|
+
if (keys && !Array.isArray(keys))
|
|
190
|
+
return res.status(400).json({ err: true, msg: "keys must be an array" });
|
|
191
|
+
try {
|
|
192
|
+
const data = deserializeFunctions({ search, arg, add_arg, context }, keys || []);
|
|
193
|
+
const db = req.dataCenter;
|
|
194
|
+
const result = await db.updateOneOrAdd(collection, data.search, data.arg, data.add_arg || {}, data.context || {}, id_gen || true);
|
|
195
|
+
res.json({ err: false, result });
|
|
196
|
+
}
|
|
197
|
+
catch (err) {
|
|
198
|
+
console.error(err);
|
|
199
|
+
res.status(500).json({ err: true, msg: err.message });
|
|
200
|
+
}
|
|
201
|
+
});
|
|
202
|
+
router.post("/removeCollection", async (req, res) => {
|
|
203
|
+
const { name } = req.body;
|
|
204
|
+
if (!name)
|
|
205
|
+
return res.status(400).json({ err: true, msg: "name is required" });
|
|
206
|
+
if (!isPathSafe(global.baseDir, name))
|
|
207
|
+
return res.status(400).json({ err: true, msg: "invalid name" });
|
|
208
|
+
try {
|
|
209
|
+
const db = req.dataCenter;
|
|
210
|
+
const result = await db.removeCollection(name);
|
|
211
|
+
res.json({ err: false, result });
|
|
212
|
+
}
|
|
213
|
+
catch (err) {
|
|
214
|
+
console.error(err);
|
|
215
|
+
res.status(500).json({ err: true, msg: err.message });
|
|
216
|
+
}
|
|
217
|
+
});
|
|
218
|
+
export default router;
|
|
@@ -0,0 +1,87 @@
|
|
|
1
|
+
import { createContext, runInContext } from "node:vm";
|
|
2
|
+
const sandbox = {
|
|
3
|
+
console: {
|
|
4
|
+
log: console.log,
|
|
5
|
+
},
|
|
6
|
+
Math,
|
|
7
|
+
Date,
|
|
8
|
+
setTimeout: undefined,
|
|
9
|
+
setInterval: undefined,
|
|
10
|
+
setImmediate: undefined,
|
|
11
|
+
clearTimeout: undefined,
|
|
12
|
+
clearInterval: undefined,
|
|
13
|
+
clearImmediate: undefined,
|
|
14
|
+
require: undefined,
|
|
15
|
+
module: undefined,
|
|
16
|
+
exports: undefined,
|
|
17
|
+
process: undefined,
|
|
18
|
+
Buffer: undefined,
|
|
19
|
+
};
|
|
20
|
+
const context = createContext(sandbox);
|
|
21
|
+
function changeStringToFunction(func) {
|
|
22
|
+
try {
|
|
23
|
+
const userFunction = runInContext(`(${func})`, context);
|
|
24
|
+
return userFunction;
|
|
25
|
+
}
|
|
26
|
+
catch (e) {
|
|
27
|
+
throw new Error("Invalid function");
|
|
28
|
+
}
|
|
29
|
+
}
|
|
30
|
+
function deserializeFunctions(data, keys) {
|
|
31
|
+
const setAtPath = (obj, path, value) => {
|
|
32
|
+
const segments = path.split(".").map(segment => segment.replace(/\[dot\]/g, "."));
|
|
33
|
+
let currentLevel = obj;
|
|
34
|
+
for (let i = 0; i < segments.length - 1; i++) {
|
|
35
|
+
const segment = segments[i];
|
|
36
|
+
if (Array.isArray(currentLevel)) {
|
|
37
|
+
const index = parseInt(segment, 10);
|
|
38
|
+
if (!currentLevel[index])
|
|
39
|
+
currentLevel[index] = {};
|
|
40
|
+
currentLevel = currentLevel[index];
|
|
41
|
+
}
|
|
42
|
+
else if (!currentLevel[segment]) {
|
|
43
|
+
currentLevel[segment] = {};
|
|
44
|
+
currentLevel = currentLevel[segment];
|
|
45
|
+
}
|
|
46
|
+
else {
|
|
47
|
+
currentLevel = currentLevel[segment];
|
|
48
|
+
}
|
|
49
|
+
}
|
|
50
|
+
currentLevel[segments[segments.length - 1]] = value;
|
|
51
|
+
};
|
|
52
|
+
const getAtPath = (obj, path) => {
|
|
53
|
+
const segments = path.split(".").map(key => key.replace(/\[dot\]/g, "."));
|
|
54
|
+
return segments.reduce((acc, key) => {
|
|
55
|
+
if (Array.isArray(acc)) {
|
|
56
|
+
const index = parseInt(key, 10);
|
|
57
|
+
return acc[index];
|
|
58
|
+
}
|
|
59
|
+
return acc && acc[key];
|
|
60
|
+
}, obj);
|
|
61
|
+
};
|
|
62
|
+
keys.forEach((keyPath) => {
|
|
63
|
+
const value = getAtPath(data, keyPath);
|
|
64
|
+
if (typeof value === "string") {
|
|
65
|
+
const fn = changeStringToFunction(value);
|
|
66
|
+
setAtPath(data, keyPath, fn);
|
|
67
|
+
}
|
|
68
|
+
else if (typeof value === "object" && value !== null) {
|
|
69
|
+
if (Array.isArray(value)) {
|
|
70
|
+
value.forEach((item, index) => {
|
|
71
|
+
if (typeof item === "string") {
|
|
72
|
+
value[index] = changeStringToFunction(item);
|
|
73
|
+
}
|
|
74
|
+
});
|
|
75
|
+
}
|
|
76
|
+
else {
|
|
77
|
+
Object.keys(value).forEach((key) => {
|
|
78
|
+
if (typeof value[key] === "string") {
|
|
79
|
+
value[key] = changeStringToFunction(value[key]);
|
|
80
|
+
}
|
|
81
|
+
});
|
|
82
|
+
}
|
|
83
|
+
}
|
|
84
|
+
});
|
|
85
|
+
return data;
|
|
86
|
+
}
|
|
87
|
+
export default deserializeFunctions;
|