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

@ -1,78 +1,94 @@
{extends "../@layout.xml"} {extends "../@layout.xml"}
{block title}{_"registration"}{/block} {block title}{_"registration"}{/block}
{block header} {block header}
{_"registration"} {_"registration"}
{/block} {/block}
{block content} {block headIncludes}
<form method="POST" enctype="multipart/form-data"> {if !$referer}
<table cellspacing="7" cellpadding="0" width="40%" border="0" align="center"> <meta name="description" content="Зарегистрируйтесь в OpenVK прямо сейчас!" />
<tbody> {else}
<tr> <meta property="og:title" content="{$referer->getFullName()} приглашает вас в OpenVK!" />
<td> <meta property="og:image" content="{$referer->getAvatarUrl()}" />
<span>{_"name"}: </span>
</td> <meta name="description"
<td> content="Присоединяйтесь к {$referer->getFullName()} и множеству других пользователей в OpenVK!" />
<input type="text" name="first_name" required /> {/if}
</td> {/block}
</tr>
<tr> {block content}
<td> <p n:if="!is_null($referer)" align="center">
<span>{_"surname"}: </span> <strong>{$referer->getFullName()}</strong> приглашает вас в OpenVK!
</td> </p>
<td>
<input type="text" name="last_name" required /> <form method="POST" enctype="multipart/form-data">
</td> <table cellspacing="7" cellpadding="0" width="40%" border="0" align="center">
</tr> <tbody>
<tr> <tr>
<td> <td>
<span>{_"gender"}: </span> <span>{_"name"}: </span>
</td> </td>
<td> <td>
{var femalePreferred = OPENVK_ROOT_CONF["openvk"]["preferences"]["femaleGenderPriority"]} <input type="text" name="first_name" required />
<select name="sex" required> </td>
<option n:attr="selected => !$femalePreferred" value="male">{_"male"}</option> </tr>
<option n:attr="selected => $femalePreferred" value="female">{_"female"}</option> <tr>
</select> <td>
</td> <span>{_"surname"}: </span>
</tr> </td>
<tr></tr> <td>
<tr> <input type="text" name="last_name" required />
<td> </td>
<span>{_"email"}: </span> </tr>
</td> <tr>
<td> <td>
<input type="email" name="email" required /> <span>{_"gender"}: </span>
</td> </td>
</tr> <td>
<tr> {var femalePreferred = OPENVK_ROOT_CONF["openvk"]["preferences"]["femaleGenderPriority"]}
<td> <select name="sex" required>
<span>{_"password"}: </span> <option n:attr="selected => !$femalePreferred" value="male">{_"male"}</option>
</td> <option n:attr="selected => $femalePreferred" value="female">{_"female"}</option>
<td> </select>
<input type="password" name="password" required /> </td>
</td> </tr>
</tr> <tr></tr>
<tr> <tr>
<td> <td>
<span>CAPTCHA: </span> <span>{_"email"}: </span>
</td> </td>
<td> <td>
{captcha_template()|noescape} <input type="email" name="email" required />
</td> </td>
</tr> </tr>
<tr> <tr>
<td> <td>
<span>{_"password"}: </span>
</td> </td>
<td> <td>
<input type="hidden" name="hash" value="{$csrfToken}" /> <input type="password" name="password" required />
<input type="submit" value="{_'registration'}" class="button" /> </td>
<a href="/login">{_"log_in"}</a> </tr>
</td> <tr>
</tr> <td>
</tbody> <span>CAPTCHA: </span>
</table> </td>
</form> <td>
{/block} {captcha_template()|noescape}
</td>
</tr>
<tr>
<td>
</td>
<td>
<input type="hidden" name="hash" value="{$csrfToken}" />
<input type="submit" value="{_'registration'}" class="button" />
<a href="/login">{_"log_in"}</a>
</td>
</tr>
</tbody>
</table>
</form>
{/block}

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}"