wallabag / wallabag/wallabagger
Access token is never persisted — `POST /oauth/v2/token` fires on every background-page wake-up
- Dominant language
- JavaScript
- Stars
- 471
- Forks
- 71
- Avg merge
- 4d 17h
- Merged PRs (30d)
- 4
Description
# Access token is never persisted — `POST /oauth/v2/token` fires on every background-page wake-up
Wallabagger 1.23.1, Firefox 149.0.2 on Linux and macOS, self-hosted `wallabag/wallabag` Docker instance.
This is **not** about the broader auth-flow / credential-storage concern already discussed in #151 — that's waiting on upstream `wallabag/wallabag#2800` and is out of scope here. The narrow issue below is purely about how often the current flow re-runs, and is independent of whatever flow eventually replaces it.
## What happens
Leaving Firefox running, totally idle, I watched my Wallabag access log and saw this pattern roughly every ~30 seconds, forever:
```
20:36:41.552 POST /oauth/v2/token HTTP/1.1 200
20:36:41.643 GET /api/tags.json HTTP/1.1 200
20:37:12.545 POST /oauth/v2/token HTTP/1.1 200
20:37:12.638 GET /api/tags.json HTTP/1.1 200
20:37:44.026 POST /oauth/v2/token HTTP/1.1 200
20:37:44.133 GET /api/tags.json HTTP/1.1 200
```
Each `POST /oauth/v2/token` is a fresh `grant_type=password` login — even though the access token returned a few seconds earlier is still well within its `expires_in` window. On an always-on machine this works out to ~2,880 token requests per day per browser profile, all of them unnecessary.
This happens regardless of the "Indicate if page already saved" (`AllowExistCheck`) option, because `boot()` at `wallabagger/js/background.js:193` calls `await api.getTags()` unconditionally on every event-page start.
## Why
`#getAppToken` in `wallabagger/js/wallabag-api.js:259-276` updates `this.data.ApiToken`, `RefreshToken`, and `ExpireDate` in memory and returns — but never writes them back to `browser.storage.local`. A grep for `browser.storage.local.set` in that file returns only `saveParams()` on line 107, which is invoked only when the user interacts with the options page. So when Firefox suspends the non-persistent MV3 background page (default ~30 s idle) the in-memory token evaporates; on the next wake-up, `api.init()` → `#load()` reads storage, finds `ApiToken: null` (the default from `defaultValues` — it was never saved), and `#checkToken()` fires another `passwordToken()`.
## Suggested fix (1 line)
In `#getAppToken`, after the in-memory mutations, persist `this.data`:
```js
this.data.ApiToken = data.access_token;
this.data.RefreshToken = data.refresh_token;
this.data.ExpireDate = Date.now() + data.expires_in * 1000;
this.data.isTokenExpired = this.#isTokenExpired();
await browser.storage.local.set({ wallabagdata: this.data }); // ← this line
return data;
```
(Also make `#getAppToken` `async`, or chain the set inside the existing `.then`.)
With this change, a refreshed token survives background-page suspends and gets reused until `ExpireDate` is actually past — one refresh per `expires_in` interval (3600 s by default) instead of one per ~30 s wake-up. ~100× reduction in the OAuth traffic without touching anything in the auth-flow design debate from #151.
One side note worth knowing: `PRIVACY.md` in this repo currently states
> … refresh token, which is used for refreshing access token after it is expired … After the refresh token expires itself, the stored credentials are used for obtaining a new one.
The refresh token *is* stored into `this.data.RefreshToken` by `#getAppToken`, but no code path ever reads it back — every token refresh goes through the password grant. Once #2800 upstream settles and this repo picks up a proper flow, PRIVACY.md will become accurate again; in the meantime the persistence fix above at least stops the noise.
Happy to send a PR for the one-liner if it's helpful.
Contributor guide
No contributing guide indexed for this repository
Research direction
Start with wallabagger/js/wallabag-api.js at #getAppToken and wallabagger/js/background.js:193, where boot() calls api.getTags() on each event-page start. Check how api.init() and #load() restore wallabagdata, then verify that the updated token fields are persisted and reused after background-page wake-ups. Done means repeated wake-ups no longer issue password-grant requests while the token remains within its expires_in window.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- javascript
- Domain
- frontend
- Issue type
- Bug
- Difficulty
- 2/5
- Estimated time
- 1-3 hours
- Activity status
- Quiet
- Clarity
- Clearly specified
- Newbie friendliness
- 82/100