Add authentication system with login, password reset, and member area
This commit is contained in:
125
server/utils/auth.js
Normal file
125
server/utils/auth.js
Normal file
@@ -0,0 +1,125 @@
|
||||
import bcrypt from 'bcryptjs'
|
||||
import jwt from 'jsonwebtoken'
|
||||
import { promises as fs } from 'fs'
|
||||
import path from 'path'
|
||||
|
||||
const JWT_SECRET = process.env.JWT_SECRET || 'harheimertc-secret-key-change-in-production'
|
||||
const USERS_FILE = path.join(process.cwd(), 'server/data/users.json')
|
||||
const SESSIONS_FILE = path.join(process.cwd(), 'server/data/sessions.json')
|
||||
|
||||
// Read users from file
|
||||
export async function readUsers() {
|
||||
try {
|
||||
const data = await fs.readFile(USERS_FILE, 'utf-8')
|
||||
return JSON.parse(data)
|
||||
} catch (error) {
|
||||
console.error('Fehler beim Lesen der Benutzerdaten:', error)
|
||||
return []
|
||||
}
|
||||
}
|
||||
|
||||
// Write users to file
|
||||
export async function writeUsers(users) {
|
||||
try {
|
||||
await fs.writeFile(USERS_FILE, JSON.stringify(users, null, 2), 'utf-8')
|
||||
return true
|
||||
} catch (error) {
|
||||
console.error('Fehler beim Schreiben der Benutzerdaten:', error)
|
||||
return false
|
||||
}
|
||||
}
|
||||
|
||||
// Read sessions from file
|
||||
export async function readSessions() {
|
||||
try {
|
||||
const data = await fs.readFile(SESSIONS_FILE, 'utf-8')
|
||||
return JSON.parse(data)
|
||||
} catch (error) {
|
||||
console.error('Fehler beim Lesen der Sessions:', error)
|
||||
return []
|
||||
}
|
||||
}
|
||||
|
||||
// Write sessions to file
|
||||
export async function writeSessions(sessions) {
|
||||
try {
|
||||
await fs.writeFile(SESSIONS_FILE, JSON.stringify(sessions, null, 2), 'utf-8')
|
||||
return true
|
||||
} catch (error) {
|
||||
console.error('Fehler beim Schreiben der Sessions:', error)
|
||||
return false
|
||||
}
|
||||
}
|
||||
|
||||
// Hash password
|
||||
export async function hashPassword(password) {
|
||||
const salt = await bcrypt.genSalt(10)
|
||||
return await bcrypt.hash(password, salt)
|
||||
}
|
||||
|
||||
// Verify password
|
||||
export async function verifyPassword(password, hash) {
|
||||
return await bcrypt.compare(password, hash)
|
||||
}
|
||||
|
||||
// Generate JWT token
|
||||
export function generateToken(user) {
|
||||
return jwt.sign(
|
||||
{
|
||||
id: user.id,
|
||||
email: user.email,
|
||||
role: user.role
|
||||
},
|
||||
JWT_SECRET,
|
||||
{ expiresIn: '7d' }
|
||||
)
|
||||
}
|
||||
|
||||
// Verify JWT token
|
||||
export function verifyToken(token) {
|
||||
try {
|
||||
return jwt.verify(token, JWT_SECRET)
|
||||
} catch (error) {
|
||||
return null
|
||||
}
|
||||
}
|
||||
|
||||
// Get user from token
|
||||
export async function getUserFromToken(token) {
|
||||
const decoded = verifyToken(token)
|
||||
if (!decoded) return null
|
||||
|
||||
const users = await readUsers()
|
||||
return users.find(u => u.id === decoded.id)
|
||||
}
|
||||
|
||||
// Create session
|
||||
export async function createSession(userId, token) {
|
||||
const sessions = await readSessions()
|
||||
const session = {
|
||||
id: Date.now().toString(),
|
||||
userId,
|
||||
token,
|
||||
createdAt: new Date().toISOString(),
|
||||
expiresAt: new Date(Date.now() + 7 * 24 * 60 * 60 * 1000).toISOString() // 7 days
|
||||
}
|
||||
sessions.push(session)
|
||||
await writeSessions(sessions)
|
||||
return session
|
||||
}
|
||||
|
||||
// Delete session
|
||||
export async function deleteSession(token) {
|
||||
const sessions = await readSessions()
|
||||
const filtered = sessions.filter(s => s.token !== token)
|
||||
await writeSessions(filtered)
|
||||
}
|
||||
|
||||
// Clean expired sessions
|
||||
export async function cleanExpiredSessions() {
|
||||
const sessions = await readSessions()
|
||||
const now = new Date()
|
||||
const valid = sessions.filter(s => new Date(s.expiresAt) > now)
|
||||
await writeSessions(valid)
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user