Skip to content

Commit 3e3cdb7

Browse files
betegonclaude
andcommitted
feat(auth): enforce auth by default in buildCommand (#611)
## Summary All commands now require authentication by default. `buildCommand` checks `isAuthenticated()` before invoking the command function and throws `AuthError("not_authenticated")` if no token exists — this feeds into the existing auto-auth middleware that prompts login and retries. Previously each command had to manually guard auth or rely on an API call failing deep in execution. `sentry init` in particular had no auth check at all and would proceed into the wizard flow before eventually failing. ## Changes Added `auth?: boolean` to `buildCommand` options (defaults `true`). The check runs before the generator, so the auto-auth middleware in `cli.ts` catches it and kicks off the interactive login flow on unauthenticated runs. Commands that intentionally work without a token opt out with `auth: false`: - `auth login`, `auth logout`, `auth refresh`, `auth status` - `help`, `schema` - `cli fix`, `cli setup`, `cli upgrade`, `cli feedback` With this in place, the redundant explicit `isAuthenticated()` checks in `auth whoami` and `auth token` were removed. ## Test Plan - `sentry init` (unauthenticated) → should immediately prompt "Authentication required. Starting login flow..." - `sentry auth login` (unauthenticated) → should work normally - `sentry auth status` (unauthenticated) → should show "not authenticated" cleanly, no login prompt - `sentry auth logout` (unauthenticated) → should return "Not currently authenticated." - `SENTRY_AUTH_TOKEN=xxx sentry init` → no auth prompt, proceeds normally --------- Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com>
1 parent 3047930 commit 3e3cdb7

14 files changed

Lines changed: 40 additions & 8 deletions

File tree

src/commands/auth/login.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -107,6 +107,7 @@ async function handleExistingAuth(force: boolean): Promise<boolean> {
107107
}
108108

109109
export const loginCommand = buildCommand({
110+
auth: false,
110111
docs: {
111112
brief: "Authenticate with Sentry",
112113
fullDescription:

src/commands/auth/logout.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@ export type LogoutResult = {
2828
};
2929

3030
export const logoutCommand = buildCommand({
31+
auth: false,
3132
docs: {
3233
brief: "Log out of Sentry",
3334
fullDescription:

src/commands/auth/refresh.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,7 @@ function formatRefreshResult(data: RefreshOutput): string {
3939
}
4040

4141
export const refreshCommand = buildCommand({
42+
auth: false,
4243
docs: {
4344
brief: "Refresh your authentication token",
4445
fullDescription: `

src/commands/auth/status.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -138,6 +138,7 @@ async function verifyCredentials(): Promise<AuthStatusData["verification"]> {
138138
}
139139

140140
export const statusCommand = buildCommand({
141+
auth: false,
141142
docs: {
142143
brief: "View authentication status",
143144
fullDescription:

src/commands/auth/token.ts

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,6 @@ export const tokenCommand = buildCommand({
2727
if (!token) {
2828
throw new AuthError("not_authenticated");
2929
}
30-
3130
return yield new CommandOutput(token);
3231
},
3332
});

src/commands/auth/whoami.ts

Lines changed: 0 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -9,9 +9,7 @@
99
import type { SentryContext } from "../../context.js";
1010
import { getCurrentUser } from "../../lib/api-client.js";
1111
import { buildCommand } from "../../lib/command.js";
12-
import { isAuthenticated } from "../../lib/db/auth.js";
1312
import { setUserInfo } from "../../lib/db/user.js";
14-
import { AuthError } from "../../lib/errors.js";
1513
import { formatUserIdentity } from "../../lib/formatters/index.js";
1614
import { CommandOutput } from "../../lib/formatters/output.js";
1715
import {
@@ -46,10 +44,6 @@ export const whoamiCommand = buildCommand({
4644
async *func(this: SentryContext, flags: WhoamiFlags) {
4745
applyFreshFlag(flags);
4846

49-
if (!isAuthenticated()) {
50-
throw new AuthError("not_authenticated");
51-
}
52-
5347
const user = await getCurrentUser();
5448

5549
// Keep cached user info up to date. Non-fatal: display must succeed even

src/commands/cli/feedback.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@ export type FeedbackResult = {
2525
};
2626

2727
export const feedbackCommand = buildCommand({
28+
auth: false,
2829
docs: {
2930
brief: "Send feedback about the CLI",
3031
fullDescription:

src/commands/cli/fix.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -650,6 +650,7 @@ function safeHandleSchemaIssues(
650650
}
651651

652652
export const fixCommand = buildCommand({
653+
auth: false,
653654
docs: {
654655
brief: "Diagnose and repair CLI database issues",
655656
fullDescription:

src/commands/cli/setup.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -428,6 +428,7 @@ async function runConfigurationSteps(opts: ConfigStepOptions) {
428428
}
429429

430430
export const setupCommand = buildCommand({
431+
auth: false,
431432
docs: {
432433
brief: "Configure shell integration",
433434
fullDescription:

src/commands/cli/upgrade.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -643,6 +643,7 @@ async function buildCheckResultWithChangelog(opts: {
643643
}
644644

645645
export const upgradeCommand = buildCommand({
646+
auth: false,
646647
docs: {
647648
brief: "Update the Sentry CLI to the latest version",
648649
fullDescription:

0 commit comments

Comments
 (0)