Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
100.00% covered (success)
100.00%
44 / 44
100.00% covered (success)
100.00%
16 / 16
CRAP
100.00% covered (success)
100.00%
1 / 1
JwtConfig
100.00% covered (success)
100.00%
44 / 44
100.00% covered (success)
100.00%
16 / 16
21
100.00% covered (success)
100.00%
1 / 1
 __construct
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 getPrivateKey
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 getPublicKey
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 getAlgorithm
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 getAlgorithmValue
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 getTtlMinutes
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 getTtlSeconds
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 getRefreshTtlMinutes
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 getRefreshTtlSeconds
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 getIssuer
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 getAudience
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 getRequiredClaims
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 getTimezone
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 getDateTimeZone
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 fromArray
100.00% covered (success)
100.00%
19 / 19
100.00% covered (success)
100.00%
1 / 1
6
 fromKeyFiles
100.00% covered (success)
100.00%
11 / 11
100.00% covered (success)
100.00%
1 / 1
1
1<?php
2
3declare(strict_types=1);
4
5namespace DevToolbelt\JwtTokenManager;
6
7use DateTimeZone;
8use DevToolbelt\Enums\Locale\Timezone;
9use DevToolbelt\Enums\Security\Algorithm;
10
11final class JwtConfig
12{
13    private const DEFAULT_TTL_MINUTES = 60;
14    private const DEFAULT_REFRESH_TTL_MINUTES = 20160;
15
16    /** @var array<string> */
17    private const DEFAULT_REQUIRED_CLAIMS = ['iss', 'jti', 'exp', 'iat', 'typ', 'sub'];
18
19    /**
20     * @param array<string>|null $audience
21     * @param array<string> $requiredClaims
22     */
23    public function __construct(
24        private readonly string $privateKey,
25        private readonly string $publicKey,
26        private readonly string $issuer,
27        private readonly Algorithm $algorithm = Algorithm::RS256,
28        private readonly int $ttlMinutes = self::DEFAULT_TTL_MINUTES,
29        private readonly int $refreshTtlMinutes = self::DEFAULT_REFRESH_TTL_MINUTES,
30        private readonly ?array $audience = null,
31        private readonly array $requiredClaims = self::DEFAULT_REQUIRED_CLAIMS,
32        private readonly Timezone $timezone = Timezone::UTC
33    ) {
34    }
35
36    public function getPrivateKey(): string
37    {
38        return $this->privateKey;
39    }
40
41    public function getPublicKey(): string
42    {
43        return $this->publicKey;
44    }
45
46    public function getAlgorithm(): Algorithm
47    {
48        return $this->algorithm;
49    }
50
51    public function getAlgorithmValue(): string
52    {
53        return $this->algorithm->value;
54    }
55
56    public function getTtlMinutes(): int
57    {
58        return $this->ttlMinutes;
59    }
60
61    public function getTtlSeconds(): int
62    {
63        return $this->ttlMinutes * 60;
64    }
65
66    public function getRefreshTtlMinutes(): int
67    {
68        return $this->refreshTtlMinutes;
69    }
70
71    public function getRefreshTtlSeconds(): int
72    {
73        return $this->refreshTtlMinutes * 60;
74    }
75
76    public function getIssuer(): string
77    {
78        return $this->issuer;
79    }
80
81    /**
82     * @return array<string>|null
83     */
84    public function getAudience(): ?array
85    {
86        return $this->audience;
87    }
88
89    /**
90     * @return array<string>
91     */
92    public function getRequiredClaims(): array
93    {
94        return $this->requiredClaims;
95    }
96
97    public function getTimezone(): Timezone
98    {
99        return $this->timezone;
100    }
101
102    public function getDateTimeZone(): DateTimeZone
103    {
104        return $this->timezone->toDateTimeZone();
105    }
106
107    /**
108     * @param array<string, mixed> $config
109     */
110    public static function fromArray(array $config): self
111    {
112        $algorithm = isset($config['algorithm'])
113            ? (is_string($config['algorithm']) ? Algorithm::from($config['algorithm']) : $config['algorithm'])
114            : Algorithm::RS256;
115
116        $timezone = Timezone::UTC;
117        if (isset($config['timezone'])) {
118            $timezone = is_string($config['timezone'])
119                ? Timezone::from($config['timezone'])
120                : $config['timezone'];
121        }
122
123        return new self(
124            privateKey: $config['private_key'],
125            publicKey: $config['public_key'],
126            issuer: $config['issuer'],
127            algorithm: $algorithm,
128            ttlMinutes: $config['ttl_minutes'] ?? self::DEFAULT_TTL_MINUTES,
129            refreshTtlMinutes: $config['refresh_ttl_minutes'] ?? self::DEFAULT_REFRESH_TTL_MINUTES,
130            audience: isset($config['audience']) ? (array) $config['audience'] : null,
131            requiredClaims: $config['required_claims'] ?? self::DEFAULT_REQUIRED_CLAIMS,
132            timezone: $timezone
133        );
134    }
135
136    /**
137     * @param array<string>|null $audience
138     * @param array<string> $requiredClaims
139     */
140    public static function fromKeyFiles(
141        string $privateKeyPath,
142        string $publicKeyPath,
143        string $issuer,
144        Algorithm $algorithm = Algorithm::RS256,
145        int $ttlMinutes = self::DEFAULT_TTL_MINUTES,
146        int $refreshTtlMinutes = self::DEFAULT_REFRESH_TTL_MINUTES,
147        ?array $audience = null,
148        array $requiredClaims = self::DEFAULT_REQUIRED_CLAIMS,
149        Timezone $timezone = Timezone::UTC
150    ): self {
151        return new self(
152            privateKey: file_get_contents($privateKeyPath),
153            publicKey: file_get_contents($publicKeyPath),
154            issuer: $issuer,
155            algorithm: $algorithm,
156            ttlMinutes: $ttlMinutes,
157            refreshTtlMinutes: $refreshTtlMinutes,
158            audience: $audience,
159            requiredClaims: $requiredClaims,
160            timezone: $timezone
161        );
162    }
163}