diff --git a/app/Http/Controllers/Api/Client/Servers/BackupController.php b/app/Http/Controllers/Api/Client/Servers/BackupController.php index 222f6711c..1cbecf262 100644 --- a/app/Http/Controllers/Api/Client/Servers/BackupController.php +++ b/app/Http/Controllers/Api/Client/Servers/BackupController.php @@ -87,7 +87,9 @@ class BackupController extends ClientApiController } $backup = $this->initiateBackupService - ->setIgnoredFiles($request->input('ignored')) + ->setIgnoredFiles( + explode(PHP_EOL, $request->input('ignored') ?? '') + ) ->handle($server, $request->input('name')); return $this->fractal->item($backup) diff --git a/app/Http/Requests/Api/Client/Servers/Backups/StoreBackupRequest.php b/app/Http/Requests/Api/Client/Servers/Backups/StoreBackupRequest.php index b5ef7110e..e6dd2ad43 100644 --- a/app/Http/Requests/Api/Client/Servers/Backups/StoreBackupRequest.php +++ b/app/Http/Requests/Api/Client/Servers/Backups/StoreBackupRequest.php @@ -22,7 +22,7 @@ class StoreBackupRequest extends ClientApiRequest { return [ 'name' => 'nullable|string|max:255', - 'ignore' => 'nullable|string', + 'ignored' => 'nullable|string', ]; } } diff --git a/app/Http/Requests/Api/Remote/ReportBackupCompleteRequest.php b/app/Http/Requests/Api/Remote/ReportBackupCompleteRequest.php index d115fc50c..edf744dc9 100644 --- a/app/Http/Requests/Api/Remote/ReportBackupCompleteRequest.php +++ b/app/Http/Requests/Api/Remote/ReportBackupCompleteRequest.php @@ -13,8 +13,8 @@ class ReportBackupCompleteRequest extends FormRequest { return [ 'successful' => 'boolean', - 'checksum' => 'string|required_if:successful,true', - 'size' => 'numeric|required_if:successful,true', + 'checksum' => 'nullable|string|required_if:successful,true', + 'size' => 'nullable|numeric|required_if:successful,true', ]; } } diff --git a/app/Models/Backup.php b/app/Models/Backup.php index 6259f11c6..d324090e5 100644 --- a/app/Models/Backup.php +++ b/app/Models/Backup.php @@ -9,7 +9,7 @@ use Illuminate\Database\Eloquent\SoftDeletes; * @property int $server_id * @property int $uuid * @property string $name - * @property string $ignored_files + * @property string[] $ignored_files * @property string $disk * @property string|null $sha256_hash * @property int $bytes @@ -45,6 +45,7 @@ class Backup extends Model protected $casts = [ 'id' => 'int', 'bytes' => 'int', + 'ignored_files' => 'array', ]; /** @@ -69,7 +70,7 @@ class Backup extends Model 'server_id' => 'bail|required|numeric|exists:servers,id', 'uuid' => 'required|uuid', 'name' => 'required|string', - 'ignored_files' => 'string', + 'ignored_files' => 'array', 'disk' => 'required|string', 'sha256_hash' => 'nullable|string', 'bytes' => 'numeric', diff --git a/app/Repositories/Wings/DaemonBackupRepository.php b/app/Repositories/Wings/DaemonBackupRepository.php index d27425e27..e40793dd7 100644 --- a/app/Repositories/Wings/DaemonBackupRepository.php +++ b/app/Repositories/Wings/DaemonBackupRepository.php @@ -29,7 +29,7 @@ class DaemonBackupRepository extends DaemonRepository [ 'json' => [ 'uuid' => $backup->uuid, - 'ignored_files' => explode(PHP_EOL, $backup->ignored_files), + 'ignored_files' => $backup->ignored_files, ], ] ); diff --git a/app/Services/Backups/InitiateBackupService.php b/app/Services/Backups/InitiateBackupService.php index f9c4de4b5..24a3203cb 100644 --- a/app/Services/Backups/InitiateBackupService.php +++ b/app/Services/Backups/InitiateBackupService.php @@ -4,6 +4,7 @@ namespace Pterodactyl\Services\Backups; use Ramsey\Uuid\Uuid; use Carbon\CarbonImmutable; +use Webmozart\Assert\Assert; use Pterodactyl\Models\Backup; use Pterodactyl\Models\Server; use Illuminate\Database\ConnectionInterface; @@ -13,7 +14,7 @@ use Pterodactyl\Repositories\Wings\DaemonBackupRepository; class InitiateBackupService { /** - * @var string|null + * @var string[]|null */ private $ignoredFiles; @@ -52,12 +53,23 @@ class InitiateBackupService /** * Sets the files to be ignored by this backup. * - * @param string|null $ignored + * @param string[]|null $ignored * @return $this */ - public function setIgnoredFiles(?string $ignored) + public function setIgnoredFiles(?array $ignored) { - $this->ignoredFiles = $ignored; + if (is_array($ignored)) { + foreach ($ignored as $value) { + Assert::string($value); + } + } + + // Set the ignored files to be any values that are not empty in the array. Don't use + // the PHP empty function here incase anything that is "empty" by default (0, false, etc.) + // were passed as a file or folder name. + $this->ignoredFiles = is_null($ignored) ? [] : array_filter($ignored, function ($value) { + return strlen($value) > 0; + }); return $this; } @@ -79,7 +91,7 @@ class InitiateBackupService 'server_id' => $server->id, 'uuid' => Uuid::uuid4()->toString(), 'name' => trim($name) ?: sprintf('Backup at %s', CarbonImmutable::now()->toDateTimeString()), - 'ignored_files' => $this->ignoredFiles ?? '', + 'ignored_files' => is_array($this->ignoredFiles) ? array_values($this->ignoredFiles) : [], 'disk' => 'local', ], true, true); diff --git a/resources/scripts/api/server/backups/createServerBackup.ts b/resources/scripts/api/server/backups/createServerBackup.ts index 2616c2bf3..ade809bb1 100644 --- a/resources/scripts/api/server/backups/createServerBackup.ts +++ b/resources/scripts/api/server/backups/createServerBackup.ts @@ -1,10 +1,10 @@ import { rawDataToServerBackup, ServerBackup } from '@/api/server/backups/getServerBackups'; import http from '@/api/http'; -export default (uuid: string, name?: string, ignore?: string): Promise => { +export default (uuid: string, name?: string, ignored?: string): Promise => { return new Promise((resolve, reject) => { http.post(`/api/client/servers/${uuid}/backups`, { - name, ignore, + name, ignored, }) .then(({ data }) => resolve(rawDataToServerBackup(data))) .catch(reject); diff --git a/resources/scripts/components/server/backups/CreateBackupButton.tsx b/resources/scripts/components/server/backups/CreateBackupButton.tsx index 476ce0b7a..9e0e8421c 100644 --- a/resources/scripts/components/server/backups/CreateBackupButton.tsx +++ b/resources/scripts/components/server/backups/CreateBackupButton.tsx @@ -33,7 +33,7 @@ const ModalContent = ({ ...props }: RequiredModalProps) => {
{ `} >