mirror of
https://github.com/openvk/openvk
synced 2025-01-21 15:24:17 +03:00
Merge branch 'master' of https://github.com/openvk/openvk into ton-integration
This commit is contained in:
commit
13bc1b877d
12 changed files with 498 additions and 20 deletions
204
Email/change-email.eml.latte
Normal file
204
Email/change-email.eml.latte
Normal 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']}/settings/change_email?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']}/settings/change_email?key={$key}" style="color: #000; text-decoration: none;">
|
||||
http://{$_SERVER['HTTP_HOST']}/settings/change_email?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>
|
||||
Вы получили это письмо так как кто-то или вы изменили адрес электронной почты. Это не рассылка и от неё нельзя отписаться. Если вы всё равно хотите перестать получать подобные письма, деактивируйте ваш аккаунт.
|
||||
</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>
|
|
@ -23,11 +23,12 @@ final class Wall extends VKAPIRequestHandler
|
|||
foreach ($posts->getPostsFromUsersWall((int)$owner_id, 1, $count, $offset) as $post) {
|
||||
$from_id = get_class($post->getOwner()) == "openvk\Web\Models\Entities\Club" ? $post->getOwner()->getId() * (-1) : $post->getOwner()->getId();
|
||||
|
||||
$attachments;
|
||||
foreach($post->getChildren() as $attachment)
|
||||
{
|
||||
if($attachment instanceof \openvk\Web\Models\Entities\Photo)
|
||||
{
|
||||
$attachments = [];
|
||||
foreach($post->getChildren() as $attachment) {
|
||||
if($attachment instanceof \openvk\Web\Models\Entities\Photo) {
|
||||
if($attachment->isDeleted())
|
||||
continue;
|
||||
|
||||
$attachments[] = [
|
||||
"type" => "photo",
|
||||
"photo" => [
|
||||
|
|
15
Web/Models/Entities/EmailChangeVerification.php
Normal file
15
Web/Models/Entities/EmailChangeVerification.php
Normal file
|
@ -0,0 +1,15 @@
|
|||
<?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 EmailChangeVerification extends PasswordReset
|
||||
{
|
||||
protected $tableName = "email_change_verifications";
|
||||
|
||||
function getNewEmail(): string
|
||||
{
|
||||
return $this->getRecord()->new_email;
|
||||
}
|
||||
}
|
|
@ -877,6 +877,17 @@ class User extends RowModel
|
|||
return true;
|
||||
}
|
||||
|
||||
function setEmail(string $email): void
|
||||
{
|
||||
DatabaseConnection::i()->getContext()->table("ChandlerUsers")
|
||||
->where("id", $this->getChandlerUser()->getId())->update([
|
||||
"login" => $email
|
||||
]);
|
||||
|
||||
$this->stateChanges("email", $email);
|
||||
$this->save();
|
||||
}
|
||||
|
||||
function adminNotify(string $message): bool
|
||||
{
|
||||
$admId = OPENVK_ROOT_CONF["openvk"]["preferences"]["support"]["adminAccount"];
|
||||
|
|
33
Web/Models/Repositories/EmailChangeVerifications.php
Normal file
33
Web/Models/Repositories/EmailChangeVerifications.php
Normal file
|
@ -0,0 +1,33 @@
|
|||
<?php declare(strict_types=1);
|
||||
namespace openvk\Web\Models\Repositories;
|
||||
use Chandler\Database\DatabaseConnection;
|
||||
use openvk\Web\Models\Entities\EmailChangeVerification;
|
||||
use openvk\Web\Models\Entities\User;
|
||||
use Nette\Database\Table\ActiveRow;
|
||||
|
||||
class EmailChangeVerifications
|
||||
{
|
||||
private $context;
|
||||
private $verifications;
|
||||
|
||||
function __construct()
|
||||
{
|
||||
$this->context = DatabaseConnection::i()->getContext();
|
||||
$this->verifications = $this->context->table("email_change_verifications");
|
||||
}
|
||||
|
||||
function toEmailChangeVerification(?ActiveRow $ar): ?EmailChangeVerification
|
||||
{
|
||||
return is_null($ar) ? NULL : new EmailChangeVerification($ar);
|
||||
}
|
||||
|
||||
function getByToken(string $token): ?EmailChangeVerification
|
||||
{
|
||||
return $this->toEmailChangeVerification($this->verifications->where("key", $token)->fetch());
|
||||
}
|
||||
|
||||
function getLatestByUser(User $user): ?EmailChangeVerification
|
||||
{
|
||||
return $this->toEmailChangeVerification($this->verifications->where("profile", $user->getId())->order("timestamp DESC")->fetch());
|
||||
}
|
||||
}
|
|
@ -9,12 +9,15 @@ use openvk\Web\Models\Repositories\Albums;
|
|||
use openvk\Web\Models\Repositories\Videos;
|
||||
use openvk\Web\Models\Repositories\Notes;
|
||||
use openvk\Web\Models\Repositories\Vouchers;
|
||||
use openvk\Web\Models\Repositories\EmailChangeVerifications;
|
||||
use openvk\Web\Models\Exceptions\InvalidUserNameException;
|
||||
use openvk\Web\Util\Validator;
|
||||
use openvk\Web\Models\Entities\Notifications\{CoinsTransferNotification, RatingUpNotification};
|
||||
use openvk\Web\Models\Entities\EmailChangeVerification;
|
||||
use Chandler\Security\Authenticator;
|
||||
use lfkeitel\phptotp\{Base32, Totp};
|
||||
use chillerlan\QRCode\{QRCode, QROptions};
|
||||
use Nette\Database\UniqueConstraintViolationException;
|
||||
|
||||
final class UserPresenter extends OpenVKPresenter
|
||||
{
|
||||
|
@ -132,7 +135,7 @@ final class UserPresenter extends OpenVKPresenter
|
|||
|
||||
if(!$id)
|
||||
$this->notFound();
|
||||
|
||||
|
||||
$user = $this->users->get($id);
|
||||
if($_SERVER["REQUEST_METHOD"] === "POST") {
|
||||
$this->willExecuteWriteAction($_GET['act'] === "status");
|
||||
|
@ -300,7 +303,7 @@ final class UserPresenter extends OpenVKPresenter
|
|||
|
||||
if(!$id)
|
||||
$this->notFound();
|
||||
|
||||
|
||||
if(in_array($this->queryParam("act"), ["finance", "finance.top-up"]) && !OPENVK_ROOT_CONF["openvk"]["preferences"]["commerce"])
|
||||
$this->flashFail("err", tr("error"), tr("feature_disabled"));
|
||||
|
||||
|
@ -312,7 +315,7 @@ final class UserPresenter extends OpenVKPresenter
|
|||
if($this->postParam("old_pass") && $this->postParam("new_pass") && $this->postParam("repeat_pass")) {
|
||||
if($this->postParam("new_pass") === $this->postParam("repeat_pass")) {
|
||||
if($this->user->identity->is2faEnabled()) {
|
||||
$code = $this->postParam("code");
|
||||
$code = $this->postParam("password_change_code");
|
||||
if(!($code === (new Totp)->GenerateToken(Base32::decode($this->user->identity->get2faSecret())) || $this->user->identity->use2faBackupCode((int) $code)))
|
||||
$this->flashFail("err", tr("error"), tr("incorrect_2fa_code"));
|
||||
}
|
||||
|
@ -323,6 +326,46 @@ final class UserPresenter extends OpenVKPresenter
|
|||
$this->flashFail("err", tr("error"), tr("error_new_password"));
|
||||
}
|
||||
}
|
||||
|
||||
if($this->postParam("new_email")) {
|
||||
if(!Validator::i()->emailValid($this->postParam("new_email")))
|
||||
$this->flashFail("err", tr("invalid_email_address"), tr("invalid_email_address_comment"));
|
||||
|
||||
if(!Authenticator::verifyHash($this->postParam("email_change_pass"), $user->getChandlerUser()->getRaw()->passwordHash))
|
||||
$this->flashFail("err", tr("error"), tr("incorrect_password"));
|
||||
|
||||
if($user->is2faEnabled()) {
|
||||
$code = $this->postParam("email_change_code");
|
||||
if(!($code === (new Totp)->GenerateToken(Base32::decode($user->get2faSecret())) || $user->use2faBackupCode((int) $code)))
|
||||
$this->flashFail("err", tr("error"), tr("incorrect_2fa_code"));
|
||||
}
|
||||
|
||||
if($this->postParam("new_email") !== $user->getEmail()) {
|
||||
if (OPENVK_ROOT_CONF['openvk']['preferences']['security']['requireEmail']) {
|
||||
$request = (new EmailChangeVerifications)->getLatestByUser($user);
|
||||
if(!is_null($request) && $request->isNew())
|
||||
$this->flashFail("err", tr("forbidden"), tr("email_rate_limit_error"));
|
||||
|
||||
$verification = new EmailChangeVerification;
|
||||
$verification->setProfile($user->getId());
|
||||
$verification->setNew_Email($this->postParam("new_email"));
|
||||
$verification->save();
|
||||
|
||||
$params = [
|
||||
"key" => $verification->getKey(),
|
||||
"name" => $user->getCanonicalName(),
|
||||
];
|
||||
$this->sendmail($this->postParam("new_email"), "change-email", $params); #Vulnerability possible
|
||||
$this->flashFail("succ", tr("information_-1"), tr("email_change_confirm_message"));
|
||||
}
|
||||
|
||||
try {
|
||||
$user->setEmail($this->postParam("new_email"));
|
||||
} catch(UniqueConstraintViolationException $ex) {
|
||||
$this->flashFail("err", tr("error"), tr("user_already_exists"));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if(!$user->setShortCode(empty($this->postParam("sc")) ? NULL : $this->postParam("sc")))
|
||||
$this->flashFail("err", tr("error"), tr("error_shorturl_incorrect"));
|
||||
|
@ -400,11 +443,7 @@ final class UserPresenter extends OpenVKPresenter
|
|||
throw $ex;
|
||||
}
|
||||
|
||||
$this->flash(
|
||||
"succ",
|
||||
"Изменения сохранены",
|
||||
"Новые данные появятся на вашей странице."
|
||||
);
|
||||
$this->flash("succ", tr("changes_saved"), tr("changes_saved_comment"));
|
||||
}
|
||||
$this->template->mode = in_array($this->queryParam("act"), [
|
||||
"main", "privacy", "finance", "finance.top-up", "interface"
|
||||
|
@ -502,6 +541,9 @@ final class UserPresenter extends OpenVKPresenter
|
|||
$this->assertUserLoggedIn();
|
||||
$this->willExecuteWriteAction();
|
||||
|
||||
if(!OPENVK_ROOT_CONF["openvk"]["preferences"]["commerce"])
|
||||
$this->flashFail("err", tr("error"), tr("feature_disabled"));
|
||||
|
||||
$receiverAddress = $this->postParam("receiver");
|
||||
$value = (int) $this->postParam("value");
|
||||
$message = $this->postParam("message");
|
||||
|
@ -517,7 +559,7 @@ final class UserPresenter extends OpenVKPresenter
|
|||
|
||||
$receiver = $this->users->getByAddress($receiverAddress);
|
||||
if(!$receiver)
|
||||
$this->flashFail("err", tr("failed_to_tranfer_points"), tr("receiver_not_found"));
|
||||
$this->flashFail("err", tr("failed_to_tranfer_points"), tr("receiver_not_found"));
|
||||
|
||||
if($this->user->identity->getCoins() < $value)
|
||||
$this->flashFail("err", tr("failed_to_tranfer_points"), tr("you_dont_have_enough_points"));
|
||||
|
@ -574,4 +616,24 @@ final class UserPresenter extends OpenVKPresenter
|
|||
|
||||
$this->flashFail("succ", tr("information_-1"), tr("rating_increase_successful", $receiver->getURL(), htmlentities($receiver->getCanonicalName()), $value));
|
||||
}
|
||||
|
||||
function renderEmailChangeFinish(): void
|
||||
{
|
||||
$request = (new EmailChangeVerifications)->getByToken(str_replace(" ", "+", $this->queryParam("key")));
|
||||
if(!$request || !$request->isStillValid()) {
|
||||
$this->flash("err", tr("token_manipulation_error"), tr("token_manipulation_error_comment"));
|
||||
$this->redirect("/settings");
|
||||
} else {
|
||||
$request->delete(false);
|
||||
|
||||
try {
|
||||
$request->getUser()->setEmail($request->getNewEmail());
|
||||
} catch(UniqueConstraintViolationException $ex) {
|
||||
$this->flashFail("err", tr("error"), tr("user_already_exists"));
|
||||
}
|
||||
|
||||
$this->flash("succ", tr("changes_saved"), tr("changes_saved_comment"));
|
||||
$this->redirect("/settings");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -64,7 +64,7 @@
|
|||
<span class="nobold">{_"2fa_code"}</span>
|
||||
</td>
|
||||
<td>
|
||||
<input type="text" name="code" style="width: 100%;" />
|
||||
<input type="text" name="password_change_code" style="width: 100%;" />
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
|
@ -154,6 +154,38 @@
|
|||
{$user->getEmail()}
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td width="120" valign="top">
|
||||
<span class="nobold">{_new_email_address}</span>
|
||||
</td>
|
||||
<td>
|
||||
<input type="email" name="new_email" style="width: 100%;" />
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td width="120" valign="top">
|
||||
<span class="nobold">{_password}</span>
|
||||
</td>
|
||||
<td>
|
||||
<input type="password" name="email_change_pass" style="width: 100%;" />
|
||||
</td>
|
||||
</tr>
|
||||
<tr n:if="$user->is2faEnabled()">
|
||||
<td width="120" valign="top">
|
||||
<span class="nobold">{_"2fa_code"}</span>
|
||||
</td>
|
||||
<td>
|
||||
<input type="text" name="email_change_code" style="width: 100%;" />
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>
|
||||
|
||||
</td>
|
||||
<td>
|
||||
<input type="submit" value="{_save_email_address}" class="button" />
|
||||
</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
<br/>
|
||||
|
|
|
@ -73,6 +73,8 @@ routes:
|
|||
handler: "User->disableTwoFactorAuth"
|
||||
- url: "/settings/reset_theme"
|
||||
handler: "User->resetThemepack"
|
||||
- url: "/settings/change_email"
|
||||
handler: "User->emailChangeFinish"
|
||||
- url: "/coins_transfer"
|
||||
handler: "User->coinsTransfer"
|
||||
- url: "/increase_social_credits"
|
||||
|
|
8
install/sqls/00023-email-change.sql
Normal file
8
install/sqls/00023-email-change.sql
Normal file
|
@ -0,0 +1,8 @@
|
|||
CREATE TABLE IF NOT EXISTS `email_change_verifications` (
|
||||
`id` bigint(20) unsigned NOT NULL AUTO_INCREMENT,
|
||||
`profile` bigint(20) unsigned NOT NULL,
|
||||
`key` char(64) COLLATE utf8mb4_unicode_520_ci NOT NULL,
|
||||
`new_email` varchar(90) COLLATE utf8mb4_unicode_520_ci DEFAULT NULL,
|
||||
`timestamp` bigint(20) unsigned NOT NULL,
|
||||
PRIMARY KEY (`id`)
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_520_ci;
|
|
@ -9,6 +9,7 @@
|
|||
|
||||
"home" = "Գլխավոր";
|
||||
"welcome" = "Բարի գալուստ";
|
||||
"to_top" = "Վերև";
|
||||
|
||||
/* Login */
|
||||
|
||||
|
@ -381,7 +382,6 @@
|
|||
|
||||
"left_menu_donate" = "Աջակցել";
|
||||
|
||||
|
||||
"footer_about_instance" = "հոսքի մասին";
|
||||
"footer_blog" = "բլոգ";
|
||||
"footer_help" = "օգնություն";
|
||||
|
@ -410,6 +410,8 @@
|
|||
"style" = "Ոճ";
|
||||
|
||||
"default" = "Սովորական";
|
||||
|
||||
"arbitrary_avatars" = "Կամայական";
|
||||
"cut" = "Կտրվածք";
|
||||
"round_avatars" = "Կլոր ավատար";
|
||||
|
||||
|
@ -519,6 +521,8 @@
|
|||
"videos_many" = "$1 տեսանյութ";
|
||||
"videos_other" = "$1 տեսանյութ";
|
||||
|
||||
"view_video" = "Դիտում";
|
||||
|
||||
/* Notifications */
|
||||
|
||||
"feedback" = "Հետադարձ կապ";
|
||||
|
@ -624,6 +628,21 @@
|
|||
"receiver_not_found" = "Ստացողը չի գտնվել։";
|
||||
"you_dont_have_enough_points" = "Դուք չունե՛ք բավական ձայն։";
|
||||
|
||||
"increase_rating" = "Բարձրացնել վարկանիշը";
|
||||
"increase_rating_button" = "Բարձրացնել";
|
||||
"to_whom" = "Ում";
|
||||
"increase_by" = "Բարձրացնել";
|
||||
"price" = "Արժողություն";
|
||||
|
||||
"you_have_unused_votes" = "Ձեր մոտ $1 չօգտագործված ձայն կա հաշվի վրա։";
|
||||
"apply_voucher" = "Կիրառել վաուչեր";
|
||||
|
||||
"failed_to_increase_rating" = "Չհաջողվե՛ց բարձրացնել վարկանիշը";
|
||||
"rating_increase_successful" = "Դուք հաջողությամբ բարձրացրեցիք Ձեր վարկանիշը <b><a href=\"$1\">$2</a></b> <b>$3%</b>-ով։";
|
||||
"negative_rating_value" = "Կներե՛ք, մենք չենք կարող գողանալ ուրիշի վարկանիշը։";
|
||||
|
||||
"increased_your_rating_by" = "բարձրացրել է վարկանիշը";
|
||||
|
||||
/* Gifts */
|
||||
|
||||
"gift" = "Նվեր";
|
||||
|
@ -703,6 +722,9 @@
|
|||
"ticket_changed" = "Տոմսը փոփոխված է";
|
||||
"ticket_changed_comment" = "Փոփոխությունները ուժի մեջ կմտնեն մի քանի վայրկյանից։";
|
||||
|
||||
"banned_in_support_1" = "Կներե՛ք, <b>$1</b>, բայց հիմա Ձեզ թույլատրված չէ դիմումներ ստեղծել։";
|
||||
"banned_in_support_2" = "Դրա պատճառաբանությունը սա է․ <b>$1</b>։ Ցավո՛ք, այդ հնարավորությունը մենք Ձեզնից վերցրել ենք առհավետ։";
|
||||
|
||||
/* Invite */
|
||||
|
||||
"invite" = "Հրավիրել";
|
||||
|
@ -711,9 +733,9 @@
|
|||
|
||||
/* Banned */
|
||||
|
||||
"banned_title" = "Բլոկավորված եք";
|
||||
"banned_header" = "Ձեզ կասեցրել է կառլենի անհաջող բոցը։";
|
||||
"banned_alt" = "Օգտատերը բլոկավորված է";
|
||||
"banned_title" = "Արգելափակված եք";
|
||||
"banned_header" = "Ձեզ կասեցրել է կարլենի անհաջող բոցը։";
|
||||
"banned_alt" = "Օգտատերը արգելափակված է";
|
||||
"banned_1" = "Կներե՛ք, <b>$1</b>, բայց Դուք կասեցված եք։";
|
||||
"banned_2" = "Պատճառը հետևյալն է․ <b>$1</b>. Ափսոս, բայց մենք ստիպված Ձեզ հավերժ ենք կասեցրել;";
|
||||
"banned_3" = "Դուք դեռ կարող եք <a href=\"/support?act=new\">գրել նամակ աջակցության ծառայությանը</a>, եթե համարում եք որ դա սխալմունք է, կամ էլ կարող եք <a href=\"/logout?hash=$1\">դուրս գալ</a>։";
|
||||
|
@ -835,6 +857,7 @@
|
|||
"captcha_error" = "Սխալ են գրված սիմվոլները";
|
||||
"captcha_error_comment" = "Խնդրում ենք համոզվել, որ ճիշտ եք ներմուծել կապտչայի սիմվոլները։";
|
||||
|
||||
|
||||
/* Admin actions */
|
||||
|
||||
"login_as" = "Մտնել ինչպես $1";
|
||||
|
@ -843,7 +866,84 @@
|
|||
"ban_user_action" = "Բլոկավորել օգտվողին";
|
||||
"warn_user_action" = "Զգուշացնել օգտվողին";
|
||||
|
||||
/* Paginator (subject to delete) */
|
||||
|
||||
/* Admin panel */
|
||||
|
||||
"admin" = "Ադմին-վահանակ";
|
||||
|
||||
"admin_ownerid" = "Տիրոջ ID";
|
||||
"admin_author" = "Հեղինակ";
|
||||
"admin_name" = "Անուն";
|
||||
"admin_title" = "Անվանում";
|
||||
"admin_description" = "Նկարագրություն";
|
||||
"admin_first_known_ip" = "Առաջին IP";
|
||||
"admin_shortcode" = "Կարճ հասցե";
|
||||
"admin_verification" = "Վերիֆիկացիա";
|
||||
"admin_banreason" = "Արգելափակման պատճառ";
|
||||
"admin_banned" = "արգելափակված է";
|
||||
"admin_actions" = "Գործողություններ";
|
||||
"admin_image" = "Նկար";
|
||||
"admin_image_replace" = "Փոխե՞լ նկարը";
|
||||
"admin_uses" = "Օգտագործումներ";
|
||||
"admin_uses_reset" = "Զրոյացնե՞լ օգտագործումների քանակը";
|
||||
"admin_limits" = "Սահմանափակումներ";
|
||||
"admin_limits_reset" = "Զրոյացնել օգտագործումների քանակը";
|
||||
"admin_open" = "Բացել";
|
||||
"admin_loginas" = "Մուտք գործել ինչպես...";
|
||||
"admin_commonsettings" = "Ընդհանուր կարգավորումներ";
|
||||
"admin_langsettings" = "Լեզվից կախված կարգավորումներ";
|
||||
|
||||
"admin_tab_main" = "Գլխավոր";
|
||||
"admin_tab_ban" = "Բլոկավորում";
|
||||
"admin_tab_followers" = "Մասնակիցներ";
|
||||
|
||||
"admin_overview" = "Դիտում";
|
||||
"admin_overview_summary" = "Ամփոփում";
|
||||
|
||||
"admin_content" = "Օգտատիրային կոնտենտ";
|
||||
"admin_user_search" = "Օգտատերերի որոնում";
|
||||
"admin_user_online" = "Օնլայն վիճակ";
|
||||
"admin_user_online_default" = "Ըստ նախնականի";
|
||||
"admin_user_online_incognito" = "Ինկոգնիտո";
|
||||
"admin_user_online_deceased" = "Հանգուցյալ";
|
||||
"admin_club_search" = "Խմբերի որոնում";
|
||||
"admin_club_excludeglobalfeed" = "Չ՛ցույց տալ գլոբալ ժապավենում";
|
||||
|
||||
"admin_services" = "Վճարովի ծառայություններ";
|
||||
"admin_newgift" = "Նոր նվեր";
|
||||
"admin_price" = "Գին";
|
||||
"admin_giftset" = "Նվերների հավաքախու";
|
||||
"admin_giftsets" = "Նվերների հավաքախուներ";
|
||||
"admin_giftsets_none" = "Նվերների հավաքածու չկա։ Ստեղծե՛ք հավաքածու նվեր ավելացնելու համար։";
|
||||
"admin_giftsets_create" = "Ստեղծել նվերների հավաքածու";
|
||||
"admin_giftsets_title" = "Հավաքածույի ներքին անվանում, եթե չի հաջողվում որոնել այն օգտատիրոջ լեզվով";
|
||||
"admin_giftsets_description" = "Հավաքածույի ներքին նկարագրություն, եթե չի հաջողվում որոնել այն օգտատիրոջ լեզվով";
|
||||
"admin_price_free" = "անվճար";
|
||||
"admin_voucher_rating" = "Վարկանիշ";
|
||||
"admin_voucher_serial" = "Սերիական համար";
|
||||
"admin_voucher_serial_desc" = "Համարը բաղկացած է 24 նշից։ Եթե Դուք այն սխալ գրեք, այն կտրվի ավտոմատ։";
|
||||
"admin_voucher_coins" = "Ձայների քանակ";
|
||||
"admin_voucher_rating" = "Վարկանշի քանակ";
|
||||
"admin_voucher_usages_desc" = "Վաուչերը օգտագործող ակկաունտների քանակ։ Եթե գրեք -1, ապա այն կլինի օգտագործել անվերջ։";
|
||||
"admin_voucher_status" = "Կարգավիճակ";
|
||||
"admin_voucher_status_opened" = "ակտիվ է";
|
||||
"admin_voucher_status_closed" = "վերջացել է";
|
||||
|
||||
"admin_settings" = "Կարգավորումներ";
|
||||
"admin_settings_tuning" = "Ընդհանուր";
|
||||
"admin_settings_appearance" = "Արտաքին տեսք";
|
||||
"admin_settings_security" = "Անվտանգություն";
|
||||
"admin_settings_integrations" = "Ինտեգրացիաներ";
|
||||
"admin_settings_system" = "Համակարգ";
|
||||
|
||||
"admin_about" = "OpenVK-ի մասին";
|
||||
"admin_about_version" = "Վերսիա";
|
||||
"admin_about_instance" = "Հոսք";
|
||||
|
||||
"admin_commerce_disabled" = "Կոմմերցիան անջատված է համակարգային ադմինիստրատորի կողմից";
|
||||
"admin_commerce_disabled_desc" = "Վաուչերների և նվերների կարգավորումները կպահպանվեն, բայց ոչ մի ազդեցություն չեն ունենա։";
|
||||
|
||||
/* Paginator (deprecated) */
|
||||
|
||||
"paginator_back" = "Հետ";
|
||||
"paginator_page" = "$1 էջ";
|
||||
|
@ -857,6 +957,8 @@
|
|||
"rules" = "Կանոններ";
|
||||
"most_popular_groups" = "Ամենահայտնի խմբերը";
|
||||
"on_this_instance_are" = "Այս հոսքում․";
|
||||
"about_links" = "Հղումներ";
|
||||
"instance_links" = "Հոսքերի հղումներ․";
|
||||
|
||||
"about_users_one" = "<b>Մեկ</b> օգտատեր";
|
||||
"about_users_few" = "<b>$1</b> օգտատեր";
|
||||
|
|
|
@ -444,6 +444,8 @@
|
|||
"your_page_address" = "Your address page";
|
||||
"page_address" = "Address page";
|
||||
"current_email_address" = "Current email address";
|
||||
"new_email_address" = "New email address";
|
||||
"save_email_address" = "Save email address";
|
||||
"page_id" = "Page ID";
|
||||
"you_can_also" = "You can also";
|
||||
"delete_your_page" = "delete your page";
|
||||
|
@ -458,6 +460,8 @@
|
|||
"additional_links" = "Additional links";
|
||||
"ad_poster" = "Ad poster";
|
||||
|
||||
"email_change_confirm_message" = "Please confirm your new email address for the change to take effect. We have sent instructions to it.";
|
||||
|
||||
/* Two-factor authentication */
|
||||
|
||||
"two_factor_authentication" = "Two-factor authentication";
|
||||
|
|
|
@ -472,6 +472,8 @@
|
|||
"your_page_address" = "Адрес Вашей страницы";
|
||||
"page_address" = "Адрес страницы";
|
||||
"current_email_address" = "Текущий адрес";
|
||||
"new_email_address" = "Новый адрес";
|
||||
"save_email_address" = "Сохранить адрес";
|
||||
"page_id" = "ID страницы";
|
||||
"you_can_also" = "Вы также можете";
|
||||
"delete_your_page" = "удалить свою страницу";
|
||||
|
@ -486,6 +488,8 @@
|
|||
"additional_links" = "Дополнительные ссылки";
|
||||
"ad_poster" = "Рекламный плакат";
|
||||
|
||||
"email_change_confirm_message" = "Чтобы изменение вступило в силу, подтвердите ваш новый адрес электронной почты. Мы отправили инструкции на него.";
|
||||
|
||||
/* Two-factor authentication */
|
||||
|
||||
"two_factor_authentication" = "Двухфакторная аутентификация";
|
||||
|
|
Loading…
Reference in a new issue