Neurotic Pantaloon Maker
Share your code. npm Orgs help your team discover, share, and reuse code. Create a free org »

documentdb-session

1.0.1 • Public • Published

documentdb-session

npm npm Build Status David GitHub issues GitHub license

GitHub forks GitHub stars GitHub watchers GitHub followers

An Azure DocumentDB store for express-session.

Overview

Used in conjunction with the express-session package, documentdb-session saves and retrieves your session data (req.session) to and from DocumentDB, Microsoft Azure's NoSQL database service.

Features:

  • Works with partitioned or single-partition collections.

  • Session data can be stored in an existing collection along with other data, or reside in its own collection.

  • Supports an optional TTL (time-to-live / expiration) for session data.

  • Supports all required, recommended, and optional methods for a session store, as outlined by express-session's specification.

  • Makes the DocumentDB document ID for the session the same as the session ID. This makes it easy to look up sessions in your database, and helps with debugging.

  • Provides an optional .initialize() method if you'd like to initialize your database, collection, and stored procedures before making your first request, allowing you to check for errors before making other requests (otherwise the database will be initialized on the first request).

Install

npm install --save documentdb-session

Typical Usage

const DocumentDBSession = require('documentdb-session');
const express = require('express');
const session = require('express-session');
 
// pass the express-session object to documentdb-session
const DocumentDBStore = DocumentDBSession(session);
 
// you could pass the express-session object when you require the module if you'd prefer:
// const DocumentDBStore = require('documentdb-session')(session);
 
const config = {
  host: `https://mydbaccount.documents.azure.com:443/`,
  key:  '8idtLLsiRJsKvgHLi...vgOJ9YXTTYK61LX15pobbmQ==',
  ttl:  28800 // expire document in 8 hours (in seconds)
};
 
const app = express();
 
app.use(session({
  cookie: {
    maxAge: 28800000, // expire cookie in 8 hours (in milliseconds),
  },
  resave: false,
  saveUninitialized: false,
  secret: 'mycookiesecret',
  store: new DocumentDBStore(config) // pass the DocumentDB session store to express-session
}));

Config Options

Option Default Description
collection "sessions" The ID of the collection where the session data should be stored. If the collection does not exist, it will be created when the session store initializes. The collection may contain other data, or it may be a dedicated collection just for sessions.
database "sessionstore" The ID of the database where the session data should be stored. If the database does not exist, it will be creaed when the session store initializes.
discriminator { type: "session" } By default, documentdb-session sets a "type" attribute on each session document with a value of "session", to distinguish session documents from other documents in the collection. If you would like a different attribute or value to be used to discriminate session documents from other documents, enter that as an attribute-value pair in an object here, e.g. { site: "mysite.com" } or { _type: "session" }.
host (required) none The URL / hostname of your DocumentDB database account, usually of the form https://mydbaccount.documents.azure.com:443/. You can also provide this in an environment variable, (DOCUMENTDB_URL) instead.
key (required) none The primary key for your DocumentDB account. A primary key is required because documentdb-session may create a new database for your account, if none exists. You can also provide this in an environment variable (DOCUMENTDB_KEY) instead.
ttl none The TTL (time-to-live or expiration time) for your sessions, in seconds. After this time has elapsed since the last change to the session data, the session will be deleted. A session's TTL is extended each time session data is changed, restarting the timer. See more on Configuring TTL below. Enabling TTL is strongly recommended.

NB: If you'd like to more fully customize the settings for the collection where your session data is stored (e.g. the connection policy and consistency level), you can create the collection in advance, and simply provide the ID of that collection in the collection config parameter. documentdb-session will then use that collection's settings.

Configuring TTL (Time-to-Live or Expiration Time)

Because sessions are generally short-lived, and because your application will be creating new sessions frequently, it is a good idea to automatically delete sessions once they have been inactive for a certain period of time. That period of time is the time-to-live or TTL for a session, and typically you will want this value to be the same as the maxAge value of the session cookie. There are two recommended strategies for using TTL with sessions:

1. Set a default TTL for the entire collection

Choose this option if sessions are the only type of document in your collection. This will automatically delete every document in the collection once it has been inactive (not changed or updated) for the time specified by the TTL. If you choose this option, you do not need to set the ttl config property in documentdb-session.

Important: If you have other, non-session data in your collection, do not set a default TTL for the collection, or ALL your documents will be deleted once they expire.

You can set a default TTL for the collection either by calling the .replaceCollection() method of the DocumentDB Node.js SDK and including an attribute "defaultTtl": {your TTL, in seconds}, or by going to the Settings blade for the collection in the Azure Portal and choosing On and providing a default value.

2. Only set a TTL for session documents

Choose this option if you will be storing other kinds of data besides just sessions in your collection. With this option, each session document will be given a ttl attribute with the value you specify in the documentdb-session config object (see the config options above). The session documents will be deleted after they expire, but not the other documents in your collection (unless they also have a ttl property on them).

To configure TTL for session documents, include a value for ttl in the documentdb-session config object, and make sure that your collection has TTL enabled, but without a default expiration time. documentdb-session will not enable TTL on the collection unless it creates the collection during initialization; if you created your own collection, you will need to enable TTL manually.

To enable TTL without a default expiration, either call the .replaceCollection() method of the DocumentDB Node.js SDK and include an attribute "defaultTtl": -1, or go to the Settings blade for the collection in the Azure Portal and select On (no default).

(You can read more about DocumentDB's TTL feature here.)

Working with Partitioned Collections

If you use partitioned collections, you can enable partitioning in the same way that you would enable it using the DocumentDB Node.js SDK. The session store instance exposes the DocumentDB SDK's DocumentClient object (as .client), which you can use to register your partition resolver. A short example is below, and you can see a more complete example of using a partition resolver here.

const documentdb = require('documentdb');
const DocumentDBStore = require('documentdb-session');
 
const store = new DocumentDBStore({ /* config options */ });
 
const PartitionResolver = documentdb.HashPartitionResolver;
 
const databaseLink = 'dbs/mysessionsdb';
const coll1 = `${databaseLink}/colls/coll1`;
const coll2 = `${databaseLink}/colls/coll2`;
 
const partitionFunction = doc => {
  /* your partition function */
};
 
const resolver = new PartitionResolver(partitionFunction, [coll1, coll2]);
 
store.client.partitionResolvers[databaseLink] = resolver;

API

documentdb-session follows the specification for session stores given by express-session. It includes all required, recommended, and optional methods, as well as a few extra convenience methods.

DocumentDBSession

The DocumentDBSession method is exposed by requiring documentdb-session. Calling this function and passing it the express-session instance will return the DocumentDBStore constructor. Example use:

const session = require('express-session');
const DocumentDBStore = require('documentdb-session')(session);
const store = new DocumentDBStore({ /* config options */ });

DocumentDBStore

The DocumentDBStore constructor exposed by documentdb-session is used to create a new instance of a session store object. Calling this function and passing it an object with config options will return the new DocumentDB store object. This may then be passed to express-session. See the Typical Usage and DocumentDBSession sections above for examples.

store.client

The DocumentDB DocumentClient object from the Node.js SDK (complete documentation here). This provides complete access to the DocumentDB API and all its methods, and can be used to customize collection settings, or make other database calls independent of storing session data.

store.all(cb)

Retrieves all sessions from the collection, by filtering on the session discriminator (usually "type": "session").

callback(err, sessions = [])

store.clear(cb)

Deletes all sessions from the collection. Callback is fired once the collection is cleared of all sessions. Other documents in the collection that are not sessions are not affected. This operation uses a stored procedure called clear, which is uploaded to the collection on initialization.

callback(err)

store.destroy(sid, cb)

Deletes a session with the given session ID (sid). Callback is fired once the document is deleted.

callback(err)

store.get(sid, cb)

Retrieves a session from the collection using the given session ID (sid). The session is returned as an object, and includes its administrative database properties (e.g. _RID, _ETAG). If the session is not found, the session object will be set to null.

callback(err, session)

store.initialize(cb)

Normally, documentdb-session will check for a DocumentDB database and collection the first time a request to the database is made, and will create them if they do not exist. It will also upload a few stored procedures to the collection. If you would like to initialize the database before you start making database calls, you can do so by calling .initialize(). This is useful if you want your application to check for database configuration errors before attempting to write sessions, and for testing.

callback(err)

Example

const app = express();
const store = new DocumentDBStore(config);
 
app.use(session({ store }));
 
store.initialize((err, db) => {
  if (err) throw new Error('Could not initialize database');
  console.log(`Database ${db.id} successfully initialized.`);
});

store.length(cb)

Retrieves a count of the number of sessions in the collection, filtering on the session discriminator (usually "type": "session"). This operation uses a stored procedure called length, which is uploaded to the collection on initialization.

callback(err, len)

store.set(sid, session, cb)

Upserts the session into the collection given a session ID (sid) and session object (session). The callback fires once the session has been added to the collection.

callback(err)

store.touch(sid, session, cb)

Resets the TTL (time-to-live) for the session (see the ttl config option above). The callback fires onces the document has been updated. This operation works by updating the lastActive field on the document.

callback(err)

Tests

Testing is done using Jasmine, and tests are run automatically using Travis CI. To run the tests yourself:

  1. Make sure Jasmine is installed (npm install --save-dev Jasmine).

  2. Set the following environment variables using the settings for the DocumentDB database account you'd like to test with:

  • DOCUMENTDB_URL: The URL/hostname of your database account, e.g. https://mydbaccount.documents.azure.com:443/.

  • DOCUMENTDB_KEY: The primary/master key for your account, e.g. 8idtLLsiRJsKvgHLizvuKDVBlsTswCT5fOzR7jIYwN0k7tINMQpgkwXAiSzJX4UvgOJ9YXTTYK61LX15pobbmQ==. A primary key is required because this package creates a new database if one doesn't already exist.

  1. Run npm test.

NB: The tests will create and then delete a single test database and collection. This means you will be charged a very small amount for the time the collection existed. You can read more about DocumentDB's pricing here.

Issues & Contributing

Issues, feature requests, & pull requests welcome!

Git Workflow

  • master - Only contains stable, tested code. New versions are published to npm from here. Pull requests to master must pass all required Travis-CI checks, and use a squash commit.
  • dev - Contains code for the next version. Prerelease versions are published to npm from here.

Pull requests can be made to either dev or master.

install

npm i documentdb-session

Downloadsweekly downloads

26

version

1.0.1

license

MIT

homepage

github.com

repository

Gitgithub

last publish

collaborators

  • avatar
Report a vulnerability