### Generate Secret Key (Local Install) Source: https://github.com/fastify/fastify-secure-session/blob/main/README.md Generate a secret key if the library is installed locally, avoiding npx. ```sh ./node_modules/@fastify/secure-session/genkey.js > secret-key ``` -------------------------------- ### Registering Secure Session with a Single Key Source: https://github.com/fastify/fastify-secure-session/blob/main/README.md Initial setup for Fastify Secure Session using a single secret key for signing and encryption. ```javascript fastify.register(require('@fastify/secure-session'), { key: [mySecureKey], cookie: { path: '/' // options for setCookie, see https://github.com/fastify/fastify-cookie } }) ``` -------------------------------- ### Full Example: Key Rotation with File-Based Keys Source: https://github.com/fastify/fastify-secure-session/blob/main/README.md A complete Fastify application demonstrating key rotation using keys read from files. Sessions are signed with the first key and can be decoded by subsequent keys if the first fails. ```javascript const fs = require('node:fs') const fastify = require('fastify')({ logger: false }) const key1 = fs.readFileSync(path.join(__dirname, 'secret-key1')) const key2 = fs.readFileSync(path.join(__dirname, 'secret-key2')) fastify.register(require('@fastify/secure-session'), { // any old sessions signed with key2 will still be decoded successfully the first time and // then re-signed with key1 to keep good performance with subsequent calls key: [key1, key2], cookie: { path: '/' // options for setCookie, see https://github.com/fastify/fastify-cookie } }) fastify.post('/', (request, reply) => { // will always be encrypted using `key1` with the configuration above request.session.set('data', request.body) reply.send('session set') }) fastify.get('/', (request, reply) => { // will attempt to decode using key1 and then key2 if decoding with key1 fails const data = request.session.get('data') if (!data) { reply.code(404).send() return } reply.send(data) }) fastify.listen({ port: 3000 }) ``` -------------------------------- ### Get Session Data Source: https://github.com/fastify/fastify-secure-session/blob/main/README.md Retrieve data from the session using the `get` method. Returns undefined if the key does not exist. ```javascript const data = request.session.get('data') if (!data) { reply.code(404).send() return } reply.send(data) ``` -------------------------------- ### Set Session Data Source: https://github.com/fastify/fastify-secure-session/blob/main/README.md Set data within the session using the `set` method. This example demonstrates setting request body data under the key 'data'. ```javascript request.session.set('data', request.body) ``` -------------------------------- ### Retrieve All Session Data using session.data() Source: https://context7.com/fastify/fastify-secure-session/llms.txt Use `session.data()` to get all session data as an object, excluding internal properties like the timestamp. This is useful for debugging or returning the full session state. ```javascript fastify.get('/session', (request, reply) => { // Get all session data (excludes internal __ts timestamp) const sessionData = request.session.data() if (!sessionData || Object.keys(sessionData).length === 0) { reply.code(404).send({ error: 'No session data' }) return } reply.send(sessionData) }) ``` -------------------------------- ### fastify.encodeSecureSession(session, sessionName) Source: https://context7.com/fastify/fastify-secure-session/llms.txt Encode a session object into an encrypted cookie string. Returns the base64-encoded ciphertext suitable for Set-Cookie headers. Optional sessionName parameter for multi-session setups. ```APIDOC ## fastify.encodeSecureSession(session, sessionName) Encode a session object into an encrypted cookie string. Returns the base64-encoded ciphertext suitable for Set-Cookie headers. Optional sessionName parameter for multi-session setups. ### Parameters - **session** (object): The session object to encode. - **sessionName** (string, optional): The name of the session to encode, used in multi-session configurations. ### Example Usage ```javascript fastify.get('/export-session', (request, reply) => { // Create custom session data const exportSession = fastify.createSecureSession({ exportedAt: Date.now(), userId: request.session.get('userId'), purpose: 'api-access' }) // Encode to encrypted cookie string const encoded = fastify.encodeSecureSession(exportSession) // For multi-session setup: // const encoded = fastify.encodeSecureSession(exportSession, 'apiSession') reply.send({ token: encoded, // Token format: base64(ciphertext);base64(nonce) }) }) ``` ``` -------------------------------- ### Encode Session Object to Cookie String Source: https://context7.com/fastify/fastify-secure-session/llms.txt Encode a session object into an encrypted cookie string using `fastify.encodeSecureSession()`. Returns a base64-encoded ciphertext suitable for Set-Cookie headers. An optional `sessionName` parameter can be provided for multi-session setups. ```javascript fastify.get('/export-session', (request, reply) => { // Create custom session data const exportSession = fastify.createSecureSession({ exportedAt: Date.now(), userId: request.session.get('userId'), purpose: 'api-access' }) // Encode to encrypted cookie string const encoded = fastify.encodeSecureSession(exportSession) // For multi-session setup: // const encoded = fastify.encodeSecureSession(exportSession, 'apiSession') reply.send({ token: encoded, // Token format: base64(ciphertext);base64(nonce) }) }) ``` -------------------------------- ### Set Data in Multiple Sessions Source: https://github.com/fastify/fastify-secure-session/blob/main/README.md Demonstrates setting data in two different session instances, each with its own `sessionName`. ```javascript request.mySession.set('data', request.body) request.myOtherSession.set('data', request.body) reply.send('hello world') ``` -------------------------------- ### Plugin Registration with Pre-generated Key Source: https://context7.com/fastify/fastify-secure-session/llms.txt Demonstrates how to register the Fastify Secure Session plugin using a pre-generated encryption key loaded from a file. This is the recommended method for production. ```APIDOC ## Plugin Registration with Pre-generated Key Register the plugin with a pre-generated encryption key loaded from a file. This is the recommended approach for production deployments where the key is stored securely and loaded at runtime. ### JavaScript Example ```javascript const fastify = require('fastify')({ logger: false }) const fs = require('node:fs') const path = require('node:path') fastify.register(require('@fastify/secure-session'), { // Name of the session property on request object (default: 'session') sessionName: 'session', // Name of the session cookie (default: value of sessionName) cookieName: 'my-session-cookie', // Load the 32-byte encryption key from file key: fs.readFileSync(path.join(__dirname, 'secret-key')), // Session expiry in seconds (default: 86401 = ~24 hours) expiry: 24 * 60 * 60, cookie: { path: '/', httpOnly: true, // Recommended for security secure: true, // Use in production with HTTPS maxAge: 86400 // Cookie max age in seconds } }) await fastify.listen({ port: 3000 }) ``` ### Configuration Options - **sessionName** (string) - Optional - Name of the session property on the request object (default: 'session'). - **cookieName** (string) - Optional - Name of the session cookie (default: value of sessionName). - **key** (Buffer) - Required - The 32-byte encryption key loaded from a file. - **expiry** (number) - Optional - Session expiry in seconds (default: 86401). - **cookie** (object) - Optional - Cookie configuration object. - **path** (string) - Optional - Path for the cookie (default: '/'). - **httpOnly** (boolean) - Optional - Recommended for security (default: false). - **secure** (boolean) - Optional - Use in production with HTTPS (default: false). - **maxAge** (number) - Optional - Cookie max age in seconds. ``` -------------------------------- ### Initialize Secure Session with Secret and Salt Source: https://github.com/fastify/fastify-secure-session/blob/main/README.md Initialize the @fastify/secure-session plugin using a secret passphrase and salt. This method adds a startup delay due to cryptographic operations but simplifies key management. Ensure the secret is longer than 32 characters and configure httpOnly cookies for production. ```javascript const fastify = require('fastify')({ logger: false }) fastify.register(require('@fastify/secure-session'), { secret: 'averylogphrasebiggerthanthirtytwochars', salt: 'mq9hDxBVDbspDR6n', cookie: { path: '/', httpOnly: true // Use httpOnly for all production purposes // options for setCookie, see https://github.com/fastify/fastify-cookie } }) fastify.post('/', (request, reply) => { request.session.set('data', request.body) reply.send('session set') }) fastify.get('/', (request, reply) => { const data = request.session.get('data') if (!data) { reply.code(404).send() return } reply.send(data) }) fastify.get('/all', (request, reply) => { // get all data from session const data = request.session.data() if (!data) { reply.code(404).send() return } reply.send(data) }) fastify.listen({ port: 3000 }) ``` -------------------------------- ### Plugin Registration with Hexadecimal Key from Environment Source: https://context7.com/fastify/fastify-secure-session/llms.txt Shows how to load the encryption key from an environment variable as a hexadecimal string, suitable for containerized environments. ```APIDOC ## Plugin Registration with Hexadecimal Key from Environment Load the encryption key from an environment variable as a hexadecimal string, useful for containerized deployments and cloud platforms where file-based secrets are impractical. ### JavaScript Example ```javascript const fastify = require('fastify')({ logger: false }) // Convert key file to hex: fs.readFileSync('secret-key').toString('hex') // Store in environment variable: COOKIE_KEY=4fe91796c30bd989d95b62dc46c7c3ba... fastify.register(require('@fastify/secure-session'), { key: Buffer.from(process.env.COOKIE_KEY, 'hex'), cookie: { path: '/', httpOnly: true } }) await fastify.listen({ port: 3000 }) ``` ### Configuration Options - **key** (Buffer) - Required - The encryption key as a Buffer, converted from a hexadecimal string environment variable. - **cookie** (object) - Optional - Cookie configuration object. - **path** (string) - Optional - Path for the cookie (default: '/'). - **httpOnly** (boolean) - Optional - Recommended for security (default: false). ``` -------------------------------- ### Plugin Registration with Secret Passphrase Source: https://context7.com/fastify/fastify-secure-session/llms.txt Explains how to register the plugin using a secret passphrase, which is derived into an encryption key using password hashing. This method is simpler but incurs startup latency. ```APIDOC ## Plugin Registration with Secret Passphrase Register using a secret passphrase that gets derived into an encryption key using sodium's password hashing. This approach is simpler but adds startup latency due to the key derivation process. ### JavaScript Example ```javascript const fastify = require('fastify')({ logger: false }) fastify.register(require('@fastify/secure-session'), { // Secret must be at least 32 characters secret: 'averylogphrasebiggerthanthirtytwochars', // Salt must be exactly 16 bytes salt: 'mq9hDxBVDbspDR6n', cookie: { path: '/', httpOnly: true, secure: true } }) fastify.post('/login', (request, reply) => { request.session.set('user', request.body.username) reply.send('Logged in') }) fastify.listen({ port: 3000 }) ``` ### Configuration Options - **secret** (string) - Required - A secret passphrase (at least 32 characters). - **salt** (string) - Required - A 16-byte salt. - **cookie** (object) - Optional - Cookie configuration object. - **path** (string) - Optional - Path for the cookie (default: '/'). - **httpOnly** (boolean) - Optional - Recommended for security (default: false). - **secure** (boolean) - Optional - Use in production with HTTPS (default: false). ``` -------------------------------- ### Convert Key File to Hex String Source: https://github.com/fastify/fastify-secure-session/blob/main/README.md Use this script to convert a key file into a hexadecimal string, which is useful for loading keys from environment variables. ```javascript const keyBuffer = fs.readFileSync(path.join(__dirname, 'secret-key')); const hexString = keyBuffer.toString('hex'); console.log(hexString) // Outputs: 4fe91796c30bd989d95b62dc46c7c3ba0b6aa2df2187400586a4121c54c53b85 ``` -------------------------------- ### Register Plugin with Pre-generated Key Source: https://context7.com/fastify/fastify-secure-session/llms.txt Register the secure session plugin by loading a pre-generated 32-byte encryption key from a file. This is recommended for production. ```javascript const fastify = require('fastify')({ logger: false }) const fs = require('node:fs') const path = require('node:path') fastify.register(require('@fastify/secure-session'), { // Name of the session property on request object (default: 'session') sessionName: 'session', // Name of the session cookie (default: value of sessionName) cookieName: 'my-session-cookie', // Load the 32-byte encryption key from file key: fs.readFileSync(path.join(__dirname, 'secret-key')), // Session expiry in seconds (default: 86401 = ~24 hours) expiry: 24 * 60 * 60, cookie: { path: '/', httpOnly: true, // Recommended for security secure: true, // Use in production with HTTPS maxAge: 86400 // Cookie max age in seconds } }) await fastify.listen({ port: 3000 }) ``` -------------------------------- ### Register Plugin with Hexadecimal Key from Environment Source: https://context7.com/fastify/fastify-secure-session/llms.txt Load the encryption key from an environment variable as a hexadecimal string. This is useful for containerized deployments. ```javascript const fastify = require('fastify')({ logger: false }) // Convert key file to hex: fs.readFileSync('secret-key').toString('hex') // Store in environment variable: COOKIE_KEY=4fe91796c30bd989d95b62dc46c7c3ba... fastify.register(require('@fastify/secure-session'), { key: Buffer.from(process.env.COOKIE_KEY, 'hex'), cookie: { path: '/', httpOnly: true } }) await fastify.listen({ port: 3000 }) ``` -------------------------------- ### Generate a Secret Key Source: https://github.com/fastify/fastify-secure-session/blob/main/README.md Use this command to generate a secret key for session encryption. The `--yes` flag is recommended to avoid prompts when using npx. ```sh npx --yes @fastify/secure-session > secret-key ``` -------------------------------- ### Generate Encryption Keys with npx Source: https://context7.com/fastify/fastify-secure-session/llms.txt Use this command to generate a new 32-byte secret key for session encryption. The key is output to standard output. ```bash npx @fastify/secure-session > secret-key ``` ```powershell npx @fastify/secure-session | Out-File -Encoding default -NoNewline -FilePath secret-key ``` ```bash ./node_modules/@fastify/secure-session/genkey.js > secret-key ``` -------------------------------- ### Registering Secure Session with Key Rotation Source: https://github.com/fastify/fastify-secure-session/blob/main/README.md Configure Fastify Secure Session to use multiple keys for key rotation. The new key should be the first in the array to ensure compatibility with older sessions. ```javascript fastify.register(require('@fastify/secure-session'), { key: [myNewKey, mySecureKey], cookie: { path: '/' // options for setCookie, see https://github.com/fastify/fastify-cookie } }) ``` -------------------------------- ### Load Hex Key from Environment Variable Source: https://github.com/fastify/fastify-secure-session/blob/main/README.md Configure the @fastify/secure-session plugin to use a hexadecimal key loaded from an environment variable. Ensure the key is a secret of the correct length. ```javascript fastify.register(require('@fastify/secure-session'), { key: Buffer.from(process.env.COOKIE_KEY, 'hex') }) ``` -------------------------------- ### Register Plugin with Secret Passphrase Source: https://context7.com/fastify/fastify-secure-session/llms.txt Register the plugin using a secret passphrase, which is derived into an encryption key using password hashing. This adds startup latency. ```javascript const fastify = require('fastify')({ logger: false }) fastify.register(require('@fastify/secure-session'), { // Secret must be at least 32 characters secret: 'averylogphrasebiggerthanthirtytwochars', // Salt must be exactly 16 bytes salt: 'mq9hDxBVDbspDR6n', cookie: { path: '/', httpOnly: true, secure: true } }) fastify.post('/login', (request, reply) => { request.session.set('user', request.body.username) reply.send('Logged in') }) fastify.listen({ port: 3000 }) ``` -------------------------------- ### Implement Key Rotation for Security Source: https://context7.com/fastify/fastify-secure-session/llms.txt Support gradual key rotation by providing an array of keys. New sessions use the first key, but decryption attempts all keys. Old sessions are automatically re-encrypted with the new key upon access. ```javascript const fastify = require('fastify')({ logger: false }) const fs = require('node:fs') const path = require('node:path') // Key rotation: new key first, then old keys for backward compatibility const newKey = fs.readFileSync(path.join(__dirname, 'secret-key-new')) const oldKey = fs.readFileSync(path.join(__dirname, 'secret-key-old')) fastify.register(require('@fastify/secure-session'), { // New sessions encrypted with newKey // Old sessions can still be decrypted with oldKey, then re-encrypted with newKey key: [newKey, oldKey], cookie: { path: '/', httpOnly: true } }) fastify.get('/data', (request, reply) => { // Sessions encrypted with oldKey are automatically re-signed with newKey // when accessed, allowing gradual migration const data = request.session.get('data') reply.send(data || {}) }) // For string keys (e.g., from environment variables): // key: [ // Buffer.from(process.env.NEW_SESSION_KEY, 'hex'), // Buffer.from(process.env.OLD_SESSION_KEY, 'hex') // ] ``` -------------------------------- ### Generating Encryption Keys Source: https://context7.com/fastify/fastify-secure-session/llms.txt This section details how to generate the necessary 32-byte encryption keys for the Fastify Secure Session plugin using the provided CLI tool or script. ```APIDOC ## Generating Encryption Keys The plugin provides a CLI tool to generate cryptographically secure keys required for session encryption. Keys must be exactly 32 bytes (256 bits) for the sodium secret box encryption. ### Bash Commands ```bash # Generate a new secret key using npx npx @fastify/secure-session > secret-key # For Windows PowerShell npx @fastify/secure-session | Out-File -Encoding default -NoNewline -FilePath secret-key # Using the genkey.js script directly ./node_modules/@fastify/secure-session/genkey.js > secret-key ``` ``` -------------------------------- ### Multiple Sessions Configuration Source: https://context7.com/fastify/fastify-secure-session/llms.txt Register multiple independent sessions with different configurations, each with its own encryption key, cookie name, and options. Useful for separating concerns like authentication vs preferences. ```APIDOC ## Multiple Sessions Configuration Register multiple independent sessions with different configurations, each with its own encryption key, cookie name, and options. Useful for separating concerns like authentication vs preferences. ### Example Usage ```javascript const fastify = require('fastify')({ logger: false }) fastify.register(require('@fastify/secure-session'), [ { sessionName: 'authSession', cookieName: 'auth', secret: 'authentication-secret-at-least-32-chars-long', salt: 'mq9hDxBVDbspDR6n', expiry: 3600, // 1 hour cookie: { path: '/', httpOnly: true, secure: true, maxAge: 3600 } }, { sessionName: 'prefsSession', cookieName: 'prefs', secret: 'preferences-secret-at-least-32-chars-long', salt: 'abcdefghijklmnop', expiry: 86400 * 365, // 1 year cookie: { path: '/', httpOnly: true, maxAge: 86400 * 365 } } ]) fastify.post('/login', (request, reply) => { // Short-lived auth session request.authSession.set('userId', request.body.userId) request.authSession.set('loginTime', Date.now()) // Long-lived preferences session request.prefsSession.set('theme', request.body.theme || 'light') request.prefsSession.set('language', request.body.language || 'en') reply.send({ message: 'Logged in with preferences saved' }) }) fastify.get('/profile', (request, reply) => { const userId = request.authSession.get('userId') const theme = request.prefsSession.get('theme') if (!userId) { reply.code(401).send({ error: 'Not authenticated' }) return } reply.send({ userId, theme }) }) ``` ### Configuration Options - **sessionName** (string): The name to use for accessing the session object on the request (e.g., `request.authSession`). - **cookieName** (string): The name of the cookie to be set in the browser. - **secret** (string): The secret key used for encrypting session data. Must be at least 32 characters long. - **salt** (string): A salt to enhance the security of the encryption. - **expiry** (number): The session expiration time in seconds. - **cookie** (object): An object containing cookie options (e.g., `path`, `httpOnly`, `secure`, `maxAge`). ``` -------------------------------- ### session.set(key, value) Source: https://context7.com/fastify/fastify-secure-session/llms.txt Explains how to store data in the session using the `session.set()` method. The session is automatically encrypted and sent as a cookie upon response. ```APIDOC ## session.set(key, value) Store a value in the session. The session is automatically marked as changed and will be encrypted and sent as a cookie in the response. Supports any JSON-serializable value. ### JavaScript Example ```javascript fastify.post('/login', (request, reply) => { // Store user data in session request.session.set('userId', 12345) request.session.set('email', request.body.email) request.session.set('preferences', { theme: 'dark', language: 'en' }) // Alternative: use property setter syntax request.session.username = request.body.username reply.send({ message: 'Login successful' }) }) // Example request: // POST /login // Content-Type: application/json // {"email": "user@example.com", "username": "johndoe"} // // Response includes Set-Cookie header with encrypted session ``` ### Method `session.set(key, value)` ### Parameters - **key** (string) - Required - The key under which to store the value. - **value** (any JSON-serializable) - Required - The value to store in the session. ### Request Body Example ```json { "email": "user@example.com", "username": "johndoe" } ``` ### Response - **Set-Cookie** (string) - The HTTP header containing the encrypted session cookie. ``` -------------------------------- ### Retrieve Session Data using session.get() Source: https://context7.com/fastify/fastify-secure-session/llms.txt Use `session.get(key)` to retrieve specific values from the session. The session is automatically decrypted from the cookie. If the key does not exist, `undefined` is returned. Property getter syntax is also supported. ```javascript fastify.get('/profile', (request, reply) => { // Retrieve values using get method const userId = request.session.get('userId') const email = request.session.get('email') const preferences = request.session.get('preferences') // Alternative: use property getter syntax const username = request.session.username if (!userId) { reply.code(401).send({ error: 'Not authenticated' }) return } reply.send({ userId, email, username, preferences }) }) ``` -------------------------------- ### Configure Multiple Independent Sessions Source: https://context7.com/fastify/fastify-secure-session/llms.txt Register multiple sessions with distinct configurations for encryption keys, cookie names, and options. Useful for separating different types of session data. ```javascript const fastify = require('fastify')({ logger: false }) const fs = require('node:fs') fastify.register(require('@fastify/secure-session'), [ { sessionName: 'authSession', cookieName: 'auth', secret: 'authentication-secret-at-least-32-chars-long', salt: 'mq9hDxBVDbspDR6n', expiry: 3600, // 1 hour cookie: { path: '/', httpOnly: true, secure: true, maxAge: 3600 } }, { sessionName: 'prefsSession', cookieName: 'prefs', secret: 'preferences-secret-at-least-32-chars-long', salt: 'abcdefghijklmnop', expiry: 86400 * 365, // 1 year cookie: { path: '/', httpOnly: true, maxAge: 86400 * 365 } } ]) fastify.post('/login', (request, reply) => { // Short-lived auth session request.authSession.set('userId', request.body.userId) request.authSession.set('loginTime', Date.now()) // Long-lived preferences session request.prefsSession.set('theme', request.body.theme || 'light') request.prefsSession.set('language', request.body.language || 'en') reply.send({ message: 'Logged in with preferences saved' }) }) fastify.get('/profile', (request, reply) => { const userId = request.authSession.get('userId') const theme = request.prefsSession.get('theme') if (!userId) { reply.code(401).send({ error: 'Not authenticated' }) return } reply.send({ userId, theme }) }) ``` -------------------------------- ### Create Secure Session Programmatically Source: https://context7.com/fastify/fastify-secure-session/llms.txt Create a new session object programmatically without an HTTP request context using `fastify.createSecureSession()`. Useful for WebSocket connections or background jobs. ```javascript fastify.get('/websocket-token', async (request, reply) => { // Create a session for WebSocket authentication const wsSession = fastify.createSecureSession({ userId: request.session.get('userId'), wsPermissions: ['read', 'write'], createdAt: Date.now() }) // Encode it for transmission const token = fastify.encodeSecureSession(wsSession) reply.send({ wsToken: token }) }) ``` -------------------------------- ### Register Multiple Secure Session Plugins Source: https://github.com/fastify/fastify-secure-session/blob/main/README.md Register multiple instances of the secure session plugin with different configurations, including distinct session names and cookie paths. The `sessionName` is mandatory when registering multiple plugins. ```javascript fastify.register(require('@fastify/secure-session'), [{ sessionName: 'mySession', cookieName: 'my-session-cookie', key: fs.readFileSync(path.join(__dirname, 'secret-key')), cookie: { path: '/' } }, { sessionName: 'myOtherSession', key: fs.readFileSync(path.join(__dirname, 'another-secret-key')), cookie: { path: '/path', maxAge: 100 } }]) ``` -------------------------------- ### Key Rotation for Enhanced Security Source: https://context7.com/fastify/fastify-secure-session/llms.txt Support gradual key rotation by providing an array of keys. New sessions use the first key, but decryption attempts all keys. When an old-key session is decoded, it's automatically re-encrypted with the new key. ```APIDOC ## Key Rotation for Enhanced Security Support gradual key rotation by providing an array of keys. New sessions use the first key, but decryption attempts all keys. When an old-key session is decoded, it's automatically re-encrypted with the new key. ### Example Usage ```javascript const fastify = require('fastify')({ logger: false }) const fs = require('node:fs') const path = require('node:path') // Key rotation: new key first, then old keys for backward compatibility const newKey = fs.readFileSync(path.join(__dirname, 'secret-key-new')) const oldKey = fs.readFileSync(path.join(__dirname, 'secret-key-old')) fastify.register(require('@fastify/secure-session'), { // New sessions encrypted with newKey // Old sessions can still be decrypted with oldKey, then re-encrypted with newKey key: [newKey, oldKey], cookie: { path: '/', httpOnly: true } }) fastify.get('/data', (request, reply) => { // Sessions encrypted with oldKey are automatically re-signed with newKey // when accessed, allowing gradual migration const data = request.session.get('data') reply.send(data || {}) }) // For string keys (e.g., from environment variables): // key: [ // Buffer.from(process.env.NEW_SESSION_KEY, 'hex'), // Buffer.from(process.env.OLD_SESSION_KEY, 'hex') // ] ``` ### Configuration Options - **key** (Array): An array of keys (as Buffers or hex strings) for encryption and decryption. The first key is used for new encryption, while all keys are attempted for decryption. This enables gradual key rotation. - **cookie** (object): An object containing cookie options. ``` -------------------------------- ### Store Session Data with session.set() Source: https://context7.com/fastify/fastify-secure-session/llms.txt Store JSON-serializable values in the session using the `session.set(key, value)` method or property setter syntax. The session is automatically encrypted and sent as a cookie. ```javascript fastify.post('/login', (request, reply) => { // Store user data in session request.session.set('userId', 12345) request.session.set('email', request.body.email) request.session.set('preferences', { theme: 'dark', language: 'en' }) // Alternative: use property setter syntax request.session.username = request.body.username reply.send({ message: 'Login successful' }) }) // Example request: // POST /login // Content-Type: application/json // {"email": "user@example.com", "username": "johndoe"} // // Response includes Set-Cookie header with encrypted session ``` -------------------------------- ### Register Secure Session Plugin Source: https://github.com/fastify/fastify-secure-session/blob/main/README.md Register the @fastify/secure-session plugin with custom session and cookie names, key, and expiry. Ensure the key path is correct. ```javascript 'use strict' const fastify = require('fastify')({ logger: false }) const fs = require('node:fs') const path = require('node:path') fastify.register(require('@fastify/secure-session'), { // the name of the attribute decorated on the request-object, defaults to 'session' sessionName: 'session', // the name of the session cookie, defaults to value of sessionName cookieName: 'my-session-cookie', // adapt this to point to the directory where secret-key is located key: fs.readFileSync(path.join(__dirname, 'secret-key')), // the amount of time the session is considered valid; this is different from the cookie options // and based on value within the session. expiry: 24 * 60 * 60, // Default 1 day cookie: { path: '/' // options for setCookie, see https://github.com/fastify/fastify-cookie } }) ``` -------------------------------- ### Generate Secret Key (Powershell) Source: https://github.com/fastify/fastify-secure-session/blob/main/README.md Alternative command for generating a secret key in Windows Powershell. ```powershell npx @fastify/secure-session | Out-File -Encoding default -NoNewline -FilePath secret-key ``` -------------------------------- ### fastify.createSecureSession(data) Source: https://context7.com/fastify/fastify-secure-session/llms.txt Create a new session object programmatically without an HTTP request context. Useful for WebSocket connections, background jobs, or custom session handling scenarios. ```APIDOC ## fastify.createSecureSession(data) Create a new session object programmatically without an HTTP request context. Useful for WebSocket connections, background jobs, or custom session handling scenarios. ### Parameters - **data** (object): An object containing the initial data for the session. ### Example Usage ```javascript fastify.get('/websocket-token', async (request, reply) => { // Create a session for WebSocket authentication const wsSession = fastify.createSecureSession({ userId: request.session.get('userId'), wsPermissions: ['read', 'write'], createdAt: Date.now() }) // Encode it for transmission const token = fastify.encodeSecureSession(wsSession) reply.send({ wsToken: token }) }) ``` ``` -------------------------------- ### Encode and Decode Sessions Manually Source: https://github.com/fastify/fastify-secure-session/blob/main/README.md Use these decorators to manually encode and decode sessions when integrating with libraries that do not use standard Fastify Request objects. This is useful for systems like @fastify/websocket. ```javascript fastify.createSecureSession({ foo: 'bar' }) // => Session returns a session object for manipulating with .get and .set to then be encoded with encodeSecureSession fastify.encodeSecureSession(request.session) // => "abcdefg" returns the signed and encrypted cookie string, suitable for passing to a Set-Cookie header fastify.decodeSecureSession(request.cookies['session']) // => Session | null returns a session object which you can use to .get values from if decoding is successful, and null otherwise ``` ```javascript fastify.encodeSecureSession(request.session, 'mySecondSession') fastify.decodeSecureSession(request.cookies['session'], undefined, 'mySecondSession') ``` -------------------------------- ### session.options(opts) Source: https://context7.com/fastify/fastify-secure-session/llms.txt Allows overriding the default cookie serialization options for the current request. This method accepts standard cookie options and applies them only to the response being generated, without affecting global settings. ```APIDOC ## POST /remember-me ### Description Sets the user's session and extends the cookie's expiration to 30 days, implementing a 'remember me' functionality. ### Method POST ### Endpoint /remember-me ### Parameters #### Request Body - **userId** (string) - The ID of the user to be remembered. ### Request Example ```json { "userId": "user123" } ``` ### Response #### Success Response (200) - **message** (string) - Confirmation message. #### Response Example ```json { "message": "Session extended" } ``` ### Notes Sets cookie options: `maxAge: 30 * 24 * 60 * 60`, `path: '/'`, `httpOnly: true`, `secure: true`, `sameSite: 'strict'`. ``` ```APIDOC ## POST /secure-action ### Description Initiates a secure action by setting a session variable and configuring the session cookie to expire in 5 minutes for enhanced security. ### Method POST ### Endpoint /secure-action ### Parameters None ### Request Example None ### Response #### Success Response (200) - **message** (string) - Confirmation message. #### Response Example ```json { "message": "Secure action initiated" } ``` ### Notes Sets cookie options: `maxAge: 300` (5 minutes). ``` -------------------------------- ### session.get(key) Source: https://context7.com/fastify/fastify-secure-session/llms.txt Retrieves a specific value from the session using its key. If the key does not exist, it returns undefined. The session data is automatically decrypted from the cookie on each request. ```APIDOC ## GET /profile ### Description Retrieves user-specific data like userId, email, username, and preferences from the session. ### Method GET ### Endpoint /profile ### Parameters #### Query Parameters None #### Request Body None ### Request Example ``` GET /profile Cookie: my-session-cookie= ``` ### Response #### Success Response (200) - **userId** (number) - The unique identifier for the user. - **email** (string) - The user's email address. - **username** (string) - The user's chosen username. - **preferences** (object) - User-defined preferences. #### Response Example ```json { "userId": 12345, "email": "user@example.com", "username": "johndoe", "preferences": { "theme": "dark" } } ``` #### Error Response (401) - **error** (string) - Indicates that the user is not authenticated. ``` -------------------------------- ### Configuring Cookie Options within a Route Source: https://github.com/fastify/fastify-secure-session/blob/main/README.md Set cookie options, such as `maxAge`, directly within a route handler using `request.session.options()`. The `maxAge` option is specified in seconds. ```javascript fastify.post('/', (request, reply) => { request.session.set('data', request.body) // .options takes any parameter that you can pass to setCookie request.session.options({ maxAge: 60 * 60 }); // 3600 seconds => maxAge is always passed in seconds reply.send('hello world') }) ``` -------------------------------- ### session.data() Source: https://context7.com/fastify/fastify-secure-session/llms.txt Retrieves all session data as a plain JavaScript object. This method returns a copy of the session data, excluding internal properties like the timestamp, making it useful for debugging or returning the full session state. ```APIDOC ## GET /session ### Description Retrieves all available session data, excluding internal properties, for debugging or display purposes. ### Method GET ### Endpoint /session ### Parameters None ### Request Example None ### Response #### Success Response (200) - **(object)** - An object containing all session data. #### Response Example ```json { "userId": 12345, "email": "user@example.com", "preferences": { "theme": "dark" } } ``` #### Error Response (404) - **error** (string) - Indicates that no session data is found. ``` -------------------------------- ### Override Cookie Options with session.options() Source: https://context7.com/fastify/fastify-secure-session/llms.txt Use `session.options(opts)` to override cookie serialization options for the current request. Changes apply only to this response. This is useful for features like 'remember me' or setting shorter expiration times for sensitive operations. ```javascript fastify.post('/remember-me', (request, reply) => { request.session.set('userId', request.body.userId) // Extend session cookie to 30 days for "remember me" feature request.session.options({ maxAge: 30 * 24 * 60 * 60, // 30 days in seconds path: '/', httpOnly: true, secure: true, sameSite: 'strict' }) reply.send({ message: 'Session extended' }) }) ``` ```javascript fastify.post('/secure-action', (request, reply) => { // For sensitive operations, make session expire sooner request.session.options({ maxAge: 300 }) // 5 minutes request.session.set('secureActionTime', Date.now()) reply.send({ message: 'Secure action initiated' }) }) ``` -------------------------------- ### TypeScript Type Definitions Source: https://context7.com/fastify/fastify-secure-session/llms.txt Extend the SessionData interface for custom session properties and FastifyRequest for custom session names to achieve full type safety. ```APIDOC ## Extending SessionData ### Description Allows defining custom types for session properties when using the default 'session' property. ### Usage Use declaration merging to extend the `SessionData` interface. ```typescript import fastify from 'fastify' import secureSession, { Session } from '@fastify/secure-session' declare module '@fastify/secure-session' { interface SessionData { userId: number email: string roles: string[] } } const app = fastify() app.register(secureSession, { key: Buffer.from(process.env.SESSION_KEY!, 'hex'), cookie: { path: '/' } }) app.get('/profile', (request, reply) => { // TypeScript knows these types: const userId = request.session.get('userId') // number | undefined const email = request.session.get('email') // string | undefined const roles = request.session.get('roles') // string[] | undefined // Type-safe property access also works const id: number | undefined = request.session.userId reply.send({ userId, email, roles }) }) ``` ## Extending FastifyRequest for Custom Session Names ### Description Enables the use of custom session names by extending the `FastifyRequest` interface. ### Usage Define a new interface for your custom session data and declare it within the `fastify` module. ```typescript import fastify from 'fastify' import secureSession, { Session } from '@fastify/secure-session' // Define custom session data interface interface AdminSessionData { adminId: number permissions: string[] } // Extend FastifyRequest to include the custom session property declare module 'fastify' { interface FastifyRequest { adminSession: Session } } const app = fastify() app.register(secureSession, { key: Buffer.from(process.env.SESSION_KEY!, 'hex'), cookie: { path: '/', signed: true }, sessionName: 'adminSession' // Specify the custom session name }) app.get('/admin/dashboard', (request, reply) => { // Access the custom session const adminId = request.adminSession.get('adminId') const permissions = request.adminSession.get('permissions') reply.send({ adminId, permissions }) }) ``` ``` -------------------------------- ### Regenerate Session with session.regenerate() Source: https://context7.com/fastify/fastify-secure-session/llms.txt Use `session.regenerate(ignoredFields)` to clear all session data while optionally preserving specific keys. This is crucial for security-sensitive operations like privilege escalation to prevent session fixation attacks. Calling `regenerate()` without arguments clears all session data. ```javascript fastify.post('/elevate-privileges', (request, reply) => { // After re-authentication, regenerate session keeping user identity request.session.regenerate(['userId', 'email']) // Add new elevated privileges request.session.set('isAdmin', true) request.session.set('elevatedAt', Date.now()) reply.send({ message: 'Privileges elevated' }) }) ``` ```javascript fastify.post('/full-logout', (request, reply) => { // Clear everything - complete session reset request.session.regenerate() reply.send({ message: 'Session completely cleared' }) }) ``` -------------------------------- ### session.touch() Source: https://context7.com/fastify/fastify-secure-session/llms.txt Forces the session cookie to be resent to the client, even if the session data has not changed. This is particularly useful for implementing sliding session windows, as it refreshes the cookie's expiration time based on user activity. ```APIDOC ## GET /ping ### Description Resets the session cookie's expiration time without altering the session data, effectively extending the user's session. ### Method GET ### Endpoint /ping ### Parameters None ### Request Example None ### Response #### Success Response (200) - **status** (string) - Indicates the server is responsive ('pong'). - **timestamp** (number) - The server's current timestamp when the request was processed. #### Response Example ```json { "status": "pong", "timestamp": 1678886400000 } ``` ### Notes Each request to this endpoint will reset the session cookie's timer, keeping active users logged in. ``` -------------------------------- ### TypeScript Type Definitions for Session Properties Source: https://context7.com/fastify/fastify-secure-session/llms.txt Extend the SessionData interface using declaration merging for full type safety of session properties. Configure custom session names by extending the FastifyRequest interface. ```typescript import fastify from 'fastify' import secureSession, { Session } from '@fastify/secure-session' // Extend SessionData for default 'session' property declare module '@fastify/secure-session' { interface SessionData { userId: number email: string roles: string[] } } // For custom session names, extend FastifyRequest interface AdminSessionData { adminId: number permissions: string[] } declare module 'fastify' { interface FastifyRequest { adminSession: Session } } const app = fastify() app.register(secureSession, { key: Buffer.from(process.env.SESSION_KEY!, 'hex'), cookie: { path: '/' } }) app.get('/profile', (request, reply) => { // TypeScript knows these types: const userId = request.session.get('userId') // number | undefined const email = request.session.get('email') // string | undefined const roles = request.session.get('roles') // string[] | undefined // Type-safe property access also works const id: number | undefined = request.session.userId reply.send({ userId, email, roles }) }) ``` -------------------------------- ### Refresh Session Cookie Expiration using session.touch() Source: https://context7.com/fastify/fastify-secure-session/llms.txt Use `request.session.touch()` to force the session cookie to be resent, updating its expiration without changing session data. This is ideal for implementing sliding session windows. ```javascript fastify.get('/ping', (request, reply) => { // Update cookie expiration without modifying session data request.session.touch() reply.send({ status: 'pong', timestamp: Date.now() }) }) ``` -------------------------------- ### Add TypeScript Types for Session Data Source: https://github.com/fastify/fastify-secure-session/blob/main/README.md Extend the `SessionData` interface using declaration merging to improve type support for session data. This allows for type-safe access to session properties. ```typescript declare module '@fastify/secure-session' { interface SessionData { foo: string; } } fastify.get('/', (request, reply) => { request.session.get('foo'); // typed `string | undefined` reply.send('hello world') }) ``` ```typescript interface FooSessionData { foo: string; } declare module "fastify" { interface FastifyRequest { foo: Session; } } fastify.get('/', (request, reply) => { request.foo.get('foo'); // typed `string | undefined` reply.send('hello world') }) ```