тикеты ланучера
This commit is contained in:
@@ -120,7 +120,30 @@ class LauncherController extends Controller
|
||||
public function download(string $path): JsonResponse
|
||||
{
|
||||
$disk = Storage::disk($this->disk());
|
||||
$fullPath = $this->basePath() . '/' . $path;
|
||||
if (! $this->validRelativePath($path)) {
|
||||
return response()->json(['message' => 'Недопустимый путь.'], 422);
|
||||
}
|
||||
|
||||
$manifestKey = config('moonwell.launcher.manifest_key');
|
||||
if (! $disk->exists($manifestKey)) {
|
||||
return response()->json(['message' => 'Манифест не найден.'], 404);
|
||||
}
|
||||
|
||||
$manifest = json_decode($disk->get($manifestKey), true);
|
||||
$file = collect($manifest['files'] ?? [])->first(
|
||||
fn ($file) => is_array($file) && ($file['path'] ?? null) === $path,
|
||||
);
|
||||
if ($file === null) {
|
||||
return response()->json(['message' => 'Файл не найден в манифесте.'], 404);
|
||||
}
|
||||
|
||||
// New Rust deployments pin each file to an immutable release; legacy inventories use the base path.
|
||||
$basePath = $this->basePath();
|
||||
$fullPath = $file['objectKey'] ?? $basePath.'/'.$path;
|
||||
if (! is_string($fullPath) || ! $this->validRelativePath($fullPath)
|
||||
|| ! str_starts_with($fullPath, $basePath.'/')) {
|
||||
return response()->json(['message' => 'Некорректный ключ файла в манифесте.'], 500);
|
||||
}
|
||||
|
||||
if (! $disk->exists($fullPath)) {
|
||||
return response()->json(['message' => 'Файл не найден.'], 404);
|
||||
@@ -213,4 +236,10 @@ class LauncherController extends Controller
|
||||
{
|
||||
return config('moonwell.launcher.base_path', 'World of Warcraft 1.12.1');
|
||||
}
|
||||
|
||||
private function validRelativePath(string $path): bool
|
||||
{
|
||||
return $path !== '' && ! preg_match('/[\\\\:\x00-\x1f\x7f]/', $path)
|
||||
&& ! array_intersect(explode('/', $path), ['', '.', '..']);
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user