add getHashCache where applicable=

This commit is contained in:
Michael C
2021-11-27 02:41:34 -05:00
parent 7e1550f3c0
commit a5a90e3c84
24 changed files with 90 additions and 47 deletions

View File

@@ -1,5 +1,6 @@
import { getIP } from "../utils/getIP"; import { getIP } from "../utils/getIP";
import { getHash } from "../utils/getHash"; import { getHash } from "../utils/getHash";
import { getHashCache } from "../utils/getHashCache";
import rateLimit from "express-rate-limit"; import rateLimit from "express-rate-limit";
import { RateLimitConfig } from "../types/config.model"; import { RateLimitConfig } from "../types/config.model";
import { Request } from "express"; import { Request } from "express";
@@ -17,7 +18,7 @@ export function rateLimitMiddleware(limitConfig: RateLimitConfig, getUserID?: (r
return getHash(getIP(req), 1); return getHash(getIP(req), 1);
}, },
handler: async (req, res, next) => { handler: async (req, res, next) => {
if (getUserID === undefined || !await isUserVIP(getHash(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);
} else { } else {
return next(); return next();

View File

@@ -1,4 +1,4 @@
import { getHash } from "../utils/getHash"; import { getHashCache } from "../utils/getHashCache";
import { db } from "../databases/databases"; import { db } from "../databases/databases";
import { config } from "../config"; import { config } from "../config";
import { Request, Response } from "express"; import { Request, Response } from "express";
@@ -24,7 +24,7 @@ export async function addUserAsVIP(req: AddUserAsVIPRequest, res: Response): Pro
} }
// hash the userID // hash the userID
const adminUserIDInput = getHash(adminUserID); const adminUserIDInput = await getHashCache(adminUserID);
if (adminUserIDInput !== config.adminUserID) { if (adminUserIDInput !== config.adminUserID) {
// not authorized // not authorized

View File

@@ -1,6 +1,6 @@
import { Request, Response } from "express"; import { Request, Response } from "express";
import { isUserVIP } from "../utils/isUserVIP"; import { isUserVIP } from "../utils/isUserVIP";
import { getHash } from "../utils/getHash"; import { getHashCache } from "../utils/getHashCache";
import { db } from "../databases/databases"; import { db } from "../databases/databases";
import { Category, Service, VideoID } from "../types/segments.model"; import { Category, Service, VideoID } from "../types/segments.model";
import { UserID } from "../types/user.model"; import { UserID } from "../types/user.model";
@@ -39,7 +39,7 @@ export async function deleteLockCategoriesEndpoint(req: DeleteLockCategoriesRequ
} }
// Check if user is VIP // Check if user is VIP
const hashedUserID = getHash(userID); const hashedUserID = await getHashCache(userID);
const userIsVIP = await isUserVIP(hashedUserID); const userIsVIP = await isUserVIP(hashedUserID);
if (!userIsVIP) { if (!userIsVIP) {

View File

@@ -1,5 +1,5 @@
import { Logger } from "../utils/logger"; import { Logger } from "../utils/logger";
import { getHash } from "../utils/getHash"; import { getHashCache } from "../utils/getHashCache";
import { isUserVIP } from "../utils/isUserVIP"; 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";
@@ -13,7 +13,7 @@ export async function getIsUserVIP(req: Request, res: Response): Promise<Respons
} }
//hash the userID //hash the userID
const hashedUserID: HashedUserID = getHash(userID); const hashedUserID: HashedUserID = await getHashCache(userID);
try { try {
const vipState = await isUserVIP(hashedUserID); const vipState = await isUserVIP(hashedUserID);

View File

@@ -1,6 +1,6 @@
import { db } from "../databases/databases"; import { db } from "../databases/databases";
import { Request, Response } from "express"; import { Request, Response } from "express";
import { getHash } from "../utils/getHash"; import { getHashCache } from "../utils/getHashCache";
import { config } from "../config"; import { config } from "../config";
import { Logger } from "../utils/logger"; import { Logger } from "../utils/logger";
@@ -15,7 +15,7 @@ export async function getSavedTimeForUser(req: Request, res: Response): Promise<
} }
//hash the userID //hash the userID
userID = getHash(userID); userID = await getHashCache(userID);
try { try {
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]); 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]);

View File

@@ -5,7 +5,7 @@ import { skipSegmentsHashKey, skipSegmentsKey } from "../utils/redisKeys";
import { SBRecord } from "../types/lib.model"; import { SBRecord } from "../types/lib.model";
import { ActionType, Category, CategoryActionType, DBSegment, HashedIP, IPAddress, OverlappingSegmentGroup, Segment, SegmentCache, SegmentUUID, Service, VideoData, VideoID, VideoIDHash, Visibility, VotableObject } from "../types/segments.model"; import { ActionType, Category, CategoryActionType, DBSegment, HashedIP, IPAddress, OverlappingSegmentGroup, Segment, SegmentCache, SegmentUUID, Service, VideoData, VideoID, VideoIDHash, Visibility, VotableObject } from "../types/segments.model";
import { getCategoryActionType } from "../utils/categoryInfo"; import { getCategoryActionType } from "../utils/categoryInfo";
import { getHash } from "../utils/getHash"; import { getHashCache } from "../utils/getHashCache";
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";
@@ -33,10 +33,10 @@ async function prepareCategorySegments(req: Request, videoID: VideoID, category:
} }
//if this isn't their ip, don't send it to them //if this isn't their ip, don't send it to them
return cache.shadowHiddenSegmentIPs[videoID][segment.timeSubmitted]?.some((shadowHiddenSegment) => { return cache.shadowHiddenSegmentIPs[videoID][segment.timeSubmitted]?.some(async (shadowHiddenSegment) => {
if (cache.userHashedIP === undefined) { if (cache.userHashedIP === undefined) {
//hash the IP only if it's strictly necessary //hash the IP only if it's strictly necessary
cache.userHashedIP = getHash((getIP(req) + config.globalSalt) as IPAddress); cache.userHashedIP = await getHashCache((getIP(req) + config.globalSalt) as IPAddress);
} }
return shadowHiddenSegment.hashedIP === cache.userHashedIP; return shadowHiddenSegment.hashedIP === cache.userHashedIP;

View File

@@ -1,5 +1,5 @@
import { db } from "../databases/databases"; import { db } from "../databases/databases";
import { getHash } from "../utils/getHash"; import { getHashCache } from "../utils/getHashCache";
import { isUserVIP } from "../utils/isUserVIP"; import { isUserVIP } from "../utils/isUserVIP";
import { Request, Response } from "express"; import { Request, Response } from "express";
import { Logger } from "../utils/logger"; import { Logger } from "../utils/logger";
@@ -134,7 +134,7 @@ const dbGetValue = (userID: HashedUserID, property: string): Promise<string|Segm
async function getUserInfo(req: Request, res: Response): Promise<Response> { 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 ? await getHashCache(userID) : req.query.publicUserID as HashedUserID;
const defaultProperties: string[] = ["userID", "userName", "minutesSaved", "segmentCount", "ignoredSegmentCount", const defaultProperties: string[] = ["userID", "userName", "minutesSaved", "segmentCount", "ignoredSegmentCount",
"viewCount", "ignoredViewCount", "warnings", "warningReason", "reputation", "viewCount", "ignoredViewCount", "warnings", "warningReason", "reputation",
"vip", "lastSegmentID"]; "vip", "lastSegmentID"];

View File

@@ -1,5 +1,5 @@
import { db } from "../databases/databases"; import { db } from "../databases/databases";
import { getHash } from "../utils/getHash"; import { getHashCache } from "../utils/getHashCache";
import { Request, Response } from "express"; import { Request, Response } from "express";
import { HashedUserID, UserID } from "../types/user.model"; import { HashedUserID, UserID } from "../types/user.model";
import { config } from "../config"; import { config } from "../config";
@@ -78,7 +78,7 @@ async function dbGetUsername(userID: HashedUserID) {
export async function getUserStats(req: Request, res: Response): Promise<Response> { export async function getUserStats(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 ? await getHashCache(userID) : req.query.publicUserID as HashedUserID;
const fetchCategoryStats = req.query.fetchCategoryStats == "true"; const fetchCategoryStats = req.query.fetchCategoryStats == "true";
const fetchActionTypeStats = req.query.fetchActionTypeStats == "true"; const fetchActionTypeStats = req.query.fetchActionTypeStats == "true";

View File

@@ -1,5 +1,5 @@
import { db } from "../databases/databases"; import { db } from "../databases/databases";
import { getHash } from "../utils/getHash"; import { getHashCache } from "../utils/getHashCache";
import { Logger } from "../utils/logger"; import { Logger } from "../utils/logger";
import { Request, Response } from "express"; import { Request, Response } from "express";
@@ -12,7 +12,7 @@ export async function getUsername(req: Request, res: Response): Promise<Response
} }
//hash the userID //hash the userID
userID = getHash(userID); userID = await getHashCache(userID);
try { try {
const 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]);

View File

@@ -1,6 +1,6 @@
import { db } from "../databases/databases"; import { db } from "../databases/databases";
import { Request, Response } from "express"; import { Request, Response } from "express";
import { getHash } from "../utils/getHash"; import { getHashCache } from "../utils/getHashCache";
import { Logger } from "../utils/logger"; import { Logger } from "../utils/logger";
export async function getViewsForUser(req: Request, res: Response): Promise<Response> { export async function getViewsForUser(req: Request, res: Response): Promise<Response> {
@@ -12,7 +12,7 @@ export async function getViewsForUser(req: Request, res: Response): Promise<Resp
} }
//hash the userID //hash the userID
userID = getHash(userID); userID = await getHashCache(userID);
try { try {
const 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]);

View File

@@ -1,6 +1,6 @@
import { Logger } from "../utils/logger"; import { Logger } from "../utils/logger";
import { HashedUserID, UserID } from "../types/user.model"; import { HashedUserID, UserID } from "../types/user.model";
import { getHash } from "../utils/getHash"; import { getHashCache } from "../utils/getHashCache";
import { Request, Response } from "express"; import { Request, Response } from "express";
import { Service, VideoID } from "../types/segments.model"; import { Service, VideoID } from "../types/segments.model";
import { QueryCacher } from "../utils/queryCacher"; import { QueryCacher } from "../utils/queryCacher";
@@ -28,9 +28,9 @@ export async function postClearCache(req: Request, res: Response): Promise<Respo
} }
// hash the userID as early as possible // hash the userID as early as possible
const hashedUserID: HashedUserID = getHash(userID); const hashedUserID: HashedUserID = await getHashCache(userID);
// hash videoID // hash videoID
const hashedVideoID: VideoIDHash = getHash(videoID, 1); const hashedVideoID: VideoIDHash = await getHashCache(videoID, 1);
// Ensure user is a VIP // Ensure user is a VIP
if (!(await isUserVIP(hashedUserID))){ if (!(await isUserVIP(hashedUserID))){

View File

@@ -1,5 +1,5 @@
import { Logger } from "../utils/logger"; import { Logger } from "../utils/logger";
import { getHash } from "../utils/getHash"; import { getHashCache } from "../utils/getHashCache";
import { isUserVIP } from "../utils/isUserVIP"; 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";
@@ -28,7 +28,7 @@ export async function postLockCategories(req: Request, res: Response): Promise<s
} }
// Check if user is VIP // Check if user is VIP
userID = getHash(userID); userID = await getHashCache(userID);
const userIsVIP = await isUserVIP(userID); const userIsVIP = await isUserVIP(userID);
if (!userIsVIP) { if (!userIsVIP) {
@@ -62,7 +62,7 @@ export async function postLockCategories(req: Request, res: Response): Promise<s
}); });
// calculate hash of videoID // calculate hash of videoID
const hashedVideoID: VideoIDHash = getHash(videoID, 1); const hashedVideoID: VideoIDHash = await getHashCache(videoID, 1);
// create database entry // create database entry
for (const category of categoriesToMark) { for (const category of categoriesToMark) {

View File

@@ -1,5 +1,5 @@
import { Logger } from "../utils/logger"; import { Logger } from "../utils/logger";
import { getHash } from "../utils/getHash"; import { getHashCache } from "../utils/getHashCache";
import { isUserVIP } from "../utils/isUserVIP"; 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";
@@ -18,7 +18,7 @@ export async function postPurgeAllSegments(req: Request, res: Response): Promise
} }
//hash the userID //hash the userID
const hashedUserID: HashedUserID = getHash(userID); const hashedUserID: HashedUserID = await getHashCache(userID);
try { try {
const vipState = await isUserVIP(hashedUserID); const vipState = await isUserVIP(hashedUserID);
@@ -30,7 +30,7 @@ export async function postPurgeAllSegments(req: Request, res: Response): Promise
await db.prepare("run", `UPDATE "sponsorTimes" SET "hidden" = 1 WHERE "videoID" = ?`, [videoID]); await db.prepare("run", `UPDATE "sponsorTimes" SET "hidden" = 1 WHERE "videoID" = ?`, [videoID]);
const hashedVideoID: VideoIDHash = getHash(videoID, 1); const hashedVideoID: VideoIDHash = await getHashCache(videoID, 1);
QueryCacher.clearSegmentCache({ QueryCacher.clearSegmentCache({
videoID, videoID,
hashedVideoID, hashedVideoID,

View File

@@ -1,7 +1,7 @@
import { Request, Response } from "express"; import { Request, Response } from "express";
import { Logger } from "../utils/logger"; import { Logger } from "../utils/logger";
import { isUserVIP } from "../utils/isUserVIP"; import { isUserVIP } from "../utils/isUserVIP";
import { getHash } from "../utils/getHash"; import { getHashCache } from "../utils/getHashCache";
import { db } from "../databases/databases"; import { db } from "../databases/databases";
const ACTION_NONE = Symbol("none"); const ACTION_NONE = Symbol("none");
@@ -64,7 +64,7 @@ export async function postSegmentShift(req: Request, res: Response): Promise<Res
} }
// Check if user is VIP // Check if user is VIP
userID = getHash(userID); userID = await getHashCache(userID);
const userIsVIP = await isUserVIP(userID); const userIsVIP = await isUserVIP(userID);
if (!userIsVIP) { if (!userIsVIP) {

View File

@@ -4,6 +4,7 @@ import { db, privateDB } from "../databases/databases";
import { getMaxResThumbnail, YouTubeAPI } from "../utils/youtubeApi"; import { getMaxResThumbnail, YouTubeAPI } from "../utils/youtubeApi";
import { getSubmissionUUID } from "../utils/getSubmissionUUID"; import { getSubmissionUUID } from "../utils/getSubmissionUUID";
import { getHash } from "../utils/getHash"; import { getHash } from "../utils/getHash";
import { getHashCache } from "../utils/getHashCache";
import { getIP } from "../utils/getIP"; import { getIP } from "../utils/getIP";
import { getFormattedTime } from "../utils/getFormattedTime"; import { getFormattedTime } from "../utils/getFormattedTime";
import { dispatchEvent } from "../utils/webhookUtils"; import { dispatchEvent } from "../utils/webhookUtils";
@@ -580,7 +581,7 @@ export async function postSkipSegments(req: Request, res: Response): Promise<Res
} }
//hash the userID //hash the userID
userID = getHash(userID); userID = await getHashCache(userID);
const userWarningCheckResult = await checkUserActiveWarning(userID); const userWarningCheckResult = await checkUserActiveWarning(userID);
if (!userWarningCheckResult.pass) { if (!userWarningCheckResult.pass) {
@@ -615,7 +616,7 @@ export async function postSkipSegments(req: Request, res: Response): Promise<Res
const newSegments = []; const newSegments = [];
//hash the ip 5000 times so no one can get it from the database //hash the ip 5000 times so no one can get it from the database
const hashedIP = getHash(getIP(req) + config.globalSalt); const hashedIP = await getHashCache(getIP(req) + config.globalSalt);
try { try {
//get current time //get current time

View File

@@ -2,7 +2,7 @@ import { Request, Response } from "express";
import { Logger } from "../utils/logger"; import { Logger } from "../utils/logger";
import { db } from "../databases/databases"; import { db } from "../databases/databases";
import { isUserVIP } from "../utils/isUserVIP"; import { isUserVIP } from "../utils/isUserVIP";
import { getHash } from "../utils/getHash"; import { getHashCache } from "../utils/getHashCache";
import { HashedUserID, UserID } from "../types/user.model"; import { HashedUserID, UserID } from "../types/user.model";
import { config } from "../config"; import { config } from "../config";
@@ -25,7 +25,7 @@ export async function postWarning(req: Request, res: Response): Promise<Response
// exit early if no body passed in // exit early if no body passed in
if (!req.body.userID && !req.body.issuerUserID) return res.status(400).json({ "message": "Missing parameters" }); if (!req.body.userID && !req.body.issuerUserID) return res.status(400).json({ "message": "Missing parameters" });
// Collect user input data // Collect user input data
const issuerUserID: HashedUserID = getHash(<UserID> req.body.issuerUserID); const issuerUserID: HashedUserID = await getHashCache(<UserID> req.body.issuerUserID);
const userID: UserID = req.body.userID; const userID: UserID = req.body.userID;
const issueTime = new Date().getTime(); const issueTime = new Date().getTime();
const enabled: boolean = req.body.enabled ?? true; const enabled: boolean = req.body.enabled ?? true;

View File

@@ -1,6 +1,7 @@
import { Logger } from "../../utils/logger"; import { Logger } from "../../utils/logger";
import { HashedUserID, UserID } from "../../types/user.model"; import { HashedUserID, UserID } from "../../types/user.model";
import { getHash } from "../../utils/getHash"; import { getHash } from "../../utils/getHash";
import { getHashCache } from "../../utils/getHashCache";
import { Request, Response } from "express"; import { Request, Response } from "express";
import { Service, VideoID } from "../../types/segments.model"; import { Service, VideoID } from "../../types/segments.model";
import { QueryCacher } from "../../utils/queryCacher"; import { QueryCacher } from "../../utils/queryCacher";
@@ -28,7 +29,7 @@ export async function postClearCache(req: Request, res: Response): Promise<Respo
} }
// hash the userID as early as possible // hash the userID as early as possible
const hashedUserID: HashedUserID = getHash(userID); const hashedUserID: HashedUserID = await getHashCache(userID);
// hash videoID // hash videoID
const hashedVideoID: VideoIDHash = getHash(videoID, 1); const hashedVideoID: VideoIDHash = getHash(videoID, 1);

View File

@@ -1,5 +1,6 @@
import { db, privateDB } from "../../databases/databases"; import { db, privateDB } from "../../databases/databases";
import { getHash } from "../../utils/getHash"; import { getHash } from "../../utils/getHash";
import { getHashCache } from "../../utils/getHashCache";
import { Logger } from "../../utils/logger"; import { Logger } from "../../utils/logger";
import { Request, Response } from "express"; import { Request, Response } from "express";
import { HashedUserID, UserID } from "../../types/user.model"; import { HashedUserID, UserID } from "../../types/user.model";
@@ -25,7 +26,7 @@ export async function postRating(req: Request, res: Response): Promise<Response>
} }
const hashedIP: HashedIP = getHash(getIP(req) + config.globalSalt as IPAddress, 1); const hashedIP: HashedIP = getHash(getIP(req) + config.globalSalt as IPAddress, 1);
const hashedUserID: HashedUserID = getHash(privateUserID); const hashedUserID: HashedUserID = await getHashCache(privateUserID);
const hashedVideoID = getHash(videoID, 1); const hashedVideoID = getHash(videoID, 1);
try { try {

View File

@@ -1,7 +1,7 @@
import { config } from "../config"; import { config } from "../config";
import { Logger } from "../utils/logger"; import { Logger } from "../utils/logger";
import { db, privateDB } from "../databases/databases"; import { db, privateDB } from "../databases/databases";
import { getHash } from "../utils/getHash"; import { getHashCache } from "../utils/getHashCache";
import { Request, Response } from "express"; import { Request, Response } from "express";
function logUserNameChange(userID: string, newUserName: string, oldUserName: string, updatedByAdmin: boolean): Promise<Response> { function logUserNameChange(userID: string, newUserName: string, oldUserName: string, updatedByAdmin: boolean): Promise<Response> {
@@ -34,7 +34,7 @@ export async function setUsername(req: Request, res: Response): Promise<Response
if (adminUserIDInput != undefined) { if (adminUserIDInput != undefined) {
//this is the admin controlling the other users account, don't hash the controling account's ID //this is the admin controlling the other users account, don't hash the controling account's ID
adminUserIDInput = getHash(adminUserIDInput); adminUserIDInput = await getHashCache(adminUserIDInput);
if (adminUserIDInput != config.adminUserID) { if (adminUserIDInput != config.adminUserID) {
//they aren't the admin //they aren't the admin
@@ -42,7 +42,7 @@ export async function setUsername(req: Request, res: Response): Promise<Response
} }
} else { } else {
//hash the userID //hash the userID
userID = getHash(userID); userID = await getHashCache(userID);
} }
try { try {

View File

@@ -1,5 +1,5 @@
import { db } from "../databases/databases"; import { db } from "../databases/databases";
import { getHash } from "../utils/getHash"; import { getHashCache } from "../utils/getHashCache";
import { Request, Response } from "express"; import { Request, Response } from "express";
import { config } from "../config"; import { config } from "../config";
import { Category, Service, VideoID, VideoIDHash } from "../types/segments.model"; import { Category, Service, VideoID, VideoIDHash } from "../types/segments.model";
@@ -28,7 +28,7 @@ export async function shadowBanUser(req: Request, res: Response): Promise<Respon
} }
//hash the userID //hash the userID
const adminUserID = getHash(adminUserIDInput); const adminUserID = await getHashCache(adminUserIDInput);
const isVIP = await isUserVIP(adminUserID); const isVIP = await isUserVIP(adminUserID);
if (!isVIP) { if (!isVIP) {

View File

@@ -7,7 +7,7 @@ import { db, privateDB } from "../databases/databases";
import { dispatchEvent, getVoteAuthor, getVoteAuthorRaw } from "../utils/webhookUtils"; import { dispatchEvent, getVoteAuthor, getVoteAuthorRaw } from "../utils/webhookUtils";
import { getFormattedTime } from "../utils/getFormattedTime"; import { getFormattedTime } from "../utils/getFormattedTime";
import { getIP } from "../utils/getIP"; import { getIP } from "../utils/getIP";
import { getHash } from "../utils/getHash"; import { getHashCache } from "../utils/getHashCache";
import { config } from "../config"; import { config } from "../config";
import { UserID } from "../types/user.model"; import { UserID } from "../types/user.model";
import { Category, CategoryActionType, HashedIP, IPAddress, SegmentUUID, Service, VideoID, VideoIDHash, Visibility, VideoDuration } from "../types/segments.model"; import { Category, CategoryActionType, HashedIP, IPAddress, SegmentUUID, Service, VideoID, VideoIDHash, Visibility, VideoDuration } from "../types/segments.model";
@@ -292,8 +292,8 @@ export async function voteOnSponsorTime(req: Request, res: Response): Promise<Re
} }
//hash the userID //hash the userID
const nonAnonUserID = getHash(paramUserID); const nonAnonUserID = await getHashCache(paramUserID);
const userID = getHash(paramUserID + UUID); const userID = await getHashCache(paramUserID + UUID);
// To force a non 200, change this early // To force a non 200, change this early
const finalResponse: FinalResponse = { const finalResponse: FinalResponse = {
@@ -308,7 +308,7 @@ export async function voteOnSponsorTime(req: Request, res: Response): Promise<Re
const ip = getIP(req); const ip = getIP(req);
//hash the ip 5000 times so no one can get it from the database //hash the ip 5000 times so no one can get it from the database
const hashedIP: HashedIP = getHash((ip + config.globalSalt) as IPAddress); const hashedIP: HashedIP = await getHashCache((ip + config.globalSalt) as IPAddress);
//check if this user is on the vip list //check if this user is on the vip list
const isVIP = await isUserVIP(nonAnonUserID); const isVIP = await isUserVIP(nonAnonUserID);

32
src/utils/getHashCache.ts Normal file
View File

@@ -0,0 +1,32 @@
import redis from "../utils/redis";
import { userHashKey } from "../utils/redisKeys";
import { HashedValue } from "../types/hash.model";
import { Logger } from "../utils/logger";
import { getHash } from "../utils/getHash";
export async function getHashCache<T extends string>(value: T, times = 5000): Promise<T & HashedValue> {
if (times === 5000) {
const hashKey = getHash(value, 1);
const result: HashedValue = await getFromRedis(hashKey);
return result as T & HashedValue;
}
return getHash(value, times);
}
async function getFromRedis<T extends string>(key: HashedValue): Promise<T & HashedValue> {
const redisKey = userHashKey(key);
const { err, reply } = await redis.getAsync(redisKey);
if (!err && reply) {
try {
Logger.debug(`Got data from redis: ${reply}`);
return reply as T & HashedValue;
} catch (e) {
// If all else, continue on hashing
}
}
const data = getHash(key, 5000-1);
redis.setAsync(key, data);
return data as T & HashedValue;
}

View File

@@ -1,5 +1,6 @@
import { Service, VideoID, VideoIDHash } from "../types/segments.model"; import { Service, VideoID, VideoIDHash } from "../types/segments.model";
import { UserID } from "../types/user.model"; import { UserID } from "../types/user.model";
import { HashedValue } from "../types/hash.model";
import { Logger } from "./logger"; import { Logger } from "./logger";
export function skipSegmentsKey(videoID: VideoID, service: Service): string { export function skipSegmentsKey(videoID: VideoID, service: Service): string {
@@ -23,3 +24,9 @@ export function ratingHashKey(hashPrefix: VideoIDHash, service: Service): string
return `rating.${service}.${hashPrefix}`; return `rating.${service}.${hashPrefix}`;
} }
export function userHashKey(userID: HashedValue): string {
if (userID.length !== 64) Logger.warn(`Redis userHash key is not length 64! ${userID}`);
return `user.${userID}`;
}