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

@hattip/session

v0.0.48

Published

Session management for Hattip

Downloads

596

Readme

@hattip/session

Session middleware for Hattip. It persists data between requests in a cookie or a custom session store.

This middleware uses the Web Crypto API which is supported by:

  • Node.js 16 or later
  • Cloudflare Workers
  • Deno
  • ✅ Vercel Serverless (since it uses Node.js)
  • ✅ Vercel Edge (since it uses Cloudflare Workers)
  • ✅ Netlify Functions (since it uses Node.js)
  • ✅ Netlify Edge Functions (since it uses Deno)
  • 🚧 Bun

Usage

import { cookie } from "@hattip/cookie";
import { session, SignedCookieStore } from "@hattip/session";
import { json } from "@hattip/response";

// session() requires cookie() or
// getSessionId option to be set to read
// the session ID from somewhere else
app.use(cookie());

app.use(
  session({
    // Session store
    store: new SignedCookieStore(
      await SignedCookieStore.generateKeysFromSecrets(["secret"]),
    ),
    // Default session data when a new session is created.
    // It can be a function.
    // It is shallow cloned, if you need a deep clone, use a function.
    defaultSessionData: {},
  }),
);

app.get((ctx) => {
  return json(ctx.session.data);
});

You can set the session data type using module augmentation:

declare module "@hattip/session" {
  interface SessionData {
    userId: string;
  }
}

Stores

@hattip/session comes bundled with a few ready-to-use session stores. Cookie stores store their data in a cookie and are appropriate for small amounts of data. External stores store a key in a cookie and use external storage to store the data. External stores are appropriate for large amounts of data.

External stores support a session.regenerate() method, which will generate a new session ID and persist the session data to the new ID. You should call it when you want to invalidate the current session, such as when a user logs in or logs out to prevent session fixation attacks.

UnsignedCookieStore

It stores the session data in an unsigned cookie. The client can read and modify the cookie, so it should only be used for non-sensitive data. Also, you should always validate the session data by passing a custom parse function to the constructor:

const store = new SimpleCookieStore({
  parse(data) {
    const parsed = JSON.parse(data);
    validate(parsed);
    return parsed;
  },
});

SignedCookieStore

It stores the session data in a signed cookie. The client can read the cookie, but cannot modify it. It requires at least one secret key to sign the cookie. If you provide multiple keys, all of them will be used to verify the cookie but only the first one will be used to sign it. This allows you to rotate the keys without invalidating existing sessions.

You can generate keys from password-like secrets using SignedCookieStore.generateKeysFromSecrets or you can use SignedCookieStore.generateKey to generate a secure key. SignedCookieStore.exportKey can be used to base64 encode a key for storing, e.g. in an environment variable. SignedCookieStore.generateKeysFromBase64 can be used to decode a series of keys from base64.

new SignedCookieStore(
  await SignedCookieStore.generateKeysFromSecrets(["my new secret", "my old secret]),
);

EncryptedCookieStore

It stores the session data in an encrypted cookie. The client cannot read or modify the cookie. It requires at least one secret key to encrypt the cookie. If you provide multiple keys, all of them will be used to decrypt the cookie but only the first one will be used to encrypt it. This allows you to rotate the keys without invalidating existing sessions.

You can use EncryptedCookieStore.generateKey to generate a secure key. EncryptedCookieStore.exportKey can be used to base64 encode a key for storing, e.g. in an environment variable. EncryptedCookieStore.generateKeysFromBase64 can be used to decode a series of keys from base64.

new EncryptedCookieStore(
  await EncryptedCookieStore.generateKeysFromBase64([
    "cnNwJHcQHlHHB7+/zRYOJP/m0JEXxQpoGskCs8Eg+XI=",
  ]),
);

UnsafeMemoryStore

It stores the session data in memory. On edge and serverless runtimes, this store will lose its data. On long-running servers (Node, Deno, Bun, etc.) it will leak memory and lose its data on server restart. For these reasons, it is only useful for development and should never be used in production.

RedisSessionStore

It stores the session data in a Redis database. It requires a node-redis compatible Redis client factory (a function that returns the Redis client) to be passed to the constructor.

const store = new RedisSessionStore({ getClient: () => redis.createClient() });

KvSessionStore

It stores the session data in Cloudflare Workers KV. It requires a KV namespace factory (a function that returns a KV namespace) to be passed to the constructor. For example, if your KV namespace is called SESSIONS:

const store = new KvSessionStore({
  getStore: (ctx) => ctx.platform.env.SESSIONS,
});