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.
89 lines
3.1 KiB
TypeScript
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,
|
|
};
|