Skip to content

Commit

Permalink
Add more options and tests.
Browse files Browse the repository at this point in the history
  • Loading branch information
terabytesoftw committed Sep 29, 2020
1 parent 26b46c2 commit dabbebb
Show file tree
Hide file tree
Showing 30 changed files with 1,009 additions and 50 deletions.
9 changes: 8 additions & 1 deletion README.md
Expand Up @@ -69,7 +69,6 @@ All the configuration is in the `config directory` of the `application`.
./yii migrate/up
~~~


## Using PHP built-in server

~~~
Expand All @@ -82,6 +81,14 @@ php -S 127.0.0.1:8080 -t public
http://localhost:8080
~~~

## Implemented functions

- [x] Admin Panel Dashboard.
- [x] /auth/login
- [x] /registration/register
- [x] /registration/resend
- [x] /registration/confirm[/{id}/{token}

## Codeception testing

The package is tested with [Codeception](https://github.com/Codeception/Codeception). To run tests:
Expand Down
3 changes: 2 additions & 1 deletion composer.json
Expand Up @@ -39,11 +39,12 @@
"yiisoft/yii-web": "^3.0@dev"
},
"require-dev": {
"roave/security-advisories": "dev-master",
"codeception/codeception": "^4.1.5",
"codeception/module-asserts": "@dev",
"codeception/module-db": "^1.0",
"codeception/module-phpbrowser": "@dev",
"phpunit/phpunit": "^9.3",
"roave/security-advisories": "dev-master",
"vimeo/psalm": "^3.15"
},
"autoload": {
Expand Down
61 changes: 58 additions & 3 deletions composer.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

90 changes: 90 additions & 0 deletions src/Module/User/Action/Confirm.php
@@ -0,0 +1,90 @@
<?php

declare(strict_types=1);

namespace App\Module\User\Action;

use App\Module\User\Entity\User;
use App\Module\User\Entity\Token;
use App\Module\User\Repository\TokenRepository;
use App\Module\User\Service\Login as LoginService;
use App\Service\Parameters;
use App\Service\View;
use Psr\Http\Message\ResponseInterface;
use Psr\Http\Message\ServerRequestInterface;
use Yiisoft\Auth\IdentityRepositoryInterface;
use Yiisoft\DataResponse\DataResponseFactoryInterface;
use Yiisoft\Router\UrlGeneratorInterface;

final class Confirm
{
public function confirm(
Parameters $app,
IdentityRepositoryInterface $identityRepository,
LoginService $loginService,
ServerRequestInterface $request,
DataResponseFactoryInterface $responseFactory,
TokenRepository $tokenRepository,
UrlGeneratorInterface $url,
View $view
): ResponseInterface {
$id = (string) $request->getAttribute('id');
$code = $request->getAttribute('code');
$ip = $request->getServerParams()['REMOTE_ADDR'];
$user = null;
$token = null;

if ($id !== null) {
$user = $identityRepository->findIdentity($id);
}

if ($user !== null && $code !== null) {
$token = $tokenRepository->findTokenByParams(
(int) $user->getId(),
$code,
Token::TYPE_CONFIRMATION
);
}

if (
$user === null ||
!$token instanceof Token ||
$token->isExpired($app->get('user.tokenConfirmWithin'))
) {
$view->addFlash(
'is-danger',
$app->get('user.messageHeader'),
'The requested page does not exist.'
);

return $responseFactory
->createResponse(302)
->withHeader('Location', $url->generate('index'));
}

if (
$user !== null
&& $token instanceof Token
&& $loginService->isLoginConfirm($identityRepository, $id, $ip)
&& !$token->isExpired($app->get('user.tokenConfirmWithin'))
) {
$token->delete();

/** @var User $user */
$user->updateAttributes([
'unconfirmed_email' => null,
'confirmed_at' => time()
]);

$view->addFlash(
'is-success',
$app->get('user.messageHeader'),
'Your user has been confirmed.'
);
}

return $responseFactory
->createResponse(302)
->withHeader('Location', $url->generate('index'));
}
}
11 changes: 9 additions & 2 deletions src/Module/User/Action/Login.php
Expand Up @@ -11,24 +11,31 @@
use Psr\Http\Message\ResponseInterface;
use Psr\Http\Message\ServerRequestInterface;
use Yiisoft\DataResponse\DataResponseFactoryInterface;
use Yiisoft\Auth\IdentityRepositoryInterface;
use Yiisoft\Router\UrlGeneratorInterface;

final class Login
{
public function login(
Parameters $app,
DataResponseFactoryInterface $responseFactory,
IdentityRepositoryInterface $identityRepository,
LoginForm $loginForm,
LoginService $loginService,
ServerRequestInterface $request,
DataResponseFactoryInterface $responseFactory,
UrlGeneratorInterface $url,
View $view
): ResponseInterface {
$body = $request->getParsedBody();
$method = $request->getMethod();
$ip = $request->getServerParams()['REMOTE_ADDR'];

if ($method === 'POST' && $loginForm->load($body) && $loginForm->validate() && $loginService->isLogin($ip)) {
if (
$method === 'POST'
&& $loginForm->load($body)
&& $loginForm->validate()
&& $loginService->isLogin($identityRepository, $ip)
) {
$view->addFlash(
'is-success',
$app->get('user.messageHeader'),
Expand Down
11 changes: 7 additions & 4 deletions src/Module/User/Action/Register.php
Expand Up @@ -5,37 +5,40 @@
namespace App\Module\User\Action;

use RuntimeException;
use App\Module\User\Repository\UserRepository;
use App\Service\Parameters;
use App\Service\View;
use App\Module\User\Form\Registration as RegistrationForm;
use App\Module\User\Repository\UserRepository;
use Psr\Http\Message\ResponseInterface;
use Psr\Http\Message\ServerRequestInterface;
use Yiisoft\Auth\IdentityRepositoryInterface;
use Yiisoft\DataResponse\DataResponseFactoryInterface;
use Yiisoft\Router\UrlGeneratorInterface;

final class Register
{
public function register(
Parameters $app,
IdentityRepositoryInterface $identityRepository,
RegistrationForm $registrationForm,
ServerRequestInterface $request,
DataResponseFactoryInterface $responseFactory,
UrlGeneratorInterface $url,
UserRepository $userRepository,
View $view
): ResponseInterface {
$body = $request->getParsedBody();
$method = $request->getMethod();
$registrationForm->ip($request->getServerParams()['REMOTE_ADDR']);

/** @var UserRepository $identityRepository */
if (
$method === 'POST'
&& $registrationForm->load($body)
&& $registrationForm->validate()
&& $userRepository->register()
&& $identityRepository->register()
) {
if ($userRepository->sendMailer()) {
/** @var UserRepository $identityRepository */
if ($identityRepository->sendMailer()) {
$view->addFlash(
'is-info',
$app->get('user.messageHeader'),
Expand Down
53 changes: 53 additions & 0 deletions src/Module/User/Action/Resend.php
@@ -0,0 +1,53 @@
<?php

declare(strict_types=1);

namespace App\Module\User\Action;

use App\Module\User\Form\Resend as ResendForm;
use App\Module\User\Service\Resend as ResendService;
use App\Service\Parameters;
use App\Service\View;
use Psr\Http\Message\ResponseInterface;
use Psr\Http\Message\ServerRequestInterface;
use Yiisoft\Auth\IdentityRepositoryInterface;
use Yiisoft\DataResponse\DataResponseFactoryInterface;
use Yiisoft\Router\UrlGeneratorInterface;

final class Resend
{
public function resend(
Parameters $app,
IdentityRepositoryInterface $identityRepository,
ResendForm $resendForm,
ResendService $resendService,
DataResponseFactoryInterface $responseFactory,
ServerRequestInterface $request,
UrlGeneratorInterface $url,
View $view
): ResponseInterface {
$body = $request->getParsedBody();
$method = $request->getMethod();

if (
$method === 'POST'
&& $resendForm->load($body)
&& $resendForm->validate()
&& $resendService->run($resendForm, $identityRepository)
) {
$view->addFlash(
'is-warning',
$app->get('user.messageHeader'),
'Please check your email to activate your username.'
);

return $responseFactory
->createResponse(302)
->withHeader('Location', $url->generate('index'));
}

return $view
->viewPath('@user/resources/views')
->renderWithLayout('/registration/resend', ['data' => $resendForm]);
}
}
23 changes: 23 additions & 0 deletions src/Module/User/Asset/Resend.php
@@ -0,0 +1,23 @@
<?php

declare(strict_types=1);

namespace App\Module\User\Asset;

use Yiisoft\Assets\AssetBundle;
use Yiisoft\Yii\Bulma\Asset\BulmaAsset;

final class Resend extends AssetBundle
{
public ?string $basePath = '@assets';
public ?string $baseUrl = '@assetsUrl';
public ?string $sourcePath = '@user/resources/asset/css';

public array $css = [
'resend.css',
];

public array $depends = [
BulmaAsset::class
];
}

0 comments on commit dabbebb

Please sign in to comment.