Skip to content

Commit

Permalink
Merge pull request #321 from PermanentOrg/feature/VSP-1480
Browse files Browse the repository at this point in the history
2FA Enabled Status screen
  • Loading branch information
flaviahandrea-vsp authored Jan 13, 2025
2 parents 9661374 + eef168e commit 843de4c
Show file tree
Hide file tree
Showing 18 changed files with 388 additions and 27 deletions.
1 change: 1 addition & 0 deletions app/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -102,6 +102,7 @@ dependencies {
implementation 'net.openid:appauth:0.11.1'
implementation 'androidx.window:window-core:1.2.0'
implementation 'androidx.window:window:1.2.0'
implementation 'com.google.code.gson:gson:2.9.0'

//====================================== ARCHITECTURE COMPONENTS ===============================
implementation 'androidx.lifecycle:lifecycle-runtime-ktx:2.4.1'
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,6 @@ package org.permanent.permanent.network
import org.permanent.permanent.network.models.TwoFAVO

interface ITwoFAListener {
fun onSuccess(twoFAVO: TwoFAVO?)
fun onSuccess(twoFAVOList: List<TwoFAVO>?)
fun onFailed(error: String?)
}
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
package org.permanent.permanent.network.models

class TwoFAVO {
var methodId: String? = null
var method: String? = null
var value: String? = null // email or phone nr
var methodId: String? = null // ex: "VJ7F"
lateinit var method: String // "email" or "sms"
lateinit var value: String // "[email protected]" or "(917) 695 - 2195"
}
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,7 @@ class StelaAccountRepositoryImpl(context: Context) : StelaAccountRepository {
if (response.isSuccessful) {
val twoFAVOList = response.body()
if (twoFAVOList != null) {
listener.onSuccess(if (twoFAVOList.isEmpty()) null else twoFAVOList[0])
listener.onSuccess(twoFAVOList.ifEmpty { null })
} else {
listener.onFailed(appContext.getString(R.string.generic_error))
}
Expand Down
17 changes: 15 additions & 2 deletions app/src/main/java/org/permanent/permanent/ui/Extensions.kt
Original file line number Diff line number Diff line change
Expand Up @@ -11,13 +11,15 @@ import android.view.View
import android.view.inputmethod.InputMethodManager
import androidx.window.core.layout.WindowSizeClass
import androidx.window.layout.WindowMetricsCalculator
import net.openid.appauth.*
import com.google.gson.Gson
import com.google.gson.reflect.TypeToken
import org.permanent.permanent.network.models.TwoFAVO
import java.io.File
import java.io.FileOutputStream
import java.io.IOException
import java.io.OutputStream
import java.text.SimpleDateFormat
import java.util.*
import java.util.Date


fun Context.hideKeyboardFrom(windowToken: IBinder) {
Expand Down Expand Up @@ -162,3 +164,14 @@ fun Uri.getFile(context: Context, displayName: String): File? {
}
return null
}

// Serialize a list of TwoFAVO to JSON
fun List<TwoFAVO>.toJson(): String {
return Gson().toJson(this)
}

// Deserialize JSON to a list of TwoFAVO
fun String.toTwoFAVOList(): List<TwoFAVO> {
val type = object : TypeToken<List<TwoFAVO>>() {}.type
return Gson().fromJson(this, type)
}
15 changes: 15 additions & 0 deletions app/src/main/java/org/permanent/permanent/ui/PreferencesHelper.kt
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import org.permanent.permanent.CurrentArchivePermissionsManager
import org.permanent.permanent.models.AccessRole
import org.permanent.permanent.models.Archive
import org.permanent.permanent.models.ArchiveType
import org.permanent.permanent.network.models.TwoFAVO

const val PREFS_NAME = "permanent_preferences"
const val IS_USER_LOGGED_IN = "is_user_logged_in"
Expand Down Expand Up @@ -38,6 +39,7 @@ const val PREFS_UPLOAD_URL = "preferences_upload_url"
const val PREFS_DEEP_LINK_FILE_ARCHIVE_NR = "preferences_deep_link_file_archive_nr"
const val PREFS_DEEP_LINK_FOLDER_ARCHIVE_NR = "preferences_deep_link_folder_archive_nr"
const val PREFS_DEEP_LINK_FOLDER_LINK_ID = "preferences_deep_link_folder_link_id"
const val KEY_TWO_FA_LIST = "key_two_fa_list"

class PreferencesHelper(private val sharedPreferences: SharedPreferences) {

Expand Down Expand Up @@ -421,4 +423,17 @@ class PreferencesHelper(private val sharedPreferences: SharedPreferences) {
fun isTwoFAEnabled(): Boolean {
return sharedPreferences.getBoolean(IS_TWO_FA_ENABLED, false)
}

fun setTwoFAList(twoFAList: List<TwoFAVO>) {
with(sharedPreferences.edit()) {
putString(KEY_TWO_FA_LIST, twoFAList.toJson())
apply()
}
}

// Retrieve 2FA methods
fun getTwoFAList(): List<TwoFAVO> {
val json = sharedPreferences.getString(KEY_TWO_FA_LIST, null) ?: return emptyList()
return json.toTwoFAVOList().sortedByDescending { it.method == "sms" }
}
}
Original file line number Diff line number Diff line change
@@ -1,8 +1,10 @@
package org.permanent.permanent.ui.login

import android.app.AlertDialog
import android.content.Context
import android.content.Intent
import android.os.Bundle
import android.provider.Settings
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
Expand All @@ -12,6 +14,7 @@ import androidx.lifecycle.Observer
import androidx.lifecycle.ViewModelProvider
import org.permanent.permanent.EventType
import org.permanent.permanent.EventsManager
import org.permanent.permanent.R
import org.permanent.permanent.ui.PREFS_NAME
import org.permanent.permanent.ui.PermanentBaseFragment
import org.permanent.permanent.ui.PreferencesHelper
Expand Down Expand Up @@ -95,6 +98,17 @@ class AuthenticationFragment : PermanentBaseFragment() {
startArchiveOnboardingActivity()
}

private val showBiometricsDialogObserver = Observer<Boolean> {
AlertDialog.Builder(context).apply {
setTitle(context.getString(R.string.login_biometric_error_no_biometrics_enrolled_title))
setMessage(context.getString(R.string.login_biometric_error_no_biometrics_enrolled_message))
setPositiveButton(R.string.yes_button) { _, _ -> startActivity(Intent(Settings.ACTION_SECURITY_SETTINGS)) }
setNegativeButton(R.string.button_cancel) { _, _ -> }
create()
show()
}
}

private fun startArchiveOnboardingActivity() {
startActivity(Intent(context, ArchiveOnboardingActivity::class.java))
activity?.finish()
Expand Down Expand Up @@ -125,13 +139,15 @@ class AuthenticationFragment : PermanentBaseFragment() {
viewModel.getOnSignedIn().observe(this, onSignedIn)
viewModel.getOnAuthenticated().observe(this, onAuthenticated)
viewModel.getOnUserMissingDefaultArchive().observe(this, userMissingDefaultArchiveObserver)
viewModel.getOnShowEnrollBiometricsDialog().observe(this, showBiometricsDialogObserver)
}

override fun disconnectViewModelEvents() {
viewModel.getOnAccountCreated().removeObserver(onAccountCreated)
viewModel.getOnSignedIn().removeObserver(onSignedIn)
viewModel.getOnAuthenticated().removeObserver(onAuthenticated)
viewModel.getOnUserMissingDefaultArchive().removeObserver(userMissingDefaultArchiveObserver)
viewModel.getOnShowEnrollBiometricsDialog().removeObserver(showBiometricsDialogObserver)
}

override fun onResume() {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,19 +6,24 @@ import android.view.View
import android.view.ViewGroup
import androidx.compose.material3.MaterialTheme
import androidx.compose.ui.platform.ComposeView
import androidx.lifecycle.ViewModelProvider
import org.permanent.permanent.ui.PermanentBaseFragment
import org.permanent.permanent.ui.settings.compose.TwoStepVerificationScreen
import org.permanent.permanent.ui.settings.compose.TwoStepVerificationStatefulScreen
import org.permanent.permanent.viewmodels.TwoStepVerificationViewModel

class TwoStepVerificationFragment : PermanentBaseFragment() {

private lateinit var viewModel: TwoStepVerificationViewModel

override fun onCreateView(
inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?
): View {
viewModel = ViewModelProvider(this)[TwoStepVerificationViewModel::class.java]

return ComposeView(requireContext()).apply {
setContent {
MaterialTheme {
TwoStepVerificationScreen { //TODO: onAddTwoStepBtn
}
TwoStepVerificationStatefulScreen(viewModel)
}
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ import androidx.compose.ui.unit.sp
import org.permanent.permanent.R

@Composable
fun TwoStepVerificationScreen(
fun TwoStepVerificationDisabledScreen(
onAddTwoStepVerificationClick: () -> Unit
) {
Column(
Expand Down
Loading

0 comments on commit 843de4c

Please sign in to comment.