diff --git a/vector/src/agent/AndroidManifest.xml b/vector/src/agent/AndroidManifest.xml index 60034f9eec0..da39331dc6c 100755 --- a/vector/src/agent/AndroidManifest.xml +++ b/vector/src/agent/AndroidManifest.xml @@ -13,8 +13,12 @@ - - + + + + + + @@ -25,8 +29,12 @@ - - + + + + + + @@ -37,8 +45,12 @@ - - + + + + + + @@ -49,8 +61,12 @@ - - + + + + + + @@ -61,8 +77,12 @@ - - + + + + + + @@ -73,8 +93,12 @@ - - + + + + + + @@ -85,8 +109,12 @@ - - + + + + + + @@ -97,8 +125,12 @@ - - + + + + + + @@ -109,8 +141,12 @@ - - + + + + + + @@ -121,8 +157,12 @@ - - + + + + + + @@ -133,8 +173,12 @@ - - + + + + + + @@ -145,8 +189,12 @@ - - + + + + + + @@ -157,8 +205,12 @@ - - + + + + + + @@ -169,8 +221,12 @@ - - + + + + + + @@ -181,8 +237,12 @@ - - + + + + + + @@ -193,8 +253,28 @@ - - + + + + + + + + + + + + + + + + + + + + + + diff --git a/vector/src/main/java/fr/gouv/tchap/activity/TchapLoginActivity.java b/vector/src/main/java/fr/gouv/tchap/activity/TchapLoginActivity.java index a6fc7b5107f..fb47c7c1031 100644 --- a/vector/src/main/java/fr/gouv/tchap/activity/TchapLoginActivity.java +++ b/vector/src/main/java/fr/gouv/tchap/activity/TchapLoginActivity.java @@ -310,6 +310,9 @@ protected void onNewIntent(Intent aIntent) { Log.d(LOG_TAG, "## onNewIntent(): Unexpected value - aIntent=null "); } else if (null == (receivedBundle = aIntent.getExtras())) { Log.d(LOG_TAG, "## onNewIntent(): Unexpected value - extras are missing"); + } else if (receivedBundle.containsKey(VectorUniversalLinkActivity.EXTRA_VALIDATED_EMAIL_PARAMS)) { + Log.d(LOG_TAG, "## onNewIntent() Login activity resumed on a successful email verification"); + resumeOnValidatedEmail(receivedBundle); } else if (receivedBundle.containsKey(VectorUniversalLinkActivity.EXTRA_EMAIL_VALIDATION_PARAMS)) { Log.d(LOG_TAG, "## onNewIntent() Login activity started by email verification for registration"); @@ -439,6 +442,9 @@ public void onClick(View view) { if (receivedBundle.containsKey(VectorUniversalLinkReceiver.EXTRA_UNIVERSAL_LINK_URI)) { mUniversalLinkUri = receivedBundle.getParcelable(VectorUniversalLinkReceiver.EXTRA_UNIVERSAL_LINK_URI); Log.d(LOG_TAG, "## onCreate() Login activity started by universal link"); + } else if (receivedBundle.containsKey(VectorUniversalLinkActivity.EXTRA_VALIDATED_EMAIL_PARAMS)) { + Log.d(LOG_TAG, "## onCreate() Login activity resumed on a successful email verification"); + resumeOnValidatedEmail(receivedBundle); } else if (receivedBundle.containsKey(VectorUniversalLinkActivity.EXTRA_EMAIL_VALIDATION_PARAMS)) { Log.d(LOG_TAG, "## onCreate() Login activity started by email verification for registration"); if (processEmailValidationExtras(receivedBundle)) { @@ -968,6 +974,84 @@ private void onFailureDuringAuthRequest(MatrixError matrixError) { } } + /** + * Parse the given bundle to check if it contains the parameters to pursue the operation for + * which the email has been verified. + * If yes, it initializes the TchapLoginActivity to finalize a registration or a reset password + * This is mainly used when the TchapLoginActivity is triggered from the {@link VectorUniversalLinkActivity}. + * + * @param bundle bundle to be parsed + */ + private void resumeOnValidatedEmail(Bundle bundle) { + HashMap extraParams = (HashMap) bundle.getSerializable(VectorUniversalLinkActivity.EXTRA_VALIDATED_EMAIL_PARAMS); + + if (null != extraParams) { + Log.d(LOG_TAG, "## resumeOnValidatedEmail(): IN"); + Matrix.getInstance(this).clearSessions(this, true, null); + + // display waiting UI.. + enableLoadingScreen(true); + // display wait screen with no text (same as iOS) for now.. + hideMainLayoutAndToast(""); + + String clientSecret = extraParams.get(VectorUniversalLinkActivity.KEY_MAIL_VALIDATION_CLIENT_SECRET); + String identityServerSessId = extraParams.get(VectorUniversalLinkActivity.KEY_MAIL_VALIDATION_IDENTITY_SERVER_SESSION_ID); + String sessionId = extraParams.get(VectorUniversalLinkActivity.KEY_MAIL_VALIDATION_SESSION_ID); + String homeServer = extraParams.get(VectorUniversalLinkActivity.KEY_MAIL_VALIDATION_HOME_SERVER_URL); + String identityServer = extraParams.get(VectorUniversalLinkActivity.KEY_MAIL_VALIDATION_IDENTITY_SERVER_URL); + + // When the user tries to update his/her password after forgetting it (tap on the dedicated link) + // The HS / IS urls are not provided in the email link. + // This link should be only opened by the webclient (known issue server side) + // Use the current configuration by default (it might not work on some account if the user uses another HS) + if (null == homeServer) { + homeServer = getHomeServerUrl(); + } + if (null == identityServer) { + identityServer = getIdentityServerUrl(); + } + + // test if the home server urls are valid + try { + Uri.parse(homeServer); + Uri.parse(identityServer); + } catch (Exception e) { + // Stop and display a toast to notify email has been validated + enableLoadingScreen(false); + Toast.makeText(TchapLoginActivity.this, getString(R.string.tchap_email_validation_succeeded), Toast.LENGTH_LONG).show(); + return; + } + + final HomeServerConnectionConfig homeServerConfig + = mServerConfig + = HomeServerConnectionConfigFactoryKt.createHomeServerConnectionConfig(homeServer, identityServer); + + // if sessionId is null, it means that this request has been triggered by clicking on a "forgot password" link + if (null == sessionId) { + Log.d(TchapLoginActivity.LOG_TAG, "## resumeOnValidatedEmail(): the password update is in progress"); + + mMode = MODE_FORGOT_PASSWORD_WAITING_VALIDATION; + + mForgotPid = new ThreePidCredentials(); + mForgotPid.clientSecret = clientSecret; + mForgotPid.idServer = homeServerConfig.getIdentityServerUri().getHost(); + mForgotPid.sid = identityServerSessId; + + mIsPasswordResetted = false; + onForgotOnEmailValidated(homeServerConfig); + } else { + // the validation of mail ownership succeed, just resume the registration flow + // next step: just register + Log.d(TchapLoginActivity.LOG_TAG, "## resumeOnValidatedEmail(): registerAfterEmailValidations() started"); + mRegistrationManager.setHsConfig(homeServerConfig); + mMode = MODE_ACCOUNT_CREATION; + mRegistrationManager.registerAfterEmailValidation(TchapLoginActivity.this, clientSecret, identityServerSessId, identityServer, sessionId, TchapLoginActivity.this); + } + } else { + Log.d(LOG_TAG, "## resumeOnValidatedEmail(): skipped"); + } + } + /** * Parse the given bundle to check if it contains the email verification extra. * If yes, it initializes the TchapLoginActivity to start in registration mode to finalize a registration @@ -1137,8 +1221,6 @@ public void onUnexpectedError(Exception e) { * @param registrationFlowResponse the response */ private void onRegistrationFlow(RegistrationFlowResponse registrationFlowResponse) { - enableLoadingScreen(false); - mRegistrationResponse = registrationFlowResponse; } diff --git a/vector/src/main/java/im/vector/LoginHandler.java b/vector/src/main/java/im/vector/LoginHandler.java index 619e8e32752..dfb09dfde8c 100644 --- a/vector/src/main/java/im/vector/LoginHandler.java +++ b/vector/src/main/java/im/vector/LoginHandler.java @@ -217,7 +217,8 @@ public void submitEmailTokenValidation(final Context aCtx, final ApiCallback aRespCallback) { ThirdPidRestClient restClient = new ThirdPidRestClient(aHomeServerConfig); - restClient.submitValidationToken( + // Tchap: submitValidationToken returns an error 403 on Tchap server - We force the legacy version for the moment + restClient.submitValidationTokenLegacy( ThreePid.MEDIUM_EMAIL, aToken, aClientSecret, diff --git a/vector/src/main/java/im/vector/activity/VectorUniversalLinkActivity.java b/vector/src/main/java/im/vector/activity/VectorUniversalLinkActivity.java index 674120d188e..6d4485bf3c3 100644 --- a/vector/src/main/java/im/vector/activity/VectorUniversalLinkActivity.java +++ b/vector/src/main/java/im/vector/activity/VectorUniversalLinkActivity.java @@ -27,6 +27,8 @@ import androidx.appcompat.app.AlertDialog; import androidx.localbroadcastmanager.content.LocalBroadcastManager; + +import android.os.AsyncTask; import android.text.TextUtils; import android.widget.Toast; @@ -54,6 +56,10 @@ import im.vector.R; import im.vector.receiver.LoginConfig; import im.vector.receiver.VectorUniversalLinkReceiver; +import okhttp3.HttpUrl; +import okhttp3.OkHttpClient; +import okhttp3.Request; +import okhttp3.Response; /** * Dummy activity used to dispatch the vector URL links. @@ -65,10 +71,18 @@ public class VectorUniversalLinkActivity extends VectorAppCompatActivity { private final VectorUniversalLinkReceiver mUniversalLinkReceiver = new VectorUniversalLinkReceiver(); //private static final String SUPPORTED_PATH_CONFIG = "/config/config"; + + private static final String MATRIX_PATH_PREFIX = "/_matrix/"; + // Email validation query + private static final String REGISTRATION_EMAIL_VALIDATION_PATH_SUFFIX = "/registration/email/submit_token"; + private static final String PASSWORD_RESET_EMAIL_VALIDATION_PATH_SUFFIX = "/password_reset/email/submit_token"; // Account validity query private static final String ACCOUNT_VALIDITY_RENEW_PATH_SUFFIX = "/account_validity/renew"; private static final String ACCOUNT_VALIDITY_RENEW_TOKEN = "token"; + // Intent Extras + public static final String EXTRA_VALIDATED_EMAIL_PARAMS = "EXTRA_VALIDATED_EMAIL_PARAMS"; + @Override public int getLayoutRes() { // display a spinner while binding the email @@ -91,46 +105,61 @@ public void initUiAndData() { Uri intentUri = getIntent().getData(); String dataPath = intentUri.getPath(); - if (dataPath.endsWith(EMAIL_VALIDATION_PATH_SUFFIX)) { - // We consider here an email validation - final Map mailRegParams = parseMailRegistrationLink(intentUri); - - // Assume it is a new account creation when there is a next link, or when no session is already available. - MXSession session = Matrix.getInstance(this).getDefaultSession(); - - if (mailRegParams.containsKey(KEY_MAIL_VALIDATION_NEXT_LINK) || (null == session)) { - if (session == null) { - // build Login intent - Intent intent = new Intent(VectorUniversalLinkActivity.this, TchapLoginActivity.class); - intent.putExtra(EXTRA_EMAIL_VALIDATION_PARAMS, (HashMap) mailRegParams); - intent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP | Intent.FLAG_ACTIVITY_SINGLE_TOP | Intent.FLAG_ACTIVITY_NEW_TASK); - startActivity(intent); - - finish(); + if (dataPath.startsWith(MATRIX_PATH_PREFIX)) { + if (dataPath.endsWith(REGISTRATION_EMAIL_VALIDATION_PATH_SUFFIX)) { + MXSession session = Matrix.getInstance(this).getDefaultSession(); + if (session != null) { + Log.d(LOG_TAG, "## Prompt the user to logout before finalizing an account creation based on an email validation"); + promptToLogoutBeforeHandlingRegistrationLink(intentUri.toString()); } else { - Log.d(LOG_TAG, "## logout the current sessions, before finalizing an account creation based on an email validation"); - - // This logout is asynchronous, pursue the action in the callback to have the LoginActivity in a "no credentials state". - CommonActivityUtils.logout(VectorUniversalLinkActivity.this, - Matrix.getMXSessions(VectorUniversalLinkActivity.this), - true, - new SimpleApiCallback() { - @Override - public void onSuccess(Void info) { - Log.d(LOG_TAG, "## logout succeeded"); - - // build Login intent - Intent intent = new Intent(VectorUniversalLinkActivity.this, TchapLoginActivity.class); - intent.putExtra(EXTRA_EMAIL_VALIDATION_PARAMS, (HashMap) mailRegParams); - intent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP | Intent.FLAG_ACTIVITY_SINGLE_TOP | Intent.FLAG_ACTIVITY_NEW_TASK); - startActivity(intent); - - finish(); - } - }); + new EmailValidationTask().execute(intentUri.toString(), true); + } + } else if (dataPath.endsWith(PASSWORD_RESET_EMAIL_VALIDATION_PATH_SUFFIX)) { + MXSession session = Matrix.getInstance(this).getDefaultSession(); + new EmailValidationTask().execute(intentUri.toString(), session == null); + } else if (dataPath.endsWith(ACCOUNT_VALIDITY_RENEW_PATH_SUFFIX)) { + renewAccountValidity(intentUri); + } else if (dataPath.endsWith(LEGACY_EMAIL_VALIDATION_PATH_SUFFIX)) { + // We consider here an email validation + final Map mailRegParams = parseMailRegistrationLink(intentUri); + + // Assume it is a new account creation when there is a next link, or when no session is already available. + MXSession session = Matrix.getInstance(this).getDefaultSession(); + + if (mailRegParams.containsKey(KEY_MAIL_VALIDATION_NEXT_LINK) || (null == session)) { + if (session == null) { + // build Login intent + Intent intent = new Intent(VectorUniversalLinkActivity.this, TchapLoginActivity.class); + intent.putExtra(EXTRA_EMAIL_VALIDATION_PARAMS, (HashMap) mailRegParams); + intent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP | Intent.FLAG_ACTIVITY_SINGLE_TOP | Intent.FLAG_ACTIVITY_NEW_TASK); + startActivity(intent); + + finish(); + } else { + Log.d(LOG_TAG, "## logout the current sessions, before finalizing an account creation based on an email validation"); + + // This logout is asynchronous, pursue the action in the callback to have the LoginActivity in a "no credentials state". + CommonActivityUtils.logout(VectorUniversalLinkActivity.this, + Matrix.getMXSessions(VectorUniversalLinkActivity.this), + true, + new SimpleApiCallback() { + @Override + public void onSuccess(Void info) { + Log.d(LOG_TAG, "## logout succeeded"); + + // build Login intent + Intent intent = new Intent(VectorUniversalLinkActivity.this, TchapLoginActivity.class); + intent.putExtra(EXTRA_EMAIL_VALIDATION_PARAMS, (HashMap) mailRegParams); + intent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP | Intent.FLAG_ACTIVITY_SINGLE_TOP | Intent.FLAG_ACTIVITY_NEW_TASK); + startActivity(intent); + + finish(); + } + }); + } + } else { + emailBinding(intentUri, mailRegParams); } - } else { - emailBinding(intentUri, mailRegParams); } // } else if (SUPPORTED_PATH_CONFIG.equals(dataPath)) { // MXSession mSession = Matrix.getInstance(this).getDefaultSession(); @@ -143,8 +172,6 @@ public void onSuccess(Void info) { // displayAlreadyLoginPopup(); // return; // } - } else if (dataPath.endsWith(ACCOUNT_VALIDITY_RENEW_PATH_SUFFIX)) { - renewAccountValidity(intentUri); } else { intentAction = VectorUniversalLinkReceiver.BROADCAST_ACTION_UNIVERSAL_LINK; } @@ -170,6 +197,139 @@ protected void onPause() { LocalBroadcastManager.getInstance(this).unregisterReceiver(mUniversalLinkReceiver); } + /** + * Prompt to disconnect when clicking on registration email validation link + */ + private void promptToLogoutBeforeHandlingRegistrationLink(String emailValidationLink) { + new AlertDialog.Builder(this) + .setTitle(R.string.dialog_title_warning) + .setMessage(R.string.tchap_register_user_already_logged_in_prompt) + .setCancelable(false) + .setPositiveButton(R.string.logout, new DialogInterface.OnClickListener() { + @Override + public void onClick(DialogInterface dialog, int which) { + CommonActivityUtils.logout(VectorUniversalLinkActivity.this, + Matrix.getMXSessions(VectorUniversalLinkActivity.this), + true, + new SimpleApiCallback() { + @Override + public void onSuccess(Void info) { + Log.d(LOG_TAG, "## promptToLogoutBeforeHandlingRegistrationLink(): logout succeeded"); + new EmailValidationTask().execute(emailValidationLink, true); + } + }); + } + }) + .setNegativeButton(R.string.cancel, new DialogInterface.OnClickListener() { + @Override + public void onClick(DialogInterface dialog, int which) { + finish(); + } + }) + .show(); + } + + private class EmailValidationTask extends AsyncTask { + @Override + protected Void doInBackground(Object... params) { + boolean isSuccess = false; + String validationLink = (String)params[0]; + Boolean goToLoginActivityOnSuccess = (Boolean)params[1]; + if (null != validationLink) { + Request request = new Request.Builder() + .url(validationLink) + .build(); + + int responseCode = HttpURLConnection.HTTP_INTERNAL_ERROR; + Response response = null; + + // Trigger the request + try { + response = new OkHttpClient().newCall(request).execute(); + responseCode = response.code(); + } catch (Exception e) { + Log.e(LOG_TAG, "response " + e.getMessage(), e); + } + + if (responseCode == HttpURLConnection.HTTP_OK) { + isSuccess = true; + + if (goToLoginActivityOnSuccess) { + // Extract the parameters from the request url + // In case of registration, the url has been replaced with the next link + // provided during the request of the token (url redirection). + HttpUrl httpURL = response.request().url(); + final Map linkParams = parseEmailValidationLink(httpURL); + runOnUiThread(new Runnable() { + @Override + public void run() { + if (linkParams != null) { + Intent intent = new Intent(VectorUniversalLinkActivity.this, TchapLoginActivity.class); + intent.putExtra(EXTRA_VALIDATED_EMAIL_PARAMS, (HashMap) linkParams); + intent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP | Intent.FLAG_ACTIVITY_SINGLE_TOP | Intent.FLAG_ACTIVITY_NEW_TASK); + startActivity(intent); + } else { + Toast.makeText(getApplicationContext(), getString(R.string.tchap_email_validation_succeeded), Toast.LENGTH_LONG).show(); + } + finish(); + } + }); + } else { + runOnUiThread(new Runnable() { + @Override + public void run() { + Toast.makeText(getApplicationContext(), getString(R.string.tchap_email_validation_succeeded), Toast.LENGTH_LONG).show(); + finish(); + } + }); + } + } + } + + if (!isSuccess) { + runOnUiThread(new Runnable() { + @Override + public void run() { + Toast.makeText(getApplicationContext(), getString(R.string.tchap_email_validation_failed), Toast.LENGTH_LONG).show(); + finish(); + } + }); + } + return null; + } + } + + private Map parseEmailValidationLink(HttpUrl url) { + Map mapParams = new HashMap<>(); + try { + // remove potential "#" to allow query params parsing + Uri uri = Uri.parse(url.toString().replace("#/", "")); + String host = uri.getHost(); + Log.i(LOG_TAG, "## parseEmailValidationLink(): host=" + host); + + String clientSecret = uri.getQueryParameter(KEY_MAIL_VALIDATION_CLIENT_SECRET); + mapParams.put(KEY_MAIL_VALIDATION_CLIENT_SECRET, clientSecret); + String sid = uri.getQueryParameter(KEY_MAIL_VALIDATION_IDENTITY_SERVER_SESSION_ID); + mapParams.put(KEY_MAIL_VALIDATION_IDENTITY_SERVER_SESSION_ID, sid); + String sessionId = uri.getQueryParameter(KEY_MAIL_VALIDATION_SESSION_ID); + mapParams.put(KEY_MAIL_VALIDATION_SESSION_ID, sessionId); + + String hsURL = uri.getQueryParameter(KEY_MAIL_VALIDATION_HOME_SERVER_URL); + mapParams.put(KEY_MAIL_VALIDATION_HOME_SERVER_URL, hsURL); + String idServerUrl = uri.getQueryParameter(KEY_MAIL_VALIDATION_IDENTITY_SERVER_URL); + if (idServerUrl != null) { + mapParams.put(KEY_MAIL_VALIDATION_IDENTITY_SERVER_URL, idServerUrl); + } else { + mapParams.put(KEY_MAIL_VALIDATION_IDENTITY_SERVER_URL, hsURL); + } + } catch (Exception e) { + mapParams = null; + Log.e(LOG_TAG, "## parseEmailValidationLink(): Exception - Msg=" + e.getLocalizedMessage(), e); + } + + return mapParams; + } + // /** // * Start the login screen with identity server and home server pre-filled // */ @@ -380,14 +540,16 @@ private void bringAppToForeground() { } /* ========================================================================================== - * Registration link + * Registration link - Deprecated (the handling of this email validation via the id server + * must be removed when all the servers will be updated on Prod. We should only keep the email + * binding, but this option is not allowed on Tchap for the moment) * ========================================================================================== */ // Intent Extras public static final String EXTRA_EMAIL_VALIDATION_PARAMS = "EXTRA_EMAIL_VALIDATION_PARAMS"; // The suffix of the email validation path - private static final String EMAIL_VALIDATION_PATH_SUFFIX = "/validate/email/submitToken"; + private static final String LEGACY_EMAIL_VALIDATION_PATH_SUFFIX = "/validate/email/submitToken"; // mail validation url query parameters // Examples: diff --git a/vector/src/main/java/im/vector/util/BugReporter.java b/vector/src/main/java/im/vector/util/BugReporter.java index 65e95850cc1..fa717d7412f 100755 --- a/vector/src/main/java/im/vector/util/BugReporter.java +++ b/vector/src/main/java/im/vector/util/BugReporter.java @@ -286,7 +286,7 @@ protected String doInBackground(Void... voids) { } // tag Tchap bug reports to better triage them - builder.addFormDataPart("label", "dinsic"); + builder.addFormDataPart("label", "DINUM"); BugReporterMultipartBody requestBody = builder.build(); diff --git a/vector/src/main/res/values-fr/strings.xml b/vector/src/main/res/values-fr/strings.xml index 93afb1abb08..d5f63673aea 100644 --- a/vector/src/main/res/values-fr/strings.xml +++ b/vector/src/main/res/values-fr/strings.xml @@ -914,6 +914,9 @@ Appareils inconnus : Cette adresse e-mail n’est pas autorisée Ce mot de passe est trop faible. Il doit contenir au moins 8 caractères, avec au moins un caractère de chaque type : majuscule, minuscule, chiffre, caractère spécial. Ce mot de passe a été trouvé dans un dictionnaire, il n’est pas autorisé + Il semblerait que vous essayez de vous connecter avec un autre compte. Voulez-vous vous déconnecter \? + Votre email a été validé, vous pouvez poursuivre l’opération qui attendait cette validation. + La validation de l’email a échouée. Le lien a expiré, ou il n’est pas valide. Votre nouveau mot de passe doit contenir au moins 8 caractères, avec au moins un caractère de chaque type : majuscule, minuscule, chiffre, caractère spécial. diff --git a/vector/src/main/res/values/strings.xml b/vector/src/main/res/values/strings.xml index 70f94eb5a70..70459d05e46 100755 --- a/vector/src/main/res/values/strings.xml +++ b/vector/src/main/res/values/strings.xml @@ -1341,6 +1341,9 @@ This email address is unauthorized This password is too weak. It must include a lower-case letter, an upper-case letter, a number and a symbol and be at a minimum 8 characters in length. This password was found in a dictionary, and is not acceptable + It looks like you’re trying to connect with another account. Do you want to sign out? + The email has been validated. You may pursue the related operation. + The email validation failed. The link has expired, or it is not valid. Your new password must include a lower-case letter, an upper-case letter, a number and a symbol and be at a minimum 8 characters in length. diff --git a/vector/src/preprod/AndroidManifest.xml b/vector/src/preprod/AndroidManifest.xml index af79c154b79..8ee30a52a47 100755 --- a/vector/src/preprod/AndroidManifest.xml +++ b/vector/src/preprod/AndroidManifest.xml @@ -13,8 +13,12 @@ - - + + + + + + @@ -25,8 +29,12 @@ - - + + + + + + diff --git a/vector/src/protecteed/AndroidManifest.xml b/vector/src/protecteed/AndroidManifest.xml index df8e1fcb435..b0eb3d4507d 100755 --- a/vector/src/protecteed/AndroidManifest.xml +++ b/vector/src/protecteed/AndroidManifest.xml @@ -13,8 +13,12 @@ - - + + + + + + @@ -25,8 +29,12 @@ - - + + + + + + @@ -37,8 +45,12 @@ - - + + + + + + @@ -49,8 +61,12 @@ - - + + + + + + @@ -61,8 +77,12 @@ - - + + + + + + @@ -73,8 +93,12 @@ - - + + + + + + @@ -85,8 +109,12 @@ - - + + + + + + @@ -97,8 +125,12 @@ - - + + + + + + @@ -109,8 +141,12 @@ - - + + + + + + @@ -121,8 +157,12 @@ - - + + + + + + @@ -133,8 +173,12 @@ - - + + + + + + @@ -145,8 +189,12 @@ - - + + + + + + @@ -157,8 +205,12 @@ - - + + + + + + @@ -169,8 +221,12 @@ - - + + + + + +