Enable Token-Based Authentication (Montblanc, Vinson, Elbrus, and Kilimanjaro)

Prepare your SuiteCommerce Advanced (SCA) or Site Builder Extensions implementation to use token-based authentication with the developer tools, including the extension, theme, and SuiteCommerce Advanced tools, as described in the following steps. You need to update several files, add new files, and then also download new theme and extension developer tools, so be sure to complete all of the required steps as outlined in the following procedures:

Modify the index.js File for Gulp Deployments

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

  2. Find the following line of code:

                    , doUntilGetRoles 
    
                  

    And replace it with the following lines of code:

                    , ui.selectToken
    , net.authorize 
    
                  
  3. Find the following lines of code:

                    async.apply(ui.roles, deploy),
    net.targetFolder, 
    
                  

    And replace them with the following code:

                    async.apply(net.targetFolder, deploy), 
    
                  
  4. 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, 
    
                  

    And replace them with the following code:

                    async.apply(net.getWebsitesAndDomains, deploy), 
    
                  
  5. Find the following lines of code:

                    ,   ui.email
    ,   ui.password
    ,   net.roles
    ,   ui.roles 
    
                  

    And replace them with the following code:

                    ,   ui.selectToken
    ,   net.authorize 
    
                  

Modify the tool.js File in the NPM Repository

  1. In the SuiteCommerce Advanced source directory, open this file: .../ns_npm_repository/suitetalk4node/src/tool.js

  2. Find the following line of code:

                    nsVersion: '2015_1' 
    
                  

    And replace it with the following code:

                    nsVersion: '2020_2' 
    
                  

Modify the getDataCenterUrls.tpl File

  1. In the SuiteCommerce Advanced source directory, open this file: .../ns_npm_repository/suitetalk4node/src/templates/getDataCenterUrls.tpl

  2. Find the following line of code:

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

    And replace it with the following code:

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

Modify the template.js File in the NPM Repository

  1. In the SuiteCommerce Advanced source directory, open this file: .../ns_npm_repository/suitetalk4node/src/template.js

  2. Find the following lines of code:

                    var Handlebars = require('handlebars')
    ,   fs = require('fs') 
    
                  

    And replace them with the following 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 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

  1. In the SuiteCommerce Advanced source directory, open this file: .../ns_npm_repository/suitetalk4node/src/communications.js

  2. 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(){}; 
    
                  
  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 || 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

  1. In the SuiteCommerce Advanced source directory, open this file: .../ns_npm_repository/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 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.

  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 them with the following 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 code:

                    cb(null, deploy, context); 
    
                  

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", 
    
                  

Create the oauth1 Directory

  1. In the SuiteCommerce Advanced source directory, create a new directory named oauth1 in the ns_npm_repository folder: .../ns_npm_repository/oauth1

  2. 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 this command completes, continue with additional updates for token-based authentication. For detailed instructions, see Token-Based Authentication Updates for Developer Tools.

Additional Steps for SCA Vinson

In some implementations of the Vinson release of SCA, completing the preceding steps can return the error message, "getFileNamesearcherror undefined," after you run the gulp deploy command.

The following procedure describes the additional steps to enable token-based authentication on Vinson implementations of SCA if you encounter errors.

To enable token-based authentication on SCA Vinson:

  1. Prepare your Vinson installation of SCA for token-based authentication as described in the preceding procedures.

  2. In the top level of the SCA source directory, open the package.json file.

  3. Add the following line to the dependencies:

                      "xmlbuilder": "8.0.0", 
    
                    
  4. Save the file and close it.

  5. Run the following command at the top level of the SCA source directory:

    npm cache clear –force

  6. After the command successfully completes, run the following command in the same directory:

    npm install

  7. After steps 5 and 6 are successfully completed, go to the node_modules\gulp-ttf2eot directory and open the package.json file.

  8. Find the following line of code:

                      "ttf2eot": "latest" 
    
                    
  9. And replace it with the following code:

                      "ttf2eot": "2.0.0" 
    
                    
  10. Save the file and close it.

  11. From the node_modules\gulp-ttf2eot directory, run the following command:

    npm install

  12. Go back to the top level of the SCA source directory, then go to the node_modules\gulp-ttf2woff directory and open the package.json file.

  13. Find the following line of code:

                      "ttf2woff": "latest" 
    
                    
  14. And replace it with the following code:

                      "ttf2woff": "2.0.2" 
    
                    
  15. Save the file and close it.

  16. From the node_modules\gulp-ttf2woff, run the following command:

    npm install

  17. Go back to the top level of the SCA source directory and run the following command:

    gulp deploy

Related Topics

SCA Patches

General Notices