);
@@ -56,7 +81,4 @@ const MalwareReports = createFragmentContainer(MalwareReportsComponent, {
`,
});
-export default compose(
- inject18n,
- withStyles(styles),
-)(MalwareReports);
+export default compose(inject18n, withStyles(styles))(MalwareReports);
diff --git a/opencti-platform/opencti-front/src/private/components/threats/threat_actors/ThreatActorReports.js b/opencti-platform/opencti-front/src/private/components/threats/threat_actors/ThreatActorReports.js
index d94157573c28..b8cc23d3fb74 100644
--- a/opencti-platform/opencti-front/src/private/components/threats/threat_actors/ThreatActorReports.js
+++ b/opencti-platform/opencti-front/src/private/components/threats/threat_actors/ThreatActorReports.js
@@ -10,9 +10,20 @@ import ThreatActorPopover from './ThreatActorPopover';
import Reports from '../../reports/Reports';
import StixDomainEntityHeader from '../../common/stix_domain_entities/StixDomainEntityHeader';
-const styles = () => ({
+const styles = (theme) => ({
container: {
- margin: 0,
+ transition: theme.transitions.create('padding', {
+ easing: theme.transitions.easing.sharp,
+ duration: theme.transitions.duration.leavingScreen,
+ }),
+ },
+ containerWithPadding: {
+ flexGrow: 1,
+ transition: theme.transitions.create('padding', {
+ easing: theme.transitions.easing.easeOut,
+ duration: theme.transitions.duration.enteringScreen,
+ }),
+ paddingRight: 310,
},
paper: {
height: '100%',
@@ -24,16 +35,30 @@ const styles = () => ({
});
class ThreatActorReportsComponent extends Component {
+ constructor(props) {
+ super(props);
+ this.state = { withPadding: false };
+ }
+
render() {
+ const { withPadding } = this.state;
const { classes, threatActor } = this.props;
return (
-
+
}
/>
-
+ this.setState({ withPadding: openExports })
+ }
+ />
);
@@ -59,7 +84,4 @@ const ThreatActorReports = createFragmentContainer(
},
);
-export default compose(
- inject18n,
- withStyles(styles),
-)(ThreatActorReports);
+export default compose(inject18n, withStyles(styles))(ThreatActorReports);
diff --git a/opencti-platform/opencti-front/src/utils/ListParameters.js b/opencti-platform/opencti-front/src/utils/ListParameters.js
index 92ef179ef174..d287570d8075 100644
--- a/opencti-platform/opencti-front/src/utils/ListParameters.js
+++ b/opencti-platform/opencti-front/src/utils/ListParameters.js
@@ -14,6 +14,10 @@ export const saveViewParameters = (
dissoc('observableTypes'),
dissoc('openExports'),
dissoc('numberOfElements'),
+ dissoc('lastSeenStart'),
+ dissoc('lastSeenStop'),
+ dissoc('targetEntityTypes'),
+ dissoc('inferred'),
)(params);
history.replace(
`${location.pathname}?${new URLSearchParams(urlParams).toString()}`,
diff --git a/opencti-platform/opencti-front/src/utils/Localization.js b/opencti-platform/opencti-front/src/utils/Localization.js
index 7da928a03e1f..48643052402a 100644
--- a/opencti-platform/opencti-front/src/utils/Localization.js
+++ b/opencti-platform/opencti-front/src/utils/Localization.js
@@ -438,6 +438,7 @@ const i18n = {
Month: 'Mois',
Year: 'Année',
Role: 'Rôle',
+ Date: 'Date',
'Start date': 'Date de début',
'End date': 'Date de fin',
// Properties
diff --git a/opencti-platform/opencti-front/src/utils/Number.js b/opencti-platform/opencti-front/src/utils/Number.js
index 913edad29032..9d25a7276a6a 100644
--- a/opencti-platform/opencti-front/src/utils/Number.js
+++ b/opencti-platform/opencti-front/src/utils/Number.js
@@ -25,9 +25,9 @@ export const numberFormat = (number, digits = 2) => {
};
};
-export const setNumberOfElements = (prevProps, props, key, callback) => {
- const currentNumberOfElements = pathOr(0, [key, 'pageInfo', 'globalCount'], props.data);
- const prevNumberOfElements = pathOr(0, [key, 'pageInfo', 'globalCount'], prevProps.data);
+export const setNumberOfElements = (prevProps, props, key, callback, propKey = 'data') => {
+ const currentNumberOfElements = pathOr(0, [key, 'pageInfo', 'globalCount'], props[propKey]);
+ const prevNumberOfElements = pathOr(0, [key, 'pageInfo', 'globalCount'], prevProps[propKey]);
if (currentNumberOfElements !== prevNumberOfElements) {
callback(numberFormat(currentNumberOfElements));
}
diff --git a/opencti-platform/opencti-graphql/config/schema/opencti.graphql b/opencti-platform/opencti-graphql/config/schema/opencti.graphql
index df4cb8643936..3e8e853385d6 100644
--- a/opencti-platform/opencti-graphql/config/schema/opencti.graphql
+++ b/opencti-platform/opencti-graphql/config/schema/opencti.graphql
@@ -417,6 +417,11 @@ enum StixDomainEntitiesFilter {
alias
stix_id_key
hasExternalReference
+ knowledgeContains
+ observablesContains
+ tags
+ createdBy
+ indicates
}
input StixDomainEntitiesFiltering {
key: StixDomainEntitiesFilter!
@@ -566,6 +571,11 @@ enum StixRelationsOrdering {
modified
created_at
updated_at
+ toName
+ toValidFrom
+ toValidUntil
+ toPatternType
+ toCreatedAt
}
type StixRelationConnection {
pageInfo: PageInfo!
diff --git a/opencti-platform/opencti-graphql/src/database/grakn.js b/opencti-platform/opencti-graphql/src/database/grakn.js
index bd6da802db1e..4569f0e478e2 100644
--- a/opencti-platform/opencti-graphql/src/database/grakn.js
+++ b/opencti-platform/opencti-graphql/src/database/grakn.js
@@ -68,6 +68,7 @@ const dateFormat = 'YYYY-MM-DDTHH:mm:ss';
const GraknString = 'String';
const GraknDate = 'Date';
+export const REL_CONNECTED_SUFFIX = 'CONNECTED';
export const TYPE_OPENCTI_INTERNAL = 'Internal';
export const TYPE_STIX_DOMAIN = 'Stix-Domain';
export const TYPE_STIX_DOMAIN_ENTITY = 'Stix-Domain-Entity';
@@ -819,9 +820,14 @@ export const listRelations = async (relationType, relationFilter, args) => {
if (isRelationOrderBy) {
const [relation, field] = orderBy.split('.');
const curatedRelation = relation.replace(REL_INDEX_PREFIX, '');
- relationsFields.push(
- `($rel, $${curatedRelation}) isa ${curatedRelation}; $${curatedRelation} has ${field} $order;`
- );
+ if (curatedRelation.includes(REL_CONNECTED_SUFFIX)) {
+ const finalCuratedRelation = curatedRelation.replace(REL_CONNECTED_SUFFIX, '');
+ relationsFields.push(`$${finalCuratedRelation} has ${field} $order;`);
+ } else {
+ relationsFields.push(
+ `($rel, $${curatedRelation}) isa ${curatedRelation}; $${curatedRelation} has ${field} $order;`
+ );
+ }
} else if (orderBy) {
attributesFields.push(`$rel has ${orderBy} $order;`);
}
diff --git a/opencti-platform/opencti-graphql/src/domain/report.js b/opencti-platform/opencti-graphql/src/domain/report.js
index eb7f076883c0..b3e031889a39 100644
--- a/opencti-platform/opencti-graphql/src/domain/report.js
+++ b/opencti-platform/opencti-graphql/src/domain/report.js
@@ -76,7 +76,7 @@ export const observableRefs = (reportId, args) => {
}
return findWithConnectedRelations(
`match $from isa Report; $rel(observables_aggregation:$from, soo:$to) isa observable_refs;
- $to isa ${args.type ? escape(args.type) : 'Stix-Domain-Entity'};
+ $to isa ${args.type ? escape(args.type) : 'Stix-Observable'};
$from has internal_id_key "${escapeString(reportId)}"; get;`,
'to',
'rel'
diff --git a/opencti-platform/opencti-graphql/src/domain/stixDomainEntity.js b/opencti-platform/opencti-graphql/src/domain/stixDomainEntity.js
index fc5d1a146b19..a6222be636ea 100644
--- a/opencti-platform/opencti-graphql/src/domain/stixDomainEntity.js
+++ b/opencti-platform/opencti-graphql/src/domain/stixDomainEntity.js
@@ -1,4 +1,4 @@
-import { assoc, dissoc, map } from 'ramda';
+import { assoc, dissoc, map, propOr, pipe, invertObj } from 'ramda';
import { BUS_TOPICS } from '../config/conf';
import { delEditContext, notify, setEditContext } from '../database/redis';
import {
@@ -22,6 +22,7 @@ import { generateFileExportName, upload } from '../database/minio';
import { connectorsForExport } from './connector';
import { createWork, workToExportFile } from './work';
import { pushToConnector } from '../database/rabbitmq';
+import stixDomainEntityResolvers from '../resolvers/stixDomainEntity';
export const findAll = args => {
const noTypes = !args.types || args.types.length === 0;
@@ -86,6 +87,29 @@ const askJobExports = async (
}));
}, connectors)
);
+ let finalListArgs = listArgs;
+ if (listArgs !== null) {
+ const stixDomainEntitiesFiltersInversed = invertObj(stixDomainEntityResolvers.StixDomainEntitiesFilter);
+ const stixDomainEntitiesOrderingInversed = invertObj(stixDomainEntityResolvers.StixDomainEntitiesOrdering);
+ finalListArgs = pipe(
+ assoc(
+ 'filters',
+ map(
+ n => ({
+ key: n.key in stixDomainEntitiesFiltersInversed ? stixDomainEntitiesFiltersInversed[n.key] : n.key,
+ values: n.values
+ }),
+ propOr([], 'filters', listArgs)
+ )
+ ),
+ assoc(
+ 'orderBy',
+ listArgs.orderBy in stixDomainEntitiesOrderingInversed
+ ? stixDomainEntitiesOrderingInversed[listArgs.orderBy]
+ : listArgs.orderBy
+ )
+ )(listArgs);
+ }
// Send message to all correct connectors queues
await Promise.all(
map(data => {
@@ -97,7 +121,7 @@ const askJobExports = async (
export_type: exportType, // for entity, simple or full / for list, withArgs / withoutArgs
entity_type: entity ? entity.entity_type : type, // report, threat, ...
entity_id: entity ? entity.id : null, // report(id), thread(id), ...
- list_args: listArgs,
+ list_args: finalListArgs,
file_name: work.work_file // Base path for the upload
};
return pushToConnector(connector, message);
diff --git a/opencti-platform/opencti-graphql/src/resolvers/file.js b/opencti-platform/opencti-graphql/src/resolvers/file.js
index a6a0a1da6970..8d5905ad472d 100644
--- a/opencti-platform/opencti-graphql/src/resolvers/file.js
+++ b/opencti-platform/opencti-graphql/src/resolvers/file.js
@@ -4,8 +4,7 @@ import { loadFileWorks } from '../domain/work';
const fileResolvers = {
Query: {
- importFiles: (entity, { first }) => filesListing(first, 'import'),
-
+ importFiles: (entity, { first }) => filesListing(first, 'import')
},
File: {
works: file => loadFileWorks(file.id)
diff --git a/opencti-platform/opencti-graphql/src/resolvers/stixDomainEntity.js b/opencti-platform/opencti-graphql/src/resolvers/stixDomainEntity.js
index d179e688a3f6..aef20a21f7d2 100644
--- a/opencti-platform/opencti-graphql/src/resolvers/stixDomainEntity.js
+++ b/opencti-platform/opencti-graphql/src/resolvers/stixDomainEntity.js
@@ -36,7 +36,12 @@ const stixDomainEntityResolvers = {
tags: `${REL_INDEX_PREFIX}tagged.value`
},
StixDomainEntitiesFilter: {
- hasExternalReference: `${REL_INDEX_PREFIX}external_references.internal_id_key`
+ tags: `${REL_INDEX_PREFIX}tagged.internal_id_key`,
+ createdBy: `${REL_INDEX_PREFIX}created_by_ref.internal_id_key`,
+ knowledgeContains: `${REL_INDEX_PREFIX}object_refs.internal_id_key`,
+ observablesContains: `${REL_INDEX_PREFIX}observable_refs.internal_id_key`,
+ hasExternalReference: `${REL_INDEX_PREFIX}external_references.internal_id_key`,
+ indicates: `${REL_INDEX_PREFIX}indicates.internal_id_key`
},
StixDomainEntity: {
// eslint-disable-next-line no-underscore-dangle
@@ -64,7 +69,8 @@ const stixDomainEntityResolvers = {
}),
stixDomainEntityAdd: (_, { input }, { user }) => addStixDomainEntity(user, input),
stixDomainEntitiesExportAsk: (_, args) => stixDomainEntityExportAsk(args),
- stixDomainEntitiesExportPush: (_, { type, file, listArgs }, { user }) => stixDomainEntityExportPush(user, type, null, file, listArgs)
+ stixDomainEntitiesExportPush: (_, { type, file, listArgs }, { user }) =>
+ stixDomainEntityExportPush(user, type, null, file, listArgs)
},
Subscription: {
stixDomainEntity: {
diff --git a/opencti-platform/opencti-graphql/src/resolvers/stixRelation.js b/opencti-platform/opencti-graphql/src/resolvers/stixRelation.js
index 3113bff76246..8a0d1ed83b96 100644
--- a/opencti-platform/opencti-graphql/src/resolvers/stixRelation.js
+++ b/opencti-platform/opencti-graphql/src/resolvers/stixRelation.js
@@ -15,7 +15,8 @@ import {
import { pubsub } from '../database/redis';
import withCancel from '../graphql/subscriptionWrapper';
import { killChainPhases } from '../domain/stixEntity';
-import { distributionRelations, loadByGraknId, timeSeriesRelations } from '../database/grakn';
+import { distributionRelations, loadByGraknId, timeSeriesRelations, REL_CONNECTED_SUFFIX } from '../database/grakn';
+import { REL_INDEX_PREFIX } from '../database/elasticSearch';
const stixRelationResolvers = {
Query: {
@@ -25,6 +26,13 @@ const stixRelationResolvers = {
stixRelationsDistribution: async (_, args) => distributionRelations(args),
stixRelationsNumber: (_, args) => stixRelationsNumber(args)
},
+ StixRelationsOrdering: {
+ toName: `${REL_INDEX_PREFIX}${REL_CONNECTED_SUFFIX}to.name`,
+ toValidFrom: `${REL_INDEX_PREFIX}${REL_CONNECTED_SUFFIX}to.valid_from`,
+ toValidUntil: `${REL_INDEX_PREFIX}${REL_CONNECTED_SUFFIX}to.valid_until`,
+ toPatternType: `${REL_INDEX_PREFIX}${REL_CONNECTED_SUFFIX}to.pattern_type`,
+ toCreatedAt: `${REL_INDEX_PREFIX}${REL_CONNECTED_SUFFIX}to.created_at`
+ },
StixRelation: {
killChainPhases: rel => killChainPhases(rel.id),
from: rel => loadByGraknId(rel.fromId),