mirror of
https://github.com/element-hq/element-android
synced 2024-11-24 10:25:35 +03:00
Update account data for invited users by email
When an user has been invited by email to a DM, account data entry was stuck on the user email after the user account creation. When the user has joined element, an event m.room.member is triggered for each room attached to the user, containing a third party invite with the user matrix id. We use this event to update the user account with the matrix id.
This commit is contained in:
parent
6d47fdf3d3
commit
ac56b1ef3e
4 changed files with 65 additions and 10 deletions
|
@ -20,22 +20,30 @@ import io.realm.Realm
|
|||
import org.matrix.android.sdk.api.session.events.model.Event
|
||||
import org.matrix.android.sdk.api.session.events.model.EventType
|
||||
import org.matrix.android.sdk.api.session.room.model.RoomMemberContent
|
||||
import org.matrix.android.sdk.internal.di.UserId
|
||||
import org.matrix.android.sdk.internal.session.events.getFixedRoomMemberContent
|
||||
import org.matrix.android.sdk.internal.session.sync.SyncResponsePostTreatmentAggregator
|
||||
import org.matrix.android.sdk.internal.session.user.UserEntityFactory
|
||||
import javax.inject.Inject
|
||||
|
||||
internal class RoomMemberEventHandler @Inject constructor() {
|
||||
internal class RoomMemberEventHandler @Inject constructor(
|
||||
@UserId private val myUserId: String
|
||||
) {
|
||||
|
||||
fun handle(realm: Realm, roomId: String, event: Event): Boolean {
|
||||
fun handle(realm: Realm, roomId: String, event: Event, aggregator: SyncResponsePostTreatmentAggregator? = null): Boolean {
|
||||
if (event.type != EventType.STATE_ROOM_MEMBER) {
|
||||
return false
|
||||
}
|
||||
val userId = event.stateKey ?: return false
|
||||
val roomMember = event.getFixedRoomMemberContent()
|
||||
return handle(realm, roomId, userId, roomMember)
|
||||
return handle(realm, roomId, userId, roomMember, aggregator)
|
||||
}
|
||||
|
||||
fun handle(realm: Realm, roomId: String, userId: String, roomMember: RoomMemberContent?): Boolean {
|
||||
fun handle(realm: Realm,
|
||||
roomId: String,
|
||||
userId: String,
|
||||
roomMember: RoomMemberContent?,
|
||||
aggregator: SyncResponsePostTreatmentAggregator? = null): Boolean {
|
||||
if (roomMember == null) {
|
||||
return false
|
||||
}
|
||||
|
@ -45,6 +53,14 @@ internal class RoomMemberEventHandler @Inject constructor() {
|
|||
val userEntity = UserEntityFactory.create(userId, roomMember)
|
||||
realm.insertOrUpdate(userEntity)
|
||||
}
|
||||
|
||||
// check whether this new room member event may be used to update the directs dictionary in account data
|
||||
// this is required to handle correctly invite by email in DM
|
||||
val mxId = roomMember.thirdPartyInvite?.signed?.mxid
|
||||
if (mxId != null && mxId != myUserId) {
|
||||
aggregator?.directChatsToCheck?.put(roomId, mxId)
|
||||
}
|
||||
|
||||
return true
|
||||
}
|
||||
}
|
||||
|
|
|
@ -221,7 +221,7 @@ internal class RoomSyncHandler @Inject constructor(private val readReceiptHandle
|
|||
}
|
||||
// Give info to crypto module
|
||||
cryptoService.onStateEvent(roomId, event)
|
||||
roomMemberEventHandler.handle(realm, roomId, event)
|
||||
roomMemberEventHandler.handle(realm, roomId, event, aggregator)
|
||||
}
|
||||
}
|
||||
if (roomSync.timeline?.events?.isNotEmpty() == true) {
|
||||
|
@ -233,7 +233,8 @@ internal class RoomSyncHandler @Inject constructor(private val readReceiptHandle
|
|||
roomSync.timeline.prevToken,
|
||||
roomSync.timeline.limited,
|
||||
insertType,
|
||||
syncLocalTimestampMillis
|
||||
syncLocalTimestampMillis,
|
||||
aggregator
|
||||
)
|
||||
roomEntity.addIfNecessary(chunkEntity)
|
||||
}
|
||||
|
@ -337,7 +338,8 @@ internal class RoomSyncHandler @Inject constructor(private val readReceiptHandle
|
|||
prevToken: String? = null,
|
||||
isLimited: Boolean = true,
|
||||
insertType: EventInsertType,
|
||||
syncLocalTimestampMillis: Long): ChunkEntity {
|
||||
syncLocalTimestampMillis: Long,
|
||||
aggregator: SyncResponsePostTreatmentAggregator): ChunkEntity {
|
||||
val lastChunk = ChunkEntity.findLastForwardChunkOfRoom(realm, roomEntity.roomId)
|
||||
val chunkEntity = if (!isLimited && lastChunk != null) {
|
||||
lastChunk
|
||||
|
@ -371,7 +373,7 @@ internal class RoomSyncHandler @Inject constructor(private val readReceiptHandle
|
|||
if (event.type == EventType.STATE_ROOM_MEMBER) {
|
||||
val fixedContent = event.getFixedRoomMemberContent()
|
||||
roomMemberContentsByUser[event.stateKey] = fixedContent
|
||||
roomMemberEventHandler.handle(realm, roomEntity.roomId, event.stateKey, fixedContent)
|
||||
roomMemberEventHandler.handle(realm, roomEntity.roomId, event.stateKey, fixedContent, aggregator)
|
||||
}
|
||||
}
|
||||
roomMemberContentsByUser.getOrPut(event.senderId) {
|
||||
|
|
|
@ -19,4 +19,6 @@ package org.matrix.android.sdk.internal.session.sync
|
|||
internal class SyncResponsePostTreatmentAggregator {
|
||||
// List of RoomId
|
||||
val ephemeralFilesToDelete = mutableListOf<String>()
|
||||
// Map of roomId to directUserId
|
||||
val directChatsToCheck = mutableMapOf<String, String>()
|
||||
}
|
||||
|
|
|
@ -16,13 +16,19 @@
|
|||
|
||||
package org.matrix.android.sdk.internal.session.sync
|
||||
|
||||
import org.matrix.android.sdk.api.MatrixPatterns
|
||||
import org.matrix.android.sdk.internal.session.user.accountdata.DirectChatsHelper
|
||||
import org.matrix.android.sdk.internal.session.user.accountdata.UpdateUserAccountDataTask
|
||||
import javax.inject.Inject
|
||||
|
||||
internal class SyncResponsePostTreatmentAggregatorHandler @Inject constructor(
|
||||
private val ephemeralTemporaryStore: RoomSyncEphemeralTemporaryStore
|
||||
private val directChatsHelper: DirectChatsHelper,
|
||||
private val ephemeralTemporaryStore: RoomSyncEphemeralTemporaryStore,
|
||||
private val updateUserAccountDataTask: UpdateUserAccountDataTask
|
||||
) {
|
||||
fun handle(synResHaResponsePostTreatmentAggregator: SyncResponsePostTreatmentAggregator) {
|
||||
suspend fun handle(synResHaResponsePostTreatmentAggregator: SyncResponsePostTreatmentAggregator) {
|
||||
cleanupEphemeralFiles(synResHaResponsePostTreatmentAggregator.ephemeralFilesToDelete)
|
||||
updateDirectUserIds(synResHaResponsePostTreatmentAggregator.directChatsToCheck)
|
||||
}
|
||||
|
||||
private fun cleanupEphemeralFiles(ephemeralFilesToDelete: List<String>) {
|
||||
|
@ -30,4 +36,33 @@ internal class SyncResponsePostTreatmentAggregatorHandler @Inject constructor(
|
|||
ephemeralTemporaryStore.delete(it)
|
||||
}
|
||||
}
|
||||
|
||||
private suspend fun updateDirectUserIds(directUserIdsToUpdate: Map<String, String>) {
|
||||
val directChats = directChatsHelper.getLocalDirectMessages()
|
||||
var hasUpdate = false
|
||||
directUserIdsToUpdate.forEach { (roomId, candidateUserId) ->
|
||||
// consider room is a DM if referenced in the DM dictionary
|
||||
val currentDirectUserId = directChats.firstNotNullOfOrNull { (userId, roomIds) -> userId.takeIf { roomId in roomIds } }
|
||||
// update directUserId with the given candidateUserId if it mismatches the current one
|
||||
if (currentDirectUserId != null && !MatrixPatterns.isUserId(currentDirectUserId)) {
|
||||
// link roomId with the matrix id
|
||||
directChats
|
||||
.getOrPut(candidateUserId) { arrayListOf() }
|
||||
.apply {
|
||||
if (!contains(roomId)) {
|
||||
hasUpdate = true
|
||||
add(roomId)
|
||||
}
|
||||
}
|
||||
|
||||
// remove roomId from currentDirectUserId entry
|
||||
hasUpdate = hasUpdate or(directChats[currentDirectUserId]?.remove(roomId) == true)
|
||||
// remove currentDirectUserId entry if there is no attached room anymore
|
||||
hasUpdate = hasUpdate or(directChats.takeIf { it[currentDirectUserId].isNullOrEmpty() }?.remove(currentDirectUserId) != null)
|
||||
}
|
||||
}
|
||||
if (hasUpdate) {
|
||||
updateUserAccountDataTask.execute(UpdateUserAccountDataTask.DirectChatParams(directMessages = directChats))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue