From ff6e692633054f2c5f8d3ce01b00147838a6894d Mon Sep 17 00:00:00 2001 From: Alan Meekins Date: Tue, 13 Dec 2022 03:26:05 -0800 Subject: [PATCH 01/13] basic websocket server listening --- examples/test-service-host.js | 8 ++- package.json | 1 + src/service/service-host-websocket.js | 99 +++++++++++++++++++++++++++ src/service/service-host.js | 21 +++++- 4 files changed, 125 insertions(+), 4 deletions(-) create mode 100644 src/service/service-host-websocket.js diff --git a/examples/test-service-host.js b/examples/test-service-host.js index 319a05a..83b8a31 100644 --- a/examples/test-service-host.js +++ b/examples/test-service-host.js @@ -37,7 +37,7 @@ async function main(){ const service = new ExampleService({ name: '@dataparty/example', version: '0.0.1' }) - const build = await service.compile(Path.join(__dirname,'../dataparty'), true) + const build = await service.compile(Path.join(__dirname,'/dataparty'), true) debug('built', Object.keys(build)) @@ -46,7 +46,11 @@ async function main(){ sendFullErrors: true }) - const host = new Dataparty.ServiceHost({runner, trust_proxy: true}) + const host = new Dataparty.ServiceHost({ + runner, + trust_proxy: false, + wsEnabled: true + }) await party.start() await runner.start() diff --git a/package.json b/package.json index ea79e2e..79c56be 100644 --- a/package.json +++ b/package.json @@ -102,6 +102,7 @@ "uuidv4": "^6.2.12", "vm2": "^3.9.2", "websocket": "github:sevenbitbyte/WebSocket-Node#parcel-build", + "ws": "^8.11.0", "zangodb": "github:sevenbitbyte/zangodb#hash-patch" }, "devDependencies": { diff --git a/src/service/service-host-websocket.js b/src/service/service-host-websocket.js new file mode 100644 index 0000000..cb92e00 --- /dev/null +++ b/src/service/service-host-websocket.js @@ -0,0 +1,99 @@ +const {URL} = require('url') +const debug = require('debug')('dataparty.service-host-websocket') + +const ws = require('ws') +const WebSocketServer = ws.WebSocketServer + +const WATCHDOG_INTERVAL = 30000 + +class ServiceHostWebsocket{ + + constructor({trust_proxy, port, path, runner, wsSettings}){ + this.port = port + this.path = path || '/ws' + this.runner = runner + this.trust_proxy = trust_proxy + this.wsSettings = wsSettings || {} + + this.ws = null + } + + start(server){ + + debug('start') + + let settings = {} + + if(!server){ + settings = { port: this.port, ...this.wsSettings } + + } else { + settings = { noServer: true, ...this.wsSettings } + } + + debug('\t','settings', settings) + + this.ws = new WebSocketServer(settings) + + this.ws.on('connection', this.handleConnection.bind(this)) + + server.on('upgrade', this.handleUpgrade.bind(this)) + + this.watchdog = setInterval(this.checkClients.bind(this), WATCHDOG_INTERVAL) + } + + handleUpgrade(request, socket, head){ + + debug('handleUpgrade', request.url) + + if(request.url == this.path){ + this.doUpgrade(request, socket, head) + } else { + socket.destroy() + } + } + + doUpgrade(request, socket, head){ + debug('doUpgrade') + this.ws.handleUpgrade(request, socket, head, (conn)=>{ + debug('head', head) + this.ws.emit('connection', conn, request) + }) + } + + getConnectionIp(req){ + if(this.trust_proxy){ + const ip = req.headers['x-forwarded-for'].split(',')[0].trim(); + + return ip + } + + return req.socket.remoteAddress + } + + handleConnection(conn, req){ + conn.ip = this.getConnectionIp(req) + + debug('handleConnection - ', conn.ip) + + conn.isAlive = true + conn.on('pong', ()=>{ + conn.isAlive = true + }) + } + + checkClients(){ + debug('checkClients') + this.ws.clients.forEach( (conn)=>{ + if (conn.isAlive === false){ + debug('\t','terminating client') + return conn.terminate() + } + + conn.isAlive = false + conn.ping() + }); + } +} + +module.exports = ServiceHostWebsocket \ No newline at end of file diff --git a/src/service/service-host.js b/src/service/service-host.js index 508d214..3b6b115 100644 --- a/src/service/service-host.js +++ b/src/service/service-host.js @@ -9,6 +9,8 @@ const bodyParser = require('body-parser') const expressListRoutes = require('express-list-routes') const debug = require('debug')('dataparty.service-host') +const ServiceHostWebsocket = require('./service-host-websocket') + const Pify = async (p)=>{ return await p } @@ -22,6 +24,8 @@ class ServiceHost { cors = {}, trust_proxy = false, listenUri = 'http://0.0.0.0:4001', + wsEnabled = true, + wsPort = null, runner }={}){ this.apiApp = express() @@ -45,11 +49,20 @@ class ServiceHost { this.errorHandlerTimer = null this.apiServerUri = new URL(listenUri) + + if(wsEnabled){ + this.wsServer = new ServiceHostWebsocket({ + trust_proxy, + port: wsPort, + runner: this.runner + }) + } + } async start(){ - debug('starting server') + debug('starting server', this.apiServerUri.toString()) if(this.apiServer==null){ debug('adding default endpoints') @@ -81,7 +94,6 @@ class ServiceHost { } - debug('server listening', this.apiServerUri.toString()) await new Promise((resolve,reject)=>{ this.apiServer.listen(listenPort, listenHost, resolve) @@ -94,6 +106,11 @@ class ServiceHost { debug('server listening') debug('address', this.apiServer.address()) + + if(this.wsServer && this.apiServer){ + debug('starting websocket') + this.wsServer.start(this.apiServer) + } } async stop(){ From f70dbbf977ade722f9ccc52d49c2436fd7e9c382 Mon Sep 17 00:00:00 2001 From: Alan Meekins Date: Wed, 14 Dec 2022 02:53:38 -0800 Subject: [PATCH 02/13] unsandboxed service host --- examples/test-service-host.js | 2 +- examples/test-service-node-host.js | 68 ++++++ src/party/peer/peer-party.js | 6 - src/sandbox/sandbox.js | 2 +- src/service/endpoints/echo.js | 2 +- src/service/endpoints/secure-echo.js | 2 +- src/service/endpoints/service-identity.js | 2 +- src/service/endpoints/service-version.js | 2 +- src/service/iendpoint.js | 10 +- src/service/imiddleware.js | 11 +- src/service/index.js | 1 + src/service/middleware/post/encrypt.js | 2 +- src/service/middleware/post/validate.js | 2 +- src/service/middleware/pre/decrypt.js | 2 +- src/service/middleware/pre/validate.js | 2 +- src/service/service-host-websocket.js | 27 ++- src/service/service-host.js | 2 +- src/service/service-runner-node.js | 241 ++++++++++++++++++++++ src/service/service-runner.js | 2 +- src/utils/joi-objectid.js | 19 ++ 20 files changed, 381 insertions(+), 26 deletions(-) create mode 100644 examples/test-service-node-host.js create mode 100644 src/service/service-runner-node.js create mode 100644 src/utils/joi-objectid.js diff --git a/examples/test-service-host.js b/examples/test-service-host.js index 83b8a31..dd2c181 100644 --- a/examples/test-service-host.js +++ b/examples/test-service-host.js @@ -48,7 +48,7 @@ async function main(){ const host = new Dataparty.ServiceHost({ runner, - trust_proxy: false, + trust_proxy: true, wsEnabled: true }) diff --git a/examples/test-service-node-host.js b/examples/test-service-node-host.js new file mode 100644 index 0000000..f0886df --- /dev/null +++ b/examples/test-service-node-host.js @@ -0,0 +1,68 @@ +const Path = require('path') +const debug = require('debug')('test.server-db') +const Dataparty = require('../src') + +const BouncerServerModels = require('@dataparty/bouncer-model') +const BouncerClientModels = require('@dataparty/bouncer-model/dist/bouncer-model.json') + +class ExampleService extends Dataparty.IService { + constructor(opts){ + super(opts) + + this.addMiddleware(Dataparty.middleware_paths.pre.decrypt) + this.addMiddleware(Dataparty.middleware_paths.pre.validate) + + this.addMiddleware(Dataparty.middleware_paths.post.validate) + this.addMiddleware(Dataparty.middleware_paths.post.encrypt) + + this.addEndpoint(Dataparty.endpoint_paths.echo) + this.addEndpoint(Dataparty.endpoint_paths.secureecho) + this.addEndpoint(Dataparty.endpoint_paths.identity) + this.addEndpoint(Dataparty.endpoint_paths.version) + } + +} + +async function main(){ + + const uri = 'mongodb://localhost:27017/server-party-test' + debug('db location', uri) + + let party = new Dataparty.MongoParty({ + uri, + model: BouncerClientModels, + serverModels: BouncerServerModels, + config: new Dataparty.Config.MemoryConfig() + }) + + const service = new ExampleService({ name: '@dataparty/example', version: '0.0.1' }) + + const build = await service.compile(Path.join(__dirname,'/dataparty'), true) + + debug('built', Object.keys(build)) + + const runner = new Dataparty.ServiceRunnerNode({ + party, service, + sendFullErrors: true + }) + + const host = new Dataparty.ServiceHost({ + runner, + trust_proxy: true, + wsEnabled: true + }) + + await party.start() + await runner.start() + await host.start() + + console.log('started') + + //process.exit() +} + + + +main().catch(err=>{ + console.error(err) +}) \ No newline at end of file diff --git a/src/party/peer/peer-party.js b/src/party/peer/peer-party.js index 4b84d73..ddb3161 100644 --- a/src/party/peer/peer-party.js +++ b/src/party/peer/peer-party.js @@ -2,10 +2,8 @@ const debug = require('debug')('dataparty.peer-party') -//const WRTC = require('wrtc') const Qb = require('../qb') const IParty = require('../iparty') -//const RTCSocketComms = require('../../comms/rtc-socket-comms') /** * @class @@ -34,10 +32,6 @@ class PeerParty extends IParty { } } - static get WRTC(){ - return WRTC - } - async start(){ await super.start() if(this.comms.host){ diff --git a/src/sandbox/sandbox.js b/src/sandbox/sandbox.js index 185bceb..8ab7c58 100644 --- a/src/sandbox/sandbox.js +++ b/src/sandbox/sandbox.js @@ -40,7 +40,7 @@ class Sandbox { }) let fn = vm.run(this.script) - const retVal = await fn(context) + const retVal = await fn(context, sandbox) return retVal } catch(err) { diff --git a/src/service/endpoints/echo.js b/src/service/endpoints/echo.js index a824156..71dff35 100644 --- a/src/service/endpoints/echo.js +++ b/src/service/endpoints/echo.js @@ -29,7 +29,7 @@ module.exports = class EchoEndpoint extends IEndpoint { } } - static async run(ctx){ + static async run(ctx, {Package}){ ctx.debug('hello') debug('echo') diff --git a/src/service/endpoints/secure-echo.js b/src/service/endpoints/secure-echo.js index dc1ebe7..ab81d15 100644 --- a/src/service/endpoints/secure-echo.js +++ b/src/service/endpoints/secure-echo.js @@ -29,7 +29,7 @@ module.exports = class SecureEchoEndpoint extends IEndpoint { } } - static async run(ctx){ + static async run(ctx, {Package}){ ctx.debug('hello') debug('echo') diff --git a/src/service/endpoints/service-identity.js b/src/service/endpoints/service-identity.js index d5fc3a2..a9063c3 100644 --- a/src/service/endpoints/service-identity.js +++ b/src/service/endpoints/service-identity.js @@ -38,7 +38,7 @@ module.exports = class ServiceIdentity extends IEndpoint { } } - static async run(ctx, static_ctx){ + static async run(ctx, {Package}){ const identity = ctx.party.identity diff --git a/src/service/endpoints/service-version.js b/src/service/endpoints/service-version.js index f5220cc..f42a25b 100644 --- a/src/service/endpoints/service-version.js +++ b/src/service/endpoints/service-version.js @@ -33,7 +33,7 @@ module.exports = class ServiceVersion extends IEndpoint { } } - static async run(ctx, static_ctx){ + static async run(ctx, {Package}){ return { ...Package diff --git a/src/service/iendpoint.js b/src/service/iendpoint.js index 85be433..e50ef37 100644 --- a/src/service/iendpoint.js +++ b/src/service/iendpoint.js @@ -19,7 +19,15 @@ module.exports = class IEndpoint { } - static async run(context){ + static async run(context, {Package}){ throw new Error('not implemented') } + + static get info(){ + return { + Name: this.Name, + Description: this.Description, + MiddlewareConfig: this.MiddlewareConfig + } + } } \ No newline at end of file diff --git a/src/service/imiddleware.js b/src/service/imiddleware.js index 1a42fcd..d6bc9d9 100644 --- a/src/service/imiddleware.js +++ b/src/service/imiddleware.js @@ -23,7 +23,16 @@ module.exports = class IMiddleware { } - static async run(context){ + static async run(context, {Config}){ throw new Error('not implemented') } + + static get info(){ + return { + Name: this.Name, + Type: this.Type, + Description: this.Description, + ConfigSchema: this.ConfigSchema + } + } } \ No newline at end of file diff --git a/src/service/index.js b/src/service/index.js index 6d920e4..ef27ce7 100644 --- a/src/service/index.js +++ b/src/service/index.js @@ -7,6 +7,7 @@ module.exports = { IMiddleware: require('./imiddleware'), ServiceHost: require('./service-host'), ServiceRunner: require('./service-runner'), + ServiceRunnerNode: require('./service-runner-node'), EndpointRunner: require('./endpoint-runner'), EndpointContext: require('./endpoint-context'), MiddlewareRunner: require('./middleware-runner'), diff --git a/src/service/middleware/post/encrypt.js b/src/service/middleware/post/encrypt.js index b448674..1de93aa 100644 --- a/src/service/middleware/post/encrypt.js +++ b/src/service/middleware/post/encrypt.js @@ -27,7 +27,7 @@ module.exports = class Encrypt extends IMiddleware { } - static async run(ctx){ + static async run(ctx, {Config}){ if (!Config){ return } diff --git a/src/service/middleware/post/validate.js b/src/service/middleware/post/validate.js index c146bd5..76bea74 100644 --- a/src/service/middleware/post/validate.js +++ b/src/service/middleware/post/validate.js @@ -28,7 +28,7 @@ module.exports = class Validate extends IMiddleware { } - static async run(context){ + static async run(context, {Config}){ if (!Config){ return } diff --git a/src/service/middleware/pre/decrypt.js b/src/service/middleware/pre/decrypt.js index 5d630a5..81d2188 100644 --- a/src/service/middleware/pre/decrypt.js +++ b/src/service/middleware/pre/decrypt.js @@ -27,7 +27,7 @@ module.exports = class Decrypt extends IMiddleware { } - static async run(context){ + static async run(context, {Config}){ if (!Config){ return } diff --git a/src/service/middleware/pre/validate.js b/src/service/middleware/pre/validate.js index 5714ce5..0c602d4 100644 --- a/src/service/middleware/pre/validate.js +++ b/src/service/middleware/pre/validate.js @@ -28,7 +28,7 @@ module.exports = class Validate extends IMiddleware { } - static async run(context){ + static async run(context, {Config}){ if (!Config){ return } diff --git a/src/service/service-host-websocket.js b/src/service/service-host-websocket.js index cb92e00..4bc5955 100644 --- a/src/service/service-host-websocket.js +++ b/src/service/service-host-websocket.js @@ -1,5 +1,5 @@ const {URL} = require('url') -const debug = require('debug')('dataparty.service-host-websocket') +const debug = require('debug')('dataparty.service.host-websocket') const ws = require('ws') const WebSocketServer = ws.WebSocketServer @@ -62,13 +62,24 @@ class ServiceHostWebsocket{ } getConnectionIp(req){ + let ip = null if(this.trust_proxy){ - const ip = req.headers['x-forwarded-for'].split(',')[0].trim(); - return ip + if(!req.headers['x-forwarded-for']){ + debug('getConnectionIp - WARN - connection without x-forwarded-for', req.socket.remoteAddress) + } + else{ + debug('getConnectionIp - xfwd', req.headers['x-forwarded-for']) + ip = req.headers['x-forwarded-for'].split(',')[0].trim(); + } + } + + if(!ip){ + return req.socket.remoteAddress } - return req.socket.remoteAddress + return ip + } handleConnection(conn, req){ @@ -80,13 +91,17 @@ class ServiceHostWebsocket{ conn.on('pong', ()=>{ conn.isAlive = true }) + + conn.on('close',()=>{ + debug('connection closed', conn.ip) + }) } checkClients(){ - debug('checkClients') + debug('checkClients', this.ws.clients.size) this.ws.clients.forEach( (conn)=>{ if (conn.isAlive === false){ - debug('\t','terminating client') + debug('\t','terminating client', conn.ip) return conn.terminate() } diff --git a/src/service/service-host.js b/src/service/service-host.js index 3b6b115..f1e52e8 100644 --- a/src/service/service-host.js +++ b/src/service/service-host.js @@ -7,7 +7,7 @@ const morgan = require('morgan') const express = require('express') const bodyParser = require('body-parser') const expressListRoutes = require('express-list-routes') -const debug = require('debug')('dataparty.service-host') +const debug = require('debug')('dataparty.service.host') const ServiceHostWebsocket = require('./service-host-websocket') diff --git a/src/service/service-runner-node.js b/src/service/service-runner-node.js new file mode 100644 index 0000000..6881acc --- /dev/null +++ b/src/service/service-runner-node.js @@ -0,0 +1,241 @@ +const Path = require('path') +const Joi = require('@hapi/joi') +const Hoek = require('@hapi/hoek') +const {VM, VMScript} = require('vm2') +const Debug = require('debug') +const debug = Debug('dataparty.service.runner-node') +const EndpointContext = require('./endpoint-context') +const DeltaTime = require('../utils/delta-time') + +const Router = require('origin-router').Router + +class ServiceRunnerNode { + constructor({service, party, sendFullErrors=false}){ + this.party = party + this.service = service + this.sendFullErrors = sendFullErrors + + this.middleware = { pre: {}, post: {} } + this.endpoint = {} + + this.router = new Router() + } + + async start(){ + debug('starting endpoints') + + const eps = Hoek.reach(this.service, 'compiled.endpoints') + //const endpointsLoading = [] + for(let name in eps){ + debug('\t',name) + await this.loadEndpoint(name) + //endpointsLoading.push( this.loadEndpoint(name) ) + } + + //await Promise.all(endpointsLoading) + debug('endpoints ready:') + for(let name in this.endpoint){ + debug('\t', Path.join('/', name)) + } + } + + async loadEndpoint(name){ + if(this.endpoint[name]){ + return + } + + debug('loadEndpoint', name) + + let dt = new DeltaTime().start() + const build = Hoek.reach(this.service, `compiled.endpoints.${name}`) + + "use strict" + let endpoint = eval(build.code/*, build.map*/) + + debug('endpoint info', endpoint.info) + + await this.checkEndpointConfig(endpoint) + + await this.loadEndpointMiddleware(endpoint, 'pre') + await this.loadEndpointMiddleware(endpoint, 'post') + + await endpoint.start(this.party) + + this.endpoint[name] = endpoint + + this.router.add(name, this.endpointHandler(endpoint)) + dt.end() + debug('loaded endpoint',name,'in',dt.deltaMs,'ms') + } + + + async loadEndpointMiddleware(endpoint, type='pre'){ + const middlewareList = Hoek.reach(endpoint, `info.MiddlewareConfig.${type}`) + for(let name in middlewareList){ + const middleware = await this.loadMiddleware(name, type, endpoint) + + const middlewareCfg = Hoek.reach(endpoint, `info.MiddlewareConfig.${type}.${name}`) + await this.checkMiddlewareConfig(middleware, middlewareCfg) + } + + + } + + async loadMiddleware(name, type='pre'){ + if(this.middleware[type][name]){ + debug('cached',type,'middleware',name) + return this.middleware[type][name] + } + + debug('loadMiddleware', type, name) + + let dt = new DeltaTime().start() + const build = Hoek.reach(this.service, `compiled.middleware.${type}.${name}`) + + if(!build || !build.code){ + debug(`middleware ${type} [${name}] does not exist`) + throw new Error(`middleware ${type} [${name}] does not exist`) + } + + let ret = async ()=>{ + "use strict" + let middle = eval(build.code/*, build.map/*/) + + debug('middleware info', middle.info) + + //await runner.getInfo() + //await runner.start(this.party) + await middle.start(this.party) + + this.middleware[type][name] = middle + + dt.end() + debug('loaded',type,'middleware',name,'in',dt.deltaMs,'ms') + + return middle + } + + return await ret() + + + } + + async checkEndpointConfig(endpoint){ + //! check basic structure {pre: Object, post: Object} + + return await Joi.object().keys({ + pre: Joi.object().keys(null), + post: Joi.object().keys(null) + }) + .validateAsync(endpoint.info.MiddlewareConfig) + } + + async checkMiddlewareConfig(middleware, middlewareCfg){ + //! check endpoint configures middleware correctly + + return await middleware.info.ConfigSchema.validateAsync(middlewareCfg) + } + + async onRequest(req, res){ + debug('onRequest') + + debug('req', req.method, req.url, req.body) + + + + let route = await this.router.route(req, res) + + debug('req done') + + + if(!route){ + res.status(404).end() + return + } + } + + + endpointHandler(endpoint){ + return async (event)=>{ + + debug('event',event.method, event.pathname, event.request.ip, event.request.ips) + + + const context = new EndpointContext({ + req: event.request, res: event.response, + endpoint, + party: this.party, + input: event.request.body, + debug: Debug, + sendFullErrors: this.sendFullErrors + }) + + debug('running', endpoint.info.Name) + + const middlewareCfg = Hoek.reach(endpoint, 'info.MiddlewareConfig') + + try{ + + await this.runMiddleware(middlewareCfg, context, 'pre') + + const result = await endpoint.run(context, {Package: this.service.compiled.package}) + + context.setOutput(result) + + await this.runMiddleware(middlewareCfg, context, 'post') + + context.dt.end() + + /*debug('ctx.log', context._debugContent)*/ + debug('ran endpoint', endpoint.info.Name, 'in', context.dt.deltaMs, 'ms') + debug('result', context.output) + + context.res.send(context.output) + + } + catch(err){ + debug('caught error', err) + + context.dt.end() + + debug('crashed (',endpoint.info.Name,') in', context.dt.deltaMs, 'ms') + + context.res.status(500).send({ + error: { + code: err.code, + message: err.message, + stack: (!context.sendFullErrors ? undefined : err.stack), + ... (!context.sendFullErrors ? null : err) + } + }) + } + + } + } + + async runMiddleware(middlewareCfg, ctx, type='pre'){ + debug(`run ${type} middleware`) + + const cfg = Hoek.reach(middlewareCfg, type) + const order = Hoek.reach(this.service, 'compiled.middleware_order.'+type) + + debug('\tmiddleware order', order) + + for(let name of order){ + const info = Hoek.reach(cfg, name) + + if(!info){ continue } + + debug('\t\trunning', name) + const middleware = Hoek.reach(this.middleware, `${type}.${name}`) + + const dt = new DeltaTime().start() + await middleware.run(ctx, {Config:info}) + dt.end() + + debug('runMiddleware(',type,name,') in', dt.deltaMs, 'ms') + } + } +} + +module.exports = ServiceRunnerNode \ No newline at end of file diff --git a/src/service/service-runner.js b/src/service/service-runner.js index af5a962..863db35 100644 --- a/src/service/service-runner.js +++ b/src/service/service-runner.js @@ -3,7 +3,7 @@ const Joi = require('@hapi/joi') const Hoek = require('@hapi/hoek') const {VM, VMScript} = require('vm2') const Debug = require('debug') -const debug = Debug('dataparty.service-runner') +const debug = Debug('dataparty.service.runner') const MiddlewareRunner = require('./middleware-runner') const EndpointContext = require('./endpoint-context') const EndpointRunner = require('./endpoint-runner') diff --git a/src/utils/joi-objectid.js b/src/utils/joi-objectid.js new file mode 100644 index 0000000..6906877 --- /dev/null +++ b/src/utils/joi-objectid.js @@ -0,0 +1,19 @@ +'use strict'; + +var assert = require('assert'); + +module.exports = function joiObjectId(Joi, message) { + assert(Joi && Joi.object, 'you must pass Joi as an argument'); + if (!message || !(typeof message === 'string')) { + message = 'valid mongo id'; + } + return function objectId() { + return Joi.alternatives( + Joi.string().regex(/^[0-9a-fA-F]{24}$/, message), + Joi.object().keys({ + id: Joi.any(), + _bsontype: Joi.allow('ObjectId') + }) + ); + }; +} \ No newline at end of file From af878b6f2edf1bede87cbc56436a556fda8a376b Mon Sep 17 00:00:00 2001 From: Alan Meekins Date: Wed, 14 Dec 2022 04:38:42 -0800 Subject: [PATCH 03/13] npm run build-test working --- examples/party/schema/user.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/examples/party/schema/user.js b/examples/party/schema/user.js index e32729c..e55d89c 100644 --- a/examples/party/schema/user.js +++ b/examples/party/schema/user.js @@ -14,7 +14,7 @@ class User extends ISchema { photo: { type: String, maxlength: 500, description: 'user photo url' }, created: Utils.created, enabled: Boolean, - profile: Utils.profile, + profile: Object, tutorial: { done: Boolean } From eb03531549dae3233146a411a01de494682b8503 Mon Sep 17 00:00:00 2001 From: Alan Meekins Date: Sat, 17 Dec 2022 10:54:54 +0000 Subject: [PATCH 04/13] support websockets as a peer-comms --- examples/test-peer-party.js | 8 ++- examples/test-service-host.js | 11 ++-- examples/test-service-node-host.js | 15 +++-- src/comms/peer-comms.js | 10 ++-- src/comms/rest-comms.js | 2 +- src/comms/rtc-socket-comms.js | 5 +- src/comms/socket-comms.js | 15 ++++- src/comms/websocket-comms.js | 85 +++++++++++++++++++++++---- src/service/middleware/pre/decrypt.js | 8 ++- src/service/service-host-websocket.js | 27 +++++++-- src/service/service-runner-node.js | 57 ++++++++++++++---- 11 files changed, 191 insertions(+), 52 deletions(-) diff --git a/examples/test-peer-party.js b/examples/test-peer-party.js index ab668db..5ea3ecc 100644 --- a/examples/test-peer-party.js +++ b/examples/test-peer-party.js @@ -18,7 +18,8 @@ async function main(){ comms: new Dataparty.Comms.RTCSocketComms({ host: true, wrtc: WRTC, - trickle: true + trickle: true, + discoverRemoteIdentity: true }), hostParty: hostLocal, model: BouncerModel, @@ -29,7 +30,8 @@ async function main(){ let peer2 = new Dataparty.PeerParty({ comms: new Dataparty.Comms.RTCSocketComms({ wrtc: WRTC, - trickle: true + trickle: true, + session: 'foobar' }), model: BouncerModel, config: new Dataparty.Config.MemoryConfig() @@ -40,7 +42,7 @@ async function main(){ await peer1.loadIdentity() await peer2.loadIdentity() - peer1.comms.remoteIdentity = peer2.identity + //peer1.comms.remoteIdentity = peer2.identity peer2.comms.remoteIdentity = peer1.identity await peer1.start() diff --git a/examples/test-service-host.js b/examples/test-service-host.js index dd2c181..fdf52d3 100644 --- a/examples/test-service-host.js +++ b/examples/test-service-host.js @@ -25,16 +25,19 @@ class ExampleService extends Dataparty.IService { async function main(){ - const uri = 'mongodb://localhost:27017/server-party-test' - debug('db location', uri) + //const uri = 'mongodb://localhost:27017/server-party-test' + //debug('db location', uri) - let party = new Dataparty.MongoParty({ - uri, + const path = '/data/datparty/srv-party' + + let party = new Dataparty.TingoParty({ + path, model: BouncerClientModels, serverModels: BouncerServerModels, config: new Dataparty.Config.MemoryConfig() }) + const service = new ExampleService({ name: '@dataparty/example', version: '0.0.1' }) const build = await service.compile(Path.join(__dirname,'/dataparty'), true) diff --git a/examples/test-service-node-host.js b/examples/test-service-node-host.js index f0886df..7e39524 100644 --- a/examples/test-service-node-host.js +++ b/examples/test-service-node-host.js @@ -25,11 +25,14 @@ class ExampleService extends Dataparty.IService { async function main(){ - const uri = 'mongodb://localhost:27017/server-party-test' - debug('db location', uri) + + //const uri = 'mongodb://localhost:27017/server-party-test' + //debug('db location', uri) + + const path = '/data/datparty/srv-party' - let party = new Dataparty.MongoParty({ - uri, + let party = new Dataparty.TingoParty({ + path, model: BouncerClientModels, serverModels: BouncerServerModels, config: new Dataparty.Config.MemoryConfig() @@ -43,7 +46,7 @@ async function main(){ const runner = new Dataparty.ServiceRunnerNode({ party, service, - sendFullErrors: true + sendFullErrors: false }) const host = new Dataparty.ServiceHost({ @@ -65,4 +68,4 @@ async function main(){ main().catch(err=>{ console.error(err) -}) \ No newline at end of file +}) diff --git a/src/comms/peer-comms.js b/src/comms/peer-comms.js index aa4d35c..6946d0c 100644 --- a/src/comms/peer-comms.js +++ b/src/comms/peer-comms.js @@ -7,12 +7,12 @@ const SocketComms = require('./socket-comms') const AUTH_TIMEOUT_MS = 3000 class PeerComms extends SocketComms { - constructor({remoteIdentity, host, party, socket}){ - super({remoteIdentity, party}) + constructor({remoteIdentity, discoverRemoteIdentity, host, party, socket, ...options}){ + super({remoteIdentity, discoverRemoteIdentity, party, ...options}) this.socket = socket || null - this.host = host + this.host = host //! Is comms host this.party = party this.oncall = null @@ -114,10 +114,12 @@ class PeerComms extends SocketComms { this.socket.on('close', this.onclose.bind(this)) if(this.host){ + debug('host mode comms') this.socket.on('connect', this.handleClientConnection.bind(this)) this.socket.on('data', this.handleClientCall.bind(this)) } else{ + debug('client mode comms') this.socket.on('connect', this.onopen.bind(this)) this.socket.on('data', this.handleMessage.bind(this)) } @@ -132,7 +134,7 @@ class PeerComms extends SocketComms { } close(){ - debug('Client closing connection') + debug('closing connection') this.socket.destroy() } diff --git a/src/comms/rest-comms.js b/src/comms/rest-comms.js index b5f2976..0adc6fe 100644 --- a/src/comms/rest-comms.js +++ b/src/comms/rest-comms.js @@ -4,7 +4,7 @@ const debug = require('debug')('dataparty.comms.rest') const dataparty_crypto = require('@dataparty/crypto') -const WebsocketComms = require('./websocket-comms') +const WebsocketComms = require('./old-websocket-comms') const AuthError = require('../errors/auth-error') diff --git a/src/comms/rtc-socket-comms.js b/src/comms/rtc-socket-comms.js index a25aeb8..6b4a69e 100644 --- a/src/comms/rtc-socket-comms.js +++ b/src/comms/rtc-socket-comms.js @@ -3,11 +3,10 @@ const debug = require('debug')('dataparty.comms.rtcsocketcomms') const SimplePeer = require('simple-peer') const PeerComms = require('./peer-comms') -const AUTH_TIMEOUT_MS = 3000 class RTCSocketComms extends PeerComms { - constructor({remoteIdentity, host, party, wrtc, trickle = false}){ - super({remoteIdentity, host, party}) + constructor({remoteIdentity, host, party, wrtc, trickle = false, ...options}){ + super({remoteIdentity, host, party, ...options}) this.rtcSettings = { wrtc, diff --git a/src/comms/socket-comms.js b/src/comms/socket-comms.js index 53f7cac..aeea889 100644 --- a/src/comms/socket-comms.js +++ b/src/comms/socket-comms.js @@ -10,11 +10,12 @@ const RosShim = require('./ros-shim') class SocketComms extends EventEmitter { - constructor({session, uri, party, remoteIdentity}){ + constructor({session, uri, party, remoteIdentity, discoverRemoteIdentity}){ super() this.uri = uri this.session = session this.remoteIdentity = remoteIdentity + this.discoverRemoteIdentity = discoverRemoteIdentity this.party = party //used for access to primary identity @@ -84,10 +85,20 @@ class SocketComms extends EventEmitter { return resolve(msg.decrypt(this.party._identity).then(content=>{ const senderPub = Routines.extractPublicKeys(msg.enc) + debug('sender', sender, '\tdiscover', this.discoverRemoteIdentity) + if(this.discoverRemoteIdentity && !sender){ + debug('discovered remote identity', senderPub) + this.remoteIdentity = { + key: { + public: senderPub + } + } + sender = this.remoteIdentity + } debug(`senderPub - ${senderPub}`) if(senderPub.box != sender.key.public.box || senderPub.sign != sender.key.public.sign){ - return Promise.reject('TRUST - reply is not from service') + return Promise.reject('TRUST - reply is not from expected remote') } debug('decrypted data') diff --git a/src/comms/websocket-comms.js b/src/comms/websocket-comms.js index 153a2bb..b8c05e1 100644 --- a/src/comms/websocket-comms.js +++ b/src/comms/websocket-comms.js @@ -1,20 +1,81 @@ -'use strict' +const debug = require('debug')('dataparty.comms.websocket') -const debug = require('debug')('dataparty.comms.websocketcomms') -const W3CWebSocket = require('websocket').w3cwebsocket; -const WebSocket = W3CWebSocket +const WebSocket = require('ws') +const EventEmitter = require('eventemitter3') -const SocketComms = require('./socket-comms') -class WebsocketComms extends SocketComms { - constructor({session, uri, identity, remoteIdentity}){ - super({session, uri, identity, remoteIdentity}) +const PeerComms = require('./peer-comms') - this.socket = new WebSocket(this.uri) - this.socket.onclose = this.onclose.bind(this) - this.socket.onopen = this.onopen.bind(this) - this.socket.onmessage = this.onmessage.bind(this) + +class WebsocketShim extends EventEmitter { + constructor(conn){ + super() + this.conn = conn + + this.conn.onmessage = (evt) => { + this.emit('data', evt.data) + } + + this.conn.onopen = () => { + debug('shim open') + this.emit('connect') + } + + this.conn.onclose = () => { + this.emit('close') + } + + this.conn.onerror = (err) => { + this.emit('error', err) + } + + if(this.conn.readyState == WebSocket.OPEN){ + setTimeout(()=>{this.emit('connect')}, 1) + } + + debug('connection shim', this.conn.readyState) + } + + close(){ + this.conn.close() + } + + destroy(){ + this.conn.terminate() + } + + send(val){ this.conn.send(val) } + +} + +class WebsocketComms extends PeerComms { + constructor({uri, connection, remoteIdentity, host, party, ...options}){ + super({remoteIdentity, host, party, ...options}) + + this.uri = uri + this.connection = connection + + if(this.host && !this.connection){ + throw new Error('existing connection expected') + } + + if(!this.host && (!this.uri && !this.connection)){ + throw new Error('uri or existing connection expected') + } + } + + + async socketInit(){ + debug('init') + + if(!this.host && !this.connection){ + debug('opening client connection to',this.uri) + this.connection = new WebSocket(this.uri) } + + this.socket = new WebsocketShim(this.connection) + } } + module.exports = WebsocketComms \ No newline at end of file diff --git a/src/service/middleware/pre/decrypt.js b/src/service/middleware/pre/decrypt.js index 81d2188..fef4a75 100644 --- a/src/service/middleware/pre/decrypt.js +++ b/src/service/middleware/pre/decrypt.js @@ -31,11 +31,15 @@ module.exports = class Decrypt extends IMiddleware { if (!Config){ return } - context.debug('input', context.input) + if(!context.input || !context.input.enc){ + throw new Error('insecure message') + } + + context.debug('input', context.input, typeof context.input) const msg = new Message(context.input) - context.debug('privateIdentity', context.party.privateIdentity) + context.debug('privateIdentity', context.party.privateIdentity.id) const publicKeys = Routines.extractPublicKeys(msg.enc) diff --git a/src/service/service-host-websocket.js b/src/service/service-host-websocket.js index 4bc5955..abd94b3 100644 --- a/src/service/service-host-websocket.js +++ b/src/service/service-host-websocket.js @@ -6,6 +6,9 @@ const WebSocketServer = ws.WebSocketServer const WATCHDOG_INTERVAL = 30000 +const Comms = require('../comms') +const PeerParty = require('../party/peer/peer-party') + class ServiceHostWebsocket{ constructor({trust_proxy, port, path, runner, wsSettings}){ @@ -44,7 +47,7 @@ class ServiceHostWebsocket{ handleUpgrade(request, socket, head){ - debug('handleUpgrade', request.url) + debug('handleUpgrade', request.headers.host, request.url) if(request.url == this.path){ this.doUpgrade(request, socket, head) @@ -56,7 +59,6 @@ class ServiceHostWebsocket{ doUpgrade(request, socket, head){ debug('doUpgrade') this.ws.handleUpgrade(request, socket, head, (conn)=>{ - debug('head', head) this.ws.emit('connection', conn, request) }) } @@ -82,10 +84,10 @@ class ServiceHostWebsocket{ } - handleConnection(conn, req){ + async handleConnection(conn, req){ conn.ip = this.getConnectionIp(req) - debug('handleConnection - ', conn.ip) + debug('handleConnection - ', conn.ip, '\t>\t' , req.headers.host, req.url) conn.isAlive = true conn.on('pong', ()=>{ @@ -95,6 +97,23 @@ class ServiceHostWebsocket{ conn.on('close',()=>{ debug('connection closed', conn.ip) }) + + debug('creating peer party') + + let peer = new PeerParty({ + hostParty: this.runner.party, + mode: this.runner.party.model, + config: this.runner.party.config, + comms: new Comms.WebsocketComms({ + host: true, + connection: conn, + discoverRemoteIdentity: true + }) + }) + + await peer.start() + debug('peer created') + } checkClients(){ diff --git a/src/service/service-runner-node.js b/src/service/service-runner-node.js index 6881acc..144033a 100644 --- a/src/service/service-runner-node.js +++ b/src/service/service-runner-node.js @@ -10,10 +10,11 @@ const DeltaTime = require('../utils/delta-time') const Router = require('origin-router').Router class ServiceRunnerNode { - constructor({service, party, sendFullErrors=false}){ + constructor({service, party, sendFullErrors=false, useNative=true}){ this.party = party this.service = service this.sendFullErrors = sendFullErrors + this.useNative = useNative this.middleware = { pre: {}, post: {} } this.endpoint = {} @@ -47,10 +48,19 @@ class ServiceRunnerNode { debug('loadEndpoint', name) let dt = new DeltaTime().start() - const build = Hoek.reach(this.service, `compiled.endpoints.${name}`) + "use strict" - let endpoint = eval(build.code/*, build.map*/) + let endpoint=null + + if(!this.useNative){ + const build = Hoek.reach(this.service, `compiled.endpoints.${name}`) + endpoint = eval(build.code/*, build.map*/) + } + else{ + endpoint = this.service.constructors.endpoints[name] + } + debug('endpoint info', endpoint.info) @@ -83,7 +93,7 @@ class ServiceRunnerNode { async loadMiddleware(name, type='pre'){ if(this.middleware[type][name]){ - debug('cached',type,'middleware',name) + //debug('cached',type,'middleware',name) return this.middleware[type][name] } @@ -92,16 +102,29 @@ class ServiceRunnerNode { let dt = new DeltaTime().start() const build = Hoek.reach(this.service, `compiled.middleware.${type}.${name}`) - if(!build || !build.code){ - debug(`middleware ${type} [${name}] does not exist`) - throw new Error(`middleware ${type} [${name}] does not exist`) + if(this.useNative && !this.service.constructors.middleware[type][name]){ + debug(`native middleware ${type} [${name}] does not exist`) + throw new Error(`native middleware ${type} [${name}] does not exist`) + } + + if(!this.useNative && (!build || !build.code) ){ + debug(`compiled middleware ${type} [${name}] does not exist`) + throw new Error(`compiled middleware ${type} [${name}] does not exist`) } let ret = async ()=>{ + "use strict" - let middle = eval(build.code/*, build.map/*/) + let middle=null + + if(!this.useNative){ + middle = eval(build.code/*, build.map*/) + } + else{ + middle = this.service.constructors.middleware[type][name] + } - debug('middleware info', middle.info) + //debug('middleware info', middle.info) //await runner.getInfo() //await runner.start(this.party) @@ -139,7 +162,7 @@ class ServiceRunnerNode { async onRequest(req, res){ debug('onRequest') - debug('req', req.method, req.url, req.body) + debug('req', req.method, req.hostname, req.url, req.ips, req.body) @@ -173,16 +196,21 @@ class ServiceRunnerNode { debug('running', endpoint.info.Name) const middlewareCfg = Hoek.reach(endpoint, 'info.MiddlewareConfig') + let phase = 'pre-middleware' try{ await this.runMiddleware(middlewareCfg, context, 'pre') + phase = 'endpoint' const result = await endpoint.run(context, {Package: this.service.compiled.package}) + phase = 'output' context.setOutput(result) + phase = 'post-middleware' await this.runMiddleware(middlewareCfg, context, 'post') + phase = 'send' context.dt.end() @@ -194,7 +222,13 @@ class ServiceRunnerNode { } catch(err){ - debug('caught error', err) + + if(this.sendFullErrors){ + debug('caught error', err) + } + else{ + debug('caught error (', err.message, ')') + } context.dt.end() @@ -204,6 +238,7 @@ class ServiceRunnerNode { error: { code: err.code, message: err.message, + phase, stack: (!context.sendFullErrors ? undefined : err.stack), ... (!context.sendFullErrors ? null : err) } From 26b7c28bdc72c005dfdaeb94d2ee69307d8d9a92 Mon Sep 17 00:00:00 2001 From: Alan Meekins Date: Sun, 18 Dec 2022 22:41:12 +0000 Subject: [PATCH 05/13] store example node host identity between runs --- examples/test-service-node-host.js | 2 +- src/service/service-host-websocket.js | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/examples/test-service-node-host.js b/examples/test-service-node-host.js index 7e39524..222a18e 100644 --- a/examples/test-service-node-host.js +++ b/examples/test-service-node-host.js @@ -35,7 +35,7 @@ async function main(){ path, model: BouncerClientModels, serverModels: BouncerServerModels, - config: new Dataparty.Config.MemoryConfig() + config: new Dataparty.Config.JsonFileConfig({basePath: '/data/datparty/'}) }) const service = new ExampleService({ name: '@dataparty/example', version: '0.0.1' }) diff --git a/src/service/service-host-websocket.js b/src/service/service-host-websocket.js index abd94b3..be57c95 100644 --- a/src/service/service-host-websocket.js +++ b/src/service/service-host-websocket.js @@ -102,7 +102,7 @@ class ServiceHostWebsocket{ let peer = new PeerParty({ hostParty: this.runner.party, - mode: this.runner.party.model, + model: this.runner.party.factory.model, config: this.runner.party.config, comms: new Comms.WebsocketComms({ host: true, From 7967fb66223b245b85066dd52012ffb31fe1160b Mon Sep 17 00:00:00 2001 From: Alan Meekins Date: Sun, 18 Dec 2022 22:48:00 +0000 Subject: [PATCH 06/13] tweak browser build --- package.json | 5 ++--- src/index-browser.js | 3 ++- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/package.json b/package.json index 79c56be..d179091 100644 --- a/package.json +++ b/package.json @@ -1,7 +1,7 @@ { "name": "@dataparty/api", "private": false, - "version": "1.2.14", + "version": "1.2.15", "main": "dist/dataparty.js", "frontend": "dist/dataparty-browser.js", "backend": "dist/dataparty.js", @@ -17,8 +17,7 @@ "context": "browser", "source": "src/index-browser.js", "optimize": false, - "includeNodeModules": true, - "scopeHoist": false, + "outputFormat": "global", "engines": { "browsers": "Chrome 80" } diff --git a/src/index-browser.js b/src/index-browser.js index e493d28..44380b3 100644 --- a/src/index-browser.js +++ b/src/index-browser.js @@ -17,4 +17,5 @@ let lib = { } -module.exports = lib \ No newline at end of file +module.exports = lib +window.Dataparty = lib \ No newline at end of file From d12c21cb180de77800984530b4322c13f33119ac Mon Sep 17 00:00:00 2001 From: Alan Meekins Date: Sun, 18 Dec 2022 22:50:41 +0000 Subject: [PATCH 07/13] disable rest.websocket --- src/comms/rest-comms.js | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/comms/rest-comms.js b/src/comms/rest-comms.js index 0adc6fe..a39cfe4 100644 --- a/src/comms/rest-comms.js +++ b/src/comms/rest-comms.js @@ -4,7 +4,7 @@ const debug = require('debug')('dataparty.comms.rest') const dataparty_crypto = require('@dataparty/crypto') -const WebsocketComms = require('./old-websocket-comms') +//const WebsocketComms = require('./old-websocket-comms') const AuthError = require('../errors/auth-error') @@ -325,6 +325,7 @@ class RestComms extends EventEmitter { } } + /* async websocket(reuse = true) { if (reuse && this.websocketComm && this.websocketComm.connected) { return this.websocketComm @@ -349,7 +350,7 @@ class RestComms extends EventEmitter { return comm.authorized() }) - } + }*/ static async HttpRequest(verb, url, data) { From 636b0afd8c75d3672f5d08739c73aaa3d92f56a7 Mon Sep 17 00:00:00 2001 From: Alan Meekins Date: Sun, 18 Dec 2022 23:15:45 +0000 Subject: [PATCH 08/13] loki local storage adapter --- src/bouncer/db/loki-db.js | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/bouncer/db/loki-db.js b/src/bouncer/db/loki-db.js index 5a08491..ed27a9d 100644 --- a/src/bouncer/db/loki-db.js +++ b/src/bouncer/db/loki-db.js @@ -24,6 +24,10 @@ module.exports = class LokiDb extends IDb { this.error = null } + static get LokiLocalStorageAdapter(){ + return Loki.LokiLocalStorageAdapter + } + async start(){ From 09502dd97874c31689d16938d1367cc4bea62c39 Mon Sep 17 00:00:00 2001 From: Alan Meekins Date: Sun, 18 Dec 2022 23:36:49 +0000 Subject: [PATCH 09/13] str to obj --- src/comms/rest-comms.js | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/comms/rest-comms.js b/src/comms/rest-comms.js index a39cfe4..de69fbf 100644 --- a/src/comms/rest-comms.js +++ b/src/comms/rest-comms.js @@ -132,8 +132,8 @@ class RestComms extends EventEmitter { let reply try { - const str = await RestComms.HttpPost(fullPath, content) - reply = JSON.parse(str) + reply = await RestComms.HttpPost(fullPath, content) + //reply = JSON.parse(str) // debug('raw reply ->', reply) } catch (error) { @@ -203,7 +203,7 @@ class RestComms extends EventEmitter { const serverIdentity = await RestComms.HttpGet(this.uri + `${this.uriPrefix}identity`) debug('server identity - ', serverIdentity) - this.remoteIdentity = dataparty_crypto.Identity.fromString(serverIdentity) + this.remoteIdentity = new dataparty_crypto.Identity(serverIdentity) } return this.remoteIdentity From 5bf72f3be93ce939f588db0699aec4ea31c6bdcd Mon Sep 17 00:00:00 2001 From: Alan Meekins Date: Tue, 20 Dec 2022 08:08:54 +0000 Subject: [PATCH 10/13] multi-part support --- package.json | 1 + src/service/service-host.js | 2 ++ 2 files changed, 3 insertions(+) diff --git a/package.json b/package.json index d179091..4c3657d 100644 --- a/package.json +++ b/package.json @@ -83,6 +83,7 @@ "mkdirp": "^0.5.1", "moment": "^2.29.4", "morgan": "^1.10.0", + "multer": "^1.4.5-lts.1", "nconf": "^0.10.0", "node-persist": "^3.0.1", "origin-router": "^1.6.4", diff --git a/src/service/service-host.js b/src/service/service-host.js index f1e52e8..8d02be5 100644 --- a/src/service/service-host.js +++ b/src/service/service-host.js @@ -5,6 +5,7 @@ const http = require('http') const https = require('https') const morgan = require('morgan') const express = require('express') +const multer = require('multer') const bodyParser = require('body-parser') const expressListRoutes = require('express-list-routes') const debug = require('debug')('dataparty.service.host') @@ -42,6 +43,7 @@ class ServiceHost { this.apiApp.use(bodyParser.urlencoded({ extended: true })) this.apiApp.use(bodyParser.json()) + this.apiApp.use(multer()) this.apiApp.set('trust proxy', trust_proxy) From 58f7a330b4532398b64530ac7b5b7801b1a80415 Mon Sep 17 00:00:00 2001 From: Alan Meekins Date: Tue, 20 Dec 2022 08:30:51 +0000 Subject: [PATCH 11/13] reject file uploads by default --- src/service/service-host.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/service/service-host.js b/src/service/service-host.js index 8d02be5..f9458e9 100644 --- a/src/service/service-host.js +++ b/src/service/service-host.js @@ -43,7 +43,7 @@ class ServiceHost { this.apiApp.use(bodyParser.urlencoded({ extended: true })) this.apiApp.use(bodyParser.json()) - this.apiApp.use(multer()) + this.apiApp.use(multer().none()) this.apiApp.set('trust proxy', trust_proxy) From f7850c57a82dc9e0c8ee9e7e39398a212cbe0bfb Mon Sep 17 00:00:00 2001 From: Alan Meekins Date: Tue, 20 Dec 2022 08:40:46 +0000 Subject: [PATCH 12/13] raw and multipart array --- src/service/service-host.js | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/service/service-host.js b/src/service/service-host.js index f9458e9..2d43dfc 100644 --- a/src/service/service-host.js +++ b/src/service/service-host.js @@ -41,9 +41,10 @@ class ServiceHost { if(debug.enabled){ this.apiApp.use(morgan('combined')) } + this.apiApp.use(multer().array()) this.apiApp.use(bodyParser.urlencoded({ extended: true })) this.apiApp.use(bodyParser.json()) - this.apiApp.use(multer().none()) + this.apiApp.use(bodyParser.raw()) this.apiApp.set('trust proxy', trust_proxy) From 918affbf62be0edee88486ef48ac714b0b4e0c56 Mon Sep 17 00:00:00 2001 From: Alan Meekins Date: Tue, 20 Dec 2022 09:09:35 +0000 Subject: [PATCH 13/13] no multer --- src/service/service-host.js | 2 -- 1 file changed, 2 deletions(-) diff --git a/src/service/service-host.js b/src/service/service-host.js index 2d43dfc..46c5b61 100644 --- a/src/service/service-host.js +++ b/src/service/service-host.js @@ -5,7 +5,6 @@ const http = require('http') const https = require('https') const morgan = require('morgan') const express = require('express') -const multer = require('multer') const bodyParser = require('body-parser') const expressListRoutes = require('express-list-routes') const debug = require('debug')('dataparty.service.host') @@ -41,7 +40,6 @@ class ServiceHost { if(debug.enabled){ this.apiApp.use(morgan('combined')) } - this.apiApp.use(multer().array()) this.apiApp.use(bodyParser.urlencoded({ extended: true })) this.apiApp.use(bodyParser.json()) this.apiApp.use(bodyParser.raw())