Aktueller Stand
This commit is contained in:
76
app/api/settings/google-places/route.ts
Normal file
76
app/api/settings/google-places/route.ts
Normal file
@@ -0,0 +1,76 @@
|
||||
import { NextResponse } from "next/server";
|
||||
import { prisma } from "../../../../lib/prisma";
|
||||
import { isSuperAdminSession, requireSession } from "../../../../lib/auth-helpers";
|
||||
|
||||
export async function GET() {
|
||||
const { session } = await requireSession();
|
||||
if (!session) {
|
||||
return NextResponse.json({ error: "Unauthorized" }, { status: 401 });
|
||||
}
|
||||
|
||||
const apiKeySetting = await prisma.setting.findUnique({
|
||||
where: { key: "google_places_api_key" }
|
||||
});
|
||||
const providerSetting = await prisma.setting.findUnique({
|
||||
where: { key: "geocoding_provider" }
|
||||
});
|
||||
const registrationSetting = await prisma.setting.findUnique({
|
||||
where: { key: "registration_enabled" }
|
||||
});
|
||||
|
||||
const apiKey = apiKeySetting?.value || "";
|
||||
const provider =
|
||||
providerSetting?.value || (apiKey ? "google" : "osm");
|
||||
const registrationEnabled = registrationSetting?.value !== "false";
|
||||
|
||||
return NextResponse.json({ apiKey, provider, registrationEnabled });
|
||||
}
|
||||
|
||||
export async function POST(request: Request) {
|
||||
const { session } = await requireSession();
|
||||
if (!session) {
|
||||
return NextResponse.json({ error: "Unauthorized" }, { status: 401 });
|
||||
}
|
||||
|
||||
if (!isSuperAdminSession(session)) {
|
||||
return NextResponse.json({ error: "Forbidden" }, { status: 403 });
|
||||
}
|
||||
|
||||
const body = await request.json();
|
||||
const { apiKey, provider, registrationEnabled } = body || {};
|
||||
|
||||
if (!provider || !["google", "osm"].includes(provider)) {
|
||||
return NextResponse.json({ error: "Provider erforderlich." }, { status: 400 });
|
||||
}
|
||||
|
||||
if (provider === "google" && !apiKey) {
|
||||
return NextResponse.json({ error: "API-Key erforderlich." }, { status: 400 });
|
||||
}
|
||||
|
||||
const apiKeyValue = provider === "google" ? apiKey : "";
|
||||
|
||||
const apiKeySetting = await prisma.setting.upsert({
|
||||
where: { key: "google_places_api_key" },
|
||||
update: { value: apiKeyValue },
|
||||
create: { key: "google_places_api_key", value: apiKeyValue }
|
||||
});
|
||||
|
||||
const providerSetting = await prisma.setting.upsert({
|
||||
where: { key: "geocoding_provider" },
|
||||
update: { value: provider },
|
||||
create: { key: "geocoding_provider", value: provider }
|
||||
});
|
||||
|
||||
const registrationValue = registrationEnabled === false ? "false" : "true";
|
||||
await prisma.setting.upsert({
|
||||
where: { key: "registration_enabled" },
|
||||
update: { value: registrationValue },
|
||||
create: { key: "registration_enabled", value: registrationValue }
|
||||
});
|
||||
|
||||
return NextResponse.json({
|
||||
apiKey: apiKeySetting.value,
|
||||
provider: providerSetting.value,
|
||||
registrationEnabled: registrationValue !== "false"
|
||||
});
|
||||
}
|
||||
118
app/api/settings/logo/route.ts
Normal file
118
app/api/settings/logo/route.ts
Normal file
@@ -0,0 +1,118 @@
|
||||
import { NextResponse } from "next/server";
|
||||
import { promises as fs } from "fs";
|
||||
import path from "path";
|
||||
import { prisma } from "../../../../lib/prisma";
|
||||
import { isSuperAdminSession, requireSession } from "../../../../lib/auth-helpers";
|
||||
|
||||
export const dynamic = "force-dynamic";
|
||||
export const revalidate = 0;
|
||||
|
||||
const DATA_DIR = path.join(process.cwd(), "prisma", "data");
|
||||
const UPLOADS_DIR = path.join(DATA_DIR, "uploads");
|
||||
|
||||
const MIME_TO_EXT: Record<string, string> = {
|
||||
"image/png": "png",
|
||||
"image/jpeg": "jpg",
|
||||
"image/webp": "webp",
|
||||
"image/svg+xml": "svg"
|
||||
};
|
||||
|
||||
const resolveLogoPath = (relativePath: string) => {
|
||||
const absolutePath = path.join(DATA_DIR, relativePath);
|
||||
if (!absolutePath.startsWith(DATA_DIR)) {
|
||||
throw new Error("Ungültiger Pfad.");
|
||||
}
|
||||
return absolutePath;
|
||||
};
|
||||
|
||||
const getLogoSetting = async () =>
|
||||
prisma.setting.findUnique({ where: { key: "app_logo_path" } });
|
||||
|
||||
const getLogoTypeSetting = async () =>
|
||||
prisma.setting.findUnique({ where: { key: "app_logo_type" } });
|
||||
|
||||
export async function POST(request: Request) {
|
||||
const { session } = await requireSession();
|
||||
if (!session) {
|
||||
return NextResponse.json({ error: "Unauthorized" }, { status: 401 });
|
||||
}
|
||||
if (!isSuperAdminSession(session)) {
|
||||
return NextResponse.json({ error: "Forbidden" }, { status: 403 });
|
||||
}
|
||||
|
||||
const formData = await request.formData();
|
||||
const file = formData.get("file");
|
||||
|
||||
if (!file || !(file instanceof File)) {
|
||||
return NextResponse.json({ error: "Datei fehlt." }, { status: 400 });
|
||||
}
|
||||
|
||||
const extension = MIME_TO_EXT[file.type];
|
||||
if (!extension) {
|
||||
return NextResponse.json({ error: "Dateityp nicht unterstützt." }, { status: 400 });
|
||||
}
|
||||
|
||||
await fs.mkdir(UPLOADS_DIR, { recursive: true });
|
||||
|
||||
const previousSetting = await getLogoSetting();
|
||||
const previousTypeSetting = await getLogoTypeSetting();
|
||||
|
||||
const filename = `app-logo.${extension}`;
|
||||
const relativePath = path.join("uploads", filename);
|
||||
const absolutePath = resolveLogoPath(relativePath);
|
||||
|
||||
const buffer = Buffer.from(await file.arrayBuffer());
|
||||
await fs.writeFile(absolutePath, buffer);
|
||||
|
||||
if (previousSetting?.value && previousSetting.value !== relativePath) {
|
||||
try {
|
||||
await fs.unlink(resolveLogoPath(previousSetting.value));
|
||||
} catch {
|
||||
// ignore missing old file
|
||||
}
|
||||
}
|
||||
|
||||
await prisma.setting.upsert({
|
||||
where: { key: "app_logo_path" },
|
||||
update: { value: relativePath },
|
||||
create: { key: "app_logo_path", value: relativePath }
|
||||
});
|
||||
|
||||
await prisma.setting.upsert({
|
||||
where: { key: "app_logo_type" },
|
||||
update: { value: file.type },
|
||||
create: { key: "app_logo_type", value: file.type }
|
||||
});
|
||||
|
||||
return NextResponse.json({ ok: true });
|
||||
}
|
||||
|
||||
export async function DELETE() {
|
||||
const { session } = await requireSession();
|
||||
if (!session) {
|
||||
return NextResponse.json({ error: "Unauthorized" }, { status: 401 });
|
||||
}
|
||||
if (!isSuperAdminSession(session)) {
|
||||
return NextResponse.json({ error: "Forbidden" }, { status: 403 });
|
||||
}
|
||||
|
||||
const logoSetting = await getLogoSetting();
|
||||
const typeSetting = await getLogoTypeSetting();
|
||||
|
||||
if (logoSetting?.value) {
|
||||
try {
|
||||
await fs.unlink(resolveLogoPath(logoSetting.value));
|
||||
} catch {
|
||||
// ignore missing file
|
||||
}
|
||||
}
|
||||
|
||||
if (logoSetting) {
|
||||
await prisma.setting.delete({ where: { key: "app_logo_path" } });
|
||||
}
|
||||
if (typeSetting) {
|
||||
await prisma.setting.delete({ where: { key: "app_logo_type" } });
|
||||
}
|
||||
|
||||
return NextResponse.json({ ok: true });
|
||||
}
|
||||
Reference in New Issue
Block a user