Для тех, кто еще не запустил конвейер по производству веб-приложений, я покажу, насколько это просто и быстро.
Именно для скорости я взял «скоростную» связку webix+databoom.

С помощью webix мы будем разрабатывать наш фронт-энд, а databoom послужит бэк-эндом.

Что в итоге должно получиться? Приложеньице, с помощью которого два (или более?) пользователя смогут обмениваться информацией не подкармливая свою паранойю.

Набор элементов следующий:
  • Текстовое поле для сообщения
  • Поле для псевдонима
  • Кнопка отправки сообщения
  • Сам список сообщений
  • Дополнительные опции


Начнем с фронт-энда


Подключим webix и накидаем разметку будущего приложения
webix.ui(
		{rows:[
			{view:'toolbar', cols:[
				// Тулбар
			]},
			// Сообщения,
			{view: 'resizer'},
			{view:'form', elements:[
				{cols:[
					// Текстовое поле
					{rows:[
						// Псевдоним (никнейм),
						// Кнопка отправки
					]}
				]}
			]}
		]}
	)


Пока все просто. С помощью вышеприведенного кода мы создаем разметку нашего приложения.
После подключения библиотеки webix инициализация происходит в методе ui() объекта webix.
В качестве параметра он принимает объект с описанием структуры приложения.
Все названия говорящие: rows — массив строк, cols — массив колонок, view — компонент webix.

Теперь вместо комментариев надо вставить нужные нам компоненты вебикса, пойдем сверху вниз.

Тулбар представляет собой набор элементов панели инструментов. Нам понадобятся только кнопки:
{view:'toolbar', cols:[
	{view:'button', value:'Удалить', align:'right', width:100, click:function(){}},
	{view:'button', value:'Расшифровать выделенные', width:200, click:function(){}}
]}

Позже мы опишем их функции, а пока выведем на экран все необходимые элементы.
Самым подходящим для вывода сообщений (учитывая связку с databoom) я посчитал компонент datatable
{view:"datatable", id:'datatableCblp', url: data, select:'row', multiselect:true, columns:[
	{id:'from', header:['От кого']},
	{id:'msg', header:['Сообщение']}
]}

В параметре select указываем тип выделения (строка/ячейка/столбец, в нашем случае строка), это нам понадобится для реализации возможности удалять сообщения и дешифровывать выборочно.
Параметр multiselect отвечает за возможность выделять несколько строк (с шифтом).
Массив columns описывает то, какие колонки будут в нашей таблице. Для нашего простейшего варианта остановимся на имени отправителя и тексте сообщения.

Элементы формы (поля и кнопки) расписывать не буду, ту все предельно просто
{view:'form', elements:[
	{cols:[
		{ view:"textarea", label:"Сообщение", id:'Message'},
		{rows:[
			{ view:"text", label:"Псевдоним", id:'NickName'},
			{ view:"text", label:"Ключ", id:'CryptoKey'},
			{ view:"button", value:"Отправить", click:function(){}}
		]}
	]}
]}


На этом размечать визуальную часть закончим, перейдем к реализации технической стороны вопроса.

DataBoom


Чтобы начать пользоваться базой данных, вам необходимо зарегистрироваться на сайте, после чего вам придет письмо со ссылкой в административную панель вашей базы.

Здесь нам нужно сделать несколько манипуляций:

  • Разрешить всем пользователям читать данные из базы
  • Все


Для осуществления первого пункта ставим условия для группы пользователей anonymus
{"GET":{"*":true},"PUT":{"*":true},"DELETE":{"*":true}}

Все можно, все true.

Для управления базой данных из нашего приложения необходимо подключить скрипт
https://databoom.space/databoom.js

После его подключения создадим объект базы
db = databoom(config.baseHost, config.baseName);


Параметры, которые на этом этапе от вас требуются — это «хост» и «имя базы».
В письме databoom прислал вам ссылку на вашу базу данных, моя выглядит так:
Database URL: https://t014.databoom.space/api1/b014


Хостом является домен, включая «http(s)». А имя базы написано в конце, у нас это «b014».
После того, как объект базы данных инициализирован, мы можем описать функцию отправки сообщения на сервер:
{ view:"button", value:"Отправить", click:function(){
	var newData = {};
	newData.from = $$('NickName').getValue()
	newData.msg = $$('Message').getValue()
	db.save(config.collection, newData);
}}


Обращаться к объектам вебикса можно с помощью $$, осуществляя селектор по id, который мы указываем описании компонента (этот id не имеет ничего общего с id DOM элемента).

db.save() сохраняет данные в базу. Первым параметром мы указываем «коллекцию». Считайте это названием таблицы в базе данных, если угодно. Восхищение вызывает тот факт, что ее не надо создавать ни в админке databoom, ни из скрипта, она просто есть. Любая. В качестве коллекции можно указать произвольную (почти) строку, главное ее запомнить, мы еще будем к ней обращаться.

Хорошо, сообщение на сервер отправили, пришло время его считать. Для этого у нас служит параметр url компонента datatable
data = webix.proxy("databoomtree", config.basePath);

{view:"datatable", id:'datatableCblp', url: data, select:'row', multiselect:true, columns:[
	{id:'from', header:['От кого']},
	{id:'msg', header:['Сообщение']}
]}

В параметре url мы указываем вебикс-прокси объект, аргументом которому будет путь до нужной коллекции (я назвал ее crypto)
https://t014.databoom.space/api1/b014/collections/crypto

И вот мы уже получаем хранящиеся на сервере сообщения. Давайте немного запутаем врагов, внеся капельку криптографии. Можно использовать любой алгоритм шифрования по ключу, я использовал один из простых.
Код
define([''], function(){

	var сaesar = function (text, key, decode) {
	    var textLetter, keyLetter, result = "", conv = decode ? -1 : 1;
	    key = key ? key : " ";
	    for (textLetter = keyLetter = 0; textLetter < text.length; textLetter++, keyLetter++) {
	        if (keyLetter >= key.length) keyLetter = 0;
	            result += String.fromCharCode( text.charCodeAt(textLetter) + conv * key.charCodeAt(keyLetter) );
	 
	    }
	    return result
	}

	var crypt = {
		on: function(text, key){
			return сaesar(text, key);
		},
		off: function(text, key){
			return сaesar(text, key, true);
		}
	}

	return crypt;

});


Шифровать, разумеется, будем до отправки на сервер (сохранения в базу). Внесем некоторые изменения, добавив поле ввода ключа:
{ view:"button", value:"Отправить", click:function(){
	var newData = {};
	newData.from = crypt.on($$('NickName').getValue(), $$('CryptoKey').getValue()); // crypt
	newData.msg = crypt.on($$('Message').getValue(), $$('CryptoKey').getValue());  // crypt
	db.save(config.collection, newData);
}}


Обратите внимание, что ключи, которые мы записываем в базу (from/msg) совпадают с id'ами, столбцов нашей datatable.

Понять и прочесть


Так как мы знаем, каким ключем шифрования пользуется наш собеседник (в этом и задумка), мы можем прочитать получаемые с сервера зашифрованные сообщения. Опишем функцию кнопки «расшифровать выделенные»:
{view:'button', value:'Расшифровать выделенные',width:200, click:function(){
	var sel = $$("datatableCblp").getSelectedId(); // Выделенная ячейка
	if(!Array.isArray(sel)){
		var row = $$("datatableCblp").getItem(sel.row); // Вычисляем выделенную строку
		row['msg'] = crypt.off(row.msg); // Раскриптовываем
		row['from'] = crypt.off(row.from); // Раскриптовываем
		$$("datatableCblp").updateItem(sel.row, row); // Заменяем данные в наших строках на расшифрованные
	}else{
                 // Аналогично для каждой выделенной строки
	}
}}


Заключение


Надеюсь, вы убедились, что создавать нечто не самое грандиозное весьма просто.
В числе прочего мы только что дали возможность разным людям общаться через один месенджер и не мешать друг другу. За исключением случая, если все решат, что их ключ «1234» самый классный.

Практики вам много и разной (новичкам).

Материалы




Благодарности


  • @databoom за удобнейшую реализацию связки с webix (у меня пришлось усложнить в виду промежуточной обработки информации перед сохранением)
  • @Skaner за обучалку касаемо публикации такого рода приложений через гугл диск

Комментарии (31)


  1. beaverBox
    27.08.2015 08:09

    Смотрю в сторону webix уже недели две, попробую-ка его на ощупь.
    Мизерные придирки к коду:

    • зачем подключаете gulp-livereload если не используете его?
    • добавьте .gitignore для исключения из репы папки node_modules/
    • сам webix хорошо тянется с bower


    1. seokirill
      27.08.2015 10:20

      Конструктивнейший комментарий!
      Как не использую livereload?

      gulp.task('connect', function() {
        connect.server({
          root: 'public',
          livereload: true
        });
      });
      


      node_modules зачем исключать?
      На основе package.json их можно подтянуть?


      1. NeXTs_od
        27.08.2015 10:39
        +1

        Да как-то не принято на гитхаб заливать содержимое node_modules. Там же полно зависимостей, да и какой смысл так делать?
        npm install вписали — все зависимости из package.json подтянулись


        1. seokirill
          27.08.2015 10:52
          +1

          Учел. Больше так не буду.


      1. beaverBox
        27.08.2015 12:41

        В данном случае livereload: true является частью API gulp-connect.


        1. beaverBox
          27.08.2015 12:52
          +1

          И

          node_modules зачем исключать?
          На основе package.json их можно подтянуть?

          Самым штатным образом:
          npm install
          


          1. seokirill
            27.08.2015 13:02

            Уже записал себе, благодарю


            1. Mithgol
              28.08.2015 11:23

              Рекомендую всё же употреблять для этой цели команду «npm install --production» вместо более простого варианта «npm install», потому что этот последний занимается и установкою devDependencies, а не одних только обыкновенных зависимостей.


  1. inkvizitor68sl
    27.08.2015 13:12
    +1

    Мессенджер для параноиков — это ssh-chat, поднимаемый каждый день на новом сервере. Ну и с авторизацией по ключам, конечно же.


    1. klirichek
      27.08.2015 19:18
      +1

      Ну это для «мягких» параноиков. А то вдруг там руткит в ring0, прошитый прямо в BIOS?
      Лучше на микроконтроллере (без возможности виртуализации), в bare-metal, чтоб выдавал во внешний интерфейс уже зашифрованные пакеты. Типа клавиатуры для ввода пин-кода в банкомате.


      1. inkvizitor68sl
        27.08.2015 19:19
        +1

        Для таких параноиков лучше вообще без мессенджера общаться)


        1. seokirill
          28.08.2015 01:50

          Да, оставлять телефоны дома и общаться в парке лично, учитывая последние статьи о прослушке. Но мало кто настолько интересует ФСБ. А если уж на карандаше, то не стоит совершать столь опасных дел. Головой-то тоже думать надо.


    1. redmanmale
      28.08.2015 11:02

      Вполне достаточно Tox'а.


  1. Glebcha
    27.08.2015 23:08

    Для облегчения жизни форкающему и ближнему рекомендую добавить в package.json скрипты для установки глобально плагинов галпа если таковые отстуствуют и создания символических ссылок, чтобы не тянуть все модули каждый раз в каждый новый проект.
    Пример можно у меня подсмотреть.

    Также советую добавить обработку ошибок при сборке с уведомлениями (gulp-notify). Тоже в гисте наличиствует.

    И вопрос — зачем овер 1к строк стилей в одной мешанине? Может лучше препроцессор какой-нибудь и фрагментировать?


    1. seokirill
      28.08.2015 01:48

      Вопрос не понял. Стили склеиваются и минифицируются галпом. При разработке все обычно. Препроцессор попозже изучу, в очереди стоит на изучение.


      1. Glebcha
        28.08.2015 05:58

        У вас там один файл стилей объемом более 1400 строк. Такое сложно читать уже, а еще боли добавляет приведение каждого выражения к однострочному варианту.
        Разбейте на несколько файлов (по блочному контексту или еще как-то), сделайте ваши труды читаемыми.
        В публичном репозитории обычно самый полный вариант для разработки (без минификаторов и прочей байды), чтобы все могли ознакомиться с кодом, настроить сборку так как им нужно.


        1. beaverBox
          28.08.2015 07:58

          Там стили — от webix, своих стилей нет.

          рекомендую добавить в package.json скрипты для установки глобально плагинов галпа

          Зачем глобально-то? Gulp — сборщик одного проекта, зачем тащить всё в систему?

          чтобы не тянуть все модули каждый раз в каждый новый проект

          С нормальным .gitignore ничто никуда не тянется, проект в репах остается чистым.


          1. Glebcha
            28.08.2015 20:52

            Причем тут .gitignore? Понятно, что node_modules там будет, я писал про «один раз поставил пакеты глобально и в каждый последующий проект ни один из них не тянешь (кажется с 10-й ноды такое), лишь создаешь символическией ссылки». Gulp используется не только на одном проекте, это весьма популярный инструмент.
            Так-то вообще можно минифицированные конкатенированные выложить, тоже ничего ведь, да? Только кто форкнет и вообще посмотрит, его же не перепилишь как нужно тебе, а не автору.


            1. seokirill
              29.08.2015 01:12

              Не вполне понял, то есть все установить глобально заранее? Типа все предусмотреть? Есть ли от этого профит?


              1. Glebcha
                29.08.2015 10:06

                Конечно есть — следующие проекты можно собирать без установки локально пакетов в директорию проекта, лишь создать символические ссылки. Место на жестком диске не уходит и пакеты всегда можно использовать где угодно. Я специально заметил, что это я использую только для плагинов галпа (еще и основных модулей, общих для всех моих проектов), так как сборщик используется везде.


                1. seokirill
                  29.08.2015 12:30

                  Подскажи-ка где про символические ссылочки почитать


        1. seokirill
          28.08.2015 10:28

          А, понял, о чем вы. Так это файл стилей webix'а. В этот раз я ни строчки стилей не писал, забыл совсем.


  1. Mithgol
    28.08.2015 11:26
    +2

    Я чего-то не понимаю, кажется. Как должен рассуждать параноик, чтобы начать хранить свои данные в облаке databoom.space вместо собственного компьютера?


    1. seokirill
      28.08.2015 11:55
      +1

      Они ж там шифрованные, да и есть кнопка «удалить»


      1. zharikovpro
        28.08.2015 18:26
        +1

        Параноик должен понимать, что кнопка может быть бутафорской, а шифрование лишь на словах.


        1. seokirill
          29.08.2015 01:10
          +1

          Так если ввести другой ключ шифрования, то прочитать нельзя. Это можно протестировать имея 2 вкладки браузера.
          И если нельзя прочитать, не имея ключа нужного, это должно обнадеживать.


          1. zharikovpro
            29.08.2015 01:23

            > И если нельзя прочитать, не имея ключа нужного, это должно обнадеживать.

            Но данные-то отдаются «на сторону»! Ни тебе бэкапов нормальных, ни полного контроля. Так что речь шла исключительно об ассоциациях, которые вызывает слово «паранойя»)


            1. seokirill
              29.08.2015 02:56

              Если паранойя тотальная (ничему не верю), то тут уж не спасет ничто: каждый встречный агент, все телефоны — жучки, комп прошит врагами — то, скорее всего, человек вообще с компами дело не имеет, если рассуждать логически. А раз пользуется, значит степень паранойи пока не критическая. Для таких подойдут всяческие анонимайзеры, торы и пр.


          1. isden
            29.08.2015 10:48

            > И если нельзя прочитать, не имея ключа нужного, это должно обнадеживать.

            Вы реализацию их алгоритмов шифрования видели? Вполне может быть, например, вот так:

            — Есть некий мастер-ключ.
            — На самом деле все лежит в открытом виде, а конечному пользователю лишь эмулируется описанное поведение.
            — Шифрование честное, но производится каким-нибудь XOR на основе первых 2 символов хэша пользовательского ключа.


      1. Glebcha
        29.08.2015 10:09

        Они там и это уже не безопасно.


    1. b1rdex
      01.09.2015 14:54

      А как вы себе представляете средство общения через интернет, без использования сети для хранения/передачи данных?