aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLibravatar buttercat1791 <mjjurkoic@gmail.com>2024-05-31 09:30:03 -0500
committerLibravatar buttercat1791 <mjjurkoic@gmail.com>2024-05-31 09:30:03 -0500
commit15c061974ae164a9b6b0d159d35f0389711d0345 (patch)
tree0a75a40c7e5d860000ee4477cb839a0e587df464
parent308840a3a3d80616e5a61bebbcdebb6d8ad99c66 (diff)
Parse connection token
-rw-r--r--include/signer/noscrypt_signer.hpp21
-rw-r--r--src/signer/noscrypt_signer.cpp74
2 files changed, 94 insertions, 1 deletions
diff --git a/include/signer/noscrypt_signer.hpp b/include/signer/noscrypt_signer.hpp
index d2135da..606438e 100644
--- a/include/signer/noscrypt_signer.hpp
+++ b/include/signer/noscrypt_signer.hpp
@@ -40,6 +40,9 @@ private:
std::string _localPrivateKey;
std::string _localPublicKey;
+ std::string _remotePublicKey;
+ std::string _bunkerSecret;
+
///< A list of relays that will be used to connect to the remote signer.
std::vector<std::string> _relays;
@@ -58,6 +61,24 @@ private:
*/
std::tuple<std::string, std::string> _createLocalKeypair();
+ /**
+ * @brief Parses the remote signer npub from a connection token provided by the signer.
+ * @param connectionToken A connection token beginning with `bunker://`.
+ * @returns The index of the first character of the connection token's query string, or -1 if
+ * no valid public key could be parsed.
+ * @remark This function updates the `_remotePublicKey` string in its class instance by side
+ * effect.
+ */
+ int _parseRemotePublicKey(std::string connectionToken);
+
+ /**
+ * @brief Parses a single query param from a connection token provided by a remote signer.
+ * @param param A single query param from the connection token of the form `key=value`.
+ * @remark This function updates the `_relays` vector and the `_bunkerSecret` string in its
+ * class instance by side effect.
+ */
+ void _handleConnectionTokenParam(std::string param);
+
#pragma region Logging
void _logNoscryptInitResult(NCResult initResult);
diff --git a/src/signer/noscrypt_signer.cpp b/src/signer/noscrypt_signer.cpp
index 2b00cca..d02aa93 100644
--- a/src/signer/noscrypt_signer.cpp
+++ b/src/signer/noscrypt_signer.cpp
@@ -32,7 +32,30 @@ NoscryptSigner::~NoscryptSigner()
void NoscryptSigner::receiveConnection(string connectionToken)
{
- // Receive the connection token here.
+ if (connectionToken.empty())
+ {
+ PLOG_ERROR << "No connection token was provided - unable to connect to a remote signer.";
+ return;
+ }
+
+ int queryStart = this->_parseRemotePublicKey(connectionToken);
+ if (queryStart == -1)
+ {
+ return;
+ }
+
+ string remainingToken = connectionToken.substr(queryStart);
+ int splitIndex = remainingToken.find('&');
+ do
+ {
+ string param = remainingToken.substr(0, splitIndex);
+ this->_handleConnectionTokenParam(param);
+
+ remainingToken = remainingToken.substr(splitIndex + 1);
+ splitIndex = remainingToken.find('&');
+ } while (splitIndex != string::npos);
+
+ // TODO: Handle any messaging with the remote signer.
};
string NoscryptSigner::initiateConnection(
@@ -73,6 +96,8 @@ string NoscryptSigner::initiateConnection(
ss << "}";
return ss.str();
+
+ // TODO: Handle any messaging with the remote signer.
};
void NoscryptSigner::sign(shared_ptr<data::Event> event)
@@ -176,6 +201,53 @@ tuple<string, string> NoscryptSigner::_createLocalKeypair()
return make_tuple(privateKey, publicKey);
};
+int NoscryptSigner::_parseRemotePublicKey(string connectionToken)
+{
+ int queryStart = connectionToken.find('?');
+ if (queryStart == string::npos)
+ {
+ PLOG_ERROR << "The connection token is invalid - no query string was found.";
+ return -1;
+ }
+
+ const int pubkeyStart = 9;
+ string prefix = connectionToken.substr(0, pubkeyStart);
+ if (prefix != "bunker://")
+ {
+ PLOG_ERROR << "The connection token is invalid - the token must begin with 'bunker://'.";
+ return -1;
+ }
+
+ string remotePubkey = connectionToken.substr(pubkeyStart, queryStart);
+ this->_remotePublicKey = remotePubkey;
+
+ return queryStart + 1;
+};
+
+void NoscryptSigner::_handleConnectionTokenParam(string param)
+{
+ // Parse the query param into a key-value pair.
+ int splitIndex = param.find('=');
+ if (splitIndex == string::npos)
+ {
+ PLOG_ERROR << "The connection token query param is invalid - it is not of the form 'key=value'.";
+ return;
+ }
+
+ string key = param.substr(0, splitIndex);
+ string value = param.substr(splitIndex + 1);
+
+ // Handle the key-value pair.
+ if (key == "relay")
+ {
+ this->_relays.push_back(value);
+ }
+ else if (key == "secret")
+ {
+ this->_bunkerSecret = value;
+ }
+};
+
#pragma region Logging
void NoscryptSigner::_logNoscryptInitResult(NCResult initResult)