Credential Profiles, Naming Template, Cloning, and Major Refactor
⚠️ Breaking: Existing Sources, Destinations and Notifications that store credentials inline will require a Credential Profile to be assigned before they come back online. Create the matching profiles in the Security Vault, then assign them to each adapter via the edit form. This has to be done manually for each adapter, so take some time before upgrading. The new Credential Profile system is a critical security improvement that centralizes and encrypts all secrets in the Vault, but it does require some manual migration effort for existing adapters. New adapters created after the update will require credential profiles from the start.
✨ Features
- credentials: Added the Generic Credential Profile System - reusable, AES-256-GCM encrypted credential profiles (Username/Password, SSH Key, Access Key, Token, SMTP) that adapters reference instead of storing secrets inline. Profiles are managed in the Security Vault, assigned via a searchable picker in the adapter form, and automatically merged into every backup, restore, health check, and notification at runtime.
- setup: Added Credential Profile picker to the Quick Setup Wizard Source, Destination, and Notification steps - the picker now renders identically to the standalone "Add Source/Destination/Notification" dialogs, including SSH credential support. The selected profile IDs are included in the adapter creation payload.
- ui: Added clone (copy) button to Sources, Destinations, Notifications, and Backup Jobs - cloning creates a duplicate with the name suffix "(Copy)" and carries over all settings including Vault credential references. Cloned jobs start as disabled to prevent accidental execution. Resolves #34
- storage: Added
jurisdiction field to the Cloudflare R2 adapter (Standard, EU, FedRAMP) - EU-jurisdiction buckets require the *.eu.r2.cloudflarestorage.com endpoint, without this setting they return "Access Denied" or "bucket does not exist"
- website: Added a new Website https://dbackup.app
- scheduler: Added a UI setting in Settings > General to configure the scheduler timezone without changing the
TZ environment variable. When set, the DB value takes explicit priority over TZ for all cron jobs. Thanks @iberlob (#41)
- backup: Added a configurable filename pattern for backup files. Patterns support tokens (
{name}, {db_name}, yyyy, MM, dd, HH, mm, ss) with a live preview and clickable token chips in Settings > General. Thanks @iberlob (#41)
- 2fa: Added a "Can't scan? Copy the secret key" button to the 2FA setup dialog so users who cannot scan the QR code can manually enter the TOTP secret into their authenticator app. (#39)
🐛 Bug Fixes
- storage: Fixed FTP/FTPS adapter uploading to a doubled path when the job folder contains subdirectories -
basic-ftp's ensureDir changes the working directory to the created directory, causing the subsequent uploadFrom call to resolve the relative path against the new CWD instead of root, resulting in a 553 Permission denied error from the server. A cd("/") is now called after ensureDir to reset the working directory before the upload.
- notifications: Fixed Email (SMTP)
From and To fields appearing in both the Connection and Configuration tabs - removed from and to from NOTIFICATION_CONNECTION_KEYS so they only render in the Configuration tab
- storage: Fixed Google Drive, OneDrive, and Dropbox OAuth redirect URIs using
req.nextUrl.origin (resolves to 0.0.0.0:3000 internally) instead of BETTER_AUTH_URL when deployed behind a reverse proxy, causing OAuth failures - Thanks @garrettstoupe
- jobs: Fixed pipeline Compression selector being permanently disabled for all adapter types on the job form -
isNativeCompressionActive now only evaluates to true when a PostgreSQL source is selected and a native compression algorithm (Legacy, Gzip, LZ4, ZSTD) is active. Non-PostgreSQL adapters can always choose a compression algorithm.
🔒 Security
- deps: Updated
next from 16.2.2 to 16.2.4 - fixes DoS with Server Components (GHSA-q4gf-8mx6-v5v3)
- deps: Updated
@scalar/api-reference-react from 0.9.18 to 0.9.31 - resolves critical protobufjs arbitrary code execution (GHSA-xq3m-2v4x-88gg) via transitive dependency update
- deps: Updated
better-auth and @better-auth/sso from 1.5.6 to 1.6.9 - resolves drizzle-orm SQL injection (GHSA-gpj5-g38j-94v9) and 4 @xmldom/xmldom XML injection/DoS vulnerabilities via transitive dependency updates
- deps: Added
vite@^7.3.2 as direct devDependency - fixes 3 high-severity path traversal and arbitrary file read vulnerabilities in dev server (GHSA-v2wj-q39q-566r, GHSA-p9ff-h696-f583, GHSA-4w7w-66w2-5vf9)
- deps: Updated
nodemailer from 7.0.13 to 8.0.7 - fixes SMTP command injection via CRLF in transport name and envelope size (GHSA-vvjj-xcjg-gr5g, GHSA-c7w3-x93f-qmm8)
🎨 Improvements
- history: Replaced native browser scrollbar with Shadcn
ScrollArea in the Notification Log preview dialog, consistent with the Activity Log dialog
- jobs: Renamed "Security" tab to "Advanced" in the backup job form - the tab contains both Compression and Encryption settings, so "Advanced" is more accurate
- refactor: Major codebase reorganization - split three oversized files (
config-service.ts, restore-service.ts, adapters/definitions.ts) into focused sub-modules via the Facade Pattern, and grouped all loose files in src/lib/ (20 files into 6 folders), src/services/ (19 files into 9 folders), and src/app/actions/ (14 files into 5 folders) into a clear directory structure. Also consolidated src/types.ts into src/types/index.ts, all ~600 import paths across source, tests, and docs were updated and public APIs remain unchanged
🔄 Changed
- docs: Renamed
wiki/ folder to docs/ and moved documentation domain from dbackup.app to docs.dbackup.app across all configuration files, app source code, CI/CD workflows, and docs content
- deps: Bumped minor/patch versions for
react, react-dom, tailwindcss, @tailwindcss/postcss, eslint-config-next, vitest, basic-ftp, @aws-sdk/client-s3, @aws-sdk/lib-storage, jsdom, mongodb, mssql, tar-stream, zod, react-hook-form, lucide-react - no breaking changes
📝 Documentation
- SSO: Fixed incorrect SSO callback URL in all provider setup guides - the correct path is
/api/auth/sso/callback/{provider-id}, not /api/auth/callback/{provider-id}.
- credentials: Added a new user-guide page
security/credential-profiles.md documenting types, slots, inline creation flow, reference tracking, REVEAL semantics, and the REST surface, added a top-of-page note to security/encryption.md clarifying that the Vault now hosts both an Encryption tab and a Credentials tab, added the page to the security sidebar in .vitepress/config.mts
- api: Documented the full
/api/credentials REST surface in public/openapi.yaml under the Vault tag, including a CredentialType enum and per-type data schemas (UsernamePasswordData, SshKeyData, AccessKeyData, TokenData, SmtpData), plus a new BadRequest shared response
- api: Added missing
POST /jobs/{id}/clone, POST /adapters/{id}/clone, and POST /executions/{id}/cancel endpoints to both public/openapi.yaml and api-docs/openapi.yaml. Fixed ExecutionStatus schema to include the Cancelled value. Extended /adapters/test-connection request body with optional primaryCredentialId and sshCredentialId fields. Synced Vault tag description between both files.
- adapters: Updated all database source guides (MySQL, PostgreSQL, MongoDB, Redis, MSSQL, SQLite) to replace inline credential fields with Credential Profile pickers (
USERNAME_PASSWORD or SSH_KEY type). Added ::: info Credential Profile required boxes with links to the credential-profiles page.
- adapters: Updated all destination guides (SFTP, FTP, SMB, WebDAV, rsync, Amazon S3, S3-Compatible, Cloudflare R2, Hetzner Object Storage) to replace inline credential fields with Credential Profile pickers (
SSH_KEY, USERNAME_PASSWORD, or ACCESS_KEY type). Added setup guide steps to create the credential profile first. Added Jurisdiction field and EU jurisdiction warning to R2 guide.
- adapters: Updated Email (SMTP) notification guide to replace inline User/Password fields with
SMTP credential profile picker.
- jobs: Added "Filename Pattern" section to
jobs/index.md documenting the configurable filename pattern setting (Settings → General), all supported tokens ({name}, {db_name}, date/time tokens), live preview, and clickable token chips.
- first-steps: Updated Quick Setup "Advanced tab" reference (renamed from "Security" in v2.0.0) and revised Manual Setup Step 2 (MySQL example) to reference creating a
USERNAME_PASSWORD credential profile before adding the source.
- profile-settings: Added note about "Can't scan? Copy the secret key" button in the 2FA setup dialog.
🗑️ Removed
- dead-code: Removed unused
checkPermission as _checkPermission alias imports from actions/backup/encryption.ts and actions/backup/upload.ts - the symbol was never called in either file
- dead-code: Removed 43-line developer thought-stream comment block from
uploadAvatar() in actions/backup/upload.ts, along with a redundant await getUserPermissions() call that served no authorization purpose
🧪 Tests
- coverage: Massively expanded the unit test suite across the entire codebase - added hundreds of new tests covering all database adapters (MySQL, PostgreSQL, MSSQL, MongoDB, Redis, SQLite), all storage adapters, notification adapters, the backup pipeline steps, services, auth, crypto, OIDC, and core utilities, bringing the majority of source files to 100% statement and line coverage.
🐳 Docker
- Image:
skyfay/dbackup:v2.0.0
- Also tagged as:
latest, v2
- Platforms: linux/amd64, linux/arm64