diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 549f3340..df3908d7 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -35,6 +35,24 @@ The GraphQL API can be queried with a POST request to `/api/graphql`. There is a The REST API can be queried at `/api/v1`. An interactive Swagger API explorer is available at `/api/swagger-ui`. +### Tracker client authorization +#### OAuth +Since the url of a Suwayomi-Server is not known, it is not possible to redirect directly to the client.
+Thus, to provide tracker support via oauth, the tracker clients redirect to the [suwayomi website](https://suwayomi.org/) +and there the actual redirection to the client takes place. + +When implementing the login process in your client you have to make sure to follow some preconditions: + +To be able to redirect to the client you have to attach a `state` object to the query of the auth url +- this `state` object has to have a `redirectUrl` which points to the client route at which you want to handle the auth result +- besides the `redirectUrl` you can pass any information you require to handle the result (e.g. the server `id` of the tracker client) +- example URL for AniList: `https://anilist.co/api/v2/oauth/authorize?client_id=ID&response_type=token&state={ redirectUrl: "http://localhost:4567/handle/oauth/result", trackerId: 1, anyOtherInfo: "your client requires" }` + +Once the permission has been granted, you will get redirected to the client at the provided route (`redirectUrl`).
+- Example URL (decoded) for AniList: `http://localhost:4567/tracker/login?access_token=TOKEN&token_type=Bearer&expires_in=31622400&state={ redirectUrl: "http://localhost:4567/handle/oauth/result", trackerId: 1, anyOtherInfo: "your client requires" }`).
+ +Finally, to finish the login process, you just have to pass this URL to the server as the `callbackUrl`. + ## Why a web app? This structure is chosen to - Achieve the maximum multi-platform-ness diff --git a/server/src/main/kotlin/suwayomi/tachidesk/graphql/server/TachideskDataLoaderRegistryFactory.kt b/server/src/main/kotlin/suwayomi/tachidesk/graphql/server/TachideskDataLoaderRegistryFactory.kt index 24953c1f..572896ae 100644 --- a/server/src/main/kotlin/suwayomi/tachidesk/graphql/server/TachideskDataLoaderRegistryFactory.kt +++ b/server/src/main/kotlin/suwayomi/tachidesk/graphql/server/TachideskDataLoaderRegistryFactory.kt @@ -15,6 +15,7 @@ import suwayomi.tachidesk.graphql.dataLoaders.CategoryMetaDataLoader import suwayomi.tachidesk.graphql.dataLoaders.ChapterDataLoader import suwayomi.tachidesk.graphql.dataLoaders.ChapterMetaDataLoader import suwayomi.tachidesk.graphql.dataLoaders.ChaptersForMangaDataLoader +import suwayomi.tachidesk.graphql.dataLoaders.DisplayScoreForTrackRecordDataLoader import suwayomi.tachidesk.graphql.dataLoaders.DownloadedChapterCountForMangaDataLoader import suwayomi.tachidesk.graphql.dataLoaders.ExtensionDataLoader import suwayomi.tachidesk.graphql.dataLoaders.ExtensionForSourceDataLoader @@ -30,6 +31,10 @@ import suwayomi.tachidesk.graphql.dataLoaders.MangaForSourceDataLoader import suwayomi.tachidesk.graphql.dataLoaders.MangaMetaDataLoader import suwayomi.tachidesk.graphql.dataLoaders.SourceDataLoader import suwayomi.tachidesk.graphql.dataLoaders.SourcesForExtensionDataLoader +import suwayomi.tachidesk.graphql.dataLoaders.TrackRecordDataLoader +import suwayomi.tachidesk.graphql.dataLoaders.TrackRecordsForMangaIdDataLoader +import suwayomi.tachidesk.graphql.dataLoaders.TrackRecordsForTrackerIdDataLoader +import suwayomi.tachidesk.graphql.dataLoaders.TrackerDataLoader import suwayomi.tachidesk.graphql.dataLoaders.UnreadChapterCountForMangaDataLoader class TachideskDataLoaderRegistryFactory { @@ -59,11 +64,11 @@ class TachideskDataLoaderRegistryFactory { SourcesForExtensionDataLoader(), ExtensionDataLoader(), ExtensionForSourceDataLoader(), - // TrackerDataLoader(), - // TrackRecordsForMangaIdDataLoader(), - // DisplayScoreForTrackRecordDataLoader(), - // TrackRecordsForTrackerIdDataLoader(), - // TrackRecordDataLoader(), + TrackerDataLoader(), + TrackRecordsForMangaIdDataLoader(), + DisplayScoreForTrackRecordDataLoader(), + TrackRecordsForTrackerIdDataLoader(), + TrackRecordDataLoader(), ) } } 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 6d7cbdac..ae2ce146 100644 --- a/server/src/main/kotlin/suwayomi/tachidesk/graphql/server/TachideskGraphQLSchema.kt +++ b/server/src/main/kotlin/suwayomi/tachidesk/graphql/server/TachideskGraphQLSchema.kt @@ -24,6 +24,7 @@ import suwayomi.tachidesk.graphql.mutations.MangaMutation import suwayomi.tachidesk.graphql.mutations.MetaMutation import suwayomi.tachidesk.graphql.mutations.SettingsMutation import suwayomi.tachidesk.graphql.mutations.SourceMutation +import suwayomi.tachidesk.graphql.mutations.TrackMutation import suwayomi.tachidesk.graphql.mutations.UpdateMutation import suwayomi.tachidesk.graphql.queries.BackupQuery import suwayomi.tachidesk.graphql.queries.CategoryQuery @@ -35,6 +36,7 @@ import suwayomi.tachidesk.graphql.queries.MangaQuery import suwayomi.tachidesk.graphql.queries.MetaQuery import suwayomi.tachidesk.graphql.queries.SettingsQuery import suwayomi.tachidesk.graphql.queries.SourceQuery +import suwayomi.tachidesk.graphql.queries.TrackQuery import suwayomi.tachidesk.graphql.queries.UpdateQuery import suwayomi.tachidesk.graphql.server.primitives.Cursor import suwayomi.tachidesk.graphql.server.primitives.GraphQLCursor @@ -76,7 +78,7 @@ val schema = TopLevelObject(MetaQuery()), TopLevelObject(SettingsQuery()), TopLevelObject(SourceQuery()), - // TopLevelObject(TrackQuery()), + TopLevelObject(TrackQuery()), TopLevelObject(UpdateQuery()), ), mutations = @@ -92,7 +94,7 @@ val schema = TopLevelObject(MetaMutation()), TopLevelObject(SettingsMutation()), TopLevelObject(SourceMutation()), - // TopLevelObject(TrackMutation()), + TopLevelObject(TrackMutation()), TopLevelObject(UpdateMutation()), ), subscriptions = diff --git a/server/src/main/kotlin/suwayomi/tachidesk/graphql/types/MangaType.kt b/server/src/main/kotlin/suwayomi/tachidesk/graphql/types/MangaType.kt index 1180c216..c805f12a 100644 --- a/server/src/main/kotlin/suwayomi/tachidesk/graphql/types/MangaType.kt +++ b/server/src/main/kotlin/suwayomi/tachidesk/graphql/types/MangaType.kt @@ -155,9 +155,9 @@ class MangaType( return dataFetchingEnvironment.getValueFromDataLoader("SourceDataLoader", sourceId) } - // fun trackRecords(dataFetchingEnvironment: DataFetchingEnvironment): CompletableFuture { - // return dataFetchingEnvironment.getValueFromDataLoader("TrackRecordsForMangaIdDataLoader", id) - // } + fun trackRecords(dataFetchingEnvironment: DataFetchingEnvironment): CompletableFuture { + return dataFetchingEnvironment.getValueFromDataLoader("TrackRecordsForMangaIdDataLoader", id) + } } data class MangaNodeList( diff --git a/server/src/main/kotlin/suwayomi/tachidesk/manga/MangaAPI.kt b/server/src/main/kotlin/suwayomi/tachidesk/manga/MangaAPI.kt index f75f797e..e017ad4e 100644 --- a/server/src/main/kotlin/suwayomi/tachidesk/manga/MangaAPI.kt +++ b/server/src/main/kotlin/suwayomi/tachidesk/manga/MangaAPI.kt @@ -20,6 +20,7 @@ import suwayomi.tachidesk.manga.controller.DownloadController import suwayomi.tachidesk.manga.controller.ExtensionController import suwayomi.tachidesk.manga.controller.MangaController import suwayomi.tachidesk.manga.controller.SourceController +import suwayomi.tachidesk.manga.controller.TrackController import suwayomi.tachidesk.manga.controller.UpdateController object MangaAPI { @@ -133,13 +134,13 @@ object MangaAPI { ws("", UpdateController::categoryUpdateWS) } - // path("track") { - // get("list", TrackController.list) - // post("login", TrackController.login) - // post("logout", TrackController.logout) - // post("search", TrackController.search) - // post("bind", TrackController.bind) - // post("update", TrackController.update) - // } + path("track") { + get("list", TrackController.list) + post("login", TrackController.login) + post("logout", TrackController.logout) + post("search", TrackController.search) + post("bind", TrackController.bind) + post("update", TrackController.update) + } } }