Version 4.5.0

This commit is contained in:
Neo committed 2025-12-19 05:51:58 -08:00
1 parent 1a0c7fd3c2
commit f79dcf067a
3791 files changed
+248032 -76372

No files matched your search

+155 -46
View File
@@ -7,8 +7,7 @@
* @package Invision Community
* @since 29 Apr 2017
*/
define('REPORT_EXCEPTIONS', TRUE);
\define('REPORT_EXCEPTIONS', TRUE);
require '../../init.php';
class oAuthServerAuthorizationRequest
@@ -43,15 +42,27 @@ class oAuthServerAuthorizationRequest
*/
protected $scope = array();
/**
* @brief Code Challenge
*/
protected $codeChallenge;
/**
* @brief Code Challenge Method
*/
protected $codeChallengeMethod;
/**
* Init
*
* @param string $clientId Client ID
* @param string $redirectUri Redirect URI, if provided
* @param string|NULL $state The state, if provided
* @param string $clientId Client ID
* @param string $redirectUri Redirect URI, if provided
* @param string|NULL $state The state, if provided
* @param string|NULL $codeChallenge The code challenge, if provided
* @param string|NULL $codeChallengeMethod The code challenge method, if provided
* @return void
*/
public static function init( $clientId, $redirectUri = NULL, $state = NULL )
public static function init( $clientId, $redirectUri = NULL, $state = NULL, $codeChallenge = NULL, $codeChallengeMethod = NULL )
{
$obj = new static;
@@ -71,9 +82,15 @@ class oAuthServerAuthorizationRequest
/* Set the Redirect URI */
$allowedRedirectUris = json_decode( $obj->client->redirect_uris );
if( \defined('\IPS\DEBUG_OAUTH_REDIRECTS') )
{
$allowedRedirectUris = array_merge( $allowedRedirectUris, \IPS\DEBUG_OAUTH_REDIRECTS );
}
if ( $redirectUri )
{
if ( !in_array( $redirectUri, $allowedRedirectUris ) )
if ( !\in_array( $redirectUri, $allowedRedirectUris ) )
{
throw new \IPS\Login\Handler\OAuth2\InitException('oauth_err_invalid_redirect_uri');
}
@@ -82,7 +99,7 @@ class oAuthServerAuthorizationRequest
$obj->redirectUri = \IPS\Http\Url::external( $redirectUri );
}
}
elseif ( count( $allowedRedirectUris ) === 1 )
elseif ( \count( $allowedRedirectUris ) === 1 )
{
$obj->redirectUri = \IPS\Http\Url::external( array_shift( $allowedRedirectUris ) );
}
@@ -98,9 +115,30 @@ class oAuthServerAuthorizationRequest
$obj->state = $state;
}
/* Set code challenge and method if applicable */
if ( $codeChallenge )
{
$obj->codeChallenge = $codeChallenge;
$obj->codeChallengeMethod = $codeChallengeMethod;
}
return $obj;
}
/**
* Validate the request is valid
*
* @return void
* @throws \IPS\Login\Handler\OAuth2\Exception
*/
public function validate()
{
if ( ( $this->client->pkce !== 'none' and !$this->codeChallenge ) or ( $this->client->pkce === 'S256' and $this->codeChallengeMethod !== 'S256' ) )
{
throw new \IPS\Login\Handler\OAuth2\Exception( 'invalid_request', $this->codeChallenge ? "transform algorithm not supported" : "code challenge required" );
}
}
/**
* Set the response type
*
@@ -111,14 +149,14 @@ class oAuthServerAuthorizationRequest
{
if ( $responseType === 'code' )
{
if ( !in_array( 'authorization_code', explode( ',', $this->client->grant_types ) ) )
if ( !\in_array( 'authorization_code', explode( ',', $this->client->grant_types ) ) )
{
throw new \IPS\Login\Handler\OAuth2\Exception('unsupported_response_type');
}
}
elseif ( $responseType === 'token' )
{
if ( !in_array( 'implicit', explode( ',', $this->client->grant_types ) ) )
if ( !\in_array( 'implicit', explode( ',', $this->client->grant_types ) ) )
{
throw new \IPS\Login\Handler\OAuth2\Exception('unsupported_response_type');
}
@@ -154,13 +192,14 @@ class oAuthServerAuthorizationRequest
/**
* Get URL to redirect the user back to the client after successful authorization
*
* @param \IPS\Member $member The member
* @param array $scopes The authorized scopes
* @param \IPS\Member $member The member
* @param array $scopes The authorized scopes
* @return void
*/
public function authorized( \IPS\Member $member, $scopes )
{
$scopes = $this->client->choose_scopes ? $scopes : $this->scope;
$device = \IPS\Member\Device::loadOrCreate( $member );
if ( $this->responseType === 'code' )
{
@@ -171,19 +210,23 @@ class oAuthServerAuthorizationRequest
while ( \IPS\Db::i()->select( 'COUNT(*)', 'core_oauth_server_authorization_codes', array( 'client_id=? AND code=?', $this->client->client_id, $authorizationCode ) )->first() );
\IPS\Db::i()->insert( 'core_oauth_server_authorization_codes', array(
'client_id' => $this->client->client_id,
'redirect_uri' => $this->providedRedirectUri ?: NULL,
'member_id' => $member->member_id,
'expires' => time() + 60,
'code' => $authorizationCode,
'scope' => $scopes ? json_encode( $scopes ) : NULL
'client_id' => $this->client->client_id,
'redirect_uri' => $this->providedRedirectUri ?: NULL,
'member_id' => $member->member_id,
'expires' => time() + 60,
'code' => $authorizationCode,
'scope' => $scopes ? json_encode( $scopes ) : NULL,
'code_challenge' => $this->codeChallenge,
'code_challenge_method' => $this->codeChallengeMethod,
'user_agent' => isset( $_SERVER['HTTP_USER_AGENT'] ) ? $_SERVER['HTTP_USER_AGENT'] : NULL,
'device_key' => $device ? $device->device_key : NULL
) );
return $this->redirect( array( 'code' => $authorizationCode ) );
}
else
{
$accessToken = $this->client->generateAccessToken( $member, $scopes, 'implicit', TRUE );
$accessToken = $this->client->generateAccessToken( $member, $scopes, 'implicit', TRUE, NULL, isset( $_SERVER['HTTP_USER_AGENT'] ) ? $_SERVER['HTTP_USER_AGENT'] : NULL, isset( $_SERVER['HTTP_USER_AGENT'] ) ? $_SERVER['HTTP_USER_AGENT'] : NULL, $device );
$response = array( 'access_token' => $accessToken['access_token'], 'token_type' => 'bearer' );
if ( $accessToken['access_token_expires'] )
@@ -232,6 +275,12 @@ class oAuthServerAuthorizationRequest
return TRUE;
}
/* If we're banned or validating, we'll show those screens instead */
if ( \IPS\Member::loggedIn()->isBanned() or \IPS\Member::loggedIn()->members_bitoptions['validating'] )
{
return TRUE;
}
/* Have we gone through it already? */
if ( isset( \IPS\Request::i()->allow ) and \IPS\Login::compareHashes( (string) \IPS\Session::i()->csrfKey, (string) \IPS\Request::i()->csrfKey ) )
{
@@ -243,7 +292,7 @@ class oAuthServerAuthorizationRequest
}
/* Does the client require it? */
if ( $this->client->prompt !== 'automatic' )
if ( !\in_array( $this->client->prompt, array( 'none', 'automatic' ) ) )
{
return TRUE;
}
@@ -253,15 +302,21 @@ class oAuthServerAuthorizationRequest
{
return TRUE;
}
/* Are we always bypassing? */
if ( $this->client->prompt === 'none' )
{
return FALSE;
}
/* Do we already have an access token with these scopes? */
$accessToken = $this->client->getAccessToken( \IPS\Member::loggedIn(), $this->scope );
if ( $accessToken )
{
\IPS\Request::i()->grantedScope = array_combine( json_decode( $accessToken['scope'], TRUE ), array_fill( 0, count( json_decode( $accessToken['scope'], TRUE ) ), TRUE ) );
\IPS\Request::i()->grantedScope = $accessToken['scope'] ? array_combine( json_decode( $accessToken['scope'], TRUE ), array_fill( 0, \count( json_decode( $accessToken['scope'], TRUE ) ), TRUE ) ) : array();
return FALSE;
}
/* No? We need a new token */
return TRUE;
}
@@ -269,12 +324,23 @@ class oAuthServerAuthorizationRequest
/**
* Show authorization form
*
* @param string $requestedPromptType Requested prompt type, if provided
* @param bool $loggedIn Has the user logged in?
* @param string $requestedPromptType Requested prompt type, if provided
* @param bool $loggedIn Has the user logged in?
* @return void
*/
public function prompt( $requestedPromptType, $loggedIn )
{
/* If we're banned or validating, we'll show those screens instead */
if ( \IPS\Member::loggedIn()->isBanned() )
{
\IPS\Output::i()->showBanned();
exit;
}
elseif ( \IPS\Member::loggedIn()->members_bitoptions['validating'] )
{
\IPS\Output::i()->redirect( \IPS\Http\Url::internal( 'app=core&module=system&controller=register&do=validating', 'front', 'register' ) );
}
/* We mustn't have the redirect_uri in the URL when displaying the page as this needs to be handled securely (it will
probably include a client-issued CSRF key) and if we use it in the URL, any third party scripts that may be being
used on the community (tracking or advertisements, for example) will have access to it - this also makes the URI
@@ -285,17 +351,28 @@ class oAuthServerAuthorizationRequest
\IPS\Request::i()->setCookie( 'oauth_authorize', $key );
\IPS\Db::i()->insert( 'core_oauth_authorize_prompts', array(
'session_id' => $key,
'client_id' => $this->client->client_id,
'response_type' => $this->responseType,
'redirect_uri' => $this->providedRedirectUri ?: NULL,
'scope' => implode( ' ', $this->scope ),
'state' => $this->state,
'timestamp' => time(),
'logged_in' => FALSE
'session_id' => $key,
'client_id' => $this->client->client_id,
'response_type' => $this->responseType,
'redirect_uri' => $this->providedRedirectUri ?: NULL,
'scope' => implode( ' ', $this->scope ),
'state' => $this->state,
'timestamp' => time(),
'logged_in' => FALSE,
'prompt' => \in_array( $requestedPromptType, array( 'login', 'reauthorize' ) ) ? $requestedPromptType : NULL,
'code_challenge' => $this->codeChallenge,
'code_challenge_method' => $this->codeChallengeMethod
), TRUE );
\IPS\Output::i()->redirect( \IPS\Http\Url::internal( 'oauth/authorize/', 'interface' ) );
$url = \IPS\Http\Url::internal( 'oauth/authorize/', 'interface' );
if ( isset( \IPS\Request::i()->_processLogin ) ) // This is if they clicked a social sign in button on the registration form throwing them back to here
{
$url = $url->setQueryString( array(
'_processLogin' => \IPS\Request::i()->_processLogin,
'csrfKey' => \IPS\Request::i()->csrfKey,
) );
}
\IPS\Output::i()->redirect( $url );
}
/* Construct the URL for this page */
@@ -320,7 +397,7 @@ class oAuthServerAuthorizationRequest
{
if ( $success = $login->authenticate() )
{
\IPS\Db::i()->update( 'core_oauth_authorize_prompts', array( 'logged_in' => TRUE ), array( 'session_id=?', \IPS\Request::i()->cookie['oauth_authorize'] ) );
\IPS\Db::i()->update( 'core_oauth_authorize_prompts', array( 'logged_in' => TRUE, 'prompt' => NULL ), array( 'session_id=?', \IPS\Request::i()->cookie['oauth_authorize'] ) );
if ( $success->mfa() )
{
@@ -367,9 +444,8 @@ class oAuthServerAuthorizationRequest
\IPS\Output::i()->title = \IPS\Member::loggedIn()->language()->addToStack( 'oauth_authorize', FALSE, array( 'sprintf' => array( \IPS\Settings::i()->board_name ) ) );
\IPS\Output::i()->httpHeaders['X-Frame-Options'] = 'DENY';
/* Check we are not IP banned */
$ipBanned = \IPS\Request::i()->ipAddressIsBanned();
if ( $ipBanned )
/* Check we are not banned */
if ( \IPS\Request::i()->ipAddressIsBanned() or \IPS\Member::loggedIn()->isBanned() )
{
\IPS\Output::i()->showBanned();
}
@@ -379,7 +455,7 @@ try
{
/* Get our params */
$loggedIn = FALSE;
if ( !isset( \IPS\Request::i()->client_id ) )
if ( !isset( \IPS\Request::i()->client_id ) and isset( \IPS\Request::i()->cookie['oauth_authorize'] ) )
{
try
{
@@ -390,6 +466,15 @@ try
$scope = $row['scope'];
$state = $row['state'];
$loggedIn = $row['logged_in'];
$prompt = $row['prompt'];
$codeChallenge = $row['code_challenge'];
$codeChallengeMethod = $row['code_challenge_method'];
if ( isset( \IPS\Request::i()->prompt ) and \in_array( \IPS\Request::i()->prompt, array( 'login', 'reauthorize' ) ) )
{
\IPS\Db::i()->update( 'core_oauth_authorize_prompts', array( 'prompt' => \IPS\Request::i()->prompt ), array( 'session_id=?', \IPS\Request::i()->cookie['oauth_authorize'] ) );
$prompt = \IPS\Request::i()->prompt;
}
}
catch ( \UnderflowException $e )
{
@@ -403,10 +488,31 @@ try
$redirectUri = \IPS\Request::i()->redirect_uri;
$scope = \IPS\Request::i()->scope;
$state = \IPS\Request::i()->state;
$prompt = \IPS\Request::i()->prompt;
$codeChallenge = isset( \IPS\Request::i()->code_challenge ) ? \IPS\Request::i()->code_challenge : NULL;
$codeChallengeMethod = ( isset( \IPS\Request::i()->code_challenge_method ) and \in_array( \IPS\Request::i()->code_challenge_method, array( 'plain', 'S256' ) ) ) ? \IPS\Request::i()->code_challenge_method : NULL;
}
/* Have we asked to register? */
if ( isset( \IPS\Request::i()->register ) )
{
/* The authorize prompt data will probably expire before we're done, so put the referal URL (for after registration)
to the full URL which will initiate a new prompt. But don't delete the current prompt data in case the user hits back */
$url = \IPS\Http\Url::internal( 'oauth/authorize/', 'interface' )->setQueryString( array(
'client_id' => $clientId,
'response_type' => $responseType,
'redirect_uri' => $redirectUri,
'scope' => $scope,
'state' => $state,
'prompt' => ( $prompt === 'login' ) ? 'reauthorize' : $prompt, // We never need to log in immediately after registering, that's confusing
) );
\IPS\Output::i()->redirect( \IPS\Http\Url::internal( 'app=core&module=system&controller=register', 'front', 'register' )->addRef( (string) $url )->setQueryString( 'oauth', 1 ) );
exit;
}
/* Init, validating client_id and redirect_uri */
$request = oAuthServerAuthorizationRequest::init( $clientId, $redirectUri, $state );
$request = oAuthServerAuthorizationRequest::init( $clientId, $redirectUri, $state, $codeChallenge, $codeChallengeMethod );
$request->validate();
/* If site is offline, return temporarily_unavailable */
if ( ( isset( \IPS\Settings::i()->setup_in_progress ) AND \IPS\Settings::i()->setup_in_progress ) or !\IPS\Settings::i()->site_online )
@@ -426,17 +532,20 @@ try
{
$request->setScope( $scope );
}
/* Do we need them to be prompted? */
$authorizedUrl = NULL;
if ( $request->promptRequired( \IPS\Request::i()->prompt ) )
if ( $request->promptRequired( $prompt ) )
{
$request->prompt( \IPS\Request::i()->prompt, $loggedIn );
$request->prompt( $prompt, $loggedIn );
}
/* Still here? Go ahead */
\IPS\Db::i()->delete( 'core_oauth_authorize_prompts', array( 'session_id=?', \IPS\Request::i()->cookie['oauth_authorize'] ) );
\IPS\Request::i()->setCookie( 'oauth_authorize', NULL );
if ( isset( \IPS\Request::i()->cookie['oauth_authorize'] ) )
{
\IPS\Db::i()->delete( 'core_oauth_authorize_prompts', array( 'session_id=?', \IPS\Request::i()->cookie['oauth_authorize'] ) );
\IPS\Request::i()->setCookie( 'oauth_authorize', NULL );
}
\IPS\Output::i()->redirect( $request->authorized( \IPS\Member::loggedIn(), isset( \IPS\Request::i()->grantedScope ) ? array_keys( \IPS\Request::i()->grantedScope ) : array() ), NULL, 302 );
}
catch ( \IPS\Login\Handler\OAuth2\InitException $e )
+8 -3
View File
@@ -7,12 +7,11 @@
* @package Invision Community
* @since 31 May 2017
*/
define('REPORT_EXCEPTIONS', TRUE);
\define('REPORT_EXCEPTIONS', TRUE);
require '../../init.php';
\IPS\Session\Front::i();
if ( isset( \IPS\Request::i()->state ) and $explodedData = explode( '-', \IPS\Request::i()->state ) and count( $explodedData ) === 4 and $destination = @base64_decode( $explodedData[1] ) )
if ( isset( \IPS\Request::i()->state ) and $explodedData = explode( '-', \IPS\Request::i()->state ) and \count( $explodedData ) === 4 and $destination = @base64_decode( $explodedData[1] ) )
{
try
{
@@ -61,6 +60,12 @@ if ( isset( \IPS\Request::i()->state ) and $explodedData = explode( '-', \IPS\Re
}
elseif ( isset( \IPS\Request::i()->code ) )
{
/* Sign in with Apple does not make name available any later in the process */
if ( isset( \IPS\Request::i()->user ) )
{
$_SESSION['oauth_user'] = \IPS\Request::i()->user;
}
$destination = $destination->setQueryString( 'code', \IPS\Request::i()->code );
}
View File
Whitespace-only changes.
+62 -15
View File
@@ -7,8 +7,7 @@
* @package Invision Community
* @since 29 Apr 2017
*/
define('REPORT_EXCEPTIONS', TRUE);
\define('REPORT_EXCEPTIONS', TRUE);
require '../../init.php';
class oAuthServerTokenRequest
@@ -87,7 +86,7 @@ class oAuthServerTokenRequest
*/
public function grantType( $grantType )
{
if ( !in_array( $grantType, array( 'authorization_code', 'implicit', 'client_credentials', 'password', 'refresh_token' ) ) )
if ( !\in_array( $grantType, array( 'authorization_code', 'implicit', 'client_credentials', 'password', 'refresh_token' ) ) )
{
throw new \IPS\Login\Handler\OAuth2\Exception( 'unsupported_grant_type' );
}
@@ -99,7 +98,7 @@ class oAuthServerTokenRequest
throw new \IPS\Login\Handler\OAuth2\Exception( 'unsupported_grant_type' );
}
}
elseif ( !in_array( $grantType, explode( ',', $this->client->grant_types ) ) )
elseif ( !\in_array( $grantType, explode( ',', $this->client->grant_types ) ) )
{
throw new \IPS\Login\Handler\OAuth2\Exception( 'unauthorized_client' );
}
@@ -111,10 +110,12 @@ class oAuthServerTokenRequest
/**
* Validate Authorization Code
*
* @param string $authorizationCode The Authorization Code
* @param string $authorizationCode The Authorization Code
* @param string|NULL $redirectUri The redirect URI, if provided
* @param string|NULL $codeVerifier The code verifier, if provided
* @return array|NULL
*/
public function validateAuthorizationCode( $authorizationCode, $redirectUri = NULL )
public function validateAuthorizationCode( $authorizationCode, $redirectUri = NULL, $codeVerifier = NULL )
{
try
{
@@ -140,11 +141,45 @@ class oAuthServerTokenRequest
return;
}
/* If it has a code verifier, validate that */
if ( $authorizationCode['code_challenge'] or $this->client->pkce !== 'none' )
{
if ( !$codeVerifier or !$authorizationCode['code_challenge'] )
{
return;
}
if ( $authorizationCode['code_challenge_method'] === 'S256' or $this->client->pkce === 'S256' )
{
$codeVerifier = rtrim( strtr( base64_encode( pack( 'H*', hash( 'sha256', $codeVerifier ) ) ), '+/', '-_' ), '=' );
}
if ( !\IPS\Login::compareHashes( $authorizationCode['code_challenge'], $codeVerifier ) )
{
return;
}
}
/* Check we're not banned and not validating */
$member = \IPS\Member::load( $authorizationCode['member_id'] );
if ( $member->isBanned() or $member->members_bitoptions['validating'] )
{
return;
}
/* Mark it used */
\IPS\Db::i()->update( 'core_oauth_server_authorization_codes', array( 'used' => 1 ), array( 'client_id=? AND code=?', $authorizationCode['client_id'], $authorizationCode['code'] ) );
/* Return access token */
return $this->client->generateAccessToken( \IPS\Member::load( $authorizationCode['member_id'] ), $authorizationCode['scope'] ? json_decode( $authorizationCode['scope'] ) : NULL, 'authorization_code', FALSE, $authorizationCode['code'] );
try
{
$device = $authorizationCode['device_key'] ? \IPS\Member\Device::load( $authorizationCode['device_key'] ) : NULL;
}
catch ( \UnderflowException $e )
{
$device = NULL;
}
return $this->client->generateAccessToken( $member, $authorizationCode['scope'] ? json_decode( $authorizationCode['scope'] ) : NULL, 'authorization_code', FALSE, $authorizationCode['code'], $authorizationCode['user_agent'], isset( $_SERVER['HTTP_USER_AGENT'] ) ? $_SERVER['HTTP_USER_AGENT'] : NULL, $device );
}
catch ( \UnderflowException $e )
{
@@ -156,7 +191,7 @@ class oAuthServerTokenRequest
* Validate Password
*
* @param string $username Username
* @param string $password Password
* @param object $password The plaintext password provided by the user, wrapped in an object that can be cast to a string so it doesn't show in any logs
* @param array|null $scope Scopes
* @return array|NULL
*/
@@ -175,7 +210,10 @@ class oAuthServerTokenRequest
$member = $method->authenticateUsernamePassword( $login, $username, $password );
\IPS\Login::checkIfAccountIsLocked( $member, TRUE );
$accessToken = $this->client->generateAccessToken( $member, $scope, 'password' );
if ( !$member->isBanned() and !$member->members_bitoptions['validating'] )
{
$accessToken = $this->client->generateAccessToken( $member, $scope, 'password', FALSE, NULL, isset( $_SERVER['HTTP_USER_AGENT'] ) ? $_SERVER['HTTP_USER_AGENT'] : NULL, isset( $_SERVER['HTTP_USER_AGENT'] ) ? $_SERVER['HTTP_USER_AGENT'] : NULL, NULL );
}
break;
}
catch ( \IPS\Login\Exception $e )
@@ -192,7 +230,7 @@ class oAuthServerTokenRequest
{
if ( !$member or $failedMember->member_id != $failedMember->member_id )
{
$failedLogins = is_array( $failedMember->failed_logins ) ? $failedMember->failed_logins : array();
$failedLogins = \is_array( $failedMember->failed_logins ) ? $failedMember->failed_logins : array();
$failedLogins[ \IPS\Request::i()->ipAddress() ][] = time();
$failedMember->failed_logins = $failedLogins;
$failedMember->save();
@@ -212,7 +250,7 @@ class oAuthServerTokenRequest
{
if ( $this->client->client_secret )
{
return $this->client->generateAccessToken( NULL, $scope, 'client_credentials', TRUE );
return $this->client->generateAccessToken( NULL, $scope, 'client_credentials', TRUE, NULL, NULL, isset( $_SERVER['HTTP_USER_AGENT'] ) ? $_SERVER['HTTP_USER_AGENT'] : NULL );
}
}
@@ -232,7 +270,7 @@ class oAuthServerTokenRequest
if ( $accessToken['member_id'] )
{
$member = \IPS\Member::load( $accessToken['member_id'] );
if ( !$member->member_id )
if ( !$member->member_id or $member->isBanned() or $member->members_bitoptions['validating'] )
{
return;
}
@@ -241,7 +279,16 @@ class oAuthServerTokenRequest
$originalScope = $accessToken['scope'] ? json_decode( $accessToken['scope'], TRUE ) : array();
$scope = $newScope ? array_intersect( $originalScope, $newScope ) : $originalScope;
return $this->client->generateAccessToken( $member, $scope, 'refresh_token', TRUE );
try
{
$device = $accessToken['device_key'] ? \IPS\Member\Device::load( $accessToken['device_key'] ) : NULL;
}
catch ( \UnderflowException $e )
{
$device = NULL;
}
return $this->client->generateAccessToken( $member, $scope, 'refresh_token', TRUE, NULL, $accessToken['auth_user_agent'], isset( $_SERVER['HTTP_USER_AGENT'] ) ? $_SERVER['HTTP_USER_AGENT'] : NULL, $device, $accessToken );
}
}
}
@@ -305,10 +352,10 @@ try
switch ( $request->grantType( \IPS\Request::i()->grant_type ) )
{
case 'authorization_code':
$accessToken = $request->validateAuthorizationCode( \IPS\Request::i()->code, \IPS\Request::i()->redirect_uri );
$accessToken = $request->validateAuthorizationCode( \IPS\Request::i()->code, \IPS\Request::i()->redirect_uri, isset( \IPS\Request::i()->code_verifier ) ? \IPS\Request::i()->code_verifier : NULL );
break;
case 'password':
$accessToken = $request->validatePassword( \IPS\Request::i()->username, \IPS\Request::i()->password, isset( \IPS\Request::i()->scope ) ? explode( ' ', \IPS\Request::i()->scope ) : NULL );
$accessToken = $request->validatePassword( \IPS\Request::i()->username, \IPS\Request::i()->protect('password'), isset( \IPS\Request::i()->scope ) ? explode( ' ', \IPS\Request::i()->scope ) : NULL );
break;
case 'client_credentials':
$accessToken = $request->validateClientCredentials( isset( \IPS\Request::i()->scope ) ? explode( ' ', \IPS\Request::i()->scope ) : NULL );