Merge pull request #5953 from vector-im/task/eric/reformat-project
Reformats project based on editorconfig
This commit is contained in:
commit
9f9c6fbc5b
1
changelog.d/5953.misc
Normal file
1
changelog.d/5953.misc
Normal file
@ -0,0 +1 @@
|
|||||||
|
Reformatted project code
|
@ -37,7 +37,10 @@ class PermalinkParserTest {
|
|||||||
Assert.assertTrue("Should be parsed as email invite but was ${parsedLink::class.java}", parsedLink is PermalinkData.RoomEmailInviteLink)
|
Assert.assertTrue("Should be parsed as email invite but was ${parsedLink::class.java}", parsedLink is PermalinkData.RoomEmailInviteLink)
|
||||||
parsedLink as PermalinkData.RoomEmailInviteLink
|
parsedLink as PermalinkData.RoomEmailInviteLink
|
||||||
Assert.assertEquals("!MRBNLPtFnMAazZVPMO:matrix.org", parsedLink.roomId)
|
Assert.assertEquals("!MRBNLPtFnMAazZVPMO:matrix.org", parsedLink.roomId)
|
||||||
Assert.assertEquals("XmOwRZnSFabCRhTywFbJWKXWVNPysOpXIbroMGaUymqkJSvHeVKRsjHajwjCYdBsvGSvHauxbKfJmOxtXldtyLnyBMLKpBQCMzyYggrdapbVIceWZBtmslOQrXLABRoe", parsedLink.token)
|
Assert.assertEquals(
|
||||||
|
"XmOwRZnSFabCRhTywFbJWKXWVNPysOpXIbroMGaUymqkJSvHeVKRsjHajwjCYdBsvGSvHauxbKfJmOxtXldtyLnyBMLKpBQCMzyYggrdapbVIceWZBtmslOQrXLABRoe",
|
||||||
|
parsedLink.token
|
||||||
|
)
|
||||||
Assert.assertEquals("vector.im", parsedLink.identityServer)
|
Assert.assertEquals("vector.im", parsedLink.identityServer)
|
||||||
Assert.assertEquals("Team2", parsedLink.roomName)
|
Assert.assertEquals("Team2", parsedLink.roomName)
|
||||||
Assert.assertEquals("hiphop5", parsedLink.inviterName)
|
Assert.assertEquals("hiphop5", parsedLink.inviterName)
|
||||||
@ -45,7 +48,8 @@ class PermalinkParserTest {
|
|||||||
|
|
||||||
@Test
|
@Test
|
||||||
fun testParseLinkWIthEvent() {
|
fun testParseLinkWIthEvent() {
|
||||||
val rawInvite = "https://matrix.to/#/!OGEhHVWSdvArJzumhm:matrix.org/\$xuvJUVDJnwEeVjPx029rAOZ50difpmU_5gZk_T0jGfc?via=matrix.org&via=libera.chat&via=matrix.example.io"
|
val rawInvite =
|
||||||
|
"https://matrix.to/#/!OGEhHVWSdvArJzumhm:matrix.org/\$xuvJUVDJnwEeVjPx029rAOZ50difpmU_5gZk_T0jGfc?via=matrix.org&via=libera.chat&via=matrix.example.io"
|
||||||
|
|
||||||
val parsedLink = PermalinkParser.parse(rawInvite)
|
val parsedLink = PermalinkParser.parse(rawInvite)
|
||||||
Assert.assertTrue("Should be parsed as room link", parsedLink is PermalinkData.RoomLink)
|
Assert.assertTrue("Should be parsed as room link", parsedLink is PermalinkData.RoomLink)
|
||||||
|
@ -21,5 +21,7 @@ import kotlinx.coroutines.asCoroutineDispatcher
|
|||||||
import org.matrix.android.sdk.api.MatrixCoroutineDispatchers
|
import org.matrix.android.sdk.api.MatrixCoroutineDispatchers
|
||||||
import java.util.concurrent.Executors
|
import java.util.concurrent.Executors
|
||||||
|
|
||||||
internal val testCoroutineDispatchers = MatrixCoroutineDispatchers(Main, Main, Main, Main,
|
internal val testCoroutineDispatchers = MatrixCoroutineDispatchers(
|
||||||
Executors.newSingleThreadExecutor().asCoroutineDispatcher())
|
Main, Main, Main, Main,
|
||||||
|
Executors.newSingleThreadExecutor().asCoroutineDispatcher()
|
||||||
|
)
|
||||||
|
@ -67,9 +67,11 @@ class DeactivateAccountTest : InstrumentedTest {
|
|||||||
val throwable = commonTestHelper.logAccountWithError(session.myUserId, TestConstants.PASSWORD)
|
val throwable = commonTestHelper.logAccountWithError(session.myUserId, TestConstants.PASSWORD)
|
||||||
|
|
||||||
// Test the error
|
// Test the error
|
||||||
assertTrue(throwable is Failure.ServerError &&
|
assertTrue(
|
||||||
throwable.error.code == MatrixError.M_USER_DEACTIVATED &&
|
throwable is Failure.ServerError &&
|
||||||
throwable.error.message == "This account has been deactivated")
|
throwable.error.code == MatrixError.M_USER_DEACTIVATED &&
|
||||||
|
throwable.error.message == "This account has been deactivated"
|
||||||
|
)
|
||||||
|
|
||||||
// Try to create an account with the deactivate account user id, it will fail (M_USER_IN_USE)
|
// Try to create an account with the deactivate account user id, it will fail (M_USER_IN_USE)
|
||||||
val hs = commonTestHelper.createHomeServerConfig()
|
val hs = commonTestHelper.createHomeServerConfig()
|
||||||
@ -95,8 +97,10 @@ class DeactivateAccountTest : InstrumentedTest {
|
|||||||
|
|
||||||
// Test the error
|
// Test the error
|
||||||
accountCreationError.let {
|
accountCreationError.let {
|
||||||
assertTrue(it is Failure.ServerError &&
|
assertTrue(
|
||||||
it.error.code == MatrixError.M_USER_IN_USE)
|
it is Failure.ServerError &&
|
||||||
|
it.error.code == MatrixError.M_USER_IN_USE
|
||||||
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
// No need to close the session, it has been deactivated
|
// No need to close the session, it has been deactivated
|
||||||
|
@ -291,7 +291,8 @@ class CryptoTestHelper(private val testHelper: CommonTestHelper) {
|
|||||||
)
|
)
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
}, it)
|
}, it
|
||||||
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -308,7 +309,8 @@ class CryptoTestHelper(private val testHelper: CommonTestHelper) {
|
|||||||
requestID,
|
requestID,
|
||||||
roomId,
|
roomId,
|
||||||
bob.myUserId,
|
bob.myUserId,
|
||||||
bob.sessionParams.credentials.deviceId!!)
|
bob.sessionParams.credentials.deviceId!!
|
||||||
|
)
|
||||||
|
|
||||||
// we should reach SHOW SAS on both
|
// we should reach SHOW SAS on both
|
||||||
var alicePovTx: OutgoingSasVerificationTransaction? = null
|
var alicePovTx: OutgoingSasVerificationTransaction? = null
|
||||||
|
@ -29,15 +29,17 @@ import org.matrix.android.sdk.internal.raw.RawModule
|
|||||||
import org.matrix.android.sdk.internal.settings.SettingsModule
|
import org.matrix.android.sdk.internal.settings.SettingsModule
|
||||||
import org.matrix.android.sdk.internal.util.system.SystemModule
|
import org.matrix.android.sdk.internal.util.system.SystemModule
|
||||||
|
|
||||||
@Component(modules = [
|
@Component(
|
||||||
TestModule::class,
|
modules = [
|
||||||
MatrixModule::class,
|
TestModule::class,
|
||||||
NetworkModule::class,
|
MatrixModule::class,
|
||||||
AuthModule::class,
|
NetworkModule::class,
|
||||||
RawModule::class,
|
AuthModule::class,
|
||||||
SettingsModule::class,
|
RawModule::class,
|
||||||
SystemModule::class
|
SettingsModule::class,
|
||||||
])
|
SystemModule::class
|
||||||
|
]
|
||||||
|
)
|
||||||
@MatrixScope
|
@MatrixScope
|
||||||
internal interface TestMatrixComponent : MatrixComponent {
|
internal interface TestMatrixComponent : MatrixComponent {
|
||||||
|
|
||||||
|
@ -76,9 +76,11 @@ class CryptoStoreTest : InstrumentedTest {
|
|||||||
}
|
}
|
||||||
|
|
||||||
val olmSession1 = OlmSession().apply {
|
val olmSession1 = OlmSession().apply {
|
||||||
initOutboundSession(olmAccount1,
|
initOutboundSession(
|
||||||
|
olmAccount1,
|
||||||
olmAccount1.identityKeys()[OlmAccount.JSON_KEY_IDENTITY_KEY],
|
olmAccount1.identityKeys()[OlmAccount.JSON_KEY_IDENTITY_KEY],
|
||||||
olmAccount1.oneTimeKeys()[OlmAccount.JSON_KEY_ONE_TIME_KEY]?.values?.first())
|
olmAccount1.oneTimeKeys()[OlmAccount.JSON_KEY_ONE_TIME_KEY]?.values?.first()
|
||||||
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
val sessionId1 = olmSession1.sessionIdentifier()
|
val sessionId1 = olmSession1.sessionIdentifier()
|
||||||
@ -93,9 +95,11 @@ class CryptoStoreTest : InstrumentedTest {
|
|||||||
}
|
}
|
||||||
|
|
||||||
val olmSession2 = OlmSession().apply {
|
val olmSession2 = OlmSession().apply {
|
||||||
initOutboundSession(olmAccount2,
|
initOutboundSession(
|
||||||
|
olmAccount2,
|
||||||
olmAccount2.identityKeys()[OlmAccount.JSON_KEY_IDENTITY_KEY],
|
olmAccount2.identityKeys()[OlmAccount.JSON_KEY_IDENTITY_KEY],
|
||||||
olmAccount2.oneTimeKeys()[OlmAccount.JSON_KEY_ONE_TIME_KEY]?.values?.first())
|
olmAccount2.oneTimeKeys()[OlmAccount.JSON_KEY_ONE_TIME_KEY]?.values?.first()
|
||||||
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
val sessionId2 = olmSession2.sessionIdentifier()
|
val sessionId2 = olmSession2.sessionIdentifier()
|
||||||
|
@ -299,11 +299,13 @@ class E2eeSanityTests : InstrumentedTest {
|
|||||||
}
|
}
|
||||||
|
|
||||||
val importedResult = testHelper.doSync<ImportRoomKeysResult> {
|
val importedResult = testHelper.doSync<ImportRoomKeysResult> {
|
||||||
keysBackupService.restoreKeyBackupWithPassword(keyVersionResult!!,
|
keysBackupService.restoreKeyBackupWithPassword(
|
||||||
|
keyVersionResult!!,
|
||||||
keyBackupPassword,
|
keyBackupPassword,
|
||||||
null,
|
null,
|
||||||
null,
|
null,
|
||||||
null, it)
|
null, it
|
||||||
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
assertEquals(3, importedResult.totalNumberOfKeys)
|
assertEquals(3, importedResult.totalNumberOfKeys)
|
||||||
|
@ -93,9 +93,11 @@ class ExportEncryptionTest {
|
|||||||
fail("## checkExportDecrypt1() failed : " + e.message)
|
fail("## checkExportDecrypt1() failed : " + e.message)
|
||||||
}
|
}
|
||||||
|
|
||||||
assertEquals("## checkExportDecrypt1() : expectedString $expectedString -- decodedString $decodedString",
|
assertEquals(
|
||||||
|
"## checkExportDecrypt1() : expectedString $expectedString -- decodedString $decodedString",
|
||||||
expectedString,
|
expectedString,
|
||||||
decodedString)
|
decodedString
|
||||||
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@ -111,9 +113,11 @@ class ExportEncryptionTest {
|
|||||||
fail("## checkExportDecrypt2() failed : " + e.message)
|
fail("## checkExportDecrypt2() failed : " + e.message)
|
||||||
}
|
}
|
||||||
|
|
||||||
assertEquals("## checkExportDecrypt2() : expectedString $expectedString -- decodedString $decodedString",
|
assertEquals(
|
||||||
|
"## checkExportDecrypt2() : expectedString $expectedString -- decodedString $decodedString",
|
||||||
expectedString,
|
expectedString,
|
||||||
decodedString)
|
decodedString
|
||||||
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@ -129,9 +133,11 @@ class ExportEncryptionTest {
|
|||||||
fail("## checkExportDecrypt3() failed : " + e.message)
|
fail("## checkExportDecrypt3() failed : " + e.message)
|
||||||
}
|
}
|
||||||
|
|
||||||
assertEquals("## checkExportDecrypt3() : expectedString $expectedString -- decodedString $decodedString",
|
assertEquals(
|
||||||
|
"## checkExportDecrypt3() : expectedString $expectedString -- decodedString $decodedString",
|
||||||
expectedString,
|
expectedString,
|
||||||
decodedString)
|
decodedString
|
||||||
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@ -147,9 +153,11 @@ class ExportEncryptionTest {
|
|||||||
fail("## checkExportEncrypt1() failed : " + e.message)
|
fail("## checkExportEncrypt1() failed : " + e.message)
|
||||||
}
|
}
|
||||||
|
|
||||||
assertEquals("## checkExportEncrypt1() : expectedString $expectedString -- decodedString $decodedString",
|
assertEquals(
|
||||||
|
"## checkExportEncrypt1() : expectedString $expectedString -- decodedString $decodedString",
|
||||||
expectedString,
|
expectedString,
|
||||||
decodedString)
|
decodedString
|
||||||
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@ -165,9 +173,11 @@ class ExportEncryptionTest {
|
|||||||
fail("## checkExportEncrypt2() failed : " + e.message)
|
fail("## checkExportEncrypt2() failed : " + e.message)
|
||||||
}
|
}
|
||||||
|
|
||||||
assertEquals("## checkExportEncrypt2() : expectedString $expectedString -- decodedString $decodedString",
|
assertEquals(
|
||||||
|
"## checkExportEncrypt2() : expectedString $expectedString -- decodedString $decodedString",
|
||||||
expectedString,
|
expectedString,
|
||||||
decodedString)
|
decodedString
|
||||||
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@ -183,9 +193,11 @@ class ExportEncryptionTest {
|
|||||||
fail("## checkExportEncrypt3() failed : " + e.message)
|
fail("## checkExportEncrypt3() failed : " + e.message)
|
||||||
}
|
}
|
||||||
|
|
||||||
assertEquals("## checkExportEncrypt3() : expectedString $expectedString -- decodedString $decodedString",
|
assertEquals(
|
||||||
|
"## checkExportEncrypt3() : expectedString $expectedString -- decodedString $decodedString",
|
||||||
expectedString,
|
expectedString,
|
||||||
decodedString)
|
decodedString
|
||||||
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@ -201,8 +213,10 @@ class ExportEncryptionTest {
|
|||||||
fail("## checkExportEncrypt4() failed : " + e.message)
|
fail("## checkExportEncrypt4() failed : " + e.message)
|
||||||
}
|
}
|
||||||
|
|
||||||
assertEquals("## checkExportEncrypt4() : expectedString $expectedString -- decodedString $decodedString",
|
assertEquals(
|
||||||
|
"## checkExportEncrypt4() : expectedString $expectedString -- decodedString $decodedString",
|
||||||
expectedString,
|
expectedString,
|
||||||
decodedString)
|
decodedString
|
||||||
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -171,7 +171,10 @@ class UnwedgingTest : InstrumentedTest {
|
|||||||
// Let us wedge the session now. Set crypto state like after the first message
|
// Let us wedge the session now. Set crypto state like after the first message
|
||||||
Timber.i("## CRYPTO | testUnwedging: wedge the session now. Set crypto state like after the first message")
|
Timber.i("## CRYPTO | testUnwedging: wedge the session now. Set crypto state like after the first message")
|
||||||
|
|
||||||
aliceCryptoStore.storeSession(OlmSessionWrapper(deserializeFromRealm<OlmSession>(oldSession)!!), bobSession.cryptoService().getMyDevice().identityKey()!!)
|
aliceCryptoStore.storeSession(
|
||||||
|
OlmSessionWrapper(deserializeFromRealm<OlmSession>(oldSession)!!),
|
||||||
|
bobSession.cryptoService().getMyDevice().identityKey()!!
|
||||||
|
)
|
||||||
olmDevice.clearOlmSessionCache()
|
olmDevice.clearOlmSessionCache()
|
||||||
Thread.sleep(6_000)
|
Thread.sleep(6_000)
|
||||||
|
|
||||||
@ -218,7 +221,8 @@ class UnwedgingTest : InstrumentedTest {
|
|||||||
)
|
)
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
}, it)
|
}, it
|
||||||
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Wait until we received back the key
|
// Wait until we received back the key
|
||||||
|
@ -126,8 +126,16 @@ class XSigningTest : InstrumentedTest {
|
|||||||
assertNull("Alice should not see bob User key", bobKeysFromAlicePOV.userKey())
|
assertNull("Alice should not see bob User key", bobKeysFromAlicePOV.userKey())
|
||||||
assertNotNull("Alice can see bob SelfSigned key", bobKeysFromAlicePOV.selfSigningKey())
|
assertNotNull("Alice can see bob SelfSigned key", bobKeysFromAlicePOV.selfSigningKey())
|
||||||
|
|
||||||
assertEquals("Bob keys from alice pov should match", bobKeysFromAlicePOV.masterKey()?.unpaddedBase64PublicKey, bobSession.cryptoService().crossSigningService().getMyCrossSigningKeys()?.masterKey()?.unpaddedBase64PublicKey)
|
assertEquals(
|
||||||
assertEquals("Bob keys from alice pov should match", bobKeysFromAlicePOV.selfSigningKey()?.unpaddedBase64PublicKey, bobSession.cryptoService().crossSigningService().getMyCrossSigningKeys()?.selfSigningKey()?.unpaddedBase64PublicKey)
|
"Bob keys from alice pov should match",
|
||||||
|
bobKeysFromAlicePOV.masterKey()?.unpaddedBase64PublicKey,
|
||||||
|
bobSession.cryptoService().crossSigningService().getMyCrossSigningKeys()?.masterKey()?.unpaddedBase64PublicKey
|
||||||
|
)
|
||||||
|
assertEquals(
|
||||||
|
"Bob keys from alice pov should match",
|
||||||
|
bobKeysFromAlicePOV.selfSigningKey()?.unpaddedBase64PublicKey,
|
||||||
|
bobSession.cryptoService().crossSigningService().getMyCrossSigningKeys()?.selfSigningKey()?.unpaddedBase64PublicKey
|
||||||
|
)
|
||||||
|
|
||||||
assertFalse("Bob keys from alice pov should not be trusted", bobKeysFromAlicePOV.isTrusted())
|
assertFalse("Bob keys from alice pov should not be trusted", bobKeysFromAlicePOV.isTrusted())
|
||||||
|
|
||||||
|
@ -145,7 +145,10 @@ class KeyShareTests : InstrumentedTest {
|
|||||||
Log.v("TEST", "Incoming request Session 1 (looking for $outGoingRequestId)")
|
Log.v("TEST", "Incoming request Session 1 (looking for $outGoingRequestId)")
|
||||||
Log.v("TEST", "=========================")
|
Log.v("TEST", "=========================")
|
||||||
it.forEach { keyRequest ->
|
it.forEach { keyRequest ->
|
||||||
Log.v("TEST", "[ts${keyRequest.localCreationTimestamp}] requestId ${keyRequest.requestId}, for sessionId ${keyRequest.requestBody?.sessionId} is ${keyRequest.state}")
|
Log.v(
|
||||||
|
"TEST",
|
||||||
|
"[ts${keyRequest.localCreationTimestamp}] requestId ${keyRequest.requestId}, for sessionId ${keyRequest.requestBody?.sessionId} is ${keyRequest.state}"
|
||||||
|
)
|
||||||
}
|
}
|
||||||
Log.v("TEST", "=========================")
|
Log.v("TEST", "=========================")
|
||||||
}
|
}
|
||||||
@ -164,8 +167,10 @@ class KeyShareTests : InstrumentedTest {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Mark the device as trusted
|
// Mark the device as trusted
|
||||||
aliceSession.cryptoService().setDeviceVerification(DeviceTrustLevel(crossSigningVerified = false, locallyVerified = true), aliceSession.myUserId,
|
aliceSession.cryptoService().setDeviceVerification(
|
||||||
aliceSession2.sessionParams.deviceId ?: "")
|
DeviceTrustLevel(crossSigningVerified = false, locallyVerified = true), aliceSession.myUserId,
|
||||||
|
aliceSession2.sessionParams.deviceId ?: ""
|
||||||
|
)
|
||||||
|
|
||||||
// Re request
|
// Re request
|
||||||
aliceSession2.cryptoService().reRequestRoomKeyForEvent(receivedEvent.root)
|
aliceSession2.cryptoService().reRequestRoomKeyForEvent(receivedEvent.root)
|
||||||
@ -223,7 +228,8 @@ class KeyShareTests : InstrumentedTest {
|
|||||||
)
|
)
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
}, it)
|
}, it
|
||||||
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Also bootstrap keybackup on first session
|
// Also bootstrap keybackup on first session
|
||||||
@ -282,8 +288,10 @@ class KeyShareTests : InstrumentedTest {
|
|||||||
})
|
})
|
||||||
|
|
||||||
val txId = "m.testVerif12"
|
val txId = "m.testVerif12"
|
||||||
aliceVerificationService2.beginKeyVerification(VerificationMethod.SAS, aliceSession1.myUserId, aliceSession1.sessionParams.deviceId
|
aliceVerificationService2.beginKeyVerification(
|
||||||
?: "", txId)
|
VerificationMethod.SAS, aliceSession1.myUserId, aliceSession1.sessionParams.deviceId
|
||||||
|
?: "", txId
|
||||||
|
)
|
||||||
|
|
||||||
commonTestHelper.waitWithLatch { latch ->
|
commonTestHelper.waitWithLatch { latch ->
|
||||||
commonTestHelper.retryPeriodicallyWithLatch(latch) {
|
commonTestHelper.retryPeriodicallyWithLatch(latch) {
|
||||||
@ -337,7 +345,8 @@ class KeyShareTests : InstrumentedTest {
|
|||||||
)
|
)
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
}, it)
|
}, it
|
||||||
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Create an encrypted room and send a couple of messages
|
// Create an encrypted room and send a couple of messages
|
||||||
@ -371,7 +380,8 @@ class KeyShareTests : InstrumentedTest {
|
|||||||
)
|
)
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
}, it)
|
}, it
|
||||||
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Let alice invite bob
|
// Let alice invite bob
|
||||||
|
@ -147,13 +147,15 @@ class WithHeldTests : InstrumentedTest {
|
|||||||
val aliceInterceptor = testHelper.getTestInterceptor(aliceSession)
|
val aliceInterceptor = testHelper.getTestInterceptor(aliceSession)
|
||||||
|
|
||||||
// Simulate no OTK
|
// Simulate no OTK
|
||||||
aliceInterceptor!!.addRule(MockOkHttpInterceptor.SimpleRule(
|
aliceInterceptor!!.addRule(
|
||||||
"/keys/claim",
|
MockOkHttpInterceptor.SimpleRule(
|
||||||
200,
|
"/keys/claim",
|
||||||
"""
|
200,
|
||||||
|
"""
|
||||||
{ "one_time_keys" : {} }
|
{ "one_time_keys" : {} }
|
||||||
"""
|
"""
|
||||||
))
|
)
|
||||||
|
)
|
||||||
Log.d("#TEST", "Recovery :${aliceSession.sessionParams.credentials.accessToken}")
|
Log.d("#TEST", "Recovery :${aliceSession.sessionParams.credentials.accessToken}")
|
||||||
|
|
||||||
val roomAlicePov = aliceSession.getRoom(testData.roomId)!!
|
val roomAlicePov = aliceSession.getRoom(testData.roomId)!!
|
||||||
@ -184,7 +186,10 @@ class WithHeldTests : InstrumentedTest {
|
|||||||
|
|
||||||
// Ensure that alice has marked the session to be shared with bob
|
// Ensure that alice has marked the session to be shared with bob
|
||||||
val sessionId = eventBobPOV!!.root.content.toModel<EncryptedEventContent>()!!.sessionId!!
|
val sessionId = eventBobPOV!!.root.content.toModel<EncryptedEventContent>()!!.sessionId!!
|
||||||
val chainIndex = aliceSession.cryptoService().getSharedWithInfo(testData.roomId, sessionId).getObject(bobSession.myUserId, bobSession.sessionParams.credentials.deviceId)
|
val chainIndex = aliceSession.cryptoService().getSharedWithInfo(testData.roomId, sessionId).getObject(
|
||||||
|
bobSession.myUserId,
|
||||||
|
bobSession.sessionParams.credentials.deviceId
|
||||||
|
)
|
||||||
|
|
||||||
Assert.assertEquals("Alice should have marked bob's device for this session", 0, chainIndex)
|
Assert.assertEquals("Alice should have marked bob's device for this session", 0, chainIndex)
|
||||||
// Add a new device for bob
|
// Add a new device for bob
|
||||||
@ -202,7 +207,10 @@ class WithHeldTests : InstrumentedTest {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
val chainIndex2 = aliceSession.cryptoService().getSharedWithInfo(testData.roomId, sessionId).getObject(bobSecondSession.myUserId, bobSecondSession.sessionParams.credentials.deviceId)
|
val chainIndex2 = aliceSession.cryptoService().getSharedWithInfo(testData.roomId, sessionId).getObject(
|
||||||
|
bobSecondSession.myUserId,
|
||||||
|
bobSecondSession.sessionParams.credentials.deviceId
|
||||||
|
)
|
||||||
|
|
||||||
Assert.assertEquals("Alice should have marked bob's device for this session", 1, chainIndex2)
|
Assert.assertEquals("Alice should have marked bob's device for this session", 1, chainIndex2)
|
||||||
|
|
||||||
|
@ -54,9 +54,11 @@ class KeysBackupPasswordTest : InstrumentedTest {
|
|||||||
assertEquals(OlmPkDecryption.privateKeyLength(), generatePrivateKeyResult.privateKey.size)
|
assertEquals(OlmPkDecryption.privateKeyLength(), generatePrivateKeyResult.privateKey.size)
|
||||||
|
|
||||||
// Reverse operation
|
// Reverse operation
|
||||||
val retrievedPrivateKey = retrievePrivateKeyWithPassword(PASSWORD,
|
val retrievedPrivateKey = retrievePrivateKeyWithPassword(
|
||||||
|
PASSWORD,
|
||||||
generatePrivateKeyResult.salt,
|
generatePrivateKeyResult.salt,
|
||||||
generatePrivateKeyResult.iterations)
|
generatePrivateKeyResult.iterations
|
||||||
|
)
|
||||||
|
|
||||||
assertEquals(OlmPkDecryption.privateKeyLength(), retrievedPrivateKey.size)
|
assertEquals(OlmPkDecryption.privateKeyLength(), retrievedPrivateKey.size)
|
||||||
assertArrayEquals(generatePrivateKeyResult.privateKey, retrievedPrivateKey)
|
assertArrayEquals(generatePrivateKeyResult.privateKey, retrievedPrivateKey)
|
||||||
@ -102,9 +104,11 @@ class KeysBackupPasswordTest : InstrumentedTest {
|
|||||||
assertEquals(OlmPkDecryption.privateKeyLength(), generatePrivateKeyResult.privateKey.size)
|
assertEquals(OlmPkDecryption.privateKeyLength(), generatePrivateKeyResult.privateKey.size)
|
||||||
|
|
||||||
// Reverse operation, with bad password
|
// Reverse operation, with bad password
|
||||||
val retrievedPrivateKey = retrievePrivateKeyWithPassword(BAD_PASSWORD,
|
val retrievedPrivateKey = retrievePrivateKeyWithPassword(
|
||||||
|
BAD_PASSWORD,
|
||||||
generatePrivateKeyResult.salt,
|
generatePrivateKeyResult.salt,
|
||||||
generatePrivateKeyResult.iterations)
|
generatePrivateKeyResult.iterations
|
||||||
|
)
|
||||||
|
|
||||||
assertEquals(OlmPkDecryption.privateKeyLength(), retrievedPrivateKey.size)
|
assertEquals(OlmPkDecryption.privateKeyLength(), retrievedPrivateKey.size)
|
||||||
assertByteArrayNotEqual(generatePrivateKeyResult.privateKey, retrievedPrivateKey)
|
assertByteArrayNotEqual(generatePrivateKeyResult.privateKey, retrievedPrivateKey)
|
||||||
@ -122,9 +126,11 @@ class KeysBackupPasswordTest : InstrumentedTest {
|
|||||||
assertEquals(OlmPkDecryption.privateKeyLength(), generatePrivateKeyResult.privateKey.size)
|
assertEquals(OlmPkDecryption.privateKeyLength(), generatePrivateKeyResult.privateKey.size)
|
||||||
|
|
||||||
// Reverse operation, with bad iteration
|
// Reverse operation, with bad iteration
|
||||||
val retrievedPrivateKey = retrievePrivateKeyWithPassword(PASSWORD,
|
val retrievedPrivateKey = retrievePrivateKeyWithPassword(
|
||||||
|
PASSWORD,
|
||||||
generatePrivateKeyResult.salt,
|
generatePrivateKeyResult.salt,
|
||||||
500_001)
|
500_001
|
||||||
|
)
|
||||||
|
|
||||||
assertEquals(OlmPkDecryption.privateKeyLength(), retrievedPrivateKey.size)
|
assertEquals(OlmPkDecryption.privateKeyLength(), retrievedPrivateKey.size)
|
||||||
assertByteArrayNotEqual(generatePrivateKeyResult.privateKey, retrievedPrivateKey)
|
assertByteArrayNotEqual(generatePrivateKeyResult.privateKey, retrievedPrivateKey)
|
||||||
@ -142,9 +148,11 @@ class KeysBackupPasswordTest : InstrumentedTest {
|
|||||||
assertEquals(OlmPkDecryption.privateKeyLength(), generatePrivateKeyResult.privateKey.size)
|
assertEquals(OlmPkDecryption.privateKeyLength(), generatePrivateKeyResult.privateKey.size)
|
||||||
|
|
||||||
// Reverse operation, with bad iteration
|
// Reverse operation, with bad iteration
|
||||||
val retrievedPrivateKey = retrievePrivateKeyWithPassword(PASSWORD,
|
val retrievedPrivateKey = retrievePrivateKeyWithPassword(
|
||||||
|
PASSWORD,
|
||||||
BAD_SALT,
|
BAD_SALT,
|
||||||
generatePrivateKeyResult.iterations)
|
generatePrivateKeyResult.iterations
|
||||||
|
)
|
||||||
|
|
||||||
assertEquals(OlmPkDecryption.privateKeyLength(), retrievedPrivateKey.size)
|
assertEquals(OlmPkDecryption.privateKeyLength(), retrievedPrivateKey.size)
|
||||||
assertByteArrayNotEqual(generatePrivateKeyResult.privateKey, retrievedPrivateKey)
|
assertByteArrayNotEqual(generatePrivateKeyResult.privateKey, retrievedPrivateKey)
|
||||||
@ -168,7 +176,8 @@ class KeysBackupPasswordTest : InstrumentedTest {
|
|||||||
116.toByte(), 224.toByte(), 229.toByte(), 224.toByte(), 9.toByte(), 3.toByte(), 178.toByte(), 162.toByte(),
|
116.toByte(), 224.toByte(), 229.toByte(), 224.toByte(), 9.toByte(), 3.toByte(), 178.toByte(), 162.toByte(),
|
||||||
120.toByte(), 23.toByte(), 108.toByte(), 218.toByte(), 22.toByte(), 61.toByte(), 241.toByte(), 200.toByte(),
|
120.toByte(), 23.toByte(), 108.toByte(), 218.toByte(), 22.toByte(), 61.toByte(), 241.toByte(), 200.toByte(),
|
||||||
235.toByte(), 173.toByte(), 236.toByte(), 100.toByte(), 115.toByte(), 247.toByte(), 33.toByte(), 132.toByte(),
|
235.toByte(), 173.toByte(), 236.toByte(), 100.toByte(), 115.toByte(), 247.toByte(), 33.toByte(), 132.toByte(),
|
||||||
195.toByte(), 154.toByte(), 64.toByte(), 158.toByte(), 184.toByte(), 148.toByte(), 20.toByte(), 85.toByte())
|
195.toByte(), 154.toByte(), 64.toByte(), 158.toByte(), 184.toByte(), 148.toByte(), 20.toByte(), 85.toByte()
|
||||||
|
)
|
||||||
|
|
||||||
assertArrayEquals(privateKeyBytes, retrievedPrivateKey)
|
assertArrayEquals(privateKeyBytes, retrievedPrivateKey)
|
||||||
}
|
}
|
||||||
|
@ -272,10 +272,12 @@ class KeysBackupTest : InstrumentedTest {
|
|||||||
assertNotNull(decryption)
|
assertNotNull(decryption)
|
||||||
// - Check decryptKeyBackupData() returns stg
|
// - Check decryptKeyBackupData() returns stg
|
||||||
val sessionData = keysBackup
|
val sessionData = keysBackup
|
||||||
.decryptKeyBackupData(keyBackupData,
|
.decryptKeyBackupData(
|
||||||
|
keyBackupData,
|
||||||
session.olmInboundGroupSession!!.sessionIdentifier(),
|
session.olmInboundGroupSession!!.sessionIdentifier(),
|
||||||
cryptoTestData.roomId,
|
cryptoTestData.roomId,
|
||||||
decryption!!)
|
decryption!!
|
||||||
|
)
|
||||||
assertNotNull(sessionData)
|
assertNotNull(sessionData)
|
||||||
// - Compare the decrypted megolm key with the original one
|
// - Compare the decrypted megolm key with the original one
|
||||||
keysBackupTestHelper.assertKeysEquals(session.exportKeys(), sessionData)
|
keysBackupTestHelper.assertKeysEquals(session.exportKeys(), sessionData)
|
||||||
@ -297,7 +299,8 @@ class KeysBackupTest : InstrumentedTest {
|
|||||||
|
|
||||||
// - Restore the e2e backup from the homeserver
|
// - Restore the e2e backup from the homeserver
|
||||||
val importRoomKeysResult = testHelper.doSync<ImportRoomKeysResult> {
|
val importRoomKeysResult = testHelper.doSync<ImportRoomKeysResult> {
|
||||||
testData.aliceSession2.cryptoService().keysBackupService().restoreKeysWithRecoveryKey(testData.aliceSession2.cryptoService().keysBackupService().keysBackupVersion!!,
|
testData.aliceSession2.cryptoService().keysBackupService().restoreKeysWithRecoveryKey(
|
||||||
|
testData.aliceSession2.cryptoService().keysBackupService().keysBackupVersion!!,
|
||||||
testData.prepareKeysBackupDataResult.megolmBackupCreationInfo.recoveryKey,
|
testData.prepareKeysBackupDataResult.megolmBackupCreationInfo.recoveryKey,
|
||||||
null,
|
null,
|
||||||
null,
|
null,
|
||||||
@ -680,7 +683,8 @@ class KeysBackupTest : InstrumentedTest {
|
|||||||
val steps = ArrayList<StepProgressListener.Step>()
|
val steps = ArrayList<StepProgressListener.Step>()
|
||||||
|
|
||||||
val importRoomKeysResult = testHelper.doSync<ImportRoomKeysResult> {
|
val importRoomKeysResult = testHelper.doSync<ImportRoomKeysResult> {
|
||||||
testData.aliceSession2.cryptoService().keysBackupService().restoreKeyBackupWithPassword(testData.aliceSession2.cryptoService().keysBackupService().keysBackupVersion!!,
|
testData.aliceSession2.cryptoService().keysBackupService().restoreKeyBackupWithPassword(
|
||||||
|
testData.aliceSession2.cryptoService().keysBackupService().keysBackupVersion!!,
|
||||||
password,
|
password,
|
||||||
null,
|
null,
|
||||||
null,
|
null,
|
||||||
@ -771,7 +775,8 @@ class KeysBackupTest : InstrumentedTest {
|
|||||||
|
|
||||||
// - Restore the e2e backup with the recovery key.
|
// - Restore the e2e backup with the recovery key.
|
||||||
val importRoomKeysResult = testHelper.doSync<ImportRoomKeysResult> {
|
val importRoomKeysResult = testHelper.doSync<ImportRoomKeysResult> {
|
||||||
testData.aliceSession2.cryptoService().keysBackupService().restoreKeysWithRecoveryKey(testData.aliceSession2.cryptoService().keysBackupService().keysBackupVersion!!,
|
testData.aliceSession2.cryptoService().keysBackupService().restoreKeysWithRecoveryKey(
|
||||||
|
testData.aliceSession2.cryptoService().keysBackupService().keysBackupVersion!!,
|
||||||
testData.prepareKeysBackupDataResult.megolmBackupCreationInfo.recoveryKey,
|
testData.prepareKeysBackupDataResult.megolmBackupCreationInfo.recoveryKey,
|
||||||
null,
|
null,
|
||||||
null,
|
null,
|
||||||
@ -1055,7 +1060,11 @@ class KeysBackupTest : InstrumentedTest {
|
|||||||
assertFalse(keysBackup2.isEnabled)
|
assertFalse(keysBackup2.isEnabled)
|
||||||
|
|
||||||
// - Validate the old device from the new one
|
// - Validate the old device from the new one
|
||||||
aliceSession2.cryptoService().setDeviceVerification(DeviceTrustLevel(crossSigningVerified = false, locallyVerified = true), aliceSession2.myUserId, oldDeviceId)
|
aliceSession2.cryptoService().setDeviceVerification(
|
||||||
|
DeviceTrustLevel(crossSigningVerified = false, locallyVerified = true),
|
||||||
|
aliceSession2.myUserId,
|
||||||
|
oldDeviceId
|
||||||
|
)
|
||||||
|
|
||||||
// -> Backup should automatically enable on the new device
|
// -> Backup should automatically enable on the new device
|
||||||
val latch4 = CountDownLatch(1)
|
val latch4 = CountDownLatch(1)
|
||||||
|
@ -88,10 +88,12 @@ internal class KeysBackupTestHelper(
|
|||||||
|
|
||||||
stateObserver.stopAndCheckStates(null)
|
stateObserver.stopAndCheckStates(null)
|
||||||
|
|
||||||
return KeysBackupScenarioData(cryptoTestData,
|
return KeysBackupScenarioData(
|
||||||
|
cryptoTestData,
|
||||||
aliceKeys,
|
aliceKeys,
|
||||||
prepareKeysBackupDataResult,
|
prepareKeysBackupDataResult,
|
||||||
aliceSession2)
|
aliceSession2
|
||||||
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
fun prepareAndCreateKeysBackupData(keysBackup: KeysBackupService,
|
fun prepareAndCreateKeysBackupData(keysBackup: KeysBackupService,
|
||||||
|
@ -207,14 +207,16 @@ class QuadSTests : InstrumentedTest {
|
|||||||
|
|
||||||
// Assert that can decrypt with both keys
|
// Assert that can decrypt with both keys
|
||||||
testHelper.runBlockingTest {
|
testHelper.runBlockingTest {
|
||||||
aliceSession.sharedSecretStorageService().getSecret("my.secret",
|
aliceSession.sharedSecretStorageService().getSecret(
|
||||||
|
"my.secret",
|
||||||
keyId1,
|
keyId1,
|
||||||
RawBytesKeySpec.fromRecoveryKey(key1Info.recoveryKey)!!
|
RawBytesKeySpec.fromRecoveryKey(key1Info.recoveryKey)!!
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
testHelper.runBlockingTest {
|
testHelper.runBlockingTest {
|
||||||
aliceSession.sharedSecretStorageService().getSecret("my.secret",
|
aliceSession.sharedSecretStorageService().getSecret(
|
||||||
|
"my.secret",
|
||||||
keyId2,
|
keyId2,
|
||||||
RawBytesKeySpec.fromRecoveryKey(key2Info.recoveryKey)!!
|
RawBytesKeySpec.fromRecoveryKey(key2Info.recoveryKey)!!
|
||||||
)
|
)
|
||||||
@ -245,13 +247,15 @@ class QuadSTests : InstrumentedTest {
|
|||||||
|
|
||||||
testHelper.runBlockingTest {
|
testHelper.runBlockingTest {
|
||||||
try {
|
try {
|
||||||
aliceSession.sharedSecretStorageService().getSecret("my.secret",
|
aliceSession.sharedSecretStorageService().getSecret(
|
||||||
|
"my.secret",
|
||||||
keyId1,
|
keyId1,
|
||||||
RawBytesKeySpec.fromPassphrase(
|
RawBytesKeySpec.fromPassphrase(
|
||||||
"A bad passphrase",
|
"A bad passphrase",
|
||||||
key1Info.content?.passphrase?.salt ?: "",
|
key1Info.content?.passphrase?.salt ?: "",
|
||||||
key1Info.content?.passphrase?.iterations ?: 0,
|
key1Info.content?.passphrase?.iterations ?: 0,
|
||||||
null)
|
null
|
||||||
|
)
|
||||||
)
|
)
|
||||||
} catch (throwable: Throwable) {
|
} catch (throwable: Throwable) {
|
||||||
assert(throwable is SharedSecretStorageError.BadMac)
|
assert(throwable is SharedSecretStorageError.BadMac)
|
||||||
@ -260,13 +264,15 @@ class QuadSTests : InstrumentedTest {
|
|||||||
|
|
||||||
// Now try with correct key
|
// Now try with correct key
|
||||||
testHelper.runBlockingTest {
|
testHelper.runBlockingTest {
|
||||||
aliceSession.sharedSecretStorageService().getSecret("my.secret",
|
aliceSession.sharedSecretStorageService().getSecret(
|
||||||
|
"my.secret",
|
||||||
keyId1,
|
keyId1,
|
||||||
RawBytesKeySpec.fromPassphrase(
|
RawBytesKeySpec.fromPassphrase(
|
||||||
passphrase,
|
passphrase,
|
||||||
key1Info.content?.passphrase?.salt ?: "",
|
key1Info.content?.passphrase?.salt ?: "",
|
||||||
key1Info.content?.passphrase?.iterations ?: 0,
|
key1Info.content?.passphrase?.iterations ?: 0,
|
||||||
null)
|
null
|
||||||
|
)
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -321,7 +327,8 @@ class QuadSTests : InstrumentedTest {
|
|||||||
keyId,
|
keyId,
|
||||||
passphrase,
|
passphrase,
|
||||||
emptyKeySigner,
|
emptyKeySigner,
|
||||||
null)
|
null
|
||||||
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
assertAccountData(session, "${DefaultSharedSecretStorageService.KEY_ID_BASE}.$keyId")
|
assertAccountData(session, "${DefaultSharedSecretStorageService.KEY_ID_BASE}.$keyId")
|
||||||
|
@ -75,10 +75,12 @@ class SASTest : InstrumentedTest {
|
|||||||
}
|
}
|
||||||
bobVerificationService.addListener(bobListener)
|
bobVerificationService.addListener(bobListener)
|
||||||
|
|
||||||
val txID = aliceVerificationService.beginKeyVerification(VerificationMethod.SAS,
|
val txID = aliceVerificationService.beginKeyVerification(
|
||||||
|
VerificationMethod.SAS,
|
||||||
bobSession.myUserId,
|
bobSession.myUserId,
|
||||||
bobSession.cryptoService().getMyDevice().deviceId,
|
bobSession.cryptoService().getMyDevice().deviceId,
|
||||||
null)
|
null
|
||||||
|
)
|
||||||
assertNotNull("Alice should have a started transaction", txID)
|
assertNotNull("Alice should have a started transaction", txID)
|
||||||
|
|
||||||
val aliceKeyTx = aliceVerificationService.getExistingTransaction(bobSession.myUserId, txID!!)
|
val aliceKeyTx = aliceVerificationService.getExistingTransaction(bobSession.myUserId, txID!!)
|
||||||
@ -467,8 +469,10 @@ class SASTest : InstrumentedTest {
|
|||||||
val aliceTx = aliceVerificationService.getExistingTransaction(bobUserId, verificationSAS!!) as SASDefaultVerificationTransaction
|
val aliceTx = aliceVerificationService.getExistingTransaction(bobUserId, verificationSAS!!) as SASDefaultVerificationTransaction
|
||||||
val bobTx = bobVerificationService.getExistingTransaction(aliceSession.myUserId, verificationSAS) as SASDefaultVerificationTransaction
|
val bobTx = bobVerificationService.getExistingTransaction(aliceSession.myUserId, verificationSAS) as SASDefaultVerificationTransaction
|
||||||
|
|
||||||
assertEquals("Should have same SAS", aliceTx.getShortCodeRepresentation(SasMode.DECIMAL),
|
assertEquals(
|
||||||
bobTx.getShortCodeRepresentation(SasMode.DECIMAL))
|
"Should have same SAS", aliceTx.getShortCodeRepresentation(SasMode.DECIMAL),
|
||||||
|
bobTx.getShortCodeRepresentation(SasMode.DECIMAL)
|
||||||
|
)
|
||||||
|
|
||||||
cryptoTestData.cleanUp(testHelper)
|
cryptoTestData.cleanUp(testHelper)
|
||||||
}
|
}
|
||||||
@ -544,7 +548,8 @@ class SASTest : InstrumentedTest {
|
|||||||
|
|
||||||
// Assert that devices are verified
|
// Assert that devices are verified
|
||||||
val bobDeviceInfoFromAlicePOV: CryptoDeviceInfo? = aliceSession.cryptoService().getDeviceInfo(bobUserId, bobDeviceId)
|
val bobDeviceInfoFromAlicePOV: CryptoDeviceInfo? = aliceSession.cryptoService().getDeviceInfo(bobUserId, bobDeviceId)
|
||||||
val aliceDeviceInfoFromBobPOV: CryptoDeviceInfo? = bobSession.cryptoService().getDeviceInfo(aliceSession.myUserId, aliceSession.cryptoService().getMyDevice().deviceId)
|
val aliceDeviceInfoFromBobPOV: CryptoDeviceInfo? =
|
||||||
|
bobSession.cryptoService().getDeviceInfo(aliceSession.myUserId, aliceSession.cryptoService().getMyDevice().deviceId)
|
||||||
|
|
||||||
assertTrue("alice device should be verified from bob point of view", aliceDeviceInfoFromBobPOV!!.isVerified)
|
assertTrue("alice device should be verified from bob point of view", aliceDeviceInfoFromBobPOV!!.isVerified)
|
||||||
assertTrue("bob device should be verified from alice point of view", bobDeviceInfoFromAlicePOV!!.isVerified)
|
assertTrue("bob device should be verified from alice point of view", bobDeviceInfoFromAlicePOV!!.isVerified)
|
||||||
@ -611,14 +616,16 @@ class SASTest : InstrumentedTest {
|
|||||||
requestID!!,
|
requestID!!,
|
||||||
cryptoTestData.roomId,
|
cryptoTestData.roomId,
|
||||||
bobSession.myUserId,
|
bobSession.myUserId,
|
||||||
bobSession.sessionParams.deviceId!!)
|
bobSession.sessionParams.deviceId!!
|
||||||
|
)
|
||||||
|
|
||||||
bobVerificationService.beginKeyVerificationInDMs(
|
bobVerificationService.beginKeyVerificationInDMs(
|
||||||
VerificationMethod.SAS,
|
VerificationMethod.SAS,
|
||||||
requestID!!,
|
requestID!!,
|
||||||
cryptoTestData.roomId,
|
cryptoTestData.roomId,
|
||||||
aliceSession.myUserId,
|
aliceSession.myUserId,
|
||||||
aliceSession.sessionParams.deviceId!!)
|
aliceSession.sessionParams.deviceId!!
|
||||||
|
)
|
||||||
|
|
||||||
// we should reach SHOW SAS on both
|
// we should reach SHOW SAS on both
|
||||||
var alicePovTx: SasVerificationTransaction?
|
var alicePovTx: SasVerificationTransaction?
|
||||||
|
@ -37,7 +37,8 @@ class QrCodeTest : InstrumentedTest {
|
|||||||
sharedSecret = "MTIzNDU2Nzg"
|
sharedSecret = "MTIzNDU2Nzg"
|
||||||
)
|
)
|
||||||
|
|
||||||
private val value1 = "MATRIX\u0002\u0000\u0000\u000DMaTransaction\u0092Ñ0qCú²íq\u0087á®\u0013à\u0098\u0091\u000DÇéoÃ\"_²lq]hC«¢UMynd¤Ù.ô\u0091XäÏ\u0094ê\u008B«\u009Døl\u000F¿+\u008CË\u0014¤®õÁ\u008BA¥12345678"
|
private val value1 =
|
||||||
|
"MATRIX\u0002\u0000\u0000\u000DMaTransaction\u0092Ñ0qCú²íq\u0087á®\u0013à\u0098\u0091\u000DÇéoÃ\"_²lq]hC«¢UMynd¤Ù.ô\u0091XäÏ\u0094ê\u008B«\u009Døl\u000F¿+\u008CË\u0014¤®õÁ\u008BA¥12345678"
|
||||||
|
|
||||||
private val qrCode2 = QrCodeData.SelfVerifyingMasterKeyTrusted(
|
private val qrCode2 = QrCodeData.SelfVerifyingMasterKeyTrusted(
|
||||||
transactionId = "MaTransaction",
|
transactionId = "MaTransaction",
|
||||||
@ -46,7 +47,8 @@ class QrCodeTest : InstrumentedTest {
|
|||||||
sharedSecret = "MTIzNDU2Nzg"
|
sharedSecret = "MTIzNDU2Nzg"
|
||||||
)
|
)
|
||||||
|
|
||||||
private val value2 = "MATRIX\u0002\u0001\u0000\u000DMaTransaction\u0092Ñ0qCú²íq\u0087á®\u0013à\u0098\u0091\u000DÇéoÃ\"_²lq]hC«¢UMynd¤Ù.ô\u0091XäÏ\u0094ê\u008B«\u009Døl\u000F¿+\u008CË\u0014¤®õÁ\u008BA¥12345678"
|
private val value2 =
|
||||||
|
"MATRIX\u0002\u0001\u0000\u000DMaTransaction\u0092Ñ0qCú²íq\u0087á®\u0013à\u0098\u0091\u000DÇéoÃ\"_²lq]hC«¢UMynd¤Ù.ô\u0091XäÏ\u0094ê\u008B«\u009Døl\u000F¿+\u008CË\u0014¤®õÁ\u008BA¥12345678"
|
||||||
|
|
||||||
private val qrCode3 = QrCodeData.SelfVerifyingMasterKeyNotTrusted(
|
private val qrCode3 = QrCodeData.SelfVerifyingMasterKeyNotTrusted(
|
||||||
transactionId = "MaTransaction",
|
transactionId = "MaTransaction",
|
||||||
@ -55,7 +57,8 @@ class QrCodeTest : InstrumentedTest {
|
|||||||
sharedSecret = "MTIzNDU2Nzg"
|
sharedSecret = "MTIzNDU2Nzg"
|
||||||
)
|
)
|
||||||
|
|
||||||
private val value3 = "MATRIX\u0002\u0002\u0000\u000DMaTransactionMynd¤Ù.ô\u0091XäÏ\u0094ê\u008B«\u009Døl\u000F¿+\u008CË\u0014¤®õÁ\u008BA¥\u0092Ñ0qCú²íq\u0087á®\u0013à\u0098\u0091\u000DÇéoÃ\"_²lq]hC«¢U12345678"
|
private val value3 =
|
||||||
|
"MATRIX\u0002\u0002\u0000\u000DMaTransactionMynd¤Ù.ô\u0091XäÏ\u0094ê\u008B«\u009Døl\u000F¿+\u008CË\u0014¤®õÁ\u008BA¥\u0092Ñ0qCú²íq\u0087á®\u0013à\u0098\u0091\u000DÇéoÃ\"_²lq]hC«¢U12345678"
|
||||||
|
|
||||||
private val sharedSecretByteArray = "12345678".toByteArray(Charsets.ISO_8859_1)
|
private val sharedSecretByteArray = "12345678".toByteArray(Charsets.ISO_8859_1)
|
||||||
|
|
||||||
|
@ -175,7 +175,8 @@ class VerificationTest : InstrumentedTest {
|
|||||||
)
|
)
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
}, callback)
|
}, callback
|
||||||
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
testHelper.doSync<Unit> { callback ->
|
testHelper.doSync<Unit> { callback ->
|
||||||
@ -191,7 +192,8 @@ class VerificationTest : InstrumentedTest {
|
|||||||
)
|
)
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
}, callback)
|
}, callback
|
||||||
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
val aliceVerificationService = aliceSession.cryptoService().verificationService()
|
val aliceVerificationService = aliceSession.cryptoService().verificationService()
|
||||||
|
@ -71,10 +71,12 @@ class MarkdownParserTest : InstrumentedTest {
|
|||||||
testIdentity("")
|
testIdentity("")
|
||||||
testIdentity("a")
|
testIdentity("a")
|
||||||
testIdentity("1")
|
testIdentity("1")
|
||||||
testIdentity("Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et " +
|
testIdentity(
|
||||||
"dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea com" +
|
"Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et " +
|
||||||
"modo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pari" +
|
"dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea com" +
|
||||||
"atur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.")
|
"modo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pari" +
|
||||||
|
"atur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum."
|
||||||
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@ -294,16 +296,20 @@ class MarkdownParserTest : InstrumentedTest {
|
|||||||
"$markdownPattern$name$markdownPattern"
|
"$markdownPattern$name$markdownPattern"
|
||||||
.let {
|
.let {
|
||||||
markdownParser.parse(it)
|
markdownParser.parse(it)
|
||||||
.expect(expectedText = it,
|
.expect(
|
||||||
expectedFormattedText = "<$htmlExpectedTag>$name</$htmlExpectedTag>")
|
expectedText = it,
|
||||||
|
expectedFormattedText = "<$htmlExpectedTag>$name</$htmlExpectedTag>"
|
||||||
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Test twice the same tag
|
// Test twice the same tag
|
||||||
"$markdownPattern$name$markdownPattern and $markdownPattern$name bis$markdownPattern"
|
"$markdownPattern$name$markdownPattern and $markdownPattern$name bis$markdownPattern"
|
||||||
.let {
|
.let {
|
||||||
markdownParser.parse(it)
|
markdownParser.parse(it)
|
||||||
.expect(expectedText = it,
|
.expect(
|
||||||
expectedFormattedText = "<$htmlExpectedTag>$name</$htmlExpectedTag> and <$htmlExpectedTag>$name bis</$htmlExpectedTag>")
|
expectedText = it,
|
||||||
|
expectedFormattedText = "<$htmlExpectedTag>$name</$htmlExpectedTag> and <$htmlExpectedTag>$name bis</$htmlExpectedTag>"
|
||||||
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
val textBefore = "a"
|
val textBefore = "a"
|
||||||
@ -313,48 +319,60 @@ class MarkdownParserTest : InstrumentedTest {
|
|||||||
"$textBefore$markdownPattern$name$markdownPattern"
|
"$textBefore$markdownPattern$name$markdownPattern"
|
||||||
.let {
|
.let {
|
||||||
markdownParser.parse(it)
|
markdownParser.parse(it)
|
||||||
.expect(expectedText = it,
|
.expect(
|
||||||
expectedFormattedText = "$textBefore<$htmlExpectedTag>$name</$htmlExpectedTag>")
|
expectedText = it,
|
||||||
|
expectedFormattedText = "$textBefore<$htmlExpectedTag>$name</$htmlExpectedTag>"
|
||||||
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
// With text before and space
|
// With text before and space
|
||||||
"$textBefore $markdownPattern$name$markdownPattern"
|
"$textBefore $markdownPattern$name$markdownPattern"
|
||||||
.let {
|
.let {
|
||||||
markdownParser.parse(it)
|
markdownParser.parse(it)
|
||||||
.expect(expectedText = it,
|
.expect(
|
||||||
expectedFormattedText = "$textBefore <$htmlExpectedTag>$name</$htmlExpectedTag>")
|
expectedText = it,
|
||||||
|
expectedFormattedText = "$textBefore <$htmlExpectedTag>$name</$htmlExpectedTag>"
|
||||||
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
// With sticked text after
|
// With sticked text after
|
||||||
"$markdownPattern$name$markdownPattern$textAfter"
|
"$markdownPattern$name$markdownPattern$textAfter"
|
||||||
.let {
|
.let {
|
||||||
markdownParser.parse(it)
|
markdownParser.parse(it)
|
||||||
.expect(expectedText = it,
|
.expect(
|
||||||
expectedFormattedText = "<$htmlExpectedTag>$name</$htmlExpectedTag>$textAfter")
|
expectedText = it,
|
||||||
|
expectedFormattedText = "<$htmlExpectedTag>$name</$htmlExpectedTag>$textAfter"
|
||||||
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
// With space and text after
|
// With space and text after
|
||||||
"$markdownPattern$name$markdownPattern $textAfter"
|
"$markdownPattern$name$markdownPattern $textAfter"
|
||||||
.let {
|
.let {
|
||||||
markdownParser.parse(it)
|
markdownParser.parse(it)
|
||||||
.expect(expectedText = it,
|
.expect(
|
||||||
expectedFormattedText = "<$htmlExpectedTag>$name</$htmlExpectedTag> $textAfter")
|
expectedText = it,
|
||||||
|
expectedFormattedText = "<$htmlExpectedTag>$name</$htmlExpectedTag> $textAfter"
|
||||||
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
// With sticked text before and text after
|
// With sticked text before and text after
|
||||||
"$textBefore$markdownPattern$name$markdownPattern$textAfter"
|
"$textBefore$markdownPattern$name$markdownPattern$textAfter"
|
||||||
.let {
|
.let {
|
||||||
markdownParser.parse(it)
|
markdownParser.parse(it)
|
||||||
.expect(expectedText = it,
|
.expect(
|
||||||
expectedFormattedText = "a<$htmlExpectedTag>$name</$htmlExpectedTag>$textAfter")
|
expectedText = it,
|
||||||
|
expectedFormattedText = "a<$htmlExpectedTag>$name</$htmlExpectedTag>$textAfter"
|
||||||
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
// With text before and after, with spaces
|
// With text before and after, with spaces
|
||||||
"$textBefore $markdownPattern$name$markdownPattern $textAfter"
|
"$textBefore $markdownPattern$name$markdownPattern $textAfter"
|
||||||
.let {
|
.let {
|
||||||
markdownParser.parse(it)
|
markdownParser.parse(it)
|
||||||
.expect(expectedText = it,
|
.expect(
|
||||||
expectedFormattedText = "$textBefore <$htmlExpectedTag>$name</$htmlExpectedTag> $textAfter")
|
expectedText = it,
|
||||||
|
expectedFormattedText = "$textBefore <$htmlExpectedTag>$name</$htmlExpectedTag> $textAfter"
|
||||||
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -366,16 +384,20 @@ class MarkdownParserTest : InstrumentedTest {
|
|||||||
"$markdownPattern$name\n$name$markdownPattern"
|
"$markdownPattern$name\n$name$markdownPattern"
|
||||||
.let {
|
.let {
|
||||||
markdownParser.parse(it)
|
markdownParser.parse(it)
|
||||||
.expect(expectedText = it,
|
.expect(
|
||||||
expectedFormattedText = "<$htmlExpectedTag>$name$softBreak$name</$htmlExpectedTag>")
|
expectedText = it,
|
||||||
|
expectedFormattedText = "<$htmlExpectedTag>$name$softBreak$name</$htmlExpectedTag>"
|
||||||
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
// With new line between two blocks
|
// With new line between two blocks
|
||||||
"$markdownPattern$name$markdownPattern\n$markdownPattern$name$markdownPattern"
|
"$markdownPattern$name$markdownPattern\n$markdownPattern$name$markdownPattern"
|
||||||
.let {
|
.let {
|
||||||
markdownParser.parse(it)
|
markdownParser.parse(it)
|
||||||
.expect(expectedText = it,
|
.expect(
|
||||||
expectedFormattedText = "<$htmlExpectedTag>$name</$htmlExpectedTag><br /><$htmlExpectedTag>$name</$htmlExpectedTag>")
|
expectedText = it,
|
||||||
|
expectedFormattedText = "<$htmlExpectedTag>$name</$htmlExpectedTag><br /><$htmlExpectedTag>$name</$htmlExpectedTag>"
|
||||||
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -39,27 +39,35 @@ internal class JsonCanonicalizerTest : InstrumentedTest {
|
|||||||
"""{"a":["c":"b","d":"e"]}""",
|
"""{"a":["c":"b","d":"e"]}""",
|
||||||
"""{"a":["d":"b","c":"e"]}"""
|
"""{"a":["d":"b","c":"e"]}"""
|
||||||
).forEach {
|
).forEach {
|
||||||
assertEquals(it,
|
assertEquals(
|
||||||
JsonCanonicalizer.canonicalize(it))
|
it,
|
||||||
|
JsonCanonicalizer.canonicalize(it)
|
||||||
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
fun reorderTest() {
|
fun reorderTest() {
|
||||||
assertEquals("""{"a":true,"b":false}""",
|
assertEquals(
|
||||||
JsonCanonicalizer.canonicalize("""{"b":false,"a":true}"""))
|
"""{"a":true,"b":false}""",
|
||||||
|
JsonCanonicalizer.canonicalize("""{"b":false,"a":true}""")
|
||||||
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
fun realSampleTest() {
|
fun realSampleTest() {
|
||||||
assertEquals("""{"algorithms":["m.megolm.v1.aes-sha2","m.olm.v1.curve25519-aes-sha2"],"device_id":"VSCUNFSOUI","keys":{"curve25519:VSCUNFSOUI":"utyOjnhiQ73qNhi9HlN0OgWIowe5gthTS8r0r9TcJ3o","ed25519:VSCUNFSOUI":"qNhEt+Yggaajet0hX\/FjTRLfySgs65ldYyomm7PIx6U"},"user_id":"@benoitx:matrix.org"}""",
|
assertEquals(
|
||||||
JsonCanonicalizer.canonicalize("""{"algorithms":["m.megolm.v1.aes-sha2","m.olm.v1.curve25519-aes-sha2"],"device_id":"VSCUNFSOUI","user_id":"@benoitx:matrix.org","keys":{"curve25519:VSCUNFSOUI":"utyOjnhiQ73qNhi9HlN0OgWIowe5gthTS8r0r9TcJ3o","ed25519:VSCUNFSOUI":"qNhEt+Yggaajet0hX/FjTRLfySgs65ldYyomm7PIx6U"}}"""))
|
"""{"algorithms":["m.megolm.v1.aes-sha2","m.olm.v1.curve25519-aes-sha2"],"device_id":"VSCUNFSOUI","keys":{"curve25519:VSCUNFSOUI":"utyOjnhiQ73qNhi9HlN0OgWIowe5gthTS8r0r9TcJ3o","ed25519:VSCUNFSOUI":"qNhEt+Yggaajet0hX\/FjTRLfySgs65ldYyomm7PIx6U"},"user_id":"@benoitx:matrix.org"}""",
|
||||||
|
JsonCanonicalizer.canonicalize("""{"algorithms":["m.megolm.v1.aes-sha2","m.olm.v1.curve25519-aes-sha2"],"device_id":"VSCUNFSOUI","user_id":"@benoitx:matrix.org","keys":{"curve25519:VSCUNFSOUI":"utyOjnhiQ73qNhi9HlN0OgWIowe5gthTS8r0r9TcJ3o","ed25519:VSCUNFSOUI":"qNhEt+Yggaajet0hX/FjTRLfySgs65ldYyomm7PIx6U"}}""")
|
||||||
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
fun doubleQuoteTest() {
|
fun doubleQuoteTest() {
|
||||||
assertEquals("{\"a\":\"\\\"\"}",
|
assertEquals(
|
||||||
JsonCanonicalizer.canonicalize("{\"a\":\"\\\"\"}"))
|
"{\"a\":\"\\\"\"}",
|
||||||
|
JsonCanonicalizer.canonicalize("{\"a\":\"\\\"\"}")
|
||||||
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
/* ==========================================================================================
|
/* ==========================================================================================
|
||||||
@ -68,38 +76,52 @@ internal class JsonCanonicalizerTest : InstrumentedTest {
|
|||||||
|
|
||||||
@Test
|
@Test
|
||||||
fun matrixOrg001Test() {
|
fun matrixOrg001Test() {
|
||||||
assertEquals("""{}""",
|
assertEquals(
|
||||||
JsonCanonicalizer.canonicalize("""{}"""))
|
"""{}""",
|
||||||
|
JsonCanonicalizer.canonicalize("""{}""")
|
||||||
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
fun matrixOrg002Test() {
|
fun matrixOrg002Test() {
|
||||||
assertEquals("""{"one":1,"two":"Two"}""",
|
assertEquals(
|
||||||
JsonCanonicalizer.canonicalize("""{
|
"""{"one":1,"two":"Two"}""",
|
||||||
|
JsonCanonicalizer.canonicalize(
|
||||||
|
"""{
|
||||||
"one": 1,
|
"one": 1,
|
||||||
"two": "Two"
|
"two": "Two"
|
||||||
}"""))
|
}"""
|
||||||
|
)
|
||||||
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
fun matrixOrg003Test() {
|
fun matrixOrg003Test() {
|
||||||
assertEquals("""{"a":"1","b":"2"}""",
|
assertEquals(
|
||||||
JsonCanonicalizer.canonicalize("""{
|
"""{"a":"1","b":"2"}""",
|
||||||
|
JsonCanonicalizer.canonicalize(
|
||||||
|
"""{
|
||||||
"b": "2",
|
"b": "2",
|
||||||
"a": "1"
|
"a": "1"
|
||||||
}"""))
|
}"""
|
||||||
|
)
|
||||||
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
fun matrixOrg004Test() {
|
fun matrixOrg004Test() {
|
||||||
assertEquals("""{"a":"1","b":"2"}""",
|
assertEquals(
|
||||||
JsonCanonicalizer.canonicalize("""{"b":"2","a":"1"}"""))
|
"""{"a":"1","b":"2"}""",
|
||||||
|
JsonCanonicalizer.canonicalize("""{"b":"2","a":"1"}""")
|
||||||
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
fun matrixOrg005Test() {
|
fun matrixOrg005Test() {
|
||||||
assertEquals("""{"auth":{"mxid":"@john.doe:example.com","profile":{"display_name":"John Doe","three_pids":[{"address":"john.doe@example.org","medium":"email"},{"address":"123456789","medium":"msisdn"}]},"success":true}}""",
|
assertEquals(
|
||||||
JsonCanonicalizer.canonicalize("""{
|
"""{"auth":{"mxid":"@john.doe:example.com","profile":{"display_name":"John Doe","three_pids":[{"address":"john.doe@example.org","medium":"email"},{"address":"123456789","medium":"msisdn"}]},"success":true}}""",
|
||||||
|
JsonCanonicalizer.canonicalize(
|
||||||
|
"""{
|
||||||
"auth": {
|
"auth": {
|
||||||
"success": true,
|
"success": true,
|
||||||
"mxid": "@john.doe:example.com",
|
"mxid": "@john.doe:example.com",
|
||||||
@ -117,37 +139,53 @@ internal class JsonCanonicalizerTest : InstrumentedTest {
|
|||||||
]
|
]
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}"""))
|
}"""
|
||||||
|
)
|
||||||
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
fun matrixOrg006Test() {
|
fun matrixOrg006Test() {
|
||||||
assertEquals("""{"a":"日本語"}""",
|
assertEquals(
|
||||||
JsonCanonicalizer.canonicalize("""{
|
"""{"a":"日本語"}""",
|
||||||
|
JsonCanonicalizer.canonicalize(
|
||||||
|
"""{
|
||||||
"a": "日本語"
|
"a": "日本語"
|
||||||
}"""))
|
}"""
|
||||||
|
)
|
||||||
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
fun matrixOrg007Test() {
|
fun matrixOrg007Test() {
|
||||||
assertEquals("""{"日":1,"本":2}""",
|
assertEquals(
|
||||||
JsonCanonicalizer.canonicalize("""{
|
"""{"日":1,"本":2}""",
|
||||||
|
JsonCanonicalizer.canonicalize(
|
||||||
|
"""{
|
||||||
"本": 2,
|
"本": 2,
|
||||||
"日": 1
|
"日": 1
|
||||||
}"""))
|
}"""
|
||||||
|
)
|
||||||
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
fun matrixOrg008Test() {
|
fun matrixOrg008Test() {
|
||||||
assertEquals("""{"a":"日"}""",
|
assertEquals(
|
||||||
JsonCanonicalizer.canonicalize("{\"a\": \"\u65E5\"}"))
|
"""{"a":"日"}""",
|
||||||
|
JsonCanonicalizer.canonicalize("{\"a\": \"\u65E5\"}")
|
||||||
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
fun matrixOrg009Test() {
|
fun matrixOrg009Test() {
|
||||||
assertEquals("""{"a":null}""",
|
assertEquals(
|
||||||
JsonCanonicalizer.canonicalize("""{
|
"""{"a":null}""",
|
||||||
|
JsonCanonicalizer.canonicalize(
|
||||||
|
"""{
|
||||||
"a": null
|
"a": null
|
||||||
}"""))
|
}"""
|
||||||
|
)
|
||||||
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -26,9 +26,18 @@ class StringOrderTest {
|
|||||||
|
|
||||||
@Test
|
@Test
|
||||||
fun testbasing() {
|
fun testbasing() {
|
||||||
assertEquals("a", StringOrderUtils.baseToString(StringOrderUtils.stringToBase("a", StringOrderUtils.DEFAULT_ALPHABET), StringOrderUtils.DEFAULT_ALPHABET))
|
assertEquals(
|
||||||
assertEquals("element", StringOrderUtils.baseToString(StringOrderUtils.stringToBase("element", StringOrderUtils.DEFAULT_ALPHABET), StringOrderUtils.DEFAULT_ALPHABET))
|
"a",
|
||||||
assertEquals("matrix", StringOrderUtils.baseToString(StringOrderUtils.stringToBase("matrix", StringOrderUtils.DEFAULT_ALPHABET), StringOrderUtils.DEFAULT_ALPHABET))
|
StringOrderUtils.baseToString(StringOrderUtils.stringToBase("a", StringOrderUtils.DEFAULT_ALPHABET), StringOrderUtils.DEFAULT_ALPHABET)
|
||||||
|
)
|
||||||
|
assertEquals(
|
||||||
|
"element",
|
||||||
|
StringOrderUtils.baseToString(StringOrderUtils.stringToBase("element", StringOrderUtils.DEFAULT_ALPHABET), StringOrderUtils.DEFAULT_ALPHABET)
|
||||||
|
)
|
||||||
|
assertEquals(
|
||||||
|
"matrix",
|
||||||
|
StringOrderUtils.baseToString(StringOrderUtils.stringToBase("matrix", StringOrderUtils.DEFAULT_ALPHABET), StringOrderUtils.DEFAULT_ALPHABET)
|
||||||
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
|
@ -59,7 +59,8 @@ class ThreadMessagingTest : InstrumentedTest {
|
|||||||
val sentMessages = commonTestHelper.sendTextMessage(
|
val sentMessages = commonTestHelper.sendTextMessage(
|
||||||
room = aliceRoom,
|
room = aliceRoom,
|
||||||
message = textMessage,
|
message = textMessage,
|
||||||
nbOfMessages = 1)
|
nbOfMessages = 1
|
||||||
|
)
|
||||||
|
|
||||||
val initMessage = sentMessages.first()
|
val initMessage = sentMessages.first()
|
||||||
|
|
||||||
@ -73,7 +74,8 @@ class ThreadMessagingTest : InstrumentedTest {
|
|||||||
room = aliceRoom,
|
room = aliceRoom,
|
||||||
message = "Reply In the above thread",
|
message = "Reply In the above thread",
|
||||||
numberOfMessages = 1,
|
numberOfMessages = 1,
|
||||||
rootThreadEventId = initMessage.root.eventId.orEmpty())
|
rootThreadEventId = initMessage.root.eventId.orEmpty()
|
||||||
|
)
|
||||||
|
|
||||||
val replyInThread = repliesInThread.first()
|
val replyInThread = repliesInThread.first()
|
||||||
replyInThread.root.isThread().shouldBeTrue()
|
replyInThread.root.isThread().shouldBeTrue()
|
||||||
@ -116,7 +118,8 @@ class ThreadMessagingTest : InstrumentedTest {
|
|||||||
val sentMessages = commonTestHelper.sendTextMessage(
|
val sentMessages = commonTestHelper.sendTextMessage(
|
||||||
room = aliceRoom,
|
room = aliceRoom,
|
||||||
message = textMessage,
|
message = textMessage,
|
||||||
nbOfMessages = 1)
|
nbOfMessages = 1
|
||||||
|
)
|
||||||
|
|
||||||
val initMessage = sentMessages.first()
|
val initMessage = sentMessages.first()
|
||||||
|
|
||||||
@ -134,7 +137,8 @@ class ThreadMessagingTest : InstrumentedTest {
|
|||||||
room = bobRoom,
|
room = bobRoom,
|
||||||
message = "Reply In the above thread",
|
message = "Reply In the above thread",
|
||||||
numberOfMessages = 1,
|
numberOfMessages = 1,
|
||||||
rootThreadEventId = initMessage.root.eventId.orEmpty())
|
rootThreadEventId = initMessage.root.eventId.orEmpty()
|
||||||
|
)
|
||||||
|
|
||||||
val replyInThread = repliesInThread.first()
|
val replyInThread = repliesInThread.first()
|
||||||
replyInThread.root.isThread().shouldBeTrue()
|
replyInThread.root.isThread().shouldBeTrue()
|
||||||
@ -190,7 +194,8 @@ class ThreadMessagingTest : InstrumentedTest {
|
|||||||
val sentMessages = commonTestHelper.sendTextMessage(
|
val sentMessages = commonTestHelper.sendTextMessage(
|
||||||
room = aliceRoom,
|
room = aliceRoom,
|
||||||
message = textMessage,
|
message = textMessage,
|
||||||
nbOfMessages = 5)
|
nbOfMessages = 5
|
||||||
|
)
|
||||||
|
|
||||||
sentMessages.forEach {
|
sentMessages.forEach {
|
||||||
it.root.isThread().shouldBeFalse()
|
it.root.isThread().shouldBeFalse()
|
||||||
@ -206,7 +211,8 @@ class ThreadMessagingTest : InstrumentedTest {
|
|||||||
room = aliceRoom,
|
room = aliceRoom,
|
||||||
message = "Reply In the above thread",
|
message = "Reply In the above thread",
|
||||||
numberOfMessages = 40,
|
numberOfMessages = 40,
|
||||||
rootThreadEventId = selectedInitMessage.root.eventId.orEmpty())
|
rootThreadEventId = selectedInitMessage.root.eventId.orEmpty()
|
||||||
|
)
|
||||||
|
|
||||||
repliesInThread.forEach {
|
repliesInThread.forEach {
|
||||||
it.root.isThread().shouldBeTrue()
|
it.root.isThread().shouldBeTrue()
|
||||||
@ -253,7 +259,8 @@ class ThreadMessagingTest : InstrumentedTest {
|
|||||||
val sentMessages = commonTestHelper.sendTextMessage(
|
val sentMessages = commonTestHelper.sendTextMessage(
|
||||||
room = aliceRoom,
|
room = aliceRoom,
|
||||||
message = textMessage,
|
message = textMessage,
|
||||||
nbOfMessages = 5)
|
nbOfMessages = 5
|
||||||
|
)
|
||||||
|
|
||||||
sentMessages.forEach {
|
sentMessages.forEach {
|
||||||
it.root.isThread().shouldBeFalse()
|
it.root.isThread().shouldBeFalse()
|
||||||
@ -270,7 +277,8 @@ class ThreadMessagingTest : InstrumentedTest {
|
|||||||
room = aliceRoom,
|
room = aliceRoom,
|
||||||
message = "Alice reply In the above second thread message",
|
message = "Alice reply In the above second thread message",
|
||||||
numberOfMessages = 35,
|
numberOfMessages = 35,
|
||||||
rootThreadEventId = secondMessage.root.eventId.orEmpty())
|
rootThreadEventId = secondMessage.root.eventId.orEmpty()
|
||||||
|
)
|
||||||
|
|
||||||
// Let's reply in timeline to that message from another user
|
// Let's reply in timeline to that message from another user
|
||||||
val bobSession = cryptoTestData.secondSession!!
|
val bobSession = cryptoTestData.secondSession!!
|
||||||
@ -282,14 +290,16 @@ class ThreadMessagingTest : InstrumentedTest {
|
|||||||
room = bobRoom,
|
room = bobRoom,
|
||||||
message = "Bob reply In the above first thread message",
|
message = "Bob reply In the above first thread message",
|
||||||
numberOfMessages = 42,
|
numberOfMessages = 42,
|
||||||
rootThreadEventId = firstMessage.root.eventId.orEmpty())
|
rootThreadEventId = firstMessage.root.eventId.orEmpty()
|
||||||
|
)
|
||||||
|
|
||||||
// Bob will also reply in second thread 5 times
|
// Bob will also reply in second thread 5 times
|
||||||
val bobThreadRepliesInSecondMessage = commonTestHelper.replyInThreadMessage(
|
val bobThreadRepliesInSecondMessage = commonTestHelper.replyInThreadMessage(
|
||||||
room = bobRoom,
|
room = bobRoom,
|
||||||
message = "Another Bob reply In the above second thread message",
|
message = "Another Bob reply In the above second thread message",
|
||||||
numberOfMessages = 20,
|
numberOfMessages = 20,
|
||||||
rootThreadEventId = secondMessage.root.eventId.orEmpty())
|
rootThreadEventId = secondMessage.root.eventId.orEmpty()
|
||||||
|
)
|
||||||
|
|
||||||
aliceThreadRepliesInSecondMessage.forEach {
|
aliceThreadRepliesInSecondMessage.forEach {
|
||||||
it.root.isThread().shouldBeTrue()
|
it.root.isThread().shouldBeTrue()
|
||||||
|
@ -68,7 +68,8 @@ internal class ChunkEntityTest : InstrumentedTest {
|
|||||||
roomId = ROOM_ID,
|
roomId = ROOM_ID,
|
||||||
eventEntity = fakeEvent,
|
eventEntity = fakeEvent,
|
||||||
direction = PaginationDirection.FORWARDS,
|
direction = PaginationDirection.FORWARDS,
|
||||||
roomMemberContentsByUser = emptyMap())
|
roomMemberContentsByUser = emptyMap()
|
||||||
|
)
|
||||||
chunk.timelineEvents.size shouldBeEqualTo 1
|
chunk.timelineEvents.size shouldBeEqualTo 1
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -84,12 +85,14 @@ internal class ChunkEntityTest : InstrumentedTest {
|
|||||||
roomId = ROOM_ID,
|
roomId = ROOM_ID,
|
||||||
eventEntity = fakeEvent,
|
eventEntity = fakeEvent,
|
||||||
direction = PaginationDirection.FORWARDS,
|
direction = PaginationDirection.FORWARDS,
|
||||||
roomMemberContentsByUser = emptyMap())
|
roomMemberContentsByUser = emptyMap()
|
||||||
|
)
|
||||||
chunk.addTimelineEvent(
|
chunk.addTimelineEvent(
|
||||||
roomId = ROOM_ID,
|
roomId = ROOM_ID,
|
||||||
eventEntity = fakeEvent,
|
eventEntity = fakeEvent,
|
||||||
direction = PaginationDirection.FORWARDS,
|
direction = PaginationDirection.FORWARDS,
|
||||||
roomMemberContentsByUser = emptyMap())
|
roomMemberContentsByUser = emptyMap()
|
||||||
|
)
|
||||||
chunk.timelineEvents.size shouldBeEqualTo 1
|
chunk.timelineEvents.size shouldBeEqualTo 1
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -162,7 +165,8 @@ internal class ChunkEntityTest : InstrumentedTest {
|
|||||||
roomId = roomId,
|
roomId = roomId,
|
||||||
eventEntity = fakeEvent,
|
eventEntity = fakeEvent,
|
||||||
direction = direction,
|
direction = direction,
|
||||||
roomMemberContentsByUser = emptyMap())
|
roomMemberContentsByUser = emptyMap()
|
||||||
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -71,7 +71,8 @@ class TimelineForwardPaginationTest : InstrumentedTest {
|
|||||||
val sentMessages = commonTestHelper.sendTextMessage(
|
val sentMessages = commonTestHelper.sendTextMessage(
|
||||||
roomFromAlicePOV,
|
roomFromAlicePOV,
|
||||||
message,
|
message,
|
||||||
numberOfMessagesToSend)
|
numberOfMessagesToSend
|
||||||
|
)
|
||||||
|
|
||||||
// Alice clear the cache and restart the sync
|
// Alice clear the cache and restart the sync
|
||||||
commonTestHelper.clearCacheAndSync(aliceSession)
|
commonTestHelper.clearCacheAndSync(aliceSession)
|
||||||
|
@ -94,7 +94,8 @@ class TimelinePreviousLastForwardTest : InstrumentedTest {
|
|||||||
val firstMessageFromAliceId = commonTestHelper.sendTextMessage(
|
val firstMessageFromAliceId = commonTestHelper.sendTextMessage(
|
||||||
roomFromAlicePOV,
|
roomFromAlicePOV,
|
||||||
firstMessage,
|
firstMessage,
|
||||||
30)
|
30
|
||||||
|
)
|
||||||
.last()
|
.last()
|
||||||
.eventId
|
.eventId
|
||||||
|
|
||||||
@ -130,7 +131,8 @@ class TimelinePreviousLastForwardTest : InstrumentedTest {
|
|||||||
commonTestHelper.sendTextMessage(
|
commonTestHelper.sendTextMessage(
|
||||||
roomFromAlicePOV,
|
roomFromAlicePOV,
|
||||||
secondMessage,
|
secondMessage,
|
||||||
30)
|
30
|
||||||
|
)
|
||||||
|
|
||||||
// Bob start to sync
|
// Bob start to sync
|
||||||
bobSession.startSync(true)
|
bobSession.startSync(true)
|
||||||
|
@ -64,7 +64,8 @@ class TimelineSimpleBackPaginationTest : InstrumentedTest {
|
|||||||
commonTestHelper.sendTextMessage(
|
commonTestHelper.sendTextMessage(
|
||||||
roomFromAlicePOV,
|
roomFromAlicePOV,
|
||||||
message,
|
message,
|
||||||
numberOfMessagesToSent)
|
numberOfMessagesToSent
|
||||||
|
)
|
||||||
|
|
||||||
val bobTimeline = roomFromBobPOV.timelineService().createTimeline(null, TimelineSettings(30))
|
val bobTimeline = roomFromBobPOV.timelineService().createTimeline(null, TimelineSettings(30))
|
||||||
bobTimeline.start()
|
bobTimeline.start()
|
||||||
|
@ -85,7 +85,8 @@ class SearchMessagesTest : InstrumentedTest {
|
|||||||
commonTestHelper.sendTextMessage(
|
commonTestHelper.sendTextMessage(
|
||||||
roomFromAlicePOV,
|
roomFromAlicePOV,
|
||||||
MESSAGE,
|
MESSAGE,
|
||||||
2)
|
2
|
||||||
|
)
|
||||||
|
|
||||||
val data = commonTestHelper.runBlockingTest {
|
val data = commonTestHelper.runBlockingTest {
|
||||||
block.invoke(cryptoTestData)
|
block.invoke(cryptoTestData)
|
||||||
|
@ -177,21 +177,27 @@ class SpaceHierarchyTest : InstrumentedTest {
|
|||||||
val commonTestHelper = CommonTestHelper(context())
|
val commonTestHelper = CommonTestHelper(context())
|
||||||
val session = commonTestHelper.createAccount("John", SessionTestParams(true))
|
val session = commonTestHelper.createAccount("John", SessionTestParams(true))
|
||||||
|
|
||||||
val spaceAInfo = createPublicSpace(session, "SpaceA", listOf(
|
val spaceAInfo = createPublicSpace(
|
||||||
|
session, "SpaceA", listOf(
|
||||||
Triple("A1", true /*auto-join*/, true/*canonical*/),
|
Triple("A1", true /*auto-join*/, true/*canonical*/),
|
||||||
Triple("A2", true, true)
|
Triple("A2", true, true)
|
||||||
))
|
)
|
||||||
|
)
|
||||||
|
|
||||||
/* val spaceBInfo = */ createPublicSpace(session, "SpaceB", listOf(
|
/* val spaceBInfo = */ createPublicSpace(
|
||||||
|
session, "SpaceB", listOf(
|
||||||
Triple("B1", true /*auto-join*/, true/*canonical*/),
|
Triple("B1", true /*auto-join*/, true/*canonical*/),
|
||||||
Triple("B2", true, true),
|
Triple("B2", true, true),
|
||||||
Triple("B3", true, true)
|
Triple("B3", true, true)
|
||||||
))
|
)
|
||||||
|
)
|
||||||
|
|
||||||
val spaceCInfo = createPublicSpace(session, "SpaceC", listOf(
|
val spaceCInfo = createPublicSpace(
|
||||||
|
session, "SpaceC", listOf(
|
||||||
Triple("C1", true /*auto-join*/, true/*canonical*/),
|
Triple("C1", true /*auto-join*/, true/*canonical*/),
|
||||||
Triple("C2", true, true)
|
Triple("C2", true, true)
|
||||||
))
|
)
|
||||||
|
)
|
||||||
|
|
||||||
// add C as a subspace of A
|
// add C as a subspace of A
|
||||||
val spaceA = session.spaceService().getSpace(spaceAInfo.spaceId)
|
val spaceA = session.spaceService().getSpace(spaceAInfo.spaceId)
|
||||||
@ -254,15 +260,19 @@ class SpaceHierarchyTest : InstrumentedTest {
|
|||||||
val commonTestHelper = CommonTestHelper(context())
|
val commonTestHelper = CommonTestHelper(context())
|
||||||
val session = commonTestHelper.createAccount("John", SessionTestParams(true))
|
val session = commonTestHelper.createAccount("John", SessionTestParams(true))
|
||||||
|
|
||||||
val spaceAInfo = createPublicSpace(session, "SpaceA", listOf(
|
val spaceAInfo = createPublicSpace(
|
||||||
|
session, "SpaceA", listOf(
|
||||||
Triple("A1", true /*auto-join*/, true/*canonical*/),
|
Triple("A1", true /*auto-join*/, true/*canonical*/),
|
||||||
Triple("A2", true, true)
|
Triple("A2", true, true)
|
||||||
))
|
)
|
||||||
|
)
|
||||||
|
|
||||||
val spaceCInfo = createPublicSpace(session, "SpaceC", listOf(
|
val spaceCInfo = createPublicSpace(
|
||||||
|
session, "SpaceC", listOf(
|
||||||
Triple("C1", true /*auto-join*/, true/*canonical*/),
|
Triple("C1", true /*auto-join*/, true/*canonical*/),
|
||||||
Triple("C2", true, true)
|
Triple("C2", true, true)
|
||||||
))
|
)
|
||||||
|
)
|
||||||
|
|
||||||
// add C as a subspace of A
|
// add C as a subspace of A
|
||||||
val spaceA = session.spaceService().getSpace(spaceAInfo.spaceId)
|
val spaceA = session.spaceService().getSpace(spaceAInfo.spaceId)
|
||||||
@ -296,16 +306,20 @@ class SpaceHierarchyTest : InstrumentedTest {
|
|||||||
val commonTestHelper = CommonTestHelper(context())
|
val commonTestHelper = CommonTestHelper(context())
|
||||||
val session = commonTestHelper.createAccount("John", SessionTestParams(true))
|
val session = commonTestHelper.createAccount("John", SessionTestParams(true))
|
||||||
|
|
||||||
val spaceAInfo = createPublicSpace(session, "SpaceA", listOf(
|
val spaceAInfo = createPublicSpace(
|
||||||
|
session, "SpaceA", listOf(
|
||||||
Triple("A1", true /*auto-join*/, true/*canonical*/),
|
Triple("A1", true /*auto-join*/, true/*canonical*/),
|
||||||
Triple("A2", true, true)
|
Triple("A2", true, true)
|
||||||
))
|
)
|
||||||
|
)
|
||||||
|
|
||||||
val spaceBInfo = createPublicSpace(session, "SpaceB", listOf(
|
val spaceBInfo = createPublicSpace(
|
||||||
|
session, "SpaceB", listOf(
|
||||||
Triple("B1", true /*auto-join*/, true/*canonical*/),
|
Triple("B1", true /*auto-join*/, true/*canonical*/),
|
||||||
Triple("B2", true, true),
|
Triple("B2", true, true),
|
||||||
Triple("B3", true, true)
|
Triple("B3", true, true)
|
||||||
))
|
)
|
||||||
|
)
|
||||||
|
|
||||||
// add B as a subspace of A
|
// add B as a subspace of A
|
||||||
val spaceA = session.spaceService().getSpace(spaceAInfo.spaceId)
|
val spaceA = session.spaceService().getSpace(spaceAInfo.spaceId)
|
||||||
@ -315,10 +329,12 @@ class SpaceHierarchyTest : InstrumentedTest {
|
|||||||
session.spaceService().setSpaceParent(spaceBInfo.spaceId, spaceAInfo.spaceId, true, viaServers)
|
session.spaceService().setSpaceParent(spaceBInfo.spaceId, spaceAInfo.spaceId, true, viaServers)
|
||||||
}
|
}
|
||||||
|
|
||||||
val spaceCInfo = createPublicSpace(session, "SpaceC", listOf(
|
val spaceCInfo = createPublicSpace(
|
||||||
|
session, "SpaceC", listOf(
|
||||||
Triple("C1", true /*auto-join*/, true/*canonical*/),
|
Triple("C1", true /*auto-join*/, true/*canonical*/),
|
||||||
Triple("C2", true, true)
|
Triple("C2", true, true)
|
||||||
))
|
)
|
||||||
|
)
|
||||||
|
|
||||||
commonTestHelper.waitWithLatch { latch ->
|
commonTestHelper.waitWithLatch { latch ->
|
||||||
|
|
||||||
@ -446,21 +462,27 @@ class SpaceHierarchyTest : InstrumentedTest {
|
|||||||
val commonTestHelper = CommonTestHelper(context())
|
val commonTestHelper = CommonTestHelper(context())
|
||||||
val session = commonTestHelper.createAccount("John", SessionTestParams(true))
|
val session = commonTestHelper.createAccount("John", SessionTestParams(true))
|
||||||
|
|
||||||
/* val spaceAInfo = */ createPublicSpace(session, "SpaceA", listOf(
|
/* val spaceAInfo = */ createPublicSpace(
|
||||||
|
session, "SpaceA", listOf(
|
||||||
Triple("A1", true /*auto-join*/, true/*canonical*/),
|
Triple("A1", true /*auto-join*/, true/*canonical*/),
|
||||||
Triple("A2", true, true)
|
Triple("A2", true, true)
|
||||||
))
|
)
|
||||||
|
)
|
||||||
|
|
||||||
val spaceBInfo = createPublicSpace(session, "SpaceB", listOf(
|
val spaceBInfo = createPublicSpace(
|
||||||
|
session, "SpaceB", listOf(
|
||||||
Triple("B1", true /*auto-join*/, true/*canonical*/),
|
Triple("B1", true /*auto-join*/, true/*canonical*/),
|
||||||
Triple("B2", true, true),
|
Triple("B2", true, true),
|
||||||
Triple("B3", true, true)
|
Triple("B3", true, true)
|
||||||
))
|
)
|
||||||
|
)
|
||||||
|
|
||||||
val spaceCInfo = createPublicSpace(session, "SpaceC", listOf(
|
val spaceCInfo = createPublicSpace(
|
||||||
|
session, "SpaceC", listOf(
|
||||||
Triple("C1", true /*auto-join*/, true/*canonical*/),
|
Triple("C1", true /*auto-join*/, true/*canonical*/),
|
||||||
Triple("C2", true, true)
|
Triple("C2", true, true)
|
||||||
))
|
)
|
||||||
|
)
|
||||||
|
|
||||||
val viaServers = listOf(session.sessionParams.homeServerHost ?: "")
|
val viaServers = listOf(session.sessionParams.homeServerHost ?: "")
|
||||||
|
|
||||||
@ -494,10 +516,12 @@ class SpaceHierarchyTest : InstrumentedTest {
|
|||||||
val aliceSession = commonTestHelper.createAccount("Alice", SessionTestParams(true))
|
val aliceSession = commonTestHelper.createAccount("Alice", SessionTestParams(true))
|
||||||
val bobSession = commonTestHelper.createAccount("Bib", SessionTestParams(true))
|
val bobSession = commonTestHelper.createAccount("Bib", SessionTestParams(true))
|
||||||
|
|
||||||
val spaceAInfo = createPrivateSpace(aliceSession, "Private Space A", listOf(
|
val spaceAInfo = createPrivateSpace(
|
||||||
|
aliceSession, "Private Space A", listOf(
|
||||||
Triple("General", true /*suggested*/, true/*canonical*/),
|
Triple("General", true /*suggested*/, true/*canonical*/),
|
||||||
Triple("Random", true, true)
|
Triple("Random", true, true)
|
||||||
))
|
)
|
||||||
|
)
|
||||||
|
|
||||||
commonTestHelper.runBlockingTest {
|
commonTestHelper.runBlockingTest {
|
||||||
aliceSession.getRoom(spaceAInfo.spaceId)!!.membershipService().invite(bobSession.myUserId, null)
|
aliceSession.getRoom(spaceAInfo.spaceId)!!.membershipService().invite(bobSession.myUserId, null)
|
||||||
|
@ -28,8 +28,12 @@ internal class MathsHtmlNodeRenderer(private val context: HtmlNodeRendererContex
|
|||||||
val display = node.javaClass == DisplayMaths::class.java
|
val display = node.javaClass == DisplayMaths::class.java
|
||||||
val contents = node.firstChild // should be the only child
|
val contents = node.firstChild // should be the only child
|
||||||
val latex = (contents as Text).literal
|
val latex = (contents as Text).literal
|
||||||
val attributes = context.extendAttributes(node, if (display) "div" else "span", Collections.singletonMap("data-mx-maths",
|
val attributes = context.extendAttributes(
|
||||||
latex))
|
node, if (display) "div" else "span", Collections.singletonMap(
|
||||||
|
"data-mx-maths",
|
||||||
|
latex
|
||||||
|
)
|
||||||
|
)
|
||||||
html.tag(if (display) "div" else "span", attributes)
|
html.tag(if (display) "div" else "span", attributes)
|
||||||
html.tag("code")
|
html.tag("code")
|
||||||
context.render(contents)
|
context.render(contents)
|
||||||
|
@ -132,9 +132,11 @@ class Matrix private constructor(context: Context, matrixConfiguration: MatrixCo
|
|||||||
val matrixConfiguration = (appContext as MatrixConfiguration.Provider).providesMatrixConfiguration()
|
val matrixConfiguration = (appContext as MatrixConfiguration.Provider).providesMatrixConfiguration()
|
||||||
instance = Matrix(appContext, matrixConfiguration)
|
instance = Matrix(appContext, matrixConfiguration)
|
||||||
} else {
|
} else {
|
||||||
throw IllegalStateException("Matrix is not initialized properly." +
|
throw IllegalStateException(
|
||||||
" If you want to manage your own Matrix instance use Matrix.createInstance" +
|
"Matrix is not initialized properly." +
|
||||||
" otherwise you should call Matrix.initialize or let your application implement MatrixConfiguration.Provider.")
|
" If you want to manage your own Matrix instance use Matrix.createInstance" +
|
||||||
|
" otherwise you should call Matrix.initialize or let your application implement MatrixConfiguration.Provider."
|
||||||
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return instance
|
return instance
|
||||||
|
@ -1,127 +1,129 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright 2020 The Matrix.org Foundation C.I.C.
|
* Copyright 2020 The Matrix.org Foundation C.I.C.
|
||||||
*
|
*
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
* you may not use this file except in compliance with the License.
|
* you may not use this file except in compliance with the License.
|
||||||
* You may obtain a copy of the License at
|
* You may obtain a copy of the License at
|
||||||
*
|
*
|
||||||
* http://www.apache.org/licenses/LICENSE-2.0
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
*
|
*
|
||||||
* Unless required by applicable law or agreed to in writing, software
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
* See the License for the specific language governing permissions and
|
* See the License for the specific language governing permissions and
|
||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
package org.matrix.android.sdk.api.auth
|
package org.matrix.android.sdk.api.auth
|
||||||
|
|
||||||
import org.matrix.android.sdk.api.auth.data.LocalizedFlowDataLoginTerms
|
import org.matrix.android.sdk.api.auth.data.LocalizedFlowDataLoginTerms
|
||||||
import org.matrix.android.sdk.api.auth.registration.TermPolicies
|
import org.matrix.android.sdk.api.auth.registration.TermPolicies
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* This method extract the policies from the login terms parameter, regarding the user language.
|
* This method extract the policies from the login terms parameter, regarding the user language.
|
||||||
* For each policy, if user language is not found, the default language is used and if not found, the first url and name are used (not predictable)
|
* For each policy, if user language is not found, the default language is used and if not found, the first url and name are used (not predictable)
|
||||||
*
|
*
|
||||||
* Example of Data:
|
* Example of Data:
|
||||||
* <pre>
|
* <pre>
|
||||||
* "m.login.terms": {
|
* "m.login.terms": {
|
||||||
* "policies": {
|
* "policies": {
|
||||||
* "privacy_policy": {
|
* "privacy_policy": {
|
||||||
* "version": "1.0",
|
* "version": "1.0",
|
||||||
* "en": {
|
* "en": {
|
||||||
* "url": "http:\/\/matrix.org\/_matrix\/consent?v=1.0",
|
* "url": "http:\/\/matrix.org\/_matrix\/consent?v=1.0",
|
||||||
* "name": "Terms and Conditions"
|
* "name": "Terms and Conditions"
|
||||||
* }
|
* }
|
||||||
* }
|
* }
|
||||||
* }
|
* }
|
||||||
* }
|
* }
|
||||||
*</pre>
|
*</pre>
|
||||||
*
|
*
|
||||||
* @param userLanguage the user language
|
* @param userLanguage the user language
|
||||||
* @param defaultLanguage the default language to use if the user language is not found for a policy in registrationFlowResponse
|
* @param defaultLanguage the default language to use if the user language is not found for a policy in registrationFlowResponse
|
||||||
*/
|
*/
|
||||||
fun TermPolicies.toLocalizedLoginTerms(userLanguage: String,
|
fun TermPolicies.toLocalizedLoginTerms(userLanguage: String,
|
||||||
defaultLanguage: String = "en"): List<LocalizedFlowDataLoginTerms> {
|
defaultLanguage: String = "en"): List<LocalizedFlowDataLoginTerms> {
|
||||||
val result = ArrayList<LocalizedFlowDataLoginTerms>()
|
val result = ArrayList<LocalizedFlowDataLoginTerms>()
|
||||||
|
|
||||||
val policies = get("policies")
|
val policies = get("policies")
|
||||||
if (policies is Map<*, *>) {
|
if (policies is Map<*, *>) {
|
||||||
policies.keys.forEach { policyName ->
|
policies.keys.forEach { policyName ->
|
||||||
val localizedFlowDataLoginTermsPolicyName = policyName as String
|
val localizedFlowDataLoginTermsPolicyName = policyName as String
|
||||||
var localizedFlowDataLoginTermsVersion: String? = null
|
var localizedFlowDataLoginTermsVersion: String? = null
|
||||||
var localizedFlowDataLoginTermsLocalizedUrl: String? = null
|
var localizedFlowDataLoginTermsLocalizedUrl: String? = null
|
||||||
var localizedFlowDataLoginTermsLocalizedName: String? = null
|
var localizedFlowDataLoginTermsLocalizedName: String? = null
|
||||||
|
|
||||||
val policy = policies[policyName]
|
val policy = policies[policyName]
|
||||||
|
|
||||||
// Enter this policy
|
// Enter this policy
|
||||||
if (policy is Map<*, *>) {
|
if (policy is Map<*, *>) {
|
||||||
// Version
|
// Version
|
||||||
localizedFlowDataLoginTermsVersion = policy["version"] as String?
|
localizedFlowDataLoginTermsVersion = policy["version"] as String?
|
||||||
|
|
||||||
var userLanguageUrlAndName: UrlAndName? = null
|
var userLanguageUrlAndName: UrlAndName? = null
|
||||||
var defaultLanguageUrlAndName: UrlAndName? = null
|
var defaultLanguageUrlAndName: UrlAndName? = null
|
||||||
var firstUrlAndName: UrlAndName? = null
|
var firstUrlAndName: UrlAndName? = null
|
||||||
|
|
||||||
// Search for language
|
// Search for language
|
||||||
policy.keys.forEach { policyKey ->
|
policy.keys.forEach { policyKey ->
|
||||||
when (policyKey) {
|
when (policyKey) {
|
||||||
"version" -> Unit // Ignore
|
"version" -> Unit // Ignore
|
||||||
userLanguage -> {
|
userLanguage -> {
|
||||||
// We found the data for the user language
|
// We found the data for the user language
|
||||||
userLanguageUrlAndName = extractUrlAndName(policy[policyKey])
|
userLanguageUrlAndName = extractUrlAndName(policy[policyKey])
|
||||||
}
|
}
|
||||||
defaultLanguage -> {
|
defaultLanguage -> {
|
||||||
// We found default language
|
// We found default language
|
||||||
defaultLanguageUrlAndName = extractUrlAndName(policy[policyKey])
|
defaultLanguageUrlAndName = extractUrlAndName(policy[policyKey])
|
||||||
}
|
}
|
||||||
else -> {
|
else -> {
|
||||||
if (firstUrlAndName == null) {
|
if (firstUrlAndName == null) {
|
||||||
// Get at least some data
|
// Get at least some data
|
||||||
firstUrlAndName = extractUrlAndName(policy[policyKey])
|
firstUrlAndName = extractUrlAndName(policy[policyKey])
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Copy found language data by priority
|
// Copy found language data by priority
|
||||||
when {
|
when {
|
||||||
userLanguageUrlAndName != null -> {
|
userLanguageUrlAndName != null -> {
|
||||||
localizedFlowDataLoginTermsLocalizedUrl = userLanguageUrlAndName!!.url
|
localizedFlowDataLoginTermsLocalizedUrl = userLanguageUrlAndName!!.url
|
||||||
localizedFlowDataLoginTermsLocalizedName = userLanguageUrlAndName!!.name
|
localizedFlowDataLoginTermsLocalizedName = userLanguageUrlAndName!!.name
|
||||||
}
|
}
|
||||||
defaultLanguageUrlAndName != null -> {
|
defaultLanguageUrlAndName != null -> {
|
||||||
localizedFlowDataLoginTermsLocalizedUrl = defaultLanguageUrlAndName!!.url
|
localizedFlowDataLoginTermsLocalizedUrl = defaultLanguageUrlAndName!!.url
|
||||||
localizedFlowDataLoginTermsLocalizedName = defaultLanguageUrlAndName!!.name
|
localizedFlowDataLoginTermsLocalizedName = defaultLanguageUrlAndName!!.name
|
||||||
}
|
}
|
||||||
firstUrlAndName != null -> {
|
firstUrlAndName != null -> {
|
||||||
localizedFlowDataLoginTermsLocalizedUrl = firstUrlAndName!!.url
|
localizedFlowDataLoginTermsLocalizedUrl = firstUrlAndName!!.url
|
||||||
localizedFlowDataLoginTermsLocalizedName = firstUrlAndName!!.name
|
localizedFlowDataLoginTermsLocalizedName = firstUrlAndName!!.name
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
result.add(LocalizedFlowDataLoginTerms(
|
result.add(
|
||||||
policyName = localizedFlowDataLoginTermsPolicyName,
|
LocalizedFlowDataLoginTerms(
|
||||||
version = localizedFlowDataLoginTermsVersion,
|
policyName = localizedFlowDataLoginTermsPolicyName,
|
||||||
localizedUrl = localizedFlowDataLoginTermsLocalizedUrl,
|
version = localizedFlowDataLoginTermsVersion,
|
||||||
localizedName = localizedFlowDataLoginTermsLocalizedName
|
localizedUrl = localizedFlowDataLoginTermsLocalizedUrl,
|
||||||
))
|
localizedName = localizedFlowDataLoginTermsLocalizedName
|
||||||
}
|
)
|
||||||
}
|
)
|
||||||
|
}
|
||||||
return result
|
}
|
||||||
}
|
|
||||||
|
return result
|
||||||
private fun extractUrlAndName(policyData: Any?): UrlAndName? {
|
}
|
||||||
if (policyData is Map<*, *>) {
|
|
||||||
val url = policyData["url"] as String?
|
private fun extractUrlAndName(policyData: Any?): UrlAndName? {
|
||||||
val name = policyData["name"] as String?
|
if (policyData is Map<*, *>) {
|
||||||
|
val url = policyData["url"] as String?
|
||||||
if (url != null && name != null) {
|
val name = policyData["name"] as String?
|
||||||
return UrlAndName(url, name)
|
|
||||||
}
|
if (url != null && name != null) {
|
||||||
}
|
return UrlAndName(url, name)
|
||||||
return null
|
}
|
||||||
}
|
}
|
||||||
|
return null
|
||||||
|
}
|
||||||
|
@ -88,8 +88,10 @@ fun RegistrationFlowResponse.toFlowResult(): FlowResult {
|
|||||||
val isMandatory = flows?.all { type in it.stages.orEmpty() } == true
|
val isMandatory = flows?.all { type in it.stages.orEmpty() } == true
|
||||||
|
|
||||||
val stage = when (type) {
|
val stage = when (type) {
|
||||||
LoginFlowTypes.RECAPTCHA -> Stage.ReCaptcha(isMandatory, ((params?.get(type) as? Map<*, *>)?.get("public_key") as? String)
|
LoginFlowTypes.RECAPTCHA -> Stage.ReCaptcha(
|
||||||
?: "")
|
isMandatory, ((params?.get(type) as? Map<*, *>)?.get("public_key") as? String)
|
||||||
|
?: ""
|
||||||
|
)
|
||||||
LoginFlowTypes.DUMMY -> Stage.Dummy(isMandatory)
|
LoginFlowTypes.DUMMY -> Stage.Dummy(isMandatory)
|
||||||
LoginFlowTypes.TERMS -> Stage.Terms(isMandatory, params?.get(type) as? TermPolicies ?: emptyMap<String, String>())
|
LoginFlowTypes.TERMS -> Stage.Terms(isMandatory, params?.get(type) as? TermPolicies ?: emptyMap<String, String>())
|
||||||
LoginFlowTypes.EMAIL_IDENTITY -> Stage.Email(isMandatory)
|
LoginFlowTypes.EMAIL_IDENTITY -> Stage.Email(isMandatory)
|
||||||
|
@ -93,7 +93,8 @@ data class CryptoCrossSigningKey(
|
|||||||
userId = userId,
|
userId = userId,
|
||||||
usages = listOf(usage.value),
|
usages = listOf(usage.value),
|
||||||
keys = mapOf("ed25519:$b64key" to b64key),
|
keys = mapOf("ed25519:$b64key" to b64key),
|
||||||
signatures = signMap)
|
signatures = signMap
|
||||||
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -68,7 +68,8 @@ interface FileService {
|
|||||||
mxcUrl = messageContent.getFileUrl(),
|
mxcUrl = messageContent.getFileUrl(),
|
||||||
fileName = messageContent.getFileName(),
|
fileName = messageContent.getFileName(),
|
||||||
mimeType = messageContent.mimeType,
|
mimeType = messageContent.mimeType,
|
||||||
elementToDecrypt = messageContent.encryptedFileInfo?.toElementToDecrypt())
|
elementToDecrypt = messageContent.encryptedFileInfo?.toElementToDecrypt()
|
||||||
|
)
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Use this URI and pass it to intent using flag Intent.FLAG_GRANT_READ_URI_PERMISSION
|
* Use this URI and pass it to intent using flag Intent.FLAG_GRANT_READ_URI_PERMISSION
|
||||||
|
@ -379,9 +379,11 @@ internal class DefaultAuthenticationService @Inject constructor(
|
|||||||
throw MatrixIdFailure.InvalidMatrixId
|
throw MatrixIdFailure.InvalidMatrixId
|
||||||
}
|
}
|
||||||
|
|
||||||
return getWellknownTask.execute(GetWellknownTask.Params(
|
return getWellknownTask.execute(
|
||||||
domain = matrixId.getDomain(),
|
GetWellknownTask.Params(
|
||||||
homeServerConnectionConfig = homeServerConnectionConfig)
|
domain = matrixId.getDomain(),
|
||||||
|
homeServerConnectionConfig = homeServerConnectionConfig
|
||||||
|
)
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -390,13 +392,15 @@ internal class DefaultAuthenticationService @Inject constructor(
|
|||||||
password: String,
|
password: String,
|
||||||
initialDeviceName: String,
|
initialDeviceName: String,
|
||||||
deviceId: String?): Session {
|
deviceId: String?): Session {
|
||||||
return directLoginTask.execute(DirectLoginTask.Params(
|
return directLoginTask.execute(
|
||||||
homeServerConnectionConfig = homeServerConnectionConfig,
|
DirectLoginTask.Params(
|
||||||
userId = matrixId,
|
homeServerConnectionConfig = homeServerConnectionConfig,
|
||||||
password = password,
|
userId = matrixId,
|
||||||
deviceName = initialDeviceName,
|
password = password,
|
||||||
deviceId = deviceId
|
deviceName = initialDeviceName,
|
||||||
))
|
deviceId = deviceId
|
||||||
|
)
|
||||||
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun buildAuthAPI(homeServerConnectionConfig: HomeServerConnectionConfig): AuthAPI {
|
private fun buildAuthAPI(homeServerConnectionConfig: HomeServerConnectionConfig): AuthAPI {
|
||||||
|
@ -21,9 +21,11 @@ import io.realm.annotations.RealmModule
|
|||||||
/**
|
/**
|
||||||
* Realm module for authentication classes
|
* Realm module for authentication classes
|
||||||
*/
|
*/
|
||||||
@RealmModule(library = true,
|
@RealmModule(
|
||||||
|
library = true,
|
||||||
classes = [
|
classes = [
|
||||||
SessionParamsEntity::class,
|
SessionParamsEntity::class,
|
||||||
PendingSessionEntity::class
|
PendingSessionEntity::class
|
||||||
])
|
]
|
||||||
|
)
|
||||||
internal class AuthRealmModule
|
internal class AuthRealmModule
|
||||||
|
@ -44,7 +44,8 @@ internal class PendingSessionMapper @Inject constructor(moshi: Moshi) {
|
|||||||
resetPasswordData = resetPasswordData,
|
resetPasswordData = resetPasswordData,
|
||||||
currentSession = entity.currentSession,
|
currentSession = entity.currentSession,
|
||||||
isRegistrationStarted = entity.isRegistrationStarted,
|
isRegistrationStarted = entity.isRegistrationStarted,
|
||||||
currentThreePidData = threePidData)
|
currentThreePidData = threePidData
|
||||||
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
fun map(sessionData: PendingSessionData?): PendingSessionEntity? {
|
fun map(sessionData: PendingSessionData?): PendingSessionEntity? {
|
||||||
|
@ -54,6 +54,7 @@ internal class SessionParamsMapper @Inject constructor(moshi: Moshi) {
|
|||||||
sessionParams.userId,
|
sessionParams.userId,
|
||||||
credentialsJson,
|
credentialsJson,
|
||||||
homeServerConnectionConfigJson,
|
homeServerConnectionConfigJson,
|
||||||
sessionParams.isTokenValid)
|
sessionParams.isTokenValid
|
||||||
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -120,21 +120,25 @@ internal class DefaultRegistrationWizard(
|
|||||||
RegisterAddThreePidTask.Params(
|
RegisterAddThreePidTask.Params(
|
||||||
threePid,
|
threePid,
|
||||||
pendingSessionData.clientSecret,
|
pendingSessionData.clientSecret,
|
||||||
pendingSessionData.sendAttempt))
|
pendingSessionData.sendAttempt
|
||||||
|
)
|
||||||
|
)
|
||||||
|
|
||||||
pendingSessionData = pendingSessionData.copy(sendAttempt = pendingSessionData.sendAttempt + 1)
|
pendingSessionData = pendingSessionData.copy(sendAttempt = pendingSessionData.sendAttempt + 1)
|
||||||
.also { pendingSessionStore.savePendingSessionData(it) }
|
.also { pendingSessionStore.savePendingSessionData(it) }
|
||||||
|
|
||||||
val params = RegistrationParams(
|
val params = RegistrationParams(
|
||||||
auth = if (threePid is RegisterThreePid.Email) {
|
auth = if (threePid is RegisterThreePid.Email) {
|
||||||
AuthParams.createForEmailIdentity(safeSession,
|
AuthParams.createForEmailIdentity(
|
||||||
|
safeSession,
|
||||||
ThreePidCredentials(
|
ThreePidCredentials(
|
||||||
clientSecret = pendingSessionData.clientSecret,
|
clientSecret = pendingSessionData.clientSecret,
|
||||||
sid = response.sid
|
sid = response.sid
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
} else {
|
} else {
|
||||||
AuthParams.createForMsisdnIdentity(safeSession,
|
AuthParams.createForMsisdnIdentity(
|
||||||
|
safeSession,
|
||||||
ThreePidCredentials(
|
ThreePidCredentials(
|
||||||
clientSecret = pendingSessionData.clientSecret,
|
clientSecret = pendingSessionData.clientSecret,
|
||||||
sid = response.sid
|
sid = response.sid
|
||||||
|
@ -712,8 +712,10 @@ internal class DefaultCryptoService @Inject constructor(
|
|||||||
}.foldToCallback(callback)
|
}.foldToCallback(callback)
|
||||||
} else {
|
} else {
|
||||||
val algorithm = getEncryptionAlgorithm(roomId)
|
val algorithm = getEncryptionAlgorithm(roomId)
|
||||||
val reason = String.format(MXCryptoError.UNABLE_TO_ENCRYPT_REASON,
|
val reason = String.format(
|
||||||
algorithm ?: MXCryptoError.NO_MORE_ALGORITHM_REASON)
|
MXCryptoError.UNABLE_TO_ENCRYPT_REASON,
|
||||||
|
algorithm ?: MXCryptoError.NO_MORE_ALGORITHM_REASON
|
||||||
|
)
|
||||||
Timber.tag(loggerTag.value).e("encryptEventContent() : failed $reason")
|
Timber.tag(loggerTag.value).e("encryptEventContent() : failed $reason")
|
||||||
callback.onFailure(Failure.CryptoError(MXCryptoError.Base(MXCryptoError.ErrorType.UNABLE_TO_ENCRYPT, reason)))
|
callback.onFailure(Failure.CryptoError(MXCryptoError.Base(MXCryptoError.ErrorType.UNABLE_TO_ENCRYPT, reason)))
|
||||||
}
|
}
|
||||||
|
@ -137,10 +137,14 @@ internal class EnsureOlmSessionsForDevicesAction @Inject constructor(
|
|||||||
olmDevice.verifySignature(fingerprint, oneTimeKey.signalableJSONDictionary(), signature)
|
olmDevice.verifySignature(fingerprint, oneTimeKey.signalableJSONDictionary(), signature)
|
||||||
isVerified = true
|
isVerified = true
|
||||||
} catch (e: Exception) {
|
} catch (e: Exception) {
|
||||||
Timber.tag(loggerTag.value).d(e, "verifyKeyAndStartSession() : Verify error for otk: ${oneTimeKey.signalableJSONDictionary()}," +
|
Timber.tag(loggerTag.value).d(
|
||||||
" signature:$signature fingerprint:$fingerprint")
|
e, "verifyKeyAndStartSession() : Verify error for otk: ${oneTimeKey.signalableJSONDictionary()}," +
|
||||||
Timber.tag(loggerTag.value).e("verifyKeyAndStartSession() : Verify error for ${deviceInfo.userId}|${deviceInfo.deviceId} " +
|
" signature:$signature fingerprint:$fingerprint"
|
||||||
" - signable json ${oneTimeKey.signalableJSONDictionary()}")
|
)
|
||||||
|
Timber.tag(loggerTag.value).e(
|
||||||
|
"verifyKeyAndStartSession() : Verify error for ${deviceInfo.userId}|${deviceInfo.deviceId} " +
|
||||||
|
" - signable json ${oneTimeKey.signalableJSONDictionary()}"
|
||||||
|
)
|
||||||
errorMessage = e.message
|
errorMessage = e.message
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -96,11 +96,13 @@ internal class MXMegolmDecryption(private val userId: String,
|
|||||||
}
|
}
|
||||||
|
|
||||||
return runCatching {
|
return runCatching {
|
||||||
olmDevice.decryptGroupMessage(encryptedEventContent.ciphertext,
|
olmDevice.decryptGroupMessage(
|
||||||
|
encryptedEventContent.ciphertext,
|
||||||
event.roomId,
|
event.roomId,
|
||||||
timeline,
|
timeline,
|
||||||
encryptedEventContent.sessionId,
|
encryptedEventContent.sessionId,
|
||||||
encryptedEventContent.senderKey)
|
encryptedEventContent.senderKey
|
||||||
|
)
|
||||||
}
|
}
|
||||||
.fold(
|
.fold(
|
||||||
{ olmDecryptionResult ->
|
{ olmDecryptionResult ->
|
||||||
@ -132,9 +134,11 @@ internal class MXMegolmDecryption(private val userId: String,
|
|||||||
requestKeysForEvent(event, true)
|
requestKeysForEvent(event, true)
|
||||||
}
|
}
|
||||||
// Encapsulate as withHeld exception
|
// Encapsulate as withHeld exception
|
||||||
throw MXCryptoError.Base(MXCryptoError.ErrorType.KEYS_WITHHELD,
|
throw MXCryptoError.Base(
|
||||||
|
MXCryptoError.ErrorType.KEYS_WITHHELD,
|
||||||
withHeldInfo.code?.value ?: "",
|
withHeldInfo.code?.value ?: "",
|
||||||
withHeldInfo.reason)
|
withHeldInfo.reason
|
||||||
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
if (requestKeysOnFail) {
|
if (requestKeysOnFail) {
|
||||||
@ -144,7 +148,8 @@ internal class MXMegolmDecryption(private val userId: String,
|
|||||||
throw MXCryptoError.Base(
|
throw MXCryptoError.Base(
|
||||||
MXCryptoError.ErrorType.UNKNOWN_MESSAGE_INDEX,
|
MXCryptoError.ErrorType.UNKNOWN_MESSAGE_INDEX,
|
||||||
"UNKNOWN_MESSAGE_INDEX",
|
"UNKNOWN_MESSAGE_INDEX",
|
||||||
null)
|
null
|
||||||
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
val reason = String.format(MXCryptoError.OLM_REASON, throwable.olmException.message)
|
val reason = String.format(MXCryptoError.OLM_REASON, throwable.olmException.message)
|
||||||
@ -153,7 +158,8 @@ internal class MXMegolmDecryption(private val userId: String,
|
|||||||
throw MXCryptoError.Base(
|
throw MXCryptoError.Base(
|
||||||
MXCryptoError.ErrorType.OLM,
|
MXCryptoError.ErrorType.OLM,
|
||||||
reason,
|
reason,
|
||||||
detailedReason)
|
detailedReason
|
||||||
|
)
|
||||||
}
|
}
|
||||||
if (throwable is MXCryptoError.Base) {
|
if (throwable is MXCryptoError.Base) {
|
||||||
if (
|
if (
|
||||||
@ -166,9 +172,11 @@ internal class MXMegolmDecryption(private val userId: String,
|
|||||||
requestKeysForEvent(event, true)
|
requestKeysForEvent(event, true)
|
||||||
}
|
}
|
||||||
// Encapsulate as withHeld exception
|
// Encapsulate as withHeld exception
|
||||||
throw MXCryptoError.Base(MXCryptoError.ErrorType.KEYS_WITHHELD,
|
throw MXCryptoError.Base(
|
||||||
|
MXCryptoError.ErrorType.KEYS_WITHHELD,
|
||||||
withHeldInfo.code?.value ?: "",
|
withHeldInfo.code?.value ?: "",
|
||||||
withHeldInfo.reason)
|
withHeldInfo.reason
|
||||||
|
)
|
||||||
} else {
|
} else {
|
||||||
// This is un-used in Matrix Android SDK2, not sure if needed
|
// This is un-used in Matrix Android SDK2, not sure if needed
|
||||||
// addEventToPendingList(event, timeline)
|
// addEventToPendingList(event, timeline)
|
||||||
@ -298,13 +306,15 @@ internal class MXMegolmDecryption(private val userId: String,
|
|||||||
}
|
}
|
||||||
|
|
||||||
Timber.tag(loggerTag.value).i("onRoomKeyEvent addInboundGroupSession ${roomKeyContent.sessionId}")
|
Timber.tag(loggerTag.value).i("onRoomKeyEvent addInboundGroupSession ${roomKeyContent.sessionId}")
|
||||||
val added = olmDevice.addInboundGroupSession(roomKeyContent.sessionId,
|
val added = olmDevice.addInboundGroupSession(
|
||||||
|
roomKeyContent.sessionId,
|
||||||
roomKeyContent.sessionKey,
|
roomKeyContent.sessionKey,
|
||||||
roomKeyContent.roomId,
|
roomKeyContent.roomId,
|
||||||
senderKey,
|
senderKey,
|
||||||
forwardingCurve25519KeyChain,
|
forwardingCurve25519KeyChain,
|
||||||
keysClaimed,
|
keysClaimed,
|
||||||
exportFormat)
|
exportFormat
|
||||||
|
)
|
||||||
|
|
||||||
if (added) {
|
if (added) {
|
||||||
defaultKeysBackupService.maybeBackupKeys()
|
defaultKeysBackupService.maybeBackupKeys()
|
||||||
|
@ -56,6 +56,7 @@ internal class MXMegolmDecryptionFactory @Inject constructor(
|
|||||||
sendToDeviceTask,
|
sendToDeviceTask,
|
||||||
coroutineDispatchers,
|
coroutineDispatchers,
|
||||||
cryptoCoroutineScope,
|
cryptoCoroutineScope,
|
||||||
eventsManager)
|
eventsManager
|
||||||
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -337,8 +337,9 @@ internal class MXMegolmEncryption(
|
|||||||
sessionId: String,
|
sessionId: String,
|
||||||
senderKey: String?,
|
senderKey: String?,
|
||||||
code: WithHeldCode) {
|
code: WithHeldCode) {
|
||||||
Timber.tag(loggerTag.value).d("notifyKeyWithHeld() :sending withheld for session:$sessionId and code $code to" +
|
Timber.tag(loggerTag.value).d(
|
||||||
" ${targets.joinToString { "${it.userId}|${it.deviceId}" }}"
|
"notifyKeyWithHeld() :sending withheld for session:$sessionId and code $code to" +
|
||||||
|
" ${targets.joinToString { "${it.userId}|${it.deviceId}" }}"
|
||||||
)
|
)
|
||||||
val withHeldContent = RoomKeyWithHeldContent(
|
val withHeldContent = RoomKeyWithHeldContent(
|
||||||
roomId = roomId,
|
roomId = roomId,
|
||||||
|
@ -36,6 +36,7 @@ internal class SharedWithHelper(
|
|||||||
userId = deviceInfo.userId,
|
userId = deviceInfo.userId,
|
||||||
deviceId = deviceInfo.deviceId,
|
deviceId = deviceInfo.deviceId,
|
||||||
deviceIdentityKey = deviceInfo.identityKey() ?: "",
|
deviceIdentityKey = deviceInfo.identityKey() ?: "",
|
||||||
chainIndex = chainIndex)
|
chainIndex = chainIndex
|
||||||
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -45,20 +45,26 @@ internal class MXOlmDecryption(
|
|||||||
override suspend fun decryptEvent(event: Event, timeline: String): MXEventDecryptionResult {
|
override suspend fun decryptEvent(event: Event, timeline: String): MXEventDecryptionResult {
|
||||||
val olmEventContent = event.content.toModel<OlmEventContent>() ?: run {
|
val olmEventContent = event.content.toModel<OlmEventContent>() ?: run {
|
||||||
Timber.tag(loggerTag.value).e("## decryptEvent() : bad event format")
|
Timber.tag(loggerTag.value).e("## decryptEvent() : bad event format")
|
||||||
throw MXCryptoError.Base(MXCryptoError.ErrorType.BAD_EVENT_FORMAT,
|
throw MXCryptoError.Base(
|
||||||
MXCryptoError.BAD_EVENT_FORMAT_TEXT_REASON)
|
MXCryptoError.ErrorType.BAD_EVENT_FORMAT,
|
||||||
|
MXCryptoError.BAD_EVENT_FORMAT_TEXT_REASON
|
||||||
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
val cipherText = olmEventContent.ciphertext ?: run {
|
val cipherText = olmEventContent.ciphertext ?: run {
|
||||||
Timber.tag(loggerTag.value).e("## decryptEvent() : missing cipher text")
|
Timber.tag(loggerTag.value).e("## decryptEvent() : missing cipher text")
|
||||||
throw MXCryptoError.Base(MXCryptoError.ErrorType.MISSING_CIPHER_TEXT,
|
throw MXCryptoError.Base(
|
||||||
MXCryptoError.MISSING_CIPHER_TEXT_REASON)
|
MXCryptoError.ErrorType.MISSING_CIPHER_TEXT,
|
||||||
|
MXCryptoError.MISSING_CIPHER_TEXT_REASON
|
||||||
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
val senderKey = olmEventContent.senderKey ?: run {
|
val senderKey = olmEventContent.senderKey ?: run {
|
||||||
Timber.tag(loggerTag.value).e("## decryptEvent() : missing sender key")
|
Timber.tag(loggerTag.value).e("## decryptEvent() : missing sender key")
|
||||||
throw MXCryptoError.Base(MXCryptoError.ErrorType.MISSING_SENDER_KEY,
|
throw MXCryptoError.Base(
|
||||||
MXCryptoError.MISSING_SENDER_KEY_TEXT_REASON)
|
MXCryptoError.ErrorType.MISSING_SENDER_KEY,
|
||||||
|
MXCryptoError.MISSING_SENDER_KEY_TEXT_REASON
|
||||||
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
val messageAny = cipherText[olmDevice.deviceCurve25519Key] ?: run {
|
val messageAny = cipherText[olmDevice.deviceCurve25519Key] ?: run {
|
||||||
@ -98,52 +104,70 @@ internal class MXOlmDecryption(
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (olmPayloadContent.recipient != userId) {
|
if (olmPayloadContent.recipient != userId) {
|
||||||
Timber.tag(loggerTag.value).e("## decryptEvent() : Event ${event.eventId}:" +
|
Timber.tag(loggerTag.value).e(
|
||||||
" Intended recipient ${olmPayloadContent.recipient} does not match our id $userId")
|
"## decryptEvent() : Event ${event.eventId}:" +
|
||||||
throw MXCryptoError.Base(MXCryptoError.ErrorType.BAD_RECIPIENT,
|
" Intended recipient ${olmPayloadContent.recipient} does not match our id $userId"
|
||||||
String.format(MXCryptoError.BAD_RECIPIENT_REASON, olmPayloadContent.recipient))
|
)
|
||||||
|
throw MXCryptoError.Base(
|
||||||
|
MXCryptoError.ErrorType.BAD_RECIPIENT,
|
||||||
|
String.format(MXCryptoError.BAD_RECIPIENT_REASON, olmPayloadContent.recipient)
|
||||||
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
val recipientKeys = olmPayloadContent.recipientKeys ?: run {
|
val recipientKeys = olmPayloadContent.recipientKeys ?: run {
|
||||||
Timber.tag(loggerTag.value).e("## decryptEvent() : Olm event (id=${event.eventId}) contains no 'recipient_keys'" +
|
Timber.tag(loggerTag.value).e(
|
||||||
" property; cannot prevent unknown-key attack")
|
"## decryptEvent() : Olm event (id=${event.eventId}) contains no 'recipient_keys'" +
|
||||||
throw MXCryptoError.Base(MXCryptoError.ErrorType.MISSING_PROPERTY,
|
" property; cannot prevent unknown-key attack"
|
||||||
String.format(MXCryptoError.ERROR_MISSING_PROPERTY_REASON, "recipient_keys"))
|
)
|
||||||
|
throw MXCryptoError.Base(
|
||||||
|
MXCryptoError.ErrorType.MISSING_PROPERTY,
|
||||||
|
String.format(MXCryptoError.ERROR_MISSING_PROPERTY_REASON, "recipient_keys")
|
||||||
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
val ed25519 = recipientKeys["ed25519"]
|
val ed25519 = recipientKeys["ed25519"]
|
||||||
|
|
||||||
if (ed25519 != olmDevice.deviceEd25519Key) {
|
if (ed25519 != olmDevice.deviceEd25519Key) {
|
||||||
Timber.tag(loggerTag.value).e("## decryptEvent() : Event ${event.eventId}: Intended recipient ed25519 key $ed25519 did not match ours")
|
Timber.tag(loggerTag.value).e("## decryptEvent() : Event ${event.eventId}: Intended recipient ed25519 key $ed25519 did not match ours")
|
||||||
throw MXCryptoError.Base(MXCryptoError.ErrorType.BAD_RECIPIENT_KEY,
|
throw MXCryptoError.Base(
|
||||||
MXCryptoError.BAD_RECIPIENT_KEY_REASON)
|
MXCryptoError.ErrorType.BAD_RECIPIENT_KEY,
|
||||||
|
MXCryptoError.BAD_RECIPIENT_KEY_REASON
|
||||||
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
if (olmPayloadContent.sender.isNullOrBlank()) {
|
if (olmPayloadContent.sender.isNullOrBlank()) {
|
||||||
Timber.tag(loggerTag.value)
|
Timber.tag(loggerTag.value)
|
||||||
.e("## decryptEvent() : Olm event (id=${event.eventId}) contains no 'sender' property; cannot prevent unknown-key attack")
|
.e("## decryptEvent() : Olm event (id=${event.eventId}) contains no 'sender' property; cannot prevent unknown-key attack")
|
||||||
throw MXCryptoError.Base(MXCryptoError.ErrorType.MISSING_PROPERTY,
|
throw MXCryptoError.Base(
|
||||||
String.format(MXCryptoError.ERROR_MISSING_PROPERTY_REASON, "sender"))
|
MXCryptoError.ErrorType.MISSING_PROPERTY,
|
||||||
|
String.format(MXCryptoError.ERROR_MISSING_PROPERTY_REASON, "sender")
|
||||||
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
if (olmPayloadContent.sender != event.senderId) {
|
if (olmPayloadContent.sender != event.senderId) {
|
||||||
Timber.tag(loggerTag.value)
|
Timber.tag(loggerTag.value)
|
||||||
.e("Event ${event.eventId}: sender ${olmPayloadContent.sender} does not match reported sender ${event.senderId}")
|
.e("Event ${event.eventId}: sender ${olmPayloadContent.sender} does not match reported sender ${event.senderId}")
|
||||||
throw MXCryptoError.Base(MXCryptoError.ErrorType.FORWARDED_MESSAGE,
|
throw MXCryptoError.Base(
|
||||||
String.format(MXCryptoError.FORWARDED_MESSAGE_REASON, olmPayloadContent.sender))
|
MXCryptoError.ErrorType.FORWARDED_MESSAGE,
|
||||||
|
String.format(MXCryptoError.FORWARDED_MESSAGE_REASON, olmPayloadContent.sender)
|
||||||
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
if (olmPayloadContent.roomId != event.roomId) {
|
if (olmPayloadContent.roomId != event.roomId) {
|
||||||
Timber.tag(loggerTag.value)
|
Timber.tag(loggerTag.value)
|
||||||
.e("## decryptEvent() : Event ${event.eventId}: room ${olmPayloadContent.roomId} does not match reported room ${event.roomId}")
|
.e("## decryptEvent() : Event ${event.eventId}: room ${olmPayloadContent.roomId} does not match reported room ${event.roomId}")
|
||||||
throw MXCryptoError.Base(MXCryptoError.ErrorType.BAD_ROOM,
|
throw MXCryptoError.Base(
|
||||||
String.format(MXCryptoError.BAD_ROOM_REASON, olmPayloadContent.roomId))
|
MXCryptoError.ErrorType.BAD_ROOM,
|
||||||
|
String.format(MXCryptoError.BAD_ROOM_REASON, olmPayloadContent.roomId)
|
||||||
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
val keys = olmPayloadContent.keys ?: run {
|
val keys = olmPayloadContent.keys ?: run {
|
||||||
Timber.tag(loggerTag.value).e("## decryptEvent failed : null keys")
|
Timber.tag(loggerTag.value).e("## decryptEvent failed : null keys")
|
||||||
throw MXCryptoError.Base(MXCryptoError.ErrorType.UNABLE_TO_DECRYPT,
|
throw MXCryptoError.Base(
|
||||||
MXCryptoError.MISSING_CIPHER_TEXT_REASON)
|
MXCryptoError.ErrorType.UNABLE_TO_DECRYPT,
|
||||||
|
MXCryptoError.MISSING_CIPHER_TEXT_REASON
|
||||||
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
return MXEventDecryptionResult(
|
return MXEventDecryptionResult(
|
||||||
|
@ -26,6 +26,7 @@ internal class MXOlmDecryptionFactory @Inject constructor(private val olmDevice:
|
|||||||
fun create(): MXOlmDecryption {
|
fun create(): MXOlmDecryption {
|
||||||
return MXOlmDecryption(
|
return MXOlmDecryption(
|
||||||
olmDevice,
|
olmDevice,
|
||||||
userId)
|
userId
|
||||||
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -38,6 +38,7 @@ internal class MXOlmEncryptionFactory @Inject constructor(private val olmDevice:
|
|||||||
cryptoStore,
|
cryptoStore,
|
||||||
messageEncrypter,
|
messageEncrypter,
|
||||||
deviceListManager,
|
deviceListManager,
|
||||||
ensureOlmSessionsForUsersAction)
|
ensureOlmSessionsForUsersAction
|
||||||
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -566,8 +566,10 @@ internal class DefaultCrossSigningService @Inject constructor(
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Sign the other MasterKey with our UserSigning key
|
// Sign the other MasterKey with our UserSigning key
|
||||||
val newSignature = JsonCanonicalizer.getCanonicalJson(Map::class.java,
|
val newSignature = JsonCanonicalizer.getCanonicalJson(
|
||||||
otherMasterKeys.signalableJSONDictionary()).let { userPkSigning?.sign(it) }
|
Map::class.java,
|
||||||
|
otherMasterKeys.signalableJSONDictionary()
|
||||||
|
).let { userPkSigning?.sign(it) }
|
||||||
|
|
||||||
if (newSignature == null) {
|
if (newSignature == null) {
|
||||||
// race??
|
// race??
|
||||||
@ -684,7 +686,8 @@ internal class DefaultCrossSigningService @Inject constructor(
|
|||||||
val otherSSKSignature = otherDevice.signatures?.get(otherUserId)?.get("ed25519:${otherKeys.selfSigningKey()?.unpaddedBase64PublicKey}")
|
val otherSSKSignature = otherDevice.signatures?.get(otherUserId)?.get("ed25519:${otherKeys.selfSigningKey()?.unpaddedBase64PublicKey}")
|
||||||
?: return legacyFallbackTrust(
|
?: return legacyFallbackTrust(
|
||||||
locallyTrusted,
|
locallyTrusted,
|
||||||
DeviceTrustResult.MissingDeviceSignature(otherDeviceId, otherKeys.selfSigningKey()
|
DeviceTrustResult.MissingDeviceSignature(
|
||||||
|
otherDeviceId, otherKeys.selfSigningKey()
|
||||||
?.unpaddedBase64PublicKey
|
?.unpaddedBase64PublicKey
|
||||||
?: ""
|
?: ""
|
||||||
)
|
)
|
||||||
@ -733,7 +736,8 @@ internal class DefaultCrossSigningService @Inject constructor(
|
|||||||
val otherSSKSignature = otherDevice.signatures?.get(otherKeys.userId)?.get("ed25519:${otherKeys.selfSigningKey()?.unpaddedBase64PublicKey}")
|
val otherSSKSignature = otherDevice.signatures?.get(otherKeys.userId)?.get("ed25519:${otherKeys.selfSigningKey()?.unpaddedBase64PublicKey}")
|
||||||
?: return legacyFallbackTrust(
|
?: return legacyFallbackTrust(
|
||||||
locallyTrusted,
|
locallyTrusted,
|
||||||
DeviceTrustResult.MissingDeviceSignature(otherDevice.deviceId, otherKeys.selfSigningKey()
|
DeviceTrustResult.MissingDeviceSignature(
|
||||||
|
otherDevice.deviceId, otherKeys.selfSigningKey()
|
||||||
?.unpaddedBase64PublicKey
|
?.unpaddedBase64PublicKey
|
||||||
?: ""
|
?: ""
|
||||||
)
|
)
|
||||||
|
@ -516,7 +516,8 @@ internal class DefaultKeysBackupService @Inject constructor(
|
|||||||
UpdateKeysBackupVersionBody(
|
UpdateKeysBackupVersionBody(
|
||||||
algorithm = keysBackupVersion.algorithm,
|
algorithm = keysBackupVersion.algorithm,
|
||||||
authData = newMegolmBackupAuthDataWithNewSignature.toJsonDict(),
|
authData = newMegolmBackupAuthDataWithNewSignature.toJsonDict(),
|
||||||
version = keysBackupVersion.version)
|
version = keysBackupVersion.version
|
||||||
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
// And send it to the homeserver
|
// And send it to the homeserver
|
||||||
@ -719,14 +720,18 @@ internal class DefaultKeysBackupService @Inject constructor(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Timber.v("restoreKeysWithRecoveryKey: Decrypted ${sessionsData.size} keys out" +
|
Timber.v(
|
||||||
" of $sessionsFromHsCount from the backup store on the homeserver")
|
"restoreKeysWithRecoveryKey: Decrypted ${sessionsData.size} keys out" +
|
||||||
|
" of $sessionsFromHsCount from the backup store on the homeserver"
|
||||||
|
)
|
||||||
|
|
||||||
// Do not trigger a backup for them if they come from the backup version we are using
|
// Do not trigger a backup for them if they come from the backup version we are using
|
||||||
val backUp = keysVersionResult.version != keysBackupVersion?.version
|
val backUp = keysVersionResult.version != keysBackupVersion?.version
|
||||||
if (backUp) {
|
if (backUp) {
|
||||||
Timber.v("restoreKeysWithRecoveryKey: Those keys will be backed up" +
|
Timber.v(
|
||||||
" to backup version: ${keysBackupVersion?.version}")
|
"restoreKeysWithRecoveryKey: Those keys will be backed up" +
|
||||||
|
" to backup version: ${keysBackupVersion?.version}"
|
||||||
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Import them into the crypto store
|
// Import them into the crypto store
|
||||||
@ -801,11 +806,15 @@ internal class DefaultKeysBackupService @Inject constructor(
|
|||||||
// Get key for the room and for the session
|
// Get key for the room and for the session
|
||||||
val data = getRoomSessionDataTask.execute(GetRoomSessionDataTask.Params(roomId, sessionId, version))
|
val data = getRoomSessionDataTask.execute(GetRoomSessionDataTask.Params(roomId, sessionId, version))
|
||||||
// Convert to KeysBackupData
|
// Convert to KeysBackupData
|
||||||
KeysBackupData(mutableMapOf(
|
KeysBackupData(
|
||||||
roomId to RoomKeysBackupData(mutableMapOf(
|
mutableMapOf(
|
||||||
sessionId to data
|
roomId to RoomKeysBackupData(
|
||||||
))
|
mutableMapOf(
|
||||||
))
|
sessionId to data
|
||||||
|
)
|
||||||
|
)
|
||||||
|
)
|
||||||
|
)
|
||||||
} else if (roomId != null) {
|
} else if (roomId != null) {
|
||||||
// Get all keys for the room
|
// Get all keys for the room
|
||||||
val data = getRoomSessionsDataTask.execute(GetRoomSessionsDataTask.Params(roomId, version))
|
val data = getRoomSessionsDataTask.execute(GetRoomSessionsDataTask.Params(roomId, version))
|
||||||
@ -1326,7 +1335,8 @@ internal class DefaultKeysBackupService @Inject constructor(
|
|||||||
"sender_key" to sessionData.senderKey,
|
"sender_key" to sessionData.senderKey,
|
||||||
"sender_claimed_keys" to sessionData.senderClaimedKeys,
|
"sender_claimed_keys" to sessionData.senderClaimedKeys,
|
||||||
"forwarding_curve25519_key_chain" to (sessionData.forwardingCurve25519KeyChain.orEmpty()),
|
"forwarding_curve25519_key_chain" to (sessionData.forwardingCurve25519KeyChain.orEmpty()),
|
||||||
"session_key" to sessionData.sessionKey)
|
"session_key" to sessionData.sessionKey
|
||||||
|
)
|
||||||
|
|
||||||
val json = MoshiProvider.providesMoshi()
|
val json = MoshiProvider.providesMoshi()
|
||||||
.adapter(Map::class.java)
|
.adapter(Map::class.java)
|
||||||
@ -1354,7 +1364,8 @@ internal class DefaultKeysBackupService @Inject constructor(
|
|||||||
sessionData = mapOf(
|
sessionData = mapOf(
|
||||||
"ciphertext" to encryptedSessionBackupData.mCipherText,
|
"ciphertext" to encryptedSessionBackupData.mCipherText,
|
||||||
"mac" to encryptedSessionBackupData.mMac,
|
"mac" to encryptedSessionBackupData.mMac,
|
||||||
"ephemeral" to encryptedSessionBackupData.mEphemeralKey)
|
"ephemeral" to encryptedSessionBackupData.mEphemeralKey
|
||||||
|
)
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -40,7 +40,8 @@ internal class DefaultDeleteRoomSessionDataTask @Inject constructor(
|
|||||||
roomKeysApi.deleteRoomSessionData(
|
roomKeysApi.deleteRoomSessionData(
|
||||||
params.roomId,
|
params.roomId,
|
||||||
params.sessionId,
|
params.sessionId,
|
||||||
params.version)
|
params.version
|
||||||
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -38,7 +38,8 @@ internal class DefaultDeleteRoomSessionsDataTask @Inject constructor(
|
|||||||
return executeRequest(globalErrorReceiver) {
|
return executeRequest(globalErrorReceiver) {
|
||||||
roomKeysApi.deleteRoomSessionsData(
|
roomKeysApi.deleteRoomSessionsData(
|
||||||
params.roomId,
|
params.roomId,
|
||||||
params.version)
|
params.version
|
||||||
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -41,7 +41,8 @@ internal class DefaultGetRoomSessionDataTask @Inject constructor(
|
|||||||
roomKeysApi.getRoomSessionData(
|
roomKeysApi.getRoomSessionData(
|
||||||
params.roomId,
|
params.roomId,
|
||||||
params.sessionId,
|
params.sessionId,
|
||||||
params.version)
|
params.version
|
||||||
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -39,7 +39,8 @@ internal class DefaultGetRoomSessionsDataTask @Inject constructor(
|
|||||||
return executeRequest(globalErrorReceiver) {
|
return executeRequest(globalErrorReceiver) {
|
||||||
roomKeysApi.getRoomSessionsData(
|
roomKeysApi.getRoomSessionsData(
|
||||||
params.roomId,
|
params.roomId,
|
||||||
params.version)
|
params.version
|
||||||
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -44,7 +44,8 @@ internal class DefaultStoreRoomSessionDataTask @Inject constructor(
|
|||||||
params.roomId,
|
params.roomId,
|
||||||
params.sessionId,
|
params.sessionId,
|
||||||
params.version,
|
params.version,
|
||||||
params.keyBackupData)
|
params.keyBackupData
|
||||||
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -42,7 +42,8 @@ internal class DefaultStoreRoomSessionsDataTask @Inject constructor(
|
|||||||
roomKeysApi.storeRoomSessionsData(
|
roomKeysApi.storeRoomSessionsData(
|
||||||
params.roomId,
|
params.roomId,
|
||||||
params.version,
|
params.version,
|
||||||
params.roomKeysBackupData)
|
params.roomKeysBackupData
|
||||||
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -40,7 +40,8 @@ internal class DefaultStoreSessionsDataTask @Inject constructor(
|
|||||||
return executeRequest(globalErrorReceiver) {
|
return executeRequest(globalErrorReceiver) {
|
||||||
roomKeysApi.storeSessionsData(
|
roomKeysApi.storeSessionsData(
|
||||||
params.version,
|
params.version,
|
||||||
params.keysBackupData)
|
params.keysBackupData
|
||||||
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -213,7 +213,8 @@ internal class DefaultSharedSecretStorageService @Inject constructor(
|
|||||||
secretKey.privateKey,
|
secretKey.privateKey,
|
||||||
ByteArray(32) { 0.toByte() },
|
ByteArray(32) { 0.toByte() },
|
||||||
secretName.toByteArray(),
|
secretName.toByteArray(),
|
||||||
64)
|
64
|
||||||
|
)
|
||||||
|
|
||||||
// The first 32 bytes are used as the AES key, and the next 32 bytes are used as the MAC key
|
// The first 32 bytes are used as the AES key, and the next 32 bytes are used as the MAC key
|
||||||
val aesKey = pseudoRandomKey.copyOfRange(0, 32)
|
val aesKey = pseudoRandomKey.copyOfRange(0, 32)
|
||||||
@ -255,7 +256,8 @@ internal class DefaultSharedSecretStorageService @Inject constructor(
|
|||||||
secretKey.privateKey,
|
secretKey.privateKey,
|
||||||
ByteArray(32) { 0.toByte() },
|
ByteArray(32) { 0.toByte() },
|
||||||
secretName.toByteArray(),
|
secretName.toByteArray(),
|
||||||
64)
|
64
|
||||||
|
)
|
||||||
|
|
||||||
// The first 32 bytes are used as the AES key, and the next 32 bytes are used as the MAC key
|
// The first 32 bytes are used as the AES key, and the next 32 bytes are used as the MAC key
|
||||||
val aesKey = pseudoRandomKey.copyOfRange(0, 32)
|
val aesKey = pseudoRandomKey.copyOfRange(0, 32)
|
||||||
|
@ -38,7 +38,8 @@ import org.matrix.android.sdk.internal.crypto.store.db.model.WithHeldSessionEnti
|
|||||||
/**
|
/**
|
||||||
* Realm module for Crypto store classes
|
* Realm module for Crypto store classes
|
||||||
*/
|
*/
|
||||||
@RealmModule(library = true,
|
@RealmModule(
|
||||||
|
library = true,
|
||||||
classes = [
|
classes = [
|
||||||
CryptoMetadataEntity::class,
|
CryptoMetadataEntity::class,
|
||||||
CryptoRoomEntity::class,
|
CryptoRoomEntity::class,
|
||||||
@ -57,5 +58,6 @@ import org.matrix.android.sdk.internal.crypto.store.db.model.WithHeldSessionEnti
|
|||||||
WithHeldSessionEntity::class,
|
WithHeldSessionEntity::class,
|
||||||
SharedSessionEntity::class,
|
SharedSessionEntity::class,
|
||||||
OutboundGroupSessionInfoEntity::class
|
OutboundGroupSessionInfoEntity::class
|
||||||
])
|
]
|
||||||
|
)
|
||||||
internal class RealmCryptoStoreModule
|
internal class RealmCryptoStoreModule
|
||||||
|
@ -27,11 +27,13 @@ import javax.inject.Inject
|
|||||||
|
|
||||||
internal class CrossSigningKeysMapper @Inject constructor(moshi: Moshi) {
|
internal class CrossSigningKeysMapper @Inject constructor(moshi: Moshi) {
|
||||||
|
|
||||||
private val signaturesAdapter = moshi.adapter<Map<String, Map<String, String>>>(Types.newParameterizedType(
|
private val signaturesAdapter = moshi.adapter<Map<String, Map<String, String>>>(
|
||||||
Map::class.java,
|
Types.newParameterizedType(
|
||||||
String::class.java,
|
Map::class.java,
|
||||||
Any::class.java
|
String::class.java,
|
||||||
))
|
Any::class.java
|
||||||
|
)
|
||||||
|
)
|
||||||
|
|
||||||
fun update(keyInfo: KeyInfoEntity, cryptoCrossSigningKey: CryptoCrossSigningKey) {
|
fun update(keyInfo: KeyInfoEntity, cryptoCrossSigningKey: CryptoCrossSigningKey) {
|
||||||
// update signatures?
|
// update signatures?
|
||||||
|
@ -72,16 +72,20 @@ internal class MigrateCryptoTo004(realm: DynamicRealm) : RealmMigrator(realm, 4)
|
|||||||
?.addField(CryptoMetadataEntityFields.X_SIGN_SELF_SIGNED_PRIVATE_KEY, String::class.java)
|
?.addField(CryptoMetadataEntityFields.X_SIGN_SELF_SIGNED_PRIVATE_KEY, String::class.java)
|
||||||
|
|
||||||
val moshi = Moshi.Builder().add(SerializeNulls.JSON_ADAPTER_FACTORY).build()
|
val moshi = Moshi.Builder().add(SerializeNulls.JSON_ADAPTER_FACTORY).build()
|
||||||
val listMigrationAdapter = moshi.adapter<List<String>>(Types.newParameterizedType(
|
val listMigrationAdapter = moshi.adapter<List<String>>(
|
||||||
List::class.java,
|
Types.newParameterizedType(
|
||||||
String::class.java,
|
List::class.java,
|
||||||
Any::class.java
|
String::class.java,
|
||||||
))
|
Any::class.java
|
||||||
val mapMigrationAdapter = moshi.adapter<JsonDict>(Types.newParameterizedType(
|
)
|
||||||
Map::class.java,
|
)
|
||||||
String::class.java,
|
val mapMigrationAdapter = moshi.adapter<JsonDict>(
|
||||||
Any::class.java
|
Types.newParameterizedType(
|
||||||
))
|
Map::class.java,
|
||||||
|
String::class.java,
|
||||||
|
Any::class.java
|
||||||
|
)
|
||||||
|
)
|
||||||
|
|
||||||
realm.schema.get("DeviceInfoEntity")
|
realm.schema.get("DeviceInfoEntity")
|
||||||
?.addField(DeviceInfoEntityFields.USER_ID, String::class.java)
|
?.addField(DeviceInfoEntityFields.USER_ID, String::class.java)
|
||||||
|
@ -27,21 +27,27 @@ import timber.log.Timber
|
|||||||
internal object CryptoMapper {
|
internal object CryptoMapper {
|
||||||
|
|
||||||
private val moshi = Moshi.Builder().add(SerializeNulls.JSON_ADAPTER_FACTORY).build()
|
private val moshi = Moshi.Builder().add(SerializeNulls.JSON_ADAPTER_FACTORY).build()
|
||||||
private val listMigrationAdapter = moshi.adapter<List<String>>(Types.newParameterizedType(
|
private val listMigrationAdapter = moshi.adapter<List<String>>(
|
||||||
List::class.java,
|
Types.newParameterizedType(
|
||||||
String::class.java,
|
List::class.java,
|
||||||
Any::class.java
|
String::class.java,
|
||||||
))
|
Any::class.java
|
||||||
private val mapMigrationAdapter = moshi.adapter<JsonDict>(Types.newParameterizedType(
|
)
|
||||||
Map::class.java,
|
)
|
||||||
String::class.java,
|
private val mapMigrationAdapter = moshi.adapter<JsonDict>(
|
||||||
Any::class.java
|
Types.newParameterizedType(
|
||||||
))
|
Map::class.java,
|
||||||
private val mapOfStringMigrationAdapter = moshi.adapter<Map<String, Map<String, String>>>(Types.newParameterizedType(
|
String::class.java,
|
||||||
Map::class.java,
|
Any::class.java
|
||||||
String::class.java,
|
)
|
||||||
Any::class.java
|
)
|
||||||
))
|
private val mapOfStringMigrationAdapter = moshi.adapter<Map<String, Map<String, String>>>(
|
||||||
|
Types.newParameterizedType(
|
||||||
|
Map::class.java,
|
||||||
|
String::class.java,
|
||||||
|
Any::class.java
|
||||||
|
)
|
||||||
|
)
|
||||||
|
|
||||||
internal fun mapToEntity(deviceInfo: CryptoDeviceInfo): DeviceInfoEntity {
|
internal fun mapToEntity(deviceInfo: CryptoDeviceInfo): DeviceInfoEntity {
|
||||||
return DeviceInfoEntity(primaryKey = DeviceInfoEntity.createPrimaryKey(deviceInfo.userId, deviceInfo.deviceId))
|
return DeviceInfoEntity(primaryKey = DeviceInfoEntity.createPrimaryKey(deviceInfo.userId, deviceInfo.deviceId))
|
||||||
@ -91,11 +97,13 @@ internal object CryptoMapper {
|
|||||||
},
|
},
|
||||||
keys = deviceInfoEntity.keysMapJson?.let {
|
keys = deviceInfoEntity.keysMapJson?.let {
|
||||||
try {
|
try {
|
||||||
moshi.adapter<Map<String, String>>(Types.newParameterizedType(
|
moshi.adapter<Map<String, String>>(
|
||||||
Map::class.java,
|
Types.newParameterizedType(
|
||||||
String::class.java,
|
Map::class.java,
|
||||||
Any::class.java
|
String::class.java,
|
||||||
)).fromJson(it)
|
Any::class.java
|
||||||
|
)
|
||||||
|
).fromJson(it)
|
||||||
} catch (failure: Throwable) {
|
} catch (failure: Throwable) {
|
||||||
Timber.e(failure)
|
Timber.e(failure)
|
||||||
null
|
null
|
||||||
|
@ -73,11 +73,13 @@ internal class DefaultSendEventTask @Inject constructor(
|
|||||||
@Throws
|
@Throws
|
||||||
private suspend fun handleEncryption(params: SendEventTask.Params): Event {
|
private suspend fun handleEncryption(params: SendEventTask.Params): Event {
|
||||||
if (params.encrypt && !params.event.isEncrypted()) {
|
if (params.encrypt && !params.event.isEncrypted()) {
|
||||||
return encryptEventTask.execute(EncryptEventTask.Params(
|
return encryptEventTask.execute(
|
||||||
params.event.roomId ?: "",
|
EncryptEventTask.Params(
|
||||||
params.event,
|
params.event.roomId ?: "",
|
||||||
listOf("m.relates_to")
|
params.event,
|
||||||
))
|
listOf("m.relates_to")
|
||||||
|
)
|
||||||
|
)
|
||||||
}
|
}
|
||||||
return params.event
|
return params.event
|
||||||
}
|
}
|
||||||
|
@ -64,11 +64,13 @@ internal class DefaultSendVerificationMessageTask @Inject constructor(
|
|||||||
private suspend fun handleEncryption(params: SendVerificationMessageTask.Params): Event {
|
private suspend fun handleEncryption(params: SendVerificationMessageTask.Params): Event {
|
||||||
if (cryptoSessionInfoProvider.isRoomEncrypted(params.event.roomId ?: "")) {
|
if (cryptoSessionInfoProvider.isRoomEncrypted(params.event.roomId ?: "")) {
|
||||||
try {
|
try {
|
||||||
return encryptEventTask.execute(EncryptEventTask.Params(
|
return encryptEventTask.execute(
|
||||||
params.event.roomId ?: "",
|
EncryptEventTask.Params(
|
||||||
params.event,
|
params.event.roomId ?: "",
|
||||||
listOf("m.relates_to")
|
params.event,
|
||||||
))
|
listOf("m.relates_to")
|
||||||
|
)
|
||||||
|
)
|
||||||
} catch (throwable: Throwable) {
|
} catch (throwable: Throwable) {
|
||||||
// We said it's ok to send verification request in clear
|
// We said it's ok to send verification request in clear
|
||||||
}
|
}
|
||||||
|
@ -53,7 +53,8 @@ internal class DefaultIncomingSASDefaultVerificationTransaction(
|
|||||||
transactionId,
|
transactionId,
|
||||||
otherUserID,
|
otherUserID,
|
||||||
null,
|
null,
|
||||||
isIncoming = true),
|
isIncoming = true
|
||||||
|
),
|
||||||
IncomingSasVerificationTransaction {
|
IncomingSasVerificationTransaction {
|
||||||
|
|
||||||
override val uxState: IncomingSasVerificationTransaction.UxState
|
override val uxState: IncomingSasVerificationTransaction.UxState
|
||||||
|
@ -50,7 +50,8 @@ internal class DefaultOutgoingSASDefaultVerificationTransaction(
|
|||||||
transactionId,
|
transactionId,
|
||||||
otherUserId,
|
otherUserId,
|
||||||
otherDeviceId,
|
otherDeviceId,
|
||||||
isIncoming = false),
|
isIncoming = false
|
||||||
|
),
|
||||||
OutgoingSasVerificationTransaction {
|
OutgoingSasVerificationTransaction {
|
||||||
|
|
||||||
override val uxState: OutgoingSasVerificationTransaction.UxState
|
override val uxState: OutgoingSasVerificationTransaction.UxState
|
||||||
|
@ -105,8 +105,10 @@ internal abstract class DefaultVerificationTransaction(
|
|||||||
|
|
||||||
private fun setDeviceVerified(userId: String, deviceId: String) {
|
private fun setDeviceVerified(userId: String, deviceId: String) {
|
||||||
// TODO should not override cross sign status
|
// TODO should not override cross sign status
|
||||||
setDeviceVerificationAction.handle(DeviceTrustLevel(crossSigningVerified = false, locallyVerified = true),
|
setDeviceVerificationAction.handle(
|
||||||
|
DeviceTrustLevel(crossSigningVerified = false, locallyVerified = true),
|
||||||
userId,
|
userId,
|
||||||
deviceId)
|
deviceId
|
||||||
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -58,7 +58,8 @@ internal abstract class SASDefaultVerificationTransaction(
|
|||||||
transactionId,
|
transactionId,
|
||||||
otherUserId,
|
otherUserId,
|
||||||
otherDeviceId,
|
otherDeviceId,
|
||||||
isIncoming),
|
isIncoming
|
||||||
|
),
|
||||||
SasVerificationTransaction {
|
SasVerificationTransaction {
|
||||||
|
|
||||||
companion object {
|
companion object {
|
||||||
@ -297,9 +298,11 @@ internal abstract class SASDefaultVerificationTransaction(
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
trust(otherMasterKeyIsVerified,
|
trust(
|
||||||
|
otherMasterKeyIsVerified,
|
||||||
verifiedDevices,
|
verifiedDevices,
|
||||||
eventuallyMarkMyMasterKeyAsTrusted = otherMasterKey?.trustLevel?.isVerified() == false)
|
eventuallyMarkMyMasterKeyAsTrusted = otherMasterKey?.trustLevel?.isVerified() == false
|
||||||
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun cancel() {
|
override fun cancel() {
|
||||||
|
@ -54,7 +54,8 @@ internal class DefaultQrCodeVerificationTransaction(
|
|||||||
transactionId,
|
transactionId,
|
||||||
otherUserId,
|
otherUserId,
|
||||||
otherDeviceId,
|
otherDeviceId,
|
||||||
isIncoming),
|
isIncoming
|
||||||
|
),
|
||||||
QrCodeVerificationTransaction {
|
QrCodeVerificationTransaction {
|
||||||
|
|
||||||
override val qrCodeText: String?
|
override val qrCodeText: String?
|
||||||
|
@ -56,7 +56,8 @@ internal sealed class QrCodeData(
|
|||||||
transactionId,
|
transactionId,
|
||||||
userMasterCrossSigningPublicKey,
|
userMasterCrossSigningPublicKey,
|
||||||
otherUserMasterCrossSigningPublicKey,
|
otherUserMasterCrossSigningPublicKey,
|
||||||
sharedSecret)
|
sharedSecret
|
||||||
|
)
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* self-verifying in which the current device does trust the master key
|
* self-verifying in which the current device does trust the master key
|
||||||
@ -77,7 +78,8 @@ internal sealed class QrCodeData(
|
|||||||
transactionId,
|
transactionId,
|
||||||
userMasterCrossSigningPublicKey,
|
userMasterCrossSigningPublicKey,
|
||||||
otherDeviceKey,
|
otherDeviceKey,
|
||||||
sharedSecret)
|
sharedSecret
|
||||||
|
)
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* self-verifying in which the current device does not yet trust the master key
|
* self-verifying in which the current device does not yet trust the master key
|
||||||
@ -98,5 +100,6 @@ internal sealed class QrCodeData(
|
|||||||
transactionId,
|
transactionId,
|
||||||
deviceKey,
|
deviceKey,
|
||||||
userMasterCrossSigningPublicKey,
|
userMasterCrossSigningPublicKey,
|
||||||
sharedSecret)
|
sharedSecret
|
||||||
|
)
|
||||||
}
|
}
|
||||||
|
@ -207,8 +207,10 @@ internal fun List<TimelineEvent>.mapEventsWithEdition(realm: Realm, roomId: Stri
|
|||||||
?.eventId
|
?.eventId
|
||||||
?.let { editedEventId ->
|
?.let { editedEventId ->
|
||||||
TimelineEventEntity.where(realm, roomId, eventId = editedEventId).findFirst()?.let { editedEvent ->
|
TimelineEventEntity.where(realm, roomId, eventId = editedEventId).findFirst()?.let { editedEvent ->
|
||||||
it.root.threadDetails = it.root.threadDetails?.copy(lastRootThreadEdition = editedEvent.root?.asDomain()?.getDecryptedTextSummary()
|
it.root.threadDetails = it.root.threadDetails?.copy(
|
||||||
?: "(edited)")
|
lastRootThreadEdition = editedEvent.root?.asDomain()?.getDecryptedTextSummary()
|
||||||
|
?: "(edited)"
|
||||||
|
)
|
||||||
it
|
it
|
||||||
} ?: it
|
} ?: it
|
||||||
} ?: it
|
} ?: it
|
||||||
@ -341,7 +343,8 @@ internal fun updateNotificationsNew(roomId: String, realm: Realm, currentUserId:
|
|||||||
realm = realm,
|
realm = realm,
|
||||||
roomId = roomId,
|
roomId = roomId,
|
||||||
rootThreadEventId = eventId,
|
rootThreadEventId = eventId,
|
||||||
senderId = currentUserId)
|
senderId = currentUserId
|
||||||
|
)
|
||||||
val rootThreadEventEntity = EventEntity.where(realm, eventId).findFirst()
|
val rootThreadEventEntity = EventEntity.where(realm, eventId).findFirst()
|
||||||
|
|
||||||
if (isUserParticipating) {
|
if (isUserParticipating) {
|
||||||
|
@ -24,7 +24,8 @@ import org.matrix.android.sdk.internal.database.model.threads.ThreadSummaryEntit
|
|||||||
/**
|
/**
|
||||||
* Realm module for Session
|
* Realm module for Session
|
||||||
*/
|
*/
|
||||||
@RealmModule(library = true,
|
@RealmModule(
|
||||||
|
library = true,
|
||||||
classes = [
|
classes = [
|
||||||
ChunkEntity::class,
|
ChunkEntity::class,
|
||||||
EventEntity::class,
|
EventEntity::class,
|
||||||
@ -71,5 +72,6 @@ import org.matrix.android.sdk.internal.database.model.threads.ThreadSummaryEntit
|
|||||||
SpaceParentSummaryEntity::class,
|
SpaceParentSummaryEntity::class,
|
||||||
UserPresenceEntity::class,
|
UserPresenceEntity::class,
|
||||||
ThreadSummaryEntity::class
|
ThreadSummaryEntity::class
|
||||||
])
|
]
|
||||||
|
)
|
||||||
internal class SessionRealmModule
|
internal class SessionRealmModule
|
||||||
|
@ -43,15 +43,17 @@ import org.matrix.android.sdk.internal.worker.MatrixWorkerFactory
|
|||||||
import org.matrix.olm.OlmManager
|
import org.matrix.olm.OlmManager
|
||||||
import java.io.File
|
import java.io.File
|
||||||
|
|
||||||
@Component(modules = [
|
@Component(
|
||||||
MatrixModule::class,
|
modules = [
|
||||||
NetworkModule::class,
|
MatrixModule::class,
|
||||||
AuthModule::class,
|
NetworkModule::class,
|
||||||
RawModule::class,
|
AuthModule::class,
|
||||||
SettingsModule::class,
|
RawModule::class,
|
||||||
SystemModule::class,
|
SettingsModule::class,
|
||||||
NoOpTestModule::class
|
SystemModule::class,
|
||||||
])
|
NoOpTestModule::class
|
||||||
|
]
|
||||||
|
)
|
||||||
@MatrixScope
|
@MatrixScope
|
||||||
internal interface MatrixComponent {
|
internal interface MatrixComponent {
|
||||||
|
|
||||||
|
@ -36,7 +36,8 @@ internal object MatrixModule {
|
|||||||
@Provides
|
@Provides
|
||||||
@MatrixScope
|
@MatrixScope
|
||||||
fun providesMatrixCoroutineDispatchers(): MatrixCoroutineDispatchers {
|
fun providesMatrixCoroutineDispatchers(): MatrixCoroutineDispatchers {
|
||||||
return MatrixCoroutineDispatchers(io = Dispatchers.IO,
|
return MatrixCoroutineDispatchers(
|
||||||
|
io = Dispatchers.IO,
|
||||||
computation = Dispatchers.Default,
|
computation = Dispatchers.Default,
|
||||||
main = Dispatchers.Main,
|
main = Dispatchers.Main,
|
||||||
crypto = createBackgroundHandler("Crypto_Thread").asCoroutineDispatcher(),
|
crypto = createBackgroundHandler("Crypto_Thread").asCoroutineDispatcher(),
|
||||||
|
@ -46,17 +46,18 @@ internal object MoshiProvider {
|
|||||||
.add(TlsVersionMoshiAdapter())
|
.add(TlsVersionMoshiAdapter())
|
||||||
// Use addLast here so we can inject a SplitLazyRoomSyncJsonAdapter later to override the default parsing.
|
// Use addLast here so we can inject a SplitLazyRoomSyncJsonAdapter later to override the default parsing.
|
||||||
.addLast(DefaultLazyRoomSyncEphemeralJsonAdapter())
|
.addLast(DefaultLazyRoomSyncEphemeralJsonAdapter())
|
||||||
.add(RuntimeJsonAdapterFactory.of(MessageContent::class.java, "msgtype", MessageDefaultContent::class.java)
|
.add(
|
||||||
.registerSubtype(MessageTextContent::class.java, MessageType.MSGTYPE_TEXT)
|
RuntimeJsonAdapterFactory.of(MessageContent::class.java, "msgtype", MessageDefaultContent::class.java)
|
||||||
.registerSubtype(MessageNoticeContent::class.java, MessageType.MSGTYPE_NOTICE)
|
.registerSubtype(MessageTextContent::class.java, MessageType.MSGTYPE_TEXT)
|
||||||
.registerSubtype(MessageEmoteContent::class.java, MessageType.MSGTYPE_EMOTE)
|
.registerSubtype(MessageNoticeContent::class.java, MessageType.MSGTYPE_NOTICE)
|
||||||
.registerSubtype(MessageAudioContent::class.java, MessageType.MSGTYPE_AUDIO)
|
.registerSubtype(MessageEmoteContent::class.java, MessageType.MSGTYPE_EMOTE)
|
||||||
.registerSubtype(MessageImageContent::class.java, MessageType.MSGTYPE_IMAGE)
|
.registerSubtype(MessageAudioContent::class.java, MessageType.MSGTYPE_AUDIO)
|
||||||
.registerSubtype(MessageVideoContent::class.java, MessageType.MSGTYPE_VIDEO)
|
.registerSubtype(MessageImageContent::class.java, MessageType.MSGTYPE_IMAGE)
|
||||||
.registerSubtype(MessageLocationContent::class.java, MessageType.MSGTYPE_LOCATION)
|
.registerSubtype(MessageVideoContent::class.java, MessageType.MSGTYPE_VIDEO)
|
||||||
.registerSubtype(MessageFileContent::class.java, MessageType.MSGTYPE_FILE)
|
.registerSubtype(MessageLocationContent::class.java, MessageType.MSGTYPE_LOCATION)
|
||||||
.registerSubtype(MessageVerificationRequestContent::class.java, MessageType.MSGTYPE_VERIFICATION_REQUEST)
|
.registerSubtype(MessageFileContent::class.java, MessageType.MSGTYPE_FILE)
|
||||||
.registerSubtype(MessagePollResponseContent::class.java, MessageType.MSGTYPE_POLL_RESPONSE)
|
.registerSubtype(MessageVerificationRequestContent::class.java, MessageType.MSGTYPE_VERIFICATION_REQUEST)
|
||||||
|
.registerSubtype(MessagePollResponseContent::class.java, MessageType.MSGTYPE_POLL_RESPONSE)
|
||||||
)
|
)
|
||||||
.add(SerializeNulls.JSON_ADAPTER_FACTORY)
|
.add(SerializeNulls.JSON_ADAPTER_FACTORY)
|
||||||
.build()
|
.build()
|
||||||
|
@ -84,9 +84,11 @@ internal class WorkManagerProvider @Inject constructor(
|
|||||||
if (workInfo?.state?.isFinished == true) {
|
if (workInfo?.state?.isFinished == true) {
|
||||||
checkWorkerLiveState.removeObserver(this)
|
checkWorkerLiveState.removeObserver(this)
|
||||||
if (workInfo.state == WorkInfo.State.FAILED) {
|
if (workInfo.state == WorkInfo.State.FAILED) {
|
||||||
throw RuntimeException("MatrixWorkerFactory is not being set on your worker configuration.\n" +
|
throw RuntimeException(
|
||||||
"Makes sure to add it to a DelegatingWorkerFactory if you have your own factory or use it directly.\n" +
|
"MatrixWorkerFactory is not being set on your worker configuration.\n" +
|
||||||
"You can grab the instance through the Matrix class.")
|
"Makes sure to add it to a DelegatingWorkerFactory if you have your own factory or use it directly.\n" +
|
||||||
|
"You can grab the instance through the Matrix class."
|
||||||
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -76,10 +76,12 @@ class WellKnown {
|
|||||||
if (apiUrl != null &&
|
if (apiUrl != null &&
|
||||||
apiUrl.startsWith("https://") &&
|
apiUrl.startsWith("https://") &&
|
||||||
uiUrl!!.startsWith("https://")) {
|
uiUrl!!.startsWith("https://")) {
|
||||||
managers.add(WellKnownManagerConfig(
|
managers.add(
|
||||||
apiUrl = apiUrl,
|
WellKnownManagerConfig(
|
||||||
uiUrl = uiUrl
|
apiUrl = apiUrl,
|
||||||
))
|
uiUrl = uiUrl
|
||||||
|
)
|
||||||
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -63,8 +63,10 @@ internal class RuntimeJsonAdapterFactory<T>(
|
|||||||
}
|
}
|
||||||
val fallbackAdapter = moshi.adapter<Any>(fallbackType)
|
val fallbackAdapter = moshi.adapter<Any>(fallbackType)
|
||||||
val objectJsonAdapter = moshi.adapter(Any::class.java)
|
val objectJsonAdapter = moshi.adapter(Any::class.java)
|
||||||
return RuntimeJsonAdapter(labelKey, labelToAdapter, typeToLabel,
|
return RuntimeJsonAdapter(
|
||||||
objectJsonAdapter, fallbackAdapter).nullSafe()
|
labelKey, labelToAdapter, typeToLabel,
|
||||||
|
objectJsonAdapter, fallbackAdapter
|
||||||
|
).nullSafe()
|
||||||
}
|
}
|
||||||
|
|
||||||
@Suppress("UNCHECKED_CAST")
|
@Suppress("UNCHECKED_CAST")
|
||||||
@ -77,8 +79,10 @@ internal class RuntimeJsonAdapterFactory<T>(
|
|||||||
override fun fromJson(reader: JsonReader): Any? {
|
override fun fromJson(reader: JsonReader): Any? {
|
||||||
val peekedToken = reader.peek()
|
val peekedToken = reader.peek()
|
||||||
if (peekedToken != JsonReader.Token.BEGIN_OBJECT) {
|
if (peekedToken != JsonReader.Token.BEGIN_OBJECT) {
|
||||||
throw JsonDataException("Expected BEGIN_OBJECT but was " + peekedToken +
|
throw JsonDataException(
|
||||||
" at path " + reader.path)
|
"Expected BEGIN_OBJECT but was " + peekedToken +
|
||||||
|
" at path " + reader.path
|
||||||
|
)
|
||||||
}
|
}
|
||||||
val jsonValue = reader.readJsonValue()
|
val jsonValue = reader.readJsonValue()
|
||||||
val jsonObject = jsonValue as Map<String, Any>?
|
val jsonObject = jsonValue as Map<String, Any>?
|
||||||
@ -91,13 +95,15 @@ internal class RuntimeJsonAdapterFactory<T>(
|
|||||||
override fun toJson(writer: JsonWriter, value: Any?) {
|
override fun toJson(writer: JsonWriter, value: Any?) {
|
||||||
val type: Class<*> = value!!.javaClass
|
val type: Class<*> = value!!.javaClass
|
||||||
val label = typeToLabel[type]
|
val label = typeToLabel[type]
|
||||||
?: throw IllegalArgumentException("Expected one of " +
|
?: throw IllegalArgumentException(
|
||||||
typeToLabel.keys +
|
"Expected one of " +
|
||||||
" but found " +
|
typeToLabel.keys +
|
||||||
value +
|
" but found " +
|
||||||
", a " +
|
value +
|
||||||
value.javaClass +
|
", a " +
|
||||||
". Register this subtype.")
|
value.javaClass +
|
||||||
|
". Register this subtype."
|
||||||
|
)
|
||||||
val adapter = labelToAdapter[label]!!
|
val adapter = labelToAdapter[label]!!
|
||||||
val jsonValue = adapter.toJsonValue(value) as Map<String, Any>?
|
val jsonValue = adapter.toJsonValue(value) as Map<String, Any>?
|
||||||
val valueWithLabel: MutableMap<String, Any> = LinkedHashMap(1 + jsonValue!!.size)
|
val valueWithLabel: MutableMap<String, Any> = LinkedHashMap(1 + jsonValue!!.size)
|
||||||
|
@ -35,8 +35,10 @@ internal fun RealmQuery<RoomSummaryEntity>.process(sortOrder: RoomSortOrder): Re
|
|||||||
arrayOf(
|
arrayOf(
|
||||||
RoomSummaryEntityFields.IS_FAVOURITE,
|
RoomSummaryEntityFields.IS_FAVOURITE,
|
||||||
RoomSummaryEntityFields.IS_LOW_PRIORITY,
|
RoomSummaryEntityFields.IS_LOW_PRIORITY,
|
||||||
RoomSummaryEntityFields.LAST_ACTIVITY_TIME),
|
RoomSummaryEntityFields.LAST_ACTIVITY_TIME
|
||||||
arrayOf(Sort.DESCENDING, Sort.ASCENDING, Sort.DESCENDING))
|
),
|
||||||
|
arrayOf(Sort.DESCENDING, Sort.ASCENDING, Sort.DESCENDING)
|
||||||
|
)
|
||||||
}
|
}
|
||||||
RoomSortOrder.NONE -> {
|
RoomSortOrder.NONE -> {
|
||||||
}
|
}
|
||||||
|
@ -23,9 +23,11 @@ import org.matrix.android.sdk.internal.database.model.RawCacheEntity
|
|||||||
/**
|
/**
|
||||||
* Realm module for global classes
|
* Realm module for global classes
|
||||||
*/
|
*/
|
||||||
@RealmModule(library = true,
|
@RealmModule(
|
||||||
|
library = true,
|
||||||
classes = [
|
classes = [
|
||||||
RawCacheEntity::class,
|
RawCacheEntity::class,
|
||||||
KnownServerUrlEntity::class
|
KnownServerUrlEntity::class
|
||||||
])
|
]
|
||||||
|
)
|
||||||
internal class GlobalRealmModule
|
internal class GlobalRealmModule
|
||||||
|
@ -68,7 +68,8 @@ import org.matrix.android.sdk.internal.session.widgets.WidgetModule
|
|||||||
import org.matrix.android.sdk.internal.task.TaskExecutor
|
import org.matrix.android.sdk.internal.task.TaskExecutor
|
||||||
import org.matrix.android.sdk.internal.util.system.SystemModule
|
import org.matrix.android.sdk.internal.util.system.SystemModule
|
||||||
|
|
||||||
@Component(dependencies = [MatrixComponent::class],
|
@Component(
|
||||||
|
dependencies = [MatrixComponent::class],
|
||||||
modules = [
|
modules = [
|
||||||
SessionModule::class,
|
SessionModule::class,
|
||||||
RoomModule::class,
|
RoomModule::class,
|
||||||
|
@ -289,12 +289,14 @@ internal class UploadContentWorker(val context: Context, params: WorkerParameter
|
|||||||
|
|
||||||
val uploadThumbnailResult = dealWithThumbnail(params)
|
val uploadThumbnailResult = dealWithThumbnail(params)
|
||||||
|
|
||||||
handleSuccess(params,
|
handleSuccess(
|
||||||
|
params,
|
||||||
contentUploadResponse.contentUri,
|
contentUploadResponse.contentUri,
|
||||||
uploadedFileEncryptedFileInfo,
|
uploadedFileEncryptedFileInfo,
|
||||||
uploadThumbnailResult?.uploadedThumbnailUrl,
|
uploadThumbnailResult?.uploadedThumbnailUrl,
|
||||||
uploadThumbnailResult?.uploadedThumbnailEncryptedFileInfo,
|
uploadThumbnailResult?.uploadedThumbnailEncryptedFileInfo,
|
||||||
newAttachmentAttributes)
|
newAttachmentAttributes
|
||||||
|
)
|
||||||
} catch (t: Throwable) {
|
} catch (t: Throwable) {
|
||||||
Timber.e(t, "## ERROR ${t.localizedMessage}")
|
Timber.e(t, "## ERROR ${t.localizedMessage}")
|
||||||
handleFailure(params, t)
|
handleFailure(params, t)
|
||||||
|
@ -21,9 +21,11 @@ import io.realm.annotations.RealmModule
|
|||||||
/**
|
/**
|
||||||
* Realm module for content scanner classes
|
* Realm module for content scanner classes
|
||||||
*/
|
*/
|
||||||
@RealmModule(library = true,
|
@RealmModule(
|
||||||
|
library = true,
|
||||||
classes = [
|
classes = [
|
||||||
ContentScannerInfoEntity::class,
|
ContentScannerInfoEntity::class,
|
||||||
ContentScanResultEntity::class
|
ContentScanResultEntity::class
|
||||||
])
|
]
|
||||||
|
)
|
||||||
internal class ContentScannerRealmModule
|
internal class ContentScannerRealmModule
|
||||||
|
@ -94,10 +94,12 @@ internal class DefaultGetHomeServerCapabilitiesTask @Inject constructor(
|
|||||||
}.getOrNull()
|
}.getOrNull()
|
||||||
|
|
||||||
val wellknownResult = runCatching {
|
val wellknownResult = runCatching {
|
||||||
getWellknownTask.execute(GetWellknownTask.Params(
|
getWellknownTask.execute(
|
||||||
domain = userId.getDomain(),
|
GetWellknownTask.Params(
|
||||||
homeServerConnectionConfig = homeServerConnectionConfig
|
domain = userId.getDomain(),
|
||||||
))
|
homeServerConnectionConfig = homeServerConnectionConfig
|
||||||
|
)
|
||||||
|
)
|
||||||
}.getOrNull()
|
}.getOrNull()
|
||||||
|
|
||||||
insertInDb(capabilities, mediaConfig, versions, wellknownResult)
|
insertInDb(capabilities, mediaConfig, versions, wellknownResult)
|
||||||
|
@ -218,9 +218,11 @@ internal class DefaultIdentityService @Inject constructor(
|
|||||||
listeners.toList().forEach { tryOrNull { it.onIdentityServerChange() } }
|
listeners.toList().forEach { tryOrNull { it.onIdentityServerChange() } }
|
||||||
}
|
}
|
||||||
|
|
||||||
updateUserAccountDataTask.execute(UpdateUserAccountDataTask.IdentityParams(
|
updateUserAccountDataTask.execute(
|
||||||
identityContent = IdentityServerContent(baseUrl = url)
|
UpdateUserAccountDataTask.IdentityParams(
|
||||||
))
|
identityContent = IdentityServerContent(baseUrl = url)
|
||||||
|
)
|
||||||
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun getUserConsent(): Boolean {
|
override fun getUserConsent(): Boolean {
|
||||||
@ -297,11 +299,13 @@ internal class DefaultIdentityService @Inject constructor(
|
|||||||
}
|
}
|
||||||
|
|
||||||
override suspend fun sign3pidInvitation(identiyServer: String, token: String, secret: String): SignInvitationResult {
|
override suspend fun sign3pidInvitation(identiyServer: String, token: String, secret: String): SignInvitationResult {
|
||||||
return sign3pidInvitationTask.execute(Sign3pidInvitationTask.Params(
|
return sign3pidInvitationTask.execute(
|
||||||
url = identiyServer,
|
Sign3pidInvitationTask.Params(
|
||||||
token = token,
|
url = identiyServer,
|
||||||
privateKey = secret
|
token = token,
|
||||||
))
|
privateKey = secret
|
||||||
|
)
|
||||||
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun addListener(listener: IdentityServiceListener) {
|
override fun addListener(listener: IdentityServiceListener) {
|
||||||
|
@ -83,11 +83,13 @@ internal class DefaultIdentityBulkLookupTask @Inject constructor(
|
|||||||
return try {
|
return try {
|
||||||
LookUpData(hashedAddresses,
|
LookUpData(hashedAddresses,
|
||||||
executeRequest(null) {
|
executeRequest(null) {
|
||||||
identityAPI.lookup(IdentityLookUpParams(
|
identityAPI.lookup(
|
||||||
hashedAddresses,
|
IdentityLookUpParams(
|
||||||
IdentityHashDetailResponse.ALGORITHM_SHA256,
|
hashedAddresses,
|
||||||
hashDetailResponse.pepper
|
IdentityHashDetailResponse.ALGORITHM_SHA256,
|
||||||
))
|
hashDetailResponse.pepper
|
||||||
|
)
|
||||||
|
)
|
||||||
})
|
})
|
||||||
} catch (failure: Throwable) {
|
} catch (failure: Throwable) {
|
||||||
// Catch invalid hash pepper and retry
|
// Catch invalid hash pepper and retry
|
||||||
@ -117,8 +119,10 @@ internal class DefaultIdentityBulkLookupTask @Inject constructor(
|
|||||||
return withOlmUtility { olmUtility ->
|
return withOlmUtility { olmUtility ->
|
||||||
threePids.map { threePid ->
|
threePids.map { threePid ->
|
||||||
base64ToBase64Url(
|
base64ToBase64Url(
|
||||||
olmUtility.sha256(threePid.value.lowercase(Locale.ROOT) +
|
olmUtility.sha256(
|
||||||
" " + threePid.toMedium() + " " + pepper)
|
threePid.value.lowercase(Locale.ROOT) +
|
||||||
|
" " + threePid.toMedium() + " " + pepper
|
||||||
|
)
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -57,18 +57,22 @@ internal class DefaultIdentityRequestTokenForBindingTask @Inject constructor(
|
|||||||
|
|
||||||
val tokenResponse = executeRequest(null) {
|
val tokenResponse = executeRequest(null) {
|
||||||
when (params.threePid) {
|
when (params.threePid) {
|
||||||
is ThreePid.Email -> identityAPI.requestTokenToBindEmail(IdentityRequestTokenForEmailBody(
|
is ThreePid.Email -> identityAPI.requestTokenToBindEmail(
|
||||||
clientSecret = clientSecret,
|
IdentityRequestTokenForEmailBody(
|
||||||
sendAttempt = sendAttempt,
|
clientSecret = clientSecret,
|
||||||
email = params.threePid.email
|
sendAttempt = sendAttempt,
|
||||||
))
|
email = params.threePid.email
|
||||||
|
)
|
||||||
|
)
|
||||||
is ThreePid.Msisdn -> {
|
is ThreePid.Msisdn -> {
|
||||||
identityAPI.requestTokenToBindMsisdn(IdentityRequestTokenForMsisdnBody(
|
identityAPI.requestTokenToBindMsisdn(
|
||||||
clientSecret = clientSecret,
|
IdentityRequestTokenForMsisdnBody(
|
||||||
sendAttempt = sendAttempt,
|
clientSecret = clientSecret,
|
||||||
phoneNumber = params.threePid.msisdn,
|
sendAttempt = sendAttempt,
|
||||||
countryCode = params.threePid.getCountryCode()
|
phoneNumber = params.threePid.msisdn,
|
||||||
))
|
countryCode = params.threePid.getCountryCode()
|
||||||
|
)
|
||||||
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -50,7 +50,8 @@ internal class DefaultIdentitySubmitTokenForBindingTask @Inject constructor(
|
|||||||
clientSecret = identityPendingBinding.clientSecret,
|
clientSecret = identityPendingBinding.clientSecret,
|
||||||
sid = identityPendingBinding.sid,
|
sid = identityPendingBinding.sid,
|
||||||
token = params.token
|
token = params.token
|
||||||
))
|
)
|
||||||
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!tokenResponse.isSuccess()) {
|
if (!tokenResponse.isSuccess()) {
|
||||||
|
@ -21,9 +21,11 @@ import io.realm.annotations.RealmModule
|
|||||||
/**
|
/**
|
||||||
* Realm module for identity server classes
|
* Realm module for identity server classes
|
||||||
*/
|
*/
|
||||||
@RealmModule(library = true,
|
@RealmModule(
|
||||||
|
library = true,
|
||||||
classes = [
|
classes = [
|
||||||
IdentityDataEntity::class,
|
IdentityDataEntity::class,
|
||||||
IdentityPendingBindingEntity::class
|
IdentityPendingBindingEntity::class
|
||||||
])
|
]
|
||||||
|
)
|
||||||
internal class IdentityRealmModule
|
internal class IdentityRealmModule
|
||||||
|
@ -50,7 +50,8 @@ internal class DefaultBindThreePidsTask @Inject constructor(private val profileA
|
|||||||
identityServerUrlWithoutProtocol = identityServerUrlWithoutProtocol,
|
identityServerUrlWithoutProtocol = identityServerUrlWithoutProtocol,
|
||||||
identityServerAccessToken = identityServerAccessToken,
|
identityServerAccessToken = identityServerAccessToken,
|
||||||
sid = identityPendingBinding.sid
|
sid = identityPendingBinding.sid
|
||||||
))
|
)
|
||||||
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Binding is over, cleanup the store
|
// Binding is over, cleanup the store
|
||||||
|
@ -135,21 +135,25 @@ internal class DefaultProfileService @Inject constructor(private val taskExecuto
|
|||||||
override suspend fun finalizeAddingThreePid(threePid: ThreePid,
|
override suspend fun finalizeAddingThreePid(threePid: ThreePid,
|
||||||
userInteractiveAuthInterceptor: UserInteractiveAuthInterceptor) {
|
userInteractiveAuthInterceptor: UserInteractiveAuthInterceptor) {
|
||||||
finalizeAddingThreePidTask
|
finalizeAddingThreePidTask
|
||||||
.execute(FinalizeAddingThreePidTask.Params(
|
.execute(
|
||||||
threePid = threePid,
|
FinalizeAddingThreePidTask.Params(
|
||||||
userInteractiveAuthInterceptor = userInteractiveAuthInterceptor,
|
threePid = threePid,
|
||||||
userWantsToCancel = false
|
userInteractiveAuthInterceptor = userInteractiveAuthInterceptor,
|
||||||
))
|
userWantsToCancel = false
|
||||||
|
)
|
||||||
|
)
|
||||||
refreshThreePids()
|
refreshThreePids()
|
||||||
}
|
}
|
||||||
|
|
||||||
override suspend fun cancelAddingThreePid(threePid: ThreePid) {
|
override suspend fun cancelAddingThreePid(threePid: ThreePid) {
|
||||||
finalizeAddingThreePidTask
|
finalizeAddingThreePidTask
|
||||||
.execute(FinalizeAddingThreePidTask.Params(
|
.execute(
|
||||||
threePid = threePid,
|
FinalizeAddingThreePidTask.Params(
|
||||||
userInteractiveAuthInterceptor = null,
|
threePid = threePid,
|
||||||
userWantsToCancel = true
|
userInteractiveAuthInterceptor = null,
|
||||||
))
|
userWantsToCancel = true
|
||||||
|
)
|
||||||
|
)
|
||||||
refreshThreePids()
|
refreshThreePids()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -45,7 +45,8 @@ internal class DefaultUnbindThreePidsTask @Inject constructor(private val profil
|
|||||||
identityServerUrlWithoutProtocol,
|
identityServerUrlWithoutProtocol,
|
||||||
params.threePid.toMedium(),
|
params.threePid.toMedium(),
|
||||||
params.threePid.value
|
params.threePid.value
|
||||||
))
|
)
|
||||||
|
)
|
||||||
}.isSuccess()
|
}.isSuccess()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -85,17 +85,19 @@ internal class DefaultPushersService @Inject constructor(
|
|||||||
deviceDisplayName: String,
|
deviceDisplayName: String,
|
||||||
append: Boolean) {
|
append: Boolean) {
|
||||||
addPusherTask.execute(
|
addPusherTask.execute(
|
||||||
AddPusherTask.Params(JsonPusher(
|
AddPusherTask.Params(
|
||||||
pushKey = email,
|
JsonPusher(
|
||||||
kind = Pusher.KIND_EMAIL,
|
pushKey = email,
|
||||||
appId = Pusher.APP_ID_EMAIL,
|
kind = Pusher.KIND_EMAIL,
|
||||||
profileTag = "",
|
appId = Pusher.APP_ID_EMAIL,
|
||||||
lang = lang,
|
profileTag = "",
|
||||||
appDisplayName = appDisplayName,
|
lang = lang,
|
||||||
deviceDisplayName = deviceDisplayName,
|
appDisplayName = appDisplayName,
|
||||||
data = JsonPusherData(brand = emailBranding),
|
deviceDisplayName = deviceDisplayName,
|
||||||
append = append
|
data = JsonPusherData(brand = emailBranding),
|
||||||
))
|
append = append
|
||||||
|
)
|
||||||
|
)
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -67,8 +67,10 @@ internal class DefaultProcessEventForPushTask @Inject constructor(
|
|||||||
}.filter {
|
}.filter {
|
||||||
it.senderId != userId
|
it.senderId != userId
|
||||||
}
|
}
|
||||||
Timber.v("[PushRules] Found ${allEvents.size} out of ${(newJoinEvents + inviteEvents).size}" +
|
Timber.v(
|
||||||
" to check for push rules with ${params.rules.size} rules")
|
"[PushRules] Found ${allEvents.size} out of ${(newJoinEvents + inviteEvents).size}" +
|
||||||
|
" to check for push rules with ${params.rules.size} rules"
|
||||||
|
)
|
||||||
val matchedEvents = allEvents.mapNotNull { event ->
|
val matchedEvents = allEvents.mapNotNull { event ->
|
||||||
pushRuleFinder.fulfilledBingRule(event, params.rules)?.let {
|
pushRuleFinder.fulfilledBingRule(event, params.rules)?.let {
|
||||||
Timber.v("[PushRules] Rule $it match for event ${event.eventId}")
|
Timber.v("[PushRules] Rule $it match for event ${event.eventId}")
|
||||||
|
@ -116,7 +116,8 @@ internal class CreateRoomBodyBuilder @Inject constructor(
|
|||||||
fileUploader.uploadFromUri(
|
fileUploader.uploadFromUri(
|
||||||
uri = avatarUri,
|
uri = avatarUri,
|
||||||
filename = UUID.randomUUID().toString(),
|
filename = UUID.randomUUID().toString(),
|
||||||
mimeType = MimeTypes.Jpeg)
|
mimeType = MimeTypes.Jpeg
|
||||||
|
)
|
||||||
}
|
}
|
||||||
}?.let { response ->
|
}?.let { response ->
|
||||||
Event(
|
Event(
|
||||||
|
@ -83,7 +83,8 @@ internal class RoomMemberEventHandler @Inject constructor(
|
|||||||
roomMember,
|
roomMember,
|
||||||
// When an update is happening, insertOrUpdate replace existing values with null if they are not provided,
|
// When an update is happening, insertOrUpdate replace existing values with null if they are not provided,
|
||||||
// but we want to preserve presence record value and not replace it with null
|
// but we want to preserve presence record value and not replace it with null
|
||||||
getExistingPresenceState(realm, roomId, userId))
|
getExistingPresenceState(realm, roomId, userId)
|
||||||
|
)
|
||||||
realm.insertOrUpdate(roomMemberEntity)
|
realm.insertOrUpdate(roomMemberEntity)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -148,7 +148,8 @@ internal class RedactionEventProcessor @Inject constructor() : EventInsertLivePr
|
|||||||
EventType.STATE_ROOM_MEMBER -> listOf("membership")
|
EventType.STATE_ROOM_MEMBER -> listOf("membership")
|
||||||
EventType.STATE_ROOM_CREATE -> listOf("creator")
|
EventType.STATE_ROOM_CREATE -> listOf("creator")
|
||||||
EventType.STATE_ROOM_JOIN_RULES -> listOf("join_rule")
|
EventType.STATE_ROOM_JOIN_RULES -> listOf("join_rule")
|
||||||
EventType.STATE_ROOM_POWER_LEVELS -> listOf("users",
|
EventType.STATE_ROOM_POWER_LEVELS -> listOf(
|
||||||
|
"users",
|
||||||
"users_default",
|
"users_default",
|
||||||
"events",
|
"events",
|
||||||
"events_default",
|
"events_default",
|
||||||
@ -156,7 +157,8 @@ internal class RedactionEventProcessor @Inject constructor() : EventInsertLivePr
|
|||||||
"ban",
|
"ban",
|
||||||
"kick",
|
"kick",
|
||||||
"redact",
|
"redact",
|
||||||
"invite")
|
"invite"
|
||||||
|
)
|
||||||
EventType.STATE_ROOM_ALIASES -> listOf("aliases")
|
EventType.STATE_ROOM_ALIASES -> listOf("aliases")
|
||||||
EventType.STATE_ROOM_CANONICAL_ALIAS -> listOf("alias")
|
EventType.STATE_ROOM_CANONICAL_ALIAS -> listOf("alias")
|
||||||
EventType.FEEDBACK -> listOf("type", "target_event_id")
|
EventType.FEEDBACK -> listOf("type", "target_event_id")
|
||||||
|
@ -131,7 +131,8 @@ internal class DefaultRelationService @AssistedInject constructor(
|
|||||||
replyText = replyText,
|
replyText = replyText,
|
||||||
autoMarkdown = autoMarkdown,
|
autoMarkdown = autoMarkdown,
|
||||||
rootThreadEventId = rootThreadEventId,
|
rootThreadEventId = rootThreadEventId,
|
||||||
showInThread = showInThread)
|
showInThread = showInThread
|
||||||
|
)
|
||||||
?.also { saveLocalEcho(it) }
|
?.also { saveLocalEcho(it) }
|
||||||
?: return null
|
?: return null
|
||||||
|
|
||||||
@ -186,7 +187,8 @@ internal class DefaultRelationService @AssistedInject constructor(
|
|||||||
text = replyInThreadText,
|
text = replyInThreadText,
|
||||||
msgType = msgType,
|
msgType = msgType,
|
||||||
autoMarkdown = autoMarkdown,
|
autoMarkdown = autoMarkdown,
|
||||||
formattedText = formattedText)
|
formattedText = formattedText
|
||||||
|
)
|
||||||
.also {
|
.also {
|
||||||
saveLocalEcho(it)
|
saveLocalEcho(it)
|
||||||
}
|
}
|
||||||
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user