Prevent send and show toast for invalid conversations

This commit is contained in:
Scott Nonnenberg 2020-11-16 13:34:41 -08:00 committed by GitHub
parent 34be0744d2
commit 3ee830ae63
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
5 changed files with 83 additions and 45 deletions

View File

@ -311,6 +311,10 @@
"message": "You are no longer a member of the group.",
"description": "Displayed when a user can't send a message because they have left the group"
},
"invalidConversation": {
"message": "This group is invalid. Please create a new group.",
"description": "Displayed when a user can't send a message because something has gone wrong in the conversation."
},
"scrollDown": {
"message": "Scroll to bottom of conversation",
"description": "Alt text for button to take user down to bottom of conversation, shown when user scrolls up"

View File

@ -163,6 +163,8 @@ type UpdatesResultType = {
// Constants
export const MASTER_KEY_LENGTH = 32;
export const ID_V1_LENGTH = 16;
export const ID_LENGTH = 32;
const TEMPORAL_AUTH_REJECTED_CODE = 401;
const GROUP_ACCESS_DENIED_CODE = 403;
const SUPPORTED_CHANGE_EPOCH = 0;

View File

@ -266,7 +266,8 @@ export class ConversationModel extends window.Backbone.Model<
return false;
}
return fromEncodedBinaryToArrayBuffer(groupId).byteLength === 16;
const buffer = fromEncodedBinaryToArrayBuffer(groupId);
return buffer.byteLength === window.Signal.Groups.ID_V1_LENGTH;
}
isGroupV2(): boolean {
@ -277,7 +278,10 @@ export class ConversationModel extends window.Backbone.Model<
const groupVersion = this.get('groupVersion') || 0;
return groupVersion === 2 && base64ToArrayBuffer(groupId).byteLength === 32;
return (
groupVersion === 2 &&
base64ToArrayBuffer(groupId).byteLength === window.Signal.Groups.ID_LENGTH
);
}
isMemberPending(conversationId: string): boolean {
@ -822,6 +826,10 @@ export class ConversationModel extends window.Backbone.Model<
});
}
isValid(): boolean {
return this.isPrivate() || this.isGroupV1() || this.isGroupV2();
}
maybeRepairGroupV2(data: {
masterKey: string;
secretParams: string;

View File

@ -76,6 +76,12 @@ Whisper.LeftGroupToast = Whisper.ToastView.extend({
},
});
Whisper.InvalidConversationToast = Whisper.ToastView.extend({
render_attributes() {
return { toastMessage: window.i18n('invalidConversation') };
},
});
Whisper.OriginalNotFoundToast = Whisper.ToastView.extend({
render_attributes() {
return { toastMessage: window.i18n('originalMessageNotFound') };
@ -2897,6 +2903,10 @@ Whisper.ConversationView = Whisper.View.extend({
this.model.set({ profileSharing: true });
}
if (this.showInvalidMessageToast()) {
return;
}
const { packId, stickerId } = options;
this.model.sendStickerMessage(packId, stickerId);
} catch (error) {
@ -3030,6 +3040,43 @@ Whisper.ConversationView = Whisper.View.extend({
});
},
showInvalidMessageToast(messageText?: string): boolean {
let ToastView;
if (window.reduxStore.getState().expiration.hasExpired) {
ToastView = Whisper.ExpiredToast;
}
if (!this.model.isValid()) {
ToastView = Whisper.InvalidConversationToast;
}
if (
this.model.isPrivate() &&
(window.storage.isBlocked(this.model.get('e164')) ||
window.storage.isUuidBlocked(this.model.get('uuid')))
) {
ToastView = Whisper.BlockedToast;
}
if (
!this.model.isPrivate() &&
window.storage.isGroupBlocked(this.model.get('groupId'))
) {
ToastView = Whisper.BlockedGroupToast;
}
if (!this.model.isPrivate() && this.model.get('left')) {
ToastView = Whisper.LeftGroupToast;
}
if (messageText && messageText.length > MAX_MESSAGE_BODY_LENGTH) {
ToastView = Whisper.MessageBodyTooLongToast;
}
if (ToastView) {
this.showToast(ToastView);
return true;
}
return false;
},
async sendMessage(message = '', mentions = [], options = {}) {
this.sendStart = Date.now();
@ -3058,32 +3105,7 @@ Whisper.ConversationView = Whisper.View.extend({
this.model.clearTypingTimers();
let ToastView;
if (window.reduxStore.getState().expiration.hasExpired) {
ToastView = Whisper.ExpiredToast;
}
if (
this.model.isPrivate() &&
(window.storage.isBlocked(this.model.get('e164')) ||
window.storage.isUuidBlocked(this.model.get('uuid')))
) {
ToastView = Whisper.BlockedToast;
}
if (
!this.model.isPrivate() &&
window.storage.isGroupBlocked(this.model.get('groupId'))
) {
ToastView = Whisper.BlockedGroupToast;
}
if (!this.model.isPrivate() && this.model.get('left')) {
ToastView = Whisper.LeftGroupToast;
}
if (message.length > MAX_MESSAGE_BODY_LENGTH) {
ToastView = Whisper.MessageBodyTooLongToast;
}
if (ToastView) {
this.showToast(ToastView);
if (this.showInvalidMessageToast(message)) {
this.enableMessageField();
return;
}

36
ts/window.d.ts vendored
View File

@ -674,28 +674,30 @@ export type WhisperType = {
deliveryReceiptBatcher: BatcherType<WhatIsThis>;
RotateSignedPreKeyListener: WhatIsThis;
ExpiredToast: typeof Whisper.ToastView;
BlockedToast: typeof Whisper.ToastView;
BlockedGroupToast: typeof Whisper.ToastView;
LeftGroupToast: typeof Whisper.ToastView;
OriginalNotFoundToast: typeof Whisper.ToastView;
OriginalNoLongerAvailableToast: typeof Whisper.ToastView;
BlockedToast: typeof Whisper.ToastView;
CannotMixImageAndNonImageAttachmentsToast: typeof Whisper.ToastView;
DangerousFileTypeToast: typeof Whisper.ToastView;
ExpiredToast: typeof Whisper.ToastView;
FileSavedToast: typeof Whisper.ToastView;
FileSizeToast: any;
FoundButNotLoadedToast: typeof Whisper.ToastView;
VoiceNoteLimit: typeof Whisper.ToastView;
VoiceNoteMustBeOnlyAttachmentToast: typeof Whisper.ToastView;
InvalidConversationToast: typeof Whisper.ToastView;
LeftGroupToast: typeof Whisper.ToastView;
MaxAttachmentsToast: typeof Whisper.ToastView;
MessageBodyTooLongToast: typeof Whisper.ToastView;
OneNonImageAtATimeToast: typeof Whisper.ToastView;
OriginalNoLongerAvailableToast: typeof Whisper.ToastView;
OriginalNotFoundToast: typeof Whisper.ToastView;
PinnedConversationsFullToast: typeof Whisper.ToastView;
ReactionFailedToast: typeof Whisper.ToastView;
TapToViewExpiredIncomingToast: typeof Whisper.ToastView;
TapToViewExpiredOutgoingToast: typeof Whisper.ToastView;
FileSavedToast: typeof Whisper.ToastView;
ReactionFailedToast: typeof Whisper.ToastView;
MessageBodyTooLongToast: typeof Whisper.ToastView;
FileSizeToast: any;
UnableToLoadToast: typeof Whisper.ToastView;
DangerousFileTypeToast: typeof Whisper.ToastView;
OneNonImageAtATimeToast: typeof Whisper.ToastView;
CannotMixImageAndNonImageAttachmentsToast: typeof Whisper.ToastView;
MaxAttachmentsToast: typeof Whisper.ToastView;
TimerConflictToast: typeof Whisper.ToastView;
PinnedConversationsFullToast: typeof Whisper.ToastView;
UnableToLoadToast: typeof Whisper.ToastView;
VoiceNoteLimit: typeof Whisper.ToastView;
VoiceNoteMustBeOnlyAttachmentToast: typeof Whisper.ToastView;
ConversationLoadingScreen: typeof Whisper.View;
ConversationView: typeof Whisper.View;
View: typeof Backbone.View;