feat(auth): add OAuth device-code login (Global / CN) into config.json#139
Merged
Conversation
added 4 commits
May 12, 2026 19:02
Adds an end-to-end OAuth 2.0 Device Authorization Grant flow against the
MiniMax account servers (account.minimax.io / account.minimaxi.com),
selectable via a single first-run menu:
▸ MiniMax · OAuth login (Global)
MiniMaxCN · OAuth login (China)
API key · Paste sk-cp-... or sk-...
Tokens are persisted into ~/.mmx/config.json under an 'oauth' subobject —
no separate credentials.json file, so logout clears one place and users
have a single file to back up.
Highlights:
* Single 3-option menu (no two-step method-then-region prompt)
* Browser opened via execFile/spawn (shell-injection safe, #79)
* Refresh derives the OAuth host from the saved region — no
Config.oauthApiHost field is added, so existing test fixtures
are unaffected (zero churn)
* Honest field naming: expires_at (ISO 8601) at the boundary;
no internal env-var leakage (BEDROCK_LANE / X-User-Pre etc.)
Net diff: 15 files, -27 lines (browser-callback dead code removed).
- Both OAuth options labelled 'MiniMax', region in parens - After any login (OAuth or API key), print the same dashboard as bare 'mmx' (help panel + quota table) so the user lands on a useful view instead of returning to a blank shell prompt
…, region detection
- Menu labels show the API endpoint:
MiniMax (OAuth login → api.minimax.io)
MiniMax (OAuth login → api.minimaxi.com)
API key
- config.json now stores oauth XOR api_key:
OAuth login clears any existing api_key
API-key login clears any existing oauth subobject
- Status bar shows the API URL instead of the region label:
MINIMAX ~/.mmx/config.json | URL: api.minimaxi.com | Key: oat-...vBBY
- API-key login auto-detects the region by probing both Global and CN
(uses existing detectRegion helper); detected region is persisted.
- New --recommend flag jumps straight to OAuth, skipping the 3-option
menu. Combine with --region=global|cn to skip the region picker too:
mmx auth login --recommend
mmx auth login --recommend --region=global
mmx auth login --recommend --region=cn
…o region) - Quick Start prefers interactive 'mmx auth login' (with --api-key as the non-interactive variant) - Auth section documents the 3-option menu, --recommend / --recommend --region=global|cn, and the api_key XOR oauth invariant in config.json - Mention API-key auto-region detection - Drop the now-stale reference to ~/.mmx/credentials.json
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
End-to-end OAuth 2.0 Device Authorization Grant against the MiniMax account servers (
account.minimax.io/account.minimaxi.com), wired intommx auth loginvia a single first-run menu:Tokens are persisted into
~/.mmx/config.jsonunder anoauthsubobject. No separatecredentials.jsonfile — logout clears one place and users have a single file to back up.This is an alternative to #134, written from scratch on top of
mainso it doesn't inherit any of the rough edges from that branch.Highlights
execFile/spawn, neverexec()with template-string interpolation of the auth-server URL (preserves the Bugs/improvements/security issues #79 fix)Config.oauthApiHostfield — the OAuth host is derived from the region stored in the saved credentials. No required Config field means zero test-fixture churn.expires_at(ISO 8601) at every API boundary; the badly-named server fieldexpired_in(which is actually a Unix-ms timestamp) is converted on the spot insideoauth.ts/refresh.tsand never leaks.BEDROCK_LANE/X-User-Preenv-var sprinkles — those are internal/staging concerns that don't belong in the public CLI.Diff
15 files, -27 lines net (
+371 / -398).~/.mmx/config.jsonschema{ "api_key": "sk-cp-...", // optional, as before "region": "global", "oauth": { // new — was a separate credentials.json "access_token": "...", "refresh_token": "...", "expires_at": "2026-05-15T12:34:56Z", "region": "global", // OAuth host this token came from "resource_url": "https://api.minimax.io" }, "base_url": "...", "output": "text" }Test plan
bun run typecheckcleanbun test212 / 212 passbun run lintcleanbun run buildproducesdist/mmx.mjs(137 KB)mmx auth login(CN region) — interactive OAuth completes, tokens land in~/.mmx/config.jsonoauthsubobjectmmx auth status— reads back: Methodoauth, Sourceconfig.jsonmmx auth logout— clearsoauthfromconfig.json(api_key untouched if present)Relationship to #134
Same goal, independent implementation. Reviewers can pick whichever they prefer; this branch is rebased cleanly on
mainand intentionally avoids the issues called out in #134's review (separate JSON file, required Config field, exec() shell-injection regression, internal env-var leakage, mismatched field naming).