Commit Graph

1056 Commits

Author SHA1 Message Date
DuckieTM 485642637e Merge pull request #255 from simoleo89/fix/ui-bug-sweep
fix(youtube): interpolate videoId in the share-to-X tweet text
2026-06-18 12:29:46 +02:00
DuckieTM 61cfb361fa Merge pull request #254 from simoleo89/fix/dep-security-dompurify
chore(deps): bump dompurify to 3.4.11 (fixes low-severity audit advisory)
2026-06-18 12:29:12 +02:00
DuckieTM feba3e30d3 Merge pull request #253 from simoleo89/feat/code-splitting
perf(bundle): lazy-load emoji-mart picker (defer ~82 KB gzip from first paint)
2026-06-18 12:28:49 +02:00
DuckieTM fec0361129 Merge pull request #252 from simoleo89/fix/purse-seasonal-currency-label
fix(purse): don't show raw localization keys for unnamed seasonal currencies
2026-06-18 12:28:02 +02:00
DuckieTM ff3bd1691b Merge pull request #251 from simoleo89/fix/sanitize-user-html
fix(security): client XSS & external-link hardening
2026-06-18 12:27:33 +02:00
simoleo89 9ad4dab471 fix(youtube): interpolate videoId in the share-to-X tweet text
The share button built the tweet text from a single-quoted string containing ${videoId}, so it shared the literal 'watch?v=${videoId}' instead of the actual video URL. Use a template literal so videoId interpolates.
2026-06-17 21:57:13 +02:00
simoleo89 3a93e309f2 chore(deps): bump dompurify to ^3.4.10 (3.4.11) — fixes low-severity advisory
dompurify 3.4.8 is flagged by yarn audit (npm advisory 1120805: a Trusted Types policy survives clearConfig and can poison later RETURN_TRUSTED_TYPE output, patched in >=3.4.9). It's the library behind SanitizeHtml — the client's XSS defence — so keep it current. After the bump yarn audit reports 0 vulnerabilities. typecheck 0, tests green.
2026-06-17 21:50:54 +02:00
simoleo89 4d81fe7c82 perf(bundle): lazy-load emoji-mart picker (defer ~82 KB gzip from first paint)
@emoji-mart/data (~430 KB / ~82 KB gzip) was pulled into the initial load by three always-mounted views (catalog custom-prefix, nick-icon, chat-input emoji selector) importing it statically. Add LazyEmojiPicker — a Suspense wrapper that dynamically imports the data + Picker on first open — and use it in those three sites.

Verified via the build manifest: the entry chunk no longer imports vendor-emoji statically or dynamically; vendor-emoji is now a dynamicImport of src/index.tsx, loaded on first picker open. No behaviour change. typecheck 0, tests 545/545.
2026-06-17 21:26:55 +02:00
simoleo89 58fe56175f fix(purse): don't show raw localization keys for unnamed seasonal currencies
A seasonal currency with no purse.seasonal.currency.<type> text rendered the raw key (e.g. 'purse.seasonal.currency.11') in the purse. Share PurseView's existing localizeWithFallback helper (extracted to api/utils with a pure resolveLocalized core + tests) and use it in SeasonalView with an empty fallback, so an unnamed currency shows just its icon + amount. Verified in-app.
2026-06-17 20:15:48 +02:00
simoleo89 e39f88f98e fix(security): sanitize server-pushed notification HTML (alert + bubble)
NotificationDefaultAlertView / NotificationDefaultBubbleView injected the server notification message (newline->br only) via dangerouslySetInnerHTML. Route through SanitizeHtml — the allow-list keeps the br/link/formatting these alerts use and strips anything else. Left Nitropedia (rich fetched HTML w/ tags outside the allow-list) and NitrobubbleHidden (<style> block) untouched on purpose: SanitizeHtml would break them.
2026-06-17 19:57:35 +02:00
simoleo89 24d10aced1 fix(security): harden external-link opening (protocol allow-list + noopener)
URLs reached window.open from user/server-controlled content without a protocol check or noopener, allowing reverse-tabnabbing and (for the chat link handler) a javascript:/data: href running in our origin.

- add isSafeExternalUrl() (http/https only) + tests; gate the chat link opener (useOnClickChat) and external photo opener with it

- SanitizeHtml: afterSanitizeAttributes hook forces rel="noopener noreferrer" on any target=_blank anchor (overrides attacker-supplied rel)

- add noopener,noreferrer to the remaining window.open(_blank) sites (YouTube share, external photo, guide forum link); drop a stray console.log
2026-06-17 19:12:01 +02:00
simoleo89 301294ecf4 fix(security): sanitize user-controlled HTML in chat & username sinks
Several dangerouslySetInnerHTML sinks rendered user-controlled strings (chat messages, usernames, chat history) without sanitisation, relying implicitly on upstream formatting or server-side charset limits. Route them all through the existing SanitizeHtml (DOMPurify) helper so the security guarantee is local to each render site.

Sinks fixed: ChatWidgetWindowView (name/message/original/translated), ChatHistoryView (name/message), AvatarInfoWidgetNameView + AvatarInfoWidgetAvatarView (username), SelectReportedUserView (username).

Add regression suites: SanitizeHtml.test.ts (XSS neutralised, chat markup preserved) and RoomChatFormatter.test.ts (pins the existing encodeHTML defence). No behaviour change: SanitizeHtml's allow-list keeps the b/i/u/span/strong/em/br markup the chat/profile UI relies on.
2026-06-17 19:00:42 +02:00
DuckieTM 1b032bcd23 Merge pull request #250 from simoleo89/feat/toolbar-habbo
Feat/toolbar habbo
2026-06-17 10:06:25 +02:00
DuckieTM 957e0758a7 Merge pull request #249 from simoleo89/feat/earnings-center-dev
feat(vault): functional Guadagni (Earnings Center) window
2026-06-17 10:05:03 +02:00
simoleo89 2d09a344ba fix(chat): keep flood warning inside the chat bar
The flood/mute warning was rendered inside the inline-grid input-sizer with no
single-line constraint, so a long message (e.g. a large remaining time) wrapped
to a second line and, with the bar's overflow-visible, spilled out the top. Give
it its own centered, single-line, truncating container so it stays within the
bar regardless of length.
2026-06-15 22:35:36 +02:00
simoleo89 f7e10b5f46 feat(vault): functional Guadagni (Earnings Center) window
VaultView wired to the Earnings Center packets: requests data on open, renders
real amounts/claimable per category from EarningsCenterEvent, Riscatta + Richiedili
Tutti send the claim composers, refreshes on EarningsClaimResultEvent. Category
keys match the emulator contract; reward currencies derived from reward type.
Adds the real earnings_icon assets. Wired into MainView.
2026-06-15 22:29:10 +02:00
simoleo89 4fa93cfaf3 fix(help): Habbo-green buttons + restyle sanctions box
Move the .nitro-help blue-header / grey-body override to global CSS so it also
covers the separate SanctionStatusView card (was an inline <style> in HelpView,
so the sanctions body stayed teal). Replace the flat 'success' buttons with the
beveled Habbo-green button (.habbo-btn-green) matching the reference. Restructure
the sanctions box to a single column: text on top, safety link (left) + green
'Ho capito' (right) pinned to the bottom.
2026-06-15 22:23:16 +02:00
simoleo89 20ad8b705a feat(help): restyle Aiuto window to match Habbo reference
Centered single-column index (blue header + light grey body), the real
help_duck asset, two green buttons (report + player support), and three
green-arrow links: read more about safety, my sanctions, my reports. The
report-flow steps keep the original 2-column grid.
2026-06-15 22:16:39 +02:00
simoleo89 d15457b43c feat(vault): wire Guadagni window to earnings packets
Request earnings on open (RequestEarningsCenterComposer), render real
amounts/claimable per category from EarningsCenterEvent, per-row Riscatta +
Richiedili Tutti send the claim composers, refresh on EarningsClaimResultEvent.
Category keys aligned to the emulator contract; reward currencies derived from
reward type; rows fall back to the static skeleton before data lands.
2026-06-15 22:00:08 +02:00
simoleo89 e94463df6a style(vault): fix body bg selector (content-shell) + compact rows
Target .nitro-card-content-shell for the grey body (the previous .content-area
selector didn't match), and tighten row height (smaller icon box + less gap) to
match the more compact Habbo reference.
2026-06-15 21:32:40 +02:00
simoleo89 983c659e9a style(vault): classic blue header + cool grey body (scoped to the window)
Override the shared teal/cream primary-slim theme just for the Guadagni window:
blue header gradient + grey-blue body, matching the reference.
2026-06-15 21:25:12 +02:00
simoleo89 eaf9a1b04d fix(vault): use the standard earnings.* localization keys
Use the real gamedata keys (earnings.title, earnings.dailygift.label,
earnings.achievements.label, earnings.claim.button, ...) instead of invented
ones, so the window is properly localized. 'games'/'clubwork' have no standard
key — custom key + Italian fallback.
2026-06-15 21:04:59 +02:00
simoleo89 7a2b016704 fix(vault): header reads 'Guadagni' (key resolved to English) 2026-06-15 20:54:33 +02:00
simoleo89 38ffc80d0a style(vault): bold black currency amounts + align Riscatta buttons 2026-06-15 20:47:04 +02:00
simoleo89 e4fb00baac style(vault): classic gray beveled buttons + thinner row border (closer to reference) 2026-06-15 20:44:31 +02:00
simoleo89 6b34bd9103 feat(vault): use the hotel's real earnings_icon assets
Replace the FontAwesome placeholders with the hotel's actual earnings_icon_*
PNGs (daily gift, games, achievements, marketplace, HC payday, level
progression, donations, bonus bag, surprise). Club e Lavoro uses the generic
earnings icon (no dedicated asset).
2026-06-15 20:40:32 +02:00
simoleo89 8c9566f928 style(vault): match the reference Guadagni layout
Each row is now a white bordered card (icon + name) with the currencies and a
gray disabled Riscatta button outside it, plus a gray disabled Richiedili Tutti
at the bottom — matching the reference screenshot.
2026-06-15 20:31:25 +02:00
simoleo89 5ac3b34916 fix(purse): Join/Entra opens the HC Center (habboUI/open/hccenter)
The Entra button pointed at catalog/open/<habbo_club> (a catalog page that often
doesn't exist); open the real HC Center view instead.
2026-06-15 20:28:39 +02:00
simoleo89 bf59ce2311 style(purse): tighten gear dropdown rows (compact spacing like reference) 2026-06-15 20:26:37 +02:00
simoleo89 88f5ecffd3 style(purse): widen the gear dropdown to match the purse width (234px) 2026-06-15 20:25:11 +02:00
simoleo89 3a5588d83a feat(vault): add the Guadagni/earnings window (client shell)
Wire the dead 'Guadagni' purse button (habboUI/open/vault) to a new VaultView:
the 10 earning categories from the reference, each with currency icons, a 0
placeholder amount and a disabled Riscatta button, plus a disabled Richiedili
Tutti. Amounts/claims are placeholders until the emulator exposes the data.
2026-06-15 20:18:35 +02:00
simoleo89 340ca3e0e8 feat(settings): revert to gear dropdown menu + add Gestione Account entry
Bring back the purse gear dropdown (Audio/Discord/Chat/Altre/Filtro) instead of
the tabbed window, and add a 'Gestione Account' item that opens the account
settings window.
2026-06-15 20:10:32 +02:00
simoleo89 992e65cb3d style(settings): card-style rows + section labels + 340px width
Match the account window's look across all settings tabs: each control sits in
a rounded white card row with a section label, and the window width is 340px.
2026-06-15 20:03:52 +02:00
simoleo89 63b92a4e65 feat(settings): gear opens a multi-tab settings window with account management
Replace the gear dropdown with a single tabbed window: Audio / Chat / Altre /
Account. Audio/Chat/Altre reuse the existing volume + preference controls;
Account recovers UserAccountSettingsView (now embeddable via an 'embedded' prop
that renders its body without its own card). Removes the dropdown menu + dead css.
2026-06-15 20:01:17 +02:00
DuckieTM 124858c0f8 Merge pull request #248 from Lorenzune/pr-restore-client-release
Restore client release workflow
2026-06-15 07:18:00 +02:00
DuckieTM 5e1e8ce654 Merge pull request #247 from simoleo89/docs/claude-md-runtime-verify
docs(CLAUDE): add Runtime verification section (Claude-in-Chrome, not headless)
2026-06-15 07:17:42 +02:00
DuckieTM 25e53e85b1 Merge pull request #246 from simoleo89/fix/marketplace-bugs
fix(marketplace): creditsWaiting reset & re-priced offer vanish
2026-06-15 07:17:20 +02:00
DuckieTM c14a6ec4d8 Merge pull request #245 from simoleo89/fix/purse-hc-status
fix(purse): HC status EXPIRED for ex-Club non-VIP users
2026-06-15 07:17:02 +02:00
DuckieTM fbbcca6dd6 Merge pull request #244 from simoleo89/fix/groups-color-picker
fix(groups): colour-picker highlight follows live selection
2026-06-15 07:16:41 +02:00
DuckieTM f57c2bd2bf Merge pull request #243 from simoleo89/fix/camera-bugs
fix(camera): delete-index reset & full-roll discard
2026-06-15 07:16:18 +02:00
DuckieTM c69ccba51d Merge pull request #242 from simoleo89/fix/modtools-bugs
fix(mod-tools): default-sanction topic id & alert typos
2026-06-15 07:15:52 +02:00
DuckieTM 75cd2791f8 Merge pull request #241 from simoleo89/fix/wired-bugs
fix(wired): @altitude scale & date-range NaN
2026-06-15 07:15:31 +02:00
DuckieTM 6fb8387afd Merge pull request #240 from simoleo89/fix/room-widget-bugs
fix(room): name-bubble, pet-fertilize chat & word-quiz bugs
2026-06-15 07:15:09 +02:00
DuckieTM 3eec31629f Merge pull request #239 from simoleo89/fix/messenger-setread-render
fix(messenger): mark thread read in an effect, not during render
2026-06-15 07:14:47 +02:00
DuckieTM abce531616 Merge pull request #238 from simoleo89/fix/inventory-state-bugs
fix(inventory): state-mutation & stale-read bugs
2026-06-15 07:14:28 +02:00
DuckieTM f1c9e1baee Merge pull request #237 from simoleo89/feat/furni-editor-create-missing
feat(furni-editor): create furnidata entry when missing (upsert Save)
2026-06-15 07:14:04 +02:00
Lorenzune dd1b8b7613 Fix release bundle chunk loading 2026-06-15 02:20:54 +02:00
Lorenzune 29cba0be2d Restore client release workflow 2026-06-15 02:16:23 +02:00
simoleo89 c2be4dbed3 feat(settings): gear dropdown opening focused settings sections
The purse gear now opens a dropdown (Audio / Discord / Chat / Altre / Filtro
Parole). Audio/Chat/Altre open UserSettingsView focused on that section
(reusing the existing volume + preference controls) with a Back button; Discord
and Filtro Parole are placeholders for now.
2026-06-14 22:25:55 +02:00
simoleo89 28df1da69b style(help): green action buttons + drop the disabled tips button
Make the two help actions (report bully / player support) green and remove the
always-disabled 'tips' button, matching the reference help window.
2026-06-14 22:17:30 +02:00