/ Backend / controllers / dapps-metadata-controller.js
dapps-metadata-controller.js
  1  const DAppMetadata = require('./../models/dapps-metadata-model')
  2  
  3  const TemplateParser = require('./../inputs/template-parser')
  4  const DAppsMetadataInputTemplates = require('./../inputs/templates/dapps-metadata')
  5  
  6  const IPFSService = require('./../services/ipfs-service')
  7  const DiscoverService = require('./../services/discover-service')
  8  const DAppImageService = require('./../services/dapp-image-service')
  9  const DAppMetadataService = require('./../services/dapp-metadata-service')
 10  
 11  const ApprovalEmail = require('./../emails/approval-email')
 12  const BadRequestError = require('./../errors/bad-request-error')
 13  
 14  const DAPP_METADATA_STATUSES = require('./../constants/dapp-metadata-statuses')
 15  
 16  const web3 = require('./../blockchain/web3')
 17  const logger = require('./../logger/logger').getLoggerFor(
 18    'DApps-Metadata-Controller',
 19  )
 20  
 21  class DAppsMetadataController {
 22    static async uploadDAppMetadata(req, res) {
 23      try {
 24        const parsedInput = TemplateParser.parse(
 25          req.body,
 26          DAppsMetadataInputTemplates.UploadingTemplate,
 27        )
 28  
 29        const uploadedMetadata = await DAppMetadataService.upload(
 30          req,
 31          parsedInput,
 32        )
 33  
 34        logger.info(
 35          `A dapp metadata with hash [${uploadedMetadata.hash}] has been uploaded successfully`,
 36        )
 37  
 38        res.status(200).json({ hash: uploadedMetadata.hash })
 39      } catch (error) {
 40        logger.error(error.message)
 41        throw new BadRequestError(error)
 42      }
 43    }
 44  
 45    static async sendApprovalEmail(req, res) {
 46      const dappMetadata = await DAppMetadata.findOne({ hash: req.params.hash })
 47  
 48      if (!dappMetadata) {
 49        return void res.status(404).send()
 50      }
 51  
 52      if (dappMetadata.status == DAPP_METADATA_STATUSES.NEW) {
 53        const approvalEmail = new ApprovalEmail(dappMetadata)
 54        approvalEmail.send()
 55      }
 56  
 57      res.status(200).send()
 58    }
 59  
 60    static async setMetadataStatus(req, res) {
 61      waitToBeMined(req.body.txHash, async () => {
 62        const dapp = await DiscoverService.retrieveDApp(req.params.dappId)
 63        const dappMetadata = await DAppMetadata.findByBytes32Hash(dapp.metadata)
 64        const initialDAppMetadata = await DAppMetadata.findOne({
 65          compressedMetadata: req.params.dappId,
 66        })
 67  
 68        if (
 69          dappMetadata &&
 70          initialDAppMetadata &&
 71          initialDAppMetadata.status != DAPP_METADATA_STATUSES.NEW
 72        ) {
 73          dappMetadata.status = DAPP_METADATA_STATUSES.APPROVED
 74          dappMetadata.compressedMetadata = initialDAppMetadata.compressedMetadata
 75          await dappMetadata.save()
 76  
 77          initialDAppMetadata.status = DAPP_METADATA_STATUSES.UPDATED
 78          await initialDAppMetadata.save()
 79        }
 80      })
 81  
 82      res.status(200).send()
 83    }
 84  
 85    static async getDAppMetadata(req, res) {
 86      try {
 87        const dappMetadata = await DAppMetadata.findOne({ hash: req.params.hash })
 88  
 89        if (dappMetadata) {
 90          return void res
 91            .status(200)
 92            .jsonCutSensitives(dappMetadata, ['_id', '__v'])
 93        }
 94  
 95        res.status(404).send()
 96      } catch (error) {
 97        logger.error(error.message)
 98        res.status(404).send()
 99      }
100    }
101  
102    static async getDAppImage(req, res) {
103      try {
104        const dappImage = await DAppImageService.retrieveImage(req.params.hash)
105        if (!dappImage) {
106          res.status(404).send()
107        }
108  
109        const imageBuffer = Buffer.from(dappImage.content, 'base64')
110  
111        /* allow for caching of images, since they are the bulk of requests */
112        res.set('Cache-Control', 'public, max-age=31557600')
113        res.set('Content-Type', 'image/png')
114        res.set('Content-Length', imageBuffer.length)
115        res.status(200)
116        return void res.end(imageBuffer)
117      } catch (error) {
118        logger.error(error.message)
119        res.status(404).send()
120      }
121    }
122  
123    static async getAllDappsMetadata(req, res) {
124      const dappsMetadata = await DAppMetadata.find()
125      const dappsFormatedMetadata = {}
126  
127      for (let i = 0; i < dappsMetadata.length; i++) {
128        const metadataHash = dappsMetadata[i].hash
129        dappsFormatedMetadata[metadataHash] = dappsMetadata[i]
130      }
131  
132      /* don't cache for longer than 60 seconds to show new dapps quicker */
133      res.set('Cache-Control', 'public, max-age=60')
134      res.status(200).json(dappsFormatedMetadata)
135    }
136  
137    static async approveDApp(req, res) {
138      const dappMetadata = await DAppMetadata.findOne({ hash: req.params.hash })
139  
140      if (dappMetadata) {
141        dappMetadata.status = DAPP_METADATA_STATUSES.APPROVED
142  
143        var json = JSON.stringify(dappMetadata.details);
144        dappMetadata.ipfsHash = await IPFSService.addContent(json)
145  
146        await dappMetadata.save()
147  
148        logger.info(`A dapp with hash [${dappMetadata.hash}] has been approved`)
149        return void res.status(200).send()
150      }
151  
152      res.status(404).send()
153    }
154  
155    static async rejectDApp(req, res) {
156      const dappMetadata = await DAppMetadata.findOne({ hash: req.params.hash })
157  
158      if (dappMetadata) {
159        await dappMetadata.remove()
160        return void res.status(200).send()
161      }
162  
163      res.status(404).send()
164    }
165  }
166  
167  const waitToBeMined = async function (txHash, callback) {
168    const updateMetadataTx = await web3.eth.getTransaction(txHash)
169  
170    if (!updateMetadataTx.blockNumber) {
171      setTimeout(() => {
172        waitToBeMined(txHash, callback)
173      }, 10000)
174    } else {
175      callback()
176    }
177  }
178  
179  module.exports = DAppsMetadataController