mirror of
https://github.com/open-reception/appointment-booking-software.git
synced 2026-08-17 21:25:52 +02:00
#53 Auth handler updates
This commit is contained in:
@@ -0,0 +1,102 @@
|
||||
# API Routes Authentication Overview
|
||||
|
||||
This document provides a comprehensive overview of all API routes and their authentication requirements.
|
||||
|
||||
## 🔓 Public Routes (No Authentication Required)
|
||||
|
||||
### Authentication Routes
|
||||
|
||||
- `/api/auth/challenge` - Generate WebAuthn challenge
|
||||
- `/api/auth/login` - User login (WebAuthn or passphrase)
|
||||
- `/api/auth/register` - User registration
|
||||
- `/api/auth/confirm` - Email confirmation
|
||||
- `/api/auth/resend-confirmation` - Resend confirmation email
|
||||
|
||||
### System Routes
|
||||
|
||||
- `/api/health` - Health check
|
||||
- `/api/health/services` - Service health status
|
||||
- `/api/docs` - API documentation
|
||||
- `/api/openapi.json` - OpenAPI specification
|
||||
- `/api/env` - Environment information
|
||||
- `/api/log` - Logging endpoint
|
||||
|
||||
### Admin Setup Routes
|
||||
|
||||
- `/api/admin/init` - Initialize first global admin
|
||||
- `/api/admin/exists` - Check if global admin exists
|
||||
|
||||
## 🔒 Protected Routes (Authentication Required)
|
||||
|
||||
### Protected Auth Routes (Any Authenticated User)
|
||||
|
||||
- `/api/auth/logout` - User logout
|
||||
- `/api/auth/refresh` - Refresh authentication tokens
|
||||
- `/api/auth/session` - Get current session info
|
||||
- `/api/auth/sessions` - Manage user sessions
|
||||
- `/api/auth/sessions/[sessionId]` - Manage specific session
|
||||
- `/api/auth/passkeys` - Add additional WebAuthn keys
|
||||
|
||||
### Global Admin Routes (GLOBAL_ADMIN Role Required)
|
||||
|
||||
- `/api/tenants` - Create and list tenants
|
||||
- `/api/tenants/[id]` - Manage specific tenant
|
||||
- `/api/tenants/[id]/config` - Tenant configuration
|
||||
- `/api/tenants/config/defaults` - Default tenant configuration
|
||||
|
||||
### Admin Routes (ADMIN Role Required)
|
||||
|
||||
- `/api/admin/tenant` - Tenant management for admins
|
||||
|
||||
## 📋 Route Categories
|
||||
|
||||
### By Authentication Level:
|
||||
|
||||
1. **Public**: 12 routes - No authentication required
|
||||
2. **Protected Auth**: 6 routes - Any authenticated user
|
||||
3. **Global Admin**: 5 routes - GLOBAL_ADMIN role required
|
||||
|
||||
### By Functionality:
|
||||
|
||||
- **Authentication**: 11 routes (5 public, 6 protected)
|
||||
- **Admin Management**: 2 routes (2 public)
|
||||
- **Tenant Management**: 5 routes (5 global admin)
|
||||
- **System/Utility**: 6 routes (6 public)
|
||||
|
||||
## 🔧 Implementation Details
|
||||
|
||||
### Authentication Flow:
|
||||
|
||||
1. **Session Cookie**: `session` cookie for browser-based auth
|
||||
2. **Bearer Token**: Authorization header for API access
|
||||
3. **Role Checking**: `AuthorizationService.hasRole()` for role verification
|
||||
|
||||
### Security Features:
|
||||
|
||||
- JWT token verification
|
||||
- Session validation
|
||||
- Role-based access control (RBAC)
|
||||
- Proper HTTP status codes (401 vs 403)
|
||||
- Detailed logging for security events
|
||||
|
||||
### Configuration Location:
|
||||
|
||||
- Main config: `src/server-hooks/authHandle.ts`
|
||||
- Authorization service: `src/lib/server/auth/authorization-service.ts`
|
||||
- Session service: `src/lib/server/auth/session-service.ts`
|
||||
|
||||
## 🚨 Security Considerations
|
||||
|
||||
1. **Public Routes**: Should be carefully reviewed for security implications
|
||||
2. **Protected Routes**: Require valid authentication but no specific roles
|
||||
3. **Global Admin Routes**: High privilege routes requiring GLOBAL_ADMIN role
|
||||
4. **Rate Limiting**: Applied to all routes via `rateLimitHandle`
|
||||
5. **CORS**: Properly configured for API access
|
||||
6. **HTTPS**: Security headers enforced in production
|
||||
|
||||
## 📝 Notes
|
||||
|
||||
- All routes are automatically covered by the authentication middleware
|
||||
- New API routes should be explicitly added to the appropriate category
|
||||
- Role requirements are enforced at the middleware level
|
||||
- Session management is handled automatically for authenticated routes
|
||||
@@ -8,31 +8,58 @@ import { AuthorizationService } from "$lib/server/auth/authorization-service";
|
||||
const logger = new UniversalLogger().setContext("AuthHandle");
|
||||
|
||||
const SESSION_COOKIE_NAME = "session";
|
||||
const PROTECTED_PATHS = ["/api/admin", "/api/tenant-admin"];
|
||||
const PROTECTED_PATHS = ["/api/admin", "/api/tenant-admin", "/api/tenants", "/api/auth/register"];
|
||||
const PUBLIC_PATHS = [
|
||||
"/api/auth",
|
||||
"/api/auth/challenge",
|
||||
"/api/auth/login",
|
||||
|
||||
"/api/auth/confirm",
|
||||
"/api/auth/resend-confirmation",
|
||||
"/api/health",
|
||||
"/api/docs",
|
||||
"/api/openapi.json",
|
||||
"/api/env",
|
||||
"/api/log",
|
||||
"/api/admin/init",
|
||||
"/api/admin/confirm",
|
||||
"/api/admin/exists"
|
||||
];
|
||||
const GLOBAL_ADMIN_PATHS = ["/api/admin"];
|
||||
const GLOBAL_ADMIN_PATHS = ["/api/admin", "/api/tenants"];
|
||||
const ADMIN_PATHS = ["/api/tenant-admin"];
|
||||
|
||||
const PROTECTED_AUTH_PATHS = [
|
||||
"/api/auth/logout",
|
||||
"/api/auth/refresh",
|
||||
"/api/auth/session",
|
||||
"/api/auth/sessions",
|
||||
"/api/auth/passkeys"
|
||||
];
|
||||
|
||||
export const authHandle: Handle = async ({ event, resolve }) => {
|
||||
const { url, request } = event;
|
||||
const path = url.pathname;
|
||||
|
||||
const isProtectedPath = PROTECTED_PATHS.some((protectedPath) => path.startsWith(protectedPath));
|
||||
const isPublicPath = PUBLIC_PATHS.some((publicPath) => path.startsWith(publicPath));
|
||||
const isProtectedAuthPath = PROTECTED_AUTH_PATHS.some((authPath) => path.startsWith(authPath));
|
||||
const isGlobalAdminPath = GLOBAL_ADMIN_PATHS.some((gadPath) => path.startsWith(gadPath));
|
||||
const isAdminPath = ADMIN_PATHS.some((gadPath) => path.startsWith(gadPath));
|
||||
|
||||
if (!isProtectedPath || isPublicPath) {
|
||||
// Allow public paths
|
||||
if (isPublicPath) {
|
||||
return resolve(event);
|
||||
}
|
||||
|
||||
// Require authentication for protected paths and protected auth paths
|
||||
if (!isProtectedPath && !isProtectedAuthPath) {
|
||||
return new Response(
|
||||
JSON.stringify({ error: `Path ${path} not handled by auth. This is an error` }),
|
||||
{
|
||||
status: 400,
|
||||
headers: { "Content-Type": "application/json" }
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
let sessionToken: string | null = null;
|
||||
let accessToken: string | null = null;
|
||||
|
||||
@@ -87,9 +114,10 @@ export const authHandle: Handle = async ({ event, resolve }) => {
|
||||
|
||||
event.locals.user = user;
|
||||
event.locals.sessionToken = sessionToken || undefined;
|
||||
|
||||
if (isGlobalAdminPath && !AuthorizationService.hasRole(user, "GLOBAL_ADMIN")) {
|
||||
return new Response(JSON.stringify({ error: "Authentication failed" }), {
|
||||
status: 401,
|
||||
status: 403,
|
||||
headers: { "Content-Type": "application/json" }
|
||||
});
|
||||
} else if (
|
||||
@@ -97,10 +125,12 @@ export const authHandle: Handle = async ({ event, resolve }) => {
|
||||
!AuthorizationService.hasAnyRole(user, ["GLOBAL_ADMIN", "TENANT_ADMIN"])
|
||||
) {
|
||||
return new Response(JSON.stringify({ error: "Authentication failed" }), {
|
||||
status: 401,
|
||||
status: 403,
|
||||
headers: { "Content-Type": "application/json" }
|
||||
});
|
||||
}
|
||||
// Protected auth paths require any authenticated user (no specific role required)
|
||||
// The authentication check above is sufficient
|
||||
|
||||
logger.debug(`User authenticated: ${user.email} for ${path}`);
|
||||
|
||||
|
||||
Reference in New Issue
Block a user