Files
crewli/api/app/Http/Controllers/Api/V1/EmailChangeController.php
bert.hausmans 836cffa232 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>
2026-04-14 15:38:54 +02:00

72 lines
2.0 KiB
PHP

<?php
declare(strict_types=1);
namespace App\Http\Controllers\Api\V1;
use App\Http\Controllers\Controller;
use App\Services\EmailChangeService;
use Illuminate\Http\JsonResponse;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Hash;
use Illuminate\Validation\ValidationException;
final class EmailChangeController extends Controller
{
public function __construct(private readonly EmailChangeService $service) {}
/**
* POST /api/v1/me/change-email
* User requests to change their own email.
*/
public function request(Request $request): JsonResponse
{
$validated = $request->validate([
'new_email' => ['required', 'email', 'max:255'],
'password' => ['required'],
'app' => ['required', 'in:app,portal,admin'],
]);
// Verify current password
if (! Hash::check($validated['password'], $request->user()->password)) {
throw ValidationException::withMessages([
'password' => ['Het huidige wachtwoord is onjuist.'],
]);
}
$frontendUrls = [
'admin' => config('app.frontend_admin_url'),
'app' => config('app.frontend_app_url'),
'portal' => config('app.frontend_portal_url'),
];
$this->service->requestChange(
$request->user(),
$validated['new_email'],
$request->user(),
$frontendUrls[$validated['app']],
);
return $this->success(
message: 'Er is een verificatiemail verstuurd naar ' . $validated['new_email'] . '.',
);
}
/**
* POST /api/v1/verify-email-change
* Public endpoint — verifies the token from the email link.
*/
public function verify(Request $request): JsonResponse
{
$validated = $request->validate([
'token' => ['required', 'string'],
]);
$this->service->verifyChange($validated['token']);
return $this->success(
message: 'Je e-mailadres is succesvol gewijzigd.',
);
}
}