Skip to content

Commit

Permalink
Delete for Everyone: Don't allow unrestricted deletes in Note to Self
Browse files Browse the repository at this point in the history
Co-authored-by: Scott Nonnenberg <scott@signal.org>
  • Loading branch information
automated-signal and scottnonnenberg-signal committed Jan 3, 2024
1 parent a98c5ba commit 39897c4
Show file tree
Hide file tree
Showing 4 changed files with 25 additions and 15 deletions.
2 changes: 1 addition & 1 deletion ts/components/DeleteMessagesModal.tsx
Expand Up @@ -41,7 +41,7 @@ export default function DeleteMessagesModal({
: i18n('icu:DeleteMessagesModal--deleteForMe'),
});

if (canDeleteForEveryone || isMe) {
if (canDeleteForEveryone) {
const tooManyMessages = messageCount > MAX_DELETE_FOR_EVERYONE;
actions.push({
'aria-disabled': tooManyMessages,
Expand Down
21 changes: 13 additions & 8 deletions ts/state/selectors/message.ts
Expand Up @@ -727,7 +727,7 @@ export const getPropsForMessage = (
payment,
canCopy: canCopy(message),
canEditMessage: canEditMessage(message),
canDeleteForEveryone: canDeleteForEveryone(message),
canDeleteForEveryone: canDeleteForEveryone(message, conversation.isMe),
canDownload: canDownload(message, conversationSelector),
canReact: canReact(message, ourConversationId, conversationSelector),
canReply: canReply(message, ourConversationId, conversationSelector),
Expand Down Expand Up @@ -1872,26 +1872,31 @@ export function canDeleteForEveryone(
message: Pick<
MessageWithUIFieldsType,
'type' | 'deletedForEveryone' | 'sent_at' | 'sendStateByConversationId'
>
>,
isMe: boolean
): boolean {
return (
// Is this a message I sent?
isOutgoing(message) &&
// Has the message already been deleted?
!message.deletedForEveryone &&
// Is it too old to delete?
isMoreRecentThan(message.sent_at, DAY) &&
// Is it too old to delete? (we relax that requirement in Note to Self)
(isMoreRecentThan(message.sent_at, DAY) || isMe) &&
// Is it sent to anyone?
someSendStatus(message.sendStateByConversationId, isSent)
);
}

export const canDeleteMessagesForEveryone = createSelector(
[getMessages, (_state, messageIds: ReadonlyArray<string>) => messageIds],
(messagesLookup, messageIds) => {
return messageIds.every(messageId => {
[
getMessages,
(_state, options: { messageIds: ReadonlyArray<string>; isMe: boolean }) =>
options,
],
(messagesLookup, options) => {
return options.messageIds.every(messageId => {
const message = getOwn(messagesLookup, messageId);
return message != null && canDeleteForEveryone(message);
return message != null && canDeleteForEveryone(message, options.isMe);
});
}
);
Expand Down
2 changes: 1 addition & 1 deletion ts/state/smart/DeleteMessagesModal.tsx
Expand Up @@ -29,7 +29,7 @@ export function SmartDeleteMessagesModal(): JSX.Element | null {
});

const canDeleteForEveryone = useSelector((state: StateType) => {
return canDeleteMessagesForEveryone(state, messageIds);
return canDeleteMessagesForEveryone(state, { messageIds, isMe });
});
const lastSelectedMessage = useSelector((state: StateType) => {
return state.conversations.lastSelectedMessage;
Expand Down
15 changes: 10 additions & 5 deletions ts/test-electron/state/selectors/messages_test.ts
Expand Up @@ -73,8 +73,9 @@ describe('state/selectors/messages', () => {
type: 'incoming' as const,
sent_at: Date.now() - 1000,
};
const isMe = false;

assert.isFalse(canDeleteForEveryone(message));
assert.isFalse(canDeleteForEveryone(message, isMe));
});

it('returns false for messages that were already deleted for everyone', () => {
Expand All @@ -93,8 +94,9 @@ describe('state/selectors/messages', () => {
},
},
};
const isMe = false;

assert.isFalse(canDeleteForEveryone(message));
assert.isFalse(canDeleteForEveryone(message, isMe));
});

it('returns false for messages that were are too old to delete', () => {
Expand All @@ -112,8 +114,9 @@ describe('state/selectors/messages', () => {
},
},
};
const isMe = false;

assert.isFalse(canDeleteForEveryone(message));
assert.isFalse(canDeleteForEveryone(message, isMe));
});

it("returns false for messages that haven't been sent to anyone", () => {
Expand All @@ -131,8 +134,9 @@ describe('state/selectors/messages', () => {
},
},
};
const isMe = false;

assert.isFalse(canDeleteForEveryone(message));
assert.isFalse(canDeleteForEveryone(message, isMe));
});

it('returns true for messages that meet all criteria for deletion', () => {
Expand All @@ -154,8 +158,9 @@ describe('state/selectors/messages', () => {
},
},
};
const isMe = false;

assert.isTrue(canDeleteForEveryone(message));
assert.isTrue(canDeleteForEveryone(message, isMe));
});
});

Expand Down

0 comments on commit 39897c4

Please sign in to comment.