Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
19 changes: 19 additions & 0 deletions .eslintrc.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
{
"env": {
"browser": true,
"commonjs": true,
"es6": true
},
"extends": [
"airbnb-base"
],
"globals": {
"Atomics": "readonly",
"SharedArrayBuffer": "readonly"
},
"parserOptions": {
"ecmaVersion": 2018
},
"rules": {
}
}
38 changes: 38 additions & 0 deletions app.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
const express = require('express');
const bodyParser = require('body-parser');
const cookieParser = require('cookie-parser');
const path = require('path');
const todoRouter = require('./routes/route');
const adminController = require('./controllers/admin');

const app = express();
const port = 8080;


app.use(bodyParser.json());
app.use(bodyParser.urlencoded({ extended: true }));
app.use(cookieParser());

app.use(express.static(`${__dirname}/public`));

app.get('/', (req, res) => {
res.sendFile(path.join(__dirname, '/views', 'index.html'));
});

app.get('/todo', adminController.getToDoList);

app.post('/signup', adminController.signUp);

app.get('/signup', adminController.getSignUpPage);

app.post('/login', adminController.login);

app.get('/login', adminController.getLoginPage);

app.get('/logout', adminController.logout);

app.use(adminController.verify);

app.use(todoRouter);

app.listen(port, () => console.log(`Now listening on port ${port}...`));
115 changes: 115 additions & 0 deletions controllers/admin.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,115 @@
const bcrypt = require('bcrypt');
const jwt = require('jsonwebtoken');
const path = require('path');
const Admin = require('../models/Admin');

const signUp = (req, res) => {
const { email, password, username } = req.body;

const saltRounds = 8;
bcrypt
.hash(password, saltRounds)
.then((hashedPassword) => {
console.log('Hashed Password: ', hashedPassword);
Admin.add(email, hashedPassword, username);
})
.then(() => res.status(201).send('Admin account created.'))
.catch((err) => {
console.log(err);
res.send(err);
});
};

const login = async (req, res) => {
const { email, password } = req.body;

try {
const user = await Admin.getByEmail(email);
const validPassword = await bcrypt.compare(password, user.password);

req.body.userEmail = user.email;
req.body.userPassword = user.password;
req.body.userId = user.id;
req.body.username = user.username;

if (!user) {
return res.status(403).send('Email does not exsist.');
}
if (validPassword) {
const privateKey = 'superdupersecret';

return jwt.sign(
{
id: user.id,
email: user.email,
password: user.password,
name: user.username,
},
privateKey,
(err, payload) => {
res.cookie('userToken', payload, { httpOnly: true });
res.redirect('/tasks');
},
);
}
return res.status(403).send('Email or password is incorrect.');
} catch (err) {
console.log(err);
return res.send(err);
}
};

const verify = async (req, res, next) => {
if (!req.cookies.userToken) {
return res.status(401).send('Unauthorized User.');
}
const payload = jwt.verify(req.cookies.userToken, 'superdupersecret');
const { email, password } = payload;
try {
const user = await Admin.getUserByEmail(email);

req.body.userId = user.id;

if (!user) {
return res.status(403).send('Unauthorized User: User does not exist.');
}

const isValidPassword = await bcrypt.compare(password, user.password);

if (isValidPassword) {
return next();
}

return res.status(403).send('Unauthorized User: Try logging in again.');
} catch (err) {
return res.send(err);
}
};

const logout = (req, res) => {
res.clearCookie('userToken');
res.redirect('/login');
};

const getLoginPage = (req, res) => {
res.sendFile(path.join(__dirname, '../views', 'login.html'));
};

const getSignUpPage = (req, res) => {
res.sendFile(path.join(__dirname, '../views', 'signUp.html'));
};

const getToDoList = (req, res) => {
res.sendFile(path.join(__dirname, '../views', 'todo.html'));
};


module.exports = {
signUp,
login,
verify,
logout,
getLoginPage,
getSignUpPage,
getToDoList,
};
75 changes: 75 additions & 0 deletions controllers/todo.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,75 @@
const jwt = require('jsonwebtoken');
const path = require('path');
const Task = require('../models/Task');
const Admin = require('../models/Admin');


const getUserId = async (token) => {
const privateKey = 'superdupersecret';
const payload = jwt.verify(token, privateKey);
const { email } = payload;
try {
const user = await Admin.getByEmail(email);
return user.id;
} catch (err) {
throw new Error();
}
};

const getAllTasks = async (req, res) => {
const { userToken } = req.cookies;
const userId = await getUserId(userToken);
let response;
let tasks;
try {
response = await Task.getAllTasks(userId);
tasks = response.rows;
} catch (err) {
res.status(500).json({ error: '500 Internal Server Error' });
}
res.status(200).json(tasks.rows);
};

const getTaskById = async (req, res) => {
const { userToken } = req.cookies;
const userId = await getUserId(userToken);
const { taskId } = req.params;
const task = await Task.find(userId, taskId);
res.status(200).json(task);
};

const addTask = async (req, res) => {
const { userToken } = req.cookies;
const { taskTitle, taskDescription, dueDate } = req.body;
const userId = await getUserId(userToken);

await Task.create(taskTitle, taskDescription, dueDate, userId);
const lastTask = await Task.getLastCreated(userId);
res.status(200).json(lastTask);
};

const deleteTask = (req, res) => {
const { id } = req.params;
Task.deleteTask(id)
.then(() => res.status(204).json({ message: 'Task successfully deleted.' }))
.then(() => res.redirect('/todo'))
.catch(() => res.status(500).json({ error: 'Internal Server Error: Task could not be deleted.' }));
};

const getAddTask = (req, res) => {
res.sendFile(path.join(__dirname, '../views', 'addTask.html'));
};

const getUpdateTask = (req, res) => {
res.sendFile(path.join(__dirname, '../views', 'updateTask.html'));
};


module.exports = {
getAllTasks,
getTaskById,
addTask,
deleteTask,
getAddTask,
getUpdateTask,
};
18 changes: 18 additions & 0 deletions db.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
const { Pool } = require('pg');

const pool = new Pool({
// connectionString: process.env.DATABASE_URL,
user: 'carmensalas',
host: 'localhost',
database: 'todo',
password: null,
port: 5432,
});

// pool.query('SELECT * FROM task;').then((data) => console.log(data));

module.exports = {
query(text, params) {
return pool.query(text, params);
},
};
17 changes: 17 additions & 0 deletions models/Admin.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
const db = require('../db');

class Admin {
static add(email, password, username) {
const queryText = `INSERT INTO admins (email, password, username)
VALUES ($1, $2, $3);`;
return db.query(queryText, [email, password, username]);
}

static getByEmail(email) {
const queryText = 'SELECT * FROM admins WHERE email=$1';
return db.query(queryText, [email])
.then((data) => data.rows[0]);
}
}

module.exports = Admin;
58 changes: 58 additions & 0 deletions models/Task.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
const db = require('../db');

class Task {
static createTask(
taskName,
taskDescription,
dateCreated,
dueDate,
isComplete,
userId,
) {
const queryText = 'INSERT INTO task (task_name, task_description, date_created, due_date, is_complete, user_id) VALUES($1,$2,$3,$4,$5)';
return db.query(queryText, [
taskName,
taskDescription,
dateCreated,
dueDate,
false,
userId,
]);
}

static getAllTasks(userId) {
return db.query('SELECT * FROM task WHERE user_id = $1;', [userId]);
}

static getTaskById(userId, id) {
const queryText = 'SELECT * FROM task WHERE user_id = $1 AND id = $2;';
return db
.query(queryText, [userId, id])
.then((res) => res.rows[0])
.catch((err) => {
console.log(err);
});
}

static getLastCreated(id) {
const queryText = 'SELECT * FROM task ORDER BY id DESC LIMIT 1;';
return db
.query(queryText, [id])
.then((res) => res.rows[0])
.catch((err) => {
console.log(err);
});
}

static completeTask(id) {
const queryText = 'UPDATE task SET is_complete = true WHERE id = $1;';
return db.query(queryText, [id]);
}

static deleteTask(id) {
const queryText = 'DELETE FROM task WHERE id = $1';
return db.query(queryText, [id]);
}
}

module.exports = Task;
Loading