]> nmode's Git Repositories - signal-cli/commitdiff
Add submitRateLimitChallenge command
authorAsamK <asamk@gmx.de>
Thu, 9 Sep 2021 17:20:48 +0000 (19:20 +0200)
committerAsamK <asamk@gmx.de>
Thu, 9 Sep 2021 17:20:48 +0000 (19:20 +0200)
Related #708

lib/src/main/java/org/asamk/signal/manager/Manager.java
src/main/java/org/asamk/signal/commands/Commands.java
src/main/java/org/asamk/signal/commands/SubmitRateLimitChallengeCommand.java [new file with mode: 0644]
src/main/java/org/asamk/signal/util/ErrorUtils.java

index a7a691cc4ce4a93ecfad4e64963eafad43c78ae5..a7e80f7cb3abb9c8b33d3b3af92d513c28bf7a83 100644 (file)
@@ -405,6 +405,10 @@ public class Manager implements Closeable {
         account.setRegistered(false);
     }
 
+    public void submitRateLimitRecaptchaChallenge(String challenge, String captcha) throws IOException {
+        dependencies.getAccountManager().submitRateLimitRecaptchaChallenge(challenge, captcha);
+    }
+
     public List<Device> getLinkedDevices() throws IOException {
         var devices = dependencies.getAccountManager().getDevices();
         account.setMultiDevice(devices.size() > 1);
index 90e8e114237770013198a79bcf8d75e5301e0685..5d637eee0c9833f18ea133bae4c38cb003c42e29 100644 (file)
@@ -34,6 +34,7 @@ public class Commands {
         addCommand(new SendSyncRequestCommand());
         addCommand(new SendTypingCommand());
         addCommand(new SetPinCommand());
+        addCommand(new SubmitRateLimitChallengeCommand());
         addCommand(new TrustCommand());
         addCommand(new UnblockCommand());
         addCommand(new UnregisterCommand());
diff --git a/src/main/java/org/asamk/signal/commands/SubmitRateLimitChallengeCommand.java b/src/main/java/org/asamk/signal/commands/SubmitRateLimitChallengeCommand.java
new file mode 100644 (file)
index 0000000..46f6989
--- /dev/null
@@ -0,0 +1,44 @@
+package org.asamk.signal.commands;
+
+import net.sourceforge.argparse4j.inf.Namespace;
+import net.sourceforge.argparse4j.inf.Subparser;
+
+import org.asamk.signal.OutputWriter;
+import org.asamk.signal.commands.exceptions.CommandException;
+import org.asamk.signal.commands.exceptions.IOErrorException;
+import org.asamk.signal.manager.Manager;
+
+import java.io.IOException;
+
+public class SubmitRateLimitChallengeCommand implements JsonRpcLocalCommand {
+
+    @Override
+    public String getName() {
+        return "submitRateLimitChallenge";
+    }
+
+    @Override
+    public void attachToSubparser(final Subparser subparser) {
+        subparser.help(
+                "Submit a captcha challenge to lift the rate limit. This command should only be necessary when sending fails with a proof required error.");
+        subparser.addArgument("--challenge")
+                .required(true)
+                .help("The challenge token taken from the proof required error.");
+        subparser.addArgument("--captcha")
+                .required(true)
+                .help("The captcha token from the solved captcha on the signal website.");
+    }
+
+    @Override
+    public void handleCommand(final Namespace ns, final Manager m, OutputWriter outputWriter) throws CommandException {
+        final var challenge = ns.getString("challenge");
+        final var captchaString = ns.getString("captcha");
+        final var captcha = captchaString == null ? null : captchaString.replace("signalcaptcha://", "");
+
+        try {
+            m.submitRateLimitRecaptchaChallenge(challenge, captcha);
+        } catch (IOException e) {
+            throw new IOErrorException("Submit challenge error: " + e.getMessage(), e);
+        }
+    }
+}
index ef1956c3f5ca72db7e426192a2b4eed972e12aa4..e245492588f751ef82d2b967f44c6b5bb955f0cc 100644 (file)
@@ -67,7 +67,17 @@ public class ErrorUtils {
         } else if (result.getProofRequiredFailure() != null) {
             final var failure = result.getProofRequiredFailure();
             return String.format(
-                    "CAPTCHA proof required for sending to \"%s\", available options \"%s\" with challenge token \"%s\", or wait \"%d\" seconds",
+                    "CAPTCHA proof required for sending to \"%s\", available options \"%s\" with challenge token \"%s\", or wait \"%d\" seconds.\n"
+                            + (
+                            failure.getOptions().contains(ProofRequiredException.Option.RECAPTCHA)
+                                    ?
+                                    "To get the captcha token, go to https://signalcaptchas.org/registration/generate.html\n"
+                                            + "Check the developer tools (F12) console for a failed redirect to signalcaptcha://\n"
+                                            + "Everything after signalcaptcha:// is the captcha token.\n"
+                                            + "Use the following command to submit the captcha token:\n"
+                                            + "signal-cli submitRateLimitChallenge --challenge CHALLENGE_TOKEN --captcha CAPTCHA_TOKEN"
+                                    : ""
+                    ),
                     identifier,
                     failure.getOptions()
                             .stream()