mirror of
https://github.com/kevachat/webapp.git
synced 2025-01-23 21:14:17 +00:00
implement new room submit feature
This commit is contained in:
parent
df68a3aa91
commit
7c51f3d57a
21
.env
21
.env
@ -19,7 +19,7 @@ APP_ENV=dev
|
||||
APP_SECRET=EDIT_ME
|
||||
###< symfony/framework-bundle ###
|
||||
|
||||
APP_VERSION=1.3.1
|
||||
APP_VERSION=1.4.0
|
||||
|
||||
APP_NAME=KevaChat
|
||||
|
||||
@ -61,23 +61,32 @@ APP_KEVACOIN_ROOM_NAMESPACE_DEFAULT=EDIT_ME
|
||||
# Online session expiration timeout
|
||||
APP_SESSION_ONLINE_TIMEOUT=900
|
||||
|
||||
# Moderators IP with extra permissions, separated with |
|
||||
APP_MODERATOR_REMOTE_IP=
|
||||
|
||||
# Allow remotes to create new rooms (namespaces)
|
||||
APP_ADD_ROOM_REMOTE_IP_REGEX=/.*/
|
||||
|
||||
# Time quota delay for new room submit ability per IP (seconds)
|
||||
APP_ADD_ROOM_REMOTE_IP_DELAY=86400
|
||||
|
||||
# Skip access limits for banned IPs separated by |
|
||||
APP_ADD_ROOM_REMOTE_IP_DENIED=
|
||||
|
||||
# Room name rules (for kevacoin _KEVA_NS_, max length 520)
|
||||
APP_ADD_ROOM_KEVA_NS_VALUE_REGEX=/^[\w\s_-]{2,140}$/ui
|
||||
|
||||
# Allow remotes to create new posts (submit key/values)
|
||||
APP_ADD_POST_REMOTE_IP_REGEX=/.*/
|
||||
|
||||
# Time quota for remote publications by IP (seconds)
|
||||
# Time quota delay for post publications per IP (seconds)
|
||||
APP_ADD_POST_REMOTE_IP_DELAY=60
|
||||
|
||||
# Skip access limits for following IPs separated by |
|
||||
APP_ADD_POST_REMOTE_IP_MODERATORS=
|
||||
|
||||
# Skip access limits for banned IPs separated by |
|
||||
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]+)@([A-z0-9\.\:\[\]]+)$/
|
||||
|
||||
# Post content rules (for kevacoin value)
|
||||
# Post content rules (for kevacoin value, max length 3072)
|
||||
APP_ADD_POST_VALUE_REGEX=/^[\w\s\:\.\,\'\"\/\!\?\@\#\%\(\)\[\]\+\-\*\$\%]{2,3072}$/ui
|
12
composer.lock
generated
12
composer.lock
generated
@ -132,16 +132,16 @@
|
||||
},
|
||||
{
|
||||
"name": "kevachat/kevacoin",
|
||||
"version": "1.4.2",
|
||||
"version": "1.5.0",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/kevachat/kevacoin-php.git",
|
||||
"reference": "b6e5416c58d379fd197bbd6d1039a30042ea0481"
|
||||
"reference": "44608e688f69ff1545f2a3103c4504bfb3294831"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/kevachat/kevacoin-php/zipball/b6e5416c58d379fd197bbd6d1039a30042ea0481",
|
||||
"reference": "b6e5416c58d379fd197bbd6d1039a30042ea0481",
|
||||
"url": "https://api.github.com/repos/kevachat/kevacoin-php/zipball/44608e688f69ff1545f2a3103c4504bfb3294831",
|
||||
"reference": "44608e688f69ff1545f2a3103c4504bfb3294831",
|
||||
"shasum": ""
|
||||
},
|
||||
"type": "library",
|
||||
@ -156,9 +156,9 @@
|
||||
],
|
||||
"support": {
|
||||
"issues": "https://github.com/kevachat/kevacoin-php/issues",
|
||||
"source": "https://github.com/kevachat/kevacoin-php/tree/1.4.2"
|
||||
"source": "https://github.com/kevachat/kevacoin-php/tree/1.5.0"
|
||||
},
|
||||
"time": "2023-12-06T09:20:08+00:00"
|
||||
"time": "2023-12-09T18:55:04+00:00"
|
||||
},
|
||||
{
|
||||
"name": "league/commonmark",
|
||||
|
@ -24,12 +24,15 @@ parameters:
|
||||
app.kevacoin.mine.solo.url: '%env(APP_KEVACOIN_MINE_SOLO_URL)%'
|
||||
app.session.online.timeout: '%env(APP_SESSION_ONLINE_TIMEOUT)%'
|
||||
app.add.room.remote.ip.regex: '%env(APP_ADD_ROOM_REMOTE_IP_REGEX)%'
|
||||
app.add.room.remote.ip.delay: '%env(APP_ADD_ROOM_REMOTE_IP_DELAY)%'
|
||||
app.add.room.remote.ip.denied: '%env(APP_ADD_ROOM_REMOTE_IP_DENIED)%'
|
||||
app.add.room.keva.ns.value.regex: '%env(APP_ADD_ROOM_KEVA_NS_VALUE_REGEX)%'
|
||||
app.add.post.remote.ip.regex: '%env(APP_ADD_POST_REMOTE_IP_REGEX)%'
|
||||
app.add.post.remote.ip.delay: '%env(APP_ADD_POST_REMOTE_IP_DELAY)%'
|
||||
app.add.post.remote.ip.moderators: '%env(APP_ADD_POST_REMOTE_IP_MODERATORS)%'
|
||||
app.add.post.remote.ip.denied: '%env(APP_ADD_POST_REMOTE_IP_DENIED)%'
|
||||
app.add.post.key.regex: '%env(APP_ADD_POST_KEY_REGEX)%'
|
||||
app.add.post.value.regex: '%env(APP_ADD_POST_VALUE_REGEX)%'
|
||||
app.moderator.remote.ip: '%env(APP_MODERATOR_REMOTE_IP)%'
|
||||
|
||||
services:
|
||||
# default configuration for services in *this* file
|
||||
|
@ -155,6 +155,7 @@ footer > form
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
footer > form > input[type="text"],
|
||||
footer > form > textarea
|
||||
{
|
||||
box-sizing: border-box;
|
||||
|
@ -99,18 +99,27 @@ class ModuleController extends AbstractController
|
||||
Request $request
|
||||
): Response
|
||||
{
|
||||
$client = new \Kevachat\Kevacoin\Client(
|
||||
$this->getParameter('app.kevacoin.protocol'),
|
||||
$this->getParameter('app.kevacoin.host'),
|
||||
$this->getParameter('app.kevacoin.port'),
|
||||
$this->getParameter('app.kevacoin.username'),
|
||||
$this->getParameter('app.kevacoin.password')
|
||||
);
|
||||
// Create rooms list
|
||||
$list = [];
|
||||
|
||||
foreach ((array) explode('|', $this->getParameter('app.kevacoin.room.namespaces.pinned')) as $room)
|
||||
{
|
||||
$list[] = $room;
|
||||
}
|
||||
|
||||
// Append custom valid namespace to the rooms list menu
|
||||
if (!in_array($request->get('namespace'), $list) && preg_match('/^[A-z0-9]{34}$/', $request->get('namespace')))
|
||||
{
|
||||
$list[] = $request->get('namespace');
|
||||
}
|
||||
|
||||
// Render the template
|
||||
return $this->render(
|
||||
'default/module/rooms.html.twig',
|
||||
[
|
||||
'list' => (array) explode('|', $this->getParameter('app.kevacoin.room.namespaces.pinned')),
|
||||
'list' => array_unique(
|
||||
$list
|
||||
),
|
||||
'form' =>
|
||||
[
|
||||
'namespace' =>
|
||||
@ -178,4 +187,17 @@ class ModuleController extends AbstractController
|
||||
]
|
||||
);
|
||||
}
|
||||
|
||||
public function room(
|
||||
Request $request
|
||||
): Response
|
||||
{
|
||||
return $this->render(
|
||||
'default/module/room.html.twig',
|
||||
[
|
||||
'name' => $request->get('name'),
|
||||
'error' => $request->get('error')
|
||||
]
|
||||
);
|
||||
}
|
||||
}
|
@ -95,9 +95,9 @@ class RoomController extends AbstractController
|
||||
array_multisort(
|
||||
array_column(
|
||||
$list,
|
||||
'name'
|
||||
'total'
|
||||
),
|
||||
SORT_ASC,
|
||||
SORT_DESC,
|
||||
$list
|
||||
);
|
||||
|
||||
@ -165,7 +165,7 @@ class RoomController extends AbstractController
|
||||
$feed = [];
|
||||
|
||||
// Get pending paradise
|
||||
foreach ((array) $client->kevaPending() as $pending)
|
||||
foreach ((array) $client->kevaPending() as $pending) // @TODO relate to this room
|
||||
{
|
||||
// Ignore pending posts from other rooms
|
||||
if ($pending['namespace'] !== $request->get('namespace'))
|
||||
@ -347,7 +347,7 @@ class RoomController extends AbstractController
|
||||
$this->getParameter('app.kevacoin.password')
|
||||
);
|
||||
|
||||
// Check namespace defined in config
|
||||
// Check namespace available on this wallet
|
||||
$rooms = [];
|
||||
|
||||
foreach ((array) $client->kevaListNamespaces() as $value)
|
||||
@ -373,7 +373,7 @@ class RoomController extends AbstractController
|
||||
// Ignore this rule for is moderators
|
||||
!in_array(
|
||||
$request->getClientIp(),
|
||||
(array) explode('|', $this->getParameter('app.add.post.remote.ip.moderators'))
|
||||
(array) explode('|', $this->getParameter('app.moderator.remote.ip'))
|
||||
) &&
|
||||
|
||||
// Check namespace writable or user is moderator
|
||||
@ -401,7 +401,10 @@ class RoomController extends AbstractController
|
||||
[
|
||||
'namespace' => $request->get('namespace'),
|
||||
'message' => $request->get('message'),
|
||||
'error' => $translator->trans('Access denied for this IP!')
|
||||
'error' => sprintf(
|
||||
$translator->trans('Access denied for host %s!'),
|
||||
$request->getClientIp()
|
||||
)
|
||||
]
|
||||
);
|
||||
}
|
||||
@ -414,7 +417,10 @@ class RoomController extends AbstractController
|
||||
[
|
||||
'namespace' => $request->get('namespace'),
|
||||
'message' => $request->get('message'),
|
||||
'error' => $translator->trans('Access not allowed for this IP!')
|
||||
'error' => sprintf(
|
||||
$translator->trans('Access restricted for host %s!'),
|
||||
$request->getClientIp()
|
||||
)
|
||||
]
|
||||
);
|
||||
}
|
||||
@ -445,7 +451,7 @@ class RoomController extends AbstractController
|
||||
'namespace' => $request->get('namespace'),
|
||||
'message' => $request->get('message'),
|
||||
'error' => sprintf(
|
||||
$translator->trans('Please wait for %s seconds before post new message!'),
|
||||
$translator->trans('Please wait %s seconds before post new message!'),
|
||||
(int) $this->getParameter('app.add.post.remote.ip.delay') - (time() - $delay)
|
||||
)
|
||||
]
|
||||
@ -462,7 +468,7 @@ class RoomController extends AbstractController
|
||||
'message' => $request->get('message'),
|
||||
'error' => sprintf(
|
||||
$translator->trans('Insufficient funds, wallet: %s'),
|
||||
$this->getParameter('app.kevacoin.mine.address')
|
||||
$this->getParameter('app.kevacoin.boost.address')
|
||||
)
|
||||
]
|
||||
);
|
||||
@ -510,6 +516,187 @@ class RoomController extends AbstractController
|
||||
);
|
||||
}
|
||||
|
||||
#[Route(
|
||||
'/room/add',
|
||||
name: 'room_add',
|
||||
methods:
|
||||
[
|
||||
'POST'
|
||||
]
|
||||
)]
|
||||
public function add(
|
||||
Request $request,
|
||||
TranslatorInterface $translator
|
||||
): Response
|
||||
{
|
||||
// Check maintenance mode disabled
|
||||
if ($this->getParameter('app.maintenance'))
|
||||
{
|
||||
return $this->redirectToRoute(
|
||||
'room_namespace',
|
||||
[
|
||||
'namespace' => $request->get('namespace'),
|
||||
'message' => $request->get('message'),
|
||||
'error' => $this->getParameter('app.maintenance')
|
||||
]
|
||||
);
|
||||
}
|
||||
|
||||
// Connect memcached
|
||||
$memcached = new \Memcached();
|
||||
$memcached->addServer(
|
||||
$this->getParameter('app.memcached.host'),
|
||||
$this->getParameter('app.memcached.port')
|
||||
);
|
||||
|
||||
$memory = md5(
|
||||
sprintf(
|
||||
'%s.RoomController::add:add.room.remote.ip.delay:%s',
|
||||
__DIR__,
|
||||
$request->getClientIp(),
|
||||
),
|
||||
);
|
||||
|
||||
// Connect kevacoin
|
||||
$client = new \Kevachat\Kevacoin\Client(
|
||||
$this->getParameter('app.kevacoin.protocol'),
|
||||
$this->getParameter('app.kevacoin.host'),
|
||||
$this->getParameter('app.kevacoin.port'),
|
||||
$this->getParameter('app.kevacoin.username'),
|
||||
$this->getParameter('app.kevacoin.password')
|
||||
);
|
||||
|
||||
// Trim extra spaces from room name
|
||||
$name = trim(
|
||||
$request->get('name')
|
||||
);
|
||||
|
||||
// Validate room name regex
|
||||
if (!preg_match($this->getParameter('app.add.room.keva.ns.value.regex'), $name))
|
||||
{
|
||||
return $this->redirectToRoute(
|
||||
'room_list',
|
||||
[
|
||||
'name' => $name,
|
||||
'error' => sprintf(
|
||||
$translator->trans('Room name does not match node requirements: %s'),
|
||||
$this->getParameter('app.add.room.keva.ns.value.regex')
|
||||
)
|
||||
]
|
||||
);
|
||||
}
|
||||
|
||||
// Check room name not added before
|
||||
$rooms = [];
|
||||
|
||||
foreach ((array) $client->kevaListNamespaces() as $value)
|
||||
{
|
||||
$rooms[$value['namespaceId']] = $value['displayName'];
|
||||
}
|
||||
|
||||
if (in_array($name, $rooms))
|
||||
{
|
||||
return $this->redirectToRoute(
|
||||
'room_list',
|
||||
[
|
||||
'name' => $name,
|
||||
'error' => $translator->trans('Room with same name already exists on this node!')
|
||||
]
|
||||
);
|
||||
}
|
||||
|
||||
// Deny requests from banned remote hosts
|
||||
if (in_array($request->getClientIp(), (array) explode('|', $this->getParameter('app.add.room.remote.ip.denied'))))
|
||||
{
|
||||
return $this->redirectToRoute(
|
||||
'room_list',
|
||||
[
|
||||
'name' => $name,
|
||||
'error' => sprintf(
|
||||
$translator->trans('Access denied for host %s!'),
|
||||
$request->getClientIp()
|
||||
)
|
||||
]
|
||||
);
|
||||
}
|
||||
|
||||
// Validate remote IP regex
|
||||
if (!preg_match($this->getParameter('app.add.room.remote.ip.regex'), $request->getClientIp()))
|
||||
{
|
||||
return $this->redirectToRoute(
|
||||
'room_list',
|
||||
[
|
||||
'name' => $name,
|
||||
'error' => sprintf(
|
||||
$translator->trans('Access restricted for host %s!'),
|
||||
$request->getClientIp()
|
||||
)
|
||||
]
|
||||
);
|
||||
}
|
||||
|
||||
// Validate remote IP limits
|
||||
if ($delay = (int) $memcached->get($memory))
|
||||
{
|
||||
// Error
|
||||
return $this->redirectToRoute(
|
||||
'room_list',
|
||||
[
|
||||
'name' => $name,
|
||||
'error' => sprintf(
|
||||
$translator->trans('Please wait for %s seconds before add new room!'),
|
||||
(int) $this->getParameter('app.add.room.remote.ip.delay') - (time() - $delay)
|
||||
)
|
||||
]
|
||||
);
|
||||
}
|
||||
|
||||
// Validate funds available yet
|
||||
if (1 > $client->getBalance())
|
||||
{
|
||||
return $this->redirectToRoute(
|
||||
'room_list',
|
||||
[
|
||||
'name' => $name,
|
||||
'error' => sprintf(
|
||||
$translator->trans('Insufficient funds, wallet: %s'),
|
||||
$this->getParameter('app.kevacoin.boost.address')
|
||||
)
|
||||
]
|
||||
);
|
||||
}
|
||||
|
||||
// Send message to DHT
|
||||
if ($namespace = $client->kevaNamespace($name))
|
||||
{
|
||||
// Register event time
|
||||
$memcached->set(
|
||||
$memory,
|
||||
time(),
|
||||
(int) $this->getParameter('app.add.room.remote.ip.delay') // auto remove on cache expire
|
||||
);
|
||||
|
||||
// Redirect to new room
|
||||
return $this->redirectToRoute(
|
||||
'room_namespace',
|
||||
[
|
||||
'namespace' => $namespace['namespaceId'],
|
||||
'error' => null,
|
||||
'message' => null
|
||||
]
|
||||
);
|
||||
}
|
||||
|
||||
// Something went wrong, return error message
|
||||
return $this->redirectToRoute(
|
||||
'room_list',
|
||||
[
|
||||
'name' => $name,
|
||||
'error' => $translator->trans('Internal error! Please feedback')
|
||||
]
|
||||
);
|
||||
}
|
||||
|
||||
private function _post(array $data): ?object
|
||||
{
|
||||
// Validate key format allowed in settings
|
||||
|
7
templates/default/module/room.html.twig
Normal file
7
templates/default/module/room.html.twig
Normal file
@ -0,0 +1,7 @@
|
||||
<form name="room" action="{{ path('room_add') }}" method="post">
|
||||
{% if error %}
|
||||
<output name="error" for="form-room-name">{{ error }}</output>
|
||||
{% endif %}
|
||||
<input type="text" name="name" id="form-room-name" value="{{ name }}" placeholder="{{ 'enter new room name...' | trans }}" />
|
||||
<button type="submit">{{ 'add' | trans }}</button>
|
||||
</form>
|
@ -1,4 +1,4 @@
|
||||
<form name="room" action="{{ path('room_index') }}" method="get">
|
||||
<form name="rooms" action="{{ path('room_index') }}" method="get">
|
||||
<input type="text" name="namespace" value="{{ form.namespace.value }}" placeholder="{{ 'join room by kevacoin namespace...' | trans }}" />
|
||||
</form>
|
||||
{% if list %}
|
||||
|
@ -43,4 +43,16 @@
|
||||
</li>
|
||||
</ul>
|
||||
{% endif %}
|
||||
{% endblock %}
|
||||
{% block footer_content %}
|
||||
{{
|
||||
render(
|
||||
controller(
|
||||
'App\\Controller\\ModuleController::room',
|
||||
{
|
||||
request: request
|
||||
}
|
||||
)
|
||||
)
|
||||
}}
|
||||
{% endblock %}
|
Loading…
x
Reference in New Issue
Block a user