Merge pull request #1223 from Bilb/various-closed-group-fixes

* fix display name and avatar to be shown when message is coming from a secondary device
* fix show of expiretimer in the group conversation when it is for it.
* fix a bug creating empty conversation when sync closed group message is received on secondary device
* trigger an expiretimer update message to all members when updating a group.
* trigger an expiretimer update message when sending back group details (after a requestGroupInfo)
pull/1227/head
Audric Ackermann 5 years ago committed by GitHub
commit d5cfcf9edc
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23

@ -626,24 +626,24 @@
window.doUpdateGroup = async (groupId, groupName, members, avatar) => { window.doUpdateGroup = async (groupId, groupName, members, avatar) => {
const ourKey = textsecure.storage.user.getNumber(); const ourKey = textsecure.storage.user.getNumber();
const convo = await ConversationController.getOrCreateAndWait(
groupId,
'group'
);
const ev = { const ev = {
groupDetails: { groupDetails: {
id: groupId, id: groupId,
name: groupName, name: groupName,
members, members,
active: true, active: true,
expireTimer: 0, expireTimer: convo.get('expireTimer'),
avatar: '', avatar,
is_medium_group: false, is_medium_group: false,
}, },
confirm: () => {}, confirm: () => {},
}; };
const convo = await ConversationController.getOrCreateAndWait(
groupId,
'group'
);
const recipients = _.union(convo.get('members'), members); const recipients = _.union(convo.get('members'), members);
await window.NewReceiver.onGroupReceived(ev); await window.NewReceiver.onGroupReceived(ev);

@ -1901,9 +1901,20 @@
); );
await this.sendClosedGroupMessageWithSync(groupUpdateMessage, recipients); await this.sendClosedGroupMessageWithSync(groupUpdateMessage, recipients);
const expireUpdate = {
timestamp: Date.now(),
expireTimer: this.get('expireTimer'),
groupId: this.get('id'),
};
const expirationTimerMessage = new libsession.Messages.Outgoing.ExpirationTimerUpdateMessage(
expireUpdate
);
await libsession.getMessageQueue().sendToGroup(expirationTimerMessage);
}, },
sendGroupInfo(recipient) { async sendGroupInfo(recipient) {
// Only send group info if we're a closed group and we haven't left // Only send group info if we're a closed group and we haven't left
if (this.isClosedGroup() && !this.get('left')) { if (this.isClosedGroup() && !this.get('left')) {
const updateParams = { const updateParams = {
@ -1922,10 +1933,28 @@
window.console.warn('sendGroupInfo invalid pubkey:', recipient); window.console.warn('sendGroupInfo invalid pubkey:', recipient);
return; return;
} }
libsession
try {
await libsession
.getMessageQueue() .getMessageQueue()
.send(recipientPubKey, groupUpdateMessage) .send(recipientPubKey, groupUpdateMessage);
.catch(log.error);
const expireUpdate = {
timestamp: Date.now(),
expireTimer: this.get('expireTimer'),
groupId: this.get('id'),
};
const expirationTimerMessage = new libsession.Messages.Outgoing.ExpirationTimerUpdateMessage(
expireUpdate
);
await libsession
.getMessageQueue()
.sendUsingMultiDevice(recipientPubKey, expirationTimerMessage);
} catch (e) {
log.error('Failed to send groupInfo:', e);
}
} }
}, },

@ -1096,7 +1096,7 @@
attachments, attachments,
preview, preview,
quote, quote,
lokiProfile: this.getOurProfile(), lokiProfile: this.conversation.getOurProfile(),
}); });
// Special-case the self-send case - we send only a sync message // Special-case the self-send case - we send only a sync message

@ -222,7 +222,7 @@ export class SessionGroupSettings extends React.Component<Props, any> {
const leaveGroupString = isPublic const leaveGroupString = isPublic
? window.i18n('leaveOpenGroup') ? window.i18n('leaveOpenGroup')
: isKickedFromGroup : isKickedFromGroup
? window.i18n('youGotKickedFromThisGroup') ? window.i18n('youGotKickedFromGroup')
: window.i18n('leaveClosedGroup'); : window.i18n('leaveClosedGroup');
const disappearingMessagesOptions = timerOptions.map(option => { const disappearingMessagesOptions = timerOptions.map(option => {

@ -70,12 +70,20 @@ export async function updateProfile(
newProfile.avatar = null; newProfile.avatar = null;
} }
await conversation.setLokiProfile(newProfile); const allUserDevices = await MultiDeviceProtocol.getAllDevices(
conversation.id
);
const { ConversationController } = window;
if (conversation.isSecondaryDevice()) { await Promise.all(
const primaryConversation = await conversation.getPrimaryConversation(); allUserDevices.map(async device => {
await primaryConversation.setLokiProfile(newProfile); const conv = await ConversationController.getOrCreateAndWait(
} device.key,
'private'
);
await conv.setLokiProfile(newProfile);
})
);
} }
function cleanAttachment(attachment: any) { function cleanAttachment(attachment: any) {
@ -298,15 +306,7 @@ export async function handleDataMessage(
} }
const source = envelope.senderIdentity || senderPubKey; const source = envelope.senderIdentity || senderPubKey;
const ownDevice = await MultiDeviceProtocol.isOurDevice(source);
const isOwnDevice = async (device: string) => {
const pubKey = new PubKey(device);
const allDevices = await MultiDeviceProtocol.getAllDevices(pubKey);
return allDevices.some(d => d.isEqual(pubKey));
};
const ownDevice = await isOwnDevice(source);
const ownMessage = conversation.isMediumGroup() && ownDevice; const ownMessage = conversation.isMediumGroup() && ownDevice;
@ -413,6 +413,7 @@ interface MessageCreationData {
isRss: boolean; isRss: boolean;
source: boolean; source: boolean;
serverId: string; serverId: string;
message: any;
// Needed for synced outgoing messages // Needed for synced outgoing messages
unidentifiedStatus: any; // ??? unidentifiedStatus: any; // ???
@ -430,9 +431,13 @@ export function initIncomingMessage(data: MessageCreationData): MessageModel {
isRss, isRss,
source, source,
serverId, serverId,
message,
} = data; } = data;
const type = 'incoming'; const type = 'incoming';
const messageGroupId = message?.group?.id;
const groupId =
messageGroupId && messageGroupId.length > 0 ? messageGroupId : null;
const messageData: any = { const messageData: any = {
source, source,
@ -440,7 +445,7 @@ export function initIncomingMessage(data: MessageCreationData): MessageModel {
serverId, // + (not present below in `createSentMessage`) serverId, // + (not present below in `createSentMessage`)
sent_at: timestamp, sent_at: timestamp,
received_at: receivedAt || Date.now(), received_at: receivedAt || Date.now(),
conversationId: source, conversationId: groupId ?? source,
unidentifiedDeliveryReceived, // + unidentifiedDeliveryReceived, // +
type, type,
direction: 'incoming', // + direction: 'incoming', // +
@ -621,6 +626,7 @@ export async function handleMessageEvent(event: MessageEvent): Promise<void> {
dropping an admin only update from a non admin, ... dropping an admin only update from a non admin, ...
*/ */
conversationId = message.group.id; conversationId = message.group.id;
const shouldReturn = await preprocessGroupMessage( const shouldReturn = await preprocessGroupMessage(
source, source,
message.group, message.group,

@ -13,18 +13,15 @@ async function handleGroups(
group: any, group: any,
source: any source: any
): Promise<any> { ): Promise<any> {
const textsecure = window.textsecure;
const GROUP_TYPES = SignalService.GroupContext.Type; const GROUP_TYPES = SignalService.GroupContext.Type;
// TODO: this should be primary device id!
const ourNumber = textsecure.storage.user.getNumber();
let groupUpdate = null; let groupUpdate = null;
// conversation attributes // conversation attributes
const attributes: any = { const attributes: any = {
type: 'group', type: 'group',
groupId: group.id, groupId: group.id,
...conversation.attributes,
}; };
const oldMembers = conversation.get('members'); const oldMembers = conversation.get('members');
@ -54,15 +51,21 @@ async function handleGroups(
// Check if anyone got kicked: // Check if anyone got kicked:
const removedMembers = _.difference(oldMembers, attributes.members); const removedMembers = _.difference(oldMembers, attributes.members);
const isOurDeviceMap = await Promise.all(
removedMembers.map(async member =>
MultiDeviceProtocol.isOurDevice(member)
)
);
const ourDeviceWasRemoved = isOurDeviceMap.includes(true);
if (removedMembers.includes(ourNumber)) { if (ourDeviceWasRemoved) {
groupUpdate.kicked = 'You'; groupUpdate.kicked = 'You';
attributes.isKickedFromGroup = true; attributes.isKickedFromGroup = true;
} else if (removedMembers.length) { } else if (removedMembers.length) {
groupUpdate.kicked = removedMembers; groupUpdate.kicked = removedMembers;
} }
} else if (group.type === GROUP_TYPES.QUIT) { } else if (group.type === GROUP_TYPES.QUIT) {
if (source === ourNumber) { if (await MultiDeviceProtocol.isOurDevice(source)) {
attributes.left = true; attributes.left = true;
groupUpdate = { left: 'You' }; groupUpdate = { left: 'You' };
} else { } else {

@ -66,6 +66,8 @@ export abstract class ClosedGroupUpdateMessage extends ClosedGroupMessage {
groupContext.admins = this.admins; groupContext.admins = this.admins;
} }
groupContext.avatar = this.avatar;
return groupContext; return groupContext;
} }
} }

@ -8,7 +8,9 @@ import ByteBuffer from 'bytebuffer';
*/ */
export function convertToTS(object: any): any { export function convertToTS(object: any): any {
// No idea why js `ByteBuffer` and ts `ByteBuffer` differ ... // No idea why js `ByteBuffer` and ts `ByteBuffer` differ ...
if ( if (object instanceof Uint8Array) {
return object;
} else if (
object && object &&
object.constructor && object.constructor &&
object.constructor.name === 'ByteBuffer' object.constructor.name === 'ByteBuffer'

Loading…
Cancel
Save