fix(dev): Vite-API-Proxy, Auth, Stripe-Mails und Backend-Erweiterungen

- Client: API-Basis-URL (joinApiUrl, /v1-Falle), Vite strictPort + Proxy 127.0.0.1, Nicht-JSON-Fehler

- Server: /api-404 ohne Wildcard-Bug, SPA-Fallback, Auth-Middleware, Cron, Mailer, Crypto

- Routen: OAuth-State, Email/Stripe/Analytics; client/.env.example

Made-with: Cursor
This commit is contained in:
2026-04-03 00:23:01 +02:00
parent 61008b63bb
commit ecae89a79d
33 changed files with 1663 additions and 550 deletions

View File

@@ -4,6 +4,7 @@
*/
import { RateLimitError } from './errorHandler.mjs'
import { isAdmin } from '../config/index.mjs'
// In-memory store for rate limiting (use Redis in production)
const requestCounts = new Map()
@@ -25,6 +26,7 @@ setInterval(() => {
* @param {number} options.max - Max requests per window
* @param {string} options.message - Error message
* @param {Function} options.keyGenerator - Function to generate unique key
* @param {Function} options.skip - If (req) => true, do not count this request
*/
export function rateLimit(options = {}) {
const {
@@ -32,9 +34,14 @@ export function rateLimit(options = {}) {
max = 100,
message = 'Zu viele Anfragen. Bitte versuche es später erneut.',
keyGenerator = (req) => req.ip,
skip = () => false,
} = options
return (req, res, next) => {
if (skip(req)) {
return next()
}
const key = keyGenerator(req)
const now = Date.now()
@@ -80,11 +87,12 @@ export const limiters = {
message: 'Zu viele Anmeldeversuche. Bitte warte 15 Minuten.',
}),
// Limit for email sorting (expensive operation)
// Limit for email sorting (expensive operation); ADMIN_EMAILS (isAdmin) bypass
emailSort: rateLimit({
windowMs: 60000,
max: 30, // Erhöht für Entwicklung
message: 'E-Mail-Sortierung ist limitiert. Bitte warte eine Minute.',
skip: (req) => isAdmin(req.appwriteUser?.email),
}),
// Limit for AI operations