storage.js 9.1 KB

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