mirror of
https://github.com/ajayyy/SponsorBlockServer.git
synced 2025-12-12 14:37:17 +03:00
More logging
This commit is contained in:
@@ -47,6 +47,7 @@ addDefaults(config, {
|
|||||||
discordMaliciousReportWebhookURL: null,
|
discordMaliciousReportWebhookURL: null,
|
||||||
discordDeArrowLockedWebhookURL: null,
|
discordDeArrowLockedWebhookURL: null,
|
||||||
discordDeArrowWarnedWebhookURL: null,
|
discordDeArrowWarnedWebhookURL: null,
|
||||||
|
discordNewUserWebhookURL: null,
|
||||||
minReputationToSubmitChapter: 0,
|
minReputationToSubmitChapter: 0,
|
||||||
minReputationToSubmitFiller: 0,
|
minReputationToSubmitFiller: 0,
|
||||||
getTopUsersCacheTimeMinutes: 240,
|
getTopUsersCacheTimeMinutes: 240,
|
||||||
|
|||||||
@@ -60,10 +60,36 @@ export async function postBranding(req: Request, res: Response) {
|
|||||||
|
|
||||||
const permission = await canSubmitDeArrow(hashedUserID);
|
const permission = await canSubmitDeArrow(hashedUserID);
|
||||||
if (!permission.canSubmit) {
|
if (!permission.canSubmit) {
|
||||||
Logger.warn(`New user trying to submit dearrow: ${userID} ${videoID} ${title} ${req.headers["user-agent"]}`);
|
Logger.warn(`New user trying to submit dearrow: ${userID} ${videoID} ${videoDuration} ${title} ${req.headers["user-agent"]}`);
|
||||||
|
|
||||||
res.status(403).send(permission.reason);
|
res.status(403).send(permission.reason);
|
||||||
return;
|
return;
|
||||||
|
} else if (permission.newUser && config.discordNewUserWebhookURL) {
|
||||||
|
axios.post(config.discordNewUserWebhookURL, {
|
||||||
|
"embeds": [{
|
||||||
|
"title": userID,
|
||||||
|
"url": `https://www.youtube.com/watch?v=${videoID}`,
|
||||||
|
"description": `**User Agent**: ${userAgent}\
|
||||||
|
\n\n**Real User Agent**: ${req.headers["user-agent"]}\
|
||||||
|
\n**Video Duration**: ${videoDuration}`,
|
||||||
|
"color": 10813440,
|
||||||
|
"thumbnail": {
|
||||||
|
"url": getMaxResThumbnail(videoID),
|
||||||
|
},
|
||||||
|
}],
|
||||||
|
})
|
||||||
|
.then(res => {
|
||||||
|
if (res.status >= 400) {
|
||||||
|
Logger.error("Error sending reported submission Discord hook");
|
||||||
|
Logger.error(JSON.stringify((res.data)));
|
||||||
|
Logger.error("\n");
|
||||||
|
}
|
||||||
|
})
|
||||||
|
.catch(err => {
|
||||||
|
Logger.error("Failed to send reported submission Discord hook.");
|
||||||
|
Logger.error(JSON.stringify(err));
|
||||||
|
Logger.error("\n");
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
if (videoDuration && thumbnail && await checkForWrongVideoDuration(videoID, videoDuration)) {
|
if (videoDuration && thumbnail && await checkForWrongVideoDuration(videoID, videoDuration)) {
|
||||||
|
|||||||
@@ -513,6 +513,32 @@ export async function postSkipSegments(req: Request, res: Response): Promise<Res
|
|||||||
if (!permission.canSubmit) {
|
if (!permission.canSubmit) {
|
||||||
Logger.warn(`New user trying to submit: ${userID} ${videoID} ${videoDurationParam} ${userAgent} ${req.headers["user-agent"]}`);
|
Logger.warn(`New user trying to submit: ${userID} ${videoID} ${videoDurationParam} ${userAgent} ${req.headers["user-agent"]}`);
|
||||||
return res.status(403).send(permission.reason);
|
return res.status(403).send(permission.reason);
|
||||||
|
} else if (permission.newUser && config.discordNewUserWebhookURL) {
|
||||||
|
axios.post(config.discordNewUserWebhookURL, {
|
||||||
|
"embeds": [{
|
||||||
|
"title": userID,
|
||||||
|
"url": `https://www.youtube.com/watch?v=${videoID}`,
|
||||||
|
"description": `**User Agent**: ${userAgent}\
|
||||||
|
\n\n**Real User Agent**: ${req.headers["user-agent"]}\
|
||||||
|
\n**Video Duration**: ${videoDurationParam}`,
|
||||||
|
"color": 10813440,
|
||||||
|
"thumbnail": {
|
||||||
|
"url": getMaxResThumbnail(videoID),
|
||||||
|
},
|
||||||
|
}],
|
||||||
|
})
|
||||||
|
.then(res => {
|
||||||
|
if (res.status >= 400) {
|
||||||
|
Logger.error("Error sending reported submission Discord hook");
|
||||||
|
Logger.error(JSON.stringify((res.data)));
|
||||||
|
Logger.error("\n");
|
||||||
|
}
|
||||||
|
})
|
||||||
|
.catch(err => {
|
||||||
|
Logger.error("Failed to send reported submission Discord hook.");
|
||||||
|
Logger.error(JSON.stringify(err));
|
||||||
|
Logger.error("\n");
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
const invalidCheckResult = await checkInvalidFields(videoID, paramUserID, userID, segments, videoDurationParam, userAgent, service);
|
const invalidCheckResult = await checkInvalidFields(videoID, paramUserID, userID, segments, videoDurationParam, userAgent, service);
|
||||||
|
|||||||
@@ -55,6 +55,7 @@ export interface SBSConfig {
|
|||||||
discordMaliciousReportWebhookURL?: string;
|
discordMaliciousReportWebhookURL?: string;
|
||||||
discordDeArrowLockedWebhookURL?: string,
|
discordDeArrowLockedWebhookURL?: string,
|
||||||
discordDeArrowWarnedWebhookURL?: string,
|
discordDeArrowWarnedWebhookURL?: string,
|
||||||
|
discordNewUserWebhookURL?: string;
|
||||||
neuralBlockURL?: string;
|
neuralBlockURL?: string;
|
||||||
discordNeuralBlockRejectWebhookURL?: string;
|
discordNeuralBlockRejectWebhookURL?: string;
|
||||||
minReputationToSubmitChapter: number;
|
minReputationToSubmitChapter: number;
|
||||||
|
|||||||
@@ -9,11 +9,22 @@ import redis from "./redis";
|
|||||||
import { getReputation } from "./reputation";
|
import { getReputation } from "./reputation";
|
||||||
import { getServerConfig } from "./serverConfig";
|
import { getServerConfig } from "./serverConfig";
|
||||||
|
|
||||||
|
interface OldSubmitterResult {
|
||||||
|
canSubmit: boolean;
|
||||||
|
newUser: boolean;
|
||||||
|
}
|
||||||
|
|
||||||
interface CanSubmitResult {
|
interface CanSubmitResult {
|
||||||
canSubmit: boolean;
|
canSubmit: boolean;
|
||||||
reason: string;
|
reason: string;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
interface CanSubmitGlobalResult {
|
||||||
|
canSubmit: boolean;
|
||||||
|
newUser: boolean;
|
||||||
|
reason: string;
|
||||||
|
}
|
||||||
|
|
||||||
async function lowDownvotes(userID: HashedUserID): Promise<boolean> {
|
async function lowDownvotes(userID: HashedUserID): Promise<boolean> {
|
||||||
const result = await db.prepare("get", `SELECT count(*) as "submissionCount", SUM(CASE WHEN "votes" < 0 AND "views" > 5 THEN 1 ELSE 0 END) AS "downvotedSubmissions" FROM "sponsorTimes" WHERE "userID" = ?`
|
const result = await db.prepare("get", `SELECT count(*) as "submissionCount", SUM(CASE WHEN "votes" < 0 AND "views" > 5 THEN 1 ELSE 0 END) AS "downvotedSubmissions" FROM "sponsorTimes" WHERE "userID" = ?`
|
||||||
, [userID], { useReplica: true });
|
, [userID], { useReplica: true });
|
||||||
@@ -22,11 +33,11 @@ async function lowDownvotes(userID: HashedUserID): Promise<boolean> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
const fiveMinutes = 5 * 60 * 1000;
|
const fiveMinutes = 5 * 60 * 1000;
|
||||||
async function oldSubmitterOrAllowed(userID: HashedUserID): Promise<boolean> {
|
async function oldSubmitterOrAllowed(userID: HashedUserID): Promise<OldSubmitterResult> {
|
||||||
const submitterThreshold = await getServerConfig("old-submitter-block-date");
|
const submitterThreshold = await getServerConfig("old-submitter-block-date");
|
||||||
const maxUsers = await getServerConfig("max-users-per-minute");
|
const maxUsers = await getServerConfig("max-users-per-minute");
|
||||||
if (!submitterThreshold && !maxUsers) {
|
if (!submitterThreshold && !maxUsers) {
|
||||||
return true;
|
return { canSubmit: true, newUser: false };
|
||||||
}
|
}
|
||||||
|
|
||||||
const result = await db.prepare("get", `SELECT count(*) as "submissionCount" FROM "sponsorTimes" WHERE "userID" = ? AND "shadowHidden" = 0 AND "votes" >= 0 AND "timeSubmitted" < ?`
|
const result = await db.prepare("get", `SELECT count(*) as "submissionCount" FROM "sponsorTimes" WHERE "userID" = ? AND "shadowHidden" = 0 AND "votes" >= 0 AND "timeSubmitted" < ?`
|
||||||
@@ -39,18 +50,18 @@ async function oldSubmitterOrAllowed(userID: HashedUserID): Promise<boolean> {
|
|||||||
|
|
||||||
if (maxUsers && last5MinUsers < parseInt(maxUsers)) {
|
if (maxUsers && last5MinUsers < parseInt(maxUsers)) {
|
||||||
await redis.zAdd("submitters", { score: Date.now(), value: userID });
|
await redis.zAdd("submitters", { score: Date.now(), value: userID });
|
||||||
return true;
|
return { canSubmit: true, newUser: true };
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return isOldSubmitter;
|
return { canSubmit: isOldSubmitter, newUser: false };
|
||||||
}
|
}
|
||||||
|
|
||||||
async function oldDeArrowSubmitterOrAllowed(userID: HashedUserID): Promise<boolean> {
|
async function oldDeArrowSubmitterOrAllowed(userID: HashedUserID): Promise<OldSubmitterResult> {
|
||||||
const submitterThreshold = await getServerConfig("old-submitter-block-date");
|
const submitterThreshold = await getServerConfig("old-submitter-block-date");
|
||||||
const maxUsers = await getServerConfig("max-users-per-minute-dearrow");
|
const maxUsers = await getServerConfig("max-users-per-minute-dearrow");
|
||||||
if (!submitterThreshold && !maxUsers) {
|
if (!submitterThreshold && !maxUsers) {
|
||||||
return true;
|
return { canSubmit: true, newUser: false };
|
||||||
}
|
}
|
||||||
|
|
||||||
const result = await db.prepare("get", `SELECT count(*) as "submissionCount" FROM "titles" JOIN "titleVotes" ON "titles"."UUID" = "titleVotes"."UUID" WHERE "userID" = ? AND "shadowHidden" = 0 AND "votes" >= 0 AND "timeSubmitted" < ?`
|
const result = await db.prepare("get", `SELECT count(*) as "submissionCount" FROM "titles" JOIN "titleVotes" ON "titles"."UUID" = "titleVotes"."UUID" WHERE "userID" = ? AND "shadowHidden" = 0 AND "votes" >= 0 AND "timeSubmitted" < ?`
|
||||||
@@ -62,7 +73,7 @@ async function oldDeArrowSubmitterOrAllowed(userID: HashedUserID): Promise<boole
|
|||||||
const voteResult = await privateDB.prepare("get", `SELECT "UUID" from "titleVotes" where "userID" = ?`, [userID], { useReplica: true });
|
const voteResult = await privateDB.prepare("get", `SELECT "UUID" from "titleVotes" where "userID" = ?`, [userID], { useReplica: true });
|
||||||
if (voteResult?.UUID) {
|
if (voteResult?.UUID) {
|
||||||
// Count at least one vote as an old submitter as well
|
// Count at least one vote as an old submitter as well
|
||||||
return true;
|
return { canSubmit: true, newUser: false };
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -71,11 +82,11 @@ async function oldDeArrowSubmitterOrAllowed(userID: HashedUserID): Promise<boole
|
|||||||
|
|
||||||
if (maxUsers && last5MinUsers < parseInt(maxUsers)) {
|
if (maxUsers && last5MinUsers < parseInt(maxUsers)) {
|
||||||
await redis.zAdd("submittersDeArrow", { score: Date.now(), value: userID });
|
await redis.zAdd("submittersDeArrow", { score: Date.now(), value: userID });
|
||||||
return true;
|
return { canSubmit: true, newUser: true };
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return isOldSubmitter;
|
return { canSubmit: isOldSubmitter, newUser: false };
|
||||||
}
|
}
|
||||||
|
|
||||||
export async function canSubmit(userID: HashedUserID, category: Category): Promise<CanSubmitResult> {
|
export async function canSubmit(userID: HashedUserID, category: Category): Promise<CanSubmitResult> {
|
||||||
@@ -97,20 +108,26 @@ export async function canSubmit(userID: HashedUserID, category: Category): Promi
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
export async function canSubmitGlobal(userID: HashedUserID): Promise<CanSubmitResult> {
|
export async function canSubmitGlobal(userID: HashedUserID): Promise<CanSubmitGlobalResult> {
|
||||||
|
const oldSubmitterOrAllowedPromise = oldSubmitterOrAllowed(userID);
|
||||||
|
|
||||||
return {
|
return {
|
||||||
canSubmit: await oneOf([isUserVIP(userID),
|
canSubmit: await oneOf([isUserVIP(userID),
|
||||||
oldSubmitterOrAllowed(userID)
|
(async () => (await oldSubmitterOrAllowedPromise).canSubmit)()
|
||||||
]),
|
]),
|
||||||
|
newUser: (await oldSubmitterOrAllowedPromise).newUser,
|
||||||
reason: "We are currently experiencing a mass spam attack, we are restricting submissions for now"
|
reason: "We are currently experiencing a mass spam attack, we are restricting submissions for now"
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
export async function canSubmitDeArrow(userID: HashedUserID): Promise<CanSubmitResult> {
|
export async function canSubmitDeArrow(userID: HashedUserID): Promise<CanSubmitGlobalResult> {
|
||||||
|
const oldSubmitterOrAllowedPromise = oldDeArrowSubmitterOrAllowed(userID);
|
||||||
|
|
||||||
return {
|
return {
|
||||||
canSubmit: await oneOf([isUserVIP(userID),
|
canSubmit: await oneOf([isUserVIP(userID),
|
||||||
oldDeArrowSubmitterOrAllowed(userID)
|
(async () => (await oldSubmitterOrAllowedPromise).canSubmit)()
|
||||||
]),
|
]),
|
||||||
|
newUser: (await oldSubmitterOrAllowedPromise).newUser,
|
||||||
reason: "We are currently experiencing a mass spam attack, we are restricting submissions for now"
|
reason: "We are currently experiencing a mass spam attack, we are restricting submissions for now"
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
Reference in New Issue
Block a user