Getting Started with Web
This overview guides you through the steps that are required to integrate the BlackBerry Spark Communications Services SDK for JavaScript with your web application.
See the discussion of differences between the JavaScript and other editions of the SDK.
Prerequisites
The SDK requires a Web browser that offers at least the following features:
- Map
- Promise
- Set
- Object.entries and Object.values
- WebAssembly must be supported only when the SDK is configured to use the BlackBerry Key Management Service
-
Web
Crypto, specifically the following APIs and algorithms:
- RandomSource.getRandomValues
- CryptoKeyPair
- CryptoKey
- SubtleCrypto.digest with algorithms for SHA-256 and SHA-512
- SubtleCrypto.deriveBits with the ECDH algorithm using the P-521 curve
- SubtleCrypto.deriveKey with the AES-CTR, AES-GCM, ECDSA, and ECDH algorithms using the P-521 curve
- SubtleCrypto.encrypt and SubtleCrypto.decrypt with the AES-CTR and AES-GCM algorithms
- SubtleCrypto.sign and SubtleCrypto.verify with the ECDSA and HMAC algorithm
-
SubtleCrypto.importKey
and
SubtleCrypto.exportKey
using the
raw
andjwt
key formats
Your application must be served via HTTPS (and not HTTP) because the SDK uses browser features that are only available when the page is running in a secure context.
The following browsers are supported:
- Google Chrome 59 and newer
- Mozilla Firefox 53 and newer
The following browsers are supported with caveats:
- Safari 9 and newer
- Edge 16.16299 and newer
The Safari and Edge browsers are do not include the P-521 ECC algorithms
in their native WebCrypto implementation. The missing functionality can
be provided via a WebCrypto polyfill
prior to loading the bbm_sdk_web.js
script. However,
the use of polyfill is not recommended. The WebCrypto
object is globally accessible. Any polyfill used to enhance the WebCrypto
interface can be interfered with by any malicious script that can gain
access to your application. This can result in user keys being
compromised.
The SDK can be run in a web worker in any supported browser as well as in Safari (Safari is subject to the same caveat as when not running in a web worker).
You can provide a WebCrypto getRandomValues()
polyfill,
but it will likely require that you pass a secure random number generator
seed into the web worker from outside.
Cross-Origin Resource Sharing
Cross-Origin Resource Sharing (CORS) is a mechanism that allows web applications to securely access API resources served by different organizations. The BlackBerry Infrastructure and your users' web browsers use this mechanism to determine who can use your application's domain via the SDK's APIs. This helps keep your application safe from cross-origin attacks on the web.
If your application has web endpoints, you must tell the BlackBerry
Infrastructure where you will serve your application. The BlackBerry
Infrastructure will then tell your users' web browsers that same information
in API responses so that the browsers can enforce the CORS rules securely.
Your application domain must be configured with an HTTP
Access-Control-Allow-Origin
header value that
will be returned in all API responses. This value must contain your
application's Origin
, which is the scheme, host, and any
non-default port that your application is served from.
For example, if your application is served from the URL
https://example.com/application
, then your application's
Origin
is https://example.com
.
Origin
never contains any path or other URL
components. For example, it does not end with a /
and it does
not contain the /application
path component.
To configure your domain for CORS, select your application from the
BlackBerry
Online Account application list, select the Communications
Services tab, and click on Edit. Enter your application's
Origin
value in the Allowed Origin field.

You can configure a value of *
to allow your domain to be
accessed from any web site or web application. This can be useful when
developing and testing your application in the
sandbox. However, BlackBerry recommends
configuring a full Allowed Origin value even for sandbox domains
because it is more secure.
*
for
production domains.
Content Security Policy
If you are using a Content-Security-Policy
(CSP) 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 an
identity provider 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:
connect-src 'self'
connect-src https://application.example.com/path/to/argon2.wasm
Add the SDK to your Application
-
Download & Configure the latest version of the SDK for JavaScript.
-
Copy
sdk/bbm_sdk_web.js
to a location accessible by your Web application. -
If your application is going to use the BlackBerry Key Management Service, you must also copy the
sdk/argon2.wasm
file to be in the same directory as the HTML page that loads the SDK.You can use thekmsArgonWasmUrl
parameter in theBBMEnterprise
configuration
constructor argument to specify an alternate location for theargon2.wasm
file. -
Import the SDK into your Web application by including the
bbm_sdk_web.js
script in your application's HTML file.<script src="path/to/bbm_sdk_web.js"></script>
This provides access to the global
BBMEnterprise
object, which can be used to access the SDK functionality.
Authentication
Your application is responsible for providing access tokens to the SDK with
the BBMEnterprise.authTokenCallback
APIs. These tokens are used to identify, authenticate, and authorize your
users.
As described in the Identity
Providers guide, you can configure your domain in the sandbox to have
user authentication disabled. Your application must still provide tokens
using the BBMEnterprise.authTokenCallback
APIs, but instead of getting them from a real identity provider, your
application generates its own unsigned JWT tokens.
By default, all examples expect your domain to have user authentication disabled. Some examples may optionally be configured to use Google Sign-In or Azure Active Directory as an identity provider.
Key Management
By default, all examples use the BlackBerry Key Management Service which provides automatic management and synchronization of keys. The Support library comes with code that you can use for using Cloud Key Storage with Google Firebase or Azure Cosmos DB.
Start the SDK
In your application, create a new BBMEnterprise
object as
shown in the example below.
// Create the MockAuthManager that will generate unsigned JWT tokens for our // sandbox domain that has user authentication disabled. This example only // returns a fixed user ID. A real application would determine the user ID // through user interaction or other means. const mockAuthManager = new MockAuthManager(); mockAuthManager.getUserId = () => Promise.resolve('user1'); // Immediately invoke that getUserId() function and resolve its promise. const localUserInfo = await mockAuthManager.authenticate(); // Initialize the SDK. const sdk = 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', // The user ID of the identity that is using the SDK. In this example, it // comes from the localUserInfo returned by the MockAuthManager. userId: localUserInfo.userId, // This function is called when the SDK needs an access token. Your // application must return a promise of the new access token. In this // example, access tokens are supplied by the MockAuthManager. getToken: () => mockAuthManager.getBbmSdkToken(), // 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: navigator.userAgent, // A friendly name in addition to the description. The nickname is optional // and should be set by a user, if desired. nickname: 'My web client', });
BlackBerry Key Management Service
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.
The following code shows how to handle these events.
getPasscode()
that returns a promise of the passcode that
protects the user's keys.
// Register to handle the setupState events. sdk.on('setupState', async (state) => { try { 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 (sdk.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. sdk.syncStart(await getPasscode(), 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'. sdk.syncStart( await getPasscode(), 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; } } // Handle getPasscode() promise rejections. catch(error) { // Handle the error appropriately. console.error(`Endpoint setup failed: ${error}`); } }); // Register to handle setupError events. sdk.on('setupError', error => { console.log(`Endpoint setup failed: ${error.value}`); }); // Start the SDK. sdk.setupStart();
Cloud Key Storage
If your application is configured to use Cloud Key Storage, you must start the SDK differently.
You must define the getKeyProvider()
function as a property of
the BBMEnterprise
configuration
constructor
argument. You must write this function.
// If your application uses Cloud Key Storage, you must define this function. getKeyProvider: function() { // You must return a promise that will resolve to an implementation of // BBMEnterprise.KeyProviderInterface. return Promise.reject(new Error('You must implement getKeyProvider().')); }
You must call setup()
to begin endpoint setup.
// Start the SDK. sdk.setup() .then(() => { // Setup succeeded! Your application can now begin using the Messenger // and Media interfaces. }) .catch(error => { console.log(`Endpoint setup failed: ${error}`); });
Exploring the Examples
The SDK for JavaScript has example applications that are web applications that need to be served by a web server as standard HTML, JavaScript, CSS, and image files with the correct MIME types.
The simplest configuration is to simply have your web server serve the
entire content of the expanded SDK archive, including the sdk
and examples
directories. The example applications expect
those two directories to be siblings in the served content.
To use the examples that do not come in the SDK package, clone them from
GitHub and add a symlink to the support
directory that comes in
the SDK's examples
directory. This will allow these examples to
find both the Support library and the SDK itself within the served
content.
cd blackberry-spark-communications-services-sdk-web-* git clone https://github.com/blackberry/BlackBerry-Communication-Services-Examples.git github-examples ln -s ../examples/support github-examples/javascript/support
The README files that come with each of the web example applications explain how to configure and run them.