You can not select more than 25 topics
			Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
		
		
		
		
		
			
		
			
				
					
					
						
							125 lines
						
					
					
						
							3.2 KiB
						
					
					
				
			
		
		
	
	
							125 lines
						
					
					
						
							3.2 KiB
						
					
					
				'use strict';
 | 
						|
const Msg = require('./core/connection/msg').Msg;
 | 
						|
const KillCursor = require('./core/connection/commands').KillCursor;
 | 
						|
const GetMore = require('./core/connection/commands').GetMore;
 | 
						|
const deepCopy = require('./utils').deepCopy;
 | 
						|
 | 
						|
/** Commands that we want to redact because of the sensitive nature of their contents */
 | 
						|
const SENSITIVE_COMMANDS = new Set([
 | 
						|
  'authenticate',
 | 
						|
  'saslStart',
 | 
						|
  'saslContinue',
 | 
						|
  'getnonce',
 | 
						|
  'createUser',
 | 
						|
  'updateUser',
 | 
						|
  'copydbgetnonce',
 | 
						|
  'copydbsaslstart',
 | 
						|
  'copydb'
 | 
						|
]);
 | 
						|
 | 
						|
const HELLO_COMMANDS = new Set(['hello', 'ismaster', 'isMaster']);
 | 
						|
 | 
						|
const LEGACY_FIND_QUERY_MAP = {
 | 
						|
  $query: 'filter',
 | 
						|
  $orderby: 'sort',
 | 
						|
  $hint: 'hint',
 | 
						|
  $comment: 'comment',
 | 
						|
  $maxScan: 'maxScan',
 | 
						|
  $max: 'max',
 | 
						|
  $min: 'min',
 | 
						|
  $returnKey: 'returnKey',
 | 
						|
  $showDiskLoc: 'showRecordId',
 | 
						|
  $maxTimeMS: 'maxTimeMS',
 | 
						|
  $snapshot: 'snapshot'
 | 
						|
};
 | 
						|
 | 
						|
const LEGACY_FIND_OPTIONS_MAP = {
 | 
						|
  numberToSkip: 'skip',
 | 
						|
  numberToReturn: 'batchSize',
 | 
						|
  returnFieldsSelector: 'projection'
 | 
						|
};
 | 
						|
 | 
						|
const OP_QUERY_KEYS = [
 | 
						|
  'tailable',
 | 
						|
  'oplogReplay',
 | 
						|
  'noCursorTimeout',
 | 
						|
  'awaitData',
 | 
						|
  'partial',
 | 
						|
  'exhaust'
 | 
						|
];
 | 
						|
 | 
						|
const collectionName = command => command.ns.split('.')[1];
 | 
						|
 | 
						|
const shouldRedactCommand = (commandName, cmd) =>
 | 
						|
  SENSITIVE_COMMANDS.has(commandName) ||
 | 
						|
  (HELLO_COMMANDS.has(commandName) && !!cmd.speculativeAuthenticate);
 | 
						|
 | 
						|
/**
 | 
						|
 * Extract the actual command from the query, possibly upconverting if it's a legacy
 | 
						|
 * format
 | 
						|
 *
 | 
						|
 * @param {Object} command the command
 | 
						|
 */
 | 
						|
const extractCommand = command => {
 | 
						|
  let extractedCommand;
 | 
						|
  if (command instanceof GetMore) {
 | 
						|
    extractedCommand = {
 | 
						|
      getMore: deepCopy(command.cursorId),
 | 
						|
      collection: collectionName(command),
 | 
						|
      batchSize: command.numberToReturn
 | 
						|
    };
 | 
						|
  } else if (command instanceof KillCursor) {
 | 
						|
    extractedCommand = {
 | 
						|
      killCursors: collectionName(command),
 | 
						|
      cursors: deepCopy(command.cursorIds)
 | 
						|
    };
 | 
						|
  } else if (command instanceof Msg) {
 | 
						|
    extractedCommand = deepCopy(command.command);
 | 
						|
  } else if (command.query && command.query.$query) {
 | 
						|
    let result;
 | 
						|
    if (command.ns === 'admin.$cmd') {
 | 
						|
      // upconvert legacy command
 | 
						|
      result = Object.assign({}, command.query.$query);
 | 
						|
    } else {
 | 
						|
      // upconvert legacy find command
 | 
						|
      result = { find: collectionName(command) };
 | 
						|
      Object.keys(LEGACY_FIND_QUERY_MAP).forEach(key => {
 | 
						|
        if (typeof command.query[key] !== 'undefined')
 | 
						|
          result[LEGACY_FIND_QUERY_MAP[key]] = deepCopy(command.query[key]);
 | 
						|
      });
 | 
						|
    }
 | 
						|
 | 
						|
    Object.keys(LEGACY_FIND_OPTIONS_MAP).forEach(key => {
 | 
						|
      if (typeof command[key] !== 'undefined')
 | 
						|
        result[LEGACY_FIND_OPTIONS_MAP[key]] = deepCopy(command[key]);
 | 
						|
    });
 | 
						|
 | 
						|
    OP_QUERY_KEYS.forEach(key => {
 | 
						|
      if (command[key]) result[key] = command[key];
 | 
						|
    });
 | 
						|
 | 
						|
    if (typeof command.pre32Limit !== 'undefined') {
 | 
						|
      result.limit = command.pre32Limit;
 | 
						|
    }
 | 
						|
 | 
						|
    if (command.query.$explain) {
 | 
						|
      extractedCommand = { explain: result };
 | 
						|
    } else {
 | 
						|
      extractedCommand = result;
 | 
						|
    }
 | 
						|
  } else {
 | 
						|
    extractedCommand = deepCopy(command.query || command);
 | 
						|
  }
 | 
						|
 | 
						|
  const commandName = Object.keys(extractedCommand)[0];
 | 
						|
  return {
 | 
						|
    cmd: extractedCommand,
 | 
						|
    name: commandName,
 | 
						|
    shouldRedact: shouldRedactCommand(commandName, extractedCommand)
 | 
						|
  };
 | 
						|
};
 | 
						|
 | 
						|
module.exports = {
 | 
						|
  extractCommand
 | 
						|
};
 |