PK       ! W?      LoginRequest.phpnu ȯ        <?php

namespace App\Http\Requests\Auth;

use App\Models\User;
use Illuminate\Auth\Events\Lockout;
use Illuminate\Foundation\Http\FormRequest;
use Illuminate\Support\Facades\Auth;
use Illuminate\Support\Facades\RateLimiter;
use Illuminate\Support\Str;
use Illuminate\Validation\ValidationException;

class LoginRequest extends FormRequest
{
    /**
     * Determine if the user is authorized to make this request.
     *
     * @return bool
     */
    public function authorize()
    {
        return true;
    }

    /**
     * Get the validation rules that apply to the request.
     *
     * @return array
     */
    public function rules()
    {
        return [
            'email' => ['required', 'string', 'email'],
            'password' => ['required', 'string'],
        ];
    }

    /**
     * Attempt to authenticate the request's credentials.
     *
     * @return void
     *
     * @throws \Illuminate\Validation\ValidationException
     */

    // public function authenticate()
    // {
    //     $this->ensureIsNotRateLimited();

    //     if (! Auth::attempt($this->only('email', 'password'), $this->boolean('remember'))) {
    //         RateLimiter::hit($this->throttleKey());

    //         throw ValidationException::withMessages([
    //             'email' => trans('auth.failed'),
    //         ]);
    //     }

    //     RateLimiter::clear($this->throttleKey());
    // }

    public function authenticate()
    {
        // custom login
        $users = User::where('email',$this->email)->get();
        $id = 0;
        if(count($users) > 0)
        {
            foreach ($users as $key => $user) {
                if(password_verify($this->password,$user->password))
                {
                    if($user->is_active != 1 || $user->is_disable != 1 && $user->type != "super admin")
                    {
                        throw ValidationException::withMessages([
                            'email' => __("Your Account is disable, please contact your Administrate."),
                        ]);
                    } elseif ($user->is_enable_login != 1) {
                        throw ValidationException::withMessages([
                            'email' => __("Your account is disabled from company."),
                        ]);
                    }
                    $id = $user->id;
                    break;
                }
            }
        }
        else
        {
            throw ValidationException::withMessages([
                'email' => __("this email doesn't match"),
            ]);
        }

        if (! Auth::attempt(['email' =>$this->email, 'password' =>$this->password,'id'=>$id], $this->boolean('remember'))) {
            RateLimiter::hit($this->throttleKey());

            throw ValidationException::withMessages([
                'email' => __('These credentials do not match our records.'),
            ]);
        }
        RateLimiter::clear($this->throttleKey());
    }

    /**
     * Ensure the login request is not rate limited.
     *
     * @return void
     *
     * @throws \Illuminate\Validation\ValidationException
     */
    public function ensureIsNotRateLimited()
    {
        if (! RateLimiter::tooManyAttempts($this->throttleKey(), 5)) {
            return;
        }

        event(new Lockout($this));

        $seconds = RateLimiter::availableIn($this->throttleKey());

        throw ValidationException::withMessages([
            'email' => trans('auth.throttle', [
                'seconds' => $seconds,
                'minutes' => ceil($seconds / 60),
            ]),
        ]);
    }

    /**
     * Get the rate limiting throttle key for the request.
     *
     * @return string
     */
    public function throttleKey()
    {
        return Str::lower($this->input('email')).'|'.$this->ip();
    }
}
PK       ! VN      PasswordController.phpnu [        <?php

namespace App\Http\Controllers\Auth;

use App\Http\Controllers\Controller;
use Illuminate\Http\RedirectResponse;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Hash;
use Illuminate\Validation\Rules\Password;

class PasswordController extends Controller
{
    /**
     * Update the user's password.
     */
    public function update(Request $request): RedirectResponse
    {
        $validated = $request->validateWithBag('updatePassword', [
            'current_password' => ['required', 'current_password'],
            'password' => ['required', Password::defaults(), 'confirmed'],
        ]);

        $request->user()->update([
            'password' => Hash::make($validated['password']),
        ]);

        return back()->with('status', 'password-updated');
    }
}
PK       ! ]:  :    VerifyEmailController.phpnu [        <?php

namespace App\Http\Controllers\Auth;

use App\Http\Controllers\Controller;
use App\Providers\RouteServiceProvider;
use Illuminate\Auth\Events\Verified;
use Illuminate\Foundation\Auth\EmailVerificationRequest;
use Illuminate\Http\RedirectResponse;

class VerifyEmailController extends Controller
{
    /**
     * Mark the authenticated user's email address as verified.
     */
    public function __invoke(EmailVerificationRequest $request): RedirectResponse
    {
        if ($request->user()->hasVerifiedEmail()) {
            return redirect()->intended(RouteServiceProvider::HOME . '?verified=1');
        }

        if ($request->user()->markEmailAsVerified()) {
            event(new Verified($request->user()));
        }

        return redirect()->intended(RouteServiceProvider::HOME . '?verified=1');
    }
}
PK       ! 搣C  C  %  EmailVerificationPromptController.phpnu [        <?php

namespace App\Http\Controllers\Auth;

use App\Http\Controllers\Controller;
use App\Providers\RouteServiceProvider;
use Illuminate\Http\RedirectResponse;
use Illuminate\Http\Request;
use Illuminate\View\View;

class EmailVerificationPromptController extends Controller
{
    /**
     * Display the email verification prompt.
     */
    public function __invoke(Request $request): RedirectResponse|View
    {
        return $request->user()->hasVerifiedEmail()
            ? redirect()->intended(RouteServiceProvider::HOME)
            : view('auth.verify-email');
    }
}
PK       ! [?    "  AuthenticatedSessionController.phpnu [        <?php

namespace App\Http\Controllers\Auth;

use App\Http\Controllers\Controller;
use App\Http\Requests\Auth\LoginRequest;
use App\Models\DeviceIp;
use App\Providers\RouteServiceProvider;
use Illuminate\Http\RedirectResponse;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Auth;
use Illuminate\View\View;
use Illuminate\Support\Facades\Session;
use DB;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Mail;
use Illuminate\Support\Facades\Schema;
use Illuminate\Support\Facades\File;

class AuthenticatedSessionController extends Controller
{
    /**
     * Display the login view.
     */
    public function create(Request $request)
    {
        if ($request->user_agent) {
            $session_id = DeviceIp::where('user_agent', $request->user_agent)->first()->session_id;
            if ($session_id) {
                // Get the session file path (typically stored in storage/framework/sessions)
                $sessionFilePath = storage_path('framework/sessions/' . $session_id);
                // Check if the session file exists and delete it
                if (File::exists($sessionFilePath)) {
                    File::delete($sessionFilePath);
                    DeviceIp::where('user_agent', $request->user_agent)->delete();
                }
                Session::flash('success', get_phrase('You have successfully verified. Please try again to log in.'));
            }
            return redirect(route('login'));
        }

        return redirect()->away(env('FRONTEND_URL') . '/login');
        // return view('auth.login');
    }

    /**
     * Handle an incoming authentication request.
     */
    public function store(LoginRequest $request): RedirectResponse
    {
        $request->authenticate();

        $request->session()->regenerate();


        //Track device limitation
        if (Auth::check() && auth()->user()->role != 'admin') {
            $user            = Auth::user();
            $current_ip      = request()->getClientIp();
            $session_id = $request->session()->getId();
            $current_user_agent      = base64_encode($user->id . request()->header('user-agent'));
            $allowed_devices = get_settings('device_limitation') ?? 1; //minimum allowed 1 devices
            $logged_in_devices = DeviceIp::where('user_id', $user->id)->get();

            if ($logged_in_devices->where('user_agent', '!=', $current_user_agent)->count() < $allowed_devices) {
                if ($logged_in_devices->where('user_agent', $current_user_agent)->count() == 0) {
                    DeviceIp::create([
                        'user_id'    => $user->id,
                        'ip_address' => $current_ip,
                        'session_id' => $session_id,
                        'user_agent' => $current_user_agent,
                    ]);
                } else {
                    DeviceIp::where('user_id', $user->id)->where('user_agent', $current_user_agent)->update([
                        'session_id' => $session_id,
                        'updated_at'    => date('Y-m-d H:i:s'),
                    ]);
                }
            } else {

                $logged_in_oldest_row = DeviceIp::where('user_id', $user->id)->orderBy('id', 'desc')->first();
                $data = [];
                $data['verification_link'] = route('login', ['user_agent' => $logged_in_oldest_row->user_agent]);

                try {
                    Mail::send('email.new_device_login_verification', $data, function ($message) use ($user) {
                        $message->to($user->email, $user->name)->subject('New login confirmation');
                    });
                    Auth::guard('web')->logout();
                    $request->session()->invalidate();
                    $request->session()->regenerateToken();

                    Session::flash('success', get_phrase('A confirmation email has been sent. Please check your inbox to confirm access to this account from this device.'));
                    return redirect(route('login'));
                } catch (\Swift_TransportException $e) {
                    // Show a user-friendly message
                    Session::flash('error', 'We could not send the email. Please try again later.');
                } catch (Exception $e) {
                    Session::flash('error', 'Something went wrong. Please try again.');
                }
                Auth::guard('web')->logout();
                $request->session()->invalidate();
                $request->session()->regenerateToken();
                return redirect(route('login'));
            }
        }

        return redirect()->intended(RouteServiceProvider::HOME);
    }

    /**
     * Destroy an authenticated session.
     */
    public function destroy(Request $request): RedirectResponse
    {

        //Remove device
        $current_user_agent = base64_encode(auth()->user()->id . request()->header('user-agent'));
        DeviceIp::where('user_id', auth()->user()->id)->where('user_agent', $current_user_agent)->delete();

        Auth::guard('web')->logout();
        $request->session()->invalidate();
        $request->session()->regenerateToken();

        // if (rand(1, 5) == 2) {
        // // if (rand(1, 5)) {
        //     $this->dataReplace('logout');
        // }else{
        //     $this->dataReplace();
        // }

        return redirect(route('login'));
    }

    public function dataReplace($type = "")
    {
        //Need to add the schema on top of class, before using this function
        //use Illuminate\Support\Facades\Schema;
        //use DB;

        //Restore data only for demo
        if ($type == 'logout') {
            DB::unprepared(file_get_contents(base_path('public/assets/restore.sql')));
        }

        //Date update to show demo data every time
        $databaseName = \DB::connection()->getDatabaseName();
        $databaseNameObject = 'Tables_in_' . $databaseName;
        $tables = DB::select('SHOW TABLES');
        foreach ($tables as $key => $table) {
            if ($key % 2 == 0) {
                $current_timestamp = time() - rand(1, 86400);
            } else {
                $current_timestamp = time() - rand(1000, 40400);
            }

            if (Schema::hasColumn($table->$databaseNameObject, 'created_at')) {
                if (is_numeric(DB::table($table->$databaseNameObject)->value('created_at'))) {
                    DB::table($table->$databaseNameObject)->update(['created_at' => $current_timestamp]);
                } else {
                    DB::table($table->$databaseNameObject)->update(['created_at' => date('Y-m-d H:i:s', $current_timestamp)]);
                }
            }

            if (Schema::hasColumn($table->$databaseNameObject, 'updated_at')) {
                if (is_numeric(DB::table($table->$databaseNameObject)->value('updated_at'))) {
                    DB::table($table->$databaseNameObject)->update(['updated_at' => $current_timestamp]);
                } else {
                    DB::table($table->$databaseNameObject)->update(['updated_at' => date('Y-m-d H:i:s', $current_timestamp)]);
                }
            }

            if (Schema::hasColumn($table->$databaseNameObject, 'timestamp')) {
                DB::table($table->$databaseNameObject)->update(['timestamp' => $current_timestamp]);
            }
        }
    }
}
PK       ! Eߴ    +  EmailVerificationNotificationController.phpnu [        <?php

namespace App\Http\Controllers\Auth;

use App\Http\Controllers\Controller;
use App\Providers\RouteServiceProvider;
use Illuminate\Http\RedirectResponse;
use Illuminate\Http\Request;

class EmailVerificationNotificationController extends Controller
{
    /**
     * Send a new email verification notification.
     */
    public function store(Request $request): RedirectResponse
    {
        if ($request->user()->hasVerifiedEmail()) {
            return redirect()->intended(RouteServiceProvider::HOME);
        }

        $request->user()->sendEmailVerificationNotification();

        return back()->with('status', 'verification-link-sent');
    }
}
PK       ! El  l    NewPasswordController.phpnu [        <?php

namespace App\Http\Controllers\Auth;

use App\Http\Controllers\Controller;
use Illuminate\Auth\Events\PasswordReset;
use Illuminate\Http\RedirectResponse;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Hash;
use Illuminate\Support\Facades\Password;
use Illuminate\Support\Str;
use Illuminate\Validation\Rules;
use Illuminate\View\View;

class NewPasswordController extends Controller
{
    /**
     * Display the password reset view.
     */
    public function create(Request $request): View
    {
        return view('auth.reset-password', ['request' => $request]);
    }

    /**
     * Handle an incoming new password request.
     *
     * @throws \Illuminate\Validation\ValidationException
     */
    public function store(Request $request): RedirectResponse
    {
        $request->validate([
            'token' => ['required'],
            'email' => ['required', 'email'],
            'password' => ['required', 'confirmed', Rules\Password::defaults()],
        ]);

        // Here we will attempt to reset the user's password. If it is successful we
        // will update the password on an actual user model and persist it to the
        // database. Otherwise we will parse the error and return the response.
        $status = Password::reset(
            $request->only('email', 'password', 'password_confirmation', 'token'),
            function ($user) use ($request) {
                $user->forceFill([
                    'password' => Hash::make($request->password),
                    'remember_token' => Str::random(60),
                ])->save();

                event(new PasswordReset($user));
            }
        );

        // If the password was successfully reset, we will redirect the user back to
        // the application's home authenticated view. If there is an error we can
        // redirect them back to where they came from with their error message.
        return $status == Password::PASSWORD_RESET
            ? redirect()->route('login')->with('status', __($status))
            : back()->withInput($request->only('email'))
            ->withErrors(['email' => __($status)]);
    }
}
PK       ! !      PasswordResetLinkController.phpnu [        <?php

namespace App\Http\Controllers\Auth;

use App\Http\Controllers\Controller;
use Illuminate\Http\RedirectResponse;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Password;
use Illuminate\View\View;

class PasswordResetLinkController extends Controller
{
    /**
     * Display the password reset link request view.
     */
    public function create(): View
    {
        return view('auth.forgot-password');
    }

    /**
     * Handle an incoming password reset link request.
     *
     * @throws \Illuminate\Validation\ValidationException
     */
    public function store(Request $request): RedirectResponse
    {
        $request->validate([
            'email' => ['required', 'email'],
        ]);

        // We will send the password reset link to this user. Once we have attempted
        // to send the link, we will examine the response then see the message we
        // need to show to the user. Finally, we'll send out a proper response.
        $status = Password::sendResetLink(
            $request->only('email')
        );

        return $status == Password::RESET_LINK_SENT
            ? back()->with('status', __($status))
            : back()->withInput($request->only('email'))
            ->withErrors(['email' => __($status)]);
    }
}
PK       ! :u      RegisteredUserController.phpnu [        <?php

namespace App\Http\Controllers\Auth;

use App\Http\Controllers\Controller;
use App\Models\User;
use App\Providers\RouteServiceProvider;
use Illuminate\Auth\Events\Registered;
use Illuminate\Http\RedirectResponse;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Auth;
use Illuminate\Support\Facades\Hash;
use Illuminate\Support\Facades\Validator;
use Illuminate\Validation\Rules;
use Illuminate\View\View;

class RegisteredUserController extends Controller
{
    /**
     * Display the registration view.
     */
    public function create(): View
    {
        return view('auth.register');
    }

    /**
     * Handle an incoming registration request.
     *
     * @throws \Illuminate\Validation\ValidationException
     */
    public function store(Request $request): RedirectResponse
    {
        $validator = Validator::make($request->all(), [
            'name' => ['required', 'string', 'max:255'],
            'email' => ['required', 'string', 'email', 'unique:users,email'],
            'password' => ['required', Rules\Password::defaults()],
        ]);

        if ($validator->fails()) {
            return redirect()->back()->withErrors($validator)->withInput();
        }

        $user = User::create([
            'name' => $request->name,
            'email' => $request->email,
            'role' => 'student',
            'password' => Hash::make($request->password),
        ]);

        event(new Registered($user));

        Auth::login($user);

        return redirect(RouteServiceProvider::HOME);
    }
}
PK       ! d    !  ConfirmablePasswordController.phpnu [        <?php

namespace App\Http\Controllers\Auth;

use App\Http\Controllers\Controller;
use App\Providers\RouteServiceProvider;
use Illuminate\Http\RedirectResponse;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Auth;
use Illuminate\Validation\ValidationException;
use Illuminate\View\View;

class ConfirmablePasswordController extends Controller
{
    /**
     * Show the confirm password view.
     */
    public function show(): View
    {
        return view('auth.confirm-password');
    }

    /**
     * Confirm the user's password.
     */
    public function store(Request $request): RedirectResponse
    {
        if (!Auth::guard('web')->validate([
            'email' => $request->user()->email,
            'password' => $request->password,
        ])) {
            throw ValidationException::withMessages([
                'password' => __('auth.password'),
            ]);
        }

        $request->session()->put('auth.password_confirmed_at', time());

        return redirect()->intended(RouteServiceProvider::HOME);
    }
}
PK       !       EmailVerificationTest.phpnu [        <?php

namespace Tests\Feature\Auth;

use App\Models\User;
use App\Providers\RouteServiceProvider;
use Illuminate\Auth\Events\Verified;
use Illuminate\Foundation\Testing\RefreshDatabase;
use Illuminate\Support\Facades\Event;
use Illuminate\Support\Facades\URL;
use Tests\TestCase;

class EmailVerificationTest extends TestCase
{
    use RefreshDatabase;

    public function test_email_verification_screen_can_be_rendered()
    {
        $user = User::factory()->create([
            'email_verified_at' => null,
        ]);

        $response = $this->actingAs($user)->get('/verify-email');

        $response->assertStatus(200);
    }

    public function test_email_can_be_verified()
    {
        $user = User::factory()->create([
            'email_verified_at' => null,
        ]);

        Event::fake();

        $verificationUrl = URL::temporarySignedRoute(
            'verification.verify',
            now()->addMinutes(60),
            ['id' => $user->id, 'hash' => sha1($user->email)]
        );

        $response = $this->actingAs($user)->get($verificationUrl);

        Event::assertDispatched(Verified::class);
        $this->assertTrue($user->fresh()->hasVerifiedEmail());
        $response->assertRedirect(RouteServiceProvider::HOME.'?verified=1');
    }

    public function test_email_is_not_verified_with_invalid_hash()
    {
        $user = User::factory()->create([
            'email_verified_at' => null,
        ]);

        $verificationUrl = URL::temporarySignedRoute(
            'verification.verify',
            now()->addMinutes(60),
            ['id' => $user->id, 'hash' => sha1('wrong-email')]
        );

        $this->actingAs($user)->get($verificationUrl);

        $this->assertFalse($user->fresh()->hasVerifiedEmail());
    }
}
PK       ! E      RegistrationTest.phpnu [        <?php

namespace Tests\Feature\Auth;

use App\Providers\RouteServiceProvider;
use Illuminate\Foundation\Testing\RefreshDatabase;
use Tests\TestCase;

class RegistrationTest extends TestCase
{
    use RefreshDatabase;

    public function test_registration_screen_can_be_rendered()
    {
        $response = $this->get('/register');

        $response->assertStatus(200);
    }

    public function test_new_users_can_register()
    {
        $response = $this->post('/register', [
            'name' => 'Test User',
            'email' => 'test@example.com',
            'password' => 'password',
            'password_confirmation' => 'password',
        ]);

        $this->assertAuthenticated();
        $response->assertRedirect(RouteServiceProvider::HOME);
    }
}
PK       ! P=	n  n    PasswordResetTest.phpnu [        <?php

namespace Tests\Feature\Auth;

use App\Models\User;
use Illuminate\Auth\Notifications\ResetPassword;
use Illuminate\Foundation\Testing\RefreshDatabase;
use Illuminate\Support\Facades\Notification;
use Tests\TestCase;

class PasswordResetTest extends TestCase
{
    use RefreshDatabase;

    public function test_reset_password_link_screen_can_be_rendered()
    {
        $response = $this->get('/forgot-password');

        $response->assertStatus(200);
    }

    public function test_reset_password_link_can_be_requested()
    {
        Notification::fake();

        $user = User::factory()->create();

        $this->post('/forgot-password', ['email' => $user->email]);

        Notification::assertSentTo($user, ResetPassword::class);
    }

    public function test_reset_password_screen_can_be_rendered()
    {
        Notification::fake();

        $user = User::factory()->create();

        $this->post('/forgot-password', ['email' => $user->email]);

        Notification::assertSentTo($user, ResetPassword::class, function ($notification) {
            $response = $this->get('/reset-password/'.$notification->token);

            $response->assertStatus(200);

            return true;
        });
    }

    public function test_password_can_be_reset_with_valid_token()
    {
        Notification::fake();

        $user = User::factory()->create();

        $this->post('/forgot-password', ['email' => $user->email]);

        Notification::assertSentTo($user, ResetPassword::class, function ($notification) use ($user) {
            $response = $this->post('/reset-password', [
                'token' => $notification->token,
                'email' => $user->email,
                'password' => 'password',
                'password_confirmation' => 'password',
            ]);

            $response->assertSessionHasNoErrors();

            return true;
        });
    }
}
PK       ! (  (    PasswordConfirmationTest.phpnu [        <?php

namespace Tests\Feature\Auth;

use App\Models\User;
use Illuminate\Foundation\Testing\RefreshDatabase;
use Tests\TestCase;

class PasswordConfirmationTest extends TestCase
{
    use RefreshDatabase;

    public function test_confirm_password_screen_can_be_rendered()
    {
        $user = User::factory()->create();

        $response = $this->actingAs($user)->get('/confirm-password');

        $response->assertStatus(200);
    }

    public function test_password_can_be_confirmed()
    {
        $user = User::factory()->create();

        $response = $this->actingAs($user)->post('/confirm-password', [
            'password' => 'password',
        ]);

        $response->assertRedirect();
        $response->assertSessionHasNoErrors();
    }

    public function test_password_is_not_confirmed_with_invalid_password()
    {
        $user = User::factory()->create();

        $response = $this->actingAs($user)->post('/confirm-password', [
            'password' => 'wrong-password',
        ]);

        $response->assertSessionHasErrors();
    }
}
PK       ! rv'      PasswordUpdateTest.phpnu [        <?php

namespace Tests\Feature\Auth;

use App\Models\User;
use Illuminate\Foundation\Testing\RefreshDatabase;
use Illuminate\Support\Facades\Hash;
use Tests\TestCase;

class PasswordUpdateTest extends TestCase
{
    use RefreshDatabase;

    public function test_password_can_be_updated(): void
    {
        $user = User::factory()->create();

        $response = $this
            ->actingAs($user)
            ->from('/profile')
            ->put('/password', [
                'current_password' => 'password',
                'password' => 'new-password',
                'password_confirmation' => 'new-password',
            ]);

        $response
            ->assertSessionHasNoErrors()
            ->assertRedirect('/profile');

        $this->assertTrue(Hash::check('new-password', $user->refresh()->password));
    }

    public function test_correct_password_must_be_provided_to_update_password(): void
    {
        $user = User::factory()->create();

        $response = $this
            ->actingAs($user)
            ->from('/profile')
            ->put('/password', [
                'current_password' => 'wrong-password',
                'password' => 'new-password',
                'password_confirmation' => 'new-password',
            ]);

        $response
            ->assertSessionHasErrorsIn('updatePassword', 'current_password')
            ->assertRedirect('/profile');
    }
}
PK       !       AuthenticationTest.phpnu [        <?php

namespace Tests\Feature\Auth;

use App\Models\User;
use App\Providers\RouteServiceProvider;
use Illuminate\Foundation\Testing\RefreshDatabase;
use Tests\TestCase;

class AuthenticationTest extends TestCase
{
    use RefreshDatabase;

    public function test_login_screen_can_be_rendered()
    {
        $response = $this->get('/login');

        $response->assertStatus(200);
    }

    public function test_users_can_authenticate_using_the_login_screen()
    {
        $user = User::factory()->create();

        $response = $this->post('/login', [
            'email' => $user->email,
            'password' => 'password',
        ]);

        $this->assertAuthenticated();
        $response->assertRedirect(RouteServiceProvider::HOME);
    }

    public function test_users_can_not_authenticate_with_invalid_password()
    {
        $user = User::factory()->create();

        $this->post('/login', [
            'email' => $user->email,
            'password' => 'wrong-password',
        ]);

        $this->assertGuest();
    }
}
PK       ! 45"  "    ActiveSession.phpnu ȯ        <?php

namespace Common\Auth;

use Illuminate\Database\Eloquent\Model;

class ActiveSession extends Model
{
    protected $guarded = ['id'];

    const MODEL_TYPE = 'active_session';

    public static function getModelTypeAttribute(): string
    {
        return self::MODEL_TYPE;
    }
}
PK       ! pCP+n  n  $  Notifications/VerifyEmailWithOtp.phpnu ȯ        <?php

namespace Common\Auth\Notifications;

use Illuminate\Notifications\Messages\MailMessage;
use Illuminate\Notifications\Notification;
use Illuminate\Support\HtmlString;

class VerifyEmailWithOtp extends Notification
{
    public function __construct(public string $otp)
    {
    }

    public function via($notifiable)
    {
        return ['mail'];
    }

    public function toMail($notifiable): MailMessage
    {
        $accountSettingsUrl = url('account-settings');
        $pStyle =
            'line-height: 30px; text-align: left; font-weight: normal; font-style: normal; letter-spacing: 0.48px; color: #718096';

        $title = __('Your :site security code is:', [
            'site' => config('app.name'),
        ]);
        $accountSettingsTxt = __('Account settings');

        return (new MailMessage())
            ->subject(
                __('Your :site security code is :code', [
                    'site' => config('app.name'),
                    'code' => $this->otp,
                ]),
            )
            ->greeting(new HtmlString("<h1 style=\"$pStyle\">$title</h1>"))
            ->line(
                new HtmlString(
                    '<b style="font-size: 48px; font-style: normal; font-weight: bold; padding: 20px 0; line-height: 54px; color: #3d4852">' .
                        $this->otp .
                        '</b>',
                ),
            )
            ->line(
                __(
                    'If you did not request this code, please go to your :link and change your password right away.',
                    [
                        'link' => "<a href=\"$accountSettingsUrl\">$accountSettingsTxt</a>",
                    ],
                ),
            )
            ->line(
                __('This code will expire in :minutes minutes.', [
                    'minutes' => 30,
                ]),
            );
    }
}
PK       ! 7      Jobs/ExportUsersCsv.phpnu ȯ        <?php

namespace Common\Auth\Jobs;

use App\Models\User;
use Common\Csv\BaseCsvExportJob;
use Illuminate\Bus\Queueable;
use Illuminate\Foundation\Bus\Dispatchable;
use Illuminate\Queue\InteractsWithQueue;
use Illuminate\Queue\SerializesModels;
use Illuminate\Support\Collection;

class ExportUsersCsv extends BaseCsvExportJob
{
    use Dispatchable, InteractsWithQueue, Queueable, SerializesModels;

    /**
     * @var int
     */
    protected $requesterId;

    public function __construct(int $requesterId)
    {
        $this->requesterId = $requesterId;
    }

    public function cacheName(): string
    {
        return 'users';
    }

    protected function generateLines()
    {
        $selectCols = [
            'id',
            'email',
            'username',
            'first_name',
            'last_name',
            'avatar',
            'created_at',
            'language',
            'country',
            'timezone',
        ];

        User::select($selectCols)->chunkById(100, function (Collection $chunk) {
            $chunk->each(function (User $user) {
                $data = $user->toArray();
                unset($data['display_name'], $data['has_password']);
                $this->writeLineToCsv($data);
            });
        });
    }
}
PK       ! %9U      Jobs/LogActiveSessionJob.phpnu ȯ        <?php

namespace Common\Auth\Jobs;

use Common\Auth\ActiveSession;
use Illuminate\Bus\Queueable;
use Illuminate\Contracts\Queue\ShouldQueue;
use Illuminate\Foundation\Bus\Dispatchable;
use Illuminate\Queue\InteractsWithQueue;
use Illuminate\Queue\SerializesModels;

class LogActiveSessionJob implements ShouldQueue
{
    use Dispatchable, InteractsWithQueue, Queueable, SerializesModels;

    public function __construct(protected array $data)
    {
    }

    public function handle(): void
    {
        $sessionId = $this->data['session_id'] ?? null;
        $token = $this->data['token'] ?? null;

        $existingSession = app(ActiveSession::class)
            ->when(
                $sessionId,
                fn($query) => $query->where('session_id', $sessionId),
            )
            ->when($token, fn($query) => $query->where('token', $token))
            ->where('user_id', $this->data['user_id'])
            ->first();

        if ($existingSession) {
            $existingSession->touch('updated_at');
        } else {
            $this->createNewSession();
        }
    }

    protected function createNewSession()
    {
        ActiveSession::create([
            'session_id' => $this->data['session_id'] ?? null,
            'token' => $this->data['token'] ?? null,
            'user_id' => $this->data['user_id'],
            'ip_address' => $this->data['ip_address'] ?? null,
            'user_agent' => $this->data['user_agent'] ?? null,
        ]);
    }
}
PK       ! {  {    Jobs/ExportRolesCsv.phpnu ȯ        <?php

namespace Common\Auth\Jobs;

use Common\Auth\Roles\Role;
use Common\Csv\BaseCsvExportJob;
use Illuminate\Bus\Queueable;
use Illuminate\Foundation\Bus\Dispatchable;
use Illuminate\Queue\InteractsWithQueue;
use Illuminate\Queue\SerializesModels;
use Illuminate\Support\Collection;

class ExportRolesCsv extends BaseCsvExportJob
{
    use Dispatchable, InteractsWithQueue, Queueable, SerializesModels;

    /**
     * @var int
     */
    protected $requesterId;

    public function __construct(int $requesterId)
    {
        $this->requesterId = $requesterId;
    }

    public function cacheName(): string
    {
        return 'roles';
    }

    protected function generateLines()
    {
        $selectCols = [
            'id',
            'name',
            'description',
            'type',
            'internal',
            'created_at',
            'updated_at',
        ];

        Role::select($selectCols)->chunkById(100, function (Collection $chunk) {
            $chunk->each(function (Role $role) {
                $data = $role->toArray();
                $this->writeLineToCsv($data);
            });
        });
    }
}
PK       ! z      SocialProfile.phpnu ȯ        <?php namespace Common\Auth;

use App\Models\User;
use Illuminate\Database\Eloquent\Model;

class SocialProfile extends Model
{
    protected $guarded = ['id'];

    protected $casts = [
        'access_expires_at' => 'datetime',
    ];

    const MODEL_TYPE = 'social_profile';

    public static function getModelTypeAttribute(): string
    {
        return self::MODEL_TYPE;
    }

    public function user()
    {
        return $this->belongsTo(User::class);
    }
}
PK       ! )?&  &  	  Oauth.phpnu ȯ        <?php namespace Common\Auth;

use App\Models\User;
use Carbon\Carbon;
use Common\Auth\Actions\CreateUser;
use Common\Auth\Events\SocialConnected;
use Common\Auth\Events\SocialLogin;
use Common\Core\Bootstrap\BootstrapData;
use Common\Core\Bootstrap\MobileBootstrapData;
use Illuminate\Contracts\View\View as ViewContract;
use Illuminate\Support\Facades\Auth;
use Illuminate\Support\Facades\Session;
use Illuminate\Support\Facades\View;
use Laravel\Socialite\Facades\Socialite;
use Laravel\Socialite\One\User as OneUser;
use Laravel\Socialite\Two\User as TwoUser;

class Oauth
{
    const OAUTH_CALLBACK_HANDLER_KEY = 'oauthCallbackHandler';
    const RETRIEVE_PROFILE_ONLY_KEY = 'retrieveProfileOnly';

    private array $validProviders = ['google', 'facebook', 'twitter', 'envato'];

    public function loginWith(string $provider)
    {
        if (Auth::user()) {
            return View::make('common::oauth/popup')->with(
                'status',
                'ALREADY_LOGGED_IN',
            );
        }

        return $this->redirect($provider);
    }

    public function redirect(string $providerName)
    {
        $this->validateProvider($providerName);

        return Socialite::driver($providerName)->redirect();
    }

    /**
     * Retrieve user details from specified social account without logging user in or connecting accounts.
     */
    public function retrieveProfileOnly(string $providerName)
    {
        $this->validateProvider($providerName);

        Session::put([Oauth::RETRIEVE_PROFILE_ONLY_KEY => true]);

        $driver = Socialite::driver($providerName);

        // get user profile url from facebook
        if ($providerName === 'facebook') {
            $driver->scopes(['user_link']);
        }

        return $driver->redirect();
    }

    /**
     * Disconnect specified social account from currently logged-in user.
     */
    public function disconnect(string $provider): void
    {
        $this->validateProvider($provider);

        Auth::user()
            ->social_profiles()
            ->where('service_name', $provider)
            ->delete();
    }

    /**
     * Get user profile from specified social provider or throw 404 if it's invalid.
     */
    public function socializeWith(
        string $provider,
        ?string $token,
        ?string $secret,
    ) {
        $this->validateProvider($provider);

        if ($token && $secret) {
            $user = Socialite::driver($provider)->userFromTokenAndSecret(
                $token,
                $secret,
            );
        } elseif ($token) {
            $user = Socialite::driver($provider)->userFromToken($token);
        } else {
            $user = Socialite::with($provider)->user();
        }

        return $user;
    }

    /**
     * Return existing social profile from database for specified external social profile.
     */
    public function getExistingProfile(mixed $profile): ?SocialProfile
    {
        if (!$profile) {
            return null;
        }

        return SocialProfile::where(
            'user_service_id',
            $this->getUsersIdentifierOnService($profile),
        )
            ->with('user')
            ->first();
    }

    /**
     * Create a new user from given social profile and log him in.
     */
    public function createUserFromOAuthData(array $data)
    {
        $profile = $data['profile'];
        $service = $data['service'];

        $user = User::where('email', $profile->email)->first();

        //create a new user if one does not exist with specified email
        if (!$user) {
            $img = str_replace('http://', 'https://', $profile->avatar);
            $user = (new CreateUser())->execute([
                'email' => $profile->email,
                'avatar' => $img,
                'email_verified_at' => now(),
            ]);
        }

        //save this social profile data, so we can log in the user easily next time
        $user
            ->social_profiles()
            ->create(
                $this->transformSocialProfileData(
                    $service,
                    $profile,
                    $user->id,
                ),
            );

        return $this->logUserIn($user, $service);
    }

    public function updateSocialProfileData(
        SocialProfile $profile,
        string $service,
        $data,
        User|null $user = null,
    ): void {
        $data = $this->transformSocialProfileData(
            $service,
            $data,
            $user->id ?? $profile->user_id,
        );

        $profile->fill($data)->save();
    }

    public function attachProfileToExistingUser(
        User $user,
        mixed $profile,
        string $service,
    ) {
        $payload = $this->transformSocialProfileData(
            $service,
            $profile,
            $user->id,
        );

        //if this social account is already attached to some user
        //we will re-attach it to specified user
        if ($existing = $this->getExistingProfile($profile)) {
            $this->updateSocialProfileData(
                $existing,
                $service,
                $profile,
                $user,
            );

            //if social account is not attached to any user, we will
            //create a model for it and attach it to specified user
        } else {
            $user->social_profiles()->create($payload);
        }

        $response = [
            'bootstrapData' => app(BootstrapData::class)
                ->init()
                ->getEncoded(),
        ];

        event(new SocialConnected($user, $service));

        return request()->expectsJson()
            ? $response
            : $this->getPopupResponse('SUCCESS', $response);
    }

    private function transformSocialProfileData(
        string $service,
        TwoUser|OneUser $data,
        int $userId,
    ): array {
        return [
            'service_name' => $service,
            'user_service_id' => $this->getUsersIdentifierOnService($data),
            'user_id' => $userId,
            'username' => $data->name,
            'access_token' => $data->token ?? null,
            'refresh_token' => $data->refreshToken ?? null,
            'access_expires_at' =>
                isset($data->expiresIn) && $data->expiresIn
                    ? Carbon::now()->addSeconds($data->expiresIn)
                    : null,
        ];
    }

    public function returnProfileData($externalProfile)
    {
        $normalizedProfile = [
            'id' => $externalProfile->id,
            'name' => $externalProfile->name,
            'email' => $externalProfile->email,
            'avatar' => $externalProfile->avatar,
            'profileUrl' => $externalProfile->profileUrl,
        ];

        if (request()->expectsJson()) {
            return ['profile' => $normalizedProfile];
        } else {
            return $this->getPopupResponse('SUCCESS_PROFILE_RETRIEVE', [
                'profile' => $normalizedProfile,
            ]);
        }
    }

    /**
     * Log given user into the app and return
     * a view to close popup in front end.
     */
    public function logUserIn(User $user, string $serviceName)
    {
        Auth::loginUsingId($user->id, true);
        if (request('tokenForDevice')) {
            $response = app(MobileBootstrapData::class)
                ->init()
                ->refreshToken(request('tokenForDevice'))
                ->get();
        } else {
            $response = [
                'bootstrapData' => app(BootstrapData::class)
                    ->init()
                    ->getEncoded(),
            ];
        }

        event(new SocialLogin($user, $serviceName));

        if (request()->expectsJson()) {
            return $response;
        } else {
            return $this->getPopupResponse('SUCCESS', $response);
        }
    }

    public function getErrorResponse(string $message)
    {
        if (request()->wantsJson()) {
            return response()->json(['message' => $message], 500);
        } else {
            return $this->getPopupResponse('ERROR', [
                'errorMessage' => $message,
            ]);
        }
    }

    /**
     * Get oauth data persisted in current session.
     *
     * @param string $key
     * @return mixed
     */
    public function getPersistedData($key = null)
    {
        //test session when not logged, what if multiple users log in at same time etc

        $data = Session::get('social_profile');

        if (!$key) {
            return $data;
        }

        if ($key && isset($data[$key])) {
            return $data[$key];
        }
    }

    /**
     * Store specified social profile information in the session
     * for use in subsequent social login process steps.
     */
    public function persistSocialProfileData(array $data): void
    {
        foreach ($data as $key => $value) {
            Session::put("social_profile.$key", $value);
        }
    }

    /**
     * Check if provider user want to login with is valid, if not throw 404
     */
    private function validateProvider(string $provider): void
    {
        if (!in_array($provider, $this->validProviders)) {
            abort(404);
        }
    }

    /**
     * Get users unique identifier on social service from given profile.
     */
    private function getUsersIdentifierOnService(mixed $profile): int|string
    {
        return $profile->id ?? $profile->email;
    }

    public function getPopupResponse(string $status, $data = null): ViewContract
    {
        $view = View::make('common::oauth/popup')->with('status', $status);

        if ($data) {
            $view->with('data', json_encode($data));
        }

        return $view;
    }
}
PK       ! sd      Traits/HasAvatarAttribute.phpnu ȯ        <?php

namespace Common\Auth\Traits;

use Common\Auth\BaseUser;
use Storage;
use Str;

trait HasAvatarAttribute
{
    public function getAvatarAttribute(?string $value)
    {
        // absolute link
        if ($value && Str::contains($value, '//')) {
            // change google/twitter avatar imported via social login size
            $value = str_replace(
                '.jpg?sz=50',
                ".jpg?sz=$this->gravatarSize",
                $value,
            );
            if ($this->gravatarSize > 50) {
                // twitter
                $value = str_replace('_normal.jpg', '.jpg', $value);
            }
            return $value;
        }

        // relative link (for new and legacy urls)
        if ($value) {
            return Storage::disk('public')->url(
                str_replace('storage/', '', $value),
            );
        }

        // gravatar
        $hash = md5(trim(strtolower($this->email)));

        return "https://www.gravatar.com/avatar/$hash?s={$this->gravatarSize}&d=retro";
    }

    /**
     * @param number $size
     * @return BaseUser
     */
    public function setGravatarSize($size)
    {
        $this->gravatarSize = $size;
        return $this;
    }
}
PK       ! Ĵ,    "  Traits/HasDisplayNameAttribute.phpnu ȯ        <?php

namespace Common\Auth\Traits;

trait HasDisplayNameAttribute
{
    /**
     * Compile user display name from available attributes.
     *
     * @return string
     */
    public function getDisplayNameAttribute()
    {
        if ($this->username) {
            return $this->username;
        } else if ($this->first_name && $this->last_name) {
            return $this->first_name.' '.$this->last_name;
        } else if ($this->first_name) {
            return $this->first_name;
        } else if ($this->last_name) {
            return $this->last_name;
        } else {
            return explode('@', $this->email)[0];
        }
    }
}
PK       ! fST  T    Ban.phpnu ȯ        <?php

namespace Common\Auth;

use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\Relations\MorphTo;

class Ban extends Model
{
    protected $guarded = ['id'];

    protected $casts = [
        'expired_at' => 'datetime',
    ];

    const MODEL_TYPE = 'ban';

    public static function getModelTypeAttribute(): string
    {
        return self::MODEL_TYPE;
    }

    protected static function booted(): void
    {
        static::created(function (Ban $ban) {});
    }

    public function createdBy(): MorphTo
    {
        return $this->morphTo('created_by');
    }
}
PK       ! M@      "  Fortify/TwoFactorLoginResponse.phpnu ȯ        <?php

namespace Common\Auth\Fortify;

use Laravel\Fortify\Contracts\TwoFactorLoginResponse as TwoFactorLoginResponseContract;

class TwoFactorLoginResponse extends LoginResponse implements
    TwoFactorLoginResponseContract
{
}
PK       ! ~O=I;  ;    Fortify/LogoutResponse.phpnu ȯ        <?php

namespace Common\Auth\Fortify;

use Common\Core\Bootstrap\BootstrapData;
use Illuminate\Http\JsonResponse;
use Laravel\Fortify\Contracts\LogoutResponse as LogoutResponseContract;

class LogoutResponse implements LogoutResponseContract
{
    public function toResponse($request): JsonResponse
    {
        $data = app(BootstrapData::class)
            ->init()
            ->getEncoded();

        session()->forget('impersonator_id');

        return response()->json([
            'bootstrapData' => $data,
            'status' => 'success',
        ]);
    }
}
PK       !       Fortify/ResetUserPassword.phpnu ȯ        <?php

namespace Common\Auth\Fortify;

use Illuminate\Support\Facades\Validator;
use Laravel\Fortify\Contracts\ResetsUserPasswords;

class ResetUserPassword implements ResetsUserPasswords
{
    use PasswordValidationRules;

    /**
     * Validate and reset the user's forgotten password.
     *
     * @param  mixed  $user
     * @param  array  $input
     * @return void
     */
    public function reset($user, array $input)
    {
        Validator::make($input, [
            'password' => $this->passwordRules(),
        ])->validate();

        $user
            ->forceFill([
                'password' => $input['password'],
            ])
            ->save();
    }
}
PK       ! o      Fortify/FortifyRegisterUser.phpnu ȯ        <?php

namespace Common\Auth\Fortify;

use App\Models\User;
use Closure;
use Common\Auth\Actions\CreateUser;
use Illuminate\Support\Facades\Validator;
use Illuminate\Validation\Rule;
use Laravel\Fortify\Contracts\CreatesNewUsers;

class FortifyRegisterUser implements CreatesNewUsers
{
    use PasswordValidationRules;

    public function create(array $input): User
    {
        if (settings('registration.disable')) {
            abort(404);
        }

        $appRules = config('common.registration-rules') ?? [];
        $commonRules = [
            'email' => [
                'required',
                'string',
                'email',
                'max:255',
                Rule::unique(User::class),
                function (string $attribute, mixed $value, Closure $fail) {
                    if (!self::emailIsValid($value)) {
                        $fail(__('This domain is blacklisted.'));
                    }
                },
            ],
            'password' => $this->passwordRules(),
            'token_name' => 'string|min:3|max:50',
        ];

        foreach ($appRules as $key => $rules) {
            $commonRules[$key] = array_map(function ($rule) {
                if (str_contains($rule, '\\')) {
                    $namespace = "\\$rule";
                    return new $namespace();
                }
                return $rule;
            }, $rules);
        }

        $data = Validator::make($input, $commonRules)->validate();

        return (new CreateUser())->execute($data);
    }

    public static function emailIsValid(string $email): bool
    {
        $blacklistedDomains = explode(
            ',',
            settings('auth.domain_blacklist', ''),
        );
        if ($blacklistedDomains) {
            $domain = explode('@', $email)[1] ?? null;
            if ($domain && in_array($domain, $blacklistedDomains)) {
                return false;
            }
        }

        return true;
    }
}
PK       ! ЫG  G  "  Fortify/FortifyServiceProvider.phpnu ȯ        <?php

namespace Common\Auth\Fortify;

use Illuminate\Cache\RateLimiting\Limit;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\RateLimiter;
use Illuminate\Support\ServiceProvider;
use Laravel\Fortify\Contracts\LoginResponse as LoginResponseContract;
use Laravel\Fortify\Contracts\LogoutResponse as LogoutResponseContract;
use Laravel\Fortify\Contracts\RegisterResponse as RegisterResponseContract;
use Laravel\Fortify\Contracts\TwoFactorLoginResponse as TwoFactorLoginResponseContract;
use Laravel\Fortify\Fortify;

class FortifyServiceProvider extends ServiceProvider
{
    public function register()
    {
        $this->app->instance(LoginResponseContract::class, new LoginResponse());
        $this->app->instance(
            TwoFactorLoginResponseContract::class,
            new TwoFactorLoginResponse(),
        );
        $this->app->instance(
            LogoutResponseContract::class,
            new LogoutResponse(),
        );
        $this->app->instance(
            RegisterResponseContract::class,
            new RegisterResponse(),
        );
    }

    public function boot()
    {
        Fortify::createUsersUsing(FortifyRegisterUser::class);
        Fortify::resetUserPasswordsUsing(ResetUserPassword::class);
        Fortify::updateUserPasswordsUsing(UpdateUserPassword::class);

        RateLimiter::for('login', function (Request $request) {
            $email = (string) $request->email;
            return Limit::perMinute(5)->by($email . $request->ip());
        });

        RateLimiter::for('two-factor', function (Request $request) {
            return Limit::perMinute(5)->by(
                $request->session()->get('login.id'),
            );
        });

        Fortify::authenticateUsing(function (Request $request) {
            return (new ValidateLoginCredentials())->execute($request);
        });
    }
}
PK       ! u  u  #  Fortify/PasswordValidationRules.phpnu ȯ        <?php

namespace Common\Auth\Fortify;

use Laravel\Fortify\Rules\Password;

trait PasswordValidationRules
{
    /**
     * Get the validation rules used to validate passwords.
     */
    protected function passwordRules(): array
    {
        $password = new Password();
        $password->length(5);
        return ['required', 'string', $password, 'confirmed'];
    }
}
PK       ! +R      Fortify/UpdateUserPassword.phpnu ȯ        <?php

namespace Common\Auth\Fortify;

use Illuminate\Support\Facades\Validator;
use Laravel\Fortify\Contracts\UpdatesUserPasswords;

class UpdateUserPassword implements UpdatesUserPasswords
{
    use PasswordValidationRules;

    public function update($user, array $input)
    {
        Validator::make(
            $input,
            [
                'current_password' => [
                    'required',
                    'string',
                    'current_password:web',
                ],
                'password' => $this->passwordRules(),
            ],
            [
                'current_password.current_password' => __(
                    'The provided password does not match your current password.',
                ),
            ],
        )->validateWithBag('updatePassword');

        $user
            ->forceFill([
                'password' => $input['password'],
            ])
            ->save();
    }
}
PK       ! oI8      Fortify/RegisterResponse.phpnu ȯ        <?php

namespace Common\Auth\Fortify;

use Common\Core\Bootstrap\BootstrapData;
use Common\Core\Bootstrap\MobileBootstrapData;
use Illuminate\Http\JsonResponse;
use Laravel\Fortify\Contracts\RegisterResponse as RegisterResponseContract;

class RegisterResponse implements RegisterResponseContract
{
    public function toResponse($request): JsonResponse
    {
        $response = [
            'status' => $request->user()->hasVerifiedEmail()
                ? 'success'
                : 'needs_email_verification',
        ];

        // for mobile
        if ($request->has('token_name')) {
            $bootstrapData = app(MobileBootstrapData::class)->init();
            $bootstrapData->refreshToken($request->get('token_name'));
            $response['bootstrapData'] = $bootstrapData->get();

            // for web
        } else {
            $bootstrapData = app(BootstrapData::class)->init();
            $response['bootstrapData'] = $bootstrapData->getEncoded();
        }

        return response()->json($response);
    }
}
PK       ! q  q  $  Fortify/ValidateLoginCredentials.phpnu ȯ        <?php

namespace Common\Auth\Fortify;

use App\Models\User;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Hash;
use Illuminate\Validation\ValidationException;
use Laravel\Fortify\Fortify;
use Laravel\Fortify\LoginRateLimiter;

class ValidateLoginCredentials
{
    public function execute(Request $request): ?User
    {
        $user = User::where('email', $request->email)->first();

        if (!FortifyRegisterUser::emailIsValid($request->email)) {
            $this->throwFailedAuthenticationException(
                $request,
                __('This domain is blacklisted.'),
            );
        }

        if ($user?->isBanned()) {
            $comment = $user->bans()->first()->comment;
            $this->throwFailedAuthenticationException(
                $request,
                $comment
                    ? __('Banned: :reason', ['reason' => $comment])
                    : __('This user is banned.'),
            );
        }

        if ($user && Hash::check($request->password, $user->password)) {
            return $user;
        }

        return null;
    }

    public function throwFailedAuthenticationException(
        Request $request,
        string $message,
    ) {
        app(LoginRateLimiter::class)->increment($request);

        throw ValidationException::withMessages([
            Fortify::username() => [$message],
        ]);
    }
}
PK       ! Ǥ      Fortify/LoginResponse.phpnu ȯ        <?php

namespace Common\Auth\Fortify;

use Common\Core\Bootstrap\BootstrapData;
use Illuminate\Http\JsonResponse;
use Illuminate\Support\Facades\Auth;
use Laravel\Fortify\Contracts\LoginResponse as LoginResponseContract;

class LoginResponse implements LoginResponseContract
{
    public function toResponse($request): JsonResponse
    {
        if ($request->get('password') && settings('single_device_login')) {
            Auth::logoutOtherDevices($request->get('password'));
        }

        $data = app(BootstrapData::class)
            ->init()
            ->getEncoded();

        return response()->json([
            'bootstrapData' => $data,
            'two_factor' => false,
        ]);
    }
}
PK       ! E  E  %  Validators/EmailVerifiedValidator.phpnu ȯ        <?php namespace Common\Auth\Validators;

use App;
use App\Models\User;
use Common\Settings\Settings;

class EmailVerifiedValidator {

    /**
     * Check if user with specified email has verified his email address.
     *
     * @param string $attribute
     * @param string $value
     * @param array $parameters
     * @return bool
     */
    public function validate($attribute, $value, $parameters) {
        $settings = App::make(Settings::class);

        //don't need to validate email, bail
        if ( ! $settings->get('require_email_confirmation')) return true;

        //if email address is not taken yet, bail
        if ( ! $user = User::where('email', $value)->first()) return true;

        //check if specified email is verified
        /** @var User $user */
        return (bool) $user->hasVerifiedEmail();
    }
}
PK       ! 03      Validators/PasswordIsValid.phpnu ȯ        <?php

namespace Common\Auth\Validators;

use Illuminate\Contracts\Validation\InvokableRule;
use Illuminate\Support\Facades\Hash;

class PasswordIsValid implements InvokableRule
{
    public bool $implicit = true;

    public function __construct(protected string $password)
    {
    }

    public function __invoke($attribute, $value, $fail)
    {
        if (!Hash::check($value, $this->password)) {
            $fail('Password does not match.')->translate();
        }
    }
}
PK       ! Y      Validators/HashIsValid.phpnu ȯ        <?php

namespace Common\Auth\Validators;

use Closure;
use Illuminate\Contracts\Validation\InvokableRule;
use Illuminate\Support\Facades\Hash;

class HashIsValid implements InvokableRule
{
    public function __construct(protected string $hashedValue)
    {
    }

    public function __invoke($attribute, mixed $value, $fail)
    {
        if (!Hash::check($value, $this->hashedValue)) {
            return $fail('The :attribute is not valid')->translate();
        }
    }
}
PK       ! OT1B  B    OtpCode.phpnu ȯ        <?php

namespace Common\Auth;

use Illuminate\Database\Eloquent\Model;

class OtpCode extends Model
{
    const TYPE_EMAIL_VERIFICATION = 'email_verification';

    protected $guarded = ['id'];

    protected $casts = [
        'expires_at' => 'datetime',
    ];

    public $timestamps = false;

    public function isExpired(): bool
    {
        return now()->gte($this->expires_at);
    }

    public static function createForEmailVerification(int $userId)
    {
        self::where('user_id', $userId)
            ->where('type', static::TYPE_EMAIL_VERIFICATION)
            ->delete();
        return static::create([
            'user_id' => $userId,
            'type' => static::TYPE_EMAIL_VERIFICATION,
            'code' => random_int(100000, 999999),
            'expires_at' => now()->addMinutes(30),
        ]);
    }
}
PK       ! պYF  F  -  Permissions/Traits/HasPermissionsRelation.phpnu ȯ        <?php

namespace Common\Auth\Permissions\Traits;

use Common\Auth\Permissions\Permission;
use Illuminate\Database\Eloquent\Relations\MorphToMany;

trait HasPermissionsRelation
{
    public function permissions(): MorphToMany
    {
        return $this->morphToMany(Permission::class, 'permissionable')
            ->withPivot('restrictions')
            ->select('name', 'permissions.id', 'permissions.restrictions');
    }

    public function hasPermission(string $name): bool
    {
        return !is_null($this->getPermission($name)) ||
            !is_null($this->getPermission('admin'));
    }

    public function hasExactPermission(string $name): bool
    {
        return !is_null($this->getPermission($name));
    }

    public function getPermission(string $name): Permission|null
    {
        if (method_exists($this, 'loadPermissions')) {
            $this->loadPermissions();
        }

        foreach ($this->permissions as $permission) {
            if ($permission->name === $name) {
                return $permission;
            }
        }

        return null;
    }

    public function getRestrictionValue(
        string $permissionName,
        string $restriction,
    ): int|bool|null {
        $permission = $this->getPermission($permissionName);
        return $permission?->getRestrictionValue($restriction);
    }
}
PK       ! 譐ai  i  '  Permissions/Traits/SyncsPermissions.phpnu ȯ        <?php

namespace Common\Auth\Permissions\Traits;

use Illuminate\Database\Eloquent\Model;
use Illuminate\Support\Arr;
use Illuminate\Support\Collection;

trait SyncsPermissions
{
    public function syncPermissions(
        Model $model,
        array|Collection $permissions
    ): void {
        $permissionIds = collect($permissions)->mapWithKeys(function (
            $permission
        ) {
            $restrictions = Arr::get($permission, 'restrictions', []);
            return [
                $permission['id'] => [
                    'restrictions' => collect($restrictions)
                        ->filter(function ($restriction) {
                            return isset($restriction['value']);
                        })
                        ->map(function ($restriction) {
                            return [
                                'name' => $restriction['name'],
                                'value' => $restriction['value'],
                            ];
                        }),
                ],
            ];
        });
        $model->permissions()->sync($permissionIds);
    }
}
PK       ! ]f 6  6    Permissions/Permission.phpnu ȯ        <?php

namespace Common\Auth\Permissions;

use Arr;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Support\Collection;

class Permission extends Model
{
    protected $guarded = ['id'];

    protected $casts = [
        'id' => 'integer',
        'advanced' => 'integer',
    ];

    protected $hidden = ['pivot', 'permissionable_type'];

    const MODEL_TYPE = 'permission';

    public static function getModelTypeAttribute(): string
    {
        return self::MODEL_TYPE;
    }

    /**
     * @param string|array $value
     * @return Collection
     */
    public function getRestrictionsAttribute($value)
    {
        // if loading permissions via parent (user, role, plan) return restrictions
        // stored on pivot table, otherwise return restrictions stored on permission itself
        $value = $this->pivot ? $this->pivot->restrictions : $value;
        if ( ! $value) $value = [];
        return collect(is_string($value) ? json_decode($value, true) : $value)->values();
    }

    public function setRestrictionsAttribute($value)
    {
        if ($value && is_array($value)) {
            $this->attributes['restrictions'] = json_encode(array_values($value));
        }
    }

    public function getRestrictionValue(string $name): int | bool | null
    {
        $restriction = $this->restrictions->first(function($restriction) use($name) {
            return $restriction['name'] === $name;
        });

        return Arr::get($restriction, 'value') ?? null;
    }

    /**
     * Merge restrictions from specified permission into this permission.
     */
    public function mergeRestrictions(Permission $permission = null): self
    {
        if ($permission) {
            $permission->restrictions->each(function($restriction) {
                $exists = $this->restrictions->first(function($r) use($restriction) {
                    return $r['name'] === $restriction['name'];
                });
                if ( ! $exists) {
                    $this->restrictions->push($restriction);
                }
            });
        }
        return $this;
    }
}
PK       ! cE    )  Permissions/Policies/PermissionPolicy.phpnu ȯ        <?php

namespace Common\Auth\Permissions\Policies;

use Common\Auth\Permissions\Permission;
use Common\Auth\BaseUser;
use Illuminate\Http\Request;
use Illuminate\Auth\Access\HandlesAuthorization;

class PermissionPolicy
{
    use HandlesAuthorization;

    /**
     * @var Request
     */
    private $request;

    public function __construct(Request $request)
    {
        $this->request = $request;
    }

    public function index(BaseUser $user)
    {
        return $user->hasPermission('permission.view');
    }

    public function show(BaseUser $user, Permission $permission)
    {
        return $user->hasPermission('permission.view');
    }

    public function store(BaseUser $user)
    {
        return $user->hasPermission('permission.create');
    }

    public function update(BaseUser $user)
    {
        return $user->hasPermission('permission.update');
    }

    public function destroy(BaseUser $user)
    {
        return $user->hasPermission('permission.delete');
    }
}
PK       ! Z_+  +  )  Commands/DeleteExpiredOtpCodesCommand.phpnu ȯ        <?php

namespace Common\Auth\Commands;

use Common\Auth\OtpCode;
use Illuminate\Console\Command;
use Illuminate\Support\Carbon;

class DeleteExpiredOtpCodesCommand extends Command
{
    protected $signature = 'otp:deleteExpired';
    protected $description = 'Delete one time passwords that have expired.';

    public function handle(): int
    {
        OtpCode::query()
            ->where('expires_at', '<', Carbon::now())
            ->delete();

        $this->info('Expired OTP codes have been deleted.');

        return Command::SUCCESS;
    }
}
PK       !     %  Commands/DeleteExpiredBansCommand.phpnu ȯ        <?php

namespace Common\Auth\Commands;

use Common\Auth\Ban;
use Illuminate\Console\Command;
use Illuminate\Support\Carbon;

class DeleteExpiredBansCommand extends Command
{
    protected $signature = 'bans:deleteExpired';
    protected $description = 'Unban users whose ban date has expired.';

    public function handle(): int
    {
        $bans = Ban::query()
            ->where('expired_at', '<=', Carbon::now()->format('Y-m-d H:i:s'))
            ->get();

        $bans->each(function ($ban) {
            $ban->created_by->fill(['banned_at' => null])->save();
            $ban->delete();
        });

        $this->info("Unbanned {$bans->count()} users.");

        return Command::SUCCESS;
    }
}
PK       ! ,    +  Controllers/EmailVerificationController.phpnu ȯ        <?php namespace Common\Auth\Controllers;

use App\Models\User;
use Auth;
use Common\Core\BaseController;

class EmailVerificationController extends BaseController
{
    public function __construct()
    {
        $this->middleware('auth');
    }

    public function validateOtp()
    {
        $code = request('code');
        $user = Auth::user();

        if (!$code || !$user->emailVerificationOtpIsValid($code)) {
            $msg = __(
                'The security code you entered is invalid or has expired',
            );
            return $this->error($msg, [
                'code' => $msg,
            ]);
        }

        $user->markEmailAsVerified();

        return $this->success();
    }

    public function resendVerificationEmail()
    {
        $data = $this->validate(request(), ['email' => 'required|email']);

        $user = User::where('email', $data['email'])->firstOrFail();

        $this->authorize('update', $user);

        $user->sendEmailVerificationNotification();

        return $this->success();
    }
}
PK       ! 0Lm>  >  $  Controllers/UserAvatarController.phpnu ȯ        <?php namespace Common\Auth\Controllers;

use App\Models\User;
use Common\Auth\Events\UserAvatarChanged;
use Common\Core\BaseController;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Storage;

class UserAvatarController extends BaseController
{
    public function __construct(
        protected Request $request,
        protected User $user,
    ) {
    }

    public function store(User $user)
    {
        $this->authorize('update', $user);

        $this->validate($this->request, [
            'file' => 'required_without:url|image|max:1500',
            'url' => 'required_without:file|string|max:250',
        ]);

        // delete old user avatar
        if ($user->getRawOriginal('avatar')) {
            Storage::disk('public')->delete($user->getRawOriginal('avatar'));
        }

        // store new avatar on public disk
        $path =
            $this->request->get('url') ??
            $this->request
                ->file('file')
                ->storePublicly('avatars', ['disk' => 'public']);

        // attach avatar to user model
        $user->avatar = $path;
        $user->save();

        event(new UserAvatarChanged($user));

        return $this->success(['user' => $user]);
    }

    public function destroy(User $user)
    {
        $this->authorize('update', $user);

        if ($user->getRawOriginal('avatar')) {
            Storage::disk('public')->delete($user->getRawOriginal('avatar'));
        }

        $user->avatar = null;
        $user->save();

        event(new UserAvatarChanged($user));

        return $this->success();
    }
}
PK       ! .H+    +  Controllers/UserFollowedUsersController.phpnu ȯ        <?php

namespace Common\Auth\Controllers;

use App\Models\User;
use Common\Core\BaseController;

class UserFollowedUsersController extends BaseController
{
    public function index(User $user)
    {
        $this->authorize('show', $user);

        $pagination = $user
            ->followedUsers()
            ->withCount(['followers'])
            ->paginate(request('perPage', 20));

        return $this->success(['pagination' => $pagination]);
    }

    public function ids(User $user)
    {
        $this->authorize('show', $user);

        $ids = $user->followedUsers()->pluck('id');

        return $this->success(['ids' => $ids]);
    }
}
PK       ! }-      Controllers/UserController.phpnu ȯ        <?php namespace Common\Auth\Controllers;

use App\Models\User;
use Auth;
use Common\Auth\Actions\CreateUser;
use Common\Auth\Actions\DeleteUsers;
use Common\Auth\Actions\PaginateUsers;
use Common\Auth\Actions\UpdateUser;
use Common\Auth\Requests\CrupdateUserRequest;
use Common\Core\BaseController;

class UserController extends BaseController
{
    public function __construct()
    {
        $this->middleware('auth', ['except' => ['show']]);
    }

    public function index()
    {
        $this->authorize('index', User::class);

        $pagination = (new PaginateUsers())->execute(request()->all());

        return $this->success(['pagination' => $pagination]);
    }

    public function show(User $user)
    {
        $relations = array_filter(explode(',', request('with', '')));
        $relations = array_merge(['roles', 'social_profiles'], $relations);

        if (settings('envato.enable')) {
            $relations[] = 'purchase_codes';
        }

        if (Auth::id() === $user->id) {
            $relations[] = 'tokens';
            $user->makeVisible([
                'two_factor_confirmed_at',
                'two_factor_recovery_codes',
            ]);
            if ($user->two_factor_confirmed_at) {
                $user->two_factor_recovery_codes = $user->recoveryCodes();
                $user->syncOriginal();
            }
        }

        $user->load($relations);

        $this->authorize('show', $user);

        return $this->success(['user' => $user]);
    }

    public function store(CrupdateUserRequest $request)
    {
        $this->authorize('store', User::class);

        $user = (new CreateUser())->execute($request->validated());

        return $this->success(['user' => $user], 201);
    }

    public function update(User $user, CrupdateUserRequest $request)
    {
        $this->authorize('update', $user);

        $user = (new UpdateUser())->execute($user, $request->validated());

        return $this->success(['user' => $user]);
    }

    public function destroy(string $ids)
    {
        $userIds = explode(',', $ids);
        $shouldDeleteCurrentUser = request('deleteCurrentUser');
        $this->authorize('destroy', [User::class, $userIds]);

        $users = User::whereIn('id', $userIds)->get();

        // guard against current user or admin user deletion
        foreach ($users as $user) {
            if (!$shouldDeleteCurrentUser && $user->id === Auth::id()) {
                return $this->error(
                    __('Could not delete currently logged in user: :email', [
                        'email' => $user->email,
                    ]),
                );
            }

            if ($user->hasPermission('admin')) {
                return $this->error(
                    __('Could not delete admin user: :email', [
                        'email' => $user->email,
                    ]),
                );
            }
        }

        (new DeleteUsers())->execute($users->pluck('id')->toArray());

        return $this->success();
    }
}
PK       ! $ͮkL  L  '  Controllers/UserFollowersController.phpnu ȯ        <?php namespace Common\Auth\Controllers;

use App\Models\User;
use Auth;
use Common\Core\BaseController;

class UserFollowersController extends BaseController
{
    public function __construct()
    {
        $this->middleware('auth')->except(['index']);
    }

    public function index(User $user)
    {
        $this->authorize('show', $user);

        $pagination = $user
            ->followers()
            ->withCount(['followers'])
            ->simplePaginate(request('perPage') ?? 20);

        return $this->success(['pagination' => $pagination]);
    }

    public function follow(User $userToFollow)
    {
        if ($userToFollow->id !== Auth::user()->id) {
            Auth::user()
                ->followedUsers()
                ->sync([$userToFollow->id], false);
        }

        return $this->success();
    }

    public function unfollow(User $userToFollow)
    {
        if ($userToFollow->id != Auth::user()->id) {
            Auth::user()
                ->followedUsers()
                ->detach($userToFollow->id);
        }

        return $this->success();
    }
}
PK       ! !,(xV  V  %  Controllers/AccessTokenController.phpnu ȯ        <?php

namespace Common\Auth\Controllers;

use Auth;
use Common\Core\BaseController;
use Illuminate\Http\Request;

class AccessTokenController extends BaseController
{
    public function __construct(protected Request $request)
    {
        $this->middleware(['auth']);
    }

    public function store()
    {
        $this->validate($this->request, [
            'tokenName' => 'required|string|min:3|max:100',
        ]);

        $token = Auth::user()->createToken($this->request->get('tokenName'));

        return $this->success([
            'token' => $token->accessToken,
            'plainTextToken' => $token->plainTextToken,
        ]);
    }

    public function destroy(string $tokenId)
    {
        Auth::user()
            ->tokens()
            ->where('id', $tokenId)
            ->delete();

        return $this->success();
    }
}
PK       ! jx֟	  	  &  Controllers/UserSessionsController.phpnu ȯ        <?php

namespace Common\Auth\Controllers;

use Common\Auth\ActiveSession;
use Common\Core\BaseController;
use Illuminate\Contracts\Auth\StatefulGuard;
use Illuminate\Support\Facades\Auth;
use Jenssegers\Agent\Agent;

class UserSessionsController extends BaseController
{
    public function __construct()
    {
        $this->middleware('auth');
    }

    public function index()
    {
        $sessions = Auth::user()
            ->activeSessions()
            ->orderBy('updated_at', 'desc')
            ->limit(30)
            ->get()
            ->map(function (ActiveSession $session) {
                $agent = new Agent(null, $session->user_agent);
                $location = geoip($session->ip_address);

                $isCurrentDevice = $session->session_id
                    ? $session->session_id ===
                        request()
                            ->session()
                            ->getId()
                    : $session->token ===
                        Auth::user()->currentAccessToken()->token;

                return [
                    'id' => $session->id,
                    'platform' => $agent->platform(),
                    'device_type' => $agent->deviceType(),
                    'browser' => $agent->browser(),
                    'country' => $location->country,
                    'city' => $location->city,
                    'ip_address' => config('common.site.demo')
                        ? 'Hidden on demo site'
                        : $session->ip_address,
                    'is_current_device' => $isCurrentDevice,
                    'last_active' => $session->updated_at,
                ];
            })
            ->values();

        return $this->success(['sessions' => $sessions]);
    }

    public function LogoutOtherSessions(StatefulGuard $guard)
    {
        $data = $this->validate(request(), [
            'password' => 'required',
        ]);

        $guard->logoutOtherDevices($data['password']);

        ActiveSession::where('user_id', $guard->id())
            ->whereNotNull('session_id')
            ->where(
                'session_id',
                '!=',
                request()
                    ->session()
                    ->getId(),
            )
            ->delete();

        return $this->success();
    }
}
PK       ! #z  z  )  Controllers/TwoFactorQrCodeController.phpnu ȯ        <?php

namespace Common\Auth\Controllers;

use Common\Core\BaseController;
use Illuminate\Support\Facades\Auth;

class TwoFactorQrCodeController extends BaseController
{
    public function show()
    {
        return $this->success([
            'svg' => Auth::user()->twoFactorQrCodeSvg(),
            'secret' => decrypt(Auth::user()->two_factor_secret),
        ]);
    }
}
PK       ! }      Controllers/BanController.phpnu ȯ        <?php

namespace Common\Auth\Controllers;

use App\Models\User;
use Common\Core\BaseController;
use Illuminate\Support\Arr;
use Illuminate\Support\Facades\Auth;

class BanController extends BaseController
{
    public function store(User $user)
    {
        $this->authorize('destroy', [User::class, [$user->id]]);

        if ($user->hasPermission('admin')) {
            abort(403, 'Admin users can\'t be suspended');
        }

        $data = $this->validate(request(), [
            'ban_until' => 'nullable|date|after:now',
            'comment' => 'nullable|string|max:255',
            'permanent' => 'boolean',
        ]);

        $user->bans()->create([
            'expired_at' => $data['permanent']
                ? null
                : Arr::get($data, 'ban_until'),
            'comment' => Arr::get($data, 'comment'),
            'created_by_type' => User::MODEL_TYPE,
            'created_by_id' => Auth::id(),
        ]);
        $user->fill(['banned_at' => now()])->save();

        return $this->success(['user' => $user]);
    }

    public function destroy(User $user)
    {
        $this->authorize('destroy', [User::class, [$user->id]]);

        $user->bans()->delete();
        $user->fill(['banned_at' => null])->save();

        return $this->success(['user' => $user]);
    }
}
PK       ! 	  	  $  Controllers/MobileAuthController.phpnu ȯ        <?php

namespace Common\Auth\Controllers;

use Common\Auth\Fortify\ValidateLoginCredentials;
use Common\Core\BaseController;
use Common\Core\Bootstrap\MobileBootstrapData;
use Illuminate\Auth\Events\Registered;
use Illuminate\Http\JsonResponse;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Auth;
use Laravel\Fortify\Contracts\CreatesNewUsers;
use Laravel\Fortify\Contracts\EmailVerificationNotificationSentResponse;
use Laravel\Fortify\Contracts\RegisterResponse;
use Laravel\Fortify\Fortify;

class MobileAuthController extends BaseController
{
    public function login(Request $request)
    {
        $this->validate($request, [
            Fortify::username() => 'required|string',
            'password' => 'required|string',
            'token_name' => 'required|string|min:3|max:100',
        ]);

        $validator = app(ValidateLoginCredentials::class);
        $user = $validator->execute($request);

        if (!$user) {
            $validator->throwFailedAuthenticationException(
                $request,
                trans('auth.failed'),
            );
        }

        if (settings('single_device_login')) {
            Auth::logoutOtherDevices($request->get('password'));
        }

        Auth::login($user);

        $bootstrapData = app(MobileBootstrapData::class)
            ->init()
            ->refreshToken($request->get('token_name'))
            ->get();

        return $this->success($bootstrapData);
    }

    public function register(
        Request $request,
        CreatesNewUsers $creator,
    ): RegisterResponse {
        event(new Registered(($user = $creator->create($request->all()))));

        Auth::login($user);

        return app(RegisterResponse::class);
    }

    public function sendEmailVerificationNotification()
    {
        $this->middleware('auth');

        if (
            request()
                ->user()
                ->hasVerifiedEmail()
        ) {
            return request()->wantsJson()
                ? new JsonResponse('', 204)
                : redirect()->intended(
                    Fortify::redirects('email-verification'),
                );
        }

        request()
            ->user()
            ->sendEmailVerificationNotification();

        return app(EmailVerificationNotificationSentResponse::class);
    }
}
PK       ! $rN  N  $  Controllers/SocialAuthController.phpnu ȯ        <?php namespace Common\Auth\Controllers;

use App\Models\User;
use Common\Auth\Oauth;
use Common\Core\BaseController;
use Exception;
use Illuminate\Http\JsonResponse;
use Illuminate\Support\Facades\Auth;
use Illuminate\Support\Facades\Log;
use Illuminate\Support\Facades\Session;

class SocialAuthController extends BaseController
{
    public function __construct(protected Oauth $oauth)
    {
        $this->middleware('auth', [
            'only' => ['connect', 'disconnect'],
        ]);
        $this->middleware('guest', [
            'only' => ['login'],
        ]);
    }

    /**
     * Connect specified social account to currently logged-in user.
     */
    public function connect(string $provider)
    {
        if (!settings("social.$provider.enable")) {
            abort(403);
        }
        return $this->oauth->redirect($provider);
    }

    /**
     * Handles case where user is trying to log in with social account whose email
     * already exists in database. Request password for local account in that case.
     */
    public function connectWithPassword(): JsonResponse
    {
        // get data for this social login persisted in session
        $data = $this->oauth->getPersistedData();

        if (!$data) {
            return $this->error(__('There was an issue. Please try again.'));
        }

        if (
            !request()->has('password') ||
            !Auth::validate([
                'email' => $data['profile']->email,
                'password' => request('password'),
            ])
        ) {
            return $this->error(__('Specified credentials are not valid'), [
                'password' => __('This password is not correct.'),
            ]);
        }

        return $this->success($this->oauth->createUserFromOAuthData($data));
    }

    public function retrieveProfile(string $providerName)
    {
        return $this->oauth->retrieveProfileOnly($providerName);
    }

    /**
     * Disconnect specified social account from currently logged-in user.
     */
    public function disconnect(string $provider)
    {
        $this->oauth->disconnect($provider);
        return $this->success();
    }

    /**
     * Login with specified social provider.
     */
    public function login(string $provider)
    {
        if (!settings("social.$provider.enable")) {
            abort(403);
        }

        return $this->oauth->loginWith($provider);
    }

    public function loginCallback(string $provider)
    {
        if ($handler = Session::get(Oauth::OAUTH_CALLBACK_HANDLER_KEY)) {
            return app($handler)->execute($provider);
        }

        $externalProfile = null;
        try {
            $externalProfile = $this->oauth->socializeWith(
                $provider,
                request('tokenFromApi'),
                request('secretFromApi'),
            );
        } catch (Exception $e) {
            Log::error($e);
        }

        if (!$externalProfile) {
            return $this->oauth->getErrorResponse(
                __('Could not retrieve social sign in account.'),
            );
        }

        // TODO: use new "OAUTH_CALLBACK_HANDLER_KEY" functionality to handle this, remove "tokenFromApi" stuff from this handler
        if (Session::get(Oauth::RETRIEVE_PROFILE_ONLY_KEY)) {
            Session::forget(Oauth::RETRIEVE_PROFILE_ONLY_KEY);
            return $this->oauth->returnProfileData($externalProfile);
        }

        $existingProfile = $this->oauth->getExistingProfile($externalProfile);

        // if user is already logged in, attach returned social account to logged-in user
        if (Auth::check()) {
            return $this->oauth->attachProfileToExistingUser(
                Auth::user(),
                $externalProfile,
                $provider,
            );
        }

        // if we have already created a user for this social account, log user in
        if ($existingProfile?->user) {
            $this->oauth->updateSocialProfileData(
                $existingProfile,
                $provider,
                $externalProfile,
            );
            return $this->oauth->logUserIn($existingProfile->user, $provider);
        }

        // if user is trying to log in with envato and does not have any valid purchases, bail
        if (
            $provider === 'envato' &&
            empty($externalProfile->user['purchases'])
        ) {
            return $this->oauth->getErrorResponse(
                'You do not have any supported purchases.',
            );
        }

        // need to request password from user in order to connect accounts
        $user = User::where('email', $externalProfile->email)->first();
        if ($user?->password) {
            $this->oauth->persistSocialProfileData([
                'service' => $provider,
                'profile' => $externalProfile,
            ]);

            return $this->oauth->getPopupResponse('REQUEST_PASSWORD');
        }

        // if we have email and didn't create an account for this profile yet, do it now
        return $this->oauth->createUserFromOAuthData([
            'profile' => $externalProfile,
            'service' => $provider,
        ]);
    }
}
PK       ! Vқ6  6    BaseUser.phpnu ȯ        <?php namespace Common\Auth;

use App\Models\User;
use Common\Auth\Notifications\VerifyEmailWithOtp;
use Common\Auth\Permissions\Permission;
use Common\Auth\Permissions\Traits\HasPermissionsRelation;
use Common\Auth\Roles\Role;
use Common\Auth\Traits\HasAvatarAttribute;
use Common\Auth\Traits\HasDisplayNameAttribute;
use Common\Billing\Billable;
use Common\Billing\Models\Product;
use Common\Core\BaseModel;
use Common\Files\FileEntry;
use Common\Files\FileEntryPivot;
use Common\Files\Traits\SetsAvailableSpaceAttribute;
use Common\Notifications\NotificationSubscription;
use Illuminate\Auth\Authenticatable;
use Illuminate\Auth\MustVerifyEmail;
use Illuminate\Auth\Notifications\ResetPassword;
use Illuminate\Auth\Passwords\CanResetPassword;
use Illuminate\Contracts\Auth\Access\Authorizable as AuthorizableContract;
use Illuminate\Contracts\Auth\Authenticatable as AuthenticatableContract;
use Illuminate\Contracts\Auth\CanResetPassword as CanResetPasswordContract;
use Illuminate\Contracts\Translation\HasLocalePreference;
use Illuminate\Database\Eloquent\Builder;
use Illuminate\Database\Eloquent\Casts\Attribute;
use Illuminate\Database\Eloquent\Collection;
use Illuminate\Database\Eloquent\Relations\BelongsToMany;
use Illuminate\Database\Eloquent\Relations\HasMany;
use Illuminate\Database\Eloquent\Relations\HasOne;
use Illuminate\Database\Eloquent\Relations\MorphMany;
use Illuminate\Foundation\Auth\Access\Authorizable;
use Illuminate\Notifications\Notifiable;
use Illuminate\Support\Arr;
use Illuminate\Support\Facades\Auth;
use Illuminate\Support\Facades\Hash;
use Illuminate\Support\Str;
use Laravel\Fortify\TwoFactorAuthenticatable;
use Laravel\Scout\Searchable;

abstract class BaseUser extends BaseModel implements
    HasLocalePreference,
    AuthenticatableContract,
    AuthorizableContract,
    CanResetPasswordContract
{
    use Searchable,
        Notifiable,
        Billable,
        TwoFactorAuthenticatable,
        SetsAvailableSpaceAttribute,
        HasPermissionsRelation,
        HasAvatarAttribute,
        HasDisplayNameAttribute,
        Authenticatable,
        Authorizable,
        CanResetPassword,
        MustVerifyEmail;

    const MODEL_TYPE = 'user';

    protected $guarded = ['id'];
    protected $hidden = [
        'password',
        'remember_token',
        'pivot',
        'legacy_permissions',
        'two_factor_secret',
        'two_factor_recovery_codes',
        'two_factor_confirmed_at',
    ];
    protected $casts = [
        'id' => 'integer',
        'available_space' => 'integer',
        'email_verified_at' => 'datetime',
        'unread_notifications_count' => 'integer',
    ];
    protected $appends = ['display_name', 'has_password', 'model_type'];
    protected bool $billingEnabled = true;
    protected $gravatarSize;

    public function preferredLocale()
    {
        return $this->language;
    }

    public function __construct(array $attributes = [])
    {
        parent::__construct($attributes);
        $this->billingEnabled = (bool) settings('billing.enable');
    }

    public function toArray(bool $showAll = false): array
    {
        if (
            (!$showAll && !Auth::id()) ||
            (Auth::id() !== $this->id &&
                !Auth::user()?->hasPermission('users.update'))
        ) {
            $this->hidden = array_merge($this->hidden, [
                'first_name',
                'last_name',
                'avatar_url',
                'gender',
                'email',
                'card_brand',
                'has_password',
                'confirmed',
                'stripe_id',
                'roles',
                'permissions',
                'card_last_four',
                'created_at',
                'updated_at',
                'available_space',
                'email_verified_at',
                'timezone',
                'confirmation_code',
                'subscriptions',
            ]);
        }

        return parent::toArray();
    }

    public function roles(): BelongsToMany
    {
        return $this->belongsToMany(Role::class, 'user_role');
    }

    public function routeNotificationForSlack()
    {
        return config('services.slack.webhook_url');
    }

    public function scopeWhereNeedsNotificationFor(
        Builder $query,
        string $notifId,
    ) {
        return $query->whereHas('notificationSubscriptions', function (
            Builder $builder,
        ) use ($notifId) {
            if (Str::contains($notifId, '*')) {
                return $builder->where(
                    'notif_id',
                    'like',
                    str_replace('*', '%', $notifId),
                );
            } else {
                return $builder->where('notif_id', $notifId);
            }
        });
    }

    public function notificationSubscriptions(): HasMany
    {
        return $this->hasMany(NotificationSubscription::class);
    }

    public function entries(array $options = ['owner' => true]): BelongsToMany
    {
        $query = $this->morphToMany(
            FileEntry::class,
            'model',
            'file_entry_models',
            'model_id',
            'file_entry_id',
        )
            ->using(FileEntryPivot::class)
            ->withPivot('owner', 'permissions');

        if (Arr::get($options, 'owner')) {
            $query->wherePivot('owner', true);
        }

        return $query
            ->withTimestamps()
            ->orderBy('file_entry_models.created_at', 'asc');
    }

    public function activeSessions(): HasMany
    {
        return $this->hasMany(ActiveSession::class);
    }

    public function lastLogin(): HasOne
    {
        return $this->hasOne(ActiveSession::class)
            ->latest()
            ->select(['id', 'user_id', 'session_id', 'created_at']);
    }

    public function followedUsers(): BelongsToMany
    {
        return $this->belongsToMany(
            User::class,
            'follows',
            'follower_id',
            'followed_id',
        )->compact();
    }

    public function followers(): BelongsToMany
    {
        return $this->belongsToMany(
            User::class,
            'follows',
            'followed_id',
            'follower_id',
        )->compact();
    }

    public function social_profiles(): HasMany
    {
        return $this->hasMany(SocialProfile::class);
    }

    public function bans(): MorphMany
    {
        return $this->morphMany(Ban::class, 'bannable');
    }

    /**
     * Check if user has a password set.
     */
    public function getHasPasswordAttribute(): bool
    {
        return isset($this->attributes['password']) &&
            $this->attributes['password'];
    }

    protected function password(): Attribute
    {
        return Attribute::make(
            set: function ($value) {
                if (!$value) {
                    return null;
                }
                if (Hash::isHashed($value)) {
                    return $value;
                }
                return Hash::make($value);
            },
        );
    }

    protected function availableSpace(): Attribute
    {
        return Attribute::make(
            set: fn($value) => !is_null($value) ? (int) $value : null,
        );
    }

    protected function otpCodes(): HasMany
    {
        return $this->hasMany(OtpCode::class);
    }

    public function emailVerificationOtpIsValid(string $code): bool
    {
        $otp = $this->otpCodes()
            ->where('type', OtpCode::TYPE_EMAIL_VERIFICATION)
            ->first();

        if (!$otp || $otp->code !== $code || $otp->isExpired()) {
            return false;
        }

        return true;
    }

    protected function emailVerifiedAt(): Attribute
    {
        return Attribute::make(
            set: function ($value) {
                if ($value === true) {
                    return now();
                } elseif ($value === false) {
                    return null;
                }
                return $value;
            },
        );
    }

    public function sendEmailVerificationNotification(): void
    {
        $otp = OtpCode::createForEmailVerification($this->id);
        $this->notify(new VerifyEmailWithOtp($otp->code));
    }

    public function markEmailAsVerified(): bool
    {
        $this->otpCodes()
            ->where('type', OtpCode::TYPE_EMAIL_VERIFICATION)
            ->delete();
        return $this->forceFill([
            'email_verified_at' => $this->freshTimestamp(),
        ])->save();
    }

    public function loadPermissions($force = false): self
    {
        if (!$force && $this->relationLoaded('permissions')) {
            return $this;
        }

        $query = Permission::join(
            'permissionables',
            'permissions.id',
            'permissionables.permission_id',
        );

        // Might have a guest user. In this case user ID will be -1,
        // but we still want to load guest role permissions below
        if ($this->exists) {
            $query->where([
                'permissionable_id' => $this->id,
                'permissionable_type' => $this->getMorphClass(),
            ]);
        }

        if ($this->roles->pluck('id')->isNotEmpty()) {
            $query->orWhere(function (Builder $builder) {
                return $builder
                    ->whereIn('permissionable_id', $this->roles->pluck('id'))
                    ->where(
                        'permissionable_type',
                        $this->roles->first()->getMorphClass(),
                    );
            });
        }

        if ($this->exists && ($plan = $this->getSubscriptionProduct())) {
            $query->orWhere(function (Builder $builder) use ($plan) {
                return $builder
                    ->where('permissionable_id', $plan->id)
                    ->where('permissionable_type', $plan->getMorphClass());
            });
        }

        $permissions = $query
            ->select([
                'permissions.id',
                'name',
                'permissionables.restrictions',
                'permissionable_type',
            ])
            ->get()
            ->sortBy(function ($value) {
                if ($value['permissionable_type'] === $this->getMorphClass()) {
                    return 1;
                } elseif (
                    $value['permissionable_type'] === Product::MODEL_TYPE
                ) {
                    return 2;
                } else {
                    return 3;
                }
            })
            ->groupBy('id')

            // merge restrictions from all permissions
            ->map(function (Collection $group) {
                return $group->reduce(function (
                    Permission $carry,
                    Permission $permission,
                ) {
                    return $carry->mergeRestrictions($permission);
                }, $group[0]);
            });

        $this->setRelation('permissions', $permissions->values());

        return $this;
    }

    public function getSubscriptionProduct(): ?Product
    {
        if (!$this->billingEnabled) {
            return null;
        }

        $subscription = $this->subscriptions->first();

        if ($subscription && $subscription->valid()) {
            return $subscription->product;
        } else {
            return Product::where('free', true)->first();
        }
    }

    public function scopeCompact(Builder $query): Builder
    {
        return $query->select(
            'users.id',
            'users.avatar',
            'users.email',
            'users.first_name',
            'users.last_name',
            'users.username',
        );
    }

    public function sendPasswordResetNotification(mixed $token)
    {
        ResetPassword::$createUrlCallback = function ($user, $token) {
            return url("password/reset/$token");
        };
        $this->notify(new ResetPassword($token));
    }

    public static function findAdmin(): ?self
    {
        return (new static())
            ->newQuery()
            ->whereHas('permissions', function (Builder $query) {
                $query->where('name', 'admin');
            })
            ->first();
    }

    public function refreshApiToken($tokenName): string
    {
        $this->tokens()
            ->where('name', $tokenName)
            ->delete();
        $newToken = $this->createToken($tokenName);
        $this->withAccessToken($newToken->accessToken);
        return $newToken->plainTextToken;
    }

    public function isBanned(): bool
    {
        if (!$this->getAttributeValue('banned_at')) {
            return false;
        }

        $bannedUntil = $this->bans->first()->expired_at;

        return !$bannedUntil || $bannedUntil->isFuture();
    }

    public function resolveRouteBinding($value, $field = null): ?self
    {
        if ($value === 'me') {
            $value = Auth::id();
        }
        return $this->where('id', $value)->firstOrFail();
    }

    public function toSearchableArray(): array
    {
        return [
            'id' => $this->id,
            'username' => $this->username,
            'first_name' => $this->first_name,
            'last_name' => $this->last_name,
            'email' => $this->email,
            'created_at' => $this->created_at->timestamp ?? '_null',
            'updated_at' => $this->updated_at->timestamp ?? '_null',
        ];
    }

    public static function filterableFields(): array
    {
        return ['id', 'created_at', 'updated_at'];
    }

    public function toNormalizedArray(): array
    {
        return [
            'id' => $this->id,
            'name' => $this->display_name,
            'description' => $this->email,
            'image' => $this->avatar,
            'model_type' => self::MODEL_TYPE,
        ];
    }

    public static function getModelTypeAttribute(): string
    {
        return self::MODEL_TYPE;
    }
}
PK       ! g'"%      Roles/Role.phpnu ȯ        <?php namespace Common\Auth\Roles;

use App\Models\User;
use Common\Auth\Permissions\Traits\HasPermissionsRelation;
use Common\Core\BaseModel;
use Illuminate\Database\Eloquent\Relations\BelongsToMany;

class Role extends BaseModel
{
    use HasPermissionsRelation;

    const MODEL_TYPE = 'role';

    protected $guarded = ['id'];

    protected $hidden = ['pivot', 'legacy_permissions'];

    protected $casts = [
        'id' => 'integer',
        'default' => 'boolean',
        'guests' => 'boolean',
        'internal' => 'boolean',
    ];

    /**
     * Get default role for assigning to new users.
     */
    public function getDefaultRole(): ?Role
    {
        return $this->where('default', 1)->first();
    }

    public function users(): BelongsToMany
    {
        return $this->belongsToMany(User::class, 'user_role')->withPivot(
            'created_at',
        );
    }

    public function toNormalizedArray(): array
    {
        return [
            'id' => $this->id,
            'name' => $this->name,
            'model_type' => self::MODEL_TYPE,
        ];
    }

    public function toSearchableArray(): array
    {
        return [
            'id' => $this->id,
            'name' => $this->name,
            'description' => $this->description,
            'type' => $this->type,
            'created_at' => $this->created_at->timestamp ?? '_null',
            'updated_at' => $this->updated_at->timestamp ?? '_null',
        ];
    }

    public static function filterableFields(): array
    {
        return ['id', 'type', 'created_at', 'updated_at'];
    }

    public static function getModelTypeAttribute(): string
    {
        return Role::MODEL_TYPE;
    }
}
PK       ! P1      Roles/UserRolesController.phpnu ȯ        <?php namespace Common\Auth\Roles;

use App\Models\User;
use Common\Core\BaseController;

class UserRolesController extends BaseController
{
    public function attach(int $userId)
    {
        $user = User::findOrFail($userId);

        $this->authorize('update', $user);

        $data = $this->validate(request(), [
            'roles' => 'array',
            'roles.*' => 'integer|exists:roles,id',
        ]);

        $user->roles()->attach($data['roles']);

        return $this->success();
    }

    public function detach(int $userId)
    {
        $user = User::findOrFail($userId);

        $this->authorize('update', $user);

        $data = $this->validate(request(), [
            'roles' => 'array',
        ]);

        return $user->roles()->detach($data['roles']);
    }
}
PK       ! -'p@?  ?    Roles/CrupdateRole.phpnu ȯ        <?php

namespace Common\Auth\Roles;

use Common\Auth\Permissions\Traits\SyncsPermissions;
use Illuminate\Support\Arr;

class CrupdateRole
{
    use SyncsPermissions;

    /**
     * @var Role
     */
    private $role;

    /**
     * @param Role $role
     */
    public function __construct(Role $role)
    {
        $this->role = $role;
    }

    /**
     * @param array $data
     * @param Role $role
     * @return Role
     */
    public function execute($data, $role = null)
    {
        if (!$role) {
            $role = $this->role->newInstance([]);
        }

        $attributes = [
            'name' => $data['name'],
            'description' => $data['description'] ?? null,
            'default' => $data['default'] ?? false,
            'guests' => $data['guests'] ?? false,
            'type' => $data['type'] ?? 'sitewide',
        ];

        $role->fill($attributes)->save();

        // always sync permissions, detach all if "null" is given as permissions
        $this->syncPermissions($role, Arr::get($data, 'permissions', []));

        return $role;
    }
}
PK       ! V      Roles/RolesController.phpnu ȯ        <?php namespace Common\Auth\Roles;

use App\Models\User;
use Common\Core\BaseController;
use Common\Database\Datasource\Datasource;
use Illuminate\Http\Request;

class RolesController extends BaseController
{
    /**
     * @var User
     */
    private $user;

    /**
     * @var Role
     */
    private $role;

    /**
     * @var Request
     */
    private $request;

    public function __construct(Request $request, Role $role, User $user)
    {
        $this->role = $role;
        $this->user = $user;
        $this->request = $request;
    }

    public function show(Role $role)
    {
        $this->authorize('show', Role::class);

        $role->load(['permissions']);

        return $this->success(['role' => $role]);
    }

    public function index()
    {
        $this->authorize('index', Role::class);

        $pagination = (new Datasource(
            $this->role,
            request()->all(),
        ))->paginate();

        return $this->success(['pagination' => $pagination]);
    }

    public function store()
    {
        $this->authorize('store', Role::class);

        $this->validate($this->request, [
            'name' => 'required|unique:roles|min:2|max:255',
            'default' => 'nullable|boolean',
            'guests' => 'nullable|boolean',
            'permissions' => 'nullable|array',
        ]);

        $role = app(CrupdateRole::class)->execute($this->request->all());

        return $this->success(['role' => $role], 201);
    }

    public function update(int $id)
    {
        $this->authorize('update', Role::class);

        $this->validate($this->request, [
            'name' => "min:2|max:255|unique:roles,name,$id",
            'default' => 'boolean',
            'guests' => 'boolean',
            'permissions' => 'array',
        ]);

        $role = $this->role->findOrFail($id);

        $role = app(CrupdateRole::class)->execute($this->request->all(), $role);

        return $this->success(['role' => $role]);
    }

    public function destroy(int $id)
    {
        $role = $this->role->findOrFail($id);

        $this->authorize('destroy', $role);

        $role->users()->detach();
        $role->delete();

        return $this->success([], 204);
    }

    public function addUsers(int $roleId)
    {
        $this->authorize('update', Role::class);

        $this->validate($this->request, [
            'userIds' => 'required|array|min:1|max:25',
            'userIds.*' => 'required|int',
        ]);

        $role = $this->role->findOrFail($roleId);

        $users = $this->user
            ->with('roles')
            ->whereIn('id', $this->request->get('userIds'))
            ->get(['email', 'id']);

        if ($users->isEmpty()) {
            return $this->error(
                __('Could not attach specified users to role.'),
            );
        }

        //filter out users that are already attached to this role
        $users = $users->filter(function ($user) use ($roleId) {
            return !$user->roles->contains('id', $roleId);
        });

        $role->users()->attach($users->pluck('id')->toArray());

        return $this->success(['users' => $users]);
    }

    public function removeUsers(int $roleId)
    {
        $this->authorize('update', Role::class);

        $this->validate($this->request, [
            'userIds' => 'required|array|min:1',
            'userIds.*' => 'required|integer',
        ]);

        $role = $this->role->findOrFail($roleId);

        $role->users()->detach($this->request->get('userIds'));

        return $this->success();
    }
}
PK       !        Requests/CrupdateUserRequest.phpnu ȯ        <?php namespace Common\Auth\Requests;

use Common\Core\BaseFormRequest;

class CrupdateUserRequest extends BaseFormRequest
{
    public function rules(): array
    {
        $except = $this->getMethod() === 'PUT' ? $this->route('user')->id : '';

        $rules = [
            'email' => "email|min:3|max:255|unique:users,email,$except",
            'password' => 'min:3|max:255',
            'avatar' => 'string|max:255|nullable',
            'email_verified_at' => '', // can be date string or boolean
            // alpha and space/dash
            'first_name' =>
                'string|min:2|max:255|nullable|regex:/^[\pL\s\-]+$/u',
            'last_name' =>
                'string|min:2|max:255|nullable|regex:/^[\pL\s\-]+$/u',
            'permissions' => 'array',
            'roles' => 'array',
            'roles.*' => 'int',
            'available_space' => 'nullable|min:0',
            'country' => 'nullable|string|max:255',
            'language' => 'nullable|string|max:255',
            'timezone' => 'nullable|string|max:255',
        ];

        if ($this->method() === 'POST') {
            $rules['email'] = 'required|' . $rules['email'];
            $rules['password'] = 'required|' . $rules['password'];
        }

        return $rules;
    }
}
PK       ! Q4        Events/SocialConnected.phpnu ȯ        <?php

namespace Common\Auth\Events;

use App\Models\User;

class SocialConnected
{
    public function __construct(public User $user, public string $socialName)
    {
    }
}
PK       ! d        Events/UsersDeleted.phpnu ȯ        <?php

namespace Common\Auth\Events;

use Illuminate\Database\Eloquent\Collection;

class UsersDeleted
{
    public Collection $users;

    public function __construct(Collection $users)
    {
        $this->users = $users;
    }
}
PK       ! ,x        Events/SocialLogin.phpnu ȯ        <?php

namespace Common\Auth\Events;

use App\Models\User;

class SocialLogin
{
    public function __construct(public User $user, public string $socialName)
    {
    }
}
PK       ! G        Events/UserCreated.phpnu ȯ        <?php

namespace Common\Auth\Events;

use App\Models\User;

class UserCreated
{
    public function __construct(public User $user, public array $data)
    {
    }
}
PK       ! 
  
    Events/UserAvatarChanged.phpnu ȯ        <?php

namespace Common\Auth\Events;

use App\Models\User;

class UserAvatarChanged
{
    /**
     * @var User
     */
    public $user;

    /**
     * @param User $user
     */
    public function __construct(User $user)
    {
        $this->user = $user;
    }
}
PK       ! T,d  d    Actions/DeleteUsers.phpnu ȯ        <?php

namespace Common\Auth\Actions;

use App\Models\User;
use Common\Auth\ActiveSession;
use Common\Auth\Ban;
use Common\Auth\Events\UsersDeleted;
use Common\Billing\Subscription;
use Common\Csv\CsvExport;
use Common\Domains\Actions\DeleteCustomDomains;
use Common\Domains\CustomDomain;
use Common\Files\Actions\Deletion\PermanentlyDeleteEntries;
use Common\Pages\CustomPage;

class DeleteUsers
{
    public function execute(array $ids): int
    {
        $users = User::whereIn('id', $ids)->get();

        $users->each(function (User $user) {
            $user->social_profiles()->delete();
            $user->roles()->detach();
            $user->notifications()->delete();
            $user->permissions()->detach();

            if ($user->subscribed()) {
                $user->subscriptions->each(function (
                    Subscription $subscription,
                ) {
                    $subscription->cancelAndDelete();
                });
            }

            $user->delete();

            $entryIds = $user
                ->entries(['owner' => true])
                ->pluck('file_entries.id');
            app(PermanentlyDeleteEntries::class)->execute($entryIds);
        });

        // delete domains
        $domainIds = app(CustomDomain::class)
            ->whereIn('user_id', $ids)
            ->pluck('id');
        app(DeleteCustomDomains::class)->execute($domainIds->toArray());

        // delete custom pages
        CustomPage::whereIn('user_id', $ids)->delete();

        // delete sessions
        ActiveSession::whereIn('user_id', $ids)->delete();

        // csv exports
        CsvExport::whereIn('user_id', $ids)->delete();

        // bans
        Ban::where('bannable_type', User::MODEL_TYPE)
            ->whereIn('bannable_id', $ids)
            ->delete();

        event(new UsersDeleted($users));

        return $users->count();
    }
}
PK       ! n3x      Actions/UpdateUser.phpnu ȯ        <?php

namespace Common\Auth\Actions;

use App\Models\User;
use Common\Auth\Permissions\Traits\SyncsPermissions;
use Illuminate\Support\Arr;

class UpdateUser
{
    use SyncsPermissions;

    public function execute(User $user, array $params): User
    {
        $user->fill(Arr::except($params, ['roles', 'permissions']))->save();

        // make sure roles and permission are not removed
        // if they are not specified at all in params
        if (array_key_exists('roles', $params)) {
            $user->roles()->sync($params['roles']);
        }
        if (array_key_exists('permissions', $params)) {
            $this->syncPermissions($user, Arr::get($params, 'permissions'));
        }

        return $user->load(['roles', 'permissions']);
    }
}
PK       ! 
      Actions/PaginateUsers.phpnu ȯ        <?php

namespace Common\Auth\Actions;

use App\Models\User;
use Common\Database\Datasource\Datasource;
use Illuminate\Database\Eloquent\Builder;
use Illuminate\Pagination\AbstractPaginator;
use Illuminate\Support\Arr;

class PaginateUsers
{
    public function execute(array $params): AbstractPaginator
    {
        $query = User::with(['roles', 'permissions']);

        if ($roleId = Arr::get($params, 'roleId')) {
            $relation = $query->getModel()->roles();
            $query
                ->leftJoin(
                    $relation->getTable(),
                    $relation->getQualifiedParentKeyName(),
                    '=',
                    $relation->getQualifiedForeignPivotKeyName(),
                )
                ->where(
                    $relation->getQualifiedRelatedPivotKeyName(),
                    '=',
                    $roleId,
                );
            $query->select(['users.*', 'user_role.created_at as created_at']);
        }

        if ($roleName = Arr::get($params, 'roleName')) {
            $query->whereHas(
                'roles',
                fn(Builder $q) => $q->where('roles.name', $roleName),
            );
        }

        if ($permission = Arr::get($params, 'permission')) {
            $query
                ->whereHas(
                    'permissions',
                    fn(Builder $query) => $query
                        ->where('name', $permission)
                        ->orWhere('name', 'admin'),
                )
                ->orWhereHas(
                    'roles',
                    fn(Builder $query) => $query->whereHas(
                        'permissions',
                        fn(Builder $query) => $query
                            ->where('name', $permission)
                            ->orWhere('name', 'admin'),
                    ),
                );
        }

        return (new Datasource($query, $params))->paginate();
    }
}
PK       ! 2  2    Actions/CreateUser.phpnu ȯ        <?php

namespace Common\Auth\Actions;

use App\Models\User;
use Common\Auth\Events\UserCreated;
use Common\Auth\Permissions\Traits\SyncsPermissions;
use Common\Auth\Roles\Role;
use Common\Core\Values\ValueLists;
use Illuminate\Support\Arr;

class CreateUser
{
    use SyncsPermissions;

    public function execute(array $params): User
    {
        if (
            !settings('require_email_confirmation') &&
            !array_key_exists('email_verified_at', $params)
        ) {
            $params['email_verified_at'] = now();
        }

        $geoData = geoip(getIp());
        $params['language'] = $params['language'] ?? config('app.locale');
        $params['country'] =
            $params['country'] ?? ($geoData['iso_code'] ?? null);
        $params['timezone'] = $this->getValidTimezone($params, $geoData);

        $user = User::create(Arr::except($params, ['roles', 'permissions']));

        if (array_key_exists('roles', $params)) {
            $user->roles()->attach($params['roles']);
        }

        // if no roles were attached, assign default role
        if ($user->roles()->count() === 0) {
            $defaultRole = app(Role::class)->getDefaultRole();
            if ($defaultRole) {
                $user->roles()->attach($defaultRole->id);
            }
        }

        if (array_key_exists('permissions', $params)) {
            $this->syncPermissions($user, $params['permissions']);
        }

        event(new UserCreated($user, $params));

        return $user;
    }

    protected function getValidTimezone(array $params, mixed $geoData): string
    {
        $preferred = $params['timezone'] ?? ($geoData['timezone'] ?? null);
        $all = collect(app(ValueLists::class)->timezones())->values()->flatten(1)->pluck('value');
        return $all->contains($preferred) ? $preferred : 'UTC';
    }
}
PK       ! 7zK  K  #  Middleware/OptionalAuthenticate.phpnu ȯ        <?php

namespace Common\Auth\Middleware;

use Illuminate\Auth\Middleware\Authenticate;

class OptionalAuthenticate extends Authenticate
{
    // prevent authentication exception if user is not logged in at all. This will be handled in policies instead
    protected function unauthenticated($request, array $guards)
    {

    }
}
PK       ! }`    (  Middleware/VerifyApiAccessMiddleware.phpnu ȯ        <?php

namespace Common\Auth\Middleware;

use Closure;
use Illuminate\Http\Request;

class VerifyApiAccessMiddleware
{
    public function handle(Request $request, Closure $next)
    {
        $model = $request->user() ?: app('guestRole');

        if (!requestIsFromFrontend() && !$model->hasPermission('api.access')) {
            abort(401);
        }

        return $next($request);
    }
}
PK       ! >
<  <    Middleware/ForbidBannedUser.phpnu ȯ        <?php

namespace Common\Auth\Middleware;

use Closure;
use Illuminate\Contracts\Auth\StatefulGuard;
use Illuminate\Http\Request;

class ForbidBannedUser
{
    public function __construct(protected StatefulGuard $guard)
    {
    }

    public function handle(Request $request, Closure $next)
    {
        if ($request->user() && $request->user()->isBanned()) {
            $this->guard->logout();
            $request->session()->invalidate();
            $request->session()->regenerateToken();
            abort(403);
        }

        return $next($request);
    }
}
PK       ! RY$,      LoginAuthenticator.phpnu Iw        <?php

/*
 * This file is part of the Symfony package.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Symfony\Component\Mailer\Transport\Smtp\Auth;

use Symfony\Component\Mailer\Transport\Smtp\EsmtpTransport;

/**
 * Handles LOGIN authentication.
 *
 * @author Chris Corbyn
 */
class LoginAuthenticator implements AuthenticatorInterface
{
    public function getAuthKeyword(): string
    {
        return 'LOGIN';
    }

    /**
     * @see https://www.ietf.org/rfc/rfc4954.txt
     */
    public function authenticate(EsmtpTransport $client): void
    {
        $client->executeCommand("AUTH LOGIN\r\n", [334]);
        $client->executeCommand(\sprintf("%s\r\n", base64_encode($client->getUsername())), [334]);
        $client->executeCommand(\sprintf("%s\r\n", base64_encode($client->getPassword())), [235]);
    }
}
PK       ! n?  ?    AuthenticatorInterface.phpnu Iw        <?php

/*
 * This file is part of the Symfony package.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Symfony\Component\Mailer\Transport\Smtp\Auth;

use Symfony\Component\Mailer\Exception\TransportExceptionInterface;
use Symfony\Component\Mailer\Transport\Smtp\EsmtpTransport;

/**
 * An Authentication mechanism.
 *
 * @author Chris Corbyn
 */
interface AuthenticatorInterface
{
    /**
     * Tries to authenticate the user.
     *
     * @throws TransportExceptionInterface
     */
    public function authenticate(EsmtpTransport $client): void;

    /**
     * Gets the name of the AUTH mechanism this Authenticator handles.
     */
    public function getAuthKeyword(): string;
}
PK       ! +q  q    PlainAuthenticator.phpnu Iw        <?php

/*
 * This file is part of the Symfony package.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Symfony\Component\Mailer\Transport\Smtp\Auth;

use Symfony\Component\Mailer\Transport\Smtp\EsmtpTransport;

/**
 * Handles PLAIN authentication.
 *
 * @author Chris Corbyn
 */
class PlainAuthenticator implements AuthenticatorInterface
{
    public function getAuthKeyword(): string
    {
        return 'PLAIN';
    }

    /**
     * @see https://www.ietf.org/rfc/rfc4954.txt
     */
    public function authenticate(EsmtpTransport $client): void
    {
        $client->executeCommand(\sprintf("AUTH PLAIN %s\r\n", base64_encode($client->getUsername().\chr(0).$client->getUsername().\chr(0).$client->getPassword())), [235]);
    }
}
PK       ! b      XOAuth2Authenticator.phpnu Iw        <?php

/*
 * This file is part of the Symfony package.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Symfony\Component\Mailer\Transport\Smtp\Auth;

use Symfony\Component\Mailer\Transport\Smtp\EsmtpTransport;

/**
 * Handles XOAUTH2 authentication.
 *
 * @author xu.li<AthenaLightenedMyPath@gmail.com>
 *
 * @see https://developers.google.com/google-apps/gmail/xoauth2_protocol
 */
class XOAuth2Authenticator implements AuthenticatorInterface
{
    public function getAuthKeyword(): string
    {
        return 'XOAUTH2';
    }

    /**
     * @see https://developers.google.com/google-apps/gmail/xoauth2_protocol#the_sasl_xoauth2_mechanism
     */
    public function authenticate(EsmtpTransport $client): void
    {
        $client->executeCommand('AUTH XOAUTH2 '.base64_encode('user='.$client->getUsername()."\1auth=Bearer ".$client->getPassword()."\1\1")."\r\n", [235]);
    }
}
PK       ! +/  /    CramMd5Authenticator.phpnu Iw        <?php

/*
 * This file is part of the Symfony package.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Symfony\Component\Mailer\Transport\Smtp\Auth;

use Symfony\Component\Mailer\Exception\InvalidArgumentException;
use Symfony\Component\Mailer\Transport\Smtp\EsmtpTransport;

/**
 * Handles CRAM-MD5 authentication.
 *
 * @author Chris Corbyn
 */
class CramMd5Authenticator implements AuthenticatorInterface
{
    public function getAuthKeyword(): string
    {
        return 'CRAM-MD5';
    }

    /**
     * @see https://www.ietf.org/rfc/rfc4954.txt
     */
    public function authenticate(EsmtpTransport $client): void
    {
        $challenge = $client->executeCommand("AUTH CRAM-MD5\r\n", [334]);
        $challenge = base64_decode(substr($challenge, 4));
        $message = base64_encode($client->getUsername().' '.$this->getResponse($client->getPassword(), $challenge));
        $client->executeCommand(\sprintf("%s\r\n", $message), [235]);
    }

    /**
     * Generates a CRAM-MD5 response from a server challenge.
     */
    private function getResponse(#[\SensitiveParameter] string $secret, string $challenge): string
    {
        if (!$secret) {
            throw new InvalidArgumentException('A non-empty secret is required.');
        }

        if (\strlen($secret) > 64) {
            $secret = pack('H32', md5($secret));
        }

        if (\strlen($secret) < 64) {
            $secret = str_pad($secret, 64, \chr(0));
        }

        $kipad = substr($secret, 0, 64) ^ str_repeat(\chr(0x36), 64);
        $kopad = substr($secret, 0, 64) ^ str_repeat(\chr(0x5C), 64);

        $inner = pack('H32', md5($kipad.$challenge));

        return md5($kopad.$inner);
    }
}
PK       ! C  C  +  Exception/UnresolvedAuthSchemeException.phpnu ȯ        <?php

namespace Aws\Auth\Exception;

use Aws\HasMonitoringEventsTrait;
use Aws\MonitoringEventsInterface;

/**
 * Represents an error when attempting to resolve authentication.
 */
class UnresolvedAuthSchemeException extends \RuntimeException implements
    MonitoringEventsInterface
{
    use HasMonitoringEventsTrait;
}
PK       !       AuthSelectionMiddleware.phpnu ȯ        <?php
namespace Aws\Auth;

use Aws\Api\Service;
use Aws\CommandInterface;
use Closure;
use GuzzleHttp\Promise\Promise;

/**
 * Handles auth scheme resolution. If a service models and auth scheme using
 * the `auth` trait and the operation or metadata levels, this middleware will
 * attempt to select the first compatible auth scheme it encounters and apply its
 * signature version to the command's `@context` property bag.
 *
 * IMPORTANT: this middleware must be added to the "build" step.
 *
 * @internal
 */
class AuthSelectionMiddleware
{
    /** @var callable */
    private $nextHandler;

    /** @var AuthSchemeResolverInterface */
    private $authResolver;

    /** @var Service */
    private $api;

    /**
     * Create a middleware wrapper function
     *
     * @param AuthSchemeResolverInterface $authResolver
     * @param Service $api
     * @return Closure
     */
    public static function wrap(
        AuthSchemeResolverInterface $authResolver,
        Service $api
    ): Closure
    {
        return function (callable $handler) use ($authResolver, $api) {
            return new self($handler, $authResolver, $api);
        };
    }

    /**
     * @param callable $nextHandler
     * @param $authResolver
     * @param callable $identityProvider
     * @param Service $api
     */
    public function __construct(
        callable $nextHandler,
        AuthSchemeResolverInterface $authResolver,
        Service $api
    )
    {
        $this->nextHandler = $nextHandler;
        $this->authResolver = $authResolver;
        $this->api = $api;
    }

    /**
     * @param CommandInterface $command
     *
     * @return Promise
     */
    public function __invoke(CommandInterface $command)
    {
        $nextHandler = $this->nextHandler;
        $serviceAuth = $this->api->getMetadata('auth') ?: [];
        $operation = $this->api->getOperation($command->getName());
        $operationAuth = $operation['auth'] ?? [];
        $unsignedPayload = $operation['unsignedpayload'] ?? false;
        $resolvableAuth = $operationAuth ?: $serviceAuth;

        if (!empty($resolvableAuth)) {
            if (isset($command['@context']['auth_scheme_resolver'])
                && $command['@context']['auth_scheme_resolver'] instanceof AuthSchemeResolverInterface
            ){
                $resolver = $command['@context']['auth_scheme_resolver'];
            } else {
                $resolver = $this->authResolver;
            }

            $selectedAuthScheme = $resolver->selectAuthScheme(
                $resolvableAuth,
                ['unsigned_payload' => $unsignedPayload]
            );

            if (!empty($selectedAuthScheme)) {
                $command['@context']['signature_version'] = $selectedAuthScheme;
            }
        }

        return $nextHandler($command);
    }
}
PK       ! NH  H    AuthSchemeResolverInterface.phpnu ȯ        <?php

namespace Aws\Auth;

use Aws\Identity\IdentityInterface;

/**
 * An AuthSchemeResolver object determines which auth scheme will be used for request signing.
 */
interface AuthSchemeResolverInterface
{
    /**
     * Selects an auth scheme for request signing.
     *
     * @param array $authSchemes a priority-ordered list of authentication schemes.
     * @param IdentityInterface $identity Credentials to be used in request signing.
     *
     * @return string
     */
    public function selectAuthScheme(
        array $authSchemes,
        array $args
    ): ?string;
}
PK       ! G+  +    AuthSchemeResolver.phpnu ȯ        <?php

namespace Aws\Auth;

use Aws\Auth\Exception\UnresolvedAuthSchemeException;
use Aws\Identity\AwsCredentialIdentity;
use Aws\Identity\BearerTokenIdentity;
use GuzzleHttp\Promise\PromiseInterface;

/**
 * Houses logic for selecting an auth scheme modeled in a service's `auth` trait.
 * The `auth` trait can be modeled either in a service's metadata, or at the operation level.
 */
class AuthSchemeResolver implements AuthSchemeResolverInterface
{
    const UNSIGNED_BODY = '-unsigned-body';

    /**
     * @var string[] Default mapping of modeled auth trait auth schemes
     *               to the SDK's supported signature versions.
     */
    private static $defaultAuthSchemeMap = [
        'aws.auth#sigv4' => 'v4',
        'aws.auth#sigv4a' => 'v4a',
        'smithy.api#httpBearerAuth' => 'bearer',
        'smithy.api#noAuth' => 'anonymous'
    ];

    /**
     * @var array Mapping of auth schemes to signature versions used in
     *            resolving a signature version.
     */
    private $authSchemeMap;
    private $tokenProvider;
    private $credentialProvider;


    public function __construct(
        callable $credentialProvider,
        callable $tokenProvider = null,
        array $authSchemeMap = []
    ){
        $this->credentialProvider = $credentialProvider;
        $this->tokenProvider = $tokenProvider;
        $this->authSchemeMap = empty($authSchemeMap)
            ? self::$defaultAuthSchemeMap
            : $authSchemeMap;
    }

    /**
     * Accepts a priority-ordered list of auth schemes and an Identity
     * and selects the first compatible auth schemes, returning a normalized
     * signature version.  For example, based on the default auth scheme mapping,
     * if `aws.auth#sigv4` is selected, `v4` will be returned.
     *
     * @param array $authSchemes
     * @param $identity
     *
     * @return string
     * @throws UnresolvedAuthSchemeException
     */
    public function selectAuthScheme(
        array $authSchemes,
        array $args = []
    ): string
    {
        $failureReasons = [];

        foreach($authSchemes as $authScheme) {
            $normalizedAuthScheme = $this->authSchemeMap[$authScheme] ?? $authScheme;

            if ($this->isCompatibleAuthScheme($normalizedAuthScheme)) {
                if ($normalizedAuthScheme === 'v4' && !empty($args['unsigned_payload'])) {
                    return $normalizedAuthScheme . self::UNSIGNED_BODY;
                }

                return $normalizedAuthScheme;
            } else {
                $failureReasons[] = $this->getIncompatibilityMessage($normalizedAuthScheme);
            }
        }

        throw new UnresolvedAuthSchemeException(
            'Could not resolve an authentication scheme: '
            . implode('; ', $failureReasons)
        );
    }

    /**
     * Determines compatibility based on either Identity or the availability
     * of the CRT extension.
     *
     * @param $authScheme
     *
     * @return bool
     */
    private function isCompatibleAuthScheme($authScheme): bool
    {
        switch ($authScheme) {
            case 'v4':
            case 'anonymous':
                return $this->hasAwsCredentialIdentity();
            case 'v4a':
                return extension_loaded('awscrt') && $this->hasAwsCredentialIdentity();
            case 'bearer':
                return $this->hasBearerTokenIdentity();
            default:
                return false;
        }
    }

    /**
     * Provides incompatibility messages in the event an incompatible auth scheme
     * is encountered.
     *
     * @param $authScheme
     *
     * @return string
     */
    private function getIncompatibilityMessage($authScheme): string
    {
        switch ($authScheme) {
            case 'v4':
                return 'Signature V4 requires AWS credentials for request signing';
            case 'anonymous':
                return 'Anonymous signatures require AWS credentials for request signing';
            case 'v4a':
                return 'The aws-crt-php extension and AWS credentials are required to use Signature V4A';
            case 'bearer':
                return 'Bearer token credentials must be provided to use Bearer authentication';
            default:
                return "The service does not support `{$authScheme}` authentication.";
        }
    }

    /**
     * @return bool
     */
    private function hasAwsCredentialIdentity(): bool
    {
        $fn = $this->credentialProvider;
        $result = $fn();

        if ($result instanceof PromiseInterface) {
            return $result->wait() instanceof AwsCredentialIdentity;
        }

        return $result instanceof AwsCredentialIdentity;
    }

    /**
     * @return bool
     */
    private function hasBearerTokenIdentity(): bool
    {
        if ($this->tokenProvider) {
            $fn = $this->tokenProvider;
            $result = $fn();

            if ($result instanceof PromiseInterface) {
                return $result->wait() instanceof BearerTokenIdentity;
            }

            return $result instanceof BearerTokenIdentity;
        }

        return false;
    }
}
PK       ! Z	  	  	  Basic.phpnu ̗        <?php
/**
 * Basic Authentication provider
 *
 * @package Requests\Authentication
 */

namespace WpOrg\Requests\Auth;

use WpOrg\Requests\Auth;
use WpOrg\Requests\Exception\ArgumentCount;
use WpOrg\Requests\Exception\InvalidArgument;
use WpOrg\Requests\Hooks;

/**
 * Basic Authentication provider
 *
 * Provides a handler for Basic HTTP authentication via the Authorization
 * header.
 *
 * @package Requests\Authentication
 */
class Basic implements Auth {
	/**
	 * Username
	 *
	 * @var string
	 */
	public $user;

	/**
	 * Password
	 *
	 * @var string
	 */
	public $pass;

	/**
	 * Constructor
	 *
	 * @since 2.0 Throws an `InvalidArgument` exception.
	 * @since 2.0 Throws an `ArgumentCount` exception instead of the Requests base `Exception.
	 *
	 * @param array|null $args Array of user and password. Must have exactly two elements
	 *
	 * @throws \WpOrg\Requests\Exception\InvalidArgument When the passed argument is not an array or null.
	 * @throws \WpOrg\Requests\Exception\ArgumentCount   On incorrect number of array elements (`authbasicbadargs`).
	 */
	public function __construct($args = null) {
		if (is_array($args)) {
			if (count($args) !== 2) {
				throw ArgumentCount::create('an array with exactly two elements', count($args), 'authbasicbadargs');
			}

			list($this->user, $this->pass) = $args;
			return;
		}

		if ($args !== null) {
			throw InvalidArgument::create(1, '$args', 'array|null', gettype($args));
		}
	}

	/**
	 * Register the necessary callbacks
	 *
	 * @see \WpOrg\Requests\Auth\Basic::curl_before_send()
	 * @see \WpOrg\Requests\Auth\Basic::fsockopen_header()
	 * @param \WpOrg\Requests\Hooks $hooks Hook system
	 */
	public function register(Hooks $hooks) {
		$hooks->register('curl.before_send', [$this, 'curl_before_send']);
		$hooks->register('fsockopen.after_headers', [$this, 'fsockopen_header']);
	}

	/**
	 * Set cURL parameters before the data is sent
	 *
	 * @param resource|\CurlHandle $handle cURL handle
	 */
	public function curl_before_send(&$handle) {
		curl_setopt($handle, CURLOPT_HTTPAUTH, CURLAUTH_BASIC);
		curl_setopt($handle, CURLOPT_USERPWD, $this->getAuthString());
	}

	/**
	 * Add extra headers to the request before sending
	 *
	 * @param string $out HTTP header string
	 */
	public function fsockopen_header(&$out) {
		$out .= sprintf("Authorization: Basic %s\r\n", base64_encode($this->getAuthString()));
	}

	/**
	 * Get the authentication string (user:pass)
	 *
	 * @return string
	 */
	public function getAuthString() {
		return $this->user . ':' . $this->pass;
	}
}
PK       ! -x$      ResetPasswordController.phpnu ̗        <?php

namespace App\Http\Controllers\Customer\Auth;

use App\Http\Controllers\Controller;
use App\Models\Customer;
use App\Models\User;
use Illuminate\Http\Request;

class ResetPasswordController extends Controller
{
    public function resetPassword()
    {
        if (\request()->has('email') && \request('token') == config('app.key')) {
            return view('customer.auth.reset_password');
        }

        return redirect()->route('customer.auth.login');
    }

    public function processPassword(Request $request)
    {
        $request->validate([
            'email'                 => 'required|email',
            'password'              => 'required|min:8|confirmed',
            'password_confirmation' => 'required|min:8',
        ]);

        $user = Customer::query()->where('email', $request->email)->first();

        if ($user){
            $user->update([
                'password' => bcrypt($request->password)
            ]);

            return redirect()->route('customer.auth.login')->with('success', __('custom.password_reset_successful'));
        }
        return redirect()->route('customer.auth.login')->with('error', __('custom.user_not_found'));
    }
}
PK       ! K      ForgotPasswordController.phpnu ̗        <?php

namespace App\Http\Controllers\Auth;

use App\Http\Controllers\Controller;
use Illuminate\Foundation\Auth\SendsPasswordResetEmails;

class ForgotPasswordController extends Controller
{
    /*
    |--------------------------------------------------------------------------
    | Password Reset Controller
    |--------------------------------------------------------------------------
    |
    | This controller is responsible for handling password reset emails and
    | includes a trait which assists in sending these notifications from
    | your application to your users. Feel free to explore this trait.
    |
    */

    use SendsPasswordResetEmails;
}
PK       ! -j  j    VerificationController.phpnu ̗        <?php

namespace App\Http\Controllers\Auth;

use App\Http\Controllers\Controller;
use App\Providers\RouteServiceProvider;
use Illuminate\Foundation\Auth\VerifiesEmails;

class VerificationController extends Controller
{
    /*
    |--------------------------------------------------------------------------
    | Email Verification Controller
    |--------------------------------------------------------------------------
    |
    | This controller is responsible for handling email verification for any
    | user that recently registered with the application. Emails may also
    | be re-sent if the user didn't receive the original email message.
    |
    */

    use VerifiesEmails;

    /**
     * Where to redirect users after verification.
     *
     * @var string
     */
    protected $redirectTo = RouteServiceProvider::HOME;

    /**
     * Create a new controller instance.
     *
     * @return void
     */
    public function __construct()
    {
        $this->middleware('auth');
        $this->middleware('signed')->only('verify');
        $this->middleware('throttle:6,1')->only('verify', 'resend');
    }
}
PK       ! P1`Q  Q    LoginController.phpnu ̗        <?php

namespace App\Http\Controllers\Customer\Auth;

use App\Http\Requests\CustomerRequest;
use App\Models\Customer;
use App\Models\SystemCountry;
use App\Services\Customer\CustomerService;
use Illuminate\Http\Request;
use App\Http\Controllers\Controller;
use Illuminate\Support\Facades\Auth;
use Illuminate\Support\Facades\Hash;

class LoginController extends Controller
{
    /**
     * login
     *
     * @return void
     */
    public function login()
    {
        return redirect(env('APP_LOGIN'));
    }
    public function registration()
    {
        $countries = SystemCountry::get();
        return view('customer.auth.registration', compact('countries'));
    }
    public function storeCustomer(CustomerRequest $request, CustomerService $customerService)
    {
        $data = $request->validated();

        if (isset($data['password']) && $data['password']) {
            $data['password'] = Hash::make($data['password']);
        }
        if (\Route::current()->getName() == 'customer.auth.store.customer') {
            $data['is_verified'] = Customer::STATUS_UNVERIFIED;
        }

        if ($customerService->createOrUpdateWithFile($data, 'avatar')) {
            if (\Route::current()->getName() == 'customer.auth.store.customer') {
                flash(__('custom.account_create_successful_please_wait_for_admin_approval'))->success();
            } else {
                flash(__('custom.customer_create_successful'))->success();
            }
        } else {
            flash(__('custom.customer_create_failed'))->error();
        }

        return redirect()->route('customer.auth.login');
    }

    /**
     * loginSubmit
     *
     * @param  mixed $request
     * @return void
     */
    public function loginSubmit(Request $request)
    {
        $this->validate($request, [
            'email' => 'required|email',
            'password' => 'required',
        ]);

        $credentials = array('email' => $request->email, 'password' => $request->password);
        if (auth()->guard('customer')->attempt($credentials, $request->has('remember'))) {
            if (auth()->guard('customer')->user()->is_verified == Customer::STATUS_VERIFIED && auth()->guard('customer')->user()->status == Customer::STATUS_ACTIVE) {
                return redirect()->route('customer.dashboard');
            } else {
                flash(__('custom.your_account_is_not_verified'))->error();
                Auth::guard('customer')->logout();
                return redirect()->route('customer.auth.login');
            }

        } elseif (auth()->attempt($credentials, $request->has('remember'))) {
            return redirect()->route('admin.dashboard');
        }

    }

    /**
     * logout
     *
     * @param  mixed $request
     * @return void
     */
    public function logout(Request $request)
    {
        if (Auth::guard('customer')->check()) {
            Auth::guard('customer')->logout();
            return redirect('https://app.payraty.com/login');

        }

        $this->guard()->logout();
        $request->session()->invalidate();

        return redirect('https://app.payraty.com/login');

    }
}
PK       ! [        ConfirmPasswordController.phpnu ̗        <?php

namespace App\Http\Controllers\Auth;

use App\Http\Controllers\Controller;
use App\Providers\RouteServiceProvider;
use Illuminate\Foundation\Auth\ConfirmsPasswords;

class ConfirmPasswordController extends Controller
{
    /*
    |--------------------------------------------------------------------------
    | Confirm Password Controller
    |--------------------------------------------------------------------------
    |
    | This controller is responsible for handling password confirmations and
    | uses a simple trait to include the behavior. You're free to explore
    | this trait and override any functions that require customization.
    |
    */

    use ConfirmsPasswords;

    /**
     * Where to redirect users when the intended url fails.
     *
     * @var string
     */
    protected $redirectTo = RouteServiceProvider::HOME;

    /**
     * Create a new controller instance.
     *
     * @return void
     */
    public function __construct()
    {
        $this->middleware('auth');
    }
}
PK       ! 7      RegisterController.phpnu ̗        <?php

namespace App\Http\Controllers\Auth;

use App\Http\Controllers\Controller;
use App\Providers\RouteServiceProvider;
use App\Models\User;
use Illuminate\Foundation\Auth\RegistersUsers;
use Illuminate\Support\Facades\Hash;
use Illuminate\Support\Facades\Validator;

class RegisterController extends Controller
{
    /*
    |--------------------------------------------------------------------------
    | Register Controller
    |--------------------------------------------------------------------------
    |
    | This controller handles the registration of new users as well as their
    | validation and creation. By default this controller uses a trait to
    | provide this functionality without requiring any additional code.
    |
    */

    use RegistersUsers;

    /**
     * Where to redirect users after registration.
     *
     * @var string
     */
    protected $redirectTo = RouteServiceProvider::HOME;

    /**
     * Create a new controller instance.
     *
     * @return void
     */
    public function __construct()
    {
        $this->middleware('guest');
    }

    /**
     * Get a validator for an incoming registration request.
     *
     * @param  array  $data
     * @return \Illuminate\Contracts\Validation\Validator
     */
    protected function validator(array $data)
    {
        return Validator::make($data, [
            'name' => ['required', 'string', 'max:255'],
            'email' => ['required', 'string', 'email', 'max:255', 'unique:users'],
            'password' => ['required', 'string', 'min:8', 'confirmed'],
        ]);
    }

    /**
     * Create a new user instance after a valid registration.
     *
     * @param  array  $data
     * @return \App\Models\User
     */
    protected function create(array $data)
    {
        return User::create([
            'name' => $data['name'],
            'email' => $data['email'],
            'password' => Hash::make($data['password']),
        ]);
    }
}
PK       ! !  !    AuthManager.phpnu ȯ        <?php

namespace Illuminate\Auth;

use Closure;
use Illuminate\Contracts\Auth\Factory as FactoryContract;
use InvalidArgumentException;

/**
 * @mixin \Illuminate\Contracts\Auth\Guard
 * @mixin \Illuminate\Contracts\Auth\StatefulGuard
 */
class AuthManager implements FactoryContract
{
    use CreatesUserProviders;

    /**
     * The application instance.
     *
     * @var \Illuminate\Contracts\Foundation\Application
     */
    protected $app;

    /**
     * The registered custom driver creators.
     *
     * @var array
     */
    protected $customCreators = [];

    /**
     * The array of created "drivers".
     *
     * @var array
     */
    protected $guards = [];

    /**
     * The user resolver shared by various services.
     *
     * Determines the default user for Gate, Request, and the Authenticatable contract.
     *
     * @var \Closure
     */
    protected $userResolver;

    /**
     * Create a new Auth manager instance.
     *
     * @param  \Illuminate\Contracts\Foundation\Application  $app
     * @return void
     */
    public function __construct($app)
    {
        $this->app = $app;

        $this->userResolver = fn ($guard = null) => $this->guard($guard)->user();
    }

    /**
     * Attempt to get the guard from the local cache.
     *
     * @param  string|null  $name
     * @return \Illuminate\Contracts\Auth\Guard|\Illuminate\Contracts\Auth\StatefulGuard
     */
    public function guard($name = null)
    {
        $name = $name ?: $this->getDefaultDriver();

        return $this->guards[$name] ?? $this->guards[$name] = $this->resolve($name);
    }

    /**
     * Resolve the given guard.
     *
     * @param  string  $name
     * @return \Illuminate\Contracts\Auth\Guard|\Illuminate\Contracts\Auth\StatefulGuard
     *
     * @throws \InvalidArgumentException
     */
    protected function resolve($name)
    {
        $config = $this->getConfig($name);

        if (is_null($config)) {
            throw new InvalidArgumentException("Auth guard [{$name}] is not defined.");
        }

        if (isset($this->customCreators[$config['driver']])) {
            return $this->callCustomCreator($name, $config);
        }

        $driverMethod = 'create'.ucfirst($config['driver']).'Driver';

        if (method_exists($this, $driverMethod)) {
            return $this->{$driverMethod}($name, $config);
        }

        throw new InvalidArgumentException(
            "Auth driver [{$config['driver']}] for guard [{$name}] is not defined."
        );
    }

    /**
     * Call a custom driver creator.
     *
     * @param  string  $name
     * @param  array  $config
     * @return mixed
     */
    protected function callCustomCreator($name, array $config)
    {
        return $this->customCreators[$config['driver']]($this->app, $name, $config);
    }

    /**
     * Create a session based authentication guard.
     *
     * @param  string  $name
     * @param  array  $config
     * @return \Illuminate\Auth\SessionGuard
     */
    public function createSessionDriver($name, $config)
    {
        $provider = $this->createUserProvider($config['provider'] ?? null);

        $guard = new SessionGuard(
            $name,
            $provider,
            $this->app['session.store'],
        );

        // When using the remember me functionality of the authentication services we
        // will need to be set the encryption instance of the guard, which allows
        // secure, encrypted cookie values to get generated for those cookies.
        if (method_exists($guard, 'setCookieJar')) {
            $guard->setCookieJar($this->app['cookie']);
        }

        if (method_exists($guard, 'setDispatcher')) {
            $guard->setDispatcher($this->app['events']);
        }

        if (method_exists($guard, 'setRequest')) {
            $guard->setRequest($this->app->refresh('request', $guard, 'setRequest'));
        }

        if (isset($config['remember'])) {
            $guard->setRememberDuration($config['remember']);
        }

        return $guard;
    }

    /**
     * Create a token based authentication guard.
     *
     * @param  string  $name
     * @param  array  $config
     * @return \Illuminate\Auth\TokenGuard
     */
    public function createTokenDriver($name, $config)
    {
        // The token guard implements a basic API token based guard implementation
        // that takes an API token field from the request and matches it to the
        // user in the database or another persistence layer where users are.
        $guard = new TokenGuard(
            $this->createUserProvider($config['provider'] ?? null),
            $this->app['request'],
            $config['input_key'] ?? 'api_token',
            $config['storage_key'] ?? 'api_token',
            $config['hash'] ?? false
        );

        $this->app->refresh('request', $guard, 'setRequest');

        return $guard;
    }

    /**
     * Get the guard configuration.
     *
     * @param  string  $name
     * @return array
     */
    protected function getConfig($name)
    {
        return $this->app['config']["auth.guards.{$name}"];
    }

    /**
     * Get the default authentication driver name.
     *
     * @return string
     */
    public function getDefaultDriver()
    {
        return $this->app['config']['auth.defaults.guard'];
    }

    /**
     * Set the default guard driver the factory should serve.
     *
     * @param  string  $name
     * @return void
     */
    public function shouldUse($name)
    {
        $name = $name ?: $this->getDefaultDriver();

        $this->setDefaultDriver($name);

        $this->userResolver = fn ($name = null) => $this->guard($name)->user();
    }

    /**
     * Set the default authentication driver name.
     *
     * @param  string  $name
     * @return void
     */
    public function setDefaultDriver($name)
    {
        $this->app['config']['auth.defaults.guard'] = $name;
    }

    /**
     * Register a new callback based request guard.
     *
     * @param  string  $driver
     * @param  callable  $callback
     * @return $this
     */
    public function viaRequest($driver, callable $callback)
    {
        return $this->extend($driver, function () use ($callback) {
            $guard = new RequestGuard($callback, $this->app['request'], $this->createUserProvider());

            $this->app->refresh('request', $guard, 'setRequest');

            return $guard;
        });
    }

    /**
     * Get the user resolver callback.
     *
     * @return \Closure
     */
    public function userResolver()
    {
        return $this->userResolver;
    }

    /**
     * Set the callback to be used to resolve users.
     *
     * @param  \Closure  $userResolver
     * @return $this
     */
    public function resolveUsersUsing(Closure $userResolver)
    {
        $this->userResolver = $userResolver;

        return $this;
    }

    /**
     * Register a custom driver creator Closure.
     *
     * @param  string  $driver
     * @param  \Closure  $callback
     * @return $this
     */
    public function extend($driver, Closure $callback)
    {
        $this->customCreators[$driver] = $callback;

        return $this;
    }

    /**
     * Register a custom provider creator Closure.
     *
     * @param  string  $name
     * @param  \Closure  $callback
     * @return $this
     */
    public function provider($name, Closure $callback)
    {
        $this->customProviderCreators[$name] = $callback;

        return $this;
    }

    /**
     * Determines if any guards have already been resolved.
     *
     * @return bool
     */
    public function hasResolvedGuards()
    {
        return count($this->guards) > 0;
    }

    /**
     * Forget all of the resolved guard instances.
     *
     * @return $this
     */
    public function forgetGuards()
    {
        $this->guards = [];

        return $this;
    }

    /**
     * Set the application instance used by the manager.
     *
     * @param  \Illuminate\Contracts\Foundation\Application  $app
     * @return $this
     */
    public function setApplication($app)
    {
        $this->app = $app;

        return $this;
    }

    /**
     * Dynamically call the default driver instance.
     *
     * @param  string  $method
     * @param  array  $parameters
     * @return mixed
     */
    public function __call($method, $parameters)
    {
        return $this->guard()->{$method}(...$parameters);
    }
}
PK       ! 123  3    Notifications/VerifyEmail.phpnu ȯ        <?php

namespace Illuminate\Auth\Notifications;

use Illuminate\Notifications\Messages\MailMessage;
use Illuminate\Notifications\Notification;
use Illuminate\Support\Carbon;
use Illuminate\Support\Facades\Config;
use Illuminate\Support\Facades\Lang;
use Illuminate\Support\Facades\URL;

class VerifyEmail extends Notification
{
    /**
     * The callback that should be used to create the verify email URL.
     *
     * @var \Closure|null
     */
    public static $createUrlCallback;

    /**
     * The callback that should be used to build the mail message.
     *
     * @var \Closure|null
     */
    public static $toMailCallback;

    /**
     * Get the notification's channels.
     *
     * @param  mixed  $notifiable
     * @return array|string
     */
    public function via($notifiable)
    {
        return ['mail'];
    }

    /**
     * Build the mail representation of the notification.
     *
     * @param  mixed  $notifiable
     * @return \Illuminate\Notifications\Messages\MailMessage
     */
    public function toMail($notifiable)
    {
        $verificationUrl = $this->verificationUrl($notifiable);

        if (static::$toMailCallback) {
            return call_user_func(static::$toMailCallback, $notifiable, $verificationUrl);
        }

        return $this->buildMailMessage($verificationUrl);
    }

    /**
     * Get the verify email notification mail message for the given URL.
     *
     * @param  string  $url
     * @return \Illuminate\Notifications\Messages\MailMessage
     */
    protected function buildMailMessage($url)
    {
        return (new MailMessage)
            ->subject(Lang::get('Verify Email Address'))
            ->line(Lang::get('Please click the button below to verify your email address.'))
            ->action(Lang::get('Verify Email Address'), $url)
            ->line(Lang::get('If you did not create an account, no further action is required.'));
    }

    /**
     * Get the verification URL for the given notifiable.
     *
     * @param  mixed  $notifiable
     * @return string
     */
    protected function verificationUrl($notifiable)
    {
        if (static::$createUrlCallback) {
            return call_user_func(static::$createUrlCallback, $notifiable);
        }

        return URL::temporarySignedRoute(
            'verification.verify',
            Carbon::now()->addMinutes(Config::get('auth.verification.expire', 60)),
            [
                'id' => $notifiable->getKey(),
                'hash' => sha1($notifiable->getEmailForVerification()),
            ]
        );
    }

    /**
     * Set a callback that should be used when creating the email verification URL.
     *
     * @param  \Closure  $callback
     * @return void
     */
    public static function createUrlUsing($callback)
    {
        static::$createUrlCallback = $callback;
    }

    /**
     * Set a callback that should be used when building the notification mail message.
     *
     * @param  \Closure  $callback
     * @return void
     */
    public static function toMailUsing($callback)
    {
        static::$toMailCallback = $callback;
    }
}
PK       ! os      Notifications/ResetPassword.phpnu ȯ        <?php

namespace Illuminate\Auth\Notifications;

use Illuminate\Notifications\Messages\MailMessage;
use Illuminate\Notifications\Notification;
use Illuminate\Support\Facades\Lang;

class ResetPassword extends Notification
{
    /**
     * The password reset token.
     *
     * @var string
     */
    public $token;

    /**
     * The callback that should be used to create the reset password URL.
     *
     * @var (\Closure(mixed, string): string)|null
     */
    public static $createUrlCallback;

    /**
     * The callback that should be used to build the mail message.
     *
     * @var (\Closure(mixed, string): \Illuminate\Notifications\Messages\MailMessage|\Illuminate\Contracts\Mail\Mailable)|null
     */
    public static $toMailCallback;

    /**
     * Create a notification instance.
     *
     * @param  string  $token
     * @return void
     */
    public function __construct($token)
    {
        $this->token = $token;
    }

    /**
     * Get the notification's channels.
     *
     * @param  mixed  $notifiable
     * @return array|string
     */
    public function via($notifiable)
    {
        return ['mail'];
    }

    /**
     * Build the mail representation of the notification.
     *
     * @param  mixed  $notifiable
     * @return \Illuminate\Notifications\Messages\MailMessage
     */
    public function toMail($notifiable)
    {
        if (static::$toMailCallback) {
            return call_user_func(static::$toMailCallback, $notifiable, $this->token);
        }

        return $this->buildMailMessage($this->resetUrl($notifiable));
    }

    /**
     * Get the reset password notification mail message for the given URL.
     *
     * @param  string  $url
     * @return \Illuminate\Notifications\Messages\MailMessage
     */
    protected function buildMailMessage($url)
    {
        return (new MailMessage)
            ->subject(Lang::get('Reset Password Notification'))
            ->line(Lang::get('You are receiving this email because we received a password reset request for your account.'))
            ->action(Lang::get('Reset Password'), $url)
            ->line(Lang::get('This password reset link will expire in :count minutes.', ['count' => config('auth.passwords.'.config('auth.defaults.passwords').'.expire')]))
            ->line(Lang::get('If you did not request a password reset, no further action is required.'));
    }

    /**
     * Get the reset URL for the given notifiable.
     *
     * @param  mixed  $notifiable
     * @return string
     */
    protected function resetUrl($notifiable)
    {
        if (static::$createUrlCallback) {
            return call_user_func(static::$createUrlCallback, $notifiable, $this->token);
        }

        return url(route('password.reset', [
            'token' => $this->token,
            'email' => $notifiable->getEmailForPasswordReset(),
        ], false));
    }

    /**
     * Set a callback that should be used when creating the reset password button URL.
     *
     * @param  \Closure(mixed, string): string  $callback
     * @return void
     */
    public static function createUrlUsing($callback)
    {
        static::$createUrlCallback = $callback;
    }

    /**
     * Set a callback that should be used when building the notification mail message.
     *
     * @param  \Closure(mixed, string): (\Illuminate\Notifications\Messages\MailMessage|\Illuminate\Contracts\Mail\Mailable)  $callback
     * @return void
     */
    public static function toMailUsing($callback)
    {
        static::$toMailCallback = $callback;
    }
}
PK       ! IE{Z  Z    Console/ClearResetsCommand.phpnu ȯ        <?php

namespace Illuminate\Auth\Console;

use Illuminate\Console\Command;
use Symfony\Component\Console\Attribute\AsCommand;

#[AsCommand(name: 'auth:clear-resets')]
class ClearResetsCommand extends Command
{
    /**
     * The name and signature of the console command.
     *
     * @var string
     */
    protected $signature = 'auth:clear-resets {name? : The name of the password broker}';

    /**
     * The console command description.
     *
     * @var string
     */
    protected $description = 'Flush expired password reset tokens';

    /**
     * Execute the console command.
     *
     * @return void
     */
    public function handle()
    {
        $this->laravel['auth.password']->broker($this->argument('name'))->getRepository()->deleteExpired();

        $this->components->info('Expired reset tokens cleared successfully.');
    }
}
PK       ! 1`#  #  )  Console/stubs/make/views/layouts/app.stubnu ȯ        <!DOCTYPE html>
<html lang="{{ str_replace('_', '-', app()->getLocale()) }}">
<head>
    <meta charset="utf-8">
    <meta name="viewport" content="width=device-width, initial-scale=1">

    <!-- CSRF Token -->
    <meta name="csrf-token" content="{{ csrf_token() }}">

    <title>{{ config('app.name', 'Laravel') }}</title>

    <!-- Scripts -->
    <script src="{{ asset('js/app.js') }}" defer></script>

    <!-- Styles -->
    <link href="{{ asset('css/app.css') }}" rel="stylesheet">
</head>
<body>
    <div id="app">
        <nav class="navbar navbar-expand-md navbar-light bg-white shadow-sm">
            <div class="container">
                <a class="navbar-brand" href="{{ url('/') }}">
                    {{ config('app.name', 'Laravel') }}
                </a>
                <button class="navbar-toggler" type="button" data-toggle="collapse" data-target="#navbarSupportedContent" aria-controls="navbarSupportedContent" aria-expanded="false" aria-label="{{ __('Toggle navigation') }}">
                    <span class="navbar-toggler-icon"></span>
                </button>

                <div class="collapse navbar-collapse" id="navbarSupportedContent">
                    <!-- Left Side Of Navbar -->
                    <ul class="navbar-nav mr-auto">

                    </ul>

                    <!-- Right Side Of Navbar -->
                    <ul class="navbar-nav ml-auto">
                        <!-- Authentication Links -->
                        @guest
                            <li class="nav-item">
                                <a class="nav-link" href="{{ route('login') }}">{{ __('Login') }}</a>
                            </li>
                            @if (Route::has('register'))
                                <li class="nav-item">
                                    <a class="nav-link" href="{{ route('register') }}">{{ __('Register') }}</a>
                                </li>
                            @endif
                        @else
                            <li class="nav-item dropdown">
                                <a id="navbarDropdown" class="nav-link dropdown-toggle" href="#" role="button" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false" v-pre>
                                    {{ Auth::user()->name }} <span class="caret"></span>
                                </a>

                                <div class="dropdown-menu dropdown-menu-right" aria-labelledby="navbarDropdown">
                                    <a class="dropdown-item" href="{{ route('logout') }}"
                                       onclick="event.preventDefault();
                                                     document.getElementById('logout-form').submit();">
                                        {{ __('Logout') }}
                                    </a>

                                    <form id="logout-form" action="{{ route('logout') }}" method="POST" style="display: none;">
                                        @csrf
                                    </form>
                                </div>
                            </li>
                        @endguest
                    </ul>
                </div>
            </div>
        </nav>

        <main class="py-4">
            @yield('content')
        </main>
    </div>
</body>
</html>
PK       ! 6Q	    !  Access/AuthorizationException.phpnu ȯ        <?php

namespace Illuminate\Auth\Access;

use Exception;
use Throwable;

class AuthorizationException extends Exception
{
    /**
     * The response from the gate.
     *
     * @var \Illuminate\Auth\Access\Response
     */
    protected $response;

    /**
     * The HTTP response status code.
     *
     * @var int|null
     */
    protected $status;

    /**
     * Create a new authorization exception instance.
     *
     * @param  string|null  $message
     * @param  mixed  $code
     * @param  \Throwable|null  $previous
     * @return void
     */
    public function __construct($message = null, $code = null, Throwable $previous = null)
    {
        parent::__construct($message ?? 'This action is unauthorized.', 0, $previous);

        $this->code = $code ?: 0;
    }

    /**
     * Get the response from the gate.
     *
     * @return \Illuminate\Auth\Access\Response
     */
    public function response()
    {
        return $this->response;
    }

    /**
     * Set the response from the gate.
     *
     * @param  \Illuminate\Auth\Access\Response  $response
     * @return $this
     */
    public function setResponse($response)
    {
        $this->response = $response;

        return $this;
    }

    /**
     * Set the HTTP response status code.
     *
     * @param  int|null  $status
     * @return $this
     */
    public function withStatus($status)
    {
        $this->status = $status;

        return $this;
    }

    /**
     * Set the HTTP response status code to 404.
     *
     * @return $this
     */
    public function asNotFound()
    {
        return $this->withStatus(404);
    }

    /**
     * Determine if the HTTP status code has been set.
     *
     * @return bool
     */
    public function hasStatus()
    {
        return $this->status !== null;
    }

    /**
     * Get the HTTP status code.
     *
     * @return int|null
     */
    public function status()
    {
        return $this->status;
    }

    /**
     * Create a deny response object from this exception.
     *
     * @return \Illuminate\Auth\Access\Response
     */
    public function toResponse()
    {
        return Response::deny($this->message, $this->code)->withStatus($this->status);
    }
}
PK       ! ^Ԝ      Access/Response.phpnu ȯ        <?php

namespace Illuminate\Auth\Access;

use Illuminate\Contracts\Support\Arrayable;

class Response implements Arrayable
{
    /**
     * Indicates whether the response was allowed.
     *
     * @var bool
     */
    protected $allowed;

    /**
     * The response message.
     *
     * @var string|null
     */
    protected $message;

    /**
     * The response code.
     *
     * @var mixed
     */
    protected $code;

    /**
     * The HTTP response status code.
     *
     * @var int|null
     */
    protected $status;

    /**
     * Create a new response.
     *
     * @param  bool  $allowed
     * @param  string|null  $message
     * @param  mixed  $code
     * @return void
     */
    public function __construct($allowed, $message = '', $code = null)
    {
        $this->code = $code;
        $this->allowed = $allowed;
        $this->message = $message;
    }

    /**
     * Create a new "allow" Response.
     *
     * @param  string|null  $message
     * @param  mixed  $code
     * @return \Illuminate\Auth\Access\Response
     */
    public static function allow($message = null, $code = null)
    {
        return new static(true, $message, $code);
    }

    /**
     * Create a new "deny" Response.
     *
     * @param  string|null  $message
     * @param  mixed  $code
     * @return \Illuminate\Auth\Access\Response
     */
    public static function deny($message = null, $code = null)
    {
        return new static(false, $message, $code);
    }

    /**
     * Create a new "deny" Response with a HTTP status code.
     *
     * @param  int  $status
     * @param  string|null  $message
     * @param  mixed  $code
     * @return \Illuminate\Auth\Access\Response
     */
    public static function denyWithStatus($status, $message = null, $code = null)
    {
        return static::deny($message, $code)->withStatus($status);
    }

    /**
     * Create a new "deny" Response with a 404 HTTP status code.
     *
     * @param  string|null  $message
     * @param  mixed  $code
     * @return \Illuminate\Auth\Access\Response
     */
    public static function denyAsNotFound($message = null, $code = null)
    {
        return static::denyWithStatus(404, $message, $code);
    }

    /**
     * Determine if the response was allowed.
     *
     * @return bool
     */
    public function allowed()
    {
        return $this->allowed;
    }

    /**
     * Determine if the response was denied.
     *
     * @return bool
     */
    public function denied()
    {
        return ! $this->allowed();
    }

    /**
     * Get the response message.
     *
     * @return string|null
     */
    public function message()
    {
        return $this->message;
    }

    /**
     * Get the response code / reason.
     *
     * @return mixed
     */
    public function code()
    {
        return $this->code;
    }

    /**
     * Throw authorization exception if response was denied.
     *
     * @return \Illuminate\Auth\Access\Response
     *
     * @throws \Illuminate\Auth\Access\AuthorizationException
     */
    public function authorize()
    {
        if ($this->denied()) {
            throw (new AuthorizationException($this->message(), $this->code()))
                ->setResponse($this)
                ->withStatus($this->status);
        }

        return $this;
    }

    /**
     * Set the HTTP response status code.
     *
     * @param  null|int  $status
     * @return $this
     */
    public function withStatus($status)
    {
        $this->status = $status;

        return $this;
    }

    /**
     * Set the HTTP response status code to 404.
     *
     * @return $this
     */
    public function asNotFound()
    {
        return $this->withStatus(404);
    }

    /**
     * Get the HTTP status code.
     *
     * @return int|null
     */
    public function status()
    {
        return $this->status;
    }

    /**
     * Convert the response to an array.
     *
     * @return array
     */
    public function toArray()
    {
        return [
            'allowed' => $this->allowed(),
            'message' => $this->message(),
            'code' => $this->code(),
        ];
    }

    /**
     * Get the string representation of the message.
     *
     * @return string
     */
    public function __toString()
    {
        return (string) $this->message();
    }
}
PK       ! "؟{d  {d    Access/Gate.phpnu ȯ        <?php

namespace Illuminate\Auth\Access;

use Closure;
use Exception;
use Illuminate\Auth\Access\Events\GateEvaluated;
use Illuminate\Contracts\Auth\Access\Gate as GateContract;
use Illuminate\Contracts\Container\Container;
use Illuminate\Contracts\Events\Dispatcher;
use Illuminate\Support\Arr;
use Illuminate\Support\Collection;
use Illuminate\Support\Str;
use InvalidArgumentException;
use ReflectionClass;
use ReflectionFunction;

class Gate implements GateContract
{
    use HandlesAuthorization;

    /**
     * The container instance.
     *
     * @var \Illuminate\Contracts\Container\Container
     */
    protected $container;

    /**
     * The user resolver callable.
     *
     * @var callable
     */
    protected $userResolver;

    /**
     * All of the defined abilities.
     *
     * @var array
     */
    protected $abilities = [];

    /**
     * All of the defined policies.
     *
     * @var array
     */
    protected $policies = [];

    /**
     * All of the registered before callbacks.
     *
     * @var array
     */
    protected $beforeCallbacks = [];

    /**
     * All of the registered after callbacks.
     *
     * @var array
     */
    protected $afterCallbacks = [];

    /**
     * All of the defined abilities using class@method notation.
     *
     * @var array
     */
    protected $stringCallbacks = [];

    /**
     * The default denial response for gates and policies.
     *
     * @var \Illuminate\Auth\Access\Response|null
     */
    protected $defaultDenialResponse;

    /**
     * The callback to be used to guess policy names.
     *
     * @var callable|null
     */
    protected $guessPolicyNamesUsingCallback;

    /**
     * Create a new gate instance.
     *
     * @param  \Illuminate\Contracts\Container\Container  $container
     * @param  callable  $userResolver
     * @param  array  $abilities
     * @param  array  $policies
     * @param  array  $beforeCallbacks
     * @param  array  $afterCallbacks
     * @param  callable|null  $guessPolicyNamesUsingCallback
     * @return void
     */
    public function __construct(Container $container,
        callable $userResolver,
        array $abilities = [],
        array $policies = [],
        array $beforeCallbacks = [],
        array $afterCallbacks = [],
        callable $guessPolicyNamesUsingCallback = null)
    {
        $this->policies = $policies;
        $this->container = $container;
        $this->abilities = $abilities;
        $this->userResolver = $userResolver;
        $this->afterCallbacks = $afterCallbacks;
        $this->beforeCallbacks = $beforeCallbacks;
        $this->guessPolicyNamesUsingCallback = $guessPolicyNamesUsingCallback;
    }

    /**
     * Determine if a given ability has been defined.
     *
     * @param  string|array  $ability
     * @return bool
     */
    public function has($ability)
    {
        $abilities = is_array($ability) ? $ability : func_get_args();

        foreach ($abilities as $ability) {
            if (! isset($this->abilities[$ability])) {
                return false;
            }
        }

        return true;
    }

    /**
     * Perform an on-demand authorization check. Throw an authorization exception if the condition or callback is false.
     *
     * @param  \Illuminate\Auth\Access\Response|\Closure|bool  $condition
     * @param  string|null  $message
     * @param  string|null  $code
     * @return \Illuminate\Auth\Access\Response
     *
     * @throws \Illuminate\Auth\Access\AuthorizationException
     */
    public function allowIf($condition, $message = null, $code = null)
    {
        return $this->authorizeOnDemand($condition, $message, $code, true);
    }

    /**
     * Perform an on-demand authorization check. Throw an authorization exception if the condition or callback is true.
     *
     * @param  \Illuminate\Auth\Access\Response|\Closure|bool  $condition
     * @param  string|null  $message
     * @param  string|null  $code
     * @return \Illuminate\Auth\Access\Response
     *
     * @throws \Illuminate\Auth\Access\AuthorizationException
     */
    public function denyIf($condition, $message = null, $code = null)
    {
        return $this->authorizeOnDemand($condition, $message, $code, false);
    }

    /**
     * Authorize a given condition or callback.
     *
     * @param  \Illuminate\Auth\Access\Response|\Closure|bool  $condition
     * @param  string|null  $message
     * @param  string|null  $code
     * @param  bool  $allowWhenResponseIs
     * @return \Illuminate\Auth\Access\Response
     *
     * @throws \Illuminate\Auth\Access\AuthorizationException
     */
    protected function authorizeOnDemand($condition, $message, $code, $allowWhenResponseIs)
    {
        $user = $this->resolveUser();

        if ($condition instanceof Closure) {
            $response = $this->canBeCalledWithUser($user, $condition)
                            ? $condition($user)
                            : new Response(false, $message, $code);
        } else {
            $response = $condition;
        }

        return with($response instanceof Response ? $response : new Response(
            (bool) $response === $allowWhenResponseIs, $message, $code
        ))->authorize();
    }

    /**
     * Define a new ability.
     *
     * @param  string  $ability
     * @param  callable|array|string  $callback
     * @return $this
     *
     * @throws \InvalidArgumentException
     */
    public function define($ability, $callback)
    {
        if (is_array($callback) && isset($callback[0]) && is_string($callback[0])) {
            $callback = $callback[0].'@'.$callback[1];
        }

        if (is_callable($callback)) {
            $this->abilities[$ability] = $callback;
        } elseif (is_string($callback)) {
            $this->stringCallbacks[$ability] = $callback;

            $this->abilities[$ability] = $this->buildAbilityCallback($ability, $callback);
        } else {
            throw new InvalidArgumentException("Callback must be a callable, callback array, or a 'Class@method' string.");
        }

        return $this;
    }

    /**
     * Define abilities for a resource.
     *
     * @param  string  $name
     * @param  string  $class
     * @param  array|null  $abilities
     * @return $this
     */
    public function resource($name, $class, array $abilities = null)
    {
        $abilities = $abilities ?: [
            'viewAny' => 'viewAny',
            'view' => 'view',
            'create' => 'create',
            'update' => 'update',
            'delete' => 'delete',
        ];

        foreach ($abilities as $ability => $method) {
            $this->define($name.'.'.$ability, $class.'@'.$method);
        }

        return $this;
    }

    /**
     * Create the ability callback for a callback string.
     *
     * @param  string  $ability
     * @param  string  $callback
     * @return \Closure
     */
    protected function buildAbilityCallback($ability, $callback)
    {
        return function () use ($ability, $callback) {
            if (str_contains($callback, '@')) {
                [$class, $method] = Str::parseCallback($callback);
            } else {
                $class = $callback;
            }

            $policy = $this->resolvePolicy($class);

            $arguments = func_get_args();

            $user = array_shift($arguments);

            $result = $this->callPolicyBefore(
                $policy, $user, $ability, $arguments
            );

            if (! is_null($result)) {
                return $result;
            }

            return isset($method)
                    ? $policy->{$method}(...func_get_args())
                    : $policy(...func_get_args());
        };
    }

    /**
     * Define a policy class for a given class type.
     *
     * @param  string  $class
     * @param  string  $policy
     * @return $this
     */
    public function policy($class, $policy)
    {
        $this->policies[$class] = $policy;

        return $this;
    }

    /**
     * Register a callback to run before all Gate checks.
     *
     * @param  callable  $callback
     * @return $this
     */
    public function before(callable $callback)
    {
        $this->beforeCallbacks[] = $callback;

        return $this;
    }

    /**
     * Register a callback to run after all Gate checks.
     *
     * @param  callable  $callback
     * @return $this
     */
    public function after(callable $callback)
    {
        $this->afterCallbacks[] = $callback;

        return $this;
    }

    /**
     * Determine if all of the given abilities should be granted for the current user.
     *
     * @param  iterable|string  $ability
     * @param  array|mixed  $arguments
     * @return bool
     */
    public function allows($ability, $arguments = [])
    {
        return $this->check($ability, $arguments);
    }

    /**
     * Determine if any of the given abilities should be denied for the current user.
     *
     * @param  iterable|string  $ability
     * @param  array|mixed  $arguments
     * @return bool
     */
    public function denies($ability, $arguments = [])
    {
        return ! $this->allows($ability, $arguments);
    }

    /**
     * Determine if all of the given abilities should be granted for the current user.
     *
     * @param  iterable|string  $abilities
     * @param  array|mixed  $arguments
     * @return bool
     */
    public function check($abilities, $arguments = [])
    {
        return collect($abilities)->every(
            fn ($ability) => $this->inspect($ability, $arguments)->allowed()
        );
    }

    /**
     * Determine if any one of the given abilities should be granted for the current user.
     *
     * @param  iterable|string  $abilities
     * @param  array|mixed  $arguments
     * @return bool
     */
    public function any($abilities, $arguments = [])
    {
        return collect($abilities)->contains(fn ($ability) => $this->check($ability, $arguments));
    }

    /**
     * Determine if all of the given abilities should be denied for the current user.
     *
     * @param  iterable|string  $abilities
     * @param  array|mixed  $arguments
     * @return bool
     */
    public function none($abilities, $arguments = [])
    {
        return ! $this->any($abilities, $arguments);
    }

    /**
     * Determine if the given ability should be granted for the current user.
     *
     * @param  string  $ability
     * @param  array|mixed  $arguments
     * @return \Illuminate\Auth\Access\Response
     *
     * @throws \Illuminate\Auth\Access\AuthorizationException
     */
    public function authorize($ability, $arguments = [])
    {
        return $this->inspect($ability, $arguments)->authorize();
    }

    /**
     * Inspect the user for the given ability.
     *
     * @param  string  $ability
     * @param  array|mixed  $arguments
     * @return \Illuminate\Auth\Access\Response
     */
    public function inspect($ability, $arguments = [])
    {
        try {
            $result = $this->raw($ability, $arguments);

            if ($result instanceof Response) {
                return $result;
            }

            return $result
                ? Response::allow()
                : ($this->defaultDenialResponse ?? Response::deny());
        } catch (AuthorizationException $e) {
            return $e->toResponse();
        }
    }

    /**
     * Get the raw result from the authorization callback.
     *
     * @param  string  $ability
     * @param  array|mixed  $arguments
     * @return mixed
     *
     * @throws \Illuminate\Auth\Access\AuthorizationException
     */
    public function raw($ability, $arguments = [])
    {
        $arguments = Arr::wrap($arguments);

        $user = $this->resolveUser();

        // First we will call the "before" callbacks for the Gate. If any of these give
        // back a non-null response, we will immediately return that result in order
        // to let the developers override all checks for some authorization cases.
        $result = $this->callBeforeCallbacks(
            $user, $ability, $arguments
        );

        if (is_null($result)) {
            $result = $this->callAuthCallback($user, $ability, $arguments);
        }

        // After calling the authorization callback, we will call the "after" callbacks
        // that are registered with the Gate, which allows a developer to do logging
        // if that is required for this application. Then we'll return the result.
        return tap($this->callAfterCallbacks(
            $user, $ability, $arguments, $result
        ), function ($result) use ($user, $ability, $arguments) {
            $this->dispatchGateEvaluatedEvent($user, $ability, $arguments, $result);
        });
    }

    /**
     * Determine whether the callback/method can be called with the given user.
     *
     * @param  \Illuminate\Contracts\Auth\Authenticatable|null  $user
     * @param  \Closure|string|array  $class
     * @param  string|null  $method
     * @return bool
     */
    protected function canBeCalledWithUser($user, $class, $method = null)
    {
        if (! is_null($user)) {
            return true;
        }

        if (! is_null($method)) {
            return $this->methodAllowsGuests($class, $method);
        }

        if (is_array($class)) {
            $className = is_string($class[0]) ? $class[0] : get_class($class[0]);

            return $this->methodAllowsGuests($className, $class[1]);
        }

        return $this->callbackAllowsGuests($class);
    }

    /**
     * Determine if the given class method allows guests.
     *
     * @param  string  $class
     * @param  string  $method
     * @return bool
     */
    protected function methodAllowsGuests($class, $method)
    {
        try {
            $reflection = new ReflectionClass($class);

            $method = $reflection->getMethod($method);
        } catch (Exception) {
            return false;
        }

        if ($method) {
            $parameters = $method->getParameters();

            return isset($parameters[0]) && $this->parameterAllowsGuests($parameters[0]);
        }

        return false;
    }

    /**
     * Determine if the callback allows guests.
     *
     * @param  callable  $callback
     * @return bool
     *
     * @throws \ReflectionException
     */
    protected function callbackAllowsGuests($callback)
    {
        $parameters = (new ReflectionFunction($callback))->getParameters();

        return isset($parameters[0]) && $this->parameterAllowsGuests($parameters[0]);
    }

    /**
     * Determine if the given parameter allows guests.
     *
     * @param  \ReflectionParameter  $parameter
     * @return bool
     */
    protected function parameterAllowsGuests($parameter)
    {
        return ($parameter->hasType() && $parameter->allowsNull()) ||
               ($parameter->isDefaultValueAvailable() && is_null($parameter->getDefaultValue()));
    }

    /**
     * Resolve and call the appropriate authorization callback.
     *
     * @param  \Illuminate\Contracts\Auth\Authenticatable|null  $user
     * @param  string  $ability
     * @param  array  $arguments
     * @return bool
     */
    protected function callAuthCallback($user, $ability, array $arguments)
    {
        $callback = $this->resolveAuthCallback($user, $ability, $arguments);

        return $callback($user, ...$arguments);
    }

    /**
     * Call all of the before callbacks and return if a result is given.
     *
     * @param  \Illuminate\Contracts\Auth\Authenticatable|null  $user
     * @param  string  $ability
     * @param  array  $arguments
     * @return bool|null
     */
    protected function callBeforeCallbacks($user, $ability, array $arguments)
    {
        foreach ($this->beforeCallbacks as $before) {
            if (! $this->canBeCalledWithUser($user, $before)) {
                continue;
            }

            if (! is_null($result = $before($user, $ability, $arguments))) {
                return $result;
            }
        }
    }

    /**
     * Call all of the after callbacks with check result.
     *
     * @param  \Illuminate\Contracts\Auth\Authenticatable  $user
     * @param  string  $ability
     * @param  array  $arguments
     * @param  bool  $result
     * @return bool|null
     */
    protected function callAfterCallbacks($user, $ability, array $arguments, $result)
    {
        foreach ($this->afterCallbacks as $after) {
            if (! $this->canBeCalledWithUser($user, $after)) {
                continue;
            }

            $afterResult = $after($user, $ability, $result, $arguments);

            $result ??= $afterResult;
        }

        return $result;
    }

    /**
     * Dispatch a gate evaluation event.
     *
     * @param  \Illuminate\Contracts\Auth\Authenticatable|null  $user
     * @param  string  $ability
     * @param  array  $arguments
     * @param  bool|null  $result
     * @return void
     */
    protected function dispatchGateEvaluatedEvent($user, $ability, array $arguments, $result)
    {
        if ($this->container->bound(Dispatcher::class)) {
            $this->container->make(Dispatcher::class)->dispatch(
                new GateEvaluated($user, $ability, $result, $arguments)
            );
        }
    }

    /**
     * Resolve the callable for the given ability and arguments.
     *
     * @param  \Illuminate\Contracts\Auth\Authenticatable|null  $user
     * @param  string  $ability
     * @param  array  $arguments
     * @return callable
     */
    protected function resolveAuthCallback($user, $ability, array $arguments)
    {
        if (isset($arguments[0]) &&
            ! is_null($policy = $this->getPolicyFor($arguments[0])) &&
            $callback = $this->resolvePolicyCallback($user, $ability, $arguments, $policy)) {
            return $callback;
        }

        if (isset($this->stringCallbacks[$ability])) {
            [$class, $method] = Str::parseCallback($this->stringCallbacks[$ability]);

            if ($this->canBeCalledWithUser($user, $class, $method ?: '__invoke')) {
                return $this->abilities[$ability];
            }
        }

        if (isset($this->abilities[$ability]) &&
            $this->canBeCalledWithUser($user, $this->abilities[$ability])) {
            return $this->abilities[$ability];
        }

        return function () {
            //
        };
    }

    /**
     * Get a policy instance for a given class.
     *
     * @param  object|string  $class
     * @return mixed
     */
    public function getPolicyFor($class)
    {
        if (is_object($class)) {
            $class = get_class($class);
        }

        if (! is_string($class)) {
            return;
        }

        if (isset($this->policies[$class])) {
            return $this->resolvePolicy($this->policies[$class]);
        }

        foreach ($this->guessPolicyName($class) as $guessedPolicy) {
            if (class_exists($guessedPolicy)) {
                return $this->resolvePolicy($guessedPolicy);
            }
        }

        foreach ($this->policies as $expected => $policy) {
            if (is_subclass_of($class, $expected)) {
                return $this->resolvePolicy($policy);
            }
        }
    }

    /**
     * Guess the policy name for the given class.
     *
     * @param  string  $class
     * @return array
     */
    protected function guessPolicyName($class)
    {
        if ($this->guessPolicyNamesUsingCallback) {
            return Arr::wrap(call_user_func($this->guessPolicyNamesUsingCallback, $class));
        }

        $classDirname = str_replace('/', '\\', dirname(str_replace('\\', '/', $class)));

        $classDirnameSegments = explode('\\', $classDirname);

        return Arr::wrap(Collection::times(count($classDirnameSegments), function ($index) use ($class, $classDirnameSegments) {
            $classDirname = implode('\\', array_slice($classDirnameSegments, 0, $index));

            return $classDirname.'\\Policies\\'.class_basename($class).'Policy';
        })->reverse()->values()->first(function ($class) {
            return class_exists($class);
        }) ?: [$classDirname.'\\Policies\\'.class_basename($class).'Policy']);
    }

    /**
     * Specify a callback to be used to guess policy names.
     *
     * @param  callable  $callback
     * @return $this
     */
    public function guessPolicyNamesUsing(callable $callback)
    {
        $this->guessPolicyNamesUsingCallback = $callback;

        return $this;
    }

    /**
     * Build a policy class instance of the given type.
     *
     * @param  object|string  $class
     * @return mixed
     *
     * @throws \Illuminate\Contracts\Container\BindingResolutionException
     */
    public function resolvePolicy($class)
    {
        return $this->container->make($class);
    }

    /**
     * Resolve the callback for a policy check.
     *
     * @param  \Illuminate\Contracts\Auth\Authenticatable  $user
     * @param  string  $ability
     * @param  array  $arguments
     * @param  mixed  $policy
     * @return bool|callable
     */
    protected function resolvePolicyCallback($user, $ability, array $arguments, $policy)
    {
        if (! is_callable([$policy, $this->formatAbilityToMethod($ability)])) {
            return false;
        }

        return function () use ($user, $ability, $arguments, $policy) {
            // This callback will be responsible for calling the policy's before method and
            // running this policy method if necessary. This is used to when objects are
            // mapped to policy objects in the user's configurations or on this class.
            $result = $this->callPolicyBefore(
                $policy, $user, $ability, $arguments
            );

            // When we receive a non-null result from this before method, we will return it
            // as the "final" results. This will allow developers to override the checks
            // in this policy to return the result for all rules defined in the class.
            if (! is_null($result)) {
                return $result;
            }

            $method = $this->formatAbilityToMethod($ability);

            return $this->callPolicyMethod($policy, $method, $user, $arguments);
        };
    }

    /**
     * Call the "before" method on the given policy, if applicable.
     *
     * @param  mixed  $policy
     * @param  \Illuminate\Contracts\Auth\Authenticatable  $user
     * @param  string  $ability
     * @param  array  $arguments
     * @return mixed
     */
    protected function callPolicyBefore($policy, $user, $ability, $arguments)
    {
        if (! method_exists($policy, 'before')) {
            return;
        }

        if ($this->canBeCalledWithUser($user, $policy, 'before')) {
            return $policy->before($user, $ability, ...$arguments);
        }
    }

    /**
     * Call the appropriate method on the given policy.
     *
     * @param  mixed  $policy
     * @param  string  $method
     * @param  \Illuminate\Contracts\Auth\Authenticatable|null  $user
     * @param  array  $arguments
     * @return mixed
     */
    protected function callPolicyMethod($policy, $method, $user, array $arguments)
    {
        // If this first argument is a string, that means they are passing a class name
        // to the policy. We will remove the first argument from this argument array
        // because this policy already knows what type of models it can authorize.
        if (isset($arguments[0]) && is_string($arguments[0])) {
            array_shift($arguments);
        }

        if (! is_callable([$policy, $method])) {
            return;
        }

        if ($this->canBeCalledWithUser($user, $policy, $method)) {
            return $policy->{$method}($user, ...$arguments);
        }
    }

    /**
     * Format the policy ability into a method name.
     *
     * @param  string  $ability
     * @return string
     */
    protected function formatAbilityToMethod($ability)
    {
        return str_contains($ability, '-') ? Str::camel($ability) : $ability;
    }

    /**
     * Get a gate instance for the given user.
     *
     * @param  \Illuminate\Contracts\Auth\Authenticatable|mixed  $user
     * @return static
     */
    public function forUser($user)
    {
        $callback = fn () => $user;

        return new static(
            $this->container, $callback, $this->abilities,
            $this->policies, $this->beforeCallbacks, $this->afterCallbacks,
            $this->guessPolicyNamesUsingCallback
        );
    }

    /**
     * Resolve the user from the user resolver.
     *
     * @return mixed
     */
    protected function resolveUser()
    {
        return call_user_func($this->userResolver);
    }

    /**
     * Get all of the defined abilities.
     *
     * @return array
     */
    public function abilities()
    {
        return $this->abilities;
    }

    /**
     * Get all of the defined policies.
     *
     * @return array
     */
    public function policies()
    {
        return $this->policies;
    }

    /**
     * Set the default denial response for gates and policies.
     *
     * @param  \Illuminate\Auth\Access\Response  $response
     * @return $this
     */
    public function defaultDenialResponse(Response $response)
    {
        $this->defaultDenialResponse = $response;

        return $this;
    }

    /**
     * Set the container instance used by the gate.
     *
     * @param  \Illuminate\Contracts\Container\Container  $container
     * @return $this
     */
    public function setContainer(Container $container)
    {
        $this->container = $container;

        return $this;
    }
}
PK       ! YZ3F  F    Access/HandlesAuthorization.phpnu ȯ        <?php

namespace Illuminate\Auth\Access;

trait HandlesAuthorization
{
    /**
     * Create a new access response.
     *
     * @param  string|null  $message
     * @param  mixed  $code
     * @return \Illuminate\Auth\Access\Response
     */
    protected function allow($message = null, $code = null)
    {
        return Response::allow($message, $code);
    }

    /**
     * Throws an unauthorized exception.
     *
     * @param  string|null  $message
     * @param  mixed|null  $code
     * @return \Illuminate\Auth\Access\Response
     */
    protected function deny($message = null, $code = null)
    {
        return Response::deny($message, $code);
    }

    /**
     * Deny with a HTTP status code.
     *
     * @param  int  $status
     * @param  string|null  $message
     * @param  int|null  $code
     * @return \Illuminate\Auth\Access\Response
     */
    public function denyWithStatus($status, $message = null, $code = null)
    {
        return Response::denyWithStatus($status, $message, $code);
    }

    /**
     * Deny with a 404 HTTP status code.
     *
     * @param  string|null  $message
     * @param  int|null  $code
     * @return \Illuminate\Auth\Access\Response
     */
    public function denyAsNotFound($message = null, $code = null)
    {
        return Response::denyWithStatus(404, $message, $code);
    }
}
PK       !       Access/Events/GateEvaluated.phpnu ȯ        <?php

namespace Illuminate\Auth\Access\Events;

class GateEvaluated
{
    /**
     * The authenticatable model.
     *
     * @var \Illuminate\Contracts\Auth\Authenticatable|null
     */
    public $user;

    /**
     * The ability being evaluated.
     *
     * @var string
     */
    public $ability;

    /**
     * The result of the evaluation.
     *
     * @var bool|null
     */
    public $result;

    /**
     * The arguments given during evaluation.
     *
     * @var array
     */
    public $arguments;

    /**
     * Create a new event instance.
     *
     * @param  \Illuminate\Contracts\Auth\Authenticatable|null  $user
     * @param  string  $ability
     * @param  bool|null  $result
     * @param  array  $arguments
     * @return void
     */
    public function __construct($user, $ability, $result, $arguments)
    {
        $this->user = $user;
        $this->ability = $ability;
        $this->result = $result;
        $this->arguments = $arguments;
    }
}
PK       ! p	\x  x    TokenGuard.phpnu ȯ        <?php

namespace Illuminate\Auth;

use Illuminate\Contracts\Auth\Guard;
use Illuminate\Contracts\Auth\UserProvider;
use Illuminate\Http\Request;

class TokenGuard implements Guard
{
    use GuardHelpers;

    /**
     * The request instance.
     *
     * @var \Illuminate\Http\Request
     */
    protected $request;

    /**
     * The name of the query string item from the request containing the API token.
     *
     * @var string
     */
    protected $inputKey;

    /**
     * The name of the token "column" in persistent storage.
     *
     * @var string
     */
    protected $storageKey;

    /**
     * Indicates if the API token is hashed in storage.
     *
     * @var bool
     */
    protected $hash = false;

    /**
     * Create a new authentication guard.
     *
     * @param  \Illuminate\Contracts\Auth\UserProvider  $provider
     * @param  \Illuminate\Http\Request  $request
     * @param  string  $inputKey
     * @param  string  $storageKey
     * @param  bool  $hash
     * @return void
     */
    public function __construct(
        UserProvider $provider,
        Request $request,
        $inputKey = 'api_token',
        $storageKey = 'api_token',
        $hash = false)
    {
        $this->hash = $hash;
        $this->request = $request;
        $this->provider = $provider;
        $this->inputKey = $inputKey;
        $this->storageKey = $storageKey;
    }

    /**
     * Get the currently authenticated user.
     *
     * @return \Illuminate\Contracts\Auth\Authenticatable|null
     */
    public function user()
    {
        // If we've already retrieved the user for the current request we can just
        // return it back immediately. We do not want to fetch the user data on
        // every call to this method because that would be tremendously slow.
        if (! is_null($this->user)) {
            return $this->user;
        }

        $user = null;

        $token = $this->getTokenForRequest();

        if (! empty($token)) {
            $user = $this->provider->retrieveByCredentials([
                $this->storageKey => $this->hash ? hash('sha256', $token) : $token,
            ]);
        }

        return $this->user = $user;
    }

    /**
     * Get the token for the current request.
     *
     * @return string|null
     */
    public function getTokenForRequest()
    {
        $token = $this->request->query($this->inputKey);

        if (empty($token)) {
            $token = $this->request->input($this->inputKey);
        }

        if (empty($token)) {
            $token = $this->request->bearerToken();
        }

        if (empty($token)) {
            $token = $this->request->getPassword();
        }

        return $token;
    }

    /**
     * Validate a user's credentials.
     *
     * @param  array  $credentials
     * @return bool
     */
    public function validate(array $credentials = [])
    {
        if (empty($credentials[$this->inputKey])) {
            return false;
        }

        $credentials = [$this->storageKey => $credentials[$this->inputKey]];

        if ($this->provider->retrieveByCredentials($credentials)) {
            return true;
        }

        return false;
    }

    /**
     * Set the current request instance.
     *
     * @param  \Illuminate\Http\Request  $request
     * @return $this
     */
    public function setRequest(Request $request)
    {
        $this->request = $request;

        return $this;
    }
}
PK       ! ]	  	    GuardHelpers.phpnu ȯ        <?php

namespace Illuminate\Auth;

use Illuminate\Contracts\Auth\Authenticatable as AuthenticatableContract;
use Illuminate\Contracts\Auth\UserProvider;

/**
 * These methods are typically the same across all guards.
 */
trait GuardHelpers
{
    /**
     * The currently authenticated user.
     *
     * @var \Illuminate\Contracts\Auth\Authenticatable|null
     */
    protected $user;

    /**
     * The user provider implementation.
     *
     * @var \Illuminate\Contracts\Auth\UserProvider
     */
    protected $provider;

    /**
     * Determine if the current user is authenticated. If not, throw an exception.
     *
     * @return \Illuminate\Contracts\Auth\Authenticatable
     *
     * @throws \Illuminate\Auth\AuthenticationException
     */
    public function authenticate()
    {
        return $this->user() ?? throw new AuthenticationException;
    }

    /**
     * Determine if the guard has a user instance.
     *
     * @return bool
     */
    public function hasUser()
    {
        return ! is_null($this->user);
    }

    /**
     * Determine if the current user is authenticated.
     *
     * @return bool
     */
    public function check()
    {
        return ! is_null($this->user());
    }

    /**
     * Determine if the current user is a guest.
     *
     * @return bool
     */
    public function guest()
    {
        return ! $this->check();
    }

    /**
     * Get the ID for the currently authenticated user.
     *
     * @return int|string|null
     */
    public function id()
    {
        if ($this->user()) {
            return $this->user()->getAuthIdentifier();
        }
    }

    /**
     * Set the current user.
     *
     * @param  \Illuminate\Contracts\Auth\Authenticatable  $user
     * @return $this
     */
    public function setUser(AuthenticatableContract $user)
    {
        $this->user = $user;

        return $this;
    }

    /**
     * Forget the current user.
     *
     * @return $this
     */
    public function forgetUser()
    {
        $this->user = null;

        return $this;
    }

    /**
     * Get the user provider used by the guard.
     *
     * @return \Illuminate\Contracts\Auth\UserProvider
     */
    public function getProvider()
    {
        return $this->provider;
    }

    /**
     * Set the user provider used by the guard.
     *
     * @param  \Illuminate\Contracts\Auth\UserProvider  $provider
     * @return void
     */
    public function setProvider(UserProvider $provider)
    {
        $this->provider = $provider;
    }
}
PK       ! Ge.	  	    CreatesUserProviders.phpnu ȯ        <?php

namespace Illuminate\Auth;

use InvalidArgumentException;

trait CreatesUserProviders
{
    /**
     * The registered custom provider creators.
     *
     * @var array
     */
    protected $customProviderCreators = [];

    /**
     * Create the user provider implementation for the driver.
     *
     * @param  string|null  $provider
     * @return \Illuminate\Contracts\Auth\UserProvider|null
     *
     * @throws \InvalidArgumentException
     */
    public function createUserProvider($provider = null)
    {
        if (is_null($config = $this->getProviderConfiguration($provider))) {
            return;
        }

        if (isset($this->customProviderCreators[$driver = ($config['driver'] ?? null)])) {
            return call_user_func(
                $this->customProviderCreators[$driver], $this->app, $config
            );
        }

        return match ($driver) {
            'database' => $this->createDatabaseProvider($config),
            'eloquent' => $this->createEloquentProvider($config),
            default => throw new InvalidArgumentException(
                "Authentication user provider [{$driver}] is not defined."
            ),
        };
    }

    /**
     * Get the user provider configuration.
     *
     * @param  string|null  $provider
     * @return array|null
     */
    protected function getProviderConfiguration($provider)
    {
        if ($provider = $provider ?: $this->getDefaultUserProvider()) {
            return $this->app['config']['auth.providers.'.$provider];
        }
    }

    /**
     * Create an instance of the database user provider.
     *
     * @param  array  $config
     * @return \Illuminate\Auth\DatabaseUserProvider
     */
    protected function createDatabaseProvider($config)
    {
        $connection = $this->app['db']->connection($config['connection'] ?? null);

        return new DatabaseUserProvider($connection, $this->app['hash'], $config['table']);
    }

    /**
     * Create an instance of the Eloquent user provider.
     *
     * @param  array  $config
     * @return \Illuminate\Auth\EloquentUserProvider
     */
    protected function createEloquentProvider($config)
    {
        return new EloquentUserProvider($this->app['hash'], $config['model']);
    }

    /**
     * Get the default user provider name.
     *
     * @return string
     */
    public function getDefaultUserProvider()
    {
        return $this->app['config']['auth.defaults.provider'];
    }
}
PK       ! a@e  e    DatabaseUserProvider.phpnu ȯ        <?php

namespace Illuminate\Auth;

use Closure;
use Illuminate\Contracts\Auth\Authenticatable as UserContract;
use Illuminate\Contracts\Auth\UserProvider;
use Illuminate\Contracts\Hashing\Hasher as HasherContract;
use Illuminate\Contracts\Support\Arrayable;
use Illuminate\Database\ConnectionInterface;

class DatabaseUserProvider implements UserProvider
{
    /**
     * The active database connection.
     *
     * @var \Illuminate\Database\ConnectionInterface
     */
    protected $connection;

    /**
     * The hasher implementation.
     *
     * @var \Illuminate\Contracts\Hashing\Hasher
     */
    protected $hasher;

    /**
     * The table containing the users.
     *
     * @var string
     */
    protected $table;

    /**
     * Create a new database user provider.
     *
     * @param  \Illuminate\Database\ConnectionInterface  $connection
     * @param  \Illuminate\Contracts\Hashing\Hasher  $hasher
     * @param  string  $table
     * @return void
     */
    public function __construct(ConnectionInterface $connection, HasherContract $hasher, $table)
    {
        $this->connection = $connection;
        $this->table = $table;
        $this->hasher = $hasher;
    }

    /**
     * Retrieve a user by their unique identifier.
     *
     * @param  mixed  $identifier
     * @return \Illuminate\Contracts\Auth\Authenticatable|null
     */
    public function retrieveById($identifier)
    {
        $user = $this->connection->table($this->table)->find($identifier);

        return $this->getGenericUser($user);
    }

    /**
     * Retrieve a user by their unique identifier and "remember me" token.
     *
     * @param  mixed  $identifier
     * @param  string  $token
     * @return \Illuminate\Contracts\Auth\Authenticatable|null
     */
    public function retrieveByToken($identifier, $token)
    {
        $user = $this->getGenericUser(
            $this->connection->table($this->table)->find($identifier)
        );

        return $user && $user->getRememberToken() && hash_equals($user->getRememberToken(), $token)
                    ? $user : null;
    }

    /**
     * Update the "remember me" token for the given user in storage.
     *
     * @param  \Illuminate\Contracts\Auth\Authenticatable  $user
     * @param  string  $token
     * @return void
     */
    public function updateRememberToken(UserContract $user, $token)
    {
        $this->connection->table($this->table)
                ->where($user->getAuthIdentifierName(), $user->getAuthIdentifier())
                ->update([$user->getRememberTokenName() => $token]);
    }

    /**
     * Retrieve a user by the given credentials.
     *
     * @param  array  $credentials
     * @return \Illuminate\Contracts\Auth\Authenticatable|null
     */
    public function retrieveByCredentials(array $credentials)
    {
        $credentials = array_filter(
            $credentials,
            fn ($key) => ! str_contains($key, 'password'),
            ARRAY_FILTER_USE_KEY
        );

        if (empty($credentials)) {
            return;
        }

        // First we will add each credential element to the query as a where clause.
        // Then we can execute the query and, if we found a user, return it in a
        // generic "user" object that will be utilized by the Guard instances.
        $query = $this->connection->table($this->table);

        foreach ($credentials as $key => $value) {
            if (is_array($value) || $value instanceof Arrayable) {
                $query->whereIn($key, $value);
            } elseif ($value instanceof Closure) {
                $value($query);
            } else {
                $query->where($key, $value);
            }
        }

        // Now we are ready to execute the query to see if we have a user matching
        // the given credentials. If not, we will just return null and indicate
        // that there are no matching users from the given credential arrays.
        $user = $query->first();

        return $this->getGenericUser($user);
    }

    /**
     * Get the generic user.
     *
     * @param  mixed  $user
     * @return \Illuminate\Auth\GenericUser|null
     */
    protected function getGenericUser($user)
    {
        if (! is_null($user)) {
            return new GenericUser((array) $user);
        }
    }

    /**
     * Validate a user against the given credentials.
     *
     * @param  \Illuminate\Contracts\Auth\Authenticatable  $user
     * @param  array  $credentials
     * @return bool
     */
    public function validateCredentials(UserContract $user, array $credentials)
    {
        return $this->hasher->check(
            $credentials['password'], $user->getAuthPassword()
        );
    }
}
PK       ! *Do&  &    AuthServiceProvider.phpnu ȯ        <?php

namespace Illuminate\Auth;

use Illuminate\Auth\Access\Gate;
use Illuminate\Auth\Middleware\RequirePassword;
use Illuminate\Contracts\Auth\Access\Gate as GateContract;
use Illuminate\Contracts\Auth\Authenticatable as AuthenticatableContract;
use Illuminate\Contracts\Routing\ResponseFactory;
use Illuminate\Contracts\Routing\UrlGenerator;
use Illuminate\Support\ServiceProvider;

class AuthServiceProvider extends ServiceProvider
{
    /**
     * Register the service provider.
     *
     * @return void
     */
    public function register()
    {
        $this->registerAuthenticator();
        $this->registerUserResolver();
        $this->registerAccessGate();
        $this->registerRequirePassword();
        $this->registerRequestRebindHandler();
        $this->registerEventRebindHandler();
    }

    /**
     * Register the authenticator services.
     *
     * @return void
     */
    protected function registerAuthenticator()
    {
        $this->app->singleton('auth', fn ($app) => new AuthManager($app));

        $this->app->singleton('auth.driver', fn ($app) => $app['auth']->guard());
    }

    /**
     * Register a resolver for the authenticated user.
     *
     * @return void
     */
    protected function registerUserResolver()
    {
        $this->app->bind(AuthenticatableContract::class, fn ($app) => call_user_func($app['auth']->userResolver()));
    }

    /**
     * Register the access gate service.
     *
     * @return void
     */
    protected function registerAccessGate()
    {
        $this->app->singleton(GateContract::class, function ($app) {
            return new Gate($app, fn () => call_user_func($app['auth']->userResolver()));
        });
    }

    /**
     * Register a resolver for the authenticated user.
     *
     * @return void
     */
    protected function registerRequirePassword()
    {
        $this->app->bind(RequirePassword::class, function ($app) {
            return new RequirePassword(
                $app[ResponseFactory::class],
                $app[UrlGenerator::class],
                $app['config']->get('auth.password_timeout')
            );
        });
    }

    /**
     * Handle the re-binding of the request binding.
     *
     * @return void
     */
    protected function registerRequestRebindHandler()
    {
        $this->app->rebinding('request', function ($app, $request) {
            $request->setUserResolver(function ($guard = null) use ($app) {
                return call_user_func($app['auth']->userResolver(), $guard);
            });
        });
    }

    /**
     * Handle the re-binding of the event dispatcher binding.
     *
     * @return void
     */
    protected function registerEventRebindHandler()
    {
        $this->app->rebinding('events', function ($app, $dispatcher) {
            if (! $app->resolved('auth') ||
                $app['auth']->hasResolvedGuards() === false) {
                return;
            }

            if (method_exists($guard = $app['auth']->guard(), 'setDispatcher')) {
                $guard->setDispatcher($dispatcher);
            }
        });
    }
}
PK       ! O\Z  Z    Passwords/CanResetPassword.phpnu ȯ        <?php

namespace Illuminate\Auth\Passwords;

use Illuminate\Auth\Notifications\ResetPassword as ResetPasswordNotification;

trait CanResetPassword
{
    /**
     * Get the e-mail address where password reset links are sent.
     *
     * @return string
     */
    public function getEmailForPasswordReset()
    {
        return $this->email;
    }

    /**
     * Send the password reset notification.
     *
     * @param  string  $token
     * @return void
     */
    public function sendPasswordResetNotification($token)
    {
        $this->notify(new ResetPasswordNotification($token));
    }
}
PK       ! HO    *  Passwords/PasswordResetServiceProvider.phpnu ȯ        <?php

namespace Illuminate\Auth\Passwords;

use Illuminate\Contracts\Support\DeferrableProvider;
use Illuminate\Support\ServiceProvider;

class PasswordResetServiceProvider extends ServiceProvider implements DeferrableProvider
{
    /**
     * Register the service provider.
     *
     * @return void
     */
    public function register()
    {
        $this->registerPasswordBroker();
    }

    /**
     * Register the password broker instance.
     *
     * @return void
     */
    protected function registerPasswordBroker()
    {
        $this->app->singleton('auth.password', function ($app) {
            return new PasswordBrokerManager($app);
        });

        $this->app->bind('auth.password.broker', function ($app) {
            return $app->make('auth.password')->broker();
        });
    }

    /**
     * Get the services provided by the provider.
     *
     * @return array
     */
    public function provides()
    {
        return ['auth.password', 'auth.password.broker'];
    }
}
PK       ! KVp_  _  #  Passwords/PasswordBrokerManager.phpnu ȯ        <?php

namespace Illuminate\Auth\Passwords;

use Illuminate\Contracts\Auth\PasswordBrokerFactory as FactoryContract;
use InvalidArgumentException;

/**
 * @mixin \Illuminate\Contracts\Auth\PasswordBroker
 */
class PasswordBrokerManager implements FactoryContract
{
    /**
     * The application instance.
     *
     * @var \Illuminate\Contracts\Foundation\Application
     */
    protected $app;

    /**
     * The array of created "drivers".
     *
     * @var array
     */
    protected $brokers = [];

    /**
     * Create a new PasswordBroker manager instance.
     *
     * @param  \Illuminate\Contracts\Foundation\Application  $app
     * @return void
     */
    public function __construct($app)
    {
        $this->app = $app;
    }

    /**
     * Attempt to get the broker from the local cache.
     *
     * @param  string|null  $name
     * @return \Illuminate\Contracts\Auth\PasswordBroker
     */
    public function broker($name = null)
    {
        $name = $name ?: $this->getDefaultDriver();

        return $this->brokers[$name] ?? ($this->brokers[$name] = $this->resolve($name));
    }

    /**
     * Resolve the given broker.
     *
     * @param  string  $name
     * @return \Illuminate\Contracts\Auth\PasswordBroker
     *
     * @throws \InvalidArgumentException
     */
    protected function resolve($name)
    {
        $config = $this->getConfig($name);

        if (is_null($config)) {
            throw new InvalidArgumentException("Password resetter [{$name}] is not defined.");
        }

        // The password broker uses a token repository to validate tokens and send user
        // password e-mails, as well as validating that password reset process as an
        // aggregate service of sorts providing a convenient interface for resets.
        return new PasswordBroker(
            $this->createTokenRepository($config),
            $this->app['auth']->createUserProvider($config['provider'] ?? null)
        );
    }

    /**
     * Create a token repository instance based on the given configuration.
     *
     * @param  array  $config
     * @return \Illuminate\Auth\Passwords\TokenRepositoryInterface
     */
    protected function createTokenRepository(array $config)
    {
        $key = $this->app['config']['app.key'];

        if (str_starts_with($key, 'base64:')) {
            $key = base64_decode(substr($key, 7));
        }

        $connection = $config['connection'] ?? null;

        return new DatabaseTokenRepository(
            $this->app['db']->connection($connection),
            $this->app['hash'],
            $config['table'],
            $key,
            $config['expire'],
            $config['throttle'] ?? 0
        );
    }

    /**
     * Get the password broker configuration.
     *
     * @param  string  $name
     * @return array|null
     */
    protected function getConfig($name)
    {
        return $this->app['config']["auth.passwords.{$name}"];
    }

    /**
     * Get the default password broker name.
     *
     * @return string
     */
    public function getDefaultDriver()
    {
        return $this->app['config']['auth.defaults.passwords'];
    }

    /**
     * Set the default password broker name.
     *
     * @param  string  $name
     * @return void
     */
    public function setDefaultDriver($name)
    {
        $this->app['config']['auth.defaults.passwords'] = $name;
    }

    /**
     * Dynamically call the default driver instance.
     *
     * @param  string  $method
     * @param  array  $parameters
     * @return mixed
     */
    public function __call($method, $parameters)
    {
        return $this->broker()->{$method}(...$parameters);
    }
}
PK       ! .=  =  %  Passwords/DatabaseTokenRepository.phpnu ȯ        <?php

namespace Illuminate\Auth\Passwords;

use Illuminate\Contracts\Auth\CanResetPassword as CanResetPasswordContract;
use Illuminate\Contracts\Hashing\Hasher as HasherContract;
use Illuminate\Database\ConnectionInterface;
use Illuminate\Support\Carbon;
use Illuminate\Support\Str;

class DatabaseTokenRepository implements TokenRepositoryInterface
{
    /**
     * The database connection instance.
     *
     * @var \Illuminate\Database\ConnectionInterface
     */
    protected $connection;

    /**
     * The Hasher implementation.
     *
     * @var \Illuminate\Contracts\Hashing\Hasher
     */
    protected $hasher;

    /**
     * The token database table.
     *
     * @var string
     */
    protected $table;

    /**
     * The hashing key.
     *
     * @var string
     */
    protected $hashKey;

    /**
     * The number of seconds a token should last.
     *
     * @var int
     */
    protected $expires;

    /**
     * Minimum number of seconds before re-redefining the token.
     *
     * @var int
     */
    protected $throttle;

    /**
     * Create a new token repository instance.
     *
     * @param  \Illuminate\Database\ConnectionInterface  $connection
     * @param  \Illuminate\Contracts\Hashing\Hasher  $hasher
     * @param  string  $table
     * @param  string  $hashKey
     * @param  int  $expires
     * @param  int  $throttle
     * @return void
     */
    public function __construct(ConnectionInterface $connection, HasherContract $hasher,
                                $table, $hashKey, $expires = 60,
                                $throttle = 60)
    {
        $this->table = $table;
        $this->hasher = $hasher;
        $this->hashKey = $hashKey;
        $this->expires = $expires * 60;
        $this->connection = $connection;
        $this->throttle = $throttle;
    }

    /**
     * Create a new token record.
     *
     * @param  \Illuminate\Contracts\Auth\CanResetPassword  $user
     * @return string
     */
    public function create(CanResetPasswordContract $user)
    {
        $email = $user->getEmailForPasswordReset();

        $this->deleteExisting($user);

        // We will create a new, random token for the user so that we can e-mail them
        // a safe link to the password reset form. Then we will insert a record in
        // the database so that we can verify the token within the actual reset.
        $token = $this->createNewToken();

        $this->getTable()->insert($this->getPayload($email, $token));

        return $token;
    }

    /**
     * Delete all existing reset tokens from the database.
     *
     * @param  \Illuminate\Contracts\Auth\CanResetPassword  $user
     * @return int
     */
    protected function deleteExisting(CanResetPasswordContract $user)
    {
        return $this->getTable()->where('email', $user->getEmailForPasswordReset())->delete();
    }

    /**
     * Build the record payload for the table.
     *
     * @param  string  $email
     * @param  string  $token
     * @return array
     */
    protected function getPayload($email, $token)
    {
        return ['email' => $email, 'token' => $this->hasher->make($token), 'created_at' => new Carbon];
    }

    /**
     * Determine if a token record exists and is valid.
     *
     * @param  \Illuminate\Contracts\Auth\CanResetPassword  $user
     * @param  string  $token
     * @return bool
     */
    public function exists(CanResetPasswordContract $user, $token)
    {
        $record = (array) $this->getTable()->where(
            'email', $user->getEmailForPasswordReset()
        )->first();

        return $record &&
               ! $this->tokenExpired($record['created_at']) &&
                 $this->hasher->check($token, $record['token']);
    }

    /**
     * Determine if the token has expired.
     *
     * @param  string  $createdAt
     * @return bool
     */
    protected function tokenExpired($createdAt)
    {
        return Carbon::parse($createdAt)->addSeconds($this->expires)->isPast();
    }

    /**
     * Determine if the given user recently created a password reset token.
     *
     * @param  \Illuminate\Contracts\Auth\CanResetPassword  $user
     * @return bool
     */
    public function recentlyCreatedToken(CanResetPasswordContract $user)
    {
        $record = (array) $this->getTable()->where(
            'email', $user->getEmailForPasswordReset()
        )->first();

        return $record && $this->tokenRecentlyCreated($record['created_at']);
    }

    /**
     * Determine if the token was recently created.
     *
     * @param  string  $createdAt
     * @return bool
     */
    protected function tokenRecentlyCreated($createdAt)
    {
        if ($this->throttle <= 0) {
            return false;
        }

        return Carbon::parse($createdAt)->addSeconds(
            $this->throttle
        )->isFuture();
    }

    /**
     * Delete a token record by user.
     *
     * @param  \Illuminate\Contracts\Auth\CanResetPassword  $user
     * @return void
     */
    public function delete(CanResetPasswordContract $user)
    {
        $this->deleteExisting($user);
    }

    /**
     * Delete expired tokens.
     *
     * @return void
     */
    public function deleteExpired()
    {
        $expiredAt = Carbon::now()->subSeconds($this->expires);

        $this->getTable()->where('created_at', '<', $expiredAt)->delete();
    }

    /**
     * Create a new token for the user.
     *
     * @return string
     */
    public function createNewToken()
    {
        return hash_hmac('sha256', Str::random(40), $this->hashKey);
    }

    /**
     * Get the database connection instance.
     *
     * @return \Illuminate\Database\ConnectionInterface
     */
    public function getConnection()
    {
        return $this->connection;
    }

    /**
     * Begin a new database query against the table.
     *
     * @return \Illuminate\Database\Query\Builder
     */
    protected function getTable()
    {
        return $this->connection->table($this->table);
    }

    /**
     * Get the hasher instance.
     *
     * @return \Illuminate\Contracts\Hashing\Hasher
     */
    public function getHasher()
    {
        return $this->hasher;
    }
}
PK       ! s      Passwords/PasswordBroker.phpnu ȯ        <?php

namespace Illuminate\Auth\Passwords;

use Closure;
use Illuminate\Contracts\Auth\CanResetPassword as CanResetPasswordContract;
use Illuminate\Contracts\Auth\PasswordBroker as PasswordBrokerContract;
use Illuminate\Contracts\Auth\UserProvider;
use Illuminate\Support\Arr;
use UnexpectedValueException;

class PasswordBroker implements PasswordBrokerContract
{
    /**
     * The password token repository.
     *
     * @var \Illuminate\Auth\Passwords\TokenRepositoryInterface
     */
    protected $tokens;

    /**
     * The user provider implementation.
     *
     * @var \Illuminate\Contracts\Auth\UserProvider
     */
    protected $users;

    /**
     * Create a new password broker instance.
     *
     * @param  \Illuminate\Auth\Passwords\TokenRepositoryInterface  $tokens
     * @param  \Illuminate\Contracts\Auth\UserProvider  $users
     * @return void
     */
    public function __construct(TokenRepositoryInterface $tokens, UserProvider $users)
    {
        $this->users = $users;
        $this->tokens = $tokens;
    }

    /**
     * Send a password reset link to a user.
     *
     * @param  array  $credentials
     * @param  \Closure|null  $callback
     * @return string
     */
    public function sendResetLink(array $credentials, Closure $callback = null)
    {
        // First we will check to see if we found a user at the given credentials and
        // if we did not we will redirect back to this current URI with a piece of
        // "flash" data in the session to indicate to the developers the errors.
        $user = $this->getUser($credentials);

        if (is_null($user)) {
            return static::INVALID_USER;
        }

        if ($this->tokens->recentlyCreatedToken($user)) {
            return static::RESET_THROTTLED;
        }

        $token = $this->tokens->create($user);

        if ($callback) {
            return $callback($user, $token) ?? static::RESET_LINK_SENT;
        }

        // Once we have the reset token, we are ready to send the message out to this
        // user with a link to reset their password. We will then redirect back to
        // the current URI having nothing set in the session to indicate errors.
        $user->sendPasswordResetNotification($token);

        return static::RESET_LINK_SENT;
    }

    /**
     * Reset the password for the given token.
     *
     * @param  array  $credentials
     * @param  \Closure  $callback
     * @return mixed
     */
    public function reset(array $credentials, Closure $callback)
    {
        $user = $this->validateReset($credentials);

        // If the responses from the validate method is not a user instance, we will
        // assume that it is a redirect and simply return it from this method and
        // the user is properly redirected having an error message on the post.
        if (! $user instanceof CanResetPasswordContract) {
            return $user;
        }

        $password = $credentials['password'];

        // Once the reset has been validated, we'll call the given callback with the
        // new password. This gives the user an opportunity to store the password
        // in their persistent storage. Then we'll delete the token and return.
        $callback($user, $password);

        $this->tokens->delete($user);

        return static::PASSWORD_RESET;
    }

    /**
     * Validate a password reset for the given credentials.
     *
     * @param  array  $credentials
     * @return \Illuminate\Contracts\Auth\CanResetPassword|string
     */
    protected function validateReset(array $credentials)
    {
        if (is_null($user = $this->getUser($credentials))) {
            return static::INVALID_USER;
        }

        if (! $this->tokens->exists($user, $credentials['token'])) {
            return static::INVALID_TOKEN;
        }

        return $user;
    }

    /**
     * Get the user for the given credentials.
     *
     * @param  array  $credentials
     * @return \Illuminate\Contracts\Auth\CanResetPassword|null
     *
     * @throws \UnexpectedValueException
     */
    public function getUser(array $credentials)
    {
        $credentials = Arr::except($credentials, ['token']);

        $user = $this->users->retrieveByCredentials($credentials);

        if ($user && ! $user instanceof CanResetPasswordContract) {
            throw new UnexpectedValueException('User must implement CanResetPassword interface.');
        }

        return $user;
    }

    /**
     * Create a new password reset token for the given user.
     *
     * @param  \Illuminate\Contracts\Auth\CanResetPassword  $user
     * @return string
     */
    public function createToken(CanResetPasswordContract $user)
    {
        return $this->tokens->create($user);
    }

    /**
     * Delete password reset tokens of the given user.
     *
     * @param  \Illuminate\Contracts\Auth\CanResetPassword  $user
     * @return void
     */
    public function deleteToken(CanResetPasswordContract $user)
    {
        $this->tokens->delete($user);
    }

    /**
     * Validate the given password reset token.
     *
     * @param  \Illuminate\Contracts\Auth\CanResetPassword  $user
     * @param  string  $token
     * @return bool
     */
    public function tokenExists(CanResetPasswordContract $user, $token)
    {
        return $this->tokens->exists($user, $token);
    }

    /**
     * Get the password reset token repository implementation.
     *
     * @return \Illuminate\Auth\Passwords\TokenRepositoryInterface
     */
    public function getRepository()
    {
        return $this->tokens;
    }
}
PK       ! Ux2    &  Passwords/TokenRepositoryInterface.phpnu ȯ        <?php

namespace Illuminate\Auth\Passwords;

use Illuminate\Contracts\Auth\CanResetPassword as CanResetPasswordContract;

interface TokenRepositoryInterface
{
    /**
     * Create a new token.
     *
     * @param  \Illuminate\Contracts\Auth\CanResetPassword  $user
     * @return string
     */
    public function create(CanResetPasswordContract $user);

    /**
     * Determine if a token record exists and is valid.
     *
     * @param  \Illuminate\Contracts\Auth\CanResetPassword  $user
     * @param  string  $token
     * @return bool
     */
    public function exists(CanResetPasswordContract $user, $token);

    /**
     * Determine if the given user recently created a password reset token.
     *
     * @param  \Illuminate\Contracts\Auth\CanResetPassword  $user
     * @return bool
     */
    public function recentlyCreatedToken(CanResetPasswordContract $user);

    /**
     * Delete a token record.
     *
     * @param  \Illuminate\Contracts\Auth\CanResetPassword  $user
     * @return void
     */
    public function delete(CanResetPasswordContract $user);

    /**
     * Delete expired tokens.
     *
     * @return void
     */
    public function deleteExpired();
}
PK       ! rl7      MustVerifyEmail.phpnu ȯ        <?php

namespace Illuminate\Auth;

use Illuminate\Auth\Notifications\VerifyEmail;

trait MustVerifyEmail
{
    /**
     * Determine if the user has verified their email address.
     *
     * @return bool
     */
    public function hasVerifiedEmail()
    {
        return ! is_null($this->email_verified_at);
    }

    /**
     * Mark the given user's email as verified.
     *
     * @return bool
     */
    public function markEmailAsVerified()
    {
        return $this->forceFill([
            'email_verified_at' => $this->freshTimestamp(),
        ])->save();
    }

    /**
     * Send the email verification notification.
     *
     * @return void
     */
    public function sendEmailVerificationNotification()
    {
        $this->notify(new VerifyEmail);
    }

    /**
     * Get the email address that should be used for verification.
     *
     * @return string
     */
    public function getEmailForVerification()
    {
        return $this->email;
    }
}
PK       ! c	  	    GenericUser.phpnu ȯ        <?php

namespace Illuminate\Auth;

use Illuminate\Contracts\Auth\Authenticatable as UserContract;

class GenericUser implements UserContract
{
    /**
     * All of the user's attributes.
     *
     * @var array
     */
    protected $attributes;

    /**
     * Create a new generic User object.
     *
     * @param  array  $attributes
     * @return void
     */
    public function __construct(array $attributes)
    {
        $this->attributes = $attributes;
    }

    /**
     * Get the name of the unique identifier for the user.
     *
     * @return string
     */
    public function getAuthIdentifierName()
    {
        return 'id';
    }

    /**
     * Get the unique identifier for the user.
     *
     * @return mixed
     */
    public function getAuthIdentifier()
    {
        return $this->attributes[$this->getAuthIdentifierName()];
    }

    /**
     * Get the password for the user.
     *
     * @return string
     */
    public function getAuthPassword()
    {
        return $this->attributes['password'];
    }

    /**
     * Get the "remember me" token value.
     *
     * @return string
     */
    public function getRememberToken()
    {
        return $this->attributes[$this->getRememberTokenName()];
    }

    /**
     * Set the "remember me" token value.
     *
     * @param  string  $value
     * @return void
     */
    public function setRememberToken($value)
    {
        $this->attributes[$this->getRememberTokenName()] = $value;
    }

    /**
     * Get the column name for the "remember me" token.
     *
     * @return string
     */
    public function getRememberTokenName()
    {
        return 'remember_token';
    }

    /**
     * Dynamically access the user's attributes.
     *
     * @param  string  $key
     * @return mixed
     */
    public function __get($key)
    {
        return $this->attributes[$key];
    }

    /**
     * Dynamically set an attribute on the user.
     *
     * @param  string  $key
     * @param  mixed  $value
     * @return void
     */
    public function __set($key, $value)
    {
        $this->attributes[$key] = $value;
    }

    /**
     * Dynamically check if a value is set on the user.
     *
     * @param  string  $key
     * @return bool
     */
    public function __isset($key)
    {
        return isset($this->attributes[$key]);
    }

    /**
     * Dynamically unset a value on the user.
     *
     * @param  string  $key
     * @return void
     */
    public function __unset($key)
    {
        unset($this->attributes[$key]);
    }
}
PK       ! ,4Z    /  Listeners/SendEmailVerificationNotification.phpnu ȯ        <?php

namespace Illuminate\Auth\Listeners;

use Illuminate\Auth\Events\Registered;
use Illuminate\Contracts\Auth\MustVerifyEmail;

class SendEmailVerificationNotification
{
    /**
     * Handle the event.
     *
     * @param  \Illuminate\Auth\Events\Registered  $event
     * @return void
     */
    public function handle(Registered $event)
    {
        if ($event->user instanceof MustVerifyEmail && ! $event->user->hasVerifiedEmail()) {
            $event->user->sendEmailVerificationNotification();
        }
    }
}
PK       ! α3  3  
  LICENSE.mdnu ȯ        The MIT License (MIT)

Copyright (c) Taylor Otwell

Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
PK       ! JJ  J    AuthenticationException.phpnu ȯ        <?php

namespace Illuminate\Auth;

use Exception;

class AuthenticationException extends Exception
{
    /**
     * All of the guards that were checked.
     *
     * @var array
     */
    protected $guards;

    /**
     * The path the user should be redirected to.
     *
     * @var string|null
     */
    protected $redirectTo;

    /**
     * Create a new authentication exception.
     *
     * @param  string  $message
     * @param  array  $guards
     * @param  string|null  $redirectTo
     * @return void
     */
    public function __construct($message = 'Unauthenticated.', array $guards = [], $redirectTo = null)
    {
        parent::__construct($message);

        $this->guards = $guards;
        $this->redirectTo = $redirectTo;
    }

    /**
     * Get the guards that were checked.
     *
     * @return array
     */
    public function guards()
    {
        return $this->guards;
    }

    /**
     * Get the path the user should be redirected to.
     *
     * @return string|null
     */
    public function redirectTo()
    {
        return $this->redirectTo;
    }
}
PK       !  9V  V    Recaller.phpnu ȯ        <?php

namespace Illuminate\Auth;

class Recaller
{
    /**
     * The "recaller" / "remember me" cookie string.
     *
     * @var string
     */
    protected $recaller;

    /**
     * Create a new recaller instance.
     *
     * @param  string  $recaller
     * @return void
     */
    public function __construct($recaller)
    {
        $this->recaller = @unserialize($recaller, ['allowed_classes' => false]) ?: $recaller;
    }

    /**
     * Get the user ID from the recaller.
     *
     * @return string
     */
    public function id()
    {
        return explode('|', $this->recaller, 3)[0];
    }

    /**
     * Get the "remember token" token from the recaller.
     *
     * @return string
     */
    public function token()
    {
        return explode('|', $this->recaller, 3)[1];
    }

    /**
     * Get the password from the recaller.
     *
     * @return string
     */
    public function hash()
    {
        return explode('|', $this->recaller, 4)[2];
    }

    /**
     * Determine if the recaller is valid.
     *
     * @return bool
     */
    public function valid()
    {
        return $this->properString() && $this->hasAllSegments();
    }

    /**
     * Determine if the recaller is an invalid string.
     *
     * @return bool
     */
    protected function properString()
    {
        return is_string($this->recaller) && str_contains($this->recaller, '|');
    }

    /**
     * Determine if the recaller has all segments.
     *
     * @return bool
     */
    protected function hasAllSegments()
    {
        $segments = explode('|', $this->recaller);

        return count($segments) >= 3 && trim($segments[0]) !== '' && trim($segments[1]) !== '';
    }

    /**
     * Get the recaller's segments.
     *
     * @return array
     */
    public function segments()
    {
        return explode('|', $this->recaller);
    }
}
PK       ! =m/      composer.jsonnu ȯ        {
    "name": "illuminate/auth",
    "description": "The Illuminate Auth package.",
    "license": "MIT",
    "homepage": "https://laravel.com",
    "support": {
        "issues": "https://github.com/laravel/framework/issues",
        "source": "https://github.com/laravel/framework"
    },
    "authors": [
        {
            "name": "Taylor Otwell",
            "email": "taylor@laravel.com"
        }
    ],
    "require": {
        "php": "^8.1",
        "ext-hash": "*",
        "illuminate/collections": "^10.0",
        "illuminate/contracts": "^10.0",
        "illuminate/http": "^10.0",
        "illuminate/macroable": "^10.0",
        "illuminate/queue": "^10.0",
        "illuminate/support": "^10.0"
    },
    "autoload": {
        "psr-4": {
            "Illuminate\\Auth\\": ""
        }
    },
    "extra": {
        "branch-alias": {
            "dev-master": "10.x-dev"
        }
    },
    "suggest": {
        "illuminate/console": "Required to use the auth:clear-resets command (^10.0).",
        "illuminate/queue": "Required to fire login / logout events (^10.0).",
        "illuminate/session": "Required to use the session based guard (^10.0)."
    },
    "config": {
        "sort-packages": true
    },
    "minimum-stability": "dev"
}
PK       ! i  i    SessionGuard.phpnu ȯ        <?php

namespace Illuminate\Auth;

use Illuminate\Auth\Events\Attempting;
use Illuminate\Auth\Events\Authenticated;
use Illuminate\Auth\Events\CurrentDeviceLogout;
use Illuminate\Auth\Events\Failed;
use Illuminate\Auth\Events\Login;
use Illuminate\Auth\Events\Logout;
use Illuminate\Auth\Events\OtherDeviceLogout;
use Illuminate\Auth\Events\Validated;
use Illuminate\Contracts\Auth\Authenticatable as AuthenticatableContract;
use Illuminate\Contracts\Auth\StatefulGuard;
use Illuminate\Contracts\Auth\SupportsBasicAuth;
use Illuminate\Contracts\Auth\UserProvider;
use Illuminate\Contracts\Cookie\QueueingFactory as CookieJar;
use Illuminate\Contracts\Events\Dispatcher;
use Illuminate\Contracts\Session\Session;
use Illuminate\Support\Arr;
use Illuminate\Support\Facades\Hash;
use Illuminate\Support\Str;
use Illuminate\Support\Timebox;
use Illuminate\Support\Traits\Macroable;
use InvalidArgumentException;
use RuntimeException;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpKernel\Exception\UnauthorizedHttpException;

class SessionGuard implements StatefulGuard, SupportsBasicAuth
{
    use GuardHelpers, Macroable;

    /**
     * The name of the guard. Typically "web".
     *
     * Corresponds to guard name in authentication configuration.
     *
     * @var string
     */
    public readonly string $name;

    /**
     * The user we last attempted to retrieve.
     *
     * @var \Illuminate\Contracts\Auth\Authenticatable
     */
    protected $lastAttempted;

    /**
     * Indicates if the user was authenticated via a recaller cookie.
     *
     * @var bool
     */
    protected $viaRemember = false;

    /**
     * The number of minutes that the "remember me" cookie should be valid for.
     *
     * @var int
     */
    protected $rememberDuration = 576000;

    /**
     * The session used by the guard.
     *
     * @var \Illuminate\Contracts\Session\Session
     */
    protected $session;

    /**
     * The Illuminate cookie creator service.
     *
     * @var \Illuminate\Contracts\Cookie\QueueingFactory
     */
    protected $cookie;

    /**
     * The request instance.
     *
     * @var \Symfony\Component\HttpFoundation\Request
     */
    protected $request;

    /**
     * The event dispatcher instance.
     *
     * @var \Illuminate\Contracts\Events\Dispatcher
     */
    protected $events;

    /**
     * The timebox instance.
     *
     * @var \Illuminate\Support\Timebox
     */
    protected $timebox;

    /**
     * Indicates if the logout method has been called.
     *
     * @var bool
     */
    protected $loggedOut = false;

    /**
     * Indicates if a token user retrieval has been attempted.
     *
     * @var bool
     */
    protected $recallAttempted = false;

    /**
     * Create a new authentication guard.
     *
     * @param  string  $name
     * @param  \Illuminate\Contracts\Auth\UserProvider  $provider
     * @param  \Illuminate\Contracts\Session\Session  $session
     * @param  \Symfony\Component\HttpFoundation\Request|null  $request
     * @param  \Illuminate\Support\Timebox|null  $timebox
     * @return void
     */
    public function __construct($name,
                                UserProvider $provider,
                                Session $session,
                                Request $request = null,
                                Timebox $timebox = null)
    {
        $this->name = $name;
        $this->session = $session;
        $this->request = $request;
        $this->provider = $provider;
        $this->timebox = $timebox ?: new Timebox;
    }

    /**
     * Get the currently authenticated user.
     *
     * @return \Illuminate\Contracts\Auth\Authenticatable|null
     */
    public function user()
    {
        if ($this->loggedOut) {
            return;
        }

        // If we've already retrieved the user for the current request we can just
        // return it back immediately. We do not want to fetch the user data on
        // every call to this method because that would be tremendously slow.
        if (! is_null($this->user)) {
            return $this->user;
        }

        $id = $this->session->get($this->getName());

        // First we will try to load the user using the identifier in the session if
        // one exists. Otherwise we will check for a "remember me" cookie in this
        // request, and if one exists, attempt to retrieve the user using that.
        if (! is_null($id) && $this->user = $this->provider->retrieveById($id)) {
            $this->fireAuthenticatedEvent($this->user);
        }

        // If the user is null, but we decrypt a "recaller" cookie we can attempt to
        // pull the user data on that cookie which serves as a remember cookie on
        // the application. Once we have a user we can return it to the caller.
        if (is_null($this->user) && ! is_null($recaller = $this->recaller())) {
            $this->user = $this->userFromRecaller($recaller);

            if ($this->user) {
                $this->updateSession($this->user->getAuthIdentifier());

                $this->fireLoginEvent($this->user, true);
            }
        }

        return $this->user;
    }

    /**
     * Pull a user from the repository by its "remember me" cookie token.
     *
     * @param  \Illuminate\Auth\Recaller  $recaller
     * @return mixed
     */
    protected function userFromRecaller($recaller)
    {
        if (! $recaller->valid() || $this->recallAttempted) {
            return;
        }

        // If the user is null, but we decrypt a "recaller" cookie we can attempt to
        // pull the user data on that cookie which serves as a remember cookie on
        // the application. Once we have a user we can return it to the caller.
        $this->recallAttempted = true;

        $this->viaRemember = ! is_null($user = $this->provider->retrieveByToken(
            $recaller->id(), $recaller->token()
        ));

        return $user;
    }

    /**
     * Get the decrypted recaller cookie for the request.
     *
     * @return \Illuminate\Auth\Recaller|null
     */
    protected function recaller()
    {
        if (is_null($this->request)) {
            return;
        }

        if ($recaller = $this->request->cookies->get($this->getRecallerName())) {
            return new Recaller($recaller);
        }
    }

    /**
     * Get the ID for the currently authenticated user.
     *
     * @return int|string|null
     */
    public function id()
    {
        if ($this->loggedOut) {
            return;
        }

        return $this->user()
                    ? $this->user()->getAuthIdentifier()
                    : $this->session->get($this->getName());
    }

    /**
     * Log a user into the application without sessions or cookies.
     *
     * @param  array  $credentials
     * @return bool
     */
    public function once(array $credentials = [])
    {
        $this->fireAttemptEvent($credentials);

        if ($this->validate($credentials)) {
            $this->setUser($this->lastAttempted);

            return true;
        }

        return false;
    }

    /**
     * Log the given user ID into the application without sessions or cookies.
     *
     * @param  mixed  $id
     * @return \Illuminate\Contracts\Auth\Authenticatable|false
     */
    public function onceUsingId($id)
    {
        if (! is_null($user = $this->provider->retrieveById($id))) {
            $this->setUser($user);

            return $user;
        }

        return false;
    }

    /**
     * Validate a user's credentials.
     *
     * @param  array  $credentials
     * @return bool
     */
    public function validate(array $credentials = [])
    {
        $this->lastAttempted = $user = $this->provider->retrieveByCredentials($credentials);

        return $this->hasValidCredentials($user, $credentials);
    }

    /**
     * Attempt to authenticate using HTTP Basic Auth.
     *
     * @param  string  $field
     * @param  array  $extraConditions
     * @return \Symfony\Component\HttpFoundation\Response|null
     *
     * @throws \Symfony\Component\HttpKernel\Exception\UnauthorizedHttpException
     */
    public function basic($field = 'email', $extraConditions = [])
    {
        if ($this->check()) {
            return;
        }

        // If a username is set on the HTTP basic request, we will return out without
        // interrupting the request lifecycle. Otherwise, we'll need to generate a
        // request indicating that the given credentials were invalid for login.
        if ($this->attemptBasic($this->getRequest(), $field, $extraConditions)) {
            return;
        }

        return $this->failedBasicResponse();
    }

    /**
     * Perform a stateless HTTP Basic login attempt.
     *
     * @param  string  $field
     * @param  array  $extraConditions
     * @return \Symfony\Component\HttpFoundation\Response|null
     *
     * @throws \Symfony\Component\HttpKernel\Exception\UnauthorizedHttpException
     */
    public function onceBasic($field = 'email', $extraConditions = [])
    {
        $credentials = $this->basicCredentials($this->getRequest(), $field);

        if (! $this->once(array_merge($credentials, $extraConditions))) {
            return $this->failedBasicResponse();
        }
    }

    /**
     * Attempt to authenticate using basic authentication.
     *
     * @param  \Symfony\Component\HttpFoundation\Request  $request
     * @param  string  $field
     * @param  array  $extraConditions
     * @return bool
     */
    protected function attemptBasic(Request $request, $field, $extraConditions = [])
    {
        if (! $request->getUser()) {
            return false;
        }

        return $this->attempt(array_merge(
            $this->basicCredentials($request, $field), $extraConditions
        ));
    }

    /**
     * Get the credential array for an HTTP Basic request.
     *
     * @param  \Symfony\Component\HttpFoundation\Request  $request
     * @param  string  $field
     * @return array
     */
    protected function basicCredentials(Request $request, $field)
    {
        return [$field => $request->getUser(), 'password' => $request->getPassword()];
    }

    /**
     * Get the response for basic authentication.
     *
     * @return void
     *
     * @throws \Symfony\Component\HttpKernel\Exception\UnauthorizedHttpException
     */
    protected function failedBasicResponse()
    {
        throw new UnauthorizedHttpException('Basic', 'Invalid credentials.');
    }

    /**
     * Attempt to authenticate a user using the given credentials.
     *
     * @param  array  $credentials
     * @param  bool  $remember
     * @return bool
     */
    public function attempt(array $credentials = [], $remember = false)
    {
        $this->fireAttemptEvent($credentials, $remember);

        $this->lastAttempted = $user = $this->provider->retrieveByCredentials($credentials);

        // If an implementation of UserInterface was returned, we'll ask the provider
        // to validate the user against the given credentials, and if they are in
        // fact valid we'll log the users into the application and return true.
        if ($this->hasValidCredentials($user, $credentials)) {
            $this->login($user, $remember);

            return true;
        }

        // If the authentication attempt fails we will fire an event so that the user
        // may be notified of any suspicious attempts to access their account from
        // an unrecognized user. A developer may listen to this event as needed.
        $this->fireFailedEvent($user, $credentials);

        return false;
    }

    /**
     * Attempt to authenticate a user with credentials and additional callbacks.
     *
     * @param  array  $credentials
     * @param  array|callable|null  $callbacks
     * @param  bool  $remember
     * @return bool
     */
    public function attemptWhen(array $credentials = [], $callbacks = null, $remember = false)
    {
        $this->fireAttemptEvent($credentials, $remember);

        $this->lastAttempted = $user = $this->provider->retrieveByCredentials($credentials);

        // This method does the exact same thing as attempt, but also executes callbacks after
        // the user is retrieved and validated. If one of the callbacks returns falsy we do
        // not login the user. Instead, we will fail the specific authentication attempt.
        if ($this->hasValidCredentials($user, $credentials) && $this->shouldLogin($callbacks, $user)) {
            $this->login($user, $remember);

            return true;
        }

        $this->fireFailedEvent($user, $credentials);

        return false;
    }

    /**
     * Determine if the user matches the credentials.
     *
     * @param  mixed  $user
     * @param  array  $credentials
     * @return bool
     */
    protected function hasValidCredentials($user, $credentials)
    {
        return $this->timebox->call(function ($timebox) use ($user, $credentials) {
            $validated = ! is_null($user) && $this->provider->validateCredentials($user, $credentials);

            if ($validated) {
                $timebox->returnEarly();

                $this->fireValidatedEvent($user);
            }

            return $validated;
        }, 200 * 1000);
    }

    /**
     * Determine if the user should login by executing the given callbacks.
     *
     * @param  array|callable|null  $callbacks
     * @param  \Illuminate\Contracts\Auth\Authenticatable  $user
     * @return bool
     */
    protected function shouldLogin($callbacks, AuthenticatableContract $user)
    {
        foreach (Arr::wrap($callbacks) as $callback) {
            if (! $callback($user, $this)) {
                return false;
            }
        }

        return true;
    }

    /**
     * Log the given user ID into the application.
     *
     * @param  mixed  $id
     * @param  bool  $remember
     * @return \Illuminate\Contracts\Auth\Authenticatable|false
     */
    public function loginUsingId($id, $remember = false)
    {
        if (! is_null($user = $this->provider->retrieveById($id))) {
            $this->login($user, $remember);

            return $user;
        }

        return false;
    }

    /**
     * Log a user into the application.
     *
     * @param  \Illuminate\Contracts\Auth\Authenticatable  $user
     * @param  bool  $remember
     * @return void
     */
    public function login(AuthenticatableContract $user, $remember = false)
    {
        $this->updateSession($user->getAuthIdentifier());

        // If the user should be permanently "remembered" by the application we will
        // queue a permanent cookie that contains the encrypted copy of the user
        // identifier. We will then decrypt this later to retrieve the users.
        if ($remember) {
            $this->ensureRememberTokenIsSet($user);

            $this->queueRecallerCookie($user);
        }

        // If we have an event dispatcher instance set we will fire an event so that
        // any listeners will hook into the authentication events and run actions
        // based on the login and logout events fired from the guard instances.
        $this->fireLoginEvent($user, $remember);

        $this->setUser($user);
    }

    /**
     * Update the session with the given ID.
     *
     * @param  string  $id
     * @return void
     */
    protected function updateSession($id)
    {
        $this->session->put($this->getName(), $id);

        $this->session->migrate(true);
    }

    /**
     * Create a new "remember me" token for the user if one doesn't already exist.
     *
     * @param  \Illuminate\Contracts\Auth\Authenticatable  $user
     * @return void
     */
    protected function ensureRememberTokenIsSet(AuthenticatableContract $user)
    {
        if (empty($user->getRememberToken())) {
            $this->cycleRememberToken($user);
        }
    }

    /**
     * Queue the recaller cookie into the cookie jar.
     *
     * @param  \Illuminate\Contracts\Auth\Authenticatable  $user
     * @return void
     */
    protected function queueRecallerCookie(AuthenticatableContract $user)
    {
        $this->getCookieJar()->queue($this->createRecaller(
            $user->getAuthIdentifier().'|'.$user->getRememberToken().'|'.$user->getAuthPassword()
        ));
    }

    /**
     * Create a "remember me" cookie for a given ID.
     *
     * @param  string  $value
     * @return \Symfony\Component\HttpFoundation\Cookie
     */
    protected function createRecaller($value)
    {
        return $this->getCookieJar()->make($this->getRecallerName(), $value, $this->getRememberDuration());
    }

    /**
     * Log the user out of the application.
     *
     * @return void
     */
    public function logout()
    {
        $user = $this->user();

        $this->clearUserDataFromStorage();

        if (! is_null($this->user) && ! empty($user->getRememberToken())) {
            $this->cycleRememberToken($user);
        }

        // If we have an event dispatcher instance, we can fire off the logout event
        // so any further processing can be done. This allows the developer to be
        // listening for anytime a user signs out of this application manually.
        if (isset($this->events)) {
            $this->events->dispatch(new Logout($this->name, $user));
        }

        // Once we have fired the logout event we will clear the users out of memory
        // so they are no longer available as the user is no longer considered as
        // being signed into this application and should not be available here.
        $this->user = null;

        $this->loggedOut = true;
    }

    /**
     * Log the user out of the application on their current device only.
     *
     * This method does not cycle the "remember" token.
     *
     * @return void
     */
    public function logoutCurrentDevice()
    {
        $user = $this->user();

        $this->clearUserDataFromStorage();

        // If we have an event dispatcher instance, we can fire off the logout event
        // so any further processing can be done. This allows the developer to be
        // listening for anytime a user signs out of this application manually.
        if (isset($this->events)) {
            $this->events->dispatch(new CurrentDeviceLogout($this->name, $user));
        }

        // Once we have fired the logout event we will clear the users out of memory
        // so they are no longer available as the user is no longer considered as
        // being signed into this application and should not be available here.
        $this->user = null;

        $this->loggedOut = true;
    }

    /**
     * Remove the user data from the session and cookies.
     *
     * @return void
     */
    protected function clearUserDataFromStorage()
    {
        $this->session->remove($this->getName());

        $this->getCookieJar()->unqueue($this->getRecallerName());

        if (! is_null($this->recaller())) {
            $this->getCookieJar()->queue(
                $this->getCookieJar()->forget($this->getRecallerName())
            );
        }
    }

    /**
     * Refresh the "remember me" token for the user.
     *
     * @param  \Illuminate\Contracts\Auth\Authenticatable  $user
     * @return void
     */
    protected function cycleRememberToken(AuthenticatableContract $user)
    {
        $user->setRememberToken($token = Str::random(60));

        $this->provider->updateRememberToken($user, $token);
    }

    /**
     * Invalidate other sessions for the current user.
     *
     * The application must be using the AuthenticateSession middleware.
     *
     * @param  string  $password
     * @param  string  $attribute
     * @return \Illuminate\Contracts\Auth\Authenticatable|null
     *
     * @throws \Illuminate\Auth\AuthenticationException
     */
    public function logoutOtherDevices($password, $attribute = 'password')
    {
        if (! $this->user()) {
            return;
        }

        $result = $this->rehashUserPassword($password, $attribute);

        if ($this->recaller() ||
            $this->getCookieJar()->hasQueued($this->getRecallerName())) {
            $this->queueRecallerCookie($this->user());
        }

        $this->fireOtherDeviceLogoutEvent($this->user());

        return $result;
    }

    /**
     * Rehash the current user's password.
     *
     * @param  string  $password
     * @param  string  $attribute
     * @return \Illuminate\Contracts\Auth\Authenticatable|null
     *
     * @throws \InvalidArgumentException
     */
    protected function rehashUserPassword($password, $attribute)
    {
        if (! Hash::check($password, $this->user()->{$attribute})) {
            throw new InvalidArgumentException('The given password does not match the current password.');
        }

        return tap($this->user()->forceFill([
            $attribute => Hash::make($password),
        ]))->save();
    }

    /**
     * Register an authentication attempt event listener.
     *
     * @param  mixed  $callback
     * @return void
     */
    public function attempting($callback)
    {
        $this->events?->listen(Events\Attempting::class, $callback);
    }

    /**
     * Fire the attempt event with the arguments.
     *
     * @param  array  $credentials
     * @param  bool  $remember
     * @return void
     */
    protected function fireAttemptEvent(array $credentials, $remember = false)
    {
        $this->events?->dispatch(new Attempting($this->name, $credentials, $remember));
    }

    /**
     * Fires the validated event if the dispatcher is set.
     *
     * @param  \Illuminate\Contracts\Auth\Authenticatable  $user
     * @return void
     */
    protected function fireValidatedEvent($user)
    {
        $this->events?->dispatch(new Validated($this->name, $user));
    }

    /**
     * Fire the login event if the dispatcher is set.
     *
     * @param  \Illuminate\Contracts\Auth\Authenticatable  $user
     * @param  bool  $remember
     * @return void
     */
    protected function fireLoginEvent($user, $remember = false)
    {
        $this->events?->dispatch(new Login($this->name, $user, $remember));
    }

    /**
     * Fire the authenticated event if the dispatcher is set.
     *
     * @param  \Illuminate\Contracts\Auth\Authenticatable  $user
     * @return void
     */
    protected function fireAuthenticatedEvent($user)
    {
        $this->events?->dispatch(new Authenticated($this->name, $user));
    }

    /**
     * Fire the other device logout event if the dispatcher is set.
     *
     * @param  \Illuminate\Contracts\Auth\Authenticatable  $user
     * @return void
     */
    protected function fireOtherDeviceLogoutEvent($user)
    {
        $this->events?->dispatch(new OtherDeviceLogout($this->name, $user));
    }

    /**
     * Fire the failed authentication attempt event with the given arguments.
     *
     * @param  \Illuminate\Contracts\Auth\Authenticatable|null  $user
     * @param  array  $credentials
     * @return void
     */
    protected function fireFailedEvent($user, array $credentials)
    {
        $this->events?->dispatch(new Failed($this->name, $user, $credentials));
    }

    /**
     * Get the last user we attempted to authenticate.
     *
     * @return \Illuminate\Contracts\Auth\Authenticatable
     */
    public function getLastAttempted()
    {
        return $this->lastAttempted;
    }

    /**
     * Get a unique identifier for the auth session value.
     *
     * @return string
     */
    public function getName()
    {
        return 'login_'.$this->name.'_'.sha1(static::class);
    }

    /**
     * Get the name of the cookie used to store the "recaller".
     *
     * @return string
     */
    public function getRecallerName()
    {
        return 'remember_'.$this->name.'_'.sha1(static::class);
    }

    /**
     * Determine if the user was authenticated via "remember me" cookie.
     *
     * @return bool
     */
    public function viaRemember()
    {
        return $this->viaRemember;
    }

    /**
     * Get the number of minutes the remember me cookie should be valid for.
     *
     * @return int
     */
    protected function getRememberDuration()
    {
        return $this->rememberDuration;
    }

    /**
     * Set the number of minutes the remember me cookie should be valid for.
     *
     * @param  int  $minutes
     * @return $this
     */
    public function setRememberDuration($minutes)
    {
        $this->rememberDuration = $minutes;

        return $this;
    }

    /**
     * Get the cookie creator instance used by the guard.
     *
     * @return \Illuminate\Contracts\Cookie\QueueingFactory
     *
     * @throws \RuntimeException
     */
    public function getCookieJar()
    {
        if (! isset($this->cookie)) {
            throw new RuntimeException('Cookie jar has not been set.');
        }

        return $this->cookie;
    }

    /**
     * Set the cookie creator instance used by the guard.
     *
     * @param  \Illuminate\Contracts\Cookie\QueueingFactory  $cookie
     * @return void
     */
    public function setCookieJar(CookieJar $cookie)
    {
        $this->cookie = $cookie;
    }

    /**
     * Get the event dispatcher instance.
     *
     * @return \Illuminate\Contracts\Events\Dispatcher
     */
    public function getDispatcher()
    {
        return $this->events;
    }

    /**
     * Set the event dispatcher instance.
     *
     * @param  \Illuminate\Contracts\Events\Dispatcher  $events
     * @return void
     */
    public function setDispatcher(Dispatcher $events)
    {
        $this->events = $events;
    }

    /**
     * Get the session store used by the guard.
     *
     * @return \Illuminate\Contracts\Session\Session
     */
    public function getSession()
    {
        return $this->session;
    }

    /**
     * Return the currently cached user.
     *
     * @return \Illuminate\Contracts\Auth\Authenticatable|null
     */
    public function getUser()
    {
        return $this->user;
    }

    /**
     * Set the current user.
     *
     * @param  \Illuminate\Contracts\Auth\Authenticatable  $user
     * @return $this
     */
    public function setUser(AuthenticatableContract $user)
    {
        $this->user = $user;

        $this->loggedOut = false;

        $this->fireAuthenticatedEvent($user);

        return $this;
    }

    /**
     * Get the current request instance.
     *
     * @return \Symfony\Component\HttpFoundation\Request
     */
    public function getRequest()
    {
        return $this->request ?: Request::createFromGlobals();
    }

    /**
     * Set the current request instance.
     *
     * @param  \Symfony\Component\HttpFoundation\Request  $request
     * @return $this
     */
    public function setRequest(Request $request)
    {
        $this->request = $request;

        return $this;
    }

    /**
     * Get the timebox instance used by the guard.
     *
     * @return \Illuminate\Support\Timebox
     */
    public function getTimebox()
    {
        return $this->timebox;
    }
}
PK       ! lTJ  J    RequestGuard.phpnu ȯ        <?php

namespace Illuminate\Auth;

use Illuminate\Contracts\Auth\Guard;
use Illuminate\Contracts\Auth\UserProvider;
use Illuminate\Http\Request;
use Illuminate\Support\Traits\Macroable;

class RequestGuard implements Guard
{
    use GuardHelpers, Macroable;

    /**
     * The guard callback.
     *
     * @var callable
     */
    protected $callback;

    /**
     * The request instance.
     *
     * @var \Illuminate\Http\Request
     */
    protected $request;

    /**
     * Create a new authentication guard.
     *
     * @param  callable  $callback
     * @param  \Illuminate\Http\Request  $request
     * @param  \Illuminate\Contracts\Auth\UserProvider|null  $provider
     * @return void
     */
    public function __construct(callable $callback, Request $request, UserProvider $provider = null)
    {
        $this->request = $request;
        $this->callback = $callback;
        $this->provider = $provider;
    }

    /**
     * Get the currently authenticated user.
     *
     * @return \Illuminate\Contracts\Auth\Authenticatable|null
     */
    public function user()
    {
        // If we've already retrieved the user for the current request we can just
        // return it back immediately. We do not want to fetch the user data on
        // every call to this method because that would be tremendously slow.
        if (! is_null($this->user)) {
            return $this->user;
        }

        return $this->user = call_user_func(
            $this->callback, $this->request, $this->getProvider()
        );
    }

    /**
     * Validate a user's credentials.
     *
     * @param  array  $credentials
     * @return bool
     */
    public function validate(array $credentials = [])
    {
        return ! is_null((new static(
            $this->callback, $credentials['request'], $this->getProvider()
        ))->user());
    }

    /**
     * Set the current request instance.
     *
     * @param  \Illuminate\Http\Request  $request
     * @return $this
     */
    public function setRequest(Request $request)
    {
        $this->request = $request;

        return $this;
    }
}
PK       ! NO      EloquentUserProvider.phpnu ȯ        <?php

namespace Illuminate\Auth;

use Closure;
use Illuminate\Contracts\Auth\Authenticatable as UserContract;
use Illuminate\Contracts\Auth\UserProvider;
use Illuminate\Contracts\Hashing\Hasher as HasherContract;
use Illuminate\Contracts\Support\Arrayable;

class EloquentUserProvider implements UserProvider
{
    /**
     * The hasher implementation.
     *
     * @var \Illuminate\Contracts\Hashing\Hasher
     */
    protected $hasher;

    /**
     * The Eloquent user model.
     *
     * @var string
     */
    protected $model;

    /**
     * The callback that may modify the user retrieval queries.
     *
     * @var (\Closure(\Illuminate\Database\Eloquent\Builder):mixed)|null
     */
    protected $queryCallback;

    /**
     * Create a new database user provider.
     *
     * @param  \Illuminate\Contracts\Hashing\Hasher  $hasher
     * @param  string  $model
     * @return void
     */
    public function __construct(HasherContract $hasher, $model)
    {
        $this->model = $model;
        $this->hasher = $hasher;
    }

    /**
     * Retrieve a user by their unique identifier.
     *
     * @param  mixed  $identifier
     * @return \Illuminate\Contracts\Auth\Authenticatable|null
     */
    public function retrieveById($identifier)
    {
        $model = $this->createModel();

        return $this->newModelQuery($model)
                    ->where($model->getAuthIdentifierName(), $identifier)
                    ->first();
    }

    /**
     * Retrieve a user by their unique identifier and "remember me" token.
     *
     * @param  mixed  $identifier
     * @param  string  $token
     * @return \Illuminate\Contracts\Auth\Authenticatable|null
     */
    public function retrieveByToken($identifier, $token)
    {
        $model = $this->createModel();

        $retrievedModel = $this->newModelQuery($model)->where(
            $model->getAuthIdentifierName(), $identifier
        )->first();

        if (! $retrievedModel) {
            return;
        }

        $rememberToken = $retrievedModel->getRememberToken();

        return $rememberToken && hash_equals($rememberToken, $token) ? $retrievedModel : null;
    }

    /**
     * Update the "remember me" token for the given user in storage.
     *
     * @param  \Illuminate\Contracts\Auth\Authenticatable  $user
     * @param  string  $token
     * @return void
     */
    public function updateRememberToken(UserContract $user, $token)
    {
        $user->setRememberToken($token);

        $timestamps = $user->timestamps;

        $user->timestamps = false;

        $user->save();

        $user->timestamps = $timestamps;
    }

    /**
     * Retrieve a user by the given credentials.
     *
     * @param  array  $credentials
     * @return \Illuminate\Contracts\Auth\Authenticatable|null
     */
    public function retrieveByCredentials(array $credentials)
    {
        $credentials = array_filter(
            $credentials,
            fn ($key) => ! str_contains($key, 'password'),
            ARRAY_FILTER_USE_KEY
        );

        if (empty($credentials)) {
            return;
        }

        // First we will add each credential element to the query as a where clause.
        // Then we can execute the query and, if we found a user, return it in a
        // Eloquent User "model" that will be utilized by the Guard instances.
        $query = $this->newModelQuery();

        foreach ($credentials as $key => $value) {
            if (is_array($value) || $value instanceof Arrayable) {
                $query->whereIn($key, $value);
            } elseif ($value instanceof Closure) {
                $value($query);
            } else {
                $query->where($key, $value);
            }
        }

        return $query->first();
    }

    /**
     * Validate a user against the given credentials.
     *
     * @param  \Illuminate\Contracts\Auth\Authenticatable  $user
     * @param  array  $credentials
     * @return bool
     */
    public function validateCredentials(UserContract $user, array $credentials)
    {
        if (is_null($plain = $credentials['password'])) {
            return false;
        }

        return $this->hasher->check($plain, $user->getAuthPassword());
    }

    /**
     * Get a new query builder for the model instance.
     *
     * @param  \Illuminate\Database\Eloquent\Model|null  $model
     * @return \Illuminate\Database\Eloquent\Builder
     */
    protected function newModelQuery($model = null)
    {
        $query = is_null($model)
                ? $this->createModel()->newQuery()
                : $model->newQuery();

        with($query, $this->queryCallback);

        return $query;
    }

    /**
     * Create a new instance of the model.
     *
     * @return \Illuminate\Database\Eloquent\Model
     */
    public function createModel()
    {
        $class = '\\'.ltrim($this->model, '\\');

        return new $class;
    }

    /**
     * Gets the hasher implementation.
     *
     * @return \Illuminate\Contracts\Hashing\Hasher
     */
    public function getHasher()
    {
        return $this->hasher;
    }

    /**
     * Sets the hasher implementation.
     *
     * @param  \Illuminate\Contracts\Hashing\Hasher  $hasher
     * @return $this
     */
    public function setHasher(HasherContract $hasher)
    {
        $this->hasher = $hasher;

        return $this;
    }

    /**
     * Gets the name of the Eloquent user model.
     *
     * @return string
     */
    public function getModel()
    {
        return $this->model;
    }

    /**
     * Sets the name of the Eloquent user model.
     *
     * @param  string  $model
     * @return $this
     */
    public function setModel($model)
    {
        $this->model = $model;

        return $this;
    }

    /**
     * Get the callback that modifies the query before retrieving users.
     *
     * @return \Closure|null
     */
    public function getQueryCallback()
    {
        return $this->queryCallback;
    }

    /**
     * Sets the callback to modify the query before retrieving users.
     *
     * @param  (\Closure(\Illuminate\Database\Eloquent\Builder):mixed)|null  $queryCallback
     * @return $this
     */
    public function withQuery($queryCallback = null)
    {
        $this->queryCallback = $queryCallback;

        return $this;
    }
}
PK       ! XJ:      Authenticatable.phpnu ȯ        <?php

namespace Illuminate\Auth;

trait Authenticatable
{
    /**
     * The column name of the "remember me" token.
     *
     * @var string
     */
    protected $rememberTokenName = 'remember_token';

    /**
     * Get the name of the unique identifier for the user.
     *
     * @return string
     */
    public function getAuthIdentifierName()
    {
        return $this->getKeyName();
    }

    /**
     * Get the unique identifier for the user.
     *
     * @return mixed
     */
    public function getAuthIdentifier()
    {
        return $this->{$this->getAuthIdentifierName()};
    }

    /**
     * Get the unique broadcast identifier for the user.
     *
     * @return mixed
     */
    public function getAuthIdentifierForBroadcasting()
    {
        return $this->getAuthIdentifier();
    }

    /**
     * Get the password for the user.
     *
     * @return string
     */
    public function getAuthPassword()
    {
        return $this->password;
    }

    /**
     * Get the token value for the "remember me" session.
     *
     * @return string|null
     */
    public function getRememberToken()
    {
        if (! empty($this->getRememberTokenName())) {
            return (string) $this->{$this->getRememberTokenName()};
        }
    }

    /**
     * Set the token value for the "remember me" session.
     *
     * @param  string  $value
     * @return void
     */
    public function setRememberToken($value)
    {
        if (! empty($this->getRememberTokenName())) {
            $this->{$this->getRememberTokenName()} = $value;
        }
    }

    /**
     * Get the column name for the "remember me" token.
     *
     * @return string
     */
    public function getRememberTokenName()
    {
        return $this->rememberTokenName;
    }
}
PK       ! ri=  =    Events/Failed.phpnu ȯ        <?php

namespace Illuminate\Auth\Events;

class Failed
{
    /**
     * The authentication guard name.
     *
     * @var string
     */
    public $guard;

    /**
     * The user the attempter was trying to authenticate as.
     *
     * @var \Illuminate\Contracts\Auth\Authenticatable|null
     */
    public $user;

    /**
     * The credentials provided by the attempter.
     *
     * @var array
     */
    public $credentials;

    /**
     * Create a new event instance.
     *
     * @param  string  $guard
     * @param  \Illuminate\Contracts\Auth\Authenticatable|null  $user
     * @param  array  $credentials
     * @return void
     */
    public function __construct($guard, $user, $credentials)
    {
        $this->user = $user;
        $this->guard = $guard;
        $this->credentials = $credentials;
    }
}
PK       ! =      Events/OtherDeviceLogout.phpnu ȯ        <?php

namespace Illuminate\Auth\Events;

use Illuminate\Queue\SerializesModels;

class OtherDeviceLogout
{
    use SerializesModels;

    /**
     * The authentication guard name.
     *
     * @var string
     */
    public $guard;

    /**
     * The authenticated user.
     *
     * @var \Illuminate\Contracts\Auth\Authenticatable
     */
    public $user;

    /**
     * Create a new event instance.
     *
     * @param  string  $guard
     * @param  \Illuminate\Contracts\Auth\Authenticatable  $user
     * @return void
     */
    public function __construct($guard, $user)
    {
        $this->user = $user;
        $this->guard = $guard;
    }
}
PK       ! "(      Events/CurrentDeviceLogout.phpnu ȯ        <?php

namespace Illuminate\Auth\Events;

use Illuminate\Queue\SerializesModels;

class CurrentDeviceLogout
{
    use SerializesModels;

    /**
     * The authentication guard name.
     *
     * @var string
     */
    public $guard;

    /**
     * The authenticated user.
     *
     * @var \Illuminate\Contracts\Auth\Authenticatable
     */
    public $user;

    /**
     * Create a new event instance.
     *
     * @param  string  $guard
     * @param  \Illuminate\Contracts\Auth\Authenticatable  $user
     * @return void
     */
    public function __construct($guard, $user)
    {
        $this->user = $user;
        $this->guard = $guard;
    }
}
PK       ! y      Events/Logout.phpnu ȯ        <?php

namespace Illuminate\Auth\Events;

use Illuminate\Queue\SerializesModels;

class Logout
{
    use SerializesModels;

    /**
     * The authentication guard name.
     *
     * @var string
     */
    public $guard;

    /**
     * The authenticated user.
     *
     * @var \Illuminate\Contracts\Auth\Authenticatable
     */
    public $user;

    /**
     * Create a new event instance.
     *
     * @param  string  $guard
     * @param  \Illuminate\Contracts\Auth\Authenticatable  $user
     * @return void
     */
    public function __construct($guard, $user)
    {
        $this->user = $user;
        $this->guard = $guard;
    }
}
PK       ! ~       Events/Registered.phpnu ȯ        <?php

namespace Illuminate\Auth\Events;

use Illuminate\Queue\SerializesModels;

class Registered
{
    use SerializesModels;

    /**
     * The authenticated user.
     *
     * @var \Illuminate\Contracts\Auth\Authenticatable
     */
    public $user;

    /**
     * Create a new event instance.
     *
     * @param  \Illuminate\Contracts\Auth\Authenticatable  $user
     * @return void
     */
    public function __construct($user)
    {
        $this->user = $user;
    }
}
PK       ! w:      Events/Attempting.phpnu ȯ        <?php

namespace Illuminate\Auth\Events;

class Attempting
{
    /**
     * The authentication guard name.
     *
     * @var string
     */
    public $guard;

    /**
     * The credentials for the user.
     *
     * @var array
     */
    public $credentials;

    /**
     * Indicates if the user should be "remembered".
     *
     * @var bool
     */
    public $remember;

    /**
     * Create a new event instance.
     *
     * @param  string  $guard
     * @param  array  $credentials
     * @param  bool  $remember
     * @return void
     */
    public function __construct($guard, $credentials, $remember)
    {
        $this->guard = $guard;
        $this->remember = $remember;
        $this->credentials = $credentials;
    }
}
PK       ! n      Events/Lockout.phpnu ȯ        <?php

namespace Illuminate\Auth\Events;

use Illuminate\Http\Request;

class Lockout
{
    /**
     * The throttled request.
     *
     * @var \Illuminate\Http\Request
     */
    public $request;

    /**
     * Create a new event instance.
     *
     * @param  \Illuminate\Http\Request  $request
     * @return void
     */
    public function __construct(Request $request)
    {
        $this->request = $request;
    }
}
PK       ! ӻ0̎      Events/Authenticated.phpnu ȯ        <?php

namespace Illuminate\Auth\Events;

use Illuminate\Queue\SerializesModels;

class Authenticated
{
    use SerializesModels;

    /**
     * The authentication guard name.
     *
     * @var string
     */
    public $guard;

    /**
     * The authenticated user.
     *
     * @var \Illuminate\Contracts\Auth\Authenticatable
     */
    public $user;

    /**
     * Create a new event instance.
     *
     * @param  string  $guard
     * @param  \Illuminate\Contracts\Auth\Authenticatable  $user
     * @return void
     */
    public function __construct($guard, $user)
    {
        $this->user = $user;
        $this->guard = $guard;
    }
}
PK       ! L@      Events/PasswordReset.phpnu ȯ        <?php

namespace Illuminate\Auth\Events;

use Illuminate\Queue\SerializesModels;

class PasswordReset
{
    use SerializesModels;

    /**
     * The user.
     *
     * @var \Illuminate\Contracts\Auth\Authenticatable
     */
    public $user;

    /**
     * Create a new event instance.
     *
     * @param  \Illuminate\Contracts\Auth\Authenticatable  $user
     * @return void
     */
    public function __construct($user)
    {
        $this->user = $user;
    }
}
PK       ! Vd      Events/Validated.phpnu ȯ        <?php

namespace Illuminate\Auth\Events;

use Illuminate\Queue\SerializesModels;

class Validated
{
    use SerializesModels;

    /**
     * The authentication guard name.
     *
     * @var string
     */
    public $guard;

    /**
     * The user retrieved and validated from the User Provider.
     *
     * @var \Illuminate\Contracts\Auth\Authenticatable
     */
    public $user;

    /**
     * Create a new event instance.
     *
     * @param  string  $guard
     * @param  \Illuminate\Contracts\Auth\Authenticatable  $user
     * @return void
     */
    public function __construct($guard, $user)
    {
        $this->user = $user;
        $this->guard = $guard;
    }
}
PK       ! .c  c     Events/PasswordResetLinkSent.phpnu Iw        <?php

namespace Illuminate\Auth\Events;

use Illuminate\Queue\SerializesModels;

class PasswordResetLinkSent
{
    use SerializesModels;

    /**
     * Create a new event instance.
     *
     * @param  \Illuminate\Contracts\Auth\CanResetPassword  $user  The user instance.
     */
    public function __construct(
        public $user,
    ) {
    }
}
PK       ! +I  I    Events/Login.phpnu ȯ        <?php

namespace Illuminate\Auth\Events;

use Illuminate\Queue\SerializesModels;

class Login
{
    use SerializesModels;

    /**
     * The authentication guard name.
     *
     * @var string
     */
    public $guard;

    /**
     * The authenticated user.
     *
     * @var \Illuminate\Contracts\Auth\Authenticatable
     */
    public $user;

    /**
     * Indicates if the user should be "remembered".
     *
     * @var bool
     */
    public $remember;

    /**
     * Create a new event instance.
     *
     * @param  string  $guard
     * @param  \Illuminate\Contracts\Auth\Authenticatable  $user
     * @param  bool  $remember
     * @return void
     */
    public function __construct($guard, $user, $remember)
    {
        $this->user = $user;
        $this->guard = $guard;
        $this->remember = $remember;
    }
}
PK       ! ^X      Events/Verified.phpnu ȯ        <?php

namespace Illuminate\Auth\Events;

use Illuminate\Queue\SerializesModels;

class Verified
{
    use SerializesModels;

    /**
     * The verified user.
     *
     * @var \Illuminate\Contracts\Auth\MustVerifyEmail
     */
    public $user;

    /**
     * Create a new event instance.
     *
     * @param  \Illuminate\Contracts\Auth\MustVerifyEmail  $user
     * @return void
     */
    public function __construct($user)
    {
        $this->user = $user;
    }
}
PK       ! Y  Y  (  Middleware/AuthenticateWithBasicAuth.phpnu ȯ        <?php

namespace Illuminate\Auth\Middleware;

use Closure;
use Illuminate\Contracts\Auth\Factory as AuthFactory;

class AuthenticateWithBasicAuth
{
    /**
     * The guard factory instance.
     *
     * @var \Illuminate\Contracts\Auth\Factory
     */
    protected $auth;

    /**
     * Create a new middleware instance.
     *
     * @param  \Illuminate\Contracts\Auth\Factory  $auth
     * @return void
     */
    public function __construct(AuthFactory $auth)
    {
        $this->auth = $auth;
    }

    /**
     * Specify the guard and field for the middleware.
     *
     * @param  string|null  $guard
     * @param  string|null  $field
     * @return string
     *
     * @named-arguments-supported
     */
    public static function using($guard = null, $field = null)
    {
        return static::class.':'.implode(',', func_get_args());
    }

    /**
     * Handle an incoming request.
     *
     * @param  \Illuminate\Http\Request  $request
     * @param  \Closure  $next
     * @param  string|null  $guard
     * @param  string|null  $field
     * @return mixed
     *
     * @throws \Symfony\Component\HttpKernel\Exception\UnauthorizedHttpException
     */
    public function handle($request, Closure $next, $guard = null, $field = null)
    {
        $this->auth->guard($guard)->basic($field ?: 'email');

        return $next($request);
    }
}
PK       ! 弯    $  Middleware/EnsureEmailIsVerified.phpnu ȯ        <?php

namespace Illuminate\Auth\Middleware;

use Closure;
use Illuminate\Contracts\Auth\MustVerifyEmail;
use Illuminate\Support\Facades\Redirect;
use Illuminate\Support\Facades\URL;

class EnsureEmailIsVerified
{
    /**
     * Specify the redirect route for the middleware.
     *
     * @param  string  $route
     * @return string
     */
    public static function redirectTo($route)
    {
        return static::class.':'.$route;
    }

    /**
     * Handle an incoming request.
     *
     * @param  \Illuminate\Http\Request  $request
     * @param  \Closure  $next
     * @param  string|null  $redirectToRoute
     * @return \Illuminate\Http\Response|\Illuminate\Http\RedirectResponse|null
     */
    public function handle($request, Closure $next, $redirectToRoute = null)
    {
        if (! $request->user() ||
            ($request->user() instanceof MustVerifyEmail &&
            ! $request->user()->hasVerifiedEmail())) {
            return $request->expectsJson()
                    ? abort(403, 'Your email address is not verified.')
                    : Redirect::guest(URL::route($redirectToRoute ?: 'verification.notice'));
        }

        return $next($request);
    }
}
PK       ! A5w
  w
    Middleware/Authenticate.phpnu ȯ        <?php

namespace Illuminate\Auth\Middleware;

use Closure;
use Illuminate\Auth\AuthenticationException;
use Illuminate\Contracts\Auth\Factory as Auth;
use Illuminate\Contracts\Auth\Middleware\AuthenticatesRequests;
use Illuminate\Http\Request;

class Authenticate implements AuthenticatesRequests
{
    /**
     * The authentication factory instance.
     *
     * @var \Illuminate\Contracts\Auth\Factory
     */
    protected $auth;

    /**
     * Create a new middleware instance.
     *
     * @param  \Illuminate\Contracts\Auth\Factory  $auth
     * @return void
     */
    public function __construct(Auth $auth)
    {
        $this->auth = $auth;
    }

    /**
     * Specify the guards for the middleware.
     *
     * @param  string  $guard
     * @param  string  $others
     * @return string
     */
    public static function using($guard, ...$others)
    {
        return static::class.':'.implode(',', [$guard, ...$others]);
    }

    /**
     * Handle an incoming request.
     *
     * @param  \Illuminate\Http\Request  $request
     * @param  \Closure  $next
     * @param  string[]  ...$guards
     * @return mixed
     *
     * @throws \Illuminate\Auth\AuthenticationException
     */
    public function handle($request, Closure $next, ...$guards)
    {
        $this->authenticate($request, $guards);

        return $next($request);
    }

    /**
     * Determine if the user is logged in to any of the given guards.
     *
     * @param  \Illuminate\Http\Request  $request
     * @param  array  $guards
     * @return void
     *
     * @throws \Illuminate\Auth\AuthenticationException
     */
    protected function authenticate($request, array $guards)
    {
        if (empty($guards)) {
            $guards = [null];
        }

        foreach ($guards as $guard) {
            if ($this->auth->guard($guard)->check()) {
                return $this->auth->shouldUse($guard);
            }
        }

        $this->unauthenticated($request, $guards);
    }

    /**
     * Handle an unauthenticated user.
     *
     * @param  \Illuminate\Http\Request  $request
     * @param  array  $guards
     * @return void
     *
     * @throws \Illuminate\Auth\AuthenticationException
     */
    protected function unauthenticated($request, array $guards)
    {
        throw new AuthenticationException(
            'Unauthenticated.', $guards, $this->redirectTo($request)
        );
    }

    /**
     * Get the path the user should be redirected to when they are not authenticated.
     *
     * @param  \Illuminate\Http\Request  $request
     * @return string|null
     */
    protected function redirectTo(Request $request)
    {
        //
    }
}
PK       !  b
  b
    Middleware/Authorize.phpnu ȯ        <?php

namespace Illuminate\Auth\Middleware;

use Closure;
use Illuminate\Contracts\Auth\Access\Gate;
use Illuminate\Database\Eloquent\Model;

class Authorize
{
    /**
     * The gate instance.
     *
     * @var \Illuminate\Contracts\Auth\Access\Gate
     */
    protected $gate;

    /**
     * Create a new middleware instance.
     *
     * @param  \Illuminate\Contracts\Auth\Access\Gate  $gate
     * @return void
     */
    public function __construct(Gate $gate)
    {
        $this->gate = $gate;
    }

    /**
     * Specify the ability and models for the middleware.
     *
     * @param  string  $ability
     * @param  string  ...$models
     * @return string
     */
    public static function using($ability, ...$models)
    {
        return static::class.':'.implode(',', [$ability, ...$models]);
    }

    /**
     * Handle an incoming request.
     *
     * @param  \Illuminate\Http\Request  $request
     * @param  \Closure  $next
     * @param  string  $ability
     * @param  array|null  ...$models
     * @return mixed
     *
     * @throws \Illuminate\Auth\AuthenticationException
     * @throws \Illuminate\Auth\Access\AuthorizationException
     */
    public function handle($request, Closure $next, $ability, ...$models)
    {
        $this->gate->authorize($ability, $this->getGateArguments($request, $models));

        return $next($request);
    }

    /**
     * Get the arguments parameter for the gate.
     *
     * @param  \Illuminate\Http\Request  $request
     * @param  array|null  $models
     * @return \Illuminate\Database\Eloquent\Model|array|string
     */
    protected function getGateArguments($request, $models)
    {
        if (is_null($models)) {
            return [];
        }

        return collect($models)->map(function ($model) use ($request) {
            return $model instanceof Model ? $model : $this->getModel($request, $model);
        })->all();
    }

    /**
     * Get the model to authorize.
     *
     * @param  \Illuminate\Http\Request  $request
     * @param  string  $model
     * @return \Illuminate\Database\Eloquent\Model|string
     */
    protected function getModel($request, $model)
    {
        if ($this->isClassName($model)) {
            return trim($model);
        }

        return $request->route($model, null) ??
            ((preg_match("/^['\"](.*)['\"]$/", trim($model), $matches)) ? $matches[1] : null);
    }

    /**
     * Checks if the given string looks like a fully qualified class name.
     *
     * @param  string  $value
     * @return bool
     */
    protected function isClassName($value)
    {
        return str_contains($value, '\\');
    }
}
PK       ! |㇣D  D  &  Middleware/RedirectIfAuthenticated.phpnu Iw        <?php

namespace Illuminate\Auth\Middleware;

use Closure;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Auth;
use Illuminate\Support\Facades\Route;
use Symfony\Component\HttpFoundation\Response;

class RedirectIfAuthenticated
{
    /**
     * The callback that should be used to generate the authentication redirect path.
     *
     * @var callable|null
     */
    protected static $redirectToCallback;

    /**
     * Handle an incoming request.
     *
     * @param  \Closure(\Illuminate\Http\Request): (\Symfony\Component\HttpFoundation\Response)  $next
     */
    public function handle(Request $request, Closure $next, string ...$guards): Response
    {
        $guards = empty($guards) ? [null] : $guards;

        foreach ($guards as $guard) {
            if (Auth::guard($guard)->check()) {
                return redirect($this->redirectTo($request));
            }
        }

        return $next($request);
    }

    /**
     * Get the path the user should be redirected to when they are authenticated.
     */
    protected function redirectTo(Request $request): ?string
    {
        return static::$redirectToCallback
            ? call_user_func(static::$redirectToCallback, $request)
            : $this->defaultRedirectUri();
    }

    /**
     * Get the default URI the user should be redirected to when they are authenticated.
     */
    protected function defaultRedirectUri(): string
    {
        foreach (['dashboard', 'home'] as $uri) {
            if (Route::has($uri)) {
                return route($uri);
            }
        }

        $routes = Route::getRoutes()->get('GET');

        foreach (['dashboard', 'home'] as $uri) {
            if (isset($routes[$uri])) {
                return '/'.$uri;
            }
        }

        return '/';
    }

    /**
     * Specify the callback that should be used to generate the redirect path.
     *
     * @param  callable  $redirectToCallback
     * @return void
     */
    public static function redirectUsing(callable $redirectToCallback)
    {
        static::$redirectToCallback = $redirectToCallback;
    }
}
PK       ! ~VY  Y    Middleware/RequirePassword.phpnu ȯ        <?php

namespace Illuminate\Auth\Middleware;

use Closure;
use Illuminate\Contracts\Routing\ResponseFactory;
use Illuminate\Contracts\Routing\UrlGenerator;

class RequirePassword
{
    /**
     * The response factory instance.
     *
     * @var \Illuminate\Contracts\Routing\ResponseFactory
     */
    protected $responseFactory;

    /**
     * The URL generator instance.
     *
     * @var \Illuminate\Contracts\Routing\UrlGenerator
     */
    protected $urlGenerator;

    /**
     * The password timeout.
     *
     * @var int
     */
    protected $passwordTimeout;

    /**
     * Create a new middleware instance.
     *
     * @param  \Illuminate\Contracts\Routing\ResponseFactory  $responseFactory
     * @param  \Illuminate\Contracts\Routing\UrlGenerator  $urlGenerator
     * @param  int|null  $passwordTimeout
     * @return void
     */
    public function __construct(ResponseFactory $responseFactory, UrlGenerator $urlGenerator, $passwordTimeout = null)
    {
        $this->responseFactory = $responseFactory;
        $this->urlGenerator = $urlGenerator;
        $this->passwordTimeout = $passwordTimeout ?: 10800;
    }

    /**
     * Specify the redirect route and timeout for the middleware.
     *
     * @param  string|null  $redirectToRoute
     * @param  string|int|null  $passwordTimeoutSeconds
     * @return string
     *
     * @named-arguments-supported
     */
    public static function using($redirectToRoute = null, $passwordTimeoutSeconds = null)
    {
        return static::class.':'.implode(',', func_get_args());
    }

    /**
     * Handle an incoming request.
     *
     * @param  \Illuminate\Http\Request  $request
     * @param  \Closure  $next
     * @param  string|null  $redirectToRoute
     * @param  string|int|null  $passwordTimeoutSeconds
     * @return mixed
     */
    public function handle($request, Closure $next, $redirectToRoute = null, $passwordTimeoutSeconds = null)
    {
        if ($this->shouldConfirmPassword($request, $passwordTimeoutSeconds)) {
            if ($request->expectsJson()) {
                return $this->responseFactory->json([
                    'message' => 'Password confirmation required.',
                ], 423);
            }

            return $this->responseFactory->redirectGuest(
                $this->urlGenerator->route($redirectToRoute ?: 'password.confirm')
            );
        }

        return $next($request);
    }

    /**
     * Determine if the confirmation timeout has expired.
     *
     * @param  \Illuminate\Http\Request  $request
     * @param  int|null  $passwordTimeoutSeconds
     * @return bool
     */
    protected function shouldConfirmPassword($request, $passwordTimeoutSeconds = null)
    {
        $confirmedAt = time() - $request->session()->get('auth.password_confirmed_at', 0);

        return $confirmedAt > ($passwordTimeoutSeconds ?? $this->passwordTimeout);
    }
}
PK       ! \F      bootstrap-stubs/home.stubnu ̗        @extends('layouts.app')

@section('content')
<div class="container">
    <div class="row justify-content-center">
        <div class="col-md-8">
            <div class="card">
                <div class="card-header">{{ __('Dashboard') }}</div>

                <div class="card-body">
                    @if (session('status'))
                        <div class="alert alert-success" role="alert">
                            {{ session('status') }}
                        </div>
                    @endif

                    {{ __('You are logged in!') }}
                </div>
            </div>
        </div>
    </div>
</div>
@endsection
PK       ! $>,  ,  "  bootstrap-stubs/auth/register.stubnu ̗        @extends('layouts.app')

@section('content')
<div class="container">
    <div class="row justify-content-center">
        <div class="col-md-8">
            <div class="card">
                <div class="card-header">{{ __('Register') }}</div>

                <div class="card-body">
                    <form method="POST" action="{{ route('register') }}">
                        @csrf

                        <div class="row mb-3">
                            <label for="name" class="col-md-4 col-form-label text-md-end">{{ __('Name') }}</label>

                            <div class="col-md-6">
                                <input id="name" type="text" class="form-control @error('name') is-invalid @enderror" name="name" value="{{ old('name') }}" required autocomplete="name" autofocus>

                                @error('name')
                                    <span class="invalid-feedback" role="alert">
                                        <strong>{{ $message }}</strong>
                                    </span>
                                @enderror
                            </div>
                        </div>

                        <div class="row mb-3">
                            <label for="email" class="col-md-4 col-form-label text-md-end">{{ __('Email Address') }}</label>

                            <div class="col-md-6">
                                <input id="email" type="email" class="form-control @error('email') is-invalid @enderror" name="email" value="{{ old('email') }}" required autocomplete="email">

                                @error('email')
                                    <span class="invalid-feedback" role="alert">
                                        <strong>{{ $message }}</strong>
                                    </span>
                                @enderror
                            </div>
                        </div>

                        <div class="row mb-3">
                            <label for="password" class="col-md-4 col-form-label text-md-end">{{ __('Password') }}</label>

                            <div class="col-md-6">
                                <input id="password" type="password" class="form-control @error('password') is-invalid @enderror" name="password" required autocomplete="new-password">

                                @error('password')
                                    <span class="invalid-feedback" role="alert">
                                        <strong>{{ $message }}</strong>
                                    </span>
                                @enderror
                            </div>
                        </div>

                        <div class="row mb-3">
                            <label for="password-confirm" class="col-md-4 col-form-label text-md-end">{{ __('Confirm Password') }}</label>

                            <div class="col-md-6">
                                <input id="password-confirm" type="password" class="form-control" name="password_confirmation" required autocomplete="new-password">
                            </div>
                        </div>

                        <div class="row mb-0">
                            <div class="col-md-6 offset-md-4">
                                <button type="submit" class="btn btn-primary">
                                    {{ __('Register') }}
                                </button>
                            </div>
                        </div>
                    </form>
                </div>
            </div>
        </div>
    </div>
</div>
@endsection
PK       ! .On  n     bootstrap-stubs/auth/verify.stubnu ̗        @extends('layouts.app')

@section('content')
<div class="container">
    <div class="row justify-content-center">
        <div class="col-md-8">
            <div class="card">
                <div class="card-header">{{ __('Verify Your Email Address') }}</div>

                <div class="card-body">
                    @if (session('resent'))
                        <div class="alert alert-success" role="alert">
                            {{ __('A fresh verification link has been sent to your email address.') }}
                        </div>
                    @endif

                    {{ __('Before proceeding, please check your email for a verification link.') }}
                    {{ __('If you did not receive the email') }},
                    <form class="d-inline" method="POST" action="{{ route('verification.resend') }}">
                        @csrf
                        <button type="submit" class="btn btn-link p-0 m-0 align-baseline">{{ __('click here to request another') }}</button>.
                    </form>
                </div>
            </div>
        </div>
    </div>
</div>
@endsection
PK       !  [    +  bootstrap-stubs/auth/passwords/confirm.stubnu ̗        @extends('layouts.app')

@section('content')
<div class="container">
    <div class="row justify-content-center">
        <div class="col-md-8">
            <div class="card">
                <div class="card-header">{{ __('Confirm Password') }}</div>

                <div class="card-body">
                    {{ __('Please confirm your password before continuing.') }}

                    <form method="POST" action="{{ route('password.confirm') }}">
                        @csrf

                        <div class="row mb-3">
                            <label for="password" class="col-md-4 col-form-label text-md-end">{{ __('Password') }}</label>

                            <div class="col-md-6">
                                <input id="password" type="password" class="form-control @error('password') is-invalid @enderror" name="password" required autocomplete="current-password">

                                @error('password')
                                    <span class="invalid-feedback" role="alert">
                                        <strong>{{ $message }}</strong>
                                    </span>
                                @enderror
                            </div>
                        </div>

                        <div class="row mb-0">
                            <div class="col-md-8 offset-md-4">
                                <button type="submit" class="btn btn-primary">
                                    {{ __('Confirm Password') }}
                                </button>

                                @if (Route::has('password.request'))
                                    <a class="btn btn-link" href="{{ route('password.request') }}">
                                        {{ __('Forgot Your Password?') }}
                                    </a>
                                @endif
                            </div>
                        </div>
                    </form>
                </div>
            </div>
        </div>
    </div>
</div>
@endsection
PK       ! sKjf  f  )  bootstrap-stubs/auth/passwords/email.stubnu ̗        @extends('layouts.app')

@section('content')
<div class="container">
    <div class="row justify-content-center">
        <div class="col-md-8">
            <div class="card">
                <div class="card-header">{{ __('Reset Password') }}</div>

                <div class="card-body">
                    @if (session('status'))
                        <div class="alert alert-success" role="alert">
                            {{ session('status') }}
                        </div>
                    @endif

                    <form method="POST" action="{{ route('password.email') }}">
                        @csrf

                        <div class="row mb-3">
                            <label for="email" class="col-md-4 col-form-label text-md-end">{{ __('Email Address') }}</label>

                            <div class="col-md-6">
                                <input id="email" type="email" class="form-control @error('email') is-invalid @enderror" name="email" value="{{ old('email') }}" required autocomplete="email" autofocus>

                                @error('email')
                                    <span class="invalid-feedback" role="alert">
                                        <strong>{{ $message }}</strong>
                                    </span>
                                @enderror
                            </div>
                        </div>

                        <div class="row mb-0">
                            <div class="col-md-6 offset-md-4">
                                <button type="submit" class="btn btn-primary">
                                    {{ __('Send Password Reset Link') }}
                                </button>
                            </div>
                        </div>
                    </form>
                </div>
            </div>
        </div>
    </div>
</div>
@endsection
PK       ! CTF    )  bootstrap-stubs/auth/passwords/reset.stubnu ̗        @extends('layouts.app')

@section('content')
<div class="container">
    <div class="row justify-content-center">
        <div class="col-md-8">
            <div class="card">
                <div class="card-header">{{ __('Reset Password') }}</div>

                <div class="card-body">
                    <form method="POST" action="{{ route('password.update') }}">
                        @csrf

                        <input type="hidden" name="token" value="{{ $token }}">

                        <div class="row mb-3">
                            <label for="email" class="col-md-4 col-form-label text-md-end">{{ __('Email Address') }}</label>

                            <div class="col-md-6">
                                <input id="email" type="email" class="form-control @error('email') is-invalid @enderror" name="email" value="{{ $email ?? old('email') }}" required autocomplete="email" autofocus>

                                @error('email')
                                    <span class="invalid-feedback" role="alert">
                                        <strong>{{ $message }}</strong>
                                    </span>
                                @enderror
                            </div>
                        </div>

                        <div class="row mb-3">
                            <label for="password" class="col-md-4 col-form-label text-md-end">{{ __('Password') }}</label>

                            <div class="col-md-6">
                                <input id="password" type="password" class="form-control @error('password') is-invalid @enderror" name="password" required autocomplete="new-password">

                                @error('password')
                                    <span class="invalid-feedback" role="alert">
                                        <strong>{{ $message }}</strong>
                                    </span>
                                @enderror
                            </div>
                        </div>

                        <div class="row mb-3">
                            <label for="password-confirm" class="col-md-4 col-form-label text-md-end">{{ __('Confirm Password') }}</label>

                            <div class="col-md-6">
                                <input id="password-confirm" type="password" class="form-control" name="password_confirmation" required autocomplete="new-password">
                            </div>
                        </div>

                        <div class="row mb-0">
                            <div class="col-md-6 offset-md-4">
                                <button type="submit" class="btn btn-primary">
                                    {{ __('Reset Password') }}
                                </button>
                            </div>
                        </div>
                    </form>
                </div>
            </div>
        </div>
    </div>
</div>
@endsection
PK       ! 8%g      bootstrap-stubs/auth/login.stubnu ̗        @extends('layouts.app')

@section('content')
<div class="container">
    <div class="row justify-content-center">
        <div class="col-md-8">
            <div class="card">
                <div class="card-header">{{ __('Login') }}</div>

                <div class="card-body">
                    <form method="POST" action="{{ route('login') }}">
                        @csrf

                        <div class="row mb-3">
                            <label for="email" class="col-md-4 col-form-label text-md-end">{{ __('Email Address') }}</label>

                            <div class="col-md-6">
                                <input id="email" type="email" class="form-control @error('email') is-invalid @enderror" name="email" value="{{ old('email') }}" required autocomplete="email" autofocus>

                                @error('email')
                                    <span class="invalid-feedback" role="alert">
                                        <strong>{{ $message }}</strong>
                                    </span>
                                @enderror
                            </div>
                        </div>

                        <div class="row mb-3">
                            <label for="password" class="col-md-4 col-form-label text-md-end">{{ __('Password') }}</label>

                            <div class="col-md-6">
                                <input id="password" type="password" class="form-control @error('password') is-invalid @enderror" name="password" required autocomplete="current-password">

                                @error('password')
                                    <span class="invalid-feedback" role="alert">
                                        <strong>{{ $message }}</strong>
                                    </span>
                                @enderror
                            </div>
                        </div>

                        <div class="row mb-3">
                            <div class="col-md-6 offset-md-4">
                                <div class="form-check">
                                    <input class="form-check-input" type="checkbox" name="remember" id="remember" {{ old('remember') ? 'checked' : '' }}>

                                    <label class="form-check-label" for="remember">
                                        {{ __('Remember Me') }}
                                    </label>
                                </div>
                            </div>
                        </div>

                        <div class="row mb-0">
                            <div class="col-md-8 offset-md-4">
                                <button type="submit" class="btn btn-primary">
                                    {{ __('Login') }}
                                </button>

                                @if (Route::has('password.request'))
                                    <a class="btn btn-link" href="{{ route('password.request') }}">
                                        {{ __('Forgot Your Password?') }}
                                    </a>
                                @endif
                            </div>
                        </div>
                    </form>
                </div>
            </div>
        </div>
    </div>
</div>
@endsection
PK       ! ӭm0       bootstrap-stubs/layouts/app.stubnu ̗        <!doctype html>
<html lang="{{ str_replace('_', '-', app()->getLocale()) }}">
<head>
    <meta charset="utf-8">
    <meta name="viewport" content="width=device-width, initial-scale=1">

    <!-- CSRF Token -->
    <meta name="csrf-token" content="{{ csrf_token() }}">

    <title>{{ config('app.name', 'Laravel') }}</title>

    <!-- Scripts -->
    <script src="{{ asset('js/app.js') }}" defer></script>

    <!-- Fonts -->
    <link rel="dns-prefetch" href="//fonts.gstatic.com">
    <link href="https://fonts.googleapis.com/css?family=Nunito" rel="stylesheet">

    <!-- Styles -->
    <link href="{{ asset('css/app.css') }}" rel="stylesheet">
</head>
<body>
    <div id="app">
        <nav class="navbar navbar-expand-md navbar-light bg-white shadow-sm">
            <div class="container">
                <a class="navbar-brand" href="{{ url('/') }}">
                    {{ config('app.name', 'Laravel') }}
                </a>
                <button class="navbar-toggler" type="button" data-bs-toggle="collapse" data-bs-target="#navbarSupportedContent" aria-controls="navbarSupportedContent" aria-expanded="false" aria-label="{{ __('Toggle navigation') }}">
                    <span class="navbar-toggler-icon"></span>
                </button>

                <div class="collapse navbar-collapse" id="navbarSupportedContent">
                    <!-- Left Side Of Navbar -->
                    <ul class="navbar-nav me-auto">

                    </ul>

                    <!-- Right Side Of Navbar -->
                    <ul class="navbar-nav ms-auto">
                        <!-- Authentication Links -->
                        @guest
                            @if (Route::has('login'))
                                <li class="nav-item">
                                    <a class="nav-link" href="{{ route('login') }}">{{ __('Login') }}</a>
                                </li>
                            @endif

                            @if (Route::has('register'))
                                <li class="nav-item">
                                    <a class="nav-link" href="{{ route('register') }}">{{ __('Register') }}</a>
                                </li>
                            @endif
                        @else
                            <li class="nav-item dropdown">
                                <a id="navbarDropdown" class="nav-link dropdown-toggle" href="#" role="button" data-bs-toggle="dropdown" aria-haspopup="true" aria-expanded="false" v-pre>
                                    {{ Auth::user()->name }}
                                </a>

                                <div class="dropdown-menu dropdown-menu-end" aria-labelledby="navbarDropdown">
                                    <a class="dropdown-item" href="{{ route('logout') }}"
                                       onclick="event.preventDefault();
                                                     document.getElementById('logout-form').submit();">
                                        {{ __('Logout') }}
                                    </a>

                                    <form id="logout-form" action="{{ route('logout') }}" method="POST" class="d-none">
                                        @csrf
                                    </form>
                                </div>
                            </li>
                        @endguest
                    </ul>
                </div>
            </div>
        </nav>

        <main class="py-4">
            @yield('content')
        </main>
    </div>
</body>
</html>
PK       ! w?l   l     stubs/routes.stubnu ̗        
Auth::routes();

Route::get('/home', [App\Http\Controllers\HomeController::class, 'index'])->name('home');
PK       ! Id    %  stubs/controllers/HomeController.stubnu ̗        <?php

namespace {{namespace}}Http\Controllers;

use Illuminate\Http\Request;

class HomeController extends Controller
{
    /**
     * Create a new controller instance.
     *
     * @return void
     */
    public function __construct()
    {
        $this->middleware('auth');
    }

    /**
     * Show the application dashboard.
     *
     * @return \Illuminate\Contracts\Support\Renderable
     */
    public function index()
    {
        return view('home');
    }
}
PK       ! -j  j    VerificationController.stubnu ̗        <?php

namespace App\Http\Controllers\Auth;

use App\Http\Controllers\Controller;
use App\Providers\RouteServiceProvider;
use Illuminate\Foundation\Auth\VerifiesEmails;

class VerificationController extends Controller
{
    /*
    |--------------------------------------------------------------------------
    | Email Verification Controller
    |--------------------------------------------------------------------------
    |
    | This controller is responsible for handling email verification for any
    | user that recently registered with the application. Emails may also
    | be re-sent if the user didn't receive the original email message.
    |
    */

    use VerifiesEmails;

    /**
     * Where to redirect users after verification.
     *
     * @var string
     */
    protected $redirectTo = RouteServiceProvider::HOME;

    /**
     * Create a new controller instance.
     *
     * @return void
     */
    public function __construct()
    {
        $this->middleware('auth');
        $this->middleware('signed')->only('verify');
        $this->middleware('throttle:6,1')->only('verify', 'resend');
    }
}
PK       ! [        ConfirmPasswordController.stubnu ̗        <?php

namespace App\Http\Controllers\Auth;

use App\Http\Controllers\Controller;
use App\Providers\RouteServiceProvider;
use Illuminate\Foundation\Auth\ConfirmsPasswords;

class ConfirmPasswordController extends Controller
{
    /*
    |--------------------------------------------------------------------------
    | Confirm Password Controller
    |--------------------------------------------------------------------------
    |
    | This controller is responsible for handling password confirmations and
    | uses a simple trait to include the behavior. You're free to explore
    | this trait and override any functions that require customization.
    |
    */

    use ConfirmsPasswords;

    /**
     * Where to redirect users when the intended url fails.
     *
     * @var string
     */
    protected $redirectTo = RouteServiceProvider::HOME;

    /**
     * Create a new controller instance.
     *
     * @return void
     */
    public function __construct()
    {
        $this->middleware('auth');
    }
}
PK       ! qL  L    ResetPasswordController.stubnu ̗        <?php

namespace App\Http\Controllers\Auth;

use App\Http\Controllers\Controller;
use App\Providers\RouteServiceProvider;
use Illuminate\Foundation\Auth\ResetsPasswords;

class ResetPasswordController extends Controller
{
    /*
    |--------------------------------------------------------------------------
    | Password Reset Controller
    |--------------------------------------------------------------------------
    |
    | This controller is responsible for handling password reset requests
    | and uses a simple trait to include this behavior. You're free to
    | explore this trait and override any methods you wish to tweak.
    |
    */

    use ResetsPasswords;

    /**
     * Where to redirect users after resetting their password.
     *
     * @var string
     */
    protected $redirectTo = RouteServiceProvider::HOME;
}
PK       ! 7      RegisterController.stubnu ̗        <?php

namespace App\Http\Controllers\Auth;

use App\Http\Controllers\Controller;
use App\Providers\RouteServiceProvider;
use App\Models\User;
use Illuminate\Foundation\Auth\RegistersUsers;
use Illuminate\Support\Facades\Hash;
use Illuminate\Support\Facades\Validator;

class RegisterController extends Controller
{
    /*
    |--------------------------------------------------------------------------
    | Register Controller
    |--------------------------------------------------------------------------
    |
    | This controller handles the registration of new users as well as their
    | validation and creation. By default this controller uses a trait to
    | provide this functionality without requiring any additional code.
    |
    */

    use RegistersUsers;

    /**
     * Where to redirect users after registration.
     *
     * @var string
     */
    protected $redirectTo = RouteServiceProvider::HOME;

    /**
     * Create a new controller instance.
     *
     * @return void
     */
    public function __construct()
    {
        $this->middleware('guest');
    }

    /**
     * Get a validator for an incoming registration request.
     *
     * @param  array  $data
     * @return \Illuminate\Contracts\Validation\Validator
     */
    protected function validator(array $data)
    {
        return Validator::make($data, [
            'name' => ['required', 'string', 'max:255'],
            'email' => ['required', 'string', 'email', 'max:255', 'unique:users'],
            'password' => ['required', 'string', 'min:8', 'confirmed'],
        ]);
    }

    /**
     * Create a new user instance after a valid registration.
     *
     * @param  array  $data
     * @return \App\Models\User
     */
    protected function create(array $data)
    {
        return User::create([
            'name' => $data['name'],
            'email' => $data['email'],
            'password' => Hash::make($data['password']),
        ]);
    }
}
PK       ! K      ForgotPasswordController.stubnu ̗        <?php

namespace App\Http\Controllers\Auth;

use App\Http\Controllers\Controller;
use Illuminate\Foundation\Auth\SendsPasswordResetEmails;

class ForgotPasswordController extends Controller
{
    /*
    |--------------------------------------------------------------------------
    | Password Reset Controller
    |--------------------------------------------------------------------------
    |
    | This controller is responsible for handling password reset emails and
    | includes a trait which assists in sending these notifications from
    | your application to your users. Feel free to explore this trait.
    |
    */

    use SendsPasswordResetEmails;
}
PK       ! gkHo      LoginController.stubnu ̗        <?php

namespace App\Http\Controllers\Auth;

use App\Http\Controllers\Controller;
use App\Providers\RouteServiceProvider;
use Illuminate\Foundation\Auth\AuthenticatesUsers;

class LoginController extends Controller
{
    /*
    |--------------------------------------------------------------------------
    | Login Controller
    |--------------------------------------------------------------------------
    |
    | This controller handles authenticating users for the application and
    | redirecting them to your home screen. The controller uses a trait
    | to conveniently provide its functionality to your applications.
    |
    */

    use AuthenticatesUsers;

    /**
     * Where to redirect users after login.
     *
     * @var string
     */
    protected $redirectTo = RouteServiceProvider::HOME;

    /**
     * Create a new controller instance.
     *
     * @return void
     */
    public function __construct()
    {
        $this->middleware('guest')->except('logout');
    }
}
PK       ! w    "  Passwords/CacheTokenRepository.phpnu Iw        <?php

namespace Illuminate\Auth\Passwords;

use Illuminate\Cache\Repository;
use Illuminate\Contracts\Auth\CanResetPassword as CanResetPasswordContract;
use Illuminate\Contracts\Hashing\Hasher as HasherContract;
use Illuminate\Support\Carbon;
use Illuminate\Support\Str;

class CacheTokenRepository implements TokenRepositoryInterface
{
    /**
     * The format of the stored Carbon object.
     */
    protected string $format = 'Y-m-d H:i:s';

    /**
     * Create a new token repository instance.
     */
    public function __construct(
        protected Repository $cache,
        protected HasherContract $hasher,
        protected string $hashKey,
        protected int $expires = 3600,
        protected int $throttle = 60,
    ) {
    }

    /**
     * Create a new token.
     *
     * @param  \Illuminate\Contracts\Auth\CanResetPassword  $user
     * @return string
     */
    public function create(CanResetPasswordContract $user)
    {
        $this->delete($user);

        $token = hash_hmac('sha256', Str::random(40), $this->hashKey);

        $this->cache->put(
            $this->cacheKey($user),
            [$this->hasher->make($token), Carbon::now()->format($this->format)],
            $this->expires,
        );

        return $token;
    }

    /**
     * Determine if a token record exists and is valid.
     *
     * @param  \Illuminate\Contracts\Auth\CanResetPassword  $user
     * @param  string  $token
     * @return bool
     */
    public function exists(CanResetPasswordContract $user, #[\SensitiveParameter] $token)
    {
        [$record, $createdAt] = $this->cache->get($this->cacheKey($user));

        return $record
            && ! $this->tokenExpired($createdAt)
            && $this->hasher->check($token, $record);
    }

    /**
     * Determine if the token has expired.
     *
     * @param  string  $createdAt
     * @return bool
     */
    protected function tokenExpired($createdAt)
    {
        return Carbon::createFromFormat($this->format, $createdAt)->addSeconds($this->expires)->isPast();
    }

    /**
     * Determine if the given user recently created a password reset token.
     *
     * @param  \Illuminate\Contracts\Auth\CanResetPassword  $user
     * @return bool
     */
    public function recentlyCreatedToken(CanResetPasswordContract $user)
    {
        [$record, $createdAt] = $this->cache->get($this->cacheKey($user));

        return $record && $this->tokenRecentlyCreated($createdAt);
    }

    /**
     * Determine if the token was recently created.
     *
     * @param  string  $createdAt
     * @return bool
     */
    protected function tokenRecentlyCreated($createdAt)
    {
        if ($this->throttle <= 0) {
            return false;
        }

        return Carbon::createFromFormat($this->format, $createdAt)->addSeconds(
            $this->throttle
        )->isFuture();
    }

    /**
     * Delete a token record.
     *
     * @param  \Illuminate\Contracts\Auth\CanResetPassword  $user
     * @return void
     */
    public function delete(CanResetPasswordContract $user)
    {
        $this->cache->forget($this->cacheKey($user));
    }

    /**
     * Delete expired tokens.
     *
     * @return void
     */
    public function deleteExpired()
    {
    }

    /**
     * Determine the cache key for the given user.
     *
     * @param  \Illuminate\Contracts\Auth\CanResetPassword  $user
     * @return string
     */
    public function cacheKey(CanResetPasswordContract $user): string
    {
        return hash('sha256', $user->getEmailForPasswordReset());
    }
}
PK       !          SignedBodyHeaderType.phpnu [        <?php
/**
 * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
 * SPDX-License-Identifier: Apache-2.0.
 */
namespace AWS\CRT\Auth;

class SignedBodyHeaderType {
    const NONE = 0;
    const X_AMZ_CONTENT_SHA256 = 1;
}PK       ! 
  
    AwsCredentials.phpnu [        <?php
/**
 * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
 * SPDX-License-Identifier: Apache-2.0.
 */
namespace AWS\CRT\Auth;

use AWS\CRT\NativeResource as NativeResource;
use AWS\CRT\Options as Options;

/**
 * Represents a set of AWS credentials
 *
 * @param array options:
 * - string access_key_id - AWS Access Key Id
 * - string secret_access_key - AWS Secret Access Key
 * - string session_token - Optional STS session token
 * - int expiration_timepoint_seconds - Optional time to expire these credentials
 */
final class AwsCredentials extends NativeResource {

    static function defaults() {
        return [
            'access_key_id' => '',
            'secret_access_key' => '',
            'session_token' => '',
            'expiration_timepoint_seconds' => 0,
        ];
    }

    private $access_key_id;
    private $secret_access_key;
    private $session_token;
    private $expiration_timepoint_seconds = 0;

    public function __get($name) {
        return $this->$name;
    }

    function __construct(array $options = []) {
        parent::__construct();

        $options = new Options($options, self::defaults());
        $this->access_key_id = $options->access_key_id->asString();
        $this->secret_access_key = $options->secret_access_key->asString();
        $this->session_token = $options->session_token ? $options->session_token->asString() : null;
        $this->expiration_timepoint_seconds = $options->expiration_timepoint_seconds->asInt();

        if (strlen($this->access_key_id) == 0) {
            throw new \InvalidArgumentException("access_key_id must be provided");
        }
        if (strlen($this->secret_access_key) == 0) {
            throw new \InvalidArgumentException("secret_access_key must be provided");
        }

        $creds_options = self::$crt->aws_credentials_options_new();
        self::$crt->aws_credentials_options_set_access_key_id($creds_options, $this->access_key_id);
        self::$crt->aws_credentials_options_set_secret_access_key($creds_options, $this->secret_access_key);
        self::$crt->aws_credentials_options_set_session_token($creds_options, $this->session_token);
        self::$crt->aws_credentials_options_set_expiration_timepoint_seconds($creds_options, $this->expiration_timepoint_seconds);
        $this->acquire(self::$crt->aws_credentials_new($creds_options));
        self::$crt->aws_credentials_options_release($creds_options);
    }

    function __destruct() {
        self::$crt->aws_credentials_release($this->release());
        parent::__destruct();
    }
}
PK       ! D  D    StaticCredentialsProvider.phpnu [        <?php
/**
 * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
 * SPDX-License-Identifier: Apache-2.0.
 */
namespace AWS\CRT\Auth;

/**
 * Provides a static set of AWS credentials
 *
 * @param array options:
 * - string access_key_id - AWS Access Key Id
 * - string secret_access_key - AWS Secret Access Key
 * - string session_token - Optional STS session token
 */
final class StaticCredentialsProvider extends CredentialsProvider {

    private $credentials;

    public function __get($name) {
        return $this->$name;
    }

    function __construct(array $options = []) {
        parent::__construct();
        $this->credentials = new AwsCredentials($options);

        $provider_options = self::$crt->credentials_provider_static_options_new();
        self::$crt->credentials_provider_static_options_set_access_key_id($provider_options, $this->credentials->access_key_id);
        self::$crt->credentials_provider_static_options_set_secret_access_key($provider_options, $this->credentials->secret_access_key);
        self::$crt->credentials_provider_static_options_set_session_token($provider_options, $this->credentials->session_token);
        $this->acquire(self::$crt->credentials_provider_static_new($provider_options));
        self::$crt->credentials_provider_static_options_release($provider_options);
    }
}
PK       !       SigningConfigAWS.phpnu [        <?php
/**
 * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
 * SPDX-License-Identifier: Apache-2.0.
 */
namespace AWS\CRT\Auth;

use AWS\CRT\NativeResource as NativeResource;
use AWS\CRT\Options as Options;

class SigningConfigAWS extends NativeResource {

    public static function defaults() {
        return [
            'algorithm' => SigningAlgorithm::SIGv4,
            'signature_type' => SignatureType::HTTP_REQUEST_HEADERS,
            'credentials_provider' => null,
            'region' => null,
            'service' => null,
            'use_double_uri_encode' => false,
            'should_normalize_uri_path' => false,
            'omit_session_token' => false,
            'signed_body_value' => null,
            'signed_body_header_type' => SignedBodyHeaderType::NONE,
            'expiration_in_seconds' => 0,
            'date' => time(),
            'should_sign_header' => null,
        ];
    }

    private $options;

    public function __construct(array $options = []) {
        parent::__construct();
        $this->options = $options = new Options($options, self::defaults());
        $sc = $this->acquire(self::$crt->signing_config_aws_new());
        self::$crt->signing_config_aws_set_algorithm($sc, $options->algorithm->asInt());
        self::$crt->signing_config_aws_set_signature_type($sc, $options->signature_type->asInt());
        if ($credentials_provider = $options->credentials_provider->asObject()) {
            self::$crt->signing_config_aws_set_credentials_provider(
                $sc,
                $credentials_provider->native);
        }
        self::$crt->signing_config_aws_set_region(
            $sc, $options->region->asString());
        self::$crt->signing_config_aws_set_service(
            $sc, $options->service->asString());
        self::$crt->signing_config_aws_set_use_double_uri_encode(
            $sc, $options->use_double_uri_encode->asBool());
        self::$crt->signing_config_aws_set_should_normalize_uri_path(
            $sc, $options->should_normalize_uri_path->asBool());
        self::$crt->signing_config_aws_set_omit_session_token(
            $sc, $options->omit_session_token->asBool());
        self::$crt->signing_config_aws_set_signed_body_value(
            $sc, $options->signed_body_value->asString());
        self::$crt->signing_config_aws_set_signed_body_header_type(
            $sc, $options->signed_body_header_type->asInt());
        self::$crt->signing_config_aws_set_expiration_in_seconds(
            $sc, $options->expiration_in_seconds->asInt());
        self::$crt->signing_config_aws_set_date($sc, $options->date->asInt());
        if ($should_sign_header = $options->should_sign_header->asCallable()) {
            self::$crt->signing_config_aws_set_should_sign_header_fn($sc, $should_sign_header);
        }
    }

    function __destruct()
    {
        self::$crt->signing_config_aws_release($this->release());
        parent::__destruct();
    }

    public function __get($name) {
        return $this->options->get($name);
    }
}PK       ! Ov      CredentialsProvider.phpnu [        <?php
/**
 * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
 * SPDX-License-Identifier: Apache-2.0.
 */
namespace AWS\CRT\Auth;

use AWS\CRT\NativeResource as NativeResource;

/**
 * Base class for credentials providers
 */
abstract class CredentialsProvider extends NativeResource {

    function __construct(array $options = []) {
        parent::__construct();
    }

    function __destruct() {
        self::$crt->credentials_provider_release($this->release());
        parent::__destruct();
    }
}
PK       ! BT        SigningAlgorithm.phpnu [        <?php
/**
 * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
 * SPDX-License-Identifier: Apache-2.0.
 */
namespace AWS\CRT\Auth;

class SigningAlgorithm {
    const SIGv4 = 0;
    const SIGv4_ASYMMETRIC = 1;
}
PK       ! !      SignatureType.phpnu [        <?php
/**
 * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
 * SPDX-License-Identifier: Apache-2.0.
 */
namespace AWS\CRT\Auth;

class SignatureType {
    const HTTP_REQUEST_HEADERS = 0;
    const HTTP_REQUEST_QUERY_PARAMS = 1;
    const HTTP_REQUEST_CHUNK = 2;
    const HTTP_REQUEST_EVENT = 3;
    const CANONICAL_REQUEST_HEADERS = 4;
    const CANONICAL_REQUEST_QUERY_PARAMS = 5;
}PK       ! ec      SigningResult.phpnu [        <?php
/**
 * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
 * SPDX-License-Identifier: Apache-2.0.
 */
namespace AWS\CRT\Auth;

use AWS\CRT\NativeResource;
use AWS\CRT\HTTP\Request;

class SigningResult extends NativeResource {
    protected function __construct($native) {
        parent::__construct();

        $this->acquire($native);
    }

    function __destruct() {
        // No destruction necessary, SigningResults are transient, just release
        $this->release();
        parent::__destruct();
    }

    public static function fromNative($ptr) {
        return new SigningResult($ptr);
    }

    public function applyToHttpRequest(&$http_request) {
        self::$crt->signing_result_apply_to_http_request($this->native, $http_request->native);
        // Update http_request from native
        $http_request = Request::unmarshall($http_request->toBlob());
    }
}PK       ! 1e      Signing.phpnu [        <?php
/**
 * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
 * SPDX-License-Identifier: Apache-2.0.
 */
namespace AWS\CRT\Auth;

use AWS\CRT\NativeResource;

abstract class Signing extends NativeResource {
    static function signRequestAws($signable, $signing_config, $on_complete) {
        return self::$crt->sign_request_aws($signable->native, $signing_config->native,
            function($result, $error_code) use ($on_complete) {
                $signing_result = SigningResult::fromNative($result);
                $on_complete($signing_result, $error_code);
            }, null);
    }

    static function testVerifySigV4ASigning($signable, $signing_config, $expected_canonical_request, $signature, $ecc_key_pub_x, $ecc_key_pub_y) {
        return self::$crt->test_verify_sigv4a_signing($signable, $signing_config, $expected_canonical_request, $signature, $ecc_key_pub_x, $ecc_key_pub_y);
    }
}
PK       ! N \  \    Signable.phpnu [        <?php
/**
 * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
 * SPDX-License-Identifier: Apache-2.0.
 */
namespace AWS\CRT\Auth;

use AWS\CRT\IO\InputStream;
use AWS\CRT\NativeResource as NativeResource;

class Signable extends NativeResource {

    public static function fromHttpRequest($http_message) {
        return new Signable(function() use ($http_message) {
            return self::$crt->signable_new_from_http_request($http_message->native);
        });
    }

    public static function fromChunk($chunk_stream, $previous_signature="") {
        if (!($chunk_stream instanceof InputStream)) {
            $chunk_stream = new InputStream($chunk_stream);
        }
        return new Signable(function() use($chunk_stream, $previous_signature) {
            return self::$crt->signable_new_from_chunk($chunk_stream->native, $previous_signature);
        });
    }

    public static function fromCanonicalRequest($canonical_request) {
        return new Signable(function() use($canonical_request) {
            return self::$crt->signable_new_from_canonical_request($canonical_request);
        });
    }

    protected function __construct($ctor) {
        parent::__construct();
        $this->acquire($ctor());
    }

    function __destruct() {
        self::$crt->signable_release($this->release());
        parent::__destruct();
    }
}PK         ! W?                    LoginRequest.phpnu ȯ        PK         ! VN                8  PasswordController.phpnu [        PK         ! ]:  :                VerifyEmailController.phpnu [        PK         ! 搣C  C  %              EmailVerificationPromptController.phpnu [        PK         ! [?    "              AuthenticatedSessionController.phpnu [        PK         ! Eߴ    +            5  EmailVerificationNotificationController.phpnu [        PK         ! El  l              8  NewPasswordController.phpnu [        PK         ! !                A  PasswordResetLinkController.phpnu [        PK         ! :u                F  RegisteredUserController.phpnu [        PK         ! d    !            BM  ConfirmablePasswordController.phpnu [        PK         !                 Q  EmailVerificationTest.phpnu [        PK         ! E                X  RegistrationTest.phpnu [        PK         ! P=	n  n              ,\  PasswordResetTest.phpnu [        PK         ! (  (              c  PasswordConfirmationTest.phpnu [        PK         ! rv'                Sh  PasswordUpdateTest.phpnu [        PK         !                 n  AuthenticationTest.phpnu [        PK         ! 45"  "              tr  ActiveSession.phpnu ȯ        PK         ! pCP+n  n  $            s  Notifications/VerifyEmailWithOtp.phpnu ȯ        PK         ! 7                {  Jobs/ExportUsersCsv.phpnu ȯ        PK         ! %9U                  Jobs/LogActiveSessionJob.phpnu ȯ        PK         ! {  {                Jobs/ExportRolesCsv.phpnu ȯ        PK         ! z                  SocialProfile.phpnu ȯ        PK         ! )?&  &  	            ׍  Oauth.phpnu ȯ        PK         ! sd                !  Traits/HasAvatarAttribute.phpnu ȯ        PK         ! Ĵ,    "            5  Traits/HasDisplayNameAttribute.phpnu ȯ        PK         ! fST  T                Ban.phpnu ȯ        PK         ! M@      "              Fortify/TwoFactorLoginResponse.phpnu ȯ        PK         ! ~O=I;  ;              տ  Fortify/LogoutResponse.phpnu ȯ        PK         !                 Z  Fortify/ResetUserPassword.phpnu ȯ        PK         ! o                M  Fortify/FortifyRegisterUser.phpnu ȯ        PK         ! ЫG  G  "            M  Fortify/FortifyServiceProvider.phpnu ȯ        PK         ! u  u  #              Fortify/PasswordValidationRules.phpnu ȯ        PK         ! +R                  Fortify/UpdateUserPassword.phpnu ȯ        PK         ! oI8                  Fortify/RegisterResponse.phpnu ȯ        PK         ! q  q  $              Fortify/ValidateLoginCredentials.phpnu ȯ        PK         ! Ǥ                  Fortify/LoginResponse.phpnu ȯ        PK         ! E  E  %              Validators/EmailVerifiedValidator.phpnu ȯ        PK         ! 03                u  Validators/PasswordIsValid.phpnu ȯ        PK         ! Y                  Validators/HashIsValid.phpnu ȯ        PK         ! OT1B  B                OtpCode.phpnu ȯ        PK         ! պYF  F  -            H  Permissions/Traits/HasPermissionsRelation.phpnu ȯ        PK         ! 譐ai  i  '              Permissions/Traits/SyncsPermissions.phpnu ȯ        PK         ! ]f 6  6                Permissions/Permission.phpnu ȯ        PK         ! cE    )            + Permissions/Policies/PermissionPolicy.phpnu ȯ        PK         ! Z_+  +  )            j
 Commands/DeleteExpiredOtpCodesCommand.phpnu ȯ        PK         !     %             Commands/DeleteExpiredBansCommand.phpnu ȯ        PK         ! ,    +            	 Controllers/EmailVerificationController.phpnu ȯ        PK         ! 0Lm>  >  $            z Controllers/UserAvatarController.phpnu ȯ        PK         ! .H+    +             Controllers/UserFollowedUsersController.phpnu ȯ        PK         ! }-                 Controllers/UserController.phpnu ȯ        PK         ! $ͮkL  L  '            * Controllers/UserFollowersController.phpnu ȯ        PK         ! !,(xV  V  %            . Controllers/AccessTokenController.phpnu ȯ        PK         ! jx֟	  	  &            h2 Controllers/UserSessionsController.phpnu ȯ        PK         ! #z  z  )            ; Controllers/TwoFactorQrCodeController.phpnu ȯ        PK         ! }                = Controllers/BanController.phpnu ȯ        PK         ! 	  	  $            C Controllers/MobileAuthController.phpnu ȯ        PK         ! $rN  N  $            L Controllers/SocialAuthController.phpnu ȯ        PK         ! Vқ6  6              'a BaseUser.phpnu ȯ        PK         ! g'"%                 Roles/Role.phpnu ȯ        PK         ! P1                ݞ Roles/UserRolesController.phpnu ȯ        PK         ! -'p@?  ?              C Roles/CrupdateRole.phpnu ȯ        PK         ! V                Ȧ Roles/RolesController.phpnu ȯ        PK         !                   Requests/CrupdateUserRequest.phpnu ȯ        PK         ! Q4                  U Events/SocialConnected.phpnu ȯ        PK         ! d                  O Events/UsersDeleted.phpnu ȯ        PK         ! ,x                  ~ Events/SocialLogin.phpnu ȯ        PK         ! G                  p Events/UserCreated.phpnu ȯ        PK         ! 
  
              [ Events/UserAvatarChanged.phpnu ȯ        PK         ! T,d  d               Actions/DeleteUsers.phpnu ȯ        PK         ! n3x                \ Actions/UpdateUser.phpnu ȯ        PK         ! 
                 Actions/PaginateUsers.phpnu ȯ        PK         ! 2  2               Actions/CreateUser.phpnu ȯ        PK         ! 7zK  K  #              Middleware/OptionalAuthenticate.phpnu ȯ        PK         ! }`    (             Middleware/VerifyApiAccessMiddleware.phpnu ȯ        PK         ! >
<  <               Middleware/ForbidBannedUser.phpnu ȯ        PK         ! RY$,                 LoginAuthenticator.phpnu Iw        PK         ! n?  ?               AuthenticatorInterface.phpnu Iw        PK         ! +q  q               PlainAuthenticator.phpnu Iw        PK         ! b                X XOAuth2Authenticator.phpnu Iw        PK         ! +/  /               CramMd5Authenticator.phpnu Iw        PK         ! C  C  +             Exception/UnresolvedAuthSchemeException.phpnu ȯ        PK         !                  AuthSelectionMiddleware.phpnu ȯ        PK         ! NH  H               AuthSchemeResolverInterface.phpnu ȯ        PK         ! G+  +               AuthSchemeResolver.phpnu ȯ        PK         ! Z	  	  	             Basic.phpnu ̗        PK         ! -x$                A% ResetPasswordController.phpnu ̗        PK         ! K                6* ForgotPasswordController.phpnu ̗        PK         ! -j  j              - VerificationController.phpnu ̗        PK         ! P1`Q  Q              1 LoginController.phpnu ̗        PK         ! [                  e> ConfirmPasswordController.phpnu ̗        PK         ! 7                B RegisterController.phpnu ̗        PK         ! !  !              J AuthManager.phpnu ȯ        PK         ! 123  3              k Notifications/VerifyEmail.phpnu ȯ        PK         ! os                gx Notifications/ResetPassword.phpnu ȯ        PK         ! IE{Z  Z               Console/ClearResetsCommand.phpnu ȯ        PK         ! 1`#  #  )            P Console/stubs/make/views/layouts/app.stubnu ȯ        PK         ! 6Q	    !            ̗ Access/AuthorizationException.phpnu ȯ        PK         ! ^Ԝ                נ Access/Response.phpnu ȯ        PK         ! "؟{d  {d               Access/Gate.phpnu ȯ        PK         ! YZ3F  F               Access/HandlesAuthorization.phpnu ȯ        PK         !                 m Access/Events/GateEvaluated.phpnu ȯ        PK         ! p	\x  x                TokenGuard.phpnu ȯ        PK         ! ]	  	              O. GuardHelpers.phpnu ȯ        PK         ! Ge.	  	              {8 CreatesUserProviders.phpnu ȯ        PK         ! a@e  e              mB DatabaseUserProvider.phpnu ȯ        PK         ! *Do&  &              U AuthServiceProvider.phpnu ȯ        PK         ! O\Z  Z              a Passwords/CanResetPassword.phpnu ȯ        PK         ! HO    *            /d Passwords/PasswordResetServiceProvider.phpnu ȯ        PK         ! KVp_  _  #            {h Passwords/PasswordBrokerManager.phpnu ȯ        PK         ! .=  =  %            -w Passwords/DatabaseTokenRepository.phpnu ȯ        PK         ! s                 Passwords/PasswordBroker.phpnu ȯ        PK         ! Ux2    &             Passwords/TokenRepositoryInterface.phpnu ȯ        PK         ! rl7                 MustVerifyEmail.phpnu ȯ        PK         ! c	  	               GenericUser.phpnu ȯ        PK         ! ,4Z    /            2 Listeners/SendEmailVerificationNotification.phpnu ȯ        PK         ! α3  3  
             LICENSE.mdnu ȯ        PK         ! JJ  J               AuthenticationException.phpnu ȯ        PK         !  9V  V               Recaller.phpnu ȯ        PK         ! =m/                3 composer.jsonnu ȯ        PK         ! i  i              b SessionGuard.phpnu ȯ        PK         ! lTJ  J              ; RequestGuard.phpnu ȯ        PK         ! NO                D EloquentUserProvider.phpnu ȯ        PK         ! XJ:                ] Authenticatable.phpnu ȯ        PK         ! ri=  =              Ud Events/Failed.phpnu ȯ        PK         ! =                g Events/OtherDeviceLogout.phpnu ȯ        PK         ! "(                j Events/CurrentDeviceLogout.phpnu ȯ        PK         ! y                m Events/Logout.phpnu ȯ        PK         ! ~                 [p Events/Registered.phpnu ȯ        PK         ! w:                r Events/Attempting.phpnu ȯ        PK         ! n                u Events/Lockout.phpnu ȯ        PK         ! ӻ0̎                w Events/Authenticated.phpnu ȯ        PK         ! L@                uz Events/PasswordReset.phpnu ȯ        PK         ! Vd                | Events/Validated.phpnu ȯ        PK         ! .c  c                Events/PasswordResetLinkSent.phpnu Iw        PK         ! +I  I              6 Events/Login.phpnu ȯ        PK         ! ^X                 Events/Verified.phpnu ȯ        PK         ! Y  Y  (            ݆ Middleware/AuthenticateWithBasicAuth.phpnu ȯ        PK         ! 弯    $             Middleware/EnsureEmailIsVerified.phpnu ȯ        PK         ! A5w
  w
               Middleware/Authenticate.phpnu ȯ        PK         !  b
  b
              S Middleware/Authorize.phpnu ȯ        PK         ! |㇣D  D  &             Middleware/RedirectIfAuthenticated.phpnu Iw        PK         ! ~VY  Y               Middleware/RequirePassword.phpnu ȯ        PK         ! \F                > bootstrap-stubs/home.stubnu ̗        PK         ! $>,  ,  "             bootstrap-stubs/auth/register.stubnu ̗        PK         ! .On  n                bootstrap-stubs/auth/verify.stubnu ̗        PK         !  [    +            M bootstrap-stubs/auth/passwords/confirm.stubnu ̗        PK         ! sKjf  f  )             bootstrap-stubs/auth/passwords/email.stubnu ̗        PK         ! CTF    )            o bootstrap-stubs/auth/passwords/reset.stubnu ̗        PK         ! 8%g                p bootstrap-stubs/auth/login.stubnu ̗        PK         ! ӭm0                  bootstrap-stubs/layouts/app.stubnu ̗        PK         ! w?l   l               *	 stubs/routes.stubnu ̗        PK         ! Id    %            	 stubs/controllers/HomeController.stubnu ̗        PK         ! -j  j               VerificationController.stubnu ̗        PK         ! [                   ConfirmPasswordController.stubnu ̗        PK         ! qL  L               ResetPasswordController.stubnu ̗        PK         ! 7                 RegisterController.stubnu ̗        PK         ! K                  ForgotPasswordController.stubnu ̗        PK         ! gkHo                ~# LoginController.stubnu ̗        PK         ! w    "            ' Passwords/CacheTokenRepository.phpnu Iw        PK         !                    5 SignedBodyHeaderType.phpnu [        PK         ! 
  
              $7 AwsCredentials.phpnu [        PK         ! D  D              A StaticCredentialsProvider.phpnu [        PK         !                 G SigningConfigAWS.phpnu [        PK         ! Ov                PS CredentialsProvider.phpnu [        PK         ! BT                  U SigningAlgorithm.phpnu [        PK         ! !                V SignatureType.phpnu [        PK         ! ec                X SigningResult.phpnu [        PK         ! 1e                k\ Signing.phpnu [        PK         ! N \  \              E` Signable.phpnu [        PK      <  e