• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

daycry / jwt / 25547514855

08 May 2026 09:15AM UTC coverage: 78.328% (-2.0%) from 80.319%
25547514855

push

github

daycry
test: give each generated key pair a unique filename

testRsaTokenSignedWithDifferentKeyFails was hitting a CI-only false
negative because generateRsaKeyPair() always wrote to the same
fixture paths (rsa-private.pem / rsa-public.pem). The second call
overwrote the first key pair, so $publicA and $publicB ended up
pointing at the same file on disk — the verifier was effectively
verifying with the right key and the test never reached the expected
RequiredConstraintsViolated.

Suffix each pair with `uniqid('', true)` so distinct calls produce
distinct files. Same fix applied to generateEcdsaKeyPair() for
symmetry.

Surfaced when CI Linux finally ran the asymmetric tests (previously
skipped on Windows due to missing openssl.cnf).

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>

253 of 323 relevant lines covered (78.33%)

7.86 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

40.91
/src/Commands/JWTGenerateKey.php
1
<?php
2

3
namespace Daycry\JWT\Commands;
4

5
use CodeIgniter\CLI\BaseCommand;
6
use CodeIgniter\CLI\CLI;
7
use Exception;
8

9
class JWTGenerateKey extends BaseCommand
10
{
11
    protected $group       = 'JWT';
12
    protected $name        = 'jwt:key';
13
    protected $description = 'Generate a secure JWT signing key';
14
    protected $usage       = 'jwt:key [length]';
15
    protected $arguments   = [
16
        'length' => 'Key length in bytes (default: 32)',
17
    ];
18
    protected $options = [
19
        '--show'  => 'Display the key instead of updating .env file',
20
        '--force' => 'Force overwrite existing key in .env',
21
    ];
22

23
    public function run(array $params)
24
    {
25
        $length = (int) ($params[0] ?? 32);
5✔
26

27
        // Validate length
28
        if ($length < 16) {
5✔
29
            CLI::error('Key length must be at least 16 bytes for security');
1✔
30

31
            return;
1✔
32
        }
33

34
        if ($length > 128) {
4✔
35
            CLI::error('Key length cannot exceed 128 bytes');
1✔
36

37
            return;
1✔
38
        }
39

40
        try {
41
            // Generate secure random key
42
            $key = base64_encode(random_bytes($length));
3✔
43

44
            if (CLI::getOption('show')) {
3✔
45
                $this->displayKey($key, $length);
3✔
46

47
                return;
3✔
48
            }
49

50
            $this->updateEnvFile($key);
×
51
        } catch (Exception $e) {
×
52
            CLI::error('Failed to generate key: ' . $e->getMessage());
×
53
        }
54
    }
55

56
    private function displayKey(string $key, int $length): void
57
    {
58
        CLI::write('Generated JWT Key (' . $length . ' bytes):', 'yellow');
3✔
59
        CLI::write($key, 'green');
3✔
60
        CLI::newLine();
3✔
61
        CLI::write('Add this to your .env file:', 'yellow');
3✔
62
        CLI::write("jwt.signer={$key}", 'cyan');
3✔
63
        CLI::newLine();
3✔
64
        CLI::write('⚠️  Keep this key secure and never commit it to version control!', 'red');
3✔
65
    }
66

67
    private function updateEnvFile(string $key): void
68
    {
69
        $envPath        = ROOTPATH . '.env';
×
70
        $envExamplePath = ROOTPATH . '.env.example';
×
71

72
        // Check if .env exists
73
        if (! file_exists($envPath)) {
×
74
            CLI::error('.env file not found. Please create one first.');
×
75
            CLI::write('You can copy from .env.example if it exists:', 'yellow');
×
76
            if (file_exists($envExamplePath)) {
×
77
                CLI::write("cp {$envExamplePath} {$envPath}", 'cyan');
×
78
            }
79

80
            return;
×
81
        }
82

83
        $envContent = file_get_contents($envPath);
×
84

85
        // Check if jwt.signer already exists
86
        if (preg_match('/^jwt\.signer\s*=.*$/m', $envContent)) {
×
87
            // In testing environment or with --force flag, skip prompt
88
            $isTestingEnv   = (getenv('CI_ENVIRONMENT') === 'testing' || getenv('APP_ENV') === 'testing');
×
89
            $forceOverwrite = CLI::getOption('force') || $isTestingEnv;
×
90

91
            if (! $forceOverwrite && CLI::prompt('JWT key already exists in .env. Overwrite?', ['y', 'n']) === 'n') {
×
92
                CLI::write('Operation cancelled.', 'yellow');
×
93

94
                return;
×
95
            }
96

97
            // Update existing key
98
            $envContent = preg_replace('/^jwt\.signer\s*=.*$/m', "jwt.signer={$key}", $envContent);
×
99
        } else {
100
            // Add new key
101
            $envContent .= "\n# JWT Configuration\njwt.signer={$key}\n";
×
102
        }
103

104
        if (file_put_contents($envPath, $envContent)) {
×
105
            CLI::write('✅ JWT key successfully added to .env file', 'green');
×
106
            CLI::write('Generated key: ' . $key, 'cyan');
×
107
            CLI::newLine();
×
108
            CLI::write('⚠️  Keep your .env file secure and never commit it to version control!', 'red');
×
109
        } else {
110
            CLI::error('Failed to write to .env file. Check permissions.');
×
111
        }
112
    }
113
}
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2026 Coveralls, Inc