Skip to content

Commit dfc9b1c

Browse files
committed
fix: imporved authentication handling
1 parent e4bf74c commit dfc9b1c

File tree

1 file changed

+51
-67
lines changed

1 file changed

+51
-67
lines changed

src/server.js

Lines changed: 51 additions & 67 deletions
Original file line numberDiff line numberDiff line change
@@ -216,17 +216,23 @@ class CoCreateLazyLoader {
216216
if (!key)
217217
throw new Error(`Missing ${name} key in organization apis object`);
218218

219-
let name = data.req.url.split('/');
220-
name = name[3] || name[2] || name[1]
219+
let webhookName = data.req.url.split('/');
220+
webhookName = webhookName[webhookName.length - 1]
221221

222-
// TODO: webhook secert could be a key pair
223-
const webhook = data.apis[environment].webhooks[name];
222+
const webhook = apis[environment].webhooks[webhookName];
224223
if (!webhook)
225-
throw new Error(`Webhook ${name} is not defined`);
226-
else if (!webhook.eventKey)
224+
throw new Error(`Webhook ${name} ${webhookName} is not defined`);
225+
226+
let dataKey = webhook.dataKey || apis[environment].dataKey
227+
if (!dataKey)
228+
throw new Error(`Webhook ${name} eventKey is not defined`);
229+
230+
let nameKey = webhook.nameKey || apis[environment].nameKey
231+
if (!nameKey)
227232
throw new Error(`Webhook ${name} eventKey is not defined`);
228-
else if (!webhook.events)
229-
throw new Error(`Webhook ${name} events is not defined`);
233+
234+
if (!webhook.events)
235+
throw new Error(`Webhook ${name} events are not defined`);
230236

231237
let rawBody = '';
232238
await new Promise((resolve, reject) => {
@@ -243,53 +249,27 @@ class CoCreateLazyLoader {
243249

244250
let parameters, method
245251

246-
if (webhook.events[webhook.eventKey].authenticate) {
247-
method = webhook.events[eventName].authenticate.method
248-
parameters = webhook.events[eventName].authenticate.parameters
252+
if (webhook.authenticate) {
253+
method = webhook.authenticate.method
254+
parameters = webhook.authenticate.parameters
249255
}
250256

251-
if (!parameters && webhook.authenticate && webhook.authenticate.parameters) {
252-
parameters = webhook.authenticate.parameters
253-
} else if (!parameters && data.apis[environment].authenticate) {
254-
parameters = webhook.authenticate.parameters
257+
if (!parameters && apis[environment].authenticate && apis[environment].authenticate.parameters) {
258+
parameters = apis[environment].authenticate.parameters
255259
} else
256260
throw new Error(`Webhook secret ${name} is not defined`);
257261

258-
if (!method && webhook.authenticate && webhook.authenticate.method)
259-
method = webhook.authenticate.method
260-
else if (!method && data.apis[environment].authenticate)
261-
method = data.apis[environment].authenticate.method
262-
263-
264-
if (!method && parameters[0] !== parameters[1])
265-
throw new Error(`Webhook secret failed for ${name}. Unauthorized access attempt.`);
262+
if (!method && apis[environment].authenticate)
263+
method = apis[environment].authenticate.method
266264

265+
// TODO: webhook secert could be a key pair
267266

268-
let event, eventName
267+
let event
269268
if (!method) {
270-
event = JSON.parse(rawBody)
271-
eventName = event[webhook.eventKey]
272-
273-
if (!eventName) {
274-
throw new Error(`Webhook ${name} eventKey: ${webhook.eventKey} could not be found in the event.`);
275-
} else if (!webhook.events[eventName]) {
276-
throw new Error(`Webhook ${name} eventName: ${webhook.eventName} is not defined.`);
277-
} else if (webhook.events[eventName].authenticate) {
278-
method = webhook.events[eventName].authenticate.method
279-
parameters = webhook.events[eventName].authenticate.parameters
280-
}
281-
282-
if (!parameters && webhook.authenticate && webhook.authenticate.parameters) {
283-
parameters = webhook.authenticate.parameters
284-
} else
285-
throw new Error(`Webhook secret ${name} is not defined`);
286-
287-
if (!method && webhook.authenticate)
288-
method = webhook.authenticate.method
289-
290-
if (!method && parameters[0] !== parameters[1])
269+
if (!parameters[0] !== parameters[1])
291270
throw new Error(`Webhook secret failed for ${name}. Unauthorized access attempt.`);
292271

272+
event = JSON.parse(rawBody)
293273
} else {
294274
const service = require(config.path);
295275
const instance = new service[config.initialize](key);
@@ -306,9 +286,17 @@ class CoCreateLazyLoader {
306286
event = await property.apply(instance, parameters);
307287
}
308288

289+
let eventName = getValueFromObject(event, nameKey)
290+
if (!eventName)
291+
throw new Error(`Webhook ${name} nameKey: ${nameKey} could not be found in the event.`);
292+
293+
let eventData = getValueFromObject(event, dataKey)
294+
if (!eventData)
295+
throw new Error(`Webhook ${name} dataKey: ${dataKey} could not be found in the event.`);
296+
309297
let execute = webhook.events[eventName];
310298
if (execute) {
311-
execute = await processOperators(data, execute);
299+
execute = await processOperators(data, event, execute);
312300
}
313301

314302
data.res.writeHead(200, { 'Content-Type': 'application/json' });
@@ -335,36 +323,36 @@ class CoCreateLazyLoader {
335323

336324
}
337325

338-
async function processOperators(data, obj, parent = null, parentKey = null) {
339-
if (Array.isArray(obj)) {
340-
obj.forEach(async (item, index) => await processOperators(data, item, obj, index));
341-
} else if (typeof obj === 'object' && obj !== null) {
342-
for (let key of Object.keys(obj)) {
326+
async function processOperators(data, event, execute, parent = null, parentKey = null) {
327+
if (Array.isArray(execute)) {
328+
execute.forEach(async (item, index) => await processOperators(data, event, item, execute, index));
329+
} else if (typeof execute === 'executeect' && execute !== null) {
330+
for (let key of Object.keys(execute)) {
343331
// Check if key is an operator
344332
if (key.startsWith('$')) {
345-
const operatorResult = await processOperator(data, key, obj[key]);
333+
const operatorResult = await processOperator(data, event, key, execute[key]);
346334
if (parent && operatorResult !== null) {
347335
if (parentKey !== null) {
348336
parent[parentKey] = operatorResult;
349-
await processOperators(data, parent[parentKey], parent, parentKey);
337+
await processOperators(data, event, parent[parentKey], parent, parentKey);
350338
}
351339
// else {
352-
// // Scenario 2: Replace the key (more complex, might require re-structuring the object)
340+
// // Scenario 2: Replace the key (more complex, might require re-structuring the executable object)
353341
// delete parent[key]; // Remove the original key
354-
// parent[operatorResult] = obj[key]; // Assign the value to the new key
342+
// parent[operatorResult] = execute[key]; // Assign the value to the new key
355343
// // Continue processing the new key if necessary
356344
// }
357345
}
358346
} else {
359-
await processOperators(data, obj[key], obj, key);
347+
await processOperators(data, event, execute[key], execute, key);
360348
}
361349
}
362350
} else {
363-
return await processOperator(data, obj);
351+
return await processOperator(data, event, execute);
364352
}
365353
}
366354

367-
async function processOperator(data, operator, context) {
355+
async function processOperator(data, event, operator, context) {
368356
if (operator.startsWith('$data.')) {
369357
operator = getValueFromObject(data, operator.substring(6))
370358
} else if (operator.startsWith('$req.')) {
@@ -382,17 +370,13 @@ async function processOperator(data, operator, context) {
382370
} else if (operator.startsWith('$api')) {
383371
let name = context.method.split('.')[0]
384372
operator = this.executeScriptWithTimeout(name, context)
385-
} else if (operator.startsWith('$webhook')) {
386-
// TODO: would expect a data.req
387-
// let name = context.method.split('.')[0]
388-
// operator = this.executeScriptWithTimeout(name, context)
373+
} else if (operator.startsWith('$webhook.')) {
374+
operator = getValueFromObject(webhook, operator.substring(9))
375+
} else if (operator.startsWith('$event.')) {
376+
operator = getValueFromObject(event, operator.substring(7))
389377
}
390378

391-
// TODO: function to parse and execute object in order to broadcast/store some or all of the returned event
392-
393-
// TODO: using request.method and event.type get object and send socket.onMessage for proccessing
394-
395-
return operator; // For illustration, return the operator itself or the computed value
379+
return operator;
396380
}
397381

398382
function getModuleDependencies(modulePath) {

0 commit comments

Comments
 (0)