I'm setting up a custom authentication system in my meteor app.
When a user signs up, they are sent an email verification link. If they click on this, it changes the verification boolean to true as expected.
I have a button in the users account setting page that allows them to resend a verification email if needed. Clicking on this works ok and they receive another email with a different link.
When this new link is clicked, it redirects to the home page but it doesn't verify the email address.
My guess is that the users account isn't aware of the new token.
//server code
Meteor.methods({
'sendVerificationEmail' : function(userId, primaryEmail){
var userId = Meteor.user();
Accounts.sendVerificationEmail(userId, primaryEmail, function (error) {
if (! error) {
return alert('Verfication email sent');
} else {
return alert(error);
};
});
}
});
//Client code
Accounts.onEmailVerificationLink(function (token, done) {
Accounts.verifyEmail(token, function (error) {
if (! error) {
console.log('Account verified');
alert('Account verified');
}
done();
// show something if there was an error.
});
});
// Email verification route
Router.route('/verify-email/:token', {
name: 'verifyEmail'
});
Related
I am using Angular 9 and firebase. When a user signs up they get a verification email and the when they click it they are taken to a verification screen saying it has been verified. But they are getting an error when they do to login saying email is not verified. The page has to be reloaded for it to work.
onSignup(form: NgForm) {
this.submitted = true;
if (form.valid) {
this.authService.RegisterUser(this.signup.username, this.signup.password)
.then((res) => {
// Do something here
this.authService.SendVerificationMail();
this.router.navigateByUrl('/email-verification');
}).catch((error) => {
window.alert(error.message)
})
}
}
Here is the send verification mail from the auth service.
SendVerificationMail() {
this.ngFireAuth.onAuthStateChanged(function(user) {
user.sendEmailVerification();
});
}
Why is this happening and what should I do?
I am doing an email update for the user, but first I need to know if the email has been previously registered in firebase authentication.
In this way I updated the email:
if(administrador.correo != vm.editedItem.correo){
console.log("ESTA ACTUALIZANDO CORREO");
console.log(vm.editedItem);
firebase.auth().signInWithEmailAndPassword(vm.editedItem.correo, vm.editedItem.contrasenia)
.then(function(userCredential) {
console.log("USER CREDENTIAL");
console.log(userCredential);
userCredential.user.updateEmail(vm.editedItem.correo)
.then(function() {
console.log("email update");
// Update successful.
}).catch(function(error) {
console.log("ERROR");
console.log(error);
// An error happened.
});
})
}
But before I can update the email I have to validate if it already exists, if the email exists, since it is not allowed to update mail and if the email does not exist, therefore I update the email.
Beforehand thank you very much.
Check below code. I think you are trying to change same email using which you are logged in. I made some minor changes and comments.
if (administrador.correo != vm.editedItem.correo) {
console.log("ESTA ACTUALIZANDO CORREO");
console.log(vm.editedItem);
firebase.auth().signInWithEmailAndPassword(vm.currentItem.correo, vm.editedItem.contrasenia) // sign in with current email and password
.then(function (userCredential) {
console.log("USER CREDENTIAL");
console.log(userCredential);
userCredential.user.updateEmail(vm.editedItem.correo) // update new email
.then(function () {
console.log("email update");
// Update successful.
}).catch(function (error) {
console.log("ERROR");
console.log(error);
// An error happened.
// if updated user email already exists, it returns error code: auth/email-already-in-use
});
})
}
follow this link for more updateEmail
If error occurred then check Error Code auth/email-already-in-use.
https://firebase.google.com/docs/reference/js/firebase.auth.Auth
Or, Use admin.auth().getUserByEmail(). Build to Cloud Functions and call a function from your app.
https://firebase.google.com/docs/reference/admin/node/admin.auth.Auth#getUserByEmail
https://firebase.google.com/docs/functions/callable
I have clicked "Reset Password" in Cognito and now when I login I get "PasswordResetRequiredException", how should I handle this? I cant find anything in the docs that tell me what should I do?
check this http://docs.aws.amazon.com/cognito/latest/developerguide/cognito-user-pools-using-import-tool-password-reset.html
you need to call ForgotPassword()...
I figured out the exact way that you can handle this on (onFailure) callback:
// Create a cognito user instance
const cognitoUser = new AmazonCognitoIdentity.CognitoUser(userData);
// Trigger to authenticate the user
cognitoUser.authenticateUser(authenticationDetails, {
onFailure: function(err) {
if (err.code == "PasswordResetRequiredException") {
// Confirm user data
cognitoUser.confirmPassword(
"", // Put your verification code here
"", // Here is your new password
{
onSuccess: result => {
// Everything worked as expected
},
onFailure: err => {
// Trigger failure
}
}
);
} else {
// Trigger failure
}
}
});
I think that the specific user should have had an email or sms sent to them (if their email or phone number had been verified). In this email there should be a code which you can use with ConfirmForgotPassword
You would have to implement the newPasswordRequired callback for authenticateUser such as below:
cognitoUser.authenticateUser(authenticationDetails, {
onSuccess: function (result) {
// User authentication was successful
},
onFailure: function(err) {
// User authentication was not successful
},
mfaRequired: function(codeDeliveryDetails) {
// MFA is required to complete user authentication.
// Get the code from user and call
cognitoUser.sendMFACode(mfaCode, this)
},
newPasswordRequired: function(userAttributes, requiredAttributes) {
// User was signed up by an admin and must provide new
// password and required attributes, if any, to complete
// authentication.
// the api doesn't accept this field back
delete userAttributes.email_verified;
// Get these details and call
cognitoUser.completeNewPasswordChallenge(newPassword, userAttributes, this);
}
});
If I change the verify-email so it wouldn't have the # in it , My user is not getting verified , once they landed on the page i want them to , and keeps asking for email verification .shown in code below
this is how i change the verify email link
Accounts.urls.verifyEmail = function(token){
return Meteor.absoluteUrl("verify-email/" + token);
};
and here is my router ( I am using FlowRouter not iron-router )
FlowRouter.route('/verify-email/:token',{
name: 'verifyEmail',
action: function(){
BlazeLayout.render('MainLayout', {content: 'VerifyEmail'});
}
});
and here is how I verify the user
Template.VerifyEmail.created = function() {
if (Accounts._verifyEmailToken) {
Accounts.verifyEmail(Accounts._verifyEmailToken, function(err) {
if (err != null) {
if (err.message = 'Verify email link expired [403]') {
console.log('Sorry this verification link has expired.')
}
} else {
console.log('You account is active now !')
}
});
}
};
If I do not change the sent verify link and let the original verification token sent , once its clicked it goes to the home page of and i need to change the Template.VerifyEmail.created = function() to
Template.Home.created = function() it works which is not what i want
thanks
First a little background:
I am working on an seperate mobile application that is connected with the main app. The connection is succesfully initiated and I can retrieve all collections, through subscriptions:
Remote = DDP.connect('http://localhost:3000/');
Meteor.users = new Meteor.Collection('users', {
connection: Remote
});
Remote.subscribe('users', true);
Now I want to make sure users can log in through the interface of the second app. After installing the accounts-password and the meteor-ddp-login package, I should be able to authenticate with the main app by using the next piece of code in the client side.
var Remote = DDP.connect('http://localhost:3000/');
DDP.loginWithPassword(Remote, {
username: username
}, password, function(error) {
if (!error) {
console.log(username + " is logged in!");
} else {
console.log(error);
}
});
Well, so far so good. No errors appear and the console logs a success message. Now the question comes:
How can I retrieve the user object of the user who just logged in.
I've set up several publish functions in the main app, but the user data does not become available to the client in the second app (other collections work fine, but Meteor.user() is undefined).
And also: How can I authenticate users who login with Facebook/Google/Twitter
Came across this, I had a similar need recently. Following code works in Meteor version 1.2.0.2
if (Meteor.isClient) {
Meteor.startup(function(){
//Seems that without this, on page refresh, it doesn't work.
//COMMENT: Ideally this should not be needed if the core takes care of this use case of a different connection for Accounts
//hack block 1***********
var token = Accounts._storedLoginToken();
if(token) {
Meteor.loginWithToken(token, function(err){
// this is going to throw error if we logged out
if(err)
console.log(err);
else
console.log('loginWithToken');
});//loginWithToken
}
//hack block 1***********
});//startup function
var connection = DDP.connect("http://localhost:3060");
Accounts.connection= connection;
//COMMENT: Ideally this should not be needed if the core takes care of this use case of a different connection for Accounts
//hack block 2***********
Accounts.users = new Meteor.Collection('users', {
connection: connection
});
//hack block 2***********
Tracker.autorun(function () {
//No code which directly affects the functionality. Just for testing
console.log(Meteor.user());
Accounts.connection.call('user',function(err,result){
if(err)
console.log(err);
if(result){
console.log(result);
if(result._id === Meteor.user()._id){
console.log("Server and client shows that the same user has logged in");
} else {console.log("Server and client shows different users");}
}
})
});
Template.register.events({
'submit #register-form' : function(e, t) {
e.preventDefault();
var email = t.find('#account-email').value
, password = t.find('#account-password').value;
Accounts.createUser({email:email,password:password}, function(err,result){
if (err) {
// Inform the user that account creation failed
console.log(err);
} else {
// Success. Account has been created and the user
// has logged in successfully.
console.log("registered user");
console.log('response is '+ result);
console.log(Meteor.user());
}
});//createUser
return false;
}
});//register
Template.login.events({
'submit #login-form': function(e,t){
e.preventDefault();
var email = t.find('#login-email').value
, password = t.find('#login-password').value;
Meteor.loginWithPassword(email, password, function(err){
if (err)
console.log(err);
else
// The user has been logged in.
console.log('logged in successfully');
});
return false;
}
});//login
Template.statusloggedin.events({
'click #logout': function(e,t){
e.preventDefault();
Meteor.logout();
return false;
}
});//logout
}