refactor(validation): implement centralized validation patterns across components
- Introduced `ValidationPatterns` class to standardize validation rules and messages for various fields across multiple components. - Updated components including `General`, `StackForm`, `Create`, and `Show` to utilize the new validation patterns, ensuring consistent validation logic. - Enhanced error messages for required fields and added regex validation for names and descriptions to improve user feedback. - Adjusted styling in the `create.blade.php` view for better visual hierarchy.
This commit is contained in:
@@ -4,6 +4,7 @@ namespace App\Livewire\Project\Application;
|
|||||||
|
|
||||||
use App\Actions\Application\GenerateConfig;
|
use App\Actions\Application\GenerateConfig;
|
||||||
use App\Models\Application;
|
use App\Models\Application;
|
||||||
|
use App\Support\ValidationPatterns;
|
||||||
use Illuminate\Support\Collection;
|
use Illuminate\Support\Collection;
|
||||||
use Livewire\Component;
|
use Livewire\Component;
|
||||||
use Spatie\Url\Url;
|
use Spatie\Url\Url;
|
||||||
@@ -52,52 +53,89 @@ class General extends Component
|
|||||||
'configurationChanged' => '$refresh',
|
'configurationChanged' => '$refresh',
|
||||||
];
|
];
|
||||||
|
|
||||||
protected $rules = [
|
protected function rules(): array
|
||||||
'application.name' => 'required',
|
{
|
||||||
'application.description' => 'nullable',
|
return [
|
||||||
'application.fqdn' => 'nullable',
|
'application.name' => ValidationPatterns::nameRules(),
|
||||||
'application.git_repository' => 'required',
|
'application.description' => ValidationPatterns::descriptionRules(),
|
||||||
'application.git_branch' => 'required',
|
'application.fqdn' => 'nullable',
|
||||||
'application.git_commit_sha' => 'nullable',
|
'application.git_repository' => 'required',
|
||||||
'application.install_command' => 'nullable',
|
'application.git_branch' => 'required',
|
||||||
'application.build_command' => 'nullable',
|
'application.git_commit_sha' => 'nullable',
|
||||||
'application.start_command' => 'nullable',
|
'application.install_command' => 'nullable',
|
||||||
'application.build_pack' => 'required',
|
'application.build_command' => 'nullable',
|
||||||
'application.static_image' => 'required',
|
'application.start_command' => 'nullable',
|
||||||
'application.base_directory' => 'required',
|
'application.build_pack' => 'required',
|
||||||
'application.publish_directory' => 'nullable',
|
'application.static_image' => 'required',
|
||||||
'application.ports_exposes' => 'required',
|
'application.base_directory' => 'required',
|
||||||
'application.ports_mappings' => 'nullable',
|
'application.publish_directory' => 'nullable',
|
||||||
'application.custom_network_aliases' => 'nullable',
|
'application.ports_exposes' => 'required',
|
||||||
'application.dockerfile' => 'nullable',
|
'application.ports_mappings' => 'nullable',
|
||||||
'application.docker_registry_image_name' => 'nullable',
|
'application.custom_network_aliases' => 'nullable',
|
||||||
'application.docker_registry_image_tag' => 'nullable',
|
'application.dockerfile' => 'nullable',
|
||||||
'application.dockerfile_location' => 'nullable',
|
'application.docker_registry_image_name' => 'nullable',
|
||||||
'application.docker_compose_location' => 'nullable',
|
'application.docker_registry_image_tag' => 'nullable',
|
||||||
'application.docker_compose' => 'nullable',
|
'application.dockerfile_location' => 'nullable',
|
||||||
'application.docker_compose_raw' => 'nullable',
|
'application.docker_compose_location' => 'nullable',
|
||||||
'application.dockerfile_target_build' => 'nullable',
|
'application.docker_compose' => 'nullable',
|
||||||
'application.docker_compose_custom_start_command' => 'nullable',
|
'application.docker_compose_raw' => 'nullable',
|
||||||
'application.docker_compose_custom_build_command' => 'nullable',
|
'application.dockerfile_target_build' => 'nullable',
|
||||||
'application.custom_labels' => 'nullable',
|
'application.docker_compose_custom_start_command' => 'nullable',
|
||||||
'application.custom_docker_run_options' => 'nullable',
|
'application.docker_compose_custom_build_command' => 'nullable',
|
||||||
'application.pre_deployment_command' => 'nullable',
|
'application.custom_labels' => 'nullable',
|
||||||
'application.pre_deployment_command_container' => 'nullable',
|
'application.custom_docker_run_options' => 'nullable',
|
||||||
'application.post_deployment_command' => 'nullable',
|
'application.pre_deployment_command' => 'nullable',
|
||||||
'application.post_deployment_command_container' => 'nullable',
|
'application.pre_deployment_command_container' => 'nullable',
|
||||||
'application.custom_nginx_configuration' => 'nullable',
|
'application.post_deployment_command' => 'nullable',
|
||||||
'application.settings.is_static' => 'boolean|required',
|
'application.post_deployment_command_container' => 'nullable',
|
||||||
'application.settings.is_spa' => 'boolean|required',
|
'application.custom_nginx_configuration' => 'nullable',
|
||||||
'application.settings.is_build_server_enabled' => 'boolean|required',
|
'application.settings.is_static' => 'boolean|required',
|
||||||
'application.settings.is_container_label_escape_enabled' => 'boolean|required',
|
'application.settings.is_spa' => 'boolean|required',
|
||||||
'application.settings.is_container_label_readonly_enabled' => 'boolean|required',
|
'application.settings.is_build_server_enabled' => 'boolean|required',
|
||||||
'application.settings.is_preserve_repository_enabled' => 'boolean|required',
|
'application.settings.is_container_label_escape_enabled' => 'boolean|required',
|
||||||
'application.is_http_basic_auth_enabled' => 'boolean|required',
|
'application.settings.is_container_label_readonly_enabled' => 'boolean|required',
|
||||||
'application.http_basic_auth_username' => 'string|nullable',
|
'application.settings.is_preserve_repository_enabled' => 'boolean|required',
|
||||||
'application.http_basic_auth_password' => 'string|nullable',
|
'application.is_http_basic_auth_enabled' => 'boolean|required',
|
||||||
'application.watch_paths' => 'nullable',
|
'application.http_basic_auth_username' => 'string|nullable',
|
||||||
'application.redirect' => 'string|required',
|
'application.http_basic_auth_password' => 'string|nullable',
|
||||||
];
|
'application.watch_paths' => 'nullable',
|
||||||
|
'application.redirect' => 'string|required',
|
||||||
|
];
|
||||||
|
}
|
||||||
|
|
||||||
|
protected function messages(): array
|
||||||
|
{
|
||||||
|
return array_merge(
|
||||||
|
ValidationPatterns::combinedMessages(),
|
||||||
|
[
|
||||||
|
'application.name.required' => 'The Name field is required.',
|
||||||
|
'application.name.regex' => 'The Name may only contain letters, numbers, spaces, dashes (-), underscores (_), dots (.), slashes (/), colons (:), and parentheses ().',
|
||||||
|
'application.description.regex' => 'The Description contains invalid characters. Only letters, numbers, spaces, and common punctuation (- _ . : / () \' " , ! ? @ # % & + = [] {} | ~ ` *) are allowed.',
|
||||||
|
'application.git_repository.required' => 'The Git Repository field is required.',
|
||||||
|
'application.git_branch.required' => 'The Git Branch field is required.',
|
||||||
|
'application.build_pack.required' => 'The Build Pack field is required.',
|
||||||
|
'application.static_image.required' => 'The Static Image field is required.',
|
||||||
|
'application.base_directory.required' => 'The Base Directory field is required.',
|
||||||
|
'application.ports_exposes.required' => 'The Exposed Ports field is required.',
|
||||||
|
'application.settings.is_static.required' => 'The Static setting is required.',
|
||||||
|
'application.settings.is_static.boolean' => 'The Static setting must be true or false.',
|
||||||
|
'application.settings.is_spa.required' => 'The SPA setting is required.',
|
||||||
|
'application.settings.is_spa.boolean' => 'The SPA setting must be true or false.',
|
||||||
|
'application.settings.is_build_server_enabled.required' => 'The Build Server setting is required.',
|
||||||
|
'application.settings.is_build_server_enabled.boolean' => 'The Build Server setting must be true or false.',
|
||||||
|
'application.settings.is_container_label_escape_enabled.required' => 'The Container Label Escape setting is required.',
|
||||||
|
'application.settings.is_container_label_escape_enabled.boolean' => 'The Container Label Escape setting must be true or false.',
|
||||||
|
'application.settings.is_container_label_readonly_enabled.required' => 'The Container Label Readonly setting is required.',
|
||||||
|
'application.settings.is_container_label_readonly_enabled.boolean' => 'The Container Label Readonly setting must be true or false.',
|
||||||
|
'application.settings.is_preserve_repository_enabled.required' => 'The Preserve Repository setting is required.',
|
||||||
|
'application.settings.is_preserve_repository_enabled.boolean' => 'The Preserve Repository setting must be true or false.',
|
||||||
|
'application.is_http_basic_auth_enabled.required' => 'The HTTP Basic Auth setting is required.',
|
||||||
|
'application.is_http_basic_auth_enabled.boolean' => 'The HTTP Basic Auth setting must be true or false.',
|
||||||
|
'application.redirect.required' => 'The Redirect setting is required.',
|
||||||
|
'application.redirect.string' => 'The Redirect setting must be a string.',
|
||||||
|
]
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
protected $validationAttributes = [
|
protected $validationAttributes = [
|
||||||
'application.name' => 'name',
|
'application.name' => 'name',
|
||||||
|
|||||||
@@ -6,9 +6,9 @@ use App\Actions\Database\StartDatabaseProxy;
|
|||||||
use App\Actions\Database\StopDatabaseProxy;
|
use App\Actions\Database\StopDatabaseProxy;
|
||||||
use App\Models\Server;
|
use App\Models\Server;
|
||||||
use App\Models\StandaloneClickhouse;
|
use App\Models\StandaloneClickhouse;
|
||||||
|
use App\Support\ValidationPatterns;
|
||||||
use Exception;
|
use Exception;
|
||||||
use Illuminate\Support\Facades\Auth;
|
use Illuminate\Support\Facades\Auth;
|
||||||
use Livewire\Attributes\Validate;
|
|
||||||
use Livewire\Component;
|
use Livewire\Component;
|
||||||
|
|
||||||
class General extends Component
|
class General extends Component
|
||||||
@@ -17,40 +17,28 @@ class General extends Component
|
|||||||
|
|
||||||
public StandaloneClickhouse $database;
|
public StandaloneClickhouse $database;
|
||||||
|
|
||||||
#[Validate(['required', 'string'])]
|
|
||||||
public string $name;
|
public string $name;
|
||||||
|
|
||||||
#[Validate(['nullable', 'string'])]
|
|
||||||
public ?string $description = null;
|
public ?string $description = null;
|
||||||
|
|
||||||
#[Validate(['required', 'string'])]
|
|
||||||
public string $clickhouseAdminUser;
|
public string $clickhouseAdminUser;
|
||||||
|
|
||||||
#[Validate(['required', 'string'])]
|
|
||||||
public string $clickhouseAdminPassword;
|
public string $clickhouseAdminPassword;
|
||||||
|
|
||||||
#[Validate(['required', 'string'])]
|
|
||||||
public string $image;
|
public string $image;
|
||||||
|
|
||||||
#[Validate(['nullable', 'string'])]
|
|
||||||
public ?string $portsMappings = null;
|
public ?string $portsMappings = null;
|
||||||
|
|
||||||
#[Validate(['nullable', 'boolean'])]
|
|
||||||
public ?bool $isPublic = null;
|
public ?bool $isPublic = null;
|
||||||
|
|
||||||
#[Validate(['nullable', 'integer'])]
|
|
||||||
public ?int $publicPort = null;
|
public ?int $publicPort = null;
|
||||||
|
|
||||||
#[Validate(['nullable', 'string'])]
|
|
||||||
public ?string $customDockerRunOptions = null;
|
public ?string $customDockerRunOptions = null;
|
||||||
|
|
||||||
#[Validate(['nullable', 'string'])]
|
|
||||||
public ?string $dbUrl = null;
|
public ?string $dbUrl = null;
|
||||||
|
|
||||||
#[Validate(['nullable', 'string'])]
|
|
||||||
public ?string $dbUrlPublic = null;
|
public ?string $dbUrlPublic = null;
|
||||||
|
|
||||||
#[Validate(['nullable', 'boolean'])]
|
|
||||||
public bool $isLogDrainEnabled = false;
|
public bool $isLogDrainEnabled = false;
|
||||||
|
|
||||||
public function getListeners()
|
public function getListeners()
|
||||||
@@ -72,6 +60,40 @@ class General extends Component
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
protected function rules(): array
|
||||||
|
{
|
||||||
|
return [
|
||||||
|
'name' => ValidationPatterns::nameRules(),
|
||||||
|
'description' => ValidationPatterns::descriptionRules(),
|
||||||
|
'clickhouseAdminUser' => 'required|string',
|
||||||
|
'clickhouseAdminPassword' => 'required|string',
|
||||||
|
'image' => 'required|string',
|
||||||
|
'portsMappings' => 'nullable|string',
|
||||||
|
'isPublic' => 'nullable|boolean',
|
||||||
|
'publicPort' => 'nullable|integer',
|
||||||
|
'customDockerRunOptions' => 'nullable|string',
|
||||||
|
'dbUrl' => 'nullable|string',
|
||||||
|
'dbUrlPublic' => 'nullable|string',
|
||||||
|
'isLogDrainEnabled' => 'nullable|boolean',
|
||||||
|
];
|
||||||
|
}
|
||||||
|
|
||||||
|
protected function messages(): array
|
||||||
|
{
|
||||||
|
return array_merge(
|
||||||
|
ValidationPatterns::combinedMessages(),
|
||||||
|
[
|
||||||
|
'clickhouseAdminUser.required' => 'The Admin User field is required.',
|
||||||
|
'clickhouseAdminUser.string' => 'The Admin User must be a string.',
|
||||||
|
'clickhouseAdminPassword.required' => 'The Admin Password field is required.',
|
||||||
|
'clickhouseAdminPassword.string' => 'The Admin Password must be a string.',
|
||||||
|
'image.required' => 'The Docker Image field is required.',
|
||||||
|
'image.string' => 'The Docker Image must be a string.',
|
||||||
|
'publicPort.integer' => 'The Public Port must be an integer.',
|
||||||
|
]
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
public function syncData(bool $toModel = false)
|
public function syncData(bool $toModel = false)
|
||||||
{
|
{
|
||||||
if ($toModel) {
|
if ($toModel) {
|
||||||
|
|||||||
@@ -8,10 +8,10 @@ use App\Helpers\SslHelper;
|
|||||||
use App\Models\Server;
|
use App\Models\Server;
|
||||||
use App\Models\SslCertificate;
|
use App\Models\SslCertificate;
|
||||||
use App\Models\StandaloneDragonfly;
|
use App\Models\StandaloneDragonfly;
|
||||||
|
use App\Support\ValidationPatterns;
|
||||||
use Carbon\Carbon;
|
use Carbon\Carbon;
|
||||||
use Exception;
|
use Exception;
|
||||||
use Illuminate\Support\Facades\Auth;
|
use Illuminate\Support\Facades\Auth;
|
||||||
use Livewire\Attributes\Validate;
|
|
||||||
use Livewire\Component;
|
use Livewire\Component;
|
||||||
|
|
||||||
class General extends Component
|
class General extends Component
|
||||||
@@ -20,42 +20,30 @@ class General extends Component
|
|||||||
|
|
||||||
public StandaloneDragonfly $database;
|
public StandaloneDragonfly $database;
|
||||||
|
|
||||||
#[Validate(['required', 'string'])]
|
|
||||||
public string $name;
|
public string $name;
|
||||||
|
|
||||||
#[Validate(['nullable', 'string'])]
|
|
||||||
public ?string $description = null;
|
public ?string $description = null;
|
||||||
|
|
||||||
#[Validate(['required', 'string'])]
|
|
||||||
public string $dragonflyPassword;
|
public string $dragonflyPassword;
|
||||||
|
|
||||||
#[Validate(['required', 'string'])]
|
|
||||||
public string $image;
|
public string $image;
|
||||||
|
|
||||||
#[Validate(['nullable', 'string'])]
|
|
||||||
public ?string $portsMappings = null;
|
public ?string $portsMappings = null;
|
||||||
|
|
||||||
#[Validate(['nullable', 'boolean'])]
|
|
||||||
public ?bool $isPublic = null;
|
public ?bool $isPublic = null;
|
||||||
|
|
||||||
#[Validate(['nullable', 'integer'])]
|
|
||||||
public ?int $publicPort = null;
|
public ?int $publicPort = null;
|
||||||
|
|
||||||
#[Validate(['nullable', 'string'])]
|
|
||||||
public ?string $customDockerRunOptions = null;
|
public ?string $customDockerRunOptions = null;
|
||||||
|
|
||||||
#[Validate(['nullable', 'string'])]
|
|
||||||
public ?string $dbUrl = null;
|
public ?string $dbUrl = null;
|
||||||
|
|
||||||
#[Validate(['nullable', 'string'])]
|
|
||||||
public ?string $dbUrlPublic = null;
|
public ?string $dbUrlPublic = null;
|
||||||
|
|
||||||
#[Validate(['nullable', 'boolean'])]
|
|
||||||
public bool $isLogDrainEnabled = false;
|
public bool $isLogDrainEnabled = false;
|
||||||
|
|
||||||
public ?Carbon $certificateValidUntil = null;
|
public ?Carbon $certificateValidUntil = null;
|
||||||
|
|
||||||
#[Validate(['nullable', 'boolean'])]
|
|
||||||
public bool $enable_ssl = false;
|
public bool $enable_ssl = false;
|
||||||
|
|
||||||
public function getListeners()
|
public function getListeners()
|
||||||
@@ -85,6 +73,38 @@ class General extends Component
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
protected function rules(): array
|
||||||
|
{
|
||||||
|
return [
|
||||||
|
'name' => ValidationPatterns::nameRules(),
|
||||||
|
'description' => ValidationPatterns::descriptionRules(),
|
||||||
|
'dragonflyPassword' => 'required|string',
|
||||||
|
'image' => 'required|string',
|
||||||
|
'portsMappings' => 'nullable|string',
|
||||||
|
'isPublic' => 'nullable|boolean',
|
||||||
|
'publicPort' => 'nullable|integer',
|
||||||
|
'customDockerRunOptions' => 'nullable|string',
|
||||||
|
'dbUrl' => 'nullable|string',
|
||||||
|
'dbUrlPublic' => 'nullable|string',
|
||||||
|
'isLogDrainEnabled' => 'nullable|boolean',
|
||||||
|
'enable_ssl' => 'nullable|boolean',
|
||||||
|
];
|
||||||
|
}
|
||||||
|
|
||||||
|
protected function messages(): array
|
||||||
|
{
|
||||||
|
return array_merge(
|
||||||
|
ValidationPatterns::combinedMessages(),
|
||||||
|
[
|
||||||
|
'dragonflyPassword.required' => 'The Dragonfly Password field is required.',
|
||||||
|
'dragonflyPassword.string' => 'The Dragonfly Password must be a string.',
|
||||||
|
'image.required' => 'The Docker Image field is required.',
|
||||||
|
'image.string' => 'The Docker Image must be a string.',
|
||||||
|
'publicPort.integer' => 'The Public Port must be an integer.',
|
||||||
|
]
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
public function syncData(bool $toModel = false)
|
public function syncData(bool $toModel = false)
|
||||||
{
|
{
|
||||||
if ($toModel) {
|
if ($toModel) {
|
||||||
|
|||||||
@@ -8,10 +8,10 @@ use App\Helpers\SslHelper;
|
|||||||
use App\Models\Server;
|
use App\Models\Server;
|
||||||
use App\Models\SslCertificate;
|
use App\Models\SslCertificate;
|
||||||
use App\Models\StandaloneKeydb;
|
use App\Models\StandaloneKeydb;
|
||||||
|
use App\Support\ValidationPatterns;
|
||||||
use Carbon\Carbon;
|
use Carbon\Carbon;
|
||||||
use Exception;
|
use Exception;
|
||||||
use Illuminate\Support\Facades\Auth;
|
use Illuminate\Support\Facades\Auth;
|
||||||
use Livewire\Attributes\Validate;
|
|
||||||
use Livewire\Component;
|
use Livewire\Component;
|
||||||
|
|
||||||
class General extends Component
|
class General extends Component
|
||||||
@@ -20,45 +20,32 @@ class General extends Component
|
|||||||
|
|
||||||
public StandaloneKeydb $database;
|
public StandaloneKeydb $database;
|
||||||
|
|
||||||
#[Validate(['required', 'string'])]
|
|
||||||
public string $name;
|
public string $name;
|
||||||
|
|
||||||
#[Validate(['nullable', 'string'])]
|
|
||||||
public ?string $description = null;
|
public ?string $description = null;
|
||||||
|
|
||||||
#[Validate(['nullable', 'string'])]
|
|
||||||
public ?string $keydbConf = null;
|
public ?string $keydbConf = null;
|
||||||
|
|
||||||
#[Validate(['required', 'string'])]
|
|
||||||
public string $keydbPassword;
|
public string $keydbPassword;
|
||||||
|
|
||||||
#[Validate(['required', 'string'])]
|
|
||||||
public string $image;
|
public string $image;
|
||||||
|
|
||||||
#[Validate(['nullable', 'string'])]
|
|
||||||
public ?string $portsMappings = null;
|
public ?string $portsMappings = null;
|
||||||
|
|
||||||
#[Validate(['nullable', 'boolean'])]
|
|
||||||
public ?bool $isPublic = null;
|
public ?bool $isPublic = null;
|
||||||
|
|
||||||
#[Validate(['nullable', 'integer'])]
|
|
||||||
public ?int $publicPort = null;
|
public ?int $publicPort = null;
|
||||||
|
|
||||||
#[Validate(['nullable', 'string'])]
|
|
||||||
public ?string $customDockerRunOptions = null;
|
public ?string $customDockerRunOptions = null;
|
||||||
|
|
||||||
#[Validate(['nullable', 'string'])]
|
|
||||||
public ?string $dbUrl = null;
|
public ?string $dbUrl = null;
|
||||||
|
|
||||||
#[Validate(['nullable', 'string'])]
|
|
||||||
public ?string $dbUrlPublic = null;
|
public ?string $dbUrlPublic = null;
|
||||||
|
|
||||||
#[Validate(['nullable', 'boolean'])]
|
|
||||||
public bool $isLogDrainEnabled = false;
|
public bool $isLogDrainEnabled = false;
|
||||||
|
|
||||||
public ?Carbon $certificateValidUntil = null;
|
public ?Carbon $certificateValidUntil = null;
|
||||||
|
|
||||||
#[Validate(['boolean'])]
|
|
||||||
public bool $enable_ssl = false;
|
public bool $enable_ssl = false;
|
||||||
|
|
||||||
public function getListeners()
|
public function getListeners()
|
||||||
@@ -89,6 +76,41 @@ class General extends Component
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
protected function rules(): array
|
||||||
|
{
|
||||||
|
$baseRules = [
|
||||||
|
'name' => ValidationPatterns::nameRules(),
|
||||||
|
'description' => ValidationPatterns::descriptionRules(),
|
||||||
|
'keydbConf' => 'nullable|string',
|
||||||
|
'keydbPassword' => 'required|string',
|
||||||
|
'image' => 'required|string',
|
||||||
|
'portsMappings' => 'nullable|string',
|
||||||
|
'isPublic' => 'nullable|boolean',
|
||||||
|
'publicPort' => 'nullable|integer',
|
||||||
|
'customDockerRunOptions' => 'nullable|string',
|
||||||
|
'dbUrl' => 'nullable|string',
|
||||||
|
'dbUrlPublic' => 'nullable|string',
|
||||||
|
'isLogDrainEnabled' => 'nullable|boolean',
|
||||||
|
'enable_ssl' => 'boolean',
|
||||||
|
];
|
||||||
|
|
||||||
|
return $baseRules;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected function messages(): array
|
||||||
|
{
|
||||||
|
return array_merge(
|
||||||
|
ValidationPatterns::combinedMessages(),
|
||||||
|
[
|
||||||
|
'keydbPassword.required' => 'The KeyDB Password field is required.',
|
||||||
|
'keydbPassword.string' => 'The KeyDB Password must be a string.',
|
||||||
|
'image.required' => 'The Docker Image field is required.',
|
||||||
|
'image.string' => 'The Docker Image must be a string.',
|
||||||
|
'publicPort.integer' => 'The Public Port must be an integer.',
|
||||||
|
]
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
public function syncData(bool $toModel = false)
|
public function syncData(bool $toModel = false)
|
||||||
{
|
{
|
||||||
if ($toModel) {
|
if ($toModel) {
|
||||||
|
|||||||
@@ -8,6 +8,7 @@ use App\Helpers\SslHelper;
|
|||||||
use App\Models\Server;
|
use App\Models\Server;
|
||||||
use App\Models\SslCertificate;
|
use App\Models\SslCertificate;
|
||||||
use App\Models\StandaloneMariadb;
|
use App\Models\StandaloneMariadb;
|
||||||
|
use App\Support\ValidationPatterns;
|
||||||
use Carbon\Carbon;
|
use Carbon\Carbon;
|
||||||
use Exception;
|
use Exception;
|
||||||
use Illuminate\Support\Facades\Auth;
|
use Illuminate\Support\Facades\Auth;
|
||||||
@@ -37,22 +38,43 @@ class General extends Component
|
|||||||
];
|
];
|
||||||
}
|
}
|
||||||
|
|
||||||
protected $rules = [
|
protected function rules(): array
|
||||||
'database.name' => 'required',
|
{
|
||||||
'database.description' => 'nullable',
|
return [
|
||||||
'database.mariadb_root_password' => 'required',
|
'database.name' => ValidationPatterns::nameRules(),
|
||||||
'database.mariadb_user' => 'required',
|
'database.description' => ValidationPatterns::descriptionRules(),
|
||||||
'database.mariadb_password' => 'required',
|
'database.mariadb_root_password' => 'required',
|
||||||
'database.mariadb_database' => 'required',
|
'database.mariadb_user' => 'required',
|
||||||
'database.mariadb_conf' => 'nullable',
|
'database.mariadb_password' => 'required',
|
||||||
'database.image' => 'required',
|
'database.mariadb_database' => 'required',
|
||||||
'database.ports_mappings' => 'nullable',
|
'database.mariadb_conf' => 'nullable',
|
||||||
'database.is_public' => 'nullable|boolean',
|
'database.image' => 'required',
|
||||||
'database.public_port' => 'nullable|integer',
|
'database.ports_mappings' => 'nullable',
|
||||||
'database.is_log_drain_enabled' => 'nullable|boolean',
|
'database.is_public' => 'nullable|boolean',
|
||||||
'database.custom_docker_run_options' => 'nullable',
|
'database.public_port' => 'nullable|integer',
|
||||||
'database.enable_ssl' => 'boolean',
|
'database.is_log_drain_enabled' => 'nullable|boolean',
|
||||||
];
|
'database.custom_docker_run_options' => 'nullable',
|
||||||
|
'database.enable_ssl' => 'boolean',
|
||||||
|
];
|
||||||
|
}
|
||||||
|
|
||||||
|
protected function messages(): array
|
||||||
|
{
|
||||||
|
return array_merge(
|
||||||
|
ValidationPatterns::combinedMessages(),
|
||||||
|
[
|
||||||
|
'database.name.required' => 'The Name field is required.',
|
||||||
|
'database.name.regex' => 'The Name may only contain letters, numbers, spaces, dashes (-), underscores (_), dots (.), slashes (/), colons (:), and parentheses ().',
|
||||||
|
'database.description.regex' => 'The Description contains invalid characters. Only letters, numbers, spaces, and common punctuation (- _ . : / () \' " , ! ? @ # % & + = [] {} | ~ ` *) are allowed.',
|
||||||
|
'database.mariadb_root_password.required' => 'The Root Password field is required.',
|
||||||
|
'database.mariadb_user.required' => 'The MariaDB User field is required.',
|
||||||
|
'database.mariadb_password.required' => 'The MariaDB Password field is required.',
|
||||||
|
'database.mariadb_database.required' => 'The MariaDB Database field is required.',
|
||||||
|
'database.image.required' => 'The Docker Image field is required.',
|
||||||
|
'database.public_port.integer' => 'The Public Port must be an integer.',
|
||||||
|
]
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
protected $validationAttributes = [
|
protected $validationAttributes = [
|
||||||
'database.name' => 'Name',
|
'database.name' => 'Name',
|
||||||
|
|||||||
@@ -8,6 +8,7 @@ use App\Helpers\SslHelper;
|
|||||||
use App\Models\Server;
|
use App\Models\Server;
|
||||||
use App\Models\SslCertificate;
|
use App\Models\SslCertificate;
|
||||||
use App\Models\StandaloneMongodb;
|
use App\Models\StandaloneMongodb;
|
||||||
|
use App\Support\ValidationPatterns;
|
||||||
use Carbon\Carbon;
|
use Carbon\Carbon;
|
||||||
use Exception;
|
use Exception;
|
||||||
use Illuminate\Support\Facades\Auth;
|
use Illuminate\Support\Facades\Auth;
|
||||||
@@ -37,22 +38,43 @@ class General extends Component
|
|||||||
];
|
];
|
||||||
}
|
}
|
||||||
|
|
||||||
protected $rules = [
|
protected function rules(): array
|
||||||
'database.name' => 'required',
|
{
|
||||||
'database.description' => 'nullable',
|
return [
|
||||||
'database.mongo_conf' => 'nullable',
|
'database.name' => ValidationPatterns::nameRules(),
|
||||||
'database.mongo_initdb_root_username' => 'required',
|
'database.description' => ValidationPatterns::descriptionRules(),
|
||||||
'database.mongo_initdb_root_password' => 'required',
|
'database.mongo_conf' => 'nullable',
|
||||||
'database.mongo_initdb_database' => 'required',
|
'database.mongo_initdb_root_username' => 'required',
|
||||||
'database.image' => 'required',
|
'database.mongo_initdb_root_password' => 'required',
|
||||||
'database.ports_mappings' => 'nullable',
|
'database.mongo_initdb_database' => 'required',
|
||||||
'database.is_public' => 'nullable|boolean',
|
'database.image' => 'required',
|
||||||
'database.public_port' => 'nullable|integer',
|
'database.ports_mappings' => 'nullable',
|
||||||
'database.is_log_drain_enabled' => 'nullable|boolean',
|
'database.is_public' => 'nullable|boolean',
|
||||||
'database.custom_docker_run_options' => 'nullable',
|
'database.public_port' => 'nullable|integer',
|
||||||
'database.enable_ssl' => 'boolean',
|
'database.is_log_drain_enabled' => 'nullable|boolean',
|
||||||
'database.ssl_mode' => 'nullable|string|in:allow,prefer,require,verify-full',
|
'database.custom_docker_run_options' => 'nullable',
|
||||||
];
|
'database.enable_ssl' => 'boolean',
|
||||||
|
'database.ssl_mode' => 'nullable|string|in:allow,prefer,require,verify-full',
|
||||||
|
];
|
||||||
|
}
|
||||||
|
|
||||||
|
protected function messages(): array
|
||||||
|
{
|
||||||
|
return array_merge(
|
||||||
|
ValidationPatterns::combinedMessages(),
|
||||||
|
[
|
||||||
|
'database.name.required' => 'The Name field is required.',
|
||||||
|
'database.name.regex' => 'The Name may only contain letters, numbers, spaces, dashes (-), underscores (_), dots (.), slashes (/), colons (:), and parentheses ().',
|
||||||
|
'database.description.regex' => 'The Description contains invalid characters. Only letters, numbers, spaces, and common punctuation (- _ . : / () \' " , ! ? @ # % & + = [] {} | ~ ` *) are allowed.',
|
||||||
|
'database.mongo_initdb_root_username.required' => 'The Root Username field is required.',
|
||||||
|
'database.mongo_initdb_root_password.required' => 'The Root Password field is required.',
|
||||||
|
'database.mongo_initdb_database.required' => 'The MongoDB Database field is required.',
|
||||||
|
'database.image.required' => 'The Docker Image field is required.',
|
||||||
|
'database.public_port.integer' => 'The Public Port must be an integer.',
|
||||||
|
'database.ssl_mode.in' => 'The SSL Mode must be one of: allow, prefer, require, verify-full.',
|
||||||
|
]
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
protected $validationAttributes = [
|
protected $validationAttributes = [
|
||||||
'database.name' => 'Name',
|
'database.name' => 'Name',
|
||||||
|
|||||||
@@ -8,6 +8,7 @@ use App\Helpers\SslHelper;
|
|||||||
use App\Models\Server;
|
use App\Models\Server;
|
||||||
use App\Models\SslCertificate;
|
use App\Models\SslCertificate;
|
||||||
use App\Models\StandaloneMysql;
|
use App\Models\StandaloneMysql;
|
||||||
|
use App\Support\ValidationPatterns;
|
||||||
use Carbon\Carbon;
|
use Carbon\Carbon;
|
||||||
use Exception;
|
use Exception;
|
||||||
use Illuminate\Support\Facades\Auth;
|
use Illuminate\Support\Facades\Auth;
|
||||||
@@ -37,23 +38,45 @@ class General extends Component
|
|||||||
];
|
];
|
||||||
}
|
}
|
||||||
|
|
||||||
protected $rules = [
|
protected function rules(): array
|
||||||
'database.name' => 'required',
|
{
|
||||||
'database.description' => 'nullable',
|
return [
|
||||||
'database.mysql_root_password' => 'required',
|
'database.name' => ValidationPatterns::nameRules(),
|
||||||
'database.mysql_user' => 'required',
|
'database.description' => ValidationPatterns::descriptionRules(),
|
||||||
'database.mysql_password' => 'required',
|
'database.mysql_root_password' => 'required',
|
||||||
'database.mysql_database' => 'required',
|
'database.mysql_user' => 'required',
|
||||||
'database.mysql_conf' => 'nullable',
|
'database.mysql_password' => 'required',
|
||||||
'database.image' => 'required',
|
'database.mysql_database' => 'required',
|
||||||
'database.ports_mappings' => 'nullable',
|
'database.mysql_conf' => 'nullable',
|
||||||
'database.is_public' => 'nullable|boolean',
|
'database.image' => 'required',
|
||||||
'database.public_port' => 'nullable|integer',
|
'database.ports_mappings' => 'nullable',
|
||||||
'database.is_log_drain_enabled' => 'nullable|boolean',
|
'database.is_public' => 'nullable|boolean',
|
||||||
'database.custom_docker_run_options' => 'nullable',
|
'database.public_port' => 'nullable|integer',
|
||||||
'database.enable_ssl' => 'boolean',
|
'database.is_log_drain_enabled' => 'nullable|boolean',
|
||||||
'database.ssl_mode' => 'nullable|string|in:PREFERRED,REQUIRED,VERIFY_CA,VERIFY_IDENTITY',
|
'database.custom_docker_run_options' => 'nullable',
|
||||||
];
|
'database.enable_ssl' => 'boolean',
|
||||||
|
'database.ssl_mode' => 'nullable|string|in:PREFERRED,REQUIRED,VERIFY_CA,VERIFY_IDENTITY',
|
||||||
|
];
|
||||||
|
}
|
||||||
|
|
||||||
|
protected function messages(): array
|
||||||
|
{
|
||||||
|
return array_merge(
|
||||||
|
ValidationPatterns::combinedMessages(),
|
||||||
|
[
|
||||||
|
'database.name.required' => 'The Name field is required.',
|
||||||
|
'database.name.regex' => 'The Name may only contain letters, numbers, spaces, dashes (-), underscores (_), dots (.), slashes (/), colons (:), and parentheses ().',
|
||||||
|
'database.description.regex' => 'The Description contains invalid characters. Only letters, numbers, spaces, and common punctuation (- _ . : / () \' " , ! ? @ # % & + = [] {} | ~ ` *) are allowed.',
|
||||||
|
'database.mysql_root_password.required' => 'The Root Password field is required.',
|
||||||
|
'database.mysql_user.required' => 'The MySQL User field is required.',
|
||||||
|
'database.mysql_password.required' => 'The MySQL Password field is required.',
|
||||||
|
'database.mysql_database.required' => 'The MySQL Database field is required.',
|
||||||
|
'database.image.required' => 'The Docker Image field is required.',
|
||||||
|
'database.public_port.integer' => 'The Public Port must be an integer.',
|
||||||
|
'database.ssl_mode.in' => 'The SSL Mode must be one of: PREFERRED, REQUIRED, VERIFY_CA, VERIFY_IDENTITY.',
|
||||||
|
]
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
protected $validationAttributes = [
|
protected $validationAttributes = [
|
||||||
'database.name' => 'Name',
|
'database.name' => 'Name',
|
||||||
|
|||||||
@@ -8,6 +8,7 @@ use App\Helpers\SslHelper;
|
|||||||
use App\Models\Server;
|
use App\Models\Server;
|
||||||
use App\Models\SslCertificate;
|
use App\Models\SslCertificate;
|
||||||
use App\Models\StandalonePostgresql;
|
use App\Models\StandalonePostgresql;
|
||||||
|
use App\Support\ValidationPatterns;
|
||||||
use Carbon\Carbon;
|
use Carbon\Carbon;
|
||||||
use Exception;
|
use Exception;
|
||||||
use Illuminate\Support\Facades\Auth;
|
use Illuminate\Support\Facades\Auth;
|
||||||
@@ -41,25 +42,46 @@ class General extends Component
|
|||||||
];
|
];
|
||||||
}
|
}
|
||||||
|
|
||||||
protected $rules = [
|
protected function rules(): array
|
||||||
'database.name' => 'required',
|
{
|
||||||
'database.description' => 'nullable',
|
return [
|
||||||
'database.postgres_user' => 'required',
|
'database.name' => ValidationPatterns::nameRules(),
|
||||||
'database.postgres_password' => 'required',
|
'database.description' => ValidationPatterns::descriptionRules(),
|
||||||
'database.postgres_db' => 'required',
|
'database.postgres_user' => 'required',
|
||||||
'database.postgres_initdb_args' => 'nullable',
|
'database.postgres_password' => 'required',
|
||||||
'database.postgres_host_auth_method' => 'nullable',
|
'database.postgres_db' => 'required',
|
||||||
'database.postgres_conf' => 'nullable',
|
'database.postgres_initdb_args' => 'nullable',
|
||||||
'database.init_scripts' => 'nullable',
|
'database.postgres_host_auth_method' => 'nullable',
|
||||||
'database.image' => 'required',
|
'database.postgres_conf' => 'nullable',
|
||||||
'database.ports_mappings' => 'nullable',
|
'database.init_scripts' => 'nullable',
|
||||||
'database.is_public' => 'nullable|boolean',
|
'database.image' => 'required',
|
||||||
'database.public_port' => 'nullable|integer',
|
'database.ports_mappings' => 'nullable',
|
||||||
'database.is_log_drain_enabled' => 'nullable|boolean',
|
'database.is_public' => 'nullable|boolean',
|
||||||
'database.custom_docker_run_options' => 'nullable',
|
'database.public_port' => 'nullable|integer',
|
||||||
'database.enable_ssl' => 'boolean',
|
'database.is_log_drain_enabled' => 'nullable|boolean',
|
||||||
'database.ssl_mode' => 'nullable|string|in:allow,prefer,require,verify-ca,verify-full',
|
'database.custom_docker_run_options' => 'nullable',
|
||||||
];
|
'database.enable_ssl' => 'boolean',
|
||||||
|
'database.ssl_mode' => 'nullable|string|in:allow,prefer,require,verify-ca,verify-full',
|
||||||
|
];
|
||||||
|
}
|
||||||
|
|
||||||
|
protected function messages(): array
|
||||||
|
{
|
||||||
|
return array_merge(
|
||||||
|
ValidationPatterns::combinedMessages(),
|
||||||
|
[
|
||||||
|
'database.name.required' => 'The Name field is required.',
|
||||||
|
'database.name.regex' => 'The Name may only contain letters, numbers, spaces, dashes (-), underscores (_), dots (.), slashes (/), colons (:), and parentheses ().',
|
||||||
|
'database.description.regex' => 'The Description contains invalid characters. Only letters, numbers, spaces, and common punctuation (- _ . : / () \' " , ! ? @ # % & + = [] {} | ~ ` *) are allowed.',
|
||||||
|
'database.postgres_user.required' => 'The Postgres User field is required.',
|
||||||
|
'database.postgres_password.required' => 'The Postgres Password field is required.',
|
||||||
|
'database.postgres_db.required' => 'The Postgres Database field is required.',
|
||||||
|
'database.image.required' => 'The Docker Image field is required.',
|
||||||
|
'database.public_port.integer' => 'The Public Port must be an integer.',
|
||||||
|
'database.ssl_mode.in' => 'The SSL Mode must be one of: allow, prefer, require, verify-ca, verify-full.',
|
||||||
|
]
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
protected $validationAttributes = [
|
protected $validationAttributes = [
|
||||||
'database.name' => 'Name',
|
'database.name' => 'Name',
|
||||||
|
|||||||
@@ -8,6 +8,7 @@ use App\Helpers\SslHelper;
|
|||||||
use App\Models\Server;
|
use App\Models\Server;
|
||||||
use App\Models\SslCertificate;
|
use App\Models\SslCertificate;
|
||||||
use App\Models\StandaloneRedis;
|
use App\Models\StandaloneRedis;
|
||||||
|
use App\Support\ValidationPatterns;
|
||||||
use Carbon\Carbon;
|
use Carbon\Carbon;
|
||||||
use Exception;
|
use Exception;
|
||||||
use Illuminate\Support\Facades\Auth;
|
use Illuminate\Support\Facades\Auth;
|
||||||
@@ -42,20 +43,39 @@ class General extends Component
|
|||||||
];
|
];
|
||||||
}
|
}
|
||||||
|
|
||||||
protected $rules = [
|
protected function rules(): array
|
||||||
'database.name' => 'required',
|
{
|
||||||
'database.description' => 'nullable',
|
return [
|
||||||
'database.redis_conf' => 'nullable',
|
'database.name' => ValidationPatterns::nameRules(),
|
||||||
'database.image' => 'required',
|
'database.description' => ValidationPatterns::descriptionRules(),
|
||||||
'database.ports_mappings' => 'nullable',
|
'database.redis_conf' => 'nullable',
|
||||||
'database.is_public' => 'nullable|boolean',
|
'database.image' => 'required',
|
||||||
'database.public_port' => 'nullable|integer',
|
'database.ports_mappings' => 'nullable',
|
||||||
'database.is_log_drain_enabled' => 'nullable|boolean',
|
'database.is_public' => 'nullable|boolean',
|
||||||
'database.custom_docker_run_options' => 'nullable',
|
'database.public_port' => 'nullable|integer',
|
||||||
'redis_username' => 'required',
|
'database.is_log_drain_enabled' => 'nullable|boolean',
|
||||||
'redis_password' => 'required',
|
'database.custom_docker_run_options' => 'nullable',
|
||||||
'database.enable_ssl' => 'boolean',
|
'redis_username' => 'required',
|
||||||
];
|
'redis_password' => 'required',
|
||||||
|
'database.enable_ssl' => 'boolean',
|
||||||
|
];
|
||||||
|
}
|
||||||
|
|
||||||
|
protected function messages(): array
|
||||||
|
{
|
||||||
|
return array_merge(
|
||||||
|
ValidationPatterns::combinedMessages(),
|
||||||
|
[
|
||||||
|
'database.name.required' => 'The Name field is required.',
|
||||||
|
'database.name.regex' => 'The Name may only contain letters, numbers, spaces, dashes (-), underscores (_), dots (.), slashes (/), colons (:), and parentheses ().',
|
||||||
|
'database.description.regex' => 'The Description contains invalid characters. Only letters, numbers, spaces, and common punctuation (- _ . : / () \' " , ! ? @ # % & + = [] {} | ~ ` *) are allowed.',
|
||||||
|
'database.image.required' => 'The Docker Image field is required.',
|
||||||
|
'database.public_port.integer' => 'The Public Port must be an integer.',
|
||||||
|
'redis_username.required' => 'The Redis Username field is required.',
|
||||||
|
'redis_password.required' => 'The Redis Password field is required.',
|
||||||
|
]
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
protected $validationAttributes = [
|
protected $validationAttributes = [
|
||||||
'database.name' => 'Name',
|
'database.name' => 'Name',
|
||||||
|
|||||||
@@ -3,6 +3,7 @@
|
|||||||
namespace App\Livewire\Project\Service;
|
namespace App\Livewire\Project\Service;
|
||||||
|
|
||||||
use App\Models\Service;
|
use App\Models\Service;
|
||||||
|
use App\Support\ValidationPatterns;
|
||||||
use Illuminate\Support\Collection;
|
use Illuminate\Support\Collection;
|
||||||
use Livewire\Component;
|
use Livewire\Component;
|
||||||
|
|
||||||
@@ -14,13 +15,38 @@ class StackForm extends Component
|
|||||||
|
|
||||||
protected $listeners = ['saveCompose'];
|
protected $listeners = ['saveCompose'];
|
||||||
|
|
||||||
public $rules = [
|
protected function rules(): array
|
||||||
'service.docker_compose_raw' => 'required',
|
{
|
||||||
'service.docker_compose' => 'required',
|
$baseRules = [
|
||||||
'service.name' => 'required',
|
'service.docker_compose_raw' => 'required',
|
||||||
'service.description' => 'nullable',
|
'service.docker_compose' => 'required',
|
||||||
'service.connect_to_docker_network' => 'nullable',
|
'service.name' => ValidationPatterns::nameRules(),
|
||||||
];
|
'service.description' => ValidationPatterns::descriptionRules(),
|
||||||
|
'service.connect_to_docker_network' => 'nullable',
|
||||||
|
];
|
||||||
|
|
||||||
|
// Add dynamic field rules
|
||||||
|
foreach ($this->fields ?? collect() as $key => $field) {
|
||||||
|
$rules = data_get($field, 'rules', 'nullable');
|
||||||
|
$baseRules["fields.$key.value"] = $rules;
|
||||||
|
}
|
||||||
|
|
||||||
|
return $baseRules;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected function messages(): array
|
||||||
|
{
|
||||||
|
return array_merge(
|
||||||
|
ValidationPatterns::combinedMessages(),
|
||||||
|
[
|
||||||
|
'service.name.required' => 'The Name field is required.',
|
||||||
|
'service.name.regex' => 'The Name may only contain letters, numbers, spaces, dashes (-), underscores (_), dots (.), slashes (/), colons (:), and parentheses ().',
|
||||||
|
'service.description.regex' => 'The Description contains invalid characters. Only letters, numbers, spaces, and common punctuation (- _ . : / () \' " , ! ? @ # % & + = [] {} | ~ ` *) are allowed.',
|
||||||
|
'service.docker_compose_raw.required' => 'The Docker Compose Raw field is required.',
|
||||||
|
'service.docker_compose.required' => 'The Docker Compose field is required.',
|
||||||
|
]
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
public $validationAttributes = [];
|
public $validationAttributes = [];
|
||||||
|
|
||||||
@@ -45,7 +71,6 @@ class StackForm extends Component
|
|||||||
'customHelper' => $customHelper,
|
'customHelper' => $customHelper,
|
||||||
]);
|
]);
|
||||||
|
|
||||||
$this->rules["fields.$key.value"] = $rules;
|
|
||||||
$this->validationAttributes["fields.$key.value"] = $fieldKey;
|
$this->validationAttributes["fields.$key.value"] = $fieldKey;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -3,6 +3,7 @@
|
|||||||
namespace App\Livewire\Security\PrivateKey;
|
namespace App\Livewire\Security\PrivateKey;
|
||||||
|
|
||||||
use App\Models\PrivateKey;
|
use App\Models\PrivateKey;
|
||||||
|
use App\Support\ValidationPatterns;
|
||||||
use Livewire\Component;
|
use Livewire\Component;
|
||||||
|
|
||||||
class Create extends Component
|
class Create extends Component
|
||||||
@@ -17,10 +18,25 @@ class Create extends Component
|
|||||||
|
|
||||||
public ?string $publicKey = null;
|
public ?string $publicKey = null;
|
||||||
|
|
||||||
protected $rules = [
|
protected function rules(): array
|
||||||
'name' => 'required|string',
|
{
|
||||||
'value' => 'required|string',
|
return [
|
||||||
];
|
'name' => ValidationPatterns::nameRules(),
|
||||||
|
'description' => ValidationPatterns::descriptionRules(),
|
||||||
|
'value' => 'required|string',
|
||||||
|
];
|
||||||
|
}
|
||||||
|
|
||||||
|
protected function messages(): array
|
||||||
|
{
|
||||||
|
return array_merge(
|
||||||
|
ValidationPatterns::combinedMessages(),
|
||||||
|
[
|
||||||
|
'value.required' => 'The Private Key field is required.',
|
||||||
|
'value.string' => 'The Private Key must be a valid string.',
|
||||||
|
]
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
public function generateNewRSAKey()
|
public function generateNewRSAKey()
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -3,6 +3,7 @@
|
|||||||
namespace App\Livewire\Security\PrivateKey;
|
namespace App\Livewire\Security\PrivateKey;
|
||||||
|
|
||||||
use App\Models\PrivateKey;
|
use App\Models\PrivateKey;
|
||||||
|
use App\Support\ValidationPatterns;
|
||||||
use Livewire\Component;
|
use Livewire\Component;
|
||||||
|
|
||||||
class Show extends Component
|
class Show extends Component
|
||||||
@@ -11,12 +12,29 @@ class Show extends Component
|
|||||||
|
|
||||||
public $public_key = 'Loading...';
|
public $public_key = 'Loading...';
|
||||||
|
|
||||||
protected $rules = [
|
protected function rules(): array
|
||||||
'private_key.name' => 'required|string',
|
{
|
||||||
'private_key.description' => 'nullable|string',
|
return [
|
||||||
'private_key.private_key' => 'required|string',
|
'private_key.name' => ValidationPatterns::nameRules(),
|
||||||
'private_key.is_git_related' => 'nullable|boolean',
|
'private_key.description' => ValidationPatterns::descriptionRules(),
|
||||||
];
|
'private_key.private_key' => 'required|string',
|
||||||
|
'private_key.is_git_related' => 'nullable|boolean',
|
||||||
|
];
|
||||||
|
}
|
||||||
|
|
||||||
|
protected function messages(): array
|
||||||
|
{
|
||||||
|
return array_merge(
|
||||||
|
ValidationPatterns::combinedMessages(),
|
||||||
|
[
|
||||||
|
'private_key.name.required' => 'The Name field is required.',
|
||||||
|
'private_key.name.regex' => 'The Name may only contain letters, numbers, spaces, dashes (-), underscores (_), dots (.), slashes (/), colons (:), and parentheses ().',
|
||||||
|
'private_key.description.regex' => 'The Description contains invalid characters. Only letters, numbers, spaces, and common punctuation (- _ . : / () \' " , ! ? @ # % & + = [] {} | ~ ` *) are allowed.',
|
||||||
|
'private_key.private_key.required' => 'The Private Key field is required.',
|
||||||
|
'private_key.private_key.string' => 'The Private Key must be a valid string.',
|
||||||
|
]
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
protected $validationAttributes = [
|
protected $validationAttributes = [
|
||||||
'private_key.name' => 'name',
|
'private_key.name' => 'name',
|
||||||
|
|||||||
@@ -5,9 +5,9 @@ namespace App\Livewire\Server\New;
|
|||||||
use App\Enums\ProxyTypes;
|
use App\Enums\ProxyTypes;
|
||||||
use App\Models\Server;
|
use App\Models\Server;
|
||||||
use App\Models\Team;
|
use App\Models\Team;
|
||||||
|
use App\Support\ValidationPatterns;
|
||||||
use Illuminate\Support\Collection;
|
use Illuminate\Support\Collection;
|
||||||
use Livewire\Attributes\Locked;
|
use Livewire\Attributes\Locked;
|
||||||
use Livewire\Attributes\Validate;
|
|
||||||
use Livewire\Component;
|
use Livewire\Component;
|
||||||
|
|
||||||
class ByIp extends Component
|
class ByIp extends Component
|
||||||
@@ -18,43 +18,30 @@ class ByIp extends Component
|
|||||||
#[Locked]
|
#[Locked]
|
||||||
public $limit_reached;
|
public $limit_reached;
|
||||||
|
|
||||||
#[Validate('nullable|integer', as: 'Private Key')]
|
|
||||||
public ?int $private_key_id = null;
|
public ?int $private_key_id = null;
|
||||||
|
|
||||||
#[Validate('nullable|string', as: 'Private Key Name')]
|
|
||||||
public $new_private_key_name;
|
public $new_private_key_name;
|
||||||
|
|
||||||
#[Validate('nullable|string', as: 'Private Key Description')]
|
|
||||||
public $new_private_key_description;
|
public $new_private_key_description;
|
||||||
|
|
||||||
#[Validate('nullable|string', as: 'Private Key Value')]
|
|
||||||
public $new_private_key_value;
|
public $new_private_key_value;
|
||||||
|
|
||||||
#[Validate('required|string', as: 'Name')]
|
|
||||||
public string $name;
|
public string $name;
|
||||||
|
|
||||||
#[Validate('nullable|string', as: 'Description')]
|
|
||||||
public ?string $description = null;
|
public ?string $description = null;
|
||||||
|
|
||||||
#[Validate('required|string', as: 'IP Address/Domain')]
|
|
||||||
public string $ip;
|
public string $ip;
|
||||||
|
|
||||||
#[Validate('required|string', as: 'User')]
|
|
||||||
public string $user = 'root';
|
public string $user = 'root';
|
||||||
|
|
||||||
#[Validate('required|integer|between:1,65535', as: 'Port')]
|
|
||||||
public int $port = 22;
|
public int $port = 22;
|
||||||
|
|
||||||
#[Validate('required|boolean', as: 'Swarm Manager')]
|
|
||||||
public bool $is_swarm_manager = false;
|
public bool $is_swarm_manager = false;
|
||||||
|
|
||||||
#[Validate('required|boolean', as: 'Swarm Worker')]
|
|
||||||
public bool $is_swarm_worker = false;
|
public bool $is_swarm_worker = false;
|
||||||
|
|
||||||
#[Validate('nullable|integer', as: 'Swarm Cluster')]
|
|
||||||
public $selected_swarm_cluster = null;
|
public $selected_swarm_cluster = null;
|
||||||
|
|
||||||
#[Validate('required|boolean', as: 'Build Server')]
|
|
||||||
public bool $is_build_server = false;
|
public bool $is_build_server = false;
|
||||||
|
|
||||||
#[Locked]
|
#[Locked]
|
||||||
@@ -70,6 +57,50 @@ class ByIp extends Component
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
protected function rules(): array
|
||||||
|
{
|
||||||
|
return [
|
||||||
|
'private_key_id' => 'nullable|integer',
|
||||||
|
'new_private_key_name' => 'nullable|string',
|
||||||
|
'new_private_key_description' => 'nullable|string',
|
||||||
|
'new_private_key_value' => 'nullable|string',
|
||||||
|
'name' => ValidationPatterns::nameRules(),
|
||||||
|
'description' => ValidationPatterns::descriptionRules(),
|
||||||
|
'ip' => 'required|string',
|
||||||
|
'user' => 'required|string',
|
||||||
|
'port' => 'required|integer|between:1,65535',
|
||||||
|
'is_swarm_manager' => 'required|boolean',
|
||||||
|
'is_swarm_worker' => 'required|boolean',
|
||||||
|
'selected_swarm_cluster' => 'nullable|integer',
|
||||||
|
'is_build_server' => 'required|boolean',
|
||||||
|
];
|
||||||
|
}
|
||||||
|
|
||||||
|
protected function messages(): array
|
||||||
|
{
|
||||||
|
return array_merge(ValidationPatterns::combinedMessages(), [
|
||||||
|
'private_key_id.integer' => 'The Private Key field must be an integer.',
|
||||||
|
'private_key_id.nullable' => 'The Private Key field is optional.',
|
||||||
|
'new_private_key_name.string' => 'The Private Key Name must be a string.',
|
||||||
|
'new_private_key_description.string' => 'The Private Key Description must be a string.',
|
||||||
|
'new_private_key_value.string' => 'The Private Key Value must be a string.',
|
||||||
|
'ip.required' => 'The IP Address/Domain is required.',
|
||||||
|
'ip.string' => 'The IP Address/Domain must be a string.',
|
||||||
|
'user.required' => 'The User field is required.',
|
||||||
|
'user.string' => 'The User field must be a string.',
|
||||||
|
'port.required' => 'The Port field is required.',
|
||||||
|
'port.integer' => 'The Port field must be an integer.',
|
||||||
|
'port.between' => 'The Port field must be between 1 and 65535.',
|
||||||
|
'is_swarm_manager.required' => 'The Swarm Manager field is required.',
|
||||||
|
'is_swarm_manager.boolean' => 'The Swarm Manager field must be true or false.',
|
||||||
|
'is_swarm_worker.required' => 'The Swarm Worker field is required.',
|
||||||
|
'is_swarm_worker.boolean' => 'The Swarm Worker field must be true or false.',
|
||||||
|
'selected_swarm_cluster.integer' => 'The Swarm Cluster field must be an integer.',
|
||||||
|
'is_build_server.required' => 'The Build Server field is required.',
|
||||||
|
'is_build_server.boolean' => 'The Build Server field must be true or false.',
|
||||||
|
]);
|
||||||
|
}
|
||||||
|
|
||||||
public function setPrivateKey(string $private_key_id)
|
public function setPrivateKey(string $private_key_id)
|
||||||
{
|
{
|
||||||
$this->private_key_id = $private_key_id;
|
$this->private_key_id = $private_key_id;
|
||||||
|
|||||||
@@ -6,82 +6,60 @@ use App\Actions\Server\StartSentinel;
|
|||||||
use App\Actions\Server\StopSentinel;
|
use App\Actions\Server\StopSentinel;
|
||||||
use App\Events\ServerReachabilityChanged;
|
use App\Events\ServerReachabilityChanged;
|
||||||
use App\Models\Server;
|
use App\Models\Server;
|
||||||
|
use App\Support\ValidationPatterns;
|
||||||
use Livewire\Attributes\Computed;
|
use Livewire\Attributes\Computed;
|
||||||
use Livewire\Attributes\Locked;
|
use Livewire\Attributes\Locked;
|
||||||
use Livewire\Attributes\Validate;
|
|
||||||
use Livewire\Component;
|
use Livewire\Component;
|
||||||
|
|
||||||
class Show extends Component
|
class Show extends Component
|
||||||
{
|
{
|
||||||
public Server $server;
|
public Server $server;
|
||||||
|
|
||||||
#[Validate(['required'])]
|
|
||||||
public string $name;
|
public string $name;
|
||||||
|
|
||||||
#[Validate(['nullable'])]
|
|
||||||
public ?string $description = null;
|
public ?string $description = null;
|
||||||
|
|
||||||
#[Validate(['required'])]
|
|
||||||
public string $ip;
|
public string $ip;
|
||||||
|
|
||||||
#[Validate(['required'])]
|
|
||||||
public string $user;
|
public string $user;
|
||||||
|
|
||||||
#[Validate(['required'])]
|
|
||||||
public string $port;
|
public string $port;
|
||||||
|
|
||||||
#[Validate(['nullable'])]
|
|
||||||
public ?string $validationLogs = null;
|
public ?string $validationLogs = null;
|
||||||
|
|
||||||
#[Validate(['nullable', 'url'])]
|
|
||||||
public ?string $wildcardDomain = null;
|
public ?string $wildcardDomain = null;
|
||||||
|
|
||||||
#[Validate(['required'])]
|
|
||||||
public bool $isReachable;
|
public bool $isReachable;
|
||||||
|
|
||||||
#[Validate(['required'])]
|
|
||||||
public bool $isUsable;
|
public bool $isUsable;
|
||||||
|
|
||||||
#[Validate(['required'])]
|
|
||||||
public bool $isSwarmManager;
|
public bool $isSwarmManager;
|
||||||
|
|
||||||
#[Validate(['required'])]
|
|
||||||
public bool $isSwarmWorker;
|
public bool $isSwarmWorker;
|
||||||
|
|
||||||
#[Validate(['required'])]
|
|
||||||
public bool $isBuildServer;
|
public bool $isBuildServer;
|
||||||
|
|
||||||
#[Locked]
|
#[Locked]
|
||||||
public bool $isBuildServerLocked = false;
|
public bool $isBuildServerLocked = false;
|
||||||
|
|
||||||
#[Validate(['required'])]
|
|
||||||
public bool $isMetricsEnabled;
|
public bool $isMetricsEnabled;
|
||||||
|
|
||||||
#[Validate(['required'])]
|
|
||||||
public string $sentinelToken;
|
public string $sentinelToken;
|
||||||
|
|
||||||
#[Validate(['nullable'])]
|
|
||||||
public ?string $sentinelUpdatedAt = null;
|
public ?string $sentinelUpdatedAt = null;
|
||||||
|
|
||||||
#[Validate(['required', 'integer', 'min:1'])]
|
|
||||||
public int $sentinelMetricsRefreshRateSeconds;
|
public int $sentinelMetricsRefreshRateSeconds;
|
||||||
|
|
||||||
#[Validate(['required', 'integer', 'min:1'])]
|
|
||||||
public int $sentinelMetricsHistoryDays;
|
public int $sentinelMetricsHistoryDays;
|
||||||
|
|
||||||
#[Validate(['required', 'integer', 'min:10'])]
|
|
||||||
public int $sentinelPushIntervalSeconds;
|
public int $sentinelPushIntervalSeconds;
|
||||||
|
|
||||||
#[Validate(['nullable', 'url'])]
|
|
||||||
public ?string $sentinelCustomUrl = null;
|
public ?string $sentinelCustomUrl = null;
|
||||||
|
|
||||||
#[Validate(['required'])]
|
|
||||||
public bool $isSentinelEnabled;
|
public bool $isSentinelEnabled;
|
||||||
|
|
||||||
#[Validate(['required'])]
|
|
||||||
public bool $isSentinelDebugEnabled;
|
public bool $isSentinelDebugEnabled;
|
||||||
|
|
||||||
#[Validate(['required'])]
|
|
||||||
public string $serverTimezone;
|
public string $serverTimezone;
|
||||||
|
|
||||||
public function getListeners()
|
public function getListeners()
|
||||||
@@ -91,6 +69,59 @@ class Show extends Component
|
|||||||
];
|
];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
protected function rules(): array
|
||||||
|
{
|
||||||
|
return [
|
||||||
|
'name' => ValidationPatterns::nameRules(),
|
||||||
|
'description' => ValidationPatterns::descriptionRules(),
|
||||||
|
'ip' => 'required',
|
||||||
|
'user' => 'required',
|
||||||
|
'port' => 'required',
|
||||||
|
'validationLogs' => 'nullable',
|
||||||
|
'wildcardDomain' => 'nullable|url',
|
||||||
|
'isReachable' => 'required',
|
||||||
|
'isUsable' => 'required',
|
||||||
|
'isSwarmManager' => 'required',
|
||||||
|
'isSwarmWorker' => 'required',
|
||||||
|
'isBuildServer' => 'required',
|
||||||
|
'isMetricsEnabled' => 'required',
|
||||||
|
'sentinelToken' => 'required',
|
||||||
|
'sentinelUpdatedAt' => 'nullable',
|
||||||
|
'sentinelMetricsRefreshRateSeconds' => 'required|integer|min:1',
|
||||||
|
'sentinelMetricsHistoryDays' => 'required|integer|min:1',
|
||||||
|
'sentinelPushIntervalSeconds' => 'required|integer|min:10',
|
||||||
|
'sentinelCustomUrl' => 'nullable|url',
|
||||||
|
'isSentinelEnabled' => 'required',
|
||||||
|
'isSentinelDebugEnabled' => 'required',
|
||||||
|
'serverTimezone' => 'required',
|
||||||
|
];
|
||||||
|
}
|
||||||
|
|
||||||
|
protected function messages(): array
|
||||||
|
{
|
||||||
|
return array_merge(
|
||||||
|
ValidationPatterns::combinedMessages(),
|
||||||
|
[
|
||||||
|
'ip.required' => 'The IP Address field is required.',
|
||||||
|
'user.required' => 'The User field is required.',
|
||||||
|
'port.required' => 'The Port field is required.',
|
||||||
|
'wildcardDomain.url' => 'The Wildcard Domain must be a valid URL.',
|
||||||
|
'sentinelToken.required' => 'The Sentinel Token field is required.',
|
||||||
|
'sentinelMetricsRefreshRateSeconds.required' => 'The Metrics Refresh Rate field is required.',
|
||||||
|
'sentinelMetricsRefreshRateSeconds.integer' => 'The Metrics Refresh Rate must be an integer.',
|
||||||
|
'sentinelMetricsRefreshRateSeconds.min' => 'The Metrics Refresh Rate must be at least 1 second.',
|
||||||
|
'sentinelMetricsHistoryDays.required' => 'The Metrics History Days field is required.',
|
||||||
|
'sentinelMetricsHistoryDays.integer' => 'The Metrics History Days must be an integer.',
|
||||||
|
'sentinelMetricsHistoryDays.min' => 'The Metrics History Days must be at least 1 day.',
|
||||||
|
'sentinelPushIntervalSeconds.required' => 'The Push Interval field is required.',
|
||||||
|
'sentinelPushIntervalSeconds.integer' => 'The Push Interval must be an integer.',
|
||||||
|
'sentinelPushIntervalSeconds.min' => 'The Push Interval must be at least 10 seconds.',
|
||||||
|
'sentinelCustomUrl.url' => 'The Custom Sentinel URL must be a valid URL.',
|
||||||
|
'serverTimezone.required' => 'The Server Timezone field is required.',
|
||||||
|
]
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
public function mount(string $server_uuid)
|
public function mount(string $server_uuid)
|
||||||
{
|
{
|
||||||
try {
|
try {
|
||||||
|
|||||||
@@ -3,6 +3,7 @@
|
|||||||
namespace App\Livewire\Storage;
|
namespace App\Livewire\Storage;
|
||||||
|
|
||||||
use App\Models\S3Storage;
|
use App\Models\S3Storage;
|
||||||
|
use App\Support\ValidationPatterns;
|
||||||
use Illuminate\Support\Uri;
|
use Illuminate\Support\Uri;
|
||||||
use Livewire\Component;
|
use Livewire\Component;
|
||||||
|
|
||||||
@@ -24,15 +25,38 @@ class Create extends Component
|
|||||||
|
|
||||||
public S3Storage $storage;
|
public S3Storage $storage;
|
||||||
|
|
||||||
protected $rules = [
|
protected function rules(): array
|
||||||
'name' => 'required|min:3|max:255',
|
{
|
||||||
'description' => 'nullable|min:3|max:255',
|
return [
|
||||||
'region' => 'required|max:255',
|
'name' => ValidationPatterns::nameRules(),
|
||||||
'key' => 'required|max:255',
|
'description' => ValidationPatterns::descriptionRules(),
|
||||||
'secret' => 'required|max:255',
|
'region' => 'required|max:255',
|
||||||
'bucket' => 'required|max:255',
|
'key' => 'required|max:255',
|
||||||
'endpoint' => 'required|url|max:255',
|
'secret' => 'required|max:255',
|
||||||
];
|
'bucket' => 'required|max:255',
|
||||||
|
'endpoint' => 'required|url|max:255',
|
||||||
|
];
|
||||||
|
}
|
||||||
|
|
||||||
|
protected function messages(): array
|
||||||
|
{
|
||||||
|
return array_merge(
|
||||||
|
ValidationPatterns::combinedMessages(),
|
||||||
|
[
|
||||||
|
'region.required' => 'The Region field is required.',
|
||||||
|
'region.max' => 'The Region may not be greater than 255 characters.',
|
||||||
|
'key.required' => 'The Access Key field is required.',
|
||||||
|
'key.max' => 'The Access Key may not be greater than 255 characters.',
|
||||||
|
'secret.required' => 'The Secret Key field is required.',
|
||||||
|
'secret.max' => 'The Secret Key may not be greater than 255 characters.',
|
||||||
|
'bucket.required' => 'The Bucket field is required.',
|
||||||
|
'bucket.max' => 'The Bucket may not be greater than 255 characters.',
|
||||||
|
'endpoint.required' => 'The Endpoint field is required.',
|
||||||
|
'endpoint.url' => 'The Endpoint must be a valid URL.',
|
||||||
|
'endpoint.max' => 'The Endpoint may not be greater than 255 characters.',
|
||||||
|
]
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
protected $validationAttributes = [
|
protected $validationAttributes = [
|
||||||
'name' => 'Name',
|
'name' => 'Name',
|
||||||
|
|||||||
@@ -3,22 +3,48 @@
|
|||||||
namespace App\Livewire\Storage;
|
namespace App\Livewire\Storage;
|
||||||
|
|
||||||
use App\Models\S3Storage;
|
use App\Models\S3Storage;
|
||||||
|
use App\Support\ValidationPatterns;
|
||||||
use Livewire\Component;
|
use Livewire\Component;
|
||||||
|
|
||||||
class Form extends Component
|
class Form extends Component
|
||||||
{
|
{
|
||||||
public S3Storage $storage;
|
public S3Storage $storage;
|
||||||
|
|
||||||
protected $rules = [
|
protected function rules(): array
|
||||||
'storage.is_usable' => 'nullable|boolean',
|
{
|
||||||
'storage.name' => 'nullable|min:3|max:255',
|
return [
|
||||||
'storage.description' => 'nullable|min:3|max:255',
|
'storage.is_usable' => 'nullable|boolean',
|
||||||
'storage.region' => 'required|max:255',
|
'storage.name' => ValidationPatterns::nameRules(required: false),
|
||||||
'storage.key' => 'required|max:255',
|
'storage.description' => ValidationPatterns::descriptionRules(),
|
||||||
'storage.secret' => 'required|max:255',
|
'storage.region' => 'required|max:255',
|
||||||
'storage.bucket' => 'required|max:255',
|
'storage.key' => 'required|max:255',
|
||||||
'storage.endpoint' => 'required|url|max:255',
|
'storage.secret' => 'required|max:255',
|
||||||
];
|
'storage.bucket' => 'required|max:255',
|
||||||
|
'storage.endpoint' => 'required|url|max:255',
|
||||||
|
];
|
||||||
|
}
|
||||||
|
|
||||||
|
protected function messages(): array
|
||||||
|
{
|
||||||
|
return array_merge(
|
||||||
|
ValidationPatterns::combinedMessages(),
|
||||||
|
[
|
||||||
|
'storage.name.regex' => 'The Name may only contain letters, numbers, spaces, dashes (-), underscores (_), dots (.), slashes (/), colons (:), and parentheses ().',
|
||||||
|
'storage.description.regex' => 'The Description contains invalid characters. Only letters, numbers, spaces, and common punctuation (- _ . : / () \' " , ! ? @ # % & + = [] {} | ~ ` *) are allowed.',
|
||||||
|
'storage.region.required' => 'The Region field is required.',
|
||||||
|
'storage.region.max' => 'The Region may not be greater than 255 characters.',
|
||||||
|
'storage.key.required' => 'The Access Key field is required.',
|
||||||
|
'storage.key.max' => 'The Access Key may not be greater than 255 characters.',
|
||||||
|
'storage.secret.required' => 'The Secret Key field is required.',
|
||||||
|
'storage.secret.max' => 'The Secret Key may not be greater than 255 characters.',
|
||||||
|
'storage.bucket.required' => 'The Bucket field is required.',
|
||||||
|
'storage.bucket.max' => 'The Bucket may not be greater than 255 characters.',
|
||||||
|
'storage.endpoint.required' => 'The Endpoint field is required.',
|
||||||
|
'storage.endpoint.url' => 'The Endpoint must be a valid URL.',
|
||||||
|
'storage.endpoint.max' => 'The Endpoint may not be greater than 255 characters.',
|
||||||
|
]
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
protected $validationAttributes = [
|
protected $validationAttributes = [
|
||||||
'storage.is_usable' => 'Is Usable',
|
'storage.is_usable' => 'Is Usable',
|
||||||
|
|||||||
@@ -3,17 +3,28 @@
|
|||||||
namespace App\Livewire\Team;
|
namespace App\Livewire\Team;
|
||||||
|
|
||||||
use App\Models\Team;
|
use App\Models\Team;
|
||||||
use Livewire\Attributes\Validate;
|
use App\Support\ValidationPatterns;
|
||||||
use Livewire\Component;
|
use Livewire\Component;
|
||||||
|
|
||||||
class Create extends Component
|
class Create extends Component
|
||||||
{
|
{
|
||||||
#[Validate(['required', 'min:3', 'max:255'])]
|
|
||||||
public string $name = '';
|
public string $name = '';
|
||||||
|
|
||||||
#[Validate(['nullable', 'min:3', 'max:255'])]
|
|
||||||
public ?string $description = null;
|
public ?string $description = null;
|
||||||
|
|
||||||
|
protected function rules(): array
|
||||||
|
{
|
||||||
|
return [
|
||||||
|
'name' => ValidationPatterns::nameRules(),
|
||||||
|
'description' => ValidationPatterns::descriptionRules(),
|
||||||
|
];
|
||||||
|
}
|
||||||
|
|
||||||
|
protected function messages(): array
|
||||||
|
{
|
||||||
|
return ValidationPatterns::combinedMessages();
|
||||||
|
}
|
||||||
|
|
||||||
public function submit()
|
public function submit()
|
||||||
{
|
{
|
||||||
try {
|
try {
|
||||||
|
|||||||
@@ -4,6 +4,7 @@ namespace App\Livewire\Team;
|
|||||||
|
|
||||||
use App\Models\Team;
|
use App\Models\Team;
|
||||||
use App\Models\TeamInvitation;
|
use App\Models\TeamInvitation;
|
||||||
|
use App\Support\ValidationPatterns;
|
||||||
use Illuminate\Support\Facades\Auth;
|
use Illuminate\Support\Facades\Auth;
|
||||||
use Illuminate\Support\Facades\DB;
|
use Illuminate\Support\Facades\DB;
|
||||||
use Livewire\Component;
|
use Livewire\Component;
|
||||||
@@ -14,10 +15,25 @@ class Index extends Component
|
|||||||
|
|
||||||
public Team $team;
|
public Team $team;
|
||||||
|
|
||||||
protected $rules = [
|
protected function rules(): array
|
||||||
'team.name' => 'required|min:3|max:255',
|
{
|
||||||
'team.description' => 'nullable|min:3|max:255',
|
return [
|
||||||
];
|
'team.name' => ValidationPatterns::nameRules(),
|
||||||
|
'team.description' => ValidationPatterns::descriptionRules(),
|
||||||
|
];
|
||||||
|
}
|
||||||
|
|
||||||
|
protected function messages(): array
|
||||||
|
{
|
||||||
|
return array_merge(
|
||||||
|
ValidationPatterns::combinedMessages(),
|
||||||
|
[
|
||||||
|
'team.name.required' => 'The Name field is required.',
|
||||||
|
'team.name.regex' => 'The Name may only contain letters, numbers, spaces, dashes (-), underscores (_), dots (.), slashes (/), colons (:), and parentheses ().',
|
||||||
|
'team.description.regex' => 'The Description contains invalid characters. Only letters, numbers, spaces, and common punctuation (- _ . : / () \' " , ! ? @ # % & + = [] {} | ~ ` *) are allowed.',
|
||||||
|
]
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
protected $validationAttributes = [
|
protected $validationAttributes = [
|
||||||
'team.name' => 'name',
|
'team.name' => 'name',
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
<div>
|
<div>
|
||||||
<div class="pb-0 subtitle">
|
<div class="pb-2 subtitle">
|
||||||
<div>Private Keys are used to connect to your servers without passwords.</div>
|
<div>Private Keys are used to connect to your servers without passwords.</div>
|
||||||
<div class="font-bold">You should not use passphrase protected keys.</div>
|
<div class="font-bold">You should not use passphrase protected keys.</div>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
Reference in New Issue
Block a user