Refactored Peer Information to use InformationFields rather than being hard-coded into the peer record

This commit is contained in:
netkas 2025-01-24 15:10:20 -05:00
parent 75de51c910
commit f689e36378
45 changed files with 1422 additions and 1337 deletions

View file

@ -10,21 +10,21 @@ use Socialbox\Classes\Utilities;
use Socialbox\Enums\Status\CaptchaStatus;
use Socialbox\Exceptions\DatabaseOperationException;
use Socialbox\Objects\Database\CaptchaRecord;
use Socialbox\Objects\Database\RegisteredPeerRecord;
use Socialbox\Objects\Database\PeerRecord;
class CaptchaManager
{
/**
* Creates a new captcha for the given peer UUID.
*
* @param string|RegisteredPeerRecord $peer_uuid The UUID of the peer to create the captcha for.
* @param string|PeerRecord $peer_uuid The UUID of the peer to create the captcha for.
* @return string The answer to the captcha.
* @throws DatabaseOperationException If the operation fails.
*/
public static function createCaptcha(string|RegisteredPeerRecord $peer_uuid): string
public static function createCaptcha(string|PeerRecord $peer_uuid): string
{
// If the peer_uuid is a RegisteredPeerRecord, get the UUID
if($peer_uuid instanceof RegisteredPeerRecord)
if($peer_uuid instanceof PeerRecord)
{
$peer_uuid = $peer_uuid->getUuid();
}
@ -73,14 +73,14 @@ class CaptchaManager
/**
* Answers a captcha for the given peer UUID.
*
* @param string|RegisteredPeerRecord $peer_uuid The UUID of the peer to answer the captcha for.
* @param string|PeerRecord $peer_uuid The UUID of the peer to answer the captcha for.
* @param string $answer The answer to the captcha.
* @return bool True if the answer is correct, false otherwise.
* @throws DatabaseOperationException If the operation fails.
*/
public static function answerCaptcha(string|RegisteredPeerRecord $peer_uuid, string $answer): bool
public static function answerCaptcha(string|PeerRecord $peer_uuid, string $answer): bool
{
if($peer_uuid instanceof RegisteredPeerRecord)
if($peer_uuid instanceof PeerRecord)
{
$peer_uuid = $peer_uuid->getUuid();
}
@ -129,14 +129,14 @@ class CaptchaManager
/**
* Retrieves the captcha record for the given peer UUID.
*
* @param string|RegisteredPeerRecord $peer_uuid The UUID of the peer to retrieve the captcha for.
* @param string|PeerRecord $peer_uuid The UUID of the peer to retrieve the captcha for.
* @return CaptchaRecord|null The captcha record.
* @throws DatabaseOperationException If the operation fails.
*/
public static function getCaptcha(string|RegisteredPeerRecord $peer_uuid): ?CaptchaRecord
public static function getCaptcha(string|PeerRecord $peer_uuid): ?CaptchaRecord
{
// If the peer_uuid is a RegisteredPeerRecord, get the UUID
if($peer_uuid instanceof RegisteredPeerRecord)
if($peer_uuid instanceof PeerRecord)
{
$peer_uuid = $peer_uuid->getUuid();
}
@ -166,14 +166,14 @@ class CaptchaManager
/**
* Checks if a captcha exists for the given peer UUID.
*
* @param string|RegisteredPeerRecord $peer_uuid The UUID of the peer to check for a captcha.
* @param string|PeerRecord $peer_uuid The UUID of the peer to check for a captcha.
* @return bool True if a captcha exists, false otherwise.
* @throws DatabaseOperationException If the operation fails.
*/
public static function captchaExists(string|RegisteredPeerRecord $peer_uuid): bool
public static function captchaExists(string|PeerRecord $peer_uuid): bool
{
// If the peer_uuid is a RegisteredPeerRecord, get the UUID
if($peer_uuid instanceof RegisteredPeerRecord)
if($peer_uuid instanceof PeerRecord)
{
$peer_uuid = $peer_uuid->getUuid();
}

View file

@ -10,20 +10,20 @@
use Socialbox\Classes\OtpCryptography;
use Socialbox\Exceptions\CryptographyException;
use Socialbox\Exceptions\DatabaseOperationException;
use Socialbox\Objects\Database\RegisteredPeerRecord;
use Socialbox\Objects\Database\PeerRecord;
class OneTimePasswordManager
{
/**
* Checks if a given peer uses OTP for authentication.
*
* @param string|RegisteredPeerRecord $peerUuid Either a UUID as a string or a RegisteredPeerRecord object representing the peer.
* @param string|PeerRecord $peerUuid Either a UUID as a string or a RegisteredPeerRecord object representing the peer.
* @return bool Returns true if the peer uses OTP, otherwise false.
* @throws DatabaseOperationException Thrown when a database error occurs.
*/
public static function usesOtp(string|RegisteredPeerRecord $peerUuid): bool
public static function usesOtp(string|PeerRecord $peerUuid): bool
{
if($peerUuid instanceof RegisteredPeerRecord)
if($peerUuid instanceof PeerRecord)
{
$peerUuid = $peerUuid->getUuid();
}
@ -45,12 +45,12 @@
/**
* Creates and stores a new OTP (One-Time Password) secret for the specified peer, and generates a key URI.
*
* @param string|RegisteredPeerRecord $peer The unique identifier of the peer, either as a string UUID
* @param string|PeerRecord $peer The unique identifier of the peer, either as a string UUID
* or an instance of RegisteredPeerRecord.
* @return string The generated OTP key URI that can be used for applications like authenticator apps.
* @throws DatabaseOperationException If there is an error during the database operation.
*/
public static function createOtp(string|RegisteredPeerRecord $peer): string
public static function createOtp(string|PeerRecord $peer): string
{
if(is_string($peer))
{
@ -84,16 +84,16 @@
/**
* Verifies the provided OTP (One-Time Password) against the stored secret associated with the specified peer.
*
* @param string|RegisteredPeerRecord $peerUuid The unique identifier of the peer, either as a string UUID
* @param string|PeerRecord $peerUuid The unique identifier of the peer, either as a string UUID
* or an instance of RegisteredPeerRecord.
* @param string $otp The OTP to be verified.
* @return bool Returns true if the OTP is valid; otherwise, false.
* @throws DatabaseOperationException If there is an error during the database operation.
* @throws CryptographyException If there is a failure in decrypting the stored OTP secret.
*/
public static function verifyOtp(string|RegisteredPeerRecord $peerUuid, string $otp): bool
public static function verifyOtp(string|PeerRecord $peerUuid, string $otp): bool
{
if($peerUuid instanceof RegisteredPeerRecord)
if($peerUuid instanceof PeerRecord)
{
$peerUuid = $peerUuid->getUuid();
}
@ -145,13 +145,13 @@
/**
* Deletes the OTP record associated with the specified peer.
*
* @param string|RegisteredPeerRecord $peerUuid The peer's UUID or an instance of RegisteredPeerRecord whose OTP record needs to be deleted.
* @param string|PeerRecord $peerUuid The peer's UUID or an instance of RegisteredPeerRecord whose OTP record needs to be deleted.
* @return void
* @throws DatabaseOperationException if the database operation fails.
*/
public static function deleteOtp(string|RegisteredPeerRecord $peerUuid): void
public static function deleteOtp(string|PeerRecord $peerUuid): void
{
if($peerUuid instanceof RegisteredPeerRecord)
if($peerUuid instanceof PeerRecord)
{
$peerUuid = $peerUuid->getUuid();
}
@ -171,12 +171,12 @@
/**
* Retrieves the last updated timestamp for the OTP record of the specified peer.
*
* @param string|RegisteredPeerRecord $peerUuid The peer's UUID or an instance of RegisteredPeerRecord whose OTP record's last updated timestamp needs to be retrieved
* @param string|PeerRecord $peerUuid The peer's UUID or an instance of RegisteredPeerRecord whose OTP record's last updated timestamp needs to be retrieved
* @return int The last updated timestamp of the OTP record, or 0 if no such record exists
*/
public static function getLastUpdated(string|RegisteredPeerRecord $peerUuid): int
public static function getLastUpdated(string|PeerRecord $peerUuid): int
{
if($peerUuid instanceof RegisteredPeerRecord)
if($peerUuid instanceof PeerRecord)
{
$peerUuid = $peerUuid->getUuid();
}

View file

@ -10,20 +10,20 @@
use Socialbox\Classes\Database;
use Socialbox\Exceptions\CryptographyException;
use Socialbox\Exceptions\DatabaseOperationException;
use Socialbox\Objects\Database\RegisteredPeerRecord;
use Socialbox\Objects\Database\PeerRecord;
class PasswordManager
{
/**
* Checks if the given peer UUID is associated with a password in the database.
*
* @param string|RegisteredPeerRecord $peerUuid The UUID of the peer, or an instance of RegisteredPeerRecord from which the UUID will be retrieved.
* @param string|PeerRecord $peerUuid The UUID of the peer, or an instance of RegisteredPeerRecord from which the UUID will be retrieved.
* @return bool Returns true if the peer UUID is associated with a password, otherwise false.
* @throws DatabaseOperationException If an error occurs while querying the database.
*/
public static function usesPassword(string|RegisteredPeerRecord $peerUuid): bool
public static function usesPassword(string|PeerRecord $peerUuid): bool
{
if($peerUuid instanceof RegisteredPeerRecord)
if($peerUuid instanceof PeerRecord)
{
$peerUuid = $peerUuid->getUuid();
}
@ -45,15 +45,15 @@
/**
* Sets a secured password for the given peer UUID or registered peer record.
*
* @param string|RegisteredPeerRecord $peerUuid The unique identifier or registered peer record of the user.
* @param string|PeerRecord $peerUuid The unique identifier or registered peer record of the user.
* @param string $hash The plaintext password to be securely stored.
* @return void
* @throws DatabaseOperationException If an error occurs while storing the password in the database.
* @throws CryptographyException If an error occurs during password encryption or hashing.
*/
public static function setPassword(string|RegisteredPeerRecord $peerUuid, string $hash): void
public static function setPassword(string|PeerRecord $peerUuid, string $hash): void
{
if($peerUuid instanceof RegisteredPeerRecord)
if($peerUuid instanceof PeerRecord)
{
$peerUuid = $peerUuid->getUuid();
}
@ -84,15 +84,15 @@
/**
* Updates the secured password associated with the given peer UUID.
*
* @param string|RegisteredPeerRecord $peerUuid The unique identifier or registered peer record of the user.
* @param string|PeerRecord $peerUuid The unique identifier or registered peer record of the user.
* @param string $hash The new password to be stored securely.
* @return void
* @throws DatabaseOperationException If an error occurs while updating the password in the database.
* @throws CryptographyException If an error occurs while encrypting the password or validating the hash.
*/
public static function updatePassword(string|RegisteredPeerRecord $peerUuid, string $hash): void
public static function updatePassword(string|PeerRecord $peerUuid, string $hash): void
{
if($peerUuid instanceof RegisteredPeerRecord)
if($peerUuid instanceof PeerRecord)
{
$peerUuid = $peerUuid->getUuid();
}
@ -124,13 +124,13 @@
/**
* Deletes the stored password for a specific peer.
*
* @param string|RegisteredPeerRecord $peerUuid The unique identifier of the peer, or an instance of RegisteredPeerRecord.
* @param string|PeerRecord $peerUuid The unique identifier of the peer, or an instance of RegisteredPeerRecord.
* @return void
* @throws DatabaseOperationException If an error occurs during the database operation.
*/
public static function deletePassword(string|RegisteredPeerRecord $peerUuid): void
public static function deletePassword(string|PeerRecord $peerUuid): void
{
if($peerUuid instanceof RegisteredPeerRecord)
if($peerUuid instanceof PeerRecord)
{
$peerUuid = $peerUuid->getUuid();
}
@ -150,15 +150,15 @@
/**
* Verifies a given password against a stored password hash for a specific peer.
*
* @param string|RegisteredPeerRecord $peerUuid The unique identifier of the peer, or an instance of RegisteredPeerRecord.
* @param string|PeerRecord $peerUuid The unique identifier of the peer, or an instance of RegisteredPeerRecord.
* @param string $sha512 The SHA-512 hash of the password to be verified.
* @return bool Returns true if the password matches the stored hash; false otherwise.
* @throws CryptographyException If the password hash is invalid or an error occurs during the cryptographic operation.
* @throws DatabaseOperationException If an error occurs during the database operation.
*/
public static function verifyPassword(string|RegisteredPeerRecord $peerUuid, string $sha512): bool
public static function verifyPassword(string|PeerRecord $peerUuid, string $sha512): bool
{
if($peerUuid instanceof RegisteredPeerRecord)
if($peerUuid instanceof PeerRecord)
{
$peerUuid = $peerUuid->getUuid();
}

View file

@ -0,0 +1,282 @@
<?php
namespace Socialbox\Managers;
use PDOException;
use Socialbox\Classes\Configuration;
use Socialbox\Classes\Database;
use Socialbox\Enums\PrivacyState;
use Socialbox\Enums\Types\InformationFieldName;
use Socialbox\Exceptions\DatabaseOperationException;
use Socialbox\Objects\Database\PeerInformationFieldRecord;
use Socialbox\Objects\Database\PeerRecord;
class PeerInformationManager
{
/**
* Adds a property to a peer's information record.
*
* @param string|PeerRecord $peerUuid The UUID of the peer to add the property to.
* @param InformationFieldName $property The name of the property to add.
* @param string $value The value of the property to add.
* @param PrivacyState|null $privacyState The privacy state of the property to add.
*
* @return void
*
* @throws DatabaseOperationException Thrown if the operation fails.
*/
public static function addField(string|PeerRecord $peerUuid, InformationFieldName $property, string $value, ?PrivacyState $privacyState=null): void
{
if($peerUuid instanceof PeerRecord)
{
$peerUuid = $peerUuid->getUuid();
}
if($privacyState === null)
{
$privacyState = match($property)
{
InformationFieldName::DISPLAY_NAME => Configuration::getPoliciesConfiguration()->getDefaultDisplayPicturePrivacy(),
InformationFieldName::FIRST_NAME => Configuration::getPoliciesConfiguration()->getDefaultFirstNamePrivacy(),
InformationFieldName::MIDDLE_NAME => Configuration::getPoliciesConfiguration()->getDefaultMiddleNamePrivacy(),
InformationFieldName::LAST_NAME => Configuration::getPoliciesConfiguration()->getDefaultLastNamePrivacy(),
InformationFieldName::EMAIL_ADDRESS => Configuration::getPoliciesConfiguration()->getDefaultEmailAddressPrivacy(),
InformationFieldName::PHONE_NUMBER => Configuration::getPoliciesConfiguration()->getDefaultPhoneNumberPrivacy(),
InformationFieldName::BIRTHDAY => Configuration::getPoliciesConfiguration()->getDefaultBirthdayPrivacy(),
InformationFieldName::DISPLAY_PICTURE => COnfiguration::getPoliciesConfiguration()->getDefaultDisplayPicturePrivacy(),
InformationFieldName::URL => Configuration::getPoliciesConfiguration()->getDefaultUrlPrivacy(),
};
}
try
{
$stmt = Database::getConnection()->prepare('INSERT INTO peer_information (peer_uuid, property_name, property_value, privacy_state) VALUES (:peer_uuid, :property_name, :property_value, :privacy_state)');
$stmt->bindValue(':peer_uuid', $peerUuid);
$propertyName = $property->value;
$stmt->bindValue(':property_name', $propertyName);
$stmt->bindValue(':property_value', $value);
$stmt->bindValue(':privacy_state', $privacyState->value);
$stmt->execute();
}
catch(PDOException $e)
{
throw new DatabaseOperationException(sprintf('Failed to add property for peer %s', $peerUuid), $e);
}
}
/**
* Updates a property for a peer's information record.
*
* @param string|PeerRecord $peerUuid The UUID of the peer to update the property for.
* @param InformationFieldName $property The name of the property to update.
* @param string $value The new value of the property.
*
* @return void
*
* @throws DatabaseOperationException Thrown if the operation fails.
*/
public static function updateField(string|PeerRecord $peerUuid, InformationFieldName $property, string $value): void
{
if($peerUuid instanceof PeerRecord)
{
$peerUuid = $peerUuid->getUuid();
}
if(!self::fieldExists($peerUuid, $property))
{
throw new DatabaseOperationException(sprintf('Cannot to update property %s for peer %s, property does not exist', $property->value, $peerUuid));
}
try
{
$stmt = Database::getConnection()->prepare('UPDATE peer_information SET property_value=:property_value WHERE peer_uuid=:peer_uuid AND property_name=:property_name');
$stmt->bindValue(':peer_uuid', $peerUuid);
$propertyName = $property->value;
$stmt->bindValue(':property_name', $propertyName);
$stmt->bindValue(':property_value', $value);
$stmt->execute();
}
catch(PDOException $e)
{
throw new DatabaseOperationException(sprintf('Failed to update property %s for peer %s', $property->value, $peerUuid), $e);
}
}
/**
* Updates the privacy state for a property in a peer's information record.
*
* @param string|PeerRecord $peerUuid The UUID of the peer to update the privacy state for.
* @param InformationFieldName $property The name of the property to update the privacy state for.
* @param PrivacyState $privacyState The new privacy state of the property.
*
* @return void
*
* @throws DatabaseOperationException Thrown if the operation fails.
*/
public static function updatePrivacyState(string|PeerRecord $peerUuid, InformationFieldName $property, PrivacyState $privacyState): void
{
if($peerUuid instanceof PeerRecord)
{
$peerUuid = $peerUuid->getUuid();
}
if(!self::fieldExists($peerUuid, $property))
{
throw new \InvalidArgumentException(sprintf('Cannot update privacy state, the requested property %s does not exist with %s', $property->value, $peerUuid));
}
try
{
$stmt = Database::getConnection()->prepare('UPDATE peer_information SET privacy_state=:privacy_state WHERE peer_uuid=:peer_uuid AND property_name=:property_name');
$stmt->bindValue(':peer_uuid', $peerUuid);
$propertyName = $property->value;
$stmt->bindValue(':property_name', $propertyName);
$privacyState = $privacyState->value;
$stmt->bindValue(':privacy_state', $privacyState);
$stmt->execute();
}
catch(PDOException $e)
{
throw new DatabaseOperationException(sprintf('Failed to update privacy state for property %s for peer %s', $property->value, $peerUuid), $e);
}
}
/**
* Checks if a property exists for a peer.
*
* @param string|PeerRecord $peerUuid The UUID of the peer to check for the property.
* @param InformationFieldName $property The name of the property to check for.
*
* @return bool
*
* @throws DatabaseOperationException Thrown if the operation fails.
*/
public static function fieldExists(string|PeerRecord $peerUuid, InformationFieldName $property): bool
{
if($peerUuid instanceof PeerRecord)
{
$peerUuid = $peerUuid->getUuid();
}
try
{
$stmt = Database::getConnection()->prepare('SELECT COUNT(*) FROM peer_information WHERE peer_uuid=:peer_uuid AND property_name=:property_name LIMIT 1');
$stmt->bindValue(':peer_uuid', $peerUuid);
$propertyName = $property->value;
$stmt->bindValue(':property_name', $propertyName);
$stmt->execute();
return $stmt->fetchColumn() > 0;
}
catch(PDOException $e)
{
throw new DatabaseOperationException(sprintf('Failed to check if property exists for peer %s', $peerUuid), $e);
}
}
/**
* Gets a property from a peer's information record.
*
* @param string|PeerRecord $peerUuid The UUID of the peer to get the property from.
* @param InformationFieldName $property The name of the property to get.
*
* @return PeerInformationFieldRecord
*
* @throws DatabaseOperationException Thrown if the operation fails.
*/
public static function getField(string|PeerRecord $peerUuid, InformationFieldName $property): PeerInformationFieldRecord
{
if($peerUuid instanceof PeerRecord)
{
$peerUuid = $peerUuid->getUuid();
}
try
{
$stmt = Database::getConnection()->prepare('SELECT * FROM peer_information WHERE peer_uuid=:peer_uuid AND property_name=:property_name LIMIT 1');
$stmt->bindValue(':peer_uuid', $peerUuid);
$propertyName = $property->value;
$stmt->bindValue(':property_name', $propertyName);
$stmt->execute();
$result = $stmt->fetch();
if($result === false)
{
throw new DatabaseOperationException(sprintf('Property %s does not exist for peer %s', $property->value, $peerUuid));
}
return PeerInformationFieldRecord::fromArray($result);
}
catch(PDOException $e)
{
throw new DatabaseOperationException(sprintf('Failed to get property %s for peer %s', $property->value, $peerUuid), $e);
}
}
/**
* Gets all properties from a peer's information record.
*
* @param string|PeerRecord $peerUuid The UUID of the peer to get the properties from.
*
* @return PeerInformationFieldRecord[]
*
* @throws DatabaseOperationException Thrown if the operation fails.
*/
public static function getFields(string|PeerRecord $peerUuid): array
{
if($peerUuid instanceof PeerRecord)
{
$peerUuid = $peerUuid->getUuid();
}
try
{
$stmt = Database::getConnection()->prepare('SELECT * FROM peer_information WHERE peer_uuid=:peer_uuid');
$stmt->bindValue(':peer_uuid', $peerUuid);
$stmt->execute();
$results = $stmt->fetchAll();
if(!$results)
{
return [];
}
return array_map(fn($result) => PeerInformationFieldRecord::fromArray($result), $results);
}
catch(PDOException $e)
{
throw new DatabaseOperationException(sprintf('Failed to get properties for peer %s', $peerUuid), $e);
}
}
/**
* Deletes a property from a peer's information record.
*
* @param string|PeerRecord $peerUuid The UUID of the peer to delete the property from.
* @param InformationFieldName $property The name of the property to delete.
*
* @return void
*
* @throws DatabaseOperationException Thrown if the operation fails.
*/
public static function deleteField(string|PeerRecord $peerUuid, InformationFieldName $property): void
{
if($peerUuid instanceof PeerRecord)
{
$peerUuid = $peerUuid->getUuid();
}
try
{
$stmt = Database::getConnection()->prepare('DELETE FROM peer_information WHERE peer_uuid=:peer_uuid AND property_name=:property_name');
$stmt->bindValue(':peer_uuid', $peerUuid);
$propertyName = $property->value;
$stmt->bindValue(':property_name', $propertyName);
$stmt->execute();
}
catch(PDOException $e)
{
throw new DatabaseOperationException(sprintf('Failed to delete property %s for peer %s', $property->value, $peerUuid), $e);
}
}
}

View file

@ -10,11 +10,10 @@
use Socialbox\Classes\Configuration;
use Socialbox\Classes\Database;
use Socialbox\Classes\Logger;
use Socialbox\Classes\Validator;
use Socialbox\Enums\Flags\PeerFlags;
use Socialbox\Enums\ReservedUsernames;
use Socialbox\Exceptions\DatabaseOperationException;
use Socialbox\Objects\Database\RegisteredPeerRecord;
use Socialbox\Objects\Database\PeerRecord;
use Socialbox\Objects\PeerAddress;
use Socialbox\Objects\Standard\Peer;
use Symfony\Component\Uid\Uuid;
@ -34,7 +33,7 @@
try
{
$statement = Database::getConnection()->prepare('SELECT COUNT(*) FROM `registered_peers` WHERE username=?');
$statement = Database::getConnection()->prepare('SELECT COUNT(*) FROM peers WHERE username=?');
$statement->bindParam(1, $username);
$statement->execute();
@ -68,7 +67,7 @@
try
{
$statement = Database::getConnection()->prepare('INSERT INTO `registered_peers` (uuid, username, server, enabled) VALUES (?, ?, ?, ?)');
$statement = Database::getConnection()->prepare('INSERT INTO peers (uuid, username, server, enabled) VALUES (?, ?, ?, ?)');
$statement->bindParam(1, $uuid);
$username = $peerAddress->getUsername();
$statement->bindParam(2, $username);
@ -88,13 +87,13 @@
* Deletes a peer from the database based on the given UUID or RegisteredPeerRecord.
* WARNING: This operation is cascading and will delete all associated data.
*
* @param string|RegisteredPeerRecord $uuid The UUID or RegisteredPeerRecord instance representing the peer to be deleted.
* @param string|PeerRecord $uuid The UUID or RegisteredPeerRecord instance representing the peer to be deleted.
* @return void
* @throws DatabaseOperationException If the operation fails.
*/
public static function deletePeer(string|RegisteredPeerRecord $uuid): void
public static function deletePeer(string|PeerRecord $uuid): void
{
if($uuid instanceof RegisteredPeerRecord)
if($uuid instanceof PeerRecord)
{
$uuid = $uuid->getUuid();
}
@ -103,7 +102,7 @@
try
{
$statement = Database::getConnection()->prepare('DELETE FROM `registered_peers` WHERE uuid=?');
$statement = Database::getConnection()->prepare('DELETE FROM peers WHERE uuid=?');
$statement->bindParam(1, $uuid);
$statement->execute();
}
@ -116,13 +115,13 @@
/**
* Retrieves a registered peer record based on the given unique identifier or RegisteredPeerRecord object.
*
* @param string|RegisteredPeerRecord $uuid The unique identifier of the registered peer, or an instance of RegisteredPeerRecord.
* @return RegisteredPeerRecord Returns a RegisteredPeerRecord object containing the peer's information.
* @param string|PeerRecord $uuid The unique identifier of the registered peer, or an instance of RegisteredPeerRecord.
* @return PeerRecord Returns a RegisteredPeerRecord object containing the peer's information.
* @throws DatabaseOperationException If there is an error during the database operation.
*/
public static function getPeer(string|RegisteredPeerRecord $uuid): RegisteredPeerRecord
public static function getPeer(string|PeerRecord $uuid): PeerRecord
{
if($uuid instanceof RegisteredPeerRecord)
if($uuid instanceof PeerRecord)
{
$uuid = $uuid->getUuid();
}
@ -131,7 +130,7 @@
try
{
$statement = Database::getConnection()->prepare('SELECT * FROM `registered_peers` WHERE uuid=?');
$statement = Database::getConnection()->prepare('SELECT * FROM peers WHERE uuid=?');
$statement->bindParam(1, $uuid);
$statement->execute();
@ -142,7 +141,7 @@
throw new DatabaseOperationException(sprintf("The requested peer '%s' does not exist", $uuid));
}
return new RegisteredPeerRecord($result);
return new PeerRecord($result);
}
catch(Exception $e)
{
@ -154,16 +153,16 @@
* Retrieves a peer record by the given username.
*
* @param PeerAddress $address The address of the peer to be retrieved.
* @return RegisteredPeerRecord|null The record of the peer associated with the given username.
* @return PeerRecord|null The record of the peer associated with the given username.
* @throws DatabaseOperationException If there is an error while querying the database.
*/
public static function getPeerByAddress(PeerAddress $address): ?RegisteredPeerRecord
public static function getPeerByAddress(PeerAddress $address): ?PeerRecord
{
Logger::getLogger()->verbose(sprintf("Retrieving peer %s from the database", $address->getAddress()));
try
{
$statement = Database::getConnection()->prepare('SELECT * FROM `registered_peers` WHERE username=? AND server=?');
$statement = Database::getConnection()->prepare('SELECT * FROM peers WHERE username=? AND server=?');
$username = $address->getUsername();
$statement->bindParam(1, $username);
$server = $address->getDomain();
@ -184,7 +183,7 @@
return null;
}
return new RegisteredPeerRecord($result);
return new PeerRecord($result);
}
catch(Exception $e)
{
@ -223,13 +222,11 @@
try
{
$statement = Database::getConnection()->prepare('UPDATE `registered_peers` SET display_name=?, updated=? WHERE uuid=?');
$displayName = $peer->getDisplayName();
$statement->bindParam(1, $displayName);
$statement = Database::getConnection()->prepare('UPDATE peers SET updated=? WHERE uuid=?');
$updated = new DateTime();
$statement->bindParam(2, $updated);
$statement->bindParam(':updated', $updated);
$uuid = $existingPeer->getUuid();
$statement->bindParam(3, $uuid);
$statement->bindParam(':uuid', $uuid);
$statement->execute();
}
catch(PDOException $e)
@ -244,14 +241,12 @@
try
{
$statement = Database::getConnection()->prepare('INSERT INTO `registered_peers` (uuid, username, server, display_name, enabled) VALUES (:uuid, :username, :server, :display_name, 1)');
$statement = Database::getConnection()->prepare('INSERT INTO peers (uuid, username, server, enabled) VALUES (:uuid, :username, :server, 1)');
$statement->bindParam(':uuid', $uuid);
$username = $peer->getAddress()->getUsername();
$statement->bindParam(':username', $username);
$server = $peer->getAddress()->getDomain();
$statement->bindParam(':server', $server);
$displayName = $peer->getDisplayName();
$statement->bindParam(':display_name', $displayName);
$statement->execute();
}
@ -264,13 +259,13 @@
/**
* Enables a peer identified by the given UUID or RegisteredPeerRecord.
*
* @param string|RegisteredPeerRecord $uuid The UUID or RegisteredPeerRecord instance representing the peer to be enabled.
* @param string|PeerRecord $uuid The UUID or RegisteredPeerRecord instance representing the peer to be enabled.
* @return void
* @throws DatabaseOperationException If there is an error while updating the database.
*/
public static function enablePeer(string|RegisteredPeerRecord $uuid): void
public static function enablePeer(string|PeerRecord $uuid): void
{
if($uuid instanceof RegisteredPeerRecord)
if($uuid instanceof PeerRecord)
{
$uuid = $uuid->getUuid();
}
@ -279,7 +274,7 @@
try
{
$statement = Database::getConnection()->prepare('UPDATE `registered_peers` SET enabled=1 WHERE uuid=?');
$statement = Database::getConnection()->prepare('UPDATE peers SET enabled=1 WHERE uuid=?');
$statement->bindParam(1, $uuid);
$statement->execute();
}
@ -292,13 +287,13 @@
/**
* Disables the peer identified by the given UUID or RegisteredPeerRecord.
*
* @param string|RegisteredPeerRecord $uuid The UUID or RegisteredPeerRecord instance representing the peer.
* @param string|PeerRecord $uuid The UUID or RegisteredPeerRecord instance representing the peer.
* @return void
* @throws DatabaseOperationException If there is an error while updating the peer's status in the database.
*/
public static function disablePeer(string|RegisteredPeerRecord $uuid): void
public static function disablePeer(string|PeerRecord $uuid): void
{
if($uuid instanceof RegisteredPeerRecord)
if($uuid instanceof PeerRecord)
{
$uuid = $uuid->getUuid();
}
@ -307,7 +302,7 @@
try
{
$statement = Database::getConnection()->prepare('UPDATE `registered_peers` SET enabled=0 WHERE uuid=?');
$statement = Database::getConnection()->prepare('UPDATE peers SET enabled=0 WHERE uuid=?');
$statement->bindParam(1, $uuid);
$statement->execute();
}
@ -320,14 +315,14 @@
/**
* Adds a specific flag to the peer identified by the given UUID or RegisteredPeerRecord.
*
* @param string|RegisteredPeerRecord $uuid The UUID or RegisteredPeerRecord instance representing the peer.
* @param string|PeerRecord $uuid The UUID or RegisteredPeerRecord instance representing the peer.
* @param PeerFlags|array $flags The flag or array of flags to be added to the peer.
* @return void
* @throws DatabaseOperationException If there is an error while updating the database.
*/
public static function addFlag(string|RegisteredPeerRecord $uuid, PeerFlags|array $flags): void
public static function addFlag(string|PeerRecord $uuid, PeerFlags|array $flags): void
{
if($uuid instanceof RegisteredPeerRecord)
if($uuid instanceof PeerRecord)
{
$uuid = $uuid->getUuid();
}
@ -349,7 +344,7 @@
try
{
$implodedFlags = implode(',', array_map(fn($flag) => $flag->name, $existingFlags));
$statement = Database::getConnection()->prepare('UPDATE `registered_peers` SET flags=? WHERE uuid=?');
$statement = Database::getConnection()->prepare('UPDATE peers SET flags=? WHERE uuid=?');
$statement->bindParam(1, $implodedFlags);
$statement->bindParam(2, $uuid);
$statement->execute();
@ -363,12 +358,12 @@
/**
* Removes a specific flag from the peer identified by the given UUID or RegisteredPeerRecord.
*
* @param string|RegisteredPeerRecord $peer
* @param string|PeerRecord $peer
* @param PeerFlags $flag The flag to be removed from the peer.
* @return void
* @throws DatabaseOperationException If there is an error while updating the database.
*/
public static function removeFlag(string|RegisteredPeerRecord $peer, PeerFlags $flag): void
public static function removeFlag(string|PeerRecord $peer, PeerFlags $flag): void
{
if(is_string($peer))
{
@ -387,7 +382,7 @@
try
{
$implodedFlags = PeerFlags::toString($peer->getFlags());
$statement = Database::getConnection()->prepare('UPDATE `registered_peers` SET flags=? WHERE uuid=?');
$statement = Database::getConnection()->prepare('UPDATE peers SET flags=? WHERE uuid=?');
$statement->bindParam(1, $implodedFlags);
$statement->bindParam(2, $registeredPeer);
$statement->execute();
@ -397,435 +392,4 @@
throw new DatabaseOperationException('Failed to remove the flag from the peer in the database', $e);
}
}
/**
* Updates the display name of a registered peer based on the given unique identifier or RegisteredPeerRecord object.
*
* @param string|RegisteredPeerRecord $peer The unique identifier of the registered peer, or an instance of RegisteredPeerRecord.
* @param string $name The new display name to set to the user
* @throws DatabaseOperationException Thrown if there was an error while trying to update the display name
*/
public static function updateDisplayName(string|RegisteredPeerRecord $peer, string $name): void
{
if(empty($name))
{
throw new InvalidArgumentException('The display name cannot be empty');
}
if(strlen($name) > 256)
{
throw new InvalidArgumentException('The display name cannot exceed 256 characters');
}
if(is_string($peer))
{
$peer = self::getPeer($peer);
}
if($peer->isExternal())
{
throw new InvalidArgumentException('Cannot update the display name of an external peer');
}
Logger::getLogger()->verbose(sprintf("Updating display name of peer %s to %s", $peer->getUuid(), $name));
try
{
$statement = Database::getConnection()->prepare('UPDATE `registered_peers` SET display_name=? WHERE uuid=?');
$statement->bindParam(1, $name);
$uuid = $peer->getUuid();
$statement->bindParam(2, $uuid);
$statement->execute();
}
catch(PDOException $e)
{
throw new DatabaseOperationException('Failed to update the display name of the peer in the database', $e);
}
}
/**
* Deletes the display name of a registered peer identified by a unique identifier or RegisteredPeerRecord object.
*
* @param string|RegisteredPeerRecord $peer The unique identifier of the registered peer, or an instance of RegisteredPeerRecord.
* @return void
* @throws InvalidArgumentException If the peer is external and its display name cannot be deleted.
* @throws DatabaseOperationException If there is an error during the database operation.
*/
public static function deleteDisplayName(string|RegisteredPeerRecord $peer): void
{
if(is_string($peer))
{
$peer = self::getPeer($peer);
}
if($peer->isExternal())
{
throw new InvalidArgumentException('Cannot delete the display name of an external peer');
}
Logger::getLogger()->verbose(sprintf("Deleting display name of peer %s", $peer->getUuid()));
try
{
$statement = Database::getConnection()->prepare('UPDATE `registered_peers` SET display_name=NULL WHERE uuid=?');
$uuid = $peer->getUuid();
$statement->bindParam(1, $uuid);
$statement->execute();
}
catch(PDOException $e)
{
throw new DatabaseOperationException('Failed to delete the display name of the peer in the database', $e);
}
}
/**
* Updates the display picture of a registered peer in the database.
*
* @param string|RegisteredPeerRecord $peer The unique identifier of the peer or an instance of RegisteredPeerRecord.
* @param string $displayPictureData The raw jpeg data of the display picture.
* @return void
* @throws DatabaseOperationException If there is an error during the database operation.
*/
public static function updateDisplayPicture(string|RegisteredPeerRecord $peer, string $displayPictureData): void
{
if(empty($uuid))
{
throw new InvalidArgumentException('The display picture UUID cannot be empty');
}
$uuid = Uuid::v4()->toRfc4122();
$displayPicturePath = Configuration::getStorageConfiguration()->getUserDisplayImagesPath() . DIRECTORY_SEPARATOR . $uuid . '.jpeg';
// Delete the file if it already exists
if(file_exists($displayPicturePath))
{
unlink($displayPicturePath);
}
// Write the file contents & set the permissions
file_put_contents($displayPicturePath, $displayPictureData);
chmod($displayPicturePath, 0644);
if(is_string($peer))
{
$peer = self::getPeer($peer);
}
// TODO: Handle for external peers, needs a way to resolve peers to their external counterparts
if($peer->isExternal())
{
throw new InvalidArgumentException('Cannot update the display picture of an external peer');
}
Logger::getLogger()->verbose(sprintf("Updating display picture of peer %s to %s", $peer->getUuid(), $uuid));
try
{
$statement = Database::getConnection()->prepare('UPDATE `registered_peers` SET display_picture=? WHERE uuid=?');
$statement->bindParam(1, $uuid);
$peerUuid = $peer->getUuid();
$statement->bindParam(2, $peerUuid);
$statement->execute();
}
catch(PDOException $e)
{
throw new DatabaseOperationException('Failed to update the display picture of the peer in the database', $e);
}
}
/**
* Deletes the display picture of a registered peer based on the given unique identifier or RegisteredPeerRecord object.
*
* @param string|RegisteredPeerRecord $peer The unique identifier of the registered peer, or an instance of RegisteredPeerRecord.
* @return void
* @throws InvalidArgumentException If the peer is external and its display picture cannot be deleted.
* @throws DatabaseOperationException If there is an error during the database operation.
*/
public static function deleteDisplayPicture(string|RegisteredPeerRecord $peer): void
{
if(is_string($peer))
{
$peer = self::getPeer($peer);
}
if($peer->isExternal())
{
// TODO: Implement this
throw new InvalidArgumentException('Cannot delete the display picture of an external peer');
}
Logger::getLogger()->verbose(sprintf("Deleting display picture of peer %s", $peer->getUuid()));
// Delete the file if it exists
$displayPicturePath = Configuration::getStorageConfiguration()->getUserDisplayImagesPath() . DIRECTORY_SEPARATOR . $peer->getDisplayPicture() . '.jpeg';
if(file_exists($displayPicturePath))
{
unlink($displayPicturePath);
}
try
{
$statement = Database::getConnection()->prepare('UPDATE `registered_peers` SET display_picture=NULL WHERE uuid=?');
$uuid = $peer->getUuid();
$statement->bindParam(1, $uuid);
$statement->execute();
}
catch(PDOException $e)
{
throw new DatabaseOperationException('Failed to delete the display picture of the peer in the database', $e);
}
}
/**
* Updates the email address of a registered peer.
*
* @param string|RegisteredPeerRecord $peer The unique identifier of the peer, or an instance of RegisteredPeerRecord.
* @param string $emailAddress The new email address to be assigned to the peer.
* @return void
* @throws InvalidArgumentException If the email address is empty, exceeds 256 characters, is not a valid email format, or if the peer is external.
* @throws DatabaseOperationException If there is an error during the database operation.
*/
public static function updateEmailAddress(string|RegisteredPeerRecord $peer, string $emailAddress): void
{
if(empty($emailAddress))
{
throw new InvalidArgumentException('The email address cannot be empty');
}
if(strlen($emailAddress) > 256)
{
throw new InvalidArgumentException('The email address cannot exceed 256 characters');
}
if(filter_var($emailAddress, FILTER_VALIDATE_EMAIL) === false)
{
throw new InvalidArgumentException('The email address is not valid');
}
if(is_string($peer))
{
$peer = self::getPeer($peer);
}
if($peer->isExternal())
{
throw new InvalidArgumentException('Cannot update the email address of an external peer');
}
Logger::getLogger()->verbose(sprintf("Updating email address of peer %s to %s", $peer->getUuid(), $emailAddress));
try
{
$statement = Database::getConnection()->prepare('UPDATE `registered_peers` SET email_address=? WHERE uuid=?');
$statement->bindParam(1, $emailAddress);
$uuid = $peer->getUuid();
$statement->bindParam(2, $uuid);
$statement->execute();
}
catch(PDOException $e)
{
throw new DatabaseOperationException('Failed to update the email address of the peer in the database', $e);
}
}
/**
* Deletes the email address of a registered peer identified by either a unique identifier or a RegisteredPeerRecord object.
*
* @param string|RegisteredPeerRecord $peer The unique identifier of the registered peer, or an instance of RegisteredPeerRecord.
* @return void
* @throws InvalidArgumentException If the peer is external and its email address cannot be deleted.
* @throws DatabaseOperationException If there is an error during the database operation.
*/
public static function deleteEmailAddress(string|RegisteredPeerRecord $peer): void
{
if(is_string($peer))
{
$peer = self::getPeer($peer);
}
if($peer->isExternal())
{
throw new InvalidArgumentException('Cannot delete the email address of an external peer');
}
Logger::getLogger()->verbose(sprintf("Deleting email address of peer %s", $peer->getUuid()));
try
{
$statement = Database::getConnection()->prepare('UPDATE `registered_peers` SET email_address=NULL WHERE uuid=?');
$uuid = $peer->getUuid();
$statement->bindParam(1, $uuid);
$statement->execute();
}
catch(PDOException $e)
{
throw new DatabaseOperationException('Failed to delete the email address of the peer in the database', $e);
}
}
/**
* Updates the phone number of the specified registered peer.
*
* @param string|RegisteredPeerRecord $peer The unique identifier of the registered peer, or an instance of RegisteredPeerRecord.
* @param string $phoneNumber The new phone number to be set for the peer.
* @return void
* @throws InvalidArgumentException If the phone number is empty, exceeds 16 characters, is invalid, or if the peer is external.
* @throws DatabaseOperationException If there is an error during the database operation.
*/
public static function updatePhoneNumber(string|RegisteredPeerRecord $peer, string $phoneNumber): void
{
if(empty($phoneNumber))
{
throw new InvalidArgumentException('The phone number cannot be empty');
}
if(strlen($phoneNumber) > 16)
{
throw new InvalidArgumentException('The phone number cannot exceed 16 characters');
}
if(!Validator::validatePhoneNumber($phoneNumber))
{
throw new InvalidArgumentException('The phone number is not valid');
}
if(is_string($peer))
{
$peer = self::getPeer($peer);
}
if($peer->isExternal())
{
throw new InvalidArgumentException('Cannot update the phone number of an external peer');
}
Logger::getLogger()->verbose(sprintf("Updating phone number of peer %s to %s", $peer->getUuid(), $phoneNumber));
try
{
$statement = Database::getConnection()->prepare('UPDATE `registered_peers` SET phone_number=? WHERE uuid=?');
$statement->bindParam(1, $phoneNumber);
$uuid = $peer->getUuid();
$statement->bindParam(2, $uuid);
$statement->execute();
}
catch(PDOException $e)
{
throw new DatabaseOperationException('Failed to update the phone number of the peer in the database', $e);
}
}
/**
* Deletes the phone number of a registered peer based on the given unique identifier or RegisteredPeerRecord object.
*
* @param string|RegisteredPeerRecord $peer The unique identifier of the registered peer, or an instance of RegisteredPeerRecord.
* @return void This method does not return a value.
* @throws InvalidArgumentException If the peer is external and its phone number cannot be deleted.
* @throws DatabaseOperationException If there is an error during the database operation.
*/
public static function deletePhoneNumber(string|RegisteredPeerRecord $peer): void
{
if(is_string($peer))
{
$peer = self::getPeer($peer);
}
if($peer->isExternal())
{
throw new InvalidArgumentException('Cannot delete the phone number of an external peer');
}
Logger::getLogger()->verbose(sprintf("Deleting phone number of peer %s", $peer->getUuid()));
try
{
$statement = Database::getConnection()->prepare('UPDATE `registered_peers` SET phone_number=NULL WHERE uuid=?');
$uuid = $peer->getUuid();
$statement->bindParam(1, $uuid);
$statement->execute();
}
catch(PDOException $e)
{
throw new DatabaseOperationException('Failed to delete the phone number of the peer in the database', $e);
}
}
/**
* Sets the birthday of a registered peer record based on the provided date components.
*
* @param string|RegisteredPeerRecord $peer The unique identifier of the peer or an instance of RegisteredPeerRecord.
* @param int $month The month component of the birthday.
* @param int $day The day component of the birthday.
* @param int $year The year component of the birthday.
* @return void
* @throws InvalidArgumentException If the peer is external or the provided date is invalid.
* @throws DatabaseOperationException If there is an error during the database operation.
*/
public static function updateBirthday(string|RegisteredPeerRecord $peer, int $month, int $day, int $year): void
{
if(is_string($peer))
{
$peer = self::getPeer($peer);
}
if($peer->isExternal())
{
throw new InvalidArgumentException('Cannot set the birthday of an external peer');
}
if(!Validator::validateDate($month, $day, $year))
{
throw new InvalidArgumentException('The provided date is not valid');
}
Logger::getLogger()->verbose(sprintf("Setting birthday of peer %s to %d-%d-%d", $peer->getUuid(), $year, $month, $day));
try
{
$statement = Database::getConnection()->prepare('UPDATE `registered_peers` SET birthday=? WHERE uuid=?');
$birthday = (new DateTime())->setDate($year, $month, $day)->format('Y-m-d');
$statement->bindParam(1, $birthday);
$uuid = $peer->getUuid();
$statement->bindParam(2, $uuid);
$statement->execute();
}
catch(PDOException $e)
{
throw new DatabaseOperationException('Failed to set the birthday of the peer in the database', $e);
}
}
/**
* Deletes the birthday of a registered peer based on the given unique identifier or RegisteredPeerRecord object.
*
* @param string|RegisteredPeerRecord $peer The unique identifier of the registered peer, or an instance of RegisteredPeerRecord.
* @throws InvalidArgumentException If the peer is marked as external and cannot have its birthday deleted.
* @throws DatabaseOperationException If there is an error during the database operation.
*/
public static function deleteBirthday(string|RegisteredPeerRecord $peer): void
{
if(is_string($peer))
{
$peer = self::getPeer($peer);
}
if($peer->isExternal())
{
throw new InvalidArgumentException('Cannot delete the birthday of an external peer');
}
Logger::getLogger()->verbose(sprintf("Deleting birthday of peer %s", $peer->getUuid()));
try
{
$statement = Database::getConnection()->prepare('UPDATE `registered_peers` SET birthday=NULL WHERE uuid=?');
$uuid = $peer->getUuid();
$statement->bindParam(1, $uuid);
$statement->execute();
}
catch(PDOException $e)
{
throw new DatabaseOperationException('Failed to delete the birthday of the peer in the database', $e);
}
}
}

View file

@ -16,7 +16,7 @@
use Socialbox\Enums\StandardError;
use Socialbox\Exceptions\DatabaseOperationException;
use Socialbox\Exceptions\StandardException;
use Socialbox\Objects\Database\RegisteredPeerRecord;
use Socialbox\Objects\Database\PeerRecord;
use Socialbox\Objects\Database\SessionRecord;
use Socialbox\Objects\KeyPair;
use Symfony\Component\Uid\Uuid;
@ -26,7 +26,7 @@
/**
* Creates a new session for a given peer and client details, and stores it in the database.
*
* @param RegisteredPeerRecord $peer The peer record for which the session is being created.
* @param PeerRecord $peer The peer record for which the session is being created.
* @param string $clientName The name of the client application.
* @param string $clientVersion The version of the client application.
* @param string $clientPublicSigningKey The client's public signing key, which must be a valid Ed25519 key.
@ -36,7 +36,7 @@
* @throws InvalidArgumentException If the provided public signing key or encryption key is invalid.
* @throws DatabaseOperationException If there is an error during the session creation in the database.
*/
public static function createSession(RegisteredPeerRecord $peer, string $clientName, string $clientVersion, string $clientPublicSigningKey, string $clientPublicEncryptionKey, KeyPair $serverEncryptionKeyPair): string
public static function createSession(PeerRecord $peer, string $clientName, string $clientVersion, string $clientPublicSigningKey, string $clientPublicEncryptionKey, KeyPair $serverEncryptionKeyPair): string
{
if($clientPublicSigningKey === '' || Cryptography::validatePublicSigningKey($clientPublicSigningKey) === false)
{