From cdf75be0ec07de230f4e0332bfca73f04d4fccbc Mon Sep 17 00:00:00 2001 From: Adam Brown Date: Fri, 19 Aug 2022 12:24:20 +0100 Subject: [PATCH 1/5] redirecting to the edit server screen when attempting to select the initial homeserver choice and it fails --- .../onboarding/OnboardingViewModel.kt | 10 +++-- ...FtueAuthCombinedServerSelectionFragment.kt | 2 +- .../onboarding/ftueauth/FtueAuthVariant.kt | 37 +++++++++++++++---- 3 files changed, 38 insertions(+), 11 deletions(-) diff --git a/vector/src/main/java/im/vector/app/features/onboarding/OnboardingViewModel.kt b/vector/src/main/java/im/vector/app/features/onboarding/OnboardingViewModel.kt index e60bedc612..987d3f38a2 100644 --- a/vector/src/main/java/im/vector/app/features/onboarding/OnboardingViewModel.kt +++ b/vector/src/main/java/im/vector/app/features/onboarding/OnboardingViewModel.kt @@ -701,9 +701,8 @@ class OnboardingViewModel @AssistedInject constructor( private fun onAuthenticationStartError(error: Throwable, trigger: OnboardingAction.HomeServerChange) { when { - error.isHomeserverUnavailable() && applicationContext.inferNoConnectivity(sdkIntProvider) -> _viewEvents.post( - OnboardingViewEvents.Failure(error) - ) + error.isHomeserverUnavailable() && applicationContext.inferNoConnectivity(sdkIntProvider) -> _viewEvents.post(OnboardingViewEvents.Failure(error)) + isUnableToSelectServer(error, trigger) -> handle(OnboardingAction.PostViewEvent(OnboardingViewEvents.EditServerSelection)) deeplinkUrlIsUnavailable(error, trigger) -> _viewEvents.post( OnboardingViewEvents.DeeplinkAuthenticationFailure( retryAction = (trigger as OnboardingAction.HomeServerChange.SelectHomeServer).resetToDefaultUrl() @@ -716,6 +715,9 @@ class OnboardingViewModel @AssistedInject constructor( } } + private fun isUnableToSelectServer(error: Throwable, trigger: OnboardingAction.HomeServerChange) = + trigger is OnboardingAction.HomeServerChange.SelectHomeServer && error.isHomeserverUnavailable() + private fun deeplinkUrlIsUnavailable(error: Throwable, trigger: OnboardingAction.HomeServerChange) = error.isHomeserverUnavailable() && loginConfig != null && trigger is OnboardingAction.HomeServerChange.SelectHomeServer @@ -807,6 +809,8 @@ class OnboardingViewModel @AssistedInject constructor( return loginConfig?.homeServerUrl } + fun getDefaultHomeserverUrl() = defaultHomeserverUrl + fun fetchSsoUrl(redirectUrl: String, deviceId: String?, provider: SsoIdentityProvider?): String? { setState { val authDescription = AuthenticationDescription.Register(provider.toAuthenticationType()) diff --git a/vector/src/main/java/im/vector/app/features/onboarding/ftueauth/FtueAuthCombinedServerSelectionFragment.kt b/vector/src/main/java/im/vector/app/features/onboarding/ftueauth/FtueAuthCombinedServerSelectionFragment.kt index 749aac2898..2563c1d777 100644 --- a/vector/src/main/java/im/vector/app/features/onboarding/ftueauth/FtueAuthCombinedServerSelectionFragment.kt +++ b/vector/src/main/java/im/vector/app/features/onboarding/ftueauth/FtueAuthCombinedServerSelectionFragment.kt @@ -86,7 +86,7 @@ class FtueAuthCombinedServerSelectionFragment @Inject constructor() : AbstractFt ) if (views.chooseServerInput.content().isEmpty()) { - val userUrlInput = state.selectedHomeserver.userFacingUrl?.toReducedUrlKeepingSchemaIfInsecure() + val userUrlInput = state.selectedHomeserver.userFacingUrl?.toReducedUrlKeepingSchemaIfInsecure() ?: viewModel.getDefaultHomeserverUrl() views.chooseServerInput.editText().setText(userUrlInput) } } diff --git a/vector/src/main/java/im/vector/app/features/onboarding/ftueauth/FtueAuthVariant.kt b/vector/src/main/java/im/vector/app/features/onboarding/ftueauth/FtueAuthVariant.kt index 601d577e02..96a3ed3f65 100644 --- a/vector/src/main/java/im/vector/app/features/onboarding/ftueauth/FtueAuthVariant.kt +++ b/vector/src/main/java/im/vector/app/features/onboarding/ftueauth/FtueAuthVariant.kt @@ -46,6 +46,7 @@ import im.vector.app.features.login.SignMode import im.vector.app.features.login.TextInputFormFragmentMode import im.vector.app.features.onboarding.OnboardingAction import im.vector.app.features.onboarding.OnboardingActivity +import im.vector.app.features.onboarding.OnboardingFlow import im.vector.app.features.onboarding.OnboardingVariant import im.vector.app.features.onboarding.OnboardingViewEvents import im.vector.app.features.onboarding.OnboardingViewModel @@ -213,7 +214,7 @@ class FtueAuthVariant( option = commonOption ) } - OnboardingViewEvents.OpenCombinedRegister -> openStartCombinedRegister() + OnboardingViewEvents.OpenCombinedRegister -> onStartCombinedRegister() is OnboardingViewEvents.OnAccountCreated -> onAccountCreated() OnboardingViewEvents.OnAccountSignedIn -> onAccountSignedIn() OnboardingViewEvents.OnChooseDisplayName -> onChooseDisplayName() @@ -229,21 +230,43 @@ class FtueAuthVariant( tag = FRAGMENT_EDIT_HOMESERVER_TAG ) } - OnboardingViewEvents.OnHomeserverEdited -> supportFragmentManager.popBackStack( - FRAGMENT_EDIT_HOMESERVER_TAG, - FragmentManager.POP_BACK_STACK_INCLUSIVE - ) + OnboardingViewEvents.OnHomeserverEdited -> { + supportFragmentManager.popBackStack( + FRAGMENT_EDIT_HOMESERVER_TAG, + FragmentManager.POP_BACK_STACK_INCLUSIVE + ) + ensureEditServerBackstack() + } OnboardingViewEvents.OpenCombinedLogin -> onStartCombinedLogin() is OnboardingViewEvents.DeeplinkAuthenticationFailure -> onDeeplinkedHomeserverUnavailable(viewEvents) OnboardingViewEvents.DisplayRegistrationFallback -> displayFallbackWebDialog() is OnboardingViewEvents.DisplayRegistrationStage -> doStage(viewEvents.stage) OnboardingViewEvents.DisplayStartRegistration -> when { - vectorFeatures.isOnboardingCombinedRegisterEnabled() -> openStartCombinedRegister() + vectorFeatures.isOnboardingCombinedRegisterEnabled() -> onStartCombinedRegister() else -> openAuthLoginFragmentWithTag(FRAGMENT_REGISTRATION_STAGE_TAG) } } } + private fun ensureEditServerBackstack() { + when (activity.supportFragmentManager.findFragmentById(views.loginFragmentContainer.id)) { + is FtueAuthCombinedLoginFragment, + is FtueAuthCombinedRegisterFragment -> { + // do nothing + } + else -> { + withState(onboardingViewModel) { state -> + when (state.onboardingFlow) { + OnboardingFlow.SignIn -> onStartCombinedLogin() + OnboardingFlow.SignUp -> onStartCombinedRegister() + OnboardingFlow.SignInSignUp, + null -> error("${state.onboardingFlow} does not support editing server url") + } + } + } + } + } + private fun onDeeplinkedHomeserverUnavailable(viewEvents: OnboardingViewEvents.DeeplinkAuthenticationFailure) { showHomeserverUnavailableDialog(onboardingViewModel.getInitialHomeServerUrl().orEmpty()) { onboardingViewModel.handle(OnboardingAction.ResetDeeplinkConfig) @@ -264,7 +287,7 @@ class FtueAuthVariant( addRegistrationStageFragmentToBackstack(FtueAuthCombinedLoginFragment::class.java, allowStateLoss = true) } - private fun openStartCombinedRegister() { + private fun onStartCombinedRegister() { addRegistrationStageFragmentToBackstack(FtueAuthCombinedRegisterFragment::class.java, allowStateLoss = true) } From 4cc0b81c8642c7aa9d3870071e52948488b30d8f Mon Sep 17 00:00:00 2001 From: Adam Brown Date: Fri, 19 Aug 2022 12:25:26 +0100 Subject: [PATCH 2/5] removing deeplink error handling as its now covered by the edit server flow instead --- .../onboarding/OnboardingViewEvents.kt | 1 - .../onboarding/OnboardingViewModel.kt | 11 ---------- .../onboarding/ftueauth/FtueAuthVariant.kt | 17 --------------- .../onboarding/OnboardingViewModelTest.kt | 21 ------------------- 4 files changed, 50 deletions(-) diff --git a/vector/src/main/java/im/vector/app/features/onboarding/OnboardingViewEvents.kt b/vector/src/main/java/im/vector/app/features/onboarding/OnboardingViewEvents.kt index 1441152128..dcf6521499 100644 --- a/vector/src/main/java/im/vector/app/features/onboarding/OnboardingViewEvents.kt +++ b/vector/src/main/java/im/vector/app/features/onboarding/OnboardingViewEvents.kt @@ -29,7 +29,6 @@ import org.matrix.android.sdk.api.failure.Failure as SdkFailure sealed class OnboardingViewEvents : VectorViewEvents { data class Loading(val message: CharSequence? = null) : OnboardingViewEvents() data class Failure(val throwable: Throwable) : OnboardingViewEvents() - data class DeeplinkAuthenticationFailure(val retryAction: OnboardingAction) : OnboardingViewEvents() data class UnrecognisedCertificateFailure(val retryAction: OnboardingAction, val cause: SdkFailure.UnrecognizedCertificateFailure) : OnboardingViewEvents() object DisplayRegistrationFallback : OnboardingViewEvents() diff --git a/vector/src/main/java/im/vector/app/features/onboarding/OnboardingViewModel.kt b/vector/src/main/java/im/vector/app/features/onboarding/OnboardingViewModel.kt index 987d3f38a2..9fb82380b3 100644 --- a/vector/src/main/java/im/vector/app/features/onboarding/OnboardingViewModel.kt +++ b/vector/src/main/java/im/vector/app/features/onboarding/OnboardingViewModel.kt @@ -703,11 +703,6 @@ class OnboardingViewModel @AssistedInject constructor( when { error.isHomeserverUnavailable() && applicationContext.inferNoConnectivity(sdkIntProvider) -> _viewEvents.post(OnboardingViewEvents.Failure(error)) isUnableToSelectServer(error, trigger) -> handle(OnboardingAction.PostViewEvent(OnboardingViewEvents.EditServerSelection)) - deeplinkUrlIsUnavailable(error, trigger) -> _viewEvents.post( - OnboardingViewEvents.DeeplinkAuthenticationFailure( - retryAction = (trigger as OnboardingAction.HomeServerChange.SelectHomeServer).resetToDefaultUrl() - ) - ) error.isUnrecognisedCertificate() -> { _viewEvents.post(OnboardingViewEvents.UnrecognisedCertificateFailure(trigger, error as Failure.UnrecognizedCertificateFailure)) } @@ -718,12 +713,6 @@ class OnboardingViewModel @AssistedInject constructor( private fun isUnableToSelectServer(error: Throwable, trigger: OnboardingAction.HomeServerChange) = trigger is OnboardingAction.HomeServerChange.SelectHomeServer && error.isHomeserverUnavailable() - private fun deeplinkUrlIsUnavailable(error: Throwable, trigger: OnboardingAction.HomeServerChange) = error.isHomeserverUnavailable() && - loginConfig != null && - trigger is OnboardingAction.HomeServerChange.SelectHomeServer - - private fun OnboardingAction.HomeServerChange.SelectHomeServer.resetToDefaultUrl() = copy(homeServerUrl = defaultHomeserverUrl) - private suspend fun onAuthenticationStartedSuccess( trigger: OnboardingAction.HomeServerChange, config: HomeServerConnectionConfig, diff --git a/vector/src/main/java/im/vector/app/features/onboarding/ftueauth/FtueAuthVariant.kt b/vector/src/main/java/im/vector/app/features/onboarding/ftueauth/FtueAuthVariant.kt index 96a3ed3f65..f3767aa546 100644 --- a/vector/src/main/java/im/vector/app/features/onboarding/ftueauth/FtueAuthVariant.kt +++ b/vector/src/main/java/im/vector/app/features/onboarding/ftueauth/FtueAuthVariant.kt @@ -238,7 +238,6 @@ class FtueAuthVariant( ensureEditServerBackstack() } OnboardingViewEvents.OpenCombinedLogin -> onStartCombinedLogin() - is OnboardingViewEvents.DeeplinkAuthenticationFailure -> onDeeplinkedHomeserverUnavailable(viewEvents) OnboardingViewEvents.DisplayRegistrationFallback -> displayFallbackWebDialog() is OnboardingViewEvents.DisplayRegistrationStage -> doStage(viewEvents.stage) OnboardingViewEvents.DisplayStartRegistration -> when { @@ -267,22 +266,6 @@ class FtueAuthVariant( } } - private fun onDeeplinkedHomeserverUnavailable(viewEvents: OnboardingViewEvents.DeeplinkAuthenticationFailure) { - showHomeserverUnavailableDialog(onboardingViewModel.getInitialHomeServerUrl().orEmpty()) { - onboardingViewModel.handle(OnboardingAction.ResetDeeplinkConfig) - onboardingViewModel.handle(viewEvents.retryAction) - } - } - - private fun showHomeserverUnavailableDialog(url: String, action: () -> Unit) { - MaterialAlertDialogBuilder(activity) - .setTitle(R.string.dialog_title_error) - .setMessage(activity.getString(R.string.login_error_homeserver_from_url_not_found, url)) - .setPositiveButton(R.string.login_error_homeserver_from_url_not_found_enter_manual) { _, _ -> action() } - .setNegativeButton(R.string.action_cancel, null) - .show() - } - private fun onStartCombinedLogin() { addRegistrationStageFragmentToBackstack(FtueAuthCombinedLoginFragment::class.java, allowStateLoss = true) } diff --git a/vector/src/test/java/im/vector/app/features/onboarding/OnboardingViewModelTest.kt b/vector/src/test/java/im/vector/app/features/onboarding/OnboardingViewModelTest.kt index cee8f3622c..c1b2439227 100644 --- a/vector/src/test/java/im/vector/app/features/onboarding/OnboardingViewModelTest.kt +++ b/vector/src/test/java/im/vector/app/features/onboarding/OnboardingViewModelTest.kt @@ -411,27 +411,6 @@ class OnboardingViewModelTest { .finish() } - @Test - fun `given unavailable deeplink, when selecting homeserver, then emits failure with default homeserver as retry action`() = runTest { - fakeContext.givenHasConnection() - fakeHomeServerConnectionConfigFactory.givenConfigFor(A_HOMESERVER_URL, fingerprint = null, A_HOMESERVER_CONFIG) - fakeStartAuthenticationFlowUseCase.givenHomeserverUnavailable(A_HOMESERVER_CONFIG) - val test = viewModel.test() - - viewModel.handle(OnboardingAction.InitWith(LoginConfig(A_HOMESERVER_URL, null))) - viewModel.handle(OnboardingAction.HomeServerChange.SelectHomeServer(A_HOMESERVER_URL)) - - val expectedRetryAction = OnboardingAction.HomeServerChange.SelectHomeServer("${R.string.matrix_org_server_url.toTestString()}/") - test - .assertStatesChanges( - initialState, - { copy(isLoading = true) }, - { copy(isLoading = false) } - ) - .assertEvents(OnboardingViewEvents.DeeplinkAuthenticationFailure(expectedRetryAction)) - .finish() - } - @Test fun `given in the sign up flow, when editing homeserver, then updates selected homeserver state and emits edited event`() = runTest { viewModelWith(initialState.copy(onboardingFlow = OnboardingFlow.SignUp)) From b50b6daca19a72ce27791df5a53caeea259ca574 Mon Sep 17 00:00:00 2001 From: Adam Brown Date: Fri, 19 Aug 2022 12:44:01 +0100 Subject: [PATCH 3/5] using wider range network error when deciding to forward to the edit server instead of just unknown host - will also capture timeouts --- .../matrix/android/sdk/api/failure/Extensions.kt | 2 ++ .../features/onboarding/OnboardingViewModel.kt | 16 ++++++++++++++-- 2 files changed, 16 insertions(+), 2 deletions(-) diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/failure/Extensions.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/failure/Extensions.kt index 429d346a1b..5b41ddaaec 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/failure/Extensions.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/failure/Extensions.kt @@ -89,6 +89,8 @@ fun Throwable.isInvalidUIAAuth() = this is Failure.ServerError && fun Throwable.isHomeserverUnavailable() = this is Failure.NetworkConnection && this.ioException is UnknownHostException +fun Throwable.isHomeserverConnectionError() = this is Failure.NetworkConnection + fun Throwable.isMissingEmailVerification() = this is Failure.ServerError && error.code == MatrixError.M_UNAUTHORIZED && error.message == "Unable to get validated threepid" diff --git a/vector/src/main/java/im/vector/app/features/onboarding/OnboardingViewModel.kt b/vector/src/main/java/im/vector/app/features/onboarding/OnboardingViewModel.kt index 9fb82380b3..9661feb002 100644 --- a/vector/src/main/java/im/vector/app/features/onboarding/OnboardingViewModel.kt +++ b/vector/src/main/java/im/vector/app/features/onboarding/OnboardingViewModel.kt @@ -61,6 +61,7 @@ import org.matrix.android.sdk.api.auth.login.LoginWizard import org.matrix.android.sdk.api.auth.registration.RegistrationAvailability import org.matrix.android.sdk.api.auth.registration.RegistrationWizard import org.matrix.android.sdk.api.failure.Failure +import org.matrix.android.sdk.api.failure.isHomeserverConnectionError import org.matrix.android.sdk.api.failure.isHomeserverUnavailable import org.matrix.android.sdk.api.failure.isUnrecognisedCertificate import org.matrix.android.sdk.api.network.ssl.Fingerprint @@ -702,7 +703,14 @@ class OnboardingViewModel @AssistedInject constructor( private fun onAuthenticationStartError(error: Throwable, trigger: OnboardingAction.HomeServerChange) { when { error.isHomeserverUnavailable() && applicationContext.inferNoConnectivity(sdkIntProvider) -> _viewEvents.post(OnboardingViewEvents.Failure(error)) - isUnableToSelectServer(error, trigger) -> handle(OnboardingAction.PostViewEvent(OnboardingViewEvents.EditServerSelection)) + isUnableToSelectServer(error, trigger) -> { + withState { state -> + when { + canEditServerSelectionError(state) -> handle(OnboardingAction.PostViewEvent(OnboardingViewEvents.EditServerSelection)) + else -> _viewEvents.post(OnboardingViewEvents.Failure(error)) + } + } + } error.isUnrecognisedCertificate() -> { _viewEvents.post(OnboardingViewEvents.UnrecognisedCertificateFailure(trigger, error as Failure.UnrecognizedCertificateFailure)) } @@ -710,8 +718,12 @@ class OnboardingViewModel @AssistedInject constructor( } } + private fun canEditServerSelectionError(state: OnboardingViewState) = + (state.onboardingFlow == OnboardingFlow.SignIn && vectorFeatures.isOnboardingCombinedLoginEnabled()) || + (state.onboardingFlow == OnboardingFlow.SignUp && vectorFeatures.isOnboardingCombinedRegisterEnabled()) + private fun isUnableToSelectServer(error: Throwable, trigger: OnboardingAction.HomeServerChange) = - trigger is OnboardingAction.HomeServerChange.SelectHomeServer && error.isHomeserverUnavailable() + trigger is OnboardingAction.HomeServerChange.SelectHomeServer && error.isHomeserverConnectionError() private suspend fun onAuthenticationStartedSuccess( trigger: OnboardingAction.HomeServerChange, From d7bc43584d52f442ea9a9d92f1004127a9f59098 Mon Sep 17 00:00:00 2001 From: Adam Brown Date: Fri, 19 Aug 2022 13:03:59 +0100 Subject: [PATCH 4/5] adding tests around forwarding to the edit server selection when the initial server selection fails --- .../onboarding/OnboardingViewModelTest.kt | 69 +++++++++++++++++++ 1 file changed, 69 insertions(+) diff --git a/vector/src/test/java/im/vector/app/features/onboarding/OnboardingViewModelTest.kt b/vector/src/test/java/im/vector/app/features/onboarding/OnboardingViewModelTest.kt index c1b2439227..0e4a4704b9 100644 --- a/vector/src/test/java/im/vector/app/features/onboarding/OnboardingViewModelTest.kt +++ b/vector/src/test/java/im/vector/app/features/onboarding/OnboardingViewModelTest.kt @@ -411,6 +411,63 @@ class OnboardingViewModelTest { .finish() } + @Test + fun `given in sign in flow, when selecting homeserver fails with network error, then emits Failure`() = runTest { + viewModelWith(initialState.copy(onboardingFlow = OnboardingFlow.SignIn)) + fakeVectorFeatures.givenCombinedLoginEnabled() + givenHomeserverSelectionFailsWith(AN_ERROR) + val test = viewModel.test() + + viewModel.handle(OnboardingAction.HomeServerChange.SelectHomeServer(A_HOMESERVER_URL)) + + test + .assertStatesChanges( + initialState, + { copy(isLoading = true) }, + { copy(isLoading = false) } + ) + .assertEvents(OnboardingViewEvents.Failure(AN_ERROR)) + .finish() + } + + @Test + fun `given in sign in flow, when selecting homeserver fails with network error, then emits EditServerSelection`() = runTest { + viewModelWith(initialState.copy(onboardingFlow = OnboardingFlow.SignIn)) + fakeVectorFeatures.givenCombinedLoginEnabled() + givenHomeserverSelectionFailsWithNetworkError() + val test = viewModel.test() + + viewModel.handle(OnboardingAction.HomeServerChange.SelectHomeServer(A_HOMESERVER_URL)) + + test + .assertStatesChanges( + initialState, + { copy(isLoading = true) }, + { copy(isLoading = false) } + ) + .assertEvents(OnboardingViewEvents.EditServerSelection) + .finish() + } + + @Test + fun `given in sign up flow, when selecting homeserver fails with network error, then emits EditServerSelection`() = runTest { + viewModelWith(initialState.copy(onboardingFlow = OnboardingFlow.SignUp)) + fakeVectorFeatures.givenCombinedRegisterEnabled() + givenHomeserverSelectionFailsWithNetworkError() + val test = viewModel.test() + + viewModel.handle(OnboardingAction.HomeServerChange.SelectHomeServer(A_HOMESERVER_URL)) + + test + .assertStatesChanges( + initialState, + { copy(isLoading = true) }, + { copy(isLoading = false) } + ) + .assertEvents(OnboardingViewEvents.EditServerSelection) + .finish() + } + @Test fun `given in the sign up flow, when editing homeserver, then updates selected homeserver state and emits edited event`() = runTest { viewModelWith(initialState.copy(onboardingFlow = OnboardingFlow.SignUp)) @@ -1121,6 +1178,18 @@ class OnboardingViewModelTest { private fun initialRegistrationState(homeServerUrl: String) = initialState.copy( onboardingFlow = OnboardingFlow.SignUp, selectedHomeserver = SelectedHomeserverState(userFacingUrl = homeServerUrl) ) + + private fun givenHomeserverSelectionFailsWithNetworkError() { + fakeContext.givenHasConnection() + fakeHomeServerConnectionConfigFactory.givenConfigFor(A_HOMESERVER_URL, fingerprint = null, A_HOMESERVER_CONFIG) + fakeStartAuthenticationFlowUseCase.givenHomeserverUnavailable(A_HOMESERVER_CONFIG) + } + + private fun givenHomeserverSelectionFailsWith(cause: Throwable) { + fakeContext.givenHasConnection() + fakeHomeServerConnectionConfigFactory.givenConfigFor(A_HOMESERVER_URL, fingerprint = null, A_HOMESERVER_CONFIG) + fakeStartAuthenticationFlowUseCase.givenErrors(A_HOMESERVER_CONFIG, cause) + } } private fun HomeServerCapabilities.toPersonalisationState(displayName: String? = null) = PersonalizationState( From 8336d4c269f4db8ddedf82eed252e95ce65d90bc Mon Sep 17 00:00:00 2001 From: Adam Brown Date: Fri, 19 Aug 2022 13:06:04 +0100 Subject: [PATCH 5/5] adding changelog entry --- changelog.d/6718.bugfix | 1 + 1 file changed, 1 insertion(+) create mode 100644 changelog.d/6718.bugfix diff --git a/changelog.d/6718.bugfix b/changelog.d/6718.bugfix new file mode 100644 index 0000000000..a7c4c503c7 --- /dev/null +++ b/changelog.d/6718.bugfix @@ -0,0 +1 @@ +Fixes onboarding requiring matrix.org to be accessible on the first step, the server can now be manually changed