Giter Club home page Giter Club logo

Comments (6)

czernika avatar czernika commented on May 26, 2024 3

@kaizirlewagen What are you missing is you need to use TwoFactorScreenAuthenticatable as a trait within Screen

Basically the whole setup process is

  1. Install Laravel Fortify package
composer require laravel/fortify
  1. Publish its resources
php artisan vendor:publish --provider="Laravel\Fortify\FortifyServiceProvider"
  1. Run migrations to add two_fa columns
php artisan migrate
  1. Add FortifyServiceProvider into providers array within config/app.php (I lost 15 minutes of my life when forget to do this in a first time :)
  2. Add TwoFactorAuthenticatable trait to User model
use Laravel\Fortify\TwoFactorAuthenticatable;

class User extends Authenticatable
{
    use TwoFactorAuthenticatable;
}
  1. Install Orchid Fortify
composer require orchid/fortify
  1. Set to false auth key of config/platform.php

  2. Within required Screen (for example, UserProfileScreen add following lines

use Orchid\Screen\Screen;
use Orchid\Fortify\TwoFactorScreenAuthenticatable;

class UserProfileScreen extends Screen
{
	use TwoFactorScreenAuthenticatable; // I guess this is where you've been stacked

    public function commandBar(): iterable
    {
        return [
		$this->twoFactorCommandBar(), // dropdown button
	];
    }

    public function layout(): iterable
    {
        return [
		// other layouts
		
		$this->twoFactorLayout(), // modal and methods
        ];
    }
}
  1. Almost done, BUT it is still needs extra actions to be done to work

Fortify provides some options - one of them is to confirm Two FA or not. You may find this within config/fortify.php

'features' => [
    Features::twoFactorAuthentication([
        'confirm' => true, // confirm Two FA
        'confirmPassword' => true, // confirm password to enable Two FA
    ]),
],

confirm key requires to you to confirm TwoFA. If TwoFA keys was not confirmed you still be able to login without TwoFA.

Or you may just disable it ('confirm' => false) if you're ok with no confirmation - it is will work

You may achieve this as you wish, I will show "my way"

  1. Create Layout for confirmation code
use Orchid\Screen\Field;
use Orchid\Screen\Fields\Input;
use Orchid\Screen\Layouts\Rows;

class ProfileTwoFALayout extends Rows
{
    protected function fields(): iterable
    {
        return [
		Input::make('code'), // key should be named `code`. That's basically required minimum
	];
    }
}
  1. Add Layout to your Screen
class UserProfileScreen extends Screen
{
use TwoFactorScreenAuthenticatable; // I guess this is where you've been stacked

    public function commandBar(): iterable
    {
        return [
		$this->twoFactorCommandBar(), // dropdown button
	];
    }

    public function layout(): iterable
    {
        return [
            Layout::block(ProfileTwoFALayout::class)
                ->title(__('Confirm Two FA'))
		->canSee(
                    auth()->user()->two_factor_secret && // show if authorized user has enabled Two FA
                    !auth()->user()->two_factor_confirmed_at // but still doesn't confirmed it
                )
                ->commands(
                    Button::make(__('Confirm'))
                        ->type(Color::PRIMARY())
                        ->icon('check')
                        ->action(route('two-factor.confirm')) // this route provided by Fortify and should not be changed
                ),

		// other layouts

		$this->twoFactorLayout(), // modal and methods
        ];
    }
}

As you can see I implemented canSee() method to show this layout by specific condition. As I am using it only for user profile screen, I can use auth()->user() with no fear. You app may require other logic to handle

After hitting confirm you will be redirect back, and in your database you will see all three columns two_factor_secret, two_factor_recovery_code and two_factor_confirmed_at filled with information.

And that's it

from fortify.

tabuna avatar tabuna commented on May 26, 2024

Hi @kaizirlewagen

It means that you need to add this trend and code to the UserProfileScreen class

from fortify.

kaizirlewagen avatar kaizirlewagen commented on May 26, 2024

I edit "UserProfileScreen.php" and i add use Orchid\Fortify\TwoFactorScreenAuthenticatable; and change the following functions:

     * Button commands.
     *
     * @return Action[]
     */
    public function commandBar(): iterable
    {
	    return [
	        $this->twoFactorCommandBar(),
	    ];
    }

    /**
     * @return \Orchid\Screen\Layout[]
     */
    public function layout(): iterable
    {
        return [
            $this->twoFactorLayout(),
            
            Layout::block(UserEditLayout::class)
                ->title(__('Profile Information'))
                ->description(__("Update your account's profile information and email address."))
                ->commands(
                    Button::make(__('Save'))
                        ->type(Color::DEFAULT())
                        ->icon('check')
                        ->method('save')
                ),

            Layout::block(ProfilePasswordLayout::class)
                ->title(__('Update Password'))
                ->description(__('Ensure your account is using a long, random password to stay secure.'))
                ->commands(
                    Button::make(__('Update password'))
                        ->type(Color::DEFAULT())
                        ->icon('check')
                        ->method('changePassword')
                ),
        ];
    }`

After that the following error is shown:

BadMethodCallException
Method App\Orchid\Screens\User\UserProfileScreen::twoFactorCommandBar does not exist.

Do you have an idea?

from fortify.

kaizirlewagen avatar kaizirlewagen commented on May 26, 2024

@czernika Amazing... thank you very much... i will try it today. 👍

from fortify.

kaizirlewagen avatar kaizirlewagen commented on May 26, 2024

@czernika Works perfect. Thx for your help 👍

from fortify.

darkol avatar darkol commented on May 26, 2024

I guess this should be added to README.md

I have followed the procedure above, filling some more information:

  1. Install Laravel Fortify package
composer require laravel/fortify
  1. Publish its resources
php artisan vendor:publish --provider="Laravel\Fortify\FortifyServiceProvider"
  1. Run migrations to add two_fa columns
php artisan migrate
  1. Add FortifyServiceProvider into providers array within config/app.php

Add App\Providers\FortifyServiceProvider::class to providers

    'providers' => ServiceProvider::defaultProviders()->merge([
        /*
         * Package Service Providers...
         */

        /*
         * Application Service Providers...
         */
        App\Providers\AppServiceProvider::class,
        App\Providers\AuthServiceProvider::class,
        // App\Providers\BroadcastServiceProvider::class,
        App\Providers\EventServiceProvider::class,
        App\Providers\RouteServiceProvider::class,
        App\Providers\FortifyServiceProvider::class,
    ])->toArray(),
  1. Add TwoFactorAuthenticatable trait to User model app\Models\User.php
use Laravel\Fortify\TwoFactorAuthenticatable;

class User extends Authenticatable
{
    use TwoFactorAuthenticatable;
}
  1. Install Orchid Fortify
composer require orchid/fortify
  1. Set to false the auth key of config/platform.php

  2. Within required Screen - for example UserProfileScreen (app\Orchid\Screens\User\UserProfileScreen.php) add following lines

use Orchid\Screen\Screen;
use Orchid\Fortify\TwoFactorScreenAuthenticatable;

class UserProfileScreen extends Screen
{
	use TwoFactorScreenAuthenticatable; // I guess this is where you've been stacked

    public function commandBar(): iterable
    {
        return [
		$this->twoFactorCommandBar(), // dropdown button
	];
    }

    public function layout(): iterable
    {
        return [
		// other layouts
		
		$this->twoFactorLayout(), // modal and methods
        ];
    }
}
  1. Almost done, BUT it is still needs extra actions to be done to work

Fortify provides some options - one of them is to confirm Two FA or not. You may find this within config/fortify.php

'features' => [
    Features::twoFactorAuthentication([
        'confirm' => true, // confirm Two FA
        'confirmPassword' => true, // confirm password to enable Two FA
    ]),
],

confirm key requires to you to confirm TwoFA. If TwoFA keys was not confirmed you still be able to login without TwoFA.

Or you may just disable it ('confirm' => false) if you're ok with no confirmation - it is will work

You may achieve this as you wish, I will show "my way"

Create Layout for confirmation code in new file app\Orchid\Screens\User\ProfileTwoFALayout.php

<?php

declare(strict_types=1);

namespace App\Orchid\Screens\User;

use Orchid\Screen\Field;
use Orchid\Screen\Fields\Input;
use Orchid\Screen\Layouts\Rows;

class ProfileTwoFALayout extends Rows
{
    protected function fields(): iterable
    {
        return [
			Input::make('code'), // key should be named `code`. That's basically required minimum
		];
    }
}

Add Layout to your Screen in app\Orchid\Screens\User\UserProfileScreen.php

class UserProfileScreen extends Screen
{
use TwoFactorScreenAuthenticatable; // I guess this is where you've been stacked

    public function commandBar(): iterable
    {
        return [
		$this->twoFactorCommandBar(), // dropdown button
	];
    }

    public function layout(): iterable
    {
        return [
            Layout::block(ProfileTwoFALayout::class)
                ->title(__('Confirm Two FA'))
		->canSee(
                    auth()->user()->two_factor_secret && // show if authorized user has enabled Two FA
                    !auth()->user()->two_factor_confirmed_at // but still doesn't confirmed it
                )
                ->commands(
                    Button::make(__('Confirm'))
                        ->type(Color::PRIMARY())
                        ->icon('check')
                        ->action(route('two-factor.confirm')) // this route provided by Fortify and should not be changed
                ),

		// other layouts

		$this->twoFactorLayout(), // modal and methods
        ];
    }
}

As you can see I implemented canSee() method to show this layout by specific condition.
As I am using it only for user profile screen, I can use auth()->user() with no fear. You app may require other logic to handle

After hitting confirm you will be redirect back, and in your database you will see all three columns two_factor_secret, two_factor_recovery_code and two_factor_confirmed_at filled with information.

PROBLEM: OK, I can add 2FA to the user that has at least main privilege to access admin panel to reach his User Profile Screen and I can see all three fields in the database populated, and confirm button is no longer visible in User Profile Screen, but I am not asked for 2FA on login?! What am I missing?

from fortify.

Related Issues (8)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.