@mdf.js/openc2-core
Version:
MMS - API Core - OpenC2
198 lines • 8.67 kB
JavaScript
;
/**
* Copyright 2024 Mytra Control S.L. All rights reserved.
*
* Use of this source code is governed by an MIT-style license that can be found in the LICENSE file
* or at https://opensource.org/licenses/MIT.
*/
Object.defineProperty(exports, "__esModule", { value: true });
exports.Checkers = void 0;
const lodash_1 = require("lodash");
const modules_1 = require("../modules");
const types_1 = require("../types");
const Accessors_1 = require("./Accessors");
const Helpers_1 = require("./Helpers");
const responseRequested = 'content.args.response_requested';
class Checkers {
/**
* Check if the message is a valid message.
* @param message - message to be check
* @param uuid - traceability identifier
* @returns Validated message.
* @throws In case of invalid message, throw a validation error.
*/
static isValidMessageSync(message, uuid) {
return modules_1.Checker.attempt('Control.Message', message, uuid);
}
/**
* Check if the message is a valid message.
* @param message - message to be check
* @param uuid - traceability identifier
* @returns Promise with the validated message.
*/
static isValidMessage(message, uuid) {
return modules_1.Checker.validate('Control.Message', message, uuid);
}
/**
* Check if the command is a valid command message.
* @param command - command to be check
* @param uuid - traceability identifier
* @returns Validated command message.
* @throws In case of invalid command, throw a validation error.
*/
static isValidCommandSync(command, uuid) {
return modules_1.Checker.attempt('Control.Message.Command', command, uuid);
}
/**
* Check if the command is a valid command message.
* @param command - command to be check
* @param uuid - traceability identifier
* @returns Promise with the validated command message.
*/
static isValidCommand(command, uuid) {
return modules_1.Checker.validate('Control.Message.Command', command, uuid);
}
/**
* Check if the response is a valid response message
* @param response - response to be checked
* @param uuid - traceability identifier
* @returns Validated response message.
* @throws In case of invalid response, throw a validation error.
*/
static isValidResponseSync(response, uuid) {
return modules_1.Checker.attempt('Control.Message.Response', response, uuid);
}
/**
* Check if the response is a valid response message
* @param response - response to be checked
* @param uuid - traceability identifier
* @returns Promise with the validated response message.
*/
static isValidResponse(response, uuid) {
return modules_1.Checker.validate('Control.Message.Response', response, uuid);
}
/**
* Checks if the command should be response with a default response
* @param command - message to be checked
* @param options - Consumer options
* @returns Default response for the command or undefined if the command has no default response
*/
static hasDefaultResponse(command, options) {
if (!this.isOnTime(command)) {
return Helpers_1.Helpers.badRequest(command, options.id, 'Command is out of time');
}
else if (this.isQueryFeaturesRequest(command)) {
if (this.isValidQueryFeaturesRequest(command)) {
return Helpers_1.Helpers.respondFeatures(command, options.id, options.actionTargetPairs, options.profiles);
}
else {
(0, lodash_1.set)(command, responseRequested, types_1.Control.ResponseType.Complete);
return Helpers_1.Helpers.badRequest(command, options.id, 'Invalid Query Features');
}
}
else if (!this.isSupportedAction(command, options.actionTargetPairs)) {
return Helpers_1.Helpers.notImplemented(command, options.id, 'Command not supported');
}
else if (this.isAckOnlyRequested(command)) {
return Helpers_1.Helpers.processing(command, options.id, undefined, 'Command accepted');
}
else {
return undefined;
}
}
/**
* Check if the message is a command the instance indicated or for all the instances
* @param message - message to be checked
* @param id - instance identification
* @returns true if the message is for this instance or for all the instances
*/
static isCommandToInstance(message, id) {
return (message.msg_type === types_1.Control.MessageType.Command &&
(message.to.includes(id) || message.to.includes('*')) &&
message.from !== id);
}
/**
* Check if the message is a response for our command
* @param message - message to be checked
* @param from - from field of the original command
* @param requestId - request_id field of the original command
* @returns
*/
static isResponseToInstance(message, from, requestId) {
return (message.msg_type === types_1.Control.MessageType.Response &&
(message.to.includes(from) || message.to.includes('*')) &&
message.request_id === requestId);
}
/**
* Check if the command has arguments based on execution time and if we are on time
* @param command - message to be checked
* @returns
*/
static isOnTime(command) {
const startTime = (0, lodash_1.get)(command, 'content.args.start_time', undefined);
const stopTime = (0, lodash_1.get)(command, 'content.args.stop_time', undefined);
const duration = (0, lodash_1.get)(command, 'content.args.duration', undefined);
const wrongConfiguration = startTime !== undefined && stopTime !== undefined && duration !== undefined;
const startTimeHasPassedBasedOnStartTime = startTime !== undefined && duration !== undefined && startTime + duration < Date.now();
const startTimeHasPassedBasedOnStopTime = startTime === undefined &&
stopTime !== undefined &&
duration !== undefined &&
stopTime < Date.now();
return (!wrongConfiguration &&
!startTimeHasPassedBasedOnStartTime &&
!startTimeHasPassedBasedOnStopTime);
}
/**
* Check if the command is supported
* @param command - message to be checked
* @param pairs - action-target pairs supported by the consumer
* @returns
*/
static isSupportedAction(command, pairs) {
var _a;
const action = command.content.action;
const targetType = new RegExp(`^${Accessors_1.Accessors.getTargetFromCommandMessage(command)}$`);
const supportedActions = (0, lodash_1.get)(pairs, action);
return (_a = supportedActions === null || supportedActions === void 0 ? void 0 : supportedActions.some(target => targetType.test(target))) !== null && _a !== void 0 ? _a : false;
}
/**
* Check if the command only request an ack as response
* @param command - message to be checked
* @returns
*/
static isAckOnlyRequested(command) {
return (0, lodash_1.get)(command, responseRequested) === types_1.Control.ResponseType.ACK;
}
/**
* Check if the command is a featured request
* @param command - message to be checked
* @returns
*/
static isQueryFeaturesRequest(command) {
const action = command.content.action;
const targetType = Accessors_1.Accessors.getTargetFromCommandMessage(command);
return action === types_1.Control.Action.Query && targetType === 'features';
}
/**
* Check if the command is a valid featured request
* @param command - message to be checked
* @returns
*/
static isValidQueryFeaturesRequest(command) {
return (0, lodash_1.get)(command, responseRequested) === types_1.Control.ResponseType.Complete;
}
/**
* Return the delay allowed from command
* @param command - message to be processed
*/
static isDelayDefinedOnCommand(command) {
const startTimeIsDefined = Boolean((0, lodash_1.get)(command, 'args.start_time', undefined));
const stopTimeIsDefined = Boolean((0, lodash_1.get)(command, 'args.stop_time', undefined));
const durationIsDefined = Boolean((0, lodash_1.get)(command, 'args.duration', undefined));
const basedInDuration = startTimeIsDefined && durationIsDefined;
const basedInStopTime = stopTimeIsDefined;
return basedInStopTime !== basedInDuration;
}
}
exports.Checkers = Checkers;
//# sourceMappingURL=Checkers.js.map