This commit is contained in:
2026-08-17 21:20:45 +02:00
parent 321f11e817
commit 6fcdc74843
157 changed files with 2895 additions and 7544 deletions
+14 -11
View File
@@ -2,6 +2,7 @@ package mail
import (
"fmt"
"html"
"log"
"net"
"net/smtp"
@@ -109,31 +110,33 @@ func hasHeaderBreak(v string) bool {
func InviteMessage(webOrigin, email, token, companyName string) Message {
link := AcceptInviteURL(webOrigin, token)
text := fmt.Sprintf("You have been invited to %s on Descrybe.\n\nAccept: %s\n", companyName, link)
html := fmt.Sprintf(
htmlBody := fmt.Sprintf(
`<p>You have been invited to <strong>%s</strong> on Descrybe.</p><p><a href="%s">Accept invite</a></p>`,
companyName, link,
html.EscapeString(companyName), html.EscapeString(link),
)
return Message{To: email, Subject: "You are invited to Descrybe", Text: text, HTML: html}
return Message{To: email, Subject: "You are invited to Descrybe", Text: text, HTML: htmlBody}
}
// AcceptInviteURL builds the durable invite / set-password accept link (hashed invite tokens).
// Token is placed in the URL fragment so it is not sent on the page GET (Referer/access logs).
func AcceptInviteURL(webOrigin, token string) string {
return strings.TrimRight(webOrigin, "/") + "/accept-invite?token=" + token
return strings.TrimRight(webOrigin, "/") + "/accept-invite#token=" + token
}
// SetPasswordURL builds the HMAC set-password accept-invite link.
// Token is placed in the URL fragment so it is not sent on the page GET (Referer/access logs).
func SetPasswordURL(webOrigin, token string) string {
return strings.TrimRight(webOrigin, "/") + "/accept-invite?token=" + token + "&mode=set-password"
return strings.TrimRight(webOrigin, "/") + "/accept-invite#token=" + token + "&mode=set-password"
}
func SetPasswordMessage(webOrigin, email, token string) Message {
link := SetPasswordURL(webOrigin, token)
text := fmt.Sprintf("Set your Descrybe password:\n\n%s\n\nThis link expires in 72 hours.\n", link)
html := fmt.Sprintf(
htmlBody := fmt.Sprintf(
`<p>Set your Descrybe password:</p><p><a href="%s">Set password</a></p><p>This link expires in 72 hours.</p>`,
link,
html.EscapeString(link),
)
return Message{To: email, Subject: "Set your Descrybe password", Text: text, HTML: html}
return Message{To: email, Subject: "Set your Descrybe password", Text: text, HTML: htmlBody}
}
// MigratedSetPasswordMessage uses migrator invite tokens (accept-invite flow).
@@ -143,11 +146,11 @@ func MigratedSetPasswordMessage(webOrigin, email, token string) Message {
"Your Descrybe account was migrated. Set your password here:\n\n%s\n\nIf you did not expect this email, ignore it.\n",
link,
)
html := fmt.Sprintf(
htmlBody := fmt.Sprintf(
`<p>Your Descrybe account was migrated.</p><p><a href="%s">Set your password</a></p><p>If you did not expect this email, ignore it.</p>`,
link,
html.EscapeString(link),
)
return Message{To: email, Subject: "Set your Descrybe password", Text: text, HTML: html}
return Message{To: email, Subject: "Set your Descrybe password", Text: text, HTML: htmlBody}
}
// ResetPasswordURL builds the self-serve forgot-password reset link.