Failed Conditions
Push — master ( bd1917...152deb )
by Arnold
07:23
created

src/Session/Jwt.php (3 issues)

Labels
Severity
1
<?php
2
3
declare(strict_types=1);
4
5
namespace Jasny\Auth\Session;
6
7
use Jasny\Auth\Session\Jwt\Cookie;
8
use Jasny\Auth\Session\Jwt\CookieInterface;
9
use Jasny\Immutable;
10
use Lcobucci\JWT\Parser;
11
use Lcobucci\JWT\Builder;
12
use Lcobucci\JWT\Signer;
13
use Lcobucci\JWT\ValidationData;
14
15
/**
16
 * Use JSON Web Token and JSON Web Signature (RFC 7519) to store auth session info.
17
 *
18
 * @see https://github.com/lcobucci/jwt
19
 */
20
class Jwt implements SessionInterface
21
{
22
    use Immutable\With;
23
24
    protected Builder $builder;
25
    protected Signer $signer;
26
    protected Signer\Key $key;
27
28
    protected Parser $parser;
29
    protected ValidationData $validation;
30
31
    protected int $ttl = 24 * 3600;
32
    protected CookieInterface $cookie;
33
34
    /**
35
     * JWT constructor.
36
     */
37
    public function __construct(Builder $builder, Signer $signer, Signer\Key $key, ValidationData $validation)
38
    {
39
        $this->builder = $builder;
40
        $this->signer = $signer;
41
        $this->key = $key;
42
43
        $this->validation = $validation;
44
        $this->parser = new Parser();
45
46
        $this->cookie = new Cookie('jwt');
47
    }
48
49
    /**
50
     * Get a copy with a different TTL for expiry.
51
     */
52
    public function withTtl(int $seconds): self
53
    {
54
        return $this->withProperty('ttl', $seconds);
55
    }
56
57
    /**
58
     * Get a copy with custom cookie handler.
59
     */
60
    public function withCookie(CookieInterface $cookie): self
61
    {
62
        return $this->withProperty('cookie', $cookie);
63
    }
64
65
    /**
66
     * Get a copy with a custom JWT parser.
67
     */
68
    public function withParser(Parser $parser): self
69
    {
70
        return $this->withProperty('parser', $parser);
71
    }
72
73
    /**
74
     * @inheritDoc
75
     */
76
    public function getInfo(): array
77
    {
78
        $jwt = $this->cookie->get();
79
80
        $token = $jwt !== null && $jwt !== ''
81
            ? $this->parser->parse($jwt)
82
            : null;
83
84
        if ($token === null || !$token->validate($this->validation)) {
85
            return ['user' => null, 'context' => null, 'checksum' => null, 'timestamp' => null];
86
        }
87
88
        return [
89
            'user' => $token->claims()->get('user'),
90
            'context' => $token->claims()->get('context'),
91
            'checksum' => $token->claims()->get('checksum'),
92
            'timestamp' => $token->headers()->get('iat'),
93
        ];
94
    }
95
96
    /**
97
     * @inheritDoc
98
     */
99
    public function persist($user, $context, ?string $checksum, ?\DateTimeInterface $timestamp): void
100
    {
101
        $builder = clone $this->builder;
102
103
        if ($timestamp instanceof \DateTime) {
104
            $timestamp = \DateTimeImmutable::createFromMutable($timestamp);
105
        }
106
        $time = $timestamp ?? new \DateTimeImmutable();
107
        $expire = $time->add(new \DateInterval("PT{$this->ttl}S"));
0 ignored issues
show
Call to an undefined method DateTimeInterface::add().
Loading history...
The method add() does not exist on null. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

107
        /** @scrutinizer ignore-call */ 
108
        $expire = $time->add(new \DateInterval("PT{$this->ttl}S"));

This check looks for calls to methods that do not seem to exist on a given type. It looks for the method on the type itself as well as in inherited classes or implemented interfaces.

This is most likely a typographical error or the method has been renamed.

Loading history...
108
109
        $builder
110
            ->withClaim('user', $user)
111
            ->withClaim('context', $context)
112
            ->withClaim('checksum', $checksum)
113
            ->issuedAt($time)
0 ignored issues
show
Parameter #1 $issuedAt of method Lcobucci\JWT\Builder::issuedAt() expects DateTimeImmutable|int, DateTimeInterface given.
Loading history...
114
            ->expiresAt($expire);
115
116
        if ($timestamp !== null) {
117
            $builder->withHeader('iat', $timestamp);
118
        }
119
120
        $this->cookie->set(
121
            (string)$builder->getToken($this->signer, $this->key),
122
            $expire->getTimestamp()
123
        );
124
    }
125
126
    /**
127
     * @inheritDoc
128
     */
129
    public function clear(): void
130
    {
131
        $this->cookie->clear();
132
    }
133
}
134