Files
vereinskalender/lib/system-settings.ts
2026-01-18 00:40:01 +01:00

123 lines
3.3 KiB
TypeScript

import { prisma } from "./prisma";
export type AccessSettings = {
publicAccessEnabled: boolean;
};
export type SystemSettings = AccessSettings & {
apiKey: string;
provider: "google" | "osm";
registrationEnabled: boolean;
emailVerificationRequired: boolean;
};
const PUBLIC_ACCESS_KEY = "public_access_enabled";
const EMAIL_VERIFICATION_KEY = "email_verification_required";
const LEGACY_ACCESS_KEYS = [
"public_events_enabled",
"anonymous_access_enabled"
] as const;
const SYSTEM_KEYS = [
"google_places_api_key",
"geocoding_provider",
"registration_enabled",
EMAIL_VERIFICATION_KEY
] as const;
const getSettingMap = async (keys: readonly string[]) => {
const records = await prisma.setting.findMany({
where: { key: { in: [...keys] } }
});
return new Map(records.map((record) => [record.key, record.value]));
};
const readBoolean = (value: string | undefined, fallback: boolean) => {
if (value === undefined) return fallback;
return value !== "false";
};
const ensurePublicAccessSetting = async (
prefetched?: Map<string, string>
) => {
const existingValue = prefetched?.get(PUBLIC_ACCESS_KEY);
if (existingValue !== undefined) {
return existingValue !== "false";
}
const existing = await prisma.setting.findUnique({
where: { key: PUBLIC_ACCESS_KEY }
});
if (existing) {
return existing.value !== "false";
}
const legacy = await prisma.setting.findMany({
where: { key: { in: [...LEGACY_ACCESS_KEYS] } }
});
const legacyMap = new Map(legacy.map((record) => [record.key, record.value]));
const publicEventsEnabled = readBoolean(
legacyMap.get("public_events_enabled"),
true
);
const anonymousAccessEnabled = readBoolean(
legacyMap.get("anonymous_access_enabled"),
true
);
const combined = publicEventsEnabled && anonymousAccessEnabled;
await prisma.setting.upsert({
where: { key: PUBLIC_ACCESS_KEY },
update: { value: combined ? "true" : "false" },
create: { key: PUBLIC_ACCESS_KEY, value: combined ? "true" : "false" }
});
if (legacy.length > 0) {
await prisma.setting.deleteMany({
where: { key: { in: [...LEGACY_ACCESS_KEYS] } }
});
}
return combined;
};
export async function getAccessSettings(): Promise<AccessSettings> {
const publicAccessEnabled = await ensurePublicAccessSetting();
return { publicAccessEnabled };
}
export async function getSystemSettings(): Promise<SystemSettings> {
const settings = await getSettingMap(SYSTEM_KEYS);
const apiKey = settings.get("google_places_api_key") || "";
const storedProvider = settings.get("geocoding_provider");
const provider =
storedProvider === "google" || storedProvider === "osm"
? storedProvider
: apiKey
? "google"
: "osm";
const registrationEnabled = readBoolean(
settings.get("registration_enabled"),
true
);
const emailVerificationRequired = readBoolean(
settings.get(EMAIL_VERIFICATION_KEY),
true
);
const publicAccessEnabled = await ensurePublicAccessSetting(settings);
return {
apiKey,
provider,
registrationEnabled,
publicAccessEnabled,
emailVerificationRequired
};
}
export async function getEmailVerificationRequired(): Promise<boolean> {
const setting = await prisma.setting.findUnique({
where: { key: EMAIL_VERIFICATION_KEY }
});
return setting?.value !== "false";
}