feature/RVRNEXT-2-implement-login-to-old-rvr #6
@ -19,3 +19,5 @@ GOOGLE_OAUTH_CLIENT_SECRET=your_google_oauth_client_secret
|
|||||||
GOOGLE_ANALITICS_ID=your_google_analytics_id
|
GOOGLE_ANALITICS_ID=your_google_analytics_id
|
||||||
RECAPTCHA_SITEKEY=your_recaptcha_sitekey
|
RECAPTCHA_SITEKEY=your_recaptcha_sitekey
|
||||||
RECAPTCHA_SECRET=your_recaptcha_secret
|
RECAPTCHA_SECRET=your_recaptcha_secret
|
||||||
|
JWT_RSA_PRIVATE_KEY=jwt-rsa256-private.pem
|
||||||
|
JWT_RSA_PUBLIC_KEY=jwt-rsa256-public.pem
|
||||||
|
1
.gitignore
vendored
1
.gitignore
vendored
@ -2,3 +2,4 @@
|
|||||||
installed
|
installed
|
||||||
vendor
|
vendor
|
||||||
node_modules
|
node_modules
|
||||||
|
*.pem
|
||||||
|
@ -10,7 +10,8 @@
|
|||||||
}
|
}
|
||||||
],
|
],
|
||||||
"require": {
|
"require": {
|
||||||
"esoko/soko-web": "0.1"
|
"esoko/soko-web": "0.1",
|
||||||
|
"firebase/php-jwt": "^6.4"
|
||||||
},
|
},
|
||||||
"require-dev": {
|
"require-dev": {
|
||||||
"phpunit/phpunit": "^9.6",
|
"phpunit/phpunit": "^9.6",
|
||||||
|
65
composer.lock
generated
65
composer.lock
generated
@ -4,7 +4,7 @@
|
|||||||
"Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies",
|
"Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies",
|
||||||
"This file is @generated automatically"
|
"This file is @generated automatically"
|
||||||
],
|
],
|
||||||
"content-hash": "3479948070678fa4e980114fbe8b71b5",
|
"content-hash": "f2dcf297a4a619bc5edfe7b4fac0836e",
|
||||||
"packages": [
|
"packages": [
|
||||||
{
|
{
|
||||||
"name": "esoko/soko-web",
|
"name": "esoko/soko-web",
|
||||||
@ -35,6 +35,69 @@
|
|||||||
"description": "Lightweight web framework",
|
"description": "Lightweight web framework",
|
||||||
"time": "2023-04-07T17:32:15+00:00"
|
"time": "2023-04-07T17:32:15+00:00"
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
"name": "firebase/php-jwt",
|
||||||
|
"version": "v6.4.0",
|
||||||
|
"source": {
|
||||||
|
"type": "git",
|
||||||
|
"url": "https://github.com/firebase/php-jwt.git",
|
||||||
|
"reference": "4dd1e007f22a927ac77da5a3fbb067b42d3bc224"
|
||||||
|
},
|
||||||
|
"dist": {
|
||||||
|
"type": "zip",
|
||||||
|
"url": "https://api.github.com/repos/firebase/php-jwt/zipball/4dd1e007f22a927ac77da5a3fbb067b42d3bc224",
|
||||||
|
"reference": "4dd1e007f22a927ac77da5a3fbb067b42d3bc224",
|
||||||
|
"shasum": ""
|
||||||
|
},
|
||||||
|
"require": {
|
||||||
|
"php": "^7.1||^8.0"
|
||||||
|
},
|
||||||
|
"require-dev": {
|
||||||
|
"guzzlehttp/guzzle": "^6.5||^7.4",
|
||||||
|
"phpspec/prophecy-phpunit": "^1.1",
|
||||||
|
"phpunit/phpunit": "^7.5||^9.5",
|
||||||
|
"psr/cache": "^1.0||^2.0",
|
||||||
|
"psr/http-client": "^1.0",
|
||||||
|
"psr/http-factory": "^1.0"
|
||||||
|
},
|
||||||
|
"suggest": {
|
||||||
|
"ext-sodium": "Support EdDSA (Ed25519) signatures",
|
||||||
|
"paragonie/sodium_compat": "Support EdDSA (Ed25519) signatures when libsodium is not present"
|
||||||
|
},
|
||||||
|
"type": "library",
|
||||||
|
"autoload": {
|
||||||
|
"psr-4": {
|
||||||
|
"Firebase\\JWT\\": "src"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"notification-url": "https://packagist.org/downloads/",
|
||||||
|
"license": [
|
||||||
|
"BSD-3-Clause"
|
||||||
|
],
|
||||||
|
"authors": [
|
||||||
|
{
|
||||||
|
"name": "Neuman Vong",
|
||||||
|
"email": "neuman+pear@twilio.com",
|
||||||
|
"role": "Developer"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "Anant Narayanan",
|
||||||
|
"email": "anant@php.net",
|
||||||
|
"role": "Developer"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"description": "A simple library to encode and decode JSON Web Tokens (JWT) in PHP. Should conform to the current spec.",
|
||||||
|
"homepage": "https://github.com/firebase/php-jwt",
|
||||||
|
"keywords": [
|
||||||
|
"jwt",
|
||||||
|
"php"
|
||||||
|
],
|
||||||
|
"support": {
|
||||||
|
"issues": "https://github.com/firebase/php-jwt/issues",
|
||||||
|
"source": "https://github.com/firebase/php-jwt/tree/v6.4.0"
|
||||||
|
},
|
||||||
|
"time": "2023-02-09T21:01:23+00:00"
|
||||||
|
},
|
||||||
{
|
{
|
||||||
"name": "graham-campbell/result-type",
|
"name": "graham-campbell/result-type",
|
||||||
"version": "v1.1.1",
|
"version": "v1.1.1",
|
||||||
|
10
database/migrations/structure/20230408_1129_oauth.sql
Normal file
10
database/migrations/structure/20230408_1129_oauth.sql
Normal file
@ -0,0 +1,10 @@
|
|||||||
|
CREATE TABLE `oauth_tokens` (
|
||||||
|
`id` int(10) unsigned NOT NULL AUTO_INCREMENT,
|
||||||
|
`nonce` varchar(255) CHARACTER SET ascii COLLATE ascii_bin NOT NULL,
|
||||||
|
`user_id` int(10) unsigned DEFAULT NULL,
|
||||||
|
`code` varchar(255) CHARACTER SET ascii COLLATE ascii_bin NOT NULL,
|
||||||
|
`created` timestamp NOT NULL DEFAULT current_timestamp(),
|
||||||
|
`expires` timestamp NOT NULL DEFAULT current_timestamp() ON UPDATE current_timestamp(),
|
||||||
|
PRIMARY KEY (`id`),
|
||||||
|
UNIQUE KEY `code` (`code`)
|
||||||
|
) ENGINE = InnoDB DEFAULT CHARSET = utf8mb4;
|
@ -27,21 +27,27 @@ class LoginController
|
|||||||
|
|
||||||
private UserPasswordResetterRepository $userPasswordResetterRepository;
|
private UserPasswordResetterRepository $userPasswordResetterRepository;
|
||||||
|
|
||||||
|
private string $redirectUrl;
|
||||||
|
|
||||||
public function __construct(IRequest $request)
|
public function __construct(IRequest $request)
|
||||||
{
|
{
|
||||||
$this->request = $request;
|
$this->request = $request;
|
||||||
$this->pdm = new PersistentDataManager();
|
$this->pdm = new PersistentDataManager();
|
||||||
$this->userRepository = new UserRepository();
|
$this->userRepository = new UserRepository();
|
||||||
$this->userPasswordResetterRepository = new UserPasswordResetterRepository();
|
$this->userPasswordResetterRepository = new UserPasswordResetterRepository();
|
||||||
|
$this->redirectUrl = $this->request->session()->has('redirect_after_login') ?
|
||||||
|
$this->request->session()->get('redirect_after_login') :
|
||||||
|
\Container::$routeCollection->getRoute('index')->generateLink();
|
||||||
}
|
}
|
||||||
|
|
||||||
public function getLoginForm()
|
public function getLoginForm()
|
||||||
{
|
{
|
||||||
if ($this->request->user() !== null) {
|
if ($this->request->user() !== null) {
|
||||||
return new Redirect(\Container::$routeCollection->getRoute('index')->generateLink(), IRedirect::TEMPORARY);
|
$this->deleteRedirectUrl();
|
||||||
|
return new Redirect($this->redirectUrl, IRedirect::TEMPORARY);
|
||||||
}
|
}
|
||||||
|
|
||||||
return new HtmlContent('login/login', ['redirectUrl' => $this->getRedirectUrl()]);
|
return new HtmlContent('login/login', ['redirectUrl' => $this->redirectUrl]);
|
||||||
}
|
}
|
||||||
|
|
||||||
public function getGoogleLoginRedirect(): IRedirect
|
public function getGoogleLoginRedirect(): IRedirect
|
||||||
@ -65,7 +71,8 @@ class LoginController
|
|||||||
public function getRequestPasswordResetForm()
|
public function getRequestPasswordResetForm()
|
||||||
{
|
{
|
||||||
if ($this->request->user() !== null) {
|
if ($this->request->user() !== null) {
|
||||||
return new Redirect(\Container::$routeCollection->getRoute('index')->generateLink(), IRedirect::TEMPORARY);
|
$this->deleteRedirectUrl();
|
||||||
|
return new Redirect($this->redirectUrl, IRedirect::TEMPORARY);
|
||||||
}
|
}
|
||||||
|
|
||||||
return new HtmlContent('login/password_reset_request', ['email' => $this->request->query('email')]);
|
return new HtmlContent('login/password_reset_request', ['email' => $this->request->query('email')]);
|
||||||
@ -79,7 +86,8 @@ class LoginController
|
|||||||
public function getResetPasswordForm()
|
public function getResetPasswordForm()
|
||||||
{
|
{
|
||||||
if ($this->request->user() !== null) {
|
if ($this->request->user() !== null) {
|
||||||
return new Redirect(\Container::$routeCollection->getRoute('index')->generateLink(), IRedirect::TEMPORARY);
|
$this->deleteRedirectUrl();
|
||||||
|
return new Redirect($this->redirectUrl, IRedirect::TEMPORARY);
|
||||||
}
|
}
|
||||||
|
|
||||||
$token = $this->request->query('token');
|
$token = $this->request->query('token');
|
||||||
@ -91,7 +99,7 @@ class LoginController
|
|||||||
|
|
||||||
$user = $this->userRepository->getById($resetter->getUserId());
|
$user = $this->userRepository->getById($resetter->getUserId());
|
||||||
|
|
||||||
return new HtmlContent('login/reset_password', ['success' => true, 'token' => $token, 'email' => $user->getEmail(), 'redirectUrl' => $this->getRedirectUrl()]);
|
return new HtmlContent('login/reset_password', ['success' => true, 'token' => $token, 'email' => $user->getEmail(), 'redirectUrl' => $this->redirectUrl]);
|
||||||
}
|
}
|
||||||
|
|
||||||
public function login(): IContent
|
public function login(): IContent
|
||||||
@ -123,7 +131,7 @@ class LoginController
|
|||||||
|
|
||||||
if ($this->request->user() !== null) {
|
if ($this->request->user() !== null) {
|
||||||
$this->deleteRedirectUrl();
|
$this->deleteRedirectUrl();
|
||||||
return new Redirect($this->getRedirectUrl(), IRedirect::TEMPORARY);
|
return new Redirect($this->redirectUrl, IRedirect::TEMPORARY);
|
||||||
}
|
}
|
||||||
|
|
||||||
if ($this->request->query('state') !== $this->request->session()->get('oauth_state')) {
|
if ($this->request->query('state') !== $this->request->session()->get('oauth_state')) {
|
||||||
@ -159,7 +167,7 @@ class LoginController
|
|||||||
$this->request->setUser($user);
|
$this->request->setUser($user);
|
||||||
|
|
||||||
$this->deleteRedirectUrl();
|
$this->deleteRedirectUrl();
|
||||||
return new Redirect($this->getRedirectUrl(), IRedirect::TEMPORARY);
|
return new Redirect($this->redirectUrl, IRedirect::TEMPORARY);
|
||||||
}
|
}
|
||||||
|
|
||||||
public function logout(): IRedirect
|
public function logout(): IRedirect
|
||||||
@ -175,7 +183,7 @@ class LoginController
|
|||||||
$this->deleteRedirectUrl();
|
$this->deleteRedirectUrl();
|
||||||
return new JsonContent([
|
return new JsonContent([
|
||||||
'redirect' => [
|
'redirect' => [
|
||||||
'target' => $this->getRedirectUrl()
|
'target' => $this->redirectUrl
|
||||||
]
|
]
|
||||||
]);
|
]);
|
||||||
}
|
}
|
||||||
@ -239,7 +247,7 @@ class LoginController
|
|||||||
$this->deleteRedirectUrl();
|
$this->deleteRedirectUrl();
|
||||||
return new JsonContent([
|
return new JsonContent([
|
||||||
'redirect' => [
|
'redirect' => [
|
||||||
'target' => $this->getRedirectUrl()
|
'target' => $this->redirectUrl
|
||||||
]
|
]
|
||||||
]);
|
]);
|
||||||
}
|
}
|
||||||
@ -298,15 +306,6 @@ class LoginController
|
|||||||
$mail->send();
|
$mail->send();
|
||||||
}
|
}
|
||||||
|
|
||||||
private function getRedirectUrl(): string
|
|
||||||
{
|
|
||||||
$redirectUrl = $this->request->session()->get('redirect_after_login');
|
|
||||||
if ($redirectUrl === null) {
|
|
||||||
return \Container::$routeCollection->getRoute('index')->generateLink();
|
|
||||||
}
|
|
||||||
return $redirectUrl;
|
|
||||||
}
|
|
||||||
|
|
||||||
private function deleteRedirectUrl(): void
|
private function deleteRedirectUrl(): void
|
||||||
{
|
{
|
||||||
$this->request->session()->delete('redirect_after_login');
|
$this->request->session()->delete('redirect_after_login');
|
||||||
|
124
src/Controller/OAuthLoginController.php
Normal file
124
src/Controller/OAuthLoginController.php
Normal file
@ -0,0 +1,124 @@
|
|||||||
|
<?php namespace RVR\Controller;
|
||||||
|
|
||||||
|
use DateTime;
|
||||||
|
use Firebase\JWT\JWT;
|
||||||
|
use RVR\PersistentData\Model\OAuthToken;
|
||||||
|
use RVR\Repository\OAuthTokenRepository;
|
||||||
|
use RVR\Repository\UserRepository;
|
||||||
|
use RVR\PersistentData\Model\User;
|
||||||
|
use SokoWeb\Interfaces\Request\IRequest;
|
||||||
|
use SokoWeb\Interfaces\Response\IContent;
|
||||||
|
use SokoWeb\Interfaces\Response\IRedirect;
|
||||||
|
use SokoWeb\Response\Redirect;
|
||||||
|
use SokoWeb\PersistentData\PersistentDataManager;
|
||||||
|
use SokoWeb\Response\HtmlContent;
|
||||||
|
use SokoWeb\Response\JsonContent;
|
||||||
|
|
||||||
|
class OAuthLoginController
|
||||||
|
{
|
||||||
|
private IRequest $request;
|
||||||
|
|
||||||
|
private PersistentDataManager $pdm;
|
||||||
|
|
||||||
|
public function __construct(IRequest $request)
|
||||||
|
{
|
||||||
|
$this->request = $request;
|
||||||
|
$this->pdm = new PersistentDataManager();
|
||||||
|
}
|
||||||
|
|
||||||
|
public function startOauth()
|
||||||
|
{
|
||||||
|
$redirectUri = $this->request->query('redirect_uri');
|
||||||
|
$state = $this->request->query('state');
|
||||||
|
$nonce = $this->request->query('nonce');
|
||||||
|
|
||||||
|
if (!$redirectUri || !$state) {
|
||||||
|
return new HtmlContent('oauth/oauth_error', ['error' => 'An invalid request was made. Please start authentication again.']);
|
||||||
|
}
|
||||||
|
|
||||||
|
$this->request->session()->set('oauth_state', [
|
||||||
|
'redirect_uri' => $redirectUri,
|
||||||
|
'state' => $state,
|
||||||
|
'nonce' => $nonce === null ? '' : $nonce
|
||||||
|
]);
|
||||||
|
|
||||||
|
$this->request->session()->set('redirect_after_login', \Container::$routeCollection->getRoute('oauth-finish')->generateLink());
|
||||||
|
|
||||||
|
return new Redirect(\Container::$routeCollection->getRoute('login')->generateLink(), IRedirect::TEMPORARY);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function finishOauth()
|
||||||
|
{
|
||||||
|
$oauthState = $this->request->session()->get('oauth_state');
|
||||||
|
if ($oauthState === null) {
|
||||||
|
return new HtmlContent('oauth/oauth_error', ['error' => 'An invalid request was made. Please start authentication again.']);
|
||||||
|
}
|
||||||
|
|
||||||
|
$this->request->session()->delete('oauth_state');
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @var ?User $user
|
||||||
|
*/
|
||||||
|
$user = $this->request->user();
|
||||||
|
if ($user === null) {
|
||||||
|
return new HtmlContent('oauth/oauth_error', ['error' => 'You are not logged in. Please start authentication again.']);
|
||||||
|
}
|
||||||
|
|
||||||
|
$code = bin2hex(random_bytes(16));
|
||||||
|
|
||||||
|
$token = new OAuthToken();
|
||||||
|
$token->setNonce($oauthState['nonce']);
|
||||||
|
$token->setUser($user);
|
||||||
|
$token->setCode($code);
|
||||||
|
$token->setCreatedDate(new DateTime());
|
||||||
|
$token->setExpiresDate(new DateTime('+5 minutes'));
|
||||||
|
$this->pdm->saveToDb($token);
|
||||||
|
|
||||||
|
$redirectUri = $oauthState['redirect_uri'];
|
||||||
|
$additionalUriParams = [
|
||||||
|
'state' => $oauthState['state'],
|
||||||
|
'code' => $code
|
||||||
|
];
|
||||||
|
$and = (strpos($redirectUri, '?') !== false) ? '&' : '?';
|
||||||
|
$finalRedirectUri = $redirectUri . $and . http_build_query($additionalUriParams);
|
||||||
|
|
||||||
|
return new Redirect($finalRedirectUri, IRedirect::TEMPORARY);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getToken(): ?IContent
|
||||||
|
{
|
||||||
|
$oAuthTokenRepository = new OAuthTokenRepository();
|
||||||
|
$userRepository = new UserRepository();
|
||||||
|
$token = $oAuthTokenRepository->getByCode($this->request->query('code'));
|
||||||
|
|
||||||
|
if ($token === null || $token->getExpiresDate() < new DateTime()) {
|
||||||
|
return new JsonContent([
|
||||||
|
'error' => 'The provided code is invalid.'
|
||||||
|
]);
|
||||||
|
}
|
||||||
|
|
||||||
|
$user = $userRepository->getById($token->getUserId());
|
||||||
|
|
||||||
|
$payload = [
|
||||||
|
'iss' => $_ENV['APP_URL'],
|
||||||
|
'iat' => (int)$token->getCreatedDate()->format('U'),
|
||||||
|
'nbf' => (int)$token->getCreatedDate()->format('U'),
|
||||||
|
'exp' => (int)$token->getExpiresDate()->format('U'),
|
||||||
|
'nonce' => $token->getNonce(),
|
||||||
|
'sub' => $user->getId(),
|
||||||
|
'email' => $user->getEmail()
|
||||||
|
];
|
||||||
|
$privateKey = file_get_contents(ROOT . '/' . $_ENV['JWT_RSA_PRIVATE_KEY']);
|
||||||
|
$jwt = JWT::encode($payload, $privateKey, 'RS256');
|
||||||
|
|
||||||
|
return new JsonContent([
|
||||||
|
'id_token' => $jwt
|
||||||
|
]);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getJwtPublicKey(): IContent
|
||||||
|
{
|
||||||
|
$publicKey = file_get_contents(ROOT . '/' . $_ENV['JWT_RSA_PUBLIC_KEY']);
|
||||||
|
return new JsonContent(['pubkey' => $publicKey]);
|
||||||
|
}
|
||||||
|
}
|
105
src/PersistentData/Model/OAuthToken.php
Normal file
105
src/PersistentData/Model/OAuthToken.php
Normal file
@ -0,0 +1,105 @@
|
|||||||
|
<?php namespace RVR\PersistentData\Model;
|
||||||
|
|
||||||
|
use DateTime;
|
||||||
|
use SokoWeb\PersistentData\Model\Model;
|
||||||
|
|
||||||
|
class OAuthToken extends Model
|
||||||
|
{
|
||||||
|
protected static string $table = 'oauth_tokens';
|
||||||
|
|
||||||
|
protected static array $fields = ['nonce', 'user_id', 'code', 'created', 'expires'];
|
||||||
|
|
||||||
|
protected static array $relations = ['user' => User::class];
|
||||||
|
|
||||||
|
private string $nonce = '';
|
||||||
|
|
||||||
|
private ?User $user = null;
|
||||||
|
|
||||||
|
private ?int $userId = null;
|
||||||
|
|
||||||
|
private string $code = '';
|
||||||
|
|
||||||
|
private DateTime $created;
|
||||||
|
|
||||||
|
private DateTime $expires;
|
||||||
|
|
||||||
|
public function setNonce(string $nonce): void
|
||||||
|
{
|
||||||
|
$this->nonce = $nonce;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function setUser(User $user): void
|
||||||
|
{
|
||||||
|
$this->user = $user;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function setUserId(int $userId): void
|
||||||
|
{
|
||||||
|
$this->userId = $userId;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function setCode(string $code): void
|
||||||
|
{
|
||||||
|
$this->code = $code;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function setCreatedDate(DateTime $created): void
|
||||||
|
{
|
||||||
|
$this->created = $created;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function setExpiresDate(DateTime $expires): void
|
||||||
|
{
|
||||||
|
$this->expires = $expires;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function setCreated(string $created): void
|
||||||
|
{
|
||||||
|
$this->created = new DateTime($created);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function setExpires(string $expires): void
|
||||||
|
{
|
||||||
|
$this->expires = new DateTime($expires);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getNonce(): string
|
||||||
|
{
|
||||||
|
return $this->nonce;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getUser(): ?User
|
||||||
|
{
|
||||||
|
return $this->user;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getUserId(): ?int
|
||||||
|
{
|
||||||
|
return $this->userId;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getCode(): string
|
||||||
|
{
|
||||||
|
return $this->code;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getCreatedDate(): DateTime
|
||||||
|
{
|
||||||
|
return $this->created;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getCreated(): string
|
||||||
|
{
|
||||||
|
return $this->created->format('Y-m-d H:i:s');
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getExpiresDate(): DateTime
|
||||||
|
{
|
||||||
|
return $this->expires;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getExpires(): string
|
||||||
|
{
|
||||||
|
return $this->expires->format('Y-m-d H:i:s');
|
||||||
|
}
|
||||||
|
}
|
38
src/Repository/OAuthTokenRepository.php
Normal file
38
src/Repository/OAuthTokenRepository.php
Normal file
@ -0,0 +1,38 @@
|
|||||||
|
<?php namespace RVR\Repository;
|
||||||
|
|
||||||
|
use DateTime;
|
||||||
|
use Generator;
|
||||||
|
use SokoWeb\Database\Query\Select;
|
||||||
|
use RVR\PersistentData\Model\OAuthToken;
|
||||||
|
use SokoWeb\PersistentData\PersistentDataManager;
|
||||||
|
|
||||||
|
class OAuthTokenRepository
|
||||||
|
{
|
||||||
|
private PersistentDataManager $pdm;
|
||||||
|
|
||||||
|
public function __construct()
|
||||||
|
{
|
||||||
|
$this->pdm = new PersistentDataManager();
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getById(int $id): ?OAuthToken
|
||||||
|
{
|
||||||
|
return $this->pdm->selectFromDbById($id, OAuthToken::class);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getByCode(string $code): ?OAuthToken
|
||||||
|
{
|
||||||
|
$select = new Select(\Container::$dbConnection);
|
||||||
|
$select->where('code', '=', $code);
|
||||||
|
|
||||||
|
return $this->pdm->selectFromDb($select, OAuthToken::class);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getAllExpired(): Generator
|
||||||
|
{
|
||||||
|
$select = new Select(\Container::$dbConnection);
|
||||||
|
$select->where('expires', '<', (new DateTime())->format('Y-m-d H:i:s'));
|
||||||
|
|
||||||
|
yield from $this->pdm->selectMultipleFromDb($select, OAuthToken::class);
|
||||||
|
}
|
||||||
|
}
|
8
views/oauth/oauth_error.php
Normal file
8
views/oauth/oauth_error.php
Normal file
@ -0,0 +1,8 @@
|
|||||||
|
@extends(templates/layout_normal)
|
||||||
|
|
||||||
|
@section(main)
|
||||||
|
<h2>OAuth error</h2>
|
||||||
|
<div class="box">
|
||||||
|
<p class="error justify"><?= $error ?></p>
|
||||||
|
</div>
|
||||||
|
@endsection
|
6
web.php
6
web.php
@ -20,6 +20,12 @@ Container::$routeCollection->group('login', function (SokoWeb\Routing\RouteColle
|
|||||||
$routeCollection->get('login-google', 'google', [RVR\Controller\LoginController::class, 'getGoogleLoginRedirect']);
|
$routeCollection->get('login-google', 'google', [RVR\Controller\LoginController::class, 'getGoogleLoginRedirect']);
|
||||||
$routeCollection->get('login-google-action', 'google/code', [RVR\Controller\LoginController::class, 'loginWithGoogle']);
|
$routeCollection->get('login-google-action', 'google/code', [RVR\Controller\LoginController::class, 'loginWithGoogle']);
|
||||||
});
|
});
|
||||||
|
Container::$routeCollection->group('oauth', function (SokoWeb\Routing\RouteCollection $routeCollection) {
|
||||||
|
$routeCollection->get('oauth-start', 'start', [RVR\Controller\OAuthLoginController::class, 'startOauth']);
|
||||||
|
$routeCollection->get('oauth-finish', 'finish', [RVR\Controller\OAuthLoginController::class, 'finishOauth']);
|
||||||
|
$routeCollection->get('oauth-getToken', 'getToken', [RVR\Controller\OAuthLoginController::class, 'getToken']);
|
||||||
|
$routeCollection->get('oauth-getJwtPublicKey', 'getJwtPublicKey', [RVR\Controller\OAuthLoginController::class, 'getJwtPublicKey']);
|
||||||
|
});
|
||||||
Container::$routeCollection->group('password', function (SokoWeb\Routing\RouteCollection $routeCollection) {
|
Container::$routeCollection->group('password', function (SokoWeb\Routing\RouteCollection $routeCollection) {
|
||||||
$routeCollection->get('password-requestReset', 'requestReset', [RVR\Controller\LoginController::class, 'getRequestPasswordResetForm']);
|
$routeCollection->get('password-requestReset', 'requestReset', [RVR\Controller\LoginController::class, 'getRequestPasswordResetForm']);
|
||||||
$routeCollection->post('password-requestReset-action', 'requestReset', [RVR\Controller\LoginController::class, 'requestPasswordReset']);
|
$routeCollection->post('password-requestReset-action', 'requestReset', [RVR\Controller\LoginController::class, 'requestPasswordReset']);
|
||||||
|
Loading…
Reference in New Issue
Block a user