Add API token allowlist, docs, UI and tests

Introduce API token allowlist support and documentation. Adds a new backend docs page for API tokens and updates TABLEOFCONTENTS. Implements API token constants and a compiled matcher (isEndpointAllowed) with support for single-segment :placeholders and an isWrite flag. Split getCurrentUser into a JWT-only helper and added getCurrentUserAsync to recognize rmab_ API tokens; updated the audiobooks search route to use getCurrentUserAsync. Update API docs UI (EndpointCard and api-docs page) to surface Write badges and disable "Try it" for mutating endpoints, and add a profile warning in ApiTokensSection. Add tests for the allowlist matcher and middleware, and adjust existing route tests/mocks accordingly.
This commit is contained in:
kikootwo
2026-05-16 14:17:49 -04:00
parent e39e44ee44
commit 6ec53ff7e3
11 changed files with 417 additions and 39 deletions
+3 -3
View File
@@ -8,7 +8,7 @@ import { getAudibleService } from '@/lib/integrations/audible.service';
import { enrichAudiobooksWithMatches } from '@/lib/utils/audiobook-matcher';
import { deduplicateAndCollectGroups } from '@/lib/utils/deduplicate-audiobooks';
import { persistDedupGroups, collapseByExistingWorks } from '@/lib/services/works.service';
import { getCurrentUser } from '@/lib/middleware/auth';
import { getCurrentUserAsync } from '@/lib/middleware/auth';
import { RMABLogger } from '@/lib/utils/logger';
import { annotateWithIgnoreStatus } from '@/lib/utils/ignored-audiobooks';
@@ -37,8 +37,8 @@ export async function GET(request: NextRequest) {
const audibleService = getAudibleService();
const results = await audibleService.search(query, page);
// Get current user (optional - for request status enrichment)
const currentUser = getCurrentUser(request);
// Get current user (optional — JWT or API token — for request-status enrichment)
const currentUser = await getCurrentUserAsync(request);
const userId = currentUser?.sub || undefined;
// Two-pass dedup: local title/narrator/duration matching first, then collapse