Skip to content

feat(ui): spec billing/portal, saml/reauth and ws/ssh/session - #6924

Merged
otavio merged 1 commit into
masterfrom
feat/openapi-unspecced-routes
Aug 19, 2026
Merged

feat(ui): spec billing/portal, saml/reauth and ws/ssh/session#6924
otavio merged 1 commit into
masterfrom
feat/openapi-unspecced-routes

Conversation

@luizhf42

Copy link
Copy Markdown
Member

What

Adds OpenAPI path specs for the three routes unspeccedRoutes.ts was covering by hand (POST /api/billing/portal, GET /api/user/saml/reauth, POST /ws/ssh/session), so @hey-api/openapi-ts generates typed operations for them. The hand-written wrappers and their test are deleted; every console call site now uses the generated SDK.

Why

These routes were left out of the spec when #6919 merged the console onto a single HTTP transport. The hand-typed request/response shapes in unspeccedRoutes.ts could drift silently from the Go handlers, and /ws/ssh/session was subject to response validation with no schema to validate against.

Closes shellhub-io/team#218

Changes

  • openapi/spec/paths/: three new path files, each modeled after its nearest sibling (api@billing@subscription.yaml, api@user@saml@auth.yaml, api@auth@ssh.yaml). ws@ssh@session.yaml uses oneOf to enforce the mutual exclusion between password and fingerprint auth.
  • openapi/spec/{cloud,community,openapi}.yaml: wired the new paths into the cloud, community, and combined spec roots.
  • ui/apps/console/src/hooks/useBilling.ts: useOpenBillingPortal calls the generated createBillingPortalSession instead of getBillingPortal.
  • ui/apps/console/src/pages/SSHApproval.tsx: startSso calls the generated getSamlReauthUrl with { query, throwOnError }.
  • ui/apps/console/src/components/terminal/TerminalInstance.tsx: connect builds the body as a discriminated union (CreateWebSshSessionData["body"]) and calls the generated createWebSshSession.
  • ui/apps/console/src/api/unspeccedRoutes.ts and its test: deleted.
  • ui/apps/console/src/hooks/__tests__/useBilling.test.ts: mock target changed from the deleted module to @/client.

Testing

  • tsc -b passes — the generated union type for ws/ssh/session catches any mismatch between the spec and the console's conditional body construction.
  • 215 test files / 3102 tests green; ESLint clean.
  • The response validator already covers /api/billing/portal and /api/user/saml/reauth; /ws/ssh/session was already non-exempt in openAPIValidationSkipper and now has a schema to validate against.

Add the three missing OpenAPI path files and wire them into the
community, cloud and combined spec roots so `@hey-api/openapi-ts`
generates typed operations for each route.

Replace the hand-written wrappers in `unspeccedRoutes.ts` with the
generated SDK calls at every console call site (`useBilling`,
`SSHApproval`, `TerminalInstance`) and delete the module and its test.

Fixes: shellhub-io/team#218
@luizhf42
luizhf42 requested review from a team as code owners August 19, 2026 13:06
@github-actions

github-actions Bot commented Aug 19, 2026

Copy link
Copy Markdown

Claude finished @luizhf42's task in 6m 23s —— View job


Code Review Complete

Reviewed 12 files across code quality, security, testing, language patterns, and architecture — no new issues found. The code looks good as-is.

A few things I specifically verified that hold up well:

  • Specs match the Go handlers. ws@ssh@session.yaml, api@user@saml@reauth.yaml, and api@billing@portal.yaml faithfully mirror server/ssh/web and the cloud saml/billing routes — request/response shapes, required fields, and the jwt security scheme all line up.
  • Spec-root wiring is correct. /ws/ssh/session lives only in community-openapi.yaml + the combined openapi.yaml; cloud/enterprise inherit it via $ref: community-openapi.yaml#/paths, so it is not missing from the cloud spec. billing/portal and saml/reauth are correctly cloud-only. All $ref component targets exist.
  • The oneOf union rewire in TerminalInstance.tsx is type-safe. CreateWebSshSessionData["body"] compiles to the base object intersected with the password/fingerprint union; both ternary branches match one arm. password: session.password ?? "" and public_key: session.publicKeyLine are behavior-preserving vs. the old wrappers (password is a required string on TerminalSession; undefined optionals are dropped by JSON.stringify).
  • Test rewiring is consistent. useBilling.test.ts correctly moves to the { data: { url } } envelope and mocks @/client; the deleted unspeccedRoutes.test.ts leaves no broken or assert-nothing tests behind.
  • No security regressions. SDK calls route through the same interceptor pipeline; useBilling.ts's window.open keeps noopener,noreferrer; access control in the specs matches the handlers (BlockAPIKey on saml/reauth, JWT on all three).

If you push additional changes and want a new review, tag @shellhub-io/admin and a team member can trigger it.

@luizhf42 luizhf42 self-assigned this Aug 19, 2026
@otavio
otavio merged commit dc19967 into master Aug 19, 2026
52 of 71 checks passed
@otavio
otavio deleted the feat/openapi-unspecced-routes branch August 19, 2026 13:13
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants