fix(imaging): normalise avatar figures before building URLs
CI / check (push) Successful in 39s
CI / tests-integration (push) Successful in 2m2s
CI / tests-unit (push) Successful in 2m7s
CI / tests-ui (push) Successful in 2m46s
CI / preflight (push) Skipped
CI / tests-imaging-browsers (push) Successful in 3m9s
CI / tests-quality (push) Successful in 1m24s
CI / deploy (push) Successful in 4m9s
CI / check (push) Successful in 39s
CI / tests-integration (push) Successful in 2m2s
CI / tests-unit (push) Successful in 2m7s
CI / tests-ui (push) Successful in 2m46s
CI / preflight (push) Skipped
CI / tests-imaging-browsers (push) Successful in 3m9s
CI / tests-quality (push) Successful in 1m24s
CI / deploy (push) Successful in 4m9s
Legacy accounts can carry a malformed stored look — the old register default `hr-100-.hd-180-1...` has an empty colour slot — which the imager rejects with 400 "Invalid figure format", so the avatar renders broken everywhere the look appears. Normalise the figure in the shared URL builder (`getAvatarUrl`, used by every avatar on the site): an unrenderable look becomes `DEFAULT_AVATAR_FIGURE` while the proxy route keeps rejecting malformed input with 400. The rule set and default now live in one client-safe module (`src/lib/avatar-figure.ts`), shared by the URL builder and the server parser.
This commit is contained in:
1 parent
1e3406a7ae
commit
61107848f8
7 files changed
+106
-14
No files matched your search
@@ -639,9 +639,20 @@ A production issue that this section documents: **the `avatar-imaging-pixinode`
|
||||
|
||||
Since then the CMS-side avatar proxies (`/api/imaging/avatar` and `/imaging`) are resilient: when the configured upstream (the Polaris container on `8082`) fails or times out, the request is retried against Habbo's public renderer (`https://www.habbo.com/habbo-imaging/avatarimage`), with the `effect` parameter stripped and `img_format` forced to `png`, since the public renderer supports neither. The response is then marked with `X-Imager-Source: primary|fallback` and a shorter `Cache-Control` TTL when served from fallback, so the configured imager is retried soon instead of being masked for hours. No fallback is attempted when the configured upstream already is the Habbo public renderer. As a last line of defence every avatar `<img>` on the site falls back to a grayscale silhouette placeholder instead of a broken-image glyph.
|
||||
|
||||
### Figure string validation (`src/app/api/imaging/avatar/route.ts`)
|
||||
### Figure string validation
|
||||
|
||||
The CMS-side route re-validates the incoming figure against `/^[a-z]{2}-\d+(-\d+)?(\.[a-z]{2}-\d+(-\d+)?)*$/i`. Real Habbo figure strings use `type-id-color` parts separated by dots (`hd-180-1.ch-210-66`), so each part allows an optional second number. Invalid input is rejected with `400` before any render happens.
|
||||
The URL builder (`src/lib/imager.ts`) and the proxy routes share one rule set
|
||||
(`src/lib/avatar-figure.ts`): a figure must look like `part-id` segments
|
||||
separated by dots (`hd-180-1.ch-210-66`). Some clients append extra segments the
|
||||
renderer still accepts (e.g. a trailing `.0`), so the pattern is deliberately
|
||||
loose; over-strict validation once turned valid avatars into 400s.
|
||||
|
||||
Before a URL is built, the stored look is normalised: anything the imager would
|
||||
reject — an empty part slot such as the legacy `hr-100-.hd-180-1` default, a
|
||||
path-traversal attempt, an over-long value — is replaced with
|
||||
`DEFAULT_AVATAR_FIGURE`. That stops legacy accounts from rendering broken
|
||||
avatars without weakening the route, which still answers `400` to a malformed
|
||||
figure (`src/app/api/imaging/avatar/route.ts`).
|
||||
|
||||
---
|
||||
|
||||
|
||||
Reference in new issue
Block a user