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)
+ }
}
}