mirror of
https://github.com/kikootwo/ReadMeABook.git
synced 2026-06-03 04:40:09 +00:00
Add requireSetupIncompleteOrAdmin and adjust routes
Introduce a new middleware requireSetupIncompleteOrAdmin that allows unauthenticated access while the setup wizard is in progress but enforces admin authentication once setup is complete. Replace requireSetupIncomplete with the new guard in test-paths, test-abs and test-oidc API routes. Update the front-end hook to use fetchWithAuth for authenticated requests. Revise setup-guard tests to cover the new semantics: shared endpoints now return 401 when setup is complete and no auth is provided, return 403 for authenticated non-admin users, and allow admin access or unauthenticated access during setup/DB-unready conditions; also add jwt verification and user lookup mocks to the tests.
This commit is contained in:
@@ -6,6 +6,7 @@
|
||||
'use client';
|
||||
|
||||
import { useState } from 'react';
|
||||
import { fetchWithAuth } from '@/lib/utils/api';
|
||||
import type { PathsSettings, TestResult } from '../../lib/types';
|
||||
|
||||
interface UsePathsSettingsProps {
|
||||
@@ -34,7 +35,7 @@ export function usePathsSettings({ paths, onChange, onValidationChange }: UsePat
|
||||
setTestResult(null);
|
||||
|
||||
try {
|
||||
const response = await fetch('/api/setup/test-paths', {
|
||||
const response = await fetchWithAuth('/api/setup/test-paths', {
|
||||
method: 'POST',
|
||||
headers: { 'Content-Type': 'application/json' },
|
||||
body: JSON.stringify({
|
||||
|
||||
@@ -4,10 +4,10 @@
|
||||
*/
|
||||
|
||||
import { NextRequest, NextResponse } from 'next/server';
|
||||
import { requireSetupIncomplete } from '@/lib/middleware/auth';
|
||||
import { requireSetupIncompleteOrAdmin } from '@/lib/middleware/auth';
|
||||
|
||||
export async function POST(request: NextRequest) {
|
||||
return requireSetupIncomplete(request, async (req) => {
|
||||
return requireSetupIncompleteOrAdmin(request, async (req) => {
|
||||
try {
|
||||
const { serverUrl, apiToken } = await req.json();
|
||||
|
||||
|
||||
@@ -5,13 +5,13 @@
|
||||
|
||||
import { NextRequest, NextResponse } from 'next/server';
|
||||
import { Issuer } from 'openid-client';
|
||||
import { requireSetupIncomplete } from '@/lib/middleware/auth';
|
||||
import { requireSetupIncompleteOrAdmin } from '@/lib/middleware/auth';
|
||||
import { RMABLogger } from '@/lib/utils/logger';
|
||||
|
||||
const logger = RMABLogger.create('API.Setup.TestOIDC');
|
||||
|
||||
export async function POST(request: NextRequest) {
|
||||
return requireSetupIncomplete(request, async (req) => {
|
||||
return requireSetupIncompleteOrAdmin(request, async (req) => {
|
||||
try {
|
||||
const body = await req.json();
|
||||
const { issuerUrl, clientId, clientSecret } = body;
|
||||
|
||||
@@ -6,7 +6,7 @@
|
||||
import { NextRequest, NextResponse } from 'next/server';
|
||||
import fs from 'fs/promises';
|
||||
import path from 'path';
|
||||
import { requireSetupIncomplete } from '@/lib/middleware/auth';
|
||||
import { requireSetupIncompleteOrAdmin } from '@/lib/middleware/auth';
|
||||
import { RMABLogger } from '@/lib/utils/logger';
|
||||
import { validateTemplate, generateMockPreviews } from '@/lib/utils/path-template.util';
|
||||
|
||||
@@ -46,7 +46,7 @@ async function testPath(dirPath: string): Promise<boolean> {
|
||||
}
|
||||
|
||||
export async function POST(request: NextRequest) {
|
||||
return requireSetupIncomplete(request, async (req) => {
|
||||
return requireSetupIncompleteOrAdmin(request, async (req) => {
|
||||
try {
|
||||
const { downloadDir, mediaDir, audiobookPathTemplate } = await req.json();
|
||||
|
||||
|
||||
@@ -253,3 +253,35 @@ export async function requireSetupIncomplete(
|
||||
|
||||
return handler(request);
|
||||
}
|
||||
|
||||
/**
|
||||
* Middleware: Require setup incomplete OR authenticated admin
|
||||
* For endpoints shared between the setup wizard and admin settings.
|
||||
* Allows access during setup (no auth needed) or after setup (admin auth required).
|
||||
*/
|
||||
export async function requireSetupIncompleteOrAdmin(
|
||||
request: NextRequest,
|
||||
handler: (request: NextRequest) => Promise<NextResponse>
|
||||
): Promise<NextResponse> {
|
||||
let setupComplete = false;
|
||||
|
||||
try {
|
||||
const config = await prisma.configuration.findUnique({
|
||||
where: { key: 'setup_completed' },
|
||||
});
|
||||
setupComplete = config?.value === 'true';
|
||||
} catch {
|
||||
// If database is not ready, setup is definitely not complete — allow through
|
||||
return handler(request);
|
||||
}
|
||||
|
||||
if (!setupComplete) {
|
||||
// Setup in progress — allow unauthenticated access (setup wizard)
|
||||
return handler(request);
|
||||
}
|
||||
|
||||
// Setup is complete — require admin authentication
|
||||
return requireAuth(request, (authenticatedReq) =>
|
||||
requireAdmin(authenticatedReq, () => handler(request))
|
||||
);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user