Skip to main content

Official Support Articles

Search or browse our knowledge base to find answers to your questions ranging from account questions to troubleshooting error messages. The content is curated and updated by our global Support team

Announcements
NEW webinar Dec. 7th: 2023 Outlook, A Pivotal Year for Data Integration SIGN ME UP!

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

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

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)

The information in this article is provided as-is and to be used at own discretion. Depending on tool(s) used, customization(s), and/or other factors ongoing support on the solution below may not be provided by Qlik Support.

 

Environment:

Qlik Sense Enterprise on Windows 

 

Resolution

 

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)
Version history
Last update:
‎2021-05-28 07:40 AM
Updated by:
Contributors