Json at position error - node.js

I am using passport.js for my backend (node.js) app to signin up the user. I am getting always following error:
ERROR SyntaxError: Unexpected token < in JSON at position 0
at Object.parse ()
at Response.webpackJsonp.../../../http/#angular/http.es5.js.Body.json
(http.es5.js:797)
at MapSubscriber.project (signup.component.ts:31)
After refresh the site I am signed-up. What is wrong with my code?
Here is my angular function:
signUp() {
this.userNotExist = "";
this.userExist="";
this.http.post('/signup',this.signform.value).map((res: any) => res.json())
.subscribe((res: any) => {
console.log('TTTTTTTTT')
console.log(res)
console.log('TTTTTTTTT')
if(res=='EXIST'){
this.userNotExist = "";
this.userExist = 'The email already exists';
}else {
this.userExist = "";
this.userNotExist = 'Congrats! You are now signed up';
window.location.reload();
}
}
),(error: any) => {
console.log(error);
}
}
My Node.js app:
passport.use('local-signup', new LocalStrategy({
// by default, local strategy uses username and password, we will override with email
usernameField : 'email',
passwordField : 'password',
nameMainField : 'nameMain',
firstNameField: 'firstName',
passReqToCallback : true // allows us to pass back the entire request to the callback
},
function(req, email, password, done) {
// find a user whose email is the same as the forms email
// we are checking to see if the user trying to login already exists
User.findOne({ 'local.email' : email }).lean().exec( function(err, user) {
// if there are any errors, return the error
if (err)
return done(err);
// check to see if theres already a user with that email
if (user) {
return done(null, false, req.flash('signupMessage', 'Email already exists.'));
} else {
var newUserS = new User();
// set the user's local credentials
newUserS.local.email = email;
newUserS.local.password = newUserS.generateHash(password); // use the generateHash function in our user model
newUserS.local.nameMain = req.body.firstName + ' ' + req.body.nameMain;
newUserS.local.firstName = req.body.firstName;
newUserS.role=0;
newUserS.profileImage='/assets/fonts/male.png';
// save the user
newUserS.save(function(err, u) {
if (err)
throw err;
return done(null, newUserS);
});
}
});
}));

You are getting xml response instead of JSON response. I am pretty sure it is something like this:
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE paymentService PUBLIC "-//WorldPay//DTD WorldPay PaymentService v1//EN"
"http://dtd.WorldPay.com/paymentService_v1.dtd">
<paymentService version="1.4" merchantCode="ExampleCode1"> <!--The merchantCode you supplied originally-->
<reply>
<orderStatus orderCode="ExampleOrder1"> <!--Not present for parse or security violation errors-->
<error code="2">
<![CDATA[Invalid address: Postal code is missing or empty.]]>
</error>
</orderStatus>
</reply>
</paymentService>
The exception comes from the first char at the xml response.

Related

FETCH request doesn't work unless I refresh my page

I have a React-Ionic web app doing some queries to a custom NodeJS server. I can read users but I cant create one unless I refresh my page. All of my GET and POST queries are working properly after I refresh my page.
Here is my function to create a User. Every log are showing except 'USR SUCESSFULLY LAUNCH...'
export async function createUser(p_user: StudentSkeletonDB) {
//Normalize name guid familyname and comments
//Removing all specials characters
console.log("USR STARTING TO CREATE :")
let newUser: StudentSkeletonDB = p_user;
newUser.firstname = newUser.firstname.replace(/[~`!##$%^&*()+={}\[\];:\'\"<>.,\/\\]/g, '');
newUser.guid_id = newUser.guid_id.replace(/[~`!##$%^&*()+={}\[\];:\'\"<>.,\/\\]/g, '');
newUser.familyname = newUser?.familyname != undefined ? newUser.familyname.replace(/[~`!##$%^&*()+={}\[\];:\'\"<>.,\/\\]/g, '') : "";
newUser.comments = newUser?.comments != undefined ? newUser.comments.replace(/[~`!##$%^&*()+={}\[\];:\'\"<>.,\/\\]/g, '') : "";
console.log("USR NORMALIZED :")
console.log(newUser)
var myHeaders = new Headers();
myHeaders.append('Content-Type', 'application/json');
myHeaders.append('Content-Lenght', '' + JSON.stringify(newUser).length);
var data = new FormData();
data.append("json", JSON.stringify(newUser));
console.log("USR SENDING... :")
return await fetch("http://127.0.0.1:8083/signup", {
headers: myHeaders,
method: 'POST',
body: JSON.stringify(newUser)
}).then((s) => {
console.log("USR SUCCESSFULLY LAUNCH... :")
return s;
});
}
On my NodeJS Server, even the first log is not showing.
exports.postSignup = async(req, res, next) => {
//getting user data from request body
console.log("STARTING TO CREATE USER")
const { guid_id, firstname, familyname, _password, birthday, usertype, class_id, login, filenumber, avatar, language, isactive, ef_sessionpid, comments, connected, created, simu_password, gender, driving_school_code, nb_connection } = req.body;
try {
const user = new User({
guid_id,
firstname,
familyname,
_password,
birthday,
usertype,
class_id,
login,
filenumber,
avatar,
language,
isactive,
ef_sessionpid,
comments,
connected,
created,
simu_password,
gender,
driving_school_code,
nb_connection
});
const result = await user.createUser();
result.send(user);
} catch (error) {
const errorToThrow = new Error();
switch (error.code) {
case '23505':
errorToThrow.message = 'User already exists';
errorToThrow.statusCode = 403;
break;
default:
errorToThrow.statusCode = 500;
}
//pass error to next()
next(errorToThrow);
}
};
I repeat it, but if I refresh any page of my web app, then create a User, everything works properly and al my logs (even NodeJS) are showing. My newUser object is fine even without refreshing, it look like fetch itself doesnt work.
I tried to change fetch url to something totally wrong like return await fetch("http://127.0.0.1:8083/dzedzededze/dzedze)" and it doesn't even raise an error.
FIXED IT !
The previous request on my NodeJS server was crashing something.
All POST requests were in a queue.
There was multiples error in my code like Content-Lenght. I'm not very good in english : 'ght' and 'gth' are a big weakness of mine.
data was not used either.

What is the proper way to update a particular column in nestjs

I want to save token generated into the user's confirmed email column. The token is part of the confirmation link that will be sent to the user so that when the user clicks on the link I can check if it matches, then updates it to "activated".
Now the problem is I can't figure out how to save it in the ConfirmEmailLink method .
async register(createDTO: CreateUserDto) {
const { email } = createDTO;
const user = await this.userModel.findOne({ email })
if (user) {
throw new HttpException('User already exists', HttpStatus.BAD_REQUEST);
}
const createdUser = new this.userModel(createDTO);
var newUser = await createdUser.save();
await SendEmail(createDTO.email, await **this.ConfirmEmailLink(createdUser._id)**, createDTO.email);
return this.sanitizeUser(createdUser);
//return null;
}
In the above code there is ConfirmEmailLink that is a parameter to SendEmail method
async ConfirmEmailLink(userId: string) {
const id = v4();
var payload = { userId: userId };
var secret = process.env.JWT_SIMPLE_TOKEN;
var token = jwt.encode(payload, secret);
console.log("This is uuid", userId);
var link = `${process.env.HOST}/user/confirm/${token}/${id}`;
let user = await this.userModel.findById(userId);
if (!user) {
throw new HttpException("Registration not complete, try again or contact admin", HttpStatus.NOT_FOUND);
}
**//This is where the problem is, I want to save the token in ConfirmEmail column**
await this.userModel.updateOne({confirmEmail: token});
return link;
}
I will appreciate your suggestions or if there is a better way to do this
Thanks
updateOne needs 2 parameters, a filter to identify which document to modify, and a update indicating what to do.
.updateOnde({"_id":userId},{"$set":{"confirmEmail": token}})

How can axios-mock-adapter return an object on GET request?

There's a block of code that uses axios-mock-adapter and returns an object via a GET request:
mock.onGet('/api/auth').reply((config) => {
const data = JSON.parse(config.data);
const {email, password} = data;
const user = _.cloneDeep(authDB.users.find(_user => _user.data.email === email));
const error = {
email : user ? null : 'Check your username/email',
password: user && user.password === password ? null : 'Check your password'
};
if ( !error.email && !error.password && !error.displayName )
{
delete user['password'];
const access_token = jwt.sign({id: user.uuid}, jwtConfig.secret, {expiresIn: jwtConfig.expiresIn});
const response = {
"user" : user,
"access_token": access_token
};
return [200, response];
}
else
{
return [200, {error}];
}
});
User is a JSON object with various amounts of values. How is this possible? What would it look like in the URL? I'm studying the code block to learn how to do it without axios-mock-adapter.

Password reset is not working in loopback 3.0

I've been trying to implement the reset password functionality in my project which uses nodejs and loopback version 3.0 . Loopback provides in built method for this reset password functionality in the user.js.
When I run the project and and test the reset password it runs without giving any errors but the email is not received.
This is the inbuilt method given by loopback for password reset functionality.
User.resetPassword = function(options, cb) {
// console.log("options : "+options);
// console.log("cb : "+cb);
cb = cb || utils.createPromiseCallback();
var UserModel = this;
var ttl = UserModel.settings.resetPasswordTokenTTL || DEFAULT_RESET_PW_TTL;
options = options || {};
if (typeof options.email !== 'string') {
var err = new Error(g.f('Email is required'));
err.statusCode = 400;
err.code = 'EMAIL_REQUIRED';
cb(err);
return cb.promise;
}
try {
if (options.password) {
UserModel.validatePassword(options.password);
}
} catch (err) {
return cb(err);
}
var where = {
email: options.email,
};
if (options.realm) {
where.realm = options.realm;
}
UserModel.findOne({where: where}, function(err, user) {
if (err) {
return cb(err);
}
if (!user) {
err = new Error(g.f('Email not found'));
err.statusCode = 404;
err.code = 'EMAIL_NOT_FOUND';
return cb(err);
}
// create a short lived access token for temp login to change password
// TODO(ritch) - eventually this should only allow password change
if (UserModel.settings.emailVerificationRequired && !user.emailVerified) {
err = new Error(g.f('Email has not been verified'));
err.statusCode = 401;
err.code = 'RESET_FAILED_EMAIL_NOT_VERIFIED';
return cb(err);
}
if (UserModel.settings.restrictResetPasswordTokenScope) {
const tokenData = {
ttl: ttl,
scopes: ['reset-password'],
};
user.createAccessToken(tokenData, options, onTokenCreated);
} else {
// We need to preserve backwards-compatibility with
// user-supplied implementations of "createAccessToken"
// that may not support "options" argument (we have such
// examples in our test suite).
user.createAccessToken(ttl, onTokenCreated);
}
function onTokenCreated(err, accessToken) {
if (err) {
return cb(err);
}
cb();
UserModel.emit('resetPasswordRequest', {
email: options.email,
accessToken: accessToken,
user: user,
options: options,
}
);
}
});
return cb.promise;
};
When i enter the email from loopback api for password reset it gives no errors in the console but the email is not working.
The method resetPassword is called during the process.Console log inside the method is printed as shown below.
{ email: '**********#gmail.com',
authorizedRoles: { '$everyone': true } }
[Function: callback]
The thing which confuses me is that the verify email method is working
which is also comes inbuilt in the user.js .The following is printed in the console when the verification email is sent.
mx resolved: [ { exchange: 'alt1.gmail-smtp-in.l.google.com', priority: 10 },
{ exchange: 'alt2.gmail-smtp-in.l.google.com', priority: 20 },
{ exchange: 'gmail-smtp-in.l.google.com', priority: 5 },
{ exchange: 'alt4.gmail-smtp-in.l.google.com', priority: 40 },
{ exchange: 'alt3.gmail-smtp-in.l.google.com', priority: 30 } ]
MX connection created: alt1.gmail-smtp-in.l.google.com
recv gmail.com>220 mx.google.com ESMTP 1si9238203plw.390 - gsmtp
send gmail.com>EHLO gmail.com
recv gmail.com>250-mx.google.com at your service, [112.135.5.40]
recv gmail.com>250-SIZE 157286400
recv gmail.com>250-8BITMIME
recv gmail.com>250-STARTTLS
recv gmail.com>250-ENHANCEDSTATUSCODES
recv gmail.com>250-PIPELINING
recv gmail.com>250 SMTPUTF8
send gmail.com>MAIL FROM:<hasikasadaruwan.mgtuk#gmail.com>
recv gmail.com>452 (IP, Sender) first encounter.
It would be a great help if anyone help me to solve this problem, I've been stuck here for days.
THANKS in advance.
You must handle resetPasswordRequest endpoint in your extended model like this.
MyUser.on("resetPasswordRequest", function(info) {
console.log(info.email); // the email of the requested user
console.log(info.accessToken.id); // the temp access token to allow password reset
var url = "http://**********";
var html =
'Click <a href="' +
url +
"?access_token=" +
info.accessToken.id +
'">here</a> to reset your password.</br><h2>Link will be expired in 15 minutes.';
//'here' in above html is linked to : 'http://<host:port>/reset-password?access_token=<short-lived/temporary access token>'
MyUser.app.models.Email.send(
{
to: info.email,
from: senderAddress,
subject: "Password reset",
html: html
},
function(err) {
if (err) return console.log("> error sending password reset email");
console.log("> sending password reset email to:", info.email);
}
); });
Provide URL of your form. On that form submit use reset-password endpoint.
Checkout this reference: loopback-example-user-management
This worked for me. Thank you!

Update Contact Details using Azure AD Graph & Node

I am using Node.js and azure-graph to create a user in Azure. It works as expected for basic fields like Name, etc. However, jobTitle and other fields that are usually found in the portal cannot be updated. Any pointers?
let msRest = require('ms-rest-azure');
let azureGraph = require('azure-graph');
let tenantId = common.configDefaults.azure_tenant;
let clientId = common.configDefaults.azure_client_id;
let clientPwd = common.configDefaults.azure_client_secret;
let create_user_in_azure_ad = function (user, cb) {
msRest.loginWithServicePrincipalSecret(clientId, clientPwd, tenantId, {
tokenAudience: 'graph'
}, function (err, credentials, subscriptions) {
if (err) {
done(err.message, null);
} else {
// Create Azure Graph Client to access
let client = new azureGraph(credentials, tenantId);
let password = common.generatePassword(10);
let userParams = {
accountEnabled: true,
userPrincipalName: user.email_official, //please add your domain over here
displayName: user.display_name,
mailNickname: user.email_official.split("#")[0],
jobTitle: "A FANCY TITLE",
passwordProfile: {
password: password,
forceChangePasswordNextLogin: true
},
};
// Now, we can create the User in Active Directory
client.users.create(userParams, function (err, done) {
if (err) {
cb(err, null);
} else {
// The user is created now with a password. Return this information
cb(null, {user: user, password: password});
}
});
}
});
};
Though I'm not aware of Node.js, but I think you can create/update jobTitle by updating contact of a specific user.

Resources