feat: add attachment analysis access links

This commit is contained in:
kris
2026-03-29 17:06:54 +08:00
parent 18dc7c6120
commit 88ab2d011a
7 changed files with 169 additions and 10 deletions

View File

@@ -4,30 +4,52 @@ import { Readable } from "node:stream";
import { NextRequest, NextResponse } from "next/server";
import { requireRequestSession } from "@/lib/boss-auth";
import { canSessionAccessAttachmentProject } from "@/lib/boss-attachment-access";
import { getAttachmentById, getAttachmentStorageConfig, readState } from "@/lib/boss-data";
import { getAttachmentById, getAttachmentStorageConfig, getMasterAgentTask, readState } from "@/lib/boss-data";
import { buildAttachmentDownloadHeaders } from "@/lib/boss-attachments";
import { getAliyunOssSignedDownloadUrl } from "@/lib/boss-storage-aliyun-oss";
import { resolveServerFileAttachmentAbsolutePath } from "@/lib/boss-storage-server-file";
export const runtime = "nodejs";
async function hasTaskTokenAccess(request: NextRequest, attachmentId: string) {
const taskId = request.nextUrl.searchParams.get("taskId")?.trim();
const token = request.nextUrl.searchParams.get("token")?.trim();
if (!taskId || !token) {
return false;
}
const task = await getMasterAgentTask(taskId);
if (!task || task.taskType !== "attachment_analysis") {
return false;
}
if (task.attachmentId !== attachmentId || task.attachmentDownloadToken !== token) {
return false;
}
if (!task.attachmentDownloadExpiresAt) {
return false;
}
return Date.parse(task.attachmentDownloadExpiresAt) > Date.now();
}
export async function GET(
request: NextRequest,
context: { params: Promise<{ attachmentId: string }> },
) {
const { attachmentId } = await context.params;
const session = await requireRequestSession(request);
if (!session) {
const taskTokenAccess = session ? false : await hasTaskTokenAccess(request, attachmentId);
if (!session && !taskTokenAccess) {
return NextResponse.json({ ok: false, message: "UNAUTHORIZED" }, { status: 401 });
}
const { attachmentId } = await context.params;
const record = await getAttachmentById(attachmentId);
if (!record) {
return NextResponse.json({ ok: false, message: "ATTACHMENT_NOT_FOUND" }, { status: 404 });
}
const state = await readState();
if (!canSessionAccessAttachmentProject(state, session, record.project)) {
return NextResponse.json({ ok: false, message: "FORBIDDEN" }, { status: 403 });
if (session) {
const state = await readState();
if (!canSessionAccessAttachmentProject(state, session, record.project)) {
return NextResponse.json({ ok: false, message: "FORBIDDEN" }, { status: 403 });
}
}
if (record.attachment.storageBackend === "aliyun_oss") {