Add eslint rules for dealing with promises

This commit is contained in:
Ajay 2022-09-07 20:01:11 -04:00
parent 0ca134dc8f
commit bd7dfc63ff
15 changed files with 79 additions and 63 deletions

View file

@ -29,4 +29,18 @@ module.exports = {
"semi": "warn", "semi": "warn",
"no-console": "warn" "no-console": "warn"
}, },
overrides: [
{
files: ["src/**/*.ts"],
parserOptions: {
project: ["./tsconfig.json"],
},
rules: {
"@typescript-eslint/no-misused-promises": "warn",
"@typescript-eslint/no-floating-promises" : "warn"
}
},
],
}; };

View file

@ -85,18 +85,18 @@ function setupRoutes(router: Router) {
} }
//add the get function //add the get function
router.get("/api/getVideoSponsorTimes", oldGetVideoSponsorTimes); router.get("/api/getVideoSponsorTimes", void oldGetVideoSponsorTimes);
//add the oldpost function //add the oldpost function
router.get("/api/postVideoSponsorTimes", oldSubmitSponsorTimes); router.get("/api/postVideoSponsorTimes", void oldSubmitSponsorTimes);
router.post("/api/postVideoSponsorTimes", oldSubmitSponsorTimes); router.post("/api/postVideoSponsorTimes", void oldSubmitSponsorTimes);
//add the skip segments functions //add the skip segments functions
router.get("/api/skipSegments", getSkipSegments); router.get("/api/skipSegments", void getSkipSegments);
router.post("/api/skipSegments", postSkipSegments); router.post("/api/skipSegments", void postSkipSegments);
// add the privacy protecting skip segments functions // add the privacy protecting skip segments functions
router.get("/api/skipSegments/:prefix", getSkipSegmentsByHash); router.get("/api/skipSegments/:prefix", void getSkipSegmentsByHash);
//voting endpoint //voting endpoint
router.get("/api/voteOnSponsorTime", ...voteEndpoints); router.get("/api/voteOnSponsorTime", ...voteEndpoints);
@ -107,106 +107,106 @@ function setupRoutes(router: Router) {
router.post("/api/viewedVideoSponsorTime", ...viewEndpoints); router.post("/api/viewedVideoSponsorTime", ...viewEndpoints);
//To set your username for the stats view //To set your username for the stats view
router.post("/api/setUsername", setUsername); router.post("/api/setUsername", void setUsername);
//get what username this user has //get what username this user has
router.get("/api/getUsername", getUsername); router.get("/api/getUsername", void getUsername);
//Endpoint used to hide a certain user's data //Endpoint used to hide a certain user's data
router.post("/api/shadowBanUser", shadowBanUser); router.post("/api/shadowBanUser", void shadowBanUser);
//Endpoint used to make a user a VIP user with special privileges //Endpoint used to make a user a VIP user with special privileges
router.post("/api/addUserAsVIP", addUserAsVIP); router.post("/api/addUserAsVIP", void addUserAsVIP);
//Endpoint to add a user as a temporary VIP //Endpoint to add a user as a temporary VIP
router.post("/api/addUserAsTempVIP", addUserAsTempVIP); router.post("/api/addUserAsTempVIP", void addUserAsTempVIP);
//Gets all the views added up for one userID //Gets all the views added up for one userID
//Useful to see how much one user has contributed //Useful to see how much one user has contributed
router.get("/api/getViewsForUser", getViewsForUser); router.get("/api/getViewsForUser", void getViewsForUser);
//Gets all the saved time added up (views * sponsor length) for one userID //Gets all the saved time added up (views * sponsor length) for one userID
//Useful to see how much one user has contributed //Useful to see how much one user has contributed
//In minutes //In minutes
router.get("/api/getSavedTimeForUser", getSavedTimeForUser); router.get("/api/getSavedTimeForUser", void getSavedTimeForUser);
router.get("/api/getTopUsers", getTopUsers); router.get("/api/getTopUsers", void getTopUsers);
router.get("/api/getTopCategoryUsers", getTopCategoryUsers); router.get("/api/getTopCategoryUsers", void getTopCategoryUsers);
//send out totals //send out totals
//send the total submissions, total views and total minutes saved //send the total submissions, total views and total minutes saved
router.get("/api/getTotalStats", getTotalStats); router.get("/api/getTotalStats", void getTotalStats);
router.get("/api/getUserInfo", getUserInfo); router.get("/api/getUserInfo", void getUserInfo);
router.get("/api/userInfo", getUserInfo); router.get("/api/userInfo", void getUserInfo);
//send out a formatted time saved total //send out a formatted time saved total
router.get("/api/getDaysSavedFormatted", getDaysSavedFormatted); router.get("/api/getDaysSavedFormatted", void getDaysSavedFormatted);
//submit video to lock categories //submit video to lock categories
router.post("/api/noSegments", postLockCategories); router.post("/api/noSegments", void postLockCategories);
router.post("/api/lockCategories", postLockCategories); router.post("/api/lockCategories", void postLockCategories);
router.delete("/api/noSegments", deleteLockCategoriesEndpoint); router.delete("/api/noSegments", void deleteLockCategoriesEndpoint);
router.delete("/api/lockCategories", deleteLockCategoriesEndpoint); router.delete("/api/lockCategories", void deleteLockCategoriesEndpoint);
//get if user is a vip //get if user is a vip
router.get("/api/isUserVIP", getIsUserVIP); router.get("/api/isUserVIP", void getIsUserVIP);
//sent user a warning //sent user a warning
router.post("/api/warnUser", postWarning); router.post("/api/warnUser", void postWarning);
//get if user is a vip //get if user is a vip
router.post("/api/segmentShift", postSegmentShift); router.post("/api/segmentShift", void postSegmentShift);
//get segment info //get segment info
router.get("/api/segmentInfo", getSegmentInfo); router.get("/api/segmentInfo", void getSegmentInfo);
//clear cache as VIP //clear cache as VIP
router.post("/api/clearCache", postClearCache); router.post("/api/clearCache", void postClearCache);
//purge all segments for VIP //purge all segments for VIP
router.post("/api/purgeAllSegments", postPurgeAllSegments); router.post("/api/purgeAllSegments", void postPurgeAllSegments);
router.post("/api/unlistedVideo", addUnlistedVideo); router.post("/api/unlistedVideo", void addUnlistedVideo);
// get userID from username // get userID from username
router.get("/api/userID", getUserID); router.get("/api/userID", void getUserID);
// get lock categores from userID // get lock categores from userID
router.get("/api/lockCategories", getLockCategories); router.get("/api/lockCategories", void getLockCategories);
// get privacy protecting lock categories functions // get privacy protecting lock categories functions
router.get("/api/lockCategories/:prefix", getLockCategoriesByHash); router.get("/api/lockCategories/:prefix", void getLockCategoriesByHash);
// get all segments that match a search // get all segments that match a search
router.get("/api/searchSegments", getSearchSegments); router.get("/api/searchSegments", void getSearchSegments);
// autocomplete chapter names // autocomplete chapter names
router.get("/api/chapterNames", getChapterNames); router.get("/api/chapterNames", void getChapterNames);
// get status // get status
router.get("/api/status/:value", getStatus); router.get("/api/status/:value", void getStatus);
router.get("/api/status", getStatus); router.get("/api/status", void getStatus);
router.get("/api/youtubeApiProxy", youtubeApiProxy); router.get("/api/youtubeApiProxy", void youtubeApiProxy);
// get user category stats // get user category stats
router.get("/api/userStats", getUserStats); router.get("/api/userStats", void getUserStats);
router.get("/api/lockReason", getLockReason); router.get("/api/lockReason", void getLockReason);
router.post("/api/feature", addFeature); router.post("/api/feature", void addFeature);
router.get("/api/generateToken/:type", generateTokenRequest); router.get("/api/generateToken/:type", void generateTokenRequest);
router.get("/api/verifyToken", verifyTokenRequest); router.get("/api/verifyToken", void verifyTokenRequest);
if (config.postgres?.enabled) { if (config.postgres?.enabled) {
router.get("/database", (req, res) => dumpDatabase(req, res, true)); router.get("/database", (req, res) => void dumpDatabase(req, res, true));
router.get("/database.json", (req, res) => dumpDatabase(req, res, false)); router.get("/database.json", (req, res) => void dumpDatabase(req, res, false));
router.get("/database/*", downloadFile); router.get("/database/*", void downloadFile);
router.use("/download", express.static(appExportPath)); router.use("/download", express.static(appExportPath));
} 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

@ -57,7 +57,7 @@ export const archiveDownvoteSegment = async (dayLimit: number, voteLimit: number
const DownvoteSegmentArchiveJob = new CronJob( const DownvoteSegmentArchiveJob = new CronJob(
jobConfig?.schedule || "0 0 * * * 0", jobConfig?.schedule || "0 0 * * * 0",
() => archiveDownvoteSegment(jobConfig?.timeThresholdInDays, jobConfig?.voteThreshold) () => void archiveDownvoteSegment(jobConfig?.timeThresholdInDays, jobConfig?.voteThreshold)
); );
if (serverConfig?.crons?.enabled && jobConfig && !jobConfig.schedule) { if (serverConfig?.crons?.enabled && jobConfig && !jobConfig.schedule) {

View file

@ -177,7 +177,7 @@ export class Postgres implements IDatabase {
); );
} }
client.end(); client.end().catch(err => Logger.error(`closing db (postgres): ${err}`));
} }
private async upgradeDB(fileNamePrefix: string, schemaFolder: string) { private async upgradeDB(fileNamePrefix: string, schemaFolder: string) {

View file

@ -27,4 +27,4 @@ async function init() {
}).setTimeout(15000); }).setTimeout(15000);
} }
init(); init().catch((err) => Logger.error(err));

View file

@ -22,6 +22,7 @@ export function rateLimitMiddleware(limitConfig: RateLimitConfig, getUserID?: (r
keyGenerator: (req) => { keyGenerator: (req) => {
return getHash(getIP(req), 1); return getHash(getIP(req), 1);
}, },
// eslint-disable-next-line @typescript-eslint/no-misused-promises
handler: async (req, res, next) => { handler: async (req, res, next) => {
if (getUserID === undefined || !await isUserVIP(await getHashCache(getUserID(req)))) { if (getUserID === undefined || !await isUserVIP(await getHashCache(getUserID(req)))) {
return res.status(limitConfig.statusCode).send(limitConfig.message); return res.status(limitConfig.statusCode).send(limitConfig.message);

View file

@ -75,6 +75,7 @@ function removeOutdatedDumps(exportPath: string): Promise<void> {
}, {}); }, {});
// read files in export directory // read files in export directory
// eslint-disable-next-line @typescript-eslint/no-misused-promises
fs.readdir(exportPath, async (err: any, files: string[]) => { fs.readdir(exportPath, async (err: any, files: string[]) => {
if (err) Logger.error(err); if (err) Logger.error(err);
if (err) return resolve(); if (err) return resolve();

View file

@ -4,7 +4,7 @@ import { config } from "../config";
import { Request, Response } from "express"; import { Request, Response } from "express";
const MILLISECONDS_IN_MINUTE = 60000; const MILLISECONDS_IN_MINUTE = 60000;
const getTopCategoryUsersWithCache = createMemoryCache(generateTopCategoryUsersStats, config.getTopUsersCacheTimeMinutes * MILLISECONDS_IN_MINUTE); const getTopCategoryUsersWithCache = createMemoryCache(void generateTopCategoryUsersStats, config.getTopUsersCacheTimeMinutes * MILLISECONDS_IN_MINUTE);
const maxRewardTimePerSegmentInSeconds = config.maxRewardTimePerSegmentInSeconds ?? 86400; const maxRewardTimePerSegmentInSeconds = config.maxRewardTimePerSegmentInSeconds ?? 86400;
interface DBSegment { interface DBSegment {

View file

@ -4,7 +4,7 @@ import { config } from "../config";
import { Request, Response } from "express"; import { Request, Response } from "express";
const MILLISECONDS_IN_MINUTE = 60000; const MILLISECONDS_IN_MINUTE = 60000;
const getTopUsersWithCache = createMemoryCache(generateTopUsersStats, config.getTopUsersCacheTimeMinutes * MILLISECONDS_IN_MINUTE); const getTopUsersWithCache = createMemoryCache(void generateTopUsersStats, config.getTopUsersCacheTimeMinutes * MILLISECONDS_IN_MINUTE);
const maxRewardTimePerSegmentInSeconds = config.maxRewardTimePerSegmentInSeconds ?? 86400; const maxRewardTimePerSegmentInSeconds = config.maxRewardTimePerSegmentInSeconds ?? 86400;
async function generateTopUsersStats(sortBy: string, categoryStatsEnabled = false) { async function generateTopUsersStats(sortBy: string, categoryStatsEnabled = false) {

View file

@ -76,7 +76,7 @@ async function sendWebhooks(apiVideoInfo: APIVideoInfo, userID: string, videoID:
sendWebhookNotification(userID, videoID, UUID, userSubmissionCountRow.submissionCount, data, { sendWebhookNotification(userID, videoID, UUID, userSubmissionCountRow.submissionCount, data, {
submissionStart: startTime, submissionStart: startTime,
submissionEnd: endTime, submissionEnd: endTime,
}, segmentInfo); }, segmentInfo).catch(Logger.error);
// If it is a first time submission // If it is a first time submission
// Then send a notification to discord // Then send a notification to discord
@ -395,7 +395,7 @@ async function updateDataIfVideoDurationChange(videoID: VideoID, service: Servic
await db.prepare("run", `UPDATE "sponsorTimes" SET "hidden" = 1 WHERE "UUID" = ?`, [submission.UUID]); await db.prepare("run", `UPDATE "sponsorTimes" SET "hidden" = 1 WHERE "UUID" = ?`, [submission.UUID]);
} }
lockedCategoryList = []; lockedCategoryList = [];
deleteLockCategories(videoID, null, null, service); deleteLockCategories(videoID, null, null, service).catch(Logger.error);
} }
return { return {
@ -614,7 +614,7 @@ export async function postSkipSegments(req: Request, res: Response): Promise<Res
} }
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).catch(Logger.error);
} }
return res.json(newSegments); return res.json(newSegments);
} }

View file

@ -25,7 +25,7 @@ export async function verifyTokenRequest(req: VerifyTokenRequest, res: Response)
const identity = await getPatreonIdentity(tokens.accessToken); const identity = await getPatreonIdentity(tokens.accessToken);
if (tokens.expiresIn < 15 * 24 * 60 * 60) { if (tokens.expiresIn < 15 * 24 * 60 * 60) {
refreshToken(TokenType.patreon, licenseKey, tokens.refreshToken); refreshToken(TokenType.patreon, licenseKey, tokens.refreshToken).catch(Logger.error);
} }
if (identity) { if (identity) {

View file

@ -412,7 +412,7 @@ export async function vote(ip: IPAddress, UUID: SegmentUUID, paramUserID: UserID
// no restrictions on checkDuration // no restrictions on checkDuration
// check duration of all submissions on this video // check duration of all submissions on this video
if (type <= 0) { if (type <= 0) {
checkVideoDuration(UUID); checkVideoDuration(UUID).catch(Logger.error);
} }
try { try {
@ -525,7 +525,7 @@ export async function vote(ip: IPAddress, UUID: SegmentUUID, paramUserID: UserID
incrementAmount, incrementAmount,
oldIncrementAmount, oldIncrementAmount,
finalResponse finalResponse
}); }).catch(Logger.error);
} }
return { status: finalResponse.finalStatus, message: finalResponse.finalMessage ?? undefined }; return { status: finalResponse.finalStatus, message: finalResponse.finalMessage ?? undefined };
} catch (err) { } catch (err) {

View file

@ -53,7 +53,7 @@ async function getAndSplit<T, U extends string>(fetchFromDB: (values: U[]) => Pr
if (valuesToBeFetched.length > 0) { if (valuesToBeFetched.length > 0) {
data = await fetchFromDB(valuesToBeFetched); data = await fetchFromDB(valuesToBeFetched);
new Promise(() => { void new Promise(() => {
const newResults: Record<string, T[]> = {}; const newResults: Record<string, T[]> = {};
for (const item of data) { for (const item of data) {
const splitValue = (item as unknown as Record<string, string>)[splitKey]; const splitValue = (item as unknown as Record<string, string>)[splitKey];

View file

@ -28,7 +28,7 @@ let exportClient: RedisSB = {
if (config.redis?.enabled) { if (config.redis?.enabled) {
Logger.info("Connected to redis"); Logger.info("Connected to redis");
const client = createClient(config.redis); const client = createClient(config.redis);
client.connect(); void client.connect(); // void as we don't care about the promise
exportClient = client as RedisSB; exportClient = client as RedisSB;
const get = client.get.bind(client); const get = client.get.bind(client);
@ -40,7 +40,7 @@ if (config.redis?.enabled) {
}).catch((err) => reject(err)); }).catch((err) => reject(err));
}); });
exportClient.increment = (key) => new Promise((resolve, reject) => exportClient.increment = (key) => new Promise((resolve, reject) =>
client.multi() void client.multi()
.incr(key) .incr(key)
.expire(key, 60) .expire(key, 60)
.exec() .exec()

View file

@ -39,8 +39,8 @@ export class YouTubeAPI {
} }
const apiResult = data as APIVideoData; const apiResult = data as APIVideoData;
DiskCache.set(cacheKey, apiResult) DiskCache.set(cacheKey, apiResult)
.catch((err: any) => Logger.warn(err)) .then(() => Logger.debug(`YouTube API: video information cache set for: ${videoID}`))
.then(() => Logger.debug(`YouTube API: video information cache set for: ${videoID}`)); .catch((err: any) => Logger.warn(err));
return { err: false, data: apiResult }; return { err: false, data: apiResult };
} else { } else {