Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Additional function: array with multiple passwords #4

Open
gbdesign2023 opened this issue Nov 10, 2024 · 4 comments
Open

Additional function: array with multiple passwords #4

gbdesign2023 opened this issue Nov 10, 2024 · 4 comments

Comments

@gbdesign2023
Copy link

gbdesign2023 commented Nov 10, 2024

I added the function to your script that allows me to use different passwords.
This can be useful if a password changes monthly, and you want to create a list in advance.

config.php

'pechente.kirby-password-guard' => [
    'enabled' => true,
    'passwords' => [
        'password',
        'password2',
        'password3'
    ],
    'pattern' => '(:all)',
],

index.php

<?php

use Kirby\Cms\Page;

Kirby::plugin('pechente/kirby-password-guard', [
    'templates' => [
        'password-guard' => __DIR__ . '/templates/password-guard.php',
    ],
    'snippets' => [
        'panel-icon' => __DIR__ . '/snippets/panel-icon.php',
    ],
    'routes' => [
        [
            'pattern' => 'password-guard',
            'language' => '*',
            'method' => 'POST',
            'action' => function () {
                $password = get('password');
                $hashedPassword = password_hash($password, PASSWORD_BCRYPT);

                $session = kirby()->session();
                $session->set('kirby-password-guard.password-hash', $hashedPassword);

                $redirect = get('redirect');

                kirby()->response()->redirect($redirect);
            }
        ],
        [
            'pattern' => option('pechente.kirby-password-guard.pattern', '(:all)'),
            'method' => 'GET',
            'action' => function (string $uid) {
                if (
                    option('pechente.kirby-password-guard.enabled') === false ||
                    !option('pechente.kirby-password-guard.passwords') || // Adjustment here: Check for an array of passwords
                    kirby()->user()
                ) {
                    $this->next();
                }
                $passwordIncorrect = false;

                // Retrieve the session and stored hash
                $session = kirby()->session();
                $hash = $session->get('kirby-password-guard.password-hash');
                $passwords = option('pechente.kirby-password-guard.passwords'); // Load the array of passwords

                // Check if any of the passwords are correct
                if ($hash) {
                    foreach ($passwords as $password) {
                        if (password_verify($password, $hash)) {
                            $this->next(); // Redirect if the password is correct
                        }
                    }
                    // If no password was correct, mark the password as incorrect
                    $passwordIncorrect = true;
                    kirby()->session()->remove('kirby-password-guard.password-hash');
                }

                // Render the password page if the password is incorrect
                $passwordPage = new Page([
                    'slug' => 'password-guard',
                    'template' => 'password-guard',
                    'content' => [
                        'title' => 'Password Guard',
                        'redirect' => url($uid),
                        'passwordIncorrect' => $passwordIncorrect
                    ]
                ]);

                return $passwordPage->render();
            }
        ]
    ],
]);
@Pechente
Copy link
Owner

Pechente commented Nov 10, 2024

That's pretty cool! Feel free to submit a pull request. One note though: It would be great if it was still compatible with the old config pattern. I.e if 'password' is filled in the config, just add it to the array of passwords. That way existing configs will not break.

@gbdesign2023
Copy link
Author

gbdesign2023 commented Nov 10, 2024

And with this addition, it is possible to de-/activate the plugin in the panel:

site.yml

fields:
  passwordGuardEnabled:
    label:
      en: 'Enable "Password Guard"?'
      de: '"Password Guard" aktivieren?'
    type: toggle
    text:
      -
        en: not activated
        de: nicht aktiviert
      -
        en: activated
        de: aktiviert
    default: false
    icon: lock
    help:
      en: The website is only protected for users who are logged out.
      de: Die Website wird nur für ausgeloggte User geschützt.
<?php

use Kirby\Cms\Page;

Kirby::plugin('pechente/kirby-password-guard', [
    'templates' => [
        'password-guard' => __DIR__ . '/templates/password-guard.php',
    ],
    'snippets' => [
        'panel-icon' => __DIR__ . '/snippets/panel-icon.php',
    ],
    'routes' => [
        [
            'pattern' => 'password-guard',
            'language' => '*',
            'method' => 'POST',
            'action' => function () {
                $password = get('password');
                $hashedPassword = password_hash($password, PASSWORD_BCRYPT);

                $session = kirby()->session();
                $session->set('kirby-password-guard.password-hash', $hashedPassword);

                $redirect = get('redirect');

                kirby()->response()->redirect($redirect);
            }
        ],
        [
            'pattern' => option('pechente.kirby-password-guard.pattern', '(:all)'),
            'method' => 'GET',
            'action' => function (string $uid) {
                // Check if the password guard is enabled using the value from the Panel field
                if (
                    site()->passwordGuardEnabled()->toBool() === false || // Use the value from the site field
                    !option('pechente.kirby-password-guard.passwords') || // Check for an array of passwords
                    kirby()->user()
                ) {
                    $this->next();
                }
                $passwordIncorrect = false;

                // Retrieve the session and stored hash
                $session = kirby()->session();
                $hash = $session->get('kirby-password-guard.password-hash');
                $passwords = option('pechente.kirby-password-guard.passwords'); // Load the array of passwords

                // Check if any of the passwords are correct
                if ($hash) {
                    foreach ($passwords as $password) {
                        if (password_verify($password, $hash)) {
                            $this->next(); // Redirect if the password is correct
                        }
                    }
                    // If no password was correct, mark the password as incorrect
                    $passwordIncorrect = true;
                    kirby()->session()->remove('kirby-password-guard.password-hash');
                }

                // Render the password page if the password is incorrect
                $passwordPage = new Page([
                    'slug' => 'password-guard',
                    'template' => 'password-guard',
                    'content' => [
                        'title' => 'Password Guard',
                        'redirect' => url($uid),
                        'passwordIncorrect' => $passwordIncorrect
                    ]
                ]);

                return $passwordPage->render();
            }
        ]
    ],
]);

@gbdesign2023
Copy link
Author

@Pechente I have to admit that I have never created a pull request...
With the addition in the site.yml blueprint, it would also be better to create a snippet in the plugin.

@gbdesign2023
Copy link
Author

@Pechente It is also possible to create a list of passwords in the panel. These are then stored in plain text in site.txt. This is, of course, not as secure as hardcoding them in config.php. Would this option still be of interest to you?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants