Adding new query handler
This commit is contained in:
parent
68011e3866
commit
9f944549b6
3
.editorconfig
Normal file
3
.editorconfig
Normal file
@ -0,0 +1,3 @@
|
|||||||
|
charset = utf-8
|
||||||
|
indent_size = 3
|
||||||
|
indent_style = space
|
6
package-lock.json
generated
6
package-lock.json
generated
@ -122,12 +122,6 @@
|
|||||||
"integrity": "sha512-PGAK759pxyfXE78NbKxyfRcWYA/KwW17X290cNev/qAsn9eQIxkH4shoNBafH37wewhDG/0p1cHPbK6+SzZjWQ==",
|
"integrity": "sha512-PGAK759pxyfXE78NbKxyfRcWYA/KwW17X290cNev/qAsn9eQIxkH4shoNBafH37wewhDG/0p1cHPbK6+SzZjWQ==",
|
||||||
"dev": true
|
"dev": true
|
||||||
},
|
},
|
||||||
"@types/ini": {
|
|
||||||
"version": "1.3.30",
|
|
||||||
"resolved": "https://registry.npmjs.org/@types/ini/-/ini-1.3.30.tgz",
|
|
||||||
"integrity": "sha512-2+iF8zPSbpU83UKE+PNd4r/MhwNAdyGpk3H+VMgEH3EhjFZq1kouLgRoZrmIcmoGX97xFvqdS44DkICR5Nz3tQ==",
|
|
||||||
"dev": true
|
|
||||||
},
|
|
||||||
"@types/jsonwebtoken": {
|
"@types/jsonwebtoken": {
|
||||||
"version": "8.3.5",
|
"version": "8.3.5",
|
||||||
"resolved": "https://registry.npmjs.org/@types/jsonwebtoken/-/jsonwebtoken-8.3.5.tgz",
|
"resolved": "https://registry.npmjs.org/@types/jsonwebtoken/-/jsonwebtoken-8.3.5.tgz",
|
||||||
|
@ -44,4 +44,4 @@
|
|||||||
"what-the-pack": "^2.0.3",
|
"what-the-pack": "^2.0.3",
|
||||||
"ws": "^7.2.0"
|
"ws": "^7.2.0"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -19,6 +19,21 @@ async function verifyJWT(token: string, publicKey: string) {
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const StoreSym = Symbol("store");
|
||||||
|
function StoreQuery(result?: any) {
|
||||||
|
return {
|
||||||
|
[StoreSym]: true,
|
||||||
|
result
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function DeleteQuery(result?: any) {
|
||||||
|
return {
|
||||||
|
[StoreSym]: false,
|
||||||
|
result
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
import { URLSearchParams } from "url";
|
import { URLSearchParams } from "url";
|
||||||
|
|
||||||
type QueryTypes = "keys" | "get" | "set" | "update" | "delete" | "push" | "subscribe" | "unsubscribe";
|
type QueryTypes = "keys" | "get" | "set" | "update" | "delete" | "push" | "subscribe" | "unsubscribe";
|
||||||
@ -84,68 +99,85 @@ export class ConnectionManager {
|
|||||||
|
|
||||||
const handler = new Map<string, ((data: any) => void)>();
|
const handler = new Map<string, ((data: any) => void)>();
|
||||||
type QueryData = { id: string, type: QueryTypes, path: string[], data: any, options: any };
|
type QueryData = { id: string, type: QueryTypes, path: string[], data: any, options: any };
|
||||||
|
|
||||||
|
const queryHandler = new Map<string, (query: Query, permissions: { read: boolean, write: boolean }, data?: any) => Promise<any>>();
|
||||||
|
|
||||||
|
const noperm = new Error("No permisison!");
|
||||||
|
|
||||||
|
queryHandler.set("keys", (query, perm, data) => {
|
||||||
|
if (!perm.read)
|
||||||
|
throw noperm;
|
||||||
|
return query.keys();
|
||||||
|
})
|
||||||
|
|
||||||
|
queryHandler.set("get", (query, perm, data) => {
|
||||||
|
if (!perm.read)
|
||||||
|
throw noperm;
|
||||||
|
return query.get();
|
||||||
|
})
|
||||||
|
|
||||||
|
queryHandler.set("set", (query, perm, data) => {
|
||||||
|
if (!perm.write)
|
||||||
|
throw noperm;
|
||||||
|
return query.set(data, {});
|
||||||
|
})
|
||||||
|
|
||||||
|
queryHandler.set("update", (query, perm, data) => {
|
||||||
|
if (!perm.write)
|
||||||
|
throw noperm;
|
||||||
|
return query.update(data);
|
||||||
|
})
|
||||||
|
|
||||||
|
queryHandler.set("delete", (query, perm, data) => {
|
||||||
|
if (!perm.write)
|
||||||
|
throw noperm;
|
||||||
|
return query.delete();
|
||||||
|
})
|
||||||
|
|
||||||
|
queryHandler.set("subscribe", async (query, perm, data) => {
|
||||||
|
if (!perm.read)
|
||||||
|
throw noperm;
|
||||||
|
|
||||||
|
let subscriptionID = shortid.generate();
|
||||||
|
|
||||||
|
query.subscribe((data) => {
|
||||||
|
socket.send(JSON.stringify({ ns: "event", data: { id: subscriptionID, data } }));
|
||||||
|
}, data.types, data.options);
|
||||||
|
|
||||||
|
return StoreQuery(subscriptionID);
|
||||||
|
})
|
||||||
|
|
||||||
|
queryHandler.set("unsubscribe", async (query, perm, data) => {
|
||||||
|
query.unsubscribe();
|
||||||
|
return DeleteQuery(true);
|
||||||
|
})
|
||||||
|
|
||||||
handler.set("query", async ({ id, type, path, data }: QueryData) => {
|
handler.set("query", async ({ id, type, path, data }: QueryData) => {
|
||||||
//TODO: Handle case with no id, type, path
|
//TODO: Handle case with no id, type, path
|
||||||
Logging.debug(`Request with id '${id}' from type '${type}' and path '${path}' with data`, data)
|
Logging.debug(`Request with id '${id}' from type '${type}' and path '${path}' with data`, data)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
try {
|
try {
|
||||||
const perms = db.rules.hasPermission(path, session);
|
|
||||||
const noperm = new Error("No permisison!");
|
|
||||||
if (!db)
|
if (!db)
|
||||||
answer(id, "Database not found!", true);
|
throw new Error("Database not found!");
|
||||||
else {
|
else {
|
||||||
const query = stored.get(id) || db.getQuery(path, session.sessionid);
|
let handler = queryHandler.get(type);
|
||||||
|
if (!handler) {
|
||||||
|
throw new Error("Invalid Request!");
|
||||||
|
} else {
|
||||||
|
const query = stored.get(id) || db.getQuery(path || [], session.sessionid);
|
||||||
|
const perms = db.rules.hasPermission(path, session);
|
||||||
|
|
||||||
switch (type) {
|
let res = await handler(query, perms, data);
|
||||||
case "keys":
|
if (res[StoreSym] !== undefined) {
|
||||||
if (!perms.read)
|
if (res[StoreSym])
|
||||||
throw noperm;
|
stored.set(id, query);
|
||||||
answer(id, await query.keys());
|
else
|
||||||
return;
|
stored.delete(id);
|
||||||
case "get":
|
}
|
||||||
if (!perms.read)
|
answer(id, res);
|
||||||
throw noperm;
|
|
||||||
answer(id, await query.get());
|
|
||||||
return;
|
|
||||||
case "set":
|
|
||||||
if (!perms.write)
|
|
||||||
throw noperm;
|
|
||||||
answer(id, await query.set(data, {}));
|
|
||||||
return;
|
|
||||||
case "update":
|
|
||||||
if (!perms.write)
|
|
||||||
throw noperm;
|
|
||||||
answer(id, await query.update(data));
|
|
||||||
return;
|
|
||||||
case "delete":
|
|
||||||
if (!perms.write)
|
|
||||||
throw noperm;
|
|
||||||
answer(id, await query.delete());
|
|
||||||
return;
|
|
||||||
case "push":
|
|
||||||
if (!perms.write)
|
|
||||||
throw noperm;
|
|
||||||
answer(id, await query.push(data));
|
|
||||||
return;
|
|
||||||
case "subscribe":
|
|
||||||
if (!perms.read)
|
|
||||||
throw noperm;
|
|
||||||
|
|
||||||
let subscriptionID = shortid.generate();
|
|
||||||
|
|
||||||
query.subscribe((data) => {
|
|
||||||
socket.send(JSON.stringify({ ns: "event", data: { id: subscriptionID, data } }));
|
|
||||||
}, data.types, data.options);
|
|
||||||
stored.set(id, query);
|
|
||||||
answer(id, subscriptionID);
|
|
||||||
return;
|
|
||||||
case "unsubscribe":
|
|
||||||
query.unsubscribe();
|
|
||||||
stored.delete(id);
|
|
||||||
answer(id, true);
|
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
answer(id, "Invalid request!", true);
|
|
||||||
}
|
}
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
Logging.error(err);
|
Logging.error(err);
|
||||||
|
@ -1,6 +1,5 @@
|
|||||||
import { Database, Change, ChangeTypes } from "./database";
|
import { Database, Change, ChangeTypes } from "./database";
|
||||||
import { resNull, LevelDB } from "../storage";
|
import { resNull } from "../storage";
|
||||||
import { LevelUpChain } from "levelup";
|
|
||||||
import shortid = require("shortid");
|
import shortid = require("shortid");
|
||||||
import Logging from "@hibas123/nodelogging";
|
import Logging from "@hibas123/nodelogging";
|
||||||
import * as MSGPack from "what-the-pack";
|
import * as MSGPack from "what-the-pack";
|
||||||
|
Reference in New Issue
Block a user