diff --git a/.eslintrc.js b/.eslintrc.js index c082e3d..2234574 100644 --- a/.eslintrc.js +++ b/.eslintrc.js @@ -16,17 +16,18 @@ module.exports = { plugins: ["@typescript-eslint"], rules: { // TODO: Remove warn rules when not needed anymore - "no-self-assign": "off", - "semi": "warn", "@typescript-eslint/no-empty-interface": "off", "@typescript-eslint/no-explicit-any": "off", + "indent": ["warn", 4, { "SwitchCase": 1 }], + "newline-before-return": "warn", + "no-multiple-empty-lines": ["error", { max: 2, maxEOF: 0 }], + "no-self-assign": "off", "no-trailing-spaces": "warn", + "object-curly-spacing": ["warn", "always"], "prefer-template": "warn", "quotes": ["warn", "double", { "avoidEscape": true, "allowTemplateLiterals": true }], - "no-multiple-empty-lines": ["error", { max: 2, maxEOF: 0 }], - "indent": ["warn", 4, { "SwitchCase": 1 }], - "object-curly-spacing": ["warn", "always"], "require-await": "warn", + "semi": "warn", "no-console": "warn" }, }; diff --git a/src/routes/addUnlistedVideo.ts b/src/routes/addUnlistedVideo.ts index 4c6cdba..d66e36c 100644 --- a/src/routes/addUnlistedVideo.ts +++ b/src/routes/addUnlistedVideo.ts @@ -10,24 +10,33 @@ import { Logger } from "../utils/logger"; * https://support.google.com/youtube/answer/9230970 */ -export function addUnlistedVideo(req: Request, res: Response): Response { - const videoID = req.body.videoID; - const year = req.body.year || 0; - const views = req.body.views || 0; - const channelID = req.body.channelID || "Unknown"; - const service = getService(req.body.service); +export async function addUnlistedVideo(req: Request, res: Response): Promise { + const { + body: { + videoID = null, + year = 0, + views = 0, + channelID = "Unknown", + service + } + } = req; - if (videoID === undefined || typeof(videoID) !== "string" || videoID.length !== 11) { + if (typeof(videoID) !== "string" || videoID.length !== 11) { return res.status(400).send("Invalid parameters"); } try { const timeSubmitted = Date.now(); - db.prepare("run", `INSERT INTO "unlistedVideos" ("videoID", "year", "views", "channelID", "timeSubmitted", "service") values (?, ?, ?, ?, ?, ?)`, [videoID, year, views, channelID, timeSubmitted, service]); + await db.prepare( + "run", + `INSERT INTO "unlistedVideos" ("videoID", "year", "views", "channelID", "timeSubmitted", "service") values (?, ?, ?, ?, ?, ?)`, + [videoID, year, views, channelID, timeSubmitted, getService(service)] + ); + + return res.sendStatus(200); } catch (err) { Logger.error(err as string); - return res.sendStatus(500); } - return res.sendStatus(200); -} \ No newline at end of file + return res.sendStatus(500); +} diff --git a/src/routes/addUserAsVIP.ts b/src/routes/addUserAsVIP.ts index dd2c244..3d94490 100644 --- a/src/routes/addUserAsVIP.ts +++ b/src/routes/addUserAsVIP.ts @@ -5,35 +5,41 @@ import { Request, Response } from "express"; import { isUserVIP } from "../utils/isUserVIP"; import { HashedUserID } from "../types/user.model"; +interface AddUserAsVIPRequest extends Request { + query: { + userID: HashedUserID; + adminUserID: string; + enabled: string; + } +} -export async function addUserAsVIP(req: Request, res: Response): Promise { - const userID = req.query.userID as HashedUserID; - let adminUserIDInput = req.query.adminUserID as string; +export async function addUserAsVIP(req: AddUserAsVIPRequest, res: Response): Promise { + const { query: { userID, adminUserID } } = req; - const enabled = req.query.enabled === undefined - ? false - : req.query.enabled === "true"; + const enabled = req.query?.enabled === "true"; - if (userID == undefined || adminUserIDInput == undefined) { - //invalid request + if (!userID || !adminUserID) { + // invalid request return res.sendStatus(400); } - //hash the userID - adminUserIDInput = getHash(adminUserIDInput); + // hash the userID + const adminUserIDInput = getHash(adminUserID); if (adminUserIDInput !== config.adminUserID) { - //not authorized + // not authorized return res.sendStatus(403); } - //check to see if this user is already a vip + // check to see if this user is already a vip const userIsVIP = await isUserVIP(userID); if (enabled && !userIsVIP) { - //add them to the vip list + // add them to the vip list await db.prepare("run", 'INSERT INTO "vipUsers" VALUES(?)', [userID]); - } else if (!enabled && userIsVIP) { + } + + if (!enabled && userIsVIP) { //remove them from the shadow ban list await db.prepare("run", 'DELETE FROM "vipUsers" WHERE "userID" = ?', [userID]); } diff --git a/src/routes/deleteLockCategories.ts b/src/routes/deleteLockCategories.ts index ec1b665..e98ed23 100644 --- a/src/routes/deleteLockCategories.ts +++ b/src/routes/deleteLockCategories.ts @@ -6,12 +6,25 @@ import { Category, Service, VideoID } from "../types/segments.model"; import { UserID } from "../types/user.model"; import { getService } from "../utils/getService"; -export async function deleteLockCategoriesEndpoint(req: Request, res: Response): Promise { +interface DeleteLockCategoriesRequest extends Request { + body: { + categories: Category[]; + service: string; + userID: UserID; + videoID: VideoID; + }; +} + +export async function deleteLockCategoriesEndpoint(req: DeleteLockCategoriesRequest, res: Response): Promise { // Collect user input data - const videoID = req.body.videoID as VideoID; - const userID = req.body.userID as UserID; - const categories = req.body.categories as Category[]; - const service = getService(req.body.service); + const { + body: { + videoID, + userID, + categories, + service + } + } = req; // Check input data is valid if (!videoID @@ -35,9 +48,9 @@ export async function deleteLockCategoriesEndpoint(req: Request, res: Response): }); } - await deleteLockCategories(videoID, categories, service); + await deleteLockCategories(videoID, categories, getService(service)); - return res.status(200).json({ message: `Removed lock categories entrys for video ${videoID}` }); + return res.status(200).json({ message: `Removed lock categories entries for video ${videoID}` }); } /** @@ -47,17 +60,21 @@ export async function deleteLockCategoriesEndpoint(req: Request, res: Response): * @param service */ export async function deleteLockCategories(videoID: VideoID, categories: Category[], service: Service): Promise { - const entries = ( - await db.prepare("all", 'SELECT * FROM "lockCategories" WHERE "videoID" = ? AND "service" = ?', [videoID, service])) - .filter((entry: any) => { - return categories === null || categories.indexOf(entry.category) !== -1; - }); + type DBEntry = { category: Category }; + const dbEntries = await db.prepare( + "all", + 'SELECT * FROM "lockCategories" WHERE "videoID" = ? AND "service" = ?', + [videoID, service] + ) as Array; - for (const entry of entries) { - await db.prepare( + const entries = dbEntries.filter( + ({ category }: DBEntry) => categories === null || categories.indexOf(category) !== -1); + + await Promise.all( + entries.map(({ category }: DBEntry) => db.prepare( "run", 'DELETE FROM "lockCategories" WHERE "videoID" = ? AND "service" = ? AND "category" = ?', - [videoID, service, entry.category] - ); - } + [videoID, service, category] + )) + ); } diff --git a/src/utils/getService.ts b/src/utils/getService.ts index 980f240..9a9e7f6 100644 --- a/src/utils/getService.ts +++ b/src/utils/getService.ts @@ -1,14 +1,15 @@ import { Service } from "../types/segments.model"; export function getService(...value: T[]): Service { + const serviceByName = Object.values(Service).reduce((acc, serviceName) => { + acc[serviceName.toLowerCase()] = serviceName; + + return acc; + }, {} as Record); + for (const name of value) { - if (name) { - const service = Object.values(Service).find( - (val) => val.toLowerCase() === name.trim().toLowerCase() - ); - if (service) { - return service; - } + if (name?.trim().toLowerCase() in serviceByName) { + return serviceByName[name.trim().toLowerCase()]; } }