Passed
Push — master ( c0d33c...41aaf7 )
by Arnold
15:34 queued 05:37
created

Jwt::getInfo()   A

Complexity

Conditions 6
Paths 12

Size

Total Lines 19
Code Lines 13

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
eloc 13
dl 0
loc 19
rs 9.2222
c 0
b 0
f 0
cc 6
nc 12
nop 0
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\ValidationData;
13
14
/**
15
 * Use JSON Web Token and JSON Web Signature (RFC 7519) to store auth session info.
16
 *
17
 * @see https://github.com/lcobucci/jwt
18
 */
19
class Jwt implements SessionInterface
20
{
21
    use Immutable\With;
22
23
    protected Builder $builder;
24
    protected Parser $parser;
25
    protected ValidationData $validation;
26
27
    protected int $ttl = 24 * 3600;
28
    protected CookieInterface $cookie;
29
30
    /**
31
     * JWT constructor.
32
     */
33
    public function __construct(Builder $builder, ValidationData $validation)
34
    {
35
        $this->builder = $builder;
36
        $this->validation = $validation;
37
        $this->parser = new Parser();
38
39
        $this->cookie = new Cookie('jwt');
40
    }
41
42
    /**
43
     * Get a copy with a different TTL for expiry.
44
     */
45
    public function withTtl(int $seconds): self
46
    {
47
        return $this->withProperty('ttl', $seconds);
48
    }
49
50
    /**
51
     * Get a copy with custom cookie handler.
52
     */
53
    public function withCookie(CookieInterface $cookie): self
54
    {
55
        return $this->withProperty('cookie', $cookie);
56
    }
57
58
    /**
59
     * Get a copy with a custom JWT parser.
60
     */
61
    public function withParser(Parser $parser): self
62
    {
63
        return $this->withProperty('parser', $parser);
64
    }
65
66
    /**
67
     * @inheritDoc
68
     */
69
    public function getInfo(): array
70
    {
71
        $jwt = $this->cookie->get();
72
73
        $token = $jwt !== null && $jwt !== ''
74
            ? $this->parser->parse($jwt)
75
            : null;
76
77
        if ($token === null || !$token->validate($this->validation)) {
78
            return ['user' => null, 'context' => null, 'checksum' => null, 'timestamp' => null];
79
        }
80
81
        return [
82
            'user' => $token->getClaim('user'),
83
            'context' => $token->getClaim('context'),
84
            'checksum' => $token->getClaim('checksum'),
85
            'timestamp' => $token->hasHeader('iat')
86
                ? (new \DateTimeImmutable())->setTimestamp($token->getHeader('iat'))
87
                : null,
88
        ];
89
    }
90
91
    /**
92
     * @inheritDoc
93
     */
94
    public function persist($user, $context, ?string $checksum, ?\DateTimeInterface $timestamp): void
95
    {
96
        $builder = clone $this->builder;
97
98
        $time = isset($timestamp) ? $timestamp->getTimestamp() : time();
99
        $expire = $time + $this->ttl;
100
101
        $token = $builder
102
            ->withClaim('user', $user)
103
            ->withClaim('context', $context)
104
            ->withClaim('checksum', $checksum)
105
            ->issuedAt($time, $timestamp !== null)
106
            ->expiresAt($expire)
107
            ->getToken();
108
109
        $this->cookie->set((string)$token, $expire);
110
    }
111
112
    /**
113
     * @inheritDoc
114
     */
115
    public function clear(): void
116
    {
117
        $this->cookie->clear();
118
    }
119
}
120