userModel = new UserModel(); } public function __invoke(ServerRequestInterface $request) { $userId = (int) ($request->getAttribute('user_id') ?? 0); if ($userId <= 0) { return Payload::fail('Unauthorized: Missing authenticated user', [], 'E_VALIDATE', 401); } $body = json_decode((string) $request->getBody(), true) ?: []; $currentPassword = (string) ($body['currentPassword'] ?? ''); $newPassword = (string) ($body['newPassword'] ?? ''); $confirmPassword = (string) ($body['confirmPassword'] ?? ''); $validator = (new Validator([ 'currentPassword' => $currentPassword, 'newPassword' => $newPassword, 'confirmPassword' => $confirmPassword, ])) ->required('currentPassword')->minLength('currentPassword', 8)->maxLength('currentPassword', 255) ->required('newPassword')->minLength('newPassword', 8)->maxLength('newPassword', 255) ->required('confirmPassword')->minLength('confirmPassword', 8)->maxLength('confirmPassword', 255); if ($validator->fails()) { return Payload::fail($validator->firstError() ?? 'Invalid payload', [], 'E_VALIDATE', 400); } if ($newPassword !== $confirmPassword) { return Payload::fail('New password and confirmation do not match', [], 'E_VALIDATE', 400); } if ($currentPassword === $newPassword) { return Payload::fail('New password must be different from current password', [], 'E_VALIDATE', 400); } $result = $this->userModel->changePassword($userId, $currentPassword, $newPassword); if ($result === 'not_found') { return Payload::fail('User not found', [], 'E_NOT_FOUND', 404); } if ($result === 'invalid_current_password') { return Payload::fail('Current password is invalid', [], 'E_VALIDATE', 400); } if ($result === 'error') { return Payload::fail('Failed to update password', [], 'E_GENERIC', 500); } return Payload::ok([], 'S_OK', 'Password updated.'); } }