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

little-apps / LittleJWT / 14801220098

02 May 2025 06:36PM UTC coverage: 83.439% (-0.1%) from 83.535%
14801220098

push

github

little-apps
Added PHPDoc

1315 of 1576 relevant lines covered (83.44%)

424.18 hits per line

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

82.76
/src/Factories/KeyBuilder.php
1
<?php
2

3
namespace LittleApps\LittleJWT\Factories;
4

5
use Illuminate\Support\Facades\Log;
6
use Illuminate\Support\Traits\ForwardsCalls;
7
use Jose\Component\Core\JWK;
8
use Jose\Component\KeyManagement\JWKFactory;
9
use LittleApps\LittleJWT\Exceptions\InvalidJWKException;
10
use LittleApps\LittleJWT\Exceptions\MissingKeyException;
11
use LittleApps\LittleJWT\JWK\JsonWebKey;
12
use LittleApps\LittleJWT\Utils\Base64Encoder;
13

14
class KeyBuilder
15
{
16
    use ForwardsCalls;
17

18
    /**
19
     * Used to specify a secret phrase is used to create JWK.
20
     */
21
    public const KEY_SECRET = 'secret';
22

23
    /**
24
     * Used to specify a key file is used to create JWK. The KEY_FILES_* constants are the different types of acceptable key files.
25
     */
26
    public const KEY_FILE = 'file';
27

28
    /**
29
     * Used to specify a random JWK is used each time.
30
     */
31
    public const KEY_RANDOM = 'random';
32

33
    /**
34
     * Used to specify no JWK is used (not recommended).
35
     */
36
    public const KEY_NONE = 'none';
37

38
    /**
39
     * Used to specify a key file is used to create JWK. The KEY_FILES_* constants are the different types of acceptable key files.
40
     */
41
    public const KEY_FILES_PEM = 'pem';
42

43
    /**
44
     * Used to specify a key file is used to create JWK. The KEY_FILES_* constants are the different types of acceptable key files.
45
     */
46
    public const KEY_FILES_P12 = 'p12';
47

48
    /**
49
     * Used to specify a key file is used to create JWK. The KEY_FILES_* constants are the different types of acceptable key files.
50
     */
51
    public const KEY_FILES_CRT = 'crt';
52

53
    /**
54
     * The default hashing algorithm to use when no algorithm is set.
55
     */
56
    public const DEFAULT_ALGORITHM = 'HS256';
57

58
    /**
59
     * Builds JSON Web Key from configuration.
60
     *
61
     * @return JsonWebKey
62
     */
63
    public static function buildFromConfig(array $config)
64
    {
65
        $keyType = isset($config['default']) ? $config['default'] : 'unknown';
1,540✔
66

67
        $options = match ($keyType) {
1,540✔
68
            static::KEY_NONE => [],
1,540✔
69
            static::KEY_FILE => $config[static::KEY_FILE],
1,540✔
70
            static::KEY_SECRET => $config[static::KEY_SECRET],
1,540✔
71
            static::KEY_RANDOM => ['size' => $config[static::KEY_RANDOM]['size'] ?? 1024],
430✔
72
            default => []
10✔
73
        };
1,540✔
74

75
        $extra = [
1,540✔
76
            'use' => 'sig',
1,540✔
77
            'alg' => $config['alg'] ?? static::DEFAULT_ALGORITHM,
1,540✔
78
        ];
1,540✔
79

80
        return static::build($keyType, $options, $extra);
1,540✔
81
    }
82

83
    /**
84
     * Builds a JWK to use to sign/verify JWTs
85
     *
86
     * @param  string  $keyType  Key type (one of KEY_* constants).
87
     * @param  array  $options  Options to build key type.
88
     * @param  array  $extra  Any extra values to include in JWK.
89
     * @return JsonWebKey
90
     *
91
     * @throws InvalidJWKException Thrown if JWK is invalid.
92
     */
93
    public static function build(string $keyType, array $options, array $extra)
94
    {
95
        switch ($keyType) {
96
            case static::KEY_NONE:
1,540✔
97
                $jwk = static::createNoneJwk($extra);
×
98

99
                break;
×
100

101
            case static::KEY_FILE:
1,540✔
102
                $jwk = static::buildFromFile($options, $extra);
×
103

104
                break;
×
105

106
            case static::KEY_SECRET:
1,540✔
107
                $jwk = static::buildFromSecret($options, $extra);
1,540✔
108

109
                break;
1,540✔
110

111
            case static::KEY_RANDOM:
430✔
112
                $size = $options['size'] ?? 1024;
430✔
113

114
                $jwk = static::generateRandomJwk($size, $extra);
430✔
115

116
                break;
430✔
117

118
            default:
119
                Log::warning('LittleJWT is reverting to use no key. This is NOT recommended.');
10✔
120

121
                $jwk = static::createNoneJwk($extra);
10✔
122

123
                break;
10✔
124
        }
125

126
        return $jwk;
1,540✔
127
    }
128

129
    /**
130
     * Creates a none key.
131
     *
132
     * @return JsonWebKey
133
     */
134
    public static function createNoneJwk(array $extra = [])
135
    {
136
        return static::wrap(JWKFactory::createNoneKey($extra));
10✔
137
    }
138

139
    /**
140
     * Generates a random JWK
141
     *
142
     * @param  int  $size  # of bits for key size (must be multiple of 8)
143
     * @return JsonWebKey
144
     */
145
    public static function generateRandomJwk($size = 1024, array $extra = [])
146
    {
147
        return static::wrap(JWKFactory::createOctKey(
490✔
148
            $size, // Size in bits of the key. We recommend at least 128 bits.
490✔
149
            $extra
490✔
150
        ));
490✔
151
    }
152

153
    /**
154
     * Builds JWK from secret phrase.
155
     *
156
     * @return JsonWebKey
157
     */
158
    public static function buildFromSecret(array $config, array $extra = [])
159
    {
160
        if (! isset($config['allow_unsecure']) || ! $config['allow_unsecure']) {
1,540✔
161
            if (! isset($config['phrase'])) {
1,540✔
162
                throw new MissingKeyException;
10✔
163
            } elseif ($config['phrase'] === '') {
1,540✔
164
                Log::warning('LittleJWT is using an empty secret phrase. This is NOT recommended.');
40✔
165
            }
166
        }
167

168
        $phrase = Base64Encoder::decode($config['phrase']);
1,540✔
169

170
        return static::wrap(JWKFactory::createFromSecret($phrase, $extra));
1,540✔
171
    }
172

173
    /**
174
     * Builds JWK from key file.
175
     *
176
     * @return JsonWebKey
177
     */
178
    public static function buildFromFile(array $config, array $extra = [])
179
    {
180
        if (! is_file($config['path'])) {
10✔
181
            throw new MissingKeyException;
×
182
        }
183

184
        switch ($config['type']) {
10✔
185
            case static::KEY_FILES_CRT:
10✔
186
                $jwk = JWKFactory::createFromCertificateFile($config['path'], $extra);
×
187

188
                break;
×
189

190
            case static::KEY_FILES_P12:
10✔
191
                $jwk = JWKFactory::createFromPKCS12CertificateFile($config['path'], $config['secret'], $extra);
×
192

193
                break;
×
194

195
            default:
196
                $jwk = JWKFactory::createFromKeyFile($config['path'], $config['secret'], $extra);
10✔
197

198
                break;
10✔
199
        }
200

201
        return static::wrap($jwk);
10✔
202
    }
203

204
    /**
205
     * Creates JSON Web Key from existing JWK
206
     *
207
     * @return JsonWebKey
208
     */
209
    public static function wrap(JWK $jwk)
210
    {
211
        return $jwk instanceof JsonWebKey ? $jwk : new JsonWebKey($jwk->all());
1,540✔
212
    }
213

214
    /**
215
     * Forwards calls to static methods in JWKFactory
216
     *
217
     * @param  string  $name  Method name
218
     * @param  array  $params  Method parameters
219
     * @return mixed
220
     *
221
     * @throws \BadMethodCallException Thrown if method doesn't exist in JWKFactory
222
     */
223
    public static function __callStatic($name, $params)
224
    {
225
        if (method_exists(JWKFactory::class, $name)) {
10✔
226
            return call_user_func_array([JWKFactory::class, $name], $params);
10✔
227
        }
228

229
        static::throwBadMethodCallException($name);
×
230
    }
231
}
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