You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
session-desktop/ts/receiver/libsession/handleLibSessionMessage.ts

89 lines
3.1 KiB
TypeScript

import { EncryptionDomain, GroupPubkeyType, PubkeyType } from 'libsession_util_nodejs';
import { isNumber, toNumber } from 'lodash';
import { ConvoHub } from '../../session/conversations';
import { LibSodiumWrappers, WithLibSodiumWrappers } from '../../session/crypto';
import { PubKey } from '../../session/types';
import { DecryptionFailed, InvalidMessage } from '../../session/utils/errors';
import { assertUnreachable } from '../../types/sqlSharedTypes';
import {
MetaGroupWrapperActions,
UserGroupsWrapperActions,
} from '../../webworker/workers/browser/libsession_worker_interface';
/**
* Logic for handling the `groupKicked` `LibSessionMessage`, this message should only be processed if it was
* sent after the user joined the group (while unlikely, it's possible to receive this message when re-joining a group after
* previously being kicked in which case we don't want to delete the data).
*/
async function handleLibSessionKickedMessage({
decrypted,
sodium,
ourPk,
groupPk,
}: {
decrypted: Uint8Array;
sodium: LibSodiumWrappers;
ourPk: PubkeyType;
groupPk: GroupPubkeyType;
}) {
const pubkeyBytesCount = PubKey.PUBKEY_BYTE_COUNT_NO_PREFIX;
if (decrypted.length <= pubkeyBytesCount) {
throw new DecryptionFailed('DecryptionFailed for handleLibSessionKickedMessage');
}
// pubkey without prefix should be at the start, and current_gen as a string the rest of the content.
const pubkeyEmbedded = decrypted.slice(0, pubkeyBytesCount);
const currentGenStr = sodium.to_string(decrypted.slice(pubkeyBytesCount));
const currentGenEmbedded = toNumber(currentGenStr);
if (!isNumber(currentGenEmbedded)) {
throw new InvalidMessage('currentGenEmbedded not a number');
}
const pubkeyEmbeddedHex = sodium.to_hex(pubkeyEmbedded);
if (ourPk.slice(2) !== pubkeyEmbeddedHex) {
throw new InvalidMessage('embedded pubkey does not match current user pubkey');
}
const currentGenFromWrapper = await MetaGroupWrapperActions.keyGetCurrentGen(groupPk);
if (currentGenEmbedded < currentGenFromWrapper) {
throw new InvalidMessage('currentgen in wrapper is higher than the one in the message ');
}
const groupInUserGroup = await UserGroupsWrapperActions.getGroup(groupPk);
const inviteWasPending = groupInUserGroup?.invitePending || false;
await ConvoHub.use().deleteGroup(groupPk, {
sendLeaveMessage: false,
fromSyncMessage: false,
deletionType: inviteWasPending ? 'doNotKeep' : 'keepAsKicked',
deleteAllMessagesOnSwarm: false,
forceDestroyForAllMembers: false,
clearFetchedHashes: true,
});
}
async function handleLibSessionMessage(
opts: {
decrypted: Uint8Array;
domain: EncryptionDomain;
ourPk: PubkeyType;
groupPk: GroupPubkeyType;
} & WithLibSodiumWrappers
) {
switch (opts.domain) {
case 'SessionGroupKickedMessage':
await handleLibSessionKickedMessage(opts);
return;
default:
assertUnreachable(
opts.domain,
`handleLibSessionMessage unhandled case for domain: ${opts.domain}`
);
break;
}
}
export const LibsessionMessageHandler = {
handleLibSessionMessage,
};