From bf5f8c3cfb2eb523a77239addb8249adf9f8b31d Mon Sep 17 00:00:00 2001 From: aeneasr <3372410+aeneasr@users.noreply.github.com> Date: Mon, 12 Feb 2024 13:12:38 +0100 Subject: [PATCH] feat: add request URL to email and SMS templates --- courier/template/email/login_code_valid.go | 7 ++-- .../template/email/recovery_code_invalid.go | 3 +- courier/template/email/recovery_code_valid.go | 1 + courier/template/email/recovery_invalid.go | 3 +- courier/template/email/recovery_valid.go | 1 + .../template/email/registration_code_valid.go | 1 + .../email/verification_code_invalid.go | 3 +- .../template/email/verification_code_valid.go | 1 + .../template/email/verification_invalid.go | 3 +- courier/template/email/verification_valid.go | 1 + courier/template/sms/login_code_valid.go | 7 ++-- courier/template/sms/verification_code.go | 1 + selfservice/strategy/code/code_sender.go | 32 +++++++++++++------ selfservice/strategy/link/sender.go | 32 +++++++++++++------ 14 files changed, 67 insertions(+), 29 deletions(-) diff --git a/courier/template/email/login_code_valid.go b/courier/template/email/login_code_valid.go index ea1dde008728..f48ae6116118 100644 --- a/courier/template/email/login_code_valid.go +++ b/courier/template/email/login_code_valid.go @@ -18,9 +18,10 @@ type ( model *LoginCodeValidModel } LoginCodeValidModel struct { - To string `json:"to"` - LoginCode string `json:"login_code"` - Identity map[string]interface{} `json:"identity"` + To string `json:"to"` + LoginCode string `json:"login_code"` + Identity map[string]interface{} `json:"identity"` + RequestURL string `json:"request_url"` } ) diff --git a/courier/template/email/recovery_code_invalid.go b/courier/template/email/recovery_code_invalid.go index 2ac8022bf2d0..e2f648003271 100644 --- a/courier/template/email/recovery_code_invalid.go +++ b/courier/template/email/recovery_code_invalid.go @@ -18,7 +18,8 @@ type ( model *RecoveryCodeInvalidModel } RecoveryCodeInvalidModel struct { - To string `json:"to"` + To string `json:"to"` + RequestURL string `json:"request_url"` } ) diff --git a/courier/template/email/recovery_code_valid.go b/courier/template/email/recovery_code_valid.go index e386de93d984..f9e2ad9ec20f 100644 --- a/courier/template/email/recovery_code_valid.go +++ b/courier/template/email/recovery_code_valid.go @@ -21,6 +21,7 @@ type ( To string `json:"to"` RecoveryCode string `json:"recovery_code"` Identity map[string]interface{} `json:"identity"` + RequestURL string `json:"request_url"` } ) diff --git a/courier/template/email/recovery_invalid.go b/courier/template/email/recovery_invalid.go index 4d19808206f5..38d70d44bdc9 100644 --- a/courier/template/email/recovery_invalid.go +++ b/courier/template/email/recovery_invalid.go @@ -18,7 +18,8 @@ type ( m *RecoveryInvalidModel } RecoveryInvalidModel struct { - To string `json:"to"` + To string `json:"to"` + RequestURL string `json:"request_url"` } ) diff --git a/courier/template/email/recovery_valid.go b/courier/template/email/recovery_valid.go index 0a9e01e35919..18e4fde7bd66 100644 --- a/courier/template/email/recovery_valid.go +++ b/courier/template/email/recovery_valid.go @@ -21,6 +21,7 @@ type ( To string `json:"to"` RecoveryURL string `json:"recovery_url"` Identity map[string]interface{} `json:"identity"` + RequestURL string `json:"request_url"` } ) diff --git a/courier/template/email/registration_code_valid.go b/courier/template/email/registration_code_valid.go index 1c48b89f80c4..e63812b00b80 100644 --- a/courier/template/email/registration_code_valid.go +++ b/courier/template/email/registration_code_valid.go @@ -21,6 +21,7 @@ type ( To string `json:"to"` Traits map[string]interface{} `json:"traits"` RegistrationCode string `json:"registration_code"` + RequestURL string `json:"request_url"` } ) diff --git a/courier/template/email/verification_code_invalid.go b/courier/template/email/verification_code_invalid.go index 491997a50ec3..77aec0c04c3e 100644 --- a/courier/template/email/verification_code_invalid.go +++ b/courier/template/email/verification_code_invalid.go @@ -18,7 +18,8 @@ type ( m *VerificationCodeInvalidModel } VerificationCodeInvalidModel struct { - To string `json:"to"` + To string `json:"to"` + RequestURL string `json:"request_url"` } ) diff --git a/courier/template/email/verification_code_valid.go b/courier/template/email/verification_code_valid.go index 3f6ccb966ed9..7cf5823b0524 100644 --- a/courier/template/email/verification_code_valid.go +++ b/courier/template/email/verification_code_valid.go @@ -22,6 +22,7 @@ type ( VerificationURL string `json:"verification_url"` VerificationCode string `json:"verification_code"` Identity map[string]interface{} `json:"identity"` + RequestURL string `json:"request_url"` } ) diff --git a/courier/template/email/verification_invalid.go b/courier/template/email/verification_invalid.go index dc2e050a585e..7b0a776fa254 100644 --- a/courier/template/email/verification_invalid.go +++ b/courier/template/email/verification_invalid.go @@ -18,7 +18,8 @@ type ( m *VerificationInvalidModel } VerificationInvalidModel struct { - To string `json:"to"` + To string `json:"to"` + RequestURL string `json:"request_url"` } ) diff --git a/courier/template/email/verification_valid.go b/courier/template/email/verification_valid.go index 9c088d144735..c04913953519 100644 --- a/courier/template/email/verification_valid.go +++ b/courier/template/email/verification_valid.go @@ -21,6 +21,7 @@ type ( To string `json:"to"` VerificationURL string `json:"verification_url"` Identity map[string]interface{} `json:"identity"` + RequestURL string `json:"request_url"` } ) diff --git a/courier/template/sms/login_code_valid.go b/courier/template/sms/login_code_valid.go index 2f56aee885a7..439856accb8a 100644 --- a/courier/template/sms/login_code_valid.go +++ b/courier/template/sms/login_code_valid.go @@ -17,9 +17,10 @@ type ( model *LoginCodeValidModel } LoginCodeValidModel struct { - To string `json:"to"` - LoginCode string `json:"login_code"` - Identity map[string]interface{} `json:"identity"` + To string `json:"to"` + LoginCode string `json:"login_code"` + Identity map[string]interface{} `json:"identity"` + RequestURL string `json:"request_url"` } ) diff --git a/courier/template/sms/verification_code.go b/courier/template/sms/verification_code.go index a4d19e3d4a7d..a367de9e584c 100644 --- a/courier/template/sms/verification_code.go +++ b/courier/template/sms/verification_code.go @@ -21,6 +21,7 @@ type ( To string `json:"to"` VerificationCode string `json:"verification_code"` Identity map[string]interface{} `json:"identity"` + RequestURL string `json:"request_url"` } ) diff --git a/selfservice/strategy/code/code_sender.go b/selfservice/strategy/code/code_sender.go index ccc3330f9ba8..d0166e86863f 100644 --- a/selfservice/strategy/code/code_sender.go +++ b/selfservice/strategy/code/code_sender.go @@ -102,6 +102,7 @@ func (s *Sender) SendCode(ctx context.Context, f flow.Flow, id *identity.Identit To: address.To, RegistrationCode: rawCode, Traits: model, + RequestURL: f.GetRequestURL(), } s.deps.Audit(). @@ -143,15 +144,17 @@ func (s *Sender) SendCode(ctx context.Context, f flow.Flow, id *identity.Identit switch address.Via { case identity.ChannelTypeEmail: t = email.NewLoginCodeValid(s.deps, &email.LoginCodeValidModel{ - To: address.To, - LoginCode: rawCode, - Identity: model, + To: address.To, + LoginCode: rawCode, + Identity: model, + RequestURL: f.GetRequestURL(), }) case identity.ChannelTypeSMS: t = sms.NewLoginCodeValid(s.deps, &sms.LoginCodeValidModel{ - To: address.To, - LoginCode: rawCode, - Identity: model, + To: address.To, + LoginCode: rawCode, + Identity: model, + RequestURL: f.GetRequestURL(), }) } @@ -189,7 +192,10 @@ func (s *Sender) SendRecoveryCode(ctx context.Context, f *recovery.Flow, via ide Info("Account recovery was requested for an unknown address.") if !notifyUnknownRecipients { // do nothing - } else if err := s.send(ctx, string(via), email.NewRecoveryCodeInvalid(s.deps, &email.RecoveryCodeInvalidModel{To: to})); err != nil { + } else if err := s.send(ctx, string(via), email.NewRecoveryCodeInvalid(s.deps, &email.RecoveryCodeInvalidModel{ + To: to, + RequestURL: f.RequestURL, + })); err != nil { return err } return errors.WithStack(ErrUnknownAddress) @@ -220,10 +226,10 @@ func (s *Sender) SendRecoveryCode(ctx context.Context, f *recovery.Flow, via ide return err } - return s.SendRecoveryCodeTo(ctx, i, rawCode, code) + return s.SendRecoveryCodeTo(ctx, i, rawCode, code, f) } -func (s *Sender) SendRecoveryCodeTo(ctx context.Context, i *identity.Identity, codeString string, code *RecoveryCode) error { +func (s *Sender) SendRecoveryCodeTo(ctx context.Context, i *identity.Identity, codeString string, code *RecoveryCode, f flow.Flow) error { s.deps.Audit(). WithField("via", code.RecoveryAddress.Via). WithField("identity_id", code.RecoveryAddress.IdentityID). @@ -241,6 +247,7 @@ func (s *Sender) SendRecoveryCodeTo(ctx context.Context, i *identity.Identity, c To: code.RecoveryAddress.Value, RecoveryCode: codeString, Identity: model, + RequestURL: f.GetRequestURL(), } return s.send(ctx, string(code.RecoveryAddress.Via), email.NewRecoveryCodeValid(s.deps, &emailModel)) @@ -268,7 +275,10 @@ func (s *Sender) SendVerificationCode(ctx context.Context, f *verification.Flow, Info("Address verification was requested for an unknown address.") if !notifyUnknownRecipients { // do nothing - } else if err := s.send(ctx, string(via), email.NewVerificationCodeInvalid(s.deps, &email.VerificationCodeInvalidModel{To: to})); err != nil { + } else if err := s.send(ctx, string(via), email.NewVerificationCodeInvalid(s.deps, &email.VerificationCodeInvalidModel{ + To: to, + RequestURL: f.GetRequestURL(), + })); err != nil { return err } return errors.WithStack(ErrUnknownAddress) @@ -333,12 +343,14 @@ func (s *Sender) SendVerificationCodeTo(ctx context.Context, f *verification.Flo VerificationURL: s.constructVerificationLink(ctx, f.ID, codeString), Identity: model, VerificationCode: codeString, + RequestURL: f.GetRequestURL(), }) case identity.ChannelTypeSMS: t = sms.NewVerificationCodeValid(s.deps, &sms.VerificationCodeValidModel{ To: code.VerifiableAddress.Value, VerificationCode: codeString, Identity: model, + RequestURL: f.GetRequestURL(), }) default: return errors.WithStack(herodot.ErrInternalServerError.WithReasonf("Expected email or sms but got %s", code.VerifiableAddress.Via)) diff --git a/selfservice/strategy/link/sender.go b/selfservice/strategy/link/sender.go index d58f167335d7..874f0b92129d 100644 --- a/selfservice/strategy/link/sender.go +++ b/selfservice/strategy/link/sender.go @@ -79,7 +79,10 @@ func (s *Sender) SendRecoveryLink(ctx context.Context, f *recovery.Flow, via ide Info("Account recovery was requested for an unknown address.") if !notifyUnknownRecipients { // do nothing - } else if err := s.send(ctx, string(via), email.NewRecoveryInvalid(s.r, &email.RecoveryInvalidModel{To: to})); err != nil { + } else if err := s.send(ctx, string(via), email.NewRecoveryInvalid(s.r, &email.RecoveryInvalidModel{ + To: to, + RequestURL: f.GetRequestURL(), + })); err != nil { return err } return errors.WithStack(ErrUnknownAddress) @@ -128,7 +131,10 @@ func (s *Sender) SendVerificationLink(ctx context.Context, f *verification.Flow, Info("Address verification was requested for an unknown address.") if !notifyUnknownRecipients { // do nothing - } else if err := s.send(ctx, string(via), email.NewVerificationInvalid(s.r, &email.VerificationInvalidModel{To: to})); err != nil { + } else if err := s.send(ctx, string(via), email.NewVerificationInvalid(s.r, &email.VerificationInvalidModel{ + To: to, + RequestURL: f.GetRequestURL(), + })); err != nil { return err } return errors.WithStack(ErrUnknownAddress) @@ -174,7 +180,10 @@ func (s *Sender) SendRecoveryTokenTo(ctx context.Context, f *recovery.Flow, i *i url.Values{ "token": {token.Token}, "flow": {f.ID.String()}, - }).String(), Identity: model})) + }).String(), + Identity: model, + RequestURL: f.GetRequestURL(), + })) } func (s *Sender) SendVerificationTokenTo(ctx context.Context, f *verification.Flow, i *identity.Identity, address *identity.VerifiableAddress, token *VerificationToken) error { @@ -192,12 +201,17 @@ func (s *Sender) SendVerificationTokenTo(ctx context.Context, f *verification.Fl } if err := s.send(ctx, string(address.Via), email.NewVerificationValid(s.r, - &email.VerificationValidModel{To: address.Value, VerificationURL: urlx.CopyWithQuery( - urlx.AppendPaths(s.r.Config().SelfServiceLinkMethodBaseURL(ctx), verification.RouteSubmitFlow), - url.Values{ - "flow": {f.ID.String()}, - "token": {token.Token}, - }).String(), Identity: model})); err != nil { + &email.VerificationValidModel{ + To: address.Value, + VerificationURL: urlx.CopyWithQuery( + urlx.AppendPaths(s.r.Config().SelfServiceLinkMethodBaseURL(ctx), verification.RouteSubmitFlow), + url.Values{ + "flow": {f.ID.String()}, + "token": {token.Token}, + }).String(), + Identity: model, + RequestURL: f.GetRequestURL(), + })); err != nil { return err } address.Status = identity.VerifiableAddressStatusSent