Note – The below could be done when the gulp deploy command shows Invalid login credentials for older versions.
Modify the index.js File for Gulp Deployments
- In the SuiteCommerce Advanced source directory, open this file: …/gulp/ns-deploy/index.js
- Find the following line of code:
,doUntilGetRolesCopy
- And replace it with the following lines of code:
, ui.selectToken, net.authorizeCopy
- Find the following lines of code:
async.apply(ui.roles, deploy),net.targetFolder,
- CopyAnd replace them with the following code:
async.apply(net.targetFolder, deploy),
- This step is required only if the version of your SCA implementation is Kilimanjaro. If so, find the following lines of code:
async.apply(ui.roles, deploy),net.getWebsitesAndDomains,
- CopyAnd replace them with the following code:
async.apply(net.getWebsitesAndDomains, deploy),
- Find the following lines of code:
, ui.email, ui.password, net.roles, ui.roles
- CopyAnd replace them with the following code:
, ui.selectToken, net.authorize
Modify the tool.js File in the NPM Repository
- In the SuiteCommerce Advanced source directory, open this file: …/ns_npm_repository/suitetalk4node/src/tool.js
- Find the following line of code:
nsVersion: '2015_1'
- CopyAnd replace it with the following code:
nsVersion: '2020_2'
Modify the getDataCenterUrls.tpl File
- In the SuiteCommerce Advanced source directory, open this file: …/ns_npm_repository/suitetalk4node/src/templates/getDataCenterUrls.tpl
- Find the following line of code:
<nsmessages:account>{{account}}</nsmessages:account>
- CopyAnd replace it with the following code:
<nsmessages:account>{{credentials.account}}</nsmessages:account>
Modify the template.js File in the NPM Repository
- In the SuiteCommerce Advanced source directory, open this file: …/ns_npm_repository/suitetalk4node/src/template.js
- Find the following lines of code:
var Handlebars = require('handlebars'), fs = require('fs')Copy
- And replace them with the following code:
var Handlebars = require('handlebars'), OAuth1 = require('oauth1').OAuth1, fs = require('fs')
Find the _template method:
, _template: function(file_name, params)
{
this._initTemplateContext(params);
var fileName = path.join(__dirname, '/templates/', file_name);
var template = Handlebars.compile(fs.readFileSync(fileName, {encoding: 'utf8'}).toString());
return template(params);
}
And replace it with the following code:
, _template: function(file_name, params)
{
var self = this;
var oauth1 = new OAuth1(this.credentials);
return oauth1.soapAuthorize(this.credentials.authID).then(function(credentials) {
self._initTemplateContext(params);
params.credentials = params.credentials || {};
params.credentials.vm = self.credentials.vm;
params.credentials.molecule = self.credentials.molecule;
params.credentials.authID = self.credentials.authID;
params.credentials.token = credentials.token || self.credentials.token;
params.credentials.signature = credentials.signature || self.credentials.signature;
params.credentials.nonce = credentials.nonce || self.credentials.nonce;
params.credentials.timestamp = credentials.timestamp || self.credentials.timestamp;
params.credentials.account = credentials.account || self.credentials.account;
params.credentials.consumerKey = credentials.consumerKey || self.credentials.consumerKey;
var fileName = path.join(__dirname, '/templates/', file_name);
var template = Handlebars.compile(fs.readFileSync(fileName, {encoding: 'utf8'}).toString());
return template(params);
});
}
Modify the communication.js File in the NPM Repository
- In the SuiteCommerce Advanced source directory, open this file: …/ns_npm_repository/suitetalk4node/src/communications.js
Find the following lines of code:
, _request: function(action, payload, cb)
{
And replace them with the following code:
, _request: function(action, payload, cb)
{
cb = cb || function(){};
Find the _request method:
, __request: function(action, payload, cb)
{
var self = this
, deferred = Q.defer();
cb = cb || function(){};
var datacenterDomain = self.dataCenterDomains && self.dataCenterDomains.webservices || this.getDefaultWebServiceUrl();
// console.log('datacenterDomain', datacenterDomain, datacenterDomain + '/services/NetSuitePort_' + self.nsVersion)
this.getQueue().add(self, function(taskDone)
{
var req = request({
method: 'POST'
, uri: datacenterDomain + '/services/NetSuitePort_' + self.nsVersion
, headers: {
'User-Agent': 'Node-SOAP/0.0.1'
, 'Accept': 'text/html,application/xhtml+xml,application/xml,text/xml;q=0.9,*/*;q=0.8'
, 'Accept-Encoding': 'none'
, 'Accept-Charset': 'utf-8'
, 'Connection': 'close'
, 'Content-Type': 'text/xml; charset=utf-8'
, 'SOAPAction': '"' + action + '"'
, 'Expect': '100-continue'
}
}, function(err, response)
{
if (err)
{
return cb(err);
}
self.log('Response text for action: ' + action + '\n' + response.body);
xml2js.parseString(response.body, self._xml2jsOptions , function(err, result)
{
if (err)
{
deferred.reject(err);
return cb(err);
}
var soap_body = result.Envelope.Body[0];
if (soap_body && soap_body.Fault)
{
deferred.reject(new Error(soap_body.Fault[0].faultstring[0]));
return cb(new Error(soap_body.Fault[0].faultstring[0]));
}
deferred.resolve(soap_body);
taskDone();
cb(null, soap_body, result);
});
});
self.log('Request text for action: ' + action+'\n'+ payload);
req.end(payload);
});
return deferred.promise;
}
And replace it with the following code:
, __request: function(action, payload, cb) {
const self = this;
cb = cb || function() {};
const datacenterDomain =
(self.dataCenterDomains && self.dataCenterDomains.webservices) ||
this.getDefaultWebServiceUrl();
const args = require('yargs').argv;
if (args.proxy) {
request = request.defaults({ proxy: args.proxy });
}
return payload.then(function(payloadResult) {
return new Promise(function(resolve, reject) {
self.getQueue().add(self, function(taskDone) {
const req = request(
{
method: 'POST',
uri: datacenterDomain + "/services/NetSuitePort_" + self.nsVersion,
headers: {
'User-Agent': self.credentials.user_agent || 'Node-SOAP/0.0.1',
Accept:
'text/html,application/xhtml+xml,application/xml,text/xml;q=0.9,*/*;q=0.8',
'Accept-Encoding': 'none',
'Accept-Charset': 'utf-8',
Connection: 'close',
'Content-Type': 'text/xml; charset=utf-8',
SOAPAction: '"' + action + '"'
}
},
function(err, response) {
if (err) {
return cb(err);
}
xml2js.parseString(response.body, self._xml2jsOptions, function(
err,
result
) {
if (err) {
reject(err);
return cb(err);
}
const soap_body = result.Envelope.Body[0];
if (soap_body && soap_body.Fault) {
reject(new Error(soap_body.Fault[0].faultstring[0]));
return cb(new Error(soap_body.Fault[0].faultstring[0]));
}
resolve(soap_body);
taskDone();
cb(null, soap_body, result);
});
}
);
req.end(payloadResult);
});
});
});
}
Modify the passport.tpl File in the NPM Repository
- In the SuiteCommerce Advanced source directory, open this file: …/ns_npm_repository/suitetalk4node/src/templates/_passport.tpl
Find the following lines of code:
<nsmessages:passport>
{{#if credentials.email}}<nscore:email>{{credentials.email}}</nscore:email>{{/if}}
{{#if credentials.password}}<nscore:password>{{credentials.password}}</nscore:password>{{/if}}
{{#if credentials.account}}<nscore:account>{{credentials.account}}</nscore:account>{{/if}}
{{#if credentials.roleId}}<nscore:role internalId="{{credentials.roleId}}"/>{{/if}}
</nsmessages:passport>
And replace them with the following code:
<ns:tokenPassport actor="http://schemas.xmlsoap.org/soap/actor/next" mustUnderstand="0"
xmlns:ns="urn:messages_2020_1.platform.webservices.netsuite.com">
{{#if credentials.account}}<ns:account>{{credentials.account}}</ns:account>{{/if}}
{{#if credentials.consumerKey}}<ns:consumerKey>{{credentials.consumerKey}}</ns:consumerKey>{{/if}}
{{#if credentials.token}}<ns:token>{{credentials.token}}</ns:token>{{/if}}
{{#if credentials.nonce}}<ns:nonce>{{credentials.nonce}}</ns:nonce>{{/if}}
{{#if credentials.timestamp}}<ns:timestamp>{{credentials.timestamp}}</ns:timestamp>{{/if}}
{{#if credentials.signature}}<ns:signature algorithm="HMAC_SHA256">{{credentials.signature}}</ns:signature>{{/if}}
</ns:tokenPassport>
Modify the fs.js File (Vinson and Montblanc)
Follow these steps only if your SCA implementation is Vinson or Montblanc.
- In the SuiteCommerce Advanced source directory, open this file: …/gulp/ns-deploy/fs.js
Find the following lines of code:
, processBackup: function(deploy, took, cb)
{
gutil.log('Finished', gutil.colors.cyan('Deploy website' + (took ? ', took ' + took : '') ) );
And replace them with the following code:
, processBackup: function(deploy, cb)
{
gutil.log('Finished', gutil.colors.cyan('Deploy website') );
Find the following line of code:
cb(null, deploy, context, took);
And replace it with the following code:
cb(null, deploy, context);
Modify package.json Dependencies
- In the top level of the SuiteCommerce Advanced source directory, open the package.json file.
Add the following line to the dependencies:
"oauth1": "file:./ns_npm_repository/oauth1",
As shown in the following example excerpt:
"dependencies": {
"oauth1": "file:./ns_npm_repository/oauth1",
"ansi-colors": "2.0.1",
"archiver": "2.1.1",
"async": "2.6.1",
Create the oauth1 Directory
- In the SuiteCommerce Advanced source directory, create a new directory named oauth1 in the ns_npm_repository folder:
.../ns_npm_repository/oauth1 - Copy the source files from the oauth1 folder in the TBApatch-elbrus-vinson-kilimanjaro.zip file to the new oauth1 directory you created in the preceding step.
Replace Gulp Files
Replace the following files in the SuiteCommerce Advanced source directory with the modified versions of the same files available in the .zip file for this patch: TBApatch-elbrus-vinson-kilimanjaro.zip
- …/gulp/ns-deploy/net.js
- …/gulp/ns-deploy/ui.js
Run NPM Command for oauth1
After updating all files as required, adding new files from the .zip file for the patch, and downloading and setting up the theme and extension developer tools, you must run the following command to ensure that token-based authentication functions properly.
Run the following command at the top level of the SuiteCommerce Advanced source directory:
npm i oauth1 suitetalk
When the command completes, verify that token-based authentication is working