mirror of
https://github.com/ajayyy/SponsorBlockServer.git
synced 2025-12-17 13:08:49 +03:00
Merge branch 'master' of https://github.com/ajayyy/SponsorBlockServer
This commit is contained in:
@@ -298,7 +298,7 @@ async function checkUserActiveWarning(userID: string): Promise<CheckResult> {
|
|||||||
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"
|
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. "
|
+ " that are not malicious, and we just want to clarify the rules. "
|
||||||
+ "Could you please send a message in discord.gg/SponsorBlock or matrix.to/#/+sponsor:ajay.app so we can further help you? "
|
+ "Could you please send a message in discord.gg/SponsorBlock or matrix.to/#/#sponsor:ajay.app so we can further help you? "
|
||||||
+ `Your userID is ${userID}.`;
|
+ `Your userID is ${userID}.`;
|
||||||
|
|
||||||
return {
|
return {
|
||||||
@@ -324,6 +324,15 @@ function checkInvalidFields(videoID: any, userID: any, segments: Array<any>): Ch
|
|||||||
if (!Array.isArray(segments) || segments.length < 1) {
|
if (!Array.isArray(segments) || segments.length < 1) {
|
||||||
invalidFields.push("segments");
|
invalidFields.push("segments");
|
||||||
}
|
}
|
||||||
|
// validate start and end times (no : marks)
|
||||||
|
for (const segmentPair of segments) {
|
||||||
|
const startTime = segmentPair.segment[0];
|
||||||
|
const endTime = segmentPair.segment[1];
|
||||||
|
if ((typeof startTime === "string" && startTime.includes(":")) ||
|
||||||
|
(typeof endTime === "string" && endTime.includes(":"))) {
|
||||||
|
invalidFields.push("segment time");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (invalidFields.length !== 0) {
|
if (invalidFields.length !== 0) {
|
||||||
// invalid request
|
// invalid request
|
||||||
@@ -366,7 +375,7 @@ async function checkEachSegmentValid(userID: string, videoID: VideoID
|
|||||||
`${lockedCategoryList[lockIndex].reason?.length !== 0 ? `\nLock reason: '${lockedCategoryList[lockIndex].reason}'` : ""}\n` +
|
`${lockedCategoryList[lockIndex].reason?.length !== 0 ? `\nLock reason: '${lockedCategoryList[lockIndex].reason}'` : ""}\n` +
|
||||||
`${(segments[i].category === "sponsor" ? "\nMaybe the segment you are submitting is a different category that you have not enabled and is not a sponsor. " +
|
`${(segments[i].category === "sponsor" ? "\nMaybe 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" : "")}` +
|
"Categories that aren't sponsor, such as self-promotion can be enabled in the options.\n" : "")}` +
|
||||||
`\nIf you believe this is incorrect, please contact someone on discord.gg/SponsorBlock or matrix.to/#/+sponsor:ajay.app`
|
`\nIf you believe this is incorrect, please contact someone on discord.gg/SponsorBlock or matrix.to/#/#sponsor:ajay.app`
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -381,6 +390,11 @@ async function checkEachSegmentValid(userID: string, videoID: VideoID
|
|||||||
return { pass: false, errorMessage: "One of your segments times are invalid (too short, startTime before endTime, etc.)", errorCode: 400};
|
return { pass: false, errorMessage: "One of your segments times are invalid (too short, startTime before endTime, etc.)", errorCode: 400};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Check for POI segments before 1 second
|
||||||
|
if (getCategoryActionType(segments[i].category) === CategoryActionType.POI && startTime < 1) {
|
||||||
|
return { pass: false, errorMessage: "POI must be after 1 second", errorCode: 400};
|
||||||
|
}
|
||||||
|
|
||||||
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
|
||||||
return { pass: false, errorMessage: "Sponsors must be longer than 1 second long", errorCode: 400};
|
return { pass: false, errorMessage: "Sponsors must be longer than 1 second long", errorCode: 400};
|
||||||
|
|||||||
@@ -48,16 +48,7 @@ export async function shadowBanUser(req: Request, res: Response): Promise<Respon
|
|||||||
|
|
||||||
//find all previous submissions and hide them
|
//find all previous submissions and hide them
|
||||||
if (unHideOldSubmissions) {
|
if (unHideOldSubmissions) {
|
||||||
await db.prepare("run", `UPDATE "sponsorTimes" SET "shadowHidden" = 1 WHERE "userID" = ? AND "category" in (${categories.map((c) => `'${c}'`).join(",")})
|
await unHideSubmissions(categories, userID);
|
||||||
AND NOT EXISTS ( SELECT "videoID", "category" FROM "lockCategories" WHERE
|
|
||||||
"sponsorTimes"."videoID" = "lockCategories"."videoID" AND "sponsorTimes"."category" = "lockCategories"."category")`, [userID]);
|
|
||||||
|
|
||||||
// clear cache for all old videos
|
|
||||||
(await db.prepare("all", `SELECT "videoID", "hashedVideoID", "service", "votes", "views" FROM "sponsorTimes" WHERE "userID" = ?`, [userID]))
|
|
||||||
.forEach((videoInfo: {category: Category, videoID: VideoID, hashedVideoID: VideoIDHash, service: Service, userID: UserID}) => {
|
|
||||||
QueryCacher.clearVideoCache(videoInfo);
|
|
||||||
}
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
} else if (!enabled && row.userCount > 0) {
|
} else if (!enabled && row.userCount > 0) {
|
||||||
//remove them from the shadow ban list
|
//remove them from the shadow ban list
|
||||||
@@ -84,6 +75,16 @@ export async function shadowBanUser(req: Request, res: Response): Promise<Respon
|
|||||||
return db.prepare("run", `UPDATE "sponsorTimes" SET "shadowHidden" = 0 WHERE "UUID" = ? AND "category" in (${categories.map((c) => `'${c}'`).join(",")})`, [UUID]);
|
return db.prepare("run", `UPDATE "sponsorTimes" SET "shadowHidden" = 0 WHERE "UUID" = ? AND "category" in (${categories.map((c) => `'${c}'`).join(",")})`, [UUID]);
|
||||||
}));
|
}));
|
||||||
}
|
}
|
||||||
|
// already shadowbanned
|
||||||
|
} else if (enabled && row.userCount > 0) {
|
||||||
|
// apply unHideOldSubmissions if applicable
|
||||||
|
if (unHideOldSubmissions) {
|
||||||
|
await unHideSubmissions(categories, userID);
|
||||||
|
return res.sendStatus(200);
|
||||||
|
}
|
||||||
|
|
||||||
|
// otherwise ban already exists, send 409
|
||||||
|
return res.sendStatus(409);
|
||||||
}
|
}
|
||||||
} else if (hashedIP) {
|
} else if (hashedIP) {
|
||||||
//check to see if this user is already shadowbanned
|
//check to see if this user is already shadowbanned
|
||||||
@@ -115,3 +116,16 @@ export async function shadowBanUser(req: Request, res: Response): Promise<Respon
|
|||||||
}
|
}
|
||||||
return res.sendStatus(200);
|
return res.sendStatus(200);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
async function unHideSubmissions(categories: string[], userID: UserID) {
|
||||||
|
await db.prepare("run", `UPDATE "sponsorTimes" SET "shadowHidden" = 1 WHERE "userID" = ? AND "category" in (${categories.map((c) => `'${c}'`).join(",")})
|
||||||
|
AND NOT EXISTS ( SELECT "videoID", "category" FROM "lockCategories" WHERE
|
||||||
|
"sponsorTimes"."videoID" = "lockCategories"."videoID" AND "sponsorTimes"."category" = "lockCategories"."category")`, [userID]);
|
||||||
|
|
||||||
|
// clear cache for all old videos
|
||||||
|
(await db.prepare("all", `SELECT "videoID", "hashedVideoID", "service", "votes", "views" FROM "sponsorTimes" WHERE "userID" = ?`, [userID]))
|
||||||
|
.forEach((videoInfo: { category: Category; videoID: VideoID; hashedVideoID: VideoIDHash; service: Service; userID: UserID; }) => {
|
||||||
|
QueryCacher.clearVideoCache(videoInfo);
|
||||||
|
}
|
||||||
|
); //eslint-disable-line
|
||||||
|
}
|
||||||
@@ -612,7 +612,7 @@ describe("postSkipSegments", () => {
|
|||||||
const userID = "09dee632bfbb1acc9fda3169cc14b46e459b45cee4f4449be305590e612b5eb7";
|
const userID = "09dee632bfbb1acc9fda3169cc14b46e459b45cee4f4449be305590e612b5eb7";
|
||||||
const expected = "Submission rejected due to a warning from a moderator. This means that we noticed you were making some common mistakes"
|
const expected = "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. "
|
+ " that are not malicious, and we just want to clarify the rules. "
|
||||||
+ "Could you please send a message in discord.gg/SponsorBlock or matrix.to/#/+sponsor:ajay.app so we can further help you? "
|
+ "Could you please send a message in discord.gg/SponsorBlock or matrix.to/#/#sponsor:ajay.app so we can further help you? "
|
||||||
+ `Your userID is ${userID}.\n\nWarning reason: '${reason}'`;
|
+ `Your userID is ${userID}.\n\nWarning reason: '${reason}'`;
|
||||||
|
|
||||||
assert.strictEqual(errorMessage, expected);
|
assert.strictEqual(errorMessage, expected);
|
||||||
@@ -987,4 +987,38 @@ describe("postSkipSegments", () => {
|
|||||||
})
|
})
|
||||||
.catch(err => done(err));
|
.catch(err => done(err));
|
||||||
});
|
});
|
||||||
|
|
||||||
|
it("Should be rejected if a POI is at less than 1 second", (done: Done) => {
|
||||||
|
fetch(`${getbaseURL()
|
||||||
|
}/api/skipSegments?videoID=qqwerty&startTime=0.5&endTime=0.5&category=poi_highlight&userID=testtesttesttesttesttesttesttesttesting`, {
|
||||||
|
method: "POST",
|
||||||
|
})
|
||||||
|
.then(res => {
|
||||||
|
assert.strictEqual(res.status, 400);
|
||||||
|
done();
|
||||||
|
})
|
||||||
|
.catch(err => done(err));
|
||||||
|
});
|
||||||
|
|
||||||
|
it("Should not be able to submit with colons in timestamps", (done: Done) => {
|
||||||
|
fetch(`${getbaseURL()}/api/postVideoSponsorTimes`, {
|
||||||
|
method: "POST",
|
||||||
|
headers: {
|
||||||
|
"Content-Type": "application/json"
|
||||||
|
},
|
||||||
|
body: JSON.stringify({
|
||||||
|
userID: "testtesttesttesttesttesttesttesttest",
|
||||||
|
videoID: "colon-1",
|
||||||
|
segments: [{
|
||||||
|
segment: ["0:2.000", "3:10.392"],
|
||||||
|
category: "sponsor",
|
||||||
|
}]
|
||||||
|
}),
|
||||||
|
})
|
||||||
|
.then(res => {
|
||||||
|
assert.strictEqual(res.status, 400);
|
||||||
|
done();
|
||||||
|
})
|
||||||
|
.catch(err => done(err));
|
||||||
|
});
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -18,7 +18,11 @@ describe("shadowBanUser", () => {
|
|||||||
await db.prepare("run", insertQuery, ["testtesttest", 1, 11, 2, 0, "shadow-3-uuid-0", "shadowBanned3", 0, 50, "sponsor", "YouTube", 100, 0, 1, getHash("testtesttest", 1)]);
|
await db.prepare("run", insertQuery, ["testtesttest", 1, 11, 2, 0, "shadow-3-uuid-0", "shadowBanned3", 0, 50, "sponsor", "YouTube", 100, 0, 1, getHash("testtesttest", 1)]);
|
||||||
await db.prepare("run", insertQuery, ["testtesttest2", 1, 11, 2, 0, "shadow-3-uuid-0-1", "shadowBanned3", 0, 50, "sponsor", "PeerTube", 120, 0, 1, getHash("testtesttest2", 1)]);
|
await db.prepare("run", insertQuery, ["testtesttest2", 1, 11, 2, 0, "shadow-3-uuid-0-1", "shadowBanned3", 0, 50, "sponsor", "PeerTube", 120, 0, 1, getHash("testtesttest2", 1)]);
|
||||||
await db.prepare("run", insertQuery, ["testtesttest", 20, 33, 2, 0, "shadow-3-uuid-2", "shadowBanned3", 0, 50, "intro", "YouTube", 101, 0, 1, getHash("testtesttest", 1)]);
|
await db.prepare("run", insertQuery, ["testtesttest", 20, 33, 2, 0, "shadow-3-uuid-2", "shadowBanned3", 0, 50, "intro", "YouTube", 101, 0, 1, getHash("testtesttest", 1)]);
|
||||||
|
|
||||||
|
await db.prepare("run", insertQuery, ["testtesttest", 21, 34, 2, 0, "shadow-4-uuid-1", "shadowBanned4", 0, 50, "sponsor", "YouTube", 101, 0, 0, getHash("testtesttest", 1)]);
|
||||||
|
|
||||||
await db.prepare("run", `INSERT INTO "shadowBannedUsers" ("userID") VALUES(?)`, ["shadowBanned3"]);
|
await db.prepare("run", `INSERT INTO "shadowBannedUsers" ("userID") VALUES(?)`, ["shadowBanned3"]);
|
||||||
|
await db.prepare("run", `INSERT INTO "shadowBannedUsers" ("userID") VALUES(?)`, ["shadowBanned4"]);
|
||||||
|
|
||||||
await db.prepare("run", `INSERT INTO "vipUsers" ("userID") VALUES(?)`, [getHash("shadow-ban-vip")]);
|
await db.prepare("run", `INSERT INTO "vipUsers" ("userID") VALUES(?)`, [getHash("shadow-ban-vip")]);
|
||||||
});
|
});
|
||||||
@@ -106,4 +110,38 @@ describe("shadowBanUser", () => {
|
|||||||
.catch(err => done(err));
|
.catch(err => done(err));
|
||||||
});
|
});
|
||||||
|
|
||||||
|
it("Should get 409 when re-shadowbanning user", (done: Done) => {
|
||||||
|
fetch(`${getbaseURL()
|
||||||
|
}/api/shadowBanUser?userID=shadowBanned4&adminUserID=shadow-ban-vip&enabled=true&categories=["sponsor"]&unHideOldSubmissions=false`, {
|
||||||
|
method: "POST"
|
||||||
|
})
|
||||||
|
.then(async res => {
|
||||||
|
assert.strictEqual(res.status, 409);
|
||||||
|
const videoRow = await db.prepare("all", `SELECT "shadowHidden", "category" FROM "sponsorTimes" WHERE "userID" = ? AND "shadowHidden" = ?`, ["shadowBanned4", 0]);
|
||||||
|
const shadowRow = await db.prepare("get", `SELECT * FROM "shadowBannedUsers" WHERE "userID" = ?`, ["shadowBanned4"]);
|
||||||
|
assert.ok(shadowRow); // ban still exists
|
||||||
|
assert.strictEqual(videoRow.length, 1); // videos should not be hidden
|
||||||
|
assert.strictEqual(videoRow[0].category, "sponsor");
|
||||||
|
done();
|
||||||
|
})
|
||||||
|
.catch(err => done(err));
|
||||||
|
});
|
||||||
|
|
||||||
|
it("Should be able to re-shadowban user to hide old submissions", (done: Done) => {
|
||||||
|
fetch(`${getbaseURL()
|
||||||
|
}/api/shadowBanUser?userID=shadowBanned4&adminUserID=shadow-ban-vip&enabled=true&categories=["sponsor"]&unHideOldSubmissions=true`, {
|
||||||
|
method: "POST"
|
||||||
|
})
|
||||||
|
.then(async res => {
|
||||||
|
assert.strictEqual(res.status, 200);
|
||||||
|
const videoRow = await db.prepare("all", `SELECT "shadowHidden", "category" FROM "sponsorTimes" WHERE "userID" = ? AND "shadowHidden" = ?`, ["shadowBanned4", 1]);
|
||||||
|
const shadowRow = await db.prepare("get", `SELECT * FROM "shadowBannedUsers" WHERE "userID" = ?`, ["shadowBanned4"]);
|
||||||
|
assert.ok(shadowRow); // ban still exists
|
||||||
|
assert.strictEqual(videoRow.length, 1); // videos should be hidden
|
||||||
|
assert.strictEqual(videoRow[0].category, "sponsor");
|
||||||
|
done();
|
||||||
|
})
|
||||||
|
.catch(err => done(err));
|
||||||
|
});
|
||||||
|
|
||||||
});
|
});
|
||||||
|
|||||||
Reference in New Issue
Block a user