forked from gitea/gitea
Backport #19169 Unfortunately many email readers will (helpfully) detect url or url-like names and automatically create links to them, even in HTML emails. This is not ideal when usernames can have dots in them. This PR tries to prevent this behaviour by sticking ZWJ characters between dots and also set the meta tag to prevent format detection. Not every email template has been changed in this way - just the activation emails but it may be that we should be setting the above meta tag in all of our emails too. Signed-off-by: Andrew Thornton <art27@cantab.net>
This commit is contained in:
parent
d21b7fd3af
commit
bb0e2121a3
|
@ -633,6 +633,11 @@ func JSEscape(raw string) string {
|
|||
return template.JSEscapeString(raw)
|
||||
}
|
||||
|
||||
// DotEscape wraps a dots in names with ZWJ [U+200D] in order to prevent autolinkers from detecting these as urls
|
||||
func DotEscape(raw string) string {
|
||||
return strings.ReplaceAll(raw, ".", "\u200d.\u200d")
|
||||
}
|
||||
|
||||
// Sha1 returns sha1 sum of string
|
||||
func Sha1(str string) string {
|
||||
return base.EncodeSha1(str)
|
||||
|
|
|
@ -77,8 +77,9 @@ func sendUserMail(language string, u *user_model.User, tpl base.TplName, code, s
|
|||
"Code": code,
|
||||
"Language": locale.Language(),
|
||||
// helper
|
||||
"i18n": locale,
|
||||
"Str2html": templates.Str2html,
|
||||
"i18n": locale,
|
||||
"Str2html": templates.Str2html,
|
||||
"DotEscape": templates.DotEscape,
|
||||
}
|
||||
|
||||
var content bytes.Buffer
|
||||
|
@ -127,8 +128,9 @@ func SendActivateEmailMail(u *user_model.User, email *user_model.EmailAddress) {
|
|||
"Email": email.Email,
|
||||
"Language": locale.Language(),
|
||||
// helper
|
||||
"i18n": locale,
|
||||
"Str2html": templates.Str2html,
|
||||
"i18n": locale,
|
||||
"Str2html": templates.Str2html,
|
||||
"DotEscape": templates.DotEscape,
|
||||
}
|
||||
|
||||
var content bytes.Buffer
|
||||
|
@ -157,8 +159,9 @@ func SendRegisterNotifyMail(u *user_model.User) {
|
|||
"Username": u.Name,
|
||||
"Language": locale.Language(),
|
||||
// helper
|
||||
"i18n": locale,
|
||||
"Str2html": templates.Str2html,
|
||||
"i18n": locale,
|
||||
"Str2html": templates.Str2html,
|
||||
"DotEscape": templates.DotEscape,
|
||||
}
|
||||
|
||||
var content bytes.Buffer
|
||||
|
@ -190,8 +193,9 @@ func SendCollaboratorMail(u, doer *user_model.User, repo *repo_model.Repository)
|
|||
"Link": repo.HTMLURL(),
|
||||
"Language": locale.Language(),
|
||||
// helper
|
||||
"i18n": locale,
|
||||
"Str2html": templates.Str2html,
|
||||
"i18n": locale,
|
||||
"Str2html": templates.Str2html,
|
||||
"DotEscape": templates.DotEscape,
|
||||
}
|
||||
|
||||
var content bytes.Buffer
|
||||
|
@ -273,8 +277,9 @@ func composeIssueCommentMessages(ctx *mailCommentContext, lang string, recipient
|
|||
"ReviewComments": reviewComments,
|
||||
"Language": locale.Language(),
|
||||
// helper
|
||||
"i18n": locale,
|
||||
"Str2html": templates.Str2html,
|
||||
"i18n": locale,
|
||||
"Str2html": templates.Str2html,
|
||||
"DotEscape": templates.DotEscape,
|
||||
}
|
||||
|
||||
var mailSubject bytes.Buffer
|
||||
|
|
|
@ -74,8 +74,9 @@ func mailNewRelease(lang string, tos []string, rel *models.Release) {
|
|||
"Subject": subject,
|
||||
"Language": locale.Language(),
|
||||
// helper
|
||||
"i18n": locale,
|
||||
"Str2html": templates.Str2html,
|
||||
"i18n": locale,
|
||||
"Str2html": templates.Str2html,
|
||||
"DotEscape": templates.DotEscape,
|
||||
}
|
||||
|
||||
var mailBody bytes.Buffer
|
||||
|
|
|
@ -73,8 +73,9 @@ func sendRepoTransferNotifyMailPerLang(lang string, newOwner, doer *user_model.U
|
|||
"Language": locale.Language(),
|
||||
"Destination": destination,
|
||||
// helper
|
||||
"i18n": locale,
|
||||
"Str2html": templates.Str2html,
|
||||
"i18n": locale,
|
||||
"Str2html": templates.Str2html,
|
||||
"DotEscape": templates.DotEscape,
|
||||
}
|
||||
|
||||
if err := bodyTemplates.ExecuteTemplate(&content, string(mailRepoTransferNotify), data); err != nil {
|
||||
|
|
|
@ -2,12 +2,13 @@
|
|||
<html>
|
||||
<head>
|
||||
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
|
||||
<title>{{.i18n.Tr "mail.activate_account.title" .DisplayName}}</title>
|
||||
<meta name="format-detection" content="telephone=no,date=no,address=no,email=no,url=no"/>
|
||||
<title>{{.i18n.Tr "mail.activate_account.title" (.DisplayName|DotEscape)}}</title>
|
||||
</head>
|
||||
|
||||
{{ $activate_url := printf "%suser/activate?code=%s" AppUrl (QueryEscape .Code)}}
|
||||
<body>
|
||||
<p>{{.i18n.Tr "mail.activate_account.text_1" .DisplayName AppName | Str2html}}</p><br>
|
||||
<p>{{.i18n.Tr "mail.activate_account.text_1" (.DisplayName|DotEscape) AppName | Str2html}}</p><br>
|
||||
<p>{{.i18n.Tr "mail.activate_account.text_2" .ActiveCodeLives | Str2html}}</p><p><a href="{{$activate_url}}">{{$activate_url}}</a></p><br>
|
||||
<p>{{.i18n.Tr "mail.link_not_working_do_paste"}}</p>
|
||||
|
||||
|
|
|
@ -2,12 +2,13 @@
|
|||
<html>
|
||||
<head>
|
||||
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
|
||||
<title>{{.i18n.Tr "mail.activate_email.title" .DisplayName}}</title>
|
||||
<meta name="format-detection" content="telephone=no,date=no,address=no,email=no,url=no"/>
|
||||
<title>{{.i18n.Tr "mail.activate_email.title" (.DisplayName|DotEscape)}}</title>
|
||||
</head>
|
||||
|
||||
{{ $activate_url := printf "%suser/activate_email?code=%s&email=%s" AppUrl (QueryEscape .Code) (QueryEscape .Email)}}
|
||||
<body>
|
||||
<p>{{.i18n.Tr "mail.hi_user_x" .DisplayName | Str2html}}</p><br>
|
||||
<p>{{.i18n.Tr "mail.hi_user_x" (.DisplayName|DotEscape) | Str2html}}</p><br>
|
||||
<p>{{.i18n.Tr "mail.activate_email.text" .ActiveCodeLives | Str2html}}</p><p><a href="{{$activate_url}}">{{$activate_url}}</a></p><br>
|
||||
<p>{{.i18n.Tr "mail.link_not_working_do_paste"}}</p>
|
||||
|
||||
|
|
|
@ -2,12 +2,13 @@
|
|||
<html>
|
||||
<head>
|
||||
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
|
||||
<title>{{.i18n.Tr "mail.register_notify.title" .DisplayName AppName}}</title>
|
||||
<meta name="format-detection" content="telephone=no,date=no,address=no,email=no,url=no"/>
|
||||
<title>{{.i18n.Tr "mail.register_notify.title" (.DisplayName|DotEscape) AppName}}</title>
|
||||
</head>
|
||||
|
||||
{{$set_pwd_url := printf "%[1]suser/forgot_password" AppUrl}}
|
||||
<body>
|
||||
<p>{{.i18n.Tr "mail.hi_user_x" .DisplayName | Str2html}}</p><br>
|
||||
<p>{{.i18n.Tr "mail.hi_user_x" (.DisplayName|DotEscape) | Str2html}}</p><br>
|
||||
<p>{{.i18n.Tr "mail.register_notify.text_1" AppName}}</p><br>
|
||||
<p>{{.i18n.Tr "mail.register_notify.text_2" .Username}}</p><p><a href="{{AppUrl}}user/login">{{AppUrl}}user/login</a></p><br>
|
||||
<p>{{.i18n.Tr "mail.register_notify.text_3" ($set_pwd_url | Escape) | Str2html}}</p><br>
|
||||
|
|
|
@ -2,12 +2,13 @@
|
|||
<html>
|
||||
<head>
|
||||
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
|
||||
<title>{{.i18n.Tr "mail.reset_password.title" .DisplayName}}</title>
|
||||
<meta name="format-detection" content="telephone=no,date=no,address=no,email=no,url=no"/>
|
||||
<title>{{.i18n.Tr "mail.reset_password.title" (.DisplayName|DotEscape)}}</title>
|
||||
</head>
|
||||
|
||||
{{ $recover_url := printf "%suser/recover_account?code=%s" AppUrl (QueryEscape .Code)}}
|
||||
<body>
|
||||
<p>{{.i18n.Tr "mail.hi_user_x" .DisplayName | Str2html}}</p><br>
|
||||
<p>{{.i18n.Tr "mail.hi_user_x" (.DisplayName|DotEscape) | Str2html}}</p><br>
|
||||
<p>{{.i18n.Tr "mail.reset_password.text" .ResetPwdCodeLives | Str2html}}</p><p><a href="{{$recover_url}}">{{$recover_url}}</a></p><br>
|
||||
<p>{{.i18n.Tr "mail.link_not_working_do_paste"}}</p>
|
||||
|
||||
|
|
Loading…
Reference in New Issue