# Profile Direct Login Feature ## Overview This feature allows you to create direct links to User, Organization, Bank, and Admin profile logins that can be used in emails or other external communications. The system handles the authentication flow automatically for all profile types, with automatic username pre-filling for better user experience. ## How It Works The direct login route implements a secure, multi-step authentication flow: 1. **User Authentication Check** - If the user is not logged in with their personal User profile, they are redirected to the user login page - **For User profiles**: Username is automatically pre-filled on the login form via URL parameter - After successful user login, they are automatically redirected back to continue the profile switch flow 2. **Relationship Verification** - The system verifies that the authenticated user has access to the specified profile: - **User**: Authenticated user must match the target user - **Organization**: User owns/is a member of the organization - **Bank**: User manages the bank - **Admin**: User has this admin profile - If the user doesn't have access, a 403 Forbidden error is returned 3. **Profile Switch** - **User**: Direct redirect to main page (or custom intended URL) - **Organization**: Direct switch without password (matches normal profile switching behavior) - **Bank**: Redirected to bank password entry page - **Admin**: Redirected to admin password entry page 4. **Final Redirect** - **User**: Redirected to intended URL or main page - **Organization/Bank/Admin**: Redirected to intended URL or main page after profile switch ## Usage ### User Profile To create a link to a user login: ```php route('user.direct-login', ['userId' => $user->id]) ``` **Example URL:** ``` https://yoursite.com/user/123/login ``` With custom intended destination (e.g., profile edit) and username pre-fill: ```php route('user.direct-login', [ 'userId' => $user->id, 'intended' => route('profile.edit'), 'name' => $user->name // Optional: pre-fills username on login form ]) ``` **Example URL with username pre-fill:** ``` https://yoursite.com/nl/user/123/login?intended=https%3A%2F%2Fyoursite.com%2Fnl%2Fprofiel%2Fbewerken&name=johndoe ``` **Note:** - User direct login defaults to redirecting to the main page after login, but you can override this with the `intended` parameter - The `name` parameter is automatically included when generating links via `ProfileEditedByAdminMail` for improved user experience - When the user is redirected to the login page, the username field will be automatically pre-filled with the value from the `name` parameter ### Organization Profile To create a link to an organization login: ```php route('organization.direct-login', ['organizationId' => $organization->id]) ``` **Example URL:** ``` https://yoursite.com/organization/123/login ``` With intended destination: ```php route('organization.direct-login', [ 'organizationId' => $organization->id, 'intended' => route('organization.settings') ]) ``` ### Bank Profile To create a link to a bank login: ```php route('bank.direct-login', ['bankId' => $bank->id]) ``` **Example URL:** ``` https://yoursite.com/bank/456/login ``` With intended destination: ```php route('bank.direct-login', [ 'bankId' => $bank->id, 'intended' => route('transactions.review') ]) ``` ### Admin Profile To create a link to an admin login: ```php route('admin.direct-login', ['adminId' => $admin->id]) ``` **Example URL:** ``` https://yoursite.com/admin/789/login ``` With intended destination: ```php route('admin.direct-login', [ 'adminId' => $admin->id, 'intended' => route('admin.dashboard') ]) ``` ### In Email Templates ```blade Login to {{ $organization->name }} ``` Or with a specific destination: ```blade Edit this post as {{ $organization->name }} ``` ## Security Features ### Multi-Layer Authentication - **User Guard First**: Ensures base authentication is established - **Relationship Verification**: Only users with proper access can switch to the organization - **Password Re-Authentication**: Separate password required for organization access ### Session Management - Profile switch intent is stored in encrypted session - Intended URLs are validated and sanitized - Sessions are cleared after successful authentication ### Access Control - 404 error if organization doesn't exist - 403 error if user doesn't have access to organization - All authentication follows the existing SwitchGuardTrait security pattern ## Flow Diagram ``` User clicks email link | v Is user authenticated? --NO--> User Login --> [Back to this flow] | YES v Does user own/manage org? --NO--> 403 Forbidden | YES v Set profile switch intent | v Organization password page | v Password correct? --NO--> Error message | YES v Switch to Organization guard | v Redirect to intended URL or main page ``` ## Implementation Details ### Route Definitions Located in `routes/web.php`: **User Route (Guest accessible - no auth middleware):** ```php // Located in the guest routes section (line ~182) // Accessible to both authenticated and non-authenticated users Route::get('/user/{userId}/login', [UserLoginController::class, 'directLogin']) ->name('user.direct-login'); ``` **Organization/Bank/Admin Routes (Inside auth middleware group):** ```php // Located inside the auth middleware group (line ~439+) // Require user authentication before accessing Route::get('/organization/{organizationId}/login', [OrganizationLoginController::class, 'directLogin']) ->name('organization.direct-login'); Route::get('/bank/{bankId}/login', [BankLoginController::class, 'directLogin']) ->name('bank.direct-login'); Route::get('/admin/{adminId}/login', [AdminLoginController::class, 'directLogin']) ->name('admin.direct-login'); ``` **Important:** The user route is placed in the guest routes section (outside auth middleware) to allow unauthenticated users to access it. The controller handles authentication checks internally and redirects to login when needed. ### Controller Methods Located in: - `app/Http/Controllers/UserLoginController.php` - `app/Http/Controllers/OrganizationLoginController.php` - `app/Http/Controllers/BankLoginController.php` - `app/Http/Controllers/AdminLoginController.php` Each `directLogin()` method handles: - Profile existence validation - User authentication check - Relationship verification: - **User**: Authenticated user must match target user - **Organization**: User owns/is a member of the organization - **Bank**: User manages the bank - **Admin**: User has this admin profile - Session intent setting (for Organization, Bank, Admin) - Proper redirects for each step **User-specific features:** - **Username Pre-fill**: When redirecting to login, the `name` query parameter is preserved and passed to the login page - **Localized URLs**: Uses `LaravelLocalization` to generate properly localized redirect URLs - **URL Parameter Handling**: The `name` parameter from the direct login URL is forwarded to the login page as a query parameter - The login form reads the `name` parameter via `request()->input('name')` and pre-fills the username field ### Login Form Implementation The login form in `resources/views/auth/login.blade.php` supports username pre-filling via URL parameter: ```blade
``` **Key points:** - The `value` attribute uses `old('name', request()->input('name'))` to: 1. First check for validation errors (old input) 2. Fall back to the URL query parameter if no old input exists - The `autocomplete="username"` attribute helps browsers identify the field correctly - This works for direct URL access (e.g., `/nl/inloggen?name=johndoe`) as well as redirects ### Session Keys Used **For all profile types:** - `url.intended`: Laravel's standard intended redirect URL (used for user login redirect back to profile login) - `intended_profile_switch_type`: Set to 'Organization', 'Bank', or 'Admin' - `intended_profile_switch_id`: Profile ID **Profile-specific:** - `organization_login_intended_url`: Optional final destination URL after organization login - `bank_login_intended_url`: Optional final destination URL after bank login - `admin_login_intended_url`: Optional final destination URL after admin login ## Examples ### Example 1: Simple Profile Login Links ```php // User $url = route('user.direct-login', ['userId' => 123]); // Result: https://yoursite.com/user/123/login // Organization $url = route('organization.direct-login', ['organizationId' => 5]); // Result: https://yoursite.com/organization/5/login // Bank $url = route('bank.direct-login', ['bankId' => 2]); // Result: https://yoursite.com/bank/2/login // Admin $url = route('admin.direct-login', ['adminId' => 1]); // Result: https://yoursite.com/admin/1/login ``` ### Example 2: Deep Links to Specific Pages ```php // User: Direct link to profile edit page $url = route('user.direct-login', [ 'userId' => $user->id, 'intended' => route('profile.edit') ]); // Organization: Direct link to post management page $url = route('organization.direct-login', [ 'organizationId' => $org->id, 'intended' => route('posts.index') ]); // Bank: Direct link to transaction review $url = route('bank.direct-login', [ 'bankId' => $bank->id, 'intended' => route('transactions.pending') ]); // Admin: Direct link to user management $url = route('admin.direct-login', [ 'adminId' => $admin->id, 'intended' => route('admin.users') ]); ``` ### Example 3: In Blade Email Templates **User Profile Edited Notification (Automated via ProfileEditedByAdminMail):** The `ProfileEditedByAdminMail` class automatically generates properly localized URLs with username pre-fill: ```php // In ProfileEditedByAdminMail.php constructor: $profileEditPath = LaravelLocalization::getURLFromRouteNameTranslated( $this->locale, 'routes.profile.edit' ); $profileEditUrl = url($profileEditPath); // Direct user login with redirect to profile.edit and username pre-filled $this->buttonUrl = LaravelLocalization::localizeURL( route('user.direct-login', [ 'userId' => $profile->id, 'intended' => $profileEditUrl, 'name' => $profile->name // Username pre-fill ]), $this->locale ); ``` **Generated URL example:** ``` https://yoursite.com/nl/user/2/login?intended=https%3A%2F%2Fyoursite.com%2Fnl%2Fprofiel%2Fbewerken&name=johndoe ``` **Email template usage:** ```blade @component('emails.layouts.html', ['locale' => $locale])Hello {{ $profile->full_name ?? $profile->name }},
An administrator has made changes to your profile.
| Review Your Profile |
Hello {{ $user->name }},
A new event requires your organization's approval.
| Review Event as {{ $organization->name }} |
Hello {{ $user->name }},
A large transaction requires bank approval.
| Review Transaction as {{ $bank->name }} |
Hello {{ $user->name }},
A user has been reported and requires admin review.
| Review Report as Admin |