Changelog

What's New

The latest updates, improvements and fixes to Lamunix.com.

Latest

Maj 05-11

1.5.3
New Features
1
  • Added

    • Server vote webhooks — Servers now have full webhook parity with bots. A new serverWebhooks table was added to the database, along with a complete CRUD API at /api/servers/[id]/webhooks (GET, POST, DELETE). Every time a user votes for a server, a signed HTTP POST is sent to the configured URL with a HMAC-SHA256 X-Signature header so receivers can verify the payload is authentic.

    • Vote Webhook UI in server dashboard — Server owners can now manage their vote webhook directly from the dashboard. The new card lets you paste a webhook URL, optionally set or rotate the signing secret, save or remove the configuration, and see an "Active" badge when a webhook is configured. Success and error feedback is shown inline without a page reload.

    • Anonymous votes trigger webhooks — Previously, vote webhooks were only dispatched when the voter was authenticated. The webhook call has been moved outside the session guard, so anonymous votes now fire the webhook correctly just like logged-in votes do.

    • Dedicated CRON_SECRET for cron job authentication — All /api/cron/* endpoints previously validated incoming requests using SESSION_SECRET. A separate CRON_SECRET environment variable has been introduced so cron credentials are isolated from session credentials. Update your Railway / hosting environment variables accordingly.

🐛Bug Fixes
1
  • Fixed

    • Webhook HMAC signing was broken — The secret_hash column was storing a SHA-256 hash of the secret instead of the raw value. Because HMAC-SHA256 signing requires the original secret, all signatures were being computed incorrectly. The column has been renamed to secret and now stores the plaintext value. Existing webhook configs will need to be re-saved.

    • Raw database errors leaked to clients — When a Drizzle or Postgres query failed, the full exception (including table names, column names, and query fragments) was serialised into the API response. All server-side handlers now catch these low-level errors and return a generic 500 Internal Server Error message instead.

    • Rate limiting could be bypassed with an unknown IP — The vote rate-limiter built its Redis key as vote:<ip>. When the client IP could not be detected, the key fell back to vote:unknown, meaning every request from an undetectable IP shared the same bucket and effectively got unlimited votes. Requests where the IP cannot be determined now receive 400 Bad Request immediately.

    • 46+ empty catch blocks swallowed all errors silently — Across the entire API layer, exceptions were being caught and discarded with .catch(() => {}). This made it impossible to diagnose failures in Railway logs. Every instance has been replaced with .catch((err) => console.error('[tag] ...', err)) so errors are always visible.

    • useAuth failed silently on authentication errors — The fetchUser() function inside useAuth.ts had an empty error handler, so any failure during session hydration (expired token, network error, etc.) produced no output whatsoever. The catch block now logs [useAuth] fetchUser failed: with the full error.

    • Discord notifications were fire-and-forget with no error visibility — Bot and server approval/rejection notifications sent via the Discord bot had no .catch() handler, so a failed DM or channel message would disappear without a trace. All notification calls now log failures with console.error('[notify] ...').

♻️Refactors
1
  • Refactored

    • Removed any types from three Vue files — Untyped any references were replaced with explicit TypeScript interfaces to improve type safety and catch bugs at compile time:
      • admin/auctions.vue — new AuctionSlot and AuctionBid interfaces; all $fetch calls, modal refs, and helper functions (isLive, isUpcoming, openEditModal, pickWinner) are now fully typed.
      • compare.vue — new CompareItem, CompareRating, and CompareResult interfaces; winner(), itemAvatar(), and all $fetch calls are typed.
      • CollectionCard.vue — new Collection and CollectionOwner interfaces; defineProps<{ collection: any }>() replaced with a proper typed prop.

Maj 05-11

1.5.2
🐛Bug Fixes
2
  • 🔴 Critical Bug Fixes

    • Webhook now signs with plaintext secret instead of hash The secret_hash column in the webhooks table has been renamed to secret and now stores the raw plaintext secret (matching the userWebhooks pattern). HMAC-SHA256 signatures on vote webhooks are now correct and recipients can verify payloads again. Migration: 0013_webhook_secret_rename.sql

    • Anonymous votes now trigger webhooks Webhook delivery was wrapped inside an if (session) block, meaning votes from non-logged-in users never notified the bot owner. The call has been moved outside the block and now fires for all votes. Anonymous votes use 'anonymous' as the userId in the payload.

    • Raw database errors no longer exposed to the client POST /api/bots was returning the full Postgres error message to the browser, leaking table and column names. The error is now logged server-side only and the client receives a generic "Internal server error".

  • 🟠 High Priority Fixes

    • Cron endpoints now use a dedicated CRON_SECRET All 5 cron endpoints (check-status, reset-monthly-votes, update-trending, weekly-leaderboard, auto-vote) were authenticating with SESSION_SECRET, which is intended for user sessions only. A dedicated CRON_SECRET env variable has been added to nuxt.config.ts and all endpoints updated. Action required: Set CRON_SECRET as an environment variable on Railway and update cron job request headers.

    • Vote endpoints now reject requests with undetectable IP If getRequestIP() returned null, both vote handlers (/api/bots/[id]/vote and /api/servers/[id]/vote) fell back to 'unknown' as the rate limit key, meaning all such requests shared the same bucket and effectively bypassed rate limiting. They now return 400 Bad Request instead.

    • Server votes now send webhooks Bots had webhook notifications on votes — servers did not. Added:

      • serverWebhooks table in db/schema.ts
      • Migration: 0014_server_webhooks.sql
      • New route: GET/POST/DELETE /api/servers/[id]/webhooks
      • Server vote handler now sends webhooks for all votes (authenticated and anonymous)

Maj 2026

1.5.2
🐛Bug Fixes
1
  • Refactor API routes to update import paths and fix comment formatting

    • Updated import paths for database and utility modules in various API route files to use relative paths.
    • Corrected comment formatting in multiple files to ensure consistent use of dashes and avoid encoding issues.
    • Ensured all routes maintain proper functionality after changes to import statements.

April 25, 2026

V1.5.2
New Features
1
  • Partner badge

    User profile pages now show a Partner badge (🤝) if their Discord account is linked to an active partner entry. Linkage is managed from Admin → Partners via the "Linked User ID" field.

    • Tag dropdown

    Tags on "Add Bot" and "Add Server" are now a searchable dropdown. Typing filters the list live; pressing Enter selects the top match or adds a custom tag.

    • Custom tags

    Users can type any tag not in the preset list and add it directly (max 32 chars, max 5 tags total).

🐛Bug Fixes
1
  • welcome_channel_id unknown setting key

    Admin settings API rejected saves containing welcome_channel_id because it was missing from the allowed keys list. Now included.

    • Partners disappearing

    After the partner badge feature, the admin partners list went blank. The /api/users/[id] endpoint queried partners.user_id which didn't exist in the DB yet, crashing the request. Fixed by adding the missing ALTER TABLE to the startup migration plugin.

    • User profile pages returning 404

    Same root cause as the partners bug above. Fixed alongside it.

💅UI / Styling
1
  • Massive tag expansion

    Preset tag lists greatly expanded: Bots now has ~270 tags across 14 categories; Servers has ~295 tags across 12 categories including 25 language/regional tags, new gaming titles, music genres, and more.

April 25, 2026

V1.5.1
New Features
1
  • Bot of the Week

    New homepage section that automatically highlights the bot with the most votes in the past 7 days. The winner is fetched from a new /api/bot-of-week endpoint, cached in Redis for 1 hour, and displayed in a clean minimal card with avatar, stats (total votes + servers joined), and direct links to add or view the bot.

    • Changelog system

    Full manual changelog system built from scratch:

    • New site_changelogs table (id, version, title, changes JSON, publishedAt) created via server/plugins/migrate.ts
    • Public /changelog page at app/pages/changelog.vue clean timeline UI, no GitHub references, entries grouped by change type with color-coded badges
    • Admin API at server/routes/api/admin/changelog.ts GET (list all), POST (create), DELETE (by id), all protected by requireAdmin
    • Admin editor at app/pages/admin/changelog.vue full split-editor layout with live preview
🐛Bug Fixes
1
  • Bot avatar not loading on Bot of the Week card

    The avatar field in the database stores a full URL, not a Discord avatar hash. The homepage was incorrectly building a CDN URL from it. Fixed to use botOfWeek.avatar directly, with an @error fallback to the default Discord embed avatar based on discordId % 6.

💅UI / Styling
1
  • Bot of the Week card redesign*

    Replaced the overly complex layered card (diagonal lines, animated shimmer border, pulsing vote pill) with a clean, minimal card that fits the rest of the site's design language: subtle gold top-border accent, soft background glow blurs, crown 👑 icon positioned above the avatar, and a single stats pill-bar.

    • Admin Changelog editor redesign

    Replaced the cramped inline form (single-line <input> per change + plain <select> dropdown) with a full split-editor:

    • Left panel: meta fields (title, version, optional publish date) + change items with auto-resizing <textarea> and clickable color-coded type badges instead of a dropdown

    • Right panel: sticky live preview that mirrors exactly how the entry will look on /changelog, updating reactively as you type

    • Editor is a separate full-page mode (not a modal), accessed via "New Entry" button

    • Footer Added "Changelog" link to the site footer pointing to /changelog

    • Admin dashboard Added "Changelog Manager" card on the admin index page with a book icon and indigo color scheme, linking to /admin/changelog