using System; using System.Threading.Tasks; using Microsoft.AspNetCore.Identity; using Bit.Core.Models.Table; using Bit.Core.Enums; using OtpNet; namespace Bit.Core.Identity { public class AuthenticatorTokenProvider : IUserTwoFactorTokenProvider { public Task CanGenerateTwoFactorTokenAsync(UserManager manager, User user) { var canGenerate = user.TwoFactorEnabled && user.TwoFactorProvider.HasValue && user.TwoFactorProvider.Value == TwoFactorProviderType.Authenticator && !string.IsNullOrWhiteSpace(user.AuthenticatorKey); return Task.FromResult(canGenerate); } public Task GetUserModifierAsync(string purpose, UserManager manager, User user) { return Task.FromResult(null); } public Task GenerateAsync(string purpose, UserManager manager, User user) { return Task.FromResult(null); } public Task ValidateAsync(string purpose, string token, UserManager manager, User user) { var otp = new Totp(Base32Encoding.ToBytes(user.AuthenticatorKey)); long timeStepMatched; var valid = otp.VerifyTotp(token, out timeStepMatched, new VerificationWindow(1, 1)); return Task.FromResult(valid); } } }