mirror of
https://github.com/ajayyy/SponsorBlockServer.git
synced 2024-11-10 01:02:30 +01:00
Add malicious vote type for chapters
This commit is contained in:
parent
cc953884d9
commit
f9de547b95
7 changed files with 70 additions and 15 deletions
|
@ -209,6 +209,7 @@
|
||||||
| userID | TEXT | not null |
|
| userID | TEXT | not null |
|
||||||
| hashedIP | TEXT | not null |
|
| hashedIP | TEXT | not null |
|
||||||
| type | INTEGER | not null |
|
| type | INTEGER | not null |
|
||||||
|
| originalVoteType | INTEGER | not null | # Since type was reused to also specify the number of votes removed when less than 0, this is being used for the actual type
|
||||||
|
|
||||||
| index | field |
|
| index | field |
|
||||||
| -- | :--: |
|
| -- | :--: |
|
||||||
|
|
9
databases/_upgrade_private_10.sql
Normal file
9
databases/_upgrade_private_10.sql
Normal file
|
@ -0,0 +1,9 @@
|
||||||
|
BEGIN TRANSACTION;
|
||||||
|
|
||||||
|
-- Add primary keys
|
||||||
|
|
||||||
|
ALTER TABLE "votes" ADD "originalType" INTEGER NOT NULL default -1;
|
||||||
|
|
||||||
|
UPDATE "config" SET value = 10 WHERE key = 'version';
|
||||||
|
|
||||||
|
COMMIT;
|
|
@ -42,6 +42,7 @@ addDefaults(config, {
|
||||||
discordNeuralBlockRejectWebhookURL: null,
|
discordNeuralBlockRejectWebhookURL: null,
|
||||||
discordFailedReportChannelWebhookURL: null,
|
discordFailedReportChannelWebhookURL: null,
|
||||||
discordReportChannelWebhookURL: null,
|
discordReportChannelWebhookURL: null,
|
||||||
|
discordMaliciousReportWebhookURL: null,
|
||||||
getTopUsersCacheTimeMinutes: 240,
|
getTopUsersCacheTimeMinutes: 240,
|
||||||
globalSalt: null,
|
globalSalt: null,
|
||||||
mode: "",
|
mode: "",
|
||||||
|
|
|
@ -11,7 +11,7 @@ import { getIP } from "../utils/getIP";
|
||||||
import { getHashCache } from "../utils/getHashCache";
|
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 { DBSegment, Category, HashedIP, IPAddress, SegmentUUID, Service, VideoID, VideoIDHash, VideoDuration, ActionType } from "../types/segments.model";
|
import { DBSegment, Category, HashedIP, IPAddress, SegmentUUID, Service, VideoID, VideoIDHash, VideoDuration, ActionType, VoteType } from "../types/segments.model";
|
||||||
import { QueryCacher } from "../utils/queryCacher";
|
import { QueryCacher } from "../utils/queryCacher";
|
||||||
import axios from "axios";
|
import axios from "axios";
|
||||||
|
|
||||||
|
@ -36,6 +36,7 @@ interface FinalResponse {
|
||||||
interface VoteData {
|
interface VoteData {
|
||||||
UUID: string;
|
UUID: string;
|
||||||
nonAnonUserID: string;
|
nonAnonUserID: string;
|
||||||
|
originalType: VoteType;
|
||||||
voteTypeEnum: number;
|
voteTypeEnum: number;
|
||||||
isTempVIP: boolean;
|
isTempVIP: boolean;
|
||||||
isVIP: boolean;
|
isVIP: boolean;
|
||||||
|
@ -112,7 +113,9 @@ async function sendWebhooks(voteData: VoteData) {
|
||||||
|
|
||||||
if (submissionInfoRow !== undefined && userSubmissionCountRow != undefined) {
|
if (submissionInfoRow !== undefined && userSubmissionCountRow != undefined) {
|
||||||
let webhookURL: string = null;
|
let webhookURL: string = null;
|
||||||
if (voteData.voteTypeEnum === voteTypes.normal) {
|
if (voteData.originalType === VoteType.Malicious) {
|
||||||
|
webhookURL = config.discordMaliciousReportWebhookURL;
|
||||||
|
} else if (voteData.voteTypeEnum === voteTypes.normal) {
|
||||||
switch (voteData.finalResponse.webhookType) {
|
switch (voteData.finalResponse.webhookType) {
|
||||||
case VoteWebhookType.Normal:
|
case VoteWebhookType.Normal:
|
||||||
webhookURL = config.discordReportChannelWebhookURL;
|
webhookURL = config.discordReportChannelWebhookURL;
|
||||||
|
@ -329,6 +332,8 @@ export async function vote(ip: IPAddress, UUID: SegmentUUID, paramUserID: UserID
|
||||||
return { status: 200 };
|
return { status: 200 };
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const originalType = type;
|
||||||
|
|
||||||
//hash the userID
|
//hash the userID
|
||||||
const nonAnonUserID = await getHashCache(paramUserID);
|
const nonAnonUserID = await getHashCache(paramUserID);
|
||||||
const userID = await getHashCache(paramUserID + UUID);
|
const userID = await getHashCache(paramUserID + UUID);
|
||||||
|
@ -421,13 +426,13 @@ export async function vote(ip: IPAddress, UUID: SegmentUUID, paramUserID: UserID
|
||||||
let incrementAmount = 0;
|
let incrementAmount = 0;
|
||||||
let oldIncrementAmount = 0;
|
let oldIncrementAmount = 0;
|
||||||
|
|
||||||
if (type == 1) {
|
if (type == VoteType.Upvote) {
|
||||||
//upvote
|
//upvote
|
||||||
incrementAmount = 1;
|
incrementAmount = 1;
|
||||||
} else if (type == 0) {
|
} else if (type === VoteType.Downvote || type === VoteType.Malicious) {
|
||||||
//downvote
|
//downvote
|
||||||
incrementAmount = -1;
|
incrementAmount = -1;
|
||||||
} else if (type == 20) {
|
} else if (type == VoteType.Undo) {
|
||||||
//undo/cancel vote
|
//undo/cancel vote
|
||||||
incrementAmount = 0;
|
incrementAmount = 0;
|
||||||
} else {
|
} else {
|
||||||
|
@ -435,17 +440,13 @@ export async function vote(ip: IPAddress, UUID: SegmentUUID, paramUserID: UserID
|
||||||
return { status: 400 };
|
return { status: 400 };
|
||||||
}
|
}
|
||||||
if (votesRow) {
|
if (votesRow) {
|
||||||
if (votesRow.type === 1) {
|
if (votesRow.type === VoteType.Upvote) {
|
||||||
//upvote
|
|
||||||
oldIncrementAmount = 1;
|
oldIncrementAmount = 1;
|
||||||
} else if (votesRow.type === 0) {
|
} else if (votesRow.type === VoteType.Downvote) {
|
||||||
//downvote
|
|
||||||
oldIncrementAmount = -1;
|
oldIncrementAmount = -1;
|
||||||
} else if (votesRow.type === 2) {
|
} else if (votesRow.type === VoteType.ExtraDownvote) {
|
||||||
//extra downvote
|
|
||||||
oldIncrementAmount = -4;
|
oldIncrementAmount = -4;
|
||||||
} else if (votesRow.type === 20) {
|
} else if (votesRow.type === VoteType.Undo) {
|
||||||
//undo/cancel vote
|
|
||||||
oldIncrementAmount = 0;
|
oldIncrementAmount = 0;
|
||||||
} else if (votesRow.type < 0) {
|
} else if (votesRow.type < 0) {
|
||||||
//vip downvote
|
//vip downvote
|
||||||
|
@ -466,8 +467,14 @@ export async function vote(ip: IPAddress, UUID: SegmentUUID, paramUserID: UserID
|
||||||
type = incrementAmount;
|
type = incrementAmount;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (type === VoteType.Malicious) {
|
||||||
|
incrementAmount = -Math.min(segmentInfo.votes + 2 - oldIncrementAmount, 5);
|
||||||
|
type = incrementAmount;
|
||||||
|
}
|
||||||
|
|
||||||
// Only change the database if they have made a submission before and haven't voted recently
|
// Only change the database if they have made a submission before and haven't voted recently
|
||||||
const userAbleToVote = (!(isOwnSubmission && incrementAmount > 0 && oldIncrementAmount >= 0)
|
const userAbleToVote = (!(isOwnSubmission && incrementAmount > 0 && oldIncrementAmount >= 0)
|
||||||
|
&& !(originalType === VoteType.Malicious && segmentInfo.actionType !== ActionType.Chapter)
|
||||||
&& !finalResponse.blockVote
|
&& !finalResponse.blockVote
|
||||||
&& finalResponse.finalStatus === 200
|
&& finalResponse.finalStatus === 200
|
||||||
&& (await db.prepare("get", `SELECT "userID" FROM "sponsorTimes" WHERE "userID" = ?`, [nonAnonUserID])) !== undefined
|
&& (await db.prepare("get", `SELECT "userID" FROM "sponsorTimes" WHERE "userID" = ?`, [nonAnonUserID])) !== undefined
|
||||||
|
@ -480,9 +487,9 @@ export async function vote(ip: IPAddress, UUID: SegmentUUID, paramUserID: UserID
|
||||||
if (ableToVote) {
|
if (ableToVote) {
|
||||||
//update the votes table
|
//update the votes table
|
||||||
if (votesRow) {
|
if (votesRow) {
|
||||||
await privateDB.prepare("run", `UPDATE "votes" SET "type" = ? WHERE "userID" = ? AND "UUID" = ?`, [type, userID, UUID]);
|
await privateDB.prepare("run", `UPDATE "votes" SET "type" = ?, "originalType" = ? WHERE "userID" = ? AND "UUID" = ?`, [type, originalType, userID, UUID]);
|
||||||
} else {
|
} else {
|
||||||
await privateDB.prepare("run", `INSERT INTO "votes" VALUES(?, ?, ?, ?, ?)`, [UUID, userID, hashedIP, type, nonAnonUserID]);
|
await privateDB.prepare("run", `INSERT INTO "votes" VALUES(?, ?, ?, ?, ?, ?)`, [UUID, userID, hashedIP, type, nonAnonUserID, originalType]);
|
||||||
}
|
}
|
||||||
|
|
||||||
// update the vote count on this sponsorTime
|
// update the vote count on this sponsorTime
|
||||||
|
@ -510,6 +517,7 @@ export async function vote(ip: IPAddress, UUID: SegmentUUID, paramUserID: UserID
|
||||||
sendWebhooks({
|
sendWebhooks({
|
||||||
UUID,
|
UUID,
|
||||||
nonAnonUserID,
|
nonAnonUserID,
|
||||||
|
originalType,
|
||||||
voteTypeEnum,
|
voteTypeEnum,
|
||||||
isTempVIP,
|
isTempVIP,
|
||||||
isVIP,
|
isVIP,
|
||||||
|
|
|
@ -24,6 +24,7 @@ export interface SBSConfig {
|
||||||
discordFailedReportChannelWebhookURL?: string;
|
discordFailedReportChannelWebhookURL?: string;
|
||||||
discordFirstTimeSubmissionsWebhookURL?: string;
|
discordFirstTimeSubmissionsWebhookURL?: string;
|
||||||
discordCompletelyIncorrectReportWebhookURL?: string;
|
discordCompletelyIncorrectReportWebhookURL?: string;
|
||||||
|
discordMaliciousReportWebhookURL?: string;
|
||||||
neuralBlockURL?: string;
|
neuralBlockURL?: string;
|
||||||
discordNeuralBlockRejectWebhookURL?: string;
|
discordNeuralBlockRejectWebhookURL?: string;
|
||||||
userCounterURL?: string;
|
userCounterURL?: string;
|
||||||
|
|
|
@ -120,3 +120,12 @@ export enum SortableFields {
|
||||||
votes = "votes",
|
votes = "votes",
|
||||||
views = "views",
|
views = "views",
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
export enum VoteType {
|
||||||
|
Downvote = 0,
|
||||||
|
Upvote = 1,
|
||||||
|
ExtraDownvote = 2,
|
||||||
|
Undo = 20,
|
||||||
|
Malicious = 30
|
||||||
|
}
|
|
@ -67,6 +67,8 @@ describe("voteOnSponsorTime", () => {
|
||||||
await db.prepare("run", insertSponsorTimeQuery, ["duration-changed", 1, 12, 0, 0, "duration-changed-uuid-3", "testman", 20, 0, "sponsor", "skip", 0, 0]);
|
await db.prepare("run", insertSponsorTimeQuery, ["duration-changed", 1, 12, 0, 0, "duration-changed-uuid-3", "testman", 20, 0, "sponsor", "skip", 0, 0]);
|
||||||
// add videoDuration to duration-changed-uuid-2
|
// add videoDuration to duration-changed-uuid-2
|
||||||
await db.prepare("run", `UPDATE "sponsorTimes" SET "videoDuration" = 150 WHERE "UUID" = 'duration-changed-uuid-2'`);
|
await db.prepare("run", `UPDATE "sponsorTimes" SET "videoDuration" = 150 WHERE "UUID" = 'duration-changed-uuid-2'`);
|
||||||
|
await db.prepare("run", insertSponsorTimeQuery, ["chapter-video", 1, 10, 0, 0, "chapter-uuid-1", "testman", 0, 0, "chapter", "chapter", 0, 0]);
|
||||||
|
await db.prepare("run", insertSponsorTimeQuery, ["chapter-video", 1, 10, 0, 0, "non-chapter-uuid-2", "testman", 0, 0, "sponsor", "skip", 0, 0]);
|
||||||
|
|
||||||
const insertWarningQuery = 'INSERT INTO "warnings" ("userID", "issueTime", "issuerUserID", "enabled") VALUES(?, ?, ?, ?)';
|
const insertWarningQuery = 'INSERT INTO "warnings" ("userID", "issueTime", "issuerUserID", "enabled") VALUES(?, ?, ?, ?)';
|
||||||
await db.prepare("run", insertWarningQuery, [warnUser01Hash, now, warnVip01Hash, 1]);
|
await db.prepare("run", insertWarningQuery, [warnUser01Hash, now, warnVip01Hash, 1]);
|
||||||
|
@ -223,6 +225,30 @@ describe("voteOnSponsorTime", () => {
|
||||||
.catch(err => done(err));
|
.catch(err => done(err));
|
||||||
});
|
});
|
||||||
|
|
||||||
|
it("should be able to completely downvote chapter using malicious", (done) => {
|
||||||
|
const UUID = "chapter-uuid-1";
|
||||||
|
postVote(randomID2, UUID, 30)
|
||||||
|
.then(async res => {
|
||||||
|
assert.strictEqual(res.status, 200);
|
||||||
|
const row = await getSegmentVotes(UUID);
|
||||||
|
assert.strictEqual(row.votes, -2);
|
||||||
|
done();
|
||||||
|
})
|
||||||
|
.catch(err => done(err));
|
||||||
|
});
|
||||||
|
|
||||||
|
it("should not be able to completely downvote non-chapter using malicious", (done) => {
|
||||||
|
const UUID = "non-chapter-uuid-2";
|
||||||
|
postVote(randomID2, UUID, 30)
|
||||||
|
.then(async res => {
|
||||||
|
assert.strictEqual(res.status, 200);
|
||||||
|
const row = await getSegmentVotes(UUID);
|
||||||
|
assert.strictEqual(row.votes, 0);
|
||||||
|
done();
|
||||||
|
})
|
||||||
|
.catch(err => done(err));
|
||||||
|
});
|
||||||
|
|
||||||
it("Should be able to vote for a category and it should add your vote to the database", (done) => {
|
it("Should be able to vote for a category and it should add your vote to the database", (done) => {
|
||||||
const UUID = "vote-uuid-4";
|
const UUID = "vote-uuid-4";
|
||||||
postVoteCategory(randomID2, UUID, "intro")
|
postVoteCategory(randomID2, UUID, "intro")
|
||||||
|
|
Loading…
Reference in a new issue