summaryrefslogtreecommitdiff
path: root/frontend/app/api/upload
diff options
context:
space:
mode:
authordiogo464 <[email protected]>2025-08-12 16:32:00 +0100
committerdiogo464 <[email protected]>2025-08-12 16:32:00 +0100
commitfcd70649f43a72dbbcbc79e524fbe3fe20261021 (patch)
tree9bfa929fa7b6f740d6c15a9da550849bcda27150 /frontend/app/api/upload
parent70738d871decbcdec4f5535a7b6f57de26de7d2a (diff)
Replace complex /api/fs with simple /api/upload endpoint
- Create new /api/upload endpoint for file uploads with path query parameter - Simplify DriveDirectoryClient upload logic to use POST instead of PUT - Remove complex path encoding and AUTH header handling from client - Remove unused /api/fs endpoint entirely - no longer needed - Maintain all existing upload functionality (file size limits, auth, etc.) - Test uploads to root directory and subdirectories - both working perfectly Benefits: - Cleaner API surface with single-purpose endpoints - Simpler client code with less complexity - Better separation of concerns - Maintained backward compatibility for user experience 🤖 Generated with [Claude Code](https://claude.ai/code) Co-Authored-By: Claude <[email protected]>
Diffstat (limited to 'frontend/app/api/upload')
-rw-r--r--frontend/app/api/upload/route.ts71
1 files changed, 71 insertions, 0 deletions
diff --git a/frontend/app/api/upload/route.ts b/frontend/app/api/upload/route.ts
new file mode 100644
index 0000000..518c28e
--- /dev/null
+++ b/frontend/app/api/upload/route.ts
@@ -0,0 +1,71 @@
1import { NextRequest, NextResponse } from 'next/server'
2import { writeFile, unlink } from 'fs/promises'
3import { tmpdir } from 'os'
4import { join } from 'path'
5import { randomUUID } from 'crypto'
6import { Auth_get_user, Auth_user_can_upload } from '@/lib/auth'
7import { Drive_import } from '@/lib/drive_server'
8import { UPLOAD_MAX_FILE_SIZE } from '@/lib/constants'
9
10// POST /api/upload - Simple file upload endpoint
11export async function POST(request: NextRequest) {
12 try {
13 // Check user authentication and permissions
14 const user = await Auth_get_user()
15 if (!user.isLoggedIn) {
16 return NextResponse.json({ error: 'User not authenticated' }, { status: 401 })
17 }
18
19 if (!Auth_user_can_upload(user)) {
20 return NextResponse.json({ error: 'User does not have upload permissions' }, { status: 403 })
21 }
22
23 // Get the target path from query parameters
24 const url = new URL(request.url)
25 const targetPath = url.searchParams.get('path') || '/'
26
27 // Handle multipart form data
28 const formData = await request.formData()
29 const file = formData.get('file') as File
30
31 if (!file) {
32 return NextResponse.json({ error: 'No file provided' }, { status: 400 })
33 }
34
35 if (file.size > UPLOAD_MAX_FILE_SIZE) {
36 return NextResponse.json({
37 error: `File exceeds maximum size of ${UPLOAD_MAX_FILE_SIZE / (1024 * 1024)}MB`
38 }, { status: 400 })
39 }
40
41 const bytes = await file.arrayBuffer()
42 const fileBuffer = Buffer.from(bytes)
43
44 // Create temporary file
45 const tempFileName = `${randomUUID()}-${file.name}`
46 const tempFilePath = join(tmpdir(), tempFileName)
47
48 // Save file to temporary location
49 await writeFile(tempFilePath, fileBuffer)
50
51 // Construct the final drive path
52 const finalPath = targetPath === '/' ? file.name : `${targetPath.replace(/^\/+|\/+$/g, '')}/${file.name}`
53
54 // Import file using Drive_import (uses --mode move, so temp file is automatically deleted)
55 await Drive_import(tempFilePath, finalPath, user.email)
56
57 return NextResponse.json({
58 success: true,
59 message: 'File uploaded successfully',
60 path: finalPath,
61 filename: file.name
62 })
63
64 } catch (error) {
65 console.error('Upload error:', error)
66 return NextResponse.json(
67 { error: error instanceof Error ? error.message : 'Internal server error' },
68 { status: 500 }
69 )
70 }
71} \ No newline at end of file