mirror of
https://github.com/ZSCGR/CloudFlare-ImgBed.git
synced 2026-08-13 04:03:42 +08:00
feat: configure image resizing in security settings
This commit is contained in:
File diff suppressed because one or more lines are too long
Binary file not shown.
File diff suppressed because one or more lines are too long
Binary file not shown.
@@ -1 +1 @@
|
||||
<!doctype html><html lang=""><head><meta charset="utf-8"><meta http-equiv="X-UA-Compatible" content="IE=edge"><meta name="viewport" content="width=device-width,initial-scale=1,maximum-scale=1,user-scalable=no,viewport-fit=cover"><link rel="icon" href="/static/media/logo.png"><link rel="apple-touch-icon" href="/static/media/logo.png"><link rel="mask-icon" href="/static/media/logo.png" color="#f4b400"><meta name="description" content="Sanyue ImgHub - A modern file hosting platform"><meta name="keywords" content="Sanyue, ImgHub, file hosting, image hosting, cloud storage"><meta name="author" content="SanyueQi"><title>Sanyue ImgHub</title><script defer="defer" src="/js/chunk-vendors.6243340b.js"></script><script defer="defer" src="/js/app.739c9465.js"></script><link href="/css/chunk-vendors.f9cd4701.css" rel="stylesheet"><link href="/css/app.710cde74.css" rel="stylesheet"></head><body><noscript><strong>We're sorry but sanyue_imghub doesn't work properly without JavaScript enabled. Please enable it to continue.</strong></noscript><div id="app"></div></body></html>
|
||||
<!doctype html><html lang=""><head><meta charset="utf-8"><meta http-equiv="X-UA-Compatible" content="IE=edge"><meta name="viewport" content="width=device-width,initial-scale=1,maximum-scale=1,user-scalable=no,viewport-fit=cover"><link rel="icon" href="/static/media/logo.png"><link rel="apple-touch-icon" href="/static/media/logo.png"><link rel="mask-icon" href="/static/media/logo.png" color="#f4b400"><meta name="description" content="Sanyue ImgHub - A modern file hosting platform"><meta name="keywords" content="Sanyue, ImgHub, file hosting, image hosting, cloud storage"><meta name="author" content="SanyueQi"><title>Sanyue ImgHub</title><script defer="defer" src="/js/chunk-vendors.6243340b.js"></script><script defer="defer" src="/js/app.50a5ba1e.js"></script><link href="/css/chunk-vendors.f9cd4701.css" rel="stylesheet"><link href="/css/app.710cde74.css" rel="stylesheet"></head><body><noscript><strong>We're sorry but sanyue_imghub doesn't work properly without JavaScript enabled. Please enable it to continue.</strong></noscript><div id="app"></div></body></html>
|
||||
Binary file not shown.
File diff suppressed because one or more lines are too long
Binary file not shown.
File diff suppressed because one or more lines are too long
Binary file not shown.
File diff suppressed because one or more lines are too long
Binary file not shown.
File diff suppressed because one or more lines are too long
Binary file not shown.
File diff suppressed because one or more lines are too long
Binary file not shown.
File diff suppressed because one or more lines are too long
Binary file not shown.
Binary file not shown.
File diff suppressed because one or more lines are too long
Binary file not shown.
File diff suppressed because one or more lines are too long
Binary file not shown.
File diff suppressed because one or more lines are too long
Binary file not shown.
File diff suppressed because one or more lines are too long
Binary file not shown.
Binary file not shown.
@@ -51,6 +51,16 @@ export async function onRequest(context) {
|
||||
settings.access = newSettings.access || settings.access
|
||||
settings.access.userSessionMaxAge = normalizeSessionMaxAgeDays(settings.access.userSessionMaxAge)
|
||||
settings.access.adminSessionMaxAge = normalizeSessionMaxAgeDays(settings.access.adminSessionMaxAge)
|
||||
settings.access.imageTransformEnabled = settings.access.imageTransformEnabled === true
|
||||
|
||||
const allowedSizes = normalizeImageTransformAllowedSizes(settings.access.imageTransformAllowedSizes)
|
||||
if (allowedSizes.error) {
|
||||
return new Response(JSON.stringify({ error: allowedSizes.error }), {
|
||||
status: 400,
|
||||
headers: { 'content-type': 'application/json' },
|
||||
})
|
||||
}
|
||||
settings.access.imageTransformAllowedSizes = allowedSizes.value
|
||||
|
||||
// 处理认证设置:空密码表示不修改,_clear 标记表示清除密码
|
||||
let userPasswordChanged = false;
|
||||
@@ -172,6 +182,8 @@ export async function getSecurityConfig(db, env) {
|
||||
const access = {
|
||||
allowedDomains: kvAccess.allowedDomains || env.ALLOWED_DOMAINS || '',
|
||||
whiteListMode: kvAccess.whiteListMode ?? env.WhiteList_Mode === 'true',
|
||||
imageTransformEnabled: kvAccess.imageTransformEnabled === true,
|
||||
imageTransformAllowedSizes: normalizeImageTransformAllowedSizes(kvAccess.imageTransformAllowedSizes).value,
|
||||
// 新增会话安全策略字段
|
||||
sessionSecure: kvAccess.sessionSecure ?? false,
|
||||
userSessionMaxAge: normalizeSessionMaxAgeDays(kvAccess.userSessionMaxAge ?? 14),
|
||||
@@ -189,6 +201,35 @@ export async function getSecurityConfig(db, env) {
|
||||
return settings;
|
||||
}
|
||||
|
||||
function normalizeImageTransformAllowedSizes(value) {
|
||||
if (value === undefined || value === null || String(value).trim() === '') {
|
||||
return { value: '' }
|
||||
}
|
||||
|
||||
const sizes = String(value)
|
||||
.split(',')
|
||||
.map(size => size.trim().toLowerCase())
|
||||
.filter(Boolean)
|
||||
const normalized = []
|
||||
|
||||
for (const size of sizes) {
|
||||
const match = size.match(/^(auto|[1-9]\d*)x(auto|[1-9]\d*)$/)
|
||||
if (!match || (match[1] === 'auto' && match[2] === 'auto')) {
|
||||
return { error: `Invalid image transform size: ${size}` }
|
||||
}
|
||||
|
||||
for (const dimension of match.slice(1)) {
|
||||
if (dimension !== 'auto' && Number(dimension) > 4096) {
|
||||
return { error: `Invalid image transform size: ${size}` }
|
||||
}
|
||||
}
|
||||
|
||||
if (!normalized.includes(size)) normalized.push(size)
|
||||
}
|
||||
|
||||
return { value: normalized.join(',') }
|
||||
}
|
||||
|
||||
function normalizeIpQueryParams(params) {
|
||||
if (!Array.isArray(params) || params.length === 0) {
|
||||
return [{ key: 'ip', value: '{ip}' }];
|
||||
|
||||
@@ -51,7 +51,7 @@ export async function onRequest(context) { // Contents of context object
|
||||
const url = new URL(request.url);
|
||||
context.url = url;
|
||||
|
||||
context.imageTransform = parseImageTransform(url, env);
|
||||
context.imageTransform = parseImageTransform(url, securityConfig.access);
|
||||
const imageTransformError = validateImageTransformRequest(request, context.imageTransform);
|
||||
if (imageTransformError) {
|
||||
return imageTransformError;
|
||||
|
||||
@@ -13,7 +13,7 @@ const OUTPUT_FORMATS = new Map([
|
||||
['image/svg+xml', 'image/png'],
|
||||
]);
|
||||
|
||||
export function parseImageTransform(url, env = {}) {
|
||||
export function parseImageTransform(url, accessConfig = {}) {
|
||||
const widthResult = parseDimension(url.searchParams, 'width');
|
||||
const heightResult = parseDimension(url.searchParams, 'height');
|
||||
const fitResult = parseFit(url.searchParams);
|
||||
@@ -30,6 +30,14 @@ export function parseImageTransform(url, env = {}) {
|
||||
return { requested: false };
|
||||
}
|
||||
|
||||
if (accessConfig.imageTransformEnabled !== true) {
|
||||
return {
|
||||
requested: true,
|
||||
error: 'Image resizing is disabled',
|
||||
errorStatus: 403,
|
||||
};
|
||||
}
|
||||
|
||||
const width = widthResult.value;
|
||||
const height = heightResult.value;
|
||||
const fit = fitResult.value;
|
||||
@@ -42,7 +50,7 @@ export function parseImageTransform(url, env = {}) {
|
||||
}
|
||||
|
||||
const sizeKey = `${width || 'auto'}x${height || 'auto'}`;
|
||||
const allowedSizes = parseAllowedSizes(env.IMAGE_TRANSFORM_ALLOWED_SIZES);
|
||||
const allowedSizes = parseAllowedSizes(accessConfig.imageTransformAllowedSizes);
|
||||
|
||||
if (allowedSizes.size > 0 && !allowedSizes.has(sizeKey)) {
|
||||
return {
|
||||
@@ -66,7 +74,7 @@ export function validateImageTransformRequest(request, imageTransform) {
|
||||
if (!imageTransform.requested) return null;
|
||||
|
||||
if (imageTransform.error) {
|
||||
return imageTransformError(imageTransform.error, 400);
|
||||
return imageTransformError(imageTransform.error, imageTransform.errorStatus || 400);
|
||||
}
|
||||
|
||||
if (request.method !== 'GET') {
|
||||
|
||||
@@ -112,7 +112,15 @@ export async function fetchSecurityConfig(env, options = {}) {
|
||||
customApi: { url: "", params: [{ key: "ip", value: "{ip}" }], responseFields: [] }
|
||||
}
|
||||
},
|
||||
access: { allowedDomains: "", whiteListMode: false, sessionSecure: false, userSessionMaxAge: 14, adminSessionMaxAge: 14 }
|
||||
access: {
|
||||
allowedDomains: "",
|
||||
whiteListMode: false,
|
||||
imageTransformEnabled: false,
|
||||
imageTransformAllowedSizes: "",
|
||||
sessionSecure: false,
|
||||
userSessionMaxAge: 14,
|
||||
adminSessionMaxAge: 14
|
||||
}
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user