From 601ff4acb62180daa3f7130d8d7e965fc7e1a16e Mon Sep 17 00:00:00 2001 From: Elie Gambache Date: Tue, 17 Jun 2025 18:27:52 +0300 Subject: [PATCH 1/7] Update dependencies to replace `gplay.scrapper` with `androidappstorekit.gplay` library - Migrated all references to `gplay.scrapper` and `gplay.scrapper.core` to the new `androidappstorekit.gplay` library. - Updated dependency versions in `build.gradle.kts` and `libs.versions.toml`. - Fixed imports in DAO classes for `GooglePlayApplicationInfo`. - Adjusted README section anchors for consistency. --- README.MD | 16 ++++++++-------- dao/build.gradle.kts | 3 ++- .../database/dao/AppInfoWithExtras.kt | 2 +- .../kdroidfilter/database/dao/ApplicationsDao.kt | 2 +- downloader/build.gradle.kts | 3 ++- generators/store/build.gradle.kts | 3 +-- gradle/libs.versions.toml | 12 ++++++------ sample/composeApp/build.gradle.kts | 3 +-- 8 files changed, 22 insertions(+), 22 deletions(-) diff --git a/README.MD b/README.MD index e76559e..8e013b2 100644 --- a/README.MD +++ b/README.MD @@ -5,8 +5,8 @@ ## πŸ“‘ Table of Contents - [Introduction](#introduction) - [Available Modes](#here-is-a-simple-tree-of-all-available-modes-) -- [Directory Structure](#️-directory-structure) -- [Supported Policy Types & Templates](#πŸ“-supported-policy-types--templates) +- [Directory Structure](#️-directory-structure-) +- [Supported Policy Types & Templates](#-supported-policy-types--templates) - [FixedPolicy](#1️⃣-fixedpolicy) - [ModeBasedPolicy](#2️⃣-modebasedpolicy) - [MultiModePolicy](#3️⃣-multimodePolicy) @@ -15,14 +15,14 @@ - [Validating JSON Files](#validating-json-files) - [Questions & Answers](#❓-questions--answers) - [What is the difference between LOCAL_ONLY and OFFLINE?](#what-is-the-difference-between-local_only-and-offline) - - [Optional Flags: Content and Risk Warnings](#⚠️-optional-flags-content-and-risk-warnings) + - [Optional Flags: Content and Risk Warnings](#-optional-flags-content-and-risk-warnings) - [Why would an app require Play Store installation?](#why-would-an-app-require-play-store-installation) - - [Example: Risky Applications](#πŸ”„-example-risky-applications) + - [Example: Risky Applications](#-example-risky-applications) - [Importing KDroid Database Modules](#importing-kdroid-database-modules) - - [Core Module](#core-module) - - [Localization Module](#localization-module) - - [Downloader Module](#downloader-module) - - [DAO Module](#dao-module) + - [Core Module](#core-module-) + - [Localization Module](#localization-module-) + - [Downloader Module](#downloader-module-) + - [DAO Module](#dao-module-) ## Introduction diff --git a/dao/build.gradle.kts b/dao/build.gradle.kts index b738307..2195c5d 100644 --- a/dao/build.gradle.kts +++ b/dao/build.gradle.kts @@ -57,7 +57,8 @@ kotlin { commonMain.dependencies { api(project(":core")) implementation(project(":localization")) - api(libs.gplay.scrapper.core) + api(libs.android.appstore.kit.gplay.scrapper) + implementation(libs.kotlinx.coroutines.core) implementation(libs.kotlinx.serialization.json) implementation(libs.kermit) diff --git a/dao/src/commonMain/kotlin/io/github/kdroidfilter/database/dao/AppInfoWithExtras.kt b/dao/src/commonMain/kotlin/io/github/kdroidfilter/database/dao/AppInfoWithExtras.kt index 965b24c..f1a13da 100644 --- a/dao/src/commonMain/kotlin/io/github/kdroidfilter/database/dao/AppInfoWithExtras.kt +++ b/dao/src/commonMain/kotlin/io/github/kdroidfilter/database/dao/AppInfoWithExtras.kt @@ -1,6 +1,6 @@ package io.github.kdroidfilter.database.dao -import com.kdroid.gplayscrapper.core.model.GooglePlayApplicationInfo +import io.github.kdroidfilter.androidappstorekit.gplay.core.model.GooglePlayApplicationInfo /** * Extended class to add additional information to the GooglePlayApplicationInfo model diff --git a/dao/src/commonMain/kotlin/io/github/kdroidfilter/database/dao/ApplicationsDao.kt b/dao/src/commonMain/kotlin/io/github/kdroidfilter/database/dao/ApplicationsDao.kt index df42734..10a9e35 100644 --- a/dao/src/commonMain/kotlin/io/github/kdroidfilter/database/dao/ApplicationsDao.kt +++ b/dao/src/commonMain/kotlin/io/github/kdroidfilter/database/dao/ApplicationsDao.kt @@ -1,6 +1,6 @@ package io.github.kdroidfilter.database.dao -import com.kdroid.gplayscrapper.core.model.GooglePlayApplicationInfo +import io.github.kdroidfilter.androidappstorekit.gplay.core.model.GooglePlayApplicationInfo import io.github.kdroidfilter.database.store.Database import io.github.kdroidfilter.database.core.AppCategory import io.github.kdroidfilter.database.localization.LocalizedAppCategory diff --git a/downloader/build.gradle.kts b/downloader/build.gradle.kts index 7550a50..ab71aab 100644 --- a/downloader/build.gradle.kts +++ b/downloader/build.gradle.kts @@ -38,7 +38,8 @@ kotlin { commonMain.dependencies { api(project(":core")) - api(libs.gplay.scrapper) + api("io.github.kdroidfilter.androidappstorekit.gplay:scrapper:0.4.0") + implementation(libs.kotlinx.coroutines.core) implementation(libs.kermit) implementation(libs.platform.tools.release.fetcher) diff --git a/generators/store/build.gradle.kts b/generators/store/build.gradle.kts index 89fa7b7..ad6ad23 100644 --- a/generators/store/build.gradle.kts +++ b/generators/store/build.gradle.kts @@ -22,8 +22,7 @@ kotlin { implementation(libs.kotlinx.coroutines.test) implementation(libs.kotlinx.serialization.json) implementation(libs.kermit) - implementation(libs.gplay.scrapper) - implementation(libs.gplay.scrapper.core) + implementation(libs.android.appstore.kit.gplay.core) implementation(libs.platform.tools.release.fetcher) implementation(libs.kotlinx.coroutines.swing) implementation(libs.sqlite.jdbc) diff --git a/gradle/libs.versions.toml b/gradle/libs.versions.toml index 13c8a74..90790d3 100644 --- a/gradle/libs.versions.toml +++ b/gradle/libs.versions.toml @@ -6,20 +6,20 @@ kotlin = "2.1.21" agp = "8.9.3" kotlinx-coroutines = "1.10.2" kotlinx-serialization = "1.8.1" -kermit = "2.0.5" -koin = "4.0.4" +kermit = "2.0.6" +koin = "4.1.0" compose = "1.8.1" androidx-activityCompose = "1.10.1" mavenSlf4jProvider = "3.9.9" netfreetoolsCertificates = "1.0.1" sqliteJdbc = "3.49.1.0" -platformtools = "0.3.4" +platformtools = "0.4.0" ktor = "3.1.3" sqlDelight = "2.1.0" sqlJs = "1.8.0" webPackPlugin = "9.1.0" -gplayscrapper = "0.3.2" kotlinxBrowserWasmJs = "0.3" +androidAppstoreKit = "0.4.0" [libraries] @@ -41,8 +41,8 @@ androidx-activityCompose = { module = "androidx.activity:activity-compose", vers maven-slf4j-provider = { module = "org.apache.maven:maven-slf4j-provider", version.ref = "mavenSlf4jProvider" } netfreetools-certificates = { module = "io.github.kdroidfilter:netfreetools.certificates", version.ref = "netfreetoolsCertificates" } sqlite-jdbc = { module = "org.xerial:sqlite-jdbc", version.ref = "sqliteJdbc" } -gplay-scrapper = { module = "io.github.kdroidfilter:gplayscrapper ", version.ref = "gplayscrapper"} -gplay-scrapper-core = { module = "io.github.kdroidfilter:gplayscrapper-core", version.ref = "gplayscrapper"} +android-appstore-kit-gplay-scrapper = { module = "io.github.kdroidfilter.androidappstorekit.gplay:core", version.ref ="androidAppstoreKit"} +android-appstore-kit-gplay-core = { module ="io.github.kdroidfilter.androidappstorekit.gplay:scrapper", version.ref = "androidAppstoreKit"} platform-tools-release-fetcher = {module = "io.github.kdroidfilter:platformtools.releasefetcher", version.ref = "platformtools"} ktor-client-core = { module = "io.ktor:ktor-client-core", version.ref = "ktor" } diff --git a/sample/composeApp/build.gradle.kts b/sample/composeApp/build.gradle.kts index 8b02f30..334d433 100644 --- a/sample/composeApp/build.gradle.kts +++ b/sample/composeApp/build.gradle.kts @@ -30,8 +30,7 @@ kotlin { implementation(compose.materialIconsExtended) implementation(libs.kermit) implementation(libs.kotlinx.serialization.json) - implementation(libs.gplay.scrapper.core) - + implementation(libs.android.appstore.kit.gplay.scrapper) implementation(libs.ktor.client.core) implementation(libs.platform.tools.release.fetcher) implementation(libs.coil.compose) From e5ebfd0a4d7e6e52a4c660462c392264412b643e Mon Sep 17 00:00:00 2001 From: Elie Gambache Date: Wed, 18 Jun 2025 12:37:20 +0300 Subject: [PATCH 2/7] Migrate from `androidappstorekit.gplay` to `storekit` library - Updated dependencies and versions in `build.gradle.kts` and `libs.versions.toml`. - Fixed imports for `GooglePlayApplicationInfo` in DAO classes. - Replaced all references to the older library with the new `storekit` implementation. --- dao/build.gradle.kts | 2 +- .../kdroidfilter/database/dao/AppInfoWithExtras.kt | 2 +- .../kdroidfilter/database/dao/ApplicationsDao.kt | 2 +- generators/store/build.gradle.kts | 2 +- gradle/libs.versions.toml | 12 ++++++++---- sample/composeApp/build.gradle.kts | 6 +++++- 6 files changed, 17 insertions(+), 9 deletions(-) diff --git a/dao/build.gradle.kts b/dao/build.gradle.kts index 2195c5d..9c9766e 100644 --- a/dao/build.gradle.kts +++ b/dao/build.gradle.kts @@ -57,7 +57,7 @@ kotlin { commonMain.dependencies { api(project(":core")) implementation(project(":localization")) - api(libs.android.appstore.kit.gplay.scrapper) + api(libs.storekit.gplayscrapper) implementation(libs.kotlinx.coroutines.core) implementation(libs.kotlinx.serialization.json) diff --git a/dao/src/commonMain/kotlin/io/github/kdroidfilter/database/dao/AppInfoWithExtras.kt b/dao/src/commonMain/kotlin/io/github/kdroidfilter/database/dao/AppInfoWithExtras.kt index f1a13da..2cbbb7f 100644 --- a/dao/src/commonMain/kotlin/io/github/kdroidfilter/database/dao/AppInfoWithExtras.kt +++ b/dao/src/commonMain/kotlin/io/github/kdroidfilter/database/dao/AppInfoWithExtras.kt @@ -1,6 +1,6 @@ package io.github.kdroidfilter.database.dao -import io.github.kdroidfilter.androidappstorekit.gplay.core.model.GooglePlayApplicationInfo +import io.github.kdroidfilter.storekit.gplay.core.model.GooglePlayApplicationInfo /** * Extended class to add additional information to the GooglePlayApplicationInfo model diff --git a/dao/src/commonMain/kotlin/io/github/kdroidfilter/database/dao/ApplicationsDao.kt b/dao/src/commonMain/kotlin/io/github/kdroidfilter/database/dao/ApplicationsDao.kt index 10a9e35..374b2b9 100644 --- a/dao/src/commonMain/kotlin/io/github/kdroidfilter/database/dao/ApplicationsDao.kt +++ b/dao/src/commonMain/kotlin/io/github/kdroidfilter/database/dao/ApplicationsDao.kt @@ -1,12 +1,12 @@ package io.github.kdroidfilter.database.dao -import io.github.kdroidfilter.androidappstorekit.gplay.core.model.GooglePlayApplicationInfo import io.github.kdroidfilter.database.store.Database import io.github.kdroidfilter.database.core.AppCategory import io.github.kdroidfilter.database.localization.LocalizedAppCategory import io.github.kdroidfilter.database.store.App_categories import io.github.kdroidfilter.database.store.Applications import io.github.kdroidfilter.database.store.Developers +import io.github.kdroidfilter.storekit.gplay.core.model.GooglePlayApplicationInfo /** * Data Access Object for Applications diff --git a/generators/store/build.gradle.kts b/generators/store/build.gradle.kts index ad6ad23..b229bfe 100644 --- a/generators/store/build.gradle.kts +++ b/generators/store/build.gradle.kts @@ -22,7 +22,7 @@ kotlin { implementation(libs.kotlinx.coroutines.test) implementation(libs.kotlinx.serialization.json) implementation(libs.kermit) - implementation(libs.android.appstore.kit.gplay.core) + implementation(libs.storekit.gplaycore) implementation(libs.platform.tools.release.fetcher) implementation(libs.kotlinx.coroutines.swing) implementation(libs.sqlite.jdbc) diff --git a/gradle/libs.versions.toml b/gradle/libs.versions.toml index 90790d3..992e21b 100644 --- a/gradle/libs.versions.toml +++ b/gradle/libs.versions.toml @@ -8,7 +8,7 @@ kotlinx-coroutines = "1.10.2" kotlinx-serialization = "1.8.1" kermit = "2.0.6" koin = "4.1.0" -compose = "1.8.1" +compose = "1.8.2" androidx-activityCompose = "1.10.1" mavenSlf4jProvider = "3.9.9" netfreetoolsCertificates = "1.0.1" @@ -19,7 +19,7 @@ sqlDelight = "2.1.0" sqlJs = "1.8.0" webPackPlugin = "9.1.0" kotlinxBrowserWasmJs = "0.3" -androidAppstoreKit = "0.4.0" +storekit = "0.4.1" [libraries] @@ -38,11 +38,15 @@ kermit = { module = "co.touchlab:kermit", version.ref = "kermit" } koin-core = { module = "io.insert-koin:koin-core", version.ref = "koin" } koin-compose = { module = "io.insert-koin:koin-compose", version.ref = "koin" } androidx-activityCompose = { module = "androidx.activity:activity-compose", version.ref = "androidx-activityCompose" } +ktor-client-cio = { module = "io.ktor:ktor-client-cio", version.ref = "ktor" } +ktor-client-content-negotiation = { module = "io.ktor:ktor-client-content-negotiation", version.ref = "ktor" } +ktor-client-logging = { module = "io.ktor:ktor-client-logging", version.ref = "ktor" } +ktor-client-serialization = { module = "io.ktor:ktor-client-serialization", version.ref = "ktor" } maven-slf4j-provider = { module = "org.apache.maven:maven-slf4j-provider", version.ref = "mavenSlf4jProvider" } netfreetools-certificates = { module = "io.github.kdroidfilter:netfreetools.certificates", version.ref = "netfreetoolsCertificates" } sqlite-jdbc = { module = "org.xerial:sqlite-jdbc", version.ref = "sqliteJdbc" } -android-appstore-kit-gplay-scrapper = { module = "io.github.kdroidfilter.androidappstorekit.gplay:core", version.ref ="androidAppstoreKit"} -android-appstore-kit-gplay-core = { module ="io.github.kdroidfilter.androidappstorekit.gplay:scrapper", version.ref = "androidAppstoreKit"} +storekit-gplayscrapper = { module = "io.github.kdroidfilter:storekit-gplay-scrapper", version.ref = "storekit" } +storekit-gplaycore = { module ="io.github.kdroidfilter:storekit-gplay-core", version.ref = "storekit" } platform-tools-release-fetcher = {module = "io.github.kdroidfilter:platformtools.releasefetcher", version.ref = "platformtools"} ktor-client-core = { module = "io.ktor:ktor-client-core", version.ref = "ktor" } diff --git a/sample/composeApp/build.gradle.kts b/sample/composeApp/build.gradle.kts index 334d433..777fc2d 100644 --- a/sample/composeApp/build.gradle.kts +++ b/sample/composeApp/build.gradle.kts @@ -30,8 +30,12 @@ kotlin { implementation(compose.materialIconsExtended) implementation(libs.kermit) implementation(libs.kotlinx.serialization.json) - implementation(libs.android.appstore.kit.gplay.scrapper) + implementation(libs.storekit.gplayscrapper) implementation(libs.ktor.client.core) + implementation(libs.ktor.client.content.negotiation) + implementation(libs.ktor.client.serialization) + implementation(libs.ktor.client.logging) + implementation(libs.ktor.client.cio) implementation(libs.platform.tools.release.fetcher) implementation(libs.coil.compose) implementation(libs.coil.network.okhttp) From 5cdf810edc3c178127d603e71c3a22a77fee2689 Mon Sep 17 00:00:00 2001 From: Elie Gambache Date: Wed, 18 Jun 2025 21:17:12 +0300 Subject: [PATCH 3/7] Add SHA-1 support to policies and integrate with AptoideService - Introduced `sha1` field in `AppPolicy` and its implementations: `FixedPolicy`, `ModeBasedPolicy`, and `MultiModePolicy`. - Integrated AptoideService to fetch app signatures and populate the `sha1` field during SQLite database generation. - Updated `build.gradle.kts` to include new dependencies for Aptoide API. - Bumped `storekit` version to `0.4.2` in `libs.versions.toml`. --- .../database/core/policies/AppPolicy.kt | 1 + .../database/core/policies/FixedPolicy.kt | 1 + .../database/core/policies/ModeBasedPolicy.kt | 1 + .../database/core/policies/MultiModePolicy.kt | 1 + generators/policies/build.gradle.kts | 11 ++- .../src/jvmMain/kotlin/SqlitePolicyBuilder.kt | 75 ++++++++++++++++++- gradle/libs.versions.toml | 3 +- 7 files changed, 86 insertions(+), 7 deletions(-) diff --git a/core/src/commonMain/kotlin/io/github/kdroidfilter/database/core/policies/AppPolicy.kt b/core/src/commonMain/kotlin/io/github/kdroidfilter/database/core/policies/AppPolicy.kt index 19f1196..5abffd8 100644 --- a/core/src/commonMain/kotlin/io/github/kdroidfilter/database/core/policies/AppPolicy.kt +++ b/core/src/commonMain/kotlin/io/github/kdroidfilter/database/core/policies/AppPolicy.kt @@ -14,6 +14,7 @@ sealed interface AppPolicy { val hasUnmodestImage : Boolean val isPotentiallyDangerous : Boolean val isRecommendedInStore : Boolean + val sha1: String val detectionRules: List } diff --git a/core/src/commonMain/kotlin/io/github/kdroidfilter/database/core/policies/FixedPolicy.kt b/core/src/commonMain/kotlin/io/github/kdroidfilter/database/core/policies/FixedPolicy.kt index 2f085f7..d14d1a9 100644 --- a/core/src/commonMain/kotlin/io/github/kdroidfilter/database/core/policies/FixedPolicy.kt +++ b/core/src/commonMain/kotlin/io/github/kdroidfilter/database/core/policies/FixedPolicy.kt @@ -18,5 +18,6 @@ data class FixedPolicy( override val hasUnmodestImage: Boolean = false, override val isPotentiallyDangerous: Boolean = false, override val isRecommendedInStore: Boolean = false, + override val sha1: String = "", override val detectionRules: List = emptyList() ) : AppPolicy diff --git a/core/src/commonMain/kotlin/io/github/kdroidfilter/database/core/policies/ModeBasedPolicy.kt b/core/src/commonMain/kotlin/io/github/kdroidfilter/database/core/policies/ModeBasedPolicy.kt index db2a3db..401c2f9 100644 --- a/core/src/commonMain/kotlin/io/github/kdroidfilter/database/core/policies/ModeBasedPolicy.kt +++ b/core/src/commonMain/kotlin/io/github/kdroidfilter/database/core/policies/ModeBasedPolicy.kt @@ -19,5 +19,6 @@ data class ModeBasedPolicy( override val hasUnmodestImage: Boolean = false, override val isPotentiallyDangerous: Boolean = false, override val isRecommendedInStore: Boolean = false, + override val sha1: String = "", override val detectionRules: List = emptyList() ) : AppPolicy diff --git a/core/src/commonMain/kotlin/io/github/kdroidfilter/database/core/policies/MultiModePolicy.kt b/core/src/commonMain/kotlin/io/github/kdroidfilter/database/core/policies/MultiModePolicy.kt index 8893db6..d831658 100644 --- a/core/src/commonMain/kotlin/io/github/kdroidfilter/database/core/policies/MultiModePolicy.kt +++ b/core/src/commonMain/kotlin/io/github/kdroidfilter/database/core/policies/MultiModePolicy.kt @@ -44,6 +44,7 @@ data class MultiModePolicy( override val hasUnmodestImage: Boolean = false, override val isPotentiallyDangerous: Boolean = false, override val isRecommendedInStore: Boolean = false, + override val sha1: String = "", override val detectionRules: List = emptyList() ) : AppPolicy { diff --git a/generators/policies/build.gradle.kts b/generators/policies/build.gradle.kts index c4f2b2e..765931f 100644 --- a/generators/policies/build.gradle.kts +++ b/generators/policies/build.gradle.kts @@ -11,20 +11,27 @@ kotlin { sourceSets { - jvmMain.dependencies { + jvmTest.dependencies { implementation(kotlin("test")) } jvmMain.dependencies { implementation(project(":core")) implementation(libs.kotlinx.coroutines.core) - implementation(libs.kotlinx.coroutines.test) implementation(libs.kotlinx.serialization.json) implementation(libs.kermit) implementation(libs.platform.tools.release.fetcher) implementation(libs.kotlinx.coroutines.swing) implementation(libs.sqlite.jdbc) implementation(libs.maven.slf4j.provider) + implementation(libs.storekit.aptoide.api) + + implementation(libs.ktor.client.core) + implementation(libs.ktor.client.content.negotiation) + implementation(libs.ktor.client.serialization) + implementation(libs.ktor.client.logging) + implementation(libs.ktor.client.cio) + } } diff --git a/generators/policies/src/jvmMain/kotlin/SqlitePolicyBuilder.kt b/generators/policies/src/jvmMain/kotlin/SqlitePolicyBuilder.kt index 0a46318..ec51b43 100644 --- a/generators/policies/src/jvmMain/kotlin/SqlitePolicyBuilder.kt +++ b/generators/policies/src/jvmMain/kotlin/SqlitePolicyBuilder.kt @@ -1,5 +1,11 @@ import co.touchlab.kermit.Logger import io.github.kdroidfilter.database.core.policies.AppPolicy +import io.github.kdroidfilter.database.core.policies.FixedPolicy +import io.github.kdroidfilter.database.core.policies.ModeBasedPolicy +import io.github.kdroidfilter.database.core.policies.MultiModePolicy +import io.github.kdroidfilter.storekit.aptoide.api.extensions.toFormattedSha1 +import io.github.kdroidfilter.storekit.aptoide.api.services.AptoideService +import kotlinx.coroutines.runBlocking import kotlinx.serialization.json.Json import java.nio.file.Files import java.nio.file.Path @@ -83,16 +89,77 @@ object SqlitePolicyBuilder { VALUES(?, ?) """.trimIndent() + val aptoideService = AptoideService() + val failedApps = mutableListOf() conn.prepareStatement(insertSql).use { ps -> val policies = PolicyRepository.loadAll(policiesDir) policies.forEach { policy -> - val jsonStr = json.encodeToString(AppPolicy.serializer(), policy) - ps.setString(1, policy.packageName) - ps.setString(2, jsonStr) - ps.addBatch() + runBlocking { + // Try to get the app signature, but use an empty string if it fails + val appSignature = try { + aptoideService.getAppMetaByPackageName(policy.packageName) + .file.signature.toFormattedSha1() + } catch (e: Exception) { + logger.w { "Failed to get signature for ${policy.packageName}: ${e.message}" } + failedApps.add(policy.packageName) + "" + } + // Create a new policy with the updated sha1 value + val policyWithSignature = when (policy) { + is FixedPolicy -> FixedPolicy( + packageName = policy.packageName, + category = policy.category, + networkPolicy = policy.networkPolicy, + minimumVersionCode = policy.minimumVersionCode, + requiresPlayStoreInstallation = policy.requiresPlayStoreInstallation, + hasUnmodestImage = policy.hasUnmodestImage, + isPotentiallyDangerous = policy.isPotentiallyDangerous, + isRecommendedInStore = policy.isRecommendedInStore, + sha1 = appSignature, + detectionRules = policy.detectionRules + ) + is ModeBasedPolicy -> ModeBasedPolicy( + packageName = policy.packageName, + category = policy.category, + modePolicies = policy.modePolicies, + minimumVersionCode = policy.minimumVersionCode, + requiresPlayStoreInstallation = policy.requiresPlayStoreInstallation, + hasUnmodestImage = policy.hasUnmodestImage, + isPotentiallyDangerous = policy.isPotentiallyDangerous, + isRecommendedInStore = policy.isRecommendedInStore, + sha1 = appSignature, + detectionRules = policy.detectionRules + ) + is MultiModePolicy -> MultiModePolicy( + packageName = policy.packageName, + category = policy.category, + modeVariants = policy.modeVariants, + minimumVersionCode = policy.minimumVersionCode, + requiresPlayStoreInstallation = policy.requiresPlayStoreInstallation, + hasUnmodestImage = policy.hasUnmodestImage, + isPotentiallyDangerous = policy.isPotentiallyDangerous, + isRecommendedInStore = policy.isRecommendedInStore, + sha1 = appSignature, + detectionRules = policy.detectionRules + ) + else -> throw IllegalArgumentException("Unknown policy type: ${policy::class.simpleName}") + } + val jsonStr = json.encodeToString(AppPolicy.serializer(), policyWithSignature) + ps.setString(1, policy.packageName) + ps.setString(2, jsonStr) + ps.addBatch() + } } ps.executeBatch() logger.i { "βœ… Inserted ${policies.size} policies" } + + // Log summary of apps with failed signature retrieval + if (failedApps.isNotEmpty()) { + logger.w { "⚠️ Failed to get signatures for ${failedApps.size} apps:" } + failedApps.forEach { packageName -> + logger.w { " - $packageName" } + } + } } } } diff --git a/gradle/libs.versions.toml b/gradle/libs.versions.toml index 992e21b..fcdaf04 100644 --- a/gradle/libs.versions.toml +++ b/gradle/libs.versions.toml @@ -19,7 +19,7 @@ sqlDelight = "2.1.0" sqlJs = "1.8.0" webPackPlugin = "9.1.0" kotlinxBrowserWasmJs = "0.3" -storekit = "0.4.1" +storekit = "0.4.2" [libraries] @@ -45,6 +45,7 @@ ktor-client-serialization = { module = "io.ktor:ktor-client-serialization", vers maven-slf4j-provider = { module = "org.apache.maven:maven-slf4j-provider", version.ref = "mavenSlf4jProvider" } netfreetools-certificates = { module = "io.github.kdroidfilter:netfreetools.certificates", version.ref = "netfreetoolsCertificates" } sqlite-jdbc = { module = "org.xerial:sqlite-jdbc", version.ref = "sqliteJdbc" } +storekit-aptoide-api = { module = "io.github.kdroidfilter:storekit-aptoide-api", version.ref = "storekit" } storekit-gplayscrapper = { module = "io.github.kdroidfilter:storekit-gplay-scrapper", version.ref = "storekit" } storekit-gplaycore = { module ="io.github.kdroidfilter:storekit-gplay-core", version.ref = "storekit" } platform-tools-release-fetcher = {module = "io.github.kdroidfilter:platformtools.releasefetcher", version.ref = "platformtools"} From 661afa9d5baa1683b31de3abeefe3e7935525571 Mon Sep 17 00:00:00 2001 From: Elie Gambache Date: Thu, 19 Jun 2025 10:48:46 +0300 Subject: [PATCH 4/7] Enhance app metadata handling and update dependencies - Improved app metadata retrieval in `SqlitePolicyBuilder` by integrating fallback logic for SHA-1 and version codes using `AptoideService`. - Added skipped app logging for better visibility of failed metadata fetches. - Refactored SQL table creation for readability. - Updated `libs.versions.toml`: - Unified `coil` version references. - Bumped `storekit` version to `0.6.0`. --- .../src/jvmMain/kotlin/SqlitePolicyBuilder.kt | 144 +++++++++++------- gradle/libs.versions.toml | 12 +- 2 files changed, 93 insertions(+), 63 deletions(-) diff --git a/generators/policies/src/jvmMain/kotlin/SqlitePolicyBuilder.kt b/generators/policies/src/jvmMain/kotlin/SqlitePolicyBuilder.kt index ec51b43..436ec7b 100644 --- a/generators/policies/src/jvmMain/kotlin/SqlitePolicyBuilder.kt +++ b/generators/policies/src/jvmMain/kotlin/SqlitePolicyBuilder.kt @@ -1,4 +1,5 @@ import co.touchlab.kermit.Logger +import io.github.kdroidfilter.database.core.AppCategory import io.github.kdroidfilter.database.core.policies.AppPolicy import io.github.kdroidfilter.database.core.policies.FixedPolicy import io.github.kdroidfilter.database.core.policies.ModeBasedPolicy @@ -53,19 +54,23 @@ object SqlitePolicyBuilder { } private fun createTables(conn: Connection) = with(conn.createStatement()) { - executeUpdate(""" + executeUpdate( + """ CREATE TABLE IF NOT EXISTS policies ( package_name TEXT PRIMARY KEY, data TEXT NOT NULL ) - """.trimIndent()) + """.trimIndent() + ) - executeUpdate(""" + executeUpdate( + """ CREATE TABLE IF NOT EXISTS version ( id INTEGER PRIMARY KEY AUTOINCREMENT, release_name TEXT NOT NULL ) - """.trimIndent()) + """.trimIndent() + ) close() } @@ -91,71 +96,96 @@ object SqlitePolicyBuilder { val aptoideService = AptoideService() val failedApps = mutableListOf() + var insertedCount = 0 + conn.prepareStatement(insertSql).use { ps -> val policies = PolicyRepository.loadAll(policiesDir) policies.forEach { policy -> runBlocking { - // Try to get the app signature, but use an empty string if it fails - val appSignature = try { - aptoideService.getAppMetaByPackageName(policy.packageName) - .file.signature.toFormattedSha1() - } catch (e: Exception) { - logger.w { "Failed to get signature for ${policy.packageName}: ${e.message}" } - failedApps.add(policy.packageName) - "" + // If we need to fetch data from API (empty SHA1 or version code is 0) + var appSignature = policy.sha1 + var appMinVersionCode = policy.minimumVersionCode + + // Only make API call if we need either signature or version code + if (appSignature.isEmpty() || appMinVersionCode == 0) { + try { + // Make a single API call and store the result + val appMeta = aptoideService.getAppMetaByPackageName(policy.packageName) + + // Update signature if needed + if (appSignature.isEmpty()) { + appSignature = appMeta.file.signature.toFormattedSha1() + } + + // Update version code if needed + if (appMinVersionCode == 0) { + appMinVersionCode = appMeta.file.vercode + } + } catch (e: Exception) { + logger.w { "Failed to get app metadata for ${policy.packageName}: ${e.message}" } + if (appSignature.isEmpty()) { + failedApps.add(policy.packageName) + } + } } - // Create a new policy with the updated sha1 value - val policyWithSignature = when (policy) { - is FixedPolicy -> FixedPolicy( - packageName = policy.packageName, - category = policy.category, - networkPolicy = policy.networkPolicy, - minimumVersionCode = policy.minimumVersionCode, - requiresPlayStoreInstallation = policy.requiresPlayStoreInstallation, - hasUnmodestImage = policy.hasUnmodestImage, - isPotentiallyDangerous = policy.isPotentiallyDangerous, - isRecommendedInStore = policy.isRecommendedInStore, - sha1 = appSignature, - detectionRules = policy.detectionRules - ) - is ModeBasedPolicy -> ModeBasedPolicy( - packageName = policy.packageName, - category = policy.category, - modePolicies = policy.modePolicies, - minimumVersionCode = policy.minimumVersionCode, - requiresPlayStoreInstallation = policy.requiresPlayStoreInstallation, - hasUnmodestImage = policy.hasUnmodestImage, - isPotentiallyDangerous = policy.isPotentiallyDangerous, - isRecommendedInStore = policy.isRecommendedInStore, - sha1 = appSignature, - detectionRules = policy.detectionRules - ) - is MultiModePolicy -> MultiModePolicy( - packageName = policy.packageName, - category = policy.category, - modeVariants = policy.modeVariants, - minimumVersionCode = policy.minimumVersionCode, - requiresPlayStoreInstallation = policy.requiresPlayStoreInstallation, - hasUnmodestImage = policy.hasUnmodestImage, - isPotentiallyDangerous = policy.isPotentiallyDangerous, - isRecommendedInStore = policy.isRecommendedInStore, - sha1 = appSignature, - detectionRules = policy.detectionRules - ) - else -> throw IllegalArgumentException("Unknown policy type: ${policy::class.simpleName}") + + // Only add to the database if the signature is not empty, if it's a system app, or if it has a valid minimumVersionCode (for tests) + if (appSignature.isNotEmpty() || policy.category == AppCategory.SYSTEM || policy.minimumVersionCode > 0) { + // Create a new policy with the updated sha1 value + val policyWithSignature = when (policy) { + is FixedPolicy -> FixedPolicy( + packageName = policy.packageName, + category = policy.category, + networkPolicy = policy.networkPolicy, + minimumVersionCode = appMinVersionCode, + requiresPlayStoreInstallation = policy.requiresPlayStoreInstallation, + hasUnmodestImage = policy.hasUnmodestImage, + isPotentiallyDangerous = policy.isPotentiallyDangerous, + isRecommendedInStore = policy.isRecommendedInStore, + sha1 = appSignature, + detectionRules = policy.detectionRules + ) + + is ModeBasedPolicy -> ModeBasedPolicy( + packageName = policy.packageName, + category = policy.category, + modePolicies = policy.modePolicies, + minimumVersionCode = appMinVersionCode, + requiresPlayStoreInstallation = policy.requiresPlayStoreInstallation, + hasUnmodestImage = policy.hasUnmodestImage, + isPotentiallyDangerous = policy.isPotentiallyDangerous, + isRecommendedInStore = policy.isRecommendedInStore, + sha1 = appSignature, + detectionRules = policy.detectionRules + ) + + is MultiModePolicy -> MultiModePolicy( + packageName = policy.packageName, + category = policy.category, + modeVariants = policy.modeVariants, + minimumVersionCode = appMinVersionCode, + requiresPlayStoreInstallation = policy.requiresPlayStoreInstallation, + hasUnmodestImage = policy.hasUnmodestImage, + isPotentiallyDangerous = policy.isPotentiallyDangerous, + isRecommendedInStore = policy.isRecommendedInStore, + sha1 = appSignature, + detectionRules = policy.detectionRules + ) + } + val jsonStr = json.encodeToString(AppPolicy.serializer(), policyWithSignature) + ps.setString(1, policy.packageName) + ps.setString(2, jsonStr) + ps.addBatch() + insertedCount++ } - val jsonStr = json.encodeToString(AppPolicy.serializer(), policyWithSignature) - ps.setString(1, policy.packageName) - ps.setString(2, jsonStr) - ps.addBatch() } } ps.executeBatch() - logger.i { "βœ… Inserted ${policies.size} policies" } + logger.i { "βœ… Inserted $insertedCount policies (out of ${policies.size} total)" } // Log summary of apps with failed signature retrieval if (failedApps.isNotEmpty()) { - logger.w { "⚠️ Failed to get signatures for ${failedApps.size} apps:" } + logger.w { "⚠️ Skipped ${failedApps.size} apps without signatures:" } failedApps.forEach { packageName -> logger.w { " - $packageName" } } diff --git a/gradle/libs.versions.toml b/gradle/libs.versions.toml index fcdaf04..eb2e42c 100644 --- a/gradle/libs.versions.toml +++ b/gradle/libs.versions.toml @@ -1,6 +1,6 @@ [versions] -coilNetworkOkhttp = "3.2.0" +coil = "3.2.0" junitJupiterApi = "5.10.1" kotlin = "2.1.21" agp = "8.9.3" @@ -10,7 +10,7 @@ kermit = "2.0.6" koin = "4.1.0" compose = "1.8.2" androidx-activityCompose = "1.10.1" -mavenSlf4jProvider = "3.9.9" +slf4j = "3.9.9" netfreetoolsCertificates = "1.0.1" sqliteJdbc = "3.49.1.0" platformtools = "0.4.0" @@ -19,13 +19,13 @@ sqlDelight = "2.1.0" sqlJs = "1.8.0" webPackPlugin = "9.1.0" kotlinxBrowserWasmJs = "0.3" -storekit = "0.4.2" +storekit = "0.6.0" [libraries] androidcontextprovider = { module = "io.github.kdroidfilter:androidcontextprovider", version.ref = "netfreetoolsCertificates" } -coil-compose = { module = "io.coil-kt.coil3:coil-compose", version.ref = "coilNetworkOkhttp" } -coil-network-okhttp = { module = "io.coil-kt.coil3:coil-network-okhttp", version.ref = "coilNetworkOkhttp" } +coil-compose = { module = "io.coil-kt.coil3:coil-compose", version.ref = "coil" } +coil-network-okhttp = { module = "io.coil-kt.coil3:coil-network-okhttp", version.ref = "coil" } junit-jupiter-api = { module = "org.junit.jupiter:junit-jupiter-api", version.ref = "junitJupiterApi" } junit-jupiter-engine = { module = "org.junit.jupiter:junit-jupiter-engine", version.ref = "junitJupiterApi" } junit-jupiter-params = { module = "org.junit.jupiter:junit-jupiter-params", version.ref = "junitJupiterApi" } @@ -42,7 +42,7 @@ ktor-client-cio = { module = "io.ktor:ktor-client-cio", version.ref = "ktor" } ktor-client-content-negotiation = { module = "io.ktor:ktor-client-content-negotiation", version.ref = "ktor" } ktor-client-logging = { module = "io.ktor:ktor-client-logging", version.ref = "ktor" } ktor-client-serialization = { module = "io.ktor:ktor-client-serialization", version.ref = "ktor" } -maven-slf4j-provider = { module = "org.apache.maven:maven-slf4j-provider", version.ref = "mavenSlf4jProvider" } +maven-slf4j-provider = { module = "org.apache.maven:maven-slf4j-provider", version.ref = "slf4j" } netfreetools-certificates = { module = "io.github.kdroidfilter:netfreetools.certificates", version.ref = "netfreetoolsCertificates" } sqlite-jdbc = { module = "org.xerial:sqlite-jdbc", version.ref = "sqliteJdbc" } storekit-aptoide-api = { module = "io.github.kdroidfilter:storekit-aptoide-api", version.ref = "storekit" } From aa819261b14e2aca25975847cfa3da1f8d309143 Mon Sep 17 00:00:00 2001 From: Elie Gambache Date: Thu, 19 Jun 2025 10:56:52 +0300 Subject: [PATCH 5/7] Add CI workflow and policy checker for validating app metadata - Introduced GitHub Actions workflow to run policy checks on pull requests. - Added `PolicyChecker` utility to validate minimum version codes and SHA-1 signatures. - Implemented Gradle task `checkPolicies` for validating policy files locally. - Updated README with instructions for running the new policy check task. --- .github/workflows/ci-policy-checks.yml | 32 ++++++ README.MD | 22 +++- generators/policies/build.gradle.kts | 12 ++ .../src/jvmMain/kotlin/PolicyChecker.kt | 107 ++++++++++++++++++ 4 files changed, 171 insertions(+), 2 deletions(-) create mode 100644 .github/workflows/ci-policy-checks.yml create mode 100644 generators/policies/src/jvmMain/kotlin/PolicyChecker.kt diff --git a/.github/workflows/ci-policy-checks.yml b/.github/workflows/ci-policy-checks.yml new file mode 100644 index 0000000..487a285 --- /dev/null +++ b/.github/workflows/ci-policy-checks.yml @@ -0,0 +1,32 @@ +name: CI – Policy Checks + +on: + pull_request: + +jobs: + policy-checks: + name: Check policies for missing version codes and signatures + runs-on: ubuntu-latest + + steps: + - name: Checkout repository + uses: actions/checkout@v3 + + - name: Set up Java 17 + uses: actions/setup-java@v3 + with: + distribution: temurin + java-version: '17' + + - name: Cache Gradle dependencies + uses: actions/cache@v3 + with: + path: | + ~/.gradle/caches + ~/.gradle/wrapper + key: ${{ runner.os }}-gradle-${{ hashFiles('**/*.gradle*','**/gradle-wrapper.properties') }} + restore-keys: | + ${{ runner.os }}-gradle- + + - name: Check policies + run: ./gradlew :generators:policies:checkPolicies \ No newline at end of file diff --git a/README.MD b/README.MD index 8e013b2..8d68e16 100644 --- a/README.MD +++ b/README.MD @@ -236,8 +236,12 @@ Use when each user mode has multiple variants, each with its own rules and optio 1. πŸ”Ž **Validate JSON** with a linter (e.g., [jsonlint.com](https://jsonlint.com/)) or use the project's built-in validation task (see below). 2. πŸ“‚ **Place** your file under the correct category folder. -3. πŸ“œ **Commit only** the JSON fileβ€”no code or docs changes. -4. πŸ“ **PR title** should clearly state the app package. +3. πŸ”’ **Include a minimum version code** (`minimumVersionCode`) for each app. This is imperative for proper app validation. While our system can try to determine this automatically, it's not 100% reliable and will always use the latest version available. +4. πŸ” **Include the SHA1 signature** (`sha1`) of the app's certificate. This is crucial for security verification. Our system can attempt to retrieve this, but it's not always reliable. +5. πŸ“œ **Commit only** the JSON fileβ€”no code or docs changes. +6. πŸ“ **PR title** should clearly state the app package. + +> **Note**: For system apps (category `SYSTEM`), the minimum version code and SHA1 signature are not required. CI will reject invalid JSON or misplaced files. Good luck! πŸ™Œ @@ -262,6 +266,20 @@ This task checks all JSON files in the `app-policies` directory to ensure they: The task will report any validation errors found, making it easier to identify and fix issues before submitting. +### Checking Policies + +To check policies for missing version codes and signatures: + +```bash +./gradlew :generators:policies:checkPolicies +``` + +This task verifies that all policy files have: +- A valid minimum version code (greater than 0) +- A valid SHA1 signature for the app's certificate + +The system will attempt to retrieve missing values from the Aptoide API, but this is not always reliable. The task will report any policies that fail these checks, except for system apps which are exempt. + --- ## ❓ Questions & Answers diff --git a/generators/policies/build.gradle.kts b/generators/policies/build.gradle.kts index 765931f..dac2b93 100644 --- a/generators/policies/build.gradle.kts +++ b/generators/policies/build.gradle.kts @@ -71,3 +71,15 @@ tasks.register("validateJson") { ) mainClass.set("JsonValidatorKt") } + +tasks.register("checkPolicies") { + group = "validation" + description = "Checks policies for missing version codes and signatures" + + dependsOn(kotlin.jvm().compilations["main"].compileTaskProvider) + classpath = files( + kotlin.jvm().compilations["main"].output.allOutputs, + kotlin.jvm().compilations["main"].runtimeDependencyFiles + ) + mainClass.set("PolicyCheckerKt") +} diff --git a/generators/policies/src/jvmMain/kotlin/PolicyChecker.kt b/generators/policies/src/jvmMain/kotlin/PolicyChecker.kt new file mode 100644 index 0000000..92e8546 --- /dev/null +++ b/generators/policies/src/jvmMain/kotlin/PolicyChecker.kt @@ -0,0 +1,107 @@ +import co.touchlab.kermit.Logger +import io.github.kdroidfilter.database.core.AppCategory +import io.github.kdroidfilter.database.core.policies.AppPolicy +import io.github.kdroidfilter.storekit.aptoide.api.extensions.toFormattedSha1 +import io.github.kdroidfilter.storekit.aptoide.api.services.AptoideService +import kotlinx.coroutines.runBlocking +import java.nio.file.Files +import java.nio.file.Path +import kotlin.system.exitProcess + +/** + * Utility to check policies for missing version codes and signatures + */ +object PolicyChecker { + private val logger = Logger.withTag("PolicyChecker") + + /** + * Checks all policies for missing version codes and signatures + * @param policiesDir The directory containing policy files + * @return true if all checks pass, false otherwise + */ + fun checkPolicies(policiesDir: Path): Boolean { + logger.i { "πŸ” Checking policies in: $policiesDir" } + + val aptoideService = AptoideService() + val policies = PolicyRepository.loadAll(policiesDir) + + val versionCodeIssues = mutableListOf() + val signatureIssues = mutableListOf() + + policies.forEach { policy -> + runBlocking { + // Check version code + if (policy.minimumVersionCode == 0) { + try { + val appMeta = aptoideService.getAppMetaByPackageName(policy.packageName) + logger.i { "βœ… Successfully retrieved version code for ${policy.packageName}" } + } catch (e: Exception) { + // If it's not a system app, add to issues list + if (policy.category != AppCategory.SYSTEM) { + logger.w { "❌ Failed to retrieve version code for ${policy.packageName}: ${e.message}" } + versionCodeIssues.add(policy.packageName) + } else { + logger.i { "⚠️ System app ${policy.packageName} has version code 0 but is exempt from check" } + } + } + } + + // Check signature + if (policy.sha1.isEmpty()) { + try { + val appMeta = aptoideService.getAppMetaByPackageName(policy.packageName) + val signature = appMeta.file.signature.toFormattedSha1() + logger.i { "βœ… Successfully retrieved signature for ${policy.packageName}" } + } catch (e: Exception) { + // If it's not a system app, add to issues list + if (policy.category != AppCategory.SYSTEM) { + logger.w { "❌ Failed to retrieve signature for ${policy.packageName}: ${e.message}" } + signatureIssues.add(policy.packageName) + } else { + logger.i { "⚠️ System app ${policy.packageName} has empty signature but is exempt from check" } + } + } + } + } + } + + // Print summary + logger.i { "πŸ“Š Check complete: ${policies.size} policies checked" } + + val hasIssues = versionCodeIssues.isNotEmpty() || signatureIssues.isNotEmpty() + + if (versionCodeIssues.isNotEmpty()) { + logger.e { "❌ Found ${versionCodeIssues.size} policies with version code 0 that cannot be retrieved from API:" } + versionCodeIssues.forEach { packageName -> + logger.e { " - $packageName" } + } + } + + if (signatureIssues.isNotEmpty()) { + logger.e { "❌ Found ${signatureIssues.size} policies with empty signature that cannot be retrieved from API:" } + signatureIssues.forEach { packageName -> + logger.e { " - $packageName" } + } + } + + return !hasIssues + } +} + +/** + * Main function to run the policy checker + */ +fun main() { + val logger = Logger.withTag("PolicyChecker") + val projectDir = java.nio.file.Paths.get("").toAbsolutePath() + val root = projectDir.parent.resolve("../app-policies") + + val isValid = PolicyChecker.checkPolicies(root) + + if (!isValid) { + logger.e { "❌ Policy checks failed. Please fix the issues above." } + exitProcess(1) + } else { + logger.i { "βœ… All policy checks passed!" } + } +} From d2256ddd4bef7bde3edddadbd6ed19bec3ae69f3 Mon Sep 17 00:00:00 2001 From: Elie Gambache Date: Thu, 19 Jun 2025 11:05:12 +0300 Subject: [PATCH 6/7] Update README with CI failure explanation for non-system app policies - Added clarification on CI pipeline behavior when minimum version code or SHA-1 signature cannot be determined for non-system apps. --- README.MD | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/README.MD b/README.MD index 8d68e16..ad49b54 100644 --- a/README.MD +++ b/README.MD @@ -242,6 +242,8 @@ Use when each user mode has multiple variants, each with its own rules and optio 6. πŸ“ **PR title** should clearly state the app package. > **Note**: For system apps (category `SYSTEM`), the minimum version code and SHA1 signature are not required. +> +> **Important**: If our system cannot determine the minimum version code or signature for a non-system app, the CI will fail. Make sure these values are either provided in the policy file or can be reliably retrieved from the Aptoide API. CI will reject invalid JSON or misplaced files. Good luck! πŸ™Œ @@ -280,6 +282,8 @@ This task verifies that all policy files have: The system will attempt to retrieve missing values from the Aptoide API, but this is not always reliable. The task will report any policies that fail these checks, except for system apps which are exempt. +**Note**: This task is run as part of the CI pipeline. If the system cannot determine the minimum version code or signature for a non-system app, the CI will fail. + --- ## ❓ Questions & Answers From 19356daf927d03807c8bbbcfe1a8457eeee2266e Mon Sep 17 00:00:00 2001 From: Elie Gambache Date: Thu, 19 Jun 2025 11:25:53 +0300 Subject: [PATCH 7/7] Add SHA-1 signatures and update minimum version codes for app policies - Updated app policies with `sha1` field and valid minimum version codes for multiple apps. --- .github/workflows/{ci.yml => ci-json-checks.yml} | 0 app-policies/music-audio/com.apple.bnd.json | 5 +++-- app-policies/music-audio/kcm.fm.volume.json | 5 +++-- app-policies/productivity/com.github.android.json | 3 ++- app-policies/torah/com.mendelg.otzaria.json | 5 +++-- 5 files changed, 11 insertions(+), 7 deletions(-) rename .github/workflows/{ci.yml => ci-json-checks.yml} (100%) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci-json-checks.yml similarity index 100% rename from .github/workflows/ci.yml rename to .github/workflows/ci-json-checks.yml diff --git a/app-policies/music-audio/com.apple.bnd.json b/app-policies/music-audio/com.apple.bnd.json index e4aafd9..a612195 100644 --- a/app-policies/music-audio/com.apple.bnd.json +++ b/app-policies/music-audio/com.apple.bnd.json @@ -2,9 +2,10 @@ "type": "Fixed", "packageName": "com.apple.bnd", "category": "MUSIC_AUDIO", - "minimumVersionCode": 0, + "minimumVersionCode": 25500, "hasUnmodestImage": true, "networkPolicy": { "mode": "FULL_OPEN" - } + }, + "sha1" : "33e7ba4c0f1cab0831c32fab77d3d23e24505f61" } diff --git a/app-policies/music-audio/kcm.fm.volume.json b/app-policies/music-audio/kcm.fm.volume.json index 951e8c6..639a558 100644 --- a/app-policies/music-audio/kcm.fm.volume.json +++ b/app-policies/music-audio/kcm.fm.volume.json @@ -2,8 +2,9 @@ "type": "Fixed", "packageName": "kcm.fm.volume", "category": "MUSIC_AUDIO", - "minimumVersionCode": 0, + "minimumVersionCode": 30, "networkPolicy": { "mode": "FULL_OPEN" - } + }, + "sha1" : "e99f8d4f6cf2bfbed8d82b8185931898681aa25c" } diff --git a/app-policies/productivity/com.github.android.json b/app-policies/productivity/com.github.android.json index d8b25bc..04e8cf2 100644 --- a/app-policies/productivity/com.github.android.json +++ b/app-policies/productivity/com.github.android.json @@ -5,5 +5,6 @@ "networkPolicy": { "mode": "FULL_OPEN" }, - "minimumVersionCode": 0 + "minimumVersionCode": 10257, + "sha1" : "75ac713fee04aa0a6d8325af6110e37c47de7698" } diff --git a/app-policies/torah/com.mendelg.otzaria.json b/app-policies/torah/com.mendelg.otzaria.json index 0ae7438..46a14a2 100644 --- a/app-policies/torah/com.mendelg.otzaria.json +++ b/app-policies/torah/com.mendelg.otzaria.json @@ -2,8 +2,9 @@ "type": "Fixed", "packageName": "com.mendelg.otzaria", "category": "TORAH", - "minimumVersionCode": 0, + "minimumVersionCode": 44389637, "networkPolicy": { "mode": "FULL_OPEN" - } + }, + "sha1" : "bb4acfb8a076d09c22ddee39bf4633d956edf369" }