Update pages

This commit is contained in:
themohooks 2024-07-04 12:50:26 +03:00
parent 9a8bc356d2
commit cf7f7e959a
12 changed files with 598 additions and 33 deletions

View file

@ -0,0 +1,90 @@
<?php
namespace App\Controllers\Api;
use App\Services\{Auth, Router, GenerateRandomStr, DB, Json};
use \App\Controllers\ExceptionRegister;
use \App\Core\Page;
use donatj\UserAgent\UserAgentParser;
class Login
{
public function __construct()
{
$username = $_POST['username'];
$password = $_POST['password'];
if (DB::query('SELECT email FROM users WHERE email=:username OR username=:username', array(':username' => $username))) {
$email = DB::query('SELECT email FROM users WHERE email=:username OR username=:username', array(':username'=>$username))[0]['email'];
if (password_verify($password, DB::query('SELECT password FROM users WHERE email=:username', array(':username' => $email))[0]['password'])) {
$cstrong = True;
$token = GenerateRandomStr::gen_uuid();
$user_id = DB::query('SELECT id FROM users WHERE email=:username', array(':username' => $email))[0]['id'];
if (!empty($_SERVER['HTTP_CLIENT_IP'])) {
$ip = $_SERVER['HTTP_CLIENT_IP'];
} elseif (!empty($_SERVER['HTTP_X_FORWARDED_FOR'])) {
$ip = $_SERVER['HTTP_X_FORWARDED_FOR'];
} else {
$ip = $_SERVER['REMOTE_ADDR'];
}
$parser = new UserAgentParser();
$ua = $parser->parse();
$ua = $parser();
$servicekey = GenerateRandomStr::gen_uuid();
$url = 'http://ip-api.com/json/'.$ip;
$response = file_get_contents($url);
$data = json_decode($response, true);
$loc = $data['country'].', '.$data['city'];
DB::query('INSERT INTO login_tokens VALUES (\'0\', :token, :user_id, :platform, :browser, :browserversion, 0, :ip, :servicekey, :loc)', array(
':token' => $token,
':user_id' => $user_id,
':platform' => $ua->platform(),
':browser' => $ua->browser(),
':browserversion' => $ua->browserVersion(),
':ip' => $ip,
':servicekey' => $servicekey,
':loc' => $loc
));
setcookie("BIRUXSESS", $token, time() + 50 * 50 * 54 * 72, '/', NULL, NULL, TRUE);
setcookie("BIRUXSERVICE", $servicekey, time() + 50 * 50 * 54 * 72, '/', NULL, NULL, TRUE);
setcookie("BIRUXSESS_", '1', time() + 50 * 50 * 54 * 72, '/', NULL, NULL, TRUE);
setcookie("BIRUXID", $user_id, time() + 50 * 50 * 54 * 72, '/', NULL, NULL, TRUE);
echo Json::return (
array(
'errorcode' => '0',
'error' => 0
)
);
} else {
echo Json::return (
array(
'errorcode' => '1',
'error' => 1
)
);
}
} else {
echo Json::return (
array(
'errorcode' => '1',
'error' => 1
)
);
}
}
}

View file

@ -4,29 +4,13 @@ namespace App\Controllers;
use \App\Services\{Router, Auth, DB, Json}; use \App\Services\{Router, Auth, DB, Json};
use \App\Controllers\ExceptionRegister; use \App\Controllers\ExceptionRegister;
use \App\Core\Page; use \App\Core\Page;
use \App\Controllers\Api\Login;
class MainController class ApiController
{ {
public function __invoke()
{
}
public static function i() public static function login() {
{ return new Login();
}
public static function logout()
{
DB::query('DELETE FROM login_tokens WHERE servicekey=:userid', array(':userid'=>$_COOKIE['NGALLERYSERVICE']));
setcookie('NGALLERYSERVICE', '', 1);
setcookie('NGALLERYSESS', '', 1);
setcookie('NGALLERYSESS_', '', 1);
setcookie('NGALLERYID', '', 1);
header('Location: /');
} }
} }

View file

@ -12,7 +12,9 @@ class Routes
public static function init() public static function init()
{ {
Router::get('/', 'MainController@i'); Router::get('/', 'MainController@i');
Router::get('/login', 'LoginController@i');
Router::get('/photo/$id', 'PhotoController@i'); Router::get('/photo/$id', 'PhotoController@i');
Router::post('/api/login', 'ApiController@login');

View file

@ -16,6 +16,7 @@
"require": { "require": {
"aws/aws-sdk-php": "^3.315", "aws/aws-sdk-php": "^3.315",
"tracy/tracy": "^2.10", "tracy/tracy": "^2.10",
"symfony/yaml": "^7.1" "symfony/yaml": "^7.1",
"donatj/phpuseragentparser": "^1.8"
} }
} }

76
composer.lock generated
View file

@ -4,7 +4,7 @@
"Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies", "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies",
"This file is @generated automatically" "This file is @generated automatically"
], ],
"content-hash": "4cb3046ee61db32e4866c8f8ba6c0f99", "content-hash": "73b4865b189367ec43d243dbb63808e2",
"packages": [ "packages": [
{ {
"name": "aws/aws-crt-php", "name": "aws/aws-crt-php",
@ -155,6 +155,80 @@
}, },
"time": "2024-07-03T18:12:51+00:00" "time": "2024-07-03T18:12:51+00:00"
}, },
{
"name": "donatj/phpuseragentparser",
"version": "v1.8.0",
"source": {
"type": "git",
"url": "https://github.com/donatj/PhpUserAgent.git",
"reference": "b8c16fd6e963651c6d86f66cb782ce599d62418e"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/donatj/PhpUserAgent/zipball/b8c16fd6e963651c6d86f66cb782ce599d62418e",
"reference": "b8c16fd6e963651c6d86f66cb782ce599d62418e",
"shasum": ""
},
"require": {
"ext-ctype": "*",
"php": ">=5.4.0"
},
"require-dev": {
"camspiers/json-pretty": "~1.0",
"donatj/drop": "*",
"ext-json": "*",
"phpunit/phpunit": "~4.8|~9"
},
"type": "library",
"autoload": {
"files": [
"src/UserAgentParser.php"
],
"psr-4": {
"donatj\\UserAgent\\": "src/UserAgent"
}
},
"notification-url": "https://packagist.org/downloads/",
"license": [
"MIT"
],
"authors": [
{
"name": "Jesse G. Donat",
"email": "donatj@gmail.com",
"homepage": "https://donatstudios.com",
"role": "Developer"
}
],
"description": "Lightning fast, minimalist PHP UserAgent string parser.",
"homepage": "https://donatstudios.com/PHP-Parser-HTTP_USER_AGENT",
"keywords": [
"browser",
"browser detection",
"parser",
"user agent",
"useragent"
],
"support": {
"issues": "https://github.com/donatj/PhpUserAgent/issues",
"source": "https://github.com/donatj/PhpUserAgent/tree/v1.8.0"
},
"funding": [
{
"url": "https://www.paypal.me/donatj/15",
"type": "custom"
},
{
"url": "https://github.com/donatj",
"type": "github"
},
{
"url": "https://ko-fi.com/donatj",
"type": "ko_fi"
}
],
"time": "2023-10-27T05:22:44+00:00"
},
{ {
"name": "guzzlehttp/guzzle", "name": "guzzlehttp/guzzle",
"version": "7.8.1", "version": "7.8.1",

98
static/js/core.js Normal file
View file

@ -0,0 +1,98 @@
var _text = {};
function _getID(t)
{
return document.getElementById(t);
}
function trim(t)
{
return t.replace(/^\s+/, '').replace(/\s+$/, '');
}
function addTexts(txt)
{
for (var key in txt) _text[key] = txt[key];
}
function switchClass(objNode, strCurrClass, strNewClass)
{
if (matchClass(objNode, strNewClass))
replaceClass(objNode, strCurrClass, strNewClass);
else replaceClass(objNode, strNewClass, strCurrClass);
}
function removeClass(objNode, strCurrClass)
{
replaceClass(objNode, '', strCurrClass);
}
function addClass(objNode, strNewClass)
{
replaceClass(objNode, strNewClass, '');
}
function replaceClass(objNode, strNewClass, strCurrClass)
{
var strOldClass = strNewClass;
if (strCurrClass && strCurrClass.length)
{
strCurrClass = strCurrClass.replace('/\s+(\S)/g', '|$1');
if (strOldClass.length) strOldClass += '|';
strOldClass += strCurrClass;
}
objNode.className = objNode.className.replace(new RegExp('(^|\\s+)(' + strOldClass + ')($|\\s+)', 'g'), '$1');
objNode.className += ((objNode.className.length)? ' ' : '') + strNewClass;
}
function matchClass(objNode, strCurrClass)
{
return (objNode && objNode.className.length && objNode.className.match(new RegExp('(^|\\s+)(' + strCurrClass + ')($|\\s+)')));
}
function showId(id)
{
_getID(id).style.display = 'block';
}
function hideId(id)
{
_getID(id).style.display = 'none';
}
$(document).ready(function()
{
$(this).on('keydown', function(e)
{
if ($(e.target).is('input, textarea')) return;
if (e.ctrlKey)
{
var link;
switch (e.which)
{
case 0x24: window.location = '/'; return;
case 0x25: link = 'PrevLink'; break;
case 0x27: link = 'NextLink'; break;
case 0x26: link = 'UpLink'; break;
case 0x28: link = 'DownLink'; break;
}
if (link)
{
var a = $('#' + link);
if (a.length) window.location = a.attr('href')
}
}
});
$('a.self-close').on('click', function()
{
window.open(this.href);
return false;
});
$('input, select, textarea', $('.form-field')).on('focus blur', function() { $(this).closest('.form-field').toggleClass('active').prev('.form-label').toggleClass('active'); })
});

213
static/js/index.js Normal file
View file

@ -0,0 +1,213 @@
ar1 = new Image();
ar1.src = '/img/ar1.gif';
$(document).ready(function()
{
$('.ix-country > a[href="#"]').on('click', function(e)
{
var block = $(this).parent().next('div');
if (block.is(':hidden'))
{
block.slideDown();
$('.ix-arrow', this).addClass('ix-arrow-expanded');
}
else
{
block.slideUp();
$('.ix-arrow', this).removeClass('ix-arrow-expanded');
}
return false;
});
$(window).on('load resize', function()
{
var list = $('#idx-regions-list');
var h = list.closest('table').height() - list.position().top + 40;
list.css('height', h + 'px');
});
$('#loadmore').on('click', LoadRecentPhotos).click();
$('#newrand' ).on('click', LoadRandomPhotos).click();
updateInterval = setInterval(LoadPubPhotos, 60000);
//$('#cname').citySelector('cid', { defaultLabel: _text['IX_ANY'] });
$('#type').on('change', function() { $('#type').attr('class', $('#type option:selected').attr('class')); }).change();
$('#num').on('change keyup', function() { $('#qsearch').prop('disabled', $('#num').val().trim() == ''); }).on('keypress', function(event) { if (event.keyCode == 13) { searchVehicles(); return false; } }).change();
$('#searchbtn').on('click', searchVehicles);
/*$('#qcity').citySelector(null, {
selectCallback: function(item) { window.open('/city/' + item.value + '/'); },
clearField: true
});*/
$(document).on('click', function(e)
{
var target = $(e.target);
if (target.closest('#cars_list').length > 0 ||
target.closest('#idx-column-menu').length > 0 ||
target.is('#mobile-menu') ||
target.is('button')) return;
$('#cars_list').hide().html('');
var menu = $('div#idx-column-menu');
if (menu.is(':visible'))
{
menu.hide();
$('#backgr').hide();
}
e.stopPropagation();
});
$('#loginbtn').on('click', function()
{
var username = $('#username').val().trim();
var password = $('#password').val().trim();
if (username != '' && username != '')
{
$('#loginbtn').prop('disabled', true).val(_text['IX_LOGGING']);
$.post('/api.php?action=check-login', { username: username, password: password, remember: $('#remember').is('checked') }, function(r)
{
if (r == 0)
$('#loginform').submit();
else window.location.reload();
})
.fail(function(jx) { if (jx.responseText != '') alert(jx.responseText); });
}
});
$('#mobile-menu').on('click', function()
{
$('#idx-column-menu, #backgr').toggle();
return false;
});
$('.ix-plus, .ix-minus').on('click', function()
{
$(this).toggleClass('ix-plus ix-minus');
var block = $(this).closest('.ix-region');
$('.ix-hideable-citylist, .ix-hideable-cname', block).toggle();
return false;
});
});
function searchVehicles()
{
$('#cars_list').html('<img src="/img/wait.gif" style="display:block; padding:2px">').show();
$.get('/api.php', { action: 'index-qsearch', cid: $('#cid').val(), type: $('#type').val(), num: $('#num').val() }, function (r) { $('#cars_list').html(r); });
return false;
}
function AddPhotoToBlock(block, arr, prepend)
{
block[prepend ? 'prepend' : 'append']('<div class="prw-grid-item"><div class="prw-wrapper">' + arr.links + '<div>' + arr.pdate + '</div></div><a href="/photo/' + arr.pid + '/" target="_blank" class="prw-animate" style="background-image:url(\'' + arr.prw + '\')">' + (arr.ccnt != 0 ? '<div class="hdshade"><div class="com-icon">' + arr.ccnt + '</div></div>' : '') + '</a></div>');
}
function LoadRandomPhotos()
{
var random = $('#random-photos');
var width = random.is('.mobile') ? 0 : random.width();
var newrand = $('#newrand');
var loader = $('#newrand-loader');
newrand.hide();
loader.show();
$.getJSON('/api.php', { action: 'get-random-photos', width: width }, function(data)
{
random.html('');
if (data)
for (var i = 0; i < data.length; i++) AddPhotoToBlock(random, data[i]);
else random.append('Load error');
newrand.show();
loader.hide();
})
.fail(function(jx) { if (jx.responseText != '') console.log(jx.responseText); });
return false;
}
function LoadRecentPhotos()
{
var recent = $('#recent-photos');
var lastpid = recent.attr('lastpid');
var width = recent.width();
var loadmore = $('#loadmore');
var hidden = $('.prw-grid-item:hidden', recent);
if (recent.is('.mobile')) width *= 1.5;
loadmore.prop('disabled', true).addClass('loader-button').val(' ');
$.getJSON('/api.php', { action: 'get-recent-photos', width: width, lastpid: lastpid, hidden: hidden.length }, function(data)
{
if (data)
{
if (lastpid == 0) recent.attr('firstpid', data[0].pid);
hidden.show();
for (var i = 0; i < data.length; i++) AddPhotoToBlock(recent, data[i]);
recent.attr('lastpid', data[i-1].pid);
}
else recent.append('Load error');
loadmore.prop('disabled', false).removeClass('loader-button').val(_text['IX_LOADMORE']);
})
.fail(function(jx) { if (jx.responseText != '') console.log(jx.responseText); });
}
function LoadPubPhotos()
{
var recent = $('#recent-photos');
var firstpid = recent.attr('firstpid');
if (firstpid == 0) return;
$.getJSON('/api.php', { action: 'get-pub-photos', firstpid: firstpid }, function(data)
{
if (data)
{
if (data.length)
{
for (var i = 0; i < data.length; i++)
{
$('.prw-grid-item:visible', recent).eq(-1).hide();
AddPhotoToBlock(recent, data[i], true);
}
recent.attr('firstpid', data[i-1].pid);
}
}
else clearInterval(updateInterval);
})
.fail(function(jx) { if (jx.responseText != '') console.log(jx.responseText); });
}

1
static/js/jquery-ui.js vendored Normal file

File diff suppressed because one or more lines are too long

5
static/js/jquery.js vendored Normal file

File diff suppressed because one or more lines are too long

View file

@ -8,4 +8,8 @@
<link rel="stylesheet" href="/static/css/style.css"> <link rel="stylesheet" href="/static/css/style.css">
<link rel="stylesheet" href="/static/css/desktop.css"> <link rel="stylesheet" href="/static/css/desktop.css">
<link rel="stylesheet" href="/static/css/trans.css"> <link rel="stylesheet" href="/static/css/trans.css">
<link rel="stylesheet" href="/static/css/photo.css"> <link rel="stylesheet" href="/static/css/photo.css">
<script src="/static/js/jquery.js"></script>
<script src="/static/js/jquery-ui.js"></script>
<script src="/static/js/core.js"></script>
<script src="/static/js/index.js"></script>

View file

@ -0,0 +1,99 @@
<!DOCTYPE html>
<html lang="ru">
<head>
<?php include($_SERVER['DOCUMENT_ROOT'] . '/views/components/LoadHead.php'); ?>
</head>
<body>
<div id="backgr"></div>
<table class="tmain">
<?php include($_SERVER['DOCUMENT_ROOT'] . '/views/components/Navbar.php'); ?>
<div id="backgr"></div>
<tr>
<td class="main">
<center>
<h1>Вход на сайт</h1>
<div class="mf-center-block mf-label">
<form id="form" method="post" class="p20i mf-center-block-wide mf-label">
<input type="hidden" name="ref" value="/">
<input type="text" name="username" id="username" class="mf-input-wide" placeholder="Имя или e-mail" value="">
<div style="color:#e00" id="err_username"></div>
<input type="password" name="password" id="password" class="mf-input-wide" placeholder="Пароль">
<div style="color:#e00" id="err_password"></div>
<input type="button" id="loginbtn" class="mf-button-wide" value="Войти">
</form>
<div style="margin-top:15px"><a href="/register.php" class="mf-button">Регистрация</a></div>
<div style="margin-top:15px"><a href="/forgot.php" class="mf-label-narrow">Забыли пароль?</a></div>
</div><br />
<script>
$(document).ready(function() {
$('#username').on('input', function() {
$('#err_password, #err_username').html('');
});
$('#password').on('input', function() {
$('#err_password').html('');
});
$('#loginbtn').on('click', function() {
var username = $('#username').val().trim();
var password = $('#password').val().trim();
var err_username = $('#err_username').html('');
var err_password = $('#err_password').html('');
if (username == '') err_username.html('Поле не заполнено');
if (password == '') err_password.html('Поле не заполнено');
if (err_username.html() + err_password.html() == '') {
$('#loginbtn').prop('disabled', true).val('Отправка данных...');
$.post('/api/login', {
username: username,
password: password,
remember: $('#remember').is('checked')
}, function(r) {
r = JSON.parse(r);
if (r.errorcode == 1) {
err_password.html('Неверно указаны логин и/или пароль');
$('#loginbtn').prop('disabled', false).val('Войти');
} else window.location.href = '/';
})
.fail(function(jx) {
if (jx.responseText != '') alert(jx.responseText);
});
}
});
});
</script>
</center>
</td>
</tr>
<tr>
<td class="footer"><b><a href="/">Главная</a> &nbsp; &nbsp; <a href="https://forum.transphoto.org">Форум</a> &nbsp; &nbsp; <a href="/rules/">Правила</a> &nbsp; &nbsp; <a href="/admin/">Редколлегия</a></b><br>
<a href="/set.php?pcver=0">Мобильная версия</a><br><a href="/set.php?dark=1" style="display:inline-block; padding:1px 10px; margin-top:5px; background-color:#333; color:#fff">Тёмная тема</a>
<div class="sitecopy">&copy; Администрация ТрансФото и авторы материалов, 2002—2024<br>Использование фотографий и иных материалов, опубликованных на сайте, допускается только с разрешения их авторов.</div>
<div style="margin:15px 0">
</div>
</td>
</tr>
</table>
</body>
</html>

View file

@ -2,16 +2,10 @@
<html lang="ru"> <html lang="ru">
<head> <head>
<meta http-equiv="content-type" content="text/html;charset=UTF-8"> <?php include($_SERVER['DOCUMENT_ROOT'] . '/views/components/LoadHead.php'); ?>
<meta name="viewport" content="width=1000,user-scalable=yes">
<title>NativeGallery</title>
<link rel="preconnect" href="https://fonts.googleapis.com"> </head>
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
<link href="https://fonts.googleapis.com/css2?family=PT+Sans+Narrow:wght@400;700&amp;display=swap" rel="stylesheet">
<link rel="stylesheet" href="/static/css/fontawesome/css/all.min.css?1649451403">
<link rel="stylesheet" href="/static/css/style.css?1718122698">
<link rel="stylesheet" href="/static/css/desktop.css?1704280890">
<link rel="stylesheet" href="/static/css/trans.css?1670622746">
<style> <style>