Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
100.00% covered (success)
100.00%
26 / 26
100.00% covered (success)
100.00%
2 / 2
CRAP
100.00% covered (success)
100.00%
1 / 1
OidcDiscoveryDocument
100.00% covered (success)
100.00%
26 / 26
100.00% covered (success)
100.00%
2 / 2
9
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
 fromArray
100.00% covered (success)
100.00%
25 / 25
100.00% covered (success)
100.00%
1 / 1
8
1<?php
2
3/**
4 * Typed OIDC discovery document.
5 *
6 * This Source Code Form is subject to the terms of the Mozilla Public License,
7 * v. 2.0. If a copy of the MPL was not distributed with this file, You can
8 * obtain one at https://mozilla.org/MPL/2.0/.
9 *
10 * @package   phpMyFAQ
11 * @author    Thorsten Rinne <thorsten@phpmyfaq.de>
12 * @copyright 2026 phpMyFAQ Team
13 * @license   https://www.mozilla.org/MPL/2.0/ Mozilla Public License Version 2.0
14 * @link      https://www.phpmyfaq.de
15 * @since     2026-04-18
16 */
17
18declare(strict_types=1);
19
20namespace phpMyFAQ\Auth\Oidc;
21
22use InvalidArgumentException;
23
24final readonly class OidcDiscoveryDocument
25{
26    public function __construct(
27        public string $issuer,
28        public string $authorizationEndpoint,
29        public string $tokenEndpoint,
30        public string $userInfoEndpoint,
31        public string $jwksUri,
32        public ?string $endSessionEndpoint = null,
33    ) {
34    }
35
36    /**
37     * @param array<string, mixed> $data
38     */
39    public static function fromArray(array $data): self
40    {
41        foreach ([
42            'issuer',
43            'authorization_endpoint',
44            'token_endpoint',
45            'userinfo_endpoint',
46            'jwks_uri',
47        ] as $requiredKey) {
48            if (
49                !array_key_exists($requiredKey, $data)
50                || !is_string($data[$requiredKey])
51                || trim($data[$requiredKey]) === ''
52            ) {
53                throw new InvalidArgumentException(sprintf(
54                    'Missing or invalid OIDC discovery field: %s',
55                    $requiredKey,
56                ));
57            }
58        }
59
60        $endSessionEndpoint = null;
61        if (array_key_exists('end_session_endpoint', $data) && is_string($data['end_session_endpoint'])) {
62            $endSessionEndpoint = trim($data['end_session_endpoint']);
63        }
64
65        return new self(
66            issuer: trim((string) $data['issuer']),
67            authorizationEndpoint: trim((string) $data['authorization_endpoint']),
68            tokenEndpoint: trim((string) $data['token_endpoint']),
69            userInfoEndpoint: trim((string) $data['userinfo_endpoint']),
70            jwksUri: trim((string) $data['jwks_uri']),
71            endSessionEndpoint: $endSessionEndpoint !== '' ? $endSessionEndpoint : null,
72        );
73    }
74}