Commit Graph
11 Commits
Author SHA1 Message Date
Simo 5b4228261a Reapply "Add missing admin action files and navigation links"
This reverts commit 4d515bc400.
2026-07-11 20:52:56 +02:00
Simo 4d515bc400 Revert "Add missing admin action files and navigation links"
This reverts commit 41be6835bf.
2026-07-11 20:37:56 +02:00
openhands 41be6835bf Add missing admin action files and navigation links
- Add 11 missing server action files: badges, bulk-users, catalog, catalog-bc, catalog-items, import-badges, import-furni, multi-account-detect, permissions, rooms, soundtracks
- Add missing admin navigation links: tickets, sounds, translations, import, radio sub-pages
- Add translation keys for all new navigation items
2026-07-11 12:01:05 +02:00
openhands 942bc6fc8d Security hardening, code quality, and ESLint setup
- Remove production DB dump (db_backup_*.sql) and update.log from git tracking
- Add DB backups to .gitignore
- Replace all console.log/console.error with structured logger module
- Translate Dutch error messages to English (link-discord.ts)
- Remove dead code blocks (register-form.tsx false && pattern)
- Add ESLint flat config with TypeScript, React, Next.js, jsx-a11y, and security plugins
- Add Prettier config
- Add eslint-plugin-security for security-aware linting
- Fix all 119+ ESLint warnings across the codebase:
  - Resolve security/detect-object-injection with safe access patterns
  - Resolve security/detect-non-literal-fs-filename with path traversal validation
  - Replace <img> with next/image <Image> component
  - Remove unused variables and imports
  - Replace non-null assertions with proper type guards
  - Replace <a> with <Link> for internal navigation
  - Use next/script Script component for external scripts
- Fix setState-in-useEffect anti-patterns (navbar-color-picker, logo-generator, theme-switcher)
- Add lint and format scripts to package.json

All checks: typecheck ✓, tests 58/58 ✓, lint 0 errors 0 warnings ✓
2026-07-10 22:48:22 +02:00
openhands 8bcbc501ba Performance, SEO, a11y, and code quality improvements
CI / check (push) Has been cancelled
1. Performance: 25 pages switched from force-dynamic to revalidate=300 (ISR);
   2 pages (community, developers) now fully static (SSG)
2. DB indexes: Added @@index on foreign keys for WebsiteArticles,
   WebsiteArticleReactions, WebsiteArticleComments, WebsiteHelpCenterTickets,
   WebsiteShopArticles, RadioSongRequests, StaffActivities
3. SEO: Added robots.ts, sitemap.ts, canonical URLs, Open Graph + Twitter
   Card metadata on root layout and news articles
4. A11Y: Replaced <details>/<summary> dropdowns with accessible button-based
   NavDropdown (aria-expanded, aria-haspopup, role=menu). MobileNav now
   uses translated aria-label, aria-expanded, aria-controls, role=menu
5. Code quality: Added try/catch to updateArticle/deleteArticle; deleteArticle
   now uses prisma. for atomicity
6. CI/CD: Added GitHub Actions workflow (typecheck + test)
7. i18n: Added openMenu/closeMenu keys to all 6 locales
8. Observability: Health endpoint now checks SMTP reachability when configured
9. Loading states: Added loading.tsx for root, admin, and news sections
10. Word filter cache: Added 60s TTL auto-refresh instead of manual cache bust
2026-07-04 19:41:04 +02:00
Simo e004dfedaf i18n: translate all public page bodies (EN + IT)
Internationalised the ~44 public pages with next-intl (the shell was
already translated). Each page now pulls its copy from a "pages.<slug>"
namespace via getTranslations (server) / useTranslations (client); the
EN + IT catalogs were authored by parallel agents and merged centrally,
with natural Italian (ICU plurals) and it backfilled from en for any
gap. request.ts gained getMessageFallback/onError so a missing key
degrades to the English value, never a raw key.

Behaviour unchanged (only display text moved to t() calls; queries,
actions, fields, ContentCard structure preserved). Verified on the prod
server: with NEXT_LOCALE=it, home/community/staff/news/shop/rankings all
render Italian copy, no raw-key leakage; English unchanged. The nav
language switcher toggles EN/IT live. tsc 0, vitest 49/49, next build 0.

Admin pages intentionally left in English (staff tooling).
2026-06-28 20:40:06 +02:00
Simo 6f15e0c8a3 Production hardening: error pages, rate limiting, metadata
- Custom not-found (404) + error / global-error boundaries, styled with
  the public design system; raw errors logged, never shown to users.
- In-process rate limiter (src/lib/rate-limit.ts) wired into the abuse-
  prone flows: login (10/5min/IP), register (5/10min/IP), password-reset
  request (3/15min/IP), keyed by the proxy-forwarded client IP.
- SEO/metadata: root generateMetadata sets a `%s · {hotel}` title
  template from the live hotel_name; dynamic generateMetadata on
  news/[slug] (article title + excerpt) and u/[username] (name + motto);
  static titles on 12 primary public pages.
- env.ts: added the vars introduced since (PASSWORD_HASH, OPENAI_API_KEY,
  DISCORD_WEBHOOK_URL, ALERT_EMAIL, PAYPAL_*) so env stays authoritative.

Verified on the prod server: /missing → 404 card, news title renders
"News · Habbo". tsc 0, vitest 49/49, next build 0.
2026-06-28 20:12:12 +02:00
Simo e9ea19795a Adapt + improve all public pages to the atom design system
Extended the same design-system treatment to the public site, faithful
to AtomCMS's "atom" theme. New src/components/public/ui.tsx provides the
signature atom building blocks + a scoped CSS layer:
- ContentCard: surface card with a primary-tinted header (icon circle +
  title + subtitle) and padded body — the atom content-card, used as
  every page's header and section wrapper.
- StatBlock / stat-grid, EmptyState, OnlineBadge (online/offline pill),
  RankBadge (medals for the top 3), and responsive .card-grid helpers.

Swept ~45 public pages (home/community/rankings hand-built as the
reference; the rest via parallel agents that read the schema and
preserved every query, server action, auth gate and field name):
heroes → ContentCard headers, lists → card-grids in ContentCards,
"no X" → EmptyState, status → OnlineBadge/RankBadge. The leaderboard
gained Credits/Diamonds/Duckets tabs (usersCurrency).

Behaviour unchanged. Verified on the prod server against amx_test: 15+
public pages render the content-cards/grids with real data, no errors;
computed styles confirm the tinted header, icon circle, medal + online
pills. Fixed an undefined --color-golden ref. tsc 0, vitest 49/49,
next build 0.
2026-06-28 19:28:36 +02:00
Simo e668fa85ec Add 2FA, email + password reset, and batch-7 pages
Auth (hand-built on the auth core):
- 2FA: User model gains two_factor_secret/recovery_codes/confirmed_at (+ idempotent
  MariaDB migration). authorize() requires a valid TOTP code when 2FA is confirmed
  (secret decrypted via Laravel APP_KEY, fail-closed). Two-step login (precheckLogin
  reveals the code field). /settings/2fa enable/confirm/disable flow.
- Password reset: nodemailer email service; PasswordReset model + migration;
  /forgot (request, generic response) + /reset (token sha256 + 1h TTL, sets argon2id
  hash). Login links to forgot.

Batch 7 (parallel agents): /admin/commandocentrum (RCON controls + emulator_errors),
social write actions (friend request + guild forum new thread), /help/[category],
/badges (public). env: APP_KEY, APP_URL, SMTP_*. Nav extended.

Verified: tsc exit 0, vitest 48/48, next build exit 0 (64 page routes).
2026-06-28 14:25:19 +02:00
Simo 486ce51559 Add social login (Discord/Google) + batch-6 pages
Auth: NextAuth Discord + Google providers (enabled when env id+secret set);
OAuth signIn allowed only if a hotel account matches the email; jwt binds the
session to that account (id/rank/username). Login page gets social buttons.

Batch 6 (parallel agents): /friends (messenger_friendships), /guilds/[id]/forum
(threads), /admin/navigation (navigator config), /admin/maintenance (toggle
maintenance settings), /admin/alerts (alert_logs + send hotel alert via RCON).
Header (Friends) + admin nav (Alerts/Maintenance/Navigator) extended.

Verified: tsc exit 0, vitest 48/48, next build exit 0 (57 page routes).
2026-06-28 14:13:41 +02:00
Simo e8be0461d8 Add niche admin + public expansions + self-host Nunito font (batches 3-4)
Built via two more parallel agent workflows (read schema -> return files),
integrated + verified.

Admin: /admin/emulator (emulator_settings + emulator_texts key/value editor),
/admin/badges (give-badge via RCON), /admin/rare-values (CRUD), /admin/housekeeping
(CRUD), /admin/email-templates (CRUD), /admin/photos (moderation).
Public: /rares (+[category]), /leaderboard (credits/diamonds/duckets),
/guilds (+[id] members), /redeem (voucher -> sendCurrency).
Expanded: /u/[username] now shows badges + photos + guestbook (post form);
/news/[slug] now shows reactions + comments (comment form). Reactions tallied
in JS (Prisma groupBy typing avoided).
Self-hosted Nunito via next/font/google wired to --font-nunito (the atom theme
font, no runtime external fetch). Header + admin nav extended.

Verified: tsc exit 0, vitest 48/48, next build exit 0.
2026-06-28 13:44:23 +02:00