Skip to content

✨ feat(login): use session login by default, move OAuth behind --oauth - #3

Merged
kud merged 1 commit into
mainfrom
feat/session-login-default
Jul 31, 2026
Merged

kud merged 1 commit into
mainfrom
feat/session-login-default

Conversation

@kud

@kud kud commented Jul 31, 2026

Copy link
Copy Markdown
Owner

Why

pcloud login failed out of the box, for the CLI's own author:

$ pcloud login

🔐 Welcome to pCloud CLI Setup!

You will be redirected to pCloud in your browser to log in.
After logging in, you'll be redirected back automatically.

❌ Missing credentials. Export PCLOUD_CLIENT_ID and PCLOUD_CLIENT_SECRET…

Three problems in one screen:

  1. It promises a browser redirect and then discovers it has nothing to
    redirect with. The credential check sat below the banner.
  2. The error names only the harder path. It never mentions --session, which
    needs no setup at all.
  3. docs/authentication.mdx documented only the OAuth flow, including a
    "Create an OAuth application" section. --session appeared nowhere.

So the documented, default route required registering an OAuth application, while
the route that required nothing was invisible.

The default was inverted

Comparing the two tiers:

session OAuth
Setup none register an OAuth application
Password handled by CLI yes, once never
Revisions, trash, zip, downloads ✅ ❌ not reachable

The default demanded more setup and delivered less capability. This is not a
new opinion in the codebase — resolveStoredAuth already prefers a stored session
token over an access token, commented "the session token is the strictly more
capable tier", and TRASH_OAUTH_WARNING already states OAuth cannot reach trash
at all.

What changed

pcloud login              → email + password (session)
pcloud login --oauth      → browser flow (needs CLIENT_ID + SECRET)
pcloud login --session    → accepted and ignored; same as bare `login`

--session is kept as a no-op so existing muscle memory and any scripted use
keep working. Passing --oauth and --session together is refused rather than
silently resolved — they ask for different things, so picking one for the user
would be a guess.

The OAuth credential check now runs before the banner, and its error offers
the way out:

❌ OAuth needs PCLOUD_CLIENT_ID and PCLOUD_CLIENT_SECRET.

Register an application at
  https://docs.pcloud.com/methods/oauth_2.0/
then export both in your shell or a .env file.

Or just run `pcloud login` — it needs no setup at all, and
reaches revisions, trash, zip and downloads that OAuth cannot.

Session login points back the other way too, so neither flow is a dead end.

Docs

docs/authentication.mdx rewritten to lead with session login and present OAuth
as the deliberate alternative, opening with a comparison table so the choice is
made knowingly rather than by default.

docs/index.mdx had drifted and is corrected alongside: it claimed Node 20
(0.7.0 raised the floor to 24), described authentication as OAuth-only, and never
mentioned the sync commands shipped in 0.7.0. The configuration table now marks
the client variables as --oauth-only and documents PCLOUD_AUTH.

Breaking-ish

Anyone with PCLOUD_CLIENT_ID + PCLOUD_CLIENT_SECRET exported who runs bare
pcloud login will now get a password prompt instead of a browser. Their fix is
one flag, --oauth, and existing stored tokens are untouched — nobody is logged
out by this. Auto-detecting on the presence of those variables was considered and
rejected: the same command behaving differently depending on environment is
harder to document and harder to predict than an explicit flag.

Testing

Six new tests in src/login.test.ts, spawning the CLI with the client variables
stripped. Verified in both directions — each invariant was re-run against
deliberately reverted code, and each experiment failed exactly one test:

Reverted Test that failed
default routing back to OAuth goes to session login, not OAuth
banner moved back above the check does not promise a browser it cannot open

That second column is the point. The assertion worth making is not "the error
appears" — the error always appeared — but "the contradicting promise does not".

npm run typecheck clean, full suite 26 passing.

…h flag

Session login (email + password) is now the default authentication flow,
with browser-based OAuth moved behind the --oauth flag. This prioritises
the simpler, more reliable credential-based authentication for typical use.
@kud
kud marked this pull request as ready for review July 31, 2026 15:05
@kud
kud merged commit c959ade into main Jul 31, 2026
1 check passed
@kud
kud deleted the feat/session-login-default branch July 31, 2026 15:05
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.

1 participant