diff options
Diffstat (limited to 'plugins/VNLib.Plugins.Essentials.Accounts/src/Endpoints')
3 files changed, 38 insertions, 3 deletions
diff --git a/plugins/VNLib.Plugins.Essentials.Accounts/src/Endpoints/KeepAliveEndpoint.cs b/plugins/VNLib.Plugins.Essentials.Accounts/src/Endpoints/KeepAliveEndpoint.cs index fe5a65b..0ff0869 100644 --- a/plugins/VNLib.Plugins.Essentials.Accounts/src/Endpoints/KeepAliveEndpoint.cs +++ b/plugins/VNLib.Plugins.Essentials.Accounts/src/Endpoints/KeepAliveEndpoint.cs @@ -27,14 +27,19 @@ using System.Net; using System.Text.Json; using System.Collections.Generic; +using VNLib.Utils.Extensions; using VNLib.Plugins.Essentials.Endpoints; +using VNLib.Plugins.Essentials.Extensions; using VNLib.Plugins.Extensions.Loading; + namespace VNLib.Plugins.Essentials.Accounts.Endpoints { [ConfigurationName("keepalive_endpoint")] internal sealed class KeepAliveEndpoint : ProtectedWebEndpoint { + readonly TimeSpan tokenRegenTime; + /* * Endpoint does not use a log, so IniPathAndLog is never called * and path verification happens verbosly @@ -43,6 +48,8 @@ namespace VNLib.Plugins.Essentials.Accounts.Endpoints { string? path = config["path"].GetString(); + tokenRegenTime = config["token_refresh_sec"].GetTimeSpan(TimeParseType.Seconds); + InitPathAndLog(path, pbase.Log); } @@ -56,6 +63,24 @@ namespace VNLib.Plugins.Essentials.Accounts.Endpoints //Allow post to update user's credentials protected override VfReturnType Post(HttpEntity entity) { + //Get the last token update + DateTimeOffset lastTokenUpdate = entity.Session.LastTokenUpgrade(); + + //See if its expired + if (lastTokenUpdate.Add(tokenRegenTime) < entity.RequestedTimeUtc) + { + //if so updaet token + WebMessage webm = new() + { + Token = entity.RegenerateClientToken(), + Success = true + }; + + //Send the update message to the client + entity.CloseResponse(webm); + return VfReturnType.VirtualSkip; + } + //Return okay entity.CloseResponse(HttpStatusCode.OK); return VfReturnType.VirtualSkip; diff --git a/plugins/VNLib.Plugins.Essentials.Accounts/src/Endpoints/LoginEndpoint.cs b/plugins/VNLib.Plugins.Essentials.Accounts/src/Endpoints/LoginEndpoint.cs index 4100620..f973fe8 100644 --- a/plugins/VNLib.Plugins.Essentials.Accounts/src/Endpoints/LoginEndpoint.cs +++ b/plugins/VNLib.Plugins.Essentials.Accounts/src/Endpoints/LoginEndpoint.cs @@ -44,7 +44,7 @@ using VNLib.Plugins.Essentials.Accounts.Validators; using VNLib.Plugins.Extensions.Loading; using VNLib.Plugins.Extensions.Loading.Users; using static VNLib.Plugins.Essentials.Statics; -using static VNLib.Plugins.Essentials.Accounts.AccountManager; +using static VNLib.Plugins.Essentials.Accounts.AccountUtil; namespace VNLib.Plugins.Essentials.Accounts.Endpoints @@ -378,11 +378,14 @@ namespace VNLib.Plugins.Essentials.Accounts.Endpoints private static string EncryptSecret(string pubKey, byte[] secret) { //Alloc buffer for secret - using IMemoryHandle<byte> buffer = Memory.SafeAlloc<byte>(4096); + using IMemoryHandle<byte> buffer = MemoryUtil.SafeAlloc<byte>(4096); + //Try to encrypt the data ERRNO count = TryEncryptClientData(pubKey, secret, buffer.Span); + //Clear secret RandomHash.GetRandomBytes(secret); + //Convert to base64 string return Convert.ToBase64String(buffer.Span[..(int)count]); } @@ -391,11 +394,13 @@ namespace VNLib.Plugins.Essentials.Accounts.Endpoints { //Recover last counter value TimestampedCounter flc = user.FailedLoginCount(); + if(flc.Count < MaxFailedLogins) { //Period exceeded return false; } + //See if the flc timeout period has expired if (flc.LastModified.Add(FailedCountTimeout) < DateTimeOffset.UtcNow) { @@ -403,6 +408,7 @@ namespace VNLib.Plugins.Essentials.Accounts.Endpoints user.FailedLoginCount(0); return false; } + //Count has been exceeded, and has not timed out yet return true; } diff --git a/plugins/VNLib.Plugins.Essentials.Accounts/src/Endpoints/MFAEndpoint.cs b/plugins/VNLib.Plugins.Essentials.Accounts/src/Endpoints/MFAEndpoint.cs index 6ebb024..df20084 100644 --- a/plugins/VNLib.Plugins.Essentials.Accounts/src/Endpoints/MFAEndpoint.cs +++ b/plugins/VNLib.Plugins.Essentials.Accounts/src/Endpoints/MFAEndpoint.cs @@ -162,11 +162,13 @@ namespace VNLib.Plugins.Essentials.Accounts.Endpoints //generate a new secret (passing the buffer which will get copied to an array because the pw bytes can be modified during encryption) byte[] secretBuffer = user.MFAGenreateTOTPSecret(MultiFactor); //Alloc output buffer - UnsafeMemoryHandle<byte> outputBuffer = Memory.UnsafeAlloc<byte>(4096, true); + UnsafeMemoryHandle<byte> outputBuffer = MemoryUtil.UnsafeAlloc<byte>(4096, true); + try { //Encrypt the secret for the client ERRNO count = entity.Session.TryEncryptClientData(secretBuffer, outputBuffer.Span); + if (!count) { webm.Result = "There was an error updating your credentials"; @@ -174,6 +176,7 @@ namespace VNLib.Plugins.Essentials.Accounts.Endpoints Log.Warn("TOTP secret encryption failed, for requested user {uid}", entity.Session.UserID); break; } + webm.Result = new TOTPUpdateMessage() { Issuer = MultiFactor.IssuerName, @@ -183,6 +186,7 @@ namespace VNLib.Plugins.Essentials.Accounts.Endpoints //Convert the secret to base64 string to send to client Base64EncSecret = Convert.ToBase64String(outputBuffer.Span[..(int)count]) }; + //set success flag webm.Success = true; } |