fix: resolve CI lint failures (spotless + detekt)

- spotlessApply across core:repository, core:service, core:ui
- Android LockdownPassphraseStoreImpl: inline requirePrefs() body
  (FunctionSignature)
- JVM LockdownPassphraseStoreImpl: suppress ReturnCount on deserialize()
This commit is contained in:
James Rich
2026-05-13 16:50:03 -05:00
parent 1d24b38746
commit 431f0d77bf
5 changed files with 11 additions and 10 deletions

View File

@@ -32,10 +32,10 @@ interface LockdownCoordinator {
fun onDisconnect()
/**
* Lifecycle hook called on every config_complete_id from the device.
*
* Currently a no-op; retained so implementations can react to config-complete in the future without changing the
* public contract.
* Lifecycle hook called on every config_complete_id from the device.
*
* Currently a no-op; retained so implementations can react to config-complete in the future without changing the
* public contract.
*/
fun onConfigComplete()

View File

@@ -52,8 +52,7 @@ class LockdownPassphraseStoreImpl(app: Application) : LockdownPassphraseStore {
}
}
private fun requirePrefs(): SharedPreferences =
prefs ?: error("Encrypted passphrase store unavailable")
private fun requirePrefs(): SharedPreferences = prefs ?: error("Encrypted passphrase store unavailable")
@Suppress("ReturnCount")
override fun getPassphrase(deviceAddress: String): StoredPassphrase? {

View File

@@ -34,8 +34,8 @@ import javax.crypto.spec.GCMParameterSpec
* File-backed encrypted passphrase store for JVM/Desktop.
*
* Uses a PKCS12 KeyStore to hold an AES-256 master key and AES-256-GCM to encrypt each passphrase entry. Entries are
* stored as individual `.enc` files under `$MESHTASTIC_DATA_DIR/lockdown/` (default: `~/.meshtastic/lockdown/`),
* keyed by a sanitized device address.
* stored as individual `.enc` files under `$MESHTASTIC_DATA_DIR/lockdown/` (default: `~/.meshtastic/lockdown/`), keyed
* by a sanitized device address.
*
* The keystore password is fixed because the threat model mirrors Android's `EncryptedSharedPreferences`: file-system
* permission is the primary access control; the encryption layer protects data at rest against casual file browsing or
@@ -117,6 +117,7 @@ class LockdownPassphraseStoreImpl : LockdownPassphraseStore {
private fun serialize(passphrase: String, boots: Int, hours: Int): ByteArray =
"$boots\n$hours\n$passphrase".encodeToByteArray()
@Suppress("ReturnCount")
private fun deserialize(plaintext: ByteArray): StoredPassphrase? {
val text = plaintext.decodeToString()
val lines = text.split("\n", limit = 3)
@@ -163,6 +164,7 @@ class LockdownPassphraseStoreImpl : LockdownPassphraseStore {
private const val KEYSTORE_FILE = "keystore.p12"
private const val KEYSTORE_TYPE = "PKCS12"
private const val KEY_ALIAS = "lockdown_master"
// Intentional: this mirrors the documented desktop threat model for at-rest protection only.
private val KEYSTORE_PASSWORD = "meshtastic-lockdown".toCharArray()
private const val AES_ALGORITHM = "AES"

View File

@@ -56,4 +56,4 @@ class LockdownPassphraseStoreImplTest {
assertNull(store.getPassphrase("AA:BB:CC:DD"))
}
}
}

View File

@@ -52,6 +52,7 @@ import org.meshtastic.core.model.toEventEdition
import org.meshtastic.core.model.util.dispatchMeshtasticUri
import org.meshtastic.core.navigation.DeepLinkRouter
import org.meshtastic.core.repository.FirmwareReleaseRepository
import org.meshtastic.core.repository.LockdownPassphraseStore
import org.meshtastic.core.repository.MeshLogRepository
import org.meshtastic.core.repository.NodeRepository
import org.meshtastic.core.repository.NotificationManager
@@ -59,7 +60,6 @@ import org.meshtastic.core.repository.PacketRepository
import org.meshtastic.core.repository.RadioInterfaceService
import org.meshtastic.core.repository.ServiceRepository
import org.meshtastic.core.repository.UiPrefs
import org.meshtastic.core.repository.LockdownPassphraseStore
import org.meshtastic.core.resources.Res
import org.meshtastic.core.resources.client_notification
import org.meshtastic.core.resources.compromised_keys