Initial commit

This commit is contained in:
kikootwo
2026-01-28 11:41:24 -05:00
commit a3ba192fbd
257 changed files with 89482 additions and 0 deletions
@@ -0,0 +1,75 @@
/**
* User Approval API
* Documentation: documentation/features/audiobookshelf-integration.md
*/
import { NextRequest, NextResponse } from 'next/server';
import { requireAuth, requireAdmin, AuthenticatedRequest } from '@/lib/middleware/auth';
import { prisma } from '@/lib/db';
export async function POST(
request: NextRequest,
{ params }: { params: Promise<{ id: string }> }
) {
return requireAuth(request, async (req: AuthenticatedRequest) => {
return requireAdmin(req, async () => {
try {
const { id } = await params;
const body = await request.json();
const { approve } = body; // true = approve, false = reject
const user = await prisma.user.findUnique({
where: { id },
select: {
id: true,
plexUsername: true,
registrationStatus: true,
},
});
if (!user) {
return NextResponse.json(
{ error: 'User not found' },
{ status: 404 }
);
}
if (user.registrationStatus !== 'pending_approval') {
return NextResponse.json(
{ error: 'User is not pending approval' },
{ status: 400 }
);
}
if (approve) {
// Approve user
await prisma.user.update({
where: { id },
data: { registrationStatus: 'approved' },
});
return NextResponse.json({
success: true,
message: `User ${user.plexUsername} has been approved`
});
} else {
// Reject user (delete the account)
await prisma.user.delete({
where: { id },
});
return NextResponse.json({
success: true,
message: `User ${user.plexUsername} has been rejected and removed`
});
}
} catch (error) {
console.error('[Admin] Failed to approve/reject user:', error);
return NextResponse.json(
{ error: 'Failed to process user approval' },
{ status: 500 }
);
}
});
});
}
+82
View File
@@ -0,0 +1,82 @@
/**
* Component: Admin User Update API
* Documentation: documentation/admin-dashboard.md
*/
import { NextRequest, NextResponse } from 'next/server';
import { requireAuth, requireAdmin, AuthenticatedRequest } from '@/lib/middleware/auth';
import { prisma } from '@/lib/db';
export async function PUT(
request: NextRequest,
{ params }: { params: Promise<{ id: string }> }
) {
return requireAuth(request, async (req: AuthenticatedRequest) => {
return requireAdmin(req, async () => {
try {
const { id } = await params;
const body = await request.json();
const { role } = body;
// Validate role
if (!role || (role !== 'user' && role !== 'admin')) {
return NextResponse.json(
{ error: 'Invalid role. Must be "user" or "admin"' },
{ status: 400 }
);
}
// Prevent user from demoting themselves
if (req.user && id === req.user.sub) {
return NextResponse.json(
{ error: 'You cannot change your own role' },
{ status: 403 }
);
}
// Check if user is the setup admin
const targetUser = await prisma.user.findUnique({
where: { id },
select: {
isSetupAdmin: true,
plexUsername: true,
},
});
if (!targetUser) {
return NextResponse.json(
{ error: 'User not found' },
{ status: 404 }
);
}
// Prevent changing setup admin role
if (targetUser.isSetupAdmin && role !== 'admin') {
return NextResponse.json(
{ error: 'Cannot change the setup admin role. This account must always remain an admin.' },
{ status: 403 }
);
}
// Update user role
const updatedUser = await prisma.user.update({
where: { id },
data: { role },
select: {
id: true,
plexUsername: true,
role: true,
},
});
return NextResponse.json({ user: updatedUser });
} catch (error) {
console.error('[Admin] Failed to update user:', error);
return NextResponse.json(
{ error: 'Failed to update user' },
{ status: 500 }
);
}
});
});
}