From a6c310b3abdb86d5c679f7b2625cd5253334f927 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sergio=20Guti=C3=A9rrez?= Date: Wed, 17 Jun 2026 16:44:22 +0200 Subject: [PATCH] feat(network): store and return HMAC in finishUpload and getDownloadLinks Accept optional hmac field in POST /v2/buckets/:id/files/finish and persist it on the BucketEntry document. Return it from GET /v2/buckets/:id/files/:file/mirrors so the client can verify file integrity on download. Omitted for existing files without HMAC. --- lib/core/bucketEntries/BucketEntry.ts | 1 + lib/core/buckets/usecase.ts | 10 ++++++---- lib/server/routes/buckets.js | 8 +++++--- 3 files changed, 12 insertions(+), 7 deletions(-) diff --git a/lib/core/bucketEntries/BucketEntry.ts b/lib/core/bucketEntries/BucketEntry.ts index 547c9fbe0..69d41a882 100644 --- a/lib/core/bucketEntries/BucketEntry.ts +++ b/lib/core/bucketEntries/BucketEntry.ts @@ -15,6 +15,7 @@ export interface BucketEntry { renewal?: Date; version?: number; size?: number; + hmac?: { type: 'sha512'; value: string }; } export interface BucketEntryWithFrame extends Omit { diff --git a/lib/core/buckets/usecase.ts b/lib/core/buckets/usecase.ts index 34ba46407..5530595c7 100644 --- a/lib/core/buckets/usecase.ts +++ b/lib/core/buckets/usecase.ts @@ -496,11 +496,12 @@ export class BucketsUsecase { } async completeUpload( - userId: User['uuid'], - bucketId: Bucket['id'], - fileIndex: string, + userId: User['uuid'], + bucketId: Bucket['id'], + fileIndex: string, shards: ShardWithPossibleMultiUpload[], - auth: { username: string; password: string } + auth: { username: string; password: string }, + hmac?: { type: 'sha512'; value: string } ): Promise { const [bucket, user, uploads] = await Promise.all([ this.bucketsRepository.findOne({ id: bucketId }), @@ -576,6 +577,7 @@ export class BucketsUsecase { index: fileIndex, version: 2, size: bucketEntrySize, + hmac, }); const [newBucketEntry, ...newShards] = await Promise.all([ diff --git a/lib/server/routes/buckets.js b/lib/server/routes/buckets.js index 0551241b8..b61661424 100644 --- a/lib/server/routes/buckets.js +++ b/lib/server/routes/buckets.js @@ -1268,7 +1268,7 @@ BucketsRouter.prototype.finishUpload = async function (req, res, next) { return next(new errors.BadRequestError('Missing parameters')); } - const { index, shards } = req.body; + const { index, shards, hmac } = req.body; if (!isHexString(index) || index.length !== 64) { return next(new errors.BadRequestError('Invalid index')); @@ -1302,7 +1302,8 @@ BucketsRouter.prototype.finishUpload = async function (req, res, next) { bucketId, index, shards, - auth + auth, + hmac ); await this.fileStateUsecase.updateOrSetLastAccessDate(bucketEntry.id) @@ -1407,7 +1408,8 @@ BucketsRouter.prototype.getDownloadLinks = async function (req, res, next) { bucket: bucketId, index: bucketEntry.index, created: bucketEntry.created, - shards: shardsWithoutUuid + shards: shardsWithoutUuid, + hmac: bucketEntry.hmac, }); };