658 lines
22 KiB
PHP
658 lines
22 KiB
PHP
<?php
|
|
/**
|
|
* @brief Mobile App Settings
|
|
* @author <a href='https://www.invisioncommunity.com'>Invision Power Services, Inc.</a>
|
|
* @copyright (c) Invision Power Services, Inc.
|
|
* @license https://www.invisioncommunity.com/legal/standards/
|
|
* @package Invision Community
|
|
* @since 18 Mar 2019
|
|
*/
|
|
|
|
namespace IPS\core\modules\admin\mobile;
|
|
|
|
/* To prevent PHP errors (extending class does not exist) revealing path */
|
|
if ( !\defined( '\IPS\SUITE_UNIQUE_KEY' ) )
|
|
{
|
|
header( ( isset( $_SERVER['SERVER_PROTOCOL'] ) ? $_SERVER['SERVER_PROTOCOL'] : 'HTTP/1.0' ) . ' 403 Forbidden' );
|
|
exit;
|
|
}
|
|
|
|
/**
|
|
* Mobile App Settings
|
|
*/
|
|
class _mobile extends \IPS\Dispatcher\Controller
|
|
{
|
|
/**
|
|
* @brief Has been CSRF-protected
|
|
*/
|
|
public static $csrfProtected = TRUE;
|
|
|
|
/**
|
|
* Execute
|
|
*
|
|
* @return void
|
|
*/
|
|
public function execute()
|
|
{
|
|
if ( \IPS\DEMO_MODE )
|
|
{
|
|
\IPS\Output::i()->error( 'demo_mode_function_blocked', '1C418/1', 403, '' );
|
|
}
|
|
|
|
\IPS\Dispatcher::i()->checkAcpPermission( 'mobile_manage' );
|
|
parent::execute();
|
|
}
|
|
|
|
/**
|
|
* Mobile App Page
|
|
*
|
|
* @return void
|
|
*/
|
|
protected function manage()
|
|
{
|
|
\IPS\Output::i()->title = \IPS\Member::loggedIn()->language()->addToStack( 'menu__core_mobile' );
|
|
|
|
/* If the mobile app has been set up, show the details page... */
|
|
if ( \IPS\Settings::i()->mobile_app_id )
|
|
{
|
|
try
|
|
{
|
|
/* Get details from directory */
|
|
$details = \IPS\Http\Url::ips('mobile/directory')->setQueryString( array( 'id' => \IPS\Settings::i()->mobile_app_id ) )->request()->login( \IPS\Settings::i()->mobile_app_id, \IPS\Settings::i()->mobile_app_secret )->get()->decodeJson();
|
|
if ( \count( $details ) !== 1 )
|
|
{
|
|
if ( \count( $details ) === 0 )
|
|
{
|
|
\IPS\Settings::i()->changeValues( array( 'mobile_app_id' => '', 'mobile_app_secret' => '' ) );
|
|
return $this->_notSetup();
|
|
}
|
|
else
|
|
{
|
|
throw new \DomainException;
|
|
}
|
|
}
|
|
$details = $details[0];
|
|
$langaugeOptions = \IPS\Http\Url::ips('mobile/languages')->request()->get()->decodeJson();
|
|
$languages = [];
|
|
foreach ( $details['languages'] as $langCode )
|
|
{
|
|
if ( array_key_exists( $langCode, $langaugeOptions ) )
|
|
{
|
|
$langauges[] = $langaugeOptions[ $langCode ];
|
|
}
|
|
}
|
|
$details['languages'] = $langauges;
|
|
|
|
/* If it says the status is other than what we expect, refresh our license key cache */
|
|
if ( $licenseKey = \IPS\IPS::licenseKey() and ( ( $details['status'] === 'active' and !$licenseKey['active'] ) or ( $details['status'] === 'expired' and !$licenseKey['active'] ) ) )
|
|
{
|
|
$licenseKey = \IPS\IPS::licenseKey( TRUE );
|
|
}
|
|
|
|
/* Unless we're suspended, show a button to turn off mobile app integration */
|
|
if ( $details['category'] === 'unlisted' or \in_array( $details['status'], array( 'pending', 'active', 'expired' ) ) )
|
|
{
|
|
\IPS\Output::i()->sidebar['actions']['deregister'] = array(
|
|
'icon' => 'times',
|
|
'title' => 'disable',
|
|
'link' => \IPS\Http\Url::internal('app=core&module=mobile&controller=mobile&do=deregister')->csrf(),
|
|
'data' => array(
|
|
'confirm' => '',
|
|
'confirmSubMessage' => $details['category'] === 'unlisted' ? '' : \IPS\Member::loggedIn()->language()->addToStack('mobile_app_deregister_confirm')
|
|
)
|
|
);
|
|
}
|
|
|
|
/* Build the settings form */
|
|
$settings = NULL;
|
|
if ( \in_array( $details['status'], array( 'active' ) ) )
|
|
{
|
|
\IPS\Output::i()->sidebar['actions']['tokens'] = array(
|
|
'icon' => 'key',
|
|
'title' => 'oauth_view_authorizations',
|
|
'link' => \IPS\Http\Url::internal('app=core&module=applications&controller=api&tab=oauth')->setQueryString( array( 'do' => 'tokens', 'client_id' => $this->_getClient()->client_id ) )
|
|
);
|
|
|
|
$settings = new \IPS\Helpers\Form;
|
|
$settings->add( new \IPS\Helpers\Form\Sort( 'mobile_app_home_blocks_order', json_decode( \IPS\Settings::i()->mobile_app_home_blocks_order, TRUE ), FALSE, array( 'checkboxes' => 'mobile_app_home_blocks_' ) ) );
|
|
|
|
if ( $details['category'] === 'unlisted' )
|
|
{
|
|
$settings->add( new \IPS\Helpers\Form\Text( 'mobile_app_redirect_scheme', \IPS\Settings::i()->mobile_app_redirect_scheme, FALSE, array( 'placeholder' => 'your-app-schema' ), NULL, NULL, '://', 'mobile_app_redirect_scheme' ) );
|
|
}
|
|
|
|
$settings->add( new \IPS\Helpers\Form\YesNo( 'mobile_app_prompt', \IPS\Settings::i()->mobile_app_prompt, FALSE, array( 'togglesOn' => array( 'mobile_app_itunes_id', 'mobile_app_itunes_url', 'mobile_app_play_id', 'mobile_app_play_url', 'itunes_affiliate_string' ) ) ) );
|
|
|
|
if( $details['category'] !== 'unlisted' )
|
|
{
|
|
$settings->add( new \IPS\Helpers\Form\YesNo( 'mobile_app_hide_stats', \IPS\Settings::i()->mobile_app_hide_stats, FALSE ) );
|
|
}
|
|
|
|
if ( $details['category'] === 'unlisted' )
|
|
{
|
|
$settings->add( new \IPS\Helpers\Form\Text( 'mobile_app_itunes_id', \IPS\Settings::i()->mobile_app_itunes_id, FALSE, array( 'placeholder' => '123456789' ), NULL, NULL, NULL, 'mobile_app_itunes_id' ) );
|
|
$settings->add( new \IPS\Helpers\Form\Url( 'mobile_app_itunes_url', \IPS\Settings::i()->mobile_app_itunes_url, FALSE, array( 'placeholder' => 'https://itunes.apple.com/us/app/my-app/123456789' ), NULL, NULL, NULL, 'mobile_app_itunes_url' ) );
|
|
$settings->add( new \IPS\Helpers\Form\Text( 'mobile_app_play_id', \IPS\Settings::i()->mobile_app_play_id, FALSE, array( 'placeholder' => 'com.company.appname' ), NULL, NULL, NULL, 'mobile_app_play_id' ) );
|
|
$settings->add( new \IPS\Helpers\Form\Url( 'mobile_app_play_url', \IPS\Settings::i()->mobile_app_play_url, FALSE, array( 'placeholder' => 'https://play.google.com/store/apps/details?id=com.company.appname' ), NULL, NULL, NULL, 'mobile_app_play_url' ) );
|
|
}
|
|
$settings->add( new \IPS\Helpers\Form\Text( 'itunes_affiliate_string', \IPS\Settings::i()->itunes_affiliate_string, FALSE, array(), NULL, NULL, NULL, 'itunes_affiliate_string' ) );
|
|
|
|
if ( $values = $settings->values() )
|
|
{
|
|
$values['mobile_app_home_blocks_order'] = json_encode( $values['mobile_app_home_blocks_order'] );
|
|
if ( $details['category'] !== 'unlisted' )
|
|
{
|
|
$values['mobile_app_redirect_scheme'] = '';
|
|
$values['mobile_app_itunes_id'] = '';
|
|
$values['mobile_app_itunes_url'] = '';
|
|
$values['mobile_app_play_id'] = '';
|
|
$values['mobile_app_play_url'] = '';
|
|
}
|
|
|
|
$settings->saveAsSettings( $values );
|
|
if ( $details['category'] == 'unlisted' and $values['mobile_app_redirect_scheme'] )
|
|
{
|
|
$this->_updateClient( $this->_getClient() );
|
|
}
|
|
unset( \IPS\Data\Store::i()->manifest );
|
|
|
|
\IPS\Output::i()->redirect( \IPS\Http\Url::internal('app=core&module=mobile&controller=mobile') );
|
|
}
|
|
}
|
|
elseif ( \IPS\Settings::i()->mobile_app_prompt )
|
|
{
|
|
\IPS\Settings::i()->changeValues( array( 'mobile_app_prompt' => 0 ) );
|
|
unset( \IPS\Data\Store::i()->manifest );
|
|
}
|
|
|
|
/* Display */
|
|
\IPS\Output::i()->output = \IPS\Theme::i()->getTemplate( 'mobile' )->details( $details, $settings );
|
|
}
|
|
catch ( \Exception $e )
|
|
{
|
|
\IPS\Output::i()->error( 'mobile_app_registration_error', '4C397/7', 500, NULL, array(), \IPS\IPS::getExceptionDetails( $e ) );
|
|
}
|
|
}
|
|
/* Otherwise show the splash screen */
|
|
else
|
|
{
|
|
return $this->_notSetup();
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Mobile App: Not Setup
|
|
*
|
|
* @return void
|
|
*/
|
|
protected function _notSetup()
|
|
{
|
|
\IPS\Output::i()->sidebar['actions']['manual'] = array(
|
|
'icon' => 'cog',
|
|
'title' => 'mobile_app_splash_manual',
|
|
'link' => \IPS\Http\Url::internal('app=core&module=mobile&controller=mobile&do=manual'),
|
|
'data' => array( 'ipsDialog' => '', 'ipsDialog-title' => \IPS\Member::loggedIn()->language()->addToStack('mobile_app_splash_manual') )
|
|
);
|
|
|
|
\IPS\Output::i()->output = \IPS\Theme::i()->getTemplate( 'mobile' )->splash();
|
|
}
|
|
|
|
/**
|
|
* Mobile App: Submit to Multi Community
|
|
*
|
|
* @return void
|
|
*/
|
|
protected function submit()
|
|
{
|
|
/* Before we do anything, check the license key */
|
|
if ( $licenseKey = \IPS\IPS::licenseKey( TRUE ) )
|
|
{
|
|
if ( !$licenseKey['active'] )
|
|
{
|
|
\IPS\Output::i()->error( 'mobile_app_requires_active_license', '1C397/8', 403 );
|
|
}
|
|
}
|
|
else
|
|
{
|
|
\IPS\Output::i()->error( 'mobile_app_requires_license', '1C397/9', 403 );
|
|
}
|
|
|
|
/* Create the form */
|
|
$form = new \IPS\Helpers\Form( 'mobile_app_submit', 'submit' );
|
|
$existing = NULL;
|
|
if ( \IPS\Settings::i()->mobile_app_id )
|
|
{
|
|
try
|
|
{
|
|
$details = \IPS\Http\Url::ips('mobile/directory')->setQueryString( array( 'id' => \IPS\Settings::i()->mobile_app_id ) )->request()->login( \IPS\Settings::i()->mobile_app_id, \IPS\Settings::i()->mobile_app_secret )->get()->decodeJson();
|
|
if ( \count( $details ) !== 1 )
|
|
{
|
|
throw new \DomainException;
|
|
}
|
|
$existing = $details[0];
|
|
}
|
|
catch ( \Exception $e )
|
|
{
|
|
\IPS\Output::i()->error( 'mobile_app_registration_error', '4C397/6', 500, NULL, array(), \IPS\IPS::getExceptionDetails( $e ) );
|
|
}
|
|
$form->addMessage('mobile_app_listing_update_info');
|
|
}
|
|
$form->add( new \IPS\Helpers\Form\Text( 'mobile_app_listing_name', $existing ? ( $existing['pending_name'] ?: $existing['name'] ) : \IPS\Settings::i()->board_name, TRUE ) );
|
|
$form->add( new \IPS\Helpers\Form\TextArea( 'mobile_app_listing_desc', $existing ? ( $existing['pending_description'] ?: $existing['description'] ) : NULL, TRUE, array( 'maxLength' => 125 ) ) );
|
|
if ( $existing )
|
|
{
|
|
$form->add( new \IPS\Helpers\Form\Radio( 'mobile_app_listing_logo_choose', 'keep', TRUE, array(
|
|
'options' => array(
|
|
'keep' => 'mobile_app_listing_logo_keep',
|
|
'change' => 'mobile_app_listing_logo_change',
|
|
),
|
|
'toggles' => array(
|
|
'change' => array( 'mobile_app_listing_logo_upload' )
|
|
)
|
|
) ) );
|
|
}
|
|
$homeScreen = json_decode( \IPS\Settings::i()->icons_homescreen, TRUE ) ?? array();
|
|
$form->add( new \IPS\Helpers\Form\Upload( 'mobile_app_listing_logo', $existing ? NULL : ( ( isset( $homeScreen['original'] ) ) ? \IPS\File::get( 'core_Icons', $homeScreen['original'] ) : NULL ), TRUE, array( 'image' => TRUE, 'storageExtension' => 'core_Icons' ), function ( $file ) {
|
|
if ( $file )
|
|
{
|
|
$image = \IPS\Image::create( $file->contents() );
|
|
if ( !$image->isSquare() )
|
|
{
|
|
throw new \DomainException('mobile_app_listing_logo_square');
|
|
}
|
|
if ( $image->width < 512 )
|
|
{
|
|
throw new \DomainException('mobile_app_listing_logo_dims');
|
|
}
|
|
}
|
|
}, NULL, NULL, 'mobile_app_listing_logo_upload' ) );
|
|
try
|
|
{
|
|
$categoryData = \IPS\Http\Url::ips('mobile/categories')->request()->get()->decodeJson();
|
|
$categories = array();
|
|
|
|
foreach( $categoryData as $_key => $_cat )
|
|
{
|
|
$categories[ $_key ] = $_cat['title'];
|
|
}
|
|
|
|
$form->add( new \IPS\Helpers\Form\Select( 'mobile_app_listing_category', $existing ? $existing['category'] : 'general', TRUE, array( 'options' => $categories ) ) );
|
|
|
|
$langaugeOptions = \IPS\Http\Url::ips('mobile/languages')->request()->get()->decodeJson();
|
|
if ( $existing )
|
|
{
|
|
$langauges = explode( ',', $existing['languages'] );
|
|
}
|
|
else
|
|
{
|
|
$langauges = [];
|
|
foreach ( \IPS\Lang::languages() as $lang )
|
|
{
|
|
$code = mb_substr( $lang->bcp47(), 0, 2 );
|
|
if ( array_key_exists( $code, $langaugeOptions ) )
|
|
{
|
|
$langauges[] = $code;
|
|
}
|
|
}
|
|
if ( !$langauges )
|
|
{
|
|
$langauges = ['en'];
|
|
}
|
|
}
|
|
$form->add( new \IPS\Helpers\Form\CheckboxSet( 'mobile_app_listing_languages', $existing ? explode( ',', $existing['languages'] ): ['en'], TRUE, array( 'multiple' => TRUE, 'options' => $langaugeOptions ) ) );
|
|
}
|
|
catch ( \Exception $e )
|
|
{
|
|
\IPS\Output::i()->error( 'mobile_app_registration_error', '4C397/3', 500, NULL, array(), \IPS\IPS::getExceptionDetails( $e ) );
|
|
}
|
|
|
|
/* Handle submissions */
|
|
if ( $values = $form->values() )
|
|
{
|
|
/* If we haven't set application icons for our manifest, use the icon provided */
|
|
if ( !isset( $homeScreen['original'] ) )
|
|
{
|
|
\IPS\Settings::i()->changeValues( \IPS\core\modules\admin\customization\icons::processApplicationIcon( array( 'icons_homescreen' => $values['mobile_app_listing_logo'] ), $homeScreen ) );
|
|
}
|
|
|
|
try
|
|
{
|
|
/* Work out logo */
|
|
$logo = NULL;
|
|
$logoExt = NULL;
|
|
$logoMime = NULL;
|
|
if ( !$existing or $values['mobile_app_listing_logo_choose'] === 'change' )
|
|
{
|
|
$logo = $values['mobile_app_listing_logo']->contents();
|
|
$logoExt = mb_substr( $values['mobile_app_listing_logo']->originalFilename, mb_strrpos( $values['mobile_app_listing_logo']->originalFilename, '.' ) + 1 );
|
|
$logoMime = \IPS\File::getMimeType( $values['mobile_app_listing_logo']->originalFilename );
|
|
}
|
|
|
|
/* Submit to IPS */
|
|
$response = $this->_updateRegistration( array(
|
|
'name' => $values['mobile_app_listing_name'],
|
|
'description' => $values['mobile_app_listing_desc'],
|
|
'category' => $values['mobile_app_listing_category'],
|
|
'logo' => $logo,
|
|
'logo_type' => $logoExt,
|
|
'logo_mime' => $logoMime,
|
|
'languages' => implode( ',', $values['mobile_app_listing_languages'] )
|
|
), $existing ? \IPS\Settings::i()->mobile_app_id : NULL, $existing ? \IPS\Settings::i()->mobile_app_secret : NULL );
|
|
|
|
/* If we already had an icon for our manifest, delete the logo we just uploaded */
|
|
if ( isset( $homeScreen['original'] ) and $values['mobile_app_listing_logo'] and (string) $homeScreen['original'] != (string) $values['mobile_app_listing_logo'] )
|
|
{
|
|
$values['mobile_app_listing_logo']->delete();
|
|
}
|
|
}
|
|
catch ( \DomainException $e )
|
|
{
|
|
\IPS\Output::i()->error( $e->getMessage(), '2C397/4', 500 );
|
|
}
|
|
catch ( \Exception $e )
|
|
{
|
|
\IPS\Output::i()->error( 'mobile_app_registration_error', '4C397/5', 500, NULL, array(), \IPS\IPS::getExceptionDetails( $e ) );
|
|
}
|
|
|
|
if ( $existing )
|
|
{
|
|
\IPS\Session::i()->log( 'acplogs__mobile_app_updated' );
|
|
}
|
|
else
|
|
{
|
|
$this->_doEnable( $response['id'], $response['secret'] );
|
|
|
|
\IPS\Session::i()->log( 'acplogs__mobile_app_registered' );
|
|
}
|
|
|
|
\IPS\Output::i()->redirect( \IPS\Http\Url::internal('app=core&module=mobile&controller=mobile') );
|
|
}
|
|
|
|
/* Display */
|
|
\IPS\Output::i()->title = \IPS\Member::loggedIn()->language()->addToStack( 'menu__core_mobile_mobile' );
|
|
\IPS\Output::i()->output = $form;
|
|
}
|
|
|
|
/**
|
|
* Mobile App: Activate Manually
|
|
*
|
|
* @return void
|
|
*/
|
|
protected function manual()
|
|
{
|
|
\IPS\Output::i()->title = \IPS\Member::loggedIn()->language()->addToStack( 'mobile_app_splash_manual' );
|
|
|
|
$form = new \IPS\Helpers\Form;
|
|
$form->addDummy( 'oauth_client_id', $this->_getClient( TRUE )->client_id );
|
|
$form->add( new \IPS\Helpers\Form\Text( 'mobile_app_splash_manual_id', NULL, TRUE, array(), function( $val ) {
|
|
try
|
|
{
|
|
$response = \IPS\Http\Url::ips('mobile/directory')->setQueryString( array( 'id' => $val ) )->request()->get()->decodeJson();
|
|
}
|
|
catch ( \Exception $e )
|
|
{
|
|
throw new \DomainException('mobile_app_registration_error');
|
|
}
|
|
|
|
if ( \count( $response ) !== 1 )
|
|
{
|
|
throw new \DomainException('mobile_app_splash_manual_error');
|
|
}
|
|
if ( $response[0]['url'] !== \IPS\Settings::i()->base_url )
|
|
{
|
|
throw new \DomainException('mobile_app_splash_manual_error_url');
|
|
}
|
|
} ) );
|
|
$form->add( new \IPS\Helpers\Form\Text( 'mobile_app_splash_manual_secret', NULL, TRUE, array(), function( $val ) {
|
|
try
|
|
{
|
|
$response = \IPS\Http\Url::ips('mobile/notify')->request()->login( \IPS\Request::i()->mobile_app_splash_manual_id, $val )->post( array( 'data' => array() ) );
|
|
}
|
|
catch ( \Exception $e )
|
|
{
|
|
throw new \DomainException('mobile_app_registration_error');
|
|
}
|
|
|
|
if ( $response->httpResponseCode != 200 )
|
|
{
|
|
throw new \DomainException('mobile_app_splash_manual_error');
|
|
}
|
|
} ) );
|
|
if ( $values = $form->values() )
|
|
{
|
|
try
|
|
{
|
|
$this->_updateRegistration( array( ), $values['mobile_app_splash_manual_id'], $values['mobile_app_splash_manual_secret'] );
|
|
}
|
|
catch ( \DomainException $e )
|
|
{
|
|
\IPS\Output::i()->error( $e->getMessage(), '2C397/1', 500 );
|
|
}
|
|
catch ( \Exception $e )
|
|
{
|
|
\IPS\Output::i()->error( 'mobile_app_registration_error', '4C397/2', 500, NULL, array(), \IPS\IPS::getExceptionDetails( $e ) );
|
|
}
|
|
|
|
$this->_doEnable( $values['mobile_app_splash_manual_id'], $values['mobile_app_splash_manual_secret'] );
|
|
|
|
\IPS\Session::i()->log( 'acplogs__mobile_app_activated' );
|
|
|
|
\IPS\Output::i()->redirect( \IPS\Http\Url::internal('app=core&module=mobile&controller=mobile') );
|
|
}
|
|
|
|
\IPS\Output::i()->output = $form;
|
|
}
|
|
|
|
/**
|
|
* Mobile App: Deregister
|
|
*
|
|
* @return void
|
|
*/
|
|
protected function deregister()
|
|
{
|
|
\IPS\Session::i()->csrfCheck();
|
|
|
|
if ( \IPS\Settings::i()->mobile_app_id )
|
|
{
|
|
try
|
|
{
|
|
\IPS\Http\Url::ips('mobile/unregister')->request()->login( \IPS\Settings::i()->mobile_app_id, \IPS\Settings::i()->mobile_app_secret )->post( array(
|
|
'lkey' => trim( \IPS\Settings::i()->ipb_reg_number ),
|
|
) );
|
|
}
|
|
catch ( \Exception $e )
|
|
{
|
|
// It doesn't really matter if this failed (which could happen if the stores secret was somehow wrong)
|
|
// It might just require tech support to go in and manually remove them before they can register again
|
|
}
|
|
|
|
\IPS\Settings::i()->changeValues( array(
|
|
'mobile_app_id' => '',
|
|
'mobile_app_secret' => '',
|
|
) );
|
|
}
|
|
if ( $client = $this->_getClient() )
|
|
{
|
|
$client->delete();
|
|
}
|
|
|
|
\IPS\Session::i()->log( 'acplogs__mobile_app_unregistered' );
|
|
|
|
\IPS\Output::i()->redirect( \IPS\Http\Url::internal( 'app=core&module=mobile&controller=mobile' ) );
|
|
}
|
|
|
|
/**
|
|
* Get OAuth Client if there is one
|
|
*
|
|
* @bool bool $createIfNot If there isn't one, create one
|
|
* @return \IPS\Api\OAuthClient|NULL
|
|
*/
|
|
protected function _getClient( $createIfNot = FALSE )
|
|
{
|
|
try
|
|
{
|
|
return \IPS\Api\OAuthClient::constructFromData( \IPS\Db::i()->select( '*', 'core_oauth_clients', array( 'oauth_type=?', 'mobile' ) )->first() );
|
|
}
|
|
catch ( \UnderflowException $e )
|
|
{
|
|
if ( $createIfNot )
|
|
{
|
|
$client = $this->_createClient();
|
|
$this->_updateClient( $client );
|
|
return $client;
|
|
}
|
|
else
|
|
{
|
|
return NULL;
|
|
}
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Create an OAuth Client
|
|
*
|
|
* @return \IPS\Api\OAuthClient
|
|
*/
|
|
protected function _createClient()
|
|
{
|
|
$client = new \IPS\Api\OAuthClient;
|
|
do
|
|
{
|
|
$client->client_id = \IPS\Login::generateRandomString( 32 );
|
|
}
|
|
while ( \IPS\Db::i()->select( 'COUNT(*)', 'core_oauth_clients', array( 'oauth_client_id=?', $client->client_id ) )->first() );
|
|
$client->enabled = TRUE;
|
|
$client->prompt = 'none';
|
|
$client->ucp = FALSE;
|
|
|
|
\IPS\Lang::copyCustom( 'core', 'mobile_app_default_client_name', "core_oauth_client_{$client->client_id}" );
|
|
|
|
return $client;
|
|
}
|
|
|
|
/**
|
|
* Update OAuth Client with appropriate settings
|
|
*
|
|
* @param \IPS\Api\OAuthClient $client The client
|
|
* @return void
|
|
*/
|
|
protected function _updateClient( \IPS\Api\OAuthClient $client )
|
|
{
|
|
$client->client_secret = NULL;
|
|
foreach ( \IPS\Api\OAuthClient::mobileAppValues() as $k => $v )
|
|
{
|
|
if ( $k === 'redirect_uris' or $k === 'scopes' )
|
|
{
|
|
$client->$k = json_encode( $v );
|
|
}
|
|
else
|
|
{
|
|
$client->$k = \is_array( $v ) ? implode( ',', $v ) : $v;
|
|
}
|
|
}
|
|
$client->save();
|
|
}
|
|
|
|
/**
|
|
* Update registration details on remoteservices
|
|
*
|
|
* @param array $details Details to update (name, description, etc)
|
|
* @param string|NULL $appId If updating, the ID
|
|
* @param string|NULL $appSecret If updating, the secret
|
|
* @return array
|
|
*/
|
|
protected function _updateRegistration( $details, $appId = NULL, $appSecret = NULL )
|
|
{
|
|
/* First of all, create or update our OAuth Client */
|
|
$client = $this->_getClient();
|
|
if ( !$client )
|
|
{
|
|
$client = $this->_createClient();
|
|
}
|
|
$this->_updateClient( $client );
|
|
|
|
/* Set details to send */
|
|
$details['lkey'] = trim( \IPS\Settings::i()->ipb_reg_number );
|
|
$details['url'] = \IPS\Settings::i()->base_url;
|
|
$details['client_id'] = $client->client_id;
|
|
|
|
/* Register or update remoteservices */
|
|
if ( $appId )
|
|
{
|
|
$response = \IPS\Http\Url::ips('mobile/register')->request()->login( $appId, $appSecret )->post( $details );
|
|
|
|
if ( $response->httpResponseCode != 200 )
|
|
{
|
|
throw new \DomainException( ( (string) $response ) ?: 'mobile_app_registration_error' );
|
|
}
|
|
}
|
|
else
|
|
{
|
|
$response = \IPS\Http\Url::ips('mobile/register')->request()->post( $details );
|
|
|
|
if ( $response->httpResponseCode != 201 )
|
|
{
|
|
throw new \DomainException( ( (string) $response ) ?: 'mobile_app_registration_error' );
|
|
}
|
|
}
|
|
return $response->decodeJson();
|
|
}
|
|
|
|
/**
|
|
* Enable mobile app
|
|
*
|
|
* @param string $appId If updating, the ID
|
|
* @param string $appSecret If updating, the secret
|
|
* @return array
|
|
*/
|
|
protected function _doEnable( $appId, $appSecret )
|
|
{
|
|
\IPS\Settings::i()->changeValues( array(
|
|
'mobile_app_id' => $appId,
|
|
'mobile_app_secret' => $appSecret,
|
|
) );
|
|
|
|
/* Add it to our notification defaults */
|
|
if ( \IPS\Db::i()->select( 'COUNT(*)', 'core_notification_defaults' )->first() )
|
|
{
|
|
$keysToAddPushTo = array();
|
|
|
|
foreach( \IPS\Application::allExtensions( 'core', 'Notifications', FALSE ) as $group => $class )
|
|
{
|
|
if ( method_exists( $class, 'configurationOptions' ) )
|
|
{
|
|
foreach ( $class->configurationOptions( NULL ) as $key => $data )
|
|
{
|
|
if ( $data['type'] == 'standard' and \in_array( 'push', $data['default'] ) )
|
|
{
|
|
$keysToAddPushTo[] = $key;
|
|
foreach ( $data['notificationTypes'] as $type )
|
|
{
|
|
$keysToAddPushTo[] = $type;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
elseif ( method_exists( $class, 'getConfiguration' ) )
|
|
{
|
|
$configuration = $class->getConfiguration( NULL );
|
|
if ( !empty( $configuration ) )
|
|
{
|
|
foreach ( $configuration as $key => $data )
|
|
{
|
|
if ( \in_array( 'push', $data['default'] ) )
|
|
{
|
|
$keysToAddPushTo[] = $key;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
if ( \count( $keysToAddPushTo ) )
|
|
{
|
|
\IPS\Db::i()->update( 'core_notification_defaults', "`default` = IF( `default` = '', 'push', CONCAT_WS( ',', `default`, 'push' ) )", \IPS\Db::i()->in( 'notification_key', $keysToAddPushTo ) );
|
|
}
|
|
}
|
|
}
|
|
} |