const _ = require('lodash') const sanitize = require('sanitize-filename') const graphHelper = require('../../helpers/graph') const assetHelper = require('../../helpers/asset') /* global WIKI */ module.exports = { Query: { async assets() { return {} } }, Mutation: { async assets() { return {} } }, AssetQuery: { async list(obj, args, context) { let cond = { folderId: args.folderId === 0 ? null : args.folderId } if (args.kind !== 'ALL') { cond.kind = args.kind.toLowerCase() } const folderHierarchy = await WIKI.models.assetFolders.getHierarchy(args.folderId) const folderPath = folderHierarchy.map(h => h.slug).join('/') const results = await WIKI.models.assets.query().where(cond) return _.filter(results, r => { const path = folderPath ? `${folderPath}/${r.filename}` : r.filename return WIKI.auth.checkAccess(context.req.user, ['read:assets'], { path }) }).map(a => ({ ...a, kind: a.kind.toUpperCase() })) }, async folders(obj, args, context) { const results = await WIKI.models.assetFolders.query().where({ parentId: args.parentFolderId === 0 ? null : args.parentFolderId }) const parentHierarchy = await WIKI.models.assetFolders.getHierarchy(args.parentFolderId) const parentPath = parentHierarchy.map(h => h.slug).join('/') return _.filter(results, r => { const path = parentPath ? `${parentPath}/${r.slug}` : r.slug return WIKI.auth.checkAccess(context.req.user, ['read:assets'], { path }) }) } }, AssetMutation: { /** * Create New Asset Folder */ async createFolder(obj, args, context) { try { const folderSlug = sanitize(args.slug).toLowerCase() const parentFolderId = args.parentFolderId === 0 ? null : args.parentFolderId const result = await WIKI.models.assetFolders.query().where({ parentId: parentFolderId, slug: folderSlug }).first() if (!result) { await WIKI.models.assetFolders.query().insert({ slug: folderSlug, name: folderSlug, parentId: parentFolderId }) return { responseResult: graphHelper.generateSuccess('Asset Folder has been created successfully.') } } else { throw new WIKI.Error.AssetFolderExists() } } catch (err) { return graphHelper.generateError(err) } }, /** * Rename an Asset */ async renameAsset(obj, args, context) { try { const filename = sanitize(args.filename).toLowerCase() const asset = await WIKI.models.assets.query().findById(args.id) if (asset) { // Check for extension mismatch if (!_.endsWith(filename, asset.ext)) { throw new WIKI.Error.AssetRenameInvalidExt() } // Check for non-dot files changing to dotfile if (asset.ext.length > 0 && filename.length - asset.ext.length < 1) { throw new WIKI.Error.AssetRenameInvalid() } // Check for collision const assetCollision = await WIKI.models.assets.query().where({ filename, folderId: asset.folderId }).first() if (assetCollision) { throw new WIKI.Error.AssetRenameCollision() } // Get asset folder path let hierarchy = [] if (asset.folderId) { hierarchy = await WIKI.models.assetFolders.getHierarchy(asset.folderId) } // Check source asset permissions const assetSourcePath = (asset.folderId) ? hierarchy.map(h => h.slug).join('/') + `/${asset.filename}` : asset.filename if (!WIKI.auth.checkAccess(context.req.user, ['manage:assets'], { path: assetSourcePath })) { throw new WIKI.Error.AssetRenameForbidden() } // Check target asset permissions const assetTargetPath = (asset.folderId) ? hierarchy.map(h => h.slug).join('/') + `/${filename}` : filename if (!WIKI.auth.checkAccess(context.req.user, ['write:assets'], { path: assetTargetPath })) { throw new WIKI.Error.AssetRenameTargetForbidden() } // Update filename + hash const fileHash = assetHelper.generateHash(assetTargetPath) await WIKI.models.assets.query().patch({ filename: filename, hash: fileHash }).findById(args.id) // Delete old asset cache await asset.deleteAssetCache() // Rename in Storage await WIKI.models.storage.assetEvent({ event: 'renamed', asset: { ...asset, path: assetSourcePath, destinationPath: assetTargetPath, moveAuthorId: context.req.user.id, moveAuthorName: context.req.user.name, moveAuthorEmail: context.req.user.email } }) return { responseResult: graphHelper.generateSuccess('Asset has been renamed successfully.') } } else { throw new WIKI.Error.AssetInvalid() } } catch (err) { return graphHelper.generateError(err) } }, /** * Delete an Asset */ async deleteAsset(obj, args, context) { try { const asset = await WIKI.models.assets.query().findById(args.id) if (asset) { // Check permissions const assetPath = await asset.getAssetPath() if (!WIKI.auth.checkAccess(context.req.user, ['manage:assets'], { path: assetPath })) { throw new WIKI.Error.AssetDeleteForbidden() } await WIKI.models.knex('assetData').where('id', args.id).del() await WIKI.models.assets.query().deleteById(args.id) await asset.deleteAssetCache() // Delete from Storage await WIKI.models.storage.assetEvent({ event: 'deleted', asset: { ...asset, path: assetPath, authorId: context.req.user.id, authorName: context.req.user.name, authorEmail: context.req.user.email } }) return { responseResult: graphHelper.generateSuccess('Asset has been deleted successfully.') } } else { throw new WIKI.Error.AssetInvalid() } } catch (err) { return graphHelper.generateError(err) } }, /** * Flush Temporary Uploads */ async flushTempUploads(obj, args, context) { try { await WIKI.models.assets.flushTempUploads() return { responseResult: graphHelper.generateSuccess('Temporary Uploads have been flushed successfully.') } } catch (err) { return graphHelper.generateError(err) } } } // File: { // folder(fl) { // return fl.getFolder() // } // } }