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 + } ); } }