IBM Support

QJSLib - Javascript Library

How To


Summary

The App Framework JavaScript library provides helper functions for common QRadar calls that you can integrate into your own scripts.

Steps

The helper functions that are included in the App Framework JavaScript library (QJSLib) can be used to do the following tasks:

  • Get information on the current application, user, item, or selected table rows.
  • Open the Details page for an asset.
  • Search for an event or flow by using a specified AQL query.
  • Open the Details page for an offense.
  • Call a REST method by using an XMLHttpRequest.
  • Retrieve named services and named service endpoints.

For a full list of QJSLib functionality and a reference of available functions, see the QJSLib GitHub wiki.

Importing QJSLib

There are two ways to import QJSLib; either as a dependency referenced directly in the HTML and loaded through the browser, or bundled up with webpack as a packaged dependency with your JavaScript bundle; imported with NPM.

The following tutorials will explain and showcase each approach.

Browser Script

This tutorial requires the following dependencies:

  • QRadar App SDK v2

Create the Browser App

Create a new folder for the app:

mkdir QJSLibBrowser && cd QJSLibBrowser

Use the QRadar App SDK to initialise the app code:

qapp create

Write the Browser App Manifest

Open the manifest.json file to edit some values to make it more relevant to the app, making it look like this:

{
  "name": "QJSLib as a browser import",
  "description": "App showing how to use QJSLib imported in the browser",
  "version": "1.0.0",
  "image": "qradar-app-base:2.0.0",
  "areas": [
    {
      "id": "QQJSLibBrowser",
      "text": "QJSLib",
      "description": "Area displaying QJSLib functionality",
      "url": "index",
      "required_capabilities": []
    }
  ],
  "uuid": "<your unique app UUID>"
}

This manifest defines an area called QQJSLibBrowser that will serve the app user interface.

Write the Browser App HTML

Delete app/templates/hello.html and create a new file app/templates/index.html:

<!DOCTYPE html>
<html>
  <head>
    <title>QJSLib as a browser import</title>
  </head>
  <body>
    <h1>QJSLib as a browser import</h1>
    <p id="qjslib-load-status">QJSLib not loaded</p>
    <p id="current-user-label">
      Currently logged in as: <span id="current-user"></span>
    </p>
    <p id="installed-apps-label">
      Installed apps:
      <ul id="installed-apps"></ul>
    </p>
    <script src="./static/qjslib/qappfw.min.js"></script>
    <script src="./static/main.js"></script>
  </body>
</html>

This HTML defines some places for us to modify with our JavaScript, adding in values retrieved using QJSLib - such as the currently logged in user, and a list of all installed apps.

The HTML also handles loading both the QJSLib script from app/static/qjslib/qappfw.min.js and the app JavaScript file from app/static/main.js.

Write the Browser App Endpoint

Add the app HTTP endpoint by editing app/views.py:

from flask import Blueprint, render_template

# pylint: disable=invalid-name
viewsbp = Blueprint('viewsbp', __name__, url_prefix='/')


# Simple endpoint that returns index.html, all work is done client side
# with QJSLib
@viewsbp.route('/index')
def index():
    return render_template('index.html')

This sets up the app /index endpoint to return app/templates/index.html.

Write the Browser JavaScript

Add the app JavaScript by creating app/static/main.js:

const QRadar = window.qappfw.QRadar;

const loadField = document.getElementById("qjslib-load-status");
const currentUserField = document.getElementById("current-user");
const installedAppsList = document.getElementById("installed-apps");

QRadar.fetch("/api/gui_app_framework/applications")
    .then(function(response)  { return response.json() })
    .then(function(apps) {
        for (const app of apps) {
            const appItem = document.createElement('li');
            appItem.appendChild(document.createTextNode(app.manifest.name));
            installedAppsList.appendChild(appItem);
        }
    })
    .catch(function(error) { alert(error) });

const currentUser = QRadar.getCurrentUser()
currentUserField.innerText = currentUser.username;

loadField.innerText = "QJSLib loaded successfully"

This Javascript will first reassign the QJSLib library from the global window scope into QRadar for easier use, and then will get HTML elements from the page which are referenced later.

The JavaScript then makes a number of calls using QJSLib, assigning the output to the HTML elements retrieved earlier. This includes an asynchronous HTTP request using QRadar.fetch.

Run the Browser App/Package the Browser App

The app can then be run locally with:

qapp run

Or packaged and deployed with:

qapp package -p <app zip name>

qapp deploy -p <app zip name> -q <qradar console> -q <qradar user>

NPM Package Bundled with Webpack

This tutorial requires the following dependencies:

  • QRadar App SDK v2
  • NodeJS
  • NPM

Create the NPM App

Create a new folder for the app:

mkdir QJSLibNPM && cd QJSLibNPM

Use the QRadar App SDK to initialise the app code:

qapp create

Set up NPM and Webpack

To set up NPM and webpack for handling JavaScript dependencies and bundling, follow these steps:

npm init

This command will ask a number of questions for setting up your project, answer them and then a package.json will be generated.

Next, add QJSLib as a dependency:

npm install qjslib

Then add webpack as development dependencies:

npm install webpack webpack-cli --save-dev

Then configure webpack by creating a webpack.config.js:

const path = require('path');

module.exports = {
    entry: './src/index.js',
    output: {
        filename: 'main.js',
        path: path.resolve(__dirname, 'app/static'),
    },
};

This configures webpack to take the src/index.js file and bundle any of its, dependencies into app/static/main.js.

Finally configure your package.json so it looks something like this:

{
  "name": "qjslib_npm",
  "version": "1.0.0",
  "description": "Sample app showing how to use QJSLib imported as an NPM package",
  "main": "src/index.js",
  "scripts": {
    "build": "webpack --mode=development"
  },
  "author": "IBM",
  "license": "GSA ADP",
  "dependencies": {
    "qjslib": "^1.1.0"
  },
  "devDependencies": {
    "webpack": "^4.44.1",
    "webpack-cli": "^3.3.12"
  }
}

The key field here is:

  "scripts": {
    "build": "webpack --mode=development"
  },

Which allows us to easily build our app's JavaScript.

Write the NPM App Manifest

Open the manifest.json file to edit some values to make it more relevant to the app, making it look like this:

{
  "name": "QJSLib as an NPM package",
  "description": "App showing how to use QJSLib imported as an NPM package",
  "version": "1.0.0",
  "image": "qradar-app-base:2.0.0",
  "areas": [
    {
      "id": "QQJSLibNPM",
      "text": "QJSLib",
      "description": "Area displaying QJSLib functionality",
      "url": "index",
      "required_capabilities": []
    }
  ],
  "uuid": "<your unique app UUID>"
}

This manifest defines an area called QQJSLibNPM that will serve the app user interface.

Write the NPM App HTML

Delete app/templates/hello.html and create a new file app/templates/index.html:

<!DOCTYPE html>
<html>
  <head>
    <title>QJSLib as an NPM package</title>
  </head>
  <body>
    <h1>QJSLib as an NPM package</h1>
    <p id="qjslib-load-status">QJSLib not loaded</p>
    <p id="current-user-label">
      Currently logged in as: <span id="current-user"></span>
    </p>
    <p id="installed-apps-label">
      Installed apps:
      <ul id="installed-apps"></ul>
    </p>
    <script src="static/main.js"></script>
  </body>
</html>

This HTML defines some places for us to modify with our JavaScript, adding in values retrieved using QJSLib - such as the currently logged in user, and a list of all installed apps.

Write the NPM App Endpoint

Add the app HTTP endpoint by editing app/views.py:

from flask import Blueprint, render_template

# pylint: disable=invalid-name
viewsbp = Blueprint('viewsbp', __name__, url_prefix='/')


# Simple endpoint that returns index.html, all work is done client side
# with QJSLib
@viewsbp.route('/index')
def index():
    return render_template('index.html')

This sets up the app /index endpoint to return app/templates/index.html.

Write the NPM JavaScript

Add the app JavaScript by creating src/index.js:

import { QRadar } from "qjslib";

const loadField = document.getElementById("qjslib-load-status");
const currentUserField = document.getElementById("current-user");
const installedAppsList = document.getElementById("installed-apps");

QRadar.fetch("/api/gui_app_framework/applications")
    .then((response) => response.json())
    .then((apps) => {
        for (const app of apps) {
            const appItem = document.createElement('li');
            appItem.appendChild(document.createTextNode(app.manifest.name));
            installedAppsList.appendChild(appItem);
        }
    })
    .catch((error) => alert(error));

const currentUser = QRadar.getCurrentUser()
currentUserField.innerText = currentUser.username;

loadField.innerText = "QJSLib loaded successfully"

This JavaScript file will be transpiled and bundled at build time into app/static/main.js, with QJSLib bundled up with it.

This Javascript first loads the QJSLib library for use in this script:

import { QRadar } from "qjslib";

The JavaScript then makes a number of calls using QJSLib, assigning the output to the HTML elements retrieved earlier. This includes an asynchronous HTTP request using QRadar.fetch.

Run the NPM App/Package the NPM App

The app can then be run locally with:

npm run build && qapp run

Or packaged and deployed with:

npm run build && qapp package -p <app zip name>

qapp deploy -p <app zip name> -q <qradar console> -q <qradar user>

Document Location

Worldwide

[{"Line of Business":{"code":"LOB24","label":"Security Software"},"Business Unit":{"code":"BU059","label":"IBM Software w\/o TPS"},"Product":{"code":"SSBQAC","label":"IBM Security QRadar SIEM"},"ARM Category":[{"code":"a8m0z000000cwt3AAA","label":"QRadar Apps"}],"ARM Case Number":"","Platform":[{"code":"PF025","label":"Platform Independent"}],"Version":"All Version(s)"}]

Document Information

Modified date:
30 March 2021

UID

ibm16437465