added webdav server

This commit is contained in:
2026-01-17 15:15:34 +01:00
parent 6adf09faa0
commit 6423886930
2 changed files with 108 additions and 0 deletions

View File

@@ -5,6 +5,7 @@
"main": "index.js",
"scripts": {
"dev": "tsx watch src/index.ts",
"dev:dav": "tsx watch src/webdav/server.ts",
"build": "tsc",
"start": "node dist/src/index.js",
"schema:index": "ts-node scripts/generate-schema-index.ts"
@@ -48,6 +49,7 @@
"pg": "^8.16.3",
"pngjs": "^7.0.0",
"sharp": "^0.34.5",
"webdav-server": "^2.6.2",
"xmlbuilder": "^15.1.1",
"zpl-image": "^0.2.0",
"zpl-renderer-js": "^2.0.2"

View File

@@ -0,0 +1,106 @@
import 'dotenv/config';
import { v2 as webdav } from 'webdav-server';
import { db } from '../../db';
// WICHTIG: 'folders' muss hier importiert werden
import { tenants, files, folders } from '../../db/schema';
import { eq } from 'drizzle-orm';
// 1. User & Rechte Setup
const userManager = new webdav.SimpleUserManager();
const user = userManager.addUser('admin', 'admin', true);
const privilegeManager = new webdav.SimplePathPrivilegeManager();
privilegeManager.setRights(user, '/', [ 'all' ]);
const server = new webdav.WebDAVServer({
httpAuthentication: new webdav.HTTPDigestAuthentication(userManager, 'Default realm'),
privilegeManager: privilegeManager,
port: 3200,
});
async function startServer() {
console.log('------------------------------------------------');
console.log('[WebDAV] Lade Struktur (Tenants -> Folders -> Files)...');
try {
// A. Alle Daten abrufen
const allTenants = await db.select().from(tenants);
const allFolders = await db.select().from(folders);
const allFiles = await db.select().from(files);
console.log(`[WebDAV] Stats: ${allTenants.length} Tenants, ${allFolders.length} Ordner, ${allFiles.length} Dateien.`);
// --------------------------------------------------------------------
// REKURSIVE FUNKTION: Baut den Inhalt eines Ordners
// --------------------------------------------------------------------
const buildFolderContent = (tenantId: string, parentFolderId: string | null) => {
const currentDir: any = {};
// 1. UNTERORDNER finden
// Wir suchen Ordner, die zum aktuellen Tenant gehören UND diesen Ordner als Parent haben
const subFolders = allFolders.filter(f =>
f.tenant === tenantId && f.parent === parentFolderId
);
subFolders.forEach(folder => {
// Rekursion: Wir rufen die Funktion für diesen Unterordner erneut auf
// Das Objekt, das zurückkommt, ist der Inhalt des Unterordners
currentDir[folder.name] = buildFolderContent(tenantId, folder.id);
});
// 2. DATEIEN finden
// Wir suchen Dateien, die in diesem Ordner liegen
const dirFiles = allFiles.filter(f =>
f.tenant === tenantId && f.folder === parentFolderId
);
dirFiles.forEach(file => {
// Name aus Pfad extrahieren (wie im Frontend)
let fileName = 'Unbenannt.txt';
if (file.path) fileName = file.path.split('/').pop() || 'Unbenannt.txt';
else if (file.name) fileName = file.name;
// Inhalt (Placeholder)
currentDir[fileName] = `Datei: ${fileName}\nID: ${file.id}`;
});
return currentDir;
};
// B. Hauptbaum bauen (Einstiegspunkt)
const dbTree: any = {};
allTenants.forEach(tenant => {
const tenantName = tenant.name.replace(/\//g, '-');
// Wir starten die Rekursion am "Root" des Tenants (parentFolderId = null)
const tenantRootContent = buildFolderContent(tenant.id, null);
// Wenn Tenant komplett leer ist (keine Ordner im Root, keine Files im Root)
if (Object.keys(tenantRootContent).length === 0) {
tenantRootContent['(Leer).txt'] = 'Dieser Tenant ist leer.';
}
dbTree[tenantName] = tenantRootContent;
});
// Fallback für leere DB
if (Object.keys(dbTree).length === 0) {
dbTree['Status.txt'] = 'Keine Tenants gefunden.';
}
// C. Baum registrieren
const root = server.rootFileSystem();
root.addSubTree(server.createExternalContext(), dbTree);
// D. Starten
server.start(() => {
console.log('[WebDAV] 🚀 READY auf http://localhost:3200');
});
} catch (error) {
console.error('[WebDAV] 💥 Fehler:', error);
}
}
startServer();