Bringing together all the stuff for attachments and link previews

pull/566/head
Beaudan Brown 6 years ago
parent 9114a3bc03
commit 638f1c0e6c

@ -648,7 +648,13 @@ class LokiPublicChannelAPI {
} }
} }
static getSigData(sigVer, noteValue, adnMessage) { static getSigData(
sigVer,
noteValue,
attachmentAnnotations,
previewAnnotations,
adnMessage
) {
let sigString = ''; let sigString = '';
sigString += adnMessage.text.trim(); sigString += adnMessage.text.trim();
sigString += noteValue.timestamp; sigString += noteValue.timestamp;
@ -660,6 +666,12 @@ class LokiPublicChannelAPI {
sigString += adnMessage.reply_to; sigString += adnMessage.reply_to;
} }
} }
attachmentAnnotations
.concat(previewAnnotations)
.map(data => data.id || data.image.id)
.sort()
// eslint-disable-next-line no-return-assign
.forEach(id => sigString += id);
sigString += sigVer; sigString += sigVer;
return dcodeIO.ByteBuffer.wrap(sigString, 'utf8').toArrayBuffer(); return dcodeIO.ByteBuffer.wrap(sigString, 'utf8').toArrayBuffer();
} }
@ -682,17 +694,26 @@ class LokiPublicChannelAPI {
const { timestamp, quote } = noteValue; const { timestamp, quote } = noteValue;
if (quote) { if (quote) {
// TODO: Enable quote attachments again using proper ADN style
quote.attachments = []; quote.attachments = [];
} }
// try to verify signature // try to verify signature
const { sig, sigver } = noteValue; const { sig, sigver } = noteValue;
const annoCopy = [...adnMessage.annotations]; const annoCopy = [...adnMessage.annotations];
const attachments = annoCopy
.filter(anno => anno.value.lokiType === LOKI_ATTACHMENT_TYPE)
.map(attachment => ({ isRaw: true, ...attachment.value }));
const preview = annoCopy
.filter(anno => anno.value.lokiType === LOKI_PREVIEW_TYPE)
.map(LokiPublicChannelAPI.getPreviewFromAnnotation);
// strip out sig and sigver // strip out sig and sigver
annoCopy[0] = _.omit(annoCopy[0], ['value.sig', 'value.sigver']); annoCopy[0] = _.omit(annoCopy[0], ['value.sig', 'value.sigver']);
const sigData = LokiPublicChannelAPI.getSigData( const sigData = LokiPublicChannelAPI.getSigData(
sigver, sigver,
noteValue, noteValue,
attachments,
preview,
adnMessage adnMessage
); );
@ -730,6 +751,8 @@ class LokiPublicChannelAPI {
return { return {
timestamp, timestamp,
attachments,
preview,
quote, quote,
}; };
} }
@ -789,7 +812,7 @@ class LokiPublicChannelAPI {
return; return;
} }
const { timestamp, quote } = messengerData; const { timestamp, quote, attachments, preview } = messengerData;
if (!timestamp) { if (!timestamp) {
return; // Invalid message return; // Invalid message
} }
@ -836,7 +859,7 @@ class LokiPublicChannelAPI {
isPublic: true, isPublic: true,
message: { message: {
body: adnMessage.text, body: adnMessage.text,
attachments: [], attachments,
group: { group: {
id: this.conversationId, id: this.conversationId,
type: textsecure.protobuf.GroupContext.Type.DELIVER, type: textsecure.protobuf.GroupContext.Type.DELIVER,
@ -849,7 +872,7 @@ class LokiPublicChannelAPI {
sent_at: timestamp, sent_at: timestamp,
quote, quote,
contact: [], contact: [],
preview: [], preview,
profile: { profile: {
displayName: from, displayName: from,
}, },
@ -956,6 +979,8 @@ class LokiPublicChannelAPI {
timestamp: messageTimeStamp, timestamp: messageTimeStamp,
}, },
}, },
...attachmentAnnotations,
...previewAnnotations,
], ],
}; };
if (quote && quote.id) { if (quote && quote.id) {
@ -988,6 +1013,8 @@ class LokiPublicChannelAPI {
const sigData = LokiPublicChannelAPI.getSigData( const sigData = LokiPublicChannelAPI.getSigData(
sigVer, sigVer,
payload.annotations[0].value, payload.annotations[0].value,
attachmentAnnotations.map(anno => anno.value),
previewAnnotations.map(anno => anno.value),
mockAdnMessage mockAdnMessage
); );
const sig = await libsignal.Curve.async.calculateSignature( const sig = await libsignal.Curve.async.calculateSignature(

@ -2,8 +2,6 @@
const LokiAppDotNetAPI = require('./loki_app_dot_net_api'); const LokiAppDotNetAPI = require('./loki_app_dot_net_api');
/* global log */
const DEVICE_MAPPING_ANNOTATION_KEY = 'network.loki.messenger.devicemapping'; const DEVICE_MAPPING_ANNOTATION_KEY = 'network.loki.messenger.devicemapping';
class LokiFileServerAPI { class LokiFileServerAPI {

@ -93,11 +93,7 @@ class LokiMessageAPI {
'Missing public send data for public chat message' 'Missing public send data for public chat message'
); );
} }
const res = await publicSendData.sendMessage( const res = await publicSendData.sendMessage(data, messageTimeStamp);
data.body,
data.quote,
messageTimeStamp
);
if (res === false) { if (res === false) {
throw new window.textsecure.PublicChatError( throw new window.textsecure.PublicChatError(
'Failed to send public chat message' 'Failed to send public chat message'

@ -168,7 +168,7 @@ MessageSender.prototype = {
constructor: MessageSender, constructor: MessageSender,
// makeAttachmentPointer :: Attachment -> Promise AttachmentPointerProto // makeAttachmentPointer :: Attachment -> Promise AttachmentPointerProto
makeAttachmentPointer(attachment) { async makeAttachmentPointer(attachment, publicServer = null) {
if (typeof attachment !== 'object' || attachment == null) { if (typeof attachment !== 'object' || attachment == null) {
return Promise.resolve(undefined); return Promise.resolve(undefined);
} }
@ -185,42 +185,49 @@ MessageSender.prototype = {
} }
const proto = new textsecure.protobuf.AttachmentPointer(); const proto = new textsecure.protobuf.AttachmentPointer();
proto.key = libsignal.crypto.getRandomBytes(64); let attachmentData;
let server;
const iv = libsignal.crypto.getRandomBytes(16); if (publicServer) {
return textsecure.crypto attachmentData = attachment.data;
.encryptAttachment(attachment.data, proto.key, iv) server = publicServer;
.then(result => } else {
this.server proto.key = libsignal.crypto.getRandomBytes(64);
.putAttachment(result.ciphertext) const iv = libsignal.crypto.getRandomBytes(16);
.then(async ({ url, id }) => { const result = await textsecure.crypto.encryptAttachment(
proto.id = id; attachment.data,
proto.url = url; proto.key,
proto.contentType = attachment.contentType; iv
proto.digest = result.digest;
if (attachment.size) {
proto.size = attachment.size;
}
if (attachment.fileName) {
proto.fileName = attachment.fileName;
}
if (attachment.flags) {
proto.flags = attachment.flags;
}
if (attachment.width) {
proto.width = attachment.width;
}
if (attachment.height) {
proto.height = attachment.height;
}
if (attachment.caption) {
proto.caption = attachment.caption;
}
return proto;
})
); );
proto.digest = result.digest;
attachmentData = result.ciphertext;
({ server } = this);
}
const { url, id } = await server.putAttachment(attachmentData);
proto.id = id;
proto.url = url;
proto.contentType = attachment.contentType;
if (attachment.size) {
proto.size = attachment.size;
}
if (attachment.fileName) {
proto.fileName = attachment.fileName;
}
if (attachment.flags) {
proto.flags = attachment.flags;
}
if (attachment.width) {
proto.width = attachment.width;
}
if (attachment.height) {
proto.height = attachment.height;
}
if (attachment.caption) {
proto.caption = attachment.caption;
}
return proto;
}, },
queueJobForNumber(number, runJob) { queueJobForNumber(number, runJob) {
@ -243,9 +250,11 @@ MessageSender.prototype = {
}); });
}, },
uploadAttachments(message) { uploadAttachments(message, publicServer) {
return Promise.all( return Promise.all(
message.attachments.map(this.makeAttachmentPointer.bind(this)) message.attachments.map(attachment =>
this.makeAttachmentPointer(attachment, publicServer)
)
) )
.then(attachmentPointers => { .then(attachmentPointers => {
// eslint-disable-next-line no-param-reassign // eslint-disable-next-line no-param-reassign
@ -260,12 +269,12 @@ MessageSender.prototype = {
}); });
}, },
async uploadLinkPreviews(message) { async uploadLinkPreviews(message, publicServer) {
try { try {
const preview = await Promise.all( const preview = await Promise.all(
(message.preview || []).map(async item => ({ (message.preview || []).map(async item => ({
...item, ...item,
image: await this.makeAttachmentPointer(item.image), image: await this.makeAttachmentPointer(item.image, publicServer),
})) }))
); );
// eslint-disable-next-line no-param-reassign // eslint-disable-next-line no-param-reassign
@ -279,7 +288,7 @@ MessageSender.prototype = {
} }
}, },
uploadThumbnails(message) { uploadThumbnails(message, publicServer) {
const makePointer = this.makeAttachmentPointer.bind(this); const makePointer = this.makeAttachmentPointer.bind(this);
const { quote } = message; const { quote } = message;
@ -294,7 +303,7 @@ MessageSender.prototype = {
return null; return null;
} }
return makePointer(thumbnail).then(pointer => { return makePointer(thumbnail, publicServer).then(pointer => {
// eslint-disable-next-line no-param-reassign // eslint-disable-next-line no-param-reassign
attachment.attachmentPointer = pointer; attachment.attachmentPointer = pointer;
}); });
@ -311,11 +320,13 @@ MessageSender.prototype = {
sendMessage(attrs, options) { sendMessage(attrs, options) {
const message = new Message(attrs); const message = new Message(attrs);
const silent = false; const silent = false;
const publicServer =
options.publicSendData && options.publicSendData.serverAPI;
return Promise.all([ return Promise.all([
this.uploadAttachments(message), this.uploadAttachments(message, publicServer),
this.uploadThumbnails(message), this.uploadThumbnails(message, publicServer),
this.uploadLinkPreviews(message), this.uploadLinkPreviews(message, publicServer),
]).then( ]).then(
() => () =>
new Promise((resolve, reject) => { new Promise((resolve, reject) => {

Loading…
Cancel
Save