File size: 2,959 Bytes
36d9100
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
<?php
header('Content-Type: application/json');
header('Access-Control-Allow-Origin: *');
header('Access-Control-Allow-Methods: POST, OPTIONS');
header('Access-Control-Allow-Headers: Content-Type');

if ($_SERVER['REQUEST_METHOD'] === 'OPTIONS') {
    http_response_code(204);
    exit;
}

if ($_SERVER['REQUEST_METHOD'] !== 'POST') {
    http_response_code(405);
    echo json_encode(['error' => 'Method not allowed']);
    exit;
}

$username = trim($_POST['username'] ?? '');

// Validate username
if (!preg_match('/^[a-z0-9]{3,32}$/', $username)) {
    http_response_code(400);
    echo json_encode(['error' => 'Invalid username']);
    exit;
}

// Check user exists
$db = new PDO('sqlite:/data/db/platform.sqlite');
$db->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
$stmt = $db->prepare('SELECT id FROM users WHERE username = ?');
$stmt->execute([$username]);
if (!$stmt->fetch()) {
    http_response_code(404);
    echo json_encode(['error' => 'User not found']);
    exit;
}

$htdocs = "/data/sites/{$username}/htdocs";

// Allowed file extensions
$allowed = [
    'php','html','htm','css','js','json','txt','xml',
    'png','jpg','jpeg','gif','webp','svg','ico',
    'woff','woff2','ttf','eot','pdf','zip'
];

if (empty($_FILES['files'])) {
    http_response_code(400);
    echo json_encode(['error' => 'No files uploaded']);
    exit;
}

$uploaded = [];
$errors   = [];

// Normalise $_FILES array for multiple uploads
$files = $_FILES['files'];
$count = is_array($files['name']) ? count($files['name']) : 1;

for ($i = 0; $i < $count; $i++) {
    $name  = is_array($files['name'])  ? $files['name'][$i]  : $files['name'];
    $tmp   = is_array($files['tmp_name']) ? $files['tmp_name'][$i] : $files['tmp_name'];
    $error = is_array($files['error']) ? $files['error'][$i] : $files['error'];

    if ($error !== UPLOAD_ERR_OK) {
        $errors[] = "{$name}: upload error code {$error}";
        continue;
    }

    // Sanitise filename — strip any path components
    $name = basename($name);
    $ext  = strtolower(pathinfo($name, PATHINFO_EXTENSION));

    if (!in_array($ext, $allowed)) {
        $errors[] = "{$name}: file type .{$ext} not allowed";
        continue;
    }

    // Enforce 10 MB per file
    if (filesize($tmp) > 10 * 1024 * 1024) {
        $errors[] = "{$name}: exceeds 10 MB limit";
        continue;
    }

    $dest = "{$htdocs}/{$name}";
    if (move_uploaded_file($tmp, $dest)) {
        // Update files table
        $stmt = $db->prepare('
            INSERT INTO files (username, filepath, updated_at)
            VALUES (?, ?, datetime("now"))
            ON CONFLICT(username, filepath) DO UPDATE SET updated_at=datetime("now")
        ');
        $stmt->execute([$username, $name]);
        $uploaded[] = $name;
    } else {
        $errors[] = "{$name}: failed to save file";
    }
}

echo json_encode([
    'success'  => count($uploaded) > 0,
    'uploaded' => $uploaded,
    'errors'   => $errors
]);