Hi I am getting invalid signature in the login audit trail when trying to send a request to Postman using pre-request scripts as well as the test scripts. I am using the same script from the Postman collection. I am attaching both scripts for reference. When I try to call the NetSuite request within the test script while creating the authentication within pre-request script, it gives me the invalid signature error.
const cyptojs = require('crypto-js');
const oauth_consumer_key = pm.environment.get('token_client_id');
//const oauth_consumer_key = '5d2544ee52821edfe7f6ab9cfe8bee2f2cb37473b7e22c620cc4557949a82323Z'; // for testing: completely invalid
//const oauth_consumer_key = '4941f26f1007d63cb25aab078cdf0bf0efbf63d6b8f1e6af5e5195e0011f5ec1'; // for testing: exists, but not the intended app
const oauth_consumer_secret = pm.environment.get('token_client_secret');
//const oauth_consumer_secret = '366f1c95144cf272df508907cd8b7b73303eda0ddddb06c72d2eda419d127471Z';
const oauth_token_id = pm.environment.get('TOKEN_ID');
//const oauth_token_id = 'edb13811086083953e977af4ee2f81ed8e5740c2eb9f2d48d5eca5dd8d4876ffZ'; // for testing: invalid, does not represent valid user
//const oauth_token_id = 'b7af443691d2cab8edf854fc41ca75c1675a1fb736b9ba88c487218b5cf627b7'; // for testing: different user
const oauth_token_secret = pm.environment.get('TOKEN_SECRET');
//const oauth_token_secret = '5e0aa25d969ab27820e421c97a988b09dbd9c4a776d4d94534d2129ff64de489';
const oauth_account_id = pm.environment.get('ACCOUNT_ID');
//const oauth_account_id = 'tstdrv2245019'; // Account IDs that have alpha characters are always in all uppercase, so this is invalid
//const oauth_account_id = 'TSTDRV2262076'; // If valid account id, but someone else's, so you will get an error
const oauth_signing_key = `${encodeURIComponent(oauth_consumer_secret)}&${encodeURIComponent(oauth_token_secret)}`;
const random_source = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789';
let oauth_nonce = '';
for (var i = 0; i < 32; i++) {
oauth_nonce += random_source.charAt(Math.floor(Math.random() * random_source.length));
}
const oauth_nonce_array = cyptojs.enc.Utf8.parse(oauth_nonce);
const oauth_nonce_final = encodeURIComponent(cyptojs.enc.Base64.stringify(oauth_nonce_array));
const oauth_parameter_string_object = {};
oauth_parameter_string_object.oauth_consumer_key = oauth_consumer_key;
oauth_parameter_string_object.oauth_token = oauth_token_id;
//oauth_parameter_string_object.oauth_nonce = 'abcd1234'; // for testing: at same timestamp and nonce, you get NonceUsed error in Login Audit Trail
oauth_parameter_string_object.oauth_nonce = oauth_nonce_final;
oauth_parameter_string_object.oauth_timestamp = Math.round((new Date()).getTime() / 1000);
//oauth_parameter_string_object.oauth_timestamp = 1632587834 // for testing: at same timestamp and nonce, you get NonceUsed error in Login Audit Trail
//oauth_parameter_string_object.oauth_timestamp = 163258783499 // for testing: with invalid timestamp, you get InvalidTimestamp error in Login Audit Trail
oauth_parameter_string_object.oauth_signature_method = 'HMAC-SHA256';
oauth_parameter_string_object.oauth_version = '1.0';
//oauth_parameter_string_object.oauth_version = '1.1'; // for testing: you get VersionRejected error in Login Audit Trail
const oauth_authorization_header_object = {};
for (var key in oauth_parameter_string_object) {
oauth_authorization_header_object[key] = oauth_parameter_string_object[key];
}
oauth_authorization_header_object.realm = oauth_account_id;
const url_query_string = pm.request.url.getQueryString({ // Postman method to get query string
ignoreDisabled: true
});
console.log("url_query_string: " + url_query_string);
let url_query_string_array = [];
if (url_query_string != ""){
url_query_string_array = url_query_string.split('&');
}
let url_query_string_object = {};
if (url_query_string !== "") {
url_query_string_object = JSON.parse(`{"${url_query_string.replace(/&/g, '","').replace(/=/g,'":"')}"}`, function(key, value) {return key === "" ? value : encodeURIComponent(value)});
}
// parse request.params
for (var key in url_query_string_object) {;
oauth_parameter_string_object[key] = url_query_string_object[key];
}
// sort object by key
const oauth_parameter_string_object_ordered = {};
Object.keys(oauth_parameter_string_object).sort().forEach(function(key) {
oauth_parameter_string_object_ordered[key] = oauth_parameter_string_object[key];
});
// convert object into array
const oauth_parameter_string_array = [];
for (var key in oauth_parameter_string_object_ordered) {
oauth_parameter_string_array.push(`${key}=${oauth_parameter_string_object_ordered[key]}`);
}
// generate parameter string
const oauth_parameter_string = oauth_parameter_string_array.join('&');
let base_host = pm.request.url.getOAuth1BaseUrl();
let regexp = /{{(.*?)}}/g;
while (result = regexp.exec(base_host)) {
let value = pm.environment.get(result[1]);
base_host = base_host.replace(new RegExp(`{{${result[1]}}}`, 'g'), value);
}
const oauth_base_string = `${pm.request.method}&${encodeURIComponent(base_host)}&${encodeURIComponent(oauth_parameter_string)}`;
let oauth_signature = cyptojs.HmacSHA256(oauth_base_string, oauth_signing_key).toString(cyptojs.enc.Base64);
oauth_authorization_header_object.oauth_signature = encodeURIComponent(oauth_signature);
// convert object into array (for Authorization header string)
const oauth_authorization_header_array = [];
for (var key in oauth_authorization_header_object) {
oauth_authorization_header_array.push(`${key}="${oauth_authorization_header_object[key]}"`);
}
const oauth_authorization_header = oauth_authorization_header_array.join(', ');
pm.environment.set("netsuite_auth_token", 'OAuth ' + oauth_authorization_header);
// generate Authorization header, FINALLY!
pm.request.headers.add({
key: 'Authorization',
value: 'OAuth ' + oauth_authorization_header
});
console.log(pm.request);
console.log("here: " + url_query_string_array.length);
// Escape URI parameters using encodeURIComponent => RFC3986
// This is encoding the query string params in the request.
if (url_query_string_array.length !== 0) {
let request_parameter_array = [];
for (var key in url_query_string_object) {
request_parameter_array.push(key + '=' + url_query_string_object[key]);
}
const request_parameter_string = request_parameter_array.join('&');
console.log("pm.request.url.getOAuth1BaseUrl: " + pm.request.url.getOAuth1BaseUrl());
pm.request.url = pm.request.url.getOAuth1BaseUrl() + "?" + request_parameter_string;
}
Basically i try to set the OAuth section to an environment variable (netsuite_auth_token)
and then use it in the test scripts which “works” except that the signature is invalid, meaning I see data there in the request as seen below:

Here is the section from my test script calling the request:
console.log("invAcctID: " + invAcctID);
// Send the modified request
pm.sendRequest({
url: 'https://<<>>.restlets.api.netsuite.com/app/site/hosting/restlet.nl?script=<<>>&deploy=1',
method: 'POST',
header: {
'Content-Type': 'application/json',
'Authorization':pm.environment.get("netsuite_auth_token")
},
body: {
mode: 'raw', // Set mode to raw
raw: JSON.stringify({ // Set format to JSON
"searchID": '<<>>',
"searchColumn": '<<>>',
"searchValue": invAcctID
})
}
}, function (err, res) {
if (err) {
console.error(err);
return;
}
console.log(res.json());
});
}
Please advise on what I may be doing wrong. Any help is appreciated! Thanks in advance.