From a9561ef2f13a7f88d840835e795cc007082e79c3 Mon Sep 17 00:00:00 2001 From: Tran Tu Date: Mon, 9 Jan 2017 11:54:09 -0800 Subject: [PATCH] feat(plugin-board): support file contents --- packages/plugin-board/src/board.js | 51 ++++++++++++------- packages/plugin-board/src/realtime.js | 21 ++++---- .../test/integration/spec/board.js | 10 ++-- .../test/integration/spec/realtime.js | 7 ++- packages/plugin-board/test/unit/spec/board.js | 10 ++-- .../plugin-board/test/unit/spec/realtime.js | 6 ++- src/client/services/board/board.js | 2 +- 7 files changed, 68 insertions(+), 39 deletions(-) diff --git a/packages/plugin-board/src/board.js b/packages/plugin-board/src/board.js index 8d0a7ac3b28..8b8a9712ff5 100644 --- a/packages/plugin-board/src/board.js +++ b/packages/plugin-board/src/board.js @@ -46,10 +46,14 @@ const Board = SparkPlugin.extend({ addImage(channel, image) { return this.spark.board._uploadImage(channel, image) .then((scr) => this.spark.board.addContent(channel, [{ - mimeType: image.type, - size: image.size, + type: `FILE`, displayName: image.name, - scr + file: { + mimeType: image.type, + scr, + size: image.size, + url: scr.loc + } }])); }, @@ -135,7 +139,7 @@ const Board = SparkPlugin.extend({ let decryptPromise; if (content.type === `FILE`) { - decryptPromise = this.decryptSingleFileContent(content.encryptionKeyUrl, content.payload); + decryptPromise = this.decryptSingleFileContent(content.encryptionKeyUrl, content); } else { decryptPromise = this.decryptSingleContent(content.encryptionKeyUrl, content.payload); @@ -166,20 +170,24 @@ const Board = SparkPlugin.extend({ * Decryts a single FILE content object * @memberof Board.BoardService * @param {string} encryptionKeyUrl - * @param {string} encryptedData + * @param {object} encryptedContent {file, payload} * @returns {Promise} */ - decryptSingleFileContent(encryptionKeyUrl, encryptedData) { - const payload = JSON.parse(encryptedData); + decryptSingleFileContent(encryptionKeyUrl, encryptedContent) { + let metadata = {}; + + if (encryptedContent.payload) { + metadata = JSON.parse(encryptedContent.payload); + } - return this.spark.encryption.decryptScr(encryptionKeyUrl, payload.scr) + return this.spark.encryption.decryptScr(encryptionKeyUrl, encryptedContent.file.scr) .then((scr) => { - payload.scr = scr; - return this.spark.encryption.decryptText(encryptionKeyUrl, payload.displayName); + encryptedContent.file.scr = scr; + return this.spark.encryption.decryptText(encryptionKeyUrl, metadata.displayName); }) .then((displayName) => { - payload.displayName = displayName; - return payload; + encryptedContent.displayName = displayName; + return encryptedContent; }); }, @@ -225,7 +233,7 @@ const Board = SparkPlugin.extend({ let contentType = `STRING`; // the existence of an scr will determine if the content is a FILE. - if (content.scr) { + if (content.file) { contentType = `FILE`; encryptionPromise = this.encryptSingleFileContent(encryptionKeyUrl, content); } @@ -234,12 +242,14 @@ const Board = SparkPlugin.extend({ } return encryptionPromise - .then((res) => ({ + .then((res) => assign({ device: this.spark.device.deviceType, type: contentType, encryptionKeyUrl, payload: res.encryptedData - })); + }, + pick(res, `file`) + )); })); }, @@ -266,16 +276,19 @@ const Board = SparkPlugin.extend({ * @returns {Promise} */ encryptSingleFileContent(encryptionKeyUrl, content) { - return this.spark.encryption.encryptScr(encryptionKeyUrl, content.scr) + return this.spark.encryption.encryptScr(encryptionKeyUrl, content.file.scr) .then((encryptedScr) => { - content.scr = encryptedScr; + content.file.scr = encryptedScr; return this.spark.encryption.encryptText(encryptionKeyUrl, content.displayName); }) .then((encryptedDisplayName) => { - content.displayName = encryptedDisplayName; + const metadata = { + displayName: encryptedDisplayName + }; return { - encryptedData: JSON.stringify(content), + file: content.file, + encryptedData: JSON.stringify(metadata), encryptionKeyUrl }; }); diff --git a/packages/plugin-board/src/realtime.js b/packages/plugin-board/src/realtime.js index 046865f6b28..841e0694b51 100644 --- a/packages/plugin-board/src/realtime.js +++ b/packages/plugin-board/src/realtime.js @@ -37,7 +37,7 @@ const RealtimeService = Mercury.extend({ let encryptionPromise; let contentType = `STRING`; - if (message.payload.scr) { + if (message.payload.file) { contentType = `FILE`; encryptionPromise = this.spark.board.encryptSingleFileContent(channel.defaultEncryptionKeyUrl, message.payload); } @@ -46,20 +46,19 @@ const RealtimeService = Mercury.extend({ } return encryptionPromise - .then((encryptedPayloadAndKeyUrl) => this.publishEncrypted(encryptedPayloadAndKeyUrl.encryptionKeyUrl, encryptedPayloadAndKeyUrl.encryptedData, contentType)); + .then((encryptedPayloadAndKeyUrl) => this.publishEncrypted(encryptedPayloadAndKeyUrl, contentType)); }, /** * Sends the message via the socket. The message should already have been * encrypted * @memberof Board.RealtimeService - * @param {string} encryptionKeyUrl - * @param {string} encryptedData + * @param {object} encryptedPayloadAndKeyUrl * @param {string} contentType - provides hint for decryption. Defaults to * `STRING`, and could also be `FILE` * @returns {Promise} */ - publishEncrypted(encryptionKeyUrl, encryptedData, contentType) { + publishEncrypted(encryptedPayloadAndKeyUrl, contentType) { const bindings = this.spark.board.realtime.get(`boardBindings`); const data = { id: uuid.v4(), @@ -71,16 +70,20 @@ const RealtimeService = Mercury.extend({ }], data: { eventType: `board.activity`, - payload: encryptedData, + contentType, + payload: encryptedPayloadAndKeyUrl.encryptedData, envelope: { - encryptionKeyUrl + encryptionKeyUrl: encryptedPayloadAndKeyUrl.encryptionKeyUrl } } }; // provide a hint for decryption - if (contentType) { - data.data.contentType = contentType; + if (contentType === `FILE`) { + data.data.payload = { + file: encryptedPayloadAndKeyUrl.file, + payload: encryptedPayloadAndKeyUrl.encryptedData + }; } return this.socket.send(data); }, diff --git a/packages/plugin-board/test/integration/spec/board.js b/packages/plugin-board/test/integration/spec/board.js index fddde324178..4c45e1e1f62 100644 --- a/packages/plugin-board/test/integration/spec/board.js +++ b/packages/plugin-board/test/integration/spec/board.js @@ -143,7 +143,8 @@ describe(`plugin-board`, () => { assert.equal(testContent.type, `FILE`, `content type should be image`); assert.property(testContent, `contentUrl`, `content should contain contentId property`); assert.property(testContent, `channelUrl`, `content should contain contentUrl property`); - assert.property(testContent, `scr`, `content should contain scr property`); + assert.property(testContent, `file`, `content should contain file property`); + assert.property(testContent.file, `scr`, `content file should contain scr property`); }); }); @@ -152,10 +153,11 @@ describe(`plugin-board`, () => { .then((allContents) => { const imageContent = find(allContents.items, {contentId: testContent.contentId}); assert.isDefined(imageContent); - assert.property(imageContent, `scr`); + assert.property(imageContent, `file`); + assert.property(imageContent.file, `scr`); assert.equal(imageContent.displayName, `sample-image-small-one.png`); - testScr = imageContent.scr; - return imageContent.scr; + testScr = imageContent.file.scr; + return imageContent.file.scr; }); }); diff --git a/packages/plugin-board/test/integration/spec/realtime.js b/packages/plugin-board/test/integration/spec/realtime.js index 9e91ef5c72e..38cf6e23f94 100644 --- a/packages/plugin-board/test/integration/spec/realtime.js +++ b/packages/plugin-board/test/integration/spec/realtime.js @@ -159,7 +159,10 @@ describe(`plugin-board`, () => { }, payload: { displayName: `image.png`, - scr: testScr + type: `FILE`, + file: { + scr: testScr + } } }; @@ -167,7 +170,7 @@ describe(`plugin-board`, () => { // same data that was sent. participants[1].spark.board.realtime.once(`event:board.activity`, ({data}) => { assert.equal(data.contentType, `FILE`); - assert.equal(data.payload.scr.loc, testScr.loc); + assert.equal(data.payload.file.scr.loc, testScr.loc); assert.equal(data.payload.displayName, `image.png`); done(); }); diff --git a/packages/plugin-board/test/unit/spec/board.js b/packages/plugin-board/test/unit/spec/board.js index 6de7e142953..249adee56e6 100644 --- a/packages/plugin-board/test/unit/spec/board.js +++ b/packages/plugin-board/test/unit/spec/board.js @@ -366,8 +366,10 @@ describe(`plugin-board`, () => { const imageContents = [{ displayName: `FileName`, - scr: { - loc: fakeURL + file: { + scr: { + loc: fakeURL + } } }]; @@ -430,9 +432,11 @@ describe(`plugin-board`, () => { type: `FILE`, payload: JSON.stringify({ type: `image`, - scr: `encryptedScr`, displayName: `encryptedDisplayName` }), + file: { + scr: `encryptedScr` + }, encryptionKeyUrl: fakeURL }] }; diff --git a/packages/plugin-board/test/unit/spec/realtime.js b/packages/plugin-board/test/unit/spec/realtime.js index eba441b56b8..a4718c8f05b 100644 --- a/packages/plugin-board/test/unit/spec/realtime.js +++ b/packages/plugin-board/test/unit/spec/realtime.js @@ -96,7 +96,10 @@ describe(`plugin-board`, () => { beforeEach(() => { sinon.stub(uuid, `v4`).returns(`stubbedUUIDv4`); - return spark.board.realtime.publishEncrypted(`fakeURL`, `encryptedData`); + return spark.board.realtime.publishEncrypted({ + encryptedData: `encryptedData`, + encryptedKeyUrl: `fakeURL` + }, `STRING`); }); afterEach(() => { @@ -116,6 +119,7 @@ describe(`plugin-board`, () => { route: `binding` }], data: { + contentType: `STRING`, eventType: `board.activity`, envelope: { encryptionKeyUrl: `fakeURL` diff --git a/src/client/services/board/board.js b/src/client/services/board/board.js index a8c64f8872b..d611ee84aed 100644 --- a/src/client/services/board/board.js +++ b/src/client/services/board/board.js @@ -182,7 +182,7 @@ var BoardService = SparkBase.extend({ .then(function returnEncryptedContent(encryptedDisplayName) { var metadata = { displayName: encryptedDisplayName - } + }; return { file: content.file,