Skip to content

Fix remaining security scan regressions#349

Merged
bdamokos merged 2 commits into
mainfrom
codex/security-findings-2026-05-21
May 21, 2026
Merged

Fix remaining security scan regressions#349
bdamokos merged 2 commits into
mainfrom
codex/security-findings-2026-05-21

Conversation

@bdamokos

@bdamokos bdamokos commented May 21, 2026

Copy link
Copy Markdown
Owner

Summary

  • harden OSRM proxy forwarded-host fallback with a trusted proxy secret
  • avoid caching empty weather lookup failures
  • validate YNAB import dates and preserve instance-keyed duplicate imports
  • normalize null route point updates and clear stale expense-link UI state

Verification

  • bun run test:unit -- src/app/tests/api/osrm-routing-validation.test.ts src/app/tests/unit/weatherService.test.ts src/app/tests/api/travel-data-auth-cache.test.ts src/app/tests/unit/MultiRouteLinkManager.test.tsx src/app/tests/unit/TravelItemSelector.loadFailure.test.tsx --modulePathIgnorePatterns="/.worktrees" --modulePathIgnorePatterns="/.next"
  • JEST_INTEGRATION_TESTS=true bun run test:integration -- src/app/tests/integration/cost-tracking-validation.integration.test.ts --modulePathIgnorePatterns="/.worktrees" --modulePathIgnorePatterns="/.next"
  • bun run lint
  • bun run build

Summary by CodeRabbit

  • New Features

    • Added proxy secret header validation for admin routing requests to enhance security.
  • Bug Fixes

    • Route point null values now normalize to empty arrays.
    • Invalid YNAB transaction dates are skipped during import.
    • Travel item selector clears selection on load failure.
    • Weather service no longer persists empty cache entries.
  • Tests

    • Added comprehensive test coverage for routing validation, cost tracking, and UI components.

Review Change Stack

@coderabbitai

coderabbitai Bot commented May 21, 2026

Copy link
Copy Markdown
Contributor

Warning

Rate limit exceeded

@bdamokos has exceeded the limit for the number of commits that can be reviewed per hour. Please wait 53 minutes and 12 seconds before requesting another review.

You’ve run out of usage credits. Purchase more in the billing tab.

⌛ How to resolve this issue?

After the wait time has elapsed, a review can be triggered using the @coderabbitai review command as a PR comment. Alternatively, push new commits to this PR.

We recommend that you space out your commits to avoid hitting the rate limit.

🚦 How do rate limits work?

CodeRabbit enforces hourly rate limits for each developer per organization.

Our paid plans have higher rate limits than the trial, open-source and free plans. In all cases, we re-allow further reviews after a brief timeout.

Please see our FAQ for further information.

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: 1405d3a5-8e14-4378-8099-585bf35c7ebb

📥 Commits

Reviewing files that changed from the base of the PR and between e648594 and accf5e9.

📒 Files selected for processing (6)
  • src/app/__tests__/api/osrm-routing-validation.test.ts
  • src/app/__tests__/integration/cost-tracking-validation.integration.test.ts
  • src/app/__tests__/unit/weatherService.test.ts
  • src/app/admin/components/TravelItemSelector.tsx
  • src/app/api/cost-tracking/[id]/ynab-process/route.ts
  • src/app/services/weatherService.ts
📝 Walkthrough

Walkthrough

This PR integrates validation, security, and error-handling improvements across the routing API, travel data, cost tracking, UI components, and weather service. A new proxy-secret validation mechanism gates OSRM forwarded-host access; route-points are normalized in batch and single updates; YNAB transaction dates are validated and invalid entries are skipped; components now properly clear state on errors; and weather caching is optimized to skip persisting empty results.

Changes

Validation, Security, and Error Handling

Layer / File(s) Summary
OSRM Proxy Secret Validation
src/app/api/routing/osrm/route.ts, src/app/__tests__/api/osrm-routing-validation.test.ts
hasTrustedForwardedHostSecret validates x-travel-tracker-admin-proxy-secret header against ADMIN_PROXY_SECRET environment variable. Local proxy-hop requests now require both the trusted secret and admin-domain validation. Test setup/teardown manage environment state; tests verify rejection without secret and acceptance with correct header.
Route Points Normalization
src/app/api/travel-data/route.ts, src/app/__tests__/api/travel-data-auth-cache.test.ts
Batch and single route updates validate routePoints and apply normalized results. Batch handler accumulates validated updates in validatedUpdates array and logs validated count. Test verifies routePoints: null normalizes to [] on admin-domain PATCH request.
YNAB Transaction Date Validation
src/app/api/cost-tracking/[id]/ynab-process/route.ts, src/app/__tests__/integration/cost-tracking-validation.integration.test.ts
New getValidYnabISODate helper validates YNAB date conversion. Preview step skips transactions with invalid dates and counts them as already imported. Import step validates selected transaction date up front; on failure, skips selection. New hasSpecificSelection flag refines legacy-hash consumption. Expense creation and ProcessedYnabTransaction use prevalidated isoDate. Tests verify invalid-date skipping and instance-keyed duplicate handling.
Component Error Handling
src/app/admin/components/MultiRouteLinkManager.tsx, src/app/admin/components/TravelItemSelector.tsx, src/app/__tests__/unit/MultiRouteLinkManager.test.tsx, src/app/__tests__/unit/TravelItemSelector.loadFailure.test.tsx
MultiRouteLinkManager now propagates empty link arrays on removal. TravelItemSelector clears selection state and notifies parent on travel-items load failure when initial value or selection exists; added initialValue to effect dependency array. Tests verify link removal callbacks and load-failure state clearing.
Weather Service Cache Behavior
src/app/services/weatherService.ts, src/app/__tests__/unit/weatherService.test.ts
Removed EMPTY_WEATHER_CACHE_TTL_MS constant and changed isFreshEmptyCacheEntry to always return false. Cache persistence is now conditional: written only for non-empty fetches; empty results log fetch:failed-no-data and skip disk write. Test updated to reflect empty cache entries are no longer fresh.

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~25 minutes

Possibly related PRs

  • bdamokos/travel-tracker#311: Both PRs modify route-points validation in travel-data PATCH updates with normalization of invalid inputs like routePoints: null.
  • bdamokos/travel-tracker#256: Both PRs modify TravelItemSelector error handling and state-clearing behavior on travel-items load failure.
  • bdamokos/travel-tracker#117: Both PRs modify YNAB processing pipeline in cost-tracking with transaction validation and import logic changes.

Suggested labels

codex

🐰 A hare hops through the code with glee,
Validating dates and secrets with care—
Route-points dance to empty arrays bright,
Error states cleared in the quiet night,
Where weather caches breathe easier still!

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 18.18% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title accurately summarizes the main changes: fixing security scan regressions through hardened OSRM proxy validation, weather caching fixes, YNAB import validation, and route/UI state normalization.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch codex/security-findings-2026-05-21

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Actionable comments posted: 2

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
src/app/api/cost-tracking/[id]/ynab-process/route.ts (1)

158-171: ⚠️ Potential issue | 🟡 Minor | ⚡ Quick win

Invalid-date transactions consume legacy hash counts and are mislabeled as “already imported.”

Two related concerns in the preview loop:

  1. consumeLegacyImportedHash(legacyImportedHashCounts, hash) runs at Line 161, before the date validation at Line 167. When a transaction is dropped because of an invalid date, its legacy-hash count has already been decremented. A later valid duplicate with the same hash could then escape legacy-duplicate detection (or, conversely, the invalid one "uses up" a slot it shouldn't).
  2. Invalid-date transactions are bucketed into alreadyImportedCount, which is surfaced to the UI as "already imported" in the response message at Line 251. That's misleading — these were skipped because of a parse failure, not because they were imported before.

Consider moving date validation above the legacy-hash consumption and exposing a separate counter (e.g. invalidDateCount) so the UI can distinguish the two cases.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@src/app/api/cost-tracking/`[id]/ynab-process/route.ts around lines 158 - 171,
The loop currently calls consumeLegacyImportedHash(legacyImportedHashCounts,
hash) and computes hasLegacyImportedHash before validating the transaction date,
which causes invalid-date transactions to consume legacy hash counts and be
miscounted as already imported; fix by first calling
getValidYnabISODate(transaction.Date) and if the date is invalid increment a new
invalidDateCount (do not modify legacyImportedHashCounts or existingHashSet),
then only after the date is valid compute hash via createTransactionHash and
check existingHashSet and call consumeLegacyImportedHash to detect legacy
duplicates; ensure alreadyImportedCount remains for true duplicates and map
lookup (mappings.find(...)) logic stays the same.
🧹 Nitpick comments (4)
src/app/__tests__/unit/weatherService.test.ts (1)

32-45: 💤 Low value

Optional: rename the “expires empty cache entries after the negative cache TTL” test.

Since isFreshEmptyCacheEntry now unconditionally returns false, this test no longer exercises a TTL boundary — it’s asserting the same behavior as the “recent empty entries” test above. Consider renaming/merging it (e.g. “returns false regardless of fetchedAt age”) so the description matches the new semantics and doesn’t imply a TTL that no longer exists.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@src/app/__tests__/unit/weatherService.test.ts` around lines 32 - 45, The test
titled "expires empty cache entries after the negative cache TTL" is now
misleading because isFreshEmptyCacheEntry (in weatherServiceTestUtils) always
returns false; rename the test to reflect the new semantics (e.g., "returns
false regardless of fetchedAt age") or merge it with the "recent empty entries"
test so the description matches what is being asserted and no TTL boundary is
implied; update only the it(...) description string where that test is defined.
src/app/services/weatherService.ts (1)

434-439: 💤 Low value

Optional: collapse the now-dead branches in isFreshEmptyCacheEntry and its caller.

With the function unconditionally returning false, the length check on Line 436 and the entire cache:negative-hit branch at Lines 774–780 (including the log('cache:negative-hit', …) call) are unreachable. Consider either inlining the false result at the call site and dropping the helper, or keeping the helper as a thin no-op with a comment so the intent (negative caching disabled) is explicit and the dead branches/log don’t mislead future readers.

♻️ One possible cleanup
-function isFreshEmptyCacheEntry(cached: CacheEntry, now: Date): boolean {
-  void now;
-  if (cached.summary.dailyWeather.length > 0) return false;
-
-  return false;
-}
+// Negative caching for empty weather lookups is disabled; kept exported
+// for test compatibility.
+function isFreshEmptyCacheEntry(_cached: CacheEntry, _now: Date): boolean {
+  return false;
+}

And in getWeatherForLocation, the if (isFreshEmptyCacheEntry(cached, now)) { … 'cache:negative-hit' … } block can be removed.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@src/app/services/weatherService.ts` around lines 434 - 439, The helper
isFreshEmptyCacheEntry currently always returns false, making its length check
and the 'cache:negative-hit' branch in getWeatherForLocation unreachable; either
remove the helper and delete the entire if block that logs 'cache:negative-hit'
in getWeatherForLocation, or keep isFreshEmptyCacheEntry as an explicit no-op
(return false) but add a clarifying comment and remove the dead log/branch (the
cache:negative-hit check and log call) so readers aren't misled—locate the
function isFreshEmptyCacheEntry and the caller in getWeatherForLocation to apply
the change.
src/app/__tests__/api/osrm-routing-validation.test.ts (1)

68-87: ⚡ Quick win

Consider adding a test for missing/mismatched header when ADMIN_PROXY_SECRET is configured.

This test covers the case where ADMIN_PROXY_SECRET is unset (helper returns false via the early return). The more realistic bypass-attempt scenario — operator has configured the secret, but the inbound request lacks x-travel-tracker-admin-proxy-secret or sends a wrong value — isn't currently asserted. Adding it would lock in the header comparison branch in hasTrustedForwardedHostSecret.

🧪 Suggested additional test case
+  it('rejects forwarded admin hosts from local proxy hops with a missing or mismatched proxy secret', async () => {
+    process.env.ADMIN_DOMAIN = 'admin.example.test';
+    process.env.ADMIN_PROXY_SECRET = 'proxy-secret';
+    const fetchSpy = jest.spyOn(global, 'fetch');
+
+    const response = await GET(
+      new NextRequest(
+        'http://127.0.0.1:3000/api/routing/osrm?profile=car&fromLat=51.5&fromLng=-0.1&toLat=48.8&toLng=2.3',
+        {
+          headers: {
+            host: '127.0.0.1:3000',
+            'x-forwarded-host': 'admin.example.test',
+            'x-travel-tracker-admin-proxy-secret': 'wrong-secret'
+          }
+        }
+      )
+    );
+
+    await expect(response.json()).resolves.toEqual({ error: 'Admin domain required' });
+    expect(response.status).toBe(403);
+    expect(fetchSpy).not.toHaveBeenCalled();
+  });
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@src/app/__tests__/api/osrm-routing-validation.test.ts` around lines 68 - 87,
Add a test that simulates the case where ADMIN_PROXY_SECRET is set but the
incoming request either omits or supplies a wrong
x-travel-tracker-admin-proxy-secret header so the hasTrustedForwardedHostSecret
branch is exercised; in the new test (in
src/app/__tests__/api/osrm-routing-validation.test.ts) set
process.env.ADMIN_DOMAIN and process.env.ADMIN_PROXY_SECRET, call GET with
x-forwarded-host set to the admin domain but either no
x-travel-tracker-admin-proxy-secret header or a mismatched value, then assert
the response is 403 with { error: 'Admin domain required' } and that
global.fetch was not called to verify the header comparison branch in
hasTrustedForwardedHostSecret is covered.
src/app/api/cost-tracking/[id]/ynab-process/route.ts (1)

49-52: 💤 Low value

Helper can be simplified.

convertYnabDateToISO already returns a falsy value on failure, so isoDate ? isoDate : null is equivalent to convertYnabDateToISO(ynabDate) || null. The wrapper currently only exists to coerce undefined/'' to null; a one-liner or inlining is fine.

Proposed simplification
-function getValidYnabISODate(ynabDate: string): string | null {
-  const isoDate = convertYnabDateToISO(ynabDate);
-  return isoDate ? isoDate : null;
-}
+function getValidYnabISODate(ynabDate: string): string | null {
+  return convertYnabDateToISO(ynabDate) || null;
+}
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@src/app/api/cost-tracking/`[id]/ynab-process/route.ts around lines 49 - 52,
The helper getValidYnabISODate is redundant because convertYnabDateToISO already
yields a falsy value on failure; replace the body with a one-liner that returns
convertYnabDateToISO(ynabDate) || null, or remove getValidYnabISODate and inline
convertYnabDateToISO(ynabDate) || null wherever the helper is used so the call
coerces undefined/empty to null directly; update all references to the helper
(getValidYnabISODate) accordingly.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@src/app/__tests__/integration/cost-tracking-validation.integration.test.ts`:
- Around line 184-185: The test creates an unused NextRequest instance in the
variable named request and then calls costTrackingListGET with a freshly
constructed NextRequest; either remove the unused const request declaration or
reuse it by passing request into costTrackingListGET instead of creating a
second NextRequest. Update the lines around the NextRequest construction so only
one NextRequest is created and used with costTrackingListGET to eliminate the
unused variable.

In `@src/app/admin/components/TravelItemSelector.tsx`:
- Line 349: The effect in TravelItemSelector is depending on the object-identity
of initialValue (a TravelLinkInfo) which causes repeated refetches when parents
pass inline object literals; change the dependency list to use stable primitives
instead (e.g. initialValue?.id and initialValue?.type) rather than initialValue
itself for the fetch effect (the one currently depending on [initialValue,
tripId, reloadToken]) and also update the hydration effect deps (the effect
around lines 180-185) to use the same stable fields so the effects only re-run
on meaningful changes.

---

Outside diff comments:
In `@src/app/api/cost-tracking/`[id]/ynab-process/route.ts:
- Around line 158-171: The loop currently calls
consumeLegacyImportedHash(legacyImportedHashCounts, hash) and computes
hasLegacyImportedHash before validating the transaction date, which causes
invalid-date transactions to consume legacy hash counts and be miscounted as
already imported; fix by first calling getValidYnabISODate(transaction.Date) and
if the date is invalid increment a new invalidDateCount (do not modify
legacyImportedHashCounts or existingHashSet), then only after the date is valid
compute hash via createTransactionHash and check existingHashSet and call
consumeLegacyImportedHash to detect legacy duplicates; ensure
alreadyImportedCount remains for true duplicates and map lookup
(mappings.find(...)) logic stays the same.

---

Nitpick comments:
In `@src/app/__tests__/api/osrm-routing-validation.test.ts`:
- Around line 68-87: Add a test that simulates the case where ADMIN_PROXY_SECRET
is set but the incoming request either omits or supplies a wrong
x-travel-tracker-admin-proxy-secret header so the hasTrustedForwardedHostSecret
branch is exercised; in the new test (in
src/app/__tests__/api/osrm-routing-validation.test.ts) set
process.env.ADMIN_DOMAIN and process.env.ADMIN_PROXY_SECRET, call GET with
x-forwarded-host set to the admin domain but either no
x-travel-tracker-admin-proxy-secret header or a mismatched value, then assert
the response is 403 with { error: 'Admin domain required' } and that
global.fetch was not called to verify the header comparison branch in
hasTrustedForwardedHostSecret is covered.

In `@src/app/__tests__/unit/weatherService.test.ts`:
- Around line 32-45: The test titled "expires empty cache entries after the
negative cache TTL" is now misleading because isFreshEmptyCacheEntry (in
weatherServiceTestUtils) always returns false; rename the test to reflect the
new semantics (e.g., "returns false regardless of fetchedAt age") or merge it
with the "recent empty entries" test so the description matches what is being
asserted and no TTL boundary is implied; update only the it(...) description
string where that test is defined.

In `@src/app/api/cost-tracking/`[id]/ynab-process/route.ts:
- Around line 49-52: The helper getValidYnabISODate is redundant because
convertYnabDateToISO already yields a falsy value on failure; replace the body
with a one-liner that returns convertYnabDateToISO(ynabDate) || null, or remove
getValidYnabISODate and inline convertYnabDateToISO(ynabDate) || null wherever
the helper is used so the call coerces undefined/empty to null directly; update
all references to the helper (getValidYnabISODate) accordingly.

In `@src/app/services/weatherService.ts`:
- Around line 434-439: The helper isFreshEmptyCacheEntry currently always
returns false, making its length check and the 'cache:negative-hit' branch in
getWeatherForLocation unreachable; either remove the helper and delete the
entire if block that logs 'cache:negative-hit' in getWeatherForLocation, or keep
isFreshEmptyCacheEntry as an explicit no-op (return false) but add a clarifying
comment and remove the dead log/branch (the cache:negative-hit check and log
call) so readers aren't misled—locate the function isFreshEmptyCacheEntry and
the caller in getWeatherForLocation to apply the change.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: 606d0513-df23-48e9-bc9f-e1d59e8edc42

📥 Commits

Reviewing files that changed from the base of the PR and between d232c7d and e648594.

📒 Files selected for processing (12)
  • src/app/__tests__/api/osrm-routing-validation.test.ts
  • src/app/__tests__/api/travel-data-auth-cache.test.ts
  • src/app/__tests__/integration/cost-tracking-validation.integration.test.ts
  • src/app/__tests__/unit/MultiRouteLinkManager.test.tsx
  • src/app/__tests__/unit/TravelItemSelector.loadFailure.test.tsx
  • src/app/__tests__/unit/weatherService.test.ts
  • src/app/admin/components/MultiRouteLinkManager.tsx
  • src/app/admin/components/TravelItemSelector.tsx
  • src/app/api/cost-tracking/[id]/ynab-process/route.ts
  • src/app/api/routing/osrm/route.ts
  • src/app/api/travel-data/route.ts
  • src/app/services/weatherService.ts
💤 Files with no reviewable changes (1)
  • src/app/admin/components/MultiRouteLinkManager.tsx

Comment thread src/app/__tests__/integration/cost-tracking-validation.integration.test.ts Outdated
Comment thread src/app/admin/components/TravelItemSelector.tsx Outdated

@gemini-code-assist gemini-code-assist Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Code Review

This pull request enhances security and data integrity by introducing a proxy secret for OSRM routing, improving YNAB transaction import logic with date validation, and refining batch route updates. It also disables negative caching for empty weather results and improves error handling in the TravelItemSelector UI component. Review feedback identifies a misleading counter increment for invalid YNAB dates and warns against including initialValue in a useEffect dependency array to prevent redundant network requests.

Comment thread src/app/api/cost-tracking/[id]/ynab-process/route.ts
Comment thread src/app/admin/components/TravelItemSelector.tsx Outdated
@greptile-apps

greptile-apps Bot commented May 21, 2026

Copy link
Copy Markdown
Contributor

Confidence Score: 5/5

Safe to merge. All changes are targeted bug fixes with direct test coverage; no regressions identified in the changed paths.

Every fix is well-scoped: the proxy secret check fails closed (no env var → no forwarded-host trust), date validation happens before hash computation so it cannot pollute alreadyImportedCount, and null route points are normalized by the existing validateRoutePoints helper rather than by ad-hoc checks. The test suite covers the happy path, the rejection paths, and the edge cases (mismatched secret, invalid date, instance-keyed duplicate) for each change.

No files require special attention. Operators upgrading who use a local reverse proxy for the OSRM endpoint must set ADMIN_PROXY_SECRET — without it the forwarded-host fallback is now unconditionally blocked.

Important Files Changed

Filename Overview
src/app/api/routing/osrm/route.ts Adds ADMIN_PROXY_SECRET header validation before trusting x-forwarded-host from local proxies; clean security hardening with correct short-circuit logic.
src/app/api/cost-tracking/[id]/ynab-process/route.ts Validates YNAB dates before hash computation, preserves instance-keyed imports when a legacy base hash already exists, and returns invalidDateCount in preview responses.
src/app/api/travel-data/route.ts Introduces validatedUpdates to carry normalized (null→[]) route points through the batch path; single-route path now also uses validation.points instead of the raw input.
src/app/services/weatherService.ts Disables negative caching by always returning false from isFreshEmptyCacheEntry and skipping the cache write when fetched results are empty.
src/app/admin/components/TravelItemSelector.tsx Extracts stable primitive dependencies from initialValue to break the infinite-loop risk; clears selection state and calls onReferenceChange(undefined) on load failure.
src/app/admin/components/MultiRouteLinkManager.tsx Removes the early-return guard that silently suppressed the onLinksChange([]) notification when all links were removed while initialLinks was non-empty.
src/app/tests/api/osrm-routing-validation.test.ts Adds three new test cases covering rejection without secret, rejection with wrong secret, and acceptance with correct secret; restores env vars correctly in afterEach.
src/app/tests/integration/cost-tracking-validation.integration.test.ts Adds integration tests for invalid-date skipping and instance-keyed duplicate imports; fixes resetAllMocks and passes request object to costTrackingListGET.
src/app/tests/unit/MultiRouteLinkManager.test.tsx New unit test verifying that removing the last link triggers onLinksChange([]).
src/app/tests/unit/TravelItemSelector.loadFailure.test.tsx New unit test verifying that a network failure during item load causes onReferenceChange(undefined) to be called.
src/app/tests/unit/weatherService.test.ts Renames and inverts the two isFreshEmptyCacheEntry tests to match the new always-false behavior.
src/app/tests/api/travel-data-auth-cache.test.ts Adds a test that null routePoints in a batch PATCH is normalized to [] and written back correctly.

Flowchart

%%{init: {'theme': 'neutral'}}%%
flowchart TD
    A[Incoming OSRM GET] --> B{isAdminHost\nhost header?}
    B -- yes --> ALLOW[Proxy to OSRM upstream]
    B -- no --> C{isLocalProxyHost?}
    C -- no --> DENY[403 Admin domain required]
    C -- yes --> D{ADMIN_PROXY_SECRET\nenv set?}
    D -- no --> DENY
    D -- yes --> E{x-travel-tracker-admin-proxy-secret\nmatches?}
    E -- no --> DENY
    E -- yes --> F{isAdminHost\nx-forwarded-host?}
    F -- no --> DENY
    F -- yes --> ALLOW
Loading

Reviews (2): Last reviewed commit: "Address review feedback" | Re-trigger Greptile

Comment thread src/app/admin/components/TravelItemSelector.tsx Outdated
Comment thread src/app/api/cost-tracking/[id]/ynab-process/route.ts
Comment thread src/app/services/weatherService.ts Outdated
@bdamokos bdamokos merged commit 004f96a into main May 21, 2026
5 checks passed
@bdamokos bdamokos deleted the codex/security-findings-2026-05-21 branch May 21, 2026 17:16
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