diff --git a/.gitignore b/.gitignore
index acc2262..1a57d56 100644
--- a/.gitignore
+++ b/.gitignore
@@ -4,7 +4,6 @@ uploads/
.env
.DS_Store
Thumbs.db
-webdav-tree.json
203_cert.pem
203_key.pem
private-key.pem
diff --git a/README.md b/README.md
index 680cffa..b3ca509 100644
--- a/README.md
+++ b/README.md
@@ -1,6 +1,6 @@
# DOCX Template Server
-Ein Node.js-Server für die automatische Verarbeitung von DOCX-Templates mit WebDAV-ähnlicher Dateifreigabe.
+Ein Node.js-Server für die automatische Verarbeitung von DOCX-Templates mit Management-GUI.
## ✨ Features
@@ -25,9 +25,11 @@ npm start
## 🌐 Zugriff
-- **Web-Interface:** http://localhost:80
-- **Templates:** http://localhost:80/webdav/templates/
-- **Dokumente:** http://localhost:80/webdav/documents/
+### 🌐 **Web-Zugriff:**
+- **Server:** http://localhost:80/
+- **Management:** http://localhost:3000/
+- **Templates:** http://localhost:80/templates/
+- **Dokumente:** http://localhost:80/documents/
## 📋 Verwendung
@@ -41,7 +43,8 @@ Erstellen Sie ein DOCX-Dokument mit Tags wie:
### 2. Template hochladen
- Über Web-Interface: Datei auswählen und hochladen
- Über API: `POST /upload-template`
-- Über Dateifreigabe: Datei in `/webdav/templates/` kopieren
+- Über Web-Upload: http://localhost:80/ → "Template hochladen"
+- Direkt in Ordner: Datei in `/templates/` kopieren
### 3. Automatische Verarbeitung
Der Server erkennt automatisch alle Tags und füllt sie mit passenden Demo-Daten:
@@ -125,25 +128,12 @@ Body: {
}
```
-## 💾 Dateifreigabe Setup
+## 🌐 HTTP-Zugriff
-### Windows Explorer
-1. Windows Explorer öffnen
-2. Adressleiste: `\\localhost\webdav$`
-3. Oder: "Netzlaufwerk verbinden" → `http://localhost:80/webdav/templates/`
-
-### Linux/macOS
-```bash
-# Verzeichnis erstellen
-sudo mkdir -p /mnt/docx-templates
-sudo mkdir -p /mnt/docx-documents
-
-# Mounten (davfs2 erforderlich)
-sudo mount -t davfs http://localhost:80/webdav/templates/ /mnt/docx-templates
-sudo mount -t davfs http://localhost:80/webdav/documents/ /mnt/docx-documents
-
-# Oder über GUI: Dateimanager → "Mit Server verbinden" → http://localhost:80/webdav/templates/
-```
+### Direkte HTTP-URLs:
+Templates und generierte Dokumente sind über HTTP zugänglich:
+- **Templates:** http://localhost:80/templates/
+- **Dokumente:** http://localhost:80/documents/
## 🔒 SSL/HTTPS Einrichtung
@@ -297,15 +287,10 @@ ls -la private-key.pem certificate.pem
- Tags richtig geschrieben (`{tag}` nicht `{{tag}}`)?
- Datei-Berechtigungen prüfen
-### Dateifreigabe funktioniert nicht
-```bash
-# WebDAV-Client installieren
-# Ubuntu/Debian:
-sudo apt install davfs2
-
-# macOS:
-brew install davfs2
-```
+### Templates nicht sichtbar
+Prüfen Sie:
+- Server läuft: `http://localhost:80/`
+- Templates-Ordner: `http://localhost:80/templates/`
### SSL-Probleme
```bash
diff --git a/SCHREIBSCHUTZ-BEHOBEN.md b/SCHREIBSCHUTZ-BEHOBEN.md
deleted file mode 100644
index 6d878d0..0000000
--- a/SCHREIBSCHUTZ-BEHOBEN.md
+++ /dev/null
@@ -1,127 +0,0 @@
-# 🔓 SCHREIBSCHUTZ-PROBLEM BEHOBEN!
-
-## ✅ **Erweiterte WebDAV-Implementierung**
-
-Ich habe die WebDAV-Implementierung erweitert, um das Schreibschutz-Problem zu lösen:
-
-### 🔧 **Was wurde verbessert:**
-
-#### **1. Erweiterte WebDAV-Properties:**
-- `F` - Explizit NICHT schreibgeschützt
-- `F` - Microsoft Office spezifisch
-- `F` - Nicht ausführbar
-- `F` - Nicht versteckt
-
-#### **2. Office-kompatible HTTP-Header:**
-- `Server: Microsoft-IIS/10.0` - Word erkennt als IIS-Server
-- `DAV: 1, 2, ordered-collections, versioning` - Vollständige WebDAV-Unterstützung
-- `Cache-Control: no-cache` - Keine Zwischenspeicherung
-- `ETag` und `Last-Modified` für Versionskontrolle
-
-#### **3. Automatische Dateiberechtigungen:**
-- Dateien werden mit `chmod 666` (rw-rw-rw-) gespeichert
-- Explizite Schreibrechte für alle Benutzer
-
-#### **4. Bessere Lock-Unterstützung:**
-- Sowohl exklusive als auch geteilte Locks
-- Office-kompatible Lock-Token
-
-### 📝 **Neue Word-Integration:**
-
-#### **Schritt 1: WebDAV-Netzlaufwerk einrichten**
-```
-1. Windows Explorer öffnen
-2. "Dieser PC" → Rechtsklick → "Netzlaufwerk verbinden"
-3. Ordner: \\localhost\webdav\templates (oder \documents)
-4. Port: 80
-5. NICHT "Mit anderen Anmeldeinformationen" ankreuzen
-```
-
-#### **Schritt 2: In Word öffnen**
-```
-1. Word öffnen
-2. Datei → Öffnen
-3. Das neue Netzlaufwerk auswählen
-4. Template öffnen
-```
-
-#### **Schritt 3: Test der Schreibrechte**
-```
-1. Text bearbeiten
-2. Strg+S drücken
-3. Sollte jetzt DIREKT auf dem Server speichern!
-```
-
-### 🚨 **Troubleshooting:**
-
-#### **Falls immer noch schreibgeschützt:**
-
-**Option 1: Dateiberechtigungen prüfen**
-```bash
-cd /home/OfficeServerJS/templates
-ls -la *.docx
-# Sollte zeigen: -rw-rw-rw-
-```
-
-**Option 2: Alternative WebDAV-URL**
-```
-Statt: http://localhost:80/webdav/templates/
-Verwenden: http://localhost/webdav/templates/
-Oder: http://127.0.0.1:80/webdav/templates/
-```
-
-**Option 3: Windows WebDAV-Client konfigurieren**
-```cmd
-# Als Administrator ausführen:
-net stop webclient
-net start webclient
-
-# WebDAV Registry-Einstellungen:
-reg add HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\WebClient\Parameters /v BasicAuthLevel /t REG_DWORD /d 2 /f
-```
-
-**Option 4: Office Trust Center**
-```
-1. Word → Datei → Optionen
-2. Trust Center → Trust Center-Einstellungen
-3. Geschützte Ansicht → Alle Häkchen entfernen
-4. Datenschutz-Optionen → "Dateien aus dem Internet..." deaktivieren
-```
-
-### 🔍 **Live-Monitoring:**
-
-Der Server zeigt jetzt Live-Logs:
-```
-📖 Word öffnet Template: rechnung_template.docx
-📝 Word speichert Template: rechnung_template.docx
-✅ Template gespeichert: rechnung_template.docx
-```
-
-### 🎯 **Test-Verfahren:**
-
-1. **Server-Logs beobachten** beim Öffnen/Speichern
-2. **Datei-Timestamps prüfen** nach dem Speichern
-3. **Browser-Zugriff testen**: http://localhost:80/webdav/templates/
-
-### ⚡ **Sofort-Test:**
-
-```bash
-# 1. Datei über WebDAV hochladen
-curl -X PUT --data-binary @test.docx http://localhost:80/webdav/templates/test.docx
-
-# 2. Berechtigung prüfen
-ls -la /home/OfficeServerJS/templates/test.docx
-
-# 3. WebDAV-Properties abfragen
-curl -X PROPFIND -H "Depth: 1" http://localhost:80/webdav/templates/test.docx
-```
-
-## 🎉 **Ergebnis:**
-
-✅ **Erweiterte WebDAV-Properties** für Office-Kompatibilität
-✅ **Explizite Schreibrechte** in XML-Response
-✅ **Automatische Dateiberechtigungen** beim Speichern
-✅ **Office-optimierte HTTP-Header**
-✅ **Live-Monitoring** für Debugging
-
-**Word sollte jetzt die Dateien als beschreibbar erkennen und direkt auf dem Server speichern! 🔓✍️**
\ No newline at end of file
diff --git a/SSL-SETUP.md b/SSL-SETUP.md
index b1ce845..dd83b0c 100644
--- a/SSL-SETUP.md
+++ b/SSL-SETUP.md
@@ -41,13 +41,13 @@ cd /home/OfficeServerJS
### HTTP (immer verfügbar):
- **Web-Interface:** http://localhost:80
-- **Templates:** http://localhost:80/webdav/templates/
-- **Dokumente:** http://localhost:80/webdav/documents/
+- **Templates:** http://localhost:80/templates/
+- **Dokumente:** http://localhost:80/documents/
### HTTPS (nach SSL-Aktivierung):
- **Web-Interface:** https://localhost:443
-- **Templates:** https://localhost:443/webdav/templates/
-- **Dokumente:** https://localhost:443/webdav/documents/
+- **Templates:** https://localhost:443/templates/
+- **Dokumente:** https://localhost:443/documents/
## 🔧 Zertifikat-Validierung
diff --git a/SSL-SUCCESS.md b/SSL-SUCCESS.md
index 3f5df15..b4bd9eb 100644
--- a/SSL-SUCCESS.md
+++ b/SSL-SUCCESS.md
@@ -15,14 +15,14 @@ Ihr DOCX Template Server läuft jetzt mit **vollständiger SSL-Verschlüsselung*
#### HTTP (Port 80):
- **Web-Interface:** http://localhost:80
-- **Templates:** http://localhost:80/webdav/templates/
-- **Dokumente:** http://localhost:80/webdav/documents/
+- **Templates:** http://localhost:80/templates/
+- **Dokumente:** http://localhost:80/documents/
- **API:** http://localhost:80/api/
#### HTTPS (Port 443) - **NEU AKTIV**:
- **Web-Interface:** https://localhost:443
-- **Templates:** https://localhost:443/webdav/templates/
-- **Dokumente:** https://localhost:443/webdav/documents/
+- **Templates:** https://localhost:443/templates/
+- **Dokumente:** https://localhost:443/documents/
- **API:** https://localhost:443/api/
### 🚀 **Server-Features:**
@@ -31,7 +31,7 @@ Ihr DOCX Template Server läuft jetzt mit **vollständiger SSL-Verschlüsselung*
- ✅ **DOCX-Template-Verarbeitung** mit automatischer Tag-Erkennung
- ✅ **Demo-Daten-Generierung** für alle Tag-Typen
- ✅ **Tabellen-Unterstützung** für Listen und Wiederholungen
-- ✅ **WebDAV-ähnliche Dateifreigabe** ohne Authentifizierung
+- ✅ **HTTP-Dateifreigabe** ohne Authentifizierung
- ✅ **Vollständige API** für programmatischen Zugriff
### 📋 **Einsatz in der Produktion:**
@@ -103,7 +103,7 @@ curl -I -k https://localhost:443
✅ **docxtemplater-Integration** mit intelligenter Tag-Erkennung
✅ **Automatische Demo-Daten-Generierung**
✅ **Tabellen- und Listen-Unterstützung**
-✅ **WebDAV-ähnliche Dateifreigabe** ohne Authentifizierung
+✅ **HTTP-Dateifreigabe** ohne Authentifizierung
✅ **Produktionsbereit** mit vollständiger Dokumentation
**Ihr DOCX Template Server ist vollständig einsatzbereit und SSL-gesichert! 🔒✨**
\ No newline at end of file
diff --git a/STATUS.md b/STATUS.md
index 91c1e8a..e9918a5 100644
--- a/STATUS.md
+++ b/STATUS.md
@@ -8,14 +8,14 @@
- ✅ **Intelligente Tag-Erkennung** - erkennt automatisch alle `{tags}` im Template
- ✅ **Demo-Daten-Generierung** - füllt Tags mit realistischen Testdaten
- ✅ **Tabellen-Unterstützung** - `{#items}...{/items}` für Listen/Tabellen
-- ✅ **WebDAV-ähnliche Dateifreigabe** - Templates und Dokumente ohne Auth zugänglich
+- ✅ **HTTP-Dateifreigabe** - Templates und Dokumente über HTTP zugänglich
- ✅ **Web-Interface** - Benutzerfreundliche Oberfläche
- ✅ **SSL-Vorbereitung** - Ready für HTTPS mit Zertifikaten
### 📁 Verfügbare Endpoints
- ✅ `http://localhost:80` - Web-Interface
-- ✅ `http://localhost:80/webdav/templates/` - Template-Verzeichnis
-- ✅ `http://localhost:80/webdav/documents/` - Dokument-Verzeichnis
+- ✅ `http://localhost:80/templates/` - Template-Verzeichnis
+- ✅ `http://localhost:80/documents/` - Dokument-Verzeichnis
- ✅ `http://localhost:80/api/templates` - Template-API
- ✅ `http://localhost:80/api/documents` - Dokument-API
@@ -48,8 +48,8 @@ Der Server erkennt automatisch und befüllt:
Der Server ist aktiv und einsatzbereit:
- 🌐 Web-Interface: http://localhost:80
-- 📁 Templates: http://localhost:80/webdav/templates/
-- 📁 Dokumente: http://localhost:80/webdav/documents/
+- 📁 Templates: http://localhost:80/templates/
+- 📁 Dokumente: http://localhost:80/documents/
## 🎯 Nächste Schritte:
@@ -78,10 +78,10 @@ Der Server ist aktiv und einsatzbereit:
4. Fertiges Dokument herunterladen
### Upload via Dateifreigabe:
-1. Template in `http://localhost:80/webdav/templates/` kopieren
+1. Template in `http://localhost:80/templates/` hochladen
2. Server erkennt Template automatisch
3. Über API verarbeiten lassen
-4. Ergebnis aus `http://localhost:80/webdav/documents/` abholen
+4. Ergebnis aus `http://localhost:80/documents/` abholen
### API-Verwendung:
```bash
@@ -101,7 +101,7 @@ curl -X POST -H "Content-Type: application/json" \
✅ **Automatische Tag-Erkennung**
✅ **Demo-Daten-Generierung**
✅ **Tabellen-Unterstützung**
-✅ **WebDAV-ähnliche Dateifreigabe** ohne Auth
+✅ **HTTP-Dateifreigabe** ohne Auth
✅ **SSL-Vorbereitung**
✅ **Vollständige Dokumentation**
diff --git a/TABELLE-SUCCESS.md b/TABELLE-SUCCESS.md
index 219924b..79653c4 100644
--- a/TABELLE-SUCCESS.md
+++ b/TABELLE-SUCCESS.md
@@ -38,12 +38,12 @@
### 🌐 **Zugriff auf Templates und Dokumente:**
**HTTP:**
-- Templates: http://localhost:80/webdav/templates/
-- Dokumente: http://localhost:80/webdav/documents/
+- Templates: http://localhost:80/templates/
+- Dokumente: http://localhost:80/documents/
**HTTPS:**
-- Templates: https://localhost:443/webdav/templates/
-- Dokumente: https://localhost:443/webdav/documents/
+- Templates: https://localhost:443/templates/
+- Dokumente: https://localhost:443/documents/
### 🧪 **Demo-Daten werden automatisch generiert:**
- **Position:** 1, 2, 3, 4, 5... (fortlaufend)
diff --git a/WEBDAV-INTEGRATION.md b/WEBDAV-INTEGRATION.md
deleted file mode 100644
index 404bb7d..0000000
--- a/WEBDAV-INTEGRATION.md
+++ /dev/null
@@ -1,106 +0,0 @@
-# 🔗 WORD-WEBDAV-INTEGRATION EINGERICHTET!
-
-## ✅ **Server mit echter WebDAV-Unterstützung**
-
-Ihr Server unterstützt jetzt **echte WebDAV-Funktionen** für direktes Speichern in Word/Office:
-
-### 🌐 **WebDAV-Endpunkte:**
-- **Templates:** http://localhost:80/webdav/templates/
-- **Dokumente:** http://localhost:80/webdav/documents/
-- **HTTPS Templates:** https://localhost:443/webdav/templates/
-- **HTTPS Dokumente:** https://localhost:443/webdav/documents/
-
-## 📝 **Word-Integration Setup:**
-
-### **Methode 1: Word → Datei → Öffnen → Netzwerk hinzufügen**
-1. Öffnen Sie Microsoft Word
-2. Gehen Sie zu **Datei** → **Öffnen**
-3. Klicken Sie auf **Netzwerk hinzufügen**
-4. Wählen Sie **WebDAV**
-5. Geben Sie ein: `http://localhost:80/webdav/templates/`
-6. **Kein Benutzername/Passwort erforderlich** (einfach OK klicken)
-
-### **Methode 2: Windows Explorer → Netzlaufwerk**
-1. Öffnen Sie Windows Explorer
-2. Rechtsklick auf **Dieser PC**
-3. **Netzlaufwerk verbinden**
-4. Als Ordner eingeben: `http://localhost:80/webdav/templates/`
-5. **"Anmeldung mit anderen Anmeldeinformationen"** NICHT ankreuzen
-
-### **Methode 3: Direkte URL in Word**
-- Templates: `\\localhost@80\webdav\templates\`
-- Dokumente: `\\localhost@80\webdav\documents\`
-
-## 🔧 **Was jetzt funktioniert:**
-
-### ✅ **WebDAV-Funktionen implementiert:**
-- **PROPFIND** - Dateilisten für Office
-- **GET/PUT** - Dateien öffnen und speichern
-- **LOCK/UNLOCK** - Office-Sperrmechanismus
-- **DAV-Header** - Word erkennt WebDAV-Server
-
-### ✅ **Word-Integration:**
-- **Direktes Öffnen** von Templates über WebDAV
-- **Automatisches Speichern** auf dem Server (nicht lokal!)
-- **Versionskontrolle** durch Server-basierte Speicherung
-- **Gleichzeitiges Arbeiten** mit Locks
-
-### ✅ **API erweitert:**
-```json
-{
- "templates": [
- {
- "name": "rechnung_template.docx",
- "fileUrl": "http://localhost:80/webdav/templates/rechnung_template.docx",
- "wordWebdavUrl": "ms-word:ofe|u|http://localhost:80/webdav/templates/rechnung_template.docx",
- "wordDirectUrl": "word:ofe|u|http://localhost:80/webdav/templates/rechnung_template.docx",
- "downloadUrl": "http://localhost:80/webdav/templates/rechnung_template.docx",
- "webdavDirect": "\\\\localhost@80\\webdav\\templates\\rechnung_template.docx"
- }
- ]
-}
-```
-
-## 🎯 **So funktioniert das Speichern:**
-
-### **Vorher (Problem):**
-- Word öffnet Datei → Bearbeiten → **Speichern geht nur lokal**
-
-### **Jetzt (Lösung):**
-- Word öffnet über WebDAV → Bearbeiten → **Speichern geht direkt auf Server!**
-
-## 🔍 **Test der WebDAV-Funktionen:**
-
-### Server-Status prüfen:
-```bash
-curl -X PROPFIND -H "Depth: 1" http://localhost:80/webdav/templates/
-```
-
-### Datei hochladen via WebDAV:
-```bash
-curl -X PUT --data-binary @meine_datei.docx http://localhost:80/webdav/templates/meine_datei.docx
-```
-
-### API-Test:
-```bash
-curl http://localhost:80/api/templates
-```
-
-## 📋 **Anleitung für Benutzer:**
-
-1. **Word öffnen**
-2. **Datei → Öffnen → Netzwerk hinzufügen → WebDAV**
-3. **URL eingeben:** `http://localhost:80/webdav/templates/`
-4. **Template auswählen und öffnen**
-5. **Bearbeiten**
-6. **Strg+S drücken** → **Speichert automatisch auf dem Server!**
-
-## 🚀 **Ergebnis:**
-
-✅ **Echte WebDAV-Integration** für Office
-✅ **Direktes Speichern** auf dem Server
-✅ **Keine lokalen Kopien** mehr nötig
-✅ **Professioneller Workflow** für Teams
-✅ **Zentrale Datenverwaltung** auf dem Server
-
-**Word speichert jetzt automatisch auf dem Server, wenn über WebDAV geöffnet! 🎉**
\ No newline at end of file
diff --git a/documents/final-test-custom-tags.docx b/documents/final-test-custom-tags.docx
new file mode 100644
index 0000000..74a8d51
Binary files /dev/null and b/documents/final-test-custom-tags.docx differ
diff --git a/documents/test-all-custom-tags.docx b/documents/test-all-custom-tags.docx
new file mode 100644
index 0000000..f6abbb8
Binary files /dev/null and b/documents/test-all-custom-tags.docx differ
diff --git a/documents/test-with-custom-tags.docx b/documents/test-with-custom-tags.docx
new file mode 100644
index 0000000..32e3ac4
Binary files /dev/null and b/documents/test-with-custom-tags.docx differ
diff --git a/server_old.js b/server_old.js
deleted file mode 100644
index 4a758ba..0000000
--- a/server_old.js
+++ /dev/null
@@ -1,939 +0,0 @@
-const express = require('express');
-const Docxtemplater = require('docxtemplater');
-const PizZip = require('pizzip');
-const fs = require('fs');
-const path = require('path');
-const multer = require('multer');
-const cors = require('cors');
-const helmet = require('helmet');
-const https = require('https');
-const crypto = require('crypto');
-const { faker } = require('@faker-js/faker');
-
-const app = express();
-const PORT = process.env.PORT || 80;
-
-// Middleware
-app.use(helmet());
-app.use(cors());
-app.use(express.json());
-app.use(express.urlencoded({ extended: true }));
-
-// Verzeichnisse erstellen
-const templateDir = path.join(__dirname, 'templates');
-const outputDir = path.join(__dirname, 'documents');
-
-[templateDir, outputDir].forEach(dir => {
- if (!fs.existsSync(dir)) {
- fs.mkdirSync(dir, { recursive: true });
- }
-});
-
-// WebDAV-Implementierung für Word/Office-Integration mit SharePoint-Kompatibilität
-const webdavMethods = ['PROPFIND', 'PROPPATCH', 'MKCOL', 'COPY', 'MOVE', 'LOCK', 'UNLOCK'];
-
-// SharePoint-spezifische Namespaces und Header
-const sharePointNamespaces = {
- 'xmlns:D': 'DAV:',
- 'xmlns:S': 'http://schemas.microsoft.com/sharepoint/soap/',
- 'xmlns:Z': 'urn:schemas-microsoft-com:',
- 'xmlns:O': 'urn:schemas-microsoft-com:office:office',
- 'xmlns:T': 'http://schemas.microsoft.com/repl/'
-};
-
-// WebDAV PROPFIND Handler mit SharePoint-Modus
-app.use('/webdav', (req, res, next) => {
- // Erweiterte CORS und WebDAV-Header für Office/SharePoint
- res.set({
- 'DAV': '1, 2, ordered-collections, versioning, extended-mkcol',
- 'MS-Author-Via': 'DAV',
- 'Server': 'Microsoft-IIS/10.0 Microsoft-HTTPAPI/2.0',
- 'MicrosoftSharePointTeamServices': '15.0.0.4569',
- 'SPRequestGuid': `{${crypto.randomUUID()}}`,
- 'SPIisLatency': '0',
- 'Allow': 'GET, HEAD, POST, PUT, DELETE, OPTIONS, PROPFIND, PROPPATCH, MKCOL, COPY, MOVE, LOCK, UNLOCK',
- 'Access-Control-Allow-Origin': '*',
- 'Access-Control-Allow-Methods': 'GET, HEAD, POST, PUT, DELETE, OPTIONS, PROPFIND, PROPPATCH, MKCOL, COPY, MOVE, LOCK, UNLOCK',
- 'Access-Control-Allow-Headers': 'Content-Type, Depth, Authorization, Destination, If, Lock-Token, Overwrite, Timeout, X-Requested-With, SOAPAction',
- 'Cache-Control': 'no-cache, no-store, must-revalidate',
- 'Pragma': 'no-cache',
- 'Expires': '0',
- 'X-SharePointHealthScore': '0',
- 'X-AspNet-Version': '4.0.30319',
- 'X-Powered-By': 'ASP.NET'
- });
-
- if (req.method === 'OPTIONS') {
- return res.status(200).end();
- }
-
- if (req.method === 'PROPFIND') {
- const depth = req.headers.depth || 'infinity';
- const requestPath = req.path.replace('/webdav', '');
-
- let targetDir;
- if (requestPath.startsWith('/templates')) {
- targetDir = path.join(templateDir, requestPath.replace('/templates', ''));
- } else if (requestPath.startsWith('/documents')) {
- targetDir = path.join(outputDir, requestPath.replace('/documents', ''));
- } else {
- targetDir = __dirname;
- }
-
- try {
- let items = [];
-
- if (fs.existsSync(targetDir)) {
- const stats = fs.statSync(targetDir);
-
- if (stats.isDirectory()) {
- const files = fs.readdirSync(targetDir);
-
- // Verzeichnis selbst
- items.push({
- href: req.path + (req.path.endsWith('/') ? '' : '/'),
- isDirectory: true,
- lastModified: stats.mtime.toUTCString(),
- size: 0
- });
-
- // Dateien im Verzeichnis
- files.forEach(file => {
- const filePath = path.join(targetDir, file);
- const fileStats = fs.statSync(filePath);
-
- items.push({
- href: req.path + (req.path.endsWith('/') ? '' : '/') + file,
- isDirectory: fileStats.isDirectory(),
- lastModified: fileStats.mtime.toUTCString(),
- size: fileStats.size || 0,
- contentType: fileStats.isDirectory() ? 'httpd/unix-directory' : 'application/vnd.openxmlformats-officedocument.wordprocessingml.document'
- });
- });
- } else {
- // Einzelne Datei
- items.push({
- href: req.path,
- isDirectory: false,
- lastModified: stats.mtime.toUTCString(),
- size: stats.size,
- contentType: 'application/vnd.openxmlformats-officedocument.wordprocessingml.document'
- });
- }
- }
-
- // WebDAV XML Response mit SharePoint-spezifischen Eigenschaften
- const xmlResponse = `
-
-${items.map(item => `
-
- ${item.href}
-
-
- ${path.basename(item.href)}
- ${item.lastModified}
- ${item.size}
- ${item.contentType}
- ${item.isDirectory ? '' : ''}
-
-
-
-
-
-
-
-
-
-
- "${Date.now()}-${item.size}"
- ${new Date(item.lastModified).toISOString()}
- ${item.isDirectory ? 'true' : 'false'}
- F
- F
- F
- F
- ${new Date(item.lastModified).toISOString()}
- ${new Date().toISOString()}
- ${new Date(item.lastModified).toISOString()}
- 00000020
- System Account
-
- 0
-
- 1
- 0x0101
- 0
-
- HTTP/1.1 200 OK
-
- `).join('')}
-`;
-
- res.set('Content-Type', 'application/xml; charset=utf-8');
- res.status(207).send(xmlResponse);
- } catch (error) {
- res.status(404).send('Not Found');
- }
- return;
- }
-
- next();
-});
-
-// WebDAV PUT Handler für Dateien speichern
-// PUT - File Upload (für Word Speichern)
-app.put('/dav/*', (req, res) => {
- const filePath = path.join(__dirname, 'uploads', req.params[0]);
- const dirPath = path.dirname(filePath);
-
- console.log(`� PUT Request: ${req.params[0]}`);
- console.log(`📂 Speichere nach: ${filePath}`);
-
- // Stelle sicher dass der Ordner existiert
- fs.mkdirSync(dirPath, { recursive: true });
-
- const writeStream = fs.createWriteStream(filePath);
-
- req.pipe(writeStream);
-
- writeStream.on('finish', () => {
- console.log(`✅ Datei gespeichert: ${filePath}`);
- res.set({
- 'DAV': '1, 2, ordered-collections, versioning, extended-mkcol',
- 'MS-Author-Via': 'DAV',
- 'Server': 'Microsoft-IIS/10.0 Microsoft-HTTPAPI/2.0',
- 'MicrosoftSharePointTeamServices': '15.0.0.4569',
- 'SPRequestGuid': `{${crypto.randomUUID()}}`,
- 'Cache-Control': 'no-cache',
- 'ETag': `"${Date.now()}-${req.headers['content-length'] || 0}"`,
- 'Last-Modified': new Date().toUTCString(),
- 'X-SharePoint-HealthScore': '0'
- });
- res.status(201).send('Created');
- });
-
- writeStream.on('error', (err) => {
- console.error(`❌ Fehler beim Speichern: ${err.message}`);
- res.status(500).send('Internal Server Error');
- });
-});
-
-app.put('/webdav/documents/:filename', (req, res) => {
- const filename = req.params.filename;
- const filePath = path.join(outputDir, filename);
-
- console.log(`📝 Word speichert Dokument: ${filename}`);
-
- const writeStream = fs.createWriteStream(filePath);
- req.pipe(writeStream);
-
- writeStream.on('finish', () => {
- // Dateirechte explizit setzen
- try {
- fs.chmodSync(filePath, 0o666); // Lese-/Schreibrechte für alle
- } catch (error) {
- console.warn('Warnung: Konnte Dateiberechtigungen nicht setzen:', error.message);
- }
-
- res.set({
- 'DAV': '1, 2, ordered-collections, versioning',
- 'MS-Author-Via': 'DAV',
- 'Server': 'Microsoft-IIS/10.0',
- 'Cache-Control': 'no-cache',
- 'ETag': `"${Date.now()}-${req.headers['content-length'] || 0}"`,
- 'Last-Modified': new Date().toUTCString()
- });
- res.status(201).send('Created');
- console.log(`✅ Dokument gespeichert: ${filename}`);
- });
-
- writeStream.on('error', (error) => {
- console.error('❌ Fehler beim Speichern:', error);
- res.status(500).send('Internal Server Error');
- });
-});
-
-// WebDAV GET Handler für Dateien lesen
-app.get('/webdav/templates/:filename', (req, res) => {
- const filename = req.params.filename;
- const filePath = path.join(templateDir, filename);
-
- if (fs.existsSync(filePath)) {
- const stats = fs.statSync(filePath);
- res.set({
- 'DAV': '1, 2, ordered-collections, versioning',
- 'MS-Author-Via': 'DAV',
- 'Server': 'Microsoft-IIS/10.0',
- 'Content-Type': 'application/vnd.openxmlformats-officedocument.wordprocessingml.document',
- 'Content-Length': stats.size,
- 'Last-Modified': stats.mtime.toUTCString(),
- 'ETag': `"${stats.mtime.getTime()}-${stats.size}"`,
- 'Accept-Ranges': 'bytes',
- 'Cache-Control': 'no-cache'
- });
- console.log(`📖 Word öffnet Template: ${filename}`);
- res.sendFile(filePath);
- } else {
- res.status(404).send('Not Found');
- }
-});
-
-app.get('/webdav/documents/:filename', (req, res) => {
- const filename = req.params.filename;
- const filePath = path.join(outputDir, filename);
-
- if (fs.existsSync(filePath)) {
- const stats = fs.statSync(filePath);
- res.set({
- 'DAV': '1, 2, ordered-collections, versioning',
- 'MS-Author-Via': 'DAV',
- 'Server': 'Microsoft-IIS/10.0',
- 'Content-Type': 'application/vnd.openxmlformats-officedocument.wordprocessingml.document',
- 'Content-Length': stats.size,
- 'Last-Modified': stats.mtime.toUTCString(),
- 'ETag': `"${stats.mtime.getTime()}-${stats.size}"`,
- 'Accept-Ranges': 'bytes',
- 'Cache-Control': 'no-cache'
- });
- console.log(`📖 Word öffnet Dokument: ${filename}`);
- res.sendFile(filePath);
- } else {
- res.status(404).send('Not Found');
- }
-});
-
-// WebDAV LOCK/UNLOCK für Office
-app.use('/webdav', (req, res, next) => {
- if (req.method === 'LOCK') {
- const lockToken = 'opaquelocktoken:' + Date.now() + '-' + Math.random().toString(36).substr(2, 9);
-
- const lockResponse = `
-
-
-
-
-
- 0
- Second-604800
- ${lockToken}
-
-
-`;
-
- res.set({
- 'Content-Type': 'application/xml; charset=utf-8',
- 'Lock-Token': `<${lockToken}>`,
- 'DAV': '1, 2',
- 'MS-Author-Via': 'DAV'
- });
- res.status(200).send(lockResponse);
- return;
- }
-
- if (req.method === 'UNLOCK') {
- res.set({
- 'DAV': '1, 2',
- 'MS-Author-Via': 'DAV'
- });
- res.status(204).send();
- return;
- }
-
- next();
-});
-
-app.use('/webdav/documents', express.static(outputDir, {
- setHeaders: (res, path) => {
- res.set({
- 'DAV': '1, 2',
- 'Allow': 'GET, PUT, DELETE, PROPFIND, PROPPATCH, MKCOL, COPY, MOVE, HEAD, OPTIONS',
- 'Access-Control-Allow-Origin': '*',
- 'Access-Control-Allow-Methods': 'GET, PUT, DELETE, PROPFIND, PROPPATCH, MKCOL, COPY, MOVE, HEAD, OPTIONS',
- 'Access-Control-Allow-Headers': 'Content-Type, Depth, Authorization, If-Match, If-None-Match, Overwrite, Destination',
- 'MS-Author-Via': 'DAV',
- 'Cache-Control': 'no-cache'
- });
- }
-}));
-
-// WebDAV PROPFIND Support für Word
-app.use('/webdav/*', (req, res, next) => {
- if (req.method === 'PROPFIND') {
- res.set({
- 'Content-Type': 'application/xml; charset=utf-8',
- 'DAV': '1, 2',
- 'MS-Author-Via': 'DAV'
- });
-
- const propfindResponse = `
-
-
- ${req.originalUrl}
-
- HTTP/1.1 200 OK
-
-
- httpd/unix-directory
-
-
-
-
-
-
-
-
-
-`;
-
- res.status(207).send(propfindResponse);
- return;
- }
- next();
-});
-
-// SharePoint-spezifische Endpunkte
-app.get('/_vti_inf.html', (req, res) => {
- // SharePoint Info-Seite
- res.set('Content-Type', 'text/html');
- res.send(``);
-});
-
-app.post('/_vti_bin/lists.asmx', (req, res) => {
- // SharePoint Lists Web Service
- res.set({
- 'Content-Type': 'text/xml; charset=utf-8',
- 'SOAPAction': req.headers.soapaction || ''
- });
-
- const soapResponse = `
-
-
-
-
-
-
-
-
-
-
-`;
-
- res.send(soapResponse);
-});
-
-app.get('/_vti_bin/owssvr.dll', (req, res) => {
- // SharePoint OWS Service
- if (req.query.Cmd === 'Display' && req.query.List) {
- res.set('Content-Type', 'text/xml');
- res.send(`
-
-
-
-
-
-
-
-
-
-
-
-`);
- } else {
- res.status(404).send('Not Found');
- }
-});
-
-// SharePoint-kompatible WebDAV-Root
-app.use('/sharepoint', (req, res, next) => {
- // SharePoint-spezifische Header
- res.set({
- 'MicrosoftSharePointTeamServices': '15.0.0.4569',
- 'SharePointHealthScore': '0',
- 'SPRequestGuid': `{${crypto.randomUUID()}}`,
- 'X-SharePoint-HealthScore': '0'
- });
-
- // Weiterleitung zu WebDAV
- const newPath = req.path.replace('/sharepoint', '/webdav');
- req.url = newPath;
- next();
-});
-
-console.log('SharePoint-Kompatibilitätsmodus aktiviert:');
-console.log('SharePoint WebDAV: http://localhost:' + (process.env.PORT || 80) + '/sharepoint/templates/');
-console.log('SharePoint Info: http://localhost:' + (process.env.PORT || 80) + '/_vti_inf.html');
-
-// Multer für File Upload
-const upload = multer({ dest: 'uploads/' });
-
-// Demo-Daten Generator
-class DemoDataGenerator {
- static generateData(tags) {
- const data = {};
-
- tags.forEach(tag => {
- const lowerTag = tag.toLowerCase();
-
- if (lowerTag.includes('name') || lowerTag.includes('vorname')) {
- data[tag] = faker.person.firstName();
- } else if (lowerTag.includes('nachname') || lowerTag.includes('surname')) {
- data[tag] = faker.person.lastName();
- } else if (lowerTag.includes('email') || lowerTag.includes('mail')) {
- data[tag] = faker.internet.email();
- } else if (lowerTag.includes('telefon') || lowerTag.includes('phone')) {
- data[tag] = faker.phone.number();
- } else if (lowerTag.includes('adresse') || lowerTag.includes('address')) {
- data[tag] = faker.location.streetAddress();
- } else if (lowerTag.includes('stadt') || lowerTag.includes('city')) {
- data[tag] = faker.location.city();
- } else if (lowerTag.includes('plz') || lowerTag.includes('postal')) {
- data[tag] = faker.location.zipCode();
- } else if (lowerTag.includes('land') || lowerTag.includes('country')) {
- data[tag] = faker.location.country();
- } else if (lowerTag.includes('datum') || lowerTag.includes('date')) {
- data[tag] = faker.date.recent().toLocaleDateString('de-DE');
- } else if (lowerTag.includes('betrag') || lowerTag.includes('preis') || lowerTag.includes('amount')) {
- data[tag] = faker.commerce.price();
- } else if (lowerTag.includes('firma') || lowerTag.includes('company')) {
- data[tag] = faker.company.name();
- } else if (lowerTag.includes('produkt') || lowerTag.includes('product')) {
- data[tag] = faker.commerce.productName();
- } else if (lowerTag.includes('beschreibung') || lowerTag.includes('description')) {
- data[tag] = faker.lorem.paragraph();
- } else if (lowerTag.includes('nummer') || lowerTag.includes('number') || lowerTag.includes('id')) {
- data[tag] = faker.string.numeric(6);
- } else {
- // Fallback für unbekannte Tags
- data[tag] = faker.lorem.words(2);
- }
- });
-
- return data;
- }
-
- static generateTableData(tableStructure) {
- const rows = Math.floor(Math.random() * 5) + 2; // 2-6 Zeilen
- const tableData = [];
-
- for (let i = 0; i < rows; i++) {
- const row = {};
- tableStructure.forEach(column => {
- if (column.includes('position')) {
- row[column] = (i + 1).toString(); // Fortlaufende Positionsnummer
- } else {
- row[column] = this.generateData([column])[column];
- }
- });
- tableData.push(row);
- }
-
- return tableData;
- }
-}
-
-// Template Tag Extractor
-class TemplateTagExtractor {
- static extractTags(docxBuffer) {
- try {
- const zip = new PizZip(docxBuffer);
- const doc = new Docxtemplater(zip, {
- paragraphLoop: true,
- linebreaks: true,
- });
-
- // Alle Tags aus dem Template extrahieren
- const tags = new Set();
- const content = zip.file('word/document.xml').asText();
-
- // Einfache Tags: {tag}
- const simpleTagRegex = /{([^{}]+)}/g;
- let match;
- while ((match = simpleTagRegex.exec(content)) !== null) {
- const tag = match[1].trim();
- if (!tag.includes('#') && !tag.includes('/')) {
- tags.add(tag);
- }
- }
-
- // Loop Tags für Tabellen: {#items}...{/items}
- const loopTagRegex = /{#(\w+)}/g;
- const loopTags = [];
- while ((match = loopTagRegex.exec(content)) !== null) {
- loopTags.push(match[1]);
- }
-
- return {
- simpleTags: Array.from(tags),
- loopTags: loopTags
- };
- } catch (error) {
- console.error('Fehler beim Extrahieren der Tags:', error);
- return { simpleTags: [], loopTags: [] };
- }
- }
-}
-
-// Template Processor
-class TemplateProcessor {
- static async processTemplate(templatePath, outputPath, customData = null) {
- try {
- const content = fs.readFileSync(templatePath, 'binary');
- const zip = new PizZip(content);
-
- // Tags extrahieren
- const { simpleTags, loopTags } = TemplateTagExtractor.extractTags(Buffer.from(content, 'binary'));
-
- // Daten generieren oder verwenden
- let data = customData || {};
-
- if (!customData) {
- // Demo-Daten für einfache Tags generieren
- data = DemoDataGenerator.generateData(simpleTags);
-
- // Demo-Daten für Loop Tags (Tabellen) generieren
- loopTags.forEach(loopTag => {
- // Erweiterte Tabellen-Spalten für professionelle Rechnung
- const tableColumns = [`${loopTag}_position`, `${loopTag}_name`, `${loopTag}_value`, `${loopTag}_date`];
- data[loopTag] = DemoDataGenerator.generateTableData(tableColumns);
- });
- }
-
- const doc = new Docxtemplater(zip, {
- paragraphLoop: true,
- linebreaks: true,
- });
-
- doc.render(data);
-
- const buf = doc.getZip().generate({
- type: 'nodebuffer',
- compression: 'DEFLATE',
- });
-
- fs.writeFileSync(outputPath, buf);
-
- return {
- success: true,
- data: data,
- extractedTags: { simpleTags, loopTags }
- };
- } catch (error) {
- console.error('Template Verarbeitung fehlgeschlagen:', error);
- return {
- success: false,
- error: error.message
- };
- }
- }
-}
-
-// Routes
-
-// Hauptseite
-app.get('/', (req, res) => {
- res.send(`
-
-
-
- DOCX Template Server
-
-
-
-
-
-
DOCX Template Server
-
-
-
📄 Template hochladen und verarbeiten
-
-
-
-
-
📁 Office-Integration
-
-
Office-Integration: Öffnen Sie in Word/Excel: Datei → Öffnen → Netzwerk hinzufügen → WebDAV → http://localhost:${PORT}/webdav/templates/
-
Direkt speichern: Word speichert automatisch auf dem Server wenn über WebDAV geöffnet.
-
-
-
-
🔧 API Endpunkte
-
-
Word-Integration: Die API liefert spezielle Links für Microsoft Word:
-
- wordWebdavUrl - Direkt in Word öffnen (ms-word: Protocol)
- wordDirectUrl - Alternative Word-Integration
- webdavDirect - Windows UNC-Pfad für Netzlaufwerk
-
-
-
-
-
📋 Test Template
-
Test Template erstellen
-
Erstellt ein Beispiel-Template mit verschiedenen Tag-Typen für Tests.
-
-
-
-
- `);
-});
-
-// Template Upload und Verarbeitung
-app.post('/upload-template', upload.single('template'), async (req, res) => {
- try {
- if (!req.file) {
- return res.status(400).json({ error: 'Keine Datei hochgeladen' });
- }
-
- const templateName = req.file.originalname;
- const templatePath = path.join(templateDir, templateName);
- const outputName = templateName.replace('.docx', '_ausgefuellt.docx');
- const outputPath = path.join(outputDir, outputName);
-
- // Template in Templates-Verzeichnis kopieren
- fs.copyFileSync(req.file.path, templatePath);
-
- // Template verarbeiten
- const result = await TemplateProcessor.processTemplate(templatePath, outputPath);
-
- // Upload-Datei löschen
- fs.unlinkSync(req.file.path);
-
- if (result.success) {
- const protocol = req.secure ? 'https' : 'http';
- const host = req.get('host') || `localhost:${PORT}`;
-
- res.json({
- message: 'Template erfolgreich verarbeitet',
- templateName: templateName,
- outputName: outputName,
- extractedTags: result.extractedTags,
- generatedData: result.data,
- fileUrls: {
- template: `${protocol}://${host}/webdav/templates/${templateName}`,
- document: `${protocol}://${host}/webdav/documents/${outputName}`,
- wordWebdavTemplate: `ms-word:ofe|u|${protocol}://${host}/webdav/templates/${encodeURIComponent(templateName)}`,
- wordWebdavDocument: `ms-word:ofe|u|${protocol}://${host}/webdav/documents/${encodeURIComponent(outputName)}`,
- wordDirectTemplate: `word:ofe|u|${protocol}://${host}/webdav/templates/${encodeURIComponent(templateName)}`,
- wordDirectDocument: `word:ofe|u|${protocol}://${host}/webdav/documents/${encodeURIComponent(outputName)}`
- }
- });
- } else {
- res.status(500).json({ error: result.error });
- }
- } catch (error) {
- console.error('Upload Fehler:', error);
- res.status(500).json({ error: 'Server Fehler beim Upload' });
- }
-});
-
-// Test Template erstellen
-app.get('/create-test-template', (req, res) => {
- const PizZip = require('pizzip');
-
- // Minimales DOCX Template erstellen
- const testContent = `
-
-
- Firmenname: {firma}
- Ansprechpartner: {vorname} {nachname}
- E-Mail: {email}
- Telefon: {telefon}
- Adresse: {adresse}, {plz} {stadt}
- Datum: {datum}
- Rechnungsnummer: {nummer}
-
- Positionen:
- {#items}
- - {items_name}: {items_value} EUR ({items_date})
- {/items}
-
- Gesamtbetrag: {betrag} EUR
-
- Beschreibung:
- {beschreibung}
-
-
- `;
-
- try {
- // Minimal DOCX Struktur
- const zip = new PizZip();
-
- // document.xml
- zip.file('word/document.xml', testContent);
-
- // [Content_Types].xml
- zip.file('[Content_Types].xml', `
-
-
-
-
- `);
-
- // _rels/.rels
- zip.file('_rels/.rels', `
-
-
- `);
-
- // word/_rels/document.xml.rels
- zip.file('word/_rels/document.xml.rels', `
-
- `);
-
- const buffer = zip.generate({ type: 'nodebuffer' });
- const testTemplatePath = path.join(templateDir, 'test_template.docx');
-
- fs.writeFileSync(testTemplatePath, buffer);
-
- res.json({
- message: 'Test Template erstellt',
- templatePath: 'test_template.docx',
- fileUrl: `http://localhost:${PORT}/webdav/templates/test_template.docx`,
- info: 'Sie können das Template jetzt über den Datei-Server herunterladen, bearbeiten und wieder hochladen.'
- });
- } catch (error) {
- console.error('Fehler beim Erstellen des Test Templates:', error);
- res.status(500).json({ error: 'Fehler beim Erstellen des Test Templates' });
- }
-});
-
-// API Endpunkte
-app.get('/api/templates', (req, res) => {
- try {
- const files = fs.readdirSync(templateDir).filter(file => file.endsWith('.docx'));
- const protocol = req.secure ? 'https' : 'http';
- const host = req.get('host') || `localhost:${PORT}`;
-
- res.json({
- templates: files.map(file => ({
- name: file,
- fileUrl: `${protocol}://${host}/webdav/templates/${file}`,
- wordWebdavUrl: `ms-word:ofe|u|${protocol}://${host}/webdav/templates/${encodeURIComponent(file)}`,
- wordDirectUrl: `word:ofe|u|${protocol}://${host}/webdav/templates/${encodeURIComponent(file)}`,
- downloadUrl: `${protocol}://${host}/webdav/templates/${file}`,
- webdavDirect: `\\\\${host.split(':')[0]}@${PORT}\\webdav\\templates\\${file}`
- }))
- });
- } catch (error) {
- res.status(500).json({ error: 'Fehler beim Auflisten der Templates' });
- }
-});
-
-app.get('/api/documents', (req, res) => {
- try {
- const files = fs.readdirSync(outputDir).filter(file => file.endsWith('.docx'));
- const protocol = req.secure ? 'https' : 'http';
- const host = req.get('host') || `localhost:${PORT}`;
-
- res.json({
- documents: files.map(file => ({
- name: file,
- fileUrl: `${protocol}://${host}/webdav/documents/${file}`,
- wordWebdavUrl: `ms-word:ofe|u|${protocol}://${host}/webdav/documents/${encodeURIComponent(file)}`,
- wordDirectUrl: `word:ofe|u|${protocol}://${host}/webdav/documents/${encodeURIComponent(file)}`,
- downloadUrl: `${protocol}://${host}/webdav/documents/${file}`,
- webdavDirect: `\\\\${host.split(':')[0]}@${PORT}\\webdav\\documents\\${file}`,
- createdAt: fs.statSync(path.join(outputDir, file)).mtime
- }))
- });
- } catch (error) {
- res.status(500).json({ error: 'Fehler beim Auflisten der Dokumente' });
- }
-});
-
-// Template mit benutzerdefinierten Daten verarbeiten
-app.post('/api/process-template/:templateName', (req, res) => {
- try {
- const templateName = req.params.templateName;
- const templatePath = path.join(templateDir, templateName);
-
- if (!fs.existsSync(templatePath)) {
- return res.status(404).json({ error: 'Template nicht gefunden' });
- }
-
- const outputName = templateName.replace('.docx', '_custom.docx');
- const outputPath = path.join(outputDir, outputName);
-
- TemplateProcessor.processTemplate(templatePath, outputPath, req.body).then(result => {
- if (result.success) {
- res.json({
- message: 'Template mit benutzerdefinierten Daten verarbeitet',
- outputName: outputName,
- fileUrl: `http://localhost:${PORT}/webdav/documents/${outputName}`
- });
- } else {
- res.status(500).json({ error: result.error });
- }
- });
- } catch (error) {
- res.status(500).json({ error: 'Fehler beim Verarbeiten des Templates' });
- }
-});
-
-// SSL Konfiguration
-const certPath = path.join(__dirname, '203_cert.pem');
-const keyPath = path.join(__dirname, '203_key.pem');
-
-if (fs.existsSync(keyPath) && fs.existsSync(certPath)) {
- try {
- const sslOptions = {
- key: fs.readFileSync(keyPath),
- cert: fs.readFileSync(certPath)
- };
-
- https.createServer(sslOptions, app).listen(443, () => {
- console.log('🔒 HTTPS Server läuft auf Port 443');
- console.log('🌐 HTTPS Zugang: https://localhost:443');
- });
- } catch (error) {
- console.warn('⚠️ SSL-Zertifikate gefunden, aber Fehler beim Laden:', error.message);
- console.log('ℹ️ Server läuft nur mit HTTP');
- }
-} else {
- console.log('ℹ️ SSL-Zertifikate nicht gefunden - Server läuft nur mit HTTP');
- console.log('💡 Für HTTPS: Platzieren Sie 203_cert.pem und 203_key.pem in /home/OfficeServerJS/');
-}
-
-// Server starten
-app.listen(PORT, () => {
- console.log(`\n🚀 DOCX Template Server gestartet!`);
- console.log(`📍 HTTP Server: http://localhost:${PORT}`);
- console.log(`📁 Templates: http://localhost:${PORT}/webdav/templates/`);
- console.log(`📁 Documents: http://localhost:${PORT}/webdav/documents/`);
- console.log(`\n💡 Tipp: Besuchen Sie http://localhost:${PORT} für die Web-Oberfläche`);
-
- // SSL-Status anzeigen
- const certPath = path.join(__dirname, '203_cert.pem');
- const keyPath = path.join(__dirname, '203_key.pem');
- if (fs.existsSync(keyPath) && fs.existsSync(certPath)) {
- console.log(`🔒 HTTPS auch verfügbar: https://localhost:443`);
- }
-});
-
-module.exports = app;
\ No newline at end of file
diff --git a/server_webdav_backup.js b/server_webdav_backup.js
deleted file mode 100644
index 4a758ba..0000000
--- a/server_webdav_backup.js
+++ /dev/null
@@ -1,939 +0,0 @@
-const express = require('express');
-const Docxtemplater = require('docxtemplater');
-const PizZip = require('pizzip');
-const fs = require('fs');
-const path = require('path');
-const multer = require('multer');
-const cors = require('cors');
-const helmet = require('helmet');
-const https = require('https');
-const crypto = require('crypto');
-const { faker } = require('@faker-js/faker');
-
-const app = express();
-const PORT = process.env.PORT || 80;
-
-// Middleware
-app.use(helmet());
-app.use(cors());
-app.use(express.json());
-app.use(express.urlencoded({ extended: true }));
-
-// Verzeichnisse erstellen
-const templateDir = path.join(__dirname, 'templates');
-const outputDir = path.join(__dirname, 'documents');
-
-[templateDir, outputDir].forEach(dir => {
- if (!fs.existsSync(dir)) {
- fs.mkdirSync(dir, { recursive: true });
- }
-});
-
-// WebDAV-Implementierung für Word/Office-Integration mit SharePoint-Kompatibilität
-const webdavMethods = ['PROPFIND', 'PROPPATCH', 'MKCOL', 'COPY', 'MOVE', 'LOCK', 'UNLOCK'];
-
-// SharePoint-spezifische Namespaces und Header
-const sharePointNamespaces = {
- 'xmlns:D': 'DAV:',
- 'xmlns:S': 'http://schemas.microsoft.com/sharepoint/soap/',
- 'xmlns:Z': 'urn:schemas-microsoft-com:',
- 'xmlns:O': 'urn:schemas-microsoft-com:office:office',
- 'xmlns:T': 'http://schemas.microsoft.com/repl/'
-};
-
-// WebDAV PROPFIND Handler mit SharePoint-Modus
-app.use('/webdav', (req, res, next) => {
- // Erweiterte CORS und WebDAV-Header für Office/SharePoint
- res.set({
- 'DAV': '1, 2, ordered-collections, versioning, extended-mkcol',
- 'MS-Author-Via': 'DAV',
- 'Server': 'Microsoft-IIS/10.0 Microsoft-HTTPAPI/2.0',
- 'MicrosoftSharePointTeamServices': '15.0.0.4569',
- 'SPRequestGuid': `{${crypto.randomUUID()}}`,
- 'SPIisLatency': '0',
- 'Allow': 'GET, HEAD, POST, PUT, DELETE, OPTIONS, PROPFIND, PROPPATCH, MKCOL, COPY, MOVE, LOCK, UNLOCK',
- 'Access-Control-Allow-Origin': '*',
- 'Access-Control-Allow-Methods': 'GET, HEAD, POST, PUT, DELETE, OPTIONS, PROPFIND, PROPPATCH, MKCOL, COPY, MOVE, LOCK, UNLOCK',
- 'Access-Control-Allow-Headers': 'Content-Type, Depth, Authorization, Destination, If, Lock-Token, Overwrite, Timeout, X-Requested-With, SOAPAction',
- 'Cache-Control': 'no-cache, no-store, must-revalidate',
- 'Pragma': 'no-cache',
- 'Expires': '0',
- 'X-SharePointHealthScore': '0',
- 'X-AspNet-Version': '4.0.30319',
- 'X-Powered-By': 'ASP.NET'
- });
-
- if (req.method === 'OPTIONS') {
- return res.status(200).end();
- }
-
- if (req.method === 'PROPFIND') {
- const depth = req.headers.depth || 'infinity';
- const requestPath = req.path.replace('/webdav', '');
-
- let targetDir;
- if (requestPath.startsWith('/templates')) {
- targetDir = path.join(templateDir, requestPath.replace('/templates', ''));
- } else if (requestPath.startsWith('/documents')) {
- targetDir = path.join(outputDir, requestPath.replace('/documents', ''));
- } else {
- targetDir = __dirname;
- }
-
- try {
- let items = [];
-
- if (fs.existsSync(targetDir)) {
- const stats = fs.statSync(targetDir);
-
- if (stats.isDirectory()) {
- const files = fs.readdirSync(targetDir);
-
- // Verzeichnis selbst
- items.push({
- href: req.path + (req.path.endsWith('/') ? '' : '/'),
- isDirectory: true,
- lastModified: stats.mtime.toUTCString(),
- size: 0
- });
-
- // Dateien im Verzeichnis
- files.forEach(file => {
- const filePath = path.join(targetDir, file);
- const fileStats = fs.statSync(filePath);
-
- items.push({
- href: req.path + (req.path.endsWith('/') ? '' : '/') + file,
- isDirectory: fileStats.isDirectory(),
- lastModified: fileStats.mtime.toUTCString(),
- size: fileStats.size || 0,
- contentType: fileStats.isDirectory() ? 'httpd/unix-directory' : 'application/vnd.openxmlformats-officedocument.wordprocessingml.document'
- });
- });
- } else {
- // Einzelne Datei
- items.push({
- href: req.path,
- isDirectory: false,
- lastModified: stats.mtime.toUTCString(),
- size: stats.size,
- contentType: 'application/vnd.openxmlformats-officedocument.wordprocessingml.document'
- });
- }
- }
-
- // WebDAV XML Response mit SharePoint-spezifischen Eigenschaften
- const xmlResponse = `
-
-${items.map(item => `
-
- ${item.href}
-
-
- ${path.basename(item.href)}
- ${item.lastModified}
- ${item.size}
- ${item.contentType}
- ${item.isDirectory ? '' : ''}
-
-
-
-
-
-
-
-
-
-
- "${Date.now()}-${item.size}"
- ${new Date(item.lastModified).toISOString()}
- ${item.isDirectory ? 'true' : 'false'}
- F
- F
- F
- F
- ${new Date(item.lastModified).toISOString()}
- ${new Date().toISOString()}
- ${new Date(item.lastModified).toISOString()}
- 00000020
- System Account
-
- 0
-
- 1
- 0x0101
- 0
-
- HTTP/1.1 200 OK
-
- `).join('')}
-`;
-
- res.set('Content-Type', 'application/xml; charset=utf-8');
- res.status(207).send(xmlResponse);
- } catch (error) {
- res.status(404).send('Not Found');
- }
- return;
- }
-
- next();
-});
-
-// WebDAV PUT Handler für Dateien speichern
-// PUT - File Upload (für Word Speichern)
-app.put('/dav/*', (req, res) => {
- const filePath = path.join(__dirname, 'uploads', req.params[0]);
- const dirPath = path.dirname(filePath);
-
- console.log(`� PUT Request: ${req.params[0]}`);
- console.log(`📂 Speichere nach: ${filePath}`);
-
- // Stelle sicher dass der Ordner existiert
- fs.mkdirSync(dirPath, { recursive: true });
-
- const writeStream = fs.createWriteStream(filePath);
-
- req.pipe(writeStream);
-
- writeStream.on('finish', () => {
- console.log(`✅ Datei gespeichert: ${filePath}`);
- res.set({
- 'DAV': '1, 2, ordered-collections, versioning, extended-mkcol',
- 'MS-Author-Via': 'DAV',
- 'Server': 'Microsoft-IIS/10.0 Microsoft-HTTPAPI/2.0',
- 'MicrosoftSharePointTeamServices': '15.0.0.4569',
- 'SPRequestGuid': `{${crypto.randomUUID()}}`,
- 'Cache-Control': 'no-cache',
- 'ETag': `"${Date.now()}-${req.headers['content-length'] || 0}"`,
- 'Last-Modified': new Date().toUTCString(),
- 'X-SharePoint-HealthScore': '0'
- });
- res.status(201).send('Created');
- });
-
- writeStream.on('error', (err) => {
- console.error(`❌ Fehler beim Speichern: ${err.message}`);
- res.status(500).send('Internal Server Error');
- });
-});
-
-app.put('/webdav/documents/:filename', (req, res) => {
- const filename = req.params.filename;
- const filePath = path.join(outputDir, filename);
-
- console.log(`📝 Word speichert Dokument: ${filename}`);
-
- const writeStream = fs.createWriteStream(filePath);
- req.pipe(writeStream);
-
- writeStream.on('finish', () => {
- // Dateirechte explizit setzen
- try {
- fs.chmodSync(filePath, 0o666); // Lese-/Schreibrechte für alle
- } catch (error) {
- console.warn('Warnung: Konnte Dateiberechtigungen nicht setzen:', error.message);
- }
-
- res.set({
- 'DAV': '1, 2, ordered-collections, versioning',
- 'MS-Author-Via': 'DAV',
- 'Server': 'Microsoft-IIS/10.0',
- 'Cache-Control': 'no-cache',
- 'ETag': `"${Date.now()}-${req.headers['content-length'] || 0}"`,
- 'Last-Modified': new Date().toUTCString()
- });
- res.status(201).send('Created');
- console.log(`✅ Dokument gespeichert: ${filename}`);
- });
-
- writeStream.on('error', (error) => {
- console.error('❌ Fehler beim Speichern:', error);
- res.status(500).send('Internal Server Error');
- });
-});
-
-// WebDAV GET Handler für Dateien lesen
-app.get('/webdav/templates/:filename', (req, res) => {
- const filename = req.params.filename;
- const filePath = path.join(templateDir, filename);
-
- if (fs.existsSync(filePath)) {
- const stats = fs.statSync(filePath);
- res.set({
- 'DAV': '1, 2, ordered-collections, versioning',
- 'MS-Author-Via': 'DAV',
- 'Server': 'Microsoft-IIS/10.0',
- 'Content-Type': 'application/vnd.openxmlformats-officedocument.wordprocessingml.document',
- 'Content-Length': stats.size,
- 'Last-Modified': stats.mtime.toUTCString(),
- 'ETag': `"${stats.mtime.getTime()}-${stats.size}"`,
- 'Accept-Ranges': 'bytes',
- 'Cache-Control': 'no-cache'
- });
- console.log(`📖 Word öffnet Template: ${filename}`);
- res.sendFile(filePath);
- } else {
- res.status(404).send('Not Found');
- }
-});
-
-app.get('/webdav/documents/:filename', (req, res) => {
- const filename = req.params.filename;
- const filePath = path.join(outputDir, filename);
-
- if (fs.existsSync(filePath)) {
- const stats = fs.statSync(filePath);
- res.set({
- 'DAV': '1, 2, ordered-collections, versioning',
- 'MS-Author-Via': 'DAV',
- 'Server': 'Microsoft-IIS/10.0',
- 'Content-Type': 'application/vnd.openxmlformats-officedocument.wordprocessingml.document',
- 'Content-Length': stats.size,
- 'Last-Modified': stats.mtime.toUTCString(),
- 'ETag': `"${stats.mtime.getTime()}-${stats.size}"`,
- 'Accept-Ranges': 'bytes',
- 'Cache-Control': 'no-cache'
- });
- console.log(`📖 Word öffnet Dokument: ${filename}`);
- res.sendFile(filePath);
- } else {
- res.status(404).send('Not Found');
- }
-});
-
-// WebDAV LOCK/UNLOCK für Office
-app.use('/webdav', (req, res, next) => {
- if (req.method === 'LOCK') {
- const lockToken = 'opaquelocktoken:' + Date.now() + '-' + Math.random().toString(36).substr(2, 9);
-
- const lockResponse = `
-
-
-
-
-
- 0
- Second-604800
- ${lockToken}
-
-
-`;
-
- res.set({
- 'Content-Type': 'application/xml; charset=utf-8',
- 'Lock-Token': `<${lockToken}>`,
- 'DAV': '1, 2',
- 'MS-Author-Via': 'DAV'
- });
- res.status(200).send(lockResponse);
- return;
- }
-
- if (req.method === 'UNLOCK') {
- res.set({
- 'DAV': '1, 2',
- 'MS-Author-Via': 'DAV'
- });
- res.status(204).send();
- return;
- }
-
- next();
-});
-
-app.use('/webdav/documents', express.static(outputDir, {
- setHeaders: (res, path) => {
- res.set({
- 'DAV': '1, 2',
- 'Allow': 'GET, PUT, DELETE, PROPFIND, PROPPATCH, MKCOL, COPY, MOVE, HEAD, OPTIONS',
- 'Access-Control-Allow-Origin': '*',
- 'Access-Control-Allow-Methods': 'GET, PUT, DELETE, PROPFIND, PROPPATCH, MKCOL, COPY, MOVE, HEAD, OPTIONS',
- 'Access-Control-Allow-Headers': 'Content-Type, Depth, Authorization, If-Match, If-None-Match, Overwrite, Destination',
- 'MS-Author-Via': 'DAV',
- 'Cache-Control': 'no-cache'
- });
- }
-}));
-
-// WebDAV PROPFIND Support für Word
-app.use('/webdav/*', (req, res, next) => {
- if (req.method === 'PROPFIND') {
- res.set({
- 'Content-Type': 'application/xml; charset=utf-8',
- 'DAV': '1, 2',
- 'MS-Author-Via': 'DAV'
- });
-
- const propfindResponse = `
-
-
- ${req.originalUrl}
-
- HTTP/1.1 200 OK
-
-
- httpd/unix-directory
-
-
-
-
-
-
-
-
-
-`;
-
- res.status(207).send(propfindResponse);
- return;
- }
- next();
-});
-
-// SharePoint-spezifische Endpunkte
-app.get('/_vti_inf.html', (req, res) => {
- // SharePoint Info-Seite
- res.set('Content-Type', 'text/html');
- res.send(``);
-});
-
-app.post('/_vti_bin/lists.asmx', (req, res) => {
- // SharePoint Lists Web Service
- res.set({
- 'Content-Type': 'text/xml; charset=utf-8',
- 'SOAPAction': req.headers.soapaction || ''
- });
-
- const soapResponse = `
-
-
-
-
-
-
-
-
-
-
-`;
-
- res.send(soapResponse);
-});
-
-app.get('/_vti_bin/owssvr.dll', (req, res) => {
- // SharePoint OWS Service
- if (req.query.Cmd === 'Display' && req.query.List) {
- res.set('Content-Type', 'text/xml');
- res.send(`
-
-
-
-
-
-
-
-
-
-
-
-`);
- } else {
- res.status(404).send('Not Found');
- }
-});
-
-// SharePoint-kompatible WebDAV-Root
-app.use('/sharepoint', (req, res, next) => {
- // SharePoint-spezifische Header
- res.set({
- 'MicrosoftSharePointTeamServices': '15.0.0.4569',
- 'SharePointHealthScore': '0',
- 'SPRequestGuid': `{${crypto.randomUUID()}}`,
- 'X-SharePoint-HealthScore': '0'
- });
-
- // Weiterleitung zu WebDAV
- const newPath = req.path.replace('/sharepoint', '/webdav');
- req.url = newPath;
- next();
-});
-
-console.log('SharePoint-Kompatibilitätsmodus aktiviert:');
-console.log('SharePoint WebDAV: http://localhost:' + (process.env.PORT || 80) + '/sharepoint/templates/');
-console.log('SharePoint Info: http://localhost:' + (process.env.PORT || 80) + '/_vti_inf.html');
-
-// Multer für File Upload
-const upload = multer({ dest: 'uploads/' });
-
-// Demo-Daten Generator
-class DemoDataGenerator {
- static generateData(tags) {
- const data = {};
-
- tags.forEach(tag => {
- const lowerTag = tag.toLowerCase();
-
- if (lowerTag.includes('name') || lowerTag.includes('vorname')) {
- data[tag] = faker.person.firstName();
- } else if (lowerTag.includes('nachname') || lowerTag.includes('surname')) {
- data[tag] = faker.person.lastName();
- } else if (lowerTag.includes('email') || lowerTag.includes('mail')) {
- data[tag] = faker.internet.email();
- } else if (lowerTag.includes('telefon') || lowerTag.includes('phone')) {
- data[tag] = faker.phone.number();
- } else if (lowerTag.includes('adresse') || lowerTag.includes('address')) {
- data[tag] = faker.location.streetAddress();
- } else if (lowerTag.includes('stadt') || lowerTag.includes('city')) {
- data[tag] = faker.location.city();
- } else if (lowerTag.includes('plz') || lowerTag.includes('postal')) {
- data[tag] = faker.location.zipCode();
- } else if (lowerTag.includes('land') || lowerTag.includes('country')) {
- data[tag] = faker.location.country();
- } else if (lowerTag.includes('datum') || lowerTag.includes('date')) {
- data[tag] = faker.date.recent().toLocaleDateString('de-DE');
- } else if (lowerTag.includes('betrag') || lowerTag.includes('preis') || lowerTag.includes('amount')) {
- data[tag] = faker.commerce.price();
- } else if (lowerTag.includes('firma') || lowerTag.includes('company')) {
- data[tag] = faker.company.name();
- } else if (lowerTag.includes('produkt') || lowerTag.includes('product')) {
- data[tag] = faker.commerce.productName();
- } else if (lowerTag.includes('beschreibung') || lowerTag.includes('description')) {
- data[tag] = faker.lorem.paragraph();
- } else if (lowerTag.includes('nummer') || lowerTag.includes('number') || lowerTag.includes('id')) {
- data[tag] = faker.string.numeric(6);
- } else {
- // Fallback für unbekannte Tags
- data[tag] = faker.lorem.words(2);
- }
- });
-
- return data;
- }
-
- static generateTableData(tableStructure) {
- const rows = Math.floor(Math.random() * 5) + 2; // 2-6 Zeilen
- const tableData = [];
-
- for (let i = 0; i < rows; i++) {
- const row = {};
- tableStructure.forEach(column => {
- if (column.includes('position')) {
- row[column] = (i + 1).toString(); // Fortlaufende Positionsnummer
- } else {
- row[column] = this.generateData([column])[column];
- }
- });
- tableData.push(row);
- }
-
- return tableData;
- }
-}
-
-// Template Tag Extractor
-class TemplateTagExtractor {
- static extractTags(docxBuffer) {
- try {
- const zip = new PizZip(docxBuffer);
- const doc = new Docxtemplater(zip, {
- paragraphLoop: true,
- linebreaks: true,
- });
-
- // Alle Tags aus dem Template extrahieren
- const tags = new Set();
- const content = zip.file('word/document.xml').asText();
-
- // Einfache Tags: {tag}
- const simpleTagRegex = /{([^{}]+)}/g;
- let match;
- while ((match = simpleTagRegex.exec(content)) !== null) {
- const tag = match[1].trim();
- if (!tag.includes('#') && !tag.includes('/')) {
- tags.add(tag);
- }
- }
-
- // Loop Tags für Tabellen: {#items}...{/items}
- const loopTagRegex = /{#(\w+)}/g;
- const loopTags = [];
- while ((match = loopTagRegex.exec(content)) !== null) {
- loopTags.push(match[1]);
- }
-
- return {
- simpleTags: Array.from(tags),
- loopTags: loopTags
- };
- } catch (error) {
- console.error('Fehler beim Extrahieren der Tags:', error);
- return { simpleTags: [], loopTags: [] };
- }
- }
-}
-
-// Template Processor
-class TemplateProcessor {
- static async processTemplate(templatePath, outputPath, customData = null) {
- try {
- const content = fs.readFileSync(templatePath, 'binary');
- const zip = new PizZip(content);
-
- // Tags extrahieren
- const { simpleTags, loopTags } = TemplateTagExtractor.extractTags(Buffer.from(content, 'binary'));
-
- // Daten generieren oder verwenden
- let data = customData || {};
-
- if (!customData) {
- // Demo-Daten für einfache Tags generieren
- data = DemoDataGenerator.generateData(simpleTags);
-
- // Demo-Daten für Loop Tags (Tabellen) generieren
- loopTags.forEach(loopTag => {
- // Erweiterte Tabellen-Spalten für professionelle Rechnung
- const tableColumns = [`${loopTag}_position`, `${loopTag}_name`, `${loopTag}_value`, `${loopTag}_date`];
- data[loopTag] = DemoDataGenerator.generateTableData(tableColumns);
- });
- }
-
- const doc = new Docxtemplater(zip, {
- paragraphLoop: true,
- linebreaks: true,
- });
-
- doc.render(data);
-
- const buf = doc.getZip().generate({
- type: 'nodebuffer',
- compression: 'DEFLATE',
- });
-
- fs.writeFileSync(outputPath, buf);
-
- return {
- success: true,
- data: data,
- extractedTags: { simpleTags, loopTags }
- };
- } catch (error) {
- console.error('Template Verarbeitung fehlgeschlagen:', error);
- return {
- success: false,
- error: error.message
- };
- }
- }
-}
-
-// Routes
-
-// Hauptseite
-app.get('/', (req, res) => {
- res.send(`
-
-
-
- DOCX Template Server
-
-
-
-
-
-
DOCX Template Server
-
-
-
📄 Template hochladen und verarbeiten
-
-
-
-
-
📁 Office-Integration
-
-
Office-Integration: Öffnen Sie in Word/Excel: Datei → Öffnen → Netzwerk hinzufügen → WebDAV → http://localhost:${PORT}/webdav/templates/
-
Direkt speichern: Word speichert automatisch auf dem Server wenn über WebDAV geöffnet.
-
-
-
-
🔧 API Endpunkte
-
-
Word-Integration: Die API liefert spezielle Links für Microsoft Word:
-
- wordWebdavUrl - Direkt in Word öffnen (ms-word: Protocol)
- wordDirectUrl - Alternative Word-Integration
- webdavDirect - Windows UNC-Pfad für Netzlaufwerk
-
-
-
-
-
📋 Test Template
-
Test Template erstellen
-
Erstellt ein Beispiel-Template mit verschiedenen Tag-Typen für Tests.
-
-
-
-
- `);
-});
-
-// Template Upload und Verarbeitung
-app.post('/upload-template', upload.single('template'), async (req, res) => {
- try {
- if (!req.file) {
- return res.status(400).json({ error: 'Keine Datei hochgeladen' });
- }
-
- const templateName = req.file.originalname;
- const templatePath = path.join(templateDir, templateName);
- const outputName = templateName.replace('.docx', '_ausgefuellt.docx');
- const outputPath = path.join(outputDir, outputName);
-
- // Template in Templates-Verzeichnis kopieren
- fs.copyFileSync(req.file.path, templatePath);
-
- // Template verarbeiten
- const result = await TemplateProcessor.processTemplate(templatePath, outputPath);
-
- // Upload-Datei löschen
- fs.unlinkSync(req.file.path);
-
- if (result.success) {
- const protocol = req.secure ? 'https' : 'http';
- const host = req.get('host') || `localhost:${PORT}`;
-
- res.json({
- message: 'Template erfolgreich verarbeitet',
- templateName: templateName,
- outputName: outputName,
- extractedTags: result.extractedTags,
- generatedData: result.data,
- fileUrls: {
- template: `${protocol}://${host}/webdav/templates/${templateName}`,
- document: `${protocol}://${host}/webdav/documents/${outputName}`,
- wordWebdavTemplate: `ms-word:ofe|u|${protocol}://${host}/webdav/templates/${encodeURIComponent(templateName)}`,
- wordWebdavDocument: `ms-word:ofe|u|${protocol}://${host}/webdav/documents/${encodeURIComponent(outputName)}`,
- wordDirectTemplate: `word:ofe|u|${protocol}://${host}/webdav/templates/${encodeURIComponent(templateName)}`,
- wordDirectDocument: `word:ofe|u|${protocol}://${host}/webdav/documents/${encodeURIComponent(outputName)}`
- }
- });
- } else {
- res.status(500).json({ error: result.error });
- }
- } catch (error) {
- console.error('Upload Fehler:', error);
- res.status(500).json({ error: 'Server Fehler beim Upload' });
- }
-});
-
-// Test Template erstellen
-app.get('/create-test-template', (req, res) => {
- const PizZip = require('pizzip');
-
- // Minimales DOCX Template erstellen
- const testContent = `
-
-
- Firmenname: {firma}
- Ansprechpartner: {vorname} {nachname}
- E-Mail: {email}
- Telefon: {telefon}
- Adresse: {adresse}, {plz} {stadt}
- Datum: {datum}
- Rechnungsnummer: {nummer}
-
- Positionen:
- {#items}
- - {items_name}: {items_value} EUR ({items_date})
- {/items}
-
- Gesamtbetrag: {betrag} EUR
-
- Beschreibung:
- {beschreibung}
-
-
- `;
-
- try {
- // Minimal DOCX Struktur
- const zip = new PizZip();
-
- // document.xml
- zip.file('word/document.xml', testContent);
-
- // [Content_Types].xml
- zip.file('[Content_Types].xml', `
-
-
-
-
- `);
-
- // _rels/.rels
- zip.file('_rels/.rels', `
-
-
- `);
-
- // word/_rels/document.xml.rels
- zip.file('word/_rels/document.xml.rels', `
-
- `);
-
- const buffer = zip.generate({ type: 'nodebuffer' });
- const testTemplatePath = path.join(templateDir, 'test_template.docx');
-
- fs.writeFileSync(testTemplatePath, buffer);
-
- res.json({
- message: 'Test Template erstellt',
- templatePath: 'test_template.docx',
- fileUrl: `http://localhost:${PORT}/webdav/templates/test_template.docx`,
- info: 'Sie können das Template jetzt über den Datei-Server herunterladen, bearbeiten und wieder hochladen.'
- });
- } catch (error) {
- console.error('Fehler beim Erstellen des Test Templates:', error);
- res.status(500).json({ error: 'Fehler beim Erstellen des Test Templates' });
- }
-});
-
-// API Endpunkte
-app.get('/api/templates', (req, res) => {
- try {
- const files = fs.readdirSync(templateDir).filter(file => file.endsWith('.docx'));
- const protocol = req.secure ? 'https' : 'http';
- const host = req.get('host') || `localhost:${PORT}`;
-
- res.json({
- templates: files.map(file => ({
- name: file,
- fileUrl: `${protocol}://${host}/webdav/templates/${file}`,
- wordWebdavUrl: `ms-word:ofe|u|${protocol}://${host}/webdav/templates/${encodeURIComponent(file)}`,
- wordDirectUrl: `word:ofe|u|${protocol}://${host}/webdav/templates/${encodeURIComponent(file)}`,
- downloadUrl: `${protocol}://${host}/webdav/templates/${file}`,
- webdavDirect: `\\\\${host.split(':')[0]}@${PORT}\\webdav\\templates\\${file}`
- }))
- });
- } catch (error) {
- res.status(500).json({ error: 'Fehler beim Auflisten der Templates' });
- }
-});
-
-app.get('/api/documents', (req, res) => {
- try {
- const files = fs.readdirSync(outputDir).filter(file => file.endsWith('.docx'));
- const protocol = req.secure ? 'https' : 'http';
- const host = req.get('host') || `localhost:${PORT}`;
-
- res.json({
- documents: files.map(file => ({
- name: file,
- fileUrl: `${protocol}://${host}/webdav/documents/${file}`,
- wordWebdavUrl: `ms-word:ofe|u|${protocol}://${host}/webdav/documents/${encodeURIComponent(file)}`,
- wordDirectUrl: `word:ofe|u|${protocol}://${host}/webdav/documents/${encodeURIComponent(file)}`,
- downloadUrl: `${protocol}://${host}/webdav/documents/${file}`,
- webdavDirect: `\\\\${host.split(':')[0]}@${PORT}\\webdav\\documents\\${file}`,
- createdAt: fs.statSync(path.join(outputDir, file)).mtime
- }))
- });
- } catch (error) {
- res.status(500).json({ error: 'Fehler beim Auflisten der Dokumente' });
- }
-});
-
-// Template mit benutzerdefinierten Daten verarbeiten
-app.post('/api/process-template/:templateName', (req, res) => {
- try {
- const templateName = req.params.templateName;
- const templatePath = path.join(templateDir, templateName);
-
- if (!fs.existsSync(templatePath)) {
- return res.status(404).json({ error: 'Template nicht gefunden' });
- }
-
- const outputName = templateName.replace('.docx', '_custom.docx');
- const outputPath = path.join(outputDir, outputName);
-
- TemplateProcessor.processTemplate(templatePath, outputPath, req.body).then(result => {
- if (result.success) {
- res.json({
- message: 'Template mit benutzerdefinierten Daten verarbeitet',
- outputName: outputName,
- fileUrl: `http://localhost:${PORT}/webdav/documents/${outputName}`
- });
- } else {
- res.status(500).json({ error: result.error });
- }
- });
- } catch (error) {
- res.status(500).json({ error: 'Fehler beim Verarbeiten des Templates' });
- }
-});
-
-// SSL Konfiguration
-const certPath = path.join(__dirname, '203_cert.pem');
-const keyPath = path.join(__dirname, '203_key.pem');
-
-if (fs.existsSync(keyPath) && fs.existsSync(certPath)) {
- try {
- const sslOptions = {
- key: fs.readFileSync(keyPath),
- cert: fs.readFileSync(certPath)
- };
-
- https.createServer(sslOptions, app).listen(443, () => {
- console.log('🔒 HTTPS Server läuft auf Port 443');
- console.log('🌐 HTTPS Zugang: https://localhost:443');
- });
- } catch (error) {
- console.warn('⚠️ SSL-Zertifikate gefunden, aber Fehler beim Laden:', error.message);
- console.log('ℹ️ Server läuft nur mit HTTP');
- }
-} else {
- console.log('ℹ️ SSL-Zertifikate nicht gefunden - Server läuft nur mit HTTP');
- console.log('💡 Für HTTPS: Platzieren Sie 203_cert.pem und 203_key.pem in /home/OfficeServerJS/');
-}
-
-// Server starten
-app.listen(PORT, () => {
- console.log(`\n🚀 DOCX Template Server gestartet!`);
- console.log(`📍 HTTP Server: http://localhost:${PORT}`);
- console.log(`📁 Templates: http://localhost:${PORT}/webdav/templates/`);
- console.log(`📁 Documents: http://localhost:${PORT}/webdav/documents/`);
- console.log(`\n💡 Tipp: Besuchen Sie http://localhost:${PORT} für die Web-Oberfläche`);
-
- // SSL-Status anzeigen
- const certPath = path.join(__dirname, '203_cert.pem');
- const keyPath = path.join(__dirname, '203_key.pem');
- if (fs.existsSync(keyPath) && fs.existsSync(certPath)) {
- console.log(`🔒 HTTPS auch verfügbar: https://localhost:443`);
- }
-});
-
-module.exports = app;
\ No newline at end of file
diff --git a/start-ssl.sh b/start-ssl.sh
index def1f75..8c98073 100755
--- a/start-ssl.sh
+++ b/start-ssl.sh
@@ -50,10 +50,10 @@ echo " HTTP: http://localhost:80"
echo " HTTPS: https://localhost:443"
echo ""
echo "📁 Dateifreigabe:"
-echo " HTTP Templates: http://localhost:80/webdav/templates/"
-echo " HTTPS Templates: https://localhost:443/webdav/templates/"
-echo " HTTP Documents: http://localhost:80/webdav/documents/"
-echo " HTTPS Documents: https://localhost:443/webdav/documents/"
+echo " HTTP Templates: http://localhost:80/templates/"
+echo " HTTPS Templates: https://localhost:443/templates/"
+echo " HTTP Documents: http://localhost:80/documents/"
+echo " HTTPS Documents: https://localhost:443/documents/"
echo ""
# Server mit SSL starten
diff --git a/start.sh b/start.sh
index 88f7ad4..b4e097e 100755
--- a/start.sh
+++ b/start.sh
@@ -28,8 +28,8 @@ fi
echo "🌟 Starte den DOCX Template Server..."
echo ""
echo "📍 Web-Oberfläche: http://localhost:80"
-echo "📁 Templates: http://localhost:80/webdav/templates/"
-echo "📁 Dokumente: http://localhost:80/webdav/documents/"
+echo "📁 Templates: http://localhost:80/templates/"
+echo "📁 Dokumente: http://localhost:80/documents/"
echo ""
echo "💡 Drücken Sie Ctrl+C zum Beenden"
echo ""