update documentation
Some checks are pending
Tests & Quality Checks / Test on Python 3.11 (push) Waiting to run
Tests & Quality Checks / Test on Python 3.12 (push) Waiting to run
Tests & Quality Checks / Test on Python 3.11-1 (push) Waiting to run
Tests & Quality Checks / Test on Python 3.12-1 (push) Waiting to run
Tests & Quality Checks / Test on Python 3.10 (push) Waiting to run
Tests & Quality Checks / Test on Python 3.11-2 (push) Waiting to run
Tests & Quality Checks / Test on Python 3.12-2 (push) Waiting to run
Tests & Quality Checks / Build Artifacts (push) Blocked by required conditions
Tests & Quality Checks / Build Artifacts-1 (push) Blocked by required conditions
Some checks are pending
Tests & Quality Checks / Test on Python 3.11 (push) Waiting to run
Tests & Quality Checks / Test on Python 3.12 (push) Waiting to run
Tests & Quality Checks / Test on Python 3.11-1 (push) Waiting to run
Tests & Quality Checks / Test on Python 3.12-1 (push) Waiting to run
Tests & Quality Checks / Test on Python 3.10 (push) Waiting to run
Tests & Quality Checks / Test on Python 3.11-2 (push) Waiting to run
Tests & Quality Checks / Test on Python 3.12-2 (push) Waiting to run
Tests & Quality Checks / Build Artifacts (push) Blocked by required conditions
Tests & Quality Checks / Build Artifacts-1 (push) Blocked by required conditions
This commit is contained in:
parent
4cc158a791
commit
f0bab2afa5
4 changed files with 109 additions and 51 deletions
12
.github/copilot-instructions.md
vendored
12
.github/copilot-instructions.md
vendored
|
|
@ -19,16 +19,18 @@ WebDrop Bridge is a professional Qt-based desktop application (v0.5.0) that conv
|
||||||
|
|
||||||
| File | Purpose |
|
| File | Purpose |
|
||||||
|------|---------|
|
|------|---------|
|
||||||
| `src/webdrop_bridge/__init__.py` | Package info, version (0.5.0) |
|
| `src/webdrop_bridge/__init__.py` | Package info, version (0.7.1) |
|
||||||
| `src/webdrop_bridge/main.py` | Application entry point, config loading |
|
| `src/webdrop_bridge/main.py` | Application entry point, config loading |
|
||||||
| `src/webdrop_bridge/config.py` | Configuration management (file/env), URL mappings, validation |
|
| `src/webdrop_bridge/config.py` | Configuration management (file/env), URL mappings, validation |
|
||||||
| `src/webdrop_bridge/core/validator.py` | Path validation against whitelist, security checks |
|
| `src/webdrop_bridge/core/validator.py` | Path validation against whitelist, security checks |
|
||||||
| `src/webdrop_bridge/core/drag_interceptor.py` | Drag-and-drop event handling |
|
| `src/webdrop_bridge/core/drag_interceptor.py` | Drag-and-drop event handling |
|
||||||
| `src/webdrop_bridge/core/config_manager.py` | File-based config loading and caching |
|
| `src/webdrop_bridge/core/config_manager.py` | Configuration validation, profiles, import/export |
|
||||||
| `src/webdrop_bridge/core/url_converter.py` | Azure blob URL → local path conversion |
|
| `src/webdrop_bridge/core/url_converter.py` | Azure blob URL → local path conversion |
|
||||||
| `src/webdrop_bridge/core/updater.py` | Update checking via Forgejo API, release management |
|
| `src/webdrop_bridge/core/updater.py` | Update checking via Forgejo API, release management |
|
||||||
| `src/webdrop_bridge/ui/main_window.py` | Main Qt window, config injection, menu bar |
|
| `src/webdrop_bridge/ui/main_window.py` | Main Qt window, config injection, menu bar |
|
||||||
| `src/webdrop_bridge/ui/restricted_web_view.py` | Hardened QWebEngineView with security policies |
|
| `src/webdrop_bridge/ui/restricted_web_view.py` | Hardened QWebEngineView with security policies |
|
||||||
|
| `src/webdrop_bridge/ui/bridge_script_intercept.js` | JavaScript drag interception and WebChannel bridge |
|
||||||
|
| `src/webdrop_bridge/ui/download_interceptor.js` | Download handling for web content |
|
||||||
| `src/webdrop_bridge/ui/settings_dialog.py` | Settings UI, URL mapping configuration |
|
| `src/webdrop_bridge/ui/settings_dialog.py` | Settings UI, URL mapping configuration |
|
||||||
| `src/webdrop_bridge/ui/update_manager_ui.py` | Update check UI and dialogs |
|
| `src/webdrop_bridge/ui/update_manager_ui.py` | Update check UI and dialogs |
|
||||||
| `src/webdrop_bridge/utils/logging.py` | Logging configuration (console + file) |
|
| `src/webdrop_bridge/utils/logging.py` | Logging configuration (console + file) |
|
||||||
|
|
@ -254,6 +256,6 @@ git push origin feature/my-feature
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
**Current Status**: Phase 4 Complete (Jan 29, 2026) - Phase 5 (Release Candidates) Planned
|
**Current Status**: Phase 4 Complete - Phase 5 (Release Candidates) In Progress
|
||||||
**Version**: 0.5.0
|
**Version**: 0.7.1
|
||||||
**Last Updated**: February 18, 2026
|
**Last Updated**: March 3, 2026
|
||||||
|
|
|
||||||
|
|
@ -36,10 +36,11 @@
|
||||||
|
|
||||||
**Key Components:**
|
**Key Components:**
|
||||||
|
|
||||||
- `validator.py`: Path validation against whitelist
|
- `validator.py`: Path validation against whitelist with security checks
|
||||||
- `drag_interceptor.py`: Drag event handling and conversion
|
- `drag_interceptor.py`: Drag event handling and native drag operations
|
||||||
- `config.py`: Configuration management
|
- `config_manager.py`: Configuration loading from files and caching
|
||||||
- `errors.py`: Custom exception classes
|
- `url_converter.py`: Azure Blob Storage URL → local path conversion
|
||||||
|
- `updater.py`: Update checking via Forgejo API
|
||||||
|
|
||||||
**Dependencies**: None (only stdlib + pathlib)
|
**Dependencies**: None (only stdlib + pathlib)
|
||||||
|
|
||||||
|
|
@ -49,9 +50,12 @@
|
||||||
|
|
||||||
**Key Components:**
|
**Key Components:**
|
||||||
|
|
||||||
- `main_window.py`: Main application window
|
- `main_window.py`: Main application window with web engine integration
|
||||||
- `widgets.py`: Reusable custom widgets
|
- `restricted_web_view.py`: Hardened QWebEngineView with security policies
|
||||||
- `styles.py`: UI styling and themes
|
- `settings_dialog.py`: Settings UI for configuration
|
||||||
|
- `update_manager_ui.py`: Update checking and notification UI
|
||||||
|
- `bridge_script_intercept.js`: JavaScript drag interception and WebChannel bridge for Qt communication
|
||||||
|
- `download_interceptor.js`: Download handling for web content
|
||||||
|
|
||||||
**Dependencies**: PySide6, core/
|
**Dependencies**: PySide6, core/
|
||||||
|
|
||||||
|
|
@ -61,9 +65,7 @@
|
||||||
|
|
||||||
**Key Components:**
|
**Key Components:**
|
||||||
|
|
||||||
- `logging.py`: Logging configuration
|
- `logging.py`: Logging configuration (console + file with rotation)
|
||||||
- `constants.py`: Application constants
|
|
||||||
- `helpers.py`: General-purpose helper functions
|
|
||||||
|
|
||||||
**Dependencies**: stdlib only
|
**Dependencies**: stdlib only
|
||||||
|
|
||||||
|
|
@ -72,34 +74,57 @@
|
||||||
### Drag-and-Drop Operation
|
### Drag-and-Drop Operation
|
||||||
|
|
||||||
```
|
```
|
||||||
User in Web App
|
User in Web App (browser)
|
||||||
↓
|
↓
|
||||||
[dragstart event] → JavaScript sets dataTransfer.text = "Z:\path\file.txt"
|
[dragstart event] → bridge_script_intercept.js detects drag
|
||||||
|
├─ Checks if content is convertible (file path or Azure URL)
|
||||||
|
├─ Calls window.bridge.start_file_drag(url)
|
||||||
|
└─ preventDefault() → Blocks normal browser drag
|
||||||
|
|
||||||
↓
|
↓
|
||||||
[dragend event] → Drag leaves WebEngine widget
|
JavaScript → QWebChannel Bridge
|
||||||
↓
|
↓
|
||||||
DragInterceptor.dragEnterEvent() triggered
|
_DragBridge.start_file_drag(path_text) [main_window.py]
|
||||||
|
├─ Defers execution via QTimer (drag manager safety)
|
||||||
|
└─ Calls DragInterceptor.handle_drag()
|
||||||
|
|
||||||
↓
|
↓
|
||||||
Extract text from QMimeData
|
DragInterceptor.handle_drag() [core/drag_interceptor.py]
|
||||||
|
├─ Check if Azure URL: Use URLConverter → local path
|
||||||
|
├─ Else: Treat as direct file path
|
||||||
|
└─ Validate with PathValidator
|
||||||
|
|
||||||
↓
|
↓
|
||||||
PathValidator.is_valid_file(path)
|
PathValidator.validate(path)
|
||||||
├─ is_allowed(path) → Check whitelist
|
├─ Resolve to absolute path
|
||||||
└─ path.exists() and path.is_file() → File system check
|
├─ Check file exists (if configured)
|
||||||
|
├─ Check is regular file (not directory)
|
||||||
|
└─ Check path within allowed_roots (whitelist)
|
||||||
|
|
||||||
↓
|
↓
|
||||||
If valid:
|
If valid:
|
||||||
→ Create QUrl.fromLocalFile(path)
|
→ Create QUrl.fromLocalFile(path)
|
||||||
→ Create new QMimeData with URLs
|
→ Create QMimeData with file URL
|
||||||
→ QDrag.exec() → Native file drag
|
→ QDrag.exec(Qt.CopyAction) → Native file drag
|
||||||
|
→ Emit drag_started signal
|
||||||
↓
|
↓
|
||||||
If invalid:
|
If invalid:
|
||||||
→ event.ignore()
|
→ Emit drag_failed signal with error
|
||||||
→ Log warning
|
→ Log validation error
|
||||||
↓
|
↓
|
||||||
OS receives native file drag
|
OS receives native file drag
|
||||||
↓
|
↓
|
||||||
InDesign/Word receives file handle
|
Target application (InDesign/Word) receives file handle
|
||||||
```
|
```
|
||||||
|
|
||||||
|
**Key Components in Data Flow:**
|
||||||
|
|
||||||
|
1. **bridge_script_intercept.js**: Opens a WebChannel to Qt's _DragBridge
|
||||||
|
2. **_DragBridge**: Exposes `start_file_drag()` slot to JavaScript
|
||||||
|
3. **DragInterceptor**: Handles validation and native drag creation
|
||||||
|
4. **URLConverter**: Maps Azure Blob Storage URLs to local paths via config
|
||||||
|
5. **PathValidator**: Security-critical validation against whitelist
|
||||||
|
|
||||||
## Security Model
|
## Security Model
|
||||||
|
|
||||||
### Path Validation Strategy
|
### Path Validation Strategy
|
||||||
|
|
|
||||||
|
|
@ -12,7 +12,7 @@ The configuration file must be named `.env` and contains settings like:
|
||||||
|
|
||||||
```dotenv
|
```dotenv
|
||||||
APP_NAME=WebDrop Bridge
|
APP_NAME=WebDrop Bridge
|
||||||
APP_VERSION=0.1.0
|
APP_VERSION=0.7.1
|
||||||
WEBAPP_URL=https://example.com
|
WEBAPP_URL=https://example.com
|
||||||
ALLOWED_ROOTS=Z:/,C:/Users/Public
|
ALLOWED_ROOTS=Z:/,C:/Users/Public
|
||||||
ALLOWED_URLS=
|
ALLOWED_URLS=
|
||||||
|
|
|
||||||
|
|
@ -1,8 +1,28 @@
|
||||||
# Drag & Drop Problem Analysis - File Drop + Web App Popup
|
# Drag & Drop Problem Analysis - File Drop + Web App Popup
|
||||||
|
|
||||||
## Das Kernproblem
|
**Status**: Phase 1 (File Drop) ✅ Implemented | Phase 2 (Popup Trigger) ⏸️ Planned
|
||||||
|
**Last Updated**: March 3, 2026
|
||||||
|
|
||||||
**Ziel**: Bei ALT-Drag soll:
|
## Overview
|
||||||
|
|
||||||
|
### Current Implementation Status
|
||||||
|
|
||||||
|
✅ **Phase 1 - File Drop (IMPLEMENTED)**
|
||||||
|
- JavaScript in `bridge_script_intercept.js` intercepts drag events
|
||||||
|
- Calls `window.bridge.start_file_drag(url)` via QWebChannel to Qt
|
||||||
|
- Validates path against whitelist via `PathValidator`
|
||||||
|
- Converts Azure Storage URLs to local paths via `URLConverter`
|
||||||
|
- Creates and executes native Qt file drag operation
|
||||||
|
- Target application (InDesign, Word, etc.) successfully receives file
|
||||||
|
|
||||||
|
⏸️ **Phase 2 - Programmatic Popup Trigger (PLANNED)**
|
||||||
|
- Would require reverse-engineering the web app's popup trigger mechanism
|
||||||
|
- Could be implemented by calling JavaScript function after successful drop
|
||||||
|
- Currently: Applications handle popups manually or separately from file drops
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Das Kernproblem
|
||||||
1. ✅ File gedroppt werden (Z:\ Laufwerk) → Native File-Drop
|
1. ✅ File gedroppt werden (Z:\ Laufwerk) → Native File-Drop
|
||||||
2. ✅ Web-App Popup erscheinen (Auschecken-Dialog) → Web-App Drop-Event
|
2. ✅ Web-App Popup erscheinen (Auschecken-Dialog) → Web-App Drop-Event
|
||||||
|
|
||||||
|
|
@ -250,28 +270,39 @@ Object.defineProperty(DataTransfer.prototype, 'types', {
|
||||||
|
|
||||||
## 📝 Empfehlung
|
## 📝 Empfehlung
|
||||||
|
|
||||||
**Sofortige Maßnahmen:**
|
### Current Status (as of March 2026)
|
||||||
|
|
||||||
1. ✅ **Lösung A Phase 1 ist bereits implementiert** (File-Drop funktioniert)
|
✅ **Phase 1 Complete:**
|
||||||
|
- File-drop via native Qt drag operations is fully functional
|
||||||
|
- JavaScript bridge (`bridge_script_intercept.js`) successfully intercepts and converts drags
|
||||||
|
- Path validation and Azure URL mapping working
|
||||||
|
- Tested with real applications (InDesign, Word, etc.)
|
||||||
|
|
||||||
2. 🔍 **Reverse-Engineering durchführen:**
|
### For Future Enhancement (Phase 2 - Popup Trigger)
|
||||||
- GlobalDAM JRI im Browser öffnen
|
|
||||||
- DevTools öffnen (F12)
|
|
||||||
- ALT-Drag+Drop durchführen
|
|
||||||
- Beobachten:
|
|
||||||
- Network-Tab → API-Calls?
|
|
||||||
- Console → Fehler/Logs?
|
|
||||||
- Angular DevTools → Component-Events?
|
|
||||||
|
|
||||||
3. 🛠️ **Popup-Trigger implementieren:**
|
**If popup trigger integration is needed:**
|
||||||
- Sobald bekannt WIE Popup ausgelöst wird
|
|
||||||
- JavaScript-Funktion `trigger_checkout_popup()` erstellen
|
|
||||||
- Von Qt aus nach erfolgreichem Drop aufrufen
|
|
||||||
|
|
||||||
4. 🧪 **Testen:**
|
1. 🔍 **Reverse-Engineering the Target Web App:**
|
||||||
- ALT-Drag eines Assets
|
- Identify how popups are triggered (API call, component method, event, etc.)
|
||||||
- File-Drop sollte funktionieren
|
- Use browser DevTools:
|
||||||
- Popup sollte erscheinen
|
- Network tab → Monitor API calls
|
||||||
|
- Console → Check for JavaScript errors/logs
|
||||||
|
- Elements → Inspect component structure
|
||||||
|
- Angular/Vue DevTools if applicable
|
||||||
|
|
||||||
**Fallback:**
|
2. 🛠️ **Implement Popup Trigger:**
|
||||||
Falls Reverse-Engineering zu komplex ist → **Lösung B** verwenden (Kein Drag, nur Copy nach Popup-Bestätigung)
|
- Create JavaScript hook function (e.g., `window.trigger_popup(assetId)`)
|
||||||
|
- Connect to drop success signal from Qt
|
||||||
|
- Call popup trigger after successful file drop
|
||||||
|
|
||||||
|
3. 🧪 **Test Integration:**
|
||||||
|
- Verify file drops successfully
|
||||||
|
- Verify popup appears after drop
|
||||||
|
- Test with real assets/files
|
||||||
|
|
||||||
|
**Alternative Approaches:**
|
||||||
|
|
||||||
|
- **Lösung B (Manual)**: Keep file drop and popup as separate user actions
|
||||||
|
- **Lösung C (Complex)**: Use overlay window approach (more involved)
|
||||||
|
|
||||||
|
Current implementation uses **Phase 1 of Lösung A** and is production-ready.
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue