diff --git a/addOns/wappalyzer/CHANGELOG.md b/addOns/wappalyzer/CHANGELOG.md index 361646fb04d..8c073e6488d 100644 --- a/addOns/wappalyzer/CHANGELOG.md +++ b/addOns/wappalyzer/CHANGELOG.md @@ -8,6 +8,9 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/). ### Fixed - Icon sizing in the Technology table when a transparent placeholder needs to be used. +### Changed +- The Tech Detection panel toolbar now includes a toggle button to link it's displayed content to the Sites Tree selection. + ## [21.48.0] - 2025-09-02 ### Changed - Updated with enthec upstream icon and pattern changes. diff --git a/addOns/wappalyzer/src/main/java/org/zaproxy/zap/extension/wappalyzer/ExtensionWappalyzer.java b/addOns/wappalyzer/src/main/java/org/zaproxy/zap/extension/wappalyzer/ExtensionWappalyzer.java index 1e6115a345f..30b54cfc272 100644 --- a/addOns/wappalyzer/src/main/java/org/zaproxy/zap/extension/wappalyzer/ExtensionWappalyzer.java +++ b/addOns/wappalyzer/src/main/java/org/zaproxy/zap/extension/wappalyzer/ExtensionWappalyzer.java @@ -56,14 +56,9 @@ import org.zaproxy.zap.extension.search.ExtensionSearch; import org.zaproxy.zap.utils.ThreadUtils; import org.zaproxy.zap.view.ScanPanel; -import org.zaproxy.zap.view.SiteMapListener; -import org.zaproxy.zap.view.SiteMapTreeCellRenderer; public class ExtensionWappalyzer extends ExtensionAdaptor - implements SessionChangedListener, - SiteMapListener, - ApplicationHolder, - ExampleAlertProvider { + implements SessionChangedListener, ApplicationHolder, ExampleAlertProvider { public static final String NAME = "ExtensionWappalyzer"; @@ -175,7 +170,6 @@ public void hook(ExtensionHook extensionHook) { super.hook(extensionHook); extensionHook.addSessionListener(this); - extensionHook.addSiteMapListener(this); if (hasView()) { @SuppressWarnings("unused") @@ -183,6 +177,8 @@ public void hook(ExtensionHook extensionHook) { extensionHook.getHookView().addStatusPanel(getTechPanel()); extensionHook.getHookMenu().addPopupMenuItem(this.getPopupMenuEvidence()); extensionHook.getHookView().addOptionPanel(new TechOptionsPanel()); + + extensionHook.addSiteMapListener(getTechPanel()); } extensionHook.addApiImplementor(new TechApi(this)); @@ -365,16 +361,6 @@ public void search(Pattern p, ExtensionSearch.Type type) { } } - @Override - public void nodeSelected(SiteNode node) { - // Event from SiteMapListenner - this.getTechPanel().siteSelected(normalizeSite(node.getHistoryReference().getURI())); - } - - @Override - public void onReturnNodeRendererComponent( - SiteMapTreeCellRenderer arg0, boolean arg1, SiteNode arg2) {} - @Override public void sessionAboutToChange(Session arg0) { // Ignore diff --git a/addOns/wappalyzer/src/main/java/org/zaproxy/zap/extension/wappalyzer/TechPanel.java b/addOns/wappalyzer/src/main/java/org/zaproxy/zap/extension/wappalyzer/TechPanel.java index 1e1ed896a42..ed66fac2c94 100644 --- a/addOns/wappalyzer/src/main/java/org/zaproxy/zap/extension/wappalyzer/TechPanel.java +++ b/addOns/wappalyzer/src/main/java/org/zaproxy/zap/extension/wappalyzer/TechPanel.java @@ -39,6 +39,7 @@ import javax.swing.JLabel; import javax.swing.JPanel; import javax.swing.JScrollPane; +import javax.swing.JToggleButton; import javax.swing.JToolBar; import javax.swing.SwingConstants; import javax.swing.SwingUtilities; @@ -50,14 +51,17 @@ import org.parosproxy.paros.Constant; import org.parosproxy.paros.control.Control; import org.parosproxy.paros.extension.AbstractPanel; +import org.parosproxy.paros.model.SiteNode; import org.parosproxy.paros.view.View; import org.zaproxy.zap.utils.DisplayUtils; import org.zaproxy.zap.utils.SortedComboBoxModel; import org.zaproxy.zap.utils.TableExportButton; +import org.zaproxy.zap.view.SiteMapListener; +import org.zaproxy.zap.view.SiteMapTreeCellRenderer; import org.zaproxy.zap.view.ZapToggleButton; @SuppressWarnings("serial") -public class TechPanel extends AbstractPanel { +public class TechPanel extends AbstractPanel implements SiteMapListener { private static final long serialVersionUID = 1L; @@ -76,9 +80,12 @@ public class TechPanel extends AbstractPanel { private TechTableModel techModel = new TechTableModel(); private TableExportButton exportButton = null; + private ZapToggleButton linkWithSitesTreeButton = null; private ZapToggleButton enableButton = null; private JButton optionsButton; + private boolean linkWithSitesTreeSelection; + private static final Icon TRANSPARENT_ICON = new Icon() { @@ -167,6 +174,7 @@ private JToolBar getPanelToolbar() { panelToolbar.add( new JLabel(Constant.messages.getString("wappalyzer.toolbar.site.label"))); panelToolbar.add(getSiteSelect()); + panelToolbar.add(getLinkWithSitesTreeButton()); panelToolbar.add(getExportButton()); panelToolbar.add(getEnableToggleButton()); @@ -386,4 +394,44 @@ private JButton getOptionsButton() { } return optionsButton; } + + private JToggleButton getLinkWithSitesTreeButton() { + if (linkWithSitesTreeButton == null) { + linkWithSitesTreeButton = new ZapToggleButton(); + linkWithSitesTreeButton.setIcon( + new ImageIcon( + TechPanel.class.getResource( + ExtensionWappalyzer.RESOURCE + "/earth-grey.png"))); + linkWithSitesTreeButton.setToolTipText( + Constant.messages.getString( + "wappalyzer.toolbar.toggle.site.link.disabled.tooltip")); + linkWithSitesTreeButton.setSelectedIcon( + new ImageIcon( + TechPanel.class.getResource( + ExtensionWappalyzer.RESOURCE + "/earth-colour.png"))); + linkWithSitesTreeButton.setSelectedToolTipText( + Constant.messages.getString( + "wappalyzer.toolbar.toggle.site.link.enabled.tooltip")); + DisplayUtils.scaleIcon(linkWithSitesTreeButton); + + linkWithSitesTreeButton.addActionListener( + e -> linkWithSitesTreeSelection = linkWithSitesTreeButton.isSelected()); + linkWithSitesTreeButton.setSelected(true); + } + return linkWithSitesTreeButton; + } + + @Override + public void nodeSelected(SiteNode node) { + // Event from SiteMapListenner + if (linkWithSitesTreeSelection) { + siteSelected(ExtensionWappalyzer.normalizeSite(node.getHistoryReference().getURI())); + } + } + + @Override + public void onReturnNodeRendererComponent( + SiteMapTreeCellRenderer component, boolean leaf, SiteNode value) { + // Nothing to do + } } diff --git a/addOns/wappalyzer/src/main/javahelp/org/zaproxy/zap/extension/wappalyzer/resources/help/contents/wappalyzer.html b/addOns/wappalyzer/src/main/javahelp/org/zaproxy/zap/extension/wappalyzer/resources/help/contents/wappalyzer.html index 0442f4d8d66..a5a061362bc 100644 --- a/addOns/wappalyzer/src/main/javahelp/org/zaproxy/zap/extension/wappalyzer/resources/help/contents/wappalyzer.html +++ b/addOns/wappalyzer/src/main/javahelp/org/zaproxy/zap/extension/wappalyzer/resources/help/contents/wappalyzer.html @@ -22,13 +22,16 @@

The Technology Tab

Selecting a regex will switch to the 'Search' tab and search through the history for that regex. Note: If multiple rows are selected the menu will not be displayed.

-Beside the site selection drop down is an Export button which can be used to export a CSV (comma separated values) file based on the +Beside the site selection drop down is a button (with a Globe icon) which controls whether or not the Technology tab's display is linked to the selection in the Sites Tree. +

+Next is an Export button which can be used to export a CSV (comma separated values) file based on the table information currently being displayed.

The toolbar also includes: