From 5042900560187156c24977d7d7dbd281356e940e Mon Sep 17 00:00:00 2001 From: koalasat Date: Wed, 30 Apr 2025 16:43:09 +0200 Subject: [PATCH] Prerelease fixes --- .../src/components/Dialogs/Coordinator.tsx | 46 ++++++++++--------- .../src/components/TradeBox/CancelButton.tsx | 5 +- frontend/src/models/Coordinator.model.ts | 2 +- frontend/src/models/Order.model.ts | 6 +-- frontend/src/models/Robot.model.ts | 5 ++ frontend/src/services/RoboPool/index.ts | 2 +- frontend/src/utils/nostr.ts | 6 ++- frontend/static/locales/fr.json | 6 +-- frontend/static/locales/it.json | 4 +- .../com/robosats/NotificationsService.java | 21 ++++++++- .../java/com/robosats/modules/TorModule.java | 2 - tests/test_trade_pipeline.py | 2 +- tests/utils/trade.py | 23 ++++------ 13 files changed, 78 insertions(+), 52 deletions(-) diff --git a/frontend/src/components/Dialogs/Coordinator.tsx b/frontend/src/components/Dialogs/Coordinator.tsx index 859926d1..12f85999 100644 --- a/frontend/src/components/Dialogs/Coordinator.tsx +++ b/frontend/src/components/Dialogs/Coordinator.tsx @@ -525,29 +525,31 @@ const CoordinatorDialog = ({ open = false, onClose, shortAlias }: Props): JSX.El /> - - - - - - {`${String( - coordinator?.[settings.network][settings.selfhostedClient ? 'onion' : origin], - )}`} - - + + + + + {`${String( + coordinator?.[settings.network][settings.selfhostedClient ? 'onion' : origin], + )}`} + + + )} {!coordinator || coordinator?.loadingInfo ? ( diff --git a/frontend/src/components/TradeBox/CancelButton.tsx b/frontend/src/components/TradeBox/CancelButton.tsx index c0e034bc..9b9f2ad8 100644 --- a/frontend/src/components/TradeBox/CancelButton.tsx +++ b/frontend/src/components/TradeBox/CancelButton.tsx @@ -27,6 +27,7 @@ const CancelButton = ({ Boolean(order?.is_maker && [0, 1, 2].includes(order?.status)) || Boolean([3, 6, 7].includes(order?.status ?? -1)); const showCollabCancelButton = order?.status === 9 && !order?.asked_for_cancel; + const unTaken = Boolean(order?.is_maker && [1, 2].includes(order?.status)); const noConfirmation = Boolean(order?.is_maker && [0, 1, 2].includes(order?.status)) || Boolean(order?.is_taker && order?.status === 3); @@ -55,7 +56,9 @@ const CancelButton = ({ ? () => { setOpenCancelWarning(true); } - : openCancelDialog + : unTaken + ? onClickCancel + : openCancelDialog } > {t('Cancel')} diff --git a/frontend/src/models/Coordinator.model.ts b/frontend/src/models/Coordinator.model.ts index fd96e204..17127b32 100644 --- a/frontend/src/models/Coordinator.model.ts +++ b/frontend/src/models/Coordinator.model.ts @@ -180,7 +180,7 @@ export class Coordinator { this.url = hostUrl; this.basePath = `/${settings.network}/${this.shortAlias}`; } else { - this.url = String(this[settings.network][origin]); + this.url = String(this[settings.network]?.[origin]); this.basePath = ''; } }; diff --git a/frontend/src/models/Order.model.ts b/frontend/src/models/Order.model.ts index acae1da3..d140f04f 100644 --- a/frontend/src/models/Order.model.ts +++ b/frontend/src/models/Order.model.ts @@ -202,10 +202,10 @@ class Order { if (slot) { const coordinator = federation.getCoordinator(this.shortAlias); const { basePath, url } = coordinator; + const authHeaders = slot.getRobot()?.getAuthHeaders(); + if (!authHeaders) return this; const data = await apiClient - .post(url + basePath, '/api/make/', body, { - tokenSHA256: slot?.getRobot()?.tokenSHA256 ?? '', - }) + .post(url + basePath, '/api/make/', body, authHeaders) .catch((e) => { console.log(e); }); diff --git a/frontend/src/models/Robot.model.ts b/frontend/src/models/Robot.model.ts index 5970f64c..c16af9dc 100644 --- a/frontend/src/models/Robot.model.ts +++ b/frontend/src/models/Robot.model.ts @@ -57,6 +57,11 @@ class Robot { await apiClient .get(coordinator.url, `${coordinator.basePath}/api/robot/`, authHeaders) .then((data: any) => { + if (data?.bad_request) { + console.error(data?.bad_request); + return; + } + this.update({ nickname: data.nickname, activeOrderId: data.active_order_id ?? null, diff --git a/frontend/src/services/RoboPool/index.ts b/frontend/src/services/RoboPool/index.ts index c42d0fc5..a2101e81 100644 --- a/frontend/src/services/RoboPool/index.ts +++ b/frontend/src/services/RoboPool/index.ts @@ -16,7 +16,7 @@ class RoboPool { this.relays = []; const federationRelays = Object.values(defaultFederation) .map((coord) => { - const url: string = coord[this.network][settings.selfhostedClient ? 'onion' : origin]; + const url: string = coord[this.network]?.[settings.selfhostedClient ? 'onion' : origin]; if (!url) return undefined; diff --git a/frontend/src/utils/nostr.ts b/frontend/src/utils/nostr.ts index 6c237a43..54e6cecc 100644 --- a/frontend/src/utils/nostr.ts +++ b/frontend/src/utils/nostr.ts @@ -114,7 +114,11 @@ export const verifyCoordinatorToken: (event: Event) => boolean = (event) => { const hash = `${event.pubkey}${orderId ?? ''}`; const coordinatorPubKey = event.tags.find((t) => t[0] === 'p')?.[1]; if (signature && coordinatorPubKey) { - return schnorr.verify(signature, hash, coordinatorPubKey); + try { + return schnorr.verify(signature, hash, coordinatorPubKey); + } catch (e) { + return false; + } } return false; }; diff --git a/frontend/static/locales/fr.json b/frontend/static/locales/fr.json index f93f24e1..deb97d5a 100644 --- a/frontend/static/locales/fr.json +++ b/frontend/static/locales/fr.json @@ -479,7 +479,7 @@ "The order has expired": "L'ordre a expiré", "The pinned location is approximate. The exact location for the meeting place must be exchanged in the encrypted chat.": "The pinned location is approximate. The exact location for the meeting place must be exchanged in the encrypted chat.", "You cannot take an order yet! Wait {{timeMin}}m {{timeSec}}s": "Vous ne pouvez pas encore prendre un ordre! Attendez {{timeMin}}m {{timeSec}}s", - "You receive via {{method}} {{amount}}": "Vous recevez via {{méthode}} {{montant}}", + "You receive via {{method}} {{amount}}": "Vous recevez via {{method}} {{amount}}", "You receive {{amount}} Sats (Approx)": "Vous recevez via Lightning {{amount}} Sats (environ)", "You send via Lightning {{amount}} Sats (Approx)": "Vous envoyez via Lightning {{amount}} Sats (environ)", "You send via {{method}} {{amount}}": "Vous envoyez via {{method}} {{amount}}", @@ -570,10 +570,10 @@ "#56": "Phrases in components/TradeBox/Dialogs/ConfirmFiatReceived.tsx", "Confirm": "Confirmer", "Confirm you received {{amount}} {{currencyCode}}?": "Confirmez que vous avez reçu les {{amount}} {{currencyCode}}?", - "Confirming that you received {{amount}} {{currencyCode}} will finalize the trade. The satoshis in the escrow will be released to the buyer. Only confirm after {{amount}} {{currencyCode}} have arrived to your account. Note that if you have received the payment and do not click confirm, you risk losing your bond.": "Confirmer que vous avez reçu {{montant}} {{currencyCode}} finalisera la transaction. Les satoshis en caution seront remis à l'acheteur. Ne confirmez qu'une fois que {{montant}} {{currencyCode}} sont arrivés sur votre compte. Notez que si vous avez reçu le paiement et que vous ne cliquez pas sur confirmer, vous risquez de perdre votre caution.", + "Confirming that you received {{amount}} {{currencyCode}} will finalize the trade. The satoshis in the escrow will be released to the buyer. Only confirm after {{amount}} {{currencyCode}} have arrived to your account. Note that if you have received the payment and do not click confirm, you risk losing your bond.": "Confirmer que vous avez reçu {{amount}} {{currencyCode}} finalisera la transaction. Les satoshis en caution seront remis à l'acheteur. Ne confirmez qu'une fois que {{amount}} {{currencyCode}} sont arrivés sur votre compte. Notez que si vous avez reçu le paiement et que vous ne cliquez pas sur confirmer, vous risquez de perdre votre caution.", "#57": "Phrases in components/TradeBox/Dialogs/ConfirmFiatSent.tsx", "Confirm you sent {{amount}} {{currencyCode}}?": "Confirmez votre envoi {{amount}} {{currencyCode}}?", - "Confirming that you sent {{amount}} {{currencyCode}} will allow your peer to finalize the trade. If you have not yet sent it and you still proceed to falsely confirm, you risk losing your bond.": "Confirmer que vous avez envoyé {{montant}} {{currencyCode}} permettra à votre correspondant de finaliser la transaction. Si vous ne l'avez pas encore envoyé et que vous procédez à une fausse confirmation, vous risquez de perdre votre caution.", + "Confirming that you sent {{amount}} {{currencyCode}} will allow your peer to finalize the trade. If you have not yet sent it and you still proceed to falsely confirm, you risk losing your bond.": "Confirmer que vous avez envoyé {{amount}} {{currencyCode}} permettra à votre correspondant de finaliser la transaction. Si vous ne l'avez pas encore envoyé et que vous procédez à une fausse confirmation, vous risquez de perdre votre caution.", "#58": "Phrases in components/TradeBox/Dialogs/ConfirmUndoFiatSent.tsx", "READ. In case your payment to the seller has been blocked and it is absolutely impossible to finish the trade, you can revert your confirmation of \"Fiat sent\". Do so only if you and the seller have ALREADY AGREED in the chat to proceed to a collaborative cancellation. After confirming, the \"Collaborative cancel\" button will be visible again. Only click this button if you know what you are doing. First time users of RoboSats are highly discouraged from performing this action! Make 100% sure your payment has failed and the amount is in your account.": "LIRE. Si votre paiement au vendeur a été bloqué et qu'il est absolument impossible de terminer la transaction, vous pouvez annuler votre confirmation de vente de \"Fiat envoyé\". Ne le faites que si vous et le vendeur avez DÉJÀ ACCORDÉ dans le chat de procéder à une annulation collaborative. Après avoir confirmé, le bouton \"Annulation collaborative\" sera à nouveau visible. Ne cliquez sur ce bouton que si vous savez ce que vous faites. Il est fortement déconseillé aux nouveaux utilisateurs de RoboSats d'effectuer cette action ! Assurez-vous à 100 % que votre paiement a échoué et que le montant est sur votre compte.", "Revert the confirmation of fiat sent?": "Revenir sur la confirmation de l'envoi fiat ?", diff --git a/frontend/static/locales/it.json b/frontend/static/locales/it.json index a12f5077..812d40c8 100644 --- a/frontend/static/locales/it.json +++ b/frontend/static/locales/it.json @@ -570,10 +570,10 @@ "#56": "Phrases in components/TradeBox/Dialogs/ConfirmFiatReceived.tsx", "Confirm": "Conferma", "Confirm you received {{amount}} {{currencyCode}}?": "Confermi la ricezione di {{amount}} {{currencyCode}}?", - "Confirming that you received {{amount}} {{currencyCode}} will finalize the trade. The satoshis in the escrow will be released to the buyer. Only confirm after {{amount}} {{currencyCode}} have arrived to your account. Note that if you have received the payment and do not click confirm, you risk losing your bond.": "Confermando di aver ricevuto {{importo}} {{currencyCode}} concluderai lo scambio. I satoshi in deposito saranno rilasciati all'acquirente. Conferma solo dopo che {{amount}} {{valutaCodice}} sono arrivati sul tuo conto. Si noti che se si riceve il pagamento e non si clicca su conferma, si rischia di perdere la propria cauzione.", + "Confirming that you received {{amount}} {{currencyCode}} will finalize the trade. The satoshis in the escrow will be released to the buyer. Only confirm after {{amount}} {{currencyCode}} have arrived to your account. Note that if you have received the payment and do not click confirm, you risk losing your bond.": "Confermando di aver ricevuto {{amount}} {{currencyCode}} concluderai lo scambio. I satoshi in deposito saranno rilasciati all'acquirente. Conferma solo dopo che {{amount}} {{valutaCodice}} sono arrivati sul tuo conto. Si noti che se si riceve il pagamento e non si clicca su conferma, si rischia di perdere la propria cauzione.", "#57": "Phrases in components/TradeBox/Dialogs/ConfirmFiatSent.tsx", "Confirm you sent {{amount}} {{currencyCode}}?": "Confermi di aver inviato {{amount}} {{currencyCode}}?", - "Confirming that you sent {{amount}} {{currencyCode}} will allow your peer to finalize the trade. If you have not yet sent it and you still proceed to falsely confirm, you risk losing your bond.": "Confermando di aver inviato {{importo}} {{currencyCode}} consentirai al tuo pari di finalizzare la transazione. Se non lo si è ancora inviato e si procede comunque a una falsa conferma, si rischia di perdere la propria cauzione.", + "Confirming that you sent {{amount}} {{currencyCode}} will allow your peer to finalize the trade. If you have not yet sent it and you still proceed to falsely confirm, you risk losing your bond.": "Confermando di aver inviato {{amount}} {{currencyCode}} consentirai al tuo pari di finalizzare la transazione. Se non lo si è ancora inviato e si procede comunque a una falsa conferma, si rischia di perdere la propria cauzione.", "#58": "Phrases in components/TradeBox/Dialogs/ConfirmUndoFiatSent.tsx", "READ. In case your payment to the seller has been blocked and it is absolutely impossible to finish the trade, you can revert your confirmation of \"Fiat sent\". Do so only if you and the seller have ALREADY AGREED in the chat to proceed to a collaborative cancellation. After confirming, the \"Collaborative cancel\" button will be visible again. Only click this button if you know what you are doing. First time users of RoboSats are highly discouraged from performing this action! Make 100% sure your payment has failed and the amount is in your account.": "LEGGERE. Nel caso in cui il pagamento al venditore sia stato bloccato e sia assolutamente impossibile concludere la compravendita, puoi annullare la tua conferma di \"Fiat inviate\". Questo solo se tu e il venditore avete già concordato in chat di procedere a un annullamento collaborativo. Dopo la conferma, il pulsante \"Annullamento collaborativo\" sarà nuovamente visibile. Fare clic su questo pulsante solo se si sa cosa si sta facendo. Agli utenti che utilizzano RoboSats per la prima volta è caldamente sconsigliato eseguire questa azione! Assicurarsi al 100% che il pagamento non sia andato a buon fine e che l'importo sia presente nel conto.", "Revert the confirmation of fiat sent?": "Annullare la conferma dell'invio di fiat?", diff --git a/mobile/android/app/src/main/java/com/robosats/NotificationsService.java b/mobile/android/app/src/main/java/com/robosats/NotificationsService.java index f9c87490..6ac60dc3 100644 --- a/mobile/android/app/src/main/java/com/robosats/NotificationsService.java +++ b/mobile/android/app/src/main/java/com/robosats/NotificationsService.java @@ -141,6 +141,7 @@ public class NotificationsService extends Service { while (it.hasNext()) { String robotToken = it.next(); + Log.d("NotificationsService", "Checking Slot"); JSONObject slot = (JSONObject) slots.get(robotToken); JSONObject robots = slot.getJSONObject("robots"); JSONObject coordinatorRobot; @@ -187,9 +188,25 @@ public class NotificationsService extends Service { OkHttpClient client = builder.build(); Request.Builder requestBuilder = new Request.Builder().url(url); - + String header = String.format("Token %s", token); + try { + String pubKey = robot.getString("pubKey"); + String parsedPubKey = String.join("\\", pubKey.split("\n")); + String encPrivKey = robot.getString("encPrivKey"); + String parsedEncPrivKey = String.join("\\", encPrivKey.split("\n")); + header += String.format(" | Public %s | Private %s", parsedPubKey, parsedEncPrivKey); + } catch (JSONException e) { + Log.e("NotificationsService", "Error obtaining PGP keys"); + return; + } + try { + String nostrPubKey = robot.getString("nostrPubKey"); + header += String.format(" | Nostr %s", nostrPubKey); + } catch (JSONException e) { + Log.d("NotificationsService", "Nostr key not found"); + } requestBuilder - .addHeader("Authorization", "Token " + token); + .addHeader("Authorization", header); requestBuilder.get(); Request request = requestBuilder.build(); diff --git a/mobile/android/app/src/main/java/com/robosats/modules/TorModule.java b/mobile/android/app/src/main/java/com/robosats/modules/TorModule.java index 0dcf6c53..9a3ef36f 100644 --- a/mobile/android/app/src/main/java/com/robosats/modules/TorModule.java +++ b/mobile/android/app/src/main/java/com/robosats/modules/TorModule.java @@ -99,13 +99,11 @@ public class TorModule extends ReactContextBaseJavaModule { @Override public void onMessage(@NonNull WebSocket webSocket, @NonNull String text) { - Log.d("Tormodule", "WebSocket Message received: " + text); onWsMessage(path, text); } @Override public void onMessage(@NonNull WebSocket webSocket, ByteString bytes) { - Log.d("Tormodule", "WebSocket Message received: " + bytes.hex()); onWsMessage(path, bytes.hex()); } diff --git a/tests/test_trade_pipeline.py b/tests/test_trade_pipeline.py index e9c0e9cd..aa78851b 100644 --- a/tests/test_trade_pipeline.py +++ b/tests/test_trade_pipeline.py @@ -362,7 +362,7 @@ class TradeTest(BaseAPITestCase): ) # Test what we can see with newly created robot 2 (only for public status) - trade.get_order(robot_index=2, first_encounter=True) + trade.get_order(robot_index=2) public_data = trade.response.json() self.assertFalse(public_data["is_participant"]) diff --git a/tests/utils/trade.py b/tests/utils/trade.py index 3608a663..4a6aeb2c 100644 --- a/tests/utils/trade.py +++ b/tests/utils/trade.py @@ -61,7 +61,7 @@ class Trade: self.make_order(self.maker_form, maker_index) - def get_robot_auth(self, robot_index, first_encounter=False): + def get_robot_auth(self, robot_index): """ Create an AUTH header that embeds token, pub_key, and enc_priv_key into a single string as requested by the robosats token middleware. @@ -73,12 +73,9 @@ class Trade: nostr_pubkey = read_file(f"tests/robots/{robot_index}/nostr_pubkey") # First time a robot authenticated, it is registered by the backend, so pub_key and enc_priv_key is needed - if first_encounter: - headers = { - "HTTP_AUTHORIZATION": f"Token {b91_token} | Public {pub_key} | Private {enc_priv_key} | Nostr {nostr_pubkey}" - } - else: - headers = {"HTTP_AUTHORIZATION": f"Token {b91_token}"} + headers = { + "HTTP_AUTHORIZATION": f"Token {b91_token} | Public {pub_key} | Private {enc_priv_key} | Nostr {nostr_pubkey}" + } return headers @@ -87,7 +84,7 @@ class Trade: Creates the robots in /tests/robots/{robot_index} """ path = reverse("robot") - headers = self.get_robot_auth(robot_index, True) + headers = self.get_robot_auth(robot_index) return self.client.get(path, **headers) @@ -97,7 +94,7 @@ class Trade: """ path = reverse("make") # Get valid robot auth headers - headers = self.get_robot_auth(robot_index, True) + headers = self.get_robot_auth(robot_index) response = self.client.post(path, maker_form, **headers) @@ -105,13 +102,13 @@ class Trade: if response.status_code == 201: self.order_id = response.json()["id"] - def get_order(self, robot_index=1, first_encounter=False): + def get_order(self, robot_index=1): """ Fetch the latest state of the order """ path = reverse("order") params = f"?order_id={self.order_id}" - headers = self.get_robot_auth(robot_index, first_encounter) + headers = self.get_robot_auth(robot_index) self.response = self.client.get(path + params, **headers) def get_review(self, robot_index=1): @@ -189,7 +186,7 @@ class Trade: def take_order(self): path = reverse("order") params = f"?order_id={self.order_id}" - headers = self.get_robot_auth(self.taker_index, first_encounter=True) + headers = self.get_robot_auth(self.taker_index) body = {"action": "take", "amount": self.take_amount} self.response = self.client.post(path + params, body, **headers) @@ -197,7 +194,7 @@ class Trade: def take_order_third(self): path = reverse("order") params = f"?order_id={self.order_id}" - headers = self.get_robot_auth(self.third_index, first_encounter=True) + headers = self.get_robot_auth(self.third_index) body = {"action": "take", "amount": self.take_amount} self.response = self.client.post(path + params, body, **headers)