diff --git a/ArchiSteamFarm/IPC/Controllers/Api/TwoFactorAuthenticationController.cs b/ArchiSteamFarm/IPC/Controllers/Api/TwoFactorAuthenticationController.cs
index 1793cf402..efe752410 100644
--- a/ArchiSteamFarm/IPC/Controllers/Api/TwoFactorAuthenticationController.cs
+++ b/ArchiSteamFarm/IPC/Controllers/Api/TwoFactorAuthenticationController.cs
@@ -38,6 +38,35 @@ namespace ArchiSteamFarm.IPC.Controllers.Api;
[Route("Api/Bot/{botNames:required}/TwoFactorAuthentication")]
public sealed class TwoFactorAuthenticationController : ArchiController {
+ ///
+ /// Fetches pending 2FA confirmations of given bots, requires ASF 2FA module to be active on them.
+ ///
+ [HttpGet("Confirmations")]
+ [ProducesResponseType(typeof(GenericResponse>>>), (int) HttpStatusCode.OK)]
+ [ProducesResponseType(typeof(GenericResponse), (int) HttpStatusCode.BadRequest)]
+ public async Task> ConfirmationsGet(string botNames) {
+ if (string.IsNullOrEmpty(botNames)) {
+ throw new ArgumentNullException(nameof(botNames));
+ }
+
+ HashSet? bots = Bot.GetBots(botNames);
+
+ if ((bots == null) || (bots.Count == 0)) {
+ return BadRequest(new GenericResponse>>(false, string.Format(CultureInfo.CurrentCulture, Strings.BotNotFound, botNames)));
+ }
+
+ IList<(bool Success, IReadOnlyCollection? Confirmations, string Message)> results = await Utilities.InParallel(bots.Select(static bot => bot.Actions.GetConfirmations())).ConfigureAwait(false);
+
+ Dictionary>> result = new(bots.Count, Bot.BotsComparer);
+
+ foreach (Bot bot in bots) {
+ (bool success, IReadOnlyCollection? confirmations, string message) = results[result.Count];
+ result[bot.BotName] = new GenericResponse>(success, message, confirmations);
+ }
+
+ return Ok(new GenericResponse>>>(result));
+ }
+
///
/// Handles 2FA confirmations of given bots, requires ASF 2FA module to be active on them.
///
diff --git a/ArchiSteamFarm/Steam/Interaction/Actions.cs b/ArchiSteamFarm/Steam/Interaction/Actions.cs
index c17059554..234d4be8b 100644
--- a/ArchiSteamFarm/Steam/Interaction/Actions.cs
+++ b/ArchiSteamFarm/Steam/Interaction/Actions.cs
@@ -132,6 +132,23 @@ public sealed class Actions : IAsyncDisposable, IDisposable {
return new SemaphoreLock(TradingSemaphore);
}
+ [PublicAPI]
+ public async Task<(bool Success, IReadOnlyCollection? Confirmations, string Message)> GetConfirmations() {
+ if (Bot.BotDatabase.MobileAuthenticator == null) {
+ return (false, null, Strings.BotNoASFAuthenticator);
+ }
+
+ if (!Bot.IsConnectedAndLoggedOn) {
+ return (false, null, Strings.BotNotConnected);
+ }
+
+ ImmutableHashSet? confirmations = await Bot.BotDatabase.MobileAuthenticator.GetConfirmations().ConfigureAwait(false);
+
+ bool success = confirmations != null;
+
+ return (success, null, success ? Strings.Success : Strings.WarningFailed);
+ }
+
[PublicAPI]
public async Task<(bool Success, IReadOnlyCollection? HandledConfirmations, string Message)> HandleTwoFactorAuthenticationConfirmations(bool accept, Confirmation.EConfirmationType? acceptedType = null, IReadOnlyCollection? acceptedCreatorIDs = null, bool waitIfNeeded = false) {
if (Bot.BotDatabase.MobileAuthenticator == null) {