feat(doctor): claim captcha+mobile, owner profile delete, admin map zoom fix
- DoctorClaimController: ALTCHA CaptchaGuard on /claim (dev no-op via ALTCHA_ENABLED=false); optional `mobile` field must match the logged-in user's number (422 ERR_CONFLICT_001 on mismatch) - DoctorController::delete: now IS_AUTHENTICATED_FULLY — admin (any) or the owner of a claimed profile (IDOR-guarded); FK appointment guard kept - DoctorDetailPage address map: MapController calls map.invalidateSize() before flyTo (fixes needing to pick a city twice on a freshly-mounted map); geocode retries once (nominatim empty/429 on first hit) - tests: mobile mismatch, owner-delete allowed + others 403, unclaimed not deletable by random user - docs: doctor-claim.md (mobile+captcha), doctor.md (delete permission) Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -24,6 +24,7 @@ class DoctorClaimController extends BaseController
|
||||
private readonly DoctorClaimService $claimService,
|
||||
private readonly RateLimiterFactory $doctorClaimLimiter,
|
||||
private readonly \App\Doctor\Repository\DoctorClaimRequestRepository $claimRepo,
|
||||
private readonly \App\Shared\Captcha\CaptchaGuard $captcha,
|
||||
) {}
|
||||
|
||||
#[OA\Get(
|
||||
@@ -82,6 +83,9 @@ class DoctorClaimController extends BaseController
|
||||
throw new TooManyRequestsHttpException($limit->getRetryAfter()->getTimestamp() - time());
|
||||
}
|
||||
|
||||
// کپچای ALTCHA (در dev با ALTCHA_ENABLED=false بیاثر) — خطا → ERR_CAPTCHA_001 (422)
|
||||
$this->captcha->assertValid($request);
|
||||
|
||||
$doctor = $this->doctorRepo->findByUuid($uuid);
|
||||
if ($doctor === null) {
|
||||
return $this->error(ErrorCodes::ERR_NOT_FOUND_001, 'پزشک یافت نشد', 404);
|
||||
@@ -92,7 +96,11 @@ class DoctorClaimController extends BaseController
|
||||
$birthDate = trim(\App\Shared\Util\PersianText::normalize((string) ($data['birth_date'] ?? '')));
|
||||
$firstName = trim((string) ($data['first_name'] ?? ''));
|
||||
$lastName = trim((string) ($data['last_name'] ?? ''));
|
||||
$mobile = preg_replace('/\D/', '', \App\Shared\Util\PersianText::normalize((string) ($data['mobile'] ?? '')));
|
||||
|
||||
if ($mobile !== '' && $mobile !== $user->getMobileNumber()) {
|
||||
return $this->error(ErrorCodes::ERR_CONFLICT_001, 'شماره موبایل باید با حساب کاربری شما یکی باشد', 422, 'mobile');
|
||||
}
|
||||
if (!preg_match('/^\d{10}$/', $nationalCode)) {
|
||||
return $this->error(ErrorCodes::ERR_VALIDATION_001, 'کد ملی نامعتبر است', 422, 'national_code');
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user