diff --git a/.env.example b/.env.example index bdbddab..d942911 100644 --- a/.env.example +++ b/.env.example @@ -6,6 +6,8 @@ PGPASSWORD=dbuserpassword PGDATABASE=mydatabase PGPORT=5432 +PUBLIC_SUBMIT_PAGE=false + #MAIL_FROM=fromaddress@example.com #MAIL_HOST=smtp.smtphost.net #MAIL_PORT=465 diff --git a/database/database.js b/database/database.js index 08c1a37..c0b7257 100644 --- a/database/database.js +++ b/database/database.js @@ -40,7 +40,7 @@ async function checkForDatabaseInitialization() { let latestMigration; try { const latestMigrationQuery = `SELECT value FROM metadata WHERE property = 'latest_migration';`; - latestMigration = (await executeQuery(latestMigrationQuery))[0][0]; + latestMigration = +((await executeQuery(latestMigrationQuery))[0][0]); } catch { latestMigration = 0; } @@ -54,7 +54,7 @@ async function performMigrations(currentMigration) { const migrationFileList = fs.readdirSync('database/migrations'); const latestMigration = +migrationFileList[migrationFileList.length - 1].slice(0, 1); - for(let i = currentMigration + 1; i <= latestMigration; i++) { + for(let i = +currentMigration + 1; i <= latestMigration; i++) { const sql = fs.readFileSync(`database/migrations/${i}.sql`).toString(); await executeQuery(sql); console.log(`Performed database migration ${i}`); diff --git a/database/init_database.sql b/database/init_database.sql index 83ff6c4..8cd8747 100644 --- a/database/init_database.sql +++ b/database/init_database.sql @@ -15,14 +15,14 @@ scores: *season_id* | school_year games: - *game_id* | ~division_id~ | ~season_id~ | game_date | ~team1_id~ | ~team2_id~ | team1_score | team2_score | ~submitter_id~ | updated_timestamp + *game_id* | ~division_id~ | ~season_id~ | game_date | ~team1_id~ | ~team2_id~ | team1_score | team2_score | ~submitter_id~ | updated_timestamp | submitter_name accounts: users: - *user_id* | email | password | admin + *user_id* | email | password | admin | full_name */ @@ -91,7 +91,8 @@ CREATE TABLE IF NOT EXISTS scores.games( team2_id BIGINT NOT NULL, team1_score INTEGER NOT NULL, team2_score INTEGER NOT NULL, - submitter_id BIGINT NOT NULL, + submitter_name TEXT, + submitter_id BIGINT, updated_timestamp TIMESTAMP WITH TIME ZONE DEFAULT now(), PRIMARY KEY(game_id), CONSTRAINT fk_division @@ -118,6 +119,6 @@ CREATE TABLE IF NOT EXISTS metadata( ); INSERT INTO metadata(property, value) - VALUES("latest_migration", "2"); + VALUES("latest_migration", "3"); COMMIT; \ No newline at end of file diff --git a/database/migrations/3.sql b/database/migrations/3.sql new file mode 100644 index 0000000..117779a --- /dev/null +++ b/database/migrations/3.sql @@ -0,0 +1,15 @@ +/* ADD OPTIONAL SUBMITTER NAME COLUMN IN GAMES TABLE */ + +BEGIN; + +ALTER TABLE scores.games ALTER COLUMN submitter_id DROP NOT NULL; + +ALTER TABLE scores.games +ADD COLUMN submitter_name TEXT; + + +UPDATE metadata +SET value = '3' +WHERE property = 'latest_migration'; + +COMMIT; \ No newline at end of file diff --git a/database/scores/games.js b/database/scores/games.js index 4c5b22e..5680c58 100644 --- a/database/scores/games.js +++ b/database/scores/games.js @@ -5,7 +5,7 @@ const database = require('./../database'); class Game { - constructor(id, date, team1ID, team2ID, team1Score, team2Score, divisionID, seasonID, submitterID) { + constructor(id, date, team1ID, team2ID, team1Score, team2Score, divisionID, seasonID, submitterID, submitterName) { this.id = id; this.date = date; this.team1ID = team1ID; @@ -15,17 +15,26 @@ class Game { this.divisionID = divisionID; this.seasonID = seasonID; this.submitterID = submitterID; + this.submitterName = submitterName; } } -async function add(divisionID, seasonID, date, team1ID, team2ID, team1Score, team2Score, userID) { - const query = `INSERT INTO scores.games(division_id, season_id, game_date, team1_id, team2_id, team1_score, team2_score, submitter_id) - VALUES($1, $2, $3, $4, $5, $6, $7, $8) - RETURNING game_id;`; +async function add(divisionID, seasonID, date, team1ID, team2ID, team1Score, team2Score, submitterID, submitterName = undefined) { + let id; + if(submitterName) { + const query = `INSERT INTO scores.games(division_id, season_id, game_date, team1_id, team2_id, team1_score, team2_score, submitter_name) + VALUES($1, $2, $3, $4, $5, $6, $7, $8) + RETURNING game_id;`; + id = (await database.executeQuery(query, [divisionID, seasonID, date, team1ID, team2ID, team1Score, team2Score, submitterName]))[0][0]; + } else { + const query = `INSERT INTO scores.games(division_id, season_id, game_date, team1_id, team2_id, team1_score, team2_score, submitter_id) + VALUES($1, $2, $3, $4, $5, $6, $7, $8) + RETURNING game_id;`; + id = (await database.executeQuery(query, [divisionID, seasonID, date, team1ID, team2ID, team1Score, team2Score, submitterID]))[0][0]; + } - const id = (await database.executeQuery(query, [divisionID, seasonID, date, team1ID, team2ID, team1Score, team2Score, userID]))[0][0]; return new Game(id, date, team1ID, team2ID, team1Score, team2Score); } @@ -41,14 +50,14 @@ async function retrieve(teamID, divisionID, seasonID) { let table; if(teamID && divisionID && seasonID) { - const query = `SELECT game_id, division_id, season_id, game_date, team1_id, team2_id, team1_score, team2_score, submitter_id + const query = `SELECT game_id, division_id, season_id, game_date, team1_id, team2_id, team1_score, team2_score, submitter_id, submitter_name FROM scores.games WHERE (team1_id = $1 OR team2_id = $1) AND division_id = $2 AND season_id = $3 ORDER BY game_date DESC;`; table = await database.executeQuery(query, [teamID,divisionID,seasonID]); } else { - const query = `SELECT game_id, division_id, season_id, game_date, team1_id, team2_id, team1_score, team2_score, submitter_id + const query = `SELECT game_id, division_id, season_id, game_date, team1_id, team2_id, team1_score, team2_score, submitter_id, submitter_name FROM scores.games ORDER BY game_date DESC;`; table = await database.executeQuery(query); @@ -63,10 +72,10 @@ async function retrieve(teamID, divisionID, seasonID) { const teamScore = opponentIsTeam2 ? row[6] : row[7]; const opponentScore = opponentIsTeam2 ? row[7] : row[6]; - gamesList.push(new Game(row[0], row[3].toISOString().slice(0,10), teamID, opponentID, teamScore, opponentScore, row[1], row[2], row[8])); + gamesList.push(new Game(row[0], row[3].toISOString().slice(0,10), teamID, opponentID, teamScore, opponentScore, row[1], row[2], row[8], row[9])); } else { - gamesList.push(new Game(row[0], row[3].toISOString().slice(0,10), row[4], row[5], row[6], row[7], row[1], row[2], row[8])); + gamesList.push(new Game(row[0], row[3].toISOString().slice(0,10), row[4], row[5], row[6], row[7], row[1], row[2], row[8], row[9])); } }); return gamesList; diff --git a/public/scripts/manage.js b/public/scripts/manage.js index 2b958f9..a77a7d6 100644 --- a/public/scripts/manage.js +++ b/public/scripts/manage.js @@ -291,8 +291,13 @@ CATEGORIES.push(new Category( row.appendChild(dateCell); const submitterCell = document.createElement('td'); - Data.getAccount(game.submitterID) - .then(data => submitterCell.textContent = data.name); + if(game.submitterID) { + Data.getAccount(game.submitterID) + .then(data => submitterCell.textContent = data.name); + } else { + submitterCell.textContent = game.submitterName; + console.log(game.submitterName); + } row.appendChild(submitterCell); }, async function addGame() { diff --git a/public/scripts/manage/game.js b/public/scripts/manage/game.js index 9b0e86e..5d0bd29 100644 --- a/public/scripts/manage/game.js +++ b/public/scripts/manage/game.js @@ -12,6 +12,7 @@ const team1Dropdown = document.getElementById('team1-dropdown'); const team2Dropdown = document.getElementById('team2-dropdown'); const team1ScoreTextbox = document.getElementById('team1-score-textbox'); const team2ScoreTextbox = document.getElementById('team2-score-textbox'); +const nameTextbox = document.getElementById('name-textbox'); const submitButton = document.getElementById('submit-button'); const deleteButton = document.getElementById('delete-button'); @@ -70,6 +71,9 @@ async function initializeForm() { team2Dropdown.disabled = false; team1ScoreTextbox.disabled = false; team2ScoreTextbox.disabled = false; + if(nameTextbox) { + nameTextbox.disabled = false; + } sportDropdown.onchange = async () => { await Form.populateGenders(genderDropdown, sportDropdown.value) @@ -89,6 +93,7 @@ async function initializeForm() { team1ScoreTextbox.addEventListener('keyup', checkDataValidity); team2Dropdown.onchange = checkDataValidity; team2ScoreTextbox.addEventListener('keyup', checkDataValidity); + if(nameTextbox) nameTextbox.addEventListener('keyup', checkDataValidity); checkDataValidity(); } @@ -112,6 +117,8 @@ async function checkDataValidity() { if(dateInput.value == "") dataIsValid = false; + if(nameTextbox && nameTextbox.value == "") dataIsValid = false; + submitButton.disabled = !dataIsValid; } diff --git a/routes/index.js b/routes/index.js index 42fa2b0..c18f5a5 100644 --- a/routes/index.js +++ b/routes/index.js @@ -1,9 +1,12 @@ var express = require('express'); var router = express.Router(); -/* GET home page. */ router.get('/', function(req, res, next) { res.render('index', { title: 'View Scores', userLoggedIn: !!req.user, hideHomeButton: true }); }); +router.get('/submit', function(req, res, next) { + res.redirect('/manage/game'); +}); + module.exports = router; diff --git a/routes/manage.js b/routes/manage.js index b1d8809..bad5f4c 100644 --- a/routes/manage.js +++ b/routes/manage.js @@ -12,19 +12,47 @@ var accounts = require('../database/accounts/accounts'); var checkLoginStatus = require('./checkLoginStatus'); +if (process.env.NODE_ENV !== 'production' || process.env.NODE_ENV !== 'testing') { + require('dotenv').config(); +} + router.get('/' ,checkLoginStatus.user, function(req, res, next) { if(req.user[2]) res.render('manage', { title: 'Management Panel', userLoggedIn: !!req.user }); else res.render('manage/manage-nonadmin', { title: "My Games", userLoggedIn: !!req.user }); }); -router.get('/game', checkLoginStatus.user, function(req, res, next) { - let title = req.query.game ? 'Edit Game' : 'Submit Score' - - res.render('manage/addgame', { title, userLoggedIn: !!req.user, message: req.flash('error') }); +router.get('/game', function(req, res, next) { + if(!(process.env.PUBLIC_SUBMIT_PAGE && process.env.PUBLIC_SUBMIT_PAGE.toLowerCase() == 'true')) { + if (req.user) { + next(); + } + else { + res.redirect('/auth/login'); + } + } else { + next(); + } + }, + function(req, res, next) { + let title = req.query.game ? 'Edit Game' : 'Submit Score'; + + res.render('manage/addgame', { title, userLoggedIn: !!req.user, message: req.flash('error') }); }); -router.post('/game', checkLoginStatus.user, async function(req, res, next) { +router.post('/game', function(req, res, next) { + if(!(process.env.PUBLIC_SUBMIT_PAGE && process.env.PUBLIC_SUBMIT_PAGE.toLowerCase() == 'true')) { + if (req.user) { + next(); + } + else { + res.redirect('/auth/login'); + } + } else { + next(); + } +}, + async function(req, res, next) { const id = req.body['game']; const remove = req.body['remove']; @@ -38,14 +66,20 @@ router.post('/game', checkLoginStatus.user, async function(req, res, next) { const team1Score = req.body['team1-score']; const team2ID = req.body['team2']; const team2Score = req.body['team2-score']; - const userID = req.user[0]; - - const loggedInUserID = req.user[0]; - const loggedInUserIsAdmin = req.user[2]; + const submitterName = req.body['name']; + + let submitterID; + let loggedInUserID; + let loggedInUserIsAdmin; + if(req.user) { + submitterID = req.user[0]; + loggedInUserID = req.user[0]; + loggedInUserIsAdmin = req.user[2]; + } const game = id ? await games.getFromID(id) : null; - if(!loggedInUserIsAdmin && game && loggedInUserID != game.submitterID) { + if((!loggedInUserIsAdmin && game && loggedInUserID != game.submitterID) || (!req.user && game)) { res.status(403).send("ACCESS DENIED"); } else if(remove) { @@ -57,7 +91,7 @@ router.post('/game', checkLoginStatus.user, async function(req, res, next) { res.redirect('/manage#games'); } else { - await games.add(divisionID, seasonID, date, team1ID, team2ID, team1Score, team2Score, userID); + await games.add(divisionID, seasonID, date, team1ID, team2ID, team1Score, team2Score, submitterID, submitterName); res.redirect('/'); } } catch(err) { diff --git a/views/manage/addgame.pug b/views/manage/addgame.pug index 3a44834..bdc362c 100644 --- a/views/manage/addgame.pug +++ b/views/manage/addgame.pug @@ -45,6 +45,11 @@ block content label Score span(class='form-section-input') input#team2-score-textbox(type="number", name="team2-score", value="0" disabled) + if !userLoggedIn + span(class='form-section') + label Your name + span(class='form-section-input') + input#name-textbox(type="text" name="name" disabled) .error #{message} span(class='form-section') button#submit-button(type="submit" disabled) Submit