What I'm trying to accomplish is to write a message in a database when the user sends a message. I'm using the MEAN stack with angular-cli.
The error I am receiving is:
TypeError: Cannot read property '_id' of undefined
at JwtStrategy._verify (/Volumes/SSD/Documents/WebProjects/MEANTest/config/passport.js:11:38)
at /Volumes/SSD/Documents/WebProjects/MEANTest/node_modules/passport-jwt/lib/strategy.js:110:26
at /Volumes/SSD/Documents/WebProjects/MEANTest/node_modules/jsonwebtoken/verify.js:27:18
at _combinedTickCallback (internal/process/next_tick.js:73:7)
at process._tickCallback (internal/process/next_tick.js:104:9)
Here is every bit of code I use to see if someone can figure out what I'm doing wrong.
Node with Express located in '/users':
router.post('/newmessages', passport.authenticate('jwt', {session: false}), function(req, res, next){
var msgID = getMessageID(req.body.user.username);
let newMessage = Message({
createdBy:req.body.message.createdBy,
recipients:req.body.message.recipients,
dateCreated:getTodayDate(),
subject:req.body.message.subject,
message:req.body.message.message,
read: false,
previousMessage:req.body.message.previousMessage,
nextMessage:req.body.message.nextMessage,
messageID:msgID
});
console.log(newMessage);
Message.checkMessageID(newMessage, function(err, isFound){
if(err) throw err;
if(isFound)
{
newMessage.messageID = getMessageID(req.body.username);
}
else
{
Message.createMessage(newMessage, function(err, isCreated){
if(err) throw err;
if(isCreated)
{
var token = jwt.sign(req.body, config.secret, {
expiresIn: 604800 // A week worth of seconds
});
res.json({
success: true,
token: "JWT " + token,
user: {
id: req.body._id,
name: req.body.name,
username: req.body.username,
email: req.body.email
},
msg: "Your password has been changed."
});
}
else
{
var token = jwt.sign(req.body, config.secret, {
expiresIn: 604800 // A week worth of seconds
});
res.json({
success: true,
token: "JWT " + token,
user: {
id: req.body._id,
name: req.body.name,
username: req.body.username,
email: req.body.email
},
msg: "Your password has been changed."
});
}
});
}
});
});
Mongoose schema and code:
var mongoose = require('mongoose');
var config = require('../config/messages');
// Message Schema
var messageSchema = mongoose.Schema({
createdBy: {
type: String,
required: true
},
recipients:{
type: String,
required: true
},
dateCreated: {
type: String,
required: true
},
subject: {
type: String,
required: true
},
message: {
type: String,
required: true
},
previousMessage: {
type: String,
required: true
},
nextMessage: {
type: String,
required: true
},
read: {
type:Boolean,
required: true
},
messageID: {
type: String,
required: true
}
});
var secondConn = mongoose.createConnection(config.database);
// On Connection
secondConn.on('connected', function(){
console.log("Connected to database "+ config.database);
});
// On Error
secondConn.on('error', function(err){
console.log("Database Error " + err);
});
var Messages = module.exports = secondConn.model('Messages', messageSchema);
module.exports.getAllUserMessages = function(user, callback){
var query = {createdBy: user};
Messages.find(query, callback);
};
module.exports.getAllRecpMessages = function(user, callback){
var query = {recipients: user};
Messages.find(query, callback);
};
module.exports.deleteMessage = function(list, callback){
var query, i;
for(i = 0; i < list.length; i++)
{
query = { messageID: list[i].messageID};
Messages.remove(query, function(err){
});
}
};
module.exports.createMessage = function(message, callback){
message.save(function(err, doc){
if(err) throw err;
if(doc === null)
{
callback(null, false);
}
else
{
callback(null, true);
}
});
};
// Returns false if no other message has the same ID
module.exports.checkMessageID = function(message, callback){
var query = {messageID: message.messageID};
Messages.findOne(query, function(err, message){
if(err) throw err;
if(message === null)
{
callback(null, false);
}
else
{
callback(null, true);
}
});
};
Angular typescript for '/users/messages':
import { Component, OnInit } from '@angular/core';
import { AuthService } from '../../services/auth.service';
import { Router } from '@angular/router';
import { FlashMessagesService } from 'angular2-flash-messages';
@Component({
selector: 'app-messages',
templateUrl: './messages.component.html',
styleUrls: ['./messages.component.css']
})
export class MessagesComponent implements OnInit {
createdBy: String;
recipients: String;
subject: String;
message: String;
previousMessage: String;
nextMessage: String;
user: Object;
constructor(private authService: AuthService,
private router: Router,
private flashMessage: FlashMessagesService
) { }
ngOnInit() {
this.authService.getProfile().subscribe(profile => {
this.user = profile.user;
this.createdBy = profile.user.username;
},
err => {
console.log(err);
return false;
});
}
// Need to create Message object and pass to Back End
newMessage(){
const newMessage = {
createdBy: this.createdBy,
recipients: this.recipients,
subject: this.subject,
message: this.message,
previousMessage: " ",
nextMessage: " "
}
this.authService.newMessage(this.user, newMessage).subscribe(data => {
if(data.success){
this.authService.storeUserData(data.token, data.user);
console.log(data);
this.router.navigate(['profile']);
}else{
console.log(data);
this.router.navigate(['dashboard']);
}
});
}
getMessages(){
this.authService.getMessages(this.user).subscribe(data => {
if(data.success){
this.authService.storeUserData(data.token, data.user);
this.router.navigate(['messages']);
console.log(data);
}else{
this.router.navigate(['dashboard']);
}
});
}
}
Angular auth service:
import { Injectable } from '@angular/core';
import { Http, Headers } from '@angular/http';
import 'rxjs/add/operator/map';
import { tokenNotExpired } from 'angular2-jwt';
@Injectable()
export class AuthService {
authToken: any;
user: any;
message: any;
constructor(private http: Http) { }
// Need to pass Message object to Front End
newMessage(user, message){
console.log(user.username + " " + message.createdBy);
let headers = new Headers();
this.loadToken();
headers.append('Authorization', this.authToken);
headers.append('Content-Type', 'application/json');
var info = {user, message};
return this.http.post('/users/newmessages', user, {headers: headers, body: info})
.map(res => res.json());
}
getMessages(user){
let headers = new Headers();
this.loadToken();
headers.append('Authorization', this.authToken);
headers.append('Content-Type', 'application/json');
return this.http.post('/users/messages', user, {headers: headers})
.map(res => res.json());
}
registerUser(user){
let headers = new Headers();
headers.append('Content-Type', 'application/json');
return this.http.post('/users/register', user, {headers: headers})
.map(res => res.json());
}
authenticateUser(user){
let headers = new Headers();
headers.append('Content-Type', 'application/json');
return this.http.post('/users/authenticate', user, {headers: headers})
.map(res => res.json());
}
changePassword(user){
let headers = new Headers();
this.loadToken();
headers.append('Authorization', this.authToken);
headers.append('Content-Type', 'application/json');
return this.http.post('/users/changepassword', user, {headers: headers})
.map(res => res.json());
}
getProfile(){
let headers = new Headers();
this.loadToken();
headers.append('Authorization', this.authToken);
headers.append('Content-Type', 'application/json');
return this.http.get('/users/profile', {headers: headers})
.map(res => res.json());
}
storeUserData(token, user){
localStorage.setItem('id_token', token);
localStorage.setItem('user', JSON.stringify(user));
this.authToken = token;
this.user = user;
}
loadToken(){
const token = localStorage.getItem('id_token');
this.authToken = token;
}
loggedIn(){
return tokenNotExpired('id_token');
}
logout(){
this.authToken = null;
this.user = null;
localStorage.clear();
}
}
Just in case, here's my partial user model from the Mongoose Schema:
var mongoose = require('mongoose');
var bcrypt = require('bcryptjs');
var config = require('../config/database');
// User Schema
var userSchema = mongoose.Schema({
name: {
type: String
},
email:{
type: String,
required: true
},
username: {
type: String,
required: true
},
password: {
type: String,
required: true
},
verify: {
type: Boolean,
required: true
}
});
via A. Angee
No comments:
Post a Comment