Tips to start using the NodeJS SDK

I am a novel NodeJS developer… and are familiar with using the npm modules to import packages.

However… I am not sure if this approach can be used to import the Open Ziti NodeJS package.

Any tips?

Once I understand this, I will tackle making ZAC dark… this was my first hurdle to get over.

Hi Scott,

Installing the NodeJS SDK is done using the following cmd:

npm i ziti-sdk-nodejs

Just make sure the version of NodeJS you are running at the time is v14.x.

The above cmd will download and install the appropriate package for the OS, architecture, and NodeJS version you are running. I have not yet shipped packages for NodeJS versions newer than 14.x, so if you are running on one of those, the install attempt will not find the binary package, and will fail.

1 Like

Super awesome… I will be testing this out today :slight_smile:

Quick update… I have the SDK installed… and found some of the sample test scripts

I am a bit stuck with the following file


I have made it this far…

node https-test.js /Users/houst/.zssh/zssh.json

but are still missing the host and path.

I am not really sure what this script is doing… or what I need to have setup for it to work… though I am certainly closer than at the start of the day.

Let me know if you have any tips on next steps.

PS… once I get this working… I should be able to identify what to modify in ZAC to make it dark :slight_smile:

PS… this is a summary of the steps taken…

  1. reset NPM to version 14…
  2. run npm i ziti-sdk-nodejs to install the SDK…
  3. copy and paste the package.json from the SDK folder
  4. run npm install to install all of the dependencies

I also found some good references here
ziti-sdk-nodejs - npm

PS… after a bit more playing around… it would be good to know how to define the ziti_options

When I run a test file as follows

node hello_after.js /Users/houst/.zssh/zssh.json httpzitified

I get the following error

load_config(options->config, &cfg) => -13 (Configuration is invalid)

@markamind You may also find this example Node.JS app instructive because it is published along with the CI steps necessary to build that particular app.

1 Like

Super helpful. Thanks

@markamind you referenced https-test.js:

The tests/https-test.js script is a small testing tool used by sdk developers to sanity check the SDK during development.

Here is an example of how to run it:

  1. cd to top-level ziti-sdk-nodejs dir

  2. npm i (to ensure module ‘@mapbox/node-pre-gyp’ is installed; this module is used by the script)

  3. node tests/https-test.js /path/to/identity.json "http://somehost/:8065" GET

The identity.json should be for an enrolled identity on the Ziti network.
The somehost/:8065 should be for a service on the ZIti network that maps to some web server.

When you have everything properly set up, running the script should produce output resembling the following:

{9:02}~/Repos/nf/github/ziti-sdk-nodejs:main ✓ ➭ node tests/https-test.js /Users/curt/Repos/nf/github/ziti-http-agent/identity/ziti-http-agent.json "http://mattermost-blue/:8065" GET
[        0.000] INFO	ziti-sdk-nodejs/src/ziti-add-on.c:62 Init(): Ziti NodeJS SDK version
	Version:	0.4.0
	Build Date:	Tue May 3 16:52:36 UTC 2022
	Git Branch:	main
	Git SHA:	ff5bc3e
	OS:     	macOS
	Arch:   	x64
	@ff5bc3e(main) starting at (2022-06-06T13:02:18.870)
[        0.003]    INFO ziti-sdk:ziti.c:391 ziti_init_async() ztx[0] Ziti C SDK version 0.28.0-109 @17cf053(HEAD) starting at (2022-06-06T13:02:18.874)
[        0.003]    INFO ziti-sdk:ziti.c:392 ziti_init_async() ztx[0] using uv_mbed[v0.14.4], tls[OpenSSL 1.1.1m  14 Dec 2021]
[        0.003]    INFO ziti-sdk:ziti.c:393 ziti_init_async() ztx[0] Loading from config[/Users/curt/Repos/nf/github/ziti-http-agent/identity/ziti-http-agent.json] controller[https://ziti-edge-controller:1280]
[        0.003]    INFO ziti-sdk:ziti_ctrl.c:375 ziti_ctrl_init() ctrl[ziti-edge-controller] ziti controller client initialized
[        0.003]    INFO ziti-sdk:ziti.c:779 ziti_re_auth_with_cb() ztx[0] starting to re-auth with ctlr[https://ziti-edge-controller:1280] api_session_status[0] api_session_expired[TRUE]
[        0.029]    INFO ziti-sdk:ziti.c:1424 version_cb() ztx[0] connected to controller https://ziti-edge-controller:1280 version v0.25.9(92d702a804a1 2022-05-23T17:30:18Z)
[        0.123]    INFO ziti-sdk:ziti.c:1314 ziti_set_api_session() ztx[0] api session set, setting api_session_timer to 540s
[        0.124] INFO	ziti-sdk-nodejs/src/ziti_init.c:130 on_ziti_event(): controller version = v0.25.9(92d702a804a1)[2022-05-23T17:30:18Z]
[        0.124] INFO	ziti-sdk-nodejs/src/ziti_init.c:131 on_ziti_event(): identity = <ziti-http-agent>[Wkx72Cu.U]@https://ziti-edge-controller:1280
No 'body' will be sent
[        0.127]    INFO ziti-sdk:channel.c:219 new_ziti_channel() ch[0] (ziti-edge-router-wss@tls://ziti-edge-router-wss:3024) new channel for ztx[0] identity[ziti-http-agent]
[        0.128] INFO	ziti-sdk-nodejs/src/ziti_init.c:178 on_ziti_event(): edge router ziti-edge-router-wss@tls://ziti-edge-router-wss:3024 was added
[        0.127]    INFO ziti-sdk:channel.c:733 reconnect_channel() ch[0] reconnecting NOW
headers ([ [length]: 0 ])
inside JS Ziti_http_request(), req is (0)
inside JS main(), req is (0)
headers ([ [length]: 0 ])
inside JS Ziti_http_request(), req is (0)
[        0.130]    INFO ziti-sdk:posture.c:197 ziti_send_posture_data() ztx[0] first run or potential controller restart detected
inside JS main() setTimeout(), req is (0)
headers ([ [length]: 0 ])
inside JS Ziti_http_request(), req is (0)
inside JS main() setTimeout(), req is (0)
headers ([ [length]: 0 ])
inside JS Ziti_http_request(), req is (0)
inside JS main() setTimeout(), req is (0)
----------- Now inside Ziti_http_request on_req callback ----------, obj is:
{ req: 105553118396480 }
----------- Now inside Ziti_http_request on_req callback ----------, obj is:
{ req: 105553118396576 }
----------- Now inside Ziti_http_request on_req callback ----------, obj is:
{ req: 105553118396672 }
----------- Now inside Ziti_http_request on_req callback ----------, obj is:
{ req: 105553118396768 }
[        0.150]    INFO ziti-sdk:channel.c:629 hello_reply_cb() ch[0] connected. EdgeRouter version: v0.0.0|local|2020-01-01 01:01:01|darwin|arm64
[        0.150] INFO	ziti-sdk-nodejs/src/ziti_init.c:166 on_ziti_event(): ziti connected to edge router ziti-edge-router-wss@tls://ziti-edge-router-wss:3024
version = v0.0.0|local|2020-01-01 01:01:01|darwin|arm64
----------- Now inside Ziti_http_request on_resp callback ----------, obj is:
  req: 105553171890176,
  code: 200,
  status: 'OK',
  headers: {
    Date: 'Mon, 06 Jun 2022 13:02:19 GMT',
    'X-Version-Id': '',
    'X-Request-Id': 'fq9gstjqt3yizbzxe3mc3xtufa',
    'X-Frame-Options': 'SAMEORIGIN',
    'Last-Modified': 'Wed, 01 Jun 2022 12:23:06 GMT',
    'Content-Type': 'text/html; charset=utf-8',
    'Content-Security-Policy': "frame-ancestors 'self'; script-src 'self'",
    'Content-Length': '3122',
    'Cache-Control': 'no-cache, max-age=31556926, public',
    'Accept-Ranges': 'bytes'
----------- Now inside Ziti_http_request on_resp_data callback ----------, obj is:
  req: 105553171890176,
  len: 3122,
  body: <Buffer 3c 21 64 6f 63 74 79 70 65 20 68 74 6d 6c 3e 3c 68 74 6d 6c 20 6c 61 6e 67 3d 22 65 6e 22 3e 3c 68 65 61 64 3e 3c 6d 65 74 61 20 63 68 61 72 73 65 74 ... 3072 more bytes>
----------- obj.body is:
<!doctype html><html lang="en"><head><meta charset="utf-8"><meta name="viewport" content="width=device-width,initial-scale=1,maximum-scale=1,user-scalable=0"><meta name="robots" content="noindex, nofollow"><meta name="referrer" content="no-referrer"><title>Mattermost</title><meta name="mobile-web-app-capable" content="yes"><meta name="application-name" content="Mattermost"><meta name="format-detection" content="telephone=no"><link rel="icon" type="image/png" href="/static/images/favicon/favicon-default-16x16.png" sizes="16x16"><link rel="icon" type="image/png" href="/static/images/favicon/favicon-default-24x24.png" sizes="24x24"><link rel="icon" type="image/png" href="/static/images/favicon/favicon-default-32x32.png" sizes="32x32"><link rel="icon" type="image/png" href="/static/images/favicon/favicon-default-64x64.png" sizes="64x64"><link rel="icon" type="image/png" href="/static/images/favicon/favicon-default-96x96.png" sizes="96x96"><link rel="stylesheet" class="code_theme"><style>.error-screen{font-family:'Helvetica Neue',Helvetica,Arial,sans-serif;padding-top:50px;max-width:750px;font-size:14px;color:#333;margin:auto;display:none;line-height:1.5}.error-screen h2{font-size:30px;font-weight:400;line-height:1.2}.error-screen ul{padding-left:15px;line-height:1.7;margin-top:0;margin-bottom:10px}.error-screen hr{color:#ddd;margin-top:20px;margin-bottom:20px;border:0;border-top:1px solid #eee}.error-screen-visible{display:block}</style><meta http-equiv="Content-Security-Policy" content="script-src 'self'"><script defer="defer" src="/static/main.92f5b46dd5c8dbcfab6b.js"></script><link href="/static/main.0b393c15ad8879ca188d.css" rel="stylesheet"><meta name="apple-mobile-web-app-title" content="Mattermost" /><meta name="apple-mobile-web-app-capable" content="yes" /><meta name="apple-mobile-web-app-status-bar-style" content="default" /><link rel="apple-touch-icon" sizes="76x76" href="/static/icon_76x76.png" /><link rel="apple-touch-icon" sizes="72x72" href="/static/icon_72x72.png" /><link rel="apple-touch-icon" sizes="60x60" href="/static/icon_60x60.png" /><link rel="apple-touch-icon" sizes="57x57" href="/static/icon_57x57.png" /><link rel="apple-touch-icon" sizes="152x152" href="/static/icon_152x152.png" /><link rel="apple-touch-icon" sizes="144x144" href="/static/icon_144x144.png" /><link rel="apple-touch-icon" sizes="120x120" href="/static/icon_120x120.png" /><link rel="manifest" href="/static/manifest.json" /></head><body class="font--open_sans enable-animations"><div id="root"><div class="error-screen"><h2>Cannot connect to Mattermost</h2><hr/><p>We're having trouble connecting to Mattermost. If refreshing this page (Ctrl+R or Command+R) does not work, please verify that your computer is connected to the internet.</p><br/></div><div class="loading-screen" style="position:relative"><div class="loading__content"><div class="round round-1"></div><div class="round round-2"></div><div class="round round-3"></div></div></div></div><div id="root-portal"></div><noscript>To use Mattermost, please enable JavaScript.</noscript></body></html>

@markamind you mentioned

I should be able to identify what to modify modify in ZAC to make it dark

It should be noted that although the current ziti-sdk-nodejs has support to dial out to services, it does not yet have the support needed to host a service.

If you wanted to Zitify the ZAC such that it was capable of receiving incoming Ziti connect attempts, you will need to host a service.

Future releases of the ziti-sdk-nodejs will be able to do that, but not today.

1 Like

Thanks Clint… this is very helpful…

I was not aware that the SDKs could not host a service…

which brings me back to a backup plan for making ZAC dark

put it behind a reverse proxy of which I already have a solution for.

I will set this up and give it a shot to see how it performs… which makes one more port that I can close on my dev / test env :slight_smile:

Most of the SDKs can host services. Just not ziti-sdk-nodejs (yet)

1 Like

Great news… please advise when this is available so that I can get back to this.


I will be releasing new versions of the NodeJS SDK this week that have the ability to host services.

What’s more is I am also looking at ways of making it easy to host a Ziti service in a Node/Express app (e.g. the ZAC).

I’ll be back in touch again soon.

1 Like