feat: Remove deprecated routes and old API

Backwards compatibility should be and is now handled by the reverse proxy.
This commit is contained in:
oSumAtrIX 2024-11-06 04:26:51 +01:00
parent 0b66fc2bca
commit eca40a6979
No known key found for this signature in database
GPG Key ID: A9B3094ACDB604B4
9 changed files with 12 additions and 141 deletions

View File

@ -81,7 +81,6 @@ Some of the features ReVanced API include:
and links of the hoster of ReVanced API and links of the hoster of ReVanced API
- 🧩 **Patches**: Get the latest updates of ReVanced Patches, directly from ReVanced API - 🧩 **Patches**: Get the latest updates of ReVanced Patches, directly from ReVanced API
- 👥 **Contributors**: List all contributors involved in the project - 👥 **Contributors**: List all contributors involved in the project
- 🔄 **Backwards compatibility**: Proxy an old API for migration purposes and backwards compatibility
## 🚀 How to get started ## 🚀 How to get started

View File

@ -4,7 +4,6 @@ cors-allowed-hosts = [
"*.revanced.app" "*.revanced.app"
] ]
endpoint = "https://api.revanced.app" endpoint = "https://api.revanced.app"
old-api-endpoint = "https://old-api.revanced.app"
static-files-path = "static/root" static-files-path = "static/root"
versioned-static-files-path = "static/versioned" versioned-static-files-path = "static/versioned"
backend-service-name = "GitHub" backend-service-name = "GitHub"

View File

@ -51,7 +51,6 @@ fun Application.configureDependencies(
AuthenticationService(issuer, validityInMin, jwtSecret, authSHA256DigestString) AuthenticationService(issuer, validityInMin, jwtSecret, authSHA256DigestString)
} }
singleOf(::OldApiService)
singleOf(::AnnouncementService) singleOf(::AnnouncementService)
singleOf(::SignatureService) singleOf(::SignatureService)
singleOf(::PatchesService) singleOf(::PatchesService)

View File

@ -4,7 +4,6 @@ import app.revanced.api.configuration.repository.ConfigurationRepository
import app.revanced.api.configuration.routes.* import app.revanced.api.configuration.routes.*
import app.revanced.api.configuration.routes.announcementsRoute import app.revanced.api.configuration.routes.announcementsRoute
import app.revanced.api.configuration.routes.apiRoute import app.revanced.api.configuration.routes.apiRoute
import app.revanced.api.configuration.routes.oldApiRoute
import app.revanced.api.configuration.routes.patchesRoute import app.revanced.api.configuration.routes.patchesRoute
import io.bkbn.kompendium.core.routes.redoc import io.bkbn.kompendium.core.routes.redoc
import io.bkbn.kompendium.core.routes.swagger import io.bkbn.kompendium.core.routes.swagger
@ -55,7 +54,4 @@ internal fun Application.configureRouting() = routing {
swagger(pageTitle = "ReVanced API", path = "/") swagger(pageTitle = "ReVanced API", path = "/")
redoc(pageTitle = "ReVanced API", path = "/redoc") redoc(pageTitle = "ReVanced API", path = "/redoc")
// TODO: Remove, once migration period from v2 API is over (In 1-2 years).
oldApiRoute()
} }

View File

@ -30,7 +30,6 @@ import kotlin.io.path.createDirectories
* @property apiVersion The version to use for the API. * @property apiVersion The version to use for the API.
* @property corsAllowedHosts The hosts allowed to make requests to the API. * @property corsAllowedHosts The hosts allowed to make requests to the API.
* @property endpoint The endpoint of the API. * @property endpoint The endpoint of the API.
* @property oldApiEndpoint The endpoint of the old API to proxy requests to.
* @property staticFilesPath The path to the static files to be served under the root path. * @property staticFilesPath The path to the static files to be served under the root path.
* @property versionedStaticFilesPath The path to the static files to be served under a versioned path. * @property versionedStaticFilesPath The path to the static files to be served under a versioned path.
* @property about The path to the json file deserialized to [APIAbout] * @property about The path to the json file deserialized to [APIAbout]
@ -50,8 +49,6 @@ internal class ConfigurationRepository(
@SerialName("cors-allowed-hosts") @SerialName("cors-allowed-hosts")
val corsAllowedHosts: Set<String>, val corsAllowedHosts: Set<String>,
val endpoint: String, val endpoint: String,
@SerialName("old-api-endpoint")
val oldApiEndpoint: String,
@Serializable(with = PathSerializer::class) @Serializable(with = PathSerializer::class)
@SerialName("static-files-path") @SerialName("static-files-path")
val staticFilesPath: Path, val staticFilesPath: Path,

View File

@ -13,18 +13,9 @@ import io.ktor.server.routing.*
import org.koin.ktor.ext.get as koinGet import org.koin.ktor.ext.get as koinGet
internal fun Route.managerRoute() = route("manager") { internal fun Route.managerRoute() = route("manager") {
configure()
// TODO: Remove this deprecated route eventually.
route("latest") {
configure(deprecated = true)
}
}
private fun Route.configure(deprecated: Boolean = false) {
val managerService = koinGet<ManagerService>() val managerService = koinGet<ManagerService>()
installManagerRouteDocumentation(deprecated) installManagerRouteDocumentation()
rateLimit(RateLimitName("weak")) { rateLimit(RateLimitName("weak")) {
get { get {
@ -32,7 +23,7 @@ private fun Route.configure(deprecated: Boolean = false) {
} }
route("version") { route("version") {
installManagerVersionRouteDocumentation(deprecated) installManagerVersionRouteDocumentation()
get { get {
call.respond(managerService.latestVersion()) call.respond(managerService.latestVersion())
@ -41,11 +32,10 @@ private fun Route.configure(deprecated: Boolean = false) {
} }
} }
private fun Route.installManagerRouteDocumentation(deprecated: Boolean) = installNotarizedRoute { private fun Route.installManagerRouteDocumentation() = installNotarizedRoute {
tags = setOf("Manager") tags = setOf("Manager")
get = GetInfo.builder { get = GetInfo.builder {
if (deprecated) isDeprecated()
description("Get the current manager release") description("Get the current manager release")
summary("Get current manager release") summary("Get current manager release")
response { response {
@ -57,11 +47,10 @@ private fun Route.installManagerRouteDocumentation(deprecated: Boolean) = instal
} }
} }
private fun Route.installManagerVersionRouteDocumentation(deprecated: Boolean) = installNotarizedRoute { private fun Route.installManagerVersionRouteDocumentation() = installNotarizedRoute {
tags = setOf("Manager") tags = setOf("Manager")
get = GetInfo.builder { get = GetInfo.builder {
if (deprecated) isDeprecated()
description("Get the current manager release version") description("Get the current manager release version")
summary("Get current manager release version") summary("Get current manager release version")
response { response {

View File

@ -1,19 +0,0 @@
package app.revanced.api.configuration.routes
import app.revanced.api.configuration.services.OldApiService
import io.ktor.server.application.*
import io.ktor.server.plugins.ratelimit.*
import io.ktor.server.routing.*
import org.koin.ktor.ext.get
internal fun Route.oldApiRoute() {
val oldApiService = get<OldApiService>()
rateLimit(RateLimitName("weak")) {
route(Regex("/(v2|tools|contributors).*")) {
handle {
oldApiService.proxy(call)
}
}
}
}

View File

@ -16,18 +16,9 @@ import kotlin.time.Duration.Companion.days
import org.koin.ktor.ext.get as koinGet import org.koin.ktor.ext.get as koinGet
internal fun Route.patchesRoute() = route("patches") { internal fun Route.patchesRoute() = route("patches") {
configure()
// TODO: Remove this deprecated route eventually.
route("latest") {
configure(deprecated = true)
}
}
private fun Route.configure(deprecated: Boolean = false) {
val patchesService = koinGet<PatchesService>() val patchesService = koinGet<PatchesService>()
installPatchesRouteDocumentation(deprecated) installPatchesRouteDocumentation()
rateLimit(RateLimitName("weak")) { rateLimit(RateLimitName("weak")) {
get { get {
@ -35,7 +26,7 @@ private fun Route.configure(deprecated: Boolean = false) {
} }
route("version") { route("version") {
installPatchesVersionRouteDocumentation(deprecated) installPatchesVersionRouteDocumentation()
get { get {
call.respond(patchesService.latestVersion()) call.respond(patchesService.latestVersion())
@ -45,7 +36,7 @@ private fun Route.configure(deprecated: Boolean = false) {
rateLimit(RateLimitName("strong")) { rateLimit(RateLimitName("strong")) {
route("list") { route("list") {
installPatchesListRouteDocumentation(deprecated) installPatchesListRouteDocumentation()
get { get {
call.respondBytes(ContentType.Application.Json) { patchesService.list() } call.respondBytes(ContentType.Application.Json) { patchesService.list() }
@ -57,7 +48,7 @@ private fun Route.configure(deprecated: Boolean = false) {
route("keys") { route("keys") {
installCache(356.days) installCache(356.days)
installPatchesPublicKeyRouteDocumentation(deprecated) installPatchesPublicKeyRouteDocumentation()
get { get {
call.respond(patchesService.publicKey()) call.respond(patchesService.publicKey())
@ -66,11 +57,10 @@ private fun Route.configure(deprecated: Boolean = false) {
} }
} }
private fun Route.installPatchesRouteDocumentation(deprecated: Boolean) = installNotarizedRoute { private fun Route.installPatchesRouteDocumentation() = installNotarizedRoute {
tags = setOf("Patches") tags = setOf("Patches")
get = GetInfo.builder { get = GetInfo.builder {
if (deprecated) isDeprecated()
description("Get the current patches release") description("Get the current patches release")
summary("Get current patches release") summary("Get current patches release")
response { response {
@ -82,11 +72,10 @@ private fun Route.installPatchesRouteDocumentation(deprecated: Boolean) = instal
} }
} }
private fun Route.installPatchesVersionRouteDocumentation(deprecated: Boolean) = installNotarizedRoute { private fun Route.installPatchesVersionRouteDocumentation() = installNotarizedRoute {
tags = setOf("Patches") tags = setOf("Patches")
get = GetInfo.builder { get = GetInfo.builder {
if (deprecated) isDeprecated()
description("Get the current patches release version") description("Get the current patches release version")
summary("Get current patches release version") summary("Get current patches release version")
response { response {
@ -98,11 +87,10 @@ private fun Route.installPatchesVersionRouteDocumentation(deprecated: Boolean) =
} }
} }
private fun Route.installPatchesListRouteDocumentation(deprecated: Boolean) = installNotarizedRoute { private fun Route.installPatchesListRouteDocumentation() = installNotarizedRoute {
tags = setOf("Patches") tags = setOf("Patches")
get = GetInfo.builder { get = GetInfo.builder {
if (deprecated) isDeprecated()
description("Get the list of patches from the current patches release") description("Get the list of patches from the current patches release")
summary("Get list of patches from current patches release") summary("Get list of patches from current patches release")
response { response {
@ -114,11 +102,10 @@ private fun Route.installPatchesListRouteDocumentation(deprecated: Boolean) = in
} }
} }
private fun Route.installPatchesPublicKeyRouteDocumentation(deprecated: Boolean) = installNotarizedRoute { private fun Route.installPatchesPublicKeyRouteDocumentation() = installNotarizedRoute {
tags = setOf("Patches") tags = setOf("Patches")
get = GetInfo.builder { get = GetInfo.builder {
if (deprecated) isDeprecated()
description("Get the public keys for verifying patches assets") description("Get the public keys for verifying patches assets")
summary("Get patches public keys") summary("Get patches public keys")
response { response {

View File

@ -1,76 +0,0 @@
package app.revanced.api.configuration.services
import app.revanced.api.configuration.repository.ConfigurationRepository
import io.ktor.client.*
import io.ktor.client.engine.okhttp.*
import io.ktor.client.plugins.*
import io.ktor.client.request.*
import io.ktor.client.statement.*
import io.ktor.http.*
import io.ktor.http.content.*
import io.ktor.server.application.*
import io.ktor.server.request.*
import io.ktor.server.response.*
import io.ktor.util.*
import io.ktor.utils.io.*
internal class OldApiService(configurationRepository: ConfigurationRepository) {
private val client = HttpClient(OkHttp) {
defaultRequest { url(configurationRepository.oldApiEndpoint) }
}
@OptIn(InternalAPI::class)
suspend fun proxy(call: ApplicationCall) {
val channel = call.request.receiveChannel()
val size = channel.availableForRead
val byteArray = ByteArray(size)
channel.readFully(byteArray)
val response: HttpResponse = client.request(call.request.uri) {
method = call.request.httpMethod
headers {
appendAll(
call.request.headers.filter { key, _ ->
!(
key.equals(HttpHeaders.ContentType, ignoreCase = true) ||
key.equals(HttpHeaders.ContentLength, ignoreCase = true) ||
key.equals(HttpHeaders.Host, ignoreCase = true)
)
},
)
}
when (call.request.httpMethod) {
HttpMethod.Post,
HttpMethod.Put,
HttpMethod.Patch,
HttpMethod.Delete,
-> body = ByteArrayContent(byteArray, call.request.contentType())
}
}
val headers = response.headers
call.respond(object : OutgoingContent.WriteChannelContent() {
override val contentLength: Long? = headers[HttpHeaders.ContentLength]?.toLong()
override val contentType = headers[HttpHeaders.ContentType]?.let { ContentType.parse(it) }
override val headers: Headers = Headers.build {
appendAll(
headers.filter { key, _ ->
!key.equals(
HttpHeaders.ContentType,
ignoreCase = true,
) &&
!key.equals(HttpHeaders.ContentLength, ignoreCase = true)
},
)
}
override val status = response.status
override suspend fun writeTo(channel: ByteWriteChannel) {
response.content.copyAndClose(channel)
}
})
}
}