3 Commits

Author SHA1 Message Date
Sebastian 6d51e9b8f2 Update dependency vue to v3.5.40 2026-07-19 03:04:33 +00:00
Sebastian 5de313b449 fix: remove deprecated baseUrl from module tsconfigs
Signed-off-by: Sebastian Krupinski <krupinski01@gmail.com>
2026-07-18 21:33:56 -04:00
Sebastian 1ddd49d6d7 fix: login via code
Signed-off-by: Sebastian Krupinski <krupinski01@gmail.com>
2026-07-18 21:25:51 -04:00
6 changed files with 68 additions and 72 deletions
+8 -1
View File
@@ -128,7 +128,7 @@ class EnrollmentController extends ControllerAbstract
/**
* 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
{
$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
$verifyResult = $this->enrollmentService->verifyCode($userId, $code);
if (!$verifyResult['success']) {
+1 -1
View File
@@ -128,7 +128,7 @@ class EnrollmentService
}
// Verify the code
if (!$this->verifyCode($enrollment['secret'], $code)) {
if (!$this->verifyTotpCode($enrollment['secret'], $code)) {
return [
'success' => false,
'error' => 'Invalid verification code',
+7 -6
View File
@@ -116,9 +116,9 @@ class EnrollmentStore
}
/**
* Get unused recovery codes for a user
*
* @return array<string> Unused recovery codes
* Get unused recovery codes for a user, keyed by their original index
*
* @return array<int, string> Unused recovery codes
*/
public function getRecoveryCodes(string $tenantId, string $userId): array
{
@@ -130,14 +130,15 @@ class EnrollmentStore
$codes = $enrollment['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 = [];
foreach ($codes as $index => $code) {
if (!in_array($index, $usedIndices, true)) {
$result[] = $code;
$result[$index] = $code;
}
}
return $result;
}
+48 -61
View File
@@ -923,53 +923,53 @@
}
},
"node_modules/@vue/compiler-core": {
"version": "3.5.39",
"resolved": "https://registry.npmjs.org/@vue/compiler-core/-/compiler-core-3.5.39.tgz",
"integrity": "sha512-16KBTEXAJCpDr0mwlw+AZyhu8iyC7R3S2vBwsI7QnWJU6X3WKc9VKeNEZpiMdZ569qWhz9574L3vV55qRL0Vtw==",
"version": "3.5.40",
"resolved": "https://registry.npmjs.org/@vue/compiler-core/-/compiler-core-3.5.40.tgz",
"integrity": "sha512-39E8IgOhTbVDnoJFMKc2DvYnypcZwUqgUhQkccva/0m6FUwtIKSGV7n1hpVmYcFaoRAwf9pBcwnKlCEsN63ZEQ==",
"license": "MIT",
"dependencies": {
"@babel/parser": "^7.29.7",
"@vue/shared": "3.5.39",
"@vue/shared": "3.5.40",
"entities": "^7.0.1",
"estree-walker": "^2.0.2",
"source-map-js": "^1.2.1"
}
},
"node_modules/@vue/compiler-dom": {
"version": "3.5.39",
"resolved": "https://registry.npmjs.org/@vue/compiler-dom/-/compiler-dom-3.5.39.tgz",
"integrity": "sha512-oQPigALqYbNxTNPvNgSOe+czwVExfbVF02lz8jP0S3AXJiu3jxYDygNUiqSep4ezzW8XgnubqH63My2A7JR/vg==",
"version": "3.5.40",
"resolved": "https://registry.npmjs.org/@vue/compiler-dom/-/compiler-dom-3.5.40.tgz",
"integrity": "sha512-pwkx4vqlqOspFstrcmzwkKLePVMD3PT65imRzLhanU2V1Fj4K13g6OXjanOyzw3aTAuRk84BOmY8f3rEHqPaVA==",
"license": "MIT",
"dependencies": {
"@vue/compiler-core": "3.5.39",
"@vue/shared": "3.5.39"
"@vue/compiler-core": "3.5.40",
"@vue/shared": "3.5.40"
}
},
"node_modules/@vue/compiler-sfc": {
"version": "3.5.39",
"resolved": "https://registry.npmjs.org/@vue/compiler-sfc/-/compiler-sfc-3.5.39.tgz",
"integrity": "sha512-d0ki86iOyN8LoZPBmk5SJWNwHP19CnDDCfuo//+2WJa2g5Ke0Jay983PIBIcSSzldC68I8DrD5GrHV3OSDfodg==",
"version": "3.5.40",
"resolved": "https://registry.npmjs.org/@vue/compiler-sfc/-/compiler-sfc-3.5.40.tgz",
"integrity": "sha512-gIf497P4kpuALcvs5n3AEg1Vdn0pSY4XbjASIfHNYF1/MP3T2Mf2STERTubysBxCRxzJGJYtF/O7vwJrxFB3Vw==",
"license": "MIT",
"dependencies": {
"@babel/parser": "^7.29.7",
"@vue/compiler-core": "3.5.39",
"@vue/compiler-dom": "3.5.39",
"@vue/compiler-ssr": "3.5.39",
"@vue/shared": "3.5.39",
"@vue/compiler-core": "3.5.40",
"@vue/compiler-dom": "3.5.40",
"@vue/compiler-ssr": "3.5.40",
"@vue/shared": "3.5.40",
"estree-walker": "^2.0.2",
"magic-string": "^0.30.21",
"postcss": "^8.5.15",
"postcss": "^8.5.19",
"source-map-js": "^1.2.1"
}
},
"node_modules/@vue/compiler-ssr": {
"version": "3.5.39",
"resolved": "https://registry.npmjs.org/@vue/compiler-ssr/-/compiler-ssr-3.5.39.tgz",
"integrity": "sha512-Ce7/wvwMHai74bdszfXExdazFigYnlF9zgCmEQUcM1j0fOymlouZ7XilTYNo8oUjhlnjYOZbGrcYKuqjz89Ucw==",
"version": "3.5.40",
"resolved": "https://registry.npmjs.org/@vue/compiler-ssr/-/compiler-ssr-3.5.40.tgz",
"integrity": "sha512-rrE5xiXG663+vHCHa3J9p2z5OcBRjXmoqenprJxAFQxg5pSshzeBiCE6pu46axapRJ2Adk0YDA2BRZVjiHXnhg==",
"license": "MIT",
"dependencies": {
"@vue/compiler-dom": "3.5.39",
"@vue/shared": "3.5.39"
"@vue/compiler-dom": "3.5.40",
"@vue/shared": "3.5.40"
}
},
"node_modules/@vue/devtools-api": {
@@ -1046,53 +1046,40 @@
}
},
"node_modules/@vue/reactivity": {
"version": "3.5.39",
"resolved": "https://registry.npmjs.org/@vue/reactivity/-/reactivity-3.5.39.tgz",
"integrity": "sha512-TpsuBJ9gGlZa5d23XcM2y8EXanz9dZeVDQBXRwzy46ItgvM+rWpzs+UVM0wcRLxGvcav0HE5jz2gNL53xlRAog==",
"version": "3.5.40",
"resolved": "https://registry.npmjs.org/@vue/reactivity/-/reactivity-3.5.40.tgz",
"integrity": "sha512-B7ot9UlUZOi1zbq61/LvE88ZLTV8IlajTdiZTAEiDQgrnIMIZoPr9kGw0Zw46ObW62O9+H/Be3kMbfb7kYPQZA==",
"license": "MIT",
"dependencies": {
"@vue/shared": "3.5.39"
"@vue/shared": "3.5.40"
}
},
"node_modules/@vue/runtime-core": {
"version": "3.5.39",
"resolved": "https://registry.npmjs.org/@vue/runtime-core/-/runtime-core-3.5.39.tgz",
"integrity": "sha512-9GLtNyRvPAUMbX+7ono0RC2j0guo2LXVi8LvcmAooImACUKm0oFf0jjwbX8/H0AE/t1nxhAkn8RSl9PMCzzxZw==",
"version": "3.5.40",
"resolved": "https://registry.npmjs.org/@vue/runtime-core/-/runtime-core-3.5.40.tgz",
"integrity": "sha512-KAZLweuZ6uUJPK1PMSQPgBU5gCjgrrfjUhSglmU9NhH+Zjepa8cnwSydPWDWHDwOgY4g3VcZ+PljbiHlURNCbw==",
"license": "MIT",
"dependencies": {
"@vue/reactivity": "3.5.39",
"@vue/shared": "3.5.39"
"@vue/reactivity": "3.5.40",
"@vue/shared": "3.5.40"
}
},
"node_modules/@vue/runtime-dom": {
"version": "3.5.39",
"resolved": "https://registry.npmjs.org/@vue/runtime-dom/-/runtime-dom-3.5.39.tgz",
"integrity": "sha512-7Y6aAGboKcXAZ3ECuUy7RrS5yy2r47dhTp2SKaJmYxjopImaVFaNa5Ne66NwGovsrxVAl5S5rwc7m22UG7Lmww==",
"version": "3.5.40",
"resolved": "https://registry.npmjs.org/@vue/runtime-dom/-/runtime-dom-3.5.40.tgz",
"integrity": "sha512-ZfrX8ssZQds900L9pr8AuK05ddnMsR4MPMZr8cPN9GoqoPWcXLhjvvbIA2SMv+7a97sJ1vv9pj/zxK0Cq/eEFQ==",
"license": "MIT",
"dependencies": {
"@vue/reactivity": "3.5.39",
"@vue/runtime-core": "3.5.39",
"@vue/shared": "3.5.39",
"@vue/reactivity": "3.5.40",
"@vue/runtime-core": "3.5.40",
"@vue/shared": "3.5.40",
"csstype": "^3.2.3"
}
},
"node_modules/@vue/server-renderer": {
"version": "3.5.39",
"resolved": "https://registry.npmjs.org/@vue/server-renderer/-/server-renderer-3.5.39.tgz",
"integrity": "sha512-yZSakiAGw85rZfG7UM8akMnIF+FmeiNk47uvHf2nVBBSe+dIKUhZuZq9+XgJhbV3nS5Z4ALH23/MpXofW+mbcw==",
"license": "MIT",
"dependencies": {
"@vue/compiler-ssr": "3.5.39",
"@vue/shared": "3.5.39"
},
"peerDependencies": {
"vue": "3.5.39"
}
},
"node_modules/@vue/shared": {
"version": "3.5.39",
"resolved": "https://registry.npmjs.org/@vue/shared/-/shared-3.5.39.tgz",
"integrity": "sha512-l1rrBtBfTnmxvtsvdQDXltUUy8S1Y+ZaqdfUzmAnJkTd8Z8rv5v/ytW+TKiqEOWyHPoqtPlNFSs0lhRmYVSHVA==",
"version": "3.5.40",
"resolved": "https://registry.npmjs.org/@vue/shared/-/shared-3.5.40.tgz",
"integrity": "sha512-WxnBtruIqOoV3rA4jeKDWzrYI5h7Cp4+pjwDi8kWGHz+IslhiN+wguLVVhtv2l8VoU02rzDCVfDjgCl1lNpZVg==",
"license": "MIT"
},
"node_modules/@vue/tsconfig": {
@@ -2316,16 +2303,16 @@
"license": "MIT"
},
"node_modules/vue": {
"version": "3.5.39",
"resolved": "https://registry.npmjs.org/vue/-/vue-3.5.39.tgz",
"integrity": "sha512-xmZCYabFGcirU8r0fTuvl/LICc1OU620rnqepaJDL/a141ZigkG7AyaxQLdqJ02ZRYzWe6YPaDHeQx7MfknQfA==",
"version": "3.5.40",
"resolved": "https://registry.npmjs.org/vue/-/vue-3.5.40.tgz",
"integrity": "sha512-+8PJ4SJXdn/cHGImF4CKdxlWHIN5Dkt7DoufRREM6h6uVCx2m7QxgcEQmmzyOK8A9mcafg7sFbJFYsdFVubTig==",
"license": "MIT",
"dependencies": {
"@vue/compiler-dom": "3.5.39",
"@vue/compiler-sfc": "3.5.39",
"@vue/runtime-dom": "3.5.39",
"@vue/server-renderer": "3.5.39",
"@vue/shared": "3.5.39"
"@vue/compiler-dom": "3.5.40",
"@vue/compiler-sfc": "3.5.40",
"@vue/runtime-dom": "3.5.40",
"@vue/server-renderer": "3.5.40",
"@vue/shared": "3.5.40"
},
"peerDependencies": {
"typescript": "*"
+4 -2
View File
@@ -140,9 +140,11 @@ async function disableTotp() {
disableError.value = ''
try {
const response = await fetch(`${apiBase}/totp/enroll?code=${encodeURIComponent(disableCode.value)}`, {
method: 'DELETE',
const response = await fetch(`${apiBase}/totp/enroll/remove`, {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
credentials: 'include',
body: JSON.stringify({ code: disableCode.value }),
})
const data = await response.json()
-1
View File
@@ -6,7 +6,6 @@
"composite": true,
"tsBuildInfoFile": "./node_modules/.tmp/tsconfig.app.tsbuildinfo",
"baseUrl": ".",
"paths": {
"@/*": ["./src/*"],
"@KTXC/*": ["../../core/src/*"]