refactor: Update paths and imports in controllers

This commit is contained in:
Peifan Li
2025-12-26 21:32:03 -05:00
parent 90b5eb92c5
commit 1d976591c6
4 changed files with 47 additions and 29 deletions

11
.codacy/codacy.yaml Normal file
View File

@@ -0,0 +1,11 @@
runtimes:
- java@17.0.10
- node@22.2.0
- python@3.11.11
tools:
- eslint@8.57.0
- lizard@1.17.31
- pmd@6.55.0
- pylint@3.3.9
- semgrep@1.78.0
- trivy@0.66.0

7
.codacyignore Normal file
View File

@@ -0,0 +1,7 @@
node_modules/
backend/bgutil-ytdlp-pot-provider/
dist/
build/
coverage/
.codacy/
.git/

View File

@@ -1,11 +1,12 @@
import bcrypt from "bcryptjs"; import bcrypt from "bcryptjs";
import crypto from "crypto";
import { Request, Response } from "express"; import { Request, Response } from "express";
import fs from "fs-extra"; import fs from "fs-extra";
import path from "path"; import path from "path";
import { import {
COLLECTIONS_DATA_PATH, COLLECTIONS_DATA_PATH,
STATUS_DATA_PATH, STATUS_DATA_PATH,
VIDEOS_DATA_PATH, VIDEOS_DATA_PATH,
} from "../config/paths"; } from "../config/paths";
import { NotFoundError, ValidationError } from "../errors/DownloadErrors"; import { NotFoundError, ValidationError } from "../errors/DownloadErrors";
import { cloudflaredService } from "../services/cloudflaredService"; import { cloudflaredService } from "../services/cloudflaredService";
@@ -323,23 +324,23 @@ export const updateSettings = async (
if (newSettings.cloudflaredTunnelEnabled) { if (newSettings.cloudflaredTunnelEnabled) {
// Determine port // Determine port
const port = process.env.PORT ? parseInt(process.env.PORT) : 5551; const port = process.env.PORT ? parseInt(process.env.PORT) : 5551;
const shouldRestart = existingSettings.cloudflaredTunnelEnabled; const shouldRestart = existingSettings.cloudflaredTunnelEnabled;
if (shouldRestart) { if (shouldRestart) {
// If it was already enabled, we need to restart to apply changes (Token -> No Token, or vice versa) // If it was already enabled, we need to restart to apply changes (Token -> No Token, or vice versa)
if (newSettings.cloudflaredToken) { if (newSettings.cloudflaredToken) {
cloudflaredService.restart(newSettings.cloudflaredToken); cloudflaredService.restart(newSettings.cloudflaredToken);
} else { } else {
cloudflaredService.restart(undefined, port); cloudflaredService.restart(undefined, port);
} }
} else { } else {
// It was disabled, now enabling -> just start // It was disabled, now enabling -> just start
if (newSettings.cloudflaredToken) { if (newSettings.cloudflaredToken) {
cloudflaredService.start(newSettings.cloudflaredToken); cloudflaredService.start(newSettings.cloudflaredToken);
} else { } else {
cloudflaredService.start(undefined, port); cloudflaredService.start(undefined, port);
} }
} }
} else { } else {
// If disabled, stop // If disabled, stop
@@ -517,13 +518,13 @@ export const resetPassword = async (
_req: Request, _req: Request,
res: Response res: Response
): Promise<void> => { ): Promise<void> => {
// Generate random 8-character password // Generate random 8-character password using cryptographically secure random
const chars = const chars =
"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789"; "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789";
let newPassword = ""; const randomBytes = crypto.randomBytes(8);
for (let i = 0; i < 8; i++) { const newPassword = Array.from(randomBytes, (byte) =>
newPassword += chars.charAt(Math.floor(Math.random() * chars.length)); chars.charAt(byte % chars.length)
} ).join("");
// Hash the new password // Hash the new password
const salt = await bcrypt.genSalt(10); const salt = await bcrypt.genSalt(10);
@@ -922,4 +923,3 @@ export const getCloudflaredStatus = async (
const status = cloudflaredService.getStatus(); const status = cloudflaredService.getStatus();
res.json(status); res.json(status);
}; };

View File

@@ -6,7 +6,7 @@ import { NotFoundError, ValidationError } from "../errors/DownloadErrors";
import * as storageService from "../services/storageService"; import * as storageService from "../services/storageService";
import { logger } from "../utils/logger"; import { logger } from "../utils/logger";
import { successResponse } from "../utils/response"; import { successResponse } from "../utils/response";
import { execFileSafe, validateVideoPath, validateImagePath } from "../utils/security"; import { execFileSafe, validateImagePath, validateVideoPath } from "../utils/security";
/** /**
* Rate video * Rate video
@@ -63,8 +63,11 @@ export const refreshThumbnail = async (
throw new ValidationError("Video file path not found in record", "video"); throw new ValidationError("Video file path not found in record", "video");
} }
if (!fs.existsSync(videoFilePath)) { // Validate paths to prevent path traversal
throw new NotFoundError("Video file", videoFilePath); const validatedVideoPath = validateVideoPath(videoFilePath);
if (!fs.existsSync(validatedVideoPath)) {
throw new NotFoundError("Video file", validatedVideoPath);
} }
// Determine thumbnail path on disk // Determine thumbnail path on disk
@@ -89,11 +92,8 @@ export const refreshThumbnail = async (
} }
// Ensure directory exists // Ensure directory exists
fs.ensureDirSync(path.dirname(thumbnailAbsolutePath));
// Validate paths to prevent path traversal
const validatedVideoPath = validateVideoPath(videoFilePath);
const validatedThumbnailPath = validateImagePath(thumbnailAbsolutePath); const validatedThumbnailPath = validateImagePath(thumbnailAbsolutePath);
fs.ensureDirSync(path.dirname(validatedThumbnailPath));
// Generate thumbnail using execFileSafe to prevent command injection // Generate thumbnail using execFileSafe to prevent command injection
try { try {