Parse AfterSave trigger going in a loop - javascript

I am having trouble with my aftersave handler. So when a new user logs in, it checks to see of both tProfile and sProfile fields are empty, if so it saves saves an acl for the user and then sends an email to the user using nodemailer nmp package. But after a user is saved the server keeps on sending email after email in a loop, there were about 64 emails sent after which google blocked out the login attemps, help would be very appreciated. My cloud code is given below
Parse.Cloud.afterSave(Parse.User, (request) => {
const user = request.object;
const t = user.get('tProfile');
const s = user.get('sProfile');
if (!t && !s) {
user.setACL(new Parse.ACL(user));
user.save(null,{ useMasterKey: true });
sendWelcomeEmail(user.getUsername(),user.get('type'));
return;
}else{
console.log("Condition Working");
return;
}
});
const sendWelcomeEmail = (userName,type) => {
var nodemailer = require('nodemailer');
var transporter = nodemailer.createTransport({
service: 'gmail',
auth: {
user: 'tanzim3421#gmail.com',
pass: 'oyhlyk****ocvhaa'
}
});
var mailOptions = {
from: 'tutorbeargroup#gmail.com',
to: userName,
subject: 'Welcome to TutorBear',
text: 'Dear '+type+', thankyou for signing up with us. If you have any questions please contact us at: 01726409161'
};
transporter.sendMail(mailOptions,(error, info)=>{
if (error) {
console.log(error);
} else {
console.log('Email sent: ' + info.response);
}
});
}

If you try to save same class object in afterSave it will be recursive function.
You can use beforeSave trigger
Parse.Cloud.beforeSave(Parse.User,async(req)=>{
let userObject = req.object;
if(userObject.isNew()){
//Your Logic
}
});

Related

Is it possible to retrieve user attributes from aws cognito in javascript on page load (Before login)?

I am using AWS cognito and successfully fulfilling all my requirements. However, there is a scenario is which I am struggling. I have an Auth code field along with username and password on login page and my requirement is to populate that auth code field before logging in.
I am successfully retrieving user attributes after login but in this case, I need to retrieve a user attribute before login to populate the input field.
My question is that is it possible to fetch a specific user attribute (Auth Code) before even login?
Below is the code for your reference that I am using to retrieve user attributes on clicking login button. Please have a look.
function signInButton() {
var authcode = document.getElementById("authcode").value;
var authenticationData = {
Username : document.getElementById("inputUsername").value,
Password : document.getElementById("inputPassword").value,
Authcode : document.getElementById("authcode").value,
};
var authenticationDetails = new AmazonCognitoIdentity.AuthenticationDetails(authenticationData);
var poolData = {
UserPoolId : _config.cognito.userPoolId, // Your user pool id here
ClientId : _config.cognito.clientId, // Your client id here
};
var userPool = new AmazonCognitoIdentity.CognitoUserPool(poolData);
var userData = {
Username : document.getElementById("inputUsername").value,
Pool : userPool,
};
var cognitoUser = new AmazonCognitoIdentity.CognitoUser(userData);
var userid = document.getElementById("inputUsername").value;
console.log('userid: ',userid)
if(authcode=='1234'){
cognitoUser.authenticateUser(authenticationDetails, {
onSuccess: function (result) {
var accessToken = result.getAccessToken().getJwtToken();
/////Getting User Attributes//////
AWS.config.update({region:'us-east-1'});
var params = {
AccessToken: accessToken
};
var cognitoidentityserviceprovider = new AWS.CognitoIdentityServiceProvider();
cognitoidentityserviceprovider.getUser(params, function(err, data) {
if (err) {
console.log(err, err.stack);
} // an error occurred
else{
console.log(data);
} // successful response
})
/////// End /////////
if(accessToken!=null || accessToken!=''){
$.post("testapi.php", {userid: userid}, function(result){
console.log('result: ',result);
if(result.includes("accept")){
window.open("landing.php?status=Logged In","_self");
}else{
alert('Unauthorized User ID. Please try again with correct ID!')
}
});
}
console.log(accessToken);
},
onFailure: function(err) {
alert(err.message || JSON.stringify(err));
window.open("landing.php?status=Not Logged In","_self");
},
});
}else{
alert('Incorrect Authentication Code. Please try again');
}
}
Please suggest a possible solution.
Thank you

RabbitMQ Node JS Validate User ID

I use RabbitMQ, SocketIO and MongoDB to make private messages for my app.
The plan is when new user register, app make new unique RabbitMQ Queue for that user, with that user is able to get messages when it is offline. So user send message through SocketIO and it is passed to RabbitMQ Publisher and then when consumer is online he get that message.
My questions now is how to set Validate User ID from sendToQueue (Publisher) function to be able later to read sender ID from consume function?
amqp.connect(CONN_URL, function(err, conn) {
conn.createChannel(function(err, channel) {
ch = channel;
console.log("RabbitMQ channel created...");
});
});
const publishToQueue = async (queueName, data) => {
ch.sendToQueue(queueName, Buffer.from(data.message));
};
const consumeToQueue = async queueName => {
ch.consume(
queueName,
function(msg) {
return msg.content.toString();
},
{ noAck: true }
);
};
I worked out...
const publishToQueue = async (queueName, data) => {
let properties = { headers: {userId: data.to }, timestamp: Date.now() };
ch.sendToQueue(queueName, Buffer.from(data.message), properties);
};
This will send headers with userId information and also timestamp of message

database is not updating despite the db.insert function

I'm making a forgot password functionality in my express app suing node mailer package which sends a new password to the email of the user and then updating the database with the new password but the problem is that the database is not updating with the new password i have reviewed my code many times but unable to figure out the problem.
`app.post('/forgot', (req, res) => {
const { email } = req.body;
let newPassword = generatePassword();
db.select('*').from('login')
.where('email', '=', email)
.returning('*')
.then(user => {
if (user.length > 0) {
let mailOptions = {
from: 'haroonrmit#gmail.com',
to: `${email}`,
subject: 'Password reset',
html: `<p>Your new password is ${newPassword}</p>`
};
transporter.sendMail(mailOptions);
db('login')
.where({email: user[0].email})
.update({
password: newPassword
})
res.json(user[0]);
} else {
res.status(404).json('email not found');
}
})
});`
You are not calling .then for the second query, so it is built but never ran.
Also your http returns a value before it knows if update was executed with success.

AWS Cognito forgotPassword returns request aborted

I'm build a React web client using AWS Cognito for user management. I'm using the amazon-cognito-identity-js library for this.
Login and sign up work fine.
Now, I'm unable to implement Use case 12: Starting and completing a forgot password flow for an unauthenticated user:
var cognitoUser = getCognitoUser({
Username : this.state.email //email from React component state
});
cognitoUser.forgotPassword({
onSuccess: function (result) {
console.log('call result: ' + result);
},
onFailure: function(err) {
console.log("failed", err);
alert(err);
},
inputVerificationCode() {
var verificationCode = prompt('Please input verification code ' ,'');
var newPassword = prompt('Enter new password ' ,'');
cognitoUser.confirmPassword(verificationCode, newPassword, this);
}
});
getCognitoUser
function getCognitoUser(userData) {
userData.Pool = getUserPool();
return new CognitoUser(userData);
}
getUserPool
function getUserPool() {
return new CognitoUserPool({
UserPoolId: config.cognito.USER_POOL_ID,
ClientId: config.cognito.APP_CLIENT_ID
});
}
The problem is that no matter what I type as an email, onFailure is called and I get a "RequestAbortedError: Request aborted" error.
Anybody knows what I'm doing wrong or how to get a better error message?
This actually works, I just forgot the event.preventDefault(); in the beginning of my click handler

Getting Correct Info in Console, But Angular 2 Login Not Working as Expected

I have a login in my Angular 2 app, and I have been converting it from using a fake backend (which works) to connect to our mongoDB-based API instead.
This is the login function I am using in the authentication service:
login(username: string, password: string) {
const u = encodeURIComponent(username);
const p = encodeURIComponent(password);
this._url = `https://api.somesite.com/v0/staff/login/${u}/${p}?apikey=somekey`;
console.log(this._url);
return this.http.post(this._url, JSON.stringify({ username: username, password: password }))
.map((response: Response) => {
// login successful if there's a jwt token in the response
const user = response.json();
if (user && user.token) {
// store user details and jwt token in local storage to keep user logged in between page refreshes
localStorage.setItem('currentUser', JSON.stringify(user));
}
});
}
In my login component I am subscribing like this:
login() {
this.loading = true;
this.authenticationService.login(this.model.username, this.model.password)
.subscribe(
data => {
this.router.navigate(['/']);
console.log('User logged in as: ' + this.model.username);
},
error => {
this.alertService.error(error);
this.loading = false;
});
this.authenticationService.username = this.model.username;
}
When I try this, and log to the console "this_url", I get what I would expect. For instance, if the user typed in "billsmith" for username, and "parisnow" for password, I see this in the console for "this_url":
https://api.somesite.com/v0/staff/login/billsmith/parisnow?apikey=somekey
Furthermore, I can type that url directly into the browser address window and see data (when the username and password correctly correspond to actual records in our database). So it's accessing the correct info in that sense.
But in the console I get a "404" error for that generated url. It also doesn't "do anything". In other words, it doesn't correctly redirect to the main component as it did with the fakeBackend-enabled login. And the only thing that's different now is the url that I am calling (because I'm connecting to our actual API now, as opposed to a fake backend provider).
FYI, the url when using the fake backend looked like this:
return this.http.post('/api/authenticate', JSON.stringify({ username: username, password: password}))
What am I missing here?
By the way, this is how things look on the server side re: our mongoDB:
exports.byLogin = function(req, res, next) {
let ioOnly = false, username, password;
if (_.isUndefined(req.params)){
ioOnly=true;
username = req.username;
password = req.password;
}
else {
username = req.params.username;
password = req.params.password;
}
staff.findOne({username: username, password: password}, function(err, doc) {
if (err) { if (!ioOnly) { return next(err) } else { return res(err)}}
else if(doc) ((!ioOnly) ? res.send(doc) : res(doc));
else ((!ioOnly) ? res.sendStatus(204) : res(doc));
});
};

Categories

Resources