package handlers import ( "fmt" "strings" "github.com/authelia/authelia/v4/internal/authentication" "github.com/authelia/authelia/v4/internal/middlewares" "github.com/authelia/authelia/v4/internal/templates" ) const ( eventLogKeyAction = "Action" eventLogKeyCategory = "Category" eventLogKeyDescription = "Description" eventEmailAction2FABody = "Second Factor Method" eventLogAction2FAAdded = "Second Factor Method Added" eventLogAction2FARemoved = "Second Factor Method Removed" eventEmailAction2FAPrefix = "a" eventEmailAction2FAAddedSuffix = "was added to your account." eventEmailAction2FARemovedSuffix = "was removed from your account." eventEmailActionPasswordModifyPrefix = "your" eventEmailActionPasswordReset = "Password Reset" eventEmailActionPasswordChange = "Password Change" eventEmailActionPasswordModifySuffix = "was successful." eventLogCategoryOneTimePassword = "One-Time Password" eventLogCategoryWebAuthnCredential = "WebAuthn Credential" //nolint:gosec ) type emailEventBody struct { Prefix string Body string Suffix string } func ctxLogEvent(ctx *middlewares.AutheliaCtx, username, description string, body emailEventBody, eventDetails map[string]any) { var ( details *authentication.UserDetails err error ) ctx.Logger.Debugf("Getting user details for notification") // Send Notification. if details, err = ctx.Providers.UserProvider.GetDetails(username); err != nil { ctx.Logger.WithError(err).Errorf("Error occurred looking up user details for user '%s' while attempting to alert them of an important event", username) return } if len(details.Emails) == 0 { ctx.Logger.WithError(fmt.Errorf("no email address was found for user")).Errorf("Error occurred looking up user details for user '%s' while attempting to alert them of an important event", username) return } data := templates.EmailEventValues{ Title: description, DisplayName: details.DisplayName, RemoteIP: ctx.RemoteIP().String(), Details: eventDetails, BodyPrefix: body.Prefix, BodyEvent: body.Body, BodySuffix: body.Suffix, } ctx.Logger.Debugf("Getting user addresses for notification") addresses := details.Addresses() ctx.Logger.Debugf("Sending an email to user %s (%s) to inform them of an important event.", username, addresses[0].String()) if err = ctx.Providers.Notifier.Send(ctx, addresses[0], description, ctx.Providers.Templates.GetEventEmailTemplate(), data); err != nil { ctx.Logger.WithError(err).Errorf("Error occurred sending notification to user '%s' while attempting to alert them of an important event", username) return } } func redactEmail(email string) string { parts := strings.Split(email, "@") if len(parts) != 2 { return "" } localPart := parts[0] domain := parts[1] if len(localPart) <= 2 { return strings.Repeat("*", len(localPart)) + "@" + domain } first := string(localPart[0]) last := string(localPart[len(localPart)-1]) middle := strings.Repeat("*", len(localPart)-2) return first + middle + last + "@" + domain }