"use strict";
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.Ja3FingerprintLink = exports.HostDetailsLink = exports.GoogleLink = exports.ExternalLink = exports.DEFAULT_NUMBER_OF_LINK = exports.DEFAULT_MORE_MAX_HEIGHT = exports.CreateCaseLink = exports.CertificateFingerprintLink = exports.CaseDetailsLink = void 0;
Object.defineProperty(exports, "LinkAnchor", {
enumerable: true,
get: function () {
return _helpers2.LinkAnchor;
}
});
Object.defineProperty(exports, "LinkButton", {
enumerable: true,
get: function () {
return _helpers2.LinkButton;
}
});
exports.WhoIsLink = exports.UserDetailsLink = exports.SecuritySolutionLinkButton = exports.SecuritySolutionLinkAnchor = exports.ReputationLink = exports.PortOrServiceNameLink = exports.NetworkDetailsLink = void 0;
Object.defineProperty(exports, "useGetSecuritySolutionLinkProps", {
enumerable: true,
get: function () {
return _link_props.useGetSecuritySolutionLinkProps;
}
});
Object.defineProperty(exports, "useSecuritySolutionLinkProps", {
enumerable: true,
get: function () {
return _link_props.useSecuritySolutionLinkProps;
}
});
Object.defineProperty(exports, "withSecuritySolutionLink", {
enumerable: true,
get: function () {
return _link_props.withSecuritySolutionLink;
}
});
var _eui = require("@elastic/eui");
var _react = _interopRequireWildcard(require("react"));
var _fp = require("lodash/fp");
var _tour_step = require("../guided_onboarding_tour/tour_step");
var _tour_config = require("../guided_onboarding_tour/tour_config");
var _guided_onboarding_tour = require("../guided_onboarding_tour");
var _constants = require("../../../../common/constants");
var _helpers = require("../../lib/helpers");
var _link_to = require("../link_to");
var _network = require("../../../../common/search_strategy/security_solution/network");
var _kibana = require("../../lib/kibana");
var _validators = require("../../utils/validators");
var i18n = _interopRequireWildcard(require("./translations"));
var _types = require("../../../app/types");
var _redirect_to_users = require("../link_to/redirect_to_users");
var _helpers2 = require("./helpers");
var _link_props = require("./link_props");
function _getRequireWildcardCache(nodeInterop) { if (typeof WeakMap !== "function") return null; var cacheBabelInterop = new WeakMap(); var cacheNodeInterop = new WeakMap(); return (_getRequireWildcardCache = function (nodeInterop) { return nodeInterop ? cacheNodeInterop : cacheBabelInterop; })(nodeInterop); }
function _interopRequireWildcard(obj, nodeInterop) { if (!nodeInterop && obj && obj.__esModule) { return obj; } if (obj === null || typeof obj !== "object" && typeof obj !== "function") { return { default: obj }; } var cache = _getRequireWildcardCache(nodeInterop); if (cache && cache.has(obj)) { return cache.get(obj); } var newObj = {}; var hasPropertyDescriptor = Object.defineProperty && Object.getOwnPropertyDescriptor; for (var key in obj) { if (key !== "default" && Object.prototype.hasOwnProperty.call(obj, key)) { var desc = hasPropertyDescriptor ? Object.getOwnPropertyDescriptor(obj, key) : null; if (desc && (desc.get || desc.set)) { Object.defineProperty(newObj, key, desc); } else { newObj[key] = obj[key]; } } } newObj.default = obj; if (cache) { cache.set(obj, newObj); } return newObj; }
/*
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
* or more contributor license agreements. Licensed under the Elastic License
* 2.0; you may not use this file except in compliance with the Elastic License
* 2.0.
*/
const DEFAULT_NUMBER_OF_LINK = 5;
/** The default max-height of the Reputation Links popover used to show "+n More" items (e.g. `+9 More`) */
exports.DEFAULT_NUMBER_OF_LINK = DEFAULT_NUMBER_OF_LINK;
const DEFAULT_MORE_MAX_HEIGHT = '200px';
// Internal Links
exports.DEFAULT_MORE_MAX_HEIGHT = DEFAULT_MORE_MAX_HEIGHT;
const UserDetailsLinkComponent = ({
children,
Component,
userName,
isButton,
onClick: onClickParam,
title,
userTab
}) => {
const encodedUserName = encodeURIComponent(userName);
const {
formatUrl,
search
} = (0, _link_to.useFormatUrl)(_types.SecurityPageName.users);
const {
application: {
navigateToApp
},
telemetry
} = (0, _kibana.useKibana)().services;
const goToUsersDetails = (0, _react.useCallback)(ev => {
ev.preventDefault();
navigateToApp(_constants.APP_UI_ID, {
deepLinkId: _types.SecurityPageName.users,
path: userTab ? (0, _redirect_to_users.getTabsOnUsersDetailsUrl)(encodedUserName, userTab, search) : (0, _redirect_to_users.getUsersDetailsUrl)(encodedUserName, search)
});
}, [encodedUserName, navigateToApp, search, userTab]);
const href = (0, _react.useMemo)(() => formatUrl(userTab ? (0, _redirect_to_users.getTabsOnUsersDetailsUrl)(encodedUserName, userTab) : (0, _redirect_to_users.getUsersDetailsUrl)(encodedUserName)), [formatUrl, encodedUserName, userTab]);
const onClick = (0, _react.useCallback)(e => {
telemetry.reportEntityDetailsClicked({
entity: 'user'
});
const callback = onClickParam !== null && onClickParam !== void 0 ? onClickParam : goToUsersDetails;
callback(e);
}, [goToUsersDetails, onClickParam, telemetry]);
return isButton ? /*#__PURE__*/_react.default.createElement(_helpers2.GenericLinkButton, {
Component: Component,
dataTestSubj: "data-grid-user-details",
href: href,
onClick: onClick,
title: title !== null && title !== void 0 ? title : userName
}, children ? children : userName) : /*#__PURE__*/_react.default.createElement(_helpers2.LinkAnchor, {
"data-test-subj": "users-link-anchor",
onClick: onClick,
href: href
}, children ? children : userName);
};
const UserDetailsLink = /*#__PURE__*/_react.default.memo(UserDetailsLinkComponent);
exports.UserDetailsLink = UserDetailsLink;
const HostDetailsLinkComponent = ({
children,
Component,
hostName,
isButton,
onClick: onClickParam,
title,
hostTab
}) => {
const {
formatUrl,
search
} = (0, _link_to.useFormatUrl)(_types.SecurityPageName.hosts);
const {
application: {
navigateToApp
},
telemetry
} = (0, _kibana.useKibana)().services;
const encodedHostName = encodeURIComponent(hostName);
const goToHostDetails = (0, _react.useCallback)(ev => {
ev.preventDefault();
navigateToApp(_constants.APP_UI_ID, {
deepLinkId: _types.SecurityPageName.hosts,
path: hostTab ? (0, _link_to.getTabsOnHostDetailsUrl)(encodedHostName, hostTab, search) : (0, _link_to.getHostDetailsUrl)(encodedHostName, search)
});
}, [encodedHostName, navigateToApp, search, hostTab]);
const href = (0, _react.useMemo)(() => formatUrl(hostTab ? (0, _link_to.getTabsOnHostDetailsUrl)(encodedHostName, hostTab) : (0, _link_to.getHostDetailsUrl)(encodedHostName)), [formatUrl, encodedHostName, hostTab]);
const onClick = (0, _react.useCallback)(e => {
telemetry.reportEntityDetailsClicked({
entity: 'host'
});
const callback = onClickParam !== null && onClickParam !== void 0 ? onClickParam : goToHostDetails;
callback(e);
}, [goToHostDetails, onClickParam, telemetry]);
return isButton ? /*#__PURE__*/_react.default.createElement(_helpers2.GenericLinkButton, {
Component: Component,
dataTestSubj: "data-grid-host-details",
href: href,
iconType: "expand",
onClick: onClick,
title: title !== null && title !== void 0 ? title : hostName
}, children) : /*#__PURE__*/_react.default.createElement(_helpers2.LinkAnchor, {
onClick: onClick,
href: href,
"data-test-subj": "host-details-button"
}, children ? children : hostName);
};
const HostDetailsLink = /*#__PURE__*/_react.default.memo(HostDetailsLinkComponent);
exports.HostDetailsLink = HostDetailsLink;
const allowedUrlSchemes = ['http://', 'https://'];
const ExternalLink = /*#__PURE__*/_react.default.memo(({
url,
children,
idx,
overflowIndexStart = DEFAULT_NUMBER_OF_LINK,
allItemsLimit = DEFAULT_NUMBER_OF_LINK
}) => {
const lastVisibleItemIndex = overflowIndexStart - 1;
const lastItemIndex = allItemsLimit - 1;
const lastIndexToShow = Math.max(0, Math.min(lastVisibleItemIndex, lastItemIndex));
const inAllowlist = allowedUrlSchemes.some(scheme => url.indexOf(scheme) === 0);
return url && inAllowlist && !(0, _validators.isUrlInvalid)(url) && children ? /*#__PURE__*/_react.default.createElement(_eui.EuiToolTip, {
content: url,
position: "top",
"data-test-subj": "externalLinkTooltip"
}, /*#__PURE__*/_react.default.createElement(_react.default.Fragment, null, /*#__PURE__*/_react.default.createElement(_eui.EuiLink, {
href: url,
target: "_blank",
rel: "noopener",
"data-test-subj": "externalLink"
}, children), !(0, _fp.isNil)(idx) && idx < lastIndexToShow && /*#__PURE__*/_react.default.createElement(_helpers2.Comma, {
"data-test-subj": "externalLinkComma"
}))) : null;
});
exports.ExternalLink = ExternalLink;
ExternalLink.displayName = 'ExternalLink';
const NetworkDetailsLinkComponent = ({
Component,
children,
ip,
flowTarget = _network.FlowTarget.source,
isButton,
onClick,
title
}) => {
const getSecuritySolutionLinkProps = (0, _link_props.useGetSecuritySolutionLinkProps)();
const getLink = (0, _react.useCallback)((cIp, i) => {
const {
onClick: onClickNavigation,
href
} = getSecuritySolutionLinkProps({
deepLinkId: _types.SecurityPageName.network,
path: (0, _link_to.getNetworkDetailsUrl)(encodeURIComponent((0, _helpers.encodeIpv6)(cIp)), flowTarget)
});
const onLinkClick = onClick !== null && onClick !== void 0 ? onClick : e => onClickNavigation(e);
return isButton ? /*#__PURE__*/_react.default.createElement(_helpers2.GenericLinkButton, {
Component: Component,
key: `${cIp}-${i}`,
dataTestSubj: "data-grid-network-details",
onClick: onLinkClick,
href: href,
title: title !== null && title !== void 0 ? title : cIp
}, children) : /*#__PURE__*/_react.default.createElement(_helpers2.LinkAnchor, {
key: `${cIp}-${i}`,
onClick: onLinkClick,
href: href,
"data-test-subj": "network-details"
}, children ? children : cIp);
}, [children, Component, flowTarget, getSecuritySolutionLinkProps, onClick, isButton, title]);
return (0, _fp.isArray)(ip) ? /*#__PURE__*/_react.default.createElement(_react.default.Fragment, null, ip.map(getLink)) : getLink(ip, 0);
};
const NetworkDetailsLink = /*#__PURE__*/_react.default.memo(NetworkDetailsLinkComponent);
exports.NetworkDetailsLink = NetworkDetailsLink;
const CaseDetailsLinkComponent = ({
index,
children,
detailName,
title
}) => {
const {
formatUrl,
search
} = (0, _link_to.useFormatUrl)(_types.SecurityPageName.case);
const {
navigateToApp
} = (0, _kibana.useKibana)().services.application;
const {
activeStep,
isTourShown
} = (0, _guided_onboarding_tour.useTourContext)();
const isTourStepActive = (0, _react.useMemo)(() => activeStep === _tour_config.AlertsCasesTourSteps.viewCase && isTourShown(_tour_config.SecurityStepId.alertsCases) && index === 0, [activeStep, index, isTourShown]);
const goToCaseDetails = (0, _react.useCallback)(async ev => {
if (ev) ev.preventDefault();
return navigateToApp(_constants.APP_UI_ID, {
deepLinkId: _types.SecurityPageName.case,
path: (0, _link_to.getCaseDetailsUrl)({
id: detailName,
search
})
});
}, [detailName, navigateToApp, search]);
(0, _react.useEffect)(() => {
var _document$querySelect;
if (isTourStepActive) (_document$querySelect = document.querySelector(`[tour-step="RelatedCases-accordion"]`)) === null || _document$querySelect === void 0 ? void 0 : _document$querySelect.scrollIntoView();
}, [isTourStepActive]);
return /*#__PURE__*/_react.default.createElement(_tour_step.GuidedOnboardingTourStep, {
onClick: goToCaseDetails,
isTourAnchor: isTourStepActive,
step: _tour_config.AlertsCasesTourSteps.viewCase,
tourId: _tour_config.SecurityStepId.alertsCases
}, /*#__PURE__*/_react.default.createElement(_helpers2.LinkAnchor, {
onClick: goToCaseDetails,
href: formatUrl((0, _link_to.getCaseDetailsUrl)({
id: detailName
})),
"data-test-subj": "case-details-link",
"aria-label": i18n.CASE_DETAILS_LINK_ARIA(title !== null && title !== void 0 ? title : detailName)
}, children ? children : detailName));
};
const CaseDetailsLink = /*#__PURE__*/_react.default.memo(CaseDetailsLinkComponent);
exports.CaseDetailsLink = CaseDetailsLink;
CaseDetailsLink.displayName = 'CaseDetailsLink';
const CreateCaseLink = /*#__PURE__*/_react.default.memo(({
children
}) => {
const {
formatUrl,
search
} = (0, _link_to.useFormatUrl)(_types.SecurityPageName.case);
const {
navigateToApp
} = (0, _kibana.useKibana)().services.application;
const goToCreateCase = (0, _react.useCallback)(async ev => {
ev.preventDefault();
return navigateToApp(_constants.APP_UI_ID, {
deepLinkId: _types.SecurityPageName.case,
path: (0, _link_to.getCreateCaseUrl)(search)
});
}, [navigateToApp, search]);
return /*#__PURE__*/_react.default.createElement(_helpers2.LinkAnchor, {
onClick: goToCreateCase,
href: formatUrl((0, _link_to.getCreateCaseUrl)())
}, children);
});
exports.CreateCaseLink = CreateCaseLink;
CreateCaseLink.displayName = 'CreateCaseLink';
// External Links
const GoogleLink = /*#__PURE__*/_react.default.memo(({
children,
link
}) => {
const url = (0, _react.useMemo)(() => `https://www.google.com/search?q=${encodeURIComponent(link)}`, [link]);
return /*#__PURE__*/_react.default.createElement(ExternalLink, {
url: url
}, children ? children : link);
});
exports.GoogleLink = GoogleLink;
GoogleLink.displayName = 'GoogleLink';
const PortOrServiceNameLink = /*#__PURE__*/_react.default.memo(({
Component,
title,
children,
portOrServiceName
}) => {
var _ref;
const href = (0, _react.useMemo)(() => `https://www.iana.org/assignments/service-names-port-numbers/service-names-port-numbers.xhtml?search=${encodeURIComponent(String(portOrServiceName))}`, [portOrServiceName]);
return Component ? /*#__PURE__*/_react.default.createElement(Component, {
href: href,
"data-test-subj": "data-grid-port-or-service-name-link",
title: title,
iconType: "link"
}, (_ref = title !== null && title !== void 0 ? title : children) !== null && _ref !== void 0 ? _ref : portOrServiceName) : /*#__PURE__*/_react.default.createElement(_helpers2.PortContainer, null, /*#__PURE__*/_react.default.createElement(_eui.EuiLink, {
"data-test-subj": "port-or-service-name-link",
href: href,
target: "_blank"
}, children ? children : portOrServiceName));
});
exports.PortOrServiceNameLink = PortOrServiceNameLink;
PortOrServiceNameLink.displayName = 'PortOrServiceNameLink';
const Ja3FingerprintLink = /*#__PURE__*/_react.default.memo(({
children,
ja3Fingerprint
}) => {
const href = (0, _react.useMemo)(() => `https://sslbl.abuse.ch/ja3-fingerprints/${encodeURIComponent(ja3Fingerprint)}`, [ja3Fingerprint]);
return /*#__PURE__*/_react.default.createElement(_eui.EuiLink, {
"data-test-subj": "ja3-fingerprint-link",
href: href,
target: "_blank"
}, children ? children : ja3Fingerprint);
});
exports.Ja3FingerprintLink = Ja3FingerprintLink;
Ja3FingerprintLink.displayName = 'Ja3FingerprintLink';
const CertificateFingerprintLink = /*#__PURE__*/_react.default.memo(({
children,
certificateFingerprint
}) => {
const href = (0, _react.useMemo)(() => `https://sslbl.abuse.ch/ssl-certificates/sha1/${encodeURIComponent(certificateFingerprint)}`, [certificateFingerprint]);
return /*#__PURE__*/_react.default.createElement(_eui.EuiLink, {
"data-test-subj": "certificate-fingerprint-link",
href: href,
target: "_blank"
}, children ? children : certificateFingerprint);
});
exports.CertificateFingerprintLink = CertificateFingerprintLink;
CertificateFingerprintLink.displayName = 'CertificateFingerprintLink';
var DefaultReputationLink;
(function (DefaultReputationLink) {
DefaultReputationLink["virustotal.com"] = "virustotal.com";
DefaultReputationLink["talosIntelligence.com"] = "talosIntelligence.com";
})(DefaultReputationLink || (DefaultReputationLink = {}));
function isDefaultReputationLink(name) {
return name === DefaultReputationLink['virustotal.com'] || name === DefaultReputationLink['talosIntelligence.com'];
}
const isReputationLink = rowItem => rowItem.url_template !== undefined && rowItem.name !== undefined;
const defaultNameMapping = {
[DefaultReputationLink['virustotal.com']]: i18n.VIEW_VIRUS_TOTAL,
[DefaultReputationLink['talosIntelligence.com']]: i18n.VIEW_TALOS_INTELLIGENCE
};
const ReputationLinkComponent = ({
overflowIndexStart = DEFAULT_NUMBER_OF_LINK,
allItemsLimit = DEFAULT_NUMBER_OF_LINK,
showDomain = false,
domain,
direction = 'row'
}) => {
const [ipReputationLinksSetting] = (0, _kibana.useUiSetting$)(_constants.IP_REPUTATION_LINKS_SETTING);
const ipReputationLinks = (0, _react.useMemo)(() => ipReputationLinksSetting === null || ipReputationLinksSetting === void 0 ? void 0 : ipReputationLinksSetting.slice(0, allItemsLimit).filter(
// eslint-disable-next-line @typescript-eslint/naming-convention
({
url_template,
name
}) => !(0, _fp.isNil)(url_template) && !(0, _fp.isNil)(name) && !(0, _validators.isUrlInvalid)(url_template))
// eslint-disable-next-line @typescript-eslint/naming-convention
.map(({
name,
url_template
}) => ({
name: isDefaultReputationLink(name) ? defaultNameMapping[name] : name,
url_template: url_template.replace(`{{ip}}`, encodeURIComponent(domain))
})),
// eslint-disable-next-line react-hooks/exhaustive-deps
[ipReputationLinksSetting, domain, defaultNameMapping, allItemsLimit]);
const renderCallback = (0, _react.useCallback)(rowItem => {
var _rowItem$name;
return isReputationLink(rowItem) && /*#__PURE__*/_react.default.createElement(ExternalLink, {
url: rowItem.url_template,
overflowIndexStart: overflowIndexStart,
allItemsLimit: allItemsLimit
}, /*#__PURE__*/_react.default.createElement(_react.default.Fragment, null, (_rowItem$name = rowItem.name) !== null && _rowItem$name !== void 0 ? _rowItem$name : domain));
}, [allItemsLimit, domain, overflowIndexStart]);
return (ipReputationLinks === null || ipReputationLinks === void 0 ? void 0 : ipReputationLinks.length) > 0 ? /*#__PURE__*/_react.default.createElement("section", null, /*#__PURE__*/_react.default.createElement(_eui.EuiFlexGroup, {
gutterSize: "none",
justifyContent: "center",
direction: direction,
alignItems: "center",
"data-test-subj": "reputationLinkGroup"
}, /*#__PURE__*/_react.default.createElement(_eui.EuiFlexItem, {
grow: true
}, ipReputationLinks === null || ipReputationLinks === void 0 ? void 0 : ipReputationLinks.slice(0, overflowIndexStart).map(({
name,
url_template: urlTemplate
}, id) => /*#__PURE__*/_react.default.createElement(ExternalLink, {
allItemsLimit: ipReputationLinks.length,
idx: id,
overflowIndexStart: overflowIndexStart,
url: urlTemplate,
"data-test-subj": "externalLinkComponent",
key: `reputationLink-${id}`
}, /*#__PURE__*/_react.default.createElement(_react.default.Fragment, null, showDomain ? domain : name !== null && name !== void 0 ? name : domain)))), /*#__PURE__*/_react.default.createElement(_eui.EuiFlexItem, {
grow: false
}, /*#__PURE__*/_react.default.createElement(_helpers2.ReputationLinksOverflow, {
rowItems: ipReputationLinks,
render: renderCallback,
moreMaxHeight: DEFAULT_MORE_MAX_HEIGHT,
overflowIndexStart: overflowIndexStart
})))) : null;
};
ReputationLinkComponent.displayName = 'ReputationLinkComponent';
const ReputationLink = /*#__PURE__*/_react.default.memo(ReputationLinkComponent);
exports.ReputationLink = ReputationLink;
const WhoIsLink = /*#__PURE__*/_react.default.memo(({
children,
domain
}) => {
const url = (0, _react.useMemo)(() => `https://www.iana.org/whois?q=${encodeURIComponent(domain)}`, [domain]);
return /*#__PURE__*/_react.default.createElement(ExternalLink, {
url: url
}, children ? children : domain);
});
exports.WhoIsLink = WhoIsLink;
WhoIsLink.displayName = 'WhoIsLink';
/**
* Security Solutions internal link button.
*
* `;`
*/
const SecuritySolutionLinkButton = (0, _link_props.withSecuritySolutionLink)(_helpers2.LinkButton);
/**
* Security Solutions internal link anchor.
*
* `;`
*/
exports.SecuritySolutionLinkButton = SecuritySolutionLinkButton;
const SecuritySolutionLinkAnchor = (0, _link_props.withSecuritySolutionLink)(_helpers2.LinkAnchor);
exports.SecuritySolutionLinkAnchor = SecuritySolutionLinkAnchor;