diff --git a/.gitignore b/.gitignore index 456f45a..8c57df3 100644 --- a/.gitignore +++ b/.gitignore @@ -1,3 +1,4 @@ .vscode/ node_modules/ -nodemon.json \ No newline at end of file +nodemon.json +now.json \ No newline at end of file diff --git a/api/routes/auth.js b/api/routes/auth.js index e06593c..06bc3b4 100644 --- a/api/routes/auth.js +++ b/api/routes/auth.js @@ -3,57 +3,58 @@ const bcrypt = require('bcrypt') const User = require('../models/user') const { decodeToken, generateToken } = require('../lib/token') -router.get('/profile', async (req, res, next) => { - try { - const payload = decodeToken(req.token) - const user = await User.findOne({ _id: payload.id }).select('-__v -password') - - const status = 200 - res.json({ status, user }) - } catch (e) { - console.error(e) - const error = new Error('You are not authorized to access this route.') - error.status = 401 - next(error) - } +router.get('/profile', async(req, res, next) => { + try { + const payload = decodeToken(req.token) + const user = await User.findOne({ _id: payload.id }).select('-__v -password') + + const status = 200 + res.json({ status, user }) + } catch (e) { + console.error(e) + const error = new Error('You are not authorized to access this route.') + error.status = 401 + next(error) + } }) -router.post('/login', async (req, res, next) => { - const { username, password } = req.body - const user = await User.findOne({ username }) - if (user) { - const valid = await bcrypt.compare(password, user.password) - if (valid) { - const status = 200 - const response = 'You have successful logged in.' - const token = generateToken(user._id) - return res.status(status).json({ status, response, token }) +router.post('/login', async(req, res, next) => { + const { username, password } = req.body + const user = await User.findOne({ username }) + if (user) { + const valid = await bcrypt.compare(password, user.password) + if (valid) { + const status = 200 + const response = 'You have successful logged in.' + console.log(user._id) + const token = generateToken(user._id) + return res.status(status).json({ status, response, token }) + } } - } - const message = `Username or password incorrect. Please check credentials and try again.` - const error = Error(message) - error.status = 401 - next(error) + const message = `Username or password incorrect. Please check credentials and try again.` + const error = Error(message) + error.status = 401 + next(error) }) -router.post('/signup', async (req, res, next) => { - const { username, password } = req.body - const rounds = 10 - const hashed = await bcrypt.hash(password, rounds) +router.post('/signup', async(req, res, next) => { + const { username, password } = req.body + const rounds = 10 + const hashed = await bcrypt.hash(password, rounds) - const alreadyExists = await User.findOne({ username }) - if (alreadyExists) { - const error = new Error(`Username '${username}' is already taken.`) - error.status = 400 + const alreadyExists = await User.findOne({ username }) + if (alreadyExists) { + const error = new Error(`Username '${username}' is already taken.`) + error.status = 400 - return next(error) - } + return next(error) + } - const status = 201 - const user = await User.create({ username, password: hashed }) - const token = generateToken(user._id) - res.status(status).json({ status, token }) + const status = 201 + const user = await User.create({ username, password: hashed }) + const token = generateToken(user._id) + res.status(status).json({ status, token }) }) -module.exports = router +module.exports = router \ No newline at end of file diff --git a/api/routes/users.js b/api/routes/users.js index d2211b2..b4b9ca3 100644 --- a/api/routes/users.js +++ b/api/routes/users.js @@ -5,34 +5,57 @@ const { validate } = require('../middleware/users') const excludeKeys = '-__v -password' -router.get('/', isLoggedIn, async (req, res, next) => { - const status = 200 - const response = await User.find(req.query).select(excludeKeys) - res.json({ status, response }) +router.get('/', isLoggedIn, async(req, res, next) => { + const status = 200 + const response = await User.find(req.query).select(excludeKeys) + res.json({ status, response }) }) -router.get('/:userId', isLoggedIn, async (req, res, next) => { - const status = 200 - const response = await User.findById(req.params.userId).select(excludeKeys) - res.json({ status, response }) +router.get('/:userId', isLoggedIn, async(req, res, next) => { + const status = 200 + const response = await User.findById(req.params.userId).select(excludeKeys) + res.json({ status, response }) }) -router.put('/:userId', isLoggedIn, isSameUser, validate, async (req, res, next) => { - const status = 200 - const query = { _id: req.params.userId } - const options = { new: true } - const response = await User.findOneAndUpdate(query, req.body, options).select(excludeKeys) +router.put('/:userId', isLoggedIn, isSameUser, validate, async(req, res, next) => { + const status = 200 + const query = { _id: req.params.userId } + const options = { new: true } + const response = await User.findOneAndUpdate(query, req.body, options).select(excludeKeys) - res.json({ status, response }) + res.json({ status, response }) }) -router.delete('/:userId', isLoggedIn, isSameUser, async (req, res, next) => { - const status = 200 +router.delete('/:userId', isLoggedIn, isSameUser, async(req, res, next) => { + const status = 200 - const query = { _id: req.params.userId } - const response = await User.findOneAndDelete(query, req.body).select(excludeKeys) + const query = { _id: req.params.userId } + const response = await User.findOneAndDelete(query, req.body).select(excludeKeys) - res.json({ status, response }) + res.json({ status, response }) }) +router.delete('/:userId/posts/:postId', isLoggedIn, isSameUser, async(req, res, next) => { + const status = 200 + console.log('BALEETED') + const query = { _id: req.params.userId } + const user = await User.findOne(query) + console.log(user.posts) + // const post = user.posts.findOne(req.params.postId) + const postQuery = { _id: req.params.userId } + const post = user.posts.id(req.params.postId) + post.remove() + + await user.save() + res.json({ status, response: post }) +}) + +router.post('/:userId/posts/:postId', isLoggedIn, isSameUser, async(req, res, next) => { + const status = 200 + console.log('Created!') + const query = { _id: req.params.userId } + const user = await User.findOne(query) + +}) + -module.exports = router +module.exports = router \ No newline at end of file diff --git a/app.js b/app.js index 97b2cdf..4648676 100644 --- a/app.js +++ b/app.js @@ -1,16 +1,23 @@ -const { NODE_ENV, PORT } = process.env +const { CLIENT_BASE_URL, NODE_ENV, PORT } = process.env const express = require('express') const app = express() +const cors = require('cors') // Database Connection require('./db/connection')() // Application-level Middleware +var corsOptions = { + origin: CLIENT_BASE_URL, + optionsSuccessStatus: 200 + } + // Attach token to request +app.use(require('./api/middleware/set-token')) + if (NODE_ENV === 'development') app.use(require('morgan')('dev')) app.use(require('body-parser').json()) - -// Attach token to request -app.use(require('./api/middleware/set-token')) + // CORS Access +app.use(cors(corsOptions)) // Routes app.use('/api', require('./api/routes/auth')) @@ -18,18 +25,18 @@ app.use('/api/users', require('./api/routes/users')) // Not Found Handler app.use((req, res, next) => { - const error = new Error(`Could not ${req.method} ${req.path}`) - error.status = 404 - next(error) + const error = new Error(`Could not ${req.method} ${req.path}`) + error.status = 404 + next(error) }) // Error Handler app.use((err, req, res, next) => { - if (NODE_ENV === 'development') console.error(err) - const { message, status } = err - res.status(status).json({ status, message }) + if (NODE_ENV === 'development') console.error(err) + const { message, status } = err + res.status(status).json({ status, message }) }) // Open Connection const listener = () => console.log(`Listening on Port ${PORT}!`) -app.listen(PORT, listener) +app.listen(PORT, listener) \ No newline at end of file diff --git a/db/seeds.js b/db/seeds.js index dea767f..27dc177 100644 --- a/db/seeds.js +++ b/db/seeds.js @@ -1,29 +1,25 @@ -const bcrypt = require('bcrypt') -const mongoose = require('mongoose') -const config = require('../nodemon.json') -const User = require('../api/models/user') + const bcrypt = require('bcrypt') + const mongoose = require('mongoose') + const config = require('../nodemon.json') + const User = require('../api/models/user') -const reset = async () => { - mongoose.connect(config.env.MONGO_DB_CONNECTION, { useNewUrlParser: true }) - // Careful with .remove() -- it sends a command directly to the database - // and skips any mongoose validations - await User.deleteMany() // Deletes all records - return User.create([ - { - name: 'Student User', - username: 'student.user', - password: bcrypt.hashSync('password', 10), - posts: [ - { - content: 'Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nullam gravida tincidunt tellus, vel vehicula turpis euismod a. Nulla lobortis mi nec sagittis hendrerit. Sed ultrices metus ut eros interdum, vel blandit mi lacinia.', - emotion: 'joy' - } - ] + const reset = async() => { + mongoose.connect(config.env.MONGO_DB_CONNECTION, { useNewUrlParser: true }) + // Careful with .remove() -- it sends a command directly to the database + // and skips any mongoose validations + await User.deleteMany() // Deletes all records + return User.create([{ + name: 'Student User', + username: 'student.user', + password: bcrypt.hashSync('password', 10), + posts: [{ + content: 'Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nullam gravida tincidunt tellus, vel vehicula turpis euismod a. Nulla lobortis mi nec sagittis hendrerit. Sed ultrices metus ut eros interdum, vel blandit mi lacinia.', + emotion: 'joy' + }] + }]) } - ]) -} -reset().catch(console.error).then((response) => { - console.log(`Seeds successful! ${response.length} records created.`) - return mongoose.disconnect() -}) + reset().catch(console.error).then((response) => { + console.log(`Seeds successful! ${response.length} records created.`) + return mongoose.disconnect() + }) \ No newline at end of file diff --git a/nodemon.sample.json b/nodemon.sample.json index 5bd928e..381766d 100644 --- a/nodemon.sample.json +++ b/nodemon.sample.json @@ -1,8 +1,9 @@ { - "env": { - "MONGO_DB_CONNECTION": "", - "NODE_ENV": "development", - "PORT": 5000, - "SECRET_KEY": "MYSECRETKEY" - } + "env": { + "CLIENT_BASE_URL": "http://localhost:3000", + "MONGO_DB_CONNECTION": "", + "NODE_ENV": "development", + "PORT": 5000, + "SECRET_KEY": "MYSECRETKEY" + } } \ No newline at end of file diff --git a/now.sample.json b/now.sample.json new file mode 100644 index 0000000..6864586 --- /dev/null +++ b/now.sample.json @@ -0,0 +1,18 @@ +{ + "name": "w6-backend-server", + "version": 2, + "builds": [{ + "src": "app.js", + "use": "@now/node-server" + }], + "routes": [{ + "src": "/.*", + "dest": "/app.js" + }], + "env": { + "CLIENT_BASE_URL": "https://..now.sh", + "MONGO_DB_CONNECTION": "mongodb+srv://steve_dave:C9ajzqCbVoHaGsHQ@sandbox01-40rq2.gcp.mongodb.net/journal_dev?retryWrites=true&w=majority", + "NODE_ENV": "production", + "SECRET_KEY": "SecretKey" + } +} \ No newline at end of file diff --git a/package-lock.json b/package-lock.json index 9c4b285..e817dee 100644 --- a/package-lock.json +++ b/package-lock.json @@ -642,6 +642,15 @@ "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.2.tgz", "integrity": "sha1-tf1UIgqivFq1eqtxQMlAdUUDwac=" }, + "cors": { + "version": "2.8.5", + "resolved": "https://registry.npmjs.org/cors/-/cors-2.8.5.tgz", + "integrity": "sha512-KIHbLJqu73RGr/hnbrO9uBeixNGuvSQjul/jdFvS/KFSIH1hWVd1ng7zOHx+YrEfInLG7q4n6GHQ9cDtxv/P6g==", + "requires": { + "object-assign": "^4", + "vary": "^1" + } + }, "create-error-class": { "version": "3.0.2", "resolved": "https://registry.npmjs.org/create-error-class/-/create-error-class-3.0.2.tgz", diff --git a/package.json b/package.json index 297f6b5..13113e8 100644 --- a/package.json +++ b/package.json @@ -20,6 +20,7 @@ "dependencies": { "bcrypt": "^3.0.6", "body-parser": "^1.19.0", + "cors": "^2.8.5", "express": "^4.17.1", "jsonwebtoken": "^8.5.1", "mongoose": "^5.6.5"