Changelog
All notable changes to Generous.nz are recorded here, grouped by version. Every deployed build has a version number, a git tag, and an entry below.
Versioning scheme
Versions follow MAJOR.MINOR.PATCH:
- 0.x — pre-launch. Minor bumps mark a completed build phase or major feature set; patches are bug fixes on the current build.
- 1.0.0 — first public launch.
- 1.x+ — post-launch: minor = new features, patch = fixes, major = breaking changes or significant re-architecture.
Each version is tagged in git (v0.2.0) and the current version is kept in
package.json. See docs/version-control.md for how to cut a release.
[0.9.46] — 2026-08-24
Clear duplicate-SKU error for wholesale products + admin error log.
Fixed
- Adding or editing a wholesale catalogue product with a SKU/code already used in your catalogue now shows a clear message ("That SKU/code is already used in your catalogue…") instead of the generic "Something went wrong". The same applies to bulk CSV imports, which now label the offending row with the duplicate SKU.
Added
- Admin → Error log: unexpected server errors are recorded with the
route, error code, user, time and stack trace, and are browsable from the
admin sidebar (next to the email log). New
SystemErrorLogtable (migration0032_system_error_log).
[0.9.45] — 2026-08-24
Fundraiser (donation page) expiry with a no-expiry option.
Added
- New Fundraiser expiry choice when creating a fundraiser: No expiry (default), 15, 30, 45 or 90 days. Pages with an expiry auto-close on that date; pages without one stay open indefinitely.
- Dashboard fundraiser cards now show the current status ("No expiry",
"Expires
" or "Closed ") with a control to set, extend or remove the expiry — including reopening a closed page. - Public fundraiser pages show "Accepting donations until
", and once closed display a "This fundraiser closed" notice with donations, orders, tickets and supporter-page signups switched off.
Changed
- Closed fundraisers stop accepting donations, purchases, raffle/event tickets, subscriptions and new supporter pages (enforced server-side, not just hidden in the UI).
- Closed fundraisers are filtered out of the public fundraiser list, Explore results and the wholesale store picker, and can't have new wholesale items added to them.
- New database column
Fundraiser.expiresAt(migration0031_fundraiser_expiry).
[0.9.44] — 2026-08-24
Better passkey retry UX.
Fixed
- If the passkey prompt is cancelled or fails, the login page now returns to the password step with a clear message instead of leaving the user stuck on a "Continue with passkey" button whose one-time grant was already consumed.
[0.9.43] — 2026-08-24
Enforce the password-before-passkey gate.
Security
- The Auth.js passkey provider issues an authentication challenge even when
getUserInforeturns null, which would have let a passkey be used without the password.getUserInfonow rejects (throws) any unauthenticated request that doesn't carry a valid, single-use password-verified grant, so a challenge can only ever be minted after the password is confirmed.
[0.9.42] — 2026-08-24
Fix passkey provider startup.
Fixed
- The Auth.js WebAuthn provider refused to start without
experimental.enableWebAuthn, which surfaced as a "server configuration" error on/api/auth/providers. The flag is now set, so the passkey 2FA provider loads correctly (v0.9.41's runtime fix).
[0.9.41] — 2026-08-24
Account tab (change password + two-factor login with passkeys, including Heylogin).
Added
- New Account item at the bottom of the dashboard sidebar, available to
every signed-in user, with two sections:
- Change password — verify the current password, set a new one. Social (Google/Apple) accounts without a password can set their first one here.
- Two-factor login (passkeys) — add and remove passkeys. Works with Heylogin, Windows Hello, Touch ID, Face ID and hardware security keys.
- Passkey sign-in after your password: users with a passkey enrolled now complete two steps — password, then a passkey confirmation. The password alone can no longer create a session for those accounts.
- New
Authenticatordatabase model (migration0030_passkeys) via the Auth.js built-in passkey provider; no third-party auth service required. - Admin recovery tool on the Users page: "Remove passkeys" clears all 2FA credentials for an account if someone loses their device.
- Audit log entries for password changes and passkey add/remove.
Changed
- Login flow now checks the password first (
/api/auth/login-step1) and only then issues a short-lived, single-use passkey challenge, so a passkey can never be used as the only credential. - Dependencies:
@simplewebauthn/browserand@simplewebauthn/server(the peer packages the Auth.js passkey provider uses).
Security
- Rate limiting on password verification and password-change endpoints.
- WebAuthn challenges are single-use, expire after five minutes, and are bound to the password-verified user.
[0.9.40] — 2026-08-24
Fix "client-side exception" from stale cached assets after deploys.
Changed
- The service worker cache version was bumped so every visitor's browser drops old cached pages/scripts after this update. Stale HTML from an older build could reference JS files the new build removed, which caused the "Application error: a client-side exception" screen after rapid deploys.
- The service worker no longer caches error responses, so a brief 500 during a deploy can't become a broken cached page.
[0.9.39] — 2026-08-24
Account-aware dashboard overview.
Changed
- Approved wholesalers now land on a business-focused overview instead of the fundraiser dashboard: paid-to-you total, orders/units, catalogue product count, awaiting-fulfilment count, a 30-day sales chart, their wholesale tool links and their most popular products.
- Fundraisers keep the existing fundraising overview unchanged.