From d97a4693e125efc8d0c0d884520917404b519c47 Mon Sep 17 00:00:00 2001 From: Robert Hall Date: Sat, 22 Sep 2018 15:06:36 -0600 Subject: [PATCH] Some basic shell --- app/auth/db.js | 23 +++++++++++ app/auth/setup.js | 95 +++++++++++++++++++++++++++++++++++++++++++++ app/server.js | 31 +++++++++++---- components/Nav.html | 6 ++- routes/login.html | 5 +++ routes/signup.html | 5 +++ 6 files changed, 157 insertions(+), 8 deletions(-) create mode 100644 app/auth/db.js create mode 100644 app/auth/setup.js create mode 100644 routes/login.html create mode 100644 routes/signup.html diff --git a/app/auth/db.js b/app/auth/db.js new file mode 100644 index 0000000..ba3e738 --- /dev/null +++ b/app/auth/db.js @@ -0,0 +1,23 @@ +// WARNING: THIS HELPER FILE IS NOT GOOD PRACTICE AND ONLY HERE FOR CONVENIENCE +// use a real database for persisting users instead + +// const Users = [{ +// username: 'general-zod', +// email: 'general.zod@krypton.com', +// hash: '', +// }, { +// username: 'kal-el', +// email: 'kal-el@krypton.com', +// hash: '', +// }]; +const Users = []; + +export default { + find(key, value) { + return Users.find(user => user[key] === value); + }, + add(user) { + Users.push(user); + return user; + }, +}; diff --git a/app/auth/setup.js b/app/auth/setup.js new file mode 100644 index 0000000..ddf2bd2 --- /dev/null +++ b/app/auth/setup.js @@ -0,0 +1,95 @@ +import passport from 'passport'; +import jwt from 'jsonwebtoken'; +import bcrypt from 'bcrypt'; +import { Strategy as LocalStrategy } from 'passport-local'; + +// WARNING: use a database instead of persistent memory to store users +// THE FOLLOWING IS BAD PRACTICE AND WILL NOT SCALE!!! +// It's only here for convenience. +import db from './db'; + +const env = process.env.NODE_ENV; + +export function authSetup(app) { + + passport.use(new LocalStrategy(async(username, password, done) => { + try { + const user = db.find('username', username); + if (user) { + const match = await bcrypt.compare(password, user.hash); + if (!match) { + return done(null, false, { message: `${user.username} is not authentic to that password.` }); + } + done(null, { username: user.username, email: user.email }); + } else { + return done(null, false, { message: `${username} does not exist.` }); + } + } catch (error) { + done(error); + } + })); + + app.use(passport.initialize()); + + app.post('/auth/signup', async(req, res, next) => { + try { + const { username, email, password } = req.body; + + const userExists = db.find('username', username); + const emailExists = db.find('email', email); + + if (userExists || emailExists) { + res.end(JSON.stringify({ userExists: !!userExists, emailExists: !!emailExists })); + } + + const user = db.add({ + username, + email, + hash: await bcrypt.hash(password, 10), + }); + const userToSendToClient = { username: user.username, email: user.email }; + + // generate a signed son web token with the contents of user object and return it in the response + const month = 60 * 60 * 24 * 30; + const token = jwt.sign(userToSendToClient, config.JWT_SECRET, { expiresIn: month }); + res.cookie('ds', token, { + // httpOnly: false, + secure: env === 'production' ? true : false, + maxAge: 1000 * month, + }); + res.status(200).send({ userToSendToClient }); + } catch (error) { + res.status(400).send({ error: 'req body should take the form { username, password }' }); + } + }); + + app.post('/auth/local/login', (req, res) => { + passport.authenticate('local', { session: false, successRedirect: '/', failureRedirect: '/login' }, (err, user) => { + if (err || !user) { + return res.status(400).json({ + message: 'Something went wrong.', + user: user ? user : false, + }); + } + req.login(user, { session: false }, error => { + if (error) { + res.send(error); + } + // generate a signed son web token with the contents of user object and return it in the response + const month = 60 * 60 * 24 * 30; + const token = jwt.sign(user, config.JWT_SECRET, { expiresIn: month }); + return res.cookie('ds', token, { + // httpOnly: false, + secure: env === 'production' ? true : false, + maxAge: 1000 * month, + }).json(user); + }) + })(req, res); + }); + + app.post('/auth/logout', (req, res) => { + req.logout(); + res.end('ok'); + }); + +} diff --git a/app/server.js b/app/server.js index dec9098..a71ee74 100644 --- a/app/server.js +++ b/app/server.js @@ -1,18 +1,35 @@ import sirv from 'sirv'; import polka from 'polka'; +// import bodyParser from 'body-parser'; +// import cookieParser from 'cookie-parser'; +import { authSetup } from './auth/setup'; import sapper from 'sapper'; import compression from 'compression'; +// import { Store } from 'svelte/store.js'; +// import { validate } from '../routes/_services/auth-check.js'; import { manifest } from './manifest/server.js'; const { PORT, NODE_ENV } = process.env; const dev = NODE_ENV === 'development'; -polka() // You can also use Express - .use( - compression({ threshold: 0 }), - sirv('assets', { dev }), - sapper({ manifest }) - ) - .listen(PORT, err => { +const app = polka() // You can also use Express +polka() + app.use(compression({ threshold: 0 })) + app.use(sirv('assets', { dev })) + // app.use(bodyParser.json()) + // app.use(bodyParser.urlencoded({ extended: true })) + // app.use(cookieParser()) + + authSetup(app) + + app.use(sapper({ + manifest, + store: req => { + // const user = validate(req); + // return new Store({ user: user.unauthorized ? null : user }); + }, + })) + + app.listen(PORT, err => { if (err) console.log('error', err); }) diff --git a/components/Nav.html b/components/Nav.html index 23c0631..76b4e91 100644 --- a/components/Nav.html +++ b/components/Nav.html @@ -6,6 +6,9 @@
  • blog
  • +
  • log in
  • +
  • sign up
  • +
  • sign out
  • @@ -48,9 +51,10 @@ bottom: -1px; } - a { + a, span { text-decoration: none; padding: 1em 0.5em; display: block; + cursor: pointer; } \ No newline at end of file diff --git a/routes/login.html b/routes/login.html new file mode 100644 index 0000000..e3d5de4 --- /dev/null +++ b/routes/login.html @@ -0,0 +1,5 @@ + + Log In + + +

    Log In

    diff --git a/routes/signup.html b/routes/signup.html new file mode 100644 index 0000000..e549216 --- /dev/null +++ b/routes/signup.html @@ -0,0 +1,5 @@ + + Sign Up + + +

    Sign Up