From e2a9b3908069ddab643b5e87e128148cd6c79793 Mon Sep 17 00:00:00 2001 From: Argo Zhang Date: Sat, 26 Apr 2025 10:16:29 +0800 Subject: [PATCH 01/10] =?UTF-8?q?feat:=20=E5=A2=9E=E5=8A=A0=E5=9F=BA?= =?UTF-8?q?=E4=BA=8E=20OTP=20=E7=9A=84=E9=AA=8C=E8=AF=81=E5=99=A8=E7=BB=84?= =?UTF-8?q?=E4=BB=B6?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- BootstrapBlazor.Extensions.sln | 7 ++++ .../BootstrapBlazor.Authenticator.csproj | 22 +++++++++++ .../Extensions/OTPExtensions.cs | 21 ++++++++++ .../Extensions/ServiceCollectionExtension.cs | 38 +++++++++++++++++++ .../Services/DefaultAuthenticatorServices.cs | 20 ++++++++++ 5 files changed, 108 insertions(+) create mode 100644 src/components/BootstrapBlazor.Authenticator/BootstrapBlazor.Authenticator.csproj create mode 100644 src/components/BootstrapBlazor.Authenticator/Extensions/OTPExtensions.cs create mode 100644 src/components/BootstrapBlazor.Authenticator/Extensions/ServiceCollectionExtension.cs create mode 100644 src/components/BootstrapBlazor.Authenticator/Services/DefaultAuthenticatorServices.cs diff --git a/BootstrapBlazor.Extensions.sln b/BootstrapBlazor.Extensions.sln index 4948adcd..1296917b 100644 --- a/BootstrapBlazor.Extensions.sln +++ b/BootstrapBlazor.Extensions.sln @@ -182,6 +182,8 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "BootstrapBlazor.UniverIcon" EndProject Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "BootstrapBlazor.ChatBot", "src\components\BootstrapBlazor.ChatBot\BootstrapBlazor.ChatBot.csproj", "{2F37FBF4-5C1C-4493-B614-0E8361432621}" EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "BootstrapBlazor.Authenticator", "src\components\BootstrapBlazor.Authenticator\BootstrapBlazor.Authenticator.csproj", "{1FDDF0AD-7AB6-4706-A183-26C680817BB4}" +EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|Any CPU = Debug|Any CPU @@ -492,6 +494,10 @@ Global {2F37FBF4-5C1C-4493-B614-0E8361432621}.Debug|Any CPU.Build.0 = Debug|Any CPU {2F37FBF4-5C1C-4493-B614-0E8361432621}.Release|Any CPU.ActiveCfg = Release|Any CPU {2F37FBF4-5C1C-4493-B614-0E8361432621}.Release|Any CPU.Build.0 = Release|Any CPU + {1FDDF0AD-7AB6-4706-A183-26C680817BB4}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {1FDDF0AD-7AB6-4706-A183-26C680817BB4}.Debug|Any CPU.Build.0 = Debug|Any CPU + {1FDDF0AD-7AB6-4706-A183-26C680817BB4}.Release|Any CPU.ActiveCfg = Release|Any CPU + {1FDDF0AD-7AB6-4706-A183-26C680817BB4}.Release|Any CPU.Build.0 = Release|Any CPU EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE @@ -577,6 +583,7 @@ Global {E30AAB64-BF28-4960-89C1-1F521025F531} = {FF1089BE-C704-4374-B629-C57C08E1798F} {A657E04C-1495-439E-BC2E-1EEAB2D1B4DA} = {FF1089BE-C704-4374-B629-C57C08E1798F} {2F37FBF4-5C1C-4493-B614-0E8361432621} = {FF1089BE-C704-4374-B629-C57C08E1798F} + {1FDDF0AD-7AB6-4706-A183-26C680817BB4} = {FF1089BE-C704-4374-B629-C57C08E1798F} EndGlobalSection GlobalSection(ExtensibilityGlobals) = postSolution SolutionGuid = {D5EB1960-6F30-4CE1-B375-EAE1F787D6FF} diff --git a/src/components/BootstrapBlazor.Authenticator/BootstrapBlazor.Authenticator.csproj b/src/components/BootstrapBlazor.Authenticator/BootstrapBlazor.Authenticator.csproj new file mode 100644 index 00000000..baff302d --- /dev/null +++ b/src/components/BootstrapBlazor.Authenticator/BootstrapBlazor.Authenticator.csproj @@ -0,0 +1,22 @@ + + + + 9.0.0 + + + + Bootstrap Blazor WebAssembly wasm Authenticator 2FA MFA OTP TOTP HOTP + Bootstrap UI components extensions of Authenticator + BootstrapBlazor.Components + + + + + + + + + + + + diff --git a/src/components/BootstrapBlazor.Authenticator/Extensions/OTPExtensions.cs b/src/components/BootstrapBlazor.Authenticator/Extensions/OTPExtensions.cs new file mode 100644 index 00000000..ef37eade --- /dev/null +++ b/src/components/BootstrapBlazor.Authenticator/Extensions/OTPExtensions.cs @@ -0,0 +1,21 @@ +// Copyright (c) Argo Zhang (argo@163.com). All rights reserved. +// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. +// Website: https://www.blazor.zone or https://argozhang.github.io/ + +namespace BootstrapBlazor.Components; + +internal static class OTPExtensions +{ + public static OtpNet.OtpHashMode ToMode(this OTPHashMode mode) => mode switch + { + OTPHashMode.Sha256 => OtpNet.OtpHashMode.Sha256, + OTPHashMode.Sha512 => OtpNet.OtpHashMode.Sha512, + _ => OtpNet.OtpHashMode.Sha1 + }; + + public static OtpNet.OtpType ToType(this OTPType type) => type switch + { + OTPType.Hotp => OtpNet.OtpType.Hotp, + _ => OtpNet.OtpType.Totp + }; +} diff --git a/src/components/BootstrapBlazor.Authenticator/Extensions/ServiceCollectionExtension.cs b/src/components/BootstrapBlazor.Authenticator/Extensions/ServiceCollectionExtension.cs new file mode 100644 index 00000000..bc7173db --- /dev/null +++ b/src/components/BootstrapBlazor.Authenticator/Extensions/ServiceCollectionExtension.cs @@ -0,0 +1,38 @@ +// Copyright (c) Argo Zhang (argo@163.com). All rights reserved. +// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. +// Website: https://www.blazor.zone or https://argozhang.github.io/ + +using Microsoft.Extensions.DependencyInjection; +using Microsoft.Extensions.DependencyInjection.Extensions; +using Microsoft.Extensions.Options; + +namespace BootstrapBlazor.Components; + +/// +/// BootstrapBlazor 服务扩展类 +/// +public static class ServiceCollectionExtension +{ + /// + /// 添加百度文字识别服务 + /// + /// + /// + /// + public static IServiceCollection AddBootstrapBlazorAuthenticator(this IServiceCollection services, Action< + AuthenticatorOptions>? configOptions = null) + { + services.TryAddSingleton(); + services.AddOptionsMonitor(); + services.Configure(options => + { + configOptions?.Invoke(options); + + options.AccountName ??= "BootstrapBlazor"; + options.UserName ??= "Simulator"; + options.IssuerName ??= options.AccountName; + options.SecretKey ??= "OMM2LVLFX6QJHMYI"; + }); + return services; + } +} diff --git a/src/components/BootstrapBlazor.Authenticator/Services/DefaultAuthenticatorServices.cs b/src/components/BootstrapBlazor.Authenticator/Services/DefaultAuthenticatorServices.cs new file mode 100644 index 00000000..6efb2381 --- /dev/null +++ b/src/components/BootstrapBlazor.Authenticator/Services/DefaultAuthenticatorServices.cs @@ -0,0 +1,20 @@ +// Copyright (c) Argo Zhang (argo@163.com). All rights reserved. +// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. +// Website: https://www.blazor.zone or https://argozhang.github.io/ + +using Microsoft.Extensions.Options; +using OtpNet; + +namespace BootstrapBlazor.Components; + +internal class DefaultAuthenticatorServices(IOptionsMonitor optionsMonitor) : IAuthenticatorService +{ + public string GenerateOtpUri(AuthenticatorOptions? options = null) + { + options ??= optionsMonitor.CurrentValue; + var type = options.Type.ToType(); + var mode = options.Algorithm.ToMode(); + var uri = new OtpUri(type, options.SecretKey, options.UserName, options.IssuerName, mode, options.Digits, options.Period, options.Counter); + return uri.ToString(); + } +} From 0c9eb9a5fde820c8a313b3ec5463e8e63c9ea35f Mon Sep 17 00:00:00 2001 From: Argo Zhang Date: Sat, 26 Apr 2025 11:22:41 +0800 Subject: [PATCH 02/10] =?UTF-8?q?refactor:=20=E5=AE=8C=E5=96=84=E5=AE=9E?= =?UTF-8?q?=E7=8E=B0=E7=B1=BB?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../Services/DefaultAuthenticatorServices.cs | 40 ++++++++++++++++++- 1 file changed, 39 insertions(+), 1 deletion(-) diff --git a/src/components/BootstrapBlazor.Authenticator/Services/DefaultAuthenticatorServices.cs b/src/components/BootstrapBlazor.Authenticator/Services/DefaultAuthenticatorServices.cs index 6efb2381..c2012ac2 100644 --- a/src/components/BootstrapBlazor.Authenticator/Services/DefaultAuthenticatorServices.cs +++ b/src/components/BootstrapBlazor.Authenticator/Services/DefaultAuthenticatorServices.cs @@ -7,8 +7,10 @@ namespace BootstrapBlazor.Components; -internal class DefaultAuthenticatorServices(IOptionsMonitor optionsMonitor) : IAuthenticatorService +class DefaultAuthenticatorServices(IOptionsMonitor optionsMonitor) : IAuthenticatorService { + public TOTPInstance? TOTPInstance { get; private set; } + public string GenerateOtpUri(AuthenticatorOptions? options = null) { options ??= optionsMonitor.CurrentValue; @@ -17,4 +19,40 @@ public string GenerateOtpUri(AuthenticatorOptions? options = null) var uri = new OtpUri(type, options.SecretKey, options.UserName, options.IssuerName, mode, options.Digits, options.Period, options.Counter); return uri.ToString(); } + + public string ComputeTotp(string secretKey, DateTime? timestamp = null) + { + var totp = new Totp(Base32Encoding.ToBytes(secretKey)); + TOTPInstance = new DefaultTOTPInstance(totp); + return timestamp == null ? totp.ComputeTotp() : totp.ComputeTotp(timestamp.Value); + } + + public int GetRemainingSeconds(DateTime? timestamp = null) + { + if (TOTPInstance != null) + { + return timestamp == null ? TOTPInstance.GetRemainingSeconds() : TOTPInstance.GetRemainingSeconds(timestamp.Value); + } + var totp = new Totp(Base32Encoding.ToBytes("OMM2LVLFX6QJHMYI")); + return timestamp == null ? totp.RemainingSeconds() : totp.RemainingSeconds(timestamp.Value); + } + + public string GenerateSecretKey(int length = 20) + { + var secretKey = KeyGeneration.GenerateRandomKey(length); + return Base32Encoding.ToString(secretKey); + } + + public byte[] GetSecretKeyBytes(string input) + { + return Base32Encoding.ToBytes(input); + } +} + +class DefaultTOTPInstance(Totp totp) : TOTPInstance +{ + public override int GetRemainingSeconds(DateTime? timestamp = null) + { + return timestamp == null ? totp.RemainingSeconds() : totp.RemainingSeconds(timestamp.Value); + } } From 54cf24f0febad223693cfdb62b97d69cd25f66d4 Mon Sep 17 00:00:00 2001 From: Argo Zhang Date: Sat, 26 Apr 2025 12:30:47 +0800 Subject: [PATCH 03/10] =?UTF-8?q?refactor:=20=E6=9B=B4=E6=94=B9=E4=B8=BA?= =?UTF-8?q?=20ITOTPService=20=E6=9C=8D=E5=8A=A1?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../Extensions/OTPExtensions.cs | 2 +- .../Extensions/ServiceCollectionExtension.cs | 3 +- .../Services/DefaultAuthenticatorServices.cs | 58 --------------- .../Services/DefaultTOTPServices.cs | 73 +++++++++++++++++++ 4 files changed, 75 insertions(+), 61 deletions(-) delete mode 100644 src/components/BootstrapBlazor.Authenticator/Services/DefaultAuthenticatorServices.cs create mode 100644 src/components/BootstrapBlazor.Authenticator/Services/DefaultTOTPServices.cs diff --git a/src/components/BootstrapBlazor.Authenticator/Extensions/OTPExtensions.cs b/src/components/BootstrapBlazor.Authenticator/Extensions/OTPExtensions.cs index ef37eade..e4408066 100644 --- a/src/components/BootstrapBlazor.Authenticator/Extensions/OTPExtensions.cs +++ b/src/components/BootstrapBlazor.Authenticator/Extensions/OTPExtensions.cs @@ -15,7 +15,7 @@ internal static class OTPExtensions public static OtpNet.OtpType ToType(this OTPType type) => type switch { - OTPType.Hotp => OtpNet.OtpType.Hotp, + OTPType.HOTP => OtpNet.OtpType.Hotp, _ => OtpNet.OtpType.Totp }; } diff --git a/src/components/BootstrapBlazor.Authenticator/Extensions/ServiceCollectionExtension.cs b/src/components/BootstrapBlazor.Authenticator/Extensions/ServiceCollectionExtension.cs index bc7173db..4b2ca547 100644 --- a/src/components/BootstrapBlazor.Authenticator/Extensions/ServiceCollectionExtension.cs +++ b/src/components/BootstrapBlazor.Authenticator/Extensions/ServiceCollectionExtension.cs @@ -4,7 +4,6 @@ using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.DependencyInjection.Extensions; -using Microsoft.Extensions.Options; namespace BootstrapBlazor.Components; @@ -22,7 +21,7 @@ public static class ServiceCollectionExtension public static IServiceCollection AddBootstrapBlazorAuthenticator(this IServiceCollection services, Action< AuthenticatorOptions>? configOptions = null) { - services.TryAddSingleton(); + services.TryAddSingleton(); services.AddOptionsMonitor(); services.Configure(options => { diff --git a/src/components/BootstrapBlazor.Authenticator/Services/DefaultAuthenticatorServices.cs b/src/components/BootstrapBlazor.Authenticator/Services/DefaultAuthenticatorServices.cs deleted file mode 100644 index c2012ac2..00000000 --- a/src/components/BootstrapBlazor.Authenticator/Services/DefaultAuthenticatorServices.cs +++ /dev/null @@ -1,58 +0,0 @@ -// Copyright (c) Argo Zhang (argo@163.com). All rights reserved. -// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. -// Website: https://www.blazor.zone or https://argozhang.github.io/ - -using Microsoft.Extensions.Options; -using OtpNet; - -namespace BootstrapBlazor.Components; - -class DefaultAuthenticatorServices(IOptionsMonitor optionsMonitor) : IAuthenticatorService -{ - public TOTPInstance? TOTPInstance { get; private set; } - - public string GenerateOtpUri(AuthenticatorOptions? options = null) - { - options ??= optionsMonitor.CurrentValue; - var type = options.Type.ToType(); - var mode = options.Algorithm.ToMode(); - var uri = new OtpUri(type, options.SecretKey, options.UserName, options.IssuerName, mode, options.Digits, options.Period, options.Counter); - return uri.ToString(); - } - - public string ComputeTotp(string secretKey, DateTime? timestamp = null) - { - var totp = new Totp(Base32Encoding.ToBytes(secretKey)); - TOTPInstance = new DefaultTOTPInstance(totp); - return timestamp == null ? totp.ComputeTotp() : totp.ComputeTotp(timestamp.Value); - } - - public int GetRemainingSeconds(DateTime? timestamp = null) - { - if (TOTPInstance != null) - { - return timestamp == null ? TOTPInstance.GetRemainingSeconds() : TOTPInstance.GetRemainingSeconds(timestamp.Value); - } - var totp = new Totp(Base32Encoding.ToBytes("OMM2LVLFX6QJHMYI")); - return timestamp == null ? totp.RemainingSeconds() : totp.RemainingSeconds(timestamp.Value); - } - - public string GenerateSecretKey(int length = 20) - { - var secretKey = KeyGeneration.GenerateRandomKey(length); - return Base32Encoding.ToString(secretKey); - } - - public byte[] GetSecretKeyBytes(string input) - { - return Base32Encoding.ToBytes(input); - } -} - -class DefaultTOTPInstance(Totp totp) : TOTPInstance -{ - public override int GetRemainingSeconds(DateTime? timestamp = null) - { - return timestamp == null ? totp.RemainingSeconds() : totp.RemainingSeconds(timestamp.Value); - } -} diff --git a/src/components/BootstrapBlazor.Authenticator/Services/DefaultTOTPServices.cs b/src/components/BootstrapBlazor.Authenticator/Services/DefaultTOTPServices.cs new file mode 100644 index 00000000..6633b318 --- /dev/null +++ b/src/components/BootstrapBlazor.Authenticator/Services/DefaultTOTPServices.cs @@ -0,0 +1,73 @@ +// Copyright (c) Argo Zhang (argo@163.com). All rights reserved. +// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. +// Website: https://www.blazor.zone or https://argozhang.github.io/ + +using Microsoft.Extensions.Options; +using OtpNet; + +namespace BootstrapBlazor.Components; + +class DefaultTOTPServices(IOptionsMonitor optionsMonitor) : ITOTPService +{ + public TOTPInstanceBase? TOTPInstance { get; private set; } + + public string GenerateOtpUri(AuthenticatorOptions? options = null) + { + options ??= optionsMonitor.CurrentValue; + var type = options.Type.ToType(); + var mode = options.Algorithm.ToMode(); + var uri = new OtpUri(type, options.SecretKey, options.UserName, options.IssuerName, mode, options.Digits, options.Period, options.Counter); + return uri.ToString(); + } + + public string Compute(string secretKey, DateTime? timestamp = null) + { + var instance = new Totp(Base32Encoding.ToBytes(secretKey)); + TOTPInstance = new DefaultTOTPInstance(instance); + return timestamp == null ? instance.ComputeTotp() : instance.ComputeTotp(timestamp.Value); + } + + public int GetRemainingSeconds(DateTime? timestamp = null) + { + if (TOTPInstance != null) + { + return timestamp == null ? TOTPInstance.GetRemainingSeconds() : TOTPInstance.GetRemainingSeconds(timestamp.Value); + } + var instance = new Totp(Base32Encoding.ToBytes("OMM2LVLFX6QJHMYI")); + return timestamp == null ? instance.RemainingSeconds() : instance.RemainingSeconds(timestamp.Value); + } + + public string GenerateSecretKey(int length = 20) + { + var secretKey = KeyGeneration.GenerateRandomKey(length); + return Base32Encoding.ToString(secretKey); + } + + public byte[] GetSecretKeyBytes(string input) + { + return Base32Encoding.ToBytes(input); + } + + public bool Verify(string code, DateTime? timestamp = null) + { + if (TOTPInstance != null) + { + return timestamp == null ? TOTPInstance.Verify(code) : TOTPInstance.Verify(code, timestamp.Value); + } + var instance = new Totp(Base32Encoding.ToBytes("OMM2LVLFX6QJHMYI")); + return timestamp == null ? instance.VerifyTotp(code, out _) : instance.VerifyTotp(timestamp.Value, code, out _); + } +} + +class DefaultTOTPInstance(Totp instance) : TOTPInstanceBase +{ + public override int GetRemainingSeconds(DateTime? timestamp = null) + { + return timestamp == null ? instance.RemainingSeconds() : instance.RemainingSeconds(timestamp.Value); + } + + public override bool Verify(string code, DateTime? timestamp = null) + { + return timestamp == null ? instance.VerifyTotp(code, out _) : instance.VerifyTotp(timestamp.Value, code, out _); + } +} From 93f75b0873189fdf14b9e23b6cb7a526f4744aec Mon Sep 17 00:00:00 2001 From: Argo Zhang Date: Sat, 26 Apr 2025 14:26:43 +0800 Subject: [PATCH 04/10] =?UTF-8?q?refactor:=20=E4=BB=A3=E7=A0=81=E6=A0=BC?= =?UTF-8?q?=E5=BC=8F=E5=8C=96?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../Extensions/OTPExtensions.cs | 10 +++++----- .../Extensions/ServiceCollectionExtension.cs | 2 +- .../Services/DefaultTOTPServices.cs | 16 ++++++++-------- 3 files changed, 14 insertions(+), 14 deletions(-) diff --git a/src/components/BootstrapBlazor.Authenticator/Extensions/OTPExtensions.cs b/src/components/BootstrapBlazor.Authenticator/Extensions/OTPExtensions.cs index e4408066..5d07b818 100644 --- a/src/components/BootstrapBlazor.Authenticator/Extensions/OTPExtensions.cs +++ b/src/components/BootstrapBlazor.Authenticator/Extensions/OTPExtensions.cs @@ -6,16 +6,16 @@ namespace BootstrapBlazor.Components; internal static class OTPExtensions { - public static OtpNet.OtpHashMode ToMode(this OTPHashMode mode) => mode switch + public static OtpNet.OtpHashMode ToMode(this OtpHashMode mode) => mode switch { - OTPHashMode.Sha256 => OtpNet.OtpHashMode.Sha256, - OTPHashMode.Sha512 => OtpNet.OtpHashMode.Sha512, + OtpHashMode.Sha256 => OtpNet.OtpHashMode.Sha256, + OtpHashMode.Sha512 => OtpNet.OtpHashMode.Sha512, _ => OtpNet.OtpHashMode.Sha1 }; - public static OtpNet.OtpType ToType(this OTPType type) => type switch + public static OtpNet.OtpType ToType(this OtpType type) => type switch { - OTPType.HOTP => OtpNet.OtpType.Hotp, + OtpType.Hotp => OtpNet.OtpType.Hotp, _ => OtpNet.OtpType.Totp }; } diff --git a/src/components/BootstrapBlazor.Authenticator/Extensions/ServiceCollectionExtension.cs b/src/components/BootstrapBlazor.Authenticator/Extensions/ServiceCollectionExtension.cs index 4b2ca547..b98b7a0b 100644 --- a/src/components/BootstrapBlazor.Authenticator/Extensions/ServiceCollectionExtension.cs +++ b/src/components/BootstrapBlazor.Authenticator/Extensions/ServiceCollectionExtension.cs @@ -21,7 +21,7 @@ public static class ServiceCollectionExtension public static IServiceCollection AddBootstrapBlazorAuthenticator(this IServiceCollection services, Action< AuthenticatorOptions>? configOptions = null) { - services.TryAddSingleton(); + services.TryAddSingleton(); services.AddOptionsMonitor(); services.Configure(options => { diff --git a/src/components/BootstrapBlazor.Authenticator/Services/DefaultTOTPServices.cs b/src/components/BootstrapBlazor.Authenticator/Services/DefaultTOTPServices.cs index 6633b318..462e1142 100644 --- a/src/components/BootstrapBlazor.Authenticator/Services/DefaultTOTPServices.cs +++ b/src/components/BootstrapBlazor.Authenticator/Services/DefaultTOTPServices.cs @@ -7,9 +7,9 @@ namespace BootstrapBlazor.Components; -class DefaultTOTPServices(IOptionsMonitor optionsMonitor) : ITOTPService +class DefaultTotpServices(IOptionsMonitor optionsMonitor) : ITotpService { - public TOTPInstanceBase? TOTPInstance { get; private set; } + public TotpInstanceBase? Instance { get; private set; } public string GenerateOtpUri(AuthenticatorOptions? options = null) { @@ -23,15 +23,15 @@ public string GenerateOtpUri(AuthenticatorOptions? options = null) public string Compute(string secretKey, DateTime? timestamp = null) { var instance = new Totp(Base32Encoding.ToBytes(secretKey)); - TOTPInstance = new DefaultTOTPInstance(instance); + Instance = new DefaultTOTPInstance(instance); return timestamp == null ? instance.ComputeTotp() : instance.ComputeTotp(timestamp.Value); } public int GetRemainingSeconds(DateTime? timestamp = null) { - if (TOTPInstance != null) + if (Instance != null) { - return timestamp == null ? TOTPInstance.GetRemainingSeconds() : TOTPInstance.GetRemainingSeconds(timestamp.Value); + return timestamp == null ? Instance.GetRemainingSeconds() : Instance.GetRemainingSeconds(timestamp.Value); } var instance = new Totp(Base32Encoding.ToBytes("OMM2LVLFX6QJHMYI")); return timestamp == null ? instance.RemainingSeconds() : instance.RemainingSeconds(timestamp.Value); @@ -50,16 +50,16 @@ public byte[] GetSecretKeyBytes(string input) public bool Verify(string code, DateTime? timestamp = null) { - if (TOTPInstance != null) + if (Instance != null) { - return timestamp == null ? TOTPInstance.Verify(code) : TOTPInstance.Verify(code, timestamp.Value); + return timestamp == null ? Instance.Verify(code) : Instance.Verify(code, timestamp.Value); } var instance = new Totp(Base32Encoding.ToBytes("OMM2LVLFX6QJHMYI")); return timestamp == null ? instance.VerifyTotp(code, out _) : instance.VerifyTotp(timestamp.Value, code, out _); } } -class DefaultTOTPInstance(Totp instance) : TOTPInstanceBase +class DefaultTOTPInstance(Totp instance) : TotpInstanceBase { public override int GetRemainingSeconds(DateTime? timestamp = null) { From bd9496c82a35028664f427862122f7d21403081d Mon Sep 17 00:00:00 2001 From: Argo Zhang Date: Sat, 26 Apr 2025 15:06:11 +0800 Subject: [PATCH 05/10] =?UTF-8?q?refactor:=20=E6=9B=B4=E6=94=B9=E7=B1=BB?= =?UTF-8?q?=E5=90=8D=E7=A7=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../Services/DefaultTOTPServices.cs | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/components/BootstrapBlazor.Authenticator/Services/DefaultTOTPServices.cs b/src/components/BootstrapBlazor.Authenticator/Services/DefaultTOTPServices.cs index 462e1142..edb843c2 100644 --- a/src/components/BootstrapBlazor.Authenticator/Services/DefaultTOTPServices.cs +++ b/src/components/BootstrapBlazor.Authenticator/Services/DefaultTOTPServices.cs @@ -9,6 +9,7 @@ namespace BootstrapBlazor.Components; class DefaultTotpServices(IOptionsMonitor optionsMonitor) : ITotpService { + [NotNull] public TotpInstanceBase? Instance { get; private set; } public string GenerateOtpUri(AuthenticatorOptions? options = null) @@ -23,7 +24,7 @@ public string GenerateOtpUri(AuthenticatorOptions? options = null) public string Compute(string secretKey, DateTime? timestamp = null) { var instance = new Totp(Base32Encoding.ToBytes(secretKey)); - Instance = new DefaultTOTPInstance(instance); + Instance = new DefaultTotpInstance(instance); return timestamp == null ? instance.ComputeTotp() : instance.ComputeTotp(timestamp.Value); } @@ -59,7 +60,7 @@ public bool Verify(string code, DateTime? timestamp = null) } } -class DefaultTOTPInstance(Totp instance) : TotpInstanceBase +class DefaultTotpInstance(Totp instance) : TotpInstanceBase { public override int GetRemainingSeconds(DateTime? timestamp = null) { From 945597bf83c9e6668e98b2a4bb21eeb3d3f54b54 Mon Sep 17 00:00:00 2001 From: Argo Zhang Date: Sat, 26 Apr 2025 15:08:19 +0800 Subject: [PATCH 06/10] =?UTF-8?q?chore:=20=E5=A2=9E=E5=8A=A0=E5=8D=95?= =?UTF-8?q?=E8=AF=8D=E6=8B=BC=E5=86=99=E5=AD=97=E5=85=B8?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- exclusion.dic | 1 + 1 file changed, 1 insertion(+) diff --git a/exclusion.dic b/exclusion.dic index d5ea49ef..37ac74b7 100644 --- a/exclusion.dic +++ b/exclusion.dic @@ -101,3 +101,4 @@ vimeo scrlang Validata Validatable +Totp From 6390be760fdca963f3e22b4ad03a7a8b847fe544 Mon Sep 17 00:00:00 2001 From: Argo Zhang Date: Sun, 27 Apr 2025 15:00:18 +0800 Subject: [PATCH 07/10] =?UTF-8?q?refactor:=20=E6=9B=B4=E6=96=B0=E6=8E=A5?= =?UTF-8?q?=E5=8F=A3?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../Extensions/OTPExtensions.cs | 2 +- .../Extensions/ServiceCollectionExtension.cs | 14 ++++++-------- ...efaultTOTPServices.cs => DefaultTotpService.cs} | 8 ++++---- 3 files changed, 11 insertions(+), 13 deletions(-) rename src/components/BootstrapBlazor.Authenticator/Services/{DefaultTOTPServices.cs => DefaultTotpService.cs} (88%) diff --git a/src/components/BootstrapBlazor.Authenticator/Extensions/OTPExtensions.cs b/src/components/BootstrapBlazor.Authenticator/Extensions/OTPExtensions.cs index 5d07b818..3b5104b7 100644 --- a/src/components/BootstrapBlazor.Authenticator/Extensions/OTPExtensions.cs +++ b/src/components/BootstrapBlazor.Authenticator/Extensions/OTPExtensions.cs @@ -4,7 +4,7 @@ namespace BootstrapBlazor.Components; -internal static class OTPExtensions +internal static class OtpExtensions { public static OtpNet.OtpHashMode ToMode(this OtpHashMode mode) => mode switch { diff --git a/src/components/BootstrapBlazor.Authenticator/Extensions/ServiceCollectionExtension.cs b/src/components/BootstrapBlazor.Authenticator/Extensions/ServiceCollectionExtension.cs index b98b7a0b..6c53a9c4 100644 --- a/src/components/BootstrapBlazor.Authenticator/Extensions/ServiceCollectionExtension.cs +++ b/src/components/BootstrapBlazor.Authenticator/Extensions/ServiceCollectionExtension.cs @@ -3,27 +3,25 @@ // Website: https://www.blazor.zone or https://argozhang.github.io/ using Microsoft.Extensions.DependencyInjection; -using Microsoft.Extensions.DependencyInjection.Extensions; namespace BootstrapBlazor.Components; /// -/// BootstrapBlazor 服务扩展类 +/// BootstrapBlazor service extensions /// public static class ServiceCollectionExtension { /// - /// 添加百度文字识别服务 + /// Inject service extension method. /// /// /// /// - public static IServiceCollection AddBootstrapBlazorAuthenticator(this IServiceCollection services, Action< - AuthenticatorOptions>? configOptions = null) + public static IServiceCollection AddBootstrapBlazorTotpService(this IServiceCollection services, Action< + OtpOptions>? configOptions = null) { - services.TryAddSingleton(); - services.AddOptionsMonitor(); - services.Configure(options => + services.AddSingleton(); + services.Configure(options => { configOptions?.Invoke(options); diff --git a/src/components/BootstrapBlazor.Authenticator/Services/DefaultTOTPServices.cs b/src/components/BootstrapBlazor.Authenticator/Services/DefaultTotpService.cs similarity index 88% rename from src/components/BootstrapBlazor.Authenticator/Services/DefaultTOTPServices.cs rename to src/components/BootstrapBlazor.Authenticator/Services/DefaultTotpService.cs index edb843c2..6efe794c 100644 --- a/src/components/BootstrapBlazor.Authenticator/Services/DefaultTOTPServices.cs +++ b/src/components/BootstrapBlazor.Authenticator/Services/DefaultTotpService.cs @@ -7,12 +7,12 @@ namespace BootstrapBlazor.Components; -class DefaultTotpServices(IOptionsMonitor optionsMonitor) : ITotpService +class DefaultTotpService(IOptionsMonitor optionsMonitor) : ITotpService { [NotNull] public TotpInstanceBase? Instance { get; private set; } - public string GenerateOtpUri(AuthenticatorOptions? options = null) + public string GenerateOtpUri(OtpOptions? options = null) { options ??= optionsMonitor.CurrentValue; var type = options.Type.ToType(); @@ -21,9 +21,9 @@ public string GenerateOtpUri(AuthenticatorOptions? options = null) return uri.ToString(); } - public string Compute(string secretKey, DateTime? timestamp = null) + public string Compute(string secretKey, int step = 6, OtpHashMode mode = OtpHashMode.Sha1, int totpSize = 6, DateTime? timestamp = null) { - var instance = new Totp(Base32Encoding.ToBytes(secretKey)); + var instance = new Totp(Base32Encoding.ToBytes(secretKey), step, mode.ToMode(), totpSize, timeCorrection: null); Instance = new DefaultTotpInstance(instance); return timestamp == null ? instance.ComputeTotp() : instance.ComputeTotp(timestamp.Value); } From 0faa48a779eec748609dcb8ba60b29f04e2302f2 Mon Sep 17 00:00:00 2001 From: Argo Zhang Date: Sun, 27 Apr 2025 15:38:42 +0800 Subject: [PATCH 08/10] =?UTF-8?q?refactor:=20=E6=9B=B4=E6=96=B0=E9=BB=98?= =?UTF-8?q?=E8=AE=A4=E5=80=BC?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../BootstrapBlazor.Authenticator.csproj | 2 +- .../Services/DefaultTotpService.cs | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/components/BootstrapBlazor.Authenticator/BootstrapBlazor.Authenticator.csproj b/src/components/BootstrapBlazor.Authenticator/BootstrapBlazor.Authenticator.csproj index baff302d..0fa81d80 100644 --- a/src/components/BootstrapBlazor.Authenticator/BootstrapBlazor.Authenticator.csproj +++ b/src/components/BootstrapBlazor.Authenticator/BootstrapBlazor.Authenticator.csproj @@ -11,7 +11,7 @@ - + diff --git a/src/components/BootstrapBlazor.Authenticator/Services/DefaultTotpService.cs b/src/components/BootstrapBlazor.Authenticator/Services/DefaultTotpService.cs index 6efe794c..9a54e19c 100644 --- a/src/components/BootstrapBlazor.Authenticator/Services/DefaultTotpService.cs +++ b/src/components/BootstrapBlazor.Authenticator/Services/DefaultTotpService.cs @@ -21,9 +21,9 @@ public string GenerateOtpUri(OtpOptions? options = null) return uri.ToString(); } - public string Compute(string secretKey, int step = 6, OtpHashMode mode = OtpHashMode.Sha1, int totpSize = 6, DateTime? timestamp = null) + public string Compute(string secretKey, int period = 30, OtpHashMode mode = OtpHashMode.Sha1, int digits = 6, DateTime? timestamp = null) { - var instance = new Totp(Base32Encoding.ToBytes(secretKey), step, mode.ToMode(), totpSize, timeCorrection: null); + var instance = new Totp(Base32Encoding.ToBytes(secretKey), period, mode.ToMode(), digits, timeCorrection: null); Instance = new DefaultTotpInstance(instance); return timestamp == null ? instance.ComputeTotp() : instance.ComputeTotp(timestamp.Value); } From cdcf2952202453c2047555598ff0dd8a9ba1a3d1 Mon Sep 17 00:00:00 2001 From: Argo Zhang Date: Sun, 27 Apr 2025 15:48:46 +0800 Subject: [PATCH 09/10] =?UTF-8?q?chore:=20=E6=9B=B4=E6=96=B0=E4=BE=9D?= =?UTF-8?q?=E8=B5=96?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../BootstrapBlazor.Authenticator.csproj | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/components/BootstrapBlazor.Authenticator/BootstrapBlazor.Authenticator.csproj b/src/components/BootstrapBlazor.Authenticator/BootstrapBlazor.Authenticator.csproj index 0fa81d80..9dc86af8 100644 --- a/src/components/BootstrapBlazor.Authenticator/BootstrapBlazor.Authenticator.csproj +++ b/src/components/BootstrapBlazor.Authenticator/BootstrapBlazor.Authenticator.csproj @@ -11,7 +11,7 @@ - + From fd6386885ae3c54374bf6f1c022a3bffcaaf7f76 Mon Sep 17 00:00:00 2001 From: Argo Zhang Date: Sun, 27 Apr 2025 15:51:06 +0800 Subject: [PATCH 10/10] =?UTF-8?q?refactor:=20=E7=A7=BB=E9=99=A4=E4=BE=9D?= =?UTF-8?q?=E8=B5=96?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../BootstrapBlazor.Authenticator.csproj | 4 ---- 1 file changed, 4 deletions(-) diff --git a/src/components/BootstrapBlazor.Authenticator/BootstrapBlazor.Authenticator.csproj b/src/components/BootstrapBlazor.Authenticator/BootstrapBlazor.Authenticator.csproj index 9dc86af8..92338cfe 100644 --- a/src/components/BootstrapBlazor.Authenticator/BootstrapBlazor.Authenticator.csproj +++ b/src/components/BootstrapBlazor.Authenticator/BootstrapBlazor.Authenticator.csproj @@ -15,8 +15,4 @@ - - - -