guest_downloads_enabled = (bool) $settings->guest_downloads_enabled; $this->guest_sharing_enabled = (bool) $settings->guest_sharing_enabled; $this->guest_upload_visibility = $settings->guest_upload_visibility ?? 'review'; $this->per_device_upload_limit = (int) ($settings->per_device_upload_limit ?? 50); $this->join_token_failure_limit = (int) ($settings->join_token_failure_limit ?? 10); $this->join_token_failure_decay_minutes = (int) ($settings->join_token_failure_decay_minutes ?? 5); $this->join_token_access_limit = (int) ($settings->join_token_access_limit ?? 120); $this->join_token_access_decay_minutes = (int) ($settings->join_token_access_decay_minutes ?? 1); $this->join_token_download_limit = (int) ($settings->join_token_download_limit ?? 60); $this->join_token_download_decay_minutes = (int) ($settings->join_token_download_decay_minutes ?? 1); $this->share_link_ttl_hours = (int) ($settings->share_link_ttl_hours ?? 48); $this->guest_notification_ttl_hours = $settings->guest_notification_ttl_hours; } public function form(Schema $schema): Schema { return $schema->schema([ Section::make(__('admin.guest_policy.sections.toggles')) ->schema([ Forms\Components\Toggle::make('guest_downloads_enabled') ->label(__('admin.guest_policy.fields.guest_downloads_enabled')), Forms\Components\Toggle::make('guest_sharing_enabled') ->label(__('admin.guest_policy.fields.guest_sharing_enabled')), Forms\Components\Select::make('guest_upload_visibility') ->label(__('admin.guest_policy.fields.guest_upload_visibility')) ->options([ 'review' => __('admin.guest_policy.fields.upload_visibility_review'), 'immediate' => __('admin.guest_policy.fields.upload_visibility_immediate'), ]) ->required(), ]) ->columns(2), Section::make(__('admin.guest_policy.sections.rate_limits')) ->schema([ Forms\Components\TextInput::make('per_device_upload_limit') ->label(__('admin.guest_policy.fields.per_device_upload_limit')) ->numeric() ->minValue(0) ->helperText(__('admin.guest_policy.help.zero_disables')), Forms\Components\TextInput::make('join_token_failure_limit') ->label(__('admin.guest_policy.fields.join_token_failure_limit')) ->numeric() ->minValue(1), Forms\Components\TextInput::make('join_token_failure_decay_minutes') ->label(__('admin.guest_policy.fields.join_token_failure_decay_minutes')) ->numeric() ->minValue(1), Forms\Components\TextInput::make('join_token_access_limit') ->label(__('admin.guest_policy.fields.join_token_access_limit')) ->numeric() ->minValue(0) ->helperText(__('admin.guest_policy.help.zero_disables')), Forms\Components\TextInput::make('join_token_access_decay_minutes') ->label(__('admin.guest_policy.fields.join_token_access_decay_minutes')) ->numeric() ->minValue(1), Forms\Components\TextInput::make('join_token_download_limit') ->label(__('admin.guest_policy.fields.join_token_download_limit')) ->numeric() ->minValue(0) ->helperText(__('admin.guest_policy.help.zero_disables')), Forms\Components\TextInput::make('join_token_download_decay_minutes') ->label(__('admin.guest_policy.fields.join_token_download_decay_minutes')) ->numeric() ->minValue(1), ]) ->columns(2), Section::make(__('admin.guest_policy.sections.retention')) ->schema([ Forms\Components\TextInput::make('share_link_ttl_hours') ->label(__('admin.guest_policy.fields.share_link_ttl_hours')) ->numeric() ->minValue(1), Forms\Components\TextInput::make('guest_notification_ttl_hours') ->label(__('admin.guest_policy.fields.guest_notification_ttl_hours')) ->numeric() ->minValue(1) ->nullable() ->helperText(__('admin.guest_policy.help.notification_ttl')), ]) ->columns(2), ]); } public function save(): void { $this->validate(); $settings = GuestPolicySetting::query()->firstOrNew(['id' => 1]); $settings->guest_downloads_enabled = (bool) $this->guest_downloads_enabled; $settings->guest_sharing_enabled = (bool) $this->guest_sharing_enabled; $settings->guest_upload_visibility = $this->guest_upload_visibility; $settings->per_device_upload_limit = (int) $this->per_device_upload_limit; $settings->join_token_failure_limit = (int) $this->join_token_failure_limit; $settings->join_token_failure_decay_minutes = (int) $this->join_token_failure_decay_minutes; $settings->join_token_access_limit = (int) $this->join_token_access_limit; $settings->join_token_access_decay_minutes = (int) $this->join_token_access_decay_minutes; $settings->join_token_download_limit = (int) $this->join_token_download_limit; $settings->join_token_download_decay_minutes = (int) $this->join_token_download_decay_minutes; $settings->share_link_ttl_hours = (int) $this->share_link_ttl_hours; $settings->guest_notification_ttl_hours = $this->guest_notification_ttl_hours; $settings->save(); app(SuperAdminAuditLogger::class)->record( 'guest_policy.updated', $settings, SuperAdminAuditLogger::fieldsMetadata([ 'guest_downloads_enabled', 'guest_sharing_enabled', 'guest_upload_visibility', 'per_device_upload_limit', 'join_token_failure_limit', 'join_token_failure_decay_minutes', 'join_token_access_limit', 'join_token_access_decay_minutes', 'join_token_download_limit', 'join_token_download_decay_minutes', 'share_link_ttl_hours', 'guest_notification_ttl_hours', ]), source: static::class ); Notification::make() ->title(__('admin.guest_policy.notifications.saved')) ->success() ->send(); } }