securesite
v1.0.4
Published
a light fastify website with basic security
Downloads
295
Readme
securesite
A lightweight, secure web server factory for Fastify with built-in session authentication, security headers, and static file serving.
Features
- 🔐 Session-based Authentication - Secure cookie sessions with customizable login/logout endpoints
- 🛡️ Security First - Helmet.js integration for security headers
- 📁 Static File Serving - Optional static file support with configurable paths
- ⚡ Fastify Powered - High-performance Node.js web framework
- 🎯 Flexible Routing - Declarative route configuration with public/private route support
- 📝 Request Context - Clean handler API with user session, body, query, and params
Installation
npm install securesiteQuick Start
const securesite = require('securesite');
const app = securesite({
secret: 'your-super-secret-key-must-be-at-least-32-chars-long',
onAuthenticate: async (username, password) => {
// Your auth logic here
if (username === 'admin' && password === 'password') {
return { id: 1, username: 'admin' };
}
return null;
}
});
app.listen({ port: 3000 }, (err) => {
if (err) throw err;
console.log('Server running on http://localhost:3000');
});Configuration Options
| Option | Type | Default | Description |
|--------|------|---------|-------------|
| secret | string | required | Session secret (min 32 characters) |
| onAuthenticate | function | null | Async function (username, password) => userData \\| null |
| staticPath | string | null | Path to static files directory |
| loginUrl | string | /login | Custom login endpoint path |
| logoutUrl | string | /logout | Custom logout endpoint path |
| sessionMaxAge | number | 1800000 (30min) | Session cookie max age in milliseconds |
| trustProxy | boolean | true | Trust proxy headers (for secure cookies behind proxy) |
| limit | string | 1mb | Request body size limit |
| verbose | boolean \\| function | false | Enable logging or provide custom logger function |
Route Configuration
Define routes using HTTP method keys (get, post, put, delete, patch):
const app = securesite({
secret: 'your-super-secret-key-must-be-at-least-32-chars-long',
onAuthenticate: async (username, password) => {
// Return user data or null
return { id: 1, username };
},
// Public routes (no authentication required)
get: {
'/': async (ctx) => ({ message: 'Welcome!' }),
'/public': { public: true, handler: async (ctx) => ({ data: 'public data' }) }
},
// Protected routes (require authentication)
post: {
'/api/data': async (ctx) => {
// ctx.user contains authenticated user data
return { created: true, by: ctx.user.username };
}
}
});Handler Context
Route handlers receive a context object (ctx) with:
{
user: req.session.user || null, // Authenticated user data
session: req.session, // Full session object
body: req.body, // Request body
query: req.query, // Query parameters
params: req.params, // URL parameters
headers: req.headers, // Request headers
ip: req.ip, // Client IP address
req: req // Original Fastify request
}Authentication API
Login
POST /login
Content-Type: application/json
{
\"username\": \"admin\",
\"password\": \"password\"
}Success Response:
{
\"success\": true,
\"user\": { \"id\": 1, \"username\": \"admin\" }
}Error Response:
{
\"error\": \"Unauthorized\",
\"message\": \"Invalid credentials\"
}Logout
POST /logoutResponse:
{
\"success\": true
}Complete Example
const securesite = require('securesite');
const path = require('path');
const app = securesite({
secret: process.env.SESSION_SECRET || 'default-secret-key-32-chars-long!!',
staticPath: './public',
verbose: true,
onAuthenticate: async (username, password) => {
// Replace with your database/auth logic
const users = [
{ id: 1, username: 'admin', password: 'admin123', role: 'admin' },
{ id: 2, username: 'user', password: 'user123', role: 'user' }
];
const user = users.find(u => u.username === username && u.password === password);
if (user) {
const { password, ...userData } = user;
return userData;
}
return null;
},
// Public routes
get: {
'/health': { public: true, handler: async () => ({ status: 'ok' }) }
},
// Protected routes
get: {
'/api/profile': async (ctx) => ({
user: ctx.user,
message: `Hello ${ctx.user.username}!`
})
},
post: {
'/api/echo': async (ctx) => ({
received: ctx.body,
user: ctx.user.username
})
}
});
app.listen({ port: 3000, host: '0.0.0.0' }, (err) => {
if (err) {
console.error(err);
process.exit(1);
}
console.log('🚀 Server ready at http://localhost:3000');
});Security Considerations
- Session Secret: Always use a strong, random secret of at least 32 characters in production
- HTTPS: Set
NODE_ENV=productionto enable secure cookies (requires HTTPS) - Trust Proxy: Enable when running behind a reverse proxy (Nginx, etc.)
- Body Limit: Adjust
limitoption based on your application's needs
Dependencies
- fastify - Fast and low overhead web framework
- @fastify/helmet - Security headers
- @fastify/cookie - Cookie parsing
- @fastify/session - Session management
- @fastify/static - Static file serving (optional)
License
MIT
Author
littlejustnode
