Skip to content

feat(multi.suwayomi): add user and password support#223

Open
Cruellest wants to merge 3 commits intoAidoku-Community:mainfrom
Cruellest:main
Open

feat(multi.suwayomi): add user and password support#223
Cruellest wants to merge 3 commits intoAidoku-Community:mainfrom
Cruellest:main

Conversation

@Cruellest
Copy link

Adding support for simple login on suwayomi

It includes:

  • Adding new configurations parameters including User and Pass
  • Updating the app version
  • Interacting with suwayomi login
{
let base_url = settings::get_base_url()?;

if let Some((user, pass)) = settings::get_credentials() {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm not too familiar with aidoku auth patterns but looking at the aidoku-rs source code, this is probably what you want: https://github.com/Aidoku/aidoku-rs/blob/405b91d74c95e8099217b30ede333f852e6d9c5c/crates/lib/src/structs/source.rs#L116 instead of POSTing to login at every request.

If this is not the pattern, looking at the paperback implementation, an authorization header should be set https://github.com/Suwayomi/tachidesk-paperback-ext/blob/813586cdecd6094461b48bca95cc84220320c621/src/TachiDesk/TachiDesk.ts#L96

I'll leave it to @kkantan for guidance

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

yes, I would agree with this. @Cruellest there is a specific "login" setting type that can also be combined with a BasicLoginHandler if necessary. I briefly checked the suwayomi wiki, and it looks like you should just be able to send an Authorization header with each request that contains the base64-encoded user name and password, thus not requiring a handler.

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The login component its really better, thanks for the recomendation, i implemented diferent login logic for diferent authentication types, when using basic authentication it really is as simple as sending an authorization header, but the other login type is a little more tricky, please tell me if there is any problem with it, or if i didn't understood any recomendation

{
let base_url = settings::get_base_url()?;

if let Some((user, pass)) = settings::get_credentials() {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

yes, I would agree with this. @Cruellest there is a specific "login" setting type that can also be combined with a BasicLoginHandler if necessary. I briefly checked the suwayomi wiki, and it looks like you should just be able to send an Authorization header with each request that contains the base64-encoded user name and password, thus not requiring a handler.

@Syer10
Copy link

Syer10 commented Dec 14, 2025

A good reference for this would be the Suwayomi extension for Tachiyomi/Mihon, specifically the TokenManager.
https://github.com/Suwayomi/tachiyomi-extension/blob/main/src/all/tachidesk/src/eu/kanade/tachiyomi/extension/all/tachidesk/TokenManager.kt

I'm a dev for Suwayomi so feel free to ask me if you need any advice on implementations.

@Cruellest Cruellest requested a review from kkantan December 14, 2025 22:49
@Cruellest
Copy link
Author

A good reference for this would be the Suwayomi extension for Tachiyomi/Mihon, specifically the TokenManager. Suwayomi/tachiyomi-extension@main/src/all/tachidesk/src/eu/kanade/tachiyomi/extension/all/tachidesk/TokenManager.kt

I'm a dev for Suwayomi so feel free to ask me if you need any advice on implementations.

Wow thx for the sugestion, i will look at the Mihon implementation and see what i could improve, On that note i am implementing the UI Login logic but i couldn't find any instance of official UI that implements it (at least in my instance of suwayomi it doesn't exists) is there any recomendation of UI that uses it or any method that i could use to debug it?

@Syer10
Copy link

Syer10 commented Dec 14, 2025

Wow thx for the sugestion, i will look at the Mihon implementation and see what i could improve, On that note i am implementing the UI Login logic but i couldn't find any instance of official UI that implements it (at least in my instance of suwayomi it doesn't exists) is there any recomendation of UI that uses it or any method that i could use to debug it?

The Mihon extension does implement it. And the WebUI does as well. I would suggest you mainly reference the Mihon extension though since it is a much more centralized implementation. WebUI handles different things in different places. Such as the login(get refresh token) request in the Login page, and the refresh access token in the base client interface.

A lot of the testing for the UI_LOGIN can be done in Graphql Playground(found at /api/graphql).
Using these mutations

mutation Login($password: String!, $username: String!) { login(input: {password: $password, username: $username}) { refreshToken accessToken } } mutation RefreshAccessToken($refreshToken: String!) { refreshToken(input: {refreshToken: $refreshToken}) { accessToken } }

Then you can test normal queries by changing the headers field at the bottom of the GQL Playground to something like

{ "authorization": "Bearer MY_ACCESS_TOKEN" }
output
}

fn url_encode(input: &str) -> String {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

there's an encode_uri_component in aidoku-rs helpers you can use instead, unless this is a specific implementation?

use alloc::vec;
use core::fmt::Write;

fn base64_encode(input: &str) -> String {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

you can use the base64, with default features disabled, instead of implementing it yourself. I believe there are other sources that do this.

use aidoku::{AidokuError, alloc::string::String, imports::defaults::defaults_get, prelude::bail};
use aidoku::{Result, alloc::String, imports::defaults::defaults_get, prelude::*};

const BASE_URL_KEY: &str = "baseUrl";
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

no reason to remove this. you can also add a AUTH_MODE_KEY const.

let send_req = |with_basic: bool| {
let mut request = Request::post(format!("{base_url}/api/graphql"))?
.header("Content-Type", "application/json")
.body(body_str.clone());
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this shouldn't need to be cloned

Comment on lines +15 to +28
{
"type": "select",
"key": "authMode",
"title": "Auth Mode",
"values": ["auto", "none", "basic_auth", "simple_login"],
"titles": [
"Auto",
"None",
"Basic Auth",
"Simple Login"
],
"default": "auto",
"refreshes": ["content"]
},
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

is it not possible to determine this automatically via some request to suwayomi? I would expect it to be, but if not that's okay.

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It is not. Most clients ask the user to input the auth mode.

@kkantan kkantan linked an issue Dec 18, 2025 that may be closed by this pull request
@kkantan kkantan mentioned this pull request Jan 13, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

4 participants