fix: login via code
Signed-off-by: Sebastian Krupinski <krupinski01@gmail.com>
This commit is contained in:
@@ -128,7 +128,7 @@ class EnrollmentController extends ControllerAbstract
|
|||||||
/**
|
/**
|
||||||
* Remove TOTP enrollment (disable 2FA)
|
* Remove TOTP enrollment (disable 2FA)
|
||||||
*/
|
*/
|
||||||
#[AuthenticatedRoute('/totp/enroll', name: 'totp.enroll.remove', methods: ['DELETE'])]
|
#[AuthenticatedRoute('/totp/enroll/remove', name: 'totp.enroll.remove', methods: ['POST'])]
|
||||||
public function removeEnrollment(string $code): JsonResponse
|
public function removeEnrollment(string $code): JsonResponse
|
||||||
{
|
{
|
||||||
$userId = $this->userIdentity->identifier();
|
$userId = $this->userIdentity->identifier();
|
||||||
@@ -139,6 +139,13 @@ class EnrollmentController extends ControllerAbstract
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (empty($code)) {
|
||||||
|
return new JsonResponse(
|
||||||
|
['error' => 'Verification code is required', 'error_code' => 'invalid_request'],
|
||||||
|
JsonResponse::HTTP_BAD_REQUEST
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
// Verify current code before removing
|
// Verify current code before removing
|
||||||
$verifyResult = $this->enrollmentService->verifyCode($userId, $code);
|
$verifyResult = $this->enrollmentService->verifyCode($userId, $code);
|
||||||
if (!$verifyResult['success']) {
|
if (!$verifyResult['success']) {
|
||||||
|
|||||||
@@ -128,7 +128,7 @@ class EnrollmentService
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Verify the code
|
// Verify the code
|
||||||
if (!$this->verifyCode($enrollment['secret'], $code)) {
|
if (!$this->verifyTotpCode($enrollment['secret'], $code)) {
|
||||||
return [
|
return [
|
||||||
'success' => false,
|
'success' => false,
|
||||||
'error' => 'Invalid verification code',
|
'error' => 'Invalid verification code',
|
||||||
|
|||||||
@@ -116,9 +116,9 @@ class EnrollmentStore
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get unused recovery codes for a user
|
* Get unused recovery codes for a user, keyed by their original index
|
||||||
*
|
*
|
||||||
* @return array<string> Unused recovery codes
|
* @return array<int, string> Unused recovery codes
|
||||||
*/
|
*/
|
||||||
public function getRecoveryCodes(string $tenantId, string $userId): array
|
public function getRecoveryCodes(string $tenantId, string $userId): array
|
||||||
{
|
{
|
||||||
@@ -130,14 +130,15 @@ class EnrollmentStore
|
|||||||
$codes = $enrollment['recovery_codes'] ?? [];
|
$codes = $enrollment['recovery_codes'] ?? [];
|
||||||
$usedIndices = $enrollment['used_recovery_codes'] ?? [];
|
$usedIndices = $enrollment['used_recovery_codes'] ?? [];
|
||||||
|
|
||||||
// Filter out used codes
|
// Filter out used codes, preserving original indices so callers
|
||||||
|
// can mark the correct code as used
|
||||||
$result = [];
|
$result = [];
|
||||||
foreach ($codes as $index => $code) {
|
foreach ($codes as $index => $code) {
|
||||||
if (!in_array($index, $usedIndices, true)) {
|
if (!in_array($index, $usedIndices, true)) {
|
||||||
$result[] = $code;
|
$result[$index] = $code;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return $result;
|
return $result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -140,9 +140,11 @@ async function disableTotp() {
|
|||||||
disableError.value = ''
|
disableError.value = ''
|
||||||
|
|
||||||
try {
|
try {
|
||||||
const response = await fetch(`${apiBase}/totp/enroll?code=${encodeURIComponent(disableCode.value)}`, {
|
const response = await fetch(`${apiBase}/totp/enroll/remove`, {
|
||||||
method: 'DELETE',
|
method: 'POST',
|
||||||
|
headers: { 'Content-Type': 'application/json' },
|
||||||
credentials: 'include',
|
credentials: 'include',
|
||||||
|
body: JSON.stringify({ code: disableCode.value }),
|
||||||
})
|
})
|
||||||
|
|
||||||
const data = await response.json()
|
const data = await response.json()
|
||||||
|
|||||||
Reference in New Issue
Block a user