diff --git a/protos/SignalService.proto b/protos/SignalService.proto index a1f83950c..dac96f3ba 100644 --- a/protos/SignalService.proto +++ b/protos/SignalService.proto @@ -1,8 +1,5 @@ -// Source: https://github.com/signalapp/libsignal-service-java/blob/4684a49b2ed8f32be619e0d0eea423626b6cb2cb/protobuf/SignalService.proto package signalservice; -option java_package = "org.whispersystems.signalservice.internal.push"; -option java_outer_classname = "SignalServiceProtos"; message Envelope { @@ -15,7 +12,7 @@ message Envelope { required Type type = 1; optional string source = 2; // @required - optional uint64 timestamp = 5; + required uint64 timestamp = 5; optional bytes content = 8; } @@ -25,9 +22,9 @@ message TypingMessage { STOPPED = 1; } // @required - optional uint64 timestamp = 1; + required uint64 timestamp = 1; // @required - optional Action action = 2; + required Action action = 2; } @@ -75,16 +72,16 @@ message DataMessage { } // @required - optional uint64 id = 1; + required uint64 id = 1; // @required - optional string author = 2; + required string author = 2; optional string text = 3; repeated QuotedAttachment attachments = 4; } message Preview { // @required - optional string url = 1; + required string url = 1; optional string title = 2; optional AttachmentPointer image = 3; } diff --git a/ts/opengroup/opengroupV2/ApiUtil.ts b/ts/opengroup/opengroupV2/ApiUtil.ts index 301741321..4672447fe 100644 --- a/ts/opengroup/opengroupV2/ApiUtil.ts +++ b/ts/opengroup/opengroupV2/ApiUtil.ts @@ -56,7 +56,7 @@ export const parseMessages = async ( const opengroupv2Message = OpenGroupMessageV2.fromJson(r); if ( !opengroupv2Message?.serverId || - !opengroupv2Message.sentTimestamp || + !opengroupv2Message.sentTimestamp || // this is our serverTimestamp !opengroupv2Message.base64EncodedData || !opengroupv2Message.base64EncodedSignature ) { diff --git a/ts/session/messages/outgoing/visibleMessage/VisibleMessage.ts b/ts/session/messages/outgoing/visibleMessage/VisibleMessage.ts index e77a0e069..e90fae4b4 100644 --- a/ts/session/messages/outgoing/visibleMessage/VisibleMessage.ts +++ b/ts/session/messages/outgoing/visibleMessage/VisibleMessage.ts @@ -5,10 +5,9 @@ import { DataMessage } from '..'; import { Constants } from '../../..'; import { SignalService } from '../../../../protobuf'; import { LokiProfile } from '../../../../types/Message'; -import { ExpirationTimerUpdateMessage } from '../controlMessage/ExpirationTimerUpdateMessage'; import { MessageParams } from '../Message'; -export interface AttachmentPointer { +interface AttachmentPointerCommon { id?: number; contentType?: string; key?: Uint8Array; @@ -20,11 +19,18 @@ export interface AttachmentPointer { width?: number; height?: number; caption?: string; +} + +export interface AttachmentPointer extends AttachmentPointerCommon { url?: string; } +export interface AttachmentPointerWithUrl extends AttachmentPointerCommon { + url: string; +} + export interface Preview { - url?: string; + url: string; title?: string; image?: AttachmentPointer; } @@ -36,8 +42,8 @@ export interface QuotedAttachment { } export interface Quote { - id?: number; - author?: string; + id: number; + author: string; text?: string; attachments?: Array; } diff --git a/ts/session/utils/Attachments.ts b/ts/session/utils/Attachments.ts index acbaf27a0..c9751ad0b 100644 --- a/ts/session/utils/Attachments.ts +++ b/ts/session/utils/Attachments.ts @@ -3,12 +3,14 @@ import { Attachment } from '../../types/Attachment'; import { AttachmentPointer, + AttachmentPointerWithUrl, Preview, Quote, QuotedAttachment, } from '../messages/outgoing/visibleMessage/VisibleMessage'; import { FSv2 } from '../../fileserver'; import { addAttachmentPadding } from '../crypto/BufferPadding'; +import _ from 'lodash'; interface UploadParams { attachment: Attachment; @@ -17,21 +19,21 @@ interface UploadParams { shouldPad?: boolean; } -interface RawPreview { +export interface RawPreview { url?: string; title?: string; image: Attachment; } -interface RawQuoteAttachment { +export interface RawQuoteAttachment { contentType?: string; fileName?: string; thumbnail?: Attachment; } -interface RawQuote { - id?: number; - author?: string; +export interface RawQuote { + id: number; + author: string; text?: string; attachments?: Array; } @@ -40,7 +42,7 @@ interface RawQuote { export class AttachmentFsV2Utils { private constructor() {} - public static async uploadToFsV2(params: UploadParams): Promise { + public static async uploadToFsV2(params: UploadParams): Promise { const { attachment, isRaw = false, shouldPad = false } = params; if (typeof attachment !== 'object' || attachment == null) { throw new Error('Invalid attachment passed.'); @@ -84,15 +86,17 @@ export class AttachmentFsV2Utils { if (FSv2.useFileServerAPIV2Sending) { const uploadToV2Result = await FSv2.uploadFileToFsV2(attachmentData); if (uploadToV2Result) { - pointer.id = uploadToV2Result.fileId; - pointer.url = uploadToV2Result.fileUrl; - } else { - window?.log?.warn('upload to file server v2 failed'); + const pointerWithUrl: AttachmentPointerWithUrl = { + ...pointer, + id: uploadToV2Result.fileId, + url: uploadToV2Result.fileUrl, + }; + return pointerWithUrl; } - return pointer; - } else { - throw new Error('Only v2 fileserver upload is supported'); + window?.log?.warn('upload to file server v2 failed'); + throw new Error(`upload to file server v2 of ${attachment.fileName} failed`); } + throw new Error('Only v2 fileserver upload is supported'); } public static async uploadAttachmentsToFsV2( @@ -111,19 +115,22 @@ export class AttachmentFsV2Utils { public static async uploadLinkPreviewsToFsV2( previews: Array ): Promise> { - const promises = (previews || []).map(async item => { + const promises = (previews || []).map(async preview => { // some links does not have an image associated, and it makes the whole message fail to send - if (!item.image) { - return item; + if (!preview.image) { + window.log.warn('tried to upload file to fsv2 without image.. skipping'); + return undefined; } + const image = await this.uploadToFsV2({ + attachment: preview.image, + }); return { - ...item, - image: await this.uploadToFsV2({ - attachment: item.image, - }), - }; + ...preview, + image, + url: preview.url || image.url, + } as Preview; }); - return Promise.all(promises); + return _.compact(await Promise.all(promises)); } public static async uploadQuoteThumbnailsToFsV2(quote?: RawQuote): Promise { diff --git a/ts/session/utils/AttachmentsV2.ts b/ts/session/utils/AttachmentsV2.ts index 477aa0ebf..abd13c9ce 100644 --- a/ts/session/utils/AttachmentsV2.ts +++ b/ts/session/utils/AttachmentsV2.ts @@ -1,41 +1,24 @@ -import * as crypto from 'crypto'; import { Attachment } from '../../types/Attachment'; import { OpenGroupRequestCommonType } from '../../opengroup/opengroupV2/ApiUtil'; import { AttachmentPointer, + AttachmentPointerWithUrl, Preview, Quote, QuotedAttachment, } from '../messages/outgoing/visibleMessage/VisibleMessage'; import { uploadFileOpenGroupV2 } from '../../opengroup/opengroupV2/OpenGroupAPIV2'; import { addAttachmentPadding } from '../crypto/BufferPadding'; +import { RawPreview, RawQuote } from './Attachments'; +import _ from 'lodash'; interface UploadParamsV2 { attachment: Attachment; openGroup: OpenGroupRequestCommonType; } -interface RawPreview { - url?: string; - title?: string; - image: Attachment; -} - -interface RawQuoteAttachment { - contentType?: string; - fileName?: string; - thumbnail?: Attachment; -} - -interface RawQuote { - id?: number; - author?: string; - text?: string; - attachments?: Array; -} - -export async function uploadV2(params: UploadParamsV2): Promise { +export async function uploadV2(params: UploadParamsV2): Promise { const { attachment, openGroup } = params; if (typeof attachment !== 'object' || attachment == null) { throw new Error('Invalid attachment passed.'); @@ -62,10 +45,15 @@ export async function uploadV2(params: UploadParamsV2): Promise, openGroup: OpenGroupRequestCommonType ): Promise> { - const promises = (previews || []).map(async item => { + const promises = (previews || []).map(async preview => { // some links does not have an image associated, and it makes the whole message fail to send - if (!item.image) { - return item; + if (!preview.image) { + window.log.warn('tried to upload file to opengroupv2 without image.. skipping'); + + return undefined; } + const image = await exports.uploadV2({ + attachment: preview.image, + openGroup, + }); return { - ...item, - image: await exports.uploadV2({ - attachment: item.image, - openGroup, - }), + ...preview, + image, + url: preview.url || (image.url as string), }; }); - return Promise.all(promises); + return _.compact(await Promise.all(promises)); } export async function uploadQuoteThumbnailsV2( @@ -121,7 +113,7 @@ export async function uploadQuoteThumbnailsV2( return { ...attachment, thumbnail, - } as QuotedAttachment; + }; }); const attachments = await Promise.all(promises);