Security hardening, activity log, extension shortcuts, and sync reliability — Structured server-side activity logging, CSP and SSRF rate limits (plus a dedicated status-ping bucket), DNS IP pinning, and startup validation for self-hosters. Dashboard data revision uses content hashes and detects name/URL/shortcut drift. Config bookmark saves keep layout and weather settings intact while category moves sync to the dashboard. Browser extension can save optional shortcuts with auto-suggest. What's new modal shows the 7 most recent releases on scroll. General Essentials/Advanced toggle preserves toolbar position; Playwright E2E suite fully green.
Security & server
- new Activity log —
activity_log.go: JSON lines forbookmark.add/edit/delete/move/import, status pings (10-minute dedupe unlessrefresh=1), optional opens, and security events. Env:NEXTDASH_ACTIVITY_LOG(mutate,status,open,security,off),NEXTDASH_ACTIVITY_LOG_PERSIST,NEXTDASH_ACTIVITY_LOG_FILE. - new CSP headers —
security.gosends Content-Security-Policy on HTML responses;NEXTDASH_CSP=offdisables. - fix CSP weather —
connect-srcallows Open-Meteo geocoding and forecast APIs so the dashboard weather widget works under CSP (security.go). - new Rate limits —
rate_limit.go: per-IP limits on outbound fetches (NEXTDASH_OUTBOUND_REQUESTS_PER_MIN, default 120) and SSRF-sensitive APIs (NEXTDASH_SSRF_API_RATE_PER_MIN, default 60); separate status ping bucket (NEXTDASH_STATUS_PING_RATE_PER_MIN, default 300); HTTP 429 + optional security activity event. - fix DNS IP pinning —
host_ip_pin.go: pin resolved public IPs for ~2 minutes on outbound dials (url_safety.go). - fix Startup validation —
startup_validate.go: validatePORT(1–65535) and writableNEXTDASH_DATA_DIRbefore listen (main.go). - fix Request context —
pingURLDetailed(ctx),fetchBookmarkPreview(ctx);status.go,handlers.go,favicon_prefetch.gopassr.Context().
Dashboard & sync
- fix Hash-based data revision —
GetDataRevisionhashes file contents instead of mtimes (handlers.go,models.go). - fix Stale cache: name, URL, shortcut —
isPageBookmarksStale()compares all bookmark fields; tests indashboard-datacoverage. - fix Preview metadata cache — in-memory cache with
previewCacheDirty, periodic flush (~30 s) and shutdown flush (cache_store.go,handlers.go). - fix Tag popover save contract — popover reports failure when bookmark save fails.
- fix Preview metadata save toast — user notification when preview persist fails.
- fix Tag-filter bulk delete — success check and page-cache sync after bulk delete.
- fix Shared cache-bust tokens —
asset_versions.gocentralizes cross-page tokens; dashboard/config/health templates use{{.Assets.*}}. - fix Config → dashboard category sync — bookmark saves keep settings sync (layout chrome) and force a full dashboard render so category moves appear in the correct column; incremental patch also reparents rows across columns (
config-persistence.js,dashboard-config-sync.js,dashboard-render-incremental.js). - fix Config save layout regression — revert structure-only sync on
saveChanges()(392c1f6); structure refresh still reappliessetupDOMfor tags/finders updates (dashboard-config-sync.js). - fix Device layout overrides — bookmark-only config save no longer clears device-specific dashboard settings when server settings are unchanged (
config-persistence.js). - fix Config save settings guard —
saveChanges()syncs General UI and POSTs settings only when settings actually changed; theme/layout autosave skipsupdateFromUI; regression test for bookmark-only save (config-persistence.js,config-settings-guard-1). - fix Status ping rate limit — bookmark
/api/pinguses dedicated limiter; client treats HTTP 429 as rate-limited instead of offline (status.go,status.js,status-rate-limit-1).
Browser extension
- new Optional shortcut field —
extension/popup.html/js; auto-suggest viasuggestBookmarkShortcut()insave-common.js. - fix Shortcut on save —
postAddBookmarksends resolved shortcut (no longer always''). - fix 409 duplicate shortcut — conflict handling in popup; i18n in
extension/locales/{en,nl,de,fr}.json.
What's new modal
- new 7-release history —
MAX_VISIBLE_RELEASES = 7; manifest sorted by version tag; lazy-load per-release JSON unchanged (whats-new-v121).
Config
- fix General layer scroll —
preserveScrollcomparesprevLayertonextLayer(was always false before assignment);preserveScrollAnchorruns a synchronous fix beforerequestAnimationFrame(general-layer-scroll-anchor-2). - fix Status re-check default — General → Status defaults to every 5 minutes for background bookmark reachability checks (
status-recheck-interval-select).
Developer & docs
- fix README, MANUAL, Config Help — self-hosting security, env-var table, extension shortcuts, Help sections Browser extension and Security & self-hosting (EN/NL/DE/FR);
docker-compose.prod.ymlcommented prod env block. - fix CI on
main—release-to-main.sh+ci.ymlkeep tests onmainafter prune. - fix Playwright E2E — full suite green: finders
toBeHidden, config C14 snapshot baseline inwaitForConfigReady, tags#tags-filter-empty-hintselector, layout-nudge manual replay (AUTO_PROMO_DISABLED), General toolbar scroll within Advanced max range; fresh tempNEXTDASH_DATA_DIRper managed run;config-dashboard-category-sync.spec.jsand structure-sync assertion on bookmark save. - fix Tests — activity log, data-revision hash, stale name/url/shortcut,
asset_versions_test.godrift check. - fix Cache-bust —
whats-new-v124data version;config-settings-guard-1onconfig-persistence.js;status-rate-limit-1onstatus.js;config-category-sync-1ondashboard-render-incremental.jsanddashboard-bookmark-rows.js;general-layer-scroll-anchor-2onconfig-general-layers.js. - fix What's new sort order — manifest sorts by version tag first (
v2026.07.03beforev2026.07.02);releasedAtis tie-breaker only (whats-new-v120). - fix What's new manifest —
index.jsonregenerated from on-disk release JSON (tag order); CI checks index ↔ file parity; modal usesid || tagwhen fetching (whats-new-v121).