added webdav server
This commit is contained in:
@@ -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"
|
||||
|
||||
106
backend/src/webdav/server.ts
Normal file
106
backend/src/webdav/server.ts
Normal 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();
|
||||
Reference in New Issue
Block a user