Hot fix: added templater for future login page, fixed some critical bugs with binding socket to unix domain address
This commit is contained in:
parent
5314ffef1f
commit
3632ade86d
26
assets/HypertextPages/login.nytl.html
Normal file
26
assets/HypertextPages/login.nytl.html
Normal file
@ -0,0 +1,26 @@
|
||||
{% ELDEF main JSON pres %}
|
||||
<!DOCTYPE html>
|
||||
<html lang="{% WRITE pres.lang %}">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<title>{% WRITE pres.phr.decl.page-login %}</title>
|
||||
<link rel="stylesheet" href="/assets/css/login.css">
|
||||
|
||||
</head>
|
||||
|
||||
<body>
|
||||
<div class="form-container">
|
||||
<h1 class="hide-cursor no-select">{% WRITE pres.phr.decl.enter %}</h1>
|
||||
<form action="/" method="post">
|
||||
<label for="username">{% WRITE pres.phr.decl.nickname %}</label>
|
||||
<input type="text" name="username" id="username"><br>
|
||||
<label for="password">{% WRITE pres.phr.decl.password %}</label>
|
||||
<input type="password" name="password" id="password"><br>
|
||||
<button type="submit" class="hide-cursor no-select">{% WRITE pres.phr.act.enter %}</button>
|
||||
</form>
|
||||
</div>
|
||||
|
||||
</body>
|
||||
</html>
|
||||
{% ENDELDEF %}
|
77
assets/css/login.css
Normal file
77
assets/css/login.css
Normal file
@ -0,0 +1,77 @@
|
||||
dy {
|
||||
font-family: Arial, sans-serif;
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
height: 100vh;
|
||||
margin: 0;
|
||||
background-color: #e5e5e5;
|
||||
}
|
||||
|
||||
.form-container {
|
||||
width: 100%;
|
||||
max-width: 400px;
|
||||
background-color: white;
|
||||
box-shadow: 0 0 10px rgba(0, 0, 0, 0.1);
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
border-radius: 8px;
|
||||
padding: 40px;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
h1 {
|
||||
margin-bottom: 20px;
|
||||
color: #2F4F4F;
|
||||
}
|
||||
|
||||
input {
|
||||
width: 100%;
|
||||
background: #f7f7f7;
|
||||
font-size: 16px;
|
||||
padding: 10px;
|
||||
border: 1px solid #ddd;
|
||||
border-radius: 20px;
|
||||
margin-bottom: 15px;
|
||||
outline: none;
|
||||
}
|
||||
|
||||
button {
|
||||
width: 100%;
|
||||
padding: 15px;
|
||||
border: none;
|
||||
background-color: #0088cc;
|
||||
color: white;
|
||||
border-radius: 20px;
|
||||
cursor: pointer;
|
||||
outline: none;
|
||||
font-size: 16px;
|
||||
font-weight: bold;
|
||||
transition: background-color 0.3s;
|
||||
}
|
||||
|
||||
button:hover,
|
||||
button:focus-visible {
|
||||
background-color: #007bb5;
|
||||
}
|
||||
|
||||
.hide-cursor::placeholder {
|
||||
color: #000;
|
||||
}
|
||||
|
||||
.hide-cursor {
|
||||
caret-color: transparent;
|
||||
}
|
||||
|
||||
.no-select {
|
||||
-webkit-user-select: none; /* Для Safari */
|
||||
-moz-user-select: none; /* Для Firefox */
|
||||
user-select: none; /* Для всех остальных браузеров */
|
||||
}
|
||||
|
||||
div {
|
||||
color: red;
|
||||
font-size: 15px;
|
||||
margin-top: 10px;
|
||||
display: none;
|
||||
}
|
@ -1,4 +1,4 @@
|
||||
body {
|
||||
dy {
|
||||
font-family: Arial, sans-serif;
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
|
@ -1,68 +0,0 @@
|
||||
document.addEventListener('DOMContentLoaded', function() {
|
||||
const form = document.querySelector('form');
|
||||
const submitButton = form.querySelector('button[type="submit"]');
|
||||
const errorElement = document.getElementById('error');
|
||||
|
||||
form.addEventListener('keydown', function(event) {
|
||||
const activeElement = document.activeElement;
|
||||
const formElements = Array.from(form.elements);
|
||||
const currentIndex = formElements.indexOf(activeElement);
|
||||
|
||||
if (activeElement.tagName === 'INPUT') {
|
||||
if (event.key === 'Enter') {
|
||||
event.preventDefault();
|
||||
if (currentIndex === formElements.length - 1) {
|
||||
submitButton.focus();
|
||||
} else if (currentIndex !== -1 && formElements[currentIndex + 1]) {
|
||||
formElements[currentIndex + 1].focus();
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
submitButton.addEventListener('focus', function() {
|
||||
submitButton.classList.add('focus-visible');
|
||||
});
|
||||
|
||||
submitButton.addEventListener('blur', function() {
|
||||
submitButton.classList.remove('focus-visible');
|
||||
});
|
||||
|
||||
form.addEventListener('submit', function(event) {
|
||||
event.preventDefault();
|
||||
validateForm();
|
||||
});
|
||||
|
||||
async function validateForm() {
|
||||
const name = document.getElementById('name').value.trim();
|
||||
const nickname = document.getElementById('nickname').value.trim();
|
||||
|
||||
if (name === '' || nickname === '') {
|
||||
errorElement.textContent = 'Пожалуйста, заполните все поля';
|
||||
errorElement.style.display = 'block';
|
||||
return false;
|
||||
}
|
||||
try {
|
||||
// Отправка данных для регистрации
|
||||
let response = await fetch('/login', {
|
||||
method: 'POST',
|
||||
headers: {
|
||||
'Content-Type': 'application/json'
|
||||
},
|
||||
body: JSON.stringify({name, nickname})
|
||||
});
|
||||
|
||||
const result = await response.json();
|
||||
|
||||
if (result.status === 0) {
|
||||
window.location.href = '/';
|
||||
} else {
|
||||
throw Error(result.error);
|
||||
}
|
||||
} catch(error) {
|
||||
errorElement.textContent = 'Попробуйте еще раз';
|
||||
errorElement.style.display = 'block';
|
||||
}
|
||||
|
||||
}
|
||||
});
|
@ -1,16 +1,24 @@
|
||||
{
|
||||
"presentation": {
|
||||
"lang": "ru",
|
||||
"instance-identity": {
|
||||
"top-title": "Вэб чат от ИУ9"
|
||||
},
|
||||
"phr": {
|
||||
"decl": {
|
||||
"list-of-chat-rooms": "Список Чат-Комнат",
|
||||
"select-chat-room": "Выберете чат комнату",
|
||||
"enter": "Вход",
|
||||
"nickname": "Никнейм",
|
||||
"password": "Пароль",
|
||||
"page-login": "Вход",
|
||||
"list-of-chat-rooms": "Список Чат-Коsмнат",
|
||||
"name-of-room": "Название комнаты",
|
||||
"create-room": "Создать комнату"
|
||||
},
|
||||
"ask" : {
|
||||
"select-chat-room": "Выберете чат комнату"
|
||||
},
|
||||
"act": {
|
||||
"enter": "Войти",
|
||||
"create-room": "Создать комнату",
|
||||
"confirm": "Подтвердить",
|
||||
"create": "Создать"
|
||||
@ -31,6 +39,6 @@
|
||||
"server": {
|
||||
"workers": 8,
|
||||
"http-listen": ["127.0.0.1:1025"],
|
||||
"admin-command-listen": ["127.0.0.1:1026"]
|
||||
"admin-command-listen": ["unix:/run/iu9/iu9cawebchat-ac.sock"]
|
||||
}
|
||||
}
|
||||
|
@ -225,7 +225,7 @@ namespace een9 {
|
||||
ears[i + CRL_Nip].type = 1;
|
||||
}
|
||||
for (size_t i = 0; i < Nip; i++) {
|
||||
int listening_socket_fd = socket(AF_INET, SOCK_STREAM, 0);
|
||||
int listening_socket_fd = socket(ears[i].my_addr.v.gen.sa_family, SOCK_STREAM, 0);
|
||||
ASSERT_on_iret(listening_socket_fd, "'Listening socket' creation");
|
||||
UniqueFdWrapper listening_socket(listening_socket_fd);
|
||||
int reuseaddr_nozero_option_value = 1;
|
||||
|
@ -175,7 +175,7 @@ namespace een9 {
|
||||
if (ch == 0)
|
||||
return -1;
|
||||
res.v.gen.sa_family = AF_UNIX;
|
||||
if (sizeof(res.v.sun.sun_path) > path.size())
|
||||
if (sizeof(res.v.sun.sun_path) < path.size())
|
||||
THROW("path is too big");
|
||||
memcpy(res.v.sun.sun_path, path.c_str(), path.size());
|
||||
res.addrLen = offsetof(sockaddr_un, sun_path) + path.size();
|
||||
|
@ -26,4 +26,4 @@ int main(int argc, char** argv) {
|
||||
printf("%s\n<a><f><t><e><r><><l><f>\n", answer2.c_str());
|
||||
|
||||
return 0;
|
||||
}
|
||||
}
|
25
src/http_server/misc_tests/nytl_test1.cpp
Normal file
25
src/http_server/misc_tests/nytl_test1.cpp
Normal file
@ -0,0 +1,25 @@
|
||||
#include <jsonincpp/string_representation.h>
|
||||
#include <new_york_transit_line/templater.h>
|
||||
#include <new_york_transit_line/core.h>
|
||||
#include <engine_engine_number_9/os_utils.h>
|
||||
|
||||
int main(int argc, char** argv) {
|
||||
if (argc < 3) {
|
||||
fprintf(stderr, "Usage: test assets_dir config_file");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
std::string dir_path = argv[1];
|
||||
nytl::Templater templater(nytl::TemplaterSettings{nytl::TemplaterDetourRules{dir_path}});
|
||||
templater.update();
|
||||
|
||||
std::string config_file = argv[2];
|
||||
std::string config_text;
|
||||
een9::readFile(config_file, config_text);
|
||||
const json::JSON config = json::parse_str_flawless(config_text);
|
||||
|
||||
std::string answer2 = templater.render("login", {&config["presentation"].g()});
|
||||
printf("%s\n<a><f><t><e><r><><l><f>\n", answer2.c_str());
|
||||
|
||||
return 0;
|
||||
}
|
@ -72,6 +72,9 @@ namespace iu9cawebchat {
|
||||
if (req.uri_path == "/" || req.uri_path == "/list-rooms") {
|
||||
return rteee("list-rooms", false);
|
||||
}
|
||||
if (req.uri_path == "/login") {
|
||||
return rteee("login", true);
|
||||
}
|
||||
if (req.uri_path == "/chat") {
|
||||
return rteee("chat", false);
|
||||
}
|
||||
@ -126,8 +129,10 @@ namespace iu9cawebchat {
|
||||
auto translate_addr_list_conf = [&sap](std::vector<een9::SocketAddress>& dest, const std::vector<json::JSON>& source) {
|
||||
size_t N = source.size();
|
||||
dest.resize(N);
|
||||
for (size_t i = 0; i < N; i++)
|
||||
een9::parse_socket_address(source[i].asString(), dest[i], sap);
|
||||
for (size_t i = 0; i < N; i++) {
|
||||
int ret = een9::parse_socket_address(source[i].asString(), dest[i], sap);
|
||||
een9_ASSERT(ret == 0, "Incorrect ear address: " + source[i].asString());
|
||||
}
|
||||
};
|
||||
translate_addr_list_conf(params.client_regular_listened, config["server"]["http-listen"].g().asArray());
|
||||
translate_addr_list_conf(params.admin_control_listened, config["server"]["admin-command-listen"].g().asArray());
|
||||
|
Loading…
Reference in New Issue
Block a user