Skip to content

feat: add login --manual to sign in without a password prompt - #2

Merged
trevin-lee merged 2 commits into
trevin-lee:mainfrom
ynezz:pr/manual-login
Oct 10, 2026
Merged

trevin-lee merged 2 commits into
trevin-lee:mainfrom
ynezz:pr/manual-login

Conversation

@ynezz

@ynezz ynezz commented Oct 8, 2026

Copy link
Copy Markdown
Contributor

hi, my clankers found this nice project during research, I liked it so decided to make you aware about the changes I've made for my use cases, so everyone can profit from that, but feel free to close it or implement it differently, happy to help with testing, cheers, Petr


prusactl login asks for the Prusa Account password on the terminal. An AI agent that drives prusactl cannot answer this prompt, and it must not see the password.

login --manual prints the Prusa Account authorize link on its own line. It opens a browser unless --no-open is given. Then it reads one line from stdin: the address that the browser shows after approval, or only its code= value. prusactl compares the state in this address with the state in the link. It exchanges the code for tokens with the same PKCE flow as the password login.

There is no loopback (127.0.0.1) variant. Prusa Account rejects this redirect for the Connect client with "Mismatching redirect URI". The code must come from the address bar.

If --manual is not given and there is no terminal, login now suggests --manual. Before, it failed at the password prompt.

Testing

  • Unit tests with a mocked authorize and token server: a pasted address, a pasted query, a bare code, and a state mismatch.
  • Live sign-in against the real Prusa Account. The session was saved, and later Connect calls worked with it.

@trevin-lee

Copy link
Copy Markdown
Owner

The mechanics check out: PKCE, the state check against the pasted URL, and ask() reading from a non-tty so an agent can drive it. Opening the system browser is the right default here, and --no-open covers headless.

I'm pushing three small things:

  • README line 28 says "no browser involved", which is no longer true. Changing it to "no browser needed", since the password login still works without one.
  • The prompt says "on one line of stdin". That's right for an agent and jargon for a person. Changing it to "paste it here and press Enter".
  • A README note that this depends on Connect's auth-callback page not redeeming a code whose state it didn't issue. It worked for you, so that's how the page behaves today, but Prusa could change it and the failure would be confusing without the note.

ynezz and others added 2 commits October 10, 2026 01:13
…tdin

`prusactl login` asks for the Prusa Account password on the terminal. An
AI agent cannot answer this prompt, and it must not receive the
password.

`login --manual` prints the Prusa Account authorize link on its own
line. It opens a browser unless `--no-open` is given. Then it reads one
line from stdin: the address that the browser shows after approval, or
only its `code=` value. It compares the state in this address with the
state in the link. It exchanges the code for tokens with the same PKCE
flow as the password login.

There is no loopback variant. Prusa Account rejects a `127.0.0.1`
redirect for the Connect client ("Mismatching redirect URI"). The code
must come from the address bar.

If `--manual` is not given and there is no terminal, `login` now tells
the user to use `--manual`. Before, it failed at the password prompt.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Signed-off-by: Petr Štetiar <ynezz@true.cz>
…he prompt

The README said "no browser involved", which stopped being true the
moment --manual opened one. No browser is needed; the password login
still works without one.

--manual depends on something the README didn't say: Connect's own
auth-callback page leaves a code alone when it carries a state the page
didn't issue. That is how the page behaves today and nothing promises it
will tomorrow, so the note says what breaks if it changes.

The prompt said "on one line of stdin", which is the right description
for an agent and jargon for a person. It says "paste it here and press
Enter" now; the help text keeps the precise version.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
@trevin-lee
trevin-lee merged commit ffcb25f into trevin-lee:main Oct 10, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants