Add OFFICIAL source & mine signature

This commit is contained in:
Cuong M. Tran 2024-01-19 18:06:12 +07:00
parent 81541ca67c
commit 6731edde87
No known key found for this signature in database
GPG key ID: 733AA7624B9315C2
7 changed files with 40 additions and 4 deletions

View file

@ -6,8 +6,8 @@ import tachiyomi.core.preference.plusAssign
class CreateExtensionRepo(private val preferences: SourcePreferences) {
fun await(name: String): Result {
// Do not allow invalid formats
if (!name.matches(repoRegex)) {
// Do not allow invalid formats & avoid adding duplicating official repo
if (!name.matches(repoRegex) || name.startsWith(OFFICIAL_REPO_BASE_URL)) {
return Result.InvalidUrl
}
@ -22,4 +22,5 @@ class CreateExtensionRepo(private val preferences: SourcePreferences) {
}
}
const val OFFICIAL_REPO_BASE_URL = "https://raw.githubusercontent.com/cuong-tran/tachiyomi-extensions/repo"
private val repoRegex = """^https://.*/index\.min\.json$""".toRegex()

View file

@ -170,6 +170,11 @@ private fun ExtensionDetails(
}
}
// SY <--
if (extension.isUnofficial) {
item {
WarningBanner(MR.strings.unofficial_extension_message)
}
}
if (extension.isObsolete) {
item {
WarningBanner(MR.strings.obsolete_extension_message)

View file

@ -354,6 +354,7 @@ private fun ExtensionItemContent(
val warning = when {
extension is Extension.Untrusted -> MR.strings.ext_untrusted
extension is Extension.Installed && extension.isUnofficial -> MR.strings.ext_unofficial
extension is Extension.Installed && extension.isObsolete -> MR.strings.ext_obsolete
// SY -->
extension is Extension.Installed && extension.isRedundant -> SYMR.strings.ext_redundant

View file

@ -1,6 +1,7 @@
package eu.kanade.tachiyomi.extension.api
import android.content.Context
import eu.kanade.domain.extension.interactor.OFFICIAL_REPO_BASE_URL
import eu.kanade.domain.source.service.SourcePreferences
import eu.kanade.tachiyomi.extension.ExtensionManager
import eu.kanade.tachiyomi.extension.model.Extension
@ -36,7 +37,13 @@ internal class ExtensionApi {
suspend fun findExtensions(): List<Extension.Available> {
return withIOContext {
sourcePreferences.extensionRepos().get().flatMap { getExtensions(it) }
// Combine built-in OFFICIAL repo's extensions list with repo's list
val extensions = buildList {
addAll(getExtensions(OFFICIAL_REPO_BASE_URL))
sourcePreferences.extensionRepos().get().map { addAll(getExtensions(it)) }
}
extensions
}
}

View file

@ -27,6 +27,7 @@ sealed class Extension {
val icon: Drawable?,
val hasUpdate: Boolean = false,
val isObsolete: Boolean = false,
val isUnofficial: Boolean = false,
val isShared: Boolean,
val repoUrl: String? = null,
// SY -->

View file

@ -59,6 +59,9 @@ internal object ExtensionLoader {
PackageManager.GET_SIGNATURES or
(if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.P) PackageManager.GET_SIGNING_CERTIFICATES else 0)
// cuong-tran's key
private const val officialSignature = "cbec121aa82ebb02aaa73806992e0368a97d47b5451ed6524816d03084c45905"
private const val PRIVATE_EXTENSION_EXTENSION = "ext"
private fun getPrivateExtensionDir(context: Context) = File(context.filesDir, "exts")
@ -252,7 +255,8 @@ internal object ExtensionLoader {
if (signatures.isNullOrEmpty()) {
logcat(LogPriority.WARN) { "Package $pkgName isn't signed" }
return LoadResult.Error
} else if (!trustExtension.isTrusted(pkgInfo, signatures.last())) {
} else if (!isTrusted(pkgInfo, signatures.last())) {
// If not trusted then will load it as Untrusted extension to force use to Trust it
val extension = Extension.Untrusted(
extName,
pkgName,
@ -320,6 +324,7 @@ internal object ExtensionLoader {
isNsfw = isNsfw,
sources = sources,
pkgFactory = appInfo.metaData.getString(METADATA_SOURCE_FACTORY),
isUnofficial = !isOfficiallySigned(signatures),
icon = appInfo.loadIcon(pkgManager),
isShared = extensionInfo.isShared,
)
@ -379,6 +384,20 @@ internal object ExtensionLoader {
?.toList()
}
private fun isTrusted(pkgInfo: PackageInfo, signatureHash: String): Boolean {
if (officialSignature == signatureHash) {
return true
}
return trustExtension.isTrusted(pkgInfo, signatureHash)
}
/**
* Showing UNOFFICIAL text on extension
*/
private fun isOfficiallySigned(signatures: List<String>): Boolean {
return signatures.all { it == officialSignature }
}
/**
* On Android 13+ the ApplicationInfo generated by getPackageArchiveInfo doesn't
* have sourceDir which breaks assets loading (used for getting icon here).

View file

@ -311,12 +311,14 @@
<string name="ext_installing">Installing</string>
<string name="ext_installed">Installed</string>
<string name="ext_trust">Trust</string>
<string name="ext_unofficial">Unofficial</string>
<string name="ext_untrusted">Untrusted</string>
<string name="ext_uninstall">Uninstall</string>
<string name="ext_app_info">App info</string>
<string name="untrusted_extension">Untrusted extension</string>
<string name="untrusted_extension_message">Malicious extensions can read any stored login credentials or execute arbitrary code.\n\nBy trusting this extension, you accept these risks.</string>
<string name="obsolete_extension_message">This extension is no longer available. It may not function properly and can cause issues with the app. Uninstalling it is recommended.</string>
<string name="unofficial_extension_message">This extension is not from the official repo.</string>
<string name="extension_api_error">Failed to fetch available extensions</string>
<string name="ext_info_version">Version</string>
<string name="ext_info_language">Language</string>