fix(quick-261029-d9j): pick the mail language from Accept-Language, add mail.fallback_locale, Polish subjects

- preferred_locale and the request locale are normalised (comma lists,
  q-weights, region subtags, case) to pl or en by NormalizeMailLocale, so a
  raw Accept-Language such as en-GB,en;q=0.9 selects the -en templates
- new golem15.user.mail.fallback_locale (default pl) is used when neither
  names a supported language; ResolveMailLocaleFor applies it, and Boot
  rejects any value other than pl or en
- activate, reactivate and restore Polish templates get Polish subjects
- no template, route or payload changes; MailTemplate and
  ResolveMailLocale keep their signatures
This commit is contained in:
Jakub Zych
2026-10-29 09:47:42 +01:00
parent 91af10b572
commit 6bf219f50a
13 changed files with 487 additions and 28 deletions

View File

@@ -160,7 +160,7 @@ func Login(app *backpack.App) http.HandlerFunc {
writeOpaque500(w)
return
}
sendTemplateVars(ctx, app, mailName(ctx, user, "golem15.user::mail.reactivate"), user.Email, mailVars(displayName(user), "", ""))
sendTemplateVars(ctx, app, mailName(ctx, app, user, "golem15.user::mail.reactivate"), user.Email, mailVars(displayName(user), "", ""))
}
// A failed last_seen write is logged and never fails the login.
if err := classes.TouchLastSeen(ctx, gdb, user.ID); err != nil {
@@ -476,7 +476,7 @@ func ForgotPassword(app *backpack.App) http.HandlerFunc {
pluginLog.Error("golem15.user: issue reset code", "err", err)
} else {
packed := strconv.FormatUint(uint64(user.ID), 10) + "!" + code
sendTemplateVars(ctx, app, mailName(ctx, user, "golem15.user::mail.restore"), user.Email, mailVars(displayName(user), resetLink(app, user.ID, code), packed))
sendTemplateVars(ctx, app, mailName(ctx, app, user, "golem15.user::mail.restore"), user.Email, mailVars(displayName(user), resetLink(app, user.ID, code), packed))
}
}
writeJSON(w, http.StatusOK, map[string]any{"message": forgotPasswordBody})
@@ -937,7 +937,7 @@ func Register(app *backpack.App) http.HandlerFunc {
packed := strconv.FormatUint(uint64(user.ID), 10) + "!" + code
vars = mailVars(displayName(user), activationLink(app, user.ID, code), packed)
}
sendTemplateVars(ctx, app, mailName(ctx, user, "golem15.user::mail.activate"), user.Email, vars)
sendTemplateVars(ctx, app, mailName(ctx, app, user, "golem15.user::mail.activate"), user.Email, vars)
writeJSON(w, http.StatusOK, map[string]any{"message": "Activation email sent"})
return
}
@@ -1157,8 +1157,8 @@ func blacklistGrace(app *backpack.App) time.Duration {
return time.Duration(secs) * time.Second
}
func mailName(ctx context.Context, user *models.User, base string) string {
return classes.MailTemplate(base, classes.ResolveMailLocale(ctx, user))
func mailName(ctx context.Context, app *backpack.App, user *models.User, base string) string {
return classes.MailTemplate(base, classes.ResolveMailLocaleFor(ctx, app, user))
}
func sendTemplate(ctx context.Context, app *backpack.App, template, to string) {