diff --git a/Oqtane.Client/Modules/Admin/Visitors/Index.razor b/Oqtane.Client/Modules/Admin/Visitors/Index.razor
index 39b14006..ea5510c0 100644
--- a/Oqtane.Client/Modules/Admin/Visitors/Index.razor
+++ b/Oqtane.Client/Modules/Admin/Visitors/Index.razor
@@ -69,14 +69,20 @@ else
-
+
+
+
+
+
+
+
-
+
@@ -103,7 +109,8 @@ else
private int _page = 1;
private List
_visitors;
private string _tracking;
- private string _filter = "";
+ private int _duration = 5;
+ private string _filter = "";
private int _retention = 30;
private string _correlation = "true";
@@ -128,7 +135,8 @@ else
_tracking = PageState.Site.VisitorTracking.ToString();
var settings = await SettingService.GetSiteSettingsAsync(PageState.Site.SiteId);
- _filter = SettingService.GetSetting(settings, "VisitorFilter", Constants.DefaultVisitorFilter);
+ _duration = int.Parse(SettingService.GetSetting(settings, "VisitorDuration", "5"));
+ _filter = SettingService.GetSetting(settings, "VisitorFilter", Constants.DefaultVisitorFilter);
_retention = int.Parse(SettingService.GetSetting(settings, "VisitorRetention", "30"));
_correlation = SettingService.GetSetting(settings, "VisitorCorrelation", "true");
}
@@ -179,7 +187,8 @@ else
await SiteService.UpdateSiteAsync(site);
var settings = await SettingService.GetSiteSettingsAsync(PageState.Site.SiteId);
- settings = SettingService.SetSetting(settings, "VisitorFilter", _filter, true);
+ settings = SettingService.SetSetting(settings, "VisitorDuration", _duration.ToString(), true);
+ settings = SettingService.SetSetting(settings, "VisitorFilter", _filter, true);
settings = SettingService.SetSetting(settings, "VisitorRetention", _retention.ToString(), true);
settings = SettingService.SetSetting(settings, "VisitorCorrelation", _correlation, true);
await SettingService.UpdateSiteSettingsAsync(settings, PageState.Site.SiteId);
diff --git a/Oqtane.Client/Resources/Modules/Admin/Visitors/Index.resx b/Oqtane.Client/Resources/Modules/Admin/Visitors/Index.resx
index 28bc46d1..37599ccb 100644
--- a/Oqtane.Client/Resources/Modules/Admin/Visitors/Index.resx
+++ b/Oqtane.Client/Resources/Modules/Admin/Visitors/Index.resx
@@ -184,7 +184,7 @@
Number of days of visitor activity to retain
- Retention (Days):
+ Retention:
Indicate if new visitors to this site should be correlated based on their IP Address
@@ -192,4 +192,10 @@
Correlate Visitors?
+
+ The duration of a browsing session considered to be a distinct visit (in minutes)
+
+
+ Session Duration:
+
\ No newline at end of file
diff --git a/Oqtane.Server/Components/App.razor b/Oqtane.Server/Components/App.razor
index 86b2eb40..2ace2726 100644
--- a/Oqtane.Server/Components/App.razor
+++ b/Oqtane.Server/Components/App.razor
@@ -324,14 +324,26 @@
int? userid = Context.User.UserId();
userid = (userid == -1) ? null : userid;
- // check if cookie already exists
+ // get cookie value
+ var visitorCookieName = Constants.VisitorCookiePrefix + SiteId.ToString();
+ var visitorCookieValue = Context.Request.Cookies[visitorCookieName];
+ DateTime expiry = DateTime.MinValue;
+ if (visitorCookieValue.Contains("|"))
+ {
+ var values = visitorCookieValue.Split('|');
+ int.TryParse(values[0], out _visitorId);
+ DateTime.TryParse(values[1], out expiry);
+ }
+ else // legacy cookie format
+ {
+ int.TryParse(visitorCookieValue, out _visitorId);
+ }
+ bool setcookie = false;
Visitor visitor = null;
- bool addcookie = false;
- var VisitorCookie = Constants.VisitorCookiePrefix + SiteId.ToString();
- if (!int.TryParse(Context.Request.Cookies[VisitorCookie], out _visitorId))
+
+ if (_visitorId <= 0)
{
// if enabled use IP Address correlation
- _visitorId = -1;
var correlate = bool.Parse(settings.GetValue("VisitorCorrelation", "true"));
if (correlate)
{
@@ -339,12 +351,12 @@
if (visitor != null)
{
_visitorId = visitor.VisitorId;
- addcookie = true;
+ setcookie = true;
}
}
}
- if (_visitorId == -1)
+ if (_visitorId <= 0)
{
// create new visitor
visitor = new Visitor();
@@ -360,52 +372,59 @@
visitor.VisitedOn = DateTime.UtcNow;
visitor = VisitorRepository.AddVisitor(visitor);
_visitorId = visitor.VisitorId;
- addcookie = true;
+ setcookie = true;
}
else
{
- if (visitor == null)
+ // check expiry
+ if (DateTime.UtcNow > expiry)
{
- // get visitor if it was not previously loaded
- visitor = VisitorRepository.GetVisitor(_visitorId);
- }
- if (visitor != null)
- {
- // update visitor
- visitor.IPAddress = _remoteIPAddress;
- visitor.UserAgent = useragent;
- visitor.Language = language;
- visitor.Url = url;
- if (!string.IsNullOrEmpty(referrer))
+ if (visitor == null)
{
- visitor.Referrer = referrer;
+ // get visitor if not previously loaded
+ visitor = VisitorRepository.GetVisitor(_visitorId);
}
- if (userid != null)
+ if (visitor != null)
{
- visitor.UserId = userid;
+ // update visitor
+ visitor.IPAddress = _remoteIPAddress;
+ visitor.UserAgent = useragent;
+ visitor.Language = language;
+ visitor.Url = url;
+ if (!string.IsNullOrEmpty(referrer))
+ {
+ visitor.Referrer = referrer;
+ }
+ if (userid != null)
+ {
+ visitor.UserId = userid;
+ }
+ visitor.Visits += 1;
+ visitor.VisitedOn = DateTime.UtcNow;
+ VisitorRepository.UpdateVisitor(visitor);
+ setcookie = true;
+ }
+ else
+ {
+ // remove cookie if visitor does not exist
+ Context.Response.Cookies.Delete(visitorCookieName);
}
- visitor.Visits += 1;
- visitor.VisitedOn = DateTime.UtcNow;
- VisitorRepository.UpdateVisitor(visitor);
- }
- else
- {
- // remove cookie if VisitorId does not exist
- Context.Response.Cookies.Delete(VisitorCookie);
}
}
- // append cookie
- if (addcookie)
+ // set cookie
+ if (setcookie)
{
+ expiry = DateTime.UtcNow.AddMinutes(int.Parse(settings.GetValue("VisitorDuration", "5")));
+
Context.Response.Cookies.Append(
- VisitorCookie,
- _visitorId.ToString(),
+ visitorCookieName,
+ $"{_visitorId}|{expiry}",
new CookieOptions()
- {
- Expires = DateTimeOffset.UtcNow.AddYears(1),
- IsEssential = true
- }
+ {
+ Expires = DateTimeOffset.UtcNow.AddYears(10),
+ IsEssential = true
+ }
);
}
}