Merge pull request #294 from mchangrh/fix-eslint

fix eslint-errors
This commit is contained in:
Ajay Ramachandran 2021-07-04 18:21:00 -04:00 committed by GitHub
commit 43ae471038
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
71 changed files with 459 additions and 550 deletions

View file

@ -17,6 +17,8 @@ module.exports = {
rules: { rules: {
// TODO: Remove warn rules when not needed anymore // TODO: Remove warn rules when not needed anymore
"no-self-assign": "off", "no-self-assign": "off",
"semi": "warn",
"@typescript-eslint/no-empty-interface": "off", "@typescript-eslint/no-empty-interface": "off",
"@typescript-eslint/no-explicit-any": "off"
}, },
}; };

View file

@ -34,13 +34,14 @@ import { addUnlistedVideo } from './routes/addUnlistedVideo';
import {postPurgeAllSegments} from './routes/postPurgeAllSegments'; import {postPurgeAllSegments} from './routes/postPurgeAllSegments';
import {getUserID} from './routes/getUserID'; import {getUserID} from './routes/getUserID';
import ExpressPromiseRouter from 'express-promise-router'; import ExpressPromiseRouter from 'express-promise-router';
import { Server } from 'http';
export function createServer(callback: () => void) { export function createServer(callback: () => void): Server {
// Create a service (the app object is just a callback). // Create a service (the app object is just a callback).
const app = express(); const app = express();
const router = ExpressPromiseRouter() const router = ExpressPromiseRouter();
app.use(router) app.use(router);
//setup CORS correctly //setup CORS correctly
router.use(corsMiddleware); router.use(corsMiddleware);
@ -158,7 +159,7 @@ function setupRoutes(router: Router) {
if (config.postgres) { if (config.postgres) {
router.get('/database', (req, res) => dumpDatabase(req, res, true)); router.get('/database', (req, res) => dumpDatabase(req, res, true));
router.get('/database.json', (req, res) => dumpDatabase(req, res, false)); router.get('/database.json', (req, res) => dumpDatabase(req, res, false));
router.get('/database/*', redirectLink) router.get('/database/*', redirectLink);
} else { } else {
router.get('/database.db', function (req: Request, res: Response) { router.get('/database.db', function (req: Request, res: Response) {
res.sendFile("./databases/sponsorTimes.db", {root: "./"}); res.sendFile("./databases/sponsorTimes.db", {root: "./"});

View file

@ -1,6 +1,6 @@
import fs from 'fs'; import fs from 'fs';
import {SBSConfig} from "./types/config.model"; import {SBSConfig} from "./types/config.model";
import packageJson from "../package.json" import packageJson from "../package.json";
const isTestMode = process.env.npm_lifecycle_script === packageJson.scripts.test; const isTestMode = process.env.npm_lifecycle_script === packageJson.scripts.test;
const configFile = process.env.TEST_POSTGRES ? 'ci.json' const configFile = process.env.TEST_POSTGRES ? 'ci.json'
@ -83,7 +83,7 @@ addDefaults(config, {
// Add defaults // Add defaults
function addDefaults(config: SBSConfig, defaults: SBSConfig) { function addDefaults(config: SBSConfig, defaults: SBSConfig) {
for (const key in defaults) { for (const key in defaults) {
if (!config.hasOwnProperty(key)) { if (!Object.prototype.hasOwnProperty.call(config, key)) {
// @ts-ignore // @ts-ignore
config[key] = defaults[key]; config[key] = defaults[key];
} }

View file

@ -1,19 +1,20 @@
import {Logger} from '../utils/logger'; import {Logger} from '../utils/logger';
import {IDatabase, QueryType} from './IDatabase'; import {IDatabase, QueryType} from './IDatabase';
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
// @ts-ignore // @ts-ignore
import MysqlInterface from 'sync-mysql'; import MysqlInterface from 'sync-mysql';
export class Mysql implements IDatabase { export class Mysql implements IDatabase {
private connection: any; private connection: any;
constructor(private config: any) { constructor(private config: unknown) {
} }
async init(): Promise<void> { async init(): Promise<void> {
this.connection = new MysqlInterface(this.config); this.connection = new MysqlInterface(this.config);
} }
prepare(type: QueryType, query: string, params?: any[]) { prepare(type: QueryType, query: string, params?: any[]): Promise<any[]> {
Logger.debug(`prepare (mysql): type: ${type}, query: ${query}, params: ${params}`); Logger.debug(`prepare (mysql): type: ${type}, query: ${query}, params: ${params}`);
const queryResult = this.connection.query(query, params); const queryResult = this.connection.query(query, params);

View file

@ -17,7 +17,7 @@ types.setTypeParser(20, function(val) {
export class Postgres implements IDatabase { export class Postgres implements IDatabase {
private pool: Pool; private pool: Pool;
constructor(private config: any) {} constructor(private config: Record<string, any>) {}
async init(): Promise<void> { async init(): Promise<void> {
this.pool = new Pool(this.config.postgres); this.pool = new Pool(this.config.postgres);
@ -43,7 +43,7 @@ export class Postgres implements IDatabase {
} }
} }
async prepare(type: QueryType, query: string, params?: any[]) { async prepare(type: QueryType, query: string, params?: any[]): Promise<any[]> {
// Convert query to use numbered parameters // Convert query to use numbered parameters
let count = 1; let count = 1;
for (let char = 0; char < query.length; char++) { for (let char = 0; char < query.length; char++) {
@ -64,7 +64,7 @@ export class Postgres implements IDatabase {
return value; return value;
} }
case 'all': { case 'all': {
let values = queryResult.rows; const values = queryResult.rows;
Logger.debug(`result (postgres): ${values}`); Logger.debug(`result (postgres): ${values}`);
return values; return values;
} }

View file

@ -12,7 +12,7 @@ export class Sqlite implements IDatabase {
{ {
} }
async prepare(type: QueryType, query: string, params: any[] = []) { async prepare(type: QueryType, query: string, params: any[] = []): Promise<any[]> {
// Logger.debug(`prepare (sqlite): type: ${type}, query: ${query}, params: ${params}`); // Logger.debug(`prepare (sqlite): type: ${type}, query: ${query}, params: ${params}`);
const preparedQuery = this.db.prepare(query); const preparedQuery = this.db.prepare(query);
@ -30,7 +30,7 @@ export class Sqlite implements IDatabase {
} }
} }
async init() { async init(): Promise<void> {
// Make dirs if required // Make dirs if required
if (!fs.existsSync(path.join(this.config.dbPath, "../"))) { if (!fs.existsSync(path.join(this.config.dbPath, "../"))) {
fs.mkdirSync(path.join(this.config.dbPath, "../")); fs.mkdirSync(path.join(this.config.dbPath, "../"));
@ -61,7 +61,7 @@ export class Sqlite implements IDatabase {
this.db.exec("pragma mmap_size= 500000000;"); this.db.exec("pragma mmap_size= 500000000;");
} }
attachDatabase(database: string, attachAs: string) { attachDatabase(database: string, attachAs: string): void {
this.db.prepare(`ATTACH ? as ${attachAs}`).run(database); this.db.prepare(`ATTACH ? as ${attachAs}`).run(database);
} }
@ -83,7 +83,7 @@ export class Sqlite implements IDatabase {
} }
private static processUpgradeQuery(query: string): string { private static processUpgradeQuery(query: string): string {
let result = query.replace(/^.*--!sqlite-ignore/gm, ""); const result = query.replace(/^.*--!sqlite-ignore/gm, "");
return result; return result;
} }

View file

@ -60,7 +60,7 @@ if (config.mysql) {
enableWalCheckpointNumber: false enableWalCheckpointNumber: false
}); });
} }
async function initDb() { async function initDb(): Promise<void> {
await db.init(); await db.init();
await privateDB.init(); await privateDB.init();
@ -74,4 +74,4 @@ export {
db, db,
privateDB, privateDB,
initDb, initDb,
} };

View file

@ -1,6 +1,6 @@
import {NextFunction, Request, Response} from 'express'; import {NextFunction, Request, Response} from 'express';
export function apiCspMiddleware(req: Request, res: Response, next: NextFunction) { export function apiCspMiddleware(req: Request, res: Response, next: NextFunction): void {
res.header("Content-Security-Policy", "script-src 'none'; object-src 'none'"); res.header("Content-Security-Policy", "script-src 'none'; object-src 'none'");
next(); next();
} }

View file

@ -1,8 +1,8 @@
import {NextFunction, Request, Response} from 'express'; import {NextFunction, Request, Response} from 'express';
export function corsMiddleware(req: Request, res: Response, next: NextFunction) { export function corsMiddleware(req: Request, res: Response, next: NextFunction): void {
res.header("Access-Control-Allow-Origin", "*"); res.header("Access-Control-Allow-Origin", "*");
res.header("Access-Control-Allow-Headers", "X-Requested-With, Content-Type, Accept"); res.header("Access-Control-Allow-Headers", "X-Requested-With, Content-Type, Accept");
res.header("Access-Control-Allow-Methods", "GET, POST, OPTIONS, DELETE") res.header("Access-Control-Allow-Methods", "GET, POST, OPTIONS, DELETE");
next(); next();
} }

View file

@ -1,7 +1,7 @@
import {Logger} from '../utils/logger'; import {Logger} from '../utils/logger';
import {NextFunction, Request, Response} from 'express'; import {NextFunction, Request, Response} from 'express';
export function loggerMiddleware(req: Request, res: Response, next: NextFunction) { export function loggerMiddleware(req: Request, res: Response, next: NextFunction): void {
Logger.info(`Request received: ${req.method} ${req.url}`); Logger.info(`Request received: ${req.method} ${req.url}`);
next(); next();
} }

View file

@ -5,7 +5,7 @@ import {getIP} from '../utils/getIP';
import {getHash} from '../utils/getHash'; import {getHash} from '../utils/getHash';
import {NextFunction, Request, Response} from 'express'; import {NextFunction, Request, Response} from 'express';
export function userCounter(req: Request, res: Response, next: NextFunction) { export function userCounter(req: Request, res: Response, next: NextFunction): void {
fetch(config.userCounterURL + "/api/v1/addIP?hashedIP=" + getHash(getIP(req), 1), {method: "POST"}) fetch(config.userCounterURL + "/api/v1/addIP?hashedIP=" + getHash(getIP(req), 1), {method: "POST"})
.catch(() => Logger.debug("Failing to connect to user counter at: " + config.userCounterURL)); .catch(() => Logger.debug("Failing to connect to user counter at: " + config.userCounterURL));

View file

@ -1,4 +1,3 @@
import { time } from 'console';
import {Request, Response} from 'express'; import {Request, Response} from 'express';
import { db } from '../databases/databases'; import { db } from '../databases/databases';
import { Logger } from '../utils/logger'; import { Logger } from '../utils/logger';
@ -10,15 +9,14 @@ import { Logger } from '../utils/logger';
* https://support.google.com/youtube/answer/9230970 * https://support.google.com/youtube/answer/9230970
*/ */
export function addUnlistedVideo(req: Request, res: Response) { export function addUnlistedVideo(req: Request, res: Response): Response {
const videoID = req.body.videoID; const videoID = req.body.videoID;
const year = req.body.year || 0; const year = req.body.year || 0;
const views = req.body.views || 0; const views = req.body.views || 0;
const channelID = req.body.channelID || "Unknown"; const channelID = req.body.channelID || "Unknown";
if (videoID === undefined || typeof(videoID) !== "string" || videoID.length !== 11) { if (videoID === undefined || typeof(videoID) !== "string" || videoID.length !== 11) {
res.status(400).send("Invalid parameters"); return res.status(400).send("Invalid parameters");
return;
} }
try { try {
@ -26,10 +24,8 @@ export function addUnlistedVideo(req: Request, res: Response) {
db.prepare('run', `INSERT INTO "unlistedVideos" ("videoID", "year", "views", "channelID", "timeSubmitted") values (?, ?, ?, ?, ?)`, [videoID, year, views, channelID, timeSubmitted]); db.prepare('run', `INSERT INTO "unlistedVideos" ("videoID", "year", "views", "channelID", "timeSubmitted") values (?, ?, ?, ?, ?)`, [videoID, year, views, channelID, timeSubmitted]);
} catch (err) { } catch (err) {
Logger.error(err); Logger.error(err);
res.sendStatus(500); return res.sendStatus(500);
return;
} }
res.sendStatus(200); return res.sendStatus(200);
} }

View file

@ -3,7 +3,7 @@ import {db} from '../databases/databases';
import {config} from '../config'; import {config} from '../config';
import {Request, Response} from 'express'; import {Request, Response} from 'express';
export async function addUserAsVIP(req: Request, res: Response) { export async function addUserAsVIP(req: Request, res: Response): Promise<Response> {
const userID = req.query.userID as string; const userID = req.query.userID as string;
let adminUserIDInput = req.query.adminUserID as string; let adminUserIDInput = req.query.adminUserID as string;
@ -13,8 +13,7 @@ export async function addUserAsVIP(req: Request, res: Response) {
if (userID == undefined || adminUserIDInput == undefined) { if (userID == undefined || adminUserIDInput == undefined) {
//invalid request //invalid request
res.sendStatus(400); return res.sendStatus(400);
return;
} }
//hash the userID //hash the userID
@ -22,8 +21,7 @@ export async function addUserAsVIP(req: Request, res: Response) {
if (adminUserIDInput !== config.adminUserID) { if (adminUserIDInput !== config.adminUserID) {
//not authorized //not authorized
res.sendStatus(403); return res.sendStatus(403);
return;
} }
//check to see if this user is already a vip //check to see if this user is already a vip
@ -37,5 +35,5 @@ export async function addUserAsVIP(req: Request, res: Response) {
await db.prepare('run', 'DELETE FROM "vipUsers" WHERE "userID" = ?', [userID]); await db.prepare('run', 'DELETE FROM "vipUsers" WHERE "userID" = ?', [userID]);
} }
res.sendStatus(200); return res.sendStatus(200);
} }

View file

@ -5,7 +5,7 @@ import {db} from '../databases/databases';
import { Category, VideoID } from '../types/segments.model'; import { Category, VideoID } from '../types/segments.model';
import { UserID } from '../types/user.model'; import { UserID } from '../types/user.model';
export async function deleteLockCategoriesEndpoint(req: Request, res: Response) { export async function deleteLockCategoriesEndpoint(req: Request, res: Response): Promise<Response> {
// Collect user input data // Collect user input data
const videoID = req.body.videoID as VideoID; const videoID = req.body.videoID as VideoID;
const userID = req.body.userID as UserID; const userID = req.body.userID as UserID;
@ -18,10 +18,9 @@ export async function deleteLockCategoriesEndpoint(req: Request, res: Response)
|| !Array.isArray(categories) || !Array.isArray(categories)
|| categories.length === 0 || categories.length === 0
) { ) {
res.status(400).json({ return res.status(400).json({
message: 'Bad Format', message: 'Bad Format',
}); });
return;
} }
// Check if user is VIP // Check if user is VIP
@ -29,15 +28,14 @@ export async function deleteLockCategoriesEndpoint(req: Request, res: Response)
const userIsVIP = await isUserVIP(hashedUserID); const userIsVIP = await isUserVIP(hashedUserID);
if (!userIsVIP) { if (!userIsVIP) {
res.status(403).json({ return res.status(403).json({
message: 'Must be a VIP to mark videos.', message: 'Must be a VIP to mark videos.',
}); });
return;
} }
await deleteLockCategories(videoID, categories); await deleteLockCategories(videoID, categories);
res.status(200).json({message: 'Removed lock categories entrys for video ' + videoID}); return res.status(200).json({message: 'Removed lock categories entrys for video ' + videoID});
} }
/** /**

View file

@ -23,7 +23,7 @@ const styleHeader = `<style>
table tbody tr:nth-child(odd) { table tbody tr:nth-child(odd) {
background: #efefef; background: #efefef;
} }
</style>` </style>`;
const licenseHeader = `<p>The API and database follow <a href="https://creativecommons.org/licenses/by-nc-sa/4.0/" rel="nofollow">CC BY-NC-SA 4.0</a> unless you have explicit permission.</p> const licenseHeader = `<p>The API and database follow <a href="https://creativecommons.org/licenses/by-nc-sa/4.0/" rel="nofollow">CC BY-NC-SA 4.0</a> unless you have explicit permission.</p>
<p><a href="https://gist.github.com/ajayyy/4b27dfc66e33941a45aeaadccb51de71">Attribution Template</a></p> <p><a href="https://gist.github.com/ajayyy/4b27dfc66e33941a45aeaadccb51de71">Attribution Template</a></p>
@ -38,13 +38,13 @@ const tableNames = tables.map(table => table.name);
interface TableDumpList { interface TableDumpList {
fileName: string; fileName: string;
tableName: string; tableName: string;
}; }
let latestDumpFiles: TableDumpList[] = []; let latestDumpFiles: TableDumpList[] = [];
interface TableFile { interface TableFile {
file: string, file: string,
timestamp: number timestamp: number
}; }
if (tables.length === 0) { if (tables.length === 0) {
Logger.warn('[dumpDatabase] No tables configured'); Logger.warn('[dumpDatabase] No tables configured');
@ -55,7 +55,7 @@ let updateQueued = false;
let updateRunning = false; let updateRunning = false;
function removeOutdatedDumps(exportPath: string): Promise<void> { function removeOutdatedDumps(exportPath: string): Promise<void> {
return new Promise((resolve, reject) => { return new Promise((resolve) => {
// Get list of table names // Get list of table names
// Create array for each table // Create array for each table
const tableFiles: Record<string, TableFile[]> = tableNames.reduce((obj: any, tableName) => { const tableFiles: Record<string, TableFile[]> = tableNames.reduce((obj: any, tableName) => {
@ -81,7 +81,7 @@ function removeOutdatedDumps(exportPath: string): Promise<void> {
}); });
}); });
for (let tableName in tableFiles) { for (const tableName in tableFiles) {
const files = tableFiles[tableName].sort((a, b) => b.timestamp - a.timestamp); const files = tableFiles[tableName].sort((a, b) => b.timestamp - a.timestamp);
for (let i = 2; i < files.length; i++) { for (let i = 2; i < files.length; i++) {
// remove old file // remove old file
@ -90,13 +90,12 @@ function removeOutdatedDumps(exportPath: string): Promise<void> {
}); });
} }
} }
resolve(); resolve();
}); });
}); });
} }
export default async function dumpDatabase(req: Request, res: Response, showPage: boolean) { export default async function dumpDatabase(req: Request, res: Response, showPage: boolean): Promise<void> {
if (!config?.dumpDatabase?.enabled) { if (!config?.dumpDatabase?.enabled) {
res.status(404).send("Database dump is disabled"); res.status(404).send("Database dump is disabled");
return; return;
@ -108,7 +107,7 @@ export default async function dumpDatabase(req: Request, res: Response, showPage
updateQueueTime(); updateQueueTime();
res.status(200) res.status(200);
if (showPage) { if (showPage) {
res.send(`${styleHeader} res.send(`${styleHeader}
@ -153,7 +152,7 @@ export default async function dumpDatabase(req: Request, res: Response, showPage
size: item.fileSize, size: item.fileSize,
}; };
}), }),
}) });
} }
await queueDump(); await queueDump();
@ -182,7 +181,7 @@ export async function redirectLink(req: Request, res: Response): Promise<void> {
if (file) { if (file) {
res.redirect("/download/" + file.fileName); res.redirect("/download/" + file.fileName);
} else { } else {
res.status(404).send(); res.sendStatus(404);
} }
await queueDump(); await queueDump();

View file

@ -1,12 +1,12 @@
import {db} from '../databases/databases'; import {db} from '../databases/databases';
import {Request, Response} from 'express'; import {Request, Response} from 'express';
export async function getDaysSavedFormatted(req: Request, res: Response) { export async function getDaysSavedFormatted(req: Request, res: Response): Promise<Response> {
let row = await db.prepare('get', 'SELECT SUM(("endTime" - "startTime") / 60 / 60 / 24 * "views") as "daysSaved" from "sponsorTimes" where "shadowHidden" != 1', []); const row = await db.prepare('get', 'SELECT SUM(("endTime" - "startTime") / 60 / 60 / 24 * "views") as "daysSaved" from "sponsorTimes" where "shadowHidden" != 1', []);
if (row !== undefined) { if (row !== undefined) {
//send this result //send this result
res.send({ return res.send({
daysSaved: row.daysSaved.toFixed(2), daysSaved: row.daysSaved.toFixed(2),
}); });
} }

View file

@ -4,28 +4,25 @@ import {isUserVIP} from '../utils/isUserVIP';
import {Request, Response} from 'express'; import {Request, Response} from 'express';
import { HashedUserID, UserID } from '../types/user.model'; import { HashedUserID, UserID } from '../types/user.model';
export async function getIsUserVIP(req: Request, res: Response): Promise<void> { export async function getIsUserVIP(req: Request, res: Response): Promise<Response> {
const userID = req.query.userID as UserID; const userID = req.query.userID as UserID;
if (userID == undefined) { if (userID == undefined) {
//invalid request //invalid request
res.sendStatus(400); return res.sendStatus(400);
return;
} }
//hash the userID //hash the userID
const hashedUserID: HashedUserID = getHash(userID); const hashedUserID: HashedUserID = getHash(userID);
try { try {
let vipState = await isUserVIP(hashedUserID); const vipState = await isUserVIP(hashedUserID);
res.status(200).json({ return res.status(200).json({
hashedUserID: hashedUserID, hashedUserID: hashedUserID,
vip: vipState, vip: vipState,
}); });
} catch (err) { } catch (err) {
Logger.error(err); Logger.error(err);
res.sendStatus(500); return res.sendStatus(500);
return;
} }
} }

View file

@ -6,32 +6,29 @@ import { Logger } from '../utils/logger';
const maxRewardTimePerSegmentInSeconds = config.maxRewardTimePerSegmentInSeconds ?? 86400; const maxRewardTimePerSegmentInSeconds = config.maxRewardTimePerSegmentInSeconds ?? 86400;
export async function getSavedTimeForUser(req: Request, res: Response) { export async function getSavedTimeForUser(req: Request, res: Response): Promise<Response> {
let userID = req.query.userID as string; let userID = req.query.userID as string;
if (userID == undefined) { if (userID == undefined) {
//invalid request //invalid request
res.sendStatus(400); return res.sendStatus(400);
return;
} }
//hash the userID //hash the userID
userID = getHash(userID); userID = getHash(userID);
try { try {
let row = await db.prepare("get", 'SELECT SUM(((CASE WHEN "endTime" - "startTime" > ? THEN ? ELSE "endTime" - "startTime" END) / 60) * "views") as "minutesSaved" FROM "sponsorTimes" WHERE "userID" = ? AND "votes" > -1 AND "shadowHidden" != 1 ', [maxRewardTimePerSegmentInSeconds, maxRewardTimePerSegmentInSeconds, userID]); const row = await db.prepare("get", 'SELECT SUM(((CASE WHEN "endTime" - "startTime" > ? THEN ? ELSE "endTime" - "startTime" END) / 60) * "views") as "minutesSaved" FROM "sponsorTimes" WHERE "userID" = ? AND "votes" > -1 AND "shadowHidden" != 1 ', [maxRewardTimePerSegmentInSeconds, maxRewardTimePerSegmentInSeconds, userID]);
if (row.minutesSaved != null) { if (row.minutesSaved != null) {
res.send({ return res.send({
timeSaved: row.minutesSaved, timeSaved: row.minutesSaved,
}); });
} else { } else {
res.sendStatus(404); return res.sendStatus(404);
} }
} catch (err) { } catch (err) {
Logger.error("getSavedTimeForUser " + err); Logger.error("getSavedTimeForUser " + err);
res.sendStatus(500); return res.sendStatus(500);
return;
} }
} }

View file

@ -2,7 +2,7 @@ import { Request, Response } from 'express';
import { db } from '../databases/databases'; import { db } from '../databases/databases';
import { DBSegment, SegmentUUID } from "../types/segments.model"; import { DBSegment, SegmentUUID } from "../types/segments.model";
const isValidSegmentUUID = (str: string): Boolean => /^([a-f0-9]{64}|[a-f0-9]{8}\-[a-f0-9]{4}\-[a-f0-9]{4}\-[a-f0-9]{4}\-[a-f0-9]{12})/.test(str) const isValidSegmentUUID = (str: string): boolean => /^([a-f0-9]{64}|[a-f0-9]{8}-[a-f0-9]{4}-[a-f0-9]{4}-[a-f0-9]{4}-[a-f0-9]{12})/.test(str);
async function getSegmentFromDBByUUID(UUID: SegmentUUID): Promise<DBSegment> { async function getSegmentFromDBByUUID(UUID: SegmentUUID): Promise<DBSegment> {
try { try {
@ -18,7 +18,7 @@ async function getSegmentFromDBByUUID(UUID: SegmentUUID): Promise<DBSegment> {
async function getSegmentsByUUID(UUIDs: SegmentUUID[]): Promise<DBSegment[]> { async function getSegmentsByUUID(UUIDs: SegmentUUID[]): Promise<DBSegment[]> {
const DBSegments: DBSegment[] = []; const DBSegments: DBSegment[] = [];
for (let UUID of UUIDs) { for (const UUID of UUIDs) {
// if UUID is invalid, skip // if UUID is invalid, skip
if (!isValidSegmentUUID(UUID)) continue; if (!isValidSegmentUUID(UUID)) continue;
DBSegments.push(await getSegmentFromDBByUUID(UUID as SegmentUUID)); DBSegments.push(await getSegmentFromDBByUUID(UUID as SegmentUUID));
@ -26,7 +26,7 @@ async function getSegmentsByUUID(UUIDs: SegmentUUID[]): Promise<DBSegment[]> {
return DBSegments; return DBSegments;
} }
async function handleGetSegmentInfo(req: Request, res: Response) { async function handleGetSegmentInfo(req: Request, res: Response): Promise<DBSegment[]> {
// If using params instead of JSON, only one UUID can be pulled // If using params instead of JSON, only one UUID can be pulled
let UUIDs = req.query.UUIDs let UUIDs = req.query.UUIDs
? JSON.parse(req.query.UUIDs as string) ? JSON.parse(req.query.UUIDs as string)
@ -41,35 +41,35 @@ async function handleGetSegmentInfo(req: Request, res: Response) {
if (UUIDs.length > 10) UUIDs = UUIDs.slice(0, 10); if (UUIDs.length > 10) UUIDs = UUIDs.slice(0, 10);
if (!Array.isArray(UUIDs) || !UUIDs) { if (!Array.isArray(UUIDs) || !UUIDs) {
res.status(400).send("UUIDs parameter does not match format requirements."); res.status(400).send("UUIDs parameter does not match format requirements.");
return false; return;
} }
const DBSegments = await getSegmentsByUUID(UUIDs); const DBSegments = await getSegmentsByUUID(UUIDs);
// all uuids failed lookup // all uuids failed lookup
if (!DBSegments?.length) { if (!DBSegments?.length) {
res.sendStatus(400); res.sendStatus(400);
return false; return;
} }
// uuids valid but not found // uuids valid but not found
if (DBSegments[0] === null || DBSegments[0] === undefined) { if (DBSegments[0] === null || DBSegments[0] === undefined) {
res.sendStatus(400); res.sendStatus(400);
return false; return;
} }
return DBSegments; return DBSegments;
} }
async function endpoint(req: Request, res: Response): Promise<void> { async function endpoint(req: Request, res: Response): Promise<Response> {
try { try {
const DBSegments = await handleGetSegmentInfo(req, res); const DBSegments = await handleGetSegmentInfo(req, res);
// If false, res.send has already been called // If false, res.send has already been called
if (DBSegments) { if (DBSegments) {
//send result //send result
res.send(DBSegments); return res.send(DBSegments);
} }
} catch (err) { } catch (err) {
if (err instanceof SyntaxError) { // catch JSON.parse error if (err instanceof SyntaxError) { // catch JSON.parse error
res.status(400).send("UUIDs parameter does not match format requirements."); return res.status(400).send("UUIDs parameter does not match format requirements.");
} else res.status(500).send(); } else return res.sendStatus(500);
} }
} }

View file

@ -8,7 +8,7 @@ import { getCategoryActionType } from '../utils/categoryInfo';
import { getHash } from '../utils/getHash'; import { getHash } from '../utils/getHash';
import { getIP } from '../utils/getIP'; import { getIP } from '../utils/getIP';
import { Logger } from '../utils/logger'; import { Logger } from '../utils/logger';
import { QueryCacher } from '../utils/queryCacher' import { QueryCacher } from '../utils/queryCacher';
import { getReputation } from '../utils/reputation'; import { getReputation } from '../utils/reputation';
@ -41,7 +41,7 @@ async function prepareCategorySegments(req: Request, videoID: VideoID, category:
const filteredSegments = segments.filter((_, index) => shouldFilter[index]); const filteredSegments = segments.filter((_, index) => shouldFilter[index]);
const maxSegments = getCategoryActionType(category) === CategoryActionType.Skippable ? 32 : 1 const maxSegments = getCategoryActionType(category) === CategoryActionType.Skippable ? 32 : 1;
return (await chooseSegments(filteredSegments, maxSegments)).map((chosenSegment) => ({ return (await chooseSegments(filteredSegments, maxSegments)).map((chosenSegment) => ({
category, category,
segment: [chosenSegment.startTime, chosenSegment.endTime], segment: [chosenSegment.startTime, chosenSegment.endTime],
@ -138,7 +138,7 @@ async function getSegmentsFromDBByHash(hashedVideoIDPrefix: VideoIDHash, service
) as Promise<DBSegment[]>; ) as Promise<DBSegment[]>;
if (hashedVideoIDPrefix.length === 4) { if (hashedVideoIDPrefix.length === 4) {
return await QueryCacher.get(fetchFromDB, skipSegmentsHashKey(hashedVideoIDPrefix, service)) return await QueryCacher.get(fetchFromDB, skipSegmentsHashKey(hashedVideoIDPrefix, service));
} }
return await fetchFromDB(); return await fetchFromDB();
@ -153,7 +153,7 @@ async function getSegmentsFromDBByVideoID(videoID: VideoID, service: Service): P
[videoID, service] [videoID, service]
) as Promise<DBSegment[]>; ) as Promise<DBSegment[]>;
return await QueryCacher.get(fetchFromDB, skipSegmentsKey(videoID, service)) return await QueryCacher.get(fetchFromDB, skipSegmentsKey(videoID, service));
} }
//gets a weighted random choice from the choices array based on their `votes` property. //gets a weighted random choice from the choices array based on their `votes` property.
@ -171,7 +171,7 @@ function getWeightedRandomChoice<T extends VotableObject>(choices: T[], amountOf
//assign a weight to each choice //assign a weight to each choice
let totalWeight = 0; let totalWeight = 0;
let choicesWithWeights: TWithWeight[] = choices.map(choice => { const choicesWithWeights: TWithWeight[] = choices.map(choice => {
const boost = Math.min(choice.reputation, 4); const boost = Math.min(choice.reputation, 4);
//The 3 makes -2 the minimum votes before being ignored completely //The 3 makes -2 the minimum votes before being ignored completely
@ -241,7 +241,7 @@ async function chooseSegments(segments: DBSegment[], max: number): Promise<DBSeg
} }
cursor = Math.max(cursor, segment.endTime); cursor = Math.max(cursor, segment.endTime);
}; }
overlappingSegmentsGroups.forEach((group) => { overlappingSegmentsGroups.forEach((group) => {
if (group.required) { if (group.required) {
@ -313,26 +313,25 @@ async function handleGetSegments(req: Request, res: Response): Promise<Segment[]
if (segments.length === 0) { if (segments.length === 0) {
res.sendStatus(404); res.sendStatus(404);
return false; return false;
} }
return segments; return segments;
} }
async function endpoint(req: Request, res: Response): Promise<void> { async function endpoint(req: Request, res: Response): Promise<Response> {
try { try {
const segments = await handleGetSegments(req, res); const segments = await handleGetSegments(req, res);
// If false, res.send has already been called // If false, res.send has already been called
if (segments) { if (segments) {
//send result //send result
res.send(segments); return res.send(segments);
} }
} catch (err) { } catch (err) {
if (err instanceof SyntaxError) { if (err instanceof SyntaxError) {
res.status(400).send("Categories parameter does not match format requirements."); return res.status(400).send("Categories parameter does not match format requirements.");
} else res.status(500).send(); } else return res.sendStatus(500);
} }
} }

View file

@ -3,11 +3,10 @@ import {getSegmentsByHash} from './getSkipSegments';
import {Request, Response} from 'express'; import {Request, Response} from 'express';
import { Category, SegmentUUID, Service, VideoIDHash } from '../types/segments.model'; import { Category, SegmentUUID, Service, VideoIDHash } from '../types/segments.model';
export async function getSkipSegmentsByHash(req: Request, res: Response) { export async function getSkipSegmentsByHash(req: Request, res: Response): Promise<Response> {
let hashPrefix = req.params.prefix as VideoIDHash; let hashPrefix = req.params.prefix as VideoIDHash;
if (!hashPrefixTester(req.params.prefix)) { if (!hashPrefixTester(req.params.prefix)) {
res.status(400).send("Hash prefix does not match format requirements."); // Exit early on faulty prefix return res.status(400).send("Hash prefix does not match format requirements."); // Exit early on faulty prefix
return;
} }
hashPrefix = hashPrefix.toLowerCase() as VideoIDHash; hashPrefix = hashPrefix.toLowerCase() as VideoIDHash;
@ -61,6 +60,5 @@ export async function getSkipSegmentsByHash(req: Request, res: Response) {
hash: data.hash, hash: data.hash,
segments: data.segments, segments: data.segments,
})); }));
return res.status(output.length === 0 ? 404 : 200).json(output);
res.status(output.length === 0 ? 404 : 200).json(output);
} }

View file

@ -7,7 +7,7 @@ const MILLISECONDS_IN_MINUTE = 60000;
const getTopUsersWithCache = createMemoryCache(generateTopUsersStats, config.getTopUsersCacheTimeMinutes * MILLISECONDS_IN_MINUTE); const getTopUsersWithCache = createMemoryCache(generateTopUsersStats, config.getTopUsersCacheTimeMinutes * MILLISECONDS_IN_MINUTE);
const maxRewardTimePerSegmentInSeconds = config.maxRewardTimePerSegmentInSeconds ?? 86400; const maxRewardTimePerSegmentInSeconds = config.maxRewardTimePerSegmentInSeconds ?? 86400;
async function generateTopUsersStats(sortBy: string, categoryStatsEnabled: boolean = false) { async function generateTopUsersStats(sortBy: string, categoryStatsEnabled = false) {
const userNames = []; const userNames = [];
const viewCounts = []; const viewCounts = [];
const totalSubmissions = []; const totalSubmissions = [];
@ -63,14 +63,13 @@ async function generateTopUsersStats(sortBy: string, categoryStatsEnabled: boole
}; };
} }
export async function getTopUsers(req: Request, res: Response) { export async function getTopUsers(req: Request, res: Response): Promise<Response> {
const sortType = parseInt(req.query.sortType as string); const sortType = parseInt(req.query.sortType as string);
const categoryStatsEnabled = req.query.categoryStats; const categoryStatsEnabled = req.query.categoryStats;
if (sortType == undefined) { if (sortType == undefined) {
//invalid request //invalid request
res.sendStatus(400); return res.sendStatus(400);
return;
} }
//setup which sort type to use //setup which sort type to use
@ -89,5 +88,5 @@ export async function getTopUsers(req: Request, res: Response) {
const stats = await getTopUsersWithCache(sortBy, categoryStatsEnabled); const stats = await getTopUsersWithCache(sortBy, categoryStatsEnabled);
//send this result //send this result
res.send(stats); return res.send(stats);
} }

View file

@ -13,14 +13,14 @@ let apiUsersCache = 0;
let lastUserCountCheck = 0; let lastUserCountCheck = 0;
export async function getTotalStats(req: Request, res: Response) { export async function getTotalStats(req: Request, res: Response): Promise<void> {
const userCountQuery = `(SELECT COUNT(*) FROM (SELECT DISTINCT "userID" from "sponsorTimes") t) "userCount",`; const userCountQuery = `(SELECT COUNT(*) FROM (SELECT DISTINCT "userID" from "sponsorTimes") t) "userCount",`;
let row = await db.prepare('get', `SELECT ${req.query.countContributingUsers ? userCountQuery : ""} COUNT(*) as "totalSubmissions", const row = await db.prepare('get', `SELECT ${req.query.countContributingUsers ? userCountQuery : ""} COUNT(*) as "totalSubmissions",
SUM("views") as "viewCount", SUM(("endTime" - "startTime") / 60 * "views") as "minutesSaved" FROM "sponsorTimes" WHERE "shadowHidden" != 1 AND "votes" >= 0`, []); SUM("views") as "viewCount", SUM(("endTime" - "startTime") / 60 * "views") as "minutesSaved" FROM "sponsorTimes" WHERE "shadowHidden" != 1 AND "votes" >= 0`, []);
if (row !== undefined) { if (row !== undefined) {
let extensionUsers = chromeUsersCache + firefoxUsersCache; const extensionUsers = chromeUsersCache + firefoxUsersCache;
//send this result //send this result
res.send({ res.send({
@ -33,7 +33,7 @@ export async function getTotalStats(req: Request, res: Response) {
}); });
// Check if the cache should be updated (every ~14 hours) // Check if the cache should be updated (every ~14 hours)
let now = Date.now(); const now = Date.now();
if (now - lastUserCountCheck > 5000000) { if (now - lastUserCountCheck > 5000000) {
lastUserCountCheck = now; lastUserCountCheck = now;
@ -79,7 +79,7 @@ function updateExtensionUsers() {
}) })
.catch(() => Logger.debug("Failing to connect to " + chromeExtensionUrl)); .catch(() => Logger.debug("Failing to connect to " + chromeExtensionUrl));
}) })
.catch(err => { .catch(() => {
Logger.debug("Failing to connect to " + mozillaAddonsUrl); Logger.debug("Failing to connect to " + mozillaAddonsUrl);
}); });
} }

View file

@ -2,7 +2,7 @@ import {db} from '../databases/databases';
import {Request, Response} from 'express'; import {Request, Response} from 'express';
import {UserID} from '../types/user.model'; import {UserID} from '../types/user.model';
function getFuzzyUserID(userName: String): Promise<{userName: String, userID: UserID }[]> { function getFuzzyUserID(userName: string): Promise<{userName: string, userID: UserID }[]> {
// escape [_ % \] to avoid ReDOS // escape [_ % \] to avoid ReDOS
userName = userName.replace(/\\/g, '\\\\') userName = userName.replace(/\\/g, '\\\\')
.replace(/_/g, '\\_') .replace(/_/g, '\\_')
@ -11,13 +11,13 @@ function getFuzzyUserID(userName: String): Promise<{userName: String, userID: Us
// LIMIT to reduce overhead | ESCAPE to escape LIKE wildcards // LIMIT to reduce overhead | ESCAPE to escape LIKE wildcards
try { try {
return db.prepare('all', `SELECT "userName", "userID" FROM "userNames" WHERE "userName" return db.prepare('all', `SELECT "userName", "userID" FROM "userNames" WHERE "userName"
LIKE ? ESCAPE '\\' LIMIT 10`, [userName]) LIKE ? ESCAPE '\\' LIMIT 10`, [userName]);
} catch (err) { } catch (err) {
return null; return null;
} }
} }
function getExactUserID(userName: String): Promise<{userName: String, userID: UserID }[]> { function getExactUserID(userName: string): Promise<{userName: string, userID: UserID }[]> {
try { try {
return db.prepare('all', `SELECT "userName", "userID" from "userNames" WHERE "userName" = ? LIMIT 10`, [userName]); return db.prepare('all', `SELECT "userName", "userID" from "userNames" WHERE "userName" = ? LIMIT 10`, [userName]);
} catch (err) { } catch (err) {
@ -25,31 +25,27 @@ function getExactUserID(userName: String): Promise<{userName: String, userID: Us
} }
} }
export async function getUserID(req: Request, res: Response) { export async function getUserID(req: Request, res: Response): Promise<Response> {
let userName = req.query.username as string; const userName = req.query.username as string;
const exactSearch = req.query.exact const exactSearch = req.query.exact
? req.query.exact == "true" ? req.query.exact == "true"
: false as Boolean; : false as boolean;
// if not exact and length is 1, also skip // if not exact and length is 1, also skip
if (userName == undefined || userName.length > 64 || if (userName == undefined || userName.length > 64 ||
(!exactSearch && userName.length < 3)) { (!exactSearch && userName.length < 3)) {
// invalid request // invalid request
res.sendStatus(400); return res.sendStatus(400);
return false;
} }
const results = exactSearch const results = exactSearch
? await getExactUserID(userName) ? await getExactUserID(userName)
: await getFuzzyUserID(userName); : await getFuzzyUserID(userName);
if (results === undefined || results === null) { if (results === undefined || results === null) {
res.sendStatus(500); return res.sendStatus(500);
return false;
} else if (results.length === 0) { } else if (results.length === 0) {
res.sendStatus(404); return res.sendStatus(404);
return false;
} else { } else {
res.send(results); return res.send(results);
return false;
} }
} }

View file

@ -9,7 +9,7 @@ import { SegmentUUID } from "../types/segments.model";
async function dbGetSubmittedSegmentSummary(userID: HashedUserID): Promise<{ minutesSaved: number, segmentCount: number }> { async function dbGetSubmittedSegmentSummary(userID: HashedUserID): Promise<{ minutesSaved: number, segmentCount: number }> {
try { try {
let row = await db.prepare("get", `SELECT SUM((("endTime" - "startTime") / 60) * "views") as "minutesSaved", const row = await db.prepare("get", `SELECT SUM((("endTime" - "startTime") / 60) * "views") as "minutesSaved",
count(*) as "segmentCount" FROM "sponsorTimes" count(*) as "segmentCount" FROM "sponsorTimes"
WHERE "userID" = ? AND "votes" > -2 AND "shadowHidden" != 1`, [userID]); WHERE "userID" = ? AND "votes" > -2 AND "shadowHidden" != 1`, [userID]);
if (row.minutesSaved != null) { if (row.minutesSaved != null) {
@ -30,8 +30,8 @@ async function dbGetSubmittedSegmentSummary(userID: HashedUserID): Promise<{ min
async function dbGetIgnoredSegmentCount(userID: HashedUserID): Promise<number> { async function dbGetIgnoredSegmentCount(userID: HashedUserID): Promise<number> {
try { try {
let row = await db.prepare("get", `SELECT COUNT(*) as "ignoredSegmentCount" FROM "sponsorTimes" WHERE "userID" = ? AND ( "votes" <= -2 OR "shadowHidden" = 1 )`, [userID]); const row = await db.prepare("get", `SELECT COUNT(*) as "ignoredSegmentCount" FROM "sponsorTimes" WHERE "userID" = ? AND ( "votes" <= -2 OR "shadowHidden" = 1 )`, [userID]);
return row?.ignoredSegmentCount ?? 0 return row?.ignoredSegmentCount ?? 0;
} catch (err) { } catch (err) {
return null; return null;
} }
@ -39,7 +39,7 @@ async function dbGetIgnoredSegmentCount(userID: HashedUserID): Promise<number> {
async function dbGetUsername(userID: HashedUserID) { async function dbGetUsername(userID: HashedUserID) {
try { try {
let row = await db.prepare('get', `SELECT "userName" FROM "userNames" WHERE "userID" = ?`, [userID]); const row = await db.prepare('get', `SELECT "userName" FROM "userNames" WHERE "userID" = ?`, [userID]);
if (row !== undefined) { if (row !== undefined) {
return row.userName; return row.userName;
} else { } else {
@ -53,7 +53,7 @@ async function dbGetUsername(userID: HashedUserID) {
async function dbGetViewsForUser(userID: HashedUserID) { async function dbGetViewsForUser(userID: HashedUserID) {
try { try {
let row = await db.prepare('get', `SELECT SUM("views") as "viewCount" FROM "sponsorTimes" WHERE "userID" = ? AND "votes" > -2 AND "shadowHidden" != 1`, [userID]); const row = await db.prepare('get', `SELECT SUM("views") as "viewCount" FROM "sponsorTimes" WHERE "userID" = ? AND "votes" > -2 AND "shadowHidden" != 1`, [userID]);
return row?.viewCount ?? 0; return row?.viewCount ?? 0;
} catch (err) { } catch (err) {
return false; return false;
@ -62,7 +62,7 @@ async function dbGetViewsForUser(userID: HashedUserID) {
async function dbGetIgnoredViewsForUser(userID: HashedUserID) { async function dbGetIgnoredViewsForUser(userID: HashedUserID) {
try { try {
let row = await db.prepare('get', `SELECT SUM("views") as "ignoredViewCount" FROM "sponsorTimes" WHERE "userID" = ? AND ( "votes" <= -2 OR "shadowHidden" = 1 )`, [userID]); const row = await db.prepare('get', `SELECT SUM("views") as "ignoredViewCount" FROM "sponsorTimes" WHERE "userID" = ? AND ( "votes" <= -2 OR "shadowHidden" = 1 )`, [userID]);
return row?.ignoredViewCount ?? 0; return row?.ignoredViewCount ?? 0;
} catch (err) { } catch (err) {
return false; return false;
@ -71,7 +71,7 @@ async function dbGetIgnoredViewsForUser(userID: HashedUserID) {
async function dbGetWarningsForUser(userID: HashedUserID): Promise<number> { async function dbGetWarningsForUser(userID: HashedUserID): Promise<number> {
try { try {
let row = await db.prepare('get', `SELECT COUNT(*) as total FROM "warnings" WHERE "userID" = ? AND "enabled" = 1`, [userID]); const row = await db.prepare('get', `SELECT COUNT(*) as total FROM "warnings" WHERE "userID" = ? AND "enabled" = 1`, [userID]);
return row?.total ?? 0; return row?.total ?? 0;
} catch (err) { } catch (err) {
Logger.error('Couldn\'t get warnings for user ' + userID + '. returning 0'); Logger.error('Couldn\'t get warnings for user ' + userID + '. returning 0');
@ -81,26 +81,25 @@ async function dbGetWarningsForUser(userID: HashedUserID): Promise<number> {
async function dbGetLastSegmentForUser(userID: HashedUserID): Promise<SegmentUUID> { async function dbGetLastSegmentForUser(userID: HashedUserID): Promise<SegmentUUID> {
try { try {
let row = await db.prepare('get', `SELECT "UUID" FROM "sponsorTimes" WHERE "userID" = ? ORDER BY "timeSubmitted" DESC LIMIT 1`, [userID]); const row = await db.prepare('get', `SELECT "UUID" FROM "sponsorTimes" WHERE "userID" = ? ORDER BY "timeSubmitted" DESC LIMIT 1`, [userID]);
return row?.UUID ?? null; return row?.UUID ?? null;
} catch (err) { } catch (err) {
return null; return null;
} }
} }
export async function getUserInfo(req: Request, res: Response) { export async function getUserInfo(req: Request, res: Response): Promise<Response> {
const userID = req.query.userID as UserID; const userID = req.query.userID as UserID;
const hashedUserID: HashedUserID = userID ? getHash(userID) : req.query.publicUserID as HashedUserID; const hashedUserID: HashedUserID = userID ? getHash(userID) : req.query.publicUserID as HashedUserID;
if (hashedUserID == undefined) { if (hashedUserID == undefined) {
//invalid request //invalid request
res.status(400).send('Parameters are not valid'); return res.status(400).send('Parameters are not valid');
return;
} }
const segmentsSummary = await dbGetSubmittedSegmentSummary(hashedUserID); const segmentsSummary = await dbGetSubmittedSegmentSummary(hashedUserID);
if (segmentsSummary) { if (segmentsSummary) {
res.send({ return res.send({
userID: hashedUserID, userID: hashedUserID,
userName: await dbGetUsername(hashedUserID), userName: await dbGetUsername(hashedUserID),
minutesSaved: segmentsSummary.minutesSaved, minutesSaved: segmentsSummary.minutesSaved,
@ -114,6 +113,6 @@ export async function getUserInfo(req: Request, res: Response) {
lastSegmentID: await dbGetLastSegmentForUser(hashedUserID), lastSegmentID: await dbGetLastSegmentForUser(hashedUserID),
}); });
} else { } else {
res.status(400).send(); return res.sendStatus(400);
} }
} }

View file

@ -3,35 +3,32 @@ import {getHash} from '../utils/getHash';
import {Logger} from '../utils/logger'; import {Logger} from '../utils/logger';
import {Request, Response} from 'express'; import {Request, Response} from 'express';
export async function getUsername(req: Request, res: Response) { export async function getUsername(req: Request, res: Response): Promise<Response> {
let userID = req.query.userID as string; let userID = req.query.userID as string;
if (userID == undefined) { if (userID == undefined) {
//invalid request //invalid request
res.sendStatus(400); return res.sendStatus(400);
return;
} }
//hash the userID //hash the userID
userID = getHash(userID); userID = getHash(userID);
try { try {
let row = await db.prepare('get', `SELECT "userName" FROM "userNames" WHERE "userID" = ?`, [userID]); const row = await db.prepare('get', `SELECT "userName" FROM "userNames" WHERE "userID" = ?`, [userID]);
if (row !== undefined) { if (row !== undefined) {
res.send({ return res.send({
userName: row.userName, userName: row.userName,
}); });
} else { } else {
//no username yet, just send back the userID //no username yet, just send back the userID
res.send({ return res.send({
userName: userID, userName: userID,
}); });
} }
} catch (err) { } catch (err) {
Logger.error(err); Logger.error(err);
res.sendStatus(500); return res.sendStatus(500);
return;
} }
} }

View file

@ -3,33 +3,30 @@ import {Request, Response} from 'express';
import {getHash} from '../utils/getHash'; import {getHash} from '../utils/getHash';
import {Logger} from '../utils/logger'; import {Logger} from '../utils/logger';
export async function getViewsForUser(req: Request, res: Response) { export async function getViewsForUser(req: Request, res: Response): Promise<Response> {
let userID = req.query.userID as string; let userID = req.query.userID as string;
if (userID == undefined) { if (userID == undefined) {
//invalid request //invalid request
res.sendStatus(400); return res.sendStatus(400);
return;
} }
//hash the userID //hash the userID
userID = getHash(userID); userID = getHash(userID);
try { try {
let row = await db.prepare('get', `SELECT SUM("views") as "viewCount" FROM "sponsorTimes" WHERE "userID" = ?`, [userID]); const row = await db.prepare('get', `SELECT SUM("views") as "viewCount" FROM "sponsorTimes" WHERE "userID" = ?`, [userID]);
//increase the view count by one //increase the view count by one
if (row.viewCount != null) { if (row.viewCount != null) {
res.send({ return res.send({
viewCount: row.viewCount, viewCount: row.viewCount,
}); });
} else { } else {
res.sendStatus(404); return res.sendStatus(404);
} }
} catch (err) { } catch (err) {
Logger.error(err); Logger.error(err);
res.sendStatus(500); return res.sendStatus(500);
return;
} }
} }

View file

@ -1,20 +1,20 @@
import {handleGetSegments} from './getSkipSegments'; import {handleGetSegments} from './getSkipSegments';
import {Request, Response} from 'express'; import {Request, Response} from 'express';
export async function oldGetVideoSponsorTimes(req: Request, res: Response): Promise<void> { export async function oldGetVideoSponsorTimes(req: Request, res: Response): Promise<Response> {
let segments = await handleGetSegments(req, res); const segments = await handleGetSegments(req, res);
if (segments) { if (segments) {
// Convert to old outputs // Convert to old outputs
let sponsorTimes = []; const sponsorTimes = [];
let UUIDs = []; const UUIDs = [];
for (const segment of segments) { for (const segment of segments) {
sponsorTimes.push(segment.segment); sponsorTimes.push(segment.segment);
UUIDs.push(segment.UUID); UUIDs.push(segment.UUID);
} }
res.send({ return res.send({
sponsorTimes, sponsorTimes,
UUIDs, UUIDs,
}); });

View file

@ -1,8 +1,7 @@
import {postSkipSegments} from './postSkipSegments'; import {postSkipSegments} from './postSkipSegments';
import {Request, Response} from 'express'; import {Request, Response} from 'express';
export async function oldSubmitSponsorTimes(req: Request, res: Response) { export async function oldSubmitSponsorTimes(req: Request, res: Response): Promise<Response> {
req.query.category = "sponsor"; req.query.category = "sponsor";
return postSkipSegments(req, res); return postSkipSegments(req, res);
} }

View file

@ -7,9 +7,9 @@ import { QueryCacher } from '../utils/queryCacher';
import { isUserVIP } from '../utils/isUserVIP'; import { isUserVIP } from '../utils/isUserVIP';
import { VideoIDHash } from "../types/segments.model"; import { VideoIDHash } from "../types/segments.model";
export async function postClearCache(req: Request, res: Response) { export async function postClearCache(req: Request, res: Response): Promise<Response> {
const videoID = req.query.videoID as VideoID; const videoID = req.query.videoID as VideoID;
let userID = req.query.userID as UserID; const userID = req.query.userID as UserID;
const service = req.query.service as Service ?? Service.YouTube; const service = req.query.service as Service ?? Service.YouTube;
const invalidFields = []; const invalidFields = [];
@ -23,8 +23,7 @@ export async function postClearCache(req: Request, res: Response) {
if (invalidFields.length !== 0) { if (invalidFields.length !== 0) {
// invalid request // invalid request
const fields = invalidFields.reduce((p, c, i) => p + (i !== 0 ? ', ' : '') + c, ''); const fields = invalidFields.reduce((p, c, i) => p + (i !== 0 ? ', ' : '') + c, '');
res.status(400).send(`No valid ${fields} field(s) provided`); return res.status(400).send(`No valid ${fields} field(s) provided`);
return false;
} }
// hash the userID as early as possible // hash the userID as early as possible
@ -35,8 +34,7 @@ export async function postClearCache(req: Request, res: Response) {
// Ensure user is a VIP // Ensure user is a VIP
if (!(await isUserVIP(hashedUserID))){ if (!(await isUserVIP(hashedUserID))){
Logger.warn("Permission violation: User " + hashedUserID + " attempted to clear cache for video " + videoID + "."); Logger.warn("Permission violation: User " + hashedUserID + " attempted to clear cache for video " + videoID + ".");
res.status(403).json({"message": "Not a VIP"}); return res.status(403).json({"message": "Not a VIP"});
return false;
} }
try { try {
@ -45,11 +43,10 @@ export async function postClearCache(req: Request, res: Response) {
hashedVideoID, hashedVideoID,
service service
}); });
res.status(200).json({ return res.status(200).json({
message: "Cache cleared on video " + videoID message: "Cache cleared on video " + videoID
}); });
} catch(err) { } catch(err) {
res.status(500).send() return res.sendStatus(500);
return false;
} }
} }

View file

@ -4,11 +4,11 @@ import {isUserVIP} from '../utils/isUserVIP';
import {db} from '../databases/databases'; import {db} from '../databases/databases';
import {Request, Response} from 'express'; import {Request, Response} from 'express';
export async function postLockCategories(req: Request, res: Response) { export async function postLockCategories(req: Request, res: Response): Promise<string[]> {
// Collect user input data // Collect user input data
let videoID = req.body.videoID; const videoID = req.body.videoID;
let userID = req.body.userID; let userID = req.body.userID;
let categories = req.body.categories; const categories = req.body.categories;
// Check input data is valid // Check input data is valid
if (!videoID if (!videoID
@ -25,7 +25,7 @@ export async function postLockCategories(req: Request, res: Response) {
// Check if user is VIP // Check if user is VIP
userID = getHash(userID); userID = getHash(userID);
let userIsVIP = await isUserVIP(userID); const userIsVIP = await isUserVIP(userID);
if (!userIsVIP) { if (!userIsVIP) {
res.status(403).json({ res.status(403).json({
@ -67,7 +67,7 @@ export async function postLockCategories(req: Request, res: Response) {
message: "Internal Server Error: Could not write marker to the database.", message: "Internal Server Error: Could not write marker to the database.",
}); });
} }
}; }
res.status(200).json({ res.status(200).json({
submitted: categoriesToMark, submitted: categoriesToMark,

View file

@ -6,36 +6,31 @@ import {HashedUserID, UserID} from '../types/user.model';
import {VideoID} from "../types/segments.model"; import {VideoID} from "../types/segments.model";
import {db} from '../databases/databases'; import {db} from '../databases/databases';
export async function postPurgeAllSegments(req: Request, res: Response): Promise<void> { export async function postPurgeAllSegments(req: Request, res: Response): Promise<Response> {
const userID = req.body.userID as UserID; const userID = req.body.userID as UserID;
const videoID = req.body.videoID as VideoID; const videoID = req.body.videoID as VideoID;
if (userID == undefined) { if (userID == undefined) {
//invalid request //invalid request
res.sendStatus(400); return res.sendStatus(400);
return;
} }
//hash the userID //hash the userID
const hashedUserID: HashedUserID = getHash(userID); const hashedUserID: HashedUserID = getHash(userID);
try { try {
let vipState = await isUserVIP(hashedUserID); const vipState = await isUserVIP(hashedUserID);
if (!vipState) { if (!vipState) {
res.status(403).json({ return res.status(403).json({
message: 'Must be a VIP to perform this action.', message: 'Must be a VIP to perform this action.',
}); });
return;
} }
await db.prepare('run', `UPDATE "sponsorTimes" SET "hidden" = 1 WHERE "videoID" = ?`, [videoID]); await db.prepare('run', `UPDATE "sponsorTimes" SET "hidden" = 1 WHERE "videoID" = ?`, [videoID]);
} catch (err) { } catch (err) {
Logger.error(err); Logger.error(err);
res.sendStatus(500); return res.sendStatus(500);
return;
} }
return res.sendStatus(200);
res.sendStatus(200);
} }

View file

@ -58,10 +58,9 @@ export async function postSegmentShift(req: Request, res: Response): Promise<Res
|| !startTime || !startTime
|| !endTime || !endTime
) { ) {
res.status(400).json({ return res.status(400).json({
message: 'Bad Format', message: 'Bad Format',
}); });
return;
} }
// Check if user is VIP // Check if user is VIP
@ -69,10 +68,9 @@ export async function postSegmentShift(req: Request, res: Response): Promise<Res
const userIsVIP = await isUserVIP(userID); const userIsVIP = await isUserVIP(userID);
if (!userIsVIP) { if (!userIsVIP) {
res.status(403).json({ return res.status(403).json({
message: 'Must be a VIP to perform this action.', message: 'Must be a VIP to perform this action.',
}); });
return;
} }
try { try {
@ -92,11 +90,11 @@ export async function postSegmentShift(req: Request, res: Response): Promise<Res
await db.prepare('run', 'UPDATE "sponsorTimes" SET "startTime" = ?, "endTime" = ?, "votes" = -2 WHERE "UUID" = ?', [result.segment.startTime, result.segment.endTime, result.segment.UUID]); await db.prepare('run', 'UPDATE "sponsorTimes" SET "startTime" = ?, "endTime" = ?, "votes" = -2 WHERE "UUID" = ?', [result.segment.startTime, result.segment.endTime, result.segment.UUID]);
break; break;
} }
}; }
} catch (err) { } catch (err) {
Logger.error(err); Logger.error(err);
res.sendStatus(500); return res.sendStatus(500);
} }
res.sendStatus(200); return res.sendStatus(200);
} }

View file

@ -10,9 +10,7 @@ import {getFormattedTime} from '../utils/getFormattedTime';
import {isUserTrustworthy} from '../utils/isUserTrustworthy'; import {isUserTrustworthy} from '../utils/isUserTrustworthy';
import {dispatchEvent} from '../utils/webhookUtils'; import {dispatchEvent} from '../utils/webhookUtils';
import {Request, Response} from 'express'; import {Request, Response} from 'express';
import { skipSegmentsHashKey, skipSegmentsKey } from '../utils/redisKeys'; import { Category, CategoryActionType, IncomingSegment, SegmentUUID, Service, VideoDuration, VideoID } from '../types/segments.model';
import redis from '../utils/redis';
import { Category, CategoryActionType, IncomingSegment, Segment, SegmentUUID, Service, VideoDuration, VideoID } from '../types/segments.model';
import { deleteLockCategories } from './deleteLockCategories'; import { deleteLockCategories } from './deleteLockCategories';
import { getCategoryActionType } from '../utils/categoryInfo'; import { getCategoryActionType } from '../utils/categoryInfo';
import { QueryCacher } from '../utils/queryCacher'; import { QueryCacher } from '../utils/queryCacher';
@ -175,9 +173,6 @@ async function autoModerateSubmission(apiVideoInfo: APIVideoInfo,
const segments = submission.segments; const segments = submission.segments;
let nbString = ""; let nbString = "";
for (let i = 0; i < segments.length; i++) { for (let i = 0; i < segments.length; i++) {
const startTime = parseFloat(segments[i].segment[0]);
const endTime = parseFloat(segments[i].segment[1]);
if (duration == 0) { if (duration == 0) {
// Allow submission if the duration is 0 (bug in youtube api) // Allow submission if the duration is 0 (bug in youtube api)
return false; return false;
@ -201,8 +196,8 @@ async function autoModerateSubmission(apiVideoInfo: APIVideoInfo,
//add segments they are trying to add in this submission //add segments they are trying to add in this submission
for (let i = 0; i < segments.length; i++) { for (let i = 0; i < segments.length; i++) {
let startTime = parseFloat(segments[i].segment[0]); const startTime = parseFloat(segments[i].segment[0]);
let endTime = parseFloat(segments[i].segment[1]); const endTime = parseFloat(segments[i].segment[1]);
allSegmentTimes.push([startTime, endTime]); allSegmentTimes.push([startTime, endTime]);
} }
@ -285,7 +280,7 @@ async function checkUserActiveWarning(userID: string): Promise<{ pass: boolean;
Math.floor(now - (config.hoursAfterWarningExpires * MILLISECONDS_IN_HOUR)), Math.floor(now - (config.hoursAfterWarningExpires * MILLISECONDS_IN_HOUR)),
config.maxNumberOfActiveWarnings config.maxNumberOfActiveWarnings
], ],
) as {reason: string}[] ) as {reason: string}[];
if (warnings?.length >= config.maxNumberOfActiveWarnings) { if (warnings?.length >= config.maxNumberOfActiveWarnings) {
const defaultMessage = 'Submission rejected due to a warning from a moderator. This means that we noticed you were making some common mistakes that are not malicious, and we just want to clarify the rules. Could you please send a message in Discord or Matrix so we can further help you?'; const defaultMessage = 'Submission rejected due to a warning from a moderator. This means that we noticed you were making some common mistakes that are not malicious, and we just want to clarify the rules. Could you please send a message in Discord or Matrix so we can further help you?';
@ -307,12 +302,12 @@ function proxySubmission(req: Request) {
.then(async res => { .then(async res => {
Logger.debug('Proxy Submission: ' + res.status + ' (' + (await res.text()) + ')'); Logger.debug('Proxy Submission: ' + res.status + ' (' + (await res.text()) + ')');
}) })
.catch(err => { .catch(() => {
Logger.error("Proxy Submission: Failed to make call"); Logger.error("Proxy Submission: Failed to make call");
}); });
} }
export async function postSkipSegments(req: Request, res: Response) { export async function postSkipSegments(req: Request, res: Response): Promise<Response> {
if (config.proxySubmission) { if (config.proxySubmission) {
proxySubmission(req); proxySubmission(req);
} }
@ -346,10 +341,9 @@ export async function postSkipSegments(req: Request, res: Response) {
} }
if (invalidFields.length !== 0) { if (invalidFields.length !== 0) {
// invalid request // invalid request
const fields = invalidFields.reduce((p, c, i) => p + (i !== 0 ? ', ' : '') + c, ''); const fields = invalidFields.reduce((p, c, i) => p + (i !== 0 ? ', ' : '') + c, '');
res.status(400).send(`No valid ${fields} field(s) provided`); return res.status(400).send(`No valid ${fields} field(s) provided`);
return;
} }
//hash the userID //hash the userID
@ -360,9 +354,7 @@ export async function postSkipSegments(req: Request, res: Response) {
return res.status(403).send(warningResult.errorMessage); return res.status(403).send(warningResult.errorMessage);
} }
let lockedCategoryList = (await db.prepare('all', 'SELECT category from "lockCategories" where "videoID" = ?', [videoID])).map((list: any) => { let lockedCategoryList = (await db.prepare('all', 'SELECT category from "lockCategories" where "videoID" = ?', [videoID])).map((list: any) => list.category );
return list.category;
});
//check if this user is on the vip list //check if this user is on the vip list
const isVIP = (await db.prepare("get", `SELECT count(*) as "userCount" FROM "vipUsers" WHERE "userID" = ?`, [userID])).userCount > 0; const isVIP = (await db.prepare("get", `SELECT count(*) as "userCount" FROM "vipUsers" WHERE "userID" = ?`, [userID])).userCount > 0;
@ -407,54 +399,48 @@ export async function postSkipSegments(req: Request, res: Response) {
for (let i = 0; i < segments.length; i++) { for (let i = 0; i < segments.length; i++) {
if (segments[i] === undefined || segments[i].segment === undefined || segments[i].category === undefined) { if (segments[i] === undefined || segments[i].segment === undefined || segments[i].category === undefined) {
//invalid request //invalid request
res.status(400).send("One of your segments are invalid"); return res.status(400).send("One of your segments are invalid");
return;
} }
if (!config.categoryList.includes(segments[i].category)) { if (!config.categoryList.includes(segments[i].category)) {
res.status(400).send("Category doesn't exist."); return res.status(400).send("Category doesn't exist.");
return;
} }
// Reject segment if it's in the locked categories list // Reject segment if it's in the locked categories list
if (!isVIP && lockedCategoryList.indexOf(segments[i].category) !== -1) { if (!isVIP && lockedCategoryList.indexOf(segments[i].category) !== -1) {
// TODO: Do something about the fradulent submission // TODO: Do something about the fradulent submission
Logger.warn("Caught a no-segment submission. userID: '" + userID + "', videoID: '" + videoID + "', category: '" + segments[i].category + "'"); Logger.warn("Caught a no-segment submission. userID: '" + userID + "', videoID: '" + videoID + "', category: '" + segments[i].category + "'");
res.status(403).send( return res.status(403).send(
"New submissions are not allowed for the following category: '" "New submissions are not allowed for the following category: '"
+ segments[i].category + "'. A moderator has decided that no new segments are needed and that all current segments of this category are timed perfectly.\n\n " + segments[i].category + "'. A moderator has decided that no new segments are needed and that all current segments of this category are timed perfectly.\n\n "
+ (segments[i].category === "sponsor" ? "Maybe the segment you are submitting is a different category that you have not enabled and is not a sponsor. " + + (segments[i].category === "sponsor" ? "Maybe the segment you are submitting is a different category that you have not enabled and is not a sponsor. " +
"Categories that aren't sponsor, such as self-promotion can be enabled in the options.\n\n" : "") "Categories that aren't sponsor, such as self-promotion can be enabled in the options.\n\n" : "")
+ "If you believe this is incorrect, please contact someone on discord.gg/SponsorBlock or matrix.to/#/+sponsorblock:ajay.app", + "If you believe this is incorrect, please contact someone on discord.gg/SponsorBlock or matrix.to/#/+sponsorblock:ajay.app",
); );
return;
} }
let startTime = parseFloat(segments[i].segment[0]); const startTime = parseFloat(segments[i].segment[0]);
let endTime = parseFloat(segments[i].segment[1]); const endTime = parseFloat(segments[i].segment[1]);
if (isNaN(startTime) || isNaN(endTime) if (isNaN(startTime) || isNaN(endTime)
|| startTime === Infinity || endTime === Infinity || startTime < 0 || startTime > endTime || startTime === Infinity || endTime === Infinity || startTime < 0 || startTime > endTime
|| (getCategoryActionType(segments[i].category) === CategoryActionType.Skippable && startTime === endTime) || (getCategoryActionType(segments[i].category) === CategoryActionType.Skippable && startTime === endTime)
|| (getCategoryActionType(segments[i].category) === CategoryActionType.POI && startTime !== endTime)) { || (getCategoryActionType(segments[i].category) === CategoryActionType.POI && startTime !== endTime)) {
//invalid request //invalid request
res.status(400).send("One of your segments times are invalid (too short, startTime before endTime, etc.)"); return res.status(400).send("One of your segments times are invalid (too short, startTime before endTime, etc.)");
return;
} }
if (!isVIP && segments[i].category === "sponsor" && Math.abs(startTime - endTime) < 1) { if (!isVIP && segments[i].category === "sponsor" && Math.abs(startTime - endTime) < 1) {
// Too short // Too short
res.status(400).send("Sponsors must be longer than 1 second long"); return res.status(400).send("Sponsors must be longer than 1 second long");
return;
} }
//check if this info has already been submitted before //check if this info has already been submitted before
const duplicateCheck2Row = await db.prepare('get', `SELECT COUNT(*) as count FROM "sponsorTimes" WHERE "startTime" = ? const duplicateCheck2Row = await db.prepare('get', `SELECT COUNT(*) as count FROM "sponsorTimes" WHERE "startTime" = ?
and "endTime" = ? and "category" = ? and "videoID" = ? and "service" = ?`, [startTime, endTime, segments[i].category, videoID, service]); and "endTime" = ? and "category" = ? and "videoID" = ? and "service" = ?`, [startTime, endTime, segments[i].category, videoID, service]);
if (duplicateCheck2Row.count > 0) { if (duplicateCheck2Row.count > 0) {
res.sendStatus(409); return res.sendStatus(409);
return;
} }
} }
@ -469,8 +455,7 @@ export async function postSkipSegments(req: Request, res: Response) {
//decreaseVotes = -2; //Disable for now //decreaseVotes = -2; //Disable for now
} else if (autoModerateResult) { } else if (autoModerateResult) {
//Normal automod behavior //Normal automod behavior
res.status(403).send("Request rejected by auto moderator: " + autoModerateResult + " If this is an issue, send a message on Discord."); return res.status(403).send("Request rejected by auto moderator: " + autoModerateResult + " If this is an issue, send a message on Discord.");
return;
} }
} }
// Will be filled when submitting // Will be filled when submitting
@ -487,28 +472,26 @@ export async function postSkipSegments(req: Request, res: Response) {
const yesterday = timeSubmitted - 86400000; const yesterday = timeSubmitted - 86400000;
// Disable IP ratelimiting for now // Disable IP ratelimiting for now
// eslint-disable-next-line no-constant-condition
if (false) { if (false) {
//check to see if this ip has submitted too many sponsors today //check to see if this ip has submitted too many sponsors today
const rateLimitCheckRow = await privateDB.prepare('get', `SELECT COUNT(*) as count FROM "sponsorTimes" WHERE "hashedIP" = ? AND "videoID" = ? AND "timeSubmitted" > ?`, [hashedIP, videoID, yesterday]); const rateLimitCheckRow = await privateDB.prepare('get', `SELECT COUNT(*) as count FROM "sponsorTimes" WHERE "hashedIP" = ? AND "videoID" = ? AND "timeSubmitted" > ?`, [hashedIP, videoID, yesterday]);
if (rateLimitCheckRow.count >= 10) { if (rateLimitCheckRow.count >= 10) {
//too many sponsors for the same video from the same ip address //too many sponsors for the same video from the same ip address
res.sendStatus(429); return res.sendStatus(429);
return;
} }
} }
// Disable max submissions for now // Disable max submissions for now
// eslint-disable-next-line no-constant-condition
if (false) { if (false) {
//check to see if the user has already submitted sponsors for this video //check to see if the user has already submitted sponsors for this video
const duplicateCheckRow = await db.prepare('get', `SELECT COUNT(*) as count FROM "sponsorTimes" WHERE "userID" = ? and "videoID" = ?`, [userID, videoID]); const duplicateCheckRow = await db.prepare('get', `SELECT COUNT(*) as count FROM "sponsorTimes" WHERE "userID" = ? and "videoID" = ?`, [userID, videoID]);
if (duplicateCheckRow.count >= 16) { if (duplicateCheckRow.count >= 16) {
//too many sponsors for the same video from the same user //too many sponsors for the same video from the same user
res.sendStatus(429); return res.sendStatus(429);
return;
} }
} }
@ -522,7 +505,7 @@ export async function postSkipSegments(req: Request, res: Response) {
shadowBanned = 1; shadowBanned = 1;
} }
let startingVotes = 0 + decreaseVotes; const startingVotes = 0 + decreaseVotes;
const reputation = await getReputation(userID); const reputation = await getReputation(userID);
for (const segmentInfo of segments) { for (const segmentInfo of segments) {
@ -553,11 +536,9 @@ export async function postSkipSegments(req: Request, res: Response) {
}); });
} catch (err) { } catch (err) {
//a DB change probably occurred //a DB change probably occurred
res.sendStatus(500);
Logger.error("Error when putting sponsorTime in the DB: " + videoID + ", " + segmentInfo.segment[0] + ", " + Logger.error("Error when putting sponsorTime in the DB: " + videoID + ", " + segmentInfo.segment[0] + ", " +
segmentInfo.segment[1] + ", " + userID + ", " + segmentInfo.category + ". " + err); segmentInfo.segment[1] + ", " + userID + ", " + segmentInfo.category + ". " + err);
return res.sendStatus(500);
return;
} }
UUIDs.push(UUID); UUIDs.push(UUID);
@ -569,17 +550,13 @@ export async function postSkipSegments(req: Request, res: Response) {
} }
} catch (err) { } catch (err) {
Logger.error(err); Logger.error(err);
return res.sendStatus(500);
res.sendStatus(500);
return;
} }
res.json(newSegments);
for (let i = 0; i < segments.length; i++) { for (let i = 0; i < segments.length; i++) {
sendWebhooks(apiVideoInfo, userID, videoID, UUIDs[i], segments[i], service); sendWebhooks(apiVideoInfo, userID, videoID, UUIDs[i], segments[i], service);
} }
return res.json(newSegments);
} }
// Takes an array of arrays: // Takes an array of arrays:

View file

@ -5,7 +5,7 @@ import {isUserVIP} from '../utils/isUserVIP';
import {getHash} from '../utils/getHash'; import {getHash} from '../utils/getHash';
import { HashedUserID, UserID } from '../types/user.model'; import { HashedUserID, UserID } from '../types/user.model';
export async function postWarning(req: Request, res: Response) { export async function postWarning(req: Request, res: Response): Promise<Response> {
// Collect user input data // Collect user input data
const issuerUserID: HashedUserID = getHash(<UserID> req.body.issuerUserID); const issuerUserID: HashedUserID = getHash(<UserID> req.body.issuerUserID);
const userID: UserID = req.body.userID; const userID: UserID = req.body.userID;
@ -16,14 +16,13 @@ export async function postWarning(req: Request, res: Response) {
// Ensure user is a VIP // Ensure user is a VIP
if (!await isUserVIP(issuerUserID)) { if (!await isUserVIP(issuerUserID)) {
Logger.warn("Permission violation: User " + issuerUserID + " attempted to warn user " + userID + "."); Logger.warn("Permission violation: User " + issuerUserID + " attempted to warn user " + userID + ".");
res.status(403).json({"message": "Not a VIP"}); return res.status(403).json({"message": "Not a VIP"});
return;
} }
let resultStatus = ""; let resultStatus = "";
if (enabled) { if (enabled) {
let previousWarning = await db.prepare('get', 'SELECT * FROM "warnings" WHERE "userID" = ? AND "issuerUserID" = ?', [userID, issuerUserID]); const previousWarning = await db.prepare('get', 'SELECT * FROM "warnings" WHERE "userID" = ? AND "issuerUserID" = ?', [userID, issuerUserID]);
if (!previousWarning) { if (!previousWarning) {
await db.prepare( await db.prepare(
@ -33,15 +32,14 @@ export async function postWarning(req: Request, res: Response) {
); );
resultStatus = "issued to"; resultStatus = "issued to";
} else { } else {
res.status(409).send(); return res.sendStatus(409);
return;
} }
} else { } else {
await db.prepare('run', 'UPDATE "warnings" SET "enabled" = 0 WHERE "userID" = ?', [userID]); await db.prepare('run', 'UPDATE "warnings" SET "enabled" = 0 WHERE "userID" = ?', [userID]);
resultStatus = "removed from"; resultStatus = "removed from";
} }
res.status(200).json({ return res.status(200).json({
message: "Warning " + resultStatus + " user '" + userID + "'.", message: "Warning " + resultStatus + " user '" + userID + "'.",
}); });
} }

View file

@ -4,14 +4,14 @@ import {db, privateDB} from '../databases/databases';
import {getHash} from '../utils/getHash'; import {getHash} from '../utils/getHash';
import {Request, Response} from 'express'; import {Request, Response} from 'express';
async function logUserNameChange(userID: string, newUserName: string, oldUserName: string, updatedByAdmin: boolean): Promise<void> { async function logUserNameChange(userID: string, newUserName: string, oldUserName: string, updatedByAdmin: boolean): Promise<Response> {
return privateDB.prepare('run', return privateDB.prepare('run',
`INSERT INTO "userNameLogs"("userID", "newUserName", "oldUserName", "updatedByAdmin", "updatedAt") VALUES(?, ?, ?, ?, ?)`, `INSERT INTO "userNameLogs"("userID", "newUserName", "oldUserName", "updatedByAdmin", "updatedAt") VALUES(?, ?, ?, ?, ?)`,
[userID, newUserName, oldUserName, + updatedByAdmin, new Date().getTime()] [userID, newUserName, oldUserName, + updatedByAdmin, new Date().getTime()]
); );
} }
export async function setUsername(req: Request, res: Response) { export async function setUsername(req: Request, res: Response): Promise<Response> {
let userID = req.query.userID as string; let userID = req.query.userID as string;
let userName = req.query.username as string; let userName = req.query.username as string;
@ -19,18 +19,17 @@ export async function setUsername(req: Request, res: Response) {
if (userID == undefined || userName == undefined || userID === "undefined" || userName.length > 64) { if (userID == undefined || userName == undefined || userID === "undefined" || userName.length > 64) {
//invalid request //invalid request
res.sendStatus(400); return res.sendStatus(400);
return;
} }
if (userName.includes("discord")) { if (userName.includes("discord")) {
// Don't allow // Don't allow
res.sendStatus(200); return res.sendStatus(200);
return;
} }
// remove unicode control characters from username (example: \n, \r, \t etc.) // remove unicode control characters from username (example: \n, \r, \t etc.)
// source: https://en.wikipedia.org/wiki/Control_character#In_Unicode // source: https://en.wikipedia.org/wiki/Control_character#In_Unicode
// eslint-disable-next-line no-control-regex
userName = userName.replace(/[\u0000-\u001F\u007F-\u009F]/g, ''); userName = userName.replace(/[\u0000-\u001F\u007F-\u009F]/g, '');
if (adminUserIDInput != undefined) { if (adminUserIDInput != undefined) {
@ -39,8 +38,7 @@ export async function setUsername(req: Request, res: Response) {
if (adminUserIDInput != config.adminUserID) { if (adminUserIDInput != config.adminUserID) {
//they aren't the admin //they aren't the admin
res.sendStatus(403); return res.sendStatus(403);
return;
} }
} else { } else {
//hash the userID //hash the userID
@ -50,14 +48,12 @@ export async function setUsername(req: Request, res: Response) {
try { try {
const row = await db.prepare('get', `SELECT count(*) as count FROM "userNames" WHERE "userID" = ? AND "locked" = '1'`, [userID]); const row = await db.prepare('get', `SELECT count(*) as count FROM "userNames" WHERE "userID" = ? AND "locked" = '1'`, [userID]);
if (adminUserIDInput === undefined && row.count > 0) { if (adminUserIDInput === undefined && row.count > 0) {
res.sendStatus(200); return res.sendStatus(200);
return;
} }
} }
catch (error) { catch (error) {
Logger.error(error); Logger.error(error);
res.sendStatus(500); return res.sendStatus(500);
return;
} }
try { try {
@ -77,11 +73,9 @@ export async function setUsername(req: Request, res: Response) {
await logUserNameChange(userID, userName, oldUserName, adminUserIDInput !== undefined); await logUserNameChange(userID, userName, oldUserName, adminUserIDInput !== undefined);
res.sendStatus(200); return res.sendStatus(200);
} catch (err) { } catch (err) {
Logger.error(err); Logger.error(err);
res.sendStatus(500); return res.sendStatus(500);
return;
} }
} }

View file

@ -6,7 +6,7 @@ import { Category, Service, VideoID, VideoIDHash } from '../types/segments.model
import { UserID } from '../types/user.model'; import { UserID } from '../types/user.model';
import { QueryCacher } from '../utils/queryCacher'; import { QueryCacher } from '../utils/queryCacher';
export async function shadowBanUser(req: Request, res: Response) { export async function shadowBanUser(req: Request, res: Response): Promise<Response> {
const userID = req.query.userID as string; const userID = req.query.userID as string;
const hashedIP = req.query.hashedIP as string; const hashedIP = req.query.hashedIP as string;
let adminUserIDInput = req.query.adminUserID as string; let adminUserIDInput = req.query.adminUserID as string;
@ -23,8 +23,7 @@ export async function shadowBanUser(req: Request, res: Response) {
if (adminUserIDInput == undefined || (userID == undefined && hashedIP == undefined)) { if (adminUserIDInput == undefined || (userID == undefined && hashedIP == undefined)) {
//invalid request //invalid request
res.sendStatus(400); return res.sendStatus(400);
return;
} }
//hash the userID //hash the userID
@ -33,8 +32,7 @@ export async function shadowBanUser(req: Request, res: Response) {
const isVIP = (await db.prepare("get", `SELECT count(*) as "userCount" FROM "vipUsers" WHERE "userID" = ?`, [adminUserIDInput])).userCount > 0; const isVIP = (await db.prepare("get", `SELECT count(*) as "userCount" FROM "vipUsers" WHERE "userID" = ?`, [adminUserIDInput])).userCount > 0;
if (!isVIP) { if (!isVIP) {
//not authorized //not authorized
res.sendStatus(403); return res.sendStatus(403);
return;
} }
if (userID) { if (userID) {
@ -66,10 +64,10 @@ export async function shadowBanUser(req: Request, res: Response) {
//find all previous submissions and unhide them //find all previous submissions and unhide them
if (unHideOldSubmissions) { if (unHideOldSubmissions) {
let segmentsToIgnore = (await db.prepare('all', `SELECT "UUID" FROM "sponsorTimes" st const segmentsToIgnore = (await db.prepare('all', `SELECT "UUID" FROM "sponsorTimes" st
JOIN "lockCategories" ns on "st"."videoID" = "ns"."videoID" AND st.category = ns.category WHERE "st"."userID" = ?` JOIN "lockCategories" ns on "st"."videoID" = "ns"."videoID" AND st.category = ns.category WHERE "st"."userID" = ?`
, [userID])).map((item: {UUID: string}) => item.UUID); , [userID])).map((item: {UUID: string}) => item.UUID);
let allSegments = (await db.prepare('all', `SELECT "UUID" FROM "sponsorTimes" st WHERE "st"."userID" = ?`, [userID])) const allSegments = (await db.prepare('all', `SELECT "UUID" FROM "sponsorTimes" st WHERE "st"."userID" = ?`, [userID]))
.map((item: {UUID: string}) => item.UUID); .map((item: {UUID: string}) => item.UUID);
await Promise.all(allSegments.filter((item: {uuid: string}) => { await Promise.all(allSegments.filter((item: {uuid: string}) => {
@ -114,6 +112,5 @@ export async function shadowBanUser(req: Request, res: Response) {
// } // }
}*/ }*/
} }
return res.sendStatus(200);
res.sendStatus(200);
} }

View file

@ -2,7 +2,7 @@ import {db} from '../databases/databases';
import {Request, Response} from 'express'; import {Request, Response} from 'express';
export async function viewedVideoSponsorTime(req: Request, res: Response): Promise<Response> { export async function viewedVideoSponsorTime(req: Request, res: Response): Promise<Response> {
let UUID = req.query.UUID; const UUID = req.query.UUID;
if (UUID == undefined) { if (UUID == undefined) {
//invalid request //invalid request

View file

@ -161,31 +161,27 @@ async function sendWebhooks(voteData: VoteData) {
} }
async function categoryVote(UUID: SegmentUUID, userID: UserID, isVIP: boolean, isOwnSubmission: boolean, category: Category async function categoryVote(UUID: SegmentUUID, userID: UserID, isVIP: boolean, isOwnSubmission: boolean, category: Category
, hashedIP: HashedIP, finalResponse: FinalResponse, res: Response) { , hashedIP: HashedIP, finalResponse: FinalResponse, res: Response): Promise<Response> {
// Check if they've already made a vote // Check if they've already made a vote
const usersLastVoteInfo = await privateDB.prepare('get', `select count(*) as votes, category from "categoryVotes" where "UUID" = ? and "userID" = ? group by category`, [UUID, userID]); const usersLastVoteInfo = await privateDB.prepare('get', `select count(*) as votes, category from "categoryVotes" where "UUID" = ? and "userID" = ? group by category`, [UUID, userID]);
if (usersLastVoteInfo?.category === category) { if (usersLastVoteInfo?.category === category) {
// Double vote, ignore // Double vote, ignore
res.sendStatus(finalResponse.finalStatus); return res.sendStatus(finalResponse.finalStatus);
return;
} }
const videoInfo = (await db.prepare('get', `SELECT "category", "videoID", "hashedVideoID", "service", "userID" FROM "sponsorTimes" WHERE "UUID" = ?`, const videoInfo = (await db.prepare('get', `SELECT "category", "videoID", "hashedVideoID", "service", "userID" FROM "sponsorTimes" WHERE "UUID" = ?`,
[UUID])) as {category: Category, videoID: VideoID, hashedVideoID: VideoIDHash, service: Service, userID: UserID}; [UUID])) as {category: Category, videoID: VideoID, hashedVideoID: VideoIDHash, service: Service, userID: UserID};
if (!videoInfo) { if (!videoInfo) {
// Submission doesn't exist // Submission doesn't exist
res.status(400).send("Submission doesn't exist."); return res.status(400).send("Submission doesn't exist.");
return;
} }
if (!config.categoryList.includes(category)) { if (!config.categoryList.includes(category)) {
res.status(400).send("Category doesn't exist."); return res.status(400).send("Category doesn't exist.");
return;
} }
if (getCategoryActionType(category) !== CategoryActionType.Skippable) { if (getCategoryActionType(category) !== CategoryActionType.Skippable) {
res.status(400).send("Cannot vote for this category"); return res.status(400).send("Cannot vote for this category");
return;
} }
const nextCategoryInfo = await db.prepare("get", `select votes from "categoryVotes" where "UUID" = ? and category = ?`, [UUID, category]); const nextCategoryInfo = await db.prepare("get", `select votes from "categoryVotes" where "UUID" = ? and category = ?`, [UUID, category]);
@ -245,14 +241,14 @@ async function categoryVote(UUID: SegmentUUID, userID: UserID, isVIP: boolean, i
QueryCacher.clearVideoCache(videoInfo); QueryCacher.clearVideoCache(videoInfo);
res.sendStatus(finalResponse.finalStatus); return res.sendStatus(finalResponse.finalStatus);
} }
export function getUserID(req: Request): UserID { export function getUserID(req: Request): UserID {
return req.query.userID as UserID; return req.query.userID as UserID;
} }
export async function voteOnSponsorTime(req: Request, res: Response) { export async function voteOnSponsorTime(req: Request, res: Response): Promise<Response> {
const UUID = req.query.UUID as SegmentUUID; const UUID = req.query.UUID as SegmentUUID;
const paramUserID = getUserID(req); const paramUserID = getUserID(req);
let type = req.query.type !== undefined ? parseInt(req.query.type as string) : undefined; let type = req.query.type !== undefined ? parseInt(req.query.type as string) : undefined;
@ -260,8 +256,7 @@ export async function voteOnSponsorTime(req: Request, res: Response) {
if (UUID === undefined || paramUserID === undefined || (type === undefined && category === undefined)) { if (UUID === undefined || paramUserID === undefined || (type === undefined && category === undefined)) {
//invalid request //invalid request
res.sendStatus(400); return res.sendStatus(400);
return;
} }
//hash the userID //hash the userID
@ -269,13 +264,13 @@ export async function voteOnSponsorTime(req: Request, res: Response) {
const userID = getHash(paramUserID + UUID); const userID = getHash(paramUserID + UUID);
// To force a non 200, change this early // To force a non 200, change this early
let finalResponse: FinalResponse = { const finalResponse: FinalResponse = {
blockVote: false, blockVote: false,
finalStatus: 200, finalStatus: 200,
finalMessage: null, finalMessage: null,
webhookType: VoteWebhookType.Normal, webhookType: VoteWebhookType.Normal,
webhookMessage: null webhookMessage: null
} };
//x-forwarded-for if this server is behind a proxy //x-forwarded-for if this server is behind a proxy
const ip = getIP(req); const ip = getIP(req);
@ -292,8 +287,7 @@ export async function voteOnSponsorTime(req: Request, res: Response) {
// disallow vote types 10/11 // disallow vote types 10/11
if (type === 10 || type === 11) { if (type === 10 || type === 11) {
// no longer allow type 10/11 alternative votes // no longer allow type 10/11 alternative votes
res.sendStatus(400) return res.sendStatus(400);
return;
} }
// If not upvote // If not upvote
@ -305,8 +299,8 @@ export async function voteOnSponsorTime(req: Request, res: Response) {
if (await isSegmentLocked() || await isVideoLocked()) { if (await isSegmentLocked() || await isVideoLocked()) {
finalResponse.blockVote = true; finalResponse.blockVote = true;
finalResponse.webhookType = VoteWebhookType.Rejected finalResponse.webhookType = VoteWebhookType.Rejected;
finalResponse.webhookMessage = "Vote rejected: A moderator has decided that this segment is correct" finalResponse.webhookMessage = "Vote rejected: A moderator has decided that this segment is correct";
} }
} }
@ -320,12 +314,10 @@ export async function voteOnSponsorTime(req: Request, res: Response) {
if (voteInfo && voteInfo.votes <= -2) { if (voteInfo && voteInfo.votes <= -2) {
if (type == 1) { if (type == 1) {
res.status(403).send("Not allowed to upvote segment with too many downvotes unless you are VIP."); return res.status(403).send("Not allowed to upvote segment with too many downvotes unless you are VIP.");
return;
} else if (type == 0) { } else if (type == 0) {
// Already downvoted enough, ignore // Already downvoted enough, ignore
res.status(200).send(); return res.sendStatus(200);
return;
} }
} }
} }
@ -361,8 +353,7 @@ export async function voteOnSponsorTime(req: Request, res: Response) {
incrementAmount = 0; incrementAmount = 0;
} else { } else {
//unrecongnised type of vote //unrecongnised type of vote
res.sendStatus(400); return res.sendStatus(400);
return;
} }
if (votesRow != undefined) { if (votesRow != undefined) {
if (votesRow.type === 1) { if (votesRow.type === 1) {
@ -444,9 +435,6 @@ export async function voteOnSponsorTime(req: Request, res: Response) {
QueryCacher.clearVideoCache(videoInfo); QueryCacher.clearVideoCache(videoInfo);
} }
res.status(finalResponse.finalStatus).send(finalResponse.finalMessage ?? undefined);
if (incrementAmount - oldIncrementAmount !== 0) { if (incrementAmount - oldIncrementAmount !== 0) {
sendWebhooks({ sendWebhooks({
UUID, UUID,
@ -461,9 +449,9 @@ export async function voteOnSponsorTime(req: Request, res: Response) {
finalResponse finalResponse
}); });
} }
return res.status(finalResponse.finalStatus).send(finalResponse.finalMessage ?? undefined);
} catch (err) { } catch (err) {
Logger.error(err); Logger.error(err);
return res.status(500).json({error: 'Internal error creating segment vote'});
res.status(500).json({error: 'Internal error creating segment vote'});
} }
} }

View file

@ -10,22 +10,22 @@ if (config.diskCache) {
DiskCache = { DiskCache = {
// constructor(rootPath, options): {}; // constructor(rootPath, options): {};
init() {}, init(): void { return; },
reset() {}, reset(): void { return; },
has(key) { return false; }, has(key: string): boolean { return false; },
get(key, opts) { return null; }, get(key: string, opts): string { return null; },
// Returns size // Returns size
set(key, dataOrSteam) { return new Promise((resolve) => 0); }, set(key: string, dataOrSteam): Promise<number> { return new Promise(() => 0); },
del(key) {}, del(key: string): void { return; },
size() { return 0; }, size(): number { return 0; },
prune() {}, prune(): void {return; },
}; };
} }

View file

@ -1,9 +1,9 @@
/** /**
* Converts time in seconds to minutes:seconds * Converts time in seconds to minutes:seconds
*/ */
export function getFormattedTime(totalSeconds: number) { export function getFormattedTime(totalSeconds: number): string {
let minutes = Math.floor(totalSeconds / 60); const minutes = Math.floor(totalSeconds / 60);
let seconds = totalSeconds - minutes * 60; const seconds = totalSeconds - minutes * 60;
let secondsDisplay = seconds.toFixed(3); let secondsDisplay = seconds.toFixed(3);
if (seconds < 10) { if (seconds < 10) {
//add a zero //add a zero

View file

@ -5,7 +5,7 @@ export function getHash<T extends string>(value: T, times = 5000): T & HashedVal
if (times <= 0) return "" as T & HashedValue; if (times <= 0) return "" as T & HashedValue;
for (let i = 0; i < times; i++) { for (let i = 0; i < times; i++) {
let hashCreator = crypto.createHash('sha256'); const hashCreator = crypto.createHash('sha256');
value = hashCreator.update(value).digest('hex') as T; value = hashCreator.update(value).digest('hex') as T;
} }

View file

@ -1,5 +1,6 @@
import {getHash} from './getHash'; import {getHash} from './getHash';
import { HashedValue } from '../types/hash.model';
export function getSubmissionUUID(videoID: string, category: string, userID: string, startTime: number, endTime: number) { export function getSubmissionUUID(videoID: string, category: string, userID: string, startTime: number, endTime: number): HashedValue{
return getHash('v2-categories' + videoID + startTime + endTime + category + userID, 1); return getHash('v2-categories' + videoID + startTime + endTime + category + userID, 1);
} }

View file

@ -86,4 +86,4 @@ class Logger {
const loggerInstance = new Logger(); const loggerInstance = new Logger();
export { export {
loggerInstance as Logger loggerInstance as Logger
} };

View file

@ -22,7 +22,7 @@ async function get<T>(fetchFromDB: () => Promise<T>, key: string): Promise<T> {
return data; return data;
} }
function clearVideoCache(videoInfo: { videoID: VideoID; hashedVideoID: VideoIDHash; service: Service; userID?: UserID; }) { function clearVideoCache(videoInfo: { videoID: VideoID; hashedVideoID: VideoIDHash; service: Service; userID?: UserID; }): void {
if (videoInfo) { if (videoInfo) {
redis.delAsync(skipSegmentsKey(videoInfo.videoID, videoInfo.service)); redis.delAsync(skipSegmentsKey(videoInfo.videoID, videoInfo.service));
redis.delAsync(skipSegmentsHashKey(videoInfo.hashedVideoID, videoInfo.service)); redis.delAsync(skipSegmentsHashKey(videoInfo.hashedVideoID, videoInfo.service));
@ -33,4 +33,4 @@ function clearVideoCache(videoInfo: { videoID: VideoID; hashedVideoID: VideoIDHa
export const QueryCacher = { export const QueryCacher = {
get, get,
clearVideoCache clearVideoCache
} };

View file

@ -12,12 +12,12 @@ interface RedisSB {
let exportObject: RedisSB = { let exportObject: RedisSB = {
get: (key, callback?) => callback(null, undefined), get: (key, callback?) => callback(null, undefined),
getAsync: (key) => getAsync: () =>
new Promise((resolve) => resolve({err: null, reply: undefined})), new Promise((resolve) => resolve({err: null, reply: undefined})),
set: (key, value, callback) => callback(null, undefined), set: (key, value, callback) => callback(null, undefined),
setAsync: (key, value) => setAsync: () =>
new Promise((resolve) => resolve({err: null, reply: undefined})), new Promise((resolve) => resolve({err: null, reply: undefined})),
delAsync: (...keys) => delAsync: () =>
new Promise((resolve) => resolve(null)), new Promise((resolve) => resolve(null)),
}; };

View file

@ -1,7 +1,6 @@
import {config} from '../config'; import {config} from '../config';
import {Logger} from '../utils/logger'; import {Logger} from '../utils/logger';
import fetch from 'node-fetch'; import fetch from 'node-fetch';
import AbortController from "abort-controller";
function getVoteAuthorRaw(submissionCount: number, isVIP: boolean, isOwnSubmission: boolean): string { function getVoteAuthorRaw(submissionCount: number, isVIP: boolean, isOwnSubmission: boolean): string {
if (isOwnSubmission) { if (isOwnSubmission) {
@ -27,15 +26,15 @@ function getVoteAuthor(submissionCount: number, isVIP: boolean, isOwnSubmission:
return ""; return "";
} }
function dispatchEvent(scope: string, data: any): void { function dispatchEvent(scope: string, data: Record<string, unknown>): void {
let webhooks = config.webhooks; const webhooks = config.webhooks;
if (webhooks === undefined || webhooks.length === 0) return; if (webhooks === undefined || webhooks.length === 0) return;
Logger.debug("Dispatching webhooks"); Logger.debug("Dispatching webhooks");
for (const webhook of webhooks) { for (const webhook of webhooks) {
let webhookURL = webhook.url; const webhookURL = webhook.url;
let authKey = webhook.key; const authKey = webhook.key;
let scopes = webhook.scopes || []; const scopes = webhook.scopes || [];
if (!scopes.includes(scope.toLowerCase())) return; if (!scopes.includes(scope.toLowerCase())) return;
fetch(webhookURL, { fetch(webhookURL, {

View file

@ -17,10 +17,10 @@ export class YouTubeAPI {
if (data) { if (data) {
Logger.debug("YouTube API: cache used for video information: " + videoID); Logger.debug("YouTube API: cache used for video information: " + videoID);
return { err: null, data: JSON.parse(data) } return { err: null, data: JSON.parse(data) };
} }
} catch (err) { } catch (err) {
return { err } return { err };
} }
} }
@ -32,7 +32,7 @@ export class YouTubeAPI {
if (result.ok) { if (result.ok) {
const data = await result.json(); const data = await result.json();
if (data.error) { if (data.error) {
Logger.warn("NewLeaf API Error for " + videoID + ": " + data.error) Logger.warn("NewLeaf API Error for " + videoID + ": " + data.error);
return { err: data.error, data: null }; return { err: data.error, data: null };
} }
@ -45,7 +45,7 @@ export class YouTubeAPI {
return { err: result.statusText, data: null }; return { err: result.statusText, data: null };
} }
} catch (err) { } catch (err) {
return {err, data: null} return {err, data: null};
} }
} }
} }

View file

@ -1,10 +1,9 @@
import {db, privateDB} from '../../src/databases/databases'; import {db, privateDB} from '../../src/databases/databases';
import {Done} from '../utils';
describe('dbUpgrade', () => { describe('dbUpgrade', () => {
it('Should update the database version when starting the application', async () => { it('Should update the database version when starting the application', async () => {
let dbVersion = (await db.prepare('get', 'SELECT key, value FROM config where key = ?', ['version'])).value; const dbVersion = (await db.prepare('get', 'SELECT key, value FROM config where key = ?', ['version'])).value;
let privateVersion = (await privateDB.prepare('get', 'SELECT key, value FROM config where key = ?', ['version'])).value; const privateVersion = (await privateDB.prepare('get', 'SELECT key, value FROM config where key = ?', ['version'])).value;
if (dbVersion >= 1 && privateVersion >= 1) return; if (dbVersion >= 1 && privateVersion >= 1) return;
else return 'Versions are not at least 1. db is ' + dbVersion + ', private is ' + privateVersion; else return 'Versions are not at least 1. db is ' + dbVersion + ', private is ' + privateVersion;
}); });

View file

@ -14,7 +14,7 @@ describe('getIsUserVIP', () => {
if (res.status !== 200) done("non 200: " + res.status); if (res.status !== 200) done("non 200: " + res.status);
else done(); // pass else done(); // pass
}) })
.catch(err => done("couldn't call endpoint")); .catch(() => done("couldn't call endpoint"));
}); });
@ -24,7 +24,7 @@ describe('getIsUserVIP', () => {
if (res.status !== 400) done("non 400: " + res.status); if (res.status !== 400) done("non 400: " + res.status);
else done(); // pass else done(); // pass
}) })
.catch(err => done("couldn't call endpoint")); .catch(() => done("couldn't call endpoint"));
}); });
it('Should say a VIP is a VIP', (done: Done) => { it('Should say a VIP is a VIP', (done: Done) => {
@ -37,7 +37,7 @@ describe('getIsUserVIP', () => {
else done("Result was non-vip when should have been vip"); else done("Result was non-vip when should have been vip");
} }
}) })
.catch(err => done("couldn't call endpoint")); .catch(() => done("couldn't call endpoint"));
}); });
it('Should say a normal user is not a VIP', (done: Done) => { it('Should say a normal user is not a VIP', (done: Done) => {
@ -50,6 +50,6 @@ describe('getIsUserVIP', () => {
else done("Result was vip when should have been non-vip"); else done("Result was vip when should have been non-vip");
} }
}) })
.catch(err => done("couldn't call endpoint")); .catch(() => done("couldn't call endpoint"));
}); });
}); });

View file

@ -5,7 +5,7 @@ import {getHash} from '../../src/utils/getHash';
describe('getSavedTimeForUser', () => { describe('getSavedTimeForUser', () => {
before(async () => { before(async () => {
let startOfQuery = 'INSERT INTO "sponsorTimes" ("videoID", "startTime", "endTime", "votes", "UUID", "userID", "timeSubmitted", views, category, "shadowHidden", "hashedVideoID") VALUES'; const startOfQuery = 'INSERT INTO "sponsorTimes" ("videoID", "startTime", "endTime", "votes", "UUID", "userID", "timeSubmitted", views, category, "shadowHidden", "hashedVideoID") VALUES';
await db.prepare("run", startOfQuery + "(?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)", await db.prepare("run", startOfQuery + "(?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)",
['getSavedTimeForUser', 1, 11, 2, 'abc1239999', getHash("testman"), 0, 50, 'sponsor', 0, getHash('getSavedTimeForUser', 0)]); ['getSavedTimeForUser', 1, 11, 2, 'abc1239999', getHash("testman"), 0, 50, 'sponsor', 0, getHash('getSavedTimeForUser', 0)]);
return; return;
@ -17,6 +17,6 @@ describe('getSavedTimeForUser', () => {
if (res.status !== 200) done("non 200"); if (res.status !== 200) done("non 200");
else done(); // pass else done(); // pass
}) })
.catch(err => done("couldn't call endpoint")); .catch(() => done("couldn't call endpoint"));
}); });
}); });

View file

@ -20,7 +20,7 @@ const oldID = `${'0'.repeat(8)}-${'0000-'.repeat(3)}${'0'.repeat(12)}`
describe('getSegmentInfo', () => { describe('getSegmentInfo', () => {
before(async () => { before(async () => {
let insertQuery = `INSERT INTO const insertQuery = `INSERT INTO
"sponsorTimes"("videoID", "startTime", "endTime", "votes", "locked", "sponsorTimes"("videoID", "startTime", "endTime", "votes", "locked",
"UUID", "userID", "timeSubmitted", "views", "category", "service", "UUID", "userID", "timeSubmitted", "views", "category", "service",
"videoDuration", "hidden", "shadowHidden", "hashedVideoID") "videoDuration", "hidden", "shadowHidden", "hashedVideoID")
@ -53,7 +53,7 @@ describe('getSegmentInfo', () => {
} }
} }
}) })
.catch(err => "Couldn't call endpoint"); .catch(() => "Couldn't call endpoint");
}); });
it('Should be able to retreive downvoted segment', (done: Done) => { it('Should be able to retreive downvoted segment', (done: Done) => {
@ -69,7 +69,7 @@ describe('getSegmentInfo', () => {
} }
} }
}) })
.catch(err => "Couldn't call endpoint"); .catch(() => "Couldn't call endpoint");
}); });
it('Should be able to retreive locked up segment', (done: Done) => { it('Should be able to retreive locked up segment', (done: Done) => {
@ -85,7 +85,7 @@ describe('getSegmentInfo', () => {
} }
} }
}) })
.catch(err => "Couldn't call endpoint"); .catch(() => "Couldn't call endpoint");
}); });
it('Should be able to retreive infinite vote segment', (done: Done) => { it('Should be able to retreive infinite vote segment', (done: Done) => {
@ -101,7 +101,7 @@ describe('getSegmentInfo', () => {
} }
} }
}) })
.catch(err => "Couldn't call endpoint"); .catch(() => "Couldn't call endpoint");
}); });
it('Should be able to retreive shadowhidden segment', (done: Done) => { it('Should be able to retreive shadowhidden segment', (done: Done) => {
@ -117,7 +117,7 @@ describe('getSegmentInfo', () => {
} }
} }
}) })
.catch(err => "Couldn't call endpoint"); .catch(() => "Couldn't call endpoint");
}); });
it('Should be able to retreive locked down segment', (done: Done) => { it('Should be able to retreive locked down segment', (done: Done) => {
@ -133,7 +133,7 @@ describe('getSegmentInfo', () => {
} }
} }
}) })
.catch(err => "Couldn't call endpoint"); .catch(() => "Couldn't call endpoint");
}); });
it('Should be able to retreive hidden segment', (done: Done) => { it('Should be able to retreive hidden segment', (done: Done) => {
@ -149,7 +149,7 @@ describe('getSegmentInfo', () => {
} }
} }
}) })
.catch(err => "Couldn't call endpoint"); .catch(() => "Couldn't call endpoint");
}); });
it('Should be able to retreive segment with old ID', (done: Done) => { it('Should be able to retreive segment with old ID', (done: Done) => {
@ -165,7 +165,7 @@ describe('getSegmentInfo', () => {
} }
} }
}) })
.catch(err => "Couldn't call endpoint"); .catch(() => "Couldn't call endpoint");
}); });
it('Should be able to retreive single segment in array', (done: Done) => { it('Should be able to retreive single segment in array', (done: Done) => {
@ -181,7 +181,7 @@ describe('getSegmentInfo', () => {
} }
} }
}) })
.catch(err => "Couldn't call endpoint"); .catch(() => "Couldn't call endpoint");
}); });
it('Should be able to retreive multiple segments in array', (done: Done) => { it('Should be able to retreive multiple segments in array', (done: Done) => {
@ -199,7 +199,7 @@ describe('getSegmentInfo', () => {
} }
} }
}) })
.catch(err => "Couldn't call endpoint"); .catch(() => "Couldn't call endpoint");
}); });
it('Should be possible to send unexpected query parameters', (done: Done) => { it('Should be possible to send unexpected query parameters', (done: Done) => {
@ -215,7 +215,7 @@ describe('getSegmentInfo', () => {
} }
} }
}) })
.catch(err => "Couldn't call endpoint"); .catch(() => "Couldn't call endpoint");
}); });
it('Should return 400 if array passed to UUID', (done: Done) => { it('Should return 400 if array passed to UUID', (done: Done) => {
@ -224,7 +224,7 @@ describe('getSegmentInfo', () => {
if (res.status !== 400) done("non 400 respone code: " + res.status); if (res.status !== 400) done("non 400 respone code: " + res.status);
else done(); // pass else done(); // pass
}) })
.catch(err => ("couldn't call endpoint")); .catch(() => ("couldn't call endpoint"));
}); });
it('Should return 400 if bad array passed to UUIDs', (done: Done) => { it('Should return 400 if bad array passed to UUIDs', (done: Done) => {
@ -233,7 +233,7 @@ describe('getSegmentInfo', () => {
if (res.status !== 400) done("non 404 respone code: " + res.status); if (res.status !== 400) done("non 404 respone code: " + res.status);
else done(); // pass else done(); // pass
}) })
.catch(err => ("couldn't call endpoint")); .catch(() => ("couldn't call endpoint"));
}); });
it('Should return 400 if bad UUID passed', (done: Done) => { it('Should return 400 if bad UUID passed', (done: Done) => {
@ -242,7 +242,7 @@ describe('getSegmentInfo', () => {
if (res.status !== 400) done("non 400 respone code: " + res.status); if (res.status !== 400) done("non 400 respone code: " + res.status);
else done(); // pass else done(); // pass
}) })
.catch(err => ("couldn't call endpoint")); .catch(() => ("couldn't call endpoint"));
}); });
it('Should return 400 if bad UUIDs passed in array', (done: Done) => { it('Should return 400 if bad UUIDs passed in array', (done: Done) => {
@ -251,7 +251,7 @@ describe('getSegmentInfo', () => {
if (res.status !== 400) done("non 400 respone code: " + res.status); if (res.status !== 400) done("non 400 respone code: " + res.status);
else done(); // pass else done(); // pass
}) })
.catch(err => ("couldn't call endpoint")); .catch(() => ("couldn't call endpoint"));
}); });
it('Should return good UUID when mixed with bad UUIDs', (done: Done) => { it('Should return good UUID when mixed with bad UUIDs', (done: Done) => {
@ -267,7 +267,7 @@ describe('getSegmentInfo', () => {
} }
} }
}) })
.catch(err => ("couldn't call endpoint")); .catch(() => ("couldn't call endpoint"));
}); });
it('Should cut off array at 10', function(done: Done) { it('Should cut off array at 10', function(done: Done) {
@ -286,7 +286,7 @@ describe('getSegmentInfo', () => {
} }
} }
}) })
.catch(err => ("couldn't call endpoint")); .catch(() => ("couldn't call endpoint"));
}); });
it('Should not duplicate reponses', (done: Done) => { it('Should not duplicate reponses', (done: Done) => {
@ -302,7 +302,7 @@ describe('getSegmentInfo', () => {
} }
} }
}) })
.catch(err => ("couldn't call endpoint")); .catch(() => ("couldn't call endpoint"));
}); });
it('Should return 400 if UUID not found', (done: Done) => { it('Should return 400 if UUID not found', (done: Done) => {
@ -311,7 +311,7 @@ describe('getSegmentInfo', () => {
if (res.status !== 400) done("non 400 respone code: " + res.status); if (res.status !== 400) done("non 400 respone code: " + res.status);
else done(); // pass else done(); // pass
}) })
.catch(err => ("couldn't call endpoint")); .catch(() => ("couldn't call endpoint"));
}); });
it('Should be able to retreive multiple segments with multiple parameters', (done: Done) => { it('Should be able to retreive multiple segments with multiple parameters', (done: Done) => {
@ -329,11 +329,11 @@ describe('getSegmentInfo', () => {
} }
} }
}) })
.catch(err => "Couldn't call endpoint"); .catch(() => "Couldn't call endpoint");
}); });
it('Should not parse repeated UUID if UUIDs present', (done: Done) => { it('Should not parse repeated UUID if UUIDs present', (done: Done) => {
fetch(getbaseURL() + `/api/segmentInfo?UUID=${downvotedID}&UUID=${lockedupID}&UUIDs=[\"${upvotedID}\"]`) fetch(getbaseURL() + `/api/segmentInfo?UUID=${downvotedID}&UUID=${lockedupID}&UUIDs=["${upvotedID}"]`)
.then(async res => { .then(async res => {
if (res.status !== 200) done("Status code was: " + res.status); if (res.status !== 200) done("Status code was: " + res.status);
else { else {
@ -346,6 +346,6 @@ describe('getSegmentInfo', () => {
} }
} }
}) })
.catch(err => "Couldn't call endpoint"); .catch(() => "Couldn't call endpoint");
}); });
}); });

View file

@ -39,7 +39,7 @@ describe('getSkipSegments', () => {
} }
} }
}) })
.catch(err => "Couldn't call endpoint"); .catch(() => "Couldn't call endpoint");
}); });
it('Should be able to get a time by category for a different service 1', (done: Done) => { it('Should be able to get a time by category for a different service 1', (done: Done) => {
@ -56,7 +56,7 @@ describe('getSkipSegments', () => {
} }
} }
}) })
.catch(err => "Couldn't call endpoint"); .catch(() => "Couldn't call endpoint");
}); });
it('Should be able to get a time by category 2', (done: Done) => { it('Should be able to get a time by category 2', (done: Done) => {
@ -73,7 +73,7 @@ describe('getSkipSegments', () => {
} }
} }
}) })
.catch(err => ("Couldn't call endpoint")); .catch(() => ("Couldn't call endpoint"));
}); });
it('Should be able to get a time by categories array', (done: Done) => { it('Should be able to get a time by categories array', (done: Done) => {
@ -90,7 +90,7 @@ describe('getSkipSegments', () => {
} }
} }
}) })
.catch(err => ("Couldn't call endpoint")); .catch(() => ("Couldn't call endpoint"));
}); });
it('Should be able to get a time by categories array 2', (done: Done) => { it('Should be able to get a time by categories array 2', (done: Done) => {
@ -107,7 +107,7 @@ describe('getSkipSegments', () => {
} }
} }
}) })
.catch(err => ("Couldn't call endpoint")); .catch(() => ("Couldn't call endpoint"));
}); });
it('Should return 404 if all submissions are hidden', (done: Done) => { it('Should return 404 if all submissions are hidden', (done: Done) => {
@ -116,7 +116,7 @@ describe('getSkipSegments', () => {
if (res.status !== 404) done("non 404 respone code: " + res.status); if (res.status !== 404) done("non 404 respone code: " + res.status);
else done(); // pass else done(); // pass
}) })
.catch(err => ("Couldn't call endpoint")); .catch(() => ("Couldn't call endpoint"));
}); });
it('Should be able to get multiple times by category', (done: Done) => { it('Should be able to get multiple times by category', (done: Done) => {
@ -175,7 +175,7 @@ describe('getSkipSegments', () => {
} }
} }
}) })
.catch(err => ("Couldn't call endpoint")); .catch(() => ("Couldn't call endpoint"));
}); });
it('Should be possible to send unexpected query parameters', (done: Done) => { it('Should be possible to send unexpected query parameters', (done: Done) => {
@ -193,7 +193,7 @@ describe('getSkipSegments', () => {
} }
} }
}) })
.catch(err => done("Couldn't call endpoint")); .catch(() => done("Couldn't call endpoint"));
}); });
it('Low voted submissions should be hidden', (done: Done) => { it('Low voted submissions should be hidden', (done: Done) => {
@ -211,7 +211,7 @@ describe('getSkipSegments', () => {
} }
} }
}) })
.catch(err => ("Couldn't call endpoint")); .catch(() => ("Couldn't call endpoint"));
}); });
it('Should return 404 if no segment found', (done: Done) => { it('Should return 404 if no segment found', (done: Done) => {
@ -220,7 +220,7 @@ describe('getSkipSegments', () => {
if (res.status !== 404) done("non 404 respone code: " + res.status); if (res.status !== 404) done("non 404 respone code: " + res.status);
else done(); // pass else done(); // pass
}) })
.catch(err => ("couldn't call endpoint")); .catch(() => ("couldn't call endpoint"));
}); });
it('Should return 400 if bad categories argument', (done: Done) => { it('Should return 400 if bad categories argument', (done: Done) => {
@ -229,7 +229,7 @@ describe('getSkipSegments', () => {
if (res.status !== 400) done("non 400 respone code: " + res.status); if (res.status !== 400) done("non 400 respone code: " + res.status);
else done(); // pass else done(); // pass
}) })
.catch(err => ("couldn't call endpoint")); .catch(() => ("couldn't call endpoint"));
}); });
it('Should be able send a comma in a query param', (done: Done) => { it('Should be able send a comma in a query param', (done: Done) => {
@ -247,7 +247,7 @@ describe('getSkipSegments', () => {
} }
} }
}) })
.catch(err => ("Couldn't call endpoint")); .catch(() => ("Couldn't call endpoint"));
}); });
it('Should always get locked segment', (done: Done) => { it('Should always get locked segment', (done: Done) => {
@ -264,7 +264,7 @@ describe('getSkipSegments', () => {
} }
} }
}) })
.catch(err => ("Couldn't call endpoint")); .catch(() => ("Couldn't call endpoint"));
}); });
it('Should be able to get multiple categories with repeating parameters', (done: Done) => { it('Should be able to get multiple categories with repeating parameters', (done: Done) => {
@ -294,7 +294,7 @@ describe('getSkipSegments', () => {
} }
} }
}) })
.catch(err => ("Couldn't call endpoint")); .catch(() => ("Couldn't call endpoint"));
}); });
it('Should be able to get, categories param overriding repeating category', (done: Done) => { it('Should be able to get, categories param overriding repeating category', (done: Done) => {
@ -311,7 +311,7 @@ describe('getSkipSegments', () => {
} }
} }
}) })
.catch(err => ("Couldn't call endpoint")); .catch(() => ("Couldn't call endpoint"));
}); });
it('Should be able to get specific segments with requiredSegments', (done: Done) => { it('Should be able to get specific segments with requiredSegments', (done: Done) => {

View file

@ -33,7 +33,7 @@ describe('getSegmentsByHash', () => {
if (res.status !== 200) done("non 200 status code, was " + res.status); if (res.status !== 200) done("non 200 status code, was " + res.status);
else done(); // pass else done(); // pass
}) })
.catch(err => done("Couldn't call endpoint")); .catch(() => done("Couldn't call endpoint"));
}); });
it('Should return 404 if no segments are found even if a video for the given hash is known', (done: Done) => { it('Should return 404 if no segments are found even if a video for the given hash is known', (done: Done) => {
@ -46,7 +46,7 @@ describe('getSegmentsByHash', () => {
else done("Response had videos"); else done("Response had videos");
} }
}) })
.catch(err => done("Couldn't call endpoint")); .catch(() => done("Couldn't call endpoint"));
}); });
it('Should be able to get an empty array if no videos', (done: Done) => { it('Should be able to get an empty array if no videos', (done: Done) => {
@ -59,7 +59,7 @@ describe('getSegmentsByHash', () => {
else done("non empty array returned"); else done("non empty array returned");
} }
}) })
.catch(err => done("Couldn't call endpoint")); .catch(() => done("Couldn't call endpoint"));
}); });
it('Should be able to get an empty array if only hidden videos', (done: Done) => { it('Should be able to get an empty array if only hidden videos', (done: Done) => {
@ -72,7 +72,7 @@ describe('getSegmentsByHash', () => {
else done("non empty array returned"); else done("non empty array returned");
} }
}) })
.catch(err => done("Couldn't call endpoint")); .catch(() => done("Couldn't call endpoint"));
}); });
it('Should return 400 prefix too short', (done: Done) => { it('Should return 400 prefix too short', (done: Done) => {
@ -81,11 +81,11 @@ describe('getSegmentsByHash', () => {
if (res.status !== 400) done("non 400 status code, was " + res.status); if (res.status !== 400) done("non 400 status code, was " + res.status);
else done(); // pass else done(); // pass
}) })
.catch(err => done("Couldn't call endpoint")); .catch(() => done("Couldn't call endpoint"));
}); });
it('Should return 400 prefix too long', (done: Done) => { it('Should return 400 prefix too long', (done: Done) => {
let prefix = new Array(50).join('1'); const prefix = new Array(50).join('1');
if (prefix.length <= 32) { // default value, config can change this if (prefix.length <= 32) { // default value, config can change this
done('failed to generate a long enough string for the test ' + prefix.length); done('failed to generate a long enough string for the test ' + prefix.length);
return; return;
@ -95,7 +95,7 @@ describe('getSegmentsByHash', () => {
if (res.status !== 400) done("non 400 status code, was " + res.status); if (res.status !== 400) done("non 400 status code, was " + res.status);
else done(); // pass else done(); // pass
}) })
.catch(err => done("Couldn't call endpoint")); .catch(() => done("Couldn't call endpoint"));
}); });
it('Should not return 400 prefix in range', (done: Done) => { it('Should not return 400 prefix in range', (done: Done) => {
@ -104,7 +104,7 @@ describe('getSegmentsByHash', () => {
if (res.status === 400) done("prefix length 5 gave 400 " + res.status); if (res.status === 400) done("prefix length 5 gave 400 " + res.status);
else done(); // pass else done(); // pass
}) })
.catch(err => done("Couldn't call endpoint")); .catch(() => done("Couldn't call endpoint"));
}); });
it('Should return 404 for no hash', (done: Done) => { it('Should return 404 for no hash', (done: Done) => {
@ -113,7 +113,7 @@ describe('getSegmentsByHash', () => {
if (res.status !== 404) done("expected 404, got " + res.status); if (res.status !== 404) done("expected 404, got " + res.status);
else done(); // pass else done(); // pass
}) })
.catch(err => done("Couldn't call endpoint")); .catch(() => done("Couldn't call endpoint"));
}); });
it('Should return 400 for bad format categories', (done: Done) => { it('Should return 400 for bad format categories', (done: Done) => {
@ -122,7 +122,7 @@ describe('getSegmentsByHash', () => {
if (res.status !== 400) done("expected 400 got " + res.status); if (res.status !== 400) done("expected 400 got " + res.status);
else done(); // pass else done(); // pass
}) })
.catch(err => done("Couldn't call endpoint")); .catch(() => done("Couldn't call endpoint"));
}); });
it('Should be able to get multiple videos', (done: Done) => { it('Should be able to get multiple videos', (done: Done) => {
@ -137,7 +137,7 @@ describe('getSegmentsByHash', () => {
else done(); else done();
} }
}) })
.catch(err => done("Couldn't call endpoint")); .catch(() => done("Couldn't call endpoint"));
}); });
it('Should be able to get 200 for no categories (default sponsor)', (done: Done) => { it('Should be able to get 200 for no categories (default sponsor)', (done: Done) => {
@ -155,7 +155,7 @@ describe('getSegmentsByHash', () => {
else done(); else done();
} }
}) })
.catch(err => done("Couldn't call endpoint")); .catch(() => done("Couldn't call endpoint"));
}); });
it('Should be able to get 200 for no categories (default sponsor) for a non YouTube service', (done: Done) => { it('Should be able to get 200 for no categories (default sponsor) for a non YouTube service', (done: Done) => {
@ -170,7 +170,7 @@ describe('getSegmentsByHash', () => {
else done(); else done();
} }
}) })
.catch(err => done("Couldn't call endpoint")); .catch(() => done("Couldn't call endpoint"));
}); });
it('Should only return one segment when fetching highlight segments', (done: Done) => { it('Should only return one segment when fetching highlight segments', (done: Done) => {
@ -184,11 +184,11 @@ describe('getSegmentsByHash', () => {
else done(); else done();
} }
}) })
.catch(err => done("Couldn't call endpoint")); .catch(() => done("Couldn't call endpoint"));
}); });
it('Should be able to post a segment and get it using endpoint', (done: Done) => { it('Should be able to post a segment and get it using endpoint', (done: Done) => {
let testID = 'abc123goodVideo'; const testID = 'abc123goodVideo';
fetch(getbaseURL() + "/api/postVideoSponsorTimes", { fetch(getbaseURL() + "/api/postVideoSponsorTimes", {
method: 'POST', method: 'POST',
headers: { headers: {
@ -216,7 +216,7 @@ describe('getSegmentsByHash', () => {
else done(); else done();
} }
}) })
.catch(err => done("(get) Couldn't call endpoint")); .catch(() => done("(get) Couldn't call endpoint"));
} else { } else {
done("(post) non 200 status code, was " + res.status); done("(post) non 200 status code, was " + res.status);
} }

View file

@ -23,11 +23,10 @@ describe('getUserID', () => {
it('Should be able to get a 200', (done: Done) => { it('Should be able to get a 200', (done: Done) => {
fetch(getbaseURL() + '/api/userID?username=fuzzy+user+01') fetch(getbaseURL() + '/api/userID?username=fuzzy+user+01')
.then(async res => { .then(async res => {
const text = await res.text()
if (res.status !== 200) done('non 200 (' + res.status + ')'); if (res.status !== 200) done('non 200 (' + res.status + ')');
else done(); // pass else done(); // pass
}) })
.catch(err => done('couldn\'t call endpoint')); .catch(() => done('couldn\'t call endpoint'));
}); });
it('Should be able to get a 400 (No username parameter)', (done: Done) => { it('Should be able to get a 400 (No username parameter)', (done: Done) => {
@ -36,17 +35,16 @@ describe('getUserID', () => {
if (res.status !== 400) done('non 400 (' + res.status + ')'); if (res.status !== 400) done('non 400 (' + res.status + ')');
else done(); // pass else done(); // pass
}) })
.catch(err => done('couldn\'t call endpoint')); .catch(() => done('couldn\'t call endpoint'));
}); });
it('Should be able to get a 200 (username is public id)', (done: Done) => { it('Should be able to get a 200 (username is public id)', (done: Done) => {
fetch(getbaseURL() + '/api/userID?username='+getHash("getuserid_user_06")) fetch(getbaseURL() + '/api/userID?username='+getHash("getuserid_user_06"))
.then(async res => { .then(async res => {
const text = await res.text()
if (res.status !== 200) done('non 200 (' + res.status + ')'); if (res.status !== 200) done('non 200 (' + res.status + ')');
else done(); // pass else done(); // pass
}) })
.catch(err => done('couldn\'t call endpoint')); .catch(() => done('couldn\'t call endpoint'));
}); });
it('Should be able to get a 400 (username longer than 64 chars)', (done: Done) => { it('Should be able to get a 400 (username longer than 64 chars)', (done: Done) => {
@ -55,7 +53,7 @@ describe('getUserID', () => {
if (res.status !== 400) done('non 400 (' + res.status + ')'); if (res.status !== 400) done('non 400 (' + res.status + ')');
else done(); // pass else done(); // pass
}) })
.catch(err => done('couldn\'t call endpoint')); .catch(() => done('couldn\'t call endpoint'));
}); });
it('Should be able to get single username', (done: Done) => { it('Should be able to get single username', (done: Done) => {
@ -76,7 +74,7 @@ describe('getUserID', () => {
} }
} }
}) })
.catch(err => ("couldn't call endpoint")); .catch(() => ("couldn't call endpoint"));
}); });
it('Should be able to get multiple fuzzy user info from start', (done: Done) => { it('Should be able to get multiple fuzzy user info from start', (done: Done) => {
@ -101,7 +99,7 @@ describe('getUserID', () => {
} }
} }
}) })
.catch(err => ("couldn't call endpoint")); .catch(() => ("couldn't call endpoint"));
}); });
it('Should be able to get multiple fuzzy user info from middle', (done: Done) => { it('Should be able to get multiple fuzzy user info from middle', (done: Done) => {
@ -130,7 +128,7 @@ describe('getUserID', () => {
} }
} }
}) })
.catch(err => ("couldn't call endpoint")); .catch(() => ("couldn't call endpoint"));
}); });
it('Should be able to get with public ID', (done: Done) => { it('Should be able to get with public ID', (done: Done) => {
@ -152,7 +150,7 @@ describe('getUserID', () => {
} }
} }
}) })
.catch(err => ("couldn't call endpoint")); .catch(() => ("couldn't call endpoint"));
}); });
it('Should be able to get with fuzzy public ID', (done: Done) => { it('Should be able to get with fuzzy public ID', (done: Done) => {
@ -174,7 +172,7 @@ describe('getUserID', () => {
} }
} }
}) })
.catch(err => ("couldn't call endpoint")); .catch(() => ("couldn't call endpoint"));
}); });
it('Should be able to get repeating username', (done: Done) => { it('Should be able to get repeating username', (done: Done) => {
@ -199,7 +197,7 @@ describe('getUserID', () => {
} }
} }
}) })
.catch(err => ("couldn't call endpoint")); .catch(() => ("couldn't call endpoint"));
}); });
it('Should be able to get repeating fuzzy username', (done: Done) => { it('Should be able to get repeating fuzzy username', (done: Done) => {
@ -224,7 +222,7 @@ describe('getUserID', () => {
} }
} }
}) })
.catch(err => ("couldn't call endpoint")); .catch(() => ("couldn't call endpoint"));
}); });
it('should avoid ReDOS with _', (done: Done) => { it('should avoid ReDOS with _', (done: Done) => {
@ -245,7 +243,7 @@ describe('getUserID', () => {
} }
} }
}) })
.catch(err => ("couldn't call endpoint")); .catch(() => ("couldn't call endpoint"));
}); });
it('should avoid ReDOS with %', (done: Done) => { it('should avoid ReDOS with %', (done: Done) => {
@ -266,7 +264,7 @@ describe('getUserID', () => {
} }
} }
}) })
.catch(err => ("couldn't call endpoint")); .catch(() => ("couldn't call endpoint"));
}); });
it('should return 404 if escaped backslashes present', (done: Done) => { it('should return 404 if escaped backslashes present', (done: Done) => {
@ -275,7 +273,7 @@ describe('getUserID', () => {
if (res.status !== 404) done('non 404 (' + res.status + ')'); if (res.status !== 404) done('non 404 (' + res.status + ')');
else done(); // pass else done(); // pass
}) })
.catch(err => ("couldn't call endpoint")); .catch(() => ("couldn't call endpoint"));
}); });
it('should return 404 if backslashes present', (done: Done) => { it('should return 404 if backslashes present', (done: Done) => {
@ -284,7 +282,7 @@ describe('getUserID', () => {
if (res.status !== 404) done('non 404 (' + res.status + ')'); if (res.status !== 404) done('non 404 (' + res.status + ')');
else done(); // pass else done(); // pass
}) })
.catch(err => ("couldn't call endpoint")); .catch(() => ("couldn't call endpoint"));
}); });
it('should return user if just backslashes', (done: Done) => { it('should return user if just backslashes', (done: Done) => {
@ -305,7 +303,7 @@ describe('getUserID', () => {
} }
} }
}) })
.catch(err => ("couldn't call endpoint")); .catch(() => ("couldn't call endpoint"));
}); });
it('should not allow usernames more than 64 characters', (done: Done) => { it('should not allow usernames more than 64 characters', (done: Done) => {
@ -314,7 +312,7 @@ describe('getUserID', () => {
if (res.status !== 400) done('non 400 (' + res.status + ')'); if (res.status !== 400) done('non 400 (' + res.status + ')');
else done(); // pass else done(); // pass
}) })
.catch(err => ("couldn't call endpoint")); .catch(() => ("couldn't call endpoint"));
}); });
it('should not allow usernames less than 3 characters', (done: Done) => { it('should not allow usernames less than 3 characters', (done: Done) => {
@ -323,7 +321,7 @@ describe('getUserID', () => {
if (res.status !== 400) done('non 400 (' + res.status + ')'); if (res.status !== 400) done('non 400 (' + res.status + ')');
else done(); // pass else done(); // pass
}) })
.catch(err => ("couldn't call endpoint")); .catch(() => ("couldn't call endpoint"));
}); });
it('should allow exact match', (done: Done) => { it('should allow exact match', (done: Done) => {
@ -344,7 +342,7 @@ describe('getUserID', () => {
} }
} }
}) })
.catch(err => ("couldn't call endpoint")); .catch(() => ("couldn't call endpoint"));
}); });
it('Should be able to get repeating username with exact username', (done: Done) => { it('Should be able to get repeating username with exact username', (done: Done) => {
@ -369,7 +367,7 @@ describe('getUserID', () => {
} }
} }
}) })
.catch(err => ("couldn't call endpoint")); .catch(() => ("couldn't call endpoint"));
}); });
it('Should not get exact unless explicitly set to true', (done: Done) => { it('Should not get exact unless explicitly set to true', (done: Done) => {
@ -398,6 +396,6 @@ describe('getUserID', () => {
} }
} }
}) })
.catch(err => ("couldn't call endpoint")); .catch(() => ("couldn't call endpoint"));
}); });
}); });

View file

@ -30,7 +30,7 @@ describe('getUserInfo', () => {
if (res.status !== 200) done('non 200 (' + res.status + ')'); if (res.status !== 200) done('non 200 (' + res.status + ')');
else done(); // pass else done(); // pass
}) })
.catch(err => done('couldn\'t call endpoint')); .catch(() => done('couldn\'t call endpoint'));
}); });
it('Should be able to get a 400 (No userID parameter)', (done: Done) => { it('Should be able to get a 400 (No userID parameter)', (done: Done) => {
@ -39,7 +39,7 @@ describe('getUserInfo', () => {
if (res.status !== 400) done('non 400 (' + res.status + ')'); if (res.status !== 400) done('non 400 (' + res.status + ')');
else done(); // pass else done(); // pass
}) })
.catch(err => done('couldn\'t call endpoint')); .catch(() => done('couldn\'t call endpoint'));
}); });
it('Should be able to get user info', (done: Done) => { it('Should be able to get user info', (done: Done) => {
@ -70,7 +70,7 @@ describe('getUserInfo', () => {
} }
} }
}) })
.catch(err => ("couldn't call endpoint")); .catch(() => ("couldn't call endpoint"));
}); });
it('Should get warning data', (done: Done) => { it('Should get warning data', (done: Done) => {
@ -79,12 +79,12 @@ describe('getUserInfo', () => {
if (res.status !== 200) { if (res.status !== 200) {
done('non 200 (' + res.status + ')'); done('non 200 (' + res.status + ')');
} else { } else {
const data = await res.json();; const data = await res.json();
if (data.warnings !== 1) done('wrong number of warnings: ' + data.warnings + ', not ' + 1); if (data.warnings !== 1) done('wrong number of warnings: ' + data.warnings + ', not ' + 1);
else done(); // pass else done(); // pass
} }
}) })
.catch(err => ("couldn't call endpoint")); .catch(() => ("couldn't call endpoint"));
}); });
it('Should get warning data with public ID', (done: Done) => { it('Should get warning data with public ID', (done: Done) => {
@ -98,7 +98,7 @@ describe('getUserInfo', () => {
else done(); else done();
} }
}) })
.catch(err => ("couldn't call endpoint")); .catch(() => ("couldn't call endpoint"));
}); });
it('Should get multiple warnings', (done: Done) => { it('Should get multiple warnings', (done: Done) => {
@ -112,7 +112,7 @@ describe('getUserInfo', () => {
else done(); // pass else done(); // pass
} }
}) })
.catch(err => ("couldn't call endpoint")); .catch(() => ("couldn't call endpoint"));
}); });
it('Should not get warnings if none', (done: Done) => { it('Should not get warnings if none', (done: Done) => {
@ -126,7 +126,7 @@ describe('getUserInfo', () => {
else done(); // pass else done(); // pass
} }
}) })
.catch(err => ("couldn't call endpoint")); .catch(() => ("couldn't call endpoint"));
}); });
it('Should done(userID for userName (No userName set)', (done: Done) => { it('Should done(userID for userName (No userName set)', (done: Done) => {
@ -142,7 +142,7 @@ describe('getUserInfo', () => {
done(); // pass done(); // pass
} }
}) })
.catch(err => ('couldn\'t call endpoint')); .catch(() => ('couldn\'t call endpoint'));
}); });
it('Should return null segment if none', (done: Done) => { it('Should return null segment if none', (done: Done) => {
@ -156,20 +156,20 @@ describe('getUserInfo', () => {
else done(); // pass else done(); // pass
} }
}) })
.catch(err => ("couldn't call endpoint")); .catch(() => ("couldn't call endpoint"));
}); });
it('Should return zeroes if userid does not exist', (done: Done) => { it('Should return zeroes if userid does not exist', (done: Done) => {
fetch(getbaseURL() + '/api/userInfo?userID=getuserinfo_null') fetch(getbaseURL() + '/api/userInfo?userID=getuserinfo_null')
.then(async res => { .then(async res => {
const data = await res.json(); const data = await res.json();
for (var value in data) { for (const value in data) {
if (data[value] === null && value !== "lastSegmentID") { if (data[value] === null && value !== "lastSegmentID") {
done(`returned null for ${value}`) done(`returned null for ${value}`)
} }
} }
done(); // pass done(); // pass
}) })
.catch(err => ("couldn't call endpoint")); .catch(() => ("couldn't call endpoint"));
}); });
}); });

View file

@ -24,13 +24,13 @@ describe('lockCategoriesRecords', () => {
}); });
it('Should update the database version when starting the application', async () => { it('Should update the database version when starting the application', async () => {
let version = (await db.prepare('get', 'SELECT key, value FROM config where key = ?', ['version'])).value; const version = (await db.prepare('get', 'SELECT key, value FROM config where key = ?', ['version'])).value;
if (version > 1) return; if (version > 1) return;
else return 'Version isn\'t greater than 1. Version is ' + version; else return 'Version isn\'t greater than 1. Version is ' + version;
}); });
it('Should be able to submit categories not in video (http response)', (done: Done) => { it('Should be able to submit categories not in video (http response)', (done: Done) => {
let json = { const json = {
videoID: 'no-segments-video-id', videoID: 'no-segments-video-id',
userID: 'VIPUser-lockCategories', userID: 'VIPUser-lockCategories',
categories: [ categories: [
@ -43,7 +43,7 @@ describe('lockCategoriesRecords', () => {
], ],
}; };
let expected = { const expected = {
submitted: [ submitted: [
'outro', 'outro',
'shilling', 'shilling',
@ -66,7 +66,6 @@ describe('lockCategoriesRecords', () => {
done("Incorrect response: expected " + JSON.stringify(expected) + " got " + JSON.stringify(data)); done("Incorrect response: expected " + JSON.stringify(expected) + " got " + JSON.stringify(data));
} }
} else { } else {
const body = await res.text();
done("Status code was " + res.status); done("Status code was " + res.status);
} }
}) })
@ -74,7 +73,7 @@ describe('lockCategoriesRecords', () => {
}); });
it('Should be able to submit categories not in video (sql check)', (done: Done) => { it('Should be able to submit categories not in video (sql check)', (done: Done) => {
let json = { const json = {
videoID: 'no-segments-video-id-1', videoID: 'no-segments-video-id-1',
userID: 'VIPUser-lockCategories', userID: 'VIPUser-lockCategories',
categories: [ categories: [
@ -96,14 +95,13 @@ describe('lockCategoriesRecords', () => {
}) })
.then(async res => { .then(async res => {
if (res.status === 200) { if (res.status === 200) {
let result = await db.prepare('all', 'SELECT * FROM "lockCategories" WHERE "videoID" = ?', ['no-segments-video-id-1']); const result = await db.prepare('all', 'SELECT * FROM "lockCategories" WHERE "videoID" = ?', ['no-segments-video-id-1']);
if (result.length !== 4) { if (result.length !== 4) {
done("Expected 4 entrys in db, got " + result.length); done("Expected 4 entrys in db, got " + result.length);
} else { } else {
done(); done();
} }
} else { } else {
const body = await res.text();
done("Status code was " + res.status); done("Status code was " + res.status);
} }
}) })
@ -111,7 +109,7 @@ describe('lockCategoriesRecords', () => {
}); });
it('Should be able to submit categories with _ in the category', (done: Done) => { it('Should be able to submit categories with _ in the category', (done: Done) => {
let json = { const json = {
videoID: 'underscore', videoID: 'underscore',
userID: 'VIPUser-lockCategories', userID: 'VIPUser-lockCategories',
categories: [ categories: [
@ -128,14 +126,13 @@ describe('lockCategoriesRecords', () => {
}) })
.then(async res => { .then(async res => {
if (res.status === 200) { if (res.status === 200) {
let result = await db.prepare('all', 'SELECT * FROM "lockCategories" WHERE "videoID" = ?', ['underscore']); const result = await db.prepare('all', 'SELECT * FROM "lockCategories" WHERE "videoID" = ?', ['underscore']);
if (result.length !== 1) { if (result.length !== 1) {
done("Expected 1 entrys in db, got " + result.length); done("Expected 1 entrys in db, got " + result.length);
} else { } else {
done(); done();
} }
} else { } else {
const body = await res.text();
done("Status code was " + res.status); done("Status code was " + res.status);
} }
}) })
@ -143,7 +140,7 @@ describe('lockCategoriesRecords', () => {
}); });
it('Should be able to submit categories with upper and lower case in the category', (done: Done) => { it('Should be able to submit categories with upper and lower case in the category', (done: Done) => {
let json = { const json = {
videoID: 'bothCases', videoID: 'bothCases',
userID: 'VIPUser-lockCategories', userID: 'VIPUser-lockCategories',
categories: [ categories: [
@ -160,14 +157,13 @@ describe('lockCategoriesRecords', () => {
}) })
.then(async res => { .then(async res => {
if (res.status === 200) { if (res.status === 200) {
let result = await db.prepare('all', 'SELECT * FROM "lockCategories" WHERE "videoID" = ?', ['bothCases']); const result = await db.prepare('all', 'SELECT * FROM "lockCategories" WHERE "videoID" = ?', ['bothCases']);
if (result.length !== 1) { if (result.length !== 1) {
done("Expected 1 entrys in db, got " + result.length); done("Expected 1 entrys in db, got " + result.length);
} else { } else {
done(); done();
} }
} else { } else {
const body = await res.text();
done("Status code was " + res.status); done("Status code was " + res.status);
} }
}) })
@ -175,7 +171,7 @@ describe('lockCategoriesRecords', () => {
}); });
it('Should not be able to submit categories with $ in the category', (done: Done) => { it('Should not be able to submit categories with $ in the category', (done: Done) => {
let json = { const json = {
videoID: 'specialChar', videoID: 'specialChar',
userID: 'VIPUser-lockCategories', userID: 'VIPUser-lockCategories',
categories: [ categories: [
@ -192,14 +188,13 @@ describe('lockCategoriesRecords', () => {
}) })
.then(async res => { .then(async res => {
if (res.status === 200) { if (res.status === 200) {
let result = await db.prepare('all', 'SELECT * FROM "lockCategories" WHERE "videoID" = ?', ['specialChar']); const result = await db.prepare('all', 'SELECT * FROM "lockCategories" WHERE "videoID" = ?', ['specialChar']);
if (result.length !== 0) { if (result.length !== 0) {
done("Expected 0 entrys in db, got " + result.length); done("Expected 0 entrys in db, got " + result.length);
} else { } else {
done(); done();
} }
} else { } else {
const body = await res.text();
done("Status code was " + res.status); done("Status code was " + res.status);
} }
}) })
@ -225,7 +220,7 @@ describe('lockCategoriesRecords', () => {
}); });
it('Should return 400 for no categories', (done: Done) => { it('Should return 400 for no categories', (done: Done) => {
let json: any = { const json: any = {
videoID: 'test', videoID: 'test',
userID: 'test', userID: 'test',
categories: [], categories: [],
@ -249,7 +244,7 @@ describe('lockCategoriesRecords', () => {
}); });
it('Should return 400 for no userID', (done: Done) => { it('Should return 400 for no userID', (done: Done) => {
let json: any = { const json: any = {
videoID: 'test', videoID: 'test',
userID: null, userID: null,
categories: ['sponsor'], categories: ['sponsor'],
@ -273,7 +268,7 @@ describe('lockCategoriesRecords', () => {
}); });
it('Should return 400 for no videoID', (done: Done) => { it('Should return 400 for no videoID', (done: Done) => {
let json: any = { const json: any = {
videoID: null, videoID: null,
userID: 'test', userID: 'test',
categories: ['sponsor'], categories: ['sponsor'],
@ -297,7 +292,7 @@ describe('lockCategoriesRecords', () => {
}); });
it('Should return 400 object categories', (done: Done) => { it('Should return 400 object categories', (done: Done) => {
let json = { const json = {
videoID: 'test', videoID: 'test',
userID: 'test', userID: 'test',
categories: {}, categories: {},
@ -321,7 +316,7 @@ describe('lockCategoriesRecords', () => {
}); });
it('Should return 400 bad format categories', (done: Done) => { it('Should return 400 bad format categories', (done: Done) => {
let json = { const json = {
videoID: 'test', videoID: 'test',
userID: 'test', userID: 'test',
categories: 'sponsor', categories: 'sponsor',
@ -345,7 +340,7 @@ describe('lockCategoriesRecords', () => {
}); });
it('Should return 403 if user is not VIP', (done: Done) => { it('Should return 403 if user is not VIP', (done: Done) => {
let json = { const json = {
videoID: 'test', videoID: 'test',
userID: 'test', userID: 'test',
categories: [ categories: [
@ -371,7 +366,7 @@ describe('lockCategoriesRecords', () => {
}); });
it('Should be able to delete a lockCategories record', (done: Done) => { it('Should be able to delete a lockCategories record', (done: Done) => {
let json = { const json = {
videoID: 'delete-record', videoID: 'delete-record',
userID: 'VIPUser-lockCategories', userID: 'VIPUser-lockCategories',
categories: [ categories: [
@ -388,7 +383,7 @@ describe('lockCategoriesRecords', () => {
}) })
.then(async res => { .then(async res => {
if (res.status === 200) { if (res.status === 200) {
let result = await db.prepare('all', 'SELECT * FROM "lockCategories" WHERE "videoID" = ?', ['delete-record']); const result = await db.prepare('all', 'SELECT * FROM "lockCategories" WHERE "videoID" = ?', ['delete-record']);
if (result.length === 0) { if (result.length === 0) {
done(); done();
} else { } else {
@ -402,7 +397,7 @@ describe('lockCategoriesRecords', () => {
}); });
it('Should be able to delete one lockCategories record without removing another', (done: Done) => { it('Should be able to delete one lockCategories record without removing another', (done: Done) => {
let json = { const json = {
videoID: 'delete-record-1', videoID: 'delete-record-1',
userID: 'VIPUser-lockCategories', userID: 'VIPUser-lockCategories',
categories: [ categories: [
@ -419,7 +414,7 @@ describe('lockCategoriesRecords', () => {
}) })
.then(async res => { .then(async res => {
if (res.status === 200) { if (res.status === 200) {
let result = await db.prepare('all', 'SELECT * FROM "lockCategories" WHERE "videoID" = ?', ['delete-record-1']); const result = await db.prepare('all', 'SELECT * FROM "lockCategories" WHERE "videoID" = ?', ['delete-record-1']);
if (result.length === 1) { if (result.length === 1) {
done(); done();
} else { } else {

View file

@ -16,7 +16,7 @@ describe('getVideoSponsorTime (Old get method)', () => {
if (res.status !== 200) done("non 200 (" + res.status + ")"); if (res.status !== 200) done("non 200 (" + res.status + ")");
else done(); // pass else done(); // pass
}) })
.catch(err => done("Couldn't call endpoint")); .catch(() => done("Couldn't call endpoint"));
}); });
it('Should return 404 if no segment found', (done: Done) => { it('Should return 404 if no segment found', (done: Done) => {
@ -25,7 +25,7 @@ describe('getVideoSponsorTime (Old get method)', () => {
if (res.status !== 404) done("non 404 respone code: " + res.status); if (res.status !== 404) done("non 404 respone code: " + res.status);
else done(); // pass else done(); // pass
}) })
.catch(err => done("couldn't call endpoint")); .catch(() => done("couldn't call endpoint"));
}); });
@ -35,7 +35,7 @@ describe('getVideoSponsorTime (Old get method)', () => {
if (res.status !== 200) done("non 200"); if (res.status !== 200) done("non 200");
else done(); // pass else done(); // pass
}) })
.catch(err => done("couldn't callendpoint")); .catch(() => done("couldn't callendpoint"));
}); });
it('Should be able send a comma in a query param', (done: Done) => { it('Should be able send a comma in a query param', (done: Done) => {
@ -46,7 +46,7 @@ describe('getVideoSponsorTime (Old get method)', () => {
else if (JSON.parse(body).UUIDs[0] === 'uuid-1') done(); // pass else if (JSON.parse(body).UUIDs[0] === 'uuid-1') done(); // pass
else done("couldn't parse response"); else done("couldn't parse response");
}) })
.catch(err => done("couln't call endpoint")); .catch(() => done("couln't call endpoint"));
}); });
it('Should be able to get the correct time', (done: Done) => { it('Should be able to get the correct time', (done: Done) => {
@ -65,6 +65,6 @@ describe('getVideoSponsorTime (Old get method)', () => {
} }
}) })
.catch(err => done("couldn't call endpoint")); .catch(() => done("couldn't call endpoint"));
}); });
}); });

View file

@ -9,7 +9,7 @@ describe('postVideoSponsorTime (Old submission method)', () => {
+ "/api/postVideoSponsorTimes?videoID=dQw4w9WgXcQ&startTime=1&endTime=10&userID=test") + "/api/postVideoSponsorTimes?videoID=dQw4w9WgXcQ&startTime=1&endTime=10&userID=test")
.then(async res => { .then(async res => {
if (res.status === 200) { if (res.status === 200) {
let row = await db.prepare('get', `SELECT "startTime", "endTime", "category" FROM "sponsorTimes" WHERE "videoID" = ?`, ["dQw4w9WgXcQ"]); const row = await db.prepare('get', `SELECT "startTime", "endTime", "category" FROM "sponsorTimes" WHERE "videoID" = ?`, ["dQw4w9WgXcQ"]);
if (row.startTime === 1 && row.endTime === 10 && row.category === "sponsor") { if (row.startTime === 1 && row.endTime === 10 && row.category === "sponsor") {
done(); done();
} else { } else {
@ -32,7 +32,7 @@ describe('postVideoSponsorTime (Old submission method)', () => {
}) })
.then(async res => { .then(async res => {
if (res.status === 200) { if (res.status === 200) {
let row = await db.prepare('get', `SELECT "startTime", "endTime", "category" FROM "sponsorTimes" WHERE "videoID" = ?`, ["dQw4w9WgXcE"]); const row = await db.prepare('get', `SELECT "startTime", "endTime", "category" FROM "sponsorTimes" WHERE "videoID" = ?`, ["dQw4w9WgXcE"]);
if (row.startTime === 1 && row.endTime === 11 && row.category === "sponsor") { if (row.startTime === 1 && row.endTime === 11 && row.category === "sponsor") {
done(); done();
} else { } else {

View file

@ -6,7 +6,7 @@ import {getHash} from '../../src/utils/getHash';
describe('postClearCache', () => { describe('postClearCache', () => {
before(async () => { before(async () => {
await db.prepare("run", `INSERT INTO "vipUsers" ("userID") VALUES ('` + getHash("clearing-vip") + "')"); await db.prepare("run", `INSERT INTO "vipUsers" ("userID") VALUES ('` + getHash("clearing-vip") + "')");
let startOfQuery = 'INSERT INTO "sponsorTimes" ("videoID", "startTime", "endTime", "votes", "UUID", "userID", "timeSubmitted", views, category, "shadowHidden", "hashedVideoID") VALUES'; const startOfQuery = 'INSERT INTO "sponsorTimes" ("videoID", "startTime", "endTime", "votes", "UUID", "userID", "timeSubmitted", views, category, "shadowHidden", "hashedVideoID") VALUES';
await db.prepare("run", startOfQuery + "('clear-test', 0, 1, 2, 'clear-uuid', 'testman', 0, 50, 'sponsor', 0, '" + getHash('clear-test', 1) + "')"); await db.prepare("run", startOfQuery + "('clear-test', 0, 1, 2, 'clear-uuid', 'testman', 0, 50, 'sponsor', 0, '" + getHash('clear-test', 1) + "')");
}); });

View file

@ -20,7 +20,7 @@ async function dbSponsorTimesAdd(db: IDatabase, videoID: string, startTime: numb
} }
async function dbSponsorTimesCompareExpect(db: IDatabase, videoId: string, expectdHidden: number) { async function dbSponsorTimesCompareExpect(db: IDatabase, videoId: string, expectdHidden: number) {
let seg = await db.prepare('get', `SELECT "hidden", "UUID" FROM "sponsorTimes" WHERE "videoID" = ?`, [videoId]); const seg = await db.prepare('get', `SELECT "hidden", "UUID" FROM "sponsorTimes" WHERE "videoID" = ?`, [videoId]);
for (let i = 0, len = seg.length; i < len; i++) { for (let i = 0, len = seg.length; i < len; i++) {
if (seg.hidden !== expectdHidden) { if (seg.hidden !== expectdHidden) {
return `${seg.UUID} hidden expected to be ${expectdHidden} but found ${seg.hidden}`; return `${seg.UUID} hidden expected to be ${expectdHidden} but found ${seg.hidden}`;

View file

@ -258,7 +258,7 @@ describe('postSkipSegments', () => {
done("non 403 status code: " + res.status + " (" + body + ")"); done("non 403 status code: " + res.status + " (" + body + ")");
} }
}) })
.catch(err => done("Couldn't call endpoint")); .catch(() => done("Couldn't call endpoint"));
}); });
it('Should be able to submit a single time under a different service (JSON method)', (done: Done) => { it('Should be able to submit a single time under a different service (JSON method)', (done: Done) => {
@ -521,7 +521,7 @@ describe('postSkipSegments', () => {
done("non 200 status code: " + res.status + " (" + body + ")"); done("non 200 status code: " + res.status + " (" + body + ")");
} }
}) })
.catch(err => done("Couldn't call endpoint")); .catch(() => done("Couldn't call endpoint"));
}); });
it('Should be rejected if segment starts and ends at the same time', (done: Done) => { it('Should be rejected if segment starts and ends at the same time', (done: Done) => {
@ -536,7 +536,7 @@ describe('postSkipSegments', () => {
done("non 400 status code: " + res.status + " (" + body + ")"); done("non 400 status code: " + res.status + " (" + body + ")");
} }
}) })
.catch(err => done("Couldn't call endpoint")); .catch(() => done("Couldn't call endpoint"));
}); });
it('Should be accepted if highlight segment starts and ends at the same time', (done: Done) => { it('Should be accepted if highlight segment starts and ends at the same time', (done: Done) => {
@ -551,7 +551,7 @@ describe('postSkipSegments', () => {
done("non 200 status code: " + res.status + " (" + body + ")"); done("non 200 status code: " + res.status + " (" + body + ")");
} }
}) })
.catch(err => done("Couldn't call endpoint")); .catch(() => done("Couldn't call endpoint"));
}); });
it('Should be rejected if highlight segment doesn\'t start and end at the same time', (done: Done) => { it('Should be rejected if highlight segment doesn\'t start and end at the same time', (done: Done) => {
@ -566,7 +566,7 @@ describe('postSkipSegments', () => {
done("non 400 status code: " + res.status + " (" + body + ")"); done("non 400 status code: " + res.status + " (" + body + ")");
} }
}) })
.catch(err => done("Couldn't call endpoint")); .catch(() => done("Couldn't call endpoint"));
}); });
it('Should be rejected if a sponsor is less than 1 second', (done: Done) => { it('Should be rejected if a sponsor is less than 1 second', (done: Done) => {
@ -581,7 +581,7 @@ describe('postSkipSegments', () => {
done("non 403 status code: " + res.status + " (" + body + ")"); done("non 403 status code: " + res.status + " (" + body + ")");
} }
}) })
.catch(err => done("Couldn't call endpoint")); .catch(() => done("Couldn't call endpoint"));
}); });
it('Should be rejected if over 80% of the video', (done: Done) => { it('Should be rejected if over 80% of the video', (done: Done) => {
@ -594,7 +594,7 @@ describe('postSkipSegments', () => {
done("non 403 status code: " + res.status + " (" + body + ")"); done("non 403 status code: " + res.status + " (" + body + ")");
} }
}) })
.catch(err => done("Couldn't call endpoint")); .catch(() => done("Couldn't call endpoint"));
}); });
it("Should be rejected if NB's predicted probability is <70%.", (done: Done) => { it("Should be rejected if NB's predicted probability is <70%.", (done: Done) => {
@ -607,7 +607,7 @@ describe('postSkipSegments', () => {
done("non 200 status code: " + res.status + " (" + body + ")"); done("non 200 status code: " + res.status + " (" + body + ")");
} }
}) })
.catch(err => done("Couldn't call endpoint")); .catch(() => done("Couldn't call endpoint"));
}); });
it('Should be rejected with custom message if user has to many active warnings', (done: Done) => { it('Should be rejected with custom message if user has to many active warnings', (done: Done) => {
@ -704,7 +704,7 @@ describe('postSkipSegments', () => {
if (res.status === 400) done(); if (res.status === 400) done();
else done(true); else done(true);
}) })
.catch(err => done(true)); .catch(() => done(true));
}); });
it('Should be rejected with default message if user has to many active warnings', (done: Done) => { it('Should be rejected with default message if user has to many active warnings', (done: Done) => {
@ -760,7 +760,7 @@ describe('postSkipSegments', () => {
if (res.status === 400) done(); if (res.status === 400) done();
else done(true); else done(true);
}) })
.catch(err => done(true)); .catch(() => done(true));
}); });
it('Should return 400 for missing params (JSON method) 2', (done: Done) => { it('Should return 400 for missing params (JSON method) 2', (done: Done) => {
fetch(getbaseURL() fetch(getbaseURL()
@ -778,7 +778,7 @@ describe('postSkipSegments', () => {
if (res.status === 400) done(); if (res.status === 400) done();
else done(true); else done(true);
}) })
.catch(err => done(true)); .catch(() => done(true));
}); });
it('Should return 400 for missing params (JSON method) 3', (done: Done) => { it('Should return 400 for missing params (JSON method) 3', (done: Done) => {
fetch(getbaseURL() fetch(getbaseURL()
@ -803,7 +803,7 @@ describe('postSkipSegments', () => {
if (res.status === 400) done(); if (res.status === 400) done();
else done(true); else done(true);
}) })
.catch(err => done(true)); .catch(() => done(true));
}); });
it('Should return 400 for missing params (JSON method) 4', (done: Done) => { it('Should return 400 for missing params (JSON method) 4', (done: Done) => {
fetch(getbaseURL() fetch(getbaseURL()
@ -827,7 +827,7 @@ describe('postSkipSegments', () => {
if (res.status === 400) done(); if (res.status === 400) done();
else done(true); else done(true);
}) })
.catch(err => done(true)); .catch(() => done(true));
}); });
it('Should return 400 for missing params (JSON method) 5', (done: Done) => { it('Should return 400 for missing params (JSON method) 5', (done: Done) => {
fetch(getbaseURL() fetch(getbaseURL()
@ -845,6 +845,6 @@ describe('postSkipSegments', () => {
if (res.status === 400) done(); if (res.status === 400) done();
else done(true); else done(true);
}) })
.catch(err => done(true)); .catch(() => done(true));
}); });
}); });

View file

@ -9,7 +9,7 @@ describe('postWarning', () => {
}); });
it('Should be able to create warning if vip (exp 200)', (done: Done) => { it('Should be able to create warning if vip (exp 200)', (done: Done) => {
let json = { const json = {
issuerUserID: 'warning-vip', issuerUserID: 'warning-vip',
userID: 'warning-0', userID: 'warning-0',
reason: 'warning-reason-0' reason: 'warning-reason-0'
@ -24,7 +24,7 @@ describe('postWarning', () => {
}) })
.then(async res => { .then(async res => {
if (res.status === 200) { if (res.status === 200) {
let row = await db.prepare('get', `SELECT "userID", "issueTime", "issuerUserID", enabled, "reason" FROM warnings WHERE "userID" = ?`, [json.userID]); const row = await db.prepare('get', `SELECT "userID", "issueTime", "issuerUserID", enabled, "reason" FROM warnings WHERE "userID" = ?`, [json.userID]);
if (row?.enabled == 1 && row?.issuerUserID == getHash(json.issuerUserID) && row?.reason === json.reason) { if (row?.enabled == 1 && row?.issuerUserID == getHash(json.issuerUserID) && row?.reason === json.reason) {
done(); done();
} else { } else {
@ -40,7 +40,7 @@ describe('postWarning', () => {
}); });
it('Should be not be able to create a duplicate warning if vip', (done: Done) => { it('Should be not be able to create a duplicate warning if vip', (done: Done) => {
let json = { const json = {
issuerUserID: 'warning-vip', issuerUserID: 'warning-vip',
userID: 'warning-0', userID: 'warning-0',
}; };
@ -55,7 +55,7 @@ describe('postWarning', () => {
}) })
.then(async res => { .then(async res => {
if (res.status === 409) { if (res.status === 409) {
let row = await db.prepare('get', `SELECT "userID", "issueTime", "issuerUserID", enabled FROM warnings WHERE "userID" = ?`, [json.userID]); const row = await db.prepare('get', `SELECT "userID", "issueTime", "issuerUserID", enabled FROM warnings WHERE "userID" = ?`, [json.userID]);
if (row?.enabled == 1 && row?.issuerUserID == getHash(json.issuerUserID)) { if (row?.enabled == 1 && row?.issuerUserID == getHash(json.issuerUserID)) {
done(); done();
} else { } else {
@ -71,7 +71,7 @@ describe('postWarning', () => {
}); });
it('Should be able to remove warning if vip', (done: Done) => { it('Should be able to remove warning if vip', (done: Done) => {
let json = { const json = {
issuerUserID: 'warning-vip', issuerUserID: 'warning-vip',
userID: 'warning-0', userID: 'warning-0',
enabled: false enabled: false
@ -87,7 +87,7 @@ describe('postWarning', () => {
}) })
.then(async res => { .then(async res => {
if (res.status === 200) { if (res.status === 200) {
let row = await db.prepare('get', `SELECT "userID", "issueTime", "issuerUserID", enabled FROM warnings WHERE "userID" = ?`, [json.userID]); const row = await db.prepare('get', `SELECT "userID", "issueTime", "issuerUserID", enabled FROM warnings WHERE "userID" = ?`, [json.userID]);
if (row?.enabled == 0) { if (row?.enabled == 0) {
done(); done();
} else { } else {
@ -103,7 +103,7 @@ describe('postWarning', () => {
}); });
it('Should not be able to create warning if not vip (exp 403)', (done: Done) => { it('Should not be able to create warning if not vip (exp 403)', (done: Done) => {
let json = { const json = {
issuerUserID: 'warning-not-vip', issuerUserID: 'warning-not-vip',
userID: 'warning-1', userID: 'warning-1',
}; };

View file

@ -18,7 +18,7 @@ describe('reputation', () => {
this.timeout(5000); // this preparation takes longer then usual this.timeout(5000); // this preparation takes longer then usual
const videoID = "reputation-videoID"; const videoID = "reputation-videoID";
let sponsorTimesInsertQuery = 'INSERT INTO "sponsorTimes" ("videoID", "startTime", "endTime", "votes", "locked", "UUID", "userID", "timeSubmitted", "views", "category", "service", "videoDuration", "hidden", "shadowHidden", "hashedVideoID") VALUES(?,?,?,?,?,?,?,?,?,?,?,?,?,?,?)'; const sponsorTimesInsertQuery = 'INSERT INTO "sponsorTimes" ("videoID", "startTime", "endTime", "votes", "locked", "UUID", "userID", "timeSubmitted", "views", "category", "service", "videoDuration", "hidden", "shadowHidden", "hashedVideoID") VALUES(?,?,?,?,?,?,?,?,?,?,?,?,?,?,?)';
await db.prepare("run", sponsorTimesInsertQuery, [videoID, 1, 11, 2, 0, 'reputation-0-uuid-0', getHash(userIDLowSubmissions), 1606240000000, 50, 'sponsor', 'YouTube', 100, 0, 0, getHash(videoID, 1)]); await db.prepare("run", sponsorTimesInsertQuery, [videoID, 1, 11, 2, 0, 'reputation-0-uuid-0', getHash(userIDLowSubmissions), 1606240000000, 50, 'sponsor', 'YouTube', 100, 0, 0, getHash(videoID, 1)]);
await db.prepare("run", sponsorTimesInsertQuery, [videoID, 1, 11, 2, 0, 'reputation-0-uuid-1', getHash(userIDLowSubmissions), 1606240000000, 50, 'sponsor', 'YouTube', 100, 0, 0, getHash(videoID, 1)]); await db.prepare("run", sponsorTimesInsertQuery, [videoID, 1, 11, 2, 0, 'reputation-0-uuid-1', getHash(userIDLowSubmissions), 1606240000000, 50, 'sponsor', 'YouTube', 100, 0, 0, getHash(videoID, 1)]);
await db.prepare("run", sponsorTimesInsertQuery, [videoID, 1, 11, 100, 0, 'reputation-0-uuid-2', getHash(userIDLowSubmissions), 1606240000000, 50, 'sponsor', 'YouTube', 100, 0, 0, getHash(videoID, 1)]); await db.prepare("run", sponsorTimesInsertQuery, [videoID, 1, 11, 100, 0, 'reputation-0-uuid-2', getHash(userIDLowSubmissions), 1606240000000, 50, 'sponsor', 'YouTube', 100, 0, 0, getHash(videoID, 1)]);

View file

@ -25,7 +25,7 @@ async function dbSponsorTimesSetByUUID(db: IDatabase, UUID: string, startTime: n
async function dbSponsorTimesCompareExpect(db: IDatabase, expect: any) { async function dbSponsorTimesCompareExpect(db: IDatabase, expect: any) {
for (let i = 0, len = expect.length; i < len; i++) { for (let i = 0, len = expect.length; i < len; i++) {
const expectSeg = expect[i]; const expectSeg = expect[i];
let seg = await db.prepare('get', `SELECT "startTime", "endTime" FROM "sponsorTimes" WHERE "UUID" = ?`, [expectSeg.UUID]); const seg = await db.prepare('get', `SELECT "startTime", "endTime" FROM "sponsorTimes" WHERE "UUID" = ?`, [expectSeg.UUID]);
if ('removed' in expect) { if ('removed' in expect) {
if (expect.removed === true && seg.votes === -2) { if (expect.removed === true && seg.votes === -2) {
return; return;

View file

@ -34,7 +34,7 @@ async function getUsernameInfo(userID: string): Promise<{ userName: string, lock
return row; return row;
} }
async function addLogUserNameChange(userID: string, newUserName: string, oldUserName: string = '') { async function addLogUserNameChange(userID: string, newUserName: string, oldUserName = '') {
privateDB.prepare('run', privateDB.prepare('run',
`INSERT INTO "userNameLogs"("userID", "newUserName", "oldUserName", "updatedAt", "updatedByAdmin") VALUES(?, ?, ?, ?, ?)`, `INSERT INTO "userNameLogs"("userID", "newUserName", "oldUserName", "updatedAt", "updatedByAdmin") VALUES(?, ?, ?, ?, ?)`,
[getHash(userID), newUserName, oldUserName, new Date().getTime(), + true] [getHash(userID), newUserName, oldUserName, new Date().getTime(), + true]
@ -90,7 +90,7 @@ describe('setUsername', () => {
if (usernameInfo.locked == "1") done(`Username was locked when it shouldn't have been`); if (usernameInfo.locked == "1") done(`Username was locked when it shouldn't have been`);
done(); done();
}) })
.catch(err => done(`couldn't call endpoint`)); .catch(() => done(`couldn't call endpoint`));
}); });
it('Should return 200', (done: Done) => { it('Should return 200', (done: Done) => {
@ -103,7 +103,7 @@ describe('setUsername', () => {
testUserNameChangelog(user01PrivateUserID, decodeURIComponent('Changed%20Username'), username01, false, done); testUserNameChangelog(user01PrivateUserID, decodeURIComponent('Changed%20Username'), username01, false, done);
} }
}) })
.catch(err => done(`couldn't call endpoint`)); .catch(() => done(`couldn't call endpoint`));
}); });
it('Should return 400 for missing param "userID"', (done: Done) => { it('Should return 400 for missing param "userID"', (done: Done) => {
@ -114,7 +114,7 @@ describe('setUsername', () => {
if (res.status !== 400) done(`Status code was ${res.status}`); if (res.status !== 400) done(`Status code was ${res.status}`);
else done(); // pass else done(); // pass
}) })
.catch(err => done(`couldn't call endpoint`)); .catch(() => done(`couldn't call endpoint`));
}); });
it('Should return 400 for missing param "username"', (done: Done) => { it('Should return 400 for missing param "username"', (done: Done) => {
@ -125,7 +125,7 @@ describe('setUsername', () => {
if (res.status !== 400) done(`Status code was ${res.status}`); if (res.status !== 400) done(`Status code was ${res.status}`);
else done(); // pass else done(); // pass
}) })
.catch(err => done(`couldn't call endpoint`)); .catch(() => done(`couldn't call endpoint`));
}); });
it('Should return 400 for "username" longer then 64 characters', (done: Done) => { it('Should return 400 for "username" longer then 64 characters', (done: Done) => {
@ -137,7 +137,7 @@ describe('setUsername', () => {
if (res.status !== 400) done(`Status code was ${res.status}`); if (res.status !== 400) done(`Status code was ${res.status}`);
else done(); // pass else done(); // pass
}) })
.catch(err => done(`couldn't call endpoint`)); .catch(() => done(`couldn't call endpoint`));
}); });
it('Should not change username if it contains "discord"', (done: Done) => { it('Should not change username if it contains "discord"', (done: Done) => {
@ -155,7 +155,7 @@ describe('setUsername', () => {
else done(); else done();
} }
}) })
.catch(err => done(`couldn't call endpoint`)); .catch(() => done(`couldn't call endpoint`));
}); });
it('Should be able to change username', (done: Done) => { it('Should be able to change username', (done: Done) => {
@ -163,13 +163,13 @@ describe('setUsername', () => {
fetch(`${getbaseURL()}/api/setUsername?userID=${user03PrivateUserID}&username=${encodeURIComponent(newUsername)}`, { fetch(`${getbaseURL()}/api/setUsername?userID=${user03PrivateUserID}&username=${encodeURIComponent(newUsername)}`, {
method: 'POST', method: 'POST',
}) })
.then(async res => { .then(async () => {
const usernameInfo = await getUsernameInfo(getHash(user03PrivateUserID)); const usernameInfo = await getUsernameInfo(getHash(user03PrivateUserID));
if (usernameInfo.userName !== newUsername) done(`Username did not change`); if (usernameInfo.userName !== newUsername) done(`Username did not change`);
if (usernameInfo.locked == "1") done(`Username was locked when it shouldn't have been`); if (usernameInfo.locked == "1") done(`Username was locked when it shouldn't have been`);
testUserNameChangelog(user03PrivateUserID, newUsername, username03, false, done); testUserNameChangelog(user03PrivateUserID, newUsername, username03, false, done);
}) })
.catch(err => done(`couldn't call endpoint`)); .catch(() => done(`couldn't call endpoint`));
}); });
it('Should not be able to change locked username', (done: Done) => { it('Should not be able to change locked username', (done: Done) => {
@ -177,13 +177,13 @@ describe('setUsername', () => {
fetch(`${getbaseURL()}/api/setUsername?userID=${user04PrivateUserID}&username=${encodeURIComponent(newUsername)}`, { fetch(`${getbaseURL()}/api/setUsername?userID=${user04PrivateUserID}&username=${encodeURIComponent(newUsername)}`, {
method: 'POST', method: 'POST',
}) })
.then(async res => { .then(async () => {
const usernameInfo = await getUsernameInfo(getHash(user04PrivateUserID)); const usernameInfo = await getUsernameInfo(getHash(user04PrivateUserID));
if (usernameInfo.userName === newUsername) done(`Username '${username04}' got changed to '${usernameInfo}'`); if (usernameInfo.userName === newUsername) done(`Username '${username04}' got changed to '${usernameInfo}'`);
if (usernameInfo.locked == "0") done(`Username was unlocked when it shouldn't have been`); if (usernameInfo.locked == "0") done(`Username was unlocked when it shouldn't have been`);
else done(); else done();
}) })
.catch(err => done(`couldn't call endpoint`)); .catch(() => done(`couldn't call endpoint`));
}); });
it('Should filter out unicode control characters', (done: Done) => { it('Should filter out unicode control characters', (done: Done) => {
@ -191,12 +191,12 @@ describe('setUsername', () => {
fetch(`${getbaseURL()}/api/setUsername?userID=${user05PrivateUserID}&username=${encodeURIComponent(newUsername)}`, { fetch(`${getbaseURL()}/api/setUsername?userID=${user05PrivateUserID}&username=${encodeURIComponent(newUsername)}`, {
method: 'POST', method: 'POST',
}) })
.then(async res => { .then(async () => {
const usernameInfo = await getUsernameInfo(getHash(user05PrivateUserID)); const usernameInfo = await getUsernameInfo(getHash(user05PrivateUserID));
if (usernameInfo.userName === newUsername) done(`Username contains unicode control characters`); if (usernameInfo.userName === newUsername) done(`Username contains unicode control characters`);
testUserNameChangelog(user05PrivateUserID, wellFormatUserName(newUsername), username05, false, done); testUserNameChangelog(user05PrivateUserID, wellFormatUserName(newUsername), username05, false, done);
}) })
.catch(err => done(`couldn't call endpoint`)); .catch(() => done(`couldn't call endpoint`));
}); });
it('Incorrect adminUserID should return 403', (done: Done) => { it('Incorrect adminUserID should return 403', (done: Done) => {
@ -208,7 +208,7 @@ describe('setUsername', () => {
if (res.status !== 403) done(`Status code was ${res.status}`); if (res.status !== 403) done(`Status code was ${res.status}`);
else done(); else done();
}) })
.catch(err => done(`couldn't call endpoint`)); .catch(() => done(`couldn't call endpoint`));
}); });
it('Admin should be able to change username', (done: Done) => { it('Admin should be able to change username', (done: Done) => {
@ -216,13 +216,13 @@ describe('setUsername', () => {
fetch(`${getbaseURL()}/api/setUsername?adminUserID=${adminPrivateUserID}&userID=${getHash(user06PrivateUserID)}&username=${encodeURIComponent(newUsername)}`, { fetch(`${getbaseURL()}/api/setUsername?adminUserID=${adminPrivateUserID}&userID=${getHash(user06PrivateUserID)}&username=${encodeURIComponent(newUsername)}`, {
method: 'POST', method: 'POST',
}) })
.then(async res => { .then(async () => {
const usernameInfo = await getUsernameInfo(getHash(user06PrivateUserID)); const usernameInfo = await getUsernameInfo(getHash(user06PrivateUserID));
if (usernameInfo.userName !== newUsername) done(`Failed to change username from '${username06}' to '${newUsername}'`); if (usernameInfo.userName !== newUsername) done(`Failed to change username from '${username06}' to '${newUsername}'`);
if (usernameInfo.locked == "0") done(`Username was not locked`); if (usernameInfo.locked == "0") done(`Username was not locked`);
else testUserNameChangelog(user06PrivateUserID, newUsername, username06, true, done); else testUserNameChangelog(user06PrivateUserID, newUsername, username06, true, done);
}) })
.catch(err => done(`couldn't call endpoint`)); .catch(() => done(`couldn't call endpoint`));
}); });
it('Admin should be able to change locked username', (done: Done) => { it('Admin should be able to change locked username', (done: Done) => {
@ -230,12 +230,12 @@ describe('setUsername', () => {
fetch(`${getbaseURL()}/api/setUsername?adminUserID=${adminPrivateUserID}&userID=${getHash(user07PrivateUserID)}&username=${encodeURIComponent(newUsername)}`, { fetch(`${getbaseURL()}/api/setUsername?adminUserID=${adminPrivateUserID}&userID=${getHash(user07PrivateUserID)}&username=${encodeURIComponent(newUsername)}`, {
method: 'POST', method: 'POST',
}) })
.then(async res => { .then(async () => {
const usernameInfo = await getUsernameInfo(getHash(user06PrivateUserID)); const usernameInfo = await getUsernameInfo(getHash(user06PrivateUserID));
if (usernameInfo.userName !== newUsername) done(`Failed to change username from '${username06}' to '${newUsername}'`); if (usernameInfo.userName !== newUsername) done(`Failed to change username from '${username06}' to '${newUsername}'`);
if (usernameInfo.locked == "0") done(`Username was unlocked when it shouldn't have been`); if (usernameInfo.locked == "0") done(`Username was unlocked when it shouldn't have been`);
else testUserNameChangelog(user07PrivateUserID, newUsername, username07, true, done); else testUserNameChangelog(user07PrivateUserID, newUsername, username07, true, done);
}) })
.catch(err => done(`couldn't call endpoint`)); .catch(() => done(`couldn't call endpoint`));
}); });
}); });

View file

@ -40,7 +40,7 @@ describe('shadowBanUser', () => {
} }
} }
}) })
.catch(err => done("Couldn't call endpoint")); .catch(() => done("Couldn't call endpoint"));
}); });
it('Should be able to unban user without unhiding submissions', (done: Done) => { it('Should be able to unban user without unhiding submissions', (done: Done) => {
@ -60,7 +60,7 @@ describe('shadowBanUser', () => {
} }
} }
}) })
.catch(err => done("Couldn't call endpoint")); .catch(() => done("Couldn't call endpoint"));
}); });
it('Should be able to ban user and hide submissions from only some categories', (done: Done) => { it('Should be able to ban user and hide submissions from only some categories', (done: Done) => {
@ -80,7 +80,7 @@ describe('shadowBanUser', () => {
} }
} }
}) })
.catch(err => done("Couldn't call endpoint")); .catch(() => done("Couldn't call endpoint"));
}); });
it('Should be able to unban user and unhide submissions', (done: Done) => { it('Should be able to unban user and unhide submissions', (done: Done) => {
@ -100,7 +100,7 @@ describe('shadowBanUser', () => {
} }
} }
}) })
.catch(err => done("Couldn't call endpoint")); .catch(() => done("Couldn't call endpoint"));
}); });
it('Should be able to unban user and unhide some submissions', (done: Done) => { it('Should be able to unban user and unhide some submissions', (done: Done) => {
@ -120,7 +120,7 @@ describe('shadowBanUser', () => {
} }
} }
}) })
.catch(err => done("Couldn't call endpoint")); .catch(() => done("Couldn't call endpoint"));
}); });
}); });

View file

@ -32,7 +32,7 @@ describe('unBan', () => {
}) })
.then(async res => { .then(async res => {
if (res.status === 200) { if (res.status === 200) {
let result = await db.prepare('all', 'SELECT * FROM "sponsorTimes" WHERE "videoID" = ? AND "userID" = ? AND "shadowHidden" = ?', ['unBan-videoID-0', 'testMan-unBan', 1]); const result = await db.prepare('all', 'SELECT * FROM "sponsorTimes" WHERE "videoID" = ? AND "userID" = ? AND "shadowHidden" = ?', ['unBan-videoID-0', 'testMan-unBan', 1]);
if (result.length !== 0) { if (result.length !== 0) {
console.log(result); console.log(result);
done("Expected 0 banned entrys in db, got " + result.length); done("Expected 0 banned entrys in db, got " + result.length);
@ -57,7 +57,7 @@ describe('unBan', () => {
}) })
.then(async res => { .then(async res => {
if (res.status === 200) { if (res.status === 200) {
let result = await db.prepare('all', 'SELECT * FROM "sponsorTimes" WHERE "videoID" = ? AND "userID" = ? AND "shadowHidden" = ?', ['unBan-videoID-1', 'testWoman-unBan', 1]); const result = await db.prepare('all', 'SELECT * FROM "sponsorTimes" WHERE "videoID" = ? AND "userID" = ? AND "shadowHidden" = ?', ['unBan-videoID-1', 'testWoman-unBan', 1]);
if (result.length !== 1) { if (result.length !== 1) {
console.log(result); console.log(result);
done("Expected 1 banned entry1 in db, got " + result.length); done("Expected 1 banned entry1 in db, got " + result.length);
@ -82,7 +82,7 @@ describe('unBan', () => {
}) })
.then(async res => { .then(async res => {
if (res.status === 200) { if (res.status === 200) {
let result = await db.prepare('all', 'SELECT * FROM "sponsorTimes" WHERE "userID" = ? AND "shadowHidden" = ?', ['testEntity-unBan', 1]); const result = await db.prepare('all', 'SELECT * FROM "sponsorTimes" WHERE "userID" = ? AND "shadowHidden" = ?', ['testEntity-unBan', 1]);
if (result.length !== 1) { if (result.length !== 1) {
console.log(result); console.log(result);
done("Expected 1 banned entry1 in db, got " + result.length); done("Expected 1 banned entry1 in db, got " + result.length);

View file

@ -67,7 +67,7 @@ describe('voteOnSponsorTime', () => {
+ "/api/voteOnSponsorTime?userID=randomID&UUID=vote-uuid-0&type=1") + "/api/voteOnSponsorTime?userID=randomID&UUID=vote-uuid-0&type=1")
.then(async res => { .then(async res => {
if (res.status === 200) { if (res.status === 200) {
let row = await db.prepare('get', `SELECT "votes" FROM "sponsorTimes" WHERE "UUID" = ?`, ["vote-uuid-0"]); const row = await db.prepare('get', `SELECT "votes" FROM "sponsorTimes" WHERE "UUID" = ?`, ["vote-uuid-0"]);
if (row.votes === 3) { if (row.votes === 3) {
done(); done();
} else { } else {
@ -85,7 +85,7 @@ describe('voteOnSponsorTime', () => {
+ "/api/voteOnSponsorTime?userID=randomID2&UUID=vote-uuid-2&type=0") + "/api/voteOnSponsorTime?userID=randomID2&UUID=vote-uuid-2&type=0")
.then(async res => { .then(async res => {
if (res.status === 200) { if (res.status === 200) {
let row = await db.prepare('get', `SELECT "votes" FROM "sponsorTimes" WHERE "UUID" = ?`, ["vote-uuid-2"]); const row = await db.prepare('get', `SELECT "votes" FROM "sponsorTimes" WHERE "UUID" = ?`, ["vote-uuid-2"]);
if (row.votes < 10) { if (row.votes < 10) {
done(); done();
} else { } else {
@ -103,7 +103,7 @@ describe('voteOnSponsorTime', () => {
+ "/api/voteOnSponsorTime?userID=randomID3&UUID=vote-uuid-2&type=0") + "/api/voteOnSponsorTime?userID=randomID3&UUID=vote-uuid-2&type=0")
.then(async res => { .then(async res => {
if (res.status === 200) { if (res.status === 200) {
let row = await db.prepare('get', `SELECT "votes" FROM "sponsorTimes" WHERE "UUID" = ?`, ["vote-uuid-2"]); const row = await db.prepare('get', `SELECT "votes" FROM "sponsorTimes" WHERE "UUID" = ?`, ["vote-uuid-2"]);
if (row.votes === 9) { if (row.votes === 9) {
done(); done();
} else { } else {
@ -121,7 +121,7 @@ describe('voteOnSponsorTime', () => {
+ "/api/voteOnSponsorTime?userID=randomID4&UUID=vote-uuid-1.6&type=0") + "/api/voteOnSponsorTime?userID=randomID4&UUID=vote-uuid-1.6&type=0")
.then(async res => { .then(async res => {
if (res.status === 200) { if (res.status === 200) {
let row = await db.prepare('get', `SELECT "votes" FROM "sponsorTimes" WHERE "UUID" = ?`, ["vote-uuid-1.6"]); const row = await db.prepare('get', `SELECT "votes" FROM "sponsorTimes" WHERE "UUID" = ?`, ["vote-uuid-1.6"]);
if (row.votes === 10) { if (row.votes === 10) {
done(); done();
} else { } else {
@ -139,7 +139,7 @@ describe('voteOnSponsorTime', () => {
+ "/api/voteOnSponsorTime?userID=hasNotSubmittedID&UUID=vote-uuid-1&type=1") + "/api/voteOnSponsorTime?userID=hasNotSubmittedID&UUID=vote-uuid-1&type=1")
.then(async res => { .then(async res => {
if (res.status === 200) { if (res.status === 200) {
let row = await db.prepare('get', `SELECT "votes" FROM "sponsorTimes" WHERE "UUID" = ?`, ["vote-uuid-1"]); const row = await db.prepare('get', `SELECT "votes" FROM "sponsorTimes" WHERE "UUID" = ?`, ["vote-uuid-1"]);
if (row.votes === 2) { if (row.votes === 2) {
done(); done();
} else { } else {
@ -157,7 +157,7 @@ describe('voteOnSponsorTime', () => {
+ "/api/voteOnSponsorTime?userID=hasNotSubmittedID&UUID=vote-uuid-1.5&type=0") + "/api/voteOnSponsorTime?userID=hasNotSubmittedID&UUID=vote-uuid-1.5&type=0")
.then(async res => { .then(async res => {
if (res.status === 200) { if (res.status === 200) {
let row = await db.prepare('get', `SELECT "votes" FROM "sponsorTimes" WHERE "UUID" = ?`, ["vote-uuid-1.5"]); const row = await db.prepare('get', `SELECT "votes" FROM "sponsorTimes" WHERE "UUID" = ?`, ["vote-uuid-1.5"]);
if (row.votes === 10) { if (row.votes === 10) {
done(); done();
} else { } else {
@ -175,7 +175,7 @@ describe('voteOnSponsorTime', () => {
+ "/api/voteOnSponsorTime?userID=VIPUser&UUID=vote-uuid-3&type=0") + "/api/voteOnSponsorTime?userID=VIPUser&UUID=vote-uuid-3&type=0")
.then(async res => { .then(async res => {
if (res.status === 200) { if (res.status === 200) {
let row = await db.prepare('get', `SELECT "votes" FROM "sponsorTimes" WHERE "UUID" = ?`, ["vote-uuid-3"]); const row = await db.prepare('get', `SELECT "votes" FROM "sponsorTimes" WHERE "UUID" = ?`, ["vote-uuid-3"]);
if (row.votes <= -2) { if (row.votes <= -2) {
done(); done();
} else { } else {
@ -193,7 +193,7 @@ describe('voteOnSponsorTime', () => {
+ "/api/voteOnSponsorTime?userID=own-submission-id&UUID=own-submission-uuid&type=0") + "/api/voteOnSponsorTime?userID=own-submission-id&UUID=own-submission-uuid&type=0")
.then(async res => { .then(async res => {
if (res.status === 200) { if (res.status === 200) {
let row = await db.prepare('get', `SELECT "votes" FROM "sponsorTimes" WHERE "UUID" = ?`, ["own-submission-uuid"]); const row = await db.prepare('get', `SELECT "votes" FROM "sponsorTimes" WHERE "UUID" = ?`, ["own-submission-uuid"]);
if (row.votes <= -2) { if (row.votes <= -2) {
done(); done();
} else { } else {
@ -211,7 +211,7 @@ describe('voteOnSponsorTime', () => {
+ "/api/voteOnSponsorTime?userID=randomID2&UUID=not-own-submission-uuid&type=0") + "/api/voteOnSponsorTime?userID=randomID2&UUID=not-own-submission-uuid&type=0")
.then(async res => { .then(async res => {
if (res.status === 200) { if (res.status === 200) {
let row = await db.prepare('get', `SELECT "votes" FROM "sponsorTimes" WHERE "UUID" = ?`, ["not-own-submission-uuid"]); const row = await db.prepare('get', `SELECT "votes" FROM "sponsorTimes" WHERE "UUID" = ?`, ["not-own-submission-uuid"]);
if (row.votes === 499) { if (row.votes === 499) {
done(); done();
} else { } else {
@ -229,8 +229,8 @@ describe('voteOnSponsorTime', () => {
+ "/api/voteOnSponsorTime?userID=randomID2&UUID=vote-uuid-4&category=intro") + "/api/voteOnSponsorTime?userID=randomID2&UUID=vote-uuid-4&category=intro")
.then(async res => { .then(async res => {
if (res.status === 200) { if (res.status === 200) {
let row = await db.prepare('get', `SELECT "category" FROM "sponsorTimes" WHERE "UUID" = ?`, ["vote-uuid-4"]); const row = await db.prepare('get', `SELECT "category" FROM "sponsorTimes" WHERE "UUID" = ?`, ["vote-uuid-4"]);
let categoryRows = await db.prepare('all', `SELECT votes, category FROM "categoryVotes" WHERE "UUID" = ?`, ["vote-uuid-4"]); const categoryRows = await db.prepare('all', `SELECT votes, category FROM "categoryVotes" WHERE "UUID" = ?`, ["vote-uuid-4"]);
if (row.category === "sponsor" && categoryRows.length === 2 if (row.category === "sponsor" && categoryRows.length === 2
&& categoryRows[0]?.votes === 1 && categoryRows[0]?.category === "intro" && categoryRows[0]?.votes === 1 && categoryRows[0]?.category === "intro"
&& categoryRows[1]?.votes === 1 && categoryRows[1]?.category === "sponsor") { && categoryRows[1]?.votes === 1 && categoryRows[1]?.category === "sponsor") {
@ -250,7 +250,7 @@ describe('voteOnSponsorTime', () => {
+ "/api/voteOnSponsorTime?userID=randomID2&UUID=incorrect-category&category=fakecategory") + "/api/voteOnSponsorTime?userID=randomID2&UUID=incorrect-category&category=fakecategory")
.then(async res => { .then(async res => {
if (res.status === 400) { if (res.status === 400) {
let row = await db.prepare('get', `SELECT "category" FROM "sponsorTimes" WHERE "UUID" = ?`, ["incorrect-category"]); const row = await db.prepare('get', `SELECT "category" FROM "sponsorTimes" WHERE "UUID" = ?`, ["incorrect-category"]);
if (row.category === "sponsor") { if (row.category === "sponsor") {
done(); done();
} else { } else {
@ -268,7 +268,7 @@ describe('voteOnSponsorTime', () => {
+ "/api/voteOnSponsorTime?userID=randomID2&UUID=incorrect-category&category=highlight") + "/api/voteOnSponsorTime?userID=randomID2&UUID=incorrect-category&category=highlight")
.then(async res => { .then(async res => {
if (res.status === 400) { if (res.status === 400) {
let row = await db.prepare('get', `SELECT "category" FROM "sponsorTimes" WHERE "UUID" = ?`, ["incorrect-category"]); const row = await db.prepare('get', `SELECT "category" FROM "sponsorTimes" WHERE "UUID" = ?`, ["incorrect-category"]);
if (row.category === "sponsor") { if (row.category === "sponsor") {
done(); done();
} else { } else {
@ -286,8 +286,8 @@ describe('voteOnSponsorTime', () => {
+ "/api/voteOnSponsorTime?userID=randomID2&UUID=vote-uuid-4&category=outro") + "/api/voteOnSponsorTime?userID=randomID2&UUID=vote-uuid-4&category=outro")
.then(async res => { .then(async res => {
if (res.status === 200) { if (res.status === 200) {
let submissionRow = await db.prepare('get', `SELECT "category" FROM "sponsorTimes" WHERE "UUID" = ?`, ["vote-uuid-4"]); const submissionRow = await db.prepare('get', `SELECT "category" FROM "sponsorTimes" WHERE "UUID" = ?`, ["vote-uuid-4"]);
let categoryRows = await db.prepare('all', `SELECT votes, category FROM "categoryVotes" WHERE "UUID" = ?`, ["vote-uuid-4"]); const categoryRows = await db.prepare('all', `SELECT votes, category FROM "categoryVotes" WHERE "UUID" = ?`, ["vote-uuid-4"]);
let introVotes = 0; let introVotes = 0;
let outroVotes = 0; let outroVotes = 0;
let sponsorVotes = 0; let sponsorVotes = 0;
@ -315,8 +315,8 @@ describe('voteOnSponsorTime', () => {
const vote = (inputCat: string, assertCat: string, callback: Done) => { const vote = (inputCat: string, assertCat: string, callback: Done) => {
fetch(getbaseURL() fetch(getbaseURL()
+ "/api/voteOnSponsorTime?userID=randomID2&UUID=incorrect-category-change&category=" + inputCat) + "/api/voteOnSponsorTime?userID=randomID2&UUID=incorrect-category-change&category=" + inputCat)
.then(async res => { .then(async () => {
let row = await db.prepare('get', `SELECT "category" FROM "sponsorTimes" WHERE "UUID" = ?`, ["incorrect-category-change"]); const row = await db.prepare('get', `SELECT "category" FROM "sponsorTimes" WHERE "UUID" = ?`, ["incorrect-category-change"]);
if (row.category === assertCat) { if (row.category === assertCat) {
callback(); callback();
} else { } else {
@ -336,8 +336,8 @@ describe('voteOnSponsorTime', () => {
+ "/api/voteOnSponsorTime?userID=VIPUser&UUID=vote-uuid-5&category=outro") + "/api/voteOnSponsorTime?userID=VIPUser&UUID=vote-uuid-5&category=outro")
.then(async res => { .then(async res => {
if (res.status === 200) { if (res.status === 200) {
let row = await db.prepare('get', `SELECT "category" FROM "sponsorTimes" WHERE "UUID" = ?`, ["vote-uuid-5"]); const row = await db.prepare('get', `SELECT "category" FROM "sponsorTimes" WHERE "UUID" = ?`, ["vote-uuid-5"]);
let row2 = await db.prepare('get', `SELECT votes FROM "categoryVotes" WHERE "UUID" = ? and category = ?`, ["vote-uuid-5", "outro"]); const row2 = await db.prepare('get', `SELECT votes FROM "categoryVotes" WHERE "UUID" = ? and category = ?`, ["vote-uuid-5", "outro"]);
if (row.category === "outro" && row2.votes === 500) { if (row.category === "outro" && row2.votes === 500) {
done(); done();
} else { } else {
@ -355,7 +355,7 @@ describe('voteOnSponsorTime', () => {
+ "/api/voteOnSponsorTime?userID=testman&UUID=vote-uuid-5_1&category=outro") + "/api/voteOnSponsorTime?userID=testman&UUID=vote-uuid-5_1&category=outro")
.then(async res => { .then(async res => {
if (res.status === 200) { if (res.status === 200) {
let row = await db.prepare('get', `SELECT "category" FROM "sponsorTimes" WHERE "UUID" = ?`, ["vote-uuid-5"]); const row = await db.prepare('get', `SELECT "category" FROM "sponsorTimes" WHERE "UUID" = ?`, ["vote-uuid-5"]);
if (row.category === "outro") { if (row.category === "outro") {
done(); done();
} else { } else {
@ -385,7 +385,7 @@ describe('voteOnSponsorTime', () => {
fetch(getbaseURL() fetch(getbaseURL()
+ "/api/voteOnSponsorTime?userID=randomID2&UUID=vote-uuid-5&type=1") + "/api/voteOnSponsorTime?userID=randomID2&UUID=vote-uuid-5&type=1")
.then(async res => { .then(async res => {
let row = await db.prepare('get', `SELECT "votes" FROM "sponsorTimes" WHERE "UUID" = ?`, ["vote-uuid-5"]); const row = await db.prepare('get', `SELECT "votes" FROM "sponsorTimes" WHERE "UUID" = ?`, ["vote-uuid-5"]);
if (res.status === 403 && row.votes === -3) { if (res.status === 403 && row.votes === -3) {
done(); done();
} else { } else {
@ -399,7 +399,7 @@ describe('voteOnSponsorTime', () => {
fetch(getbaseURL() fetch(getbaseURL()
+ "/api/voteOnSponsorTime?userID=randomID2&UUID=vote-uuid-5&type=0") + "/api/voteOnSponsorTime?userID=randomID2&UUID=vote-uuid-5&type=0")
.then(async res => { .then(async res => {
let row = await db.prepare('get', `SELECT "votes" FROM "sponsorTimes" WHERE "UUID" = ?`, ["vote-uuid-5"]); const row = await db.prepare('get', `SELECT "votes" FROM "sponsorTimes" WHERE "UUID" = ?`, ["vote-uuid-5"]);
if (res.status === 200 && row.votes === -3) { if (res.status === 200 && row.votes === -3) {
done(); done();
} else { } else {
@ -414,7 +414,7 @@ describe('voteOnSponsorTime', () => {
+ "/api/voteOnSponsorTime?userID=VIPUser&UUID=vote-uuid-5&type=1") + "/api/voteOnSponsorTime?userID=VIPUser&UUID=vote-uuid-5&type=1")
.then(async res => { .then(async res => {
if (res.status === 200) { if (res.status === 200) {
let row = await db.prepare('get', `SELECT "votes" FROM "sponsorTimes" WHERE "UUID" = ?`, ["vote-uuid-5"]); const row = await db.prepare('get', `SELECT "votes" FROM "sponsorTimes" WHERE "UUID" = ?`, ["vote-uuid-5"]);
if (row.votes > -3) { if (row.votes > -3) {
done(); done();
} else { } else {
@ -444,7 +444,7 @@ describe('voteOnSponsorTime', () => {
fetch(getbaseURL() fetch(getbaseURL()
+ "/api/voteOnSponsorTime?userID=randomID&UUID=no-sponsor-segments-uuid-0&type=0") + "/api/voteOnSponsorTime?userID=randomID&UUID=no-sponsor-segments-uuid-0&type=0")
.then(async res => { .then(async res => {
let row = await db.prepare('get', `SELECT "votes" FROM "sponsorTimes" WHERE "UUID" = ?`, ["no-sponsor-segments-uuid-0"]); const row = await db.prepare('get', `SELECT "votes" FROM "sponsorTimes" WHERE "UUID" = ?`, ["no-sponsor-segments-uuid-0"]);
if (res.status === 200 && row.votes === 2) { if (res.status === 200 && row.votes === 2) {
done(); done();
} else { } else {
@ -458,7 +458,7 @@ describe('voteOnSponsorTime', () => {
fetch(getbaseURL() fetch(getbaseURL()
+ "/api/voteOnSponsorTime?userID=randomID&UUID=no-sponsor-segments-uuid-0&type=1") + "/api/voteOnSponsorTime?userID=randomID&UUID=no-sponsor-segments-uuid-0&type=1")
.then(async res => { .then(async res => {
let row = await db.prepare('get', `SELECT "votes" FROM "sponsorTimes" WHERE "UUID" = ?`, ["no-sponsor-segments-uuid-0"]); const row = await db.prepare('get', `SELECT "votes" FROM "sponsorTimes" WHERE "UUID" = ?`, ["no-sponsor-segments-uuid-0"]);
if (res.status === 200 && row.votes === 3) { if (res.status === 200 && row.votes === 3) {
done(); done();
} else { } else {
@ -472,7 +472,7 @@ describe('voteOnSponsorTime', () => {
fetch(getbaseURL() fetch(getbaseURL()
+ "/api/voteOnSponsorTime?userID=randomID&UUID=no-sponsor-segments-uuid-0&category=outro") + "/api/voteOnSponsorTime?userID=randomID&UUID=no-sponsor-segments-uuid-0&category=outro")
.then(async res => { .then(async res => {
let row = await db.prepare('get', `SELECT "category" FROM "sponsorTimes" WHERE "UUID" = ?`, ["no-sponsor-segments-uuid-0"]); const row = await db.prepare('get', `SELECT "category" FROM "sponsorTimes" WHERE "UUID" = ?`, ["no-sponsor-segments-uuid-0"]);
if (res.status === 200 && row.category === "sponsor") { if (res.status === 200 && row.category === "sponsor") {
done(); done();
} else { } else {
@ -487,7 +487,7 @@ describe('voteOnSponsorTime', () => {
+ "/api/voteOnSponsorTime?userID=VIPUser&UUID=segment-locking-uuid-1&type=1") + "/api/voteOnSponsorTime?userID=VIPUser&UUID=segment-locking-uuid-1&type=1")
.then(async res => { .then(async res => {
if (res.status === 200) { if (res.status === 200) {
let row = await db.prepare('get', `SELECT "locked" FROM "sponsorTimes" WHERE "UUID" = ?`, ["segment-locking-uuid-1"]); const row = await db.prepare('get', `SELECT "locked" FROM "sponsorTimes" WHERE "UUID" = ?`, ["segment-locking-uuid-1"]);
if (row?.locked) { if (row?.locked) {
done(); done();
} else { } else {
@ -505,7 +505,7 @@ describe('voteOnSponsorTime', () => {
+ "/api/voteOnSponsorTime?userID=VIPUser&UUID=segment-locking-uuid-1&type=0") + "/api/voteOnSponsorTime?userID=VIPUser&UUID=segment-locking-uuid-1&type=0")
.then(async res => { .then(async res => {
if (res.status === 200) { if (res.status === 200) {
let row = await db.prepare('get', `SELECT "locked" FROM "sponsorTimes" WHERE "UUID" = ?`, ["segment-locking-uuid-1"]); const row = await db.prepare('get', `SELECT "locked" FROM "sponsorTimes" WHERE "UUID" = ?`, ["segment-locking-uuid-1"]);
if (!row?.locked) { if (!row?.locked) {
done(); done();
} else { } else {
@ -523,7 +523,7 @@ describe('voteOnSponsorTime', () => {
+ "/api/voteOnSponsorTime?userID=VIPUser&UUID=segment-hidden-uuid-1&type=1") + "/api/voteOnSponsorTime?userID=VIPUser&UUID=segment-hidden-uuid-1&type=1")
.then(async res => { .then(async res => {
if (res.status === 200) { if (res.status === 200) {
let row = await db.prepare('get', `SELECT "hidden" FROM "sponsorTimes" WHERE "UUID" = ?`, ["segment-hidden-uuid-1"]); const row = await db.prepare('get', `SELECT "hidden" FROM "sponsorTimes" WHERE "UUID" = ?`, ["segment-hidden-uuid-1"]);
if (!row?.hidden) { if (!row?.hidden) {
done(); done();
} else { } else {
@ -541,7 +541,7 @@ describe('voteOnSponsorTime', () => {
+ "/api/voteOnSponsorTime?userID=randomID2&UUID=vote-uuid-2&type=20") + "/api/voteOnSponsorTime?userID=randomID2&UUID=vote-uuid-2&type=20")
.then(async res => { .then(async res => {
if (res.status === 200) { if (res.status === 200) {
let row = await db.prepare('get', `SELECT "votes" FROM "sponsorTimes" WHERE "UUID" = ?`, ["vote-uuid-2"]); const row = await db.prepare('get', `SELECT "votes" FROM "sponsorTimes" WHERE "UUID" = ?`, ["vote-uuid-2"]);
if (row.votes === 10) { if (row.votes === 10) {
done(); done();
} else { } else {
@ -560,7 +560,7 @@ describe('voteOnSponsorTime', () => {
if (res.status !== 400) done('non 400 (' + res.status + ')'); if (res.status !== 400) done('non 400 (' + res.status + ')');
else done(); // pass else done(); // pass
}) })
.catch(err => done('couldn\'t call endpoint')); .catch(() => done('couldn\'t call endpoint'));
}); });
it('Should not be able to vote with type 11', (done: Done) => { it('Should not be able to vote with type 11', (done: Done) => {
@ -569,7 +569,7 @@ describe('voteOnSponsorTime', () => {
if (res.status !== 400) done('non 400 (' + res.status + ')'); if (res.status !== 400) done('non 400 (' + res.status + ')');
else done(); // pass else done(); // pass
}) })
.catch(err => done('couldn\'t call endpoint')); .catch(() => done('couldn\'t call endpoint'));
}); });
}); });

View file

@ -1,6 +1,6 @@
import {config} from '../src/config'; import {config} from '../src/config';
export function getbaseURL() { export function getbaseURL(): string {
return "http://localhost:" + config.port; return "http://localhost:" + config.port;
} }

View file

@ -1,7 +1,7 @@
import { APIVideoData, APIVideoInfo } from "../src/types/youtubeApi.model"; import { APIVideoData, APIVideoInfo } from "../src/types/youtubeApi.model";
export class YouTubeApiMock { export class YouTubeApiMock {
static async listVideos(videoID: string, ignoreCache = false): Promise<APIVideoInfo> { static async listVideos(videoID: string): Promise<APIVideoInfo> {
const obj = { const obj = {
id: videoID id: videoID
}; };