diff --git a/GanjooRazor/Areas/User/Pages/MySessions.cshtml b/GanjooRazor/Areas/User/Pages/MySessions.cshtml
index 48d6a128..13a7ebc5 100644
--- a/GanjooRazor/Areas/User/Pages/MySessions.cshtml
+++ b/GanjooRazor/Areas/User/Pages/MySessions.cshtml
@@ -1,6 +1,7 @@
@page
@model GanjooRazor.Areas.User.Pages.MySessionsModel
@using DNTPersianUtils.Core
+@using System.Linq
@{
Layout = "_UserPanelLayout";
ViewData["Title"] = "نشستهای من";
@@ -10,6 +11,14 @@
@ViewData["Title"]
دستگاهها و مرورگرهایی که هماکنون با حساب کاربری شما وارد گنجور شدهاند. اگر دستگاهی را نمیشناسید یا دیگر از آن استفاده نمیکنید، آن را از این فهرست خارج کنید.
+@if (Model.LastError == "" && Model.Sessions != null && Model.Sessions.Count(s => s.Id != Model.CurrentSessionId) > 0)
+{
+
+}
@if (Model.LastError != "")
{
@Model.LastError
@@ -42,6 +51,29 @@ else
}
});
}
+
+ async function logoutOtherSessions() {
+ var ok = await upConfirm('با این کار از حساب کاربری خود در تمام دستگاهها و مرورگرهای دیگر (بهجز همین یکی) خارج خواهید شد. آیا ادامه میدهید؟');
+ if (!ok) return;
+
+ $.ajax({
+ type: "DELETE",
+ url: '?handler=LogoutOthers',
+ success: function (res) {
+ var removedCount = (res && res.removedCount) || 0;
+ $('.up-list-item').each(function () {
+ if (this.id !== 'session-@Model.CurrentSessionId') {
+ $(this).remove();
+ }
+ });
+ $('#logout-others-btn').closest('div').remove();
+ upToast(removedCount > 0 ? 'از ' + removedCount.toLocaleString('fa-IR') + ' دستگاه دیگر خارج شدید.' : 'دستگاه دیگری برای خروج یافت نشد.', 'success');
+ },
+ error: function (e) {
+ upToast(e.responseText || 'خروج از سایر دستگاهها با خطا مواجه شد.', 'error');
+ }
+ });
+ }
@if (Model.Sessions.Count == 0)
diff --git a/GanjooRazor/Areas/User/Pages/MySessions.cshtml.cs b/GanjooRazor/Areas/User/Pages/MySessions.cshtml.cs
index 22737a9e..4aceaf63 100644
--- a/GanjooRazor/Areas/User/Pages/MySessions.cshtml.cs
+++ b/GanjooRazor/Areas/User/Pages/MySessions.cshtml.cs
@@ -121,5 +121,33 @@ namespace GanjooRazor.Areas.User.Pages
return new JsonResult(new { loggedOutSelf });
}
+
+ ///
+ /// Logs the user out of every session but this one (a critical-account cleanup shortcut
+ /// for someone logged in on several computers, instead of removing each session one at a
+ /// time). This browser's own session is always the one preserved - it never removes the
+ /// session the request itself is authenticated with, so unlike OnDeleteSessionAsync there
+ /// is no "logged out myself" case to special-case here.
+ ///
+ public async Task OnDeleteLogoutOthersAsync()
+ {
+ using (HttpClient secureClient = new HttpClient(new GanjoorReloginHandler(Request, Response)))
+ {
+ if (await GanjoorSessionChecker.PrepareClient(secureClient, Request, Response))
+ {
+ var response = await secureClient.DeleteAsync($"{APIRoot.Url}/api/users/delothersessions?userId={Request.Cookies["UserId"]}");
+ if (response.StatusCode != HttpStatusCode.OK)
+ {
+ return new BadRequestObjectResult(await ReadErrorMessageAsync(response));
+ }
+ int removedCount = int.Parse(await response.Content.ReadAsStringAsync());
+ return new JsonResult(new { removedCount });
+ }
+ else
+ {
+ return new BadRequestObjectResult(NotLoggedInMessage);
+ }
+ }
+ }
}
}
diff --git a/RMuseum/RMuseum.csproj b/RMuseum/RMuseum.csproj
index 8b7da4de..02a97d34 100644
--- a/RMuseum/RMuseum.csproj
+++ b/RMuseum/RMuseum.csproj
@@ -29,7 +29,7 @@
-
+