Unverified Commit f72f7a5f authored by Valere's avatar Valere Committed by GitHub

Merge pull request #3365 from vector-im/feature/3pid_interactive_auth

Prompt for password to add 3pid
parents c88142fb aa4d03d4
......@@ -11,7 +11,7 @@ Improvementss 🙌:
-
Other changes:
-
- Add User-Interactive Auth to /account/3pid/add (#3333)
Bugfix 🐛:
- Crash / potential NPE after logout (#3367)
......
/*
* Copyright 2019 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.activity
import android.content.Context
import android.view.LayoutInflater
import android.view.ViewGroup
import android.widget.ImageView
import androidx.appcompat.app.AlertDialog
import com.google.android.material.textfield.TextInputEditText
import com.google.android.material.textfield.TextInputLayout
import im.vector.R
import im.vector.extensions.showPassword
object DialogUtils {
fun promptPassword(context: Context, errorText: String? = null, defaultPwd: String? = null,
done: (String) -> Unit,
cancel: (() -> Unit)? = null) {
val view: ViewGroup = LayoutInflater.from(context).inflate(R.layout.dialog_confirm_password, null) as ViewGroup
val showPassword: ImageView = view.findViewById(R.id.confirm_password_show_passwords)
val passwordTil: TextInputLayout = view.findViewById(R.id.confirm_password_til)
val passwordText: TextInputEditText = view.findViewById(R.id.password_label)
passwordText.setText(defaultPwd)
var passwordShown = false
showPassword.setOnClickListener {
passwordShown = !passwordShown
passwordText.showPassword(passwordShown)
showPassword.setImageResource(if (passwordShown) R.drawable.ic_eye_closed_black else R.drawable.ic_eye_black)
}
passwordTil.error = errorText
AlertDialog.Builder(context)
.setView(view)
.setPositiveButton(R.string._continue) { tv, _ ->
done(passwordText.text.toString())
}
.apply {
if (cancel != null) {
setNegativeButton(R.string.cancel) { _, _ ->
cancel()
}
}
}
.show()
}
}
\ No newline at end of file
......@@ -267,7 +267,7 @@ public class PhoneNumberAdditionActivity extends VectorAppCompatActivity impleme
@Override
public void onSuccess(ThreePid pid) {
hideWaitingView();
Intent intent = PhoneNumberVerificationActivity.getIntent(PhoneNumberAdditionActivity.this,
Intent intent = PhoneNumberVerificationActivity.Companion.getIntent(PhoneNumberAdditionActivity.this,
mSession.getCredentials().userId, pid);
startActivityForResult(intent, REQUEST_VERIFICATION);
}
......
/*
* Copyright 2017 Vector Creations Ltd
* Copyright 2018 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.activity;
import android.content.Context;
import android.content.Intent;
import android.text.Editable;
import android.text.TextUtils;
import android.text.TextWatcher;
import android.view.KeyEvent;
import android.view.MenuItem;
import android.view.inputmethod.EditorInfo;
import android.widget.TextView;
import android.widget.Toast;
import com.google.android.material.textfield.TextInputEditText;
import com.google.android.material.textfield.TextInputLayout;
import org.matrix.androidsdk.MXSession;
import org.matrix.androidsdk.core.Log;
import org.matrix.androidsdk.core.callback.ApiCallback;
import org.matrix.androidsdk.core.model.MatrixError;
import org.matrix.androidsdk.rest.model.SuccessResult;
import org.matrix.androidsdk.rest.model.pid.ThreePid;
import im.vector.Matrix;
import im.vector.R;
public class PhoneNumberVerificationActivity extends VectorAppCompatActivity implements TextView.OnEditorActionListener, TextWatcher {
private static final String LOG_TAG = PhoneNumberVerificationActivity.class.getSimpleName();
private static final String EXTRA_MATRIX_ID = "EXTRA_MATRIX_ID";
private static final String EXTRA_PID = "EXTRA_PID";
private TextInputEditText mPhoneNumberCode;
private TextInputLayout mPhoneNumberCodeLayout;
private MXSession mSession;
private ThreePid mThreePid;
// True when a phone number token is submitted
// Used to prevent user to submit several times in a row
private boolean mIsSubmittingToken;
/*
* *********************************************************************************************
* Static methods
* *********************************************************************************************
*/
public static Intent getIntent(final Context context, final String sessionId, final ThreePid pid) {
final Intent intent = new Intent(context, PhoneNumberVerificationActivity.class);
intent.putExtra(EXTRA_MATRIX_ID, sessionId);
intent.putExtra(EXTRA_PID, pid);
return intent;
}
/*
* *********************************************************************************************
* Activity lifecycle
* *********************************************************************************************
*/
@Override
public int getLayoutRes() {
return R.layout.activity_phone_number_verification;
}
@Override
public int getTitleRes() {
return R.string.settings_phone_number_verification;
}
@Override
public void initUiAndData() {
configureToolbar();
mPhoneNumberCode = findViewById(R.id.phone_number_code_value);
mPhoneNumberCodeLayout = findViewById(R.id.phone_number_code);
setWaitingView(findViewById(R.id.loading_view));
final Intent intent = getIntent();
mSession = Matrix.getInstance(this).getSession(intent.getStringExtra(EXTRA_MATRIX_ID));
if ((null == mSession) || !mSession.isAlive()) {
finish();
return;
}
mThreePid = intent.getParcelableExtra(EXTRA_PID);
mPhoneNumberCode.addTextChangedListener(this);
mPhoneNumberCode.setOnEditorActionListener(this);
}
@Override
protected void onResume() {
super.onResume();
mIsSubmittingToken = false;
}
@Override
public int getMenuRes() {
return R.menu.menu_phone_number_verification;
}
@Override
public boolean onOptionsItemSelected(MenuItem item) {
switch (item.getItemId()) {
case R.id.action_verify_phone_number:
submitCode();
return true;
default:
return super.onOptionsItemSelected(item);
}
}
/*
* *********************************************************************************************
* Utils
* *********************************************************************************************
*/
/**
* Submit code (token) to attach phone number to account
*/
private void submitCode() {
if (!mIsSubmittingToken) {
mIsSubmittingToken = true;
if (TextUtils.isEmpty(mPhoneNumberCode.getText())) {
mPhoneNumberCodeLayout.setErrorEnabled(true);
mPhoneNumberCodeLayout.setError(getString(R.string.settings_phone_number_verification_error_empty_code));
} else {
showWaitingView();
mSession.getIdentityServerManager().submitValidationToken(mThreePid, mPhoneNumberCode.getText().toString(),
new ApiCallback<SuccessResult>() {
@Override
public void onSuccess(SuccessResult result) {
if (result.success) {
// the validation of mail ownership succeed, just resume the registration flow
// next step: just register
Log.e(LOG_TAG, "## submitPhoneNumberValidationToken(): onSuccess() - registerAfterEmailValidations() started");
registerAfterPhoneNumberValidation(mThreePid);
} else {
Log.e(LOG_TAG, "## submitPhoneNumberValidationToken(): onSuccess() - failed (success=false)");
onSubmitCodeError(getString(R.string.settings_phone_number_verification_error));
}
}
@Override
public void onNetworkError(Exception e) {
onSubmitCodeError(e.getLocalizedMessage());
}
@Override
public void onMatrixError(MatrixError e) {
onSubmitCodeError(e.getLocalizedMessage());
}
@Override
public void onUnexpectedError(Exception e) {
onSubmitCodeError(e.getLocalizedMessage());
}
});
}
}
}
private void registerAfterPhoneNumberValidation(final ThreePid pid) {
mSession.getIdentityServerManager().finalize3pidAddSession(pid, null, new ApiCallback<Void>() {
@Override
public void onSuccess(Void info) {
Intent intent = new Intent();
setResult(RESULT_OK, intent);
finish();
}
@Override
public void onNetworkError(Exception e) {
onSubmitCodeError(e.getLocalizedMessage());
}
@Override
public void onMatrixError(MatrixError e) {
onSubmitCodeError(e.getLocalizedMessage());
}
@Override
public void onUnexpectedError(Exception e) {
onSubmitCodeError(e.getLocalizedMessage());
}
});
}
private void onSubmitCodeError(final String errorMessage) {
mIsSubmittingToken = false;
hideWaitingView();
Toast.makeText(this, errorMessage, Toast.LENGTH_SHORT).show();
}
/*
* *********************************************************************************************
* Listeners
* *********************************************************************************************
*/
@Override
public boolean onEditorAction(TextView v, int actionId, KeyEvent event) {
if (actionId == EditorInfo.IME_ACTION_DONE && !isFinishing()) {
submitCode();
return true;
}
return false;
}
@Override
public void beforeTextChanged(CharSequence s, int start, int count, int after) {
}
@Override
public void onTextChanged(CharSequence s, int start, int before, int count) {
}
@Override
public void afterTextChanged(Editable s) {
if (mPhoneNumberCodeLayout.getError() != null) {
mPhoneNumberCodeLayout.setError(null);
mPhoneNumberCodeLayout.setErrorEnabled(false);
}
}
}
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical"
android:paddingStart="?dialogPreferredPadding"
android:paddingLeft="?dialogPreferredPadding"
android:paddingTop="12dp"
android:paddingEnd="?dialogPreferredPadding"
android:paddingRight="?dialogPreferredPadding">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="horizontal">
<TextView
style="@style/Base.DialogWindowTitle.AppCompat"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginTop="8dp"
android:layout_weight="1"
android:text="@string/settings_add_3pid_confirm_password_title" />
<ImageView
android:id="@+id/confirm_password_show_passwords"
android:layout_width="@dimen/layout_touch_size"
android:layout_height="@dimen/layout_touch_size"
android:background="?attr/selectableItemBackground"
android:scaleType="center"
android:src="@drawable/ic_eye_black"
android:tint="?attr/colorAccent" />
</LinearLayout>
<com.google.android.material.textfield.TextInputLayout
android:id="@+id/confirm_password_til"
android:layout_width="match_parent"
android:layout_height="wrap_content"
app:errorEnabled="true">
<com.google.android.material.textfield.TextInputEditText
android:id="@+id/password_label"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:inputType="textPassword" />
</com.google.android.material.textfield.TextInputLayout>
</LinearLayout>
\ No newline at end of file
......@@ -630,6 +630,9 @@
<string name="settings_add_phone_number">Add phone number</string>
<string name="settings_app_info_link_title">Application info</string>
<string name="settings_app_info_link_summary">Show the application info in the system settings.</string>
<string name="settings_add_3pid_confirm_password_title">Confirm your password</string>
<string name="settings_add_3pid_flow_not_supported">You can\'t do this from Riot mobile</string>
<string name="settings_add_3pid_authentication_needed">Authentication is required</string>
<string name="settings_notification_advanced">Advanced Notification Settings</string>
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment