diff --git a/coffee/components-manager.coffee b/coffee/components-manager.coffee
index 03113db..c7185d9 100644
--- a/coffee/components-manager.coffee
+++ b/coffee/components-manager.coffee
@@ -14,6 +14,8 @@ Components Manager
db = require './persistence'
# - [Dynamic Modules](dynamic-modules.html)
dynmod = require './dynamic-modules'
+# - [Encryption](encryption.html)
+encryption = require './encryption'
# - Node.js Modules: [fs](http://nodejs.org/api/fs.html),
# [path](http://nodejs.org/api/path.html) and
@@ -159,40 +161,109 @@ getModuleParams = ( user, oPayload, dbMod, callback ) ->
answ.message = oPayload
callback answ
+getModuleUserParams = ( user, oPayload, dbMod, callback ) ->
+ answ = hasRequiredParams [ 'id' ], oPayload
+ if answ.code isnt 200
+ callback answ
+ else
+ dbMod.getUserParams oPayload.id, user.username, ( err, str ) ->
+ oParams = JSON.parse str
+ for name, oParam of oParams
+ if not oParam.shielded
+ oParam.value = encryption.decrypt oParam.value
+ answ.message = JSON.stringify oParams
+ callback answ
+
+getModuleUserArguments = ( user, oPayload, dbMod, callback ) ->
+ answ = hasRequiredParams [ 'ruleId' ,'moduleId' ], oPayload
+ if answ.code isnt 200
+ callback answ
+ else
+ dbMod.getAllModuleUserArguments user.username, oPayload.ruleId, oPayload.moduleId, ( err, oPayload ) ->
+ answ.message = oPayload
+ callback answ
forgeModule = ( user, oPayload, dbMod, callback ) =>
answ = hasRequiredParams [ 'id', 'params', 'lang', 'data' ], oPayload
if answ.code isnt 200
callback answ
else
- i = 0
- dbMod.getModule oPayload.id, ( err, mod ) =>
- if mod
- answ.code = 409
- answ.message = 'Module name already existing: ' + oPayload.id
- callback answ
- else
- src = oPayload.data
- dynmod.compileString src, user.username, 'dummyRule', oPayload.id, oPayload.lang, null, ( cm ) =>
- answ = cm.answ
- if answ.code is 200
- funcs = []
- funcs.push name for name, id of cm.module
- @log.info "CM | Storing new module with functions #{ funcs.join( ', ' ) }"
- answ.message =
- " Module #{ oPayload.id } successfully stored! Found following function(s): #{ funcs }"
- oPayload.functions = JSON.stringify funcs
- oPayload.functionArgs = JSON.stringify cm.funcParams
- dbMod.storeModule user.username, oPayload
- if oPayload.public is 'true'
- dbMod.publish oPayload.id
+ if oPayload.overwrite
+ storeModule user, oPayload, dbMod, callback
+ else
+ dbMod.getModule oPayload.id, ( err, mod ) =>
+ if mod
+ answ.code = 409
+ answ.message = 'Module name already existing: ' + oPayload.id
callback answ
+ else
+ storeModule user, oPayload, dbMod, callback
+
+storeModule = ( user, oPayload, dbMod, callback ) =>
+ src = oPayload.data
+ dynmod.compileString src, user.username, 'dummyRule', oPayload.id, oPayload.lang, null, ( cm ) =>
+ answ = cm.answ
+ if answ.code is 200
+ funcs = []
+ funcs.push name for name, id of cm.module
+ @log.info "CM | Storing new module with functions #{ funcs.join( ', ' ) }"
+ answ.message =
+ " Module #{ oPayload.id } successfully stored! Found following function(s): #{ funcs }"
+ oPayload.functions = JSON.stringify funcs
+ oPayload.functionArgs = JSON.stringify cm.funcParams
+ dbMod.storeModule user.username, oPayload
+ if oPayload.public is 'true'
+ dbMod.publish oPayload.id
+ callback answ
+
+storeRule = ( user, oPayload, callback ) =>
+ # This is how a rule is stored in the database
+ rule =
+ id: oPayload.id
+ event: oPayload.event
+ event_interval: oPayload.event_interval
+ conditions: oPayload.conditions
+ actions: oPayload.actions
+ strRule = JSON.stringify rule
+ # store the rule
+ db.storeRule rule.id, strRule
+ # link the rule to the user
+ db.linkRule rule.id, user.username
+ # activate the rule
+ db.activateRule rule.id, user.username
+ # if event module parameters were send, store them
+ if oPayload.event_params
+ epModId = rule.event.split( ' -> ' )[ 0 ]
+ db.eventPollers.storeUserParams epModId, user.username, JSON.stringify oPayload.event_params
+
+ # if action module params were send, store them
+ oParams = oPayload.action_params
+ for id, params of oParams
+ db.actionInvokers.storeUserParams id, user.username, JSON.stringify params
+ oParams = oPayload.action_functions
+ # if action function arguments were send, store them
+ for id, params of oParams
+ arr = id.split ' -> '
+ db.actionInvokers.storeUserArguments user.username, rule.id, arr[ 0 ], arr[ 1 ], JSON.stringify params
+
+ # Initialize the rule log
+ db.resetLog user.username, rule.id
+ db.appendLog user.username, rule.id, "INIT", "Rule '#{ rule.id }' initialized"
+
+ # Inform everbody about the new rule
+ eventEmitter.emit 'rule',
+ event: 'new'
+ user: user.username
+ rule: rule
+ callback
+ code: 200
+ message: "Rule '#{ rule.id }' stored and activated!"
commandFunctions =
get_public_key: ( user, oPayload, callback ) ->
callback
code: 200
- message: dynmod.getPublicKey()
+ message: encryption.getPublicKey()
# EVENT POLLERS
# -------------
@@ -208,6 +279,12 @@ commandFunctions =
get_event_poller_params: ( user, oPayload, callback ) ->
getModuleParams user, oPayload, db.eventPollers, callback
+ get_event_poller_user_params: ( user, oPayload, callback ) ->
+ getModuleUserParams user, oPayload, db.eventPollers, callback
+
+ get_event_poller_user_arguments: ( user, oPayload, callback ) ->
+ getModuleUserArguments user, oPayload, db.eventPollers, callback
+
forge_event_poller: ( user, oPayload, callback ) ->
forgeModule user, oPayload, db.eventPollers, callback
@@ -239,7 +316,13 @@ commandFunctions =
get_action_invoker_params: ( user, oPayload, callback ) ->
getModuleParams user, oPayload, db.actionInvokers, callback
- get_action_invoker_function_params: ( user, oPayload, callback ) ->
+ get_action_invoker_user_params: ( user, oPayload, callback ) ->
+ getModuleUserParams user, oPayload, db.actionInvokers, callback
+
+ get_action_invoker_user_arguments: ( user, oPayload, callback ) ->
+ getModuleUserArguments user, oPayload, db.actionInvokers, callback
+
+ get_action_invoker_function_arguments: ( user, oPayload, callback ) ->
answ = hasRequiredParams [ 'id' ], oPayload
if answ.code isnt 200
callback answ
@@ -270,6 +353,16 @@ commandFunctions =
code: 200
message: obj
+ get_rule: ( user, oPayload, callback ) ->
+ answ = hasRequiredParams [ 'id' ], oPayload
+ if answ.code isnt 200
+ callback answ
+ else
+ db.getRule oPayload.id, ( err, obj ) ->
+ callback
+ code: 200
+ message: obj
+
get_rule_log: ( user, oPayload, callback ) ->
answ = hasRequiredParams [ 'id' ], oPayload
if answ.code isnt 200
@@ -291,54 +384,16 @@ commandFunctions =
if answ.code isnt 200
callback answ
else
- db.getRule oPayload.id, ( err, oExisting ) ->
- if oExisting isnt null
- answ =
- code: 409
- message: 'Rule name already existing!'
- else
- # This is how a rule is stored in the database
- rule =
- id: oPayload.id
- event: oPayload.event
- event_interval: oPayload.event_interval
- conditions: oPayload.conditions
- actions: oPayload.actions
- strRule = JSON.stringify rule
- # store the rule
- db.storeRule rule.id, strRule
- # link the rule to the user
- db.linkRule rule.id, user.username
- # activate the rule
- db.activateRule rule.id, user.username
- # if event module parameters were send, store them
- if oPayload.event_params
- epModId = rule.event.split( ' -> ' )[0]
- db.eventPollers.storeUserParams epModId, user.username, oPayload.event_params
-
- # if action module params were send, store them
- oParams = oPayload.action_params
- for id, params of oParams
- db.actionInvokers.storeUserParams id, user.username, JSON.stringify params
- oParams = oPayload.action_functions
- # if action function arguments were send, store them
- for id, params of oParams
- arr = id.split ' -> '
- db.actionInvokers.storeUserArguments user.username, rule.id, arr[ 0 ], arr[ 1 ], JSON.stringify params
-
- # Initialize the rule log
- db.resetLog user.username, rule.id
- db.appendLog user.username, rule.id, "INIT", "Rule '#{ rule.id }' initialized"
-
- # Inform everbody about the new rule
- eventEmitter.emit 'rule',
- event: 'new'
- user: user.username
- rule: rule
- answ =
- code: 200
- message: "Rule '#{ rule.id }' stored and activated!"
- callback answ
+ if oPayload.overwrite
+ storeRule user, oPayload, callback
+ else
+ db.getRule oPayload.id, ( err, mod ) =>
+ if mod
+ answ.code = 409
+ answ.message = 'Rule name already existing: ' + oPayload.id
+ callback answ
+ else
+ storeRule user, oPayload, callback
delete_rule: ( user, oPayload, callback ) ->
answ = hasRequiredParams [ 'id' ], oPayload
diff --git a/coffee/dynamic-modules.coffee b/coffee/dynamic-modules.coffee
index 1ebd2b2..23fbce3 100644
--- a/coffee/dynamic-modules.coffee
+++ b/coffee/dynamic-modules.coffee
@@ -10,6 +10,8 @@ Dynamic Modules
# - [Persistence](persistence.html)
db = require './persistence'
+# - [Encryption](encryption.html)
+encryption = require './encryption'
# - Node.js Modules: [vm](http://nodejs.org/api/vm.html) and
# [events](http://nodejs.org/api/events.html)
@@ -18,11 +20,9 @@ needle = require 'needle'
request = require 'request'
# - External Modules: [coffee-script](http://coffeescript.org/),
-# [cryptico](https://github.com/wwwtyro/cryptico),
# [crypto-js](https://www.npmjs.org/package/crypto-js) and
# [import-io](https://www.npmjs.org/package/import-io)
cs = require 'coffee-script'
-cryptico = require 'my-cryptico'
cryptoJS = require 'crypto-js'
importio = require( 'import-io' ).client
@@ -37,21 +37,9 @@ Initializes the dynamic module handler.
###
exports = module.exports = ( args ) =>
@log = args.logger
- # FIXME this can't come through the arguments
- if not @strPublicKey and args[ 'keygen' ]
- db args
- passPhrase = args[ 'keygen' ]
- numBits = 1024
- @oPrivateRSAkey = cryptico.generateRSAKey passPhrase, numBits
- @strPublicKey = cryptico.publicKeyString @oPrivateRSAkey
- @log.info "DM | Public Key generated: #{ @strPublicKey }"
-
+ db args
module.exports
-
-exports.getPublicKey = () =>
- @strPublicKey
-
logFunction = ( uId, rId, mId ) ->
( msg ) ->
db.appendLog uId, rId, mId, msg
@@ -61,7 +49,7 @@ getFunctionParamNames = ( fName, func, oFuncs ) ->
fnStr = func.toString().replace regexpComments, ''
result = fnStr.slice( fnStr.indexOf( '(' ) + 1, fnStr.indexOf( ')' ) ).match /([^\s,]+)/g
if not result
- result = []
+ result = []
oFuncs[fName] = result
###
@@ -93,13 +81,14 @@ exports.compileString = ( src, userId, ruleId, modId, lang, dbMod, cb ) =>
if dbMod
dbMod.getUserParams modId, userId, ( err, obj ) =>
try
- oDecrypted = cryptico.decrypt obj, @oPrivateRSAkey
- obj = JSON.parse oDecrypted.plaintext
+ oParams = {}
+ for name, oParam of JSON.parse obj
+ oParams[ name ] = encryption.decrypt oParam.value
@log.info "DM | Loaded user defined params for #{ userId }, #{ ruleId }, #{ modId }"
catch err
@log.warn "DM | Error during parsing of user defined params for #{ userId }, #{ ruleId }, #{ modId }"
@log.warn err
- fTryToLoadModule userId, ruleId, modId, src, dbMod, obj, cb
+ fTryToLoadModule userId, ruleId, modId, src, dbMod, oParams, cb
else
fTryToLoadModule userId, ruleId, modId, src, dbMod, null, cb
@@ -156,8 +145,7 @@ fTryToLoadModule = ( userId, ruleId, modId, src, dbMod, params, cb ) =>
dbMod.getUserArguments userId, ruleId, modId, func, ( err, obj ) =>
if obj
try
- oDecrypted = cryptico.decrypt obj, @oPrivateRSAkey
- oFuncArgs[ func ] = JSON.parse oDecrypted.plaintext
+ oFuncArgs[ func ] = JSON.parse encryption.decrypt obj
@log.info "DM | Found and attached user-specific arguments to #{ userId }, #{ ruleId }, #{ modId }"
catch err
@log.warn "DM | Error during parsing of user-specific arguments for #{ userId }, #{ ruleId }, #{ modId }"
diff --git a/coffee/encryption.coffee b/coffee/encryption.coffee
new file mode 100644
index 0000000..6f94bb9
--- /dev/null
+++ b/coffee/encryption.coffee
@@ -0,0 +1,29 @@
+###
+
+Encryption
+===============
+> Handles RSA encryption and decryption of user specific parameters.
+###
+
+# **Loads Modules:**
+
+# - [cryptico](https://github.com/wwwtyro/cryptico)
+cryptico = require 'my-cryptico'
+
+exports = module.exports = ( args ) =>
+ @log = args.logger
+ @oPrivateRSAkey = cryptico.generateRSAKey args[ 'keygen' ], 1024
+ @strPublicKey = cryptico.publicKeyString @oPrivateRSAkey
+ @log.info "DM | Public Key generated: #{ @strPublicKey }"
+ module.exports
+
+exports.getPublicKey = () =>
+ @strPublicKey
+
+exports.encrypt = ( plainText ) =>
+ oEncrypted = cryptico.encrypt plainText, @strPublicKey
+ oEncrypted.cipher
+
+exports.decrypt = ( strEncrypted ) =>
+ oDecrypted = cryptico.decrypt strEncrypted, @oPrivateRSAkey
+ oDecrypted.plaintext
diff --git a/coffee/event-poller.coffee b/coffee/event-poller.coffee
index 08daa20..32b98df 100644
--- a/coffee/event-poller.coffee
+++ b/coffee/event-poller.coffee
@@ -8,11 +8,13 @@ Dynamic Modules
# **Loads Modules:**
-# - [Logging](logging.html), [Persistence](persistence.html)
+# - [Logging](logging.html), [Persistence](persistence.html),
+# [Encryption](encryption.html)
# and [Dynamic Modules](dynamic-modules.html)
logger = require './logging'
db = require './persistence'
dynmod = require './dynamic-modules'
+encryption = require './encryption'
# If we do not receive all required arguments we shut down immediately
if process.argv.length < 8
@@ -33,6 +35,9 @@ log.info 'EP | Event Poller starts up'
db logger: log
dynmod
logger: log
+
+encryption
+ logger: log
keygen: process.argv[ 7 ]
# Initialize module local variables and
diff --git a/coffee/persistence.coffee b/coffee/persistence.coffee
index 5c6ae58..2d0e36b 100644
--- a/coffee/persistence.coffee
+++ b/coffee/persistence.coffee
@@ -345,6 +345,22 @@ class IndexedModules
@log.info "DB | (IdxedMods) #{ @setname }.getUserArgumentsFunctions( #{ userId }, #{ ruleId }, #{ mId } )"
@db.get "#{ @setname }:#{ userId }:#{ ruleId }:#{ mId }:functions", cb
+ getAllModuleUserArguments: ( userId, ruleId, mId, cb ) =>
+ @log.info "DB | (IdxedMods) #{ @setname }.getAllModuleUserArguments( #{ userId }, #{ ruleId }, #{ mId } )"
+ @db.smembers "#{ @setname }:#{ userId }:#{ ruleId }:#{ mId }:functions", ( err, obj ) =>
+ sem = obj.length
+ console.log 'getAllModuleUserArguments'
+ console.log obj
+ oAnswer = {}
+ for func in obj
+ fRegisterFunction = ( func ) =>
+ ( err, obj ) =>
+ if obj
+ oAnswer[ func ] = obj
+ if --sem is 0
+ cb null, oAnswer
+ @db.get "#{ @setname }:#{ userId }:#{ ruleId }:#{ mId }:function:#{ func }", fRegisterFunction func
+
getUserArguments: ( userId, ruleId, mId, funcId, cb ) =>
@log.info "DB | (IdxedMods) #{ @setname }.getUserArguments( #{ userId }, #{ ruleId }, #{ mId }, #{ funcId } )"
@db.get "#{ @setname }:#{ userId }:#{ ruleId }:#{ mId }:function:#{ funcId }", cb
diff --git a/coffee/webapi-eca.coffee b/coffee/webapi-eca.coffee
index 9f6a3f3..9adbf36 100644
--- a/coffee/webapi-eca.coffee
+++ b/coffee/webapi-eca.coffee
@@ -30,6 +30,9 @@ engine = require './engine'
# - [HTTP Listener](http-listener.html)
http = require './http-listener'
+# - [Encryption](encryption.html)
+encryption = require './encryption'
+
# - [Event Poller](event-poller.html) *(will be forked into a child process)*
nameEP = 'event-poller'
@@ -134,6 +137,8 @@ init = =>
#FIXME this has to come from user input for security reasons:
args[ 'keygen' ] = conf.getKeygenPassphrase()
args[ 'webhooks' ] = conf.fetchProp 'webhooks'
+
+ encryption args
@log.info 'RS | Initialzing DB'
db args
diff --git a/js/components-manager.js b/js/components-manager.js
index f4dc21c..544908e 100644
--- a/js/components-manager.js
+++ b/js/components-manager.js
@@ -10,12 +10,14 @@ Components Manager
*/
(function() {
- var commandFunctions, db, dynmod, eventEmitter, events, exports, forgeModule, fs, getModuleParams, getModules, hasRequiredParams, path;
+ var commandFunctions, db, dynmod, encryption, eventEmitter, events, exports, forgeModule, fs, getModuleParams, getModuleUserArguments, getModuleUserParams, getModules, hasRequiredParams, path, storeModule, storeRule;
db = require('./persistence');
dynmod = require('./dynamic-modules');
+ encryption = require('./encryption');
+
fs = require('fs');
path = require('path');
@@ -221,54 +223,140 @@ Components Manager
}
};
+ getModuleUserParams = function(user, oPayload, dbMod, callback) {
+ var answ;
+ answ = hasRequiredParams(['id'], oPayload);
+ if (answ.code !== 200) {
+ return callback(answ);
+ } else {
+ return dbMod.getUserParams(oPayload.id, user.username, function(err, str) {
+ var name, oParam, oParams;
+ oParams = JSON.parse(str);
+ for (name in oParams) {
+ oParam = oParams[name];
+ if (!oParam.shielded) {
+ oParam.value = encryption.decrypt(oParam.value);
+ }
+ }
+ answ.message = JSON.stringify(oParams);
+ return callback(answ);
+ });
+ }
+ };
+
+ getModuleUserArguments = function(user, oPayload, dbMod, callback) {
+ var answ;
+ answ = hasRequiredParams(['ruleId', 'moduleId'], oPayload);
+ if (answ.code !== 200) {
+ return callback(answ);
+ } else {
+ return dbMod.getAllModuleUserArguments(user.username, oPayload.ruleId, oPayload.moduleId, function(err, oPayload) {
+ answ.message = oPayload;
+ return callback(answ);
+ });
+ }
+ };
+
forgeModule = (function(_this) {
return function(user, oPayload, dbMod, callback) {
- var answ, i;
+ var answ;
answ = hasRequiredParams(['id', 'params', 'lang', 'data'], oPayload);
if (answ.code !== 200) {
return callback(answ);
} else {
- i = 0;
- return dbMod.getModule(oPayload.id, function(err, mod) {
- var src;
- if (mod) {
- answ.code = 409;
- answ.message = 'Module name already existing: ' + oPayload.id;
- return callback(answ);
- } else {
- src = oPayload.data;
- return dynmod.compileString(src, user.username, 'dummyRule', oPayload.id, oPayload.lang, null, function(cm) {
- var funcs, id, name, _ref;
- answ = cm.answ;
- if (answ.code === 200) {
- funcs = [];
- _ref = cm.module;
- for (name in _ref) {
- id = _ref[name];
- funcs.push(name);
- }
- _this.log.info("CM | Storing new module with functions " + (funcs.join(', ')));
- answ.message = " Module " + oPayload.id + " successfully stored! Found following function(s): " + funcs;
- oPayload.functions = JSON.stringify(funcs);
- oPayload.functionArgs = JSON.stringify(cm.funcParams);
- dbMod.storeModule(user.username, oPayload);
- if (oPayload["public"] === 'true') {
- dbMod.publish(oPayload.id);
- }
- }
+ if (oPayload.overwrite) {
+ return storeModule(user, oPayload, dbMod, callback);
+ } else {
+ return dbMod.getModule(oPayload.id, function(err, mod) {
+ if (mod) {
+ answ.code = 409;
+ answ.message = 'Module name already existing: ' + oPayload.id;
return callback(answ);
- });
- }
- });
+ } else {
+ return storeModule(user, oPayload, dbMod, callback);
+ }
+ });
+ }
}
};
})(this);
+ storeModule = (function(_this) {
+ return function(user, oPayload, dbMod, callback) {
+ var src;
+ src = oPayload.data;
+ return dynmod.compileString(src, user.username, 'dummyRule', oPayload.id, oPayload.lang, null, function(cm) {
+ var answ, funcs, id, name, _ref;
+ answ = cm.answ;
+ if (answ.code === 200) {
+ funcs = [];
+ _ref = cm.module;
+ for (name in _ref) {
+ id = _ref[name];
+ funcs.push(name);
+ }
+ _this.log.info("CM | Storing new module with functions " + (funcs.join(', ')));
+ answ.message = " Module " + oPayload.id + " successfully stored! Found following function(s): " + funcs;
+ oPayload.functions = JSON.stringify(funcs);
+ oPayload.functionArgs = JSON.stringify(cm.funcParams);
+ dbMod.storeModule(user.username, oPayload);
+ if (oPayload["public"] === 'true') {
+ dbMod.publish(oPayload.id);
+ }
+ }
+ return callback(answ);
+ });
+ };
+ })(this);
+
+ storeRule = (function(_this) {
+ return function(user, oPayload, callback) {
+ var arr, epModId, id, oParams, params, rule, strRule;
+ rule = {
+ id: oPayload.id,
+ event: oPayload.event,
+ event_interval: oPayload.event_interval,
+ conditions: oPayload.conditions,
+ actions: oPayload.actions
+ };
+ strRule = JSON.stringify(rule);
+ db.storeRule(rule.id, strRule);
+ db.linkRule(rule.id, user.username);
+ db.activateRule(rule.id, user.username);
+ if (oPayload.event_params) {
+ epModId = rule.event.split(' -> ')[0];
+ db.eventPollers.storeUserParams(epModId, user.username, JSON.stringify(oPayload.event_params));
+ }
+ oParams = oPayload.action_params;
+ for (id in oParams) {
+ params = oParams[id];
+ db.actionInvokers.storeUserParams(id, user.username, JSON.stringify(params));
+ }
+ oParams = oPayload.action_functions;
+ for (id in oParams) {
+ params = oParams[id];
+ arr = id.split(' -> ');
+ db.actionInvokers.storeUserArguments(user.username, rule.id, arr[0], arr[1], JSON.stringify(params));
+ }
+ db.resetLog(user.username, rule.id);
+ db.appendLog(user.username, rule.id, "INIT", "Rule '" + rule.id + "' initialized");
+ eventEmitter.emit('rule', {
+ event: 'new',
+ user: user.username,
+ rule: rule
+ });
+ return callback({
+ code: 200,
+ message: "Rule '" + rule.id + "' stored and activated!"
+ });
+ };
+ })(this);
+
commandFunctions = {
get_public_key: function(user, oPayload, callback) {
return callback({
code: 200,
- message: dynmod.getPublicKey()
+ message: encryption.getPublicKey()
});
},
get_event_pollers: function(user, oPayload, callback) {
@@ -285,6 +373,12 @@ Components Manager
get_event_poller_params: function(user, oPayload, callback) {
return getModuleParams(user, oPayload, db.eventPollers, callback);
},
+ get_event_poller_user_params: function(user, oPayload, callback) {
+ return getModuleUserParams(user, oPayload, db.eventPollers, callback);
+ },
+ get_event_poller_user_arguments: function(user, oPayload, callback) {
+ return getModuleUserArguments(user, oPayload, db.eventPollers, callback);
+ },
forge_event_poller: function(user, oPayload, callback) {
return forgeModule(user, oPayload, db.eventPollers, callback);
},
@@ -321,7 +415,13 @@ Components Manager
get_action_invoker_params: function(user, oPayload, callback) {
return getModuleParams(user, oPayload, db.actionInvokers, callback);
},
- get_action_invoker_function_params: function(user, oPayload, callback) {
+ get_action_invoker_user_params: function(user, oPayload, callback) {
+ return getModuleUserParams(user, oPayload, db.actionInvokers, callback);
+ },
+ get_action_invoker_user_arguments: function(user, oPayload, callback) {
+ return getModuleUserArguments(user, oPayload, db.actionInvokers, callback);
+ },
+ get_action_invoker_function_arguments: function(user, oPayload, callback) {
var answ;
answ = hasRequiredParams(['id'], oPayload);
if (answ.code !== 200) {
@@ -359,6 +459,20 @@ Components Manager
});
});
},
+ get_rule: function(user, oPayload, callback) {
+ var answ;
+ answ = hasRequiredParams(['id'], oPayload);
+ if (answ.code !== 200) {
+ return callback(answ);
+ } else {
+ return db.getRule(oPayload.id, function(err, obj) {
+ return callback({
+ code: 200,
+ message: obj
+ });
+ });
+ }
+ },
get_rule_log: function(user, oPayload, callback) {
var answ;
answ = hasRequiredParams(['id'], oPayload);
@@ -379,54 +493,21 @@ Components Manager
if (answ.code !== 200) {
return callback(answ);
} else {
- return db.getRule(oPayload.id, function(err, oExisting) {
- var arr, epModId, id, oParams, params, rule, strRule;
- if (oExisting !== null) {
- answ = {
- code: 409,
- message: 'Rule name already existing!'
+ if (oPayload.overwrite) {
+ return storeRule(user, oPayload, callback);
+ } else {
+ return db.getRule(oPayload.id, (function(_this) {
+ return function(err, mod) {
+ if (mod) {
+ answ.code = 409;
+ answ.message = 'Rule name already existing: ' + oPayload.id;
+ return callback(answ);
+ } else {
+ return storeRule(user, oPayload, callback);
+ }
};
- } else {
- rule = {
- id: oPayload.id,
- event: oPayload.event,
- event_interval: oPayload.event_interval,
- conditions: oPayload.conditions,
- actions: oPayload.actions
- };
- strRule = JSON.stringify(rule);
- db.storeRule(rule.id, strRule);
- db.linkRule(rule.id, user.username);
- db.activateRule(rule.id, user.username);
- if (oPayload.event_params) {
- epModId = rule.event.split(' -> ')[0];
- db.eventPollers.storeUserParams(epModId, user.username, oPayload.event_params);
- }
- oParams = oPayload.action_params;
- for (id in oParams) {
- params = oParams[id];
- db.actionInvokers.storeUserParams(id, user.username, JSON.stringify(params));
- }
- oParams = oPayload.action_functions;
- for (id in oParams) {
- params = oParams[id];
- arr = id.split(' -> ');
- db.actionInvokers.storeUserArguments(user.username, rule.id, arr[0], arr[1], JSON.stringify(params));
- }
- db.resetLog(user.username, rule.id);
- db.appendLog(user.username, rule.id, "INIT", "Rule '" + rule.id + "' initialized");
- eventEmitter.emit('rule', {
- event: 'new',
- user: user.username,
- rule: rule
- });
- answ = {
- code: 200,
- message: "Rule '" + rule.id + "' stored and activated!"
- };
- }
- return callback(answ);
- });
+ })(this));
+ }
}
},
delete_rule: function(user, oPayload, callback) {
diff --git a/js/dynamic-modules.js b/js/dynamic-modules.js
index 07c1c6d..264ec10 100644
--- a/js/dynamic-modules.js
+++ b/js/dynamic-modules.js
@@ -9,10 +9,12 @@ Dynamic Modules
*/
(function() {
- var cryptico, cryptoJS, cs, db, exports, fTryToLoadModule, getFunctionParamNames, importio, logFunction, needle, regexpComments, request, vm;
+ var cryptoJS, cs, db, encryption, exports, fTryToLoadModule, getFunctionParamNames, importio, logFunction, needle, regexpComments, request, vm;
db = require('./persistence');
+ encryption = require('./encryption');
+
vm = require('vm');
needle = require('needle');
@@ -21,8 +23,6 @@ Dynamic Modules
cs = require('coffee-script');
- cryptico = require('my-cryptico');
-
cryptoJS = require('crypto-js');
importio = require('import-io').client;
@@ -38,26 +38,12 @@ Dynamic Modules
exports = module.exports = (function(_this) {
return function(args) {
- var numBits, passPhrase;
_this.log = args.logger;
- if (!_this.strPublicKey && args['keygen']) {
- db(args);
- passPhrase = args['keygen'];
- numBits = 1024;
- _this.oPrivateRSAkey = cryptico.generateRSAKey(passPhrase, numBits);
- _this.strPublicKey = cryptico.publicKeyString(_this.oPrivateRSAkey);
- _this.log.info("DM | Public Key generated: " + _this.strPublicKey);
- }
+ db(args);
return module.exports;
};
})(this);
- exports.getPublicKey = (function(_this) {
- return function() {
- return _this.strPublicKey;
- };
- })(this);
-
logFunction = function(uId, rId, mId) {
return function(msg) {
return db.appendLog(uId, rId, mId, msg);
@@ -110,17 +96,21 @@ Dynamic Modules
_this.log.info("DM | Trying to fetch user specific module '" + modId + "' paramters for user '" + userId + "'");
if (dbMod) {
return dbMod.getUserParams(modId, userId, function(err, obj) {
- var oDecrypted;
+ var name, oParam, oParams, _ref;
try {
- oDecrypted = cryptico.decrypt(obj, _this.oPrivateRSAkey);
- obj = JSON.parse(oDecrypted.plaintext);
+ oParams = {};
+ _ref = JSON.parse(obj);
+ for (name in _ref) {
+ oParam = _ref[name];
+ oParams[name] = encryption.decrypt(oParam.value);
+ }
_this.log.info("DM | Loaded user defined params for " + userId + ", " + ruleId + ", " + modId);
} catch (_error) {
err = _error;
_this.log.warn("DM | Error during parsing of user defined params for " + userId + ", " + ruleId + ", " + modId);
_this.log.warn(err);
}
- return fTryToLoadModule(userId, ruleId, modId, src, dbMod, obj, cb);
+ return fTryToLoadModule(userId, ruleId, modId, src, dbMod, oParams, cb);
});
} else {
return fTryToLoadModule(userId, ruleId, modId, src, dbMod, null, cb);
@@ -174,11 +164,9 @@ Dynamic Modules
oFuncArgs = {};
for (func in oFuncParams) {
dbMod.getUserArguments(userId, ruleId, modId, func, function(err, obj) {
- var oDecrypted;
if (obj) {
try {
- oDecrypted = cryptico.decrypt(obj, _this.oPrivateRSAkey);
- oFuncArgs[func] = JSON.parse(oDecrypted.plaintext);
+ oFuncArgs[func] = JSON.parse(encryption.decrypt(obj));
return _this.log.info("DM | Found and attached user-specific arguments to " + userId + ", " + ruleId + ", " + modId);
} catch (_error) {
err = _error;
diff --git a/js/encryption.js b/js/encryption.js
new file mode 100644
index 0000000..f54e09f
--- /dev/null
+++ b/js/encryption.js
@@ -0,0 +1,47 @@
+// Generated by CoffeeScript 1.7.1
+
+/*
+
+Encryption
+===============
+> Handles RSA encryption and decryption of user specific parameters.
+ */
+
+(function() {
+ var cryptico, exports;
+
+ cryptico = require('my-cryptico');
+
+ exports = module.exports = (function(_this) {
+ return function(args) {
+ _this.log = args.logger;
+ _this.oPrivateRSAkey = cryptico.generateRSAKey(args['keygen'], 1024);
+ _this.strPublicKey = cryptico.publicKeyString(_this.oPrivateRSAkey);
+ _this.log.info("DM | Public Key generated: " + _this.strPublicKey);
+ return module.exports;
+ };
+ })(this);
+
+ exports.getPublicKey = (function(_this) {
+ return function() {
+ return _this.strPublicKey;
+ };
+ })(this);
+
+ exports.encrypt = (function(_this) {
+ return function(plainText) {
+ var oEncrypted;
+ oEncrypted = cryptico.encrypt(plainText, _this.strPublicKey);
+ return oEncrypted.cipher;
+ };
+ })(this);
+
+ exports.decrypt = (function(_this) {
+ return function(strEncrypted) {
+ var oDecrypted;
+ oDecrypted = cryptico.decrypt(strEncrypted, _this.oPrivateRSAkey);
+ return oDecrypted.plaintext;
+ };
+ })(this);
+
+}).call(this);
diff --git a/js/event-poller.js b/js/event-poller.js
index fe3ad19..eb36613 100644
--- a/js/event-poller.js
+++ b/js/event-poller.js
@@ -9,7 +9,7 @@ Dynamic Modules
*/
(function() {
- var db, dynmod, fCallFunction, fCheckAndRun, fLoadModule, isRunning, listUserModules, log, logconf, logger, pollLoop;
+ var db, dynmod, encryption, fCallFunction, fCheckAndRun, fLoadModule, isRunning, listUserModules, log, logconf, logger, pollLoop;
logger = require('./logging');
@@ -17,6 +17,8 @@ Dynamic Modules
dynmod = require('./dynamic-modules');
+ encryption = require('./encryption');
+
if (process.argv.length < 8) {
console.error('Not all arguments have been passed!');
process.exit();
@@ -42,6 +44,10 @@ Dynamic Modules
});
dynmod({
+ logger: log
+ });
+
+ encryption({
logger: log,
keygen: process.argv[7]
});
diff --git a/js/persistence.js b/js/persistence.js
index 4e69134..b618715 100644
--- a/js/persistence.js
+++ b/js/persistence.js
@@ -257,6 +257,7 @@ Persistence
this.log = log;
this.deleteUserArguments = __bind(this.deleteUserArguments, this);
this.getUserArguments = __bind(this.getUserArguments, this);
+ this.getAllModuleUserArguments = __bind(this.getAllModuleUserArguments, this);
this.getUserArgumentsFunctions = __bind(this.getUserArgumentsFunctions, this);
this.storeUserArguments = __bind(this.storeUserArguments, this);
this.deleteUserParams = __bind(this.deleteUserParams, this);
@@ -438,6 +439,35 @@ Persistence
return this.db.get("" + this.setname + ":" + userId + ":" + ruleId + ":" + mId + ":functions", cb);
};
+ IndexedModules.prototype.getAllModuleUserArguments = function(userId, ruleId, mId, cb) {
+ this.log.info("DB | (IdxedMods) " + this.setname + ".getAllModuleUserArguments( " + userId + ", " + ruleId + ", " + mId + " )");
+ return this.db.smembers("" + this.setname + ":" + userId + ":" + ruleId + ":" + mId + ":functions", (function(_this) {
+ return function(err, obj) {
+ var fRegisterFunction, func, oAnswer, sem, _i, _len, _results;
+ sem = obj.length;
+ console.log('getAllModuleUserArguments');
+ console.log(obj);
+ oAnswer = {};
+ _results = [];
+ for (_i = 0, _len = obj.length; _i < _len; _i++) {
+ func = obj[_i];
+ fRegisterFunction = function(func) {
+ return function(err, obj) {
+ if (obj) {
+ oAnswer[func] = obj;
+ }
+ if (--sem === 0) {
+ return cb(null, oAnswer);
+ }
+ };
+ };
+ _results.push(_this.db.get("" + _this.setname + ":" + userId + ":" + ruleId + ":" + mId + ":function:" + func, fRegisterFunction(func)));
+ }
+ return _results;
+ };
+ })(this));
+ };
+
IndexedModules.prototype.getUserArguments = function(userId, ruleId, mId, funcId, cb) {
this.log.info("DB | (IdxedMods) " + this.setname + ".getUserArguments( " + userId + ", " + ruleId + ", " + mId + ", " + funcId + " )");
return this.db.get("" + this.setname + ":" + userId + ":" + ruleId + ":" + mId + ":function:" + funcId, cb);
diff --git a/js/webapi-eca.js b/js/webapi-eca.js
index e02cb30..6e1bab2 100644
--- a/js/webapi-eca.js
+++ b/js/webapi-eca.js
@@ -13,7 +13,7 @@ WebAPI-ECA Engine
*/
(function() {
- var argv, cm, conf, cp, db, engine, fs, http, init, logconf, logger, nameEP, opt, optimist, path, procCmds, shutDown, usage;
+ var argv, cm, conf, cp, db, encryption, engine, fs, http, init, logconf, logger, nameEP, opt, optimist, path, procCmds, shutDown, usage;
logger = require('./logging');
@@ -27,6 +27,8 @@ WebAPI-ECA Engine
http = require('./http-listener');
+ encryption = require('./encryption');
+
nameEP = 'event-poller';
fs = require('fs');
@@ -147,6 +149,7 @@ WebAPI-ECA Engine
args['db-port'] = parseInt(argv.d || conf.getDbPort());
args['keygen'] = conf.getKeygenPassphrase();
args['webhooks'] = conf.fetchProp('webhooks');
+ encryption(args);
_this.log.info('RS | Initialzing DB');
db(args);
return db.isConnected(function(err) {
diff --git a/webpages/handlers/coffee/edit_modules.coffee b/webpages/handlers/coffee/edit_modules.coffee
index a79f8a6..7d4e84e 100644
--- a/webpages/handlers/coffee/edit_modules.coffee
+++ b/webpages/handlers/coffee/edit_modules.coffee
@@ -11,14 +11,16 @@ fOnLoad = () ->
if err.status is 401
window.location.href = 'forge?page=edit_modules'
else
- if err.responseText is ''
- msg = 'No Response from Server!'
- else
- try
- oErr = JSON.parse err.responseText
- msg = oErr.message
- $( '#info' ).text errMsg + msg
- $( '#info' ).attr 'class', 'error'
+ fDelayed = () ->
+ if err.responseText is ''
+ msg = 'No Response from Server!'
+ else
+ try
+ oErr = JSON.parse err.responseText
+ msg = oErr.message
+ $( '#info' ).text errMsg + msg
+ $( '#info' ).attr 'class', 'error'
+ setTimeout fDelayed, 500
fFetchModules = () ->
if $( '#module_type' ).val() is 'Event Poller'
@@ -56,9 +58,8 @@ fOnLoad = () ->
cmd = 'delete_action_invoker'
data =
command: cmd
- payload:
+ payload: JSON.stringify
id: modName
- data.payload = JSON.stringify data.payload
$.post( '/usercommand', data )
.done fFetchModules
.fail fErrHandler 'Could not delete module! '
@@ -66,8 +67,8 @@ fOnLoad = () ->
$( '#tableModules' ).on 'click', 'img.log', () ->
modName = encodeURIComponent $( 'div', $( this ).closest( 'tr' )).text()
if $( '#module_type' ).val() is 'Event Poller'
- window.location.href = 'forge?page=forge_event_poller&id=' + modName
+ window.location.href = 'forge?page=forge_module&type=event_poller&id=' + modName
else
- window.location.href = 'forge?page=forge_action_invoker&id=' + modName
+ window.location.href = 'forge?page=forge_module&type=action_invoker&id=' + modName
window.addEventListener 'load', fOnLoad, true
diff --git a/webpages/handlers/coffee/edit_rules.coffee b/webpages/handlers/coffee/edit_rules.coffee
index 1a23b9a..be67715 100644
--- a/webpages/handlers/coffee/edit_rules.coffee
+++ b/webpages/handlers/coffee/edit_rules.coffee
@@ -50,9 +50,8 @@ fOnLoad = () ->
$( '#log_col' ).text ""
data =
command: 'delete_rule'
- payload:
+ payload: JSON.stringify
id: ruleName
- data.payload = JSON.stringify data.payload
$.post( '/usercommand', data )
.done fFetchRules
.fail fErrHandler 'Could not delete rule! '
@@ -65,47 +64,12 @@ fOnLoad = () ->
ruleName = $( 'div', $( this ).closest( 'tr' )).text()
data =
command: 'get_rule_log'
- payload:
+ payload: JSON.stringify
id: ruleName
- data.payload = JSON.stringify data.payload
$.post( '/usercommand', data )
.done ( data ) ->
log = data.message.replace new RegExp("\n", 'g'), "
"
$( '#log_col' ).html "
#{ ruleName } Log:
#{ log }"
.fail fErrHandler 'Could not get rule log! '
- # Add parameter list functionality
- fChangeInputVisibility = () ->
- $( '#tableParams tr' ).each ( id ) ->
- if $( this ).is ':last-child' or $( this ).is ':only-child'
- $( 'img', this ).hide()
- $( 'input[type=checkbox]', this ).hide()
- else
- $( 'img', this ).show()
- $( 'input[type=checkbox]', this ).show()
-
- $( '#tableParams' ).on 'click', 'img', () ->
- par = $( this ).closest 'tr'
- if not par.is ':last-child'
- par.remove()
- fChangeInputVisibility()
-
- $( '#tableParams' ).on 'keyup', 'input', ( e ) ->
- code = e.keyCode or e.which
- if code isnt 9
- par = $( this ).closest 'tr'
- if par.is ':last-child'
- tr = $ ''
- img = $( '
' ).attr( 'title', 'Remove?').attr 'src', 'red_cross_small.png'
- cb = $( '' ).attr( 'type', 'checkbox' ).attr 'title', 'Password shielded input?'
- inp = $( '' ).attr( 'type', 'text' ).attr 'class', 'textinput'
- tr.append $( '' ).append img
- tr.append $( ' | ' ).append cb
- tr.append $( ' | ' ).append inp
- par.parent().append tr
- fChangeInputVisibility()
- else if $( this ).val() is '' and not par.is ':only-child'
- par.remove()
-
- fChangeInputVisibility()
window.addEventListener 'load', fOnLoad, true
diff --git a/webpages/handlers/coffee/forge_action_invoker.coffee b/webpages/handlers/coffee/forge_action_invoker.coffee
deleted file mode 100644
index 24600da..0000000
--- a/webpages/handlers/coffee/forge_action_invoker.coffee
+++ /dev/null
@@ -1,110 +0,0 @@
-
-fOnLoad = () ->
- document.title = 'Forge Action Invoker'
- $( '#pagetitle' ).text "{{{user.username}}}, forge your custom action invoker!"
-
- # Setup the ACE editor
- editor = ace.edit "editor"
- editor.setTheme "ace/theme/monokai"
- editor.getSession().setMode "ace/mode/coffee"
- editor.setShowPrintMargin false
- editor.session.setUseSoftTabs false
-
- $( '#editor_mode' ).change ( el ) ->
- if $( this ).val() is 'CoffeeScript'
- editor.getSession().setMode "ace/mode/coffee"
- else
- editor.getSession().setMode "ace/mode/javascript"
-
- # Add parameter list functionality
- fChangeInputVisibility = () ->
- $( '#tableParams tr' ).each ( id ) ->
- if $( this ).is ':last-child' or $( this ).is ':only-child'
- $( 'img', this ).hide()
- $( 'input[type=checkbox]', this ).hide()
- else
- $( 'img', this ).show()
- $( 'input[type=checkbox]', this ).show()
-
- $( '#tableParams' ).on 'click', 'img', () ->
- par = $( this ).closest 'tr'
- if not par.is ':last-child'
- par.remove()
- fChangeInputVisibility()
-
- $( '#tableParams' ).on 'keyup', 'input', ( e ) ->
- code = e.keyCode or e.which
- if code isnt 9
- par = $( this ).closest( 'tr' )
- if par.is ':last-child'
- tr = $ ' |
'
- img = $( '
' ).attr( 'title', 'Remove?').attr 'src', 'red_cross_small.png'
- cb = $( '' ).attr( 'type', 'checkbox' ).attr 'title', 'Password shielded input?'
- inp = $( '' ).attr( 'type', 'text' ).attr 'class', 'textinput'
- tr.append( $( '' ).append img )
- tr.append( $( ' | ' ).append cb )
- tr.append( $( ' | ' ).append inp )
- par.parent().append tr
- fChangeInputVisibility()
- else if $( this ).val() is '' and not par.is ':only-child'
- par.remove()
-
- fChangeInputVisibility()
-
- # Add submit button logic
- $( '#but_submit' ).click () ->
- if $( '#input_id' ).val() is ''
- alert 'Please enter an action invoker name!'
- else
- listParams = {}
- $( '#tableParams tr' ).each () ->
- val = $( 'input.textinput', this ).val()
- shld = $( 'input[type=checkbox]', this ).is ':checked'
- if val isnt ""
- listParams[val] = shld
- true
- obj =
- command: 'forge_action_invoker'
- payload:
- id: $( '#input_id' ).val()
- lang: $( '#editor_mode' ).val()
- public: $( '#is_public' ).is ':checked'
- data: editor.getValue()
- params: JSON.stringify listParams
- obj.payload = JSON.stringify obj.payload
- window.scrollTo 0, 0
- $.post( '/usercommand', obj )
- .done ( data ) ->
- $( '#info' ).text data.message
- $( '#info' ).attr 'class', 'success'
- .fail ( err ) ->
- if err.status is 401
- window.location.href = 'forge?page=forge_action_invoker'
- else
- fDelayed = () ->
- if err.responseText is ''
- msg = 'No Response from Server!'
- else
- try
- oErr = JSON.parse err.responseText
- msg = oErr.message
- $( '#info' ).text 'Action Invoker not stored! ' + msg
- $( '#info' ).attr 'class', 'error'
- setTimeout fDelayed, 500
-
-
- # EDIT MODULES
-
- arrParams = window.location.search.substring(1).split '&'
- id = ''
- for param in arrParams
- arrKV = param.split '='
- if arrKV[ 0 ] is 'id'
- id = decodeURIComponent arrKV[ 1 ]
- if id isnt ''
- # TODO we have an idea so we want to edit this module!
- console.log id
-
-
-
-window.addEventListener 'load', fOnLoad, true
diff --git a/webpages/handlers/coffee/forge_event_poller.coffee b/webpages/handlers/coffee/forge_event_poller.coffee
deleted file mode 100644
index 9827841..0000000
--- a/webpages/handlers/coffee/forge_event_poller.coffee
+++ /dev/null
@@ -1,95 +0,0 @@
-
-fOnLoad = () ->
- document.title = 'Forge Event Poller'
- $( '#pagetitle' ).text "{{{user.username}}}, forge your custom event poller!"
-
- # Setup the ACE editor
- editor = ace.edit "editor"
- editor.setTheme "ace/theme/monokai"
- editor.getSession().setMode "ace/mode/coffee"
- editor.setShowPrintMargin false
-
- $( '#editor_mode' ).change ( el ) ->
- if $( this ).val() is 'CoffeeScript'
- editor.getSession().setMode "ace/mode/coffee"
- else
- editor.getSession().setMode "ace/mode/javascript"
-
- # Add parameter list functionality
- fChangeInputVisibility = () ->
- $( '#tableParams tr' ).each ( id ) ->
- if $( this ).is ':last-child' or $( this ).is ':only-child'
- $( 'img', this ).hide()
- $( 'input[type=checkbox]', this ).hide()
- else
- $( 'img', this ).show()
- $( 'input[type=checkbox]', this ).show()
-
- $( '#tableParams' ).on 'click', 'img', () ->
- par = $( this ).closest 'tr'
- if not par.is ':last-child'
- par.remove()
- fChangeInputVisibility()
-
- $( '#tableParams' ).on 'keyup', 'input', ( e ) ->
- code = e.keyCode or e.which
- if code isnt 9
- par = $( this ).closest( 'tr' )
- if par.is ':last-child'
- tr = $ ' |
'
- img = $( '
' ).attr( 'title', 'Remove?').attr 'src', 'red_cross_small.png'
- cb = $( '' ).attr( 'type', 'checkbox' ).attr 'title', 'Password shielded input?'
- inp = $( '' ).attr( 'type', 'text' ).attr 'class', 'textinput'
- tr.append( $( '' ).append img )
- tr.append( $( ' | ' ).append cb )
- tr.append( $( ' | ' ).append inp )
- tr.append $( ' | ' )
- par.parent().append tr
- fChangeInputVisibility()
- else if $( this ).val() is '' and not par.is ':only-child'
- par.remove()
-
- fChangeInputVisibility()
-
- # Add submit button logic
- $( '#but_submit' ).click () ->
- if $( '#input_id' ).val() is ''
- alert 'Please enter an event poller name!'
- else
- listParams = {}
- $( '#tableParams tr' ).each () ->
- val = $( 'input.textinput', this ).val()
- shld = $( 'input[type=checkbox]', this ).is ':checked'
- if val isnt ""
- listParams[val] = shld
- true
- obj =
- command: 'forge_event_poller'
- payload:
- id: $( '#input_id' ).val()
- lang: $( '#editor_mode' ).val()
- public: $( '#is_public' ).is ':checked'
- data: editor.getValue()
- params: JSON.stringify listParams
- obj.payload = JSON.stringify obj.payload
- window.scrollTo 0, 0
- $.post( '/usercommand', obj )
- .done ( data ) ->
- $( '#info' ).text data.message
- $( '#info' ).attr 'class', 'success'
- .fail ( err ) ->
- if err.status is 401
- window.location.href = 'forge?page=forge_event_poller'
- else
- fDelayed = () ->
- if err.responseText is ''
- msg = 'No Response from Server!'
- else
- try
- oErr = JSON.parse err.responseText
- msg = oErr.message
- $( '#info' ).text 'Event Poller not stored! ' + msg
- $( '#info' ).attr 'class', 'error'
- setTimeout fDelayed, 500
-
-window.addEventListener 'load', fOnLoad, true
diff --git a/webpages/handlers/coffee/forge_module.coffee b/webpages/handlers/coffee/forge_module.coffee
new file mode 100644
index 0000000..2e91576
--- /dev/null
+++ b/webpages/handlers/coffee/forge_module.coffee
@@ -0,0 +1,175 @@
+# Fetch the search string and transform it into an object for easy access
+arrParams = window.location.search.substring(1).split '&'
+oParams = {}
+for param in arrParams
+ arrKV = param.split '='
+ oParams[ arrKV[ 0 ] ] = arrKV[ 1 ]
+
+if oParams.type is 'event_poller'
+ moduleName = 'Event Poller'
+else
+ moduleName = 'Action Invoker'
+ oParams.type = 'action_invoker'
+if oParams.id
+ oParams.id = decodeURIComponent oParams.id
+
+fErrHandler = ( errMsg ) ->
+ ( err ) ->
+ if err.status is 401
+ window.location.href = "forge?page=forge_module?type=#{ oParams.type }"
+ else
+ $( '#log_col' ).text ""
+ fDelayed = () ->
+ if err.responseText is ''
+ msg = 'No Response from Server!'
+ else
+ try
+ oErr = JSON.parse err.responseText
+ msg = oErr.message
+ $( '#info' ).text errMsg + msg
+ $( '#info' ).attr 'class', 'error'
+ setTimeout fDelayed, 500
+
+fOnLoad = () ->
+ document.title = "Forge #{ moduleName }"
+ $( '#pagetitle' ).text "{{{user.username}}}, forge your custom #{ moduleName }!"
+
+ # Setup the ACE editor
+ editor = ace.edit "editor"
+ editor.setTheme "ace/theme/monokai"
+ editor.getSession().setMode "ace/mode/coffee"
+ editor.setShowPrintMargin false
+ editor.session.setUseSoftTabs false
+
+ $( '#editor_mode' ).change ( el ) ->
+ if $( this ).val() is 'CoffeeScript'
+ editor.getSession().setMode "ace/mode/coffee"
+ else
+ editor.getSession().setMode "ace/mode/javascript"
+
+ # Add parameter list functionality
+ fChangeInputVisibility = () ->
+ $( '#tableParams tr' ).each ( id ) ->
+ if $( this ).is ':last-child' or $( this ).is ':only-child'
+ $( 'img', this ).hide()
+ $( 'input[type=checkbox]', this ).hide()
+ else
+ $( 'img', this ).show()
+ $( 'input[type=checkbox]', this ).show()
+
+ fAddInputRow = ( tag ) ->
+ tr = $ ' |
'
+ img = $( '
' ).attr( 'title', 'Remove?').attr 'src', 'red_cross_small.png'
+ cb = $( '' ).attr( 'type', 'checkbox' ).attr 'title', 'Password shielded input?'
+ inp = $( '' ).attr( 'type', 'text' ).attr 'class', 'textinput'
+ tr.append( $( '' ).append img )
+ tr.append( $( ' | ' ).append cb )
+ tr.append( $( ' | ' ).append inp )
+ tag.append tr
+ fChangeInputVisibility()
+ tr
+
+ $( '#tableParams' ).on 'click', 'img', () ->
+ par = $( this ).closest 'tr'
+ if not par.is ':last-child'
+ par.remove()
+ fChangeInputVisibility()
+
+ $( '#tableParams' ).on 'keyup', 'input', ( e ) ->
+ code = e.keyCode or e.which
+ if code isnt 9
+ par = $( this ).closest( 'tr' )
+ if par.is ':last-child'
+ fAddInputRow par.parent()
+ else if $( this ).val() is '' and not par.is ':only-child'
+ par.remove()
+
+ fChangeInputVisibility()
+
+ # Add submit button logic
+ $( '#but_submit' ).click () ->
+ if $( '#input_id' ).val() is ''
+ alert "Please enter an #{ moduleName } name!"
+ else
+ listParams = {}
+ $( '#tableParams tr' ).each () ->
+ val = $( 'input.textinput', this ).val()
+ shld = $( 'input[type=checkbox]', this ).is ':checked'
+ if val isnt ""
+ listParams[val] = shld
+ true
+ obj =
+ command: "forge_#{ oParams.type }"
+ payload: JSON.stringify
+ id: $( '#input_id' ).val()
+ lang: $( '#editor_mode' ).val()
+ public: $( '#is_public' ).is ':checked'
+ data: editor.getValue()
+ params: JSON.stringify listParams
+ fCheckOverwrite = ( obj ) ->
+ ( err ) ->
+ if err.status is 409
+ if confirm 'Are you sure you want to overwrite the existing module?'
+ payl = JSON.parse obj.payload
+ payl.overwrite = true
+ obj.payload = JSON.stringify payl
+ $.post( '/usercommand', obj )
+ .done ( data ) ->
+ $( '#info' ).text data.message
+ $( '#info' ).attr 'class', 'success'
+ alert "You need to update the rules that use this module in
+ order for the changes to be applied to them!"
+ .fail fErrHandler "#{ moduleName } not stored!"
+ else
+ fErrHandler( "#{ moduleName } not stored!" ) err
+ window.scrollTo 0, 0
+ $.post( '/usercommand', obj )
+ .done ( data ) ->
+ $( '#info' ).text data.message
+ $( '#info' ).attr 'class', 'success'
+ .fail fCheckOverwrite obj
+
+ # EDIT MODULES
+
+ fAddUserParam = ( param, shielded ) ->
+ tr = fAddInputRow $( '#tableParams' )
+ $( 'input.textinput', tr ).val param
+ if shielded
+ $( 'input[type=checkbox]', tr ).prop 'checked', true
+
+ if oParams.id
+ obj =
+ command: "get_full_#{ oParams.type }"
+ payload: JSON.stringify
+ id: oParams.id
+
+ $.post( '/usercommand', obj )
+ .done ( data ) ->
+ oMod = JSON.parse data.message
+ if oMod
+ fAddUserParam param, shielded for param, shielded of JSON.parse oMod.params
+ $( '#input_id' ).val oMod.id
+ $( '#editor_mode' ).val oMod.lang
+ if oMod.public is 'true'
+ $( '#is_public' ).prop 'checked', true
+ editor.setValue oMod.data
+ editor.moveCursorTo 0, 0
+ fAddUserParam '', false
+
+ .fail fErrHandler "Could not get module #{ oParams.id }!"
+
+ else
+ # We add the standard template, params and names
+ editor.setValue $( "#template_#{ oParams.type }" ).text()
+ editor.moveCursorTo 0, 0
+ if oParams.type is 'event_poller'
+ $( '#input_id' ).val 'EmailYak'
+ fAddUserParam 'apikey', true
+ fAddUserParam '', false
+ else
+ $( '#input_id' ).val 'ProBinder'
+ fAddUserParam 'username', false
+ fAddUserParam 'password', true
+ fAddUserParam '', false
+
+window.addEventListener 'load', fOnLoad, true
diff --git a/webpages/handlers/coffee/forge_rule.coffee b/webpages/handlers/coffee/forge_rule.coffee
index 39a45dc..2d6a1bf 100644
--- a/webpages/handlers/coffee/forge_rule.coffee
+++ b/webpages/handlers/coffee/forge_rule.coffee
@@ -1,5 +1,14 @@
-strPublicKey = ''
+# Fetch the search string and transform it into an object for easy access
+arrParams = window.location.search.substring(1).split '&'
+oParams = {}
+for param in arrParams
+ arrKV = param.split '='
+ oParams[ arrKV[ 0 ] ] = arrKV[ 1 ]
+if oParams.id
+ oParams.id = decodeURIComponent oParams.id
+
+strPublicKey = ''
fPlaceAndPaintInterval = () ->
$( '#input_interval' ).html 'Interval:
@@ -40,9 +49,8 @@ fOnLoad = () ->
arr = name.split ' -> '
obj =
command: 'get_event_poller_params'
- payload:
- id: arr[0]
- obj.payload = JSON.stringify( obj.payload );
+ payload: JSON.stringify
+ id: arr[ 0 ]
$.post( '/usercommand', obj )
.done ( data ) ->
if data.message
@@ -54,7 +62,7 @@ fOnLoad = () ->
tr = $( ' |
' )
tr.append $( '| ' ).css 'width', '20px'
tr.append $( ' | ' ).attr( 'class', 'key' ).text name
- inp = $( '' ).attr 'id', "#{ name }"
+ inp = $( '' )
if shielded
inp.attr( 'type', 'password' )
tr.append $( ' | ' ).text( ' : ' ).append inp
@@ -97,6 +105,7 @@ fOnLoad = () ->
else
fPlaceAndPaintInterval()
+
# Init Action Invoker
obj =
command: 'get_action_invokers'
@@ -110,16 +119,16 @@ fOnLoad = () ->
return
fAppendActions = ( module, actions ) ->
for act in actions
- $( '#select_actions' ).append $( ' |