Releases: Manak-hash/LinkBreeze
Release list
LinkBreeze v1.1.4
Fixed
- CI badge showed failing on default branch — The CI workflow only triggered on
pull_request, so no runs ever executed onmain. Shields.io checks the default branch, causing the README badge to always show "failing". Addedpush: branches: [main]to the workflow triggers. - Theme import card didn't state the expected file format (#44) — The import/export card description was ambiguous about which file type to use. The system is and has always been JSON-only. The card description and helper text now explicitly say
.json. - Type error in manifest test —
manifest.test.tscalled.startsWith()onstart_urltyped asunknown. Added the sameas stringcast already used forshort_name. - Image background overlay rendered as a dark gradient —
resolveBackground()for image backgrounds built the overlay as a gradient with alpha only on the first stop. Fixed to a uniform translucent layer, and opacity 0 now skips the overlay entirely. modecolumn comment claimedautowas supported — Comment documenteddark, light, autobut onlydarkandlightare valid. Comment aligned to reality.- Click-inflation attack on
/go/:id(security) — The JS-free click redirect endpoint had no rate limit. Now applies the same 60 req/min/IP throttle as the JS tracking endpoint. - "Zero client JavaScript" claim was inaccurate — Inline
onclickhandlers for mailto/tel links are technically client-side JS. Claims softened to "zero client-side JS bundles" across docs.
Added
- Theme system regression matrix (69 tests) — Locks the contract between DB schema defaults, Zod validator, token resolver, and the 9 preset definitions. Prevents the drift bugs seen in v1.1.2 and v1.1.3.
- Image overlay regression test (4 tests) — Pins the fixed overlay render behavior.
- PWA manifest upgrade (closes #18) — Added
start_url,scope,orientation, maskable icons, and screenshots to the manifest for proper install prompt support. - Manifest contract test (6 tests) — Parses
public/site.webmanifestand asserts install-critical fields.
Changed
- Extracted theme presets and Zod schema into modules — Enables the regression matrix tests without importing server-only code.
- Dependency bumps — Merged minor-and-patch group and vitest 3→4. Closed typescript 7, eslint 10, and node 26 as blocked.
- Disabled theme font preloading (perf) — 483KB → ~20KB on public pages. ~60% transfer reduction. The browser only downloads the active theme's font.
Full changelog: https://github.com/Manak-hash/LinkBreeze/blob/main/CHANGELOG.md#114---2026-07-22
v1.1.3
What's Changed
🐛 Fixed
- Fresh Docker deploy crash (migration 0005 fails on startup) — Migrations 0005 and 0006 were missing
--> statement-breakpointmarkers.better-sqlite3only accepts one statement perprepare()call, so the multi-statement files crashed the server on every fresh deploy. Added the missing breakpoints. Fixes #38. - Preset themes ignored numeric
fontScalevalues — Presets like Editorial Paper (110%), Retro Sunset (120%) silently fell through to the default 15px. Now correctly treated as percentages. Pastel Softpreset rendered with wrong shadow —resolveShadow()was missing the"soft"case. Added.resolveSpacing()density values mismatched the enum —"relaxed"was dead code (fell to default alongside"normal"). Now correctly returns 16px for more spacing.- Theme name conflicts on duplicate and import — Both operations now reject names already in use instead of creating silent duplicates.
🔒 Security
- Password complexity requirements — Setup and change-password now require at least one lowercase letter, one uppercase letter, and one number. Closes #7.
- Open-redirect hardening on
/go/:id— Runtime protocol check added; onlyhttp:andhttps:URLs are accepted for redirect. - OG image and sitemap routes now respect
BASE_URLenv var — Both routes were missed in the v1.1.2 host-header injection fix. They fully trustedx-forwarded-host. Now fixed.
Changed
- Theme export schema density default:
"comfortable"→"normal"(matching the DB schema and Zod enum).
Full changelog: https://github.com/Manak-hash/LinkBreeze/blob/v1.1.3/CHANGELOG.md
v1.1.2
Security
- Forgeable admin sessions when
SECRET_KEYunset (HIGH) —getSecret()now throws in production ifSECRET_KEYis not configured, instead of falling back to a public default. Dev mode still uses a dev-only secret. - XFF-spoofing brute-force bypass (HIGH) — Added a global login rate limit (15/min) on top of the existing per-IP limit (5/min). Closes the vector where rotating
X-Forwarded-Forbypasses per-IP throttling. - Subscriber email DoS (HIGH) —
subscribers.emailnow has a UNIQUE constraint. Migration 0005 dedupes existing rows before creating the index. Per-IP rate limit (10/min) added to the subscribe endpoint. - Stored XSS via backup restore (MEDIUM) —
restoreBackup()now filtersjavascript:URLs throughisAllowedLinkUrl(). Malicious links are silently dropped. - Host-header injection for QR/OG/canonical URLs (MEDIUM) — Optional
BASE_URLenv var takes priority over all forwarded headers when generating absolute URLs.
Fixed
- Themes not seeding on fresh deploy — only Aurora appears (#35) —
getActiveTheme()had an inline fallback that seeded a single Aurora theme when the DB was empty. Because the public page calls it before the admin page is visited, the other 8 presets never got seeded. Fixed:getActiveTheme()now delegates toseedThemesIfEmpty(). - Theme changes silently not saved (#35) —
densitycolumn defaulted to"comfortable"but the Zod validator only acceptscompact/normal/relaxed. The entire save payload was rejected bysafeParseand the error was swallowed client-side. Fixed: schema default, migration 0006, and errors now surfaced in the UI. - Floating promise —
clearSubscribers()now properly awaited. - CSV export lint — Added
downloadattribute. - Stale eslint-disable — Removed from OG image route.
- CI — Added
npm run lintstep to CI pipeline.
Added
- Unique visitor count — Dashboard now shows distinct visitor count alongside total views.
/go/:idredirect endpoint — Server-side click tracking via 302 redirect. Works without JavaScript. http(s) links now use this path automatically.- vCard + File link types — Exposed in the link type dropdown (backend already supported them).
npm run seed— Seeds demo data for local development.- Skip-to-content link — Accessibility improvement on public pages.
prefers-reduced-motion— CSS-based hover effects now respect this media query.
Changed
- Dependency updates — recharts 3.9.2, shadcn/ui 4.13, @types/node 26, @types/bcryptjs 3.0.
- next.config —
poweredByHeader: false,optimizePackageImportsfor lucide-react/recharts/@dnd-kit. .env.example—SECRET_KEYmarked REQUIRED,BASE_URLdocumented.
Full Changelog: v1.1.1...v1.1.2
v1.1.1 — Fix fresh-deploy crash (error 1654975601)
Fixed
- Fresh-deploy crash (Next.js error 1654975601) — On a fresh
docker composedeploy, the SQLite database was created empty because migrations never ran. The first query threwno such table: settings, showing error code 1654975601 on every page. Migrations now run automatically on server startup. The setup wizard appears on first launch as documented. Fixes #34. - Healthcheck false-positive —
/api/healthreturned 200 without touching the database, so a broken instance still reported "healthy". Now probes the DB withSELECT 1and returns 503 on failure.
Changed
- Migration files explicitly bundled via
outputFileTracingIncludesinnext.config.ts. - Added
npm run db:migratescript for manual/dev use.
Upgrade
docker compose pull && docker compose up -dFull changelog: v1.1.0...v1.1.1
v1.1.0 — Theme System Rework
Theme System Rework
Complete redesign of the theming engine with CSS custom property (--lb-*) token system. Every visual property is now a token — no hardcoded colors, radii, or shadows anywhere.
Highlights
- 9 preset themes (was 5): Aurora, Glassmorphism, Neon Cyberpunk, Editorial Paper, Terminal Mono, Pastel Soft, Brutalist, Retro Sunset, Minimal Light
- 8 background types: solid, gradient, radial, mesh, aurora, animated gradient, image, pattern
- 6 card styles: pill, rounded, sharp, glass, outline, neon
- 10 Google Fonts loaded server-side (zero client JS)
- Link thumbnails: image on top, content below — like Discord/Slack link previews
- Embed widgets: YouTube, Spotify, SoundCloud, Vimeo, Bandcamp — inline iframe rendering
- Email capture: built-in subscriber form, exportable to CSV
- 20 new social icons (32 total)
- External analytics injection: Plausible, Umami, Matomo, Google Analytics
- Custom CSS injection for power users
- Theme import/export as JSON
Fixed
- Embed widget rendering (Spotify fixed 152px height, YouTube privacy mode, no redundant captions)
- Link thumbnail layout (block layout, text no longer crushed)
- Atomic click tracking (single transaction)
- JSON-LD XSS hardening
Full changelog: https://github.com/Manak-hash/LinkBreeze/blob/main/CHANGELOG.md#110---2026-07-06
v1.0.2 — Security Hardening + Codebase Audit
Security
- SVG upload XSS eliminated — Removed
.svgfrom the upload allowlist entirely. AddedContent-Security-Policy: default-src 'none'andX-Content-Type-Options: nosniffheaders to the uploads serving route. Closes #15. - Login rate limiting — 5 attempts/min per IP. Closes #1.
- Production secret key warning — Console warning when
SECRET_KEYunset in production +secretKeySetflag in health endpoint. Closes #9. - Backup row validation — Zod schemas validate every row before DB transaction.
- Analytics foreign key —
analytics_clicks.link_idnow has FK withON DELETE CASCADE.
Added
Fixed
- Login sidebar bug —
/loginredirects authenticated users to/dashboard. - Health endpoint version — Reads dynamically from
package.json.
Changed
- Atomic transactions for reorderLinks, clearAnalytics, setActiveTheme
- Proactive rate-limit cleanup every 30s
- Shared analytics-range module (deduplicated sinceExpr/parseRange)
- npm overrides for postcss + esbuild — 0 vulnerabilities
- CI workflow runs Vitest, Docker release workflow on tag push
Full Changelog: v1.0.1...v1.0.2
LinkBreeze v1.0.1
What's New in 1.0.1
This release focuses on security hardening, community contributions, and developer experience. It is a PATCH release — no breaking changes, no new features, just fixes and improvements.
🔒 Security
- Session invalidation on password change — stolen/old cookies are now instantly invalid after a password change
- QR download rate limiting — 30 req/min per IP to prevent CPU abuse
- Link URL scheme validation — blocks
javascript:anddata:URI XSS (contributed by @MFA-G) - Backup version validation — incompatible backups rejected before touching the database (contributed by @vku2018)
- Social icon URL detection hardened — proper hostname matching instead of
.includes(), resolves 12 CodeQL alerts - CI workflow least-privilege permissions — resolves 1 CodeQL alert
- Security docs overhaul — CSRF protection, vulnerability reporting timeline, safe harbor clause
🐛 Fixed
- Middleware HMAC session validation
- PowerShell compatibility for Docker commands
- docker-compose.yml now pulls pre-built image from GHCR by default
- 7 dependency bumps via Dependabot (next, react, tailwindcss, etc.)
📦 Added
- Dependabot config (weekly npm/Docker, monthly GitHub Actions)
- CI status badge in README
- robots.txt, sitemap.xml, LICENSE file
- TROUBLESHOOTING.md with upgrade guide and slug management docs
🤝 Community
First external contributors! Thank you:
- @MFA-G — URL scheme validation with tests (PR #29)
- @vku2018 — Backup version validation with tests (PR #30)
Full changelog: https://github.com/Manak-hash/LinkBreeze/blob/main/CHANGELOG.md
LinkBreeze v1.0.0
🎉 LinkBreeze v1.0.0 — Initial Release
The open-source, self-hosted link-in-bio platform. Stop paying $15/mo for Linktree.
🔗 Live Demo: https://linkbreeze-demo.omnirise.dev/alex
Features
- Link Management — Drag-and-drop reordering, unlimited links, custom titles & icons
- Privacy-First Analytics — Page views, click tracking, referrers, geo, device type — no cookies, no tracking
- Per-Link Analytics — Click-through rates, charts, CSV export
- Theme System — 5 built-in presets + full customizer (colors, fonts, backgrounds, animations)
- Dynamic OG Images — Auto-generated social preview cards per profile
- QR Codes — Auto-generated, download as SVG or PNG
- Link Scheduling — Schedule links to appear/disappear automatically
- Self-Hosted — Your data, your server. SQLite, no external dependencies
- One-Command Deploy — Docker compose and you're live
Tech Stack
Next.js 16 · TypeScript · SQLite (better-sqlite3) · Drizzle ORM · Tailwind CSS 4 · shadcn/ui
Quick Start
git clone https://github.com/Manak-hash/LinkBreeze.git
cd LinkBreeze
docker compose up -dVisit http://localhost:3000 — setup wizard does the rest.
License
MIT — do whatever you want.