Unverified Commit cdbb5abc authored by Minseong Choi's avatar Minseong Choi 💬
Browse files

fix(api): record credential id in passkey-register audit event

handlePasskeyRegisterFinish logged an empty target for account.passkey.registered, while the delete half logs the credential id. An operator auditing the log could see that a passkey was bound but not which one. Pass cred.ID as the audit target so bind and unbind are symmetric, and tighten the enrollment test to assert both halves name the credential id.
parent 6368ab19
Loading
Loading
Loading
Loading
+1 −1
Changes for internal/api/handlers_passkey.go: 1 added line, 1 removed line.
Original line number Diff line number Diff line
@@ -255,7 +255,7 @@ func (a *API) handlePasskeyRegisterFinish(w http.ResponseWriter, r *http.Request
		writeError(w, r, err)
		return
	}
	a.audit(r, auditActor(p), "account.passkey.registered", "")
	a.audit(r, auditActor(p), "account.passkey.registered", cred.ID)
	writeJSON(w, http.StatusCreated, passkeyView(cred))
}

+6 −4
Changes for internal/api/handlers_passkey_test.go: 6 added lines, 4 removed lines.
Original line number Diff line number Diff line
@@ -125,18 +125,20 @@ func TestPasskeyRegisterVertical(t *testing.T) {
		t.Fatalf("delete left %d credentials, want 0", len(repo.passkeyCreds))
	}

	// Both mutating halves audit by the caller's Access email.
	// Both mutating halves audit by the caller's Access email AND name the affected
	// credential id as the target, so an operator reading the log can tell which
	// passkey was bound/unbound (register previously logged an empty target).
	var registered, removed bool
	for _, a := range repo.audits {
		switch a.Action {
		case "account.passkey.registered":
			registered = a.Actor == "[email protected]"
			registered = a.Actor == "[email protected]" && a.ServerName == id
		case "account.passkey.removed":
			removed = a.Actor == "[email protected]"
			removed = a.Actor == "[email protected]" && a.ServerName == id
		}
	}
	if !registered || !removed {
		t.Errorf("want registered+removed audits by [email protected], got %+v", repo.audits)
		t.Errorf("want registered+removed audits by [email protected] targeting %s, got %+v", id, repo.audits)
	}
}