Releases: libredb/libredb-studio
v0.9.13
What's Changed
Platform Integration — Font, Icon & CI Fixes
- Removed custom
@themetext tokens, replaced with standard Tailwind classes - Added
strokeWidth={1.5}to all Lucide icons - Replaced shadcn Button with plain
<button>in sidebar/explorer - New
integration-check.ymlCI workflow for platform integration rules - Test selector fixes for font/icon changes
Full Changelog: v0.9.12...v0.9.13
v0.9.12
What's New
StudioWorkspace Embeddable Export
- Add
@libredb/studio/workspaceexport — embeddable StudioWorkspace composite component for platform integration - Add
@libredb/studio/providers,@libredb/studio/types,@libredb/studio/componentspackage exports - Add tsup build config (
bun run build:lib) for library distribution (ESM + CJS + types) - Add adapter hooks (
useConnectionAdapter,useQueryAdapter) with full test coverage
UI Improvements
- Switch to Geist font with scoped font system in embedded mode
- Implement scoped dark theme CSS injection for host app compatibility
- Replace hardcoded font sizes with semantic font scale tokens
- Clean up QueryEditor toolbar — remove Quick Actions label, use Shadcn Button ghost variant
Build & CI
- Add
dist/to ESLint ignore (tsup build output) - Fix npm-publish workflow to include
bun installandbuild:libsteps - Fix flaky RootLayout test (Inter → Geist font mock)
Install
npm install @libredb/studio@0.9.12v0.9.7
Seed Connections — Pre-Configured Database Connections
Administrators can now pre-configure database connections via a YAML/JSON config file. Users see them instantly after login — no manual setup required.
Highlights
- YAML/JSON Config File — Mount a config file to define connections with role-based access control
- Hybrid Model —
managed: true(read-only, admin-controlled) ormanaged: false(editable copy for users) - Credential Injection —
${ENV_VAR}syntax for secrets, resolved server-side from K8s Secrets or env vars - Role-Based Access —
["*"](everyone),["admin"],["user"]per connection - Hot Reload — Config changes apply within 60s without restart
- Server-Side Security — Managed connection credentials never reach the client
- Full Platform Support — Docker, docker-compose, and Kubernetes (Helm chart with ConfigMap)
Example Config
version: "1"
defaults:
managed: true
environment: production
connections:
- id: "prod-analytics"
name: "Production Analytics"
type: postgres
host: analytics-db.internal
password: "${ANALYTICS_DB_PASSWORD}"
roles: ["admin"]
color: "#10B981"
- id: "dev-sandbox"
name: "Dev Sandbox"
type: mysql
host: dev-mysql.internal
password: "${DEV_DB_PASSWORD}"
roles: ["*"]
managed: falseDemo System Removed
The legacy demo connection system (DEMO_DB_* env vars, demo mock provider, showcase queries) has been completely removed. Seed connections is the replacement — more flexible, multi-database, role-aware.
Migration: Replace DEMO_DB_* env vars with a seed connections YAML file. See docs/SEED_CONNECTIONS.md for the full guide.
Other Changes
- Single source of truth for connections — All components (Monitoring, Admin, Schema Diff) now use
useAllConnections()hook instead of direct localStorage access - OIDC test stability — Fixed flaky
encryptState/decryptStatetests caused byjosemock contamination - Auth tests improved — Real JWT sign/verify instead of mocked jose
- Comprehensive docs — SEED_CONNECTIONS.md usage guide + README section
Breaking Changes
DEMO_DB_*environment variables are no longer supportedisDemofield removed fromDatabaseConnectiontype'demo'removed fromDatabaseTypeunion/api/demo-connectionendpoint removed
Full Changelog: v0.8.20...v0.9.7
v0.8.19
Release v0.8.19 - Helm Chart, Error Handling, Connection Lifecycle & Security Hardening
This release introduces a production-grade Helm chart with ArtifactHub integration, comprehensive error handling across all API routes, connection lifecycle management with idle eviction and transaction expiration, and security hardening including log injection prevention and CodeQL scanning.
Highlights
- Helm Chart: Production-ready Kubernetes deployment with PostgreSQL subchart, HPA, PDB, NetworkPolicy, and JSON Schema validation
- ArtifactHub: Published chart with metadata, annotations, and automated release workflow
- Error Handling: Centralized error framework with typed error codes, API error wrapper, and global error boundaries (404, 500, global-error)
- Connection Lifecycle: Idle provider eviction (30min), transaction expiration (5min), explicit disconnect route, and connection leak prevention
- Log Injection Prevention: Sanitized logger with newline/control character stripping across all log output
- CodeQL Scanning: GitHub CodeQL workflow added for automated security analysis on main branch
- Schema Explorer: Right-click context menu on table items for enhanced actions
- Login Page: Community section, LibreDB hexagonal logo, and branding improvements
New Features
Production-Grade Helm Chart (#44)
A complete Kubernetes deployment chart at charts/libredb-studio/:
| Resource | Description |
|---|---|
Deployment |
Configurable replicas, resource limits, probes, security context |
Service |
ClusterIP with configurable port |
Ingress |
Optional, with TLS and custom annotations |
HPA |
Horizontal Pod Autoscaler (CPU/memory targets) |
PDB |
Pod Disruption Budget for availability |
NetworkPolicy |
Ingress/egress rules for security |
PVC |
Persistent volume for SQLite storage mode |
ConfigMap |
Non-sensitive environment configuration |
Secret |
JWT secret, admin/user passwords |
ServiceAccount |
Dedicated service account |
# Install
helm repo add libredb-studio https://libredb.org/libredb-studio/
helm install my-release libredb-studio/libredb-studio \
--set secrets.jwtSecret="your-32-char-secret" \
--set secrets.adminPassword="admin123" \
--set secrets.userPassword="user123"
# Or via OCI
helm install my-release oci://ghcr.io/libredb/charts/libredb-studio- PostgreSQL Subchart: Optional
postgresql.enabled=truefor integrated database - JSON Schema Validation:
values.schema.jsonvalidates all configuration inputs - CI Integration:
helm-release.ymlworkflow for automated chart publishing
Comprehensive Error Handling (#42)
Centralized error framework replacing ad-hoc try/catch across 30+ API routes:
| Component | Description |
|---|---|
src/lib/api/errors.ts |
AppError class hierarchy with typed error codes |
src/lib/api/error-codes.ts |
Enumerated error codes (AUTH_, DB_, VALIDATION_*, etc.) |
src/lib/api/with-error-handler.ts |
HOF wrapper for consistent API error responses |
src/app/error.tsx |
App-level error boundary |
src/app/global-error.tsx |
Root-level error boundary (catches layout errors) |
src/app/not-found.tsx |
Custom 404 page |
src/app/admin/error.tsx |
Admin dashboard error boundary |
Connection Lifecycle Management (#43)
| Feature | Description |
|---|---|
| Idle Eviction | Providers unused for 30min are automatically disconnected |
| Transaction Expiration | Open transactions expire after 5min to prevent lock leaks |
| Disconnect Route | POST /api/db/disconnect for explicit provider cleanup |
| Connection Leak Prevention | Factory tracks last-used timestamps, periodic sweep |
use-api-call Hook |
Centralized API call wrapper with error handling |
Schema Explorer Context Menu
Right-click context menu on table items with actions like SELECT, COUNT, describe, and drop — integrated via restructured TableItem component.
Login Page Enhancements (#41)
- Community section with GitHub, Discord, and documentation links
- LibreDB hexagonal logo SVG (
src/components/libredb-logo.tsx) - Favicon and branding assets (
public/favicon.ico,public/favicon-32x32.png) - Improved accessibility and responsive layout
Security
Log Injection Prevention
New structured logger (src/lib/logger.ts) with:
- Newline and control character sanitization
- Consistent log levels (info, warn, error, debug)
- Applied across all API routes and database providers
CodeQL Scanning
.github/workflows/codeql.yml added for automated security analysis on main and dev branches.
CI Workflow Hardening
All GitHub Actions workflows updated to use pinned action versions (actions/checkout@v6, etc.) for supply chain security.
Bug Fixes
- fix(mssql): Correct Azure host detection logic — hostname matching now properly identifies Azure SQL endpoints
- fix(oidc): Enhanced Auth0 logout URL handling — proper
returnToparameter construction - fix(logger): Sanitize log messages to prevent log injection attacks
- fix(storage): Improve SSL handling for local Docker host PostgreSQL connections
- fix(ci): Improve appVersion validation in CI workflow
- fix(schema): Remove overly strict minLength validation for jwtSecret in Helm values schema
- fix: Connection initialization with storage sync readiness
- fix: Tab management state handling improvements
Dependencies
No new runtime dependencies added. All changes use existing packages.
Breaking Changes
None. This release is fully backward-compatible with v0.8.0.
Testing
New Tests
| File | Description |
|---|---|
tests/unit/api-errors.test.ts |
AppError hierarchy, error codes, serialization |
tests/unit/lib/api/error-codes.test.ts |
Error code enum coverage |
tests/unit/logger.test.ts |
Logger sanitization, log levels |
tests/unit/query-cancelled-error.test.ts |
Query cancellation error handling |
tests/unit/db/factory.test.ts |
Provider factory, idle eviction, transaction expiry |
tests/api/db/disconnect.test.ts |
Disconnect route handler tests |
tests/components/CommunitySection.test.tsx |
Community section rendering |
tests/hooks/use-tab-manager.test.ts |
Extended tab management tests |
CI Pipeline
bun run lint # ESLint 9 — clean
bun run typecheck # TypeScript strict — clean
bun run test # All tests pass
bun run build # Next.js production build — clean
Full Changelog
Added
- Production-grade Helm chart with ArtifactHub integration (#44)
- Comprehensive error handling framework with typed error codes (#42)
- Connection lifecycle management — idle eviction, transaction expiration, disconnect route (#43)
- Schema explorer context menu for table actions
- Structured logger with log injection prevention
- CodeQL security scanning workflow
- Global error boundaries (404, 500, global-error)
use-api-callhook for centralized API error handling- Community section on login page (#41)
- LibreDB hexagonal logo and favicon assets
- Titanic sample dataset (
docs/sampledb/titanic.sql) - Helm chart documentation (
docs/HELM_CHART.md) - Login page documentation (
docs/LOGIN_PAGE.md)
Changed
- All GitHub Actions workflows pinned to specific versions
- 30+ API routes migrated to centralized error handler
- Database factory enhanced with provider tracking and eviction
- Tab management state handling improved
- Storage providers hardened with better SSL and error handling
Fixed
- MSSQL Azure host detection logic
- Auth0 OIDC logout URL handling
- Log injection vulnerability via unsanitized log messages
- Connection leaks from idle providers
- Tab management state inconsistencies
- Storage SSL handling for local Docker hosts
- Helm chart JWT secret validation
Security
- CodeQL workflow for automated vulnerability scanning
- Log injection prevention across all API routes
- CI workflow supply chain hardening (pinned action versions)
Full Changelog: Compare v0.8.0...v0.8.19
Docker Image: ghcr.io/libredb/libredb-studio:0.8.19
Helm Chart:
helm repo add libredb-studio https://libredb.org/libredb-studio/
helm install my-release libredb-studio/libredb-studioContributors
Full Changelog: v0.8.0...v0.8.19
libredb-studio-helm-chart-0.1.0
Web-based SQL IDE for cloud-native teams supporting PostgreSQL, MySQL, SQLite, Oracle, SQL Server, MongoDB, and Redis
v0.8.0
Release v0.8.0 - Pluggable Storage Layer, Login Redesign & Zitadel OIDC
This release introduces a pluggable storage abstraction layer, a redesigned login page, and Zitadel OIDC support. Storage supports localStorage (default), SQLite, or PostgreSQL — controlled by a single environment variable. The login page features a modern split-panel layout with responsive design. Zitadel joins Auth0, Keycloak, Okta, and Azure AD as a supported OIDC provider.
Highlights
- Three Storage Modes: localStorage (zero-config default), SQLite (single-node persistent), PostgreSQL (multi-node enterprise)
- Write-Through Cache: localStorage always serves reads (instant, synchronous); server storage is the persistent source of truth
- Automatic Migration: Existing localStorage data is seamlessly migrated to server storage on first login
- Per-User Isolation: Server storage is scoped by JWT username — no cross-user data leaks
- Single Docker Image: Runtime config via
STORAGE_PROVIDERenv var — one image supports all modes - Zero Breaking Changes: All 16+ consumer components keep the same synchronous
storage.*API - Login Redesign: Modern split-panel layout with branding panel, responsive mobile view, and OIDC/local mode support
- Zitadel OIDC: Full integration with Zitadel identity provider — PKCE, role mapping, and RP-Initiated logout
New Features
Pluggable Storage Abstraction
A complete storage module (src/lib/storage/) that decouples data persistence from the browser:
┌──────────────────────────────┐
│ 16+ Consumer Components │ ← Unchanged, same sync API
│ storage.getConnections() │
│ storage.saveConnection() │
└──────────────┬───────────────┘
│ sync read/write
┌──────────────▼───────────────┐
│ Storage Facade │ ← localStorage + CustomEvent dispatch
└──────────────┬───────────────┘
│ CustomEvent: 'libredb-storage-change'
┌──────────────▼───────────────┐
│ useStorageSync Hook │ ← Write-through cache (server mode only)
└──────────────┬───────────────┘
│ fetch (debounced 500ms)
┌──────────────▼───────────────┐
│ API Routes /api/storage/* │ ← JWT auth + user scoping
└──────────────┬───────────────┘
│
┌──────────────▼───────────────┐
│ ServerStorageProvider │ ← Strategy Pattern
│ ┌─────────┐ ┌────────────┐ │
│ │ SQLite │ │ PostgreSQL │ │
│ └─────────┘ └────────────┘ │
└──────────────────────────────┘
9 Data Collections persisted across all modes:
| Collection | Description |
|---|---|
connections |
Saved database connections |
history |
Query execution history (max 500) |
saved_queries |
User-saved SQL/JSON queries |
schema_snapshots |
Schema diff snapshots (max 50) |
saved_charts |
Saved chart configurations |
active_connection_id |
Currently active connection |
audit_log |
Audit trail events (max 1000) |
masking_config |
Data masking rules and RBAC |
threshold_config |
Monitoring alert thresholds |
Storage Modes
Local Mode (Default)
No configuration needed. All data lives in the browser's localStorage.
# Just start the app
bun devSQLite Mode
A single file on the server. Ideal for self-hosted single-node deployments.
STORAGE_PROVIDER=sqlite
# Optional: STORAGE_SQLITE_PATH=./data/libredb-storage.db (default)- Auto-creates directory, database file, and table on first request
- WAL mode enabled for concurrent read performance
better-sqlite3(Node.js native bindings)
PostgreSQL Mode
Recommended for production, teams, and high-availability deployments.
STORAGE_PROVIDER=postgres
STORAGE_POSTGRES_URL=postgresql://user:pass@host:5432/libredb- Connection pool (max 5, 30s idle timeout)
- Table auto-created via
CREATE TABLE IF NOT EXISTS - Transactional
mergeData()for migration safety
Write-Through Cache & Sync Hook
The useStorageSync hook orchestrates all client-server synchronization:
- Discovery:
GET /api/storage/configdetermines storage mode at runtime - Migration: First-time server mode users get localStorage data auto-migrated via
POST /api/storage/migrate - Pull: Server data pulled into localStorage on mount
- Push: Mutations debounced (500ms) and pushed to server via
PUT /api/storage/[collection] - Graceful Degradation: If server is unreachable, localStorage continues to work
Automatic Migration
When switching from local to server mode:
- Sync hook detects first-time server mode (no
libredb_server_migratedflag) - All 9 collections sent to server via
POST /api/storage/migrate - Server performs ID-based deduplication — no duplicates
- Flag set in localStorage to prevent re-migration
- From this point, server is the source of truth
No manual steps required — just change the env var and restart.
Per-User Isolation
Every row in user_storage is scoped by user_id (JWT email):
- Client never sends
user_id— server always extracts from JWT cookie - Every query includes
WHERE user_id = $username - OIDC users (Auth0, Keycloak, Okta, Azure AD) fully supported
Docker Deployment
SQLite:
services:
app:
image: ghcr.io/libredb/libredb-studio:latest
environment:
- STORAGE_PROVIDER=sqlite
- STORAGE_SQLITE_PATH=/app/data/libredb-storage.db
volumes:
- storage-data:/app/data
volumes:
storage-data:PostgreSQL:
services:
app:
image: ghcr.io/libredb/libredb-studio:latest
environment:
- STORAGE_PROVIDER=postgres
- STORAGE_POSTGRES_URL=postgresql://user:pass@db:5432/libredb
depends_on:
db:
condition: service_healthy
db:
image: postgres:16-alpine
environment:
- POSTGRES_DB=libredb
- POSTGRES_USER=user
- POSTGRES_PASSWORD=pass
volumes:
- pgdata:/var/lib/postgresql/data
healthcheck:
test: ["CMD-SHELL", "pg_isready -U user"]
interval: 5s
timeout: 3s
retries: 5
volumes:
pgdata:Bug Fixes
Proxy Middleware Blocking /api/storage/config
Problem: GET /api/storage/config returned a 307 redirect to /login instead of the expected JSON response. This endpoint is designed to be public (no auth required) for runtime storage mode discovery.
Root Cause: The endpoint was not included in the proxy middleware's public route whitelist (src/proxy.ts).
Fix: Added /api/storage/config to both the if condition block and the matcher regex in src/proxy.ts.
Dependencies
Added
| Package | Version | Purpose |
|---|---|---|
better-sqlite3 |
^11.x | SQLite storage provider (WAL mode, native bindings) |
@types/better-sqlite3 |
^7.x | TypeScript definitions for better-sqlite3 |
Note
PostgreSQL uses the existing pg package (already in dependencies for database connections). No new dependency needed for PostgreSQL storage.
Breaking Changes
None. This release is fully backward-compatible:
- All 16+ consumer components keep the same synchronous
storage.*API - The
@/lib/storageimport path is preserved (barrel export) - Default mode is
local— existing deployments work without any changes - localStorage key prefix standardized to
libredb_(done in v0.7.1)
Environment Variables
| Variable | Required | Default | Description |
|---|---|---|---|
STORAGE_PROVIDER |
No | local |
Storage backend: local, sqlite, or postgres |
STORAGE_SQLITE_PATH |
No | ./data/libredb-storage.db |
Path to SQLite database file |
STORAGE_POSTGRES_URL |
Yes (postgres) | — | PostgreSQL connection string |
These are server-side only variables (no
NEXT_PUBLIC_prefix). The client discovers the mode at runtime viaGET /api/storage/config. This means one Docker image works for all modes.
Testing
New Tests
| File | Tests | Description |
|---|---|---|
local-storage.test.ts |
7 | localStorage CRUD, SSR safety, JSON parse errors |
storage-facade.test.ts |
18 | All domain methods, CustomEvent dispatch |
storage-facade-extended.test.ts |
33 | History caps, snapshots, charts, edge cases |
factory.test.ts |
7 | Env-based provider selection, singleton behavior |
sqlite.test.ts |
23 | WAL mode, upsert, transactions, health check |
postgres.test.ts |
23 | Pool config, upsert, transactions, health check |
config.test.ts |
4 | Config endpoint responses for all modes |
storage-routes.test.ts |
27 | API route handlers (GET/PUT/POST, auth, validation) |
factory-singleton.test.ts |
15 | Singleton isolation, concurrent access |
use-storage-sync.test.ts |
37 | Hook lifecycle: discovery, migration, pull, push |
Total: 194 new tests across 10 files
E2E Test Results
All three storage modes verified end-to-end:
| Mode | API Tests | Browser Tests | User Isolation | Result |
|---|---|---|---|---|
| Local | 3/3 pass | 2/2 pass | N/A | PASS |
| SQLite | 6/6 pass | 3/3 pass | N/A | PASS |
| PostgreSQL | 8/8 pass | 3/3 pass | 2-user verified | PASS |
CI Pipeline
bun run lint # ESLint 9 — clean
bun run typecheck # TypeScript strict — clean
bun run test # All tests pass (unit + API + integration + hooks + components)
bun run build # Next.js production build — clean
Extending: Add Your Own Storage Provider
Adding a new backend (e.g., MySQL, DynamoDB, Redis) requires one file implementing ServerStorageProvider:
// src...v0.7.0
OIDC Authentication
This release introduces vendor-agnostic OpenID Connect (OIDC) authentication supporting any OIDC-compliant provider (Auth0, Keycloak, Okta, Azure AD, Google), upgrades the framework to Next.js 16 with React 19.2, and migrates the login system from password-only to email/password format.
Highlights
- OIDC Single Sign-On: Vendor-agnostic OpenID Connect authentication with PKCE, role mapping, and session management
- Next.js 16 Upgrade: Framework upgrade from Next.js 15 to 16 with Turbopack as default bundler
- Email/Password Login: Login system migrated from password-only to email/password format with configurable default users
- Middleware to Proxy:
middleware.tsrenamed toproxy.tsper Next.js 16 conventions - ESLint Configuration: Updated ESLint config for
eslint-config-nextv16 compatibility
New Features
OIDC Authentication (Single Sign-On)
Vendor-agnostic OpenID Connect authentication that works with any OIDC-compliant identity provider. After OIDC authentication, a local JWT session is created — middleware, hooks, and protected routes remain unchanged.
Supported Providers:
| Provider | Role Claim Example |
|---|---|
| Auth0 | https://myapp.com/roles (via Actions) |
| Keycloak | realm_access.roles (dot-notation) |
| Okta | groups |
| Azure AD | roles |
Auth Flow:
Browser → GET /api/auth/oidc/login → OIDC Discovery (cached) → Generate PKCE + state + nonce
→ Set oidc-state cookie (signed, httpOnly, 5min)
→ 302 redirect to provider's authorize endpoint
Browser → Authenticate at provider → 302 /api/auth/oidc/callback?code=xxx&state=xxx
→ Validate state → Exchange code for tokens → Extract claims → Map role
→ Create local JWT session (auth-token cookie) → Redirect to app
Key Features:
- PKCE (S256): Proof Key for Code Exchange for secure authorization code flow
- OIDC Discovery: Auto-discovery via
/.well-known/openid-configurationwith 5-minute cache - State Encryption: PKCE state cookie signed with JWT_SECRET (5-minute expiry)
- Role Mapping: Configurable claim path with dot-notation for nested claims, case-insensitive matching
- Prompt Login:
prompt=loginparameter forces re-authentication on every SSO click - OIDC Logout: Logout clears both local JWT and provider session (Auth0
/v2/logout, generic RP-Initiated Logout)
Environment Variables:
# Auth provider: "local" (default) or "oidc"
NEXT_PUBLIC_AUTH_PROVIDER=local
# OIDC Configuration (required when AUTH_PROVIDER=oidc)
OIDC_ISSUER=https://dev-xxx.auth0.com
OIDC_CLIENT_ID=your_client_id
OIDC_CLIENT_SECRET=your_client_secret
OIDC_SCOPE=openid profile email
OIDC_ROLE_CLAIM=https://myapp.com/roles
OIDC_ADMIN_ROLES=adminEmail/Password Login
Login system upgraded from password-only to email/password format with configurable default users for both local and demo environments.
Default Users:
| Role | Password | |
|---|---|---|
| Admin | admin@libredb.org |
LibreDB.2026 |
| User | user@libredb.org |
LibreDB.2026 |
Environment Variables:
ADMIN_EMAIL=admin@libredb.org
ADMIN_PASSWORD=your_secure_admin_password
USER_EMAIL=user@libredb.org
USER_PASSWORD=your_secure_user_passwordLogin Page:
- Conditional rendering: OIDC mode shows "Login with SSO" button, local mode shows email/password form
- Quick access demo buttons for Admin and User with pre-filled credentials
- OIDC error display from
?error=query parameter - Wrapped in
Suspenseboundary foruseSearchParams()compatibility
Framework Upgrade
Next.js 15 → 16
| Package | Before | After |
|---|---|---|
next |
15.5.7 |
16.1.6 |
react |
19.2.1 |
19.2.4 |
react-dom |
19.2.1 |
19.2.4 |
eslint-config-next |
15.5.7 |
16.1.6 |
@types/react |
^19 |
^19.2.14 |
@types/react-dom |
^19 |
^19.2.3 |
Key Changes:
- Turbopack Default:
next devnow uses Turbopack by default (removed explicit--turbopackflag) - Middleware → Proxy:
src/middleware.tsrenamed tosrc/proxy.ts,middleware()function renamed toproxy() - ESLint Config: Updated
eslint.config.mjsfor v16 compatibility
Architecture Changes
New Files
| File | Description |
|---|---|
src/lib/oidc.ts |
OIDC utility module (~230 lines): config, discovery, PKCE, token exchange, role mapping, state encryption, logout URL |
src/app/api/auth/oidc/login/route.ts |
OIDC login route: discovery, auth URL generation, state cookie, redirect |
src/app/api/auth/oidc/callback/route.ts |
OIDC callback route: state validation, code exchange, role mapping, session creation |
Modified Files
| File | Change |
|---|---|
src/lib/auth.ts |
Added optional username parameter to login() function |
src/app/api/auth/login/route.ts |
Email/password authentication with ADMIN_EMAIL/USER_EMAIL env vars |
src/app/api/auth/logout/route.ts |
OIDC logout support: returns redirectUrl for provider session cleanup |
src/app/login/page.tsx |
Conditional OIDC/local login UI, email/password form, Suspense boundary |
src/hooks/use-auth.ts |
OIDC logout redirect handling via window.location.href |
src/proxy.ts |
Renamed from middleware.ts, function renamed from middleware() to proxy() |
.env.example |
OIDC configuration section with provider-specific examples |
OIDC Module (src/lib/oidc.ts)
getOIDCConfig() → reads + validates OIDC env vars
discoverProvider() → OIDC Discovery with 5-min in-memory cache
generateAuthUrl() → authorization URL with PKCE + prompt=login
exchangeCode() → token exchange, ID token validation
mapOIDCRole() → role extraction from claims (dot-notation, case-insensitive)
encryptState() → sign PKCE state as JWT
decryptState() → verify + extract PKCE state from JWT
buildLogoutUrl() → provider-specific logout URL (Auth0, Keycloak, etc.)
Breaking Changes
Login API Format
The POST /api/auth/login endpoint now requires email in addition to password:
// Before (v0.6.x)
{ password: "admin123" }
// After (v0.7.0)
{ email: "admin@libredb.org", password: "LibreDB.2026" }Environment Variables
# Before (v0.6.x)
ADMIN_PASSWORD=admin123
USER_PASSWORD=user123
# After (v0.7.0)
ADMIN_EMAIL=admin@libredb.org
ADMIN_PASSWORD=LibreDB.2026
USER_EMAIL=user@libredb.org
USER_PASSWORD=LibreDB.2026Middleware Rename
// Before (v0.6.x) — Next.js 15
// src/middleware.ts
export async function middleware(request: NextRequest) { ... }
// After (v0.7.0) — Next.js 16
// src/proxy.ts
export async function proxy(request: NextRequest) { ... }Dependencies
Added
openid-clientv6 — OIDC Discovery, PKCE, Authorization Code Flow, ID token validation (by Filip Skokan, same author asjose)
Updated
next15.5.7 → 16.1.6react19.2.1 → 19.2.4react-dom19.2.1 → 19.2.4eslint-config-next15.5.7 → 16.1.6@types/react^19 → ^19.2.14@types/react-dom^19 → ^19.2.3
Note: openid-client depends on jose ^6.1.3 — same version already in the project, zero extra transitive dependencies.
Testing
New Test Files
| File | Tests | Description |
|---|---|---|
tests/unit/lib/oidc.test.ts |
17 | mapOIDCRole, getOIDCConfig, encryptState/decryptState, buildLogoutUrl |
tests/api/auth/oidc-login.test.ts |
4 | OIDC login redirect, PKCE state cookie, redirect URI, error handling |
tests/api/auth/oidc-callback.test.ts |
9 | Code exchange, role mapping, session creation, error handling |
Updated Test Files
| File | Change |
|---|---|
tests/api/auth/login.test.ts |
Updated for { email, password } format (9 tests) |
tests/api/auth/logout.test.ts |
Updated for OIDC logout support (3 tests) |
tests/components/LoginPage.test.tsx |
Updated for email/password form and new credentials (14 tests) |
tests/setup.ts |
Added ADMIN_EMAIL, USER_EMAIL env vars |
Test Results
494 pass, 0 fail across 23 component test files + 68 non-component test files
All 15 isolation groups passed
Migration Guide
For Users
-
Update environment variables:
# Add these new variables ADMIN_EMAIL=admin@libredb.org USER_EMAIL=user@libredb.org # Update passwords (or keep existing ones) ADMIN_PASSWORD=your_password USER_PASSWORD=your_password
-
To enable OIDC authentication:
NEXT_PUBLIC_AUTH_PROVIDER=oidc OIDC_ISSUER=https://your-provider.com OIDC_CLIENT_ID=your_client_id OIDC_CLIENT_SECRET=your_client_secret
-
Auth0 specific setup:
- Set Allowed Callback URLs:
http://localhost:3000/api/auth/oidc/callback - Set Allowed Logout URLs:
http://localhost:3000/login - Set Allowed Web Origins:
http://localhost:3000 - Create a Post Login Action for role mapping with namespace claim
- Set Allowed Callback URLs:
For Developers
- Middleware rename: If referencing
middleware.tsdirectly, update toproxy.ts - Login API: Update any direct calls to
/api/auth/loginto includeemailfield - Test setup: Ensure
ADMIN_EMAILandUSER_EMAILare set in test environment
Security
- PKCE S256: Authorization code flow uses Proof Key for Code Exchange to prevent code interception
- State Cookie Encryption: OIDC state signed as JWT with
JWT_SECRET, 5-minute expiry, httpOnly, sameSite=lax - Prompt Login: Every SSO attempt...
v0.6.49
What's Changed
v0.6.49 — Oracle & MSSQL Support, Admin Dashboard Overhaul, and Comprehensive Test Infrastructure
Highlights
This release brings Oracle and MSSQL database support, a significantly enhanced Admin Dashboard with real-time monitoring, a fully restructured Studio UI, and a massive investment in testing infrastructure with 2400+ automated tests across unit, integration, component, and E2E layers.
New Features
- Oracle & MSSQL Database Support — Full provider implementation with connection modal, query execution, schema exploration, and maintenance operations
- ERD Enhancement — Improved Entity-Relationship Diagram rendering with better layout and interactivity
- Schema Diff Engine — Visual schema comparison and migration SQL generation between snapshots
- Advanced Charting — Enhanced data visualization capabilities in query results
- Admin Dashboard Overhaul
- SystemInfo component for environment details
- Audit and fleet health API routes
- Animated counters and audit event timeline in OverviewTab
- Real-time fleet health monitoring across all connections
- Playwright E2E Testing — Full browser-based end-to-end test framework integrated into CI
Bug Fixes
- MySQL BLOB Serialization — Resolved binary data handling and monitoring errors for MySQL connections
- Maintenance Error Handling — Improved error handling for schema, health, and maintenance operations across all providers
- Monitoring Connection Selection — Fixed connection selection logic in MonitoringDashboard
- SSH2 Module Resolution — Added
ssh2toserverExternalPackagesfor proper server-side bundling - Studio Import Paths — Corrected component import paths after studio restructure
Refactoring
- Studio Restructure — Reorganized Studio with custom sub-components for better maintainability
- SchemaExplorer — Restructured into modular component architecture with dedicated sidebar support
- Data Masking UI — Replaced ScrollArea with native div for improved styling consistency
- OverviewTab Type Safety — Improved type annotations and component structure
Testing & CI
- 2400+ Automated Tests — Comprehensive test coverage across all layers:
- Unit tests for SQL parsing, connection string handling, schema diff, and completions
- API route tests for AI endpoints with error class coverage
- Integration tests for all database providers (PostgreSQL, MySQL, SQLite, Oracle, MSSQL, MongoDB, Redis)
- Hook tests for auth, monitoring, connection management, AI chat, and query execution
- Component tests for 40+ React components with mock isolation groups
- E2E tests with Playwright for critical user flows
- Coverage Infrastructure — Merged LCOV coverage reporting across isolated test groups, HTML coverage reports, SonarCloud integration
- CI Pipeline — Enhanced GitHub Actions workflow with unit, integration, and E2E steps with proper coverage upload
- Test Isolation — 14-group component test runner preventing
mock.module()cross-contamination
Documentation
- Updated CLAUDE.md and README.md to reflect Oracle, MSSQL, and Redis support
- Comprehensive testing strategy documentation with quality gates
- CI integration guide for coverage and E2E workflows
Full Changelog: v0.6.13...v0.6.49
v0.6.13
What's Changed
Data Privacy & Masking
The headline feature of this release — a complete data masking system that automatically detects and protects sensitive data across the entire application.
- Automatic Sensitive Column Detection — 10 built-in patterns (email, phone, credit card, SSN, password, IP, date, financial, birthdate) with regex-based column name matching
- Admin Configuration Panel — New "Data Masking" tab in Admin Dashboard to add, edit, enable/disable masking patterns with real-time preview
- RBAC Enforcement — User role cannot toggle or reveal masked data; Admin role has full control with per-cell temporary reveal (10s auto-hide)
- Export Protection — CSV, JSON, and SQL INSERT exports contain masked values when masking is active
- Full UI Coverage — Masking applied across desktop grid, mobile card view, mobile table view, row detail sheet, and clipboard operations
- Data Profiler Integration — Sample values, min/max in the AI Data Profiler are automatically masked for sensitive columns
- Persistent Configuration — Masking settings survive page reloads via localStorage
AI Safety & Performance
- Query Safety Analysis — New API route for AI-powered pre-execution risk assessment of destructive queries
- Performance Analysis — New API route for AI-driven query performance analysis with optimization suggestions
Documentation
- Updated README with Data Privacy & Masking section
- Enhanced README with new screenshots and database icons
- Added enterprise feature roadmap documentation
- Updated website (libredb.org) with Data Masking feature card and FAQ updates
Full Changelog: v0.6.11...v0.6.13
v0.6.11
What's New in v0.6.11
Database Provider Metadata Abstraction
This release introduces a major architectural improvement that eliminates 34+ hardcoded database type checks (isMongoDB, === 'mongodb') across the entire codebase, replacing them with a
polymorphic provider metadata system.
What changed:
- Provider Interface —
DatabaseProvidernow exposesgetCapabilities(),getLabels(), andprepareQuery()methods. Each provider declares its own features and UI labels instead of the
application checking types everywhere. - New API Endpoint —
/api/db/provider-metareturns capabilities and labels for any connected database, making the frontend fully type-agnostic. - Frontend Hook —
useProviderMetadata()fetches provider metadata once per connection and distributes it to all components via props. - Static UI Config —
db-ui-config.tscentralizes icons, colors, default ports, and form field visibility per database type. - Query Generators —
query-generators.tsproduces type-appropriate queries (SQL or JSON) based on capabilities.
Why it matters:
Adding a new database type previously required modifying 19+ files with conditional branches. Now it requires only 1 provider class + 1 config entry — zero changes to routes or components.
This follows the Open/Closed Principle and makes the codebase significantly more maintainable.
MongoDB Support Improvements (v0.6.10 → v0.6.11)
- Fixed
ObjectId,Binary,Decimal128handling with properinstanceofchecks - Fixed cursor closing and schema discovery limits (200 collections max)
- Removed deprecated
reIndexfor MongoDB 6.0+ compatibility - ConnectionModal now supports connection string mode for MongoDB
- QueryEditor supports JSON formatting, MQL operator autocomplete, and collection name suggestions
- AI Assistant generates proper JSON MQL queries instead of shell syntax
Developer Guide
A comprehensive guide for adding new database providers has been added at docs/adding-a-new-database-provider.md, covering the full implementation checklist with code examples.
Technical Details
New files (4):
src/app/api/db/provider-meta/route.tssrc/hooks/use-provider-metadata.tssrc/lib/db-ui-config.tssrc/lib/query-generators.ts
Modified files (19): Routes (query, maintenance, chat), all providers (postgres, mysql, sqlite, mongodb, demo), base classes (base-provider, sql-base, types, index),
frontend components (Studio, Sidebar, SchemaExplorer, QueryEditor, MaintenanceModal, ConnectionModal), and showcase-queries.ts.
- Query Optimization by @cevheri in #15
- SQL Alias-Based Code Completion by @cevheri in #16
- feat: enforce ESLint/TypeScript checks in CI and fix component bugs by @omerfarukbolat in #18
Full Changelog: v0.6.7...v0.6.11