From eee140f74fe9a01972b8d61193c1125c1d89e0df Mon Sep 17 00:00:00 2001 From: AsamK Date: Thu, 9 Sep 2021 19:20:48 +0200 Subject: [PATCH] Add submitRateLimitChallenge command Related #708 --- .../org/asamk/signal/manager/Manager.java | 4 ++ .../org/asamk/signal/commands/Commands.java | 1 + .../SubmitRateLimitChallengeCommand.java | 44 +++++++++++++++++++ .../org/asamk/signal/util/ErrorUtils.java | 12 ++++- 4 files changed, 60 insertions(+), 1 deletion(-) create mode 100644 src/main/java/org/asamk/signal/commands/SubmitRateLimitChallengeCommand.java diff --git a/lib/src/main/java/org/asamk/signal/manager/Manager.java b/lib/src/main/java/org/asamk/signal/manager/Manager.java index a7a691cc..a7e80f7c 100644 --- a/lib/src/main/java/org/asamk/signal/manager/Manager.java +++ b/lib/src/main/java/org/asamk/signal/manager/Manager.java @@ -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 getLinkedDevices() throws IOException { var devices = dependencies.getAccountManager().getDevices(); account.setMultiDevice(devices.size() > 1); diff --git a/src/main/java/org/asamk/signal/commands/Commands.java b/src/main/java/org/asamk/signal/commands/Commands.java index 90e8e114..5d637eee 100644 --- a/src/main/java/org/asamk/signal/commands/Commands.java +++ b/src/main/java/org/asamk/signal/commands/Commands.java @@ -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 index 00000000..46f69896 --- /dev/null +++ b/src/main/java/org/asamk/signal/commands/SubmitRateLimitChallengeCommand.java @@ -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); + } + } +} diff --git a/src/main/java/org/asamk/signal/util/ErrorUtils.java b/src/main/java/org/asamk/signal/util/ErrorUtils.java index ef1956c3..e2454925 100644 --- a/src/main/java/org/asamk/signal/util/ErrorUtils.java +++ b/src/main/java/org/asamk/signal/util/ErrorUtils.java @@ -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() -- 2.50.1