2
0

asset.js 6.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203
  1. const _ = require('lodash')
  2. const sanitize = require('sanitize-filename')
  3. const graphHelper = require('../../helpers/graph')
  4. const assetHelper = require('../../helpers/asset')
  5. module.exports = {
  6. Query: {
  7. async assets(obj, args, context) {
  8. let cond = {
  9. folderId: args.folderId === 0 ? null : args.folderId
  10. }
  11. if (args.kind !== 'ALL') {
  12. cond.kind = args.kind.toLowerCase()
  13. }
  14. const folderHierarchy = await WIKI.db.assetFolders.getHierarchy(args.folderId)
  15. const folderPath = folderHierarchy.map(h => h.slug).join('/')
  16. const results = await WIKI.db.assets.query().where(cond)
  17. return _.filter(results, r => {
  18. const path = folderPath ? `${folderPath}/${r.filename}` : r.filename
  19. return WIKI.auth.checkAccess(context.req.user, ['read:assets'], { path })
  20. }).map(a => ({
  21. ...a,
  22. kind: a.kind.toUpperCase()
  23. }))
  24. },
  25. async assetsFolders(obj, args, context) {
  26. const results = await WIKI.db.assetFolders.query().where({
  27. parentId: args.parentFolderId === 0 ? null : args.parentFolderId
  28. })
  29. const parentHierarchy = await WIKI.db.assetFolders.getHierarchy(args.parentFolderId)
  30. const parentPath = parentHierarchy.map(h => h.slug).join('/')
  31. return _.filter(results, r => {
  32. const path = parentPath ? `${parentPath}/${r.slug}` : r.slug
  33. return WIKI.auth.checkAccess(context.req.user, ['read:assets'], { path })
  34. })
  35. }
  36. },
  37. Mutation: {
  38. /**
  39. * Create New Asset Folder
  40. */
  41. async createAssetsFolder(obj, args, context) {
  42. try {
  43. const folderSlug = sanitize(args.slug).toLowerCase()
  44. const parentFolderId = args.parentFolderId === 0 ? null : args.parentFolderId
  45. const result = await WIKI.db.assetFolders.query().where({
  46. parentId: parentFolderId,
  47. slug: folderSlug
  48. }).first()
  49. if (!result) {
  50. await WIKI.db.assetFolders.query().insert({
  51. slug: folderSlug,
  52. name: folderSlug,
  53. parentId: parentFolderId
  54. })
  55. return {
  56. responseResult: graphHelper.generateSuccess('Asset Folder has been created successfully.')
  57. }
  58. } else {
  59. throw new WIKI.Error.AssetFolderExists()
  60. }
  61. } catch (err) {
  62. return graphHelper.generateError(err)
  63. }
  64. },
  65. /**
  66. * Rename an Asset
  67. */
  68. async renameAsset(obj, args, context) {
  69. try {
  70. const filename = sanitize(args.filename).toLowerCase()
  71. const asset = await WIKI.db.assets.query().findById(args.id)
  72. if (asset) {
  73. // Check for extension mismatch
  74. if (!_.endsWith(filename, asset.ext)) {
  75. throw new WIKI.Error.AssetRenameInvalidExt()
  76. }
  77. // Check for non-dot files changing to dotfile
  78. if (asset.ext.length > 0 && filename.length - asset.ext.length < 1) {
  79. throw new WIKI.Error.AssetRenameInvalid()
  80. }
  81. // Check for collision
  82. const assetCollision = await WIKI.db.assets.query().where({
  83. filename,
  84. folderId: asset.folderId
  85. }).first()
  86. if (assetCollision) {
  87. throw new WIKI.Error.AssetRenameCollision()
  88. }
  89. // Get asset folder path
  90. let hierarchy = []
  91. if (asset.folderId) {
  92. hierarchy = await WIKI.db.assetFolders.getHierarchy(asset.folderId)
  93. }
  94. // Check source asset permissions
  95. const assetSourcePath = (asset.folderId) ? hierarchy.map(h => h.slug).join('/') + `/${asset.filename}` : asset.filename
  96. if (!WIKI.auth.checkAccess(context.req.user, ['manage:assets'], { path: assetSourcePath })) {
  97. throw new WIKI.Error.AssetRenameForbidden()
  98. }
  99. // Check target asset permissions
  100. const assetTargetPath = (asset.folderId) ? hierarchy.map(h => h.slug).join('/') + `/${filename}` : filename
  101. if (!WIKI.auth.checkAccess(context.req.user, ['write:assets'], { path: assetTargetPath })) {
  102. throw new WIKI.Error.AssetRenameTargetForbidden()
  103. }
  104. // Update filename + hash
  105. const fileHash = assetHelper.generateHash(assetTargetPath)
  106. await WIKI.db.assets.query().patch({
  107. filename: filename,
  108. hash: fileHash
  109. }).findById(args.id)
  110. // Delete old asset cache
  111. await asset.deleteAssetCache()
  112. // Rename in Storage
  113. await WIKI.db.storage.assetEvent({
  114. event: 'renamed',
  115. asset: {
  116. ...asset,
  117. path: assetSourcePath,
  118. destinationPath: assetTargetPath,
  119. moveAuthorId: context.req.user.id,
  120. moveAuthorName: context.req.user.name,
  121. moveAuthorEmail: context.req.user.email
  122. }
  123. })
  124. return {
  125. responseResult: graphHelper.generateSuccess('Asset has been renamed successfully.')
  126. }
  127. } else {
  128. throw new WIKI.Error.AssetInvalid()
  129. }
  130. } catch (err) {
  131. return graphHelper.generateError(err)
  132. }
  133. },
  134. /**
  135. * Delete an Asset
  136. */
  137. async deleteAsset(obj, args, context) {
  138. try {
  139. const asset = await WIKI.db.assets.query().findById(args.id)
  140. if (asset) {
  141. // Check permissions
  142. const assetPath = await asset.getAssetPath()
  143. if (!WIKI.auth.checkAccess(context.req.user, ['manage:assets'], { path: assetPath })) {
  144. throw new WIKI.Error.AssetDeleteForbidden()
  145. }
  146. await WIKI.db.knex('assetData').where('id', args.id).del()
  147. await WIKI.db.assets.query().deleteById(args.id)
  148. await asset.deleteAssetCache()
  149. // Delete from Storage
  150. await WIKI.db.storage.assetEvent({
  151. event: 'deleted',
  152. asset: {
  153. ...asset,
  154. path: assetPath,
  155. authorId: context.req.user.id,
  156. authorName: context.req.user.name,
  157. authorEmail: context.req.user.email
  158. }
  159. })
  160. return {
  161. responseResult: graphHelper.generateSuccess('Asset has been deleted successfully.')
  162. }
  163. } else {
  164. throw new WIKI.Error.AssetInvalid()
  165. }
  166. } catch (err) {
  167. return graphHelper.generateError(err)
  168. }
  169. },
  170. /**
  171. * Flush Temporary Uploads
  172. */
  173. async flushTempUploads(obj, args, context) {
  174. try {
  175. await WIKI.db.assets.flushTempUploads()
  176. return {
  177. responseResult: graphHelper.generateSuccess('Temporary Uploads have been flushed successfully.')
  178. }
  179. } catch (err) {
  180. return graphHelper.generateError(err)
  181. }
  182. }
  183. }
  184. // File: {
  185. // folder(fl) {
  186. // return fl.getFolder()
  187. // }
  188. // }
  189. }