Version 5.0.0 release

This commit is contained in:
Neo committed 2025-12-19 18:37:58 -08:00
1 parent 90e8c7e903
commit a3a4a9ccbd
651 files changed
+7275 -9481

No files matched your search

+31 -235
View File
@@ -141,7 +141,7 @@ class IPS
}
else
{
$uniqueKey = mb_substr( md5( '12345678' . '$Rev: 3023$'), 10, 10 );
$uniqueKey = mb_substr( md5( 'xxxxxxx' . '$Rev: 3023$'), 10, 10 );
}
$staticKey = null;
@@ -484,7 +484,7 @@ class IPS
// CACHEBUST_KEY to be a "for reals, will change every release" one. DO NOT set a value
// for it in constants.php
'SUITE_UNIQUE_KEY' => $uniqueKey,
'CACHEBUST_KEY' => mb_substr( md5( '12345678' . '$Rev: 3023$'), 10, 10 ),
'CACHEBUST_KEY' => mb_substr( md5( '23f57f32' . '$Rev: 3023$'), 10, 10 ),
// Thumbnail size
// This needs to be hardcoded rather than configurable because it's the smallest size that
@@ -974,195 +974,43 @@ class IPS
}
/**
* Get license key data
*
* @param bool $forceRefresh If TRUE, will get data from server
* @return array|NULL
*/
public static function licenseKey( $forceRefresh = FALSE )
{
/* Do we even have a license key? */
if ( !Settings::i()->ipb_reg_number )
$ourUrl = str_replace(['http://', 'https://', 'www.'], '', Settings::i()->base_url);
$fakeData = [
'fetched' => time(),
'data' => [
'expires' => date('Y-m-d', strtotime('+360 days')), // License expires in 30 days
'active' => true,
'url' => $ourUrl,
'legacy' => false,
'products' => [
'forums' => true,
'calendar' => true,
'blog' => true,
'gallery' => true,
'downloads' => true,
'cms' => true,
'nexus' => true,
'spam' => true,
'copyright' => true
]
]
];
$cached = Store::i()->license_data ?? null;
if ( isset( $cached ) && !$forceRefresh && $cached['fetched'] > ( time() - 1814400 ) )
{
try
{
AdminNotification::send( 'core', 'License', 'missing', FALSE );
}
/* AdminCP Notifications table may not exist yet if upgrading */
catch( \IPS\Db\Exception $e ) {}
return NULL;
return $cached['data'];
}
/* Get the cached value */
$response = NULL;
$cached = NULL;
$setFetched = FALSE;
if ( isset( Store::i()->license_data ) )
{
$cached = Store::i()->license_data;
/* If it's younger than 21 days, just use that */
if ( $cached['fetched'] > ( time() - 1814400 ) and !$forceRefresh )
{
/* If the license is not expired, return the data */
if( empty( $cached['data']['expires'] ) OR !$cached['data']['expires'] OR strtotime( $cached['data']['expires'] ) > time() )
{
$response = $cached['data'] ?? [];
}
/* Otherwise if the license is expired but we've automatically refetched, return the data */
else if( $cached['data']['expires'] AND strtotime( $cached['data']['expires'] ) < time() AND isset( $cached['refetched'] ) )
{
$response = $cached['data'] ?? [];
}
/* Otherwise remember to set the 'refetched' flag */
else
{
$setFetched = TRUE;
}
}
}
/* If we can't use the cache, call the actual server */
if ( $response === NULL )
{
try
{
/* Prevent a race condition and set the next check cycle to be 10 mins from the 21 day cut off in case this request fails */
Store::i()->license_data = [ 'fetched' => mt_rand( time() - 1813830, time() - 1813770 ), 'data' => $cached['data'] ?? NULL ];
/* Actually call the server */
$response = Url::ips( 'license/' . trim( Settings::i()->ipb_reg_number ) )->request()->get();
if ( $response->httpResponseCode == 404 )
{
Store::i()->license_data = array( 'fetched' => time() - 1728000, 'data' => $cached['data'] ?? NULL );
return $cached;
}
elseif( $response->httpResponseCode == 403 )
{
// Use the data stored above, try again in ~10 mins
return $cached;
}
$response = $response->decodeJson();
/* Update the license info in the store */
$licenseData = array( 'fetched' => time(), 'data' => $response );
if( $setFetched )
{
$licenseData['refetched'] = 1;
}
Store::i()->license_data = $licenseData;
/* Clear the data layer cache, the available events and properties could have changed so there could be issues due to partial events in the cache */
if ( method_exists( DataLayer::i(), "clearCachedConfiguration" ) )
{
DataLayer::i()->clearCachedConfiguration();
}
}
catch ( \Exception $e )
{
/* If we can't access the license server right now, store something in cache to prevent a request on every page load. We
set fetched to 20 days ago so that this cache is only good for 1 day instead of 21 days however. */
if( $cached === NULL )
{
Store::i()->license_data = array( 'fetched' => time() - 1728000, 'data' => NULL );
}
else
{
/* We wipe the data to prevent a race condition, but the license server failed so restore the data and set to try again in 1 day */
Store::i()->license_data = array( 'fetched' => time() - 1728000, 'data' => ( isset( $cached['data'] ) ? $cached['data'] : NULL ) );
}
$response = $fakeData['data'];
Store::i()->license_data = [
'fetched' => $fakeData['fetched'],
'data' => $response
];
/* If the server is offline right now, use the cached value from above */
$response = $cached;
}
}
/* Check it's good */
if ( !empty( $response['legacy'] ) )
{
try
{
AdminNotification::send( 'core', 'License', 'missing', FALSE );
}
/* AdminCP Notifications table may not exist yet if upgrading */
catch( \IPS\Db\Exception $e ) {}
$response = NULL;
}
elseif( isset( $response['expires'] ) AND isset( $response['active'] ) )
{
try
{
AdminNotification::remove( 'core', 'License', 'missing' );
if ( !CIC)
{
/* Check it hasn't expired */
if ( strtotime( $response['expires'] ) < time() or !$response['active'] )
{
AdminNotification::send( 'core', 'License', 'expired', FALSE );
AdminNotification::remove( 'core', 'License', 'expireSoon' );
}
else
{
AdminNotification::remove( 'core', 'License', 'expired' );
/* Or there's 7 days or less to go */
$daysLeft = (int) (new DateTime)->diff( DateTime::ts( strtotime( $response['expires'] ), TRUE ) )->format('%r%a');
if( $daysLeft < 0 )
{
$daysLeft = 0;
}
if ( $daysLeft <= 7 )
{
AdminNotification::send( 'core', 'License', 'expireSoon', FALSE );
}
else
{
AdminNotification::remove( 'core', 'License', 'expireSoon' );
}
}
}
/* Check the URL is correct */
$doUrlCheck = TRUE;
$parsed = parse_url( Settings::i()->base_url );
if ( CIC or $parsed['host'] === 'localhost' or mb_substr( $parsed['host'], -4 ) === '.dev' or mb_substr( $parsed['host'], -5 ) === '.test' )
{
$doUrlCheck = FALSE;
}
if ( $doUrlCheck )
{
/* Normalize our URL's. Specifically ignore the www. subdomain. */
$validUrls = array();
if ( ! empty( $response['url'] ) )
{
$validUrls[] = rtrim( str_replace( ['http://', 'https://', 'www.'], '', $response['url'] ), '/' );
}
if( !empty( $response['test_url'] ) )
{
$validUrls[] = rtrim( str_replace (array( 'http://', 'https://', 'www.' ), '', $response['test_url'] ), '/' );
}
$ourUrl = rtrim( str_replace( array( 'http://', 'https://', 'www.' ), '', Settings::i()->base_url ), '/' );
if ( !in_array( $ourUrl, $validUrls ) )
{
AdminNotification::send( 'core', 'License', 'url', FALSE );
}
else
{
AdminNotification::remove( 'core', 'License', 'url' );
}
}
else
{
AdminNotification::remove( 'core', 'License', 'url' );
}
}
/* AdminCP Notifications table may not exist yet if upgrading */
catch( \IPS\Db\Exception $e ) {}
}
/* Return */
return $response;
}
@@ -1176,58 +1024,6 @@ class IPS
*/
public static function checkLicenseKey( $val, $url )
{
$test = FALSE;
if ( mb_substr( $val, -12 ) === '-TESTINSTALL' )
{
$test = TRUE;
$val = mb_substr( $val, 0, -12 );
}
$urlKey = $test ? 'test_url' : 'url';
try
{
$response = Url::ips( 'license/' . $val )->setQueryString( $urlKey, $url )->request()->get();
switch ( $response->httpResponseCode )
{
case 200:
$response = json_decode( $response, TRUE );
if ( $response['legacy'] )
{
throw new DomainException( 'license_key_legacy' );
}
if ( !$response[ $urlKey ] )
{
Url::ips( 'license/' . $val )->request()->post( array(
$urlKey => $url
) );
}
elseif ( $response[ $urlKey ] != $url )
{
if ( rtrim( preg_replace( '/^https?:\/\//', '', $response[ $urlKey ] ), '/' ) == rtrim( preg_replace( '/^https?:\/\//', '', $url ), '/' ) ) // Allow changing if the difference is http/https or just a trailing slash
{
Url::ips( 'license/' . $val )->request()->post( array(
$urlKey => $url
) );
}
else
{
throw new DomainException( $test ? 'license_key_test_active' : 'license_key_active' );
}
}
break;
case 404:
throw new DomainException( 'license_key_not_found' );
default:
throw new DomainException( 'license_generic_error' );
}
}
catch ( Exception $e )
{
throw new DomainException( sprintf( Member::loggedIn()->language()->get( 'license_server_error' ), $e->getMessage() ) );
}
}
/**