Remaining docs updated to match code (the docs that the first pass had not covered):
- Flows: Chat, Referral, Rating, Registration, Google OAuth, Negotiation, Payout,
Trezor Safekeeping — corrected endpoints, socket events, status enums, auth gaps
- API Reference: User API, Trezor API — admin route prefix/verb/status corrections,
added undocumented endpoints (ton-proof challenge, profile email verify,
GET /trezor/account, POST /trezor/verify-operation)
- Data Models: Chat, Notification, Payment, PointTransaction, User — corrected
enums (PaymentProvider, escrowState, PointTransaction.type, User.status),
90-day notification TTL, soft-delete semantics, wallet fields
Trezor "zero frontend" finding (audit C31/C32) corrected as STALE:
- Verified current code HAS a full frontend Trezor implementation (admin/trezor
page, TrezorSettingsView, trezorConnector via @trezor/connect-web,
TrezorSignDialog, actions/trezor.ts building the {message,signature} object)
- Fixed Trezor Safekeeping Flow doc (removed false "no frontend" warnings)
- Reclassified ISSUE-012 as invalid/superseded with explanation
Issue set reconciled to a single canonical numbering (ISSUE-001..054):
- Adopted the comprehensive 51-issue set (long-slug, fully indexed)
- Removed 35 superseded short-slug duplicates from the first pass
- Removed a duplicate ISSUE-046 file
- Added 3 issues the 51-set lacked: ISSUE-052 (completed-not-counted-in-stats),
ISSUE-053 (axios 401-only interceptor), ISSUE-054 (rate limiter counts all attempts)
- Regenerated Issues Index: 53 open (14 critical, 39 major) + 1 invalid
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
232 lines
11 KiB
Markdown
232 lines
11 KiB
Markdown
---
|
|
title: Admin API
|
|
tags: [api, admin, reference]
|
|
---
|
|
|
|
# Admin API
|
|
|
|
> **Last updated:** 2026-05-29 — aligned with code (see Doc vs Code Audit Report)
|
|
|
|
There is no single `/api/admin` namespace — admin-only endpoints are scattered across the service routers. This page catalogs them in one place. All require `Bearer JWT` with `req.user.role === 'admin'` unless explicitly noted otherwise. The two enforcement patterns are:
|
|
|
|
- Middleware: `authorizeRoles('admin')` after `authenticateToken` (used by the dispute, data-cleanup, blog routers).
|
|
- Inline check inside the handler: `if (req.user.role !== 'admin') return 403` (used by user, points, payment routes).
|
|
|
|
## User management
|
|
|
|
See full descriptions in [[User API]].
|
|
|
|
> **Path note:** The frontend and backend both use `/api/users/admin/*` (plural). The singular `/api/user/admin/*` paths for create/delete/status/role/list are **unreachable** — they are not mounted in the backend. Use `/api/users/admin/*` for all user-management calls.
|
|
|
|
| Endpoint | Action |
|
|
| --- | --- |
|
|
| `POST /api/users/admin/create` | Create user with role/status |
|
|
| `DELETE /api/users/admin/:userId` | Soft delete user — sets `status='deleted'` (admins cannot delete each other) |
|
|
| `PATCH /api/users/admin/:userId/status` | Activate / suspend |
|
|
| `PATCH /api/users/admin/:userId/toggle-status` | Flip active flag |
|
|
| `PATCH /api/users/admin/:userId/role` | Change role |
|
|
| `GET /api/users/admin/list` | Paginated directory + stats |
|
|
| `GET /api/users/admin/:userId/dependencies` | Pre-delete dependency check |
|
|
| `GET /api/users/admin/stats` | Aggregate user analytics |
|
|
| `GET /api/users/admin/:userId` | Full user detail (admin view) |
|
|
| `PUT /api/users/admin/:userId` | Mass update user |
|
|
| `PUT /api/users/admin/update/:email` | Mass update by email |
|
|
| `PATCH /api/users/admin/:userId/password` | Force password reset (wipes refresh tokens) |
|
|
| `POST /api/users/admin/:userId/resend-verification` | Resend verification email (legacy route — uses 8-digit codes) |
|
|
|
|
> **Verification code length:** The endpoint `POST /api/users/admin/:userId/resend-verification` is served by the legacy userRoutes and generates **8-digit** codes. The new userController generates 6-digit codes and is reached via a different path. Both coexist; the legacy route takes precedence for this path.
|
|
|
|
**⚠️ KNOWN BUG — HTTP verb mismatch (status/role updates):** The frontend Redux actions for `updateUserStatus` and `updateUserRole` send `PUT` requests, but the backend registers these handlers under `PATCH`. These calls will receive `404 Method Not Found` responses until the frontend is corrected to use `PATCH`.
|
|
|
|
**⚠️ KNOWN BUG — Status value mismatch:** The frontend sends `'inactive'` and `'pending'` as status values when updating user status. The backend only accepts `'active'`, `'suspended'`, or `'deleted'`. Sending `'inactive'` or `'pending'` will be rejected or silently ignored.
|
|
|
|
**Hard vs. soft delete note:** The legacy route `DELETE /users/admin/:id` performs a **hard delete** (`findByIdAndDelete`). The current route `DELETE /api/users/admin/:userId` performs a **soft delete** (sets `status='deleted'`). Always use the current `/api/users/admin/:userId` route to preserve data integrity.
|
|
|
|
## Listing / marketplace moderation
|
|
|
|
See [[Marketplace API]]. Admins can use most marketplace endpoints with elevated privileges (e.g. delete any purchase request, override offer status). Specific admin-only actions:
|
|
|
|
| Endpoint | Action |
|
|
| --- | --- |
|
|
| `PUT /api/marketplace/offers/:id/status` | Direct status mutation including admin overrides |
|
|
| `POST /api/marketplace/purchase-requests/:id/release-payment` | Force escrow release |
|
|
| `PATCH /api/marketplace/purchase-requests/:id/status` (any → any) | Override request state machine |
|
|
|
|
Template approval is implicit: admins use the same template CRUD endpoints with override privileges.
|
|
|
|
## Dispute mediation
|
|
|
|
See [[Dispute API]].
|
|
|
|
| Endpoint | Action |
|
|
| --- | --- |
|
|
| `POST /api/disputes/:id/assign` | Assign moderator |
|
|
| `PATCH /api/disputes/:id/status` | Update status |
|
|
| `POST /api/disputes/:id/resolve` | Final decision (buyer / seller / split) |
|
|
| `GET /api/disputes/statistics` | Admin dashboard data |
|
|
|
|
## Manual payment operations
|
|
|
|
See [[Payment API]].
|
|
|
|
| Endpoint | Action |
|
|
| --- | --- |
|
|
| `POST /api/payment/payments/cleanup-pending` | Delete stale pending payments |
|
|
| `POST /api/payment/payments/:id/fetch-tx` | Re-query chain for missing tx hash |
|
|
| `POST /api/payment/payments/auto-fetch-missing` | Batch tx-hash backfill |
|
|
| `POST /api/payment/:id/release` | Build escrow-release tx |
|
|
| `POST /api/payment/:id/release/confirm` | Confirm release tx hash |
|
|
| `POST /api/payment/:id/refund` | Build refund tx |
|
|
| `POST /api/payment/:id/refund/confirm` | Confirm refund tx hash |
|
|
| `POST /api/payment/shkeeper/payout` | Create payout task |
|
|
| `GET /api/payment/shkeeper/webhook-stats` | Webhook telemetry |
|
|
| `POST /api/payment/decentralized/admin-payout` | Direct admin-wallet payout |
|
|
|
|
**⚠️ Path correction:** Release/refund routes do **not** include a `/shkeeper/` segment. The correct paths are `/api/payment/:id/release`, `/api/payment/:id/release/confirm`, etc. (Previously documented incorrectly as `/api/payment/shkeeper/:id/…`.)
|
|
|
|
## Derived destinations & sweep
|
|
|
|
Frontend page: `/dashboard/admin/derived-destinations`. Backend registers 7 endpoints under `/api/payment/derived-destinations/*` with admin auth.
|
|
|
|
| Endpoint | Action |
|
|
| --- | --- |
|
|
| `GET /api/payment/derived-destinations` | List all derived destination addresses |
|
|
| `POST /api/payment/derived-destinations/sweep/trigger` | Trigger a sweep across all destinations |
|
|
| `POST /api/payment/derived-destinations/sweep/trigger/:id` | Trigger sweep for a single destination |
|
|
| `GET /api/payment/derived-destinations/sweep/cron/status` | Get sweep cron job status |
|
|
| `POST /api/payment/derived-destinations/sweep/cron/start` | Start the sweep cron job |
|
|
| `POST /api/payment/derived-destinations/sweep/cron/stop` | Stop the sweep cron job |
|
|
| `GET /api/payment/derived-destinations/sweep/history` | Sweep history log |
|
|
|
|
> Frontend action functions: `getDerivedDestinations`, `triggerSweep`, `triggerSingleSweep`, `getSweepCronStatus`, `startSweepCron`, `stopSweepCron`.
|
|
|
|
## Points (admin)
|
|
|
|
See [[Points API]].
|
|
|
|
| Endpoint | Action |
|
|
| --- | --- |
|
|
| `POST /api/points/admin/add` | Manually grant / deduct points for a user |
|
|
|
|
## Data cleanup
|
|
|
|
Router: [`backend/src/services/admin/dataCleanupRoutes.ts`](../../backend/src/services/admin/dataCleanupRoutes.ts). Mounted under `/api/admin/cleanup/*`. The router applies `authenticateToken` + `authorizeRoles('admin')` to every endpoint.
|
|
|
|
### GET /api/admin/cleanup/stats
|
|
|
|
**Description:** Per-collection document counts and sizes.
|
|
**Response 200:** `{ success, data: { collections: [{ name, count, sizeBytes }] } }`
|
|
|
|
### GET /api/admin/cleanup/collections
|
|
|
|
**Description:** List collections that can be cleaned and the supported flags.
|
|
**Response 200:** `{ success, data: { collections, options } }`
|
|
|
|
### POST /api/admin/cleanup/clean
|
|
|
|
**Description:** Bulk delete records. Defaults to `dryRun: true` and `keepAdmins: true`.
|
|
**Request body:**
|
|
```ts
|
|
{
|
|
collections?: string[]; // default ["all"]
|
|
dryRun?: boolean; // default true
|
|
keepAdmins?: boolean; // default true
|
|
olderThanDays?: number; // optional age filter
|
|
confirm?: "DELETE_ALL_DATA"; // required for actual deletion
|
|
}
|
|
```
|
|
**Response 200:** `{ success, data: { deletedCounts, dryRun } }`
|
|
|
|
### DELETE /api/admin/cleanup/user/:userId
|
|
|
|
**Description:** Cascade-delete all data for a specific user (GDPR). Requires `?confirm=DELETE_USER_DATA` for real execution.
|
|
**Query params:** `dryRun=true|false`, `confirm=DELETE_USER_DATA`
|
|
|
|
### POST /api/admin/cleanup/temp
|
|
|
|
**Description:** Purge temporary data older than N hours (verification codes, file temp uploads).
|
|
**Request body:** `{ olderThanHours?: number }` (default 24)
|
|
|
|
### POST /api/admin/cleanup/seed-templates
|
|
|
|
**Description:** Re-runs the request templates seeder (production safe; idempotent).
|
|
|
|
### POST /api/admin/cleanup/seed-all
|
|
|
|
**Description:** Seeds users, addresses, and templates in dependency order. Used to bootstrap a fresh staging environment.
|
|
|
|
## Scanner / monitoring
|
|
|
|
### GET /api/admin/scanner/status
|
|
|
|
**Description:** Returns the current state of the blockchain scanner / wallet monitor.
|
|
|
|
> **⚠️ SECURITY BUG — NO AUTHENTICATION:** Despite being mounted under `/api/admin/`, this endpoint has **no** `authenticateToken` or `authorizeRoles` guard. Any unauthenticated request can read scanner state.
|
|
|
|
## Settings
|
|
|
|
### AML settings
|
|
|
|
> **⚠️ RUNTIME-ONLY PERSISTENCE:** `PATCH /api/admin/settings/aml` updates `process.env` at runtime only. Changes are **lost on server restart**. There is no frontend page for these endpoints.
|
|
|
|
| Endpoint | Auth | Action |
|
|
| --- | --- | --- |
|
|
| `GET /api/admin/settings/aml` | admin | Read current AML settings |
|
|
| `PATCH /api/admin/settings/aml` | admin | Update AML settings (runtime only — not persisted to disk or DB) |
|
|
|
|
### Confirmation thresholds
|
|
|
|
Frontend page exists. Endpoints require admin auth.
|
|
|
|
| Endpoint | Action |
|
|
| --- | --- |
|
|
| `GET /api/admin/settings/confirmation-thresholds` | Get current confirmation thresholds for all chains |
|
|
| `PATCH /api/admin/settings/confirmation-thresholds/:chainId` | Update threshold for a specific chain |
|
|
|
|
> **Not implemented:** `GET /api/admin/settings/confirmation-thresholds/history` — history endpoint does not exist. `POST /api/admin/rn/networks/reload` and `POST /api/admin/rn/networks/probe/:chainId` do not exist.
|
|
|
|
## Payments awaiting confirmation
|
|
|
|
Frontend page exists.
|
|
|
|
| Endpoint | Auth | Action |
|
|
| --- | --- | --- |
|
|
| `GET /api/admin/payments/awaiting-confirmation` | admin | List payments pending blockchain confirmation |
|
|
|
|
## RN network registry
|
|
|
|
Frontend page exists.
|
|
|
|
| Endpoint | Auth | Action |
|
|
| --- | --- | --- |
|
|
| `GET /api/admin/rn/networks` | admin | List all registered RN networks |
|
|
|
|
## Blog admin
|
|
|
|
Backend registers 5 blog admin endpoints, all guarded by `authorizeRoles('admin')`. Frontend has action functions calling each.
|
|
|
|
| Endpoint | Action |
|
|
| --- | --- |
|
|
| `GET /api/blog/admin/posts` | List all blog posts (admin view, includes drafts) |
|
|
| `POST /api/blog/posts` | Create a new blog post |
|
|
| `GET /api/blog/admin/posts/:id` | Get a single blog post (admin view) |
|
|
| `PUT /api/blog/posts/:id` | Update a blog post |
|
|
| `DELETE /api/blog/posts/:id` | Delete a blog post |
|
|
|
|
## Analytics
|
|
|
|
There is no dedicated analytics router. Admin dashboards stitch together:
|
|
|
|
- `GET /api/users/admin/stats` (user metrics)
|
|
- `GET /api/payment/stats` (payment aggregates — note: `'completed'` status is excluded from `successfulPayments` count)
|
|
- `GET /api/disputes/statistics` (dispute KPIs)
|
|
- `GET /api/admin/cleanup/stats` (collection sizes)
|
|
- `GET /api/payment/shkeeper/webhook-stats` (provider health)
|
|
- `GET /api/payment/shkeeper/wallet-monitor/status` (chain monitor)
|
|
|
|
## Related
|
|
|
|
- [[Admin Console Architecture]]
|
|
- [[Authorization Model]]
|
|
- [[Error Codes]]
|