From 5eda029a9fc77174ef90b1bf9016d2e32259c7e2 Mon Sep 17 00:00:00 2001 From: Ken Tanaka Date: Mon, 13 Jul 2026 18:54:12 +0900 Subject: [PATCH 01/16] =?UTF-8?q?Symfony7=E9=81=A9=E5=90=88=20-=20?= =?UTF-8?q?=E5=9F=BA=E6=9C=AC=E3=81=A8=E3=81=AA=E3=82=8B=E6=94=B9=E4=BF=AE?= =?UTF-8?q?=E3=81=AF=20Claude=E3=81=A7=E5=AE=9F=E6=96=BD=20+=20=E3=83=AC?= =?UTF-8?q?=E3=83=93=E3=83=A5=E3=83=BC=E6=B8=88=E3=81=BF(=E8=A9=A6?= =?UTF-8?q?=E9=A8=93=E3=81=AF=E6=89=8B=E5=8B=95=E5=AE=9F=E8=A1=8C)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .github/workflows/ab-testing.yml | 104 ++++++------ .github/workflows/e2e-testing.yml | 28 ++-- .github/workflows/main.yml | 153 ++++++++++++------ .github/workflows/release.yml | 8 +- Controller/Admin/ConfigController.php | 32 ++-- .../CustomerPersonalValidationController.php | 68 +++----- .../TwoFactorAuthCustomerController.php | 44 ++--- Entity/BaseInfoTrait.php | 37 ++--- Entity/CustomerTrait.php | 98 +++-------- Entity/TwoFactorAuthConfig.php | 127 ++++++--------- Entity/TwoFactorAuthCustomerCookie.php | 143 +++++----------- Entity/TwoFactorAuthType.php | 85 ++++------ Event.php | 14 +- .../CustomerPersonalValidationListener.php | 6 +- .../CustomerTwoFactorAuthListener.php | 16 +- .../TwoFactorAuthBaseSettingTypeExtension.php | 6 +- .../TwoFactorAuthCustomerTypeExtension.php | 6 +- Form/Type/TwoFactorAuthAppTypeCustomer.php | 4 +- Form/Type/TwoFactorAuthConfigType.php | 6 +- .../TwoFactorAuthPhoneNumberTypeCustomer.php | 4 +- Form/Type/TwoFactorAuthSmsTypeCustomer.php | 4 +- Form/Type/TwoFactorAuthTypeCustomer.php | 6 +- PluginManager.php | 45 +++--- README.md | 4 +- Repository/TwoFactorAuthConfigRepository.php | 7 +- .../TwoFactorAuthCustomerCookieRepository.php | 4 +- Repository/TwoFactorAuthTypeRepository.php | 4 +- Resource/.php-cs-fixer.dist.php | 57 +++++++ Resource/rector.php | 62 +++++++ Resource/template/admin/config.twig | 2 +- Service/CustomerTwoFactorAuthService.php | 14 +- Tests/bootstrap.php | 19 +++ composer.json | 8 +- phpstan.neon.dist | 10 ++ phpunit.xml.dist | 52 +++--- 35 files changed, 618 insertions(+), 669 deletions(-) create mode 100644 Resource/.php-cs-fixer.dist.php create mode 100644 Resource/rector.php create mode 100644 Tests/bootstrap.php create mode 100644 phpstan.neon.dist diff --git a/.github/workflows/ab-testing.yml b/.github/workflows/ab-testing.yml index a793dde..99a4913 100644 --- a/.github/workflows/ab-testing.yml +++ b/.github/workflows/ab-testing.yml @@ -25,35 +25,35 @@ jobs: - name: Download Plugin uses: actions/checkout@master with: - path: app/Plugin/TwoFactorAuthCustomer42 - - name: Download Plugin TwoFactorAuthCustomerApp42 + path: app/Plugin/TwoFactorAuthCustomer44 + - name: Download Plugin TwoFactorAuthCustomerApp44 uses: actions/checkout@master with: - repository: ${{ github.repository_owner }}/TwoFactorAuthCustomerApp42 - path: app/Plugin/TwoFactorAuthCustomerApp42 - - name: Download Plugin TwoFactorAuthCustomerSms42 + repository: ${{ github.repository_owner }}/TwoFactorAuthCustomerApp44 + path: app/Plugin/TwoFactorAuthCustomerApp44 + - name: Download Plugin TwoFactorAuthCustomerSms44 uses: actions/checkout@master with: - repository: ${{ github.repository_owner }}/TwoFactorAuthCustomerSms42 - path: app/Plugin/TwoFactorAuthCustomerSms42 + repository: ${{ github.repository_owner }}/TwoFactorAuthCustomerSms44 + path: app/Plugin/TwoFactorAuthCustomerSms44 - name: Sleep for MySQL run: sleep 120s shell: bash - name: Install Plugin run: | - docker-compose -f docker-compose.yml -f docker-compose.dev.yml -f docker-compose.pgsql.yml exec -T ec-cube bin/console eccube:plugin:install --code=TwoFactorAuthCustomer42 + docker-compose -f docker-compose.yml -f docker-compose.dev.yml -f docker-compose.pgsql.yml exec -T ec-cube bin/console eccube:plugin:install --code=TwoFactorAuthCustomer44 docker-compose -f docker-compose.yml -f docker-compose.dev.yml -f docker-compose.pgsql.yml exec -T ec-cube bin/console cache:clear - docker-compose -f docker-compose.yml -f docker-compose.dev.yml -f docker-compose.pgsql.yml exec -T ec-cube bin/console eccube:plugin:enable --code=TwoFactorAuthCustomer42 + docker-compose -f docker-compose.yml -f docker-compose.dev.yml -f docker-compose.pgsql.yml exec -T ec-cube bin/console eccube:plugin:enable --code=TwoFactorAuthCustomer44 docker-compose -f docker-compose.yml -f docker-compose.dev.yml -f docker-compose.pgsql.yml exec -T ec-cube bin/console cache:clear - docker-compose -f docker-compose.yml -f docker-compose.dev.yml -f docker-compose.pgsql.yml exec -T ec-cube bin/console eccube:plugin:install --code=TwoFactorAuthCustomerApp42 + docker-compose -f docker-compose.yml -f docker-compose.dev.yml -f docker-compose.pgsql.yml exec -T ec-cube bin/console eccube:plugin:install --code=TwoFactorAuthCustomerApp44 docker-compose -f docker-compose.yml -f docker-compose.dev.yml -f docker-compose.pgsql.yml exec -T ec-cube bin/console cache:clear - docker-compose -f docker-compose.yml -f docker-compose.dev.yml -f docker-compose.pgsql.yml exec -T ec-cube bin/console eccube:plugin:enable --code=TwoFactorAuthCustomerApp42 + docker-compose -f docker-compose.yml -f docker-compose.dev.yml -f docker-compose.pgsql.yml exec -T ec-cube bin/console eccube:plugin:enable --code=TwoFactorAuthCustomerApp44 docker-compose -f docker-compose.yml -f docker-compose.dev.yml -f docker-compose.pgsql.yml exec -T ec-cube bin/console cache:clear - docker-compose -f docker-compose.yml -f docker-compose.dev.yml -f docker-compose.pgsql.yml exec -T ec-cube bin/console eccube:plugin:install --code=TwoFactorAuthCustomerSms42 + docker-compose -f docker-compose.yml -f docker-compose.dev.yml -f docker-compose.pgsql.yml exec -T ec-cube bin/console eccube:plugin:install --code=TwoFactorAuthCustomerSms44 docker-compose -f docker-compose.yml -f docker-compose.dev.yml -f docker-compose.pgsql.yml exec -T ec-cube bin/console cache:clear - docker-compose -f docker-compose.yml -f docker-compose.dev.yml -f docker-compose.pgsql.yml exec -T ec-cube bin/console eccube:plugin:enable --code=TwoFactorAuthCustomerSms42 + docker-compose -f docker-compose.yml -f docker-compose.dev.yml -f docker-compose.pgsql.yml exec -T ec-cube bin/console eccube:plugin:enable --code=TwoFactorAuthCustomerSms44 - name: Wait 30s for the database to load, (as I do not know the databases active state) run: sleep 30s - name: Start Load EC-CUBE @@ -220,17 +220,17 @@ jobs: - name: Download Plugin uses: actions/checkout@master with: - path: app/Plugin/TwoFactorAuthCustomer42 - - name: Download Plugin TwoFactorAuthCustomerApp42 + path: app/Plugin/TwoFactorAuthCustomer44 + - name: Download Plugin TwoFactorAuthCustomerApp44 uses: actions/checkout@master with: - repository: ${{ github.repository_owner }}/TwoFactorAuthCustomerApp42 - path: app/Plugin/TwoFactorAuthCustomerApp42 - - name: Download Plugin TwoFactorAuthCustomerSms42 + repository: ${{ github.repository_owner }}/TwoFactorAuthCustomerApp44 + path: app/Plugin/TwoFactorAuthCustomerApp44 + - name: Download Plugin TwoFactorAuthCustomerSms44 uses: actions/checkout@master with: - repository: ${{ github.repository_owner }}/TwoFactorAuthCustomerSms42 - path: app/Plugin/TwoFactorAuthCustomerSms42 + repository: ${{ github.repository_owner }}/TwoFactorAuthCustomerSms44 + path: app/Plugin/TwoFactorAuthCustomerSms44 - name: Start Load EC-CUBE run: | sed -i 's!APP_ENV: "dev"!APP_ENV: "prod"!g' docker-compose.yml @@ -240,19 +240,19 @@ jobs: shell: bash - name: Install Plugin run: | - docker-compose -f docker-compose.yml -f docker-compose.dev.yml -f docker-compose.mysql.yml exec -T ec-cube bin/console eccube:plugin:install --code=TwoFactorAuthCustomer42 + docker-compose -f docker-compose.yml -f docker-compose.dev.yml -f docker-compose.mysql.yml exec -T ec-cube bin/console eccube:plugin:install --code=TwoFactorAuthCustomer44 docker-compose -f docker-compose.yml -f docker-compose.dev.yml -f docker-compose.mysql.yml exec -T ec-cube bin/console cache:clear - docker-compose -f docker-compose.yml -f docker-compose.dev.yml -f docker-compose.mysql.yml exec -T ec-cube bin/console eccube:plugin:enable --code=TwoFactorAuthCustomer42 + docker-compose -f docker-compose.yml -f docker-compose.dev.yml -f docker-compose.mysql.yml exec -T ec-cube bin/console eccube:plugin:enable --code=TwoFactorAuthCustomer44 docker-compose -f docker-compose.yml -f docker-compose.dev.yml -f docker-compose.mysql.yml exec -T ec-cube bin/console cache:clear - docker-compose -f docker-compose.yml -f docker-compose.dev.yml -f docker-compose.mysql.yml exec -T ec-cube bin/console eccube:plugin:install --code=TwoFactorAuthCustomerApp42 + docker-compose -f docker-compose.yml -f docker-compose.dev.yml -f docker-compose.mysql.yml exec -T ec-cube bin/console eccube:plugin:install --code=TwoFactorAuthCustomerApp44 docker-compose -f docker-compose.yml -f docker-compose.dev.yml -f docker-compose.mysql.yml exec -T ec-cube bin/console cache:clear - docker-compose -f docker-compose.yml -f docker-compose.dev.yml -f docker-compose.mysql.yml exec -T ec-cube bin/console eccube:plugin:enable --code=TwoFactorAuthCustomerApp42 + docker-compose -f docker-compose.yml -f docker-compose.dev.yml -f docker-compose.mysql.yml exec -T ec-cube bin/console eccube:plugin:enable --code=TwoFactorAuthCustomerApp44 docker-compose -f docker-compose.yml -f docker-compose.dev.yml -f docker-compose.mysql.yml exec -T ec-cube bin/console cache:clear - docker-compose -f docker-compose.yml -f docker-compose.dev.yml -f docker-compose.mysql.yml exec -T ec-cube bin/console eccube:plugin:install --code=TwoFactorAuthCustomerSms42 + docker-compose -f docker-compose.yml -f docker-compose.dev.yml -f docker-compose.mysql.yml exec -T ec-cube bin/console eccube:plugin:install --code=TwoFactorAuthCustomerSms44 docker-compose -f docker-compose.yml -f docker-compose.dev.yml -f docker-compose.mysql.yml exec -T ec-cube bin/console cache:clear - docker-compose -f docker-compose.yml -f docker-compose.dev.yml -f docker-compose.mysql.yml exec -T ec-cube bin/console eccube:plugin:enable --code=TwoFactorAuthCustomerSms42 + docker-compose -f docker-compose.yml -f docker-compose.dev.yml -f docker-compose.mysql.yml exec -T ec-cube bin/console eccube:plugin:enable --code=TwoFactorAuthCustomerSms44 - name: Wait for 30 seconds for the database to load, (because MySQL is slow to initialize) run: sleep 30s shell: bash @@ -438,17 +438,17 @@ jobs: - name: Download Plugin uses: actions/checkout@master with: - path: app/Plugin/TwoFactorAuthCustomer42 - - name: Download Plugin TwoFactorAuthCustomerApp42 + path: app/Plugin/TwoFactorAuthCustomer44 + - name: Download Plugin TwoFactorAuthCustomerApp44 uses: actions/checkout@master with: - repository: ${{ github.repository_owner }}/TwoFactorAuthCustomerApp42 - path: app/Plugin/TwoFactorAuthCustomerApp42 - - name: Download Plugin TwoFactorAuthCustomerSms42 + repository: ${{ github.repository_owner }}/TwoFactorAuthCustomerApp44 + path: app/Plugin/TwoFactorAuthCustomerApp44 + - name: Download Plugin TwoFactorAuthCustomerSms44 uses: actions/checkout@master with: - repository: ${{ github.repository_owner }}/TwoFactorAuthCustomerSms42 - path: app/Plugin/TwoFactorAuthCustomerSms42 + repository: ${{ github.repository_owner }}/TwoFactorAuthCustomerSms44 + path: app/Plugin/TwoFactorAuthCustomerSms44 - name: Start Load EC-CUBE run: | sed -i 's!APP_ENV: "dev"!APP_ENV: "prod"!g' docker-compose.yml @@ -458,19 +458,19 @@ jobs: shell: bash - name: Install Plugin run: | - docker-compose -f docker-compose.yml -f docker-compose.dev.yml -f docker-compose.bench.pgsql.yml exec -T ec-cube bin/console eccube:plugin:install --code=TwoFactorAuthCustomer42 + docker-compose -f docker-compose.yml -f docker-compose.dev.yml -f docker-compose.bench.pgsql.yml exec -T ec-cube bin/console eccube:plugin:install --code=TwoFactorAuthCustomer44 docker-compose -f docker-compose.yml -f docker-compose.dev.yml -f docker-compose.bench.pgsql.yml exec -T ec-cube bin/console cache:clear - docker-compose -f docker-compose.yml -f docker-compose.dev.yml -f docker-compose.bench.pgsql.yml exec -T ec-cube bin/console eccube:plugin:enable --code=TwoFactorAuthCustomer42 + docker-compose -f docker-compose.yml -f docker-compose.dev.yml -f docker-compose.bench.pgsql.yml exec -T ec-cube bin/console eccube:plugin:enable --code=TwoFactorAuthCustomer44 docker-compose -f docker-compose.yml -f docker-compose.dev.yml -f docker-compose.bench.pgsql.yml exec -T ec-cube bin/console cache:clear - docker-compose -f docker-compose.yml -f docker-compose.dev.yml -f docker-compose.bench.pgsql.yml exec -T ec-cube bin/console eccube:plugin:install --code=TwoFactorAuthCustomerApp42 + docker-compose -f docker-compose.yml -f docker-compose.dev.yml -f docker-compose.bench.pgsql.yml exec -T ec-cube bin/console eccube:plugin:install --code=TwoFactorAuthCustomerApp44 docker-compose -f docker-compose.yml -f docker-compose.dev.yml -f docker-compose.bench.pgsql.yml exec -T ec-cube bin/console cache:clear - docker-compose -f docker-compose.yml -f docker-compose.dev.yml -f docker-compose.bench.pgsql.yml exec -T ec-cube bin/console eccube:plugin:enable --code=TwoFactorAuthCustomerApp42 + docker-compose -f docker-compose.yml -f docker-compose.dev.yml -f docker-compose.bench.pgsql.yml exec -T ec-cube bin/console eccube:plugin:enable --code=TwoFactorAuthCustomerApp44 docker-compose -f docker-compose.yml -f docker-compose.dev.yml -f docker-compose.bench.pgsql.yml exec -T ec-cube bin/console cache:clear - docker-compose -f docker-compose.yml -f docker-compose.dev.yml -f docker-compose.bench.pgsql.yml exec -T ec-cube bin/console eccube:plugin:install --code=TwoFactorAuthCustomerSms42 + docker-compose -f docker-compose.yml -f docker-compose.dev.yml -f docker-compose.bench.pgsql.yml exec -T ec-cube bin/console eccube:plugin:install --code=TwoFactorAuthCustomerSms44 docker-compose -f docker-compose.yml -f docker-compose.dev.yml -f docker-compose.bench.pgsql.yml exec -T ec-cube bin/console cache:clear - docker-compose -f docker-compose.yml -f docker-compose.dev.yml -f docker-compose.bench.pgsql.yml exec -T ec-cube bin/console eccube:plugin:enable --code=TwoFactorAuthCustomerSms42 + docker-compose -f docker-compose.yml -f docker-compose.dev.yml -f docker-compose.bench.pgsql.yml exec -T ec-cube bin/console eccube:plugin:enable --code=TwoFactorAuthCustomerSms44 - name: Request home page - PGSQL PLUGIN 10000 PRODUCTS run: | sudo apt-get install apache2-utils @@ -678,17 +678,17 @@ jobs: - name: Download Plugin uses: actions/checkout@master with: - path: app/Plugin/TwoFactorAuthCustomer42 - - name: Download Plugin TwoFactorAuthCustomerApp42 + path: app/Plugin/TwoFactorAuthCustomer44 + - name: Download Plugin TwoFactorAuthCustomerApp44 uses: actions/checkout@master with: - repository: ${{ github.repository_owner }}/TwoFactorAuthCustomerApp42 - path: app/Plugin/TwoFactorAuthCustomerApp42 - - name: Download Plugin TwoFactorAuthCustomerSms42 + repository: ${{ github.repository_owner }}/TwoFactorAuthCustomerApp44 + path: app/Plugin/TwoFactorAuthCustomerApp44 + - name: Download Plugin TwoFactorAuthCustomerSms44 uses: actions/checkout@master with: - repository: ${{ github.repository_owner }}/TwoFactorAuthCustomerSms42 - path: app/Plugin/TwoFactorAuthCustomerSms42 + repository: ${{ github.repository_owner }}/TwoFactorAuthCustomerSms44 + path: app/Plugin/TwoFactorAuthCustomerSms44 - name: Start Load EC-CUBE run: | sed -i 's!APP_ENV: "dev"!APP_ENV: "prod"!g' docker-compose.yml @@ -736,19 +736,19 @@ jobs: docker-compose -f docker-compose.yml -f docker-compose.dev.yml -f docker-compose.bench.mysql.yml logs ec-cube - name: Install Plugin run: | - docker-compose -f docker-compose.yml -f docker-compose.dev.yml -f docker-compose.bench.mysql.yml exec -T ec-cube bin/console eccube:plugin:install --code=TwoFactorAuthCustomer42 + docker-compose -f docker-compose.yml -f docker-compose.dev.yml -f docker-compose.bench.mysql.yml exec -T ec-cube bin/console eccube:plugin:install --code=TwoFactorAuthCustomer44 docker-compose -f docker-compose.yml -f docker-compose.dev.yml -f docker-compose.bench.mysql.yml exec -T ec-cube bin/console cache:clear - docker-compose -f docker-compose.yml -f docker-compose.dev.yml -f docker-compose.bench.mysql.yml exec -T ec-cube bin/console eccube:plugin:enable --code=TwoFactorAuthCustomer42 + docker-compose -f docker-compose.yml -f docker-compose.dev.yml -f docker-compose.bench.mysql.yml exec -T ec-cube bin/console eccube:plugin:enable --code=TwoFactorAuthCustomer44 docker-compose -f docker-compose.yml -f docker-compose.dev.yml -f docker-compose.bench.mysql.yml exec -T ec-cube bin/console cache:clear - docker-compose -f docker-compose.yml -f docker-compose.dev.yml -f docker-compose.bench.mysql.yml exec -T ec-cube bin/console eccube:plugin:install --code=TwoFactorAuthCustomerApp42 + docker-compose -f docker-compose.yml -f docker-compose.dev.yml -f docker-compose.bench.mysql.yml exec -T ec-cube bin/console eccube:plugin:install --code=TwoFactorAuthCustomerApp44 docker-compose -f docker-compose.yml -f docker-compose.dev.yml -f docker-compose.bench.mysql.yml exec -T ec-cube bin/console cache:clear - docker-compose -f docker-compose.yml -f docker-compose.dev.yml -f docker-compose.bench.mysql.yml exec -T ec-cube bin/console eccube:plugin:enable --code=TwoFactorAuthCustomerApp42 + docker-compose -f docker-compose.yml -f docker-compose.dev.yml -f docker-compose.bench.mysql.yml exec -T ec-cube bin/console eccube:plugin:enable --code=TwoFactorAuthCustomerApp44 docker-compose -f docker-compose.yml -f docker-compose.dev.yml -f docker-compose.bench.mysql.yml exec -T ec-cube bin/console cache:clear - docker-compose -f docker-compose.yml -f docker-compose.dev.yml -f docker-compose.bench.mysql.yml exec -T ec-cube bin/console eccube:plugin:install --code=TwoFactorAuthCustomerSms42 + docker-compose -f docker-compose.yml -f docker-compose.dev.yml -f docker-compose.bench.mysql.yml exec -T ec-cube bin/console eccube:plugin:install --code=TwoFactorAuthCustomerSms44 docker-compose -f docker-compose.yml -f docker-compose.dev.yml -f docker-compose.bench.mysql.yml exec -T ec-cube bin/console cache:clear - docker-compose -f docker-compose.yml -f docker-compose.dev.yml -f docker-compose.bench.mysql.yml exec -T ec-cube bin/console eccube:plugin:enable --code=TwoFactorAuthCustomerSms42 + docker-compose -f docker-compose.yml -f docker-compose.dev.yml -f docker-compose.bench.mysql.yml exec -T ec-cube bin/console eccube:plugin:enable --code=TwoFactorAuthCustomerSms44 - name: Restart Load EC-CUBE to wait for MySQL run: | docker-compose -f docker-compose.yml -f docker-compose.dev.yml -f docker-compose.bench.mysql.yml up -d diff --git a/.github/workflows/e2e-testing.yml b/.github/workflows/e2e-testing.yml index d57a645..86ecb10 100644 --- a/.github/workflows/e2e-testing.yml +++ b/.github/workflows/e2e-testing.yml @@ -71,39 +71,39 @@ jobs: bin/console doctrine:database:create --env=dev bin/console doctrine:schema:create --env=dev bin/console eccube:fixtures:load --env=dev - - name: Download Plugin TwoFactorAuthCustomer42 + - name: Download Plugin TwoFactorAuthCustomer44 uses: actions/checkout@master with: - path: app/Plugin/TwoFactorAuthCustomer42 - - name: Download Plugin TwoFactorAuthCustomerApp42 + path: app/Plugin/TwoFactorAuthCustomer44 + - name: Download Plugin TwoFactorAuthCustomerApp44 uses: actions/checkout@master with: - repository: ${{ github.repository_owner }}/TwoFactorAuthCustomerApp42 - path: app/Plugin/TwoFactorAuthCustomerApp42 - - name: Download Plugin TwoFactorAuthCustomerSms42 + repository: ${{ github.repository_owner }}/TwoFactorAuthCustomerApp44 + path: app/Plugin/TwoFactorAuthCustomerApp44 + - name: Download Plugin TwoFactorAuthCustomerSms44 uses: actions/checkout@master with: - repository: ${{ github.repository_owner }}/TwoFactorAuthCustomerSms42 - path: app/Plugin/TwoFactorAuthCustomerSms42 + repository: ${{ github.repository_owner }}/TwoFactorAuthCustomerSms44 + path: app/Plugin/TwoFactorAuthCustomerSms44 - name: Install Plugins env: APP_ENV: ${{ matrix.app_env }} DATABASE_URL: ${{ matrix.database_url }} DATABASE_SERVER_VERSION: ${{ matrix.database_server_version }} run: | - bin/console eccube:plugin:install --code=TwoFactorAuthCustomer42 + bin/console eccube:plugin:install --code=TwoFactorAuthCustomer44 bin/console cache:clear - bin/console eccube:plugin:enable --code=TwoFactorAuthCustomer42 + bin/console eccube:plugin:enable --code=TwoFactorAuthCustomer44 bin/console cache:clear - bin/console eccube:plugin:install --code=TwoFactorAuthCustomerApp42 + bin/console eccube:plugin:install --code=TwoFactorAuthCustomerApp44 bin/console cache:clear - bin/console eccube:plugin:enable --code=TwoFactorAuthCustomerApp42 + bin/console eccube:plugin:enable --code=TwoFactorAuthCustomerApp44 bin/console cache:clear - bin/console eccube:plugin:install --code=TwoFactorAuthCustomerSms42 + bin/console eccube:plugin:install --code=TwoFactorAuthCustomerSms44 bin/console cache:clear - bin/console eccube:plugin:enable --code=TwoFactorAuthCustomerSms42 + bin/console eccube:plugin:enable --code=TwoFactorAuthCustomerSms44 - name: setup-chromedriver uses: nanasess/setup-chromedriver@master diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml index 4227cd3..e828e97 100644 --- a/.github/workflows/main.yml +++ b/.github/workflows/main.yml @@ -1,4 +1,4 @@ -name: CI for TwoFactorAuthCustomer42 +name: CI for TwoFactorAuthCustomer44 on: push: branches: @@ -17,19 +17,15 @@ on: jobs: run-on-linux: name: Run on Linux - runs-on: ubuntu-22.04 + runs-on: ubuntu-24.04 strategy: fail-fast: false matrix: - eccube_version: [ '4.2','4.3' ] - php: [ '7.4', '8.0', '8.1','8.2', '8.3' ] - db: [ 'mysql', 'mysql8', 'pgsql' ] - plugin_code: [ 'TwoFactorAuthCustomer42' ] + eccube_version: [ '4.4' ] + php: [ '8.2', '8.3', '8.4', '8.5' ] + db: [ 'mysql8', 'pgsql' ] + plugin_code: [ 'TwoFactorAuthCustomer44' ] include: - - db: mysql - database_url: mysql://root:password@127.0.0.1:3306/eccube_db - database_server_version: 5.7 - database_charset: utf8mb4 - db: mysql8 database_url: mysql://root:password@127.0.0.1:3308/eccube_db database_server_version: 8 @@ -38,24 +34,7 @@ jobs: database_url: postgres://postgres:password@127.0.0.1:5432/eccube_db database_server_version: 14 database_charset: utf8 - exclude: - - eccube_version: 4.2 - php: 8.2 - - eccube_version: 4.2 - php: 8.3 - - eccube_version: 4.3 - php: 7.4 - - eccube_version: 4.3 - php: 8.0 services: - mysql: - image: mysql:5.7 - env: - MYSQL_ROOT_PASSWORD: password - MYSQL_DATABASE: ${{ matrix.dbname }} - ports: - - 3306:3306 - options: --health-cmd="mysqladmin ping" --health-interval=10s --health-timeout=5s --health-retries=3 mysql8: image: mysql:8 env: @@ -81,7 +60,7 @@ jobs: - 1025:1025 steps: - name: Checkout - uses: actions/checkout@v2 + uses: actions/checkout@v4 - name: Setup PHP uses: nanasess/setup-php@master @@ -93,17 +72,8 @@ jobs: PLUGIN_CODE: ${{ matrix.plugin_code }} run: | tar cvzf ${GITHUB_WORKSPACE}/${PLUGIN_CODE}.tar.gz ./* - - - name: Setup mock-package-api - env: - PLUGIN_CODE: ${{ matrix.plugin_code }} - run: | - mkdir -p /tmp/repos - cp ${GITHUB_WORKSPACE}/${PLUGIN_CODE}.tar.gz /tmp/repos/${PLUGIN_CODE}.tgz - docker run --name package-api -d -v /tmp/repos:/repos -e MOCK_REPO_DIR=/repos -p 8080:8080 eccube/mock-package-api:composer2 - - name: Checkout EC-CUBE - uses: actions/checkout@v2 + uses: actions/checkout@v4 with: repository: 'EC-CUBE/ec-cube' ref: ${{ matrix.eccube_version }} @@ -112,8 +82,8 @@ jobs: - name: Get Composer Cache Directory id: composer-cache run: | - echo "::set-output name=dir::$(composer config cache-files-dir)" - - uses: actions/cache@v1 + echo "dir=$(composer config cache-files-dir)" >> "$GITHUB_OUTPUT" + - uses: actions/cache@v4 with: path: ${{ steps.composer-cache.outputs.dir }} key: ${{ runner.os }}-composer-${{ hashFiles('**/composer.lock') }} @@ -121,7 +91,9 @@ jobs: ${{ runner.os }}-composer- - name: Install to composer working-directory: 'ec-cube' - run: composer install --no-interaction -o --apcu-autoloader + # Symfony 7.4 の symfony/cache が ext-redis <6.1 と衝突するが、ランナーには + # 古い php-redis(5.3.7) が入っている。本プラグイン/本体テストは redis 未使用のため無視する。 + run: composer install --no-interaction -o --apcu-autoloader --ignore-platform-req=ext-redis - name: Setup EC-CUBE env: @@ -130,7 +102,6 @@ jobs: DATABASE_URL: ${{ matrix.database_url }} DATABASE_SERVER_VERSION: ${{ matrix.database_server_version }} DATABASE_CHARSET: ${{ matrix.database_charset }} - ECCUBE_PACKAGE_API_URL: 'http://127.0.0.1:8080' working-directory: 'ec-cube' run: | bin/console doctrine:database:create @@ -144,12 +115,28 @@ jobs: DATABASE_SERVER_VERSION: ${{ matrix.database_server_version }} DATABASE_CHARSET: ${{ matrix.database_charset }} PLUGIN_CODE: ${{ matrix.plugin_code }} - ECCUBE_PACKAGE_API_URL: 'http://127.0.0.1:8080' working-directory: 'ec-cube' run: | - bin/console eccube:composer:require ec-cube/twofactorauthcustomer42 - bin/console cache:clear --no-warmup + bin/console eccube:plugin:install --code=${PLUGIN_CODE} --path=${GITHUB_WORKSPACE}/${PLUGIN_CODE}.tar.gz bin/console eccube:plugin:enable --code=${PLUGIN_CODE} + bin/console cache:clear --no-warmup + - name: Run PHPUnit + env: + APP_ENV: 'test' + APP_DEBUG: 0 + DATABASE_URL: ${{ matrix.database_url }} + DATABASE_SERVER_VERSION: ${{ matrix.database_server_version }} + DATABASE_CHARSET: ${{ matrix.database_charset }} + PLUGIN_CODE: ${{ matrix.plugin_code }} + working-directory: 'ec-cube' + run: | + # 有効化したプラグインのルーティングはコンテナのコンパイル時に確定する。 + # phpunit プロセスでの遅延コンパイルに任せると DB/タイミングで有効プラグイン一覧を + # 取りこぼし RouteNotFound になることがあるため、クリーンなプロセスで warmup して確定させる。 + bin/console cache:clear --no-warmup + bin/console cache:warmup + ./vendor/bin/phpunit -c app/Plugin/${PLUGIN_CODE}/phpunit.xml.dist app/Plugin/${PLUGIN_CODE}/Tests + - name: Disable Plugin working-directory: 'ec-cube' env: @@ -159,7 +146,6 @@ jobs: DATABASE_SERVER_VERSION: ${{ matrix.database_server_version }} DATABASE_CHARSET: ${{ matrix.database_charset }} PLUGIN_CODE: ${{ matrix.plugin_code }} - ECCUBE_PACKAGE_API_URL: 'http://127.0.0.1:8080' run: bin/console eccube:plugin:disable --code=${PLUGIN_CODE} - name: Uninstall Plugin @@ -170,6 +156,79 @@ jobs: DATABASE_SERVER_VERSION: ${{ matrix.database_server_version }} DATABASE_CHARSET: ${{ matrix.database_charset }} PLUGIN_CODE: ${{ matrix.plugin_code }} - ECCUBE_PACKAGE_API_URL: 'http://127.0.0.1:8080' working-directory: 'ec-cube' run: bin/console eccube:plugin:uninstall --code=${PLUGIN_CODE} + + static-analysis: + name: Static Analysis + runs-on: ubuntu-24.04 + # 静的解析は DB 種別に依存しないため、SQLite 1 構成で一度だけ実行する。 + # (php-cs-fixer / rector は DB 不要だが、phpstan は objectManagerLoader が + # カーネルを起動し EccubeExtension が dtb_plugin を読むため本体+DBが必要) + env: + PLUGIN_CODE: TwoFactorAuthCustomer44 + APP_ENV: 'test' + APP_DEBUG: 0 + DATABASE_URL: 'sqlite:///var/eccube.db' + DATABASE_SERVER_VERSION: 3 + DATABASE_CHARSET: 'utf8' + steps: + - name: Checkout + uses: actions/checkout@v4 + + - name: Setup PHP + uses: nanasess/setup-php@master + with: + php-version: '8.5' + + - name: Archive Plugin + run: | + tar cvzf ${GITHUB_WORKSPACE}/${PLUGIN_CODE}.tar.gz ./* + - name: Checkout EC-CUBE + uses: actions/checkout@v4 + with: + repository: 'EC-CUBE/ec-cube' + ref: '4.4' + path: 'ec-cube' + + - name: Get Composer Cache Directory + id: composer-cache + run: | + echo "dir=$(composer config cache-files-dir)" >> "$GITHUB_OUTPUT" + - uses: actions/cache@v4 + with: + path: ${{ steps.composer-cache.outputs.dir }} + key: ${{ runner.os }}-composer-${{ hashFiles('**/composer.lock') }} + restore-keys: | + ${{ runner.os }}-composer- + - name: Install to composer + working-directory: 'ec-cube' + run: composer install --no-interaction -o --apcu-autoloader --ignore-platform-req=ext-redis + + - name: Setup EC-CUBE + working-directory: 'ec-cube' + run: | + bin/console doctrine:database:create + bin/console doctrine:schema:create + # プラグイン有効化時に DeviceType 等のマスタデータを参照するため fixtures を投入する + bin/console eccube:fixtures:load + - name: Setup Plugin + working-directory: 'ec-cube' + run: | + bin/console eccube:plugin:install --code=${PLUGIN_CODE} --path=${GITHUB_WORKSPACE}/${PLUGIN_CODE}.tar.gz + bin/console eccube:plugin:enable --code=${PLUGIN_CODE} + bin/console cache:clear --no-warmup + + - name: Run php-cs-fixer + working-directory: 'ec-cube' + run: ./vendor/bin/php-cs-fixer fix --config=app/Plugin/${PLUGIN_CODE}/Resource/.php-cs-fixer.dist.php --dry-run --diff + + - name: Run Rector + working-directory: 'ec-cube' + run: ./vendor/bin/rector process --config=app/Plugin/${PLUGIN_CODE}/Resource/rector.php --dry-run + + - name: Run PHPStan + working-directory: 'ec-cube' + run: | + bin/console cache:clear --no-warmup + ./vendor/bin/phpstan analyse -c app/Plugin/${PLUGIN_CODE}/phpstan.neon.dist --no-progress diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 9a4b67a..6319ea0 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -8,19 +8,23 @@ jobs: runs-on: ubuntu-22.04 steps: - name: Checkout - uses: actions/checkout@v3 + uses: actions/checkout@v4 - name: Packaging working-directory: ../ run: | rm -rf $GITHUB_WORKSPACE/.github + # 開発・テスト用ファイルは配布パッケージに含めない + rm -rf $GITHUB_WORKSPACE/docker-compose*.yml $GITHUB_WORKSPACE/dockerbuild rm -rf $GITHUB_WORKSPACE/doc + rm -f $GITHUB_WORKSPACE/CLAUDE.md $GITHUB_WORKSPACE/phpstan.neon.dist + rm -f $GITHUB_WORKSPACE/Resource/rector.php "$GITHUB_WORKSPACE/Resource/.php-cs-fixer.dist.php" find $GITHUB_WORKSPACE -name "dummy" -delete find $GITHUB_WORKSPACE -name ".git*" -and ! -name ".gitkeep" -print0 | xargs -0 rm -rf chmod -R o+w $GITHUB_WORKSPACE cd $GITHUB_WORKSPACE tar cvzf ../${{ github.event.repository.name }}-${{ github.event.release.tag_name }}.tar.gz ./* - name: Upload binaries to release of TGZ - uses: svenstaro/upload-release-action@v2 + uses: svenstaro/upload-release-action@v1-release with: repo_token: ${{ secrets.GITHUB_TOKEN }} file: ${{ runner.workspace }}/${{ github.event.repository.name }}-${{ github.event.release.tag_name }}.tar.gz diff --git a/Controller/Admin/ConfigController.php b/Controller/Admin/ConfigController.php index 37a266f..216ab8c 100644 --- a/Controller/Admin/ConfigController.php +++ b/Controller/Admin/ConfigController.php @@ -11,42 +11,36 @@ * file that was distributed with this source code. */ -namespace Plugin\TwoFactorAuthCustomer42\Controller\Admin; +namespace Plugin\TwoFactorAuthCustomer44\Controller\Admin; use Eccube\Controller\AbstractController; -use Plugin\TwoFactorAuthCustomer42\Form\Type\TwoFactorAuthConfigType; -use Plugin\TwoFactorAuthCustomer42\Repository\TwoFactorAuthConfigRepository; -use Sensio\Bundle\FrameworkExtraBundle\Configuration\Template; +use Plugin\TwoFactorAuthCustomer44\Form\Type\TwoFactorAuthConfigType; +use Plugin\TwoFactorAuthCustomer44\Repository\TwoFactorAuthConfigRepository; +use Symfony\Bridge\Twig\Attribute\Template; use Symfony\Component\HttpFoundation\RedirectResponse; use Symfony\Component\HttpFoundation\Request; -use Symfony\Component\Routing\Annotation\Route; +use Symfony\Component\Routing\Attribute\Route; /** - * Class SmsController + * Class ConfigController */ class ConfigController extends AbstractController { - /** - * @var TwoFactorAuthConfigRepository - */ - private $smsConfigRepository; - /** * ConfigController constructor. */ - public function __construct(TwoFactorAuthConfigRepository $smsConfigRepository) - { - $this->smsConfigRepository = $smsConfigRepository; + public function __construct( + private readonly TwoFactorAuthConfigRepository $smsConfigRepository, + ) { } /** - * @Route("/%eccube_admin_route%/two_factor_auth_customer42/config", name="two_factor_auth_customer42_admin_config", methods={"GET", "POST"}) - * @Template("TwoFactorAuthCustomer42/Resource/template/admin/config.twig") - * * @param Request $request * * @return RedirectResponse|array */ + #[Route(path: '/%eccube_admin_route%/two_factor_auth_customer44/config', name: 'two_factor_auth_customer44_admin_config', methods: ['GET', 'POST'])] + #[Template('@TwoFactorAuthCustomer44/admin/config.twig')] public function index(Request $request) { // 設定情報、フォーム情報を取得 @@ -72,14 +66,14 @@ public function index(Request $request) // フォームの入力データを保存 $this->entityManager->persist($SmsConfig); - $this->entityManager->flush($SmsConfig); + $this->entityManager->flush(); // 完了メッセージを表示 log_info('config', ['status' => 'Success']); $this->addSuccess('プラグインの設定を保存しました。', 'admin'); // 設定画面にリダイレクト - return $this->redirectToRoute('two_factor_auth_customer42_admin_config'); + return $this->redirectToRoute('two_factor_auth_customer44_admin_config'); } return [ diff --git a/Controller/CustomerPersonalValidationController.php b/Controller/CustomerPersonalValidationController.php index ec43123..1542e3c 100644 --- a/Controller/CustomerPersonalValidationController.php +++ b/Controller/CustomerPersonalValidationController.php @@ -11,21 +11,20 @@ * file that was distributed with this source code. */ -namespace Plugin\TwoFactorAuthCustomer42\Controller; +namespace Plugin\TwoFactorAuthCustomer44\Controller; -use Eccube\Common\Constant; use Eccube\Controller\AbstractController; use Eccube\Entity\Customer; use Eccube\Repository\CustomerRepository; -use Plugin\TwoFactorAuthCustomer42\Form\Type\TwoFactorAuthPhoneNumberTypeCustomer; -use Plugin\TwoFactorAuthCustomer42\Form\Type\TwoFactorAuthSmsTypeCustomer; -use Plugin\TwoFactorAuthCustomer42\Service\CustomerTwoFactorAuthService; -use Sensio\Bundle\FrameworkExtraBundle\Configuration\Template; +use Plugin\TwoFactorAuthCustomer44\Form\Type\TwoFactorAuthPhoneNumberTypeCustomer; +use Plugin\TwoFactorAuthCustomer44\Form\Type\TwoFactorAuthSmsTypeCustomer; +use Plugin\TwoFactorAuthCustomer44\Service\CustomerTwoFactorAuthService; +use Symfony\Bridge\Twig\Attribute\Template; use Symfony\Component\HttpFoundation\RedirectResponse; use Symfony\Component\HttpFoundation\Request; use Symfony\Component\HttpKernel\Exception\TooManyRequestsHttpException; use Symfony\Component\RateLimiter\RateLimiterFactory; -use Symfony\Component\Routing\Annotation\Route; +use Symfony\Component\Routing\Attribute\Route; use Twig\Environment; use Twig\Error\LoaderError; use Twig\Error\RuntimeError; @@ -36,52 +35,32 @@ class CustomerPersonalValidationController extends AbstractController { - /** - * @var CustomerRepository - */ - protected CustomerRepository $customerRepository; - - /** - * @var CustomerTwoFactorAuthService - */ - protected CustomerTwoFactorAuthService $customerTwoFactorAuthService; - - /** - * @var Environment - */ - protected Environment $twig; - private RateLimiterFactory $deviceAuthRequestEmailLimiter; - /** * TwoFactorAuthCustomerController constructor. * - * @param CustomerRepository $customerRepository , - * @param CustomerTwoFactorAuthService $customerTwoFactorAuthService , + * @param RateLimiterFactory $deviceAuthRequestEmailLimiter + * @param CustomerRepository $customerRepository + * @param CustomerTwoFactorAuthService $customerTwoFactorAuthService * @param Environment $twig */ public function __construct( - RateLimiterFactory $deviceAuthRequestEmailLimiter, - CustomerRepository $customerRepository, - CustomerTwoFactorAuthService $customerTwoFactorAuthService, - Environment $twig + private RateLimiterFactory $deviceAuthRequestEmailLimiter, + protected CustomerRepository $customerRepository, + protected CustomerTwoFactorAuthService $customerTwoFactorAuthService, + protected Environment $twig, ) { - $this->customerRepository = $customerRepository; - $this->customerTwoFactorAuthService = $customerTwoFactorAuthService; - $this->twig = $twig; - $this->deviceAuthRequestEmailLimiter = $deviceAuthRequestEmailLimiter; } /** * (デバイス認証時)デバイス認証ワンタイムトークン入力画面. * - * @Route("/two_factor_auth/device_auth/input_onetime/{secret_key}", name="plg_customer_2fa_device_auth_input_onetime", requirements={"secret_key" = "^[a-zA-Z0-9]+$"}, methods={"GET", "POST"}) - * @Template("TwoFactorAuthCustomer42/Resource/template/default/device_auth/input.twig") - * * @param Request $request - * @param $secret_key + * @param string $secret_key * * @return array|RedirectResponse */ + #[Route(path: '/two_factor_auth/device_auth/input_onetime/{secret_key}', name: 'plg_customer_2fa_device_auth_input_onetime', requirements: ['secret_key' => '^[a-zA-Z0-9]+$'], methods: ['GET', 'POST'])] + #[Template('@TwoFactorAuthCustomer44/default/device_auth/input.twig')] public function deviceAuthInputOneTime(Request $request, $secret_key) { if ($this->isGranted('ROLE_USER')) { @@ -155,11 +134,8 @@ public function deviceAuthInputOneTime(Request $request, $secret_key) /** * (デバイス認証時)デバイス認証 送信先入力画面. * - * @Route("/two_factor_auth/device_auth/send_onetime/{secret_key}", name="plg_customer_2fa_device_auth_send_onetime", requirements={"secret_key" = "^[a-zA-Z0-9]+$"}, methods={"GET", "POST"}) - * @Template("TwoFactorAuthCustomer42/Resource/template/default/device_auth/send.twig") - * * @param Request $request - * @param $secret_key + * @param string $secret_key * * @return array|RedirectResponse * @@ -169,6 +145,8 @@ public function deviceAuthInputOneTime(Request $request, $secret_key) * @throws SyntaxError * @throws TwilioException */ + #[Route(path: '/two_factor_auth/device_auth/send_onetime/{secret_key}', name: 'plg_customer_2fa_device_auth_send_onetime', requirements: ['secret_key' => '^[a-zA-Z0-9]+$'], methods: ['GET', 'POST'])] + #[Template('@TwoFactorAuthCustomer44/default/device_auth/send.twig')] public function deviceAuthSendOneTime(Request $request, $secret_key) { if ($this->isGranted('ROLE_USER')) { @@ -228,10 +206,10 @@ public function deviceAuthSendOneTime(Request $request, $secret_key) /** * デバイス認証用のワンタイムトークンチェック. * - * @param $Customer - * @param $token + * @param Customer $Customer + * @param string $token * - * @return boolean + * @return bool */ private function checkDeviceToken($Customer, $token): bool { @@ -271,7 +249,7 @@ private function sendDeviceToken(Customer $Customer, string $phoneNumber) $this->entityManager->flush(); // ワンタイムトークン送信メッセージをレンダリング - $twig = 'TwoFactorAuthCustomer42/Resource/template/default/sms/onetime_message.twig'; + $twig = '@TwoFactorAuthCustomer44/default/sms/onetime_message.twig'; $body = $this->twig->render($twig, [ 'Customer' => $Customer, 'token' => $token, diff --git a/Controller/TwoFactorAuthCustomerController.php b/Controller/TwoFactorAuthCustomerController.php index 568b907..ba14308 100644 --- a/Controller/TwoFactorAuthCustomerController.php +++ b/Controller/TwoFactorAuthCustomerController.php @@ -11,57 +11,39 @@ * file that was distributed with this source code. */ -namespace Plugin\TwoFactorAuthCustomer42\Controller; +namespace Plugin\TwoFactorAuthCustomer44\Controller; use Eccube\Controller\AbstractController; use Eccube\Entity\Customer; use Eccube\Repository\CustomerRepository; -use Plugin\TwoFactorAuthCustomer42\Form\Type\TwoFactorAuthTypeCustomer; -use Plugin\TwoFactorAuthCustomer42\Service\CustomerTwoFactorAuthService; -use Sensio\Bundle\FrameworkExtraBundle\Configuration\Template; +use Plugin\TwoFactorAuthCustomer44\Form\Type\TwoFactorAuthTypeCustomer; +use Plugin\TwoFactorAuthCustomer44\Service\CustomerTwoFactorAuthService; +use Symfony\Bridge\Twig\Attribute\Template; use Symfony\Component\HttpFoundation\Request; -use Symfony\Component\Routing\Annotation\Route; +use Symfony\Component\Routing\Attribute\Route; use Twig\Environment; class TwoFactorAuthCustomerController extends AbstractController { - /** - * @var CustomerRepository - */ - protected CustomerRepository $customerRepository; - - /** - * @var CustomerTwoFactorAuthService - */ - protected CustomerTwoFactorAuthService $customerTwoFactorAuthService; - /** - * @var Environment - */ - protected Environment $twig; - /** * TwoFactorAuthCustomerController constructor. * - * @param CustomerRepository $customerRepository , - * @param CustomerTwoFactorAuthService $customerTwoFactorAuthService , + * @param CustomerRepository $customerRepository + * @param CustomerTwoFactorAuthService $customerTwoFactorAuthService * @param Environment $twig */ public function __construct( - CustomerRepository $customerRepository, - CustomerTwoFactorAuthService $customerTwoFactorAuthService, - Environment $twig + protected CustomerRepository $customerRepository, + protected CustomerTwoFactorAuthService $customerTwoFactorAuthService, + protected Environment $twig, ) { - $this->customerRepository = $customerRepository; - $this->customerTwoFactorAuthService = $customerTwoFactorAuthService; - $this->twig = $twig; } /** * (ログイン時)二段階認証設定(選択)画面. - * - * @Route("/mypage/two_factor_auth/select_type", name="plg_customer_2fa_auth_type_select", methods={"GET", "POST"}) - * @Template("TwoFactorAuthCustomer42/Resource/template/default/tfa/select_type.twig") */ + #[Route(path: '/mypage/two_factor_auth/select_type', name: 'plg_customer_2fa_auth_type_select', methods: ['GET', 'POST'])] + #[Template('@TwoFactorAuthCustomer44/default/tfa/select_type.twig')] public function selectAuthType(Request $request) { if ($this->isTwoFactorAuthed()) { @@ -106,7 +88,7 @@ public function selectAuthType(Request $request) /** * 認証済みか否か. * - * @return boolean + * @return bool */ protected function isTwoFactorAuthed(): bool { diff --git a/Entity/BaseInfoTrait.php b/Entity/BaseInfoTrait.php index 0ceda8d..4a54634 100644 --- a/Entity/BaseInfoTrait.php +++ b/Entity/BaseInfoTrait.php @@ -11,60 +11,43 @@ * file that was distributed with this source code. */ -namespace Plugin\TwoFactorAuthCustomer42\Entity; +namespace Plugin\TwoFactorAuthCustomer44\Entity; +use Doctrine\DBAL\Types\Types; use Doctrine\ORM\Mapping as ORM; -use Eccube\Annotation\EntityExtension; +use Eccube\Attribute\EntityExtension; +use Eccube\Entity\BaseInfo; -/** - * @EntityExtension("Eccube\Entity\BaseInfo") - */ +#[EntityExtension(BaseInfo::class)] trait BaseInfoTrait { /** * 2段階認証機能の利用 - * - * @var bool - * - * @ORM\Column(name="two_factor_auth_use", type="boolean", nullable=false, options={"default":false}) */ - private bool $two_factor_auth_use; + #[ORM\Column(name: 'two_factor_auth_use', type: Types::BOOLEAN, nullable: false, options: ['default' => false])] + private bool $two_factor_auth_use = false; + /** * SMS通知の設定 - * - * @var bool - * - * @ORM\Column(name="option_activate_device", type="boolean", nullable=false, options={"default":false}) */ - private bool $option_activate_device; + #[ORM\Column(name: 'option_activate_device', type: Types::BOOLEAN, nullable: false, options: ['default' => false])] + private bool $option_activate_device = false; - /** - * @return bool - */ public function isTwoFactorAuthUse(): bool { return $this->two_factor_auth_use; } - /** - * @param bool $two_factor_auth_use - */ public function setTwoFactorAuthUse(bool $two_factor_auth_use): void { $this->two_factor_auth_use = $two_factor_auth_use; } - /** - * @return bool - */ public function isOptionActivateDevice(): bool { return $this->option_activate_device; } - /** - * @param bool $option_activate_device - */ public function setOptionActivateDevice(bool $option_activate_device): void { $this->option_activate_device = $option_activate_device; diff --git a/Entity/CustomerTrait.php b/Entity/CustomerTrait.php index 6359fc3..c5de9a2 100644 --- a/Entity/CustomerTrait.php +++ b/Entity/CustomerTrait.php @@ -11,82 +11,50 @@ * file that was distributed with this source code. */ -namespace Plugin\TwoFactorAuthCustomer42\Entity; +namespace Plugin\TwoFactorAuthCustomer44\Entity; use Doctrine\Common\Collections\Collection; +use Doctrine\DBAL\Types\Types; use Doctrine\ORM\Mapping as ORM; -use Eccube\Annotation\EntityExtension; +use Eccube\Attribute\EntityExtension; +use Eccube\Entity\Customer; -/** - * @EntityExtension("Eccube\Entity\Customer") - */ +#[EntityExtension(Customer::class)] trait CustomerTrait { - /** - * @var ?string - * - * @ORM\Column(name="device_auth_one_time_token", type="string", length=255, nullable=true) - */ + #[ORM\Column(name: 'device_auth_one_time_token', type: Types::STRING, length: 255, nullable: true)] private ?string $device_auth_one_time_token = null; - /** - * @var \DateTime|null - * - * @ORM\Column(name="device_auth_one_time_token_expire", type="datetimetz", nullable=true) - */ - private $device_auth_one_time_token_expire; + #[ORM\Column(name: 'device_auth_one_time_token_expire', type: Types::DATETIMETZ_MUTABLE, nullable: true)] + private ?\DateTime $device_auth_one_time_token_expire = null; - /** - * @var boolean - * - * @ORM\Column(name="device_authed", type="boolean", nullable=false, options={"default":false}) - */ + #[ORM\Column(name: 'device_authed', type: Types::BOOLEAN, nullable: false, options: ['default' => false])] private bool $device_authed = false; - /** - * @var string|null - * - * @ORM\Column(name="device_authed_phone_number", type="string", length=14, nullable=true) - */ + #[ORM\Column(name: 'device_authed_phone_number', type: Types::STRING, length: 14, nullable: true)] private ?string $device_authed_phone_number = null; /** * 2段階認証機能の設定 - * - * @var int|null - * - * @ORM\Column(name="two_factor_auth_type", type="integer", nullable=true) */ + #[ORM\Column(name: 'two_factor_auth_type', type: Types::INTEGER, nullable: true)] private ?int $two_factor_auth_type = null; - /** - * @var TwoFactorAuthType - * - * @ORM\ManyToOne(targetEntity="\Plugin\TwoFactorAuthCustomer42\Entity\TwoFactorAuthType") - * @ORM\JoinColumns({ - * @ORM\JoinColumn(name="two_factor_auth_type_id", referencedColumnName="id") - * }) - */ - private $TwoFactorAuthType = null; + #[ORM\ManyToOne(targetEntity: TwoFactorAuthType::class)] + #[ORM\JoinColumn(name: 'two_factor_auth_type_id', referencedColumnName: 'id')] + private ?TwoFactorAuthType $TwoFactorAuthType = null; /** - * @var Collection - * - * @ORM\OneToMany(targetEntity="\Plugin\TwoFactorAuthCustomer42\Entity\TwoFactorAuthCustomerCookie", mappedBy="Customer") + * @var Collection|null */ + #[ORM\OneToMany(targetEntity: TwoFactorAuthCustomerCookie::class, mappedBy: 'Customer')] private $TwoFactorAuthCustomerCookies; - /** - * @return string - */ public function getDeviceAuthOneTimeToken(): ?string { return $this->device_auth_one_time_token; } - /** - * @param string|null $device_auth_one_time_token - */ public function setDeviceAuthOneTimeToken(?string $device_auth_one_time_token): void { $this->device_auth_one_time_token = $device_auth_one_time_token; @@ -94,10 +62,8 @@ public function setDeviceAuthOneTimeToken(?string $device_auth_one_time_token): /** * Get resetExpire. - * - * @return \DateTime|null */ - public function getDeviceAuthOneTimeTokenExpire() + public function getDeviceAuthOneTimeTokenExpire(): ?\DateTime { return $this->device_auth_one_time_token_expire; } @@ -105,8 +71,6 @@ public function getDeviceAuthOneTimeTokenExpire() /** * Set oneTimeTokenExpire. * - * @param \DateTime|null $resetExpire - * * @return Customer */ public function setDeviceAuthOneTimeTokenExpire($deviceAuthOneTimeTokenExpire = null) @@ -116,44 +80,30 @@ public function setDeviceAuthOneTimeTokenExpire($deviceAuthOneTimeTokenExpire = return $this; } - /** - * @return bool - */ public function isDeviceAuthed(): bool { return $this->device_authed; } - /** - * @param bool $device_authed - */ public function setDeviceAuthed(bool $device_authed): void { $this->device_authed = $device_authed; } - /** - * @return string - */ public function getDeviceAuthedPhoneNumber(): ?string { return $this->device_authed_phone_number; } - /** - * @param string|null $device_authed_phone_number - */ public function setDeviceAuthedPhoneNumber(?string $device_authed_phone_number): void { $this->device_authed_phone_number = $device_authed_phone_number; } /** - * Get sex. - * - * @return TwoFactorAuthType|null + * Get two-factor auth type. */ - public function getTwoFactorAuthType() + public function getTwoFactorAuthType(): ?TwoFactorAuthType { return $this->TwoFactorAuthType; } @@ -161,26 +111,20 @@ public function getTwoFactorAuthType() /** * Set two-factor auth type. * - * @param TwoFactorAuthType|null $twoFactorAuthType + * @return $this */ - public function setTwoFactorAuthType(TwoFactorAuthType $twoFactorAuthType = null) + public function setTwoFactorAuthType(?TwoFactorAuthType $twoFactorAuthType = null) { $this->TwoFactorAuthType = $twoFactorAuthType; return $this; } - /** - * @return Collection - */ public function getTwoFactorAuthCustomerCookies(): Collection { return $this->TwoFactorAuthCustomerCookies; } - /** - * @param Collection $TwoFactorAuthCustomerCookies - */ public function setTwoFactorAuthCustomerCookies(Collection $TwoFactorAuthCustomerCookies): void { $this->TwoFactorAuthCustomerCookies = $TwoFactorAuthCustomerCookies; diff --git a/Entity/TwoFactorAuthConfig.php b/Entity/TwoFactorAuthConfig.php index 94b9149..d306b0c 100644 --- a/Entity/TwoFactorAuthConfig.php +++ b/Entity/TwoFactorAuthConfig.php @@ -11,63 +11,43 @@ * file that was distributed with this source code. */ -namespace Plugin\TwoFactorAuthCustomer42\Entity; +namespace Plugin\TwoFactorAuthCustomer44\Entity; +use Doctrine\DBAL\Types\Types; use Doctrine\ORM\Mapping as ORM; use Eccube\Entity\AbstractEntity; +use Plugin\TwoFactorAuthCustomer44\Repository\TwoFactorAuthConfigRepository; use Symfony\Bridge\Doctrine\Validator\Constraints\UniqueEntity; -use Symfony\Component\Validator\Constraints as Assert; /** * TwoFactorConfig - * - * @ORM\Table(name="plg_two_factor_auth_config") - * @ORM\InheritanceType("SINGLE_TABLE") - * @ORM\DiscriminatorColumn(name="discriminator_type", type="string", length=255) - * @ORM\HasLifecycleCallbacks() - * @ORM\Entity(repositoryClass="Plugin\TwoFactorAuthCustomer42\Repository\TwoFactorAuthConfigRepository") - * @UniqueEntity("id") */ +#[ORM\Table(name: 'plg_two_factor_auth_config')] +#[ORM\InheritanceType('SINGLE_TABLE')] +#[ORM\DiscriminatorColumn(name: 'discriminator_type', type: Types::STRING, length: 255)] +#[ORM\HasLifecycleCallbacks] +#[ORM\Entity(repositoryClass: TwoFactorAuthConfigRepository::class)] +#[UniqueEntity('id')] class TwoFactorAuthConfig extends AbstractEntity { - /** - * @var int - * - * @ORM\Column(name="id", type="integer", options={"unsigned":true}) - * @ORM\Id - * @ORM\GeneratedValue(strategy="IDENTITY") - */ - private $id; + #[ORM\Column(name: 'id', type: Types::INTEGER, options: ['unsigned' => true])] + #[ORM\Id] + #[ORM\GeneratedValue(strategy: 'IDENTITY')] + private ?int $id = null; - /** - * @var string - * - * @ORM\Column(name="api_key", type="string", nullable=true, length=200) - */ - private $api_key = null; + #[ORM\Column(name: 'api_key', type: Types::STRING, nullable: true, length: 200)] + private ?string $api_key = null; - /** - * @var string - * - * @ORM\Column(name="api_secret", type="string", nullable=true, length=200) - */ - private $api_secret = null; + #[ORM\Column(name: 'api_secret', type: Types::STRING, nullable: true, length: 200)] + private ?string $api_secret = null; - private $plain_api_secret; + private ?string $plain_api_secret = null; - /** - * @var string - * - * @ORM\Column(name="from_phone_number", type="string", nullable=true, length=200) - */ - private $from_phone_number = null; + #[ORM\Column(name: 'from_phone_number', type: Types::STRING, nullable: true, length: 200)] + private ?string $from_phone_number = null; - /** - * @var string - * - * @ORM\Column(name="include_routes", type="text", nullable=true) - */ - private $include_routes = null; + #[ORM\Column(name: 'include_routes', type: Types::TEXT, nullable: true)] + private ?string $include_routes = null; /** * Constructor. @@ -78,20 +58,16 @@ public function __construct() /** * Get id. - * - * @return int */ - public function getId() + public function getId(): ?int { return $this->id; } /** * Get api_key. - * - * @return string */ - public function getApiKey() + public function getApiKey(): ?string { return $this->api_key; } @@ -99,11 +75,9 @@ public function getApiKey() /** * Set api_key. * - * @param string $apiKey - * - * @return TwoFactorAuthConfig + * @return $this */ - public function setApiKey($apiKey) + public function setApiKey(?string $apiKey): self { $this->api_key = $apiKey; @@ -112,10 +86,8 @@ public function setApiKey($apiKey) /** * Get api_secret. - * - * @return string */ - public function getApiSecret() + public function getApiSecret(): ?string { return $this->api_secret; } @@ -123,11 +95,9 @@ public function getApiSecret() /** * Set api_secret. * - * @param string $apiSecret - * - * @return TwoFactorAuthConfig + * @return $this */ - public function setApiSecret($apiSecret) + public function setApiSecret(?string $apiSecret): self { $this->api_secret = $apiSecret; @@ -136,10 +106,8 @@ public function setApiSecret($apiSecret) /** * Get from phone number. - * - * @return string */ - public function getFromPhoneNumber() + public function getFromPhoneNumber(): ?string { return $this->from_phone_number; } @@ -147,18 +115,19 @@ public function getFromPhoneNumber() /** * Set from phone number. * - * @param string $fromPhoneNumber - * - * @return TwoFactorAuthConfig + * @return $this */ - public function setFromPhoneNumber(string $fromPhoneNumber) + public function setFromPhoneNumber(string $fromPhoneNumber): self { $this->from_phone_number = $fromPhoneNumber; return $this; } - public function addIncludeRoute(string $route) + /** + * @return $this + */ + public function addIncludeRoute(string $route): self { $routes = $this->getRoutes($this->getIncludeRoutes()); @@ -180,10 +149,8 @@ private function getRoutes(?string $routes): array /** * Get include_routes. - * - * @return string|null */ - public function getIncludeRoutes() + public function getIncludeRoutes(): ?string { return $this->include_routes; } @@ -191,18 +158,19 @@ public function getIncludeRoutes() /** * Set include_routes. * - * @param string|null $include_routes - * - * @return TwoFactorAuthConfig + * @return $this */ - public function setIncludeRoutes($include_routes = null) + public function setIncludeRoutes(?string $include_routes = null): self { $this->include_routes = $include_routes; return $this; } - public function removeIncludeRoute(string $route) + /** + * @return $this + */ + public function removeIncludeRoute(string $route): self { $routes = $this->getRoutes($this->getIncludeRoutes()); @@ -220,20 +188,15 @@ private function getRoutesAsString(array $routes): string } /** - * @param string|null $plain_api_secret - * - * @return TwoFactorAuthConfig + * @return $this */ - public function setPlainApiSecret(?string $plain_api_secret): TwoFactorAuthConfig + public function setPlainApiSecret(?string $plain_api_secret): self { $this->plain_api_secret = $plain_api_secret; return $this; } - /** - * @return mixed - */ public function getPlainApiSecret(): ?string { return $this->plain_api_secret; diff --git a/Entity/TwoFactorAuthCustomerCookie.php b/Entity/TwoFactorAuthCustomerCookie.php index c88c42e..4053f6c 100644 --- a/Entity/TwoFactorAuthCustomerCookie.php +++ b/Entity/TwoFactorAuthCustomerCookie.php @@ -11,185 +11,120 @@ * file that was distributed with this source code. */ -namespace Plugin\TwoFactorAuthCustomer42\Entity; +namespace Plugin\TwoFactorAuthCustomer44\Entity; -use DateTime; +use Doctrine\DBAL\Types\Types; use Doctrine\ORM\Mapping as ORM; use Eccube\Entity\AbstractEntity; use Eccube\Entity\Customer; +use Plugin\TwoFactorAuthCustomer44\Repository\TwoFactorAuthCustomerCookieRepository; use Symfony\Bridge\Doctrine\Validator\Constraints\UniqueEntity; /** * TwoFactorCustomerCookie - * - * @ORM\Table(name="plg_two_factor_customer_cookie") - * @ORM\InheritanceType("SINGLE_TABLE") - * @ORM\DiscriminatorColumn(name="discriminator_type", type="string", length=255) - * @ORM\HasLifecycleCallbacks() - * @ORM\Entity(repositoryClass="Plugin\TwoFactorAuthCustomer42\Repository\TwoFactorAuthConfigRepository") - * @UniqueEntity("id") */ +#[ORM\Table(name: 'plg_two_factor_customer_cookie')] +#[ORM\InheritanceType('SINGLE_TABLE')] +#[ORM\DiscriminatorColumn(name: 'discriminator_type', type: Types::STRING, length: 255)] +#[ORM\HasLifecycleCallbacks] +#[ORM\Entity(repositoryClass: TwoFactorAuthCustomerCookieRepository::class)] +#[UniqueEntity('id')] class TwoFactorAuthCustomerCookie extends AbstractEntity { - /** - * @var int - * - * @ORM\Column(name="id", type="integer", options={"unsigned":true}) - * @ORM\Id - * @ORM\GeneratedValue(strategy="IDENTITY") - */ - private int $id; - /** - * @var Customer - * - * @ORM\ManyToOne(targetEntity="Eccube\Entity\Customer", inversedBy="TwoFactorCustomerCookie") - * @ORM\JoinColumns({ - * @ORM\JoinColumn(name="customer_id", referencedColumnName="id") - * }) - */ - private Customer $Customer; - /** - * @var string - * - * @ORM\Column(name="cookie_name", type="string", nullable=false, length=512) - */ + #[ORM\Column(name: 'id', type: Types::INTEGER, options: ['unsigned' => true])] + #[ORM\Id] + #[ORM\GeneratedValue(strategy: 'IDENTITY')] + private ?int $id = null; + + #[ORM\ManyToOne(targetEntity: Customer::class, inversedBy: 'TwoFactorAuthCustomerCookies')] + #[ORM\JoinColumn(name: 'customer_id', referencedColumnName: 'id')] + private ?Customer $Customer = null; + + #[ORM\Column(name: 'cookie_name', type: Types::STRING, nullable: false, length: 512)] private string $cookie_name; - /** - * @var string - * - * @ORM\Column(name="cookie_value", type="string", nullable=false, length=512, unique=true) - */ + + #[ORM\Column(name: 'cookie_value', type: Types::STRING, nullable: false, length: 512, unique: true)] private string $cookie_value; - /** - * @var \DateTime - * - * @ORM\Column(name="cookie_expire_date", type="datetime", nullable=true) - */ - private ?\DateTime $cookie_expire_date; - /** - * @var \DateTime - * - * @ORM\Column(name="created_at", type="datetime", nullable=false) - */ - private \DateTime $createdAt; - /** - * @var \DateTime - * - * @ORM\Column(name="updated_at", type="datetime", nullable=false) - */ - private \DateTime $updatedAt; - - /** - * @ORM\PrePersist - * @ORM\PreUpdate - */ + + #[ORM\Column(name: 'cookie_expire_date', type: Types::DATETIME_MUTABLE, nullable: true)] + private ?\DateTime $cookie_expire_date = null; + + #[ORM\Column(name: 'created_at', type: Types::DATETIME_MUTABLE, nullable: false)] + private ?\DateTime $createdAt = null; + + #[ORM\Column(name: 'updated_at', type: Types::DATETIME_MUTABLE, nullable: false)] + private ?\DateTime $updatedAt = null; + + #[ORM\PrePersist] + #[ORM\PreUpdate] public function updatedTimestamps(): void { $this->setUpdatedAt(new \DateTime('now')); - if (!isset($this->createdAt) || $this->getCreatedAt() === null) { + if ($this->getCreatedAt() === null) { $this->setCreatedAt(new \DateTime('now')); } } - /** - * @return \DateTime - */ - public function getCreatedAt(): \DateTime + public function getCreatedAt(): ?\DateTime { return $this->createdAt; } - /** - * @param \DateTime $createdAt - */ public function setCreatedAt(\DateTime $createdAt): void { $this->createdAt = $createdAt; } - /** - * @return int - */ - public function getId(): int + public function getId(): ?int { return $this->id; } - /** - * @return Customer - */ - public function getCustomer(): Customer + public function getCustomer(): ?Customer { return $this->Customer; } - /** - * @param Customer $Customer - */ public function setCustomer(Customer $Customer): void { $this->Customer = $Customer; } - /** - * @return string - */ public function getCookieName(): string { return $this->cookie_name; } - /** - * @param string $cookie_name - */ public function setCookieName(string $cookie_name): void { $this->cookie_name = $cookie_name; } - /** - * @return string - */ public function getCookieValue(): string { return $this->cookie_value; } - /** - * @param string $cookie_value - */ public function setCookieValue(string $cookie_value): void { $this->cookie_value = $cookie_value; } - /** - * @return \DateTime - */ - public function getCookieExpireDate(): \DateTime + public function getCookieExpireDate(): ?\DateTime { return $this->cookie_expire_date; } - /** - * @param \DateTime $cookie_expire_date - */ public function setCookieExpireDate(\DateTime $cookie_expire_date): void { $this->cookie_expire_date = $cookie_expire_date; } - /** - * @return \DateTime - */ - public function getUpdatedAt(): \DateTime + public function getUpdatedAt(): ?\DateTime { return $this->updatedAt; } - /** - * @param \DateTime $updatedAt - */ public function setUpdatedAt(\DateTime $updatedAt): void { $this->updatedAt = $updatedAt; diff --git a/Entity/TwoFactorAuthType.php b/Entity/TwoFactorAuthType.php index 0db26b0..9b4b589 100644 --- a/Entity/TwoFactorAuthType.php +++ b/Entity/TwoFactorAuthType.php @@ -11,53 +11,38 @@ * file that was distributed with this source code. */ -namespace Plugin\TwoFactorAuthCustomer42\Entity; +namespace Plugin\TwoFactorAuthCustomer44\Entity; +use Doctrine\DBAL\Types\Types; use Doctrine\ORM\Mapping as ORM; use Eccube\Entity\AbstractEntity; +use Plugin\TwoFactorAuthCustomer44\Repository\TwoFactorAuthTypeRepository; use Symfony\Bridge\Doctrine\Validator\Constraints\UniqueEntity; /** - * TwoFactorConfig - * - * @ORM\Table(name="plg_two_factor_auth_type") - * @ORM\InheritanceType("SINGLE_TABLE") - * @ORM\DiscriminatorColumn(name="discriminator_type", type="string", length=255) - * @ORM\HasLifecycleCallbacks() - * @ORM\Entity(repositoryClass="Plugin\TwoFactorAuthCustomer42\Repository\TwoFactorAuthTypeRepository") - * @UniqueEntity("id") + * TwoFactorAuthType */ +#[ORM\Table(name: 'plg_two_factor_auth_type')] +#[ORM\InheritanceType('SINGLE_TABLE')] +#[ORM\DiscriminatorColumn(name: 'discriminator_type', type: Types::STRING, length: 255)] +#[ORM\HasLifecycleCallbacks] +#[ORM\Entity(repositoryClass: TwoFactorAuthTypeRepository::class)] +#[UniqueEntity('id')] class TwoFactorAuthType extends AbstractEntity { - /** - * @var int - * - * @ORM\Column(name="id", type="integer", options={"unsigned":true}) - * @ORM\Id - * @ORM\GeneratedValue(strategy="IDENTITY") - */ - private $id; + #[ORM\Column(name: 'id', type: Types::INTEGER, options: ['unsigned' => true])] + #[ORM\Id] + #[ORM\GeneratedValue(strategy: 'IDENTITY')] + private ?int $id = null; - /** - * @var string - * - * @ORM\Column(name="name", type="string", nullable=false, length=200, unique=true) - */ - private $name; + #[ORM\Column(name: 'name', type: Types::STRING, nullable: false, length: 200, unique: true)] + private ?string $name = null; - /** - * @var string - * - * @ORM\Column(name="route", type="string", nullable=false, length=200, unique=true) - */ - private $route = null; + #[ORM\Column(name: 'route', type: Types::STRING, nullable: false, length: 200, unique: true)] + private ?string $route = null; - /** - * @var boolean - * - * @ORM\Column(name="is_disabled", type="boolean", nullable=false) - */ - private $isDisabled = false; + #[ORM\Column(name: 'is_disabled', type: Types::BOOLEAN, nullable: false)] + private bool $isDisabled = false; /** * Constructor. @@ -68,20 +53,16 @@ public function __construct() /** * Get id. - * - * @return int */ - public function getId() + public function getId(): ?int { return $this->id; } /** * Get name. - * - * @return string */ - public function getName() + public function getName(): ?string { return $this->name; } @@ -89,11 +70,9 @@ public function getName() /** * Set name. * - * @param string $name - * - * @return TwoFactorAuthType + * @return $this */ - public function setName($name) + public function setName(string $name): self { $this->name = $name; @@ -102,10 +81,8 @@ public function setName($name) /** * Get route. - * - * @return string */ - public function getRoute() + public function getRoute(): ?string { return $this->route; } @@ -113,28 +90,20 @@ public function getRoute() /** * Set route. * - * @param string $route - * - * @return TwoFactorAuthType + * @return $this */ - public function setRoute($route) + public function setRoute(string $route): self { $this->route = $route; return $this; } - /** - * @return bool - */ public function isDisabled(): bool { return $this->isDisabled; } - /** - * @param bool $isDisabled - */ public function setIsDisabled(bool $isDisabled): void { $this->isDisabled = $isDisabled; diff --git a/Event.php b/Event.php index 54c7850..dd14d23 100644 --- a/Event.php +++ b/Event.php @@ -11,10 +11,10 @@ * file that was distributed with this source code. */ -namespace Plugin\TwoFactorAuthCustomer42; +namespace Plugin\TwoFactorAuthCustomer44; use Eccube\Event\TemplateEvent; -use Plugin\TwoFactorAuthCustomer42\Repository\TwoFactorAuthTypeRepository; +use Plugin\TwoFactorAuthCustomer44\Repository\TwoFactorAuthTypeRepository; use Symfony\Component\EventDispatcher\EventSubscriberInterface; /** @@ -51,15 +51,15 @@ public static function getSubscribedEvents(): array * * @param TemplateEvent $event */ - public function onRenderAdminShopSettingEdit(TemplateEvent $event) + public function onRenderAdminShopSettingEdit(TemplateEvent $event): void { // add 本人確認認証 twig - $twig = 'TwoFactorAuthCustomer42/Resource/template/admin/shop_edit_sms.twig'; + $twig = '@TwoFactorAuthCustomer44/admin/shop_edit_sms.twig'; $event->addSnippet($twig); if ($this->hasActiveAuthType) { // add 2段階認証設定 twig - $twig = 'TwoFactorAuthCustomer42/Resource/template/admin/shop_edit_tfa.twig'; + $twig = '@TwoFactorAuthCustomer44/admin/shop_edit_tfa.twig'; $event->addSnippet($twig); } } @@ -70,10 +70,10 @@ public function onRenderAdminShopSettingEdit(TemplateEvent $event) * * @param TemplateEvent $event */ - public function onRenderAdminCustomerEdit(TemplateEvent $event) + public function onRenderAdminCustomerEdit(TemplateEvent $event): void { // add twig - $twig = 'TwoFactorAuthCustomer42/Resource/template/admin/customer_edit.twig'; + $twig = '@TwoFactorAuthCustomer44/admin/customer_edit.twig'; $event->addSnippet($twig); } } diff --git a/EventListener/CustomerPersonalValidationListener.php b/EventListener/CustomerPersonalValidationListener.php index 01ffb4f..0fb9779 100644 --- a/EventListener/CustomerPersonalValidationListener.php +++ b/EventListener/CustomerPersonalValidationListener.php @@ -11,14 +11,14 @@ * file that was distributed with this source code. */ -namespace Plugin\TwoFactorAuthCustomer42\EventListener; +namespace Plugin\TwoFactorAuthCustomer44\EventListener; use Eccube\Entity\BaseInfo; use Eccube\Repository\BaseInfoRepository; use Eccube\Repository\CustomerRepository; use Eccube\Request\Context; -use Plugin\TwoFactorAuthCustomer42\Repository\TwoFactorAuthTypeRepository; -use Plugin\TwoFactorAuthCustomer42\Service\CustomerTwoFactorAuthService; +use Plugin\TwoFactorAuthCustomer44\Repository\TwoFactorAuthTypeRepository; +use Plugin\TwoFactorAuthCustomer44\Service\CustomerTwoFactorAuthService; use Symfony\Component\EventDispatcher\EventSubscriberInterface; use Symfony\Component\HttpFoundation\RedirectResponse; use Symfony\Component\HttpFoundation\Session\Session; diff --git a/EventListener/CustomerTwoFactorAuthListener.php b/EventListener/CustomerTwoFactorAuthListener.php index fdf0ddc..18b7caf 100755 --- a/EventListener/CustomerTwoFactorAuthListener.php +++ b/EventListener/CustomerTwoFactorAuthListener.php @@ -11,7 +11,7 @@ * file that was distributed with this source code. */ -namespace Plugin\TwoFactorAuthCustomer42\EventListener; +namespace Plugin\TwoFactorAuthCustomer44\EventListener; use Eccube\Common\EccubeConfig; use Eccube\Entity\BaseInfo; @@ -19,9 +19,9 @@ use Eccube\Entity\Master\CustomerStatus; use Eccube\Repository\BaseInfoRepository; use Eccube\Request\Context; -use Plugin\TwoFactorAuthCustomer42\Repository\TwoFactorAuthTypeRepository; -use Plugin\TwoFactorAuthCustomer42\Repository\TwoFactorAuthCustomerCookieRepository; -use Plugin\TwoFactorAuthCustomer42\Service\CustomerTwoFactorAuthService; +use Plugin\TwoFactorAuthCustomer44\Repository\TwoFactorAuthTypeRepository; +use Plugin\TwoFactorAuthCustomer44\Repository\TwoFactorAuthCustomerCookieRepository; +use Plugin\TwoFactorAuthCustomer44\Service\CustomerTwoFactorAuthService; use Symfony\Component\EventDispatcher\EventSubscriberInterface; use Symfony\Component\HttpFoundation\RedirectResponse; use Symfony\Component\HttpFoundation\RequestStack; @@ -163,10 +163,8 @@ public function onKernelController(ControllerArgumentsEvent $event) * ログイン完了 イベントハンドラ. * * @param LoginSuccessEvent $event - * - * @return RedirectResponse|void */ - public function onLoginSuccess(LoginSuccessEvent $event) + public function onLoginSuccess(LoginSuccessEvent $event): void { if ($this->requestContext->isAdmin()) { // バックエンドURLの場合処理なし @@ -186,7 +184,9 @@ public function onLoginSuccess(LoginSuccessEvent $event) if ($this->requestContext->getCurrentUser()->getTwoFactorAuthType() !== null && $this->requestContext->getCurrentUser()->getTwoFactorAuthType()->isDisabled()) { // ユーザーが選択した2段階認証方式は無効になっている場合、ログアウトさせる。 - return new RedirectResponse($this->router->generate('logout'), 302); + $event->setResponse(new RedirectResponse($this->router->generate('logout'), 302)); + + return; } $this->multiFactorAuth( diff --git a/Form/Type/Extension/Admin/TwoFactorAuthBaseSettingTypeExtension.php b/Form/Type/Extension/Admin/TwoFactorAuthBaseSettingTypeExtension.php index 7efd56a..3709030 100644 --- a/Form/Type/Extension/Admin/TwoFactorAuthBaseSettingTypeExtension.php +++ b/Form/Type/Extension/Admin/TwoFactorAuthBaseSettingTypeExtension.php @@ -11,12 +11,12 @@ * file that was distributed with this source code. */ -namespace Plugin\TwoFactorAuthCustomer42\Form\Type\Extension\Admin; +namespace Plugin\TwoFactorAuthCustomer44\Form\Type\Extension\Admin; use Doctrine\ORM\EntityManagerInterface; use Eccube\Form\Type\Admin\ShopMasterType; use Eccube\Form\Type\ToggleSwitchType; -use Plugin\TwoFactorAuthCustomer42\Entity\TwoFactorAuthType; +use Plugin\TwoFactorAuthCustomer44\Entity\TwoFactorAuthType; use Symfony\Component\Form\AbstractTypeExtension; use Symfony\Component\Form\FormBuilderInterface; use Symfony\Component\Form\FormEvent; @@ -54,7 +54,7 @@ public static function getExtendedTypes(): iterable * @param FormBuilderInterface $builder * @param array $options */ - public function buildForm(FormBuilderInterface $builder, array $options) + public function buildForm(FormBuilderInterface $builder, array $options): void { if (!empty($options['skip_add_form'])) { return; diff --git a/Form/Type/Extension/Admin/TwoFactorAuthCustomerTypeExtension.php b/Form/Type/Extension/Admin/TwoFactorAuthCustomerTypeExtension.php index fe6eae8..3ea2ca9 100755 --- a/Form/Type/Extension/Admin/TwoFactorAuthCustomerTypeExtension.php +++ b/Form/Type/Extension/Admin/TwoFactorAuthCustomerTypeExtension.php @@ -11,13 +11,13 @@ * file that was distributed with this source code. */ -namespace Plugin\TwoFactorAuthCustomer42\Form\Type\Extension\Admin; +namespace Plugin\TwoFactorAuthCustomer44\Form\Type\Extension\Admin; use Doctrine\ORM\EntityManagerInterface; use Eccube\Form\Type\Admin\CustomerType; use Eccube\Form\Type\PhoneNumberType; use Eccube\Form\Type\ToggleSwitchType; -use Plugin\TwoFactorAuthCustomer42\Entity\TwoFactorAuthType; +use Plugin\TwoFactorAuthCustomer44\Entity\TwoFactorAuthType; use Symfony\Bridge\Doctrine\Form\Type\EntityType; use Symfony\Component\Form\AbstractTypeExtension; use Symfony\Component\Form\FormBuilderInterface; @@ -56,7 +56,7 @@ public static function getExtendedTypes(): iterable * @param FormBuilderInterface $builder * @param array $options */ - public function buildForm(FormBuilderInterface $builder, array $options) + public function buildForm(FormBuilderInterface $builder, array $options): void { if (!empty($options['skip_add_form'])) { return; diff --git a/Form/Type/TwoFactorAuthAppTypeCustomer.php b/Form/Type/TwoFactorAuthAppTypeCustomer.php index 4f61f4e..05b3f0b 100644 --- a/Form/Type/TwoFactorAuthAppTypeCustomer.php +++ b/Form/Type/TwoFactorAuthAppTypeCustomer.php @@ -11,7 +11,7 @@ * file that was distributed with this source code. */ -namespace Plugin\TwoFactorAuthCustomer42\Form\Type; +namespace Plugin\TwoFactorAuthCustomer44\Form\Type; use Symfony\Component\Form\AbstractType; use Symfony\Component\Form\Extension\Core\Type\HiddenType; @@ -24,7 +24,7 @@ class TwoFactorAuthAppTypeCustomer extends AbstractType /** * {@inheritdoc} */ - public function buildForm(FormBuilderInterface $builder, array $options) + public function buildForm(FormBuilderInterface $builder, array $options): void { $builder ->add( diff --git a/Form/Type/TwoFactorAuthConfigType.php b/Form/Type/TwoFactorAuthConfigType.php index 00cd14f..38df36f 100644 --- a/Form/Type/TwoFactorAuthConfigType.php +++ b/Form/Type/TwoFactorAuthConfigType.php @@ -11,10 +11,10 @@ * file that was distributed with this source code. */ -namespace Plugin\TwoFactorAuthCustomer42\Form\Type; +namespace Plugin\TwoFactorAuthCustomer44\Form\Type; use Eccube\Common\EccubeConfig; -use Plugin\TwoFactorAuthCustomer42\Entity\TwoFactorAuthConfig; +use Plugin\TwoFactorAuthCustomer44\Entity\TwoFactorAuthConfig; use Symfony\Component\Form\AbstractType; use Symfony\Component\Form\Extension\Core\Type\TextareaType; use Symfony\Component\Form\Extension\Core\Type\TextType; @@ -46,7 +46,7 @@ public function __construct(EccubeConfig $eccubeConfig, ValidatorInterface $vali $this->validator = $validator; } - public function buildForm(FormBuilderInterface $builder, array $options) + public function buildForm(FormBuilderInterface $builder, array $options): void { $builder ->add('api_key', TextType::class, [ diff --git a/Form/Type/TwoFactorAuthPhoneNumberTypeCustomer.php b/Form/Type/TwoFactorAuthPhoneNumberTypeCustomer.php index f6e665c..99ebed7 100644 --- a/Form/Type/TwoFactorAuthPhoneNumberTypeCustomer.php +++ b/Form/Type/TwoFactorAuthPhoneNumberTypeCustomer.php @@ -11,7 +11,7 @@ * file that was distributed with this source code. */ -namespace Plugin\TwoFactorAuthCustomer42\Form\Type; +namespace Plugin\TwoFactorAuthCustomer44\Form\Type; use Eccube\Form\Type\PhoneNumberType; use Symfony\Component\Form\AbstractType; @@ -22,7 +22,7 @@ class TwoFactorAuthPhoneNumberTypeCustomer extends AbstractType /** * {@inheritdoc} */ - public function buildForm(FormBuilderInterface $builder, array $options) + public function buildForm(FormBuilderInterface $builder, array $options): void { $builder ->add('phone_number', PhoneNumberType::class, [ diff --git a/Form/Type/TwoFactorAuthSmsTypeCustomer.php b/Form/Type/TwoFactorAuthSmsTypeCustomer.php index 6907926..eee2042 100644 --- a/Form/Type/TwoFactorAuthSmsTypeCustomer.php +++ b/Form/Type/TwoFactorAuthSmsTypeCustomer.php @@ -11,7 +11,7 @@ * file that was distributed with this source code. */ -namespace Plugin\TwoFactorAuthCustomer42\Form\Type; +namespace Plugin\TwoFactorAuthCustomer44\Form\Type; use Symfony\Component\Form\AbstractType; use Symfony\Component\Form\Extension\Core\Type\TextType; @@ -23,7 +23,7 @@ class TwoFactorAuthSmsTypeCustomer extends AbstractType /** * {@inheritdoc} */ - public function buildForm(FormBuilderInterface $builder, array $options) + public function buildForm(FormBuilderInterface $builder, array $options): void { $builder ->add( diff --git a/Form/Type/TwoFactorAuthTypeCustomer.php b/Form/Type/TwoFactorAuthTypeCustomer.php index 5240525..7dc4896 100644 --- a/Form/Type/TwoFactorAuthTypeCustomer.php +++ b/Form/Type/TwoFactorAuthTypeCustomer.php @@ -11,10 +11,10 @@ * file that was distributed with this source code. */ -namespace Plugin\TwoFactorAuthCustomer42\Form\Type; +namespace Plugin\TwoFactorAuthCustomer44\Form\Type; use Doctrine\ORM\EntityRepository; -use Plugin\TwoFactorAuthCustomer42\Entity\TwoFactorAuthType; +use Plugin\TwoFactorAuthCustomer44\Entity\TwoFactorAuthType; use Symfony\Bridge\Doctrine\Form\Type\EntityType; use Symfony\Component\Form\AbstractType; use Symfony\Component\Form\FormBuilderInterface; @@ -24,7 +24,7 @@ class TwoFactorAuthTypeCustomer extends AbstractType /** * {@inheritdoc} */ - public function buildForm(FormBuilderInterface $builder, array $options) + public function buildForm(FormBuilderInterface $builder, array $options): void { $builder ->add('two_factor_auth_type', EntityType::class, [ diff --git a/PluginManager.php b/PluginManager.php index 4e40a36..14fbb8e 100644 --- a/PluginManager.php +++ b/PluginManager.php @@ -11,15 +11,15 @@ * file that was distributed with this source code. */ -namespace Plugin\TwoFactorAuthCustomer42; +namespace Plugin\TwoFactorAuthCustomer44; use Doctrine\ORM\EntityManagerInterface; +use Eccube\Common\EccubeConfig; use Eccube\Entity\Layout; use Eccube\Entity\Page; use Eccube\Entity\PageLayout; use Eccube\Plugin\AbstractPluginManager; -use Eccube\Common\EccubeConfig; -use Plugin\TwoFactorAuthCustomer42\Entity\TwoFactorAuthConfig; +use Plugin\TwoFactorAuthCustomer44\Entity\TwoFactorAuthConfig; use Psr\Container\ContainerInterface; use Symfony\Component\Filesystem\Filesystem; @@ -29,17 +29,17 @@ class PluginManager extends AbstractPluginManager { // 設定対象ページ情報 - private $pages = [ - ['plg_customer_2fa_device_auth_send_onetime', 'デバイス認証送信先入力', 'TwoFactorAuthCustomer42/Resource/template/default/device_auth/send'], - ['plg_customer_2fa_device_auth_input_onetime', 'デバイス認証トークン入力', 'TwoFactorAuthCustomer42/Resource/template/default/device_auth/input'], - ['plg_customer_2fa_auth_type_select', '多要素認証方式選択', 'TwoFactorAuthCustomer42/Resource/template/default/tfa/select_type'], + private array $pages = [ + ['plg_customer_2fa_device_auth_send_onetime', 'デバイス認証送信先入力', 'TwoFactorAuthCustomer44/Resource/template/default/device_auth/send'], + ['plg_customer_2fa_device_auth_input_onetime', 'デバイス認証トークン入力', 'TwoFactorAuthCustomer44/Resource/template/default/device_auth/input'], + ['plg_customer_2fa_auth_type_select', '多要素認証方式選択', 'TwoFactorAuthCustomer44/Resource/template/default/tfa/select_type'], ]; /** - * @param array $meta + * @param array $meta * @param ContainerInterface $container */ - public function enable(array $meta, ContainerInterface $container) + public function enable(array $meta, ContainerInterface $container): void { $em = $container->get('doctrine')->getManager(); @@ -57,7 +57,7 @@ public function enable(array $meta, ContainerInterface $container) * * @param EntityManagerInterface $em */ - protected function createConfig(EntityManagerInterface $em) + protected function createConfig(EntityManagerInterface $em): void { $TwoFactorAuthConfig = $em->find(TwoFactorAuthConfig::class, 1); if ($TwoFactorAuthConfig) { @@ -75,17 +75,17 @@ protected function createConfig(EntityManagerInterface $em) * * @param ContainerInterface $container */ - protected function copyTwigFiles(ContainerInterface $container) + protected function copyTwigFiles(ContainerInterface $container): void { // テンプレートファイルコピー $templatePath = $container->get(EccubeConfig::class)->get('eccube_theme_front_dir') - . '/TwoFactorAuthCustomer42/Resource/template/default'; + .'/TwoFactorAuthCustomer44/Resource/template/default'; $fs = new Filesystem(); if ($fs->exists($templatePath)) { return; } $fs->mkdir($templatePath); - $fs->mirror(__DIR__ . '/Resource/template/default', $templatePath); + $fs->mirror(__DIR__.'/Resource/template/default', $templatePath); } /** @@ -93,7 +93,7 @@ protected function copyTwigFiles(ContainerInterface $container) * * @param EntityManagerInterface $em */ - protected function createPages(EntityManagerInterface $em) + protected function createPages(EntityManagerInterface $em): void { foreach ($this->pages as $p) { $hasPage = $em->getRepository(Page::class)->count(['url' => $p[0]]) > 0; @@ -123,10 +123,10 @@ protected function createPages(EntityManagerInterface $em) } /** - * @param array $meta + * @param array $meta * @param ContainerInterface $container */ - public function disable(array $meta, ContainerInterface $container) + public function disable(array $meta, ContainerInterface $container): void { $em = $container->get('doctrine')->getManager(); @@ -142,10 +142,10 @@ public function disable(array $meta, ContainerInterface $container) * * @param ContainerInterface $container */ - protected function removeTwigFiles(ContainerInterface $container) + protected function removeTwigFiles(ContainerInterface $container): void { $templatePath = $container->get(EccubeConfig::class)->get('eccube_theme_front_dir') - . '/TwoFactorAuthCustomer42'; + .'/TwoFactorAuthCustomer44'; $fs = new Filesystem(); $fs->remove($templatePath); } @@ -155,7 +155,7 @@ protected function removeTwigFiles(ContainerInterface $container) * * @param EntityManagerInterface $em */ - protected function removePages(EntityManagerInterface $em) + protected function removePages(EntityManagerInterface $em): void { foreach ($this->pages as $p) { $Page = $em->getRepository(Page::class)->findOneBy(['url' => $p[0]]); @@ -171,17 +171,16 @@ protected function removePages(EntityManagerInterface $em) } /** - * @param array $meta + * @param array $meta * @param ContainerInterface $container */ - public function uninstall(array $meta, ContainerInterface $container) + public function uninstall(array $meta, ContainerInterface $container): void { - $em = $container->get('doctrine')->getManager(); - // twigファイルを削除 $this->removeTwigFiles($container); // ページ削除 + $em = $container->get('doctrine')->getManager(); $this->removePages($em); } } diff --git a/README.md b/README.md index f17f5a0..5c0d3d4 100644 --- a/README.md +++ b/README.md @@ -1 +1,3 @@ -# 2段階認証プラグイン +# 2段階認証プラグイン (EC-CUBE 4.4) + +EC-CUBE 4.2/4.3 向け `TwoFactorAuthCustomer42` を EC-CUBE 4.4 / Symfony 7.4 向け `TwoFactorAuthCustomer44` に移行したプラグインです。 diff --git a/Repository/TwoFactorAuthConfigRepository.php b/Repository/TwoFactorAuthConfigRepository.php index b024e34..f97d2ac 100644 --- a/Repository/TwoFactorAuthConfigRepository.php +++ b/Repository/TwoFactorAuthConfigRepository.php @@ -11,12 +11,11 @@ * file that was distributed with this source code. */ -namespace Plugin\TwoFactorAuthCustomer42\Repository; +namespace Plugin\TwoFactorAuthCustomer44\Repository; use Doctrine\Persistence\ManagerRegistry; use Eccube\Repository\AbstractRepository; -use Plugin\TwoFactorAuthCustomer42\Entity\TwoFactorAuthConfig; -use Plugin\TwoFactorAuthCustomer42\Entity\TwoFactorAuthCustomerCookie; +use Plugin\TwoFactorAuthCustomer44\Entity\TwoFactorAuthConfig; /** * TwoFactorAuthConfigRepository. @@ -37,7 +36,7 @@ public function __construct(ManagerRegistry $registry) } /** - * @return object|TwoFactorAuthConfig|TwoFactorAuthCustomerCookie|null $result + * @return TwoFactorAuthConfig|null */ public function findOne() { diff --git a/Repository/TwoFactorAuthCustomerCookieRepository.php b/Repository/TwoFactorAuthCustomerCookieRepository.php index 8d7d4f5..a703eec 100644 --- a/Repository/TwoFactorAuthCustomerCookieRepository.php +++ b/Repository/TwoFactorAuthCustomerCookieRepository.php @@ -11,14 +11,14 @@ * file that was distributed with this source code. */ -namespace Plugin\TwoFactorAuthCustomer42\Repository; +namespace Plugin\TwoFactorAuthCustomer44\Repository; use Carbon\Carbon; use Doctrine\Persistence\ManagerRegistry; use Eccube\Entity\Customer; use Eccube\Repository\AbstractRepository; use Eccube\Util\StringUtil; -use Plugin\TwoFactorAuthCustomer42\Entity\TwoFactorAuthCustomerCookie; +use Plugin\TwoFactorAuthCustomer44\Entity\TwoFactorAuthCustomerCookie; /** * TwoFactorAuthConfigRepository. diff --git a/Repository/TwoFactorAuthTypeRepository.php b/Repository/TwoFactorAuthTypeRepository.php index 5672da0..3376ec1 100644 --- a/Repository/TwoFactorAuthTypeRepository.php +++ b/Repository/TwoFactorAuthTypeRepository.php @@ -11,11 +11,11 @@ * file that was distributed with this source code. */ -namespace Plugin\TwoFactorAuthCustomer42\Repository; +namespace Plugin\TwoFactorAuthCustomer44\Repository; use Doctrine\Persistence\ManagerRegistry; use Eccube\Repository\AbstractRepository; -use Plugin\TwoFactorAuthCustomer42\Entity\TwoFactorAuthType; +use Plugin\TwoFactorAuthCustomer44\Entity\TwoFactorAuthType; /** * TwoFactorAuthTypeRepository. diff --git a/Resource/.php-cs-fixer.dist.php b/Resource/.php-cs-fixer.dist.php new file mode 100644 index 0000000..79d83ee --- /dev/null +++ b/Resource/.php-cs-fixer.dist.php @@ -0,0 +1,57 @@ + true, + 'array_syntax' => ['syntax' => 'short'], + 'phpdoc_align' => false, + 'phpdoc_summary' => false, + 'phpdoc_annotation_without_dot' => false, + 'no_superfluous_phpdoc_tags' => false, + 'increment_style' => false, + 'yoda_style' => false, + 'header_comment' => ['header' => $header], + 'phpdoc_add_missing_param_annotation' => true, + 'phpdoc_param_order' => true, + 'phpdoc_to_comment' => false, // /** @var */ を変換してしまうため + 'phpdoc_trim' => true, + 'global_namespace_import' => [ + 'import_classes' => false, + 'import_constants' => false, + 'import_functions' => false, + ], + // PHPDocの型をネイティブ型へ + 'phpdoc_to_param_type' => true, + 'phpdoc_to_return_type' => true, + // プロパティのネイティブ型化は無効。EC-CUBE のテスト基盤が tearDown で全プロパティに + // null を代入するため、テストプロパティを非null native 型にすると TypeError になる。 + 'phpdoc_to_property_type' => false, +]; + +$finder = \PhpCsFixer\Finder::create() + ->in(dirname(__DIR__)) + ->exclude(['vendor', 'node_modules', 'Resource']) + ->name('*.php') +; +$config = new \PhpCsFixer\Config(); + +return $config + ->setRules($rules) + ->setFinder($finder) + ->setRiskyAllowed(true) + ->setUnsupportedPhpVersionAllowed(true) +; diff --git a/Resource/rector.php b/Resource/rector.php new file mode 100644 index 0000000..577ad4a --- /dev/null +++ b/Resource/rector.php @@ -0,0 +1,62 @@ +withPhpVersion(PhpVersion::PHP_82) + // プラグインのソースディレクトリ + ->withPaths([ + dirname(__DIR__).'/Controller', + dirname(__DIR__).'/Entity', + dirname(__DIR__).'/Form', + dirname(__DIR__).'/Repository', + dirname(__DIR__).'/Service', + dirname(__DIR__).'/EventListener', + dirname(__DIR__).'/PluginManager.php', + dirname(__DIR__).'/Event.php', + ]) + ->withSkip([ + dirname(__DIR__).'/vendor', + dirname(__DIR__).'/node_modules', + ]) + ->withSets([ + LevelSetList::UP_TO_PHP_82, + // Symfony 7.4 対応 (@Route → #[Route], @Template, buildForm(): void 等) + SymfonySetList::SYMFONY_74, + SymfonySetList::SYMFONY_CODE_QUALITY, + // Doctrine ORM 3.0 / DBAL 3.0 対応 (@ORM → #[ORM], 型付きプロパティ) + DoctrineSetList::DOCTRINE_CODE_QUALITY, + DoctrineSetList::DOCTRINE_DBAL_30, + DoctrineSetList::ANNOTATIONS_TO_ATTRIBUTES, + ]) + // Symfony/Doctrine 等のアノテーション → アトリビュート変換を有効化 + ->withAttributesSets() + // #[Route] は付与されるが use 文が旧 Annotation のまま残るため Attribute へ統一する + ->withConfiguredRule(RenameClassRector::class, [ + 'Symfony\Component\Routing\Annotation\Route' => 'Symfony\Component\Routing\Attribute\Route', + ]) + ->withImportNames( + importShortClasses: false, + importDocBlockNames: true, + importNames: true + ) + ->withParallel(); diff --git a/Resource/template/admin/config.twig b/Resource/template/admin/config.twig index 2c87445..e6c61c3 100644 --- a/Resource/template/admin/config.twig +++ b/Resource/template/admin/config.twig @@ -9,7 +9,7 @@ {% block main %} -
+ {{ form_widget(form._token) }}
diff --git a/Service/CustomerTwoFactorAuthService.php b/Service/CustomerTwoFactorAuthService.php index 99d78af..fdca85b 100644 --- a/Service/CustomerTwoFactorAuthService.php +++ b/Service/CustomerTwoFactorAuthService.php @@ -11,23 +11,23 @@ * file that was distributed with this source code. */ -namespace Plugin\TwoFactorAuthCustomer42\Service; +namespace Plugin\TwoFactorAuthCustomer44\Service; use Doctrine\ORM\EntityManagerInterface; use Eccube\Common\EccubeConfig; use Eccube\Entity\BaseInfo; use Eccube\Entity\Customer; use Eccube\Repository\BaseInfoRepository; -use Plugin\TwoFactorAuthCustomer42\Entity\TwoFactorAuthCustomerCookie; -use Plugin\TwoFactorAuthCustomer42\Repository\TwoFactorAuthConfigRepository; -use Plugin\TwoFactorAuthCustomer42\Repository\TwoFactorAuthCustomerCookieRepository; +use Plugin\TwoFactorAuthCustomer44\Entity\TwoFactorAuthConfig; +use Plugin\TwoFactorAuthCustomer44\Entity\TwoFactorAuthCustomerCookie; +use Plugin\TwoFactorAuthCustomer44\Repository\TwoFactorAuthConfigRepository; +use Plugin\TwoFactorAuthCustomer44\Repository\TwoFactorAuthCustomerCookieRepository; use Symfony\Component\DependencyInjection\ParameterBag\ContainerBagInterface; use Symfony\Component\HttpFoundation\Cookie; use Symfony\Component\HttpFoundation\Request; use Symfony\Component\HttpFoundation\RequestStack; use Symfony\Component\HttpFoundation\Response; use Symfony\Component\PasswordHasher\Hasher\PasswordHasherFactoryInterface; -use Symfony\Component\Security\Core\Encoder\EncoderFactoryInterface; use Twilio\Exceptions\ConfigurationException; use Twilio\Exceptions\TwilioException; use Twilio\Rest\Client; @@ -52,10 +52,6 @@ class CustomerTwoFactorAuthService * @var EccubeConfig */ protected $eccubeConfig; - /** - * @var EncoderFactoryInterface - */ - protected $encoderFactory; /** * @var RequestStack */ diff --git a/Tests/bootstrap.php b/Tests/bootstrap.php new file mode 100644 index 0000000..e465994 --- /dev/null +++ b/Tests/bootstrap.php @@ -0,0 +1,19 @@ +load($envFile); +} diff --git a/composer.json b/composer.json index 3d76137..db5265b 100644 --- a/composer.json +++ b/composer.json @@ -1,10 +1,10 @@ { - "name": "ec-cube/twofactorauthcustomer42", - "version": "4.3.0", - "description": "2 factor authentication for Customers EC-CUBE42", + "name": "ec-cube/twofactorauthcustomer44", + "version": "4.4.0", + "description": "2 factor authentication for Customers EC-CUBE 4.4", "type": "eccube-plugin", "extra": { - "code": "TwoFactorAuthCustomer42" + "code": "TwoFactorAuthCustomer44" }, "require": { "ec-cube/plugin-installer": "^2.0", diff --git a/phpstan.neon.dist b/phpstan.neon.dist new file mode 100644 index 0000000..580d6c4 --- /dev/null +++ b/phpstan.neon.dist @@ -0,0 +1,10 @@ +parameters: + level: 6 + paths: + - . + excludePaths: + - Resource/* + - Tests/bootstrap.php + doctrine: + objectManagerLoader: ../../../tests/object-manager.php + ormRepositoryClass: Eccube\Repository\AbstractRepository diff --git a/phpunit.xml.dist b/phpunit.xml.dist index dd5996d..274abad 100644 --- a/phpunit.xml.dist +++ b/phpunit.xml.dist @@ -1,20 +1,20 @@ + - - - - - - - - + + + + + + + @@ -24,26 +24,20 @@ - - - - - + + + ./ - - ./Tests - ./Resource - ./PluginManager.php - - - + + + ./Tests + ./Resource + ./PluginManager.php + + - - - - + + + + From c6faf5e7724af2999d3e5a4624885f80ac84bde2 Mon Sep 17 00:00:00 2001 From: Ken Tanaka Date: Tue, 14 Jul 2026 11:53:15 +0900 Subject: [PATCH 02/16] =?UTF-8?q?=E3=82=AF=E3=82=A8=E3=83=AA=E3=83=91?= =?UTF-8?q?=E3=83=A9=E3=83=A1=E3=83=BC=E3=82=BF=E8=A8=AD=E5=AE=9A=E3=81=AE?= =?UTF-8?q?=E4=BF=AE=E6=AD=A3?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../TwoFactorAuthCustomerCookieRepository.php | 16 ++++++---------- 1 file changed, 6 insertions(+), 10 deletions(-) diff --git a/Repository/TwoFactorAuthCustomerCookieRepository.php b/Repository/TwoFactorAuthCustomerCookieRepository.php index a703eec..4e2f388 100644 --- a/Repository/TwoFactorAuthCustomerCookieRepository.php +++ b/Repository/TwoFactorAuthCustomerCookieRepository.php @@ -88,11 +88,9 @@ public function findOldCookies(Customer $customer, string $cookieName) ->where('tfcc.Customer = :customer_id') ->andWhere('tfcc.cookie_name = :cookie_name') ->andWhere('tfcc.cookie_expire_date < :expire_date') - ->setParameters([ - 'customer_id' => $customer->getId(), - 'cookie_name' => $cookieName, - 'expire_date' => $expireDate, - ]) + ->setParameter('customer_id', $customer->getId()) + ->setParameter('cookie_name', $cookieName) + ->setParameter('expire_date', $expireDate) ->getQuery() ->getResult(); } @@ -120,11 +118,9 @@ public function searchForCookie(Customer $customer, string $cookieName) ->where('tfcc.Customer = :customer_id') ->andWhere('tfcc.cookie_name = :cookie_name') ->andWhere('tfcc.cookie_expire_date > :expire_date') - ->setParameters([ - 'customer_id' => $customer->getId(), - 'cookie_name' => $cookieName, - 'expire_date' => $expireDate, - ]) + ->setParameter('customer_id', $customer->getId()) + ->setParameter('cookie_name', $cookieName) + ->setParameter('expire_date', $expireDate) ->getQuery() ->getResult(); } From 6a6ab61fceebed96b5f9a2724344340684751d63 Mon Sep 17 00:00:00 2001 From: Ken Tanaka Date: Tue, 14 Jul 2026 12:08:24 +0900 Subject: [PATCH 03/16] =?UTF-8?q?nullable=E3=81=AE=E4=BF=AE=E6=AD=A3?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Entity/TwoFactorAuthCustomerCookie.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Entity/TwoFactorAuthCustomerCookie.php b/Entity/TwoFactorAuthCustomerCookie.php index 4053f6c..e384e4e 100644 --- a/Entity/TwoFactorAuthCustomerCookie.php +++ b/Entity/TwoFactorAuthCustomerCookie.php @@ -115,7 +115,7 @@ public function getCookieExpireDate(): ?\DateTime return $this->cookie_expire_date; } - public function setCookieExpireDate(\DateTime $cookie_expire_date): void + public function setCookieExpireDate(?\DateTime $cookie_expire_date): void { $this->cookie_expire_date = $cookie_expire_date; } From 244da88bb0c6a19ec7c954892c485dc29c1e2b7b Mon Sep 17 00:00:00 2001 From: Ken Tanaka Date: Mon, 14 Sep 2026 13:59:56 +0900 Subject: [PATCH 04/16] =?UTF-8?q?=E3=83=96=E3=83=A9=E3=83=B3=E3=83=814.4?= =?UTF-8?q?=E3=81=B8=E5=A4=89=E6=9B=B4?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .github/workflows/ab-testing.yml | 24 ++++++++++++++++-------- .github/workflows/e2e-testing.yml | 6 ++++-- 2 files changed, 20 insertions(+), 10 deletions(-) diff --git a/.github/workflows/ab-testing.yml b/.github/workflows/ab-testing.yml index 99a4913..823054e 100644 --- a/.github/workflows/ab-testing.yml +++ b/.github/workflows/ab-testing.yml @@ -29,12 +29,14 @@ jobs: - name: Download Plugin TwoFactorAuthCustomerApp44 uses: actions/checkout@master with: - repository: ${{ github.repository_owner }}/TwoFactorAuthCustomerApp44 + repository: ${{ github.repository_owner }}/TwoFactorAuthCustomerApp42 + ref: '4.4' path: app/Plugin/TwoFactorAuthCustomerApp44 - name: Download Plugin TwoFactorAuthCustomerSms44 uses: actions/checkout@master with: - repository: ${{ github.repository_owner }}/TwoFactorAuthCustomerSms44 + repository: ${{ github.repository_owner }}/TwoFactorAuthCustomerSms42 + ref: '4.4' path: app/Plugin/TwoFactorAuthCustomerSms44 - name: Sleep for MySQL run: sleep 120s @@ -224,12 +226,14 @@ jobs: - name: Download Plugin TwoFactorAuthCustomerApp44 uses: actions/checkout@master with: - repository: ${{ github.repository_owner }}/TwoFactorAuthCustomerApp44 + repository: ${{ github.repository_owner }}/TwoFactorAuthCustomerApp42 + ref: '4.4' path: app/Plugin/TwoFactorAuthCustomerApp44 - name: Download Plugin TwoFactorAuthCustomerSms44 uses: actions/checkout@master with: - repository: ${{ github.repository_owner }}/TwoFactorAuthCustomerSms44 + repository: ${{ github.repository_owner }}/TwoFactorAuthCustomerSms42 + ref: '4.4' path: app/Plugin/TwoFactorAuthCustomerSms44 - name: Start Load EC-CUBE run: | @@ -442,12 +446,14 @@ jobs: - name: Download Plugin TwoFactorAuthCustomerApp44 uses: actions/checkout@master with: - repository: ${{ github.repository_owner }}/TwoFactorAuthCustomerApp44 + repository: ${{ github.repository_owner }}/TwoFactorAuthCustomerApp42 + ref: '4.4' path: app/Plugin/TwoFactorAuthCustomerApp44 - name: Download Plugin TwoFactorAuthCustomerSms44 uses: actions/checkout@master with: - repository: ${{ github.repository_owner }}/TwoFactorAuthCustomerSms44 + repository: ${{ github.repository_owner }}/TwoFactorAuthCustomerSms42 + ref: '4.4' path: app/Plugin/TwoFactorAuthCustomerSms44 - name: Start Load EC-CUBE run: | @@ -682,12 +688,14 @@ jobs: - name: Download Plugin TwoFactorAuthCustomerApp44 uses: actions/checkout@master with: - repository: ${{ github.repository_owner }}/TwoFactorAuthCustomerApp44 + repository: ${{ github.repository_owner }}/TwoFactorAuthCustomerApp42 + ref: '4.4' path: app/Plugin/TwoFactorAuthCustomerApp44 - name: Download Plugin TwoFactorAuthCustomerSms44 uses: actions/checkout@master with: - repository: ${{ github.repository_owner }}/TwoFactorAuthCustomerSms44 + repository: ${{ github.repository_owner }}/TwoFactorAuthCustomerSms42 + ref: '4.4' path: app/Plugin/TwoFactorAuthCustomerSms44 - name: Start Load EC-CUBE run: | diff --git a/.github/workflows/e2e-testing.yml b/.github/workflows/e2e-testing.yml index 86ecb10..b2dd4d3 100644 --- a/.github/workflows/e2e-testing.yml +++ b/.github/workflows/e2e-testing.yml @@ -78,12 +78,14 @@ jobs: - name: Download Plugin TwoFactorAuthCustomerApp44 uses: actions/checkout@master with: - repository: ${{ github.repository_owner }}/TwoFactorAuthCustomerApp44 + repository: ${{ github.repository_owner }}/TwoFactorAuthCustomerApp42 + ref: '4.4' path: app/Plugin/TwoFactorAuthCustomerApp44 - name: Download Plugin TwoFactorAuthCustomerSms44 uses: actions/checkout@master with: - repository: ${{ github.repository_owner }}/TwoFactorAuthCustomerSms44 + repository: ${{ github.repository_owner }}/TwoFactorAuthCustomerSms42 + ref: '4.4' path: app/Plugin/TwoFactorAuthCustomerSms44 - name: Install Plugins env: From 3647a5a374af5f9de007f452c6ba9bd87def1a9d Mon Sep 17 00:00:00 2001 From: Ken Tanaka Date: Mon, 14 Sep 2026 14:31:04 +0900 Subject: [PATCH 05/16] =?UTF-8?q?doctrine:database:create=E3=81=AE?= =?UTF-8?q?=E5=AF=BE=E5=BF=9C?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .github/workflows/main.yml | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml index e828e97..d2d45e6 100644 --- a/.github/workflows/main.yml +++ b/.github/workflows/main.yml @@ -208,7 +208,11 @@ jobs: - name: Setup EC-CUBE working-directory: 'ec-cube' run: | - bin/console doctrine:database:create + # DBAL 4 の SQLite は doctrine:database:create 非対応(getCreateDatabaseSQL が削除済み)。 + # 本体 InstallerCommand と同様、SQLite ではファイル作成をスキップし schema:create で用意する。 + if [[ "${DATABASE_URL}" != sqlite* ]]; then + bin/console doctrine:database:create + fi bin/console doctrine:schema:create # プラグイン有効化時に DeviceType 等のマスタデータを参照するため fixtures を投入する bin/console eccube:fixtures:load From b3bd92807c1086028d1a111622f7904959919415 Mon Sep 17 00:00:00 2001 From: Ken Tanaka Date: Mon, 14 Sep 2026 14:40:19 +0900 Subject: [PATCH 06/16] =?UTF-8?q?cs-fixer=E5=AF=BE=E5=BF=9C?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Controller/Admin/ConfigController.php | 2 +- .../CustomerPersonalValidationController.php | 16 ++++---- .../TwoFactorAuthCustomerController.php | 6 +-- Entity/BaseInfoTrait.php | 2 +- Entity/CustomerTrait.php | 6 ++- Entity/TwoFactorAuthConfig.php | 2 +- Entity/TwoFactorAuthCustomerCookie.php | 2 +- Entity/TwoFactorAuthType.php | 2 +- Event.php | 2 +- .../CustomerPersonalValidationListener.php | 11 ++--- .../CustomerTwoFactorAuthListener.php | 20 +++++----- .../TwoFactorAuthBaseSettingTypeExtension.php | 10 ++--- .../TwoFactorAuthCustomerTypeExtension.php | 4 +- Form/Type/TwoFactorAuthAppTypeCustomer.php | 40 +++++++++---------- Form/Type/TwoFactorAuthConfigType.php | 2 +- .../TwoFactorAuthPhoneNumberTypeCustomer.php | 2 +- Form/Type/TwoFactorAuthSmsTypeCustomer.php | 30 +++++++------- Form/Type/TwoFactorAuthTypeCustomer.php | 2 +- PluginManager.php | 2 +- Repository/TwoFactorAuthConfigRepository.php | 4 +- .../TwoFactorAuthCustomerCookieRepository.php | 10 ++--- Repository/TwoFactorAuthTypeRepository.php | 4 +- Service/CustomerTwoFactorAuthService.php | 38 +++++++++--------- 23 files changed, 107 insertions(+), 112 deletions(-) diff --git a/Controller/Admin/ConfigController.php b/Controller/Admin/ConfigController.php index 216ab8c..5e60ff6 100644 --- a/Controller/Admin/ConfigController.php +++ b/Controller/Admin/ConfigController.php @@ -5,7 +5,7 @@ * * Copyright(c) EC-CUBE CO.,LTD. All Rights Reserved. * - * http://www.ec-cube.co.jp/ + * https://www.ec-cube.co.jp/ * * For the full copyright and license information, please view the LICENSE * file that was distributed with this source code. diff --git a/Controller/CustomerPersonalValidationController.php b/Controller/CustomerPersonalValidationController.php index 1542e3c..2e232a7 100644 --- a/Controller/CustomerPersonalValidationController.php +++ b/Controller/CustomerPersonalValidationController.php @@ -5,7 +5,7 @@ * * Copyright(c) EC-CUBE CO.,LTD. All Rights Reserved. * - * http://www.ec-cube.co.jp/ + * https://www.ec-cube.co.jp/ * * For the full copyright and license information, please view the LICENSE * file that was distributed with this source code. @@ -112,11 +112,10 @@ public function deviceAuthInputOneTime(Request $request, $secret_key) 'entry_activate', ['secret_key' => $secret_key] ); - } else { - // 認証済の場合はスキップ - log_warning('[デバイス認証(SMS)] 既に認証済みの電話番号指定'); - $error = trans('front.2fa.onetime.invalid_message__reinput'); } + // 認証済の場合はスキップ + log_warning('[デバイス認証(SMS)] 既に認証済みの電話番号指定'); + $error = trans('front.2fa.onetime.invalid_message__reinput'); } } else { $error = trans('front.2fa.onetime.invalid_message__reinput'); @@ -190,9 +189,8 @@ public function deviceAuthSendOneTime(Request $request, $secret_key) 'plg_customer_2fa_device_auth_input_onetime', ['secret_key' => $secret_key] ); - } else { - $error = trans('front.2fa.sms.send.failure_message'); } + $error = trans('front.2fa.sms.send.failure_message'); } return [ @@ -211,7 +209,7 @@ public function deviceAuthSendOneTime(Request $request, $secret_key) * * @return bool */ - private function checkDeviceToken($Customer, $token): bool + private function checkDeviceToken(Customer $Customer, string $token): bool { $now = new \DateTime(); @@ -237,7 +235,7 @@ private function checkDeviceToken($Customer, $token): bool * @throws TwilioException * @throws \Exception */ - private function sendDeviceToken(Customer $Customer, string $phoneNumber) + private function sendDeviceToken(Customer $Customer, string $phoneNumber): MessageInstance { // ワンタイムトークン生成・保存 $token = $this->customerTwoFactorAuthService->generateOneTimeTokenValue(); diff --git a/Controller/TwoFactorAuthCustomerController.php b/Controller/TwoFactorAuthCustomerController.php index ba14308..995f0b0 100644 --- a/Controller/TwoFactorAuthCustomerController.php +++ b/Controller/TwoFactorAuthCustomerController.php @@ -5,7 +5,7 @@ * * Copyright(c) EC-CUBE CO.,LTD. All Rights Reserved. * - * http://www.ec-cube.co.jp/ + * https://www.ec-cube.co.jp/ * * For the full copyright and license information, please view the LICENSE * file that was distributed with this source code. @@ -71,11 +71,11 @@ public function selectAuthType(Request $request) // 2段階認証を有効に更新 $this->entityManager->persist($Customer); $this->entityManager->flush(); + // 初回認証を実施 return $this->redirectToRoute($TwoFactorAuthType->getRoute()); - } else { - $error = trans('front.2fa.onetime.invalid_message__reinput'); } + $error = trans('front.2fa.onetime.invalid_message__reinput'); } return [ diff --git a/Entity/BaseInfoTrait.php b/Entity/BaseInfoTrait.php index 4a54634..3ec45f9 100644 --- a/Entity/BaseInfoTrait.php +++ b/Entity/BaseInfoTrait.php @@ -5,7 +5,7 @@ * * Copyright(c) EC-CUBE CO.,LTD. All Rights Reserved. * - * http://www.ec-cube.co.jp/ + * https://www.ec-cube.co.jp/ * * For the full copyright and license information, please view the LICENSE * file that was distributed with this source code. diff --git a/Entity/CustomerTrait.php b/Entity/CustomerTrait.php index c5de9a2..af332b8 100644 --- a/Entity/CustomerTrait.php +++ b/Entity/CustomerTrait.php @@ -5,7 +5,7 @@ * * Copyright(c) EC-CUBE CO.,LTD. All Rights Reserved. * - * http://www.ec-cube.co.jp/ + * https://www.ec-cube.co.jp/ * * For the full copyright and license information, please view the LICENSE * file that was distributed with this source code. @@ -71,9 +71,11 @@ public function getDeviceAuthOneTimeTokenExpire(): ?\DateTime /** * Set oneTimeTokenExpire. * + * @param mixed|null $deviceAuthOneTimeTokenExpire + * * @return Customer */ - public function setDeviceAuthOneTimeTokenExpire($deviceAuthOneTimeTokenExpire = null) + public function setDeviceAuthOneTimeTokenExpire(mixed $deviceAuthOneTimeTokenExpire = null): Customer { $this->device_auth_one_time_token_expire = $deviceAuthOneTimeTokenExpire; diff --git a/Entity/TwoFactorAuthConfig.php b/Entity/TwoFactorAuthConfig.php index d306b0c..2bdddb2 100644 --- a/Entity/TwoFactorAuthConfig.php +++ b/Entity/TwoFactorAuthConfig.php @@ -5,7 +5,7 @@ * * Copyright(c) EC-CUBE CO.,LTD. All Rights Reserved. * - * http://www.ec-cube.co.jp/ + * https://www.ec-cube.co.jp/ * * For the full copyright and license information, please view the LICENSE * file that was distributed with this source code. diff --git a/Entity/TwoFactorAuthCustomerCookie.php b/Entity/TwoFactorAuthCustomerCookie.php index e384e4e..543f4ce 100644 --- a/Entity/TwoFactorAuthCustomerCookie.php +++ b/Entity/TwoFactorAuthCustomerCookie.php @@ -5,7 +5,7 @@ * * Copyright(c) EC-CUBE CO.,LTD. All Rights Reserved. * - * http://www.ec-cube.co.jp/ + * https://www.ec-cube.co.jp/ * * For the full copyright and license information, please view the LICENSE * file that was distributed with this source code. diff --git a/Entity/TwoFactorAuthType.php b/Entity/TwoFactorAuthType.php index 9b4b589..1e02d88 100644 --- a/Entity/TwoFactorAuthType.php +++ b/Entity/TwoFactorAuthType.php @@ -5,7 +5,7 @@ * * Copyright(c) EC-CUBE CO.,LTD. All Rights Reserved. * - * http://www.ec-cube.co.jp/ + * https://www.ec-cube.co.jp/ * * For the full copyright and license information, please view the LICENSE * file that was distributed with this source code. diff --git a/Event.php b/Event.php index dd14d23..8c61a9e 100644 --- a/Event.php +++ b/Event.php @@ -5,7 +5,7 @@ * * Copyright(c) EC-CUBE CO.,LTD. All Rights Reserved. * - * http://www.ec-cube.co.jp/ + * https://www.ec-cube.co.jp/ * * For the full copyright and license information, please view the LICENSE * file that was distributed with this source code. diff --git a/EventListener/CustomerPersonalValidationListener.php b/EventListener/CustomerPersonalValidationListener.php index 0fb9779..a2b4ff7 100644 --- a/EventListener/CustomerPersonalValidationListener.php +++ b/EventListener/CustomerPersonalValidationListener.php @@ -5,7 +5,7 @@ * * Copyright(c) EC-CUBE CO.,LTD. All Rights Reserved. * - * http://www.ec-cube.co.jp/ + * https://www.ec-cube.co.jp/ * * For the full copyright and license information, please view the LICENSE * file that was distributed with this source code. @@ -17,11 +17,9 @@ use Eccube\Repository\BaseInfoRepository; use Eccube\Repository\CustomerRepository; use Eccube\Request\Context; -use Plugin\TwoFactorAuthCustomer44\Repository\TwoFactorAuthTypeRepository; use Plugin\TwoFactorAuthCustomer44\Service\CustomerTwoFactorAuthService; use Symfony\Component\EventDispatcher\EventSubscriberInterface; use Symfony\Component\HttpFoundation\RedirectResponse; -use Symfony\Component\HttpFoundation\Session\Session; use Symfony\Component\HttpKernel\Event\ControllerArgumentsEvent; use Symfony\Component\HttpKernel\Exception\NotFoundHttpException; use Symfony\Component\HttpKernel\KernelEvents; @@ -70,7 +68,7 @@ public function __construct( UrlGeneratorInterface $router, CustomerTwoFactorAuthService $customerTwoFactorAuthService, BaseInfoRepository $baseInfoRepository, - CustomerRepository $customerRepository + CustomerRepository $customerRepository, ) { $this->requestContext = $requestContext; $this->router = $router; @@ -108,8 +106,7 @@ public function onKernelController(ControllerArgumentsEvent $event) if ( ($this->baseInfo->isOptionCustomerActivate() && !$this->baseInfo->isOptionActivateDevice()) - || - !$this->baseInfo->isOptionCustomerActivate() + || !$this->baseInfo->isOptionCustomerActivate() ) { // デバイス認証なし かつ 2段階認証使用しない場合は処理なし return; @@ -143,7 +140,7 @@ private function isActivationRoute(string $route): bool * * @throws NotFoundHttpException */ - private function deviceAuth($event) + private function deviceAuth(mixed $event) { // アクティベーション $secret_key = $event->getRequest()->attributes->get('secret_key'); diff --git a/EventListener/CustomerTwoFactorAuthListener.php b/EventListener/CustomerTwoFactorAuthListener.php index 18b7caf..583c0d5 100755 --- a/EventListener/CustomerTwoFactorAuthListener.php +++ b/EventListener/CustomerTwoFactorAuthListener.php @@ -5,7 +5,7 @@ * * Copyright(c) EC-CUBE CO.,LTD. All Rights Reserved. * - * http://www.ec-cube.co.jp/ + * https://www.ec-cube.co.jp/ * * For the full copyright and license information, please view the LICENSE * file that was distributed with this source code. @@ -19,8 +19,8 @@ use Eccube\Entity\Master\CustomerStatus; use Eccube\Repository\BaseInfoRepository; use Eccube\Request\Context; -use Plugin\TwoFactorAuthCustomer44\Repository\TwoFactorAuthTypeRepository; use Plugin\TwoFactorAuthCustomer44\Repository\TwoFactorAuthCustomerCookieRepository; +use Plugin\TwoFactorAuthCustomer44\Repository\TwoFactorAuthTypeRepository; use Plugin\TwoFactorAuthCustomer44\Service\CustomerTwoFactorAuthService; use Symfony\Component\EventDispatcher\EventSubscriberInterface; use Symfony\Component\HttpFoundation\RedirectResponse; @@ -91,7 +91,7 @@ public function __construct( TwoFactorAuthTypeRepository $twoFactorAuthTypeRepository, TwoFactorAuthCustomerCookieRepository $twoFactorAuthCustomerCookieRepository, BaseInfoRepository $baseInfoRepository, - RequestStack $requestStack + RequestStack $requestStack, ) { $this->requestContext = $requestContext; $this->router = $router; @@ -181,8 +181,8 @@ public function onLoginSuccess(LoginSuccessEvent $event): void return; } - if ($this->requestContext->getCurrentUser()->getTwoFactorAuthType() !== null && - $this->requestContext->getCurrentUser()->getTwoFactorAuthType()->isDisabled()) { + if ($this->requestContext->getCurrentUser()->getTwoFactorAuthType() !== null + && $this->requestContext->getCurrentUser()->getTwoFactorAuthType()->isDisabled()) { // ユーザーが選択した2段階認証方式は無効になっている場合、ログアウトさせる。 $event->setResponse(new RedirectResponse($this->router->generate('logout'), 302)); @@ -202,7 +202,7 @@ public function onLoginSuccess(LoginSuccessEvent $event): void * * @return void */ - public function logoutEvent(LogoutEvent $logoutEvent) + public function logoutEvent(LogoutEvent $logoutEvent): void { $Customer = $this->requestContext->getCurrentUser(); if ($Customer instanceof Customer) { @@ -211,7 +211,6 @@ public function logoutEvent(LogoutEvent $logoutEvent) } } - /** * ルート・URIが個別認証対象かチェック. * @@ -273,7 +272,7 @@ private function isIncludeRoute(string $route, string $uri): bool * * @return mixed */ - private function multiFactorAuth($event, $Customer, $route) + private function multiFactorAuth(Event $event, Customer $Customer, string $route): mixed { if (!$this->baseInfo->isTwoFactorAuthUse()) { // MFA無効の場合処理なし @@ -306,7 +305,7 @@ private function multiFactorAuth($event, $Customer, $route) * @param Event $event * @param string|null $route */ - private function selectAuthType($event, ?string $route) + private function selectAuthType(Event $event, ?string $route) { // [会員] 2段階認証が未設定の場合 // コールバックURLをセッションへ設定 @@ -342,7 +341,7 @@ private function setCallbackRoute(?string $route) * @param Customer $Customer * @param string|null $route */ - private function auth($event, Customer $Customer, ?string $route) + private function auth(Event $event, Customer $Customer, ?string $route) { // コールバックURLをセッションへ設定 $this->setCallbackRoute($route); @@ -366,5 +365,4 @@ private function auth($event, Customer $Customer, ?string $route) $event->setResponse(new RedirectResponse($url, 302)); } } - } diff --git a/Form/Type/Extension/Admin/TwoFactorAuthBaseSettingTypeExtension.php b/Form/Type/Extension/Admin/TwoFactorAuthBaseSettingTypeExtension.php index 3709030..93f38d4 100644 --- a/Form/Type/Extension/Admin/TwoFactorAuthBaseSettingTypeExtension.php +++ b/Form/Type/Extension/Admin/TwoFactorAuthBaseSettingTypeExtension.php @@ -5,7 +5,7 @@ * * Copyright(c) EC-CUBE CO.,LTD. All Rights Reserved. * - * http://www.ec-cube.co.jp/ + * https://www.ec-cube.co.jp/ * * For the full copyright and license information, please view the LICENSE * file that was distributed with this source code. @@ -35,7 +35,7 @@ class TwoFactorAuthBaseSettingTypeExtension extends AbstractTypeExtension * @param EntityManagerInterface $entityManager */ public function __construct( - EntityManagerInterface $entityManager + EntityManagerInterface $entityManager, ) { $this->entityManager = $entityManager; } @@ -71,9 +71,9 @@ public function buildForm(FormBuilderInterface $builder, array $options): void } $form->add('option_activate_device', ToggleSwitchType::class, [ - 'required' => false, - 'mapped' => true, - ]); + 'required' => false, + 'mapped' => true, + ]); }); } } diff --git a/Form/Type/Extension/Admin/TwoFactorAuthCustomerTypeExtension.php b/Form/Type/Extension/Admin/TwoFactorAuthCustomerTypeExtension.php index 3ea2ca9..9c12b26 100755 --- a/Form/Type/Extension/Admin/TwoFactorAuthCustomerTypeExtension.php +++ b/Form/Type/Extension/Admin/TwoFactorAuthCustomerTypeExtension.php @@ -5,7 +5,7 @@ * * Copyright(c) EC-CUBE CO.,LTD. All Rights Reserved. * - * http://www.ec-cube.co.jp/ + * https://www.ec-cube.co.jp/ * * For the full copyright and license information, please view the LICENSE * file that was distributed with this source code. @@ -37,7 +37,7 @@ class TwoFactorAuthCustomerTypeExtension extends AbstractTypeExtension * @param EntityManagerInterface $entityManager */ public function __construct( - EntityManagerInterface $entityManager + EntityManagerInterface $entityManager, ) { $this->entityManager = $entityManager; } diff --git a/Form/Type/TwoFactorAuthAppTypeCustomer.php b/Form/Type/TwoFactorAuthAppTypeCustomer.php index 05b3f0b..6f4b8eb 100644 --- a/Form/Type/TwoFactorAuthAppTypeCustomer.php +++ b/Form/Type/TwoFactorAuthAppTypeCustomer.php @@ -5,7 +5,7 @@ * * Copyright(c) EC-CUBE CO.,LTD. All Rights Reserved. * - * http://www.ec-cube.co.jp/ + * https://www.ec-cube.co.jp/ * * For the full copyright and license information, please view the LICENSE * file that was distributed with this source code. @@ -29,27 +29,27 @@ public function buildForm(FormBuilderInterface $builder, array $options): void $builder ->add( 'device_token', TextType::class, [ - 'label' => 'front.setting.system.two_factor_auth.device_token', - 'required' => true, - 'constraints' => [ - new Assert\NotBlank(), - new Assert\Length([ - 'max' => 6, - 'min' => 6, - ]), - ], - 'attr' => [ - 'maxlength' => 6, - 'style' => 'width: 100px;', - ], - ]) + 'label' => 'front.setting.system.two_factor_auth.device_token', + 'required' => true, + 'constraints' => [ + new Assert\NotBlank(), + new Assert\Length([ + 'max' => 6, + 'min' => 6, + ]), + ], + 'attr' => [ + 'maxlength' => 6, + 'style' => 'width: 100px;', + ], + ]) ->add( 'auth_key', HiddenType::class, [ - 'required' => true, - 'constraints' => [ - new Assert\NotBlank(), - ], - ]); + 'required' => true, + 'constraints' => [ + new Assert\NotBlank(), + ], + ]); } /** diff --git a/Form/Type/TwoFactorAuthConfigType.php b/Form/Type/TwoFactorAuthConfigType.php index 38df36f..2d16fe5 100644 --- a/Form/Type/TwoFactorAuthConfigType.php +++ b/Form/Type/TwoFactorAuthConfigType.php @@ -5,7 +5,7 @@ * * Copyright(c) EC-CUBE CO.,LTD. All Rights Reserved. * - * http://www.ec-cube.co.jp/ + * https://www.ec-cube.co.jp/ * * For the full copyright and license information, please view the LICENSE * file that was distributed with this source code. diff --git a/Form/Type/TwoFactorAuthPhoneNumberTypeCustomer.php b/Form/Type/TwoFactorAuthPhoneNumberTypeCustomer.php index 99ebed7..477064a 100644 --- a/Form/Type/TwoFactorAuthPhoneNumberTypeCustomer.php +++ b/Form/Type/TwoFactorAuthPhoneNumberTypeCustomer.php @@ -5,7 +5,7 @@ * * Copyright(c) EC-CUBE CO.,LTD. All Rights Reserved. * - * http://www.ec-cube.co.jp/ + * https://www.ec-cube.co.jp/ * * For the full copyright and license information, please view the LICENSE * file that was distributed with this source code. diff --git a/Form/Type/TwoFactorAuthSmsTypeCustomer.php b/Form/Type/TwoFactorAuthSmsTypeCustomer.php index eee2042..226b425 100644 --- a/Form/Type/TwoFactorAuthSmsTypeCustomer.php +++ b/Form/Type/TwoFactorAuthSmsTypeCustomer.php @@ -5,7 +5,7 @@ * * Copyright(c) EC-CUBE CO.,LTD. All Rights Reserved. * - * http://www.ec-cube.co.jp/ + * https://www.ec-cube.co.jp/ * * For the full copyright and license information, please view the LICENSE * file that was distributed with this source code. @@ -28,20 +28,20 @@ public function buildForm(FormBuilderInterface $builder, array $options): void $builder ->add( 'one_time_token', TextType::class, [ - 'label' => 'front.setting.system.two_factor_auth.one_time_token', - 'required' => true, - 'constraints' => [ - new Assert\NotBlank(), - new Assert\Length([ - 'max' => 6, - 'min' => 6, - ]), - ], - 'attr' => [ - 'maxlength' => 6, - 'style' => 'width: 100px;', - ], - ]); + 'label' => 'front.setting.system.two_factor_auth.one_time_token', + 'required' => true, + 'constraints' => [ + new Assert\NotBlank(), + new Assert\Length([ + 'max' => 6, + 'min' => 6, + ]), + ], + 'attr' => [ + 'maxlength' => 6, + 'style' => 'width: 100px;', + ], + ]); } /** diff --git a/Form/Type/TwoFactorAuthTypeCustomer.php b/Form/Type/TwoFactorAuthTypeCustomer.php index 7dc4896..1ff4b41 100644 --- a/Form/Type/TwoFactorAuthTypeCustomer.php +++ b/Form/Type/TwoFactorAuthTypeCustomer.php @@ -5,7 +5,7 @@ * * Copyright(c) EC-CUBE CO.,LTD. All Rights Reserved. * - * http://www.ec-cube.co.jp/ + * https://www.ec-cube.co.jp/ * * For the full copyright and license information, please view the LICENSE * file that was distributed with this source code. diff --git a/PluginManager.php b/PluginManager.php index 14fbb8e..1189431 100644 --- a/PluginManager.php +++ b/PluginManager.php @@ -5,7 +5,7 @@ * * Copyright(c) EC-CUBE CO.,LTD. All Rights Reserved. * - * http://www.ec-cube.co.jp/ + * https://www.ec-cube.co.jp/ * * For the full copyright and license information, please view the LICENSE * file that was distributed with this source code. diff --git a/Repository/TwoFactorAuthConfigRepository.php b/Repository/TwoFactorAuthConfigRepository.php index f97d2ac..b99635b 100644 --- a/Repository/TwoFactorAuthConfigRepository.php +++ b/Repository/TwoFactorAuthConfigRepository.php @@ -5,7 +5,7 @@ * * Copyright(c) EC-CUBE CO.,LTD. All Rights Reserved. * - * http://www.ec-cube.co.jp/ + * https://www.ec-cube.co.jp/ * * For the full copyright and license information, please view the LICENSE * file that was distributed with this source code. @@ -38,7 +38,7 @@ public function __construct(ManagerRegistry $registry) /** * @return TwoFactorAuthConfig|null */ - public function findOne() + public function findOne(): ?TwoFactorAuthConfig { return $this->findOneBy([], ['id' => 'DESC']); } diff --git a/Repository/TwoFactorAuthCustomerCookieRepository.php b/Repository/TwoFactorAuthCustomerCookieRepository.php index 4e2f388..6ac865d 100644 --- a/Repository/TwoFactorAuthCustomerCookieRepository.php +++ b/Repository/TwoFactorAuthCustomerCookieRepository.php @@ -5,7 +5,7 @@ * * Copyright(c) EC-CUBE CO.,LTD. All Rights Reserved. * - * http://www.ec-cube.co.jp/ + * https://www.ec-cube.co.jp/ * * For the full copyright and license information, please view the LICENSE * file that was distributed with this source code. @@ -52,10 +52,9 @@ public function generateCookieData( Customer $customer, string $cookieName, int $expireSeconds, - int $CookieValueCharacterLength + int $CookieValueCharacterLength, ): TwoFactorAuthCustomerCookie { /** @var TwoFactorAuthCustomerCookie[]|null $previousCookies */ - $previousCookies = $this->findOldCookies($customer, $cookieName); foreach ($previousCookies as $cookie) { $this->getEntityManager()->remove($cookie); @@ -80,7 +79,7 @@ public function generateCookieData( * * @return float|int|mixed|string */ - public function findOldCookies(Customer $customer, string $cookieName) + public function findOldCookies(Customer $customer, string $cookieName): float|int|mixed|string|null { $expireDate = Carbon::now()->setTimezone('UTC')->format('Y-m-d H:i:s'); @@ -98,7 +97,7 @@ public function findOldCookies(Customer $customer, string $cookieName) /** * @return TwoFactorAuthCustomerCookie|null $result */ - public function findOne() + public function findOne(): ?TwoFactorAuthCustomerCookie { return $this->findOneBy([], ['id' => 'DESC']); } @@ -146,5 +145,4 @@ public function deleteByCustomer(Customer $customer) $em->commit(); } - } diff --git a/Repository/TwoFactorAuthTypeRepository.php b/Repository/TwoFactorAuthTypeRepository.php index 3376ec1..bb5bcdb 100644 --- a/Repository/TwoFactorAuthTypeRepository.php +++ b/Repository/TwoFactorAuthTypeRepository.php @@ -5,7 +5,7 @@ * * Copyright(c) EC-CUBE CO.,LTD. All Rights Reserved. * - * http://www.ec-cube.co.jp/ + * https://www.ec-cube.co.jp/ * * For the full copyright and license information, please view the LICENSE * file that was distributed with this source code. @@ -38,7 +38,7 @@ public function __construct(ManagerRegistry $registry) /** * @return object|TwoFactorAuthType|null $result */ - public function findOne() + public function findOne(): object|TwoFactorAuthType|null { return $this->findOneBy([], ['id' => 'DESC']); } diff --git a/Service/CustomerTwoFactorAuthService.php b/Service/CustomerTwoFactorAuthService.php index fdca85b..3bb07a2 100644 --- a/Service/CustomerTwoFactorAuthService.php +++ b/Service/CustomerTwoFactorAuthService.php @@ -5,7 +5,7 @@ * * Copyright(c) EC-CUBE CO.,LTD. All Rights Reserved. * - * http://www.ec-cube.co.jp/ + * https://www.ec-cube.co.jp/ * * For the full copyright and license information, please view the LICENSE * file that was distributed with this source code. @@ -140,7 +140,7 @@ public function __construct( RequestStack $requestStack, TwoFactorAuthConfigRepository $twoFactorAuthConfigRepository, TwoFactorAuthCustomerCookieRepository $twoFactorCustomerCookieRepository, - PasswordHasherFactoryInterface $hashFactory + PasswordHasherFactoryInterface $hashFactory, ) { $this->entityManager = $entityManager; $this->eccubeConfig = $eccubeConfig; @@ -164,7 +164,7 @@ public function __construct( /** * @return array */ - public function getDefaultAuthRoutes() + public function getDefaultAuthRoutes(): array { return $this->default_tfa_routes; } @@ -188,7 +188,7 @@ public function setContainer(ContainerBagInterface $container): ?ContainerBagInt * * @return Cookie */ - public function createAuthedCookie($Customer, $route = null): Cookie + public function createAuthedCookie(Customer $Customer, $route = null): Cookie { $expire = $this->expire; $cookieName = $this->cookieName; @@ -225,7 +225,7 @@ public function getIncludeRoutes(): array * @param Customer $Customer * @param null $route * - * @return boolean + * @return bool */ public function isAuthed(Customer $Customer, $route = null): bool { @@ -301,7 +301,7 @@ public function isRouteAuthed(Customer $Customer, string $cookieName, int $expir * * @return mixed */ - public function createRouteAuthCookie(Customer $Customer, string $cookieName, int $expire) + public function createRouteAuthCookie(Customer $Customer, string $cookieName, int $expire): mixed { return $this->entityManager->wrapInTransaction(function (EntityManagerInterface $em) use ($expire, $cookieName, $Customer) { $cookieData = $this->twoFactorCustomerCookieRepository->generateCookieData( @@ -355,11 +355,13 @@ public function isEnabled(): bool * * @param $phoneNumber * @param $body + * + * @return \Twilio\Rest\Api\V2010\Account\MessageInstance + * * @throws ConfigurationException * @throws TwilioException - * @return \Twilio\Rest\Api\V2010\Account\MessageInstance */ - public function sendBySms($phoneNumber, $body) + public function sendBySms($phoneNumber, $body): \Twilio\Rest\Api\V2010\Account\MessageInstance { // Twilio // SMS送信(現在国内電話番号のみ対象) @@ -384,12 +386,12 @@ public function sendBySms($phoneNumber, $body) * * @return void */ - public function clear2AuthCookies(Request $request, Response $response) + public function clear2AuthCookies(Request $request, Response $response): void { foreach ($request->cookies->all() as $key => $cookie) { if ( - $this->str_contains($key, $this->cookieName) || - $this->str_contains($key, $this->routeCookieName) + $this->str_contains($key, $this->cookieName) + || $this->str_contains($key, $this->routeCookieName) ) { // クッキーを消す $response->headers->clearCookie($key); @@ -426,13 +428,13 @@ public function hashOneTimeToken(string $token): string public function verifyOneTimeToken(string $hashedToken, string $token): bool { - if ($this->hashFactory->getPasswordHasher(Customer::class)->verify($hashedToken, $token)) { - return true; - } elseif ($hashedToken === $this->hashOneTimeToken($token)) { - return true; - } else { - return false; - } + if ($this->hashFactory->getPasswordHasher(Customer::class)->verify($hashedToken, $token)) { + return true; + } elseif ($hashedToken === $this->hashOneTimeToken($token)) { + return true; + } + + return false; } /*** From 3f92961dbefbf6594bdecd493d8d1e33e9dfa8c4 Mon Sep 17 00:00:00 2001 From: Ken Tanaka Date: Mon, 14 Sep 2026 14:55:11 +0900 Subject: [PATCH 07/16] =?UTF-8?q?git=20hub=20actions=E3=82=A8=E3=83=A9?= =?UTF-8?q?=E3=83=BC=E4=BF=AE=E6=AD=A3?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- EventListener/CustomerTwoFactorAuthListener.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/EventListener/CustomerTwoFactorAuthListener.php b/EventListener/CustomerTwoFactorAuthListener.php index 583c0d5..36b2bc0 100755 --- a/EventListener/CustomerTwoFactorAuthListener.php +++ b/EventListener/CustomerTwoFactorAuthListener.php @@ -270,9 +270,9 @@ private function isIncludeRoute(string $route, string $uri): bool * @param Customer $Customer * @param string $route * - * @return mixed + * @return void */ - private function multiFactorAuth(Event $event, Customer $Customer, string $route): mixed + private function multiFactorAuth(Event $event, Customer $Customer, string $route): void { if (!$this->baseInfo->isTwoFactorAuthUse()) { // MFA無効の場合処理なし From 9ccd54fb44c09214ba46843143ec31557c8c89ae Mon Sep 17 00:00:00 2001 From: Ken Tanaka Date: Mon, 14 Sep 2026 15:01:37 +0900 Subject: [PATCH 08/16] =?UTF-8?q?=E4=B8=8D=E6=AD=A3=E3=81=AA=E3=83=A6?= =?UTF-8?q?=E3=83=8B=E3=82=AA=E3=83=B3=E3=81=AE=E4=BF=AE=E6=AD=A3?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Repository/TwoFactorAuthCustomerCookieRepository.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Repository/TwoFactorAuthCustomerCookieRepository.php b/Repository/TwoFactorAuthCustomerCookieRepository.php index 6ac865d..e4a8be0 100644 --- a/Repository/TwoFactorAuthCustomerCookieRepository.php +++ b/Repository/TwoFactorAuthCustomerCookieRepository.php @@ -77,9 +77,9 @@ public function generateCookieData( * @param Customer $customer * @param string $cookieName * - * @return float|int|mixed|string + * @return TwoFactorAuthCustomerCookie[] */ - public function findOldCookies(Customer $customer, string $cookieName): float|int|mixed|string|null + public function findOldCookies(Customer $customer, string $cookieName): array { $expireDate = Carbon::now()->setTimezone('UTC')->format('Y-m-d H:i:s'); From 65aba5e985a072a0f878660fd1f08b6d4d305a6a Mon Sep 17 00:00:00 2001 From: Ken Tanaka Date: Mon, 14 Sep 2026 15:13:27 +0900 Subject: [PATCH 09/16] =?UTF-8?q?=E5=9E=8B=E5=AE=A3=E8=A8=80=E3=81=AE?= =?UTF-8?q?=E4=B8=8D=E6=AD=A3=E3=82=92=E4=BF=AE=E6=AD=A3?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Entity/CustomerTrait.php | 2 +- EventListener/CustomerPersonalValidationListener.php | 2 +- EventListener/CustomerTwoFactorAuthListener.php | 2 +- Repository/TwoFactorAuthCustomerCookieRepository.php | 4 ++-- Repository/TwoFactorAuthTypeRepository.php | 4 ++-- Service/CustomerTwoFactorAuthService.php | 6 +++--- 6 files changed, 10 insertions(+), 10 deletions(-) diff --git a/Entity/CustomerTrait.php b/Entity/CustomerTrait.php index af332b8..1a4af4e 100644 --- a/Entity/CustomerTrait.php +++ b/Entity/CustomerTrait.php @@ -71,7 +71,7 @@ public function getDeviceAuthOneTimeTokenExpire(): ?\DateTime /** * Set oneTimeTokenExpire. * - * @param mixed|null $deviceAuthOneTimeTokenExpire + * @param mixed $deviceAuthOneTimeTokenExpire * * @return Customer */ diff --git a/EventListener/CustomerPersonalValidationListener.php b/EventListener/CustomerPersonalValidationListener.php index a2b4ff7..fa43ee0 100644 --- a/EventListener/CustomerPersonalValidationListener.php +++ b/EventListener/CustomerPersonalValidationListener.php @@ -52,7 +52,7 @@ class CustomerPersonalValidationListener implements EventSubscriberInterface */ protected CustomerRepository $customerRepository; /** - * @var BaseInfo|object|null + * @var BaseInfo|null */ protected $baseInfo; diff --git a/EventListener/CustomerTwoFactorAuthListener.php b/EventListener/CustomerTwoFactorAuthListener.php index 36b2bc0..cd6ad7c 100755 --- a/EventListener/CustomerTwoFactorAuthListener.php +++ b/EventListener/CustomerTwoFactorAuthListener.php @@ -59,7 +59,7 @@ class CustomerTwoFactorAuthListener implements EventSubscriberInterface */ protected TwoFactorAuthCustomerCookieRepository $twoFactorAuthCustomerCookieRepository; /** - * @var BaseInfo|object|null + * @var BaseInfo|null */ protected $baseInfo; /** diff --git a/Repository/TwoFactorAuthCustomerCookieRepository.php b/Repository/TwoFactorAuthCustomerCookieRepository.php index e4a8be0..0de1dbc 100644 --- a/Repository/TwoFactorAuthCustomerCookieRepository.php +++ b/Repository/TwoFactorAuthCustomerCookieRepository.php @@ -107,9 +107,9 @@ public function findOne(): ?TwoFactorAuthCustomerCookie * * @param Customer $customer * @param string $cookieName - * @return TwoFactorAuthCustomerCookie[]|null + * @return TwoFactorAuthCustomerCookie[] */ - public function searchForCookie(Customer $customer, string $cookieName) + public function searchForCookie(Customer $customer, string $cookieName): array { $expireDate = Carbon::now()->setTimezone('UTC')->format('Y-m-d H:i:s'); diff --git a/Repository/TwoFactorAuthTypeRepository.php b/Repository/TwoFactorAuthTypeRepository.php index bb5bcdb..0dcbb16 100644 --- a/Repository/TwoFactorAuthTypeRepository.php +++ b/Repository/TwoFactorAuthTypeRepository.php @@ -36,9 +36,9 @@ public function __construct(ManagerRegistry $registry) } /** - * @return object|TwoFactorAuthType|null $result + * @return TwoFactorAuthType|null */ - public function findOne(): object|TwoFactorAuthType|null + public function findOne(): ?TwoFactorAuthType { return $this->findOneBy([], ['id' => 'DESC']); } diff --git a/Service/CustomerTwoFactorAuthService.php b/Service/CustomerTwoFactorAuthService.php index 3bb07a2..4918c0d 100644 --- a/Service/CustomerTwoFactorAuthService.php +++ b/Service/CustomerTwoFactorAuthService.php @@ -81,7 +81,7 @@ class CustomerTwoFactorAuthService */ private $entityManager; /** - * @var BaseInfo|object|null + * @var BaseInfo|null */ private $baseInfo; @@ -299,9 +299,9 @@ public function isRouteAuthed(Customer $Customer, string $cookieName, int $expir * @param string $cookieName * @param int $expire * - * @return mixed + * @return Cookie */ - public function createRouteAuthCookie(Customer $Customer, string $cookieName, int $expire): mixed + public function createRouteAuthCookie(Customer $Customer, string $cookieName, int $expire): Cookie { return $this->entityManager->wrapInTransaction(function (EntityManagerInterface $em) use ($expire, $cookieName, $Customer) { $cookieData = $this->twoFactorCustomerCookieRepository->generateCookieData( From e1f695cc9c2ae6446f525115ef41315c46ac555a Mon Sep 17 00:00:00 2001 From: Ken Tanaka Date: Mon, 14 Sep 2026 15:28:03 +0900 Subject: [PATCH 10/16] =?UTF-8?q?reactor=E3=81=AE=E4=BF=AE=E6=AD=A3?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Resource/rector.php | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/Resource/rector.php b/Resource/rector.php index 577ad4a..46556a5 100644 --- a/Resource/rector.php +++ b/Resource/rector.php @@ -40,12 +40,12 @@ ]) ->withSets([ LevelSetList::UP_TO_PHP_82, - // Symfony 7.4 対応 (@Route → #[Route], @Template, buildForm(): void 等) - SymfonySetList::SYMFONY_74, + // rector 2.6.2 でバージョン別のセット定数 (SYMFONY_74 等) は撤去された。 + // 各ルールが composer.json を見て、インストール済みバージョンに合うものだけ実行する。 + SymfonySetList::COMPOSER_BASED, SymfonySetList::SYMFONY_CODE_QUALITY, - // Doctrine ORM 3.0 / DBAL 3.0 対応 (@ORM → #[ORM], 型付きプロパティ) DoctrineSetList::DOCTRINE_CODE_QUALITY, - DoctrineSetList::DOCTRINE_DBAL_30, + DoctrineSetList::COMPOSER_BASED, DoctrineSetList::ANNOTATIONS_TO_ATTRIBUTES, ]) // Symfony/Doctrine 等のアノテーション → アトリビュート変換を有効化 From 73be10764f2a8b7a46d67017414c87377b49ba85 Mon Sep 17 00:00:00 2001 From: Ken Tanaka Date: Mon, 14 Sep 2026 15:40:10 +0900 Subject: [PATCH 11/16] =?UTF-8?q?Rector=20=E3=81=AE=20dry-run=20=E5=B7=AE?= =?UTF-8?q?=E5=88=86=E3=82=92=E9=81=A9=E7=94=A8=E3=81=97=E3=80=81Static=20?= =?UTF-8?q?Analysis=20=E3=82=92=E9=80=9A=E3=81=99=E3=80=82?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../CustomerPersonalValidationController.php | 2 +- Event.php | 2 +- .../CustomerPersonalValidationListener.php | 16 +++---- .../CustomerTwoFactorAuthListener.php | 43 ++++++------------- .../TwoFactorAuthBaseSettingTypeExtension.php | 11 +---- .../TwoFactorAuthCustomerTypeExtension.php | 11 +---- Form/Type/TwoFactorAuthAppTypeCustomer.php | 7 +-- Form/Type/TwoFactorAuthConfigType.php | 36 ++++------------ .../TwoFactorAuthPhoneNumberTypeCustomer.php | 2 +- Form/Type/TwoFactorAuthSmsTypeCustomer.php | 7 +-- Form/Type/TwoFactorAuthTypeCustomer.php | 10 ++--- Service/CustomerTwoFactorAuthService.php | 39 +++++------------ 12 files changed, 54 insertions(+), 132 deletions(-) diff --git a/Controller/CustomerPersonalValidationController.php b/Controller/CustomerPersonalValidationController.php index 2e232a7..0edbf79 100644 --- a/Controller/CustomerPersonalValidationController.php +++ b/Controller/CustomerPersonalValidationController.php @@ -44,7 +44,7 @@ class CustomerPersonalValidationController extends AbstractController * @param Environment $twig */ public function __construct( - private RateLimiterFactory $deviceAuthRequestEmailLimiter, + private readonly RateLimiterFactory $deviceAuthRequestEmailLimiter, protected CustomerRepository $customerRepository, protected CustomerTwoFactorAuthService $customerTwoFactorAuthService, protected Environment $twig, diff --git a/Event.php b/Event.php index 8c61a9e..01d0e7b 100644 --- a/Event.php +++ b/Event.php @@ -25,7 +25,7 @@ class Event implements EventSubscriberInterface /** * @var bool */ - private bool $hasActiveAuthType; + private readonly bool $hasActiveAuthType; /** * Event constructor. diff --git a/EventListener/CustomerPersonalValidationListener.php b/EventListener/CustomerPersonalValidationListener.php index fa43ee0..d1791f4 100644 --- a/EventListener/CustomerPersonalValidationListener.php +++ b/EventListener/CustomerPersonalValidationListener.php @@ -20,6 +20,7 @@ use Plugin\TwoFactorAuthCustomer44\Service\CustomerTwoFactorAuthService; use Symfony\Component\EventDispatcher\EventSubscriberInterface; use Symfony\Component\HttpFoundation\RedirectResponse; +use Symfony\Component\HttpFoundation\Response; use Symfony\Component\HttpKernel\Event\ControllerArgumentsEvent; use Symfony\Component\HttpKernel\Exception\NotFoundHttpException; use Symfony\Component\HttpKernel\KernelEvents; @@ -47,10 +48,6 @@ class CustomerPersonalValidationListener implements EventSubscriberInterface * @var BaseInfoRepository */ protected BaseInfoRepository $baseInfoRepository; - /** - * @var CustomerRepository - */ - protected CustomerRepository $customerRepository; /** * @var BaseInfo|null */ @@ -68,13 +65,12 @@ public function __construct( UrlGeneratorInterface $router, CustomerTwoFactorAuthService $customerTwoFactorAuthService, BaseInfoRepository $baseInfoRepository, - CustomerRepository $customerRepository, + protected CustomerRepository $customerRepository, ) { $this->requestContext = $requestContext; $this->router = $router; $this->customerTwoFactorAuthService = $customerTwoFactorAuthService; $this->baseInfo = $baseInfoRepository->find(1); - $this->customerRepository = $customerRepository; } /** @@ -92,7 +88,7 @@ public static function getSubscribedEvents(): array * * @param ControllerArgumentsEvent $event */ - public function onKernelController(ControllerArgumentsEvent $event) + public function onKernelController(ControllerArgumentsEvent $event): void { if (!$event->isMainRequest()) { // サブリクエストの場合、処理なし @@ -140,7 +136,7 @@ private function isActivationRoute(string $route): bool * * @throws NotFoundHttpException */ - private function deviceAuth(mixed $event) + private function deviceAuth(mixed $event): void { // アクティベーション $secret_key = $event->getRequest()->attributes->get('secret_key'); @@ -162,9 +158,7 @@ private function deviceAuth(mixed $event) ['secret_key' => $secret_key] ); - $event->setController(function () use ($url) { - return new RedirectResponse($url, 302); - }); + $event->setController(fn () => new RedirectResponse($url, Response::HTTP_FOUND)); } } } diff --git a/EventListener/CustomerTwoFactorAuthListener.php b/EventListener/CustomerTwoFactorAuthListener.php index cd6ad7c..2fba12d 100755 --- a/EventListener/CustomerTwoFactorAuthListener.php +++ b/EventListener/CustomerTwoFactorAuthListener.php @@ -25,6 +25,7 @@ use Symfony\Component\EventDispatcher\EventSubscriberInterface; use Symfony\Component\HttpFoundation\RedirectResponse; use Symfony\Component\HttpFoundation\RequestStack; +use Symfony\Component\HttpFoundation\Response; use Symfony\Component\HttpKernel\Event\ControllerArgumentsEvent; use Symfony\Component\HttpKernel\KernelEvents; use Symfony\Component\Routing\Generator\UrlGeneratorInterface; @@ -50,14 +51,6 @@ class CustomerTwoFactorAuthListener implements EventSubscriberInterface * @var CustomerTwoFactorAuthService */ protected $customerTwoFactorAuthService; - /** - * @var TwoFactorAuthTypeRepository - */ - protected TwoFactorAuthTypeRepository $twoFactorAuthTypeRepository; - /** - * @var TwoFactorAuthCustomerCookieRepository - */ - protected TwoFactorAuthCustomerCookieRepository $twoFactorAuthCustomerCookieRepository; /** * @var BaseInfo|null */ @@ -88,8 +81,8 @@ public function __construct( Context $requestContext, UrlGeneratorInterface $router, CustomerTwoFactorAuthService $customerTwoFactorAuthService, - TwoFactorAuthTypeRepository $twoFactorAuthTypeRepository, - TwoFactorAuthCustomerCookieRepository $twoFactorAuthCustomerCookieRepository, + protected TwoFactorAuthTypeRepository $twoFactorAuthTypeRepository, + protected TwoFactorAuthCustomerCookieRepository $twoFactorAuthCustomerCookieRepository, BaseInfoRepository $baseInfoRepository, RequestStack $requestStack, ) { @@ -97,8 +90,6 @@ public function __construct( $this->router = $router; $this->customerTwoFactorAuthService = $customerTwoFactorAuthService; $this->baseInfo = $baseInfoRepository->find(1); - $this->twoFactorAuthTypeRepository = $twoFactorAuthTypeRepository; - $this->twoFactorAuthCustomerCookieRepository = $twoFactorAuthCustomerCookieRepository; $this->session = $requestStack->getSession(); $this->default_routes = $this->customerTwoFactorAuthService->getDefaultAuthRoutes(); @@ -122,7 +113,7 @@ public static function getSubscribedEvents(): array * * @param ControllerArgumentsEvent $event */ - public function onKernelController(ControllerArgumentsEvent $event) + public function onKernelController(ControllerArgumentsEvent $event): void { if (!$event->isMainRequest()) { // サブリクエストの場合、処理なし @@ -184,7 +175,7 @@ public function onLoginSuccess(LoginSuccessEvent $event): void if ($this->requestContext->getCurrentUser()->getTwoFactorAuthType() !== null && $this->requestContext->getCurrentUser()->getTwoFactorAuthType()->isDisabled()) { // ユーザーが選択した2段階認証方式は無効になっている場合、ログアウトさせる。 - $event->setResponse(new RedirectResponse($this->router->generate('logout'), 302)); + $event->setResponse(new RedirectResponse($this->router->generate('logout'), Response::HTTP_FOUND)); return; } @@ -242,7 +233,7 @@ private function isTargetRoute(array $targetRoutes, string $route, string $uri): // URIで認証 foreach ($targetRoutes as $r) { - if ($r != '' && $r !== '/' && strpos($uri, $r) === 0) { + if ($r != '' && $r !== '/' && str_starts_with($uri, $r)) { return true; } } @@ -305,7 +296,7 @@ private function multiFactorAuth(Event $event, Customer $Customer, string $route * @param Event $event * @param string|null $route */ - private function selectAuthType(Event $event, ?string $route) + private function selectAuthType(Event $event, ?string $route): void { // [会員] 2段階認証が未設定の場合 // コールバックURLをセッションへ設定 @@ -314,11 +305,9 @@ private function selectAuthType(Event $event, ?string $route) $url = $this->router->generate('plg_customer_2fa_auth_type_select', [], UrlGeneratorInterface::ABSOLUTE_PATH); if ($event instanceof ControllerArgumentsEvent) { - $event->setController(function () use ($url) { - return new RedirectResponse($url, 302); - }); + $event->setController(fn () => new RedirectResponse($url, Response::HTTP_FOUND)); } else { - $event->setResponse(new RedirectResponse($url, 302)); + $event->setResponse(new RedirectResponse($url, Response::HTTP_FOUND)); } } @@ -327,7 +316,7 @@ private function selectAuthType(Event $event, ?string $route) * * @param string|null $route */ - private function setCallbackRoute(?string $route) + private function setCallbackRoute(?string $route): void { if ($route) { $this->session->set(CustomerTwoFactorAuthService::SESSION_CALL_BACK_URL, $route); @@ -341,16 +330,14 @@ private function setCallbackRoute(?string $route) * @param Customer $Customer * @param string|null $route */ - private function auth(Event $event, Customer $Customer, ?string $route) + private function auth(Event $event, Customer $Customer, ?string $route): void { // コールバックURLをセッションへ設定 $this->setCallbackRoute($route); // 選択された多要素認証方式で指定されているルートへリダイレクト if ($Customer->getTwoFactorAuthType() !== null && $Customer->getTwoFactorAuthType()->isDisabled()) { // ユーザーが選択した2段階認証方式は無効になっている場合、ログアウトさせる。 - $event->setController(function () { - return new RedirectResponse($this->router->generate('logout'), 302); - }); + $event->setController(fn () => new RedirectResponse($this->router->generate('logout'), Response::HTTP_FOUND)); return; } @@ -358,11 +345,9 @@ private function auth(Event $event, Customer $Customer, ?string $route) $url = $this->router->generate($Customer->getTwoFactorAuthType()->getRoute()); if ($event instanceof ControllerArgumentsEvent) { - $event->setController(function () use ($url) { - return new RedirectResponse($url, 302); - }); + $event->setController(fn () => new RedirectResponse($url, Response::HTTP_FOUND)); } else { - $event->setResponse(new RedirectResponse($url, 302)); + $event->setResponse(new RedirectResponse($url, Response::HTTP_FOUND)); } } } diff --git a/Form/Type/Extension/Admin/TwoFactorAuthBaseSettingTypeExtension.php b/Form/Type/Extension/Admin/TwoFactorAuthBaseSettingTypeExtension.php index 93f38d4..d501db9 100644 --- a/Form/Type/Extension/Admin/TwoFactorAuthBaseSettingTypeExtension.php +++ b/Form/Type/Extension/Admin/TwoFactorAuthBaseSettingTypeExtension.php @@ -24,20 +24,13 @@ class TwoFactorAuthBaseSettingTypeExtension extends AbstractTypeExtension { - /** - * @var EntityManagerInterface - */ - protected EntityManagerInterface $entityManager; - /** * CouponDetailType constructor. * * @param EntityManagerInterface $entityManager */ - public function __construct( - EntityManagerInterface $entityManager, - ) { - $this->entityManager = $entityManager; + public function __construct(protected EntityManagerInterface $entityManager) + { } /** diff --git a/Form/Type/Extension/Admin/TwoFactorAuthCustomerTypeExtension.php b/Form/Type/Extension/Admin/TwoFactorAuthCustomerTypeExtension.php index 9c12b26..fcd2141 100755 --- a/Form/Type/Extension/Admin/TwoFactorAuthCustomerTypeExtension.php +++ b/Form/Type/Extension/Admin/TwoFactorAuthCustomerTypeExtension.php @@ -26,20 +26,13 @@ class TwoFactorAuthCustomerTypeExtension extends AbstractTypeExtension { - /** - * @var EntityManagerInterface - */ - protected EntityManagerInterface $entityManager; - /** * CouponDetailType constructor. * * @param EntityManagerInterface $entityManager */ - public function __construct( - EntityManagerInterface $entityManager, - ) { - $this->entityManager = $entityManager; + public function __construct(protected EntityManagerInterface $entityManager) + { } /** diff --git a/Form/Type/TwoFactorAuthAppTypeCustomer.php b/Form/Type/TwoFactorAuthAppTypeCustomer.php index 6f4b8eb..eda2b4a 100644 --- a/Form/Type/TwoFactorAuthAppTypeCustomer.php +++ b/Form/Type/TwoFactorAuthAppTypeCustomer.php @@ -33,10 +33,7 @@ public function buildForm(FormBuilderInterface $builder, array $options): void 'required' => true, 'constraints' => [ new Assert\NotBlank(), - new Assert\Length([ - 'max' => 6, - 'min' => 6, - ]), + new Assert\Length(max: 6, min: 6), ], 'attr' => [ 'maxlength' => 6, @@ -55,7 +52,7 @@ public function buildForm(FormBuilderInterface $builder, array $options): void /** * {@inheritdoc} */ - public function getBlockPrefix() + public function getBlockPrefix(): string { return 'plg_customer_2fa'; } diff --git a/Form/Type/TwoFactorAuthConfigType.php b/Form/Type/TwoFactorAuthConfigType.php index 2d16fe5..7ad3072 100644 --- a/Form/Type/TwoFactorAuthConfigType.php +++ b/Form/Type/TwoFactorAuthConfigType.php @@ -33,17 +33,14 @@ class TwoFactorAuthConfigType extends AbstractType */ protected $eccubeConfig; - protected ValidatorInterface $validator; - /** * TwoFactorAuthConfigType constructor. * * @param EccubeConfig $eccubeConfig */ - public function __construct(EccubeConfig $eccubeConfig, ValidatorInterface $validator) + public function __construct(EccubeConfig $eccubeConfig, protected ValidatorInterface $validator) { $this->eccubeConfig = $eccubeConfig; - $this->validator = $validator; } public function buildForm(FormBuilderInterface $builder, array $options): void @@ -53,41 +50,29 @@ public function buildForm(FormBuilderInterface $builder, array $options): void 'required' => true, 'constraints' => [ new Assert\NotBlank(), - new Assert\Length(['max' => $this->eccubeConfig['eccube_stext_len']]), - new Assert\Regex( - [ - 'pattern' => '/^[a-zA-Z0-9]+$/i', - 'message' => 'form_error.graph_only', - ] - ), + new Assert\Length(max: $this->eccubeConfig['eccube_stext_len']), + new Assert\Regex(pattern: '/^[a-zA-Z0-9]+$/i', message: 'form_error.graph_only'), ], ]) ->add('plain_api_secret', TextType::class, [ 'required' => true, 'constraints' => [ new Assert\NotBlank(), - new Assert\Length(['max' => $this->eccubeConfig['eccube_stext_len']]), + new Assert\Length(max: $this->eccubeConfig['eccube_stext_len']), ], ]) ->add('from_phone_number', TextType::class, [ 'required' => true, 'constraints' => [ new Assert\NotBlank(), - new Assert\Length(['max' => $this->eccubeConfig['eccube_stext_len']]), - new Assert\Regex( - [ - 'pattern' => '/^[0-9]+$/i', - 'message' => 'form_error.numeric_only', - ] - ), + new Assert\Length(max: $this->eccubeConfig['eccube_stext_len']), + new Assert\Regex(pattern: '/^[0-9]+$/i', message: 'form_error.numeric_only'), ], ]) ->add('include_routes', TextareaType::class, [ 'required' => false, 'constraints' => [ - new Assert\Length([ - 'max' => $this->eccubeConfig['eccube_ltext_len'], - ]), + new Assert\Length(max: $this->eccubeConfig['eccube_ltext_len']), ], ]); @@ -97,10 +82,7 @@ public function buildForm(FormBuilderInterface $builder, array $options): void if ($data['plain_api_secret'] !== $this->eccubeConfig['eccube_default_password']) { $errors = $this->validator->validate($data['plain_api_secret'], [ - new Assert\Regex([ - 'pattern' => '/^[a-zA-Z0-9]+$/i', - 'message' => 'form_error.graph_only', - ]), + new Assert\Regex(pattern: '/^[a-zA-Z0-9]+$/i', message: 'form_error.graph_only'), ]); if ($errors) { foreach ($errors as $error) { @@ -116,7 +98,7 @@ public function buildForm(FormBuilderInterface $builder, array $options): void * * @see AbstractType::configureOptions */ - public function configureOptions(OptionsResolver $resolver) + public function configureOptions(OptionsResolver $resolver): void { $resolver->setDefaults([ 'data_class' => TwoFactorAuthConfig::class, diff --git a/Form/Type/TwoFactorAuthPhoneNumberTypeCustomer.php b/Form/Type/TwoFactorAuthPhoneNumberTypeCustomer.php index 477064a..915b652 100644 --- a/Form/Type/TwoFactorAuthPhoneNumberTypeCustomer.php +++ b/Form/Type/TwoFactorAuthPhoneNumberTypeCustomer.php @@ -33,7 +33,7 @@ public function buildForm(FormBuilderInterface $builder, array $options): void /** * {@inheritdoc} */ - public function getBlockPrefix() + public function getBlockPrefix(): string { return 'plg_customer_2fa'; } diff --git a/Form/Type/TwoFactorAuthSmsTypeCustomer.php b/Form/Type/TwoFactorAuthSmsTypeCustomer.php index 226b425..3ddc0b5 100644 --- a/Form/Type/TwoFactorAuthSmsTypeCustomer.php +++ b/Form/Type/TwoFactorAuthSmsTypeCustomer.php @@ -32,10 +32,7 @@ public function buildForm(FormBuilderInterface $builder, array $options): void 'required' => true, 'constraints' => [ new Assert\NotBlank(), - new Assert\Length([ - 'max' => 6, - 'min' => 6, - ]), + new Assert\Length(max: 6, min: 6), ], 'attr' => [ 'maxlength' => 6, @@ -47,7 +44,7 @@ public function buildForm(FormBuilderInterface $builder, array $options): void /** * {@inheritdoc} */ - public function getBlockPrefix() + public function getBlockPrefix(): string { return 'plg_customer_2fa'; } diff --git a/Form/Type/TwoFactorAuthTypeCustomer.php b/Form/Type/TwoFactorAuthTypeCustomer.php index 1ff4b41..555d34e 100644 --- a/Form/Type/TwoFactorAuthTypeCustomer.php +++ b/Form/Type/TwoFactorAuthTypeCustomer.php @@ -31,11 +31,9 @@ public function buildForm(FormBuilderInterface $builder, array $options): void 'label' => 'front.setting.system.two_factor_auth.type', 'class' => TwoFactorAuthType::class, 'required' => true, - 'query_builder' => function (EntityRepository $er) { - return $er->createQueryBuilder('tfat') - ->where('tfat.isDisabled = :id') - ->setParameter('id', false); - }, + 'query_builder' => fn (EntityRepository $er) => $er->createQueryBuilder('tfat') + ->where('tfat.isDisabled = :id') + ->setParameter('id', false), 'choice_label' => 'name', 'mapped' => true, ]); @@ -44,7 +42,7 @@ public function buildForm(FormBuilderInterface $builder, array $options): void /** * {@inheritdoc} */ - public function getBlockPrefix() + public function getBlockPrefix(): string { return 'plg_customer_2fa'; } diff --git a/Service/CustomerTwoFactorAuthService.php b/Service/CustomerTwoFactorAuthService.php index 4918c0d..cc7ecea 100644 --- a/Service/CustomerTwoFactorAuthService.php +++ b/Service/CustomerTwoFactorAuthService.php @@ -28,8 +28,10 @@ use Symfony\Component\HttpFoundation\RequestStack; use Symfony\Component\HttpFoundation\Response; use Symfony\Component\PasswordHasher\Hasher\PasswordHasherFactoryInterface; +use Symfony\Contracts\Service\Attribute\Required; use Twilio\Exceptions\ConfigurationException; use Twilio\Exceptions\TwilioException; +use Twilio\Rest\Api\V2010\Account\MessageInstance; use Twilio\Rest\Client; class CustomerTwoFactorAuthService @@ -76,10 +78,6 @@ class CustomerTwoFactorAuthService * @var int */ protected $route_expire; - /** - * @var EntityManagerInterface - */ - private $entityManager; /** * @var BaseInfo|null */ @@ -93,7 +91,7 @@ class CustomerTwoFactorAuthService /** * @var int */ - private int $tokenLength; + private readonly int $tokenLength; /** * @var array @@ -111,17 +109,7 @@ class CustomerTwoFactorAuthService 'shopping_login', ]; - /** - * @var TwoFactorAuthCustomerCookieRepository - */ - private TwoFactorAuthCustomerCookieRepository $twoFactorCustomerCookieRepository; - - /** - * @var PasswordHasherFactoryInterface - */ - private PasswordHasherFactoryInterface $hashFactory; - - private int $tokenActiveDurationSeconds; + private readonly int $tokenActiveDurationSeconds; /** * constructor. @@ -134,15 +122,14 @@ class CustomerTwoFactorAuthService * @param PasswordHasherFactoryInterface $hashFactory */ public function __construct( - EntityManagerInterface $entityManager, + private readonly EntityManagerInterface $entityManager, EccubeConfig $eccubeConfig, BaseInfoRepository $baseInfoRepository, RequestStack $requestStack, TwoFactorAuthConfigRepository $twoFactorAuthConfigRepository, - TwoFactorAuthCustomerCookieRepository $twoFactorCustomerCookieRepository, - PasswordHasherFactoryInterface $hashFactory, + private readonly TwoFactorAuthCustomerCookieRepository $twoFactorCustomerCookieRepository, + private readonly PasswordHasherFactoryInterface $hashFactory, ) { - $this->entityManager = $entityManager; $this->eccubeConfig = $eccubeConfig; $this->baseInfo = $baseInfoRepository->find(1); @@ -157,8 +144,6 @@ public function __construct( $this->tokenActiveDurationSeconds = (int) $this->eccubeConfig->get('plugin_eccube_2fa_one_time_token_expire_after_seconds'); $this->twoFactorAuthConfig = $twoFactorAuthConfigRepository->findOne(); - $this->twoFactorCustomerCookieRepository = $twoFactorCustomerCookieRepository; - $this->hashFactory = $hashFactory; } /** @@ -169,9 +154,7 @@ public function getDefaultAuthRoutes(): array return $this->default_tfa_routes; } - /** - * @required - */ + #[Required] public function setContainer(ContainerBagInterface $container): ?ContainerBagInterface { $previous = $this->container; @@ -356,12 +339,12 @@ public function isEnabled(): bool * @param $phoneNumber * @param $body * - * @return \Twilio\Rest\Api\V2010\Account\MessageInstance + * @return MessageInstance * * @throws ConfigurationException * @throws TwilioException */ - public function sendBySms($phoneNumber, $body): \Twilio\Rest\Api\V2010\Account\MessageInstance + public function sendBySms($phoneNumber, $body): MessageInstance { // Twilio // SMS送信(現在国内電話番号のみ対象) @@ -444,7 +427,7 @@ public function verifyOneTimeToken(string $hashedToken, string $token): bool * * @deprecated ECCUBEの最低PHPバージョンは8.0になったら, この関数を消してphp8.0からのstr_containsを利用する */ - private function str_contains(string $haystack, string $needle) + private function str_contains(string $haystack, string $needle): bool { return $needle !== '' && mb_strpos($haystack, $needle) !== false; } From cd992bb9b2826599ea7eff4e0efed971dabaf132 Mon Sep 17 00:00:00 2001 From: Ken Tanaka Date: Mon, 14 Sep 2026 15:52:33 +0900 Subject: [PATCH 12/16] =?UTF-8?q?PHPStan=20=E3=81=AE=E6=8C=87=E6=91=98?= =?UTF-8?q?=E3=82=92=E4=BF=AE=E6=AD=A3=E3=81=97=E3=80=81EntityExtension=20?= =?UTF-8?q?=E7=94=A8=20stub=20=E3=82=92=E8=BF=BD=E5=8A=A0=E3=81=99?= =?UTF-8?q?=E3=82=8B=E3=80=82?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Controller/Admin/ConfigController.php | 2 +- .../CustomerPersonalValidationController.php | 24 +------ .../TwoFactorAuthCustomerController.php | 3 + Entity/TwoFactorAuthConfig.php | 3 + .../CustomerPersonalValidationListener.php | 2 +- .../CustomerTwoFactorAuthListener.php | 2 +- Service/CustomerTwoFactorAuthService.php | 13 ++-- phpstan.neon.dist | 4 ++ phpstan/BaseInfo.stub | 25 +++++++ phpstan/Customer.stub | 67 +++++++++++++++++++ 10 files changed, 114 insertions(+), 31 deletions(-) create mode 100644 phpstan/BaseInfo.stub create mode 100644 phpstan/Customer.stub diff --git a/Controller/Admin/ConfigController.php b/Controller/Admin/ConfigController.php index 5e60ff6..e784a6d 100644 --- a/Controller/Admin/ConfigController.php +++ b/Controller/Admin/ConfigController.php @@ -37,7 +37,7 @@ public function __construct( /** * @param Request $request * - * @return RedirectResponse|array + * @return RedirectResponse|array */ #[Route(path: '/%eccube_admin_route%/two_factor_auth_customer44/config', name: 'two_factor_auth_customer44_admin_config', methods: ['GET', 'POST'])] #[Template('@TwoFactorAuthCustomer44/admin/config.twig')] diff --git a/Controller/CustomerPersonalValidationController.php b/Controller/CustomerPersonalValidationController.php index 0edbf79..76a12a1 100644 --- a/Controller/CustomerPersonalValidationController.php +++ b/Controller/CustomerPersonalValidationController.php @@ -26,11 +26,6 @@ use Symfony\Component\RateLimiter\RateLimiterFactory; use Symfony\Component\Routing\Attribute\Route; use Twig\Environment; -use Twig\Error\LoaderError; -use Twig\Error\RuntimeError; -use Twig\Error\SyntaxError; -use Twilio\Exceptions\ConfigurationException; -use Twilio\Exceptions\TwilioException; use Twilio\Rest\Api\V2010\Account\MessageInstance; class CustomerPersonalValidationController extends AbstractController @@ -57,7 +52,7 @@ public function __construct( * @param Request $request * @param string $secret_key * - * @return array|RedirectResponse + * @return array|RedirectResponse */ #[Route(path: '/two_factor_auth/device_auth/input_onetime/{secret_key}', name: 'plg_customer_2fa_device_auth_input_onetime', requirements: ['secret_key' => '^[a-zA-Z0-9]+$'], methods: ['GET', 'POST'])] #[Template('@TwoFactorAuthCustomer44/default/device_auth/input.twig')] @@ -69,7 +64,6 @@ public function deviceAuthInputOneTime(Request $request, $secret_key) } $error = null; - /** @var Customer $Customer */ $Customer = $this->customerRepository->getProvisionalCustomerBySecretKey($secret_key); if ($Customer === null) { @@ -136,13 +130,7 @@ public function deviceAuthInputOneTime(Request $request, $secret_key) * @param Request $request * @param string $secret_key * - * @return array|RedirectResponse - * - * @throws ConfigurationException - * @throws LoaderError - * @throws RuntimeError - * @throws SyntaxError - * @throws TwilioException + * @return array|RedirectResponse */ #[Route(path: '/two_factor_auth/device_auth/send_onetime/{secret_key}', name: 'plg_customer_2fa_device_auth_send_onetime', requirements: ['secret_key' => '^[a-zA-Z0-9]+$'], methods: ['GET', 'POST'])] #[Template('@TwoFactorAuthCustomer44/default/device_auth/send.twig')] @@ -154,7 +142,6 @@ public function deviceAuthSendOneTime(Request $request, $secret_key) } $error = null; - /** @var Customer $Customer */ $Customer = $this->customerRepository->getProvisionalCustomerBySecretKey($secret_key); if ($Customer === null) { throw $this->createNotFoundException(); @@ -227,13 +214,6 @@ private function checkDeviceToken(Customer $Customer, string $token): bool * @param string $phoneNumber * * @return MessageInstance - * - * @throws LoaderError - * @throws RuntimeError - * @throws SyntaxError - * @throws ConfigurationException - * @throws TwilioException - * @throws \Exception */ private function sendDeviceToken(Customer $Customer, string $phoneNumber): MessageInstance { diff --git a/Controller/TwoFactorAuthCustomerController.php b/Controller/TwoFactorAuthCustomerController.php index 995f0b0..5924480 100644 --- a/Controller/TwoFactorAuthCustomerController.php +++ b/Controller/TwoFactorAuthCustomerController.php @@ -19,6 +19,7 @@ use Plugin\TwoFactorAuthCustomer44\Form\Type\TwoFactorAuthTypeCustomer; use Plugin\TwoFactorAuthCustomer44\Service\CustomerTwoFactorAuthService; use Symfony\Bridge\Twig\Attribute\Template; +use Symfony\Component\HttpFoundation\RedirectResponse; use Symfony\Component\HttpFoundation\Request; use Symfony\Component\Routing\Attribute\Route; use Twig\Environment; @@ -41,6 +42,8 @@ public function __construct( /** * (ログイン時)二段階認証設定(選択)画面. + * + * @return array|RedirectResponse */ #[Route(path: '/mypage/two_factor_auth/select_type', name: 'plg_customer_2fa_auth_type_select', methods: ['GET', 'POST'])] #[Template('@TwoFactorAuthCustomer44/default/tfa/select_type.twig')] diff --git a/Entity/TwoFactorAuthConfig.php b/Entity/TwoFactorAuthConfig.php index 2bdddb2..30df8ba 100644 --- a/Entity/TwoFactorAuthConfig.php +++ b/Entity/TwoFactorAuthConfig.php @@ -138,6 +138,9 @@ public function addIncludeRoute(string $route): self return $this; } + /** + * @return list + */ private function getRoutes(?string $routes): array { if (!$routes) { diff --git a/EventListener/CustomerPersonalValidationListener.php b/EventListener/CustomerPersonalValidationListener.php index d1791f4..c4a449d 100644 --- a/EventListener/CustomerPersonalValidationListener.php +++ b/EventListener/CustomerPersonalValidationListener.php @@ -74,7 +74,7 @@ public function __construct( } /** - * @return array + * @return array */ public static function getSubscribedEvents(): array { diff --git a/EventListener/CustomerTwoFactorAuthListener.php b/EventListener/CustomerTwoFactorAuthListener.php index 2fba12d..f601aa8 100755 --- a/EventListener/CustomerTwoFactorAuthListener.php +++ b/EventListener/CustomerTwoFactorAuthListener.php @@ -97,7 +97,7 @@ public function __construct( } /** - * @return array + * @return array */ public static function getSubscribedEvents(): array { diff --git a/Service/CustomerTwoFactorAuthService.php b/Service/CustomerTwoFactorAuthService.php index cc7ecea..579157c 100644 --- a/Service/CustomerTwoFactorAuthService.php +++ b/Service/CustomerTwoFactorAuthService.php @@ -147,7 +147,7 @@ public function __construct( } /** - * @return array + * @return list */ public function getDefaultAuthRoutes(): array { @@ -189,17 +189,18 @@ public function createAuthedCookie(Customer $Customer, $route = null): Cookie /** * 要認証ルートを取得. * - * @return array + * @return list */ public function getIncludeRoutes(): array { - $routes = []; $include = $this->twoFactorAuthConfig->getIncludeRoutes(); - if ($include) { - $routes = preg_split('/\R/', $include); + if (!$include) { + return []; } - return $routes; + $routes = preg_split('/\R/', $include); + + return $routes === false ? [] : $routes; } /** diff --git a/phpstan.neon.dist b/phpstan.neon.dist index 580d6c4..1a55dd8 100644 --- a/phpstan.neon.dist +++ b/phpstan.neon.dist @@ -5,6 +5,10 @@ parameters: excludePaths: - Resource/* - Tests/bootstrap.php + - phpstan/* + stubFiles: + - phpstan/Customer.stub + - phpstan/BaseInfo.stub doctrine: objectManagerLoader: ../../../tests/object-manager.php ormRepositoryClass: Eccube\Repository\AbstractRepository diff --git a/phpstan/BaseInfo.stub b/phpstan/BaseInfo.stub new file mode 100644 index 0000000..c371ec6 --- /dev/null +++ b/phpstan/BaseInfo.stub @@ -0,0 +1,25 @@ + + */ + public function getTwoFactorAuthCustomerCookies(): Collection + { + } + + /** + * @param Collection $TwoFactorAuthCustomerCookies + */ + public function setTwoFactorAuthCustomerCookies(Collection $TwoFactorAuthCustomerCookies): void + { + } +} From 0f618fef3177fb65d3fca64f0d0e557a897b87f1 Mon Sep 17 00:00:00 2001 From: Ken Tanaka Date: Mon, 14 Sep 2026 16:01:18 +0900 Subject: [PATCH 13/16] =?UTF-8?q?PHPStan=20=E3=81=AF=20ignoreErrors=20?= =?UTF-8?q?=E3=81=AB=E5=88=87=E3=82=8A=E6=9B=BF=E3=81=88=E3=80=81EntityExt?= =?UTF-8?q?ension=20=E3=81=AE=20stub=20=E3=82=92=E3=82=84=E3=82=81?= =?UTF-8?q?=E3=82=8B=E3=80=82?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../CustomerTwoFactorAuthListener.php | 9 +-- phpstan.neon.dist | 15 +++-- phpstan/BaseInfo.stub | 25 ------- phpstan/Customer.stub | 67 ------------------- 4 files changed, 16 insertions(+), 100 deletions(-) delete mode 100644 phpstan/BaseInfo.stub delete mode 100644 phpstan/Customer.stub diff --git a/EventListener/CustomerTwoFactorAuthListener.php b/EventListener/CustomerTwoFactorAuthListener.php index f601aa8..dc3ad6b 100755 --- a/EventListener/CustomerTwoFactorAuthListener.php +++ b/EventListener/CustomerTwoFactorAuthListener.php @@ -167,13 +167,14 @@ public function onLoginSuccess(LoginSuccessEvent $event): void return; } - if ($this->requestContext->getCurrentUser() === null) { + $Customer = $this->requestContext->getCurrentUser(); + if (!$Customer instanceof Customer) { // ログインしていない場合は処理なし return; } - if ($this->requestContext->getCurrentUser()->getTwoFactorAuthType() !== null - && $this->requestContext->getCurrentUser()->getTwoFactorAuthType()->isDisabled()) { + if ($Customer->getTwoFactorAuthType() !== null + && $Customer->getTwoFactorAuthType()->isDisabled()) { // ユーザーが選択した2段階認証方式は無効になっている場合、ログアウトさせる。 $event->setResponse(new RedirectResponse($this->router->generate('logout'), Response::HTTP_FOUND)); @@ -182,7 +183,7 @@ public function onLoginSuccess(LoginSuccessEvent $event): void $this->multiFactorAuth( $event, - $this->requestContext->getCurrentUser(), + $Customer, $event->getRequest()->attributes->get('_route')); } diff --git a/phpstan.neon.dist b/phpstan.neon.dist index 1a55dd8..08ca7f9 100644 --- a/phpstan.neon.dist +++ b/phpstan.neon.dist @@ -5,10 +5,17 @@ parameters: excludePaths: - Resource/* - Tests/bootstrap.php - - phpstan/* - stubFiles: - - phpstan/Customer.stub - - phpstan/BaseInfo.stub doctrine: objectManagerLoader: ../../../tests/object-manager.php ormRepositoryClass: Eccube\Repository\AbstractRepository + # stubFiles は doctrine.objectManagerLoader が Customer/BaseInfo の + # リフレクションを上書きするため EntityExtension メソッドには効かない。 + ignoreErrors: + - + message: '#Call to an undefined method Eccube\\Entity\\Customer::(get|set|is)(DeviceAuth|DeviceAuthed|TwoFactorAuth).*#' + - + message: '#Call to an undefined method Eccube\\Entity\\BaseInfo::(is|set)(TwoFactorAuthUse|OptionActivateDevice)\(\)#' + # twilio/sdk のクラスが PHPStan のオートロードに乗らない + - + message: '#Twilio\\#' + reportUnmatchedIgnoredErrors: false diff --git a/phpstan/BaseInfo.stub b/phpstan/BaseInfo.stub deleted file mode 100644 index c371ec6..0000000 --- a/phpstan/BaseInfo.stub +++ /dev/null @@ -1,25 +0,0 @@ - - */ - public function getTwoFactorAuthCustomerCookies(): Collection - { - } - - /** - * @param Collection $TwoFactorAuthCustomerCookies - */ - public function setTwoFactorAuthCustomerCookies(Collection $TwoFactorAuthCustomerCookies): void - { - } -} From 577446fc7167403e5b5735f6416727618a3a205f Mon Sep 17 00:00:00 2001 From: Ken Tanaka Date: Mon, 14 Sep 2026 16:07:07 +0900 Subject: [PATCH 14/16] =?UTF-8?q?PHPStan=20=E3=81=AE=E6=AE=8B=E6=8C=87?= =?UTF-8?q?=E6=91=98=E3=82=92=E4=BF=AE=E6=AD=A3=E3=81=97=E3=80=81trait.unu?= =?UTF-8?q?sed=20=E3=81=A8=20columnType=20=E3=82=92=E8=A8=B1=E5=AE=B9?= =?UTF-8?q?=E3=81=99=E3=82=8B=E3=80=82?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Controller/TwoFactorAuthCustomerController.php | 14 +++++++++----- Entity/TwoFactorAuthConfig.php | 3 +++ Event.php | 5 ++++- EventListener/CustomerTwoFactorAuthListener.php | 17 +++++++++++------ .../TwoFactorAuthBaseSettingTypeExtension.php | 7 +++++-- .../TwoFactorAuthCustomerTypeExtension.php | 2 +- Repository/TwoFactorAuthTypeRepository.php | 15 +++++++++++++++ Service/CustomerTwoFactorAuthService.php | 8 ++++---- phpstan.neon.dist | 7 +++++++ 9 files changed, 59 insertions(+), 19 deletions(-) diff --git a/Controller/TwoFactorAuthCustomerController.php b/Controller/TwoFactorAuthCustomerController.php index 5924480..7ad9470 100644 --- a/Controller/TwoFactorAuthCustomerController.php +++ b/Controller/TwoFactorAuthCustomerController.php @@ -53,12 +53,17 @@ public function selectAuthType(Request $request) return $this->redirectToRoute($this->getCallbackRoute()); } - /** @var Customer $Customer */ $Customer = $this->getUser(); + if (!$Customer instanceof Customer) { + return $this->redirectToRoute('mypage'); + } // 2段階認証方式が選択されている場合は、その方式の初回認証画面へ遷移 - if ($Customer !== null && $Customer->getTwoFactorAuthType() !== null) { - return $this->redirectToRoute($Customer->getTwoFactorAuthType()->getRoute()); + if ($Customer->getTwoFactorAuthType() !== null) { + $route = $Customer->getTwoFactorAuthType()->getRoute(); + if ($route !== null) { + return $this->redirectToRoute($route); + } } $error = null; @@ -95,9 +100,8 @@ public function selectAuthType(Request $request) */ protected function isTwoFactorAuthed(): bool { - /** @var Customer $Customer */ $Customer = $this->getUser(); - if ($Customer != null && !$this->customerTwoFactorAuthService->isAuthed($Customer, $this->getCallbackRoute())) { + if ($Customer instanceof Customer && !$this->customerTwoFactorAuthService->isAuthed($Customer, $this->getCallbackRoute())) { return false; } diff --git a/Entity/TwoFactorAuthConfig.php b/Entity/TwoFactorAuthConfig.php index 30df8ba..15c769f 100644 --- a/Entity/TwoFactorAuthConfig.php +++ b/Entity/TwoFactorAuthConfig.php @@ -185,6 +185,9 @@ public function removeIncludeRoute(string $route): self return $this; } + /** + * @param array $routes + */ private function getRoutesAsString(array $routes): string { return implode(PHP_EOL, $routes); diff --git a/Event.php b/Event.php index 01d0e7b..a9ee604 100644 --- a/Event.php +++ b/Event.php @@ -34,9 +34,12 @@ class Event implements EventSubscriberInterface */ public function __construct(TwoFactorAuthTypeRepository $twoFactorAuthTypeRepository) { - $this->hasActiveAuthType = $twoFactorAuthTypeRepository->count(['isDisabled' => false]) > 0; + $this->hasActiveAuthType = $twoFactorAuthTypeRepository->hasActiveType(); } + /** + * @return array + */ public static function getSubscribedEvents(): array { return [ diff --git a/EventListener/CustomerTwoFactorAuthListener.php b/EventListener/CustomerTwoFactorAuthListener.php index dc3ad6b..6bdfea4 100755 --- a/EventListener/CustomerTwoFactorAuthListener.php +++ b/EventListener/CustomerTwoFactorAuthListener.php @@ -26,6 +26,7 @@ use Symfony\Component\HttpFoundation\RedirectResponse; use Symfony\Component\HttpFoundation\RequestStack; use Symfony\Component\HttpFoundation\Response; +use Symfony\Component\HttpFoundation\Session\SessionInterface; use Symfony\Component\HttpKernel\Event\ControllerArgumentsEvent; use Symfony\Component\HttpKernel\KernelEvents; use Symfony\Component\Routing\Generator\UrlGeneratorInterface; @@ -56,17 +57,21 @@ class CustomerTwoFactorAuthListener implements EventSubscriberInterface */ protected $baseInfo; /** - * @var Session + * @var SessionInterface */ - protected $session; + protected SessionInterface $session; /** * 通常(ログイン・マイページ)ルート. + * + * @var list */ - protected $default_routes; + protected array $default_routes; /** * 重要操作ルート. + * + * @var list */ - protected $include_routes; + protected array $include_routes; /** * @param Context $requestContext @@ -219,7 +224,7 @@ private function isDefaultRoute(string $route, string $uri): bool /** * ルート・URIが対象であるかチェック. * - * @param array $targetRoutes + * @param list $targetRoutes * @param string $route * @param string $uri * @@ -271,7 +276,7 @@ private function multiFactorAuth(Event $event, Customer $Customer, string $route return; } - if (count($this->twoFactorAuthTypeRepository->findBy(['isDisabled' => false])) == 0) { + if (!$this->twoFactorAuthTypeRepository->hasActiveType()) { // 2段階認証プラグインが有効化されていない場合処理なし return; } diff --git a/Form/Type/Extension/Admin/TwoFactorAuthBaseSettingTypeExtension.php b/Form/Type/Extension/Admin/TwoFactorAuthBaseSettingTypeExtension.php index d501db9..13c7fd8 100644 --- a/Form/Type/Extension/Admin/TwoFactorAuthBaseSettingTypeExtension.php +++ b/Form/Type/Extension/Admin/TwoFactorAuthBaseSettingTypeExtension.php @@ -17,6 +17,7 @@ use Eccube\Form\Type\Admin\ShopMasterType; use Eccube\Form\Type\ToggleSwitchType; use Plugin\TwoFactorAuthCustomer44\Entity\TwoFactorAuthType; +use Plugin\TwoFactorAuthCustomer44\Repository\TwoFactorAuthTypeRepository; use Symfony\Component\Form\AbstractTypeExtension; use Symfony\Component\Form\FormBuilderInterface; use Symfony\Component\Form\FormEvent; @@ -45,7 +46,7 @@ public static function getExtendedTypes(): iterable * buildForm. * * @param FormBuilderInterface $builder - * @param array $options + * @param array $options */ public function buildForm(FormBuilderInterface $builder, array $options): void { @@ -56,7 +57,9 @@ public function buildForm(FormBuilderInterface $builder, array $options): void $builder->addEventListener(FormEvents::POST_SET_DATA, function (FormEvent $event) { $form = $event->getForm(); - if ($this->entityManager->getRepository(TwoFactorAuthType::class)->count(['isDisabled' => false]) > 0) { + /** @var TwoFactorAuthTypeRepository $typeRepository */ + $typeRepository = $this->entityManager->getRepository(TwoFactorAuthType::class); + if ($typeRepository->hasActiveType()) { $form->add('two_factor_auth_use', ToggleSwitchType::class, [ 'required' => false, 'mapped' => true, diff --git a/Form/Type/Extension/Admin/TwoFactorAuthCustomerTypeExtension.php b/Form/Type/Extension/Admin/TwoFactorAuthCustomerTypeExtension.php index fcd2141..c1e8a69 100755 --- a/Form/Type/Extension/Admin/TwoFactorAuthCustomerTypeExtension.php +++ b/Form/Type/Extension/Admin/TwoFactorAuthCustomerTypeExtension.php @@ -47,7 +47,7 @@ public static function getExtendedTypes(): iterable * buildForm. * * @param FormBuilderInterface $builder - * @param array $options + * @param array $options */ public function buildForm(FormBuilderInterface $builder, array $options): void { diff --git a/Repository/TwoFactorAuthTypeRepository.php b/Repository/TwoFactorAuthTypeRepository.php index 0dcbb16..5dcb3f8 100644 --- a/Repository/TwoFactorAuthTypeRepository.php +++ b/Repository/TwoFactorAuthTypeRepository.php @@ -42,4 +42,19 @@ public function findOne(): ?TwoFactorAuthType { return $this->findOneBy([], ['id' => 'DESC']); } + + /** + * 有効な二段階認証方式が1件以上あるか. + */ + public function hasActiveType(): bool + { + $count = (int) $this->createQueryBuilder('t') + ->select('COUNT(t.id)') + ->where('t.isDisabled = :disabled') + ->setParameter('disabled', false) + ->getQuery() + ->getSingleScalarResult(); + + return $count > 0; + } } diff --git a/Service/CustomerTwoFactorAuthService.php b/Service/CustomerTwoFactorAuthService.php index 579157c..5eab3b5 100644 --- a/Service/CustomerTwoFactorAuthService.php +++ b/Service/CustomerTwoFactorAuthService.php @@ -167,11 +167,11 @@ public function setContainer(ContainerBagInterface $container): ?ContainerBagInt * 2段階認証用Cookie生成. * * @param Customer $Customer - * @param null $route + * @param string|null $route * * @return Cookie */ - public function createAuthedCookie(Customer $Customer, $route = null): Cookie + public function createAuthedCookie(Customer $Customer, ?string $route = null): Cookie { $expire = $this->expire; $cookieName = $this->cookieName; @@ -207,11 +207,11 @@ public function getIncludeRoutes(): array * 認証済みか? * * @param Customer $Customer - * @param null $route + * @param string|null $route * * @return bool */ - public function isAuthed(Customer $Customer, $route = null): bool + public function isAuthed(Customer $Customer, ?string $route = null): bool { if (!$Customer->getTwoFactorAuthType() === null) { return false; diff --git a/phpstan.neon.dist b/phpstan.neon.dist index 08ca7f9..ec5115d 100644 --- a/phpstan.neon.dist +++ b/phpstan.neon.dist @@ -18,4 +18,11 @@ parameters: # twilio/sdk のクラスが PHPStan のオートロードに乗らない - message: '#Twilio\\#' + # EntityExtension の trait は実行時 proxy に載るため、解析上は未使用になる + - + identifier: trait.unused + # EC-CUBE 本体と同様。new Entity() 時に nullable が必要なプロパティと DB 非 null の差 + - + message: "#^Property .+::\\$.+ type mapping mismatch: property can contain .+\\|null but database expects .+\\.$#" + identifier: doctrine.columnType reportUnmatchedIgnoredErrors: false From bd4a0620dd27420c5cd4695fda1106d66e6bc9db Mon Sep 17 00:00:00 2001 From: Ken Tanaka Date: Mon, 14 Sep 2026 16:18:26 +0900 Subject: [PATCH 15/16] =?UTF-8?q?PHPStan=20=E5=90=91=E3=81=91=E3=81=AB=20R?= =?UTF-8?q?epository=20=E3=81=AE=20generic=20=E3=81=A8=E3=82=A4=E3=83=99?= =?UTF-8?q?=E3=83=B3=E3=83=88=E5=9E=8B=E3=82=92=E4=BF=AE=E6=AD=A3=E3=81=99?= =?UTF-8?q?=E3=82=8B=E3=80=82?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../CustomerTwoFactorAuthListener.php | 46 ++++++++++++------- Form/Type/TwoFactorAuthConfigType.php | 2 +- PluginManager.php | 6 ++- Repository/TwoFactorAuthConfigRepository.php | 2 + .../TwoFactorAuthCustomerCookieRepository.php | 7 +-- Repository/TwoFactorAuthTypeRepository.php | 2 + 6 files changed, 44 insertions(+), 21 deletions(-) diff --git a/EventListener/CustomerTwoFactorAuthListener.php b/EventListener/CustomerTwoFactorAuthListener.php index 6bdfea4..5dbe17c 100755 --- a/EventListener/CustomerTwoFactorAuthListener.php +++ b/EventListener/CustomerTwoFactorAuthListener.php @@ -32,7 +32,6 @@ use Symfony\Component\Routing\Generator\UrlGeneratorInterface; use Symfony\Component\Security\Http\Event\LoginSuccessEvent; use Symfony\Component\Security\Http\Event\LogoutEvent; -use Symfony\Contracts\EventDispatcher\Event; class CustomerTwoFactorAuthListener implements EventSubscriberInterface { @@ -137,6 +136,9 @@ public function onKernelController(ControllerArgumentsEvent $event): void $route = $event->getRequest()->attributes->get('_route'); $uri = $event->getRequest()->getRequestUri(); + if (!is_string($route)) { + return; + } $Customer = $this->requestContext->getCurrentUser(); @@ -186,10 +188,12 @@ public function onLoginSuccess(LoginSuccessEvent $event): void return; } + $route = $event->getRequest()->attributes->get('_route'); $this->multiFactorAuth( $event, $Customer, - $event->getRequest()->attributes->get('_route')); + is_string($route) ? $route : '', + ); } /** @@ -263,13 +267,13 @@ private function isIncludeRoute(string $route, string $uri): bool /** * 多要素認証. * - * @param Event $event + * @param ControllerArgumentsEvent|LoginSuccessEvent $event * @param Customer $Customer * @param string $route * * @return void */ - private function multiFactorAuth(Event $event, Customer $Customer, string $route): void + private function multiFactorAuth(ControllerArgumentsEvent|LoginSuccessEvent $event, Customer $Customer, string $route): void { if (!$this->baseInfo->isTwoFactorAuthUse()) { // MFA無効の場合処理なし @@ -299,10 +303,10 @@ private function multiFactorAuth(Event $event, Customer $Customer, string $route /** * 多要素認証方式設定画面へリダイレクト. * - * @param Event $event + * @param ControllerArgumentsEvent|LoginSuccessEvent $event * @param string|null $route */ - private function selectAuthType(Event $event, ?string $route): void + private function selectAuthType(ControllerArgumentsEvent|LoginSuccessEvent $event, ?string $route): void { // [会員] 2段階認証が未設定の場合 // コールバックURLをセッションへ設定 @@ -310,11 +314,7 @@ private function selectAuthType(Event $event, ?string $route): void // 2段階認証選択画面へリダイレクト $url = $this->router->generate('plg_customer_2fa_auth_type_select', [], UrlGeneratorInterface::ABSOLUTE_PATH); - if ($event instanceof ControllerArgumentsEvent) { - $event->setController(fn () => new RedirectResponse($url, Response::HTTP_FOUND)); - } else { - $event->setResponse(new RedirectResponse($url, Response::HTTP_FOUND)); - } + $this->setRedirect($event, $url); } /** @@ -332,24 +332,38 @@ private function setCallbackRoute(?string $route): void /** * 2段階認証のディスパッチ. * - * @param Event $event + * @param ControllerArgumentsEvent|LoginSuccessEvent $event * @param Customer $Customer * @param string|null $route */ - private function auth(Event $event, Customer $Customer, ?string $route): void + private function auth(ControllerArgumentsEvent|LoginSuccessEvent $event, Customer $Customer, ?string $route): void { // コールバックURLをセッションへ設定 $this->setCallbackRoute($route); + + $authType = $Customer->getTwoFactorAuthType(); + if ($authType === null) { + return; + } + // 選択された多要素認証方式で指定されているルートへリダイレクト - if ($Customer->getTwoFactorAuthType() !== null && $Customer->getTwoFactorAuthType()->isDisabled()) { + if ($authType->isDisabled()) { // ユーザーが選択した2段階認証方式は無効になっている場合、ログアウトさせる。 - $event->setController(fn () => new RedirectResponse($this->router->generate('logout'), Response::HTTP_FOUND)); + $this->setRedirect($event, $this->router->generate('logout')); + + return; + } + $routeName = $authType->getRoute(); + if ($routeName === null) { return; } - $url = $this->router->generate($Customer->getTwoFactorAuthType()->getRoute()); + $this->setRedirect($event, $this->router->generate($routeName)); + } + private function setRedirect(ControllerArgumentsEvent|LoginSuccessEvent $event, string $url): void + { if ($event instanceof ControllerArgumentsEvent) { $event->setController(fn () => new RedirectResponse($url, Response::HTTP_FOUND)); } else { diff --git a/Form/Type/TwoFactorAuthConfigType.php b/Form/Type/TwoFactorAuthConfigType.php index 7ad3072..54cd143 100644 --- a/Form/Type/TwoFactorAuthConfigType.php +++ b/Form/Type/TwoFactorAuthConfigType.php @@ -84,7 +84,7 @@ public function buildForm(FormBuilderInterface $builder, array $options): void $errors = $this->validator->validate($data['plain_api_secret'], [ new Assert\Regex(pattern: '/^[a-zA-Z0-9]+$/i', message: 'form_error.graph_only'), ]); - if ($errors) { + if (count($errors) > 0) { foreach ($errors as $error) { $form['plain_api_secret']->addError(new FormError($error->getMessage())); } diff --git a/PluginManager.php b/PluginManager.php index 1189431..83b2bc5 100644 --- a/PluginManager.php +++ b/PluginManager.php @@ -28,7 +28,11 @@ */ class PluginManager extends AbstractPluginManager { - // 設定対象ページ情報 + /** + * 設定対象ページ情報 + * + * @var list + */ private array $pages = [ ['plg_customer_2fa_device_auth_send_onetime', 'デバイス認証送信先入力', 'TwoFactorAuthCustomer44/Resource/template/default/device_auth/send'], ['plg_customer_2fa_device_auth_input_onetime', 'デバイス認証トークン入力', 'TwoFactorAuthCustomer44/Resource/template/default/device_auth/input'], diff --git a/Repository/TwoFactorAuthConfigRepository.php b/Repository/TwoFactorAuthConfigRepository.php index b99635b..2202ab5 100644 --- a/Repository/TwoFactorAuthConfigRepository.php +++ b/Repository/TwoFactorAuthConfigRepository.php @@ -22,6 +22,8 @@ * * This class was generated by the Doctrine ORM. Add your own custom * repository methods below. + * + * @extends AbstractRepository */ class TwoFactorAuthConfigRepository extends AbstractRepository { diff --git a/Repository/TwoFactorAuthCustomerCookieRepository.php b/Repository/TwoFactorAuthCustomerCookieRepository.php index 0de1dbc..64323c9 100644 --- a/Repository/TwoFactorAuthCustomerCookieRepository.php +++ b/Repository/TwoFactorAuthCustomerCookieRepository.php @@ -21,10 +21,12 @@ use Plugin\TwoFactorAuthCustomer44\Entity\TwoFactorAuthCustomerCookie; /** - * TwoFactorAuthConfigRepository. + * TwoFactorAuthCustomerCookieRepository. * * This class was generated by the Doctrine ORM. Add your own custom * repository methods below. + * + * @extends AbstractRepository */ class TwoFactorAuthCustomerCookieRepository extends AbstractRepository { @@ -54,7 +56,6 @@ public function generateCookieData( int $expireSeconds, int $CookieValueCharacterLength, ): TwoFactorAuthCustomerCookie { - /** @var TwoFactorAuthCustomerCookie[]|null $previousCookies */ $previousCookies = $this->findOldCookies($customer, $cookieName); foreach ($previousCookies as $cookie) { $this->getEntityManager()->remove($cookie); @@ -129,7 +130,7 @@ public function searchForCookie(Customer $customer, string $cookieName): array * * @param Customer $customer */ - public function deleteByCustomer(Customer $customer) + public function deleteByCustomer(Customer $customer): void { $em = $this->getEntityManager(); $em->beginTransaction(); diff --git a/Repository/TwoFactorAuthTypeRepository.php b/Repository/TwoFactorAuthTypeRepository.php index 5dcb3f8..baed146 100644 --- a/Repository/TwoFactorAuthTypeRepository.php +++ b/Repository/TwoFactorAuthTypeRepository.php @@ -22,6 +22,8 @@ * * This class was generated by the Doctrine ORM. Add your own custom * repository methods below. + * + * @extends AbstractRepository */ class TwoFactorAuthTypeRepository extends AbstractRepository { From 71dac8a7859245a982a5051630cb7aa91c777e8e Mon Sep 17 00:00:00 2001 From: Ken Tanaka Date: Mon, 14 Sep 2026 16:29:44 +0900 Subject: [PATCH 16/16] =?UTF-8?q?PHPStan=20=E3=81=AE=E6=AE=8B=E3=82=8A?= =?UTF-8?q?=E5=9E=8B=E6=8C=87=E6=91=98=E3=82=92=E7=9B=B4=E3=81=97=E3=80=81?= =?UTF-8?q?=E8=AA=8D=E8=A8=BC=E3=82=BF=E3=82=A4=E3=83=97=E5=88=A4=E5=AE=9A?= =?UTF-8?q?=E3=81=AE=E6=BC=94=E7=AE=97=E5=AD=90=E5=84=AA=E5=85=88=E9=A0=86?= =?UTF-8?q?=E4=BD=8D=E3=82=92=E4=BF=AE=E6=AD=A3=E3=81=99=E3=82=8B=E3=80=82?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../TwoFactorAuthCustomerCookieRepository.php | 9 +++++---- Service/CustomerTwoFactorAuthService.php | 17 ++++++++--------- 2 files changed, 13 insertions(+), 13 deletions(-) diff --git a/Repository/TwoFactorAuthCustomerCookieRepository.php b/Repository/TwoFactorAuthCustomerCookieRepository.php index 64323c9..0e1ab87 100644 --- a/Repository/TwoFactorAuthCustomerCookieRepository.php +++ b/Repository/TwoFactorAuthCustomerCookieRepository.php @@ -78,7 +78,7 @@ public function generateCookieData( * @param Customer $customer * @param string $cookieName * - * @return TwoFactorAuthCustomerCookie[] + * @return list */ public function findOldCookies(Customer $customer, string $cookieName): array { @@ -103,12 +103,13 @@ public function findOne(): ?TwoFactorAuthCustomerCookie return $this->findOneBy([], ['id' => 'DESC']); } - /*** + /** * 有効クッキーを取得する * * @param Customer $customer * @param string $cookieName - * @return TwoFactorAuthCustomerCookie[] + * + * @return list */ public function searchForCookie(Customer $customer, string $cookieName): array { @@ -125,7 +126,7 @@ public function searchForCookie(Customer $customer, string $cookieName): array ->getResult(); } - /*** + /** * 会員のクッキーを削除 * * @param Customer $customer diff --git a/Service/CustomerTwoFactorAuthService.php b/Service/CustomerTwoFactorAuthService.php index 5eab3b5..0df1963 100644 --- a/Service/CustomerTwoFactorAuthService.php +++ b/Service/CustomerTwoFactorAuthService.php @@ -19,7 +19,6 @@ use Eccube\Entity\Customer; use Eccube\Repository\BaseInfoRepository; use Plugin\TwoFactorAuthCustomer44\Entity\TwoFactorAuthConfig; -use Plugin\TwoFactorAuthCustomer44\Entity\TwoFactorAuthCustomerCookie; use Plugin\TwoFactorAuthCustomer44\Repository\TwoFactorAuthConfigRepository; use Plugin\TwoFactorAuthCustomer44\Repository\TwoFactorAuthCustomerCookieRepository; use Symfony\Component\DependencyInjection\ParameterBag\ContainerBagInterface; @@ -94,9 +93,9 @@ class CustomerTwoFactorAuthService private readonly int $tokenLength; /** - * @var array + * @var list */ - private $default_tfa_routes = [ + private array $default_tfa_routes = [ 'login', 'mypage_login', 'mypage', @@ -213,7 +212,7 @@ public function getIncludeRoutes(): array */ public function isAuthed(Customer $Customer, ?string $route = null): bool { - if (!$Customer->getTwoFactorAuthType() === null) { + if ($Customer->getTwoFactorAuthType() === null) { return false; } @@ -250,7 +249,6 @@ public function isRouteAuthed(Customer $Customer, string $cookieName, int $expir if ($json = $this->request->cookies->get($cookieName)) { $configs = json_decode($json); - /** @var TwoFactorAuthCustomerCookie[]|null $activeCookies */ $activeCookies = $this ->twoFactorCustomerCookieRepository ->searchForCookie($Customer, $cookieName); @@ -337,15 +335,15 @@ public function isEnabled(): bool * * TODO: APIエラーハンドルの追加、 * - * @param $phoneNumber - * @param $body + * @param string $phoneNumber + * @param string $body * * @return MessageInstance * * @throws ConfigurationException * @throws TwilioException */ - public function sendBySms($phoneNumber, $body): MessageInstance + public function sendBySms(string $phoneNumber, string $body): MessageInstance { // Twilio // SMS送信(現在国内電話番号のみ対象) @@ -421,9 +419,10 @@ public function verifyOneTimeToken(string $hashedToken, string $token): bool return false; } - /*** + /** * @param string $haystack * @param string $needle + * * @return bool * * @deprecated ECCUBEの最低PHPバージョンは8.0になったら, この関数を消してphp8.0からのstr_containsを利用する