Version 4.7.13
This commit is contained in:
1 parent
fd22d99e69
commit
7124a02564
954 files changed
+29277
-59308
No files matched your search
@@ -0,0 +1,221 @@
|
||||
<?php
|
||||
/**
|
||||
* @brief Community Hive Helpers
|
||||
* @author <a href='https://communityhive.com'>CommunityHive.com</a>
|
||||
* @copyright (c) CommunityHive.com
|
||||
* @license https://www.invisioncommunity.com/legal/standards/
|
||||
* @package Community Hive
|
||||
* @since 16 May 2023
|
||||
*/
|
||||
|
||||
namespace IPS\core;
|
||||
|
||||
/* To prevent PHP errors (extending class does not exist) revealing path */
|
||||
|
||||
use IPS\Application;
|
||||
use IPS\Content;
|
||||
use IPS\Content\Item;
|
||||
use IPS\Content\Searchable;
|
||||
use IPS\Http\Url;
|
||||
use IPS\IPS;
|
||||
use IPS\Member;
|
||||
use IPS\Settings;
|
||||
use Jose\Component\Core\JWK;
|
||||
use IPS\Db;
|
||||
|
||||
if ( !\defined( '\IPS\SUITE_UNIQUE_KEY' ) )
|
||||
{
|
||||
header( ( isset( $_SERVER['SERVER_PROTOCOL'] ) ? $_SERVER['SERVER_PROTOCOL'] : 'HTTP/1.0' ) . ' 403 Forbidden' );
|
||||
exit;
|
||||
}
|
||||
|
||||
/**
|
||||
* Community Hive Helpers
|
||||
*/
|
||||
class _Hive extends \IPS\Patterns\Singleton
|
||||
{
|
||||
/**
|
||||
* Framework coding standards....
|
||||
*/
|
||||
public function __construct()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Make an API request with a JWT
|
||||
*
|
||||
* @param string $endpoint
|
||||
* @param array $payload
|
||||
* @return array
|
||||
*/
|
||||
public static function api( string $endpoint, array $payload ): array
|
||||
{
|
||||
$hostname = \defined( 'COMMUNITYHIVE_URL' ) ? COMMUNITYHIVE_URL : 'https://communityhive.com';
|
||||
$request = Url::external( $hostname . '/api/v1/' . $endpoint )
|
||||
->request(3)
|
||||
->put( static::_assembleJwt( $payload ) );
|
||||
|
||||
if( (int) $request->httpResponseCode !== 200 )
|
||||
{
|
||||
\IPS\Log::log( [ 'endpoint' => $hostname . '/api/v1/' . $endpoint, 'payload' => $payload, 'response' => $request ], 'hive_error' );
|
||||
throw new \LogicException( $request->decodeJson()['error'] ?? 'an unknown error occurred.' );
|
||||
}
|
||||
|
||||
return $request->decodeJson();
|
||||
}
|
||||
|
||||
/**
|
||||
* Generate group hash in an ordered way
|
||||
*
|
||||
* @param Member $member
|
||||
* @return string
|
||||
*/
|
||||
public static function groupHash( Member $member ): string
|
||||
{
|
||||
if( $member->isBanned() === FALSE )
|
||||
{
|
||||
$hash = array_filter( array_merge( [ $member->member_group_id ], explode( ',', $member->mgroup_others ) ) );
|
||||
natcasesort( $hash );
|
||||
return implode( ',', $hash );
|
||||
}
|
||||
else
|
||||
{
|
||||
return 'guest';
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief store any keys for removal in __destruct()
|
||||
*/
|
||||
protected static array $_deleteQueue = [];
|
||||
|
||||
/**
|
||||
* Remove content from Hive - Used if something is moved or content is hidden
|
||||
*
|
||||
* @param Content $content
|
||||
* @return void
|
||||
*/
|
||||
public function removeContent( Content $content )
|
||||
{
|
||||
/* Wrap it all because we don't want it to stop the moderation action */
|
||||
try
|
||||
{
|
||||
if ( !( $content instanceof Searchable ) or empty( Settings::i()->hive_key ) )
|
||||
{
|
||||
return;
|
||||
}
|
||||
$idColumn = $content::$databaseColumnId;
|
||||
|
||||
if ( $content instanceof Item )
|
||||
{
|
||||
$key1 = \get_class( $content ) . '/' . $content->$idColumn;
|
||||
}
|
||||
else
|
||||
{
|
||||
$itemIdColumn = $content->item()::$databaseColumnId;
|
||||
$key1 = \get_class( $content->item() ) . '/' . $content->item()->$itemIdColumn;
|
||||
$key2 = \get_class( $content ) . '/' . $content->$idColumn;
|
||||
}
|
||||
|
||||
/* Store IDs for removal */
|
||||
static::$_deleteQueue[] = [ 'key1' => $key1, 'key2' => $key2 ?? NULL ];
|
||||
}
|
||||
catch( \Exception | \Throwable $e )
|
||||
{
|
||||
\IPS\Log::log( $e, 'hive_content_removal' );
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Assemble a JWT with payload
|
||||
*
|
||||
* @param array $payload
|
||||
* @return string
|
||||
*/
|
||||
protected static function _assembleJwt( array $payload ): string
|
||||
{
|
||||
IPS::$PSR0Namespaces['Jose'] = \IPS\ROOT_PATH . '/system/3rd_party/JwtFramework/src';
|
||||
IPS::$PSR0Namespaces['Base64Url'] = \IPS\ROOT_PATH . '/system/3rd_party/Base64Url';
|
||||
|
||||
$jwk = new JWK([
|
||||
'kty' => 'oct',
|
||||
'k' => base64_encode( Settings::i()->hive_site_key )
|
||||
]);
|
||||
|
||||
$jwsCompactSerializer = new \Jose\Component\Signature\Serializer\CompactSerializer();
|
||||
$jwsBuilder = new \Jose\Component\Signature\JWSBuilder( new \Jose\Component\Core\AlgorithmManager( [ new \Jose\Component\Signature\Algorithm\HS256() ] ) );
|
||||
|
||||
$defaultPayload = [
|
||||
'sub' => Settings::i()->hive_site_id,
|
||||
'iss' => rtrim( Settings::i()->base_url, '/' ),
|
||||
'iat' => time(),
|
||||
'nbf' => time(),
|
||||
'exp' => time() + 60,
|
||||
'aud' => 'communityhive',
|
||||
'hive_system_version' => Application::load('core')->long_version
|
||||
];
|
||||
|
||||
$jws = $jwsBuilder
|
||||
->create()
|
||||
->withPayload( json_encode( array_merge( $defaultPayload, $payload ) ) )
|
||||
->addSignature( $jwk, [
|
||||
'typ' => 'JWT',
|
||||
'alg' => 'HS256',
|
||||
])
|
||||
->build();
|
||||
|
||||
return $jwsCompactSerializer->serialize( $jws, 0 );
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Cache whether the member is subscribed
|
||||
*/
|
||||
protected static ?bool $_showPromotion = NULL;
|
||||
|
||||
/**
|
||||
* Check if we should show the Hive Promotion for the viewing member
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public static function showPromotion(): bool
|
||||
{
|
||||
if( static::$_showPromotion !== NULL )
|
||||
{
|
||||
return static::$_showPromotion;
|
||||
}
|
||||
|
||||
if ( !Settings::i()->hive_enabled )
|
||||
{
|
||||
return static::$_showPromotion = FALSE;
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
Db::i()->select('member_id', 'core_hive_subscribers', [ 'member_id=?', Member::loggedIn()->member_id ] )->first();
|
||||
return static::$_showPromotion = FALSE;
|
||||
}
|
||||
catch ( \UnderflowException $e ){}
|
||||
|
||||
return static::$_showPromotion = TRUE;
|
||||
}
|
||||
|
||||
/**
|
||||
* Send API request to remove any content IDs that have been queued
|
||||
*/
|
||||
public function __destruct()
|
||||
{
|
||||
/* Wrap it all because we don't want it to stop the moderation action */
|
||||
try
|
||||
{
|
||||
if( \count( static::$_deleteQueue ) )
|
||||
{
|
||||
static::api( 'contentremove', [ 'keys' => static::$_deleteQueue ] );
|
||||
}
|
||||
}
|
||||
catch( \Exception | \Throwable $e )
|
||||
{
|
||||
\IPS\Log::log( $e, 'hive_content_removal' );
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in new issue
Block a user