diff --git a/app/apollo/resolvers/channel.js b/app/apollo/resolvers/channel.js index 49d71cb7c..053680359 100644 --- a/app/apollo/resolvers/channel.js +++ b/app/apollo/resolvers/channel.js @@ -20,6 +20,8 @@ const crypto = require('crypto'); const conf = require('../../conf.js').conf; const S3ClientClass = require('../../s3/s3Client'); const { UserInputError, ValidationError } = require('apollo-server'); +const { WritableStreamBuffer } = require('stream-buffers'); +const stream = require('stream'); const { ACTIONS, TYPES } = require('../models/const'); const { whoIs, validAuth, NotFoundError} = require ('./common'); @@ -155,10 +157,11 @@ const channelResolvers = { throw err; } }, - addChannelVersion: async(parent, { org_id, channel_uuid, name, type, content, description }, context)=>{ + addChannelVersion: async(parent, { org_id, channel_uuid, name, type, content, file, description }, context)=>{ const { models, me, req_id, logger } = context; + const queryName = 'addChannelVersion'; - logger.debug({req_id, user: whoIs(me), org_id, channel_uuid, name, type, description }, `${queryName} enter`); + logger.debug({req_id, user: whoIs(me), org_id, channel_uuid, name, type, description, file }, `${queryName} enter`); await validAuth(me, org_id, ACTIONS.MANAGE, TYPES.CHANNEL, queryName, context); // slightly modified code from /app/routes/v1/channelsStream.js. changed to use mongoose and graphql @@ -174,6 +177,9 @@ const channelResolvers = { if(!channel_uuid){ throw 'channel_uuid not specified'; } + if(!file && !content){ + throw `Please specify either file or content`; + } const channel = await models.Channel.findOne({ uuid: channel_uuid, org_id }); if(!channel){ @@ -189,11 +195,21 @@ const channelResolvers = { throw new ValidationError(`The version name ${name} already exists`); } + //console.log(33333, file); + let fileStream = null; + if(file){ + fileStream = (await file).createReadStream(); + } + else{ + fileStream = stream.Readable.from([ content ]); + } + console.log(33334); + const iv = crypto.randomBytes(16); const ivText = iv.toString('base64'); let location = 'mongo'; - let data = await encryptOrgData(orgKey, content); + let data = null; if(conf.s3.endpoint){ const resourceName = `${channel.name}-${name}`; @@ -204,11 +220,28 @@ const channelResolvers = { await s3Client.ensureBucketExists(bucketName); //data is now the s3 hostpath to the resource - const result = await s3Client.encryptAndUploadFile(bucketName, resourceName, content, orgKey, iv); + const result = await s3Client.encryptAndUploadFile(bucketName, resourceName, fileStream, orgKey, iv); data = result.url; location = 's3'; } + else{ + var buf = new WritableStreamBuffer(); + await stream.pipeline( + fileStream, + buf, + (err)=>{ + if(err){ + resolve(err); + } + } + ); + const content = buf.getContents().toString('utf8'); + data = await encryptOrgData(orgKey, content); + } + + console.log(1111, data); + //return; const deployableVersionObj = { _id: UUID(), diff --git a/app/apollo/schema/channel.js b/app/apollo/schema/channel.js index 02482cca3..c8d9840b3 100644 --- a/app/apollo/schema/channel.js +++ b/app/apollo/schema/channel.js @@ -90,8 +90,9 @@ const channelSchema = gql` """ Adds a yaml version to this channel + Requires either content:String or file:Upload """ - addChannelVersion(org_id: String!, channel_uuid: String!, name: String!, type: String!, content: String!, description: String): AddChannelVersionReply! + addChannelVersion(org_id: String!, channel_uuid: String!, name: String!, type: String!, content: String, file: Upload, description: String): AddChannelVersionReply! """ Removes a channel diff --git a/app/s3/s3Client.js b/app/s3/s3Client.js index 46f759925..31bbcd1bb 100644 --- a/app/s3/s3Client.js +++ b/app/s3/s3Client.js @@ -133,7 +133,7 @@ module.exports = class S3Client { } } - async encryptAndUploadFile(bucketName, path, content, encryptionKey, iv=null){ + async encryptAndUploadFile(bucketName, path, fileStream, encryptionKey, iv=null){ try { const exists = await this.bucketExists(bucketName); if(!exists){ @@ -157,7 +157,7 @@ module.exports = class S3Client { const awsStream = this._aws.upload({ Bucket: bucketName, Key: path, - Body: stream.Readable.from(content).pipe(cipher), + Body: fileStream.pipe(cipher), }); await awsStream.promise();