mirror of
https://github.com/revanced/revanced-api.git
synced 2025-04-29 22:24:31 +02:00
125 lines
4.5 KiB
Kotlin
125 lines
4.5 KiB
Kotlin
package app.revanced.api.configuration.services
|
|
|
|
import app.revanced.api.configuration.repository.BackendRepository
|
|
import app.revanced.api.configuration.repository.BackendRepository.BackendOrganization.BackendRepository.BackendRelease.Companion.first
|
|
import app.revanced.api.configuration.repository.ConfigurationRepository
|
|
import app.revanced.api.configuration.schema.*
|
|
import app.revanced.library.PatchUtils
|
|
import app.revanced.patcher.PatchBundleLoader
|
|
import com.github.benmanes.caffeine.cache.Caffeine
|
|
import io.ktor.util.*
|
|
import kotlinx.coroutines.Dispatchers
|
|
import kotlinx.coroutines.withContext
|
|
import java.io.ByteArrayOutputStream
|
|
import java.net.URL
|
|
|
|
internal class PatchesService(
|
|
private val signatureService: SignatureService,
|
|
private val backendRepository: BackendRepository,
|
|
private val configurationRepository: ConfigurationRepository,
|
|
) {
|
|
suspend fun latestRelease(): APIRelease {
|
|
val patchesRelease = backendRepository.release(
|
|
configurationRepository.organization,
|
|
configurationRepository.patches.repository,
|
|
)
|
|
|
|
val integrationsRelease = backendRepository.release(
|
|
configurationRepository.organization,
|
|
configurationRepository.integrations.repository,
|
|
)
|
|
|
|
fun ConfigurationRepository.AssetConfiguration.asset(
|
|
release: BackendRepository.BackendOrganization.BackendRepository.BackendRelease,
|
|
assetName: APIAssetName,
|
|
) = APIAsset(
|
|
release.assets.first(assetRegex).downloadUrl,
|
|
release.assets.first(signatureAssetRegex).downloadUrl,
|
|
assetName,
|
|
)
|
|
|
|
val patchesAsset = configurationRepository.patches.asset(
|
|
patchesRelease,
|
|
APIAssetName.PATCHES,
|
|
)
|
|
val integrationsAsset = configurationRepository.integrations.asset(
|
|
integrationsRelease,
|
|
APIAssetName.INTEGRATION,
|
|
)
|
|
|
|
return APIRelease(
|
|
patchesRelease.tag,
|
|
patchesRelease.createdAt,
|
|
patchesRelease.releaseNote,
|
|
listOf(patchesAsset, integrationsAsset),
|
|
)
|
|
}
|
|
|
|
suspend fun latestVersion(): APIReleaseVersion {
|
|
val patchesRelease = backendRepository.release(
|
|
configurationRepository.organization,
|
|
configurationRepository.patches.repository,
|
|
)
|
|
|
|
return APIReleaseVersion(patchesRelease.tag)
|
|
}
|
|
|
|
private val patchesListCache = Caffeine
|
|
.newBuilder()
|
|
.maximumSize(1)
|
|
.build<String, ByteArray>()
|
|
|
|
suspend fun list(): ByteArray {
|
|
val patchesRelease = backendRepository.release(
|
|
configurationRepository.organization,
|
|
configurationRepository.patches.repository,
|
|
)
|
|
|
|
return withContext(Dispatchers.IO) {
|
|
patchesListCache.get(patchesRelease.tag) {
|
|
val patchesDownloadUrl = patchesRelease.assets
|
|
.first(configurationRepository.patches.assetRegex).downloadUrl
|
|
|
|
val signatureDownloadUrl = patchesRelease.assets
|
|
.first(configurationRepository.patches.signatureAssetRegex).downloadUrl
|
|
|
|
val patchesFile = kotlin.io.path.createTempFile().toFile().apply {
|
|
outputStream().use { URL(patchesDownloadUrl).openStream().copyTo(it) }
|
|
}
|
|
|
|
val patches = if (
|
|
signatureService.verify(
|
|
patchesFile,
|
|
signatureDownloadUrl,
|
|
configurationRepository.patches.publicKeyFile,
|
|
configurationRepository.patches.publicKeyId,
|
|
)
|
|
) {
|
|
PatchBundleLoader.Jar(patchesFile)
|
|
} else {
|
|
// Use an empty set of patches if the signature is invalid.
|
|
emptySet()
|
|
}
|
|
|
|
patchesFile.delete()
|
|
|
|
ByteArrayOutputStream().use { stream ->
|
|
PatchUtils.Json.serialize(patches, outputStream = stream)
|
|
|
|
stream.toByteArray()
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
fun publicKeys(): APIAssetPublicKeys {
|
|
fun publicKeyBase64(getAssetConfiguration: ConfigurationRepository.() -> ConfigurationRepository.AssetConfiguration) =
|
|
configurationRepository.getAssetConfiguration().publicKeyFile.readBytes().encodeBase64()
|
|
|
|
return APIAssetPublicKeys(
|
|
publicKeyBase64 { patches },
|
|
publicKeyBase64 { integrations },
|
|
)
|
|
}
|
|
}
|