fix(tgbot): escape template parameters once in I18nBot

Every bot message is sent HTML-parsed while the intended markup lives
in the translation templates, yet the values filled into them were
escaped only at some call sites. Remarks and e-mails, which a node
chooses for the inbounds it reports, reached the scheduled report and
the client info unescaped and turned into markup, and the reports that
escaped their whole text instead showed the templates' own tags.

I18nBot now escapes every parameter value, the call sites drop their
own escaping and the whole-report escapes, the two values concatenated
outside a template are escaped where they are written, and callback
answers, which are plain text, are unescaped again.
This commit is contained in:
MHSanaei
2026-11-01 08:58:43 +01:00
parent a9191cb468
commit fac9009398
10 changed files with 88 additions and 172 deletions
@@ -43,7 +43,7 @@ func (t *Tgbot) screenClientIps(chatID int64, email string) {
if err != nil || len(ips) == 0 {
body += t.I18nBot("tgbot.noIpRecord")
} else {
body += t.I18nBot("tgbot.messages.ips", "IPs=="+html.EscapeString(formatIPLog(ips)))
body += t.I18nBot("tgbot.messages.ips", "IPs=="+formatIPLog(ips))
}
body += t.I18nBot("tgbot.messages.refreshedOn", "Time=="+time.Now().Format("2006-01-02 15:04:05"))
rows := [][]telego.InlineKeyboardButton{
@@ -158,9 +158,9 @@ func (t *Tgbot) screenClientLinks(chatID int64, email string) {
return
}
body := t.clientScreenBody(email, "")
body += t.I18nBot("tgbot.messages.subURL", "URL=="+html.EscapeString(subURL))
body += t.I18nBot("tgbot.messages.subURL", "URL=="+subURL)
if subJSON != "" {
body += t.I18nBot("tgbot.messages.jsonURL", "URL=="+html.EscapeString(subJSON))
body += t.I18nBot("tgbot.messages.jsonURL", "URL=="+subJSON)
}
body += t.I18nBot("tgbot.messages.refreshedOn", "Time=="+time.Now().Format("2006-01-02 15:04:05"))
rows := [][]telego.InlineKeyboardButton{
@@ -213,7 +213,7 @@ func (t *Tgbot) screenClientQR(chatID int64, email string) {
return
}
body := t.clientScreenBody(email, t.I18nBot("tgbot.answers.qrCodeForClient", "Email=="+email))
body += t.I18nBot("tgbot.messages.subURL", "URL=="+html.EscapeString(subURL))
body += t.I18nBot("tgbot.messages.subURL", "URL=="+subURL)
rows := [][]telego.InlineKeyboardButton{
tu.InlineKeyboardRow(t.btn("tgbot.buttons.individualLinks", t.encodeQuery("client_individual_links "+email))),
t.backRow(),