Skip to content

Commit

Permalink
feat(plugin-board): support file contents
Browse files Browse the repository at this point in the history
  • Loading branch information
tran2 committed Jan 23, 2017
1 parent 66b1795 commit a9561ef
Show file tree
Hide file tree
Showing 7 changed files with 68 additions and 39 deletions.
51 changes: 32 additions & 19 deletions packages/plugin-board/src/board.js
Expand Up @@ -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
}
}]));
},

Expand Down Expand Up @@ -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);
Expand Down Expand Up @@ -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<Board~Content>}
*/
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;
});
},

Expand Down Expand Up @@ -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);
}
Expand All @@ -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`)
));
}));
},

Expand All @@ -266,16 +276,19 @@ const Board = SparkPlugin.extend({
* @returns {Promise<Board~Content>}
*/
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
};
});
Expand Down
21 changes: 12 additions & 9 deletions packages/plugin-board/src/realtime.js
Expand Up @@ -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);
}
Expand All @@ -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<Board~Content>}
*/
publishEncrypted(encryptionKeyUrl, encryptedData, contentType) {
publishEncrypted(encryptedPayloadAndKeyUrl, contentType) {
const bindings = this.spark.board.realtime.get(`boardBindings`);
const data = {
id: uuid.v4(),
Expand All @@ -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);
},
Expand Down
10 changes: 6 additions & 4 deletions packages/plugin-board/test/integration/spec/board.js
Expand Up @@ -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`);
});
});

Expand All @@ -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;
});
});

Expand Down
7 changes: 5 additions & 2 deletions packages/plugin-board/test/integration/spec/realtime.js
Expand Up @@ -159,15 +159,18 @@ describe(`plugin-board`, () => {
},
payload: {
displayName: `image.png`,
scr: testScr
type: `FILE`,
file: {
scr: testScr
}
}
};

// participant 1 is going to listen for RT data and confirm that we have the
// 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();
});
Expand Down
10 changes: 7 additions & 3 deletions packages/plugin-board/test/unit/spec/board.js
Expand Up @@ -366,8 +366,10 @@ describe(`plugin-board`, () => {

const imageContents = [{
displayName: `FileName`,
scr: {
loc: fakeURL
file: {
scr: {
loc: fakeURL
}
}
}];

Expand Down Expand Up @@ -430,9 +432,11 @@ describe(`plugin-board`, () => {
type: `FILE`,
payload: JSON.stringify({
type: `image`,
scr: `encryptedScr`,
displayName: `encryptedDisplayName`
}),
file: {
scr: `encryptedScr`
},
encryptionKeyUrl: fakeURL
}]
};
Expand Down
6 changes: 5 additions & 1 deletion packages/plugin-board/test/unit/spec/realtime.js
Expand Up @@ -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(() => {
Expand All @@ -116,6 +119,7 @@ describe(`plugin-board`, () => {
route: `binding`
}],
data: {
contentType: `STRING`,
eventType: `board.activity`,
envelope: {
encryptionKeyUrl: `fakeURL`
Expand Down
2 changes: 1 addition & 1 deletion src/client/services/board/board.js
Expand Up @@ -182,7 +182,7 @@ var BoardService = SparkBase.extend({
.then(function returnEncryptedContent(encryptedDisplayName) {
var metadata = {
displayName: encryptedDisplayName
}
};

return {
file: content.file,
Expand Down

0 comments on commit a9561ef

Please sign in to comment.