diff --git a/dashboard/package-lock.json b/dashboard/package-lock.json
index 797c43f..ce1ea42 100644
--- a/dashboard/package-lock.json
+++ b/dashboard/package-lock.json
@@ -2605,7 +2605,8 @@
"@chakra-ui/css-reset": {
"version": "1.1.1",
"resolved": "https://registry.npmjs.org/@chakra-ui/css-reset/-/css-reset-1.1.1.tgz",
- "integrity": "sha512-+KNNHL4OWqeKia5SL858K3Qbd8WxMij9mWIilBzLD4j2KFrl/+aWFw8syMKth3NmgIibrjsljo+PU3fy2o50dg=="
+ "integrity": "sha512-+KNNHL4OWqeKia5SL858K3Qbd8WxMij9mWIilBzLD4j2KFrl/+aWFw8syMKth3NmgIibrjsljo+PU3fy2o50dg==",
+ "requires": {}
},
"@chakra-ui/descendant": {
"version": "2.1.1",
@@ -3209,7 +3210,8 @@
"@graphql-typed-document-node/core": {
"version": "3.1.1",
"resolved": "https://registry.npmjs.org/@graphql-typed-document-node/core/-/core-3.1.1.tgz",
- "integrity": "sha512-NQ17ii0rK1b34VZonlmT2QMJFI70m0TRwbknO/ihlbatXyaktDhN/98vBiUU6kNBPljqGqyIrl2T4nY2RpFANg=="
+ "integrity": "sha512-NQ17ii0rK1b34VZonlmT2QMJFI70m0TRwbknO/ihlbatXyaktDhN/98vBiUU6kNBPljqGqyIrl2T4nY2RpFANg==",
+ "requires": {}
},
"@popperjs/core": {
"version": "2.11.0",
@@ -3481,7 +3483,8 @@
"draftjs-utils": {
"version": "0.10.2",
"resolved": "https://registry.npmjs.org/draftjs-utils/-/draftjs-utils-0.10.2.tgz",
- "integrity": "sha512-EstHqr3R3JVcilJrBaO/A+01GvwwKmC7e4TCjC7S94ZeMh4IVmf60OuQXtHHpwItK8C2JCi3iljgN5KHkJboUg=="
+ "integrity": "sha512-EstHqr3R3JVcilJrBaO/A+01GvwwKmC7e4TCjC7S94ZeMh4IVmf60OuQXtHHpwItK8C2JCi3iljgN5KHkJboUg==",
+ "requires": {}
},
"error-ex": {
"version": "1.3.2",
@@ -3755,7 +3758,8 @@
"html-to-draftjs": {
"version": "1.5.0",
"resolved": "https://registry.npmjs.org/html-to-draftjs/-/html-to-draftjs-1.5.0.tgz",
- "integrity": "sha512-kggLXBNciKDwKf+KYsuE+V5gw4dZ7nHyGMX9m0wy7urzWjKGWyNFetmArRLvRV0VrxKN70WylFsJvMTJx02OBQ=="
+ "integrity": "sha512-kggLXBNciKDwKf+KYsuE+V5gw4dZ7nHyGMX9m0wy7urzWjKGWyNFetmArRLvRV0VrxKN70WylFsJvMTJx02OBQ==",
+ "requires": {}
},
"import-fresh": {
"version": "3.3.0",
@@ -3945,7 +3949,8 @@
"react-email-editor": {
"version": "1.6.1",
"resolved": "https://registry.npmjs.org/react-email-editor/-/react-email-editor-1.6.1.tgz",
- "integrity": "sha512-pEWpRmTY0ok03cwTGqEOoEldnzThhuRGTrcMnv8W3/jc5MTfcr9USU/IQ9HrVvFStLKoxYBIQnSKY+iCYWOtSQ=="
+ "integrity": "sha512-pEWpRmTY0ok03cwTGqEOoEldnzThhuRGTrcMnv8W3/jc5MTfcr9USU/IQ9HrVvFStLKoxYBIQnSKY+iCYWOtSQ==",
+ "requires": {}
},
"react-fast-compare": {
"version": "3.2.0",
@@ -3968,7 +3973,8 @@
"react-icons": {
"version": "4.3.1",
"resolved": "https://registry.npmjs.org/react-icons/-/react-icons-4.3.1.tgz",
- "integrity": "sha512-cB10MXLTs3gVuXimblAdI71jrJx8njrJZmNMEMC+sQu5B/BIOmlsAjskdqpn81y8UBVEGuHODd7/ci5DvoSzTQ=="
+ "integrity": "sha512-cB10MXLTs3gVuXimblAdI71jrJx8njrJZmNMEMC+sQu5B/BIOmlsAjskdqpn81y8UBVEGuHODd7/ci5DvoSzTQ==",
+ "requires": {}
},
"react-is": {
"version": "16.13.1",
@@ -4159,7 +4165,8 @@
"use-callback-ref": {
"version": "1.2.5",
"resolved": "https://registry.npmjs.org/use-callback-ref/-/use-callback-ref-1.2.5.tgz",
- "integrity": "sha512-gN3vgMISAgacF7sqsLPByqoePooY3n2emTH59Ur5d/M8eg4WTWu1xp8i8DHjohftIyEx0S08RiYxbffr4j8Peg=="
+ "integrity": "sha512-gN3vgMISAgacF7sqsLPByqoePooY3n2emTH59Ur5d/M8eg4WTWu1xp8i8DHjohftIyEx0S08RiYxbffr4j8Peg==",
+ "requires": {}
},
"use-sidecar": {
"version": "1.0.5",
diff --git a/dashboard/src/components/UpdateEmailTemplateModal.tsx b/dashboard/src/components/UpdateEmailTemplateModal.tsx
index e2d61c5..3f903e0 100644
--- a/dashboard/src/components/UpdateEmailTemplateModal.tsx
+++ b/dashboard/src/components/UpdateEmailTemplateModal.tsx
@@ -333,7 +333,7 @@ const UpdateEmailTemplate = ({
{templateVariables.map((i) => (
- {`{{${i.text}}}`}
+ {`{{.${i.text}}}`}
|
Roles
Verified |
Access |
- MFA |
+
+
+ MFA
+
+ |
Actions |
|
@@ -404,13 +408,13 @@ export default function Users() {
) : (
)}
diff --git a/server/constants/verification_types.go b/server/constants/verification_types.go
index 0a83df8..599d83a 100644
--- a/server/constants/verification_types.go
+++ b/server/constants/verification_types.go
@@ -12,5 +12,5 @@ const (
// VerificationTypeInviteMember is the invite_member verification type
VerificationTypeInviteMember = "invite_member"
// VerificationTypeOTP is the otp verification type
- VerificationTypeOTP = "otp"
+ VerificationTypeOTP = "verify_otp"
)
diff --git a/server/db/providers/cassandradb/email_template.go b/server/db/providers/cassandradb/email_template.go
index ea18fce..7cb64cb 100644
--- a/server/db/providers/cassandradb/email_template.go
+++ b/server/db/providers/cassandradb/email_template.go
@@ -29,7 +29,7 @@ func (p *provider) AddEmailTemplate(ctx context.Context, emailTemplate models.Em
return nil, fmt.Errorf("Email template with %s event_name already exists", emailTemplate.EventName)
}
- insertQuery := fmt.Sprintf("INSERT INTO %s (id, event_name, subject, template, created_at, updated_at) VALUES ('%s', '%s', '%s','%s', %d, %d)", KeySpace+"."+models.Collections.EmailTemplate, emailTemplate.ID, emailTemplate.EventName, emailTemplate.Subject, emailTemplate.Template, emailTemplate.CreatedAt, emailTemplate.UpdatedAt)
+ insertQuery := fmt.Sprintf("INSERT INTO %s (id, event_name, subject, design, template, created_at, updated_at) VALUES ('%s', '%s', '%s','%s','%s', %d, %d)", KeySpace+"."+models.Collections.EmailTemplate, emailTemplate.ID, emailTemplate.EventName, emailTemplate.Subject, emailTemplate.Design, emailTemplate.Template, emailTemplate.CreatedAt, emailTemplate.UpdatedAt)
err := p.db.Query(insertQuery).Exec()
if err != nil {
return nil, err
@@ -103,14 +103,14 @@ func (p *provider) ListEmailTemplate(ctx context.Context, pagination model.Pagin
// there is no offset in cassandra
// so we fetch till limit + offset
// and return the results from offset to limit
- query := fmt.Sprintf("SELECT id, event_name, subject, template, created_at, updated_at FROM %s LIMIT %d", KeySpace+"."+models.Collections.EmailTemplate, pagination.Limit+pagination.Offset)
+ query := fmt.Sprintf("SELECT id, event_name, subject, design, template, created_at, updated_at FROM %s LIMIT %d", KeySpace+"."+models.Collections.EmailTemplate, pagination.Limit+pagination.Offset)
scanner := p.db.Query(query).Iter().Scanner()
counter := int64(0)
for scanner.Next() {
if counter >= pagination.Offset {
var emailTemplate models.EmailTemplate
- err := scanner.Scan(&emailTemplate.ID, &emailTemplate.EventName, &emailTemplate.Subject, &emailTemplate.Template, &emailTemplate.CreatedAt, &emailTemplate.UpdatedAt)
+ err := scanner.Scan(&emailTemplate.ID, &emailTemplate.EventName, &emailTemplate.Subject, &emailTemplate.Design, &emailTemplate.Template, &emailTemplate.CreatedAt, &emailTemplate.UpdatedAt)
if err != nil {
return nil, err
}
@@ -128,8 +128,8 @@ func (p *provider) ListEmailTemplate(ctx context.Context, pagination model.Pagin
// GetEmailTemplateByID to get EmailTemplate by id
func (p *provider) GetEmailTemplateByID(ctx context.Context, emailTemplateID string) (*model.EmailTemplate, error) {
var emailTemplate models.EmailTemplate
- query := fmt.Sprintf(`SELECT id, event_name, subject, template, created_at, updated_at FROM %s WHERE id = '%s' LIMIT 1`, KeySpace+"."+models.Collections.EmailTemplate, emailTemplateID)
- err := p.db.Query(query).Consistency(gocql.One).Scan(&emailTemplate.ID, &emailTemplate.EventName, &emailTemplate.Subject, &emailTemplate.Template, &emailTemplate.CreatedAt, &emailTemplate.UpdatedAt)
+ query := fmt.Sprintf(`SELECT id, event_name, subject, design, template, created_at, updated_at FROM %s WHERE id = '%s' LIMIT 1`, KeySpace+"."+models.Collections.EmailTemplate, emailTemplateID)
+ err := p.db.Query(query).Consistency(gocql.One).Scan(&emailTemplate.ID, &emailTemplate.EventName, &emailTemplate.Subject, &emailTemplate.Design, &emailTemplate.Template, &emailTemplate.CreatedAt, &emailTemplate.UpdatedAt)
if err != nil {
return nil, err
}
@@ -139,8 +139,8 @@ func (p *provider) GetEmailTemplateByID(ctx context.Context, emailTemplateID str
// GetEmailTemplateByEventName to get EmailTemplate by event_name
func (p *provider) GetEmailTemplateByEventName(ctx context.Context, eventName string) (*model.EmailTemplate, error) {
var emailTemplate models.EmailTemplate
- query := fmt.Sprintf(`SELECT id, event_name, subject, template, created_at, updated_at FROM %s WHERE event_name = '%s' LIMIT 1 ALLOW FILTERING`, KeySpace+"."+models.Collections.EmailTemplate, eventName)
- err := p.db.Query(query).Consistency(gocql.One).Scan(&emailTemplate.ID, &emailTemplate.EventName, &emailTemplate.Subject, &emailTemplate.Template, &emailTemplate.CreatedAt, &emailTemplate.UpdatedAt)
+ query := fmt.Sprintf(`SELECT id, event_name, subject, design, template, created_at, updated_at FROM %s WHERE event_name = '%s' LIMIT 1 ALLOW FILTERING`, KeySpace+"."+models.Collections.EmailTemplate, eventName)
+ err := p.db.Query(query).Consistency(gocql.One).Scan(&emailTemplate.ID, &emailTemplate.EventName, &emailTemplate.Subject, &emailTemplate.Design, &emailTemplate.Template, &emailTemplate.CreatedAt, &emailTemplate.UpdatedAt)
if err != nil {
return nil, err
}
diff --git a/server/db/providers/cassandradb/provider.go b/server/db/providers/cassandradb/provider.go
index 0d0b193..5acb656 100644
--- a/server/db/providers/cassandradb/provider.go
+++ b/server/db/providers/cassandradb/provider.go
@@ -224,10 +224,11 @@ func NewProvider() (*provider, error) {
return nil, err
}
// add subject on email_templates table
- emailTemplateAlterQuery := fmt.Sprintf(`ALTER TABLE %s.%s ADD subject text;`, KeySpace, models.Collections.EmailTemplate)
+ emailTemplateAlterQuery := fmt.Sprintf(`ALTER TABLE %s.%s ADD (subject text, design text);`, KeySpace, models.Collections.EmailTemplate)
err = session.Query(emailTemplateAlterQuery).Exec()
if err != nil {
- return nil, err
+ log.Debug("Failed to alter table as column exists: ", err)
+ // continue
}
otpCollection := fmt.Sprintf("CREATE TABLE IF NOT EXISTS %s.%s (id text, email text, otp text, expires_at bigint, updated_at bigint, created_at bigint, PRIMARY KEY (id))", KeySpace, models.Collections.OTP)
diff --git a/server/email/email.go b/server/email/email.go
index 730ae56..fe5f7ff 100644
--- a/server/email/email.go
+++ b/server/email/email.go
@@ -18,7 +18,7 @@ import (
func getDefaultTemplate(event string) *model.EmailTemplate {
switch event {
- case constants.VerificationTypeBasicAuthSignup, constants.VerificationTypeMagicLinkLogin:
+ case constants.VerificationTypeBasicAuthSignup, constants.VerificationTypeMagicLinkLogin, constants.VerificationTypeUpdateEmail:
return &model.EmailTemplate{
Subject: emailVerificationSubject,
Template: emailVerificationTemplate,
diff --git a/server/resolvers/forgot_password.go b/server/resolvers/forgot_password.go
index 77ff265..c04bf1c 100644
--- a/server/resolvers/forgot_password.go
+++ b/server/resolvers/forgot_password.go
@@ -15,6 +15,7 @@ import (
"github.com/authorizerdev/authorizer/server/graph/model"
"github.com/authorizerdev/authorizer/server/memorystore"
"github.com/authorizerdev/authorizer/server/parsers"
+ "github.com/authorizerdev/authorizer/server/refs"
"github.com/authorizerdev/authorizer/server/token"
"github.com/authorizerdev/authorizer/server/utils"
"github.com/authorizerdev/authorizer/server/validators"
@@ -61,9 +62,9 @@ func ForgotPasswordResolver(ctx context.Context, params model.ForgotPasswordInpu
log.Debug("Failed to generate nonce: ", err)
return res, err
}
- redirectURL := parsers.GetAppURL(gc) + "/reset-password"
- if params.RedirectURI != nil {
- redirectURL = *params.RedirectURI
+ redirectURL := parsers.GetAppURL(gc)
+ if strings.TrimSpace(refs.StringValue(params.RedirectURI)) != "" {
+ redirectURL = refs.StringValue(params.RedirectURI)
}
verificationToken, err := token.CreateVerificationToken(params.Email, constants.VerificationTypeForgotPassword, hostname, nonceHash, redirectURL)
diff --git a/server/resolvers/update_profile.go b/server/resolvers/update_profile.go
index 9888aa5..3263974 100644
--- a/server/resolvers/update_profile.go
+++ b/server/resolvers/update_profile.go
@@ -245,7 +245,7 @@ func UpdateProfileResolver(ctx context.Context, params model.UpdateProfileInput)
}
// exec it as go routine so that we can reduce the api latency
- go email.SendEmail([]string{user.Email}, constants.VerificationTypeBasicAuthSignup, map[string]interface{}{
+ go email.SendEmail([]string{user.Email}, verificationType, map[string]interface{}{
"user": user.ToMap(),
"organization": utils.GetOrganization(),
"verification_url": utils.GetEmailVerificationURL(verificationToken, hostname),
diff --git a/server/test/add_email_template_test.go b/server/test/add_email_template_test.go
index 40cf94e..593e4f1 100644
--- a/server/test/add_email_template_test.go
+++ b/server/test/add_email_template_test.go
@@ -31,7 +31,7 @@ func addEmailTemplateTest(t *testing.T, s TestSetup) {
assert.Nil(t, emailTemplate)
})
- t.Run("should not add email template for empty template", func(t *testing.T) {
+ t.Run("should not add email template for empty subject", func(t *testing.T) {
emailTemplate, err := resolvers.AddEmailTemplateResolver(ctx, model.AddEmailTemplateRequest{
EventName: s.TestInfo.TestEmailTemplateEventTypes[0],
Template: " test ",
@@ -50,12 +50,25 @@ func addEmailTemplateTest(t *testing.T, s TestSetup) {
assert.Error(t, err)
assert.Nil(t, emailTemplate)
})
+
+ t.Run("should not add email template with empty design", func(t *testing.T) {
+ emailTemplate, err := resolvers.AddEmailTemplateResolver(ctx, model.AddEmailTemplateRequest{
+ EventName: s.TestInfo.TestEmailTemplateEventTypes[0],
+ Template: "test",
+ Subject: "test",
+ Design: " ",
+ })
+ assert.Error(t, err)
+ assert.Nil(t, emailTemplate)
+ })
+
for _, eventType := range s.TestInfo.TestEmailTemplateEventTypes {
t.Run("should add email template for "+eventType, func(t *testing.T) {
emailTemplate, err := resolvers.AddEmailTemplateResolver(ctx, model.AddEmailTemplateRequest{
EventName: eventType,
Template: "Test email",
Subject: "Test email",
+ Design: "Test design",
})
assert.NoError(t, err)
assert.NotNil(t, emailTemplate)
@@ -65,6 +78,7 @@ func addEmailTemplateTest(t *testing.T, s TestSetup) {
assert.NoError(t, err)
assert.Equal(t, et.EventName, eventType)
assert.Equal(t, "Test email", et.Subject)
+ assert.Equal(t, "Test design", et.Design)
})
}
})
diff --git a/server/test/update_email_template_test.go b/server/test/update_email_template_test.go
index 4f2a999..94b9de5 100644
--- a/server/test/update_email_template_test.go
+++ b/server/test/update_email_template_test.go
@@ -32,6 +32,7 @@ func updateEmailTemplateTest(t *testing.T, s TestSetup) {
ID: emailTemplate.ID,
Template: refs.NewStringRef("Updated test template"),
Subject: refs.NewStringRef("Updated subject"),
+ Design: refs.NewStringRef("Updated design"),
})
assert.NoError(t, err)
@@ -44,5 +45,6 @@ func updateEmailTemplateTest(t *testing.T, s TestSetup) {
assert.Equal(t, emailTemplate.ID, updatedEmailTemplate.ID)
assert.Equal(t, updatedEmailTemplate.Template, "Updated test template")
assert.Equal(t, updatedEmailTemplate.Subject, "Updated subject")
+ assert.Equal(t, updatedEmailTemplate.Design, "Updated design")
})
}