Enable Discovery debug logging for production troubleshooting

- Add DISCOVERY_LOG_LEVEL=debug
- Add DISCOVERY_SHOW_PROGRESS=true
- Temporary changes for debugging InitializerProcessor fixes on production
This commit is contained in:
2025-08-11 20:13:26 +02:00
parent 59fd3dd3b1
commit 55a330b223
3683 changed files with 2956207 additions and 16948 deletions

View File

@@ -0,0 +1,270 @@
<?php
declare(strict_types=1);
namespace App\Framework\Config\Console;
use App\Framework\Config\EncryptedEnvLoader;
use App\Framework\Config\Environment;
use App\Framework\Config\SecretManager;
use App\Framework\Console\ConsoleColor;
use App\Framework\Console\ConsoleCommand;
use App\Framework\Console\ConsoleInput;
use App\Framework\Console\ConsoleOutput;
use App\Framework\Console\ExitCode;
use App\Framework\Encryption\EncryptionFactory;
use App\Framework\Random\RandomGenerator;
/**
* Console commands for secrets management
*/
final readonly class SecretsCommand
{
public function __construct(
private RandomGenerator $randomGenerator,
private EncryptionFactory $encryptionFactory,
private ?SecretManager $secretManager = null
) {
}
#[ConsoleCommand('secrets:generate-key', 'Generate a secure encryption key')]
public function generateKey(ConsoleInput $input, ConsoleOutput $output): ExitCode
{
$output->writeLine('🔐 Generating encryption key...', ConsoleColor::CYAN);
$output->newLine();
try {
$length = 32;
$keyBytes = $this->randomGenerator->bytes($length);
$encodedKey = base64_encode($keyBytes);
$availableMethods = $this->encryptionFactory->getAvailableMethods();
$recommendedMethod = $this->encryptionFactory->getRecommendedMethod();
$output->writeLine("Available methods: " . implode(', ', $availableMethods));
$output->writeLine("Using recommended method: {$recommendedMethod}", ConsoleColor::GREEN);
$output->newLine();
$output->writeSuccess('✅ Encryption key generated successfully!');
$output->newLine();
$output->writeLine('ENCRYPTION_KEY=' . $encodedKey, ConsoleColor::YELLOW);
$output->newLine();
$output->writeWarning('🚨 SECURITY WARNINGS:');
$output->writeLine('• Store this key securely - it cannot be recovered if lost');
$output->writeLine('• Add this to your .env file (never commit to version control)');
$output->writeLine('• Use different keys for different environments');
$output->newLine();
$output->writeInfo('📋 Next steps:');
$output->writeLine('1. Add the key to your .env file');
$output->writeLine('2. Create .env.secrets file: php console.php secrets:init');
$output->writeLine('3. Encrypt secrets: php console.php secrets:encrypt "secret-value"');
return ExitCode::SUCCESS;
} catch (\Throwable $e) {
$output->writeError('❌ Failed to generate encryption key: ' . $e->getMessage());
return ExitCode::GENERAL_ERROR;
}
}
#[ConsoleCommand('secrets:encrypt', 'Encrypt a secret value')]
public function encrypt(ConsoleInput $input, ConsoleOutput $output): ExitCode
{
if ($this->secretManager === null) {
$output->writeError('❌ SecretManager not available. Make sure ENCRYPTION_KEY is set in .env');
return ExitCode::CONFIG_ERROR;
}
$value = $input->getArgument(0);
if (! $value) {
$value = $output->askPassword('Enter secret value to encrypt:');
}
if (empty($value)) {
$output->writeError('❌ No value provided to encrypt');
return ExitCode::CONFIG_ERROR;
}
try {
$encrypted = $this->secretManager->encryptSecret($value);
$output->writeSuccess('✅ Value encrypted successfully!');
$output->newLine();
$output->writeLine('Encrypted value:', ConsoleColor::CYAN);
$output->writeLine($encrypted, ConsoleColor::YELLOW);
$output->newLine();
$output->writeInfo('💡 Add this to your .env.secrets file like:');
$output->writeLine('SECRET_YOUR_KEY=' . $encrypted, ConsoleColor::GRAY);
return ExitCode::SUCCESS;
} catch (\Throwable $e) {
$output->writeError('❌ Failed to encrypt value: ' . $e->getMessage());
return ExitCode::SOFTWARE_ERROR;
}
}
#[ConsoleCommand('secrets:decrypt', 'Decrypt a secret value (for debugging)')]
public function decrypt(ConsoleInput $input, ConsoleOutput $output): ExitCode
{
if ($this->secretManager === null) {
$output->writeError('❌ SecretManager not available. Make sure ENCRYPTION_KEY is set in .env');
return ExitCode::CONFIG_ERROR;
}
$encryptedValue = $input->getArgument(0);
if (! $encryptedValue) {
$encryptedValue = $output->askQuestion('Enter encrypted value to decrypt:');
}
if (empty($encryptedValue)) {
$output->writeError('❌ No encrypted value provided');
return ExitCode::INVALID_INPUT;
}
try {
if (! $this->secretManager->isEncrypted($encryptedValue)) {
$output->writeWarning('⚠️ Value does not appear to be encrypted');
return ExitCode::INVALID_INPUT;
}
$decrypted = $this->secretManager->getSecret('TEMP_DECRYPT', $encryptedValue);
$output->writeSuccess('✅ Value decrypted successfully!');
$output->newLine();
$output->writeLine('Decrypted value:', ConsoleColor::CYAN);
$output->writeLine($decrypted, ConsoleColor::YELLOW);
$output->newLine();
$output->writeWarning('🔒 This value should be kept secure!');
return ExitCode::SUCCESS;
} catch (\Throwable $e) {
$output->writeError('❌ Failed to decrypt value: ' . $e->getMessage());
return ExitCode::SOFTWARE_ERROR;
}
}
#[ConsoleCommand('secrets:init', 'Initialize .env.secrets file')]
public function init(ConsoleInput $input, ConsoleOutput $output): ExitCode
{
$basePath = getcwd();
$secretsFile = $basePath . '/.env.secrets';
if (file_exists($secretsFile)) {
if (! $output->confirm('⚠️ .env.secrets already exists. Overwrite?', false)) {
$output->writeInfo('Operation cancelled');
return ExitCode::SUCCESS;
}
}
try {
$encryptedLoader = new EncryptedEnvLoader($this->encryptionFactory, $this->randomGenerator);
$filePath = $encryptedLoader->generateSecretsTemplate($basePath);
$output->writeSuccess('✅ .env.secrets template created!');
$output->writeLine("File created at: {$filePath}", ConsoleColor::GRAY);
$output->newLine();
$output->writeInfo('📋 Next steps:');
$output->writeLine('1. Edit .env.secrets and add your secret keys');
$output->writeLine('2. Encrypt values: php console.php secrets:encrypt "your-value"');
$output->writeLine('3. Add encrypted values to .env.secrets');
return ExitCode::SUCCESS;
} catch (\Throwable $e) {
$output->writeError('❌ Failed to create .env.secrets template: ' . $e->getMessage());
return ExitCode::CANT_CREATE;
}
}
#[ConsoleCommand('secrets:list', 'List all secret keys')]
public function list(ConsoleInput $input, ConsoleOutput $output): ExitCode
{
if ($this->secretManager === null) {
$output->writeError('❌ SecretManager not available. Make sure ENCRYPTION_KEY is set in .env');
return ExitCode::CONFIG_ERROR;
}
try {
$secretKeys = $this->secretManager->getSecretKeys();
if (empty($secretKeys)) {
$output->writeInfo(' No secret keys found');
return ExitCode::SUCCESS;
}
$output->writeLine('🔐 Found secret keys:', ConsoleColor::CYAN);
$output->newLine();
foreach ($secretKeys as $key) {
$output->writeLine("{$key}", ConsoleColor::WHITE);
}
$output->newLine();
$output->writeLine("Total: " . count($secretKeys) . " secrets", ConsoleColor::GRAY);
return ExitCode::SUCCESS;
} catch (\Throwable $e) {
$output->writeError('❌ Failed to list secrets: ' . $e->getMessage());
return ExitCode::CONFIG_ERROR;
}
}
#[ConsoleCommand('secrets:validate', 'Validate secrets setup')]
public function validate(ConsoleInput $input, ConsoleOutput $output): ExitCode
{
$basePath = getcwd();
$encryptedLoader = new EncryptedEnvLoader($this->encryptionFactory, $this->randomGenerator);
$env = Environment::fromFile($basePath . '/.env');
$encryptionKey = $env->get('ENCRYPTION_KEY');
$output->writeLine('🔍 Validating secrets setup...', ConsoleColor::CYAN);
$output->newLine();
$issues = $encryptedLoader->validateEncryptionSetup($basePath, $encryptionKey);
if (empty($issues)) {
$output->writeSuccess('✅ Secrets setup is valid!');
if ($this->secretManager !== null) {
$context = $this->secretManager->getSecurityContext();
$output->newLine();
$output->writeInfo('Security context:');
$output->writeLine("• HTTPS: " . ($context->isHttps ? 'Yes' : 'No'));
$output->writeLine("• Encryption: {$context->encryptionMethod}");
$output->writeLine("• Server: {$context->serverName}");
$output->writeLine("• Risk Level: {$context->getRiskLevel()->getDisplayName()}");
$output->writeLine("• Summary: {$context->getSummary()}");
}
return ExitCode::SUCCESS;
}
$output->writeWarning('⚠️ Found issues with secrets setup:');
$output->newLine();
foreach ($issues as $issue) {
$color = match ($issue['severity']) {
'high' => ConsoleColor::RED,
'medium' => ConsoleColor::YELLOW,
default => ConsoleColor::WHITE
};
$output->writeLine("{$issue['message']}", $color);
}
return ExitCode::CONFIG_ERROR;
}
}