Skip to content
Open
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
30 changes: 19 additions & 11 deletions packages/evershop/src/modules/cms/services/imageProcessor.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ import path from 'path';
import sharp from 'sharp';
import { CONSTANTS } from '../../../lib/helpers.js';
import { debug } from '../../../lib/log/logger.js';
import { getEnabledTheme } from '../../../lib/util/getEnabledTheme.js';

const hasTransparency = async (imageBuffer: Buffer): Promise<boolean> => {
try {
Expand Down Expand Up @@ -75,6 +76,9 @@ export const imageProcessor = async (
const isExternalUrl = src.startsWith('http://') || src.startsWith('https://');

if (!isExternalUrl) {
// Get the currently enabled theme (if any)
const enabledTheme = getEnabledTheme();

// Special case: Handle assets path format like "/assets/media/image.png" or "/assets/image.png"
if (src.startsWith('/assets/')) {
// Extract the filename after '/assets/'
Expand All @@ -88,10 +92,13 @@ export const imageProcessor = async (
const possiblePaths = [
`media/${assetPath}`,
`public/${assetPath}`
// For themes, we need to check each theme's public directory
// This is more complex and would require listing themes
];

// Add currently enabled theme public directory (if any) to possible paths
if (enabledTheme) {
possiblePaths.push(`themes/${enabledTheme.name}/public/${assetPath}`);
}

let fileExists = false;
for (const possiblePath of possiblePaths) {
try {
Expand Down Expand Up @@ -133,16 +140,17 @@ export const imageProcessor = async (
}

// Only allow specific directories from project root
const allowedPaths = ['media/', 'public/', 'themes/'];
const allowedPaths = ['media/', 'public/'];

const isAllowedPath = allowedPaths.some((allowedPath) => {
if (allowedPath === 'themes/') {
// Special handling for themes: must be themes/<themename>/public/
const themePattern = /^themes\/[^\/]+\/public\//;
return themePattern.test(normalizedPath);
}
return normalizedPath.startsWith(allowedPath);
});
// Only allow the currently enabled theme's public directory (if any),
// not all existing theme folders.
if (enabledTheme) {
allowedPaths.push(`themes/${enabledTheme.name}/public/`);
}

const isAllowedPath = allowedPaths.some((allowedPath) =>
normalizedPath.startsWith(allowedPath)
);

if (!isAllowedPath) {
throw new Error(
Expand Down