This repository has been archived on 2024-04-05. You can view files and clone it, but cannot push or open issues/pull-requests.
score-tracker/database/accounts/accounts.js

144 lines
4.3 KiB
JavaScript

const database = require('./../database');
const passport = require('passport');
const localStrategy = require('passport-local').Strategy;
const bcrypt = require('bcrypt');
class User {
constructor(id, email, isAdmin, name) {
this.id = id;
this.email = email;
this.isAdmin = isAdmin;
this.name = name;
}
}
async function checkForAdminAccount() {
const adminUsersQuery = `SELECT *
FROM accounts.users
WHERE admin = true;`;
const adminUsers = await database.executeQuery(adminUsersQuery);
if(adminUsers.length == 0) {
const passwordHash = await generateHash('admin');
const createTempAdminQuery = `INSERT INTO accounts.users(email, password, admin)
VALUES('admin@example.com', $1, true);`;
database.executeQuery(createTempAdminQuery, [passwordHash]);
console.log("Created temp admin account 'admin@example.com' with password 'admin'.");
}
}
database.initializationStatus.then(() => checkForAdminAccount());
passport.use(new localStrategy({
usernameField: 'email',
passwordField: 'password'},
(username, password, cb) => {
query = `SELECT user_id, email, password, admin
FROM accounts.users
WHERE email = $1`;
database.executeQuery(query, [username])
.then(result => {
if(result.length > 0) {
const first = result[0];
const matches = bcrypt.compareSync(password, first[2]);
if(matches) {
return cb(null, { id: first[0], email: first[1], admin: first[3] })
}
else
{
return cb(null, false)
}
} else {
return cb(null, false)
}
});
}));
passport.serializeUser((user, done) => {
done(null, user.id)
})
passport.deserializeUser((id, cb) => {
query = `SELECT user_id, email, admin
FROM accounts.users
WHERE user_id = $1`;
database.executeQuery(query, [parseInt(id, 10)])
.then(result => {
cb(null, result[0]);
});
});
async function generateHash(password) {
const salt = bcrypt.genSaltSync();
return bcrypt.hashSync(password, salt);
}
async function create(email, password, isAdmin, name) {
const hash = await generateHash(password);
const query = `INSERT INTO accounts.users(email, password, admin, full_name)
VALUES($1, $2, $3, $4)`;
await database.executeQuery(query, [email, hash, isAdmin, name]);
}
async function edit(id, email, password, isAdmin, name) {
if(password) {
const hash = await generateHash(password);
const query = `UPDATE accounts.users
SET email = $2,
password = $3,
admin = $4,
full_name = $5
WHERE user_id = $1;`;
await database.executeQuery(query, [id, email, hash, isAdmin, name]);
} else {
const query = `UPDATE accounts.users
SET email = $2,
admin = $3,
full_name = $4
WHERE user_id = $1;`;
await database.executeQuery(query, [id, email, isAdmin, name]);
}
return new User(id, email, isAdmin, name);
}
async function remove(id) {
const query = `DELETE FROM accounts.users
WHERE user_id = $1
RETURNING email, admin, full_name;`;
const row = (await database.executeQuery(query, [id]))[0];
return new User(id, row[0], row[1], row[2]);
}
async function retrieveAll() {
const query = `SELECT user_id, email, admin, full_name
FROM accounts.users
ORDER BY full_name;`;
const table = await database.executeQuery(query);
const accountsList = [];
table.forEach((row) => {
accountsList.push(new User(row[0], row[1], row[2], row[3]));
});
return accountsList;
}
async function getFromID(id) {
const query = `SELECT user_id, email, admin, full_name
FROM accounts.users
WHERE user_id = $1;`;
const row = (await database.executeQuery(query, [id]))[0];
return new User(id, row[1], row[2], row[3]);
}
exports.create = create;
exports.edit = edit;
exports.remove = remove;
exports.retrieveAll = retrieveAll;
exports.getFromID = getFromID;
exports.passport = passport;