import {getClient} from "../utils/database.js"; import {body, param} from "express-validator"; import jwt from "jsonwebtoken"; export const Video = { id: param("id").notEmpty().isNumeric().trim(), title: body("title").notEmpty().trim(), description: body("description").optional({values: "falsy"}).trim(), channel: body("channel").notEmpty().isNumeric().trim(), visibility: body("visibility").notEmpty().isAlpha().trim(), idBody: body("video").notEmpty().isNumeric().trim(), tags: body("tags").optional({values: "falsy"}).isArray().custom((value) => { if (value.length > 10) { throw new Error("Too many tags, maximum is 10"); } return true; }), } export const VideoCreate = { title: body("title").notEmpty().trim(), description: body("description").optional({values: "falsy"}).trim(), channel: body("channel").notEmpty().isNumeric().trim(), visibility: body("visibility").notEmpty().isAlpha().trim(), authorizedUsers: body("authorizedUsers") .optional({values: "falsy"}) .customSanitizer((value) => { // Parse JSON string back to array if (typeof value === 'string') { try { return JSON.parse(value); } catch (error) { return []; } } return value; }) .isArray() .withMessage("Authorized users must be an array"), } export const VideoThumbnail = { video: body("video").notEmpty().isNumeric().trim(), } export async function isOwner(req, res, next) { const logger = req.body.logger; const channelId = req.body.channel; const token = req.headers.authorization.split(' ')[1]; const claims = jwt.decode(token); const client = await getClient(); try { const channelQuery = `SELECT owner FROM channels WHERE id = $1`; const channelResult = await client.query(channelQuery, [channelId]); const channelInBase = channelResult.rows[0]; if (channelInBase.owner !== claims.id) { logger.write("failed because user is not owner", 403); res.status(403).json({error: "Not authorized"}); return } next() } finally { client.release(); } } export async function doVideoExists(req, res, next) { const logger = req.body.logger; const videoId = req.body.video; const client = await getClient(); try { const query = `SELECT * FROM videos WHERE id = $1`; const result = await client.query(query, [videoId]); const videos = result.rows; if (videos.length === 0) { logger.write("failed because video not found", 404); res.status(404).json({error: "Not Found"}); return } next() } finally { client.release(); } } export async function doVideoExistsParam(req, res, next) { const logger = req.body.logger; const videoId = req.params.id; const client = await getClient(); try { const query = `SELECT * FROM videos WHERE id = $1`; const result = await client.query(query, [videoId]); const video = result.rows[0]; if (!video) { logger.write("failed because video not found", 404); res.status(404).json({error: "Not Found"}); return } next() } finally { client.release(); } } export async function doAuthorizedUserExists(req, res, next) { const logger = req.body.logger; let authorizedUsers = req.body.authorizedUsers; // Parse JSON string if needed if (typeof authorizedUsers === 'string') { try { authorizedUsers = JSON.parse(authorizedUsers); } catch (error) { logger.write("failed because authorizedUsers is not valid JSON", 400); res.status(400).json({error: "Invalid authorized users format"}); return; } } if (authorizedUsers && Array.isArray(authorizedUsers) && authorizedUsers.length > 0) { const client = await getClient(); try { for (const userId of authorizedUsers) { const query = `SELECT id FROM users WHERE id = $1`; const result = await client.query(query, [userId]); const foundUser = result.rows[0]; if (!foundUser) { logger.write("failed because authorized user not found", 404); res.status(404).json({error: "Not Found"}); return } } } finally { client.release(); } } next() } export async function hasAccess(req, res, next) { const logger = req.body.logger; const videoId = req.params.id; const client = await getClient(); try { const videoQuery = "SELECT visibility FROM videos WHERE id = $1"; const videoResult = await client.query(videoQuery, [videoId]); const video = videoResult.rows[0]; console.log(video); if (video.visibility === 'private') { const token = req.headers.authorization?.split(" ")[1]; if (!req.headers.authorization || !token) { logger.write("failed because no token provided", 401); res.status(401).json({error: "Unauthorized"}); return; } const claims = jwt.decode(token); const userId = claims.id; const query = `SELECT * FROM video_authorized_users WHERE video_id = $1 AND user_id = $2`; const result = await client.query(query, [videoId, userId]); const isAuthorized = result.rows.length > 0; if (!isAuthorized) { logger.write("failed because user is not authorized", 403); res.status(403).json({error: "Not authorized"}); return; } } next(); } finally { client.release(); } }