fix: harden attachment analysis delivery

This commit is contained in:
kris
2026-03-29 17:10:58 +08:00
parent 88ab2d011a
commit 5fb75b50b4
7 changed files with 111 additions and 12 deletions

View File

@@ -53,14 +53,30 @@ export async function GET(
}
if (record.attachment.storageBackend === "aliyun_oss") {
const storageConfig = await getAttachmentStorageConfig(record.attachment.uploadedBy);
if (storageConfig.mode !== "oss" || storageConfig.ossProvider !== "aliyun_oss" || !storageConfig.aliyunOss) {
const aliyunConfig =
record.attachment.storageSnapshot?.provider === "aliyun_oss"
? {
enabled: true,
accessKeyId: record.attachment.storageSnapshot.accessKeyId,
accessKeySecretEncrypted: record.attachment.storageSnapshot.accessKeySecretEncrypted,
bucket: record.attachment.storageSnapshot.bucket,
endpoint: record.attachment.storageSnapshot.endpoint,
region: record.attachment.storageSnapshot.region,
prefix: record.attachment.storageSnapshot.prefix,
}
: null;
const storageConfig = aliyunConfig ? null : await getAttachmentStorageConfig(record.attachment.uploadedBy);
const resolvedConfig =
aliyunConfig ??
(storageConfig?.mode === "oss" &&
storageConfig.ossProvider === "aliyun_oss" &&
storageConfig.aliyunOss
? storageConfig.aliyunOss
: null);
if (!resolvedConfig) {
return NextResponse.json({ ok: false, message: "ATTACHMENT_STORAGE_CONFIG_NOT_FOUND" }, { status: 404 });
}
const signedUrl = await getAliyunOssSignedDownloadUrl(
storageConfig.aliyunOss,
record.attachment.storagePath,
);
const signedUrl = await getAliyunOssSignedDownloadUrl(resolvedConfig, record.attachment.storagePath);
return NextResponse.redirect(signedUrl, {
status: 307,
headers: buildAttachmentDownloadHeaders(record.attachment),

View File

@@ -6,6 +6,13 @@ import { queueAttachmentAnalysisTask } from "@/lib/boss-master-agent";
export const runtime = "nodejs";
function resolveRequestPublicBaseUrl(request: NextRequest) {
const protocol =
request.headers.get("x-forwarded-proto") ?? request.nextUrl.protocol.replace(/:$/, "") ?? "http";
const host = request.headers.get("x-forwarded-host") ?? request.headers.get("host") ?? request.nextUrl.host;
return `${protocol}://${host}`;
}
export async function POST(
request: NextRequest,
context: { params: Promise<{ projectId: string; attachmentId: string }> },
@@ -45,6 +52,7 @@ export async function POST(
requestedBy: session.displayName || "你",
requestedByAccount: session.account,
markProcessing: true,
publicBaseUrl: resolveRequestPublicBaseUrl(request),
});
return NextResponse.json({ ok: true, taskId: task.taskId, task });

View File

@@ -18,6 +18,13 @@ function randomToken(prefix: string) {
return `${prefix}-${randomBytes(4).toString("hex")}`;
}
function resolveRequestPublicBaseUrl(request: NextRequest) {
const protocol =
request.headers.get("x-forwarded-proto") ?? request.nextUrl.protocol.replace(/:$/, "") ?? "http";
const host = request.headers.get("x-forwarded-host") ?? request.headers.get("host") ?? request.nextUrl.host;
return `${protocol}://${host}`;
}
export async function POST(
request: NextRequest,
context: { params: Promise<{ projectId: string }> },
@@ -69,6 +76,21 @@ export async function POST(
attachmentKind,
storageBackend: stored.storageBackend,
storagePath: stored.storagePath,
storageSnapshot:
stored.storageBackend === "aliyun_oss" &&
storageConfig.mode === "oss" &&
storageConfig.ossProvider === "aliyun_oss" &&
storageConfig.aliyunOss
? {
provider: "aliyun_oss",
accessKeyId: storageConfig.aliyunOss.accessKeyId,
accessKeySecretEncrypted: storageConfig.aliyunOss.accessKeySecretEncrypted,
bucket: storageConfig.aliyunOss.bucket,
endpoint: storageConfig.aliyunOss.endpoint,
region: storageConfig.aliyunOss.region,
prefix: storageConfig.aliyunOss.prefix,
}
: undefined,
previewAvailable: attachmentKind === "image" || attachmentKind === "video" || attachmentKind === "pdf",
uploadedAt: new Date().toISOString(),
uploadedBy: session.account,
@@ -90,6 +112,7 @@ export async function POST(
requestMessageId: message.id,
requestedBy: session.displayName || "你",
requestedByAccount: session.account,
publicBaseUrl: resolveRequestPublicBaseUrl(request),
});
}