import { Router } from 'express' import { config } from '../config.js' import { getCustomerByAppwriteUserId, getPortalAccessByCustomerId, updateDocument, } from '../services/appwriteAdmin.js' import { loginWithAppwrite } from '../services/appwriteClient.js' import { clearPortalSession, requireSession, setPortalSession, } from '../middleware/session.js' const router = Router() function sanitizeCustomer(customer) { return { id: customer.$id, code: customer.code || '', name: customer.name || '', companyName: customer.companyName || '', email: customer.email || '', phone: customer.phone || '', location: customer.location || '', customerStatus: customer.customerStatus || '', portalAccessEnabled: Boolean(customer.portalAccessEnabled), } } async function validatePortalAccess(appwriteUserId) { const customer = await getCustomerByAppwriteUserId(appwriteUserId) if (!customer) { const error = new Error('Kein Kundenkonto für diesen Login gefunden.') error.status = 403 throw error } if (!customer.portalAccessEnabled) { const error = new Error('Portalzugang ist nicht freigeschaltet.') error.status = 403 throw error } const portalAccess = await getPortalAccessByCustomerId(customer.$id) if (!portalAccess || !portalAccess.enabled) { const error = new Error('Portalzugang ist deaktiviert.') error.status = 403 throw error } const status = (customer.customerStatus || '').toLowerCase() if (!config.allowedCustomerStatuses.includes(status)) { const error = new Error('Kundenkonto ist nicht aktiv.') error.status = 403 throw error } return { customer, portalAccess } } const DEBUG_LOG = (location, message, data, hypothesisId) => { // #region agent log fetch('http://127.0.0.1:7281/ingest/30e8e71c-b377-4e72-84f9-593826c6d234', { method: 'POST', headers: { 'Content-Type': 'application/json', 'X-Debug-Session-Id': '80bbfc' }, body: JSON.stringify({ sessionId: '80bbfc', location, message, data, hypothesisId, timestamp: Date.now(), }), }).catch(() => {}) // #endregion } router.post('/login', async (req, res) => { const { email, password } = req.body || {} if (!email || !password) { return res.status(400).json({ error: 'E-Mail und Passwort erforderlich' }) } try { const user = await loginWithAppwrite(email.trim(), password) DEBUG_LOG('auth.js:login', 'appwrite user ok', { userId: user.$id }, 'H3') const { customer, portalAccess } = await validatePortalAccess(user.$id) DEBUG_LOG('auth.js:login', 'portal validation ok', { customerId: customer.$id, portalAccessEnabled: Boolean(customer.portalAccessEnabled), }, 'H4') setPortalSession(res, { customerId: customer.$id, appwriteUserId: user.$id, name: customer.name || user.name || '', email: customer.email || user.email || email, }) try { await updateDocument(config.collections.customerPortalAccess, portalAccess.$id, { lastLoginAt: new Date().toISOString(), }) } catch (err) { console.warn('[auth] lastLoginAt update failed:', err.message) } return res.json({ success: true, customer: sanitizeCustomer(customer) }) } catch (err) { const status = err.status || 500 DEBUG_LOG('auth.js:login', 'login failed', { status, message: err?.message?.slice(0, 120), }, status === 403 ? 'H4' : status === 401 ? 'H1' : 'H5') return res.status(status).json({ error: err.message || 'Anmeldung fehlgeschlagen' }) } }) router.post('/logout', (_req, res) => { clearPortalSession(res) res.json({ success: true }) }) router.get('/me', requireSession, async (req, res) => { try { const customer = await getCustomerByAppwriteUserId(req.session.appwriteUserId) if (!customer) { clearPortalSession(res) return res.status(403).json({ error: 'Kundenkonto nicht gefunden' }) } return res.json({ customer: sanitizeCustomer(customer) }) } catch (err) { return res.status(500).json({ error: err.message || 'Fehler beim Laden' }) } }) export default router