mirror of
https://github.com/ajayyy/SponsorBlockServer.git
synced 2025-12-08 12:37:00 +03:00
fix dearrow bans
This commit is contained in:
@@ -14,6 +14,7 @@ import crypto from "crypto";
|
|||||||
import { QueryCacher } from "../utils/queryCacher";
|
import { QueryCacher } from "../utils/queryCacher";
|
||||||
import { acquireLock } from "../utils/redisLock";
|
import { acquireLock } from "../utils/redisLock";
|
||||||
import { hasFeature } from "../utils/features";
|
import { hasFeature } from "../utils/features";
|
||||||
|
import { checkBanStatus } from "../utils/checkBan";
|
||||||
|
|
||||||
enum BrandingType {
|
enum BrandingType {
|
||||||
Title,
|
Title,
|
||||||
@@ -43,6 +44,7 @@ export async function postBranding(req: Request, res: Response) {
|
|||||||
const isVip = await isUserVIP(hashedUserID);
|
const isVip = await isUserVIP(hashedUserID);
|
||||||
const hashedVideoID = await getHashCache(videoID, 1);
|
const hashedVideoID = await getHashCache(videoID, 1);
|
||||||
const hashedIP = await getHashCache(getIP(req) + config.globalSalt as IPAddress);
|
const hashedIP = await getHashCache(getIP(req) + config.globalSalt as IPAddress);
|
||||||
|
const isBanned = await checkBanStatus(hashedUserID, hashedIP);
|
||||||
|
|
||||||
const lock = await acquireLock(`postBranding:${videoID}.${hashedUserID}`);
|
const lock = await acquireLock(`postBranding:${videoID}.${hashedUserID}`);
|
||||||
if (!lock.status) {
|
if (!lock.status) {
|
||||||
@@ -61,7 +63,11 @@ export async function postBranding(req: Request, res: Response) {
|
|||||||
|
|
||||||
await Promise.all([(async () => {
|
await Promise.all([(async () => {
|
||||||
if (title) {
|
if (title) {
|
||||||
|
// ignore original submissions from banned users - hiding those would cause issues
|
||||||
|
if (title.original && isBanned) return;
|
||||||
|
|
||||||
const existingUUID = (await db.prepare("get", `SELECT "UUID" from "titles" where "videoID" = ? AND "title" = ?`, [videoID, title.title]))?.UUID;
|
const existingUUID = (await db.prepare("get", `SELECT "UUID" from "titles" where "videoID" = ? AND "title" = ?`, [videoID, title.title]))?.UUID;
|
||||||
|
if (existingUUID != undefined && isBanned) return; // ignore votes on existing details from banned users
|
||||||
const UUID = existingUUID || crypto.randomUUID();
|
const UUID = existingUUID || crypto.randomUUID();
|
||||||
|
|
||||||
const existingVote = await handleExistingVotes(BrandingType.Title, videoID, hashedUserID, UUID, hashedIP, voteType);
|
const existingVote = await handleExistingVotes(BrandingType.Title, videoID, hashedUserID, UUID, hashedIP, voteType);
|
||||||
@@ -72,8 +78,8 @@ export async function postBranding(req: Request, res: Response) {
|
|||||||
[videoID, title.title, title.original ? 1 : 0, hashedUserID, service, hashedVideoID, now, UUID]);
|
[videoID, title.title, title.original ? 1 : 0, hashedUserID, service, hashedVideoID, now, UUID]);
|
||||||
|
|
||||||
const verificationValue = await getVerificationValue(hashedUserID, isVip);
|
const verificationValue = await getVerificationValue(hashedUserID, isVip);
|
||||||
await db.prepare("run", `INSERT INTO "titleVotes" ("UUID", "votes", "locked", "shadowHidden", "verification") VALUES (?, 0, ?, 0, ?);`,
|
await db.prepare("run", `INSERT INTO "titleVotes" ("UUID", "votes", "locked", "shadowHidden", "verification") VALUES (?, 0, ?, ?, ?);`,
|
||||||
[UUID, isVip ? 1 : 0, verificationValue]);
|
[UUID, isVip ? 1 : 0, isBanned ? 1 : 0, verificationValue]);
|
||||||
|
|
||||||
await verifyOldSubmissions(hashedUserID, verificationValue);
|
await verifyOldSubmissions(hashedUserID, verificationValue);
|
||||||
}
|
}
|
||||||
@@ -85,10 +91,14 @@ export async function postBranding(req: Request, res: Response) {
|
|||||||
}
|
}
|
||||||
})(), (async () => {
|
})(), (async () => {
|
||||||
if (thumbnail) {
|
if (thumbnail) {
|
||||||
|
// ignore original submissions from banned users - hiding those would cause issues
|
||||||
|
if (thumbnail.original && isBanned) return;
|
||||||
|
|
||||||
const existingUUID = thumbnail.original
|
const existingUUID = thumbnail.original
|
||||||
? (await db.prepare("get", `SELECT "UUID" from "thumbnails" where "videoID" = ? AND "original" = 1`, [videoID]))?.UUID
|
? (await db.prepare("get", `SELECT "UUID" from "thumbnails" where "videoID" = ? AND "original" = 1`, [videoID]))?.UUID
|
||||||
: (await db.prepare("get", `SELECT "thumbnails"."UUID" from "thumbnailTimestamps" JOIN "thumbnails" ON "thumbnails"."UUID" = "thumbnailTimestamps"."UUID"
|
: (await db.prepare("get", `SELECT "thumbnails"."UUID" from "thumbnailTimestamps" JOIN "thumbnails" ON "thumbnails"."UUID" = "thumbnailTimestamps"."UUID"
|
||||||
WHERE "thumbnailTimestamps"."timestamp" = ? AND "thumbnails"."videoID" = ?`, [(thumbnail as TimeThumbnailSubmission).timestamp, videoID]))?.UUID;
|
WHERE "thumbnailTimestamps"."timestamp" = ? AND "thumbnails"."videoID" = ?`, [(thumbnail as TimeThumbnailSubmission).timestamp, videoID]))?.UUID;
|
||||||
|
if (existingUUID != undefined && isBanned) return; // ignore votes on existing details from banned users
|
||||||
const UUID = existingUUID || crypto.randomUUID();
|
const UUID = existingUUID || crypto.randomUUID();
|
||||||
|
|
||||||
const existingVote = await handleExistingVotes(BrandingType.Thumbnail, videoID, hashedUserID, UUID, hashedIP, voteType);
|
const existingVote = await handleExistingVotes(BrandingType.Thumbnail, videoID, hashedUserID, UUID, hashedIP, voteType);
|
||||||
@@ -98,8 +108,8 @@ export async function postBranding(req: Request, res: Response) {
|
|||||||
await db.prepare("run", `INSERT INTO "thumbnails" ("videoID", "original", "userID", "service", "hashedVideoID", "timeSubmitted", "UUID") VALUES (?, ?, ?, ?, ?, ?, ?)`,
|
await db.prepare("run", `INSERT INTO "thumbnails" ("videoID", "original", "userID", "service", "hashedVideoID", "timeSubmitted", "UUID") VALUES (?, ?, ?, ?, ?, ?, ?)`,
|
||||||
[videoID, thumbnail.original ? 1 : 0, hashedUserID, service, hashedVideoID, now, UUID]);
|
[videoID, thumbnail.original ? 1 : 0, hashedUserID, service, hashedVideoID, now, UUID]);
|
||||||
|
|
||||||
await db.prepare("run", `INSERT INTO "thumbnailVotes" ("UUID", "votes", "locked", "shadowHidden") VALUES (?, 0, ?, 0)`,
|
await db.prepare("run", `INSERT INTO "thumbnailVotes" ("UUID", "votes", "locked", "shadowHidden") VALUES (?, 0, ?, ?)`,
|
||||||
[UUID, isVip ? 1 : 0]);
|
[UUID, isVip ? 1 : 0, isBanned ? 1 : 0]);
|
||||||
|
|
||||||
if (!thumbnail.original) {
|
if (!thumbnail.original) {
|
||||||
await db.prepare("run", `INSERT INTO "thumbnailTimestamps" ("UUID", "timestamp") VALUES (?, ?)`,
|
await db.prepare("run", `INSERT INTO "thumbnailTimestamps" ("UUID", "timestamp") VALUES (?, ?)`,
|
||||||
|
|||||||
@@ -16,6 +16,7 @@ describe("postBranding", () => {
|
|||||||
const userID6 = `PostBrandingUser6${".".repeat(16)}`;
|
const userID6 = `PostBrandingUser6${".".repeat(16)}`;
|
||||||
const userID7 = `PostBrandingUser7${".".repeat(16)}`;
|
const userID7 = `PostBrandingUser7${".".repeat(16)}`;
|
||||||
const userID8 = `PostBrandingUser8${".".repeat(16)}`;
|
const userID8 = `PostBrandingUser8${".".repeat(16)}`;
|
||||||
|
const bannedUser = `BannedPostBrandingUser${".".repeat(16)}`;
|
||||||
|
|
||||||
|
|
||||||
const endpoint = "/api/branding";
|
const endpoint = "/api/branding";
|
||||||
@@ -36,6 +37,9 @@ describe("postBranding", () => {
|
|||||||
await db.prepare("run", insertVipUserQuery, [getHash(vipUser)]);
|
await db.prepare("run", insertVipUserQuery, [getHash(vipUser)]);
|
||||||
await db.prepare("run", insertVipUserQuery, [getHash(vipUser2)]);
|
await db.prepare("run", insertVipUserQuery, [getHash(vipUser2)]);
|
||||||
|
|
||||||
|
const insertBannedUserQuery = 'INSERT INTO "shadowBannedUsers" ("userID") VALUES (?)';
|
||||||
|
await db.prepare("run", insertBannedUserQuery, [getHash(bannedUser)]);
|
||||||
|
|
||||||
const insertTitleQuery = 'INSERT INTO "titles" ("videoID", "title", "original", "userID", "service", "hashedVideoID", "timeSubmitted", "UUID") VALUES (?, ?, ?, ?, ?, ?, ?, ?)';
|
const insertTitleQuery = 'INSERT INTO "titles" ("videoID", "title", "original", "userID", "service", "hashedVideoID", "timeSubmitted", "UUID") VALUES (?, ?, ?, ?, ?, ?, ?, ?)';
|
||||||
await db.prepare("run", insertTitleQuery, ["postBrandLocked1", "Some title", 0, getHash(userID1), Service.YouTube, getHash("postBrandLocked1"), Date.now(), "postBrandLocked1"]);
|
await db.prepare("run", insertTitleQuery, ["postBrandLocked1", "Some title", 0, getHash(userID1), Service.YouTube, getHash("postBrandLocked1"), Date.now(), "postBrandLocked1"]);
|
||||||
await db.prepare("run", insertTitleQuery, ["postBrandLocked2", "Some title", 1, getHash(userID2), Service.YouTube, getHash("postBrandLocked2"), Date.now(), "postBrandLocked2"]);
|
await db.prepare("run", insertTitleQuery, ["postBrandLocked2", "Some title", 1, getHash(userID2), Service.YouTube, getHash("postBrandLocked2"), Date.now(), "postBrandLocked2"]);
|
||||||
@@ -61,6 +65,18 @@ describe("postBranding", () => {
|
|||||||
await db.prepare("run", insertSegment, ["postBrandVerified3", 1, 11, 1, 0, "postBrandVerified3", getHash(userID8), 0, 50, "sponsor", "skip", "YouTube", 100, 0, 0, ""]);
|
await db.prepare("run", insertSegment, ["postBrandVerified3", 1, 11, 1, 0, "postBrandVerified3", getHash(userID8), 0, 50, "sponsor", "skip", "YouTube", 100, 0, 0, ""]);
|
||||||
await db.prepare("run", insertSegment, ["postBrandVerified3", 11, 21, 1, 0, "postBrandVerified32", getHash(userID8), 0, 50, "sponsor", "skip", "YouTube", 100, 0, 0, ""]);
|
await db.prepare("run", insertSegment, ["postBrandVerified3", 11, 21, 1, 0, "postBrandVerified32", getHash(userID8), 0, 50, "sponsor", "skip", "YouTube", 100, 0, 0, ""]);
|
||||||
await db.prepare("run", insertSegment, ["postBrandVerified3", 21, 31, 1, 0, "postBrandVerified33", getHash(userID8), 0, 50, "sponsor", "skip", "YouTube", 100, 0, 0, ""]);
|
await db.prepare("run", insertSegment, ["postBrandVerified3", 21, 31, 1, 0, "postBrandVerified33", getHash(userID8), 0, 50, "sponsor", "skip", "YouTube", 100, 0, 0, ""]);
|
||||||
|
|
||||||
|
// Testing details for banned user handling
|
||||||
|
await db.prepare("run", insertTitleQuery, ["postBrandBannedCustomVote", "Some title", 0, getHash(userID1), Service.YouTube, getHash("postBrandBannedCustomVote"), Date.now(), "postBrandBannedCustomVote"]);
|
||||||
|
await db.prepare("run", insertTitleQuery, ["postBrandBannedOriginalVote", "Some title", 1, getHash(userID1), Service.YouTube, getHash("postBrandBannedOriginalVote"), Date.now(), "postBrandBannedOriginalVote"]);
|
||||||
|
await db.prepare("run", insertTitleVotesQuery, ["postBrandBannedCustomVote", 0, 0, 0, 0]);
|
||||||
|
await db.prepare("run", insertTitleVotesQuery, ["postBrandBannedOriginalVote", 0, 0, 0, 0]);
|
||||||
|
await db.prepare("run", insertThumbnailQuery, ["postBrandBannedCustomVote", 0, getHash(userID1), Service.YouTube, getHash("postBrandBannedCustomVote"), Date.now(), "postBrandBannedCustomVote"]);
|
||||||
|
await db.prepare("run", insertThumbnailQuery, ["postBrandBannedOriginalVote", 1, getHash(userID1), Service.YouTube, getHash("postBrandBannedOriginalVote"), Date.now(), "postBrandBannedOriginalVote"]);
|
||||||
|
await db.prepare("run", insertThumbnailVotesQuery, ["postBrandBannedCustomVote", 0, 0, 0]);
|
||||||
|
await db.prepare("run", insertThumbnailVotesQuery, ["postBrandBannedOriginalVote", 0, 0, 0]);
|
||||||
|
const insertThumbnailTimestampQuery = 'INSERT INTO "thumbnailTimestamps" ("UUID", "timestamp") VALUES (?, ?)';
|
||||||
|
await db.prepare("run", insertThumbnailTimestampQuery, ["postBrandBannedCustomVote", 12.34]);
|
||||||
});
|
});
|
||||||
|
|
||||||
it("Submit only title", async () => {
|
it("Submit only title", async () => {
|
||||||
@@ -579,4 +595,193 @@ describe("postBranding", () => {
|
|||||||
|
|
||||||
assert.strictEqual(dbVotes.verification, 0);
|
assert.strictEqual(dbVotes.verification, 0);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
it("Banned users should not be able to vote (custom title)", async () => {
|
||||||
|
const videoID = "postBrandBannedCustomVote";
|
||||||
|
const title = {
|
||||||
|
title: "Some title",
|
||||||
|
original: false
|
||||||
|
};
|
||||||
|
|
||||||
|
const res = await postBranding({
|
||||||
|
title,
|
||||||
|
userID: bannedUser,
|
||||||
|
service: Service.YouTube,
|
||||||
|
videoID
|
||||||
|
});
|
||||||
|
|
||||||
|
assert.strictEqual(res.status, 200);
|
||||||
|
const dbTitle = await queryTitleByVideo(videoID);
|
||||||
|
const dbVotes = await queryTitleVotesByUUID(dbTitle.UUID);
|
||||||
|
|
||||||
|
assert.strictEqual(dbTitle.title, title.title);
|
||||||
|
assert.strictEqual(dbTitle.original, title.original ? 1 : 0);
|
||||||
|
|
||||||
|
assert.strictEqual(dbVotes.votes, 0);
|
||||||
|
assert.strictEqual(dbVotes.locked, 0);
|
||||||
|
assert.strictEqual(dbVotes.shadowHidden, 0);
|
||||||
|
});
|
||||||
|
|
||||||
|
it("Banned users should not be able to vote (original title)", async () => {
|
||||||
|
const videoID = "postBrandBannedOriginalVote";
|
||||||
|
const title = {
|
||||||
|
title: "Some title",
|
||||||
|
original: true
|
||||||
|
};
|
||||||
|
|
||||||
|
const res = await postBranding({
|
||||||
|
title,
|
||||||
|
userID: bannedUser,
|
||||||
|
service: Service.YouTube,
|
||||||
|
videoID
|
||||||
|
});
|
||||||
|
|
||||||
|
assert.strictEqual(res.status, 200);
|
||||||
|
const dbTitle = await queryTitleByVideo(videoID);
|
||||||
|
const dbVotes = await queryTitleVotesByUUID(dbTitle.UUID);
|
||||||
|
|
||||||
|
assert.strictEqual(dbTitle.title, title.title);
|
||||||
|
assert.strictEqual(dbTitle.original, title.original ? 1 : 0);
|
||||||
|
|
||||||
|
assert.strictEqual(dbVotes.votes, 0);
|
||||||
|
assert.strictEqual(dbVotes.locked, 0);
|
||||||
|
assert.strictEqual(dbVotes.shadowHidden, 0);
|
||||||
|
});
|
||||||
|
|
||||||
|
it("Banned users should not be able to vote (custom thumbnail)", async () => {
|
||||||
|
const videoID = "postBrandBannedCustomVote";
|
||||||
|
const thumbnail = {
|
||||||
|
original: false,
|
||||||
|
timestamp: 12.34
|
||||||
|
};
|
||||||
|
|
||||||
|
const res = await postBranding({
|
||||||
|
thumbnail,
|
||||||
|
userID: bannedUser,
|
||||||
|
service: Service.YouTube,
|
||||||
|
videoID
|
||||||
|
});
|
||||||
|
|
||||||
|
assert.strictEqual(res.status, 200);
|
||||||
|
const dbThumbnail = await queryThumbnailByVideo(videoID);
|
||||||
|
const dbVotes = await queryThumbnailVotesByUUID(dbThumbnail.UUID);
|
||||||
|
|
||||||
|
assert.strictEqual(dbThumbnail.original, thumbnail.original ? 1 : 0);
|
||||||
|
|
||||||
|
assert.strictEqual(dbVotes.votes, 0);
|
||||||
|
assert.strictEqual(dbVotes.locked, 0);
|
||||||
|
assert.strictEqual(dbVotes.shadowHidden, 0);
|
||||||
|
});
|
||||||
|
|
||||||
|
it("Banned users should not be able to vote (original thumbnail)", async () => {
|
||||||
|
const videoID = "postBrandBannedOriginalVote";
|
||||||
|
const thumbnail = {
|
||||||
|
original: true
|
||||||
|
};
|
||||||
|
|
||||||
|
const res = await postBranding({
|
||||||
|
thumbnail,
|
||||||
|
userID: bannedUser,
|
||||||
|
service: Service.YouTube,
|
||||||
|
videoID
|
||||||
|
});
|
||||||
|
|
||||||
|
assert.strictEqual(res.status, 200);
|
||||||
|
const dbThumbnail = await queryThumbnailByVideo(videoID);
|
||||||
|
const dbVotes = await queryThumbnailVotesByUUID(dbThumbnail.UUID);
|
||||||
|
|
||||||
|
assert.strictEqual(dbThumbnail.original, thumbnail.original ? 1 : 0);
|
||||||
|
|
||||||
|
assert.strictEqual(dbVotes.votes, 0);
|
||||||
|
assert.strictEqual(dbVotes.locked, 0);
|
||||||
|
assert.strictEqual(dbVotes.shadowHidden, 0);
|
||||||
|
});
|
||||||
|
|
||||||
|
it("Banned users' custom submissions should be hidden (title)", async () => {
|
||||||
|
const videoID = "postBrandBannedCustom";
|
||||||
|
const title = {
|
||||||
|
title: "Some title",
|
||||||
|
original: false
|
||||||
|
};
|
||||||
|
|
||||||
|
const res = await postBranding({
|
||||||
|
title,
|
||||||
|
userID: bannedUser,
|
||||||
|
service: Service.YouTube,
|
||||||
|
videoID
|
||||||
|
});
|
||||||
|
|
||||||
|
assert.strictEqual(res.status, 200);
|
||||||
|
const dbTitle = await queryTitleByVideo(videoID);
|
||||||
|
const dbVotes = await queryTitleVotesByUUID(dbTitle.UUID);
|
||||||
|
|
||||||
|
assert.strictEqual(dbTitle.title, title.title);
|
||||||
|
assert.strictEqual(dbTitle.original, title.original ? 1 : 0);
|
||||||
|
|
||||||
|
assert.strictEqual(dbVotes.votes, 0);
|
||||||
|
assert.strictEqual(dbVotes.locked, 0);
|
||||||
|
assert.strictEqual(dbVotes.shadowHidden, 1);
|
||||||
|
});
|
||||||
|
|
||||||
|
it("Banned users' custom submissions should be hidden (thumbnail)", async () => {
|
||||||
|
const videoID = "postBrandBannedCustom";
|
||||||
|
const thumbnail = {
|
||||||
|
original: false,
|
||||||
|
timestamp: 12.34
|
||||||
|
};
|
||||||
|
|
||||||
|
const res = await postBranding({
|
||||||
|
thumbnail,
|
||||||
|
userID: bannedUser,
|
||||||
|
service: Service.YouTube,
|
||||||
|
videoID
|
||||||
|
});
|
||||||
|
|
||||||
|
assert.strictEqual(res.status, 200);
|
||||||
|
const dbThumbnail = await queryThumbnailByVideo(videoID);
|
||||||
|
const dbVotes = await queryThumbnailVotesByUUID(dbThumbnail.UUID);
|
||||||
|
|
||||||
|
assert.strictEqual(dbThumbnail.original, thumbnail.original ? 1 : 0);
|
||||||
|
|
||||||
|
assert.strictEqual(dbVotes.votes, 0);
|
||||||
|
assert.strictEqual(dbVotes.locked, 0);
|
||||||
|
assert.strictEqual(dbVotes.shadowHidden, 1);
|
||||||
|
});
|
||||||
|
|
||||||
|
it("Banned users' original submissions should be ignored (title)", async () => {
|
||||||
|
const videoID = "postBrandBannedOriginal";
|
||||||
|
const title = {
|
||||||
|
title: "Some title",
|
||||||
|
original: true
|
||||||
|
};
|
||||||
|
|
||||||
|
const res = await postBranding({
|
||||||
|
title,
|
||||||
|
userID: bannedUser,
|
||||||
|
service: Service.YouTube,
|
||||||
|
videoID
|
||||||
|
});
|
||||||
|
|
||||||
|
assert.strictEqual(res.status, 200);
|
||||||
|
const dbTitle = await queryTitleByVideo(videoID);
|
||||||
|
assert.strictEqual(dbTitle, undefined);
|
||||||
|
});
|
||||||
|
|
||||||
|
it("Banned users' original submissions should be ignored (thumbnail)", async () => {
|
||||||
|
const videoID = "postBrandBannedOriginal";
|
||||||
|
const thumbnail = {
|
||||||
|
original: true
|
||||||
|
};
|
||||||
|
|
||||||
|
const res = await postBranding({
|
||||||
|
thumbnail,
|
||||||
|
userID: bannedUser,
|
||||||
|
service: Service.YouTube,
|
||||||
|
videoID
|
||||||
|
});
|
||||||
|
|
||||||
|
assert.strictEqual(res.status, 200);
|
||||||
|
const dbThumbnail = await queryThumbnailByVideo(videoID);
|
||||||
|
assert.strictEqual(dbThumbnail, undefined);
|
||||||
|
});
|
||||||
});
|
});
|
||||||
Reference in New Issue
Block a user