feat: add building and sending of invite messages
parent
6ed74c9807
commit
d7608c42b6
@ -0,0 +1,51 @@
|
|||||||
|
import { GroupMemberGet, GroupPubkeyType, Uint8ArrayLen64 } from 'libsession_util_nodejs';
|
||||||
|
import { compact } from 'lodash';
|
||||||
|
import { MetaGroupWrapperActions } from '../../../webworker/workers/browser/libsession_worker_interface';
|
||||||
|
import { GetNetworkTime } from '../../apis/snode_api/getNetworkTime';
|
||||||
|
import { GroupUpdateInviteMessage } from '../../messages/outgoing/controlMessage/group_v2/to_user/GroupUpdateInviteMessage';
|
||||||
|
import { UserUtils } from '../../utils';
|
||||||
|
import { getSodiumRenderer } from '../MessageEncrypter';
|
||||||
|
|
||||||
|
export async function getGroupInvitesMessages({
|
||||||
|
groupName,
|
||||||
|
membersFromWrapper,
|
||||||
|
secretKey,
|
||||||
|
groupPk,
|
||||||
|
}: {
|
||||||
|
membersFromWrapper: Array<GroupMemberGet>;
|
||||||
|
groupName: string;
|
||||||
|
secretKey: Uint8ArrayLen64; // len 64
|
||||||
|
groupPk: GroupPubkeyType;
|
||||||
|
}) {
|
||||||
|
const sodium = await getSodiumRenderer();
|
||||||
|
const timestamp = GetNetworkTime.getNowWithNetworkOffset();
|
||||||
|
|
||||||
|
const inviteDetails = compact(
|
||||||
|
await Promise.all(
|
||||||
|
membersFromWrapper.map(async ({ pubkeyHex: member }) => {
|
||||||
|
if (UserUtils.isUsFromCache(member)) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
const tosign = `INVITE${member}${timestamp}`;
|
||||||
|
|
||||||
|
// Note: as the signature is built with the timestamp here, we cannot override the timestamp later on the sending pipeline
|
||||||
|
const adminSignature = sodium.crypto_sign_detached(tosign, secretKey);
|
||||||
|
console.info(`before makeSwarmSubAccount ${groupPk}:${member}`);
|
||||||
|
const memberAuthData = await MetaGroupWrapperActions.makeSwarmSubAccount(groupPk, member);
|
||||||
|
debugger;
|
||||||
|
console.info(`after makeSwarmSubAccount ${groupPk}:${member}`);
|
||||||
|
|
||||||
|
const invite = new GroupUpdateInviteMessage({
|
||||||
|
groupName,
|
||||||
|
groupPk,
|
||||||
|
timestamp,
|
||||||
|
adminSignature,
|
||||||
|
memberAuthData,
|
||||||
|
});
|
||||||
|
|
||||||
|
return { member, invite };
|
||||||
|
})
|
||||||
|
)
|
||||||
|
);
|
||||||
|
return inviteDetails;
|
||||||
|
}
|
@ -0,0 +1,37 @@
|
|||||||
|
import { isEmpty } from 'lodash';
|
||||||
|
import { PubKey } from '../../types';
|
||||||
|
import { PreConditionFailed } from '../../utils/errors';
|
||||||
|
|
||||||
|
function checkUin8tArrayOrThrow({
|
||||||
|
context,
|
||||||
|
data,
|
||||||
|
expectedLength,
|
||||||
|
varName,
|
||||||
|
}: {
|
||||||
|
data: Uint8Array;
|
||||||
|
expectedLength: number;
|
||||||
|
varName: string;
|
||||||
|
context: string;
|
||||||
|
}) {
|
||||||
|
if (isEmpty(data) || data.length !== expectedLength) {
|
||||||
|
throw new PreConditionFailed(
|
||||||
|
`${varName} length should be ${expectedLength} for ctx:"${context}"`
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function checkArrayHaveOnly05Pubkeys({
|
||||||
|
context,
|
||||||
|
arr,
|
||||||
|
varName,
|
||||||
|
}: {
|
||||||
|
arr: Array<string>;
|
||||||
|
varName: string;
|
||||||
|
context: string;
|
||||||
|
}) {
|
||||||
|
if (arr.some(v => !PubKey.is05Pubkey(v))) {
|
||||||
|
throw new PreConditionFailed(`${varName} did not contain only 05 pubkeys for ctx:"${context}"`);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export const Preconditions = { checkUin8tArrayOrThrow, checkArrayHaveOnly05Pubkeys };
|
Loading…
Reference in New Issue