All notable changes to ViTransfer will be documented in this file.
The format is based on Keep a Changelog, and this project adheres to Semantic Versioning.
- Progressive Web App (PWA): ViTransfer can now be installed as an app on desktop and mobile devices
- Add to home screen support for iOS and Android
- Full-screen app experience without browser UI
- Browser Push Notifications: Real-time push notifications for admin users
- Unified event types shared with Apprise: Share Access, Admin Access, Client Comment, Video Approval, Security Alert
- Multi-device support with per-device preferences
- Test notification to verify setup
- Zero configuration required
- Client Directory: Centralized management of client companies and contacts
- New "Clients" section in admin navigation
- Searchable company and contact autocomplete when creating projects or adding recipients
- Automatic sync: new recipients and company names are added to the directory automatically
- "Sync Existing" button for bulk import from existing projects
- Customizable Email Templates: Full email template customization in Settings
- 8 template types covering all notification emails
- Placeholder system with template-specific variables
- Logo placeholder for inline logo placement
- Live email preview with sample data
- Button syntax support and CSS class shortcuts for styling
- Reset to default with one click
- Email Header Style Options: Choose between "Logo + Company Name", "Logo Only", "Name Only", or "None"
- Custom Branding Logo: Upload your own logo in Branding & Appearance, shown across all pages and emails
- Clickable Timecode Pills in Emails: Comment notification emails now include timecode badges that link directly to the exact moment in the video
- Project Description in Emails: Project descriptions are now included in email notifications
- New ViTransfer Logo: Redesigned logo and branding, dynamically colored with your chosen accent color
- "Videos" renamed to "Deliverables": Updated terminology across the share page and emails
- Admin UI Overhaul: Standardized all admin page headers, modals, and buttons for a consistent experience
- User management and project creation now open as modals instead of separate pages
- Mobile-optimized modals with proper viewport handling
- Notification Schedule Flush: Changing a notification schedule now immediately sends all pending queued notifications so nothing is lost
- Guest thumbnails now display correctly on public share pages
- Approval emails now show the correct video name
- Email timecodes now match the exact frame position shown on the share page
- Rate limit clearing now properly unblocks users
- Centralized CPU allocation (
src/lib/cpu-config.ts) for video processing- Coordinates worker concurrency and FFmpeg threads to prevent CPU overload
- Conservative allocation targeting 30-50% thread utilization
- Leaves headroom for system and host processes
- Optional
CPU_THREADSenvironment variable for Docker resource limit overrides
- Appearance settings in Global Settings
- Default theme selection (Auto/Light/Dark)
- 10 accent color presets (Blue, Purple, Green, Orange, Red, Pink, Teal, Amber, Stone, Gold)
- Dynamic email branding - email templates now use admin-configured accent color
- Improved approval emails - now shows only the specific video approved instead of listing all approved videos
- Video player now correctly displays all aspect ratios (1:1, 4:3, 4:5, 9:16) without stretching
- Preview transcoding preserves original aspect ratio instead of forcing 16:9
- Rounded corners display consistently across all screen sizes
- Project info positioned correctly below video player
- Thumbnail reel hint now shows as tooltip overlay without resizing the reel bar
- File name truncation in upload modal prevents layout issues
- Video processing no longer maxes out CPU - fixed thread allocation that was causing 100% CPU usage
- Video player uses letterbox approach with theme-aware blurred background
- Responsive breakpoint changed to xl (1280px) for better vertical video support
- Thumbnail reel hint only shows once per session
- FFmpeg thread allocation now coordinated with worker concurrency
- Worker logs now use correct terminology (threads vs cores)
- Settings reorganized: Combined "Appearance", "Company Branding", and "Domain Configuration" into single "Branding & Appearance" section
Existing 1:1 and 4:3 preview videos need reprocessing to fix stretched aspect ratios.
- Analytics page: Replaced 4 stat cards with compact horizontal stats bar; added table header for Project Activity (Type, Details, Date); dynamic page size fills screen height
- Security Events page: Added table header with aligned columns (Severity, Event Type, IP Address, Date, Block); expandable rows with single chevron; dynamic page size fills screen height
- Projects list: Replaced list view with table view (Name, Client, Status, Videos, Comments, Updated columns)
- Admin share page: Now matches client share page behavior - grid view first for all projects including single-video
- Video player: Improved sizing and styling for all aspect ratios including vertical videos
- Thumbnail generation: Preserves original video aspect ratio (9:16, 4:3, 1:1, etc.) instead of forcing 16:9 with black padding
Existing thumbnails with black bars need reprocessing. Go to Project Settings, change Preview Resolution, save without reprocessing, change back, then save with reprocessing.
- Share page redesign with thumbnail grid view and project info header
- Thumbnail reel navigation for browsing between videos
- Video upload modal with TUS resumable upload support
- Collapsible asset sections in video version cards
- Analytics: compact expandable video stats, paginated activity (20 per page)
- Security events reduced to 20 items per page
- Video player controls auto-hide after 2 seconds
- Video thumbnails not displaying on share pages (both auto-generated and custom asset thumbnails)
- Device code authentication (RFC 8628): OAuth 2.0 device authorization flow for workflow integrations (DaVinci Resolve and Premiere Pro)
- Device code endpoint for initiating authentication
- User authorization page for approving device requests
- Token endpoint for device polling
- Security event logging for device code authentication
- Per-project playback setting: Configure approved video playback behavior per project
- Approved videos no longer incorrectly show 'with Watermark' in status
- Client share page now shows client company and name instead of instance company name
- Page now reloads after video approval to properly update status
- Restored approval API call in client share page
- Added ON DELETE CASCADE to Comment-Video relation for proper cleanup
- Password reset flow: Secure self-service password recovery for admin users
- Forgot password page with email/username lookup
- Encrypted, time-limited reset tokens (30 minutes)
- Single-use token enforcement via Redis
- Rate limiting (3 requests/15min for request, 5/15min for reset)
- Email enumeration prevention (always returns success)
- Automatic session invalidation after password change
- Comprehensive security event logging
- Passkey enforcement: When passkeys are configured, password login is blocked
- Security event logged for blocked attempts
- Video player rewrite: New custom video controls with enhanced functionality
- Timeline markers showing comment positions on the scrubber
- Improved playback controls with better mobile support
- Frame-accurate seeking with timecode display
- Comments toggle button to show/hide markers
- Project info panel: Dedicated component for project metadata display
- Video technical details (resolution, codec, FPS, duration)
- Quick actions for common operations
- Keyboard shortcuts dialog
- Ko-fi support widget: Optional donation widget for community support
- Recipient session management: Session invalidation on recipient changes
- Sessions invalidated when recipient email changes
- Sessions invalidated when recipient is deleted
- Admin passkey management: Admins can now manage other users' passkeys
- List passkeys for any user (for support purposes)
- Delete passkeys with proper audit logging
- Session invalidation when passkeys are deleted
- Share token includes recipient ID: OTP-authenticated users tracked by recipient
- Validation schema centralized: Single source of truth in
@/lib/validation.ts- All project update fields use
safeStringSchemafor XSS prevention - Slug validation enforces lowercase alphanumeric with hyphens
- All project update fields use
- Comment section improvements: Better thread display and interaction
- InitialsAvatar enhancements: Improved color generation and display
- FilterDropdown refinements: Better UX for status filtering
- Database migration: Aims to resolve migration issue reported in 0.8.3
- Copy confirmation icon and text in ProjectActions component
- Marker spacing now dynamic based on video length
- Timecode validation logic improvements
- Rate limiting added to recipient PATCH/DELETE endpoints
- Shell script permissions fixed (docker-entrypoint.sh, quadlet/*.sh)
- Session invalidation on passkey deletion
- Better JWT secret validation error messages
- Centralized validation prevents schema drift
- Redis updated to version 8-alpine: Backward compatible upgrade for improved performance and features
- Applies to new installations only
- Existing installations continue to work without changes
- Fully backward compatible, seamless upgrade
- PostgreSQL updated to 18-alpine: Latest PostgreSQL version for new installations
- Uses major version tag (18-alpine) for automatic patch updates
- Applies to new installations only
- Existing installations continue to work without changes
- Optional upgrade for existing users (requires manual backup and migration according to your infrastructure practices)
- Note: TrueNAS catalog version separately managed (currently uses PostgreSQL 17.7)
- Push notifications via Apprise: Send notifications to 100+ services (Slack, Discord, Telegram, Pushover, etc.)
- Configure multiple notification channels in Settings > Integrations
- Trigger notifications on admin login, OTP requests, project approvals, and new comments
- Test notifications before saving configuration
- Notification logs with delivery status tracking
- Python/Apprise runs in isolated venv within the container
- Email unsubscribe: Recipients can opt out of email notifications
- One-click unsubscribe links in all email templates
- Dedicated unsubscribe page with confirmation
- Per-recipient unsubscribe tracking in database
- Unified email templates with consistent branding
- Project archiving: Archive projects to hide them from active views
- New ARCHIVED status blocks share page access
- Archived projects can be restored anytime
- Filter dropdown to show/hide archived projects
- Client approval control: Per-project toggle to restrict video approval to admins only
- When disabled, clients can comment and download but cannot approve
- Backend enforces restriction (not just UI)
- Custom 404 pages: Branded error pages for root, admin, and share routes
- Filter system: Reusable FilterDropdown component for status filtering across pages
- Configurable admin session timeout: Set inactivity timeout in Settings (default 15 minutes)
- Comment timestamp display setting: Choose between timecode (HH:MM:SS:FF) or simple time (MM:SS) per project
- Header about dialog: Quick access to version info and website link (replaces footer)
- Analytics moved into projects: Analytics now accessible at
/projects/[id]/analyticswith overview on dashboard - Project settings reorganized:
- Revision tracking merged into Project Details section
- New section order: Project Details → Client Information → Client Share Page → Video Processing → Security
- Client Share Page section consolidates approval, downloads, and feedback options
- User management refactored: Password and passkey management now use modal dialogs
- Settings UI: All sections use CollapsibleSection component for consistency
- Integrations page: Icon-only display for cleaner layout
- Button styling standardized: Consistent sizes and labels across all admin pages
- Comment UI refined: Theme tokens, improved bubble styling, thread layout improvements
- Tagline updated: Focus on "deliverables" messaging
- Share authentication hardened with proper 401 handling for expired/invalid tokens
- Dialog close button highlight removed for cleaner appearance
- Session timeout wording aligned across UI
- Base image updated: node:24.13.0-alpine3.23 (latest Node.js 24 LTS)
- No vulnerabilities in project dependencies (npm audit clean)
- Share pages: video sidebar now fills the full visible height consistently (including admin share view)
- Admin UI spacing tightened and made consistent across pages; grid view is now the default (with improved mobile layouts)
- Analytics + security dashboards condensed overview metrics into single cards and reduced filter UI height
- Share pages: removed footer, moved shortcuts button below the comment field, corrected shortcuts list, and added Ctrl+/ to reset speed to 1x
- Multiple asset upload queue with concurrent upload support
- Upload multiple assets at once with progress tracking
- Support for mixed file types (video/image/subtitle) in single selection
- Auto-detected categories for uploaded files
- Improved upload queue UI with auto-start functionality
- Analytics improvements for share page tracking
- Track public share pages with authMode NONE
- Asset download tracking (individual assets and ZIP downloads)
- Unified activity feed showing authentication and download events
- Changed "Accesses" to "Visits" and "Unique Users" to "Unique Visitors"
- Expandable activity entries with click-to-expand details
- Display asset filenames in download analytics
- Expanded keyboard shortcuts for video playback with speed control and frame stepping
- Ctrl+, / Ctrl+. to decrease/increase playback speed by 0.25x (range: 0.25x - 2.0x)
- Ctrl+J / Ctrl+L to step backward/forward one frame when paused (uses actual video FPS)
- Speed indicator overlay shows current playback rate when different from 1.0x
- Shortcuts help button with HelpCircle icon displays all available keyboard shortcuts
- Allow image assets to be set as project thumbnails
- Mobile video dropdown now starts collapsed by default and auto-collapses after video selection
- Added contextual labels: "Tap to select video" when collapsed, "Currently viewing" when expanded
- Improves mobile UX by prioritizing video player visibility
- Share page authentication UI clarity improvements
- Added "This authentication is for project recipients only" message
- Guest button styled with orange (warning) color to stand out
- Separator text changed from "Or" to "Not a recipient?" for better context
- Password/OTP fields hidden when OTP code is being entered (BOTH mode)
- Changed "account" to "recipient" in OTP verification message
- Default sorting set to alphabetical across all pages (projects, videos, versions)
- Replace chevron emoji with Lucide icons throughout UI
- Improved comment reply UI with extended bubble design
- Analytics UI revamped with unified activity feed
- Removed Access Methods card (redundant with activity feed)
- Renamed "Recent Access Activity" to "Project Activity"
- Shows ALL activity with no pagination limit
- Download events show type (VIDEO/ASSET/ZIP) with appropriate icons
- Simplified color scheme: blue for visits, green for downloads
- Improved expanded details layout with clear labels
- TUS upload resume handling and fingerprint detection
- Fixed fingerprint format to match library exactly
- Use absolute URL for TUS endpoint to fix fingerprint matching
- Prevent TUS from resuming uploads to wrong video/project
- Upload queue auto-start bug fixed
- Double tracking for NONE projects with guest mode
- Only track as NONE when guest mode is disabled
- When guest mode enabled, let guest endpoint track as GUEST
- TypeScript error: Added NONE to access method types
- Updated Next.js to fix security vulnerabilities
- Session invalidation now triggered when security settings change
- Password changes invalidate all project sessions
- Auth mode changes (NONE/PASSWORD/OTP/BOTH) invalidate all project sessions
- Guest mode changes invalidate all project sessions
- Guest latest-only restriction changes invalidate all project sessions
- Uses Redis-based session revocation with 7-day TTL
- Deterministic sessionIds for NONE auth mode based on IP address
- Invalid tokens handled appropriately based on auth mode (reject for PASSWORD/OTP/BOTH, allow for NONE)
- Optimized database queries with single fetch for all security checks
- Comprehensive logging shows all changed security fields
- IP and domain blocklists moved into Security Settings with dedicated management UI, inline add/remove, and loading states; Security Events page now focuses on event history and rate limits only
- Rate limit controls refreshed automatically on load and lay out responsively alongside filters and actions
- Admin project view now updates comments immediately when new comments are posted, avoiding stale threads until the next full refresh
- Hotlink blocklist forms stack cleanly on mobile and include clearer lock expiration messaging in rate limit details
- OTP-only projects now correctly display name selection dropdown in comment section
- Recipients API now returns data for all authenticated modes (PASSWORD, OTP, BOTH, NONE), not just password-protected projects
- Security dashboard blocklist forms no longer overflow on mobile devices
- Blocklist item text (IP addresses and domains) now wraps properly on small screens
- Removed admin session detection from public share page for cleaner code separation
- Public share page now treats all users (including admins) as clients - admins should use dedicated admin share page
- Made
adminUserparameter optional in comment management hook for better backwards compatibility - Improved responsive layout for security blocklist UI (stacks vertically on mobile, horizontal on desktop)
- Updated share API route to include recipients for all non-guest authenticated users
- Added
flex-col sm:flex-rowresponsive classes to blocklist forms - Added
min-w-0,break-all, andbreak-wordsclasses to prevent text overflow in blocklist items - Made
adminUseroptional with defaultnullvalue inuseCommentManagementhook
- Public share page comment system: real-time updates now work without manual refresh
- Comment name selection: custom names and recipient selections now persist across comment submissions via sessionStorage
- Comment display: removed version label (v1, v2, etc.) from comment header while preserving version filtering logic
- Security dashboard overhaul with event tracking, rate-limit visibility/unblock, and IP/domain blocklists (UI + APIs). Migration:
20251206000000_add_ip_domain_blocklists. - Share auth logging: successful password and guest access now generate security events.
- Keyboard shortcut: Ctrl+Space toggles play/pause even while typing comments.
- FPS now shown in admin video metadata; video list displays custom version labels when available.
- Standardized security event labels across admin/share auth (password, OTP, guest, passkey); clear existing security events after upgrading to avoid mixed legacy labels in the dashboard.
- Timecode: full drop-frame support (29.97/59.94) with
HH:MM:SS;FFparsing/formatting; format hints repositioned and aligned with timecode display; DF/NDF badge removed in favor of contextual hint; format hint sits above the timecode. - Comment UX: auto-pause video when typing comments; added format hint sizing tweaks; version label shown instead of raw version number in lists.
- Admin share view: fixed optimistic comment persistence when switching videos.
- Comment system: improved optimistic updates/deduping, prevent anonymous comments when a recipient name is required, clear optimistic comments on server responses, and cancel pending notifications on deletion to avoid duplicate emails.
- Consistent naming for admin/share auth events (password/OTP/guest/passkey); blocklist APIs cached with Redis and invalidated on updates.
- CRITICAL: Re-fixed file-type ESM import issue in Docker worker
- Static imports were accidentally reintroduced, breaking the worker again
- Restored dynamic imports (
await import('file-type')) for ESM compatibility - Static imports cause ERR_PACKAGE_PATH_NOT_EXPORTED error with tsx in Docker
- Affects asset-processor.ts and video-processor-helpers.ts
- Worker now starts correctly in Docker environments
- CRITICAL: Fixed file-type ESM import issue in Docker worker (initial fix)
- Changed to dynamic imports (
await import('file-type')) for ESM compatibility - Note: This fix was accidentally reverted in working tree, necessitating v0.6.6
- Changed to dynamic imports (
- Share Page Video Sorting: Sort toggle button for video sidebar (upload date ↔ alphabetical)
- Default to upload date (newest first)
- Sort applied within "For Review" and "Approved" sections
- Works on both public and admin share views
- Sort button only shows when multiple videos exist
- Timecode Conversion: Fix timecode conversion for non-even FPS values (23.98, 29.97)
- Automatic State Updates: Approval changes now reflect immediately on share page without page refresh
- Clear token cache when refreshing project data after approval
- Video tokens are re-fetched with updated approval status
- Project Password Handling: Simplified project password handling in settings
- Load decrypted password directly for admin users
- Password field now works like any other setting field
- Fixed issue where editing other settings required password to be revealed first
- Updated Docker base image to node:24.11.1-alpine3.23
- Unused
/api/projects/[id]/passwordendpoint (functionality merged into main project API)
- Admin Integrations Page: New dedicated page announcing upcoming professional NLE integrations
- DaVinci Resolve Studio and Adobe Premiere Pro integrations coming beginning of 2026
- Direct timeline comment import, project management, and render/upload workflows
- Integrations offered as one-time purchase to support continued development
- Web app remains free and open-source
- Enhanced Asset Support: Expanded project asset validation to support DaVinci Resolve formats
- Added support for .drp (DaVinci Resolve Project), .drt (DaVinci Resolve Template), and .dra (DaVinci Resolve Archive) files
- Updated file validation logic to recognize professional NLE project formats
- Timecode Format Migration: Migrated comment timestamps to standardized timecode format (HH:MM:SS or MM:SS)
- Introduced comprehensive timecode utility library for parsing and formatting
- Updated comment display, input, and email notifications to use timecode format
- Improved readability and professional appearance across all comment interfaces
- Navigation updated to include Integrations link in admin header
- Comment sanitization enhanced to preserve timecode format in notifications
- Email templates updated to display timestamps in human-readable timecode format
- Stop video player resets when switching videos and align the admin share layout with the public share view.
- Bind fallback share tokens to the correct session and reduce token churn on share pages to avoid unexpected access denials.
- Preserve custom thumbnail assets during reprocess and when deleting older versions so copied thumbnails stay valid; keep shared thumbnail files intact when deleting a video if other assets or videos still reference the same storage path.
- Allow admins to download original files via the content endpoint even before approval; admin panel downloads avoid popups and stay responsive.
- Exclude admin activity from analytics and tag admin download sessions to keep metrics clean.
- Stream/download pipeline tuned for reliability and speed: streaming chunks capped at 4MB, download chunks capped at 50MB, full-file downloads when no Range header is sent, and downloads trigger without opening new tabs.
- Admin/download UX and performance improvements: faster downloads, responsive UI, safer chunking, and admin download tagging.
- Token revocation TTL handling tightened to avoid stale tokens.
- Consistent footer branding across application
- Admin layout footer with "Powered by ViTransfer" branding
- Mobile footer on share page with version display
- Video sidebar footer for consistent branding
- Standardized version display format across all footers
- Fix timing attack in login by adding dummy bcrypt for non-existent users
- Implement refresh token rotation to prevent replay attacks
- Add protocol-aware origin validation respecting x-forwarded headers
- Email system with unified template engine
- Unified email template engine for easier maintenance
- Consolidated all email types into single reusable component
- Maintained clean, professional design aesthetic
- Reduced codebase complexity (135 fewer lines)
- Custom thumbnail fallback: when admin deletes an asset being used as a video thumbnail, the system now automatically reverts to the worker-generated thumbnail instead of leaving the video without a thumbnail
- Share page performance: removed unnecessary 30-second polling interval that was repeatedly fetching project data
- Content Security Policy now conditionally includes upgrade-insecure-requests only when HTTPS is enabled (fixes local development)
- Thumbnail cache control headers now prevent caching (no-store) for immediate updates when thumbnails change
- Updated glob dependency from 11.0.4 to 11.1.0
- Asset deletion now uses reference counting to prevent deletion of files shared between video versions
- Real-time password validation UI with inline feedback
- Shows requirements as you type (8+ chars, one letter, one number)
- Green checkmarks for met requirements, grey for pending
- Applied to both new project creation and settings pages
- Rate limiting on auth refresh endpoint (8 requests/minute per token)
- Rate limiting across all API routes
- Zod schema validation for request payloads
- Standardized authentication using requireApiAdmin helper
- Session timeout monitoring improvements
- Video player version switching now loads videos and thumbnails correctly
- Separated URL state update from reload logic
- Added key prop to force proper video element remount
- Thumbnail selection indicator shows green for active, grey for inactive
- Password generator guarantees letter + number requirements
- Thumbnail category preserved when copying assets between versions
- Share password validation with proper Zod schema and error messages
- Unused
/api/cron/cleanup-uploadsendpoint
- Password visibility in project settings (broken after password API refactor)
- Password field now loads on-demand when eye icon clicked
- Uses secure /api/projects/[id]/password endpoint with rate limiting
- Password field UI text clarity
- Placeholder changed to "Enter password for share page"
- Help text updated to "Clients will need this password to access"
Major codebase refactoring with security hardening and architecture improvements. Total changes: 2,350 lines added, 1,353 lines removed across 41 files.
- Project password API endpoint for authenticated admins
- Asset copy/move between video versions with batch operations
- Asset thumbnail management (set any image as video thumbnail)
- Comprehensive asset validation with category-based rules
- Separate asset processor worker with magic byte validation
- Asset worker integration (assets now properly queued for processing)
- File validation rejecting valid uploads (relaxed MIME validation at API level)
- Missing security-events module import
- TypeScript null to undefined type conversions
- Video Processor: 406 → 96 lines (76% reduction)
- Extracted 8 helper functions to video-processor-helpers.ts
- Eliminated magic numbers with named constants
- Reduced nesting depth from 5 to 2 levels
- Comments API: 340 → 189 lines (44% reduction)
- Extracted 5 helper functions to comment-helpers.ts
- Separated validation, sanitization, and notification logic
- Share/Content API consolidated with reduced duplication
- Enhanced FFmpeg watermark validation (strict whitelist, 100 char limit)
- Two-layer asset validation (API extension check + worker magic bytes)
- Defense-in-depth: lenient API validation + strict worker validation
- Worker architecture (excluded from Next.js build, cleaner separation)
- Asset management UX (redesigned components with better feedback)
- Centralized project access control logic
Previous releases (0.3.5-0.3.7) added major features using patch increments. Now that features are complete and stable, bumping to 0.4.0 reflects the accumulated feature additions. This release focuses on bug fixes and quality-of-life improvements to make the feature-complete 0.3.7 release production-ready.
- Guest mode settings now persist correctly when disabled
- Guest mode properly enforces restricted access when enabled
- Authentication logic refactored for reliability and maintainability
- Global watermark settings now inherited by new projects
- Password validation for PASSWORD/BOTH authentication modes
- Mobile UI layout issues with video titles and action buttons
- Video metadata display on mobile (duration/resolution/size)
- Version label truncation on long names
- Back buttons now left-aligned and more compact
- Video list layout consistent across desktop and mobile
- Info button hidden for guests
- Security recommendation when disabling guest mode
- Cleaner authentication flow following best practices
- Video Asset Management System
- Upload/download functionality for approved videos
- Asset management UI (upload modal, list view, download modal)
- Per-project allowAssetDownload setting
- Asset download restricted to approved videos only
- ZIP download support for multiple assets
- Guest Mode
- Guest access for share pages with view-only permissions
- Guest entry button on authentication screen
- Auto-entry as guest when authMode is NONE and guestMode enabled
- Guest sessions persist across page refreshes
- Guest latest-only restriction (toggle to limit guests to latest video version)
- Database-level filtering for guest security
- Guest info hidden in API responses
- Rate limiting on guest endpoint (20 requests/minute)
- Global Video Processing Settings
- Default watermark enabled toggle in global settings
- Watermark text input shows only when watermarks enabled
- Settings persist and apply to new projects
- Authentication Mode Support
- Per-project authMode setting (PASSWORD/PASSKEY/BOTH)
- Flexible authentication options per project
- Mobile VideoList layout now matches desktop appearance
- Share page authentication and access control enhanced
- Admin UI components refactored for consistency
- Redis handling improved with static imports (no dynamic imports)
- API response sanitization for guest sessions
- Redis sismember return type handling (returns number, not boolean)
- Guest sessions marked in Redis with guest_session key
- Added guestMode and guestLatestOnly fields to Project schema
- Added authMode field to Project schema
- Added allowAssetDownload field to Project schema
- Added defaultWatermarkEnabled to Settings table
- Created VideoAsset model for asset management
- Health Check Endpoint (
/api/health)- Public endpoint for Docker health checks and monitoring systems
- Tests database and Redis connectivity
- Returns minimal information (no version or config exposure)
- No authentication required for health monitoring
- Replaces deprecated
/api/settings/publicendpoint
- Database Performance Improvements
- Added indexes on Video table for status queries
- Migration:
20251117000000_add_video_status_indexes
- Security Events UI Consistency
- Replaced HTML disclosure triangle with Lucide ChevronRight icon
- Standardized font sizes across all admin sections
- Consistent text sizing with Analytics and Projects pages
- Better mobile experience with proper SVG icons
- Smooth rotation animation on details expand/collapse
- Admin Interface Typography
- Unified font sizes:
text-smfor titles and descriptions text-xsfor timestamps and labels (consistent with Analytics)- Improved readability across desktop and mobile
- Unified font sizes:
- Deprecated
/api/settings/publicendpoint (replaced by/api/health)
- Upgraded esbuild from 0.25.12 to 0.27.0 via npm overrides
- Updated Docker base image to node:25.2.0-alpine3.22
- UI consistency across admin interface
- Standardized form styling and spacing
- Improved visual consistency in user management
- Better alignment of UI elements
- OTP (One-Time Password) Authentication - Alternative authentication method for share links
- Modern 6-box OTP input component with auto-focus and keyboard navigation
- Automatic paste support for codes from email or SMS
- Configurable via per-project authMode setting (password, OTP, or both)
- Requires SMTP configuration and at least one recipient
- Integrates with existing rate limiting and security event logging
- OTP codes are 6-digit, expire after 10 minutes, and are one-time use only
- Stored securely in Redis with automatic cleanup
- Email delivery with professional template including OTP code
- Centralized Redis connection management (
src/lib/redis.ts)- Singleton pattern for consistent connection handling
getRedis()andgetRedisConnection()functions- Replaces 6 duplicate Redis connection implementations
- Centralized comment sanitization (
src/lib/comment-sanitization.ts)sanitizeComment()function for consistent PII removal- Used across all comment API routes
- Prevents email/name exposure to non-admins
- OTPInput component for user-friendly code entry
- Individual boxes for each digit with auto-advance
- Paste support that distributes digits across boxes
- Backspace support with smart cursor movement
- Arrow key navigation between boxes
- Authentication session storage now supports multiple projects simultaneously
- Changed from single project ID to Redis SET for auth sessions
- Changed from single project ID to Redis SET for video access sessions
- Add projects to session SET instead of overwriting single value
- Refresh TTL on each project access to maintain active sessions
- Update validation to use SISMEMBER instead of exact match
- Each project still requires authentication before being added to session
- Comment section height increased from 50vh to 75vh (150% larger display area)
- Authentication Attempts setting now applies to both password and OTP verification
- Rate limiting now reads max attempts from Settings instead of hardcoded values
verifyProjectAccess()now supports authMode parameter for flexible authentication- Company Name validation now properly allows empty strings
- Changed minimum length from 1 to 0 characters
- Fixes validation mismatch where UI shows field as optional but validation required it
- Updated in createProjectSchema, updateProjectSchema, and updateSettingsSchema
- CRITICAL: Multi-project session conflicts resolved
- Opening a second project no longer breaks access to the first project
- Video playback and comments work correctly across all authenticated projects
- Session state properly maintained when switching between projects
- Comment section auto-scroll behavior improved
- Now works correctly for both admin and client users
- Fixed page-level scroll issue by using scrollTop instead of scrollIntoView
- Auto-scroll only affects comments container, not entire page
- Prevents page jumping when switching video versions or when new comments appear
- Recipient change callback keeps project settings page in sync with recipient updates
- Code maintainability with major refactoring following DRY principles
- Removed 241 lines of dead/duplicate code
- Centralized Redis connection management
- Consolidated duplicate comment sanitization logic
- Flattened deep nesting in getPasskeyConfigStatus()
- Authentication UI with more concise and helpful messages
- Security event logging now tracks OTP attempts and rate limiting
- Duplicate Redis connection implementations across 6 files
- Duplicate sanitizeComment() functions from 3 API route files
src/lib/api-responses.ts(85 lines, unused)src/lib/error-handler.ts(156 lines, unused)
- Added authMode field to Project table (password, OTP, or both)
- PassKey/WebAuthn Authentication - Modern passwordless login for admin accounts
- Usernameless authentication support (no email required at login)
- Multi-device support with auto-generated device names (iPhone, Mac, Windows PC, etc.)
- Per-user PassKey management in admin user settings
- Built with SimpleWebAuthn following official security patterns
- Challenge stored in Redis with 5-minute TTL and one-time use
- Replay attack prevention via signature counter tracking
- Comprehensive security event logging for all PassKey operations
- Rate limiting on authentication endpoints
- Strict domain validation (production requires HTTPS, localhost allows HTTP)
- Configuration via Settings.appDomain (no environment variables needed)
- Restore SMTP password reveal functionality (reverted to v0.3.0 behavior)
- Admin-authenticated GET /api/settings now returns decrypted SMTP password
- Eye icon in password field works normally to show/hide actual password
- Removed unnecessary placeholder logic for cleaner implementation
- Smart password update logic prevents unnecessary database writes
- SMTP password only updates if value actually changes
- Project share password only updates if value actually changes
- Prevents unnecessary session invalidations when password unchanged
- SMTP password no longer lost when saving other settings
- Project password updates now properly compare with current value before updating
- Session invalidation only triggered when password actually changes
- PassKey authentication endpoints protected with rate limiting
- Generic error messages prevent information disclosure
- Client sees: "PassKey authentication failed. Please try again."
- Server logs detailed error for debugging
- All PassKey operations require admin authentication (except login)
- Session invalidation on password change prevents race conditions
- Added PasskeyCredential model for WebAuthn credential storage
- credentialID (unique identifier)
- publicKey (verification key)
- counter (replay attack prevention)
- transports (USB, NFC, BLE, internal)
- deviceType (single-device or multi-device)
- backedUp (synced credential indicator)
- aaguid (authenticator identifier)
- userAgent and credentialName (device tracking)
- lastUsedAt and lastUsedIP (security monitoring)
- Comment UI with color-coded message borders and improved visual contrast
- HTTPS configuration support
- Unapprove functionality
- Build script: optional --no-cache flag support
- Settings UX improvements
- Project approval logic fixes
- Security settings enhancements
- Add runtime JWT secret validation to prevent undefined secret usage
- Fix fingerprint hash truncation (use full 256-bit SHA-256 instead of 96-bit)
- Add CRLF injection protection for companyName field in email headers
- Strengthen FFmpeg watermark escaping with defense-in-depth approach
- Implement reusable Content-Disposition header sanitization for file downloads
- Add rate limiting to admin endpoints (batch ops, approve/unapprove, users)
- Add batch operation size limits (max 100 items)
- Fix SMTP password exposure in API responses (return placeholder)
- Per-project companyName field in project creation and settings
- Display priority: companyName → Primary Recipient → "Client"
- Timezone-aware date/time formatting using Intl.DateTimeFormat
- Client-side: uses browser timezone for proper user localization
- Server-side: uses TZ environment variable for emails/logs/workers
- Format adapts based on region (MM-dd-yyyy, dd-MM-yyyy, yyyy-MM-dd)
- Update all pages to show companyName with fallback logic
- Update share API to use companyName in clientName field
- Replace toLocaleString() with formatDateTime() for consistency
- Hide recipient email when companyName is set for cleaner display
- Improve comment name picker UX (starts at "Select a name..." instead of pre-selected)
- Correct product name from "VidTransfer" to "ViTransfer" throughout codebase
- Fix TypeScript build errors related to Buffer type annotations in streams
- Revert incorrect project ownership validation (admins see all projects)
Why v0.3.0? This release includes critical security hardening that warrants a minor version bump rather than a patch.
- Multiple critical and high severity security fixes applied
- Enhanced input validation and sanitization across the application
- Improved authentication and access control mechanisms
- Strengthened file path handling and storage protections
- Removed 51KB of duplicate component files
- Complete Email Notification System (originally planned for future release, delivered now!)
- Configurable notification schedules: Immediate, Hourly, Daily, Weekly
- Email notification summaries to reduce spam (batches updates by schedule)
- Separate admin and client notification settings per project
- Per-recipient notification preferences with opt-in/opt-out toggles
- Notification queue system with automatic retry logic (3 attempts, permanent failure tracking)
- BullMQ repeatable jobs for scheduled summary delivery (every minute check)
- Professional email templates with project context and direct share links
- Unified notification flow for all comment types (client comments, admin replies)
- Per-Video Revision Tracking
- Track revision count per video (not just per project)
- Better control over individual video approval cycles
- Maintains project-wide revision limits while tracking per video
- Sort toggle for projects dashboard (status/alphabetical sorting)
- Sort toggle for project videos and versions (status/alphabetical sorting)
- Section dividers in share page sidebar (For Review / Approved sections)
- Green check mark icon for approved videos in sidebar (replaces play icon)
- New
formatDate()utility for consistent date formatting (11-Nov-2025 format) - DEBUG_WORKER environment variable for optional verbose logging
- BREAKING: All comments must now be video-specific (general comments removed)
- Email notifications now fully functional with flexible scheduling
- Share page sorting now checks if ANY version is approved (not just latest)
- Video groups in admin panel sorted by approval status (unapproved first)
- Versions within groups sorted by approval status (approved first)
- Projects list extracted to client component for better performance
- README development warning now includes 3-2-1 backup principle
- All recipient IDs migrated from UUID to CUID format for consistency
- All dates now display in consistent "11-Nov-2025" format
- General/system comments (all comments must be attached to a video)
- System audit comments for approval/unapproval actions (status tracked in database)
- Old per-comment email notification system (replaced with unified notification queue)
- Duplicate component files (AdminVideoManager 2.tsx, LoginModal 2.tsx, VideoPlayer 2.tsx, VideoUpload 2.tsx)
- Comment section approval updates now instant (optimistic UI updates)
- Share page filtering refreshes immediately on approval state changes
- Comment/reply updates appear instantly without page refresh
- Optimistic updates for comment replies (no loading delays)
- Admin comment version filtering on share page more accurate
- Feedback & Discussion section updates immediately on approval changes
- Approved badge spacing in admin panel
- "All Versions" section spacing from content above
- Analytics projects card spacing to prevent overlap
- Version labels padding to prevent hover animation cutoff
- Mobile inline editing no longer overflows with action buttons
- Simplified comment filtering logic (no more null videoId checks)
- CRITICAL: Thumbnail generation failing for videos shorter than 10 seconds
- Previously hardcoded to seek to 10s, causing EOF for short videos
- Now calculates safe timestamp: 10% of duration (min 0.5s, max 10s)
- Comment section not updating when approval status changes
- Share page filtering not refreshing after approval/unapproval
- Instant comment/reply updates not working correctly
- Optimistic updates for comment replies failing
- Feedback & Discussion section not updating on approval changes
- Admin comment version filtering on share page
- Projects dashboard now loads correctly after refactoring
- Mobile overflow when editing video/group names
- Version label hover animation cutoff at top of container
- Added notification schedule fields to Settings table (admin-wide defaults)
- Added notification schedule fields to Project table (per-project overrides)
- Added notification day field for weekly schedules
- Added lastAdminNotificationSent and lastClientNotificationSent timestamps
- Created NotificationQueue table for batched email delivery with retry tracking
- Added ProjectRecipient.receiveNotifications boolean field
- Added per-video revision tracking fields
- IRREVERSIBLE: Deleted all existing general comments (where videoId IS NULL)
- Made Comment.videoId field required (NOT NULL constraint)
- IRREVERSIBLE: Migrated all UUID format recipient IDs to CUID format
- DEBUG_WORKER environment variable
- Optional verbose logging for FFmpeg and worker operations
- Logs command execution, process IDs, exit codes, timing breakdowns
- Shows download/upload speeds, file sizes, processing time breakdown
- Controllable without rebuilding Docker image (set env var and restart)
- Helps diagnose video processing issues in production
- CRITICAL: Thumbnail generation failing for videos shorter than 10 seconds
- Previously hardcoded to seek to 10 seconds, causing EOF for short videos
- Now calculates safe timestamp: 10% of duration (min 0.5s, max 10s)
- FFmpeg properly reports when no frames available for extraction
- Auto-approve project setting with toggle in global settings
- "Final Version" renamed to "Approved Version"
- Admin footer solid background, fixed at bottom on desktop
- Video information dialog clarifies it shows original video metadata
- Videos sorted by approval status (unapproved first)
- Mobile video selector now starts collapsed
- Settings pages show save/error notifications at bottom for better mobile/long page UX
- Simplified video preview note text
- Comment section height and scrolling behavior
- Recipient name selector jumping to first option
- Mobile sidebar collapsing when selecting videos
- Share page auto-scrolling issues
- Recipient name selector jumping back to first option when selecting another recipient
- Validation error when creating projects without password protection
- Validation error when creating projects without recipient email
- Docker entrypoint usermod timeout removed - allows natural completion on all platforms
- Clean startup output without false warning messages
- Version number now displays in admin footer
- Build script passes version to Docker image at build time
- Multiple recipient support for projects (ProjectRecipient model)
- Recipient management UI in project settings (add, edit, remove)
- Primary recipient designation for each project
- Projects sorted by status on admin dashboard (In Review → Share Only → Approved)
- Migrated from single clientEmail/clientName to multi-recipient system
- All notifications sent to all recipients
- Improved notification messages with recipient names
- Legacy clientEmail and clientName fields from Project model
- Code refactoring for better maintainability and reusability
- Security enhancements
Future v0.2.x releases will include notification system changes (configurable email schedules and summary notifications)
- Configurable session timeout for client share sessions (Security Settings)
- Password visibility toggle in project settings (show/hide share password)
- Configurable APP_HOST environment variable for Docker deployments
- Right-click download prevention on video player for non-admin users
- Project deletion now properly removes all folders and files
- Client names now persist correctly after page refresh
- Docker health check endpoint for K8s/TrueNAS compatibility
- TypeScript null handling for client names in comment routes
- Password field UI consistency across the application
- Password input fields now use consistent PasswordInput component with eye icon
- Share page password field layout matches SMTP password field
- Security settings with real-time feedback for timeout values
- Video reprocessing when project settings change
- Drag and drop for video uploads
- Resizable sidebar on share page
- Mobile video playback performance
- Upload cancellation deletes video records
- Share page viewport layout and scaling
- Progress bar animations with visual feedback
- Sidebar sizing (reduced to 30% max width)
- 📹 Video Upload & Processing - Automatic transcoding to multiple resolutions (720p/1080p)
- 💧 Watermarking - Customizable watermarks for preview videos
- 💬 Timestamped Comments - Collect feedback with precise video timestamps
- ✅ Approval Workflow - Client approval system with revision tracking
- 🔒 Password Protection - Secure projects with client passwords
- 📧 Email Notifications - Automated notifications for new videos and replies
- 🎨 Dark Mode - Beautiful dark/light theme support
- 📱 Fully Responsive - Works perfectly on all devices
- 👥 Multi-User Support - Create multiple admin accounts
- 📊 Analytics Dashboard - Track page visits, downloads, and engagement
- 🔐 Security Logging - Monitor access attempts and suspicious activity
- 🎯 Version Management - Hide/show specific video versions
- 🔄 Revision Tracking - Limit and track project revisions
- ⚙️ Flexible Settings - Per-project and global configuration options
- 🔐 JWT Authentication - Secure admin sessions with 15-minute inactivity timeout
- 🔑 AES-256 Encryption - Encrypted password storage for share links
- 🛡️ Rate Limiting - Protection against brute force attacks
- 📝 Security Event Logging - Track all access attempts
- 🚫 Hotlink Protection - Prevent unauthorized embedding
- 🌐 HTTPS Support - SSL/TLS for secure connections
- ⏱️ Session Monitoring - Inactivity warnings with auto-logout
- 🐳 Docker-First - Easy deployment with Docker Compose
- 🚀 Next.js 15 + React 19 - High performance modern stack
- 📦 Redis Queue - Background video processing with BullMQ
- 🎬 FFmpeg Processing - Industry-standard video transcoding
- 🗄️ PostgreSQL Database - Reliable data storage
- 🌐 TUS Protocol - Resumable uploads for large files
- 🏗️ Multi-Architecture - Support for amd64 and arm64
Starting with v0.1.0, Docker images are tagged with both version numbers and "latest":
crypt010/vitransfer:0.1.0- Specific versioncrypt010/vitransfer:latest- Always points to the latest stable release