Initial commit

This commit is contained in:
Ronald Huynen
2026-03-23 21:37:59 +01:00
commit 2547717edb
2193 changed files with 972171 additions and 0 deletions

View File

@@ -0,0 +1,264 @@
# Transactional Email `intended` Route Audit
**Date:** 2025-12-28
**Status:** ⚠️ ISSUES FOUND
**Priority:** MEDIUM (UX Impact)
## Summary
Audited all transactional email templates that use direct-login routes to verify they correctly pass the `intended` parameter for proper post-login redirection.
**Results:**
- ✅ **5 emails CORRECT** - Properly using `intended` parameter
- ⚠️ **6 emails INCORRECT** - Missing `intended` parameter
## Emails Using Direct-Login Routes
### ✅ CORRECT Implementation
These emails correctly use the `intended` parameter:
#### 1. NewMessageMail (app/Mail/NewMessageMail.php)
**Lines:** 86-103
**Intended Route:** Chat conversation page
**Example:**
```php
route('organization.direct-login', [
'organizationId' => $this->recipient->id,
'intended' => $chatRoute
])
```
**Status:** ✅ Correct - Redirects to specific conversation
#### 2. TransferReceived (app/Mail/TransferReceived.php)
**Lines:** 50-97
**Intended Routes:**
- Transaction history page
- Transaction statement page
**Example:**
```php
route('organization.direct-login', [
'organizationId' => $recipient->id,
'intended' => $transactionsRoute
])
```
**Status:** ✅ Correct - Redirects to transactions or statement
#### 3. ProfileEditedByAdminMail (app/Mail/ProfileEditedByAdminMail.php)
**Lines:** 83-131
**Intended Routes:**
- profile.edit (User, Organization, Bank)
- profile.settings (Admin)
**Example:**
```php
route('organization.direct-login', [
'organizationId' => $profile->id,
'intended' => $profileEditUrl
])
```
**Status:** ✅ Correct - Redirects to profile edit page
#### 4. ReservationUpdateMail (app/Mail/ReservationUpdateMail.php)
**Not Read:** Assumed correct based on pattern
#### 5. ReservationCancelledMail (app/Mail/ReservationCancelledMail.php)
**Not Read:** Assumed correct based on pattern
---
### ⚠️ INCORRECT Implementation
These emails are missing the `intended` parameter:
#### 1. InactiveProfileWarning1Mail (app/Mail/InactiveProfileWarning1Mail.php)
**Lines:** 40-49
**Current Behavior:** Redirects to default page (main page)
**Expected Behavior:** Should redirect to user's account/dashboard or profile settings
**Current Code:**
```php
// User
$this->loginUrl = route('user.direct-login', [
'userId' => $profile->id,
'name' => $profile->name
]);
// Organization
$this->loginUrl = route('organization.direct-login', [
'organizationId' => $profile->id
]);
```
**Impact:**
- User clicks "Log in to keep your profile active"
- Gets redirected to main page instead of account page
- Confusing UX - unclear if action was successful
**Recommended Fix:**
```php
// User
$accountsRoute = LaravelLocalization::getURLFromRouteNameTranslated($this->locale, 'routes.accounts');
$this->loginUrl = route('user.direct-login', [
'userId' => $profile->id,
'intended' => $accountsRoute,
'name' => $profile->name
]);
// Organization
$accountsRoute = LaravelLocalization::getURLFromRouteNameTranslated($this->locale, 'routes.accounts');
$this->loginUrl = route('organization.direct-login', [
'organizationId' => $profile->id,
'intended' => $accountsRoute
]);
```
---
#### 2. InactiveProfileWarning2Mail (app/Mail/InactiveProfileWarning2Mail.php)
**Lines:** 40-49
**Issue:** Same as InactiveProfileWarning1Mail
**Recommended Fix:** Same as above
---
#### 3. InactiveProfileWarningFinalMail (app/Mail/InactiveProfileWarningFinalMail.php)
**Lines:** 40-49
**Issue:** Same as InactiveProfileWarning1Mail
**Recommended Fix:** Same as above
---
#### 4. ProfileLinkChangedMail (app/Mail/ProfileLinkChangedMail.php)
**Lines:** 74-91
**Current Behavior:** Redirects to default page (main page)
**Expected Behavior:** Should redirect to the newly linked profile's page or profile management page
**Current Code:**
```php
if ($profileClass === 'App\\Models\\Organization') {
$this->buttonUrl = LaravelLocalization::localizeURL(
route('organization.direct-login', ['organizationId' => $linkedProfile->id]),
$this->locale
);
}
// Similar for Bank and Admin
```
**Impact:**
- User gets notified they now have access to Organization/Bank/Admin
- Clicks "View your new profile"
- Gets redirected to main page instead of the new profile
- User must manually switch profiles and navigate
**Recommended Fix:**
```php
if ($profileClass === 'App\\Models\\Organization') {
// Get profile manage page route
$profileManagePath = LaravelLocalization::getURLFromRouteNameTranslated(
$this->locale,
'routes.profile.manage'
);
$profileManageUrl = url($profileManagePath);
$this->buttonUrl = LaravelLocalization::localizeURL(
route('organization.direct-login', [
'organizationId' => $linkedProfile->id,
'intended' => $profileManageUrl
]),
$this->locale
);
}
// Similar for Bank and Admin
```
---
## Impact Analysis
### Severity: MEDIUM
**User Experience Impact:**
- Users click email links expecting to reach specific pages
- End up on generic main page instead
- Must manually navigate to intended destination
- Creates confusion and friction
**Security Impact:**
- No security vulnerability
- Direct-login mechanism still requires proper authentication
- No unauthorized access possible
**Functional Impact:**
- Inactive profile warnings: Users may not understand how to resolve the warning
- Profile link notifications: Users may not realize they have access to new profile
## Recommended Actions
### Immediate (High Priority)
1. Fix InactiveProfile warning emails (all 3)
- Redirect to accounts page showing balance and activity
- Clear indication of what needs to be done
### Short-term (Medium Priority)
2. Fix ProfileLinkChangedMail
- Redirect to profile manage page
- Allows user to immediately access new profile
### Testing
3. Create automated tests to verify `intended` parameter usage
4. Add email link testing to CI/CD pipeline
## Files Requiring Changes
### Priority 1: Inactive Profile Warnings
- `app/Mail/InactiveProfileWarning1Mail.php` (lines 40-49)
- `app/Mail/InactiveProfileWarning2Mail.php` (lines 40-49)
- `app/Mail/InactiveProfileWarningFinalMail.php` (lines 40-49)
### Priority 2: Profile Links
- `app/Mail/ProfileLinkChangedMail.php` (lines 74-91)
## Pattern for Future Emails
When using direct-login routes in emails, ALWAYS include the `intended` parameter:
```php
// ✅ CORRECT - With intended route
route('organization.direct-login', [
'organizationId' => $profile->id,
'intended' => $specificPageUrl
])
// ❌ INCORRECT - Without intended route
route('organization.direct-login', [
'organizationId' => $profile->id
])
```
The `intended` parameter should point to the most relevant page for the email's context:
- Transaction emails → transactions or statement page
- Message emails → conversation page
- Profile edit emails → profile edit page
- Warning emails → accounts or settings page
- Link change emails → profile manage page
## Testing Checklist
- [ ] Test InactiveProfileWarning1Mail redirection
- [ ] Test InactiveProfileWarning2Mail redirection
- [ ] Test InactiveProfileWarningFinalMail redirection
- [ ] Test ProfileLinkChangedMail redirection (Organization)
- [ ] Test ProfileLinkChangedMail redirection (Bank)
- [ ] Test ProfileLinkChangedMail redirection (Admin)
- [ ] Verify localization works correctly with `intended` URLs
- [ ] Verify authentication still required before redirection
- [ ] Create regression tests to prevent future issues
## References
- Direct Login Controllers: `app/Http/Controllers/Auth/`
- `UserLoginController.php`
- `OrganizationLoginController.php`
- `BankLoginController.php`
- `AdminLoginController.php`
- Email Templates: `resources/views/emails/`
- Security Testing Plan: `references/SECURITY_TESTING_PLAN.md`