64 lines
2.0 KiB
Kotlin
64 lines
2.0 KiB
Kotlin
package dev.inmo.tgbotapi.utils
|
|
|
|
import korlibs.crypto.*
|
|
import io.ktor.http.decodeURLQueryComponent
|
|
import io.ktor.utils.io.core.toByteArray
|
|
|
|
const val telegramBotAPIDefaultUrl = "https://api.telegram.org"
|
|
|
|
private inline val String.withoutLastSlash: String
|
|
get() {
|
|
var correctedUrl = this
|
|
while (true) {
|
|
val withoutSuffix = correctedUrl.removeSuffix("/")
|
|
if (withoutSuffix == correctedUrl) {
|
|
return correctedUrl
|
|
}
|
|
correctedUrl = withoutSuffix
|
|
}
|
|
}
|
|
|
|
class TelegramAPIUrlsKeeper(
|
|
token: String,
|
|
hostUrl: String = telegramBotAPIDefaultUrl,
|
|
urlsSuffixes: String = ""
|
|
) {
|
|
val webAppDataSecretKeyHash by lazy {
|
|
HMAC.hmacSHA256("WebAppData".toByteArray(), token.toByteArray())
|
|
}
|
|
val webAppDataSecretKey
|
|
get() = webAppDataSecretKeyHash.hexLower
|
|
|
|
val commonAPIUrl: String
|
|
val fileBaseUrl: String
|
|
|
|
constructor(token: String, testServer: Boolean, hostUrl: String = telegramBotAPIDefaultUrl) : this(
|
|
token,
|
|
hostUrl,
|
|
"/test".takeIf { testServer } ?: ""
|
|
)
|
|
|
|
init {
|
|
val correctedHost = hostUrl.withoutLastSlash
|
|
commonAPIUrl = "$correctedHost/bot$token$urlsSuffixes"
|
|
fileBaseUrl = "$correctedHost/file/bot$token$urlsSuffixes"
|
|
}
|
|
|
|
fun createFileLinkUrl(filePath: String) = "${fileBaseUrl}/$filePath"
|
|
|
|
/**
|
|
* @param rawData Data from [dev.inmo.tgbotapi.webapps.WebApp.initData]
|
|
* @param hash Data from [dev.inmo.tgbotapi.webapps.WebApp.initDataUnsafe] from the field [dev.inmo.tgbotapi.webapps.WebAppInitData.hash]
|
|
*/
|
|
fun checkWebAppData(rawData: String, hash: String): Boolean {
|
|
val preparedData = rawData
|
|
.decodeURLQueryComponent()
|
|
.split("&")
|
|
.filterNot { it.startsWith("hash=") }
|
|
.sorted()
|
|
.joinToString("\n")
|
|
|
|
return HMAC.hmacSHA256(webAppDataSecretKeyHash.bytes, preparedData.toByteArray()).hexLower == hash.lowercase()
|
|
}
|
|
}
|