Add API tokens management, docs & UI

Introduce full API token support: add a Prisma migration to create api_tokens table and indexes; add types, constants and a generateApiToken utility (hashed token + prefix). Update admin and user token routes to use the generator, enforce per-user active token caps, and integrate rate-limit checks. Add an interactive API docs page with TokenInput, EndpointCard and ResponseViewer components, plus a protected page route. Improve confirmation UX with an accessible ConfirmDialog (focus trap, Escape to close, animations) and wire confirm flows into admin/profile token sections; also update ConfirmModal to accept node messages. Add dialog CSS animations and enhance clipboard error handling. Update related middleware, utils and tests to reflect changes.
This commit is contained in:
kikootwo
2026-03-04 14:51:23 -05:00
parent 45e818c181
commit d6eca611fc
19 changed files with 1300 additions and 136 deletions
+30
View File
@@ -0,0 +1,30 @@
/**
* Component: API Token Generation Utility
* Documentation: documentation/backend/services/api-tokens.md
*/
import crypto from 'crypto';
import { API_TOKEN_PREFIX, TOKEN_RANDOM_BYTES, TOKEN_PREFIX_LENGTH } from '../constants/api-tokens';
interface GeneratedToken {
/** The full token string to return to the user (shown only once) */
fullToken: string;
/** SHA-256 hash of the full token (stored in database) */
tokenHash: string;
/** Display prefix for identification (first 12 chars) */
tokenPrefix: string;
}
/**
* Generate a new API token with its hash and display prefix.
* The full token is: API_TOKEN_PREFIX + random hex string.
* Only the hash is stored; the full token is returned once at creation.
*/
export function generateApiToken(): GeneratedToken {
const randomPart = crypto.randomBytes(TOKEN_RANDOM_BYTES).toString('hex');
const fullToken = `${API_TOKEN_PREFIX}${randomPart}`;
const tokenHash = crypto.createHash('sha256').update(fullToken).digest('hex');
const tokenPrefix = fullToken.substring(0, TOKEN_PREFIX_LENGTH);
return { fullToken, tokenHash, tokenPrefix };
}