1
0
mirror of https://github.com/volatiletech/authboss.git synced 2025-09-16 09:06:20 +02:00

Use custom struct as localization key

This commit is contained in:
Stephen Afam-Osemene
2023-12-29 23:20:30 +00:00
parent 3abb766478
commit 6d4f345ef7
5 changed files with 224 additions and 86 deletions

View File

@@ -104,16 +104,16 @@ func (a *Authboss) VerifyPassword(user AuthableUser, password string) error {
// Localizef is a helper to translate a key using the translator
// If the localizer is nil or returns an empty string,
// then the original text will be returned using [fmt.Sprintf] to interpolate the args.
func (a *Authboss) Localizef(ctx context.Context, text string, args ...any) string {
func (a *Authboss) Localizef(ctx context.Context, key LocalizationKey, args ...any) string {
if a.Config.Core.Localizer == nil {
return fmt.Sprintf(text, args...)
return fmt.Sprintf(key.Default, args...)
}
if translated := a.Config.Core.Localizer.Localizef(ctx, text, args...); translated != "" {
if translated := a.Config.Core.Localizer.Localizef(ctx, key, args...); translated != "" {
return translated
}
return fmt.Sprintf(text, args...)
return fmt.Sprintf(key.Default, args...)
}
// VerifyPassword uses authboss mechanisms to check that a password is correct.

View File

@@ -7,55 +7,193 @@ import (
type Localizer interface {
// Get the translation for the given text in the given context.
// If no translation is found, an empty string should be returned.
Localizef(ctx context.Context, txt string, args ...any) string
Localizef(ctx context.Context, key LocalizationKey, args ...any) string
}
// Translation constants
const (
TxtSuccess = "success"
type LocalizationKey struct {
ID string
Default string
}
var (
TxtSuccess = LocalizationKey{
ID: "Success",
Default: "success",
}
// Used in the auth module
TxtInvalidCredentials = "Invalid Credentials"
TxtAuthFailed = "Please login"
TxtInvalidCredentials = LocalizationKey{
ID: "InvalidCredentials",
Default: "Invalid Credentials",
}
TxtAuthFailed = LocalizationKey{
ID: "AuthFailed",
Default: "Please login",
}
// Used in the register module
TxtUserAlreadyExists = "User already exists"
TxtRegisteredAndLoggedIn = "Account successfully created, you are now logged in"
TxtUserAlreadyExists = LocalizationKey{
ID: "UserAlreadyExists",
Default: "User already exists",
}
TxtRegisteredAndLoggedIn = LocalizationKey{
ID: "RegisteredAndLoggedIn",
Default: "Account successfully created, you are now logged in",
}
// Used in the confirm module
TxtConfirmYourAccount = "Please verify your account, an e-mail has been sent to you."
TxtAccountNotConfirmed = "Your account has not been confirmed, please check your e-mail."
TxtInvalidConfirmToken = "Your confirmation token is invalid."
TxtConfrimationSuccess = "You have successfully confirmed your account."
TxtConfirmEmailSubject = "Confirm New Account"
TxtConfirmYourAccount = LocalizationKey{
ID: "ConfirmYourAccount",
Default: "Please verify your account, an e-mail has been sent to you.",
}
TxtAccountNotConfirmed = LocalizationKey{
ID: "AccountNotConfirmed",
Default: "Your account has not been confirmed, please check your e-mail.",
}
TxtInvalidConfirmToken = LocalizationKey{
ID: "InvalidConfirmToken",
Default: "Your confirmation token is invalid.",
}
TxtConfrimationSuccess = LocalizationKey{
ID: "ConfrimationSuccess",
Default: "You have successfully confirmed your account.",
}
TxtConfirmEmailSubject = LocalizationKey{
ID: "ConfirmEmailSubject",
Default: "Confirm New Account",
}
// Used in the lock module
TxtLocked = "Your account has been locked, please contact the administrator."
TxtLocked = LocalizationKey{
ID: "Locked",
Default: "Your account has been locked, please contact the administrator.",
}
// Used in the logout module
TxtLoggedOut = "You have been logged out"
TxtLoggedOut = LocalizationKey{
ID: "LoggedOut",
Default: "You have been logged out",
}
// Used in the oauth2 module
TxtOAuth2LoginOK = "Logged in successfully with %s."
TxtOAuth2LoginNotOK = "%s login cancelled or failed"
TxtOAuth2LoginOK = LocalizationKey{
ID: "OAuth2LoginOK",
Default: "Logged in successfully with %s.",
}
TxtOAuth2LoginNotOK = LocalizationKey{
ID: "OAuth2LoginNotOK",
Default: "%s login cancelled or failed",
}
// Used in the recover module
TxtRecoverInitiateSuccessFlash = "An email has been sent to you with further instructions on how to reset your password."
TxtPasswordResetEmailSubject = "Password Reset"
TxtRecoverSuccessMsg = "Successfully updated password"
TxtRecoverAndLoginSuccessMsg = "Successfully updated password and logged in"
TxtRecoverInitiateSuccessFlash = LocalizationKey{
ID: "RecoverInitiateSuccessFlash",
Default: "An email has been sent to you with further instructions on how to reset your password.",
}
TxtPasswordResetEmailSubject = LocalizationKey{
ID: "PasswordResetEmailSubject",
Default: "Password Reset",
}
TxtRecoverSuccessMsg = LocalizationKey{
ID: "RecoverSuccessMsg",
Default: "Successfully updated password",
}
TxtRecoverAndLoginSuccessMsg = LocalizationKey{
ID: "RecoverAndLoginSuccessMsg",
Default: "Successfully updated password and logged in",
}
// Used in the otp module
TxtTooManyOTPs = "You cannot have more than %d one time passwords"
TxtTooManyOTPs = LocalizationKey{
ID: "TooManyOTPs",
Default: "You cannot have more than %d one time passwords",
}
// Used in the 2fa module
TxtEmailVerifyTriggered = "An e-mail has been sent to confirm 2FA activation"
TxtEmailVerifySubject = "Add 2FA to Account"
TxtInvalid2FAVerificationToken = "Invalid 2FA email verification token"
Txt2FAAuthorizationRequired = "You must first authorize adding 2fa by e-mail"
TxtInvalid2FACode = "2FA code was invalid"
TxtRepeated2FACode = "2FA code was previously used"
TxtTOTP2FANotActive = "TOTP 2FA is not active"
TxtSMSNumberRequired = "You must provide a phone number"
TxtSMSWaitToResend = "Please wait a few moments before resending the SMS code"
TxtEmailVerifyTriggered = LocalizationKey{
ID: "EmailVerifyTriggered",
Default: "An e-mail has been sent to confirm 2FA activation",
}
TxtEmailVerifySubject = LocalizationKey{
ID: "EmailVerifySubject",
Default: "Add 2FA to Account",
}
TxtInvalid2FAVerificationToken = LocalizationKey{
ID: "Invalid2FAVerificationToken",
Default: "Invalid 2FA email verification token",
}
Txt2FAAuthorizationRequired = LocalizationKey{
ID: "2FAAuthorizationRequired",
Default: "You must first authorize adding 2fa by e-mail",
}
TxtInvalid2FACode = LocalizationKey{
ID: "Invalid2FACode",
Default: "2FA code was invalid",
}
TxtRepeated2FACode = LocalizationKey{
ID: "Repeated2FACode",
Default: "2FA code was previously used",
}
TxtTOTP2FANotActive = LocalizationKey{
ID: "TOTP2FANotActive",
Default: "TOTP 2FA is not active",
}
TxtSMSNumberRequired = LocalizationKey{
ID: "SMSNumberRequired",
Default: "You must provide a phone number",
}
TxtSMSWaitToResend = LocalizationKey{
ID: "SMSWaitToResend",
Default: "Please wait a few moments before resending the SMS code",
}
)
// // Translation constants
// const (
// TxtSuccess = "success"
//
// // Used in the auth module
// TxtInvalidCredentials = "Invalid Credentials"
// TxtAuthFailed = "Please login"
//
// // Used in the register module
// TxtUserAlreadyExists = "User already exists"
// TxtRegisteredAndLoggedIn = "Account successfully created, you are now logged in"
//
// // Used in the confirm module
// TxtConfirmYourAccount = "Please verify your account, an e-mail has been sent to you."
// TxtAccountNotConfirmed = "Your account has not been confirmed, please check your e-mail."
// TxtInvalidConfirmToken = "Your confirmation token is invalid."
// TxtConfrimationSuccess = "You have successfully confirmed your account."
// TxtConfirmEmailSubject = "Confirm New Account"
//
// // Used in the lock module
// TxtLocked = "Your account has been locked, please contact the administrator."
//
// // Used in the logout module
// TxtLoggedOut = "You have been logged out"
//
// // Used in the oauth2 module
// TxtOAuth2LoginOK = "Logged in successfully with %s."
// TxtOAuth2LoginNotOK = "%s login cancelled or failed"
//
// // Used in the recover module
// TxtRecoverInitiateSuccessFlash = "An email has been sent to you with further instructions on how to reset your password."
// TxtPasswordResetEmailSubject = "Password Reset"
// TxtRecoverSuccessMsg = "Successfully updated password"
// TxtRecoverAndLoginSuccessMsg = "Successfully updated password and logged in"
//
// // Used in the otp module
// TxtTooManyOTPs = "You cannot have more than %d one time passwords"
//
// // Used in the 2fa module
// TxtEmailVerifyTriggered = "An e-mail has been sent to confirm 2FA activation"
// TxtEmailVerifySubject = "Add 2FA to Account"
// TxtInvalid2FAVerificationToken = "Invalid 2FA email verification token"
// Txt2FAAuthorizationRequired = "You must first authorize adding 2fa by e-mail"
// TxtInvalid2FACode = "2FA code was invalid"
// TxtRepeated2FACode = "2FA code was previously used"
// TxtTOTP2FANotActive = "TOTP 2FA is not active"
// TxtSMSNumberRequired = "You must provide a phone number"
// TxtSMSWaitToResend = "Please wait a few moments before resending the SMS code"
// )

View File

@@ -22,18 +22,18 @@ func (l *Logout) Init(ab *authboss.Authboss) error {
l.Authboss = ab
var logoutRouteMethod func(string, http.Handler)
switch l.Authboss.Config.Modules.LogoutMethod {
switch l.Config.Modules.LogoutMethod {
case "GET":
logoutRouteMethod = l.Authboss.Config.Core.Router.Get
logoutRouteMethod = l.Config.Core.Router.Get
case "POST":
logoutRouteMethod = l.Authboss.Config.Core.Router.Post
logoutRouteMethod = l.Config.Core.Router.Post
case "DELETE":
logoutRouteMethod = l.Authboss.Config.Core.Router.Delete
logoutRouteMethod = l.Config.Core.Router.Delete
default:
return errors.Errorf("logout wants to register a logout route but was given an invalid method: %s", l.Authboss.Config.Modules.LogoutMethod)
return errors.Errorf("logout wants to register a logout route but was given an invalid method: %s", l.Config.Modules.LogoutMethod)
}
logoutRouteMethod("/logout", l.Authboss.Core.ErrorHandler.Wrap(l.Logout))
logoutRouteMethod("/logout", l.Core.ErrorHandler.Wrap(l.Logout))
return nil
}
@@ -61,7 +61,7 @@ func (l *Logout) Logout(w http.ResponseWriter, r *http.Request) error {
authboss.DelKnownSession(w)
authboss.DelKnownCookie(w)
handled, err = l.Authboss.Events.FireAfter(authboss.EventLogout, w, r)
handled, err = l.Events.FireAfter(authboss.EventLogout, w, r)
if err != nil {
return err
} else if handled {
@@ -70,8 +70,8 @@ func (l *Logout) Logout(w http.ResponseWriter, r *http.Request) error {
ro := authboss.RedirectOptions{
Code: http.StatusTemporaryRedirect,
RedirectPath: l.Authboss.Paths.LogoutOK,
Success: authboss.TxtLoggedOut,
RedirectPath: l.Paths.LogoutOK,
Success: l.Localizef(r.Context(), authboss.TxtLoggedOut),
}
return l.Authboss.Core.Redirector.Redirect(w, r, ro)
return l.Core.Redirector.Redirect(w, r, ro)
}

View File

@@ -47,25 +47,25 @@ type Recover struct {
func (r *Recover) Init(ab *authboss.Authboss) (err error) {
r.Authboss = ab
if err := r.Authboss.Config.Core.ViewRenderer.Load(PageRecoverStart, PageRecoverEnd); err != nil {
if err := r.Config.Core.ViewRenderer.Load(PageRecoverStart, PageRecoverEnd); err != nil {
return err
}
if err := r.Authboss.Config.Core.MailRenderer.Load(EmailRecoverHTML, EmailRecoverTxt); err != nil {
if err := r.Config.Core.MailRenderer.Load(EmailRecoverHTML, EmailRecoverTxt); err != nil {
return err
}
r.Authboss.Config.Core.Router.Get("/recover", r.Core.ErrorHandler.Wrap(r.StartGet))
r.Authboss.Config.Core.Router.Post("/recover", r.Core.ErrorHandler.Wrap(r.StartPost))
r.Authboss.Config.Core.Router.Get("/recover/end", r.Core.ErrorHandler.Wrap(r.EndGet))
r.Authboss.Config.Core.Router.Post("/recover/end", r.Core.ErrorHandler.Wrap(r.EndPost))
r.Config.Core.Router.Get("/recover", r.Core.ErrorHandler.Wrap(r.StartGet))
r.Config.Core.Router.Post("/recover", r.Core.ErrorHandler.Wrap(r.StartPost))
r.Config.Core.Router.Get("/recover/end", r.Core.ErrorHandler.Wrap(r.EndGet))
r.Config.Core.Router.Post("/recover/end", r.Core.ErrorHandler.Wrap(r.EndPost))
return nil
}
// StartGet starts the recover procedure by rendering a form for the user.
func (r *Recover) StartGet(w http.ResponseWriter, req *http.Request) error {
return r.Authboss.Config.Core.Responder.Respond(w, req, http.StatusOK, PageRecoverStart, nil)
return r.Config.Core.Responder.Respond(w, req, http.StatusOK, PageRecoverStart, nil)
}
// StartPost starts the recover procedure using values provided from the user
@@ -73,7 +73,7 @@ func (r *Recover) StartGet(w http.ResponseWriter, req *http.Request) error {
func (r *Recover) StartPost(w http.ResponseWriter, req *http.Request) error {
logger := r.RequestLogger(req)
validatable, err := r.Authboss.Core.BodyReader.Read(PageRecoverStart, req)
validatable, err := r.Core.BodyReader.Read(PageRecoverStart, req)
if err != nil {
return err
}
@@ -81,33 +81,33 @@ func (r *Recover) StartPost(w http.ResponseWriter, req *http.Request) error {
if errs := validatable.Validate(); errs != nil {
logger.Info("recover validation failed")
data := authboss.HTMLData{authboss.DataValidation: authboss.ErrorMap(errs)}
return r.Authboss.Core.Responder.Respond(w, req, http.StatusOK, PageRecoverStart, data)
return r.Core.Responder.Respond(w, req, http.StatusOK, PageRecoverStart, data)
}
recoverVals := authboss.MustHaveRecoverStartValues(validatable)
user, err := r.Authboss.Storage.Server.Load(req.Context(), recoverVals.GetPID())
user, err := r.Storage.Server.Load(req.Context(), recoverVals.GetPID())
if err == authboss.ErrUserNotFound {
logger.Infof("user %s was attempted to be recovered, user does not exist, faking successful response", recoverVals.GetPID())
ro := authboss.RedirectOptions{
Code: http.StatusTemporaryRedirect,
RedirectPath: r.Authboss.Config.Paths.RecoverOK,
Success: authboss.TxtRecoverInitiateSuccessFlash,
RedirectPath: r.Config.Paths.RecoverOK,
Success: r.Localizef(req.Context(), authboss.TxtRecoverInitiateSuccessFlash),
}
return r.Authboss.Core.Redirector.Redirect(w, req, ro)
return r.Core.Redirector.Redirect(w, req, ro)
}
ru := authboss.MustBeRecoverable(user)
req = req.WithContext(context.WithValue(req.Context(), authboss.CTXKeyUser, user))
handled, err := r.Authboss.Events.FireBefore(authboss.EventRecoverStart, w, req)
handled, err := r.Events.FireBefore(authboss.EventRecoverStart, w, req)
if err != nil {
return err
} else if handled {
return nil
}
selector, verifier, token, err := r.Authboss.Config.Core.OneTimeTokenGenerator.GenerateToken()
selector, verifier, token, err := r.Config.Core.OneTimeTokenGenerator.GenerateToken()
if err != nil {
return err
}
@@ -118,7 +118,7 @@ func (r *Recover) StartPost(w http.ResponseWriter, req *http.Request) error {
ru.PutRecoverVerifier(verifier)
ru.PutRecoverExpiry(time.Now().UTC().Add(r.Config.Modules.RecoverTokenDuration))
if err := r.Authboss.Storage.Server.Save(req.Context(), ru); err != nil {
if err := r.Storage.Server.Save(req.Context(), ru); err != nil {
return err
}
@@ -128,13 +128,13 @@ func (r *Recover) StartPost(w http.ResponseWriter, req *http.Request) error {
recoveryEmailRecipients = append(recoveryEmailRecipients, ruWithSecondaries.GetSecondaryEmails()...)
}
if r.Authboss.Modules.MailNoGoroutine {
if r.Modules.MailNoGoroutine {
r.SendRecoverEmail(req.Context(), recoveryEmailRecipients, token)
} else {
go r.SendRecoverEmail(req.Context(), recoveryEmailRecipients, token)
}
_, err = r.Authboss.Events.FireAfter(authboss.EventRecoverStart, w, req)
_, err = r.Events.FireAfter(authboss.EventRecoverStart, w, req)
if err != nil {
return err
}
@@ -142,24 +142,24 @@ func (r *Recover) StartPost(w http.ResponseWriter, req *http.Request) error {
logger.Infof("user %s password recovery initiated", ru.GetPID())
ro := authboss.RedirectOptions{
Code: http.StatusTemporaryRedirect,
RedirectPath: r.Authboss.Config.Paths.RecoverOK,
Success: authboss.TxtRecoverInitiateSuccessFlash,
RedirectPath: r.Config.Paths.RecoverOK,
Success: r.Localizef(req.Context(), authboss.TxtRecoverInitiateSuccessFlash),
}
return r.Authboss.Core.Redirector.Redirect(w, req, ro)
return r.Core.Redirector.Redirect(w, req, ro)
}
// SendRecoverEmail to a specific e-mail address passing along the encodedToken
// in an escaped URL to the templates.
func (r *Recover) SendRecoverEmail(ctx context.Context, to []string, encodedToken string) {
logger := r.Authboss.Logger(ctx)
logger := r.Logger(ctx)
mailURL := r.mailURL(encodedToken)
email := authboss.Email{
To: to,
From: r.Authboss.Config.Mail.From,
FromName: r.Authboss.Config.Mail.FromName,
Subject: r.Authboss.Config.Mail.SubjectPrefix + r.Localizef(ctx, authboss.TxtPasswordResetEmailSubject),
From: r.Config.Mail.From,
FromName: r.Config.Mail.FromName,
Subject: r.Config.Mail.SubjectPrefix + r.Localizef(ctx, authboss.TxtPasswordResetEmailSubject),
}
ro := authboss.EmailResponseOptions{
@@ -171,7 +171,7 @@ func (r *Recover) SendRecoverEmail(ctx context.Context, to []string, encodedToke
}
logger.Infof("sending recover e-mail to: %s", to)
if err := r.Authboss.Email(ctx, email, ro); err != nil {
if err := r.Email(ctx, email, ro); err != nil {
logger.Errorf("failed to recover send e-mail to %s: %+v", to, err)
}
}
@@ -179,7 +179,7 @@ func (r *Recover) SendRecoverEmail(ctx context.Context, to []string, encodedToke
// EndGet shows a password recovery form, and it should have the token that
// the user brought in the query parameters in it on submission.
func (r *Recover) EndGet(w http.ResponseWriter, req *http.Request) error {
validatable, err := r.Authboss.Core.BodyReader.Read(PageRecoverMiddle, req)
validatable, err := r.Core.BodyReader.Read(PageRecoverMiddle, req)
if err != nil {
return err
}
@@ -191,14 +191,14 @@ func (r *Recover) EndGet(w http.ResponseWriter, req *http.Request) error {
DataRecoverToken: token,
}
return r.Authboss.Config.Core.Responder.Respond(w, req, http.StatusOK, PageRecoverEnd, data)
return r.Config.Core.Responder.Respond(w, req, http.StatusOK, PageRecoverEnd, data)
}
// EndPost retrieves the token
func (r *Recover) EndPost(w http.ResponseWriter, req *http.Request) error {
logger := r.RequestLogger(req)
validatable, err := r.Authboss.Core.BodyReader.Read(PageRecoverEnd, req)
validatable, err := r.Core.BodyReader.Read(PageRecoverEnd, req)
if err != nil {
return err
}
@@ -222,7 +222,7 @@ func (r *Recover) EndPost(w http.ResponseWriter, req *http.Request) error {
return r.invalidToken(PageRecoverEnd, w, req)
}
credsGenerator := r.Authboss.Core.OneTimeTokenGenerator
credsGenerator := r.Core.OneTimeTokenGenerator
if len(rawToken) != credsGenerator.TokenSize() {
logger.Infof("invalid recover token submitted, size was wrong: %d", len(rawToken))
@@ -232,7 +232,7 @@ func (r *Recover) EndPost(w http.ResponseWriter, req *http.Request) error {
selectorBytes, verifierBytes := credsGenerator.ParseToken(string(rawToken))
selector := base64.StdEncoding.EncodeToString(selectorBytes[:])
storer := authboss.EnsureCanRecover(r.Authboss.Config.Storage.Server)
storer := authboss.EnsureCanRecover(r.Config.Storage.Server)
user, err := storer.LoadByRecoverSelector(req.Context(), selector)
if err == authboss.ErrUserNotFound {
logger.Info("invalid recover token submitted, user not found")
@@ -259,14 +259,14 @@ func (r *Recover) EndPost(w http.ResponseWriter, req *http.Request) error {
}
req = req.WithContext(context.WithValue(req.Context(), authboss.CTXKeyUser, user))
handled, err := r.Authboss.Events.FireBefore(authboss.EventRecoverEnd, w, req)
handled, err := r.Events.FireBefore(authboss.EventRecoverEnd, w, req)
if err != nil {
return err
} else if handled {
return nil
}
pass, err := r.Authboss.Config.Core.Hasher.GenerateHash(password)
pass, err := r.Config.Core.Hasher.GenerateHash(password)
if err != nil {
return err
}
@@ -280,13 +280,13 @@ func (r *Recover) EndPost(w http.ResponseWriter, req *http.Request) error {
return err
}
_, err = r.Authboss.Events.FireAfter(authboss.EventRecoverEnd, w, req)
_, err = r.Events.FireAfter(authboss.EventRecoverEnd, w, req)
if err != nil {
return err
}
successMsg := r.Localizef(req.Context(), authboss.TxtRecoverSuccessMsg)
if r.Authboss.Config.Modules.RecoverLoginAfterRecovery {
if r.Config.Modules.RecoverLoginAfterRecovery {
handled, err = r.Events.FireBefore(authboss.EventAuth, w, req)
if err != nil {
return err
@@ -304,7 +304,7 @@ func (r *Recover) EndPost(w http.ResponseWriter, req *http.Request) error {
authboss.PutSession(w, authboss.SessionKey, user.GetPID())
successMsg = r.Localizef(req.Context(), authboss.TxtRecoverAndLoginSuccessMsg)
handled, err = r.Authboss.Events.FireAfter(authboss.EventAuth, w, req)
handled, err = r.Events.FireAfter(authboss.EventAuth, w, req)
if err != nil {
return err
} else if handled {
@@ -314,16 +314,16 @@ func (r *Recover) EndPost(w http.ResponseWriter, req *http.Request) error {
ro := authboss.RedirectOptions{
Code: http.StatusTemporaryRedirect,
RedirectPath: r.Authboss.Config.Paths.RecoverOK,
RedirectPath: r.Config.Paths.RecoverOK,
Success: successMsg,
}
return r.Authboss.Config.Core.Redirector.Redirect(w, req, ro)
return r.Config.Core.Redirector.Redirect(w, req, ro)
}
func (r *Recover) invalidToken(page string, w http.ResponseWriter, req *http.Request) error {
errorsAll := []error{errors.New("recovery token is invalid")}
data := authboss.HTMLData{authboss.DataValidation: authboss.ErrorMap(errorsAll)}
return r.Authboss.Core.Responder.Respond(w, req, http.StatusOK, PageRecoverEnd, data)
return r.Core.Responder.Respond(w, req, http.StatusOK, PageRecoverEnd, data)
}
func (r *Recover) mailURL(token string) string {

View File

@@ -107,7 +107,7 @@ func (r *Register) Post(w http.ResponseWriter, req *http.Request) error {
switch {
case err == authboss.ErrUserFound:
logger.Infof("user %s attempted to re-register", pid)
errs = []error{errors.New(authboss.TxtUserAlreadyExists)}
errs = []error{errors.New(r.Localizef(req.Context(), authboss.TxtUserAlreadyExists))}
data := authboss.HTMLData{
authboss.DataValidation: authboss.ErrorMap(errs),
}
@@ -134,7 +134,7 @@ func (r *Register) Post(w http.ResponseWriter, req *http.Request) error {
logger.Infof("registered and logged in user %s", pid)
ro := authboss.RedirectOptions{
Code: http.StatusTemporaryRedirect,
Success: authboss.TxtRegisteredAndLoggedIn,
Success: r.Localizef(req.Context(), authboss.TxtRegisteredAndLoggedIn),
RedirectPath: r.Config.Paths.RegisterOK,
}
return r.Config.Core.Redirector.Redirect(w, req, ro)