Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
@if (selectedGym(); as gym) {
<div class="selected-gym">
@if (gym.url) {
<img [src]="gym.url" class="gym-photo" />
<img [src]="gym.url" class="gym-photo" referrerpolicy="no-referrer" />
} @else {
<img [src]="getTeamIcon(gym.teamId)" class="team-icon" />
<img [src]="getTeamIcon(gym.teamId)" class="team-icon" referrerpolicy="no-referrer" />
}
<div class="selected-text">
<span class="gym-name">{{ gym.name ?? gym.id }}</span>
Expand Down Expand Up @@ -31,9 +31,9 @@
<mat-option [value]="gym">
<div class="option-row">
@if (gym.url) {
<img [src]="gym.url" class="gym-photo-sm" />
<img [src]="gym.url" class="gym-photo-sm" referrerpolicy="no-referrer" />
} @else {
<img [src]="getTeamIcon(gym.teamId)" class="team-icon-sm" />
<img [src]="getTeamIcon(gym.teamId)" class="team-icon-sm" referrerpolicy="no-referrer" />
}
<div class="option-text">
<span class="option-name">{{ gym.name ?? gym.id }}</span>
Expand Down
3 changes: 3 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,9 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
- **Containers reported `unhealthy` while serving traffic normally** ([#239](https://github.com/PGAN-Dev/PoracleWeb.NET/issues/239)): the Compose healthcheck probes the app with `curl -sf http://localhost:8080/`, but the `mcr.microsoft.com/dotnet/aspnet:10.0` runtime base (Ubuntu 24.04) ships neither `curl` nor `wget`, so every probe failed with `/bin/sh: 1: curl: not found` and Docker flipped the container to `unhealthy` after three tries. ASP.NET Core was live the whole time, so the impact was cosmetic on a single host — but Swarm, Kubernetes, and auto-healer scripts treat `unhealthy` as a restart/evict signal, so it would misfire in any real deployment. The runtime stage now installs `curl` (`--no-install-recommends`, apt lists removed, ~6.5 MB) before dropping to the `appuser` account. Verified in a built image: `curl 8.5.0` resolves and runs as `appuser`.
- **Role gating required *every* listed role, and quoted values locked everyone out** ([#367](https://github.com/PGAN-Dev/PoracleWeb.NET/issues/367)): `allowed_role_ids` is described everywhere as an allow-list of Discord roles that grant access, but `CheckRoleAccessAsync` compared with `HashSet.IsSubsetOf`, which only returned true when the user held **all** of the listed roles. Configuring `123,456` therefore denied anyone who had just one of them. It now matches on `Overlaps` — holding any one listed role is enough. Two smaller problems around the same setting are fixed with it. The setting's tooltip rendered its example wrapped in quotes (`"123456789,987654321"`), so admins pasted the quotes in and the comma-split produced entries like `"123456789` that can never equal a Discord role ID; every non-admin was then denied with nothing but an info-level log to explain it (admins bypass the role check, which is why the site looked admin-only). Values are now parsed with surrounding quotes stripped — straight, curly, guillemet, and low-9 variants, matching the quote styles used across the translated tooltips — and entries that aren't numeric snowflakes are dropped and logged as a warning instead of being kept as unmatchable garbage. If a non-empty setting yields no usable IDs at all, non-admin logins are refused with `role_check_failed` and an error log rather than silently falling open to "allow everyone". Finally the tooltip copy (all 11 locales) and the settings/SSO docs now drop the misleading quotes and state the any-of semantics outright. Both callers are affected — the Discord OAuth callback and the OIDC/external-SSO path share this check. Unit tests cover the parser (quote styles, whitespace, non-snowflake entries, dedup, empty values) and the any-of grant/deny decision.

### Security
- **Gym-picker images no longer send a `Referer` header to third-party hosts** ([#242](https://github.com/PGAN-Dev/PoracleWeb.NET/issues/242)): the gym picker renders two kinds of remote image — the scanner DB's `gym.url` photo (a Niantic CDN URL in stock Golbat/RDM deployments, though an operator can rewrite the column to point at a self-hosted mirror) and the team-icon fallback from `raw.githubusercontent.com`. Neither carried a referrer policy, so every image request told the remote host which PoracleWeb instance the user was browsing. All four `<img>` tags in `gym-picker.component.html` now set `referrerpolicy="no-referrer"`. Modern browsers already default to `strict-origin-when-cross-origin`, so the pre-existing leak was the origin rather than the full URL — this closes the remainder. Presentation-only: no API, model, or scanner-query change, and `GymSearchResult.Url` still carries the raw scanner URL as before. The photo-proxy endpoint floated in the original issue was **not** implemented: server-side fetching of a URL supplied by a database PoracleWeb does not own would turn a passive disclosure into an authenticated outbound-request primitive from a host that can reach Poracle, Koji, Golbat, and both MySQL servers. A host allowlist applied at projection remains the cheaper option if a deployment ever needs the mirror case handled.

## [2.11.1] - 2026-06-05

### Fixed
Expand Down
Loading