mirror of
https://github.com/openvk/openvk
synced 2024-11-11 01:19:53 +03:00
Merge branch 'master' of github.com:openvk/openvk
This commit is contained in:
commit
4d6af6d28e
18 changed files with 437 additions and 17 deletions
204
Email/verify-email.eml.latte
Executable file
204
Email/verify-email.eml.latte
Executable file
|
@ -0,0 +1,204 @@
|
||||||
|
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
|
||||||
|
<html xmlns="http://www.w3.org/1999/xhtml">
|
||||||
|
<head>
|
||||||
|
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
|
||||||
|
<meta name="viewport" content="width=device-width" />
|
||||||
|
<title>Подтверждение Email</title>
|
||||||
|
<link rel="stylesheet" href="foundation.css" />
|
||||||
|
<style>
|
||||||
|
.container {
|
||||||
|
border-top: 5px solid pink;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
<table class="body" data-made-with-foundation="">
|
||||||
|
<tr>
|
||||||
|
<td class="float-center" align="center" valign="top">
|
||||||
|
<center>
|
||||||
|
<table class="spacer">
|
||||||
|
<tr>
|
||||||
|
<td>
|
||||||
|
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
</table>
|
||||||
|
<table class="container">
|
||||||
|
<tr>
|
||||||
|
<td>
|
||||||
|
<table class="row header">
|
||||||
|
<tr>
|
||||||
|
<th class="small-12 large-12 columns first last">
|
||||||
|
<table>
|
||||||
|
<tr>
|
||||||
|
<th>
|
||||||
|
<table class="spacer">
|
||||||
|
<tr>
|
||||||
|
<td>
|
||||||
|
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
</table>
|
||||||
|
<h4 class="text-center">Подтверждение Email</h4>
|
||||||
|
</th>
|
||||||
|
</tr>
|
||||||
|
</table>
|
||||||
|
</th>
|
||||||
|
</tr>
|
||||||
|
</table>
|
||||||
|
|
||||||
|
<table class="row">
|
||||||
|
<tr>
|
||||||
|
<th class="small-12 large-12 columns first last">
|
||||||
|
<table class="row">
|
||||||
|
<tr>
|
||||||
|
<td>
|
||||||
|
<center>
|
||||||
|
<img src="pictures/lock.jpeg" align="center" class="float-center" width=128 height=128 />
|
||||||
|
</center>
|
||||||
|
|
||||||
|
<table class="spacer">
|
||||||
|
<tr>
|
||||||
|
<td>
|
||||||
|
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
</table>
|
||||||
|
|
||||||
|
<hr/>
|
||||||
|
|
||||||
|
<table class="spacer">
|
||||||
|
<tr>
|
||||||
|
<td>
|
||||||
|
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
</table>
|
||||||
|
|
||||||
|
<p class="text-left">
|
||||||
|
Здравствуйте, {$name}! Вы вероятно зарегистрировались на одном из инстансов OpenVK. Чтобы ваш аккаунт активировался, необходимо подтвердить Email.
|
||||||
|
</p>
|
||||||
|
|
||||||
|
<table class="spacer">
|
||||||
|
<tr>
|
||||||
|
<td>
|
||||||
|
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
</table>
|
||||||
|
|
||||||
|
<table class="button large expand success">
|
||||||
|
<tr>
|
||||||
|
<td>
|
||||||
|
<table>
|
||||||
|
<tr>
|
||||||
|
<td>
|
||||||
|
<center>
|
||||||
|
<a href="http://{$_SERVER['HTTP_HOST']}/regFinish?key={rawurlencode($key)}" align="center" class="float-center">Подтвердить Email!</a>
|
||||||
|
</center>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
</table>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
</table>
|
||||||
|
|
||||||
|
<table class="spacer">
|
||||||
|
<tr>
|
||||||
|
<td>
|
||||||
|
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
</table>
|
||||||
|
|
||||||
|
<p class="text-left">
|
||||||
|
Если кнопка не работает, вы можете попробовать скопировать и вставить эту ссылку в адресную строку вашего веб-обозревателя:
|
||||||
|
</p>
|
||||||
|
|
||||||
|
<table class="callout">
|
||||||
|
<tr>
|
||||||
|
<th class="callout-inner primary">
|
||||||
|
<a href="http://{$_SERVER['HTTP_HOST']}/regFinish?key={$key}" style="color: #000; text-decoration: none;">
|
||||||
|
http://{$_SERVER['HTTP_HOST']}/regFinish?key={$key}
|
||||||
|
</a>
|
||||||
|
</th>
|
||||||
|
</tr>
|
||||||
|
</table>
|
||||||
|
|
||||||
|
<p class="text-left">
|
||||||
|
Обратите внимание на то, что эту ссылку нельзя:
|
||||||
|
</p>
|
||||||
|
|
||||||
|
<ul>
|
||||||
|
<li>Передавать другим людям (даже друзьям, питомцам, соседам, любимым девушкам)</li>
|
||||||
|
<li>Использовать, если прошло более двух дней с её генерации</li>
|
||||||
|
</ul>
|
||||||
|
|
||||||
|
<table class="callout">
|
||||||
|
<tr>
|
||||||
|
<th class="callout-inner alert">
|
||||||
|
<p>
|
||||||
|
Ещё раз <b>обратите внимание</b> на то, что данную ссылку или письмо <b>ни в коем случае нельзя</b> передавать другим людям! Даже если они представляются службой поддержки.<br/>
|
||||||
|
Это письмо предназначено исключительно для одноразового, <b>непосредственного</b> использования владельцем аккаунта.
|
||||||
|
</p>
|
||||||
|
</th>
|
||||||
|
</tr>
|
||||||
|
</table>
|
||||||
|
|
||||||
|
<table class="spacer">
|
||||||
|
<tr>
|
||||||
|
<td>
|
||||||
|
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
</table>
|
||||||
|
|
||||||
|
<p class="text-right">
|
||||||
|
С уважением, овк-тян.
|
||||||
|
</p>
|
||||||
|
|
||||||
|
<table class="spacer">
|
||||||
|
<tr>
|
||||||
|
<td>
|
||||||
|
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
</table>
|
||||||
|
|
||||||
|
<hr/>
|
||||||
|
|
||||||
|
<table class="spacer">
|
||||||
|
<tr>
|
||||||
|
<td>
|
||||||
|
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
</table>
|
||||||
|
|
||||||
|
<p class="text-left">
|
||||||
|
<small>
|
||||||
|
Вы получили это письмо так как кто-то или вы зарегистрировались на инстансе OpenVK. Это не рассылка и от неё нельзя отписаться. Если вы всё равно хотите перестать получать подобные письма, деактивируйте ваш аккаунт.
|
||||||
|
</small>
|
||||||
|
</p>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
</table>
|
||||||
|
</th>
|
||||||
|
</tr>
|
||||||
|
</table>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
</table>
|
||||||
|
<table class="spacer">
|
||||||
|
<tr>
|
||||||
|
<td>
|
||||||
|
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
</table>
|
||||||
|
</center>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
</table>
|
||||||
|
</body>
|
||||||
|
</html>
|
10
Web/Models/Entities/EmailVerification.php
Executable file
10
Web/Models/Entities/EmailVerification.php
Executable file
|
@ -0,0 +1,10 @@
|
||||||
|
<?php declare(strict_types=1);
|
||||||
|
namespace openvk\Web\Models\Entities;
|
||||||
|
use openvk\Web\Models\Repositories\Users;
|
||||||
|
use openvk\Web\Models\RowModel;
|
||||||
|
use openvk\Web\Util\DateTime;
|
||||||
|
|
||||||
|
class EmailVerification extends PasswordReset
|
||||||
|
{
|
||||||
|
protected $tableName = "email_verifications";
|
||||||
|
}
|
|
@ -34,12 +34,15 @@ class PasswordReset extends RowModel
|
||||||
*/
|
*/
|
||||||
function isNew(): bool
|
function isNew(): bool
|
||||||
{
|
{
|
||||||
return $this->getRecord()->timestamp > (time() - 301);
|
return $this->getRecord()->timestamp > (time() - (5 * MINUTE));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Token is valid only for 3 days.
|
||||||
|
*/
|
||||||
function isStillValid(): bool
|
function isStillValid(): bool
|
||||||
{
|
{
|
||||||
return $this->getRecord()->timestamp > (time() - 172801);
|
return $this->getRecord()->timestamp > (time() - (3 * DAY));
|
||||||
}
|
}
|
||||||
|
|
||||||
function verify(string $token): bool
|
function verify(string $token): bool
|
||||||
|
|
|
@ -883,5 +883,11 @@ class User extends RowModel
|
||||||
return $this->getRecord()->website;
|
return $this->getRecord()->website;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// ты устрица
|
||||||
|
function isActivated(): bool
|
||||||
|
{
|
||||||
|
return (bool) $this->getRecord()->activated;
|
||||||
|
}
|
||||||
|
|
||||||
use Traits\TSubscribable;
|
use Traits\TSubscribable;
|
||||||
}
|
}
|
||||||
|
|
33
Web/Models/Repositories/Verifications.php
Executable file
33
Web/Models/Repositories/Verifications.php
Executable file
|
@ -0,0 +1,33 @@
|
||||||
|
<?php declare(strict_types=1);
|
||||||
|
namespace openvk\Web\Models\Repositories;
|
||||||
|
use Chandler\Database\DatabaseConnection;
|
||||||
|
use openvk\Web\Models\Entities\EmailVerification;
|
||||||
|
use openvk\Web\Models\Entities\User;
|
||||||
|
use Nette\Database\Table\ActiveRow;
|
||||||
|
|
||||||
|
class Verifications
|
||||||
|
{
|
||||||
|
private $context;
|
||||||
|
private $verifications;
|
||||||
|
|
||||||
|
function __construct()
|
||||||
|
{
|
||||||
|
$this->context = DatabaseConnection::i()->getContext();
|
||||||
|
$this->verifications = $this->context->table("email_verifications");
|
||||||
|
}
|
||||||
|
|
||||||
|
function toEmailVerification(?ActiveRow $ar): ?EmailVerification
|
||||||
|
{
|
||||||
|
return is_null($ar) ? NULL : new EmailVerification($ar);
|
||||||
|
}
|
||||||
|
|
||||||
|
function getByToken(string $token): ?EmailVerification
|
||||||
|
{
|
||||||
|
return $this->toEmailVerification($this->verifications->where("key", $token)->fetch());
|
||||||
|
}
|
||||||
|
|
||||||
|
function getLatestByUser(User $user): ?EmailVerification
|
||||||
|
{
|
||||||
|
return $this->toEmailVerification($this->verifications->where("profile", $user->getId())->order("timestamp DESC")->fetch());
|
||||||
|
}
|
||||||
|
}
|
|
@ -8,6 +8,7 @@ use Chandler\Session\Session;
|
||||||
final class AboutPresenter extends OpenVKPresenter
|
final class AboutPresenter extends OpenVKPresenter
|
||||||
{
|
{
|
||||||
protected $banTolerant = true;
|
protected $banTolerant = true;
|
||||||
|
protected $activationTolerant = true;
|
||||||
|
|
||||||
function renderIndex(): void
|
function renderIndex(): void
|
||||||
{
|
{
|
||||||
|
|
|
@ -3,9 +3,11 @@ namespace openvk\Web\Presenters;
|
||||||
use openvk\Web\Models\Entities\IP;
|
use openvk\Web\Models\Entities\IP;
|
||||||
use openvk\Web\Models\Entities\User;
|
use openvk\Web\Models\Entities\User;
|
||||||
use openvk\Web\Models\Entities\PasswordReset;
|
use openvk\Web\Models\Entities\PasswordReset;
|
||||||
|
use openvk\Web\Models\Entities\EmailVerification;
|
||||||
use openvk\Web\Models\Repositories\IPs;
|
use openvk\Web\Models\Repositories\IPs;
|
||||||
use openvk\Web\Models\Repositories\Users;
|
use openvk\Web\Models\Repositories\Users;
|
||||||
use openvk\Web\Models\Repositories\Restores;
|
use openvk\Web\Models\Repositories\Restores;
|
||||||
|
use openvk\Web\Models\Repositories\Verifications;
|
||||||
use openvk\Web\Util\Validator;
|
use openvk\Web\Util\Validator;
|
||||||
use Chandler\Session\Session;
|
use Chandler\Session\Session;
|
||||||
use Chandler\Security\User as ChandlerUser;
|
use Chandler\Security\User as ChandlerUser;
|
||||||
|
@ -16,19 +18,22 @@ use lfkeitel\phptotp\{Base32, Totp};
|
||||||
final class AuthPresenter extends OpenVKPresenter
|
final class AuthPresenter extends OpenVKPresenter
|
||||||
{
|
{
|
||||||
protected $banTolerant = true;
|
protected $banTolerant = true;
|
||||||
|
protected $activationTolerant = true;
|
||||||
|
|
||||||
private $authenticator;
|
private $authenticator;
|
||||||
private $db;
|
private $db;
|
||||||
private $users;
|
private $users;
|
||||||
private $restores;
|
private $restores;
|
||||||
|
private $verifications;
|
||||||
|
|
||||||
function __construct(Users $users, Restores $restores)
|
function __construct(Users $users, Restores $restores, Verifications $verifications)
|
||||||
{
|
{
|
||||||
$this->authenticator = Authenticator::i();
|
$this->authenticator = Authenticator::i();
|
||||||
$this->db = DatabaseConnection::i()->getContext();
|
$this->db = DatabaseConnection::i()->getContext();
|
||||||
|
|
||||||
$this->users = $users;
|
$this->users = $users;
|
||||||
$this->restores = $restores;
|
$this->restores = $restores;
|
||||||
|
$this->verifications = $verifications;
|
||||||
|
|
||||||
parent::__construct();
|
parent::__construct();
|
||||||
}
|
}
|
||||||
|
@ -96,6 +101,7 @@ final class AuthPresenter extends OpenVKPresenter
|
||||||
$user->setSince(date("Y-m-d H:i:s"));
|
$user->setSince(date("Y-m-d H:i:s"));
|
||||||
$user->setRegistering_Ip(CONNECTING_IP);
|
$user->setRegistering_Ip(CONNECTING_IP);
|
||||||
$user->setBirthday(strtotime($this->postParam("birthday")));
|
$user->setBirthday(strtotime($this->postParam("birthday")));
|
||||||
|
$user->setActivated((int) !OPENVK_ROOT_CONF['openvk']['preferences']['security']['requireEmail']);
|
||||||
$user->save();
|
$user->save();
|
||||||
|
|
||||||
if(!is_null($referer)) {
|
if(!is_null($referer)) {
|
||||||
|
@ -103,6 +109,18 @@ final class AuthPresenter extends OpenVKPresenter
|
||||||
$referer->toggleSubscription($user);
|
$referer->toggleSubscription($user);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (OPENVK_ROOT_CONF['openvk']['preferences']['security']['requireEmail']) {
|
||||||
|
$verification = new EmailVerification;
|
||||||
|
$verification->setProfile($user->getId());
|
||||||
|
$verification->save();
|
||||||
|
|
||||||
|
$params = [
|
||||||
|
"key" => $verification->getKey(),
|
||||||
|
"name" => $user->getCanonicalName(),
|
||||||
|
];
|
||||||
|
$this->sendmail($user->getEmail(), "verify-email", $params); #Vulnerability possible
|
||||||
|
}
|
||||||
|
|
||||||
$this->authenticator->authenticate($chUser->getId());
|
$this->authenticator->authenticate($chUser->getId());
|
||||||
$this->redirect("/id" . $user->getId(), static::REDIRECT_TEMPORARY);
|
$this->redirect("/id" . $user->getId(), static::REDIRECT_TEMPORARY);
|
||||||
}
|
}
|
||||||
|
@ -253,4 +271,48 @@ final class AuthPresenter extends OpenVKPresenter
|
||||||
$this->flashFail("succ", tr("information_-1"), tr("password_reset_email_sent"));
|
$this->flashFail("succ", tr("information_-1"), tr("password_reset_email_sent"));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function renderResendEmail(): void
|
||||||
|
{
|
||||||
|
if(!is_null($this->user) && $this->user->identity->isActivated())
|
||||||
|
$this->redirect("/id" . $this->user->id, static::REDIRECT_TEMPORARY);
|
||||||
|
|
||||||
|
if($_SERVER["REQUEST_METHOD"] === "POST") {
|
||||||
|
$user = $this->user->identity;
|
||||||
|
if(!$user || $user->isDeleted() || $user->isActivated())
|
||||||
|
$this->flashFail("err", tr("error"), tr("email_error"));
|
||||||
|
|
||||||
|
$request = $this->verifications->getLatestByUser($user);
|
||||||
|
if(!is_null($request) && $request->isNew())
|
||||||
|
$this->flashFail("err", tr("forbidden"), tr("email_rate_limit_error"));
|
||||||
|
|
||||||
|
$verification = new EmailVerification;
|
||||||
|
$verification->setProfile($user->getId());
|
||||||
|
$verification->save();
|
||||||
|
|
||||||
|
$params = [
|
||||||
|
"key" => $verification->getKey(),
|
||||||
|
"name" => $user->getCanonicalName(),
|
||||||
|
];
|
||||||
|
$this->sendmail($user->getEmail(), "verify-email", $params); #Vulnerability possible
|
||||||
|
|
||||||
|
$this->flashFail("succ", tr("information_-1"), tr("email_sent"));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function renderVerifyEmail(): void
|
||||||
|
{
|
||||||
|
$request = $this->verifications->getByToken(str_replace(" ", "+", $this->queryParam("key")));
|
||||||
|
if(!$request || !$request->isStillValid()) {
|
||||||
|
$this->flash("err", tr("token_manipulation_error"), tr("token_manipulation_error_comment"));
|
||||||
|
$this->redirect("/");
|
||||||
|
} else {
|
||||||
|
$user = $request->getUser();
|
||||||
|
$user->setActivated(1);
|
||||||
|
$user->save();
|
||||||
|
|
||||||
|
$this->flash("success", tr("email_verify_success"));
|
||||||
|
$this->redirect("/");
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -13,6 +13,7 @@ use WhichBrowser;
|
||||||
abstract class OpenVKPresenter extends SimplePresenter
|
abstract class OpenVKPresenter extends SimplePresenter
|
||||||
{
|
{
|
||||||
protected $banTolerant = false;
|
protected $banTolerant = false;
|
||||||
|
protected $activationTolerant = false;
|
||||||
protected $errorTemplate = "@error";
|
protected $errorTemplate = "@error";
|
||||||
protected $user = NULL;
|
protected $user = NULL;
|
||||||
|
|
||||||
|
@ -212,6 +213,27 @@ abstract class OpenVKPresenter extends SimplePresenter
|
||||||
$this->template->userTainted = $user->isTainted();
|
$this->template->userTainted = $user->isTainted();
|
||||||
|
|
||||||
if($this->user->identity->isDeleted()) {
|
if($this->user->identity->isDeleted()) {
|
||||||
|
/*
|
||||||
|
⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⣠⣴⠶⠶⣶⠶⠶⠶⠶⠶⠶⠶⠶⠶⢶⠶⠶⠶⠤⠤⠤⠤⣄⣀⣀⡀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀
|
||||||
|
⠀⠀⠀⠀⠀⠀⠀⠀⣠⡾⠋⠀⠀⠊⠀⠀⠀⠀⠀⠀⠀⠀⠒⠒⠒⠀⠀⠀⠀⠤⢤⣤⣄⠉⠉⠛⠛⠷⣦⣀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀
|
||||||
|
⠀⠀⠀⠀⠀⠀⠀⣰⠟⠀⠀⠀⠀⠀⠐⠋⢑⣤⣶⣶⣤⡢⡀⠀⠀⠀⠀⠀⠀⠀⠀⢀⣠⣄⡂⠀⠀⠶⢄⠙⢷⣤⠀⠀⠀⠀⠀⠀⠀⠀
|
||||||
|
⠀⠀⠀⠀⠀⠀⣸⡿⠚⠉⡀⠀⠀⠀⠀⢰⣿⣿⣿⣿⣿⣿⡄⠀⠀⠀⢢⠀⠀⡀⣰⣿⣿⣿⣿⣦⡀⠀⠀⠡⡀⢹⡆⠀⠀⠀⠀⠀⠀⠀
|
||||||
|
⠀⠀⠀⠀⢀⣴⠏⠀⣀⣀⣀⡤⢤⣄⣠⣿⣿⣿⣿⣻⣿⣿⣷⠀⢋⣾⠈⠙⣶⠒⢿⣿⣿⣿⣿⡿⠟⠃⠀⡀⠡⠼⣧⡀⠀⠀⠀⠀⠀⠀
|
||||||
|
⠀⠀⢀⣴⣿⢃⡴⢊⢽⣶⣤⣀⠀⠊⠉⠉⡛⢿⣿⣿⣿⠿⠋⢀⡀⠁⠀⠀⢸⣁⣀⣉⣉⣉⡉⠀⠩⡡⠀⣩⣦⠀⠈⠻⣦⡀⠀⠀⠀⠀
|
||||||
|
⠀⢠⡟⢡⠇⡞⢀⠆⠀⢻⣿⣿⣷⣄⠀⢀⠈⠂⠈⢁⡤⠚⡟⠉⠀⣀⣀⠀⠈⠳⣍⠓⢆⢀⡠⢀⣨⣴⣿⣿⡏⢀⡆⠀⢸⡇⠀⠀⠀⠀
|
||||||
|
⠀⣾⠁⢸⠀⠀⢸⠀⠀⠀⠹⣿⣿⣿⣿⣶⣬⣦⣤⡈⠀⠀⠇⠀⠛⠉⣩⣤⣤⣤⣿⣤⣤⣴⣾⣿⣿⣿⣿⣿⣧⠞⠀⠀⢸⡇⠀⠀⠀⠀
|
||||||
|
⠀⢹⣆⠸⠀⠀⢸⠀⠀⠀⠀⠘⢿⣿⣿⣿⣿⣿⣿⣟⣛⠛⠛⣛⡛⠛⠛⣛⣋⡉⠉⣡⠶⢾⣿⣿⣿⣿⣿⣿⡇⠀⠀⢀⣾⠃⠀⠀⠀⠀
|
||||||
|
⠀⠀⠻⣆⡀⠀⠈⢂⠀⠀⠀⠠⡈⢻⣿⣿⣿⣿⡟⠁⠈⢧⡼⠉⠙⣆⡞⠁⠈⢹⣴⠃⠀⢸⣿⣿⣿⣿⣿⣿⠃⠀⡆⣾⠃⠀⠀⠀⠀⠀
|
||||||
|
⠀⠀⠀⠈⢻⣇⠀⠀⠀⠀⠀⠀⢡⠀⠹⣿⣿⣿⣷⡀⠀⣸⡇⠀⠀⣿⠁⠀⠀⠘⣿⠀⠀⠘⣿⣿⣿⣿⣿⣿⠀⠀⣿⡇⠀⠀⠀⠀⠀⠀
|
||||||
|
⠀⠀⠀⠀⠀⠹⣇⠀⠠⠀⠀⠀⠀⠡⠐⢬⡻⣿⣿⣿⣿⣿⣷⣶⣶⣿⣦⣤⣤⣤⣿⣦⣶⣿⣿⣿⣿⣿⣿⣿⠀⠀⣿⡇⠀⠀⠀⠀⠀⠀
|
||||||
|
⠀⠀⠀⠀⠀⠀⠹⣧⡀⠡⡀⠀⠀⠀⠑⠄⠙⢎⠻⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣦⠀⢿⡇⠀⠀⠀⠀⠀⠀
|
||||||
|
⠀⠀⠀⠀⠀⠀⠀⠈⠳⣤⡐⡄⠀⠀⠀⠈⠂⠀⠱⣌⠻⣿⣿⣿⣿⣿⣿⣿⠿⣿⠟⢻⡏⢻⣿⣿⣿⣿⣿⣿⣿⠀⢸⡇⠀⠀⠀⠀⠀⠀
|
||||||
|
⠀⠀⠀⠀⠀⠀⠀⠀⠀⠈⠻⢮⣦⡀⠂⠀⢀⠀⠀⠈⠳⣈⠻⣿⣿⣿⡇⠘⡄⢸⠀⠀⣇⠀⣻⣿⣿⣿⣿⣿⡏⠀⠸⡇⠀⠀⠀⠀⠀⠀
|
||||||
|
⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠉⠛⢶⣤⣄⡑⠄⠀⠀⠈⠑⠢⠙⠻⢷⣶⣵⣞⣑⣒⣋⣉⣁⣻⣿⠿⠟⠱⠃⡸⠀⣧⠀⠀⠀⠀⠀⠀
|
||||||
|
⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠉⠛⠻⣷⣄⡀⠐⠢⣄⣀⡀⠀⠉⠉⠉⠉⠛⠙⠭⠭⠄⠒⠈⠀⠐⠁⢀⣿⠀⠀⠀⠀⠀⠀
|
||||||
|
⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠉⠛⠷⢦⣤⣤⣀⣀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⣒⡠⠄⣠⡾⠃⠀⠀⠀⠀⠀⠀
|
||||||
|
⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠉⠙⠛⠷⠶⣦⣤⣭⣤⣬⣭⣭⣴⠶⠛⠉⠀⠀⠀⠀⠀⠀⠀⠀
|
||||||
|
*/
|
||||||
Authenticator::i()->logout();
|
Authenticator::i()->logout();
|
||||||
Session::i()->set("_su", NULL);
|
Session::i()->set("_su", NULL);
|
||||||
$this->flashFail("err", tr("error"), tr("profile_not_found"));
|
$this->flashFail("err", tr("error"), tr("profile_not_found"));
|
||||||
|
@ -228,6 +250,17 @@ abstract class OpenVKPresenter extends SimplePresenter
|
||||||
exit;
|
exit;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// ето для емейл уже надо (и по хорошему надо бы избавится от повторяющегося кода мда)
|
||||||
|
if(!$this->user->identity->isActivated() && !$this->activationTolerant) {
|
||||||
|
header("HTTP/1.1 403 Forbidden");
|
||||||
|
$this->getTemplatingEngine()->render(__DIR__ . "/templates/@email.xml", [
|
||||||
|
"thisUser" => $this->user->identity,
|
||||||
|
"csrfToken" => $GLOBALS["csrfToken"],
|
||||||
|
"isTimezoned" => Session::i()->get("_timezoneOffset"),
|
||||||
|
]);
|
||||||
|
exit;
|
||||||
|
}
|
||||||
|
|
||||||
if ($this->user->identity->onlineStatus() == 0) {
|
if ($this->user->identity->onlineStatus() == 0) {
|
||||||
$this->user->identity->setOnline(time());
|
$this->user->identity->setOnline(time());
|
||||||
$this->user->identity->save();
|
$this->user->identity->save();
|
||||||
|
|
19
Web/Presenters/templates/@email.xml
Executable file
19
Web/Presenters/templates/@email.xml
Executable file
|
@ -0,0 +1,19 @@
|
||||||
|
{extends "@layout.xml"}
|
||||||
|
{block title}{_ec_header}{/block}
|
||||||
|
|
||||||
|
{block header}
|
||||||
|
{_ec_header}
|
||||||
|
{/block}
|
||||||
|
|
||||||
|
{block content}
|
||||||
|
<div class="border-block center">
|
||||||
|
<h4>{_ec_title}</h4>
|
||||||
|
<p>{tr("ec_1", htmlentities($thisUser->getCanonicalName()))|noescape}<br/></p>
|
||||||
|
<p>{_ec_2}</p>
|
||||||
|
<p>
|
||||||
|
<form action="/reg/resend" method="post">
|
||||||
|
<input type="submit" class="button" value="{_ec_resend}">
|
||||||
|
</form>
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
{/block}
|
|
@ -93,14 +93,14 @@
|
||||||
<div class="dimmer"></div>
|
<div class="dimmer"></div>
|
||||||
|
|
||||||
<div class="toTop">
|
<div class="toTop">
|
||||||
⬆ Вверх
|
⬆ {_to_top}
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="layout">
|
<div class="layout">
|
||||||
<div id="xhead" class="dm"></div>
|
<div id="xhead" class="dm"></div>
|
||||||
<div class="page_header {if $instance_name != OPENVK_DEFAULT_INSTANCE_NAME}page_custom_header{/if}">
|
<div class="page_header {if $instance_name != OPENVK_DEFAULT_INSTANCE_NAME}page_custom_header{/if}">
|
||||||
<a href="/" class="home_button {if $instance_name != OPENVK_DEFAULT_INSTANCE_NAME}home_button_custom{/if}" title="{$instance_name}">{$instance_name}</a>
|
<a href="/" class="home_button {if $instance_name != OPENVK_DEFAULT_INSTANCE_NAME}home_button_custom{/if}" title="{$instance_name}">{$instance_name}</a>
|
||||||
<div n:if="isset($thisUser) ? !$thisUser->isBanned() : true" class="header_navigation">
|
<div n:if="isset($thisUser) ? (!$thisUser->isBanned() XOR !$thisUser->isActivated()) : true" class="header_navigation">
|
||||||
{ifset $thisUser}
|
{ifset $thisUser}
|
||||||
<div class="link">
|
<div class="link">
|
||||||
<a href="/">{_header_home}</a>
|
<a href="/">{_header_home}</a>
|
||||||
|
@ -142,7 +142,7 @@
|
||||||
<div class="sidebar">
|
<div class="sidebar">
|
||||||
<div class="navigation">
|
<div class="navigation">
|
||||||
{ifset $thisUser}
|
{ifset $thisUser}
|
||||||
{if !$thisUser->isBanned()}
|
{if !$thisUser->isBanned() XOR !$thisUser->isActivated()}
|
||||||
<a href="/edit" class="link edit-button">{_edit_button}</a>
|
<a href="/edit" class="link edit-button">{_edit_button}</a>
|
||||||
<a href="{$thisUser->getURL()}" class="link">{_my_page}</a>
|
<a href="{$thisUser->getURL()}" class="link">{_my_page}</a>
|
||||||
<a href="/friends{$thisUser->getId()}" class="link">{_my_friends}
|
<a href="/friends{$thisUser->getId()}" class="link">{_my_friends}
|
||||||
|
@ -189,6 +189,8 @@
|
||||||
<a n:if="OPENVK_ROOT_CONF['openvk']['preferences']['adPoster']['enable'] && $thisUser->getLeftMenuItemStatus('poster')" href="{php echo OPENVK_ROOT_CONF['openvk']['preferences']['adPoster']['link']}" >
|
<a n:if="OPENVK_ROOT_CONF['openvk']['preferences']['adPoster']['enable'] && $thisUser->getLeftMenuItemStatus('poster')" href="{php echo OPENVK_ROOT_CONF['openvk']['preferences']['adPoster']['link']}" >
|
||||||
<img src="{php echo OPENVK_ROOT_CONF['openvk']['preferences']['adPoster']['src']}" alt="{php echo OPENVK_ROOT_CONF['openvk']['preferences']['adPoster']['caption']}" class="psa-poster" style="max-width: 100%; margin-top: 50px;" />
|
<img src="{php echo OPENVK_ROOT_CONF['openvk']['preferences']['adPoster']['src']}" alt="{php echo OPENVK_ROOT_CONF['openvk']['preferences']['adPoster']['caption']}" class="psa-poster" style="max-width: 100%; margin-top: 50px;" />
|
||||||
</a>
|
</a>
|
||||||
|
{elseif !$thisUser->isActivated()}
|
||||||
|
<a href="/logout?hash={urlencode($csrfToken)}" class="link">{_menu_logout}</a>
|
||||||
{else}
|
{else}
|
||||||
<a href="/support" class="link">{_menu_support}
|
<a href="/support" class="link">{_menu_support}
|
||||||
{if $ticketAnsweredCount > 0}
|
{if $ticketAnsweredCount > 0}
|
||||||
|
|
|
@ -32,6 +32,7 @@ services:
|
||||||
- openvk\Web\Models\Repositories\Tickets
|
- openvk\Web\Models\Repositories\Tickets
|
||||||
- openvk\Web\Models\Repositories\Messages
|
- openvk\Web\Models\Repositories\Messages
|
||||||
- openvk\Web\Models\Repositories\Restores
|
- openvk\Web\Models\Repositories\Restores
|
||||||
|
- openvk\Web\Models\Repositories\Verifications
|
||||||
- openvk\Web\Models\Repositories\Notifications
|
- openvk\Web\Models\Repositories\Notifications
|
||||||
- openvk\Web\Models\Repositories\TicketComments
|
- openvk\Web\Models\Repositories\TicketComments
|
||||||
- openvk\Web\Models\Repositories\IPs
|
- openvk\Web\Models\Repositories\IPs
|
||||||
|
|
|
@ -59,6 +59,10 @@ routes:
|
||||||
handler: "Auth->restore"
|
handler: "Auth->restore"
|
||||||
- url: "/restore/internal-finish"
|
- url: "/restore/internal-finish"
|
||||||
handler: "Auth->finishRestoringPassword"
|
handler: "Auth->finishRestoringPassword"
|
||||||
|
- url: "/reg/resend"
|
||||||
|
handler: "Auth->resendEmail"
|
||||||
|
- url: "/regFinish"
|
||||||
|
handler: "Auth->verifyEmail"
|
||||||
- url: "/setSID/{slug}"
|
- url: "/setSID/{slug}"
|
||||||
handler: "Auth->su"
|
handler: "Auth->su"
|
||||||
- url: "/settings"
|
- url: "/settings"
|
||||||
|
|
|
@ -1831,3 +1831,13 @@ body.scrolled .toTop:hover {
|
||||||
.comments_count {
|
.comments_count {
|
||||||
padding: 5px 0px 0px 0px;
|
padding: 5px 0px 0px 0px;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.border-block {
|
||||||
|
box-shadow: inset 0px 0 0px 1px #b6bfca, inset 0px 0 0px 10px #d8dfe7;
|
||||||
|
width: 300px;
|
||||||
|
padding: 20px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.center {
|
||||||
|
margin: 0 auto;
|
||||||
|
}
|
||||||
|
|
|
@ -110,7 +110,7 @@ function setupWallPostInputHandlers(id) {
|
||||||
var textArea = e.target;
|
var textArea = e.target;
|
||||||
textArea.style.height = "5px";
|
textArea.style.height = "5px";
|
||||||
var newHeight = textArea.scrollHeight;
|
var newHeight = textArea.scrollHeight;
|
||||||
textArea.style.height = newHeight + boost;
|
textArea.style.height = newHeight + boost + "px";
|
||||||
return;
|
return;
|
||||||
|
|
||||||
// revert to original size if it is larger (possibly changed by user)
|
// revert to original size if it is larger (possibly changed by user)
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
window.addEventListener("scroll", function(e) {
|
window.addEventListener("scroll", function(e) {
|
||||||
if(document.body.scrollTop < 100) {
|
if(window.scrollY < 100) {
|
||||||
document.body.classList.toggle("scrolled", false);
|
document.body.classList.toggle("scrolled", false);
|
||||||
} else {
|
} else {
|
||||||
document.body.classList.toggle("scrolled", true);
|
document.body.classList.toggle("scrolled", true);
|
||||||
|
|
|
@ -231,7 +231,7 @@ return (function() {
|
||||||
if(is_dir($gitDir = OPENVK_ROOT . "/.git") && $showCommitHash)
|
if(is_dir($gitDir = OPENVK_ROOT . "/.git") && $showCommitHash)
|
||||||
$ver = trim(`git --git-dir="$gitDir" log --pretty="%h" -n1 HEAD` ?? "Unknown version") . "-nightly";
|
$ver = trim(`git --git-dir="$gitDir" log --pretty="%h" -n1 HEAD` ?? "Unknown version") . "-nightly";
|
||||||
else
|
else
|
||||||
$ver = "Build 15";
|
$ver = "Public Technical Preview 3";
|
||||||
|
|
||||||
// Unix time constants
|
// Unix time constants
|
||||||
define('MINUTE', 60);
|
define('MINUTE', 60);
|
||||||
|
|
|
@ -6,6 +6,7 @@
|
||||||
|
|
||||||
"home" = "Home";
|
"home" = "Home";
|
||||||
"welcome" = "Welcome";
|
"welcome" = "Welcome";
|
||||||
|
"to_top" = "To top";
|
||||||
|
|
||||||
/* Login */
|
/* Login */
|
||||||
|
|
||||||
|
@ -34,6 +35,13 @@
|
||||||
"password_reset_error" = "An unexpected error occurred while resetting the password.";
|
"password_reset_error" = "An unexpected error occurred while resetting the password.";
|
||||||
"password_reset_rate_limit_error" = "You can't do it that often, sorry.";
|
"password_reset_rate_limit_error" = "You can't do it that often, sorry.";
|
||||||
|
|
||||||
|
"email_sent" = "Mail has been successfully sent.";
|
||||||
|
"email_sent_desc" = "If your email addess exists, you will receive instructions.";
|
||||||
|
"email_error" = "An unexpected error occurred while sending the email.";
|
||||||
|
"email_rate_limit_error" = "You can't do it that often, sorry.";
|
||||||
|
|
||||||
|
"email_verify_success" = "Your Email has been verified. Have a great time!";
|
||||||
|
|
||||||
"registration_disabled_info" = "Registration has been disabled by the system administrator. If possible, ask for an invitation from your friend, if he is registered on this site.";
|
"registration_disabled_info" = "Registration has been disabled by the system administrator. If possible, ask for an invitation from your friend, if he is registered on this site.";
|
||||||
"registration_closed" = "Registration is closed.";
|
"registration_closed" = "Registration is closed.";
|
||||||
"invites_you_to" = "<strong>$1</strong> invites you to $2";
|
"invites_you_to" = "<strong>$1</strong> invites you to $2";
|
||||||
|
@ -647,6 +655,14 @@
|
||||||
"banned_2" = "And the reason for this is simple: <b>$1</b>. Unfortunately, this time we had to block you forever.";
|
"banned_2" = "And the reason for this is simple: <b>$1</b>. Unfortunately, this time we had to block you forever.";
|
||||||
"banned_3" = "You can still <a href=\"/support?act=new\">write to the support</a> if you think there was an error or <a href=\"/logout?hash=$1\">logout</a>.";
|
"banned_3" = "You can still <a href=\"/support?act=new\">write to the support</a> if you think there was an error or <a href=\"/logout?hash=$1\">logout</a>.";
|
||||||
|
|
||||||
|
/* Registration confirm */
|
||||||
|
|
||||||
|
"ec_header" = "Registration confirmation";
|
||||||
|
"ec_title" = "Thanks!";
|
||||||
|
"ec_1" = "<b>$1</b>, your registration is almost done. In a few minutes you should receive an mail with a link to confirm your email address.";
|
||||||
|
"ec_2" = "If for some reason you don't get the mail, check your spam folder. If you don't find the email there, you can resend it.";
|
||||||
|
"ec_resend" = "Resend mail";
|
||||||
|
|
||||||
/* Discussions */
|
/* Discussions */
|
||||||
|
|
||||||
"discussions" = "Discussions";
|
"discussions" = "Discussions";
|
||||||
|
|
|
@ -7,6 +7,7 @@
|
||||||
|
|
||||||
"home" = "Главная";
|
"home" = "Главная";
|
||||||
"welcome" = "Добро пожаловать";
|
"welcome" = "Добро пожаловать";
|
||||||
|
"to_top" = "Вверх";
|
||||||
|
|
||||||
/* Login */
|
/* Login */
|
||||||
|
|
||||||
|
@ -35,6 +36,13 @@
|
||||||
"password_reset_error" = "Непредвиденная ошибка при сбросе пароля.";
|
"password_reset_error" = "Непредвиденная ошибка при сбросе пароля.";
|
||||||
"password_reset_rate_limit_error" = "Нельзя делать это так часто, извините.";
|
"password_reset_rate_limit_error" = "Нельзя делать это так часто, извините.";
|
||||||
|
|
||||||
|
"email_sent" = "Письмо было успешно отправлено.";
|
||||||
|
"email_sent_desc" = "Если ваш электронный адрес существует, вы получите письмо.";
|
||||||
|
"email_error" = "Непредвиденная ошибка при отправке письма.";
|
||||||
|
"email_rate_limit_error" = "Нельзя делать это так часто, извините.";
|
||||||
|
|
||||||
|
"email_verify_success" = "Ваш Email был подтверждён. Приятного времяпрепровождения!";
|
||||||
|
|
||||||
"registration_disabled_info" = "Регистрация отключена системным администратором. При возможности попросите приглашение у вашего знакомого, если он зарегистрирован на этом сайте.";
|
"registration_disabled_info" = "Регистрация отключена системным администратором. При возможности попросите приглашение у вашего знакомого, если он зарегистрирован на этом сайте.";
|
||||||
"registration_closed" = "Регистрация закрыта.";
|
"registration_closed" = "Регистрация закрыта.";
|
||||||
"invites_you_to" = "<strong>$1</strong> приглашает вас в $2";
|
"invites_you_to" = "<strong>$1</strong> приглашает вас в $2";
|
||||||
|
@ -676,6 +684,14 @@
|
||||||
"banned_2" = "А причина этому проста: <b>$1</b>. К сожалению, на этот раз нам пришлось заблокировать вас навсегда.";
|
"banned_2" = "А причина этому проста: <b>$1</b>. К сожалению, на этот раз нам пришлось заблокировать вас навсегда.";
|
||||||
"banned_3" = "Вы всё ещё можете <a href=\"/support?act=new\">написать в службу поддержки</a>, если считаете что произошла ошибка или <a href=\"/logout?hash=$1\">выйти</a>.";
|
"banned_3" = "Вы всё ещё можете <a href=\"/support?act=new\">написать в службу поддержки</a>, если считаете что произошла ошибка или <a href=\"/logout?hash=$1\">выйти</a>.";
|
||||||
|
|
||||||
|
/* Registration confirm */
|
||||||
|
|
||||||
|
"ec_header" = "Подтверждение регистрации";
|
||||||
|
"ec_title" = "Спасибо!";
|
||||||
|
"ec_1" = "<b>$1</b>, ваша регистрация почти закончена. В течении нескольких минут на ваш адрес E-mail должно прийти письмо с ссылкой для подтверждения вашего адреса почты.";
|
||||||
|
"ec_2" = "Если по каким-то причинам вам не пришло письмо, то проверьте папку Спам. Если письма не окажется и там, то вы можете переотправить письмо.";
|
||||||
|
"ec_resend" = "Переотправить письмо";
|
||||||
|
|
||||||
/* Discussions */
|
/* Discussions */
|
||||||
|
|
||||||
"discussions" = "Обсуждения";
|
"discussions" = "Обсуждения";
|
||||||
|
|
Loading…
Reference in a new issue