-
-
Notifications
You must be signed in to change notification settings - Fork 7
Expand file tree
/
Copy pathDefaultTotpService.cs
More file actions
74 lines (63 loc) · 2.87 KB
/
DefaultTotpService.cs
File metadata and controls
74 lines (63 loc) · 2.87 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
// 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 DefaultTotpService(IOptionsMonitor<OtpOptions> optionsMonitor) : ITotpService
{
[NotNull]
public TotpInstanceBase? Instance { get; private set; }
public string GenerateOtpUri(OtpOptions? 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, int period = 30, OtpHashMode mode = OtpHashMode.Sha1, int digits = 6, DateTime? timestamp = 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);
}
public int GetRemainingSeconds(DateTime? timestamp = null)
{
if (Instance != null)
{
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);
}
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 (Instance != null)
{
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
{
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 _);
}
}