Ssh-เจ—เฉฑเจฒเจฌเจพเจค, เจญเจพเจ— 2

เจนเฉˆเจฒเฉ‹, เจนเฉˆเจฌเจฐ. เจ‡เจน ssh-chat เจฒเฉœเฉ€ เจฆเจพ เจฆเฉ‚เจœเจพ เจฒเฉ‡เจ– เจนเฉˆเฅค

เจ…เจธเฉ€เจ‚ เจ•เฉ€ เจ•เจฐเจพเจ‚เจ—เฉ‡:

  • เจ†เจ‰ เจคเฉเจนเจพเจกเฉ‡ เจ†เจชเจฃเฉ‡ เจกเจฟเจœเจผเจพเจˆเจจ เจซเฉฐเจ•เจธเจผเจจเจพเจ‚ เจจเฉ‚เฉฐ เจฌเจฃเจพเจ‰เจฃ เจฆเฉ€ เจฏเฉ‹เจ—เจคเจพ เจจเฉ‚เฉฐ เจœเฉ‹เฉœเฉ€เจ
  • เจ†เจ‰ เจฎเจพเจฐเจ•เจกเจพเจŠเจจ เจธเจชเฉ‹เจฐเจŸ เจœเฉ‹เฉœเฉ€เจ
  • เจ†เจ‰ เจฌเฉ‹เจŸ เจธเจนเจพเจ‡เจคเจพ เจœเฉ‹เฉœเฉ€เจ
  • เจชเจพเจธเจตเจฐเจก เจธเฉเจฐเฉฑเจ–เจฟเจ† เจตเจงเจพเจ“ (เจนเฉˆเจธเจผ เจ…เจคเฉ‡ เจจเจฎเจ•)
    เจฎเจพเจซเจผ เจ•เจฐเจจเจพ, เจชเจฐ เจซเจผเจพเจˆเจฒเจพเจ‚ เจจเจนเฉ€เจ‚ เจญเฉ‡เจœเฉ€เจ†เจ‚ เจœเจพเจฃเจ—เฉ€เจ†เจ‚เฅค

เจ•เจธเจŸเจฎ เจกเจฟเจœเจผเจพเจˆเจจ เจตเจฟเจธเจผเฉ‡เจธเจผเจคเจพเจตเจพเจ‚

เจตเจฐเจคเจฎเจพเจจ เจตเจฟเฉฑเจš, เจนเฉ‡เจ เจพเจ‚ เจฆเจฟเฉฑเจคเฉ‡ เจกเจฟเจœเจผเจพเจˆเจจ เจซเฉฐเจ•เจธเจผเจจ เจธเจฎเจฐเจฅเจฟเจค เจนเจจ:

  • @color
  • @bold
  • @underline
  • @hex
  • @box
    เจชเจฐ เจ‡เจน เจคเฉเจนเจพเจกเฉ‡ เจ†เจชเจฃเฉ‡ เจซเฉฐเจ•เจธเจผเจจเจพเจ‚ เจจเฉ‚เฉฐ เจฌเจฃเจพเจ‰เจฃ เจฆเฉ€ เจฏเฉ‹เจ—เจคเจพ เจจเฉ‚เฉฐ เจœเฉ‹เฉœเจจ เจฆเฉ‡ เจฏเฉ‹เจ— เจนเฉˆ:
    เจตเจฟเฉฑเจš เจธเจพเจฐเฉ‡ เจซเฉฐเจ•เจธเจผเจจ เจธเจŸเฉ‹เจฐ เจ•เฉ€เจคเฉ‡ เจœเจพเจ‚เจฆเฉ‡ เจนเจจ ะพะฑัŠะตะบั‚ะต ะฟะพะด ะฝะฐะทะฒะฐะฝะธะตะผ methods
    เจ‡เจธ เจฒเจˆ เจ‡เจน เจ‡เฉฑเจ• เจซเฉฐเจ•เจธเจผเจจ เจฌเจฃเจพเจ‰เจฃ เจฒเจˆ เจ•เจพเจซเฉ€ เจนเฉ‹เจตเฉ‡เจ—เจพ registerMethod:

// parserExec.js at end
module.exports.registerMethod  =  function(name, func) {
  methods[name] =  func
}

เจคเฉเจนเจพเจจเฉ‚เฉฐ เจธเจฐเจตเจฐ เจฌเจฃเจพเจ‰เจฃ เจคเฉ‹เจ‚ เจฌเจพเจ…เจฆ เจ‡เจธ เจตเจฟเจงเฉ€ เจจเฉ‚เฉฐ เจตเจพเจชเจธ เจ•เจฐเจจ เจฆเฉ€ เจตเฉ€ เจฒเฉ‹เฉœ เจนเฉˆ

// index.js at require part
const { registerMethod } = require('./parserExec')

// index.js at end
module.exports.registerMethod  =  registerMethod

เจนเฉเจฃ, เจธเจฐเจตเจฐ เจฌเจฃเจพเจ‰เจฃ เจตเฉ‡เจฒเฉ‡, เจ…เจธเฉ€เจ‚ เจซเจพเจฐเจฎเฉˆเจŸเจฟเฉฐเจ— เจตเจฟเจงเฉ€เจ†เจ‚ เจจเฉ‚เฉฐ เจฐเจœเจฟเจธเจŸเจฐ เจ•เจฐ เจธเจ•เจฆเฉ‡ เจนเจพเจ‚เฅค เจ‰เจฆเจพเจนเจฐเจจ:

const  chat  =  require('.')
const { formatNick } =  require('./format')

chat({})

chat.registerMethod('hello', function(p, name){
  return  'Hi, '  +  formatNick(name) +  '!'
})

Ssh-เจ—เฉฑเจฒเจฌเจพเจค, เจญเจพเจ— 2

เจฎเจพเจฐเจ•เจกเจพเจ‰เจจ เจธเจฎเจฐเจฅเจจ

เจฎเจพเจฐเจ•เจกเจพเจ‰เจจ เจฌเจนเฉเจค เจธเฉเจตเจฟเจงเจพเจœเจจเจ• เจนเฉˆ, เจ‡เจธเจฒเจˆ เจ†เจ“ เจ‡เจธเจจเฉ‚เฉฐ เจตเจฐเจคเจฆเฉ‡ เจนเฉ‹เจ เจœเฉ‹เฉœเฉ€เจ เจŸเจฐเจฎเฉ€เจจเจฒ เจฎเจพเจฐเจ• เจ•เฉ€เจคเจพ

// format.js near require
const marked = require('marked');
const TerminalRenderer = require('marked-terminal');

marked.setOptions({
  renderer: new TerminalRenderer()
});

// format.js line 23
message = marked(message)

Ssh-เจ—เฉฑเจฒเจฌเจพเจค, เจญเจพเจ— 2

เจฌเฉ‹เจŸเจธ

เจ‡เจน เจ•เจฟเจตเฉ‡เจ‚ เจ•เฉฐเจฎ เจ•เจฐเฉ‡เจ—เจพ

let writeBotBob = chat.registerBot({
  name: 'botBob',

  onConnect(nick, write){
    write('@hello{' + nick + '}')
  },

  onDisconnect(nick, write){},

  onMessage(nick, message, write) {
    if(message == 'botBob!') write('I'm here')
  },

  onCommand(command, write) {
    write('Doing ' + command)
  }
})

onCommand เจฆเฉ€ เจตเจฐเจคเฉ‹เจ‚ เจ•เจฐเจ•เฉ‡ เจฌเฉเจฒเจพเจ‡เจ† เจœเจพ เจธเจ•เจฆเจพ เจนเฉˆ @bot(botBob){Command}

เจฌเฉ‹เจŸเจพเจ‚ เจจเจพเจฒ เจ•เฉฐเจฎ เจ•เจฐเจจ เจฒเจˆ เจธเจญ เจ•เฉเจ เจซเจพเจˆเจฒ เจตเจฟเฉฑเจš เจฆเฉฑเจธเจฟเจ† เจ—เจฟเจ† เจนเฉˆ:

let bots = []; // ะ’ัะต ะฑะพั‚ั‹

let onWrite = () => {}; 

function getWrite(bot) { // ะ“ะตะฝะตั€ะธั€ัƒะตั‚ ะผะตั‚ะพะด ะพั‚ะฟั€ะฐะฒะบะธ ัะพะพะฑั‰ะตะฝะธั ะดะปั ะฑะพั‚ะฐ
  return msg => {
    onWrite(bot.name, msg);
  };
}

module.exports.message = function message(nick, message) { // index.js ะฒั‹ะฟะพะปะฝะธั‚ ัั‚ัƒ ั„ัƒะฝะบั†ะธัŽ ะฟะพัะปะต ะพั‚ะฟั€ะฐะฒะบะธ ัะพะพะฑั‰ะตะฝะธั
  bots.forEach(bot => {
    try {
      bot.onMessage(nick, message, getWrite(bot));
    } catch (e) {
      console.error(e);
    }
  });
};

module.exports.connect = function message(nick) { // ะŸั€ะธ ัะพะตะดะธะฝะตะฝะธะธ
  bots.forEach(bot => {
    try {
      bot.onConnect(nick, getWrite(bot));
    } catch (e) {
      console.error(e);
    }
  });
};

module.exports.disConnect = function message(nick) { // ะŸั€ะธ ะพั‚ัะพะตะดะธะฝะตะฝะธะธ
  bots.forEach(bot => {
    try {
      bot.onDisconnect(nick, message, getWrite(bot));
    } catch (e) {
      console.error(e);
    }
  });
};

module.exports.command = function message(name, message) { // ะŸั€ะธ ะฒั‹ะฟะพะปะฝะตะฝะธะธ ะบะพะผะฐะฝะดั‹
  bots.forEach(bot => {
    if (bot.name == name) {
      try {
        bot.onCommand(message, getWrite(bot));
      } catch (e) {
        console.error(e);
      }
    }
  });
};

module.exports.registerBot = function(bot) {
  bots.push(bot);
  return  getWrite(bot)
};

module.exports.onMessage = func => {
  onWrite = func;
};

Ssh-เจ—เฉฑเจฒเจฌเจพเจค, เจญเจพเจ— 2

เจคเฉเจธเฉ€เจ‚ เจฌเฉ‹เจŸเจพเจ‚ เจจเจพเจฒ เจ•เฉ€ เจ•เจฐ เจธเจ•เจฆเฉ‡ เจนเฉ‹:

  • เจฒเฉ‹เจก เจฎเจพเจจเฉ€เจŸเจฐ
  • เจตเฉฐเจกเฉ‹
  • เจŸเจพเจธเจ• เจฌเฉ‹เจฐเจก

เจนเฉˆเจธเจผ เจ…เจคเฉ‡ เจจเจฎเจ•

ssh เจ•เฉเฉฐเจœเฉ€เจ†เจ‚ เจ•เจฟเจ‰เจ‚ เจจเจนเฉ€เจ‚? เจ•เจฟเจ‰เจ‚เจ•เจฟ เจตเฉฑเจ–-เจตเฉฑเจ– เจกเจฟเจตเจพเจˆเจธเจพเจ‚ 'เจคเฉ‡ ssh เจ•เฉเฉฐเจœเฉ€เจ†เจ‚ เจตเฉฑเจ–เจฐเฉ€เจ†เจ‚ เจนเฉ‹เจฃเจ—เฉ€เจ†เจ‚
เจšเจฒเฉ‹ เจ‡เฉฑเจ• เจซเจพเจˆเจฒ เจฌเจฃเจพเจˆเจ เจœเฉ‹ เจชเจพเจธเจตเจฐเจก เจฆเฉ€ เจœเจพเจ‚เจš เจ…เจคเฉ‡ เจฌเจฃเจพเจ‰เจฃ เจฒเจˆ เจœเจผเจฟเฉฐเจฎเฉ‡เจตเจพเจฐ เจนเฉ‹เจตเฉ‡เจ—เฉ€

// crypto.js
const crypto = require('crypto');

function genRandomString(length) {
  return crypto
    .randomBytes(Math.ceil(length / 2))
    .toString('hex')
    .slice(0, length);
}

function sha512(password, salt){
  const hash = crypto.createHmac('sha512', salt); /** Hashing algorithm sha512 */
  hash.update(password);
  const value = hash.digest('hex');
  return value
};

function checkPass(pass, obj){
  return obj.password == sha512(pass, obj.salt)
}

function encodePass(pass){
  const salt = genRandomString(16)
  return JSON.stringify({
    salt,
    password: sha512(pass, salt)
  })
}

module.exports.encodePass = encodePass
module.exports.checkPass = checkPass

เจชเจพเจธเจตเจฐเจก เจจเฉ‚เฉฐ เจจเจฎเจ• เจ…เจคเฉ‡ เจนเฉˆเจธเจผ เจ•เจฐเจจ เจฒเจˆ เจตเฉ€ เจ‡เฉฑเจ• เจธเจ•เฉเจฐเจฟเจชเจŸ

// To generate password run node ./encryptPassword password
const { encodePass } =require('./crypto')
console.log(encodePass(process.argv[2]))

เจ…เจธเฉ€เจ‚ user.json เจตเจฟเฉฑเจš เจ…เฉฑเจชเจกเฉ‡เจŸ เจ•เจฐเจฆเฉ‡ เจนเจพเจ‚ เจ…เจคเฉ‡ lobby.js เจตเจฟเฉฑเจš เจคเฉเจฒเจจเจพ เจ•เจฐเจจ เจฆเฉ€ เจฌเจœเจพเจ เจ…เจธเฉ€เจ‚ checkPassword เจฆเฉ€ เจตเจฐเจคเฉ‹เจ‚ เจ•เจฐเจฆเฉ‡ เจนเจพเจ‚

เจจเจคเฉ€เจœเจพ

เจจเจคเฉ€เจœเฉ‡ เจตเจœเฉ‹เจ‚, เจธเจพเจกเฉ‡ เจ•เฉ‹เจฒ เจกเจฟเจœเจผเจพเจˆเจจ เจธเจฎเจฐเฉฑเจฅเจพเจตเจพเจ‚ เจ…เจคเฉ‡ เจฌเฉ‹เจŸเจพเจ‚ เจฆเฉ‡ เจจเจพเจฒ ssh เจฐเจพเจนเฉ€เจ‚ เจ—เฉฑเจฒเจฌเจพเจค เจนเฉเฉฐเจฆเฉ€ เจนเฉˆเฅค
เจ…เฉฐเจคเจฟเจฎ เจญเฉฐเจกเจพเจฐ

เจธเจฐเฉ‹เจค: www.habr.com

เจ‡เฉฑเจ• เจŸเจฟเฉฑเจชเจฃเฉ€ เจœเฉ‹เฉœเฉ‹