mirror of
https://github.com/AutoMaker-Org/automaker.git
synced 2026-02-04 09:13:08 +00:00
fix: add authentication validation to image endpoint for web mode
Adds authentication checks to the /api/fs/image endpoint to validate session tokens in web mode. This ensures background images and other image assets load correctly in web mode by validating: - session token from query parameter (web mode) - API key from query parameter (Electron mode) - session cookie (web mode fallback) - X-API-Key and X-Session-Token headers This fixes the issue where kanban board background images were not visible in web mode because the image request lacked proper authentication. Co-Authored-By: Claude Haiku 4.5 <noreply@anthropic.com>
This commit is contained in:
@@ -1,16 +1,33 @@
|
|||||||
/**
|
/**
|
||||||
* GET /image endpoint - Serve image files
|
* GET /image endpoint - Serve image files
|
||||||
|
*
|
||||||
|
* Requires authentication via:
|
||||||
|
* - apiKey query parameter (Electron mode)
|
||||||
|
* - token query parameter (web mode)
|
||||||
|
* - session cookie (web mode)
|
||||||
|
* - X-API-Key header (Electron mode)
|
||||||
|
* - X-Session-Token header (web mode)
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import type { Request, Response } from 'express';
|
import type { Request, Response } from 'express';
|
||||||
import * as secureFs from '../../../lib/secure-fs.js';
|
import * as secureFs from '../../../lib/secure-fs.js';
|
||||||
import path from 'path';
|
import path from 'path';
|
||||||
import { PathNotAllowedError } from '@automaker/platform';
|
import { PathNotAllowedError } from '@automaker/platform';
|
||||||
|
import { validateApiKey, validateSession } from '../../../lib/auth.js';
|
||||||
import { getErrorMessage, logError } from '../common.js';
|
import { getErrorMessage, logError } from '../common.js';
|
||||||
|
|
||||||
|
const SESSION_COOKIE_NAME = 'automaker_session';
|
||||||
|
|
||||||
export function createImageHandler() {
|
export function createImageHandler() {
|
||||||
return async (req: Request, res: Response): Promise<void> => {
|
return async (req: Request, res: Response): Promise<void> => {
|
||||||
try {
|
try {
|
||||||
|
// Authenticate the request
|
||||||
|
const isAuthenticated = checkImageAuthentication(req);
|
||||||
|
if (!isAuthenticated) {
|
||||||
|
res.status(401).json({ success: false, error: 'Authentication required' });
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
const { path: imagePath, projectPath } = req.query as {
|
const { path: imagePath, projectPath } = req.query as {
|
||||||
path?: string;
|
path?: string;
|
||||||
projectPath?: string;
|
projectPath?: string;
|
||||||
@@ -64,3 +81,41 @@ export function createImageHandler() {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Check if image request is authenticated
|
||||||
|
* Supports multiple authentication methods
|
||||||
|
*/
|
||||||
|
function checkImageAuthentication(req: Request): boolean {
|
||||||
|
// Check for API key in header (Electron mode)
|
||||||
|
const headerKey = req.get('x-api-key');
|
||||||
|
if (headerKey && validateApiKey(headerKey)) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Check for session token in header (web mode)
|
||||||
|
const sessionTokenHeader = req.get('x-session-token');
|
||||||
|
if (sessionTokenHeader && validateSession(sessionTokenHeader)) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Check for API key in query parameter (fallback)
|
||||||
|
const queryKey = req.query.apiKey as string | undefined;
|
||||||
|
if (queryKey && validateApiKey(queryKey)) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Check for session token in query parameter (web mode with token)
|
||||||
|
const queryToken = req.query.token as string | undefined;
|
||||||
|
if (queryToken && validateSession(queryToken)) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Check for session cookie (web mode)
|
||||||
|
const sessionCookie = req.cookies?.[SESSION_COOKIE_NAME];
|
||||||
|
if (sessionCookie && validateSession(sessionCookie)) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user