Admin Passwort in die db und in Backen konfiguriebar

This commit is contained in:
titver968
2025-04-17 16:00:18 +02:00
parent 06693cf59a
commit b3c7113ce4
11 changed files with 366 additions and 16 deletions

View File

@@ -39,6 +39,9 @@
<a href="/admin/dienststellen" class="bg-green-600 text-white px-4 py-3 rounded text-center hover:bg-green-700">
🏢 Dienststellen verwalten
</a>
<a href="/admin/change-password" class="bg-cyan-600 text-white px-4 py-3 rounded text-center hover:bg-green-700">
👨‍💼 Passwort ädern
</a>
</div>
<button
on:click={async () => {

View File

@@ -0,0 +1,82 @@
<script lang="ts">
let oldPassword = '';
let newPassword = '';
let confirmPassword = '';
let message = '';
let error = '';
async function changePassword() {
message = '';
error = '';
if (newPassword !== confirmPassword) {
error = 'Die neuen Passwörter stimmen nicht überein.';
return;
}
const res = await fetch('/api/admin/change-password', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
credentials: 'include',
body: JSON.stringify({ oldPassword, newPassword })
});
const data = await res.json();
if (!res.ok) {
error = data.error || 'Fehler beim Ändern des Passworts.';
} else {
message = '✅ Passwort erfolgreich geändert.';
oldPassword = newPassword = confirmPassword = '';
}
}
</script>
<div class="max-w-lg mx-auto bg-white p-6 rounded-2xl shadow-md space-y-6 border border-gray-200">
<h2 class="text-2xl font-bold text-gray-800">🔐 Admin-Passwort ändern</h2>
<div class="space-y-4">
<div>
<label class="block text-sm font-medium text-gray-700">Altes Passwort</label>
<input
type="password"
bind:value={oldPassword}
class="mt-1 w-full px-4 py-2 border rounded-xl focus:outline-none focus:ring-2 focus:ring-blue-500"
/>
</div>
<div>
<label class="block text-sm font-medium text-gray-700">Neues Passwort</label>
<input
type="password"
bind:value={newPassword}
class="mt-1 w-full px-4 py-2 border rounded-xl focus:outline-none focus:ring-2 focus:ring-blue-500"
/>
</div>
<div>
<label class="block text-sm font-medium text-gray-700">Neues Passwort wiederholen</label>
<input
type="password"
bind:value={confirmPassword}
class="mt-1 w-full px-4 py-2 border rounded-xl focus:outline-none focus:ring-2 focus:ring-blue-500"
/>
</div>
</div>
{#if error}
<div class="text-red-600 text-sm font-medium">{error}</div>
{/if}
{#if message}
<div class="text-green-600 text-sm font-medium">{message}</div>
{/if}
<div class="pt-4">
<button
on:click={changePassword}
class="w-full bg-blue-600 hover:bg-blue-700 text-white font-semibold py-2 px-4 rounded-xl transition duration-150"
>
Passwort ändern
</button>
</div>

View File

@@ -0,0 +1,30 @@
import { json } from '@sveltejs/kit';
import type { RequestHandler } from './$types';
import { PrismaClient } from '@prisma/client';
import bcrypt from 'bcryptjs';
const prisma = new PrismaClient();
function checkAuth(cookies: any) {
return cookies.get('admin_session') === 'true';
}
export const POST: RequestHandler = async ({ request, cookies }) => {
if (!checkAuth(cookies)) return new Response('Nicht erlaubt', { status: 401 });
const { oldPassword, newPassword } = await request.json();
const admin = await prisma.admin.findUnique({ where: { id: 1 } });
if (!admin) return json({ error: 'Admin nicht gefunden' }, { status: 500 });
const isValid = await bcrypt.compare(oldPassword, admin.password);
if (!isValid) return json({ error: 'Falsches Passwort' }, { status: 401 });
const newHashed = await bcrypt.hash(newPassword, 10);
await prisma.admin.update({
where: { id: 1 },
data: { password: newHashed }
});
return json({ success: true });
};

View File

@@ -1,20 +1,29 @@
import { json } from '@sveltejs/kit';
import type { RequestHandler } from './$types';
import { PrismaClient } from '@prisma/client';
import bcrypt from 'bcryptjs';
const ADMIN_PASS = import.meta.env.VITE_ADMIN_PASS;
const prisma = new PrismaClient();
export const POST: RequestHandler = async ({ request, cookies }) => {
const { passwort } = await request.json();
if (passwort === ADMIN_PASS) {
cookies.set('admin_session', 'true', {
path: '/',
httpOnly: true,
sameSite: 'strict',
maxAge: 60 * 60 * 4 // 4 Stunden
});
return json({ success: true });
const admin = await prisma.admin.findUnique({ where: { id: 1 } });
if (!admin) {
return json({ error: 'Kein Admin gefunden' }, { status: 500 });
}
return json({ error: 'Falsches Passwort' }, { status: 401 });
};
const isValid = await bcrypt.compare(passwort, admin.password);
if (!isValid) {
return json({ error: 'Falsches Passwort' }, { status: 401 });
}
cookies.set('admin_session', 'true', {
path: '/',
httpOnly: true,
sameSite: 'strict',
maxAge: 60 * 60 * 4 // 4 Stunden
});
return json({ success: true });
};