From 208ed1efd7ce1bb55b6bc923971ef33e3a9c5a72 Mon Sep 17 00:00:00 2001 From: Sas Swart Date: Mon, 14 Oct 2024 14:34:32 +0200 Subject: [PATCH] chore(coderd/notifications): expand golden file testing for notifications (#15032) This PR aims to close https://github.com/coder/coder/issues/14913. It expands the golden files for the notifier to include the entire payload serialised as JSON. --- .github/workflows/typos.toml | 2 + ...ent_notification_initiator_naming.down.sql | 55 +++ ...stent_notification_initiator_naming.up.sql | 57 +++ coderd/notifications/dispatch/smtp_test.go | 42 +- .../dispatch/{ => smtptest}/fixtures/ca.conf | 0 .../dispatch/{ => smtptest}/fixtures/ca.crt | 0 .../dispatch/{ => smtptest}/fixtures/ca.key | 0 .../dispatch/{ => smtptest}/fixtures/ca.srl | 0 .../{ => smtptest}/fixtures/generate.sh | 0 .../{ => smtptest}/fixtures/password.txt | 0 .../{ => smtptest}/fixtures/server.conf | 0 .../{ => smtptest}/fixtures/server.crt | 0 .../{ => smtptest}/fixtures/server.csr | 0 .../{ => smtptest}/fixtures/server.key | 0 .../{ => smtptest}/fixtures/v3_ext.conf | 0 .../{smtp_util_test.go => smtptest/server.go} | 20 +- coderd/notifications/notifications_test.go | 429 +++++++++++++++--- .../TemplateTemplateDeleted-body.md.golden | 5 - .../TemplateTemplateDeleted-title.md.golden | 1 - ...emplateUserAccountActivated-body.md.golden | 5 - ...mplateUserAccountActivated-title.md.golden | 1 - .../TemplateUserAccountCreated-body.md.golden | 5 - ...TemplateUserAccountCreated-title.md.golden | 1 - .../TemplateUserAccountDeleted-body.md.golden | 5 - ...TemplateUserAccountDeleted-title.md.golden | 1 - ...emplateUserAccountSuspended-body.md.golden | 5 - ...mplateUserAccountSuspended-title.md.golden | 1 - ...serRequestedOneTimePasscode-body.md.golden | 7 - ...erRequestedOneTimePasscode-title.md.golden | 1 - ...emplateWorkspaceAutoUpdated-body.md.golden | 5 - ...mplateWorkspaceAutoUpdated-title.md.golden | 1 - ...ateWorkspaceAutobuildFailed-body.md.golden | 5 - ...teWorkspaceAutobuildFailed-title.md.golden | 1 - ...WorkspaceBuildsFailedReport-body.md.golden | 17 - ...orkspaceBuildsFailedReport-title.md.golden | 1 - .../TemplateWorkspaceDeleted-body.md.golden | 5 - .../TemplateWorkspaceDeleted-title.md.golden | 1 - .../TemplateWorkspaceDormant-body.md.golden | 5 - .../TemplateWorkspaceDormant-title.md.golden | 1 - ...eWorkspaceManualBuildFailed-body.md.golden | 5 - ...WorkspaceManualBuildFailed-title.md.golden | 1 - ...eWorkspaceMarkedForDeletion-body.md.golden | 4 - ...WorkspaceMarkedForDeletion-title.md.golden | 1 - ...emplateYourAccountActivated-body.md.golden | 3 - ...mplateYourAccountActivated-title.md.golden | 1 - ...emplateYourAccountSuspended-body.md.golden | 3 - ...mplateYourAccountSuspended-title.md.golden | 1 - .../smtp/TemplateTemplateDeleted.html.golden | 83 ++++ .../TemplateUserAccountActivated.html.golden | 84 ++++ .../TemplateUserAccountCreated.html.golden | 83 ++++ .../TemplateUserAccountDeleted.html.golden | 83 ++++ .../TemplateUserAccountSuspended.html.golden | 85 ++++ ...teUserRequestedOneTimePasscode.html.golden | 80 ++++ .../TemplateWorkspaceAutoUpdated.html.golden | 83 ++++ ...mplateWorkspaceAutobuildFailed.html.golden | 82 ++++ ...ateWorkspaceBuildsFailedReport.html.golden | 126 +++++ .../smtp/TemplateWorkspaceDeleted.html.golden | 90 ++++ .../smtp/TemplateWorkspaceDormant.html.golden | 90 ++++ ...lateWorkspaceManualBuildFailed.html.golden | 86 ++++ ...lateWorkspaceMarkedForDeletion.html.golden | 84 ++++ .../TemplateYourAccountActivated.html.golden | 78 ++++ .../TemplateYourAccountSuspended.html.golden | 70 +++ .../TemplateTemplateDeleted.json.golden | 29 ++ .../TemplateUserAccountActivated.json.golden | 29 ++ .../TemplateUserAccountCreated.json.golden | 29 ++ .../TemplateUserAccountDeleted.json.golden | 29 ++ .../TemplateUserAccountSuspended.json.golden | 29 ++ ...teUserRequestedOneTimePasscode.json.golden | 22 + .../TemplateWorkspaceAutoUpdated.json.golden | 29 ++ ...mplateWorkspaceAutobuildFailed.json.golden | 28 ++ ...ateWorkspaceBuildsFailedReport.json.golden | 66 +++ .../TemplateWorkspaceDeleted.json.golden | 33 ++ .../TemplateWorkspaceDormant.json.golden | 31 ++ ...lateWorkspaceManualBuildFailed.json.golden | 33 ++ ...lateWorkspaceMarkedForDeletion.json.golden | 30 ++ .../TemplateYourAccountActivated.json.golden | 28 ++ .../TemplateYourAccountSuspended.json.golden | 23 + coderd/users.go | 8 +- coderd/users_test.go | 2 +- 79 files changed, 2265 insertions(+), 204 deletions(-) create mode 100644 coderd/database/migrations/000263_consistent_notification_initiator_naming.down.sql create mode 100644 coderd/database/migrations/000263_consistent_notification_initiator_naming.up.sql rename coderd/notifications/dispatch/{ => smtptest}/fixtures/ca.conf (100%) rename coderd/notifications/dispatch/{ => smtptest}/fixtures/ca.crt (100%) rename coderd/notifications/dispatch/{ => smtptest}/fixtures/ca.key (100%) rename coderd/notifications/dispatch/{ => smtptest}/fixtures/ca.srl (100%) rename coderd/notifications/dispatch/{ => smtptest}/fixtures/generate.sh (100%) rename coderd/notifications/dispatch/{ => smtptest}/fixtures/password.txt (100%) rename coderd/notifications/dispatch/{ => smtptest}/fixtures/server.conf (100%) rename coderd/notifications/dispatch/{ => smtptest}/fixtures/server.crt (100%) rename coderd/notifications/dispatch/{ => smtptest}/fixtures/server.csr (100%) rename coderd/notifications/dispatch/{ => smtptest}/fixtures/server.key (100%) rename coderd/notifications/dispatch/{ => smtptest}/fixtures/v3_ext.conf (100%) rename coderd/notifications/dispatch/{smtp_util_test.go => smtptest/server.go} (90%) delete mode 100644 coderd/notifications/testdata/rendered-templates/TemplateTemplateDeleted-body.md.golden delete mode 100644 coderd/notifications/testdata/rendered-templates/TemplateTemplateDeleted-title.md.golden delete mode 100644 coderd/notifications/testdata/rendered-templates/TemplateUserAccountActivated-body.md.golden delete mode 100644 coderd/notifications/testdata/rendered-templates/TemplateUserAccountActivated-title.md.golden delete mode 100644 coderd/notifications/testdata/rendered-templates/TemplateUserAccountCreated-body.md.golden delete mode 100644 coderd/notifications/testdata/rendered-templates/TemplateUserAccountCreated-title.md.golden delete mode 100644 coderd/notifications/testdata/rendered-templates/TemplateUserAccountDeleted-body.md.golden delete mode 100644 coderd/notifications/testdata/rendered-templates/TemplateUserAccountDeleted-title.md.golden delete mode 100644 coderd/notifications/testdata/rendered-templates/TemplateUserAccountSuspended-body.md.golden delete mode 100644 coderd/notifications/testdata/rendered-templates/TemplateUserAccountSuspended-title.md.golden delete mode 100644 coderd/notifications/testdata/rendered-templates/TemplateUserRequestedOneTimePasscode-body.md.golden delete mode 100644 coderd/notifications/testdata/rendered-templates/TemplateUserRequestedOneTimePasscode-title.md.golden delete mode 100644 coderd/notifications/testdata/rendered-templates/TemplateWorkspaceAutoUpdated-body.md.golden delete mode 100644 coderd/notifications/testdata/rendered-templates/TemplateWorkspaceAutoUpdated-title.md.golden delete mode 100644 coderd/notifications/testdata/rendered-templates/TemplateWorkspaceAutobuildFailed-body.md.golden delete mode 100644 coderd/notifications/testdata/rendered-templates/TemplateWorkspaceAutobuildFailed-title.md.golden delete mode 100644 coderd/notifications/testdata/rendered-templates/TemplateWorkspaceBuildsFailedReport-body.md.golden delete mode 100644 coderd/notifications/testdata/rendered-templates/TemplateWorkspaceBuildsFailedReport-title.md.golden delete mode 100644 coderd/notifications/testdata/rendered-templates/TemplateWorkspaceDeleted-body.md.golden delete mode 100644 coderd/notifications/testdata/rendered-templates/TemplateWorkspaceDeleted-title.md.golden delete mode 100644 coderd/notifications/testdata/rendered-templates/TemplateWorkspaceDormant-body.md.golden delete mode 100644 coderd/notifications/testdata/rendered-templates/TemplateWorkspaceDormant-title.md.golden delete mode 100644 coderd/notifications/testdata/rendered-templates/TemplateWorkspaceManualBuildFailed-body.md.golden delete mode 100644 coderd/notifications/testdata/rendered-templates/TemplateWorkspaceManualBuildFailed-title.md.golden delete mode 100644 coderd/notifications/testdata/rendered-templates/TemplateWorkspaceMarkedForDeletion-body.md.golden delete mode 100644 coderd/notifications/testdata/rendered-templates/TemplateWorkspaceMarkedForDeletion-title.md.golden delete mode 100644 coderd/notifications/testdata/rendered-templates/TemplateYourAccountActivated-body.md.golden delete mode 100644 coderd/notifications/testdata/rendered-templates/TemplateYourAccountActivated-title.md.golden delete mode 100644 coderd/notifications/testdata/rendered-templates/TemplateYourAccountSuspended-body.md.golden delete mode 100644 coderd/notifications/testdata/rendered-templates/TemplateYourAccountSuspended-title.md.golden create mode 100644 coderd/notifications/testdata/rendered-templates/smtp/TemplateTemplateDeleted.html.golden create mode 100644 coderd/notifications/testdata/rendered-templates/smtp/TemplateUserAccountActivated.html.golden create mode 100644 coderd/notifications/testdata/rendered-templates/smtp/TemplateUserAccountCreated.html.golden create mode 100644 coderd/notifications/testdata/rendered-templates/smtp/TemplateUserAccountDeleted.html.golden create mode 100644 coderd/notifications/testdata/rendered-templates/smtp/TemplateUserAccountSuspended.html.golden create mode 100644 coderd/notifications/testdata/rendered-templates/smtp/TemplateUserRequestedOneTimePasscode.html.golden create mode 100644 coderd/notifications/testdata/rendered-templates/smtp/TemplateWorkspaceAutoUpdated.html.golden create mode 100644 coderd/notifications/testdata/rendered-templates/smtp/TemplateWorkspaceAutobuildFailed.html.golden create mode 100644 coderd/notifications/testdata/rendered-templates/smtp/TemplateWorkspaceBuildsFailedReport.html.golden create mode 100644 coderd/notifications/testdata/rendered-templates/smtp/TemplateWorkspaceDeleted.html.golden create mode 100644 coderd/notifications/testdata/rendered-templates/smtp/TemplateWorkspaceDormant.html.golden create mode 100644 coderd/notifications/testdata/rendered-templates/smtp/TemplateWorkspaceManualBuildFailed.html.golden create mode 100644 coderd/notifications/testdata/rendered-templates/smtp/TemplateWorkspaceMarkedForDeletion.html.golden create mode 100644 coderd/notifications/testdata/rendered-templates/smtp/TemplateYourAccountActivated.html.golden create mode 100644 coderd/notifications/testdata/rendered-templates/smtp/TemplateYourAccountSuspended.html.golden create mode 100644 coderd/notifications/testdata/rendered-templates/webhook/TemplateTemplateDeleted.json.golden create mode 100644 coderd/notifications/testdata/rendered-templates/webhook/TemplateUserAccountActivated.json.golden create mode 100644 coderd/notifications/testdata/rendered-templates/webhook/TemplateUserAccountCreated.json.golden create mode 100644 coderd/notifications/testdata/rendered-templates/webhook/TemplateUserAccountDeleted.json.golden create mode 100644 coderd/notifications/testdata/rendered-templates/webhook/TemplateUserAccountSuspended.json.golden create mode 100644 coderd/notifications/testdata/rendered-templates/webhook/TemplateUserRequestedOneTimePasscode.json.golden create mode 100644 coderd/notifications/testdata/rendered-templates/webhook/TemplateWorkspaceAutoUpdated.json.golden create mode 100644 coderd/notifications/testdata/rendered-templates/webhook/TemplateWorkspaceAutobuildFailed.json.golden create mode 100644 coderd/notifications/testdata/rendered-templates/webhook/TemplateWorkspaceBuildsFailedReport.json.golden create mode 100644 coderd/notifications/testdata/rendered-templates/webhook/TemplateWorkspaceDeleted.json.golden create mode 100644 coderd/notifications/testdata/rendered-templates/webhook/TemplateWorkspaceDormant.json.golden create mode 100644 coderd/notifications/testdata/rendered-templates/webhook/TemplateWorkspaceManualBuildFailed.json.golden create mode 100644 coderd/notifications/testdata/rendered-templates/webhook/TemplateWorkspaceMarkedForDeletion.json.golden create mode 100644 coderd/notifications/testdata/rendered-templates/webhook/TemplateYourAccountActivated.json.golden create mode 100644 coderd/notifications/testdata/rendered-templates/webhook/TemplateYourAccountSuspended.json.golden diff --git a/.github/workflows/typos.toml b/.github/workflows/typos.toml index a9748c2d19..b384068e83 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 0000000000..0e7823a338 --- /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 0000000000..1357e7a1ef --- /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 eb12f05ad4..2687e0d82b 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 44cb8725c5..689b4d3840 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 28bd8b5190..d6eb480f75 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) + t.Run("smtp", func(t *testing.T) { + t.Parallel() - 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) + // 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) - 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") + _, 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 + }() - 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") + // nolint:gocritic // Unit test. + ctx := dbauthz.AsSystemRestricted(testutil.Context(t, testutil.WaitSuperLong)) - 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") + // smtp config shared between client and server + smtpConfig := codersdk.NotificationsEmailConfig{ + Hello: hello, + From: from, - 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 - } + Auth: codersdk.NotificationsEmailAuthConfig{ + Username: username, + Password: password, + }, + } - const hint = "run \"DB=ci make update-golden-files\" and commit the changes" + // Spin up the mock SMTP server + backend := smtptest.NewBackend(smtptest.Config{ + AuthMechanisms: []string{sasl.Login}, - 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)) + AcceptedIdentity: smtpConfig.Auth.Identity.String(), + AcceptedUsername: username, + AcceptedPassword: password, + }) - 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)) + // 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 ade9c87ff7..0000000000 --- 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 c3f3db7645..0000000000 --- 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 5a773a51dc..0000000000 --- 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 ebf8e9da36..0000000000 --- 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 88a46735f0..0000000000 --- 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 bfcdf6826f..0000000000 --- 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 4ca8bedd0c..0000000000 --- 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 199d4ddd66..0000000000 --- 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 ecf276504e..0000000000 --- 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 f2be8e201f..0000000000 --- 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 6288af33f8..0000000000 --- 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 ecf7383911..0000000000 --- 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 d9f4e27cb4..0000000000 --- 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 fb62dcd0d3..0000000000 --- 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 cddf2149d0..0000000000 --- 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 9cf98bc9e5..0000000000 --- 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 e896a0a8c9..0000000000 --- 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 f03f8fca96..0000000000 --- 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 a5c71fb3e0..0000000000 --- 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 6806624053..0000000000 --- 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 35bfe8d2c1..0000000000 --- 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 ce34a2a029..0000000000 --- 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 e1091b2888..0000000000 --- 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 e786626b74..0000000000 --- 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 21defa7c1d..0000000000 --- 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 1b561a7367..0000000000 --- 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 a3a8710de4..0000000000 --- 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 90be1ef2dd..0000000000 --- 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 86fc404017..0000000000 --- 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 3a4cb57c8a..0000000000 --- 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 0000000000..ec7c3cfdce --- /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 + + + + + + + Template "bobby-template" deleted + + +
+
+ 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 0000000000..81cbe7f54f --- /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 + + + + + + + User account "bobby" activated + + +
+
+ 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 0000000000..9a6cab0989 --- /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 + + + + + + + User account "bobby" created + + +
+
+ 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 0000000000..c7daad54f0 --- /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 + + + + + + + User account "bobby" deleted + + +
+
+ 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 0000000000..ccd40593ef --- /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 + + + + + + + User account "bobby" suspended + + +
+
+ 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 0000000000..2b61765813 --- /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 + + + + + + + Your One-Time Passcode for Coder. + + +
+
+ 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 0000000000..6c68cffa8b --- /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 + + + + + + + Workspace "bobby-workspace" updated automatically + + +
+
+ 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 0000000000..340e794f15 --- /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 + + + + + + + Workspace "bobby-workspace" autobuild failed + + +
+
+ 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 0000000000..7cc16f00f3 --- /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 + + + + + + + Workspace builds failed for template "Bobby First Template"</tit= +le> + </head> + <body style=3D"margin: 0; padding: 0; font-family: -apple-system, system-= +ui, BlinkMacSystemFont, 'Segoe UI', 'Roboto', 'Oxygen', 'Ubuntu', 'Cantarel= +l', 'Fira Sans', 'Droid Sans', 'Helvetica Neue', sans-serif; color: #020617= +; background: #f8fafc;"> + <div style=3D"max-width: 600px; margin: 20px auto; padding: 60px; borde= +r: 1px solid #e2e8f0; border-radius: 8px; background-color: #fff; text-alig= +n: left; font-size: 14px; line-height: 1.5;"> + <div style=3D"text-align: center;"> + <img src=3D"https://coder.com/coder-logo-horizontal.png" alt=3D"Cod= +er Logo" style=3D"height: 40px;" /> + </div> + <h1 style=3D"text-align: center; font-size: 24px; font-weight: 400; m= +argin: 8px 0 32px; line-height: 1.5;"> + Workspace builds failed for template "Bobby First Template" + </h1> + <div style=3D"line-height: 1.5;"> + <p>Hi Bobby,</p> + +<p>Template <strong>Bobby First Template</strong> has failed to build <sup>= +4</sup>⁄<sub>55</sub> times over the last week.</p> + +<p><strong>Report:</strong></p> + +<p><strong>bobby-template-version-1</strong> failed 3 times:</p> + +<ul> +<li><a href=3D"http://test.com/@mtojek/workspace-1/builds/1234">mtojek / wo= +rkspace-1 / #1234</a><br> +</li> +<li><a href=3D"http://test.com/@johndoe/my-workspace-3/builds/5678">johndoe= + / my-workspace-3 / #5678</a><br> +</li> +<li><a href=3D"http://test.com/@jack/workwork/builds/774">jack / workwork /= + #774</a><br> +</li> +</ul> + +<p><strong>bobby-template-version-2</strong> failed 1 time:</p> + +<ul> +<li><a href=3D"http://test.com/@ben/cool-workspace/builds/8888">ben / cool-= +workspace / #8888</a><br> +</li> +</ul> + +<p>We recommend reviewing these issues to ensure future builds are successf= +ul.</p> + </div> + <div style=3D"text-align: center; margin-top: 32px;"> + =20 + <a href=3D"http://test.com/workspaces?filter=3Dtemplate%3Abobby-fir= +st-template" style=3D"display: inline-block; padding: 13px 24px; background= +-color: #020617; color: #f8fafc; text-decoration: none; border-radius: 8px;= + margin: 0 4px;"> + View workspaces + </a> + =20 + </div> + <div style=3D"border-top: 1px solid #e2e8f0; color: #475569; font-siz= +e: 12px; margin-top: 64px; padding-top: 24px; line-height: 1.6;"> + <p>© 2024 Coder. All rights reserved - <a = +href=3D"http://test.com" style=3D"color: #2563eb; text-decoration: none;">h= +ttp://test.com</a></p> + <p><a href=3D"http://test.com/settings/notifications" style=3D"colo= +r: #2563eb; text-decoration: none;">Click here to manage your notification = +settings</a></p> + <p><a href=3D"http://test.com/settings/notifications?disabled=3D34a= +20db2-e9cc-4a93-b0e4-8569699d7a00" style=3D"color: #2563eb; text-decoration= +: none;">Stop receiving emails like this</a></p> + </div> + </div> + </body> +</html> + +--bbe61b741255b6098bb6b3c1f41b885773df633cb18d2a3002b68e4bc9c4-- diff --git a/coderd/notifications/testdata/rendered-templates/smtp/TemplateWorkspaceDeleted.html.golden b/coderd/notifications/testdata/rendered-templates/smtp/TemplateWorkspaceDeleted.html.golden new file mode 100644 index 0000000000..0d821bdc4d --- /dev/null +++ b/coderd/notifications/testdata/rendered-templates/smtp/TemplateWorkspaceDeleted.html.golden @@ -0,0 +1,90 @@ +From: system@coder.com +To: bobby@coder.com +Subject: Workspace "bobby-workspace" 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, + +Your workspace bobby-workspace was deleted. + +The specified reason was "autodeleted due to dormancy (autobuild)". + + +View workspaces: http://test.com/workspaces + +View templates: http://test.com/templates + +--bbe61b741255b6098bb6b3c1f41b885773df633cb18d2a3002b68e4bc9c4 +Content-Transfer-Encoding: quoted-printable +Content-Type: text/html; charset=UTF-8 + +<!doctype html> +<html lang=3D"en"> + <head> + <meta charset=3D"UTF-8" /> + <meta name=3D"viewport" content=3D"width=3Ddevice-width, initial-scale= +=3D1.0" /> + <title>Workspace "bobby-workspace" deleted + + +
+
+ 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 0000000000..0c6cbf5a2d --- /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 + + + + + + + Workspace "bobby-workspace" marked as dormant + + +
+
+ 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 0000000000..a1711b70ea --- /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 + + + + + + + Workspace "bobby-workspace" manual build failed + + +
+
+ 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 +
+ +
+ + + +--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 0000000000..6d91458f2c --- /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 + + + + + + + Workspace "bobby-workspace" marked for deletion + + +
+
+ 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 0000000000..aef12ab957 --- /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 + + + + + + + Your account "bobby" has been activated + + +
+
+ 3D"Cod= +
+

+ Your account "bobby" has been activated +

+
+

Hi Bobby,

+ +

Your account bobby has been activated by rob.

+
+
+ =20 + + Open Coder + + =20 +
+ +
+ + + +--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 0000000000..d9406e2c1f --- /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 + + + + + + + Your account "bobby" has been suspended + + +
+
+ 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 0000000000..4a97b3a14f --- /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 0000000000..5da6908758 --- /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 0000000000..272a5628a2 --- /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 0000000000..10b7ddbca6 --- /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 0000000000..04146d5e71 --- /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 0000000000..2c03fc7c71 --- /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 0000000000..917904a249 --- /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 0000000000..45b64a31a0 --- /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 0000000000..c6dabbfb89 --- /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 0000000000..171e893dd9 --- /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 0000000000..00c591d9d1 --- /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 0000000000..8fe2b8b86f --- /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 0000000000..3cb1690b0b --- /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 0000000000..2e01ab7c63 --- /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 0000000000..53516dbdab --- /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 2356bf2211..78b88ba892 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 7406df75bf..ff7c63e63b 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) {