-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
takuyadev
committed
Nov 4, 2022
1 parent
d6f8de3
commit da74a38
Showing
9 changed files
with
465 additions
and
13 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,89 @@ | ||
const asyncHandler = require('../middleware/async') | ||
const ErrorResponse = require('../utils/errorResponse') | ||
const User = require('../model/User') | ||
|
||
// @desc Register user | ||
// @route POST /api/v1/auth/register | ||
// @access Public | ||
|
||
exports.register = asyncHandler(async (req, res, next) => { | ||
const { name, email, password, role } = req.body | ||
|
||
// Create user | ||
const user = await User.create({ | ||
name, | ||
email, | ||
password, | ||
role | ||
}) | ||
|
||
// Create token | ||
sendTokenResponse(user, 200, res) | ||
}) | ||
|
||
|
||
// @desc Login user | ||
// @route POST /api/v1/auth/register | ||
// @access Public | ||
|
||
exports.login = asyncHandler(async (req, res, next) => { | ||
const { email, password } = req.body | ||
|
||
// Validate email & password | ||
if (!email || !password) { | ||
return next(new ErrorResponse('Please provide an email and password', 400)) | ||
} | ||
|
||
// Check for user | ||
const user = await User.findOne({ email }).select('+password') | ||
|
||
if (!user) { | ||
return next(new ErrorResponse('Invalid credentials', 401)) | ||
} | ||
|
||
// Check if password matches | ||
const isMatch = await user.matchPassword(password) | ||
|
||
if (!isMatch) { | ||
return next(new ErrorResponse('Invalid credentials', 401)) | ||
} | ||
|
||
sendTokenResponse(user, 200, res) | ||
}) | ||
|
||
|
||
// Get token from model, create cookie and send response | ||
const sendTokenResponse = (user, statusCode, res) => { | ||
// Create token | ||
const token = user.getSignedJwtToken() | ||
|
||
const options = { | ||
expires: new Date(Date.now() + process.env.JWT_COOKIE_EXPIRE * 24 * 60 * 60 * 1000), | ||
httpOnly: true | ||
} | ||
|
||
if (process.env.NODE_ENV === 'production') { | ||
options.secure = true | ||
} | ||
|
||
res | ||
.status(statusCode) | ||
.cookie('token', token, options) | ||
.json({ | ||
success: true, | ||
token | ||
}) | ||
} | ||
|
||
|
||
// @desc Get current logged in user | ||
// @route POST /api/v1/auth/me | ||
// @access Private | ||
exports.getMe = asyncHandler(async (req, res, next) => { | ||
const user = await User.findById(req.user.id) | ||
|
||
res.status(200).json({ | ||
success: true, | ||
data: user | ||
}) | ||
}) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,54 @@ | ||
const jwt = require('jsonwebtoken') | ||
const asyncHandler = require('./async') | ||
const ErrorResponse = require('../utils/errorResponse') | ||
const User = require('../model/User') | ||
|
||
// Protect routes | ||
exports.protect = asyncHandler(async (req, res, next) => { | ||
let token | ||
console.log(req.headers.authorization) | ||
|
||
if ( | ||
req.headers.authorization && | ||
req.headers.authorization.startsWith('Bearer') | ||
) { | ||
// Set token from Bearer token in header | ||
token = req.headers.authorization.split(' ')[1]; | ||
} | ||
|
||
// Set token from cookie | ||
|
||
// else if (req.cookies.token) { | ||
// token = req.cookies.token | ||
// } | ||
|
||
// Make sure token exists | ||
|
||
if (!token) { | ||
return next(new ErrorResponse(`Not authorized to access this route`, 404)) | ||
} | ||
|
||
try { | ||
// Verify token | ||
const decoded = jwt.verify(token, process.env.JWT_SECRET) | ||
|
||
console.log(decoded) | ||
|
||
req.user = await User.findById(decoded._id) | ||
|
||
next(); | ||
} catch (err) { | ||
return next(new ErrorResponse(`Not authorized to access this route`, 404)) | ||
} | ||
}) | ||
|
||
|
||
// Grant access to specific roles | ||
exports.authorize = (...roles) => { | ||
return (req, res, next) => { | ||
if (!roles.includes(req.user.role)) { | ||
return next(new ErrorResponse(`User role ${req.user.role} is unauthorized to access this route`, 403)) | ||
} | ||
next() | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,56 @@ | ||
const mongoose = require('mongoose') | ||
const bcrypt = require('bcryptjs') | ||
const jwt = require('jsonwebtoken') | ||
const UserSchema = new mongoose.Schema({ | ||
name: { | ||
type: String, | ||
required: [true, 'Please add a name'] | ||
}, | ||
email: { | ||
type: String, | ||
required: [true, 'Please add an email'], | ||
unique: true, | ||
match: [ | ||
/^(([^<>()\[\]\\.,;:\s@"]+(\.[^<>()\[\]\\.,;:\s@"]+)*)|(".+"))@((\[[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}])|(([a-zA-Z\-0-9]+\.)+[a-zA-Z]{2,}))$/, | ||
"Please use a valid email address" | ||
] | ||
}, | ||
role: { | ||
type: String, | ||
enum: ['user', 'publisher'], | ||
default: 'user' | ||
}, | ||
password: { | ||
type: String, | ||
required: [true, 'Please enter a password'], | ||
minlength: 6, | ||
select: false, | ||
}, | ||
resetPasswordToken: String, | ||
resetPasswordExpire: Date, | ||
createdAt: { | ||
type: Date, | ||
default: Date.now | ||
} | ||
}) | ||
|
||
// Encrypt password using bcrypt | ||
UserSchema.pre('save', async function () { | ||
const salt = await bcrypt.genSalt(10) | ||
this.password = await bcrypt.hash(this.password, salt) | ||
}) | ||
|
||
// Sign JWT and return | ||
UserSchema.methods.getSignedJwtToken = function () { | ||
return jwt.sign({ _id: this._id }, process.env.JWT_SECRET, { | ||
expiresIn: process.env.JWT_EXPIRE | ||
}) | ||
} | ||
|
||
// Match user entered password to hashed password in database | ||
UserSchema.methods.matchPassword = async function (enteredPassword) { | ||
return await bcrypt.compare(enteredPassword, this.password) | ||
} | ||
|
||
|
||
module.exports = mongoose.model('User', UserSchema) |
Oops, something went wrong.