Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
100.00% covered (success)
100.00%
4 / 4
100.00% covered (success)
100.00%
2 / 2
CRAP
100.00% covered (success)
100.00%
1 / 1
OAuthDiscoveryController
100.00% covered (success)
100.00%
4 / 4
100.00% covered (success)
100.00%
2 / 2
3
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
 index
100.00% covered (success)
100.00%
3 / 3
100.00% covered (success)
100.00%
1 / 1
2
1<?php
2
3/**
4 * OAuth discovery endpoint controller.
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\Controller\Frontend;
21
22use OpenApi\Attributes as OA;
23use phpMyFAQ\Api\OAuthDiscoveryService;
24use phpMyFAQ\Controller\AbstractController;
25use Symfony\Component\HttpFoundation\JsonResponse;
26use Symfony\Component\HttpKernel\Exception\NotFoundHttpException;
27use Symfony\Component\Routing\Attribute\Route;
28
29final class OAuthDiscoveryController extends AbstractController
30{
31    public function __construct(
32        private readonly OAuthDiscoveryService $oAuthDiscoveryService,
33    ) {
34        parent::__construct();
35    }
36
37    #[OA\Get(
38        path: '/.well-known/oauth-authorization-server',
39        operationId: 'getOAuthAuthorizationServerMetadata',
40        tags: ['Public Endpoints'],
41    )]
42    #[OA\Response(
43        response: 200,
44        description: 'Returns OAuth 2.0 Authorization Server Metadata.',
45        content: new OA\JsonContent(properties: [
46            new OA\Property(property: 'issuer', type: 'string', example: 'https://localhost/api'),
47            new OA\Property(property: 'authorization_endpoint', type: 'string'),
48            new OA\Property(property: 'token_endpoint', type: 'string'),
49            new OA\Property(property: 'grant_types_supported', type: 'array', items: new OA\Items(type: 'string')),
50            new OA\Property(property: 'response_types_supported', type: 'array', items: new OA\Items(type: 'string')),
51            new OA\Property(
52                property: 'token_endpoint_auth_methods_supported',
53                type: 'array',
54                items: new OA\Items(type: 'string'),
55            ),
56        ]),
57    )]
58    #[Route(path: '/.well-known/oauth-authorization-server', name: 'public.oauth.discovery', methods: ['GET'])]
59    public function index(): JsonResponse
60    {
61        if (!$this->oAuthDiscoveryService->isEnabled()) {
62            throw new NotFoundHttpException('OAuth 2.0 authorization server metadata is not available.');
63        }
64
65        return $this->json($this->oAuthDiscoveryService->getDiscoveryDocument());
66    }
67}