android, desktop: don't switch profile when prepared chat reassignment fails

changeActiveUser_ was called outside the guards that check whether
apiChangePreparedContactUser / apiChangePreparedGroupUser actually succeeded.
When the reassignment failed the app still switched to the other profile,
leaving the invitation behind in the original one - and keepingChatId then held
a chat belonging to a different user.

Reachable today: open a link, expand the profile picker, and have the connection
start in the window before tapping. profileChangeProhibited flips to true, the
API returns null, and the switch happened anyway.

The sibling picker in NewChatView already guards this correctly. iOS is
unaffected: there apiChangePreparedContactUser throws, so a failure skips the
switch by control flow.
This commit is contained in:
Narasimha-sc
2026-08-03 07:59:49 +00:00
parent 7c6f046b58
commit c38c87e26a
@@ -79,6 +79,7 @@ fun ComposeContextProfilePickerView(
fun changeProfile(newUser: User) {
withApi {
var chatMoved = false
if (chat.chatInfo is ChatInfo.Direct) {
val updatedContact = chatModel.controller.apiChangePreparedContactUser(rhId, chat.chatInfo.contact.contactId, newUser.userId)
if (updatedContact != null) {
@@ -86,6 +87,7 @@ fun ComposeContextProfilePickerView(
chatModel.controller.appPrefs.incognito.set(false)
listExpanded.value = false
chatModel.chatsContext.updateContact(rhId, updatedContact)
chatMoved = true
}
} else if (chat.chatInfo is ChatInfo.Group) {
val updatedGroup = chatModel.controller.apiChangePreparedGroupUser(rhId, chat.chatInfo.groupInfo.groupId, newUser.userId)
@@ -94,19 +96,24 @@ fun ComposeContextProfilePickerView(
chatModel.controller.appPrefs.incognito.set(false)
listExpanded.value = false
chatModel.chatsContext.updateGroup(rhId, updatedGroup)
chatMoved = true
}
}
chatModel.controller.changeActiveUser_(
rhId = newUser.remoteHostId,
toUserId = newUser.userId,
viewPwd = null,
keepingChatId = chat.id
)
if (chatModel.currentUser.value?.userId != newUser.userId) {
AlertManager.shared.showAlertMsg(
generalGetString(MR.strings.switching_profile_error_title),
String.format(generalGetString(MR.strings.switching_profile_error_message), newUser.chatViewName)
// Only switch profile if the chat was actually moved to it, otherwise the user
// would end up in another profile with the invitation left behind in this one.
if (chatMoved) {
chatModel.controller.changeActiveUser_(
rhId = newUser.remoteHostId,
toUserId = newUser.userId,
viewPwd = null,
keepingChatId = chat.id
)
if (chatModel.currentUser.value?.userId != newUser.userId) {
AlertManager.shared.showAlertMsg(
generalGetString(MR.strings.switching_profile_error_title),
String.format(generalGetString(MR.strings.switching_profile_error_message), newUser.chatViewName)
)
}
}
}
}