Merge pull request #1070 from hargata/Hargata/951

Hargata/951
This commit is contained in:
Hargata Softworks 2025-09-17 14:03:51 -06:00 committed by GitHub
commit fefe61f27e
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
10 changed files with 51 additions and 10 deletions

View File

@ -596,7 +596,8 @@ namespace CarCareTracker.Controllers
ReminderUrgencyConfig = _config.GetReminderUrgencyConfig(),
EnableAuth = _config.GetServerAuthEnabled(),
DefaultReminderEmail = _config.GetDefaultReminderEmail(),
EnableRootUserOIDC = _config.GetEnableRootUserOIDC()
EnableRootUserOIDC = _config.GetEnableRootUserOIDC(),
CookieLifeSpan = _config.GetAuthCookieLifeSpan().ToString()
};
return View(viewModel);
}

View File

@ -185,7 +185,7 @@ namespace CarCareTracker.Controllers
};
var serializedCookie = JsonSerializer.Serialize(authCookie);
var encryptedCookie = _dataProtector.Protect(serializedCookie);
Response.Cookies.Append("ACCESS_TOKEN", encryptedCookie, new CookieOptions { Expires = new DateTimeOffset(authCookie.ExpiresOn) });
Response.Cookies.Append(StaticHelper.LoginCookieName, encryptedCookie, new CookieOptions { Expires = new DateTimeOffset(authCookie.ExpiresOn) });
return new RedirectResult("/Home");
} else
{
@ -353,11 +353,11 @@ namespace CarCareTracker.Controllers
AuthCookie authCookie = new AuthCookie
{
UserData = userData,
ExpiresOn = DateTime.Now.AddDays(credentials.IsPersistent ? 30 : 1)
ExpiresOn = DateTime.Now.AddDays(credentials.IsPersistent ? _config.GetAuthCookieLifeSpan() : 1)
};
var serializedCookie = JsonSerializer.Serialize(authCookie);
var encryptedCookie = _dataProtector.Protect(serializedCookie);
Response.Cookies.Append("ACCESS_TOKEN", encryptedCookie, new CookieOptions { Expires = new DateTimeOffset(authCookie.ExpiresOn) });
Response.Cookies.Append(StaticHelper.LoginCookieName, encryptedCookie, new CookieOptions { Expires = new DateTimeOffset(authCookie.ExpiresOn) });
return Json(true);
}
}
@ -390,7 +390,7 @@ namespace CarCareTracker.Controllers
};
var serializedCookie = JsonSerializer.Serialize(authCookie);
var encryptedCookie = _dataProtector.Protect(serializedCookie);
Response.Cookies.Append("ACCESS_TOKEN", encryptedCookie, new CookieOptions { Expires = new DateTimeOffset(authCookie.ExpiresOn) });
Response.Cookies.Append(StaticHelper.LoginCookieName, encryptedCookie, new CookieOptions { Expires = new DateTimeOffset(authCookie.ExpiresOn) });
}
}
return Json(result);
@ -438,7 +438,7 @@ namespace CarCareTracker.Controllers
//destroy any login cookies.
if (result)
{
Response.Cookies.Delete("ACCESS_TOKEN");
Response.Cookies.Delete(StaticHelper.LoginCookieName);
}
return Json(result);
}
@ -452,7 +452,7 @@ namespace CarCareTracker.Controllers
[HttpPost]
public IActionResult LogOut()
{
Response.Cookies.Delete("ACCESS_TOKEN");
Response.Cookies.Delete(StaticHelper.LoginCookieName);
var remoteAuthConfig = _config.GetOpenIDConfig();
if (remoteAuthConfig.DisableRegularLogin && !string.IsNullOrWhiteSpace(remoteAuthConfig.LogOutURL))
{

View File

@ -35,6 +35,7 @@ namespace CarCareTracker.Helper
bool GetInvariantApi();
bool GetServerOpenRegistration();
string GetDefaultReminderEmail();
int GetAuthCookieLifeSpan();
}
public class ConfigHelper : IConfigHelper
{
@ -89,6 +90,26 @@ namespace CarCareTracker.Helper
{
return CheckBool(CheckString("LUBELOGGER_OPEN_REGISTRATION"));
}
public int GetAuthCookieLifeSpan()
{
var lifespan = CheckString("LUBELOGGER_COOKIE_LIFESPAN", StaticHelper.DefaultCookieLifeSpan);
if (!string.IsNullOrWhiteSpace(lifespan) && int.TryParse(lifespan, out int lifespandays))
{
if (lifespandays > 90) //max 90 days because that is the max lifetime of the DPAPI keys
{
lifespandays = 90;
}
if (lifespandays < 1) //min 1 day because cookie lifespan is incremented in days for our implementation
{
lifespandays = 1;
}
return lifespandays;
}
else
{
return int.Parse(StaticHelper.DefaultCookieLifeSpan); //default is 30 days for when remember me is selected.
}
}
public bool GetServerAuthEnabled()
{
return CheckBool(CheckString(nameof(UserConfig.EnableAuth)));
@ -244,6 +265,10 @@ namespace CarCareTracker.Helper
{
serverConfig.EnableRootUserOIDC = null;
}
if (serverConfig.CookieLifeSpan == StaticHelper.DefaultCookieLifeSpan || string.IsNullOrWhiteSpace(serverConfig.CookieLifeSpan))
{
serverConfig.CookieLifeSpan = null;
}
try
{
File.WriteAllText(StaticHelper.ServerConfigPath, JsonSerializer.Serialize(serverConfig));

View File

@ -29,6 +29,8 @@ namespace CarCareTracker.Helper
public const string ReleasePath = "https://api.github.com/repos/hargata/lubelog/releases/latest";
public const string TranslationDirectoryPath = $"{TranslationPath}/directory.json";
public const string ReportNote = "Report generated by LubeLogger, a Free and Open Source Vehicle Maintenance Tracker - LubeLogger.com";
public const string LoginCookieName = "ACCESS_TOKEN";
public const string DefaultCookieLifeSpan = "30";
public static string GetTitleCaseReminderUrgency(ReminderUrgency input)
{
switch (input)

View File

@ -1,4 +1,5 @@
using CarCareTracker.Logic;
using CarCareTracker.Helper;
using CarCareTracker.Logic;
using CarCareTracker.Models;
using Microsoft.AspNetCore.Authentication;
using Microsoft.AspNetCore.DataProtection;
@ -49,7 +50,7 @@ namespace CarCareTracker.Middleware
else
{
//auth is enabled by user, we will have to authenticate the user via a ticket retrieved from the auth cookie.
var access_token = _httpContext.HttpContext.Request.Cookies["ACCESS_TOKEN"];
var access_token = _httpContext.HttpContext.Request.Cookies[StaticHelper.LoginCookieName];
//auth using Basic Auth for API.
var request_header = _httpContext.HttpContext.Request.Headers["Authorization"];
if (string.IsNullOrWhiteSpace(access_token) && string.IsNullOrWhiteSpace(request_header))

View File

@ -74,5 +74,8 @@ namespace CarCareTracker.Models
[JsonPropertyName("LUBELOGGER_LOCALE_DT_OVERRIDE")]
[JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)]
public string? LocaleDateTimeOverride { get; set; } = string.Empty;
[JsonPropertyName("LUBELOGGER_COOKIE_LIFESPAN")]
[JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)]
public string? CookieLifeSpan { get; set; } = string.Empty;
}
}

View File

@ -22,5 +22,6 @@ namespace CarCareTracker.Models
public bool EnableRootUserOIDC { get; set; }
public bool EnableAuth { get; set; }
public List<string> AvailableLocales { get; set; }
public string CookieLifeSpan { get; set; }
}
}

View File

@ -114,6 +114,10 @@
<!option value="false" @(Model.InvariantAPIEnabled ? "" : "selected")>@translator.Translate(userLanguage, "Disabled")</!option>
</select>
</div>
<div class="form-group">
<label for="inputCookieLifeSpan" class="form-label"><span>@($"{translator.Translate(userLanguage, "Auth Cookie Lifespan")} - ")</span><span id="inputCookieLifeSpanRangeLabel">@Model.CookieLifeSpan</span><span>@($" {translator.Translate(userLanguage, "Days")}")</span></label>
<input type="range" class="form-range" oninput="updateCookieLifeSpanRange()" min="1" max="90" id="inputCookieLifeSpan" value="@Model.CookieLifeSpan">
</div>
</form>
</div>
<div class="setup-wizard-content" data-page="2" style="display:none;">

File diff suppressed because one or more lines are too long

View File

@ -53,6 +53,9 @@ function loadLocaleSample() {
})
}
}
function updateCookieLifeSpanRange() {
$("#inputCookieLifeSpanRangeLabel").text($("#inputCookieLifeSpan").val());
}
function saveSetup() {
let setupData = {
LocaleOverride: $("#inputLocale").val(),
@ -66,6 +69,7 @@ function saveSetup() {
ServerURL: $("#inputDomain").val(),
CustomWidgetsEnabled: $("#inputCustomWidget").val(),
InvariantAPIEnabled: $("#inputInvariantAPI").val(),
CookieLifeSpan: $("#inputCookieLifeSpan").val(),
SMTPConfig: {
EmailServer: $("#inputSMTPServer").val(),
EmailFrom: $("#inputSMTPFrom").val(),