Fix broken images by proxying through the app instead of redirecting to internal MinIO
The presigned URLs pointed to a private IP unreachable from the browser. The image route now streams bytes directly and the card API returns proxy paths matching the dashboard's existing approach. Made-with: Cursor
This commit is contained in:
parent
72375d2fae
commit
58f38d92ed
2 changed files with 28 additions and 8 deletions
|
|
@ -1,6 +1,6 @@
|
||||||
import { NextRequest, NextResponse } from "next/server";
|
import { NextRequest, NextResponse } from "next/server";
|
||||||
import { prisma } from "@/lib/db";
|
import { prisma } from "@/lib/db";
|
||||||
import { getPresignedUrl, deleteObject } from "@/lib/minio";
|
import { deleteObject } from "@/lib/minio";
|
||||||
import { fireIntegrationEvent } from "@/lib/integrations";
|
import { fireIntegrationEvent } from "@/lib/integrations";
|
||||||
import { logActivity, diffCardFields } from "@/lib/activity-log";
|
import { logActivity, diffCardFields } from "@/lib/activity-log";
|
||||||
|
|
||||||
|
|
@ -18,10 +18,12 @@ export async function GET(
|
||||||
return NextResponse.json({ error: "Card not found" }, { status: 404 });
|
return NextResponse.json({ error: "Card not found" }, { status: 404 });
|
||||||
}
|
}
|
||||||
|
|
||||||
const [frontImageUrl, backImageUrl] = await Promise.all([
|
const frontImageUrl = card.frontImagePath
|
||||||
card.frontImagePath ? getPresignedUrl(card.frontImagePath) : null,
|
? `/api/images/${card.frontImagePath}`
|
||||||
card.backImagePath ? getPresignedUrl(card.backImagePath) : null,
|
: null;
|
||||||
]);
|
const backImageUrl = card.backImagePath
|
||||||
|
? `/api/images/${card.backImagePath}`
|
||||||
|
: null;
|
||||||
|
|
||||||
return NextResponse.json({
|
return NextResponse.json({
|
||||||
...card,
|
...card,
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,14 @@
|
||||||
import { NextRequest, NextResponse } from "next/server";
|
import { NextRequest, NextResponse } from "next/server";
|
||||||
import { getPresignedUrl } from "@/lib/minio";
|
import { getBuffer } from "@/lib/minio";
|
||||||
|
|
||||||
|
const EXT_TO_CONTENT_TYPE: Record<string, string> = {
|
||||||
|
jpg: "image/jpeg",
|
||||||
|
jpeg: "image/jpeg",
|
||||||
|
png: "image/png",
|
||||||
|
webp: "image/webp",
|
||||||
|
gif: "image/gif",
|
||||||
|
pdf: "application/pdf",
|
||||||
|
};
|
||||||
|
|
||||||
export async function GET(
|
export async function GET(
|
||||||
_request: NextRequest,
|
_request: NextRequest,
|
||||||
|
|
@ -13,8 +22,17 @@ export async function GET(
|
||||||
return NextResponse.json({ error: "Missing path" }, { status: 400 });
|
return NextResponse.json({ error: "Missing path" }, { status: 400 });
|
||||||
}
|
}
|
||||||
|
|
||||||
const url = await getPresignedUrl(key);
|
const ext = key.split(".").pop()?.toLowerCase() ?? "";
|
||||||
return NextResponse.redirect(url);
|
const contentType = EXT_TO_CONTENT_TYPE[ext] || "application/octet-stream";
|
||||||
|
|
||||||
|
const buffer = await getBuffer(key);
|
||||||
|
|
||||||
|
return new NextResponse(buffer, {
|
||||||
|
headers: {
|
||||||
|
"Content-Type": contentType,
|
||||||
|
"Cache-Control": "private, max-age=3600",
|
||||||
|
},
|
||||||
|
});
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.error("[images GET]", error);
|
console.error("[images GET]", error);
|
||||||
return NextResponse.json(
|
return NextResponse.json(
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue