{"record":{"id":"ee4aa8db768574df","repo":"TechnitiumSoftware/DnsServer","slug":"time-based-one-time-password-totp-is-already-dis","errorCode":null,"errorMessage":"Time-based one-time password (TOTP) is already disabled for user: ","messagePattern":"Time-based one-time password \\(TOTP\\) is already disabled for user: ","errorType":"exception","errorClass":"InvalidOperationException","httpStatus":null,"severity":"warning","filePath":"DnsServerCore/Auth/User.cs","lineNumber":319,"sourceCode":"\n            if (_totpEnabled)\n                throw new InvalidOperationException(\"Time-based one-time password (TOTP) is already enabled for user: \" + _username);\n\n            Authenticator authenticator = new Authenticator(_totpKeyUri);\n\n            if (!authenticator.IsTOTPValid(totp))\n                throw new Exception(\"Invalid time-based one-time password (TOTP) was attempted for user: \" + _username);\n\n            _totpEnabled = true;\n        }\n\n        public void DisableTOTP()\n        {\n            if (_isSsoUser)\n                throw new InvalidOperationException(\"Time-based one-time password (TOTP) feature is not available for SSO users.\");\n\n            if (!_totpEnabled)\n                throw new InvalidOperationException(\"Time-based one-time password (TOTP) is already disabled for user: \" + _username);\n\n            _totpKeyUri = null;\n            _totpEnabled = false;\n        }\n\n        public void LoggedInFrom(IPAddress remoteAddress)\n        {\n            if (remoteAddress.IsIPv4MappedToIPv6)\n                remoteAddress = remoteAddress.MapToIPv4();\n\n            _previousSessionLoggedOn = _recentSessionLoggedOn;\n            _previousSessionRemoteAddress = _recentSessionRemoteAddress;\n\n            _recentSessionLoggedOn = DateTime.UtcNow;\n            _recentSessionRemoteAddress = remoteAddress;\n        }\n\n        public void AddToGroup(Group group)","sourceCodeStart":301,"sourceCodeEnd":337,"githubUrl":"https://github.com/TechnitiumSoftware/DnsServer/blob/d0484b6c1e7439cdc53d67d81e9c876cda2ad756/DnsServerCore/Auth/User.cs#L301-L337","documentation":"Thrown by User.DisableTOTP() when !_totpEnabled — i.e. TOTP was never enabled (or was already disabled). The library refuses to clear state that is already clear, preventing a misleading 'disabled' success on an account that had no 2FA. _totpKeyUri and _totpEnabled are left untouched on failure.","triggerScenarios":"Calling DisableTOTP on a user who never enrolled, or calling it twice (the second call finds _totpEnabled already false).","commonSituations":"A 'disable 2FA' admin action run against users who never set it up; a retry after the first disable already succeeded; UI state out of sync with server state.","solutions":["Check the user's current TOTP-enabled state before calling DisableTOTP and treat already-disabled as success.","Make the disable endpoint idempotent: return OK if TOTP is already off.","Refresh user state in the UI after a successful disable so the control reflects reality."],"exampleFix":"// before\nuser.DisableTOTP();\n\n// after\nif (user.TotpEnabled)\n    user.DisableTOTP();","handlingStrategy":"validation","validationCode":"if (!user.TotpEnabled)\n    return Ok(\"TOTP already disabled.\"); // idempotent\nuser.DisableTOTP();","typeGuard":"static bool NeedsDisableTotp(User user) => user.TotpEnabled;","tryCatchPattern":null,"preventionTips":["Make the disable endpoint idempotent on already-disabled state.","Refresh and show current TOTP state in the UI after each action.","Guard bulk disable routines with a TotpEnabled check."],"tags":["auth","totp","mfa","state","technitium-dns-server"],"backgroundTag":null,"analyzedSha":"d0484b6c1e7439cdc53d67d81e9c876cda2ad756","analyzedAt":"2026-08-13T22:57:35.508Z","schemaVersion":2},"datasetVersion":"2026-08-14T00:17:13.853Z"}