mirror of
https://github.com/Suwayomi/Suwayomi-Server.git
synced 2026-07-04 03:14:40 -05:00
Basic JWT implementation (#1524)
* Basic JWT implementation * Move JWT to UI_LOGIN mode and bring back SIMPLE_LOGIN as before * Update server/src/main/kotlin/suwayomi/tachidesk/global/impl/util/Jwt.kt Co-authored-by: Mitchell Syer <Syer10@users.noreply.github.com> * Refresh: Update only access token Co-authored-by: Mitchell Syer <Syer10@users.noreply.github.com> * Implement JWT Audience * Store JWT key Generates the key on startup if not set * Handle invalid Base64 * Make JWT expiry configurable * Missing value parse * Update server/src/main/kotlin/suwayomi/tachidesk/global/impl/util/Jwt.kt Co-authored-by: Mitchell Syer <Syer10@users.noreply.github.com> * Simplify Duration parsing * JWT Protect Mutations * JWT Protect Queries and Subscriptions * JWT Protect v1 WebSockets * WebSockets allow sending token via protocol header * Also respect the `suwayomi-server-token` cookie * JWT reduce default token expiry * JWT Support cookie on WebSocket as well * Lint * Authenticate graphql subscription via connection_init payload * WebView: Prefer explicit token over cookie This hack was implemented because WebView sent `"null"` if no token was supplied, just don't send a bad token, then we can do this properly * WebView: Implement basic login dialog if no token supplied --------- Co-authored-by: Mitchell Syer <Syer10@users.noreply.github.com> Co-authored-by: schroda <50052685+schroda@users.noreply.github.com>
This commit is contained in:
@@ -6,12 +6,14 @@ import androidx.preference.ListPreference
|
||||
import androidx.preference.MultiSelectListPreference
|
||||
import androidx.preference.SwitchPreferenceCompat
|
||||
import graphql.execution.DataFetcherResult
|
||||
import graphql.schema.DataFetchingEnvironment
|
||||
import org.jetbrains.exposed.sql.SqlExpressionBuilder.eq
|
||||
import org.jetbrains.exposed.sql.and
|
||||
import org.jetbrains.exposed.sql.deleteWhere
|
||||
import org.jetbrains.exposed.sql.selectAll
|
||||
import org.jetbrains.exposed.sql.transactions.transaction
|
||||
import suwayomi.tachidesk.graphql.asDataFetcherResult
|
||||
import suwayomi.tachidesk.graphql.server.getAttribute
|
||||
import suwayomi.tachidesk.graphql.types.FilterChange
|
||||
import suwayomi.tachidesk.graphql.types.MangaType
|
||||
import suwayomi.tachidesk.graphql.types.Preference
|
||||
@@ -25,7 +27,10 @@ import suwayomi.tachidesk.manga.impl.util.source.GetCatalogueSource
|
||||
import suwayomi.tachidesk.manga.model.table.MangaTable
|
||||
import suwayomi.tachidesk.manga.model.table.SourceMetaTable
|
||||
import suwayomi.tachidesk.manga.model.table.SourceTable
|
||||
import suwayomi.tachidesk.server.JavalinSetup.Attribute
|
||||
import suwayomi.tachidesk.server.JavalinSetup.future
|
||||
import suwayomi.tachidesk.server.JavalinSetup.getAttribute
|
||||
import suwayomi.tachidesk.server.user.requireUser
|
||||
import java.util.concurrent.CompletableFuture
|
||||
|
||||
class SourceMutation {
|
||||
@@ -39,7 +44,11 @@ class SourceMutation {
|
||||
val meta: SourceMetaType,
|
||||
)
|
||||
|
||||
fun setSourceMeta(input: SetSourceMetaInput): DataFetcherResult<SetSourceMetaPayload?> {
|
||||
fun setSourceMeta(
|
||||
dataFetchingEnvironment: DataFetchingEnvironment,
|
||||
input: SetSourceMetaInput,
|
||||
): DataFetcherResult<SetSourceMetaPayload?> {
|
||||
dataFetchingEnvironment.getAttribute(Attribute.TachideskUser).requireUser()
|
||||
val (clientMutationId, meta) = input
|
||||
|
||||
return asDataFetcherResult {
|
||||
@@ -61,7 +70,11 @@ class SourceMutation {
|
||||
val source: SourceType?,
|
||||
)
|
||||
|
||||
fun deleteSourceMeta(input: DeleteSourceMetaInput): DataFetcherResult<DeleteSourceMetaPayload?> {
|
||||
fun deleteSourceMeta(
|
||||
dataFetchingEnvironment: DataFetchingEnvironment,
|
||||
input: DeleteSourceMetaInput,
|
||||
): DataFetcherResult<DeleteSourceMetaPayload?> {
|
||||
dataFetchingEnvironment.getAttribute(Attribute.TachideskUser).requireUser()
|
||||
val (clientMutationId, sourceId, key) = input
|
||||
|
||||
return asDataFetcherResult {
|
||||
@@ -116,7 +129,11 @@ class SourceMutation {
|
||||
val hasNextPage: Boolean,
|
||||
)
|
||||
|
||||
fun fetchSourceManga(input: FetchSourceMangaInput): CompletableFuture<DataFetcherResult<FetchSourceMangaPayload?>> {
|
||||
fun fetchSourceManga(
|
||||
dataFetchingEnvironment: DataFetchingEnvironment,
|
||||
input: FetchSourceMangaInput,
|
||||
): CompletableFuture<DataFetcherResult<FetchSourceMangaPayload?>> {
|
||||
dataFetchingEnvironment.getAttribute(Attribute.TachideskUser).requireUser()
|
||||
val (clientMutationId, sourceId, type, page, query, filters) = input
|
||||
|
||||
return future {
|
||||
@@ -182,7 +199,11 @@ class SourceMutation {
|
||||
val source: SourceType,
|
||||
)
|
||||
|
||||
fun updateSourcePreference(input: UpdateSourcePreferenceInput): DataFetcherResult<UpdateSourcePreferencePayload?> {
|
||||
fun updateSourcePreference(
|
||||
dataFetchingEnvironment: DataFetchingEnvironment,
|
||||
input: UpdateSourcePreferenceInput,
|
||||
): DataFetcherResult<UpdateSourcePreferencePayload?> {
|
||||
dataFetchingEnvironment.getAttribute(Attribute.TachideskUser).requireUser()
|
||||
val (clientMutationId, sourceId, change) = input
|
||||
|
||||
return asDataFetcherResult {
|
||||
|
||||
Reference in New Issue
Block a user