mirror of
https://github.com/Since-3/since3-portal.git
synced 2026-10-12 20:51:17 +00:00
143 lines
4.8 KiB
TypeScript
143 lines
4.8 KiB
TypeScript
"use server";
|
|
|
|
import * as z from "zod";
|
|
import { revalidatePath } from "next/cache";
|
|
import { createAdminClient } from "@/lib/supabase/admin";
|
|
import { createClient } from "@/lib/supabase/server";
|
|
import { verifySession } from "@/lib/supabase/dal";
|
|
import { getClientId } from "@/modules/shared/queries/profile";
|
|
|
|
const CredentialSchema = z.object({
|
|
profileId: z.string().uuid(),
|
|
service: z.string().min(1, { error: "Dienst ist erforderlich." }),
|
|
username: z.string().min(1, { error: "Benutzername ist erforderlich." }),
|
|
password: z.string().min(1, { error: "Passwort ist erforderlich." }),
|
|
});
|
|
|
|
export type CredentialState = { error: string } | { success: true } | undefined;
|
|
|
|
export async function createCredential(
|
|
_prevState: CredentialState,
|
|
formData: FormData
|
|
): Promise<CredentialState> {
|
|
const session = await verifySession();
|
|
const profileId = String(formData.get("profileId") ?? "");
|
|
|
|
if (!session.isAdmin && session.userId !== profileId) {
|
|
return { error: "Keine Berechtigung." };
|
|
}
|
|
|
|
const validatedFields = CredentialSchema.safeParse({
|
|
profileId,
|
|
service: formData.get("service"),
|
|
username: formData.get("username"),
|
|
password: formData.get("password"),
|
|
});
|
|
|
|
if (!validatedFields.success) {
|
|
const { fieldErrors } = z.flattenError(validatedFields.error);
|
|
const firstError = Object.values(fieldErrors).flat()[0];
|
|
return { error: firstError ?? "Bitte alle Felder ausfüllen." };
|
|
}
|
|
|
|
const clientId = await getClientId(profileId);
|
|
if (!clientId) {
|
|
return { error: "Client hat noch keine Stammdaten hinterlegt." };
|
|
}
|
|
|
|
const supabase = await createClient();
|
|
const { error } = await supabase.rpc("create_credential", {
|
|
p_client_id: clientId,
|
|
p_service: validatedFields.data.service,
|
|
p_username: validatedFields.data.username,
|
|
p_password: validatedFields.data.password,
|
|
});
|
|
|
|
if (error) return { error: "Eintrag konnte nicht gespeichert werden." };
|
|
|
|
revalidatePath("/client/passwords");
|
|
revalidatePath(`/admin/clients/${profileId}/passwords`);
|
|
|
|
return { success: true };
|
|
}
|
|
|
|
const UpdateCredentialSchema = z.object({
|
|
profileId: z.string().uuid(),
|
|
credentialId: z.string().uuid(),
|
|
service: z.string().min(1, { error: "Dienst ist erforderlich." }),
|
|
username: z.string().min(1, { error: "Benutzername ist erforderlich." }),
|
|
password: z.string().optional(),
|
|
});
|
|
|
|
export async function updateCredential(
|
|
_prevState: CredentialState,
|
|
formData: FormData
|
|
): Promise<CredentialState> {
|
|
const session = await verifySession();
|
|
const profileId = String(formData.get("profileId") ?? "");
|
|
|
|
if (!session.isAdmin && session.userId !== profileId) {
|
|
return { error: "Keine Berechtigung." };
|
|
}
|
|
|
|
const password = String(formData.get("password") ?? "").trim();
|
|
|
|
const validatedFields = UpdateCredentialSchema.safeParse({
|
|
profileId,
|
|
credentialId: formData.get("credentialId"),
|
|
service: formData.get("service"),
|
|
username: formData.get("username"),
|
|
password: password === "" ? undefined : password,
|
|
});
|
|
|
|
if (!validatedFields.success) {
|
|
const { fieldErrors } = z.flattenError(validatedFields.error);
|
|
const firstError = Object.values(fieldErrors).flat()[0];
|
|
return { error: firstError ?? "Bitte alle Felder ausfüllen." };
|
|
}
|
|
|
|
const supabase = await createClient();
|
|
const { error } = await supabase.rpc("update_credential", {
|
|
p_id: validatedFields.data.credentialId,
|
|
p_service: validatedFields.data.service,
|
|
p_username: validatedFields.data.username,
|
|
p_password: validatedFields.data.password ?? null,
|
|
});
|
|
|
|
if (error) return { error: "Eintrag konnte nicht aktualisiert werden." };
|
|
|
|
revalidatePath("/client/passwords");
|
|
revalidatePath(`/admin/clients/${profileId}/passwords`);
|
|
|
|
return { success: true };
|
|
}
|
|
|
|
export async function revealCredential(credentialId: string): Promise<{ password: string } | { error: string }> {
|
|
await verifySession();
|
|
|
|
const supabase = await createClient();
|
|
const { data, error } = await supabase.rpc("reveal_credential", { p_id: credentialId });
|
|
|
|
if (error || typeof data !== "string") {
|
|
return { error: "Passwort konnte nicht abgerufen werden." };
|
|
}
|
|
|
|
return { password: data };
|
|
}
|
|
|
|
export async function deleteCredential(profileId: string, credentialId: string): Promise<CredentialState> {
|
|
const session = await verifySession();
|
|
|
|
if (!session.isAdmin) {
|
|
return { error: "Keine Berechtigung." };
|
|
}
|
|
|
|
const supabase = createAdminClient();
|
|
const { error } = await supabase.from("credentials").delete().eq("id", credentialId);
|
|
|
|
if (error) return { error: "Eintrag konnte nicht gelöscht werden." };
|
|
|
|
revalidatePath(`/admin/clients/${profileId}/passwords`);
|
|
|
|
return { success: true };
|
|
}
|