Ssh-chat, Ρ‡Π°ΡΡ‚ΡŒ 2

ΠŸΡ€ΠΈΠ²Π΅Ρ‚, Π₯Π°Π±Ρ€. Π­Ρ‚ΠΎ 2 ΡΡ‚Π°Ρ‚ΡŒΡ ΠΈΠ· Ρ†ΠΈΠΊΠ»Π° ssh-chat.

Π§Ρ‚ΠΎ ΠΌΡ‹ сдСлаСм:

  • Π”ΠΎΠ±Π°Π²ΠΈΠΌ Π²ΠΎΠ·ΠΌΠΎΠΆΠ½ΠΎΡΡ‚ΡŒ создания своих Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠΉ оформлСния
  • Π”ΠΎΠ±Π°Π²ΠΈΠΌ ΠΏΠΎΠ΄Π΄Π΅Ρ€ΠΆΠΊΡƒ markdown
  • Π”ΠΎΠ±Π°Π²ΠΈΠΌ ΠΏΠΎΠ΄Π΄Π΅Ρ€ΠΆΠΊΡƒ Π±ΠΎΡ‚ΠΎΠ²
  • Π£Π²Π΅Π»ΠΈΡ‡ΠΈΠΌ Π±Π΅Π·ΠΎΠΏΠ°ΡΠ½ΠΎΡΡ‚ΡŒ ΠΏΠ°Ρ€ΠΎΠ»Π΅ΠΉ(Ρ…Π΅Ρˆ ΠΈ соль)
    Π£Π²Ρ‹, Π½ΠΎ ΠΎΡ‚ΠΏΡ€Π°Π²ΠΊΠΈ Ρ„Π°ΠΉΠ»ΠΎΠ² Π½Π΅ Π±ΡƒΠ΄Π΅Ρ‚

ΠŸΠΎΠ»ΡŒΠ·ΠΎΠ²Π°Ρ‚Π΅Π»ΡŒΡΠΊΠΈΠ΅ Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠΈ оформлСния

На Π΄Π°Π½Π½Ρ‹ΠΉ ΠΌΠΎΠΌΠ΅Π½Ρ‚ Ρ€Π΅Π°Π»ΠΈΠ·ΠΎΠ²Π°Π½Π° ΠΏΠΎΠ΄Π΄Π΅Ρ€ΠΆΠΊΠ° ΡΠ»Π΅Π΄ΡƒΡŽΡ‰ΠΈΡ… Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠΉ оформлСния:

  • @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-chat, Ρ‡Π°ΡΡ‚ΡŒ 2

ΠŸΠΎΠ΄Π΄Π΅Ρ€ΠΆΠΊΠ° markdown

Markdown Π½Ρƒ ΠΎΡ‡Π΅Π½ΡŒ ΡƒΠ΄ΠΎΠ±Π΅Π½ Ρ‚Π°ΠΊ Ρ‡Ρ‚ΠΎ Π΄ΠΎΠ±Π°Π²ΠΈΠΌ Π΅Π³ΠΎ с ΠΏΠΎΠΌΠΎΡ‰ΡŒΡŽ marked terminal

// 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-chat, Ρ‡Π°ΡΡ‚ΡŒ 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-chat, Ρ‡Π°ΡΡ‚ΡŒ 2

Π§Ρ‚ΠΎ ΠΌΠΎΠΆΠ½ΠΎ ΡΠ΄Π΅Π»Π°Ρ‚ΡŒ с Π±ΠΎΡ‚Π°ΠΌΠΈ:

  • ΠœΠΎΠ½ΠΈΡ‚ΠΎΡ€ Π½Π°Π³Ρ€ΡƒΠ·ΠΊΠΈ
  • Deploy
  • Доску Π·Π°Π΄Π°Ρ‡

Π₯Сш ΠΈ соль

ΠŸΠΎΡ‡Π΅ΠΌΡƒ Π½Π΅ 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]))

ОбновляСм Π² users.json ΠΈ вмСсто сравнСния Π² lobby.js ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΡƒΠ΅ΠΌ checkPassword

Π˜Ρ‚ΠΎΠ³

Π’ Ρ€Π΅Π·ΡƒΠ»ΡŒΡ‚Π°Ρ‚Π΅ Ρƒ нас Π΅ΡΡ‚ΡŒ Ρ‡Π°Ρ‚ ΠΏΠΎ ssh с возмоТностями ΠΏΠΎ ΠΎΡ„ΠΎΡ€ΠΌΠ»Π΅Π½ΠΈΡŽ ΠΈ Π±ΠΎΡ‚Π°ΠΌΠΈ.
Π€ΠΈΠ½Π°Π»ΡŒΠ½Ρ‹ΠΉ Ρ€Π΅ΠΏΠΎΠ·ΠΈΡ‚ΠΎΡ€ΠΈΠΉ

Π˜ΡΡ‚ΠΎΡ‡Π½ΠΈΠΊ: habr.com

Π”ΠΎΠ±Π°Π²ΠΈΡ‚ΡŒ ΠΊΠΎΠΌΠΌΠ΅Π½Ρ‚Π°Ρ€ΠΈΠΉ