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/.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 e76559e..ad49b54 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 @@ -236,8 +236,14 @@ 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. +> +> **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! πŸ™Œ @@ -262,6 +268,22 @@ 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. + +**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 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" } 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/dao/build.gradle.kts b/dao/build.gradle.kts index b738307..9c9766e 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.storekit.gplayscrapper) + 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..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 com.kdroid.gplayscrapper.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 df42734..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 com.kdroid.gplayscrapper.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/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/policies/build.gradle.kts b/generators/policies/build.gradle.kts index c4f2b2e..dac2b93 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) + } } @@ -64,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!" } + } +} diff --git a/generators/policies/src/jvmMain/kotlin/SqlitePolicyBuilder.kt b/generators/policies/src/jvmMain/kotlin/SqlitePolicyBuilder.kt index 0a46318..436ec7b 100644 --- a/generators/policies/src/jvmMain/kotlin/SqlitePolicyBuilder.kt +++ b/generators/policies/src/jvmMain/kotlin/SqlitePolicyBuilder.kt @@ -1,5 +1,12 @@ 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 +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 @@ -47,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() } @@ -83,16 +94,102 @@ object SqlitePolicyBuilder { VALUES(?, ?) """.trimIndent() + val aptoideService = AptoideService() + val failedApps = mutableListOf() + var insertedCount = 0 + 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 { + // 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) + } + } + } + + // 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++ + } + } } 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 { "⚠️ Skipped ${failedApps.size} apps without signatures:" } + failedApps.forEach { packageName -> + logger.w { " - $packageName" } + } + } } } } diff --git a/generators/store/build.gradle.kts b/generators/store/build.gradle.kts index 89fa7b7..b229bfe 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.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 13c8a74..eb2e42c 100644 --- a/gradle/libs.versions.toml +++ b/gradle/libs.versions.toml @@ -1,31 +1,31 @@ [versions] -coilNetworkOkhttp = "3.2.0" +coil = "3.2.0" junitJupiterApi = "5.10.1" 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" -compose = "1.8.1" +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.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" +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" } @@ -38,11 +38,16 @@ 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" } -maven-slf4j-provider = { module = "org.apache.maven:maven-slf4j-provider", version.ref = "mavenSlf4jProvider" } +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 = "slf4j" } 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"} +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"} 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..777fc2d 100644 --- a/sample/composeApp/build.gradle.kts +++ b/sample/composeApp/build.gradle.kts @@ -30,9 +30,12 @@ kotlin { implementation(compose.materialIconsExtended) implementation(libs.kermit) implementation(libs.kotlinx.serialization.json) - implementation(libs.gplay.scrapper.core) - + 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)