Refactor authentication and data handling in API; implement encryption for user and member data storage. Update relevant components to utilize new encryption methods, ensuring secure data management across the application. Enhance error handling and streamline data writing processes for improved reliability.
This commit is contained in:
@@ -1,6 +1,7 @@
|
||||
import { promises as fs } from 'fs'
|
||||
import path from 'path'
|
||||
import { randomUUID } from 'crypto'
|
||||
import { encrypt, decrypt, encryptObject, decryptObject } from './encryption.js'
|
||||
|
||||
// Handle both dev and production paths
|
||||
const getDataPath = (filename) => {
|
||||
@@ -17,11 +18,66 @@ const getDataPath = (filename) => {
|
||||
|
||||
const MEMBERS_FILE = getDataPath('members.json')
|
||||
|
||||
// Read manual members from file
|
||||
// Get encryption key from environment or config
|
||||
function getEncryptionKey() {
|
||||
return process.env.ENCRYPTION_KEY || 'default-key-change-in-production'
|
||||
}
|
||||
|
||||
// Check if data is encrypted by trying to parse as JSON first
|
||||
function isEncrypted(data) {
|
||||
try {
|
||||
// Try to parse as JSON - if successful and looks like member data, it's unencrypted
|
||||
const parsed = JSON.parse(data.trim())
|
||||
// If it's an array (members list) or object with member-like structure, it's unencrypted
|
||||
if (Array.isArray(parsed)) {
|
||||
return false // Unencrypted array
|
||||
}
|
||||
// If it's an object but not encrypted format, it's unencrypted
|
||||
if (typeof parsed === 'object' && parsed !== null && !parsed.encryptedData) {
|
||||
return false
|
||||
}
|
||||
return false
|
||||
} catch (e) {
|
||||
// JSON parsing failed - likely encrypted base64
|
||||
return true
|
||||
}
|
||||
}
|
||||
|
||||
// Read manual members from file (with encryption support and migration)
|
||||
export async function readMembers() {
|
||||
try {
|
||||
const data = await fs.readFile(MEMBERS_FILE, 'utf-8')
|
||||
return JSON.parse(data)
|
||||
|
||||
// Check if data is encrypted or plain JSON
|
||||
const encrypted = isEncrypted(data)
|
||||
|
||||
if (encrypted) {
|
||||
// Decrypt and parse
|
||||
const encryptionKey = getEncryptionKey()
|
||||
try {
|
||||
return decryptObject(data, encryptionKey)
|
||||
} catch (decryptError) {
|
||||
console.error('Fehler beim Entschlüsseln der Mitgliederdaten:', decryptError)
|
||||
// Fallback: try to read as plain JSON (migration scenario)
|
||||
try {
|
||||
const plainData = JSON.parse(data)
|
||||
console.warn('Entschlüsselung fehlgeschlagen, versuche als unverschlüsseltes Format zu lesen')
|
||||
return plainData
|
||||
} catch (parseError) {
|
||||
console.error('Konnte Mitgliederdaten weder entschlüsseln noch als JSON lesen')
|
||||
return []
|
||||
}
|
||||
}
|
||||
} else {
|
||||
// Plain JSON - migrate to encrypted format
|
||||
const members = JSON.parse(data)
|
||||
console.log('Migriere unverschlüsselte Mitgliederdaten zu verschlüsselter Speicherung...')
|
||||
|
||||
// Write back encrypted
|
||||
await writeMembers(members)
|
||||
|
||||
return members
|
||||
}
|
||||
} catch (error) {
|
||||
if (error.code === 'ENOENT') {
|
||||
return []
|
||||
@@ -31,10 +87,12 @@ export async function readMembers() {
|
||||
}
|
||||
}
|
||||
|
||||
// Write manual members to file
|
||||
// Write manual members to file (always encrypted)
|
||||
export async function writeMembers(members) {
|
||||
try {
|
||||
await fs.writeFile(MEMBERS_FILE, JSON.stringify(members, null, 2), 'utf-8')
|
||||
const encryptionKey = getEncryptionKey()
|
||||
const encryptedData = encryptObject(members, encryptionKey)
|
||||
await fs.writeFile(MEMBERS_FILE, encryptedData, 'utf-8')
|
||||
return true
|
||||
} catch (error) {
|
||||
console.error('Fehler beim Schreiben der Mitgliederdaten:', error)
|
||||
|
||||
Reference in New Issue
Block a user