From 6fb6463b90e0ec6e4ef666d7ed78f043a3846836 Mon Sep 17 00:00:00 2001 From: ratree Date: Wed, 18 Mar 2020 16:14:27 +0700 Subject: [PATCH 01/10] CA-2108 Implement terms and service (UI) --- .../view/login/TermsAndServiceFragment.kt | 29 +++++++++++ .../res/layout/fragment_terms_and_service.xml | 52 +++++++++++++++++++ app/src/main/res/values/strings.xml | 2 + 3 files changed, 83 insertions(+) create mode 100644 app/src/main/java/org/rfcx/ranger/view/login/TermsAndServiceFragment.kt create mode 100644 app/src/main/res/layout/fragment_terms_and_service.xml diff --git a/app/src/main/java/org/rfcx/ranger/view/login/TermsAndServiceFragment.kt b/app/src/main/java/org/rfcx/ranger/view/login/TermsAndServiceFragment.kt new file mode 100644 index 000000000..c297ad157 --- /dev/null +++ b/app/src/main/java/org/rfcx/ranger/view/login/TermsAndServiceFragment.kt @@ -0,0 +1,29 @@ +package org.rfcx.ranger.view.login + + +import android.os.Bundle +import android.view.LayoutInflater +import android.view.View +import android.view.ViewGroup +import kotlinx.android.synthetic.main.fragment_terms_and_service.* +import org.rfcx.ranger.R +import org.rfcx.ranger.view.base.BaseFragment + +class TermsAndServiceFragment : BaseFragment() { + + override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, + savedInstanceState: Bundle?): View? { + return inflater.inflate(R.layout.fragment_terms_and_service, container, false) + } + + override fun onViewCreated(view: View, savedInstanceState: Bundle?) { + super.onViewCreated(view, savedInstanceState) + + termsAndConditionsWebview.loadUrl("https://rfcx.org/terms-of-service-text-only") + + checkBox.setOnClickListener { + submitButton.isEnabled = checkBox.isChecked + } + } + +} diff --git a/app/src/main/res/layout/fragment_terms_and_service.xml b/app/src/main/res/layout/fragment_terms_and_service.xml new file mode 100644 index 000000000..28fe2daa3 --- /dev/null +++ b/app/src/main/res/layout/fragment_terms_and_service.xml @@ -0,0 +1,52 @@ + + + + + + + + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index 22db05551..5c1b19565 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -38,6 +38,8 @@ Please tell us your name Name + I have read and agree to these Terms and Service + An error occurred. Please try again. Ranger App would like to use your location From bae9f31839f192d8d66422893d76d2c8832507c1 Mon Sep 17 00:00:00 2001 From: ratree Date: Wed, 18 Mar 2020 16:32:03 +0700 Subject: [PATCH 02/10] CA-2108 Change text on button --- app/src/main/res/layout/fragment_terms_and_service.xml | 2 +- app/src/main/res/values/strings.xml | 1 + 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/app/src/main/res/layout/fragment_terms_and_service.xml b/app/src/main/res/layout/fragment_terms_and_service.xml index 28fe2daa3..414866152 100644 --- a/app/src/main/res/layout/fragment_terms_and_service.xml +++ b/app/src/main/res/layout/fragment_terms_and_service.xml @@ -41,7 +41,7 @@ android:layout_marginStart="@dimen/margin_padding_normal" android:layout_marginEnd="@dimen/margin_padding_normal" android:layout_marginBottom="@dimen/margin_padding_normal" - android:text="@string/invitation_submit_button_label" + android:text="@string/continue_text" android:enabled="false" app:layout_constraintEnd_toEndOf="parent" app:layout_constraintStart_toStartOf="parent" diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index 5c1b19565..be4db5f1e 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -39,6 +39,7 @@ Name I have read and agree to these Terms and Service + Continue An error occurred. Please try again. From 84b3be4cd474575e1059c26d12c9d776b970c9b8 Mon Sep 17 00:00:00 2001 From: ratree Date: Thu, 19 Mar 2020 10:46:47 +0700 Subject: [PATCH 03/10] CA-2108 Added API "v1/users/accept-terms" --- .../ranger/data/remote/service/ServiceFactory.kt | 7 +++++++ .../ranger/data/remote/terms/TermsEndpoint.kt | 14 ++++++++++++++ .../ranger/data/remote/terms/TermsRepository.kt | 11 +++++++++++ .../data/remote/terms/TermsRepositoryImp.kt | 13 +++++++++++++ .../ranger/data/remote/terms/TermsUseCase.kt | 16 ++++++++++++++++ .../main/java/org/rfcx/ranger/di/DataModule.kt | 7 +++++++ .../java/org/rfcx/ranger/entity/terms/Terms.kt | 12 ++++++++++++ 7 files changed, 80 insertions(+) create mode 100644 app/src/main/java/org/rfcx/ranger/data/remote/terms/TermsEndpoint.kt create mode 100644 app/src/main/java/org/rfcx/ranger/data/remote/terms/TermsRepository.kt create mode 100644 app/src/main/java/org/rfcx/ranger/data/remote/terms/TermsRepositoryImp.kt create mode 100644 app/src/main/java/org/rfcx/ranger/data/remote/terms/TermsUseCase.kt create mode 100644 app/src/main/java/org/rfcx/ranger/entity/terms/Terms.kt diff --git a/app/src/main/java/org/rfcx/ranger/data/remote/service/ServiceFactory.kt b/app/src/main/java/org/rfcx/ranger/data/remote/service/ServiceFactory.kt index c320a2c9e..be85a6531 100644 --- a/app/src/main/java/org/rfcx/ranger/data/remote/service/ServiceFactory.kt +++ b/app/src/main/java/org/rfcx/ranger/data/remote/service/ServiceFactory.kt @@ -18,6 +18,7 @@ import org.rfcx.ranger.data.remote.setusername.SetNameEndpoint import org.rfcx.ranger.data.remote.shortlink.ShortLinkEndpoint import org.rfcx.ranger.data.remote.site.SiteEndpoint import org.rfcx.ranger.data.remote.subscribe.SubscribeEndpoint +import org.rfcx.ranger.data.remote.terms.TermsEndpoint import org.rfcx.ranger.data.remote.usertouch.UserTouchEndPoint import org.rfcx.ranger.util.GsonProvider import org.rfcx.ranger.util.ImprovedDateTypeAdapter @@ -101,6 +102,12 @@ object ServiceFactory { .create(SubscribeEndpoint::class.java) } + fun makeTermsService(isDebug: Boolean, context: Context): TermsEndpoint { + return createRetrofit(BuildConfig.RANGER_DOMAIN, createAuthTokenOkHttpClient(isDebug, AuthTokenInterceptor(context)), + GsonProvider.getInstance().gson) + .create(TermsEndpoint::class.java) + } + private fun createRetrofit(baseUrl: String, okHttpClient: OkHttpClient, gson: Gson): Retrofit { return Retrofit.Builder().baseUrl(baseUrl) .addCallAdapterFactory(RxJava2CallAdapterFactory.create()) diff --git a/app/src/main/java/org/rfcx/ranger/data/remote/terms/TermsEndpoint.kt b/app/src/main/java/org/rfcx/ranger/data/remote/terms/TermsEndpoint.kt new file mode 100644 index 000000000..d3a1b06bb --- /dev/null +++ b/app/src/main/java/org/rfcx/ranger/data/remote/terms/TermsEndpoint.kt @@ -0,0 +1,14 @@ +package org.rfcx.ranger.data.remote.terms + +import io.reactivex.Single +import org.rfcx.ranger.entity.terms.TermsRequest +import org.rfcx.ranger.entity.terms.TermsResponse +import retrofit2.http.Body +import retrofit2.http.POST + +interface TermsEndpoint { + + @POST("v1/users/accept-terms") + fun sendPayload(@Body body: TermsRequest): Single + +} \ No newline at end of file diff --git a/app/src/main/java/org/rfcx/ranger/data/remote/terms/TermsRepository.kt b/app/src/main/java/org/rfcx/ranger/data/remote/terms/TermsRepository.kt new file mode 100644 index 000000000..59c67ee6c --- /dev/null +++ b/app/src/main/java/org/rfcx/ranger/data/remote/terms/TermsRepository.kt @@ -0,0 +1,11 @@ +package org.rfcx.ranger.data.remote.terms + +import io.reactivex.Single +import org.rfcx.ranger.entity.terms.TermsRequest +import org.rfcx.ranger.entity.terms.TermsResponse + +interface TermsRepository { + + fun sendBodyPayload(sendBody: TermsRequest): Single + +} \ No newline at end of file diff --git a/app/src/main/java/org/rfcx/ranger/data/remote/terms/TermsRepositoryImp.kt b/app/src/main/java/org/rfcx/ranger/data/remote/terms/TermsRepositoryImp.kt new file mode 100644 index 000000000..c95eff338 --- /dev/null +++ b/app/src/main/java/org/rfcx/ranger/data/remote/terms/TermsRepositoryImp.kt @@ -0,0 +1,13 @@ +package org.rfcx.ranger.data.remote.terms + +import io.reactivex.Single +import org.rfcx.ranger.entity.terms.TermsRequest +import org.rfcx.ranger.entity.terms.TermsResponse + +class TermsRepositoryImp(private val termsEndpoint: TermsEndpoint) : TermsRepository { + + override fun sendBodyPayload(sendBody: TermsRequest): Single { + return termsEndpoint.sendPayload(sendBody) + } + +} \ No newline at end of file diff --git a/app/src/main/java/org/rfcx/ranger/data/remote/terms/TermsUseCase.kt b/app/src/main/java/org/rfcx/ranger/data/remote/terms/TermsUseCase.kt new file mode 100644 index 000000000..67ae01425 --- /dev/null +++ b/app/src/main/java/org/rfcx/ranger/data/remote/terms/TermsUseCase.kt @@ -0,0 +1,16 @@ +package org.rfcx.ranger.data.remote.terms + +import io.reactivex.Single +import org.rfcx.ranger.data.remote.domain.SingleUseCase +import org.rfcx.ranger.data.remote.domain.executor.PostExecutionThread +import org.rfcx.ranger.data.remote.domain.executor.ThreadExecutor +import org.rfcx.ranger.entity.terms.TermsRequest +import org.rfcx.ranger.entity.terms.TermsResponse + +class TermsUseCase(private val termsRepository: TermsRepository, + threadExecutor: ThreadExecutor, postExecutionThread: PostExecutionThread +) : SingleUseCase(threadExecutor, postExecutionThread) { + override fun buildUseCaseObservable(params: TermsRequest): Single { + return termsRepository.sendBodyPayload(params) + } +} \ No newline at end of file diff --git a/app/src/main/java/org/rfcx/ranger/di/DataModule.kt b/app/src/main/java/org/rfcx/ranger/di/DataModule.kt index 55ff56cba..fbd44af8a 100644 --- a/app/src/main/java/org/rfcx/ranger/di/DataModule.kt +++ b/app/src/main/java/org/rfcx/ranger/di/DataModule.kt @@ -50,6 +50,9 @@ import org.rfcx.ranger.data.remote.subscribe.SubscribeUseCase import org.rfcx.ranger.data.remote.subscribe.unsubscribe.UnsubscribeRepository import org.rfcx.ranger.data.remote.subscribe.unsubscribe.UnsubscribeRepositoryImp import org.rfcx.ranger.data.remote.subscribe.unsubscribe.UnsubscribeUseCase +import org.rfcx.ranger.data.remote.terms.TermsRepository +import org.rfcx.ranger.data.remote.terms.TermsRepositoryImp +import org.rfcx.ranger.data.remote.terms.TermsUseCase import org.rfcx.ranger.data.remote.usertouch.CheckUserTouchUseCase import org.rfcx.ranger.data.remote.usertouch.UserTouchRepository import org.rfcx.ranger.data.remote.usertouch.UserTouchRepositoryImp @@ -110,6 +113,9 @@ object DataModule { single { UnsubscribeRepositoryImp(get()) } bind UnsubscribeRepository::class single { UnsubscribeUseCase(get(), get(), get()) } + single { TermsRepositoryImp(get()) } bind TermsRepository::class + single { TermsUseCase(get(), get(), get()) } + } val remoteModule = module { @@ -125,6 +131,7 @@ object DataModule { factory { ServiceFactory.makePasswordService(BuildConfig.DEBUG, androidContext()) } factory { ServiceFactory.makeProfilePhotoService(BuildConfig.DEBUG, androidContext()) } factory { ServiceFactory.makeSubscribeService(BuildConfig.DEBUG, androidContext()) } + factory { ServiceFactory.makeTermsService(BuildConfig.DEBUG, androidContext()) } } val localModule = module { diff --git a/app/src/main/java/org/rfcx/ranger/entity/terms/Terms.kt b/app/src/main/java/org/rfcx/ranger/entity/terms/Terms.kt new file mode 100644 index 000000000..76870774d --- /dev/null +++ b/app/src/main/java/org/rfcx/ranger/entity/terms/Terms.kt @@ -0,0 +1,12 @@ +package org.rfcx.ranger.entity.terms + +import com.google.gson.annotations.SerializedName + +open class TermsRequest( + val app: String +) + +open class TermsResponse( + @SerializedName("success") + val success: Boolean +) \ No newline at end of file From fca8f422be4c4899bca1521b451c082a9e426ef7 Mon Sep 17 00:00:00 2001 From: ratree Date: Thu, 19 Mar 2020 11:47:03 +0700 Subject: [PATCH 04/10] CA-2108 Check "consentGivenRangerApp" in token --- .../main/java/org/rfcx/ranger/di/UiModule.kt | 2 + .../ranger/entity/user/UserAuthResponse.kt | 2 +- .../org/rfcx/ranger/util/CredentialKeeper.kt | 3 + .../rfcx/ranger/util/CredentialVerifier.kt | 17 +++- .../java/org/rfcx/ranger/util/Preferences.kt | 1 + .../ranger/view/login/LoginActivityNew.kt | 10 ++- .../view/login/TermsAndServiceFragment.kt | 28 +++++- .../view/login/TermsAndServiceViewModel.kt | 89 +++++++++++++++++++ .../res/layout/fragment_terms_and_service.xml | 12 +++ app/src/main/res/values/environment.xml | 1 + 10 files changed, 159 insertions(+), 6 deletions(-) create mode 100644 app/src/main/java/org/rfcx/ranger/view/login/TermsAndServiceViewModel.kt diff --git a/app/src/main/java/org/rfcx/ranger/di/UiModule.kt b/app/src/main/java/org/rfcx/ranger/di/UiModule.kt index b5f354ab9..597d86414 100644 --- a/app/src/main/java/org/rfcx/ranger/di/UiModule.kt +++ b/app/src/main/java/org/rfcx/ranger/di/UiModule.kt @@ -14,6 +14,7 @@ import org.rfcx.ranger.view.alerts.guardian.alertType.AlertValueViewModel import org.rfcx.ranger.view.login.InvitationCodeViewModel import org.rfcx.ranger.view.login.LoginViewModel import org.rfcx.ranger.view.login.SetUserNameViewModel +import org.rfcx.ranger.view.login.TermsAndServiceViewModel import org.rfcx.ranger.view.map.MapDetailViewModel import org.rfcx.ranger.view.map.MapViewModel import org.rfcx.ranger.view.map.ReportViewPagerFragmentViewModel @@ -67,5 +68,6 @@ object UiModule { viewModel { LoginViewModel(androidContext(), get()) } viewModel { InvitationCodeViewModel(androidContext(), get()) } viewModel { SetUserNameViewModel(androidContext(), get()) } + viewModel { TermsAndServiceViewModel(androidContext(), get()) } } } \ No newline at end of file diff --git a/app/src/main/java/org/rfcx/ranger/entity/user/UserAuthResponse.kt b/app/src/main/java/org/rfcx/ranger/entity/user/UserAuthResponse.kt index 77bb55742..fe3213bf3 100644 --- a/app/src/main/java/org/rfcx/ranger/entity/user/UserAuthResponse.kt +++ b/app/src/main/java/org/rfcx/ranger/entity/user/UserAuthResponse.kt @@ -6,7 +6,7 @@ package org.rfcx.ranger.entity.user data class UserAuthResponse (val guid: String, val email: String?, val nickname: String?, val idToken: String, val accessToken: String?, val refreshToken: String?, - val roles: Set = setOf(), val accessibleSites: Set = setOf(), val defaultSite: String? = null, val picture: String?) { + val roles: Set = setOf(), val accessibleSites: Set = setOf(), val defaultSite: String? = null, val picture: String?, val consentGivenRangerApp: String?) { val isRanger: Boolean get() = roles.contains("rfcxUser") && defaultSite != null diff --git a/app/src/main/java/org/rfcx/ranger/util/CredentialKeeper.kt b/app/src/main/java/org/rfcx/ranger/util/CredentialKeeper.kt index 3a354c71e..9bc72b83a 100644 --- a/app/src/main/java/org/rfcx/ranger/util/CredentialKeeper.kt +++ b/app/src/main/java/org/rfcx/ranger/util/CredentialKeeper.kt @@ -31,6 +31,9 @@ class CredentialKeeper(val context: Context) { if (user.picture != null) { preferences.putString(Preferences.IMAGE_PROFILE, user.picture) } + if (user.consentGivenRangerApp != null) { + preferences.putBoolean(Preferences.CONSENT_GIVEN, true) + } preferences.putStringSet(Preferences.ROLES, user.roles) preferences.putStringSet(Preferences.ACCESSIBLE_SITES, user.accessibleSites) if (user.defaultSite != null) { diff --git a/app/src/main/java/org/rfcx/ranger/util/CredentialVerifier.kt b/app/src/main/java/org/rfcx/ranger/util/CredentialVerifier.kt index 9b05d227c..d304b93f9 100644 --- a/app/src/main/java/org/rfcx/ranger/util/CredentialVerifier.kt +++ b/app/src/main/java/org/rfcx/ranger/util/CredentialVerifier.kt @@ -24,6 +24,7 @@ class CredentialVerifier(val context: Context) { // Parsing JWT Token val metaDataKey = getString(R.string.auth0_metadata_key) + val userMetaDataKey = getString(R.string.auth0_user_metadata_key) val withoutSignature = token.substring(0, token.lastIndexOf('.') + 1) try { val untrusted = Jwts.parser().parseClaimsJwt(withoutSignature) @@ -64,13 +65,25 @@ class CredentialVerifier(val context: Context) { } } + val userUntrusted = Jwts.parser().parseClaimsJwt(withoutSignature) + if (userUntrusted.body[userMetaDataKey] == null) { + return Err(getString(R.string.an_error_occurred)) + } + + val userMetadata = userUntrusted.body[userMetaDataKey] + if (userMetadata == null || !(userMetadata is HashMap<*, *>)) { + return Err(getString(R.string.an_error_occurred)) + } + + val consentGivenRangerApp: String? = userMetadata["consentGivenRangerApp"] as String? + when { guid.isNullOrEmpty() -> { return Err(getString(R.string.an_error_occurred)) } else -> { - return Ok(UserAuthResponse(guid, email, nickname, token, credentials.accessToken, credentials.refreshToken, roles, accessibleSites, defaultSite, picture)) - } + return Ok(UserAuthResponse(guid, email, nickname, token, credentials.accessToken, credentials.refreshToken, roles, accessibleSites, defaultSite, picture, consentGivenRangerApp)) + } } } catch (e: Exception) { e.printStackTrace() diff --git a/app/src/main/java/org/rfcx/ranger/util/Preferences.kt b/app/src/main/java/org/rfcx/ranger/util/Preferences.kt index dafcba503..81c14a6e3 100644 --- a/app/src/main/java/org/rfcx/ranger/util/Preferences.kt +++ b/app/src/main/java/org/rfcx/ranger/util/Preferences.kt @@ -43,6 +43,7 @@ class Preferences(context: Context) { const val IMAGE_PROFILE = "${PREFIX}IMAGE_PROFILE" const val EMAIL_SUBSCRIBE = "${PREFIX}EMAIL_SUBSCRIBE" const val COORDINATES_FORMAT = "${PREFIX}COORDINATES_FORMAT" + const val CONSENT_GIVEN = "${PREFIX}CONSENT_GIVEN" } init { diff --git a/app/src/main/java/org/rfcx/ranger/view/login/LoginActivityNew.kt b/app/src/main/java/org/rfcx/ranger/view/login/LoginActivityNew.kt index ed1b6eb34..0c6074075 100644 --- a/app/src/main/java/org/rfcx/ranger/view/login/LoginActivityNew.kt +++ b/app/src/main/java/org/rfcx/ranger/view/login/LoginActivityNew.kt @@ -33,7 +33,15 @@ class LoginActivityNew : BaseActivity(), LoginListener { super.onCreate(savedInstanceState) setContentView(R.layout.activity_login_new) val eventGuId = getEventFromIntentIfHave(intent) - if (CredentialKeeper(this).hasValidCredentials() && getSiteName().isNotEmpty() && getUserNickname().substring(0, 1) != "+") { + + val preferenceHelper = Preferences.getInstance(this) + val isConsentGiven = preferenceHelper.getBoolean(Preferences.CONSENT_GIVEN,false) + + if(CredentialKeeper(this).hasValidCredentials() && !isConsentGiven) { + supportFragmentManager.beginTransaction() + .add(loginContainer.id, TermsAndServiceFragment(), + "TermsAndServiceFragment").commit() + } else if (CredentialKeeper(this).hasValidCredentials() && getSiteName().isNotEmpty() && getUserNickname().substring(0, 1) != "+") { MainActivityNew.startActivity(this@LoginActivityNew, eventGuId) finish() } else { diff --git a/app/src/main/java/org/rfcx/ranger/view/login/TermsAndServiceFragment.kt b/app/src/main/java/org/rfcx/ranger/view/login/TermsAndServiceFragment.kt index c297ad157..1bd30496a 100644 --- a/app/src/main/java/org/rfcx/ranger/view/login/TermsAndServiceFragment.kt +++ b/app/src/main/java/org/rfcx/ranger/view/login/TermsAndServiceFragment.kt @@ -5,12 +5,18 @@ import android.os.Bundle import android.view.LayoutInflater import android.view.View import android.view.ViewGroup +import androidx.lifecycle.Observer import kotlinx.android.synthetic.main.fragment_terms_and_service.* +import org.koin.androidx.viewmodel.ext.android.viewModel import org.rfcx.ranger.R +import org.rfcx.ranger.data.remote.success +import org.rfcx.ranger.view.MainActivityNew import org.rfcx.ranger.view.base.BaseFragment class TermsAndServiceFragment : BaseFragment() { + private val termsAndServiceViewModel: TermsAndServiceViewModel by viewModel() + override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? { return inflater.inflate(R.layout.fragment_terms_and_service, container, false) @@ -19,11 +25,29 @@ class TermsAndServiceFragment : BaseFragment() { override fun onViewCreated(view: View, savedInstanceState: Bundle?) { super.onViewCreated(view, savedInstanceState) - termsAndConditionsWebview.loadUrl("https://rfcx.org/terms-of-service-text-only") + termsAndConditionsWebview.loadUrl("https://rfcx.org/terms-of-service-ranger-app-text-only") checkBox.setOnClickListener { submitButton.isEnabled = checkBox.isChecked } + + submitButton.setOnClickListener { + termsAndServiceViewModel.acceptTerms() + + termsAndServiceViewModel.consentGivenState.observe(this, Observer { + it.success({ state -> + if (state) { + context?.let { it1 -> MainActivityNew.startActivity(it1, null) } + } + termsProgressBar.visibility = View.GONE + }, { + termsProgressBar.visibility = View.GONE + }, { + termsProgressBar.visibility = View.VISIBLE + }) + + + }) + } } - } diff --git a/app/src/main/java/org/rfcx/ranger/view/login/TermsAndServiceViewModel.kt b/app/src/main/java/org/rfcx/ranger/view/login/TermsAndServiceViewModel.kt new file mode 100644 index 000000000..a9df10a3a --- /dev/null +++ b/app/src/main/java/org/rfcx/ranger/view/login/TermsAndServiceViewModel.kt @@ -0,0 +1,89 @@ +package org.rfcx.ranger.view.login + +import android.content.Context +import androidx.lifecycle.LiveData +import androidx.lifecycle.MutableLiveData +import androidx.lifecycle.ViewModel +import com.auth0.android.Auth0 +import com.auth0.android.authentication.AuthenticationAPIClient +import com.auth0.android.authentication.AuthenticationException +import com.auth0.android.callback.BaseCallback +import com.auth0.android.result.Credentials +import io.reactivex.observers.DisposableSingleObserver +import org.rfcx.ranger.R +import org.rfcx.ranger.data.remote.Result +import org.rfcx.ranger.data.remote.terms.TermsUseCase +import org.rfcx.ranger.entity.Err +import org.rfcx.ranger.entity.Ok +import org.rfcx.ranger.entity.guardian.GuardianGroup +import org.rfcx.ranger.entity.terms.TermsRequest +import org.rfcx.ranger.entity.terms.TermsResponse +import org.rfcx.ranger.util.CredentialKeeper +import org.rfcx.ranger.util.CredentialVerifier +import org.rfcx.ranger.util.Preferences +import org.rfcx.ranger.util.getResultError + +class TermsAndServiceViewModel(private val context: Context, private val termsUseCase: TermsUseCase) : ViewModel() { + + private val auth0 by lazy { + val auth0 = Auth0(context.getString(R.string.auth0_client_id), context.getString(R.string.auth0_domain)) + //auth0.isLoggingEnabled = true + auth0.isOIDCConformant = true + auth0 + } + + private val authentication by lazy { + AuthenticationAPIClient(auth0) + } + + private val _consentGivenState = MutableLiveData>() + val consentGivenState: LiveData> get() = _consentGivenState + + fun acceptTerms() { + _consentGivenState.value = Result.Loading + termsUseCase.execute(object : DisposableSingleObserver() { + override fun onSuccess(t: TermsResponse) { + if (t.success) { + refreshToken { + if(it){ + _consentGivenState.value = Result.Success(true) + } + } + } + } + + override fun onError(e: Throwable) { + _consentGivenState.value = e.getResultError() + } + }, TermsRequest("RangerApp")) + } + + private fun refreshToken(callback: (Boolean) -> Unit) { + val refreshToken = Preferences.getInstance(context).getString(Preferences.REFRESH_TOKEN) + if (refreshToken == null) { + callback(false) + return + } + + authentication.renewAuth(refreshToken).start(object : BaseCallback { + override fun onSuccess(credentials: Credentials) { + when (val result = CredentialVerifier(context).verify(credentials)) { + is Err -> { + callback(false) + } + is Ok -> { + val userAuthResponse = result.value + if (userAuthResponse.isRanger) { + CredentialKeeper(context).save(userAuthResponse) + } + callback(userAuthResponse.isRanger) + } + } + } + + override fun onFailure(error: AuthenticationException) { + callback(false) + } + }) + } +} \ No newline at end of file diff --git a/app/src/main/res/layout/fragment_terms_and_service.xml b/app/src/main/res/layout/fragment_terms_and_service.xml index 414866152..cde272683 100644 --- a/app/src/main/res/layout/fragment_terms_and_service.xml +++ b/app/src/main/res/layout/fragment_terms_and_service.xml @@ -47,6 +47,18 @@ app:layout_constraintStart_toStartOf="parent" app:layout_constraintBottom_toBottomOf="parent"/> + + \ No newline at end of file diff --git a/app/src/main/res/values/environment.xml b/app/src/main/res/values/environment.xml index ed63e8255..a924bfd0c 100644 --- a/app/src/main/res/values/environment.xml +++ b/app/src/main/res/values/environment.xml @@ -8,6 +8,7 @@ https://rfcx.eu.auth0.com/userinfo openid email profile offline_access https://rfcx.org/app_metadata + https://rfcx.org/user_metadata AIzaSyC-NLZPDq0jl8G5ZOvX48OeTylK8XR0M0s From 3d9922e5ca3f73d3b5b55731a272ea601c4f0a1c Mon Sep 17 00:00:00 2001 From: ratree Date: Thu, 19 Mar 2020 12:09:51 +0700 Subject: [PATCH 05/10] CA-2108 Fixed cannot invoke setValue on a background thread --- .../org/rfcx/ranger/view/login/TermsAndServiceFragment.kt | 6 +++--- .../org/rfcx/ranger/view/login/TermsAndServiceViewModel.kt | 6 +++--- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/app/src/main/java/org/rfcx/ranger/view/login/TermsAndServiceFragment.kt b/app/src/main/java/org/rfcx/ranger/view/login/TermsAndServiceFragment.kt index 1bd30496a..bcb0e8bbc 100644 --- a/app/src/main/java/org/rfcx/ranger/view/login/TermsAndServiceFragment.kt +++ b/app/src/main/java/org/rfcx/ranger/view/login/TermsAndServiceFragment.kt @@ -39,14 +39,14 @@ class TermsAndServiceFragment : BaseFragment() { if (state) { context?.let { it1 -> MainActivityNew.startActivity(it1, null) } } - termsProgressBar.visibility = View.GONE }, { termsProgressBar.visibility = View.GONE + submitButton.visibility = View.VISIBLE + }, { termsProgressBar.visibility = View.VISIBLE + submitButton.visibility = View.INVISIBLE }) - - }) } } diff --git a/app/src/main/java/org/rfcx/ranger/view/login/TermsAndServiceViewModel.kt b/app/src/main/java/org/rfcx/ranger/view/login/TermsAndServiceViewModel.kt index a9df10a3a..271052b24 100644 --- a/app/src/main/java/org/rfcx/ranger/view/login/TermsAndServiceViewModel.kt +++ b/app/src/main/java/org/rfcx/ranger/view/login/TermsAndServiceViewModel.kt @@ -15,7 +15,6 @@ import org.rfcx.ranger.data.remote.Result import org.rfcx.ranger.data.remote.terms.TermsUseCase import org.rfcx.ranger.entity.Err import org.rfcx.ranger.entity.Ok -import org.rfcx.ranger.entity.guardian.GuardianGroup import org.rfcx.ranger.entity.terms.TermsRequest import org.rfcx.ranger.entity.terms.TermsResponse import org.rfcx.ranger.util.CredentialKeeper @@ -41,12 +40,13 @@ class TermsAndServiceViewModel(private val context: Context, private val termsUs fun acceptTerms() { _consentGivenState.value = Result.Loading + termsUseCase.execute(object : DisposableSingleObserver() { override fun onSuccess(t: TermsResponse) { if (t.success) { refreshToken { - if(it){ - _consentGivenState.value = Result.Success(true) + if (it) { + _consentGivenState.postValue(Result.Success(true)) } } } From 49a8fd22c2f612b71034cb3c841ad47545ab7b1f Mon Sep 17 00:00:00 2001 From: ratree Date: Thu, 19 Mar 2020 13:29:03 +0700 Subject: [PATCH 06/10] CA-2108 User doesn't have "rfcxUser" role --- .../entity/user/InvitationCodeRequest.kt | 8 +++++++- .../java/org/rfcx/ranger/util/Preferences.kt | 1 + .../view/login/InvitationCodeViewModel.kt | 2 +- .../ranger/view/login/LoginActivityNew.kt | 8 ++++++++ .../rfcx/ranger/view/login/LoginFragment.kt | 2 +- .../rfcx/ranger/view/login/LoginViewModel.kt | 13 +++++++++--- .../view/login/TermsAndServiceFragment.kt | 20 +++++++++++++++++-- 7 files changed, 46 insertions(+), 8 deletions(-) diff --git a/app/src/main/java/org/rfcx/ranger/entity/user/InvitationCodeRequest.kt b/app/src/main/java/org/rfcx/ranger/entity/user/InvitationCodeRequest.kt index 460a8ca8c..5693553e7 100644 --- a/app/src/main/java/org/rfcx/ranger/entity/user/InvitationCodeRequest.kt +++ b/app/src/main/java/org/rfcx/ranger/entity/user/InvitationCodeRequest.kt @@ -4,5 +4,11 @@ import com.google.gson.annotations.SerializedName data class InvitationCodeRequest( @SerializedName("code") - val code: String + val code: String, + + @SerializedName("accept_terms") + val acceptTerms: Boolean, + + @SerializedName("app") + val app: String ) \ No newline at end of file diff --git a/app/src/main/java/org/rfcx/ranger/util/Preferences.kt b/app/src/main/java/org/rfcx/ranger/util/Preferences.kt index 81c14a6e3..2fde6f899 100644 --- a/app/src/main/java/org/rfcx/ranger/util/Preferences.kt +++ b/app/src/main/java/org/rfcx/ranger/util/Preferences.kt @@ -44,6 +44,7 @@ class Preferences(context: Context) { const val EMAIL_SUBSCRIBE = "${PREFIX}EMAIL_SUBSCRIBE" const val COORDINATES_FORMAT = "${PREFIX}COORDINATES_FORMAT" const val CONSENT_GIVEN = "${PREFIX}CONSENT_GIVEN" + const val IS_RANGER = "${PREFIX}IS_RANGER" } init { diff --git a/app/src/main/java/org/rfcx/ranger/view/login/InvitationCodeViewModel.kt b/app/src/main/java/org/rfcx/ranger/view/login/InvitationCodeViewModel.kt index 19dd9bd8b..f97ab5ecb 100644 --- a/app/src/main/java/org/rfcx/ranger/view/login/InvitationCodeViewModel.kt +++ b/app/src/main/java/org/rfcx/ranger/view/login/InvitationCodeViewModel.kt @@ -62,7 +62,7 @@ class InvitationCodeViewModel(private val context: Context, private val sendInvi override fun onError(e: Throwable) { callback(false) } - }, InvitationCodeRequest(code)) + }, InvitationCodeRequest(code, true, "RangerApp")) } private fun refreshToken(callback: (Boolean) -> Unit) { diff --git a/app/src/main/java/org/rfcx/ranger/view/login/LoginActivityNew.kt b/app/src/main/java/org/rfcx/ranger/view/login/LoginActivityNew.kt index 0c6074075..69e08a8dc 100644 --- a/app/src/main/java/org/rfcx/ranger/view/login/LoginActivityNew.kt +++ b/app/src/main/java/org/rfcx/ranger/view/login/LoginActivityNew.kt @@ -85,6 +85,13 @@ class LoginActivityNew : BaseActivity(), LoginListener { } + override fun openTermsAndServiceFragment() { + supportFragmentManager.beginTransaction() + .replace(loginContainer.id, TermsAndServiceFragment(), + "TermsAndServiceFragment").commit() + + } + private fun getEventFromIntentIfHave(intent: Intent?) :String? { if (intent?.hasExtra("event_guid") == true) { return intent.getStringExtra("event_guid") @@ -97,4 +104,5 @@ interface LoginListener { fun openMain() fun openInvitationCodeFragment() fun openSetUserNameFragmentFragment() + fun openTermsAndServiceFragment() } diff --git a/app/src/main/java/org/rfcx/ranger/view/login/LoginFragment.kt b/app/src/main/java/org/rfcx/ranger/view/login/LoginFragment.kt index 824cfe5eb..fd8db0b7d 100644 --- a/app/src/main/java/org/rfcx/ranger/view/login/LoginFragment.kt +++ b/app/src/main/java/org/rfcx/ranger/view/login/LoginFragment.kt @@ -90,8 +90,8 @@ class LoginFragment : BaseFragment() { loginViewModel.redirectPage.observe(this, Observer { loginRedirect -> when (loginRedirect) { LoginRedirect.MAIN_PAGE -> listener.openMain() - LoginRedirect.INVITE_CODE_PAGE -> listener.openInvitationCodeFragment() LoginRedirect.SET_USER_NAME -> listener.openSetUserNameFragmentFragment() + LoginRedirect.TERMS_AND_SERVICE -> listener.openTermsAndServiceFragment() else -> loading(false) } }) diff --git a/app/src/main/java/org/rfcx/ranger/view/login/LoginViewModel.kt b/app/src/main/java/org/rfcx/ranger/view/login/LoginViewModel.kt index d073adfe1..25fb593e1 100644 --- a/app/src/main/java/org/rfcx/ranger/view/login/LoginViewModel.kt +++ b/app/src/main/java/org/rfcx/ranger/view/login/LoginViewModel.kt @@ -159,18 +159,25 @@ class LoginViewModel(private val context: Context, private val checkUserTouchUse // } fun checkUserDetail(userAuthResponse: UserAuthResponse) { + val preferenceHelper = Preferences.getInstance(context) CredentialKeeper(context).save(userAuthResponse) checkUserTouchUseCase.execute(object : DisposableSingleObserver() { override fun onSuccess(t: Boolean) { + val isConsentGiven = preferenceHelper.getBoolean(Preferences.CONSENT_GIVEN) + if (userAuthResponse.isRanger) { - if (context.getUserNickname().substring(0, 1) == "+") { + preferenceHelper.putBoolean(Preferences.IS_RANGER, true) + if (!isConsentGiven) { + _redirectPage.postValue(LoginRedirect.TERMS_AND_SERVICE) + } else if (context.getUserNickname().substring(0, 1) == "+") { _redirectPage.postValue(LoginRedirect.SET_USER_NAME) } else { _redirectPage.postValue(LoginRedirect.MAIN_PAGE) } } else { - _redirectPage.postValue(LoginRedirect.INVITE_CODE_PAGE) + preferenceHelper.putBoolean(Preferences.IS_RANGER, false) + _redirectPage.postValue(LoginRedirect.TERMS_AND_SERVICE) } } @@ -183,5 +190,5 @@ class LoginViewModel(private val context: Context, private val checkUserTouchUse } enum class LoginRedirect { - MAIN_PAGE, INVITE_CODE_PAGE, SET_USER_NAME + MAIN_PAGE, SET_USER_NAME, TERMS_AND_SERVICE } \ No newline at end of file diff --git a/app/src/main/java/org/rfcx/ranger/view/login/TermsAndServiceFragment.kt b/app/src/main/java/org/rfcx/ranger/view/login/TermsAndServiceFragment.kt index bcb0e8bbc..9afc8d917 100644 --- a/app/src/main/java/org/rfcx/ranger/view/login/TermsAndServiceFragment.kt +++ b/app/src/main/java/org/rfcx/ranger/view/login/TermsAndServiceFragment.kt @@ -1,6 +1,7 @@ package org.rfcx.ranger.view.login +import android.content.Context import android.os.Bundle import android.view.LayoutInflater import android.view.View @@ -10,13 +11,19 @@ import kotlinx.android.synthetic.main.fragment_terms_and_service.* import org.koin.androidx.viewmodel.ext.android.viewModel import org.rfcx.ranger.R import org.rfcx.ranger.data.remote.success +import org.rfcx.ranger.util.Preferences import org.rfcx.ranger.view.MainActivityNew import org.rfcx.ranger.view.base.BaseFragment class TermsAndServiceFragment : BaseFragment() { - + lateinit var listener: LoginListener private val termsAndServiceViewModel: TermsAndServiceViewModel by viewModel() + override fun onAttach(context: Context) { + super.onAttach(context) + listener = (context as LoginListener) + } + override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? { return inflater.inflate(R.layout.fragment_terms_and_service, container, false) @@ -32,7 +39,16 @@ class TermsAndServiceFragment : BaseFragment() { } submitButton.setOnClickListener { - termsAndServiceViewModel.acceptTerms() + val preferenceHelper = context?.let { it1 -> Preferences.getInstance(it1) } + val isConsentGiven = preferenceHelper?.getBoolean(Preferences.IS_RANGER, false) + + if (isConsentGiven != null) { + if(isConsentGiven){ + termsAndServiceViewModel.acceptTerms() + } else { + listener.openInvitationCodeFragment() + } + } termsAndServiceViewModel.consentGivenState.observe(this, Observer { it.success({ state -> From 7e8d762e894d915a0c55776cc707e7b0b172d62b Mon Sep 17 00:00:00 2001 From: ratree Date: Thu, 19 Mar 2020 15:03:56 +0700 Subject: [PATCH 07/10] CA-2108 Fixed user doesn't have "rfcxUser" role --- .../rfcx/ranger/entity/user/InvitationCodeRequest.kt | 2 +- .../java/org/rfcx/ranger/util/CredentialVerifier.kt | 12 +++++++----- .../ranger/view/login/InvitationCodeViewModel.kt | 2 +- .../ranger/view/login/TermsAndServiceFragment.kt | 8 ++++---- 4 files changed, 13 insertions(+), 11 deletions(-) diff --git a/app/src/main/java/org/rfcx/ranger/entity/user/InvitationCodeRequest.kt b/app/src/main/java/org/rfcx/ranger/entity/user/InvitationCodeRequest.kt index 5693553e7..0f8fdbace 100644 --- a/app/src/main/java/org/rfcx/ranger/entity/user/InvitationCodeRequest.kt +++ b/app/src/main/java/org/rfcx/ranger/entity/user/InvitationCodeRequest.kt @@ -7,7 +7,7 @@ data class InvitationCodeRequest( val code: String, @SerializedName("accept_terms") - val acceptTerms: Boolean, + val acceptTerms: String, @SerializedName("app") val app: String diff --git a/app/src/main/java/org/rfcx/ranger/util/CredentialVerifier.kt b/app/src/main/java/org/rfcx/ranger/util/CredentialVerifier.kt index d304b93f9..916895157 100644 --- a/app/src/main/java/org/rfcx/ranger/util/CredentialVerifier.kt +++ b/app/src/main/java/org/rfcx/ranger/util/CredentialVerifier.kt @@ -66,17 +66,19 @@ class CredentialVerifier(val context: Context) { } val userUntrusted = Jwts.parser().parseClaimsJwt(withoutSignature) + var consentGivenRangerApp: String? = null + if (userUntrusted.body[userMetaDataKey] == null) { - return Err(getString(R.string.an_error_occurred)) + consentGivenRangerApp = null } val userMetadata = userUntrusted.body[userMetaDataKey] - if (userMetadata == null || !(userMetadata is HashMap<*, *>)) { - return Err(getString(R.string.an_error_occurred)) + if (userMetadata != null) { + if((userMetadata is HashMap<*, *>)) { + consentGivenRangerApp = userMetadata["consentGivenRangerApp"] as String? + } } - val consentGivenRangerApp: String? = userMetadata["consentGivenRangerApp"] as String? - when { guid.isNullOrEmpty() -> { return Err(getString(R.string.an_error_occurred)) diff --git a/app/src/main/java/org/rfcx/ranger/view/login/InvitationCodeViewModel.kt b/app/src/main/java/org/rfcx/ranger/view/login/InvitationCodeViewModel.kt index f97ab5ecb..6488951c6 100644 --- a/app/src/main/java/org/rfcx/ranger/view/login/InvitationCodeViewModel.kt +++ b/app/src/main/java/org/rfcx/ranger/view/login/InvitationCodeViewModel.kt @@ -62,7 +62,7 @@ class InvitationCodeViewModel(private val context: Context, private val sendInvi override fun onError(e: Throwable) { callback(false) } - }, InvitationCodeRequest(code, true, "RangerApp")) + }, InvitationCodeRequest(code, "true", "RangerApp")) } private fun refreshToken(callback: (Boolean) -> Unit) { diff --git a/app/src/main/java/org/rfcx/ranger/view/login/TermsAndServiceFragment.kt b/app/src/main/java/org/rfcx/ranger/view/login/TermsAndServiceFragment.kt index 9afc8d917..d4d12c208 100644 --- a/app/src/main/java/org/rfcx/ranger/view/login/TermsAndServiceFragment.kt +++ b/app/src/main/java/org/rfcx/ranger/view/login/TermsAndServiceFragment.kt @@ -40,10 +40,10 @@ class TermsAndServiceFragment : BaseFragment() { submitButton.setOnClickListener { val preferenceHelper = context?.let { it1 -> Preferences.getInstance(it1) } - val isConsentGiven = preferenceHelper?.getBoolean(Preferences.IS_RANGER, false) - - if (isConsentGiven != null) { - if(isConsentGiven){ + val isRanger = preferenceHelper?.getBoolean(Preferences.IS_RANGER, false) + + if (isRanger != null) { + if(isRanger){ termsAndServiceViewModel.acceptTerms() } else { listener.openInvitationCodeFragment() From 0bd136c0c0d2a2617a389cb6ecaf1364a29bbc10 Mon Sep 17 00:00:00 2001 From: ratree Date: Tue, 24 Mar 2020 10:03:44 +0700 Subject: [PATCH 08/10] CA-2108 Fixed spaces of line and some gap --- .../java/org/rfcx/ranger/data/remote/terms/TermsEndpoint.kt | 2 -- .../java/org/rfcx/ranger/data/remote/terms/TermsRepository.kt | 2 -- .../org/rfcx/ranger/data/remote/terms/TermsRepositoryImp.kt | 2 -- app/src/main/java/org/rfcx/ranger/util/CredentialVerifier.kt | 4 ++-- 4 files changed, 2 insertions(+), 8 deletions(-) diff --git a/app/src/main/java/org/rfcx/ranger/data/remote/terms/TermsEndpoint.kt b/app/src/main/java/org/rfcx/ranger/data/remote/terms/TermsEndpoint.kt index d3a1b06bb..3cc103161 100644 --- a/app/src/main/java/org/rfcx/ranger/data/remote/terms/TermsEndpoint.kt +++ b/app/src/main/java/org/rfcx/ranger/data/remote/terms/TermsEndpoint.kt @@ -7,8 +7,6 @@ import retrofit2.http.Body import retrofit2.http.POST interface TermsEndpoint { - @POST("v1/users/accept-terms") fun sendPayload(@Body body: TermsRequest): Single - } \ No newline at end of file diff --git a/app/src/main/java/org/rfcx/ranger/data/remote/terms/TermsRepository.kt b/app/src/main/java/org/rfcx/ranger/data/remote/terms/TermsRepository.kt index 59c67ee6c..ecf640291 100644 --- a/app/src/main/java/org/rfcx/ranger/data/remote/terms/TermsRepository.kt +++ b/app/src/main/java/org/rfcx/ranger/data/remote/terms/TermsRepository.kt @@ -5,7 +5,5 @@ import org.rfcx.ranger.entity.terms.TermsRequest import org.rfcx.ranger.entity.terms.TermsResponse interface TermsRepository { - fun sendBodyPayload(sendBody: TermsRequest): Single - } \ No newline at end of file diff --git a/app/src/main/java/org/rfcx/ranger/data/remote/terms/TermsRepositoryImp.kt b/app/src/main/java/org/rfcx/ranger/data/remote/terms/TermsRepositoryImp.kt index c95eff338..187976f79 100644 --- a/app/src/main/java/org/rfcx/ranger/data/remote/terms/TermsRepositoryImp.kt +++ b/app/src/main/java/org/rfcx/ranger/data/remote/terms/TermsRepositoryImp.kt @@ -5,9 +5,7 @@ import org.rfcx.ranger.entity.terms.TermsRequest import org.rfcx.ranger.entity.terms.TermsResponse class TermsRepositoryImp(private val termsEndpoint: TermsEndpoint) : TermsRepository { - override fun sendBodyPayload(sendBody: TermsRequest): Single { return termsEndpoint.sendPayload(sendBody) } - } \ No newline at end of file diff --git a/app/src/main/java/org/rfcx/ranger/util/CredentialVerifier.kt b/app/src/main/java/org/rfcx/ranger/util/CredentialVerifier.kt index 916895157..67e6403ec 100644 --- a/app/src/main/java/org/rfcx/ranger/util/CredentialVerifier.kt +++ b/app/src/main/java/org/rfcx/ranger/util/CredentialVerifier.kt @@ -74,7 +74,7 @@ class CredentialVerifier(val context: Context) { val userMetadata = userUntrusted.body[userMetaDataKey] if (userMetadata != null) { - if((userMetadata is HashMap<*, *>)) { + if ((userMetadata is HashMap<*, *>)) { consentGivenRangerApp = userMetadata["consentGivenRangerApp"] as String? } } @@ -85,7 +85,7 @@ class CredentialVerifier(val context: Context) { } else -> { return Ok(UserAuthResponse(guid, email, nickname, token, credentials.accessToken, credentials.refreshToken, roles, accessibleSites, defaultSite, picture, consentGivenRangerApp)) - } + } } } catch (e: Exception) { e.printStackTrace() From 75dd61ebb8a7c7bf07395837616a884885cf5030 Mon Sep 17 00:00:00 2001 From: ratree Date: Tue, 24 Mar 2020 10:04:52 +0700 Subject: [PATCH 09/10] CA-2108 Change to constant type --- .../org/rfcx/ranger/view/login/InvitationCodeViewModel.kt | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/app/src/main/java/org/rfcx/ranger/view/login/InvitationCodeViewModel.kt b/app/src/main/java/org/rfcx/ranger/view/login/InvitationCodeViewModel.kt index 6488951c6..edf8a1a26 100644 --- a/app/src/main/java/org/rfcx/ranger/view/login/InvitationCodeViewModel.kt +++ b/app/src/main/java/org/rfcx/ranger/view/login/InvitationCodeViewModel.kt @@ -62,7 +62,7 @@ class InvitationCodeViewModel(private val context: Context, private val sendInvi override fun onError(e: Throwable) { callback(false) } - }, InvitationCodeRequest(code, "true", "RangerApp")) + }, InvitationCodeRequest(code, USER_ACCEPTED, APP_NAME)) } private fun refreshToken(callback: (Boolean) -> Unit) { @@ -94,6 +94,11 @@ class InvitationCodeViewModel(private val context: Context, private val sendInvi } }) } + + companion object { + const val USER_ACCEPTED = "true" + const val APP_NAME = "RangerApp" + } } enum class SubmitState { From 81ce3fd0bab73754b7042c389667d325cfcd5f44 Mon Sep 17 00:00:00 2001 From: ratree Date: Tue, 24 Mar 2020 10:05:38 +0700 Subject: [PATCH 10/10] CA-2108 Added translate with other language --- app/src/main/res/values-es/strings.xml | 3 +++ app/src/main/res/values-in/strings.xml | 3 +++ app/src/main/res/values-nl/strings.xml | 3 +++ app/src/main/res/values-pt/strings.xml | 3 +++ app/src/main/res/values-th/strings.xml | 3 +++ 5 files changed, 15 insertions(+) diff --git a/app/src/main/res/values-es/strings.xml b/app/src/main/res/values-es/strings.xml index fda6fc7b6..1ca9bb070 100644 --- a/app/src/main/res/values-es/strings.xml +++ b/app/src/main/res/values-es/strings.xml @@ -46,6 +46,9 @@ Por favor, díganos su nombre Nombre + He leído y estoy de acuerdo con estos Términos y Servicio + Seguir + Un error ha ocurrido. Por favor intente de nuevo. A Ranger App le gustaría usar tu ubicación diff --git a/app/src/main/res/values-in/strings.xml b/app/src/main/res/values-in/strings.xml index 6c9fc4302..24a6335c7 100644 --- a/app/src/main/res/values-in/strings.xml +++ b/app/src/main/res/values-in/strings.xml @@ -46,6 +46,9 @@ Silakan beritahu kami nama Anda Nama + Saya telah membaca dan menyetujui Syarat dan Layanan + Terus + terjadi kesalahan, silahkan coba lagi Aplikasi Ranger ingin menggunakan lokasi Anda diff --git a/app/src/main/res/values-nl/strings.xml b/app/src/main/res/values-nl/strings.xml index 3268d6cf5..3ed715595 100644 --- a/app/src/main/res/values-nl/strings.xml +++ b/app/src/main/res/values-nl/strings.xml @@ -38,6 +38,9 @@ Vertel ons uw naam Naam + Ik heb gelezen en ga akkoord met deze voorwaarden en service + Doorgaan met + Er is een fout opgetreden. Probeer het opnieuw. Ranger App wilt uw locatie te gebruiken diff --git a/app/src/main/res/values-pt/strings.xml b/app/src/main/res/values-pt/strings.xml index b949ca664..f120d25d2 100644 --- a/app/src/main/res/values-pt/strings.xml +++ b/app/src/main/res/values-pt/strings.xml @@ -46,6 +46,9 @@ Por favor, diga-nos o seu nome Nome + Eu li e concordo com os Termos e Serviço + Continuar + Ocorreu um erro. Por favor, tente de novo. O aplicativo Ranger gostaria de usar sua localização diff --git a/app/src/main/res/values-th/strings.xml b/app/src/main/res/values-th/strings.xml index b007cfe6f..ab8a24b10 100644 --- a/app/src/main/res/values-th/strings.xml +++ b/app/src/main/res/values-th/strings.xml @@ -45,6 +45,9 @@ กรุณาบอกชื่อคุณกับเรา ชื่อ + ข้าพเจ้าได้อ่านและยอมรับข้อกำหนดและบริการดังกล่าว + ถัดไป + เกิดข้อผิดพลาด กรุณาลองใหม่อีกครั้ง แอป Ranger ต้องการใช้ตำแหน่งของคุณ