Skip to main content

Qlik Sense Repository API/Engine API(Enigma.js) example with JWT authentication: duplicate/scramble/export

No ratings
cancel
Showing results for 
Search instead for 
Did you mean: 
Damien_Villaret
Support
Support

Qlik Sense Repository API/Engine API(Enigma.js) example with JWT authentication: duplicate/scramble/export

Last Update:

Jul 26, 2023 4:06:40 AM

Updated By:

Sonja_Bauernfeind

Created date:

Jun 28, 2019 4:35:53 AM

Attachments

This article is provided as a sample on how to use the Repository API/Engine API (Enigma.js) with JWT authentication.

Workflow of the sample:

  1. Authenticate with JWT on the first call (Duplicate app) and retrieve session id
  2. Run Engine API call (Loop scramble data for each field in the app)
  3. Reuse the same session in the consequent API calls to scramble and export the app, then write it to disk.

Requirements

  1. A virtual proxy using JWT authentication with prefix "jwt" and cookie name "X-Qlik-Session-jwt" must be set up, the JWT token must be generated and placed in the variable jwttoken
  2. Node.js must be installed (This example was built and tested in version v10.16.0, there might be slight differences depending on the version)
This customization is provided as is. Qlik Support cannot provide continued support of the solution. For assistance, reach out to our Professional Services or engage in our active Integrations forum.

 

Usage

Copy the following script in a file called "scramble-jwt.js"

 

const WebSocket = require('ws');
const enigma = require('enigma.js');
const schema = require('enigma.js/schemas/12.170.2.json');
const fs = require('fs');
const rp = require('request-promise');

var servername = 'localhost';
var jwttoken = 'eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCJ9.eyJ1c2VyaWQiOiJBZG1pbmlzdHJhdG9yIiwiZG9taWQiOiJET01BSU4iLCJhZG1pbiI6dHJ1ZX0.ruQ6wbgqNsfhtnO-6g7qTxGFiq71XAtHuUZlDoZ9LjAASQUmOMksffMgoMxXxc1irCHTGcfaHYkrdghoy61JznKH31Q5AKuIpKYaD5Z6GeJJMYbw5VZO5rpT-1zznaMBUzWFMTHO7oUU_4fNc9XGxiEn-Y7hwAe2zc3vwEjBxbuY8PMZu71xGel4Vr7jHpFLWQNtJyfHQ';

var options = {
  uri: `https://${servername}/jwt/qrs/App/${process.argv[2]}/copy?xrfkey=1234567891234567`,
  headers: {'content-type': 'application/json','X-Qlik-xrfkey': '1234567891234567','Authorization': `Bearer ${jwttoken}`},
  method: 'POST',
json: true,
  rejectUnauthorized: false,
  resolveWithFullResponse: true
};
 
const qParam = {
  "qInfo": {
    "qId": "",
    "qType": "FieldList"
  },
  "qFieldListDef": {
    "qShowSystem": true,
    "qShowHidden": true,
    "qShowSemantic": true,
    "qShowSrcTables": true
  }
};
 
(async () => {
  try {

	var AppNewId = await rp(options, function (error, response, body) {
        if(error) 
        {
            console.log('Error: '+error);
        } 
        else 
        {
            return response;
        }
    });
	
	const sessionid = await AppNewId.rawHeaders.toString().split('X-Qlik-Session-jwt=')[1].split(';')[0];
	await console.log(AppNewId.body.id);
	await console.log('session id:'+sessionid);
	
	
	console.log('Connecting to engine.');
    const session = enigma.create({
	schema,
	url: `wss://${servername}/jwt/app/`,
	createSocket: url => new WebSocket(url, {
	rejectUnauthorized: false,
    headers: {
      'Cookie': `X-Qlik-Session-jwt=${sessionid}`,
		},
		}),
	});

    const qix = await session.open();
    var app = await qix.openDoc(AppNewId.body.id);
    const objsession = await app.createSessionObject(qParam);
             
    const fields = await objsession.getLayout();
    const results = fields.qFieldList.qItems;
 
    for (var p in results) {
        var myfield = JSON.stringify(results[p]['qName']).replace(/"/gi,'');
                            if (myfield.includes("$")==false){
                                          await app.scramble(myfield);
                            }
      }
 
    await app.doSave();
	
	var optionsexport = {
	uri: `https://${servername}/jwt/qrs/App/${AppNewId.body.id}/export/42754ecc-c143-4024-aa99-69d7e45a9025?skipData=false&xrfkey=1234567891234567`,
	headers: {'content-type': 'application/json','X-Qlik-xrfkey': '1234567891234567','Cookie': `X-Qlik-Session-jwt=${sessionid}`},
	method: 'POST',
	json: true,
	rejectUnauthorized: false
	};
	
	//export file
	var url = await rp(optionsexport, function (error, response, body) {
        if(error) 
        {
            console.log('Error: '+error);
        } 
        else 
        {
            return body;
        }
    });
	
	
	//download file
	var newurl = await `https://${servername}/jwt${url.downloadPath}`;
	var dest = await './scrambled_app.qvf';
	
  rp.get({
  url: newurl,
  encoding: null,
  rejectUnauthorized: false,
  headers:{'Cookie': `X-Qlik-Session-jwt=${sessionid}`}
}).then(function (res) {
	console.log(res);
	console.log(newurl);
    const buffer = Buffer.from(res, 'utf8');
	console.log(buffer);
    fs.writeFileSync(dest, buffer);
  });
 
    await session.close();
    console.log('Session closed.');
  } catch (err) {
    console.log('Whoops! An error occurred.', err);
    process.exit(1);
  }
})();

 

Copy the file in a folder and type the following commands:

 

npm install
node scramble-jwt.js da109a0e-4753-40c9-8c5f-aa8cbbb26e86

 

In the above, da109a0e-4753-40c9-8c5f-aa8cbbb26e86 is the guid of the app that you want to scramble.

 

 

Labels (1)
Comments
david_hg96
Partner - Contributor III
Partner - Contributor III

Hi! can you share the package.json file? because I'm having problems to install dependecies .

Regards

Sonja_Bauernfeind
Digital Support
Digital Support

Hello @david_hg96 

I've attached the package.json (thank you, Damien, for the assist!). You may get a warning when using it, but it is still valid.

All the best,
Sonja  

david_hg96
Partner - Contributor III
Partner - Contributor III

Hello thank you very much. I was able to run the example successfully. Greetings! excellent contribution

 

 

Contributors
Version history
Last update:
‎2023-07-26 04:06 AM
Updated by: