Skip to content

Commit 34ebfda

Browse files
authored
Merge pull request #19 from niden-code/1.x
Video #9
2 parents 6ce9444 + 6d4cfc6 commit 34ebfda

39 files changed

+3238
-227
lines changed

src/Domain/ADR/Input.php

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,9 @@ public function __invoke(RequestInterface $request): array
3333
$query = $request->getQuery();
3434
/** @var TRequestQuery $post */
3535
$post = $request->getPost();
36+
/** @var TRequestQuery $put */
37+
$put = $request->getPut();
3638

37-
return array_merge($query, $post);
39+
return array_merge($query, $post, $put);
3840
}
3941
}

src/Domain/ADR/InputTypes.php

Lines changed: 66 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,10 +18,75 @@
1818
* email?: string,
1919
* password?: string
2020
* }
21+
*
22+
* @phpstan-type TLogoutInput array{
23+
* token?: string
24+
* }
25+
*
26+
* @phpstan-type TRefreshInput array{
27+
* token?: string
28+
* }
29+
*
2130
* @phpstan-type TUserInput array{
22-
* userId?: int
31+
* id?: int,
32+
* status?: int,
33+
* email?: string,
34+
* password?: string,
35+
* namePrefix?: string,
36+
* nameFirst?: string,
37+
* nameMiddle?: string,
38+
* nameLast?: string,
39+
* nameSuffix?: string,
40+
* issuer?: string,
41+
* tokenPassword?: string,
42+
* tokenId?: string,
43+
* preferences?: string,
44+
* createdDate?: string,
45+
* createdUserId?: int,
46+
* updatedDate?: string,
47+
* updatedUserId?: int,
2348
* }
49+
*
50+
* @phpstan-type TUserSanitizedInsertInput array{
51+
* status: int,
52+
* email: string,
53+
* password: string,
54+
* namePrefix: string,
55+
* nameFirst: string,
56+
* nameMiddle: string,
57+
* nameLast: string,
58+
* nameSuffix: string,
59+
* issuer: string,
60+
* tokenPassword: string,
61+
* tokenId: string,
62+
* preferences: string,
63+
* createdDate: string,
64+
* createdUserId: int,
65+
* updatedDate: string,
66+
* updatedUserId: int,
67+
* }
68+
*
69+
* @phpstan-type TUserSanitizedUpdateInput array{
70+
* id: int,
71+
* status: int,
72+
* email: string,
73+
* password: string,
74+
* namePrefix: string,
75+
* nameFirst: string,
76+
* nameMiddle: string,
77+
* nameLast: string,
78+
* nameSuffix: string,
79+
* issuer: string,
80+
* tokenPassword: string,
81+
* tokenId: string,
82+
* preferences: string,
83+
* updatedDate: string,
84+
* updatedUserId: int,
85+
* }
86+
*
2487
* @phpstan-type TRequestQuery array<array-key, bool|int|string>
88+
*
89+
* @phpstan-type TValidationErrors array<int, array<int, string>>
2590
*/
2691
final class InputTypes
2792
{

src/Domain/Components/Cache/Cache.php

Lines changed: 43 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@
1717
use Phalcon\Api\Domain\Components\Constants\Dates;
1818
use Phalcon\Api\Domain\Components\DataSource\User\UserTransport;
1919
use Phalcon\Api\Domain\Components\Env\EnvManager;
20+
use Phalcon\Cache\Adapter\Redis;
2021
use Phalcon\Cache\Cache as PhalconCache;
2122
use Psr\SimpleCache\InvalidArgumentException;
2223

@@ -54,13 +55,54 @@ class Cache extends PhalconCache
5455
*/
5556
public function getCacheTokenKey(UserTransport $domainUser, string $token): string
5657
{
58+
$tokenString = '';
59+
if (true !== empty($token)) {
60+
$tokenString = sha1($token);
61+
}
62+
5763
return sprintf(
5864
self::MASK_TOKEN_USER,
5965
$domainUser->getId(),
60-
sha1($token)
66+
$tokenString
6167
);
6268
}
6369

70+
/**
71+
* @param EnvManager $env
72+
* @param UserTransport $domainUser
73+
*
74+
* @return bool
75+
* @throws InvalidArgumentException
76+
*/
77+
public function invalidateForUser(
78+
EnvManager $env,
79+
UserTransport $domainUser
80+
): bool {
81+
/**
82+
* We could store the tokens in the database but this way is faster
83+
* and Redis also has a TTL which auto expires elements.
84+
*
85+
* To get all the keys for a user, we use the underlying adapter
86+
* of the cache which is Redis and call the `getKeys()` on it. The
87+
* keys will come back with the prefix defined in the adapter. In order
88+
* to delete them, we need to remove the prefix because `delete()` will
89+
* automatically prepend each key with it.
90+
*/
91+
/** @var Redis $redis */
92+
$redis = $this->getAdapter();
93+
$pattern = $this->getCacheTokenKey($domainUser, '');
94+
$keys = $redis->getKeys($pattern);
95+
/** @var string $prefix */
96+
$prefix = $env->get('CACHE_PREFIX', '-rest-', 'string');
97+
$newKeys = [];
98+
/** @var string $key */
99+
foreach ($keys as $key) {
100+
$newKeys[] = str_replace($prefix, '', $key);
101+
}
102+
103+
return $this->deleteMultiple($newKeys);
104+
}
105+
64106
/**
65107
* @param EnvManager $env
66108
* @param UserTransport $domainUser

src/Domain/Components/Container.php

Lines changed: 50 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -23,10 +23,16 @@
2323
use Phalcon\Api\Domain\Components\Middleware\NotFoundMiddleware;
2424
use Phalcon\Api\Domain\Components\Middleware\ValidateTokenClaimsMiddleware;
2525
use Phalcon\Api\Domain\Components\Middleware\ValidateTokenPresenceMiddleware;
26+
use Phalcon\Api\Domain\Components\Middleware\ValidateTokenRevokedMiddleware;
2627
use Phalcon\Api\Domain\Components\Middleware\ValidateTokenStructureMiddleware;
2728
use Phalcon\Api\Domain\Components\Middleware\ValidateTokenUserMiddleware;
2829
use Phalcon\Api\Domain\Services\Auth\LoginPostService;
30+
use Phalcon\Api\Domain\Services\Auth\LogoutPostService;
31+
use Phalcon\Api\Domain\Services\Auth\RefreshPostService;
32+
use Phalcon\Api\Domain\Services\User\UserDeleteService;
2933
use Phalcon\Api\Domain\Services\User\UserGetService;
34+
use Phalcon\Api\Domain\Services\User\UserPostService;
35+
use Phalcon\Api\Domain\Services\User\UserPutService;
3036
use Phalcon\Api\Responder\JsonResponder;
3137
use Phalcon\Cache\AdapterFactory;
3238
use Phalcon\DataMapper\Pdo\Connection;
@@ -45,10 +51,6 @@ class Container extends Di
4551
{
4652
/** @var string */
4753
public const APPLICATION = 'application';
48-
/**
49-
* Services
50-
*/
51-
public const AUTH_LOGIN_POST_SERVICE = 'service.auth.login.post';
5254
/** @var string */
5355
public const CACHE = 'cache';
5456
/** @var string */
@@ -63,36 +65,45 @@ class Container extends Di
6365
public const JWT_TOKEN = 'jwt.token';
6466
/** @var string */
6567
public const LOGGER = 'logger';
68+
/** @var string */
69+
public const REQUEST = 'request';
70+
/** @var string */
71+
public const RESPONSE = 'response';
72+
/** @var string */
73+
public const ROUTER = 'router';
74+
/** @var string */
75+
public const SECURITY = Security::class;
76+
/** @var string */
77+
public const TIME = 'time';
78+
/**
79+
* Services
80+
*/
81+
public const AUTH_LOGIN_POST_SERVICE = 'service.auth.login.post';
82+
public const AUTH_LOGOUT_POST_SERVICE = 'service.auth.logout.post';
83+
public const AUTH_REFRESH_POST_SERVICE = 'service.auth.refresh.post';
84+
public const USER_DELETE_SERVICE = 'service.user.delete';
85+
public const USER_GET_SERVICE = 'service.user.get';
86+
public const USER_POST_SERVICE = 'service.user.post';
87+
public const USER_PUT_SERVICE = 'service.user.put';
6688
/**
6789
* Middleware
6890
*/
69-
public const MIDDLEWARE_HEALTH = HealthMiddleware::class;
70-
public const MIDDLEWARE_NOT_FOUND = NotFoundMiddleware::class;
71-
public const MIDDLEWARE_VALIDATE_TOKEN_CLAIMS = ValidateTokenClaimsMiddleware::class;
72-
public const MIDDLEWARE_VALIDATE_TOKEN_PRESENCE = ValidateTokenPresenceMiddleware::class;
91+
public const MIDDLEWARE_HEALTH = HealthMiddleware::class;
92+
public const MIDDLEWARE_NOT_FOUND = NotFoundMiddleware::class;
93+
public const MIDDLEWARE_VALIDATE_TOKEN_CLAIMS = ValidateTokenClaimsMiddleware::class;
94+
public const MIDDLEWARE_VALIDATE_TOKEN_PRESENCE = ValidateTokenPresenceMiddleware::class;
95+
public const MIDDLEWARE_VALIDATE_TOKEN_REVOKED = ValidateTokenRevokedMiddleware::class;
7396
public const MIDDLEWARE_VALIDATE_TOKEN_STRUCTURE = ValidateTokenStructureMiddleware::class;
7497
public const MIDDLEWARE_VALIDATE_TOKEN_USER = ValidateTokenUserMiddleware::class;
7598
/**
7699
* Repositories
77100
*/
78101
public const REPOSITORY = 'repository';
79102
public const REPOSITORY_TRANSPORT = TransportRepository::class;
80-
/** @var string */
81-
public const REQUEST = 'request';
82103
/**
83104
* Responders
84105
*/
85106
public const RESPONDER_JSON = JsonResponder::class;
86-
// public const MIDDLEWARE_VALIDATE_TOKEN_REVOKED = ValidateTokenRevokedMiddleware::class;
87-
/** @var string */
88-
public const RESPONSE = 'response';
89-
/** @var string */
90-
public const ROUTER = 'router';
91-
/** @var string */
92-
public const SECURITY = Security::class;
93-
/** @var string */
94-
public const TIME = 'time';
95-
public const USER_GET_SERVICE = 'service.user.get';
96107

97108
public function __construct()
98109
{
@@ -110,21 +121,28 @@ public function __construct()
110121

111122
self::REPOSITORY => $this->getServiceRepository(),
112123

113-
self::AUTH_LOGIN_POST_SERVICE => $this->getServiceAuthLoginPost(),
114-
self::USER_GET_SERVICE => $this->getServiceUserGet(),
124+
self::AUTH_LOGIN_POST_SERVICE => $this->getServiceAuthPost(LoginPostService::class),
125+
self::AUTH_LOGOUT_POST_SERVICE => $this->getServiceAuthPost(LogoutPostService::class),
126+
self::AUTH_REFRESH_POST_SERVICE => $this->getServiceAuthPost(RefreshPostService::class),
127+
self::USER_DELETE_SERVICE => $this->getServiceUser(UserDeleteService::class),
128+
self::USER_GET_SERVICE => $this->getServiceUser(UserGetService::class),
129+
self::USER_POST_SERVICE => $this->getServiceUser(UserPostService::class),
130+
self::USER_PUT_SERVICE => $this->getServiceUser(UserPutService::class),
115131
];
116132

117133
parent::__construct();
118134
}
119135

120136
/**
137+
* @param class-string $className
138+
*
121139
* @return Service
122140
*/
123-
private function getServiceAuthLoginPost(): Service
141+
private function getServiceAuthPost(string $className): Service
124142
{
125143
return new Service(
126144
[
127-
'className' => LoginPostService::class,
145+
'className' => $className,
128146
'arguments' => [
129147
[
130148
'type' => 'service',
@@ -368,13 +386,15 @@ private function getServiceRouter(): Service
368386
}
369387

370388
/**
389+
* @param class-string $className
390+
*
371391
* @return Service
372392
*/
373-
private function getServiceUserGet(): Service
393+
private function getServiceUser(string $className): Service
374394
{
375395
return new Service(
376396
[
377-
'className' => UserGetService::class,
397+
'className' => $className,
378398
'arguments' => [
379399
[
380400
'type' => 'service',
@@ -388,6 +408,10 @@ private function getServiceUserGet(): Service
388408
'type' => 'service',
389409
'name' => self::FILTER,
390410
],
411+
[
412+
'type' => 'service',
413+
'name' => self::SECURITY,
414+
],
391415
],
392416
]
393417
);

0 commit comments

Comments
 (0)