From f37b25a1c7efbf9741996bff19c6535b39affdb2 Mon Sep 17 00:00:00 2001 From: Neeraj Gupta <254676+ua741@users.noreply.github.com> Date: Thu, 21 Nov 2024 17:26:32 +0530 Subject: [PATCH] [server]Throw err if account registration is completed --- server/ente/errors.go | 6 ++++ server/ente/user.go | 1 + server/pkg/controller/user/userauth.go | 48 ++++++++++++++++++++++---- 3 files changed, 49 insertions(+), 6 deletions(-) diff --git a/server/ente/errors.go b/server/ente/errors.go index c4bbc1db87..e29b2768bb 100644 --- a/server/ente/errors.go +++ b/server/ente/errors.go @@ -111,6 +111,12 @@ var ErrSubscriptionAlreadyClaimed = ApiError{ Message: "Subscription is already associted with different account", } +var ErrUserAlreadyRegistered = &ApiError{ + Code: "USER_ALREADY_REGISTERED", + HttpStatusCode: http.StatusConflict, + Message: "User is already registered", +} + var ErrCollectionNotEmpty = ApiError{ Code: CollectionNotEmpty, HttpStatusCode: http.StatusConflict, diff --git a/server/ente/user.go b/server/ente/user.go index cd8e7e3ebe..77858c4d93 100644 --- a/server/ente/user.go +++ b/server/ente/user.go @@ -8,6 +8,7 @@ const ( EmailChangedSubject = "Email address updated" ChangeEmailOTTPurpose = "change" + SignUpOTTPurpose = "signup" ) // User represents a user in the system diff --git a/server/pkg/controller/user/userauth.go b/server/pkg/controller/user/userauth.go index f57d95869b..90bf6088d1 100644 --- a/server/pkg/controller/user/userauth.go +++ b/server/pkg/controller/user/userauth.go @@ -81,15 +81,18 @@ func hardcodedOTTForEmail(hardCodedOTT HardCodedOTT, email string) string { // SendEmailOTT generates and sends an OTT to the provided email address func (c *UserController) SendEmailOTT(context *gin.Context, email string, purpose string) error { if purpose == ente.ChangeEmailOTTPurpose { - _, err := c.UserRepo.GetUserIDWithEmail(email) - if err == nil { - // email already owned by a user - return stacktrace.Propagate(ente.ErrPermissionDenied, "") + if err := c.isEmailAlreadyUsed(email); err != nil { + return err } - if !errors.Is(err, sql.ErrNoRows) { - // unknown error, rethrow + } + if purpose == ente.SignUpOTTPurpose { + isComplete, err := c.isSignedUpComplete(email) + if err != nil { return stacktrace.Propagate(err, "") } + if isComplete { + return stacktrace.Propagate(ente.ErrUserAlreadyRegistered, "user has already completed sign up process") + } } ott, err := random.GenerateSixDigitOtp() if err != nil { @@ -134,6 +137,39 @@ func (c *UserController) SendEmailOTT(context *gin.Context, email string, purpos return nil } +func (c *UserController) isEmailAlreadyUsed(email string) error { + _, err := c.UserRepo.GetUserIDWithEmail(email) + if err == nil { + // email already owned by a user + return stacktrace.Propagate(ente.ErrPermissionDenied, "email already belongs to a user") + } + if !errors.Is(err, sql.ErrNoRows) { + // unknown error, rethrow + return stacktrace.Propagate(err, "") + } + return nil +} + +// isSignedUpComplete checks if the user has completed the entire sign up process. +// Sign up is considered complete if the user has verified their email address and their key attributes are set. +func (c *UserController) isSignedUpComplete(email string) (bool, error) { + userID, err := c.UserRepo.GetUserIDWithEmail(email) + if err != nil && errors.Is(err, sql.ErrNoRows) { + return false, nil + } + if err != nil { + return false, stacktrace.Propagate(err, "") + } + _, keyErr := c.UserRepo.GetKeyAttributes(userID) + if keyErr != nil && errors.Is(keyErr, sql.ErrNoRows) { + return false, nil + } + if keyErr != nil { + return false, stacktrace.Propagate(keyErr, "") + } + return true, nil +} + func (c *UserController) AddAdminOtt(req ente.AdminOttReq) error { emailHash, err := crypto.GetHash(req.Email, c.HashingKey) if err != nil {