docs(users): live-smoke correction — GET /api/auth/users emits sqlc ListUsersRow, no password_hash
Curated smoke run of the generated collection against the live dev server (37/37 after fixes): registration matrix (409 duplicate email, 403 admin-creation-with-admins-present, 400 weak password), non-admin 403s, device-token/opds 401s, collection CRUD incl. the documented 201 update quirk and 204 delete, stats routes, scanner, jobs, malformed-uuid 400s. Testuser untouched (password test uses a guaranteed-wrong current password -> 401); the smoke user was admin-deleted in cleanup and its token verified dead. Correction the smoke run forced: the batch-8 'password_hash leak' was a false alarm — my registry pin ([]database.Users) never matched the handler, which returns []database.ListUsersRow (sqlc join with device_count). Live response confirmed: id/email/username/theme/names/ role/max_devices/created_at/updated_at/device_count — NO hash. Doc example, field table, and registry pin all corrected; leak note replaced with the live-verified statement. Also verified via the real Bruno CLI: 9 safe generated requests (4 shown passing incl. stats/collections/devices; password-rules public) execute against the server with collection-level auth. Full-collection bru run deliberately not attempted (mutations in static bodies would touch live data).
This commit is contained in:
1 parent
cfcd95b25e
commit
0c45137f5b
2 files changed
+9
-15
No files matched your search
@@ -42,27 +42,22 @@ Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...
|
||||
"id": "550e8400-e29b-41d4-a716-446655440000",
|
||||
"email": "user@example.com",
|
||||
"username": "johndoe",
|
||||
"password_hash": "$2a$04$REDACTED",
|
||||
"theme": "tokyo-night",
|
||||
"first_name": "John",
|
||||
"last_name": "Doe",
|
||||
"role": "user",
|
||||
"theme": "tokyo-night",
|
||||
"max_devices": 10,
|
||||
"created_at": "2026-02-08T10:00:00Z",
|
||||
"timezone": "America/New_York",
|
||||
"updated_at": "2026-02-08T10:00:00Z",
|
||||
"default_audio_speed": 1
|
||||
"device_count": 3
|
||||
}
|
||||
]
|
||||
```
|
||||
|
||||
Response is a bare JSON array of full user rows — no pagination wrapper
|
||||
and no `device_count` (those were invented in an earlier draft).
|
||||
|
||||
**Leak note:** the user model json-marshals `password_hash` verbatim —
|
||||
the list-users response exposes password hashes to any admin caller.
|
||||
Known defect, tracked separately (doc mirrors the real field set; do not
|
||||
implement against a redacted shape).
|
||||
Response is a bare JSON array of sqlc `ListUsersRow`s (user fields plus a
|
||||
`device_count` join) — no pagination wrapper. Live-smoke-verified
|
||||
2026-10-24: **`password_hash` is NOT in the response** (an earlier draft
|
||||
of this doc wrongly claimed a hash leak).
|
||||
|
||||
### Response Fields
|
||||
|
||||
@@ -79,9 +74,6 @@ implement against a redacted shape).
|
||||
| `device_count` | integer | Current number of registered devices |
|
||||
| `created_at` | string | Account creation timestamp (ISO 8601) |
|
||||
| `updated_at` | string | Last update timestamp (ISO 8601) |
|
||||
| `total` | integer | Total number of users matching query |
|
||||
| `limit` | integer | Limit applied to this request |
|
||||
| `offset` | integer | Offset applied to this request |
|
||||
|
||||
## Error Responses
|
||||
|
||||
|
||||
@@ -687,7 +687,9 @@ var Schemas = map[string]Schema{
|
||||
}`),
|
||||
},
|
||||
"GET /api/auth/users": {
|
||||
Response: []database.Users{},
|
||||
// sqlc join row (device_count), NOT database.Users — no password_hash
|
||||
// on the wire (live-smoke-verified 2026-10-24).
|
||||
Response: []database.ListUsersRow{},
|
||||
},
|
||||
"PUT /api/auth/users/:id/max-devices": {
|
||||
Request: handlers.UpdateUserMaxDevicesRequest{},
|
||||
|
||||
Reference in new issue
Block a user