Привет, Хабр. Это 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) + '!'
})
Поддержка 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)
Боты
Как это будет работать
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;
};
Что можно сделать с ботами:
- Монитор нагрузки
- 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 с возможностями по оформлению и ботами.
Финальный репозиторий
Комментарии (11)
gavk
16.09.2019 07:26А можно сделать как в IRC. Спросил у бота, что у него есть из файлов и скачал.
maximmasterr Автор
16.09.2019 07:54Работа с файлами не реализовано, но можно сделать чтобы бот сообщал ссылки на файлы которые у него есть
AlexGluck
Ключи всё таки надёжнее. Можно множество ключей для одного аккаунта поддерживать. Поэтому за отсутствие ключей минус.
Обмен файлами всё таки стоит попробовать реализовать. На сервере при подключении поднимается sftp в чруте из комплекта openssh с лимитом на общий размер хранения, файлам ттл устанавливается на сутки, потом файл удаляется.
maximmasterr Автор
Несколько ключей хранить сложнее, да и проверка тоже занимает время
С sftp проблема в том что придётся реализовать весь протокол чтение, запись, список файлов, информация о файле, проще понять чисто готовой sftp сервер, и через cron в полночь чистить директорию
AlexGluck
Всё равно ключи на базу верни)
mayorovp
А зачем sftp, чем применительно к чату scp не устроил?
maximmasterr Автор
Scp копирует через sftp
mayorovp
scp — это отдельный протокол
maximmasterr Автор
В таком случае в ssh2 не реализована его поддержка
mayorovp
Там просто exec запрашивается. Поддержка exec у ssh2 есть.
AlexGluck
Это вопрос реализации. Я не знаю адекватных аргументов для реализации, кроме стоимости разработки.