Merge branch 'main' into issue/68

# Conflicts:
#	app/Filament/Resources/DatabaseHostResource/Pages/CreateDatabaseHost.php
#	app/Filament/Resources/DatabaseHostResource/Pages/EditDatabaseHost.php
#	app/Filament/Resources/ServerResource/Pages/CreateServer.php
#	app/Filament/Resources/ServerResource/Pages/EditServer.php
#	app/Filament/Resources/ServerResource/Pages/ListServers.php
#	app/Http/Requests/Admin/Node/AllocationFormRequest.php
#	app/Http/Requests/Api/Application/Allocations/StoreAllocationRequest.php
#	app/Models/AuditLog.php
#	app/Models/Server.php
This commit is contained in:
Lance Pioch 2024-06-26 21:52:05 -04:00
commit 45fcc2a09a
60 changed files with 1393 additions and 829 deletions

View File

@ -24,7 +24,7 @@ class QueueWorkerServiceCommand extends Command
$fileExists = file_exists($path); $fileExists = file_exists($path);
if ($fileExists && !$this->option('overwrite') && !$this->confirm('The service file already exists. Do you want to overwrite it?')) { if ($fileExists && !$this->option('overwrite') && !$this->confirm('The service file already exists. Do you want to overwrite it?')) {
$this->line('Creation of queue worker service file aborted because serive file already exists.'); $this->line('Creation of queue worker service file aborted because service file already exists.');
return; return;
} }
@ -32,7 +32,8 @@ class QueueWorkerServiceCommand extends Command
$user = $this->option('user') ?? $this->ask('Webserver User', 'www-data'); $user = $this->option('user') ?? $this->ask('Webserver User', 'www-data');
$group = $this->option('group') ?? $this->ask('Webserver Group', 'www-data'); $group = $this->option('group') ?? $this->ask('Webserver Group', 'www-data');
$afterRedis = $this->option('use-redis') ? '\nAfter=redis-server.service' : ''; $afterRedis = $this->option('use-redis') ? '
After=redis-server.service' : '';
$basePath = base_path(); $basePath = base_path();

View File

@ -57,19 +57,19 @@ class MakeNodeCommand extends Command
$data['public'] = $this->option('public') ?? $this->confirm(__('commands.make_node.public'), true); $data['public'] = $this->option('public') ?? $this->confirm(__('commands.make_node.public'), true);
$data['behind_proxy'] = $this->option('proxy') ?? $this->confirm(__('commands.make_node.behind_proxy')); $data['behind_proxy'] = $this->option('proxy') ?? $this->confirm(__('commands.make_node.behind_proxy'));
$data['maintenance_mode'] = $this->option('maintenance') ?? $this->confirm(__('commands.make_node.maintenance_mode')); $data['maintenance_mode'] = $this->option('maintenance') ?? $this->confirm(__('commands.make_node.maintenance_mode'));
$data['memory'] = $this->option('maxMemory') ?? $this->ask(__('commands.make_node.memory')); $data['memory'] = $this->option('maxMemory') ?? $this->ask(__('commands.make_node.memory'), '0');
$data['memory_overallocate'] = $this->option('overallocateMemory') ?? $this->ask(__('commands.make_node.memory_overallocate')); $data['memory_overallocate'] = $this->option('overallocateMemory') ?? $this->ask(__('commands.make_node.memory_overallocate'), '-1');
$data['disk'] = $this->option('maxDisk') ?? $this->ask(__('commands.make_node.disk')); $data['disk'] = $this->option('maxDisk') ?? $this->ask(__('commands.make_node.disk'), '0');
$data['disk_overallocate'] = $this->option('overallocateDisk') ?? $this->ask(__('commands.make_node.disk_overallocate')); $data['disk_overallocate'] = $this->option('overallocateDisk') ?? $this->ask(__('commands.make_node.disk_overallocate'), '-1');
$data['cpu'] = $this->option('maxCpu') ?? $this->ask(__('commands.make_node.cpu')); $data['cpu'] = $this->option('maxCpu') ?? $this->ask(__('commands.make_node.cpu'), '0');
$data['cpu_overallocate'] = $this->option('overallocateCpu') ?? $this->ask(__('commands.make_node.cpu_overallocate')); $data['cpu_overallocate'] = $this->option('overallocateCpu') ?? $this->ask(__('commands.make_node.cpu_overallocate'), '-1');
$data['upload_size'] = $this->option('uploadSize') ?? $this->ask(__('commands.make_node.upload_size'), '100'); $data['upload_size'] = $this->option('uploadSize') ?? $this->ask(__('commands.make_node.upload_size'), '256');
$data['daemon_listen'] = $this->option('daemonListeningPort') ?? $this->ask(__('commands.make_node.daemonListen'), '8080'); $data['daemon_listen'] = $this->option('daemonListeningPort') ?? $this->ask(__('commands.make_node.daemonListen'), '8080');
$data['daemon_sftp'] = $this->option('daemonSFTPPort') ?? $this->ask(__('commands.make_node.daemonSFTP'), '2022'); $data['daemon_sftp'] = $this->option('daemonSFTPPort') ?? $this->ask(__('commands.make_node.daemonSFTP'), '2022');
$data['daemon_sftp_alias'] = $this->option('daemonSFTPAlias') ?? $this->ask(__('commands.make_node.daemonSFTPAlias'), ''); $data['daemon_sftp_alias'] = $this->option('daemonSFTPAlias') ?? $this->ask(__('commands.make_node.daemonSFTPAlias'), '');
$data['daemon_base'] = $this->option('daemonBase') ?? $this->ask(__('commands.make_node.daemonBase'), '/var/lib/pelican/volumes'); $data['daemon_base'] = $this->option('daemonBase') ?? $this->ask(__('commands.make_node.daemonBase'), '/var/lib/pelican/volumes');
$node = $this->creationService->handle($data); $node = $this->creationService->handle($data);
$this->line(__('commands.make_node.succes1') . $data['name'] . __('commands.make_node.succes2') . $node->id . '.'); $this->line(__('commands.make_node.success', ['name' => $data['name'], 'id' => $node->id]));
} }
} }

View File

@ -4,10 +4,14 @@ namespace App\Filament\Resources\DatabaseHostResource\Pages;
use App\Filament\Resources\DatabaseHostResource; use App\Filament\Resources\DatabaseHostResource;
use App\Models\Objects\Endpoint; use App\Models\Objects\Endpoint;
use App\Services\Databases\Hosts\HostCreationService;
use Filament\Resources\Pages\CreateRecord; use Filament\Resources\Pages\CreateRecord;
use Filament\Forms; use Filament\Forms;
use Filament\Forms\Components\Section; use Filament\Forms\Components\Section;
use Filament\Forms\Form; use Filament\Forms\Form;
use Filament\Notifications\Notification;
use Illuminate\Database\Eloquent\Model;
use PDOException;
class CreateDatabaseHost extends CreateRecord class CreateDatabaseHost extends CreateRecord
{ {
@ -37,7 +41,7 @@ class CreateDatabaseHost extends CreateRecord
->required() ->required()
->live(onBlur: true) ->live(onBlur: true)
->afterStateUpdated(fn ($state, Forms\Set $set) => $set('name', $state)) ->afterStateUpdated(fn ($state, Forms\Set $set) => $set('name', $state))
->maxLength(191), ->maxLength(255),
Forms\Components\TextInput::make('port') Forms\Components\TextInput::make('port')
->columnSpan(1) ->columnSpan(1)
->helperText('The port that MySQL is running on for this host.') ->helperText('The port that MySQL is running on for this host.')
@ -58,12 +62,12 @@ class CreateDatabaseHost extends CreateRecord
Forms\Components\TextInput::make('username') Forms\Components\TextInput::make('username')
->helperText('The username of an account that has enough permissions to create new users and databases on the system.') ->helperText('The username of an account that has enough permissions to create new users and databases on the system.')
->required() ->required()
->maxLength(191), ->maxLength(255),
Forms\Components\TextInput::make('password') Forms\Components\TextInput::make('password')
->helperText('The password for the database user.') ->helperText('The password for the database user.')
->password() ->password()
->revealable() ->revealable()
->maxLength(191) ->maxLength(255)
->required(), ->required(),
Forms\Components\Select::make('node_id') Forms\Components\Select::make('node_id')
->searchable() ->searchable()
@ -80,11 +84,30 @@ class CreateDatabaseHost extends CreateRecord
return [ return [
$this->getCreateFormAction()->formId('form'), $this->getCreateFormAction()->formId('form'),
]; ];
} }
protected function getFormActions(): array protected function getFormActions(): array
{ {
return []; return [];
} }
protected function handleRecordCreation(array $data): Model
{
return resolve(HostCreationService::class)->handle($data);
}
public function exception($e, $stopPropagation): void
{
if ($e instanceof PDOException) {
Notification::make()
->title('Error connecting to database host')
->body($e->getMessage())
->color('danger')
->icon('tabler-database')
->danger()
->send();
$stopPropagation();
}
}
} }

View File

@ -5,11 +5,15 @@ namespace App\Filament\Resources\DatabaseHostResource\Pages;
use App\Filament\Resources\DatabaseHostResource; use App\Filament\Resources\DatabaseHostResource;
use App\Models\DatabaseHost; use App\Models\DatabaseHost;
use App\Models\Objects\Endpoint; use App\Models\Objects\Endpoint;
use App\Services\Databases\Hosts\HostUpdateService;
use Filament\Actions; use Filament\Actions;
use Filament\Resources\Pages\EditRecord; use Filament\Resources\Pages\EditRecord;
use Filament\Forms; use Filament\Forms;
use Filament\Forms\Components\Section; use Filament\Forms\Components\Section;
use Filament\Forms\Form; use Filament\Forms\Form;
use Filament\Notifications\Notification;
use Illuminate\Database\Eloquent\Model;
use PDOException;
class EditDatabaseHost extends EditRecord class EditDatabaseHost extends EditRecord
{ {
@ -33,7 +37,7 @@ class EditDatabaseHost extends EditRecord
->required() ->required()
->live(onBlur: true) ->live(onBlur: true)
->afterStateUpdated(fn ($state, Forms\Set $set) => $set('name', $state)) ->afterStateUpdated(fn ($state, Forms\Set $set) => $set('name', $state))
->maxLength(191), ->maxLength(255),
Forms\Components\TextInput::make('port') Forms\Components\TextInput::make('port')
->columnSpan(1) ->columnSpan(1)
->helperText('The port that MySQL is running on for this host.') ->helperText('The port that MySQL is running on for this host.')
@ -53,12 +57,12 @@ class EditDatabaseHost extends EditRecord
Forms\Components\TextInput::make('username') Forms\Components\TextInput::make('username')
->helperText('The username of an account that has enough permissions to create new users and databases on the system.') ->helperText('The username of an account that has enough permissions to create new users and databases on the system.')
->required() ->required()
->maxLength(191), ->maxLength(255),
Forms\Components\TextInput::make('password') Forms\Components\TextInput::make('password')
->helperText('The password for the database user.') ->helperText('The password for the database user.')
->password() ->password()
->revealable() ->revealable()
->maxLength(191) ->maxLength(255)
->required(), ->required(),
Forms\Components\Select::make('node_id') Forms\Components\Select::make('node_id')
->searchable() ->searchable()
@ -91,4 +95,24 @@ class EditDatabaseHost extends EditRecord
DatabaseHostResource\RelationManagers\DatabasesRelationManager::class, DatabaseHostResource\RelationManagers\DatabasesRelationManager::class,
]; ];
} }
protected function handleRecordUpdate($record, array $data): Model
{
return resolve(HostUpdateService::class)->handle($record->id, $data);
}
public function exception($e, $stopPropagation): void
{
if ($e instanceof PDOException) {
Notification::make()
->title('Error connecting to database host')
->body($e->getMessage())
->color('danger')
->icon('tabler-database')
->danger()
->send();
$stopPropagation();
}
}
} }

View File

@ -44,7 +44,6 @@ class DatabasesRelationManager extends RelationManager
->columns([ ->columns([
Tables\Columns\TextColumn::make('database')->icon('tabler-database'), Tables\Columns\TextColumn::make('database')->icon('tabler-database'),
Tables\Columns\TextColumn::make('username')->icon('tabler-user'), Tables\Columns\TextColumn::make('username')->icon('tabler-user'),
//Tables\Columns\TextColumn::make('password'),
Tables\Columns\TextColumn::make('remote'), Tables\Columns\TextColumn::make('remote'),
Tables\Columns\TextColumn::make('server.name') Tables\Columns\TextColumn::make('server.name')
->icon('tabler-brand-docker') ->icon('tabler-brand-docker')
@ -55,7 +54,6 @@ class DatabasesRelationManager extends RelationManager
->actions([ ->actions([
Tables\Actions\DeleteAction::make(), Tables\Actions\DeleteAction::make(),
Tables\Actions\ViewAction::make()->color('primary'), Tables\Actions\ViewAction::make()->color('primary'),
//Tables\Actions\EditAction::make(),
]); ]);
} }

View File

@ -25,14 +25,14 @@ class CreateDatabase extends CreateRecord
->numeric(), ->numeric(),
Forms\Components\TextInput::make('database') Forms\Components\TextInput::make('database')
->required() ->required()
->maxLength(191), ->maxLength(255),
Forms\Components\TextInput::make('remote') Forms\Components\TextInput::make('remote')
->required() ->required()
->maxLength(191) ->maxLength(255)
->default('%'), ->default('%'),
Forms\Components\TextInput::make('username') Forms\Components\TextInput::make('username')
->required() ->required()
->maxLength(191), ->maxLength(255),
Forms\Components\TextInput::make('password') Forms\Components\TextInput::make('password')
->password() ->password()
->revealable() ->revealable()

View File

@ -26,14 +26,14 @@ class EditDatabase extends EditRecord
->numeric(), ->numeric(),
Forms\Components\TextInput::make('database') Forms\Components\TextInput::make('database')
->required() ->required()
->maxLength(191), ->maxLength(255),
Forms\Components\TextInput::make('remote') Forms\Components\TextInput::make('remote')
->required() ->required()
->maxLength(191) ->maxLength(255)
->default('%'), ->default('%'),
Forms\Components\TextInput::make('username') Forms\Components\TextInput::make('username')
->required() ->required()
->maxLength(191), ->maxLength(255),
Forms\Components\TextInput::make('password') Forms\Components\TextInput::make('password')
->password() ->password()
->revealable() ->revealable()

View File

@ -25,11 +25,11 @@ class CreateEgg extends CreateRecord
->schema([ ->schema([
Forms\Components\TextInput::make('name') Forms\Components\TextInput::make('name')
->required() ->required()
->maxLength(191) ->maxLength(255)
->columnSpan(['default' => 1, 'sm' => 1, 'md' => 2, 'lg' => 2]) ->columnSpan(['default' => 1, 'sm' => 1, 'md' => 2, 'lg' => 2])
->helperText('A simple, human-readable name to use as an identifier for this Egg.'), ->helperText('A simple, human-readable name to use as an identifier for this Egg.'),
Forms\Components\TextInput::make('author') Forms\Components\TextInput::make('author')
->maxLength(191) ->maxLength(255)
->required() ->required()
->email() ->email()
->columnSpan(['default' => 1, 'sm' => 1, 'md' => 2, 'lg' => 2]) ->columnSpan(['default' => 1, 'sm' => 1, 'md' => 2, 'lg' => 2])
@ -88,7 +88,7 @@ class CreateEgg extends CreateRecord
->helperText('If you would like to default to settings from another Egg select it from the menu above.'), ->helperText('If you would like to default to settings from another Egg select it from the menu above.'),
Forms\Components\TextInput::make('config_stop') Forms\Components\TextInput::make('config_stop')
->required() ->required()
->maxLength(191) ->maxLength(255)
->label('Stop Command') ->label('Stop Command')
->helperText('The command that should be sent to server processes to stop them gracefully. If you need to send a SIGINT you should enter ^C here.'), ->helperText('The command that should be sent to server processes to stop them gracefully. If you need to send a SIGINT you should enter ^C here.'),
Forms\Components\Textarea::make('config_startup')->rows(10)->json() Forms\Components\Textarea::make('config_startup')->rows(10)->json()
@ -140,7 +140,7 @@ class CreateEgg extends CreateRecord
Forms\Components\TextInput::make('name') Forms\Components\TextInput::make('name')
->live() ->live()
->debounce(750) ->debounce(750)
->maxLength(191) ->maxLength(255)
->columnSpanFull() ->columnSpanFull()
->afterStateUpdated(fn (Forms\Set $set, $state) => $set('env_variable', str($state)->trim()->snake()->upper()->toString()) ->afterStateUpdated(fn (Forms\Set $set, $state) => $set('env_variable', str($state)->trim()->snake()->upper()->toString())
) )
@ -148,13 +148,13 @@ class CreateEgg extends CreateRecord
Forms\Components\Textarea::make('description')->columnSpanFull(), Forms\Components\Textarea::make('description')->columnSpanFull(),
Forms\Components\TextInput::make('env_variable') Forms\Components\TextInput::make('env_variable')
->label('Environment Variable') ->label('Environment Variable')
->maxLength(191) ->maxLength(255)
->prefix('{{') ->prefix('{{')
->suffix('}}') ->suffix('}}')
->hintIcon('tabler-code') ->hintIcon('tabler-code')
->hintIconTooltip(fn ($state) => "{{{$state}}}") ->hintIconTooltip(fn ($state) => "{{{$state}}}")
->required(), ->required(),
Forms\Components\TextInput::make('default_value')->maxLength(191), Forms\Components\TextInput::make('default_value')->maxLength(255),
Forms\Components\Fieldset::make('User Permissions') Forms\Components\Fieldset::make('User Permissions')
->schema([ ->schema([
Forms\Components\Checkbox::make('user_viewable')->label('Viewable'), Forms\Components\Checkbox::make('user_viewable')->label('Viewable'),
@ -173,7 +173,7 @@ class CreateEgg extends CreateRecord
Forms\Components\TextInput::make('script_container') Forms\Components\TextInput::make('script_container')
->required() ->required()
->maxLength(191) ->maxLength(255)
->default('alpine:3.4'), ->default('alpine:3.4'),
Forms\Components\Select::make('script_entry') Forms\Components\Select::make('script_entry')

View File

@ -4,7 +4,11 @@ namespace App\Filament\Resources\EggResource\Pages;
use App\Filament\Resources\EggResource; use App\Filament\Resources\EggResource;
use App\Models\Egg; use App\Models\Egg;
use App\Services\Eggs\Sharing\EggImporterService;
use Exception;
use Filament\Actions; use Filament\Actions;
use Filament\Forms\Components\Tabs;
use Filament\Notifications\Notification;
use Filament\Resources\Pages\EditRecord; use Filament\Resources\Pages\EditRecord;
use AbdelhamidErrahmouni\FilamentMonacoEditor\MonacoEditor; use AbdelhamidErrahmouni\FilamentMonacoEditor\MonacoEditor;
use App\Services\Eggs\Sharing\EggExporterService; use App\Services\Eggs\Sharing\EggExporterService;
@ -25,7 +29,7 @@ class EditEgg extends EditRecord
->schema([ ->schema([
Forms\Components\TextInput::make('name') Forms\Components\TextInput::make('name')
->required() ->required()
->maxLength(191) ->maxLength(255)
->columnSpan(['default' => 1, 'sm' => 1, 'md' => 2, 'lg' => 1]) ->columnSpan(['default' => 1, 'sm' => 1, 'md' => 2, 'lg' => 1])
->helperText('A simple, human-readable name to use as an identifier for this Egg.'), ->helperText('A simple, human-readable name to use as an identifier for this Egg.'),
Forms\Components\TextInput::make('uuid') Forms\Components\TextInput::make('uuid')
@ -42,7 +46,7 @@ class EditEgg extends EditRecord
->helperText('A description of this Egg that will be displayed throughout the Panel as needed.'), ->helperText('A description of this Egg that will be displayed throughout the Panel as needed.'),
Forms\Components\TextInput::make('author') Forms\Components\TextInput::make('author')
->required() ->required()
->maxLength(191) ->maxLength(255)
->email() ->email()
->disabled() ->disabled()
->columnSpan(['default' => 1, 'sm' => 1, 'md' => 2, 'lg' => 2]) ->columnSpan(['default' => 1, 'sm' => 1, 'md' => 2, 'lg' => 2])
@ -95,7 +99,7 @@ class EditEgg extends EditRecord
->relationship('configFrom', 'name', ignoreRecord: true) ->relationship('configFrom', 'name', ignoreRecord: true)
->helperText('If you would like to default to settings from another Egg select it from the menu above.'), ->helperText('If you would like to default to settings from another Egg select it from the menu above.'),
Forms\Components\TextInput::make('config_stop') Forms\Components\TextInput::make('config_stop')
->maxLength(191) ->maxLength(255)
->label('Stop Command') ->label('Stop Command')
->helperText('The command that should be sent to server processes to stop them gracefully. If you need to send a SIGINT you should enter ^C here.'), ->helperText('The command that should be sent to server processes to stop them gracefully. If you need to send a SIGINT you should enter ^C here.'),
Forms\Components\Textarea::make('config_startup')->rows(10)->json() Forms\Components\Textarea::make('config_startup')->rows(10)->json()
@ -143,7 +147,7 @@ class EditEgg extends EditRecord
Forms\Components\TextInput::make('name') Forms\Components\TextInput::make('name')
->live() ->live()
->debounce(750) ->debounce(750)
->maxLength(191) ->maxLength(255)
->columnSpanFull() ->columnSpanFull()
->afterStateUpdated(fn (Forms\Set $set, $state) => $set('env_variable', str($state)->trim()->snake()->upper()->toString()) ->afterStateUpdated(fn (Forms\Set $set, $state) => $set('env_variable', str($state)->trim()->snake()->upper()->toString())
) )
@ -151,13 +155,13 @@ class EditEgg extends EditRecord
Forms\Components\Textarea::make('description')->columnSpanFull(), Forms\Components\Textarea::make('description')->columnSpanFull(),
Forms\Components\TextInput::make('env_variable') Forms\Components\TextInput::make('env_variable')
->label('Environment Variable') ->label('Environment Variable')
->maxLength(191) ->maxLength(255)
->prefix('{{') ->prefix('{{')
->suffix('}}') ->suffix('}}')
->hintIcon('tabler-code') ->hintIcon('tabler-code')
->hintIconTooltip(fn ($state) => "{{{$state}}}") ->hintIconTooltip(fn ($state) => "{{{$state}}}")
->required(), ->required(),
Forms\Components\TextInput::make('default_value')->maxLength(191), Forms\Components\TextInput::make('default_value')->maxLength(255),
Forms\Components\Fieldset::make('User Permissions') Forms\Components\Fieldset::make('User Permissions')
->schema([ ->schema([
Forms\Components\Checkbox::make('user_viewable')->label('Viewable'), Forms\Components\Checkbox::make('user_viewable')->label('Viewable'),
@ -176,12 +180,12 @@ class EditEgg extends EditRecord
Forms\Components\TextInput::make('script_container') Forms\Components\TextInput::make('script_container')
->required() ->required()
->maxLength(191) ->maxLength(255)
->default('alpine:3.4'), ->default('alpine:3.4'),
Forms\Components\TextInput::make('script_entry') Forms\Components\TextInput::make('script_entry')
->required() ->required()
->maxLength(191) ->maxLength(255)
->default('ash'), ->default('ash'),
MonacoEditor::make('script_install') MonacoEditor::make('script_install')
@ -199,20 +203,97 @@ class EditEgg extends EditRecord
protected function getHeaderActions(): array protected function getHeaderActions(): array
{ {
return [ return [
Actions\DeleteAction::make() Actions\DeleteAction::make('deleteEgg')
->disabled(fn (Egg $egg): bool => $egg->servers()->count() > 0) ->disabled(fn (Egg $egg): bool => $egg->servers()->count() > 0)
->label(fn (Egg $egg): string => $egg->servers()->count() <= 0 ? 'Delete Egg' : 'Egg In Use'), ->label(fn (Egg $egg): string => $egg->servers()->count() <= 0 ? 'Delete' : 'In Use'),
Actions\Action::make('export')
->icon('tabler-download') Actions\Action::make('exportEgg')
->label('Export Egg') ->label('Export')
->color('primary') ->color('primary')
->action(fn (EggExporterService $service, Egg $egg) => response()->streamDownload(function () use ($service, $egg) { ->action(fn (EggExporterService $service, Egg $egg) => response()->streamDownload(function () use ($service, $egg) {
echo $service->handle($egg->id); echo $service->handle($egg->id);
}, 'egg-' . $egg->getKebabName() . '.json')), }, 'egg-' . $egg->getKebabName() . '.json')),
Actions\Action::make('importEgg')
->label('Import')
->form([
Forms\Components\Placeholder::make('warning')
->label('This will overwrite the current egg to the one you upload.'),
Tabs::make('Tabs')
->tabs([
Tabs\Tab::make('From File')
->icon('tabler-file-upload')
->schema([
Forms\Components\FileUpload::make('egg')
->label('Egg')
->hint('eg. minecraft.json')
->acceptedFileTypes(['application/json'])
->storeFiles(false),
]),
Tabs\Tab::make('From URL')
->icon('tabler-world-upload')
->schema([
Forms\Components\TextInput::make('url')
->label('URL')
->hint('Link to the egg file (eg. minecraft.json)')
->url(),
]),
])
->contained(false),
])
->action(function (array $data, Egg $egg): void {
/** @var EggImporterService $eggImportService */
$eggImportService = resolve(EggImporterService::class);
if (!empty($data['egg'])) {
try {
$eggImportService->fromFile($data['egg'], $egg);
} catch (Exception $exception) {
Notification::make()
->title('Import Failed')
->body($exception->getMessage())
->danger()
->send();
report($exception);
return;
}
}
if (!empty($data['url'])) {
try {
$eggImportService->fromUrl($data['url'], $egg);
} catch (Exception $exception) {
Notification::make()
->title('Import Failed')
->body($exception->getMessage())
->danger()
->send();
report($exception);
return;
}
}
$this->refreshForm();
Notification::make()
->title('Import Success')
->success()
->send();
}),
$this->getSaveFormAction()->formId('form'), $this->getSaveFormAction()->formId('form'),
]; ];
} }
public function refreshForm(): void
{
$this->fillForm();
}
protected function getFormActions(): array protected function getFormActions(): array
{ {
return []; return [];

View File

@ -29,8 +29,7 @@ class ListEggs extends ListRecords
->columns([ ->columns([
Tables\Columns\TextColumn::make('id') Tables\Columns\TextColumn::make('id')
->label('Id') ->label('Id')
->searchable() ->hidden(),
->sortable(),
Tables\Columns\TextColumn::make('name') Tables\Columns\TextColumn::make('name')
->icon('tabler-egg') ->icon('tabler-egg')
->description(fn ($record): ?string => (strlen($record->description) > 120) ? substr($record->description, 0, 120).'...' : $record->description) ->description(fn ($record): ?string => (strlen($record->description) > 120) ? substr($record->description, 0, 120).'...' : $record->description)

View File

@ -48,11 +48,11 @@ class CreateMount extends CreateRecord
Forms\Components\TextInput::make('source') Forms\Components\TextInput::make('source')
->required() ->required()
->helperText('File path on the host system to mount to a container.') ->helperText('File path on the host system to mount to a container.')
->maxLength(191), ->maxLength(255),
Forms\Components\TextInput::make('target') Forms\Components\TextInput::make('target')
->required() ->required()
->helperText('Where the mount will be accessible inside a container.') ->helperText('Where the mount will be accessible inside a container.')
->maxLength(191), ->maxLength(255),
Forms\Components\ToggleButtons::make('user_mountable') Forms\Components\ToggleButtons::make('user_mountable')
->hidden() ->hidden()
->label('User mountable?') ->label('User mountable?')

View File

@ -45,11 +45,11 @@ class EditMount extends EditRecord
Forms\Components\TextInput::make('source') Forms\Components\TextInput::make('source')
->required() ->required()
->helperText('File path on the host system to mount to a container.') ->helperText('File path on the host system to mount to a container.')
->maxLength(191), ->maxLength(255),
Forms\Components\TextInput::make('target') Forms\Components\TextInput::make('target')
->required() ->required()
->helperText('Where the mount will be accessible inside a container.') ->helperText('Where the mount will be accessible inside a container.')
->maxLength(191), ->maxLength(255),
Forms\Components\ToggleButtons::make('user_mountable') Forms\Components\ToggleButtons::make('user_mountable')
->hidden() ->hidden()
->label('User mountable?') ->label('User mountable?')

View File

@ -93,7 +93,7 @@ class CreateNode extends CreateRecord
$set('dns', false); $set('dns', false);
}) })
->maxLength(191), ->maxLength(255),
Forms\Components\TextInput::make('ip') Forms\Components\TextInput::make('ip')
->disabled() ->disabled()
@ -131,8 +131,8 @@ class CreateNode extends CreateRecord
]) ])
->label(trans('strings.port')) ->label(trans('strings.port'))
->helperText('If you are running the daemon behind Cloudflare you should set the daemon port to 8443 to allow websocket proxying over SSL.') ->helperText('If you are running the daemon behind Cloudflare you should set the daemon port to 8443 to allow websocket proxying over SSL.')
->minValue(0) ->minValue(1)
->maxValue(65536) ->maxValue(65535)
->default(8080) ->default(8080)
->required() ->required()
->integer(), ->integer(),
@ -158,7 +158,6 @@ class CreateNode extends CreateRecord
'md' => 1, 'md' => 1,
'lg' => 1, 'lg' => 1,
]) ])
->required()
->inline() ->inline()
->helperText(function (Forms\Get $get) { ->helperText(function (Forms\Get $get) {
if (request()->isSecure()) { if (request()->isSecure()) {
@ -243,8 +242,8 @@ class CreateNode extends CreateRecord
Forms\Components\TextInput::make('daemon_sftp') Forms\Components\TextInput::make('daemon_sftp')
->columnSpan(1) ->columnSpan(1)
->label('SFTP Port') ->label('SFTP Port')
->minValue(0) ->minValue(1)
->maxValue(65536) ->maxValue(65535)
->default(2022) ->default(2022)
->required() ->required()
->integer(), ->integer(),
@ -279,7 +278,8 @@ class CreateNode extends CreateRecord
->columnSpan(2) ->columnSpan(2)
->numeric() ->numeric()
->minValue(0) ->minValue(0)
->default(0), ->default(0)
->required(),
Forms\Components\TextInput::make('memory_overallocate') Forms\Components\TextInput::make('memory_overallocate')
->dehydratedWhenHidden() ->dehydratedWhenHidden()
->label('Overallocate')->inlineLabel() ->label('Overallocate')->inlineLabel()
@ -291,7 +291,8 @@ class CreateNode extends CreateRecord
->minValue(-1) ->minValue(-1)
->maxValue(100) ->maxValue(100)
->default(0) ->default(0)
->suffix('%'), ->suffix('%')
->required(),
]), ]),
Forms\Components\Grid::make() Forms\Components\Grid::make()
->columns(6) ->columns(6)
@ -320,7 +321,8 @@ class CreateNode extends CreateRecord
->columnSpan(2) ->columnSpan(2)
->numeric() ->numeric()
->minValue(0) ->minValue(0)
->default(0), ->default(0)
->required(),
Forms\Components\TextInput::make('disk_overallocate') Forms\Components\TextInput::make('disk_overallocate')
->dehydratedWhenHidden() ->dehydratedWhenHidden()
->hidden(fn (Forms\Get $get) => $get('unlimited_disk')) ->hidden(fn (Forms\Get $get) => $get('unlimited_disk'))
@ -332,7 +334,8 @@ class CreateNode extends CreateRecord
->minValue(-1) ->minValue(-1)
->maxValue(100) ->maxValue(100)
->default(0) ->default(0)
->suffix('%'), ->suffix('%')
->required(),
]), ]),
Forms\Components\Grid::make() Forms\Components\Grid::make()
->columns(6) ->columns(6)
@ -361,7 +364,8 @@ class CreateNode extends CreateRecord
->columnSpan(2) ->columnSpan(2)
->numeric() ->numeric()
->default(0) ->default(0)
->minValue(0), ->minValue(0)
->required(),
Forms\Components\TextInput::make('cpu_overallocate') Forms\Components\TextInput::make('cpu_overallocate')
->dehydratedWhenHidden() ->dehydratedWhenHidden()
->hidden(fn (Forms\Get $get) => $get('unlimited_cpu')) ->hidden(fn (Forms\Get $get) => $get('unlimited_cpu'))
@ -373,7 +377,8 @@ class CreateNode extends CreateRecord
->default(0) ->default(0)
->minValue(-1) ->minValue(-1)
->maxValue(100) ->maxValue(100)
->suffix('%'), ->suffix('%')
->required(),
]), ]),
]), ]),
])->columnSpanFull() ])->columnSpanFull()

View File

@ -94,7 +94,7 @@ class EditNode extends EditRecord
$set('dns', false); $set('dns', false);
}) })
->maxLength(191), ->maxLength(255),
Forms\Components\TextInput::make('ip') Forms\Components\TextInput::make('ip')
->disabled() ->disabled()
@ -132,8 +132,8 @@ class EditNode extends EditRecord
]) ])
->label(trans('strings.port')) ->label(trans('strings.port'))
->helperText('If you are running the daemon behind Cloudflare you should set the daemon port to 8443 to allow websocket proxying over SSL.') ->helperText('If you are running the daemon behind Cloudflare you should set the daemon port to 8443 to allow websocket proxying over SSL.')
->minValue(0) ->minValue(1)
->maxValue(65536) ->maxValue(65535)
->default(8080) ->default(8080)
->required() ->required()
->integer(), ->integer(),
@ -159,7 +159,6 @@ class EditNode extends EditRecord
'md' => 1, 'md' => 1,
'lg' => 1, 'lg' => 1,
]) ])
->required()
->inline() ->inline()
->helperText(function (Forms\Get $get) { ->helperText(function (Forms\Get $get) {
if (request()->isSecure()) { if (request()->isSecure()) {
@ -218,8 +217,8 @@ class EditNode extends EditRecord
Forms\Components\TextInput::make('daemon_sftp') Forms\Components\TextInput::make('daemon_sftp')
->columnSpan(['default' => 1, 'sm' => 1, 'md' => 1, 'lg' => 3]) ->columnSpan(['default' => 1, 'sm' => 1, 'md' => 1, 'lg' => 3])
->label('SFTP Port') ->label('SFTP Port')
->minValue(0) ->minValue(1)
->maxValue(65536) ->maxValue(65535)
->default(2022) ->default(2022)
->required() ->required()
->integer(), ->integer(),

View File

@ -65,7 +65,7 @@ class CreateServer extends CreateRecord
'lg' => 3, 'lg' => 3,
]) ])
->required() ->required()
->maxLength(191), ->maxLength(255),
Forms\Components\Select::make('owner_id') Forms\Components\Select::make('owner_id')
->prefixIcon('tabler-user') ->prefixIcon('tabler-user')
@ -268,7 +268,7 @@ class CreateServer extends CreateRecord
$text = Forms\Components\TextInput::make('variable_value') $text = Forms\Components\TextInput::make('variable_value')
->hidden($this->shouldHideComponent(...)) ->hidden($this->shouldHideComponent(...))
->maxLength(191) ->maxLength(255)
->required(fn (Forms\Get $get) => in_array('required', explode('|', $get('rules')))) ->required(fn (Forms\Get $get) => in_array('required', explode('|', $get('rules'))))
->rules( ->rules(
fn (Forms\Get $get): Closure => function (string $attribute, $value, Closure $fail) use ($get) { fn (Forms\Get $get): Closure => function (string $attribute, $value, Closure $fail) use ($get) {
@ -521,18 +521,21 @@ class CreateServer extends CreateRecord
->suffixIcon('tabler-network') ->suffixIcon('tabler-network')
->required() ->required()
->numeric() ->numeric()
->minValue(0)
->default(0), ->default(0),
Forms\Components\TextInput::make('database_limit') Forms\Components\TextInput::make('database_limit')
->label('Databases') ->label('Databases')
->suffixIcon('tabler-database') ->suffixIcon('tabler-database')
->required() ->required()
->numeric() ->numeric()
->minValue(0)
->default(0), ->default(0),
Forms\Components\TextInput::make('backup_limit') Forms\Components\TextInput::make('backup_limit')
->label('Backups') ->label('Backups')
->suffixIcon('tabler-copy-check') ->suffixIcon('tabler-copy-check')
->required() ->required()
->numeric() ->numeric()
->minValue(0)
->default(0), ->default(0),
]), ]),
Forms\Components\Fieldset::make('Docker Settings') Forms\Components\Fieldset::make('Docker Settings')

View File

@ -6,6 +6,11 @@ use App\Models\Node;
use App\Models\Objects\Endpoint; use App\Models\Objects\Endpoint;
use Illuminate\Database\Eloquent\Builder; use Illuminate\Database\Eloquent\Builder;
use Illuminate\Support\HtmlString; use Illuminate\Support\HtmlString;
use App\Models\Database;
use App\Services\Databases\DatabaseManagementService;
use App\Services\Databases\DatabasePasswordService;
use Filament\Forms\Components\Actions\Action;
use Filament\Forms\Components\Repeater;
use LogicException; use LogicException;
use App\Filament\Resources\ServerResource; use App\Filament\Resources\ServerResource;
use App\Http\Controllers\Admin\ServersController; use App\Http\Controllers\Admin\ServersController;
@ -47,27 +52,6 @@ class EditServer extends EditRecord
'lg' => 4, 'lg' => 4,
]) ])
->schema([ ->schema([
Forms\Components\ToggleButtons::make('condition')
->label('')
->inline()
->formatStateUsing(fn (Server $server) => $server->condition)
->options(fn ($state) => collect(ContainerStatus::cases())->merge(ServerState::cases())
->filter(fn ($condition) => $condition->value === $state)
->mapWithKeys(fn ($state) => [$state->value => str($state->value)->replace('_', ' ')->ucwords()])
)
->colors(collect(ContainerStatus::cases())->merge(ServerState::cases())->mapWithKeys(
fn ($status) => [$status->value => $status->color()]
))
->icons(collect(ContainerStatus::cases())->merge(ServerState::cases())->mapWithKeys(
fn ($status) => [$status->value => $status->icon()]
))
->columnSpan([
'default' => 1,
'sm' => 2,
'md' => 2,
'lg' => 2,
]),
Tabs::make('Tabs') Tabs::make('Tabs')
->persistTabInQueryString() ->persistTabInQueryString()
->columnSpan(6) ->columnSpan(6)
@ -96,27 +80,47 @@ class EditServer extends EditRecord
})) }))
->columnSpan([ ->columnSpan([
'default' => 2, 'default' => 2,
'sm' => 2, 'sm' => 1,
'md' => 2, 'md' => 2,
'lg' => 3, 'lg' => 3,
]) ])
->required() ->required()
->maxLength(191), ->maxLength(255),
Forms\Components\Select::make('owner_id') Forms\Components\Select::make('owner_id')
->prefixIcon('tabler-user') ->prefixIcon('tabler-user')
->label('Owner') ->label('Owner')
->columnSpan([ ->columnSpan([
'default' => 2, 'default' => 2,
'sm' => 2, 'sm' => 1,
'md' => 2, 'md' => 2,
'lg' => 3, 'lg' => 2,
]) ])
->relationship('user', 'username') ->relationship('user', 'username')
->searchable() ->searchable()
->preload() ->preload()
->required(), ->required(),
Forms\Components\ToggleButtons::make('condition')
->label('Server Status')
->formatStateUsing(fn (Server $server) => $server->condition)
->options(fn ($state) => collect(array_merge(ContainerStatus::cases(), ServerState::cases()))
->filter(fn ($condition) => $condition->value === $state)
->mapWithKeys(fn ($state) => [$state->value => str($state->value)->replace('_', ' ')->ucwords()])
)
->colors(collect(array_merge(ContainerStatus::cases(), ServerState::cases()))->mapWithKeys(
fn ($status) => [$status->value => $status->color()]
))
->icons(collect(array_merge(ContainerStatus::cases(), ServerState::cases()))->mapWithKeys(
fn ($status) => [$status->value => $status->icon()]
))
->columnSpan([
'default' => 2,
'sm' => 1,
'md' => 1,
'lg' => 1,
]),
Forms\Components\Textarea::make('description') Forms\Components\Textarea::make('description')
->label('Description') ->label('Description')
->columnSpanFull(), ->columnSpanFull(),
@ -125,7 +129,7 @@ class EditServer extends EditRecord
->hintAction(CopyAction::make()) ->hintAction(CopyAction::make())
->columnSpan([ ->columnSpan([
'default' => 2, 'default' => 2,
'sm' => 2, 'sm' => 1,
'md' => 2, 'md' => 2,
'lg' => 3, 'lg' => 3,
]) ])
@ -135,7 +139,7 @@ class EditServer extends EditRecord
->hintAction(CopyAction::make()) ->hintAction(CopyAction::make())
->columnSpan([ ->columnSpan([
'default' => 2, 'default' => 2,
'sm' => 2, 'sm' => 1,
'md' => 2, 'md' => 2,
'lg' => 3, 'lg' => 3,
]) ])
@ -144,17 +148,17 @@ class EditServer extends EditRecord
->label('External ID') ->label('External ID')
->columnSpan([ ->columnSpan([
'default' => 2, 'default' => 2,
'sm' => 2, 'sm' => 1,
'md' => 2, 'md' => 2,
'lg' => 3, 'lg' => 3,
]) ])
->maxLength(191), ->maxLength(255),
Forms\Components\Select::make('node_id') Forms\Components\Select::make('node_id')
->label('Node') ->label('Node')
->relationship('node', 'name') ->relationship('node', 'name')
->columnSpan([ ->columnSpan([
'default' => 2, 'default' => 2,
'sm' => 2, 'sm' => 1,
'md' => 2, 'md' => 2,
'lg' => 3, 'lg' => 3,
]) ])
@ -362,14 +366,17 @@ class EditServer extends EditRecord
Forms\Components\TextInput::make('allocation_limit') Forms\Components\TextInput::make('allocation_limit')
->suffixIcon('tabler-network') ->suffixIcon('tabler-network')
->required() ->required()
->minValue(0)
->numeric(), ->numeric(),
Forms\Components\TextInput::make('database_limit') Forms\Components\TextInput::make('database_limit')
->suffixIcon('tabler-database') ->suffixIcon('tabler-database')
->required() ->required()
->minValue(0)
->numeric(), ->numeric(),
Forms\Components\TextInput::make('backup_limit') Forms\Components\TextInput::make('backup_limit')
->suffixIcon('tabler-copy-check') ->suffixIcon('tabler-copy-check')
->required() ->required()
->minValue(0)
->numeric(), ->numeric(),
]), ]),
Forms\Components\Fieldset::make('Docker Settings') Forms\Components\Fieldset::make('Docker Settings')
@ -569,6 +576,7 @@ class EditServer extends EditRecord
$text = Forms\Components\TextInput::make('variable_value') $text = Forms\Components\TextInput::make('variable_value')
->hidden($this->shouldHideComponent(...)) ->hidden($this->shouldHideComponent(...))
->required(fn (ServerVariable $serverVariable) => in_array('required', explode('|', $serverVariable->variable->rules)))
->rules([ ->rules([
fn (ServerVariable $serverVariable): Closure => function (string $attribute, $value, Closure $fail) use ($serverVariable) { fn (ServerVariable $serverVariable): Closure => function (string $attribute, $value, Closure $fail) use ($serverVariable) {
$validator = Validator::make(['validatorkey' => $value], [ $validator = Validator::make(['validatorkey' => $value], [
@ -618,9 +626,56 @@ class EditServer extends EditRecord
Tabs\Tab::make('Databases') Tabs\Tab::make('Databases')
->icon('tabler-database') ->icon('tabler-database')
->schema([ ->schema([
Forms\Components\Placeholder::make('soon') Repeater::make('databases')
->label('Soon™'), ->grid()
]), ->helperText(fn (Server $server) => $server->databases->isNotEmpty() ? '' : 'No Databases exist for this Server')
->columns(2)
->schema([
Forms\Components\TextInput::make('database')
->columnSpan(2)
->label('Database Name')
->disabled()
->formatStateUsing(fn ($record) => $record->database)
->hintAction(
Action::make('Delete')
->color('danger')
->icon('tabler-trash')
->action(fn (DatabaseManagementService $databaseManagementService, $record) => $databaseManagementService->delete($record))
),
Forms\Components\TextInput::make('username')
->disabled()
->formatStateUsing(fn ($record) => $record->username)
->columnSpan(2),
Forms\Components\TextInput::make('password')
->disabled()
->hintAction(
Action::make('rotate')
->icon('tabler-refresh')
->requiresConfirmation()
->action(fn (DatabasePasswordService $service, $record, $set, $get) => $this->rotatePassword($service, $record, $set, $get))
)
->formatStateUsing(fn (Database $database) => $database->password)
->columnSpan(2),
Forms\Components\TextInput::make('remote')
->disabled()
->formatStateUsing(fn ($record) => $record->remote)
->columnSpan(1)
->label('Connections From'),
Forms\Components\TextInput::make('max_connections')
->disabled()
->formatStateUsing(fn ($record) => $record->max_connections)
->columnSpan(1),
Forms\Components\TextInput::make('JDBC')
->disabled()
->label('JDBC Connection String')
->columnSpan(2)
->formatStateUsing(fn (Forms\Get $get, $record) => 'jdbc:mysql://' . $get('username') . ':' . urlencode($record->password) . '@' . $record->host->host . ':' . $record->host->port . '/' . $get('database')),
])
->relationship('databases')
->deletable(false)
->addable(false)
->columnSpan(4),
])->columns(4),
Tabs\Tab::make('Actions') Tabs\Tab::make('Actions')
->icon('tabler-settings') ->icon('tabler-settings')
->schema([ ->schema([
@ -740,7 +795,7 @@ class EditServer extends EditRecord
protected function transferServer(Form $form): Form protected function transferServer(Form $form): Form
{ {
return $form return $form
->columns(2) ->columns()
->schema([ ->schema([
Forms\Components\Select::make('toNode') Forms\Components\Select::make('toNode')
->label('New Node'), ->label('New Node'),
@ -755,6 +810,8 @@ class EditServer extends EditRecord
Actions\DeleteAction::make('Delete') Actions\DeleteAction::make('Delete')
->successRedirectUrl(route('filament.admin.resources.servers.index')) ->successRedirectUrl(route('filament.admin.resources.servers.index'))
->color('danger') ->color('danger')
->disabled(fn (Server $server) => $server->databases()->count() > 0)
->label(fn (Server $server) => $server->databases()->count() > 0 ? 'Server has a Database' : 'Delete')
->after(fn (Server $server) => resolve(ServerDeletionService::class)->handle($server)) ->after(fn (Server $server) => resolve(ServerDeletionService::class)->handle($server))
->requiresConfirmation(), ->requiresConfirmation(),
Actions\Action::make('console') Actions\Action::make('console')
@ -920,4 +977,13 @@ class EditServer extends EditRecord
return $options; return $options;
} }
protected function rotatePassword(DatabasePasswordService $service, $record, $set, $get): void
{
$newPassword = $service->handle($record);
$jdbcString = 'jdbc:mysql://' . $get('username') . ':' . urlencode($newPassword) . '@' . $record->host->host . ':' . $record->host->port . '/' . $get('database');
$set('password', $newPassword);
$set('JDBC', $jdbcString);
}
} }

View File

@ -13,6 +13,7 @@ use chillerlan\QRCode\Common\EccLevel;
use chillerlan\QRCode\Common\Version; use chillerlan\QRCode\Common\Version;
use chillerlan\QRCode\QRCode; use chillerlan\QRCode\QRCode;
use chillerlan\QRCode\QROptions; use chillerlan\QRCode\QROptions;
use DateTimeZone;
use Filament\Forms\Components\Actions\Action; use Filament\Forms\Components\Actions\Action;
use Filament\Forms\Components\Grid; use Filament\Forms\Components\Grid;
use Filament\Forms\Components\Placeholder; use Filament\Forms\Components\Placeholder;
@ -52,7 +53,7 @@ class EditProfile extends \Filament\Pages\Auth\EditProfile
->label(trans('strings.username')) ->label(trans('strings.username'))
->disabled() ->disabled()
->readOnly() ->readOnly()
->maxLength(191) ->maxLength(255)
->unique(ignoreRecord: true) ->unique(ignoreRecord: true)
->autofocus(), ->autofocus(),
@ -61,7 +62,7 @@ class EditProfile extends \Filament\Pages\Auth\EditProfile
->label(trans('strings.email')) ->label(trans('strings.email'))
->email() ->email()
->required() ->required()
->maxLength(191) ->maxLength(255)
->unique(ignoreRecord: true), ->unique(ignoreRecord: true),
TextInput::make('password') TextInput::make('password')
@ -85,6 +86,12 @@ class EditProfile extends \Filament\Pages\Auth\EditProfile
->visible(fn (Get $get): bool => filled($get('password'))) ->visible(fn (Get $get): bool => filled($get('password')))
->dehydrated(false), ->dehydrated(false),
Select::make('timezone')
->required()
->prefixIcon('tabler-clock-pin')
->options(fn () => collect(DateTimeZone::listIdentifiers())->mapWithKeys(fn ($tz) => [$tz => $tz]))
->searchable(),
Select::make('language') Select::make('language')
->label(trans('strings.language')) ->label(trans('strings.language'))
->required() ->required()
@ -193,8 +200,10 @@ class EditProfile extends \Filament\Pages\Auth\EditProfile
->schema([ ->schema([
Grid::make(5)->schema([ Grid::make(5)->schema([
Section::make('Create API Key')->columnSpan(3)->schema([ Section::make('Create API Key')->columnSpan(3)->schema([
TextInput::make('description') TextInput::make('description')
->live(), ->live(),
TagsInput::make('allowed_ips') TagsInput::make('allowed_ips')
->live() ->live()
->splitKeys([',', ' ', 'Tab']) ->splitKeys([',', ' ', 'Tab'])

View File

@ -20,8 +20,8 @@ class EditUser extends EditRecord
return $form return $form
->schema([ ->schema([
Section::make()->schema([ Section::make()->schema([
Forms\Components\TextInput::make('username')->required()->maxLength(191), Forms\Components\TextInput::make('username')->required()->maxLength(255),
Forms\Components\TextInput::make('email')->email()->required()->maxLength(191), Forms\Components\TextInput::make('email')->email()->required()->maxLength(255),
Forms\Components\TextInput::make('password') Forms\Components\TextInput::make('password')
->dehydrateStateUsing(fn (string $state): string => Hash::make($state)) ->dehydrateStateUsing(fn (string $state): string => Hash::make($state))

View File

@ -66,7 +66,7 @@ class ListUsers extends ListRecords
->actions([ ->actions([
Tables\Actions\EditAction::make(), Tables\Actions\EditAction::make(),
]) ])
->checkIfRecordIsSelectableUsing(fn (User $user) => !$user->servers_count) ->checkIfRecordIsSelectableUsing(fn (User $user) => auth()->user()->id !== $user->id && !$user->servers_count)
->bulkActions([ ->bulkActions([
Tables\Actions\BulkActionGroup::make([ Tables\Actions\BulkActionGroup::make([
Tables\Actions\DeleteBulkAction::make(), Tables\Actions\DeleteBulkAction::make(),
@ -85,12 +85,12 @@ class ListUsers extends ListRecords
Forms\Components\TextInput::make('username') Forms\Components\TextInput::make('username')
->alphaNum() ->alphaNum()
->required() ->required()
->maxLength(191), ->maxLength(255),
Forms\Components\TextInput::make('email') Forms\Components\TextInput::make('email')
->email() ->email()
->required() ->required()
->unique() ->unique()
->maxLength(191), ->maxLength(255),
Forms\Components\TextInput::make('password') Forms\Components\TextInput::make('password')
->hintIcon('tabler-question-mark') ->hintIcon('tabler-question-mark')

View File

@ -8,9 +8,9 @@ use Illuminate\Auth\AuthManager;
use Illuminate\Http\JsonResponse; use Illuminate\Http\JsonResponse;
use App\Facades\Activity; use App\Facades\Activity;
use App\Services\Users\UserUpdateService; use App\Services\Users\UserUpdateService;
use App\Transformers\Api\Client\AccountTransformer;
use App\Http\Requests\Api\Client\Account\UpdateEmailRequest; use App\Http\Requests\Api\Client\Account\UpdateEmailRequest;
use App\Http\Requests\Api\Client\Account\UpdatePasswordRequest; use App\Http\Requests\Api\Client\Account\UpdatePasswordRequest;
use App\Transformers\Api\Client\UserTransformer;
class AccountController extends ClientApiController class AccountController extends ClientApiController
{ {
@ -25,7 +25,7 @@ class AccountController extends ClientApiController
public function index(Request $request): array public function index(Request $request): array
{ {
return $this->fractal->item($request->user()) return $this->fractal->item($request->user())
->transformWith($this->getTransformer(AccountTransformer::class)) ->transformWith($this->getTransformer(UserTransformer::class))
->toArray(); ->toArray();
} }

View File

@ -83,7 +83,7 @@ abstract class AbstractLoginController extends Controller
'data' => [ 'data' => [
'complete' => true, 'complete' => true,
'intended' => $this->redirectPath(), 'intended' => $this->redirectPath(),
'user' => $user->toVueObject(), 'user' => $user->toReactObject(),
], ],
]); ]);
} }

View File

@ -9,14 +9,14 @@ class EggFormRequest extends AdminFormRequest
public function rules(): array public function rules(): array
{ {
$rules = [ $rules = [
'name' => 'required|string|max:191', 'name' => 'required|string|max:255',
'description' => 'nullable|string', 'description' => 'nullable|string',
'docker_images' => 'required|string', 'docker_images' => 'required|string',
'force_outgoing_ip' => 'sometimes|boolean', 'force_outgoing_ip' => 'sometimes|boolean',
'file_denylist' => 'array', 'file_denylist' => 'array',
'startup' => 'required|string', 'startup' => 'required|string',
'config_from' => 'sometimes|bail|nullable|numeric', 'config_from' => 'sometimes|bail|nullable|numeric',
'config_stop' => 'required_without:config_from|nullable|string|max:191', 'config_stop' => 'required_without:config_from|nullable|string|max:255',
'config_startup' => 'required_without:config_from|nullable|json', 'config_startup' => 'required_without:config_from|nullable|json',
'config_logs' => 'required_without:config_from|nullable|json', 'config_logs' => 'required_without:config_from|nullable|json',
'config_files' => 'required_without:config_from|nullable|json', 'config_files' => 'required_without:config_from|nullable|json',

View File

@ -13,9 +13,9 @@ class EggVariableFormRequest extends AdminFormRequest
public function rules(): array public function rules(): array
{ {
return [ return [
'name' => 'required|string|min:1|max:191', 'name' => 'required|string|min:1|max:255',
'description' => 'sometimes|nullable|string', 'description' => 'sometimes|nullable|string',
'env_variable' => 'required|regex:/^[\w]{1,191}$/|notIn:' . EggVariable::RESERVED_ENV_NAMES, 'env_variable' => 'required|regex:/^[\w]{1,255}$/|notIn:' . EggVariable::RESERVED_ENV_NAMES,
'options' => 'sometimes|required|array', 'options' => 'sometimes|required|array',
'rules' => 'bail|required|string', 'rules' => 'bail|required|string',
'default_value' => 'present', 'default_value' => 'present',

View File

@ -13,8 +13,8 @@ class AdvancedSettingsFormRequest extends AdminFormRequest
{ {
return [ return [
'recaptcha:enabled' => 'required|in:true,false', 'recaptcha:enabled' => 'required|in:true,false',
'recaptcha:secret_key' => 'required|string|max:191', 'recaptcha:secret_key' => 'required|string|max:255',
'recaptcha:website_key' => 'required|string|max:191', 'recaptcha:website_key' => 'required|string|max:255',
'panel:guzzle:timeout' => 'required|integer|between:1,60', 'panel:guzzle:timeout' => 'required|integer|between:1,60',
'panel:guzzle:connect_timeout' => 'required|integer|between:1,60', 'panel:guzzle:connect_timeout' => 'required|integer|between:1,60',
'panel:client_features:allocations:enabled' => 'required|in:true,false', 'panel:client_features:allocations:enabled' => 'required|in:true,false',

View File

@ -13,7 +13,7 @@ class BaseSettingsFormRequest extends AdminFormRequest
public function rules(): array public function rules(): array
{ {
return [ return [
'app:name' => 'required|string|max:191', 'app:name' => 'required|string|max:255',
'panel:auth:2fa_required' => 'required|integer|in:0,1,2', 'panel:auth:2fa_required' => 'required|integer|in:0,1,2',
'app:locale' => ['required', 'string', Rule::in(array_keys($this->getAvailableLanguages()))], 'app:locale' => ['required', 'string', Rule::in(array_keys($this->getAvailableLanguages()))],
]; ];

View File

@ -16,10 +16,10 @@ class MailSettingsFormRequest extends AdminFormRequest
'mail:mailers:smtp:host' => 'required|string', 'mail:mailers:smtp:host' => 'required|string',
'mail:mailers:smtp:port' => 'required|integer|between:1,65535', 'mail:mailers:smtp:port' => 'required|integer|between:1,65535',
'mail:mailers:smtp:encryption' => ['present', Rule::in([null, 'tls', 'ssl'])], 'mail:mailers:smtp:encryption' => ['present', Rule::in([null, 'tls', 'ssl'])],
'mail:mailers:smtp:username' => 'nullable|string|max:191', 'mail:mailers:smtp:username' => 'nullable|string|max:255',
'mail:mailers:smtp:password' => 'nullable|string|max:191', 'mail:mailers:smtp:password' => 'nullable|string|max:255',
'mail:from:address' => 'required|string|email', 'mail:from:address' => 'required|string|email',
'mail:from:name' => 'nullable|string|max:191', 'mail:from:name' => 'nullable|string|max:255',
]; ];
} }

View File

@ -15,7 +15,7 @@ class StoreBackupRequest extends ClientApiRequest
public function rules(): array public function rules(): array
{ {
return [ return [
'name' => 'nullable|string|max:191', 'name' => 'nullable|string|max:255',
'is_locked' => 'nullable|boolean', 'is_locked' => 'nullable|boolean',
'ignored' => 'nullable|string', 'ignored' => 'nullable|string',
]; ];

View File

@ -14,7 +14,7 @@ class StoreSubuserRequest extends SubuserRequest
public function rules(): array public function rules(): array
{ {
return [ return [
'email' => 'required|email|between:1,191', 'email' => 'required|email|between:1,255',
'permissions' => 'required|array', 'permissions' => 'required|array',
'permissions.*' => 'string', 'permissions.*' => 'string',
]; ];

View File

@ -24,7 +24,7 @@ class RunTaskJob extends Job implements ShouldQueue
*/ */
public function __construct(public Task $task, public bool $manualRun = false) public function __construct(public Task $task, public bool $manualRun = false)
{ {
$this->queue = 'standard';
} }
/** /**

View File

@ -46,7 +46,7 @@ class DatabaseHost extends Model
* Validation rules to assign to this model. * Validation rules to assign to this model.
*/ */
public static array $validationRules = [ public static array $validationRules = [
'name' => 'required|string|max:191', 'name' => 'required|string|max:255',
'host' => 'required|string', 'host' => 'required|string',
'port' => 'required|numeric|between:1,65535', 'port' => 'required|numeric|between:1,65535',
'username' => 'required|string|max:32', 'username' => 'required|string|max:32',

View File

@ -105,7 +105,7 @@ class Egg extends Model
public static array $validationRules = [ public static array $validationRules = [
'uuid' => 'required|string|size:36', 'uuid' => 'required|string|size:36',
'name' => 'required|string|max:191', 'name' => 'required|string|max:255',
'description' => 'string|nullable', 'description' => 'string|nullable',
'features' => 'array|nullable', 'features' => 'array|nullable',
'author' => 'required|string|email', 'author' => 'required|string|email',
@ -115,7 +115,7 @@ class Egg extends Model
'docker_images.*' => 'required|string', 'docker_images.*' => 'required|string',
'startup' => 'required|nullable|string', 'startup' => 'required|nullable|string',
'config_from' => 'sometimes|bail|nullable|numeric|exists:eggs,id', 'config_from' => 'sometimes|bail|nullable|numeric|exists:eggs,id',
'config_stop' => 'required_without:config_from|nullable|string|max:191', 'config_stop' => 'required_without:config_from|nullable|string|max:255',
'config_startup' => 'required_without:config_from|nullable|json', 'config_startup' => 'required_without:config_from|nullable|json',
'config_logs' => 'required_without:config_from|nullable|json', 'config_logs' => 'required_without:config_from|nullable|json',
'config_files' => 'required_without:config_from|nullable|json', 'config_files' => 'required_without:config_from|nullable|json',

View File

@ -52,9 +52,9 @@ class EggVariable extends Model
public static array $validationRules = [ public static array $validationRules = [
'egg_id' => 'exists:eggs,id', 'egg_id' => 'exists:eggs,id',
'sort' => 'nullable', 'sort' => 'nullable',
'name' => 'required|string|between:1,191', 'name' => 'required|string|between:1,255',
'description' => 'string', 'description' => 'string',
'env_variable' => 'required|alphaDash|between:1,191|notIn:' . self::RESERVED_ENV_NAMES, 'env_variable' => 'required|alphaDash|between:1,255|notIn:' . self::RESERVED_ENV_NAMES,
'default_value' => 'string', 'default_value' => 'string',
'user_viewable' => 'boolean', 'user_viewable' => 'boolean',
'user_editable' => 'boolean', 'user_editable' => 'boolean',

View File

@ -2,7 +2,11 @@
namespace App\Models; namespace App\Models;
use Carbon\CarbonInterface;
use DateTimeInterface;
use Illuminate\Support\Arr; use Illuminate\Support\Arr;
use Illuminate\Support\Carbon;
use Illuminate\Support\Facades\Date;
use Illuminate\Support\Str; use Illuminate\Support\Str;
use Illuminate\Validation\Rule; use Illuminate\Validation\Rule;
use Illuminate\Container\Container; use Illuminate\Container\Container;
@ -12,6 +16,7 @@ use App\Exceptions\Model\DataValidationException;
use Illuminate\Database\Eloquent\Model as IlluminateModel; use Illuminate\Database\Eloquent\Model as IlluminateModel;
use Illuminate\Validation\Factory as ValidationFactory; use Illuminate\Validation\Factory as ValidationFactory;
use Illuminate\Validation\Validator; use Illuminate\Validation\Validator;
use InvalidArgumentException;
abstract class Model extends IlluminateModel abstract class Model extends IlluminateModel
{ {
@ -64,6 +69,36 @@ abstract class Model extends IlluminateModel
return 'uuid'; return 'uuid';
} }
protected function asDateTime($value)
{
$timezone = auth()->user()?->timezone ?? config('app.timezone', 'UTC');
if ($value instanceof CarbonInterface) {
return Date::instance($value->timezone($timezone));
}
if ($value instanceof DateTimeInterface) {
return Date::parse($value->format('Y-m-d H:i:s.u'), $timezone);
}
if (is_numeric($value)) {
return Date::createFromTimestamp($value, $timezone);
}
if ($this->isStandardDateFormat($value)) {
return Date::instance(Carbon::createFromFormat('Y-m-d', $value)->timezone($timezone)->startOfDay());
}
$format = $this->getDateFormat();
try {
$date = Date::createFromFormat($format, $value)->timezone($timezone);
} catch (InvalidArgumentException) {
$date = false;
}
return $date ?: Date::parse($value);
}
/** /**
* Returns the validator instance used by this model. * Returns the validator instance used by this model.
*/ */

View File

@ -41,7 +41,7 @@ class Mount extends Model
*/ */
public static array $validationRules = [ public static array $validationRules = [
'name' => 'required|string|min:2|max:64|unique:mounts,name', 'name' => 'required|string|min:2|max:64|unique:mounts,name',
'description' => 'nullable|string|max:191', 'description' => 'nullable|string|max:255',
'source' => 'required|string', 'source' => 'required|string',
'target' => 'required|string', 'target' => 'required|string',
'read_only' => 'sometimes|boolean', 'read_only' => 'sometimes|boolean',

View File

@ -83,7 +83,7 @@ class Node extends Model
'description' => 'string|nullable', 'description' => 'string|nullable',
'public' => 'boolean', 'public' => 'boolean',
'fqdn' => 'required|string', 'fqdn' => 'required|string',
'scheme' => 'required', 'scheme' => 'required|string|in:http,https',
'behind_proxy' => 'boolean', 'behind_proxy' => 'boolean',
'memory' => 'required|numeric|min:0', 'memory' => 'required|numeric|min:0',
'memory_overallocate' => 'required|numeric|min:-1', 'memory_overallocate' => 'required|numeric|min:-1',

View File

@ -76,7 +76,7 @@ class Schedule extends Model
public static array $validationRules = [ public static array $validationRules = [
'server_id' => 'required|exists:servers,id', 'server_id' => 'required|exists:servers,id',
'name' => 'required|string|max:191', 'name' => 'required|string|max:255',
'cron_day_of_week' => 'required|string', 'cron_day_of_week' => 'required|string',
'cron_month' => 'required|string', 'cron_month' => 'required|string',
'cron_day_of_month' => 'required|string', 'cron_day_of_month' => 'required|string',

View File

@ -74,7 +74,6 @@ use App\Exceptions\Http\Server\ServerStateConflictException;
* @property \App\Models\User $user * @property \App\Models\User $user
* @property \Illuminate\Database\Eloquent\Collection|\App\Models\EggVariable[] $variables * @property \Illuminate\Database\Eloquent\Collection|\App\Models\EggVariable[] $variables
* @property int|null $variables_count * @property int|null $variables_count
*
* @method static \Database\Factories\ServerFactory factory(...$parameters) * @method static \Database\Factories\ServerFactory factory(...$parameters)
* @method static \Illuminate\Database\Eloquent\Builder|Server newModelQuery() * @method static \Illuminate\Database\Eloquent\Builder|Server newModelQuery()
* @method static \Illuminate\Database\Eloquent\Builder|Server newQuery() * @method static \Illuminate\Database\Eloquent\Builder|Server newQuery()
@ -105,9 +104,9 @@ use App\Exceptions\Http\Server\ServerStateConflictException;
* @method static \Illuminate\Database\Eloquent\Builder|Server whereUpdatedAt($value) * @method static \Illuminate\Database\Eloquent\Builder|Server whereUpdatedAt($value)
* @method static \Illuminate\Database\Eloquent\Builder|Server whereUuid($value) * @method static \Illuminate\Database\Eloquent\Builder|Server whereUuid($value)
* @method static \Illuminate\Database\Eloquent\Builder|Server whereuuid_short($value) * @method static \Illuminate\Database\Eloquent\Builder|Server whereuuid_short($value)
*
* @property array|null $docker_labels * @property array|null $docker_labels
* @property Collection<Endpoint>|null $ports * @property Collection<Endpoint>|null $ports
* @property-read mixed $condition
* @property-read \Illuminate\Database\Eloquent\Collection<int, \App\Models\EggVariable> $eggVariables * @property-read \Illuminate\Database\Eloquent\Collection<int, \App\Models\EggVariable> $eggVariables
* @property-read int|null $egg_variables_count * @property-read int|null $egg_variables_count
* @property-read \Illuminate\Database\Eloquent\Collection<int, \App\Models\ServerVariable> $serverVariables * @property-read \Illuminate\Database\Eloquent\Collection<int, \App\Models\ServerVariable> $serverVariables
@ -149,9 +148,9 @@ class Server extends Model
protected $guarded = ['id', self::CREATED_AT, self::UPDATED_AT, 'deleted_at', 'installed_at']; protected $guarded = ['id', self::CREATED_AT, self::UPDATED_AT, 'deleted_at', 'installed_at'];
public static array $validationRules = [ public static array $validationRules = [
'external_id' => 'sometimes|nullable|string|between:1,191|unique:servers', 'external_id' => 'sometimes|nullable|string|between:1,255|unique:servers',
'owner_id' => 'required|integer|exists:users,id', 'owner_id' => 'required|integer|exists:users,id',
'name' => 'required|string|min:1|max:191', 'name' => 'required|string|min:1|max:255',
'node_id' => 'required|exists:nodes,id', 'node_id' => 'required|exists:nodes,id',
'description' => 'string', 'description' => 'string',
'status' => 'nullable|string', 'status' => 'nullable|string',
@ -165,7 +164,7 @@ class Server extends Model
'egg_id' => 'required|exists:eggs,id', 'egg_id' => 'required|exists:eggs,id',
'startup' => 'required|string', 'startup' => 'required|string',
'skip_scripts' => 'sometimes|boolean', 'skip_scripts' => 'sometimes|boolean',
'image' => 'required|string|max:191', 'image' => 'required|string|max:255',
'database_limit' => 'present|nullable|integer|min:0', 'database_limit' => 'present|nullable|integer|min:0',
'allocation_limit' => 'sometimes|nullable|integer|min:0', 'allocation_limit' => 'sometimes|nullable|integer|min:0',
'backup_limit' => 'present|nullable|integer|min:0', 'backup_limit' => 'present|nullable|integer|min:0',
@ -439,7 +438,6 @@ class Server extends Model
return $this->status->color(); return $this->status->color();
} }
public function getPrimaryEndpoint(): ?Endpoint public function getPrimaryEndpoint(): ?Endpoint
{ {
$endpoint = $this->ports->first(); $endpoint = $this->ports->first();

View File

@ -21,7 +21,7 @@ class Setting extends Model
protected $fillable = ['key', 'value']; protected $fillable = ['key', 'value'];
public static array $validationRules = [ public static array $validationRules = [
'key' => 'required|string|between:1,191', 'key' => 'required|string|between:1,255',
'value' => 'string', 'value' => 'string',
]; ];

View File

@ -42,7 +42,7 @@ use App\Notifications\SendPasswordReset as ResetPasswordNotification;
* @property bool $use_totp * @property bool $use_totp
* @property string|null $totp_secret * @property string|null $totp_secret
* @property \Illuminate\Support\Carbon|null $totp_authenticated_at * @property \Illuminate\Support\Carbon|null $totp_authenticated_at
* @property array $oauth * @property array|null $oauth
* @property bool $gravatar * @property bool $gravatar
* @property \Illuminate\Support\Carbon|null $created_at * @property \Illuminate\Support\Carbon|null $created_at
* @property \Illuminate\Support\Carbon|null $updated_at * @property \Illuminate\Support\Carbon|null $updated_at
@ -123,6 +123,7 @@ class User extends Model implements AuthenticatableContract, AuthorizableContrac
'name_last', 'name_last',
'password', 'password',
'language', 'language',
'timezone',
'use_totp', 'use_totp',
'totp_secret', 'totp_secret',
'totp_authenticated_at', 'totp_authenticated_at',
@ -155,17 +156,17 @@ class User extends Model implements AuthenticatableContract, AuthorizableContrac
*/ */
public static array $validationRules = [ public static array $validationRules = [
'uuid' => 'nullable|string|size:36|unique:users,uuid', 'uuid' => 'nullable|string|size:36|unique:users,uuid',
'email' => 'required|email|between:1,191|unique:users,email', 'email' => 'required|email|between:1,255|unique:users,email',
'external_id' => 'sometimes|nullable|string|max:191|unique:users,external_id', 'external_id' => 'sometimes|nullable|string|max:255|unique:users,external_id',
'username' => 'required|between:1,191|unique:users,username', 'username' => 'required|between:1,255|unique:users,username',
'name_first' => 'nullable|string|between:0,191', 'name_first' => 'nullable|string|between:0,255',
'name_last' => 'nullable|string|between:0,191', 'name_last' => 'nullable|string|between:0,255',
'password' => 'sometimes|nullable|string', 'password' => 'sometimes|nullable|string',
'root_admin' => 'boolean', 'root_admin' => 'boolean',
'language' => 'string', 'language' => 'string',
'use_totp' => 'boolean', 'use_totp' => 'boolean',
'totp_secret' => 'nullable|string', 'totp_secret' => 'nullable|string',
'oauth' => 'array', 'oauth' => 'array|nullable',
]; ];
protected function casts(): array protected function casts(): array
@ -215,9 +216,9 @@ class User extends Model implements AuthenticatableContract, AuthorizableContrac
} }
/** /**
* Return the user model in a format that can be passed over to Vue templates. * Return the user model in a format that can be passed over to React templates.
*/ */
public function toVueObject(): array public function toReactObject(): array
{ {
return collect($this->toArray())->except(['id', 'external_id'])->toArray(); return collect($this->toArray())->except(['id', 'external_id'])->toArray();
} }

View File

@ -17,7 +17,6 @@ use Illuminate\Support\Facades\Broadcast;
use Illuminate\Support\Facades\Event; use Illuminate\Support\Facades\Event;
use Illuminate\Support\Facades\Gate; use Illuminate\Support\Facades\Gate;
use Illuminate\Support\Facades\Http; use Illuminate\Support\Facades\Http;
use Illuminate\Support\Facades\Schema;
use Illuminate\Support\Facades\URL; use Illuminate\Support\Facades\URL;
use Illuminate\Support\Facades\View; use Illuminate\Support\Facades\View;
use Illuminate\Support\ServiceProvider; use Illuminate\Support\ServiceProvider;
@ -32,8 +31,6 @@ class AppServiceProvider extends ServiceProvider
*/ */
public function boot(): void public function boot(): void
{ {
Schema::defaultStringLength(191);
$versionData = app(SoftwareVersionService::class)->versionData(); $versionData = app(SoftwareVersionService::class)->versionData();
View::share('appVersion', $versionData['version'] ?? 'undefined'); View::share('appVersion', $versionData['version'] ?? 'undefined');
View::share('appIsGit', $versionData['is_git'] ?? false); View::share('appIsGit', $versionData['is_git'] ?? false);

View File

@ -33,13 +33,13 @@ class HostCreationService
'host' => array_get($data, 'host'), 'host' => array_get($data, 'host'),
'port' => array_get($data, 'port'), 'port' => array_get($data, 'port'),
'username' => array_get($data, 'username'), 'username' => array_get($data, 'username'),
'max_databases' => null, 'max_databases' => array_get($data, 'max_databases'),
'node_id' => array_get($data, 'node_id'), 'node_id' => array_get($data, 'node_id'),
]); ]);
// Confirm access using the provided credentials before saving data. // Confirm access using the provided credentials before saving data.
$this->dynamic->set('dynamic', $host); $this->dynamic->set('dynamic', $host);
$this->databaseManager->connection('dynamic')->select('SELECT 1 FROM dual'); $this->databaseManager->connection('dynamic')->getPdo();
return $host; return $host;
}); });

View File

@ -24,18 +24,21 @@ class HostUpdateService
* *
* @throws \Throwable * @throws \Throwable
*/ */
public function handle(int $hostId, array $data): DatabaseHost public function handle(DatabaseHost|int $host, array $data): DatabaseHost
{ {
if (!$host instanceof DatabaseHost) {
$host = DatabaseHost::query()->findOrFail($host);
}
if (empty(array_get($data, 'password'))) { if (empty(array_get($data, 'password'))) {
unset($data['password']); unset($data['password']);
} }
return $this->connection->transaction(function () use ($data, $hostId) { return $this->connection->transaction(function () use ($data, $host) {
/** @var DatabaseHost $host */
$host = DatabaseHost::query()->findOrFail($hostId);
$host->update($data); $host->update($data);
$this->dynamic->set('dynamic', $host); $this->dynamic->set('dynamic', $host);
$this->databaseManager->connection('dynamic')->select('SELECT 1 FROM dual'); $this->databaseManager->connection('dynamic')->getPdo();
return $host; return $host;
}); });

View File

@ -164,7 +164,7 @@ class EggConfigurationService
// variable from the server configuration. // variable from the server configuration.
$plucked = Arr::get( $plucked = Arr::get(
$structure, $structure,
preg_replace('/^env\./', 'build.environment.', $key), preg_replace('/^env\./', 'environment.', $key),
'' ''
); );

View File

@ -33,7 +33,7 @@ trait EnvironmentWriterTrait
$saveContents = file_get_contents($path); $saveContents = file_get_contents($path);
collect($values)->each(function ($value, $key) use (&$saveContents) { collect($values)->each(function ($value, $key) use (&$saveContents) {
$key = strtoupper($key); $key = strtoupper($key);
$saveValue = sprintf('%s=%s', $key, $this->escapeEnvironmentValue($value)); $saveValue = sprintf('%s=%s', $key, $this->escapeEnvironmentValue($value ?? ''));
if (preg_match_all('/^' . $key . '=(.*)$/m', $saveContents) < 1) { if (preg_match_all('/^' . $key . '=(.*)$/m', $saveContents) < 1) {
$saveContents = $saveContents . PHP_EOL . $saveValue; $saveContents = $saveContents . PHP_EOL . $saveValue;

View File

@ -37,7 +37,8 @@ class UserTransformer extends BaseTransformer
'last_name' => $user->name_last, 'last_name' => $user->name_last,
'language' => $user->language, 'language' => $user->language,
'root_admin' => (bool) $user->root_admin, 'root_admin' => (bool) $user->root_admin,
'2fa' => (bool) $user->use_totp, '2fa_enabled' => (bool) $user->use_totp,
'2fa' => (bool) $user->use_totp, // deprecated, use "2fa_enabled"
'created_at' => $this->formatTimestamp($user->created_at), 'created_at' => $this->formatTimestamp($user->created_at),
'updated_at' => $this->formatTimestamp($user->updated_at), 'updated_at' => $this->formatTimestamp($user->updated_at),
]; ];

View File

@ -1,32 +0,0 @@
<?php
namespace App\Transformers\Api\Client;
use App\Models\User;
class AccountTransformer extends BaseClientTransformer
{
/**
* Return the resource name for the JSONAPI output.
*/
public function getResourceName(): string
{
return 'user';
}
/**
* Return basic information about the currently logged-in user.
*/
public function transform(User $model): array
{
return [
'id' => $model->id,
'admin' => $model->root_admin,
'username' => $model->username,
'email' => $model->email,
'first_name' => $model->name_first,
'last_name' => $model->name_last,
'language' => $model->language,
];
}
}

View File

@ -19,15 +19,21 @@ class UserTransformer extends BaseClientTransformer
* Transforms a User model into a representation that can be shown to regular * Transforms a User model into a representation that can be shown to regular
* users of the API. * users of the API.
*/ */
public function transform(User $model): array public function transform(User $user): array
{ {
return [ return [
'uuid' => $model->uuid, 'uuid' => $user->uuid,
'username' => $model->username, 'username' => $user->username,
'email' => $model->email, 'email' => $user->email,
'image' => 'https://gravatar.com/avatar/' . md5(Str::lower($model->email)), 'first_name' => $user->name_first,
'2fa_enabled' => $model->use_totp, 'last_name' => $user->name_last,
'created_at' => $model->created_at->toAtomString(), 'language' => $user->language,
'image' => 'https://gravatar.com/avatar/' . md5(Str::lower($user->email)), // deprecated
'admin' => (bool) $user->root_admin, // deprecated, use "root_admin"
'root_admin' => (bool) $user->root_admin,
'2fa_enabled' => (bool) $user->use_totp,
'created_at' => $this->formatTimestamp($user->created_at),
'updated_at' => $this->formatTimestamp($user->updated_at),
]; ];
} }
} }

View File

@ -0,0 +1,28 @@
<?php
use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;
return new class extends Migration
{
/**
* Run the migrations.
*/
public function up(): void
{
Schema::table('users', function (Blueprint $table) {
$table->string('timezone')->default('UTC')->after('language');
});
}
/**
* Reverse the migrations.
*/
public function down(): void
{
Schema::table('users', function (Blueprint $table) {
$table->dropColumn('timezone');
});
}
};

View File

@ -0,0 +1,289 @@
<?php
use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;
return new class extends Migration
{
/**
* Run the migrations.
*/
public function up(): void
{
Schema::table('activity_log_subjects', function (Blueprint $table) {
$table->string('subject_type')->change();
});
Schema::table('activity_logs', function (Blueprint $table) {
$table->string('event')->change();
$table->string('ip')->change();
$table->string('actor_type')->nullable()->default(null)->change();
});
Schema::table('allocations', function (Blueprint $table) {
$table->string('ip')->change();
$table->string('notes')->nullable()->default(null)->change();
});
Schema::table('audit_logs', function (Blueprint $table) {
$table->string('action')->change();
$table->string('subaction')->nullable()->default(null)->change();
});
Schema::table('backups', function (Blueprint $table) {
$table->string('name')->change();
$table->string('disk')->change();
$table->string('checksum')->nullable()->default(null)->change();
});
Schema::table('database_hosts', function (Blueprint $table) {
$table->string('name')->change();
$table->string('host')->change();
$table->string('username')->change();
});
Schema::table('databases', function (Blueprint $table) {
$table->string('database')->change();
$table->string('username')->change();
$table->string('remote')->default('%')->change();
});
Schema::table('egg_variables', function (Blueprint $table) {
$table->string('name')->change();
$table->string('env_variable')->change();
});
Schema::table('eggs', function (Blueprint $table) {
$table->string('author')->change();
$table->string('name')->change();
$table->string('config_stop')->nullable()->default(null)->change();
$table->string('script_container')->default('alpine:3.4')->change();
$table->string('script_entry')->default('ash')->change();
});
Schema::table('failed_jobs', function (Blueprint $table) {
$table->string('uuid')->nullable()->default(null)->change();
});
Schema::table('jobs', function (Blueprint $table) {
$table->string('queue')->change();
});
Schema::table('migrations', function (Blueprint $table) {
$table->string('migration')->change();
});
Schema::table('mounts', function (Blueprint $table) {
$table->string('name')->change();
$table->string('source')->change();
$table->string('target')->change();
});
Schema::table('nodes', function (Blueprint $table) {
$table->string('name')->change();
$table->string('fqdn')->change();
$table->string('scheme')->default('https')->change();
$table->string('daemon_sftp_alias')->nullable()->default(null)->change();
$table->string('daemon_base')->change();
});
Schema::table('notifications', function (Blueprint $table) {
$table->string('id')->change();
$table->string('type')->change();
$table->string('notifiable_type')->change();
});
Schema::table('password_resets', function (Blueprint $table) {
$table->string('email')->change();
$table->string('token')->change();
});
Schema::table('recovery_tokens', function (Blueprint $table) {
$table->string('token')->change();
});
Schema::table('schedules', function (Blueprint $table) {
$table->string('name')->change();
$table->string('cron_day_of_week')->change();
$table->string('cron_month')->change();
$table->string('cron_day_of_month')->change();
$table->string('cron_hour')->change();
$table->string('cron_minute')->change();
});
Schema::table('servers', function (Blueprint $table) {
$table->string('external_id')->nullable()->default(null)->change();
$table->string('name')->change();
$table->string('status')->nullable()->default(null)->change();
$table->string('threads')->nullable()->default(null)->change();
$table->string('image')->change();
});
Schema::table('sessions', function (Blueprint $table) {
$table->string('id')->change();
});
Schema::table('settings', function (Blueprint $table) {
$table->string('key')->change();
});
Schema::table('tasks', function (Blueprint $table) {
$table->string('action')->change();
});
Schema::table('user_ssh_keys', function (Blueprint $table) {
$table->string('name')->change();
$table->string('fingerprint')->change();
});
Schema::table('users', function (Blueprint $table) {
$table->string('external_id')->nullable()->default(null)->change();
$table->string('username')->change();
$table->string('email')->change();
$table->string('name_first')->nullable()->default(null)->change();
$table->string('name_last')->nullable()->default(null)->change();
$table->string('remember_token')->nullable()->default(null)->change();
});
}
/**
* Reverse the migrations.
*/
public function down(): void
{
Schema::table('activity_log_subjects', function (Blueprint $table) {
$table->string('subject_type', 191)->change();
});
Schema::table('activity_logs', function (Blueprint $table) {
$table->string('event', 191)->change();
$table->string('ip', 191)->change();
$table->string('actor_type', 191)->nullable()->default(null)->change();
});
Schema::table('allocations', function (Blueprint $table) {
$table->string('ip', 191)->change();
$table->string('notes', 191)->nullable()->default(null)->change();
});
Schema::table('audit_logs', function (Blueprint $table) {
$table->string('action', 191)->change();
$table->string('subaction', 191)->nullable()->default(null)->change();
});
Schema::table('backups', function (Blueprint $table) {
$table->string('name', 191)->change();
$table->string('disk', 191)->change();
$table->string('checksum', 191)->nullable()->default(null)->change();
});
Schema::table('database_hosts', function (Blueprint $table) {
$table->string('name', 191)->change();
$table->string('host', 191)->change();
$table->string('username', 191)->change();
});
Schema::table('databases', function (Blueprint $table) {
$table->string('database', 191)->change();
$table->string('username', 191)->change();
$table->string('remote', 191)->default('%', 191)->change();
});
Schema::table('egg_variables', function (Blueprint $table) {
$table->string('name', 191)->change();
$table->string('env_variable', 191)->change();
});
Schema::table('eggs', function (Blueprint $table) {
$table->string('author', 191)->change();
$table->string('name', 191)->change();
$table->string('config_stop', 191)->nullable()->default(null)->change();
$table->string('script_container', 191)->default('alpine:3.4', 191)->change();
$table->string('script_entry', 191)->default('ash', 191)->change();
});
Schema::table('failed_jobs', function (Blueprint $table) {
$table->string('uuid', 191)->nullable()->default(null)->change();
});
Schema::table('jobs', function (Blueprint $table) {
$table->string('queue', 191)->change();
});
Schema::table('migrations', function (Blueprint $table) {
$table->string('migration', 191)->change();
});
Schema::table('mounts', function (Blueprint $table) {
$table->string('name', 191)->change();
$table->string('source', 191)->change();
$table->string('target', 191)->change();
});
Schema::table('nodes', function (Blueprint $table) {
$table->string('name', 191)->change();
$table->string('fqdn', 191)->change();
$table->string('scheme', 191)->default('https', 191)->change();
$table->string('daemon_sftp_alias', 191)->nullable()->default(null)->change();
$table->string('daemon_base', 191)->change();
});
Schema::table('notifications', function (Blueprint $table) {
$table->string('id', 191)->change();
$table->string('type', 191)->change();
$table->string('notifiable_type', 191)->change();
});
Schema::table('password_resets', function (Blueprint $table) {
$table->string('email', 191)->change();
$table->string('token', 191)->change();
});
Schema::table('recovery_tokens', function (Blueprint $table) {
$table->string('token', 191)->change();
});
Schema::table('schedules', function (Blueprint $table) {
$table->string('name', 191)->change();
$table->string('cron_day_of_week', 191)->change();
$table->string('cron_month', 191)->change();
$table->string('cron_day_of_month', 191)->change();
$table->string('cron_hour', 191)->change();
$table->string('cron_minute', 191)->change();
});
Schema::table('servers', function (Blueprint $table) {
$table->string('external_id', 191)->nullable()->default(null)->change();
$table->string('name', 191)->change();
$table->string('status', 191)->nullable()->default(null)->change();
$table->string('threads', 191)->nullable()->default(null)->change();
$table->string('image', 191)->change();
});
Schema::table('sessions', function (Blueprint $table) {
$table->string('id', 191)->change();
});
Schema::table('settings', function (Blueprint $table) {
$table->string('key', 191)->change();
});
Schema::table('tasks', function (Blueprint $table) {
$table->string('action', 191)->change();
});
Schema::table('user_ssh_keys', function (Blueprint $table) {
$table->string('name', 191)->change();
$table->string('fingerprint', 191)->change();
});
Schema::table('users', function (Blueprint $table) {
$table->string('external_id', 191)->nullable()->default(null)->change();
$table->string('username', 191)->change();
$table->string('email', 191)->change();
$table->string('name_first', 191)->nullable()->default(null)->change();
$table->string('name_last', 191)->nullable()->default(null)->change();
$table->string('remember_token', 191)->nullable()->default(null)->change();
});
}
};

View File

@ -12,7 +12,7 @@ return new class extends Migration
public function up(): void public function up(): void
{ {
Schema::table('users', function (Blueprint $table) { Schema::table('users', function (Blueprint $table) {
$table->json('oauth')->after('totp_authenticated_at'); $table->json('oauth')->nullable()->after('totp_authenticated_at');
}); });
} }

View File

@ -10,7 +10,7 @@ DROP TABLE IF EXISTS `activity_log_subjects`;
CREATE TABLE `activity_log_subjects` ( CREATE TABLE `activity_log_subjects` (
`id` bigint unsigned NOT NULL AUTO_INCREMENT, `id` bigint unsigned NOT NULL AUTO_INCREMENT,
`activity_log_id` bigint unsigned NOT NULL, `activity_log_id` bigint unsigned NOT NULL,
`subject_type` varchar(191) COLLATE utf8mb4_unicode_ci NOT NULL, `subject_type` varchar(255) COLLATE utf8mb4_unicode_ci NOT NULL,
`subject_id` bigint unsigned NOT NULL, `subject_id` bigint unsigned NOT NULL,
PRIMARY KEY (`id`), PRIMARY KEY (`id`),
KEY `activity_log_subjects_activity_log_id_foreign` (`activity_log_id`), KEY `activity_log_subjects_activity_log_id_foreign` (`activity_log_id`),
@ -24,10 +24,10 @@ DROP TABLE IF EXISTS `activity_logs`;
CREATE TABLE `activity_logs` ( CREATE TABLE `activity_logs` (
`id` bigint unsigned NOT NULL AUTO_INCREMENT, `id` bigint unsigned NOT NULL AUTO_INCREMENT,
`batch` char(36) COLLATE utf8mb4_unicode_ci DEFAULT NULL, `batch` char(36) COLLATE utf8mb4_unicode_ci DEFAULT NULL,
`event` varchar(191) COLLATE utf8mb4_unicode_ci NOT NULL, `event` varchar(255) COLLATE utf8mb4_unicode_ci NOT NULL,
`ip` varchar(191) COLLATE utf8mb4_unicode_ci NOT NULL, `ip` varchar(255) COLLATE utf8mb4_unicode_ci NOT NULL,
`description` text COLLATE utf8mb4_unicode_ci, `description` text COLLATE utf8mb4_unicode_ci,
`actor_type` varchar(191) COLLATE utf8mb4_unicode_ci DEFAULT NULL, `actor_type` varchar(255) COLLATE utf8mb4_unicode_ci DEFAULT NULL,
`actor_id` bigint unsigned DEFAULT NULL, `actor_id` bigint unsigned DEFAULT NULL,
`api_key_id` int unsigned DEFAULT NULL, `api_key_id` int unsigned DEFAULT NULL,
`properties` json NOT NULL, `properties` json NOT NULL,
@ -43,11 +43,11 @@ DROP TABLE IF EXISTS `allocations`;
CREATE TABLE `allocations` ( CREATE TABLE `allocations` (
`id` int unsigned NOT NULL AUTO_INCREMENT, `id` int unsigned NOT NULL AUTO_INCREMENT,
`node_id` int unsigned NOT NULL, `node_id` int unsigned NOT NULL,
`ip` varchar(191) COLLATE utf8mb4_unicode_ci NOT NULL, `ip` varchar(255) COLLATE utf8mb4_unicode_ci NOT NULL,
`ip_alias` text COLLATE utf8mb4_unicode_ci, `ip_alias` text COLLATE utf8mb4_unicode_ci,
`port` mediumint unsigned NOT NULL, `port` mediumint unsigned NOT NULL,
`server_id` int unsigned DEFAULT NULL, `server_id` int unsigned DEFAULT NULL,
`notes` varchar(191) COLLATE utf8mb4_unicode_ci DEFAULT NULL, `notes` varchar(255) COLLATE utf8mb4_unicode_ci DEFAULT NULL,
`created_at` timestamp NULL DEFAULT NULL, `created_at` timestamp NULL DEFAULT NULL,
`updated_at` timestamp NULL DEFAULT NULL, `updated_at` timestamp NULL DEFAULT NULL,
PRIMARY KEY (`id`), PRIMARY KEY (`id`),
@ -65,7 +65,8 @@ CREATE TABLE `api_keys` (
`user_id` int unsigned NOT NULL, `user_id` int unsigned NOT NULL,
`key_type` tinyint unsigned NOT NULL DEFAULT '0', `key_type` tinyint unsigned NOT NULL DEFAULT '0',
`identifier` char(16) COLLATE utf8mb4_unicode_ci DEFAULT NULL, `identifier` char(16) COLLATE utf8mb4_unicode_ci DEFAULT NULL,
`token` text CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NOT NULL, `public` char(16) COLLATE utf8mb4_unicode_ci NOT NULL,
`token` text COLLATE utf8mb4_unicode_ci NOT NULL,
`allowed_ips` text COLLATE utf8mb4_unicode_ci, `allowed_ips` text COLLATE utf8mb4_unicode_ci,
`memo` text COLLATE utf8mb4_unicode_ci, `memo` text COLLATE utf8mb4_unicode_ci,
`last_used_at` timestamp NULL DEFAULT NULL, `last_used_at` timestamp NULL DEFAULT NULL,
@ -79,6 +80,7 @@ CREATE TABLE `api_keys` (
`r_eggs` tinyint unsigned NOT NULL DEFAULT '0', `r_eggs` tinyint unsigned NOT NULL DEFAULT '0',
`r_database_hosts` tinyint unsigned NOT NULL DEFAULT '0', `r_database_hosts` tinyint unsigned NOT NULL DEFAULT '0',
`r_server_databases` tinyint unsigned NOT NULL DEFAULT '0', `r_server_databases` tinyint unsigned NOT NULL DEFAULT '0',
`r_mounts` tinyint unsigned NOT NULL DEFAULT '0',
PRIMARY KEY (`id`), PRIMARY KEY (`id`),
UNIQUE KEY `api_keys_identifier_unique` (`identifier`), UNIQUE KEY `api_keys_identifier_unique` (`identifier`),
KEY `api_keys_user_id_foreign` (`user_id`), KEY `api_keys_user_id_foreign` (`user_id`),
@ -112,8 +114,8 @@ CREATE TABLE `audit_logs` (
`is_system` tinyint(1) NOT NULL DEFAULT '0', `is_system` tinyint(1) NOT NULL DEFAULT '0',
`user_id` int unsigned DEFAULT NULL, `user_id` int unsigned DEFAULT NULL,
`server_id` int unsigned DEFAULT NULL, `server_id` int unsigned DEFAULT NULL,
`action` varchar(191) COLLATE utf8mb4_unicode_ci NOT NULL, `action` varchar(255) COLLATE utf8mb4_unicode_ci NOT NULL,
`subaction` varchar(191) COLLATE utf8mb4_unicode_ci DEFAULT NULL, `subaction` varchar(255) COLLATE utf8mb4_unicode_ci DEFAULT NULL,
`device` json NOT NULL, `device` json NOT NULL,
`metadata` json NOT NULL, `metadata` json NOT NULL,
`created_at` timestamp NOT NULL, `created_at` timestamp NOT NULL,
@ -132,13 +134,13 @@ CREATE TABLE `backups` (
`id` bigint unsigned NOT NULL AUTO_INCREMENT, `id` bigint unsigned NOT NULL AUTO_INCREMENT,
`server_id` int unsigned NOT NULL, `server_id` int unsigned NOT NULL,
`uuid` char(36) COLLATE utf8mb4_unicode_ci NOT NULL, `uuid` char(36) COLLATE utf8mb4_unicode_ci NOT NULL,
`upload_id` text COLLATE utf8mb4_unicode_ci,
`is_successful` tinyint(1) NOT NULL DEFAULT '0', `is_successful` tinyint(1) NOT NULL DEFAULT '0',
`upload_id` text COLLATE utf8mb4_unicode_ci,
`is_locked` tinyint unsigned NOT NULL DEFAULT '0', `is_locked` tinyint unsigned NOT NULL DEFAULT '0',
`name` varchar(191) COLLATE utf8mb4_unicode_ci NOT NULL, `name` varchar(255) COLLATE utf8mb4_unicode_ci NOT NULL,
`ignored_files` text COLLATE utf8mb4_unicode_ci NOT NULL, `ignored_files` text COLLATE utf8mb4_unicode_ci NOT NULL,
`disk` varchar(191) COLLATE utf8mb4_unicode_ci NOT NULL, `disk` varchar(255) COLLATE utf8mb4_unicode_ci NOT NULL,
`checksum` varchar(191) COLLATE utf8mb4_unicode_ci DEFAULT NULL, `checksum` varchar(255) COLLATE utf8mb4_unicode_ci DEFAULT NULL,
`bytes` bigint unsigned NOT NULL DEFAULT '0', `bytes` bigint unsigned NOT NULL DEFAULT '0',
`completed_at` timestamp NULL DEFAULT NULL, `completed_at` timestamp NULL DEFAULT NULL,
`created_at` timestamp NULL DEFAULT NULL, `created_at` timestamp NULL DEFAULT NULL,
@ -155,10 +157,10 @@ DROP TABLE IF EXISTS `database_hosts`;
/*!50503 SET character_set_client = utf8mb4 */; /*!50503 SET character_set_client = utf8mb4 */;
CREATE TABLE `database_hosts` ( CREATE TABLE `database_hosts` (
`id` int unsigned NOT NULL AUTO_INCREMENT, `id` int unsigned NOT NULL AUTO_INCREMENT,
`name` varchar(191) COLLATE utf8mb4_unicode_ci NOT NULL, `name` varchar(255) COLLATE utf8mb4_unicode_ci NOT NULL,
`host` varchar(191) COLLATE utf8mb4_unicode_ci NOT NULL, `host` varchar(255) COLLATE utf8mb4_unicode_ci NOT NULL,
`port` int unsigned NOT NULL, `port` int unsigned NOT NULL,
`username` varchar(191) COLLATE utf8mb4_unicode_ci NOT NULL, `username` varchar(255) COLLATE utf8mb4_unicode_ci NOT NULL,
`password` text COLLATE utf8mb4_unicode_ci NOT NULL, `password` text COLLATE utf8mb4_unicode_ci NOT NULL,
`max_databases` int unsigned DEFAULT NULL, `max_databases` int unsigned DEFAULT NULL,
`node_id` int unsigned DEFAULT NULL, `node_id` int unsigned DEFAULT NULL,
@ -176,9 +178,9 @@ CREATE TABLE `databases` (
`id` int unsigned NOT NULL AUTO_INCREMENT, `id` int unsigned NOT NULL AUTO_INCREMENT,
`server_id` int unsigned NOT NULL, `server_id` int unsigned NOT NULL,
`database_host_id` int unsigned NOT NULL, `database_host_id` int unsigned NOT NULL,
`database` varchar(191) COLLATE utf8mb4_unicode_ci NOT NULL, `database` varchar(255) COLLATE utf8mb4_unicode_ci NOT NULL,
`username` varchar(191) COLLATE utf8mb4_unicode_ci NOT NULL, `username` varchar(255) COLLATE utf8mb4_unicode_ci NOT NULL,
`remote` varchar(191) COLLATE utf8mb4_unicode_ci NOT NULL DEFAULT '%', `remote` varchar(255) COLLATE utf8mb4_unicode_ci NOT NULL DEFAULT '%',
`password` text COLLATE utf8mb4_unicode_ci NOT NULL, `password` text COLLATE utf8mb4_unicode_ci NOT NULL,
`max_connections` int DEFAULT '0', `max_connections` int DEFAULT '0',
`created_at` timestamp NULL DEFAULT NULL, `created_at` timestamp NULL DEFAULT NULL,
@ -210,13 +212,13 @@ CREATE TABLE `egg_variables` (
`id` int unsigned NOT NULL AUTO_INCREMENT, `id` int unsigned NOT NULL AUTO_INCREMENT,
`egg_id` int unsigned NOT NULL, `egg_id` int unsigned NOT NULL,
`sort` tinyint unsigned DEFAULT NULL, `sort` tinyint unsigned DEFAULT NULL,
`name` varchar(191) COLLATE utf8mb4_unicode_ci NOT NULL, `name` varchar(255) COLLATE utf8mb4_unicode_ci NOT NULL,
`description` text COLLATE utf8mb4_unicode_ci NOT NULL, `description` text COLLATE utf8mb4_unicode_ci NOT NULL,
`env_variable` varchar(191) COLLATE utf8mb4_unicode_ci NOT NULL, `env_variable` varchar(255) COLLATE utf8mb4_unicode_ci NOT NULL,
`default_value` text CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NOT NULL, `default_value` text COLLATE utf8mb4_unicode_ci NOT NULL,
`user_viewable` tinyint unsigned NOT NULL, `user_viewable` tinyint unsigned NOT NULL,
`user_editable` tinyint unsigned NOT NULL, `user_editable` tinyint unsigned NOT NULL,
`rules` text COLLATE utf8mb4_unicode_ci, `rules` text COLLATE utf8mb4_unicode_ci NOT NULL,
`created_at` timestamp NULL DEFAULT NULL, `created_at` timestamp NULL DEFAULT NULL,
`updated_at` timestamp NULL DEFAULT NULL, `updated_at` timestamp NULL DEFAULT NULL,
PRIMARY KEY (`id`), PRIMARY KEY (`id`),
@ -230,9 +232,9 @@ DROP TABLE IF EXISTS `eggs`;
CREATE TABLE `eggs` ( CREATE TABLE `eggs` (
`id` int unsigned NOT NULL AUTO_INCREMENT, `id` int unsigned NOT NULL AUTO_INCREMENT,
`uuid` char(36) COLLATE utf8mb4_unicode_ci NOT NULL, `uuid` char(36) COLLATE utf8mb4_unicode_ci NOT NULL,
`author` varchar(191) COLLATE utf8mb4_unicode_ci NOT NULL, `author` varchar(255) COLLATE utf8mb4_unicode_ci NOT NULL,
`name` varchar(191) COLLATE utf8mb4_unicode_ci NOT NULL, `name` varchar(255) COLLATE utf8mb4_unicode_ci NOT NULL,
`description` text CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci, `description` text COLLATE utf8mb4_unicode_ci,
`features` json DEFAULT NULL, `features` json DEFAULT NULL,
`docker_images` json DEFAULT NULL, `docker_images` json DEFAULT NULL,
`file_denylist` json DEFAULT NULL, `file_denylist` json DEFAULT NULL,
@ -240,12 +242,12 @@ CREATE TABLE `eggs` (
`config_files` text COLLATE utf8mb4_unicode_ci, `config_files` text COLLATE utf8mb4_unicode_ci,
`config_startup` text COLLATE utf8mb4_unicode_ci, `config_startup` text COLLATE utf8mb4_unicode_ci,
`config_logs` text COLLATE utf8mb4_unicode_ci, `config_logs` text COLLATE utf8mb4_unicode_ci,
`config_stop` varchar(191) COLLATE utf8mb4_unicode_ci DEFAULT NULL, `config_stop` varchar(255) COLLATE utf8mb4_unicode_ci DEFAULT NULL,
`config_from` int unsigned DEFAULT NULL, `config_from` int unsigned DEFAULT NULL,
`startup` text COLLATE utf8mb4_unicode_ci, `startup` text COLLATE utf8mb4_unicode_ci,
`script_container` varchar(191) COLLATE utf8mb4_unicode_ci NOT NULL DEFAULT 'alpine:3.4', `script_container` varchar(255) COLLATE utf8mb4_unicode_ci NOT NULL DEFAULT 'alpine:3.4',
`copy_script_from` int unsigned DEFAULT NULL, `copy_script_from` int unsigned DEFAULT NULL,
`script_entry` varchar(191) COLLATE utf8mb4_unicode_ci NOT NULL DEFAULT 'ash', `script_entry` varchar(255) COLLATE utf8mb4_unicode_ci NOT NULL DEFAULT 'ash',
`script_is_privileged` tinyint(1) NOT NULL DEFAULT '1', `script_is_privileged` tinyint(1) NOT NULL DEFAULT '1',
`script_install` text COLLATE utf8mb4_unicode_ci, `script_install` text COLLATE utf8mb4_unicode_ci,
`created_at` timestamp NULL DEFAULT NULL, `created_at` timestamp NULL DEFAULT NULL,
@ -265,7 +267,7 @@ DROP TABLE IF EXISTS `failed_jobs`;
/*!50503 SET character_set_client = utf8mb4 */; /*!50503 SET character_set_client = utf8mb4 */;
CREATE TABLE `failed_jobs` ( CREATE TABLE `failed_jobs` (
`id` int unsigned NOT NULL AUTO_INCREMENT, `id` int unsigned NOT NULL AUTO_INCREMENT,
`uuid` varchar(191) COLLATE utf8mb4_unicode_ci DEFAULT NULL, `uuid` varchar(255) COLLATE utf8mb4_unicode_ci DEFAULT NULL,
`connection` text COLLATE utf8mb4_unicode_ci NOT NULL, `connection` text COLLATE utf8mb4_unicode_ci NOT NULL,
`queue` text COLLATE utf8mb4_unicode_ci NOT NULL, `queue` text COLLATE utf8mb4_unicode_ci NOT NULL,
`payload` longtext COLLATE utf8mb4_unicode_ci NOT NULL, `payload` longtext COLLATE utf8mb4_unicode_ci NOT NULL,
@ -280,7 +282,7 @@ DROP TABLE IF EXISTS `jobs`;
/*!50503 SET character_set_client = utf8mb4 */; /*!50503 SET character_set_client = utf8mb4 */;
CREATE TABLE `jobs` ( CREATE TABLE `jobs` (
`id` bigint unsigned NOT NULL AUTO_INCREMENT, `id` bigint unsigned NOT NULL AUTO_INCREMENT,
`queue` varchar(191) COLLATE utf8mb4_unicode_ci NOT NULL, `queue` varchar(255) COLLATE utf8mb4_unicode_ci NOT NULL,
`payload` longtext COLLATE utf8mb4_unicode_ci NOT NULL, `payload` longtext COLLATE utf8mb4_unicode_ci NOT NULL,
`attempts` tinyint unsigned NOT NULL, `attempts` tinyint unsigned NOT NULL,
`reserved_at` int unsigned DEFAULT NULL, `reserved_at` int unsigned DEFAULT NULL,
@ -295,7 +297,7 @@ DROP TABLE IF EXISTS `migrations`;
/*!50503 SET character_set_client = utf8mb4 */; /*!50503 SET character_set_client = utf8mb4 */;
CREATE TABLE `migrations` ( CREATE TABLE `migrations` (
`id` int unsigned NOT NULL AUTO_INCREMENT, `id` int unsigned NOT NULL AUTO_INCREMENT,
`migration` varchar(191) COLLATE utf8mb4_unicode_ci NOT NULL, `migration` varchar(255) COLLATE utf8mb4_unicode_ci NOT NULL,
`batch` int NOT NULL, `batch` int NOT NULL,
PRIMARY KEY (`id`) PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci; ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
@ -330,10 +332,10 @@ DROP TABLE IF EXISTS `mounts`;
CREATE TABLE `mounts` ( CREATE TABLE `mounts` (
`id` int unsigned NOT NULL AUTO_INCREMENT, `id` int unsigned NOT NULL AUTO_INCREMENT,
`uuid` char(36) COLLATE utf8mb4_unicode_ci NOT NULL, `uuid` char(36) COLLATE utf8mb4_unicode_ci NOT NULL,
`name` varchar(191) COLLATE utf8mb4_unicode_ci NOT NULL, `name` varchar(255) COLLATE utf8mb4_unicode_ci NOT NULL,
`description` text COLLATE utf8mb4_unicode_ci, `description` text COLLATE utf8mb4_unicode_ci,
`source` varchar(191) COLLATE utf8mb4_unicode_ci NOT NULL, `source` varchar(255) COLLATE utf8mb4_unicode_ci NOT NULL,
`target` varchar(191) COLLATE utf8mb4_unicode_ci NOT NULL, `target` varchar(255) COLLATE utf8mb4_unicode_ci NOT NULL,
`read_only` tinyint unsigned NOT NULL, `read_only` tinyint unsigned NOT NULL,
`user_mountable` tinyint unsigned NOT NULL, `user_mountable` tinyint unsigned NOT NULL,
PRIMARY KEY (`id`), PRIMARY KEY (`id`),
@ -349,10 +351,10 @@ CREATE TABLE `nodes` (
`id` int unsigned NOT NULL AUTO_INCREMENT, `id` int unsigned NOT NULL AUTO_INCREMENT,
`uuid` char(36) COLLATE utf8mb4_unicode_ci NOT NULL, `uuid` char(36) COLLATE utf8mb4_unicode_ci NOT NULL,
`public` smallint unsigned NOT NULL, `public` smallint unsigned NOT NULL,
`name` varchar(191) COLLATE utf8mb4_unicode_ci NOT NULL, `name` varchar(255) COLLATE utf8mb4_unicode_ci NOT NULL,
`description` text CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci, `description` text COLLATE utf8mb4_unicode_ci,
`fqdn` varchar(191) COLLATE utf8mb4_unicode_ci NOT NULL, `fqdn` varchar(255) COLLATE utf8mb4_unicode_ci NOT NULL,
`scheme` varchar(191) COLLATE utf8mb4_unicode_ci NOT NULL DEFAULT 'https', `scheme` varchar(255) COLLATE utf8mb4_unicode_ci NOT NULL DEFAULT 'https',
`behind_proxy` tinyint(1) NOT NULL DEFAULT '0', `behind_proxy` tinyint(1) NOT NULL DEFAULT '0',
`maintenance_mode` tinyint(1) NOT NULL DEFAULT '0', `maintenance_mode` tinyint(1) NOT NULL DEFAULT '0',
`memory` int unsigned NOT NULL, `memory` int unsigned NOT NULL,
@ -363,10 +365,11 @@ CREATE TABLE `nodes` (
`cpu_overallocate` int NOT NULL DEFAULT '0', `cpu_overallocate` int NOT NULL DEFAULT '0',
`upload_size` int unsigned NOT NULL DEFAULT '100', `upload_size` int unsigned NOT NULL DEFAULT '100',
`daemon_token_id` char(16) COLLATE utf8mb4_unicode_ci NOT NULL, `daemon_token_id` char(16) COLLATE utf8mb4_unicode_ci NOT NULL,
`daemon_token` text CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NOT NULL, `daemon_token` text COLLATE utf8mb4_unicode_ci NOT NULL,
`daemon_listen` smallint unsigned NOT NULL DEFAULT '8080', `daemon_listen` smallint unsigned NOT NULL DEFAULT '8080',
`daemon_sftp` smallint unsigned NOT NULL DEFAULT '2022', `daemon_sftp` smallint unsigned NOT NULL DEFAULT '2022',
`daemon_base` varchar(191) COLLATE utf8mb4_unicode_ci NOT NULL, `daemon_sftp_alias` varchar(255) COLLATE utf8mb4_unicode_ci DEFAULT NULL,
`daemon_base` varchar(255) COLLATE utf8mb4_unicode_ci NOT NULL,
`created_at` timestamp NULL DEFAULT NULL, `created_at` timestamp NULL DEFAULT NULL,
`updated_at` timestamp NULL DEFAULT NULL, `updated_at` timestamp NULL DEFAULT NULL,
`tags` text COLLATE utf8mb4_unicode_ci NOT NULL, `tags` text COLLATE utf8mb4_unicode_ci NOT NULL,
@ -379,9 +382,9 @@ DROP TABLE IF EXISTS `notifications`;
/*!40101 SET @saved_cs_client = @@character_set_client */; /*!40101 SET @saved_cs_client = @@character_set_client */;
/*!50503 SET character_set_client = utf8mb4 */; /*!50503 SET character_set_client = utf8mb4 */;
CREATE TABLE `notifications` ( CREATE TABLE `notifications` (
`id` varchar(191) COLLATE utf8mb4_unicode_ci NOT NULL, `id` varchar(255) COLLATE utf8mb4_unicode_ci NOT NULL,
`type` varchar(191) COLLATE utf8mb4_unicode_ci NOT NULL, `type` varchar(255) COLLATE utf8mb4_unicode_ci NOT NULL,
`notifiable_type` varchar(191) COLLATE utf8mb4_unicode_ci NOT NULL, `notifiable_type` varchar(255) COLLATE utf8mb4_unicode_ci NOT NULL,
`notifiable_id` bigint unsigned NOT NULL, `notifiable_id` bigint unsigned NOT NULL,
`data` text COLLATE utf8mb4_unicode_ci NOT NULL, `data` text COLLATE utf8mb4_unicode_ci NOT NULL,
`read_at` timestamp NULL DEFAULT NULL, `read_at` timestamp NULL DEFAULT NULL,
@ -395,8 +398,8 @@ DROP TABLE IF EXISTS `password_resets`;
/*!40101 SET @saved_cs_client = @@character_set_client */; /*!40101 SET @saved_cs_client = @@character_set_client */;
/*!50503 SET character_set_client = utf8mb4 */; /*!50503 SET character_set_client = utf8mb4 */;
CREATE TABLE `password_resets` ( CREATE TABLE `password_resets` (
`email` varchar(191) COLLATE utf8mb4_unicode_ci NOT NULL, `email` varchar(255) COLLATE utf8mb4_unicode_ci NOT NULL,
`token` varchar(191) COLLATE utf8mb4_unicode_ci NOT NULL, `token` varchar(255) COLLATE utf8mb4_unicode_ci NOT NULL,
`created_at` timestamp NOT NULL, `created_at` timestamp NOT NULL,
KEY `password_resets_email_index` (`email`), KEY `password_resets_email_index` (`email`),
KEY `password_resets_token_index` (`token`) KEY `password_resets_token_index` (`token`)
@ -408,7 +411,7 @@ DROP TABLE IF EXISTS `recovery_tokens`;
CREATE TABLE `recovery_tokens` ( CREATE TABLE `recovery_tokens` (
`id` bigint unsigned NOT NULL AUTO_INCREMENT, `id` bigint unsigned NOT NULL AUTO_INCREMENT,
`user_id` int unsigned NOT NULL, `user_id` int unsigned NOT NULL,
`token` varchar(191) COLLATE utf8mb4_unicode_ci NOT NULL, `token` varchar(255) COLLATE utf8mb4_unicode_ci NOT NULL,
`created_at` timestamp NULL DEFAULT NULL, `created_at` timestamp NULL DEFAULT NULL,
PRIMARY KEY (`id`), PRIMARY KEY (`id`),
KEY `recovery_tokens_user_id_foreign` (`user_id`), KEY `recovery_tokens_user_id_foreign` (`user_id`),
@ -421,12 +424,12 @@ DROP TABLE IF EXISTS `schedules`;
CREATE TABLE `schedules` ( CREATE TABLE `schedules` (
`id` int unsigned NOT NULL AUTO_INCREMENT, `id` int unsigned NOT NULL AUTO_INCREMENT,
`server_id` int unsigned NOT NULL, `server_id` int unsigned NOT NULL,
`name` varchar(191) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NOT NULL, `name` varchar(255) COLLATE utf8mb4_unicode_ci NOT NULL,
`cron_day_of_week` varchar(191) COLLATE utf8mb4_unicode_ci NOT NULL, `cron_day_of_week` varchar(255) COLLATE utf8mb4_unicode_ci NOT NULL,
`cron_month` varchar(191) COLLATE utf8mb4_unicode_ci NOT NULL, `cron_month` varchar(255) COLLATE utf8mb4_unicode_ci NOT NULL,
`cron_day_of_month` varchar(191) COLLATE utf8mb4_unicode_ci NOT NULL, `cron_day_of_month` varchar(255) COLLATE utf8mb4_unicode_ci NOT NULL,
`cron_hour` varchar(191) COLLATE utf8mb4_unicode_ci NOT NULL, `cron_hour` varchar(255) COLLATE utf8mb4_unicode_ci NOT NULL,
`cron_minute` varchar(191) COLLATE utf8mb4_unicode_ci NOT NULL, `cron_minute` varchar(255) COLLATE utf8mb4_unicode_ci NOT NULL,
`is_active` tinyint(1) NOT NULL, `is_active` tinyint(1) NOT NULL,
`is_processing` tinyint(1) NOT NULL, `is_processing` tinyint(1) NOT NULL,
`only_when_online` tinyint unsigned NOT NULL DEFAULT '0', `only_when_online` tinyint unsigned NOT NULL DEFAULT '0',
@ -465,9 +468,9 @@ DROP TABLE IF EXISTS `server_variables`;
/*!50503 SET character_set_client = utf8mb4 */; /*!50503 SET character_set_client = utf8mb4 */;
CREATE TABLE `server_variables` ( CREATE TABLE `server_variables` (
`id` int unsigned NOT NULL AUTO_INCREMENT, `id` int unsigned NOT NULL AUTO_INCREMENT,
`server_id` int unsigned DEFAULT NULL, `server_id` int unsigned NOT NULL,
`variable_id` int unsigned NOT NULL, `variable_id` int unsigned NOT NULL,
`variable_value` text CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NOT NULL, `variable_value` text COLLATE utf8mb4_unicode_ci NOT NULL,
`created_at` timestamp NULL DEFAULT NULL, `created_at` timestamp NULL DEFAULT NULL,
`updated_at` timestamp NULL DEFAULT NULL, `updated_at` timestamp NULL DEFAULT NULL,
PRIMARY KEY (`id`), PRIMARY KEY (`id`),
@ -482,13 +485,13 @@ DROP TABLE IF EXISTS `servers`;
/*!50503 SET character_set_client = utf8mb4 */; /*!50503 SET character_set_client = utf8mb4 */;
CREATE TABLE `servers` ( CREATE TABLE `servers` (
`id` int unsigned NOT NULL AUTO_INCREMENT, `id` int unsigned NOT NULL AUTO_INCREMENT,
`external_id` varchar(191) COLLATE utf8mb4_unicode_ci DEFAULT NULL, `external_id` varchar(255) COLLATE utf8mb4_unicode_ci DEFAULT NULL,
`uuid` char(36) COLLATE utf8mb4_unicode_ci NOT NULL, `uuid` char(36) COLLATE utf8mb4_unicode_ci NOT NULL,
`uuid_short` char(8) COLLATE utf8mb4_unicode_ci NOT NULL, `uuid_short` char(8) COLLATE utf8mb4_unicode_ci NOT NULL,
`node_id` int unsigned NOT NULL, `node_id` int unsigned NOT NULL,
`name` varchar(191) COLLATE utf8mb4_unicode_ci NOT NULL, `name` varchar(255) COLLATE utf8mb4_unicode_ci NOT NULL,
`description` text COLLATE utf8mb4_unicode_ci NOT NULL, `description` text COLLATE utf8mb4_unicode_ci NOT NULL,
`status` varchar(191) COLLATE utf8mb4_unicode_ci DEFAULT NULL, `status` varchar(255) COLLATE utf8mb4_unicode_ci DEFAULT NULL,
`skip_scripts` tinyint(1) NOT NULL DEFAULT '0', `skip_scripts` tinyint(1) NOT NULL DEFAULT '0',
`owner_id` int unsigned NOT NULL, `owner_id` int unsigned NOT NULL,
`memory` int unsigned NOT NULL, `memory` int unsigned NOT NULL,
@ -496,18 +499,19 @@ CREATE TABLE `servers` (
`disk` int unsigned NOT NULL, `disk` int unsigned NOT NULL,
`io` int unsigned NOT NULL, `io` int unsigned NOT NULL,
`cpu` int unsigned NOT NULL, `cpu` int unsigned NOT NULL,
`threads` varchar(191) COLLATE utf8mb4_unicode_ci DEFAULT NULL, `threads` varchar(255) COLLATE utf8mb4_unicode_ci DEFAULT NULL,
`oom_killer` tinyint unsigned NOT NULL DEFAULT '0', `oom_killer` tinyint unsigned NOT NULL DEFAULT '0',
`allocation_id` int unsigned NOT NULL, `allocation_id` int unsigned NOT NULL,
`egg_id` int unsigned NOT NULL, `egg_id` int unsigned NOT NULL,
`startup` text COLLATE utf8mb4_unicode_ci NOT NULL, `startup` text COLLATE utf8mb4_unicode_ci NOT NULL,
`image` varchar(191) COLLATE utf8mb4_unicode_ci NOT NULL, `image` varchar(255) COLLATE utf8mb4_unicode_ci NOT NULL,
`allocation_limit` int unsigned DEFAULT NULL, `allocation_limit` int unsigned DEFAULT NULL,
`database_limit` int unsigned DEFAULT '0', `database_limit` int unsigned DEFAULT '0',
`backup_limit` int unsigned NOT NULL DEFAULT '0', `backup_limit` int unsigned NOT NULL DEFAULT '0',
`created_at` timestamp NULL DEFAULT NULL, `created_at` timestamp NULL DEFAULT NULL,
`updated_at` timestamp NULL DEFAULT NULL, `updated_at` timestamp NULL DEFAULT NULL,
`installed_at` timestamp NULL DEFAULT NULL, `installed_at` timestamp NULL DEFAULT NULL,
`docker_labels` text COLLATE utf8mb4_unicode_ci,
PRIMARY KEY (`id`), PRIMARY KEY (`id`),
UNIQUE KEY `servers_uuid_unique` (`uuid`), UNIQUE KEY `servers_uuid_unique` (`uuid`),
UNIQUE KEY `servers_uuidshort_unique` (`uuid_short`), UNIQUE KEY `servers_uuidshort_unique` (`uuid_short`),
@ -526,7 +530,7 @@ DROP TABLE IF EXISTS `sessions`;
/*!40101 SET @saved_cs_client = @@character_set_client */; /*!40101 SET @saved_cs_client = @@character_set_client */;
/*!50503 SET character_set_client = utf8mb4 */; /*!50503 SET character_set_client = utf8mb4 */;
CREATE TABLE `sessions` ( CREATE TABLE `sessions` (
`id` varchar(191) COLLATE utf8mb4_unicode_ci NOT NULL, `id` varchar(255) COLLATE utf8mb4_unicode_ci NOT NULL,
`user_id` int DEFAULT NULL, `user_id` int DEFAULT NULL,
`ip_address` varchar(45) COLLATE utf8mb4_unicode_ci DEFAULT NULL, `ip_address` varchar(45) COLLATE utf8mb4_unicode_ci DEFAULT NULL,
`user_agent` text COLLATE utf8mb4_unicode_ci, `user_agent` text COLLATE utf8mb4_unicode_ci,
@ -540,10 +544,9 @@ DROP TABLE IF EXISTS `settings`;
/*!50503 SET character_set_client = utf8mb4 */; /*!50503 SET character_set_client = utf8mb4 */;
CREATE TABLE `settings` ( CREATE TABLE `settings` (
`id` int unsigned NOT NULL AUTO_INCREMENT, `id` int unsigned NOT NULL AUTO_INCREMENT,
`key` varchar(191) COLLATE utf8mb4_unicode_ci NOT NULL, `key` varchar(255) COLLATE utf8mb4_unicode_ci NOT NULL,
`value` text COLLATE utf8mb4_unicode_ci NOT NULL, `value` text COLLATE utf8mb4_unicode_ci NOT NULL,
PRIMARY KEY (`id`), PRIMARY KEY (`id`)
UNIQUE KEY `settings_key_unique` (`key`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci; ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
/*!40101 SET character_set_client = @saved_cs_client */; /*!40101 SET character_set_client = @saved_cs_client */;
DROP TABLE IF EXISTS `subusers`; DROP TABLE IF EXISTS `subusers`;
@ -570,7 +573,7 @@ CREATE TABLE `tasks` (
`id` int unsigned NOT NULL AUTO_INCREMENT, `id` int unsigned NOT NULL AUTO_INCREMENT,
`schedule_id` int unsigned NOT NULL, `schedule_id` int unsigned NOT NULL,
`sequence_id` int unsigned NOT NULL, `sequence_id` int unsigned NOT NULL,
`action` varchar(191) COLLATE utf8mb4_unicode_ci NOT NULL, `action` varchar(255) COLLATE utf8mb4_unicode_ci NOT NULL,
`payload` text COLLATE utf8mb4_unicode_ci NOT NULL, `payload` text COLLATE utf8mb4_unicode_ci NOT NULL,
`time_offset` int unsigned NOT NULL, `time_offset` int unsigned NOT NULL,
`is_queued` tinyint(1) NOT NULL, `is_queued` tinyint(1) NOT NULL,
@ -602,8 +605,8 @@ DROP TABLE IF EXISTS `user_ssh_keys`;
CREATE TABLE `user_ssh_keys` ( CREATE TABLE `user_ssh_keys` (
`id` int unsigned NOT NULL AUTO_INCREMENT, `id` int unsigned NOT NULL AUTO_INCREMENT,
`user_id` int unsigned NOT NULL, `user_id` int unsigned NOT NULL,
`name` varchar(191) COLLATE utf8mb4_unicode_ci NOT NULL, `name` varchar(255) COLLATE utf8mb4_unicode_ci NOT NULL,
`fingerprint` varchar(191) COLLATE utf8mb4_unicode_ci NOT NULL, `fingerprint` varchar(255) COLLATE utf8mb4_unicode_ci NOT NULL,
`public_key` text COLLATE utf8mb4_unicode_ci NOT NULL, `public_key` text COLLATE utf8mb4_unicode_ci NOT NULL,
`created_at` timestamp NULL DEFAULT NULL, `created_at` timestamp NULL DEFAULT NULL,
`updated_at` timestamp NULL DEFAULT NULL, `updated_at` timestamp NULL DEFAULT NULL,
@ -618,18 +621,18 @@ DROP TABLE IF EXISTS `users`;
/*!50503 SET character_set_client = utf8mb4 */; /*!50503 SET character_set_client = utf8mb4 */;
CREATE TABLE `users` ( CREATE TABLE `users` (
`id` int unsigned NOT NULL AUTO_INCREMENT, `id` int unsigned NOT NULL AUTO_INCREMENT,
`external_id` varchar(191) COLLATE utf8mb4_unicode_ci DEFAULT NULL, `external_id` varchar(255) COLLATE utf8mb4_unicode_ci DEFAULT NULL,
`uuid` char(36) COLLATE utf8mb4_unicode_ci NOT NULL, `uuid` char(36) COLLATE utf8mb4_unicode_ci NOT NULL,
`username` varchar(191) COLLATE utf8mb4_unicode_ci NOT NULL, `username` varchar(255) COLLATE utf8mb4_unicode_ci NOT NULL,
`email` varchar(191) COLLATE utf8mb4_unicode_ci NOT NULL, `email` varchar(255) COLLATE utf8mb4_unicode_ci NOT NULL,
`name_first` varchar(191) COLLATE utf8mb4_unicode_ci DEFAULT NULL, `name_first` varchar(255) COLLATE utf8mb4_unicode_ci DEFAULT NULL,
`name_last` varchar(191) COLLATE utf8mb4_unicode_ci DEFAULT NULL, `name_last` varchar(255) COLLATE utf8mb4_unicode_ci DEFAULT NULL,
`password` text COLLATE utf8mb4_unicode_ci NOT NULL, `password` text COLLATE utf8mb4_unicode_ci NOT NULL,
`remember_token` varchar(191) COLLATE utf8mb4_unicode_ci DEFAULT NULL, `remember_token` varchar(255) COLLATE utf8mb4_unicode_ci DEFAULT NULL,
`language` char(5) COLLATE utf8mb4_unicode_ci NOT NULL DEFAULT 'en', `language` char(5) COLLATE utf8mb4_unicode_ci NOT NULL DEFAULT 'en',
`root_admin` tinyint unsigned NOT NULL DEFAULT '0', `root_admin` tinyint unsigned NOT NULL DEFAULT '0',
`use_totp` tinyint unsigned NOT NULL, `use_totp` tinyint unsigned NOT NULL,
`totp_secret` text CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci, `totp_secret` text COLLATE utf8mb4_unicode_ci,
`totp_authenticated_at` timestamp NULL DEFAULT NULL, `totp_authenticated_at` timestamp NULL DEFAULT NULL,
`gravatar` tinyint(1) NOT NULL DEFAULT '1', `gravatar` tinyint(1) NOT NULL DEFAULT '1',
`created_at` timestamp NULL DEFAULT NULL, `created_at` timestamp NULL DEFAULT NULL,
@ -704,147 +707,153 @@ INSERT INTO `migrations` (`id`, `migration`, `batch`) VALUES (53,'2016_10_23_204
INSERT INTO `migrations` (`id`, `migration`, `batch`) VALUES (54,'2016_10_23_204321_add_foreign_service_variables',1); INSERT INTO `migrations` (`id`, `migration`, `batch`) VALUES (54,'2016_10_23_204321_add_foreign_service_variables',1);
INSERT INTO `migrations` (`id`, `migration`, `batch`) VALUES (55,'2016_10_23_204454_add_foreign_subusers',1); INSERT INTO `migrations` (`id`, `migration`, `batch`) VALUES (55,'2016_10_23_204454_add_foreign_subusers',1);
INSERT INTO `migrations` (`id`, `migration`, `batch`) VALUES (56,'2016_10_23_204610_add_foreign_tasks',1); INSERT INTO `migrations` (`id`, `migration`, `batch`) VALUES (56,'2016_10_23_204610_add_foreign_tasks',1);
INSERT INTO `migrations` (`id`, `migration`, `batch`) VALUES (57,'2016_11_04_000949_add_ark_service_option_fixed',1); INSERT INTO `migrations` (`id`, `migration`, `batch`) VALUES (57,'2016_11_11_220649_add_pack_support',1);
INSERT INTO `migrations` (`id`, `migration`, `batch`) VALUES (58,'2016_11_11_220649_add_pack_support',1); INSERT INTO `migrations` (`id`, `migration`, `batch`) VALUES (58,'2016_11_11_231731_set_service_name_unique',1);
INSERT INTO `migrations` (`id`, `migration`, `batch`) VALUES (59,'2016_11_11_231731_set_service_name_unique',1); INSERT INTO `migrations` (`id`, `migration`, `batch`) VALUES (59,'2016_11_27_142519_add_pack_column',1);
INSERT INTO `migrations` (`id`, `migration`, `batch`) VALUES (60,'2016_11_27_142519_add_pack_column',1); INSERT INTO `migrations` (`id`, `migration`, `batch`) VALUES (60,'2016_12_01_173018_add_configurable_upload_limit',1);
INSERT INTO `migrations` (`id`, `migration`, `batch`) VALUES (61,'2016_12_01_173018_add_configurable_upload_limit',1); INSERT INTO `migrations` (`id`, `migration`, `batch`) VALUES (61,'2016_12_02_185206_correct_service_variables',1);
INSERT INTO `migrations` (`id`, `migration`, `batch`) VALUES (62,'2016_12_02_185206_correct_service_variables',1); INSERT INTO `migrations` (`id`, `migration`, `batch`) VALUES (62,'2017_01_07_154228_create_node_configuration_tokens_table',1);
INSERT INTO `migrations` (`id`, `migration`, `batch`) VALUES (63,'2017_01_03_150436_fix_misnamed_option_tag',1); INSERT INTO `migrations` (`id`, `migration`, `batch`) VALUES (63,'2017_01_12_135449_add_more_user_data',1);
INSERT INTO `migrations` (`id`, `migration`, `batch`) VALUES (64,'2017_01_07_154228_create_node_configuration_tokens_table',1); INSERT INTO `migrations` (`id`, `migration`, `batch`) VALUES (64,'2017_02_02_175548_UpdateColumnNames',1);
INSERT INTO `migrations` (`id`, `migration`, `batch`) VALUES (65,'2017_01_12_135449_add_more_user_data',1); INSERT INTO `migrations` (`id`, `migration`, `batch`) VALUES (65,'2017_02_03_140948_UpdateNodesTable',1);
INSERT INTO `migrations` (`id`, `migration`, `batch`) VALUES (66,'2017_02_02_175548_UpdateColumnNames',1); INSERT INTO `migrations` (`id`, `migration`, `batch`) VALUES (66,'2017_02_03_155554_RenameColumns',1);
INSERT INTO `migrations` (`id`, `migration`, `batch`) VALUES (67,'2017_02_03_140948_UpdateNodesTable',1); INSERT INTO `migrations` (`id`, `migration`, `batch`) VALUES (67,'2017_02_05_164123_AdjustColumnNames',1);
INSERT INTO `migrations` (`id`, `migration`, `batch`) VALUES (68,'2017_02_03_155554_RenameColumns',1); INSERT INTO `migrations` (`id`, `migration`, `batch`) VALUES (68,'2017_02_05_164516_AdjustColumnNamesForServicePacks',1);
INSERT INTO `migrations` (`id`, `migration`, `batch`) VALUES (69,'2017_02_05_164123_AdjustColumnNames',1); INSERT INTO `migrations` (`id`, `migration`, `batch`) VALUES (69,'2017_02_09_174834_SetupPermissionsPivotTable',1);
INSERT INTO `migrations` (`id`, `migration`, `batch`) VALUES (70,'2017_02_05_164516_AdjustColumnNamesForServicePacks',1); INSERT INTO `migrations` (`id`, `migration`, `batch`) VALUES (70,'2017_02_10_171858_UpdateAPIKeyColumnNames',1);
INSERT INTO `migrations` (`id`, `migration`, `batch`) VALUES (71,'2017_02_09_174834_SetupPermissionsPivotTable',1); INSERT INTO `migrations` (`id`, `migration`, `batch`) VALUES (71,'2017_03_03_224254_UpdateNodeConfigTokensColumns',1);
INSERT INTO `migrations` (`id`, `migration`, `batch`) VALUES (72,'2017_02_10_171858_UpdateAPIKeyColumnNames',1); INSERT INTO `migrations` (`id`, `migration`, `batch`) VALUES (72,'2017_03_05_212803_DeleteServiceExecutableOption',1);
INSERT INTO `migrations` (`id`, `migration`, `batch`) VALUES (73,'2017_03_03_224254_UpdateNodeConfigTokensColumns',1); INSERT INTO `migrations` (`id`, `migration`, `batch`) VALUES (73,'2017_03_10_162934_AddNewServiceOptionsColumns',1);
INSERT INTO `migrations` (`id`, `migration`, `batch`) VALUES (74,'2017_03_05_212803_DeleteServiceExecutableOption',1); INSERT INTO `migrations` (`id`, `migration`, `batch`) VALUES (74,'2017_03_10_173607_MigrateToNewServiceSystem',1);
INSERT INTO `migrations` (`id`, `migration`, `batch`) VALUES (75,'2017_03_10_162934_AddNewServiceOptionsColumns',1); INSERT INTO `migrations` (`id`, `migration`, `batch`) VALUES (75,'2017_03_11_215455_ChangeServiceVariablesValidationRules',1);
INSERT INTO `migrations` (`id`, `migration`, `batch`) VALUES (76,'2017_03_10_173607_MigrateToNewServiceSystem',1); INSERT INTO `migrations` (`id`, `migration`, `batch`) VALUES (76,'2017_03_12_150648_MoveFunctionsFromFileToDatabase',1);
INSERT INTO `migrations` (`id`, `migration`, `batch`) VALUES (77,'2017_03_11_215455_ChangeServiceVariablesValidationRules',1); INSERT INTO `migrations` (`id`, `migration`, `batch`) VALUES (77,'2017_03_14_175631_RenameServicePacksToSingluarPacks',1);
INSERT INTO `migrations` (`id`, `migration`, `batch`) VALUES (78,'2017_03_12_150648_MoveFunctionsFromFileToDatabase',1); INSERT INTO `migrations` (`id`, `migration`, `batch`) VALUES (78,'2017_03_14_200326_AddLockedStatusToTable',1);
INSERT INTO `migrations` (`id`, `migration`, `batch`) VALUES (79,'2017_03_14_175631_RenameServicePacksToSingluarPacks',1); INSERT INTO `migrations` (`id`, `migration`, `batch`) VALUES (79,'2017_03_16_181109_ReOrganizeDatabaseServersToDatabaseHost',1);
INSERT INTO `migrations` (`id`, `migration`, `batch`) VALUES (80,'2017_03_14_200326_AddLockedStatusToTable',1); INSERT INTO `migrations` (`id`, `migration`, `batch`) VALUES (80,'2017_03_16_181515_CleanupDatabasesDatabase',1);
INSERT INTO `migrations` (`id`, `migration`, `batch`) VALUES (81,'2017_03_16_181109_ReOrganizeDatabaseServersToDatabaseHost',1); INSERT INTO `migrations` (`id`, `migration`, `batch`) VALUES (81,'2017_03_18_204953_AddForeignKeyToPacks',1);
INSERT INTO `migrations` (`id`, `migration`, `batch`) VALUES (82,'2017_03_16_181515_CleanupDatabasesDatabase',1); INSERT INTO `migrations` (`id`, `migration`, `batch`) VALUES (82,'2017_03_31_221948_AddServerDescriptionColumn',1);
INSERT INTO `migrations` (`id`, `migration`, `batch`) VALUES (83,'2017_03_18_204953_AddForeignKeyToPacks',1); INSERT INTO `migrations` (`id`, `migration`, `batch`) VALUES (83,'2017_04_02_163232_DropDeletedAtColumnFromServers',1);
INSERT INTO `migrations` (`id`, `migration`, `batch`) VALUES (84,'2017_03_31_221948_AddServerDescriptionColumn',1); INSERT INTO `migrations` (`id`, `migration`, `batch`) VALUES (84,'2017_04_15_125021_UpgradeTaskSystem',1);
INSERT INTO `migrations` (`id`, `migration`, `batch`) VALUES (85,'2017_04_02_163232_DropDeletedAtColumnFromServers',1); INSERT INTO `migrations` (`id`, `migration`, `batch`) VALUES (85,'2017_04_20_171943_AddScriptsToServiceOptions',1);
INSERT INTO `migrations` (`id`, `migration`, `batch`) VALUES (86,'2017_04_15_125021_UpgradeTaskSystem',1); INSERT INTO `migrations` (`id`, `migration`, `batch`) VALUES (86,'2017_04_21_151432_AddServiceScriptTrackingToServers',1);
INSERT INTO `migrations` (`id`, `migration`, `batch`) VALUES (87,'2017_04_20_171943_AddScriptsToServiceOptions',1); INSERT INTO `migrations` (`id`, `migration`, `batch`) VALUES (87,'2017_04_27_145300_AddCopyScriptFromColumn',1);
INSERT INTO `migrations` (`id`, `migration`, `batch`) VALUES (88,'2017_04_21_151432_AddServiceScriptTrackingToServers',1); INSERT INTO `migrations` (`id`, `migration`, `batch`) VALUES (88,'2017_04_27_223629_AddAbilityToDefineConnectionOverSSLWithDaemonBehindProxy',1);
INSERT INTO `migrations` (`id`, `migration`, `batch`) VALUES (89,'2017_04_27_145300_AddCopyScriptFromColumn',1); INSERT INTO `migrations` (`id`, `migration`, `batch`) VALUES (89,'2017_05_01_141528_DeleteDownloadTable',1);
INSERT INTO `migrations` (`id`, `migration`, `batch`) VALUES (90,'2017_04_27_223629_AddAbilityToDefineConnectionOverSSLWithDaemonBehindProxy',1); INSERT INTO `migrations` (`id`, `migration`, `batch`) VALUES (90,'2017_05_01_141559_DeleteNodeConfigurationTable',1);
INSERT INTO `migrations` (`id`, `migration`, `batch`) VALUES (91,'2017_05_01_141528_DeleteDownloadTable',1); INSERT INTO `migrations` (`id`, `migration`, `batch`) VALUES (91,'2017_06_10_152951_add_external_id_to_users',1);
INSERT INTO `migrations` (`id`, `migration`, `batch`) VALUES (92,'2017_05_01_141559_DeleteNodeConfigurationTable',1); INSERT INTO `migrations` (`id`, `migration`, `batch`) VALUES (92,'2017_06_25_133923_ChangeForeignKeyToBeOnCascadeDelete',1);
INSERT INTO `migrations` (`id`, `migration`, `batch`) VALUES (93,'2017_06_10_152951_add_external_id_to_users',1); INSERT INTO `migrations` (`id`, `migration`, `batch`) VALUES (93,'2017_07_08_152806_ChangeUserPermissionsToDeleteOnUserDeletion',1);
INSERT INTO `migrations` (`id`, `migration`, `batch`) VALUES (94,'2017_06_25_133923_ChangeForeignKeyToBeOnCascadeDelete',1); INSERT INTO `migrations` (`id`, `migration`, `batch`) VALUES (94,'2017_07_08_154416_SetAllocationToReferenceNullOnServerDelete',1);
INSERT INTO `migrations` (`id`, `migration`, `batch`) VALUES (95,'2017_07_08_152806_ChangeUserPermissionsToDeleteOnUserDeletion',1); INSERT INTO `migrations` (`id`, `migration`, `batch`) VALUES (95,'2017_07_08_154650_CascadeDeletionWhenAServerOrVariableIsDeleted',1);
INSERT INTO `migrations` (`id`, `migration`, `batch`) VALUES (96,'2017_07_08_154416_SetAllocationToReferenceNullOnServerDelete',1); INSERT INTO `migrations` (`id`, `migration`, `batch`) VALUES (96,'2017_07_24_194433_DeleteTaskWhenParentServerIsDeleted',1);
INSERT INTO `migrations` (`id`, `migration`, `batch`) VALUES (97,'2017_07_08_154650_CascadeDeletionWhenAServerOrVariableIsDeleted',1); INSERT INTO `migrations` (`id`, `migration`, `batch`) VALUES (97,'2017_08_05_115800_CascadeNullValuesForDatabaseHostWhenNodeIsDeleted',1);
INSERT INTO `migrations` (`id`, `migration`, `batch`) VALUES (98,'2017_07_24_194433_DeleteTaskWhenParentServerIsDeleted',1); INSERT INTO `migrations` (`id`, `migration`, `batch`) VALUES (98,'2017_08_05_144104_AllowNegativeValuesForOverallocation',1);
INSERT INTO `migrations` (`id`, `migration`, `batch`) VALUES (99,'2017_08_05_115800_CascadeNullValuesForDatabaseHostWhenNodeIsDeleted',1); INSERT INTO `migrations` (`id`, `migration`, `batch`) VALUES (99,'2017_08_05_174811_SetAllocationUnqiueUsingMultipleFields',1);
INSERT INTO `migrations` (`id`, `migration`, `batch`) VALUES (100,'2017_08_05_144104_AllowNegativeValuesForOverallocation',1); INSERT INTO `migrations` (`id`, `migration`, `batch`) VALUES (100,'2017_08_15_214555_CascadeDeletionWhenAParentServiceIsDeleted',1);
INSERT INTO `migrations` (`id`, `migration`, `batch`) VALUES (101,'2017_08_05_174811_SetAllocationUnqiueUsingMultipleFields',1); INSERT INTO `migrations` (`id`, `migration`, `batch`) VALUES (101,'2017_08_18_215428_RemovePackWhenParentServiceOptionIsDeleted',1);
INSERT INTO `migrations` (`id`, `migration`, `batch`) VALUES (102,'2017_08_15_214555_CascadeDeletionWhenAParentServiceIsDeleted',1); INSERT INTO `migrations` (`id`, `migration`, `batch`) VALUES (102,'2017_09_10_225749_RenameTasksTableForStructureRefactor',1);
INSERT INTO `migrations` (`id`, `migration`, `batch`) VALUES (103,'2017_08_18_215428_RemovePackWhenParentServiceOptionIsDeleted',1); INSERT INTO `migrations` (`id`, `migration`, `batch`) VALUES (103,'2017_09_10_225941_CreateSchedulesTable',1);
INSERT INTO `migrations` (`id`, `migration`, `batch`) VALUES (104,'2017_09_10_225749_RenameTasksTableForStructureRefactor',1); INSERT INTO `migrations` (`id`, `migration`, `batch`) VALUES (104,'2017_09_10_230309_CreateNewTasksTableForSchedules',1);
INSERT INTO `migrations` (`id`, `migration`, `batch`) VALUES (105,'2017_09_10_225941_CreateSchedulesTable',1); INSERT INTO `migrations` (`id`, `migration`, `batch`) VALUES (105,'2017_09_11_002938_TransferOldTasksToNewScheduler',1);
INSERT INTO `migrations` (`id`, `migration`, `batch`) VALUES (106,'2017_09_10_230309_CreateNewTasksTableForSchedules',1); INSERT INTO `migrations` (`id`, `migration`, `batch`) VALUES (106,'2017_09_13_211810_UpdateOldPermissionsToPointToNewScheduleSystem',1);
INSERT INTO `migrations` (`id`, `migration`, `batch`) VALUES (107,'2017_09_11_002938_TransferOldTasksToNewScheduler',1); INSERT INTO `migrations` (`id`, `migration`, `batch`) VALUES (107,'2017_09_23_170933_CreateDaemonKeysTable',1);
INSERT INTO `migrations` (`id`, `migration`, `batch`) VALUES (108,'2017_09_13_211810_UpdateOldPermissionsToPointToNewScheduleSystem',1); INSERT INTO `migrations` (`id`, `migration`, `batch`) VALUES (108,'2017_09_23_173628_RemoveDaemonSecretFromServersTable',1);
INSERT INTO `migrations` (`id`, `migration`, `batch`) VALUES (109,'2017_09_23_170933_CreateDaemonKeysTable',1); INSERT INTO `migrations` (`id`, `migration`, `batch`) VALUES (109,'2017_09_23_185022_RemoveDaemonSecretFromSubusersTable',1);
INSERT INTO `migrations` (`id`, `migration`, `batch`) VALUES (110,'2017_09_23_173628_RemoveDaemonSecretFromServersTable',1); INSERT INTO `migrations` (`id`, `migration`, `batch`) VALUES (110,'2017_10_02_202000_ChangeServicesToUseAMoreUniqueIdentifier',1);
INSERT INTO `migrations` (`id`, `migration`, `batch`) VALUES (111,'2017_09_23_185022_RemoveDaemonSecretFromSubusersTable',1); INSERT INTO `migrations` (`id`, `migration`, `batch`) VALUES (111,'2017_10_02_202007_ChangeToABetterUniqueServiceConfiguration',1);
INSERT INTO `migrations` (`id`, `migration`, `batch`) VALUES (112,'2017_10_02_202000_ChangeServicesToUseAMoreUniqueIdentifier',1); INSERT INTO `migrations` (`id`, `migration`, `batch`) VALUES (112,'2017_10_03_233202_CascadeDeletionWhenServiceOptionIsDeleted',1);
INSERT INTO `migrations` (`id`, `migration`, `batch`) VALUES (113,'2017_10_02_202007_ChangeToABetterUniqueServiceConfiguration',1); INSERT INTO `migrations` (`id`, `migration`, `batch`) VALUES (113,'2017_10_06_214026_ServicesToNestsConversion',1);
INSERT INTO `migrations` (`id`, `migration`, `batch`) VALUES (114,'2017_10_03_233202_CascadeDeletionWhenServiceOptionIsDeleted',1); INSERT INTO `migrations` (`id`, `migration`, `batch`) VALUES (114,'2017_10_06_214053_ServiceOptionsToEggsConversion',1);
INSERT INTO `migrations` (`id`, `migration`, `batch`) VALUES (115,'2017_10_06_214026_ServicesToNestsConversion',1); INSERT INTO `migrations` (`id`, `migration`, `batch`) VALUES (115,'2017_10_06_215741_ServiceVariablesToEggVariablesConversion',1);
INSERT INTO `migrations` (`id`, `migration`, `batch`) VALUES (116,'2017_10_06_214053_ServiceOptionsToEggsConversion',1); INSERT INTO `migrations` (`id`, `migration`, `batch`) VALUES (116,'2017_10_24_222238_RemoveLegacySFTPInformation',1);
INSERT INTO `migrations` (`id`, `migration`, `batch`) VALUES (117,'2017_10_06_215741_ServiceVariablesToEggVariablesConversion',1); INSERT INTO `migrations` (`id`, `migration`, `batch`) VALUES (117,'2017_11_11_161922_Add2FaLastAuthorizationTimeColumn',1);
INSERT INTO `migrations` (`id`, `migration`, `batch`) VALUES (118,'2017_10_24_222238_RemoveLegacySFTPInformation',1); INSERT INTO `migrations` (`id`, `migration`, `batch`) VALUES (118,'2017_11_19_122708_MigratePubPrivFormatToSingleKey',1);
INSERT INTO `migrations` (`id`, `migration`, `batch`) VALUES (119,'2017_11_11_161922_Add2FaLastAuthorizationTimeColumn',1); INSERT INTO `migrations` (`id`, `migration`, `batch`) VALUES (119,'2017_12_04_184012_DropAllocationsWhenNodeIsDeleted',1);
INSERT INTO `migrations` (`id`, `migration`, `batch`) VALUES (120,'2017_11_19_122708_MigratePubPrivFormatToSingleKey',1); INSERT INTO `migrations` (`id`, `migration`, `batch`) VALUES (120,'2017_12_12_220426_MigrateSettingsTableToNewFormat',1);
INSERT INTO `migrations` (`id`, `migration`, `batch`) VALUES (121,'2017_12_04_184012_DropAllocationsWhenNodeIsDeleted',1); INSERT INTO `migrations` (`id`, `migration`, `batch`) VALUES (121,'2018_01_01_122821_AllowNegativeValuesForServerSwap',1);
INSERT INTO `migrations` (`id`, `migration`, `batch`) VALUES (122,'2017_12_12_220426_MigrateSettingsTableToNewFormat',1); INSERT INTO `migrations` (`id`, `migration`, `batch`) VALUES (122,'2018_01_11_213943_AddApiKeyPermissionColumns',1);
INSERT INTO `migrations` (`id`, `migration`, `batch`) VALUES (123,'2018_01_01_122821_AllowNegativeValuesForServerSwap',1); INSERT INTO `migrations` (`id`, `migration`, `batch`) VALUES (123,'2018_01_13_142012_SetupTableForKeyEncryption',1);
INSERT INTO `migrations` (`id`, `migration`, `batch`) VALUES (124,'2018_01_11_213943_AddApiKeyPermissionColumns',1); INSERT INTO `migrations` (`id`, `migration`, `batch`) VALUES (124,'2018_01_13_145209_AddLastUsedAtColumn',1);
INSERT INTO `migrations` (`id`, `migration`, `batch`) VALUES (125,'2018_01_13_142012_SetupTableForKeyEncryption',1); INSERT INTO `migrations` (`id`, `migration`, `batch`) VALUES (125,'2018_02_04_145617_AllowTextInUserExternalId',1);
INSERT INTO `migrations` (`id`, `migration`, `batch`) VALUES (126,'2018_01_13_145209_AddLastUsedAtColumn',1); INSERT INTO `migrations` (`id`, `migration`, `batch`) VALUES (126,'2018_02_10_151150_remove_unique_index_on_external_id_column',1);
INSERT INTO `migrations` (`id`, `migration`, `batch`) VALUES (127,'2018_02_04_145617_AllowTextInUserExternalId',1); INSERT INTO `migrations` (`id`, `migration`, `batch`) VALUES (127,'2018_02_17_134254_ensure_unique_allocation_id_on_servers_table',1);
INSERT INTO `migrations` (`id`, `migration`, `batch`) VALUES (128,'2018_02_10_151150_remove_unique_index_on_external_id_column',1); INSERT INTO `migrations` (`id`, `migration`, `batch`) VALUES (128,'2018_02_24_112356_add_external_id_column_to_servers_table',1);
INSERT INTO `migrations` (`id`, `migration`, `batch`) VALUES (129,'2018_02_17_134254_ensure_unique_allocation_id_on_servers_table',1); INSERT INTO `migrations` (`id`, `migration`, `batch`) VALUES (129,'2018_02_25_160152_remove_default_null_value_on_table',1);
INSERT INTO `migrations` (`id`, `migration`, `batch`) VALUES (130,'2018_02_24_112356_add_external_id_column_to_servers_table',1); INSERT INTO `migrations` (`id`, `migration`, `batch`) VALUES (130,'2018_02_25_160604_define_unique_index_on_users_external_id',1);
INSERT INTO `migrations` (`id`, `migration`, `batch`) VALUES (131,'2018_02_25_160152_remove_default_null_value_on_table',1); INSERT INTO `migrations` (`id`, `migration`, `batch`) VALUES (131,'2018_03_01_192831_add_database_and_port_limit_columns_to_servers_table',1);
INSERT INTO `migrations` (`id`, `migration`, `batch`) VALUES (132,'2018_02_25_160604_define_unique_index_on_users_external_id',1); INSERT INTO `migrations` (`id`, `migration`, `batch`) VALUES (132,'2018_03_15_124536_add_description_to_nodes',1);
INSERT INTO `migrations` (`id`, `migration`, `batch`) VALUES (133,'2018_03_01_192831_add_database_and_port_limit_columns_to_servers_table',1); INSERT INTO `migrations` (`id`, `migration`, `batch`) VALUES (133,'2018_05_04_123826_add_maintenance_to_nodes',1);
INSERT INTO `migrations` (`id`, `migration`, `batch`) VALUES (134,'2018_03_15_124536_add_description_to_nodes',1); INSERT INTO `migrations` (`id`, `migration`, `batch`) VALUES (134,'2018_09_03_143756_allow_egg_variables_to_have_longer_values',1);
INSERT INTO `migrations` (`id`, `migration`, `batch`) VALUES (135,'2018_05_04_123826_add_maintenance_to_nodes',1); INSERT INTO `migrations` (`id`, `migration`, `batch`) VALUES (135,'2018_09_03_144005_allow_server_variables_to_have_longer_values',1);
INSERT INTO `migrations` (`id`, `migration`, `batch`) VALUES (136,'2018_09_03_143756_allow_egg_variables_to_have_longer_values',1); INSERT INTO `migrations` (`id`, `migration`, `batch`) VALUES (136,'2019_03_02_142328_set_allocation_limit_default_null',1);
INSERT INTO `migrations` (`id`, `migration`, `batch`) VALUES (137,'2018_09_03_144005_allow_server_variables_to_have_longer_values',1); INSERT INTO `migrations` (`id`, `migration`, `batch`) VALUES (137,'2019_03_02_151321_fix_unique_index_to_account_for_host',1);
INSERT INTO `migrations` (`id`, `migration`, `batch`) VALUES (138,'2019_03_02_142328_set_allocation_limit_default_null',1); INSERT INTO `migrations` (`id`, `migration`, `batch`) VALUES (138,'2020_03_22_163911_merge_permissions_table_into_subusers',1);
INSERT INTO `migrations` (`id`, `migration`, `batch`) VALUES (139,'2019_03_02_151321_fix_unique_index_to_account_for_host',1); INSERT INTO `migrations` (`id`, `migration`, `batch`) VALUES (139,'2020_03_22_164814_drop_permissions_table',1);
INSERT INTO `migrations` (`id`, `migration`, `batch`) VALUES (140,'2020_03_22_163911_merge_permissions_table_into_subusers',1); INSERT INTO `migrations` (`id`, `migration`, `batch`) VALUES (140,'2020_04_03_203624_add_threads_column_to_servers_table',1);
INSERT INTO `migrations` (`id`, `migration`, `batch`) VALUES (141,'2020_03_22_164814_drop_permissions_table',1); INSERT INTO `migrations` (`id`, `migration`, `batch`) VALUES (141,'2020_04_03_230614_create_backups_table',1);
INSERT INTO `migrations` (`id`, `migration`, `batch`) VALUES (142,'2020_04_03_203624_add_threads_column_to_servers_table',1); INSERT INTO `migrations` (`id`, `migration`, `batch`) VALUES (142,'2020_04_04_131016_add_table_server_transfers',1);
INSERT INTO `migrations` (`id`, `migration`, `batch`) VALUES (143,'2020_04_03_230614_create_backups_table',1); INSERT INTO `migrations` (`id`, `migration`, `batch`) VALUES (143,'2020_04_10_141024_store_node_tokens_as_encrypted_value',1);
INSERT INTO `migrations` (`id`, `migration`, `batch`) VALUES (144,'2020_04_04_131016_add_table_server_transfers',1); INSERT INTO `migrations` (`id`, `migration`, `batch`) VALUES (144,'2020_04_17_203438_allow_nullable_descriptions',1);
INSERT INTO `migrations` (`id`, `migration`, `batch`) VALUES (145,'2020_04_10_141024_store_node_tokens_as_encrypted_value',1); INSERT INTO `migrations` (`id`, `migration`, `batch`) VALUES (145,'2020_04_22_055500_add_max_connections_column',1);
INSERT INTO `migrations` (`id`, `migration`, `batch`) VALUES (146,'2020_04_17_203438_allow_nullable_descriptions',1); INSERT INTO `migrations` (`id`, `migration`, `batch`) VALUES (146,'2020_04_26_111208_add_backup_limit_to_servers',1);
INSERT INTO `migrations` (`id`, `migration`, `batch`) VALUES (147,'2020_04_22_055500_add_max_connections_column',1); INSERT INTO `migrations` (`id`, `migration`, `batch`) VALUES (147,'2020_05_20_234655_add_mounts_table',1);
INSERT INTO `migrations` (`id`, `migration`, `batch`) VALUES (148,'2020_04_26_111208_add_backup_limit_to_servers',1); INSERT INTO `migrations` (`id`, `migration`, `batch`) VALUES (148,'2020_05_21_192756_add_mount_server_table',1);
INSERT INTO `migrations` (`id`, `migration`, `batch`) VALUES (149,'2020_05_20_234655_add_mounts_table',1); INSERT INTO `migrations` (`id`, `migration`, `batch`) VALUES (149,'2020_07_02_213612_create_user_recovery_tokens_table',1);
INSERT INTO `migrations` (`id`, `migration`, `batch`) VALUES (150,'2020_05_21_192756_add_mount_server_table',1); INSERT INTO `migrations` (`id`, `migration`, `batch`) VALUES (150,'2020_07_09_201845_add_notes_column_for_allocations',1);
INSERT INTO `migrations` (`id`, `migration`, `batch`) VALUES (151,'2020_07_02_213612_create_user_recovery_tokens_table',1); INSERT INTO `migrations` (`id`, `migration`, `batch`) VALUES (151,'2020_08_20_205533_add_backup_state_column_to_backups',1);
INSERT INTO `migrations` (`id`, `migration`, `batch`) VALUES (152,'2020_07_09_201845_add_notes_column_for_allocations',1); INSERT INTO `migrations` (`id`, `migration`, `batch`) VALUES (152,'2020_08_22_132500_update_bytes_to_unsigned_bigint',1);
INSERT INTO `migrations` (`id`, `migration`, `batch`) VALUES (153,'2020_08_20_205533_add_backup_state_column_to_backups',1); INSERT INTO `migrations` (`id`, `migration`, `batch`) VALUES (153,'2020_08_23_175331_modify_checksums_column_for_backups',1);
INSERT INTO `migrations` (`id`, `migration`, `batch`) VALUES (154,'2020_08_22_132500_update_bytes_to_unsigned_bigint',1); INSERT INTO `migrations` (`id`, `migration`, `batch`) VALUES (154,'2020_09_13_110007_drop_packs_from_servers',1);
INSERT INTO `migrations` (`id`, `migration`, `batch`) VALUES (155,'2020_08_23_175331_modify_checksums_column_for_backups',1); INSERT INTO `migrations` (`id`, `migration`, `batch`) VALUES (155,'2020_09_13_110021_drop_packs_from_api_key_permissions',1);
INSERT INTO `migrations` (`id`, `migration`, `batch`) VALUES (156,'2020_09_13_110007_drop_packs_from_servers',1); INSERT INTO `migrations` (`id`, `migration`, `batch`) VALUES (156,'2020_09_13_110047_drop_packs_table',1);
INSERT INTO `migrations` (`id`, `migration`, `batch`) VALUES (157,'2020_09_13_110021_drop_packs_from_api_key_permissions',1); INSERT INTO `migrations` (`id`, `migration`, `batch`) VALUES (157,'2020_09_13_113503_drop_daemon_key_table',1);
INSERT INTO `migrations` (`id`, `migration`, `batch`) VALUES (158,'2020_09_13_110047_drop_packs_table',1); INSERT INTO `migrations` (`id`, `migration`, `batch`) VALUES (158,'2020_10_10_165437_change_unique_database_name_to_account_for_server',1);
INSERT INTO `migrations` (`id`, `migration`, `batch`) VALUES (159,'2020_09_13_113503_drop_daemon_key_table',1); INSERT INTO `migrations` (`id`, `migration`, `batch`) VALUES (159,'2020_10_26_194904_remove_nullable_from_schedule_name_field',1);
INSERT INTO `migrations` (`id`, `migration`, `batch`) VALUES (160,'2020_10_10_165437_change_unique_database_name_to_account_for_server',1); INSERT INTO `migrations` (`id`, `migration`, `batch`) VALUES (160,'2020_11_02_201014_add_features_column_to_eggs',1);
INSERT INTO `migrations` (`id`, `migration`, `batch`) VALUES (161,'2020_10_26_194904_remove_nullable_from_schedule_name_field',1); INSERT INTO `migrations` (`id`, `migration`, `batch`) VALUES (161,'2020_12_12_102435_support_multiple_docker_images_and_updates',1);
INSERT INTO `migrations` (`id`, `migration`, `batch`) VALUES (162,'2020_11_02_201014_add_features_column_to_eggs',1); INSERT INTO `migrations` (`id`, `migration`, `batch`) VALUES (162,'2020_12_14_013707_make_successful_nullable_in_server_transfers',1);
INSERT INTO `migrations` (`id`, `migration`, `batch`) VALUES (163,'2020_12_12_102435_support_multiple_docker_images_and_updates',1); INSERT INTO `migrations` (`id`, `migration`, `batch`) VALUES (163,'2020_12_17_014330_add_archived_field_to_server_transfers_table',1);
INSERT INTO `migrations` (`id`, `migration`, `batch`) VALUES (164,'2020_12_14_013707_make_successful_nullable_in_server_transfers',1); INSERT INTO `migrations` (`id`, `migration`, `batch`) VALUES (164,'2020_12_24_092449_make_allocation_fields_json',1);
INSERT INTO `migrations` (`id`, `migration`, `batch`) VALUES (165,'2020_12_17_014330_add_archived_field_to_server_transfers_table',1); INSERT INTO `migrations` (`id`, `migration`, `batch`) VALUES (165,'2020_12_26_184914_add_upload_id_column_to_backups_table',1);
INSERT INTO `migrations` (`id`, `migration`, `batch`) VALUES (166,'2020_12_24_092449_make_allocation_fields_json',1); INSERT INTO `migrations` (`id`, `migration`, `batch`) VALUES (166,'2021_01_10_153937_add_file_denylist_to_egg_configs',1);
INSERT INTO `migrations` (`id`, `migration`, `batch`) VALUES (167,'2020_12_26_184914_add_upload_id_column_to_backups_table',1); INSERT INTO `migrations` (`id`, `migration`, `batch`) VALUES (167,'2021_01_13_013420_add_cron_month',1);
INSERT INTO `migrations` (`id`, `migration`, `batch`) VALUES (168,'2021_01_10_153937_add_file_denylist_to_egg_configs',1); INSERT INTO `migrations` (`id`, `migration`, `batch`) VALUES (168,'2021_01_17_102401_create_audit_logs_table',1);
INSERT INTO `migrations` (`id`, `migration`, `batch`) VALUES (169,'2021_01_13_013420_add_cron_month',1); INSERT INTO `migrations` (`id`, `migration`, `batch`) VALUES (169,'2021_01_17_152623_add_generic_server_status_column',1);
INSERT INTO `migrations` (`id`, `migration`, `batch`) VALUES (170,'2021_01_17_102401_create_audit_logs_table',1); INSERT INTO `migrations` (`id`, `migration`, `batch`) VALUES (170,'2021_01_26_210502_update_file_denylist_to_json',1);
INSERT INTO `migrations` (`id`, `migration`, `batch`) VALUES (171,'2021_01_17_152623_add_generic_server_status_column',1); INSERT INTO `migrations` (`id`, `migration`, `batch`) VALUES (171,'2021_02_23_205021_add_index_for_server_and_action',1);
INSERT INTO `migrations` (`id`, `migration`, `batch`) VALUES (172,'2021_01_26_210502_update_file_denylist_to_json',1); INSERT INTO `migrations` (`id`, `migration`, `batch`) VALUES (172,'2021_02_23_212657_make_sftp_port_unsigned_int',1);
INSERT INTO `migrations` (`id`, `migration`, `batch`) VALUES (173,'2021_02_23_205021_add_index_for_server_and_action',1); INSERT INTO `migrations` (`id`, `migration`, `batch`) VALUES (173,'2021_03_21_104718_force_cron_month_field_to_have_value_if_missing',1);
INSERT INTO `migrations` (`id`, `migration`, `batch`) VALUES (174,'2021_02_23_212657_make_sftp_port_unsigned_int',1); INSERT INTO `migrations` (`id`, `migration`, `batch`) VALUES (174,'2021_05_01_092457_add_continue_on_failure_option_to_tasks',1);
INSERT INTO `migrations` (`id`, `migration`, `batch`) VALUES (175,'2021_03_21_104718_force_cron_month_field_to_have_value_if_missing',1); INSERT INTO `migrations` (`id`, `migration`, `batch`) VALUES (175,'2021_05_01_092523_add_only_run_when_server_online_option_to_schedules',1);
INSERT INTO `migrations` (`id`, `migration`, `batch`) VALUES (176,'2021_05_01_092457_add_continue_on_failure_option_to_tasks',1); INSERT INTO `migrations` (`id`, `migration`, `batch`) VALUES (176,'2021_05_03_201016_add_support_for_locking_a_backup',1);
INSERT INTO `migrations` (`id`, `migration`, `batch`) VALUES (177,'2021_05_01_092523_add_only_run_when_server_online_option_to_schedules',1); INSERT INTO `migrations` (`id`, `migration`, `batch`) VALUES (177,'2021_07_12_013420_remove_userinteraction',1);
INSERT INTO `migrations` (`id`, `migration`, `batch`) VALUES (178,'2021_05_03_201016_add_support_for_locking_a_backup',1); INSERT INTO `migrations` (`id`, `migration`, `batch`) VALUES (178,'2021_07_17_211512_create_user_ssh_keys_table',1);
INSERT INTO `migrations` (`id`, `migration`, `batch`) VALUES (179,'2021_07_12_013420_remove_userinteraction',1); INSERT INTO `migrations` (`id`, `migration`, `batch`) VALUES (179,'2021_08_03_210600_change_successful_field_to_default_to_false_on_backups_table',1);
INSERT INTO `migrations` (`id`, `migration`, `batch`) VALUES (180,'2021_07_17_211512_create_user_ssh_keys_table',1); INSERT INTO `migrations` (`id`, `migration`, `batch`) VALUES (180,'2021_08_21_175111_add_foreign_keys_to_mount_node_table',1);
INSERT INTO `migrations` (`id`, `migration`, `batch`) VALUES (181,'2021_08_03_210600_change_successful_field_to_default_to_false_on_backups_table',1); INSERT INTO `migrations` (`id`, `migration`, `batch`) VALUES (181,'2021_08_21_175118_add_foreign_keys_to_mount_server_table',1);
INSERT INTO `migrations` (`id`, `migration`, `batch`) VALUES (182,'2021_08_21_175111_add_foreign_keys_to_mount_node_table',1); INSERT INTO `migrations` (`id`, `migration`, `batch`) VALUES (182,'2021_08_21_180921_add_foreign_keys_to_egg_mount_table',1);
INSERT INTO `migrations` (`id`, `migration`, `batch`) VALUES (183,'2021_08_21_175118_add_foreign_keys_to_mount_server_table',1); INSERT INTO `migrations` (`id`, `migration`, `batch`) VALUES (183,'2022_01_25_030847_drop_google_analytics',1);
INSERT INTO `migrations` (`id`, `migration`, `batch`) VALUES (184,'2021_08_21_180921_add_foreign_keys_to_egg_mount_table',1); INSERT INTO `migrations` (`id`, `migration`, `batch`) VALUES (184,'2022_05_07_165334_migrate_egg_images_array_to_new_format',1);
INSERT INTO `migrations` (`id`, `migration`, `batch`) VALUES (185,'2022_01_25_030847_drop_google_analytics',1); INSERT INTO `migrations` (`id`, `migration`, `batch`) VALUES (185,'2022_05_28_135717_create_activity_logs_table',1);
INSERT INTO `migrations` (`id`, `migration`, `batch`) VALUES (186,'2022_05_07_165334_migrate_egg_images_array_to_new_format',1); INSERT INTO `migrations` (`id`, `migration`, `batch`) VALUES (186,'2022_05_29_140349_create_activity_log_actors_table',1);
INSERT INTO `migrations` (`id`, `migration`, `batch`) VALUES (187,'2022_05_28_135717_create_activity_logs_table',1); INSERT INTO `migrations` (`id`, `migration`, `batch`) VALUES (187,'2022_06_18_112822_track_api_key_usage_for_activity_events',1);
INSERT INTO `migrations` (`id`, `migration`, `batch`) VALUES (188,'2022_05_29_140349_create_activity_log_actors_table',1); INSERT INTO `migrations` (`id`, `migration`, `batch`) VALUES (188,'2022_08_16_214400_add_force_outgoing_ip_column_to_eggs_table',1);
INSERT INTO `migrations` (`id`, `migration`, `batch`) VALUES (189,'2022_06_18_112822_track_api_key_usage_for_activity_events',1); INSERT INTO `migrations` (`id`, `migration`, `batch`) VALUES (189,'2022_08_16_230204_add_installed_at_column_to_servers_table',1);
INSERT INTO `migrations` (`id`, `migration`, `batch`) VALUES (190,'2022_08_16_214400_add_force_outgoing_ip_column_to_eggs_table',1); INSERT INTO `migrations` (`id`, `migration`, `batch`) VALUES (190,'2022_12_12_213937_update_mail_settings_to_new_format',1);
INSERT INTO `migrations` (`id`, `migration`, `batch`) VALUES (191,'2022_08_16_230204_add_installed_at_column_to_servers_table',1); INSERT INTO `migrations` (`id`, `migration`, `batch`) VALUES (191,'2023_01_24_210051_add_uuid_column_to_failed_jobs_table',1);
INSERT INTO `migrations` (`id`, `migration`, `batch`) VALUES (192,'2022_12_12_213937_update_mail_settings_to_new_format',1); INSERT INTO `migrations` (`id`, `migration`, `batch`) VALUES (192,'2023_02_23_191004_add_expires_at_column_to_api_keys_table',1);
INSERT INTO `migrations` (`id`, `migration`, `batch`) VALUES (193,'2023_01_24_210051_add_uuid_column_to_failed_jobs_table',1); INSERT INTO `migrations` (`id`, `migration`, `batch`) VALUES (193,'2024_03_12_154408_remove_nests_table',1);
INSERT INTO `migrations` (`id`, `migration`, `batch`) VALUES (194,'2023_02_23_191004_add_expires_at_column_to_api_keys_table',1); INSERT INTO `migrations` (`id`, `migration`, `batch`) VALUES (194,'2024_03_14_055537_remove_locations_table',1);
INSERT INTO `migrations` (`id`, `migration`, `batch`) VALUES (197,'2024_03_12_154408_remove_nests_table',2); INSERT INTO `migrations` (`id`, `migration`, `batch`) VALUES (195,'2024_04_14_002250_update_column_names',1);
INSERT INTO `migrations` (`id`, `migration`, `batch`) VALUES (198,'2024_03_14_055537_remove_locations_table',2); INSERT INTO `migrations` (`id`, `migration`, `batch`) VALUES (196,'2024_04_20_214441_add_egg_var_sort',1);
INSERT INTO `migrations` (`id`, `migration`, `batch`) VALUES (201,'2024_04_20_214441_add_egg_var_sort',3); INSERT INTO `migrations` (`id`, `migration`, `batch`) VALUES (197,'2024_04_28_184102_add_mounts_to_api_keys',1);
INSERT INTO `migrations` (`id`, `migration`, `batch`) VALUES (203,'2024_04_14_002250_update_column_names',4); INSERT INTO `migrations` (`id`, `migration`, `batch`) VALUES (198,'2024_05_08_094823_rename_oom_disabled_column_to_oom_killer',1);
INSERT INTO `migrations` (`id`, `migration`, `batch`) VALUES (204,'2024_05_08_094823_rename_oom_disabled_column_to_oom_killer',1); INSERT INTO `migrations` (`id`, `migration`, `batch`) VALUES (199,'2024_05_16_091207_add_cpu_columns_to_nodes_table',1);
INSERT INTO `migrations` (`id`, `migration`, `batch`) VALUES (205,'2024_05_16_091207_add_cpu_columns_to_nodes_table',1); INSERT INTO `migrations` (`id`, `migration`, `batch`) VALUES (200,'2024_05_20_002841_add_docker_container_label',1);
INSERT INTO `migrations` (`id`, `migration`, `batch`) VALUES (201,'2024_05_31_204646_fix_old_encrypted_values',1);
INSERT INTO `migrations` (`id`, `migration`, `batch`) VALUES (202,'2024_06_02_205622_update_stock_egg_uuid',1);
INSERT INTO `migrations` (`id`, `migration`, `batch`) VALUES (203,'2024_06_04_085042_add_daemon_sftp_alias_column_to_nodes',1);
INSERT INTO `migrations` (`id`, `migration`, `batch`) VALUES (204,'2024_06_05_220135_update_egg_config_variables',1);
INSERT INTO `migrations` (`id`, `migration`, `batch`) VALUES (205,'2024_06_08_020904_refix_egg_variables',1);
INSERT INTO `migrations` (`id`, `migration`, `batch`) VALUES (206,'2024_06_11_220722_update_field_length',1);

View File

@ -39,8 +39,7 @@ return [
'daemonSFTP' => 'Enter the daemon SFTP listening port', 'daemonSFTP' => 'Enter the daemon SFTP listening port',
'daemonSFTPAlias' => 'Enter the daemon SFTP alias (can be empty)', 'daemonSFTPAlias' => 'Enter the daemon SFTP alias (can be empty)',
'daemonBase' => 'Enter the base folder', 'daemonBase' => 'Enter the base folder',
'succes1' => 'Successfully created a new node with the name: ', 'success' => 'Successfully created a new node with the name :name and has an id of :id',
'succes2' => 'and has an id of: ',
], ],
'node_config' => [ 'node_config' => [
'error_not_exist' => 'The selected node does not exist.', 'error_not_exist' => 'The selected node does not exist.',

View File

@ -19,9 +19,13 @@ return [
'button_issues' => 'Create Issue', 'button_issues' => 'Create Issue',
'button_features' => 'Discuss Features', 'button_features' => 'Discuss Features',
], ],
'intro-update' => [ 'intro-update-available' => [
'heading' => 'Update available', 'heading' => 'Update available',
'content' => ':latestVersion is available! Read our documentation to update your Panel.', 'content' => ':latestVersion is now available! Read our documentation to update your Panel.',
],
'intro-no-update' => [
'heading' => 'Your Panel is up to date',
'content' => 'You are currently using :version. Your panel is up-to-date!',
], ],
'intro-first-node' => [ 'intro-first-node' => [
'heading' => 'No Nodes Detected', 'heading' => 'No Nodes Detected',

9
lang/en/search.php Normal file
View File

@ -0,0 +1,9 @@
<?php
return [
'validation' => 'Please enter at least three characters to begin searching.',
'term' => [
'label' => 'Search term',
'description' => 'Enter a server name, uuid, or allocation to begin searching.',
],
];

View File

@ -1,5 +1,4 @@
<x-filament-panels::page> <x-filament-panels::page>
<x-filament-panels::header <x-filament-panels::header
:actions="$this->getCachedHeaderActions()" :actions="$this->getCachedHeaderActions()"
:breadcrumbs="filament()->hasBreadcrumbs() ? $this->getBreadcrumbs() : []" :breadcrumbs="filament()->hasBreadcrumbs() ? $this->getBreadcrumbs() : []"
@ -9,6 +8,31 @@
<p>{{ trans('dashboard/index.expand_sections') }}</p> <p>{{ trans('dashboard/index.expand_sections') }}</p>
@if (!$isLatest)
<x-filament::section
icon="tabler-info-circle"
icon-color="warning"
id="intro-update-available"
:header-actions="$updateActions"
>
<x-slot name="heading">{{ trans('dashboard/index.sections.intro-update-available.heading') }}</x-slot>
<p>{{ trans('dashboard/index.sections.intro-update-available.content', ['latestVersion' => $latestVersion]) }}</p>
</x-filament::section>
@else
<x-filament::section
icon="tabler-checkbox"
icon-color="success"
id="intro-no-update"
>
<x-slot name="heading">{{ trans('dashboard/index.sections.intro-no-update.heading') }}</x-slot>
<p>{{ trans('dashboard/index.sections.intro-no-update.content', ['version' => $version]) }}</p>
</x-filament::section>
@endif
@if ($inDevelopment) @if ($inDevelopment)
<x-filament::section <x-filament::section
icon="tabler-code" icon="tabler-code"
@ -30,22 +54,6 @@
</x-filament::section> </x-filament::section>
@endif @endif
@if (!$isLatest)
<x-filament::section
icon="tabler-info-circle"
icon-color="warning"
id="intro-update"
collapsible
persist-collapsed
:header-actions="$updateActions"
>
<x-slot name="heading">{{ trans('dashboard/index.sections.intro-update.heading') }}</x-slot>
<p>{{ trans('dashboard/index.sections.intro-update.content', ['latestVersion' => $latestVersion]) }}</p>
</x-filament::section>
@endif
{{-- No Nodes Created --}} {{-- No Nodes Created --}}
@if ($nodesCount <= 0) @if ($nodesCount <= 0)
<x-filament::section <x-filament::section
@ -65,7 +73,6 @@
{{-- No Nodes Active --}} {{-- No Nodes Active --}}
<x-filament::section <x-filament::section
icon="tabler-heart-filled" icon="tabler-heart-filled"
icon-color="danger" icon-color="danger"
@ -84,8 +91,6 @@
</x-filament::section> </x-filament::section>
<x-filament::section <x-filament::section
icon="tabler-question-mark" icon="tabler-question-mark"
icon-color="info" icon-color="info"
@ -103,7 +108,4 @@
</p> </p>
</x-filament::section> </x-filament::section>
<div>
</div>
</x-filament-panels::page> </x-filament-panels::page>

View File

@ -17,7 +17,7 @@
@section('user-data') @section('user-data')
@if(!is_null(Auth::user())) @if(!is_null(Auth::user()))
<script> <script>
window.PanelUser = {!! json_encode(Auth::user()->toVueObject()) !!}; window.PanelUser = {!! json_encode(Auth::user()->toReactObject()) !!};
</script> </script>
@endif @endif
@if(!empty($siteConfiguration)) @if(!empty($siteConfiguration))

View File

@ -20,7 +20,7 @@ Route::get('/password/reset/{token}', [Auth\LoginController::class, 'index'])->n
// Endpoints for OAuth // Endpoints for OAuth
Route::get('/oauth/redirect/{driver}', [Auth\OAuthController::class, 'redirect'])->name('auth.oauth.redirect'); Route::get('/oauth/redirect/{driver}', [Auth\OAuthController::class, 'redirect'])->name('auth.oauth.redirect');
Route::get('/oauth/callback/{driver}', [Auth\OAuthController::class, 'callback'])->name('auth.oauth.callback'); Route::get('/oauth/callback/{driver}', [Auth\OAuthController::class, 'callback'])->name('auth.oauth.callback')->withoutMiddleware('guest');
// Apply a throttle to authentication action endpoints, in addition to the // Apply a throttle to authentication action endpoints, in addition to the
// recaptcha endpoints to slow down manual attack spammers even more. 🤷‍ // recaptcha endpoints to slow down manual attack spammers even more. 🤷‍

View File

@ -24,8 +24,8 @@ class UserControllerTest extends ApplicationApiIntegrationTestCase
$response->assertJsonStructure([ $response->assertJsonStructure([
'object', 'object',
'data' => [ 'data' => [
['object', 'attributes' => ['id', 'external_id', 'uuid', 'username', 'email', 'first_name', 'last_name', 'language', 'root_admin', '2fa', 'created_at', 'updated_at']], ['object', 'attributes' => ['id', 'external_id', 'uuid', 'username', 'email', 'first_name', 'last_name', 'language', 'root_admin', '2fa_enabled', '2fa', 'created_at', 'updated_at']],
['object', 'attributes' => ['id', 'external_id', 'uuid', 'username', 'email', 'first_name', 'last_name', 'language', 'root_admin', '2fa', 'created_at', 'updated_at']], ['object', 'attributes' => ['id', 'external_id', 'uuid', 'username', 'email', 'first_name', 'last_name', 'language', 'root_admin', '2fa_enabled', '2fa', 'created_at', 'updated_at']],
], ],
'meta' => ['pagination' => ['total', 'count', 'per_page', 'current_page', 'total_pages']], 'meta' => ['pagination' => ['total', 'count', 'per_page', 'current_page', 'total_pages']],
]); ]);
@ -56,6 +56,7 @@ class UserControllerTest extends ApplicationApiIntegrationTestCase
'last_name' => $this->getApiUser()->name_last, 'last_name' => $this->getApiUser()->name_last,
'language' => $this->getApiUser()->language, 'language' => $this->getApiUser()->language,
'root_admin' => $this->getApiUser()->root_admin, 'root_admin' => $this->getApiUser()->root_admin,
'2fa_enabled' => (bool) $this->getApiUser()->totp_enabled,
'2fa' => (bool) $this->getApiUser()->totp_enabled, '2fa' => (bool) $this->getApiUser()->totp_enabled,
'created_at' => $this->formatTimestamp($this->getApiUser()->created_at), 'created_at' => $this->formatTimestamp($this->getApiUser()->created_at),
'updated_at' => $this->formatTimestamp($this->getApiUser()->updated_at), 'updated_at' => $this->formatTimestamp($this->getApiUser()->updated_at),
@ -73,6 +74,7 @@ class UserControllerTest extends ApplicationApiIntegrationTestCase
'last_name' => $user->name_last, 'last_name' => $user->name_last,
'language' => $user->language, 'language' => $user->language,
'root_admin' => (bool) $user->root_admin, 'root_admin' => (bool) $user->root_admin,
'2fa_enabled' => (bool) $user->totp_enabled,
'2fa' => (bool) $user->totp_enabled, '2fa' => (bool) $user->totp_enabled,
'created_at' => $this->formatTimestamp($user->created_at), 'created_at' => $this->formatTimestamp($user->created_at),
'updated_at' => $this->formatTimestamp($user->updated_at), 'updated_at' => $this->formatTimestamp($user->updated_at),

View File

@ -22,13 +22,18 @@ class AccountControllerTest extends ClientApiIntegrationTestCase
$response->assertOk()->assertJson([ $response->assertOk()->assertJson([
'object' => 'user', 'object' => 'user',
'attributes' => [ 'attributes' => [
'id' => $user->id, 'uuid' => $user->uuid,
'admin' => false,
'username' => $user->username, 'username' => $user->username,
'email' => $user->email, 'email' => $user->email,
'first_name' => $user->name_first, 'first_name' => $user->name_first,
'last_name' => $user->name_last, 'last_name' => $user->name_last,
'language' => $user->language, 'language' => 'en',
'image' => 'https://gravatar.com/avatar/' . md5(Str::lower($user->email)),
'admin' => false,
'root_admin' => false,
'2fa_enabled' => false,
'created_at' => $this->formatTimestamp($user->created_at),
'updated_at' => $this->formatTimestamp($user->updated_at),
], ],
]); ]);
} }

View File

@ -80,7 +80,7 @@ class CreateServerSubuserTest extends ClientApiIntegrationTestCase
{ {
[$user, $server] = $this->generateTestAccount(); [$user, $server] = $this->generateTestAccount();
$email = str_repeat(Str::random(20), 9) . '1@gmail.com'; // 191 is the hard limit for the column in MySQL. $email = str_repeat(Str::random(35), 7) . '@gmail.com'; // 255 is the hard limit for the column in MySQL.
$response = $this->actingAs($user)->postJson($this->link($server) . '/users', [ $response = $this->actingAs($user)->postJson($this->link($server) . '/users', [
'email' => $email, 'email' => $email,
@ -99,7 +99,7 @@ class CreateServerSubuserTest extends ClientApiIntegrationTestCase
]); ]);
$response->assertStatus(Response::HTTP_UNPROCESSABLE_ENTITY); $response->assertStatus(Response::HTTP_UNPROCESSABLE_ENTITY);
$response->assertJsonPath('errors.0.detail', 'The email must be between 1 and 191 characters.'); $response->assertJsonPath('errors.0.detail', 'The email must be between 1 and 255 characters.');
$response->assertJsonPath('errors.0.meta.source_field', 'email'); $response->assertJsonPath('errors.0.meta.source_field', 'email');
} }