This commit is contained in:
seb
2026-09-18 07:13:56 +02:00
parent 9e9d3154ca
commit bac6f2a801
3 changed files with 107 additions and 18 deletions

View File

@@ -1,7 +1,7 @@
import { createHash } from 'node:crypto';
import { LIST_BY_MANIFEST } from '../../sql/manifestattachment.js';
import request from '../request.js';
import generateDocumentThumb from '../../util/generateDocumentThumb.js';
import { parseMeta } from '../manifestattachment/listByManifestId.js';
const ALLOWED_MIMETYPES = new Set([
@@ -21,7 +21,9 @@ export function shapeAttachmentMeta(row) {
size: Number(row.size),
created: row.created,
modified: row.modified,
thumbavif: row.thumbavif ?? null,
thumbavif: row.thumbavif
? (Buffer.isBuffer(row.thumbavif) ? row.thumbavif.toString('base64') : row.thumbavif)
: null,
thumbx: row.thumbx ?? null,
thumby: row.thumby ?? null,
meta: parseMeta(row.meta),
@@ -88,6 +90,8 @@ function normalizeAttachment(raw, index) {
meta = {};
for (const [key, value] of Object.entries(raw.meta)) {
if (value === undefined || value === null) continue;
// The client shall not provide thumbnails; thumbs are strictly generated server-side.
if (key === 'thumbnail') continue;
meta[key] = String(value);
}
if (Object.keys(meta).length === 0) {
@@ -132,6 +136,9 @@ export async function insertAttachments(pool, tx, sql, manifestId, files) {
const sort = a.sort ?? nextSort;
nextSort = Math.max(nextSort, sort) + 1;
// Generate thumbnail server-side (e.g. pdftocairo + sharp for PDF)
const { thumbavif, thumbx, thumby } = await generateDocumentThumb(a.content, a.mimetype);
const fileRes = await request(pool, tx)
.input('hash', a.hash)
.input('mimetype', a.mimetype)
@@ -140,9 +147,9 @@ export async function insertAttachments(pool, tx, sql, manifestId, files) {
.input('created', a.created)
.input('modified', a.modified)
.input('content', a.content)
.input('thumbavif', null)
.input('thumbx', null)
.input('thumby', null)
.input('thumbavif', thumbavif)
.input('thumbx', thumbx)
.input('thumby', thumby)
.input('meta', a.meta === null ? null : JSON.stringify(a.meta))
.query(sql.CREATE_FILE);
@@ -164,6 +171,11 @@ export async function insertAttachments(pool, tx, sql, manifestId, files) {
size: a.size,
created: a.created,
modified: a.modified,
thumbavif: thumbavif
? (Buffer.isBuffer(thumbavif) ? thumbavif.toString('base64') : thumbavif)
: null,
thumbx: thumbx ?? null,
thumby: thumby ?? null,
meta: a.meta,
});
}

View File

@@ -1,5 +1,6 @@
import { createHash } from 'node:crypto';
import sharp from 'sharp';
import generateDocumentThumb from '../../util/generateDocumentThumb.js';
import {
CREATE_FILE,
CREATE_ATTACHMENT,
@@ -142,19 +143,10 @@ export default function add(pool) {
}
if (!thumbavif) {
try {
const thumbResult = await sharp(content)
.resize(200, 200, { fit: 'inside', withoutEnlargement: true })
.avif({ effort: 4 })
.toBuffer({ resolveWithObject: true });
thumbavif = thumbResult.data;
thumbx = thumbResult.info.width;
thumby = thumbResult.info.height;
} catch {
thumbavif = null;
thumbx = null;
thumby = null;
}
const generated = await generateDocumentThumb(content, mimetype);
thumbavif = generated.thumbavif;
thumbx = generated.thumbx;
thumby = generated.thumby;
}
const { companyId } = await access(googleAuthId);