fix: fallback when we have an invite state without who invited us

pull/2963/head
Audric Ackermann 2 years ago
parent e5c76d3b70
commit ba513b29ca

@ -509,6 +509,7 @@
"respondingToRequestWarning": "Sending a message to this user will automatically accept their message request and reveal your Session ID.",
"respondingToGroupRequestWarning": "Sending a message to this group will automatically accept the group invite.",
"userInvitedYouToGroup": "<b>$name$</b> invited you to join <b>$groupName$</b>.",
"youWereInvitedToGroup": "<b>You</b> were invited to join <b>$groupName$</b>.",
"hideRequestBanner": "Hide Message Request Banner",
"openMessageRequestInbox": "Message Requests",
"noMessageRequestsPending": "No pending message requests",

@ -17,11 +17,7 @@ import {
import { useLibGroupInvitePending } from '../../state/selectors/userGroups';
import { UserGroupsWrapperActions } from '../../webworker/workers/browser/libsession_worker_interface';
import { SessionButton, SessionButtonColor } from '../basic/SessionButton';
import {
ConversationRequestExplanation,
GroupRequestExplanation,
InvitedToGroupControlMessage,
} from './SubtleNotification';
import { InvitedToGroupControlMessage, MessageRequestExplanation } from './SubtleNotification';
const MessageRequestContainer = styled.div`
display: flex;
@ -135,14 +131,14 @@ export const ConversationMessageRequestButtons = () => {
/>
<SessionButton
buttonColor={SessionButtonColor.Danger}
text={isGroupV2 ? window.i18n('delete') : window.i18n('decline')}
text={window.i18n('delete')}
onClick={() => {
handleDeclineConversationRequest(selectedConvoId, selectedConvoId, convoOrigin);
}}
dataTestId="decline-message-request"
/>
</ConversationBannerRow>
{isGroupV2 ? <GroupRequestExplanation /> : <ConversationRequestExplanation />}
<MessageRequestExplanation />
{(isGroupV2 && !!convoOrigin) || !isGroupV2 ? (
<StyledBlockUserText

@ -7,7 +7,7 @@ import {
} from '../../hooks/useParamSelector';
import { PubKey } from '../../session/types';
import {
hasSelectedConversationIncomingMessages,
hasSelectedConversationOutgoingMessages,
useSelectedHasMessages,
} from '../../state/selectors/conversations';
import {
@ -18,6 +18,7 @@ import {
useSelectedIsApproved,
useSelectedIsGroupV2,
useSelectedIsNoteToSelf,
useSelectedIsPrivate,
useSelectedNicknameOrProfileNameOrShortenedPubkey,
} from '../../state/selectors/selectedConversation';
import {
@ -51,17 +52,20 @@ function TextNotification({ html, dataTestId }: { html: string; dataTestId: stri
);
}
/**
* This component is used to display a warning when the user is responding to a message request.
*/
export const ConversationRequestExplanation = () => {
export const MessageRequestExplanation = () => {
const isGroupV2 = useSelectedIsGroupV2();
return isGroupV2 ? <GroupRequestExplanation /> : <ConversationRequestExplanation />;
};
const ConversationRequestExplanation = () => {
const selectedConversation = useSelectedConversationKey();
const isIncomingMessageRequest = useIsIncomingRequest(selectedConversation);
const showMsgRequestUI = selectedConversation && isIncomingMessageRequest;
const hasIncomingMessages = useSelector(hasSelectedConversationIncomingMessages);
const hasOutgoingMessages = useSelector(hasSelectedConversationOutgoingMessages);
if (!showMsgRequestUI || !hasIncomingMessages) {
if (!showMsgRequestUI || hasOutgoingMessages) {
return null;
}
@ -73,10 +77,7 @@ export const ConversationRequestExplanation = () => {
);
};
/**
* This component is used to display a warning when the user is responding to a group message request.
*/
export const GroupRequestExplanation = () => {
const GroupRequestExplanation = () => {
const selectedConversation = useSelectedConversationKey();
const isIncomingMessageRequest = useIsIncomingRequest(selectedConversation);
const isGroupV2 = useSelectedIsGroupV2();
@ -112,24 +113,19 @@ export const InvitedToGroupControlMessage = () => {
isApproved ||
hasMessages || // we don't want to display that "xx invited you" message if there are already other messages (incoming or outgoing)
!isGroupV2 ||
!conversationOrigin ||
!PubKey.is05Pubkey(conversationOrigin) ||
(conversationOrigin && !PubKey.is05Pubkey(conversationOrigin)) ||
!isGroupPendingInvite
) {
return null;
}
// when restoring from seed we might not have the pubkey of who invited us, in that case, we just use a fallback
const html = conversationOrigin
? window.i18n('userInvitedYouToGroup', [adminNameInvitedUs, groupName])
: window.i18n('youWereInvitedToGroup', [groupName]);
return (
<TextNotification
dataTestId="group-invite-control-message"
html={window.i18n('userInvitedYouToGroup', [adminNameInvitedUs, groupName])}
/>
);
return <TextNotification dataTestId="group-invite-control-message" html={html} />;
};
/**
* This component is used to display a warning when the user is looking at an empty conversation.
*/
export const NoMessageInConversation = () => {
const selectedConversation = useSelectedConversationKey();
@ -142,9 +138,16 @@ export const NoMessageInConversation = () => {
const privateBlindedAndBlockingMsgReqs = useSelectedHasDisabledBlindedMsgRequests();
// TODOLATER use this selector accross the whole application (left pane excluded)
const nameToRender = useSelectedNicknameOrProfileNameOrShortenedPubkey() || '';
const isPrivate = useSelectedIsPrivate();
const isIncomingRequest = useIsIncomingRequest(selectedConversation);
// groupV2 use its own invite logic as part of <GroupRequestExplanation />
if (!selectedConversation || hasMessage || (isGroupV2 && isInvitePending)) {
if (
!selectedConversation ||
hasMessage ||
(isGroupV2 && isInvitePending) ||
(isPrivate && isIncomingRequest)
) {
return null;
}
let localizedKey: LocalizerKeys = 'noMessagesInEverythingElse';

@ -518,7 +518,7 @@ export const DeclineMsgRequestMenuItem = () => {
});
}}
>
{isGroupV2 ? window.i18n('delete') : window.i18n('decline')}
{window.i18n('delete')}
</Item>
);
}

@ -197,7 +197,7 @@ export const declineConversationWithConfirm = ({
}) => {
const isGroupV2 = PubKey.is03Pubkey(conversationId);
const okKey: LocalizerKeys = alsoBlock ? 'block' : isGroupV2 ? 'delete' : 'decline';
const okKey: LocalizerKeys = alsoBlock ? 'block' : 'delete';
const nameToBlock =
alsoBlock && !!conversationIdOrigin
? ConvoHub.use().get(conversationIdOrigin)?.getContactProfileNameOrShortenedPubKey()

@ -74,6 +74,8 @@ async function handleGroupInviteMessage({
return;
}
const authorIsApproved = ConvoHub.use().get(author)?.isApproved() || false;
const sigValid = await verifySig({
pubKey: HexString.fromHexStringNoPrefix(inviteMessage.groupSessionId),
signature: inviteMessage.adminSignature,
@ -124,6 +126,10 @@ async function handleGroupInviteMessage({
found.kicked = false;
found.name = inviteMessage.name;
}
if (authorIsApproved) {
// pre approve invite to groups when we've already approved the person who invited us
found.invitePending = false;
}
// not sure if we should drop it, or set it again? They should be the same anyway
found.authData = inviteMessage.memberAuthData;
@ -142,6 +148,10 @@ async function handleGroupInviteMessage({
if (!found.invitePending) {
// if this group should already be polling
getSwarmPollingInstance().addGroupId(inviteMessage.groupSessionId);
console.warn(
'we need to do a first poll to fetch the keys etc before we can send our invite response...'
);
await sendInviteResponseToGroup({ groupPk: inviteMessage.groupSessionId });
}
}

@ -38,6 +38,7 @@ import { MessageReactsSelectorProps } from '../../components/conversation/messag
import { processQuoteAttachment } from '../../models/message';
import { isUsAnySogsFromCache } from '../../session/apis/open_group_api/sogsv3/knownBlindedkeys';
import { PubKey } from '../../session/types';
import { UserGroupsWrapperActions } from '../../webworker/workers/browser/libsession_worker_interface';
import { getSelectedConversationKey } from './selectedConversation';
import { getModeratorsOutsideRedux } from './sogsRoomInfo';
@ -272,6 +273,13 @@ const _getLeftPaneConversationIds = (
return false;
}
if (
PubKey.is03Pubkey(conversation.id) &&
UserGroupsWrapperActions.getCachedGroup(conversation.id)?.invitePending
) {
return false;
}
// a non private conversation is always returned here
if (!conversation.isPrivate) {
return true;

@ -528,6 +528,7 @@ export type LocalizerKeys =
| 'youGotKickedFromGroup'
| 'youHaveANewFriendRequest'
| 'youLeftTheGroup'
| 'youWereInvitedToGroup'
| 'yourSessionID'
| 'yourUniqueSessionID'
| 'zoomFactorSettingTitle';

@ -196,7 +196,9 @@ function dispatchCachedGroupsToRedux() {
);
}
export const UserGroupsWrapperActions: UserGroupsWrapperActionsCalls = {
export const UserGroupsWrapperActions: UserGroupsWrapperActionsCalls & {
getCachedGroup: (pubkeyHex: GroupPubkeyType) => UserGroupsGet | undefined;
} = {
/* Reuse the GenericWrapperActions with the UserGroupsConfig argument */
...createBaseActionsFor('UserGroupsConfig'),
// override the merge() as we need to refresh the cached groups
@ -287,6 +289,10 @@ export const UserGroupsWrapperActions: UserGroupsWrapperActionsCalls = {
return cloneDeep(group);
},
getCachedGroup: (pubkeyHex: GroupPubkeyType) => {
return groups.get(pubkeyHex);
},
getAllGroups: async () => {
const groupsFetched = (await callLibSessionWorker([
'UserGroupsConfig',

Loading…
Cancel
Save