V 2.1.0 Verbesserungen von Claud Code eingefügt
This commit is contained in:
@@ -12,7 +12,7 @@ export async function login(prevState: any, formData: FormData) {
|
||||
return { error: 'Bitte Benutzername und Passwort eingeben' };
|
||||
}
|
||||
|
||||
const isValid = verifyCredentials(username, password);
|
||||
const isValid = await verifyCredentials(username, password);
|
||||
|
||||
if (!isValid) {
|
||||
return { error: 'Ungültige Anmeldedaten' };
|
||||
|
||||
@@ -30,6 +30,7 @@ export default function Home() {
|
||||
'Cache-Control': 'no-cache',
|
||||
},
|
||||
});
|
||||
if (!response.ok) throw new Error(`HTTP ${response.status}`);
|
||||
const data = await response.json();
|
||||
if (data.success) {
|
||||
setEntries(data.data);
|
||||
|
||||
@@ -36,6 +36,7 @@ export default function MonatsStatistik({ typ, refreshKey }: MonatsStatistikProp
|
||||
setIsLoading(true);
|
||||
try {
|
||||
const response = await fetch(`/api/ausgaben/stats?year=${y}&month=${m}&typ=${typ}`);
|
||||
if (!response.ok) throw new Error(`HTTP ${response.status}`);
|
||||
const data = await response.json();
|
||||
if (data.success) setStats(data.data);
|
||||
} catch (error) {
|
||||
|
||||
@@ -21,6 +21,7 @@ echo "Registry: ${REGISTRY}"
|
||||
echo "Image: ${IMAGE_NAME}"
|
||||
echo "Tag: ${TAG}"
|
||||
echo "Build-Datum: ${BUILD_DATE}"
|
||||
|
||||
echo "=========================================="
|
||||
echo ""
|
||||
|
||||
|
||||
22
lib/auth.ts
22
lib/auth.ts
@@ -1,20 +1,10 @@
|
||||
/**
|
||||
* Reusable authentication library
|
||||
* Configure users via environment variables in .env:
|
||||
* AUTH_USERS=user1:$2a$10$hash1,user2:$2a$10$hash2
|
||||
*
|
||||
* Use scripts/generate-password.js to generate password hashes
|
||||
*/
|
||||
import bcrypt from 'bcryptjs';
|
||||
|
||||
export interface User {
|
||||
username: string;
|
||||
password: string;
|
||||
}
|
||||
|
||||
/**
|
||||
* Parse users from environment variable
|
||||
* Format: username:password,username2:password2
|
||||
*/
|
||||
export function getUsers(): User[] {
|
||||
const usersString = process.env.AUTH_USERS || '';
|
||||
if (!usersString) {
|
||||
@@ -30,21 +20,15 @@ export function getUsers(): User[] {
|
||||
.filter((user) => user.username && user.password);
|
||||
}
|
||||
|
||||
/**
|
||||
* Verify user credentials
|
||||
*/
|
||||
export function verifyCredentials(username: string, password: string): boolean {
|
||||
export async function verifyCredentials(username: string, password: string): Promise<boolean> {
|
||||
const users = getUsers();
|
||||
const user = users.find(u => u.username === username);
|
||||
if (!user) {
|
||||
return false;
|
||||
}
|
||||
return user.password === password;
|
||||
return bcrypt.compare(password, user.password);
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if authentication is enabled
|
||||
*/
|
||||
export function isAuthEnabled(): boolean {
|
||||
return !!process.env.AUTH_USERS;
|
||||
}
|
||||
|
||||
@@ -2,6 +2,20 @@ import type { NextConfig } from "next";
|
||||
|
||||
const nextConfig: NextConfig = {
|
||||
output: 'standalone',
|
||||
async headers() {
|
||||
return [
|
||||
{
|
||||
source: '/(.*)',
|
||||
headers: [
|
||||
{ key: 'X-Frame-Options', value: 'DENY' },
|
||||
{ key: 'X-Content-Type-Options', value: 'nosniff' },
|
||||
{ key: 'Referrer-Policy', value: 'strict-origin-when-cross-origin' },
|
||||
{ key: 'Strict-Transport-Security', value: 'max-age=63072000; includeSubDomains; preload' },
|
||||
{ key: 'Permissions-Policy', value: 'camera=(), microphone=(), geolocation=()' },
|
||||
],
|
||||
},
|
||||
];
|
||||
},
|
||||
};
|
||||
|
||||
export default nextConfig;
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "ausgaben_next",
|
||||
"version": "2.0.2",
|
||||
"version": "2.1.0",
|
||||
"private": true,
|
||||
"scripts": {
|
||||
"dev": "next dev -p 3005",
|
||||
|
||||
Reference in New Issue
Block a user