"use strict"; var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault"); Object.defineProperty(exports, "__esModule", { value: true }); exports.UserActionPersister = void 0; var _defineProperty2 = _interopRequireDefault(require("@babel/runtime/helpers/defineProperty")); var _lodash = require("lodash"); var _domain = require("../../../../common/types/domain"); var _user_actions = require("../../../common/types/user_actions"); var _constants = require("../../../../common/constants"); var _utils = require("../../../client/utils"); var _user_actions2 = require("../../../../common/utils/user_actions"); var _api = require("../../../../common/api"); var _builder_factory = require("../builder_factory"); var _type_guards = require("../type_guards"); var _audit_logger = require("../audit_logger"); /* * 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. */ class UserActionPersister { constructor(context) { (0, _defineProperty2.default)(this, "builderFactory", void 0); (0, _defineProperty2.default)(this, "auditLogger", void 0); this.context = context; this.builderFactory = new _builder_factory.BuilderFactory({ persistableStateAttachmentTypeRegistry: this.context.persistableStateAttachmentTypeRegistry }); this.auditLogger = new _audit_logger.UserActionAuditLogger(this.context.auditLogger); } buildUserActions({ updatedCases, user }) { return updatedCases.cases.reduce((acc, updatedCase) => { const originalCase = updatedCase.originalCase; if (originalCase == null) { return acc; } const caseId = updatedCase.caseId; const owner = originalCase.attributes.owner; const userActions = []; const updatedFields = Object.keys(updatedCase.updatedAttributes); updatedFields.filter(field => UserActionPersister.userActionFieldsAllowed.has(field)).forEach(field => { const originalValue = (0, _lodash.get)(originalCase, ['attributes', field]); const newValue = (0, _lodash.get)(updatedCase, ['updatedAttributes', field]); userActions.push(...this.getUserActionItemByDifference({ field, originalValue, newValue, user, owner, caseId })); }); acc[caseId] = userActions; return acc; }, {}); } async bulkCreateUpdateCase({ builtUserActions, refresh }) { await this.bulkCreateAndLog({ userActions: builtUserActions, refresh }); } getUserActionItemByDifference(params) { const { field, originalValue, newValue, caseId, owner, user } = params; if (!UserActionPersister.userActionFieldsAllowed.has(field)) { return []; } else if (field === _domain.UserActionTypes.assignees && (0, _type_guards.isAssigneesArray)(originalValue) && (0, _type_guards.isAssigneesArray)(newValue)) { return this.buildAssigneesUserActions({ ...params, originalValue, newValue }); } else if (field === _domain.UserActionTypes.tags && (0, _type_guards.isStringArray)(originalValue) && (0, _type_guards.isStringArray)(newValue)) { return this.buildTagsUserActions({ ...params, originalValue, newValue }); } else if ((0, _user_actions2.isUserActionType)(field) && newValue !== undefined) { const userActionBuilder = this.builderFactory.getBuilder(_domain.UserActionTypes[field]); const fieldUserAction = userActionBuilder === null || userActionBuilder === void 0 ? void 0 : userActionBuilder.build({ caseId, owner, user, payload: { [field]: newValue } }); return fieldUserAction ? [fieldUserAction] : []; } return []; } buildAssigneesUserActions(params) { const createPayload = items => ({ assignees: items }); return this.buildAddDeleteUserActions(params, createPayload, _domain.UserActionTypes.assignees); } buildTagsUserActions(params) { const createPayload = items => ({ tags: items }); return this.buildAddDeleteUserActions(params, createPayload, _domain.UserActionTypes.tags); } buildAddDeleteUserActions(params, createPayload, actionType) { const { originalValue, newValue } = params; const compareValues = (0, _utils.arraysDifference)(originalValue, newValue); const addUserAction = this.buildUserAction({ commonArgs: params, actionType, action: _domain.UserActionActions.add, createPayload, modifiedItems: compareValues === null || compareValues === void 0 ? void 0 : compareValues.addedItems }); const deleteUserAction = this.buildUserAction({ commonArgs: params, actionType, action: _domain.UserActionActions.delete, createPayload, modifiedItems: compareValues === null || compareValues === void 0 ? void 0 : compareValues.deletedItems }); return [...(addUserAction ? [addUserAction] : []), ...(deleteUserAction ? [deleteUserAction] : [])]; } buildUserAction({ commonArgs, actionType, action, createPayload, modifiedItems }) { const userActionBuilder = this.builderFactory.getBuilder(actionType); if (!userActionBuilder || !modifiedItems || modifiedItems.length <= 0) { return; } const { caseId, owner, user } = commonArgs; const userAction = userActionBuilder.build({ action, caseId, user, owner, payload: createPayload(modifiedItems) }); return userAction; } async bulkCreateAttachmentDeletion({ caseId, attachments, user, refresh }) { await this.bulkCreateAttachment({ caseId, attachments, user, action: _domain.UserActionActions.delete, refresh }); } async bulkCreateAttachmentCreation({ caseId, attachments, user, refresh }) { await this.bulkCreateAttachment({ caseId, attachments, user, action: _domain.UserActionActions.create, refresh }); } async bulkCreateAttachment({ caseId, attachments, user, action = _domain.UserActionActions.create, refresh }) { this.context.log.debug(`Attempting to create a bulk create case user action`); if (attachments.length <= 0) { return; } const userActions = attachments.reduce((acc, attachment) => { const userActionBuilder = this.builderFactory.getBuilder(_domain.UserActionTypes.comment); const commentUserAction = userActionBuilder === null || userActionBuilder === void 0 ? void 0 : userActionBuilder.build({ action, caseId, user, owner: attachment.owner, attachmentId: attachment.id, payload: { attachment: attachment.attachment } }); if (commentUserAction == null) { return acc; } return [...acc, commentUserAction]; }, []); await this.bulkCreateAndLog({ userActions, refresh }); } async bulkCreateAndLog({ userActions, refresh }) { const createdUserActions = await this.bulkCreate({ actions: userActions, refresh }); if (!createdUserActions) { return; } for (let i = 0; i < userActions.length; i++) { this.auditLogger.log(userActions[i].eventDetails, createdUserActions.saved_objects[i].id); } } async bulkCreate({ actions, refresh }) { if ((0, _lodash.isEmpty)(actions)) { return; } try { this.context.log.debug(`Attempting to bulk create user actions`); return await this.context.unsecuredSavedObjectsClient.bulkCreate(actions.map(action => { const decodedAttributes = (0, _api.decodeOrThrow)(_user_actions.UserActionPersistedAttributesRt)(action.parameters.attributes); return { type: _constants.CASE_USER_ACTION_SAVED_OBJECT, attributes: decodedAttributes, references: action.parameters.references }; }), { refresh }); } catch (error) { this.context.log.error(`Error on bulk creating user action: ${error}`); throw error; } } async createUserAction({ action, type, caseId, user, owner, payload, connectorId, attachmentId, refresh }) { try { this.context.log.debug(`Attempting to create a user action of type: ${type}`); const userActionBuilder = this.builderFactory.getBuilder(type); const userAction = userActionBuilder === null || userActionBuilder === void 0 ? void 0 : userActionBuilder.build({ action, caseId, user, owner, connectorId, attachmentId, payload }); if (userAction) { await this.createAndLog({ userAction, refresh }); } } catch (error) { this.context.log.error(`Error on creating user action of type: ${type}. Error: ${error}`); throw error; } } async createAndLog({ userAction, refresh }) { const createdUserAction = await this.create({ ...userAction.parameters, refresh }); this.auditLogger.log(userAction.eventDetails, createdUserAction.id); } async create({ attributes, references, refresh }) { try { this.context.log.debug(`Attempting to POST a new case user action`); const decodedAttributes = (0, _api.decodeOrThrow)(_user_actions.UserActionPersistedAttributesRt)(attributes); const res = await this.context.unsecuredSavedObjectsClient.create(_constants.CASE_USER_ACTION_SAVED_OBJECT, decodedAttributes, { references: references !== null && references !== void 0 ? references : [], refresh }); return res; } catch (error) { this.context.log.error(`Error on POST a new case user action: ${error}`); throw error; } } async bulkAuditLogCaseDeletion(caseIds) { this.context.log.debug(`Attempting to log bulk case deletion`); for (const id of caseIds) { this.auditLogger.log({ getMessage: () => `User deleted case id: ${id}`, action: _domain.UserActionActions.delete, descriptiveAction: 'case_user_action_delete_case', savedObjectId: id, savedObjectType: _constants.CASE_SAVED_OBJECT }); } } } exports.UserActionPersister = UserActionPersister; (0, _defineProperty2.default)(UserActionPersister, "userActionFieldsAllowed", new Set(Object.keys(_domain.UserActionTypes)));