
Security News
Crates.io Users Targeted by Phishing Emails
The Rust Security Response WG is warning of phishing emails from rustfoundation.dev targeting crates.io users.
@analog-tools/session
Advanced tools
⚠️ IMPORTANT: Early Development Stage ⚠️
This project is in its early development stage. Breaking changes may happen frequently as the APIs evolve. Use with caution in production environments.
A powerful session management library for H3-based applications (Nuxt, Nitro, Analog), providing persistent sessions with various storage backends.
# Using npm
npm install @analog-tools/session
# Using pnpm
pnpm add @analog-tools/session
# Using yarn
yarn add @analog-tools/session
Here's a basic example using the Unstorage session store with Redis:
import { defineEventHandler } from 'h3';
import { useSession, UnstorageSessionStore } from '@analog-tools/session';
import { createStorage } from 'unstorage';
import redisDriver from 'unstorage/drivers/redis';
// Create a Redis-backed session store
const sessionStore = new UnstorageSessionStore(
createStorage({
driver: redisDriver({
host: 'localhost',
port: 6379,
}),
}),
{
ttl: 60 * 60 * 24, // 1 day
prefix: 'sess',
}
);
export default defineEventHandler(async (event) => {
// Initialize session
await useSession(event, {
store: sessionStore,
secret: 'my-super-secret-key',
});
// Access session data
const session = event.context.sessionHandler;
// Get session data
console.log(session.data);
// Update session data
session.update((data) => ({
...data,
visits: (data.visits || 0) + 1,
}));
// Save session (required after modifications)
await session.save();
return {
sessionId: session.id,
visits: session.data.visits,
};
});
// src/server/routes/api/auth/login.ts
import { defineEventHandler, readBody } from 'h3';
import { useSession } from '@analog-tools/session';
export default defineEventHandler(async (event) => {
const { username, password } = await readBody(event);
// Validate credentials (example)
// Note: validateUser is a placeholder function you would implement
// to validate user credentials against your database
const user = await validateUser(username, password);
if (!user) {
return { success: false, message: 'Invalid credentials' };
}
// Setup session
await useSession(event);
// Store user info in session
const session = event.context.sessionHandler;
session.set({
userId: user.id,
username: user.username,
role: user.role,
isAuthenticated: true,
});
// Save session
await session.save();
return { success: true };
});
Create a session configuration file:
// src/lib/session.ts
import { createStorage } from 'unstorage';
import redisDriver from 'unstorage/drivers/redis';
import { UnstorageSessionStore } from '@analog-tools/session';
// Environment variables
const SESSION_SECRET = process.env.SESSION_SECRET || 'development-secret';
const REDIS_HOST = process.env.REDIS_HOST || 'localhost';
const REDIS_PORT = Number(process.env.REDIS_PORT || 6379);
// Create Redis storage
const storage = createStorage({
driver: redisDriver({
host: REDIS_HOST,
port: REDIS_PORT,
}),
});
// Create session store
export const sessionStore = new UnstorageSessionStore(storage, {
ttl: 60 * 60 * 24 * 7, // 1 week
prefix: 'app-sess',
});
// Session configuration
export const sessionConfig = {
store: sessionStore,
secret: SESSION_SECRET,
cookie: {
path: '/',
httpOnly: true,
secure: process.env.NODE_ENV === 'production',
maxAge: 60 * 60 * 24 * 7, // 1 week
},
saveUninitialized: false,
};
// src/server/middleware/session.ts
import { defineEventHandler } from 'h3';
import { useSession } from '@analog-tools/session';
import { sessionConfig } from '../../lib/session';
export default defineEventHandler(async (event) => {
await useSession(event, sessionConfig);
});
To apply the session middleware in your AnalogJS application, you can use one of the following approaches:
// src/server/middleware/middleware.ts
import { defineEventHandler } from 'h3';
import { useSession } from '@analog-tools/session';
import { sessionConfig } from '../../lib/session';
// This middleware will be applied to all routes
export default defineEventHandler(async (event) => {
await useSession(event, sessionConfig);
});
// src/server/middleware/auth.ts
import { defineEventHandler, createError, getRouterParam } from 'h3';
export default defineEventHandler(async (event) => {
// Access session from previous middleware
const session = event.context.sessionHandler;
// Check if user is authenticated
if (!session?.data?.isAuthenticated) {
throw createError({
statusCode: 401,
message: 'Authentication required',
});
}
});
Then, in your API routes:
// src/server/routes/api/protected/[id].ts
import { defineEventHandler, getRouterParam } from 'h3';
// Middleware runs first, ensuring authentication
export default defineEventHandler(async (event) => {
const session = event.context.sessionHandler;
const id = getRouterParam(event, 'id');
// User is guaranteed to be authenticated here
return {
id,
username: session.data.username,
message: `This is protected resource ${id}`,
};
});
@analog-tools/session provides multiple storage backends, each with different characteristics:
Store Type | Description | Best For | Configuration Complexity |
---|---|---|---|
UnstorageSessionStore | Uses Unstorage to support multiple storage drivers (Redis, Memory, FS, etc.). | Flexibility and adaptability to different environments. | Medium |
RedisSessionStore | Specialized implementation optimized for Redis. | High-performance production environments. | Low |
Memory (via Unstorage) | In-memory storage that doesn't persist across restarts. | Development and testing. | Very Low |
import { createStorage } from 'unstorage';
import memoryDriver from 'unstorage/drivers/memory';
import { UnstorageSessionStore } from '@analog-tools/session';
// Create a memory-backed session store (not persistent across restarts)
const sessionStore = new UnstorageSessionStore(
createStorage({ driver: memoryDriver() }),
{ ttl: 3600 } // 1 hour
);
You can define your session data structure by extending the SessionDataT
interface:
// Define your session data structure
declare module '@analog-tools/session' {
export interface SessionDataT {
userId?: string;
username?: string;
isAuthenticated: boolean;
lastAccess?: Date;
preferences?: {
theme: 'light' | 'dark';
language: string;
};
}
}
To rotate session secrets without invalidating existing sessions:
await useSession(event, {
store: sessionStore,
// Last secret is used for signing new cookies
// All secrets are used for verifying existing cookies
secret: ['old-secret-1', 'old-secret-2', 'new-secret'],
});
MIT
This package is inspired by and contains code adapted from @scayle/h3-session, which is based on express-session. We extend our gratitude to the original authors for their excellent work.
This library was generated with Nx.
Run nx test session
to execute the unit tests.
Run nx build session
to build the library.
FAQs
Session management for AnalogJS server-side applications
The npm package @analog-tools/session receives a total of 12 weekly downloads. As such, @analog-tools/session popularity was classified as not popular.
We found that @analog-tools/session demonstrated a healthy version release cadence and project activity because the last version was released less than a year ago. It has 1 open source maintainer collaborating on the project.
Did you know?
Socket for GitHub automatically highlights issues in each pull request and monitors the health of all your open source dependencies. Discover the contents of your packages and block harmful activity before you install or update your dependencies.
Security News
The Rust Security Response WG is warning of phishing emails from rustfoundation.dev targeting crates.io users.
Product
Socket now lets you customize pull request alert headers, helping security teams share clear guidance right in PRs to speed reviews and reduce back-and-forth.
Product
Socket's Rust support is moving to Beta: all users can scan Cargo projects and generate SBOMs, including Cargo.toml-only crates, with Rust-aware supply chain checks.