<%@ page contentType="text/html; charset=UTF-8" %> <%-- - - Copyright (C) 2004-2008 Jive Software, 2017-2025 Ignite Realtime Foundation. All rights reserved. - - Licensed under the Apache License, Version 2.0 (the "License"); - you may not use this file except in compliance with the License. - You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. --%> <%@ page import="org.jivesoftware.openfire.PresenceManager, org.jivesoftware.openfire.SessionManager, org.jivesoftware.openfire.user.User, org.jivesoftware.openfire.user.UserManager, org.jivesoftware.util.JiveGlobals, org.jivesoftware.util.ParamUtils, org.jivesoftware.util.StringUtils, org.jivesoftware.util.CookieUtils, java.text.NumberFormat, java.util.Collection" errorPage="error.jsp" %> <%@ page import="org.jivesoftware.openfire.nio.NettyConnection" %> <%@ page import="org.jivesoftware.openfire.websocket.WebSocketConnection" %> <%@ page import="org.jivesoftware.openfire.http.HttpSession" %> <%@ page import="java.util.Map" %> <%@ page import="java.util.TreeMap" %> <%@ page import="org.jivesoftware.openfire.XMPPServer" %> <%@ page import="org.jivesoftware.openfire.entitycaps.EntityCapabilities" %> <%@ page import="java.util.TreeSet" %> <%@ page import="org.jivesoftware.openfire.cluster.ClusterManager" %> <%@ page import="org.slf4j.LoggerFactory" %> <%@ page import="java.nio.charset.StandardCharsets" %> <%@ page import="org.jivesoftware.openfire.session.*" %> <%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c" %> <%@ taglib uri="http://java.sun.com/jsp/jstl/fmt" prefix="fmt" %> <%@ taglib uri="http://java.sun.com/jsp/jstl/functions" prefix="fn" %> <% webManager.init(request, response, session, application, out ); %> <% // Get parameters String jid = ParamUtils.getParameter(request, "jid"); Cookie csrfCookie = CookieUtils.getCookie(request, "csrf"); String csrfParam = ParamUtils.getParameter(request, "csrf"); boolean close = request.getParameter("close") != null; if (close) { if (csrfCookie == null || csrfParam == null || !csrfCookie.getValue().equals(csrfParam)) { close = false; } } // Get the user manager SessionManager sessionManager = webManager.getSessionManager(); // Close a connection if requested if (close) { JID address = new JID(jid); try { Session sess = sessionManager.getSession(address); sess.markNonResumable(); sess.close(); // Log the event webManager.logEvent("closed session for address "+address, null); // wait one second Thread.sleep(250L); } catch (Exception e) { // Session might have disappeared on its own LoggerFactory.getLogger("session-details.jsp").warn("Unable to manually close session for address: {}", address, e); } // Redirect back to this page response.sendRedirect("session-summary.jsp?close=success"); return; } csrfParam = StringUtils.randomString(15); CookieUtils.setCookie(request, response, "csrf", csrfParam, -1); pageContext.setAttribute("csrf", csrfParam); // Handle a "go back" click: if (request.getParameter("back") != null) { response.sendRedirect("session-summary.jsp"); return; } boolean showCaps = request.getParameter("show") != null; // Get the session & address objects JID address = new JID(jid); org.jivesoftware.openfire.session.ClientSession currentSess = sessionManager.getSession(address); boolean isAnonymous = webManager.getXMPPServer().isLocal(address) && !UserManager.getInstance().isRegisteredUser(address, false); // No current session found if (currentSess == null) { response.sendRedirect("session-summary.jsp"); return; } // Get a presence manager PresenceManager presenceManager = webManager.getPresenceManager(); // Get user object User user = null; if (!isAnonymous) { user = webManager.getUserManager().getUser(address.getNode()); } // Handle a "message" click: if (request.getParameter("message") != null) { if (csrfCookie != null && csrfParam != null && csrfCookie.getValue().equals(csrfParam)) { response.sendRedirect("user-message.jsp?username=" + URLEncoder.encode(user.getUsername(), StandardCharsets.UTF_8)); return; } } // See if there are multiple sessions for this user: Collection sessions = null; int sessionCount = sessionManager.getSessionCount(address.getNode()); if (!isAnonymous && sessionCount > 1) { sessions = sessionManager.getSessions(address); } // Number dateFormatter for all numbers on this page: NumberFormat numFormatter = NumberFormat.getNumberInstance(); final boolean clusteringEnabled = ClusterManager.isClusteringStarted() || ClusterManager.isClusteringStarting(); pageContext.setAttribute("address", address); pageContext.setAttribute("clusteringEnabled", ClusterManager.isClusteringStarted() || ClusterManager.isClusteringStarting() ); %> <fmt:message key="session.details.title"/>

<% if (clusteringEnabled) { %> <% } %>
<%= StringUtils.escapeHTMLTags(address.toString()) %>
<% String n = address.getNode(); %> <% if (isAnonymous) { %> - <%= StringUtils.escapeHTMLTags(address.getResource()) %> <% } else { %> <%= StringUtils.escapeHTMLTags(JID.unescapeNode(n)) %> - <%= StringUtils.escapeForXML(address.getResource()) %> <% } %>
<% if (currentSess instanceof LocalClientSession) { %> <% } else { %> <% } %>
: <% Session.Status status = currentSess.getStatus(); if (status == Session.Status.CLOSED) { %> <% } else if (status == Session.Status.CONNECTED) { %> <% } else if (status == Session.Status.AUTHENTICATED) { %> <% } else { %> <% } %>
: <% Presence.Show show = currentSess.getPresence().getShow(); String statusTxt = currentSess.getPresence().getStatus(); if (statusTxt != null) { statusTxt = " -- " + StringUtils.escapeHTMLTags(statusTxt); } else { statusTxt = ""; } if (!currentSess.getPresence().isAvailable()) { %> " alt=""> <% } else if (show == Presence.Show.away) { %> " alt=""> <%= statusTxt %> <% } else if (show == Presence.Show.chat) { %> " alt=""> <%= statusTxt %> <% } else if (show == Presence.Show.dnd) { %> " alt=""> <%= statusTxt %> <% } else if (show == null) { %> " alt=""> <%= statusTxt %> <% } else if (show == Presence.Show.xa) { %> " alt=""> <%= statusTxt %> <% } else { %> <% } %>
<%= currentSess.getPresence().getPriority() %>
<%= JiveGlobals.formatDateTime(currentSess.getCreationDate()) %>
<%= JiveGlobals.formatDateTime(currentSess.getLastActiveDate()) %>
<%= numFormatter.format(currentSess.getNumClientPackets()) %>/<%= numFormatter.format(currentSess.getNumServerPackets()) %>

<% if (currentSess instanceof LocalClientSession) { LocalClientSession s = (LocalClientSession)currentSess; %> <% } %> <% if (currentSess instanceof LocalClientSession) { LocalClientSession s = (LocalClientSession)currentSess; if (s.getConnection() != null && s.getConnection().getConfiguration() != null) { %> <% } } %>
: <% if (s.isDetached()) { %><% } else if (s.getConnection() instanceof NettyConnection) { %>TCP<% } else if (s.getConnection() instanceof WebSocketConnection) { %>WebSocket<% } else if (s.getConnection() instanceof HttpSession.HttpVirtualConnection) { %>BOSH<% } else { %>Unknown<% } %>
<% if (currentSess.isDetached()) { %> <% } else { try { %> <%= StringUtils.escapeHTMLTags(currentSess.getHostAddress()) %> / <%=StringUtils.escapeHTMLTags(currentSess.getHostName())%> <% } catch (java.net.UnknownHostException e) { %> Invalid session/connection <% } } %>
: <%=s.getConnection().getConfiguration().getPort()%>

<% if (currentSess.isEncrypted()) { %> <% } %> <% if (currentSess instanceof LocalSession && ((LocalSession) currentSess).getSessionData("SaslMechanism") != null) { %> <% } %>
: <%=StringUtils.escapeHTMLTags(currentSess.getTLSProtocolName())%>
: <%=StringUtils.escapeHTMLTags(currentSess.getCipherSuiteName())%>
: <% if (currentSess.isAnonymousUser()) { %> <% } else { %> <% } %>
: <%=StringUtils.escapeHTMLTags(((LocalSession) currentSess).getSessionData("SaslMechanism").toString())%>
<% // Show Software Version if there is : if (!currentSess.getSoftwareVersion().isEmpty()) { %>
<% Map treeMap = new TreeMap<>(currentSess.getSoftwareVersion()); for (Map.Entry entry : treeMap.entrySet()){ %> <% } %>
<%= StringUtils.escapeHTMLTags(entry.getKey().substring(0, 1).toUpperCase()+""+entry.getKey().substring(1)) %>: <%= StringUtils.escapeHTMLTags(entry.getValue())%>
<% } %>
<% if (currentSess instanceof LocalClientSession) { LocalClientSession s = (LocalClientSession)currentSess; %> <% } %>
: <% if (s.isDetached()) { %><% } else if (s.getStreamManager().isEnabled()) { if (s.getStreamManager().getResume()) { %><% } else { %><% } } else { %><% } %>
: <% if (s.getCsiManager().isActive()) { %> <% } else { %> (: <%= s.getCsiManager().getDelayQueueSize() %>) <% } %>
: <% if (currentSess.isMessageCarbonsEnabled()) { %> <% } else { %> <% } %>
: <% if (currentSess.isOfflineFloodStopped()) { %> <% } else { %> <% } %>
<% final EntityCapabilities caps = XMPPServer.getInstance().getEntityCapabilitiesManager().getEntityCapabilities(address); if (showCaps) { // Show any registered entity capabilities. if ( caps != null && (!caps.getIdentities().isEmpty() || !caps.getFeatures().isEmpty())) { %>
<% if ( !caps.getIdentities().isEmpty() ) { // Use a TreeSet to force natural ordering, which makes things easier to read. for (final String identity : new TreeSet<>(caps.getIdentities())) { %> <% } } %> <% // Use a TreeSet to force natural ordering, which makes things easier to read. if ( !caps.getFeatures().isEmpty() ) { for (final String feature : new TreeSet<>(caps.getFeatures())) { %> <% } } %>
: <%= StringUtils.escapeHTMLTags(identity)%>
: <%= StringUtils.escapeHTMLTags(feature)%>
<% } } %> <% // Show a list of multiple user sessions if there is more than 1 session: if (sessionCount > 1) { %>

<% int count = 0; String linkURL = "session-details.jsp"; for (ClientSession sess : sessions) { count++; boolean current = sess.getAddress().equals(address); %> <%@ include file="session-row.jspf" %> <% } %>
  "> ">

  =
<% } %>
<% if (showCaps) { %> "> <% } else if (caps != null && (!caps.getIdentities().isEmpty() || !caps.getFeatures().isEmpty())) { %> "> <% } %> ">