Initial profile site commit
This commit is contained in:
@@ -0,0 +1,100 @@
|
||||
<?php
|
||||
require_once 'config.php';
|
||||
require_once __DIR__ . '/error_config.php';
|
||||
session_start();
|
||||
set_json_headers();
|
||||
require_auth();
|
||||
|
||||
$method = $_SERVER['REQUEST_METHOD'];
|
||||
|
||||
// =====================================================
|
||||
// POST: 특정 폴더 안의 파일들 삭제
|
||||
// 또는 특정 파일 URL들 삭제
|
||||
// =====================================================
|
||||
if ($method !== 'POST') {
|
||||
json_response(['error' => 'POST만 허용됩니다'], 405);
|
||||
}
|
||||
|
||||
$input = get_json_input();
|
||||
|
||||
// 안전 가드: uploads 디렉토리 밖으로 못 나가게
|
||||
function is_safe_uploads_path($path) {
|
||||
$real_uploads = realpath(UPLOADS_DIR);
|
||||
$real_target = realpath($path);
|
||||
if ($real_uploads === false) return false;
|
||||
if ($real_target === false) return false;
|
||||
return strpos($real_target, $real_uploads) === 0;
|
||||
}
|
||||
|
||||
$deleted = [];
|
||||
$failed = [];
|
||||
|
||||
// 1) URL 리스트로 개별 파일 삭제
|
||||
if (isset($input['urls']) && is_array($input['urls'])) {
|
||||
foreach ($input['urls'] as $url) {
|
||||
$url = trim($url);
|
||||
if ($url === '') continue;
|
||||
|
||||
// uploads/ 로 시작하는 상대 경로만 허용
|
||||
if (!preg_match('#^uploads/#', $url)) {
|
||||
$failed[] = ['url' => $url, 'reason' => 'invalid path'];
|
||||
continue;
|
||||
}
|
||||
|
||||
// 외부 URL은 건너뛰기 (http://, https:// 등)
|
||||
if (preg_match('#^https?://#i', $url)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
// 절대 경로 만들기
|
||||
$relative = preg_replace('#^uploads/#', '', $url);
|
||||
$full_path = UPLOADS_DIR . '/' . $relative;
|
||||
|
||||
if (!file_exists($full_path)) {
|
||||
$failed[] = ['url' => $url, 'reason' => 'not found'];
|
||||
continue;
|
||||
}
|
||||
|
||||
if (!is_safe_uploads_path($full_path)) {
|
||||
$failed[] = ['url' => $url, 'reason' => 'unsafe path'];
|
||||
continue;
|
||||
}
|
||||
|
||||
if (@unlink($full_path)) {
|
||||
$deleted[] = $url;
|
||||
} else {
|
||||
$failed[] = ['url' => $url, 'reason' => 'unlink failed'];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 2) 폴더 삭제 (프로젝트 폴더 통째로)
|
||||
if (isset($input['folder'])) {
|
||||
$folder = trim($input['folder']);
|
||||
if ($folder !== '' && !preg_match('#[/\\\\]#', $folder)) {
|
||||
$folder_path = UPLOADS_DIR . '/' . $folder;
|
||||
if (is_dir($folder_path) && is_safe_uploads_path($folder_path)) {
|
||||
// 폴더 안의 파일들 삭제
|
||||
$files = glob($folder_path . '/*');
|
||||
foreach ($files as $f) {
|
||||
if (is_file($f)) {
|
||||
if (@unlink($f)) {
|
||||
$deleted[] = $folder . '/' . basename($f);
|
||||
} else {
|
||||
$failed[] = ['url' => $folder . '/' . basename($f), 'reason' => 'unlink failed'];
|
||||
}
|
||||
}
|
||||
}
|
||||
// 빈 폴더는 삭제
|
||||
@rmdir($folder_path);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
json_response([
|
||||
'success' => true,
|
||||
'deleted_count' => count($deleted),
|
||||
'failed_count' => count($failed),
|
||||
'deleted' => $deleted,
|
||||
'failed' => $failed
|
||||
]);
|
||||
Reference in New Issue
Block a user