wishlist Home

Changelog

You're currently on v0.3.3. New here? Make a wishlist.

v0.3.3 · Sign out actually signs you out

3 May 2026
Fixed
  • Sign-out button on the dashboard didn't clear the session. The form posted directly to /api/auth/signout, but NextAuth v5 requires a CSRF token on that endpoint, so the request was rejected silently and the cookie persisted. Hitting the landing page after "signing out" still sent you back to the dashboard. Replaced with a server-action signOut() call that handles the cookie and redirect properly.

v0.3.2 · Fix React hydration mismatch on priced items

3 May 2026
Fixed
  • Hydration mismatch (React #418) on every priced item with an ISO currency code. formatPrice() called Intl.NumberFormat with an undefined locale, which resolved to en-US on the Node server but to the user's browser locale on the client — different formatted output for the same number. The currency dropdown shipped in 0.3.0 made this latent bug fire for the first time, since users could now pick USD/EUR/NOK and trigger the ISO branch reliably. Pinned to 'en-US' on both sides.
  • Same root cause on the dashboard's "Updated …" timestamp — toLocaleDateString() with no arguments differed between server and browser locale. Pinned to en-GB DD-MMM-YYYY in UTC, matching the changelog and legal-page pattern.

v0.3.1 · Login no longer redirects to localhost

29 April 2026
Fixed
  • Login redirected to localhost in production when AUTH_URL was a stale .env value copied from .env.example. NextAuth now uses the request's Host header instead (trustHost: true), so the redirect always goes back to whichever host the user actually came from.
Changed
  • .env.example clarifies that AUTH_URL is only used for OG metadata + the share URL fallback now, not for auth callbacks.

v0.3.0 · Customization, conversation, and the buzz on the wrist

26 April 2026

Two things this release does: makes a wishlist feel like *yours* (inline title/description edit, per-wishlist accent picker with nine palettes, currency dropdown that auto-detects from your browser locale on signup), and closes the gift-giver feedback loop (an owner-only activity feed that records every item edit / reorder / reservation, plus push notifications when someone reserves a gift on a shared list — both respect the "hide reservations" toggle so the surprise stays intact).

Added
  • Inline edit on the wishlist hero — pencil flips title and description into editable inputs, save/cancel without leaving the page. PATCH /api/wishlists/[id] (the route already supported the fields; this is the missing UI).
  • Per-wishlist accent picker — nine named palettes (pink, violet, emerald, amber, sky, fuchsia, rose, teal, indigo) plus an Auto fallback that hashes from the wishlist id. Stored as wishlist.accent and applied to the hero panel on both the owner detail page and the public /share/[token] viewer, so the share link feels branded to the occasion.
  • Currency dropdown — replaces the free-text currency field on items with a list of ~25 common ISO codes plus a Custom… escape hatch. New users get a defaultCurrency seeded from their Accept-Language header at signup (en-US → USD, nb-NO → NOK, etc.), and that default pre-fills the picker on every new item.
  • Activity feed per wishlist — owner-only collapsible panel on /wishlists/[id] that lists the last 50 events: item added/edited/deleted/reordered, wishlist edited, reservation created/released. Backed by a new WishlistActivity collection and recordActivity() helper hooked into every mutating route. Reserver names are redacted to "Someone" unless revealReservations is on.
  • Push notifications — owners get a notification when someone reserves a gift on a shared wishlist (only fires for installed PWAs). New PushSubscription model, lib/sendPush.ts with VAPID, /api/push subscribe/unsubscribe, PushNotificationToggle on the dashboard. Push body redacts the reserver name when revealReservations is off, so the surprise survives even on the lock screen.
  • Service worker push + notificationclick handlers in /public/sw.js. SW VERSION bumped to v2 so existing installs pick up the new handlers on next launch.
  • web-push dependency + @types/web-push.
  • NEXT_PUBLIC_VAPID_PUBLIC_KEY build arg in the Dockerfile (must be inlined at client-bundle build time, not runtime), with VAPID_PRIVATE_KEY + VAPID_SUBJECT documented in .env.example.
Changed
  • OwnerItemCard EditForm gained a Currency row alongside Price, using the new dropdown.
  • Hero gradient definitions consolidated into lib/accents.ts — both /wishlists/[id] and /share/[token] now resolve their accent from the same source instead of holding duplicate inline tables.
  • User schema gained an optional defaultCurrency field.
  • Wishlist schema gained an optional accent field (enum of the nine accent names).
Security
  • Activity feed sanitizes the reserver name on read — even if revealReservations is later toggled off, owners viewing past activity see "Someone" rather than the original reserver.
  • Push notifications and activity entries both honor the same revealReservations gate, so there's no side-channel that leaks who reserved what.

v0.2.0 · First real release — light rebrand, PWA, reservations

26 April 2026

Big consolidation release. Pivot away from the dark-slate noobventure-default to a warm cream-and-pink theme with a Fraunces display serif, gift-themed side decorations, and confetti backgrounds — wishlist now reads as celebratory, not productivity. Adds the gift-giver killer feature (anonymous reservations on shared wishlists), drag-to-reorder + inline edit on items, password reset, a toast notification system that replaces every browser confirm() and silent action, and a fully installable PWA. Plus the legal pages and this changelog.

Added
  • Reservations on shared wishlists — anonymous gift-givers click "I'll get this", type a name, and the item shows as reserved to other viewers (with the same browser able to undo via cookie). Owner doesn't see who reserved what by default to preserve the surprise; opt-in toggle per wishlist for registries.
  • Inline item edit — pencil icon flips a card into a full edit form. PATCH /api/wishlists/[id]/items/[itemId] with the same Auto-fill button as the create form.
  • Drag-to-reorder items — HTML5 native drag with optimistic local reorder and bulk position persist via POST /api/wishlists/[id]/items/reorder.
  • Password reset flow — /forgot-password and /reset-password/[token] backed by Mailjet REST + bcrypt-hashed token + 1h expiry. Branded HTML email with the wishlist mark.
  • PWA — installable on Android (one-tap banner) and iOS (Share → Add to Home Screen instructions). Service worker with stale-while-revalidate navigation, cache-first for /_next/static, never caches /api. Dynamic apple-touch-icon and Android maskable icon generated by Next/og.
  • Toast notification system — global ToastProvider with success / error / info / warn variants, plus a styled confirm modal that replaces every browser confirm(). Hooked up across dashboard, wishlist detail, item card, and share page.
  • Legal pages — Privacy, Terms, Cookies under a shared (legal) route group with cross-links between them.
  • This changelog page (/changelog) backed by a typed lib/changelog.ts data file. Footer version badge pulses pink until you open the page.
  • Side decor — nine floating gift-themed SVG illustrations (gift boxes, balloons, ribbons, sparkles, hearts) in the wide-screen margins, each on a staggered float animation. Hidden below lg.
  • Landing page rebuild — Fraunces display serif, mock browser-chrome wishlist preview, "For every moment" occasion grid (8 cards: birthday/wedding/baby/holiday/housewarming/etc), 3-step "How it works" strip, testimonial-style quote block, FAQ accordion, vivid CTA card.
  • Auth split layout — login / register / forgot / reset all share an AuthShell with a bold pink/rose marketing column on the right (mock browser preview + feature checklist + animated logo).
  • Hero gradient panels on /wishlists/[id] and /share/[token] — vibrant gradient picked stably from the wishlist id, with stats row (items / must-have / estimated total) and confetti.
  • Dashboard greeting + stats row (lists / items / shared) with stable per-id gradient backdrops on each wishlist card.
Changed
  • Visual identity — switched from dark slate (#07040d) to warm cream (#fff7f4) with peach/blush/lavender ambient gradients. Pink/coral accents replace indigo. Fraunces serif paired with Geist sans for headlines.
  • Footer — added Privacy / Cookies / Terms / Changelog links and replaced the plain version text with a VersionBadge that pulses for unseen versions.
  • Cookie names prefixed with `wishlist.` so dev sessions don't collide with sibling stacklog cookies on localhost.
Fixed
  • serialize() type signature now correctly maps Mongoose ObjectId/Date to string in the output type. Caught at production build time only — Turbopack dev mode skipped strict type-check.
  • Dashboard item-count aggregation no longer matches every WishlistItem when the user has zero wishlists.
Security
  • OG preview endpoint (/api/og) is auth-gated with an SSRF guard rejecting private hosts, byte-cap, and per-IP rate limit so it can't be abused as an open server-side fetch proxy.
  • Reservation endpoint rate-limited per IP. Reserver tokens are SHA-256 hashed before storage so a leaked database wouldn't expose the cookie value.
  • Password reset always returns the same response regardless of whether the email exists — prevents email enumeration.
  • Password reset tokens are stored as SHA-256 hashes (not plaintext) with a 1-hour expiry.

v0.1.0 · Initial scaffold

22 April 2026

First working version. Email/password auth (with optional Google OAuth), private/link wishlist visibility with stable share tokens, items with title/url/image/price/notes/priority, OG-preview helper that auto-fills new items from any product URL, owner dashboard, public /share/[token] viewer, multi-stage Dockerfile + docker-compose. Built on the noobventure stack (Next.js 16, React 19, Tailwind 4, Mongoose, next-auth v5).

Added
  • Email/password registration and login with bcrypt + per-account login rate limiting.
  • Optional Google OAuth — auto-enables when AUTH_GOOGLE_ID and AUTH_GOOGLE_SECRET env vars are set.
  • Wishlist + WishlistItem MongoDB models with private vs link visibility and stable share tokens.
  • Owner dashboard listing all your wishlists, with create / delete.
  • Wishlist detail page — add items, set priority, view all items.
  • Public /share/[token] viewer — anyone with the link can view a link-visibility wishlist without an account.
  • /api/og URL preview helper that scrapes OpenGraph + Twitter card meta and product:price for auto-fill.
  • Multi-stage Dockerfile (Node 20 alpine, standalone output) + docker-compose with external wishlist-network on Unraid.
  • Footer with version number sourced from package.json.

Format inspired by Keep a Changelog and semver.