make oauth endpoints openid compliant
This commit is contained in:
parent
db757de71c
commit
fa90f3dbd6
@ -0,0 +1,4 @@
|
|||||||
|
ALTER TABLE `oauth_tokens`
|
||||||
|
ADD `scope` varchar(255) NOT NULL DEFAULT '',
|
||||||
|
ADD `access_token` varchar(255) CHARACTER SET ascii COLLATE ascii_bin DEFAULT NULL,
|
||||||
|
ADD UNIQUE `access_token` (`access_token`);
|
70
src/Controller/OAuthAuthController.php
Normal file
70
src/Controller/OAuthAuthController.php
Normal file
@ -0,0 +1,70 @@
|
|||||||
|
<?php namespace RVR\Controller;
|
||||||
|
|
||||||
|
use DateTime;
|
||||||
|
use RVR\PersistentData\Model\OAuthToken;
|
||||||
|
use RVR\PersistentData\Model\User;
|
||||||
|
use SokoWeb\Interfaces\Authorization\ISecured;
|
||||||
|
use SokoWeb\Interfaces\Request\IRequest;
|
||||||
|
use SokoWeb\Interfaces\Response\IRedirect;
|
||||||
|
use SokoWeb\Response\Redirect;
|
||||||
|
use SokoWeb\PersistentData\PersistentDataManager;
|
||||||
|
use SokoWeb\Response\HtmlContent;
|
||||||
|
|
||||||
|
class OAuthAuthController implements ISecured
|
||||||
|
{
|
||||||
|
private IRequest $request;
|
||||||
|
|
||||||
|
private PersistentDataManager $pdm;
|
||||||
|
|
||||||
|
public function __construct(IRequest $request)
|
||||||
|
{
|
||||||
|
$this->request = $request;
|
||||||
|
$this->pdm = new PersistentDataManager();
|
||||||
|
}
|
||||||
|
|
||||||
|
public function authorize(): bool
|
||||||
|
{
|
||||||
|
return $this->request->user() !== null;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function auth()
|
||||||
|
{
|
||||||
|
$redirectUri = $this->request->query('redirect_uri');
|
||||||
|
$scope = $this->request->query('scope') ? $this->request->query('scope'): '';
|
||||||
|
$state = $this->request->query('state');
|
||||||
|
$nonce = $this->request->query('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()->delete('oauth_payload');
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @var ?User $user
|
||||||
|
*/
|
||||||
|
$user = $this->request->user();
|
||||||
|
$code = bin2hex(random_bytes(16));
|
||||||
|
$accessToken = bin2hex(random_bytes(16));
|
||||||
|
|
||||||
|
$token = new OAuthToken();
|
||||||
|
$token->setNonce($nonce);
|
||||||
|
$token->setScope($scope);
|
||||||
|
$token->setUser($user);
|
||||||
|
$token->setCode($code);
|
||||||
|
$token->setAccessToken($accessToken);
|
||||||
|
$token->setCreatedDate(new DateTime());
|
||||||
|
$token->setExpiresDate(new DateTime('+5 minutes'));
|
||||||
|
$this->pdm->saveToDb($token);
|
||||||
|
|
||||||
|
$redirectUri = $redirectUri;
|
||||||
|
$additionalUriParams = [
|
||||||
|
'state' => $state,
|
||||||
|
'code' => $code
|
||||||
|
];
|
||||||
|
$and = (strpos($redirectUri, '?') !== false) ? '&' : '?';
|
||||||
|
$finalRedirectUri = $redirectUri . $and . http_build_query($additionalUriParams);
|
||||||
|
|
||||||
|
return new Redirect($finalRedirectUri, IRedirect::TEMPORARY);
|
||||||
|
}
|
||||||
|
}
|
182
src/Controller/OAuthController.php
Normal file
182
src/Controller/OAuthController.php
Normal file
@ -0,0 +1,182 @@
|
|||||||
|
<?php namespace RVR\Controller;
|
||||||
|
|
||||||
|
use DateTime;
|
||||||
|
use Firebase\JWT\JWT;
|
||||||
|
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\Response\JsonContent;
|
||||||
|
|
||||||
|
class OAuthController
|
||||||
|
{
|
||||||
|
private IRequest $request;
|
||||||
|
|
||||||
|
private OAuthTokenRepository $oAuthTokenRepository;
|
||||||
|
|
||||||
|
private UserRepository $userRepository;
|
||||||
|
|
||||||
|
public function __construct(IRequest $request)
|
||||||
|
{
|
||||||
|
$this->request = $request;
|
||||||
|
$this->oAuthTokenRepository = new OAuthTokenRepository();
|
||||||
|
$this->userRepository = new UserRepository();
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getToken(): ?IContent
|
||||||
|
{
|
||||||
|
$token = $this->oAuthTokenRepository->getByCode($this->request->post('code'));
|
||||||
|
|
||||||
|
if ($token === null || $token->getExpiresDate() < new DateTime()) {
|
||||||
|
return new JsonContent([
|
||||||
|
'error' => 'The provided code is invalid.'
|
||||||
|
]);
|
||||||
|
}
|
||||||
|
|
||||||
|
$payload = array_merge([
|
||||||
|
'iss' => $_ENV['APP_URL'],
|
||||||
|
'iat' => (int)$token->getCreatedDate()->getTimestamp(),
|
||||||
|
'nbf' => (int)$token->getCreatedDate()->getTimestamp(),
|
||||||
|
'exp' => (int)$token->getExpiresDate()->getTimestamp(),
|
||||||
|
'nonce' => $token->getNonce()
|
||||||
|
], $this->getUserInfoInternal(
|
||||||
|
$this->userRepository->getById($token->getUserId()),
|
||||||
|
$token->getScopeArray())
|
||||||
|
);
|
||||||
|
|
||||||
|
$privateKey = file_get_contents(ROOT . '/' . $_ENV['JWT_RSA_PRIVATE_KEY']);
|
||||||
|
$jwt = JWT::encode($payload, $privateKey, 'RS256');
|
||||||
|
|
||||||
|
return new JsonContent([
|
||||||
|
'access_token' => $token->getAccessToken(),
|
||||||
|
'expires_in' => $token->getExpiresDate()->getTimestamp() - (new DateTime())->getTimestamp(),
|
||||||
|
'scope' => $token->getScope(),
|
||||||
|
'id_token' => $jwt,
|
||||||
|
'token_type' => 'Bearer'
|
||||||
|
]);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getUserInfo() : IContent
|
||||||
|
{
|
||||||
|
//TODO: headers should be set by soko-web
|
||||||
|
$headers = getallheaders();
|
||||||
|
|
||||||
|
if (!isset($headers['Authorization'])) {
|
||||||
|
return new JsonContent([
|
||||||
|
'error' => 'No Authorization header was sent.'
|
||||||
|
]);
|
||||||
|
}
|
||||||
|
|
||||||
|
$accessToken = substr($headers['Authorization'], strlen('Bearer '));
|
||||||
|
$token = $this->oAuthTokenRepository->getByAccessToken($accessToken);
|
||||||
|
|
||||||
|
if ($token === null || $token->getExpiresDate() < new DateTime()) {
|
||||||
|
return new JsonContent([
|
||||||
|
'error' => 'The provided access token is invalid.'
|
||||||
|
]);
|
||||||
|
}
|
||||||
|
|
||||||
|
return new JsonContent(
|
||||||
|
$this->getUserInfoInternal(
|
||||||
|
$this->userRepository->getById($token->getUserId()),
|
||||||
|
$token->getScopeArray()
|
||||||
|
)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getConfig(): IContent
|
||||||
|
{
|
||||||
|
return new JsonContent([
|
||||||
|
'issuer' => $_ENV['APP_URL'],
|
||||||
|
'authorization_endpoint' => $this->request->getBase() . '/oauth/auth',
|
||||||
|
'token_endpoint' => $this->request->getBase() . '/oauth/token',
|
||||||
|
'userinfo_endpoint' => $this->request->getBase() . '/oauth/userinfo',
|
||||||
|
'jwks_uri' => $this->request->getBase() . '/oauth/certs',
|
||||||
|
'response_types_supported' =>
|
||||||
|
[
|
||||||
|
'code',
|
||||||
|
],
|
||||||
|
'subject_types_supported' =>
|
||||||
|
[
|
||||||
|
'public',
|
||||||
|
],
|
||||||
|
'id_token_signing_alg_values_supported' =>
|
||||||
|
[
|
||||||
|
'RS256',
|
||||||
|
],
|
||||||
|
'scopes_supported' =>
|
||||||
|
[
|
||||||
|
'openid',
|
||||||
|
'email',
|
||||||
|
'profile',
|
||||||
|
],
|
||||||
|
'token_endpoint_auth_methods_supported' =>
|
||||||
|
[
|
||||||
|
'client_secret_post',
|
||||||
|
],
|
||||||
|
'claims_supported' =>
|
||||||
|
[
|
||||||
|
'aud',
|
||||||
|
'email',
|
||||||
|
'exp',
|
||||||
|
'full_name',
|
||||||
|
'iat',
|
||||||
|
'id_number',
|
||||||
|
'iss',
|
||||||
|
'nickname',
|
||||||
|
'phone',
|
||||||
|
'picture',
|
||||||
|
'sub',
|
||||||
|
'username',
|
||||||
|
],
|
||||||
|
'code_challenge_methods_supported' =>
|
||||||
|
[
|
||||||
|
'plain',
|
||||||
|
'S256',
|
||||||
|
],
|
||||||
|
'grant_types_supported' =>
|
||||||
|
[
|
||||||
|
'authorization_code',
|
||||||
|
],
|
||||||
|
]);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getCerts(): IContent
|
||||||
|
{
|
||||||
|
$publicKey = file_get_contents(ROOT . '/' . $_ENV['JWT_RSA_PUBLIC_KEY']);
|
||||||
|
$keyInfo = openssl_pkey_get_details(openssl_pkey_get_public($publicKey));
|
||||||
|
|
||||||
|
return new JsonContent(['keys' => [
|
||||||
|
[
|
||||||
|
'kty' => 'RSA',
|
||||||
|
'alg' => 'RS256',
|
||||||
|
'use' => 'sig',
|
||||||
|
'kid' => '1',
|
||||||
|
'n' => str_replace(['+', '/'], ['-', '_'], base64_encode($keyInfo['rsa']['n'])),
|
||||||
|
'e' => str_replace(['+', '/'], ['-', '_'], base64_encode($keyInfo['rsa']['e'])),
|
||||||
|
]
|
||||||
|
]]);
|
||||||
|
}
|
||||||
|
|
||||||
|
private function getUserInfoInternal(User $user, array $scope): array
|
||||||
|
{
|
||||||
|
$userInfo = [];
|
||||||
|
if (in_array('openid', $scope)) {
|
||||||
|
$userInfo['sub'] = $user->getId();
|
||||||
|
}
|
||||||
|
if (in_array('email', $scope)) {
|
||||||
|
$userInfo['email'] = $user->getEmail();
|
||||||
|
}
|
||||||
|
if (in_array('profile', $scope)) {
|
||||||
|
if ($user->getUsername() !== null) {
|
||||||
|
$userInfo['preferred_username'] = $user->getUsername();
|
||||||
|
}
|
||||||
|
$userInfo['name'] = $user->getFullName();
|
||||||
|
$userInfo['nickname'] = $user->getNickname();
|
||||||
|
$userInfo['phone_number'] = $user->getPhone();
|
||||||
|
$userInfo['id_number'] = $user->getIdNumber();
|
||||||
|
}
|
||||||
|
return $userInfo;
|
||||||
|
}
|
||||||
|
}
|
@ -1,129 +0,0 @@
|
|||||||
<?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_payload', [
|
|
||||||
'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()
|
|
||||||
{
|
|
||||||
$oAuthPayload = $this->request->session()->get('oauth_payload');
|
|
||||||
if ($oAuthPayload === null) {
|
|
||||||
return new HtmlContent('oauth/oauth_error', ['error' => 'An invalid request was made. Please start authentication again.']);
|
|
||||||
}
|
|
||||||
|
|
||||||
$this->request->session()->delete('oauth_payload');
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @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($oAuthPayload['nonce']);
|
|
||||||
$token->setUser($user);
|
|
||||||
$token->setCode($code);
|
|
||||||
$token->setCreatedDate(new DateTime());
|
|
||||||
$token->setExpiresDate(new DateTime('+5 minutes'));
|
|
||||||
$this->pdm->saveToDb($token);
|
|
||||||
|
|
||||||
$redirectUri = $oAuthPayload['redirect_uri'];
|
|
||||||
$additionalUriParams = [
|
|
||||||
'state' => $oAuthPayload['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->post('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(),
|
|
||||||
'username' => $user->getUsername(),
|
|
||||||
'full_name' => $user->getFullName(),
|
|
||||||
'nickname' => $user->getNickname(),
|
|
||||||
'phone' => $user->getPhone(),
|
|
||||||
'id_number' => $user->getIdNumber()
|
|
||||||
];
|
|
||||||
$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]);
|
|
||||||
}
|
|
||||||
}
|
|
@ -7,10 +7,14 @@ class OAuthToken extends Model
|
|||||||
{
|
{
|
||||||
protected static string $table = 'oauth_tokens';
|
protected static string $table = 'oauth_tokens';
|
||||||
|
|
||||||
protected static array $fields = ['nonce', 'user_id', 'code', 'created', 'expires'];
|
protected static array $fields = ['scope', 'nonce', 'user_id', 'code', 'access_token', 'created', 'expires'];
|
||||||
|
|
||||||
protected static array $relations = ['user' => User::class];
|
protected static array $relations = ['user' => User::class];
|
||||||
|
|
||||||
|
private static array $possibleScopeValues = ['openid', 'email', 'profile'];
|
||||||
|
|
||||||
|
private array $scope = [];
|
||||||
|
|
||||||
private string $nonce = '';
|
private string $nonce = '';
|
||||||
|
|
||||||
private ?User $user = null;
|
private ?User $user = null;
|
||||||
@ -19,10 +23,22 @@ class OAuthToken extends Model
|
|||||||
|
|
||||||
private string $code = '';
|
private string $code = '';
|
||||||
|
|
||||||
|
private string $accessToken = '';
|
||||||
|
|
||||||
private DateTime $created;
|
private DateTime $created;
|
||||||
|
|
||||||
private DateTime $expires;
|
private DateTime $expires;
|
||||||
|
|
||||||
|
public function setScopeArray(array $scope): void
|
||||||
|
{
|
||||||
|
$this->scope = array_intersect($scope, self::$possibleScopeValues);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function setScope(string $scope): void
|
||||||
|
{
|
||||||
|
$this->setScopeArray(explode(' ', $scope));
|
||||||
|
}
|
||||||
|
|
||||||
public function setNonce(string $nonce): void
|
public function setNonce(string $nonce): void
|
||||||
{
|
{
|
||||||
$this->nonce = $nonce;
|
$this->nonce = $nonce;
|
||||||
@ -43,6 +59,11 @@ class OAuthToken extends Model
|
|||||||
$this->code = $code;
|
$this->code = $code;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function setAccessToken(string $accessToken): void
|
||||||
|
{
|
||||||
|
$this->accessToken = $accessToken;
|
||||||
|
}
|
||||||
|
|
||||||
public function setCreatedDate(DateTime $created): void
|
public function setCreatedDate(DateTime $created): void
|
||||||
{
|
{
|
||||||
$this->created = $created;
|
$this->created = $created;
|
||||||
@ -63,6 +84,16 @@ class OAuthToken extends Model
|
|||||||
$this->expires = new DateTime($expires);
|
$this->expires = new DateTime($expires);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function getScope(): string
|
||||||
|
{
|
||||||
|
return implode(' ', $this->scope);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getScopeArray(): array
|
||||||
|
{
|
||||||
|
return $this->scope;
|
||||||
|
}
|
||||||
|
|
||||||
public function getNonce(): string
|
public function getNonce(): string
|
||||||
{
|
{
|
||||||
return $this->nonce;
|
return $this->nonce;
|
||||||
@ -83,6 +114,11 @@ class OAuthToken extends Model
|
|||||||
return $this->code;
|
return $this->code;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function getAccessToken(): string
|
||||||
|
{
|
||||||
|
return $this->accessToken;
|
||||||
|
}
|
||||||
|
|
||||||
public function getCreatedDate(): DateTime
|
public function getCreatedDate(): DateTime
|
||||||
{
|
{
|
||||||
return $this->created;
|
return $this->created;
|
||||||
|
@ -28,6 +28,14 @@ class OAuthTokenRepository
|
|||||||
return $this->pdm->selectFromDb($select, OAuthToken::class);
|
return $this->pdm->selectFromDb($select, OAuthToken::class);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function getByAccessToken(string $accessToken): ?OAuthToken
|
||||||
|
{
|
||||||
|
$select = new Select(\Container::$dbConnection);
|
||||||
|
$select->where('access_token', '=', $accessToken);
|
||||||
|
|
||||||
|
return $this->pdm->selectFromDb($select, OAuthToken::class);
|
||||||
|
}
|
||||||
|
|
||||||
public function getAllExpired(): Generator
|
public function getAllExpired(): Generator
|
||||||
{
|
{
|
||||||
$select = new Select(\Container::$dbConnection);
|
$select = new Select(\Container::$dbConnection);
|
||||||
|
9
web.php
9
web.php
@ -21,10 +21,11 @@ Container::$routeCollection->group('login', function (SokoWeb\Routing\RouteColle
|
|||||||
$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) {
|
Container::$routeCollection->group('oauth', function (SokoWeb\Routing\RouteCollection $routeCollection) {
|
||||||
$routeCollection->get('oauth-start', 'start', [RVR\Controller\OAuthLoginController::class, 'startOauth']);
|
$routeCollection->get('oauth-auth', 'auth', [RVR\Controller\OAuthAuthController::class, 'auth']);
|
||||||
$routeCollection->get('oauth-finish', 'finish', [RVR\Controller\OAuthLoginController::class, 'finishOauth']);
|
$routeCollection->post('oauth-token', 'token', [RVR\Controller\OAuthController::class, 'getToken']);
|
||||||
$routeCollection->post('oauth-token', 'token', [RVR\Controller\OAuthLoginController::class, 'getToken']);
|
$routeCollection->get('oauth-userinfo', 'userinfo', [RVR\Controller\OAuthController::class, 'getUserInfo']);
|
||||||
$routeCollection->get('oauth-jwtPublicKey', 'jwtPublicKey', [RVR\Controller\OAuthLoginController::class, 'getJwtPublicKey']);
|
$routeCollection->get('oauth-config', '.well-known/openid-configuration', [RVR\Controller\OAuthController::class, 'getConfig']);
|
||||||
|
$routeCollection->get('oauth-certs', 'certs', [RVR\Controller\OAuthController::class, 'getCerts']);
|
||||||
});
|
});
|
||||||
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']);
|
||||||
|
Loading…
Reference in New Issue
Block a user