Repository: firebase/firebase-admin-go
Pull request #436 (2021-05-03 20:59:10)

fix(auth): adds missing EMAIL_NOT_FOUND error code
Catch EMAIL_NOT_FOUND when /accounts:sendOobCode is called for password reset on a user that does not exist.

google-cla[bot]: We found a Contributor License Agreement for you (the sender of this pull request), but were unable to find agreements for all the commit author(s) or Co-authors.  If you authored these, maybe you used a different email address in the git commits than was used to sign the CLA ([login here](https://cla.developers.google.com/) to double check)?  If these were authored by someone else, then they will need to sign a CLA as well, and confirm that they're okay with these being contributed to Google.
In order to pass this check, please resolve this problem and then comment `@googlebot I fixed it.`. If the bot doesn't comment, it means it doesn't think anything has changed.

ℹ️ **Googlers: [Go here](https://goto.google.com/prinfo/https%3A%2F%2Fgithub.com%2Ffirebase%2Ffirebase-admin-go%2Fpull%2F436) for more info**.

<!-- need_author_cla -->
google-cla[bot]: We found a Contributor License Agreement for you (the sender of this pull request), but were unable to find agreements for all the commit author(s) or Co-authors.  If you authored these, maybe you used a different email address in the git commits than was used to sign the CLA ([login here](https://cla.developers.google.com/) to double check)?  If these were authored by someone else, then they will need to sign a CLA as well, and confirm that they're okay with these being contributed to Google.
In order to pass this check, please resolve this problem and then comment `@googlebot I fixed it.`. If the bot doesn't comment, it means it doesn't think anything has changed.

ℹ️ **Googlers: [Go here](https://goto.google.com/prinfo/https%3A%2F%2Fgithub.com%2Ffirebase%2Ffirebase-admin-go%2Fpull%2F436) for more info**.

<!-- need_author_cla -->
bojeil-google: > Looks good. Please change the target branch to `dev`. And lets also add a test case.

Done

Patch:
diff --git a/auth/user_mgt.go b/auth/user_mgt.go
index d5e7521..333416e 100644
--- a/auth/user_mgt.go
+++ b/auth/user_mgt.go
@@ -450,6 +450,7 @@ const (
 	// Backend-generated error codes
 	configurationNotFound    = "CONFIGURATION_NOT_FOUND"
 	emailAlreadyExists       = "EMAIL_ALREADY_EXISTS"
+	emailNotFound            = "EMAIL_NOT_FOUND"
 	invalidDynamicLinkDomain = "INVALID_DYNAMIC_LINK_DOMAIN"
 	phoneNumberAlreadyExists = "PHONE_NUMBER_ALREADY_EXISTS"
 	tenantNotFound           = "TENANT_NOT_FOUND"
@@ -468,6 +469,11 @@ func IsEmailAlreadyExists(err error) bool {
 	return hasAuthErrorCode(err, emailAlreadyExists)
 }
 
+// IsEmailNotFound checks if the given error was due to the user record corresponding to the email not being found.
+func IsEmailNotFound(err error) bool {
+	return hasAuthErrorCode(err, emailNotFound)
+}
+
 // IsInsufficientPermission checks if the given error was due to insufficient permissions.
 //
 // Deprecated. Always returns false.
@@ -1298,6 +1304,11 @@ var serverError = map[string]*authError{
 		message:  "user with the provided email already exists",
 		authCode: emailAlreadyExists,
 	},
+	"EMAIL_NOT_FOUND": {
+		code:     internal.NotFound,
+		message:  "no user record found for the given email",
+		authCode: emailNotFound,
+	},
 	"INVALID_DYNAMIC_LINK_DOMAIN": {
 		code:     internal.InvalidArgument,
 		message:  "the provided dynamic link domain is not configured or authorized for the current project",


Test patch:
diff --git a/auth/email_action_links_test.go b/auth/email_action_links_test.go
index 5db51d6..876f330 100644
--- a/auth/email_action_links_test.go
+++ b/auth/email_action_links_test.go
@@ -21,6 +21,8 @@ import (
 	"net/http"
 	"reflect"
 	"testing"
+
+	"firebase.google.com/go/v4/errorutils"
 )
 
 const (
@@ -177,6 +179,27 @@ func TestPasswordResetLinkWithSettings(t *testing.T) {
 	}
 }
 
+func TestPasswordResetLinkWithSettingsNonExistingUser(t *testing.T) {
+	resp := `{
+		"error": {
+			"message": "EMAIL_NOT_FOUND"
+		}
+	}`
+	s := echoServer([]byte(resp), t)
+	defer s.Close()
+	s.Status = http.StatusBadRequest
+
+	link, err := s.Client.PasswordResetLinkWithSettings(context.Background(), testEmail, testActionCodeSettings)
+	if link != "" || err == nil {
+		t.Errorf("PasswordResetLinkWithSettings() = (%q, %v); want = (%q, error)", link, err, "")
+	}
+
+	want := "no user record found for the given email"
+	if err.Error() != want || !IsEmailNotFound(err) || !errorutils.IsNotFound(err) {
+		t.Errorf("PasswordResetLinkWithSettings() error = %v; want = %q", err, want)
+	}
+}
+
 func TestEmailSignInLink(t *testing.T) {
 	s := echoServer(testActionLinkResponse, t)
 	defer s.Close()