Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
83 changes: 52 additions & 31 deletions app/src/main/AndroidManifest.xml
Original file line number Diff line number Diff line change
Expand Up @@ -4,10 +4,11 @@
android:installLocation="auto">

<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE"
<uses-permission
android:name="android.permission.READ_EXTERNAL_STORAGE"
tools:ignore="ScopedStorage" />
<!-- <uses-permission android:name="android.permission.READ_MEDIA_IMAGES" />-->
<!-- <uses-permission android:name="android.permission.READ_MEDIA_VIDEO" />-->
<!-- <uses-permission android:name="android.permission.READ_MEDIA_IMAGES" />-->
<!-- <uses-permission android:name="android.permission.READ_MEDIA_VIDEO" />-->
<uses-permission android:name="android.permission.READ_MEDIA_AUDIO" />
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
Expand All @@ -23,6 +24,7 @@
<queries>
<package android:name="org.torproject.android" />
<package android:name="com.dropbox.android" />

<intent>
<action android:name="android.intent.action.OPEN_DOCUMENT" />
<category android:name="android.intent.category.OPENABLE" />
Expand All @@ -42,17 +44,17 @@
<application
android:name=".SaveApp"
android:allowBackup="false"
android:fullBackupContent="false"
android:dataExtractionRules="@xml/data_extraction_rules"
android:enableOnBackInvokedCallback="true"
android:fullBackupContent="false"
android:icon="@mipmap/ic_launcher"
android:label="@string/app_name"
android:networkSecurityConfig="@xml/network_security_config"
android:requestLegacyExternalStorage="true"
android:supportsRtl="true"
android:networkSecurityConfig="@xml/network_security_config"
android:theme="@style/AppTheme.NoActionBar"
tools:replace="android:icon,android:allowBackup"
tools:ignore="UnusedAttribute,LockedOrientationActivity">
tools:ignore="UnusedAttribute,LockedOrientationActivity"
tools:replace="android:icon,android:allowBackup">
<!-- task affinity lets us define within which 'task' does a activity belong to.
By default, the activity has the same task affinity as its root
Trail of bits ticket: https://github.com/OpenArchive/OA-Trail-of-Bits/issues/23
Expand Down Expand Up @@ -91,7 +93,8 @@
</intent-filter>
<intent-filter>
<action android:name="android.intent.action.SEND" />
<category android:name="android.intent.category.DEFAULT"/>
<category android:name="android.intent.category.DEFAULT" />

<data android:mimeType="application/*" />
<data android:mimeType="audio/*" />
<data android:mimeType="image/*" />
Expand All @@ -105,60 +108,63 @@
<activity
android:name=".services.webdav.WebDavActivity"
android:label="@string/title_activity_login"
android:windowSoftInputMode="adjustPan"
android:taskAffinity="" />
android:taskAffinity=""
android:windowSoftInputMode="adjustPan" />

<activity android:name=".features.internetarchive.presentation.InternetArchiveActivity"
<activity
android:name=".features.internetarchive.presentation.InternetArchiveActivity"
android:label="@string/title_activity_login"
android:taskAffinity="" />

<activity
android:name=".services.gdrive.GDriveActivity" />
<activity android:name=".services.gdrive.GDriveActivity" />

<activity
android:name=".features.settings.FoldersActivity"
android:label="@string/folders"
android:exported="false" />
android:exported="false"
android:label="@string/folders" />

<activity android:name=".features.settings.GeneralSettingsActivity"
android:label="@string/general"
<activity
android:name=".features.settings.GeneralSettingsActivity"
android:exported="false"
android:label="@string/general"
android:taskAffinity="" />

<activity android:name=".features.settings.ProofModeSettingsActivity"
android:label="@string/proofmode"
<activity
android:name=".features.settings.ProofModeSettingsActivity"
android:exported="false"
android:label="@string/proofmode"
android:taskAffinity="" />

<activity android:name=".features.media.PreviewActivity"
android:label="@string/preview_media"
<activity
android:name=".features.media.PreviewActivity"
android:exported="false"
android:label="@string/preview_media"
android:taskAffinity="" />

<activity
android:name=".features.media.ReviewActivity"
android:label="@string/edit_media_info"
android:windowSoftInputMode="stateHidden"
android:exported="false"
android:taskAffinity="" />
android:label="@string/edit_media_info"
android:taskAffinity=""
android:windowSoftInputMode="stateHidden" />

<activity
android:name=".features.onboarding.SpaceSetupActivity"
android:label="@string/title_activity_first_start"
android:windowSoftInputMode="adjustPan"
android:exported="false"
android:taskAffinity="" />
android:label="@string/title_activity_first_start"
android:taskAffinity=""
android:windowSoftInputMode="adjustPan" />

<activity
android:name=".features.onboarding.Onboarding23Activity"
android:noHistory="true"
android:exported="false"
android:noHistory="true"
android:taskAffinity="" />

<activity
android:name=".features.onboarding.Onboarding23InstructionsActivity"
android:noHistory="true"
android:exported="false"
android:noHistory="true"
android:taskAffinity="" />

<activity
Expand All @@ -182,6 +188,21 @@
android:label="@string/health_checks"
android:taskAffinity="" />

<activity
android:name=".features.settings.passcode.passcode_setup.PasscodeSetupActivity"
android:label="@string/passcode_setup"
android:screenOrientation="portrait"
android:taskAffinity=""
android:windowSoftInputMode="stateHidden" />

<activity
android:name=".features.settings.passcode.passcode_entry.PasscodeEntryActivity"
android:excludeFromRecents="true"
android:label="@string/passcode_entry"
android:noHistory="true"
android:screenOrientation="portrait"
android:windowSoftInputMode="stateHidden" />

<meta-data
android:name="DOMAIN_PACKAGE_NAME"
android:value="net.opendasharchive.openarchive.db" />
Expand Down Expand Up @@ -215,9 +236,9 @@

<service
android:name=".upload.UploadService"
android:permission="android.permission.BIND_JOB_SERVICE"
android:exported="false"
android:foregroundServiceType="dataSync"
android:exported="false" />
android:permission="android.permission.BIND_JOB_SERVICE" />

</application>

Expand Down
9 changes: 4 additions & 5 deletions app/src/main/java/net/opendasharchive/openarchive/SaveApp.kt
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ import info.guardianproject.netcipher.proxy.OrbotHelper
import net.opendasharchive.openarchive.core.di.coreModule
import net.opendasharchive.openarchive.core.di.featuresModule
import net.opendasharchive.openarchive.core.logger.AppLogger
import net.opendasharchive.openarchive.features.settings.passcode.PasscodeManager
import net.opendasharchive.openarchive.util.Prefs
import net.opendasharchive.openarchive.util.Theme
import org.koin.android.ext.koin.androidContext
Expand All @@ -24,16 +25,14 @@ class SaveApp : SugarApp() {

override fun onCreate() {
super.onCreate()

AppLogger.init(applicationContext, initDebugger = true)
registerActivityLifecycleCallbacks(PasscodeManager())
startKoin {
androidLogger(Level.DEBUG)
androidContext(this@SaveApp)
modules(coreModule, featuresModule)
}

if(BuildConfig.DEBUG) {
AppLogger.init(applicationContext, initDebugger = true)
}

val config = ImagePipelineConfig.newBuilder(this)
.setProgressiveJpegConfig(SimpleProgressiveJpegConfig())
Expand Down Expand Up @@ -61,4 +60,4 @@ class SaveApp : SugarApp() {

// oh.init()
}
}
}
Original file line number Diff line number Diff line change
@@ -1,9 +1,52 @@
package net.opendasharchive.openarchive.core.di

import android.content.Context
import net.opendasharchive.openarchive.features.internetarchive.internetArchiveModule
import net.opendasharchive.openarchive.features.settings.passcode.AppConfig
import net.opendasharchive.openarchive.features.settings.passcode.HapticManager
import net.opendasharchive.openarchive.features.settings.passcode.HashingStrategy
import net.opendasharchive.openarchive.features.settings.passcode.PBKDF2HashingStrategy
import net.opendasharchive.openarchive.features.settings.passcode.passcode_entry.PasscodeEntryViewModel
import net.opendasharchive.openarchive.features.settings.passcode.PasscodeRepository
import net.opendasharchive.openarchive.features.settings.passcode.passcode_setup.PasscodeSetupViewModel
import org.koin.core.module.dsl.viewModel
import org.koin.dsl.module

val featuresModule = module {
includes(internetArchiveModule)
// TODO: have some registry of feature modules

single {
AppConfig(
passcodeLength = 6,
enableHapticFeedback = true,
maxRetryLimitEnabled = false,
biometricAuthEnabled = false,
maxFailedAttempts = 5
)
}

single {
HapticManager(
appConfig = get<AppConfig>(),
)
}

single<HashingStrategy> {
PBKDF2HashingStrategy()
}

single { AppConfig() }

single {
val hashingStrategy: HashingStrategy = PBKDF2HashingStrategy()

PasscodeRepository(
context = get<Context>(),
config = get<AppConfig>(),
hashingStrategy = hashingStrategy
)
}
viewModel { PasscodeEntryViewModel(get(), get()) }
viewModel { PasscodeSetupViewModel(get(), get()) }
}
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ import android.view.WindowManager
import androidx.appcompat.app.AppCompatActivity
import net.opendasharchive.openarchive.util.Prefs

abstract class BaseActivity: AppCompatActivity() {
abstract class BaseActivity : AppCompatActivity() {

companion object {
const val EXTRA_DATA_SPACE = "space"
Expand All @@ -29,7 +29,8 @@ abstract class BaseActivity: AppCompatActivity() {
}

fun updateScreenshotPrevention() {
if (Prefs.prohibitScreenshots) {
if (Prefs.passcodeEnabled || Prefs.prohibitScreenshots) {
// Prevent screenshots and recent apps preview
window.setFlags(
WindowManager.LayoutParams.FLAG_SECURE,
WindowManager.LayoutParams.FLAG_SECURE
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ import net.opendasharchive.openarchive.features.internetarchive.infrastructure.m
import net.opendasharchive.openarchive.features.internetarchive.infrastructure.repository.InternetArchiveRepository
import net.opendasharchive.openarchive.features.internetarchive.presentation.details.InternetArchiveDetailsViewModel
import net.opendasharchive.openarchive.features.internetarchive.presentation.login.InternetArchiveLoginViewModel
import org.koin.androidx.viewmodel.dsl.viewModel
import org.koin.core.module.dsl.viewModel
import org.koin.dsl.module

typealias InternetArchiveGson = Gson
Expand Down
Original file line number Diff line number Diff line change
@@ -1,27 +1,88 @@
package net.opendasharchive.openarchive.features.settings

import android.app.Activity
import android.content.Intent
import android.os.Bundle
import android.view.MenuItem
import androidx.activity.result.contract.ActivityResultContracts
import androidx.appcompat.app.AlertDialog
import androidx.preference.Preference
import androidx.preference.PreferenceFragmentCompat
import androidx.preference.SwitchPreferenceCompat
import net.opendasharchive.openarchive.CleanInsightsManager
import net.opendasharchive.openarchive.R
import net.opendasharchive.openarchive.databinding.ActivitySettingsContainerBinding
import net.opendasharchive.openarchive.features.core.BaseActivity
import net.opendasharchive.openarchive.features.settings.passcode.PasscodeRepository
import net.opendasharchive.openarchive.features.settings.passcode.passcode_setup.PasscodeSetupActivity
import net.opendasharchive.openarchive.util.Prefs
import net.opendasharchive.openarchive.util.Theme
import org.koin.android.ext.android.inject


class GeneralSettingsActivity: BaseActivity() {

class Fragment: PreferenceFragmentCompat() {

private var mCiConsentPref: SwitchPreferenceCompat? = null
private val passcodeRepository by inject<PasscodeRepository>()

// private var mCiConsentPref: SwitchPreferenceCompat? = null

private var passcodePreference: SwitchPreferenceCompat? = null

private val activityResultLauncher = registerForActivityResult(
ActivityResultContracts.StartActivityForResult()
) { result ->
if (result.resultCode == Activity.RESULT_OK) {
val passcodeEnabled = result.data?.getBooleanExtra("passcode_enabled", false) ?: false
passcodePreference?.isChecked = passcodeEnabled
} else {
passcodePreference?.isChecked = false
}
}

override fun onCreatePreferences(savedInstanceState: Bundle?, rootKey: String?) {
setPreferencesFromResource(R.xml.prefs_general, rootKey)

passcodePreference = findPreference(Prefs.PASSCODE_ENABLED)

// findPreference<Preference>(Prefs.PASSCODE_ENABLED)?.setOnPreferenceChangeListener { _, newValue ->
// //Prefs.lockWithPasscode = newValue as Boolean
// if (newValue as? Boolean == true) {
//
// val intent = Intent(context, PasscodeSetupActivity::class.java)
// activityResultLauncher.launch(intent)
// }
// false
// }


passcodePreference?.setOnPreferenceChangeListener { _, newValue ->
val enabled = newValue as Boolean
if (enabled) {
// Launch PasscodeSetupActivity
val intent = Intent(context, PasscodeSetupActivity::class.java)
activityResultLauncher.launch(intent)
} else {
// Show confirmation dialog
AlertDialog.Builder(requireContext())
.setTitle("Disable Passcode")
.setMessage("Are you sure you want to disable the passcode?")
.setPositiveButton("Yes") { _, _ ->
passcodeRepository.clearPasscode()
passcodePreference?.isChecked = false

// Update the FLAG_SECURE dynamically
(activity as? BaseActivity)?.updateScreenshotPrevention()
}
.setNegativeButton("No") { _, _ ->
passcodePreference?.isChecked = true
}
.show()
}
// Return false to avoid the preference updating immediately
false
}

// findPreference<Preference>(Prefs.USE_TOR)?.setOnPreferenceChangeListener { _, newValue ->
// val activity = activity ?: return@setOnPreferenceChangeListener true
//
Expand Down Expand Up @@ -81,11 +142,11 @@ class GeneralSettingsActivity: BaseActivity() {
// }
}

override fun onResume() {
super.onResume()

mCiConsentPref?.isChecked = CleanInsightsManager.hasConsent()
}
// override fun onResume() {
// super.onResume()
//
// mCiConsentPref?.isChecked = CleanInsightsManager.hasConsent()
// }
}


Expand Down
Loading