prey/prey-node-client

View on GitHub
lib/agent/providers/webcam/mac/index.js

Summary

Maintainability
C
1 day
Test Coverage
const { exec } = require('child_process');
// eslint-disable-next-line camelcase
const { is_greater_than } = require('../../../helpers');
const common = require('../../../common');

const socket = require('../../../socket');
const { nameArray } = require('../../../socket/messages');
const { system } = common;
// eslint-disable-next-line camelcase
const { run_as_logged_user } = system;
// eslint-disable-next-line camelcase
const { tempfile_path } = common.system;

const pictureTimeout = 10000;

let timer;
let child;
let running = true;

const pictureUtilData = {
  appPath: '',
  pictureDir: '',
  tmpPicture: '',
};
/**
 * Executes the callback function after the completion of a task.
 *
 * @param {Error} err - The error object, if any.
 * @param {string} filePath - The path of the file.
 * @param {function} cb - The callback function to be executed.
 * @return {undefined} Executes the callback function with the specified parameters.
 */
// eslint-disable-next-line consistent-return
const done = (err, filePath, cb) => {
  running = false;
  if (timer) clearTimeout(timer);
  if (err) return cb(err);
  cb(null, filePath, 'image/jpeg');
};
/**
 * Configures the picture user data.
 *
 * @param {string} user - the user's name
 * @param {number} userId - the user's ID
 */
const configurePictureUserData = () => {
  pictureUtilData.appPath = `${__dirname}/../../../utils/Prey.app`;
  pictureUtilData.pictureDir = '/tmp';
  pictureUtilData.tmpPicture = `${pictureUtilData.pictureDir}/picture.jpg`;
};

/**
 * Takes a picture.
 *
 * @param {function} cb - The callback function to be called after the picture is taken.
 * @return {undefined} No return value.
 */
const takePicture = (cb) => {
  // eslint-disable-next-line consistent-return
  child = run_as_logged_user(`open -n ${pictureUtilData.appPath}`, ['--args', '-picture'], (err) => {
    if (err) return cb(err);
    cb();
  });
};

exports.get_picture = (callback) => {
  socket.writeMessage(nameArray[2], (err, data) => {
    if (err) return exports.get_picture_old(callback);
    try {
      if (data.result.success.toString().localeCompare('false') === 0) return done(new Error("Couldn't get picture"), null, callback);
      done(null, data.result.messages[0].message, callback);
    } catch (_ex) {
      done(new Error("Couldn't get picture"), null, callback);
    }
    // if (err) return get_screenshot_old(callback);
    // return done(null, data, callback);
  });
};

/**
 * Generates the function comment for the given function body.
 *
 * @param {function} callback - The callback function to be called.
 * @return {undefined}
 */
exports.get_picture_old = (callback) => {
  // if after 10 seconds the picture hasn't been taken, cancel it.
  timer = setTimeout(() => {
    if (running && child) child.kill();
  }, pictureTimeout);

  if (is_greater_than('10.14.0', common.os_release)) {
    const filePath1014 = tempfile_path(`picture.${process.pid}.jpg`);
    child = exec(`"${__dirname}/imagesnap" -w 1 ${filePath1014}`, (err) => {
      done(err, filePath1014, callback);
    });
    return;
  }
  // Patch for MacOS Mojave and future versions
  // eslint-disable-next-line consistent-return
  common.system.get_logged_user((err, user) => {
    if (err || !user) return done(new Error(`Unable to get logged user: ${err.toString()}`), null, callback);
    // eslint-disable-next-line consistent-return
    configurePictureUserData();
    // eslint-disable-next-line consistent-return
    takePicture((errorTakePicture) => {
      if (errorTakePicture) return done(errorTakePicture, null, callback);
      setTimeout(() => {
        done(null, pictureUtilData.tmpPicture, callback);
      }, 3000);
    });
  });
};

exports.done = done;
exports.running = running;
exports.timer = timer;
exports.pictureUtilData = pictureUtilData;
exports.configurePictureUserData = configurePictureUserData;
exports.takePicture = takePicture;