coopTilleuls / CoopTilleulsForgotPasswordBundle

Provides a "forgot password" complete feature for your API through a Symfony bundle
MIT License
79 stars 25 forks source link

Call to a member function withPost() on null #76

Closed acassan closed 3 years ago

acassan commented 3 years ago

Describe the bug Got "Call to a member function withPost() on null" in vendor/tilleuls/forgot-password-bundle/Bridge/ApiPlatform/OpenApi/OpenApiFactory.php (line 46)

Unable to generate documentation

To Reproduce Install bundle on api-platform 2.6

Expected behavior Endpoints displayed on documentation

Dont know where is problem, in var $paths, bundle routes are not set, maybe "DocumentationNormalizer" not registered ? I can PR if problem found

acassan commented 3 years ago

As workaround, I rewrite decorator


<?php
declare(strict_types=1);

namespace App\OpenApi;

use ApiPlatform\Core\OpenApi\Factory\OpenApiFactoryInterface;
use ApiPlatform\Core\OpenApi\OpenApi;
use ApiPlatform\Core\OpenApi\Model;

final class ForgotPasswordDecorator implements OpenApiFactoryInterface
{
    public function __construct(
        private OpenApiFactoryInterface $decorated
    ) {}

    public function __invoke(array $context = []): OpenApi
    {
        $openApi = ($this->decorated)($context);
        $schemas = $openApi->getComponents()->getSchemas();

        $schemas['ForgotPassword:reset'] = new \ArrayObject([
            'type' => 'object',
            'required' => ['password'],
            'properties' => [
                'password' => [
                    'type' => 'string',
                ],
            ],
        ]);

        $schemas['ForgotPassword:validate'] = new \ArrayObject([
            'type' => 'object',
        ]);

        $schemas['ForgotPassword:request'] = new \ArrayObject([
            'type' => 'object',
            'required' => ['email'],
            'properties' => [
                'email' => [
                    'type' => 'string',
                ],
            ],
        ]);

        $pathItem = new Model\PathItem(
            ref: 'ForgotPassword',
            post: new Model\Operation(
                operationId: 'postForgotPassword',
                tags: ['Forgot password'],
                responses: [
                    204 => [
                        'description' => 'Valid email address, no matter if user exists or not',
                    ],
                    400 => [
                        'description' => 'Missing email parameter or invalid format',
                    ],
                ],
                summary: 'Generates a token and send email',
                requestBody: new Model\RequestBody(
                    description: 'Request a new password',
                    content: new \ArrayObject([
                        'application/json' => [
                            'schema' => [
                                '$ref' => '#/components/schemas/ForgotPassword:request',
                            ],
                        ],
                    ]),
                ),
            ),
        );
        $openApi->getPaths()->addPath('/forgot-password/', $pathItem);

        $pathItem = new Model\PathItem(
            ref: 'ForgotPassword',
            get: new Model\Operation(
                operationId: 'getForgotPassword',
                tags: ['Forgot password'],
                responses: [
                    200 => [
                        'description' => 'Authenticated user',
                        'content' => [
                            'application/json' => [
                                'schema' => [
                                    '$ref' => '#/components/schemas/ForgotPassword:validate',
                                ],
                            ],
                        ],
                    ],
                    404 => [
                        'description' => 'Token not found or expired',
                    ],
                ],
                summary: 'Validates token',
                parameters: [
                    [
                        'name' => 'token',
                        'in' => 'path',
                        'required' => true,
                        'schema' => [
                            'type' => 'string',
                        ],
                    ],
                ]
            ),
            post: new Model\Operation(
                operationId: 'postForgotPasswordToken',
                tags: ['Forgot password'],
                responses: [
                    204 => [
                        'description' => 'Email address format valid, no matter if user exists or not',
                    ],
                    400 => [
                        'description' => 'Missing password parameter',
                    ],
                    404 => [
                        'description' => 'Token not found',
                    ],
                ],
                summary: 'Resets user password from token',
                parameters: [
                    [
                        'name' => 'token',
                        'in' => 'path',
                        'required' => true,
                        'schema' => [
                            'type' => 'string',
                        ],
                    ],
                ],
                requestBody: new Model\RequestBody(
                    description: 'Reset password',
                    content: new \ArrayObject([
                        'application/json' => [
                            'schema' => [
                                '$ref' => '#/components/schemas/ForgotPassword:reset',
                            ],
                        ],
                    ]),
                ),
            ),
        );
        $openApi->getPaths()->addPath('/forgot-password/{token}', $pathItem);

        return $openApi;
    }
}
`

Documentation is well generated
vincentchalamon commented 3 years ago

Thanks @acassan, Could you open a PR to fix it on dev-main, please? But be careful: the code is still compatible with PHP7

acassan commented 3 years ago

PR Opened, let me know, I tried to write with PHP7 compat

vincentchalamon commented 3 years ago

Thank you @acassan, I've merged your PR on main. Could you try it on your project and tell me it's working as expected, please?

acassan commented 3 years ago

Already check on my project before create PR working nice no error and all tests passed.

vincentchalamon commented 3 years ago

Tagged as v1.3.5 Thank you @acassan!