Browse Source

refactor(media): enhance directory handling for static assets

- Introduced new utility functions to ensure relative directory paths and prevent unsafe segments in environment variables for static and media directories.
- Updated the STATIC_DIR, MEDIA_UPLOAD_SUBDIR, and RELATIVE_TMP_DIR exports to utilize these new functions, improving error handling and validation.
- Adjusted POST_MEDIA_PUBLIC_PREFIX to align with the new static directory structure.

These changes improve the robustness of media and static asset management, ensuring safer and more consistent directory configurations.
main
npmrun 2 weeks ago
parent
commit
fa14e7c8bb
  1. 42
      server/constants/media.ts

42
server/constants/media.ts

@ -2,23 +2,57 @@ function trimSlashes(input: string): string {
return input.trim().replace(/^\/+|\/+$/g, ""); return input.trim().replace(/^\/+|\/+$/g, "");
} }
function hasParentSegment(input: string): boolean {
return input
.split("/")
.map((part) => part.trim())
.some((part) => part === "..");
}
function ensureRelativeDir(input: string, fallback: string, envName: string): string {
const value = input.trim();
if (!value) {
return fallback;
}
// 仅允许相对目录;绝对路径会绕过项目根约束。
if (value.startsWith("/")) {
throw new Error(`${envName} must be a relative directory path`);
}
return value;
}
function ensureSafeSubdir(input: string, fallback: string, envName: string): string {
const value = trimSlashes(input);
if (!value) {
return fallback;
}
if (hasParentSegment(value)) {
throw new Error(`${envName} must not contain ".." segments`);
}
return value;
}
/** 静态资源 URL 前缀固定为 `/static`,不允许通过环境变量覆写。 */ /** 静态资源 URL 前缀固定为 `/static`,不允许通过环境变量覆写。 */
export const STATIC_PUBLIC_PREFIX = "/static"; export const STATIC_PUBLIC_PREFIX = "/static";
/** 静态资源根目录,默认 `static` */ /** 静态资源根目录,默认 `static` */
export const STATIC_DIR = trimSlashes(process.env.STATIC_DIR ?? "static"); export const STATIC_DIR = ensureRelativeDir(process.env.STATIC_DIR ?? "static", "static", "STATIC_DIR");
/** 媒体上传子目录(相对 STATIC_DIR),默认 `media` */ /** 媒体上传子目录(相对 STATIC_DIR),默认 `media` */
export const MEDIA_UPLOAD_SUBDIR = trimSlashes(process.env.MEDIA_UPLOAD_SUBDIR ?? "media"); export const MEDIA_UPLOAD_SUBDIR = ensureSafeSubdir(
process.env.MEDIA_UPLOAD_SUBDIR ?? "media",
"media",
"MEDIA_UPLOAD_SUBDIR",
);
/** 媒体上传目录(相对项目根),默认 `static/media` */ /** 媒体上传目录(相对项目根),默认 `static/media` */
export const RELATIVE_ASSETS_DIR = `${STATIC_DIR}/${MEDIA_UPLOAD_SUBDIR}`; export const RELATIVE_ASSETS_DIR = `${STATIC_DIR}/${MEDIA_UPLOAD_SUBDIR}`;
/** 临时目录(相对项目根),默认 `.tmp` */ /** 临时目录(相对项目根),默认 `.tmp` */
export const RELATIVE_TMP_DIR = trimSlashes(process.env.TMP_DIR ?? ".tmp"); export const RELATIVE_TMP_DIR = ensureRelativeDir(process.env.TMP_DIR ?? ".tmp", ".tmp", "TMP_DIR");
/** 与 `media` 返回及静态路径一致,无前导 host */ /** 与 `media` 返回及静态路径一致,无前导 host */
export const POST_MEDIA_PUBLIC_PREFIX = `/${RELATIVE_ASSETS_DIR}/`; export const POST_MEDIA_PUBLIC_PREFIX = `${STATIC_PUBLIC_PREFIX}/${MEDIA_UPLOAD_SUBDIR}/`;
/** 从未引用:created_at 起算;曾引用:dereferenced_at 起算 */ /** 从未引用:created_at 起算;曾引用:dereferenced_at 起算 */
export const MEDIA_ORPHAN_GRACE_HOURS_NEVER_REF = 24; export const MEDIA_ORPHAN_GRACE_HOURS_NEVER_REF = 24;

Loading…
Cancel
Save