mirror of
https://github.com/toeverything/AFFiNE.git
synced 2026-07-22 20:46:38 +08:00
feat: improve attachment headers (#13709)
<!-- This is an auto-generated comment: release notes by coderabbit.ai --> ## Summary by CodeRabbit - **New Features** - Safer, consistent file downloads with automatic attachment headers and filenames. - Smarter MIME detection for uploads (avatars, workspace blobs, Copilot files/transcripts). - Sensible default buffer limit when reading uploads. - **Bug Fixes** - Prevents risky content from rendering inline by forcing downloads and adding no‑sniff protection. - More accurate content types when original metadata is missing or incorrect. <!-- end of auto-generated comment: release notes by coderabbit.ai -->
This commit is contained in:
@@ -31,6 +31,7 @@ import {
|
||||
EventBus,
|
||||
type FileUpload,
|
||||
RequestMutex,
|
||||
sniffMime,
|
||||
Throttle,
|
||||
TooManyRequest,
|
||||
UserFriendlyError,
|
||||
@@ -671,7 +672,11 @@ export class CopilotContextResolver {
|
||||
const { filename, mimetype } = content;
|
||||
|
||||
await this.storage.put(user.id, session.workspaceId, blobId, buffer);
|
||||
const file = await session.addFile(blobId, filename, mimetype);
|
||||
const file = await session.addFile(
|
||||
blobId,
|
||||
filename,
|
||||
sniffMime(buffer, mimetype) || mimetype
|
||||
);
|
||||
|
||||
await this.jobs.addFileEmbeddingQueue({
|
||||
userId: user.id,
|
||||
|
||||
@@ -32,6 +32,7 @@ import {
|
||||
} from 'rxjs';
|
||||
|
||||
import {
|
||||
applyAttachHeaders,
|
||||
BlobNotFound,
|
||||
CallMetric,
|
||||
Config,
|
||||
@@ -795,6 +796,10 @@ export class CopilotController implements BeforeApplicationShutdown {
|
||||
} else {
|
||||
this.logger.warn(`Blob ${workspaceId}/${key} has no metadata`);
|
||||
}
|
||||
applyAttachHeaders(res, {
|
||||
contentType: metadata?.contentType,
|
||||
filename: key,
|
||||
});
|
||||
|
||||
res.setHeader('cache-control', 'public, max-age=2592000, immutable');
|
||||
body.pipe(res);
|
||||
|
||||
@@ -30,6 +30,7 @@ import {
|
||||
Paginated,
|
||||
PaginationInput,
|
||||
RequestMutex,
|
||||
sniffMime,
|
||||
Throttle,
|
||||
TooManyRequest,
|
||||
UserFriendlyError,
|
||||
@@ -806,7 +807,10 @@ export class CopilotResolver {
|
||||
filename,
|
||||
uploaded.buffer
|
||||
);
|
||||
attachments.push({ attachment, mimeType: blob.mimetype });
|
||||
attachments.push({
|
||||
attachment,
|
||||
mimeType: sniffMime(uploaded.buffer, blob.mimetype) || blob.mimetype,
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -12,6 +12,7 @@ import {
|
||||
NoCopilotProviderAvailable,
|
||||
OnEvent,
|
||||
OnJob,
|
||||
sniffMime,
|
||||
} from '../../../base';
|
||||
import { Models } from '../../../models';
|
||||
import { PromptService } from '../prompt';
|
||||
@@ -85,7 +86,10 @@ export class CopilotTranscriptionService {
|
||||
`${blobId}-${idx}`,
|
||||
buffer
|
||||
);
|
||||
infos.push({ url, mimeType: blob.mimetype });
|
||||
infos.push({
|
||||
url,
|
||||
mimeType: sniffMime(buffer, blob.mimetype) || blob.mimetype,
|
||||
});
|
||||
}
|
||||
|
||||
const model = await this.getModel(userId);
|
||||
|
||||
@@ -2,7 +2,12 @@ import { createHash } from 'node:crypto';
|
||||
|
||||
import { Injectable, OnApplicationBootstrap } from '@nestjs/common';
|
||||
|
||||
import { FileUpload, JobQueue, PaginationInput } from '../../../base';
|
||||
import {
|
||||
FileUpload,
|
||||
JobQueue,
|
||||
PaginationInput,
|
||||
sniffMime,
|
||||
} from '../../../base';
|
||||
import { ServerFeature, ServerService } from '../../../core';
|
||||
import { Models } from '../../../models';
|
||||
import { CopilotStorage } from '../storage';
|
||||
@@ -64,7 +69,7 @@ export class CopilotWorkspaceService implements OnApplicationBootstrap {
|
||||
const file = await this.models.copilotWorkspace.addFile(workspaceId, {
|
||||
fileName,
|
||||
blobId,
|
||||
mimeType: content.mimetype,
|
||||
mimeType: sniffMime(buffer, content.mimetype) || content.mimetype,
|
||||
size: buffer.length,
|
||||
});
|
||||
return { blobId, file };
|
||||
|
||||
Reference in New Issue
Block a user