91 lines · 2.7 KB
Raw Download
1
<?php
2
require_once __DIR__ . '/../includes/auth.php';
3
require_once __DIR__ . '/../includes/db.php';
4
require_once __DIR__ . '/../includes/helpers.php';
5
6
require_login();
7
8
// POST-only.
9
if ($_SERVER['REQUEST_METHOD'] !== 'POST') {
10
    http_response_code(405);
11
    exit('Method not allowed.');
12
}
13
csrf_verify();
14
15
/** Recursively remove a directory identified by a path relative to UPLOAD_DIR. */
16
function remove_upload_dir(string $relPath): void
17
{
18
    $base = realpath(UPLOAD_DIR);
19
    $dir  = realpath(UPLOAD_DIR . '/' . $relPath);
20
    if ($base === false || $dir === false) {
21
        return;
22
    }
23
    // Safety: never touch anything at or above the uploads root.
24
    if ($dir === $base || strpos($dir, $base . DIRECTORY_SEPARATOR) !== 0) {
25
        return;
26
    }
27
    $items = new RecursiveIteratorIterator(
28
        new RecursiveDirectoryIterator($dir, FilesystemIterator::SKIP_DOTS),
29
        RecursiveIteratorIterator::CHILD_FIRST
30
    );
31
    foreach ($items as $item) {
32
        $item->isDir() ? @rmdir($item->getPathname()) : @unlink($item->getPathname());
33
    }
34
    @rmdir($dir);
35
}
36
37
$type = $_POST['type'] ?? '';
38
39
if ($type === 'repo') {
40
    $id   = (int) ($_POST['id'] ?? 0);
41
    $repo = get_repository($id);
42
    if ($repo) {
43
        remove_upload_dir($repo['slug']);
44
        delete_repository($id); // cascades file + folder rows
45
    }
46
    header('Location: ' . url('/admin/dashboard.php?deleted=1'));
47
    exit;
48
}
49
50
if ($type === 'folder') {
51
    $id     = (int) ($_POST['id'] ?? 0);
52
    $folder = get_folder($id);
53
    if ($folder) {
54
        $repo = get_repository((int) $folder['repo_id']);
55
        $path = delete_folder($id); // removes descendant file + folder rows
56
        if ($repo && $path !== null) {
57
            remove_upload_dir($repo['slug'] . '/' . $path);
58
        }
59
        if ($repo) {
60
            header('Location: ' . url('/admin/upload.php?repo=' . urlencode($repo['slug']) . '&deleted=1'));
61
            exit;
62
        }
63
    }
64
    header('Location: ' . url('/admin/dashboard.php?deleted=1'));
65
    exit;
66
}
67
68
if ($type === 'file') {
69
    $id   = (int) ($_POST['id'] ?? 0);
70
    $file = get_file($id);
71
    if ($file) {
72
        $repo = get_repository((int) $file['repo_id']);
73
        // Delete the file on disk, guarding against traversal.
74
        $base = realpath(UPLOAD_DIR);
75
        $full = realpath(UPLOAD_DIR . '/' . $file['filepath']);
76
        if ($base !== false && $full !== false && strpos($full, $base . DIRECTORY_SEPARATOR) === 0) {
77
            @unlink($full);
78
        }
79
        delete_file($id);
80
        if ($repo) {
81
            header('Location: ' . url('/admin/upload.php?repo=' . urlencode($repo['slug']) . '&deleted=1'));
82
            exit;
83
        }
84
    }
85
    header('Location: ' . url('/admin/dashboard.php?deleted=1'));
86
    exit;
87
}
88
89
http_response_code(400);
90
exit('Unknown delete type.');
91