Tony Cebzanov c979fcbb53 Add getRateLimitStatus JSON-RPC method
Adds a read-only query returning the most recent rate-limit state
observed from send results. Callers can check whether the account is
currently rate-limited, how long until retry, and whether a captcha
challenge is required — without having to trigger a send and inspect
the response, and without having to reconstruct state themselves.

Useful for:
- Admin UIs that want to display current rate-limit state on load
- Monitoring/alerting (poll for active rate limits)
- Clients that restart and would otherwise lose tracked state

The status is tracked in-memory on the Manager: updated whenever a
SendMessageResult reports a rate-limit failure, cleared after a
successful captcha submission, and auto-expires when the retry-after
window elapses (getRateLimitStatus returns active=false once the
current time is past expiresAtEpochSeconds).

JSON-RPC response shape:
{
  "active": bool,
  "proofRequired": bool,
  "retryAfterSeconds": long,    // omitted if not active
  "challengeToken": string,      // omitted unless proofRequired
  "expiresAtEpochSeconds": long  // omitted if not active
}

D-Bus is not updated to expose this state; DbusManagerImpl returns
inactive as a stub since D-Bus clients already observe rate-limit state
via send results.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-16 08:26:40 -04:00

96 lines
3.8 KiB
Java

package org.asamk.signal.commands;
import java.util.HashMap;
import java.util.Map;
import java.util.TreeMap;
public class Commands {
private static final Map<String, Command> commands = new HashMap<>();
private static final Map<String, SubparserAttacher> commandSubparserAttacher = new TreeMap<>();
static {
addCommand(new AcceptCallCommand());
addCommand(new AddDeviceCommand());
addCommand(new BlockCommand());
addCommand(new DaemonCommand());
addCommand(new DeleteLocalAccountDataCommand());
addCommand(new FinishChangeNumberCommand());
addCommand(new FinishLinkCommand());
addCommand(new HangupCallCommand());
addCommand(new GetAttachmentCommand());
addCommand(new GetAvatarCommand());
addCommand(new GetRateLimitStatusCommand());
addCommand(new GetStickerCommand());
addCommand(new GetUserStatusCommand());
addCommand(new AddStickerPackCommand());
addCommand(new JoinGroupCommand());
addCommand(new ListCallsCommand());
addCommand(new JsonRpcDispatcherCommand());
addCommand(new LinkCommand());
addCommand(new ListAccountsCommand());
addCommand(new ListContactsCommand());
addCommand(new ListDevicesCommand());
addCommand(new ListGroupsCommand());
addCommand(new ListIdentitiesCommand());
addCommand(new ListStickerPacksCommand());
addCommand(new QuitGroupCommand());
addCommand(new ReceiveCommand());
addCommand(new RejectCallCommand());
addCommand(new RegisterCommand());
addCommand(new RemoveContactCommand());
addCommand(new RemoveDeviceCommand());
addCommand(new RemovePinCommand());
addCommand(new RemoteDeleteCommand());
addCommand(new SendAdminDeleteCommand());
addCommand(new SendCommand());
addCommand(new SendContactsCommand());
addCommand(new SendMessageRequestResponseCommand());
addCommand(new SendPaymentNotificationCommand());
addCommand(new SendPinMessageCommand());
addCommand(new SendPollCreateCommand());
addCommand(new SendPollVoteCommand());
addCommand(new SendPollTerminateCommand());
addCommand(new SendReactionCommand());
addCommand(new SendReceiptCommand());
addCommand(new SendSyncRequestCommand());
addCommand(new SendTypingCommand());
addCommand(new SendUnpinMessageCommand());
addCommand(new SetPinCommand());
addCommand(new StartCallCommand());
addCommand(new SubmitRateLimitChallengeCommand());
addCommand(new StartChangeNumberCommand());
addCommand(new StartLinkCommand());
addCommand(new TrustCommand());
addCommand(new UnblockCommand());
addCommand(new UnregisterCommand());
addCommand(new UpdateAccountCommand());
addCommand(new UpdateConfigurationCommand());
addCommand(new UpdateContactCommand());
addCommand(new UpdateDeviceCommand());
addCommand(new UpdateGroupCommand());
addCommand(new UpdateProfileCommand());
addCommand(new UploadStickerPackCommand());
addCommand(new VerifyCommand());
addCommand(new VersionCommand());
}
public static Map<String, SubparserAttacher> getCommandSubparserAttachers() {
return commandSubparserAttacher;
}
public static Command getCommand(String commandKey) {
if (!commands.containsKey(commandKey)) {
return null;
}
return commands.get(commandKey);
}
private static void addCommand(Command command) {
commands.put(command.getName(), command);
if (command instanceof CliCommand cliCommand) {
commandSubparserAttacher.put(command.getName(), cliCommand::attachToSubparser);
}
}
}