feat: Add WebDAV support for project synchronization and backup #1436
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Description
Pull Request: Add WebDAV Support for Project Synchronization and Backup
Summary
This PR introduces comprehensive WebDAV support for Overleaf, enabling users to configure WebDAV cloud storage for project synchronization and backup. The implementation spans both frontend and backend components, providing a complete solution for automatic and manual project file synchronization to WebDAV servers.
Motivation
Many users require the ability to backup their Overleaf projects to external storage services or keep local copies synchronized with cloud storage. WebDAV is a widely-supported protocol that enables file sharing and collaborative editing across different platforms. By integrating WebDAV support, users can:
Key Features
1. WebDAV Persistor (
WebDAVPersistor.js)A new storage backend that implements the
AbstractPersistorinterface for WebDAV operations:sendFile,sendStream,getObjectStream,copyObject,deleteObjectdeleteDirectory,directorySize,listDirectoryKeys,listDirectoryStatsgetObjectSize,getObjectMd5Hash,getObjectMetadata,checkIfObjectExists2. Sync Persistor (
SyncPersistor.js)A wrapper persistor that enables synchronization between the primary storage (FS/S3) and WebDAV:
3. Project WebDAV Sync Service (
ProjectWebDAVSync.mjs)Handles synchronization of actual project content (documents and files):
4. Auto-sync Service (
ProjectWebDAVAutoSync.mjs)Automatic synchronization triggered by project modifications:
5. Frontend Components
Editor Integration
SettingsWebDAV.tsx: WebDAV settings panel in the editor left menuWebDAVSettingsModal.tsx: Modal for configuring/editing WebDAV connectionProject List Integration
LinkWebDAVModal.tsx: Modal for linking existing projects to WebDAVDeleteProjectModal.tsx: Option to preserve cloud content when deleting projectsNewProjectForm.tsx: Optional WebDAV configuration during project creation6. API Endpoints
/project/new/project/:id/webdav/link/project/:id/webdav/unlinkdeleteRemoteContentbody param)/project/:id/webdav/sync/project/:id/webdav/config7. Data Model Changes
Added
webdavConfigfield to the Project schema:syncedFileHashesField DetailsThis field stores a mapping of file paths to their content hashes, used to detect which files have actually changed and need to be synced. Due to MongoDB's restriction on field names containing dots (
.) or dollar signs ($), file paths are encoded using URL-style percent encoding:.%2E$%24%%25Example:
Files Changed
New Files (9)
libraries/object-persistor/src/WebDAVPersistor.jslibraries/object-persistor/src/SyncPersistor.jsservices/web/app/src/Features/Project/ProjectWebDAVSync.mjsservices/web/app/src/Features/Project/ProjectWebDAVAutoSync.mjsservices/filestore/app/js/ProjectConfigProvider.jsservices/history-v1/storage/lib/ProjectConfigProvider.jsservices/web/frontend/js/features/editor-left-menu/components/settings/settings-webdav.tsxservices/web/frontend/js/features/editor-left-menu/components/settings/settings-webdav-modal.tsxservices/web/frontend/js/features/project-list/components/modals/link-webdav-modal.tsxModified Files (30)
Click to expand modified files list
Libraries
libraries/object-persistor/README.md- Updated documentationlibraries/object-persistor/index.js- Export new moduleslibraries/object-persistor/package.json- Addedwebdavdependencylibraries/object-persistor/src/AbstractPersistor.js- AddedgetObjectMetadatainterfacelibraries/object-persistor/src/FSPersistor.js- ImplementedgetObjectMetadatalibraries/object-persistor/src/S3Persistor.js- ImplementedgetObjectMetadatalibraries/object-persistor/src/PersistorFactory.js- Added WebDAV persistor creationServices
services/filestore/app.js- Added WebDAV config endpointservices/filestore/app/js/PersistorManager.js- SyncPersistor integrationservices/history-v1/storage/lib/persistor.js- SyncPersistor integrationservices/real-time/app/js/WebApiManager.js- WebDAV config fetchingservices/real-time/app/js/WebsocketController.js- Auto-sync integrationWeb Service
services/web/app/src/Features/Editor/EditorHttpController.mjs- WebDAV config endpointservices/web/app/src/Features/Editor/EditorRouter.mjs- New routesservices/web/app/src/Features/Project/ProjectController.mjs- WebDAV API handlersservices/web/app/src/Features/Project/ProjectEntityUpdateHandler.mjs- Sync triggersservices/web/app/src/Features/Project/ProjectListController.mjs- WebDAV config in project list APIservices/web/app/src/Features/Project/ProjectUpdateHandler.mjs- WebDAV config handlersservices/web/app/src/models/Project.mjs- Schema updateservices/web/app/src/router.mjs- Route registrationFrontend
services/web/app/views/project/editor/_meta.pug- Meta data for WebDAV configservices/web/frontend/extracted-translations.json- Translation keys for Webpack bundlingservices/web/frontend/js/features/editor-left-menu/components/settings-menu.tsx- Menu integrationservices/web/frontend/js/features/project-list/components/modals/delete-project-modal.tsx- Cloud preserve optionservices/web/frontend/js/features/project-list/components/new-project-button/modal-content-new-project-form.tsx- WebDAV during creationservices/web/frontend/js/features/project-list/util/api.ts- API functionsservices/web/types/project/dashboard/api.d.ts- Type definitionsLocalization
services/web/locales/en.json- English translationsservices/web/locales/zh-CN.json- Chinese translationsConfiguration
.gitignore- Ignore patternsArchitecture Overview
Configuration
Environment Variables
This commit introduces the following environment variables:
WEBDAV_SYNC_INTERVAL_MS30000(30 seconds)Usage
WEBDAV_SYNC_INTERVAL_MSControls the minimum interval between automatic syncs. When a user edits a document, the system will wait for this interval after the last sync before triggering the next sync.
# Example: Set to 60 seconds WEBDAV_SYNC_INTERVAL_MS=60000Auto-Sync Timing Constants
The following internal constants are defined in
ProjectWebDAVAutoSync.mjs:DEFAULT_SYNC_INTERVAL_MSSYNC_DEBOUNCE_MSAuto-Sync Behavior
The auto-sync triggering logic works as follows:
markPendingSync(projectId, isBinaryChange)isBinaryChange=true) → Triggers immediate syncWEBDAV_SYNC_INTERVAL_MS→ Sync afterSYNC_DEBOUNCE_MSHash-based Sync Decision
During
syncAllProjectFiles(), each file is compared by its content hash:file.hashproperty from HistoryManagerIf the hash matches the stored hash in
syncedFileHashes, the file is skipped. This prevents redundant uploads when reopening a project that hasn't actually changed.Dependencies
Added the following npm dependency:
{ "webdav": "^5.8.0" }Security Considerations
Current Implementation
$unsetoperator removes entire webdavConfig on unlinkKnown Limitations & Future Improvements
Testing
Manual Testing Checklist
Recommended Test Environments
pip install wsgidav cheroot && wsgidav --host=0.0.0.0 --port=8080 --root=./webdav_test --auth=anonymous)Breaking Changes
None. This is an additive feature that does not affect existing functionality.
Migration Notes
No database migrations required. The
webdavConfigfield is optional and will beundefinedfor existing projects.Screenshots
Configure WebDAV When Creating a New Project
Configuration Entry for WebDAV in the Project
WebDAV Configuration Interface
Choose Whether to Delete WebDAV Data When Deleting a Project
Choose Whether to Delete WebDAV Data When Unlinking
Choose Whether to Delete WebDAV Data When Unlinking
Commit:
a9fab0d300Branch:
addWebDAVSupportAuthor: AinzRimuru
Date: 2025-12-21
Related issues / Pull Requests
Contributes to #147 #161 #501 #526 #1040 #1300
Contributor Agreement