Commit graph

13 commits

Author SHA1 Message Date
DJP
dd57239408 Add multi-select batch top-up on Low Balance screen
Checkboxes on each row + Select All in the header. When users are
selected, a "Top Up Selected" button appears in the filter bar.
Opens a modal with preset amounts to top up all selected users at
once. Each individual top-up is logged to history.

New endpoint: POST /api/balances/batch/add

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-13 11:03:46 -04:00
DJP
4ebf0ba3ae Update README with email notifications, history, and full setup guide
Documents all new features: email approve/reject flow, credit requests,
history tracking, low balance view. Includes complete env var reference,
email security notes, and troubleshooting section.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-27 10:42:26 -04:00
DJP
5c208d9a0c Add confirmation step to webhook approve/reject to prevent email scanner auto-clicks
Email security scanners (Microsoft Defender Safe Links, etc.) pre-click
all links in emails. Previously the GET request directly approved the
request. Now GET shows a confirmation page and only POST (clicking the
confirm button) actually processes the approval/rejection.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-27 10:24:32 -04:00
DJP
81e18f8a73 Add email notifications with one-click approve/reject from email
When a user submits a credit request, an email is sent to all
configured NOTIFY_TO recipients with approve buttons (5M, 10M, 20M),
a custom amount option, and a reject button. Each button is a
signed HMAC-SHA256 webhook URL that expires after WEBHOOK_TTL_HOURS.

Clicking approve from email processes the top-up identical to the
admin dashboard — balance update, history log, request status change.
Double-approval protection prevents the same link from being used
twice. Portal approval still works alongside email approval.

New dependencies: nodemailer
New files: services/email.js, routes/webhooks.js
Modified: server.js, routes/requests.js, .env.example

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-27 09:50:44 -04:00
DJP
a9c514d5b1 Add history tracking and user history view
- All balance changes (top-ups, sets, bulk ops, request approvals)
  are now logged to data/history.json
- New "History" tab in admin sidebar
- Search by email to see all changes for a user with totals
- Partial name search shows matching users with summary stats
- Each entry shows action type, amount, source, OMG job #,
  resulting balance, and timestamp

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-23 13:33:08 -04:00
DJP
0d552d2ed2 Add custom amount option for approving credit requests
Adds a Custom button alongside the preset 5M/10M/20M approve buttons.
Opens a modal with preset quick-picks and a free-form input for any amount.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-20 14:52:11 -04:00
DJP
a941003057 Fix request page API path when accessed without .html extension
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-20 14:49:01 -04:00
DJP
2cc8178a18 Add credit request system with public form and admin dashboard
- Public page at /request for users to submit top-up requests
  (email + OMG job number, no auth required)
- Admin "Requests" view with pending/processed/all filters
- Approve with preset amounts (5M/10M/20M) or reject
- Pending count badge in sidebar nav
- Request data stored in JSON file (data/requests.json)
- Data volume mounted for persistence across rebuilds

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-20 14:43:42 -04:00
DJP
83eed505e9 Fix special characters breaking action buttons
Apostrophes in names (e.g. O'Hagan) broke inline onclick handlers.
Switched to data attributes with event delegation for safe handling
of all special characters.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-20 13:47:20 -04:00
DJP
ac8bb32d3f Fix bulk routes matched by :userId param
Moved /balances/bulk/* routes before /balances/:userId/* so Express
doesn't treat "bulk" as a userId and try to parse it as an ObjectId.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-17 23:14:24 -04:00
DJP
e94cf8f503 Add low balance users view with threshold filters
Shows users below 1M/2M/3M/4M/5M tokens with filter buttons.
Sorted lowest first so admins can quickly find and top up users
running low.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-17 23:11:02 -04:00
DJP
4c4f7d5408 Fix asset and API paths for reverse proxy support
Paths were absolute (/css/, /js/, /api) which broke when served
behind NGINX at /balance-manager/. Now uses relative paths with
base href.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-17 23:04:14 -04:00
DJP
bbefb03c4b Initial commit - LibreChat Balance Manager
Admin dashboard for managing user token balances. View, search, top up, and bulk-manage credits.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-17 22:51:25 -04:00