Skip to content

Scanning a JavaScript/TypeScript in the browser

Step 1: Download the dynamic agent archive (.tgz)

Section titled “Step 1: Download the dynamic agent archive (.tgz)”

Download the dynamic JavaScript agent package from your Lineai server:

Terminal window
wget http://your_server/lineai/server/packages/nodejscape-dynamic.tgz

Replace your_server with your Lineai server hostname.

Step 2: Ensure your app serves source maps

Section titled “Step 2: Ensure your app serves source maps”

In order to identify and match http requests to endpoints, the dynamic agent will fetch and examine your application source maps in order to connect

Step 3: Add the archive as a dependency of your project

Section titled “Step 3: Add the archive as a dependency of your project”

Move the downloaded agent tgz file to a folder you can reference from your project. Install the dynamic agent as a dependency of your project, e.g. npm install --save-dev path/to/nodejscape-dynamic.tgz

Step 3: Add a call in your code to load the archive

Section titled “Step 3: Add a call in your code to load the archive”

Add node_modules/@lineai/nodejscape-dynamic/browser/lineai-bundle.js to the files loaded when opening your application in a browser > Example: With Create React App, place a copy of > node_modules/@lineai/nodejscape-dynamic/browser/lineai-bundle.js

into the public/ folder, and then load it by adding <script src="%PUBLIC_URL%/lineai-bundle.js"></script> to public/index.html

Step 4: Add and load a configuration script to initialize The agent

Section titled “Step 4: Add and load a configuration script to initialize The agent”

To configure nodejscape-dynamic to talk to your Lineai instance, configure it in an initializing script.

<script type="text/javascript">
const NodeJSCapeDynamic = require('@lineai/nodejscape-dynamic');
const lineai = new NodeJSCapeDynamic({
lineaiHost: 'https://localhost',
agentId: '00000000-0000-0000-0000-000000000000',
password: '<password here>',
mapToIdentity: (id) => {
console.log(id);
return id;
},
});
lineai.initialize();
</script>

In many cases the browser fetches source maps from URLs that don’t map directly to the original files (e.g. src/components/foo.ts may appear to be sourced from http://static/js/opt/app/src/components/foo.ts if the app is served from a container behind a load balancer. In order to map the URL back into a file path that can be matched up to static scans of your JavaScript codebase, NodeJSCapeDynamic can accept a hook function (mapToIdentity) normalize the matched file. This function receives the file identity detected by NodeJSCapeDynamic and gives you the chance to remove parts that are specific to your deployment.

For example, if the source map identity detected by the agent is https:/localhost/app1/ui/static/js/opt/src/components/foo.ts And this corresponds to a statically scanned file src/compoents/foo.ts, you can use this function to remove the deployment-specific prefix:

mapToIdentity: (id) => {
// identify the prefix we want to remove
const matchString = 'https:/localhost/app1/ui/static/js/opt/';
const basePathIndex = id.indexOf(matchString);
// strip that prefix, if it's part of the path
const identity = basePathIndex >= 0 ? id.slice(basePathIndex + matchString.length) : id;
// return the normalized identity
return identity;
},

If you’re not sure what the source mapped file URLs will be, you can also use this function to log the identities, simply passing the detected value though. This might help in identifying the matchString you need to use in the above example.

mapToIdentity: (id) => {
console.log(`Detected identity: ${id}`);
return id;
}