Fix email url paths

Signed-off-by: Émile Ré <emile@getprobo.com>
This commit is contained in:
Émile Ré
2026-02-02 11:56:30 +04:00
parent 37a35b3eda
commit 926d008c60
5 changed files with 39 additions and 9 deletions

View File

@@ -61,7 +61,7 @@ func DefaultPresenterConfig(baseURL string) PresenterConfig {
BaseURL: baseURL, BaseURL: baseURL,
SenderCompanyName: "Probo", SenderCompanyName: "Probo",
SenderCompanyWebsiteURL: "https://www.getprobo.com", SenderCompanyWebsiteURL: "https://www.getprobo.com",
SenderCompanyLogoURL: baseurl.MustParse(baseURL).WithPath("/logos/probo.png").MustString(), SenderCompanyLogoURL: baseurl.MustParse(baseURL).AppendPath("/logos/probo.png").MustString(),
SenderCompanyHeadquarterAddress: "Probo Inc, 490 Post St, STE 640, San Francisco, CA, 94102, US", SenderCompanyHeadquarterAddress: "Probo Inc, 490 Post St, STE 640, San Francisco, CA, 94102, US",
} }
} }
@@ -123,7 +123,7 @@ var (
func (p *Presenter) RenderConfirmEmail(confirmationURLPath string, confirmationTokenParam string) (subject string, textBody string, htmlBody *string, err error) { func (p *Presenter) RenderConfirmEmail(confirmationURLPath string, confirmationTokenParam string) (subject string, textBody string, htmlBody *string, err error) {
confirmationUrl := baseurl. confirmationUrl := baseurl.
MustParse(p.variables.BaseURL). MustParse(p.variables.BaseURL).
WithPath(confirmationURLPath). AppendPath(confirmationURLPath).
WithQuery("token", confirmationTokenParam). WithQuery("token", confirmationTokenParam).
MustString() MustString()
@@ -142,7 +142,7 @@ func (p *Presenter) RenderConfirmEmail(confirmationURLPath string, confirmationT
func (p *Presenter) RenderPasswordReset(resetPasswordURLPath string, resetPasswordToken string) (subject string, textBody string, htmlBody *string, err error) { func (p *Presenter) RenderPasswordReset(resetPasswordURLPath string, resetPasswordToken string) (subject string, textBody string, htmlBody *string, err error) {
resetUrl := baseurl. resetUrl := baseurl.
MustParse(p.variables.BaseURL). MustParse(p.variables.BaseURL).
WithPath(resetPasswordURLPath). AppendPath(resetPasswordURLPath).
WithQuery("token", resetPasswordToken). WithQuery("token", resetPasswordToken).
MustString() MustString()
@@ -161,7 +161,7 @@ func (p *Presenter) RenderPasswordReset(resetPasswordURLPath string, resetPasswo
func (p *Presenter) RenderInvitation(invitationURLPath string, invitationToken string, organizationName string) (subject string, textBody string, htmlBody *string, err error) { func (p *Presenter) RenderInvitation(invitationURLPath string, invitationToken string, organizationName string) (subject string, textBody string, htmlBody *string, err error) {
invitationURL := baseurl. invitationURL := baseurl.
MustParse(p.variables.BaseURL). MustParse(p.variables.BaseURL).
WithPath(invitationURLPath). AppendPath(invitationURLPath).
WithQuery("token", invitationToken). WithQuery("token", invitationToken).
WithQuery("fullName", p.variables.RecipientFullName). WithQuery("fullName", p.variables.RecipientFullName).
MustString() MustString()
@@ -182,7 +182,7 @@ func (p *Presenter) RenderInvitation(invitationURLPath string, invitationToken s
func (p *Presenter) RenderDocumentSigning(signinURLPath string, token string, organizationName string) (subject string, textBody string, htmlBody *string, err error) { func (p *Presenter) RenderDocumentSigning(signinURLPath string, token string, organizationName string) (subject string, textBody string, htmlBody *string, err error) {
signingURL := baseurl.MustParse(p.variables.BaseURL). signingURL := baseurl.MustParse(p.variables.BaseURL).
WithPath(signinURLPath). AppendPath(signinURLPath).
WithQuery("token", token). WithQuery("token", token).
MustString() MustString()
@@ -265,7 +265,7 @@ func (p *Presenter) RenderMagicLink(magicLinkUrlPath string, tokenString string,
OrganizationName string OrganizationName string
}{ }{
PresenterVariables: p.variables, PresenterVariables: p.variables,
MagicLinkURL: baseurl.MustParse(p.variables.BaseURL).WithPath(magicLinkUrlPath).WithQuery("token", tokenString).MustString(), MagicLinkURL: baseurl.MustParse(p.variables.BaseURL).AppendPath(magicLinkUrlPath).WithQuery("token", tokenString).MustString(),
DurationInMinutes: int(tokenDuration.Minutes()), DurationInMinutes: int(tokenDuration.Minutes()),
OrganizationName: organizationName, OrganizationName: organizationName,
} }

View File

@@ -19,7 +19,7 @@ export const TrustCenterAccess = () => {
</Text> </Text>
<Section style={buttonContainer}> <Section style={buttonContainer}>
<Button style={button} href={"{{.AccessUrl}}"}> <Button style={button} href={"{{.BaseURL}}"}>
Access Compliance Page Access Compliance Page
</Button> </Button>
</Section> </Section>

View File

@@ -4,6 +4,6 @@ Hi {{.RecipientFullName}},
You have been granted access to {{.OrganizationName}}'s compliance page! Click the link below to access it: You have been granted access to {{.OrganizationName}}'s compliance page! Click the link below to access it:
{{.AccessUrl}} {{.BaseURL}}
Probo Inc, 490 Post St, STE 640, San Francisco, CA, 94102, US Probo Inc, 490 Post St, STE 640, San Francisco, CA, 94102, US

View File

@@ -137,6 +137,32 @@ func (b *BaseURL) WithPath(path string) *URLBuilder {
} }
} }
// WithPath returns a URLBuilder with the specified path.
// The path will be properly joined with the base URL's path.
func (b *BaseURL) AppendPath(path string) *URLBuilder {
if b == nil {
return &URLBuilder{err: fmt.Errorf("base URL is nil")}
}
basePath := strings.TrimSuffix(b.parsed.Path, "/")
// Ensure path starts with /
if !strings.HasPrefix(path, "/") {
path = "/" + path
}
path = basePath + path
// Ensure path does not end with /
path = strings.TrimSuffix(path, "/")
return &URLBuilder{
base: b,
path: path,
query: make(url.Values),
}
}
// WithQuery adds a query parameter to the URL. // WithQuery adds a query parameter to the URL.
func (ub *URLBuilder) WithQuery(key, value string) *URLBuilder { func (ub *URLBuilder) WithQuery(key, value string) *URLBuilder {
if ub.err != nil { if ub.err != nil {

View File

@@ -602,7 +602,11 @@ func (s *TrustCenterAccessService) sendDocumentAccessRejectedEmail(
return fmt.Errorf("cannot get compliance page email presenter config: %w", err) return fmt.Errorf("cannot get compliance page email presenter config: %w", err)
} }
emailPresenter := emails.NewPresenterFromConfig(emailPresenterCfg, access.Name) fullName := access.Name
if fullName == "" {
fullName = access.Email.Username()
}
emailPresenter := emails.NewPresenterFromConfig(emailPresenterCfg, fullName)
subject, textBody, htmlBody, err := emailPresenter.RenderTrustCenterDocumentAccessRejected( subject, textBody, htmlBody, err := emailPresenter.RenderTrustCenterDocumentAccessRejected(
fileNames, fileNames,