From b4fde61884963c7ae82947d61c109cf48fd67571 Mon Sep 17 00:00:00 2001 From: Nikolai Ovtsinnikov Date: Fri, 15 Dec 2023 12:05:17 +0200 Subject: [PATCH 1/5] optimize CPU usage --- lib/imap-notifier.js | 45 ++++++++++++++++++++++++++++++++++---------- 1 file changed, 35 insertions(+), 10 deletions(-) diff --git a/lib/imap-notifier.js b/lib/imap-notifier.js index 1e7dd09c..dfd4397f 100644 --- a/lib/imap-notifier.js +++ b/lib/imap-notifier.js @@ -78,17 +78,42 @@ class ImapNotifier extends EventEmitter { this.subscriber.on('message', (channel, message) => { if (channel === 'wd_events') { let data; - try { - data = JSON.parse(message); - } catch (E) { - return; + // if e present at beginning, check if p also is present + // if no p -> no json parse + // if p -> json parse ONLY p + // if e not in beginning but p is -> json parse whole + + if (message[2] === 'e') { + for (let i = 6; i < 6 + 24; i++) { + if (!/[0-9ABCDEF]/i.test(message[i])) { + // check for hex char + return; // incorrect e, e HAS to be hex + } + } + + data = { e: message.slice(6, 6 + 24) }; + + if (message[33] === 'p') { + // parse next JSON only if the payload is actually there + data.p = JSON.parse('{' + message.slice(32, message.length - 1) + '}').p; + } + } else { + try { + data = JSON.parse(message); + } catch (E) { + return; + } } - if (data.e && !data.p) { - // events without payload are scheduled, these are notifications about changes in journal - scheduleDataEvent(data.e); - } else if (data.e) { - // events with payload are triggered immediatelly, these are actions for doing something - this._listeners.emit(data.e, data.p); + + if (this._listeners._events[data.e] && this._listeners._events[data.e].length > 0) { + // do not schedule or fire/emit empty events + if (data.e && !data.p) { + // events without payload are scheduled, these are notifications about changes in journal + scheduleDataEvent(data.e); + } else if (data.e) { + // events with payload are triggered immediatelly, these are actions for doing something + this._listeners.emit(data.e, data.p); + } } } }); From 713a06c216c074f532d341ae46f2a116d639c39b Mon Sep 17 00:00:00 2001 From: Nikolai Ovtsinnikov Date: Tue, 2 Jan 2024 12:28:13 +0200 Subject: [PATCH 2/5] fix requestBody issues in API docs generation --- lib/tools.js | 32 +++++++++++++++++--------------- 1 file changed, 17 insertions(+), 15 deletions(-) diff --git a/lib/tools.js b/lib/tools.js index 85f59d3c..0a895dd4 100644 --- a/lib/tools.js +++ b/lib/tools.js @@ -17,6 +17,8 @@ const ObjectId = require('mongodb').ObjectId; const log = require('npmlog'); const addressparser = require('nodemailer/lib/addressparser'); +const Joi = require('joi'); + let templates = false; const structuredCloneWrapper = typeof structuredClone === 'function' ? structuredClone : obj => JSON.parse(JSON.stringify(obj)); @@ -765,6 +767,10 @@ function parseJoiObject(path, joiObject, requestBodyProperties) { const data = { type: openApiType, description, required: isRequired }; if (format) { data.format = format; + + if (data.format === 'date') { + data.format = 'date-time'; + } } if (path) { @@ -956,22 +962,18 @@ module.exports = { // 5) add requestBody const applicationType = spec.applicationType || 'application/json'; - operationObj.requestBody = { - content: { - [applicationType]: { - schema: { - type: 'object', - properties: {} - } - } - }, - required: true - }; - for (const reqBodyKey in spec.validationObjs?.requestBody) { - const reqBodyKeyData = spec.validationObjs.requestBody[reqBodyKey]; + if (spec.validationObjs?.requestBody && Object.keys(spec.validationObjs.requestBody).length > 0) { + operationObj.requestBody = { + content: { + [applicationType]: { + schema: {} + } + }, + required: true + }; - parseJoiObject(reqBodyKey, reqBodyKeyData, operationObj.requestBody.content[applicationType].schema.properties); + parseJoiObject('schema', Joi.object(spec.validationObjs?.requestBody), operationObj.requestBody.content[applicationType]); } // 6) add parameters (queryParams + pathParams). @@ -1033,7 +1035,7 @@ module.exports = { const innerData = pathData[httpMethod]; // for every requestBody obj - for (const key in innerData.requestBody.content[Object.keys(innerData.requestBody.content)[0]].schema.properties) { + for (const key in innerData?.requestBody?.content[Object.keys(innerData.requestBody.content)[0]].schema.properties) { const reqBodyData = innerData.requestBody.content[Object.keys(innerData.requestBody.content)[0]].schema.properties[key]; parseComponetsDecoupled(reqBodyData, components.components.schemas); From 17232dd5e05b614cae8cc9d2f02be40b3fbc2df8 Mon Sep 17 00:00:00 2001 From: Nikolai Ovtsinnikov Date: Tue, 2 Jan 2024 12:33:05 +0200 Subject: [PATCH 3/5] fix requestBody issues for API generation --- lib/tools.js | 1 + 1 file changed, 1 insertion(+) diff --git a/lib/tools.js b/lib/tools.js index 0a895dd4..edd80209 100644 --- a/lib/tools.js +++ b/lib/tools.js @@ -973,6 +973,7 @@ module.exports = { required: true }; + // convert to Joi object for easier parsing parseJoiObject('schema', Joi.object(spec.validationObjs?.requestBody), operationObj.requestBody.content[applicationType]); } From 3b6ba9ae030cca246eb229e3fcf275d00a9e5a13 Mon Sep 17 00:00:00 2001 From: Nikolai Ovtsinnikov Date: Tue, 2 Jan 2024 12:34:20 +0200 Subject: [PATCH 4/5] Revert "optimize CPU usage" This reverts commit b4fde61884963c7ae82947d61c109cf48fd67571. --- lib/imap-notifier.js | 45 ++++++++++---------------------------------- 1 file changed, 10 insertions(+), 35 deletions(-) diff --git a/lib/imap-notifier.js b/lib/imap-notifier.js index dfd4397f..1e7dd09c 100644 --- a/lib/imap-notifier.js +++ b/lib/imap-notifier.js @@ -78,42 +78,17 @@ class ImapNotifier extends EventEmitter { this.subscriber.on('message', (channel, message) => { if (channel === 'wd_events') { let data; - // if e present at beginning, check if p also is present - // if no p -> no json parse - // if p -> json parse ONLY p - // if e not in beginning but p is -> json parse whole - - if (message[2] === 'e') { - for (let i = 6; i < 6 + 24; i++) { - if (!/[0-9ABCDEF]/i.test(message[i])) { - // check for hex char - return; // incorrect e, e HAS to be hex - } - } - - data = { e: message.slice(6, 6 + 24) }; - - if (message[33] === 'p') { - // parse next JSON only if the payload is actually there - data.p = JSON.parse('{' + message.slice(32, message.length - 1) + '}').p; - } - } else { - try { - data = JSON.parse(message); - } catch (E) { - return; - } + try { + data = JSON.parse(message); + } catch (E) { + return; } - - if (this._listeners._events[data.e] && this._listeners._events[data.e].length > 0) { - // do not schedule or fire/emit empty events - if (data.e && !data.p) { - // events without payload are scheduled, these are notifications about changes in journal - scheduleDataEvent(data.e); - } else if (data.e) { - // events with payload are triggered immediatelly, these are actions for doing something - this._listeners.emit(data.e, data.p); - } + if (data.e && !data.p) { + // events without payload are scheduled, these are notifications about changes in journal + scheduleDataEvent(data.e); + } else if (data.e) { + // events with payload are triggered immediatelly, these are actions for doing something + this._listeners.emit(data.e, data.p); } } }); From b0d0e7b955d3ba1a892a6b15832b601230b1b1ba Mon Sep 17 00:00:00 2001 From: Nikolai Ovtsinnikov Date: Tue, 2 Jan 2024 13:10:04 +0200 Subject: [PATCH 5/5] fix securitySchemes --- lib/tools.js | 29 +++++++++++++++-------------- 1 file changed, 15 insertions(+), 14 deletions(-) diff --git a/lib/tools.js b/lib/tools.js index edd80209..ee1f22f9 100644 --- a/lib/tools.js +++ b/lib/tools.js @@ -1060,25 +1060,26 @@ module.exports = { const finalObj = { paths: mapPathToMethods }; + components.components.securitySchemes = { + AccessTokenAuth: { + name: 'X-Access-Token', + type: 'apiKey', + in: 'header', + description: `If authentication is enabled in the WildDuck configuration, you will need to supply an access token in the \`X-Access-Token\` header.\n + \`\`\`json + { + "X-Access-Token": "59fc66a03e54454869460e45" + } + \`\`\` + ` + } + }; + docs = { ...docs, ...finalObj }; docs = { ...docs, ...components }; docs = { ...docs, - securitySchemes: { - AccessTokenAuth: { - name: 'X-Access-Token', - type: 'apiKey', - in: 'header', - description: `If authentication is enabled in the WildDuck configuration, you will need to supply an access token in the \`X-Access-Token\` header. - \`\`\`json - { - "X-Access-Token": "59fc66a03e54454869460e45" - } - \`\`\` - ` - } - }, security: [{ AccessTokenAuth: [] }] };