import loggerFactory from '~/utils/logger'; // disable no-return-await for model functions /* eslint-disable no-return-await */ // eslint-disable-next-line no-unused-vars const path = require('path'); const mongoose = require('mongoose'); const uniqueValidator = require('mongoose-unique-validator'); const mongoosePaginate = require('mongoose-paginate-v2'); const { addSeconds } = require('date-fns'); // eslint-disable-next-line no-unused-vars const logger = loggerFactory('growi:models:attachment'); const ObjectId = mongoose.Schema.Types.ObjectId; module.exports = function(crowi) { function generateFileHash(fileName) { const hash = require('crypto').createHash('md5'); hash.update(`${fileName}_${Date.now()}`); return hash.digest('hex'); } const attachmentSchema = new mongoose.Schema({ page: { type: ObjectId, ref: 'Page', index: true }, creator: { type: ObjectId, ref: 'User', index: true }, filePath: { type: String }, // DEPRECATED: remains for backward compatibility for v3.3.x or below fileName: { type: String, required: true, unique: true }, originalName: { type: String }, fileFormat: { type: String, required: true }, fileSize: { type: Number, default: 0 }, createdAt: { type: Date, default: Date.now }, temporaryUrlCached: { type: String }, temporaryUrlExpiredAt: { type: Date }, }); attachmentSchema.plugin(uniqueValidator); attachmentSchema.plugin(mongoosePaginate); attachmentSchema.virtual('filePathProxied').get(function() { return `/attachment/${this._id}`; }); attachmentSchema.virtual('downloadPathProxied').get(function() { return `/download/${this._id}`; }); attachmentSchema.set('toObject', { virtuals: true }); attachmentSchema.set('toJSON', { virtuals: true }); attachmentSchema.statics.createWithoutSave = function(pageId, user, fileStream, originalName, fileFormat, fileSize) { const Attachment = this; const extname = path.extname(originalName); let fileName = generateFileHash(originalName); if (extname.length > 1) { // ignore if empty or '.' only fileName = `${fileName}${extname}`; } const attachment = new Attachment(); attachment.page = pageId; attachment.creator = user._id; attachment.originalName = originalName; attachment.fileName = fileName; attachment.fileFormat = fileFormat; attachment.fileSize = fileSize; attachment.createdAt = Date.now(); return attachment; }; attachmentSchema.methods.getValidTemporaryUrl = function() { if (this.temporaryUrlExpiredAt == null) { return null; } // return null when expired url if (this.temporaryUrlExpiredAt.getTime() < new Date().getTime()) { return null; } return this.temporaryUrlCached; }; attachmentSchema.methods.cashTemporaryUrlByProvideSec = function(temporaryUrl, provideSec) { if (temporaryUrl == null) { throw new Error('url is required.'); } this.temporaryUrlCached = temporaryUrl; this.temporaryUrlExpiredAt = addSeconds(new Date(), provideSec); return this.save(); }; return mongoose.model('Attachment', attachmentSchema); };