Browse Source

remove key protocol dependency

main
ghost 3 months ago
parent
commit
f0bafed3ce
  1. 9
      .env
  2. 1
      config/services.yaml
  3. 22
      public/css/default.css
  4. 79
      src/Controller/RoomController.php
  5. 12
      templates/default/room/index.html.twig
  6. 6
      templates/default/room/index.rss.twig

9
.env

@ -19,7 +19,7 @@ APP_ENV=dev @@ -19,7 +19,7 @@ APP_ENV=dev
APP_SECRET=EDIT_ME
###< symfony/framework-bundle ###
APP_VERSION=1.11.0
APP_VERSION=1.12.0
APP_NAME=KevaChat
@ -74,7 +74,10 @@ APP_SESSION_ONLINE_TIMEOUT=900 @@ -74,7 +74,10 @@ APP_SESSION_ONLINE_TIMEOUT=900
# Moderators IP with extra permissions, separated with |
APP_MODERATOR_REMOTE_IP=
# Username regex rule (must be compatible with APP_ADD_POST_KEY_REGEX)
# Username anon
APP_ADD_USER_NAME_ANON=anon
# Username regex rule
APP_ADD_USER_NAME_REGEX=/^[A-z0-9-_]{1,64}$/
# User name reserved (case insensitive) separated with |
@ -107,7 +110,7 @@ APP_ADD_POST_REMOTE_IP_DENIED= @@ -107,7 +110,7 @@ APP_ADD_POST_REMOTE_IP_DENIED=
# Post ID rules (for kevacoin key)
# do not change to keep external KevaChat nodes compatibility
APP_ADD_POST_KEY_REGEX=/^([\d]{1,64})@([A-z0-9-_]{1,64})$/
APP_ADD_POST_KEY_REGEX=/.{1,255}/
# Post content rules (for kevacoin value, max length is 3072)
# do not change to keep external KevaChat nodes compatibility

1
config/services.yaml

@ -26,6 +26,7 @@ parameters: @@ -26,6 +26,7 @@ parameters:
app.kevacoin.mine.solo.url: '%env(APP_KEVACOIN_MINE_SOLO_URL)%'
app.session.default.timeout: '%env(APP_SESSION_DEFAULT_TIMEOUT)%'
app.session.online.timeout: '%env(APP_SESSION_ONLINE_TIMEOUT)%'
app.add.user.name.anon: '%env(APP_ADD_USER_NAME_ANON)%'
app.add.user.name.regex: '%env(APP_ADD_USER_NAME_REGEX)%'
app.add.user.name.blacklist: '%env(APP_ADD_USER_NAME_BLACKLIST)%'
app.add.user.remote.ip.delay: '%env(APP_ADD_USER_REMOTE_IP_DELAY)%'

22
public/css/default.css

@ -15,6 +15,11 @@ @@ -15,6 +15,11 @@
--color-warning: #ee784e;
--color-error: #ff6363;
--color-default: #999;
transition: all .1s ease-in;
-webkit-transition: all .2s ease-in;
-moz-transition: all .2s ease-in;
-o-transition: all .2s ease-in;
}
*::placeholder
@ -170,6 +175,23 @@ main ul li span > svg @@ -170,6 +175,23 @@ main ul li span > svg
float: right;
}
main ul li small
{
color: var(--color-default);
display: inline-block;
opacity: 0;
}
main ul li small svg
{
vertical-align: top;
}
main ul li > div:hover > small
{
opacity: 1;
}
main > form
{
box-sizing: border-box;

79
src/Controller/RoomController.php

@ -229,14 +229,15 @@ class RoomController extends AbstractController @@ -229,14 +229,15 @@ class RoomController extends AbstractController
}
// Require valid kevachat meta
if ($data = $this->_post($pending))
if ($data = $this->_post($client, $pending))
{
// Detect parent post
preg_match(self::PARENT_REGEX, $data->message, $mention);
$feed[$data->id] =
$feed[$data->txid] =
[
'id' => $data->id,
'txid' => $data->txid,
'key' => $data->key,
'user' => $data->user,
'time' => $data->time,
'parent' => isset($mention[1]) ? $mention[1] : null,
@ -255,21 +256,16 @@ class RoomController extends AbstractController @@ -255,21 +256,16 @@ class RoomController extends AbstractController
// Get regular posts
foreach ((array) $client->kevaFilter($request->get('namespace')) as $post)
{
// Skip values with meta keys
if (str_starts_with($post['key'], '_'))
{
continue;
}
// Require valid kevachat meta
if ($data = $this->_post($post))
if ($data = $this->_post($client, $post))
{
// Detect parent post
preg_match(self::PARENT_REGEX, $data->message, $mention);
$feed[$data->id] =
$feed[$data->txid] =
[
'id' => $data->id,
'txid' => $data->txid,
'key' => $data->key,
'user' => $data->user,
'time' => $data->time,
'parent' => isset($mention[1]) ? $mention[1] : null,
@ -579,7 +575,7 @@ class RoomController extends AbstractController @@ -579,7 +575,7 @@ class RoomController extends AbstractController
}
// Check user session exist
$username = 'anon';
$username = $this->getParameter('app.add.user.name.anon');
if ($request->get('sign') === 'username' && !empty($request->cookies->get('KEVACHAT_SESSION')) && preg_match('/[A-z0-9]{32}/', $request->cookies->get('KEVACHAT_SESSION')))
{
@ -606,7 +602,7 @@ class RoomController extends AbstractController @@ -606,7 +602,7 @@ class RoomController extends AbstractController
{
// Send message by account balance on available
if (
$username != 'anon'
$username != $this->getParameter('app.add.user.name.anon')
&&
$client->getBalance(
$username,
@ -617,9 +613,9 @@ class RoomController extends AbstractController @@ -617,9 +613,9 @@ class RoomController extends AbstractController
$client->kevaPut(
$request->get('namespace'),
sprintf(
'%d@%s',
'%d%s',
time(),
$username
$username != $this->getParameter('app.add.user.name.anon') ? sprintf('@%s', $username) : null
),
$request->get('message')
)
@ -688,9 +684,9 @@ class RoomController extends AbstractController @@ -688,9 +684,9 @@ class RoomController extends AbstractController
$pool->setKey(
sprintf(
'%d@%s',
'%d%s',
$time,
$username
$username != $this->getParameter('app.add.user.name.anon') ? sprintf('@%s', $username) : null
),
);
@ -742,9 +738,9 @@ class RoomController extends AbstractController @@ -742,9 +738,9 @@ class RoomController extends AbstractController
$client->kevaPut(
$request->get('namespace'),
sprintf(
'%d@%s',
'%d%s',
time(),
$username
$username != $this->getParameter('app.add.user.name.anon') ? sprintf('@%s', $username) : null
),
$request->get('message')
)
@ -1106,7 +1102,10 @@ class RoomController extends AbstractController @@ -1106,7 +1102,10 @@ class RoomController extends AbstractController
);
}
private function _post(array $data): ?object
private function _post(
\Kevachat\Kevacoin\Client $client,
array $data
): ?object
{
// Validate required data
if (empty($data['txid']))
@ -1124,6 +1123,12 @@ class RoomController extends AbstractController @@ -1124,6 +1123,12 @@ class RoomController extends AbstractController
return null;
}
// Skip meta records
if (str_starts_with($data['key'], '_'))
{
return null;
}
// Validate key format allowed in settings
if (!preg_match((string) $this->getParameter('app.add.post.key.regex'), $data['key'], $key))
{
@ -1136,18 +1141,30 @@ class RoomController extends AbstractController @@ -1136,18 +1141,30 @@ class RoomController extends AbstractController
return null;
}
// Validate timestamp@username
if (empty($key[1]) || empty($key[2]))
// Get transaction time
if (!$transaction = $client->getRawTransaction($data['txid']))
{
return null;
}
// Detect username (key @postfix)
if (preg_match('/@([^@]+)$/', $data['key'], $match))
{
$user = $match[1];
}
else
{
$user = $this->getParameter('app.add.user.name.anon');
}
return (object)
[
'id' => $data['txid'],
'time' => $key[1],
'user' => $key[2],
'message' => $data['value']
'txid' => $data['txid'],
'key' => $data['key'],
'message' => $data['value'],
'time' => $transaction['time'],
'user' => $user
];
}
@ -1164,7 +1181,7 @@ class RoomController extends AbstractController @@ -1164,7 +1181,7 @@ class RoomController extends AbstractController
{
$children = $this->_tree(
$feed,
$post['id']
$post['txid']
);
if ($children)
@ -1172,10 +1189,10 @@ class RoomController extends AbstractController @@ -1172,10 +1189,10 @@ class RoomController extends AbstractController
$post['tree'] = $children;
}
$tree[$post['id']] = $post;
$tree[$post['txid']] = $post;
unset(
$feed[$post['id']]
$feed[$post['txid']]
);
}
}
@ -1214,7 +1231,7 @@ class RoomController extends AbstractController @@ -1214,7 +1231,7 @@ class RoomController extends AbstractController
foreach ($raw as $data)
{
// Is valid post
if ($this->_post($data))
if ($this->_post($client, $data))
{
$total++;
}

12
templates/default/room/index.html.twig

@ -5,7 +5,7 @@ @@ -5,7 +5,7 @@
{% for post in tree %}
<li>
<div>
<a name="{{ post.id }}"></a>
<a name="{{ post.txid }}"></a>
<strong>
{{ post.user }}
</strong>
@ -22,10 +22,16 @@ @@ -22,10 +22,16 @@
</svg>
</span>
{% else %}
<a rel="nofollow" href="{{ path('room_namespace', { mode : mode, namespace : namespace, _fragment : post.id }) }}" title="{{ post.time | date('c') }}">{{ post.time | format_ago }}</a>
<a rel="nofollow" href="{{ path('room_namespace', { mode : mode, namespace : namespace, _fragment : post.txid }) }}" title="{{ post.time | date('c') }}">{{ post.time | format_ago }}</a>
&bull;
<a rel="nofollow" href="{{ path('room_namespace', { mode : mode, namespace : namespace, txid : post.id, _fragment : post.id }) }}">{{ 'reply' | trans }}</a>
<a rel="nofollow" href="{{ path('room_namespace', { mode : mode, namespace : namespace, txid : post.txid, _fragment : post.txid }) }}">{{ 'reply' | trans }}</a>
{% endif %}
<small>
<svg xmlns="http://www.w3.org/2000/svg" width="12" height="12" fill="currentColor" viewBox="0 0 16 16">
<path d="M3.5 11.5a3.5 3.5 0 1 1 3.163-5H14L15.5 8 14 9.5l-1-1-1 1-1-1-1 1-1-1-1 1H6.663a3.5 3.5 0 0 1-3.163 2M2.5 9a1 1 0 1 0 0-2 1 1 0 0 0 0 2"/>
</svg>
{{ post.key }}
</small>
{# apply markdown whitelist filters only to prevent ping from remote includes #}
{{
post.message | message_to_markdown

6
templates/default/room/index.rss.twig

@ -6,11 +6,11 @@ @@ -6,11 +6,11 @@
<link>{{ url('room_namespace', { namespace : request.get('namespace'), _fragment : 'latest' }) }}</link>
{% for post in feed %}
<item>
<title>{{ post.id }}</title>
<title>{{ post.txid }}</title>
<author>{{ post.user }}</author>
<pubDate>{{ post.time | date('D, d M Y h:i:s O') }}</pubDate>
<guid>{{ url('room_namespace', { namespace : request.get('namespace'), _fragment : post.id }) }}</guid>
<link>{{ url('room_namespace', { namespace : request.get('namespace'), _fragment : post.id }) }}</link>
<guid>{{ url('room_namespace', { namespace : request.get('namespace'), _fragment : post.txid }) }}</guid>
<link>{{ url('room_namespace', { namespace : request.get('namespace'), _fragment : post.txid }) }}</link>
<description>{{ post.message | striptags | markdown_to_html | striptags | trim }}</description>
</item>
{% endfor %}

Loading…
Cancel
Save