NATS KV Adapter
Resources
Setup
Installation
npm install @nats-io/transport-node @nats-io/kv @auth/nats-kv-adapter
Environment Variables
NATS_SERVERS,
NATS_CREDS
Configuration
You can either use this with Symbol.asyncDispose or handle the disposal yourself.
With explicit resource management
If you do choose asyncDispose, make sure you environment is configured to handled that by targeting at least es2022 and the lib
option to include esnext
or esnext.disposable
, or by providing a polyfill. Using this pattern the adapter will call the cleanup function when the adapter is after NATS operations. https://www.typescriptlang.org/docs/handbook/release-notes/typescript-5-2.html#using-declarations-and-explicit-resource-management
import NextAuth from "next-auth"
import { NatsKVAdapter } from "@auth/nats-kv-adapter"
import { connect } from "@nats-io/transport-node"
import { Kvm, KV } from "@nats-io/kv"
async function getNats(): Promise<
{ kv: KV } & {
[Symbol.asyncDispose]: () => Promise<void>
}
> {
const nc = await connect({
servers: process.env.NATS_SERVERS,
authenticator: process.env.NATS_CREDS,
})
const kvm = new Kvm(nc)
const kv = await kvm.create("name-of-auth-bucket")
return {
kv: kv,
[Symbol.asyncDispose]: async () => {
await nc.drain()
await nc.close()
},
}
}
export const { handlers, auth, signIn, signOut } = NextAuth({
adapter: NatsKVAdapter(getNats),
providers: [],
})
Without explicit resource management
You can instead provide the adapter with a KV instance, and handle the connection and disposal yourself. Useful if you want to keep the connection alive, or have explicit control over the connection.
import NextAuth from "next-auth"
import { NatsKVAdapter } from "@auth/nats-kv-adapter"
import { connect } from "@nats-io/transport-node"
import { Kvm, KV } from "@nats-io/kv"
const nc = await connect({
servers: process.env.NATS_SERVERS,
authenticator: process.env.NATS_CREDS,
})
const kvm = new Kvm(nc)
const kv = await kvm.create("name-of-auth-bucket")
export const { handlers, auth, signIn, signOut } = NextAuth({
adapter: NatsKVAdapter(kv),
providers: [],
})
Advanced usage
If you have multiple Auth.js connected apps using this instance, you need different key prefixes for every app.
You can change the prefixes by passing an options
object as the second argument to the adapter factory function.
The default values for this object are:
const defaultOptions = {
baseKeyPrefix: "",
accountKeyPrefix: "user:account:",
accountByUserIdPrefix: "user:account:by-user-id:",
emailKeyPrefix: "user:email:",
sessionKeyPrefix: "user:session:",
sessionByUserIdKeyPrefix: "user:session:by-user-id:",
userKeyPrefix: "user:",
verificationTokenKeyPrefix: "user:token:",
}
Usually changing the baseKeyPrefix
should be enough for this scenario, but for more custom setups, you can also change the prefixes of every single key.
export const { handlers, auth, signIn, signOut } = NextAuth({
adapter: NatsKVAdapter(kv, { baseKeyPrefix: "app2:" }),
})