Skip to content

feat(jira): tell how to replace a token that Jira refuses - #44

Merged
Bakhomious merged 1 commit into
mainfrom
step/jira-login
Nov 4, 2026
Merged

Bakhomious merged 1 commit into
mainfrom
step/jira-login

Conversation

@Bakhomious

Copy link
Copy Markdown
Contributor

When Jira refuses the login, baton jira now names the email and gives the command that replaces the token. A scoped token expires within a year (fact 42), so every user will hit this. This is plan row jira-login, a follow-up to #43.

What

  • Client: jira.LoginError marks a 401 Unauthorized to the gateway's logged-in requests (the issue and its comments). Jira's API gives 401 when the credentials are "incorrect or missing" (the OpenAPI spec of fact 40). The error's text is unchanged. The site's 401, to the cloud-ID request that carries no login, stays unmarked, since no token caused it.

  • baton jira: for a LoginError, it prints:

    baton jira: the Jira login as me@example.com failed (read DEMO-1: 401 Unauthorized: …): check that email, and if the token has expired or lacks the scope read:jira-work, make a new one and replace it with `security add-generic-password -U -s baton-jira -a 'me@example.com' -w`, which asks for it
    

    Jira's answer sits in parentheses, since the gateway's own text can hold a semicolon or a colon. The email in the command is quoted for the shell.

  • Docs:

    • README: the Jira section says that baton jira gives the -U command.
    • Plan: row 66 is Done (feat(jira): baton jira prints a ticket for the orchestrator #43), and the new row is jira-login. Decision 60 covers the 401.
    • Fact 41: the user chose to skip a live check of Jira (2026-11-04), so whether a site's tenant_info answers without a login stays unchecked. A site that wants a login fails with read the cloud ID of <site>: and the site's answer.

Checks

  • mise run check: green; coverage 99.5% in total.
  • Mutation probes: all 14 mutants caught: 6 in the client (any request, !login, 403, any status, never, unmarked) and 4 in the cli, run against both wordings. A %w → %v in the cli hint would survive: nothing unwraps that error; it only gets printed.
  • Smoke run: a throwaway program (deleted) ran cli.Run, wired as main.go is, against a local fake Jira, with a temp HOME and config and no tmux. The real binary can't reach a 401 without a real Jira. Results:
    • The gateway's 401 gave the message above, with 'o'\''nobody@example.com' quoted.
    • The site's 401 gave read the cloud ID of example.atlassian.net: 401 Unauthorized: … with no hint.
    • A bad key was still refused first.
  • No live run and no real Jira call: 0 credits. The user skipped the live check.

Jira's API answers 401 Unauthorized when the credentials are incorrect
or missing, as they are once a token expires, which a scoped token does
within a year. baton jira now names the email that Jira refused and gives
the command that replaces the token in the keychain, `security
add-generic-password -U`, with the email quoted for the shell.

The client marks a 401 to the gateway's logged-in requests as a
LoginError. The site's 401, to the cloud ID's request without the
login, stays unmarked, since no token caused it.

The user chose to skip a live check of Jira, so fact 41 now says that
whether tenant_info answers without a login stays unchecked. Plan row 66
is done.
@sonarqubecloud

sonarqubecloud Bot commented Nov 4, 2026

Copy link
Copy Markdown

@Bakhomious
Bakhomious merged commit a5a4900 into main Nov 4, 2026
3 checks passed
@Bakhomious
Bakhomious deleted the step/jira-login branch November 4, 2026 21:21
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