Skip to content

feat(jira): thread authType through discovery + verification endpoints#1490

Merged
aaight merged 1 commit into
devfrom
feature/mng-1743-jira-authtype-discovery-verification
Jul 10, 2026
Merged

feat(jira): thread authType through discovery + verification endpoints#1490
aaight merged 1 commit into
devfrom
feature/mng-1743-jira-authtype-discovery-verification

Conversation

@aaight

@aaight aaight commented Jul 10, 2026

Copy link
Copy Markdown
Collaborator

Summary

Threads the JIRA authType connection setting through the discovery + verification endpoints so wizard-time verification (currentUser / projects / states / customFields) and edit-mode re-verification hit the correct host — the classic site URL for basic, the Atlassian gateway for scoped. Backend-only; the wizard UI selector is a separate story.

Builds on MNG-1736 (the optional authType config/credential field) and MNG-1738 (JIRA API client host routing via resolveJiraApiBaseUrl). Both are merged; this story closes the last gap so a saved authType: 'scoped' actually reaches withJiraCredentials on the discovery/verification paths.

Backend keeps HTTP Basic (email:api_token) for both modes — authType selects the host, not the auth scheme (per MNG-1735 research; no Bearer/OAuth behavior is introduced).

Linear issue: https://linear.app/issue/MNG-1743

Changes

src/integrations/pm/jira/manifest.ts

  • Added a coerceJiraAuthType(unknown) helper that narrows a raw value to the JiraAuthType ('basic' | 'scoped') union — unknown/absent → undefined, which downstream treats as basic. Keeps garbage values from ever selecting the scoped gateway host.
  • createDiscoveryProvider now reads creds.auth_type and threads authType into withJiraCredentials(...), so discovery (projects / states / customFields / currentUser) routes through the correct host.
  • createCustomField now threads credentials.auth_type into withJiraCredentials(...).
  • configToCredentials now promotes config.authType → auth_type alongside the existing baseUrl → base_url, so the projectId (edit-mode) path of pm.discovery.* picks up the saved auth mode. Promotion is additive and independent — auth_type is emitted even when baseUrl is absent, and skipped for unrecognized values.

src/api/routers/integrationsDiscovery.ts

  • Extended jiraCredsInput with authType: z.enum(['basic','scoped']).optional().
  • withJiraCreds (raw-creds path used by jiraProjectDetails) now forwards authType into the credentials bag → withJiraCredentials.
  • jiraProjectDetailsByProject (stored-creds path) now resolves authType from the saved project_integrations.config (mirroring how baseUrl is read) and threads it into withJiraCredentials. Unknown/absent values resolve to undefined.

Tests

  • manifest-config-to-credentials.test.ts — new block asserting authType promotion to auth_type (scoped/basic, baseUrl-absent case, backward-compat when absent, and rejection of unknown/invalid values).
  • manifest-discovery.test.ts — new block asserting createDiscoveryProvider forwards auth_type into withJiraCredentials (scoped, basic, undefined-when-absent, undefined-for-unrecognized).
  • manifest-mutations.test.ts — new assertions that createCustomField threads auth_type and passes undefined when absent.
  • integrationsDiscovery.test.ts — converted the JIRA withJiraCredentials mock to a capturable vi.fn(); new assertions that both the raw-creds (jiraProjectDetails) and stored-creds (jiraProjectDetailsByProject) paths thread authType, that absent/unrecognized config values resolve to undefined, and that the input schema rejects an invalid enum value.
  • authType round-trip through jiraConfigSchema is already covered by the existing MNG-1736 suite (manifest-config-schema.test.ts); those stay green.
  • Conformance harness (pm-conformance.test.ts) stays green (100 tests).

Verification

  • npm run typecheck — clean
  • biome check on changed/new files — clean
  • Unit suites: unit-core PM + integrations (1097 passed / 23 skipped), unit-api (794 passed), plus targeted JIRA/discovery/conformance runs — all green.

Out of scope

  • The wizard UI authType selector (separate frontend story).

🤖 Generated with Claude Code

🕵️ claude-code · claude-opus-4-8 · run details

@codecov

codecov Bot commented Jul 10, 2026

Copy link
Copy Markdown

Codecov Report

✅ All modified and coverable lines are covered by tests.

📢 Thoughts on this report? Let us know!

@nhopeatall nhopeatall left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Summary

APPROVE — Correct, type-safe, and comprehensively tested. The PR threads JIRA authType through exactly the discovery + verification surfaces the work item (MNG-1743) scopes, mirroring the established baseUrl → base_url promotion pattern, with no regression to the historical basic default.

Verification

Traced the full flow and confirmed all five acceptance criteria:

  • coerceJiraAuthType narrows 'basic' | 'scoped' and collapses everything else ('', 123, null, 'bearer') to undefined → downstream resolveJiraApiBaseUrl treats it as basic. Garbage can never select the scoped gateway host.
  • createDiscoveryProvider (manifest.ts:232) and createCustomField (manifest.ts:121) both thread the coerced authType into withJiraCredentials, so currentUser / projects / states / customFields route through the correct host.
  • configToCredentials (manifest.ts:166) promotes authType → auth_type additively — emitted even when baseUrl is absent, skipped for unrecognized values. The refactor from the early return {} to the accumulating promoted object is behavior-preserving for the existing base_url case.
  • integrationsDiscovery.tsjiraCredsInput gains the optional enum (rejects unknown values at the Zod boundary); both the raw-creds (jiraProjectDetails) and stored-creds (jiraProjectDetailsByProject, resolved from project_integrations.config) paths forward it.
  • Type safety holds: JiraCredentials.authType?: JiraAuthType is consumed by resolveJiraApiBaseUrl; the pm.discovery.discover projectId path picks up the promoted auth_type via promoteConfigCredentials.

Ran the touched suites locally: manifest-config-to-credentials / manifest-discovery / manifest-mutations (28) + integrationsDiscovery (53) all green; CI 7/7.

Notes (non-blocking)

  • Runtime webhook-dispatch path is not threaded (out of scope, pre-existing). src/router/adapters/jira.ts:130 still builds { email, apiToken, baseUrl } without authType when establishing credential scope for trigger dispatch (and the Sentry adapter's JIRA branch does the same). The in-worker paths (integration.ts:71, cli/base.ts:63) and now the discovery/verification paths all thread it — only webhook-triggered dispatch does not. That means a scoped-auth JIRA project's trigger-time API calls would route to the site host rather than the gateway. This is genuinely separate from MNG-1743's discovery+verification scope and isn't a regression from this PR, but worth confirming it's tracked as a follow-up rather than an oversight.
  • Minor duplication: jiraProjectDetailsByProject re-inlines the authType narrowing (rawAuthType === 'basic' || rawAuthType === 'scoped' ? ... : undefined) that coerceJiraAuthType already encapsulates. Since the helper isn't exported from manifest.ts, the inline copy is understandable; if a shared home emerges (e.g. beside JiraAuthType in config-schema.ts), consolidating would remove the third copy of this predicate.

🕵️ claude-code · claude-opus-4-8 · run details

@aaight aaight merged commit eb14b90 into dev Jul 10, 2026
9 checks passed
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.

2 participants