Ashinch / ReadYou

An Android RSS reader presented in Material You style.
GNU General Public License v3.0
5.11k stars 202 forks source link

Cannot login to FreshRSS - "body format error for CL Token" #746

Closed shalak closed 3 months ago

shalak commented 5 months ago

1. Environment

2. Describe the bug

When trying to add my FreshRSS instance to Read You, I'm getting the following error:

image

Here's my Authentication configuration in FreshRSS:

image
Tealk commented 3 months ago

Did you append /api/greader.php to the end of the URL? That's exactly the error I got because I didn't enter the entire URL.

@Alkarex Why is the path not appended automatically?

Alkarex commented 3 months ago

Why is the path not appended automatically?

That should be a question to the developer of Read You, who could consider having some helpers functions for FreshRSS (e.g. add API path if missing, or even pre-indicate the API path in the UI when entering the server URL)

At FreshRSS level, we could potentially make some guesses and send some HTTP redirections, but that would not be so efficient

Tealk commented 3 months ago

sorry, thought you were involved in the implementation as you were mentioned in the release note.

also think the best would be an autocomplete in the app if only the domain without path is given.

shalak commented 3 months ago

image

With the https://freshrss.mydomain.net/api/greader.php, I'm getting the Invalid XML: Error on line 1: At line 1, ... error.

This URL replies with "OK" body, nothing else:

< HTTP/2 200
< content-type: text/html; charset=UTF-8
< date: Fri, 26 Jul 2024 08:29:23 GMT
< server: nginx
< vary: Accept-Encoding
< x-powered-by: PHP/8.2.13
<
* Connection #0 to host freshrss.mydomain.net left intact
OK
Tealk commented 3 months ago

is this how you get the api page displayed? https://freshrss.mydomain.net/api

shalak commented 3 months ago

Neither of the following work:

https://freshrss.mydomain.net/api/
https://freshrss.mydomain.net/api/greader.php
https://freshrss.mydomain.net/p/api/greader.php
https://freshrss.mydomain.net/p/api/

Here's what curl says:

$ curl https://freshrss.mydomain.net/api/
<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en-GB" lang="en-GB">
<head>
<meta charset="UTF-8" />
<title>FreshRSS API endpoints</title>
<meta name="robots" content="noindex" />
<link rel="start" href="../i/" />
<script src="../scripts/api.js" defer="defer"></script>
<script id="jsonVars" type="application/json">
{"greader":"https:\/\/freshrss.mydomain.net\/api\/greader.php","fever":"https:\/\/freshrss.mydomain.net\/api\/fever.php"}</script>
</head>

<body>
<h1>FreshRSS API endpoints</h1>

<h2>Google Reader compatible API</h2>
<dl>
<dt>Your API address:</dt>
<dd>https://freshrss.mydomain.net/api/greader.php</dd>
<dt>Google Reader API configuration test:</dt>
<dd id="greaderOutput">?</dd>
</dl>

<h2>Fever compatible API</h2>
<dl>
<dt>Your API address:</dt>
<dd>https://freshrss.mydomain.net/api/fever.php</dd>
<dt>Fever API configuration test:</dt>
<dd id="feverOutput">?</dd>
</dl>

</body>
</html>

$ curl https://freshrss.mydomain.net/api/greader.php
OK

$ curl https://freshrss.mydomain.net/p/api/greader.php
File not found.

$ curl https://freshrss.mydomain.net/p/api/
$ curl -L https://freshrss.mydomain.net/p/api/
<!DOCTYPE html>
<html lang="en" xml:lang="en" class="">
    <head>
        <meta charset="UTF-8" />
        <meta name="viewport" content="width=device-width, initial-scale=1.0, viewport-fit=cover" />
        <meta name="theme-color" media="(prefers-color-scheme: light)" content="#f0f0f0" /><meta name="theme-color" media="(prefers-color-scheme: dark)" content="#1f1f1f" />       <link rel="stylesheet" href="../themes/base-theme/frss.css?1698691706" />
<link rel="stylesheet" href="../themes/Origine/origine.css?1698691706" />
        <script id="jsonVars" type="application/json">
{"context":{"anonymous":true,"auto_remove_article":false,"hide_posts":true,"display_order":"DESC","display_categories":"active","auto_mark_article":true,"auto_mark_site":true,"auto_mark_scroll":false,"auto_load_more":true,"auto_actualize_feeds":false,"does_lazyload":true,"sides_close_article":false,"sticky_post":true,"html5_notif_timeout":0,"auth_type":"form","current_view":"formLogin","csrf":"5c737e746b72f6831a1ab716b2429b043550c8ff","mtime":{"extra.js":1698691706,"feed.js":1698691706}},"shortcuts":{"actualize":"q","mark_read":"r","mark_favorite":"f","go_website":"space","prev_entry":"k","next_entry":"j","next_unread_entry":"h","skip_prev_entry":"p","skip_next_entry":"n","first_entry":"home","last_entry":"end","collapse_entry":"c","load_more":"m","auto_share":"s","focus_search":"a","user_filter":"u","help":"f1","close_dropdown":"escape","normal_view":"1","global_view":"2","reading_view":"3","rss_view":"4","toggle_media":"v"},"urls":{"index":".\/","login":".\/?c=auth&amp;a=login","logout":".\/?c=auth&amp;a=logout","help":"https:\/\/freshrss.github.io\/FreshRSS\/"},"i18n":{"confirmation_default":"Are you sure you want to perform this action? It cannot be cancelled!","notif_title_articles":"FreshRSS: new articles!","notif_body_new_articles":"There are %%d new articles to read on FreshRSS.","notif_body_unread_articles":"(unread: %%d)","notif_request_failed":"A request has failed, it may have been caused by internet connection problems.","category_empty":"Empty category","labels_empty":"No labels","language":"en"},"icons":{"read":"%3Cimg%20class%3D%22icon%22%20src%3D%22..%2Fthemes%2Ficons%2Fread.svg%22%20loading%3D%22lazy%22%20alt%3D%22%E2%98%91%EF%B8%8F%22%20%2F%3E","unread":"%3Cimg%20class%3D%22icon%22%20src%3D%22..%2Fthemes%2Ficons%2Funread.svg%22%20loading%3D%22lazy%22%20alt%3D%22%F0%9F%94%B2%22%20%2F%3E"},"extensions":[]}      </script>
        <script src="../scripts/main.js?1686355627" defer="defer" async="async"></script>
<script src="../scripts/extra.js?1698691706" defer="defer" async="async"></script>
<script src="../scripts/bcrypt.min.js?1698691706" defer="defer" async="async"></script>
        <link rel="manifest" href="../themes/manifest.json" />
        <link rel="shortcut icon" id="favicon" type="image/x-icon" sizes="16x16 64x64" href="../favicon.ico" />
        <link rel="icon msapplication-TileImage apple-touch-icon" type="image/png" sizes="256x256" href="../themes/icons/favicon-256.png" />
        <link rel="apple-touch-icon" href="../themes/icons/apple-touch-icon.png" />
        <meta name="apple-mobile-web-app-capable" content="yes" />
        <meta name="apple-mobile-web-app-status-bar-style" content="black" />
        <meta name="apple-mobile-web-app-title" content="FreshRSS">
        <meta name="msapplication-TileColor" content="#FFF" />
        <meta name="theme-color" content="#FFF" />
        <meta name="referrer" content="never" />
        <title>Login · FreshRSS</title>
        <meta name="robots" content="noindex,nofollow" />
    </head>
    <body class="formLogin">
<header class="header">
    <div class="item title">
        <a href="./">
                            <img class="logo" src="../themes/icons/FreshRSS-logo.svg" alt="FreshRSS" loading="lazy" />
                    </a>
    </div>

    <div class="item search">
            </div>

        <div class="item configure">
        <a class="signin" href="./?c=auth&amp;a=login"><img class="icon" src="../themes/icons/login.svg" loading="lazy" alt="🔒" />Login</a>
    </div>
    </header>

<div id="global">
    <main class="prompt">
    <h1>Login</h1>

    <form id="crypto-form" method="post" action="./?c=auth&amp;a=login">
        <input type="hidden" name="_csrf" value="5c737e746b72f6831a1ab716b2429b043550c8ff" />
        <input type="hidden" name="original_request" value="eyJjIjoiaW5kZXgiLCJhIjoiaW5kZXgiLCJwYXJhbXMiOnsicmlkIjoiNjZhMzY3NjEwYmZjNiJ9fQ==" />

        <div class="form-group">
            <label for="username">Username</label>
            <input type="text" id="username" name="username" autocomplete="username" size="16" required="required"
                pattern="([0-9a-zA-Z_][0-9a-zA-Z_.@-]{1,38}|[0-9a-zA-Z])" autofocus="autofocus" autocapitalize="off" />
        </div>

        <div class="form-group">
            <label for="passwordPlain">Password</label>
            <div class="stick">
                <input type="password" id="passwordPlain" required="required" />
                <button type="button" class="btn toggle-password" data-toggle="passwordPlain"><img class="icon" src="../themes/icons/key.svg" loading="lazy" alt="🔑" /></button>
            </div>
            <input type="hidden" id="challenge" name="challenge" />
            <noscript><strong>JavaScript must be enabled</strong></noscript>
        </div>

        <div class="form-group">
            <label class="checkbox" for="keep_logged_in">
                <input type="checkbox" name="keep_logged_in" id="keep_logged_in" value="1" />
                Keep me logged in <small>(90 days)</small>          </label>
        </div>

        <div class="form-group form-group-actions">
            <button id="loginButton" type="submit" class="btn btn-important" disabled="disabled">
                Login           </button>
        </div>
    </form>
</main>

<footer class="main-footer">
    <a href="./?a=about">About FreshRSS</a>
    </footer>
</div>

<div id="notification" class="notification closed">
    <span class="msg"></span>
    <a class="close" href=""><img class="icon" src="../themes/icons/close.svg" loading="lazy" alt="❌" /></a>
</div>
    </body>
</html>
Tealk commented 3 months ago

What happens when you open the link in the browser? Example: https://rss.rollenspiel.monster/api/

shalak commented 3 months ago

Same as in your example: image

Tealk commented 3 months ago

Ok for me the connection worked with the following URL my username and the API password image

Alkarex commented 3 months ago

@shalak Check your FreshRSS logs in data/users/_/log_api.txt If that does not help, try the API manually with cURL https://freshrss.github.io/FreshRSS/en/developers/06_GoogleReader_API.html#google-reader-compatible-api

shalak commented 3 months ago

Hmmm, my recent attempts were done in a wrong place (instead of adding a new FreshRSS account I was adding my FreshRSS URL as a RSS feed 🤦‍♂️)

When I add the /api/greader.php in the correct place, I get different error now: Unauthorized for CL Token: image

curl calls result in Unauthorized! responses, log mentions it as well:

root@98518836a69b:/app/www/data/users/_# tail log_api.txt
[Fri, 26 Jul 2024 13:42:17 +0200] [warning] --- GReaderAPI::unauthorized
[Fri, 26 Jul 2024 13:42:50 +0200] [warning] --- GReaderAPI::unauthorized
[Fri, 26 Jul 2024 13:43:28 +0200] [warning] --- GReaderAPI::badRequest
[Fri, 26 Jul 2024 13:43:44 +0200] [warning] --- GReaderAPI::badRequest
[Fri, 26 Jul 2024 13:44:29 +0200] [warning] --- GReaderAPI::unauthorized
[Fri, 26 Jul 2024 13:44:36 +0200] [warning] --- GReaderAPI::unauthorized
[Fri, 26 Jul 2024 13:45:03 +0200] [warning] --- GReaderAPI::unauthorized
[Fri, 26 Jul 2024 13:45:50 +0200] [warning] --- GReaderAPI::unauthorized
[Fri, 26 Jul 2024 13:46:09 +0200] [warning] --- GReaderAPI::unauthorized
[Fri, 26 Jul 2024 13:46:18 +0200] [warning] --- GReaderAPI::unauthorized

I double-checked, and I do have the Allow API access (required for mobile apps) checked (as visible in my first message of this issue).

shalak commented 3 months ago

When I open https://freshrss.mydomain.net/i/?a=logs, I see the following log:

Password API mismatch for user <username>

I'm using the correct password, it has no special characters, it's just 25 alphanumeric ones.

shalak commented 3 months ago

Ok, I'm bumb as a ton of bricks. I was trying to use the the "Authentication token" from my profile, instead of API password

Alkarex commented 3 months ago

@shalak It is a frequent mistake. The reason for a distinct password for the API is that some APIs have a much lower security standard than the main FreshRSS password.