Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Investigate hook page issue on CI #5897

Open
wants to merge 10 commits into
base: next
Choose a base branch
from
146 changes: 39 additions & 107 deletions plugins/hooks/api/api.js
Original file line number Diff line number Diff line change
@@ -1,7 +1,9 @@

const Triggers = require('./parts/triggers/index.js');
const Effects = require('./parts/effects/index.js');
const asyncLib = require('async');
const EventEmitter = require('events');

const common = require('../../../api/utils/common.js');
const { validateRead, validateCreate, validateDelete, validateUpdate } = require('../../../api/utils/rights.js');
const plugins = require('../../pluginManager.js');
Expand Down Expand Up @@ -272,82 +274,46 @@ plugins.register("/permissions/features", function(ob) {
plugins.register("/i/hook/save", function(ob) {
let paramsInstance = ob.params;


validateCreate(ob.params, FEATURE_NAME, function(params) {
let hookConfig = params.qstring.hook_config;
if (!hookConfig) {
common.returnMessage(params, 400, 'Invalid hookConfig');
return true;
}

try {
hookConfig = JSON.parse(hookConfig);
hookConfig = sanitizeConfig(hookConfig);
if (hookConfig) {
// Null check for hookConfig
if (!(common.validateArgs(hookConfig, CheckHookProperties(hookConfig)))) {
common.returnMessage(params, 400, 'Not enough args');
return true;
}
if (!(common.validateArgs(hookConfig, CheckHookProperties(hookConfig)))) {
common.returnMessage(params, 400, 'Not enough args');
return true;
}

if (hookConfig.effects && !validateEffects(hookConfig.effects)) {
common.returnMessage(params, 400, 'Invalid configuration for effects');
return true;
}
if (hookConfig && hookConfig.effects && !validateEffects(hookConfig.effects)) {
common.returnMessage(params, 400, 'Invalid configuration for effects');
return true;
}

if (hookConfig._id) {
const id = hookConfig._id;
delete hookConfig._id;
return common.db.collection("hooks").findAndModify(
{ _id: common.db.ObjectID(id) },
{},
{$set: hookConfig},
{new: true},
function(err, result) {
if (!err) {
// Audit log: Hook updated
if (result && result.value) {
plugins.dispatch("/systemlogs", {
params: params,
action: "hook_updated",
data: {
updatedHookID: result.value._id,
updatedBy: params.member._id,
updatedHookName: result.value.name
}
});
}
else {
common.returnMessage(params, 500, "No result found");
}
common.returnOutput(params, result && result.value);
}
else {
common.returnMessage(params, 500, "Failed to save an hook");
}
if (hookConfig._id) {
const id = hookConfig._id;
delete hookConfig._id;
return common.db.collection("hooks").findAndModify(
{ _id: common.db.ObjectID(id) },
{},
{$set: hookConfig},
{new: true},
function(err, result) {
if (!err) {
common.returnOutput(params, result && result.value);
}
);
}

}
if (hookConfig) {
hookConfig.createdBy = params.member._id; // Accessing property now with proper check
hookConfig.created_at = new Date().getTime();
else {
common.returnMessage(params, 500, "Failed to save an hook");
}
});
}
hookConfig.createdBy = params.member._id;
hookConfig.created_at = new Date().getTime();
return common.db.collection("hooks").insert(
hookConfig,
function(err, result) {
log.d("insert new hook:", err, result);
if (!err && result && result.insertedIds && result.insertedIds[0]) {
// Audit log: Hook created
plugins.dispatch("/systemlogs", {
params: params,
action: "hook_created",
data: {
createdHookID: hookConfig._id,
createdBy: params.member._id,
createdHookName: hookConfig.name
}
});
common.returnOutput(params, result.insertedIds[0]);
}
else {
Expand Down Expand Up @@ -502,8 +468,8 @@ plugins.register("/o/hook/list", function(ob) {
});
}
catch (err) {
log.e('get hook list failed', err);
common.returnMessage(params, 500, "Failed to get hook list" + err.message);
log.e('get hook list failed');
common.returnMessage(params, 500, "Failed to get hook list");
}
}, paramsInstance);
return true;
Expand Down Expand Up @@ -544,16 +510,7 @@ plugins.register("/i/hook/status", function(ob) {
}
Promise.all(batch).then(function() {
log.d("hooks all updated.");
// Audit log: Hook status updated
plugins.dispatch("/systemlogs", {
params: params,
action: "hook_status_updated",
data: { updatedHooksCount: Object.keys(statusList).length, requestedBy: params.member._id }
});
common.returnOutput(params, true);
}).catch(function(err) {
log.e('Failed to update hook statuses: ', err);
common.returnMessage(params, 500, "Failed to update hook statuses: " + err.message);
});
}, paramsInstance);
return true;
Expand Down Expand Up @@ -587,23 +544,14 @@ plugins.register("/i/hook/delete", function(ob) {
function(err, result) {
log.d(err, result, "delete an hook");
if (!err) {
// Audit log: Hook deleted
plugins.dispatch("/systemlogs", {
params: params,
action: "hook_deleted",
data: {
deletedHookID: hookID,
requestedBy: params.member._id
}
});
common.returnMessage(params, 200, "Deleted an hook");
}
}
);
}
catch (err) {
log.e('delete hook failed', hookID, err);
common.returnMessage(params, 500, "Failed to delete an hook" + err.message);
log.e('delete hook failed', hookID);
common.returnMessage(params, 500, "Failed to delete an hook");
}
}, paramsInstance);
return true;
Expand All @@ -615,56 +563,40 @@ plugins.register("/i/hook/test", function(ob) {

validateCreate(paramsInstance, FEATURE_NAME, async(params) => {
let hookConfig = params.qstring.hook_config;
if (!hookConfig) {
common.returnMessage(params, 400, 'Invalid hookConfig');
return;
}

try {
hookConfig = JSON.parse(hookConfig);
if (!hookConfig) {
common.returnMessage(params, 400, 'Parsed hookConfig is invalid');
return;
}
hookConfig = sanitizeConfig(hookConfig);
const mockData = JSON.parse(params.qstring.mock_data);

if (!(common.validateArgs(hookConfig, CheckHookProperties(hookConfig)))) {
common.returnMessage(params, 403, "hook config invalid" + JSON.stringify(hookConfig));
return; // Add return to exit early
common.returnMessage(params, 403, "hook config invalid");
}

// Null check for effects
if (hookConfig.effects && !validateEffects(hookConfig.effects)) {
if (hookConfig && hookConfig.effects && !validateEffects(hookConfig.effects)) {
common.returnMessage(params, 400, 'Config invalid');
return; // Add return to exit early
return true;
}


// trigger process
log.d(JSON.stringify(hookConfig), "[hook test config]");
const results = [];

// build mock data
const trigger = hookConfig.trigger;
if (!trigger) {
common.returnMessage(params, 400, 'Trigger is missing');
return;
}
hookConfig._id = null;

log.d("[hook test mock data]", mockData);
const obj = {
is_mock: true,
params: mockData,
rule: hookConfig
};

log.d("[hook test config data]", obj);
const t = new Triggers[trigger.type]({
rules: [hookConfig],
});

// output trigger result
// out put trigger result
const triggerResult = await t.process(obj);
log.d("[hook trigger test result]", triggerResult);
results.push(JSON.parse(JSON.stringify(triggerResult)));
Expand Down Expand Up @@ -695,8 +627,8 @@ plugins.register("/i/hook/test", function(ob) {
return false;
}
catch (e) {
log.e("hook test error", e, hookConfig);
common.returnMessage(params, 503, "Hook test failed." + e.message);
log.e("hook test error", e);
common.returnMessage(params, 503, "Hook test failed.");
return;
}
}, paramsInstance);
Expand Down
6 changes: 3 additions & 3 deletions plugins/hooks/api/parts/triggers/api_endpoint.js
Original file line number Diff line number Diff line change
Expand Up @@ -47,8 +47,8 @@ class APIEndPointTrigger {
*/
async process(ob) {
// log.d(JSON.stringify(ob), "[hook trigger api_endpoint]");
const {params} = ob || {};
const {paths} = params || {};
const {params} = ob;
const {paths} = params;
const hookPath = paths.length >= 4 ? paths[3] : null;
const {qstring} = params || {};

Expand Down Expand Up @@ -85,4 +85,4 @@ class APIEndPointTrigger {
}
}

module.exports = APIEndPointTrigger;
module.exports = APIEndPointTrigger;
22 changes: 9 additions & 13 deletions plugins/hooks/frontend/public/localization/hooks.properties
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,7 @@ configs.help.hooks-timeWindowForRequestLimit=The time window for the request lim
hooks.InternalEventTrigger = Internal Actions
hooks.trigger-api-endpoint-uri= API Endpoint
hooks.trigger-introduction = Introduction
hooks.trigger-api-endpoint-intro-content = <span>Send a GET request with query string parameter “payload” as a JSON string to the below URL:</span><br/><span class="url"> {0}</span>
hooks.APIEndPointTrigger = API Endpoint
hooks.internal-event-selector-title = Internal Actions
hooks.internal-event-selector-placeholder = Please select an internal action
Expand Down Expand Up @@ -79,13 +80,13 @@ hooks.http-method-get = GET
hooks.http-method-post = POST
hooks.http-effect-description= Use {{payload_json}} to include the entire trigger data as a JSON object in your request body, or {{payload_string}} to include a stringified JSON in your query string. You can also use individual properties within the trigger data such as {{user}}.

hooks.intro-hooks-trigger = /hooks/trigger will capture triggered data from the selected hook trigger. Output: Trigger output data from selected hook.
hooks.intro-i-app_users-delete= /i/app_users/delete will capture deleted user profiles.Output: Individual user profile data
hooks.intro-i-app_users-update = /i/app_users/update will capture updated user profiles.Output: Individual user profile data
hooks.intro-i-app_users-create = /i/app_users/create will capture created user profiles.Output: Individual user profile data
hooks.intro-cohort-exit = /cohort/exit will capture users who exit from the selected cohort. Output: Individual user profile data
hooks.intro-cohort-enter = /cohort/enter will capture users who enter into the selected cohort. Output: Individual user profile data
hooks.intro-incoming-data = Will capture event data when match filter rules. Output: Event data & user profile data.
hooks.intro-hooks-trigger = /hooks/trigger will capture triggered data from the selected hook trigger. <br/>Output: Trigger output data from selected hook.
hooks.intro-i-app_users-delete= /i/app_users/delete will capture deleted user profiles.<br/>Output: Individual user profile data
hooks.intro-i-app_users-update = /i/app_users/update will capture updated user profiles.<br/>Output: Individual user profile data
hooks.intro-i-app_users-create = /i/app_users/create will capture created user profiles.<br/>Output: Individual user profile data
hooks.intro-cohort-exit = /cohort/exit will capture users who exit from the selected cohort. <br/>Output: Individual user profile data
hooks.intro-cohort-enter = /cohort/enter will capture users who enter into the selected cohort. <br/>Output: Individual user profile data
hooks.intro-incoming-data = Will capture event data when match filter rules. <br/>Output: Event data & user profile data.
hooks.copy-notify-message = API Endpoint URL is copied.
hooks.copy-notify-title = Copy URL
hooks.Select_country = Select Country
Expand Down Expand Up @@ -142,9 +143,4 @@ hooks.actions-tips = Select the actions the hook will do upon being triggered. Y
hooks.application-tips = The app(s) for which you want to create a hook.
hooks.trigger-count-tips = Number of times the hook has been triggered.
hooks.trigger-action-tips = Identifies the trigger for the hook, and the actions that show the method through which data will be sent.
hooks.trigger-save-failed = Hook could not be saved.

systemlogs.action.hook_created = Hook Created
systemlogs.action.hook_updated = Hook Updated
systemlogs.action.hook_status_updated = Hook Status Updated
systemlogs.action.hook_deleted = Hook Deleted
hooks.trigger-save-failed = Hook could not be saved.
Loading