storage.js 9.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231
  1. const _ = require('lodash')
  2. const graphHelper = require('../../helpers/graph')
  3. const { v4: uuid } = require('uuid')
  4. /* global WIKI */
  5. module.exports = {
  6. Query: {
  7. async storageTargets (obj, args, context, info) {
  8. const dbTargets = await WIKI.models.storage.getTargets({ siteId: args.siteId })
  9. // targets = _.sortBy(targets.map(tgt => {
  10. // const targetInfo = _.find(WIKI.data.storage, ['module', tgt.key]) || {}
  11. // return {
  12. // ...targetInfo,
  13. // ...tgt,
  14. // hasSchedule: (targetInfo.schedule !== false),
  15. // syncInterval: targetInfo.syncInterval || targetInfo.schedule || 'P0D',
  16. // syncIntervalDefault: targetInfo.schedule,
  17. // config: _.sortBy(_.transform(tgt.config, (res, value, key) => {
  18. // const configData = _.get(targetInfo.props, key, false)
  19. // if (configData) {
  20. // res.push({
  21. // key,
  22. // value: JSON.stringify({
  23. // ...configData,
  24. // value: (configData.sensitive && value.length > 0) ? '********' : value
  25. // })
  26. // })
  27. // }
  28. // }, []), 'key')
  29. // }
  30. // }), ['title', 'key'])
  31. return _.sortBy(WIKI.storage.defs.map(md => {
  32. const dbTarget = dbTargets.find(tg => tg.module === md.key)
  33. return {
  34. id: dbTarget?.id ?? uuid(),
  35. isEnabled: dbTarget?.isEnabled ?? false,
  36. module: md.key,
  37. title: md.title,
  38. description: md.description,
  39. icon: md.icon,
  40. banner: md.banner,
  41. vendor: md.vendor,
  42. website: md.website,
  43. contentTypes: {
  44. activeTypes: dbTarget?.contentTypes?.activeTypes ?? md.contentTypes.defaultTypesEnabled,
  45. largeThreshold: dbTarget?.contentTypes?.largeThreshold ?? md.contentTypes.defaultLargeThreshold
  46. },
  47. assetDelivery: {
  48. isStreamingSupported: md?.assetDelivery?.isStreamingSupported ?? false,
  49. isDirectAccessSupported: md?.assetDelivery?.isDirectAccessSupported ?? false,
  50. streaming: dbTarget?.assetDelivery?.streaming ?? md?.assetDelivery?.defaultStreamingEnabled ?? false,
  51. directAccess: dbTarget?.assetDelivery?.directAccess ?? md?.assetDelivery?.defaultDirectAccessEnabled ?? false
  52. },
  53. versioning: {
  54. isSupported: md?.versioning?.isSupported ?? false,
  55. isForceEnabled: md?.versioning?.isForceEnabled ?? false,
  56. enabled: dbTarget?.versioning?.enabled ?? md?.versioning?.defaultEnabled ?? false
  57. },
  58. sync: {},
  59. status: {},
  60. setup: {
  61. handler: md?.setup?.handler,
  62. state: dbTarget?.state?.setup ?? 'notconfigured',
  63. values: md.setup?.handler
  64. ? _.transform(md.setup.defaultValues,
  65. (r, v, k) => {
  66. r[k] = dbTarget?.config?.[k] ?? v
  67. }, {})
  68. : {}
  69. },
  70. config: _.transform(md.props, (r, v, k) => {
  71. const cfValue = dbTarget?.config?.[k] ?? v.default
  72. r[k] = {
  73. ...v,
  74. value: v.sensitive && cfValue ? '********' : cfValue,
  75. ...v.enum && {
  76. enum: v.enum.map(o => {
  77. if (o.indexOf('|') > 0) {
  78. const oParsed = o.split('|')
  79. return {
  80. value: oParsed[0],
  81. label: oParsed[1]
  82. }
  83. } else {
  84. return {
  85. value: o,
  86. label: o
  87. }
  88. }
  89. })
  90. }
  91. }
  92. }, {}),
  93. actions: md.actions
  94. }
  95. }), ['title'])
  96. }
  97. },
  98. Mutation: {
  99. async updateStorageTargets (obj, args, context) {
  100. WIKI.logger.debug(`Updating storage targets for site ${args.siteId}...`)
  101. try {
  102. const dbTargets = await WIKI.models.storage.getTargets({ siteId: args.siteId })
  103. for (const tgt of args.targets) {
  104. const md = _.find(WIKI.storage.defs, ['key', tgt.module])
  105. if (!md) {
  106. throw new Error('Invalid module key for non-existent storage target.')
  107. }
  108. const dbTarget = _.find(dbTargets, ['id', tgt.id])
  109. // -> Build update config object
  110. const updatedConfig = dbTarget?.config ?? {}
  111. if (tgt.config) {
  112. for (const [key, prop] of Object.entries(md.props)) {
  113. if (prop.readOnly) { continue }
  114. if (!Object.prototype.hasOwnProperty.call(tgt.config, key)) { continue }
  115. if (prop.sensitive && tgt.config[key] === '********') { continue }
  116. updatedConfig[key] = tgt.config[key]
  117. }
  118. }
  119. // -> Target doesn't exist yet in the DB, let's create it
  120. if (!dbTarget) {
  121. WIKI.logger.debug(`No existing DB configuration for module ${tgt.module}. Creating a new one...`)
  122. await WIKI.models.storage.query().insert({
  123. id: tgt.id,
  124. module: tgt.module,
  125. siteId: args.siteId,
  126. isEnabled: tgt.isEnabled ?? false,
  127. contentTypes: {
  128. activeTypes: tgt.contentTypes ?? md.contentTypes.defaultTypesEnabled ?? [],
  129. largeThreshold: tgt.largeThreshold ?? md.contentTypes.defaultLargeThreshold ?? '5MB'
  130. },
  131. assetDelivery: {
  132. streaming: tgt.assetDeliveryFileStreaming ?? md?.assetDelivery?.defaultStreamingEnabled ?? false,
  133. directAccess: tgt.assetDeliveryDirectAccess ?? md?.assetDelivery?.defaultDirectAccessEnabled ?? false
  134. },
  135. versioning: {
  136. enabled: tgt.useVersioning ?? md?.versioning?.defaultEnabled ?? false
  137. },
  138. state: {
  139. current: 'ok'
  140. },
  141. config: updatedConfig
  142. })
  143. } else {
  144. WIKI.logger.debug(`Updating DB configuration for module ${tgt.module}...`)
  145. await WIKI.models.storage.query().patch({
  146. isEnabled: tgt.isEnabled ?? dbTarget.isEnabled ?? false,
  147. contentTypes: {
  148. activeTypes: tgt.contentTypes ?? dbTarget?.contentTypes?.activeTypes ?? [],
  149. largeThreshold: tgt.largeThreshold ?? dbTarget?.contentTypes?.largeThreshold ?? '5MB'
  150. },
  151. assetDelivery: {
  152. streaming: tgt.assetDeliveryFileStreaming ?? dbTarget?.assetDelivery?.streaming ?? false,
  153. directAccess: tgt.assetDeliveryDirectAccess ?? dbTarget?.assetDelivery?.directAccess ?? false
  154. },
  155. versioning: {
  156. enabled: tgt.useVersioning ?? dbTarget?.versioning?.enabled ?? false
  157. },
  158. config: updatedConfig
  159. }).where('id', tgt.id)
  160. }
  161. }
  162. // await WIKI.models.storage.initTargets()
  163. return {
  164. status: graphHelper.generateSuccess('Storage targets updated successfully')
  165. }
  166. } catch (err) {
  167. return graphHelper.generateError(err)
  168. }
  169. },
  170. async setupStorageTarget (obj, args, context) {
  171. try {
  172. const tgt = await WIKI.models.storage.query().findById(args.targetId)
  173. if (!tgt) {
  174. throw new Error('Not storage target matching this ID')
  175. }
  176. const md = _.find(WIKI.storage.defs, ['key', tgt.module])
  177. if (!md) {
  178. throw new Error('No matching storage module installed.')
  179. }
  180. if (!await WIKI.models.storage.ensureModule(md.key)) {
  181. throw new Error('Failed to load storage module. Check logs for details.')
  182. }
  183. const result = await WIKI.storage.modules[md.key].setup(args.targetId, args.state)
  184. return {
  185. status: graphHelper.generateSuccess('Storage target setup step succeeded'),
  186. state: result
  187. }
  188. } catch (err) {
  189. return graphHelper.generateError(err)
  190. }
  191. },
  192. async destroyStorageTargetSetup (obj, args, context) {
  193. try {
  194. const tgt = await WIKI.models.storage.query().findById(args.targetId)
  195. if (!tgt) {
  196. throw new Error('Not storage target matching this ID')
  197. }
  198. const md = _.find(WIKI.storage.defs, ['key', tgt.module])
  199. if (!md) {
  200. throw new Error('No matching storage module installed.')
  201. }
  202. if (!await WIKI.models.storage.ensureModule(md.key)) {
  203. throw new Error('Failed to load storage module. Check logs for details.')
  204. }
  205. await WIKI.storage.modules[md.key].setupDestroy(args.targetId)
  206. return {
  207. status: graphHelper.generateSuccess('Storage target setup configuration destroyed succesfully.')
  208. }
  209. } catch (err) {
  210. return graphHelper.generateError(err)
  211. }
  212. },
  213. async executeStorageAction (obj, args, context) {
  214. try {
  215. await WIKI.models.storage.executeAction(args.targetKey, args.handler)
  216. return {
  217. status: graphHelper.generateSuccess('Action completed.')
  218. }
  219. } catch (err) {
  220. return graphHelper.generateError(err)
  221. }
  222. }
  223. }
  224. }