db.cloud.configure()


Configure the URL of the database to keep in sync with.

Syntax

npm install dexie-cloud-addon
import Dexie from "dexie";
import dexieCloud from "dexie-cloud-addon";

const db = new Dexie("mydb", {addons: [dexieCloud]});

db.version(x).stores({
  ...
});

db.cloud.configure({
  databaseUrl: "<database URL>",
  requireAuth: true | false,
  fetchToken?: customTokenFetcher
});

Remarks

The call to db.cloud.configure() must be done before any requests are put on the db (the Dexie instance) so that the database knows what to do when before opening it the first time. See Sync flow.

Parameters

Parameter Type Explanation
databaseUrl string The URL to your cloud database
requireAuth boolean Whether or not to require authentication initially
fetchToken function Custom token fetching callback

requireAuth

If this parameter is true, the system will make sure there it has a valid authentication token before before any call to the database can proceed. In practice, this means that the user will be required to authenticate the very first time app is used on the device. Authentication token will be securely cached for 3 months unless user logs out prior to that. If looking at your progressive web app as if it was a native app, regard the authentication as a part of the installation process. Once installed, the app should continue working as expected without the need of reauthentication. This policy will be configurable in a later version. We will also be looking at ways to separate the authentication policy for read and write - you might always be able to access data, but in order to mutate data you could apply a different policy with requiring reauthentication.

fetchToken

Implement your own way of retrieving a dexie-cloud token. By default, this token will be generated by Dexie Cloud server by providing email and OTP to it. But your application may have its own way of authenticating users, or integrate with a 3rd part authentication provider. In that case you will need to implement your own server-side endpoint on a server that can authenticate your user. That server endpoint (who known your user’s identity) can then request a token from Dexie Cloud without requiring the OTP step. This needs to happen server-side because in order to request a token without going through the OTP step will require the REST client to provide your client_id and client_secret in the request. You have client_id and client_secret in the dexie-cloud.key file that was generated when you created the database. These shall never be used from client side. The key file should not be added to git either but be managed in a secure way using the cloud infrastructure of your own choice.

Example: Integrate Custom Authentication

Dexie Cloud comes with zero-config email OTP authentication but if you need to replace that with any custom authentication, you can follow this guide. By defining the fetchToken configuration parameter, you opt-out from zero-config authentication and control the the authentication flow yourself instead. The fetchToken callback needs to return a promise containin the Dexie Cloud token. That token can be retrieved over server-to-server requests towards Dexie Cloud so you will need a server endpoint to do it. You can either integrate with your existing web server or create a new server endpoint using an authentication framework of your choice, such as Node.js and Passportjs. You need to extend the existing server to respond to a new URL (let’s use /dexie-cloud-token). This new URL endpoint shall request tokens from Dexie Cloud via server-to-server communication using the logged in user and return the Dexie Cloud tokens to its client. The client of your new endpoint will be dexie-cloud client (requested from your fetchToken callback).

Node.js server endpoint

The code below examplifies how to generate tokens if your authentication solution is based on Node.js and Passport. If you have another server-side platform or language for your existing authentication, you would need to translate this example to that language and platform. Note that the authentication platform (Passport or other) can use whatever mechanism to authenticate the user - integrate with OpenIDConnect, Google, Github, facebook etc. For guides for doing so, we refer to other guides on the internet that covers this. If you are starting from a white paper and just need a way to get going, we recommend the guides from auth0 or Passport but remember that Dexie Cloud comes with zero config authentication based on one-time-passwords over email, so setting up custom authentication is just an optional next-step. Make sure to get up running Dexie Cloud with zero config authentication first.

// ...other express / passport imports and setup...

const nodeFetch = require("node-fetch");

const DB_URL = process.env.DEXIE_CLOUD_DB_URL;
const CLIENT_ID = process.env.DEXIE_CLOUD_CLIENT_ID;
const CLIENT_SECRET = process.env.DEXIE_CLOUD_CLIENT_SECRET;

// ...other express / passport endpoints here...

// The new endpoint to add:
app.post('/dexie-cloud-tokens', bodyParser.json(), async (req, res, next) => {
  try {
    // Parameters that you provide:
    // Assume you've configured passport to store user on request:
    const user = req.user; // See http://www.passportjs.org/docs/configure/
    
    // Parameters that dexie-cloud client will provide via fetchTokens option.
    const public_key = req.body.public_key; // For refresh token authentication
    
    // Request token from your Dexie Cloud database:
    const tokenResponse = await nodeFetch(`${DB_URL}/token`, {
      method: "POST",
      headers: {
        "Content-Type": "application/json",
        "Accept": "application/json"
      },
      body: JSON.stringify({
        grant_type: "client_credentials",
        scopes: ["ACCESS_DB"],
        public_key,
        client_id: CLIENT_ID,
        client_secret: CLIENT_SECRET,
        claims: {
          sub: user.userId, // or user.email. Your framework must provide this.
          email: user.email, // optional but nice.
          name: user.name // optional but nice.
        }
      });
    });
    if (!tokenResponse.ok) {
      throw new Error(`Failed to retrieve token from Dexie Cloud.`);
    }

    // Forward token response to your client:
    const tokenBody = await tokenResponse.json();
    res.set('Cache-Control', 'no-store');
    res.json(tokenBody);
  } catch (error) {
    return next(error);
  }
});

fetchToken implementation in your client code

Assuming that your server endpoint will respond to the path “/dexie-cloud-tokens” as examplified above (using whatever server side technology you have for that), the client code to integrate it will be:

db.cloud.configure({
  databaseUrl: "<database URL>",
  requireAuth: true,
  fetchToken: (tokenParams) => fetch("/dexie-cloud-tokens", {
    method: "post",
    credentials: "same-origin",
    headers: { "Content-Type": "application/json" },
    body: JSON.stringify(tokenParams)
  }).then(res => res.json())
});