diff --git a/Oqtane.Client/Modules/Admin/Users/Index.razor b/Oqtane.Client/Modules/Admin/Users/Index.razor
index 8af3d381..e0d895c8 100644
--- a/Oqtane.Client/Modules/Admin/Users/Index.razor
+++ b/Oqtane.Client/Modules/Admin/Users/Index.razor
@@ -17,171 +17,180 @@ else
{
-
+
-
- |
- |
- |
+
+ |
+ |
+ |
SortTable("Username"))">@Localizer["Username"] |
SortTable("DisplayName"))">@Localizer["Name"] |
SortTable("Email"))">@Localizer["Email"] |
SortTable("LastLoginOn"))">@Localizer["LastLoginOn"] |
-
-
-
+
+
+
- |
-
+ |
+
- |
-
+ |
+
- |
- @context.User.Username |
- @context.User.DisplayName |
- @((MarkupString)string.Format("{1}", @context.User.Email, @context.User.Email)) |
- @((context.User.LastLoginOn != DateTime.MinValue) ? string.Format("{0:dd-MMM-yyyy HH:mm:ss}", context.User.LastLoginOn) : "") |
-
-
+ |
+ @context.User.Username |
+ @context.User.DisplayName |
+ @((MarkupString)string.Format("{1}", @context.User.Email, @context.User.Email)) |
+ @((context.User.LastLoginOn != DateTime.MinValue) ? string.Format("{0:dd-MMM-yyyy HH:mm:ss}", context.User.LastLoginOn) : "") |
+
+
-
-
-
-
-
-
-
-
- @if (_providertype != "")
- {
-
-
-
-
-
-
- }
- else
- {
-
- }
- @if (UserSecurity.IsAuthorized(PageState.User, RoleNames.Host))
- {
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+ @if (UserSecurity.IsAuthorized(PageState.User, RoleNames.Host))
+ {
+ @if (_providertype != "")
+ {
+
+
+
+
+
+
+ }
+ else
+ {
+
+ }
+
+
+
+
+
+
+
+
-
-
-
-
-
+
-
+
-
-
- }
-
- @if (UserSecurity.IsAuthorized(PageState.User, RoleNames.Host))
- {
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+ }
+
+ @if (UserSecurity.IsAuthorized(PageState.User, RoleNames.Host))
+ {
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
@@ -201,77 +210,77 @@ else
-
-
-
- @if (_providertype != "")
- {
-
- }
- @if (_providertype == AuthenticationProviderTypes.OpenIDConnect)
- {
-
-
- }
- @if (_providertype == AuthenticationProviderTypes.OAuth2)
- {
-
-
-
-
-
-
-
-
- }
- @if (_providertype != "")
- {
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+ @if (_providertype != "")
+ {
+
+ }
+ @if (_providertype == AuthenticationProviderTypes.OpenIDConnect)
+ {
+
+
+ }
+ @if (_providertype == AuthenticationProviderTypes.OAuth2)
+ {
+
+
+
+
+
+
+
+
+ }
+ @if (_providertype != "")
+ {
+
+
+
+
+
+
+
+
+
+
@if (_providertype == AuthenticationProviderTypes.OpenIDConnect)
{
@@ -291,32 +300,32 @@ else
}
-
+
+
+
+
+
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
@@ -334,10 +343,10 @@ else
-
-
-
-
+
+
+
+
@@ -346,16 +355,16 @@ else
-
+
+
+
+
+
@@ -374,11 +383,11 @@ else
-
-
-
-
-
+
+
+
+
+
@@ -389,20 +398,20 @@ else
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
@@ -413,51 +422,51 @@ else
}
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- }
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ }
+
+
+
-
+
}
@code {
@@ -469,6 +478,7 @@ else
private string _cookiename;
private string _cookieexpiration;
private string _alwaysremember;
+ private string _logouteverywhere;
private string _minimumlength;
private string _uniquecharacters;
@@ -529,7 +539,7 @@ else
await LoadUsersAsync(true);
var settings = await SettingService.GetSiteSettingsAsync(PageState.Site.SiteId);
- _allowregistration = PageState.Site.AllowRegistration.ToString();
+ _allowregistration = PageState.Site.AllowRegistration.ToString().ToLower();
_allowsitelogin = SettingService.GetSetting(settings, "LoginOptions:AllowSiteLogin", "true");
if (UserSecurity.IsAuthorized(PageState.User, RoleNames.Host))
@@ -538,6 +548,7 @@ else
_cookiename = SettingService.GetSetting(settings, "LoginOptions:CookieName", ".AspNetCore.Identity.Application");
_cookieexpiration = SettingService.GetSetting(settings, "LoginOptions:CookieExpiration", "");
_alwaysremember = SettingService.GetSetting(settings, "LoginOptions:AlwaysRemember", "false");
+ _logouteverywhere = SettingService.GetSetting(settings, "LoginOptions:LogoutEverywhere", "false");
_minimumlength = SettingService.GetSetting(settings, "IdentityOptions:Password:RequiredLength", "6");
_uniquecharacters = SettingService.GetSetting(settings, "IdentityOptions:Password:RequiredUniqueChars", "1");
@@ -656,6 +667,7 @@ else
settings = SettingService.SetSetting(settings, "LoginOptions:CookieName", _cookiename, true);
settings = SettingService.SetSetting(settings, "LoginOptions:CookieExpiration", _cookieexpiration, true);
settings = SettingService.SetSetting(settings, "LoginOptions:AlwaysRemember", _alwaysremember, false);
+ settings = SettingService.SetSetting(settings, "LoginOptions:LogoutEverywhere", _logouteverywhere, false);
settings = SettingService.SetSetting(settings, "IdentityOptions:Password:RequiredLength", _minimumlength, true);
settings = SettingService.SetSetting(settings, "IdentityOptions:Password:RequiredUniqueChars", _uniquecharacters, true);
diff --git a/Oqtane.Client/Resources/Modules/Admin/Users/Index.resx b/Oqtane.Client/Resources/Modules/Admin/Users/Index.resx
index 34884fb5..3b0bda17 100644
--- a/Oqtane.Client/Resources/Modules/Admin/Users/Index.resx
+++ b/Oqtane.Client/Resources/Modules/Admin/Users/Index.resx
@@ -507,4 +507,10 @@
Error Deleting User
+
+ Logout Everywhere?
+
+
+ Do you want users to be logged out of every active session on any device, or only their current session?
+
\ No newline at end of file
diff --git a/Oqtane.Client/Themes/Controls/Theme/ControlPanelInteractive.razor b/Oqtane.Client/Themes/Controls/Theme/ControlPanelInteractive.razor
index 5f1f5d5d..5dd940f8 100644
--- a/Oqtane.Client/Themes/Controls/Theme/ControlPanelInteractive.razor
+++ b/Oqtane.Client/Themes/Controls/Theme/ControlPanelInteractive.razor
@@ -573,7 +573,7 @@
else
{
// post to the Logout page to complete the logout process
- var fields = new { __RequestVerificationToken = SiteState.AntiForgeryToken, returnurl = url };
+ var fields = new { __RequestVerificationToken = SiteState.AntiForgeryToken, returnurl = url, everywhere = bool.Parse(SettingService.GetSetting(PageState.Site.Settings, "LoginOptions:LogoutEverywhere", "false")) };
var interop = new Interop(jsRuntime);
await interop.SubmitForm(Utilities.TenantUrl(PageState.Alias, "/pages/logout/"), fields);
}
diff --git a/Oqtane.Client/Themes/Controls/Theme/Login.razor b/Oqtane.Client/Themes/Controls/Theme/Login.razor
index 69bd2922..f1bf1ebc 100644
--- a/Oqtane.Client/Themes/Controls/Theme/Login.razor
+++ b/Oqtane.Client/Themes/Controls/Theme/Login.razor
@@ -15,6 +15,7 @@
}
diff --git a/Oqtane.Client/Themes/Controls/Theme/LoginBase.cs b/Oqtane.Client/Themes/Controls/Theme/LoginBase.cs
index 099be1d5..846cbcb7 100644
--- a/Oqtane.Client/Themes/Controls/Theme/LoginBase.cs
+++ b/Oqtane.Client/Themes/Controls/Theme/LoginBase.cs
@@ -4,7 +4,6 @@ using System.Threading.Tasks;
using Microsoft.AspNetCore.Components;
using Microsoft.JSInterop;
using Oqtane.Enums;
-using Oqtane.Models;
using Oqtane.Providers;
using Oqtane.Security;
using Oqtane.Services;
@@ -26,6 +25,7 @@ namespace Oqtane.Themes.Controls
protected string loginurl;
protected string logouturl;
protected string returnurl;
+ protected string everywhere;
protected override void OnParametersSet()
{
@@ -57,6 +57,7 @@ namespace Oqtane.Themes.Controls
// set logout url
logouturl = Utilities.TenantUrl(PageState.Alias, "/pages/logout/");
+ everywhere = SettingService.GetSetting(PageState.Site.Settings, "LoginOptions:LogoutEverywhere", "false");
// verify anonymous users can access current page
if (UserSecurity.IsAuthorized(null, PermissionNames.View, PageState.Page.PermissionList) && Utilities.IsEffectiveAndNotExpired(PageState.Page.EffectiveDate, PageState.Page.ExpiryDate))
@@ -98,7 +99,7 @@ namespace Oqtane.Themes.Controls
else // this condition is only valid for legacy Login button inheriting from LoginBase
{
// post to the Logout page to complete the logout process
- var fields = new { __RequestVerificationToken = SiteState.AntiForgeryToken, returnurl = returnurl };
+ var fields = new { __RequestVerificationToken = SiteState.AntiForgeryToken, returnurl = returnurl, everywhere = bool.Parse(SettingService.GetSetting(PageState.Site.Settings, "LoginOptions:LogoutEverywhere", "false")) };
var interop = new Interop(jsRuntime);
await interop.SubmitForm(logouturl, fields);
}