diff --git a/.github/workflows/typos.toml b/.github/workflows/typos.toml index a9748c2d19ea0..b384068e831f2 100644 --- a/.github/workflows/typos.toml +++ b/.github/workflows/typos.toml @@ -41,4 +41,6 @@ extend-exclude = [ "tailnet/testdata/**", "site/src/pages/SetupPage/countries.tsx", "provisioner/terraform/testdata/**", + # notifications' golden files confuse the detector because of quoted-printable encoding + "coderd/notifications/testdata/**" ] diff --git a/coderd/database/migrations/000263_consistent_notification_initiator_naming.down.sql b/coderd/database/migrations/000263_consistent_notification_initiator_naming.down.sql new file mode 100644 index 0000000000000..0e7823a3383dd --- /dev/null +++ b/coderd/database/migrations/000263_consistent_notification_initiator_naming.down.sql @@ -0,0 +1,55 @@ +-- UserAccountCreated +UPDATE notification_templates +SET + body_template = E'Hi {{.UserName}},\n\n' || + E'New user account **{{.Labels.created_account_name}}** has been created.\n\n' || + -- Mention the real name of the user who created the account: + E'This new user account was created for **{{.Labels.created_account_user_name}}** by **{{.Labels.account_creator}}**.' +WHERE + id = '4e19c0ac-94e1-4532-9515-d1801aa283b2'; + +-- UserAccountDeleted +UPDATE notification_templates +SET + body_template = E'Hi {{.UserName}},\n\n' || + E'User account **{{.Labels.deleted_account_name}}** has been deleted.\n\n' || + -- Mention the real name of the user who deleted the account: + E'The deleted account belonged to **{{.Labels.deleted_account_user_name}}** and was deleted by **{{.Labels.account_deleter_user_name}}**.' +WHERE + id = 'f44d9314-ad03-4bc8-95d0-5cad491da6b6'; + +-- UserAccountSuspended +UPDATE notification_templates +SET + body_template = E'Hi {{.UserName}},\n\n' || -- Add a \n + E'User account **{{.Labels.suspended_account_name}}** has been suspended.\n\n' || + -- Mention the real name of the user who suspended the account: + E'The newly suspended account belongs to **{{.Labels.suspended_account_user_name}}** and was suspended by **{{.Labels.account_suspender_user_name}}**.' +WHERE + id = 'b02ddd82-4733-4d02-a2d7-c36f3598997d'; + +-- YourAccountSuspended +UPDATE notification_templates +SET + body_template = E'Hi {{.UserName}},\n\n' || -- Add a \n + E'Your account **{{.Labels.suspended_account_name}}** has been suspended by **{{.Labels.account_suspender_user_name}}**.' +WHERE + id = '6a2f0609-9b69-4d36-a989-9f5925b6cbff'; + + +-- UserAccountActivated +UPDATE notification_templates +SET + body_template = E'Hi {{.UserName}},\n\n' || -- Add a \n + E'User account **{{.Labels.activated_account_name}}** has been activated.\n\n' || + E'The newly activated account belongs to **{{.Labels.activated_account_user_name}}** and was activated by **{{.Labels.account_activator_user_name}}**.' +WHERE + id = '9f5af851-8408-4e73-a7a1-c6502ba46689'; + +-- YourAccountActivated +UPDATE notification_templates +SET + body_template = E'Hi {{.UserName}},\n\n' || -- Add a \n + E'Your account **{{.Labels.activated_account_name}}** has been activated by **{{.Labels.account_activator_user_name}}**.' +WHERE + id = '1a6a6bea-ee0a-43e2-9e7c-eabdb53730e4'; diff --git a/coderd/database/migrations/000263_consistent_notification_initiator_naming.up.sql b/coderd/database/migrations/000263_consistent_notification_initiator_naming.up.sql new file mode 100644 index 0000000000000..1357e7a1ef287 --- /dev/null +++ b/coderd/database/migrations/000263_consistent_notification_initiator_naming.up.sql @@ -0,0 +1,57 @@ +-- UserAccountCreated +UPDATE notification_templates +SET + body_template = E'Hi {{.UserName}},\n\n' || + E'New user account **{{.Labels.created_account_name}}** has been created.\n\n' || + -- Use the conventional initiator label: + E'This new user account was created for **{{.Labels.created_account_user_name}}** by **{{.Labels.initiator}}**.' +WHERE + id = '4e19c0ac-94e1-4532-9515-d1801aa283b2'; + +-- UserAccountDeleted +UPDATE notification_templates +SET + body_template = E'Hi {{.UserName}},\n\n' || + E'User account **{{.Labels.deleted_account_name}}** has been deleted.\n\n' || + -- Use the conventional initiator label: + E'The deleted account belonged to **{{.Labels.deleted_account_user_name}}** and was deleted by **{{.Labels.initiator}}**.' +WHERE + id = 'f44d9314-ad03-4bc8-95d0-5cad491da6b6'; + +-- UserAccountSuspended +UPDATE notification_templates +SET + body_template = E'Hi {{.UserName}},\n\n' || -- Add a \n + E'User account **{{.Labels.suspended_account_name}}** has been suspended.\n\n' || + -- Use the conventional initiator label: + E'The newly suspended account belongs to **{{.Labels.suspended_account_user_name}}** and was suspended by **{{.Labels.initiator}}**.' +WHERE + id = 'b02ddd82-4733-4d02-a2d7-c36f3598997d'; + +-- YourAccountSuspended +UPDATE notification_templates +SET + body_template = E'Hi {{.UserName}},\n\n' || -- Add a \n + -- Use the conventional initiator label: + E'Your account **{{.Labels.suspended_account_name}}** has been suspended by **{{.Labels.initiator}}**.' +WHERE + id = '6a2f0609-9b69-4d36-a989-9f5925b6cbff'; + +-- UserAccountActivated +UPDATE notification_templates +SET + body_template = E'Hi {{.UserName}},\n\n' || -- Add a \n + E'User account **{{.Labels.activated_account_name}}** has been activated.\n\n' || + -- Use the conventional initiator label: + E'The newly activated account belongs to **{{.Labels.activated_account_user_name}}** and was activated by **{{.Labels.initiator}}**.' +WHERE + id = '9f5af851-8408-4e73-a7a1-c6502ba46689'; + +-- YourAccountActivated +UPDATE notification_templates +SET + body_template = E'Hi {{.UserName}},\n\n' || -- Add a \n + -- Use the conventional initiator label: + E'Your account **{{.Labels.activated_account_name}}** has been activated by **{{.Labels.initiator}}**.' +WHERE + id = '1a6a6bea-ee0a-43e2-9e7c-eabdb53730e4'; diff --git a/coderd/notifications/dispatch/smtp_test.go b/coderd/notifications/dispatch/smtp_test.go index eb12f05ad46c7..2687e0d82bb26 100644 --- a/coderd/notifications/dispatch/smtp_test.go +++ b/coderd/notifications/dispatch/smtp_test.go @@ -2,11 +2,8 @@ package dispatch_test import ( "bytes" - "crypto/tls" - _ "embed" "fmt" "log" - "net" "sync" "testing" @@ -22,6 +19,7 @@ import ( "github.com/coder/serpent" "github.com/coder/coder/v2/coderd/notifications/dispatch" + "github.com/coder/coder/v2/coderd/notifications/dispatch/smtptest" "github.com/coder/coder/v2/coderd/notifications/types" "github.com/coder/coder/v2/codersdk" "github.com/coder/coder/v2/testutil" @@ -47,9 +45,9 @@ func TestSMTP(t *testing.T) { subject = "This is the subject" body = "This is the body" - caFile = "fixtures/ca.crt" - certFile = "fixtures/server.crt" - keyFile = "fixtures/server.key" + caFile = "smtptest/fixtures/ca.crt" + certFile = "smtptest/fixtures/server.crt" + keyFile = "smtptest/fixtures/server.key" ) logger := slogtest.Make(t, &slogtest.Options{IgnoreErrors: true, IgnoredErrorIs: []error{}}).Leveled(slog.LevelDebug) @@ -125,7 +123,7 @@ func TestSMTP(t *testing.T) { Auth: codersdk.NotificationsEmailAuthConfig{ Username: username, - PasswordFile: "fixtures/password.txt", + PasswordFile: "smtptest/fixtures/password.txt", }, }, toAddrs: []string{to}, @@ -341,14 +339,14 @@ func TestSMTP(t *testing.T) { cfg: codersdk.NotificationsEmailConfig{ TLS: codersdk.NotificationsEmailTLSConfig{ CAFile: caFile, - CertFile: "fixtures/nope.cert", + CertFile: "smtptest/fixtures/nope.cert", KeyFile: keyFile, }, }, // not using full error message here since it differs on *nix and Windows: // *nix: no such file or directory // Windows: The system cannot find the file specified. - expectedErr: "open fixtures/nope.cert:", + expectedErr: "open smtptest/fixtures/nope.cert:", retryable: true, }, { @@ -358,13 +356,13 @@ func TestSMTP(t *testing.T) { TLS: codersdk.NotificationsEmailTLSConfig{ CAFile: caFile, CertFile: certFile, - KeyFile: "fixtures/nope.key", + KeyFile: "smtptest/fixtures/nope.key", }, }, // not using full error message here since it differs on *nix and Windows: // *nix: no such file or directory // Windows: The system cannot find the file specified. - expectedErr: "open fixtures/nope.key:", + expectedErr: "open smtptest/fixtures/nope.key:", retryable: true, }, /** @@ -417,7 +415,7 @@ func TestSMTP(t *testing.T) { tc.cfg.ForceTLS = serpent.Bool(tc.useTLS) - backend := NewBackend(Config{ + backend := smtptest.NewBackend(smtptest.Config{ AuthMechanisms: tc.authMechs, AcceptedIdentity: tc.cfg.Auth.Identity.String(), @@ -428,7 +426,7 @@ func TestSMTP(t *testing.T) { }) // Create a mock SMTP server which conditionally listens for plain or TLS connections. - srv, listen, err := createMockSMTPServer(backend, tc.useTLS) + srv, listen, err := smtptest.CreateMockSMTPServer(backend, tc.useTLS) require.NoError(t, err) t.Cleanup(func() { // We expect that the server has already been closed in the test @@ -460,7 +458,7 @@ func TestSMTP(t *testing.T) { // Wait for the server to become pingable. require.Eventually(t, func() bool { - cl, err := pingClient(listen, tc.useTLS, tc.cfg.TLS.StartTLS.Value()) + cl, err := smtptest.PingClient(listen, tc.useTLS, tc.cfg.TLS.StartTLS.Value()) if err != nil { t.Logf("smtp not yet dialable: %s", err) return false @@ -522,19 +520,3 @@ func TestSMTP(t *testing.T) { }) } } - -func pingClient(listen net.Listener, useTLS bool, startTLS bool) (*smtp.Client, error) { - tlsCfg := &tls.Config{ - // nolint:gosec // It's a test. - InsecureSkipVerify: true, - } - - switch { - case useTLS: - return smtp.DialTLS(listen.Addr().String(), tlsCfg) - case startTLS: - return smtp.DialStartTLS(listen.Addr().String(), tlsCfg) - default: - return smtp.Dial(listen.Addr().String()) - } -} diff --git a/coderd/notifications/dispatch/fixtures/ca.conf b/coderd/notifications/dispatch/smtptest/fixtures/ca.conf similarity index 100% rename from coderd/notifications/dispatch/fixtures/ca.conf rename to coderd/notifications/dispatch/smtptest/fixtures/ca.conf diff --git a/coderd/notifications/dispatch/fixtures/ca.crt b/coderd/notifications/dispatch/smtptest/fixtures/ca.crt similarity index 100% rename from coderd/notifications/dispatch/fixtures/ca.crt rename to coderd/notifications/dispatch/smtptest/fixtures/ca.crt diff --git a/coderd/notifications/dispatch/fixtures/ca.key b/coderd/notifications/dispatch/smtptest/fixtures/ca.key similarity index 100% rename from coderd/notifications/dispatch/fixtures/ca.key rename to coderd/notifications/dispatch/smtptest/fixtures/ca.key diff --git a/coderd/notifications/dispatch/fixtures/ca.srl b/coderd/notifications/dispatch/smtptest/fixtures/ca.srl similarity index 100% rename from coderd/notifications/dispatch/fixtures/ca.srl rename to coderd/notifications/dispatch/smtptest/fixtures/ca.srl diff --git a/coderd/notifications/dispatch/fixtures/generate.sh b/coderd/notifications/dispatch/smtptest/fixtures/generate.sh similarity index 100% rename from coderd/notifications/dispatch/fixtures/generate.sh rename to coderd/notifications/dispatch/smtptest/fixtures/generate.sh diff --git a/coderd/notifications/dispatch/fixtures/password.txt b/coderd/notifications/dispatch/smtptest/fixtures/password.txt similarity index 100% rename from coderd/notifications/dispatch/fixtures/password.txt rename to coderd/notifications/dispatch/smtptest/fixtures/password.txt diff --git a/coderd/notifications/dispatch/fixtures/server.conf b/coderd/notifications/dispatch/smtptest/fixtures/server.conf similarity index 100% rename from coderd/notifications/dispatch/fixtures/server.conf rename to coderd/notifications/dispatch/smtptest/fixtures/server.conf diff --git a/coderd/notifications/dispatch/fixtures/server.crt b/coderd/notifications/dispatch/smtptest/fixtures/server.crt similarity index 100% rename from coderd/notifications/dispatch/fixtures/server.crt rename to coderd/notifications/dispatch/smtptest/fixtures/server.crt diff --git a/coderd/notifications/dispatch/fixtures/server.csr b/coderd/notifications/dispatch/smtptest/fixtures/server.csr similarity index 100% rename from coderd/notifications/dispatch/fixtures/server.csr rename to coderd/notifications/dispatch/smtptest/fixtures/server.csr diff --git a/coderd/notifications/dispatch/fixtures/server.key b/coderd/notifications/dispatch/smtptest/fixtures/server.key similarity index 100% rename from coderd/notifications/dispatch/fixtures/server.key rename to coderd/notifications/dispatch/smtptest/fixtures/server.key diff --git a/coderd/notifications/dispatch/fixtures/v3_ext.conf b/coderd/notifications/dispatch/smtptest/fixtures/v3_ext.conf similarity index 100% rename from coderd/notifications/dispatch/fixtures/v3_ext.conf rename to coderd/notifications/dispatch/smtptest/fixtures/v3_ext.conf diff --git a/coderd/notifications/dispatch/smtp_util_test.go b/coderd/notifications/dispatch/smtptest/server.go similarity index 90% rename from coderd/notifications/dispatch/smtp_util_test.go rename to coderd/notifications/dispatch/smtptest/server.go index 44cb8725c5d8c..689b4d384036d 100644 --- a/coderd/notifications/dispatch/smtp_util_test.go +++ b/coderd/notifications/dispatch/smtptest/server.go @@ -1,4 +1,4 @@ -package dispatch_test +package smtptest import ( "crypto/tls" @@ -162,7 +162,7 @@ func (*Session) Reset() {} func (*Session) Logout() error { return nil } // nolint:revive // Yes, useTLS is a control flag. -func createMockSMTPServer(be *Backend, useTLS bool) (*smtp.Server, net.Listener, error) { +func CreateMockSMTPServer(be *Backend, useTLS bool) (*smtp.Server, net.Listener, error) { // nolint:gosec tlsCfg := &tls.Config{ GetCertificate: readCert, @@ -203,3 +203,19 @@ func readCert(_ *tls.ClientHelloInfo) (*tls.Certificate, error) { return &crt, nil } + +func PingClient(listen net.Listener, useTLS bool, startTLS bool) (*smtp.Client, error) { + tlsCfg := &tls.Config{ + // nolint:gosec // It's a test. + InsecureSkipVerify: true, + } + + switch { + case useTLS: + return smtp.DialTLS(listen.Addr().String(), tlsCfg) + case startTLS: + return smtp.DialStartTLS(listen.Addr().String(), tlsCfg) + default: + return smtp.Dial(listen.Addr().String()) + } +} diff --git a/coderd/notifications/notifications_test.go b/coderd/notifications/notifications_test.go index 28bd8b5190c71..d6eb480f75c9b 100644 --- a/coderd/notifications/notifications_test.go +++ b/coderd/notifications/notifications_test.go @@ -10,11 +10,13 @@ import ( "go/ast" "go/parser" "go/token" + "io" "net/http" "net/http/httptest" "net/url" "os" "path/filepath" + "regexp" "slices" "sort" "strings" @@ -23,18 +25,16 @@ import ( "testing" "time" - "golang.org/x/xerrors" - - "github.com/coder/quartz" - + "github.com/emersion/go-sasl" + "github.com/google/go-cmp/cmp" "github.com/google/uuid" smtpmock "github.com/mocktools/go-smtp-mock/v2" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" "go.uber.org/goleak" + "golang.org/x/xerrors" - "github.com/coder/serpent" - + "cdr.dev/slog" "github.com/coder/coder/v2/coderd/coderdtest" "github.com/coder/coder/v2/coderd/database" "github.com/coder/coder/v2/coderd/database/dbauthz" @@ -42,12 +42,14 @@ import ( "github.com/coder/coder/v2/coderd/database/dbtestutil" "github.com/coder/coder/v2/coderd/notifications" "github.com/coder/coder/v2/coderd/notifications/dispatch" - "github.com/coder/coder/v2/coderd/notifications/render" + "github.com/coder/coder/v2/coderd/notifications/dispatch/smtptest" "github.com/coder/coder/v2/coderd/notifications/types" "github.com/coder/coder/v2/coderd/rbac" "github.com/coder/coder/v2/coderd/util/syncmap" "github.com/coder/coder/v2/codersdk" "github.com/coder/coder/v2/testutil" + "github.com/coder/quartz" + "github.com/coder/serpent" ) // updateGoldenFiles is a flag that can be set to update golden files. @@ -691,6 +693,16 @@ func TestNotificationTemplates_Golden(t *testing.T) { t.Skip("This test requires postgres; it relies on the notification templates added by migrations in the database") } + const ( + username = "bob" + password = "🤫" + + hello = "localhost" + + from = "system@coder.com" + hint = "run \"DB=ci make update-golden-files\" and commit the changes" + ) + tests := []struct { name string id uuid.UUID @@ -700,7 +712,9 @@ func TestNotificationTemplates_Golden(t *testing.T) { name: "TemplateWorkspaceDeleted", id: notifications.TemplateWorkspaceDeleted, payload: types.MessagePayload{ - UserName: "Bobby", + UserName: "Bobby", + UserEmail: "bobby@coder.com", + UserUsername: "bobby", Labels: map[string]string{ "name": "bobby-workspace", "reason": "autodeleted due to dormancy", @@ -712,7 +726,9 @@ func TestNotificationTemplates_Golden(t *testing.T) { name: "TemplateWorkspaceAutobuildFailed", id: notifications.TemplateWorkspaceAutobuildFailed, payload: types.MessagePayload{ - UserName: "Bobby", + UserName: "Bobby", + UserEmail: "bobby@coder.com", + UserUsername: "bobby", Labels: map[string]string{ "name": "bobby-workspace", "reason": "autostart", @@ -723,7 +739,9 @@ func TestNotificationTemplates_Golden(t *testing.T) { name: "TemplateWorkspaceDormant", id: notifications.TemplateWorkspaceDormant, payload: types.MessagePayload{ - UserName: "Bobby", + UserName: "Bobby", + UserEmail: "bobby@coder.com", + UserUsername: "bobby", Labels: map[string]string{ "name": "bobby-workspace", "reason": "breached the template's threshold for inactivity", @@ -737,7 +755,9 @@ func TestNotificationTemplates_Golden(t *testing.T) { name: "TemplateWorkspaceAutoUpdated", id: notifications.TemplateWorkspaceAutoUpdated, payload: types.MessagePayload{ - UserName: "Bobby", + UserName: "Bobby", + UserEmail: "bobby@coder.com", + UserUsername: "bobby", Labels: map[string]string{ "name": "bobby-workspace", "template_version_name": "1.0", @@ -749,7 +769,9 @@ func TestNotificationTemplates_Golden(t *testing.T) { name: "TemplateWorkspaceMarkedForDeletion", id: notifications.TemplateWorkspaceMarkedForDeletion, payload: types.MessagePayload{ - UserName: "Bobby", + UserName: "Bobby", + UserEmail: "bobby@coder.com", + UserUsername: "bobby", Labels: map[string]string{ "name": "bobby-workspace", "reason": "template updated to new dormancy policy", @@ -762,11 +784,13 @@ func TestNotificationTemplates_Golden(t *testing.T) { name: "TemplateUserAccountCreated", id: notifications.TemplateUserAccountCreated, payload: types.MessagePayload{ - UserName: "Bobby", + UserName: "Bobby", + UserEmail: "bobby@coder.com", + UserUsername: "bobby", Labels: map[string]string{ "created_account_name": "bobby", "created_account_user_name": "William Tables", - "account_creator": "rob", + "initiator": "rob", }, }, }, @@ -774,11 +798,13 @@ func TestNotificationTemplates_Golden(t *testing.T) { name: "TemplateUserAccountDeleted", id: notifications.TemplateUserAccountDeleted, payload: types.MessagePayload{ - UserName: "Bobby", + UserName: "Bobby", + UserEmail: "bobby@coder.com", + UserUsername: "bobby", Labels: map[string]string{ "deleted_account_name": "bobby", - "deleted_account_user_name": "william tables", - "account_deleter_user_name": "rob", + "deleted_account_user_name": "William Tables", + "initiator": "rob", }, }, }, @@ -786,11 +812,13 @@ func TestNotificationTemplates_Golden(t *testing.T) { name: "TemplateUserAccountSuspended", id: notifications.TemplateUserAccountSuspended, payload: types.MessagePayload{ - UserName: "Bobby", + UserName: "Bobby", + UserEmail: "bobby@coder.com", + UserUsername: "bobby", Labels: map[string]string{ "suspended_account_name": "bobby", - "suspended_account_user_name": "william tables", - "account_suspender_user_name": "rob", + "suspended_account_user_name": "William Tables", + "initiator": "rob", }, }, }, @@ -798,11 +826,13 @@ func TestNotificationTemplates_Golden(t *testing.T) { name: "TemplateUserAccountActivated", id: notifications.TemplateUserAccountActivated, payload: types.MessagePayload{ - UserName: "Bobby", + UserName: "Bobby", + UserEmail: "bobby@coder.com", + UserUsername: "bobby", Labels: map[string]string{ "activated_account_name": "bobby", - "activated_account_user_name": "william tables", - "account_activator_user_name": "rob", + "activated_account_user_name": "William Tables", + "initiator": "rob", }, }, }, @@ -810,10 +840,12 @@ func TestNotificationTemplates_Golden(t *testing.T) { name: "TemplateYourAccountSuspended", id: notifications.TemplateYourAccountSuspended, payload: types.MessagePayload{ - UserName: "Bobby", + UserName: "Bobby", + UserEmail: "bobby@coder.com", + UserUsername: "bobby", Labels: map[string]string{ - "suspended_account_name": "bobby", - "account_suspender_user_name": "rob", + "suspended_account_name": "bobby", + "initiator": "rob", }, }, }, @@ -821,10 +853,12 @@ func TestNotificationTemplates_Golden(t *testing.T) { name: "TemplateYourAccountActivated", id: notifications.TemplateYourAccountActivated, payload: types.MessagePayload{ - UserName: "Bobby", + UserName: "Bobby", + UserEmail: "bobby@coder.com", + UserUsername: "bobby", Labels: map[string]string{ - "activated_account_name": "bobby", - "account_activator_user_name": "rob", + "activated_account_name": "bobby", + "initiator": "rob", }, }, }, @@ -832,7 +866,9 @@ func TestNotificationTemplates_Golden(t *testing.T) { name: "TemplateTemplateDeleted", id: notifications.TemplateTemplateDeleted, payload: types.MessagePayload{ - UserName: "Bobby", + UserName: "Bobby", + UserEmail: "bobby@coder.com", + UserUsername: "bobby", Labels: map[string]string{ "name": "bobby-template", "display_name": "Bobby's Template", @@ -844,7 +880,9 @@ func TestNotificationTemplates_Golden(t *testing.T) { name: "TemplateWorkspaceManualBuildFailed", id: notifications.TemplateWorkspaceManualBuildFailed, payload: types.MessagePayload{ - UserName: "Bobby", + UserName: "Bobby", + UserEmail: "bobby@coder.com", + UserUsername: "bobby", Labels: map[string]string{ "name": "bobby-workspace", "template_name": "bobby-template", @@ -860,7 +898,9 @@ func TestNotificationTemplates_Golden(t *testing.T) { name: "TemplateWorkspaceBuildsFailedReport", id: notifications.TemplateWorkspaceBuildsFailedReport, payload: types.MessagePayload{ - UserName: "Bobby", + UserName: "Bobby", + UserEmail: "bobby@coder.com", + UserUsername: "bobby", Labels: map[string]string{ "template_name": "bobby-first-template", "template_display_name": "Bobby First Template", @@ -911,7 +951,9 @@ func TestNotificationTemplates_Golden(t *testing.T) { name: "TemplateUserRequestedOneTimePasscode", id: notifications.TemplateUserRequestedOneTimePasscode, payload: types.MessagePayload{ - UserName: "Bobby", + UserName: "Bobby", + UserEmail: "bobby@coder.com", + UserUsername: "bobby", Labels: map[string]string{ "one_time_passcode": "fad9020b-6562-4cdb-87f1-0486f1bea415", }, @@ -919,6 +961,7 @@ func TestNotificationTemplates_Golden(t *testing.T) { }, } + // We must have a test case for every notification_template. This is enforced below: allTemplates, err := enumerateAllTemplates(t) require.NoError(t, err) for _, name := range allTemplates { @@ -938,53 +981,303 @@ func TestNotificationTemplates_Golden(t *testing.T) { t.Run(tc.name, func(t *testing.T) { t.Parallel() - _, _, sql := dbtestutil.NewDBWithSQLDB(t) - - var ( - titleTmpl string - bodyTmpl string - ) - err := sql. - QueryRow("SELECT title_template, body_template FROM notification_templates WHERE id = $1 LIMIT 1", tc.id). - Scan(&titleTmpl, &bodyTmpl) - require.NoError(t, err, "failed to query body template for template:", tc.id) - - title, err := render.GoTemplate(titleTmpl, tc.payload, defaultHelpers()) - require.NotContainsf(t, title, render.NoValue, "template %q is missing a label value", tc.name) - require.NoError(t, err, "failed to render notification title template") - require.NotEmpty(t, title, "title should not be empty") - - body, err := render.GoTemplate(bodyTmpl, tc.payload, defaultHelpers()) - require.NoError(t, err, "failed to render notification body template") - require.NotEmpty(t, body, "body should not be empty") - - partialName := strings.Split(t.Name(), "/")[1] - bodyGoldenFile := filepath.Join("testdata", "rendered-templates", partialName+"-body.md.golden") - titleGoldenFile := filepath.Join("testdata", "rendered-templates", partialName+"-title.md.golden") - - if *updateGoldenFiles { - err = os.MkdirAll(filepath.Dir(bodyGoldenFile), 0o755) - require.NoError(t, err, "want no error creating golden file directory") - err = os.WriteFile(bodyGoldenFile, []byte(body), 0o600) - require.NoError(t, err, "want no error writing body golden file") - err = os.WriteFile(titleGoldenFile, []byte(title), 0o600) - require.NoError(t, err, "want no error writing title golden file") - return - } + t.Run("smtp", func(t *testing.T) { + t.Parallel() + + // Spin up the DB + db, logger, user := func() (*database.Store, *slog.Logger, *codersdk.User) { + adminClient, _, api := coderdtest.NewWithAPI(t, nil) + db := api.Database + firstUser := coderdtest.CreateFirstUser(t, adminClient) + + _, user := coderdtest.CreateAnotherUserMutators( + t, + adminClient, + firstUser.OrganizationID, + []rbac.RoleIdentifier{rbac.RoleUserAdmin()}, + func(r *codersdk.CreateUserRequestWithOrgs) { + r.Username = tc.payload.UserUsername + r.Email = tc.payload.UserEmail + r.Name = tc.payload.UserName + }, + ) + return &db, &api.Logger, &user + }() - const hint = "run \"DB=ci make update-golden-files\" and commit the changes" + // nolint:gocritic // Unit test. + ctx := dbauthz.AsSystemRestricted(testutil.Context(t, testutil.WaitSuperLong)) - wantBody, err := os.ReadFile(bodyGoldenFile) - require.NoError(t, err, fmt.Sprintf("missing golden notification body file. %s", hint)) - wantTitle, err := os.ReadFile(titleGoldenFile) - require.NoError(t, err, fmt.Sprintf("missing golden notification title file. %s", hint)) + // smtp config shared between client and server + smtpConfig := codersdk.NotificationsEmailConfig{ + Hello: hello, + From: from, - require.Equal(t, string(wantBody), body, fmt.Sprintf("rendered template body does not match golden file. If this is expected, %s", hint)) - require.Equal(t, string(wantTitle), title, fmt.Sprintf("rendered template title does not match golden file. If this is expected, %s", hint)) + Auth: codersdk.NotificationsEmailAuthConfig{ + Username: username, + Password: password, + }, + } + + // Spin up the mock SMTP server + backend := smtptest.NewBackend(smtptest.Config{ + AuthMechanisms: []string{sasl.Login}, + + AcceptedIdentity: smtpConfig.Auth.Identity.String(), + AcceptedUsername: username, + AcceptedPassword: password, + }) + + // Create a mock SMTP server which conditionally listens for plain or TLS connections. + srv, listen, err := smtptest.CreateMockSMTPServer(backend, false) + require.NoError(t, err) + t.Cleanup(func() { + err := srv.Shutdown(ctx) + require.NoError(t, err) + }) + + var hp serpent.HostPort + require.NoError(t, hp.Set(listen.Addr().String())) + smtpConfig.Smarthost = hp + + // Start mock SMTP server in the background. + var wg sync.WaitGroup + wg.Add(1) + go func() { + defer wg.Done() + assert.NoError(t, srv.Serve(listen)) + }() + + // Wait for the server to become pingable. + require.Eventually(t, func() bool { + cl, err := smtptest.PingClient(listen, false, smtpConfig.TLS.StartTLS.Value()) + if err != nil { + t.Logf("smtp not yet dialable: %s", err) + return false + } + + if err = cl.Noop(); err != nil { + t.Logf("smtp not yet noopable: %s", err) + return false + } + + if err = cl.Close(); err != nil { + t.Logf("smtp didn't close properly: %s", err) + return false + } + + return true + }, testutil.WaitShort, testutil.IntervalFast) + + smtpCfg := defaultNotificationsConfig(database.NotificationMethodSmtp) + smtpCfg.SMTP = smtpConfig + + smtpManager, err := notifications.NewManager( + smtpCfg, + *db, + defaultHelpers(), + createMetrics(), + logger.Named("manager"), + ) + require.NoError(t, err) + + smtpManager.Run(ctx) + + notificationCfg := defaultNotificationsConfig(database.NotificationMethodSmtp) + + smtpEnqueuer, err := notifications.NewStoreEnqueuer( + notificationCfg, + *db, + defaultHelpers(), + logger.Named("enqueuer"), + quartz.NewReal(), + ) + require.NoError(t, err) + + _, err = smtpEnqueuer.EnqueueWithData( + ctx, + user.ID, + tc.id, + tc.payload.Labels, + tc.payload.Data, + user.Username, + user.ID, + ) + require.NoError(t, err) + + // Wait for the message to be fetched + var msg *smtptest.Message + require.Eventually(t, func() bool { + msg = backend.LastMessage() + return msg != nil && len(msg.Contents) > 0 + }, testutil.WaitShort, testutil.IntervalFast) + + body := normalizeGoldenEmail([]byte(msg.Contents)) + + err = smtpManager.Stop(ctx) + require.NoError(t, err) + + partialName := strings.Split(t.Name(), "/")[1] + goldenFile := filepath.Join("testdata", "rendered-templates", "smtp", partialName+".html.golden") + if *updateGoldenFiles { + err = os.MkdirAll(filepath.Dir(goldenFile), 0o755) + require.NoError(t, err, "want no error creating golden file directory") + err = os.WriteFile(goldenFile, body, 0o600) + require.NoError(t, err, "want no error writing body golden file") + return + } + + wantBody, err := os.ReadFile(goldenFile) + require.NoError(t, err, fmt.Sprintf("missing golden notification body file. %s", hint)) + require.Empty( + t, + cmp.Diff(wantBody, body), + fmt.Sprintf("golden file mismatch: %s. If this is expected, %s. (-want +got). ", goldenFile, hint), + ) + }) + + t.Run("webhook", func(t *testing.T) { + t.Parallel() + + // Spin up the DB + db, logger, user := func() (*database.Store, *slog.Logger, *codersdk.User) { + adminClient, _, api := coderdtest.NewWithAPI(t, nil) + db := api.Database + firstUser := coderdtest.CreateFirstUser(t, adminClient) + + _, user := coderdtest.CreateAnotherUserMutators( + t, + adminClient, + firstUser.OrganizationID, + []rbac.RoleIdentifier{rbac.RoleUserAdmin()}, + func(r *codersdk.CreateUserRequestWithOrgs) { + r.Username = tc.payload.UserUsername + r.Email = tc.payload.UserEmail + r.Name = tc.payload.UserName + }, + ) + return &db, &api.Logger, &user + }() + + // nolint:gocritic // Unit test. + ctx := dbauthz.AsSystemRestricted(testutil.Context(t, testutil.WaitSuperLong)) + + // Spin up the mock webhook server + var body []byte + var readErr error + var webhookReceived bool + server := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { + w.WriteHeader(http.StatusOK) + + body, readErr = io.ReadAll(r.Body) + webhookReceived = true + })) + t.Cleanup(server.Close) + + endpoint, err := url.Parse(server.URL) + require.NoError(t, err) + + webhookCfg := defaultNotificationsConfig(database.NotificationMethodWebhook) + + webhookCfg.Webhook = codersdk.NotificationsWebhookConfig{ + Endpoint: *serpent.URLOf(endpoint), + } + + webhookManager, err := notifications.NewManager( + webhookCfg, + *db, + defaultHelpers(), + createMetrics(), + logger.Named("manager"), + ) + require.NoError(t, err) + + webhookManager.Run(ctx) + + httpEnqueuer, err := notifications.NewStoreEnqueuer( + defaultNotificationsConfig(database.NotificationMethodWebhook), + *db, + defaultHelpers(), + logger.Named("enqueuer"), + quartz.NewReal(), + ) + require.NoError(t, err) + + _, err = httpEnqueuer.EnqueueWithData( + ctx, + user.ID, + tc.id, + tc.payload.Labels, + tc.payload.Data, + user.Username, + user.ID, + ) + require.NoError(t, err) + + require.Eventually(t, func() bool { + return webhookReceived + }, testutil.WaitShort, testutil.IntervalFast) + + require.NoError(t, err) + + // Handle the body that was read in the http server here. + // We need to do it here because we can't call require.* in a separate goroutine, such as the http server handler + require.NoError(t, readErr) + var prettyJSON bytes.Buffer + err = json.Indent(&prettyJSON, body, "", " ") + require.NoError(t, err) + + content := normalizeGoldenWebhook(prettyJSON.Bytes()) + + partialName := strings.Split(t.Name(), "/")[1] + goldenFile := filepath.Join("testdata", "rendered-templates", "webhook", partialName+".json.golden") + if *updateGoldenFiles { + err = os.MkdirAll(filepath.Dir(goldenFile), 0o755) + require.NoError(t, err, "want no error creating golden file directory") + err = os.WriteFile(goldenFile, content, 0o600) + require.NoError(t, err, "want no error writing body golden file") + return + } + + wantBody, err := os.ReadFile(goldenFile) + require.NoError(t, err, fmt.Sprintf("missing golden notification body file. %s", hint)) + require.Equal(t, wantBody, content, fmt.Sprintf("smtp notification does not match golden file. If this is expected, %s", hint)) + }) }) } } +func normalizeGoldenEmail(content []byte) []byte { + const ( + constantDate = "Fri, 11 Oct 2024 09:03:06 +0000" + constantMessageID = "02ee4935-73be-4fa1-a290-ff9999026b13@blush-whale-48" + constantBoundary = "bbe61b741255b6098bb6b3c1f41b885773df633cb18d2a3002b68e4bc9c4" + ) + + dateRegex := regexp.MustCompile(`Date: .+`) + messageIDRegex := regexp.MustCompile(`Message-Id: .+`) + boundaryRegex := regexp.MustCompile(`boundary=([0-9a-zA-Z]+)`) + submatches := boundaryRegex.FindSubmatch(content) + if len(submatches) == 0 { + return content + } + + boundary := submatches[1] + + content = dateRegex.ReplaceAll(content, []byte("Date: "+constantDate)) + content = messageIDRegex.ReplaceAll(content, []byte("Message-Id: "+constantMessageID)) + content = bytes.ReplaceAll(content, boundary, []byte(constantBoundary)) + + return content +} + +func normalizeGoldenWebhook(content []byte) []byte { + const constantUUID = "00000000-0000-0000-0000-000000000000" + uuidRegex := regexp.MustCompile(`[0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{12}`) + content = uuidRegex.ReplaceAll(content, []byte(constantUUID)) + + return content +} + // TestDisabledBeforeEnqueue ensures that notifications cannot be enqueued once a user has disabled that notification template func TestDisabledBeforeEnqueue(t *testing.T) { t.Parallel() diff --git a/coderd/notifications/testdata/rendered-templates/TemplateTemplateDeleted-body.md.golden b/coderd/notifications/testdata/rendered-templates/TemplateTemplateDeleted-body.md.golden deleted file mode 100644 index ade9c87ff791a..0000000000000 --- a/coderd/notifications/testdata/rendered-templates/TemplateTemplateDeleted-body.md.golden +++ /dev/null @@ -1,5 +0,0 @@ -Hi Bobby, - -The template **bobby-template** was deleted by **rob**. - -The template's display name was **Bobby's Template**. \ No newline at end of file diff --git a/coderd/notifications/testdata/rendered-templates/TemplateTemplateDeleted-title.md.golden b/coderd/notifications/testdata/rendered-templates/TemplateTemplateDeleted-title.md.golden deleted file mode 100644 index c3f3db7645422..0000000000000 --- a/coderd/notifications/testdata/rendered-templates/TemplateTemplateDeleted-title.md.golden +++ /dev/null @@ -1 +0,0 @@ -Template "bobby-template" deleted \ No newline at end of file diff --git a/coderd/notifications/testdata/rendered-templates/TemplateUserAccountActivated-body.md.golden b/coderd/notifications/testdata/rendered-templates/TemplateUserAccountActivated-body.md.golden deleted file mode 100644 index 5a773a51dc181..0000000000000 --- a/coderd/notifications/testdata/rendered-templates/TemplateUserAccountActivated-body.md.golden +++ /dev/null @@ -1,5 +0,0 @@ -Hi Bobby, - -User account **bobby** has been activated. - -The newly activated account belongs to **william tables** and was activated by **rob**. \ No newline at end of file diff --git a/coderd/notifications/testdata/rendered-templates/TemplateUserAccountActivated-title.md.golden b/coderd/notifications/testdata/rendered-templates/TemplateUserAccountActivated-title.md.golden deleted file mode 100644 index ebf8e9da36934..0000000000000 --- a/coderd/notifications/testdata/rendered-templates/TemplateUserAccountActivated-title.md.golden +++ /dev/null @@ -1 +0,0 @@ -User account "bobby" activated \ No newline at end of file diff --git a/coderd/notifications/testdata/rendered-templates/TemplateUserAccountCreated-body.md.golden b/coderd/notifications/testdata/rendered-templates/TemplateUserAccountCreated-body.md.golden deleted file mode 100644 index 88a46735f0483..0000000000000 --- a/coderd/notifications/testdata/rendered-templates/TemplateUserAccountCreated-body.md.golden +++ /dev/null @@ -1,5 +0,0 @@ -Hi Bobby, - -New user account **bobby** has been created. - -This new user account was created for **William Tables** by **rob**. \ No newline at end of file diff --git a/coderd/notifications/testdata/rendered-templates/TemplateUserAccountCreated-title.md.golden b/coderd/notifications/testdata/rendered-templates/TemplateUserAccountCreated-title.md.golden deleted file mode 100644 index bfcdf6826f772..0000000000000 --- a/coderd/notifications/testdata/rendered-templates/TemplateUserAccountCreated-title.md.golden +++ /dev/null @@ -1 +0,0 @@ -User account "bobby" created \ No newline at end of file diff --git a/coderd/notifications/testdata/rendered-templates/TemplateUserAccountDeleted-body.md.golden b/coderd/notifications/testdata/rendered-templates/TemplateUserAccountDeleted-body.md.golden deleted file mode 100644 index 4ca8bedd0ca52..0000000000000 --- a/coderd/notifications/testdata/rendered-templates/TemplateUserAccountDeleted-body.md.golden +++ /dev/null @@ -1,5 +0,0 @@ -Hi Bobby, - -User account **bobby** has been deleted. - -The deleted account belonged to **william tables** and was deleted by **rob**. \ No newline at end of file diff --git a/coderd/notifications/testdata/rendered-templates/TemplateUserAccountDeleted-title.md.golden b/coderd/notifications/testdata/rendered-templates/TemplateUserAccountDeleted-title.md.golden deleted file mode 100644 index 199d4ddd66d12..0000000000000 --- a/coderd/notifications/testdata/rendered-templates/TemplateUserAccountDeleted-title.md.golden +++ /dev/null @@ -1 +0,0 @@ -User account "bobby" deleted \ No newline at end of file diff --git a/coderd/notifications/testdata/rendered-templates/TemplateUserAccountSuspended-body.md.golden b/coderd/notifications/testdata/rendered-templates/TemplateUserAccountSuspended-body.md.golden deleted file mode 100644 index ecf276504ebc9..0000000000000 --- a/coderd/notifications/testdata/rendered-templates/TemplateUserAccountSuspended-body.md.golden +++ /dev/null @@ -1,5 +0,0 @@ -Hi Bobby, - -User account **bobby** has been suspended. - -The newly suspended account belongs to **william tables** and was suspended by **rob**. \ No newline at end of file diff --git a/coderd/notifications/testdata/rendered-templates/TemplateUserAccountSuspended-title.md.golden b/coderd/notifications/testdata/rendered-templates/TemplateUserAccountSuspended-title.md.golden deleted file mode 100644 index f2be8e201f0af..0000000000000 --- a/coderd/notifications/testdata/rendered-templates/TemplateUserAccountSuspended-title.md.golden +++ /dev/null @@ -1 +0,0 @@ -User account "bobby" suspended \ No newline at end of file diff --git a/coderd/notifications/testdata/rendered-templates/TemplateUserRequestedOneTimePasscode-body.md.golden b/coderd/notifications/testdata/rendered-templates/TemplateUserRequestedOneTimePasscode-body.md.golden deleted file mode 100644 index 6288af33f867e..0000000000000 --- a/coderd/notifications/testdata/rendered-templates/TemplateUserRequestedOneTimePasscode-body.md.golden +++ /dev/null @@ -1,7 +0,0 @@ -Hi Bobby, - -A request to reset the password for your Coder account has been made. Your one-time passcode is: - -**fad9020b-6562-4cdb-87f1-0486f1bea415** - -If you did not request to reset your password, you can ignore this message. \ No newline at end of file diff --git a/coderd/notifications/testdata/rendered-templates/TemplateUserRequestedOneTimePasscode-title.md.golden b/coderd/notifications/testdata/rendered-templates/TemplateUserRequestedOneTimePasscode-title.md.golden deleted file mode 100644 index ecf7383911053..0000000000000 --- a/coderd/notifications/testdata/rendered-templates/TemplateUserRequestedOneTimePasscode-title.md.golden +++ /dev/null @@ -1 +0,0 @@ -Your One-Time Passcode for Coder. \ No newline at end of file diff --git a/coderd/notifications/testdata/rendered-templates/TemplateWorkspaceAutoUpdated-body.md.golden b/coderd/notifications/testdata/rendered-templates/TemplateWorkspaceAutoUpdated-body.md.golden deleted file mode 100644 index d9f4e27cb4c6e..0000000000000 --- a/coderd/notifications/testdata/rendered-templates/TemplateWorkspaceAutoUpdated-body.md.golden +++ /dev/null @@ -1,5 +0,0 @@ -Hi Bobby, - -Your workspace **bobby-workspace** has been updated automatically to the latest template version (1.0). - -Reason for update: **template now includes catnip**. \ No newline at end of file diff --git a/coderd/notifications/testdata/rendered-templates/TemplateWorkspaceAutoUpdated-title.md.golden b/coderd/notifications/testdata/rendered-templates/TemplateWorkspaceAutoUpdated-title.md.golden deleted file mode 100644 index fb62dcd0d3692..0000000000000 --- a/coderd/notifications/testdata/rendered-templates/TemplateWorkspaceAutoUpdated-title.md.golden +++ /dev/null @@ -1 +0,0 @@ -Workspace "bobby-workspace" updated automatically \ No newline at end of file diff --git a/coderd/notifications/testdata/rendered-templates/TemplateWorkspaceAutobuildFailed-body.md.golden b/coderd/notifications/testdata/rendered-templates/TemplateWorkspaceAutobuildFailed-body.md.golden deleted file mode 100644 index cddf2149d0d46..0000000000000 --- a/coderd/notifications/testdata/rendered-templates/TemplateWorkspaceAutobuildFailed-body.md.golden +++ /dev/null @@ -1,5 +0,0 @@ -Hi Bobby, - -Automatic build of your workspace **bobby-workspace** failed. - -The specified reason was "**autostart**". \ No newline at end of file diff --git a/coderd/notifications/testdata/rendered-templates/TemplateWorkspaceAutobuildFailed-title.md.golden b/coderd/notifications/testdata/rendered-templates/TemplateWorkspaceAutobuildFailed-title.md.golden deleted file mode 100644 index 9cf98bc9e546a..0000000000000 --- a/coderd/notifications/testdata/rendered-templates/TemplateWorkspaceAutobuildFailed-title.md.golden +++ /dev/null @@ -1 +0,0 @@ -Workspace "bobby-workspace" autobuild failed \ No newline at end of file diff --git a/coderd/notifications/testdata/rendered-templates/TemplateWorkspaceBuildsFailedReport-body.md.golden b/coderd/notifications/testdata/rendered-templates/TemplateWorkspaceBuildsFailedReport-body.md.golden deleted file mode 100644 index e896a0a8c9e51..0000000000000 --- a/coderd/notifications/testdata/rendered-templates/TemplateWorkspaceBuildsFailedReport-body.md.golden +++ /dev/null @@ -1,17 +0,0 @@ -Hi Bobby, - -Template **Bobby First Template** has failed to build 4/55 times over the last week. - -**Report:** - -**bobby-template-version-1** failed 3 times: - -* [mtojek / workspace-1 / #1234](http://test.com/@mtojek/workspace-1/builds/1234) -* [johndoe / my-workspace-3 / #5678](http://test.com/@johndoe/my-workspace-3/builds/5678) -* [jack / workwork / #774](http://test.com/@jack/workwork/builds/774) - -**bobby-template-version-2** failed 1 time: - -* [ben / cool-workspace / #8888](http://test.com/@ben/cool-workspace/builds/8888) - -We recommend reviewing these issues to ensure future builds are successful. \ No newline at end of file diff --git a/coderd/notifications/testdata/rendered-templates/TemplateWorkspaceBuildsFailedReport-title.md.golden b/coderd/notifications/testdata/rendered-templates/TemplateWorkspaceBuildsFailedReport-title.md.golden deleted file mode 100644 index f03f8fca96c7c..0000000000000 --- a/coderd/notifications/testdata/rendered-templates/TemplateWorkspaceBuildsFailedReport-title.md.golden +++ /dev/null @@ -1 +0,0 @@ -Workspace builds failed for template "Bobby First Template" \ No newline at end of file diff --git a/coderd/notifications/testdata/rendered-templates/TemplateWorkspaceDeleted-body.md.golden b/coderd/notifications/testdata/rendered-templates/TemplateWorkspaceDeleted-body.md.golden deleted file mode 100644 index a5c71fb3e0170..0000000000000 --- a/coderd/notifications/testdata/rendered-templates/TemplateWorkspaceDeleted-body.md.golden +++ /dev/null @@ -1,5 +0,0 @@ -Hi Bobby, - -Your workspace **bobby-workspace** was deleted. - -The specified reason was "**autodeleted due to dormancy (autobuild)**". \ No newline at end of file diff --git a/coderd/notifications/testdata/rendered-templates/TemplateWorkspaceDeleted-title.md.golden b/coderd/notifications/testdata/rendered-templates/TemplateWorkspaceDeleted-title.md.golden deleted file mode 100644 index 6806624053eb9..0000000000000 --- a/coderd/notifications/testdata/rendered-templates/TemplateWorkspaceDeleted-title.md.golden +++ /dev/null @@ -1 +0,0 @@ -Workspace "bobby-workspace" deleted \ No newline at end of file diff --git a/coderd/notifications/testdata/rendered-templates/TemplateWorkspaceDormant-body.md.golden b/coderd/notifications/testdata/rendered-templates/TemplateWorkspaceDormant-body.md.golden deleted file mode 100644 index 35bfe8d2c19b6..0000000000000 --- a/coderd/notifications/testdata/rendered-templates/TemplateWorkspaceDormant-body.md.golden +++ /dev/null @@ -1,5 +0,0 @@ -Hi Bobby, - -Your workspace **bobby-workspace** has been marked as [**dormant**](https://coder.com/docs/templates/schedule#dormancy-threshold-enterprise) because of breached the template's threshold for inactivity. -Dormant workspaces are [automatically deleted](https://coder.com/docs/templates/schedule#dormancy-auto-deletion-enterprise) after 24 hours of inactivity. -To prevent deletion, use your workspace with the link below. \ No newline at end of file diff --git a/coderd/notifications/testdata/rendered-templates/TemplateWorkspaceDormant-title.md.golden b/coderd/notifications/testdata/rendered-templates/TemplateWorkspaceDormant-title.md.golden deleted file mode 100644 index ce34a2a029ab4..0000000000000 --- a/coderd/notifications/testdata/rendered-templates/TemplateWorkspaceDormant-title.md.golden +++ /dev/null @@ -1 +0,0 @@ -Workspace "bobby-workspace" marked as dormant \ No newline at end of file diff --git a/coderd/notifications/testdata/rendered-templates/TemplateWorkspaceManualBuildFailed-body.md.golden b/coderd/notifications/testdata/rendered-templates/TemplateWorkspaceManualBuildFailed-body.md.golden deleted file mode 100644 index e1091b2888830..0000000000000 --- a/coderd/notifications/testdata/rendered-templates/TemplateWorkspaceManualBuildFailed-body.md.golden +++ /dev/null @@ -1,5 +0,0 @@ -Hi Bobby, - -A manual build of the workspace **bobby-workspace** using the template **bobby-template** failed (version: **bobby-template-version**). - -The template's display name was **William's Template**. The workspace build was initiated by **joe**. \ No newline at end of file diff --git a/coderd/notifications/testdata/rendered-templates/TemplateWorkspaceManualBuildFailed-title.md.golden b/coderd/notifications/testdata/rendered-templates/TemplateWorkspaceManualBuildFailed-title.md.golden deleted file mode 100644 index e786626b74672..0000000000000 --- a/coderd/notifications/testdata/rendered-templates/TemplateWorkspaceManualBuildFailed-title.md.golden +++ /dev/null @@ -1 +0,0 @@ -Workspace "bobby-workspace" manual build failed \ No newline at end of file diff --git a/coderd/notifications/testdata/rendered-templates/TemplateWorkspaceMarkedForDeletion-body.md.golden b/coderd/notifications/testdata/rendered-templates/TemplateWorkspaceMarkedForDeletion-body.md.golden deleted file mode 100644 index 21defa7c1d500..0000000000000 --- a/coderd/notifications/testdata/rendered-templates/TemplateWorkspaceMarkedForDeletion-body.md.golden +++ /dev/null @@ -1,4 +0,0 @@ -Hi Bobby, - -Your workspace **bobby-workspace** has been marked for **deletion** after 24 hours of [dormancy](https://coder.com/docs/templates/schedule#dormancy-auto-deletion-enterprise) because of template updated to new dormancy policy. -To prevent deletion, use your workspace with the link below. \ No newline at end of file diff --git a/coderd/notifications/testdata/rendered-templates/TemplateWorkspaceMarkedForDeletion-title.md.golden b/coderd/notifications/testdata/rendered-templates/TemplateWorkspaceMarkedForDeletion-title.md.golden deleted file mode 100644 index 1b561a73678de..0000000000000 --- a/coderd/notifications/testdata/rendered-templates/TemplateWorkspaceMarkedForDeletion-title.md.golden +++ /dev/null @@ -1 +0,0 @@ -Workspace "bobby-workspace" marked for deletion \ No newline at end of file diff --git a/coderd/notifications/testdata/rendered-templates/TemplateYourAccountActivated-body.md.golden b/coderd/notifications/testdata/rendered-templates/TemplateYourAccountActivated-body.md.golden deleted file mode 100644 index a3a8710de4673..0000000000000 --- a/coderd/notifications/testdata/rendered-templates/TemplateYourAccountActivated-body.md.golden +++ /dev/null @@ -1,3 +0,0 @@ -Hi Bobby, - -Your account **bobby** has been activated by **rob**. \ No newline at end of file diff --git a/coderd/notifications/testdata/rendered-templates/TemplateYourAccountActivated-title.md.golden b/coderd/notifications/testdata/rendered-templates/TemplateYourAccountActivated-title.md.golden deleted file mode 100644 index 90be1ef2dd63c..0000000000000 --- a/coderd/notifications/testdata/rendered-templates/TemplateYourAccountActivated-title.md.golden +++ /dev/null @@ -1 +0,0 @@ -Your account "bobby" has been activated \ No newline at end of file diff --git a/coderd/notifications/testdata/rendered-templates/TemplateYourAccountSuspended-body.md.golden b/coderd/notifications/testdata/rendered-templates/TemplateYourAccountSuspended-body.md.golden deleted file mode 100644 index 86fc40401774b..0000000000000 --- a/coderd/notifications/testdata/rendered-templates/TemplateYourAccountSuspended-body.md.golden +++ /dev/null @@ -1,3 +0,0 @@ -Hi Bobby, - -Your account **bobby** has been suspended by **rob**. \ No newline at end of file diff --git a/coderd/notifications/testdata/rendered-templates/TemplateYourAccountSuspended-title.md.golden b/coderd/notifications/testdata/rendered-templates/TemplateYourAccountSuspended-title.md.golden deleted file mode 100644 index 3a4cb57c8aac0..0000000000000 --- a/coderd/notifications/testdata/rendered-templates/TemplateYourAccountSuspended-title.md.golden +++ /dev/null @@ -1 +0,0 @@ -Your account "bobby" has been suspended \ No newline at end of file diff --git a/coderd/notifications/testdata/rendered-templates/smtp/TemplateTemplateDeleted.html.golden b/coderd/notifications/testdata/rendered-templates/smtp/TemplateTemplateDeleted.html.golden new file mode 100644 index 0000000000000..ec7c3cfdce485 --- /dev/null +++ b/coderd/notifications/testdata/rendered-templates/smtp/TemplateTemplateDeleted.html.golden @@ -0,0 +1,83 @@ +From: system@coder.com +To: bobby@coder.com +Subject: Template "bobby-template" deleted +Message-Id: 02ee4935-73be-4fa1-a290-ff9999026b13@blush-whale-48 +Date: Fri, 11 Oct 2024 09:03:06 +0000 +Content-Type: multipart/alternative; boundary=bbe61b741255b6098bb6b3c1f41b885773df633cb18d2a3002b68e4bc9c4 +MIME-Version: 1.0 + +--bbe61b741255b6098bb6b3c1f41b885773df633cb18d2a3002b68e4bc9c4 +Content-Transfer-Encoding: quoted-printable +Content-Type: text/plain; charset=UTF-8 + +Hi Bobby, + +The template bobby-template was deleted by rob. + +The template's display name was Bobby's Template. + + +View templates: http://test.com/templates + +--bbe61b741255b6098bb6b3c1f41b885773df633cb18d2a3002b68e4bc9c4 +Content-Transfer-Encoding: quoted-printable +Content-Type: text/html; charset=UTF-8 + + + + + + + Codestin Search App + + +
+
+ 3D"Cod= +
+

+ Template "bobby-template" deleted +

+
+

Hi Bobby,

+ +

The template bobby-template was deleted by rob<= +/strong>.

+ +

The template’s display name was Bobby’s Template.

+
+
+ =20 + + View templates + + =20 +
+
+

© 2024 Coder. All rights reserved - h= +ttp://test.com

+

Click here to manage your notification = +settings

+

Stop receiving emails like this

+
+
+ + + +--bbe61b741255b6098bb6b3c1f41b885773df633cb18d2a3002b68e4bc9c4-- diff --git a/coderd/notifications/testdata/rendered-templates/smtp/TemplateUserAccountActivated.html.golden b/coderd/notifications/testdata/rendered-templates/smtp/TemplateUserAccountActivated.html.golden new file mode 100644 index 0000000000000..81cbe7f54fd0e --- /dev/null +++ b/coderd/notifications/testdata/rendered-templates/smtp/TemplateUserAccountActivated.html.golden @@ -0,0 +1,84 @@ +From: system@coder.com +To: bobby@coder.com +Subject: User account "bobby" activated +Message-Id: 02ee4935-73be-4fa1-a290-ff9999026b13@blush-whale-48 +Date: Fri, 11 Oct 2024 09:03:06 +0000 +Content-Type: multipart/alternative; boundary=bbe61b741255b6098bb6b3c1f41b885773df633cb18d2a3002b68e4bc9c4 +MIME-Version: 1.0 + +--bbe61b741255b6098bb6b3c1f41b885773df633cb18d2a3002b68e4bc9c4 +Content-Transfer-Encoding: quoted-printable +Content-Type: text/plain; charset=UTF-8 + +Hi Bobby, + +User account bobby has been activated. + +The newly activated account belongs to William Tables and was activated by = +rob. + + +View accounts: http://test.com/deployment/users?filter=3Dstatus%3Aactive + +--bbe61b741255b6098bb6b3c1f41b885773df633cb18d2a3002b68e4bc9c4 +Content-Transfer-Encoding: quoted-printable +Content-Type: text/html; charset=UTF-8 + + + + + + + Codestin Search App + + +
+
+ 3D"Cod= +
+

+ User account "bobby" activated +

+
+

Hi Bobby,

+ +

User account bobby has been activated.

+ +

The newly activated account belongs to William Tables a= +nd was activated by rob.

+
+
+ =20 + + View accounts + + =20 +
+
+

© 2024 Coder. All rights reserved - h= +ttp://test.com

+

Click here to manage your notification = +settings

+

Stop receiving emails like this

+
+
+ + + +--bbe61b741255b6098bb6b3c1f41b885773df633cb18d2a3002b68e4bc9c4-- diff --git a/coderd/notifications/testdata/rendered-templates/smtp/TemplateUserAccountCreated.html.golden b/coderd/notifications/testdata/rendered-templates/smtp/TemplateUserAccountCreated.html.golden new file mode 100644 index 0000000000000..9a6cab0989897 --- /dev/null +++ b/coderd/notifications/testdata/rendered-templates/smtp/TemplateUserAccountCreated.html.golden @@ -0,0 +1,83 @@ +From: system@coder.com +To: bobby@coder.com +Subject: User account "bobby" created +Message-Id: 02ee4935-73be-4fa1-a290-ff9999026b13@blush-whale-48 +Date: Fri, 11 Oct 2024 09:03:06 +0000 +Content-Type: multipart/alternative; boundary=bbe61b741255b6098bb6b3c1f41b885773df633cb18d2a3002b68e4bc9c4 +MIME-Version: 1.0 + +--bbe61b741255b6098bb6b3c1f41b885773df633cb18d2a3002b68e4bc9c4 +Content-Transfer-Encoding: quoted-printable +Content-Type: text/plain; charset=UTF-8 + +Hi Bobby, + +New user account bobby has been created. + +This new user account was created for William Tables by rob. + + +View accounts: http://test.com/deployment/users?filter=3Dstatus%3Aactive + +--bbe61b741255b6098bb6b3c1f41b885773df633cb18d2a3002b68e4bc9c4 +Content-Transfer-Encoding: quoted-printable +Content-Type: text/html; charset=UTF-8 + + + + + + + Codestin Search App + + +
+
+ 3D"Cod= +
+

+ User account "bobby" created +

+
+

Hi Bobby,

+ +

New user account bobby has been created.

+ +

This new user account was created for William Tables by= + rob.

+
+
+ =20 + + View accounts + + =20 +
+
+

© 2024 Coder. All rights reserved - h= +ttp://test.com

+

Click here to manage your notification = +settings

+

Stop receiving emails like this

+
+
+ + + +--bbe61b741255b6098bb6b3c1f41b885773df633cb18d2a3002b68e4bc9c4-- diff --git a/coderd/notifications/testdata/rendered-templates/smtp/TemplateUserAccountDeleted.html.golden b/coderd/notifications/testdata/rendered-templates/smtp/TemplateUserAccountDeleted.html.golden new file mode 100644 index 0000000000000..c7daad54f028b --- /dev/null +++ b/coderd/notifications/testdata/rendered-templates/smtp/TemplateUserAccountDeleted.html.golden @@ -0,0 +1,83 @@ +From: system@coder.com +To: bobby@coder.com +Subject: User account "bobby" deleted +Message-Id: 02ee4935-73be-4fa1-a290-ff9999026b13@blush-whale-48 +Date: Fri, 11 Oct 2024 09:03:06 +0000 +Content-Type: multipart/alternative; boundary=bbe61b741255b6098bb6b3c1f41b885773df633cb18d2a3002b68e4bc9c4 +MIME-Version: 1.0 + +--bbe61b741255b6098bb6b3c1f41b885773df633cb18d2a3002b68e4bc9c4 +Content-Transfer-Encoding: quoted-printable +Content-Type: text/plain; charset=UTF-8 + +Hi Bobby, + +User account bobby has been deleted. + +The deleted account belonged to William Tables and was deleted by rob. + + +View accounts: http://test.com/deployment/users?filter=3Dstatus%3Aactive + +--bbe61b741255b6098bb6b3c1f41b885773df633cb18d2a3002b68e4bc9c4 +Content-Transfer-Encoding: quoted-printable +Content-Type: text/html; charset=UTF-8 + + + + + + + Codestin Search App + + +
+
+ 3D"Cod= +
+

+ User account "bobby" deleted +

+
+

Hi Bobby,

+ +

User account bobby has been deleted.

+ +

The deleted account belonged to William Tables and was = +deleted by rob.

+
+
+ =20 + + View accounts + + =20 +
+
+

© 2024 Coder. All rights reserved - h= +ttp://test.com

+

Click here to manage your notification = +settings

+

Stop receiving emails like this

+
+
+ + + +--bbe61b741255b6098bb6b3c1f41b885773df633cb18d2a3002b68e4bc9c4-- diff --git a/coderd/notifications/testdata/rendered-templates/smtp/TemplateUserAccountSuspended.html.golden b/coderd/notifications/testdata/rendered-templates/smtp/TemplateUserAccountSuspended.html.golden new file mode 100644 index 0000000000000..ccd40593ef5fb --- /dev/null +++ b/coderd/notifications/testdata/rendered-templates/smtp/TemplateUserAccountSuspended.html.golden @@ -0,0 +1,85 @@ +From: system@coder.com +To: bobby@coder.com +Subject: User account "bobby" suspended +Message-Id: 02ee4935-73be-4fa1-a290-ff9999026b13@blush-whale-48 +Date: Fri, 11 Oct 2024 09:03:06 +0000 +Content-Type: multipart/alternative; boundary=bbe61b741255b6098bb6b3c1f41b885773df633cb18d2a3002b68e4bc9c4 +MIME-Version: 1.0 + +--bbe61b741255b6098bb6b3c1f41b885773df633cb18d2a3002b68e4bc9c4 +Content-Transfer-Encoding: quoted-printable +Content-Type: text/plain; charset=UTF-8 + +Hi Bobby, + +User account bobby has been suspended. + +The newly suspended account belongs to William Tables and was suspended by = +rob. + + +View suspended accounts: http://test.com/deployment/users?filter=3Dstatus%3= +Asuspended + +--bbe61b741255b6098bb6b3c1f41b885773df633cb18d2a3002b68e4bc9c4 +Content-Transfer-Encoding: quoted-printable +Content-Type: text/html; charset=UTF-8 + + + + + + + Codestin Search App + + +
+
+ 3D"Cod= +
+

+ User account "bobby" suspended +

+
+

Hi Bobby,

+ +

User account bobby has been suspended.

+ +

The newly suspended account belongs to William Tables a= +nd was suspended by rob.

+
+
+ =20 + + View suspended accounts + + =20 +
+
+

© 2024 Coder. All rights reserved - h= +ttp://test.com

+

Click here to manage your notification = +settings

+

Stop receiving emails like this

+
+
+ + + +--bbe61b741255b6098bb6b3c1f41b885773df633cb18d2a3002b68e4bc9c4-- diff --git a/coderd/notifications/testdata/rendered-templates/smtp/TemplateUserRequestedOneTimePasscode.html.golden b/coderd/notifications/testdata/rendered-templates/smtp/TemplateUserRequestedOneTimePasscode.html.golden new file mode 100644 index 0000000000000..2b61765813bcf --- /dev/null +++ b/coderd/notifications/testdata/rendered-templates/smtp/TemplateUserRequestedOneTimePasscode.html.golden @@ -0,0 +1,80 @@ +From: system@coder.com +To: bobby@coder.com +Subject: Your One-Time Passcode for Coder. +Message-Id: 02ee4935-73be-4fa1-a290-ff9999026b13@blush-whale-48 +Date: Fri, 11 Oct 2024 09:03:06 +0000 +Content-Type: multipart/alternative; boundary=bbe61b741255b6098bb6b3c1f41b885773df633cb18d2a3002b68e4bc9c4 +MIME-Version: 1.0 + +--bbe61b741255b6098bb6b3c1f41b885773df633cb18d2a3002b68e4bc9c4 +Content-Transfer-Encoding: quoted-printable +Content-Type: text/plain; charset=UTF-8 + +Hi Bobby, + +A request to reset the password for your Coder account has been made. Your = +one-time passcode is: + +fad9020b-6562-4cdb-87f1-0486f1bea415 + +If you did not request to reset your password, you can ignore this message. + + +--bbe61b741255b6098bb6b3c1f41b885773df633cb18d2a3002b68e4bc9c4 +Content-Transfer-Encoding: quoted-printable +Content-Type: text/html; charset=UTF-8 + + + + + + + Codestin Search App + + +
+
+ 3D"Cod= +
+

+ Your One-Time Passcode for Coder. +

+
+

Hi Bobby,

+ +

A request to reset the password for your Coder account has been made. Yo= +ur one-time passcode is:

+ +

fad9020b-6562-4cdb-87f1-0486f1bea415

+ +

If you did not request to reset your password, you can ignore this messa= +ge.

+
+
+ =20 +
+
+

© 2024 Coder. All rights reserved - h= +ttp://test.com

+

Click here to manage your notification = +settings

+

Stop receiving emails like this

+
+
+ + + +--bbe61b741255b6098bb6b3c1f41b885773df633cb18d2a3002b68e4bc9c4-- diff --git a/coderd/notifications/testdata/rendered-templates/smtp/TemplateWorkspaceAutoUpdated.html.golden b/coderd/notifications/testdata/rendered-templates/smtp/TemplateWorkspaceAutoUpdated.html.golden new file mode 100644 index 0000000000000..6c68cffa8bc1b --- /dev/null +++ b/coderd/notifications/testdata/rendered-templates/smtp/TemplateWorkspaceAutoUpdated.html.golden @@ -0,0 +1,83 @@ +From: system@coder.com +To: bobby@coder.com +Subject: Workspace "bobby-workspace" updated automatically +Message-Id: 02ee4935-73be-4fa1-a290-ff9999026b13@blush-whale-48 +Date: Fri, 11 Oct 2024 09:03:06 +0000 +Content-Type: multipart/alternative; boundary=bbe61b741255b6098bb6b3c1f41b885773df633cb18d2a3002b68e4bc9c4 +MIME-Version: 1.0 + +--bbe61b741255b6098bb6b3c1f41b885773df633cb18d2a3002b68e4bc9c4 +Content-Transfer-Encoding: quoted-printable +Content-Type: text/plain; charset=UTF-8 + +Hi Bobby, + +Your workspace bobby-workspace has been updated automatically to the latest= + template version (1.0). + +Reason for update: template now includes catnip. + + +View workspace: http://test.com/@bobby/bobby-workspace + +--bbe61b741255b6098bb6b3c1f41b885773df633cb18d2a3002b68e4bc9c4 +Content-Transfer-Encoding: quoted-printable +Content-Type: text/html; charset=UTF-8 + + + + + + + Codestin Search App + + +
+
+ 3D"Cod= +
+

+ Workspace "bobby-workspace" updated automatically +

+
+

Hi Bobby,

+ +

Your workspace bobby-workspace has been updated automat= +ically to the latest template version (1.0).

+ +

Reason for update: template now includes catnip.

+
+
+ =20 + + View workspace + + =20 +
+
+

© 2024 Coder. All rights reserved - h= +ttp://test.com

+

Click here to manage your notification = +settings

+

Stop receiving emails like this

+
+
+ + + +--bbe61b741255b6098bb6b3c1f41b885773df633cb18d2a3002b68e4bc9c4-- diff --git a/coderd/notifications/testdata/rendered-templates/smtp/TemplateWorkspaceAutobuildFailed.html.golden b/coderd/notifications/testdata/rendered-templates/smtp/TemplateWorkspaceAutobuildFailed.html.golden new file mode 100644 index 0000000000000..340e794f15c74 --- /dev/null +++ b/coderd/notifications/testdata/rendered-templates/smtp/TemplateWorkspaceAutobuildFailed.html.golden @@ -0,0 +1,82 @@ +From: system@coder.com +To: bobby@coder.com +Subject: Workspace "bobby-workspace" autobuild failed +Message-Id: 02ee4935-73be-4fa1-a290-ff9999026b13@blush-whale-48 +Date: Fri, 11 Oct 2024 09:03:06 +0000 +Content-Type: multipart/alternative; boundary=bbe61b741255b6098bb6b3c1f41b885773df633cb18d2a3002b68e4bc9c4 +MIME-Version: 1.0 + +--bbe61b741255b6098bb6b3c1f41b885773df633cb18d2a3002b68e4bc9c4 +Content-Transfer-Encoding: quoted-printable +Content-Type: text/plain; charset=UTF-8 + +Hi Bobby, + +Automatic build of your workspace bobby-workspace failed. + +The specified reason was "autostart". + + +View workspace: http://test.com/@bobby/bobby-workspace + +--bbe61b741255b6098bb6b3c1f41b885773df633cb18d2a3002b68e4bc9c4 +Content-Transfer-Encoding: quoted-printable +Content-Type: text/html; charset=UTF-8 + + + + + + + Codestin Search App + + +
+
+ 3D"Cod= +
+

+ Workspace "bobby-workspace" autobuild failed +

+
+

Hi Bobby,

+ +

Automatic build of your workspace bobby-workspace faile= +d.

+ +

The specified reason was “autostart”.

+
+
+ =20 + + View workspace + + =20 +
+
+

© 2024 Coder. All rights reserved - h= +ttp://test.com

+

Click here to manage your notification = +settings

+

Stop receiving emails like this

+
+
+ + + +--bbe61b741255b6098bb6b3c1f41b885773df633cb18d2a3002b68e4bc9c4-- diff --git a/coderd/notifications/testdata/rendered-templates/smtp/TemplateWorkspaceBuildsFailedReport.html.golden b/coderd/notifications/testdata/rendered-templates/smtp/TemplateWorkspaceBuildsFailedReport.html.golden new file mode 100644 index 0000000000000..7cc16f00f3796 --- /dev/null +++ b/coderd/notifications/testdata/rendered-templates/smtp/TemplateWorkspaceBuildsFailedReport.html.golden @@ -0,0 +1,126 @@ +From: system@coder.com +To: bobby@coder.com +Subject: Workspace builds failed for template "Bobby First Template" +Message-Id: 02ee4935-73be-4fa1-a290-ff9999026b13@blush-whale-48 +Date: Fri, 11 Oct 2024 09:03:06 +0000 +Content-Type: multipart/alternative; boundary=bbe61b741255b6098bb6b3c1f41b885773df633cb18d2a3002b68e4bc9c4 +MIME-Version: 1.0 + +--bbe61b741255b6098bb6b3c1f41b885773df633cb18d2a3002b68e4bc9c4 +Content-Transfer-Encoding: quoted-printable +Content-Type: text/plain; charset=UTF-8 + +Hi Bobby, + +Template Bobby First Template has failed to build 4/55 times over the last = +week. + +Report: + +bobby-template-version-1 failed 3 times: + +mtojek / workspace-1 / #1234 (http://test.com/@mtojek/workspace-1/builds/12= +34) +johndoe / my-workspace-3 / #5678 (http://test.com/@johndoe/my-workspace-3/b= +uilds/5678) +jack / workwork / #774 (http://test.com/@jack/workwork/builds/774) + +bobby-template-version-2 failed 1 time: + +ben / cool-workspace / #8888 (http://test.com/@ben/cool-workspace/builds/88= +88) + +We recommend reviewing these issues to ensure future builds are successful. + + +View workspaces: http://test.com/workspaces?filter=3Dtemplate%3Abobby-first= +-template + +--bbe61b741255b6098bb6b3c1f41b885773df633cb18d2a3002b68e4bc9c4 +Content-Transfer-Encoding: quoted-printable +Content-Type: text/html; charset=UTF-8 + + + + + + + Codestin Search App + + +
+
+ 3D"Cod= +
+

+ Workspace "bobby-workspace" deleted +

+
+

Hi Bobby,

+ +

Your workspace bobby-workspace was deleted.

+ +

The specified reason was “autodeleted due to dormancy (aut= +obuild)”.

+
+
+ =20 + + View workspaces + + =20 + + View templates + + =20 +
+
+

© 2024 Coder. All rights reserved - h= +ttp://test.com

+

Click here to manage your notification = +settings

+

Stop receiving emails like this

+
+
+ + + +--bbe61b741255b6098bb6b3c1f41b885773df633cb18d2a3002b68e4bc9c4-- diff --git a/coderd/notifications/testdata/rendered-templates/smtp/TemplateWorkspaceDormant.html.golden b/coderd/notifications/testdata/rendered-templates/smtp/TemplateWorkspaceDormant.html.golden new file mode 100644 index 0000000000000..0c6cbf5a2dd85 --- /dev/null +++ b/coderd/notifications/testdata/rendered-templates/smtp/TemplateWorkspaceDormant.html.golden @@ -0,0 +1,90 @@ +From: system@coder.com +To: bobby@coder.com +Subject: Workspace "bobby-workspace" marked as dormant +Message-Id: 02ee4935-73be-4fa1-a290-ff9999026b13@blush-whale-48 +Date: Fri, 11 Oct 2024 09:03:06 +0000 +Content-Type: multipart/alternative; boundary=bbe61b741255b6098bb6b3c1f41b885773df633cb18d2a3002b68e4bc9c4 +MIME-Version: 1.0 + +--bbe61b741255b6098bb6b3c1f41b885773df633cb18d2a3002b68e4bc9c4 +Content-Transfer-Encoding: quoted-printable +Content-Type: text/plain; charset=UTF-8 + +Hi Bobby, + +Your workspace bobby-workspace has been marked as dormant (https://coder.co= +m/docs/templates/schedule#dormancy-threshold-enterprise) because of breache= +d the template's threshold for inactivity. +Dormant workspaces are automatically deleted (https://coder.com/docs/templa= +tes/schedule#dormancy-auto-deletion-enterprise) after 24 hours of inactivit= +y. +To prevent deletion, use your workspace with the link below. + + +View workspace: http://test.com/@bobby/bobby-workspace + +--bbe61b741255b6098bb6b3c1f41b885773df633cb18d2a3002b68e4bc9c4 +Content-Transfer-Encoding: quoted-printable +Content-Type: text/html; charset=UTF-8 + + + + + + + Codestin Search App + + +
+
+ 3D"Cod= +
+

+ Workspace "bobby-workspace" marked as dormant +

+
+

Hi Bobby,

+ +

Your workspace bobby-workspace has been marked as dormant because of breached the template’s t= +hreshold for inactivity.
+Dormant workspaces are automatically deleted after 24 hour= +s of inactivity.
+To prevent deletion, use your workspace with the link below.

+
+
+ =20 + + View workspace + + =20 +
+
+

© 2024 Coder. All rights reserved - h= +ttp://test.com

+

Click here to manage your notification = +settings

+

Stop receiving emails like this

+
+
+ + + +--bbe61b741255b6098bb6b3c1f41b885773df633cb18d2a3002b68e4bc9c4-- diff --git a/coderd/notifications/testdata/rendered-templates/smtp/TemplateWorkspaceManualBuildFailed.html.golden b/coderd/notifications/testdata/rendered-templates/smtp/TemplateWorkspaceManualBuildFailed.html.golden new file mode 100644 index 0000000000000..a1711b70eae85 --- /dev/null +++ b/coderd/notifications/testdata/rendered-templates/smtp/TemplateWorkspaceManualBuildFailed.html.golden @@ -0,0 +1,86 @@ +From: system@coder.com +To: bobby@coder.com +Subject: Workspace "bobby-workspace" manual build failed +Message-Id: 02ee4935-73be-4fa1-a290-ff9999026b13@blush-whale-48 +Date: Fri, 11 Oct 2024 09:03:06 +0000 +Content-Type: multipart/alternative; boundary=bbe61b741255b6098bb6b3c1f41b885773df633cb18d2a3002b68e4bc9c4 +MIME-Version: 1.0 + +--bbe61b741255b6098bb6b3c1f41b885773df633cb18d2a3002b68e4bc9c4 +Content-Transfer-Encoding: quoted-printable +Content-Type: text/plain; charset=UTF-8 + +Hi Bobby, + +A manual build of the workspace bobby-workspace using the template bobby-te= +mplate failed (version: bobby-template-version). + +The template's display name was William's Template. The workspace build was= + initiated by joe. + + +View build: http://test.com/@mrbobby/bobby-workspace/builds/3 + +--bbe61b741255b6098bb6b3c1f41b885773df633cb18d2a3002b68e4bc9c4 +Content-Transfer-Encoding: quoted-printable +Content-Type: text/html; charset=UTF-8 + + + + + + + Codestin Search App + + +
+
+ 3D"Cod= +
+

+ Workspace "bobby-workspace" manual build failed +

+
+

Hi Bobby,

+ +

A manual build of the workspace bobby-workspace using t= +he template bobby-template failed (version: bobby-= +template-version).

+ +

The template’s display name was William’s Template. The workspace build was initiated by joe.

+
+
+ =20 + + View build + + =20 +
+
+

© 2024 Coder. All rights reserved - h= +ttp://test.com

+

Click here to manage your notification = +settings

+

Stop receiving emails like this

+
+
+ + + +--bbe61b741255b6098bb6b3c1f41b885773df633cb18d2a3002b68e4bc9c4-- diff --git a/coderd/notifications/testdata/rendered-templates/smtp/TemplateWorkspaceMarkedForDeletion.html.golden b/coderd/notifications/testdata/rendered-templates/smtp/TemplateWorkspaceMarkedForDeletion.html.golden new file mode 100644 index 0000000000000..6d91458f2cbcc --- /dev/null +++ b/coderd/notifications/testdata/rendered-templates/smtp/TemplateWorkspaceMarkedForDeletion.html.golden @@ -0,0 +1,84 @@ +From: system@coder.com +To: bobby@coder.com +Subject: Workspace "bobby-workspace" marked for deletion +Message-Id: 02ee4935-73be-4fa1-a290-ff9999026b13@blush-whale-48 +Date: Fri, 11 Oct 2024 09:03:06 +0000 +Content-Type: multipart/alternative; boundary=bbe61b741255b6098bb6b3c1f41b885773df633cb18d2a3002b68e4bc9c4 +MIME-Version: 1.0 + +--bbe61b741255b6098bb6b3c1f41b885773df633cb18d2a3002b68e4bc9c4 +Content-Transfer-Encoding: quoted-printable +Content-Type: text/plain; charset=UTF-8 + +Hi Bobby, + +Your workspace bobby-workspace has been marked for deletion after 24 hours = +of dormancy (https://coder.com/docs/templates/schedule#dormancy-auto-deleti= +on-enterprise) because of template updated to new dormancy policy. +To prevent deletion, use your workspace with the link below. + + +View workspace: http://test.com/@bobby/bobby-workspace + +--bbe61b741255b6098bb6b3c1f41b885773df633cb18d2a3002b68e4bc9c4 +Content-Transfer-Encoding: quoted-printable +Content-Type: text/html; charset=UTF-8 + + + + + + + Codestin Search App + + +
+
+ 3D"Cod= +
+

+ Workspace "bobby-workspace" marked for deletion +

+
+

Hi Bobby,

+ +

Your workspace bobby-workspace has been marked for deletion after 24 hours of dormancy because o= +f template updated to new dormancy policy.
+To prevent deletion, use your workspace with the link below.

+
+
+ =20 + + View workspace + + =20 +
+
+

© 2024 Coder. All rights reserved - h= +ttp://test.com

+

Click here to manage your notification = +settings

+

Stop receiving emails like this

+
+
+ + + +--bbe61b741255b6098bb6b3c1f41b885773df633cb18d2a3002b68e4bc9c4-- diff --git a/coderd/notifications/testdata/rendered-templates/smtp/TemplateYourAccountActivated.html.golden b/coderd/notifications/testdata/rendered-templates/smtp/TemplateYourAccountActivated.html.golden new file mode 100644 index 0000000000000..aef12ab957feb --- /dev/null +++ b/coderd/notifications/testdata/rendered-templates/smtp/TemplateYourAccountActivated.html.golden @@ -0,0 +1,78 @@ +From: system@coder.com +To: bobby@coder.com +Subject: Your account "bobby" has been activated +Message-Id: 02ee4935-73be-4fa1-a290-ff9999026b13@blush-whale-48 +Date: Fri, 11 Oct 2024 09:03:06 +0000 +Content-Type: multipart/alternative; boundary=bbe61b741255b6098bb6b3c1f41b885773df633cb18d2a3002b68e4bc9c4 +MIME-Version: 1.0 + +--bbe61b741255b6098bb6b3c1f41b885773df633cb18d2a3002b68e4bc9c4 +Content-Transfer-Encoding: quoted-printable +Content-Type: text/plain; charset=UTF-8 + +Hi Bobby, + +Your account bobby has been activated by rob. + + +Open Coder: http://test.com + +--bbe61b741255b6098bb6b3c1f41b885773df633cb18d2a3002b68e4bc9c4 +Content-Transfer-Encoding: quoted-printable +Content-Type: text/html; charset=UTF-8 + + + + + + + Codestin Search App + + +
+
+ 3D"Cod= +
+

+ Your account "bobby" has been activated +

+
+

Hi Bobby,

+ +

Your account bobby has been activated by rob.

+
+
+ =20 + + Open Coder + + =20 +
+
+

© 2024 Coder. All rights reserved - h= +ttp://test.com

+

Click here to manage your notification = +settings

+

Stop receiving emails like this

+
+
+ + + +--bbe61b741255b6098bb6b3c1f41b885773df633cb18d2a3002b68e4bc9c4-- diff --git a/coderd/notifications/testdata/rendered-templates/smtp/TemplateYourAccountSuspended.html.golden b/coderd/notifications/testdata/rendered-templates/smtp/TemplateYourAccountSuspended.html.golden new file mode 100644 index 0000000000000..d9406e2c1f344 --- /dev/null +++ b/coderd/notifications/testdata/rendered-templates/smtp/TemplateYourAccountSuspended.html.golden @@ -0,0 +1,70 @@ +From: system@coder.com +To: bobby@coder.com +Subject: Your account "bobby" has been suspended +Message-Id: 02ee4935-73be-4fa1-a290-ff9999026b13@blush-whale-48 +Date: Fri, 11 Oct 2024 09:03:06 +0000 +Content-Type: multipart/alternative; boundary=bbe61b741255b6098bb6b3c1f41b885773df633cb18d2a3002b68e4bc9c4 +MIME-Version: 1.0 + +--bbe61b741255b6098bb6b3c1f41b885773df633cb18d2a3002b68e4bc9c4 +Content-Transfer-Encoding: quoted-printable +Content-Type: text/plain; charset=UTF-8 + +Hi Bobby, + +Your account bobby has been suspended by rob. + + +--bbe61b741255b6098bb6b3c1f41b885773df633cb18d2a3002b68e4bc9c4 +Content-Transfer-Encoding: quoted-printable +Content-Type: text/html; charset=UTF-8 + + + + + + + Codestin Search App + + +
+
+ 3D"Cod= +
+

+ Your account "bobby" has been suspended +

+
+

Hi Bobby,

+ +

Your account bobby has been suspended by rob.

+
+
+ =20 +
+ +
+ + + +--bbe61b741255b6098bb6b3c1f41b885773df633cb18d2a3002b68e4bc9c4-- diff --git a/coderd/notifications/testdata/rendered-templates/webhook/TemplateTemplateDeleted.json.golden b/coderd/notifications/testdata/rendered-templates/webhook/TemplateTemplateDeleted.json.golden new file mode 100644 index 0000000000000..4a97b3a14f866 --- /dev/null +++ b/coderd/notifications/testdata/rendered-templates/webhook/TemplateTemplateDeleted.json.golden @@ -0,0 +1,29 @@ +{ + "_version": "1.1", + "msg_id": "00000000-0000-0000-0000-000000000000", + "payload": { + "_version": "1.1", + "notification_name": "Template Deleted", + "notification_template_id": "00000000-0000-0000-0000-000000000000", + "user_id": "00000000-0000-0000-0000-000000000000", + "user_email": "bobby@coder.com", + "user_name": "Bobby", + "user_username": "bobby", + "actions": [ + { + "label": "View templates", + "url": "http://test.com/templates" + } + ], + "labels": { + "display_name": "Bobby's Template", + "initiator": "rob", + "name": "bobby-template" + }, + "data": null + }, + "title": "Template \"bobby-template\" deleted", + "title_markdown": "Template \"bobby-template\" deleted", + "body": "Hi Bobby,\n\nThe template bobby-template was deleted by rob.\n\nThe template's display name was Bobby's Template.", + "body_markdown": "Hi Bobby,\n\nThe template **bobby-template** was deleted by **rob**.\n\nThe template's display name was **Bobby's Template**." +} \ No newline at end of file diff --git a/coderd/notifications/testdata/rendered-templates/webhook/TemplateUserAccountActivated.json.golden b/coderd/notifications/testdata/rendered-templates/webhook/TemplateUserAccountActivated.json.golden new file mode 100644 index 0000000000000..5da690875888e --- /dev/null +++ b/coderd/notifications/testdata/rendered-templates/webhook/TemplateUserAccountActivated.json.golden @@ -0,0 +1,29 @@ +{ + "_version": "1.1", + "msg_id": "00000000-0000-0000-0000-000000000000", + "payload": { + "_version": "1.1", + "notification_name": "User account activated", + "notification_template_id": "00000000-0000-0000-0000-000000000000", + "user_id": "00000000-0000-0000-0000-000000000000", + "user_email": "bobby@coder.com", + "user_name": "Bobby", + "user_username": "bobby", + "actions": [ + { + "label": "View accounts", + "url": "http://test.com/deployment/users?filter=status%3Aactive" + } + ], + "labels": { + "activated_account_name": "bobby", + "activated_account_user_name": "William Tables", + "initiator": "rob" + }, + "data": null + }, + "title": "User account \"bobby\" activated", + "title_markdown": "User account \"bobby\" activated", + "body": "Hi Bobby,\n\nUser account bobby has been activated.\n\nThe newly activated account belongs to William Tables and was activated by rob.", + "body_markdown": "Hi Bobby,\n\nUser account **bobby** has been activated.\n\nThe newly activated account belongs to **William Tables** and was activated by **rob**." +} \ No newline at end of file diff --git a/coderd/notifications/testdata/rendered-templates/webhook/TemplateUserAccountCreated.json.golden b/coderd/notifications/testdata/rendered-templates/webhook/TemplateUserAccountCreated.json.golden new file mode 100644 index 0000000000000..272a5628a20a7 --- /dev/null +++ b/coderd/notifications/testdata/rendered-templates/webhook/TemplateUserAccountCreated.json.golden @@ -0,0 +1,29 @@ +{ + "_version": "1.1", + "msg_id": "00000000-0000-0000-0000-000000000000", + "payload": { + "_version": "1.1", + "notification_name": "User account created", + "notification_template_id": "00000000-0000-0000-0000-000000000000", + "user_id": "00000000-0000-0000-0000-000000000000", + "user_email": "bobby@coder.com", + "user_name": "Bobby", + "user_username": "bobby", + "actions": [ + { + "label": "View accounts", + "url": "http://test.com/deployment/users?filter=status%3Aactive" + } + ], + "labels": { + "created_account_name": "bobby", + "created_account_user_name": "William Tables", + "initiator": "rob" + }, + "data": null + }, + "title": "User account \"bobby\" created", + "title_markdown": "User account \"bobby\" created", + "body": "Hi Bobby,\n\nNew user account bobby has been created.\n\nThis new user account was created for William Tables by rob.", + "body_markdown": "Hi Bobby,\n\nNew user account **bobby** has been created.\n\nThis new user account was created for **William Tables** by **rob**." +} \ No newline at end of file diff --git a/coderd/notifications/testdata/rendered-templates/webhook/TemplateUserAccountDeleted.json.golden b/coderd/notifications/testdata/rendered-templates/webhook/TemplateUserAccountDeleted.json.golden new file mode 100644 index 0000000000000..10b7ddbca6853 --- /dev/null +++ b/coderd/notifications/testdata/rendered-templates/webhook/TemplateUserAccountDeleted.json.golden @@ -0,0 +1,29 @@ +{ + "_version": "1.1", + "msg_id": "00000000-0000-0000-0000-000000000000", + "payload": { + "_version": "1.1", + "notification_name": "User account deleted", + "notification_template_id": "00000000-0000-0000-0000-000000000000", + "user_id": "00000000-0000-0000-0000-000000000000", + "user_email": "bobby@coder.com", + "user_name": "Bobby", + "user_username": "bobby", + "actions": [ + { + "label": "View accounts", + "url": "http://test.com/deployment/users?filter=status%3Aactive" + } + ], + "labels": { + "deleted_account_name": "bobby", + "deleted_account_user_name": "William Tables", + "initiator": "rob" + }, + "data": null + }, + "title": "User account \"bobby\" deleted", + "title_markdown": "User account \"bobby\" deleted", + "body": "Hi Bobby,\n\nUser account bobby has been deleted.\n\nThe deleted account belonged to William Tables and was deleted by rob.", + "body_markdown": "Hi Bobby,\n\nUser account **bobby** has been deleted.\n\nThe deleted account belonged to **William Tables** and was deleted by **rob**." +} \ No newline at end of file diff --git a/coderd/notifications/testdata/rendered-templates/webhook/TemplateUserAccountSuspended.json.golden b/coderd/notifications/testdata/rendered-templates/webhook/TemplateUserAccountSuspended.json.golden new file mode 100644 index 0000000000000..04146d5e71400 --- /dev/null +++ b/coderd/notifications/testdata/rendered-templates/webhook/TemplateUserAccountSuspended.json.golden @@ -0,0 +1,29 @@ +{ + "_version": "1.1", + "msg_id": "00000000-0000-0000-0000-000000000000", + "payload": { + "_version": "1.1", + "notification_name": "User account suspended", + "notification_template_id": "00000000-0000-0000-0000-000000000000", + "user_id": "00000000-0000-0000-0000-000000000000", + "user_email": "bobby@coder.com", + "user_name": "Bobby", + "user_username": "bobby", + "actions": [ + { + "label": "View suspended accounts", + "url": "http://test.com/deployment/users?filter=status%3Asuspended" + } + ], + "labels": { + "initiator": "rob", + "suspended_account_name": "bobby", + "suspended_account_user_name": "William Tables" + }, + "data": null + }, + "title": "User account \"bobby\" suspended", + "title_markdown": "User account \"bobby\" suspended", + "body": "Hi Bobby,\n\nUser account bobby has been suspended.\n\nThe newly suspended account belongs to William Tables and was suspended by rob.", + "body_markdown": "Hi Bobby,\n\nUser account **bobby** has been suspended.\n\nThe newly suspended account belongs to **William Tables** and was suspended by **rob**." +} \ No newline at end of file diff --git a/coderd/notifications/testdata/rendered-templates/webhook/TemplateUserRequestedOneTimePasscode.json.golden b/coderd/notifications/testdata/rendered-templates/webhook/TemplateUserRequestedOneTimePasscode.json.golden new file mode 100644 index 0000000000000..2c03fc7c71905 --- /dev/null +++ b/coderd/notifications/testdata/rendered-templates/webhook/TemplateUserRequestedOneTimePasscode.json.golden @@ -0,0 +1,22 @@ +{ + "_version": "1.1", + "msg_id": "00000000-0000-0000-0000-000000000000", + "payload": { + "_version": "1.1", + "notification_name": "One-Time Passcode", + "notification_template_id": "00000000-0000-0000-0000-000000000000", + "user_id": "00000000-0000-0000-0000-000000000000", + "user_email": "bobby@coder.com", + "user_name": "Bobby", + "user_username": "bobby", + "actions": [], + "labels": { + "one_time_passcode": "00000000-0000-0000-0000-000000000000" + }, + "data": null + }, + "title": "Your One-Time Passcode for Coder.", + "title_markdown": "Your One-Time Passcode for Coder.", + "body": "Hi Bobby,\n\nA request to reset the password for your Coder account has been made. Your one-time passcode is:\n\n00000000-0000-0000-0000-000000000000\n\nIf you did not request to reset your password, you can ignore this message.", + "body_markdown": "Hi Bobby,\n\nA request to reset the password for your Coder account has been made. Your one-time passcode is:\n\n**00000000-0000-0000-0000-000000000000**\n\nIf you did not request to reset your password, you can ignore this message." +} \ No newline at end of file diff --git a/coderd/notifications/testdata/rendered-templates/webhook/TemplateWorkspaceAutoUpdated.json.golden b/coderd/notifications/testdata/rendered-templates/webhook/TemplateWorkspaceAutoUpdated.json.golden new file mode 100644 index 0000000000000..917904a2495aa --- /dev/null +++ b/coderd/notifications/testdata/rendered-templates/webhook/TemplateWorkspaceAutoUpdated.json.golden @@ -0,0 +1,29 @@ +{ + "_version": "1.1", + "msg_id": "00000000-0000-0000-0000-000000000000", + "payload": { + "_version": "1.1", + "notification_name": "Workspace Updated Automatically", + "notification_template_id": "00000000-0000-0000-0000-000000000000", + "user_id": "00000000-0000-0000-0000-000000000000", + "user_email": "bobby@coder.com", + "user_name": "Bobby", + "user_username": "bobby", + "actions": [ + { + "label": "View workspace", + "url": "http://test.com/@bobby/bobby-workspace" + } + ], + "labels": { + "name": "bobby-workspace", + "template_version_message": "template now includes catnip", + "template_version_name": "1.0" + }, + "data": null + }, + "title": "Workspace \"bobby-workspace\" updated automatically", + "title_markdown": "Workspace \"bobby-workspace\" updated automatically", + "body": "Hi Bobby,\n\nYour workspace bobby-workspace has been updated automatically to the latest template version (1.0).\n\nReason for update: template now includes catnip.", + "body_markdown": "Hi Bobby,\n\nYour workspace **bobby-workspace** has been updated automatically to the latest template version (1.0).\n\nReason for update: **template now includes catnip**." +} \ No newline at end of file diff --git a/coderd/notifications/testdata/rendered-templates/webhook/TemplateWorkspaceAutobuildFailed.json.golden b/coderd/notifications/testdata/rendered-templates/webhook/TemplateWorkspaceAutobuildFailed.json.golden new file mode 100644 index 0000000000000..45b64a31a0adb --- /dev/null +++ b/coderd/notifications/testdata/rendered-templates/webhook/TemplateWorkspaceAutobuildFailed.json.golden @@ -0,0 +1,28 @@ +{ + "_version": "1.1", + "msg_id": "00000000-0000-0000-0000-000000000000", + "payload": { + "_version": "1.1", + "notification_name": "Workspace Autobuild Failed", + "notification_template_id": "00000000-0000-0000-0000-000000000000", + "user_id": "00000000-0000-0000-0000-000000000000", + "user_email": "bobby@coder.com", + "user_name": "Bobby", + "user_username": "bobby", + "actions": [ + { + "label": "View workspace", + "url": "http://test.com/@bobby/bobby-workspace" + } + ], + "labels": { + "name": "bobby-workspace", + "reason": "autostart" + }, + "data": null + }, + "title": "Workspace \"bobby-workspace\" autobuild failed", + "title_markdown": "Workspace \"bobby-workspace\" autobuild failed", + "body": "Hi Bobby,\n\nAutomatic build of your workspace bobby-workspace failed.\n\nThe specified reason was \"autostart\".", + "body_markdown": "Hi Bobby,\n\nAutomatic build of your workspace **bobby-workspace** failed.\n\nThe specified reason was \"**autostart**\"." +} \ No newline at end of file diff --git a/coderd/notifications/testdata/rendered-templates/webhook/TemplateWorkspaceBuildsFailedReport.json.golden b/coderd/notifications/testdata/rendered-templates/webhook/TemplateWorkspaceBuildsFailedReport.json.golden new file mode 100644 index 0000000000000..c6dabbfb89d80 --- /dev/null +++ b/coderd/notifications/testdata/rendered-templates/webhook/TemplateWorkspaceBuildsFailedReport.json.golden @@ -0,0 +1,66 @@ +{ + "_version": "1.1", + "msg_id": "00000000-0000-0000-0000-000000000000", + "payload": { + "_version": "1.1", + "notification_name": "Report: Workspace Builds Failed For Template", + "notification_template_id": "00000000-0000-0000-0000-000000000000", + "user_id": "00000000-0000-0000-0000-000000000000", + "user_email": "bobby@coder.com", + "user_name": "Bobby", + "user_username": "bobby", + "actions": [ + { + "label": "View workspaces", + "url": "http://test.com/workspaces?filter=template%3Abobby-first-template" + } + ], + "labels": { + "template_display_name": "Bobby First Template", + "template_name": "bobby-first-template" + }, + "data": { + "failed_builds": 4, + "report_frequency": "week", + "template_versions": [ + { + "failed_builds": [ + { + "build_number": 1234, + "workspace_name": "workspace-1", + "workspace_owner_username": "mtojek" + }, + { + "build_number": 5678, + "workspace_name": "my-workspace-3", + "workspace_owner_username": "johndoe" + }, + { + "build_number": 774, + "workspace_name": "workwork", + "workspace_owner_username": "jack" + } + ], + "failed_count": 3, + "template_version_name": "bobby-template-version-1" + }, + { + "failed_builds": [ + { + "build_number": 8888, + "workspace_name": "cool-workspace", + "workspace_owner_username": "ben" + } + ], + "failed_count": 1, + "template_version_name": "bobby-template-version-2" + } + ], + "total_builds": 55 + } + }, + "title": "Workspace builds failed for template \"Bobby First Template\"", + "title_markdown": "Workspace builds failed for template \"Bobby First Template\"", + "body": "Hi Bobby,\n\nTemplate Bobby First Template has failed to build 4/55 times over the last week.\n\nReport:\n\nbobby-template-version-1 failed 3 times:\n\nmtojek / workspace-1 / #1234 (http://test.com/@mtojek/workspace-1/builds/1234)\njohndoe / my-workspace-3 / #5678 (http://test.com/@johndoe/my-workspace-3/builds/5678)\njack / workwork / #774 (http://test.com/@jack/workwork/builds/774)\n\nbobby-template-version-2 failed 1 time:\n\nben / cool-workspace / #8888 (http://test.com/@ben/cool-workspace/builds/8888)\n\nWe recommend reviewing these issues to ensure future builds are successful.", + "body_markdown": "Hi Bobby,\n\nTemplate **Bobby First Template** has failed to build 4/55 times over the last week.\n\n**Report:**\n\n**bobby-template-version-1** failed 3 times:\n\n* [mtojek / workspace-1 / #1234](http://test.com/@mtojek/workspace-1/builds/1234)\n* [johndoe / my-workspace-3 / #5678](http://test.com/@johndoe/my-workspace-3/builds/5678)\n* [jack / workwork / #774](http://test.com/@jack/workwork/builds/774)\n\n**bobby-template-version-2** failed 1 time:\n\n* [ben / cool-workspace / #8888](http://test.com/@ben/cool-workspace/builds/8888)\n\nWe recommend reviewing these issues to ensure future builds are successful." +} \ No newline at end of file diff --git a/coderd/notifications/testdata/rendered-templates/webhook/TemplateWorkspaceDeleted.json.golden b/coderd/notifications/testdata/rendered-templates/webhook/TemplateWorkspaceDeleted.json.golden new file mode 100644 index 0000000000000..171e893dd943f --- /dev/null +++ b/coderd/notifications/testdata/rendered-templates/webhook/TemplateWorkspaceDeleted.json.golden @@ -0,0 +1,33 @@ +{ + "_version": "1.1", + "msg_id": "00000000-0000-0000-0000-000000000000", + "payload": { + "_version": "1.1", + "notification_name": "Workspace Deleted", + "notification_template_id": "00000000-0000-0000-0000-000000000000", + "user_id": "00000000-0000-0000-0000-000000000000", + "user_email": "bobby@coder.com", + "user_name": "Bobby", + "user_username": "bobby", + "actions": [ + { + "label": "View workspaces", + "url": "http://test.com/workspaces" + }, + { + "label": "View templates", + "url": "http://test.com/templates" + } + ], + "labels": { + "initiator": "autobuild", + "name": "bobby-workspace", + "reason": "autodeleted due to dormancy" + }, + "data": null + }, + "title": "Workspace \"bobby-workspace\" deleted", + "title_markdown": "Workspace \"bobby-workspace\" deleted", + "body": "Hi Bobby,\n\nYour workspace bobby-workspace was deleted.\n\nThe specified reason was \"autodeleted due to dormancy (autobuild)\".", + "body_markdown": "Hi Bobby,\n\nYour workspace **bobby-workspace** was deleted.\n\nThe specified reason was \"**autodeleted due to dormancy (autobuild)**\"." +} \ No newline at end of file diff --git a/coderd/notifications/testdata/rendered-templates/webhook/TemplateWorkspaceDormant.json.golden b/coderd/notifications/testdata/rendered-templates/webhook/TemplateWorkspaceDormant.json.golden new file mode 100644 index 0000000000000..00c591d9d15d3 --- /dev/null +++ b/coderd/notifications/testdata/rendered-templates/webhook/TemplateWorkspaceDormant.json.golden @@ -0,0 +1,31 @@ +{ + "_version": "1.1", + "msg_id": "00000000-0000-0000-0000-000000000000", + "payload": { + "_version": "1.1", + "notification_name": "Workspace Marked as Dormant", + "notification_template_id": "00000000-0000-0000-0000-000000000000", + "user_id": "00000000-0000-0000-0000-000000000000", + "user_email": "bobby@coder.com", + "user_name": "Bobby", + "user_username": "bobby", + "actions": [ + { + "label": "View workspace", + "url": "http://test.com/@bobby/bobby-workspace" + } + ], + "labels": { + "dormancyHours": "24", + "initiator": "autobuild", + "name": "bobby-workspace", + "reason": "breached the template's threshold for inactivity", + "timeTilDormant": "24 hours" + }, + "data": null + }, + "title": "Workspace \"bobby-workspace\" marked as dormant", + "title_markdown": "Workspace \"bobby-workspace\" marked as dormant", + "body": "Hi Bobby,\n\nYour workspace bobby-workspace has been marked as dormant (https://coder.com/docs/templates/schedule#dormancy-threshold-enterprise) because of breached the template's threshold for inactivity.\nDormant workspaces are automatically deleted (https://coder.com/docs/templates/schedule#dormancy-auto-deletion-enterprise) after 24 hours of inactivity.\nTo prevent deletion, use your workspace with the link below.", + "body_markdown": "Hi Bobby,\n\nYour workspace **bobby-workspace** has been marked as [**dormant**](https://coder.com/docs/templates/schedule#dormancy-threshold-enterprise) because of breached the template's threshold for inactivity.\nDormant workspaces are [automatically deleted](https://coder.com/docs/templates/schedule#dormancy-auto-deletion-enterprise) after 24 hours of inactivity.\nTo prevent deletion, use your workspace with the link below." +} \ No newline at end of file diff --git a/coderd/notifications/testdata/rendered-templates/webhook/TemplateWorkspaceManualBuildFailed.json.golden b/coderd/notifications/testdata/rendered-templates/webhook/TemplateWorkspaceManualBuildFailed.json.golden new file mode 100644 index 0000000000000..8fe2b8b86fd03 --- /dev/null +++ b/coderd/notifications/testdata/rendered-templates/webhook/TemplateWorkspaceManualBuildFailed.json.golden @@ -0,0 +1,33 @@ +{ + "_version": "1.1", + "msg_id": "00000000-0000-0000-0000-000000000000", + "payload": { + "_version": "1.1", + "notification_name": "Workspace Manual Build Failed", + "notification_template_id": "00000000-0000-0000-0000-000000000000", + "user_id": "00000000-0000-0000-0000-000000000000", + "user_email": "bobby@coder.com", + "user_name": "Bobby", + "user_username": "bobby", + "actions": [ + { + "label": "View build", + "url": "http://test.com/@mrbobby/bobby-workspace/builds/3" + } + ], + "labels": { + "initiator": "joe", + "name": "bobby-workspace", + "template_display_name": "William's Template", + "template_name": "bobby-template", + "template_version_name": "bobby-template-version", + "workspace_build_number": "3", + "workspace_owner_username": "mrbobby" + }, + "data": null + }, + "title": "Workspace \"bobby-workspace\" manual build failed", + "title_markdown": "Workspace \"bobby-workspace\" manual build failed", + "body": "Hi Bobby,\n\nA manual build of the workspace bobby-workspace using the template bobby-template failed (version: bobby-template-version).\n\nThe template's display name was William's Template. The workspace build was initiated by joe.", + "body_markdown": "Hi Bobby,\n\nA manual build of the workspace **bobby-workspace** using the template **bobby-template** failed (version: **bobby-template-version**).\n\nThe template's display name was **William's Template**. The workspace build was initiated by **joe**." +} \ No newline at end of file diff --git a/coderd/notifications/testdata/rendered-templates/webhook/TemplateWorkspaceMarkedForDeletion.json.golden b/coderd/notifications/testdata/rendered-templates/webhook/TemplateWorkspaceMarkedForDeletion.json.golden new file mode 100644 index 0000000000000..3cb1690b0b583 --- /dev/null +++ b/coderd/notifications/testdata/rendered-templates/webhook/TemplateWorkspaceMarkedForDeletion.json.golden @@ -0,0 +1,30 @@ +{ + "_version": "1.1", + "msg_id": "00000000-0000-0000-0000-000000000000", + "payload": { + "_version": "1.1", + "notification_name": "Workspace Marked for Deletion", + "notification_template_id": "00000000-0000-0000-0000-000000000000", + "user_id": "00000000-0000-0000-0000-000000000000", + "user_email": "bobby@coder.com", + "user_name": "Bobby", + "user_username": "bobby", + "actions": [ + { + "label": "View workspace", + "url": "http://test.com/@bobby/bobby-workspace" + } + ], + "labels": { + "dormancyHours": "24", + "name": "bobby-workspace", + "reason": "template updated to new dormancy policy", + "timeTilDormant": "24 hours" + }, + "data": null + }, + "title": "Workspace \"bobby-workspace\" marked for deletion", + "title_markdown": "Workspace \"bobby-workspace\" marked for deletion", + "body": "Hi Bobby,\n\nYour workspace bobby-workspace has been marked for deletion after 24 hours of dormancy (https://coder.com/docs/templates/schedule#dormancy-auto-deletion-enterprise) because of template updated to new dormancy policy.\nTo prevent deletion, use your workspace with the link below.", + "body_markdown": "Hi Bobby,\n\nYour workspace **bobby-workspace** has been marked for **deletion** after 24 hours of [dormancy](https://coder.com/docs/templates/schedule#dormancy-auto-deletion-enterprise) because of template updated to new dormancy policy.\nTo prevent deletion, use your workspace with the link below." +} \ No newline at end of file diff --git a/coderd/notifications/testdata/rendered-templates/webhook/TemplateYourAccountActivated.json.golden b/coderd/notifications/testdata/rendered-templates/webhook/TemplateYourAccountActivated.json.golden new file mode 100644 index 0000000000000..2e01ab7c631dc --- /dev/null +++ b/coderd/notifications/testdata/rendered-templates/webhook/TemplateYourAccountActivated.json.golden @@ -0,0 +1,28 @@ +{ + "_version": "1.1", + "msg_id": "00000000-0000-0000-0000-000000000000", + "payload": { + "_version": "1.1", + "notification_name": "Your account has been activated", + "notification_template_id": "00000000-0000-0000-0000-000000000000", + "user_id": "00000000-0000-0000-0000-000000000000", + "user_email": "bobby@coder.com", + "user_name": "Bobby", + "user_username": "bobby", + "actions": [ + { + "label": "Open Coder", + "url": "http://test.com" + } + ], + "labels": { + "activated_account_name": "bobby", + "initiator": "rob" + }, + "data": null + }, + "title": "Your account \"bobby\" has been activated", + "title_markdown": "Your account \"bobby\" has been activated", + "body": "Hi Bobby,\n\nYour account bobby has been activated by rob.", + "body_markdown": "Hi Bobby,\n\nYour account **bobby** has been activated by **rob**." +} \ No newline at end of file diff --git a/coderd/notifications/testdata/rendered-templates/webhook/TemplateYourAccountSuspended.json.golden b/coderd/notifications/testdata/rendered-templates/webhook/TemplateYourAccountSuspended.json.golden new file mode 100644 index 0000000000000..53516dbdab5ce --- /dev/null +++ b/coderd/notifications/testdata/rendered-templates/webhook/TemplateYourAccountSuspended.json.golden @@ -0,0 +1,23 @@ +{ + "_version": "1.1", + "msg_id": "00000000-0000-0000-0000-000000000000", + "payload": { + "_version": "1.1", + "notification_name": "Your account has been suspended", + "notification_template_id": "00000000-0000-0000-0000-000000000000", + "user_id": "00000000-0000-0000-0000-000000000000", + "user_email": "bobby@coder.com", + "user_name": "Bobby", + "user_username": "bobby", + "actions": [], + "labels": { + "initiator": "rob", + "suspended_account_name": "bobby" + }, + "data": null + }, + "title": "Your account \"bobby\" has been suspended", + "title_markdown": "Your account \"bobby\" has been suspended", + "body": "Hi Bobby,\n\nYour account bobby has been suspended by rob.", + "body_markdown": "Hi Bobby,\n\nYour account **bobby** has been suspended by **rob**." +} \ No newline at end of file diff --git a/coderd/users.go b/coderd/users.go index 2356bf2211a61..78b88ba892426 100644 --- a/coderd/users.go +++ b/coderd/users.go @@ -604,7 +604,7 @@ func (api *API) deleteUser(rw http.ResponseWriter, r *http.Request) { map[string]string{ "deleted_account_name": user.Username, "deleted_account_user_name": user.Name, - "account_deleter_user_name": accountDeleter.Name, + "initiator": accountDeleter.Name, }, "api-users-delete", user.ID, @@ -918,7 +918,7 @@ func (api *API) notifyUserStatusChanged(ctx context.Context, actingUserName stri labels = map[string]string{ "suspended_account_name": targetUser.Username, "suspended_account_user_name": targetUser.Name, - "account_suspender_user_name": actingUserName, + "initiator": actingUserName, } adminTemplateID = notifications.TemplateUserAccountSuspended personalTemplateID = notifications.TemplateYourAccountSuspended @@ -926,7 +926,7 @@ func (api *API) notifyUserStatusChanged(ctx context.Context, actingUserName stri labels = map[string]string{ "activated_account_name": targetUser.Username, "activated_account_user_name": targetUser.Name, - "account_activator_user_name": actingUserName, + "initiator": actingUserName, } adminTemplateID = notifications.TemplateUserAccountActivated personalTemplateID = notifications.TemplateYourAccountActivated @@ -1407,7 +1407,7 @@ func (api *API) CreateUser(ctx context.Context, store database.Store, req Create map[string]string{ "created_account_name": user.Username, "created_account_user_name": user.Name, - "account_creator": req.accountCreatorName, + "initiator": req.accountCreatorName, }, "api-users-create", user.ID, ); err != nil { diff --git a/coderd/users_test.go b/coderd/users_test.go index 7406df75bf1db..ff7c63e63bebc 100644 --- a/coderd/users_test.go +++ b/coderd/users_test.go @@ -517,7 +517,7 @@ func TestNotifyDeletedUser(t *testing.T) { require.Contains(t, notifyEnq.Sent[1].Targets, user.ID) require.Equal(t, user.Username, notifyEnq.Sent[1].Labels["deleted_account_name"]) require.Equal(t, user.Name, notifyEnq.Sent[1].Labels["deleted_account_user_name"]) - require.Equal(t, firstUser.Name, notifyEnq.Sent[1].Labels["account_deleter_user_name"]) + require.Equal(t, firstUser.Name, notifyEnq.Sent[1].Labels["initiator"]) }) t.Run("UserAdminNotified", func(t *testing.T) {