Firebase Transactional Email Address Change alert email not sending - firebase

I am using AngularFireStore and AngularFireAuth. I am able to create users via email and password. I am also able to verify a users email successfully. However, when I update a users email address there is no email sent to the user to alert them to the change. The email address update is successful though.
According to the docs I had the impression this process was automatic.
Text from image:
For security, when a user changes their email address, an email is sent to their original address so they can review the change.
The relevant code I have for updating an email address is below:
firebaseUser: Observable<firebase.User>;
updateUserEmail(newEmail: string) {
return this.firebaseUser.pipe(switchMap(user => from(user.updateEmail(newEmail))));
}
test() {
this.authService.updateUserEmail('example#example.com').subscribe(result => console.log(result));
}
Am I doing something wrong that is causing the Email Address Change transactional email not to be sent?

Related

Firebase resetting password without verifying the account

Is there a way for a user to reset his firebase password without actually verifying the account when resetting the password?
Initially when an account is created the "verified" in the userinfo is set to false, once the account is created we receive an email with the verify account url.
However, when the user "forgets his password", the password reset mail is send to the user and when he actually resets the password, the firebase userinfo "verified" is set to true.
E-Mail verification just confirms that the email belongs to that person by generally sending a link or so. Now if a user can access the link to reset password then they definitely own that email (unless someone else has access to their device).
If that's a strict requirement to not set emailVerified to true on verifying email then you'll have to implement your own logic using Firebase Admin SDK which would run on a Cloud function or custom server.

Firebase email/password authentication - how to require email verification?

Whenever I use the email/password authentication provider in Firebase, the provider sends a bearer token upon successful sign-up even though the emailVerified is false. Is there a way, out of the box, to configure the email/password auth provider to not send a bearer token (and return a 403 error) until the user has verified their email address?
Note that I'm aware of how to create a user, sign in a user, send a verification email, etc... using firebase v9.x via the methods createUserWithEmailAndPassword, signInWithEmailAndPassword, signOut, sendEmailVerification from firebase/auth. I'm just asking if there is a way to set the behavior of the provider without having to write my own handler function for this. I'd like this to behave like Cognito does whenever the email verification is required.
There is no way to require the user's email address to be verified before they can sign in to Firebase Authentication.
The closest you can get is by using email-link sign-in, which combines signing in and verifying the user's email address in one action.
But this is how you'll typically want to implement this in your application code:
User enters their credentials
You sign them in to Firebase with those credentials
You check whether their email address is verified
If not, you stop them from further using the app - and (optionally) send them a verification email.
Same with data access: if you have a custom backend code, you can check whether the email address is verified in the ID token there too, as well as in Firebase's server-side security rules.
As per the documentation, you can use blocking functions to require email verification for registration (only that it doesn't work):
exports.beforeCreate = functions.auth.user().beforeCreate((user, context) => {
const locale = context.locale;
if (user.email && !user.emailVerified) {
// Send custom email verification on sign-up.
return admin.auth().generateEmailVerificationLink(user.email).then((link) => {
return sendCustomVerificationEmail(user.email, link, locale);
});
}
});
exports.beforeSignIn = functions.auth.user().beforeSignIn((user, context) => {
if (user.email && !user.emailVerified) {
throw new functions.auth.HttpsError(
'invalid-argument', `"${user.email}" needs to be verified before access is granted.`);
}
});
generateEmailVerificationLink always returns the following error:
"err": {
"message": "There is no user record corresponding to the provided identifier.",
"code": "auth/user-not-found"
},
but the user is created anyway given that beforeCreate don't return an exception.
If you want to check by yourself just log the error:
return admin.auth().generateEmailVerificationLink(user.email)
.then((link) => {
functions.logger.info("link", {user: user, context: context, link: link})
})
.catch((err) => {
functions.logger.info("error", {user: user, context: context, err: err});
});
The createUserWithEmailAndPassword() will sign in user right after the account is created. Also there isn't any way to prevent users from logging in even if their email is not verified but you can actually check if email is verified in security rules or using Admin SDK to prevent users with unverified email from accessing your resources. You can use this rule in Firestore:
allow read, write: if request.auth.token.email_verified == true;
One workaround would be creating users using a Cloud function and Admin SDK which won't sign in users but do note that users can sign in.
If you want to prevent login unless the email is verified strictly, then you can disable account right after it is created. Now you may not be able to use sendEmailVerification() which requires user to be signed in at first place, you can always create your own solution for verifying email. The process might look something like:
Create a user and disable the account in a Cloud function
Generate some token or identifier for verifying email and send an email to user from same cloud function
Once the user visits that link and verifies the email you can enable it
Additionally, users can still create accounts by using REST API but you can disable sign ups so users can be created via Cloud function only which disables the user immediately.

Let user know when email verified

When the user wants to update the email, I'm using verifyBeforeUpdateEmail to verify before updating it.
await FirebaseAuth.instance.currentUser.verifyBeforeUpdateEmail(
email,
ActionCodeSettings(
androidInstallApp: true,
androidPackageName: 'com.example',
iOSBundleId: 'com.example',
handleCodeInApp: true,
url: 'https://example.page.link/emailVerify',
));
Can I let the user know if the email has been verified and updated? I've tried dynamic_links but it does not pick up the email verification.
The verifyBeforeUpdateEmail() method sends a verification email to a new email address. So the user needs to execute an action in order to verify the email (click on the link provided in the email). So normally the user will know he/she has verified the new email.
If you want to add an extra mechanism to "let the user know if the email has been verified and updated" you could adopt one of the following approaches:
#1 Implement a custom email action handler
As explained in the doc, "by default, user management emails link to the default action handler, which is a web page hosted at a URL in your project's Firebase Hosting domain. You can instead create and host a custom email action handler to do custom processing and to integrate the email action handler with your website".
This way, you could implement any business logic in parallel of the email verification, like sending a confirmation email or updating a flag, etc..
#2 Use a Cloud Function
There is no Authentication Cloud Functions trigger in response to the verification of an email, unfortunately. We can only trigger a Cloud Function upon the creation and deletion of Firebase user accounts. But you could implement a scheduled Cloud Function which checks if the email has been verified.

How to check if a given email is present in firebase auth?

I want to implement a reset password form. For that I need to check whether the text input email that user input in out text field is present in our firebase authentication database or not, so that if it is I can send Reset password mail or else show him a pop-dialog to rectify the email.
I've already applied the email checking part where I check wether the text is Email or not.
Firebase Auth can actually manage that for you. Simply call the sendPasswordResetEmail() method like this:
_auth.sendPasswordResetEmail(email: email)
.then((void v) => {
// password reset email sent successfully
})
.catchError((Error error) => {
// There was an error verifying the email
// Check the output of error.toString()
// This is where you may want to show a pop-up dialog
});
If the email is badly formatted or if the email is not present on the Auth Database, the code will always execute the catchError method.

API key limitations and email verification

I've recently found out that, if Evernote's user does not verify his email address, all requests to Evernote API is not working. But I didn't find any ways to request email verification in Evernote's web interface, looks like the proposal to verify email appears randomly ? Are there any ways to request email verification from the user ?
You can ask users to change their email address via the page on the web, which will send them a verification email and verify their address.

Resources