"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.registerActionFileUploadRoute = exports.getActionFileUploadHandler = void 0; var _endpoint = require("../../../../common/api/endpoint"); var _constants = require("../../../../common/endpoint/constants"); var _with_endpoint_authz = require("../with_endpoint_authz"); var _error_handler = require("../error_handler"); var _update_cases = require("../../services/actions/create/update_cases"); /* * 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 registerActionFileUploadRoute = (router, endpointContext) => { if (!endpointContext.experimentalFeatures.responseActionUploadEnabled) { return; } const logger = endpointContext.logFactory.get('uploadAction'); router.versioned.post({ access: 'public', path: _constants.UPLOAD_ROUTE, options: { authRequired: true, tags: ['access:securitySolution'], body: { accepts: ['multipart/form-data'], output: 'stream', maxBytes: endpointContext.serverConfig.maxUploadResponseActionFileBytes } } }).addVersion({ version: '2023-10-31', validate: { request: _endpoint.UploadActionRequestSchema } }, (0, _with_endpoint_authz.withEndpointAuthz)({ all: ['canWriteFileOperations'] }, logger, getActionFileUploadHandler(endpointContext))); }; exports.registerActionFileUploadRoute = registerActionFileUploadRoute; const getActionFileUploadHandler = endpointContext => { const logger = endpointContext.logFactory.get('uploadAction'); return async (context, req, res) => { var _endpointContext$serv; const fleetFiles = await endpointContext.service.getFleetToHostFilesClient(); const user = (_endpointContext$serv = endpointContext.service.security) === null || _endpointContext$serv === void 0 ? void 0 : _endpointContext$serv.authc.getCurrentUser(req); const fileStream = req.body.file; const { file: _, parameters: userParams, ...actionPayload } = req.body; const uploadParameters = { ...userParams, file_id: '', file_name: '', file_sha256: '', file_size: 0 }; try { const createdFile = await fleetFiles.create(fileStream, actionPayload.endpoint_ids); uploadParameters.file_id = createdFile.id; uploadParameters.file_name = createdFile.name; uploadParameters.file_sha256 = createdFile.sha256; uploadParameters.file_size = createdFile.size; } catch (err) { return (0, _error_handler.errorHandler)(logger, res, err); } const createActionPayload = { ...actionPayload, parameters: uploadParameters, command: 'upload', user }; const esClient = (await context.core).elasticsearch.client.asInternalUser; const endpointData = await endpointContext.service.getEndpointMetadataService().getMetadataForEndpoints(esClient, [...new Set(createActionPayload.endpoint_ids)]); const agentIds = endpointData.map(endpoint => endpoint.elastic.agent.id); try { const casesClient = await endpointContext.service.getCasesClient(req); const { action: actionId, ...data } = await endpointContext.service.getActionCreateService().createAction(createActionPayload, agentIds); // Update the file meta to include the action id, and if any errors (unlikely), // then just log them and still allow api to return success since the action has // already been created and potentially dispatched to Endpoint. Action ID is not // needed by the Endpoint or fleet-server's API, so no need to fail here try { await fleetFiles.update(uploadParameters.file_id, { actionId: data.id }); } catch (e) { logger.warn(`Attempt to update File meta with Action ID failed: ${e.message}`, e); } // update cases await (0, _update_cases.updateCases)({ casesClient, createActionPayload, endpointData }); return res.ok({ body: { action: actionId, data } }); } catch (err) { if (uploadParameters.file_id) { // Try to delete the created file since creating the action threw an error try { await fleetFiles.delete(uploadParameters.file_id); } catch (e) { logger.error(`Attempt to clean up file (after action creation was unsuccessful) failed; ${e.message}`, e); } } return (0, _error_handler.errorHandler)(logger, res, err); } }; }; exports.getActionFileUploadHandler = getActionFileUploadHandler;