diff --git a/.idea/dictionaries/bmarty.xml b/.idea/dictionaries/bmarty.xml
index 1f93d1feee..93ac86f417 100644
--- a/.idea/dictionaries/bmarty.xml
+++ b/.idea/dictionaries/bmarty.xml
@@ -12,12 +12,15 @@
fdroid
gplay
hmac
+ homeserver
ktlint
linkified
linkify
megolm
msisdn
+ msisdns
pbkdf
+ pids
pkcs
riotx
signin
diff --git a/CHANGES.md b/CHANGES.md
index bc04df2e39..b63432c489 100644
--- a/CHANGES.md
+++ b/CHANGES.md
@@ -1,14 +1,17 @@
-Changes in RiotX 0.20.0 (2020-XX-XX)
+Changes in RiotX 0.21.0 (2020-XX-XX)
===================================================
Features ✨:
- -
+ - Identity server support (#607)
+ - Switch language support (#41)
Improvements 🙌:
- -
+ - Better connectivity lost indicator when airplane mode is on
+ - Add a setting to hide redacted events (#951)
Bugfix 🐛:
- After jump to unread, newer messages are never loaded (#1008)
+ - Fix issues with FontScale switch (#69, #645)
Translations 🗣:
-
@@ -22,6 +25,26 @@ Build 🧱:
Other changes:
-
+Changes in RiotX 0.20.0 (2020-05-15)
+===================================================
+
+Features ✨:
+ - Add Direct Shortcuts (#652)
+
+Improvements 🙌:
+ - Invite member(s) to an existing room (#1276)
+ - Improve notification accessibility with ticker text (#1226)
+ - Support homeserver discovery from MXID (DISABLED: waiting for design) (#476)
+
+Bugfix 🐛:
+ - Fix | Verify Manually by Text crashes if private SSK not known (#1337)
+ - Sometimes the same device appears twice in the list of devices of a user (#1329)
+ - Random Crashes while doing sth with cross signing keys (#1364)
+ - Crash | crash while restoring key backup (#1366)
+
+SDK API changes ⚠️:
+ - excludedUserIds parameter added to the UserService.getPagedUsersLive() function
+
Changes in RiotX 0.19.0 (2020-05-04)
===================================================
diff --git a/docs/identity_server.md b/docs/identity_server.md
new file mode 100644
index 0000000000..04127c9ab0
--- /dev/null
+++ b/docs/identity_server.md
@@ -0,0 +1,92 @@
+# Identity server
+
+Issue: #607
+PR: #1354
+
+## Introduction
+Identity Servers support contact discovery on Matrix by letting people look up Third Party Identifiers to see if the owner has publicly linked them with their Matrix ID.
+
+## Implementation
+
+The current implementation was Inspired by the code from Riot-Android.
+
+Difference though (list not exhaustive):
+- Only API v2 is supported (see https://matrix.org/docs/spec/identity_service/latest)
+- Homeserver has to be up to date to support binding (Versions.isLoginAndRegistrationSupportedBySdk() has to return true)
+- The SDK managed the session and client secret when binding ThreePid. Those data are not exposed to the client.
+- The SDK supports incremental sendAttempt (this is not used by RiotX)
+- The "Continue" button is now under the information, and not as the same place that the checkbox
+- The app can cancel a binding. Current data are erased from DB.
+- The API (IdentityService) is improved.
+- A new DB to store data related to the identity server management.
+
+Missing features (list not exhaustive):
+- Invite by 3Pid (will be in a dedicated PR)
+- Add email or phone to account (not P1, can be done on Riot-Web)
+- List email and phone of the account (could be done in a dedicated PR)
+- Search contact (not P1)
+- Logout from identity server when user sign out or deactivate his account.
+
+## Related MSCs
+The list can be found here: https://matrix.org/blog/2019/09/27/privacy-improvements-in-synapse-1-4-and-riot-1-4
+
+## Steps and requirements
+
+- Only one identity server by account can be set. The user's choice is stored in account data with key `m.identity_server`. But every clients will managed its own token to log in to the identity server
+```json
+{
+ "type": "m.identity_server",
+ "content": {
+ "base_url": "https://matrix.org"
+ }
+}
+```
+- The accepted terms are stored in the account data:
+```json
+{
+ "type": "m.accepted_terms",
+ "content": {
+ "accepted": [
+ "https://vector.im/identity-server-privacy-notice-1"
+ ]
+ }
+}
+```
+
+- Default identity server URL, from Wellknown data is proposed to the user.
+- Identity server can be set
+- Identity server can be changed on another user's device, so when the change is detected (thanks to account data sync) RiotX should properly disconnect from a previous identity server (I think it was not the case in Riot-Android, where we keep the token forever)
+- Registration to the identity server is managed with an openId token
+- Terms of service can be accepted when configuring the identity server.
+- Terms of service can be accepted after, if they change.
+- Identity server can be modified
+- Identity server can be disconnected with a warning dialog, with special content if there are current bound 3pid on this identity server.
+- Email can be bound
+- Email can be unbound
+- Phone can be bound
+- Phone can be unbound
+- Look up can be performed, to get matrixIds from local contact book (phone and email): Android permission correctly handled (not done yet)
+- Look up pepper can be updated if it is rotated on the identity server
+- Invitation using 3PID can be done (See #548) (not done yet)
+- Homeserver access-token will never be sent to an identity server
+- When user sign-out: logout from the identity server if any.
+- When user deactivate account: logout from the identity server if any.
+
+## Screens
+
+### Settings
+
+Identity server settings can be accessed from the internal setting of the application, both from "Discovery" section and from identity detail section.
+
+### Discovery screen
+
+This screen displays the identity server configuration and the binding of the user's ThreePid (email and msisdn). This is the main screen of the feature.
+
+### Set identity server screen
+
+This screen is a form to set a new identity server URL
+
+## Ref:
+- https://matrix.org/blog/2019/09/27/privacy-improvements-in-synapse-1-4-and-riot-1-4 is a good summary of the role of an Identity server and the proper way to configure and use it in respect to the privacy and the consent of the user.
+- API documentation: https://matrix.org/docs/spec/identity_service/latest
+- vector.im TOS: https://vector.im/identity-server-privacy-notice
diff --git a/gradle.properties b/gradle.properties
index 2e2b110f15..d9d9e57cbc 100644
--- a/gradle.properties
+++ b/gradle.properties
@@ -8,7 +8,7 @@
# The setting is particularly useful for tweaking memory settings.
android.enableJetifier=true
android.useAndroidX=true
-org.gradle.jvmargs=-Xmx1536m
+org.gradle.jvmargs=-Xmx8192m
# When configured, Gradle will run in incubating parallel mode.
# This option should only be used with decoupled projects. More details, visit
# http://www.gradle.org/docs/current/userguide/multi_project_builds.html#sec:decoupled_projects
diff --git a/matrix-sdk-android-rx/src/main/java/im/vector/matrix/rx/RxRoom.kt b/matrix-sdk-android-rx/src/main/java/im/vector/matrix/rx/RxRoom.kt
index 193b5c3fbf..469bc514e0 100644
--- a/matrix-sdk-android-rx/src/main/java/im/vector/matrix/rx/RxRoom.kt
+++ b/matrix-sdk-android-rx/src/main/java/im/vector/matrix/rx/RxRoom.kt
@@ -28,6 +28,7 @@ import im.vector.matrix.android.api.session.room.send.UserDraft
import im.vector.matrix.android.api.session.room.timeline.TimelineEvent
import im.vector.matrix.android.api.util.Optional
import im.vector.matrix.android.api.util.toOptional
+import io.reactivex.Completable
import io.reactivex.Observable
import io.reactivex.Single
@@ -95,6 +96,10 @@ class RxRoom(private val room: Room) {
fun liveNotificationState(): Observable {
return room.getLiveRoomNotificationState().asObservable()
}
+
+ fun invite(userId: String, reason: String? = null): Completable = completableBuilder {
+ room.invite(userId, reason, it)
+ }
}
fun Room.rx(): RxRoom {
diff --git a/matrix-sdk-android-rx/src/main/java/im/vector/matrix/rx/RxSession.kt b/matrix-sdk-android-rx/src/main/java/im/vector/matrix/rx/RxSession.kt
index c2c8978500..a60e83ec96 100644
--- a/matrix-sdk-android-rx/src/main/java/im/vector/matrix/rx/RxSession.kt
+++ b/matrix-sdk-android-rx/src/main/java/im/vector/matrix/rx/RxSession.kt
@@ -21,6 +21,7 @@ import im.vector.matrix.android.api.session.Session
import im.vector.matrix.android.api.session.crypto.crosssigning.MXCrossSigningInfo
import im.vector.matrix.android.api.session.group.GroupSummaryQueryParams
import im.vector.matrix.android.api.session.group.model.GroupSummary
+import im.vector.matrix.android.api.session.identity.ThreePid
import im.vector.matrix.android.api.session.pushers.Pusher
import im.vector.matrix.android.api.session.room.RoomSummaryQueryParams
import im.vector.matrix.android.api.session.room.model.RoomSummary
@@ -90,8 +91,13 @@ class RxSession(private val session: Session) {
return session.getIgnoredUsersLive().asObservable()
}
- fun livePagedUsers(filter: String? = null): Observable> {
- return session.getPagedUsersLive(filter).asObservable()
+ fun livePagedUsers(filter: String? = null, excludedUserIds: Set? = null): Observable> {
+ return session.getPagedUsersLive(filter, excludedUserIds).asObservable()
+ }
+
+ fun liveThreePIds(refreshData: Boolean): Observable> {
+ return session.getThreePidsLive(refreshData).asObservable()
+ .startWithCallable { session.getThreePids() }
}
fun createRoom(roomParams: CreateRoomParams): Single = singleBuilder {
diff --git a/matrix-sdk-android/build.gradle b/matrix-sdk-android/build.gradle
index 514d1accae..abc860d1ff 100644
--- a/matrix-sdk-android/build.gradle
+++ b/matrix-sdk-android/build.gradle
@@ -158,6 +158,9 @@ dependencies {
// Bus
implementation 'org.greenrobot:eventbus:3.1.1'
+ // Phone number https://github.com/google/libphonenumber
+ implementation 'com.googlecode.libphonenumber:libphonenumber:8.10.23'
+
debugImplementation 'com.airbnb.okreplay:okreplay:1.5.0'
releaseImplementation 'com.airbnb.okreplay:noop:1.5.0'
androidTestImplementation 'com.airbnb.okreplay:espresso:1.5.0'
diff --git a/matrix-sdk-android/src/androidTest/java/im/vector/matrix/android/common/CommonTestHelper.kt b/matrix-sdk-android/src/androidTest/java/im/vector/matrix/android/common/CommonTestHelper.kt
index 9b3ebad03b..600bcf2983 100644
--- a/matrix-sdk-android/src/androidTest/java/im/vector/matrix/android/common/CommonTestHelper.kt
+++ b/matrix-sdk-android/src/androidTest/java/im/vector/matrix/android/common/CommonTestHelper.kt
@@ -88,7 +88,8 @@ class CommonTestHelper(context: Context) {
fun syncSession(session: Session) {
val lock = CountDownLatch(1)
- session.open()
+ GlobalScope.launch(Dispatchers.Main) { session.open() }
+
session.startSync(true)
val syncLiveData = runBlocking(Dispatchers.Main) {
diff --git a/matrix-sdk-android/src/androidTest/java/im/vector/matrix/android/common/CryptoTestHelper.kt b/matrix-sdk-android/src/androidTest/java/im/vector/matrix/android/common/CryptoTestHelper.kt
index e4aa7872aa..35ad8ff4e1 100644
--- a/matrix-sdk-android/src/androidTest/java/im/vector/matrix/android/common/CryptoTestHelper.kt
+++ b/matrix-sdk-android/src/androidTest/java/im/vector/matrix/android/common/CryptoTestHelper.kt
@@ -248,7 +248,7 @@ class CryptoTestHelper(private val mTestHelper: CommonTestHelper) {
assertNotNull(eventWireContent.get("session_id"))
assertNotNull(eventWireContent.get("sender_key"))
- assertEquals(senderSession.sessionParams.credentials.deviceId, eventWireContent.get("device_id"))
+ assertEquals(senderSession.sessionParams.deviceId, eventWireContent.get("device_id"))
assertNotNull(event.eventId)
assertEquals(roomId, event.roomId)
diff --git a/matrix-sdk-android/src/androidTest/java/im/vector/matrix/android/internal/crypto/crosssigning/XSigningTest.kt b/matrix-sdk-android/src/androidTest/java/im/vector/matrix/android/internal/crypto/crosssigning/XSigningTest.kt
index f8d30a2679..da3bbdc23c 100644
--- a/matrix-sdk-android/src/androidTest/java/im/vector/matrix/android/internal/crypto/crosssigning/XSigningTest.kt
+++ b/matrix-sdk-android/src/androidTest/java/im/vector/matrix/android/internal/crypto/crosssigning/XSigningTest.kt
@@ -122,7 +122,7 @@ class XSigningTest : InstrumentedTest {
// We will want to test that in alice POV, this new device would be trusted by cross signing
val bobSession2 = mTestHelper.logIntoAccount(bobUserId, SessionTestParams(true))
- val bobSecondDeviceId = bobSession2.sessionParams.credentials.deviceId!!
+ val bobSecondDeviceId = bobSession2.sessionParams.deviceId!!
// Check that bob first session sees the new login
val data = mTestHelper.doSync> {
diff --git a/matrix-sdk-android/src/androidTest/java/im/vector/matrix/android/internal/crypto/gossiping/KeyShareTests.kt b/matrix-sdk-android/src/androidTest/java/im/vector/matrix/android/internal/crypto/gossiping/KeyShareTests.kt
index bb6e020d89..57ab4aaf33 100644
--- a/matrix-sdk-android/src/androidTest/java/im/vector/matrix/android/internal/crypto/gossiping/KeyShareTests.kt
+++ b/matrix-sdk-android/src/androidTest/java/im/vector/matrix/android/internal/crypto/gossiping/KeyShareTests.kt
@@ -148,7 +148,7 @@ class KeyShareTests : InstrumentedTest {
// Mark the device as trusted
aliceSession.cryptoService().setDeviceVerification(DeviceTrustLevel(crossSigningVerified = false, locallyVerified = true), aliceSession.myUserId,
- aliceSession2.sessionParams.credentials.deviceId ?: "")
+ aliceSession2.sessionParams.deviceId ?: "")
// Re request
aliceSession2.cryptoService().reRequestRoomKeyForEvent(receivedEvent.root)
@@ -253,12 +253,12 @@ class KeyShareTests : InstrumentedTest {
})
val txId: String = "m.testVerif12"
- aliceVerificationService2.beginKeyVerification(VerificationMethod.SAS, aliceSession1.myUserId, aliceSession1.sessionParams.credentials.deviceId
+ aliceVerificationService2.beginKeyVerification(VerificationMethod.SAS, aliceSession1.myUserId, aliceSession1.sessionParams.deviceId
?: "", txId)
mTestHelper.waitWithLatch { latch ->
mTestHelper.retryPeriodicallyWithLatch(latch) {
- aliceSession1.cryptoService().getDeviceInfo(aliceSession1.myUserId, aliceSession2.sessionParams.credentials.deviceId ?: "")?.isVerified == true
+ aliceSession1.cryptoService().getDeviceInfo(aliceSession1.myUserId, aliceSession2.sessionParams.deviceId ?: "")?.isVerified == true
}
}
diff --git a/matrix-sdk-android/src/androidTest/java/im/vector/matrix/android/internal/crypto/keysbackup/KeysBackupScenarioData.kt b/matrix-sdk-android/src/androidTest/java/im/vector/matrix/android/internal/crypto/keysbackup/KeysBackupScenarioData.kt
index f10f2fef0e..0270c34a37 100644
--- a/matrix-sdk-android/src/androidTest/java/im/vector/matrix/android/internal/crypto/keysbackup/KeysBackupScenarioData.kt
+++ b/matrix-sdk-android/src/androidTest/java/im/vector/matrix/android/internal/crypto/keysbackup/KeysBackupScenarioData.kt
@@ -19,13 +19,13 @@ package im.vector.matrix.android.internal.crypto.keysbackup
import im.vector.matrix.android.api.session.Session
import im.vector.matrix.android.common.CommonTestHelper
import im.vector.matrix.android.common.CryptoTestData
-import im.vector.matrix.android.internal.crypto.model.OlmInboundGroupSessionWrapper
+import im.vector.matrix.android.internal.crypto.model.OlmInboundGroupSessionWrapper2
/**
* Data class to store result of [KeysBackupTestHelper.createKeysBackupScenarioWithPassword]
*/
data class KeysBackupScenarioData(val cryptoTestData: CryptoTestData,
- val aliceKeys: List,
+ val aliceKeys: List,
val prepareKeysBackupDataResult: PrepareKeysBackupDataResult,
val aliceSession2: Session) {
fun cleanUp(testHelper: CommonTestHelper) {
diff --git a/matrix-sdk-android/src/androidTest/java/im/vector/matrix/android/internal/crypto/keysbackup/KeysBackupTest.kt b/matrix-sdk-android/src/androidTest/java/im/vector/matrix/android/internal/crypto/keysbackup/KeysBackupTest.kt
index 59ef24beec..2e698a929e 100644
--- a/matrix-sdk-android/src/androidTest/java/im/vector/matrix/android/internal/crypto/keysbackup/KeysBackupTest.kt
+++ b/matrix-sdk-android/src/androidTest/java/im/vector/matrix/android/internal/crypto/keysbackup/KeysBackupTest.kt
@@ -835,7 +835,7 @@ class KeysBackupTest : InstrumentedTest {
assertTrue(signature.valid)
assertNotNull(signature.device)
assertEquals(cryptoTestData.firstSession.cryptoService().getMyDevice().deviceId, signature.deviceId)
- assertEquals(signature.device!!.deviceId, cryptoTestData.firstSession.sessionParams.credentials.deviceId)
+ assertEquals(signature.device!!.deviceId, cryptoTestData.firstSession.sessionParams.deviceId)
stateObserver.stopAndCheckStates(null)
cryptoTestData.cleanUp(mTestHelper)
@@ -997,7 +997,7 @@ class KeysBackupTest : InstrumentedTest {
keysBackup.backupAllGroupSessions(null, it)
}
- val oldDeviceId = cryptoTestData.firstSession.sessionParams.credentials.deviceId!!
+ val oldDeviceId = cryptoTestData.firstSession.sessionParams.deviceId!!
val oldKeyBackupVersion = keysBackup.currentBackupVersion
val aliceUserId = cryptoTestData.firstSession.myUserId
diff --git a/matrix-sdk-android/src/androidTest/java/im/vector/matrix/android/internal/crypto/verification/SASTest.kt b/matrix-sdk-android/src/androidTest/java/im/vector/matrix/android/internal/crypto/verification/SASTest.kt
index 1ac70d7f2b..9bdd8f1131 100644
--- a/matrix-sdk-android/src/androidTest/java/im/vector/matrix/android/internal/crypto/verification/SASTest.kt
+++ b/matrix-sdk-android/src/androidTest/java/im/vector/matrix/android/internal/crypto/verification/SASTest.kt
@@ -579,7 +579,7 @@ class SASTest : InstrumentedTest {
requestID!!,
cryptoTestData.roomId,
bobSession.myUserId,
- bobSession.sessionParams.credentials.deviceId!!,
+ bobSession.sessionParams.deviceId!!,
null)
bobVerificationService.beginKeyVerificationInDMs(
@@ -587,7 +587,7 @@ class SASTest : InstrumentedTest {
requestID!!,
cryptoTestData.roomId,
aliceSession.myUserId,
- aliceSession.sessionParams.credentials.deviceId!!,
+ aliceSession.sessionParams.deviceId!!,
null)
// we should reach SHOW SAS on both
diff --git a/matrix-sdk-android/src/main/java/im/vector/matrix/android/api/auth/AuthenticationService.kt b/matrix-sdk-android/src/main/java/im/vector/matrix/android/api/auth/AuthenticationService.kt
index 140d1c259f..effeae596a 100644
--- a/matrix-sdk-android/src/main/java/im/vector/matrix/android/api/auth/AuthenticationService.kt
+++ b/matrix-sdk-android/src/main/java/im/vector/matrix/android/api/auth/AuthenticationService.kt
@@ -20,9 +20,9 @@ import im.vector.matrix.android.api.MatrixCallback
import im.vector.matrix.android.api.auth.data.Credentials
import im.vector.matrix.android.api.auth.data.HomeServerConnectionConfig
import im.vector.matrix.android.api.auth.data.LoginFlowResult
-import im.vector.matrix.android.api.auth.data.SessionParams
import im.vector.matrix.android.api.auth.login.LoginWizard
import im.vector.matrix.android.api.auth.registration.RegistrationWizard
+import im.vector.matrix.android.api.auth.wellknown.WellknownResult
import im.vector.matrix.android.api.session.Session
import im.vector.matrix.android.api.util.Cancelable
@@ -30,13 +30,17 @@ import im.vector.matrix.android.api.util.Cancelable
* This interface defines methods to authenticate or to create an account to a matrix server.
*/
interface AuthenticationService {
-
/**
* Request the supported login flows for this homeserver.
* This is the first method to call to be able to get a wizard to login or the create an account
*/
fun getLoginFlow(homeServerConnectionConfig: HomeServerConnectionConfig, callback: MatrixCallback): Cancelable
+ /**
+ * Request the supported login flows for the corresponding sessionId.
+ */
+ fun getLoginFlowOfSession(sessionId: String, callback: MatrixCallback): Cancelable
+
/**
* Return a LoginWizard, to login to the homeserver. The login flow has to be retrieved first.
*/
@@ -74,19 +78,26 @@ interface AuthenticationService {
*/
fun getLastAuthenticatedSession(): Session?
- /**
- * Get an authenticated session. You should at least call authenticate one time before.
- * If you logout, this session will no longer be valid.
- *
- * @param sessionParams the sessionParams to open with.
- * @return the associated session if any, or null
- */
- fun getSession(sessionParams: SessionParams): Session?
-
/**
* Create a session after a SSO successful login
*/
fun createSessionFromSso(homeServerConnectionConfig: HomeServerConnectionConfig,
credentials: Credentials,
callback: MatrixCallback): Cancelable
+
+ /**
+ * Perform a wellknown request, using the domain from the matrixId
+ */
+ fun getWellKnownData(matrixId: String,
+ callback: MatrixCallback): Cancelable
+
+ /**
+ * Authenticate with a matrixId and a password
+ * Usually call this after a successful call to getWellKnownData()
+ */
+ fun directAuthentication(homeServerConnectionConfig: HomeServerConnectionConfig,
+ matrixId: String,
+ password: String,
+ initialDeviceName: String,
+ callback: MatrixCallback): Cancelable
}
diff --git a/matrix-sdk-android/src/main/java/im/vector/matrix/android/api/auth/data/Credentials.kt b/matrix-sdk-android/src/main/java/im/vector/matrix/android/api/auth/data/Credentials.kt
index 72affe24bb..d88cd5e74d 100644
--- a/matrix-sdk-android/src/main/java/im/vector/matrix/android/api/auth/data/Credentials.kt
+++ b/matrix-sdk-android/src/main/java/im/vector/matrix/android/api/auth/data/Credentials.kt
@@ -24,16 +24,38 @@ import im.vector.matrix.android.internal.util.md5
* This data class hold credentials user data.
* You shouldn't have to instantiate it.
* The access token should be use to authenticate user in all server requests.
+ * Ref: https://matrix.org/docs/spec/client_server/latest#post-matrix-client-r0-login
*/
@JsonClass(generateAdapter = true)
data class Credentials(
+ /**
+ * The fully-qualified Matrix ID that has been registered.
+ */
@Json(name = "user_id") val userId: String,
- @Json(name = "home_server") val homeServer: String,
+ /**
+ * An access token for the account. This access token can then be used to authorize other requests.
+ */
@Json(name = "access_token") val accessToken: String,
+ /**
+ * Not documented
+ */
@Json(name = "refresh_token") val refreshToken: String?,
+ /**
+ * The server_name of the homeserver on which the account has been registered.
+ * @Deprecated. Clients should extract the server_name from user_id (by splitting at the first colon)
+ * if they require it. Note also that homeserver is not spelt this way.
+ */
+ @Json(name = "home_server") val homeServer: String,
+ /**
+ * ID of the logged-in device. Will be the same as the corresponding parameter in the request, if one was specified.
+ */
@Json(name = "device_id") val deviceId: String?,
- // Optional data that may contain info to override home server and/or identity server
- @Json(name = "well_known") val wellKnown: WellKnown? = null
+ /**
+ * Optional client configuration provided by the server. If present, clients SHOULD use the provided object to
+ * reconfigure themselves, optionally validating the URLs within.
+ * This object takes the same form as the one returned from .well-known autodiscovery.
+ */
+ @Json(name = "well_known") val discoveryInformation: DiscoveryInformation? = null
)
internal fun Credentials.sessionId(): String {
diff --git a/matrix-sdk-android/src/main/java/im/vector/matrix/android/api/auth/data/DiscoveryInformation.kt b/matrix-sdk-android/src/main/java/im/vector/matrix/android/api/auth/data/DiscoveryInformation.kt
new file mode 100644
index 0000000000..2aa741bad3
--- /dev/null
+++ b/matrix-sdk-android/src/main/java/im/vector/matrix/android/api/auth/data/DiscoveryInformation.kt
@@ -0,0 +1,40 @@
+/*
+ * Copyright (c) 2020 New Vector Ltd
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package im.vector.matrix.android.api.auth.data
+
+import com.squareup.moshi.Json
+import com.squareup.moshi.JsonClass
+
+/**
+ * This is a light version of Wellknown model, used for login response
+ * Ref: https://matrix.org/docs/spec/client_server/latest#post-matrix-client-r0-login
+ */
+@JsonClass(generateAdapter = true)
+data class DiscoveryInformation(
+ /**
+ * Required. Used by clients to discover homeserver information.
+ */
+ @Json(name = "m.homeserver")
+ val homeServer: WellKnownBaseConfig? = null,
+
+ /**
+ * Used by clients to discover identity server information.
+ * Note: matrix.org does not send this field
+ */
+ @Json(name = "m.identity_server")
+ val identityServer: WellKnownBaseConfig? = null
+)
diff --git a/matrix-sdk-android/src/main/java/im/vector/matrix/android/api/auth/data/SessionParams.kt b/matrix-sdk-android/src/main/java/im/vector/matrix/android/api/auth/data/SessionParams.kt
index 2d65cac43d..1cbba50af7 100644
--- a/matrix-sdk-android/src/main/java/im/vector/matrix/android/api/auth/data/SessionParams.kt
+++ b/matrix-sdk-android/src/main/java/im/vector/matrix/android/api/auth/data/SessionParams.kt
@@ -21,7 +21,48 @@ package im.vector.matrix.android.api.auth.data
* You don't have to manually instantiate it.
*/
data class SessionParams(
+ /**
+ * Please consider using shortcuts instead
+ */
val credentials: Credentials,
+
+ /**
+ * Please consider using shortcuts instead
+ */
val homeServerConnectionConfig: HomeServerConnectionConfig,
+
+ /**
+ * Set to false if the current token is not valid anymore. Application should not have to use this info.
+ */
val isTokenValid: Boolean
-)
+) {
+ /*
+ * Shortcuts. Usually the application should only need to use these shortcuts
+ */
+
+ /**
+ * The userId of the session (Ex: "@user:domain.org")
+ */
+ val userId = credentials.userId
+
+ /**
+ * The deviceId of the session (Ex: "ABCDEFGH")
+ */
+ val deviceId = credentials.deviceId
+
+ /**
+ * The current homeserver Url. It can be different that the homeserver url entered
+ * during login phase, because a redirection may have occurred
+ */
+ val homeServerUrl = homeServerConnectionConfig.homeServerUri.toString()
+
+ /**
+ * The current homeserver host
+ */
+ val homeServerHost = homeServerConnectionConfig.homeServerUri.host
+
+ /**
+ * The default identity server url if any, returned by the homeserver during login phase
+ */
+ val defaultIdentityServerUrl = homeServerConnectionConfig.identityServerUri?.toString()
+}
diff --git a/matrix-sdk-android/src/main/java/im/vector/matrix/android/api/auth/data/WellKnown.kt b/matrix-sdk-android/src/main/java/im/vector/matrix/android/api/auth/data/WellKnown.kt
index bdad4702b7..9dd1fa2012 100644
--- a/matrix-sdk-android/src/main/java/im/vector/matrix/android/api/auth/data/WellKnown.kt
+++ b/matrix-sdk-android/src/main/java/im/vector/matrix/android/api/auth/data/WellKnown.kt
@@ -18,6 +18,7 @@ package im.vector.matrix.android.api.auth.data
import com.squareup.moshi.Json
import com.squareup.moshi.JsonClass
+import im.vector.matrix.android.api.util.JsonDict
/**
* https://matrix.org/docs/spec/client_server/r0.4.0.html#server-discovery
@@ -52,7 +53,7 @@ data class WellKnown(
val identityServer: WellKnownBaseConfig? = null,
@Json(name = "m.integrations")
- val integrations: Map? = null
+ val integrations: JsonDict? = null
) {
/**
* Returns the list of integration managers proposed
diff --git a/matrix-sdk-android/src/main/java/im/vector/matrix/android/api/auth/data/WellKnownManagerConfig.kt b/matrix-sdk-android/src/main/java/im/vector/matrix/android/api/auth/data/WellKnownManagerConfig.kt
index 33ed412a2a..ffdea37afe 100644
--- a/matrix-sdk-android/src/main/java/im/vector/matrix/android/api/auth/data/WellKnownManagerConfig.kt
+++ b/matrix-sdk-android/src/main/java/im/vector/matrix/android/api/auth/data/WellKnownManagerConfig.kt
@@ -16,6 +16,6 @@
package im.vector.matrix.android.api.auth.data
data class WellKnownManagerConfig(
- val apiUrl : String,
+ val apiUrl: String,
val uiUrl: String
)
diff --git a/matrix-sdk-android/src/main/java/im/vector/matrix/android/api/auth/wellknown/WellknownResult.kt b/matrix-sdk-android/src/main/java/im/vector/matrix/android/api/auth/wellknown/WellknownResult.kt
new file mode 100644
index 0000000000..58c7cf730e
--- /dev/null
+++ b/matrix-sdk-android/src/main/java/im/vector/matrix/android/api/auth/wellknown/WellknownResult.kt
@@ -0,0 +1,55 @@
+/*
+ * Copyright (c) 2020 New Vector Ltd
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package im.vector.matrix.android.api.auth.wellknown
+
+import im.vector.matrix.android.api.auth.data.WellKnown
+
+/**
+ * Ref: https://matrix.org/docs/spec/client_server/latest#well-known-uri
+ */
+sealed class WellknownResult {
+ /**
+ * The provided matrixId is no valid. Unable to extract a domain name.
+ */
+ object InvalidMatrixId : WellknownResult()
+
+ /**
+ * Retrieve the specific piece of information from the user in a way which fits within the existing client user experience,
+ * if the client is inclined to do so. Failure can take place instead if no good user experience for this is possible at this point.
+ */
+ data class Prompt(val homeServerUrl: String,
+ val identityServerUrl: String?,
+ val wellKnown: WellKnown) : WellknownResult()
+
+ /**
+ * Stop the current auto-discovery mechanism. If no more auto-discovery mechanisms are available,
+ * then the client may use other methods of determining the required parameters, such as prompting the user, or using default values.
+ */
+ object Ignore : WellknownResult()
+
+ /**
+ * Inform the user that auto-discovery failed due to invalid/empty data and PROMPT for the parameter.
+ */
+ object FailPrompt : WellknownResult()
+
+ /**
+ * Inform the user that auto-discovery did not return any usable URLs. Do not continue further with the current login process.
+ * At this point, valid data was obtained, but no homeserver is available to serve the client.
+ * No further guess should be attempted and the user should make a conscientious decision what to do next.
+ */
+ object FailError : WellknownResult()
+}
diff --git a/matrix-sdk-android/src/main/java/im/vector/matrix/android/api/failure/MatrixError.kt b/matrix-sdk-android/src/main/java/im/vector/matrix/android/api/failure/MatrixError.kt
index d7a6954fd5..7c9ace5d82 100644
--- a/matrix-sdk-android/src/main/java/im/vector/matrix/android/api/failure/MatrixError.kt
+++ b/matrix-sdk-android/src/main/java/im/vector/matrix/android/api/failure/MatrixError.kt
@@ -39,7 +39,10 @@ data class MatrixError(
// For M_LIMIT_EXCEEDED
@Json(name = "retry_after_ms") val retryAfterMillis: Long? = null,
// For M_UNKNOWN_TOKEN
- @Json(name = "soft_logout") val isSoftLogout: Boolean = false
+ @Json(name = "soft_logout") val isSoftLogout: Boolean = false,
+ // For M_INVALID_PEPPER
+ // {"error": "pepper does not match 'erZvr'", "lookup_pepper": "pQgMS", "algorithm": "sha256", "errcode": "M_INVALID_PEPPER"}
+ @Json(name = "lookup_pepper") val newLookupPepper: String? = null
) {
companion object {
@@ -129,6 +132,11 @@ data class MatrixError(
/** (Not documented yet) */
const val M_WRONG_ROOM_KEYS_VERSION = "M_WRONG_ROOM_KEYS_VERSION"
+ const val M_TERMS_NOT_SIGNED = "M_TERMS_NOT_SIGNED"
+
+ // For identity service
+ const val M_INVALID_PEPPER = "M_INVALID_PEPPER"
+
// Possible value for "limit_type"
const val LIMIT_TYPE_MAU = "monthly_active_user"
}
diff --git a/matrix-sdk-android/src/main/java/im/vector/matrix/android/api/session/Session.kt b/matrix-sdk-android/src/main/java/im/vector/matrix/android/api/session/Session.kt
index 1afeed922f..c86ca25faf 100644
--- a/matrix-sdk-android/src/main/java/im/vector/matrix/android/api/session/Session.kt
+++ b/matrix-sdk-android/src/main/java/im/vector/matrix/android/api/session/Session.kt
@@ -30,6 +30,7 @@ import im.vector.matrix.android.api.session.crypto.CryptoService
import im.vector.matrix.android.api.session.file.FileService
import im.vector.matrix.android.api.session.group.GroupService
import im.vector.matrix.android.api.session.homeserver.HomeServerCapabilitiesService
+import im.vector.matrix.android.api.session.identity.IdentityService
import im.vector.matrix.android.api.session.profile.ProfileService
import im.vector.matrix.android.api.session.pushers.PushersService
import im.vector.matrix.android.api.session.room.RoomDirectoryService
@@ -39,6 +40,7 @@ import im.vector.matrix.android.api.session.securestorage.SharedSecretStorageSer
import im.vector.matrix.android.api.session.signout.SignOutService
import im.vector.matrix.android.api.session.sync.FilterService
import im.vector.matrix.android.api.session.sync.SyncState
+import im.vector.matrix.android.api.session.terms.TermsService
import im.vector.matrix.android.api.session.user.UserService
/**
@@ -54,6 +56,7 @@ interface Session :
SignOutService,
FilterService,
FileService,
+ TermsService,
ProfileService,
PushRuleService,
PushersService,
@@ -77,7 +80,7 @@ interface Session :
* Useful shortcut to get access to the userId
*/
val myUserId: String
- get() = sessionParams.credentials.userId
+ get() = sessionParams.userId
/**
* The sessionId
@@ -145,6 +148,11 @@ interface Session :
*/
fun cryptoService(): CryptoService
+ /**
+ * Returns the identity service associated with the session
+ */
+ fun identityService(): IdentityService
+
/**
* Add a listener to the session.
* @param listener the listener to add.
diff --git a/matrix-sdk-android/src/main/java/im/vector/matrix/android/api/session/homeserver/HomeServerCapabilities.kt b/matrix-sdk-android/src/main/java/im/vector/matrix/android/api/session/homeserver/HomeServerCapabilities.kt
index c8526985e1..1c2b8de83b 100644
--- a/matrix-sdk-android/src/main/java/im/vector/matrix/android/api/session/homeserver/HomeServerCapabilities.kt
+++ b/matrix-sdk-android/src/main/java/im/vector/matrix/android/api/session/homeserver/HomeServerCapabilities.kt
@@ -24,7 +24,15 @@ data class HomeServerCapabilities(
/**
* Max size of file which can be uploaded to the homeserver in bytes. [MAX_UPLOAD_FILE_SIZE_UNKNOWN] if unknown or not retrieved yet
*/
- val maxUploadFileSize: Long = MAX_UPLOAD_FILE_SIZE_UNKNOWN
+ val maxUploadFileSize: Long = MAX_UPLOAD_FILE_SIZE_UNKNOWN,
+ /**
+ * Last version identity server and binding supported
+ */
+ val lastVersionIdentityServerSupported: Boolean = false,
+ /**
+ * Default identity server url, provided in Wellknown
+ */
+ val defaultIdentityServerUrl: String? = null
) {
companion object {
const val MAX_UPLOAD_FILE_SIZE_UNKNOWN = -1L
diff --git a/matrix-sdk-android/src/main/java/im/vector/matrix/android/api/session/identity/FoundThreePid.kt b/matrix-sdk-android/src/main/java/im/vector/matrix/android/api/session/identity/FoundThreePid.kt
new file mode 100644
index 0000000000..5817699636
--- /dev/null
+++ b/matrix-sdk-android/src/main/java/im/vector/matrix/android/api/session/identity/FoundThreePid.kt
@@ -0,0 +1,22 @@
+/*
+ * Copyright (c) 2020 New Vector Ltd
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package im.vector.matrix.android.api.session.identity
+
+data class FoundThreePid(
+ val threePid: ThreePid,
+ val matrixId: String
+)
diff --git a/matrix-sdk-android/src/main/java/im/vector/matrix/android/api/session/identity/IdentityService.kt b/matrix-sdk-android/src/main/java/im/vector/matrix/android/api/session/identity/IdentityService.kt
new file mode 100644
index 0000000000..2f2821d7a8
--- /dev/null
+++ b/matrix-sdk-android/src/main/java/im/vector/matrix/android/api/session/identity/IdentityService.kt
@@ -0,0 +1,109 @@
+/*
+ * Copyright (c) 2020 New Vector Ltd
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package im.vector.matrix.android.api.session.identity
+
+import im.vector.matrix.android.api.MatrixCallback
+import im.vector.matrix.android.api.util.Cancelable
+
+/**
+ * Provides access to the identity server configuration and services identity server can provide
+ */
+interface IdentityService {
+ /**
+ * Return the default identity server of the user, which may have been provided at login time by the homeserver,
+ * or by the Well-known setup of the homeserver
+ * It may be different from the current configured identity server
+ */
+ fun getDefaultIdentityServer(): String?
+
+ /**
+ * Return the current identity server URL used by this account. Returns null if no identity server is configured.
+ */
+ fun getCurrentIdentityServerUrl(): String?
+
+ /**
+ * Check if the identity server is valid
+ * See https://matrix.org/docs/spec/identity_service/latest#status-check
+ * RiotX SDK only supports identity server API v2
+ */
+ fun isValidIdentityServer(url: String, callback: MatrixCallback): Cancelable
+
+ /**
+ * Update the identity server url.
+ * If successful, any previous identity server will be disconnected.
+ * In case of error, any previous identity server will remain configured.
+ * @param url the new url.
+ * @param callback will notify the user if change is successful. The String will be the final url of the identity server.
+ * The SDK can prepend "https://" for instance.
+ */
+ fun setNewIdentityServer(url: String, callback: MatrixCallback): Cancelable
+
+ /**
+ * Disconnect (logout) from the current identity server
+ */
+ fun disconnect(callback: MatrixCallback): Cancelable
+
+ /**
+ * This will ask the identity server to send an email or an SMS to let the user confirm he owns the ThreePid
+ */
+ fun startBindThreePid(threePid: ThreePid, callback: MatrixCallback): Cancelable
+
+ /**
+ * This will cancel a pending binding of threePid.
+ */
+ fun cancelBindThreePid(threePid: ThreePid, callback: MatrixCallback): Cancelable
+
+ /**
+ * This will ask the identity server to send an new email or a new SMS to let the user confirm he owns the ThreePid
+ */
+ fun sendAgainValidationCode(threePid: ThreePid, callback: MatrixCallback): Cancelable
+
+ /**
+ * Submit the code that the identity server has sent to the user (in email or SMS)
+ * Once successful, you will have to call [finalizeBindThreePid]
+ * @param code the code sent to the user
+ */
+ fun submitValidationToken(threePid: ThreePid, code: String, callback: MatrixCallback): Cancelable
+
+ /**
+ * This will perform the actual association of ThreePid and Matrix account
+ */
+ fun finalizeBindThreePid(threePid: ThreePid, callback: MatrixCallback): Cancelable
+
+ /**
+ * Unbind a threePid
+ * The request will actually be done on the homeserver
+ */
+ fun unbindThreePid(threePid: ThreePid, callback: MatrixCallback): Cancelable
+
+ /**
+ * Search MatrixId of users providing email and phone numbers
+ */
+ fun lookUp(threePids: List, callback: MatrixCallback>): Cancelable
+
+ /**
+ * Get the status of the current user's threePid
+ * A lookup will be performed, but also pending binding state will be restored
+ *
+ * @param threePids the list of threePid the user owns (retrieved form the homeserver)
+ * @param callback onSuccess will be called with a map of ThreePid -> SharedState
+ */
+ fun getShareStatus(threePids: List, callback: MatrixCallback