Home > Net >  Converting .NodeJS Authentication Token script to Apps Script
Converting .NodeJS Authentication Token script to Apps Script

Time:08-25

I am a newer Apps Scripts user who has been stuck on this problem for some time. I am trying to connect my company's reporting feature to a Google Sheet so I can create reporting dashboards for our users.

I have a .jsNode code snippet which I am able to successfully run outside of the Apps Scripts editor, but I am having issues translating it to Apps Scripts.

My goal is to be able to generate an Authentication Token which will be used in a header within a POST request. I will then use this to get a specific URL that I can pull data from (it will be a .csv file. I already feel I can accomplish this using another script)

Below is the .NodeJS code snippet:

const crypto = require('crypto');

module.exports.init = function () {
    let prefix = 'abc-admin-v1'
    let businessId = 'XXXX'
    let publicAppKeyId = 'XXXX'
    let secretKey = 'XXXX'
    let unixTimestamp = Math.floor(Date.now() / 1000)
    let payload = `${prefix}${businessId}${unixTimestamp}`
    let rawKey = Buffer.from(secretKey, 'base64')
    let signature = crypto.createHmac('sha256', rawKey).update(payload, 'utf8').digest('base64')
    let token = `${signature}${payload}`
    let httpBasicPayload = `${publicAppKeyId}:${token}`
    let httpBasicCredentials = Buffer.from(httpBasicPayload, 'utf8').toString('base64')

    console.log(httpBasicCredentials);
};

Below will be what I have in Apps Scripts:

function apiInfo() {
  var secret = "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX";
  var apiKey = "XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX";
  var locationID = "XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX";  

  var prefix = "abc-admin-v1";
  var timeStamp = Math.round((new Date()).getTime() / 1000);
  var timeStampReal = JSON.stringify(timeStamp);

  var tokenPayload = prefix   businessID   timeStampReal;
  var enCodeTokenPayload = Utilities.base64Encode(tokenPayload);
  var deCodeTokenPayload = Utilities.base64Decode(enCodeTokenPayload);
  var tokenPayloadReal = JSON.stringify(tokenPayload);

  var rawKey = Utilities.base64Decode(secret);
  var rawMac = Utilities.computeHmacSha256Signature(tokenPayloadReal, rawKey);
  var signature = Utilities.base64Encode(rawMac);

  var token = signature   tokenPayload;

  var httpBasicPayload = apiKey   ":"   token;
  var httpBasicCredentials = Utilities.base64Encode(httpBasicPayload);

When testing using the current GAS code, it produces an invalid Auth Token.

When I run the Node.js version outside of GAS, it produces a valid Auth Token. I am looking to find out what is currently wrong with my code that is producing an invalid auth token. I would like to keep the project within GAS if possible.

CodePudding user response:

I believe your goal is as follows.

  • You want to convert your showing Node.js script to Google Apps Script. Namely, you want to retrieve the same values of httpBasicCredentials between your Node.js script and Google Apps Script.

      const crypto = require('crypto');
    
      module.exports.init = function () {
          let prefix = 'abc-admin-v1'
          let businessId = 'XXXX'
          let publicAppKeyId = 'XXXX'
          let secretKey = 'XXXX'
          let unixTimestamp = Math.floor(Date.now() / 1000)
          let payload = `${prefix}${businessId}${unixTimestamp}`
          let rawKey = Buffer.from(secretKey, 'base64')
          let signature = crypto.createHmac('sha256', rawKey).update(payload, 'utf8').digest('base64')
          let token = `${signature}${payload}`
          let httpBasicPayload = `${publicAppKeyId}:${token}`
          let httpBasicCredentials = Buffer.from(httpBasicPayload, 'utf8').toString('base64')
    
          console.log(httpBasicCredentials);
      };
    

When I saw your showing Google Apps Script, unfortunately, there are several undeclared variable and unused variables. By this, in this answer, I would like to propose to directly converting your showing Node.js to Google Apps Script.

Sample script:

function myFunction() {
  let prefix = 'abc-admin-v1'
  let businessId = 'XXXX'
  let publicAppKeyId = 'XXXX'
  let secretKey = 'XXXX'
  let unixTimestamp = Math.floor(Date.now() / 1000);
  let payload = `${prefix}${businessId}${unixTimestamp}`;
  let payloadBytes = Utilities.newBlob(payload).getBytes();
  let rawKey = Utilities.base64Decode(secretKey);
  let signature = Utilities.base64Encode(Utilities.computeHmacSha256Signature(payloadBytes, rawKey));
  let token = `${signature}${payload}`;
  let httpBasicPayload = `${publicAppKeyId}:${token}`;
  let httpBasicCredentials = Utilities.base64Encode(httpBasicPayload);
  console.log(httpBasicCredentials);
}

Testing:

In the above scripts, when the value of unixTimestamp is 1661403828, both your Node.js and my sample Google Apps Script are the same values as follows.

WFhYWDpGYXBwRk9kaFoxdDVQNGVkV2JJbFIvR1RiMkEyZ0hwYThld05BYjVDVkxnPWFiYy1hZG1pbi12MVhYWFgxNjYxNDAzODI4

Note:

  • From your question, in this answer, your Node.js is converted to Google Apps Script. Please be careful about this.

References:

  • Related