How to use DirtyKeys to know if "email" field in PFUser has been modified? - parse-server

I'm using cloudcode of Parse-Server and mailgun to send email-verification Code to users that signup or change their email.
The BeforeSave Method :
Parse.Cloud.beforeSave(Parse.User, function(request, response) {
var verificationCode = Math.floor(Math.random()*999999);
var text = "Hi ... this is a verification code:" + verificationCode;
var data = {
from: 'WBP Team <info#test.eu>',
to: request.object.get("email"),
subject: 'Please verify your e-mail for you Account',
text: text
};
mailgun.messages().send(data, function (error, body) {
if (error) {
response.error("Email not sent..."+error);
}else{
var user = Parse.User.current();
user.set("emailVerificationCode", verificationCode);
user.save();
response.success("Email Sent");
}
console.log(body);
});
});
Now the email is sent everytime the user modify any filed. But I would like to use the method only when the user change the email.

This has been answered here: you just check if request.object.dirtyKeys() contains "email"; if this is the case, the email property was changed, and you can send your verification.
Note that this check also catches the first saving (i.e. creation) of a user; if you want to avoid sending a mail then, you can use request.object.isNew() to find out if the operation is a create or an update.

Related

appleAuthRequestResponse returning null for fullName and email

I am confused why me below snippet of code is showing null for email and fullName in console after user is authenticated successfully. I have read the documentation carefully and tried every possible thing I could. Any help would be highly appreciated.
async function onAppleButtonPress() {
// performs login request
const appleAuthRequestResponse = await appleAuth.performRequest({
requestedOperation: AppleAuthRequestOperation.LOGIN,
requestedScopes: [AppleAuthRequestScope.EMAIL, AppleAuthRequestScope.FULL_NAME],
});
//api getting current state of the user
const credentialState = await appleAuth.getCredentialStateForUser(appleAuthRequestResponse.user);
if (credentialState === AppleAuthCredentialState.AUTHORIZED) {
// user is authenticated
console.log("email is",appleAuthRequestResponse.email);
console.log("full name is",appleAuthRequestResponse.fullName);
}
}
You can still retrieve the e-mail from the identityToken provided by appleAuthrequestResponse with any jwt decoder like jwt-decode
const {identityToken, nonce, email} = appleAuthRequestResponse
const {email} = jwt_decode(identityToken)
console.log(email)
Apple only returns the full name and email on the first login, it will return null on the succeeding login so you need to save those data.
To receive these again, go to your device settings; Settings > Apple ID, iCloud, iTunes & App Store > Password & Security > Apps Using Your Apple ID, tap on your app and tap Stop Using Apple ID. You can now sign-in again and you'll receive the full name and `email.
Source here.

Updating existing mongodb data MERN

So I'm creating a webpage with users, and when the user first signs up for the site they are prompted to input a first name, last name, email, etc. In the user's profile page, I added a form to change the users name. I'm able to get all the info I need into the back end, but I'm not sure of the syntax to actually update the database with it.
This is my router.put function. It accepts two parameters, with first being the first name that the user wants to change it to, and email to look up the user in the database.
router.put("/updateFirst/:first/:email", function(req, res) {
console.log("------------update first hit------------");
db.User.getUserByEmail(req.params.email)
.then(res => {
console.log("updateFirst res: " + res);
})
})
Any help is appreciated.
EDIT: This is my getUserByEmail function
module.exports.getUserByEmail = function (email, callback) {
console.log("getUserByEmail", email)
var query = { email: email };
console.log(query);
return User.findOne(query, callback);
};

I don't receive the email of sender who submit the form with details (name,email,message)?

I am using nodemailer for sending email, but email of sender is not receiving by using req.body.email.
See
This is my code:
var mailOptions = {
from: req.body.email, // sender address
to: "btazeem#gmail.com", // list of receivers
subject: "New message from Code4Share visitor 📧💭", // Subject line
text: req.body.message // plaintext body
}
Did the UI pass the data variable name "email" ? Show the UI form code and console.log(req.body) output.
Your req.body.email may have same value as btazeem#gmail.com

How to login not with a username but a different selector?

I want to implement "Login with username or customerID (never both) and password" where I let the user enter a username or their customerID in the first field and password in the second field.
The accounts-password package lets me login using a username by calling
Meteor.loginWithPassword(<username>,<password>);
OR
var selector = {username: <username>}
Meteor.loginWithPassword(selector, <password>);
I tried to select the user using the selector.
var selector = {customerID: <customerID>}
But it seems that I can use only _id,username or email in this way to select a user or I get a Match failed error.
Isn't there any other method to log a user in without a username, _id or email?
This workaround is the farthest I have reached:
1. First retrieve the username or _id using customerID.
2. Then login using the retrieved username/_id and password.
//SERVER
Meteor.methods({
findIDFromCustomerID: function(customerID){
user = Meteor.users.findOne({customerID: customerID});
if(user){
return user._id;
}else{
throw new Meteor.Error(403,"User not found");
}
}
});
//CLIENT
Meteor.call('findIDFromCustomerID',<customerID>,function(err,data){
if(data && !err){
Meteor.loginWithPassword({id: data}, <password>);
}
});
But in this, I feel that I leave a small window for the misbehaving users.

Laravel route with variable in the url

I am trying to implement the password reset logic. The user gets the link to reset the password in the email. The url looks like
http://example.com/reset/resetcode
I have the route defined for it:
Route::get('reset/{resetcode}', function(){
return View::make('users.reset_password');
});
The form is rendered in the view to submit the email, new password etc. For the post of the form I have route defined as:
Route::post('reset/{resetcode}', array( 'as' => 'reset', 'uses' => 'UserController#passwordReset'));
I grab the resetcode from post route inside the passwordReset controller below
public function passwordReset($resetcode)
{
$validation = Validator::make(Input::all(), UserModel::$rulesPasswordReset);
if ($validation->passes())
{
try
{
// Find the user using the user email address
$user = Sentry::findUserByLogin(Input::get('email'));
// Check if the reset password code is valid
if ($user->checkResetPasswordCode($resetcode))
{
// Attempt to reset the user password
if ($user->attemptResetPassword($resetcode, 'new_password'))
{
// Password reset passed
}
else
{
// Password reset failed
}
}
else
{
// The provided password reset code is Invalid
}
}
catch (Cartalyst\Sentry\Users\UserNotFoundException $e)
{
echo 'User was not found.';
}
}
else return Redirect::route('reset')->withInput()
->withErrors($validation)
->with('title', 'resetrequestfailure')
->with('message', 'Seems like you made some errors.');
}
The problem I am having is when I do Redirect::route after the validation fails. I am getting the resetcode from the route defined for post. When validation fails, the redirect route messes up and I cannot get the resetcode the second time. The supposed url of format
http://example.com/reset/8f1Z7wA4uVt7VemBpGSfaoI9mcjdEwtK8elCnQOb
becomes
http://bcnet.org/reset/%7Bcode%7D
It has to do with /{resetcode} part of the route and this is variable, so how can I get the correct resetcode even after the validation fails meaning that the url remains intact. Or how can I fix it to the appropriate Redirect::route after the validation failure.
You need to include the $resetcode on your return
else return Redirect::route('reset', $resetcode)->withInput()
->withErrors($validation)