diff --git a/client/src/API.js b/client/src/API.js index 62342da..0a80806 100644 --- a/client/src/API.js +++ b/client/src/API.js @@ -28,5 +28,33 @@ async function getAllExams() { } } -const API = {getAllCourses, getAllExams}; +async function login(credentials) { + let response = await fetch('/api/sessions', { + method: 'POST', + headers: { + 'Content-Type': 'application/json', + }, + body: JSON.stringify(credentials), + }); + if(response.ok) { + const user = await response.json(); + return user.name; + } + else { + const errDetails = await response.text(); + throw errDetails; + } +} + +async function getUserInfo() { + const response = await fetch(BASEURL + '/sessions/current'); + const userInfo = await response.json(); + if (response.ok) { + return userInfo; + } else { + throw userInfo; // an object with the error coming from the server + } +} + +const API = {getAllCourses, getAllExams, login, getUserInfo}; export default API; \ No newline at end of file diff --git a/client/src/App.js b/client/src/App.js index 2a900e0..cb73b01 100644 --- a/client/src/App.js +++ b/client/src/App.js @@ -4,25 +4,38 @@ import { Container, Row, Alert } from 'react-bootstrap'; import { ExamScores } from './ExamComponents.js'; import AppTitle from './AppTitle.js'; import { useEffect, useState } from 'react'; -import { BrowserRouter as Router, Route, Switch } from 'react-router-dom'; +import { BrowserRouter as Router, Redirect, Route, Switch } from 'react-router-dom'; import API from './API'; +import { LoginForm } from './LoginComponents'; function App() { const [exams, setExams] = useState([]); const [courses, setCourses] = useState([]); const [message, setMessage] = useState(''); + const [loggedIn, setLoggedIn] = useState(false); + + useEffect(() => { + const checkAuth = async () => { + // TODO: qui avremo le info sull'utente dal server, possiamo salvare da qualche parte + await API.getUserInfo(); + setLoggedIn(true); + }; + checkAuth(); + }, []); useEffect(()=> { const getCourses = async () => { + if(loggedIn) { const courses = await API.getAllCourses(); setCourses(courses); + } }; getCourses() .catch(err => { setMessage({msg: "Impossible to load your exams! Please, try again later...", type: 'danger'}); console.error(err); }); - }, []); + }, [loggedIn]); useEffect(()=> { const getExams = async () => { @@ -37,6 +50,17 @@ function App() { } }, [courses.length]); + const doLogin = async (credentials) => { + try { + const user = await API.login(credentials); + setLoggedIn(true); + setMessage({msg: `Welcome, ${user}!`, type: 'success'}); + }catch(err) { + setMessage({msg: err, type: 'danger'}); + } + + } + return ( @@ -47,10 +71,17 @@ function App() { } + + <>{loggedIn ? : } + } /> + <> + {loggedIn ? + : } + } /> diff --git a/client/src/LoginComponents.js b/client/src/LoginComponents.js new file mode 100644 index 0000000..d39e3fc --- /dev/null +++ b/client/src/LoginComponents.js @@ -0,0 +1,45 @@ +import { useState } from "react"; +import {Form, Button, Alert} from 'react-bootstrap'; + +function LoginForm(props) { + const [username, setUsername] = useState(''); + const [password, setPassword] = useState(''); + const [errorMessage, setErrorMessage] = useState('') ; + + const handleSubmit = (event) => { + event.preventDefault(); + setErrorMessage(''); + const credentials = { username, password }; + + // SOME VALIDATION, ADD MORE!!! + let valid = true; + if(username === '' || password === '' || password < 6) + valid = false; + + if(valid) + { + props.login(credentials); + } + else { + // show a better error message... + setErrorMessage('Error(s) in the form, please fix it.') + } + }; + + return ( +
+ {errorMessage ? {errorMessage} : ''} + + email + setUsername(ev.target.value)} /> + + + Password + setPassword(ev.target.value)} /> + + +
+ ) +} + +export { LoginForm }; \ No newline at end of file diff --git a/server/exam-dao.js b/server/exam-dao.js index cecd34d..7a41454 100644 --- a/server/exam-dao.js +++ b/server/exam-dao.js @@ -19,11 +19,11 @@ exports.listCourses = () => { }; // get all exams -exports.listExams = () => { +exports.listExams = (id) => { return new Promise((resolve, reject) => { - const sql = 'SELECT coursecode, score, date FROM exam'; + const sql = 'SELECT coursecode, score, date FROM exam WHERE userId = ?'; - db.all(sql, [], (err, rows) => { + db.all(sql, [id], (err, rows) => { if (err) { reject(err); return; diff --git a/server/package-lock.json b/server/package-lock.json index 71e8064..cb6a2ad 100644 --- a/server/package-lock.json +++ b/server/package-lock.json @@ -18,6 +18,29 @@ "negotiator": "0.6.2" } }, + "agent-base": { + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/agent-base/-/agent-base-6.0.2.tgz", + "integrity": "sha512-RZNwNclF7+MS/8bDg70amg32dyeZGZxiDuQmZxKLAlQjr3jGyLx+4Kkk58UO7D2QdgFIQCovuSuZESne6RG6XQ==", + "requires": { + "debug": "4" + }, + "dependencies": { + "debug": { + "version": "4.3.1", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.1.tgz", + "integrity": "sha512-doEwdvm4PCeK4K3RQN2ZC2BYUBaxwLARCqZmMjtF8a51J2Rb0xpVloFRnCODwqjpwnAoao4pelN8l3RJdv3gRQ==", + "requires": { + "ms": "2.1.2" + } + }, + "ms": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", + "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==" + } + } + }, "ajv": { "version": "6.12.6", "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz", @@ -100,6 +123,110 @@ "safe-buffer": "5.1.2" } }, + "bcrypt": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/bcrypt/-/bcrypt-5.0.1.tgz", + "integrity": "sha512-9BTgmrhZM2t1bNuDtrtIMVSmmxZBrJ71n8Wg+YgdjHuIWYF7SjjmCPZFB+/5i/o/PIeRpwVJR3P+NrpIItUjqw==", + "requires": { + "@mapbox/node-pre-gyp": "^1.0.0", + "node-addon-api": "^3.1.0" + }, + "dependencies": { + "@mapbox/node-pre-gyp": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/@mapbox/node-pre-gyp/-/node-pre-gyp-1.0.5.tgz", + "integrity": "sha512-4srsKPXWlIxp5Vbqz5uLfBN+du2fJChBoYn/f2h991WLdk7jUvcSk/McVLSv/X+xQIPI8eGD5GjrnygdyHnhPA==", + "requires": { + "detect-libc": "^1.0.3", + "https-proxy-agent": "^5.0.0", + "make-dir": "^3.1.0", + "node-fetch": "^2.6.1", + "nopt": "^5.0.0", + "npmlog": "^4.1.2", + "rimraf": "^3.0.2", + "semver": "^7.3.4", + "tar": "^6.1.0" + } + }, + "chownr": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/chownr/-/chownr-2.0.0.tgz", + "integrity": "sha512-bIomtDF5KGpdogkLd9VspvFzk9KfpyyGlS8YFVZl7TGPBHL5snIOnxeshwVgPteQ9b4Eydl+pVbIyE1DcvCWgQ==" + }, + "fs-minipass": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/fs-minipass/-/fs-minipass-2.1.0.tgz", + "integrity": "sha512-V/JgOLFCS+R6Vcq0slCuaeWEdNC3ouDlJMNIsacH2VtALiu9mV4LPrHc5cDl8k5aw6J8jwgWWpiTo5RYhmIzvg==", + "requires": { + "minipass": "^3.0.0" + } + }, + "minipass": { + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/minipass/-/minipass-3.1.3.tgz", + "integrity": "sha512-Mgd2GdMVzY+x3IJ+oHnVM+KG3lA5c8tnabyJKmHSaG2kAGpudxuOf8ToDkhumF7UzME7DecbQE9uOZhNm7PuJg==", + "requires": { + "yallist": "^4.0.0" + } + }, + "minizlib": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/minizlib/-/minizlib-2.1.2.tgz", + "integrity": "sha512-bAxsR8BVfj60DWXHE3u30oHzfl4G7khkSuPW+qvpd7jFRHm7dLxOjUk1EHACJ/hxLY8phGJ0YhYHZo7jil7Qdg==", + "requires": { + "minipass": "^3.0.0", + "yallist": "^4.0.0" + } + }, + "mkdirp": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-1.0.4.tgz", + "integrity": "sha512-vVqVZQyf3WLx2Shd0qJ9xuvqgAyKPLAiqITEtqW0oIUjzo3PePDd6fW9iFz30ef7Ysp/oiWqbhszeGWW2T6Gzw==" + }, + "nopt": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/nopt/-/nopt-5.0.0.tgz", + "integrity": "sha512-Tbj67rffqceeLpcRXrT7vKAN8CwfPeIBgM7E6iBkmKLV7bEMwpGgYLGv0jACUsECaa/vuxP0IjEont6umdMgtQ==", + "requires": { + "abbrev": "1" + } + }, + "rimraf": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-3.0.2.tgz", + "integrity": "sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA==", + "requires": { + "glob": "^7.1.3" + } + }, + "semver": { + "version": "7.3.5", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.5.tgz", + "integrity": "sha512-PoeGJYh8HK4BTO/a9Tf6ZG3veo/A7ZVsYrSA6J8ny9nb3B1VrpkuN+z9OE5wfE5p6H4LchYZsegiQgbJD94ZFQ==", + "requires": { + "lru-cache": "^6.0.0" + } + }, + "tar": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/tar/-/tar-6.1.0.tgz", + "integrity": "sha512-DUCttfhsnLCjwoDoFcI+B2iJgYa93vBnDUATYEeRx6sntCTdN01VnqsIuTlALXla/LWooNg0yEGeB+Y8WdFxGA==", + "requires": { + "chownr": "^2.0.0", + "fs-minipass": "^2.0.0", + "minipass": "^3.0.0", + "minizlib": "^2.1.1", + "mkdirp": "^1.0.3", + "yallist": "^4.0.0" + } + }, + "yallist": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", + "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==" + } + } + }, "bcrypt-pbkdf": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/bcrypt-pbkdf/-/bcrypt-pbkdf-1.0.2.tgz", @@ -327,6 +454,38 @@ "vary": "~1.1.2" } }, + "express-session": { + "version": "1.17.2", + "resolved": "https://registry.npmjs.org/express-session/-/express-session-1.17.2.tgz", + "integrity": "sha512-mPcYcLA0lvh7D4Oqr5aNJFMtBMKPLl++OKKxkHzZ0U0oDq1rpKBnkR5f5vCHR26VeArlTOEF9td4x5IjICksRQ==", + "requires": { + "cookie": "0.4.1", + "cookie-signature": "1.0.6", + "debug": "2.6.9", + "depd": "~2.0.0", + "on-headers": "~1.0.2", + "parseurl": "~1.3.3", + "safe-buffer": "5.2.1", + "uid-safe": "~2.1.5" + }, + "dependencies": { + "cookie": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/cookie/-/cookie-0.4.1.tgz", + "integrity": "sha512-ZwrFkGJxUR3EIoXtO+yVE69Eb7KlixbaeAWfBQB9vVsNn/o+Yw69gBWSSDK825hQNdN+wF8zELf3dFNl/kxkUA==" + }, + "depd": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/depd/-/depd-2.0.0.tgz", + "integrity": "sha512-g7nH6P6dyDioJogAAGprGpCtVImJhpPk/roCzdb3fIh61/s/nPsfR6onyMwkCAR/OlC3yBC0lESvUoQEAssIrw==" + }, + "safe-buffer": { + "version": "5.2.1", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz", + "integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==" + } + } + }, "extend": { "version": "3.0.2", "resolved": "https://registry.npmjs.org/extend/-/extend-3.0.2.tgz", @@ -504,6 +663,30 @@ "sshpk": "^1.7.0" } }, + "https-proxy-agent": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-5.0.0.tgz", + "integrity": "sha512-EkYm5BcKUGiduxzSt3Eppko+PiNWNEpa4ySk9vTC6wDsQJW9rHSa+UhGNJoRYp7bz6Ht1eaRIa6QaJqO5rCFbA==", + "requires": { + "agent-base": "6", + "debug": "4" + }, + "dependencies": { + "debug": { + "version": "4.3.1", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.1.tgz", + "integrity": "sha512-doEwdvm4PCeK4K3RQN2ZC2BYUBaxwLARCqZmMjtF8a51J2Rb0xpVloFRnCODwqjpwnAoao4pelN8l3RJdv3gRQ==", + "requires": { + "ms": "2.1.2" + } + }, + "ms": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", + "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==" + } + } + }, "iconv-lite": { "version": "0.4.24", "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.24.tgz", @@ -611,6 +794,36 @@ "verror": "1.10.0" } }, + "lru-cache": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz", + "integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==", + "requires": { + "yallist": "^4.0.0" + }, + "dependencies": { + "yallist": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", + "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==" + } + } + }, + "make-dir": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/make-dir/-/make-dir-3.1.0.tgz", + "integrity": "sha512-g3FeP20LNwhALb/6Cz6Dd4F2ngze0jz7tbzrD2wAV+o9FeNHe4rL+yK2md0J/fiSf1sa1ADhXqi5+oVwOM/eGw==", + "requires": { + "semver": "^6.0.0" + }, + "dependencies": { + "semver": { + "version": "6.3.0", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", + "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==" + } + } + }, "media-typer": { "version": "0.3.0", "resolved": "https://registry.npmjs.org/media-typer/-/media-typer-0.3.0.tgz", @@ -741,6 +954,11 @@ "resolved": "https://registry.npmjs.org/node-addon-api/-/node-addon-api-3.2.0.tgz", "integrity": "sha512-kcwSAWhPi4+QzAtsL2+2s/awvDo2GKLsvMCwNRxb5BUshteXU8U97NCyvQDsGKs/m0He9WcG4YWew/BnuLx++w==" }, + "node-fetch": { + "version": "2.6.1", + "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.6.1.tgz", + "integrity": "sha512-V4aYg89jEoVRxRb2fJdAg8FHvI7cEyYdVAh94HH0UIK8oJxUfkjlDQN9RbMx+bEjP7+ggMiFRprSti032Oipxw==" + }, "node-gyp": { "version": "3.8.0", "resolved": "https://registry.npmjs.org/node-gyp/-/node-gyp-3.8.0.tgz", @@ -907,6 +1125,28 @@ "resolved": "https://registry.npmjs.org/parseurl/-/parseurl-1.3.3.tgz", "integrity": "sha512-CiyeOxFT/JZyN5m0z9PfXw4SCBJ6Sygz1Dpl0wqjlhDEGGBP1GnsUVEL0p63hoG1fcj3fHynXi9NYO4nWOL+qQ==" }, + "passport": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/passport/-/passport-0.4.1.tgz", + "integrity": "sha512-IxXgZZs8d7uFSt3eqNjM9NQ3g3uQCW5avD8mRNoXV99Yig50vjuaez6dQK2qC0kVWPRTujxY0dWgGfT09adjYg==", + "requires": { + "passport-strategy": "1.x.x", + "pause": "0.0.1" + } + }, + "passport-local": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/passport-local/-/passport-local-1.0.0.tgz", + "integrity": "sha1-H+YyaMkudWBmJkN+O5BmYsFbpu4=", + "requires": { + "passport-strategy": "1.x.x" + } + }, + "passport-strategy": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/passport-strategy/-/passport-strategy-1.0.0.tgz", + "integrity": "sha1-tVOaqPwiWj0a0XlHbd8ja0QPUuQ=" + }, "path-is-absolute": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz", @@ -917,6 +1157,11 @@ "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-0.1.7.tgz", "integrity": "sha1-32BBeABfUi8V60SQ5yR6G/qmf4w=" }, + "pause": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/pause/-/pause-0.0.1.tgz", + "integrity": "sha1-HUCLP9t2kjuVQ9lvtMnf1TXZy10=" + }, "performance-now": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/performance-now/-/performance-now-2.1.0.tgz", @@ -954,6 +1199,11 @@ "resolved": "https://registry.npmjs.org/qs/-/qs-6.7.0.tgz", "integrity": "sha512-VCdBRNFTX1fyE7Nb6FYoURo/SPe62QCaAyzJvUjwRaIsc+NePBEniHlvxFmmX56+HZphIGtV0XeCirBtpDrTyQ==" }, + "random-bytes": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/random-bytes/-/random-bytes-1.0.0.tgz", + "integrity": "sha1-T2ih3Arli9P7lYSMMDJNt11kNgs=" + }, "range-parser": { "version": "1.2.1", "resolved": "https://registry.npmjs.org/range-parser/-/range-parser-1.2.1.tgz", @@ -1225,6 +1475,14 @@ "mime-types": "~2.1.24" } }, + "uid-safe": { + "version": "2.1.5", + "resolved": "https://registry.npmjs.org/uid-safe/-/uid-safe-2.1.5.tgz", + "integrity": "sha512-KPHm4VL5dDXKz01UuEd88Df+KzynaohSL9fBh096KWAxSKZQDI2uBrVqtvRM4rwrIrRRKsdLNML/lnaaVSRioA==", + "requires": { + "random-bytes": "~1.0.0" + } + }, "unpipe": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/unpipe/-/unpipe-1.0.0.tgz", diff --git a/server/package.json b/server/package.json index 23d70e0..446d263 100644 --- a/server/package.json +++ b/server/package.json @@ -9,8 +9,12 @@ "author": "Web Applications I, Applicazioni Web I", "license": "ISC", "dependencies": { + "bcrypt": "^5.0.1", "express": "^4.17.1", + "express-session": "^1.17.2", "morgan": "^1.10.0", + "passport": "^0.4.1", + "passport-local": "^1.0.0", "sqlite3": "^5.0.2" } } diff --git a/server/server.js b/server/server.js index 71a875d..d63de4b 100644 --- a/server/server.js +++ b/server/server.js @@ -3,6 +3,35 @@ const express = require('express'); const morgan = require('morgan'); // logging middleware const examDao = require('./exam-dao'); // module for accessing the exams in the DB +const passport = require('passport'); +const LocalStrategy = require('passport-local').Strategy; // username+psw +const session = require('express-session'); +const userDao = require('./user-dao'); + +/*** Set up Passport ***/ +passport.use(new LocalStrategy( + function(username, password, done) { + userDao.getUser(username, password).then((user) => { + if (!user) + return done(null, false, { message: 'Incorrect username and/or password.' }); + + return done(null, user); + }); + } +)); + +passport.serializeUser((user, done) => { + done(null, user.id); +}); + +passport.deserializeUser((id, done) => { + userDao.getUserById(id).then((user) => { + done(null, user); // req.user + }) + .catch((err) => { + done(err, null); + }); +}); // init express const app = express(); @@ -12,6 +41,26 @@ const port = 3001; app.use(morgan('dev')); app.use(express.json()); +const isLoggedIn = (req, res, next) => { + if(req.isAuthenticated()) { + return next(); + } + + return res.status(400).json({error: 'Not authorized'}); +} + +// enable sessions in Express +app.use(session({ + // set up here express-session + secret: 'una frase segreta da non condividere con nessuno e da nessuna parte, usata per firmare il cookie Session ID', + resave: false, + saveUninitialized: false, +})); + +// init Passport to use sessions +app.use(passport.initialize()); +app.use(passport.session()); + /*** Courses/Exams APIs ***/ // GET /api/courses @@ -22,15 +71,28 @@ app.get('/api/courses', (req, res) => { }); // GET /api/exams -app.get('/api/exams', async (req, res) => { +app.get('/api/exams', isLoggedIn, async (req, res) => { try { - const exams = await examDao.listExams(); + const exams = await examDao.listExams(req.user.id); res.json(exams); } catch(err) { res.status(500).end(); } + }); +/*** User APIs ***/ +app.post('/api/sessions', passport.authenticate('local'), (req, res) => { + res.json(req.user); +}); + +app.get('/api/sessions/current', (req, res) => { + if(req.isAuthenticated()) + res.json(req.user); + else + res.status(401).json({error: 'Not authenticated'}); +}) + /*** Other express-related instructions ***/ // Activate the server diff --git a/server/user-dao.js b/server/user-dao.js new file mode 100644 index 0000000..2e1012e --- /dev/null +++ b/server/user-dao.js @@ -0,0 +1,44 @@ +'use strict'; + +const db = require('./db'); +const bcrypt = require('bcrypt'); + +exports.getUser = (email, password) => { + return new Promise((resolve, reject) => { + const sql = 'SELECT * FROM user WHERE email = ?'; + db.get(sql, [email], (err, row) => { + if (err) { + reject(err); + } + else if (row === undefined) { + resolve(false); + } + else { + const user = {id: row.id, username: row.email, name: row.name}; + + bcrypt.compare(password, row.password).then(result => { + if(result) resolve(user); + else resolve(false); + }); + } + }); + }); +}; + +exports.getUserById = (id) => { + return new Promise((resolve, reject) => { + const sql = 'SELECT * FROM user WHERE id = ?'; + db.get(sql, [id], (err, row) => { + if (err) { + reject(err); + } + else if (row === undefined) { + resolve({error: 'User not found!'}); + } + else { + const user = {id: row.id, username: row.email, name: row.name}; + resolve(user); + } + }); + }); +}; \ No newline at end of file