Express-JWT authentication middleware error: Next is not a function - node.js

I am building a frontend application that uses 2FA in addition to JWT to authorize a authenticated account. The middleware is set up as such:
const router = require('express').Router()
const jwt = require('jsonwebtoken')
const exjwt = require('express-jwt')
const jwtMW = exjwt({
secret: 'testing out a secret',
})
const getBearerToken = (header, callback) => {
if (header) {
console.log(header)
const token = header.split(' ')
if (token) {
return callback(null, token[0])
} else {
return callback('Malformed bearer token', null)
}
} else {
return callback('Missing authorization header', null)
}
}
const validateToken = (req, res, next) => {
getBearerToken(req.headers['authorization'], (error, token) => {
if (error) {
return res.status(401).json({ success: false, message: error })
}
jwt.verify(token, jwtMW, (error, decodedToken) => {
if (error) {
return res.status(401).send({
success: false,
error: 'Invalid authorization token',
})
}
if (decodedToken.authorized) {
req.decodedToken = decodedToken
next()
} else {
return res
.status(401)
.send({ success: false, error: '2fa is required' })
}
})
})
}
I run it on protected routes like this:
router.get('/:id/profile', validateToken, (req, res) => {
User.findById(req.params.id)
.then(user => res.json(user))
.catch(err => res.status(400).json('Error: ' + err))
})
EDIT, ADDITIONAL ROUTE
And another route that fetches the token here:
router.post('/verifycheck', (req, res) => {
let tel = `+1${req.body.tel}`
const code = req.body.code
getBearerToken(req.headers['authorization'], (error, token) => {
if (error) {
console.log(error)
return res.status(401).json({ success: false, message: error })
}
if (!code) {
return res.status(401).json({
success: false,
message: 'A verification code is required',
})
}
jwt.verify(token, jwtMW, (error, decodedToken) => {
// client refers to Twilio Verify service //
client.verify
.services('xxxxxxxxxxxxxxxxxxxxx')
.verificationChecks.create({ to: tel, code: code })
.then(verification_check => {
console.log(error)
console.log(decodedToken)
if (verification_check.valid) {
decodedToken.authorized = true
console.log(decodedToken)
var token = jwt.sign(decodedToken, jwtMW, {
expiresIn: 129600,
})
return res.json({ verification_check, token })
} else {
return res.status(401).json({
success: false,
message: 'Invalid verification code',
})
}
})
.catch(err => {
res.json(err.message)
console.log(err)
})
})
})
})
And it throws an error that crashes the server, saying
TypeError: next is not a function
at middleware (D:\Users\Capstone Design\Desktop\learningmongodb\mern-rod\node_modules\express-jwt\lib\index.js:76:16)
at Object.module.exports [as verify] (D:\Users\Capstone Design\Desktop\learningmongodb\mern-rod\node_modules\jsonwebtoken\verify.js:94:10)
at getBearerToken (D:\Users\Capstone Design\Desktop\learningmongodb\mern-rod\backend\routes\index.js:109:13)
at getBearerToken (D:\Users\Capstone Design\Desktop\learningmongodb\mern-rod\backend\routes\index.js:22:20)
at router.post (D:\Users\Capstone Design\Desktop\learningmongodb\mern-rod\backend\routes\index.js:97:5)
I see where the error is happening, but I'm unsure of how to fix this error.
EDIT
I realized that jwt.verify doesn't accept callbacks as an argument. When I removed the callback function and ran the verify function in a try/catch statement, things worked as expected.
const validateToken = (req, res, next) => {
getBearerToken(req.headers['authorization'], (error, token) => {
if (error) {
return res.status(401).json({ success: false, message: error })
}
let decoded = ''
try {
decoded = jwt.verify(token, 'testing out a secret')
} catch (error) {
return res.status(401).send({
success: false,
error: 'Invalid authorization token',
})
}
if (decoded.authorized) {
req.decodedToken = decoded
next()
} else {
return res
.status(401)
.send({ success: false, error: '2fa is required' })
}
})
}

Related

Chaining 2 auth tokens in one endpoint

I'm trying to chain 2 auth tokens in one endpoint, the user and the admin, to get all merchants.
I have tried several solutions posted by several people here on stackoverflow, with no luck. I'll post my code along with the solutions I tried below.
How can I make express to continue the process if the request has ONE of the 2 tokens, admin OR user?
Thanks in advance...
Admin auth:
const adminAuth = async (req, res, next) => {
try {
const token = req.header('Authorization');
if(!token) {
return res.status(401).json({ message: 'Unauthorized', success: false });
}
const newToken = req.header('Authorization').split(' ')[1];
const decoded = JWT.verify(newToken, key);
if(decoded.role != 'admin') {
return res.status(401).json(
{ message: 'Unauthorized, only an admin is authorized!', success: false }
);
}
const findAdmin = await Admin.findOne({ username: decoded.username });
if(!findAdmin){
return res.status(409).send({ message: `Admin doesn't exist!`, success: false });
}
} catch (err) {
console.log(err);
}
next();
}
User auth:
const userAuth = async (req, res, next) => {
try {
const token = req.header('Authorization');
if(!token) {
return res.status(401).json({ message: 'Unauthorized', success: false });
}
const newToken = req.header('Authorization').split(' ')[1];
const decoded = JWT.verify(newToken, key);
if(decoded.role != 'user') {
return res.status(401).json({ message: 'Unauthorized, only a user is authorized!', success: false });
}
const findUser = await User.findOne({ email: decoded.email });
if(!findUser){
return res.status(409).send({ message: `User doesn't exist!`, success: false });
}
} catch (err) {
console.log(err);
}
next();
}
The endpoint in question:
router.get('/getall', adminAuth, usertAuth, upload.none(), async (req, res) => {
const merchantsList = await Merchant.find();
if(!merchantsList) {
return res.status(500).send({ success: false });
}
return res.status(200).send({ merchants: merchantsList, success: true });
});
I tried the below solutions:
router.get('/getall', [adminAuth, usertAuth], upload.none(), async (req, res) => {
const merchantsList = await Merchant.find();
if(!merchantsList) {
return res.status(500).send({ success: false });
}
return res.status(200).send({ merchants: merchantsList, success: true });
});
router.get('/getall', [adminAuth || usertAuth], upload.none(), async (req, res) => {
const merchantsList = await Merchant.find();
if(!merchantsList) {
return res.status(500).send({ success: false });
}
return res.status(200).send({ merchants: merchantsList, success: true });
});
router.get('/getall', [adminAuth, usertAuth, upload.none(), async (req, res) => {
const merchantsList = await Merchant.find();
if(!merchantsList) {
return res.status(500).send({ success: false });
}
return res.status(200).send({ merchants: merchantsList, success: true });
}]);
router.get('/getall', [adminAuth, usertAuth, upload.none()], async (req, res) => {
const merchantsList = await Merchant.find();
if(!merchantsList) {
return res.status(500).send({ success: false });
}
return res.status(200).send({ merchants: merchantsList, success: true });
});
That's not how middlewares work in express for example let's look at getAll route
router.get('/getall', [adminAuth, usertAuth], upload.none(), async (req, res) => {
try{
//some code
}catch(e){
//handle error
}
});
if the user is not admin it will fail at adminAuth and end the request, so you have to think of middlewares as a chain or a pipleline they pass (req,res,next) to each other
so what you need here is not make a third middleware which is the combination of adminAuth and userAuth
async function adminAndUserAuth (req, res, next){
try {
const token = req.header('Authorization');
if(!token) {
return res.status(401).json({ message: 'Unauthorized', success: false });
}
const newToken = req.header('Authorization').split(' ')[1];
const decoded = JWT.verify(newToken, key);
if(decoded.role != 'admin' && decoded.role != 'user' ) {
return res.status(401).json(
{ message: 'Unauthorized, only an admin or user are authorized!', success: false }
);
}
const found = await Admin.findOne({ username: decoded.username }) ?? await User.findOne({ email: decoded.email });
if(!found){
return res.status(409).send({ message: `Admin doesn't exist!`, success: false });
}
} catch (err) {
console.log(err);
}
next();
}
and the new route will be
router.get('/getall' , adminAndUserAuth , async (req,res) => {});

Refreshing JWT access token with refresh token within single middleware function on a post route

I'm trying to learn JWT authentication in express and one thing that I'm came across this code from Github
that this guy has initialised an middleware function to authenticate and check expiry of access token as per below:
app.post("/protected", auth, (req, res) => {
return res.json({ message: "Protected content!" });
})
async function auth(req, res, next) {
let token = req.headers["authorization"];
token = token.split(" ")[1]; //Access token
jwt.verify(token, "access", async (err, user) => {
if (user) {
req.user = user;
next();
} else if (err.message === "jwt expired") {
return res.json({
success: false,
message: "Access token expired"
});
} else {
console.log(err);
return res
.status(403)
.json({ err, message: "User not authenticated" });
}
});
}
and a separate route for refreshing the access token with the help of refresh token
app.post("/refresh", (req, res, next) => {
const refreshToken = req.body.token;
if (!refreshToken || !refreshTokens.includes(refreshToken)) {
return res.json({ message: "Refresh token not found, login again" });
}
// If the refresh token is valid, create a new accessToken and return it.
jwt.verify(refreshToken, "refresh", (err, user) => {
if (!err) {
const accessToken = jwt.sign({ username: user.name }, "access", {
expiresIn: "20s"
});
return res.json({ success: true, accessToken });
} else {
return res.json({
success: false,
message: "Invalid refresh token"
});
}
});
});
So, my question is how secure it is and how can I create single middleware function that could do both authentication and refreshing access token without hitting the app.post('/refresh') as in my view it wouldn't be a smooth experience to deal with it in frontend API management within react
Edit
My middleware seems to work well but it doesn't identify the wrong refresh token and then actually getting worked on protected route
app.post('/home', authenticateUser, (req, res) => {
res.send('welcome');
});
async function authenticateUser(req, res, next) {
let token = req.headers['authorization'];
token = token.split(' ')[1];
jwt.verify(token, JWT_AUTH_TOKEN, async (err, phone) => {
if (phone) {
req.phone = phone;
next();
} else if (err) {
const refreshToken = req.body.refreshToken;
if (!refreshToken || !refreshTokens.includes(refreshToken)) {
return res.json({ message: 'Refresh token not found, login again' });
} else {
jwt.verify(refreshToken, JWT_REFRESH_TOKEN, (err, phone) => {
if (!err) {
const accessToken = jwt.sign({ phone }, JWT_AUTH_TOKEN, { expiresIn: '30s' });
return res.json({ success: true, accessToken });
} else {
return res.json({
success: false,
message: 'Invalid refresh token'
});
}
next();
});
}
} else {
console.log(err);
return res.status(403).json({ err, message: 'User not authenticated' });
}
});
}

router.patch is returning 404 "not found"

I am working on small node api and I have an issue with patch method.
My router.patch is returning me 404.
This is how my route looks:
router.param('userId', findById);
router.patch(
'/api/projects/update/:projectId/:userId',
authCheck,
isAdmin,
findProjectById,
update
);
The findById is based on my :userId param. Whole method looks like this:
exports.findById = async (req, res, next) => {
try {
let user = await User.findById(req.params.userId);
if (!user) return res.status(400).json({ msg: 'User not found' });
next();
} catch (err) {
console.error(err.message);
if (err.kind === 'ObjectId') {
return res.status(400).json({ msg: 'User not found' });
}
res.status(500).send('Server Error');
}
};
Based on that I should get proper user for proper project.
My two ayhorization methods:
exports.authCheck = async (req, res, next) => {
try {
/* get token from header
replace('Bearer', '') - this will remove bearer from token header
*/
const token = req.header('Authorization').replace('Bearer', '');
//check if no token
if (!token) {
return res.status(401).json({ msg: 'No token, authorization denied' });
}
/*
decoded contains _id as a payload in token. Id is from getAuthToken */
const decoded = jwt.verify(token, config.get('jwtSecret'));
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).json({ msg: 'Please authenticate' });
}
};
exports.isAdmin = async (req, res, next) => {
try {
if (req.user.role !== config.get('roleSecret')) {
return res.status(403).json({
errors: [
{
msg: 'No Admin rights. Access Denied!!',
},
],
});
}
next();
} catch (err) {
res.status(403).json({ msg: 'Forbidden access' });
}
};
Finaly, my project controller where i have findProjectById, update
In findProjectById I am looking for project based on route param and i assing it to project
exports.findProjectById = async (req, res, next) => {
const _id = req.params.projectId;
try {
let project = await Project.findById(_id);
if (!project) return res.status(400).json({ msg: 'Porject not found' });
req.project = project;
next();
} catch (err) {
console.error(err.message);
if (err.kind === 'ObjectId') {
return res.status(400).json({ msg: 'Porject not found' });
}
res.status(500).send('Server Error');
}
};
My update method i s not done, because i was testing if anything heppens
exports.update = async (req, res) => {
try {
const proj = await req.project;
const _id = proj._id;
await Project.findByIdAndUpdate(_id, req.body, {
new: true,
runValidators: true,
});
if (!proj) {
return res.status(404).json({ msg: 'Project not found' });
}
return res.json(proj);
} catch (err) {
res.status(500).send('Server Error');
}
};
Not sure what am I missing here, but after few hours and lot of searching still can't get this working
Get this working. Issue was in my router path.
/api/projects/update/:projectId/:userId
Should be
/projects/update/:projectId/:userId
this can be closed

Not getting correct status code (409) if email exists using Next.js, Mongoose, MongoDb Atlas and Express

I am building a login/Register portion of my app. Right now I'm using express-validator to check if an email exists in my collection.
This is my route:
var router = require('express').Router()
var UserModel = require('../models/UserModel')
var { body } = require('express-validator');
router
.route('/registration')
.get(function(req, res) {
console.log(0)
UserModel.find({}, (err, users) => {
console.log(1);
if (err) return res.status(500).send(err)
console.log(2);
return res.json(users);
})
})
.post(body('username_email').custom(value => {
console.log("value ", value);
console.log(3)
UserModel.findOne({ 'username_email': value }, (err) => {
console.log(4);
if (err) return res.status(409).send(err);
})
}), async(req, res, next) => {
console.log(5)
try {
let newUser = new UserModel(req.body);
let savedUser = await newUser.save();
console.log(6);
if (savedUser) return res.redirect('/users/registration?success=true');
return next(new Error('Failed to save user for unknown reasons'))
} catch (err) {
return next(err)
}
})
module.exports = router
In my component on the front end I have a function in my fetch which will catch the error if there is one.
handleErrors(response) {
if (!response.ok) {
console.log('This email exists!')
throw Error(response.statusText);
}
return response;
}
handleSubmit(event) {
event.preventDefault()
var { username, password } = this.state
var mailFormat = /^(([^<>()\[\]\\.,;:\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,}))$/
var error = false
if (!username.match(mailFormat)) {
this.setState({ usernameError: true })
error = true
} else {
this.setState({ usernameError: false })
}
if (password.length <= 8) {
this.setState({ passwordError: true })
error = true
} else {
this.setState({ passwordError: false })
}
console.log(`error ${error}`)
if (error == false) {
this.setState({ formError: false, formSuccess: true })
}
window.fetch('http://localhost:8016/users/registration', {
method: 'POST',
headers: { 'Accept': 'application/json', 'Content-Type': 'application/json' },
body: JSON.stringify({ username_email: username, password: password })
})
.then(this.handleErrors)
.then(function (response) {
console.log(`response ${response}`)
return response.json()
}).then(function (data) {
console.log('User created:', data)
}).catch(function (error) {
console.log(error);
});
}
The console.log in the fetch, handleErrors is being registered in the console, but why isn't the error status a 409 like I indicated.
Closer excerpt of post route!
.post(body('username_email').custom(value => {
console.log("value ", value);
console.log(3)
Is this the problem? Node style should have a error and callback?
UserModel.findOne({ 'username_email': value }, (err) => {
console.log(4);
if (err) return res.status(409).send(err);
})
}), async(req, res, next) => {
console.log(5)
try {
let newUser = new UserModel(req.body);
let savedUser = await newUser.save();
console.log(6);
if (savedUser) return res.redirect('/users/registration?success=true');
return next(new Error('Failed to save user for unknown reasons'))
} catch (err) {
return next(err)
}
})
UPDATE
I tried Nick's solution but I get this:
MongoError: E11000 duplicate key error collection: development.users index: email_1 dup key: { : null }
at Function.create (/Users/antoniopavicevac-ortiz/Dropbox/developer_folder/hillfinder/node_modules/mongodb-core/lib/error.js:43:12)
at toError (/Users/antoniopavicevac-ortiz/Dropbox/developer_folder/hillfinder/node_modules/mongodb/lib/utils.js:149:22)
at coll.s.topology.insert (/Users/antoniopavicevac-ortiz/Dropbox/developer_folder/hillfinder/node_modules/mongodb/lib/operations/collection_ops.js:859:39)
at handler (/Users/antoniopavicevac-ortiz/Dropbox/developer_folder/hillfinder/node_modules/mongodb-core/lib/topologies/replset.js:1155:22)
at /Users/antoniopavicevac-ortiz/Dropbox/developer_folder/hillfinder/node_modules/mongodb-core/lib/connection/pool.js:397:18
at process._tickCallback (internal/process/next_tick.js:61:11)
POST /users/registration 500 312.485 ms - 51
^C
Two things I am noticing:
I get back MongoError: E11000 duplicate key error collection: development.users index: email_1 dup key: { : null }
which is the error from having a duplicate email, but number one where is E-mail already in use message in the console from the promise? And two how can I pass the error status "res.status(409).send(err);" from the promise?
The issue was that during your validation, you weren't returning the promise since the mongoose call is async. The rest the code ran before your validator was finished. I commented where you were missing the return.
router.route('/registration')
.get(function(req, res) {
UserModel.find({}, (err, users) => {
if (err) res.status(500).send(err)
res.json(users)
})
})
.post(body('username').custom(value => {
return UserModel.findOne({ 'email': value }).then(user => { // Return Promise
if (user) {
return Promise.reject('E-mail already in use');
}
});
}), async(req, res, next) => {
try {
let newUser = new UserModel(req.body)
let savedUser = await newUser.save(err => {
if (err) return res.json({ success: false, error: err })
return res.json({ success: true })
})
if (savedUser) return res.redirect('/users/registration?success=true');
return next(new Error('Failed to save user for unknown reasons'))
} catch (err) {
return next(err)
}
})
module.exports = router
UPDATE
Just read through express-validator docs. I think you would need to validate the errors during the request process
var router = require('express').Router()
var UserModel = require('../models/UserModel')
var { body, validationResult } = require('express-validator');
router.route('/registration')
.get(function(req, res) {
UserModel.find({}, (err, users) => {
if (err) res.status(500).send(err)
res.json(users)
})
})
.post(body('username').custom(value => {
return UserModel.findOne({ 'email': value }).then(user => { // Return Promise
if (user) {
return Promise.reject('E-mail already in use');
}
});
}), async(req, res, next) => {
// Checks for errors in validation
const errors = validationResult(req);
if (!errors.isEmpty()) {
return res.status(422).json({ errors: errors.array() });
}
try {
let newUser = new UserModel(req.body)
let savedUser = await newUser.save(err => {
if (err) return res.json({ success: false, error: err })
return res.json({ success: true })
})
if (savedUser) return res.redirect('/users/registration?success=true');
return next(new Error('Failed to save user for unknown reasons'))
} catch (err) {
return next(err)
}
})
module.exports = router

JSON Web Tokens resetting express server

I'm creating a demo MEAN app and everything was going well I could Add and Authenticate Users and Add, Delete and Update Messages but after I implemented web token I can only view and delete messages when I try to add a new message I get this error.
The message is still added to my mongodb database but it stops the server.
I was trying to add my code from the components but I'm not allowed as I get a message saying that my post is mostly code and I need to add more information.
zone.js?fad3:2935 POST http://localhost:3000/message?token=eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJ1c2VyIjp7Il9pZCI6IjVhNWRiMmFjYmVkMWQ3MmZmOGQzMDM3YSIsImZpcnN0TmFtZSI6IkpvaG4iLCJsYXN0TmFtZSI6IkRvZSIsInBhc3N3b3JkIjoiJDJhJDEwJHZmMVQ2S0VCeVZBSE9qSkRyQWg0WC51N3NHYXZZVXNQSHZyOHFNTllydVdJL3lZZXBKR0ZhIiwiZW1haWwiOiJqb2huQGRvZS5jb20iLCJfX3YiOjksIm1lc3NhZ2VzIjpbXX0sImlhdCI6MTUxNjEwMjM1NSwiZXhwIjoxNTE2MTA5NTU1fQ.6Kj1TcprqWRQIAZ9GSDHLxIbf_9DzPhx5qomv6QtxfA net::ERR_CONNECTION_RESET
Message Route
let express = require('express');
let router = express.Router();
let jwt = require('jsonwebtoken');
let User = require('../models/user');
let Message = require('../models/message');
router.get('/', (req, res, next) => {
Message.find()
.populate('user', 'firstName')
.exec( (err, messages) => {
if (err) {
return res.status(500).json({
title: 'An error occurred',
error: err
});
}
res.status(200).json({
message: 'Success',
obj: messages
});
});
});
router.use('/', (req, res, next) => {
jwt.verify(req.query.token, 'secret', (err, decoded) => {
if (err) {
return res.status(401).json({
title: 'Not Authenticated',
error: err
});
}
next();
})
});
router.post('/', (req, res, next) => {
let decoded = jwt.decode(req.query.token);
User.findById(decoded.user._id, (err, user) => {
if (err) {
return res.status(500).json({
title: 'An error occurred',
error: err
});
}
let message = new Message({
content: req.body.content,
user: user
});
message.save((err, result) => {
if (err) {
return res.status(500).json({
title: 'An error occurred',
error: err
});
}
user.messages.push(result);
user.save();
res.status(201).json({
message: 'Saved message',
obj: result
});
});
});
});
router.patch('/:id', (req, res, next) => {
let decoded = jwt.decode(req.query.token);
Message.findById(req.params.id, (err, message) => {
if (err) {
return res.status(500).json({
title: 'An error occurred',
error: err
});
}
if (!message) {
return res.status(500).json({
title: 'No Message Found!',
error: {message: 'Message not found'}
});
}
if (message.user != decoded.user._id) {
return res.status(401).json({
title: 'Not Authenticated',
error: {message: 'Users do not match'}
});
}
message.content = req.body.content;
message.save((err, result) => {
if (err) {
return res.status(500).json({
title: 'An error occurred',
error: err
});
}
res.status(200).json({
message: 'Updated message',
obj: result
});
});
});
});
router.delete('/:id', (req, res, next) => {
let decoded = jwt.decode(req.query.token);
Message.findById(req.params.id, (err, message) => {
if (err) {
return res.status(500).json({
title: 'An error occurred',
error: err
});
}
if (!message) {
return res.status(500).json({
title: 'No Message Found!',
error: {message: 'Message not found'}
});
}
if (message.user != decoded.user._id) {
return res.status(401).json({
title: 'Not Authenticated',
error: {message: 'Users do not match'}
});
}
message.remove((err, result) => {
if (err) {
return res.status(500).json({
title: 'An error occurred',
error: err
});
}
res.status(200).json({
message: 'Deleted message',
obj: result
});
});
});
});
module.exports = router;
Message Service
import { Http, Response, Headers } from "#angular/http";
import { Injectable, EventEmitter } from "#angular/core";
import 'rxjs/Rx';
import { Observable } from "rxjs";
import { Message } from "./message.model";
#Injectable()
export class MessageService {
private messages: Message[] = [];
messageIsEdit = new EventEmitter<Message>();
constructor(private http: Http) {
}
addMessage(message: Message) {
const body = JSON.stringify(message);
const headers = new Headers({'Content-Type': 'application/json'});
const token = localStorage.getItem('token')
? '?token=' + localStorage.getItem('token')
: '';
return this.http.post('http://localhost:3000/message' + token, body, {headers: headers})
.map((response: Response) => {
const result = response.json();
const message = new Message(
result.obj.content,
result.obj.user.firstName,
result.obj._id,
result.obj.user._id);
this.messages.push(message);
return message;
})
.catch((error: Response) => Observable.throw(error.json()));
}
getMessages() {
return this.http.get('http://localhost:3000/message')
.map((response: Response) => {
const messages = response.json().obj;
let transformedMessages: Message[] = [];
for (let message of messages) {
transformedMessages.push(new Message(
message.content,
message.user.firstName,
message._id,
message.user._id)
);
}
this.messages = transformedMessages;
return transformedMessages;
})
.catch((error: Response) => Observable.throw(error.json()));
}
editMessage(message: Message) {
this.messageIsEdit.emit(message);
}
updateMessage(message: Message) {
const body = JSON.stringify(message);
const headers = new Headers({'Content-Type': 'application/json'});
const token = localStorage.getItem('token')
? '?token=' + localStorage.getItem('token')
: '';
return this.http.patch('http://localhost:3000/message/' + message.messageId + token, body, {headers: headers})
.map((response: Response) => response.json())
.catch((error: Response) => Observable.throw(error.json()));
}
deleteMessage(message: Message) {
this.messages.splice(this.messages.indexOf(message), 1);
const token = localStorage.getItem('token')
? '?token=' + localStorage.getItem('token')
: '';
return this.http.delete('http://localhost:3000/message/' + message.messageId + token)
.map((response: Response) => response.json())
.catch((error: Response) => Observable.throw(error.json()));
}
}

Resources