stack/apps
aadesh18 5b9ae9c443
fix(account-settings): decode URL-encoded city in active sessions (#1503)
## Summary

The **Active Sessions** table in account settings showed locations like
`San%20Francisco` instead of `San Francisco`.

Vercel percent-encodes its geolocation headers (e.g.
`x-vercel-ip-city`), so a multi-word city arrives URL-encoded. The city
name was being stored verbatim, so the raw `%20` leaked into the UI.

The fix decodes the city name where the Vercel geo header is read, so
recorded sessions store the human-readable name. This also benefits any
other consumer of the location data. It falls back to the raw value if
it isn't valid percent-encoding, so a stray `%` can't break things.

## Test plan

- [ ] Unit tests (in-source, `apps/backend/src/lib/end-users.tsx`):
simulating Vercel headers with `x-vercel-ip-city: San%20Francisco` now
yields `cityName: "San Francisco"`; an invalid-encoding value (`100%
Real City`) passes through unchanged instead of throwing. All 8 tests in
the file pass.
- [ ] In a Vercel-deployed environment, sign in and open Account
Settings → Active Sessions; confirm the Location column shows a plain
city name (e.g. `San Francisco`) with no `%20`.

> Note: this can't be reproduced on localhost because there's no Vercel
proxy supplying geo headers (the location shows `Unknown`). The behavior
is covered by the unit tests, which feed the exact headers Vercel sends.

<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->
## Summary by CodeRabbit

* **Bug Fixes**
* Corrected handling of city name data from hosting-provided location
headers so multi-word city names display correctly and invalid
percent-encoding no longer causes errors.

* **Tests**
* Added tests to verify URL-decoded city names from location headers and
to ensure malformed encodings are safely preserved.

<!-- review_stack_entry_start -->

[![Review Change
Stack](https://storage.googleapis.com/coderabbit_public_assets/review-stack-in-coderabbit-ui.svg)](https://app.coderabbit.ai/change-stack/hexclave/stack-auth/pull/1503?utm_source=github_walkthrough&utm_medium=github&utm_campaign=change_stack)

<!-- review_stack_entry_end -->
<!-- end of auto-generated comment: release notes by coderabbit.ai -->
2026-05-28 11:50:00 -07:00
..
backend fix(account-settings): decode URL-encoded city in active sessions (#1503) 2026-05-28 11:50:00 -07:00
dashboard Add captureWarning for warnings (#1506) 2026-05-27 15:35:10 -07:00
dev-launchpad feat(hexclave): PR 2 — visible rebrand (Hexclave brand goes public) (#1481) 2026-05-26 19:18:20 -07:00
e2e feat(hexclave): PR 2 — visible rebrand (Hexclave brand goes public) (#1481) 2026-05-26 19:18:20 -07:00
hosted-components feat(hexclave): PR 2 — visible rebrand (Hexclave brand goes public) (#1481) 2026-05-26 19:18:20 -07:00
internal-tool feat(hexclave): PR 2 — visible rebrand (Hexclave brand goes public) (#1481) 2026-05-26 19:18:20 -07:00
mcp feat(hexclave): PR 2 — visible rebrand (Hexclave brand goes public) (#1481) 2026-05-26 19:18:20 -07:00
mock-oauth-server feat(hexclave): PR 2 — visible rebrand (Hexclave brand goes public) (#1481) 2026-05-26 19:18:20 -07:00
oauth-mock-server In-source unit tests (#429) 2025-02-14 11:47:52 -08:00
skills Rebrand skills route page to Hexclave (#1494) 2026-05-27 09:59:18 -07:00