Add new uuid mapping from v58698, add vtoken support

This commit is contained in:
Mikołaj Pich 2024-05-10 12:05:46 +02:00
parent 0766e5b30a
commit 6416b16b88
No known key found for this signature in database
8 changed files with 190 additions and 29 deletions

View file

@ -18,7 +18,7 @@ ext {
moshi = "1.13.0"
}
version = "2.6.2"
version = "2.6.3-SNAPSHOT"
group = "io.github.wulkanowy"
nexusPublishing {

View file

@ -2,11 +2,12 @@ package io.github.wulkanowy.sdk.scrapper
internal object ApiEndpoints : IApiEndpoints {
var currentVersion = 58666
var currentVersion = 58698
private val endpoints
get() = when (currentVersion) {
in 58666..Int.MAX_VALUE -> ApiEndpoints_24_4_2_58666
58698 -> ApiEndpoints_24_04_0003_58698
in 58666..58697 -> ApiEndpoints_24_4_2_58666
else -> ApiEndpoints_24_4_1_58566
}
@ -220,22 +221,22 @@ internal object ApiEndpoints_24_4_1_58566 : IApiEndpoints {
override val PlusContext = "Context"
override val PlusAutoryzacjaPesel = "AutoryzacjaPesel"
override val PlusFrekwencja = "Frekwencja"
override val PlusUsprawiedliwienia = "PlusUsprawiedliwienia"
override val PlusFrekwencjaStatystyki = "PlusFrekwencjaStatystyki"
override val PlusZarejestrowaneUrzadzenia = "PlusZarejestrowaneUrzadzenia"
override val PlusRejestracjaUrzadzeniaToken = "PlusRejestracjaUrzadzeniaToken"
override val PlusZebrania = "PlusZebrania"
override val PlusRealizacjaZajec = "PlusRealizacjaZajec"
override val PlusSprawdzianyZadaniaDomowe = "PlusSprawdzianyZadaniaDomowe"
override val PlusSprawdzianSzczegoly = "PlusSprawdzianSzczegoly"
override val PlusZadanieDomoweSzczegoly = "PlusZadanieDomoweSzczegoly"
override val PlusPlanZajec = "PlusPlanZajec"
override val PlusDniWolne = "PlusDniWolne"
override val PlusUwagi = "PlusUwagi"
override val PlusNauczyciele = "PlusNauczyciele"
override val PlusInformacje = "PlusInformacje"
override val PlusDaneUcznia = "PlusDaneUcznia"
override val PlusUczenZdjecie = "PlusUczenZdjecie"
override val PlusUsprawiedliwienia = "Usprawiedliwienia"
override val PlusFrekwencjaStatystyki = "FrekwencjaStatystyki"
override val PlusZarejestrowaneUrzadzenia = "ZarejestrowaneUrzadzenia"
override val PlusRejestracjaUrzadzeniaToken = "RejestracjaUrzadzeniaToken"
override val PlusZebrania = "Zebrania"
override val PlusRealizacjaZajec = "RealizacjaZajec"
override val PlusSprawdzianyZadaniaDomowe = "SprawdzianyZadaniaDomowe"
override val PlusSprawdzianSzczegoly = "SprawdzianSzczegoly"
override val PlusZadanieDomoweSzczegoly = "ZadanieDomoweSzczegoly"
override val PlusPlanZajec = "PlanZajec"
override val PlusDniWolne = "DniWolne"
override val PlusUwagi = "Uwagi"
override val PlusNauczyciele = "Nauczyciele"
override val PlusInformacje = "Informacje"
override val PlusDaneUcznia = "DaneUcznia"
override val PlusUczenZdjecie = "UczenZdjecie"
override val PlusOkresyKlasyfikacyjne = "OkresyKlasyfikacyjne"
override val PlusOceny = "Oceny"
@ -335,3 +336,84 @@ internal object ApiEndpoints_24_4_2_58666 : IApiEndpoints {
override val Delete = "cd379bae-9700-48b4-a0d0-9eca08ee908f"
override val RestoreTrash = "e6de58f9-4db1-4cd2-afdf-ac9fcca37e43"
}
internal object ApiEndpoints_24_04_0003_58698 : IApiEndpoints {
override val Autoryzacja = "b82c987d-8e94-4ed3-b46e-2d1818f2e0f8"
override val DostepOffice = "9d9b5874-68f4-4f1e-bef5-372f1cb11d29"
override val EgzaminySemestralne = "99b62670-2adc-4c17-9abc-6e3d42eec773"
override val EgzaminyZewnetrzne = "4db8f093-352a-4a00-a299-0e9b819c8c58"
override val EwidencjaObecnosci = "02429d97-5877-42ae-a44e-5dd7531e20b4"
override val FormularzeSzablony = "e02fac63-909e-450c-a4ab-75bfd4865189"
override val FormularzeSzablonyDownload = "FormularzeSzablonyDownload"
override val FormularzeWysylanie = "b97e880e-ae8d-44b6-a48d-92c9be7d22f5"
override val Frekwencja = "80dc9527-386d-4da5-b688-3c3a9c4c49a9"
override val FrekwencjaStatystyki = "a6d0fa58-5613-45e4-8f37-e2e5cba26dd3"
override val FrekwencjaStatystykiPrzedmioty = "baa947c6-915b-4498-afdb-11ec6b088d36"
override val Homework = "302944cd-7f41-4de8-8c9f-02dd00990f62"
override val Jadlospis = "738a6eff-3bb3-4ff7-9443-70e6e96b61ab"
override val LekcjeZaplanowane = "59874a90-98f2-4aa2-a857-f029b88a667c"
override val LekcjeZrealizowane = "23f18c73-b0eb-4a1a-b9d3-67b9f3513a12"
override val Oceny = "1e1ecd09-aa17-46ac-8cf4-90b1bf0c837d"
override val Ogloszenia = "ba99b004-dca2-41b4-af6b-13969546ce65"
override val Oplaty = "d58b34e4-0220-4363-b08f-fa307230898d"
override val PlanZajec = "e59d0f63-92e1-47d9-a8e1-293eed48e4b4"
override val Platnosc = "2b5d4da7-8b0f-45e0-923d-0b20d327800a"
override val PlatnoscMetadata = "ca5a0fa1-78f1-4fad-b7ac-59fbdf6bdaf4"
override val PodrecznikiLataSzkolne = "0c3f9d64-9561-42ab-825e-e73b4097c2d0"
override val PodrecznikiUcznia = "2e7a1def-cdc3-4944-862c-5e94207ae891"
override val Pomoc = "0cde801a-9290-4780-9099-96f7a130308e"
override val RejestracjaUrzadzeniaToken = "17786f90-2725-477f-98ac-f0e1bff11d7d"
override val RejestracjaUrzadzeniaTokenCertyfikat = "de16ca24-4638-4b11-8b2d-6ed09ec82b8a"
override val RozpoczeciePlatnosci = "90273adc-6308-47b1-be2b-b8d2297a1530"
override val ScalanieKont = "95661b3e-b9ac-416c-bf35-f195994f8af5"
override val Sprawdziany = "d6404626-e7e4-4093-8477-4eb964da19db"
override val Statystyki = "f8308032-0674-4bf7-a7d5-2642d064ef24"
override val SzkolaINauczyciele = "a5ec0ae3-f7eb-4548-a484-f725e0164634"
override val Uczen = "f8aa0d01-bd77-44d5-aa23-2606afbc27f5"
override val UczenCache = "21a5186d-2aab-4123-bad7-269aa7173bb2"
override val UczenDziennik = "a01ea13f-14f0-4c56-8b91-790e5aeecdf1"
override val UczenZdjecie = "b4a0f9aa-2a45-4e3d-bd9a-f1513e949f83"
override val Usprawiedliwienia = "81db3fa0-fb76-401a-ae9e-0fdffc86d2ff"
override val UwagiIOsiagniecia = "f63b7ca7-cfe2-4b0b-80cf-1ef1baed597d"
override val ZarejestrowaneUrzadzenia = "5a98cd83-f542-4bd2-a1eb-c53d75360aa7"
override val Zebrania = "fb20a581-5ad7-49ab-b640-ccdd3f74b0ea"
override val ZebraniaObecnosc = "a057e980-c662-4573-b485-01072dab2c14"
override val ZgloszoneNieobecnosci = "5c63a985-2149-4e7b-a30f-3692b16b69e3"
// uczenplus
override val PlusContext = "Context"
override val PlusAutoryzacjaPesel = "AutoryzacjaPesel"
override val PlusFrekwencja = "Frekwencja"
override val PlusUsprawiedliwienia = "Usprawiedliwienia"
override val PlusFrekwencjaStatystyki = "FrekwencjaStatystyki"
override val PlusZarejestrowaneUrzadzenia = "ZarejestrowaneUrzadzenia"
override val PlusRejestracjaUrzadzeniaToken = "RejestracjaUrzadzeniaToken"
override val PlusZebrania = "Zebrania"
override val PlusRealizacjaZajec = "RealizacjaZajec"
override val PlusSprawdzianyZadaniaDomowe = "SprawdzianyZadaniaDomowe"
override val PlusSprawdzianSzczegoly = "SprawdzianSzczegoly"
override val PlusZadanieDomoweSzczegoly = "ZadanieDomoweSzczegoly"
override val PlusPlanZajec = "PlanZajec"
override val PlusDniWolne = "DniWolne"
override val PlusUwagi = "Uwagi"
override val PlusNauczyciele = "Nauczyciele"
override val PlusInformacje = "Informacje"
override val PlusDaneUcznia = "DaneUcznia"
override val PlusUczenZdjecie = "UczenZdjecie"
override val PlusOkresyKlasyfikacyjne = "OkresyKlasyfikacyjne"
override val PlusOceny = "Oceny"
// wiadomosciplus
override val Skrzynki = "a04c1b46-48f5-4856-9eae-1efe9fface1a"
override val Odebrane = "be2f38a5-f090-4d38-b78a-1e776d304b20"
override val OdebraneSkrzynka = "4e096df8-70e9-4a7c-b72d-486d6d05d87d"
override val Wyslane = "dee02521-890a-4701-9699-de9b1080f30a"
override val WyslaneSkrzynka = "1aab4b35-fdeb-422d-9e62-b8337c2f1a31"
override val Usuniete = "9a1d2b04-763e-4e5a-8835-e356f52ed9b4"
override val UsunieteSkrzynka = "a3e8cd92-f3bd-4bf3-9a1b-63f20b475982"
override val WiadomoscOdpowiedzPrzekaz = "WiadomoscOdpowiedzPrzekaz"
override val WiadomoscNowa = "03051ddd-22dd-45a6-a214-211c8dab0f7d"
override val MoveTrash = "724f1218-447a-4110-a9ce-8c9bc52547f5"
override val Delete = "Delete"
override val RestoreTrash = "caf5eacb-a2ab-44d7-82c1-bcbd0b7612ed"
}

View file

@ -4,10 +4,12 @@ import io.github.wulkanowy.sdk.scrapper.login.UrlGenerator
import io.github.wulkanowy.sdk.scrapper.messages.Mailbox
import io.github.wulkanowy.sdk.scrapper.messages.Recipient
import io.github.wulkanowy.sdk.scrapper.messages.RecipientType
import io.github.wulkanowy.sdk.scrapper.messages.VTokenMapping
import org.jsoup.Jsoup
import org.slf4j.LoggerFactory
import retrofit2.HttpException
import retrofit2.Response
import java.security.MessageDigest
import java.text.Normalizer
import java.text.SimpleDateFormat
import java.time.Instant.ofEpochMilli
@ -186,3 +188,24 @@ internal fun <T> Response<T>.handleErrors(): Response<T> {
}
return this
}
@OptIn(ExperimentalStdlibApi::class)
internal fun String.md5(): String {
val md = MessageDigest.getInstance("MD5")
val digest = md.digest(this.toByteArray())
return digest.toHexString()
}
internal fun getVToken(uuid: String): String? {
if (uuid.isBlank()) return null
return buildString {
append(uuid)
append("-")
append(VTokenMapping.email)
append("-")
append(VTokenMapping.symbol)
append("-")
append(VTokenMapping.appVersion)
}.md5()
}

View file

@ -16,6 +16,8 @@ import io.github.wulkanowy.sdk.scrapper.login.LoginResult
import io.github.wulkanowy.sdk.scrapper.login.ModuleHeaders
import io.github.wulkanowy.sdk.scrapper.login.NotLoggedInException
import io.github.wulkanowy.sdk.scrapper.login.UrlGenerator
import io.github.wulkanowy.sdk.scrapper.md5
import io.github.wulkanowy.sdk.scrapper.messages.VTokenMapping
import io.github.wulkanowy.sdk.scrapper.repository.AccountRepository.Companion.SELECTOR_ADFS
import io.github.wulkanowy.sdk.scrapper.repository.AccountRepository.Companion.SELECTOR_ADFS_CARDS
import io.github.wulkanowy.sdk.scrapper.repository.AccountRepository.Companion.SELECTOR_ADFS_LIGHT
@ -147,6 +149,8 @@ internal class AutoLoginInterceptor(
appVersion = getScriptParam("version", htmlContent).ifBlank {
getScriptParam("appVersion", htmlContent)
},
email = getScriptParam("name", htmlContent),
symbol = getScriptParam("appCustomerDb", htmlContent),
)
if (moduleHeaders.token.isBlank()) {
@ -156,10 +160,19 @@ internal class AutoLoginInterceptor(
moduleHeaders.appVersion.substringAfterLast(".").toIntOrNull()?.let {
ApiEndpoints.currentVersion = it
VTokenMapping.currentVersion = it
}
when {
"uonetplus-wiadomosciplus" in url.host -> messagesModuleHeaders = moduleHeaders
"uonetplus-wiadomosciplus" in url.host -> {
messagesModuleHeaders = moduleHeaders
with(VTokenMapping) {
email = moduleHeaders.email
symbol = moduleHeaders.symbol
appVersion = moduleHeaders.appVersion
}
}
"uonetplus-uczenplus" in url.host -> studentPlusModuleHeaders = moduleHeaders
"uonetplus-uczen" in url.host -> studentModuleHeaders = moduleHeaders
}

View file

@ -4,4 +4,6 @@ internal data class ModuleHeaders(
val token: String,
val appGuid: String,
val appVersion: String,
val symbol: String? = null,
val email: String? = null,
)

View file

@ -0,0 +1,22 @@
package io.github.wulkanowy.sdk.scrapper.messages
object VTokenMapping {
var currentVersion = 58698
var email: String? = null
var symbol: String? = null
var appVersion: String? = null
const val Skrzynki = "7d4b1844-d114-40e3-a565-696564703b38"
const val Odebrane = "a94f324b-0ab8-43eb-830e-814d4a0b4aca"
const val OdebraneSkrzynka = "e17a1168-a8d1-45ba-b8e8-409cb25768a8"
const val Wyslane = "16d74af5-d36e-4c1e-93cb-21e20624d053"
const val WyslaneSkrzynka = "17a55992-7275-4c0c-945b-e0eca7bbc847"
const val Usuniete = "cf13626d-df9d-4401-8a32-bd5c3e1a13d0"
const val UsunieteSkrzynka = "bc17a165-2619-466e-bb40-2bbcd977d634"
const val WiadomoscOdpowiedzPrzekaz = ""
const val WiadomoscNowa = ""
const val MoveTrash = ""
const val RestoreTrash = ""
const val Delete = ""
}

View file

@ -100,7 +100,7 @@ internal class MessagesRepository(
if (markAsRead) {
runCatching {
loginModule()
api.markMessageAsRead(mapOf("apiGlobalKey" to globalKey))
api.markMessageAsRead(body = mapOf("apiGlobalKey" to globalKey))
}
.onFailure { logger.error("Error occur while marking message as read", it) }
.getOrNull()
@ -128,13 +128,13 @@ internal class MessagesRepository(
suspend fun deleteMessages(globalKeys: List<String>, removeForever: Boolean) {
loginModule()
when {
!removeForever -> api.moveMessageToTrash(globalKeys)
else -> api.deleteMessage(globalKeys)
!removeForever -> api.moveMessageToTrash(body = globalKeys)
else -> api.deleteMessage(body = globalKeys)
}
}
suspend fun restoreFromTrash(globalKeys: List<String>) {
api.restoreFromTrash(globalKeys)
api.restoreFromTrash(body = globalKeys)
}
private suspend fun loginModule() {

View file

@ -1,12 +1,14 @@
package io.github.wulkanowy.sdk.scrapper.service
import io.github.wulkanowy.sdk.scrapper.ApiEndpoints
import io.github.wulkanowy.sdk.scrapper.getVToken
import io.github.wulkanowy.sdk.scrapper.messages.Mailbox
import io.github.wulkanowy.sdk.scrapper.messages.MessageDetails
import io.github.wulkanowy.sdk.scrapper.messages.MessageMeta
import io.github.wulkanowy.sdk.scrapper.messages.MessageReplayDetails
import io.github.wulkanowy.sdk.scrapper.messages.Recipient
import io.github.wulkanowy.sdk.scrapper.messages.SendMessageRequest
import io.github.wulkanowy.sdk.scrapper.messages.VTokenMapping
import retrofit2.http.Body
import retrofit2.http.FieldMap
import retrofit2.http.FormUrlEncoded
@ -32,13 +34,17 @@ internal interface MessagesService {
): String
@GET("api/{path}")
suspend fun getMailboxes(@Path("path") path: String = ApiEndpoints.Skrzynki): List<Mailbox>
suspend fun getMailboxes(
@Header("V-Token") vToken: String? = getVToken(VTokenMapping.Skrzynki),
@Path("path") path: String = ApiEndpoints.Skrzynki,
): List<Mailbox>
@GET("api/Pracownicy")
suspend fun getRecipients(@Query("globalKeySkrzynka") mailboxKey: String): List<Recipient>
@GET("api/{path}")
suspend fun getReceived(
@Header("V-Token") vToken: String? = getVToken(VTokenMapping.Odebrane),
@Path("path") path: String = ApiEndpoints.Odebrane,
@Query("idLastWiadomosc") lastMessageKey: Int = 0,
@Query("pageSize") pageSize: Int = 50,
@ -46,6 +52,7 @@ internal interface MessagesService {
@GET("api/{path}")
suspend fun getReceivedMailbox(
@Header("V-Token") vToken: String? = getVToken(VTokenMapping.OdebraneSkrzynka),
@Path("path") path: String = ApiEndpoints.OdebraneSkrzynka,
@Query("globalKeySkrzynka") mailboxKey: String,
@Query("idLastWiadomosc") lastMessageKey: Int = 0,
@ -54,6 +61,7 @@ internal interface MessagesService {
@GET("api/{path}")
suspend fun getSent(
@Header("V-Token") vToken: String? = getVToken(VTokenMapping.Wyslane),
@Path("path") path: String = ApiEndpoints.Wyslane,
@Query("idLastWiadomosc") lastMessageKey: Int = 0,
@Query("pageSize") pageSize: Int = 50,
@ -61,6 +69,7 @@ internal interface MessagesService {
@GET("api/{path}")
suspend fun getSentMailbox(
@Header("V-Token") vToken: String? = getVToken(VTokenMapping.WyslaneSkrzynka),
@Path("path") path: String = ApiEndpoints.WyslaneSkrzynka,
@Query("globalKeySkrzynka") mailboxKey: String,
@Query("idLastWiadomosc") lastMessageKey: Int = 0,
@ -69,6 +78,7 @@ internal interface MessagesService {
@GET("api/{path}")
suspend fun getDeleted(
@Header("V-Token") vToken: String? = getVToken(VTokenMapping.Usuniete),
@Path("path") path: String = ApiEndpoints.Usuniete,
@Query("idLastWiadomosc") lastMessageKey: Int = 0,
@Query("pageSize") pageSize: Int = 50,
@ -76,6 +86,7 @@ internal interface MessagesService {
@GET("api/{path}")
suspend fun getDeletedMailbox(
@Header("V-Token") vToken: String? = getVToken(VTokenMapping.UsunieteSkrzynka),
@Path("path") path: String = ApiEndpoints.UsunieteSkrzynka,
@Query("globalKeySkrzynka") mailboxKey: String,
@Query("idLastWiadomosc") lastMessageKey: Int = 0,
@ -90,28 +101,36 @@ internal interface MessagesService {
@GET("api/{path}")
suspend fun getMessageReplayDetails(
@Header("V-Token") vToken: String? = getVToken(VTokenMapping.WiadomoscOdpowiedzPrzekaz),
@Path("path") path: String = ApiEndpoints.WiadomoscOdpowiedzPrzekaz,
@Query("apiGlobalKey") globalKey: String,
): MessageReplayDetails
@POST("api/{path}")
suspend fun sendMessage(
@Header("V-Token") vToken: String? = getVToken(VTokenMapping.WiadomoscNowa),
@Path("path") path: String = ApiEndpoints.WiadomoscNowa,
@Body body: SendMessageRequest,
)
@POST("api/{path}")
suspend fun moveMessageToTrash(
@Body body: List<String>,
@Header("V-Token") vToken: String? = getVToken(VTokenMapping.MoveTrash),
@Path("path") path: String = ApiEndpoints.MoveTrash,
@Body body: List<String>,
)
@POST("api/{path}")
suspend fun restoreFromTrash(
@Body body: List<String>,
@Header("V-Token") vToken: String? = getVToken(VTokenMapping.RestoreTrash),
@Path("path") path: String = ApiEndpoints.RestoreTrash,
@Body body: List<String>,
)
@POST("api/Delete")
suspend fun deleteMessage(@Body body: List<String>)
@POST("api/{path}")
suspend fun deleteMessage(
@Header("V-Token") vToken: String? = getVToken(VTokenMapping.Delete),
@Path("path") path: String = ApiEndpoints.Delete,
@Body body: List<String>,
)
}