From 6f9c2ef5178c0e9f302091d196d3abf0d4f4c01b Mon Sep 17 00:00:00 2001 From: netkas Date: Wed, 29 Jan 2025 15:42:11 -0500 Subject: [PATCH] Added additional methods and updated the return type for some of the existing methods --- src/Socialbox/SocialClient.php | 246 +++++++++++++++++++++++++++------ 1 file changed, 201 insertions(+), 45 deletions(-) diff --git a/src/Socialbox/SocialClient.php b/src/Socialbox/SocialClient.php index cf6cb70..0295c0b 100644 --- a/src/Socialbox/SocialClient.php +++ b/src/Socialbox/SocialClient.php @@ -14,13 +14,18 @@ use Socialbox\Exceptions\DatabaseOperationException; use Socialbox\Exceptions\ResolutionException; use Socialbox\Exceptions\RpcException; - use Socialbox\Objects\ExportedSession; + use Socialbox\Objects\Client\ExportedSession; + use Socialbox\Objects\Client\SignatureKeyPair; use Socialbox\Objects\PeerAddress; use Socialbox\Objects\RpcRequest; + use Socialbox\Objects\Standard\ExternalUrlVerification; + use Socialbox\Objects\Standard\ImageCaptchaVerification; use Socialbox\Objects\Standard\InformationField; use Socialbox\Objects\Standard\Peer; use Socialbox\Objects\Standard\ServerDocument; use Socialbox\Objects\Standard\SessionState; + use Socialbox\Objects\Standard\SigningKey; + use Socialbox\Objects\Standard\TextCaptchaVerification; class SocialClient extends RpcClient { @@ -160,16 +165,13 @@ /** * Sends a verification email to the specified email address by making a remote procedure call request. * - * @param string $emailAddress The email address to which the verification email will be sent. * @return true Indicates the successful initiation of the verification process. * @throws RpcException Thrown if the RPC request fails. */ - public function verificationEmail(string $emailAddress): true + public function verificationEmail(): true { return (bool)$this->sendRequest( - new RpcRequest(StandardMethods::VERIFICATION_EMAIL, Utilities::randomCrc32(), [ - 'email_address' => $emailAddress - ]) + new RpcRequest(StandardMethods::VERIFICATION_EMAIL, Utilities::randomCrc32()) )->getResponse()->getResult(); } @@ -192,16 +194,13 @@ /** * Sends a verification SMS to the specified phone number by initiating a remote procedure call. * - * @param string $phoneNumber The phone number to which the verification SMS should be sent. * @return true True if the SMS was sent successfully. * @throws RpcException Thrown if the RPC request fails. */ - public function verificationSms(string $phoneNumber): true + public function verificationSms(): true { return (bool)$this->sendRequest( - new RpcRequest(StandardMethods::VERIFICATION_SMS, Utilities::randomCrc32(), [ - 'phone_number' => $phoneNumber - ]) + new RpcRequest(StandardMethods::VERIFICATION_SMS, Utilities::randomCrc32()) )->getResponse()->getResult(); } @@ -224,16 +223,13 @@ /** * Initiates a phone verification process by sending a remote procedure call request. * - * @param string $phoneNumber The phone number to be verified. * @return bool True if the phone verification request was successful. * @throws RpcException Thrown if the RPC request fails. */ - public function verificationPhone(string $phoneNumber): true + public function verificationPhone(): true { return (bool)$this->sendRequest( - new RpcRequest(StandardMethods::VERIFICATION_PHONE_CALL, Utilities::randomCrc32(), [ - 'phone_number' => $phoneNumber - ]) + new RpcRequest(StandardMethods::VERIFICATION_PHONE_CALL, Utilities::randomCrc32()) )->getResponse()->getResult(); } @@ -256,14 +252,14 @@ /** * Retrieves the image captcha for verification purposes by sending a remote procedure call request. * - * @return string The result of the image captcha request. + * @return ImageCaptchaVerification The result of the image captcha request. * @throws RpcException Thrown if the RPC request fails. */ - public function verificationGetImageCaptcha(): string + public function verificationGetImageCaptcha(): ImageCaptchaVerification { - return (bool)$this->sendRequest( + return ImageCaptchaVerification::fromArray($this->sendRequest( new RpcRequest(StandardMethods::VERIFICATION_GET_IMAGE_CAPTCHA, Utilities::randomCrc32()) - )->getResponse()->getResult(); + )->getResponse()->getResult()); } /** @@ -285,14 +281,14 @@ /** * Retrieves the text captcha verification response. * - * @return string The result of the text captcha verification request. + * @return TextCaptchaVerification The result of the text captcha verification request. * @throws RpcException Thrown if the RPC request fails. */ - public function verificationGetTextCaptcha(): string + public function verificationGetTextCaptcha(): TextCaptchaVerification { - return (bool)$this->sendRequest( + return TextCaptchaVerification::fromArray($this->sendRequest( new RpcRequest(StandardMethods::VERIFICATION_GET_TEXT_CAPTCHA, Utilities::randomCrc32()) - )->getResponse()->getResult(); + )->getResponse()->getResult()); } /** @@ -314,14 +310,14 @@ /** * Retrieves the external URL for verification purposes by sending a remote procedure call request. * - * @return string The result of the verification URL request. + * @return ExternalUrlVerification The result of the verification URL request. * @throws RpcException Thrown if the RPC request fails. */ - public function verificationGetExternalUrl(): string + public function verificationGetExternalUrl(): ExternalUrlVerification { - return (bool)$this->sendRequest( + return ExternalUrlVerification::fromArray($this->sendRequest( new RpcRequest(StandardMethods::VERIFICATION_GET_EXTERNAL_URL, Utilities::randomCrc32()) - )->getResponse()->getResult(); + )->getResponse()->getResult()); } /** @@ -414,14 +410,15 @@ * Deletes the user's password settings by sending a remote procedure call request. * * @param string $password The password to be deleted. + * @param bool $hash Indicates whether to hash the password before sending the request. Defaults to true. * @return true Indicates successful deletion of the password. * @throws RpcException Thrown if the RPC request fails. */ - public function settingsDeletePassword(string $password): true + public function settingsDeletePassword(string $password, bool $hash=true): true { return (bool)$this->sendRequest( new RpcRequest(StandardMethods::SETTINGS_DELETE_PASSWORD, Utilities::randomCrc32(), [ - 'password' => $password + 'password' => $hash ? hash('sha512', $password) : $password ]) )->getResponse()->getResult(); } @@ -431,11 +428,23 @@ * * @param string $password The new password to be set. * @param string $existingPassword The current password for authentication. + * @param bool $hash * @return bool True if the password was successfully updated, false otherwise. + * @throws CryptographyException * @throws RpcException Thrown if the RPC request fails. */ - public function settingsUpdatePassword(string $password, string $existingPassword): bool + public function settingsUpdatePassword(string $password, string $existingPassword, bool $hash=true): bool { + if($hash) + { + $password = Cryptography::hashPassword($password); + $existingPassword = hash('sha512', $existingPassword); + } + elseif(!Cryptography::validatePasswordHash($password)) + { + throw new CryptographyException('Invalid password hash provided'); + } + return (bool)$this->sendRequest( new RpcRequest(StandardMethods::SETTINGS_UPDATE_PASSWORD, Utilities::randomCrc32(), [ 'password' => $password, @@ -447,14 +456,19 @@ /** * Updates the OTP setting by sending a remote procedure call request with the provided OTP. * - * @param string $otp The OTP to be set. If hashing is enabled, it will be hashed using SHA-512. + * @return string The result of the OTP URI request. * @throws RpcException Thrown if the RPC request fails. */ - public function settingsSetOtp(string $otp, bool $hash=true): true + public function settingsSetOtp(?string $password=null, bool $hash=true): string { + if($hash && $password !== null) + { + $password = hash('sha512', $password); + } + return (bool)$this->sendRequest( new RpcRequest(StandardMethods::SETTINGS_SET_OTP, Utilities::randomCrc32(), [ - 'otp' => $hash ? hash('sha512', $otp) : $otp + 'password' => $password ]) )->getResponse()->getResult(); } @@ -506,47 +520,162 @@ )->getResponse()->getResult(); } + /** + * Retrieves an information field by sending a remote procedure call request. + * + * @param InformationFieldName $field The field to be retrieved. + * @return InformationField The information field retrieved from the server. + * @throws RpcException Thrown if the RPC request fails. + */ + public function settingsGetInformationField(InformationFieldName $field): InformationField + { + return InformationField::fromArray($this->sendRequest( + new RpcRequest(StandardMethods::SETTINGS_GET_INFORMATION_FIELD, Utilities::randomCrc32(), [ + 'field' => $field->value + ]) + )->getResponse()->getResult()); + } + /** * Deletes an information field by sending a remote procedure call request. * - * @param InformationField $field The field to be deleted. + * @param InformationFieldName $field The field to be deleted. * @return bool True if the field was successfully deleted, false otherwise. * @throws RpcException Thrown if the RPC request fails. */ - public function settingsDeleteInformationField(InformationField $field): true + public function settingsDeleteInformationField(InformationFieldName $field): true { return (bool)$this->sendRequest( - new RpcRequest(StandardMethods::SETTINGS_DELETE_INFORMATION_FIELD, Utilities::randomCrc32()) + new RpcRequest(StandardMethods::SETTINGS_DELETE_INFORMATION_FIELD, Utilities::randomCrc32(), [ + 'field' => $field->value + ]) )->getResponse()->getResult(); } /** * Updates an information field by sending a remote procedure call request. * - * @param InformationField $field The field to be updated. + * @param InformationFieldName $field The field to be updated. * @param string $value The value to be set. * @return bool True if the field was successfully updated, false otherwise. * @throws RpcException Thrown if the RPC request fails. */ - public function settingsUpdateInformationField(InformationField $field, string $value): true + public function settingsUpdateInformationField(InformationFieldName $field, string $value): true { return (bool)$this->sendRequest( - new RpcRequest(StandardMethods::SETTINGS_UPDATE_INFORMATION_FIELD, Utilities::randomCrc32()) + new RpcRequest(StandardMethods::SETTINGS_UPDATE_INFORMATION_FIELD, Utilities::randomCrc32(), [ + 'field' => $field->value, + 'value' => $value + ]) )->getResponse()->getResult(); } /** * Updates the privacy of an information field by sending a remote procedure call request. * - * @param InformationField $field The field to be updated. + * @param InformationFieldName $field The field to be updated. * @param PrivacyState $privacy The privacy state to be set. * @return bool True if the privacy was successfully updated, false otherwise. * @throws RpcException Thrown if the RPC request fails. */ - public function settingsUpdateInformationPrivacy(InformationField $field, PrivacyState $privacy): true + public function settingsUpdateInformationPrivacy(InformationFieldName $field, PrivacyState $privacy): true { return (bool)$this->sendRequest( - new RpcRequest(StandardMethods::SETTINGS_UPDATE_INFORMATION_PRIVACY, Utilities::randomCrc32()) + new RpcRequest(StandardMethods::SETTINGS_UPDATE_INFORMATION_PRIVACY, Utilities::randomCrc32(), [ + 'field' => $field->value, + 'privacy' => $privacy->value + ]) + )->getResponse()->getResult(); + } + + /** + * Adds a signing key to the server associated with the peer by sending a remote procedure call request. + * + * @param string $publicKey The public key to be added. + * @param string|null $name The name of the signing key. + * @param int|null $expires The expiration date of the signing key. + * @return string The UUID of the signing key. + * @throws RpcException Thrown if the RPC request fails. + */ + public function settingsAddSignature(string $publicKey, ?string $name=null, ?int $expires=null): string + { + return $this->sendRequest( + new RpcRequest(StandardMethods::SETTINGS_ADD_SIGNATURE, Utilities::randomCrc32(), [ + 'public_key' => $publicKey, + 'name' => $name, + 'expires' => $expires + ]) + )->getResponse()->getResult(); + } + + /** + * Creates a signing key pair by generating a new key pair and sending a remote procedure call request to add it. + * The generated key pair is returned, this is similar to settingsAddSignature but generates the key pair. + * + * @param string|null $name The name of the signing key. + * @param int|null $expires The expiration date of the signing key. + * @return string The UUID of the signing key. + * @throws CryptographyException Thrown if the key generation fails. + * @throws RpcException Thrown if the RPC request fails. + */ + public function settingsCreateSignature(?string $name=null, ?int $expires=null): string + { + $signingKeypair = Cryptography::generateSigningKeyPair(); + $uuid = $this->settingsAddSignature($signingKeypair->getPublicKey(), $name, $expires); + $signatureKeypair = new SignatureKeyPair([ + 'uuid' => $uuid, + 'name' => $name, + 'public_key' => $signingKeypair->getPublicKey(), + 'private_key' => $signingKeypair->getPrivateKey(), + 'expires' => $expires + ]); + + $this->addSigningKey($signatureKeypair); + return $uuid; + } + + /** + * Retrieves a signing key by sending a remote procedure call request. + * + * @param string $uuid The UUID of the signing key to be retrieved. + * @return SigningKey The signing key retrieved from the server. + * @throws RpcException Thrown if the RPC request fails. + */ + public function settingsGetSigningKey(string $uuid): SigningKey + { + return SigningKey::fromArray($this->sendRequest( + new RpcRequest(StandardMethods::SETTINGS_GET_SIGNATURE, Utilities::randomCrc32(), [ + 'uuid' => $uuid + ]) + )->getResponse()->getResult()); + } + + /** + * Retrieves the list of signing keys associated with the peer by sending a remote procedure call request. + * + * @return SigningKey[] The list of signing keys retrieved from the server. + * @throws RpcException Thrown if the RPC request fails. + */ + public function settingsGetSigningKeys(): array + { + return array_map(fn($key) => SigningKey::fromArray($key), $this->sendRequest( + new RpcRequest(StandardMethods::SETTINGS_GET_SIGNATURES, Utilities::randomCrc32()) + )->getResponse()->getResult()); + } + + /** + * Deletes a signing key by sending a remote procedure call request. + * + * @param string $uuid The UUID of the signing key to be deleted. + * @return bool True if the signing key was successfully deleted, false otherwise. + * @throws RpcException Thrown if the RPC request fails. + */ + public function settingsDeleteSigningKey(string $uuid): true + { + return (bool)$this->sendRequest( + new RpcRequest(StandardMethods::SETTINGS_DELETE_SIGNATURE, Utilities::randomCrc32(), [ + 'uuid' => $uuid + ]) )->getResponse()->getResult(); } @@ -561,12 +690,14 @@ public function authenticate(): true { return (bool)$this->sendRequest( - new RpcRequest(StandardMethods::AUTHENTICATE, Utilities::randomCrc32()) + new RpcRequest(StandardMethods::VERIFICATION_AUTHENTICATE, Utilities::randomCrc32()) )->getResponse()->getResult(); } /** - * Resolves a peer by its address or a PeerAddress instance through a remote procedure call. + * Resolves a peer by its address or a PeerAddress and returns information about the peer. Note that this is a + * decentralized method call, so passing on a peer that does not belong to the host server will result in the + * host server resolving the peer externally on its end. * * @param string|PeerAddress $peerAddress The peer address as a string or an instance of PeerAddress. * @return Peer The resolved peer object. @@ -590,4 +721,29 @@ ]), true, $identifiedAs )->getResponse()->getResult()); } + + /** + * Resolves the signing key of a peer. Note that this is a decentralized method call, so passing on a peer + * that does not belong to the host server will result in the host server resolving the key externally on + * its end. + * + * @param string|PeerAddress $peerAddress The peer address as a string or an instance of PeerAddress. + * @param string $signatureUuid The UUID of the signature to resolve. + * @return SigningKey The resolved signing key. + * @throws RpcException Thrown if the RPC request fails. + */ + public function resolvePeerSignature(string|PeerAddress $peerAddress, string $signatureUuid): SigningKey + { + if($peerAddress instanceof PeerAddress) + { + $peerAddress = $peerAddress->getAddress(); + } + + return SigningKey::fromArray($this->sendRequest( + new RpcRequest(StandardMethods::RESOLVE_PEER_SIGNATURE, Utilities::randomCrc32(), [ + 'peer' => $peerAddress, + 'uuid' => $signatureUuid + ]) + )->getResponse()->getResult()); + } } \ No newline at end of file