Block voting without submitting and on the same IP

This commit is contained in:
Ajay Ramachandran
2020-07-25 21:35:43 -04:00
parent 005e88d169
commit e71680c8e3
3 changed files with 96 additions and 41 deletions

View File

@@ -49,8 +49,8 @@ app.get('/api/skipSegments', getSkipSegments);
app.post('/api/skipSegments', postSkipSegments);
//voting endpoint
app.get('/api/voteOnSponsorTime', voteOnSponsorTime);
app.post('/api/voteOnSponsorTime', voteOnSponsorTime);
app.get('/api/voteOnSponsorTime', voteOnSponsorTime.endpoint);
app.post('/api/voteOnSponsorTime', voteOnSponsorTime.endpoint);
//Endpoint when a sponsorTime is used up
app.get('/api/viewedVideoSponsorTime', viewedVideoSponsorTime);

View File

@@ -71,7 +71,7 @@ function categoryVote(UUID, userID, isVIP, category, hashedIP, res) {
res.sendStatus(200);
}
module.exports = async function voteOnSponsorTime(req, res) {
async function voteOnSponsorTime(req, res) {
let UUID = req.query.UUID;
let userID = req.query.userID;
let type = req.query.type;
@@ -131,6 +131,9 @@ module.exports = async function voteOnSponsorTime(req, res) {
} else if (type == 0 || type == 10) {
//downvote
incrementAmount = -1;
} else if (type == 20) {
//undo/cancel vote
incrementAmount = 0;
} else {
//unrecongnised type of vote
res.sendStatus(400);
@@ -243,54 +246,67 @@ module.exports = async function voteOnSponsorTime(req, res) {
}
}
//update the votes table
if (votesRow != undefined) {
privateDB.prepare('run', "UPDATE votes SET type = ? WHERE userID = ? AND UUID = ?", [type, userID, UUID]);
} else {
privateDB.prepare('run', "INSERT INTO votes VALUES(?, ?, ?, ?)", [UUID, userID, hashedIP, type]);
}
// Only change the database if they have made a submission before and haven't voted recently
let ableToVote = isVIP
|| (db.prepare("get", "SELECT count(*) as count FROM sponsorTimes WHERE userID = ?", [nonAnonUserID]).count > 0
&& privateDB.prepare("get", "SELECT count(*) as count FROM votes WHERE UUID = ? AND hashedIP = ? AND userID != ?", [UUID, hashedIP, userID]).count === 0);
let columnName = "";
if (voteTypeEnum === voteTypes.normal) {
columnName = "votes";
} else if (voteTypeEnum === voteTypes.incorrect) {
columnName = "incorrectVotes";
}
//update the vote count on this sponsorTime
//oldIncrementAmount will be zero is row is null
db.prepare('run', "UPDATE sponsorTimes SET " + columnName + " = " + columnName + " + ? WHERE UUID = ?", [incrementAmount - oldIncrementAmount, UUID]);
//for each positive vote, see if a hidden submission can be shown again
if (incrementAmount > 0 && voteTypeEnum === voteTypes.normal) {
//find the UUID that submitted the submission that was voted on
let submissionUserIDInfo = db.prepare('get', "SELECT userID FROM sponsorTimes WHERE UUID = ?", [UUID]);
if (!submissionUserIDInfo) {
// They are voting on a non-existent submission
res.status(400).send("Voting on a non-existent submission");
return;
if (ableToVote) {
//update the votes table
if (votesRow != undefined) {
privateDB.prepare('run', "UPDATE votes SET type = ? WHERE userID = ? AND UUID = ?", [type, userID, UUID]);
} else {
privateDB.prepare('run', "INSERT INTO votes VALUES(?, ?, ?, ?)", [UUID, userID, hashedIP, type]);
}
let submissionUserID = submissionUserIDInfo.userID;
let columnName = "";
if (voteTypeEnum === voteTypes.normal) {
columnName = "votes";
} else if (voteTypeEnum === voteTypes.incorrect) {
columnName = "incorrectVotes";
}
//check if any submissions are hidden
let hiddenSubmissionsRow = db.prepare('get', "SELECT count(*) as hiddenSubmissions FROM sponsorTimes WHERE userID = ? AND shadowHidden > 0", [submissionUserID]);
//update the vote count on this sponsorTime
//oldIncrementAmount will be zero is row is null
db.prepare('run', "UPDATE sponsorTimes SET " + columnName + " = " + columnName + " + ? WHERE UUID = ?", [incrementAmount - oldIncrementAmount, UUID]);
if (hiddenSubmissionsRow.hiddenSubmissions > 0) {
//see if some of this users submissions should be visible again
if (await isUserTrustworthy(submissionUserID)) {
//they are trustworthy again, show 2 of their submissions again, if there are two to show
db.prepare('run', "UPDATE sponsorTimes SET shadowHidden = 0 WHERE ROWID IN (SELECT ROWID FROM sponsorTimes WHERE userID = ? AND shadowHidden = 1 LIMIT 2)", [submissionUserID]);
//for each positive vote, see if a hidden submission can be shown again
if (incrementAmount > 0 && voteTypeEnum === voteTypes.normal) {
//find the UUID that submitted the submission that was voted on
let submissionUserIDInfo = db.prepare('get', "SELECT userID FROM sponsorTimes WHERE UUID = ?", [UUID]);
if (!submissionUserIDInfo) {
// They are voting on a non-existent submission
res.status(400).send("Voting on a non-existent submission");
return;
}
let submissionUserID = submissionUserIDInfo.userID;
//check if any submissions are hidden
let hiddenSubmissionsRow = db.prepare('get', "SELECT count(*) as hiddenSubmissions FROM sponsorTimes WHERE userID = ? AND shadowHidden > 0", [submissionUserID]);
if (hiddenSubmissionsRow.hiddenSubmissions > 0) {
//see if some of this users submissions should be visible again
if (await isUserTrustworthy(submissionUserID)) {
//they are trustworthy again, show 2 of their submissions again, if there are two to show
db.prepare('run', "UPDATE sponsorTimes SET shadowHidden = 0 WHERE ROWID IN (SELECT ROWID FROM sponsorTimes WHERE userID = ? AND shadowHidden = 1 LIMIT 2)", [submissionUserID]);
}
}
}
}
//added to db
res.sendStatus(200);
} catch (err) {
console.error(err);
res.status(500).json({error: 'Internal error creating segment vote'});
}
}
}
module.exports = {
voteOnSponsorTime,
endpoint: function (req, res) {
voteOnSponsorTime(req, res);
},
};

View File

@@ -7,16 +7,19 @@ describe('voteOnSponsorTime', () => {
before(() => {
let startOfQuery = "INSERT INTO sponsorTimes (videoID, startTime, endTime, votes, UUID, userID, timeSubmitted, views, category, shadowHidden) VALUES";
db.exec(startOfQuery + "('vote-testtesttest', 1, 11, 2, 'vote-uuid-0', 'testman', 0, 50, 'sponsor', 0)");
db.exec(startOfQuery + "('vote-testtesttest', 20, 33, 10, 'vote-uuid-2', 'testman', 0, 50, 'intro', 0)");
db.exec(startOfQuery + "('vote-testtesttest2', 1, 11, 2, 'vote-uuid-1', 'testman', 0, 50, 'sponsor', 0)");
db.exec(startOfQuery + "('vote-testtesttest2', 1, 11, 10, 'vote-uuid-1.5', 'testman', 0, 50, 'outro', 0)");
db.exec(startOfQuery + "('vote-testtesttest3', 20, 33, 10, 'vote-uuid-2', 'testman', 0, 50, 'intro', 0)");
db.exec(startOfQuery + "('vote-testtesttest,test', 1, 11, 100, 'vote-uuid-3', 'testman', 0, 50, 'sponsor', 0)");
db.exec(startOfQuery + "('vote-test3', 1, 11, 2, 'vote-uuid-4', 'testman', 0, 50, 'sponsor', 0)");
db.exec(startOfQuery + "('vote-test3', 7, 22, -3, 'vote-uuid-5', 'testman', 0, 50, 'intro', 0)");
db.exec(startOfQuery + "('vote-multiple', 1, 11, 2, 'vote-uuid-6', 'testman', 0, 50, 'intro', 0)");
db.exec(startOfQuery + "('vote-multiple', 20, 33, 2, 'vote-uuid-7', 'testman', 0, 50, 'intro', 0)");
db.exec(startOfQuery + "('voter-submitter', 1, 11, 2, 'vote-uuid-8', '" + getHash("randomID") + "', 0, 50, 'sponsor', 0)");
db.exec(startOfQuery + "('voter-submitter2', 1, 11, 2, 'vote-uuid-9', '" + getHash("randomID2") + "', 0, 50, 'sponsor', 0)");
db.exec("INSERT INTO vipUsers (userID) VALUES ('" + getHash("VIPUser") + "')");
});
it('Should be able to upvote a segment', (done) => {
request.get(utils.getbaseURL()
@@ -54,6 +57,42 @@ describe('voteOnSponsorTime', () => {
});
});
it("Should not be able to upvote a segment if the user hasn't submitted yet", (done) => {
request.get(utils.getbaseURL()
+ "/api/voteOnSponsorTime?userID=hasNotSubmittedID&UUID=vote-uuid-1&type=1", null,
(err, res, body) => {
if (err) done(err);
else if (res.statusCode === 200) {
let row = db.prepare('get', "SELECT votes FROM sponsorTimes WHERE UUID = ?", ["vote-uuid-1"]);
if (row.votes === 2) {
done()
} else {
done("Vote did not fail. Submission went from 2 votes to " + row.votes);
}
} else {
done("Status code was " + res.statusCode);
}
});
});
it("Should not be able to downvote a segment if the user hasn't submitted yet", (done) => {
request.get(utils.getbaseURL()
+ "/api/voteOnSponsorTime?userID=hasNotSubmittedID&UUID=vote-uuid-1.5&type=0", null,
(err, res, body) => {
if (err) done(err);
else if (res.statusCode === 200) {
let row = db.prepare('get', "SELECT votes FROM sponsorTimes WHERE UUID = ?", ["vote-uuid-1.5"]);
if (row.votes === 10) {
done()
} else {
done("Vote did not fail. Submission went from 10 votes to " + row.votes);
}
} else {
done("Status code was " + res.statusCode);
}
});
});
it('VIP should be able to completely downvote a segment', (done) => {
request.get(utils.getbaseURL()
+ "/api/voteOnSponsorTime?userID=VIPUser&UUID=vote-uuid-3&type=0", null,