Pre-request script in outbound REST?

conanlloyd
Giga Guru

Good afternoon all.  I am trying to connect to Absolute's API from my instance.  Yes, I know that there is their connector app and we do have it installed but it does not pull in the specific data I need.

 

By following their documentation, I was able to successfully make a call with Postman and get data.  I was able configure it to get the exact data I wanted. However, their instructions use a Pre-request Script and an entry of {{jwsReq}} in the body, which has to be set to raw.  You then use that in a POST to https://api.absolute.com/jws/validate

 

I have no idea how to replicate this inside ServiceNow

 

Can anyone help me set this up?  I don't care if it is in an outbound Rest call, script include, or whatever.

 

Pre-Request script from Postman:

 

// Fill in the token ID for your API token
var tokenId ="MY TOKEN ID HERE"
// Fill in the secret key for your API token
var tokenSecret = "MY SECRET HERE";

// Call crypto JavaScript library
pm.sendRequest({
    url: "https://raw.githubusercontent.com/AbsoluteSoftware/jsrsasign/10.4.0/jsrsasign-all-min.js", // PM dynamic var
    method: "GET",
    header: {
        "Content-Type": "application/javascript; charset=utf-8"
        }
    },
    function (err, res) {
        console.log("Loaded jsrsasign");
        generateRequest(res.text())
    });

var navigator = {};
var window = {};

// Code snippet from "Update the request example" defining the "generateRequest" function goes here ...
function generateRequest(jsLib) {
    let request = {
        kid : tokenId,
        method : "GET",
        contentType: "application/json",
        uri: "/v3/reporting/devices",
        // The queryString is URL encoded
        queryString: "deviceName=MY DEVICE NAME HERE&agentStatus=A&select=deviceName%2CagentStatus%2Cusername%2CcurrentUsername%2ClastConnectedDateTimeUtc%2ClastUpdatedDateTimeUtc&sortBy=esn%3Adesc",
        //For GET requests, the payload is empty
        payload: ""
    };
    callPublicApi(jsLib, request);
}

function callPublicApi(jsrasign, request) {
    eval(jsrasign);

    // Prepare timestamp in milliseconds (In UTC/ISO format)
    var issuedAt = Math.floor(Date.now() + 60*1000)
    // Set headers for JWT
    var header = {
        'alg': 'HS256',
        'kid' : request.kid,
        'method' : request.method,
        'content-type': request.contentType,
        'uri': request.uri,
        'query-string': request.queryString,
        'issuedAt' : issuedAt
    };

    // Wrap the payload in the "data" key
    var data = {
       'data': request.payload
    };

    var sHeader = JSON.stringify(header);
    var sPayload = JSON.stringify(data);

    var sJWT = KJUR.jws.JWS.sign(header.alg, sHeader, sPayload, tokenSecret);
    console.log('Signed and encoded JWT', sJWT)
    pm.environment.set('jwsReq',sJWT);
}

 

2 REPLIES 2

Tony Chatfield1
Kilo Patron

Hi, I would look at building a non-scripted Postman solution first, and then use that as a reference to build using the ServiceNow RESTV2 API

RESTMessageV2 | ServiceNow Developers

That's what I'm hoping to do but have no idea how to translate that script they provided in their documentation to basic Postman.