Support for single-attachment delete synced across devices
This commit is contained in:
parent
97229e2e65
commit
ac04d02d4f
26 changed files with 422 additions and 55 deletions
|
@ -156,6 +156,7 @@ import { getCallEventForProto } from '../util/callDisposition';
|
|||
import { checkOurPniIdentityKey } from '../util/checkOurPniIdentityKey';
|
||||
import { CallLogEvent } from '../types/CallDisposition';
|
||||
import { CallLinkUpdateSyncType } from '../types/CallLink';
|
||||
import { bytesToUuid } from '../util/uuidToBytes';
|
||||
|
||||
const GROUPV2_ID_LENGTH = 32;
|
||||
const RETRY_TIMEOUT = 2 * 60 * 1000;
|
||||
|
@ -3761,6 +3762,67 @@ export default class MessageReceiver
|
|||
|
||||
eventData = eventData.concat(localOnlyConversationDeletes);
|
||||
}
|
||||
if (deleteSync.attachmentDeletes?.length) {
|
||||
const attachmentDeletes: Array<DeleteForMeSyncTarget> =
|
||||
deleteSync.attachmentDeletes
|
||||
.map(item => {
|
||||
const {
|
||||
clientUuid: targetClientUuid,
|
||||
conversation: targetConversation,
|
||||
fallbackDigest: targetFallbackDigest,
|
||||
fallbackPlaintextHash: targetFallbackPlaintextHash,
|
||||
targetMessage,
|
||||
} = item;
|
||||
const conversation = targetConversation
|
||||
? processConversationToDelete(targetConversation, logId)
|
||||
: undefined;
|
||||
const message = targetMessage
|
||||
? processMessageToDelete(targetMessage, logId)
|
||||
: undefined;
|
||||
|
||||
if (!conversation) {
|
||||
log.warn(
|
||||
`${logId}/handleDeleteForMeSync/attachmentDeletes: No target conversation`
|
||||
);
|
||||
return undefined;
|
||||
}
|
||||
if (!message) {
|
||||
log.warn(
|
||||
`${logId}/handleDeleteForMeSync/attachmentDeletes: No target message`
|
||||
);
|
||||
return undefined;
|
||||
}
|
||||
const clientUuid = targetClientUuid?.length
|
||||
? bytesToUuid(targetClientUuid)
|
||||
: undefined;
|
||||
const fallbackDigest = targetFallbackDigest?.length
|
||||
? Bytes.toBase64(targetFallbackDigest)
|
||||
: undefined;
|
||||
// TODO: DESKTOP-7204
|
||||
const fallbackPlaintextHash = targetFallbackPlaintextHash?.length
|
||||
? Bytes.toHex(targetFallbackPlaintextHash)
|
||||
: undefined;
|
||||
if (!clientUuid && !fallbackDigest && !fallbackPlaintextHash) {
|
||||
log.warn(
|
||||
`${logId}/handleDeleteForMeSync/attachmentDeletes: Missing clientUuid, fallbackDigest and fallbackPlaintextHash`
|
||||
);
|
||||
return undefined;
|
||||
}
|
||||
|
||||
return {
|
||||
type: 'delete-single-attachment' as const,
|
||||
conversation,
|
||||
message,
|
||||
clientUuid,
|
||||
fallbackDigest,
|
||||
fallbackPlaintextHash,
|
||||
timestamp,
|
||||
};
|
||||
})
|
||||
.filter(isNotNil);
|
||||
|
||||
eventData = eventData.concat(attachmentDeletes);
|
||||
}
|
||||
if (!eventData.length) {
|
||||
throw new Error(`${logId}: Nothing found in sync message!`);
|
||||
}
|
||||
|
|
|
@ -1534,6 +1534,10 @@ export default class MessageSender {
|
|||
deleteForMe.localOnlyConversationDeletes.push({
|
||||
conversation,
|
||||
});
|
||||
} else if (item.type === 'delete-single-attachment') {
|
||||
throw new Error(
|
||||
"getDeleteForMeSyncMessage: Desktop currently does not support sending 'delete-single-attachment' messages"
|
||||
);
|
||||
} else {
|
||||
throw missingCaseError(item);
|
||||
}
|
||||
|
|
3
ts/textsecure/Types.d.ts
vendored
3
ts/textsecure/Types.d.ts
vendored
|
@ -105,8 +105,9 @@ export type ProcessedEnvelope = Readonly<{
|
|||
export type ProcessedAttachment = {
|
||||
cdnId?: string;
|
||||
cdnKey?: string;
|
||||
digest?: string;
|
||||
contentType: MIMEType;
|
||||
clientUuid?: string;
|
||||
digest?: string;
|
||||
key?: string;
|
||||
size: number;
|
||||
fileName?: string;
|
||||
|
|
|
@ -526,10 +526,20 @@ export const deleteLocalConversationSchema = z.object({
|
|||
conversation: conversationToDeleteSchema,
|
||||
timestamp: z.number(),
|
||||
});
|
||||
export const deleteAttachmentSchema = z.object({
|
||||
type: z.literal('delete-single-attachment').readonly(),
|
||||
conversation: conversationToDeleteSchema,
|
||||
message: messageToDeleteSchema,
|
||||
clientUuid: z.string().optional(),
|
||||
fallbackDigest: z.string().optional(),
|
||||
fallbackPlaintextHash: z.string().optional(),
|
||||
timestamp: z.number(),
|
||||
});
|
||||
export const deleteForMeSyncTargetSchema = z.union([
|
||||
deleteMessageSchema,
|
||||
deleteConversationSchema,
|
||||
deleteLocalConversationSchema,
|
||||
deleteAttachmentSchema,
|
||||
]);
|
||||
|
||||
export type DeleteForMeSyncTarget = z.infer<typeof deleteForMeSyncTargetSchema>;
|
||||
|
|
|
@ -31,6 +31,7 @@ import { PaymentEventKind } from '../types/Payment';
|
|||
import { filterAndClean } from '../types/BodyRange';
|
||||
import { isAciString } from '../util/isAciString';
|
||||
import { normalizeAci } from '../util/normalizeAci';
|
||||
import { bytesToUuid } from '../util/uuidToBytes';
|
||||
|
||||
const FLAGS = Proto.DataMessage.Flags;
|
||||
export const ATTACHMENT_MAX = 32;
|
||||
|
@ -52,7 +53,7 @@ export function processAttachment(
|
|||
const { cdnId } = attachment;
|
||||
const hasCdnId = Long.isLong(cdnId) ? !cdnId.isZero() : Boolean(cdnId);
|
||||
|
||||
const { contentType, digest, key, size } = attachment;
|
||||
const { clientUuid, contentType, digest, key, size } = attachment;
|
||||
if (!isNumber(size)) {
|
||||
throw new Error('Missing size on incoming attachment!');
|
||||
}
|
||||
|
@ -61,6 +62,7 @@ export function processAttachment(
|
|||
...shallowDropNull(attachment),
|
||||
|
||||
cdnId: hasCdnId ? String(cdnId) : undefined,
|
||||
clientUuid: clientUuid ? bytesToUuid(clientUuid) : undefined,
|
||||
contentType: contentType
|
||||
? stringToMIMEType(contentType)
|
||||
: APPLICATION_OCTET_STREAM,
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue