Weave Code
Code Weaver
Helps Laravel developers discover, compare, and choose open-source packages. See popularity, security, maintainers, and scores at a glance to make better decisions.
Feedback
Share your thoughts, report bugs, or suggest improvements.
Subject
Message

Web Terminal Laravel Package

mwguerra/web-terminal

View on GitHub
Deep Wiki
Context7

Getting Started

Minimal Setup

  1. Installation:

    composer require mwguerra/web-terminal
    php artisan vendor:publish --provider="Mwguerra\WebTerminal\WebTerminalServiceProvider" --tag="web-terminal-config"
    php artisan migrate
    
  2. Basic Configuration:

    • Edit config/web-terminal.php to define:
      • Allowed commands (e.g., ['ls', 'pwd', 'php artisan'])
      • SSH connection settings (hosts, credentials, keys)
      • Session timeouts (e.g., session_timeout_minutes = 30)
  3. First Use Case:

    • Local Shell: Embed the terminal in a Filament page:
      use Mwguerra\WebTerminal\Components\Terminal;
      
      Terminal::make()
          ->connection('local') // or 'ssh'
          ->allowedCommands(['ls', 'php artisan'])
          ->width('100%')
          ->height('600px')
      
    • SSH Connection: Configure in config/web-terminal.php:
      'connections' => [
          'ssh' => [
              'host' => 'your-server.com',
              'username' => 'deploy',
              'password' => env('SSH_PASSWORD'), // or use 'private_key'
              'port' => 22,
          ],
      ],
      

Implementation Patterns

Core Workflows

  1. Command Whitelisting:

    • Define allowed commands in config/web-terminal.php under allowed_commands:
      'allowed_commands' => [
          'ls -la',
          'php artisan {command}',
          'composer {command}',
      ],
      
    • Use placeholders ({command}) for dynamic arguments (e.g., php artisan {command} allows php artisan migrate).
  2. SSH Management:

    • Dynamic Connections: Store SSH configs in the database (via TerminalConnection model) and fetch them dynamically:
      Terminal::make()
          ->connection('ssh')
          ->connectionConfig(fn () => TerminalConnection::find(1)->toArray())
      
    • Key-Based Auth: Use private_key and private_key_passphrase in config:
      'connections' => [
          'ssh' => [
              'private_key' => file_get_contents('/path/to/key'),
              'private_key_passphrase' => env('SSH_KEY_PASSPHRASE'),
          ],
      ],
      
  3. Scripts:

    • Define reusable scripts in config/web-terminal.php:
      'scripts' => [
          'deploy' => [
              'commands' => [
                  'git pull origin main',
                  'php artisan migrate',
                  'php artisan optimize',
              ],
              'description' => 'Run full deployment',
          ],
      ],
      
    • Execute via:
      Terminal::make()->script('deploy')
      
  4. Filament Integration:

    • Terminal Page: Use the built-in Filament page:
      php artisan make:filament-page TerminalPage
      
      Then register it in AppServiceProvider:
      Filament::registerPages([
          \App\Filament\Pages\TerminalPage::class,
      ]);
      
    • Embed in Custom Pages: Add to any Filament schema:
      Terminal::make()->connection('local')
      
  5. Permissions:

    • Assign permissions via TerminalPermission enum:
      use Mwguerra\WebTerminal\Enums\TerminalPermission;
      
      $user->givePermissionTo(TerminalPermission::EXECUTE_COMMANDS);
      
    • Gate checks in policies:
      public function viewTerminal(User $user): bool
      {
          return $user->hasPermissionTo(TerminalPermission::VIEW_TERMINAL);
      }
      
  6. Session Handling:

    • Timeouts: Configure in config/web-terminal.php:
      'session_timeout_minutes' => 15,
      'disconnect_on_navigate' => true,
      
    • Active Sessions: List via Filament resource:
      php artisan make:filament-resource TerminalSession
      

Advanced Patterns

  • Multi-Tenant Isolation:

    • Use TerminalConnection::where('tenant_id', $tenant->id) to scope SSH connections.
    • Override getAllowedCommands() in a custom TerminalService to filter by tenant.
  • Custom Command Handlers:

    • Extend Mwguerra\WebTerminal\Services\CommandHandler to add logic for specific commands:
      public function handleCommand(string $command, TerminalSession $session): CommandResult
      {
          if (str_starts_with($command, 'custom:')) {
              return $this->executeCustomCommand($command);
          }
          return parent::handleCommand($command, $session);
      }
      
  • WebSocket Streaming:

    • Enable for full PTY support (e.g., vim, htop):
      'streaming' => [
          'enabled' => true,
          'websocket_path' => '/terminal/stream',
      ],
      
    • Requires Laravel Echo/Pusher setup.

Gotchas and Tips

Pitfalls

  1. Command Injection:

    • Risk: Allowing dynamic commands (e.g., php artisan {command}) can expose your system to injection if {command} isn’t sanitized.
    • Fix: Use the built-in whitelist strictly. Avoid wildcards like * or ?.
  2. SSH Key Permissions:

    • Issue: SSH connections may fail if private keys lack read permissions.
    • Fix: Ensure keys are readable by the web server:
      chmod 600 /path/to/private_key
      chown www-data:www-data /path/to/private_key
      
  3. PTY Resource Limits:

    • Problem: Long-running PTY sessions (e.g., tmux, screen) may exhaust system resources.
    • Fix: Set max_sessions in config and monitor usage via Filament stats.
  4. Filament Caching:

    • Gotcha: Filament’s page caching may interfere with real-time terminal updates.
    • Workaround: Exclude the terminal page from caching or use Livewire’s defer:
      Terminal::make()->defer()
      
  5. WebSocket CORS:

    • Issue: WebSocket streaming may block if CORS isn’t configured.
    • Fix: Add to config/cors.php:
      'paths' => ['terminal/stream', 'api/*'],
      'allowed_methods' => ['*'],
      'allowed_origins' => ['*'],
      
  6. Artisan Command Restrictions:

    • Warning: Commands like queue:work or schedule:run may hang indefinitely.
    • Solution: Use --once flags or limit to non-blocking commands:
      'allowed_commands' => [
          'php artisan queue:work --once',
      ],
      

Debugging Tips

  1. Logs:

    • Enable verbose logging in config/web-terminal.php:
      'logging' => [
          'enabled' => true,
          'level' => 'debug',
      ],
      
    • Check storage/logs/laravel.log for connection/command errors.
  2. SSH Debugging:

    • Enable SSH debugging in config:
      'ssh' => [
          'debug' => true,
      ],
      
    • Use ssh -vvv manually to test connections.
  3. WebSocket Issues:

    • Verify WebSocket endpoint is accessible:
      curl -i -N -H "Connection: Upgrade" -H "Upgrade: websocket" -H "Host: your-app.test" http://your-app.test/terminal/stream
      
    • Check Laravel Echo/Pusher setup if using Laravel Echo.
  4. Permission Denied:

    • Ensure the web server user (e.g., www-data) has execute permissions for local commands:
      sudo chmod +x /usr/bin/php /usr/bin/composer
      

Extension Points

  1. Custom Connection Types:

    • Extend Mwguerra\WebTerminal\Contracts\ConnectionInterface to add support for Docker, Kubernetes, etc.
  2. Command Pre/Post Processing:

    • Override Mwguerra\WebTerminal\Services\CommandHandler to:
      • Log commands before execution.
      • Modify command arguments (e.g., append --env=production).
      • Validate inputs (e.g., check for rm -rf).
  3. UI Customization:

    • Override Blade views in resources/views/vendor/web-terminal.
    • Customize terminal theme via CSS:
      Terminal::make()->extraAttributes(['class' => 'custom-terminal-theme'])
      
  4. Audit Trail:

    • Extend Mwguerra\WebTerminal\Models\TerminalLog to add custom fields (e.g., user_agent, ip_address):
      php artisan make:m
      
Weaver

How can I help you explore Laravel packages today?

Conversation history is not saved when not logged in.
Prompt
Add packages to context
No packages found.
comsave/common
alecsammon/php-raml-parser
chrome-php/wrench
lendable/composer-license-checker
typhoon/reflection
mesilov/moneyphp-percentage
mike42/gfx-php
bookdown/themes
aura/view
aura/html
aura/cli
povils/phpmnd
nayjest/manipulator
omnipay/tests
psr-mock/http-message-implementation
psr-mock/http-factory-implementation
psr-mock/http-client-implementation
voku/email-check
voku/urlify
rtheunissen/guzzle-log-middleware