| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177 | 'use strict'/* global lang, winston */const path = require('path')const Promise = require('bluebird')const fs = Promise.promisifyAll(require('fs-extra'))const multer = require('multer')const os = require('os')const _ = require('lodash')/** * Local Data Storage */module.exports = {  _uploadsPath: './repo/uploads',  _uploadsThumbsPath: './data/thumbs',  uploadImgHandler: null,  /**   * Initialize Local Data Storage model   *   * @return     {Object}  Local Data Storage model instance   */  init () {    this._uploadsPath = path.resolve(ROOTPATH, appconfig.paths.repo, 'uploads')    this._uploadsThumbsPath = path.resolve(ROOTPATH, appconfig.paths.data, 'thumbs')    this.createBaseDirectories(appconfig)    this.initMulter(appconfig)    return this  },  /**   * Init Multer upload handlers   *   * @param      {Object}   appconfig  The application config   * @return     {boolean}  Void   */  initMulter (appconfig) {    let maxFileSizes = {      img: appconfig.uploads.maxImageFileSize * 1024 * 1024,      file: appconfig.uploads.maxOtherFileSize * 1024 * 1024    }    // -> IMAGES    this.uploadImgHandler = multer({      storage: multer.diskStorage({        destination: (req, f, cb) => {          cb(null, path.resolve(ROOTPATH, appconfig.paths.data, 'temp-upload'))        }      }),      fileFilter: (req, f, cb) => {        // -> Check filesize        if (f.size > maxFileSizes.img) {          return cb(null, false)        }        // -> Check MIME type (quick check only)        if (!_.includes(['image/png', 'image/jpeg', 'image/gif', 'image/webp'], f.mimetype)) {          return cb(null, false)        }        cb(null, true)      }    }).array('imgfile', 20)    // -> FILES    this.uploadFileHandler = multer({      storage: multer.diskStorage({        destination: (req, f, cb) => {          cb(null, path.resolve(ROOTPATH, appconfig.paths.data, 'temp-upload'))        }      }),      fileFilter: (req, f, cb) => {        // -> Check filesize        if (f.size > maxFileSizes.file) {          return cb(null, false)        }        cb(null, true)      }    }).array('binfile', 20)    return true  },  /**   * Creates a base directories (Synchronous).   *   * @param      {Object}  appconfig  The application config   * @return     {Void}  Void   */  createBaseDirectories (appconfig) {    winston.info('Checking data directories...')    try {      fs.ensureDirSync(path.resolve(ROOTPATH, appconfig.paths.data))      fs.emptyDirSync(path.resolve(ROOTPATH, appconfig.paths.data))      fs.ensureDirSync(path.resolve(ROOTPATH, appconfig.paths.data, './cache'))      fs.ensureDirSync(path.resolve(ROOTPATH, appconfig.paths.data, './thumbs'))      fs.ensureDirSync(path.resolve(ROOTPATH, appconfig.paths.data, './temp-upload'))      if (os.type() !== 'Windows_NT') {        fs.chmodSync(path.resolve(ROOTPATH, appconfig.paths.data, './temp-upload'), '755')      }      fs.ensureDirSync(path.resolve(ROOTPATH, appconfig.paths.repo))      fs.ensureDirSync(path.resolve(ROOTPATH, appconfig.paths.repo, './uploads'))      if (os.type() !== 'Windows_NT') {        fs.chmodSync(path.resolve(ROOTPATH, appconfig.paths.repo, './uploads'), '755')      }    } catch (err) {      winston.error(err)    }    winston.info('Data and Repository directories are OK.')  },  /**   * Gets the uploads path.   *   * @return     {String}  The uploads path.   */  getUploadsPath () {    return this._uploadsPath  },  /**   * Gets the thumbnails folder path.   *   * @return     {String}  The thumbs path.   */  getThumbsPath () {    return this._uploadsThumbsPath  },  /**   * Check if filename is valid and unique   *   * @param      {String}           f        The filename   * @param      {String}           fld      The containing folder   * @param      {boolean}          isImage  Indicates if image   * @return     {Promise<String>}  Promise of the accepted filename   */  validateUploadsFilename (f, fld, isImage) {    let fObj = path.parse(f)    let fname = _.chain(fObj.name).trim().toLower().kebabCase().value().replace(new RegExp('[^a-z0-9-' + appdata.regex.cjk + appdata.regex.arabic + ']', 'g'), '')    let fext = _.toLower(fObj.ext)    if (isImage && !_.includes(['.jpg', '.jpeg', '.png', '.gif', '.webp'], fext)) {      fext = '.png'    }    f = fname + fext    let fpath = path.resolve(this._uploadsPath, fld, f)    return fs.statAsync(fpath).then((s) => {      throw new Error(lang.t('errors:fileexists', { path: f }))    }).catch((err) => {      if (err.code === 'ENOENT') {        return f      }      throw err    })  }}
 |