From 5f565474a4ed6a4894a6b02d0672ca4467ed9a59 Mon Sep 17 00:00:00 2001 From: Denis Davydov Date: Wed, 9 May 2018 10:08:12 +0300 Subject: [PATCH 1/7] init --- README.md | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) create mode 100644 README.md diff --git a/README.md b/README.md new file mode 100644 index 0000000..3476c21 --- /dev/null +++ b/README.md @@ -0,0 +1,19 @@ +# HyperboriaIM + +**HyperboriaIM** - это защищенный мессенджер, который будет функционировать в сети *Hyperboria* (cjdns). Сам мессенджер будет разделен на две части - серверная часть и клиентская часть. Серверная часть будет функционировать на компьютере пользователя. В серверной части будет реализована вся логика мессенджера. Клиентская часть будет просто вызывать функции (API) серверной. + +### Чат + +При создании чата, будет генерироваться ключ шифрования и отправляться участникам чата (или получателю, если это не групповой чат). После чего, все сообщения в чате будут шифроваться этим ключом шифрования. + +### Структура сообщения в JSON + +{ + "msgID": 1, + "peerID":"fcec:ae97:8902:d810:6c92:ec67:efb2:3ec5", + "msgText":"VJU02Om8ow==" +} + +**msgID** - ID сообщения в чате +**peerID** - IPv6 отправителя сообщения +**msgText** - зашифрованный текст сообщения (метод шифрования - Blowfish, ключ шифрования - тот, который был создал в начале чата.) \ No newline at end of file From b8d2b9198a9cd5bcffabed42b61579b6da090225 Mon Sep 17 00:00:00 2001 From: CupIvan Date: Wed, 9 May 2018 14:39:18 +0300 Subject: [PATCH 2/7] =?UTF-8?q?=D0=BD=D0=B0=D0=B1=D1=80=D0=BE=D1=81=D0=BE?= =?UTF-8?q?=D0=BA=20API?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- API.md | 86 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 86 insertions(+) create mode 100644 API.md diff --git a/API.md b/API.md new file mode 100644 index 0000000..18941f7 --- /dev/null +++ b/API.md @@ -0,0 +1,86 @@ +P2P-мессенджер. Протокол обмена +=============================== + +## Структура сети: +Связь между узлами - точка-точка + +GUI - Сервер ==== Сервер - GUI + +GUI - примитивная программа под Linux/Window/Android, которая умеет отображать сообщения и обмениваться с сервером. +Сервер - как правило сидит на localhost, принимает сообщения от GUI и переправляет на другой сервер. +В Windows/Linux GUI и серверная часть могут быть объединены. +Разделение GUI и Сервера позволяет также отправлять сообщения тем, кто оффлайн (например сервер крутится на роутере и он всё время online). +На сервере также хранится история переписки. + +У сервера есть список контактов (друзей), в формате: +``` +{ + "адрес1": {nick: "", last_online: "", last_connect: "", can_resend: 1, key: "", other_info:... } + ... +} +``` +Поле адрес - это адрес сервера, куда отправляем. Может быть как ipv4, так и ipv6 адрес в сети cjdns. + + +## Протокол обмена +Обмен сообщениями ведётся по GET/POST http протоколу в формате JSON, что позволяет делать GUI прямо в браузере. +При любой успешной отправке данных обновляем поле last_connect у контакта. +Во всех сообщениях нужно указывать ключ, если он не подойдёт - то сообщение отбрасывается. + +1. Добавление в друзья +Используется, чтобы установить связь с контактом. Для этого запрашиваем у него ключ доступа, предварительно отправив свой. +``` +{action: "handshake", key: "пароль"} +``` +ответ +``` +{status: 1} +``` +Когда один отправил запрос - то второй может отправить свой ключ и тогда сервера смогут общаться друг с другом. + +2. Отправка сообщения: +``` +{action:"send", from: "адрес", to: "адрес", message: "сообщение", timestamp: "время", enctype: "", key: "" } +``` +ответ: +``` +{status: 1} +``` +Сообщение может быть зашифровано, метод шифрования в поле enctype. +Если нет ответа, то сохраняем сообщение у себя в истории, чтобы потом переотправить. +`status==1` - доставлено, другой - недоставлено (помечаем как недоставлено + +3. Пинг - проверка онлайн +Если прошло время больше чем last_connect + 1 минута, от отправляем запрос +``` +{action: "ping"} +``` +ответ: +``` +{action: "pong"} +``` + +4. Если у нас есть сообщения для адреса и он онлайн (last_connect < 1 минуты), то передаём их +Если для этого адрес в базе есть недоставленные сообщения, то отправляем такой запрос: +``` +{action: "history", messages:[{},{},{}...]} +``` +ответ +``` +{status:[1,1,1,0,1]} +``` +В ответ приходит массив с 1 или 0. Если 1 - сообщение сохранено успешно, 0 - ошибка и его нужно потом переотправить. + +5. Отправить сообщение для другого абонента (это нужно чтобы отправлять тем, кто в offline) +Если человек, которому мы отправляем сообщение offline - то во-первых оно сохраняется у себя на сервере, для последующей отправки. +Во-вторых, можно попросить какого-то друга его переотправить. Для этого выбираем случайно несколько друзей из списка контактов, у которых can_resend == 1 и отправляем им запрос. +Для ретрансляции можно также использовать свой сервер в интернете, нужно просто его добавить в контакты. +``` +{action: "resend", ...} +``` +Параметры такие же как и для send +ответ +``` +{status: 1} +``` +Если status: 0 - то эта нода не желает пересылать сообщения и ей повторно отправлять не нужно. From 53d6ce9697e3482ef5f823a0bca14580a65b5fba Mon Sep 17 00:00:00 2001 From: ChronosX88 Date: Wed, 9 May 2018 14:41:45 +0300 Subject: [PATCH 3/7] Update API.md --- API.md | 70 +++++++++++++++++++++++++++++++------------------------ README.md | 12 +--------- 2 files changed, 40 insertions(+), 42 deletions(-) diff --git a/API.md b/API.md index 18941f7..3e6e3b7 100644 --- a/API.md +++ b/API.md @@ -1,4 +1,4 @@ -P2P-мессенджер. Протокол обмена +Протокол обмена. =============================== ## Структура сети: @@ -13,9 +13,9 @@ GUI - примитивная программа под Linux/Window/Android, к На сервере также хранится история переписки. У сервера есть список контактов (друзей), в формате: -``` +```json { - "адрес1": {nick: "", last_online: "", last_connect: "", can_resend: 1, key: "", other_info:... } + "адрес1": { "nick":"", "last_online":"", "last_connect":"", "can_resend":1, "key":"", "other_info":... } ... } ``` @@ -29,58 +29,66 @@ GUI - примитивная программа под Linux/Window/Android, к 1. Добавление в друзья Используется, чтобы установить связь с контактом. Для этого запрашиваем у него ключ доступа, предварительно отправив свой. -``` -{action: "handshake", key: "пароль"} +```json +{ "action":"handshake", "key":"пароль" } ``` ответ -``` -{status: 1} +```json +{ "status": 1 } ``` Когда один отправил запрос - то второй может отправить свой ключ и тогда сервера смогут общаться друг с другом. -2. Отправка сообщения: -``` -{action:"send", from: "адрес", to: "адрес", message: "сообщение", timestamp: "время", enctype: "", key: "" } +### Отправка сообщения + +Структура сообщения в JSON: + +```json +{ "action":"send", "from":"адрес", "to":"адрес", "message":"сообщение", "timestamp":"время", "enctype":"", "key":"" } ``` ответ: -``` -{status: 1} +```json +{ "status": 1 } ``` Сообщение может быть зашифровано, метод шифрования в поле enctype. Если нет ответа, то сохраняем сообщение у себя в истории, чтобы потом переотправить. `status==1` - доставлено, другой - недоставлено (помечаем как недоставлено -3. Пинг - проверка онлайн +### Пинг - проверка онлайна + Если прошло время больше чем last_connect + 1 минута, от отправляем запрос -``` -{action: "ping"} + +```json +{ "action":"ping" } ``` ответ: -``` -{action: "pong"} +```json +{ "action":"pong" } ``` -4. Если у нас есть сообщения для адреса и он онлайн (last_connect < 1 минуты), то передаём их +Если у нас есть сообщения для адреса и он онлайн (last_connect < 1 минуты), то передаём их Если для этого адрес в базе есть недоставленные сообщения, то отправляем такой запрос: + +```json +{ "action": "history", "messages":[{},{},{}...] } ``` -{action: "history", messages:[{},{},{}...]} -``` -ответ -``` -{status:[1,1,1,0,1]} +ответ: +```json +{ "status":[1,1,1,0,1] } ``` В ответ приходит массив с 1 или 0. Если 1 - сообщение сохранено успешно, 0 - ошибка и его нужно потом переотправить. -5. Отправить сообщение для другого абонента (это нужно чтобы отправлять тем, кто в offline) -Если человек, которому мы отправляем сообщение offline - то во-первых оно сохраняется у себя на сервере, для последующей отправки. -Во-вторых, можно попросить какого-то друга его переотправить. Для этого выбираем случайно несколько друзей из списка контактов, у которых can_resend == 1 и отправляем им запрос. +### Отправление сообщения для другого абонента (это нужно чтобы отправлять тем, кто в offline) + +Если человек, которому мы отправляем сообщение offline - то, во-первых, оно сохраняется у себя на сервере, для последующей отправки. +Во-вторых, можно попросить какого-то друга его переотправить. Для этого выбираем случайно несколько друзей из списка контактов, у которых `can_resend == 1` и отправляем им запрос. Для ретрансляции можно также использовать свой сервер в интернете, нужно просто его добавить в контакты. -``` -{action: "resend", ...} + +```json +{ "action":"resend", ... } ``` Параметры такие же как и для send ответ +```json +{ "status":1 } ``` -{status: 1} -``` -Если status: 0 - то эта нода не желает пересылать сообщения и ей повторно отправлять не нужно. +Если `status == 0` - то эта нода не желает пересылать сообщения и ей повторно отправлять не нужно. diff --git a/README.md b/README.md index 3476c21..ac7ae34 100644 --- a/README.md +++ b/README.md @@ -6,14 +6,4 @@ При создании чата, будет генерироваться ключ шифрования и отправляться участникам чата (или получателю, если это не групповой чат). После чего, все сообщения в чате будут шифроваться этим ключом шифрования. -### Структура сообщения в JSON - -{ - "msgID": 1, - "peerID":"fcec:ae97:8902:d810:6c92:ec67:efb2:3ec5", - "msgText":"VJU02Om8ow==" -} - -**msgID** - ID сообщения в чате -**peerID** - IPv6 отправителя сообщения -**msgText** - зашифрованный текст сообщения (метод шифрования - Blowfish, ключ шифрования - тот, который был создал в начале чата.) \ No newline at end of file +По контактам будет создаваться сколько угодно чатов. Более подробно о технической части [тут](https://github.com/ChronosX88/HyperboriaIM-doc/blob/master/API.md). From 07ec7f4cd479c8d8a2318a276e519952ca77ec42 Mon Sep 17 00:00:00 2001 From: CupIvan Date: Wed, 9 May 2018 15:14:45 +0300 Subject: [PATCH 4/7] =?UTF-8?q?=D0=BF=D0=B5=D1=80=D0=B5=D0=B4=D0=B5=D0=BB?= =?UTF-8?q?=D0=B0=D0=BB=20handshake?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- API.md | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/API.md b/API.md index 3e6e3b7..2436f24 100644 --- a/API.md +++ b/API.md @@ -25,25 +25,26 @@ GUI - примитивная программа под Linux/Window/Android, к ## Протокол обмена Обмен сообщениями ведётся по GET/POST http протоколу в формате JSON, что позволяет делать GUI прямо в браузере. При любой успешной отправке данных обновляем поле last_connect у контакта. -Во всех сообщениях нужно указывать ключ, если он не подойдёт - то сообщение отбрасывается. +Если пришло сообщение от контакта, которого нет в адресной книге - то оно отбрасывается. +Исключения - запрос handshake. 1. Добавление в друзья -Используется, чтобы установить связь с контактом. Для этого запрашиваем у него ключ доступа, предварительно отправив свой. +Используется, чтобы установить связь с контактом. Тот кто хочет добавиться в друзья - отправляет такой запрос. ```json -{ "action":"handshake", "key":"пароль" } +{ "action":"handshake", "nick": "" } ``` ответ ```json { "status": 1 } ``` -Когда один отправил запрос - то второй может отправить свой ключ и тогда сервера смогут общаться друг с другом. +У другого абонента висит этот контакт в списке неавторизованных. Если он хочет его тоже добавить в друзья - отправляем ему свой handshake. Возможет вариант, когда сервер автоматически добавляет в друзья (публичный сервер для пересылки offline сообщений). ### Отправка сообщения Структура сообщения в JSON: ```json -{ "action":"send", "from":"адрес", "to":"адрес", "message":"сообщение", "timestamp":"время", "enctype":"", "key":"" } +{ "action":"send", "from":"адрес", "to":"адрес", "message":"сообщение", "timestamp":"время", "enctype":"" } ``` ответ: ```json From 856e8e42b0bc1ef77724f1e216b224aec42cd7e0 Mon Sep 17 00:00:00 2001 From: Denis Davydov Date: Wed, 9 May 2018 15:27:25 +0300 Subject: [PATCH 5/7] Update API.md --- README.md | 8 +------- API.md => doc/ru/API.md | 30 ++++++++++++++++++++++++------ 2 files changed, 25 insertions(+), 13 deletions(-) rename API.md => doc/ru/API.md (97%) diff --git a/README.md b/README.md index ac7ae34..2387d61 100644 --- a/README.md +++ b/README.md @@ -1,9 +1,3 @@ # HyperboriaIM -**HyperboriaIM** - это защищенный мессенджер, который будет функционировать в сети *Hyperboria* (cjdns). Сам мессенджер будет разделен на две части - серверная часть и клиентская часть. Серверная часть будет функционировать на компьютере пользователя. В серверной части будет реализована вся логика мессенджера. Клиентская часть будет просто вызывать функции (API) серверной. - -### Чат - -При создании чата, будет генерироваться ключ шифрования и отправляться участникам чата (или получателю, если это не групповой чат). После чего, все сообщения в чате будут шифроваться этим ключом шифрования. - -По контактам будет создаваться сколько угодно чатов. Более подробно о технической части [тут](https://github.com/ChronosX88/HyperboriaIM-doc/blob/master/API.md). +**HyperboriaIM** - это защищенный мессенджер, который будет функционировать в сети *Hyperboria* (cjdns). Сам мессенджер будет разделен на две части - серверная часть и клиентская часть. Серверная часть будет функционировать на компьютере пользователя. В серверной части будет реализована вся логика мессенджера. Клиентская часть будет просто вызывать функции (API) серверной. Более подробно о технической части [тут](https://github.com/ChronosX88/HyperboriaIM-doc/blob/master/API.md). diff --git a/API.md b/doc/ru/API.md similarity index 97% rename from API.md rename to doc/ru/API.md index 2436f24..c7b9808 100644 --- a/API.md +++ b/doc/ru/API.md @@ -1,7 +1,7 @@ -Протокол обмена. -=============================== +# Протокол обмена. ## Структура сети: + Связь между узлами - точка-точка GUI - Сервер ==== Сервер - GUI @@ -13,30 +13,37 @@ GUI - примитивная программа под Linux/Window/Android, к На сервере также хранится история переписки. У сервера есть список контактов (друзей), в формате: + ```json { "адрес1": { "nick":"", "last_online":"", "last_connect":"", "can_resend":1, "key":"", "other_info":... } ... } ``` + Поле адрес - это адрес сервера, куда отправляем. Может быть как ipv4, так и ipv6 адрес в сети cjdns. - ## Протокол обмена + Обмен сообщениями ведётся по GET/POST http протоколу в формате JSON, что позволяет делать GUI прямо в браузере. При любой успешной отправке данных обновляем поле last_connect у контакта. Если пришло сообщение от контакта, которого нет в адресной книге - то оно отбрасывается. Исключения - запрос handshake. -1. Добавление в друзья +### Добавление в друзья + Используется, чтобы установить связь с контактом. Тот кто хочет добавиться в друзья - отправляет такой запрос. + ```json { "action":"handshake", "nick": "" } ``` -ответ + +ответ: + ```json { "status": 1 } ``` + У другого абонента висит этот контакт в списке неавторизованных. Если он хочет его тоже добавить в друзья - отправляем ему свой handshake. Возможет вариант, когда сервер автоматически добавляет в друзья (публичный сервер для пересылки offline сообщений). ### Отправка сообщения @@ -46,10 +53,13 @@ GUI - примитивная программа под Linux/Window/Android, к ```json { "action":"send", "from":"адрес", "to":"адрес", "message":"сообщение", "timestamp":"время", "enctype":"" } ``` + ответ: + ```json { "status": 1 } ``` + Сообщение может быть зашифровано, метод шифрования в поле enctype. Если нет ответа, то сохраняем сообщение у себя в истории, чтобы потом переотправить. `status==1` - доставлено, другой - недоставлено (помечаем как недоставлено @@ -61,7 +71,9 @@ GUI - примитивная программа под Linux/Window/Android, к ```json { "action":"ping" } ``` + ответ: + ```json { "action":"pong" } ``` @@ -72,10 +84,13 @@ GUI - примитивная программа под Linux/Window/Android, к ```json { "action": "history", "messages":[{},{},{}...] } ``` + ответ: + ```json { "status":[1,1,1,0,1] } ``` + В ответ приходит массив с 1 или 0. Если 1 - сообщение сохранено успешно, 0 - ошибка и его нужно потом переотправить. ### Отправление сообщения для другого абонента (это нужно чтобы отправлять тем, кто в offline) @@ -87,9 +102,12 @@ GUI - примитивная программа под Linux/Window/Android, к ```json { "action":"resend", ... } ``` + Параметры такие же как и для send ответ + ```json { "status":1 } ``` -Если `status == 0` - то эта нода не желает пересылать сообщения и ей повторно отправлять не нужно. + +Если `status == 0` - то эта нода не желает пересылать сообщения и ей повторно отправлять не нужно. \ No newline at end of file From eadc19a6d8b5396b010d8ca26adf7bf0450631f8 Mon Sep 17 00:00:00 2001 From: CupIvan Date: Wed, 9 May 2018 17:26:46 +0300 Subject: [PATCH 6/7] =?UTF-8?q?=D0=BF=D1=80=D0=B8=D0=BC=D0=B5=D1=80=20?= =?UTF-8?q?=D1=80=D0=B5=D0=B0=D0=BB=D0=B8=D0=B7=D0=B0=D1=86=D0=B8=D0=B8=20?= =?UTF-8?q?=D0=BC=D0=B5=D1=81=D1=81=D0=B5=D0=BD=D0=B4=D0=B6=D0=B5=D1=80?= =?UTF-8?q?=D0=B0=20=D0=BD=D0=B0=20PHP?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- php/.gitignore | 2 ++ php/config.php | 4 +++ php/index.php | 5 +++ php/init.php | 10 ++++++ php/m/api.php | 23 ++++++++++++ php/m/db.php | 63 ++++++++++++++++++++++++++++++++ php/m/functions.php | 13 +++++++ php/m/send.php | 14 ++++++++ php/post.php | 80 +++++++++++++++++++++++++++++++++++++++++ php/server.conf.example | 1 + php/server.sh | 4 +++ php/tpl/chat.tpl | 10 ++++++ php/tpl/contact.tpl | 20 +++++++++++ php/tpl/contacts.tpl | 29 +++++++++++++++ php/tpl/dns.tpl | 16 +++++++++ php/tpl/dns_edit.tpl | 19 ++++++++++ php/tpl/index.tpl | 21 +++++++++++ php/tpl/messages.tpl | 18 ++++++++++ 18 files changed, 352 insertions(+) create mode 100644 php/.gitignore create mode 100644 php/config.php create mode 100644 php/index.php create mode 100644 php/init.php create mode 100644 php/m/api.php create mode 100644 php/m/db.php create mode 100644 php/m/functions.php create mode 100644 php/m/send.php create mode 100644 php/post.php create mode 100644 php/server.conf.example create mode 100755 php/server.sh create mode 100644 php/tpl/chat.tpl create mode 100644 php/tpl/contact.tpl create mode 100644 php/tpl/contacts.tpl create mode 100644 php/tpl/dns.tpl create mode 100644 php/tpl/dns_edit.tpl create mode 100644 php/tpl/index.tpl create mode 100644 php/tpl/messages.tpl diff --git a/php/.gitignore b/php/.gitignore new file mode 100644 index 0000000..3797243 --- /dev/null +++ b/php/.gitignore @@ -0,0 +1,2 @@ +db +server.conf diff --git a/php/config.php b/php/config.php new file mode 100644 index 0000000..b2a7257 --- /dev/null +++ b/php/config.php @@ -0,0 +1,4 @@ + $v) if (is_string($v)) $m[$k] = urldecode($v); + if (is_callable($handler)) $handler($m); + else require_once "tpl/$handler"; + } +} diff --git a/php/m/db.php b/php/m/db.php new file mode 100644 index 0000000..e0ef54f --- /dev/null +++ b/php/m/db.php @@ -0,0 +1,63 @@ + $_) + $data[$id] = $a + $data[$id]; + db_save($db, $data); +} + +function db_delete($db, $filter) +{ + $data = db_get($db); + foreach (db_search($db, $filter) as $id => $_) + unset($data[$id]); + db_save($db, $data); +} + +function db_search($db, $filter = []) +{ + $res = []; + foreach (db_get($db) as $id => $a) + { + foreach ($filter as $k => $v) + if ($a[$k] != $v) continue 2; + $res[$id] = $a; + } + return $res; +} + +function db_search_one($db, $filter) +{ + $res = db_search($db, $filter); + foreach ($res as $a) return $a; + return []; +} + +function db_get($db) +{ + $fname = "./db/$db.json"; + if (!file_exists($fname)) return []; + $db = @json_decode(@file_get_contents($fname), true); + return $db ?: []; +} + +function db_save($db, $data) +{ + $fname = "./db/$db.json"; + if (empty($data)) unlink($fname); + else + { + $st = json_encode($data, JSON_UNESCAPED_UNICODE); + if (!file_exists($x = dirname($fname))) mkdir($x, 0777, true); + if ($st) file_put_contents($fname, $st); + } +} diff --git a/php/m/functions.php b/php/m/functions.php new file mode 100644 index 0000000..705ea44 --- /dev/null +++ b/php/m/functions.php @@ -0,0 +1,13 @@ + ['method'=>'POST','header'=>"Connection: close\r\nContent-Length: $data_len\r\n", 'content'=>$data_url] + ]); + + $res = json_decode(@file_get_contents('http://'.$data['to'].'/messages/', false, $context), true); + return !empty($res); +} diff --git a/php/post.php b/php/post.php new file mode 100644 index 0000000..065ab23 --- /dev/null +++ b/php/post.php @@ -0,0 +1,80 @@ +time(), 'addr'=>$_SERVER['HTTP_HOST']]; + echo json_encode($a); + exit; +}); + +api_get('/contacts/ping', function(){ + foreach (db_search('contacts') as $a) + if ($a['addr'] != $_SERVER['HTTP_HOST']) // COMMENT: сами себе не отправляем + { + if (time() - @$a['time_ping'] > TIME_PING) + { + $st = @file_get_contents('http://'.$a['addr'].'/ping'); + $json = json_decode($st, true); + $x = $json ? ['time_online' => time()] : []; + db_update('contacts', ['time_ping' => time()] + $x, ['addr'=>$a['addr']]); + } + // если на связи - пытаемся дотправить сообщения + if (time() - $a['time_online'] < TIME_ONLINE) + { + $addr = $a['addr']; + foreach (db_search("undelivered/$addr") as $a) + if (send($a)) + { + db_insert("messages/$addr", $a + ['received'=>time()]); + db_delete("undelivered/$addr", ['timestamp'=>$a['timestamp']]); + } else break; + } + if (!empty($data)) $a['messages'] = $data; + } + exit; +}); + +api_get('/messages/(?[^/]+)', 'messages.tpl'); + +if ($_SERVER['REQUEST_METHOD'] != 'POST') return; + +api_post('/contacts/(?[^/]+)', function($m){ + if (empty($_REQUEST['addr'])) die('Не указан адрес!'); + $addr = $m['addr']; + $x = db_search('contacts', $addr == 'new' ? request('addr') : ['addr'=>$addr]); + if ($addr == 'new') + { + if (!empty($x)) die('Такой адрес уже есть в базе!'); + db_insert('contacts', request('addr,nickname,email')); + redirect('/contacts/'); + } else { + if (request('delete')) + { + db_delete('contacts', ['addr'=>$addr]); + redirect('/contacts/'); + } + else + db_update('contacts', request('addr,nickname,email'), ['addr'=>$addr]); + } +}); + +api_post('/messages/(?[^/]+)', function($m){ + $a = request('text') + ['from'=>$_SERVER['HTTP_HOST'], 'to'=>$m['addr'], 'timestamp'=>time()]; + if (send($a)) + db_insert('messages/'.$m['addr'], $a + ['received'=>time()]); + else + db_insert('undelivered/'.$m['addr'], $a); + redirect($_SERVER['HTTP_REFERER']); +}); + +api_post('/messages/', function($m){ + $a = request('from,to,text,timestamp'); + if ($a['to'] == $_SERVER['HTTP_HOST']) + { + db_insert('messages/'.$a['from'], $a + ['received'=>time()]); + $res = ['received'=>time()]; + echo json_encode($res); + } + exit; +}); + +redirect(); diff --git a/php/server.conf.example b/php/server.conf.example new file mode 100644 index 0000000..2bcad11 --- /dev/null +++ b/php/server.conf.example @@ -0,0 +1 @@ +IP=127.0.0.1 diff --git a/php/server.sh b/php/server.sh new file mode 100755 index 0000000..e7d8326 --- /dev/null +++ b/php/server.sh @@ -0,0 +1,4 @@ +#!/bin/sh + +source ./server.conf +php -S $IP:8000 index.php diff --git a/php/tpl/chat.tpl b/php/tpl/chat.tpl new file mode 100644 index 0000000..4e75b88 --- /dev/null +++ b/php/tpl/chat.tpl @@ -0,0 +1,10 @@ +

Сообщения

+ + + +
+ + +
+ + diff --git a/php/tpl/contact.tpl b/php/tpl/contact.tpl new file mode 100644 index 0000000..832572c --- /dev/null +++ b/php/tpl/contact.tpl @@ -0,0 +1,20 @@ +$m['addr']]); + } +?> + + +

контакт

+
+ Адрес: + Ник: + email: + +
diff --git a/php/tpl/contacts.tpl b/php/tpl/contacts.tpl new file mode 100644 index 0000000..e9ab65c --- /dev/null +++ b/php/tpl/contacts.tpl @@ -0,0 +1,29 @@ +

Контакты

+ + + +Добавить + + + + + + + + + + + + + + + + + + +
АдресНикemailonline
TIME_ONLINE)?'нет':'да'?>сообщения
diff --git a/php/tpl/dns.tpl b/php/tpl/dns.tpl new file mode 100644 index 0000000..25d618d --- /dev/null +++ b/php/tpl/dns.tpl @@ -0,0 +1,16 @@ +

DNS записи

+ +Добавить + + + + + + + + + + + + +
АдресДомен
diff --git a/php/tpl/dns_edit.tpl b/php/tpl/dns_edit.tpl new file mode 100644 index 0000000..04ea92d --- /dev/null +++ b/php/tpl/dns_edit.tpl @@ -0,0 +1,19 @@ +$m['addr']]); + } +?> + + +

запись

+
+ Адрес: + Домен: + +
diff --git a/php/tpl/index.tpl b/php/tpl/index.tpl new file mode 100644 index 0000000..da6e3da --- /dev/null +++ b/php/tpl/index.tpl @@ -0,0 +1,21 @@ + + + + + + +

Ваш IP:

+ + +[^/]+)', 'contact.tpl'); + api_get('/contacts/(?[^/]+)/messages', 'chat.tpl'); +?> + + + + + diff --git a/php/tpl/messages.tpl b/php/tpl/messages.tpl new file mode 100644 index 0000000..bfc61f8 --- /dev/null +++ b/php/tpl/messages.tpl @@ -0,0 +1,18 @@ + + + + +

Список сообщений пуст

+ + : +(не доставлено)';?> +
+ + + From 5ec53af777e449a87ab9c208a5bcc54d49507524 Mon Sep 17 00:00:00 2001 From: ChronosX88 Date: Thu, 10 May 2018 09:39:02 +0300 Subject: [PATCH 7/7] Update README.md --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 2387d61..2803e4e 100644 --- a/README.md +++ b/README.md @@ -1,3 +1,3 @@ # HyperboriaIM -**HyperboriaIM** - это защищенный мессенджер, который будет функционировать в сети *Hyperboria* (cjdns). Сам мессенджер будет разделен на две части - серверная часть и клиентская часть. Серверная часть будет функционировать на компьютере пользователя. В серверной части будет реализована вся логика мессенджера. Клиентская часть будет просто вызывать функции (API) серверной. Более подробно о технической части [тут](https://github.com/ChronosX88/HyperboriaIM-doc/blob/master/API.md). +**HyperboriaIM** - это защищенный мессенджер, который будет функционировать в сети *Hyperboria* (cjdns). Сам мессенджер будет разделен на две части - серверная часть и клиентская часть. Серверная часть будет функционировать на компьютере пользователя. В серверной части будет реализована вся логика мессенджера. Клиентская часть будет просто вызывать функции (API) серверной. Более подробно о технической части [тут](https://github.com/ChronosX88/HyperboriaIM-doc/blob/master/doc/ru/API.md).