feat: password reset, email change with verification, and password change
Password reset: multi-app support with custom notification linking to correct frontend (app/portal/admin). Email change: self-service with password confirmation and admin-initiated, both sending verification to new address with 24h expiry. Confirmation sent to old email on completion. Password change: authenticated endpoint revoking other sessions. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -29,6 +29,8 @@ use App\Http\Controllers\Api\V1\VolunteerAvailabilityController;
|
||||
use App\Http\Controllers\Api\V1\VolunteerRegistrationController;
|
||||
use App\Http\Controllers\Api\V1\PublicRegistrationDataController;
|
||||
use App\Http\Controllers\Api\V1\PortalTokenController;
|
||||
use App\Http\Controllers\Api\V1\AccountController;
|
||||
use App\Http\Controllers\Api\V1\EmailChangeController;
|
||||
use App\Http\Controllers\Api\V1\PasswordResetController;
|
||||
use App\Http\Controllers\Api\V1\PortalMeController;
|
||||
use App\Http\Controllers\Api\V1\Portal\PortalShiftController;
|
||||
@@ -66,6 +68,9 @@ Route::post('auth/forgot-password', [PasswordResetController::class, 'sendResetL
|
||||
->middleware('throttle:5,1');
|
||||
Route::post('auth/reset-password', [PasswordResetController::class, 'resetPassword']);
|
||||
|
||||
// Email change verification (public — token from email link)
|
||||
Route::post('verify-email-change', [EmailChangeController::class, 'verify']);
|
||||
|
||||
// Public portal routes
|
||||
Route::get('public/events/{slug}/registration-data', PublicRegistrationDataController::class);
|
||||
Route::post('public/check-email', CheckEmailController::class)->middleware('throttle:10,1');
|
||||
@@ -78,6 +83,10 @@ Route::middleware('auth:sanctum')->group(function () {
|
||||
Route::get('auth/me', MeController::class);
|
||||
Route::post('auth/logout', LogoutController::class);
|
||||
|
||||
// Account management (self-service)
|
||||
Route::post('me/change-password', [AccountController::class, 'changePassword']);
|
||||
Route::post('me/change-email', [EmailChangeController::class, 'request']);
|
||||
|
||||
// Portal (authenticated)
|
||||
Route::get('portal/me', [PortalMeController::class, 'index']);
|
||||
Route::put('portal/profile', [PortalMeController::class, 'updateProfile']);
|
||||
@@ -148,6 +157,7 @@ Route::middleware('auth:sanctum')->group(function () {
|
||||
Route::get('members', [MemberController::class, 'index']);
|
||||
Route::put('members/{user}', [MemberController::class, 'update']);
|
||||
Route::delete('members/{user}', [MemberController::class, 'destroy']);
|
||||
Route::post('members/{user}/change-email', [MemberController::class, 'changeEmail']);
|
||||
|
||||
// Event sub-resources (all nested under organisation prefix — A01-13)
|
||||
Route::prefix('events/{event}')->group(function () {
|
||||
|
||||
Reference in New Issue
Block a user