Version 5.0.13

This commit is contained in:
Neo committed 2025-12-19 19:04:57 -08:00
1 parent b89858b2ff
commit 5efe744c5f
1407 files changed
+69690 -30177

No files matched your search

+3 -2
View File
@@ -174,6 +174,7 @@ class Custom extends OAuth2
$return['authorization_endpoint'] = (string) $return['authorization_endpoint'];
$return['token_endpoint'] = (string) $return['token_endpoint'];
$return['user_endpoint'] = (string) $return['user_endpoint'];
$return['oauth_authorization_endpoint'] = (string) $return['oauth_authorization_endpoint'];
return $return;
}
@@ -369,7 +370,7 @@ class Custom extends OAuth2
{
if ( isset( $this->settings['photo_field'] ) and $this->settings['photo_field'] )
{
if ( !( $link = $this->_link( $member ) ) or ( $link['token_expires'] and $link['token_expires'] < time() ) )
if ( !( $link = $this->_link( $member ) ) or ( $link['token_expires'] and $link['token_expires'] < time() ) OR empty( $link['token_access_token'] ) )
{
throw new Exception( "", Exception::INTERNAL_ERROR );
}
@@ -395,7 +396,7 @@ class Custom extends OAuth2
*/
public function userProfileName( Member $member ): ?string
{
if ( !( $link = $this->_link( $member ) ) or ( $link['token_expires'] and $link['token_expires'] < time() ) )
if ( !( $link = $this->_link( $member ) ) or ( $link['token_expires'] and $link['token_expires'] < time() ) OR empty( $link['token_access_token'] ) )
{
throw new Exception( "", Exception::INTERNAL_ERROR );
}
+37 -11
View File
@@ -49,6 +49,16 @@ class Facebook extends OAuth2
{
return 'login_handler_Facebook';
}
/**
* Can this handler sync profile photos?
*
* @return bool
*/
public function canSyncProfilePhoto() : bool
{
return true;
}
/**
* ACP Settings Form
@@ -75,6 +85,15 @@ class Facebook extends OAuth2
1 => array( 'login_update_name_changes_inc_optional' ),
)
), NULL, NULL, NULL, 'login_real_name' ),
'real_photo' => new Radio( 'login_real_photo', $this->settings['real_photo'] ?? 1, false, array(
'options' => array(
1 => 'login_real_photo_facebook',
0 => 'login_real_photo_disabled'
),
'toggles' => array(
1 => array( 'login_update_photo_changes_inc_optional' )
)
) )
),
parent::acpForm(),
array()
@@ -310,17 +329,21 @@ class Facebook extends OAuth2
*/
public function userProfilePhoto( Member $member ): ?Url
{
if ( !( $link = $this->_link( $member ) ) or ( $link['token_expires'] and $link['token_expires'] < time() ) )
if ( !( $link = $this->_link( $member ) ) or ( $link['token_expires'] and $link['token_expires'] < time() ) OR empty( $link['token_access_token'] ) )
{
throw new LoginException( "", LoginException::INTERNAL_ERROR );
}
$photoVars = explode( ':', $member->group['g_photo_max_vars'] );
$response = $this->_authorizedRequest( "{$link['token_identifier']}/picture?width={$photoVars[1]}&redirect=false", $link['token_access_token'], NULL, 'get' );
if ( !$response['data']['is_silhouette'] and isset( $response['data']['url'] ) and $response['data']['url'] )
{
return Url::external( $response['data']['url'] );
}
if ( isset( $this->settings['real_photo'] ) and $this->settings['real_photo'] )
{
$photoVars = explode( ':', $member->group['g_photo_max_vars'] );
$response = $this->_authorizedRequest( "{$link['token_identifier']}/picture?width={$photoVars[1]}&redirect=false", $link['token_access_token'], NULL, 'get' );
if ( !$response['data']['is_silhouette'] and isset( $response['data']['url'] ) and $response['data']['url'] )
{
return Url::external( $response['data']['url'] );
}
}
return NULL;
}
@@ -336,7 +359,7 @@ class Facebook extends OAuth2
*/
public function userProfileName( Member $member ): ?string
{
if ( !( $link = $this->_link( $member ) ) or ( $link['token_expires'] and $link['token_expires'] < time() ) )
if ( !( $link = $this->_link( $member ) ) or ( $link['token_expires'] and $link['token_expires'] < time() ) OR empty( $link['token_access_token'] ) )
{
throw new LoginException( "", LoginException::INTERNAL_ERROR );
}
@@ -365,8 +388,11 @@ class Facebook extends OAuth2
{
$return[] = 'name';
}
$return[] = 'photo';
if( isset( $this->settings['update_photo_changes'] ) and $this->settings['update_photo_changes'] == 'optional' and isset( $this->settings['real_photo'] ) and $this->settings['real_photo'] )
{
$return[] = 'photo';
}
return $return;
}
+37 -11
View File
@@ -49,6 +49,16 @@ class Google extends OAuth2
}
protected static bool $enableAcpLoginByDefault = FALSE;
/**
* Can this handler sync profile photos?
*
* @return bool
*/
public function canSyncProfilePhoto() : bool
{
return true;
}
/**
* ACP Settings Form
@@ -73,7 +83,16 @@ class Google extends OAuth2
'toggles' => array(
1 => array( 'login_update_name_changes_inc_optional' ),
)
), NULL, NULL, NULL, 'login_real_name' )
), NULL, NULL, NULL, 'login_real_name' ),
'real_photo' => new Radio( 'login_real_photo', $this->settings['real_photo'] ?? 1, false, array(
'options' => array(
1 => 'login_real_photo_google',
0 => 'login_real_photo_disabled'
),
'toggles' => array(
1 => array( 'login_update_photo_changes_inc_optional' )
)
) )
),
parent::acpForm()
);
@@ -280,16 +299,20 @@ class Google extends OAuth2
*/
public function userProfilePhoto( Member $member ): ?Url
{
if ( !( $link = $this->_link( $member ) ) or ( $link['token_expires'] and $link['token_expires'] < time() ) )
if ( !( $link = $this->_link( $member ) ) or ( $link['token_expires'] and $link['token_expires'] < time() ) OR empty( $link['token_access_token'] ) )
{
throw new Exception( "", Exception::INTERNAL_ERROR );
}
$userData = $this->_userData( $link['token_access_token'] );
if ( isset( $userData['picture'] ) and $userData['picture'] )
{
return Url::external( $userData['picture'] )->setQueryString( 'sz', NULL );
}
if ( isset( $this->settings['real_photo'] ) and $this->settings['real_photo'] )
{
$userData = $this->_userData( $link['token_access_token'] );
if ( isset( $userData['picture'] ) and $userData['picture'] )
{
return Url::external( $userData['picture'] )->setQueryString( 'sz', NULL );
}
}
return NULL;
}
@@ -305,7 +328,7 @@ class Google extends OAuth2
*/
public function userProfileName( Member $member ): ?string
{
if ( !( $link = $this->_link( $member ) ) or ( $link['token_expires'] and $link['token_expires'] < time() ) )
if ( !( $link = $this->_link( $member ) ) or ( $link['token_expires'] and $link['token_expires'] < time() ) OR empty( $link['token_access_token'] ) )
{
throw new Exception( "", Exception::INTERNAL_ERROR );
}
@@ -356,8 +379,11 @@ class Google extends OAuth2
{
$return[] = 'name';
}
$return[] = 'photo';
if( isset( $this->settings['update_photo_changes'] ) and $this->settings['update_photo_changes'] == 'optional' and isset( $this->settings['real_photo'] ) and $this->settings['real_photo'] )
{
$return[] = 'photo';
}
return $return;
}
+2 -2
View File
@@ -340,7 +340,7 @@ class Invision extends OAuth2
*/
public function userProfilePhoto( Member $member ): ?Url
{
if ( !( $link = $this->_link( $member ) ) or ( $link['token_expires'] and $link['token_expires'] < time() ) )
if ( !( $link = $this->_link( $member ) ) or ( $link['token_expires'] and $link['token_expires'] < time() ) OR empty( $link['token_access_token'] ) )
{
throw new LoginException( "", LoginException::INTERNAL_ERROR );
}
@@ -365,7 +365,7 @@ class Invision extends OAuth2
*/
public function userProfileName( Member $member ): ?string
{
if ( !( $link = $this->_link( $member ) ) or ( $link['token_expires'] and $link['token_expires'] < time() ) )
if ( !( $link = $this->_link( $member ) ) or ( $link['token_expires'] and $link['token_expires'] < time() ) OR empty( $link['token_access_token'] ) )
{
throw new LoginException( "", LoginException::INTERNAL_ERROR );
}
+45 -20
View File
@@ -49,6 +49,16 @@ class LinkedIn extends OAuth2
{
return 'login_handler_Linkedin';
}
/**
* Can this handler sync profile photos?
*
* @return bool
*/
public function canSyncProfilePhoto() : bool
{
return true;
}
/**
* @brief Enable AdminCP logins by default
@@ -77,8 +87,17 @@ class LinkedIn extends OAuth2
'toggles' => array(
1 => array( 'login_update_name_changes_inc_optional' ),
)
), NULL, NULL, NULL, 'login_real_name'
) ), parent::acpForm() );
), NULL, NULL, NULL, 'login_real_name' ),
'real_photo' => new Radio( 'login_real_photo', $this->settings['real_photo'] ?? 1, false, array(
'options' => array(
1 => 'login_real_photo_linkedin',
0 => 'login_real_photo_disabled'
),
'toggles' => array(
1 => array( 'login_update_photo_changes_inc_optional' )
)
) )
), parent::acpForm() );
}
/**
@@ -272,7 +291,7 @@ class LinkedIn extends OAuth2
*/
public function userProfilePhoto( Member $member ): ?Url
{
if ( !( $link = $this->_link( $member ) ) or ( $link['token_expires'] and $link['token_expires'] < time() ) )
if ( !( $link = $this->_link( $member ) ) or ( $link['token_expires'] and $link['token_expires'] < time() ) OR empty( $link['token_access_token'] ) )
{
throw new Exception( "", Exception::INTERNAL_ERROR );
}
@@ -282,21 +301,25 @@ class LinkedIn extends OAuth2
return NULL;
}
$userData = $this->_userData( $link['token_access_token'] )['profilePicture']['displayImage~']['elements'];
if ( isset( $this->settings['real_photo'] ) and $this->settings['real_photo'] )
{
$userData = $this->_userData( $link['token_access_token'] )['profilePicture']['displayImage~']['elements'];
foreach( array_reverse( $userData ) as $_userData )
{
if ( isset( $_userData['identifiers'] ) )
{
foreach( $_userData['identifiers'] as $identifier )
{
if( isset( $identifier['identifier'] ) AND $identifier['identifier'] )
{
return Url::external( $identifier['identifier'] );
}
}
}
}
}
foreach( array_reverse( $userData ) as $_userData )
{
if ( isset( $_userData['identifiers'] ) )
{
foreach( $_userData['identifiers'] as $identifier )
{
if( isset( $identifier['identifier'] ) AND $identifier['identifier'] )
{
return Url::external( $identifier['identifier'] );
}
}
}
}
return NULL;
}
@@ -312,7 +335,7 @@ class LinkedIn extends OAuth2
*/
public function userProfileName( Member $member ): ?string
{
if ( !( $link = $this->_link( $member ) ) or ( $link['token_expires'] and $link['token_expires'] < time() ) )
if ( !( $link = $this->_link( $member ) ) or ( $link['token_expires'] and $link['token_expires'] < time() ) OR empty( $link['token_access_token'] ) )
{
throw new Exception( "", Exception::INTERNAL_ERROR );
}
@@ -370,9 +393,11 @@ class LinkedIn extends OAuth2
{
$return[] = 'name';
}
$return[] = 'photo';
if( isset( $this->settings['update_photo_changes'] ) and $this->settings['update_photo_changes'] == 'optional' and isset( $this->settings['real_photo'] ) and $this->settings['real_photo'] )
{
$return[] = 'photo';
}
return $return;
}
+1 -1
View File
@@ -236,7 +236,7 @@ class Microsoft extends OAuth2
*/
public function userProfileName( Member $member ): ?string
{
if ( !( $link = $this->_link( $member ) ) or ( $link['token_expires'] and $link['token_expires'] < time() ) )
if ( !( $link = $this->_link( $member ) ) or ( $link['token_expires'] and $link['token_expires'] < time() ) OR empty( $link['token_access_token'] ) )
{
throw new Exception( "", Exception::INTERNAL_ERROR );
}
+20 -3
View File
@@ -122,6 +122,23 @@ abstract class OAuth2 extends Handler
'optional' => 'login_update_changes_optional',
'disabled' => 'login_update_changes_no',
), 'disabled' => $emailChangesDisabled ), NULL, NULL, NULL, 'login_update_email_changes_inc_optional' );
/* If this handler supports profile photos, add options for that */
if( $this->canSyncProfilePhoto() )
{
$photoChangesDisabled = array();
if( $forcePhotoHandler = static::handlerHasForceSync( 'photo', $this ) )
{
$photoChangesDisabled[] = 'force';
Member::loggedIn()->language()->words['login_update_changes_yes_photo_desc'] = Member::loggedIn()->language()->addToStack( 'login_update_changes_yes_disabled', FALSE, array( 'sprintf' => $forcePhotoHandler->_title ) );
}
$return['update_photo_changes'] = new Radio( 'login_update_photo_changes', $this->settings['update_photo_changes'] ?? 'optional', FALSE, array( 'options' => array(
'force' => 'login_update_changes_yes_photo',
'optional' => 'login_update_changes_optional',
'disabled' => 'login_update_changes_no',
), 'disabled' => $photoChangesDisabled ), null, null, null, 'login_update_photo_changes_inc_optional' );
}
return array_merge( $return, parent::acpForm() );
}
@@ -538,7 +555,7 @@ abstract class OAuth2 extends Handler
{
try
{
$identifier = Db::i()->select( 'token_identifier', 'core_login_links', array( 'token_login_method=? AND token_member=?', $this->id, $exception->member->member_id ) )->first();
$identifier = Db::i()->select( 'token_identifier', 'core_login_links', [ 'token_login_method=? AND token_member=?', $this->id, $exception->member->member_id ], flags: Db::SELECT_FROM_WRITE_SERVER )->first();
if( $identifier != $userId )
{
@@ -786,7 +803,7 @@ abstract class OAuth2 extends Handler
*/
public function userId( Member $member ): ?string
{
if ( !( $link = $this->_link( $member ) ) or ( $link['token_expires'] and $link['token_expires'] < time() ) )
if ( !( $link = $this->_link( $member ) ) or ( $link['token_expires'] and $link['token_expires'] < time() ) OR empty( $link['token_access_token'] ) )
{
throw new Exception( 'generic_error', Exception::INTERNAL_ERROR );
}
@@ -806,7 +823,7 @@ abstract class OAuth2 extends Handler
*/
public function userProfileName( Member $member ): ?string
{
if ( !( $link = $this->_link( $member ) ) or ( $link['token_expires'] and $link['token_expires'] < time() ) )
if ( !( $link = $this->_link( $member ) ) or ( $link['token_expires'] and $link['token_expires'] < time() ) OR empty( $link['token_access_token'] ) )
{
throw new Exception( 'generic_error', Exception::INTERNAL_ERROR );
}
+2 -2
View File
@@ -312,7 +312,7 @@ class Wordpress extends OAuth2
*/
public function userProfilePhoto( Member $member ): ?Url
{
if ( !( $link = $this->_link( $member ) ) or ( $link['token_expires'] and $link['token_expires'] < time() ) )
if ( !( $link = $this->_link( $member ) ) or ( $link['token_expires'] and $link['token_expires'] < time() ) OR empty( $link['token_access_token'] ) )
{
throw new Exception( "", Exception::INTERNAL_ERROR );
}
@@ -342,7 +342,7 @@ class Wordpress extends OAuth2
*/
public function userProfileName( Member $member ): ?string
{
if ( !( $link = $this->_link( $member ) ) or ( $link['token_expires'] and $link['token_expires'] < time() ) )
if ( !( $link = $this->_link( $member ) ) or ( $link['token_expires'] and $link['token_expires'] < time() ) OR empty( $link['token_access_token'] ) )
{
throw new Exception( "", Exception::INTERNAL_ERROR );
}