BlackBerry Spark Communications Services Guide

Getting Started with Node.js

This overview will guide you through the steps required to integrate the BlackBerry Spark Communications Services SDK for JavaScript into your Node.js application.

See the discussion of differences between the JavaScript and other editions of the SDK.

Prerequisites

The SDK for Node.js requires:

Content Security Policy

You can use the isomorphic SDK Node.js package to create a Web application.

If you are using a Content-Security-Policy HTTPS header when serving your application, you will need to include at least the policies shown below. You will likely also include other policies in this header to allow your application to access other services such as user-authentication and user-management.

To ensure that the SDK can connect to the BlackBerry Infrastructure using the HTTPS and WSS protocols, your Content Security Policy must include:

connect-src https://*.bbmenterprise.com wss://*.bbmenterprise.com

Content Security Policy for WebAssembly

When configured to use the BlackBerry Key Management Service, the SDK for JavaScript uses a WebAssembly module to implement Argon2id key derivation. If your web application is served with the Content-Security-Policy header, you might need to work around inconsistencies in how current browsers consider WebAssembly against this header's policies. Specifically, you might need to specify script-src 'unsafe-eval'. Please refer to the documented behavior of current implementations for details on WebAssembly interactions with Content-Security-Policy in current browsers.

By default, the SDK will load the WebAssembly module needed to perform the Argon2id key derivation from argon2.wasm located alongside your Web application. In order for the SDK to be able to load this file, you must include a connect-src policy allowing the file to be loaded. For example, either of the following two policies will allow the SDK to load the WebAssembly module:

Add the SDK to your Application

  1. Download and extract the latest version of the SDK for JavaScript to your hard drive.
  2. Initialize a directory structure for your Node.js application project by running:

    npm init

    Add the bbm-enterprise Node.js package as a dependency of your application by running:

    npm install FILENAME --production

    where FILENAME is the path to the file downloaded above.

Start the SDK

In your application, import the BBMEnterprise module:

const BBMEnterprise = require('bbm-enterprise');

In your application, create a new BBMEnterprise object as shown in the example below.

// Initialize the SDK.
const bbmeSdk = new BBMEnterprise({
  // The domain that was provided to you when you registered to use the SDK.
  // This will be of the form XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX. where each
  // X is a lowercase character or number.
  domain: 'domain',

  // It is recommended that you do your development and integration testing in
  // the sandbox environment.
  environment: 'Sandbox',

  // This is the identity of the user to log in as, as provided by the
  // identity provider module.
  userId: 'identifier',

  // This function will be called as needed by the SDK to retrieve an
  // authentication token.  When a token is needed, this function should fetch
  // a new one.  The SDK will request a token once on startup, but will not
  // request again after that until the current token becomes invalid.  The
  // function should not perform caching of the token.
  getToken: () => {
    // Request a new authentication token from your identity provider and
    // return a promise that will be resolved with the fetched token or
    // rejected with an error.
  },

  // This function must be undefined to use the BlackBerry Key Management
  // Service (KMS) as your key storage solution.
  //
  // To use a custom Cloud Key Storage solution, this function must be
  // defined.
  getKeyProvider: function() {
    // Return a promise that will resolve to an object that implements the
    // interface defined by BBMEnterprise.KeyProviderInterface.
  },

  // A description of the client. This will be used to describe this endpoint
  // when using endpoint management functionality. This should never be empty.
  // The description can be a maximum of 2000 Unicode Code Points.
  description: 'node ' + process.version,

  // A friendly name in addition to the description.  The nickname is optional
  // and should be set by a user, if desired.
  nickname: 'My node client',

  // To customize how chat messages are stored, an application may configure a
  // custom storage factory function which must return an object that
  // implements the interface defined by BBMEnterprise.MessageStorageInterface.
  //
  // The SDK for JavaScript provides a few objects in the
  // BBMEnterprise.Storage namespace that already conform to the required
  // interface.  The objects will help you get started with customizing the
  // chat message storage.
  //
  // * BBMEnterprise.Storage.Immutable: This is the default factory.  It is
  //   ideal for clients that want to receive messages in an immutable list.
  //   Changes to the list must be calculated against a previous instance of
  //   the list.
  //
  // * BBMEnterprise.Storage.SpliceWatcher: This factory is ideal for clients
  //   that want to be notified about what has changed through a series of
  //   'splice' events.
  messageStorageFactory: BBMEnterprise.StorageFactory.SpliceWatcher
});

If your application is configured to use the BlackBerry Key Management Service, you must register listeners for the setupState and setupError events and then call setupStart to begin endpoint setup.

// Register to handle the setupState events.
bbmeSdk.on('setupState', state => {
  switch (state.value) {
  case BBMEnterprise.SetupState.Success:
    // Setup succeeded!  Your application can now begin using the Messenger
    // and Media interfaces.
    break;

  case BBMEnterprise.SetupState.SyncRequired: {
    // The user's keys are ready to be synced with KMS.  The syncPasscodeState
    // indicates whether or not the user has existing keys.
    switch (BBMEnterprise.syncPasscodeState) {
    case BBMEnterprise.SyncPasscodeState.New:
      // The user does not have any keys stored in KMS.  New keys will be
      // created for them using the passcode entered by the user.
      bbmeSdk.syncStart(getPasscodeFromUser(),
                        BBMEnterprise.SyncStartAction.New);
      break;

    case BBMEnterprise.SyncPasscodeState.Existing:
      // The user has existing keys stored in KMS.  To use the existing keys,
      // start the sync with 'Existing'.  To create new keys for the user,
      // start the sync with 'New'.
      bbmeSdk.syncStart(getPasscodeFromUser(),
                        BBMEnterprise.SyncStartAction.Existing);
      break;
    }
    break;
  }

  case BBMEnterprise.SetupState.SyncStarted:
    // Syncing of the keys from KMS has started.  If syncing fails, the
    // setupState will revert to 'SyncRequired' to allow your application to
    // try a new passcode or generate new keys.
    //
    // This state allows your application to track if an attempt to sync the
    // keys has been made or not.
    break;
  }
});

// Register to handle setupError events.
bbmeSdk.on('setupError', error => {
  console.log(`Endpoint setup failed: ${error.value}`);
}

// Start the SDK.
bbmeSdk.setupStart();

If your application is configured to use a custom Cloud Key Storage solution, you must call setup to begin endpoint setup.

// Start the SDK.
bbmeSdk.setup()
.then(() => {
  // Setup succeeded!  Your application can now begin using the Messenger
  // and Media interfaces.
})
.catch(error => {
  console.log(`Endpoint setup failed: ${error}`);
});