E-Mail Anhang-Download CORS absichern

KI-AGENT: OPTIONS-Preflights werden nicht mehr durch den Auth-Hook blockiert und der E-Mail Anhang-Download setzt CORS-Header auch für Fehlerantworten explizit.
This commit is contained in:
2026-05-23 21:02:45 +02:00
parent 2c96b9c5a5
commit a34bf43756
2 changed files with 25 additions and 0 deletions

View File

@@ -64,6 +64,10 @@ export default fp(async (server: FastifyInstance) => {
} }
server.addHook("preHandler", async (req, reply) => { server.addHook("preHandler", async (req, reply) => {
if (req.method === "OPTIONS") {
return
}
// 1⃣ Token aus Header oder Cookie lesen // 1⃣ Token aus Header oder Cookie lesen
const cookieToken = req.cookies?.token const cookieToken = req.cookies?.token
const authHeader = req.headers.authorization const authHeader = req.headers.authorization

View File

@@ -39,6 +39,25 @@ export default async function emailAsUserRoutes(server: FastifyInstance) {
const bodyValue = (body: any, camelKey: string, snakeKey: string) => body[camelKey] ?? body[snakeKey] const bodyValue = (body: any, camelKey: string, snakeKey: string) => body[camelKey] ?? body[snakeKey]
const applyDownloadCorsHeaders = (req: any, reply: any) => {
const origin = req.headers.origin
if (
origin
&& (
/^http:\/\/(localhost|127\.0\.0\.1):\d+$/.test(origin)
|| origin === "https://beta.fedeo.de"
|| origin === "https://app.fedeo.de"
|| origin === "capacitor://localhost"
)
) {
reply.header("Access-Control-Allow-Origin", origin)
reply.header("Access-Control-Allow-Credentials", "true")
reply.header("Vary", "Origin")
}
reply.header("Access-Control-Expose-Headers", "Authorization, Content-Disposition, Content-Type, Content-Length")
}
const accountWhere = (tenantId: number, userId: string, id?: string) => { const accountWhere = (tenantId: number, userId: string, id?: string) => {
const conditions = [ const conditions = [
eq(userCredentials.tenantId, tenantId), eq(userCredentials.tenantId, tenantId),
@@ -456,6 +475,8 @@ export default async function emailAsUserRoutes(server: FastifyInstance) {
}) })
server.get("/email/attachments/:id/download", async (req, reply) => { server.get("/email/attachments/:id/download", async (req, reply) => {
applyDownloadCorsHeaders(req, reply)
try { try {
if (!req.user?.tenant_id) { if (!req.user?.tenant_id) {
return reply.code(400).send({ error: "No tenant selected" }) return reply.code(400).send({ error: "No tenant selected" })