Jason Woltje
46d0a06ef5
feat(#356): Build credential CRUD API endpoints
Implement comprehensive CRUD API for managing user credentials with encryption,
RLS, and audit logging following TDD methodology.
Features:
- POST /api/credentials - Create encrypted credential
- GET /api/credentials - List credentials (masked values only)
- GET /api/credentials/:id - Get single credential (masked)
- GET /api/credentials/:id/value - Decrypt plaintext (rate limited 10/min)
- PATCH /api/credentials/:id - Update metadata
- POST /api/credentials/:id/rotate - Rotate credential value
- DELETE /api/credentials/:id - Soft delete
Security:
- All values encrypted via VaultService (TransitKey.CREDENTIALS)
- List/Get endpoints NEVER return plaintext (only maskedValue)
- getValue endpoint rate limited to 10 requests/minute per user
- All operations audit-logged with CREDENTIAL_* ActivityAction
- RLS enforces per-user isolation via getRlsClient() pattern
- Input validation via class-validator DTOs
Testing:
- 26/26 unit tests passing
- 95.71% code coverage (exceeds 85% requirement)
- Service: 95.16%
- Controller: 100%
- TypeScript checks pass
Files created:
- apps/api/src/credentials/credentials.service.ts
- apps/api/src/credentials/credentials.service.spec.ts
- apps/api/src/credentials/credentials.controller.ts
- apps/api/src/credentials/credentials.controller.spec.ts
- apps/api/src/credentials/credentials.module.ts
- apps/api/src/credentials/dto/*.dto.ts (5 DTOs)
Files modified:
- apps/api/src/app.module.ts - imported CredentialsModule
Note: Admin credentials endpoints deferred to future issue. Current
implementation covers all user credential endpoints.
Refs #346
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-07 16:50:02 -06:00
..
2026-02-03 14:37:06 -06:00
2026-02-03 14:37:06 -06:00
2026-02-03 14:37:06 -06:00
2026-02-03 14:37:06 -06:00
2026-02-03 14:37:06 -06:00
2026-02-03 14:37:06 -06:00
2026-02-03 14:37:06 -06:00
2026-02-03 14:37:06 -06:00
2026-02-03 14:37:06 -06:00
2026-02-03 14:37:06 -06:00
2026-02-03 14:37:06 -06:00
2026-02-03 20:24:41 -06:00
2026-02-03 19:17:13 -06:00
2026-02-02 14:33:31 -06:00
2026-02-03 14:37:06 -06:00
2026-02-03 14:37:06 -06:00
2026-02-02 15:27:00 -06:00
2026-02-02 15:27:00 -06:00
2026-02-03 14:37:06 -06:00
2026-02-03 14:37:06 -06:00
2026-02-03 14:37:06 -06:00
2026-02-03 14:37:06 -06:00
2026-02-03 14:37:06 -06:00
2026-02-03 12:34:24 -06:00
2026-02-03 12:55:37 -06:00
2026-02-03 14:37:06 -06:00
2026-02-03 13:30:16 -06:00
2026-02-03 13:30:16 -06:00
2026-02-03 13:30:16 -06:00
2026-02-03 14:37:06 -06:00
2026-02-03 13:45:00 -06:00
2026-02-03 14:03:44 -06:00
2026-02-03 14:18:18 -06:00
2026-02-03 14:51:59 -06:00
2026-02-03 14:51:59 -06:00
2026-01-31 11:38:38 -06:00
2026-01-31 12:10:43 -06:00
2026-01-31 12:22:14 -06:00
2026-01-31 11:57:40 -06:00
2026-02-01 17:56:04 -06:00
2026-02-01 20:52:43 -06:00
2026-02-01 20:22:07 -06:00
2026-02-01 20:52:43 -06:00
2026-02-01 20:52:43 -06:00
2026-02-01 20:52:43 -06:00
2026-02-01 20:56:45 -06:00
2026-02-01 21:09:03 -06:00
2026-02-01 21:01:25 -06:00
2026-02-01 21:09:03 -06:00
2026-02-01 21:16:23 -06:00
2026-02-01 21:16:23 -06:00
2026-02-01 21:16:23 -06:00
2026-02-01 21:26:40 -06:00
2026-02-01 21:32:53 -06:00
2026-02-01 21:42:44 -06:00
2026-02-03 14:37:06 -06:00
2026-02-02 08:18:55 -06:00
2026-02-01 21:44:04 -06:00
2026-02-01 21:54:34 -06:00
2026-02-01 20:54:25 -06:00
2026-02-01 21:09:03 -06:00
2026-02-01 20:54:57 -06:00
2026-02-02 11:41:11 -06:00
2026-02-03 14:37:06 -06:00
2026-02-03 14:37:06 -06:00
2026-02-03 14:37:06 -06:00
2026-02-02 12:51:17 -06:00
2026-02-02 12:41:12 -06:00
2026-02-03 14:37:06 -06:00
2026-02-02 12:30:19 -06:00
2026-02-02 12:03:36 -06:00
2026-02-03 14:37:06 -06:00
2026-02-03 22:29:42 -06:00
2026-02-03 22:38:13 -06:00
2026-02-03 22:44:54 -06:00
2026-02-02 12:51:17 -06:00
2026-02-02 12:55:17 -06:00
2026-02-03 14:37:06 -06:00
2026-02-03 14:37:06 -06:00
2026-02-03 22:55:57 -06:00
2026-02-03 22:59:41 -06:00
2026-02-03 16:50:06 -06:00
2026-02-03 18:58:00 -06:00
2026-02-03 19:53:09 -06:00
2026-02-03 20:17:47 -06:00
2026-02-03 20:21:06 -06:00
2026-02-03 20:24:46 -06:00
2026-02-03 20:27:45 -06:00
2026-02-03 20:35:00 -06:00
2026-02-03 20:47:41 -06:00
2026-02-04 03:08:09 +00:00
2026-02-04 03:08:09 +00:00
2026-02-04 03:08:09 +00:00
2026-02-03 22:48:59 -06:00
2026-02-03 22:51:25 -06:00
2026-02-07 16:39:15 -06:00
2026-02-07 16:50:02 -06:00
2026-02-07 16:49:37 -06:00
2026-02-02 14:33:31 -06:00
2026-02-02 14:33:31 -06:00
2026-02-02 14:33:31 -06:00
2026-02-02 14:33:31 -06:00
2026-02-02 14:33:31 -06:00
2026-02-02 14:33:31 -06:00
2026-02-03 14:37:06 -06:00
2026-02-03 14:37:06 -06:00
2026-02-03 14:37:06 -06:00
2026-02-03 14:37:06 -06:00
2026-02-03 14:37:06 -06:00
2026-02-03 14:37:06 -06:00
2026-02-03 14:37:06 -06:00
2026-02-03 14:37:06 -06:00
2026-02-03 14:37:06 -06:00
2026-02-03 14:37:06 -06:00
2026-02-03 14:37:06 -06:00
2026-02-03 14:37:06 -06:00
2026-02-03 14:37:06 -06:00
2026-02-03 14:37:06 -06:00
2026-02-03 14:37:06 -06:00
2026-02-03 14:37:06 -06:00
2026-02-03 14:37:06 -06:00
2026-02-03 14:37:06 -06:00
2026-02-03 14:37:06 -06:00
2026-02-03 14:37:06 -06:00
2026-02-02 14:33:31 -06:00
2026-02-03 21:43:01 -06:00
2026-02-03 14:37:06 -06:00
2026-02-03 14:37:06 -06:00