fix: allow invite to be promote, and handle recipient side too

pull/3052/head
Audric Ackermann 6 months ago
parent 07930d4e5e
commit 8644db64bc
No known key found for this signature in database

@ -224,7 +224,11 @@ const ResendInviteButton = ({
buttonType={SessionButtonType.Solid}
text={window.i18n('resend')}
onClick={() => {
void GroupInvite.addJob({ groupPk, member: pubkey });
void GroupInvite.addJob({
groupPk,
member: pubkey,
inviteAsAdmin: window.sessionFeatureFlags.useGroupV2InviteAsAdmin,
});
}}
/>
);

@ -206,7 +206,7 @@ export const UpdateGroupMembersDialog = (props: Props) => {
}
if (groupAdmins?.includes(member)) {
if (PubKey.is03Pubkey(conversationId)) {
window?.log?.warn(`User ${member} cannot be removed as they are adn admin.`);
window?.log?.warn(`User ${member} cannot be removed as they are an admin.`);
return;
}
ToastUtils.pushCannotRemoveCreatorFromGroup();

@ -1,4 +1,4 @@
import { isEmpty, isNil } from 'lodash';
import { isNil } from 'lodash';
import {
ConversationNotificationSettingType,
READ_MESSAGE_STATE,
@ -47,16 +47,12 @@ import { urlToBlob } from '../types/attachments/VisualAttachment';
import { encryptProfile } from '../util/crypto/profileEncrypter';
import { ReleasedFeatures } from '../util/releaseFeature';
import { Storage, setLastProfileUpdateTimestamp } from '../util/storage';
import {
MetaGroupWrapperActions,
UserGroupsWrapperActions,
} from '../webworker/workers/browser/libsession_worker_interface';
import { UserGroupsWrapperActions } from '../webworker/workers/browser/libsession_worker_interface';
import { ConversationInteractionStatus, ConversationInteractionType } from './types';
import { BlockedNumberController } from '../util';
import { LocalizerComponentProps, LocalizerToken } from '../types/localizer';
import { sendInviteResponseToGroup } from '../session/sending/group/GroupInviteResponse';
import { NetworkTime } from '../util/NetworkTime';
import { GroupSync } from '../session/utils/job_runners/jobs/GroupSyncJob';
export async function copyPublicKeyByConvoId(convoId: string) {
if (OpenGroupUtils.isOpenGroupV2(convoId)) {
@ -136,17 +132,6 @@ export const handleAcceptConversationRequest = async ({ convoId }: { convoId: st
if (!previousIsApproved) {
await sendInviteResponseToGroup({ groupPk: convoId });
}
const refreshed = await UserGroupsWrapperActions.getGroup(convoId);
// if we are admin, we also need to accept it and mark ourselves as such
const weAreAdmin = refreshed && !isEmpty(refreshed.secretKey);
if (weAreAdmin) {
await MetaGroupWrapperActions.memberSetPromotionAccepted(
convoId,
UserUtils.getOurPubKeyStrFromCache()
);
await GroupSync.queueNewJobIfNeeded(convoId);
}
window.log.info(
`handleAcceptConversationRequest: first poll for group ${ed25519Str(convoId)} happened, we should have encryption keys now`

@ -42,6 +42,7 @@ export interface GroupInvitePersistedData extends PersistedJobData {
jobType: 'GroupInviteJobType';
groupPk: GroupPubkeyType;
member: PubkeyType;
inviteAsAdmin: boolean;
}
export interface GroupPromotePersistedData extends PersistedJobData {

@ -28,6 +28,7 @@ const defaultMaxAttempts = 1;
type JobExtraArgs = {
groupPk: GroupPubkeyType;
member: PubkeyType;
inviteAsAdmin: boolean;
};
export function shouldAddJob(args: JobExtraArgs) {
@ -46,11 +47,12 @@ const invitesFailed = new Map<
}
>();
async function addJob({ groupPk, member }: JobExtraArgs) {
if (shouldAddJob({ groupPk, member })) {
async function addJob({ groupPk, member, inviteAsAdmin }: JobExtraArgs) {
if (shouldAddJob({ groupPk, member, inviteAsAdmin })) {
const groupInviteJob = new GroupInviteJob({
groupPk,
member,
inviteAsAdmin,
nextAttemptTimestamp: Date.now(),
});
window.log.debug(`addGroupInviteJob: adding group invite for ${groupPk}:${member} `);
@ -123,11 +125,12 @@ class GroupInviteJob extends PersistedJob<GroupInvitePersistedData> {
constructor({
groupPk,
member,
inviteAsAdmin,
nextAttemptTimestamp,
maxAttempts,
currentRetry,
identifier,
}: Pick<GroupInvitePersistedData, 'groupPk' | 'member'> &
}: Pick<GroupInvitePersistedData, 'groupPk' | 'member' | 'inviteAsAdmin'> &
Partial<
Pick<
GroupInvitePersistedData,
@ -143,6 +146,7 @@ class GroupInviteJob extends PersistedJob<GroupInvitePersistedData> {
identifier: identifier || v4(),
member,
groupPk,
inviteAsAdmin,
delayBetweenRetries: defaultMsBetweenRetries,
maxAttempts: isNumber(maxAttempts) ? maxAttempts : defaultMaxAttempts,
nextAttemptTimestamp: nextAttemptTimestamp || Date.now() + defaultMsBetweenRetries,
@ -151,10 +155,10 @@ class GroupInviteJob extends PersistedJob<GroupInvitePersistedData> {
}
public async run(): Promise<RunJobResult> {
const { groupPk, member, jobType, identifier } = this.persistedData;
const { groupPk, member, inviteAsAdmin, jobType, identifier } = this.persistedData;
window.log.info(
`running job ${jobType} with groupPk:"${groupPk}" member: ${member} id:"${identifier}" `
`running job ${jobType} with groupPk:"${groupPk}" member:${member} inviteAsAdmin:${inviteAsAdmin} id:"${identifier}" `
);
const group = await UserGroupsWrapperActions.getGroup(groupPk);
if (!group || !group.secretKey || !group.name) {
@ -167,7 +171,7 @@ class GroupInviteJob extends PersistedJob<GroupInvitePersistedData> {
}
let failed = true;
try {
const inviteDetails = window.sessionFeatureFlags.useGroupV2InviteAsAdmin
const inviteDetails = inviteAsAdmin
? await SnodeGroupSignature.getGroupPromoteMessage({
groupName: group.name,
member,
@ -200,6 +204,16 @@ class GroupInviteJob extends PersistedJob<GroupInvitePersistedData> {
);
try {
await MetaGroupWrapperActions.memberSetInvited(groupPk, member, failed);
// Depending on this field, we either send an invite or an invite-as-admin message.
// When we do send an invite-as-admin we also need to update the promoted state, so that the invited members
// knows he needs to accept the promotion when accepting the invite
if (inviteAsAdmin) {
if (failed) {
await MetaGroupWrapperActions.memberSetPromotionFailed(groupPk, member);
} else {
await MetaGroupWrapperActions.memberSetPromotionSent(groupPk, member);
}
}
} catch (e) {
window.log.warn('GroupInviteJob memberSetInvited failed with', e.message);
}

@ -245,7 +245,11 @@ const initNewGroupInWrapper = createAsyncThunk(
// can update the group wrapper with a failed state if a message fails to be sent.
for (let index = 0; index < membersFromWrapper.length; index++) {
const member = membersFromWrapper[index];
await GroupInvite.addJob({ member: member.pubkeyHex, groupPk });
await GroupInvite.addJob({
member: member.pubkeyHex,
groupPk,
inviteAsAdmin: window.sessionFeatureFlags.useGroupV2InviteAsAdmin,
});
}
await openConversationWithMessages({ conversationKey: groupPk, messageId: null });
@ -773,7 +777,12 @@ async function handleMemberAddedFromUI({
}
// schedule send invite details, auth signature, etc. to the new users
await scheduleGroupInviteJobs(groupPk, withHistory, withoutHistory);
await scheduleGroupInviteJobs(
groupPk,
withHistory,
withoutHistory,
window.sessionFeatureFlags.useGroupV2InviteAsAdmin
);
await LibSessionUtil.saveDumpsToDb(groupPk);
convo.set({
@ -1444,14 +1453,15 @@ export const groupReducer = metaGroupSlice.reducer;
async function scheduleGroupInviteJobs(
groupPk: GroupPubkeyType,
withHistory: Array<PubkeyType>,
withoutHistory: Array<PubkeyType>
withoutHistory: Array<PubkeyType>,
inviteAsAdmin: boolean
) {
for (let index = 0; index < withoutHistory.length; index++) {
const member = withoutHistory[index];
await GroupInvite.addJob({ groupPk, member });
await GroupInvite.addJob({ groupPk, member, inviteAsAdmin });
}
for (let index = 0; index < withHistory.length; index++) {
const member = withHistory[index];
await GroupInvite.addJob({ groupPk, member });
await GroupInvite.addJob({ groupPk, member, inviteAsAdmin });
}
}

Loading…
Cancel
Save