@sammachin/node-red-dragonpbx
Version:
A Node-RED node to append JSON objects to an array in msg.callScript
91 lines (81 loc) • 3.28 kB
JavaScript
var {createHash} = require('crypto');
var {new_resolve} = require('./libs');
/** user auth */
module.exports = function(RED) {
function auth(config) {
RED.nodes.createNode(this, config);
var node = this;
node.on('input', async function(msg) {
var attemptedAuthentication = false;
var auth = msg.payload;
var authResponse = {};
var ha1_string;
if (config.ha1 && config.ha1.length) {
ha1_string = await new_resolve(RED, config.ha1, config.ha1Type, node, msg),
attemptedAuthentication = true;
}
else if (config.password && config.password.length) {
var password = await new_resolve(RED, config.password, config.passwordType, node, msg);
var ha1 = createHash('md5');
ha1.update([auth.username, auth.realm, password].join(':'));
ha1_string = ha1.digest('hex');
attemptedAuthentication = true;
}
else {
node.error('user auth: failing due to no password provided');
}
if (attemptedAuthentication) {
var ha2 = createHash('md5');
ha2.update([auth.method, auth.uri].join(':'));
var response = createHash('md5');
var responseParams = [
ha1_string,
auth.nonce
];
if (auth.cnonce) {
responseParams.push(auth.nc);
responseParams.push(auth.cnonce);
}
if (auth.qop) {
responseParams.push(auth.qop);
}
responseParams.push(ha2.digest('hex'));
response.update(responseParams.join(':'));
var calculated = response.digest('hex');
if (calculated === auth.response) {
let grantedExpires = auth.expires;
if (config.expires && config.expires.length) {
const expires = await new_resolve(RED, config.expires, config.expiresType, node, msg);
if (auth.expires && expires != null) {
grantedExpires = Math.min(auth.expires, expires);
}
}
let codecs = await new_resolve(RED, config.codecs, config.codecsType, node, msg);
if (codecs && !Array.isArray(codecs)) {
codecs = codecs.replace(/\s/g, "").split(",");
}
let dialplan = await new_resolve(RED, config.dialplan, config.dialplanType, node, msg);
if (dialplan && typeof(dialplan) != 'Object'){
dialplan = JSON.parse(dialplan);
}
Object.assign(authResponse, {
status: 'ok',
expires: grantedExpires != null ? grantedExpires : null,
codecs: codecs || null,
dialplan: dialplan
});
Object.keys(authResponse).forEach((k) => authResponse[k] == null && delete authResponse[k]);
}
else {
Object.assign(authResponse, {status: 'fail', msg: 'incorrect password'});
}
}
else {
Object.assign(authResponse, {status: 'fail', msg: 'invalid domain or username'});
}
msg.payload = authResponse;
node.send(msg);
});
}
RED.nodes.registerType('dragonpbx_auth', auth);
}