diff --git a/server/src/main/kotlin/suwayomi/tachidesk/graphql/directives/RequireAuth.kt b/server/src/main/kotlin/suwayomi/tachidesk/graphql/directives/RequireAuth.kt new file mode 100644 index 00000000..007b18c1 --- /dev/null +++ b/server/src/main/kotlin/suwayomi/tachidesk/graphql/directives/RequireAuth.kt @@ -0,0 +1,23 @@ +/* + * Copyright (C) Contributors to the Suwayomi project + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at https://mozilla.org/MPL/2.0/. */ + +package suwayomi.tachidesk.graphql.directives + +import com.expediagroup.graphql.generator.annotations.GraphQLDirective +import graphql.introspection.Introspection.DirectiveLocation + +@GraphQLDirective( + name = "requireAuth", + description = "Requires user authentication", + locations = [ + DirectiveLocation.FIELD_DEFINITION, + DirectiveLocation.OBJECT, + ], +) +@Target(AnnotationTarget.FUNCTION, AnnotationTarget.CLASS) +@Retention(AnnotationRetention.RUNTIME) +annotation class RequireAuth diff --git a/server/src/main/kotlin/suwayomi/tachidesk/graphql/directives/RequireAuthDirectiveWiring.kt b/server/src/main/kotlin/suwayomi/tachidesk/graphql/directives/RequireAuthDirectiveWiring.kt new file mode 100644 index 00000000..8fcfbe3c --- /dev/null +++ b/server/src/main/kotlin/suwayomi/tachidesk/graphql/directives/RequireAuthDirectiveWiring.kt @@ -0,0 +1,50 @@ +/* + * Copyright (C) Contributors to the Suwayomi project + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at https://mozilla.org/MPL/2.0/. */ + +package suwayomi.tachidesk.graphql.directives + +import com.expediagroup.graphql.generator.directives.KotlinFieldDirectiveEnvironment +import com.expediagroup.graphql.generator.directives.KotlinSchemaDirectiveWiring +import graphql.schema.DataFetcher +import graphql.schema.DataFetchingEnvironmentImpl +import graphql.schema.GraphQLFieldDefinition +import suwayomi.tachidesk.graphql.server.getAttribute +import suwayomi.tachidesk.server.JavalinSetup.Attribute +import suwayomi.tachidesk.server.user.requireUser + +private const val USER_ID_PARAM = "userId" + +class RequireAuthDirectiveWiring : KotlinSchemaDirectiveWiring { + override fun onField(environment: KotlinFieldDirectiveEnvironment): GraphQLFieldDefinition { + val originalDataFetcher = environment.getDataFetcher() + + val authDataFetcher = + DataFetcher { env -> + val user = env.graphQlContext.getAttribute(Attribute.TachideskUser) + val userId = user.requireUser() + + if (env.arguments.containsKey(USER_ID_PARAM)) { + throw Exception("\"$USER_ID_PARAM\" is a reserved parameter for RequireAuth") + } + + // Create a new environment with userId added to arguments + val newArguments: MutableMap = env.arguments.toMutableMap() + newArguments[USER_ID_PARAM] = userId + + val modifiedEnv = + DataFetchingEnvironmentImpl + .newDataFetchingEnvironment(env) + .arguments(newArguments) + .build() + + originalDataFetcher.get(modifiedEnv) + } + + environment.setDataFetcher(authDataFetcher) + return environment.element + } +} diff --git a/server/src/main/kotlin/suwayomi/tachidesk/graphql/mutations/BackupMutation.kt b/server/src/main/kotlin/suwayomi/tachidesk/graphql/mutations/BackupMutation.kt index 95723ce9..712f121c 100644 --- a/server/src/main/kotlin/suwayomi/tachidesk/graphql/mutations/BackupMutation.kt +++ b/server/src/main/kotlin/suwayomi/tachidesk/graphql/mutations/BackupMutation.kt @@ -1,21 +1,17 @@ package suwayomi.tachidesk.graphql.mutations -import graphql.schema.DataFetchingEnvironment import io.javalin.http.UploadedFile import kotlinx.coroutines.flow.first import kotlinx.coroutines.withTimeout +import suwayomi.tachidesk.graphql.directives.RequireAuth import suwayomi.tachidesk.graphql.server.TemporaryFileStorage -import suwayomi.tachidesk.graphql.server.getAttribute import suwayomi.tachidesk.graphql.types.BackupRestoreStatus import suwayomi.tachidesk.graphql.types.toStatus import suwayomi.tachidesk.manga.impl.backup.BackupFlags import suwayomi.tachidesk.manga.impl.backup.proto.ProtoBackupExport import suwayomi.tachidesk.manga.impl.backup.proto.ProtoBackupImport import suwayomi.tachidesk.manga.impl.backup.proto.models.Backup -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 import kotlin.time.Duration.Companion.seconds @@ -31,11 +27,8 @@ class BackupMutation { val status: BackupRestoreStatus?, ) - fun restoreBackup( - dataFetchingEnvironment: DataFetchingEnvironment, - input: RestoreBackupInput, - ): CompletableFuture { - dataFetchingEnvironment.getAttribute(Attribute.TachideskUser).requireUser() + @RequireAuth + fun restoreBackup(input: RestoreBackupInput): CompletableFuture { val (clientMutationId, backup) = input return future { @@ -66,11 +59,8 @@ class BackupMutation { val url: String, ) - fun createBackup( - dataFetchingEnvironment: DataFetchingEnvironment, - input: CreateBackupInput? = null, - ): CreateBackupPayload { - dataFetchingEnvironment.getAttribute(Attribute.TachideskUser).requireUser() + @RequireAuth + fun createBackup(input: CreateBackupInput? = null): CreateBackupPayload { val filename = Backup.getFilename() val backup = diff --git a/server/src/main/kotlin/suwayomi/tachidesk/graphql/mutations/CategoryMutation.kt b/server/src/main/kotlin/suwayomi/tachidesk/graphql/mutations/CategoryMutation.kt index c3d0c802..ba3f8b9b 100644 --- a/server/src/main/kotlin/suwayomi/tachidesk/graphql/mutations/CategoryMutation.kt +++ b/server/src/main/kotlin/suwayomi/tachidesk/graphql/mutations/CategoryMutation.kt @@ -1,7 +1,6 @@ package suwayomi.tachidesk.graphql.mutations import graphql.execution.DataFetcherResult -import graphql.schema.DataFetchingEnvironment import org.jetbrains.exposed.sql.SqlExpressionBuilder.eq import org.jetbrains.exposed.sql.SqlExpressionBuilder.inList import org.jetbrains.exposed.sql.SqlExpressionBuilder.minus @@ -13,7 +12,7 @@ import org.jetbrains.exposed.sql.selectAll import org.jetbrains.exposed.sql.transactions.transaction import org.jetbrains.exposed.sql.update import suwayomi.tachidesk.graphql.asDataFetcherResult -import suwayomi.tachidesk.graphql.server.getAttribute +import suwayomi.tachidesk.graphql.directives.RequireAuth import suwayomi.tachidesk.graphql.types.CategoryMetaType import suwayomi.tachidesk.graphql.types.CategoryType import suwayomi.tachidesk.graphql.types.MangaType @@ -25,9 +24,6 @@ import suwayomi.tachidesk.manga.model.table.CategoryMangaTable import suwayomi.tachidesk.manga.model.table.CategoryMetaTable import suwayomi.tachidesk.manga.model.table.CategoryTable import suwayomi.tachidesk.manga.model.table.MangaTable -import suwayomi.tachidesk.server.JavalinSetup.Attribute -import suwayomi.tachidesk.server.JavalinSetup.getAttribute -import suwayomi.tachidesk.server.user.requireUser class CategoryMutation { data class SetCategoryMetaInput( @@ -40,12 +36,9 @@ class CategoryMutation { val meta: CategoryMetaType, ) - fun setCategoryMeta( - dataFetchingEnvironment: DataFetchingEnvironment, - input: SetCategoryMetaInput, - ): DataFetcherResult = + @RequireAuth + fun setCategoryMeta(input: SetCategoryMetaInput): DataFetcherResult = asDataFetcherResult { - dataFetchingEnvironment.getAttribute(Attribute.TachideskUser).requireUser() val (clientMutationId, meta) = input Category.modifyMeta(meta.categoryId, meta.key, meta.value) @@ -65,12 +58,9 @@ class CategoryMutation { val category: CategoryType, ) - fun deleteCategoryMeta( - dataFetchingEnvironment: DataFetchingEnvironment, - input: DeleteCategoryMetaInput, - ): DataFetcherResult = + @RequireAuth + fun deleteCategoryMeta(input: DeleteCategoryMetaInput): DataFetcherResult = asDataFetcherResult { - dataFetchingEnvironment.getAttribute(Attribute.TachideskUser).requireUser() val (clientMutationId, categoryId, key) = input val (meta, category) = @@ -163,12 +153,9 @@ class CategoryMutation { } } - fun updateCategory( - dataFetchingEnvironment: DataFetchingEnvironment, - input: UpdateCategoryInput, - ): DataFetcherResult = + @RequireAuth + fun updateCategory(input: UpdateCategoryInput): DataFetcherResult = asDataFetcherResult { - dataFetchingEnvironment.getAttribute(Attribute.TachideskUser).requireUser() val (clientMutationId, id, patch) = input updateCategories(listOf(id), patch) @@ -184,12 +171,9 @@ class CategoryMutation { ) } - fun updateCategories( - dataFetchingEnvironment: DataFetchingEnvironment, - input: UpdateCategoriesInput, - ): DataFetcherResult = + @RequireAuth + fun updateCategories(input: UpdateCategoriesInput): DataFetcherResult = asDataFetcherResult { - dataFetchingEnvironment.getAttribute(Attribute.TachideskUser).requireUser() val (clientMutationId, ids, patch) = input updateCategories(ids, patch) @@ -216,12 +200,9 @@ class CategoryMutation { val position: Int, ) - fun updateCategoryOrder( - dataFetchingEnvironment: DataFetchingEnvironment, - input: UpdateCategoryOrderInput, - ): DataFetcherResult = + @RequireAuth + fun updateCategoryOrder(input: UpdateCategoryOrderInput): DataFetcherResult = asDataFetcherResult { - dataFetchingEnvironment.getAttribute(Attribute.TachideskUser).requireUser() val (clientMutationId, categoryId, position) = input require(position > 0) { "'order' must not be <= 0" @@ -278,12 +259,9 @@ class CategoryMutation { val category: CategoryType, ) - fun createCategory( - dataFetchingEnvironment: DataFetchingEnvironment, - input: CreateCategoryInput, - ): DataFetcherResult = + @RequireAuth + fun createCategory(input: CreateCategoryInput): DataFetcherResult = asDataFetcherResult { - dataFetchingEnvironment.getAttribute(Attribute.TachideskUser).requireUser() val (clientMutationId, name, order, default, includeInUpdate, includeInDownload) = input transaction { require(CategoryTable.selectAll().where { CategoryTable.name eq input.name }.isEmpty()) { @@ -341,12 +319,9 @@ class CategoryMutation { val mangas: List, ) - fun deleteCategory( - dataFetchingEnvironment: DataFetchingEnvironment, - input: DeleteCategoryInput, - ): DataFetcherResult { + @RequireAuth + fun deleteCategory(input: DeleteCategoryInput): DataFetcherResult { return asDataFetcherResult { - dataFetchingEnvironment.getAttribute(Attribute.TachideskUser).requireUser() val (clientMutationId, categoryId) = input if (categoryId == 0) { // Don't delete default category return@asDataFetcherResult DeleteCategoryPayload( @@ -434,12 +409,9 @@ class CategoryMutation { } } - fun updateMangaCategories( - dataFetchingEnvironment: DataFetchingEnvironment, - input: UpdateMangaCategoriesInput, - ): DataFetcherResult = + @RequireAuth + fun updateMangaCategories(input: UpdateMangaCategoriesInput): DataFetcherResult = asDataFetcherResult { - dataFetchingEnvironment.getAttribute(Attribute.TachideskUser).requireUser() val (clientMutationId, id, patch) = input updateMangas(listOf(id), patch) @@ -455,12 +427,9 @@ class CategoryMutation { ) } - fun updateMangasCategories( - dataFetchingEnvironment: DataFetchingEnvironment, - input: UpdateMangasCategoriesInput, - ): DataFetcherResult = + @RequireAuth + fun updateMangasCategories(input: UpdateMangasCategoriesInput): DataFetcherResult = asDataFetcherResult { - dataFetchingEnvironment.getAttribute(Attribute.TachideskUser).requireUser() val (clientMutationId, ids, patch) = input updateMangas(ids, patch) diff --git a/server/src/main/kotlin/suwayomi/tachidesk/graphql/mutations/ChapterMutation.kt b/server/src/main/kotlin/suwayomi/tachidesk/graphql/mutations/ChapterMutation.kt index 9b90c513..81857ffa 100644 --- a/server/src/main/kotlin/suwayomi/tachidesk/graphql/mutations/ChapterMutation.kt +++ b/server/src/main/kotlin/suwayomi/tachidesk/graphql/mutations/ChapterMutation.kt @@ -1,7 +1,6 @@ package suwayomi.tachidesk.graphql.mutations import graphql.execution.DataFetcherResult -import graphql.schema.DataFetchingEnvironment import kotlinx.coroutines.GlobalScope import kotlinx.coroutines.launch import org.jetbrains.exposed.dao.id.EntityID @@ -13,7 +12,7 @@ import org.jetbrains.exposed.sql.statements.BatchUpdateStatement import org.jetbrains.exposed.sql.transactions.transaction import org.jetbrains.exposed.sql.update import suwayomi.tachidesk.graphql.asDataFetcherResult -import suwayomi.tachidesk.graphql.server.getAttribute +import suwayomi.tachidesk.graphql.directives.RequireAuth import suwayomi.tachidesk.graphql.types.ChapterMetaType import suwayomi.tachidesk.graphql.types.ChapterType import suwayomi.tachidesk.graphql.types.SyncConflictInfoType @@ -22,10 +21,7 @@ import suwayomi.tachidesk.manga.impl.chapter.getChapterDownloadReadyById import suwayomi.tachidesk.manga.impl.sync.KoreaderSyncService import suwayomi.tachidesk.manga.model.table.ChapterMetaTable import suwayomi.tachidesk.manga.model.table.ChapterTable -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.net.URLEncoder import java.time.Instant import java.util.concurrent.CompletableFuture @@ -117,12 +113,9 @@ class ChapterMutation { } } - fun updateChapter( - dataFetchingEnvironment: DataFetchingEnvironment, - input: UpdateChapterInput, - ): DataFetcherResult = + @RequireAuth + fun updateChapter(input: UpdateChapterInput): DataFetcherResult = asDataFetcherResult { - dataFetchingEnvironment.getAttribute(Attribute.TachideskUser).requireUser() val (clientMutationId, id, patch) = input updateChapters(listOf(id), patch) @@ -138,12 +131,9 @@ class ChapterMutation { ) } - fun updateChapters( - dataFetchingEnvironment: DataFetchingEnvironment, - input: UpdateChaptersInput, - ): DataFetcherResult = + @RequireAuth + fun updateChapters(input: UpdateChaptersInput): DataFetcherResult = asDataFetcherResult { - dataFetchingEnvironment.getAttribute(Attribute.TachideskUser).requireUser() val (clientMutationId, ids, patch) = input updateChapters(ids, patch) @@ -169,11 +159,8 @@ class ChapterMutation { val chapters: List, ) - fun fetchChapters( - dataFetchingEnvironment: DataFetchingEnvironment, - input: FetchChaptersInput, - ): CompletableFuture> { - dataFetchingEnvironment.getAttribute(Attribute.TachideskUser).requireUser() + @RequireAuth + fun fetchChapters(input: FetchChaptersInput): CompletableFuture> { val (clientMutationId, mangaId) = input return future { @@ -207,12 +194,9 @@ class ChapterMutation { val meta: ChapterMetaType, ) - fun setChapterMeta( - dataFetchingEnvironment: DataFetchingEnvironment, - input: SetChapterMetaInput, - ): DataFetcherResult = + @RequireAuth + fun setChapterMeta(input: SetChapterMetaInput): DataFetcherResult = asDataFetcherResult { - dataFetchingEnvironment.getAttribute(Attribute.TachideskUser).requireUser() val (clientMutationId, meta) = input Chapter.modifyChapterMeta(meta.chapterId, meta.key, meta.value) @@ -232,12 +216,9 @@ class ChapterMutation { val chapter: ChapterType, ) - fun deleteChapterMeta( - dataFetchingEnvironment: DataFetchingEnvironment, - input: DeleteChapterMetaInput, - ): DataFetcherResult = + @RequireAuth + fun deleteChapterMeta(input: DeleteChapterMetaInput): DataFetcherResult = asDataFetcherResult { - dataFetchingEnvironment.getAttribute(Attribute.TachideskUser).requireUser() val (clientMutationId, chapterId, key) = input val (meta, chapter) = @@ -285,11 +266,8 @@ class ChapterMutation { val syncConflict: SyncConflictInfoType?, ) - fun fetchChapterPages( - dataFetchingEnvironment: DataFetchingEnvironment, - input: FetchChapterPagesInput, - ): CompletableFuture> { - dataFetchingEnvironment.getAttribute(Attribute.TachideskUser).requireUser() + @RequireAuth + fun fetchChapterPages(input: FetchChapterPagesInput): CompletableFuture> { val (clientMutationId, chapterId) = input val paramsMap = input.toParams() diff --git a/server/src/main/kotlin/suwayomi/tachidesk/graphql/mutations/DownloadMutation.kt b/server/src/main/kotlin/suwayomi/tachidesk/graphql/mutations/DownloadMutation.kt index 5991222b..57e5dfdf 100644 --- a/server/src/main/kotlin/suwayomi/tachidesk/graphql/mutations/DownloadMutation.kt +++ b/server/src/main/kotlin/suwayomi/tachidesk/graphql/mutations/DownloadMutation.kt @@ -1,13 +1,12 @@ package suwayomi.tachidesk.graphql.mutations import graphql.execution.DataFetcherResult -import graphql.schema.DataFetchingEnvironment import kotlinx.coroutines.flow.first import kotlinx.coroutines.withTimeout 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.directives.RequireAuth import suwayomi.tachidesk.graphql.types.ChapterType import suwayomi.tachidesk.graphql.types.DownloadStatus import suwayomi.tachidesk.manga.impl.Chapter @@ -15,9 +14,7 @@ import suwayomi.tachidesk.manga.impl.download.DownloadManager import suwayomi.tachidesk.manga.impl.download.model.DownloadUpdateType.DEQUEUED import suwayomi.tachidesk.manga.impl.download.model.Status import suwayomi.tachidesk.manga.model.table.ChapterTable -import suwayomi.tachidesk.server.JavalinSetup.Attribute import suwayomi.tachidesk.server.JavalinSetup.future -import suwayomi.tachidesk.server.user.requireUser import java.util.concurrent.CompletableFuture import kotlin.time.Duration.Companion.seconds @@ -32,11 +29,8 @@ class DownloadMutation { val chapters: List, ) - fun deleteDownloadedChapters( - dataFetchingEnvironment: DataFetchingEnvironment, - input: DeleteDownloadedChaptersInput, - ): DataFetcherResult { - dataFetchingEnvironment.getAttribute(Attribute.TachideskUser).requireUser() + @RequireAuth + fun deleteDownloadedChapters(input: DeleteDownloadedChaptersInput): DataFetcherResult { val (clientMutationId, chapters) = input return asDataFetcherResult { @@ -65,11 +59,8 @@ class DownloadMutation { val chapters: ChapterType, ) - fun deleteDownloadedChapter( - dataFetchingEnvironment: DataFetchingEnvironment, - input: DeleteDownloadedChapterInput, - ): DataFetcherResult { - dataFetchingEnvironment.getAttribute(Attribute.TachideskUser).requireUser() + @RequireAuth + fun deleteDownloadedChapter(input: DeleteDownloadedChapterInput): DataFetcherResult { val (clientMutationId, chapter) = input return asDataFetcherResult { @@ -95,11 +86,10 @@ class DownloadMutation { val downloadStatus: DownloadStatus, ) + @RequireAuth fun enqueueChapterDownloads( - dataFetchingEnvironment: DataFetchingEnvironment, input: EnqueueChapterDownloadsInput, ): CompletableFuture> { - dataFetchingEnvironment.getAttribute(Attribute.TachideskUser).requireUser() val (clientMutationId, chapters) = input return future { @@ -132,11 +122,8 @@ class DownloadMutation { val downloadStatus: DownloadStatus, ) - fun enqueueChapterDownload( - dataFetchingEnvironment: DataFetchingEnvironment, - input: EnqueueChapterDownloadInput, - ): CompletableFuture> { - dataFetchingEnvironment.getAttribute(Attribute.TachideskUser).requireUser() + @RequireAuth + fun enqueueChapterDownload(input: EnqueueChapterDownloadInput): CompletableFuture> { val (clientMutationId, chapter) = input return future { @@ -168,11 +155,10 @@ class DownloadMutation { val downloadStatus: DownloadStatus, ) + @RequireAuth fun dequeueChapterDownloads( - dataFetchingEnvironment: DataFetchingEnvironment, input: DequeueChapterDownloadsInput, ): CompletableFuture> { - dataFetchingEnvironment.getAttribute(Attribute.TachideskUser).requireUser() val (clientMutationId, chapters) = input return future { @@ -207,11 +193,8 @@ class DownloadMutation { val downloadStatus: DownloadStatus, ) - fun dequeueChapterDownload( - dataFetchingEnvironment: DataFetchingEnvironment, - input: DequeueChapterDownloadInput, - ): CompletableFuture> { - dataFetchingEnvironment.getAttribute(Attribute.TachideskUser).requireUser() + @RequireAuth + fun dequeueChapterDownload(input: DequeueChapterDownloadInput): CompletableFuture> { val (clientMutationId, chapter) = input return future { @@ -245,13 +228,10 @@ class DownloadMutation { val downloadStatus: DownloadStatus, ) - fun startDownloader( - dataFetchingEnvironment: DataFetchingEnvironment, - input: StartDownloaderInput, - ): CompletableFuture> = + @RequireAuth + fun startDownloader(input: StartDownloaderInput): CompletableFuture> = future { asDataFetcherResult { - dataFetchingEnvironment.getAttribute(Attribute.TachideskUser).requireUser() DownloadManager.start() StartDownloaderPayload( @@ -277,13 +257,10 @@ class DownloadMutation { val downloadStatus: DownloadStatus, ) - fun stopDownloader( - dataFetchingEnvironment: DataFetchingEnvironment, - input: StopDownloaderInput, - ): CompletableFuture> = + @RequireAuth + fun stopDownloader(input: StopDownloaderInput): CompletableFuture> = future { asDataFetcherResult { - dataFetchingEnvironment.getAttribute(Attribute.TachideskUser).requireUser() DownloadManager.stop() StopDownloaderPayload( @@ -309,13 +286,10 @@ class DownloadMutation { val downloadStatus: DownloadStatus, ) - fun clearDownloader( - dataFetchingEnvironment: DataFetchingEnvironment, - input: ClearDownloaderInput, - ): CompletableFuture> = + @RequireAuth + fun clearDownloader(input: ClearDownloaderInput): CompletableFuture> = future { asDataFetcherResult { - dataFetchingEnvironment.getAttribute(Attribute.TachideskUser).requireUser() DownloadManager.clear() ClearDownloaderPayload( @@ -343,11 +317,8 @@ class DownloadMutation { val downloadStatus: DownloadStatus, ) - fun reorderChapterDownload( - dataFetchingEnvironment: DataFetchingEnvironment, - input: ReorderChapterDownloadInput, - ): CompletableFuture> { - dataFetchingEnvironment.getAttribute(Attribute.TachideskUser).requireUser() + @RequireAuth + fun reorderChapterDownload(input: ReorderChapterDownloadInput): CompletableFuture> { val (clientMutationId, chapter, to) = input return future { diff --git a/server/src/main/kotlin/suwayomi/tachidesk/graphql/mutations/ExtensionMutation.kt b/server/src/main/kotlin/suwayomi/tachidesk/graphql/mutations/ExtensionMutation.kt index 2a2c66b1..b484890c 100644 --- a/server/src/main/kotlin/suwayomi/tachidesk/graphql/mutations/ExtensionMutation.kt +++ b/server/src/main/kotlin/suwayomi/tachidesk/graphql/mutations/ExtensionMutation.kt @@ -2,20 +2,16 @@ package suwayomi.tachidesk.graphql.mutations import eu.kanade.tachiyomi.source.local.LocalSource import graphql.execution.DataFetcherResult -import graphql.schema.DataFetchingEnvironment import io.javalin.http.UploadedFile 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.directives.RequireAuth import suwayomi.tachidesk.graphql.types.ExtensionType import suwayomi.tachidesk.manga.impl.extension.Extension import suwayomi.tachidesk.manga.impl.extension.ExtensionsList import suwayomi.tachidesk.manga.model.table.ExtensionTable -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 ExtensionMutation { @@ -78,11 +74,8 @@ class ExtensionMutation { } } - fun updateExtension( - dataFetchingEnvironment: DataFetchingEnvironment, - input: UpdateExtensionInput, - ): CompletableFuture> { - dataFetchingEnvironment.getAttribute(Attribute.TachideskUser).requireUser() + @RequireAuth + fun updateExtension(input: UpdateExtensionInput): CompletableFuture> { val (clientMutationId, id, patch) = input return future { @@ -106,11 +99,8 @@ class ExtensionMutation { } } - fun updateExtensions( - dataFetchingEnvironment: DataFetchingEnvironment, - input: UpdateExtensionsInput, - ): CompletableFuture> { - dataFetchingEnvironment.getAttribute(Attribute.TachideskUser).requireUser() + @RequireAuth + fun updateExtensions(input: UpdateExtensionsInput): CompletableFuture> { val (clientMutationId, ids, patch) = input return future { @@ -142,11 +132,8 @@ class ExtensionMutation { val extensions: List, ) - fun fetchExtensions( - dataFetchingEnvironment: DataFetchingEnvironment, - input: FetchExtensionsInput, - ): CompletableFuture> { - dataFetchingEnvironment.getAttribute(Attribute.TachideskUser).requireUser() + @RequireAuth + fun fetchExtensions(input: FetchExtensionsInput): CompletableFuture> { val (clientMutationId) = input return future { @@ -179,11 +166,10 @@ class ExtensionMutation { val extension: ExtensionType, ) + @RequireAuth fun installExternalExtension( - dataFetchingEnvironment: DataFetchingEnvironment, input: InstallExternalExtensionInput, ): CompletableFuture> { - dataFetchingEnvironment.getAttribute(Attribute.TachideskUser).requireUser() val (clientMutationId, extensionFile) = input return future { diff --git a/server/src/main/kotlin/suwayomi/tachidesk/graphql/mutations/ImageMutation.kt b/server/src/main/kotlin/suwayomi/tachidesk/graphql/mutations/ImageMutation.kt index 159fd845..f899fe86 100644 --- a/server/src/main/kotlin/suwayomi/tachidesk/graphql/mutations/ImageMutation.kt +++ b/server/src/main/kotlin/suwayomi/tachidesk/graphql/mutations/ImageMutation.kt @@ -1,12 +1,8 @@ package suwayomi.tachidesk.graphql.mutations -import graphql.schema.DataFetchingEnvironment -import suwayomi.tachidesk.graphql.server.getAttribute +import suwayomi.tachidesk.graphql.directives.RequireAuth import suwayomi.tachidesk.manga.impl.util.storage.ImageResponse import suwayomi.tachidesk.server.ApplicationDirs -import suwayomi.tachidesk.server.JavalinSetup.Attribute -import suwayomi.tachidesk.server.JavalinSetup.getAttribute -import suwayomi.tachidesk.server.user.requireUser import uy.kohesive.injekt.injectLazy private val applicationDirs: ApplicationDirs by injectLazy() @@ -26,11 +22,8 @@ class ImageMutation { val cachedPages: Boolean?, ) - fun clearCachedImages( - dataFetchingEnvironment: DataFetchingEnvironment, - input: ClearCachedImagesInput, - ): ClearCachedImagesPayload { - dataFetchingEnvironment.getAttribute(Attribute.TachideskUser).requireUser() + @RequireAuth + fun clearCachedImages(input: ClearCachedImagesInput): ClearCachedImagesPayload { val (clientMutationId, downloadedThumbnails, cachedThumbnails, cachedPages) = input val downloadedThumbnailsResult = diff --git a/server/src/main/kotlin/suwayomi/tachidesk/graphql/mutations/InfoMutation.kt b/server/src/main/kotlin/suwayomi/tachidesk/graphql/mutations/InfoMutation.kt index 6101a517..519f6aa7 100644 --- a/server/src/main/kotlin/suwayomi/tachidesk/graphql/mutations/InfoMutation.kt +++ b/server/src/main/kotlin/suwayomi/tachidesk/graphql/mutations/InfoMutation.kt @@ -1,20 +1,16 @@ package suwayomi.tachidesk.graphql.mutations import graphql.execution.DataFetcherResult -import graphql.schema.DataFetchingEnvironment import kotlinx.coroutines.flow.first import kotlinx.coroutines.withTimeout import suwayomi.tachidesk.graphql.asDataFetcherResult -import suwayomi.tachidesk.graphql.server.getAttribute +import suwayomi.tachidesk.graphql.directives.RequireAuth import suwayomi.tachidesk.graphql.types.UpdateState.DOWNLOADING import suwayomi.tachidesk.graphql.types.UpdateState.ERROR import suwayomi.tachidesk.graphql.types.UpdateState.IDLE import suwayomi.tachidesk.graphql.types.WebUIFlavor import suwayomi.tachidesk.graphql.types.WebUIUpdateStatus -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 suwayomi.tachidesk.server.util.WebInterfaceManager import java.util.concurrent.CompletableFuture import kotlin.time.Duration.Companion.seconds @@ -29,13 +25,10 @@ class InfoMutation { val updateStatus: WebUIUpdateStatus, ) - fun updateWebUI( - dataFetchingEnvironment: DataFetchingEnvironment, - input: WebUIUpdateInput, - ): CompletableFuture> { + @RequireAuth + fun updateWebUI(input: WebUIUpdateInput): CompletableFuture> { return future { asDataFetcherResult { - dataFetchingEnvironment.getAttribute(Attribute.TachideskUser).requireUser() withTimeout(30.seconds) { if (WebInterfaceManager.status.value.state === DOWNLOADING) { return@withTimeout WebUIUpdatePayload(input.clientMutationId, WebInterfaceManager.status.value) @@ -68,10 +61,10 @@ class InfoMutation { } } - fun resetWebUIUpdateStatus(dataFetchingEnvironment: DataFetchingEnvironment): CompletableFuture> = + @RequireAuth + fun resetWebUIUpdateStatus(): CompletableFuture> = future { asDataFetcherResult { - dataFetchingEnvironment.getAttribute(Attribute.TachideskUser).requireUser() withTimeout(30.seconds) { val isUpdateFinished = WebInterfaceManager.status.value.state != DOWNLOADING if (!isUpdateFinished) { diff --git a/server/src/main/kotlin/suwayomi/tachidesk/graphql/mutations/KoreaderSyncMutation.kt b/server/src/main/kotlin/suwayomi/tachidesk/graphql/mutations/KoreaderSyncMutation.kt index 71d933e1..42d38424 100644 --- a/server/src/main/kotlin/suwayomi/tachidesk/graphql/mutations/KoreaderSyncMutation.kt +++ b/server/src/main/kotlin/suwayomi/tachidesk/graphql/mutations/KoreaderSyncMutation.kt @@ -1,12 +1,11 @@ package suwayomi.tachidesk.graphql.mutations import graphql.execution.DataFetcherResult -import graphql.schema.DataFetchingEnvironment import org.jetbrains.exposed.sql.selectAll import org.jetbrains.exposed.sql.transactions.transaction import org.jetbrains.exposed.sql.update import suwayomi.tachidesk.graphql.asDataFetcherResult -import suwayomi.tachidesk.graphql.server.getAttribute +import suwayomi.tachidesk.graphql.directives.RequireAuth import suwayomi.tachidesk.graphql.types.ChapterType import suwayomi.tachidesk.graphql.types.KoSyncConnectPayload import suwayomi.tachidesk.graphql.types.LogoutKoSyncAccountPayload @@ -14,9 +13,7 @@ import suwayomi.tachidesk.graphql.types.SettingsType import suwayomi.tachidesk.graphql.types.SyncConflictInfoType import suwayomi.tachidesk.manga.impl.sync.KoreaderSyncService import suwayomi.tachidesk.manga.model.table.ChapterTable -import suwayomi.tachidesk.server.JavalinSetup.Attribute import suwayomi.tachidesk.server.JavalinSetup.future -import suwayomi.tachidesk.server.user.requireUser import java.util.concurrent.CompletableFuture class KoreaderSyncMutation { @@ -26,12 +23,9 @@ class KoreaderSyncMutation { val password: String, ) - fun connectKoSyncAccount( - dataFetchingEnvironment: DataFetchingEnvironment, - input: ConnectKoSyncAccountInput, - ): CompletableFuture = + @RequireAuth + fun connectKoSyncAccount(input: ConnectKoSyncAccountInput): CompletableFuture = future { - dataFetchingEnvironment.getAttribute(Attribute.TachideskUser).requireUser() val result = KoreaderSyncService.connect(input.username, input.password) KoSyncConnectPayload( @@ -47,12 +41,9 @@ class KoreaderSyncMutation { val clientMutationId: String? = null, ) - fun logoutKoSyncAccount( - dataFetchingEnvironment: DataFetchingEnvironment, - input: LogoutKoSyncAccountInput, - ): CompletableFuture = + @RequireAuth + fun logoutKoSyncAccount(input: LogoutKoSyncAccountInput): CompletableFuture = future { - dataFetchingEnvironment.getAttribute(Attribute.TachideskUser).requireUser() KoreaderSyncService.logout() LogoutKoSyncAccountPayload( clientMutationId = input.clientMutationId, @@ -72,14 +63,10 @@ class KoreaderSyncMutation { val chapter: ChapterType?, ) - fun pushKoSyncProgress( - dataFetchingEnvironment: DataFetchingEnvironment, - input: PushKoSyncProgressInput, - ): CompletableFuture> = + @RequireAuth + fun pushKoSyncProgress(input: PushKoSyncProgressInput): CompletableFuture> = future { asDataFetcherResult { - dataFetchingEnvironment.getAttribute(Attribute.TachideskUser).requireUser() - KoreaderSyncService.pushProgress(input.chapterId) val chapter = @@ -110,14 +97,10 @@ class KoreaderSyncMutation { val syncConflict: SyncConflictInfoType?, ) - fun pullKoSyncProgress( - dataFetchingEnvironment: DataFetchingEnvironment, - input: PullKoSyncProgressInput, - ): CompletableFuture> = + @RequireAuth + fun pullKoSyncProgress(input: PullKoSyncProgressInput): CompletableFuture> = future { asDataFetcherResult { - dataFetchingEnvironment.getAttribute(Attribute.TachideskUser).requireUser() - val syncResult = KoreaderSyncService.checkAndPullProgress(input.chapterId) var syncConflictInfo: SyncConflictInfoType? = null diff --git a/server/src/main/kotlin/suwayomi/tachidesk/graphql/mutations/MangaMutation.kt b/server/src/main/kotlin/suwayomi/tachidesk/graphql/mutations/MangaMutation.kt index f986690d..a3ad7b5f 100644 --- a/server/src/main/kotlin/suwayomi/tachidesk/graphql/mutations/MangaMutation.kt +++ b/server/src/main/kotlin/suwayomi/tachidesk/graphql/mutations/MangaMutation.kt @@ -1,7 +1,6 @@ package suwayomi.tachidesk.graphql.mutations 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 @@ -9,7 +8,7 @@ import org.jetbrains.exposed.sql.selectAll import org.jetbrains.exposed.sql.transactions.transaction import org.jetbrains.exposed.sql.update import suwayomi.tachidesk.graphql.asDataFetcherResult -import suwayomi.tachidesk.graphql.server.getAttribute +import suwayomi.tachidesk.graphql.directives.RequireAuth import suwayomi.tachidesk.graphql.types.MangaMetaType import suwayomi.tachidesk.graphql.types.MangaType import suwayomi.tachidesk.manga.impl.Library @@ -18,10 +17,7 @@ import suwayomi.tachidesk.manga.impl.update.IUpdater import suwayomi.tachidesk.manga.model.table.MangaMetaTable import suwayomi.tachidesk.manga.model.table.MangaTable import suwayomi.tachidesk.manga.model.table.toDataClass -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 uy.kohesive.injekt.injectLazy import java.time.Instant import java.util.concurrent.CompletableFuture @@ -95,11 +91,8 @@ class MangaMutation { } } - fun updateManga( - dataFetchingEnvironment: DataFetchingEnvironment, - input: UpdateMangaInput, - ): CompletableFuture> { - dataFetchingEnvironment.getAttribute(Attribute.TachideskUser).requireUser() + @RequireAuth + fun updateManga(input: UpdateMangaInput): CompletableFuture> { val (clientMutationId, id, patch) = input return future { @@ -119,11 +112,8 @@ class MangaMutation { } } - fun updateMangas( - dataFetchingEnvironment: DataFetchingEnvironment, - input: UpdateMangasInput, - ): CompletableFuture> { - dataFetchingEnvironment.getAttribute(Attribute.TachideskUser).requireUser() + @RequireAuth + fun updateMangas(input: UpdateMangasInput): CompletableFuture> { val (clientMutationId, ids, patch) = input return future { @@ -153,11 +143,8 @@ class MangaMutation { val manga: MangaType, ) - fun fetchManga( - dataFetchingEnvironment: DataFetchingEnvironment, - input: FetchMangaInput, - ): CompletableFuture> { - dataFetchingEnvironment.getAttribute(Attribute.TachideskUser).requireUser() + @RequireAuth + fun fetchManga(input: FetchMangaInput): CompletableFuture> { val (clientMutationId, id) = input return future { @@ -186,11 +173,8 @@ class MangaMutation { val meta: MangaMetaType, ) - fun setMangaMeta( - dataFetchingEnvironment: DataFetchingEnvironment, - input: SetMangaMetaInput, - ): DataFetcherResult { - dataFetchingEnvironment.getAttribute(Attribute.TachideskUser).requireUser() + @RequireAuth + fun setMangaMeta(input: SetMangaMetaInput): DataFetcherResult { val (clientMutationId, meta) = input return asDataFetcherResult { @@ -212,11 +196,8 @@ class MangaMutation { val manga: MangaType, ) - fun deleteMangaMeta( - dataFetchingEnvironment: DataFetchingEnvironment, - input: DeleteMangaMetaInput, - ): DataFetcherResult { - dataFetchingEnvironment.getAttribute(Attribute.TachideskUser).requireUser() + @RequireAuth + fun deleteMangaMeta(input: DeleteMangaMetaInput): DataFetcherResult { val (clientMutationId, mangaId, key) = input return asDataFetcherResult { diff --git a/server/src/main/kotlin/suwayomi/tachidesk/graphql/mutations/MetaMutation.kt b/server/src/main/kotlin/suwayomi/tachidesk/graphql/mutations/MetaMutation.kt index 171776f1..971b0b41 100644 --- a/server/src/main/kotlin/suwayomi/tachidesk/graphql/mutations/MetaMutation.kt +++ b/server/src/main/kotlin/suwayomi/tachidesk/graphql/mutations/MetaMutation.kt @@ -1,7 +1,6 @@ package suwayomi.tachidesk.graphql.mutations import graphql.execution.DataFetcherResult -import graphql.schema.DataFetchingEnvironment import org.jetbrains.exposed.sql.SqlExpressionBuilder.eq import org.jetbrains.exposed.sql.deleteWhere import org.jetbrains.exposed.sql.selectAll @@ -9,11 +8,8 @@ import org.jetbrains.exposed.sql.transactions.transaction import suwayomi.tachidesk.global.impl.GlobalMeta import suwayomi.tachidesk.global.model.table.GlobalMetaTable import suwayomi.tachidesk.graphql.asDataFetcherResult -import suwayomi.tachidesk.graphql.server.getAttribute +import suwayomi.tachidesk.graphql.directives.RequireAuth import suwayomi.tachidesk.graphql.types.GlobalMetaType -import suwayomi.tachidesk.server.JavalinSetup.Attribute -import suwayomi.tachidesk.server.JavalinSetup.getAttribute -import suwayomi.tachidesk.server.user.requireUser class MetaMutation { data class SetGlobalMetaInput( @@ -26,11 +22,8 @@ class MetaMutation { val meta: GlobalMetaType, ) - fun setGlobalMeta( - dataFetchingEnvironment: DataFetchingEnvironment, - input: SetGlobalMetaInput, - ): DataFetcherResult { - dataFetchingEnvironment.getAttribute(Attribute.TachideskUser).requireUser() + @RequireAuth + fun setGlobalMeta(input: SetGlobalMetaInput): DataFetcherResult { val (clientMutationId, meta) = input return asDataFetcherResult { @@ -50,11 +43,8 @@ class MetaMutation { val meta: GlobalMetaType?, ) - fun deleteGlobalMeta( - dataFetchingEnvironment: DataFetchingEnvironment, - input: DeleteGlobalMetaInput, - ): DataFetcherResult { - dataFetchingEnvironment.getAttribute(Attribute.TachideskUser).requireUser() + @RequireAuth + fun deleteGlobalMeta(input: DeleteGlobalMetaInput): DataFetcherResult { val (clientMutationId, key) = input return asDataFetcherResult { diff --git a/server/src/main/kotlin/suwayomi/tachidesk/graphql/mutations/SettingsMutation.kt b/server/src/main/kotlin/suwayomi/tachidesk/graphql/mutations/SettingsMutation.kt index aea9ad3e..7a97f95c 100644 --- a/server/src/main/kotlin/suwayomi/tachidesk/graphql/mutations/SettingsMutation.kt +++ b/server/src/main/kotlin/suwayomi/tachidesk/graphql/mutations/SettingsMutation.kt @@ -1,17 +1,14 @@ package suwayomi.tachidesk.graphql.mutations import com.expediagroup.graphql.generator.annotations.GraphQLIgnore -import graphql.schema.DataFetchingEnvironment -import suwayomi.tachidesk.graphql.server.getAttribute +import suwayomi.tachidesk.graphql.directives.RequireAuth import suwayomi.tachidesk.graphql.types.PartialSettingsType import suwayomi.tachidesk.graphql.types.Settings import suwayomi.tachidesk.graphql.types.SettingsType -import suwayomi.tachidesk.server.JavalinSetup.Attribute import suwayomi.tachidesk.server.SERVER_CONFIG_MODULE_NAME import suwayomi.tachidesk.server.ServerConfig import suwayomi.tachidesk.server.settings.SettingsUpdater import suwayomi.tachidesk.server.settings.SettingsValidator -import suwayomi.tachidesk.server.user.requireUser import xyz.nulldev.ts.config.GlobalConfigManager class SettingsMutation { @@ -35,11 +32,8 @@ class SettingsMutation { SettingsUpdater.updateAll(settings) } - fun setSettings( - dataFetchingEnvironment: DataFetchingEnvironment, - input: SetSettingsInput, - ): SetSettingsPayload { - dataFetchingEnvironment.getAttribute(Attribute.TachideskUser).requireUser() + @RequireAuth + fun setSettings(input: SetSettingsInput): SetSettingsPayload { val (clientMutationId, settings) = input updateSettings(settings) @@ -56,11 +50,8 @@ class SettingsMutation { val settings: SettingsType, ) - fun resetSettings( - dataFetchingEnvironment: DataFetchingEnvironment, - input: ResetSettingsInput, - ): ResetSettingsPayload { - dataFetchingEnvironment.getAttribute(Attribute.TachideskUser).requireUser() + @RequireAuth + fun resetSettings(input: ResetSettingsInput): ResetSettingsPayload { val (clientMutationId) = input GlobalConfigManager.resetUserConfig() diff --git a/server/src/main/kotlin/suwayomi/tachidesk/graphql/mutations/SourceMutation.kt b/server/src/main/kotlin/suwayomi/tachidesk/graphql/mutations/SourceMutation.kt index 55e8592f..f937abea 100644 --- a/server/src/main/kotlin/suwayomi/tachidesk/graphql/mutations/SourceMutation.kt +++ b/server/src/main/kotlin/suwayomi/tachidesk/graphql/mutations/SourceMutation.kt @@ -6,14 +6,13 @@ 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.directives.RequireAuth import suwayomi.tachidesk.graphql.types.FilterChange import suwayomi.tachidesk.graphql.types.MangaType import suwayomi.tachidesk.graphql.types.Preference @@ -27,10 +26,7 @@ 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 { @@ -44,11 +40,8 @@ class SourceMutation { val meta: SourceMetaType, ) - fun setSourceMeta( - dataFetchingEnvironment: DataFetchingEnvironment, - input: SetSourceMetaInput, - ): DataFetcherResult { - dataFetchingEnvironment.getAttribute(Attribute.TachideskUser).requireUser() + @RequireAuth + fun setSourceMeta(input: SetSourceMetaInput): DataFetcherResult { val (clientMutationId, meta) = input return asDataFetcherResult { @@ -70,11 +63,8 @@ class SourceMutation { val source: SourceType?, ) - fun deleteSourceMeta( - dataFetchingEnvironment: DataFetchingEnvironment, - input: DeleteSourceMetaInput, - ): DataFetcherResult { - dataFetchingEnvironment.getAttribute(Attribute.TachideskUser).requireUser() + @RequireAuth + fun deleteSourceMeta(input: DeleteSourceMetaInput): DataFetcherResult { val (clientMutationId, sourceId, key) = input return asDataFetcherResult { @@ -129,11 +119,8 @@ class SourceMutation { val hasNextPage: Boolean, ) - fun fetchSourceManga( - dataFetchingEnvironment: DataFetchingEnvironment, - input: FetchSourceMangaInput, - ): CompletableFuture> { - dataFetchingEnvironment.getAttribute(Attribute.TachideskUser).requireUser() + @RequireAuth + fun fetchSourceManga(input: FetchSourceMangaInput): CompletableFuture> { val (clientMutationId, sourceId, type, page, query, filters) = input return future { @@ -199,11 +186,8 @@ class SourceMutation { val source: SourceType, ) - fun updateSourcePreference( - dataFetchingEnvironment: DataFetchingEnvironment, - input: UpdateSourcePreferenceInput, - ): DataFetcherResult { - dataFetchingEnvironment.getAttribute(Attribute.TachideskUser).requireUser() + @RequireAuth + fun updateSourcePreference(input: UpdateSourcePreferenceInput): DataFetcherResult { val (clientMutationId, sourceId, change) = input return asDataFetcherResult { diff --git a/server/src/main/kotlin/suwayomi/tachidesk/graphql/mutations/TrackMutation.kt b/server/src/main/kotlin/suwayomi/tachidesk/graphql/mutations/TrackMutation.kt index 92eddda7..ac618133 100644 --- a/server/src/main/kotlin/suwayomi/tachidesk/graphql/mutations/TrackMutation.kt +++ b/server/src/main/kotlin/suwayomi/tachidesk/graphql/mutations/TrackMutation.kt @@ -3,21 +3,17 @@ package suwayomi.tachidesk.graphql.mutations import com.expediagroup.graphql.generator.annotations.GraphQLDeprecated import com.expediagroup.graphql.generator.annotations.GraphQLDescription import graphql.execution.DataFetcherResult -import graphql.schema.DataFetchingEnvironment import org.jetbrains.exposed.sql.and 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.directives.RequireAuth import suwayomi.tachidesk.graphql.types.TrackRecordType import suwayomi.tachidesk.graphql.types.TrackerType import suwayomi.tachidesk.manga.impl.track.Track import suwayomi.tachidesk.manga.impl.track.tracker.TrackerManager import suwayomi.tachidesk.manga.model.table.TrackRecordTable -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 TrackMutation { @@ -33,11 +29,8 @@ class TrackMutation { val tracker: TrackerType, ) - fun loginTrackerOAuth( - dataFetchingEnvironment: DataFetchingEnvironment, - input: LoginTrackerOAuthInput, - ): CompletableFuture { - dataFetchingEnvironment.getAttribute(Attribute.TachideskUser).requireUser() + @RequireAuth + fun loginTrackerOAuth(input: LoginTrackerOAuthInput): CompletableFuture { val tracker = requireNotNull(TrackerManager.getTracker(input.trackerId)) { "Could not find tracker" @@ -66,11 +59,8 @@ class TrackMutation { val tracker: TrackerType, ) - fun loginTrackerCredentials( - dataFetchingEnvironment: DataFetchingEnvironment, - input: LoginTrackerCredentialsInput, - ): CompletableFuture { - dataFetchingEnvironment.getAttribute(Attribute.TachideskUser).requireUser() + @RequireAuth + fun loginTrackerCredentials(input: LoginTrackerCredentialsInput): CompletableFuture { val tracker = requireNotNull(TrackerManager.getTracker(input.trackerId)) { "Could not find tracker" @@ -97,11 +87,8 @@ class TrackMutation { val tracker: TrackerType, ) - fun logoutTracker( - dataFetchingEnvironment: DataFetchingEnvironment, - input: LogoutTrackerInput, - ): CompletableFuture { - dataFetchingEnvironment.getAttribute(Attribute.TachideskUser).requireUser() + @RequireAuth + fun logoutTracker(input: LogoutTrackerInput): CompletableFuture { val tracker = requireNotNull(TrackerManager.getTracker(input.trackerId)) { "Could not find tracker" @@ -134,11 +121,8 @@ class TrackMutation { val trackRecord: TrackRecordType, ) - fun bindTrack( - dataFetchingEnvironment: DataFetchingEnvironment, - input: BindTrackInput, - ): CompletableFuture { - dataFetchingEnvironment.getAttribute(Attribute.TachideskUser).requireUser() + @RequireAuth + fun bindTrack(input: BindTrackInput): CompletableFuture { val (clientMutationId, mangaId, trackerId, remoteId, private) = input return future { @@ -173,11 +157,8 @@ class TrackMutation { val trackRecord: TrackRecordType, ) - fun fetchTrack( - dataFetchingEnvironment: DataFetchingEnvironment, - input: FetchTrackInput, - ): CompletableFuture { - dataFetchingEnvironment.getAttribute(Attribute.TachideskUser).requireUser() + @RequireAuth + fun fetchTrack(input: FetchTrackInput): CompletableFuture { val (clientMutationId, recordId) = input return future { @@ -209,11 +190,8 @@ class TrackMutation { val trackRecord: TrackRecordType?, ) - fun unbindTrack( - dataFetchingEnvironment: DataFetchingEnvironment, - input: UnbindTrackInput, - ): CompletableFuture { - dataFetchingEnvironment.getAttribute(Attribute.TachideskUser).requireUser() + @RequireAuth + fun unbindTrack(input: UnbindTrackInput): CompletableFuture { val (clientMutationId, recordId, deleteRemoteTrack) = input return future { @@ -243,11 +221,8 @@ class TrackMutation { val trackRecords: List, ) - fun trackProgress( - dataFetchingEnvironment: DataFetchingEnvironment, - input: TrackProgressInput, - ): CompletableFuture> { - dataFetchingEnvironment.getAttribute(Attribute.TachideskUser).requireUser() + @RequireAuth + fun trackProgress(input: TrackProgressInput): CompletableFuture> { val (clientMutationId, mangaId) = input return future { @@ -289,12 +264,9 @@ class TrackMutation { val trackRecord: TrackRecordType?, ) - fun updateTrack( - dataFetchingEnvironment: DataFetchingEnvironment, - input: UpdateTrackInput, - ): CompletableFuture = + @RequireAuth + fun updateTrack(input: UpdateTrackInput): CompletableFuture = future { - dataFetchingEnvironment.getAttribute(Attribute.TachideskUser).requireUser() Track.update( Track.UpdateInput( input.recordId, diff --git a/server/src/main/kotlin/suwayomi/tachidesk/graphql/mutations/UpdateMutation.kt b/server/src/main/kotlin/suwayomi/tachidesk/graphql/mutations/UpdateMutation.kt index 8cc5dab7..d8cbaa76 100644 --- a/server/src/main/kotlin/suwayomi/tachidesk/graphql/mutations/UpdateMutation.kt +++ b/server/src/main/kotlin/suwayomi/tachidesk/graphql/mutations/UpdateMutation.kt @@ -1,19 +1,15 @@ package suwayomi.tachidesk.graphql.mutations import graphql.execution.DataFetcherResult -import graphql.schema.DataFetchingEnvironment import kotlinx.coroutines.flow.first import kotlinx.coroutines.withTimeout import suwayomi.tachidesk.graphql.asDataFetcherResult -import suwayomi.tachidesk.graphql.server.getAttribute +import suwayomi.tachidesk.graphql.directives.RequireAuth import suwayomi.tachidesk.graphql.types.LibraryUpdateStatus import suwayomi.tachidesk.graphql.types.UpdateStatus import suwayomi.tachidesk.manga.impl.Category import suwayomi.tachidesk.manga.impl.update.IUpdater -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 uy.kohesive.injekt.injectLazy import java.util.concurrent.CompletableFuture import kotlin.time.Duration.Companion.seconds @@ -31,11 +27,8 @@ class UpdateMutation { val updateStatus: LibraryUpdateStatus, ) - fun updateLibrary( - dataFetchingEnvironment: DataFetchingEnvironment, - input: UpdateLibraryInput, - ): CompletableFuture> { - dataFetchingEnvironment.getAttribute(Attribute.TachideskUser).requireUser() + @RequireAuth + fun updateLibrary(input: UpdateLibraryInput): CompletableFuture> { updater.addCategoriesToUpdateQueue( Category.getCategoryList().filter { input.categories?.contains(it.id) ?: true }, clear = true, @@ -66,12 +59,9 @@ class UpdateMutation { val updateStatus: UpdateStatus, ) - fun updateLibraryManga( - dataFetchingEnvironment: DataFetchingEnvironment, - input: UpdateLibraryMangaInput, - ): CompletableFuture> { + @RequireAuth + fun updateLibraryManga(input: UpdateLibraryMangaInput): CompletableFuture> { updateLibrary( - dataFetchingEnvironment, UpdateLibraryInput( clientMutationId = input.clientMutationId, categories = null, @@ -101,12 +91,9 @@ class UpdateMutation { val updateStatus: UpdateStatus, ) - fun updateCategoryManga( - dataFetchingEnvironment: DataFetchingEnvironment, - input: UpdateCategoryMangaInput, - ): CompletableFuture> { + @RequireAuth + fun updateCategoryManga(input: UpdateCategoryMangaInput): CompletableFuture> { updateLibrary( - dataFetchingEnvironment, UpdateLibraryInput( clientMutationId = input.clientMutationId, categories = input.categories, @@ -134,11 +121,8 @@ class UpdateMutation { val clientMutationId: String?, ) - fun updateStop( - dataFetchingEnvironment: DataFetchingEnvironment, - input: UpdateStopInput, - ): UpdateStopPayload { - dataFetchingEnvironment.getAttribute(Attribute.TachideskUser).requireUser() + @RequireAuth + fun updateStop(input: UpdateStopInput): UpdateStopPayload { updater.reset() return UpdateStopPayload(input.clientMutationId) } diff --git a/server/src/main/kotlin/suwayomi/tachidesk/graphql/mutations/UserMutation.kt b/server/src/main/kotlin/suwayomi/tachidesk/graphql/mutations/UserMutation.kt index 714bd070..af0f86dc 100644 --- a/server/src/main/kotlin/suwayomi/tachidesk/graphql/mutations/UserMutation.kt +++ b/server/src/main/kotlin/suwayomi/tachidesk/graphql/mutations/UserMutation.kt @@ -2,9 +2,9 @@ package suwayomi.tachidesk.graphql.mutations import graphql.schema.DataFetchingEnvironment import suwayomi.tachidesk.global.impl.util.Jwt +import suwayomi.tachidesk.graphql.directives.RequireAuth import suwayomi.tachidesk.graphql.server.getAttribute import suwayomi.tachidesk.server.JavalinSetup.Attribute -import suwayomi.tachidesk.server.JavalinSetup.getAttribute import suwayomi.tachidesk.server.serverConfig import suwayomi.tachidesk.server.user.UserType diff --git a/server/src/main/kotlin/suwayomi/tachidesk/graphql/queries/BackupQuery.kt b/server/src/main/kotlin/suwayomi/tachidesk/graphql/queries/BackupQuery.kt index 6beba8e0..5c2d3532 100644 --- a/server/src/main/kotlin/suwayomi/tachidesk/graphql/queries/BackupQuery.kt +++ b/server/src/main/kotlin/suwayomi/tachidesk/graphql/queries/BackupQuery.kt @@ -1,15 +1,11 @@ package suwayomi.tachidesk.graphql.queries -import graphql.schema.DataFetchingEnvironment import io.javalin.http.UploadedFile -import suwayomi.tachidesk.graphql.server.getAttribute +import suwayomi.tachidesk.graphql.directives.RequireAuth import suwayomi.tachidesk.graphql.types.BackupRestoreStatus import suwayomi.tachidesk.graphql.types.toStatus import suwayomi.tachidesk.manga.impl.backup.proto.ProtoBackupImport import suwayomi.tachidesk.manga.impl.backup.proto.ProtoBackupValidator -import suwayomi.tachidesk.server.JavalinSetup.Attribute -import suwayomi.tachidesk.server.JavalinSetup.getAttribute -import suwayomi.tachidesk.server.user.requireUser class BackupQuery { data class ValidateBackupInput( @@ -30,11 +26,8 @@ class BackupQuery { val missingTrackers: List, ) - fun validateBackup( - dataFetchingEnvironment: DataFetchingEnvironment, - input: ValidateBackupInput, - ): ValidateBackupResult { - dataFetchingEnvironment.getAttribute(Attribute.TachideskUser).requireUser() + @RequireAuth + fun validateBackup(input: ValidateBackupInput): ValidateBackupResult { val result = ProtoBackupValidator.validate(input.backup.content()) return ValidateBackupResult( result.missingSourceIds.map { ValidateBackupSource(it.first, it.second) }, @@ -42,11 +35,6 @@ class BackupQuery { ) } - fun restoreStatus( - dataFetchingEnvironment: DataFetchingEnvironment, - id: String, - ): BackupRestoreStatus? { - dataFetchingEnvironment.getAttribute(Attribute.TachideskUser).requireUser() - return ProtoBackupImport.getRestoreState(id)?.toStatus() - } + @RequireAuth + fun restoreStatus(id: String): BackupRestoreStatus? = ProtoBackupImport.getRestoreState(id)?.toStatus() } diff --git a/server/src/main/kotlin/suwayomi/tachidesk/graphql/queries/CategoryQuery.kt b/server/src/main/kotlin/suwayomi/tachidesk/graphql/queries/CategoryQuery.kt index 2570a922..8aae3926 100644 --- a/server/src/main/kotlin/suwayomi/tachidesk/graphql/queries/CategoryQuery.kt +++ b/server/src/main/kotlin/suwayomi/tachidesk/graphql/queries/CategoryQuery.kt @@ -17,6 +17,7 @@ import org.jetbrains.exposed.sql.SqlExpressionBuilder.greater import org.jetbrains.exposed.sql.SqlExpressionBuilder.less import org.jetbrains.exposed.sql.selectAll import org.jetbrains.exposed.sql.transactions.transaction +import suwayomi.tachidesk.graphql.directives.RequireAuth import suwayomi.tachidesk.graphql.queries.filter.BooleanFilter import suwayomi.tachidesk.graphql.queries.filter.Filter import suwayomi.tachidesk.graphql.queries.filter.HasGetOp @@ -27,7 +28,6 @@ import suwayomi.tachidesk.graphql.queries.filter.andFilterWithCompare import suwayomi.tachidesk.graphql.queries.filter.andFilterWithCompareEntity import suwayomi.tachidesk.graphql.queries.filter.andFilterWithCompareString import suwayomi.tachidesk.graphql.queries.filter.applyOps -import suwayomi.tachidesk.graphql.server.getAttribute import suwayomi.tachidesk.graphql.server.primitives.Cursor import suwayomi.tachidesk.graphql.server.primitives.Order import suwayomi.tachidesk.graphql.server.primitives.OrderBy @@ -40,19 +40,14 @@ import suwayomi.tachidesk.graphql.server.primitives.maybeSwap import suwayomi.tachidesk.graphql.types.CategoryNodeList import suwayomi.tachidesk.graphql.types.CategoryType import suwayomi.tachidesk.manga.model.table.CategoryTable -import suwayomi.tachidesk.server.JavalinSetup.Attribute -import suwayomi.tachidesk.server.JavalinSetup.getAttribute -import suwayomi.tachidesk.server.user.requireUser import java.util.concurrent.CompletableFuture class CategoryQuery { + @RequireAuth fun category( dataFetchingEnvironment: DataFetchingEnvironment, id: Int, - ): CompletableFuture { - dataFetchingEnvironment.getAttribute(Attribute.TachideskUser).requireUser() - return dataFetchingEnvironment.getValueFromDataLoader("CategoryDataLoader", id) - } + ): CompletableFuture = dataFetchingEnvironment.getValueFromDataLoader("CategoryDataLoader", id) enum class CategoryOrderBy( override val column: Column<*>, @@ -127,8 +122,8 @@ class CategoryQuery { ) } + @RequireAuth fun categories( - dataFetchingEnvironment: DataFetchingEnvironment, condition: CategoryCondition? = null, filter: CategoryFilter? = null, @GraphQLDeprecated( @@ -148,7 +143,6 @@ class CategoryQuery { last: Int? = null, offset: Int? = null, ): CategoryNodeList { - dataFetchingEnvironment.getAttribute(Attribute.TachideskUser).requireUser() val queryResults = transaction { val res = CategoryTable.selectAll() diff --git a/server/src/main/kotlin/suwayomi/tachidesk/graphql/queries/ChapterQuery.kt b/server/src/main/kotlin/suwayomi/tachidesk/graphql/queries/ChapterQuery.kt index da3cc2cb..a260511f 100644 --- a/server/src/main/kotlin/suwayomi/tachidesk/graphql/queries/ChapterQuery.kt +++ b/server/src/main/kotlin/suwayomi/tachidesk/graphql/queries/ChapterQuery.kt @@ -18,6 +18,7 @@ import org.jetbrains.exposed.sql.SqlExpressionBuilder.less import org.jetbrains.exposed.sql.andWhere import org.jetbrains.exposed.sql.selectAll import org.jetbrains.exposed.sql.transactions.transaction +import suwayomi.tachidesk.graphql.directives.RequireAuth import suwayomi.tachidesk.graphql.queries.filter.BooleanFilter import suwayomi.tachidesk.graphql.queries.filter.Filter import suwayomi.tachidesk.graphql.queries.filter.FloatFilter @@ -30,7 +31,6 @@ import suwayomi.tachidesk.graphql.queries.filter.andFilterWithCompare import suwayomi.tachidesk.graphql.queries.filter.andFilterWithCompareEntity import suwayomi.tachidesk.graphql.queries.filter.andFilterWithCompareString import suwayomi.tachidesk.graphql.queries.filter.applyOps -import suwayomi.tachidesk.graphql.server.getAttribute import suwayomi.tachidesk.graphql.server.primitives.Cursor import suwayomi.tachidesk.graphql.server.primitives.Order import suwayomi.tachidesk.graphql.server.primitives.OrderBy @@ -44,9 +44,6 @@ import suwayomi.tachidesk.graphql.types.ChapterNodeList import suwayomi.tachidesk.graphql.types.ChapterType import suwayomi.tachidesk.manga.model.table.ChapterTable import suwayomi.tachidesk.manga.model.table.MangaTable -import suwayomi.tachidesk.server.JavalinSetup.Attribute -import suwayomi.tachidesk.server.JavalinSetup.getAttribute -import suwayomi.tachidesk.server.user.requireUser import java.util.concurrent.CompletableFuture /** @@ -55,6 +52,7 @@ import java.util.concurrent.CompletableFuture * - Get page list? */ class ChapterQuery { + @RequireAuth fun chapter( dataFetchingEnvironment: DataFetchingEnvironment, id: Int, @@ -200,8 +198,8 @@ class ChapterQuery { fun getLibraryOp() = andFilterWithCompare(MangaTable.inLibrary, inLibrary) } + @RequireAuth fun chapters( - dataFetchingEnvironment: DataFetchingEnvironment, condition: ChapterCondition? = null, filter: ChapterFilter? = null, @GraphQLDeprecated( @@ -221,7 +219,6 @@ class ChapterQuery { last: Int? = null, offset: Int? = null, ): ChapterNodeList { - dataFetchingEnvironment.getAttribute(Attribute.TachideskUser).requireUser() val queryResults = transaction { val res = ChapterTable.selectAll() diff --git a/server/src/main/kotlin/suwayomi/tachidesk/graphql/queries/DownloadQuery.kt b/server/src/main/kotlin/suwayomi/tachidesk/graphql/queries/DownloadQuery.kt index ffc209ff..8829d93f 100644 --- a/server/src/main/kotlin/suwayomi/tachidesk/graphql/queries/DownloadQuery.kt +++ b/server/src/main/kotlin/suwayomi/tachidesk/graphql/queries/DownloadQuery.kt @@ -1,19 +1,15 @@ package suwayomi.tachidesk.graphql.queries -import graphql.schema.DataFetchingEnvironment -import suwayomi.tachidesk.graphql.server.getAttribute +import suwayomi.tachidesk.graphql.directives.RequireAuth import suwayomi.tachidesk.graphql.types.DownloadStatus import suwayomi.tachidesk.manga.impl.download.DownloadManager -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 DownloadQuery { - fun downloadStatus(dataFetchingEnvironment: DataFetchingEnvironment): CompletableFuture = + @RequireAuth + fun downloadStatus(): CompletableFuture = future { - dataFetchingEnvironment.getAttribute(Attribute.TachideskUser).requireUser() DownloadStatus(DownloadManager.getStatus()) } } diff --git a/server/src/main/kotlin/suwayomi/tachidesk/graphql/queries/ExtensionQuery.kt b/server/src/main/kotlin/suwayomi/tachidesk/graphql/queries/ExtensionQuery.kt index cdce31ad..50a5be2f 100644 --- a/server/src/main/kotlin/suwayomi/tachidesk/graphql/queries/ExtensionQuery.kt +++ b/server/src/main/kotlin/suwayomi/tachidesk/graphql/queries/ExtensionQuery.kt @@ -19,6 +19,7 @@ import org.jetbrains.exposed.sql.SqlExpressionBuilder.less import org.jetbrains.exposed.sql.SqlExpressionBuilder.neq import org.jetbrains.exposed.sql.selectAll import org.jetbrains.exposed.sql.transactions.transaction +import suwayomi.tachidesk.graphql.directives.RequireAuth import suwayomi.tachidesk.graphql.queries.filter.BooleanFilter import suwayomi.tachidesk.graphql.queries.filter.Filter import suwayomi.tachidesk.graphql.queries.filter.HasGetOp @@ -28,7 +29,6 @@ import suwayomi.tachidesk.graphql.queries.filter.StringFilter import suwayomi.tachidesk.graphql.queries.filter.andFilterWithCompare import suwayomi.tachidesk.graphql.queries.filter.andFilterWithCompareString import suwayomi.tachidesk.graphql.queries.filter.applyOps -import suwayomi.tachidesk.graphql.server.getAttribute import suwayomi.tachidesk.graphql.server.primitives.Cursor import suwayomi.tachidesk.graphql.server.primitives.Order import suwayomi.tachidesk.graphql.server.primitives.OrderBy @@ -41,19 +41,14 @@ import suwayomi.tachidesk.graphql.server.primitives.maybeSwap import suwayomi.tachidesk.graphql.types.ExtensionNodeList import suwayomi.tachidesk.graphql.types.ExtensionType import suwayomi.tachidesk.manga.model.table.ExtensionTable -import suwayomi.tachidesk.server.JavalinSetup.Attribute -import suwayomi.tachidesk.server.JavalinSetup.getAttribute -import suwayomi.tachidesk.server.user.requireUser import java.util.concurrent.CompletableFuture class ExtensionQuery { + @RequireAuth fun extension( dataFetchingEnvironment: DataFetchingEnvironment, pkgName: String, - ): CompletableFuture { - dataFetchingEnvironment.getAttribute(Attribute.TachideskUser).requireUser() - return dataFetchingEnvironment.getValueFromDataLoader("ExtensionDataLoader", pkgName) - } + ): CompletableFuture = dataFetchingEnvironment.getValueFromDataLoader("ExtensionDataLoader", pkgName) enum class ExtensionOrderBy( override val column: Column<*>, @@ -159,8 +154,8 @@ class ExtensionQuery { ) } + @RequireAuth fun extensions( - dataFetchingEnvironment: DataFetchingEnvironment, condition: ExtensionCondition? = null, filter: ExtensionFilter? = null, @GraphQLDeprecated( @@ -180,7 +175,6 @@ class ExtensionQuery { last: Int? = null, offset: Int? = null, ): ExtensionNodeList { - dataFetchingEnvironment.getAttribute(Attribute.TachideskUser).requireUser() val queryResults = transaction { val res = ExtensionTable.selectAll() diff --git a/server/src/main/kotlin/suwayomi/tachidesk/graphql/queries/InfoQuery.kt b/server/src/main/kotlin/suwayomi/tachidesk/graphql/queries/InfoQuery.kt index 0b91d02a..d522a8a8 100644 --- a/server/src/main/kotlin/suwayomi/tachidesk/graphql/queries/InfoQuery.kt +++ b/server/src/main/kotlin/suwayomi/tachidesk/graphql/queries/InfoQuery.kt @@ -1,19 +1,15 @@ package suwayomi.tachidesk.graphql.queries import com.expediagroup.graphql.generator.annotations.GraphQLDeprecated -import graphql.schema.DataFetchingEnvironment import suwayomi.tachidesk.global.impl.AppUpdate -import suwayomi.tachidesk.graphql.server.getAttribute +import suwayomi.tachidesk.graphql.directives.RequireAuth import suwayomi.tachidesk.graphql.types.AboutWebUI import suwayomi.tachidesk.graphql.types.WebUIFlavor import suwayomi.tachidesk.graphql.types.WebUIUpdateCheck import suwayomi.tachidesk.graphql.types.WebUIUpdateStatus -import suwayomi.tachidesk.server.JavalinSetup.Attribute import suwayomi.tachidesk.server.JavalinSetup.future -import suwayomi.tachidesk.server.JavalinSetup.getAttribute import suwayomi.tachidesk.server.generated.BuildConfig import suwayomi.tachidesk.server.serverConfig -import suwayomi.tachidesk.server.user.requireUser import suwayomi.tachidesk.server.util.WebInterfaceManager import java.util.concurrent.CompletableFuture @@ -47,9 +43,9 @@ class InfoQuery { val url: String, ) - fun checkForServerUpdates(dataFetchingEnvironment: DataFetchingEnvironment): CompletableFuture> = + @RequireAuth + fun checkForServerUpdates(): CompletableFuture> = future { - dataFetchingEnvironment.getAttribute(Attribute.TachideskUser).requireUser() AppUpdate.checkUpdate().map { CheckForServerUpdatesPayload( channel = it.channel, @@ -59,15 +55,15 @@ class InfoQuery { } } - fun aboutWebUI(dataFetchingEnvironment: DataFetchingEnvironment): CompletableFuture = + @RequireAuth + fun aboutWebUI(): CompletableFuture = future { - dataFetchingEnvironment.getAttribute(Attribute.TachideskUser).requireUser() WebInterfaceManager.getAboutInfo() } - fun checkForWebUIUpdate(dataFetchingEnvironment: DataFetchingEnvironment): CompletableFuture = + @RequireAuth + fun checkForWebUIUpdate(): CompletableFuture = future { - dataFetchingEnvironment.getAttribute(Attribute.TachideskUser).requireUser() val (version, updateAvailable) = WebInterfaceManager.isUpdateAvailable(WebUIFlavor.current, raiseError = true) WebUIUpdateCheck( channel = serverConfig.webUIChannel.value, @@ -76,8 +72,6 @@ class InfoQuery { ) } - fun getWebUIUpdateStatus(dataFetchingEnvironment: DataFetchingEnvironment): WebUIUpdateStatus { - dataFetchingEnvironment.getAttribute(Attribute.TachideskUser).requireUser() - return WebInterfaceManager.status.value - } + @RequireAuth + fun getWebUIUpdateStatus(): WebUIUpdateStatus = WebInterfaceManager.status.value } diff --git a/server/src/main/kotlin/suwayomi/tachidesk/graphql/queries/KoreaderSyncQuery.kt b/server/src/main/kotlin/suwayomi/tachidesk/graphql/queries/KoreaderSyncQuery.kt index 33d4639e..cd0e521d 100644 --- a/server/src/main/kotlin/suwayomi/tachidesk/graphql/queries/KoreaderSyncQuery.kt +++ b/server/src/main/kotlin/suwayomi/tachidesk/graphql/queries/KoreaderSyncQuery.kt @@ -1,19 +1,15 @@ package suwayomi.tachidesk.graphql.queries -import graphql.schema.DataFetchingEnvironment -import suwayomi.tachidesk.graphql.server.getAttribute +import suwayomi.tachidesk.graphql.directives.RequireAuth import suwayomi.tachidesk.graphql.types.KoSyncStatusPayload import suwayomi.tachidesk.manga.impl.sync.KoreaderSyncService -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 KoreaderSyncQuery { - fun koSyncStatus(dataFetchingEnvironment: DataFetchingEnvironment): CompletableFuture = + @RequireAuth + fun koSyncStatus(): CompletableFuture = future { - dataFetchingEnvironment.getAttribute(Attribute.TachideskUser).requireUser() KoreaderSyncService.getStatus() } } diff --git a/server/src/main/kotlin/suwayomi/tachidesk/graphql/queries/MangaQuery.kt b/server/src/main/kotlin/suwayomi/tachidesk/graphql/queries/MangaQuery.kt index a435da5b..44b9d2e5 100644 --- a/server/src/main/kotlin/suwayomi/tachidesk/graphql/queries/MangaQuery.kt +++ b/server/src/main/kotlin/suwayomi/tachidesk/graphql/queries/MangaQuery.kt @@ -16,6 +16,7 @@ import org.jetbrains.exposed.sql.SortOrder import org.jetbrains.exposed.sql.SqlExpressionBuilder.greater import org.jetbrains.exposed.sql.SqlExpressionBuilder.less import org.jetbrains.exposed.sql.transactions.transaction +import suwayomi.tachidesk.graphql.directives.RequireAuth import suwayomi.tachidesk.graphql.queries.filter.BooleanFilter import suwayomi.tachidesk.graphql.queries.filter.ComparableScalarFilter import suwayomi.tachidesk.graphql.queries.filter.Filter @@ -28,7 +29,6 @@ import suwayomi.tachidesk.graphql.queries.filter.andFilterWithCompare import suwayomi.tachidesk.graphql.queries.filter.andFilterWithCompareEntity import suwayomi.tachidesk.graphql.queries.filter.andFilterWithCompareString import suwayomi.tachidesk.graphql.queries.filter.applyOps -import suwayomi.tachidesk.graphql.server.getAttribute import suwayomi.tachidesk.graphql.server.primitives.Cursor import suwayomi.tachidesk.graphql.server.primitives.Order import suwayomi.tachidesk.graphql.server.primitives.OrderBy @@ -43,19 +43,14 @@ import suwayomi.tachidesk.graphql.types.MangaType import suwayomi.tachidesk.manga.model.table.CategoryMangaTable import suwayomi.tachidesk.manga.model.table.MangaStatus import suwayomi.tachidesk.manga.model.table.MangaTable -import suwayomi.tachidesk.server.JavalinSetup.Attribute -import suwayomi.tachidesk.server.JavalinSetup.getAttribute -import suwayomi.tachidesk.server.user.requireUser import java.util.concurrent.CompletableFuture class MangaQuery { + @RequireAuth fun manga( dataFetchingEnvironment: DataFetchingEnvironment, id: Int, - ): CompletableFuture { - dataFetchingEnvironment.getAttribute(Attribute.TachideskUser).requireUser() - return dataFetchingEnvironment.getValueFromDataLoader("MangaDataLoader", id) - } + ): CompletableFuture = dataFetchingEnvironment.getValueFromDataLoader("MangaDataLoader", id) enum class MangaOrderBy( override val column: Column<*>, @@ -222,8 +217,8 @@ class MangaQuery { ) } + @RequireAuth fun mangas( - dataFetchingEnvironment: DataFetchingEnvironment, condition: MangaCondition? = null, filter: MangaFilter? = null, @GraphQLDeprecated( @@ -243,7 +238,6 @@ class MangaQuery { last: Int? = null, offset: Int? = null, ): MangaNodeList { - dataFetchingEnvironment.getAttribute(Attribute.TachideskUser).requireUser() val queryResults = transaction { val res = diff --git a/server/src/main/kotlin/suwayomi/tachidesk/graphql/queries/MetaQuery.kt b/server/src/main/kotlin/suwayomi/tachidesk/graphql/queries/MetaQuery.kt index c2451b6f..e853891a 100644 --- a/server/src/main/kotlin/suwayomi/tachidesk/graphql/queries/MetaQuery.kt +++ b/server/src/main/kotlin/suwayomi/tachidesk/graphql/queries/MetaQuery.kt @@ -18,13 +18,13 @@ import org.jetbrains.exposed.sql.SqlExpressionBuilder.less import org.jetbrains.exposed.sql.selectAll import org.jetbrains.exposed.sql.transactions.transaction import suwayomi.tachidesk.global.model.table.GlobalMetaTable +import suwayomi.tachidesk.graphql.directives.RequireAuth import suwayomi.tachidesk.graphql.queries.filter.Filter import suwayomi.tachidesk.graphql.queries.filter.HasGetOp import suwayomi.tachidesk.graphql.queries.filter.OpAnd import suwayomi.tachidesk.graphql.queries.filter.StringFilter import suwayomi.tachidesk.graphql.queries.filter.andFilterWithCompareString import suwayomi.tachidesk.graphql.queries.filter.applyOps -import suwayomi.tachidesk.graphql.server.getAttribute import suwayomi.tachidesk.graphql.server.primitives.Cursor import suwayomi.tachidesk.graphql.server.primitives.Order import suwayomi.tachidesk.graphql.server.primitives.OrderBy @@ -36,19 +36,14 @@ import suwayomi.tachidesk.graphql.server.primitives.lessNotUnique import suwayomi.tachidesk.graphql.server.primitives.maybeSwap import suwayomi.tachidesk.graphql.types.GlobalMetaNodeList import suwayomi.tachidesk.graphql.types.GlobalMetaType -import suwayomi.tachidesk.server.JavalinSetup.Attribute -import suwayomi.tachidesk.server.JavalinSetup.getAttribute -import suwayomi.tachidesk.server.user.requireUser import java.util.concurrent.CompletableFuture class MetaQuery { + @RequireAuth fun meta( dataFetchingEnvironment: DataFetchingEnvironment, key: String, - ): CompletableFuture { - dataFetchingEnvironment.getAttribute(Attribute.TachideskUser).requireUser() - return dataFetchingEnvironment.getValueFromDataLoader("GlobalMetaDataLoader", key) - } + ): CompletableFuture = dataFetchingEnvironment.getValueFromDataLoader("GlobalMetaDataLoader", key) enum class MetaOrderBy( override val column: Column<*>, @@ -111,8 +106,8 @@ class MetaQuery { ) } + @RequireAuth fun metas( - dataFetchingEnvironment: DataFetchingEnvironment, condition: MetaCondition? = null, filter: MetaFilter? = null, @GraphQLDeprecated( @@ -132,7 +127,6 @@ class MetaQuery { last: Int? = null, offset: Int? = null, ): GlobalMetaNodeList { - dataFetchingEnvironment.getAttribute(Attribute.TachideskUser).requireUser() val queryResults = transaction { val res = GlobalMetaTable.selectAll() diff --git a/server/src/main/kotlin/suwayomi/tachidesk/graphql/queries/SettingsQuery.kt b/server/src/main/kotlin/suwayomi/tachidesk/graphql/queries/SettingsQuery.kt index 51d6d697..5a65d1bc 100644 --- a/server/src/main/kotlin/suwayomi/tachidesk/graphql/queries/SettingsQuery.kt +++ b/server/src/main/kotlin/suwayomi/tachidesk/graphql/queries/SettingsQuery.kt @@ -1,15 +1,9 @@ package suwayomi.tachidesk.graphql.queries -import graphql.schema.DataFetchingEnvironment -import suwayomi.tachidesk.graphql.server.getAttribute +import suwayomi.tachidesk.graphql.directives.RequireAuth import suwayomi.tachidesk.graphql.types.SettingsType -import suwayomi.tachidesk.server.JavalinSetup.Attribute -import suwayomi.tachidesk.server.JavalinSetup.getAttribute -import suwayomi.tachidesk.server.user.requireUser class SettingsQuery { - fun settings(dataFetchingEnvironment: DataFetchingEnvironment): SettingsType { - dataFetchingEnvironment.getAttribute(Attribute.TachideskUser).requireUser() - return SettingsType() - } + @RequireAuth + fun settings(): SettingsType = SettingsType() } diff --git a/server/src/main/kotlin/suwayomi/tachidesk/graphql/queries/SourceQuery.kt b/server/src/main/kotlin/suwayomi/tachidesk/graphql/queries/SourceQuery.kt index 8a3ce6cf..2aab3d29 100644 --- a/server/src/main/kotlin/suwayomi/tachidesk/graphql/queries/SourceQuery.kt +++ b/server/src/main/kotlin/suwayomi/tachidesk/graphql/queries/SourceQuery.kt @@ -17,6 +17,7 @@ import org.jetbrains.exposed.sql.SqlExpressionBuilder.greater import org.jetbrains.exposed.sql.SqlExpressionBuilder.less import org.jetbrains.exposed.sql.selectAll import org.jetbrains.exposed.sql.transactions.transaction +import suwayomi.tachidesk.graphql.directives.RequireAuth import suwayomi.tachidesk.graphql.queries.filter.BooleanFilter import suwayomi.tachidesk.graphql.queries.filter.Filter import suwayomi.tachidesk.graphql.queries.filter.HasGetOp @@ -27,7 +28,6 @@ import suwayomi.tachidesk.graphql.queries.filter.andFilterWithCompare import suwayomi.tachidesk.graphql.queries.filter.andFilterWithCompareEntity import suwayomi.tachidesk.graphql.queries.filter.andFilterWithCompareString import suwayomi.tachidesk.graphql.queries.filter.applyOps -import suwayomi.tachidesk.graphql.server.getAttribute import suwayomi.tachidesk.graphql.server.primitives.Cursor import suwayomi.tachidesk.graphql.server.primitives.Order import suwayomi.tachidesk.graphql.server.primitives.OrderBy @@ -40,19 +40,14 @@ import suwayomi.tachidesk.graphql.server.primitives.maybeSwap import suwayomi.tachidesk.graphql.types.SourceNodeList import suwayomi.tachidesk.graphql.types.SourceType import suwayomi.tachidesk.manga.model.table.SourceTable -import suwayomi.tachidesk.server.JavalinSetup.Attribute -import suwayomi.tachidesk.server.JavalinSetup.getAttribute -import suwayomi.tachidesk.server.user.requireUser import java.util.concurrent.CompletableFuture class SourceQuery { + @RequireAuth fun source( dataFetchingEnvironment: DataFetchingEnvironment, id: Long, - ): CompletableFuture { - dataFetchingEnvironment.getAttribute(Attribute.TachideskUser).requireUser() - return dataFetchingEnvironment.getValueFromDataLoader("SourceDataLoader", id) - } + ): CompletableFuture = dataFetchingEnvironment.getValueFromDataLoader("SourceDataLoader", id) enum class SourceOrderBy( override val column: Column<*>, @@ -127,8 +122,8 @@ class SourceQuery { ) } + @RequireAuth fun sources( - dataFetchingEnvironment: DataFetchingEnvironment, condition: SourceCondition? = null, filter: SourceFilter? = null, @GraphQLDeprecated( @@ -148,7 +143,6 @@ class SourceQuery { last: Int? = null, offset: Int? = null, ): SourceNodeList { - dataFetchingEnvironment.getAttribute(Attribute.TachideskUser).requireUser() val (queryResults, resultsAsType) = transaction { val res = SourceTable.selectAll() diff --git a/server/src/main/kotlin/suwayomi/tachidesk/graphql/queries/TrackQuery.kt b/server/src/main/kotlin/suwayomi/tachidesk/graphql/queries/TrackQuery.kt index a3d9acee..fbab0173 100644 --- a/server/src/main/kotlin/suwayomi/tachidesk/graphql/queries/TrackQuery.kt +++ b/server/src/main/kotlin/suwayomi/tachidesk/graphql/queries/TrackQuery.kt @@ -10,6 +10,7 @@ import org.jetbrains.exposed.sql.SqlExpressionBuilder.greater import org.jetbrains.exposed.sql.SqlExpressionBuilder.less import org.jetbrains.exposed.sql.selectAll import org.jetbrains.exposed.sql.transactions.transaction +import suwayomi.tachidesk.graphql.directives.RequireAuth import suwayomi.tachidesk.graphql.queries.filter.BooleanFilter import suwayomi.tachidesk.graphql.queries.filter.DoubleFilter import suwayomi.tachidesk.graphql.queries.filter.Filter @@ -22,7 +23,6 @@ import suwayomi.tachidesk.graphql.queries.filter.andFilterWithCompare import suwayomi.tachidesk.graphql.queries.filter.andFilterWithCompareEntity import suwayomi.tachidesk.graphql.queries.filter.andFilterWithCompareString import suwayomi.tachidesk.graphql.queries.filter.applyOps -import suwayomi.tachidesk.graphql.server.getAttribute import suwayomi.tachidesk.graphql.server.primitives.Cursor import suwayomi.tachidesk.graphql.server.primitives.Order import suwayomi.tachidesk.graphql.server.primitives.OrderBy @@ -40,20 +40,15 @@ import suwayomi.tachidesk.graphql.types.TrackerType import suwayomi.tachidesk.manga.impl.track.tracker.TrackerManager import suwayomi.tachidesk.manga.model.table.TrackRecordTable import suwayomi.tachidesk.manga.model.table.insertAll -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 TrackQuery { + @RequireAuth fun tracker( dataFetchingEnvironment: DataFetchingEnvironment, id: Int, - ): CompletableFuture { - dataFetchingEnvironment.getAttribute(Attribute.TachideskUser).requireUser() - return dataFetchingEnvironment.getValueFromDataLoader("TrackerDataLoader", id) - } + ): CompletableFuture = dataFetchingEnvironment.getValueFromDataLoader("TrackerDataLoader", id) enum class TrackerOrderBy { ID, @@ -121,8 +116,8 @@ class TrackQuery { val not: TrackerFilter? = null, ) + @RequireAuth fun trackers( - dataFetchingEnvironment: DataFetchingEnvironment, condition: TrackerCondition? = null, @GraphQLDeprecated( "Replaced with order", @@ -141,7 +136,6 @@ class TrackQuery { last: Int? = null, offset: Int? = null, ): TrackerNodeList { - dataFetchingEnvironment.getAttribute(Attribute.TachideskUser).requireUser() val (queryResults, resultsAsType) = run { var res = TrackerManager.services.map { TrackerType(it) } @@ -246,13 +240,12 @@ class TrackQuery { ) } + @RequireAuth fun trackRecord( dataFetchingEnvironment: DataFetchingEnvironment, id: Int, - ): CompletableFuture { - dataFetchingEnvironment.getAttribute(Attribute.TachideskUser).requireUser() - return dataFetchingEnvironment.getValueFromDataLoader("TrackRecordDataLoader", id) - } + ): CompletableFuture = + dataFetchingEnvironment.getValueFromDataLoader("TrackRecordDataLoader", id) enum class TrackRecordOrderBy( override val column: Column<*>, @@ -399,8 +392,8 @@ class TrackQuery { ) } + @RequireAuth fun trackRecords( - dataFetchingEnvironment: DataFetchingEnvironment, condition: TrackRecordCondition? = null, filter: TrackRecordFilter? = null, @GraphQLDeprecated( @@ -420,7 +413,6 @@ class TrackQuery { last: Int? = null, offset: Int? = null, ): TrackRecordNodeList { - dataFetchingEnvironment.getAttribute(Attribute.TachideskUser).requireUser() val queryResults = transaction { val res = TrackRecordTable.selectAll() @@ -503,12 +495,9 @@ class TrackQuery { val trackSearches: List, ) - fun searchTracker( - dataFetchingEnvironment: DataFetchingEnvironment, - input: SearchTrackerInput, - ): CompletableFuture = + @RequireAuth + fun searchTracker(input: SearchTrackerInput): CompletableFuture = future { - dataFetchingEnvironment.getAttribute(Attribute.TachideskUser).requireUser() val tracker = requireNotNull(TrackerManager.getTracker(input.trackerId)) { "Tracker not found" diff --git a/server/src/main/kotlin/suwayomi/tachidesk/graphql/queries/UpdateQuery.kt b/server/src/main/kotlin/suwayomi/tachidesk/graphql/queries/UpdateQuery.kt index 4e349d5d..83113c52 100644 --- a/server/src/main/kotlin/suwayomi/tachidesk/graphql/queries/UpdateQuery.kt +++ b/server/src/main/kotlin/suwayomi/tachidesk/graphql/queries/UpdateQuery.kt @@ -1,16 +1,12 @@ package suwayomi.tachidesk.graphql.queries import com.expediagroup.graphql.generator.annotations.GraphQLDeprecated -import graphql.schema.DataFetchingEnvironment import kotlinx.coroutines.flow.first -import suwayomi.tachidesk.graphql.server.getAttribute +import suwayomi.tachidesk.graphql.directives.RequireAuth import suwayomi.tachidesk.graphql.types.LibraryUpdateStatus import suwayomi.tachidesk.graphql.types.UpdateStatus import suwayomi.tachidesk.manga.impl.update.IUpdater -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 uy.kohesive.injekt.injectLazy import java.util.concurrent.CompletableFuture @@ -18,15 +14,15 @@ class UpdateQuery { private val updater: IUpdater by injectLazy() @GraphQLDeprecated("Replaced with libraryUpdateStatus", ReplaceWith("libraryUpdateStatus")) - fun updateStatus(dataFetchingEnvironment: DataFetchingEnvironment): CompletableFuture = + @RequireAuth + fun updateStatus(): CompletableFuture = future { - dataFetchingEnvironment.getAttribute(Attribute.TachideskUser).requireUser() UpdateStatus(updater.status.first()) } - fun libraryUpdateStatus(dataFetchingEnvironment: DataFetchingEnvironment): CompletableFuture = + @RequireAuth + fun libraryUpdateStatus(): CompletableFuture = future { - dataFetchingEnvironment.getAttribute(Attribute.TachideskUser).requireUser() LibraryUpdateStatus(updater.getStatus()) } @@ -34,8 +30,6 @@ class UpdateQuery { val timestamp: Long, ) - fun lastUpdateTimestamp(dataFetchingEnvironment: DataFetchingEnvironment): LastUpdateTimestampPayload { - dataFetchingEnvironment.getAttribute(Attribute.TachideskUser).requireUser() - return LastUpdateTimestampPayload(updater.getLastUpdateTimestamp()) - } + @RequireAuth + fun lastUpdateTimestamp(): LastUpdateTimestampPayload = LastUpdateTimestampPayload(updater.getLastUpdateTimestamp()) } diff --git a/server/src/main/kotlin/suwayomi/tachidesk/graphql/server/TachideskGraphQLSchema.kt b/server/src/main/kotlin/suwayomi/tachidesk/graphql/server/TachideskGraphQLSchema.kt index 6c8034cc..c3dedfd9 100644 --- a/server/src/main/kotlin/suwayomi/tachidesk/graphql/server/TachideskGraphQLSchema.kt +++ b/server/src/main/kotlin/suwayomi/tachidesk/graphql/server/TachideskGraphQLSchema.kt @@ -9,10 +9,12 @@ package suwayomi.tachidesk.graphql.server import com.expediagroup.graphql.generator.SchemaGeneratorConfig import com.expediagroup.graphql.generator.TopLevelObject +import com.expediagroup.graphql.generator.directives.KotlinDirectiveWiringFactory import com.expediagroup.graphql.generator.hooks.FlowSubscriptionSchemaGeneratorHooks import com.expediagroup.graphql.generator.toSchema import graphql.schema.GraphQLType import io.javalin.http.UploadedFile +import suwayomi.tachidesk.graphql.directives.RequireAuthDirectiveWiring import suwayomi.tachidesk.graphql.mutations.BackupMutation import suwayomi.tachidesk.graphql.mutations.CategoryMutation import suwayomi.tachidesk.graphql.mutations.ChapterMutation @@ -54,6 +56,11 @@ import kotlin.reflect.KType import kotlin.time.Duration class CustomSchemaGeneratorHooks : FlowSubscriptionSchemaGeneratorHooks() { + override val wiringFactory = + KotlinDirectiveWiringFactory( + manualWiring = mapOf("requireAuth" to RequireAuthDirectiveWiring()), + ) + override fun willGenerateGraphQLType(type: KType): GraphQLType? = when (type.classifier as? KClass<*>) { Long::class -> GraphQLLongAsString // encode to string for JS diff --git a/server/src/main/kotlin/suwayomi/tachidesk/graphql/server/TachideskGraphQLServer.kt b/server/src/main/kotlin/suwayomi/tachidesk/graphql/server/TachideskGraphQLServer.kt index a643e4c6..fbfd6945 100644 --- a/server/src/main/kotlin/suwayomi/tachidesk/graphql/server/TachideskGraphQLServer.kt +++ b/server/src/main/kotlin/suwayomi/tachidesk/graphql/server/TachideskGraphQLServer.kt @@ -16,6 +16,7 @@ import graphql.GraphQL import graphql.execution.AsyncExecutionStrategy import graphql.execution.DataFetcherExceptionHandler import graphql.execution.DataFetcherExceptionHandlerResult +import graphql.schema.idl.RuntimeWiring import io.github.oshai.kotlinlogging.KotlinLogging import io.javalin.http.Context import io.javalin.websocket.WsCloseContext diff --git a/server/src/main/kotlin/suwayomi/tachidesk/graphql/subscriptions/DownloadSubscription.kt b/server/src/main/kotlin/suwayomi/tachidesk/graphql/subscriptions/DownloadSubscription.kt index 2d55b7c1..5d977ee1 100644 --- a/server/src/main/kotlin/suwayomi/tachidesk/graphql/subscriptions/DownloadSubscription.kt +++ b/server/src/main/kotlin/suwayomi/tachidesk/graphql/subscriptions/DownloadSubscription.kt @@ -9,25 +9,20 @@ package suwayomi.tachidesk.graphql.subscriptions import com.expediagroup.graphql.generator.annotations.GraphQLDeprecated import com.expediagroup.graphql.generator.annotations.GraphQLDescription -import graphql.schema.DataFetchingEnvironment import kotlinx.coroutines.flow.Flow import kotlinx.coroutines.flow.map -import suwayomi.tachidesk.graphql.server.getAttribute +import suwayomi.tachidesk.graphql.directives.RequireAuth import suwayomi.tachidesk.graphql.types.DownloadStatus import suwayomi.tachidesk.graphql.types.DownloadUpdates import suwayomi.tachidesk.manga.impl.download.DownloadManager -import suwayomi.tachidesk.server.JavalinSetup.Attribute -import suwayomi.tachidesk.server.JavalinSetup.getAttribute -import suwayomi.tachidesk.server.user.requireUser class DownloadSubscription { @GraphQLDeprecated("Replaced with downloadStatusChanged", ReplaceWith("downloadStatusChanged(input)")) - fun downloadChanged(dataFetchingEnvironment: DataFetchingEnvironment): Flow { - dataFetchingEnvironment.getAttribute(Attribute.TachideskUser).requireUser() - return DownloadManager.status.map { downloadStatus -> + @RequireAuth + fun downloadChanged(): Flow = + DownloadManager.status.map { downloadStatus -> DownloadStatus(downloadStatus) } - } data class DownloadChangedInput( @GraphQLDescription( @@ -40,11 +35,8 @@ class DownloadSubscription { val maxUpdates: Int?, ) - fun downloadStatusChanged( - dataFetchingEnvironment: DataFetchingEnvironment, - input: DownloadChangedInput, - ): Flow { - dataFetchingEnvironment.getAttribute(Attribute.TachideskUser).requireUser() + @RequireAuth + fun downloadStatusChanged(input: DownloadChangedInput): Flow { val omitUpdates = input.maxUpdates != null val maxUpdates = input.maxUpdates ?: 50 diff --git a/server/src/main/kotlin/suwayomi/tachidesk/graphql/subscriptions/InfoSubscription.kt b/server/src/main/kotlin/suwayomi/tachidesk/graphql/subscriptions/InfoSubscription.kt index 35a54100..2a59f320 100644 --- a/server/src/main/kotlin/suwayomi/tachidesk/graphql/subscriptions/InfoSubscription.kt +++ b/server/src/main/kotlin/suwayomi/tachidesk/graphql/subscriptions/InfoSubscription.kt @@ -1,17 +1,11 @@ package suwayomi.tachidesk.graphql.subscriptions -import graphql.schema.DataFetchingEnvironment import kotlinx.coroutines.flow.Flow -import suwayomi.tachidesk.graphql.server.getAttribute +import suwayomi.tachidesk.graphql.directives.RequireAuth import suwayomi.tachidesk.graphql.types.WebUIUpdateStatus -import suwayomi.tachidesk.server.JavalinSetup.Attribute -import suwayomi.tachidesk.server.JavalinSetup.getAttribute -import suwayomi.tachidesk.server.user.requireUser import suwayomi.tachidesk.server.util.WebInterfaceManager class InfoSubscription { - fun webUIUpdateStatusChange(dataFetchingEnvironment: DataFetchingEnvironment): Flow { - dataFetchingEnvironment.getAttribute(Attribute.TachideskUser).requireUser() - return WebInterfaceManager.status - } + @RequireAuth + fun webUIUpdateStatusChange(): Flow = WebInterfaceManager.status } diff --git a/server/src/main/kotlin/suwayomi/tachidesk/graphql/subscriptions/UpdateSubscription.kt b/server/src/main/kotlin/suwayomi/tachidesk/graphql/subscriptions/UpdateSubscription.kt index 280e1eb6..535d07c1 100644 --- a/server/src/main/kotlin/suwayomi/tachidesk/graphql/subscriptions/UpdateSubscription.kt +++ b/server/src/main/kotlin/suwayomi/tachidesk/graphql/subscriptions/UpdateSubscription.kt @@ -9,29 +9,24 @@ package suwayomi.tachidesk.graphql.subscriptions import com.expediagroup.graphql.generator.annotations.GraphQLDeprecated import com.expediagroup.graphql.generator.annotations.GraphQLDescription -import graphql.schema.DataFetchingEnvironment import kotlinx.coroutines.flow.Flow import kotlinx.coroutines.flow.map -import suwayomi.tachidesk.graphql.server.getAttribute +import suwayomi.tachidesk.graphql.directives.RequireAuth import suwayomi.tachidesk.graphql.types.UpdateStatus import suwayomi.tachidesk.graphql.types.UpdaterUpdates import suwayomi.tachidesk.manga.impl.update.IUpdater import suwayomi.tachidesk.manga.impl.update.UpdateUpdates -import suwayomi.tachidesk.server.JavalinSetup.Attribute -import suwayomi.tachidesk.server.JavalinSetup.getAttribute -import suwayomi.tachidesk.server.user.requireUser import uy.kohesive.injekt.injectLazy class UpdateSubscription { private val updater: IUpdater by injectLazy() @GraphQLDeprecated("Replaced with updates", ReplaceWith("updates(input)")) - fun updateStatusChanged(dataFetchingEnvironment: DataFetchingEnvironment): Flow { - dataFetchingEnvironment.getAttribute(Attribute.TachideskUser).requireUser() - return updater.status.map { updateStatus -> + @RequireAuth + fun updateStatusChanged(): Flow = + updater.status.map { updateStatus -> UpdateStatus(updateStatus) } - } data class LibraryUpdateStatusChangedInput( @GraphQLDescription( @@ -44,11 +39,8 @@ class UpdateSubscription { val maxUpdates: Int?, ) - fun libraryUpdateStatusChanged( - dataFetchingEnvironment: DataFetchingEnvironment, - input: LibraryUpdateStatusChangedInput, - ): Flow { - dataFetchingEnvironment.getAttribute(Attribute.TachideskUser).requireUser() + @RequireAuth + fun libraryUpdateStatusChanged(input: LibraryUpdateStatusChangedInput): Flow { val omitUpdates = input.maxUpdates != null val maxUpdates = input.maxUpdates ?: 50