Adding new query handler
This commit is contained in:
		
							
								
								
									
										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", | ||||||
|  | |||||||
| @ -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
	 Fabian
					Fabian