From 9fbeb0846287409865ac869a3bcf6258eccddbeb Mon Sep 17 00:00:00 2001 From: alma Date: Mon, 21 Apr 2025 11:36:27 +0200 Subject: [PATCH] Page logic dang --- app/api/nextcloud/files/route.ts | 107 ++++++++++++++++++++++--------- 1 file changed, 76 insertions(+), 31 deletions(-) diff --git a/app/api/nextcloud/files/route.ts b/app/api/nextcloud/files/route.ts index 8dbd7e92..6c07cd36 100644 --- a/app/api/nextcloud/files/route.ts +++ b/app/api/nextcloud/files/route.ts @@ -4,6 +4,7 @@ import { PrismaClient } from '@prisma/client'; import { authOptions } from '@/app/api/auth/[...nextauth]/route'; import { createClient } from 'webdav'; import { prisma } from '@/lib/prisma'; +import { Buffer } from 'buffer'; // Use a single PrismaClient instance declare global { @@ -64,40 +65,84 @@ export async function GET(request: Request) { return NextResponse.json({ error: 'Nextcloud credentials not found' }, { status: 404 }); } - // Create WebDAV client - const client = createClient(process.env.NEXTCLOUD_URL!, { - username: credentials.username, - password: credentials.password, + const nextcloudUrl = process.env.NEXTCLOUD_URL; + if (!nextcloudUrl) { + return NextResponse.json({ error: 'Nextcloud URL not configured' }, { status: 500 }); + } + + const path = `/files/${credentials.username}/Private/${folder}`; + const url = `${nextcloudUrl}/remote.php/dav${path}`; + + // Make PROPFIND request to get directory contents + const response = await fetch(url, { + method: 'PROPFIND', + headers: { + 'Authorization': `Basic ${Buffer.from(`${credentials.username}:${credentials.password}`).toString('base64')}`, + 'Depth': '1', + 'Content-Type': 'application/xml', + }, + body: '', }); - try { - const path = `/files/${credentials.username}/Private/${folder}`; - const files = await client.getDirectoryContents(path); - - // For Contacts folder, return all files - if (folder === 'Contacts') { - return NextResponse.json(files); - } - - // For other folders, filter markdown files - const markdownFiles = files - .filter((file: any) => file.basename.endsWith('.md')) - .map((file: any) => ({ - id: file.filename, - title: file.basename.replace('.md', ''), - lastModified: new Date(file.lastmod).toISOString(), - size: file.size, - type: 'file', - mime: file.mime, - etag: file.etag - })); - - return NextResponse.json(markdownFiles); - } catch (error) { - // Log error without sensitive information - console.error('Error listing directory contents:', error instanceof Error ? error.message : 'Unknown error'); - return NextResponse.json({ error: 'Failed to list directory contents' }, { status: 500 }); + if (!response.ok) { + console.error('Error fetching directory contents:', response.status, response.statusText); + return NextResponse.json({ error: 'Failed to fetch directory contents' }, { status: response.status }); } + + const text = await response.text(); + const parser = new DOMParser(); + const xmlDoc = parser.parseFromString(text, 'text/xml'); + + const files: any[] = []; + const responses = xmlDoc.getElementsByTagName('d:response'); + + for (let i = 0; i < responses.length; i++) { + const response = responses[i]; + const href = response.getElementsByTagName('d:href')[0]?.textContent; + const propstat = response.getElementsByTagName('d:propstat')[0]; + + if (href && propstat) { + const prop = propstat.getElementsByTagName('d:prop')[0]; + if (prop) { + const type = prop.getElementsByTagName('d:resourcetype')[0]; + const lastmod = prop.getElementsByTagName('d:getlastmodified')[0]?.textContent; + const size = prop.getElementsByTagName('d:getcontentlength')[0]?.textContent; + const mime = prop.getElementsByTagName('d:getcontenttype')[0]?.textContent; + const etag = prop.getElementsByTagName('d:getetag')[0]?.textContent; + + if (type && !type.getElementsByTagName('d:collection').length) { + const filename = href.split('/').pop() || ''; + + // For Contacts folder, return all files + if (folder === 'Contacts') { + files.push({ + filename: href, + basename: filename, + lastmod, + size, + type: 'file', + etag, + mime + }); + } + // For other folders, only return markdown files + else if (filename.endsWith('.md')) { + files.push({ + id: href, + title: filename.replace('.md', ''), + lastModified: new Date(lastmod || '').toISOString(), + size, + type: 'file', + mime, + etag + }); + } + } + } + } + } + + return NextResponse.json(files); } catch (error) { // Log error without sensitive information console.error('Error fetching files:', error instanceof Error ? error.message : 'Unknown error');