Skip to content

Commit 4958e3b

Browse files
authored
Merge pull request #186 from deploystackio/main
prod release
2 parents d34f196 + afd9131 commit 4958e3b

15 files changed

Lines changed: 925 additions & 766 deletions

File tree

.gitignore

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -77,4 +77,8 @@ coverage/
7777
._*.tsx
7878
._*.css
7979
._*.cjs
80+
._*.mjs
81+
._*.js
82+
._*.html
83+
._*.scss
8084
out/

app/[[...slug]]/page.tsx

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,6 @@ import { getFinalPageTitle } from '@/lib/h1-extractor';
99
import { readFile } from 'fs/promises';
1010
import { getMDXComponents } from '@/mdx-components';
1111
import { homeOptions, docsOptions } from '../layout.config';
12-
import { docs } from '@/.source/index';
1312

1413
export default async function Page({
1514
params,

app/sitemap.ts

Lines changed: 9 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -3,28 +3,17 @@ import { source } from '@/lib/source';
33

44
export const dynamic = 'force-static';
55

6-
function getPages(tree: any): any[] {
7-
const pages: any[] = [];
8-
9-
function traverse(nodes: any[]) {
10-
for (const node of nodes) {
11-
if (node.type === 'page') {
12-
pages.push(node);
13-
} else if ('children' in node) {
14-
traverse(node.children);
15-
}
16-
}
17-
}
18-
19-
traverse(tree.children);
20-
return pages;
21-
}
22-
236
export default function sitemap(): MetadataRoute.Sitemap {
24-
const pages = getPages(source.pageTree).map((page) => ({
7+
// Get all pages from source.getPages() which combines all sources
8+
const allPages = source.getPages();
9+
10+
// Map pages to sitemap entries
11+
const sitemapEntries = allPages.map((page) => ({
2512
url: new URL(page.url, 'https://docs.deploystack.io').toString(),
26-
lastModified: page.lastModified,
13+
lastModified: page.data.lastModified ? new Date(page.data.lastModified) : undefined,
14+
changeFrequency: 'weekly' as const,
15+
priority: page.url === '/' ? 1.0 : page.url.startsWith('/development') || page.url.startsWith('/self-hosted') ? 0.7 : 0.8,
2716
}));
2817

29-
return pages;
18+
return sitemapEntries;
3019
}

docs/development/backend/api-security.mdx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -179,7 +179,7 @@ fastify.get('/dual-auth-endpoint', {
179179
});
180180
```
181181

182-
For detailed OAuth2 implementation, see the [Backend OAuth Implementation Guide](/development/backend/oauth) and [Backend Security Policy](/development/backend/security#oauth2-server-security).
182+
For detailed OAuth2 implementation, see the [Backend OAuth Implementation Guide](/development/backend/oauth-providers) and [Backend Security Policy](/development/backend/security#oauth2-server-security).
183183

184184
### Team-Aware Permission System
185185

docs/development/backend/auth.mdx

Lines changed: 271 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,274 @@
11
---
2-
title: Authentication System
3-
description: Complete guide to implementing user authentication in DeployStack Backend.
2+
title: Backend Authentication System
3+
description: Technical documentation for the DeployStack backend authentication implementation, including session management, password hashing, and authentication flows.
44
---
55

6-
# DeployStack Authentication System
6+
# Backend Authentication System
7+
8+
This document provides technical details about the DeployStack backend authentication system implementation. For user-facing authentication configuration, see [Authentication Methods](/auth). For OAuth provider implementation details, see [OAuth Provider Implementation](/development/backend/oauth-providers) and [OAuth2 Server Implementation](/development/backend/oauth2-server).
9+
10+
## Architecture Overview
11+
12+
The backend authentication system is built on several key components:
13+
14+
- **[Lucia v3](https://lucia-auth.com/)** - Core session management and authentication library
15+
- **[Argon2](https://github.com/napi-rs/node-rs)** - Industry-standard password hashing
16+
- **[Arctic](https://arctic.js.org/)** - OAuth 2.0 client library for provider integration
17+
- **Database-backed sessions** - SQLite/Turso storage for session persistence
18+
- **Dual authentication** - Support for both cookie sessions and OAuth2 Bearer tokens
19+
20+
## Authentication Flow Types
21+
22+
The backend supports multiple authentication flows to accommodate different client types and use cases:
23+
24+
### 1. Email/Password Authentication
25+
26+
Traditional username/password authentication with email verification:
27+
28+
- **Registration** (`/api/auth/email/register`) - Creates new user accounts
29+
- **Login** (`/api/auth/email/login`) - Authenticates existing users
30+
- **Email Verification** - Optional verification requirement based on global settings
31+
- **Password Reset** - Secure token-based password recovery
32+
33+
### 2. OAuth Provider Authentication
34+
35+
Third-party authentication via OAuth providers (currently GitHub):
36+
37+
- **Provider Login** (`/api/auth/github/login`) - Initiates OAuth flow
38+
- **OAuth Callback** (`/api/auth/github/callback`) - Handles provider response
39+
- **Account Linking** - Automatically links OAuth accounts to existing users by email
40+
- **User Provisioning** - Creates new users from OAuth profile data
41+
42+
### 3. OAuth2 Server Authentication
43+
44+
Bearer token authentication for programmatic API access:
45+
46+
- **Authorization** (`/api/oauth2/auth`) - OAuth2 authorization endpoint
47+
- **Token Exchange** (`/api/oauth2/token`) - Exchanges codes for access tokens
48+
- **Bearer Authentication** - API access using Authorization header
49+
- **Scope-based Permissions** - Fine-grained access control
50+
51+
## Core Components
52+
53+
### Session Management
54+
55+
Sessions are managed through Lucia v3 with database persistence:
56+
57+
#### Session Storage
58+
59+
Sessions are stored in the `authSession` table with the following structure:
60+
- **Session ID**: 40-character cryptographically random identifier
61+
- **User ID**: Foreign key reference to the authenticated user
62+
- **Expiration**: 30-day lifetime from creation
63+
- **Cookie Attributes**: httpOnly, secure (production), sameSite (lax)
64+
65+
#### Session Lifecycle
66+
67+
1. **Creation**: Generated after successful authentication
68+
2. **Validation**: Checked on each request via `authHook`
69+
3. **Refresh**: Sessions are not automatically extended
70+
4. **Expiration**: Expired sessions are deleted on validation attempt
71+
5. **Logout**: Explicit session deletion
72+
73+
### Password Security
74+
75+
Passwords are secured using Argon2id with carefully chosen parameters:
76+
77+
#### Hashing Parameters
78+
- **Algorithm**: Argon2id (resistant to side-channel and GPU attacks)
79+
- **Memory Cost**: 19456 KB (19 MB)
80+
- **Time Cost**: 2 iterations
81+
- **Parallelism**: 1 thread
82+
- **Output Length**: 32 bytes
83+
- **Salt**: Unique per password, automatically generated
84+
85+
#### Password Verification
86+
87+
The verification process uses constant-time comparison to prevent timing attacks:
88+
1. Extract stored hash and salt from database
89+
2. Re-compute hash with provided password
90+
3. Compare hashes using constant-time algorithm
91+
4. Return authentication result
92+
93+
### Authentication Hooks
94+
95+
The backend uses Fastify hooks for request-level authentication:
96+
97+
#### authHook (Global)
98+
99+
Runs on every request to establish authentication context:
100+
- Reads session cookie if present
101+
- Validates session against database
102+
- Populates `request.user` and `request.session`
103+
- Handles expired session cleanup
104+
- Skips authentication if database not ready
105+
106+
#### requireAuthHook (Route-specific)
107+
108+
Enforces authentication on protected routes:
109+
- Checks for valid user and session
110+
- Returns 401 Unauthorized if not authenticated
111+
- Used as preValidation hook on protected endpoints
112+
113+
## User Registration Flow
114+
115+
### Email Registration Process
116+
117+
1. **Validation**: Input validation using Zod schemas
118+
2. **Uniqueness Check**: Verify username and email availability
119+
3. **Password Hashing**: Secure hash generation with Argon2
120+
4. **User Creation**: Database insertion with role assignment
121+
5. **First User Logic**: Automatic global_admin role for first user
122+
6. **Email Verification**: Send verification email (if enabled)
123+
7. **Team Creation**: Automatic default team creation
124+
8. **Session Creation**: Immediate login after registration
125+
9. **Response**: User data and success message
126+
127+
### Role Assignment
128+
129+
- **First User**: Automatically assigned `global_admin` role
130+
- **Subsequent Users**: Assigned `global_user` role
131+
- **OAuth Users**: Always assigned `global_user` role
132+
- **Email Verification**: First user auto-verified, others depend on settings
133+
134+
## Login Authentication Flow
135+
136+
### Email Login Process
137+
138+
1. **Global Check**: Verify login is enabled in settings
139+
2. **User Lookup**: Find user by email or username
140+
3. **Password Verification**: Argon2 hash comparison
141+
4. **Email Verification Check**: Ensure email is verified (if required)
142+
5. **Session Creation**: Generate new 30-day session
143+
6. **Cookie Setting**: Set httpOnly session cookie
144+
7. **Response**: User data and session established
145+
146+
### Authentication State
147+
148+
After successful login, the following state is established:
149+
- **Session Cookie**: Contains session ID
150+
- **Database Session**: Active session record
151+
- **User Context**: Available in `request.user`
152+
- **Session Context**: Available in `request.session`
153+
154+
## Email Verification System
155+
156+
### Verification Requirements
157+
158+
- **Controlled by**: `global.send_mail` setting
159+
- **First User**: Always auto-verified for system access
160+
- **Email Users**: Must verify before login (when enabled)
161+
- **OAuth Users**: Auto-verified (provider emails trusted)
162+
163+
### Verification Token Flow
164+
165+
1. **Token Generation**: 32-character random token
166+
2. **Token Storage**: Hashed with Argon2 (same as passwords)
167+
3. **Email Dispatch**: Verification link sent via SMTP
168+
4. **Token Validation**: Constant-time comparison
169+
5. **Account Activation**: Email marked as verified
170+
6. **Token Cleanup**: Single-use, expires after 24 hours
171+
172+
## Password Reset Flow
173+
174+
### Reset Process
175+
176+
1. **Request Initiation**: User provides email address
177+
2. **Token Generation**: Secure random reset token
178+
3. **Token Storage**: Hashed and stored with expiration
179+
4. **Email Notification**: Reset link sent to user
180+
5. **Token Validation**: Verify token and expiration
181+
6. **Password Update**: New password hashed and stored
182+
7. **Token Invalidation**: Used tokens are deleted
183+
8. **Session Creation**: Optional auto-login after reset
184+
185+
### Security Measures
186+
187+
- **Rate Limiting**: Prevent brute force attempts
188+
- **Token Expiration**: 1-hour validity window
189+
- **Single Use**: Tokens invalidated after use
190+
- **User Notification**: Email sent on password change
191+
192+
## Dual Authentication Support
193+
194+
The backend supports both cookie-based and Bearer token authentication simultaneously:
195+
196+
### Cookie Authentication
197+
198+
- **Primary Use**: Web application sessions
199+
- **Validation**: Via `authHook` on every request
200+
- **Storage**: Server-side session with cookie identifier
201+
- **Lifetime**: 30-day expiration
202+
203+
### Bearer Token Authentication
204+
205+
- **Primary Use**: CLI and API access
206+
- **Validation**: Via `oauthMiddleware`
207+
- **Format**: OAuth2 access tokens
208+
- **Lifetime**: 1-hour access, 30-day refresh
209+
210+
### Middleware Integration
211+
212+
Endpoints can accept either authentication method using `requireAuthenticationAny()`:
213+
- First checks for cookie session
214+
- Falls back to Bearer token validation
215+
- Populates same `request.user` interface
216+
- Maintains authentication type in context
217+
218+
## Security Best Practices
219+
220+
### Implementation Security
221+
222+
1. **Password Storage**: Never store plaintext, always use Argon2
223+
2. **Session Management**: Cryptographically secure IDs, proper expiration
224+
3. **Token Security**: Constant-time comparisons, secure random generation
225+
4. **HTTPS Enforcement**: Secure cookies in production
226+
5. **CSRF Protection**: State parameters in OAuth, sameSite cookies
227+
228+
### Validation and Sanitization
229+
230+
- **Input Validation**: All inputs validated with Zod schemas
231+
- **Email Normalization**: Lowercase conversion before storage
232+
- **SQL Injection Prevention**: Parameterized queries via Drizzle ORM
233+
- **XSS Prevention**: httpOnly cookies, no client-side session access
234+
235+
## Database Schema
236+
237+
The authentication system uses the following core tables:
238+
239+
### authUser Table
240+
241+
Stores user account information:
242+
- User identification (id, username, email)
243+
- Authentication data (hashed_password, auth_type)
244+
- Profile information (first_name, last_name)
245+
- OAuth provider IDs (github_id)
246+
- Account status (email_verified, role_id)
247+
248+
### authSession Table
249+
250+
Manages active user sessions:
251+
- Session identification (id)
252+
- User association (user_id)
253+
- Expiration tracking (expires_at)
254+
255+
### Additional Tables
256+
257+
Supporting tables for full functionality:
258+
- **email_verification_tokens**: Email verification tokens
259+
- **password_reset_tokens**: Password reset tokens
260+
- **oauth_authorization_codes**: OAuth2 authorization codes
261+
- **oauth_access_tokens**: OAuth2 access tokens
262+
- **oauth_refresh_tokens**: OAuth2 refresh tokens
263+
264+
## API Reference
265+
266+
For a complete list of authentication API endpoints and their specifications, see the [Backend API Documentation](/development/backend/api). The API documentation includes OpenAPI specifications with detailed request/response schemas for all authentication endpoints.
267+
268+
## Related Documentation
269+
270+
- [Security Policy](/development/backend/security) - Security implementation details
271+
- [Database Schema](/development/backend/database) - Complete database structure
272+
- [API Documentation](/development/backend/api) - Full API reference
273+
- [OAuth Provider Implementation](/development/backend/oauth-providers) - Third-party OAuth login setup
274+
- [OAuth2 Server Implementation](/development/backend/oauth2-server) - OAuth2 server for API access

0 commit comments

Comments
 (0)