feat: add reply-to header in email notification (#6393)

* feat: add reply-to header to smtp messages

* fix: grpc reply_to_address min 0 and js var name

* fix: add missing translations

* fix merge and linting

---------

Co-authored-by: Livio Spring <livio.a@gmail.com>
This commit is contained in:
Miguel Cabrerizo
2023-08-29 09:08:24 +02:00
committed by GitHub
parent 9b43e28c23
commit fd00ac533a
31 changed files with 307 additions and 120 deletions

View File

@@ -11,20 +11,21 @@ import (
)
const (
SMTPConfigProjectionTable = "projections.smtp_configs"
SMTPConfigProjectionTable = "projections.smtp_configs1"
SMTPConfigColumnAggregateID = "aggregate_id"
SMTPConfigColumnCreationDate = "creation_date"
SMTPConfigColumnChangeDate = "change_date"
SMTPConfigColumnSequence = "sequence"
SMTPConfigColumnResourceOwner = "resource_owner"
SMTPConfigColumnInstanceID = "instance_id"
SMTPConfigColumnTLS = "tls"
SMTPConfigColumnSenderAddress = "sender_address"
SMTPConfigColumnSenderName = "sender_name"
SMTPConfigColumnSMTPHost = "host"
SMTPConfigColumnSMTPUser = "username"
SMTPConfigColumnSMTPPassword = "password"
SMTPConfigColumnAggregateID = "aggregate_id"
SMTPConfigColumnCreationDate = "creation_date"
SMTPConfigColumnChangeDate = "change_date"
SMTPConfigColumnSequence = "sequence"
SMTPConfigColumnResourceOwner = "resource_owner"
SMTPConfigColumnInstanceID = "instance_id"
SMTPConfigColumnTLS = "tls"
SMTPConfigColumnSenderAddress = "sender_address"
SMTPConfigColumnSenderName = "sender_name"
SMTPConfigColumnReplyToAddress = "reply_to_address"
SMTPConfigColumnSMTPHost = "host"
SMTPConfigColumnSMTPUser = "username"
SMTPConfigColumnSMTPPassword = "password"
)
type smtpConfigProjection struct {
@@ -46,6 +47,7 @@ func newSMTPConfigProjection(ctx context.Context, config crdb.StatementHandlerCo
crdb.NewColumn(SMTPConfigColumnTLS, crdb.ColumnTypeBool),
crdb.NewColumn(SMTPConfigColumnSenderAddress, crdb.ColumnTypeText),
crdb.NewColumn(SMTPConfigColumnSenderName, crdb.ColumnTypeText),
crdb.NewColumn(SMTPConfigColumnReplyToAddress, crdb.ColumnTypeText),
crdb.NewColumn(SMTPConfigColumnSMTPHost, crdb.ColumnTypeText),
crdb.NewColumn(SMTPConfigColumnSMTPUser, crdb.ColumnTypeText),
crdb.NewColumn(SMTPConfigColumnSMTPPassword, crdb.ColumnTypeJSONB, crdb.Nullable()),
@@ -104,6 +106,7 @@ func (p *smtpConfigProjection) reduceSMTPConfigAdded(event eventstore.Event) (*h
handler.NewCol(SMTPConfigColumnTLS, e.TLS),
handler.NewCol(SMTPConfigColumnSenderAddress, e.SenderAddress),
handler.NewCol(SMTPConfigColumnSenderName, e.SenderName),
handler.NewCol(SMTPConfigColumnReplyToAddress, e.ReplyToAddress),
handler.NewCol(SMTPConfigColumnSMTPHost, e.Host),
handler.NewCol(SMTPConfigColumnSMTPUser, e.User),
handler.NewCol(SMTPConfigColumnSMTPPassword, e.Password),
@@ -117,7 +120,7 @@ func (p *smtpConfigProjection) reduceSMTPConfigChanged(event eventstore.Event) (
return nil, errors.ThrowInvalidArgumentf(nil, "HANDL-wl0wd", "reduce.wrong.event.type %s", instance.SMTPConfigChangedEventType)
}
columns := make([]handler.Column, 0, 7)
columns := make([]handler.Column, 0, 8)
columns = append(columns, handler.NewCol(SMTPConfigColumnChangeDate, e.CreationDate()),
handler.NewCol(SMTPConfigColumnSequence, e.Sequence()))
if e.TLS != nil {
@@ -129,6 +132,9 @@ func (p *smtpConfigProjection) reduceSMTPConfigChanged(event eventstore.Event) (
if e.FromName != nil {
columns = append(columns, handler.NewCol(SMTPConfigColumnSenderName, *e.FromName))
}
if e.ReplyToAddress != nil {
columns = append(columns, handler.NewCol(SMTPConfigColumnReplyToAddress, *e.ReplyToAddress))
}
if e.Host != nil {
columns = append(columns, handler.NewCol(SMTPConfigColumnSMTPHost, *e.Host))
}

View File

@@ -30,6 +30,7 @@ func TestSMTPConfigProjection_reduces(t *testing.T) {
"tls": true,
"senderAddress": "sender",
"senderName": "name",
"replyToAddress": "reply-to",
"host": "host",
"user": "user"
}`,
@@ -44,13 +45,14 @@ func TestSMTPConfigProjection_reduces(t *testing.T) {
executer: &testExecuter{
executions: []execution{
{
expectedStmt: "UPDATE projections.smtp_configs SET (change_date, sequence, tls, sender_address, sender_name, host, username) = ($1, $2, $3, $4, $5, $6, $7) WHERE (aggregate_id = $8) AND (instance_id = $9)",
expectedStmt: "UPDATE projections.smtp_configs1 SET (change_date, sequence, tls, sender_address, sender_name, reply_to_address, host, username) = ($1, $2, $3, $4, $5, $6, $7, $8) WHERE (aggregate_id = $9) AND (instance_id = $10)",
expectedArgs: []interface{}{
anyArg{},
uint64(15),
true,
"sender",
"name",
"reply-to",
"host",
"user",
"agg-id",
@@ -71,6 +73,7 @@ func TestSMTPConfigProjection_reduces(t *testing.T) {
"tls": true,
"senderAddress": "sender",
"senderName": "name",
"replyToAddress": "reply-to",
"host": "host",
"user": "user",
"password": {
@@ -89,7 +92,7 @@ func TestSMTPConfigProjection_reduces(t *testing.T) {
executer: &testExecuter{
executions: []execution{
{
expectedStmt: "INSERT INTO projections.smtp_configs (aggregate_id, creation_date, change_date, resource_owner, instance_id, sequence, tls, sender_address, sender_name, host, username, password) VALUES ($1, $2, $3, $4, $5, $6, $7, $8, $9, $10, $11, $12)",
expectedStmt: "INSERT INTO projections.smtp_configs1 (aggregate_id, creation_date, change_date, resource_owner, instance_id, sequence, tls, sender_address, sender_name, reply_to_address, host, username, password) VALUES ($1, $2, $3, $4, $5, $6, $7, $8, $9, $10, $11, $12, $13)",
expectedArgs: []interface{}{
"agg-id",
anyArg{},
@@ -100,6 +103,7 @@ func TestSMTPConfigProjection_reduces(t *testing.T) {
true,
"sender",
"name",
"reply-to",
"host",
"user",
anyArg{},
@@ -132,7 +136,7 @@ func TestSMTPConfigProjection_reduces(t *testing.T) {
executer: &testExecuter{
executions: []execution{
{
expectedStmt: "UPDATE projections.smtp_configs SET (change_date, sequence, password) = ($1, $2, $3) WHERE (aggregate_id = $4) AND (instance_id = $5)",
expectedStmt: "UPDATE projections.smtp_configs1 SET (change_date, sequence, password) = ($1, $2, $3) WHERE (aggregate_id = $4) AND (instance_id = $5)",
expectedArgs: []interface{}{
anyArg{},
uint64(15),
@@ -162,7 +166,7 @@ func TestSMTPConfigProjection_reduces(t *testing.T) {
executer: &testExecuter{
executions: []execution{
{
expectedStmt: "DELETE FROM projections.smtp_configs WHERE (aggregate_id = $1) AND (instance_id = $2)",
expectedStmt: "DELETE FROM projections.smtp_configs1 WHERE (aggregate_id = $1) AND (instance_id = $2)",
expectedArgs: []interface{}{
"agg-id",
"instance-id",
@@ -189,7 +193,7 @@ func TestSMTPConfigProjection_reduces(t *testing.T) {
executer: &testExecuter{
executions: []execution{
{
expectedStmt: "DELETE FROM projections.smtp_configs WHERE (instance_id = $1)",
expectedStmt: "DELETE FROM projections.smtp_configs1 WHERE (instance_id = $1)",
expectedArgs: []interface{}{
"agg-id",
},

View File

@@ -57,6 +57,10 @@ var (
name: projection.SMTPConfigColumnSenderName,
table: smtpConfigsTable,
}
SMTPConfigColumnReplyToAddress = Column{
name: projection.SMTPConfigColumnReplyToAddress,
table: smtpConfigsTable,
}
SMTPConfigColumnSMTPHost = Column{
name: projection.SMTPConfigColumnSMTPHost,
table: smtpConfigsTable,
@@ -83,12 +87,13 @@ type SMTPConfig struct {
ResourceOwner string
Sequence uint64
TLS bool
SenderAddress string
SenderName string
Host string
User string
Password *crypto.CryptoValue
TLS bool
SenderAddress string
SenderName string
ReplyToAddress string
Host string
User string
Password *crypto.CryptoValue
}
func (q *Queries) SMTPConfigByAggregateID(ctx context.Context, aggregateID string) (config *SMTPConfig, err error) {
@@ -123,6 +128,7 @@ func prepareSMTPConfigQuery(ctx context.Context, db prepareDatabase) (sq.SelectB
SMTPConfigColumnTLS.identifier(),
SMTPConfigColumnSenderAddress.identifier(),
SMTPConfigColumnSenderName.identifier(),
SMTPConfigColumnReplyToAddress.identifier(),
SMTPConfigColumnSMTPHost.identifier(),
SMTPConfigColumnSMTPUser.identifier(),
SMTPConfigColumnSMTPPassword.identifier()).
@@ -139,6 +145,7 @@ func prepareSMTPConfigQuery(ctx context.Context, db prepareDatabase) (sq.SelectB
&config.TLS,
&config.SenderAddress,
&config.SenderName,
&config.ReplyToAddress,
&config.Host,
&config.User,
&password,

View File

@@ -13,18 +13,19 @@ import (
)
var (
prepareSMTPConfigStmt = `SELECT projections.smtp_configs.aggregate_id,` +
` projections.smtp_configs.creation_date,` +
` projections.smtp_configs.change_date,` +
` projections.smtp_configs.resource_owner,` +
` projections.smtp_configs.sequence,` +
` projections.smtp_configs.tls,` +
` projections.smtp_configs.sender_address,` +
` projections.smtp_configs.sender_name,` +
` projections.smtp_configs.host,` +
` projections.smtp_configs.username,` +
` projections.smtp_configs.password` +
` FROM projections.smtp_configs` +
prepareSMTPConfigStmt = `SELECT projections.smtp_configs1.aggregate_id,` +
` projections.smtp_configs1.creation_date,` +
` projections.smtp_configs1.change_date,` +
` projections.smtp_configs1.resource_owner,` +
` projections.smtp_configs1.sequence,` +
` projections.smtp_configs1.tls,` +
` projections.smtp_configs1.sender_address,` +
` projections.smtp_configs1.sender_name,` +
` projections.smtp_configs1.reply_to_address,` +
` projections.smtp_configs1.host,` +
` projections.smtp_configs1.username,` +
` projections.smtp_configs1.password` +
` FROM projections.smtp_configs1` +
` AS OF SYSTEM TIME '-1 ms'`
prepareSMTPConfigCols = []string{
"aggregate_id",
@@ -35,6 +36,7 @@ var (
"tls",
"sender_address",
"sender_name",
"reply_to_address",
"smtp_host",
"smtp_user",
"smtp_password",
@@ -86,6 +88,7 @@ func Test_SMTPConfigsPrepares(t *testing.T) {
true,
"sender",
"name",
"reply-to",
"host",
"user",
&crypto.CryptoValue{},
@@ -93,17 +96,18 @@ func Test_SMTPConfigsPrepares(t *testing.T) {
),
},
object: &SMTPConfig{
AggregateID: "agg-id",
CreationDate: testNow,
ChangeDate: testNow,
ResourceOwner: "ro",
Sequence: 20211108,
TLS: true,
SenderAddress: "sender",
SenderName: "name",
Host: "host",
User: "user",
Password: &crypto.CryptoValue{},
AggregateID: "agg-id",
CreationDate: testNow,
ChangeDate: testNow,
ResourceOwner: "ro",
Sequence: 20211108,
TLS: true,
SenderAddress: "sender",
SenderName: "name",
ReplyToAddress: "reply-to",
Host: "host",
User: "user",
Password: &crypto.CryptoValue{},
},
},
{