diff options
author | 2020-11-16 00:10:28 +0100 | |
---|---|---|
committer | 2020-11-16 00:10:28 +0100 | |
commit | e06ec920f7a5d784e674c4c4b4e6d1da3dc7391d (patch) | |
tree | 55713f725f77b44ebfec86e4eec3ce33e71458ca /server | |
download | website_creator-e06ec920f7a5d784e674c4c4b4e6d1da3dc7391d.tar.gz website_creator-e06ec920f7a5d784e674c4c4b4e6d1da3dc7391d.tar.bz2 website_creator-e06ec920f7a5d784e674c4c4b4e6d1da3dc7391d.zip |
api, login, auth
Diffstat (limited to 'server')
-rw-r--r-- | server/db/mongoose.js | 6 | ||||
-rw-r--r-- | server/middleware/auth.js | 23 | ||||
-rw-r--r-- | server/models/User.js | 72 | ||||
-rw-r--r-- | server/routes/user.js | 46 |
4 files changed, 147 insertions, 0 deletions
diff --git a/server/db/mongoose.js b/server/db/mongoose.js new file mode 100644 index 0000000..579b5d7 --- /dev/null +++ b/server/db/mongoose.js @@ -0,0 +1,6 @@ +const mongoose = require("mongoose"); + +mongoose.connect('mongodb://127.0.0.1:27017/website-manager', { + useNewUrlParser: true, + useCreateIndex: true, +}); diff --git a/server/middleware/auth.js b/server/middleware/auth.js new file mode 100644 index 0000000..091d3a7 --- /dev/null +++ b/server/middleware/auth.js @@ -0,0 +1,23 @@ +const jwt = require('jsonwebtoken'); +const User = require('../models/User'); + +const auth = async (req, res, next) => { + try { + const token = req.header('Authorization').replace('Bearer ', ''); + const decoded = jwt.verify(token, 'replaceThisWithSecretString'); + const user = await User.findOne({ _id: decoded._id, 'tokens.token': token }); + + if (!user) { + throw new Error(); + } + + req.token = token; + req.user = user; + next(); + } catch (err) { + res.status(401).send({ error: 'Not authenticated.' }); + } + +}; + +module.exports = auth; diff --git a/server/models/User.js b/server/models/User.js new file mode 100644 index 0000000..4fa6ffe --- /dev/null +++ b/server/models/User.js @@ -0,0 +1,72 @@ +const mongoose = require("mongoose"); +const bcrypt = require('bcryptjs'); +const jwt = require('jsonwebtoken'); + +const userSchema = new mongoose.Schema({ + email: { + type: String, + trim: true, + lowercase: true, + unique: true, + required: true, + min: 4, + max: 255, + validate(value) { + if (!/^[^\s@]+@[^\s@]+\.[^\s@]+$/.test(value)) { + throw new Error('Wrong email address'); + } + } + }, + password: { + type: String, + required: true, + min: 4, + max: 1024, + }, + tokens: [{ + token: { + type: String, + required: true + } + }] +}); + +userSchema.methods.generateAuthToken = async function () { + const user = this; + const token = jwt.sign({ _id: user._id.toString() }, 'replaceThisWithSecretString') + + user.tokens = user.tokens.concat({ token }); + user.save(); + + return token; +} + +userSchema.statics.findByCredentials = async (email, password) => { + const user = await User.findOne({ email }); + + if (!user) { + throw new Error('Unable to login'); + } + + const isMatch = await bcrypt.compare(password, user.password); + + if (!isMatch) { + throw new Error('Unable to login'); + } + + return user; +} + +userSchema.pre('save', async function(next){ + const user = this; + + if (user.isModified('password')) { + user.password = await bcrypt.hash(user.password, 8); + } + + next(); +}) + +const User = mongoose.model('User', userSchema); + +module.exports = User; diff --git a/server/routes/user.js b/server/routes/user.js new file mode 100644 index 0000000..9830b1d --- /dev/null +++ b/server/routes/user.js @@ -0,0 +1,46 @@ +const router = require('express').Router(); +const User = require('../models/User'); +const auth = require('../middleware/auth'); + +router.post('/register', async (req, res) => { + const user = new User(req.body); + + try { + await user.save(); + const token = await user.generateAuthToken(); + res.status(201).send({ user, token }); + } catch(err) { + if (err._message) { + res.status(422).send(err._message); + } else if (err.code && err.code === 11000) { + res.status(409).send('User with this email already exist'); + } else { + res.status(400).send('Could not save the user'); + } + } +}); + +router.post('/login', async (req, res) => { + try { + const user = await User.findByCredentials(req.body.email, req.body.password); + const token = await user.generateAuthToken(); + res.send({ user, token }); + } catch (err) { + res.status(401).send('Could not login'); + } +}); + +router.post('/logout', auth, async (req, res) => { + try { + req.user.tokens = req.user.tokens.filter((token) => { + return token.token !== req.token; + }); + await req.user.save(); + + res.send(); + } catch (err) { + res.status(500).send(); + } +}); + +module.exports = router; |