feat: tambah profil akun dan ganti password
Tambahkan halaman /dashboard/profile beserta API ganti password untuk user yang sedang login. Rapikan AuthSeeder agar idempotent dan bisa ambil admin email/password dari env.
This commit is contained in:
@@ -62,4 +62,41 @@ class AuthController extends BaseApiController
|
||||
}
|
||||
return $this->successResponse($user, 'Current user');
|
||||
}
|
||||
|
||||
/**
|
||||
* POST /api/auth/change-password
|
||||
* Body: { "current_password": "", "new_password": "" }
|
||||
* User can only change their own password.
|
||||
*/
|
||||
public function changePassword(): ResponseInterface
|
||||
{
|
||||
$user = $this->authService->currentUser();
|
||||
if (!$user) {
|
||||
return $this->errorResponse('Not authenticated', null, null, 401);
|
||||
}
|
||||
|
||||
$input = $this->request->getJSON(true);
|
||||
$currentPassword = $input['current_password'] ?? '';
|
||||
$newPassword = $input['new_password'] ?? '';
|
||||
|
||||
if ($currentPassword === '' || $newPassword === '') {
|
||||
return $this->errorResponse('Current password and new password are required', null, null, 400);
|
||||
}
|
||||
|
||||
if (strlen($newPassword) < 6) {
|
||||
return $this->errorResponse('New password must be at least 6 characters', null, null, 400);
|
||||
}
|
||||
|
||||
$ok = $this->authService->changePassword(
|
||||
(int) $user['id'],
|
||||
$currentPassword,
|
||||
$newPassword
|
||||
);
|
||||
|
||||
if (!$ok) {
|
||||
return $this->errorResponse('Current password is incorrect', null, null, 400);
|
||||
}
|
||||
|
||||
return $this->successResponse(null, 'Password changed successfully');
|
||||
}
|
||||
}
|
||||
|
||||
@@ -14,4 +14,5 @@ $routes->group('api/auth', ['namespace' => 'App\Modules\Auth\Controllers'], func
|
||||
$routes->post('login', 'AuthController::login');
|
||||
$routes->post('logout', 'AuthController::logout');
|
||||
$routes->get('me', 'AuthController::me');
|
||||
$routes->post('change-password', 'AuthController::changePassword');
|
||||
});
|
||||
|
||||
@@ -67,8 +67,9 @@ class AuthService
|
||||
public function currentUser(): ?array
|
||||
{
|
||||
$session = session();
|
||||
$userId = $session->get(self::SESSION_USER_ID);
|
||||
if (!$userId) {
|
||||
$rawUserId = $session->get(self::SESSION_USER_ID);
|
||||
$userId = (int) $rawUserId;
|
||||
if ($userId <= 0) {
|
||||
return null;
|
||||
}
|
||||
|
||||
@@ -81,6 +82,31 @@ class AuthService
|
||||
return $this->userWithRoles($user);
|
||||
}
|
||||
|
||||
/**
|
||||
* Change password for the given user. Verifies current password first.
|
||||
*
|
||||
* @param int $userId
|
||||
* @param string $currentPassword
|
||||
* @param string $newPassword
|
||||
* @return bool True on success, false if current password wrong or user not found
|
||||
*/
|
||||
public function changePassword(int $userId, string $currentPassword, string $newPassword): bool
|
||||
{
|
||||
$user = $this->userModel->find($userId);
|
||||
if (!$user || !$user->isActive()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!password_verify($currentPassword, $user->password_hash)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
$hash = password_hash($newPassword, PASSWORD_DEFAULT);
|
||||
$this->userModel->update($userId, ['password_hash' => $hash]);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Build user array with roles (no password).
|
||||
*/
|
||||
|
||||
Reference in New Issue
Block a user