Skip to content

Commit

Permalink
on attachment upload calculate file content hash
Browse files Browse the repository at this point in the history
  • Loading branch information
NickOvt committed Sep 13, 2024
1 parent ceeacc7 commit 6a9bae9
Showing 1 changed file with 66 additions and 2 deletions.
68 changes: 66 additions & 2 deletions lib/attachments/gridstore-storage.js
Original file line number Diff line number Diff line change
Expand Up @@ -7,13 +7,48 @@ const errors = require('../errors');
const log = require('npmlog');
const crypto = require('crypto');
const base64Offset = require('./base64-offset');
const Transform = require('stream').Transform;

// Set to false to disable base64 decoding feature
const FEATURE_DECODE_ATTACHMENTS = true;

const ORPHANED_ATTACHMENTS_DELAY = 24 * 3600 * 1000;
const MAX_ORPHANED_ATTACHMENTS = 1000;

class FileHashCalculator extends Transform {
constructor(options) {
super(options);
this.bodyHash = crypto.createHash('sha256');
this.hash = null;
}

updateHash(chunk) {
this.bodyHash.update(chunk);
}

_transform(chunk, encoding, callback) {
if (!chunk || !chunk.length) {
return callback();
}

if (typeof chunk === 'string') {
chunk = Buffer.from(chunk, encoding);
}

this.updateHash(chunk);
this.push(chunk);

callback();
}

_flush(done) {
this.hash = this.bodyHash.digest('base64');
done();
}
}

let fileHashCalculator = new FileHashCalculator();

class GridstoreStorage {
constructor(options) {
this.bucketName = (options.options && options.options.bucket) || 'attachments';
Expand Down Expand Up @@ -129,6 +164,35 @@ class GridstoreStorage {
let storeLock;

let attachmentCallback = (...args) => {
// store finished uploading, add the hash of the file contents to file metadata
if (args.length > 2) {
const calculatedFileContentHash = args[2];

this.gridfs.collection(this.bucketName + '.files').findOneAndUpdate(
{
_id: hash
},
{
$set: {
'metadata.fileContentHash': calculatedFileContentHash
}
},
{
returnDocument: 'after'
},
(err, res) => {
if (err) {
return attachmentCallback(err);
}

if (res && res.value && res.value.metadata.fileContentHash && res.value.metadata.fileContentHash === calculatedFileContentHash) {
// all good?
// do nothing
}
}
);
}

if (storeLock) {
log.silly('GridStore', '[%s] UNLOCK lock=%s status=%s', instance, lockId, storeLock.success ? 'locked' : 'empty');
if (storeLock.success) {
Expand Down Expand Up @@ -282,13 +346,13 @@ class GridstoreStorage {
attachmentCallback(err);
});

store.once('finish', () => attachmentCallback(null, id));
store.once('finish', () => attachmentCallback(null, id, fileHashCalculator.hash));

if (!metadata.decoded) {
store.end(attachment.body);
} else {
let decoder = new libbase64.Decoder();
decoder.pipe(store);
decoder.pipe(fileHashCalculator).pipe(store);
decoder.once('error', err => {
// pass error forward
store.emit('error', err);
Expand Down

0 comments on commit 6a9bae9

Please sign in to comment.