npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2024 – Pkg Stats / Ryan Hefner

@iwsio/mongodb-express-session

v0.4.7

Published

An ESM express-session store for MongoDB using the latest MongoDb Node driver v6. Supports TTL and touch. Supports MongoDB v3.6+ (without TTL index), 5.1+ (with TTL Index).

Downloads

65

Readme

@iwsio/mongodb-express-session

@iwsio/mongodb-express-session: PUSH to main

This package provides an ESM module with an updated implementation of the Express Session Store with MongoDb 6 Driver. This store implements touch and TTL

Usage

This module exports a class with a constructor that includes these options:

type MongoSessionStoreOptions = {
	uri: string;
	collection: string;
	ttl: number | ((data: SessionData) => number);
	prefix: string;
	createTTLIndex: boolean;
};

Quick example

Setting up an express server with express-sessions and using this MongoSessionStore as its store.

// store.mts
import { MongoSessionStore } from '@iwsio/mongodb-express-session'

// create a store with default options and custom mongo uri
export const store = new MongoSessionStore({ uri: 'mongodb://localhost/express_sessions' })

store.on('info', console.log)
store.on('error', console.error)


// app.mts
import express from 'express'
import session from 'express-session'
import { store as mongoStore } from './store.mjs'

// optional, listen to store errors
store.on('error', function(error: any) {
	console.error(error)
})

const app = express()

app.enable('trust proxy', 1)

app.use(session({
	secret: 'some secret',
	resave: false,
	store: mongoStore,
	saveUninitialized: false,
	rolling: true,
	cookie: { httpOnly: true, sameSite: 'strict' },
	name: 'connect.sid'
}))


// ./bin/web.mts
// Don't forget to close the db connection on shutdown
import { store as mongoStore } from './store.mjs'

//... server setup code above

function shutdownHandler(_sig: any, _n: any) {
	if (server != null) server.close()
	mongoStore.close()
}

process.on('SIGTERM', shutdownHandler)
process.on('SIGINT', shutdownHandler)

Another example

With the saveUninitialized: false setting, testing this code out as-is without an established app will not save any session data to MongoDb. You need to modify the session in order to initialize it. Here's an example showing a simple middleware that modifies session during a request.

// global.d.ts
declare module 'express-session' {

// extends the SessionData type to include your customizations
	interface SessionData {
		something?: string
	}
}

// app.mts: example initialization middleware
app.use((req, _res, next) => {
	if (req.session.something) {
		console.log('existing something: ', req.session.something)
		return next()
	}
	req.session.something = nanoid()
	console.log('new something: ', req.session.something)
	next()
})

app.get('/', (req, res) => {
	res.status(200).send('OK')
})

Run the demo

If you clone the source code, it includes a simple demo application. Build and run the demo from the project root with Node 20 active. This requires Docker Desktop (or skip this step if you have a local MongoDb server available, in which case, you'll want to update the config settings in app.mts before this step).

# boots up the mongo db (this doesn't map data volume so it will lose everything when it shuts down)
# also FYI: shut it down with: `docker compose down`
docker compose up -d mongo

# install deps, build both workspaces and start the demo.
npm ci
npm run build
npm start -w demo

Ctrl-C to stop the server.

Test the cookie creation

Curl the site. Without providing an existing cookie, it should create one for you. You'll see it in the response as a Set-Cookie: header.

curl -v http://localhost:3000

# yields:
*   Trying 127.0.0.1:3000...
* Connected to localhost (127.0.0.1) port 3000 (#0)
> GET / HTTP/1.1
> Host: localhost:3000
> User-Agent: curl/8.1.2
> Accept: */*
> 
< HTTP/1.1 200 OK
< X-Powered-By: Express
< Content-Type: text/html; charset=utf-8
< Content-Length: 2
< ETag: W/"2-nOO9QiTIwXgNtWtBJezz8kv3SLc"
# this guy
< Set-Cookie: connect.sid=s%3ABKpbZsCtMVGsRi2uDwMYIa4pAsLMh2EE.jEiosn3OQ7RQ9WZUSAKptC%2B0KshKXPY3oA%2Fh1J%2BECPI; Path=/; Expires=Wed, 29 Nov 2023 03:27:55 GMT; HttpOnly; SameSite=Strict
< Date: Wed, 22 Nov 2023 03:27:55 GMT
< Connection: keep-alive
< Keep-Alive: timeout=5
< 
* Connection #0 to host localhost left intact
OK%

MongoDb

Check the database. use mongosh localhost/express_sessions and check the sessions collection.

use express_sessions
db.sessions.find()
[
  {
    _id: 'BKpbZsCtMVGsRi2uDwMYIa4pAsLMh2EE',
    expires: ISODate("2023-11-29T03:27:55.254Z"),
    session: {
      cookie: {
        path: '/',
        _expires: ISODate("2023-11-29T03:27:55.254Z"),
        originalMaxAge: 604800000,
        httpOnly: true,
        sameSite: 'strict'
      },
      something: 'K-o_HNG5jN6XcJ9bfrTep'
    }
  }
]

// Check for the index (default option)
db.sessions.getIndexes()
[
  { v: 2, key: { _id: 1 }, name: '_id_' },
  {
    v: 2,
    key: { expires: 1 },
    name: 'expires_1',
    expireAfterSeconds: 0
  }
]

Test re-use:

Curl the site again. Except this time, use the cookie data sent to you from the last response.

curl -v --cookie "connect.sid=s%3ABKpbZsCtMVGsRi2uDwMYIa4pAsLMh2EE.jEiosn3OQ7RQ9WZUSAKptC%2B0KshKXPY3oA%2Fh1J%2BECPI; Path=/; Expires=Wed, 29 Nov 2023 03:27:55 GMT; HttpOnly; SameSite=Strict" http://localhost:3000

Then check MongoDb; ensure that no additional cookies were created. You should still find one cookie, but with an updated expires date. touch works!

db.sessions.find()
[
  {
    _id: 'BKpbZsCtMVGsRi2uDwMYIa4pAsLMh2EE',
    expires: ISODate("2023-11-29T03:39:18.430Z"),
    session: {
      cookie: {
        path: '/',
        _expires: ISODate("2023-11-29T03:27:55.254Z"),
        originalMaxAge: 604800000,
        httpOnly: true,
        sameSite: 'strict'
      },
      something: 'K-o_HNG5jN6XcJ9bfrTep'
    }
  }
]