d31dfeae270d0499615ff8bacbad5188f27ae8dc
A self-hosted Gitea answers 401 to `Authorization: token <password>` and 200 to the same value as `user:password`, and the account store's `secret_kind` cannot tell the two apart — it is a label the human typed at `identity_save`, so a login password saved as a token is indistinguishable from a real PAT until the forge answers. `GiteaForge` had one auth path: the token header, on every call. A watch whose credential resolved to a password therefore 401'd on every poll, forever, while the same secret worked for `git push` over https (the credential helper sends it as a password). The watch looked quiet instead of broken. `GiteaForge::with_login` names the login that owns the secret, and `send` tries the token header first, then — on a 401 only — the same value as Basic auth. The retry is cloned before the token header lands, so the fallback request carries one `Authorization` header and not two. No login (a pasted watch token names none) or an unclonable body leaves the 401 to surface exactly as it did before. The login reaches the client in the next commit; this one is the adapter half, tested against a mock that refuses the token header and accepts the Basic one.
Languages
Rust
74.9%
Kotlin
13.8%
Vue
7.1%
TypeScript
3%
Dockerfile
0.5%
Other
0.6%