Prepare Kalendartool for MPM and disable invites
This commit is contained in:
@@ -1,98 +0,0 @@
|
||||
/**
|
||||
* POST /api/calendars/[id]/invites - Invite-Link erstellen (nur Owner-Admin).
|
||||
* GET /api/calendars/[id]/invites - Invite-Uebersicht (Aktiv/Abgelaufen/Verwendet).
|
||||
*/
|
||||
import { NextRequest, NextResponse } from 'next/server';
|
||||
import { prisma } from '@/lib/db/client';
|
||||
import { requireCalendarContext } from '@/lib/api/context';
|
||||
import { createInviteSchema } from '@/lib/validation';
|
||||
import { canManageCalendar } from '@/lib/permissions/permissions';
|
||||
import {
|
||||
generateInviteToken,
|
||||
hashInviteToken,
|
||||
defaultInviteExpiry,
|
||||
} from '@/lib/invites/tokens';
|
||||
import { getConfig } from '@/lib/config';
|
||||
import { errorResponse, forbiddenResponse } from '@/lib/api/responses';
|
||||
|
||||
interface RouteParams {
|
||||
params: Promise<{ id: string }>;
|
||||
}
|
||||
|
||||
export async function POST(
|
||||
request: NextRequest,
|
||||
{ params }: RouteParams,
|
||||
): Promise<NextResponse> {
|
||||
try {
|
||||
const { id } = await params;
|
||||
const context = await requireCalendarContext(id);
|
||||
|
||||
if (!canManageCalendar(context.user, context.calendar)) {
|
||||
return forbiddenResponse();
|
||||
}
|
||||
|
||||
const body = createInviteSchema.parse(await request.json());
|
||||
const expiry = body.expiresInDays
|
||||
? new Date(Date.now() + body.expiresInDays * 24 * 60 * 60 * 1000)
|
||||
: defaultInviteExpiry();
|
||||
|
||||
// Klartext-Token wird genau einmal zurueckgegeben; in der DB
|
||||
// liegt ausschliesslich der Hash (plan.md Abschnitt 9).
|
||||
const token = generateInviteToken();
|
||||
const invite = await prisma.invite.create({
|
||||
data: {
|
||||
calendarId: id,
|
||||
tokenHash: hashInviteToken(token),
|
||||
expiresAt: expiry,
|
||||
},
|
||||
select: { id: true, expiresAt: true, createdAt: true },
|
||||
});
|
||||
|
||||
return NextResponse.json(
|
||||
{
|
||||
invite,
|
||||
inviteUrl: `${getConfig().appUrl}/invite/${token}`,
|
||||
},
|
||||
{ status: 201 },
|
||||
);
|
||||
} catch (error) {
|
||||
return errorResponse(error);
|
||||
}
|
||||
}
|
||||
|
||||
export async function GET(
|
||||
_request: NextRequest,
|
||||
{ params }: RouteParams,
|
||||
): Promise<NextResponse> {
|
||||
try {
|
||||
const { id } = await params;
|
||||
const context = await requireCalendarContext(id);
|
||||
|
||||
if (!canManageCalendar(context.user, context.calendar)) {
|
||||
return forbiddenResponse();
|
||||
}
|
||||
|
||||
const invites = await prisma.invite.findMany({
|
||||
where: { calendarId: id },
|
||||
orderBy: { createdAt: 'desc' },
|
||||
select: { id: true, expiresAt: true, usedAt: true, createdAt: true },
|
||||
});
|
||||
|
||||
const now = new Date();
|
||||
const summary = {
|
||||
active: invites.filter(
|
||||
(invite) =>
|
||||
invite.usedAt === null &&
|
||||
(invite.expiresAt === null || invite.expiresAt > now),
|
||||
).length,
|
||||
expired: invites.filter(
|
||||
(invite) => invite.usedAt === null && invite.expiresAt !== null && invite.expiresAt <= now,
|
||||
).length,
|
||||
used: invites.filter((invite) => invite.usedAt !== null).length,
|
||||
};
|
||||
|
||||
return NextResponse.json({ invites, summary });
|
||||
} catch (error) {
|
||||
return errorResponse(error);
|
||||
}
|
||||
}
|
||||
@@ -3,8 +3,8 @@
|
||||
* POST /api/calendars/[id]/members - User per E-Mail hinzufuegen (nur Admin).
|
||||
* DELETE /api/calendars/[id]/members - Mitglied entfernen (nur Admin).
|
||||
*
|
||||
* DB-basiertes Einladungssystem: Statt Invite-Links werden Benutzer
|
||||
* direkt per E-Mail-Suche ueber die Datenbank zugeordnet. Der Server
|
||||
* Benutzer werden direkt per E-Mail-Suche ueber die Datenbank
|
||||
* zugeordnet. Der Server
|
||||
* prueft die Verwaltungsberechtigung zentral (canManageCalendar).
|
||||
*/
|
||||
import { NextRequest, NextResponse } from 'next/server';
|
||||
@@ -141,4 +141,4 @@ export async function DELETE(
|
||||
} catch (error) {
|
||||
return errorResponse(error);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user