From 4ea1f46f2b3b26f0ca3fa3f4fa4517ecab217db6 Mon Sep 17 00:00:00 2001 From: Nikolaj Geisle Date: Thu, 30 Sep 2021 13:09:04 +0200 Subject: [PATCH] Implemented variable data instead of hardcoded --- .../DependencyInjection/UmbracoBuilder.cs | 3 + src/Umbraco.Core/Models/UserData.cs | 19 ++++ src/Umbraco.Core/Services/IUserDataService.cs | 10 +++ src/Umbraco.Core/Services/UserDataService.cs | 57 ++++++++++++ .../Controllers/CurrentUserController.cs | 11 ++- .../common/resources/currentuser.resource.js | 9 +- .../src/common/services/platform.service.js | 87 ++++++++++++++++--- .../common/drawers/help/help.controller.js | 43 +++++++-- 8 files changed, 214 insertions(+), 25 deletions(-) create mode 100644 src/Umbraco.Core/Models/UserData.cs create mode 100644 src/Umbraco.Core/Services/IUserDataService.cs create mode 100644 src/Umbraco.Core/Services/UserDataService.cs diff --git a/src/Umbraco.Core/DependencyInjection/UmbracoBuilder.cs b/src/Umbraco.Core/DependencyInjection/UmbracoBuilder.cs index 6f6a53df66..5185e5387a 100644 --- a/src/Umbraco.Core/DependencyInjection/UmbracoBuilder.cs +++ b/src/Umbraco.Core/DependencyInjection/UmbracoBuilder.cs @@ -26,6 +26,8 @@ using Umbraco.Cms.Core.IO; using Umbraco.Cms.Core.Logging; using Umbraco.Cms.Core.Mail; using Umbraco.Cms.Core.Manifest; +using Umbraco.Cms.Core.Models; +using Umbraco.Cms.Core.Models.Membership; using Umbraco.Cms.Core.Models.PublishedContent; using Umbraco.Cms.Core.Notifications; using Umbraco.Cms.Core.PropertyEditors; @@ -179,6 +181,7 @@ namespace Umbraco.Cms.Core.DependencyInjection Services.AddUnique(); Services.AddUnique(); + Services.AddUnique(); // will be injected in controllers when needed to invoke rest endpoints on Our Services.AddUnique(); diff --git a/src/Umbraco.Core/Models/UserData.cs b/src/Umbraco.Core/Models/UserData.cs new file mode 100644 index 0000000000..07b45b3c54 --- /dev/null +++ b/src/Umbraco.Core/Models/UserData.cs @@ -0,0 +1,19 @@ +using System.Runtime.Serialization; + +namespace Umbraco.Cms.Core.Models +{ + [DataContract] + public class UserData + { + [DataMember(Name = "name")] + public string Name { get; } + [DataMember(Name = "data")] + public string Data { get; } + + public UserData(string name, string data) + { + Name = name; + Data = data; + } + } +} diff --git a/src/Umbraco.Core/Services/IUserDataService.cs b/src/Umbraco.Core/Services/IUserDataService.cs new file mode 100644 index 0000000000..e63ee3f697 --- /dev/null +++ b/src/Umbraco.Core/Services/IUserDataService.cs @@ -0,0 +1,10 @@ +using System.Collections.Generic; +using Umbraco.Cms.Core.Models; + +namespace Umbraco.Cms.Core.Services +{ + public interface IUserDataService + { + IEnumerable GetUserData(); + } +} diff --git a/src/Umbraco.Core/Services/UserDataService.cs b/src/Umbraco.Core/Services/UserDataService.cs new file mode 100644 index 0000000000..87a92d199f --- /dev/null +++ b/src/Umbraco.Core/Services/UserDataService.cs @@ -0,0 +1,57 @@ +using System; +using System.Collections.Generic; +using System.Diagnostics; +using System.IO; +using System.Runtime.InteropServices; +using System.Threading; +using Umbraco.Cms.Core.Configuration; +using Umbraco.Cms.Core.Models; +using Umbraco.Cms.Core.Web; +using Umbraco.Extensions; + +namespace Umbraco.Cms.Core.Services +{ + public class UserDataService : IUserDataService + { + private IUmbracoVersion _version; + public UserDataService(IUmbracoVersion version) + { + _version = version; + } + + public IEnumerable GetUserData() + { + + var userDataList = new List + { + + new UserData("Server OS", Environment.OSVersion.VersionString), + new UserData("Umbraco Version", _version.SemanticVersion.ToSemanticStringWithoutBuild()), + new UserData("Current Culture", Thread.CurrentThread.CurrentCulture.ToString()), + new UserData("Current UI Culture", Thread.CurrentThread.CurrentUICulture.ToString()), + new UserData("Current Webserver", GetCurrentWebServer()) + }; + return userDataList; + } + + public string GetCurrentWebServer() + { + if (IsRunningInProcessIIS()) + { + return "IIS"; + } + + return "Kestrel"; + } + public bool IsRunningInProcessIIS() + { + if (!RuntimeInformation.IsOSPlatform(OSPlatform.Windows)) + { + return false; + } + + string processName = Path.GetFileNameWithoutExtension(Process.GetCurrentProcess().ProcessName); + return (processName.Contains("w3wp") || processName.Contains("iisexpress")); + } + } +} diff --git a/src/Umbraco.Web.BackOffice/Controllers/CurrentUserController.cs b/src/Umbraco.Web.BackOffice/Controllers/CurrentUserController.cs index ba6ca36085..b7e4612b6e 100644 --- a/src/Umbraco.Web.BackOffice/Controllers/CurrentUserController.cs +++ b/src/Umbraco.Web.BackOffice/Controllers/CurrentUserController.cs @@ -22,9 +22,7 @@ using Umbraco.Cms.Core.Models.Membership; using Umbraco.Cms.Core.Security; using Umbraco.Cms.Core.Services; using Umbraco.Cms.Core.Strings; -using Umbraco.Cms.Web.BackOffice.Extensions; using Umbraco.Cms.Web.BackOffice.Filters; -using Umbraco.Cms.Web.Common.ActionsResults; using Umbraco.Cms.Web.Common.Attributes; using Umbraco.Cms.Web.Common.Authorization; using Umbraco.Cms.Web.Common.Security; @@ -47,11 +45,11 @@ namespace Umbraco.Cms.Web.BackOffice.Controllers private readonly IUserService _userService; private readonly IUmbracoMapper _umbracoMapper; private readonly IBackOfficeUserManager _backOfficeUserManager; - private readonly ILoggerFactory _loggerFactory; private readonly ILocalizedTextService _localizedTextService; private readonly AppCaches _appCaches; private readonly IShortStringHelper _shortStringHelper; private readonly IPasswordChanger _passwordChanger; + private readonly IUserDataService _userDataService; public CurrentUserController( MediaFileManager mediaFileManager, @@ -62,11 +60,11 @@ namespace Umbraco.Cms.Web.BackOffice.Controllers IUserService userService, IUmbracoMapper umbracoMapper, IBackOfficeUserManager backOfficeUserManager, - ILoggerFactory loggerFactory, ILocalizedTextService localizedTextService, AppCaches appCaches, IShortStringHelper shortStringHelper, - IPasswordChanger passwordChanger) + IPasswordChanger passwordChanger, + IUserDataService userDataService) { _mediaFileManager = mediaFileManager; _contentSettings = contentSettings.Value; @@ -76,11 +74,11 @@ namespace Umbraco.Cms.Web.BackOffice.Controllers _userService = userService; _umbracoMapper = umbracoMapper; _backOfficeUserManager = backOfficeUserManager; - _loggerFactory = loggerFactory; _localizedTextService = localizedTextService; _appCaches = appCaches; _shortStringHelper = shortStringHelper; _passwordChanger = passwordChanger; + _userDataService = userDataService; } @@ -166,6 +164,7 @@ namespace Umbraco.Cms.Web.BackOffice.Controllers var userTours = JsonConvert.DeserializeObject>(_backofficeSecurityAccessor.BackOfficeSecurity.CurrentUser.TourData); return userTours; } + public IEnumerable GetUserData() => _userDataService.GetUserData(); /// /// When a user is invited and they click on the invitation link, they will be partially logged in diff --git a/src/Umbraco.Web.UI.Client/src/common/resources/currentuser.resource.js b/src/Umbraco.Web.UI.Client/src/common/resources/currentuser.resource.js index a3be6996b1..23870d882f 100644 --- a/src/Umbraco.Web.UI.Client/src/common/resources/currentuser.resource.js +++ b/src/Umbraco.Web.UI.Client/src/common/resources/currentuser.resource.js @@ -51,7 +51,6 @@ function currentUserResource($q, $http, umbRequestHelper, umbDataFormatter) { [{ permissionToCheck: permission }, { nodeId: id }])), 'Failed to check permission for item ' + id); }, - getCurrentUserLinkedLogins: function () { return umbRequestHelper.resourcePromise( @@ -61,6 +60,14 @@ function currentUserResource($q, $http, umbRequestHelper, umbDataFormatter) { "GetCurrentUserLinkedLogins")), 'Server call failed for getting current users linked logins'); }, + getUserData: function () { + return umbRequestHelper.resourcePromise( + $http.get( + umbRequestHelper.getApiUrl( + "currentUserApiBaseUrl", + "GetUserData")), + 'Server call failed for getting current user data'); + }, saveTourStatus: function (tourStatus) { diff --git a/src/Umbraco.Web.UI.Client/src/common/services/platform.service.js b/src/Umbraco.Web.UI.Client/src/common/services/platform.service.js index 7834c2f781..acd9533151 100644 --- a/src/Umbraco.Web.UI.Client/src/common/services/platform.service.js +++ b/src/Umbraco.Web.UI.Client/src/common/services/platform.service.js @@ -1,23 +1,84 @@ -(function() { - 'use strict'; +(function () { + 'use strict'; - function platformService() { + function platformService() { + const userAgentRules = [ + ['Aol', /AOLShield\/([0-9\._]+)/], + ['Edge', /Edge\/([0-9\._]+)/], + ['Edge-ios', /EdgiOS\/([0-9\._]+)/], + ['Yandexbrowser', /YaBrowser\/([0-9\._]+)/], + ['Kakaotalk', /KAKAOTALK\s([0-9\.]+)/], + ['Samsung', /SamsungBrowser\/([0-9\.]+)/], + ['Silk', /\bSilk\/([0-9._-]+)\b/], + ['MiUI', /MiuiBrowser\/([0-9\.]+)$/], + ['Beaker', /BeakerBrowser\/([0-9\.]+)/], + ['Edge-chromium', /EdgA?\/([0-9\.]+)/], + ['chromium-webview', /(?!Chrom.*OPR)wv\).*Chrom(?:e|ium)\/([0-9\.]+)(:?\s|$)/], + ['Chrome', /(?!Chrom.*OPR)Chrom(?:e|ium)\/([0-9\.]+)(:?\s|$)/], + ['PhantomJS', /PhantomJS\/([0-9\.]+)(:?\s|$)/], + ['Crios', /CriOS\/([0-9\.]+)(:?\s|$)/], + ['Firefox', /Firefox\/([0-9\.]+)(?:\s|$)/], + ['FxiOS', /FxiOS\/([0-9\.]+)/], + ['Opera-mini', /Opera Mini.*Version\/([0-9\.]+)/], + ['Opera', /Opera\/([0-9\.]+)(?:\s|$)/], + ['Opera', /OPR\/([0-9\.]+)(:?\s|$)/], + ['IE', /Trident\/7\.0.*rv\:([0-9\.]+).*\).*Gecko$/], + ['IE', /MSIE\s([0-9\.]+);.*Trident\/[4-7].0/], + ['IE', /MSIE\s(7\.0)/], + ['BB10', /BB10;\sTouch.*Version\/([0-9\.]+)/], + ['Android', /Android\s([0-9\.]+)/], + ['iOS', /Version\/([0-9\._]+).*Mobile.*Safari.*/], + ['Safari', /Version\/([0-9\._]+).*Safari/], + ['Facebook', /FB[AS]V\/([0-9\.]+)/], + ['Instagram', /Instagram\s([0-9\.]+)/], + ['iOS-webview', /AppleWebKit\/([0-9\.]+).*Mobile/], + ['iOS-webview', /AppleWebKit\/([0-9\.]+).*Gecko\)$/], + ['Curl', /^curl\/([0-9\.]+)$/] + ]; - function isMac() { - return navigator.platform.toUpperCase().indexOf('MAC')>=0; - } + function isMac() { + return navigator.platform.toUpperCase().indexOf('MAC') >= 0; + } - //////////// - - var service = { - isMac: isMac + function getBrowserInfo(){ + let data = matchUserAgent(navigator.userAgent); + console.log(data); + if(data){ + const test = data[1]; + return { + name : data[0], + version : test[1] }; + } + return null; + } - return service; + function matchUserAgent(ua) { + return (ua !== '' && userAgentRules.reduce ( + (matched, [browser, regex]) => { + if (matched) { + return matched; + } + const uaMatch = regex.exec(ua); + return !!uaMatch && [browser, uaMatch]; + }, + false + ) + ); + } - } + //////////// - angular.module('umbraco.services').factory('platformService', platformService); + var service = { + isMac: isMac, + getBrowserInfo : getBrowserInfo + }; + + return service; + + } + + angular.module('umbraco.services').factory('platformService', platformService); })(); diff --git a/src/Umbraco.Web.UI.Client/src/views/common/drawers/help/help.controller.js b/src/Umbraco.Web.UI.Client/src/views/common/drawers/help/help.controller.js index 78adf10385..f58d42f22d 100644 --- a/src/Umbraco.Web.UI.Client/src/views/common/drawers/help/help.controller.js +++ b/src/Umbraco.Web.UI.Client/src/views/common/drawers/help/help.controller.js @@ -1,7 +1,7 @@ (function () { "use strict"; - function HelpDrawerController($scope, $routeParams, $timeout, dashboardResource, localizationService, userService, eventsService, helpService, appState, tourService, $filter, editorState, notificationsService) { + function HelpDrawerController($scope, $routeParams, $timeout, dashboardResource, localizationService, userService, eventsService, helpService, appState, tourService, $filter, editorState, notificationsService, currentUserResource, platformService) { var vm = this; var evts = []; @@ -22,8 +22,7 @@ vm.showDocTypeTour = false; vm.docTypeTours = []; - vm.systemInfo = [{name : "Umbraco Version", data : "9.0.0-rc004"}, {name : "Operating System", data : "Windows"}, {name : "Current Culture", data : "en-US"}, {name : "Current UI Culture", data : "dn-DK"}, - {name : "Webserver", data : "Kestrel"}, {name : "Packages", data : "Umbraco.TheStarterKit, uSync"}, {name : "Browser", data : "Electron"}] + vm.systemInfo = []; vm.nodeName = ''; function startTour(tour) { @@ -37,7 +36,14 @@ localizationService.localize("general_help").then(function(data){ vm.title = data; }); - + currentUserResource.getUserData().then(function(systemInfo){ + vm.systemInfo = systemInfo; + let browserInfo = platformService.getBrowserInfo(); + if(browserInfo != null){ + vm.systemInfo.push({name :"Browser", data: browserInfo.name + " " + browserInfo.version}); + } + vm.systemInfo.push({name :"User OS", data: getPlatform()}); + }); tourService.getGroupedTours().then(function(groupedTours) { vm.tours = groupedTours; getTourGroupCompletedPercentage(); @@ -208,13 +214,40 @@ }); copyText += "\n\n\n" navigator.clipboard.writeText(copyText); - if(copyText != null || copyText != ""){ + if(copyText != null){ notificationsService.success("Copied!", "Your system information is now in your clipboard"); } else{ notificationsService.error("Sadge", "something failed"); } } + function getPlatform() { + const allPlatforms = ['Win32', 'Win64', 'Windows', 'WinCE', 'Android', 'iPhone', 'iPad', 'iPod']; + return allPlatforms.find(item => item === window.navigator.platform); + } + function getCurrentBrowser(){ + let sBrowser, sUsrAg = window.navigator.userAgent; + if (sUsrAg.indexOf("Firefox") > -1) { + sBrowser = "Mozilla Firefox"; + } else if (sUsrAg.indexOf("SamsungBrowser") > -1) { + sBrowser = "Samsung Internet"; + } else if (sUsrAg.indexOf("Opera") > -1 || sUsrAg.indexOf("OPR") > -1) { + sBrowser = "Opera"; + } else if (sUsrAg.indexOf("Trident") > -1) { + sBrowser = "Microsoft Internet Explorer"; + } else if (sUsrAg.indexOf("Edge") > -1) { + sBrowser = "Microsoft Edge (Legacy)"; + } else if (sUsrAg.indexOf("Edg") > -1) { + sBrowser = "Microsoft Edge (Chromium)"; + } else if (sUsrAg.indexOf("Chrome") > -1) { + sBrowser = "Google Chrome or Chromium"; + } else if (sUsrAg.indexOf("Safari") > -1) { + sBrowser = "Apple Safari"; + } else { + sBrowser = "unknown"; + } + return sBrowser; + } evts.push(eventsService.on("appState.tour.complete", function (event, tour) { tourService.getGroupedTours().then(function(groupedTours) { vm.tours = groupedTours;