Implement: Adding MSISDN (WIP)
This commit is contained in:
parent
5a21249022
commit
e309b30203
@ -77,5 +77,6 @@ class RealmSessionStoreMigration @Inject constructor() : RealmMigration {
|
||||
.setRequired(PendingThreePidEntityFields.SEND_ATTEMPT, true)
|
||||
.addField(PendingThreePidEntityFields.SID, String::class.java)
|
||||
.setRequired(PendingThreePidEntityFields.SID, true)
|
||||
.addField(PendingThreePidEntityFields.SUBMIT_URL, String::class.java)
|
||||
}
|
||||
}
|
||||
|
@ -27,5 +27,6 @@ internal open class PendingThreePidEntity(
|
||||
var msisdn: String? = null,
|
||||
var clientSecret: String = "",
|
||||
var sendAttempt: Int = 0,
|
||||
var sid: String = ""
|
||||
var sid: String = "",
|
||||
var submitUrl: String? = null
|
||||
) : RealmObject()
|
||||
|
@ -20,7 +20,7 @@ import com.squareup.moshi.Json
|
||||
import com.squareup.moshi.JsonClass
|
||||
|
||||
@JsonClass(generateAdapter = true)
|
||||
internal data class AddThreePidResponse(
|
||||
internal data class AddEmailResponse(
|
||||
/**
|
||||
* Required. The session ID. Session IDs are opaque strings that must consist entirely
|
||||
* of the characters [0-9a-zA-Z.=_-]. Their length must not exceed 255 characters and they must not be empty.
|
@ -0,0 +1,54 @@
|
||||
/*
|
||||
* Copyright (c) 2020 New Vector Ltd
|
||||
* Copyright 2020 The Matrix.org Foundation C.I.C.
|
||||
*
|
||||
* 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 org.matrix.android.sdk.internal.session.profile
|
||||
|
||||
import com.squareup.moshi.Json
|
||||
import com.squareup.moshi.JsonClass
|
||||
|
||||
@JsonClass(generateAdapter = true)
|
||||
internal data class AddMsisdnBody(
|
||||
/**
|
||||
* Required. A unique string generated by the client, and used to identify the validation attempt.
|
||||
* It must be a string consisting of the characters [0-9a-zA-Z.=_-]. Its length must not exceed
|
||||
* 255 characters and it must not be empty.
|
||||
*/
|
||||
@Json(name = "client_secret")
|
||||
val clientSecret: String,
|
||||
|
||||
/**
|
||||
* Required. The two-letter uppercase ISO-3166-1 alpha-2 country code that the number in
|
||||
* phone_number should be parsed as if it were dialled from.
|
||||
*/
|
||||
@Json(name = "country")
|
||||
val country: String,
|
||||
|
||||
/**
|
||||
* Required. The phone number to validate.
|
||||
*/
|
||||
@Json(name = "phone_number")
|
||||
val phoneNumber: String,
|
||||
|
||||
/**
|
||||
* Required. The server will only send an SMS if the send_attempt is a number greater than the most
|
||||
* recent one which it has seen, scoped to that country + phone_number + client_secret triple. This
|
||||
* is to avoid repeatedly sending the same SMS in the case of request retries between the POSTing user
|
||||
* and the identity server. The client should increment this value if they desire a new SMS (e.g. a
|
||||
* reminder) to be sent.
|
||||
*/
|
||||
@Json(name = "send_attempt")
|
||||
val sendAttempt: Int
|
||||
)
|
@ -0,0 +1,55 @@
|
||||
/*
|
||||
* Copyright 2019 New Vector Ltd
|
||||
* Copyright 2020 The Matrix.org Foundation C.I.C.
|
||||
*
|
||||
* 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 org.matrix.android.sdk.internal.session.profile
|
||||
|
||||
import com.squareup.moshi.Json
|
||||
import com.squareup.moshi.JsonClass
|
||||
|
||||
@JsonClass(generateAdapter = true)
|
||||
internal data class AddMsisdnResponse(
|
||||
/**
|
||||
* Required. The session ID. Session IDs are opaque strings that must consist entirely of the characters [0-9a-zA-Z.=_-].
|
||||
* Their length must not exceed 255 characters and they must not be empty.
|
||||
*/
|
||||
@Json(name = "sid")
|
||||
val sid: String,
|
||||
|
||||
/**
|
||||
* An optional field containing a URL where the client must submit the validation token to, with identical parameters to the Identity
|
||||
* Service API's POST /validate/email/submitToken endpoint (without the requirement for an access token).
|
||||
* The homeserver must send this token to the user (if applicable), who should then be prompted to provide it to the client.
|
||||
*
|
||||
* If this field is not present, the client can assume that verification will happen without the client's involvement provided
|
||||
* the homeserver advertises this specification version in the /versions response (ie: r0.5.0).
|
||||
*/
|
||||
@Json(name = "submit_url")
|
||||
val submitUrl: String? = null,
|
||||
|
||||
/* ==========================================================================================
|
||||
* It seems that the homeserver is sending more data, we may need it
|
||||
* ========================================================================================== */
|
||||
|
||||
@Json(name = "msisdn")
|
||||
val msisdn: String? = null,
|
||||
|
||||
@Json(name = "intl_fmt")
|
||||
val formattedMsisdn: String? = null,
|
||||
|
||||
@Json(name = "success")
|
||||
val success: Boolean? = null
|
||||
)
|
@ -17,6 +17,7 @@
|
||||
|
||||
package org.matrix.android.sdk.internal.session.profile
|
||||
|
||||
import com.google.i18n.phonenumbers.PhoneNumberUtil
|
||||
import com.zhuinden.monarchy.Monarchy
|
||||
import org.greenrobot.eventbus.EventBus
|
||||
import org.matrix.android.sdk.api.session.identity.ThreePid
|
||||
@ -40,31 +41,76 @@ internal class DefaultAddThreePidTask @Inject constructor(
|
||||
private val eventBus: EventBus) : AddThreePidTask() {
|
||||
|
||||
override suspend fun execute(params: Params) {
|
||||
when (params.threePid) {
|
||||
is ThreePid.Email -> addEmail(params.threePid)
|
||||
is ThreePid.Msisdn -> addMsisdn(params.threePid)
|
||||
}
|
||||
}
|
||||
|
||||
private suspend fun addEmail(threePid: ThreePid.Email) {
|
||||
val clientSecret = UUID.randomUUID().toString()
|
||||
val sendAttempt = 1
|
||||
val result = when (params.threePid) {
|
||||
is ThreePid.Email ->
|
||||
executeRequest<AddThreePidResponse>(eventBus) {
|
||||
val body = AddEmailBody(
|
||||
email = params.threePid.email,
|
||||
sendAttempt = sendAttempt,
|
||||
clientSecret = clientSecret
|
||||
)
|
||||
apiCall = profileAPI.addEmail(body)
|
||||
}
|
||||
is ThreePid.Msisdn -> TODO()
|
||||
|
||||
val result = executeRequest<AddEmailResponse>(eventBus) {
|
||||
val body = AddEmailBody(
|
||||
clientSecret = clientSecret,
|
||||
email = threePid.email,
|
||||
sendAttempt = sendAttempt
|
||||
)
|
||||
apiCall = profileAPI.addEmail(body)
|
||||
}
|
||||
|
||||
// Store as a pending three pid
|
||||
monarchy.awaitTransaction { realm ->
|
||||
PendingThreePid(
|
||||
threePid = params.threePid,
|
||||
threePid = threePid,
|
||||
clientSecret = clientSecret,
|
||||
sendAttempt = sendAttempt,
|
||||
sid = result.sid
|
||||
sid = result.sid,
|
||||
submitUrl = null
|
||||
)
|
||||
.let { pendingThreePidMapper.map(it) }
|
||||
.let { realm.copyToRealm(it) }
|
||||
}
|
||||
}
|
||||
|
||||
private suspend fun addMsisdn(threePid: ThreePid.Msisdn) {
|
||||
val clientSecret = UUID.randomUUID().toString()
|
||||
val sendAttempt = 1
|
||||
|
||||
// Get country code from the phone number
|
||||
val phoneNumber = threePid.msisdn
|
||||
|
||||
val parsedNumber = PhoneNumberUtil.getInstance().parse(phoneNumber, null)
|
||||
val countryCode = parsedNumber.countryCode
|
||||
|
||||
val result = executeRequest<AddMsisdnResponse>(eventBus) {
|
||||
val body = AddMsisdnBody(
|
||||
clientSecret = clientSecret,
|
||||
country = countryCode.asString(), // TODO Convert to String,
|
||||
phoneNumber = parsedNumber.nationalNumber.toString(),
|
||||
sendAttempt = sendAttempt
|
||||
)
|
||||
apiCall = profileAPI.addMsisdn(body)
|
||||
}
|
||||
|
||||
// Store as a pending three pid
|
||||
monarchy.awaitTransaction { realm ->
|
||||
PendingThreePid(
|
||||
threePid = threePid,
|
||||
clientSecret = clientSecret,
|
||||
sendAttempt = sendAttempt,
|
||||
sid = result.sid,
|
||||
submitUrl = result.submitUrl
|
||||
)
|
||||
.let { pendingThreePidMapper.map(it) }
|
||||
.let { realm.copyToRealm(it) }
|
||||
}
|
||||
}
|
||||
|
||||
private fun Int.asString(): String {
|
||||
// TODO
|
||||
return ""
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -22,6 +22,9 @@ internal data class PendingThreePid(
|
||||
val threePid: ThreePid,
|
||||
val clientSecret: String,
|
||||
val sendAttempt: Int,
|
||||
val sid: String
|
||||
// For Msisdn and Email
|
||||
val sid: String,
|
||||
// For Msisdn only
|
||||
val submitUrl: String?
|
||||
)
|
||||
|
||||
|
@ -29,7 +29,8 @@ internal class PendingThreePidMapper @Inject constructor() {
|
||||
?: error("Invalid data"),
|
||||
clientSecret = entity.clientSecret,
|
||||
sendAttempt = entity.sendAttempt,
|
||||
sid = entity.sid
|
||||
sid = entity.sid,
|
||||
submitUrl = entity.submitUrl
|
||||
)
|
||||
}
|
||||
|
||||
@ -39,7 +40,8 @@ internal class PendingThreePidMapper @Inject constructor() {
|
||||
msisdn = domain.threePid.takeIf { it is ThreePid.Msisdn }?.value,
|
||||
clientSecret = domain.clientSecret,
|
||||
sendAttempt = domain.sendAttempt,
|
||||
sid = domain.sid
|
||||
sid = domain.sid,
|
||||
submitUrl = domain.submitUrl
|
||||
)
|
||||
}
|
||||
}
|
||||
|
@ -75,7 +75,13 @@ internal interface ProfileAPI {
|
||||
* Ref: https://matrix.org/docs/spec/client_server/r0.6.1#post-matrix-client-r0-account-3pid-email-requesttoken
|
||||
*/
|
||||
@POST(NetworkConstants.URI_API_PREFIX_PATH_R0 + "account/3pid/email/requestToken")
|
||||
fun addEmail(@Body body: AddEmailBody): Call<AddThreePidResponse>
|
||||
fun addEmail(@Body body: AddEmailBody): Call<AddEmailResponse>
|
||||
|
||||
/**
|
||||
* Ref: https://matrix.org/docs/spec/client_server/r0.6.1#post-matrix-client-r0-account-3pid-msisdn-requesttoken
|
||||
*/
|
||||
@POST(NetworkConstants.URI_API_PREFIX_PATH_R0 + "account/3pid/msisdn/requestToken")
|
||||
fun addMsisdn(@Body body: AddMsisdnBody): Call<AddMsisdnResponse>
|
||||
|
||||
/**
|
||||
* Ref: https://matrix.org/docs/spec/client_server/r0.6.1#post-matrix-client-r0-account-3pid-add
|
||||
|
@ -30,6 +30,7 @@ import im.vector.app.core.extensions.configureWith
|
||||
import im.vector.app.core.extensions.exhaustive
|
||||
import im.vector.app.core.extensions.hideKeyboard
|
||||
import im.vector.app.core.extensions.isEmail
|
||||
import im.vector.app.core.extensions.isMsisdn
|
||||
import im.vector.app.core.platform.OnBackPressed
|
||||
import im.vector.app.core.platform.VectorBaseActivity
|
||||
import im.vector.app.core.platform.VectorBaseFragment
|
||||
@ -123,6 +124,11 @@ class ThreePidsSettingsFragment @Inject constructor(
|
||||
return
|
||||
}
|
||||
|
||||
if (!msisdn.isMsisdn()) {
|
||||
viewModel.handle(ThreePidsSettingsAction.ChangeState(ThreePidsSettingsState.AddingPhoneNumber(getString(R.string.login_msisdn_error_other))))
|
||||
return
|
||||
}
|
||||
|
||||
viewModel.handle(ThreePidsSettingsAction.AddThreePid(ThreePid.Msisdn(safeMsisdn)))
|
||||
}
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user