From ecd43f12bab12a500b2bf167668df085f33aa198 Mon Sep 17 00:00:00 2001 From: Danielle Maywood Date: Tue, 22 Oct 2024 08:46:37 +0000 Subject: [PATCH 1/7] fix: show audit logs for forgot password flow --- coderd/apidoc/docs.go | 6 ++++-- coderd/apidoc/swagger.json | 6 ++++-- coderd/audit.go | 18 ++++++++++++---- coderd/database/dump.sql | 3 ++- ..._add_audit_action_forgot_password.down.sql | 2 ++ ...68_add_audit_action_forgot_password.up.sql | 2 ++ coderd/database/models.go | 21 +++++++++++-------- coderd/database/pubsub/psmock/psmock.go | 3 ++- coderd/userauth.go | 4 +++- codersdk/audit.go | 19 ++++++++++------- docs/reference/api/schemas.md | 21 ++++++++++--------- enterprise/audit/table.go | 2 +- site/src/api/typesGenerated.ts | 4 ++-- .../AuditLogRow/AuditLogDiff/AuditLogDiff.tsx | 21 +++++++++++++++++++ 14 files changed, 91 insertions(+), 41 deletions(-) create mode 100644 coderd/database/migrations/000268_add_audit_action_forgot_password.down.sql create mode 100644 coderd/database/migrations/000268_add_audit_action_forgot_password.up.sql diff --git a/coderd/apidoc/docs.go b/coderd/apidoc/docs.go index 90bb94e8d132a..ba546014bc3b7 100644 --- a/coderd/apidoc/docs.go +++ b/coderd/apidoc/docs.go @@ -9116,7 +9116,8 @@ const docTemplate = `{ "stop", "login", "logout", - "register" + "register", + "request_one_time_passcode" ], "x-enum-varnames": [ "AuditActionCreate", @@ -9126,7 +9127,8 @@ const docTemplate = `{ "AuditActionStop", "AuditActionLogin", "AuditActionLogout", - "AuditActionRegister" + "AuditActionRegister", + "AuditActionRequestOneTimePasscode" ] }, "codersdk.AuditDiff": { diff --git a/coderd/apidoc/swagger.json b/coderd/apidoc/swagger.json index 7429cef850c0a..e8d45351a62c1 100644 --- a/coderd/apidoc/swagger.json +++ b/coderd/apidoc/swagger.json @@ -8090,7 +8090,8 @@ "stop", "login", "logout", - "register" + "register", + "request_one_time_passcode" ], "x-enum-varnames": [ "AuditActionCreate", @@ -8100,7 +8101,8 @@ "AuditActionStop", "AuditActionLogin", "AuditActionLogout", - "AuditActionRegister" + "AuditActionRegister", + "AuditActionRequestOneTimePasscode" ] }, "codersdk.AuditDiff": { diff --git a/coderd/audit.go b/coderd/audit.go index 6d9a23ad217a5..3dc6fcad6ec04 100644 --- a/coderd/audit.go +++ b/coderd/audit.go @@ -274,8 +274,15 @@ func (api *API) convertAuditLog(ctx context.Context, dblog database.GetAuditLogs func auditLogDescription(alog database.GetAuditLogsOffsetRow) string { b := strings.Builder{} + // NOTE: WriteString always returns a nil error, so we never check it - _, _ = b.WriteString("{user} ") + + // Requesting a one-time passcode can be performed by anyone that knows the email + // of a user so saying the user performed this action might be slightly misleading. + if alog.AuditLog.Action != database.AuditActionRequestOneTimePasscode { + _, _ = b.WriteString("{user} ") + } + if alog.AuditLog.StatusCode >= 400 { _, _ = b.WriteString("unsuccessfully attempted to ") _, _ = b.WriteString(string(alog.AuditLog.Action)) @@ -298,13 +305,16 @@ func auditLogDescription(alog database.GetAuditLogsOffsetRow) string { return b.String() } - _, _ = b.WriteString(" ") - _, _ = b.WriteString(codersdk.ResourceType(alog.AuditLog.ResourceType).FriendlyString()) + if alog.AuditLog.Action == database.AuditActionRequestOneTimePasscode { + _, _ = b.WriteString(" for") + } else { + _, _ = b.WriteString(" ") + _, _ = b.WriteString(codersdk.ResourceType(alog.AuditLog.ResourceType).FriendlyString()) + } if alog.AuditLog.ResourceType == database.ResourceTypeConvertLogin { _, _ = b.WriteString(" to") } - _, _ = b.WriteString(" {target}") return b.String() diff --git a/coderd/database/dump.sql b/coderd/database/dump.sql index 626d00cc81b41..67243cf65417b 100644 --- a/coderd/database/dump.sql +++ b/coderd/database/dump.sql @@ -19,7 +19,8 @@ CREATE TYPE audit_action AS ENUM ( 'stop', 'login', 'logout', - 'register' + 'register', + 'request_one_time_passcode' ); CREATE TYPE automatic_updates AS ENUM ( diff --git a/coderd/database/migrations/000268_add_audit_action_forgot_password.down.sql b/coderd/database/migrations/000268_add_audit_action_forgot_password.down.sql new file mode 100644 index 0000000000000..d1d1637f4fa90 --- /dev/null +++ b/coderd/database/migrations/000268_add_audit_action_forgot_password.down.sql @@ -0,0 +1,2 @@ +-- It's not possible to drop enum values from enum types, so the UP has "IF NOT +-- EXISTS". diff --git a/coderd/database/migrations/000268_add_audit_action_forgot_password.up.sql b/coderd/database/migrations/000268_add_audit_action_forgot_password.up.sql new file mode 100644 index 0000000000000..012a4074c8528 --- /dev/null +++ b/coderd/database/migrations/000268_add_audit_action_forgot_password.up.sql @@ -0,0 +1,2 @@ +ALTER TYPE audit_action + ADD VALUE IF NOT EXISTS 'request_one_time_passcode'; diff --git a/coderd/database/models.go b/coderd/database/models.go index 05b4c404ea16f..41afaab236e23 100644 --- a/coderd/database/models.go +++ b/coderd/database/models.go @@ -138,14 +138,15 @@ func AllAppSharingLevelValues() []AppSharingLevel { type AuditAction string const ( - AuditActionCreate AuditAction = "create" - AuditActionWrite AuditAction = "write" - AuditActionDelete AuditAction = "delete" - AuditActionStart AuditAction = "start" - AuditActionStop AuditAction = "stop" - AuditActionLogin AuditAction = "login" - AuditActionLogout AuditAction = "logout" - AuditActionRegister AuditAction = "register" + AuditActionCreate AuditAction = "create" + AuditActionWrite AuditAction = "write" + AuditActionDelete AuditAction = "delete" + AuditActionStart AuditAction = "start" + AuditActionStop AuditAction = "stop" + AuditActionLogin AuditAction = "login" + AuditActionLogout AuditAction = "logout" + AuditActionRegister AuditAction = "register" + AuditActionRequestOneTimePasscode AuditAction = "request_one_time_passcode" ) func (e *AuditAction) Scan(src interface{}) error { @@ -192,7 +193,8 @@ func (e AuditAction) Valid() bool { AuditActionStop, AuditActionLogin, AuditActionLogout, - AuditActionRegister: + AuditActionRegister, + AuditActionRequestOneTimePasscode: return true } return false @@ -208,6 +210,7 @@ func AllAuditActionValues() []AuditAction { AuditActionLogin, AuditActionLogout, AuditActionRegister, + AuditActionRequestOneTimePasscode, } } diff --git a/coderd/database/pubsub/psmock/psmock.go b/coderd/database/pubsub/psmock/psmock.go index 6f5841f758ab0..da26c66e45265 100644 --- a/coderd/database/pubsub/psmock/psmock.go +++ b/coderd/database/pubsub/psmock/psmock.go @@ -12,8 +12,9 @@ package psmock import ( reflect "reflect" - pubsub "github.com/coder/coder/v2/coderd/database/pubsub" gomock "go.uber.org/mock/gomock" + + pubsub "github.com/coder/coder/v2/coderd/database/pubsub" ) // MockPubsub is a mock of Pubsub interface. diff --git a/coderd/userauth.go b/coderd/userauth.go index 0ff3dfa8f97cc..8549afccaeec5 100644 --- a/coderd/userauth.go +++ b/coderd/userauth.go @@ -220,7 +220,7 @@ func (api *API) postRequestOneTimePasscode(rw http.ResponseWriter, r *http.Reque Audit: *auditor, Log: api.Logger, Request: r, - Action: database.AuditActionWrite, + Action: database.AuditActionRequestOneTimePasscode, }) ) defer commitAudit() @@ -253,6 +253,7 @@ func (api *API) postRequestOneTimePasscode(rw http.ResponseWriter, r *http.Reque } // We continue if err == sql.ErrNoRows to help prevent a timing-based attack. aReq.Old = user + aReq.UserID = user.ID passcode := uuid.New() passcodeExpiresAt := dbtime.Now().Add(api.OneTimePasscodeValidityPeriod) @@ -365,6 +366,7 @@ func (api *API) postChangePasswordWithOneTimePasscode(rw http.ResponseWriter, r } // We continue if err == sql.ErrNoRows to help prevent a timing-based attack. aReq.Old = user + aReq.UserID = user.ID equal, err := userpassword.Compare(string(user.HashedOneTimePasscode), req.OneTimePasscode) if err != nil { diff --git a/codersdk/audit.go b/codersdk/audit.go index 7d83c8e238ce0..570f11eab63b9 100644 --- a/codersdk/audit.go +++ b/codersdk/audit.go @@ -86,14 +86,15 @@ func (r ResourceType) FriendlyString() string { type AuditAction string const ( - AuditActionCreate AuditAction = "create" - AuditActionWrite AuditAction = "write" - AuditActionDelete AuditAction = "delete" - AuditActionStart AuditAction = "start" - AuditActionStop AuditAction = "stop" - AuditActionLogin AuditAction = "login" - AuditActionLogout AuditAction = "logout" - AuditActionRegister AuditAction = "register" + AuditActionCreate AuditAction = "create" + AuditActionWrite AuditAction = "write" + AuditActionDelete AuditAction = "delete" + AuditActionStart AuditAction = "start" + AuditActionStop AuditAction = "stop" + AuditActionLogin AuditAction = "login" + AuditActionLogout AuditAction = "logout" + AuditActionRegister AuditAction = "register" + AuditActionRequestOneTimePasscode AuditAction = "request_one_time_passcode" ) func (a AuditAction) Friendly() string { @@ -114,6 +115,8 @@ func (a AuditAction) Friendly() string { return "logged out" case AuditActionRegister: return "registered" + case AuditActionRequestOneTimePasscode: + return "one time passcode requested" default: return "unknown" } diff --git a/docs/reference/api/schemas.md b/docs/reference/api/schemas.md index ac8636f3e6f46..2045b21b33a57 100644 --- a/docs/reference/api/schemas.md +++ b/docs/reference/api/schemas.md @@ -513,16 +513,17 @@ #### Enumerated Values -| Value | -| ---------- | -| `create` | -| `write` | -| `delete` | -| `start` | -| `stop` | -| `login` | -| `logout` | -| `register` | +| Value | +| --------------------------- | +| `create` | +| `write` | +| `delete` | +| `start` | +| `stop` | +| `login` | +| `logout` | +| `register` | +| `request_one_time_passcode` | ## codersdk.AuditDiff diff --git a/enterprise/audit/table.go b/enterprise/audit/table.go index 15eaaeb11b4f5..baa9f33b18786 100644 --- a/enterprise/audit/table.go +++ b/enterprise/audit/table.go @@ -145,7 +145,7 @@ var auditableResourcesTypes = map[any]map[string]Action{ "theme_preference": ActionIgnore, "name": ActionTrack, "github_com_user_id": ActionIgnore, - "hashed_one_time_passcode": ActionSecret, // Do not expose a user's one time passcode. + "hashed_one_time_passcode": ActionIgnore, "one_time_passcode_expires_at": ActionTrack, "must_reset_password": ActionTrack, }, diff --git a/site/src/api/typesGenerated.ts b/site/src/api/typesGenerated.ts index 76be331a526cf..8947518dc6db8 100644 --- a/site/src/api/typesGenerated.ts +++ b/site/src/api/typesGenerated.ts @@ -2098,8 +2098,8 @@ export type AgentSubsystem = "envbox" | "envbuilder" | "exectrace" export const AgentSubsystems: AgentSubsystem[] = ["envbox", "envbuilder", "exectrace"] // From codersdk/audit.go -export type AuditAction = "create" | "delete" | "login" | "logout" | "register" | "start" | "stop" | "write" -export const AuditActions: AuditAction[] = ["create", "delete", "login", "logout", "register", "start", "stop", "write"] +export type AuditAction = "create" | "delete" | "login" | "logout" | "register" | "request_one_time_passcode" | "start" | "stop" | "write" +export const AuditActions: AuditAction[] = ["create", "delete", "login", "logout", "register", "request_one_time_passcode", "start", "stop", "write"] // From codersdk/workspaces.go export type AutomaticUpdates = "always" | "never" diff --git a/site/src/pages/AuditPage/AuditLogRow/AuditLogDiff/AuditLogDiff.tsx b/site/src/pages/AuditPage/AuditLogRow/AuditLogDiff/AuditLogDiff.tsx index 33a4f24b58385..584269c515190 100644 --- a/site/src/pages/AuditPage/AuditLogRow/AuditLogDiff/AuditLogDiff.tsx +++ b/site/src/pages/AuditPage/AuditLogRow/AuditLogDiff/AuditLogDiff.tsx @@ -9,6 +9,14 @@ const getDiffValue = (value: unknown): string => { return `"${value}"`; } + if (isTimeObject(value)) { + if (!value.Valid) { + return "null"; + } + + return new Date(value.Time).toLocaleString(); + } + if (Array.isArray(value)) { const values = value.map((v) => getDiffValue(v)); return `[${values.join(", ")}]`; @@ -21,6 +29,19 @@ const getDiffValue = (value: unknown): string => { return String(value); }; +const isTimeObject = ( + value: unknown, +): value is { Time: string; Valid: boolean } => { + return ( + value !== null && + typeof value === "object" && + "Time" in value && + typeof value.Time === "string" && + "Valid" in value && + typeof value.Valid === "boolean" + ); +}; + interface AuditLogDiffProps { diff: AuditDiff; } From 7809c49eac62e2b115c530eab666e15470c14e13 Mon Sep 17 00:00:00 2001 From: Danielle Maywood Date: Tue, 22 Oct 2024 09:03:38 +0000 Subject: [PATCH 2/7] chore: run 'make gen' --- coderd/audit.go | 1 + docs/admin/security/audit-logs.md | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/coderd/audit.go b/coderd/audit.go index 3dc6fcad6ec04..73a5fc56fbfb1 100644 --- a/coderd/audit.go +++ b/coderd/audit.go @@ -315,6 +315,7 @@ func auditLogDescription(alog database.GetAuditLogsOffsetRow) string { if alog.AuditLog.ResourceType == database.ResourceTypeConvertLogin { _, _ = b.WriteString(" to") } + _, _ = b.WriteString(" {target}") return b.String() diff --git a/docs/admin/security/audit-logs.md b/docs/admin/security/audit-logs.md index c4b9499f8b966..b22055ff18b5a 100644 --- a/docs/admin/security/audit-logs.md +++ b/docs/admin/security/audit-logs.md @@ -25,7 +25,7 @@ We track the following resources: | Organization
|
FieldTracked
created_atfalse
descriptiontrue
display_nametrue
icontrue
idfalse
is_defaulttrue
nametrue
updated_attrue
| | Template
write, delete |
FieldTracked
active_version_idtrue
activity_bumptrue
allow_user_autostarttrue
allow_user_autostoptrue
allow_user_cancel_workspace_jobstrue
autostart_block_days_of_weektrue
autostop_requirement_days_of_weektrue
autostop_requirement_weekstrue
created_atfalse
created_bytrue
created_by_avatar_urlfalse
created_by_usernamefalse
default_ttltrue
deletedfalse
deprecatedtrue
descriptiontrue
display_nametrue
failure_ttltrue
group_acltrue
icontrue
idtrue
max_port_sharing_leveltrue
nametrue
organization_display_namefalse
organization_iconfalse
organization_idfalse
organization_namefalse
provisionertrue
require_active_versiontrue
time_til_dormanttrue
time_til_dormant_autodeletetrue
updated_atfalse
user_acltrue
| | TemplateVersion
create, write |
FieldTracked
archivedtrue
created_atfalse
created_bytrue
created_by_avatar_urlfalse
created_by_usernamefalse
external_auth_providersfalse
idtrue
job_idfalse
messagefalse
nametrue
organization_idfalse
readmetrue
template_idtrue
updated_atfalse
| -| User
create, write, delete |
FieldTracked
avatar_urlfalse
created_atfalse
deletedtrue
emailtrue
github_com_user_idfalse
hashed_one_time_passcodetrue
hashed_passwordtrue
idtrue
last_seen_atfalse
login_typetrue
must_reset_passwordtrue
nametrue
one_time_passcode_expires_attrue
quiet_hours_scheduletrue
rbac_rolestrue
statustrue
theme_preferencefalse
updated_atfalse
usernametrue
| +| User
create, write, delete |
FieldTracked
avatar_urlfalse
created_atfalse
deletedtrue
emailtrue
github_com_user_idfalse
hashed_one_time_passcodefalse
hashed_passwordtrue
idtrue
last_seen_atfalse
login_typetrue
must_reset_passwordtrue
nametrue
one_time_passcode_expires_attrue
quiet_hours_scheduletrue
rbac_rolestrue
statustrue
theme_preferencefalse
updated_atfalse
usernametrue
| | Workspace
create, write, delete |
FieldTracked
automatic_updatestrue
autostart_scheduletrue
created_atfalse
deletedfalse
deleting_attrue
dormant_attrue
favoritetrue
idtrue
last_used_atfalse
nametrue
organization_idfalse
owner_idtrue
template_idtrue
ttltrue
updated_atfalse
| | WorkspaceBuild
start, stop |
FieldTracked
build_numberfalse
created_atfalse
daily_costfalse
deadlinefalse
idfalse
initiator_by_avatar_urlfalse
initiator_by_usernamefalse
initiator_idfalse
job_idfalse
max_deadlinefalse
provisioner_statefalse
reasonfalse
template_version_idtrue
transitionfalse
updated_atfalse
workspace_idfalse
| | WorkspaceProxy
|
FieldTracked
created_attrue
deletedfalse
derp_enabledtrue
derp_onlytrue
display_nametrue
icontrue
idtrue
nametrue
region_idtrue
token_hashed_secrettrue
updated_atfalse
urltrue
versiontrue
wildcard_hostnametrue
| From 6d67f8f0670c5aa59a8168f7612cb15176b6b222 Mon Sep 17 00:00:00 2001 From: Danielle Maywood Date: Tue, 22 Oct 2024 09:46:25 +0000 Subject: [PATCH 3/7] fix: manually run mockgen --- coderd/database/pubsub/psmock/psmock.go | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/coderd/database/pubsub/psmock/psmock.go b/coderd/database/pubsub/psmock/psmock.go index da26c66e45265..6f5841f758ab0 100644 --- a/coderd/database/pubsub/psmock/psmock.go +++ b/coderd/database/pubsub/psmock/psmock.go @@ -12,9 +12,8 @@ package psmock import ( reflect "reflect" - gomock "go.uber.org/mock/gomock" - pubsub "github.com/coder/coder/v2/coderd/database/pubsub" + gomock "go.uber.org/mock/gomock" ) // MockPubsub is a mock of Pubsub interface. From 7b547980ab44099969536f7f3148baaa443eca7c Mon Sep 17 00:00:00 2001 From: Danielle Maywood Date: Tue, 22 Oct 2024 10:12:38 +0000 Subject: [PATCH 4/7] test: add some tests --- .../AuditLogDescription.stories.tsx | 7 +++++ .../AuditLogRow/AuditLogDiff/AuditLogDiff.tsx | 2 ++ .../AuditLogRow/AuditLogRow.stories.tsx | 7 +++++ site/src/testHelpers/entities.ts | 26 +++++++++++++++++++ 4 files changed, 42 insertions(+) diff --git a/site/src/pages/AuditPage/AuditLogRow/AuditLogDescription/AuditLogDescription.stories.tsx b/site/src/pages/AuditPage/AuditLogRow/AuditLogDescription/AuditLogDescription.stories.tsx index a8c1e2435475e..a99b7af75d28f 100644 --- a/site/src/pages/AuditPage/AuditLogRow/AuditLogDescription/AuditLogDescription.stories.tsx +++ b/site/src/pages/AuditPage/AuditLogRow/AuditLogDescription/AuditLogDescription.stories.tsx @@ -1,6 +1,7 @@ import type { Meta, StoryObj } from "@storybook/react"; import { MockAuditLog, + MockAuditLogRequestOneTimePasscode, MockAuditLogSuccessfulLogin, MockAuditLogUnsuccessfulLoginKnownUser, MockAuditLogWithWorkspaceBuild, @@ -57,6 +58,12 @@ export const UnsuccessfulLoginForUnknownUser: Story = { }, }; +export const RequestOneTimePasscode: Story = { + args: { + auditLog: MockAuditLogRequestOneTimePasscode, + }, +}; + export const CreateUser: Story = { args: { auditLog: { diff --git a/site/src/pages/AuditPage/AuditLogRow/AuditLogDiff/AuditLogDiff.tsx b/site/src/pages/AuditPage/AuditLogRow/AuditLogDiff/AuditLogDiff.tsx index 584269c515190..c1f5f642ca039 100644 --- a/site/src/pages/AuditPage/AuditLogRow/AuditLogDiff/AuditLogDiff.tsx +++ b/site/src/pages/AuditPage/AuditLogRow/AuditLogDiff/AuditLogDiff.tsx @@ -32,6 +32,8 @@ const getDiffValue = (value: unknown): string => { const isTimeObject = ( value: unknown, ): value is { Time: string; Valid: boolean } => { + console.log(JSON.stringify(value)); + return ( value !== null && typeof value === "object" && diff --git a/site/src/pages/AuditPage/AuditLogRow/AuditLogRow.stories.tsx b/site/src/pages/AuditPage/AuditLogRow/AuditLogRow.stories.tsx index f6b601486a833..47ae7ec15ac52 100644 --- a/site/src/pages/AuditPage/AuditLogRow/AuditLogRow.stories.tsx +++ b/site/src/pages/AuditPage/AuditLogRow/AuditLogRow.stories.tsx @@ -10,6 +10,7 @@ import { MockAuditLog, MockAuditLog2, MockAuditLogGitSSH, + MockAuditLogRequestOneTimePasscode, MockAuditLogWithDeletedResource, MockAuditLogWithWorkspaceBuild, MockUser, @@ -122,6 +123,12 @@ export const WithOrganization: Story = { }, }; +export const WithDateDiffValue: Story = { + args: { + auditLog: MockAuditLogRequestOneTimePasscode, + }, +}; + export const NoUserAgent: Story = { args: { auditLog: { diff --git a/site/src/testHelpers/entities.ts b/site/src/testHelpers/entities.ts index 7b654e54c48a2..658c272f9e002 100644 --- a/site/src/testHelpers/entities.ts +++ b/site/src/testHelpers/entities.ts @@ -2600,6 +2600,32 @@ export const MockAuditLogUnsuccessfulLoginKnownUser: TypesGen.AuditLog = { status_code: 401, }; +export const MockAuditLogRequestOneTimePasscode: TypesGen.AuditLog = { + ...MockAuditLog, + resource_type: "user", + resource_target: "member", + action: "request_one_time_passcode", + description: "one time passcode requested for {target}", + diff: { + hashed_password: { + old: "", + new: "", + secret: true, + }, + one_time_passcode_expires_at: { + old: { + Time: "0001-01-01T00:00:00Z", + Valid: false, + }, + new: { + Time: "2024-10-22T09:03:23.961702Z", + Valid: true, + }, + secret: false, + }, + } +}; + export const MockWorkspaceQuota: TypesGen.WorkspaceQuota = { credits_consumed: 0, budget: 100, From 383581b422016b37a57ee6ae7056e3d4f0d9fe76 Mon Sep 17 00:00:00 2001 From: Danielle Maywood Date: Tue, 22 Oct 2024 10:18:24 +0000 Subject: [PATCH 5/7] fix: formatting and remove console.log (oops) --- .../pages/AuditPage/AuditLogRow/AuditLogDiff/AuditLogDiff.tsx | 2 -- site/src/testHelpers/entities.ts | 2 +- 2 files changed, 1 insertion(+), 3 deletions(-) diff --git a/site/src/pages/AuditPage/AuditLogRow/AuditLogDiff/AuditLogDiff.tsx b/site/src/pages/AuditPage/AuditLogRow/AuditLogDiff/AuditLogDiff.tsx index c1f5f642ca039..584269c515190 100644 --- a/site/src/pages/AuditPage/AuditLogRow/AuditLogDiff/AuditLogDiff.tsx +++ b/site/src/pages/AuditPage/AuditLogRow/AuditLogDiff/AuditLogDiff.tsx @@ -32,8 +32,6 @@ const getDiffValue = (value: unknown): string => { const isTimeObject = ( value: unknown, ): value is { Time: string; Valid: boolean } => { - console.log(JSON.stringify(value)); - return ( value !== null && typeof value === "object" && diff --git a/site/src/testHelpers/entities.ts b/site/src/testHelpers/entities.ts index 658c272f9e002..f1c5efc43cef4 100644 --- a/site/src/testHelpers/entities.ts +++ b/site/src/testHelpers/entities.ts @@ -2623,7 +2623,7 @@ export const MockAuditLogRequestOneTimePasscode: TypesGen.AuditLog = { }, secret: false, }, - } + }, }; export const MockWorkspaceQuota: TypesGen.WorkspaceQuota = { From a258f68ee63e25d15bf3350df7584d657e89c599 Mon Sep 17 00:00:00 2001 From: Danielle Maywood Date: Tue, 22 Oct 2024 11:38:58 +0000 Subject: [PATCH 6/7] refactor: request one-time passcode -> request password reset --- coderd/apidoc/docs.go | 4 ++-- coderd/apidoc/swagger.json | 4 ++-- coderd/audit.go | 6 ++--- coderd/database/dump.sql | 2 +- ...68_add_audit_action_forgot_password.up.sql | 2 -- ...it_action_request_password_reset.down.sql} | 0 ...audit_action_request_password_reset.up.sql | 2 ++ coderd/database/models.go | 22 +++++++++---------- coderd/userauth.go | 2 +- codersdk/audit.go | 22 +++++++++---------- docs/reference/api/schemas.md | 22 +++++++++---------- site/src/api/typesGenerated.ts | 4 ++-- site/src/testHelpers/entities.ts | 4 ++-- 13 files changed, 48 insertions(+), 48 deletions(-) delete mode 100644 coderd/database/migrations/000268_add_audit_action_forgot_password.up.sql rename coderd/database/migrations/{000268_add_audit_action_forgot_password.down.sql => 000268_add_audit_action_request_password_reset.down.sql} (100%) create mode 100644 coderd/database/migrations/000268_add_audit_action_request_password_reset.up.sql diff --git a/coderd/apidoc/docs.go b/coderd/apidoc/docs.go index ba546014bc3b7..76084b1ff54dd 100644 --- a/coderd/apidoc/docs.go +++ b/coderd/apidoc/docs.go @@ -9117,7 +9117,7 @@ const docTemplate = `{ "login", "logout", "register", - "request_one_time_passcode" + "request_password_reset" ], "x-enum-varnames": [ "AuditActionCreate", @@ -9128,7 +9128,7 @@ const docTemplate = `{ "AuditActionLogin", "AuditActionLogout", "AuditActionRegister", - "AuditActionRequestOneTimePasscode" + "AuditActionRequestPasswordReset" ] }, "codersdk.AuditDiff": { diff --git a/coderd/apidoc/swagger.json b/coderd/apidoc/swagger.json index e8d45351a62c1..beff69ca22373 100644 --- a/coderd/apidoc/swagger.json +++ b/coderd/apidoc/swagger.json @@ -8091,7 +8091,7 @@ "login", "logout", "register", - "request_one_time_passcode" + "request_password_reset" ], "x-enum-varnames": [ "AuditActionCreate", @@ -8102,7 +8102,7 @@ "AuditActionLogin", "AuditActionLogout", "AuditActionRegister", - "AuditActionRequestOneTimePasscode" + "AuditActionRequestPasswordReset" ] }, "codersdk.AuditDiff": { diff --git a/coderd/audit.go b/coderd/audit.go index 73a5fc56fbfb1..f764094782a2f 100644 --- a/coderd/audit.go +++ b/coderd/audit.go @@ -277,9 +277,9 @@ func auditLogDescription(alog database.GetAuditLogsOffsetRow) string { // NOTE: WriteString always returns a nil error, so we never check it - // Requesting a one-time passcode can be performed by anyone that knows the email + // Requesting a password reset can be performed by anyone that knows the email // of a user so saying the user performed this action might be slightly misleading. - if alog.AuditLog.Action != database.AuditActionRequestOneTimePasscode { + if alog.AuditLog.Action != database.AuditActionRequestPasswordReset { _, _ = b.WriteString("{user} ") } @@ -305,7 +305,7 @@ func auditLogDescription(alog database.GetAuditLogsOffsetRow) string { return b.String() } - if alog.AuditLog.Action == database.AuditActionRequestOneTimePasscode { + if alog.AuditLog.Action == database.AuditActionRequestPasswordReset { _, _ = b.WriteString(" for") } else { _, _ = b.WriteString(" ") diff --git a/coderd/database/dump.sql b/coderd/database/dump.sql index 67243cf65417b..382cab743fb39 100644 --- a/coderd/database/dump.sql +++ b/coderd/database/dump.sql @@ -20,7 +20,7 @@ CREATE TYPE audit_action AS ENUM ( 'login', 'logout', 'register', - 'request_one_time_passcode' + 'request_password_reset' ); CREATE TYPE automatic_updates AS ENUM ( diff --git a/coderd/database/migrations/000268_add_audit_action_forgot_password.up.sql b/coderd/database/migrations/000268_add_audit_action_forgot_password.up.sql deleted file mode 100644 index 012a4074c8528..0000000000000 --- a/coderd/database/migrations/000268_add_audit_action_forgot_password.up.sql +++ /dev/null @@ -1,2 +0,0 @@ -ALTER TYPE audit_action - ADD VALUE IF NOT EXISTS 'request_one_time_passcode'; diff --git a/coderd/database/migrations/000268_add_audit_action_forgot_password.down.sql b/coderd/database/migrations/000268_add_audit_action_request_password_reset.down.sql similarity index 100% rename from coderd/database/migrations/000268_add_audit_action_forgot_password.down.sql rename to coderd/database/migrations/000268_add_audit_action_request_password_reset.down.sql diff --git a/coderd/database/migrations/000268_add_audit_action_request_password_reset.up.sql b/coderd/database/migrations/000268_add_audit_action_request_password_reset.up.sql new file mode 100644 index 0000000000000..81371517202fc --- /dev/null +++ b/coderd/database/migrations/000268_add_audit_action_request_password_reset.up.sql @@ -0,0 +1,2 @@ +ALTER TYPE audit_action + ADD VALUE IF NOT EXISTS 'request_password_reset'; diff --git a/coderd/database/models.go b/coderd/database/models.go index 41afaab236e23..c44aa6011bc22 100644 --- a/coderd/database/models.go +++ b/coderd/database/models.go @@ -138,15 +138,15 @@ func AllAppSharingLevelValues() []AppSharingLevel { type AuditAction string const ( - AuditActionCreate AuditAction = "create" - AuditActionWrite AuditAction = "write" - AuditActionDelete AuditAction = "delete" - AuditActionStart AuditAction = "start" - AuditActionStop AuditAction = "stop" - AuditActionLogin AuditAction = "login" - AuditActionLogout AuditAction = "logout" - AuditActionRegister AuditAction = "register" - AuditActionRequestOneTimePasscode AuditAction = "request_one_time_passcode" + AuditActionCreate AuditAction = "create" + AuditActionWrite AuditAction = "write" + AuditActionDelete AuditAction = "delete" + AuditActionStart AuditAction = "start" + AuditActionStop AuditAction = "stop" + AuditActionLogin AuditAction = "login" + AuditActionLogout AuditAction = "logout" + AuditActionRegister AuditAction = "register" + AuditActionRequestPasswordReset AuditAction = "request_password_reset" ) func (e *AuditAction) Scan(src interface{}) error { @@ -194,7 +194,7 @@ func (e AuditAction) Valid() bool { AuditActionLogin, AuditActionLogout, AuditActionRegister, - AuditActionRequestOneTimePasscode: + AuditActionRequestPasswordReset: return true } return false @@ -210,7 +210,7 @@ func AllAuditActionValues() []AuditAction { AuditActionLogin, AuditActionLogout, AuditActionRegister, - AuditActionRequestOneTimePasscode, + AuditActionRequestPasswordReset, } } diff --git a/coderd/userauth.go b/coderd/userauth.go index 8549afccaeec5..85ab0d77e6cc1 100644 --- a/coderd/userauth.go +++ b/coderd/userauth.go @@ -220,7 +220,7 @@ func (api *API) postRequestOneTimePasscode(rw http.ResponseWriter, r *http.Reque Audit: *auditor, Log: api.Logger, Request: r, - Action: database.AuditActionRequestOneTimePasscode, + Action: database.AuditActionRequestPasswordReset, }) ) defer commitAudit() diff --git a/codersdk/audit.go b/codersdk/audit.go index 570f11eab63b9..9fe51e5f24a5f 100644 --- a/codersdk/audit.go +++ b/codersdk/audit.go @@ -86,15 +86,15 @@ func (r ResourceType) FriendlyString() string { type AuditAction string const ( - AuditActionCreate AuditAction = "create" - AuditActionWrite AuditAction = "write" - AuditActionDelete AuditAction = "delete" - AuditActionStart AuditAction = "start" - AuditActionStop AuditAction = "stop" - AuditActionLogin AuditAction = "login" - AuditActionLogout AuditAction = "logout" - AuditActionRegister AuditAction = "register" - AuditActionRequestOneTimePasscode AuditAction = "request_one_time_passcode" + AuditActionCreate AuditAction = "create" + AuditActionWrite AuditAction = "write" + AuditActionDelete AuditAction = "delete" + AuditActionStart AuditAction = "start" + AuditActionStop AuditAction = "stop" + AuditActionLogin AuditAction = "login" + AuditActionLogout AuditAction = "logout" + AuditActionRegister AuditAction = "register" + AuditActionRequestPasswordReset AuditAction = "request_password_reset" ) func (a AuditAction) Friendly() string { @@ -115,8 +115,8 @@ func (a AuditAction) Friendly() string { return "logged out" case AuditActionRegister: return "registered" - case AuditActionRequestOneTimePasscode: - return "one time passcode requested" + case AuditActionRequestPasswordReset: + return "password reset requested" default: return "unknown" } diff --git a/docs/reference/api/schemas.md b/docs/reference/api/schemas.md index 2045b21b33a57..ed3800b3a27cd 100644 --- a/docs/reference/api/schemas.md +++ b/docs/reference/api/schemas.md @@ -513,17 +513,17 @@ #### Enumerated Values -| Value | -| --------------------------- | -| `create` | -| `write` | -| `delete` | -| `start` | -| `stop` | -| `login` | -| `logout` | -| `register` | -| `request_one_time_passcode` | +| Value | +| ------------------------ | +| `create` | +| `write` | +| `delete` | +| `start` | +| `stop` | +| `login` | +| `logout` | +| `register` | +| `request_password_reset` | ## codersdk.AuditDiff diff --git a/site/src/api/typesGenerated.ts b/site/src/api/typesGenerated.ts index 8947518dc6db8..e55167ef03f88 100644 --- a/site/src/api/typesGenerated.ts +++ b/site/src/api/typesGenerated.ts @@ -2098,8 +2098,8 @@ export type AgentSubsystem = "envbox" | "envbuilder" | "exectrace" export const AgentSubsystems: AgentSubsystem[] = ["envbox", "envbuilder", "exectrace"] // From codersdk/audit.go -export type AuditAction = "create" | "delete" | "login" | "logout" | "register" | "request_one_time_passcode" | "start" | "stop" | "write" -export const AuditActions: AuditAction[] = ["create", "delete", "login", "logout", "register", "request_one_time_passcode", "start", "stop", "write"] +export type AuditAction = "create" | "delete" | "login" | "logout" | "register" | "request_password_reset" | "start" | "stop" | "write" +export const AuditActions: AuditAction[] = ["create", "delete", "login", "logout", "register", "request_password_reset", "start", "stop", "write"] // From codersdk/workspaces.go export type AutomaticUpdates = "always" | "never" diff --git a/site/src/testHelpers/entities.ts b/site/src/testHelpers/entities.ts index f1c5efc43cef4..d9575fb44e803 100644 --- a/site/src/testHelpers/entities.ts +++ b/site/src/testHelpers/entities.ts @@ -2604,8 +2604,8 @@ export const MockAuditLogRequestOneTimePasscode: TypesGen.AuditLog = { ...MockAuditLog, resource_type: "user", resource_target: "member", - action: "request_one_time_passcode", - description: "one time passcode requested for {target}", + action: "request_password_reset", + description: "password reset requested for {target}", diff: { hashed_password: { old: "", From f49810ac27020d8047ebfbc2a6eba8069b5809fe Mon Sep 17 00:00:00 2001 From: Danielle Maywood Date: Tue, 22 Oct 2024 11:42:21 +0000 Subject: [PATCH 7/7] refactor: missed a few --- .../AuditLogDescription/AuditLogDescription.stories.tsx | 6 +++--- .../src/pages/AuditPage/AuditLogRow/AuditLogRow.stories.tsx | 4 ++-- site/src/testHelpers/entities.ts | 2 +- 3 files changed, 6 insertions(+), 6 deletions(-) diff --git a/site/src/pages/AuditPage/AuditLogRow/AuditLogDescription/AuditLogDescription.stories.tsx b/site/src/pages/AuditPage/AuditLogRow/AuditLogDescription/AuditLogDescription.stories.tsx index a99b7af75d28f..dd2c88f5be50b 100644 --- a/site/src/pages/AuditPage/AuditLogRow/AuditLogDescription/AuditLogDescription.stories.tsx +++ b/site/src/pages/AuditPage/AuditLogRow/AuditLogDescription/AuditLogDescription.stories.tsx @@ -1,7 +1,7 @@ import type { Meta, StoryObj } from "@storybook/react"; import { MockAuditLog, - MockAuditLogRequestOneTimePasscode, + MockAuditLogRequestPasswordReset, MockAuditLogSuccessfulLogin, MockAuditLogUnsuccessfulLoginKnownUser, MockAuditLogWithWorkspaceBuild, @@ -58,9 +58,9 @@ export const UnsuccessfulLoginForUnknownUser: Story = { }, }; -export const RequestOneTimePasscode: Story = { +export const RequestPasswordReset: Story = { args: { - auditLog: MockAuditLogRequestOneTimePasscode, + auditLog: MockAuditLogRequestPasswordReset, }, }; diff --git a/site/src/pages/AuditPage/AuditLogRow/AuditLogRow.stories.tsx b/site/src/pages/AuditPage/AuditLogRow/AuditLogRow.stories.tsx index 47ae7ec15ac52..12d57b63047e8 100644 --- a/site/src/pages/AuditPage/AuditLogRow/AuditLogRow.stories.tsx +++ b/site/src/pages/AuditPage/AuditLogRow/AuditLogRow.stories.tsx @@ -10,7 +10,7 @@ import { MockAuditLog, MockAuditLog2, MockAuditLogGitSSH, - MockAuditLogRequestOneTimePasscode, + MockAuditLogRequestPasswordReset, MockAuditLogWithDeletedResource, MockAuditLogWithWorkspaceBuild, MockUser, @@ -125,7 +125,7 @@ export const WithOrganization: Story = { export const WithDateDiffValue: Story = { args: { - auditLog: MockAuditLogRequestOneTimePasscode, + auditLog: MockAuditLogRequestPasswordReset, }, }; diff --git a/site/src/testHelpers/entities.ts b/site/src/testHelpers/entities.ts index d9575fb44e803..0db6e80d435d6 100644 --- a/site/src/testHelpers/entities.ts +++ b/site/src/testHelpers/entities.ts @@ -2600,7 +2600,7 @@ export const MockAuditLogUnsuccessfulLoginKnownUser: TypesGen.AuditLog = { status_code: 401, }; -export const MockAuditLogRequestOneTimePasscode: TypesGen.AuditLog = { +export const MockAuditLogRequestPasswordReset: TypesGen.AuditLog = { ...MockAuditLog, resource_type: "user", resource_target: "member",