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

little-apps / LittleJWT / 26266035191

22 May 2026 03:05AM UTC coverage: 83.376% (-0.2%) from 83.566%
26266035191

push

github

little-apps
Capitalize workflow name in CI config

Update .github/workflows/run-tests.yml to change the workflow name from 'run-tests' to 'Run Tests' for improved readability and consistency in the GitHub Actions UI.

1314 of 1576 relevant lines covered (83.38%)

300.92 hits per line

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

95.9
/src/ServiceProvider.php
1
<?php
2

3
namespace LittleApps\LittleJWT;
4

5
use Illuminate\Contracts\Container\Container;
6
use Illuminate\Http\JsonResponse;
7
use Illuminate\Http\RedirectResponse;
8
use Illuminate\Http\Request;
9
use Illuminate\Http\Response;
10
use Illuminate\Routing\ResponseFactory;
11
use Illuminate\Support\Facades\Auth;
12
use LittleApps\LittleJWT\Blacklist\BlacklistManager;
13
use LittleApps\LittleJWT\Factories\KeyBuilder;
14
use LittleApps\LittleJWT\Factories\LittleJWTBuilder;
15
use LittleApps\LittleJWT\Factories\OpenSSLBuilder;
16
use LittleApps\LittleJWT\Factories\ValidatableBuilder;
17
use LittleApps\LittleJWT\Guards\Adapters;
18
use LittleApps\LittleJWT\Guards\Guard;
19
use LittleApps\LittleJWT\JWK\JsonWebKey;
20
use LittleApps\LittleJWT\JWK\JWKValidator;
21
use LittleApps\LittleJWT\JWT\JsonWebToken;
22
use LittleApps\LittleJWT\Laravel\Middleware\ValidToken as ValidTokenMiddleware;
23
use LittleApps\LittleJWT\Laravel\Rules\ValidToken as ValidTokenRule;
24
use LittleApps\LittleJWT\Utils\ResponseBuilder;
25
use LittleApps\LittleJWT\Validation\Validatables\StackValidatable;
26
use Spatie\LaravelPackageTools\Package;
27
use Spatie\LaravelPackageTools\PackageServiceProvider;
28

29
class ServiceProvider extends PackageServiceProvider
30
{
31
    /**
32
     * {@inheritDoc}
33
     */
34
    public function configurePackage(Package $package): void
35
    {
36
        $package
1,092✔
37
            ->name('littlejwt')
1,092✔
38
            ->hasMigration('create_jwt_blacklist_table')
1,092✔
39
            ->hasCommands(
1,092✔
40
                Commands\GeneratePhraseCommand::class,
1,092✔
41
                Commands\GenerateP12Command::class,
1,092✔
42
                Commands\GeneratePemCommand::class,
1,092✔
43
                Commands\BlacklistPurgeCommand::class
1,092✔
44
            );
1,092✔
45

46
        if (! $this->app->runningUnitTests()) {
1,092✔
47
            $package->hasConfigFile();
×
48
        } else {
49
            $this->mergeConfigFrom($package->basePath('/../config/littlejwt.testing.php'), 'littlejwt');
1,092✔
50
        }
51
    }
52

53
    /**
54
     * Register services.
55
     *
56
     * @return void
57
     */
58
    public function packageRegistered()
59
    {
60
        $this->registerCore();
1,092✔
61
        $this->registerFactories();
1,092✔
62
        $this->registerBlacklistManager();
1,092✔
63
        $this->registerBuildables();
1,092✔
64
        $this->registerValidatables();
1,092✔
65
        $this->registerGuardAdapters();
1,092✔
66
        $this->registerMiddleware();
1,092✔
67
    }
68

69
    /**
70
     * Bootstrap services.
71
     *
72
     * @return void
73
     */
74
    public function packageBooted()
75
    {
76
        $this->bootGuard();
1,092✔
77
        $this->bootMacros();
1,092✔
78
        $this->bootValidatorRules();
1,092✔
79
    }
80

81
    /**
82
     * Registers the core Little JWT classes.
83
     *
84
     * @return void
85
     */
86
    protected function registerCore()
87
    {
88
        $this->app->singleton(LittleJWT::class, function (Container $app) {
1,092✔
89
            $builder = new LittleJWTBuilder($app->make(JsonWebKey::class));
1,092✔
90
            $jwkValidator = $app->make(JWKValidator::class);
1,092✔
91

92
            return $builder->withJwkValidator($jwkValidator)->build();
1,092✔
93
        });
1,092✔
94

95
        $this->app->bind(JsonWebKey::class, function (Container $app) {
1,092✔
96
            $config = $app->config->get('littlejwt.key', []);
1,092✔
97
            $jwk = KeyBuilder::buildFromConfig($config);
1,092✔
98

99
            return $jwk;
1,092✔
100
        });
1,092✔
101

102
        $this->app->bind(JWKValidator::class, function () {
1,092✔
103
            return (new JWKValidator)->withFallback(fn () => KeyBuilder::generateRandomJwk(1024, [
1,092✔
104
                'alg' => 'HS256',
1,092✔
105
                'use' => 'sig',
1,092✔
106
            ]));
1,092✔
107
        });
1,092✔
108

109
        $this->app->alias(LittleJWT::class, 'littlejwt');
1,092✔
110
    }
111

112
    /**
113
     * Registers the blacklist manager
114
     *
115
     * @return void
116
     */
117
    protected function registerBlacklistManager()
118
    {
119
        $this->app->singleton(BlacklistManager::class, function ($app) {
1,092✔
120
            return new BlacklistManager($app);
469✔
121
        });
1,092✔
122
    }
123

124
    /**
125
     * Registers the factories
126
     *
127
     * @return void
128
     */
129
    protected function registerFactories()
130
    {
131
        $this->app->singleton(OpenSSLBuilder::class, function ($app) {
1,092✔
132
            $config = $app->config->get('littlejwt.openssl', []);
77✔
133

134
            return new OpenSSLBuilder($config);
77✔
135
        });
1,092✔
136
    }
137

138
    /**
139
     * Registers the JWT buildables.
140
     *
141
     * @return void
142
     */
143
    protected function registerBuildables()
144
    {
145
        $buildables = $this->app->config->get('littlejwt.buildables', []);
1,092✔
146

147
        foreach ($buildables as $key => $options) {
1,092✔
148
            if (! isset($options['buildable'])) {
1,092✔
149
                continue;
×
150
            }
151

152
            $buildable = $options['buildable'];
1,092✔
153

154
            $config = array_diff_key($options, array_flip(['buildable']));
1,092✔
155

156
            $this->app->singleton("littlejwt.buildables.{$key}", function ($app) use ($buildable, $config) {
1,092✔
157
                return $app->make($buildable, ['config' => $config]);
903✔
158
            });
1,092✔
159
        }
160
    }
161

162
    /**
163
     * Registers the JWT validators.
164
     *
165
     * @return void
166
     */
167
    protected function registerValidatables()
168
    {
169
        $validatables = $this->app->config->get('littlejwt.validatables', []);
1,092✔
170

171
        foreach ((array) $validatables as $key => $options) {
1,092✔
172
            if (! isset($options['validatable'])) {
1,092✔
173
                continue;
×
174
            }
175

176
            $validatable = $options['validatable'];
1,092✔
177

178
            $config = array_diff_key($options, array_flip(['validatable']));
1,092✔
179

180
            $this->app->singleton("littlejwt.validatables.{$key}", function ($app) use ($validatable, $config) {
1,092✔
181
                return $app->make($validatable, ['config' => $config]);
406✔
182
            });
1,092✔
183
        }
184
    }
185

186
    /**
187
     * Registers the adapters available to use with the guard.
188
     *
189
     * @return void
190
     */
191
    protected function registerGuardAdapters()
192
    {
193
        $this->app->bind(Adapters\GenericAdapter::class, function ($app) {
1,092✔
194
            return new Adapters\GenericAdapter($app);
154✔
195
        });
1,092✔
196

197
        $this->app->bind(Adapters\FingerprintAdapter::class, function ($app) {
1,092✔
198
            $generic = $app[Adapters\GenericAdapter::class];
154✔
199

200
            return new Adapters\FingerprintAdapter($app, $generic);
154✔
201
        });
1,092✔
202
    }
203

204
    /**
205
     * Registers the middleware.
206
     *
207
     * @return void
208
     */
209
    protected function registerMiddleware()
210
    {
211
        $this->app['router']->aliasMiddleware('validtoken', ValidTokenMiddleware::class);
1,092✔
212
    }
213

214
    /**
215
     * Boots the Little JWT auth guard.
216
     *
217
     * @return void
218
     */
219
    protected function bootGuard()
220
    {
221
        Auth::extend('littlejwt', function ($app, $name, array $config) {
1,092✔
222
            // Return an instance of Illuminate\Contracts\Auth\Guard...
223
            $config = array_merge([
154✔
224
                'input_key' => 'token',
154✔
225
                'adapter' => 'generic',
154✔
226
            ], $config);
154✔
227

228
            $provider = Auth::createUserProvider($config['provider'] ?? null);
154✔
229

230
            $abstract = config("littlejwt.guard.adapters.{$config['adapter']}.adapter");
154✔
231

232
            if (! $abstract) {
154✔
233
                throw new \InvalidArgumentException("Guard adapter [{$config['adapter']}] is not defined.");
×
234
            }
235

236
            $adapter = $app->make($abstract);
154✔
237

238
            $guard = new Guard($app, $adapter, $provider, $app['request'], $config);
154✔
239

240
            $app->refresh('request', $guard, 'setRequest');
154✔
241

242
            return $guard;
154✔
243
        });
1,092✔
244
    }
245

246
    protected function bootValidatorRules()
247
    {
248
        $this->app['validator']->extendImplicit('validtoken', function ($attribute, $value, $parameters, $validator) {
1,092✔
249
            if (! empty($parameters)) {
28✔
250
                $stack = array_map(function ($key) {
14✔
251
                    return is_string($key) ? ValidatableBuilder::resolve($key) : $key;
14✔
252
                }, (array) $parameters);
14✔
253

254
                $validatable = new StackValidatable($stack);
14✔
255

256
                $rule = new ValidTokenRule($validatable, false);
14✔
257
            } else {
258
                $rule = new ValidTokenRule;
14✔
259
            }
260

261
            return $rule->passes($attribute, $value);
28✔
262
        });
1,092✔
263
    }
264

265
    /**
266
     * Boots any macros
267
     *
268
     * @return void
269
     */
270
    protected function bootMacros()
271
    {
272
        $handler = $this->app->make(LittleJWT::class)->handler();
1,092✔
273

274
        /**
275
         * Get the token for the request.
276
         *
277
         * @param  Request  $request  Request to get token from
278
         * @param  string  $inputKey  Name of input to get token from (if it exists).
279
         * @return string|null
280
         */
281
        Request::macro('getToken', function ($inputKey = 'token') {
1,092✔
282
            /*
283
             * This exact same functionality exists in the getTokenForRequest method in a \Illuminate\Auth\TokenGuard instance.
284
             * However, it's not guaranteed that the token guard will be set and it doesn't make sense to instantiate it just to use 1 method.
285
             */
286
            $tokens = [
112✔
287
                $this->query($inputKey),
112✔
288
                $this->input($inputKey),
112✔
289
                $this->bearerToken(),
112✔
290
                $this->getPassword(),
112✔
291
            ];
112✔
292

293
            foreach ($tokens as $token) {
112✔
294
                if (! empty($token)) {
112✔
295
                    return $token;
112✔
296
                }
297
            }
298

299
            return null;
×
300
        });
1,092✔
301

302
        Request::macro('getJwt', function ($inputKey = 'token') use ($handler) {
1,092✔
303
            $token = $this->getToken($inputKey);
14✔
304

305
            return ! is_null($token) ? $handler->parse($token) : null;
14✔
306
        });
1,092✔
307

308
        ResponseFactory::macro('withJwt', function (JsonWebToken $jwt) {
1,092✔
309
            return ResponseFactory::json(ResponseBuilder::buildFromJwt($jwt));
21✔
310
        });
1,092✔
311

312
        $attachJwtCallback = function ($jwt) {
1,092✔
313
            return $this->header('Authorization', sprintf('Bearer %s', (string) $jwt));
7✔
314
        };
1,092✔
315

316
        Response::macro('attachJwt', $attachJwtCallback);
1,092✔
317
        JsonResponse::macro('attachJwt', $attachJwtCallback);
1,092✔
318
        RedirectResponse::macro('attachJwt', $attachJwtCallback);
1,092✔
319
    }
320
}
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