openreader/src/lib/server/test-namespace.ts
Richard R 2c23dc9043 refactor(db): remove conditional database usage from API layer
Ensure all metadata operations consistently use the database layer,
removing filesystem-only fallback paths and conditional DB checks.

- Simplified migration scripts to always run on startup
- Updated document/audiobook APIs to always query DB
- Added ensureDbIndexed() calls across all routes
- Extracted test namespace utilities to dedicated module
- Removed migration-manager.ts (functionality consolidated)
- Updated rate limiter to assume DB is always available

BREAKING CHANGE: Database is now required in all configurations.
When auth is disabled, SQLite is used by default at /app/docstore/sqlite3.db.
2026-02-03 12:17:30 -07:00

30 lines
1 KiB
TypeScript

import path from 'path';
import { UNCLAIMED_USER_ID } from '@/lib/server/docstore';
const TEST_NAMESPACE_HEADER = 'x-openreader-test-namespace';
const SAFE_NAMESPACE_REGEX = /^[a-zA-Z0-9._-]{1,128}$/;
export function getOpenReaderTestNamespace(headers: Headers): string | null {
const raw = headers.get(TEST_NAMESPACE_HEADER)?.trim();
if (!raw) return null;
const safe = raw.replace(/[^a-zA-Z0-9._-]/g, '');
if (!safe || safe === '.' || safe === '..' || safe.includes('..')) return null;
if (!SAFE_NAMESPACE_REGEX.test(safe)) return null;
return safe;
}
export function applyOpenReaderTestNamespacePath(baseDir: string, namespace: string | null): string {
if (!namespace) return baseDir;
const resolved = path.resolve(baseDir, namespace);
if (!resolved.startsWith(path.resolve(baseDir) + path.sep)) return baseDir;
return resolved;
}
export function getUnclaimedUserIdForNamespace(namespace: string | null): string {
if (!namespace) return UNCLAIMED_USER_ID;
return `${UNCLAIMED_USER_ID}::${namespace}`;
}