Remove isPrivate, isMe, isGroupV1, isGroupV2 from model
This commit is contained in:
parent
eaf4036fc8
commit
d4875fd8f4
|
@ -13,6 +13,10 @@ import { SendOptionsType, CallbackResultType } from './textsecure/SendMessage';
|
||||||
import { ConversationModel } from './models/conversations';
|
import { ConversationModel } from './models/conversations';
|
||||||
import { maybeDeriveGroupV2Id } from './groups';
|
import { maybeDeriveGroupV2Id } from './groups';
|
||||||
import { assert } from './util/assert';
|
import { assert } from './util/assert';
|
||||||
|
import { isGroupV1, isGroupV2 } from './util/whatTypeOfConversation';
|
||||||
|
import { deprecated } from './util/deprecated';
|
||||||
|
import { getSendOptions } from './util/getSendOptions';
|
||||||
|
import { handleMessageSend } from './util/handleMessageSend';
|
||||||
|
|
||||||
const MAX_MESSAGE_BODY_LENGTH = 64 * 1024;
|
const MAX_MESSAGE_BODY_LENGTH = 64 * 1024;
|
||||||
|
|
||||||
|
@ -237,7 +241,7 @@ export class ConversationController {
|
||||||
}
|
}
|
||||||
|
|
||||||
try {
|
try {
|
||||||
if (conversation.isGroupV1()) {
|
if (isGroupV1(conversation.attributes)) {
|
||||||
await maybeDeriveGroupV2Id(conversation);
|
await maybeDeriveGroupV2Id(conversation);
|
||||||
}
|
}
|
||||||
await saveConversation(conversation.attributes);
|
await saveConversation(conversation.attributes);
|
||||||
|
@ -556,7 +560,7 @@ export class ConversationController {
|
||||||
}
|
}
|
||||||
|
|
||||||
let groupV2Id: undefined | string;
|
let groupV2Id: undefined | string;
|
||||||
if (conversation.isGroupV1()) {
|
if (isGroupV1(conversation.attributes)) {
|
||||||
// eslint-disable-next-line no-await-in-loop
|
// eslint-disable-next-line no-await-in-loop
|
||||||
await maybeDeriveGroupV2Id(conversation);
|
await maybeDeriveGroupV2Id(conversation);
|
||||||
groupV2Id = conversation.get('derivedGroupV2Id');
|
groupV2Id = conversation.get('derivedGroupV2Id');
|
||||||
|
@ -564,7 +568,7 @@ export class ConversationController {
|
||||||
groupV2Id,
|
groupV2Id,
|
||||||
'checkForConflicts: expected the group V2 ID to have been derived, but it was falsy'
|
'checkForConflicts: expected the group V2 ID to have been derived, but it was falsy'
|
||||||
);
|
);
|
||||||
} else if (conversation.isGroupV2()) {
|
} else if (isGroupV2(conversation.attributes)) {
|
||||||
groupV2Id = conversation.get('groupId');
|
groupV2Id = conversation.get('groupId');
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -573,7 +577,7 @@ export class ConversationController {
|
||||||
if (!existing) {
|
if (!existing) {
|
||||||
byGroupV2Id[groupV2Id] = conversation;
|
byGroupV2Id[groupV2Id] = conversation;
|
||||||
} else {
|
} else {
|
||||||
const logParenthetical = conversation.isGroupV1()
|
const logParenthetical = isGroupV1(conversation.attributes)
|
||||||
? ' (derived from a GV1 group ID)'
|
? ' (derived from a GV1 group ID)'
|
||||||
: '';
|
: '';
|
||||||
window.log.warn(
|
window.log.warn(
|
||||||
|
@ -581,7 +585,10 @@ export class ConversationController {
|
||||||
);
|
);
|
||||||
|
|
||||||
// Prefer the GV2 group.
|
// Prefer the GV2 group.
|
||||||
if (conversation.isGroupV2() && !existing.isGroupV2()) {
|
if (
|
||||||
|
isGroupV2(conversation.attributes) &&
|
||||||
|
!isGroupV2(existing.attributes)
|
||||||
|
) {
|
||||||
// eslint-disable-next-line no-await-in-loop
|
// eslint-disable-next-line no-await-in-loop
|
||||||
await this.combineConversations(conversation, existing);
|
await this.combineConversations(conversation, existing);
|
||||||
byGroupV2Id[groupV2Id] = conversation;
|
byGroupV2Id[groupV2Id] = conversation;
|
||||||
|
@ -730,16 +737,14 @@ export class ConversationController {
|
||||||
) => Promise<CallbackResultType | void | null>;
|
) => Promise<CallbackResultType | void | null>;
|
||||||
sendOptions: SendOptionsType | undefined;
|
sendOptions: SendOptionsType | undefined;
|
||||||
}> {
|
}> {
|
||||||
|
deprecated('prepareForSend');
|
||||||
// id is any valid conversation identifier
|
// id is any valid conversation identifier
|
||||||
const conversation = this.get(id);
|
const conversation = this.get(id);
|
||||||
const sendOptions = conversation
|
const sendOptions = conversation
|
||||||
? await conversation.getSendOptions(options)
|
? await getSendOptions(conversation.attributes, options)
|
||||||
: undefined;
|
: undefined;
|
||||||
const wrap = conversation
|
|
||||||
? conversation.wrapSend.bind(conversation)
|
|
||||||
: async (promise: Promise<CallbackResultType | void | null>) => promise;
|
|
||||||
|
|
||||||
return { wrap, sendOptions };
|
return { wrap: handleMessageSend, sendOptions };
|
||||||
}
|
}
|
||||||
|
|
||||||
async getAllGroupsInvolvingId(
|
async getAllGroupsInvolvingId(
|
||||||
|
|
|
@ -43,6 +43,7 @@ import {
|
||||||
UnprocessedType,
|
UnprocessedType,
|
||||||
UnprocessedUpdateType,
|
UnprocessedUpdateType,
|
||||||
} from './textsecure/Types.d';
|
} from './textsecure/Types.d';
|
||||||
|
import { getSendOptions } from './util/getSendOptions';
|
||||||
|
|
||||||
const TIMESTAMP_THRESHOLD = 5 * 1000; // 5 seconds
|
const TIMESTAMP_THRESHOLD = 5 * 1000; // 5 seconds
|
||||||
|
|
||||||
|
@ -1230,7 +1231,7 @@ export class SignalProtocolStore extends EventsMixin {
|
||||||
await this.archiveSession(id);
|
await this.archiveSession(id);
|
||||||
|
|
||||||
// Send a null message with newly-created session
|
// Send a null message with newly-created session
|
||||||
const sendOptions = await conversation.getSendOptions();
|
const sendOptions = await getSendOptions(conversation.attributes);
|
||||||
await window.textsecure.messaging.sendNullMessage({ uuid }, sendOptions);
|
await window.textsecure.messaging.sendNullMessage({ uuid }, sendOptions);
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
// If we failed to do the session reset, then we'll allow another attempt sooner
|
// If we failed to do the session reset, then we'll allow another attempt sooner
|
||||||
|
|
|
@ -35,6 +35,8 @@ import {
|
||||||
} from './textsecure/MessageReceiver';
|
} from './textsecure/MessageReceiver';
|
||||||
import { connectToServerWithStoredCredentials } from './util/connectToServerWithStoredCredentials';
|
import { connectToServerWithStoredCredentials } from './util/connectToServerWithStoredCredentials';
|
||||||
import * as universalExpireTimer from './util/universalExpireTimer';
|
import * as universalExpireTimer from './util/universalExpireTimer';
|
||||||
|
import { isDirectConversation, isGroupV2 } from './util/whatTypeOfConversation';
|
||||||
|
import { getSendOptions } from './util/getSendOptions';
|
||||||
|
|
||||||
const MAX_ATTACHMENT_DOWNLOAD_AGE = 3600 * 72 * 1000;
|
const MAX_ATTACHMENT_DOWNLOAD_AGE = 3600 * 72 * 1000;
|
||||||
|
|
||||||
|
@ -1955,7 +1957,7 @@ export async function startApp(): Promise<void> {
|
||||||
.getConversations()
|
.getConversations()
|
||||||
.filter(c =>
|
.filter(c =>
|
||||||
Boolean(
|
Boolean(
|
||||||
c.isPrivate() &&
|
isDirectConversation(c.attributes) &&
|
||||||
c.get('e164') &&
|
c.get('e164') &&
|
||||||
!c.get('uuid') &&
|
!c.get('uuid') &&
|
||||||
!c.isEverUnregistered()
|
!c.isEverUnregistered()
|
||||||
|
@ -2502,7 +2504,10 @@ export async function startApp(): Promise<void> {
|
||||||
}
|
}
|
||||||
|
|
||||||
// We drop typing notifications in groups we're not a part of
|
// We drop typing notifications in groups we're not a part of
|
||||||
if (!conversation.isPrivate() && !conversation.hasMember(ourId)) {
|
if (
|
||||||
|
!isDirectConversation(conversation.attributes) &&
|
||||||
|
!conversation.hasMember(ourId)
|
||||||
|
) {
|
||||||
window.log.warn(
|
window.log.warn(
|
||||||
`Received typing indicator for group ${conversation.idForLogging()}, which we're not a part of. Dropping.`
|
`Received typing indicator for group ${conversation.idForLogging()}, which we're not a part of. Dropping.`
|
||||||
);
|
);
|
||||||
|
@ -2703,7 +2708,7 @@ export async function startApp(): Promise<void> {
|
||||||
id,
|
id,
|
||||||
'group'
|
'group'
|
||||||
);
|
);
|
||||||
if (conversation.isGroupV2()) {
|
if (isGroupV2(conversation.attributes)) {
|
||||||
window.log.warn(
|
window.log.warn(
|
||||||
'Got group sync for v2 group: ',
|
'Got group sync for v2 group: ',
|
||||||
conversation.idForLogging()
|
conversation.idForLogging()
|
||||||
|
@ -3578,7 +3583,7 @@ export async function startApp(): Promise<void> {
|
||||||
);
|
);
|
||||||
|
|
||||||
const plaintext = PlaintextContent.from(message);
|
const plaintext = PlaintextContent.from(message);
|
||||||
const options = await conversation.getSendOptions();
|
const options = await getSendOptions(conversation.attributes);
|
||||||
const result = await window.textsecure.messaging.sendRetryRequest({
|
const result = await window.textsecure.messaging.sendRetryRequest({
|
||||||
plaintext,
|
plaintext,
|
||||||
options,
|
options,
|
||||||
|
|
33
ts/groups.ts
33
ts/groups.ts
|
@ -79,6 +79,13 @@ import { CURRENT_SCHEMA_VERSION as MAX_MESSAGE_SCHEMA } from '../js/modules/type
|
||||||
import { ConversationModel } from './models/conversations';
|
import { ConversationModel } from './models/conversations';
|
||||||
import { getGroupSizeHardLimit } from './groups/limits';
|
import { getGroupSizeHardLimit } from './groups/limits';
|
||||||
import { ourProfileKeyService } from './services/ourProfileKey';
|
import { ourProfileKeyService } from './services/ourProfileKey';
|
||||||
|
import {
|
||||||
|
isGroupV1 as getIsGroupV1,
|
||||||
|
isGroupV2 as getIsGroupV2,
|
||||||
|
isMe,
|
||||||
|
} from './util/whatTypeOfConversation';
|
||||||
|
import { handleMessageSend } from './util/handleMessageSend';
|
||||||
|
import { getSendOptions } from './util/getSendOptions';
|
||||||
|
|
||||||
export { joinViaLink } from './groups/joinViaLink';
|
export { joinViaLink } from './groups/joinViaLink';
|
||||||
|
|
||||||
|
@ -1231,7 +1238,7 @@ export async function modifyGroupV2({
|
||||||
}): Promise<void> {
|
}): Promise<void> {
|
||||||
const idLog = `${name}/${conversation.idForLogging()}`;
|
const idLog = `${name}/${conversation.idForLogging()}`;
|
||||||
|
|
||||||
if (!conversation.isGroupV2()) {
|
if (!getIsGroupV2(conversation.attributes)) {
|
||||||
throw new Error(
|
throw new Error(
|
||||||
`modifyGroupV2/${idLog}: Called for non-GroupV2 conversation`
|
`modifyGroupV2/${idLog}: Called for non-GroupV2 conversation`
|
||||||
);
|
);
|
||||||
|
@ -1297,13 +1304,13 @@ export async function modifyGroupV2({
|
||||||
? await ourProfileKeyService.get()
|
? await ourProfileKeyService.get()
|
||||||
: undefined;
|
: undefined;
|
||||||
|
|
||||||
const sendOptions = await conversation.getSendOptions();
|
const sendOptions = await getSendOptions(conversation.attributes);
|
||||||
const timestamp = Date.now();
|
const timestamp = Date.now();
|
||||||
const {
|
const {
|
||||||
ContentHint,
|
ContentHint,
|
||||||
} = window.textsecure.protobuf.UnidentifiedSenderMessage.Message;
|
} = window.textsecure.protobuf.UnidentifiedSenderMessage.Message;
|
||||||
|
|
||||||
const promise = conversation.wrapSend(
|
const promise = handleMessageSend(
|
||||||
window.Signal.Util.sendToGroup(
|
window.Signal.Util.sendToGroup(
|
||||||
{
|
{
|
||||||
groupV2: conversation.getGroupV2Info({
|
groupV2: conversation.getGroupV2Info({
|
||||||
|
@ -1676,7 +1683,7 @@ export async function createGroupV2({
|
||||||
const {
|
const {
|
||||||
ContentHint,
|
ContentHint,
|
||||||
} = window.textsecure.protobuf.UnidentifiedSenderMessage.Message;
|
} = window.textsecure.protobuf.UnidentifiedSenderMessage.Message;
|
||||||
const sendOptions = await conversation.getSendOptions();
|
const sendOptions = await getSendOptions(conversation.attributes);
|
||||||
|
|
||||||
await wrapWithSyncMessageSend({
|
await wrapWithSyncMessageSend({
|
||||||
conversation,
|
conversation,
|
||||||
|
@ -1729,7 +1736,7 @@ export async function hasV1GroupBeenMigrated(
|
||||||
conversation: ConversationModel
|
conversation: ConversationModel
|
||||||
): Promise<boolean> {
|
): Promise<boolean> {
|
||||||
const logId = conversation.idForLogging();
|
const logId = conversation.idForLogging();
|
||||||
const isGroupV1 = conversation.isGroupV1();
|
const isGroupV1 = getIsGroupV1(conversation.attributes);
|
||||||
if (!isGroupV1) {
|
if (!isGroupV1) {
|
||||||
window.log.warn(
|
window.log.warn(
|
||||||
`checkForGV2Existence/${logId}: Called for non-GroupV1 conversation!`
|
`checkForGV2Existence/${logId}: Called for non-GroupV1 conversation!`
|
||||||
|
@ -1766,7 +1773,7 @@ export async function hasV1GroupBeenMigrated(
|
||||||
export async function maybeDeriveGroupV2Id(
|
export async function maybeDeriveGroupV2Id(
|
||||||
conversation: ConversationModel
|
conversation: ConversationModel
|
||||||
): Promise<boolean> {
|
): Promise<boolean> {
|
||||||
const isGroupV1 = conversation.isGroupV1();
|
const isGroupV1 = getIsGroupV1(conversation.attributes);
|
||||||
const groupV1Id = conversation.get('groupId');
|
const groupV1Id = conversation.get('groupId');
|
||||||
const derived = conversation.get('derivedGroupV2Id');
|
const derived = conversation.get('derivedGroupV2Id');
|
||||||
|
|
||||||
|
@ -1797,7 +1804,7 @@ type MigratePropsType = {
|
||||||
export async function isGroupEligibleToMigrate(
|
export async function isGroupEligibleToMigrate(
|
||||||
conversation: ConversationModel
|
conversation: ConversationModel
|
||||||
): Promise<boolean> {
|
): Promise<boolean> {
|
||||||
if (!conversation.isGroupV1()) {
|
if (!getIsGroupV1(conversation.attributes)) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1860,7 +1867,7 @@ export async function getGroupMigrationMembers(
|
||||||
`getGroupMigrationMembers/${logId}: membersV2 - missing local contact for ${e164}, skipping.`
|
`getGroupMigrationMembers/${logId}: membersV2 - missing local contact for ${e164}, skipping.`
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
if (!contact.isMe() && window.GV2_MIGRATION_DISABLE_ADD) {
|
if (!isMe(contact.attributes) && window.GV2_MIGRATION_DISABLE_ADD) {
|
||||||
window.log.warn(
|
window.log.warn(
|
||||||
`getGroupMigrationMembers/${logId}: membersV2 - skipping ${e164} due to GV2_MIGRATION_DISABLE_ADD flag`
|
`getGroupMigrationMembers/${logId}: membersV2 - skipping ${e164} due to GV2_MIGRATION_DISABLE_ADD flag`
|
||||||
);
|
);
|
||||||
|
@ -1947,7 +1954,7 @@ export async function getGroupMigrationMembers(
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!contact.isMe() && window.GV2_MIGRATION_DISABLE_INVITE) {
|
if (!isMe(contact.attributes) && window.GV2_MIGRATION_DISABLE_INVITE) {
|
||||||
window.log.warn(
|
window.log.warn(
|
||||||
`getGroupMigrationMembers/${logId}: pendingMembersV2 - skipping ${e164} due to GV2_MIGRATION_DISABLE_INVITE flag`
|
`getGroupMigrationMembers/${logId}: pendingMembersV2 - skipping ${e164} due to GV2_MIGRATION_DISABLE_INVITE flag`
|
||||||
);
|
);
|
||||||
|
@ -2173,7 +2180,7 @@ export async function initiateMigrationToGroupV2(
|
||||||
});
|
});
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
const logId = conversation.idForLogging();
|
const logId = conversation.idForLogging();
|
||||||
if (!conversation.isGroupV1()) {
|
if (!getIsGroupV1(conversation.attributes)) {
|
||||||
throw error;
|
throw error;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2203,7 +2210,7 @@ export async function initiateMigrationToGroupV2(
|
||||||
const {
|
const {
|
||||||
ContentHint,
|
ContentHint,
|
||||||
} = window.textsecure.protobuf.UnidentifiedSenderMessage.Message;
|
} = window.textsecure.protobuf.UnidentifiedSenderMessage.Message;
|
||||||
const sendOptions = await conversation.getSendOptions();
|
const sendOptions = await getSendOptions(conversation.attributes);
|
||||||
|
|
||||||
await wrapWithSyncMessageSend({
|
await wrapWithSyncMessageSend({
|
||||||
conversation,
|
conversation,
|
||||||
|
@ -2361,7 +2368,7 @@ export async function joinGroupV2ViaLinkAndMigrate({
|
||||||
inviteLinkPassword: string;
|
inviteLinkPassword: string;
|
||||||
revision: number;
|
revision: number;
|
||||||
}): Promise<void> {
|
}): Promise<void> {
|
||||||
const isGroupV1 = conversation.isGroupV1();
|
const isGroupV1 = getIsGroupV1(conversation.attributes);
|
||||||
const previousGroupV1Id = conversation.get('groupId');
|
const previousGroupV1Id = conversation.get('groupId');
|
||||||
|
|
||||||
if (!isGroupV1 || !previousGroupV1Id) {
|
if (!isGroupV1 || !previousGroupV1Id) {
|
||||||
|
@ -2451,7 +2458,7 @@ export async function respondToGroupV2Migration({
|
||||||
// Ensure we have the credentials we need before attempting GroupsV2 operations
|
// Ensure we have the credentials we need before attempting GroupsV2 operations
|
||||||
await maybeFetchNewCredentials();
|
await maybeFetchNewCredentials();
|
||||||
|
|
||||||
const isGroupV1 = conversation.isGroupV1();
|
const isGroupV1 = getIsGroupV1(conversation.attributes);
|
||||||
const previousGroupV1Id = conversation.get('groupId');
|
const previousGroupV1Id = conversation.get('groupId');
|
||||||
|
|
||||||
if (!isGroupV1 || !previousGroupV1Id) {
|
if (!isGroupV1 || !previousGroupV1Id) {
|
||||||
|
|
|
@ -13,6 +13,7 @@ import {
|
||||||
} from '../groups';
|
} from '../groups';
|
||||||
import { arrayBufferToBase64, base64ToArrayBuffer } from '../Crypto';
|
import { arrayBufferToBase64, base64ToArrayBuffer } from '../Crypto';
|
||||||
import { longRunningTaskWrapper } from '../util/longRunningTaskWrapper';
|
import { longRunningTaskWrapper } from '../util/longRunningTaskWrapper';
|
||||||
|
import { isGroupV1 } from '../util/whatTypeOfConversation';
|
||||||
|
|
||||||
import type { GroupJoinInfoClass } from '../textsecure.d';
|
import type { GroupJoinInfoClass } from '../textsecure.d';
|
||||||
import type { ConversationAttributesType } from '../model-types.d';
|
import type { ConversationAttributesType } from '../model-types.d';
|
||||||
|
@ -285,7 +286,7 @@ export async function joinViaLink(hash: string): Promise<void> {
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (targetConversation.isGroupV1()) {
|
if (isGroupV1(targetConversation.attributes)) {
|
||||||
await targetConversation.joinGroupV2ViaLinkAndMigrate({
|
await targetConversation.joinGroupV2ViaLinkAndMigrate({
|
||||||
approvalRequired,
|
approvalRequired,
|
||||||
inviteLinkPassword,
|
inviteLinkPassword,
|
||||||
|
|
File diff suppressed because it is too large
Load diff
|
@ -57,6 +57,14 @@ import { MIMEType } from '../types/MIME';
|
||||||
import { LinkPreviewType } from '../types/message/LinkPreviews';
|
import { LinkPreviewType } from '../types/message/LinkPreviews';
|
||||||
import { ourProfileKeyService } from '../services/ourProfileKey';
|
import { ourProfileKeyService } from '../services/ourProfileKey';
|
||||||
import { markRead, setToExpire } from '../services/MessageUpdater';
|
import { markRead, setToExpire } from '../services/MessageUpdater';
|
||||||
|
import {
|
||||||
|
isDirectConversation,
|
||||||
|
isGroupV1,
|
||||||
|
isGroupV2,
|
||||||
|
isMe,
|
||||||
|
} from '../util/whatTypeOfConversation';
|
||||||
|
import { handleMessageSend } from '../util/handleMessageSend';
|
||||||
|
import { getSendOptions } from '../util/getSendOptions';
|
||||||
|
|
||||||
/* eslint-disable camelcase */
|
/* eslint-disable camelcase */
|
||||||
/* eslint-disable more/no-then */
|
/* eslint-disable more/no-then */
|
||||||
|
@ -744,7 +752,9 @@ export class MessageModel extends window.Backbone.Model<MessageAttributesType> {
|
||||||
|
|
||||||
getPropsForSafetyNumberNotification(): SafetyNumberNotificationProps {
|
getPropsForSafetyNumberNotification(): SafetyNumberNotificationProps {
|
||||||
const conversation = this.getConversation();
|
const conversation = this.getConversation();
|
||||||
const isGroup = Boolean(conversation && !conversation.isPrivate());
|
const isGroup = Boolean(
|
||||||
|
conversation && !isDirectConversation(conversation.attributes)
|
||||||
|
);
|
||||||
const identifier = this.get('key_changed');
|
const identifier = this.get('key_changed');
|
||||||
const contact = this.findAndFormatContact(identifier);
|
const contact = this.findAndFormatContact(identifier);
|
||||||
|
|
||||||
|
@ -981,7 +991,8 @@ export class MessageModel extends window.Backbone.Model<MessageAttributesType> {
|
||||||
: undefined;
|
: undefined;
|
||||||
|
|
||||||
const conversation = this.getConversation();
|
const conversation = this.getConversation();
|
||||||
const isGroup = conversation && !conversation.isPrivate();
|
const isGroup =
|
||||||
|
conversation && !isDirectConversation(conversation.attributes);
|
||||||
const sticker = this.get('sticker');
|
const sticker = this.get('sticker');
|
||||||
|
|
||||||
const isTapToView = this.isTapToView();
|
const isTapToView = this.isTapToView();
|
||||||
|
@ -1316,7 +1327,7 @@ export class MessageModel extends window.Backbone.Model<MessageAttributesType> {
|
||||||
let authorTitle: string;
|
let authorTitle: string;
|
||||||
let isFromMe: boolean;
|
let isFromMe: boolean;
|
||||||
|
|
||||||
if (contact && contact.isPrivate()) {
|
if (contact && isDirectConversation(contact.attributes)) {
|
||||||
const contactPhoneNumber = contact.get('e164');
|
const contactPhoneNumber = contact.get('e164');
|
||||||
|
|
||||||
authorId = contact.id;
|
authorId = contact.id;
|
||||||
|
@ -1328,7 +1339,7 @@ export class MessageModel extends window.Backbone.Model<MessageAttributesType> {
|
||||||
: undefined;
|
: undefined;
|
||||||
authorProfileName = contact.getProfileName();
|
authorProfileName = contact.getProfileName();
|
||||||
authorTitle = contact.getTitle();
|
authorTitle = contact.getTitle();
|
||||||
isFromMe = contact.isMe();
|
isFromMe = isMe(contact.attributes);
|
||||||
} else {
|
} else {
|
||||||
window.log.warn(
|
window.log.warn(
|
||||||
'getPropsForQuote: contact was missing. This may indicate a bookkeeping error or bad data from another client. Returning a placeholder contact.'
|
'getPropsForQuote: contact was missing. This may indicate a bookkeeping error or bad data from another client. Returning a placeholder contact.'
|
||||||
|
@ -1529,7 +1540,7 @@ export class MessageModel extends window.Backbone.Model<MessageAttributesType> {
|
||||||
return { text: '' };
|
return { text: '' };
|
||||||
}
|
}
|
||||||
|
|
||||||
if (fromContact.isMe()) {
|
if (isMe(fromContact.attributes)) {
|
||||||
messages.push(window.i18n('youUpdatedTheGroup'));
|
messages.push(window.i18n('youUpdatedTheGroup'));
|
||||||
} else {
|
} else {
|
||||||
messages.push(window.i18n('updatedTheGroup', [fromContact.getTitle()]));
|
messages.push(window.i18n('updatedTheGroup', [fromContact.getTitle()]));
|
||||||
|
@ -1540,7 +1551,7 @@ export class MessageModel extends window.Backbone.Model<MessageAttributesType> {
|
||||||
window.ConversationController.getOrCreate(item, 'private')
|
window.ConversationController.getOrCreate(item, 'private')
|
||||||
);
|
);
|
||||||
const joinedWithoutMe = joinedContacts.filter(
|
const joinedWithoutMe = joinedContacts.filter(
|
||||||
contact => !contact.isMe()
|
contact => !isMe(contact.attributes)
|
||||||
);
|
);
|
||||||
|
|
||||||
if (joinedContacts.length > 1) {
|
if (joinedContacts.length > 1) {
|
||||||
|
@ -1558,7 +1569,7 @@ export class MessageModel extends window.Backbone.Model<MessageAttributesType> {
|
||||||
groupUpdate.joined[0],
|
groupUpdate.joined[0],
|
||||||
'private'
|
'private'
|
||||||
);
|
);
|
||||||
if (joinedContact.isMe()) {
|
if (isMe(joinedContact.attributes)) {
|
||||||
messages.push(window.i18n('youJoinedTheGroup'));
|
messages.push(window.i18n('youJoinedTheGroup'));
|
||||||
} else {
|
} else {
|
||||||
messages.push(
|
messages.push(
|
||||||
|
@ -2282,13 +2293,13 @@ export class MessageModel extends window.Backbone.Model<MessageAttributesType> {
|
||||||
}
|
}
|
||||||
|
|
||||||
let promise;
|
let promise;
|
||||||
const options = await conversation.getSendOptions();
|
const options = await getSendOptions(conversation.attributes);
|
||||||
|
|
||||||
const {
|
const {
|
||||||
ContentHint,
|
ContentHint,
|
||||||
} = window.textsecure.protobuf.UnidentifiedSenderMessage.Message;
|
} = window.textsecure.protobuf.UnidentifiedSenderMessage.Message;
|
||||||
|
|
||||||
if (conversation.isPrivate()) {
|
if (isDirectConversation(conversation.attributes)) {
|
||||||
const [identifier] = recipients;
|
const [identifier] = recipients;
|
||||||
promise = window.textsecure.messaging.sendMessageToIdentifier(
|
promise = window.textsecure.messaging.sendMessageToIdentifier(
|
||||||
identifier,
|
identifier,
|
||||||
|
@ -2351,7 +2362,7 @@ export class MessageModel extends window.Backbone.Model<MessageAttributesType> {
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
return this.send(conversation.wrapSend(promise));
|
return this.send(handleMessageSend(promise));
|
||||||
}
|
}
|
||||||
|
|
||||||
// eslint-disable-next-line class-methods-use-this
|
// eslint-disable-next-line class-methods-use-this
|
||||||
|
@ -2534,7 +2545,7 @@ export class MessageModel extends window.Backbone.Model<MessageAttributesType> {
|
||||||
sendOptions,
|
sendOptions,
|
||||||
} = await window.ConversationController.prepareForSend(identifier);
|
} = await window.ConversationController.prepareForSend(identifier);
|
||||||
const group =
|
const group =
|
||||||
groupId && parentConversation?.isGroupV1()
|
groupId && isGroupV1(parentConversation?.attributes)
|
||||||
? {
|
? {
|
||||||
id: groupId,
|
id: groupId,
|
||||||
type: window.textsecure.protobuf.GroupContext.Type.DELIVER,
|
type: window.textsecure.protobuf.GroupContext.Type.DELIVER,
|
||||||
|
@ -2576,7 +2587,9 @@ export class MessageModel extends window.Backbone.Model<MessageAttributesType> {
|
||||||
[identifier],
|
[identifier],
|
||||||
contentMessage,
|
contentMessage,
|
||||||
ContentHint.RESENDABLE,
|
ContentHint.RESENDABLE,
|
||||||
groupId && parentConversation?.isGroupV2() ? groupId : undefined,
|
groupId && isGroupV2(parentConversation?.attributes)
|
||||||
|
? groupId
|
||||||
|
: undefined,
|
||||||
sendOptions
|
sendOptions
|
||||||
);
|
);
|
||||||
|
|
||||||
|
@ -2767,7 +2780,7 @@ export class MessageModel extends window.Backbone.Model<MessageAttributesType> {
|
||||||
retryOptions: options,
|
retryOptions: options,
|
||||||
});
|
});
|
||||||
|
|
||||||
const sendOptions = await conv.getSendOptions();
|
const sendOptions = await getSendOptions(conv.attributes);
|
||||||
|
|
||||||
// We don't have to check `sent_to` here, because:
|
// We don't have to check `sent_to` here, because:
|
||||||
//
|
//
|
||||||
|
@ -2776,11 +2789,11 @@ export class MessageModel extends window.Backbone.Model<MessageAttributesType> {
|
||||||
// in a single request to the server. So partial success is not
|
// in a single request to the server. So partial success is not
|
||||||
// possible.
|
// possible.
|
||||||
await this.send(
|
await this.send(
|
||||||
conv.wrapSend(
|
handleMessageSend(
|
||||||
// TODO: DESKTOP-724
|
// TODO: DESKTOP-724
|
||||||
// resetSession returns `Array<void>` which is incompatible with the
|
// resetSession returns `Array<void>` which is incompatible with the
|
||||||
// expected promise return values. `[]` is truthy and wrapSend assumes
|
// expected promise return values. `[]` is truthy and handleMessageSend
|
||||||
// it's a valid callback result type
|
// assumes it's a valid callback result type
|
||||||
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
|
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
|
||||||
// @ts-ignore
|
// @ts-ignore
|
||||||
window.textsecure.messaging.resetSession(
|
window.textsecure.messaging.resetSession(
|
||||||
|
@ -3601,7 +3614,7 @@ export class MessageModel extends window.Backbone.Model<MessageAttributesType> {
|
||||||
// GroupV2
|
// GroupV2
|
||||||
|
|
||||||
if (initialMessage.groupV2) {
|
if (initialMessage.groupV2) {
|
||||||
if (conversation.isGroupV1()) {
|
if (isGroupV1(conversation.attributes)) {
|
||||||
// If we received a GroupV2 message in a GroupV1 group, we migrate!
|
// If we received a GroupV2 message in a GroupV1 group, we migrate!
|
||||||
|
|
||||||
const { revision, groupChange } = initialMessage.groupV2;
|
const { revision, groupChange } = initialMessage.groupV2;
|
||||||
|
@ -3660,7 +3673,7 @@ export class MessageModel extends window.Backbone.Model<MessageAttributesType> {
|
||||||
e164: source,
|
e164: source,
|
||||||
uuid: sourceUuid,
|
uuid: sourceUuid,
|
||||||
})!;
|
})!;
|
||||||
const isGroupV2 = Boolean(initialMessage.groupV2);
|
const hasGroupV2Prop = Boolean(initialMessage.groupV2);
|
||||||
const isV1GroupUpdate =
|
const isV1GroupUpdate =
|
||||||
initialMessage.group &&
|
initialMessage.group &&
|
||||||
initialMessage.group.type !==
|
initialMessage.group.type !==
|
||||||
|
@ -3670,8 +3683,8 @@ export class MessageModel extends window.Backbone.Model<MessageAttributesType> {
|
||||||
// after applying the message's associated group changes.
|
// after applying the message's associated group changes.
|
||||||
if (
|
if (
|
||||||
type === 'incoming' &&
|
type === 'incoming' &&
|
||||||
!conversation.isPrivate() &&
|
!isDirectConversation(conversation.attributes) &&
|
||||||
isGroupV2 &&
|
hasGroupV2Prop &&
|
||||||
(conversation.get('left') ||
|
(conversation.get('left') ||
|
||||||
!conversation.hasMember(ourConversationId) ||
|
!conversation.hasMember(ourConversationId) ||
|
||||||
!conversation.hasMember(senderId))
|
!conversation.hasMember(senderId))
|
||||||
|
@ -3690,8 +3703,8 @@ export class MessageModel extends window.Backbone.Model<MessageAttributesType> {
|
||||||
// messages. We detect that via a missing 'members' field.
|
// messages. We detect that via a missing 'members' field.
|
||||||
if (
|
if (
|
||||||
type === 'incoming' &&
|
type === 'incoming' &&
|
||||||
!conversation.isPrivate() &&
|
!isDirectConversation(conversation.attributes) &&
|
||||||
!isGroupV2 &&
|
!hasGroupV2Prop &&
|
||||||
!isV1GroupUpdate &&
|
!isV1GroupUpdate &&
|
||||||
conversation.get('members') &&
|
conversation.get('members') &&
|
||||||
(conversation.get('left') || !conversation.hasMember(ourConversationId))
|
(conversation.get('left') || !conversation.hasMember(ourConversationId))
|
||||||
|
@ -3705,7 +3718,7 @@ export class MessageModel extends window.Backbone.Model<MessageAttributesType> {
|
||||||
|
|
||||||
// Because GroupV1 messages can now be multiplexed into GroupV2 conversations, we
|
// Because GroupV1 messages can now be multiplexed into GroupV2 conversations, we
|
||||||
// drop GroupV1 updates in GroupV2 groups.
|
// drop GroupV1 updates in GroupV2 groups.
|
||||||
if (isV1GroupUpdate && conversation.isGroupV2()) {
|
if (isV1GroupUpdate && isGroupV2(conversation.attributes)) {
|
||||||
window.log.warn(
|
window.log.warn(
|
||||||
`Received GroupV1 update in GroupV2 conversation ${conversation.idForLogging()}. Dropping.`
|
`Received GroupV1 update in GroupV2 conversation ${conversation.idForLogging()}. Dropping.`
|
||||||
);
|
);
|
||||||
|
@ -3793,7 +3806,7 @@ export class MessageModel extends window.Backbone.Model<MessageAttributesType> {
|
||||||
};
|
};
|
||||||
|
|
||||||
// GroupV1
|
// GroupV1
|
||||||
if (!isGroupV2 && dataMessage.group) {
|
if (!hasGroupV2Prop && dataMessage.group) {
|
||||||
const pendingGroupUpdate = [];
|
const pendingGroupUpdate = [];
|
||||||
const memberConversations: Array<ConversationModel> = await Promise.all(
|
const memberConversations: Array<ConversationModel> = await Promise.all(
|
||||||
dataMessage.group.membersE164.map((e164: string) =>
|
dataMessage.group.membersE164.map((e164: string) =>
|
||||||
|
@ -3920,7 +3933,7 @@ export class MessageModel extends window.Backbone.Model<MessageAttributesType> {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (sender.isMe()) {
|
if (isMe(sender.attributes)) {
|
||||||
attributes.left = true;
|
attributes.left = true;
|
||||||
pendingGroupUpdate.push(['left', 'You']);
|
pendingGroupUpdate.push(['left', 'You']);
|
||||||
} else {
|
} else {
|
||||||
|
@ -3962,7 +3975,7 @@ export class MessageModel extends window.Backbone.Model<MessageAttributesType> {
|
||||||
message.set({ expireTimer: dataMessage.expireTimer });
|
message.set({ expireTimer: dataMessage.expireTimer });
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!isGroupV2) {
|
if (!hasGroupV2Prop) {
|
||||||
if (message.isExpirationTimerUpdate()) {
|
if (message.isExpirationTimerUpdate()) {
|
||||||
message.set({
|
message.set({
|
||||||
expirationTimerUpdate: {
|
expirationTimerUpdate: {
|
||||||
|
@ -4023,7 +4036,7 @@ export class MessageModel extends window.Backbone.Model<MessageAttributesType> {
|
||||||
sourceUuid === window.textsecure.storage.user.getUuid()
|
sourceUuid === window.textsecure.storage.user.getUuid()
|
||||||
) {
|
) {
|
||||||
conversation.set({ profileSharing: true });
|
conversation.set({ profileSharing: true });
|
||||||
} else if (conversation.isPrivate()) {
|
} else if (isDirectConversation(conversation.attributes)) {
|
||||||
conversation.setProfileKey(profileKey);
|
conversation.setProfileKey(profileKey);
|
||||||
} else {
|
} else {
|
||||||
const localId = window.ConversationController.ensureContactIds({
|
const localId = window.ConversationController.ensureContactIds({
|
||||||
|
@ -4214,7 +4227,7 @@ export class MessageModel extends window.Backbone.Model<MessageAttributesType> {
|
||||||
}
|
}
|
||||||
|
|
||||||
// A sync'd message to ourself is automatically considered read/delivered
|
// A sync'd message to ourself is automatically considered read/delivered
|
||||||
if (isFirstRun && conversation.isMe()) {
|
if (isFirstRun && isMe(conversation.attributes)) {
|
||||||
message.set({
|
message.set({
|
||||||
read_by: conversation.getRecipients(),
|
read_by: conversation.getRecipients(),
|
||||||
delivered_to: conversation.getRecipients(),
|
delivered_to: conversation.getRecipients(),
|
||||||
|
|
|
@ -69,6 +69,7 @@ import {
|
||||||
REQUESTED_VIDEO_FRAMERATE,
|
REQUESTED_VIDEO_FRAMERATE,
|
||||||
} from '../calling/constants';
|
} from '../calling/constants';
|
||||||
import { notify } from './notify';
|
import { notify } from './notify';
|
||||||
|
import { getSendOptions } from '../util/getSendOptions';
|
||||||
|
|
||||||
const RINGRTC_HTTP_METHOD_TO_OUR_HTTP_METHOD: Map<
|
const RINGRTC_HTTP_METHOD_TO_OUR_HTTP_METHOD: Map<
|
||||||
HttpMethod,
|
HttpMethod,
|
||||||
|
@ -783,7 +784,7 @@ export class CallingClass {
|
||||||
}
|
}
|
||||||
|
|
||||||
const groupV2 = conversation.getGroupV2Info();
|
const groupV2 = conversation.getGroupV2Info();
|
||||||
const sendOptions = await conversation.getSendOptions();
|
const sendOptions = await getSendOptions(conversation.attributes);
|
||||||
if (!groupV2) {
|
if (!groupV2) {
|
||||||
window.log.error(
|
window.log.error(
|
||||||
'Unable to send group call update message for conversation that lacks groupV2 info'
|
'Unable to send group call update message for conversation that lacks groupV2 info'
|
||||||
|
@ -1408,7 +1409,7 @@ export class CallingClass {
|
||||||
): Promise<boolean> {
|
): Promise<boolean> {
|
||||||
const conversation = window.ConversationController.get(remoteUserId);
|
const conversation = window.ConversationController.get(remoteUserId);
|
||||||
const sendOptions = conversation
|
const sendOptions = conversation
|
||||||
? await conversation.getSendOptions()
|
? await getSendOptions(conversation.attributes)
|
||||||
: undefined;
|
: undefined;
|
||||||
|
|
||||||
if (!window.textsecure.messaging) {
|
if (!window.textsecure.messaging) {
|
||||||
|
|
|
@ -35,6 +35,10 @@ import { sleep } from '../util/sleep';
|
||||||
import { isMoreRecentThan } from '../util/timestamp';
|
import { isMoreRecentThan } from '../util/timestamp';
|
||||||
import { isStorageWriteFeatureEnabled } from '../storage/isFeatureEnabled';
|
import { isStorageWriteFeatureEnabled } from '../storage/isFeatureEnabled';
|
||||||
import { ourProfileKeyService } from './ourProfileKey';
|
import { ourProfileKeyService } from './ourProfileKey';
|
||||||
|
import {
|
||||||
|
ConversationTypes,
|
||||||
|
typeofConversation,
|
||||||
|
} from '../util/whatTypeOfConversation';
|
||||||
|
|
||||||
const {
|
const {
|
||||||
eraseStorageServiceStateFromConversations,
|
eraseStorageServiceStateFromConversations,
|
||||||
|
@ -152,22 +156,24 @@ async function generateManifest(
|
||||||
const identifier = new window.textsecure.protobuf.ManifestRecord.Identifier();
|
const identifier = new window.textsecure.protobuf.ManifestRecord.Identifier();
|
||||||
|
|
||||||
let storageRecord;
|
let storageRecord;
|
||||||
if (conversation.isMe()) {
|
|
||||||
|
const conversationType = typeofConversation(conversation.attributes);
|
||||||
|
if (conversationType === ConversationTypes.Me) {
|
||||||
storageRecord = new window.textsecure.protobuf.StorageRecord();
|
storageRecord = new window.textsecure.protobuf.StorageRecord();
|
||||||
// eslint-disable-next-line no-await-in-loop
|
// eslint-disable-next-line no-await-in-loop
|
||||||
storageRecord.account = await toAccountRecord(conversation);
|
storageRecord.account = await toAccountRecord(conversation);
|
||||||
identifier.type = ITEM_TYPE.ACCOUNT;
|
identifier.type = ITEM_TYPE.ACCOUNT;
|
||||||
} else if (conversation.isPrivate()) {
|
} else if (conversationType === ConversationTypes.Direct) {
|
||||||
storageRecord = new window.textsecure.protobuf.StorageRecord();
|
storageRecord = new window.textsecure.protobuf.StorageRecord();
|
||||||
// eslint-disable-next-line no-await-in-loop
|
// eslint-disable-next-line no-await-in-loop
|
||||||
storageRecord.contact = await toContactRecord(conversation);
|
storageRecord.contact = await toContactRecord(conversation);
|
||||||
identifier.type = ITEM_TYPE.CONTACT;
|
identifier.type = ITEM_TYPE.CONTACT;
|
||||||
} else if (conversation.isGroupV2()) {
|
} else if (conversationType === ConversationTypes.GroupV2) {
|
||||||
storageRecord = new window.textsecure.protobuf.StorageRecord();
|
storageRecord = new window.textsecure.protobuf.StorageRecord();
|
||||||
// eslint-disable-next-line no-await-in-loop
|
// eslint-disable-next-line no-await-in-loop
|
||||||
storageRecord.groupV2 = await toGroupV2Record(conversation);
|
storageRecord.groupV2 = await toGroupV2Record(conversation);
|
||||||
identifier.type = ITEM_TYPE.GROUPV2;
|
identifier.type = ITEM_TYPE.GROUPV2;
|
||||||
} else if (conversation.isGroupV1()) {
|
} else if (conversationType === ConversationTypes.GroupV1) {
|
||||||
storageRecord = new window.textsecure.protobuf.StorageRecord();
|
storageRecord = new window.textsecure.protobuf.StorageRecord();
|
||||||
// eslint-disable-next-line no-await-in-loop
|
// eslint-disable-next-line no-await-in-loop
|
||||||
storageRecord.groupV1 = await toGroupV1Record(conversation);
|
storageRecord.groupV1 = await toGroupV1Record(conversation);
|
||||||
|
|
|
@ -43,6 +43,7 @@ import {
|
||||||
set as setUniversalExpireTimer,
|
set as setUniversalExpireTimer,
|
||||||
} from '../util/universalExpireTimer';
|
} from '../util/universalExpireTimer';
|
||||||
import { ourProfileKeyService } from './ourProfileKey';
|
import { ourProfileKeyService } from './ourProfileKey';
|
||||||
|
import { isGroupV1, isGroupV2 } from '../util/whatTypeOfConversation';
|
||||||
|
|
||||||
const { updateConversation } = dataInterface;
|
const { updateConversation } = dataInterface;
|
||||||
|
|
||||||
|
@ -241,7 +242,7 @@ export async function toAccountRecord(
|
||||||
uuid: pinnedConversation.get('uuid'),
|
uuid: pinnedConversation.get('uuid'),
|
||||||
e164: pinnedConversation.get('e164'),
|
e164: pinnedConversation.get('e164'),
|
||||||
};
|
};
|
||||||
} else if (pinnedConversation.isGroupV1()) {
|
} else if (isGroupV1(pinnedConversation.attributes)) {
|
||||||
pinnedConversationRecord.identifier = 'legacyGroupId';
|
pinnedConversationRecord.identifier = 'legacyGroupId';
|
||||||
const groupId = pinnedConversation.get('groupId');
|
const groupId = pinnedConversation.get('groupId');
|
||||||
if (!groupId) {
|
if (!groupId) {
|
||||||
|
@ -252,7 +253,7 @@ export async function toAccountRecord(
|
||||||
pinnedConversationRecord.legacyGroupId = fromEncodedBinaryToArrayBuffer(
|
pinnedConversationRecord.legacyGroupId = fromEncodedBinaryToArrayBuffer(
|
||||||
groupId
|
groupId
|
||||||
);
|
);
|
||||||
} else if (pinnedConversation.isGroupV2()) {
|
} else if (isGroupV2(pinnedConversation.attributes)) {
|
||||||
pinnedConversationRecord.identifier = 'groupMasterKey';
|
pinnedConversationRecord.identifier = 'groupMasterKey';
|
||||||
const masterKey = pinnedConversation.get('masterKey');
|
const masterKey = pinnedConversation.get('masterKey');
|
||||||
if (!masterKey) {
|
if (!masterKey) {
|
||||||
|
@ -508,7 +509,7 @@ export async function mergeGroupV1Record(
|
||||||
// where the binary representation of its ID matches a v2 record in memory.
|
// where the binary representation of its ID matches a v2 record in memory.
|
||||||
// Here we ensure that the record we're about to process is GV1 otherwise
|
// Here we ensure that the record we're about to process is GV1 otherwise
|
||||||
// we drop the update.
|
// we drop the update.
|
||||||
if (conversation && !conversation.isGroupV1()) {
|
if (conversation && !isGroupV1(conversation.attributes)) {
|
||||||
throw new Error(
|
throw new Error(
|
||||||
`Record has group type mismatch ${conversation.idForLogging()}`
|
`Record has group type mismatch ${conversation.idForLogging()}`
|
||||||
);
|
);
|
||||||
|
@ -565,7 +566,7 @@ export async function mergeGroupV1Record(
|
||||||
|
|
||||||
let hasPendingChanges: boolean;
|
let hasPendingChanges: boolean;
|
||||||
|
|
||||||
if (conversation.isGroupV1()) {
|
if (isGroupV1(conversation.attributes)) {
|
||||||
addUnknownFields(groupV1Record, conversation);
|
addUnknownFields(groupV1Record, conversation);
|
||||||
|
|
||||||
hasPendingChanges = doesRecordHavePendingChanges(
|
hasPendingChanges = doesRecordHavePendingChanges(
|
||||||
|
@ -684,7 +685,7 @@ export async function mergeGroupV2Record(
|
||||||
const isFirstSync = !window.storage.get('storageFetchComplete');
|
const isFirstSync = !window.storage.get('storageFetchComplete');
|
||||||
const dropInitialJoinMessage = isFirstSync;
|
const dropInitialJoinMessage = isFirstSync;
|
||||||
|
|
||||||
if (conversation.isGroupV1()) {
|
if (isGroupV1(conversation.attributes)) {
|
||||||
// If we found a GroupV1 conversation from this incoming GroupV2 record, we need to
|
// If we found a GroupV1 conversation from this incoming GroupV2 record, we need to
|
||||||
// migrate it!
|
// migrate it!
|
||||||
|
|
||||||
|
|
11
ts/util/deprecated.ts
Normal file
11
ts/util/deprecated.ts
Normal file
|
@ -0,0 +1,11 @@
|
||||||
|
// Copyright 2021 Signal Messenger, LLC
|
||||||
|
// SPDX-License-Identifier: AGPL-3.0-only
|
||||||
|
|
||||||
|
import { getEnvironment, Environment } from '../environment';
|
||||||
|
import * as log from '../logging/log';
|
||||||
|
|
||||||
|
export function deprecated(message?: string): void {
|
||||||
|
if (getEnvironment() === Environment.Development) {
|
||||||
|
log.error(new Error(`This method is deprecated: ${message}`));
|
||||||
|
}
|
||||||
|
}
|
|
@ -40,9 +40,10 @@ export async function getSendOptions(
|
||||||
if (!conversation) {
|
if (!conversation) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
const {
|
const { sendMetadata: conversationSendMetadata } = await getSendOptions(
|
||||||
sendMetadata: conversationSendMetadata,
|
conversation.attributes,
|
||||||
} = await conversation.getSendOptions(options);
|
options
|
||||||
|
);
|
||||||
Object.assign(sendMetadata, conversationSendMetadata || {});
|
Object.assign(sendMetadata, conversationSendMetadata || {});
|
||||||
})
|
})
|
||||||
);
|
);
|
||||||
|
|
|
@ -38,6 +38,7 @@ import {
|
||||||
import { ContentClass } from '../textsecure.d';
|
import { ContentClass } from '../textsecure.d';
|
||||||
|
|
||||||
import { assert } from './assert';
|
import { assert } from './assert';
|
||||||
|
import { isGroupV2 } from './whatTypeOfConversation';
|
||||||
|
|
||||||
const ERROR_EXPIRED_OR_MISSING_DEVICES = 409;
|
const ERROR_EXPIRED_OR_MISSING_DEVICES = 409;
|
||||||
const ERROR_STALE_DEVICES = 410;
|
const ERROR_STALE_DEVICES = 410;
|
||||||
|
@ -116,7 +117,7 @@ export async function sendContentMessageToGroup({
|
||||||
|
|
||||||
if (
|
if (
|
||||||
ourConversation?.get('capabilities')?.senderKey &&
|
ourConversation?.get('capabilities')?.senderKey &&
|
||||||
conversation.isGroupV2()
|
isGroupV2(conversation.attributes)
|
||||||
) {
|
) {
|
||||||
try {
|
try {
|
||||||
return await sendToGroupViaSenderKey({
|
return await sendToGroupViaSenderKey({
|
||||||
|
@ -138,7 +139,7 @@ export async function sendContentMessageToGroup({
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
const groupId = conversation.isGroupV2()
|
const groupId = isGroupV2(conversation.attributes)
|
||||||
? conversation.get('groupId')
|
? conversation.get('groupId')
|
||||||
: undefined;
|
: undefined;
|
||||||
return window.textsecure.messaging.sendGroupProto(
|
return window.textsecure.messaging.sendGroupProto(
|
||||||
|
@ -191,7 +192,7 @@ export async function sendToGroupViaSenderKey(options: {
|
||||||
}
|
}
|
||||||
|
|
||||||
const groupId = conversation.get('groupId');
|
const groupId = conversation.get('groupId');
|
||||||
if (!groupId || !conversation.isGroupV2()) {
|
if (!groupId || !isGroupV2(conversation.attributes)) {
|
||||||
throw new Error(
|
throw new Error(
|
||||||
`sendToGroupViaSenderKey/${logId}: Missing groupId or group is not GV2`
|
`sendToGroupViaSenderKey/${logId}: Missing groupId or group is not GV2`
|
||||||
);
|
);
|
||||||
|
|
|
@ -2,11 +2,12 @@
|
||||||
// SPDX-License-Identifier: AGPL-3.0-only
|
// SPDX-License-Identifier: AGPL-3.0-only
|
||||||
|
|
||||||
import { ConversationModel } from '../models/conversations';
|
import { ConversationModel } from '../models/conversations';
|
||||||
|
import { isMe } from './whatTypeOfConversation';
|
||||||
|
|
||||||
export async function shouldRespondWithProfileKey(
|
export async function shouldRespondWithProfileKey(
|
||||||
sender: ConversationModel
|
sender: ConversationModel
|
||||||
): Promise<boolean> {
|
): Promise<boolean> {
|
||||||
if (sender.isMe() || !sender.getAccepted() || sender.isBlocked()) {
|
if (isMe(sender.attributes) || !sender.getAccepted() || sender.isBlocked()) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -2,6 +2,14 @@
|
||||||
// SPDX-License-Identifier: AGPL-3.0-only
|
// SPDX-License-Identifier: AGPL-3.0-only
|
||||||
|
|
||||||
import { ConversationAttributesType } from '../model-types.d';
|
import { ConversationAttributesType } from '../model-types.d';
|
||||||
|
import { base64ToArrayBuffer, fromEncodedBinaryToArrayBuffer } from '../Crypto';
|
||||||
|
|
||||||
|
export enum ConversationTypes {
|
||||||
|
Me = 'Me',
|
||||||
|
Direct = 'Direct',
|
||||||
|
GroupV1 = 'GroupV1',
|
||||||
|
GroupV2 = 'GroupV2',
|
||||||
|
}
|
||||||
|
|
||||||
export function isDirectConversation(
|
export function isDirectConversation(
|
||||||
conversationAttrs: ConversationAttributesType
|
conversationAttrs: ConversationAttributesType
|
||||||
|
@ -15,3 +23,56 @@ export function isMe(conversationAttrs: ConversationAttributesType): boolean {
|
||||||
const ourUuid = window.textsecure.storage.user.getUuid();
|
const ourUuid = window.textsecure.storage.user.getUuid();
|
||||||
return Boolean((e164 && e164 === ourNumber) || (uuid && uuid === ourUuid));
|
return Boolean((e164 && e164 === ourNumber) || (uuid && uuid === ourUuid));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export function isGroupV1(
|
||||||
|
conversationAttrs: ConversationAttributesType
|
||||||
|
): boolean {
|
||||||
|
const { groupId } = conversationAttrs;
|
||||||
|
if (!groupId) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
const buffer = fromEncodedBinaryToArrayBuffer(groupId);
|
||||||
|
return buffer.byteLength === window.Signal.Groups.ID_V1_LENGTH;
|
||||||
|
}
|
||||||
|
|
||||||
|
export function isGroupV2(
|
||||||
|
conversationAttrs: ConversationAttributesType
|
||||||
|
): boolean {
|
||||||
|
const { groupId, groupVersion = 0 } = conversationAttrs;
|
||||||
|
if (!groupId) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
return (
|
||||||
|
groupVersion === 2 &&
|
||||||
|
base64ToArrayBuffer(groupId).byteLength === window.Signal.Groups.ID_LENGTH
|
||||||
|
);
|
||||||
|
} catch (error) {
|
||||||
|
window.log.error('isGroupV2: Failed to process groupId in base64!');
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export function typeofConversation(
|
||||||
|
conversationAttrs: ConversationAttributesType
|
||||||
|
): ConversationTypes | undefined {
|
||||||
|
if (isMe(conversationAttrs)) {
|
||||||
|
return ConversationTypes.Me;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (isDirectConversation(conversationAttrs)) {
|
||||||
|
return ConversationTypes.Direct;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (isGroupV2(conversationAttrs)) {
|
||||||
|
return ConversationTypes.GroupV2;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (isGroupV1(conversationAttrs)) {
|
||||||
|
return ConversationTypes.GroupV1;
|
||||||
|
}
|
||||||
|
|
||||||
|
return undefined;
|
||||||
|
}
|
||||||
|
|
|
@ -15,6 +15,12 @@ import { maybeParseUrl } from '../util/url';
|
||||||
import { addReportSpamJob } from '../jobs/helpers/addReportSpamJob';
|
import { addReportSpamJob } from '../jobs/helpers/addReportSpamJob';
|
||||||
import { reportSpamJobQueue } from '../jobs/reportSpamJobQueue';
|
import { reportSpamJobQueue } from '../jobs/reportSpamJobQueue';
|
||||||
import { GroupNameCollisionsWithIdsByTitle } from '../util/groupMemberNameCollisions';
|
import { GroupNameCollisionsWithIdsByTitle } from '../util/groupMemberNameCollisions';
|
||||||
|
import {
|
||||||
|
isDirectConversation,
|
||||||
|
isGroupV1,
|
||||||
|
isGroupV2,
|
||||||
|
isMe,
|
||||||
|
} from '../util/whatTypeOfConversation';
|
||||||
|
|
||||||
type GetLinkPreviewImageResult = {
|
type GetLinkPreviewImageResult = {
|
||||||
data: ArrayBuffer;
|
data: ArrayBuffer;
|
||||||
|
@ -486,7 +492,7 @@ Whisper.ConversationView = Whisper.View.extend({
|
||||||
onResetSession: () => this.endSession(),
|
onResetSession: () => this.endSession(),
|
||||||
onSearchInConversation: () => {
|
onSearchInConversation: () => {
|
||||||
const { searchInConversation } = window.reduxActions.search;
|
const { searchInConversation } = window.reduxActions.search;
|
||||||
const name = this.model.isMe()
|
const name = isMe(this.model.attributes)
|
||||||
? window.i18n('noteToSelf')
|
? window.i18n('noteToSelf')
|
||||||
: this.model.getTitle();
|
: this.model.getTitle();
|
||||||
searchInConversation(this.model.id, name);
|
searchInConversation(this.model.id, name);
|
||||||
|
@ -1281,7 +1287,7 @@ Whisper.ConversationView = Whisper.View.extend({
|
||||||
async startMigrationToGV2(): Promise<void> {
|
async startMigrationToGV2(): Promise<void> {
|
||||||
const logId = this.model.idForLogging();
|
const logId = this.model.idForLogging();
|
||||||
|
|
||||||
if (!this.model.isGroupV1()) {
|
if (!isGroupV1(this.model.attributes)) {
|
||||||
throw new Error(
|
throw new Error(
|
||||||
`startMigrationToGV2/${logId}: Cannot start, not a GroupV1 group`
|
`startMigrationToGV2/${logId}: Cannot start, not a GroupV1 group`
|
||||||
);
|
);
|
||||||
|
@ -2682,7 +2688,7 @@ Whisper.ConversationView = Whisper.View.extend({
|
||||||
|
|
||||||
let model = providedMembers || this.model.contactCollection;
|
let model = providedMembers || this.model.contactCollection;
|
||||||
|
|
||||||
if (!providedMembers && this.model.isGroupV2()) {
|
if (!providedMembers && isGroupV2(this.model.attributes)) {
|
||||||
model = new Whisper.GroupConversationCollection(
|
model = new Whisper.GroupConversationCollection(
|
||||||
this.model.get('membersV2').map(({ conversationId, role }: any) => ({
|
this.model.get('membersV2').map(({ conversationId, role }: any) => ({
|
||||||
conversation: window.ConversationController.get(conversationId),
|
conversation: window.ConversationController.get(conversationId),
|
||||||
|
@ -2738,7 +2744,7 @@ Whisper.ConversationView = Whisper.View.extend({
|
||||||
showSafetyNumber(id: any) {
|
showSafetyNumber(id: any) {
|
||||||
let conversation;
|
let conversation;
|
||||||
|
|
||||||
if (!id && this.model.isPrivate()) {
|
if (!id && isDirectConversation(this.model.attributes)) {
|
||||||
// eslint-disable-next-line prefer-destructuring
|
// eslint-disable-next-line prefer-destructuring
|
||||||
conversation = this.model;
|
conversation = this.model;
|
||||||
} else {
|
} else {
|
||||||
|
@ -3786,19 +3792,22 @@ Whisper.ConversationView = Whisper.View.extend({
|
||||||
ToastView = Whisper.InvalidConversationToast;
|
ToastView = Whisper.InvalidConversationToast;
|
||||||
}
|
}
|
||||||
if (
|
if (
|
||||||
this.model.isPrivate() &&
|
isDirectConversation(this.model.attributes) &&
|
||||||
(window.storage.isBlocked(this.model.get('e164')) ||
|
(window.storage.isBlocked(this.model.get('e164')) ||
|
||||||
window.storage.isUuidBlocked(this.model.get('uuid')))
|
window.storage.isUuidBlocked(this.model.get('uuid')))
|
||||||
) {
|
) {
|
||||||
ToastView = Whisper.BlockedToast;
|
ToastView = Whisper.BlockedToast;
|
||||||
}
|
}
|
||||||
if (
|
if (
|
||||||
!this.model.isPrivate() &&
|
!isDirectConversation(this.model.attributes) &&
|
||||||
window.storage.isGroupBlocked(this.model.get('groupId'))
|
window.storage.isGroupBlocked(this.model.get('groupId'))
|
||||||
) {
|
) {
|
||||||
ToastView = Whisper.BlockedGroupToast;
|
ToastView = Whisper.BlockedGroupToast;
|
||||||
}
|
}
|
||||||
if (!this.model.isPrivate() && this.model.get('left')) {
|
if (
|
||||||
|
!isDirectConversation(this.model.attributes) &&
|
||||||
|
this.model.get('left')
|
||||||
|
) {
|
||||||
ToastView = Whisper.LeftGroupToast;
|
ToastView = Whisper.LeftGroupToast;
|
||||||
}
|
}
|
||||||
if (messageText && messageText.length > MAX_MESSAGE_BODY_LENGTH) {
|
if (messageText && messageText.length > MAX_MESSAGE_BODY_LENGTH) {
|
||||||
|
|
Loading…
Reference in a new issue