What happens
A flex-cli login that the Build API rejects still writes the rejected key to auth.edn, overwriting whatever was there. It also prints Hello ! on stdout and exits 0, so both a human and a script read it as success.
The practical consequence: mistyping your API key logs you out. The working key that was in auth.edn is gone, replaced by the bad one, and nothing in the exit code says so.
Reproduction, no credentials needed
The stub ignores the key it is sent and answers 401 the way the Build API does.
// login-401.mjs
import http from 'node:http';
const body = '["^ ","~:errors",[["^ ","~:status",401,"~:code","~:access-denied","~:title","Access denied"]]]';
http.createServer((req, res) => {
res.writeHead(401, { 'Content-Type': 'application/transit+json;charset=UTF-8' });
res.end(body);
}).listen(18714, '127.0.0.1');
node login-401.mjs &
export XDG_CONFIG_HOME=$(mktemp -d)
mkdir -p "$XDG_CONFIG_HOME/flex-cli"
echo '{:api-key "PRE-EXISTING-GOOD-KEY"}' > "$XDG_CONFIG_HOME/flex-cli/auth.edn"
echo 'wrong-key-typed-by-mistake' | \
FLEX_API_BASE_URL=http://127.0.0.1:18714/v1/build-api flex-cli login
echo "exit=$?"
cat "$XDG_CONFIG_HOME/flex-cli/auth.edn"
Observed with flex-cli 1.17.1 from npm:
› Error: Access denied
›
› Failed to verify API key ending with ...take
›
› Check your API key and use flex-cli login to relogin.
Hello !
exit=0
{:api-key "wrong-key-typed-by-mistake"}
The error page is correct and helpful. Everything after it should not have run.
Why
login in src/sharetribe/flex_cli/commands/login.cljs reads the admin, then stores, then greets:
{:keys [data]} (<? (do-get api-client "/current_admin/show" nil))]
(credential-store/set-api-key api-key)
(io-util/ppd [:span "Hello " (:admin/email data) "!"])
The intent is clearly to store only after the call succeeds. In practice the failed <? does not stop the body, so set-api-key runs with the rejected key and ppd runs with data nil, which is where the empty Hello ! comes from.
This is the same shape as #125, where a failed do-get in pull-assets does not stop print-progress! from running on a null stream. Whatever fixes the propagation in one probably fixes both, so they may be worth looking at together.
Suggested fix
Make the failure stop the rest of login, so the store and the greeting are only reached on success. Exiting non-zero on a rejected key matters too, since a script cannot currently tell a successful login from a failed one.
What happens
A
flex-cli loginthat the Build API rejects still writes the rejected key toauth.edn, overwriting whatever was there. It also printsHello !on stdout and exits 0, so both a human and a script read it as success.The practical consequence: mistyping your API key logs you out. The working key that was in
auth.ednis gone, replaced by the bad one, and nothing in the exit code says so.Reproduction, no credentials needed
The stub ignores the key it is sent and answers 401 the way the Build API does.
Observed with flex-cli 1.17.1 from npm:
The error page is correct and helpful. Everything after it should not have run.
Why
logininsrc/sharetribe/flex_cli/commands/login.cljsreads the admin, then stores, then greets:{:keys [data]} (<? (do-get api-client "/current_admin/show" nil))] (credential-store/set-api-key api-key) (io-util/ppd [:span "Hello " (:admin/email data) "!"])The intent is clearly to store only after the call succeeds. In practice the failed
<?does not stop the body, soset-api-keyruns with the rejected key andppdruns withdatanil, which is where the emptyHello !comes from.This is the same shape as #125, where a failed
do-getinpull-assetsdoes not stopprint-progress!from running on a null stream. Whatever fixes the propagation in one probably fixes both, so they may be worth looking at together.Suggested fix
Make the failure stop the rest of
login, so the store and the greeting are only reached on success. Exiting non-zero on a rejected key matters too, since a script cannot currently tell a successful login from a failed one.