diff --git a/databases/_upgrade_sponsorTimes_2.sql b/databases/_upgrade_sponsorTimes_2.sql new file mode 100644 index 0000000..46c0fad --- /dev/null +++ b/databases/_upgrade_sponsorTimes_2.sql @@ -0,0 +1,13 @@ +BEGIN TRANSACTION; + +/* Add incorrectVotes field */ +CREATE TABLE "noSegments" ( + "videoID" TEXT NOT NULL, + "userID" TEXT NOT NULL, + "category" TEXT NOT NULL +); + +/* Add version to config */ +UPDATE config SET value = 2 WHERE key = 'version'; + +COMMIT; \ No newline at end of file diff --git a/index.js b/index.js index 508c089..a877bab 100644 --- a/index.js +++ b/index.js @@ -1,5 +1,6 @@ var config = require('./src/config.js'); var createServer = require('./src/app.js'); +const logger = require('./src/utils/logger.js'); var server = createServer(() => { - console.log("Server started on port " + config.port + "."); + logger.info("Server started on port " + config.port + "."); }); diff --git a/src/app.js b/src/app.js index 1ce1674..ef6c554 100644 --- a/src/app.js +++ b/src/app.js @@ -21,6 +21,7 @@ var getViewsForUser = require('./routes/getViewsForUser.js'); var getTopUsers = require('./routes/getTopUsers.js'); var getTotalStats = require('./routes/getTotalStats.js'); var getDaysSavedFormatted = require('./routes/getDaysSavedFormatted.js'); +var postNoSegments = require('./routes/postNoSegments.js'); // Old Routes var oldGetVideoSponsorTimes = require('./routes/oldGetVideoSponsorTimes.js'); @@ -86,6 +87,9 @@ app.get('/api/getTotalStats', getTotalStats); //send out a formatted time saved total app.get('/api/getDaysSavedFormatted', getDaysSavedFormatted); +//submit video containing no segments +app.post('/api/postNoSegments', postNoSegments); + app.get('/database.db', function (req, res) { res.sendFile("./databases/sponsorTimes.db", { root: "./" }); }); diff --git a/src/databases/databases.js b/src/databases/databases.js index 1a1b448..a3aeb59 100644 --- a/src/databases/databases.js +++ b/src/databases/databases.js @@ -3,7 +3,8 @@ var Sqlite3 = require('better-sqlite3'); var fs = require('fs'); var path = require('path'); var Sqlite = require('./Sqlite.js') -var Mysql = require('./Mysql.js') +var Mysql = require('./Mysql.js'); +const logger = require('../utils/logger.js'); let options = { readonly: config.readOnly, @@ -60,12 +61,16 @@ if (config.mysql) { let versionCodeInfo = db.prepare("SELECT value FROM config WHERE key = ?").get("version"); let versionCode = versionCodeInfo ? versionCodeInfo.value : 0; - let path = config.schemaFolder + "/_upgrade_" + prefix + "_" + (versionCode + 1) + ".sql"; + let path = config.schemaFolder + "/_upgrade_" + prefix + "_" + (parseInt(versionCode) + 1) + ".sql"; + logger.debug('db update: trying ' + path); while (fs.existsSync(path)) { + logger.debug('db update: updating ' + path); db.exec(fs.readFileSync(path).toString()); versionCode = db.prepare("SELECT value FROM config WHERE key = ?").get("version").value; - path = config.schemaFolder + "/_upgrade_" + prefix + "_" + (versionCode + 1) + ".sql"; + path = config.schemaFolder + "/_upgrade_" + prefix + "_" + (parseInt(versionCode) + 1) + ".sql"; + logger.debug('db update: trying ' + path); } + logger.debug('db update: no file ' + path); } } \ No newline at end of file diff --git a/src/routes/postNoSegments.js b/src/routes/postNoSegments.js new file mode 100644 index 0000000..58074b8 --- /dev/null +++ b/src/routes/postNoSegments.js @@ -0,0 +1,31 @@ +const getHash = require('../utils/getHash.js'); +const isUserVIP = require('../utils/isUserVIP.js'); + +module.exports = (req, res) => { + // Collect user input data + let videoID = req.body.videoID; + let userID = req.body.userID; + let categorys = req.body.categorys; + + // Check input data is valid + if (!videoID + || !userID + || !categorys + || !Array.isArray(categorys) + || categorys.length === 0 + ) { + res.status(400).json({}); + return; + } + + // Check if user is VIP + userID = getHash(userID); + let userIsVIP = isUserVIP(userID); + + if (!userIsVIP) { + res.status(403).json({}); + return; + } + + res.status(200).json({status: 200}); +}; \ No newline at end of file diff --git a/src/routes/voteOnSponsorTime.js b/src/routes/voteOnSponsorTime.js index 0e9fdf8..9ce6afa 100644 --- a/src/routes/voteOnSponsorTime.js +++ b/src/routes/voteOnSponsorTime.js @@ -4,7 +4,7 @@ var config = require('../config.js'); var getHash = require('../utils/getHash.js'); var getIP = require('../utils/getIP.js'); var getFormattedTime = require('../utils/getFormattedTime.js'); -var isUserTrustworthy = require('../utils/isUserTrustworthy.js') +var isUserTrustworthy = require('../utils/isUserTrustworthy.js'); var databases = require('../databases/databases.js'); var db = databases.db; diff --git a/src/utils/isUserVIP.js b/src/utils/isUserVIP.js new file mode 100644 index 0000000..eeb25dc --- /dev/null +++ b/src/utils/isUserVIP.js @@ -0,0 +1,8 @@ +const databases = require('../databases/databases.js'); +const db = databases.db; + +module.exports = (userID) => { + return db.prepare('get', "SELECT count(*) as userCount FROM vipUsers WHERE userID = ?", [userID]).userCount > 0; +} + + diff --git a/src/utils/logger.js b/src/utils/logger.js index 70fe13e..351e45c 100644 --- a/src/utils/logger.js +++ b/src/utils/logger.js @@ -17,6 +17,8 @@ const settings = { if (config.mode === 'development') { settings.INFO = true; settings.DEBUG = true; +} else if (config.mode === 'test') { + settings.DEBUG = true; } function log(level, string) { diff --git a/test.js b/test.js index 45ace90..9810786 100644 --- a/test.js +++ b/test.js @@ -9,6 +9,7 @@ if (fs.existsSync(config.privateDB)) fs.unlinkSync(config.privateDB); var createServer = require('./src/app.js'); var createMockServer = require('./test/mocks.js'); +const logger = require('./src/utils/logger.js'); // Instantiate a Mocha instance. var mocha = new Mocha(); @@ -27,9 +28,9 @@ fs.readdirSync(testDir).filter(function(file) { }); var mockServer = createMockServer(() => { - console.log("Started mock HTTP Server"); + logger.info("Started mock HTTP Server"); var server = createServer(() => { - console.log("Started main HTTP server"); + logger.info("Started main HTTP server"); // Run the tests. mocha.run(function(failures) { mockServer.close(); diff --git a/test/cases/postNoSegments.js b/test/cases/postNoSegments.js new file mode 100644 index 0000000..5ab2b3d --- /dev/null +++ b/test/cases/postNoSegments.js @@ -0,0 +1,175 @@ +var request = require('request'); + +var utils = require('../utils.js'); +const getHash = require('../../src/utils/getHash.js'); + +var databases = require('../../src/databases/databases.js'); +var db = databases.db; + +describe('postNoSegments', () => { + before(() => { + db.exec("INSERT INTO vipUsers (userID) VALUES ('" + getHash("VIPUser-noSegments") + "')"); + }); + + it('should update the database version when starting the application', (done) => { + let version = db.prepare('get', 'SELECT key, value FROM config where key = ?', ['version']).value; + if (version > 1) done(); + else done('Version isn\'t greater that 1. Version is ' + version); + }); + + it('Should be able to submit no segments', (done) => { + let json = { + videoID: 'noSegmentsTestVideoID', + userID: 'VIPUser-noSegments', + categorys: [ + 'sponsor' + ] + }; + + request.post(utils.getbaseURL() + + "/api/postNoSegments", {json}, + (err, res, body) => { + if (err) done(err); + else if (res.statusCode === 200) { + //let row = db.prepare('get', "SELECT startTime, endTime, category FROM sponsorTimes WHERE videoID = ?", ["noSegmentsTestVideoID"]); + //if (row.startTime === 2 && row.endTime === 10 && row.category === "sponsor") { + done() + //} else { + // done("Submitted times were not saved. Actual submission: " + JSON.stringify(row)); + //} + } else { + console.log(body); + done("Status code was " + res.statusCode); + } + }); + }); + + it('Should return 400 for missing params', (done) => { + request.post(utils.getbaseURL() + + "/api/postNoSegments", {json: {}}, + (err, res, body) => { + if (err) done(err); + else if (res.statusCode === 400) { + done() + } else { + done("Status code was " + res.statusCode); + } + }); + }); + + it('Should return 400 for no categorys', (done) => { + let json = { + videoID: 'test', + userID: 'test', + categorys: [] + }; + + request.post(utils.getbaseURL() + + "/api/postNoSegments", {json}, + (err, res, body) => { + if (err) done(err); + else if (res.statusCode === 400) { + done() + } else { + done("Status code was " + res.statusCode); + } + }); + }); + + it('Should return 400 for no userID', (done) => { + let json = { + videoID: 'test', + userID: null, + categorys: ['sponsor'] + }; + + request.post(utils.getbaseURL() + + "/api/postNoSegments", {json}, + (err, res, body) => { + if (err) done(err); + else if (res.statusCode === 400) { + done() + } else { + done("Status code was " + res.statusCode); + } + }); + }); + + it('Should return 400 for no videoID', (done) => { + let json = { + videoID: null, + userID: 'test', + categorys: ['sponsor'] + }; + + request.post(utils.getbaseURL() + + "/api/postNoSegments", {json}, + (err, res, body) => { + if (err) done(err); + else if (res.statusCode === 400) { + done() + } else { + done("Status code was " + res.statusCode); + } + }); + }); + + it('Should return 400 object categorys)', (done) => { + let json = { + videoID: 'test', + userID: 'test', + categorys: {} + }; + + request.post(utils.getbaseURL() + + "/api/postNoSegments", {json}, + (err, res, body) => { + if (err) done(err); + else if (res.statusCode === 400) { + done() + } else { + done("Status code was " + res.statusCode); + } + }); + }); + + it('Should return 400 bad format categorys', (done) => { + let json = { + videoID: 'test', + userID: 'test', + categorys: 'sponsor' + }; + + request.post(utils.getbaseURL() + + "/api/postNoSegments", {json}, + (err, res, body) => { + if (err) done(err); + else if (res.statusCode === 400) { + done() + } else { + done("Status code was " + res.statusCode); + } + }); + }); + + it('Should return 403 if user is not VIP', (done) => { + let json = { + videoID: 'test', + userID: 'test', + categorys: [ + 'sponsor' + ] + }; + + request.post(utils.getbaseURL() + + "/api/postNoSegments", {json}, + (err, res, body) => { + if (err) done(err); + else if (res.statusCode === 403) { + done() + } else { + done("Status code was " + res.statusCode); + } + }); + }); +}); \ No newline at end of file