New Case Study:See how Anthropic automated 95% of dependency reviews with Socket.Learn More
Socket
Sign inDemoInstall
Socket

dynamicscrm-api

Package Overview
Dependencies
Maintainers
2
Versions
15
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

dynamicscrm-api - npm Package Compare versions

Comparing version 0.1.0 to 0.1.1

545

lib/util.js
/*jslint nomen: true, stupid: true */
// module dependencies
var xpath = require('xpath');
var xpath = require("xpath");
var Cache = require("mem-cache");
var uuid = require("node-uuid");
var domParser = new (require('xmldom').DOMParser)();
var domParser = new (require("xmldom").DOMParser)();
var fs = require("fs");
var parseString = require('xml2js').parseString;
var traverse = require('traverse');
var Serializer = require('./serializer.js');
var WSTrustFlow = require('../lib/ws-security/wsTrustFlow.js');
var parseString = require("xml2js").parseString;
var traverse = require("traverse");
var Serializer = require("./serializer.js");
var WSTrustFlow = require("../lib/ws-security/wsTrustFlow.js");
var constants = require("constants");
var cookie = require("cookie");
var httpntlm = require("httpntlm");
var ntlm = require("httpntlm/ntlm.js");
var Agentkeepalive = require("agentkeepalive");
var request = require("request");
var kidoConnector = require("kido-connector");
var cookie = require('cookie');
var httpntlm = require('httpntlm');
var ntlm = require('httpntlm/ntlm.js');
var Agentkeepalive = require('agentkeepalive');
var request = require('request');
// this class implements all features
// this class implements all features
var Util = function (settings) {

@@ -28,16 +28,16 @@ "use strict";

// Arguments validation
if (!settings || typeof settings !== "object") { throw new Error("'settings' argument must be an object instance."); }
if (!settings.domain || typeof settings.domain !== "string") { throw new Error("'settings.domain' property is a required string."); }
if (settings.domainUrlSuffix && typeof settings.domainUrlSuffix !== "string") { throw new Error("'settings.domainUrlSuffix' must be string."); }
if (settings.timeout && typeof settings.timeout !== "number") { throw new Error("'settings.timeout' property must be a number."); }
if (settings.username && typeof settings.username !== "string") { throw new Error("'settings.username' property must be a string."); }
if (settings.password && typeof settings.password !== "string") { throw new Error("'settings.password' property must be a string."); }
if (settings.port && typeof settings.port !== "number") { throw new Error("'settings.port' property must be a number."); }
if (settings.organizationName && typeof settings.organizationName !== "string") { throw new Error("'settings.organizationName' property must be a string."); }
if (!settings || typeof settings !== "object") throw new Error("'settings' argument must be an object instance.");
if (!settings.domain || typeof settings.domain !== "string") throw new Error("'settings.domain' property is a required string.");
if (settings.domainUrlSuffix && typeof settings.domainUrlSuffix !== "string") throw new Error("'settings.domainUrlSuffix' must be string.");
if (settings.timeout && typeof settings.timeout !== "number") throw new Error("'settings.timeout' property must be a number.");
if (settings.username && typeof settings.username !== "string") throw new Error("'settings.username' property must be a string.");
if (settings.password && typeof settings.password !== "string") throw new Error("'settings.password' property must be a string.");
if (settings.port && typeof settings.port !== "number") throw new Error("'settings.port' property must be a number.");
if (settings.organizationName && typeof settings.organizationName !== "string") throw new Error("'settings.organizationName' property must be a string.");
//Set default value if authentication type is wrong or invalid
if (!settings.authType || typeof settings.authType !== "string" || authenticationTypes.indexOf(settings.authType) === -1) { settings.authType = "live_id"; }
if (!settings.authType || typeof settings.authType !== "string" || authenticationTypes.indexOf(settings.authType) === -1) settings.authType = "live_id";
// Sets default arguments values
settings.timeout = settings.timeout || 15 * 60 * 1000; // default sessions timeout of 15 minutes in ms
settings.timeout = settings.timeout || 15 * 60 * 1000; // default sessions timeout of 15 minutes in ms
settings.returnJson = true;

@@ -49,5 +49,4 @@ settings.port = settings.port || (settings.useHttp ? 80 : 443);

getHostname = function () {
if (settings.domainUrlSuffix) {
return settings.domain + settings.domainUrlSuffix;
}
if (settings.domainUrlSuffix) return settings.domain + settings.domainUrlSuffix;
return settings.domain + defaultUrlSuffix;

@@ -58,3 +57,3 @@ },

organizationPath = "/XRMServices/2011/Organization.svc",
organizationServiceEndpoint = 'https://' + hostname + organizationPath,
organizationServiceEndpoint = "https://" + hostname + organizationPath,
userAgent = "Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/38.0.2125.111 Safari/537.36",

@@ -111,3 +110,3 @@ SOAPActionBase = "http://schemas.microsoft.com/xrm/2011/Contracts/Services/IOrganizationService/",

defaultCb = function (err) {
if (err) { throw err; }
if (err) throw err;
};

@@ -118,3 +117,3 @@

reqOptions.secureOptions = constants.SSL_OP_NO_TLSv1_2;
reqOptions.ciphers = 'ECDHE-RSA-AES256-SHA:AES256-SHA:RC4-SHA:RC4:HIGH:!MD5:!aNULL:!EDH:!AESGCM';
reqOptions.ciphers = "ECDHE-RSA-AES256-SHA:AES256-SHA:RC4-SHA:RC4:HIGH:!MD5:!aNULL:!EDH:!AESGCM";
reqOptions.honorCipherOrder = true;

@@ -125,5 +124,3 @@ }

fetchEndpoints = function (cb) {
if (endpoints) {
return cb(null, endpoints);
}
if (endpoints) return cb(null, endpoints);

@@ -137,3 +134,3 @@ var options = {

request(options, function (err, res, body) {
if (err) { return cb(err); }
if (err) return cb(err);

@@ -145,3 +142,3 @@ var resXml = domParser.parseFromString(body),

if (fault.length > 0) { return cb(new Error(fault.toString()), null); }
if (fault.length > 0) return cb(new Error(fault.toString()), null);

@@ -159,3 +156,3 @@ location = xpath.select(importLocationXpath, resXml)

request(opts, function (err, res, body) {
if (err) { return cb(err); }
if (err) return cb(err);

@@ -174,3 +171,3 @@ var resXmlImport,

faultImport = xpath.select(faultTextXpath, resXmlImport);
if (faultImport.length > 0) { return cb(new Error(faultImport.toString()), null); }
if (faultImport.length > 0) return cb(new Error(faultImport.toString()), null);

@@ -202,8 +199,6 @@ authenticationType = xpath.select(authenticationTypeXpath, resXmlImport).toString();

loadOrRegisterDevice = function (options, cb) {
if (device) {
return cb(null, device);
}
if (device) return cb(null, device);
var username = generateRandom(24, 'aA#'),
password = generateRandom(24, 'aA#');
var username = generateRandom(24, "aA#"),
password = generateRandom(24, "aA#");

@@ -216,8 +211,8 @@ authCreateDeviceMessage = authCreateDeviceMessage

options = {
method: 'POST',
method: "POST",
uri: options.DeviceAddUrl,
body: authCreateDeviceMessage,
headers: {
'Content-Type': 'application/soap+xml; charset=UTF-8',
'Content-Length': authCreateDeviceMessage.length
"Content-Type": "application/soap+xml; charset=UTF-8",
"Content-Length": authCreateDeviceMessage.length
}

@@ -229,3 +224,3 @@ };

request(options, function (err, res, body) {
if (err) { return cb(err); }
if (err) return cb(err);

@@ -236,3 +231,3 @@ var resXml = domParser.parseFromString(body),

if (fault.length > 0) { return cb(new Error(fault.toString()), null); }
if (fault.length > 0) return cb(new Error(fault.toString()), null);

@@ -242,5 +237,5 @@ puid = xpath.select("/DeviceAddResponse/puid/text()", resXml).toString();

device = {
deviceUsername : username,
devicePassword : password,
puid : puid
deviceUsername: username,
devicePassword: password,
puid: puid
};

@@ -258,5 +253,3 @@

if (cipher) {
return cb(null, cipher);
}
if (cipher) return cb(null, cipher);

@@ -273,8 +266,8 @@ authRequestDeviceTokenMessage = authRequestDeviceTokenMessage

requestOptions = {
method: 'POST',
method: "POST",
uri: options.IssuerAddress,
body: authRequestDeviceTokenMessage,
headers: {
'Content-Type': 'application/soap+xml; charset=UTF-8',
'Content-Length': Buffer.byteLength(authRequestDeviceTokenMessage)
"Content-Type": "application/soap+xml; charset=UTF-8",
"Content-Length": Buffer.byteLength(authRequestDeviceTokenMessage)
}

@@ -286,3 +279,3 @@ };

request(requestOptions, function (err, res, body) {
if (err) { return cb(err); }
if (err) return cb(err);

@@ -293,6 +286,6 @@ var resXml = domParser.parseFromString(body),

if (fault.length > 0) { return cb(new Error(fault.toString()), null); }
if (fault.length > 0) return cb(new Error(fault.toString()), null);
cipherValue = xpath.select("//*[local-name()='RequestedSecurityToken' and namespace-uri()='http://schemas.xmlsoap.org/ws/2005/02/trust']/*[name()='EncryptedData']/*[name()='CipherData']/*[name()='CipherValue']/text()", resXml).toString();
cipher = {CipherValue : cipherValue};
cipher = {CipherValue: cipherValue};

@@ -306,14 +299,13 @@ tokensForDeviceCache.set("auth_tokenrequest_device", cipher);

generateRandom = function (length, chars) {
var mask = '',
result = '',
var mask = "",
result = "",
i;
if (chars.indexOf('a') > -1) { mask += 'abcdefghijklmnopqrstuvwxyz'; }
if (chars.indexOf('A') > -1) { mask += 'ABCDEFGHIJKLMNOPQRSTUVWXYZ'; }
if (chars.indexOf('#') > -1) { mask += '0123456789'; }
if (chars.indexOf('!') > -1) { mask += '~`!@#$%^&*()_+-={}[]:";\'<>?,./|\\'; }
if (chars.indexOf("a") > -1) mask += "abcdefghijklmnopqrstuvwxyz";
if (chars.indexOf("A") > -1) mask += "ABCDEFGHIJKLMNOPQRSTUVWXYZ";
if (chars.indexOf("#") > -1) mask += "0123456789";
if (chars.indexOf("!") > -1) mask += "~`!@#$%^&*()_+-={}[]:\";'<>?,./|\\";
for (i = length; i > 0; i = i - 1) {
for (i = length; i > 0; i = i - 1)
result += mask[Math.round(Math.random() * (mask.length - 1))];
}

@@ -326,5 +318,3 @@ return result;

prefixes.forEach(function (p) {
if (objInd.indexOf(p) === 0) {
rk = objInd.replace(p, '');
}
if (objInd.indexOf(p) === 0) rk = objInd.replace(p, "");
});

@@ -341,7 +331,7 @@ return rk;

if (fault.length > 0) { return cb(new Error(fault.toString())); }
if (fault.length > 0) return cb(new Error(fault.toString()));
if (settings.returnJson) {
if (settings.returnJson)
parseString(body, {explicitArray: false}, function (err, jsondata) {
if (err) { return cb(err); }
if (err) return cb(err);

@@ -352,9 +342,8 @@ prefixes = [];

if (this.key !== undefined) {
var pos = this.key.indexOf('xmlns:'),
k = this.key.substring(6, this.key.length) + ':';
var pos = this.key.indexOf("xmlns:"),
k = this.key.substring(6, this.key.length) + ":";
if (pos > -1 || this.key.indexOf('xmlns') > -1) {
if (prefixes.lastIndexOf(k) === -1) {
prefixes.push(k);
}
if (pos > -1 || this.key.indexOf("xmlns") > -1) {
if (prefixes.lastIndexOf(k) === -1) prefixes.push(k);
this.remove();

@@ -368,79 +357,60 @@ }

});
} else {
cb(null, data);
}
else cb(null, data);
};
executeSoapPost = function (options, action, template, body, cb) {
var timeCreated = new Date(),
timeExpires = new Date(timeCreated.getTime() + 5 * 60000),
requestOptions,
soapHeader,
xmlrequestbody,
soapPostMessage,
security,
ntlmOptions,
type1msg,
agent,
reqOptions,
url,
httpHeaders = {};
kidoConnector.isHostAllowed(hostname, function (err, allowed) {
if (err) return cb(err);
if (!allowed) return cb(new Error("The hostname is not allowed"));
xmlrequestbody = template.replace("{requetbody}", body);
var timeCreated = new Date(),
timeExpires = new Date(timeCreated.getTime() + 5 * 60000),
requestOptions,
soapHeader,
xmlrequestbody,
soapPostMessage,
security,
ntlmOptions,
type1msg,
agent,
reqOptions,
url,
httpHeaders = {};
if (settings.authType === "ntlm") {
soapPostMessage = soapEnvelopeMessage
.replace("{envelopeNS}", "http://schemas.xmlsoap.org/soap/envelope/")
.replace("{header}", "")
.replace("{body}", xmlrequestbody);
xmlrequestbody = template.replace("{requetbody}", body);
url = (settings.useHttp ? "http://" : "https://") + hostname + ":" + settings.port + "/" + settings.organizationName + organizationPath + "/web";
if (settings.authType === "ntlm") {
soapPostMessage = soapEnvelopeMessage
.replace("{envelopeNS}", "http://schemas.xmlsoap.org/soap/envelope/")
.replace("{header}", "")
.replace("{body}", xmlrequestbody);
httpHeaders.cookie = "ReqClientId=" + options.ReqClientId;
httpHeaders.SOAPAction = SOAPActionBase + action;
httpHeaders['Content-Length'] = Buffer.byteLength(soapPostMessage);
httpHeaders['Content-Type'] = "text/xml; charset=utf-8";
httpHeaders.Accept = 'application/xml, text/xml, */*';
httpHeaders["User-Agent"] = userAgent;
url = (settings.useHttp ? "http://" : "https://") + hostname + ":" + settings.port + "/" + settings.organizationName + organizationPath + "/web";
ntlmOptions = {
username : options.username || settings.username,
password : options.password || settings.password,
workstation : options.workstation || settings.workstation || '',
domain : options.ntlmDomain || settings.ntlmDomain || ''
};
httpHeaders.cookie = "ReqClientId=" + options.ReqClientId;
httpHeaders.SOAPAction = SOAPActionBase + action;
httpHeaders["Content-Length"] = Buffer.byteLength(soapPostMessage);
httpHeaders["Content-Type"] = "text/xml; charset=utf-8";
httpHeaders.Accept = "application/xml, text/xml, */*";
httpHeaders["User-Agent"] = userAgent;
type1msg = ntlm.createType1Message(ntlmOptions);
agent = settings.useHttp ? new Agentkeepalive() : new Agentkeepalive.HttpsAgent();
ntlmOptions = {
username: options.username || settings.username,
password: options.password || settings.password,
workstation: options.workstation || settings.workstation || "",
domain: options.ntlmDomain || settings.ntlmDomain || ""
};
reqOptions = {
method: options.method || "GET",
url: url,
headers: {
Authorization: type1msg,
},
agent: agent,
timeout : settings.requestTimeout
};
type1msg = ntlm.createType1Message(ntlmOptions);
agent = settings.useHttp ? new Agentkeepalive() : new Agentkeepalive.HttpsAgent();
addSecureOptions(reqOptions);
request(reqOptions, function (err, res) {
if (err) { return cb(err); }
if (!res.headers['www-authenticate']) {
return cb(new Error('www-authenticate not found on response of second request'));
}
var type2msg = ntlm.parseType2Message(res.headers['www-authenticate']),
type3msg = ntlm.createType3Message(type2msg, ntlmOptions);
httpHeaders.Authorization = type3msg;
reqOptions = {
method : "POST",
method: options.method || "GET",
url: url,
body: soapPostMessage,
headers: {
Authorization: type1msg,
},
agent: agent,
timeout : settings.requestTimeout,
headers: httpHeaders
timeout: settings.requestTimeout
};

@@ -450,53 +420,73 @@

request(reqOptions, function (err, res, body) {
if (err) { return cb(err); }
request(reqOptions, function (err, res) {
if (err) return cb(err);
if (!res.headers["www-authenticate"]) return cb(new Error("www-authenticate not found on response of second request"));
parseResponse(body, cb);
});
});
var type2msg = ntlm.parseType2Message(res.headers["www-authenticate"]),
type3msg = ntlm.createType3Message(type2msg, ntlmOptions);
} else {
soapHeader = soapHeaderMessage
.replace("{action}", action)
.replace("{messageid}", uuid.v4())
.replace("{crmurl}", organizationServiceEndpoint);
httpHeaders.Authorization = type3msg;
if (options.encryptedData) {
security = '<wsse:Security s:mustUnderstand="1" xmlns:wsse="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd">\
<u:Timestamp u:Id="_0">\
<u:Created>' + timeCreated.toISOString() + '</u:Created>\
<u:Expires>' + timeExpires.toISOString() + '</u:Expires>\
</u:Timestamp>' + options.encryptedData + '</wsse:Security>';
reqOptions = {
method: "POST",
url: url,
body: soapPostMessage,
agent: agent,
timeout: settings.requestTimeout,
headers: httpHeaders
};
soapHeader = soapHeader.replace("{security}", security);
} else if (options.header) {
soapHeader = soapHeader.replace("{security}", options.header);
addSecureOptions(reqOptions);
request(reqOptions, function (err, res, body) {
if (err) return cb(err);
parseResponse(body, cb);
});
});
} else {
return cb(new Error("Neither token or header found."));
}
soapHeader = soapHeaderMessage
.replace("{action}", action)
.replace("{messageid}", uuid.v4())
.replace("{crmurl}", organizationServiceEndpoint);
url = (settings.useHttp ? "http://" : "https://") + hostname + ":" + settings.port + organizationPath;
soapPostMessage = soapEnvelopeMessage
.replace("{envelopeNS}", "http://www.w3.org/2003/05/soap-envelope")
.replace("{header}", soapHeader)
.replace("{body}", xmlrequestbody);
if (options.encryptedData) {
security = '<wsse:Security s:mustUnderstand="1" xmlns:wsse="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd">\
<u:Timestamp u:Id="_0">\
<u:Created>' + timeCreated.toISOString() + "</u:Created>\
<u:Expires>" + timeExpires.toISOString() + "</u:Expires>\
</u:Timestamp>" + options.encryptedData + "</wsse:Security>";
httpHeaders['Content-Type'] = 'application/soap+xml; charset=UTF-8';
httpHeaders['Content-Length'] = Buffer.byteLength(soapPostMessage);
soapHeader = soapHeader.replace("{security}", security);
requestOptions = {
method: 'POST',
uri: url,
body: soapPostMessage,
headers: httpHeaders
};
} else if (options.header) soapHeader = soapHeader.replace("{security}", options.header);
addSecureOptions(requestOptions);
else return cb(new Error("Neither token or header found."));
request(requestOptions, function (err, res, body) {
if (err) { return cb(err); }
url = (settings.useHttp ? "http://" : "https://") + hostname + ":" + settings.port + organizationPath;
soapPostMessage = soapEnvelopeMessage
.replace("{envelopeNS}", "http://www.w3.org/2003/05/soap-envelope")
.replace("{header}", soapHeader)
.replace("{body}", xmlrequestbody);
parseResponse(body, cb);
});
}
httpHeaders["Content-Type"] = "application/soap+xml; charset=UTF-8";
httpHeaders["Content-Length"] = Buffer.byteLength(soapPostMessage);
requestOptions = {
method: "POST",
uri: url,
body: soapPostMessage,
headers: httpHeaders
};
addSecureOptions(requestOptions);
request(requestOptions, function (err, res, body) {
if (err) return cb(err);
parseResponse(body, cb);
});
}
});
};

@@ -509,22 +499,14 @@

if (typeof dupeObj === 'object') {
if (dupeObj.length) {
retObj = [];
}
if (typeof dupeObj === "object") {
if (dupeObj.length) retObj = [];
for (objInd in dupeObj) {
if (dupeObj.hasOwnProperty(objInd)) {
rk = renameKey(objInd, pfxs);
if (typeof dupeObj[objInd] === 'object') {
retObj[rk] = deepObjCopy(dupeObj[objInd], pfxs);
} else if (typeof dupeObj[objInd] === 'string') {
retObj[rk] = dupeObj[objInd];
} else if (typeof dupeObj[objInd] === 'number') {
retObj[rk] = dupeObj[objInd];
} else if (typeof dupeObj[objInd] === 'boolean') {
if (dupeObj[rk]) {
retObj[objInd] = true;
} else {
retObj[objInd] = false;
}
}
if (typeof dupeObj[objInd] === "object") retObj[rk] = deepObjCopy(dupeObj[objInd], pfxs);
else if (typeof dupeObj[objInd] === "string") retObj[rk] = dupeObj[objInd];
else if (typeof dupeObj[objInd] === "number") retObj[rk] = dupeObj[objInd];
else if (typeof dupeObj[objInd] === "boolean")
if (dupeObj[rk]) retObj[objInd] = true;
else retObj[objInd] = false;
}

@@ -555,6 +537,6 @@ }

options = {
method: 'POST',
method: "POST",
uri: "https://" + host + path,
body: samlRequest,
headers: { 'Content-Length': Buffer.byteLength(samlRequest) }
headers: { "Content-Length": Buffer.byteLength(samlRequest) }
};

@@ -565,3 +547,3 @@

request(options, function (err, res, body) {
if (err) { return cb(err); }
if (err) return cb(err);

@@ -571,8 +553,6 @@ var resXml = domParser.parseFromString(body),

// search for a fault
exp = ['S:Envelope', 'S:Body', 'S:Fault', 'S:Detail', 'psf:error', 'psf:internalerror', 'psf:text'].map(name).join("") + "/text()",
exp = ["S:Envelope", "S:Body", "S:Fault", "S:Detail", "psf:error", "psf:internalerror", "psf:text"].map(name).join("") + "/text()",
fault = xpath.select(exp, resXml);
if (fault.length > 0) {
return cb(new Error(fault.toString()));
}
if (fault.length > 0) return cb(new Error(fault.toString()));

@@ -587,3 +567,3 @@ return cb(null, resXml);

fetchEndpoints(function (err, result) {
if (err) { return cb(err); }
if (err) return cb(err);

@@ -594,7 +574,7 @@ authOptions = result;

loadOrRegisterDevice(authOptions, function (err, result) {
if (err) { return cb(err); }
if (err) return cb(err);
authOptions.DeviceInfo = result;
getTokenUsingDeviceId(authOptions, function (err, result) {
if (err) { return cb(err); }
if (err) return cb(err);

@@ -616,8 +596,8 @@ var timeCreated = new Date(),

requestOptions = {
method: 'POST',
method: "POST",
uri: authOptions.IssuerAddress,
body: authRequestSTSTokenMessage,
headers: {
'Content-Type': 'application/soap+xml; charset=UTF-8',
'Content-Length': Buffer.byteLength(authRequestSTSTokenMessage)
"Content-Type": "application/soap+xml; charset=UTF-8",
"Content-Length": Buffer.byteLength(authRequestSTSTokenMessage)
}

@@ -629,3 +609,3 @@ };

request(requestOptions, function (err, res, body) {
if (err) { return cb(err); }
if (err) return cb(err);

@@ -638,19 +618,15 @@ var resXml = domParser.parseFromString(body),

if (fault.length > 0) {
fullMessage = fault.toString();
faultDetailsXpath = "//*[local-name()='Fault']/*[local-name()='Detail']";
faultDetails = xpath.select(faultDetailsXpath, resXml);
if (fault.length <= 0) return cb(null, resXml);
if (faultDetails.length > 0) {
parseString(faultDetails.toString(), {explicitArray: false}, function (err, data) {
if (err) { return cb(err); }
fullMessage = fault.toString();
faultDetailsXpath = "//*[local-name()='Fault']/*[local-name()='Detail']";
faultDetails = xpath.select(faultDetailsXpath, resXml);
fullMessage = fullMessage + ". Details:" + data;
return cb(new Error(fullMessage), null);
});
}
} else {
return cb(null, resXml);
}
if (faultDetails.length > 0)
parseString(faultDetails.toString(), {explicitArray: false}, function (err, data) {
if (err) return cb(err);
fullMessage = fullMessage + ". Details:" + data;
return cb(new Error(fullMessage), null);
});
});

@@ -664,3 +640,3 @@ });

fetchEndpoints(function (err, wsdlInfo) {
if (err) { return cb(err); }
if (err) return cb(err);
var wstrustFlowOptions,

@@ -671,8 +647,7 @@ flow,

if (wsdlInfo.KeyType === keyTypeUnsupported) {
if (wsdlInfo.KeyType === keyTypeUnsupported)
wsdlInfo.KeyType = "http://schemas.xmlsoap.org/ws/2005/02/trust/SymmetricKey";
}
wstrustFlowOptions = {
wstrustEndpoint: identifier + '/2005/usernamemixed',
wstrustEndpoint: identifier + "/2005/usernamemixed",
username: authOptions.username,

@@ -688,3 +663,3 @@ password: authOptions.password,

flow.getWSSecurityHeader(function (err, header) {
if (err) { return cb(err); }
if (err) return cb(err);

@@ -699,6 +674,6 @@ return cb(null, header);

url: (settings.useHttp ? "http://" : "https://") + hostname + ":" + settings.port,
username : options.username || settings.username,
password : options.password || settings.password,
workstation : options.workstation || settings.workstation || '',
domain : options.ntlmDomain || settings.ntlmDomain || '',
username: options.username || settings.username,
password: options.password || settings.password,
workstation: options.workstation || settings.workstation || "",
domain: options.ntlmDomain || settings.ntlmDomain || "",

@@ -711,4 +686,4 @@ headers: {

httpntlm.get(authOptions, function (err, res) {
if (err) { return cb(err); }
if (res.cookies.length === 0) { return cb(Error.create("Invalid Username or Password")); }
if (err) return cb(err);
if (res.cookies.length === 0) return cb(Error.create("Invalid Username or Password"));

@@ -730,51 +705,53 @@ var cookies = cookie.parse(res.headers["set-cookie"].join(";")),

this.Authenticate = function (options, cb) {
var responseXMLCB = function (err, resXml) {
if (err) { return cb(err); }
kidoConnector.isHostAllowed(hostname, function (err, allowed) {
if (err) return cb(err);
if (!allowed) return cb(new Error("The hostname is not allowed"));
var token = xpath.select("//*[local-name()='EncryptedData']", resXml).toString(),
authToken = uuid.v4(),
authItem = {token: token};
var responseXMLCB = function (err, resXml) {
if (err) return cb(err);
cacheTokenByAuth.set(authToken, authItem);
cacheAuthByUser.set(options.username, authToken);
return cb(null, {auth: authToken});
},
var token = xpath.select("//*[local-name()='EncryptedData']", resXml).toString(),
authToken = uuid.v4(),
authItem = {token: token};
federationCB = function (err, header) {
if (err) { return cb(err); }
cacheTokenByAuth.set(authToken, authItem);
cacheAuthByUser.set(options.username, authToken);
return cb(null, {auth: authToken});
},
var authToken = uuid.v4(),
authItem = {header: header};
federationCB = function (err, header) {
if (err) return cb(err);
cacheTokenByAuth.set(authToken, authItem);
cacheAuthByUser.set(options.username, authToken);
return cb(null, {auth: authToken});
};
var authToken = uuid.v4(),
authItem = {header: header};
// handles optional 'options' argument
if (!cb && typeof options === 'function') {
cb = options;
options = {};
}
cacheTokenByAuth.set(authToken, authItem);
cacheAuthByUser.set(options.username, authToken);
return cb(null, {auth: authToken});
};
// sets default values
cb = cb || defaultCb;
options = options || {};
// handles optional 'options' argument
if (!cb && typeof options === "function") {
cb = options;
options = {};
}
// validates arguments values
if (typeof options !== 'object') { return cb(new Error("'options' argument is missing or invalid.")); }
// sets default values
cb = cb || defaultCb;
options = options || {};
// Validates username and password
options.username = options.username || settings.username;
options.password = options.password || settings.password;
// validates arguments values
if (typeof options !== "object") return cb(new Error("'options' argument is missing or invalid."));
if (settings.authType === "microsoft_online") {
authenticateUsingMicrosoftOnline(options, responseXMLCB);
} else if (settings.authType === "federation") {
authenticateUsingFederation(options, federationCB);
} else if (settings.authType === "ntlm") {
authenticateUsingNTLM(options, cb);
} else { //Default Live Id
authenticateUsingLiveId(options, responseXMLCB);
}
// Validates username and password
options.username = options.username || settings.username;
options.password = options.password || settings.password;
if (settings.authType === "microsoft_online") authenticateUsingMicrosoftOnline(options, responseXMLCB);
else if (settings.authType === "federation") authenticateUsingFederation(options, federationCB);
else if (settings.authType === "ntlm") authenticateUsingNTLM(options, cb);
//Default Live Id
else authenticateUsingLiveId(options, responseXMLCB);
});
};

@@ -840,3 +817,3 @@

// handles optional 'options' argument
if (!cb && typeof options === 'function') {
if (!cb && typeof options === "function") {
cb = options;

@@ -849,9 +826,6 @@ options = {};

options = options || {};
if (!options || typeof options !== 'object') {
return cb(new Error("'options' argument is missing or invalid."));
}
if (!options || typeof options !== "object") return cb(new Error("'options' argument is missing or invalid."));
if (options.encryptedData || options.header) {
executeSoapPost(options, action, template, body, cb);
} else if (options.auth) {
if (options.encryptedData || options.header) executeSoapPost(options, action, template, body, cb);
else if (options.auth) {
authItem = cacheTokenByAuth.get(options.auth);

@@ -863,5 +837,5 @@ options.encryptedData = authItem.token; //For LiveId an MSOnline

executeSoapPost(options, action, template, body, cb);
} else {
} else
this.Authenticate(options, function (err, data) {
if (err) { return cb(err); }
if (err) return cb(err);

@@ -874,3 +848,2 @@ authItem = cacheTokenByAuth.get(data.auth);

});
}
};

@@ -877,0 +850,0 @@ };

{
"name": "dynamicscrm-api",
"version": "0.1.0",
"version": "0.1.1",
"description": "Pure SOAP module that allows to invoke Microsoft Dynamics CRM Online services",

@@ -43,3 +43,4 @@ "author": "Kidozen <development@kidozen.com>",

"httpntlm": "https://github.com/kidozen/node-http-ntlm/tarball/master",
"request": "2.44.0"
"request": "2.44.0",
"kido-connector": "^1.1.1"
},

@@ -46,0 +47,0 @@ "devDependencies": {

/*global describe, before, beforeEach, it */
var assert = require('assert');
var Dynamics = require('../index.js');
var assert = require("assert");
var Dynamics = require("../index.js");
var settingsForMicrosoftOnlineAuth = {
username : "",
password : "",
organizationid : "",
domain : "",
username: "",
password: "",
organizationid: "",
domain: "",
domainUrlSuffix: "",

@@ -16,5 +16,5 @@ authType: "microsoft_online" //Office365

settingsForLiveIdAuth = {
username : "",
password : "",
organizationid : "",
username: "",
password: "",
organizationid: "",
domain: "",

@@ -25,4 +25,4 @@ authType: "live_id"

settingForFederationAuth = {
username : "",
password : "",
username: "",
password: "",
domain: "",

@@ -144,2 +144,15 @@ domainUrlSuffix: "",

it("Should fail with unallowed host running on hub", function (done) {
process.env.RUNNING_ON = "hub";
var connector = new Dynamics({domain: "127.0", domainUrlSuffix: ".0.1"});
connector.Authenticate({username: "invalid"}, function (err, result) {
assert.ok(err);
assert.ok(!result);
assert.strictEqual(err.message, "The hostname is not allowed");
process.env.RUNNING_ON = "";
done();
});
});
it("Should authenticate OK", function (done) {

@@ -175,3 +188,3 @@ dynamics.Authenticate({}, function (err, result) {

assert.ok(err);
assert.strictEqual(err.message, "The password for the account has expired.\r\n");
assert.strictEqual(err.message, "The entered and stored passwords do not match.\r\n");
done();

@@ -232,3 +245,3 @@ });

assert.ok(result.username);
assert.equal('string', typeof result.auth);
assert.equal("string", typeof result.auth);
assert.equal(36, result.auth.length);

@@ -242,4 +255,4 @@ done();

var options = {};
options.EntityName = 'lead';
options.id = '0f993360-d987-43f7-8995-ab5ffb50a43f';
options.EntityName = "lead";
options.id = "0f993360-d987-43f7-8995-ab5ffb50a43f";

@@ -263,5 +276,5 @@ dynamics.Authenticate({}, function (err, authData) {

var options = {};
options.LogicalName = 'lead';
options.Attributes = [ { key: 'lastname', value : 'Doe'},
{ key: 'firstname', value : 'John'}];
options.LogicalName = "lead";
options.Attributes = [ { key: "lastname", value: "Doe"},
{ key: "firstname", value: "John"}];

@@ -279,3 +292,3 @@ dynamics.Authenticate({}, function (err, authData) {

options = {};
options.EntityName = 'lead';
options.EntityName = "lead";
options.id = result2.Envelope.Body.CreateResponse.CreateResult;

@@ -315,9 +328,8 @@ options.auth = authData.auth;

if (entities.length) { //It's an array
assert.ok(entities[0].LogicalName === 'account');
assert.ok(entities[0].LogicalName === "account");
assert.equal(entities[0].Attributes
.KeyValuePairOfstringanyType.length, 2); //Entity with 2 attributes, accountid and name
} else {
assert.ok(entities.LogicalName === 'account');
}
} else assert.ok(entities.LogicalName === "account");
done();

@@ -350,3 +362,3 @@ });

describe("Method execution with MicrosoftOnline Auth", function () {
describe.skip("Method execution with MicrosoftOnline Auth", function () {
var settings,

@@ -410,3 +422,3 @@ dynamics;

var id = "d4ea3aab-8263-e411-9446-22000b4712e7",
var id = "41658D20-C986-E411-9446-22000B4712E7".toLowerCase(),
logicalName = "contact";

@@ -413,0 +425,0 @@

SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc