mirror of
https://github.com/Darkrock-Studios/hammer-editor.git
synced 2026-08-05 07:40:00 +00:00
Replace the plaintext FileAuthTokenStore binding with platform-specific encrypted stores behind the same AuthTokenStore interface, wired via a new expect/actual authTokenStoreModule. Android: EncryptedSharedPrefsAuthTokenStore backed by EncryptedSharedPreferences with a Keystore-backed AES256_GCM master key (androidx.security:security-crypto). Desktop: EncryptedFileAuthTokenStore writes the token-map JSON as AES/GCM/NoPadding to the config directory. The key is derived (PBKDF2WithHmacSHA256) from the OS user name and home dir plus a static salt, with no key file on disk, so a copied token file is useless on another machine or user. A random 12-byte IV is prepended per write and owner-only POSIX perms are applied best-effort. Decryption failure is treated as no tokens rather than crashing. This guards against casual disk scraping and off-machine copies, not same-user local malware that can re-derive the key. iOS: still uses the plaintext file store pending a Keychain-backed implementation (TODO marker in the iOS binding). Migration: a legacy plaintext auth_tokens.json from an intermediate build is imported into the encrypted store and deleted on first access; existing encrypted tokens win on key collision so a stale plaintext entry cannot clobber a fresh session.
203 lines
No EOL
5.2 KiB
Kotlin
203 lines
No EOL
5.2 KiB
Kotlin
import org.jetbrains.kotlin.gradle.ExperimentalKotlinGradlePluginApi
|
|
import org.jetbrains.kotlin.gradle.dsl.JvmTarget
|
|
|
|
plugins {
|
|
alias(libs.plugins.kotlin.multiplatform)
|
|
alias(libs.plugins.kotlin.serialization)
|
|
alias(libs.plugins.kotlin.powerassert)
|
|
alias(libs.plugins.android.kotlin.multiplatform.library)
|
|
alias(libs.plugins.kotlin.parcelize)
|
|
alias(libs.plugins.jetbrains.kover)
|
|
alias(libs.plugins.jetbrains.compose)
|
|
alias(libs.plugins.compose.compiler)
|
|
alias(libs.plugins.buildconfig)
|
|
}
|
|
|
|
group = "com.darkrockstudios.apps.hammer"
|
|
version = libs.versions.app.get()
|
|
|
|
kotlin {
|
|
androidLibrary {
|
|
namespace = "com.darkrockstudios.apps.hammer.common"
|
|
compileSdk = libs.versions.android.sdk.compile.get().toInt()
|
|
minSdk = libs.versions.android.sdk.min.get().toInt()
|
|
|
|
androidResources {
|
|
enable = true
|
|
}
|
|
|
|
compilerOptions {
|
|
jvmTarget.set(JvmTarget.fromTarget(libs.versions.jvm.get()))
|
|
}
|
|
|
|
withHostTest {}
|
|
}
|
|
jvm("desktop") {
|
|
compilerOptions {
|
|
jvmTarget.set(JvmTarget.fromTarget(libs.versions.jvm.get()))
|
|
}
|
|
}
|
|
|
|
iosArm64()
|
|
iosSimulatorArm64()
|
|
|
|
applyDefaultHierarchyTemplate()
|
|
|
|
sourceSets {
|
|
all {
|
|
languageSettings {
|
|
optIn("kotlin.io.encoding.ExperimentalEncodingApi")
|
|
optIn("kotlin.uuid.ExperimentalUuidApi")
|
|
}
|
|
}
|
|
|
|
val commonMain by getting {
|
|
resources.srcDirs("resources")
|
|
|
|
dependencies {
|
|
api(project(":base"))
|
|
|
|
api(libs.decompose)
|
|
api(libs.napier)
|
|
api(libs.coroutines.core)
|
|
api(project.dependencies.platform(libs.koin.bom.get()))
|
|
api(libs.koin.core)
|
|
api(libs.okio)
|
|
|
|
implementation(libs.bundles.ktor.client)
|
|
implementation(libs.ktor.serialization.kotlinx.json)
|
|
|
|
api(libs.serialization.core)
|
|
api(libs.serialization.json)
|
|
api(libs.kotlinx.datetime)
|
|
api(libs.kotlinx.collections.immutable)
|
|
implementation(libs.tomlkt)
|
|
api(libs.bundles.essenty)
|
|
implementation(libs.cache4k)
|
|
implementation(libs.jetbrains.compose.runtime)
|
|
implementation(libs.jetbrains.compose.components.resources)
|
|
implementation(libs.kotlinx.atomicfu)
|
|
implementation(libs.aboutlibraries.core)
|
|
implementation(libs.multiplatform.settings)
|
|
implementation(libs.platform.spellcheckerkt)
|
|
implementation(libs.kmp.zip)
|
|
implementation(libs.kmp.zip.okio)
|
|
implementation(libs.markdown)
|
|
implementation(libs.xmlutil.core)
|
|
implementation(libs.epub4kmp.core)
|
|
implementation(libs.pdfkmp)
|
|
implementation(libs.kotlinx.html)
|
|
}
|
|
}
|
|
val commonTest by getting {
|
|
dependencies {
|
|
implementation(kotlin("test"))
|
|
implementation(libs.koin.test)
|
|
implementation(libs.okio.fakefilesystem)
|
|
implementation(libs.kotlin.reflect)
|
|
}
|
|
}
|
|
val jvmMain by creating {
|
|
dependsOn(commonMain)
|
|
}
|
|
val jvmTest by creating {
|
|
dependsOn(commonTest)
|
|
}
|
|
val androidMain by getting {
|
|
dependsOn(jvmMain)
|
|
dependencies {
|
|
api(libs.androidx.core.ktx)
|
|
api(libs.coroutines.android)
|
|
implementation(libs.koin.android)
|
|
implementation(libs.ktor.client.okhttp)
|
|
implementation(libs.moko.permissions)
|
|
implementation(libs.moko.permissions.storage)
|
|
implementation(libs.androidx.security.crypto)
|
|
}
|
|
}
|
|
val iosMain by getting {
|
|
dependencies {
|
|
api(libs.decompose)
|
|
api(libs.bundles.essenty)
|
|
api(libs.ktor.client.darwin)
|
|
}
|
|
}
|
|
val iosTest by getting
|
|
val androidHostTest by getting {
|
|
dependencies {
|
|
implementation(kotlin("test"))
|
|
}
|
|
}
|
|
val desktopMain by getting {
|
|
dependsOn(jvmMain)
|
|
dependencies {
|
|
implementation(libs.slf4j.simple)
|
|
api(libs.serialization.jvm)
|
|
api(libs.coroutines.swing)
|
|
implementation(libs.appdirs)
|
|
implementation(libs.ktor.client.java)
|
|
implementation(libs.turbine)
|
|
}
|
|
}
|
|
val desktopTest by getting {
|
|
dependsOn(jvmTest)
|
|
dependencies {
|
|
implementation(libs.bundles.junit.jupiter)
|
|
implementation(libs.coroutines.test)
|
|
implementation(libs.mockk)
|
|
implementation(libs.koin.test)
|
|
implementation(libs.koin.test.junit5)
|
|
implementation(compose.desktop.currentOs)
|
|
implementation(libs.poi.ooxml)
|
|
implementation(libs.ktor.client.mock)
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
compose.resources {
|
|
publicResClass = true
|
|
packageOfResClass = "com.darkrockstudios.apps.hammer"
|
|
}
|
|
|
|
buildConfig {
|
|
useKotlinOutput { internalVisibility = false }
|
|
packageName("com.darkrockstudios.apps.hammer.common")
|
|
|
|
val isDebug = project.findProperty("hammer.debug")?.toString()?.toBoolean() ?: false
|
|
buildConfigField("Boolean", "DEBUG", isDebug.toString())
|
|
|
|
// Mirrors the F-Droid detection in settings.gradle.kts so runtime code can branch
|
|
// on the build channel (e.g. public-storage projects, which Google Play disallows).
|
|
val isFDroid = project.findProperty("fdroid")?.toString()?.isNotEmpty() == true ||
|
|
System.getenv("FDROID_BUILD") != null
|
|
buildConfigField("Boolean", "FDROID", isFDroid.toString())
|
|
}
|
|
|
|
kover {
|
|
reports {
|
|
filters {
|
|
includes {
|
|
packages("com.darkrockstudios.apps.hammer.*")
|
|
}
|
|
excludes {
|
|
packages(
|
|
"com.darkrockstudios.apps.hammer.util.*",
|
|
"com.darkrockstudios.apps.hammer.parcelize.*",
|
|
"com.darkrockstudios.apps.hammer.fileio.*",
|
|
)
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
@OptIn(ExperimentalKotlinGradlePluginApi::class)
|
|
powerAssert {
|
|
functions = listOf(
|
|
"kotlin.assert",
|
|
"kotlin.test.assertTrue",
|
|
"kotlin.test.assertEquals",
|
|
"kotlin.test.assertNull"
|
|
)
|
|
includedSourceSets = listOf("commonTest", "desktopTest")
|
|
} |