const map = require('lodash/map'); const filter = require('lodash/filter'); const resolvePath = require('resolve-path'); const fs = require('mz/fs'); class Upload { constructor(values) { var self = this; self.id = values.id || values._id || null; self.userId = values.userId || null; self.code = values.code || null; self.created = values.created || new Date(); self.expirationDate = values.expirationDate || null; self.files = values.files || []; } } class UploadRepository { constructor(store) { var self = this; self.store = store; } init() { var self = this; return new Promise((resolve, reject) => { // Initialize database if empty self.store.count({}, (err, count) => { if (err) { reject(err); return; } if (count == 0) self.addUser('admin', null, 'test', null); resolve(); }); }); } insert(userId, code, files, expirationDate) { var self = this; return new Promise((resolve, reject) => { var upload = { created: new Date(), userId: userId, code: code, expirationDate: expirationDate, files: map(filter(files, (file) => file.hasOwnProperty('id') && file.hasOwnProperty('name')), (file) => { return { id: file.id, name: file.name, size: file.size } }) }; if (upload.files.length) { self.store.insert(upload, (err, dbUpload) => { if (err) { reject(err); return; } resolve(dbUpload._id); }); } else { reject(); } }); } list(userId) { var self = this; return new Promise((resolve, reject) => { self.store.find(userId != null ? { userId: userId } : {}, (err, docs) => { if (err) { reject(err); return; } resolve(docs.map((dbUpload) => { return new Upload(dbUpload); })); }); }); } get(uploadId) { var self = this; return new Promise((resolve, reject) => { self.store.findOne({ _id: uploadId }, (err, doc) => { if (err) { reject(err); return; } resolve(doc !== null ? new Upload(doc) : null); }); }); } delete(uploadId) { var self = this; return new Promise((resolve, reject) => { self.store.findOne({ _id: uploadId }, (err, doc) => { if (err) { reject(err); return; } if (doc === null) { resolve(); return; } let upload = new Upload(doc); self.store.remove({ _id: uploadId }, async (err, numRemoved) => { if (err) { reject(err); return; } await Promise.all(upload.files.map(async (file) => { if (!file.id) return; if (!(await self.fileExists(file.id))) { var fullpath = resolvePath(config.fileUpload.path, file.id); try { await fs.unlink(fullpath); } catch (err) { console.log('Failed to delete ' + fullpath); } } })); resolve(); }); }); }); } fileExists(fileId) { var self = this; return new Promise((resolve, reject) => { self.store.findOne({ 'files.id': fileId }, (err, doc) => { if (err) { reject(err); return; } resolve(doc !== null); }); }); } } module.exports = { UploadRepository }