Enable Token-Based Authentication in Denali Version

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:
, doUntilGetRoles

And replace it with the following lines of code:

, ui.selectToken
, net.authorize
  • Find the following line of code:
async.apply(ui.roles, deploy),
net.targetFolder,

And replace it with the following lines of code:

async.apply(net.targetFolder, deploy),
  • Find the following line of code:
,   ui.email
,   ui.password
,   net.roles
,   ui.roles

And replace it with the following lines of code:

,   ui.selectToken
,   net.authorize

Modify the tool.js File

  1. In the SuiteCommerce Advanced source directory, open this file: …/gulp/ns-deploy/suitetalk4node/src/tool.js
  2. Find the following line of code:
nsVersion: '2015_1'

And replace it with the following lines of code:

nsVersion: '2020_2'

Modify the getDataCenterUrls.tpl File

  1. In the SuiteCommerce Advanced source directory, open this file: …/gulp/ns-deploy/suitetalk4node/src/templates/getDataCenterUrls.tpl
  2. File the following line:
<nsmessages:account>{{account}}</nsmessages:account>

And replace it with the following lines of code:

<nsmessages:account>{{credentials.account}}</nsmessages:account>

Modify the template.js File

  1. In the SuiteCommerce Advanced source directory, open this file: …/gulp/ns-deploy/suitetalk4node/src/template.js
  2. Find the following lines of code:
var Handlebars = require('handlebars')
,   fs = require('fs')

And replace it with the following lines of code:

var Handlebars = require('handlebars')
,   OAuth1 = require('oauth1').OAuth1
,   fs = require('fs')

3. 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 lines of 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

1.In the SuiteCommerce Advanced source directory, open this file: .../gulp/ns-deploy/suitetalk4node/src/communications.js

2.Find the following lines of code:
,   _request: function(action, payload, cb)
{

And replace it with the following lines of code:

,   _request: function(action, payload, cb)
{
    cb = cb || function(){};

3. 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 || 'https://webservices.netsuite.com';
    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)
        {
            // console.log('json response: ', JSON.stringify(result.Envelope.Body, null,2))
            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);
            cb(null, soap_body, result);
        });
    });

    self.log('Request text for action: ' + action+'\n'+ payload);
    // console.log(payload);
    // payload = prettyData.xmlmin(payload); //minify xml
    req.end(payload);
    return deferred.promise;
}

And replace it with the following lines of 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) {
            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);

                        cb(null, soap_body, result);
                    });
                }
            );

            req.end(payloadResult);
        });
    });
}

4. Add the getDefaultWebServiceUrl method directly above the request method in the communications.js file as shown in the following example:

,   getDefaultWebServiceUrl: function()
        {
            if (this.credentials.molecule)
            {
                return 'https://webservices.' + this.credentials.molecule + '.netsuite.com'
            }
            if(this.credentials.vm)
            {
                return this.credentials.vm;
            }
            else
            {
                return 'https://webservices.netsuite.com'
            }
        }

    //@method __request - has the same signature as _request but it won't perform the data center domain verification.
,   __request: function(action, payload, cb) {

Modify the passport.tpl File

  1. In the SuiteCommerce Advanced source directory, open this file: …gulp/ns-deploy/suitetalk4node/src/templates/_passport.tpl
  2. 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 it with the following lines of 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 package.json Dependencies

  1. In the top level of the SuiteCommerce Advanced source directory, open the package.json file.
  2. 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",

Modify the fs.js File

  1. In the SuiteCommerce Advanced source directory, open this file: …/gulp/ns-deploy/fs.js
  2. Find the following lines of code:
,   processBackup: function(deploy, took, cb)
{
    gutil.log('Finished', gutil.colors.cyan('Deploy website' + (took ? ', took ' + took : '') ) );

And replace it with the following lines of code:

,   processBackup: function(deploy, cb)
{
        gutil.log('Finished', gutil.colors.cyan('Deploy website') );

3.Find the following line of code:

cb(null, deploy, context, took);

And replace it with the following lines of code:

cb(null, deploy, context);

Modify the filecabinet-util.js File

  1. In the SuiteCommerce Advanced source directory, open this file: …/gulp/ns-deploy/ns-uploader/src/filecabinet-util.js
  2. Add the getFolderNamed method directly above the addOrUplodateFile method as shown in the following example:
,   getFolderNamed: function(parentFolderId, fileName, doGet)
    {
        return this.getFileNamed(parentFolderId, fileName, doGet, true);
    }

,   addOrUplodateFile: function(parentFolderId, fileName, fileContents, fileType)

Create the ns_npm_repository/oauth1 Directory

  1. In the top level of the SuiteCommerce Advanced source directory, create a new directory named ns_npm_repository.
  2. Copy the oauth1 folder from the TBApatch-denali.zip file to the new ns_npm_repository 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-denali.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

Ten perform gulp deploy that will lead to authentication.

Leave a comment

Your email address will not be published. Required fields are marked *