refactor: updated swagger;

feat: helper function in errors for checking postgres error types;
feat: sql query method for finding users by their email;
feat: registration begin/complete with checking existing username/email;
refactor: error handling in controller
This commit is contained in:
2025-07-03 04:33:25 +03:00
parent d08db300fc
commit 0a51727af8
12 changed files with 348 additions and 31 deletions

View File

@@ -24,6 +24,7 @@ import (
"easywish/internal/utils"
"easywish/internal/utils/enums"
"github.com/jackc/pgerrcode"
"github.com/jackc/pgx/v5"
"go.uber.org/zap"
)
@@ -55,11 +56,40 @@ func (a *authServiceImpl) RegistrationBegin(request models.RegistrationBeginRequ
var err error
if user, err = db.TXQueries.CreateUser(db.CTX, request.Username); err != nil {
if errs.IsPgErr(err, pgerrcode.UniqueViolation) {
a.log.Warn(
"Attempted registration for a taken username",
zap.String("username", request.Username),
zap.Error(err))
return false, errs.ErrUsernameTaken
}
a.log.Error("Failed to add user to database", zap.Error(err))
return false, errs.ErrServerError
}
a.log.Info("Registraion of a new user", zap.String("username", user.Username), zap.Int64("id", user.ID))
if _, err := db.TXQueries.GetUserByEmail(db.CTX, *request.Email); err == nil {
a.log.Warn(
"Attempted registration for a taken email",
zap.String("email", *request.Email))
return false, errs.ErrEmailTaken
} else if !errs.IsPgErr(err, pgerrcode.NoData) {
a.log.Error(
"Failed to check if email is not taken",
zap.String("email", *request.Email),
zap.Error(err))
return false, errs.ErrServerError
} else {
a.log.Debug("Verified that email is not taken", zap.String("email", *request.Email))
}
a.log.Info(
"Registraion of a new user",
zap.String("username", user.Username),
zap.Int64("id", user.ID))
if _, err = db.TXQueries.CreateLoginInformation(db.CTX, database.CreateLoginInformationParams{
UserID: user.ID,
@@ -109,11 +139,19 @@ func (a *authServiceImpl) RegistrationComplete(request models.RegistrationComple
user, err = db.TXQueries.GetUserByUsername(db.CTX, request.Username)
if err != nil {
if errs.IsPgErr(err, pgerrcode.NoData) {
a.log.Warn(
"Could not find user attempting to complete registration with given username",
zap.String("username", request.Username),
zap.Error(err))
return nil, errs.ErrUserNotFound
}
a.log.Error(
"Failed to find user attempting to complete registration",
zap.String("username", request.Username),
"Failed to get user",
zap.String("username", request.Username),
zap.Error(err))
return nil, errs.ErrUserNotFound
return nil, errs.ErrServerError
}
confirmationCode, err = db.TXQueries.GetConfirmationCodeByCode(db.CTX, database.GetConfirmationCodeByCodeParams{
@@ -123,11 +161,20 @@ func (a *authServiceImpl) RegistrationComplete(request models.RegistrationComple
})
if err != nil {
a.log.Warn(
"User supplied wrong confirmation code for completing registration",
zap.String("username", user.Username),
if errs.IsPgErr(err, pgerrcode.NoData) {
a.log.Warn(
"User supplied unexistent confirmation code for completing registration",
zap.String("username", user.Username),
zap.String("code", request.VerificationCode),
zap.Error(err))
return nil, errs.ErrForbidden
}
a.log.Error(
"Failed to acquire specified registration code",
zap.String("username", user.Username),
zap.Error(err))
return nil, errs.ErrForbidden
return nil, errs.ErrServerError
}
err = db.TXQueries.UpdateConfirmationCode(db.CTX, database.UpdateConfirmationCodeParams{
@@ -140,8 +187,7 @@ func (a *authServiceImpl) RegistrationComplete(request models.RegistrationComple
"Failed to update the user's registration code used state",
zap.String("username", user.Username),
zap.Int64("confirmation_code_id", confirmationCode.ID),
zap.Error(err),
)
zap.Error(err))
return nil, errs.ErrServerError
}
@@ -179,6 +225,7 @@ func (a *authServiceImpl) RegistrationComplete(request models.RegistrationComple
return nil, errs.ErrServerError
}
// TODO: session info
session, err = db.TXQueries.CreateSession(db.CTX, database.CreateSessionParams{
UserID: user.ID,
Name: utils.NewPointer("First device"),
@@ -206,6 +253,10 @@ func (a *authServiceImpl) RegistrationComplete(request models.RegistrationComple
helper.Commit()
a.log.Info(
"User verified registration",
zap.String("username", request.Username))
response := models.RegistrationCompleteResponse{Tokens: models.Tokens{
AccessToken: accessToken,
RefreshToken: refreshToken,