|
|
@ -96,6 +96,7 @@ class ArchiveUserLocalJob extends SiteWorkerProcess { |
|
|
|
await this.archiveUserComments(job); |
|
|
|
await this.archiveUserStickers(job); |
|
|
|
await this.archiveUserImages(job); |
|
|
|
await this.archiveUserAttachments(job); |
|
|
|
|
|
|
|
/* |
|
|
|
* Create the .zip file archive, upload it to storage, and create the |
|
|
@ -119,7 +120,7 @@ class ArchiveUserLocalJob extends SiteWorkerProcess { |
|
|
|
}); |
|
|
|
// await User.deleteOne({ _id: job.data.userId });
|
|
|
|
} catch (error) { |
|
|
|
this.log.error('failed to delete attachment', { attachmentId: job.data.attachmentId, error }); |
|
|
|
this.log.error('failed to archive user', { userId: job.data.userId, error }); |
|
|
|
throw error; |
|
|
|
} finally { |
|
|
|
if (job.data.workPath) { |
|
|
@ -309,6 +310,71 @@ class ArchiveUserLocalJob extends SiteWorkerProcess { |
|
|
|
}); |
|
|
|
} |
|
|
|
|
|
|
|
async archiveUserAttachments (job) { |
|
|
|
const Attachment = mongoose.model('Attachment'); |
|
|
|
const { minio: minioService } = this.dtp.services; |
|
|
|
|
|
|
|
job.data.attachmentPath = path.join(job.data.workPath, 'attachments'); |
|
|
|
await fs.promises.mkdir(job.data.attachmentPath, { recursive: true }); |
|
|
|
|
|
|
|
job.data.originalAttachmentPath = path.join(job.data.attachmentPath, 'original'); |
|
|
|
await fs.promises.mkdir(job.data.originalAttachmentPath, { recursive: true }); |
|
|
|
|
|
|
|
job.data.encodedAttachmentPath = path.join(job.data.attachmentPath, 'encoded'); |
|
|
|
await fs.promises.mkdir(job.data.encodedAttachmentPath, { recursive: true }); |
|
|
|
|
|
|
|
this.log.info('archiving user attachments', { |
|
|
|
user: { |
|
|
|
_id: job.data.user._id, |
|
|
|
username: job.data.user.username, |
|
|
|
}, |
|
|
|
}); |
|
|
|
|
|
|
|
await Attachment |
|
|
|
.find({ owner: job.data.user._id }) |
|
|
|
.cursor() |
|
|
|
.eachAsync(async (attachment) => { |
|
|
|
try { |
|
|
|
/* |
|
|
|
* Write the JSON record archive |
|
|
|
*/ |
|
|
|
const metadataFilename = path.join(job.data.attachmentPath, `attachment-${attachment._id}.metadata.json`); |
|
|
|
await fs.promises.writeFile(metadataFilename, JSON.stringify(attachment, null, 2)); |
|
|
|
|
|
|
|
/* |
|
|
|
* Download and save the original file (if present) |
|
|
|
*/ |
|
|
|
if (attachment.original && attachment.original.bucket && attachment.original.key) { |
|
|
|
let originalExt = mime.getExtension(attachment.original.mime); |
|
|
|
const originalFilename = path.join(job.data.originalAttachmentPath, `attachment-${attachment._id}.${originalExt}`); |
|
|
|
await minioService.downloadFile({ |
|
|
|
bucket: attachment.original.bucket, |
|
|
|
key: attachment.original.key, |
|
|
|
filePath: originalFilename, |
|
|
|
}); |
|
|
|
} |
|
|
|
|
|
|
|
/* |
|
|
|
* Download and save the encoded file (if present) |
|
|
|
*/ |
|
|
|
if (attachment.encoded && attachment.encoded.bucket && attachment.encoded.key) { |
|
|
|
let encodedExt = mime.getExtension(attachment.encoded.mime); |
|
|
|
const encodedFilename = path.join(job.data.encodedAttachmentPath, `attachment-${attachment._id}.${encodedExt}`); |
|
|
|
await minioService.downloadFile({ |
|
|
|
bucket: attachment.encoded.bucket, |
|
|
|
key: attachment.encoded.key, |
|
|
|
filePath: encodedFilename, |
|
|
|
}); |
|
|
|
} |
|
|
|
} catch (error) { |
|
|
|
this.log.error('failed to archive attachment', { |
|
|
|
attachment: { _id: attachment._id }, |
|
|
|
error, |
|
|
|
}); |
|
|
|
} |
|
|
|
}); |
|
|
|
} |
|
|
|
|
|
|
|
async createArchiveFile (job) { |
|
|
|
const { minio: minioService } = this.dtp.services; |
|
|
|
try { |
|
|
|