Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
100.00% covered (success)
100.00%
24 / 24
100.00% covered (success)
100.00%
4 / 4
CRAP
100.00% covered (success)
100.00%
1 / 1
OAuthDiscoveryService
100.00% covered (success)
100.00%
24 / 24
100.00% covered (success)
100.00%
4 / 4
10
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
 getMetaDiscovery
100.00% covered (success)
100.00%
12 / 12
100.00% covered (success)
100.00%
1 / 1
4
 getDiscoveryDocument
100.00% covered (success)
100.00%
9 / 9
100.00% covered (success)
100.00%
1 / 1
1
 isEnabled
100.00% covered (success)
100.00%
2 / 2
100.00% covered (success)
100.00%
1 / 1
4
1<?php
2
3/**
4 * OAuth discovery metadata service.
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-11
16 */
17
18declare(strict_types=1);
19
20namespace phpMyFAQ\Api;
21
22use phpMyFAQ\Configuration;
23
24final readonly class OAuthDiscoveryService
25{
26    public function __construct(
27        private Configuration $configuration,
28    ) {
29    }
30
31    /**
32     * @return array<string, bool|string|string[]>
33     */
34    public function getMetaDiscovery(): array
35    {
36        $document = $this->getDiscoveryDocument();
37
38        return [
39            'enabled' => $this->isEnabled(),
40            'issuer' => is_string($document['issuer'] ?? null) ? $document['issuer'] : '',
41            'authorizationEndpoint' => is_string($document['authorization_endpoint'] ?? null)
42                ? $document['authorization_endpoint']
43                : '',
44            'tokenEndpoint' => is_string($document['token_endpoint'] ?? null) ? $document['token_endpoint'] : '',
45            'grantTypesSupported' => $document['grant_types_supported'],
46            'responseTypesSupported' => $document['response_types_supported'],
47            'tokenEndpointAuthMethodsSupported' => $document['token_endpoint_auth_methods_supported'],
48        ];
49    }
50
51    /**
52     * @return array<string, string|string[]>
53     */
54    public function getDiscoveryDocument(): array
55    {
56        $apiBaseUrl = rtrim($this->configuration->getDefaultUrl(), characters: '/') . '/api';
57
58        return [
59            'issuer' => $apiBaseUrl,
60            'authorization_endpoint' => $apiBaseUrl . '/oauth/authorize',
61            'token_endpoint' => $apiBaseUrl . '/oauth/token',
62            'grant_types_supported' => ['authorization_code', 'client_credentials', 'refresh_token'],
63            'response_types_supported' => ['code'],
64            'token_endpoint_auth_methods_supported' => ['client_secret_basic', 'client_secret_post', 'none'],
65        ];
66    }
67
68    public function isEnabled(): bool
69    {
70        $value = $this->configuration->get('oauth2.enable');
71
72        return $value === true || $value === 1 || $value === '1' || $value === 'true';
73    }
74}