Invite: normal implementation

Co-authored-by: celestora <kitsuruko@gmail.com>
This commit is contained in:
Ilya Prokopenko 2021-09-13 10:22:05 +07:00
parent 30b91af13c
commit dd307f29c2
No known key found for this signature in database
GPG key ID: 7736BBBB05F14A56
8 changed files with 145 additions and 88 deletions

View file

@ -280,7 +280,7 @@ final class Messages extends VKAPIRequestHandler
if($group_id > 0) if($group_id > 0)
$this->fail(-151, "Not implemented"); $this->fail(-151, "Not implemented");
$url = "http" . ($_SERVER["HTTPS"] === "on" ? "s" : "") . "://$_SERVER[HTTP_HOST]/nim" . $this->getUser()->getId(); $url = "http" . (ovk_is_ssl() ? "s" : "") . "://$_SERVER[HTTP_HOST]/nim" . $this->getUser()->getId();
$key = openssl_random_pseudo_bytes(8); $key = openssl_random_pseudo_bytes(8);
$key = bin2hex($key) . bin2hex($key ^ ( ~CHANDLER_ROOT_CONF["security"]["secret"] | ((string) $this->getUser()->getId()) )); $key = bin2hex($key) . bin2hex($key ^ ( ~CHANDLER_ROOT_CONF["security"]["secret"] | ((string) $this->getUser()->getId()) ));
$res = [ $res = [

View file

@ -498,10 +498,9 @@ class User extends RowModel
function getRefLinkId(): string function getRefLinkId(): string
{ {
$rand = openssl_random_pseudo_bytes(SODIUM_CRYPTO_STREAM_NONCEBYTES); # anime :) $hash = hash_hmac("Snefru", (string) $this->getId(), CHANDLER_ROOT_CONF["security"]["secret"], true);
$key = substr(hex2bin(CHANDLER_ROOT_CONF["security"]["secret"]), 0, SODIUM_CRYPTO_STREAM_KEYBYTES);
return bin2hex($rand) . bin2hex(sodium_crypto_stream_xor((string) $this->getId(), $rand, $key)); return dechex($this->getId()) . " " . base64_encode($hash);
} }
function getNsfwTolerance(): int function getNsfwTolerance(): int

View file

@ -37,7 +37,9 @@ final class AboutPresenter extends OpenVKPresenter
{} {}
function renderInvite(): void function renderInvite(): void
{} {
$this->assertUserLoggedIn();
}
function renderDonate(): void function renderDonate(): void
{ {

View file

@ -57,6 +57,26 @@ final class AuthPresenter extends OpenVKPresenter
if(!$this->hasPermission("user", "register", -1)) exit("Вас забанили"); if(!$this->hasPermission("user", "register", -1)) exit("Вас забанили");
$referer = NULL;
if(!is_null($refLink = $this->queryParam("ref"))) {
$pieces = explode(" ", $refLink, 2);
if(sizeof($pieces) !== 2)
$this->flashFail("err", "Пригласительная ссылка кривая", "Пригласительная ссылка недействительна.");
[$ref, $hash] = $pieces;
$ref = hexdec($ref);
$hash = base64_decode($hash);
$referer = (new Users)->get($ref);
if(!$referer)
$this->flashFail("err", "Пригласительная ссылка кривая", "Пригласительная ссылка недействительна.");
if($referer->getRefLinkId() !== $refLink)
$this->flashFail("err", "Пригласительная ссылка кривая", "Пригласительная ссылка недействительна.");
}
$this->template->referer = $referer;
if($_SERVER["REQUEST_METHOD"] === "POST") { if($_SERVER["REQUEST_METHOD"] === "POST") {
$this->assertCaptchaCheckPassed(); $this->assertCaptchaCheckPassed();
@ -80,6 +100,11 @@ final class AuthPresenter extends OpenVKPresenter
$user->setRegistering_Ip(CONNECTING_IP); $user->setRegistering_Ip(CONNECTING_IP);
$user->save(); $user->save();
if(!is_null($referer)) {
$user->toggleSubscription($referer);
$referer->toggleSubscription($user);
}
$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);
} }

View file

@ -8,11 +8,7 @@
{block content} {block content}
Вы можете пригласить своих друзей или знакомых в сеть с помощью индивидуальной ссылки:<br><br> Вы можете пригласить своих друзей или знакомых в сеть с помощью индивидуальной ссылки:<br><br>
<center> <center>
<input type="text" readonly value="https://{$_SERVER["HTTP_HOST"]}/reg?ref={$thisUser->getRefLinkId()}" size="50" /> <input type="text" readonly value="https://{$_SERVER["HTTP_HOST"]}/reg?ref={rawurlencode($thisUser->getRefLinkId())}" size="50" />
</center> </center>
<p>Приложите эту ссылку к вашему сообщению. Пользователь зарегистрируется, и он сразу появится у вас в друзьях.</p> <p>Приложите эту ссылку к вашему сообщению. Пользователь зарегистрируется, и он сразу появится у вас в друзьях.</p>
<div class="msg msg_err">
<b>Пока не работает</b><br>
Надо индивидуальный токен создать для такой ссылки, а то пиздец будет.
</div>
{/block} {/block}

View file

@ -5,7 +5,23 @@
{_"registration"} {_"registration"}
{/block} {/block}
{block headIncludes}
{if !$referer}
<meta name="description" content="Зарегистрируйтесь в OpenVK прямо сейчас!" />
{else}
<meta property="og:title" content="{$referer->getFullName()} приглашает вас в OpenVK!" />
<meta property="og:image" content="{$referer->getAvatarUrl()}" />
<meta name="description"
content="Присоединяйтесь к {$referer->getFullName()} и множеству других пользователей в OpenVK!" />
{/if}
{/block}
{block content} {block content}
<p n:if="!is_null($referer)" align="center">
<strong>{$referer->getFullName()}</strong> приглашает вас в OpenVK!
</p>
<form method="POST" enctype="multipart/form-data"> <form method="POST" enctype="multipart/form-data">
<table cellspacing="7" cellpadding="0" width="40%" border="0" align="center"> <table cellspacing="7" cellpadding="0" width="40%" border="0" align="center">
<tbody> <tbody>

View file

@ -2,6 +2,7 @@ services:
- openvk\Web\Presenters\AwayPresenter - openvk\Web\Presenters\AwayPresenter
- openvk\Web\Presenters\AboutPresenter - openvk\Web\Presenters\AboutPresenter
- openvk\Web\Presenters\AuthPresenter - openvk\Web\Presenters\AuthPresenter
- openvk\Web\Presenters\AudiosPresenter
- openvk\Web\Presenters\UserPresenter - openvk\Web\Presenters\UserPresenter
- openvk\Web\Presenters\WallPresenter - openvk\Web\Presenters\WallPresenter
- openvk\Web\Presenters\CommentPresenter - openvk\Web\Presenters\CommentPresenter

View file

@ -151,6 +151,24 @@ routes:
handler: "User->groups" handler: "User->groups"
- url: "/groups_create" - url: "/groups_create"
handler: "Group->create" handler: "Group->create"
- url: "/audios{num}"
handler: "Audios->app"
- url: "/audios{num}.json"
handler: "Audios->apiListSongs"
- url: "/audios/popular.json"
handler: "Audios->apiListPopSongs"
- url: "/audios/playlist{num}.json"
handler: "Audios->apiListPlaylists"
- url: "/audios/search.json"
handler: "Audios->apiSearch"
- url: "/audios/add.json"
handler: "Audios->apiAdd"
- url: "/audios/playlist.json"
handler: "Audios->apiAddPlaylist"
- url: "/audios/upload.json"
handler: "Audios->apiUpload"
- url: "/audios/beacon"
handler: "Audios->apiBeacon"
- url: "/im" - url: "/im"
handler: "Messenger->index" handler: "Messenger->index"
- url: "/im/sel{num}" - url: "/im/sel{num}"