/** * Appwrite JWT verification for user-scoped API routes. */ import { Client, Account } from 'node-appwrite' import { config } from '../config/index.mjs' import { AuthenticationError } from './errorHandler.mjs' /** * Verify Authorization: Bearer and attach Appwrite user to req.appwriteUser */ export function requireAuth(req, res, next) { ;(async () => { try { const header = req.headers.authorization || '' const m = /^Bearer\s+(.+)$/i.exec(header) if (!m?.[1]) { throw new AuthenticationError('Authorization Bearer token required') } const jwt = m[1].trim() const client = new Client() .setEndpoint(config.appwrite.endpoint) .setProject(config.appwrite.projectId) .setJWT(jwt) const account = new Account(client) const user = await account.get() if (!user || !user.$id) { throw new AuthenticationError('Ungültige Appwrite-Sitzung') } req.appwriteUser = { id: user.$id, email: user.email || '', name: user.name || '', } next() } catch (err) { if (err instanceof AuthenticationError) { next(err) return } next(new AuthenticationError(err.message || 'Invalid or expired session')) } })() } /** * Skip auth for email provider inbound webhooks only. */ export function requireAuthUnlessEmailWebhook(req, res, next) { const p = req.path || '' if (p === '/webhook/gmail' || p === '/webhook/outlook') { return next() } return requireAuth(req, res, next) }