diff --git a/resources/views/livewire/project/database/backup-executions.blade.php b/resources/views/livewire/project/database/backup-executions.blade.php index a361eb8d3..c9be822e3 100644 --- a/resources/views/livewire/project/database/backup-executions.blade.php +++ b/resources/views/livewire/project/database/backup-executions.blade.php @@ -24,7 +24,7 @@ class="relative flex flex-col p-4 bg-white box-without-bg dark:bg-coolgray-100"
@if (data_get($execution, 'status') === 'success') Download + wire:click="download_file({{ data_get($execution, 'id') }})">Download @endif diff --git a/routes/web.php b/routes/web.php index c33e3b0eb..ecc9d1998 100644 --- a/routes/web.php +++ b/routes/web.php @@ -46,7 +46,6 @@ use App\Livewire\Project\Database\Configuration as DatabaseConfiguration; use App\Livewire\Project\Database\Backup\Index as DatabaseBackupIndex; use App\Livewire\Project\Database\Backup\Execution as DatabaseBackupExecution; - use App\Livewire\Project\Service\Configuration as ServiceConfiguration; use App\Livewire\Project\Service\Index as ServiceIndex; @@ -77,10 +76,62 @@ use App\Livewire\TeamSharedVariablesIndex; use App\Livewire\Waitlist\Index as WaitlistIndex; +use App\Models\ScheduledDatabaseBackupExecution; +use Illuminate\Support\Facades\Storage; +use Symfony\Component\HttpFoundation\StreamedResponse; if (isDev()) { Route::get('/dev/compose', Compose::class)->name('dev.compose'); } + +Route::get('/download/backup/{executionId}', function () { + try { + $team = auth()->user()->currentTeam(); + $exeuctionId = request()->route('executionId'); + $execution = ScheduledDatabaseBackupExecution::where('id', $exeuctionId)->firstOrFail(); + // get team + if ($team->id !== $execution->scheduledDatabaseBackup->database->team()->id) { + abort(403); + } + if (is_null($execution)) { + $this->dispatch('error', 'Backup execution not found.'); + return; + } + $filename = data_get($execution, 'filename'); + if ($execution->scheduledDatabaseBackup->database->getMorphClass() === 'App\Models\ServiceDatabase') { + $server = $execution->scheduledDatabaseBackup->database->service->destination->server; + } else { + $server = $execution->scheduledDatabaseBackup->database->destination->server; + } + $privateKeyLocation = savePrivateKeyToFs($server); + $disk = Storage::build([ + 'driver' => 'sftp', + 'host' => $server->ip, + 'port' => $server->port, + 'username' => $server->user, + 'privateKey' => $privateKeyLocation, + ]); + return new StreamedResponse(function () use ($disk, $filename) { + if (ob_get_level()) ob_end_clean(); + $stream = $disk->readStream($filename); + if ($stream === false) { + abort(500, 'Failed to open stream for the requested file.'); + } + while (!feof($stream)) { + echo fread($stream, 2048); + flush(); + } + + fclose($stream); + }, 200, [ + 'Content-Type' => 'application/octet-stream', + 'Content-Disposition' => 'attachment; filename="' . basename($filename) . '"', + ]); + } catch (\Throwable $e) { + throw $e; + } +})->name('download.backup'); + Route::get('/admin', AdminIndex::class)->name('admin.index'); Route::post('/forgot-password', [Controller::class, 'forgot_password'])->name('password.forgot');