Skip to content

v1.9.45 Backport#17

Merged
Esity merged 8 commits into
Optum:mainfrom
LegionIO:main
Jul 2, 2026
Merged

v1.9.45 Backport#17
Esity merged 8 commits into
Optum:mainfrom
LegionIO:main

Conversation

@Esity

@Esity Esity commented Jul 2, 2026

Copy link
Copy Markdown
Member

No description provided.

Esity added 4 commits July 1, 2026 23:55
…#213)

`connect status` reported `microsoft: not connected` after a successful
Teams/delegated login. The status check used the legacy
Legion::Auth::TokenManager, which reads secret keys
(microsoft_access_token / microsoft_token_expires_at) that the delegated
login never writes — it saves via Entra::Helpers::TokenManager
(vault/local/memory). The two stores never intersect, so status always
returned false.

- status now consults Entra::Helpers::TokenManager.token_data(:delegated)
  + expired? for the microsoft provider, mirroring the Entra delegated
  `status` command; other providers keep the legacy path.
- fix `connect microsoft` argument forwarding: previously
  ARGV.select { |a| a.start_with?('--') } dropped flag values and never
  mapped --scope to teams' --scopes. Now forwards tenant_id/client_id/scope
  explicitly from parsed options.
…tore (fixes #212)

The Teams delegated OAuth callback persisted tokens via
Entra::Helpers::TokenManager.save_token(:delegated, …) but omitted
tenant_id/client_id. TokenManager#refresh_token requires both from the
stored token data; without them, refresh falls back to settings_auth
(empty for delegated-only logins) and silently fails. The callback's
`entry` hash already carries both — now forwarded through
store_teams_token.

The original #212 500 (phantom `require` of unshipped TokenCache raising
an uncatchable LoadError) was already resolved in 1.9.43 via #229; this
completes the remaining piece of #212's suggested fix.

Bumped version to 1.9.45 and updated CHANGELOG.
fix(cli+api): connect status + Teams OAuth token store (fixes #213, #212)
@Esity Esity self-assigned this Jul 2, 2026
Esity added 4 commits July 2, 2026 00:10
GET /api/extensions/tools returned HTTP 500 with
`undefined method 'filter_tool_entries'`. The route block executes in the
Sinatra instance context, but filter_tool_entries/serialize_tool_entry are
class methods on Routes::Extensions (inside `class << self`), so bare calls
resolved against the wrong receiver and raised NoMethodError.

Call them on the explicit Routes::Extensions receiver, matching the pattern
already used by the other catalog routes (e.g. Routes::Extensions.extension_entries).

Added request specs for /api/extensions/tools (200 + extension/deferred
filters) — the route had no coverage, which is how the regression slipped in.

Bumped version to 1.9.46 and updated CHANGELOG.
…ixes #194)

/api/health returned 200 ok unconditionally, so load balancers and monitors
kept routing to instances whose transport session was broken
(session_open: false after a recovery failure).

Added Legion::API::Health which assesses transport/cache/data and returns
`degraded` + HTTP 503 when an enabled, previously-healthy subsystem has
broken. The "enabled AND previously-healthy" gate maps to
Legion::Readiness.status[c] == true: Service marks a component ready only
when its config flag is on and setup succeeded, so disabled (:skipped) and
still-booting (nil/false) subsystems never fail the check — only a subsystem
that came up and later degraded does. Live liveness reuses the same checks
as /api/stats (session.open?/lite mode, Cache.connected?, data connected).

Response now includes a per-component `components` breakdown
(enabled/healthy/detail). OpenAPI updated to document the 503 + components.

Bumped version to 1.9.47 and updated CHANGELOG.
The auth middleware's skip_path? used bare prefix matching (start_with?),
so any path sharing a prefix with an unauthenticated route bypassed auth —
e.g. /api/healthily_fake, /api/health/admin/export, /api/auth/tokens_dump
all matched /api/health or /api/auth/token (CWE-284, Improper Access
Control).

Replaced with segment-bounded matching via precompiled SKIP_PATTERNS:
each skip path matches only exactly or as a `/`-delimited sub-path. Legit
sub-paths like /api/health/live still skip; prefix-collision paths now
require auth (401).

Bumped version to 1.9.48 and updated CHANGELOG.
fix(api): extensions/tools 500, health subsystem status, auth skip-path bypass (fixes #227, #194, #209)
@Esity Esity merged commit 70319f5 into Optum:main Jul 2, 2026
14 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.

1 participant