diff --git a/x-pack/plugins/cases/server/common/types/attachments.ts b/x-pack/plugins/cases/server/common/types/attachments.ts index 7ed93908d77c7..0e2d84c425848 100644 --- a/x-pack/plugins/cases/server/common/types/attachments.ts +++ b/x-pack/plugins/cases/server/common/types/attachments.ts @@ -21,9 +21,18 @@ export interface AttachmentRequestAttributes { type: string; alertId?: string | string[]; index?: string | string[]; - rule?: Record; + rule?: { + id: string | null; + name: string | null; + }; comment?: string; - actions?: Record; + actions?: { + targets: Array<{ + hostname: string; + endpointId: string; + }>; + type: string; + }; externalReferenceMetadata?: Record | null; externalReferenceAttachmentTypeId?: string; externalReferenceStorage?: { @@ -31,6 +40,7 @@ export interface AttachmentRequestAttributes { soType?: string; }; persistableStateAttachmentState?: Record; + persistableStateAttachmentTypeId?: string; } export type AttachmentPersistedAttributes = AttachmentRequestAttributes & diff --git a/x-pack/plugins/cases/server/common/utils.ts b/x-pack/plugins/cases/server/common/utils.ts index e4d1396526650..b04c9fd596503 100644 --- a/x-pack/plugins/cases/server/common/utils.ts +++ b/x-pack/plugins/cases/server/common/utils.ts @@ -34,7 +34,6 @@ import type { CommentRequest, CommentRequestActionsType, CommentRequestAlertType, - CommentRequestExternalReferenceSOType, CommentRequestUserType, CommentResponse, CommentsResponse, @@ -45,7 +44,6 @@ import { CaseStatuses, CommentType, ConnectorTypes, - ExternalReferenceStorageType, ExternalReferenceSORt, FileAttachmentMetadataRt, } from '../../common/api'; @@ -55,7 +53,6 @@ import { getLensVisualizations, } from '../../common/utils/markdown_plugins/utils'; import { dedupAssignees } from '../client/cases/utils'; -import type { AttachmentRequestAttributes } from './types/attachments'; import type { CaseSavedObjectTransformed, CaseTransformedAttributes } from './types/case'; /** @@ -255,18 +252,6 @@ export const isCommentRequestTypeAlert = ( return context.type === CommentType.alert; }; -/** - * A type narrowing function for external reference so attachments. - */ -export const isCommentRequestTypeExternalReferenceSO = ( - context: Partial -): context is CommentRequestExternalReferenceSOType => { - return ( - context.type === CommentType.externalReference && - context.externalReferenceStorage?.type === ExternalReferenceStorageType.savedObject - ); -}; - /** * A type narrowing function for file attachments. */ diff --git a/x-pack/plugins/cases/server/services/attachments/index.ts b/x-pack/plugins/cases/server/services/attachments/index.ts index 183db25fd78f9..e76b93ce0e5b9 100644 --- a/x-pack/plugins/cases/server/services/attachments/index.ts +++ b/x-pack/plugins/cases/server/services/attachments/index.ts @@ -14,10 +14,7 @@ import type { } from '@kbn/core/server'; import type * as estypes from '@elastic/elasticsearch/lib/api/typesWithBodyKey'; -import type { - CommentAttributes as AttachmentAttributes, - CommentAttributesWithoutRefs as AttachmentAttributesWithoutRefs, -} from '../../../common/api'; +import type { CommentAttributes as AttachmentAttributes } from '../../../common/api'; import { CommentType } from '../../../common/api'; import { CASE_COMMENT_SAVED_OBJECT, CASE_SAVED_OBJECT } from '../../../common/constants'; import { buildFilter, combineFilters } from '../../client/utils'; @@ -102,10 +99,7 @@ export class AttachmentService { const combinedFilter = combineFilters([attachmentFilter, filter]); - const response = await this.context.unsecuredSavedObjectsClient.find< - AttachmentAttributes, - Agg - >({ + const response = await this.context.unsecuredSavedObjectsClient.find({ type: CASE_COMMENT_SAVED_OBJECT, hasReference: { type: CASE_SAVED_OBJECT, id: caseId }, page: 1, @@ -254,7 +248,7 @@ export class AttachmentService { const shouldUpdateRefs = extractedReferences.length > 0 || didDeleteOperation; const res = - await this.context.unsecuredSavedObjectsClient.update( + await this.context.unsecuredSavedObjectsClient.update( CASE_COMMENT_SAVED_OBJECT, attachmentId, extractedAttributes, @@ -291,7 +285,7 @@ export class AttachmentService { ); const res = - await this.context.unsecuredSavedObjectsClient.bulkUpdate( + await this.context.unsecuredSavedObjectsClient.bulkUpdate( comments.map((c) => { const { attributes: extractedAttributes, diff --git a/x-pack/plugins/cases/server/services/attachments/operations/get.ts b/x-pack/plugins/cases/server/services/attachments/operations/get.ts index 138157a6e62dd..635b9c9364c3a 100644 --- a/x-pack/plugins/cases/server/services/attachments/operations/get.ts +++ b/x-pack/plugins/cases/server/services/attachments/operations/get.ts @@ -76,7 +76,9 @@ export class AttachmentGetter { `Attempting to retrieve attachments associated with cases: [${caseIds}]` ); - const finder = this.context.unsecuredSavedObjectsClient.createPointInTimeFinder({ + // We are intentionally not adding the type here because we only want to interact with the id and this function + // should not use the attributes + const finder = this.context.unsecuredSavedObjectsClient.createPointInTimeFinder({ type: CASE_COMMENT_SAVED_OBJECT, hasReference: caseIds.map((id) => ({ id, type: CASE_SAVED_OBJECT })), sortField: 'created_at', diff --git a/x-pack/plugins/cases/server/services/so_references.ts b/x-pack/plugins/cases/server/services/so_references.ts index c88b6f83924c7..8a3cc747c752a 100644 --- a/x-pack/plugins/cases/server/services/so_references.ts +++ b/x-pack/plugins/cases/server/services/so_references.ts @@ -15,7 +15,6 @@ import type { CommentAttributesNoSO, CommentAttributes, CommentPatchAttributes, - CommentAttributesWithoutRefs, } from '../../common/api'; import type { PersistableStateAttachmentTypeRegistry } from '../attachment_framework/persistable_state_registry'; import { @@ -27,11 +26,13 @@ import type { AttachmentPersistedAttributes, AttachmentRequestAttributes, } from '../common/types/attachments'; -import { isCommentRequestTypeExternalReferenceSO } from '../common/utils'; +import { isCommentRequestTypeExternalReferenceSO } from './type_guards'; import type { PartialField } from '../types'; import { SOReferenceExtractor } from './so_reference_extractor'; -export const getAttachmentSOExtractor = (attachment: Partial) => { +export const getAttachmentSOExtractor = ( + attachment: Partial +): SOReferenceExtractor => { const fieldsToExtract = []; if (isCommentRequestTypeExternalReferenceSO(attachment)) { @@ -72,7 +73,7 @@ const hasAttributes = (savedObject: OptionalAttributes): savedObject is Sa export const injectAttachmentSOAttributesFromRefs = ( savedObject: SavedObject, persistableStateAttachmentTypeRegistry: PersistableStateAttachmentTypeRegistry -) => { +): SavedObject => { const soExtractor = getAttachmentSOExtractor(savedObject.attributes); const so = soExtractor.populateFieldsFromReferences(savedObject); const injectedAttributes = injectPersistableReferencesToSO(so.attributes, so.references, { @@ -84,9 +85,9 @@ export const injectAttachmentSOAttributesFromRefs = ( export const injectAttachmentSOAttributesFromRefsForPatch = ( updatedAttributes: CommentPatchAttributes, - savedObject: SavedObjectsUpdateResponse, + savedObject: SavedObjectsUpdateResponse, persistableStateAttachmentTypeRegistry: PersistableStateAttachmentTypeRegistry -) => { +): SavedObjectsUpdateResponse => { const soExtractor = getAttachmentSOExtractor(savedObject.attributes); const so = soExtractor.populateFieldsFromReferencesForPatch({ dataBeforeRequest: updatedAttributes, @@ -107,11 +108,17 @@ export const injectAttachmentSOAttributesFromRefsForPatch = ( } as SavedObjectsUpdateResponse; }; +interface ExtractionResults { + attributes: AttachmentPersistedAttributes; + references: SavedObjectReference[]; + didDeleteOperation: boolean; +} + export const extractAttachmentSORefsFromAttributes = ( attributes: CommentAttributes | CommentPatchAttributes, references: SavedObjectReference[], persistableStateAttachmentTypeRegistry: PersistableStateAttachmentTypeRegistry -) => { +): ExtractionResults => { const soExtractor = getAttachmentSOExtractor(attributes); const { @@ -135,5 +142,5 @@ export const extractAttachmentSORefsFromAttributes = ( }; }; -export const getUniqueReferences = (references: SavedObjectReference[]) => +export const getUniqueReferences = (references: SavedObjectReference[]): SavedObjectReference[] => uniqWith(references, isEqual); diff --git a/x-pack/plugins/cases/server/services/type_guards.ts b/x-pack/plugins/cases/server/services/type_guards.ts new file mode 100644 index 0000000000000..ec4c100b17585 --- /dev/null +++ b/x-pack/plugins/cases/server/services/type_guards.ts @@ -0,0 +1,22 @@ +/* + * 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. + */ + +import type { CommentRequestExternalReferenceSOType } from '../../common/api'; +import { CommentType, ExternalReferenceStorageType } from '../../common/api'; +import type { AttachmentRequestAttributes } from '../common/types/attachments'; + +/** + * A type narrowing function for external reference saved object attachments. + */ +export const isCommentRequestTypeExternalReferenceSO = ( + context: Partial +): context is CommentRequestExternalReferenceSOType => { + return ( + context.type === CommentType.externalReference && + context.externalReferenceStorage?.type === ExternalReferenceStorageType.savedObject + ); +}; diff --git a/x-pack/plugins/cases/server/services/user_actions/transform.ts b/x-pack/plugins/cases/server/services/user_actions/transform.ts index 439e57eed386d..87f3eb898efe1 100644 --- a/x-pack/plugins/cases/server/services/user_actions/transform.ts +++ b/x-pack/plugins/cases/server/services/user_actions/transform.ts @@ -30,7 +30,7 @@ import { PUSH_CONNECTOR_ID_REFERENCE_NAME, } from '../../common/constants'; import { findConnectorIdReference } from '../transform'; -import { isCommentRequestTypeExternalReferenceSO } from '../../common/utils'; +import { isCommentRequestTypeExternalReferenceSO } from '../type_guards'; import type { PersistableStateAttachmentTypeRegistry } from '../../attachment_framework/persistable_state_registry'; import { injectPersistableReferencesToSO } from '../../attachment_framework/so_references'; import { findReferenceId } from '../../common/references';