mirror of
https://github.com/JustArchiNET/ArchiSteamFarm.git
synced 2026-01-16 08:25:28 +00:00
Closes #3343
This commit is contained in:
@@ -34,6 +34,7 @@ using ArchiSteamFarm.IPC.Responses;
|
||||
using ArchiSteamFarm.Localization;
|
||||
using ArchiSteamFarm.Steam.Interaction;
|
||||
using ArchiSteamFarm.Storage;
|
||||
using Microsoft.AspNetCore.Http;
|
||||
using Microsoft.AspNetCore.Mvc;
|
||||
using Microsoft.Extensions.Hosting;
|
||||
|
||||
@@ -51,10 +52,7 @@ public sealed class ASFController : ArchiController {
|
||||
ApplicationLifetime = applicationLifetime;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Encrypts data with ASF encryption mechanisms using provided details.
|
||||
/// </summary>
|
||||
[Consumes("application/json")]
|
||||
[EndpointSummary("Encrypts data with ASF encryption mechanisms using provided details.")]
|
||||
[HttpPost("Encrypt")]
|
||||
[ProducesResponseType<GenericResponse<string>>((int) HttpStatusCode.OK)]
|
||||
[ProducesResponseType<GenericResponse>((int) HttpStatusCode.BadRequest)]
|
||||
@@ -70,9 +68,7 @@ public sealed class ASFController : ArchiController {
|
||||
return Ok(new GenericResponse<string>(encryptedString));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Fetches common info related to ASF as a whole.
|
||||
/// </summary>
|
||||
[EndpointSummary("Fetches common info related to ASF as a whole")]
|
||||
[HttpGet]
|
||||
[ProducesResponseType<GenericResponse<ASFResponse>>((int) HttpStatusCode.OK)]
|
||||
public ActionResult<GenericResponse<ASFResponse>> ASFGet() {
|
||||
@@ -87,10 +83,7 @@ public sealed class ASFController : ArchiController {
|
||||
return Ok(new GenericResponse<ASFResponse>(result));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Hashes data with ASF hashing mechanisms using provided details.
|
||||
/// </summary>
|
||||
[Consumes("application/json")]
|
||||
[EndpointSummary("Hashes data with ASF hashing mechanisms using provided details")]
|
||||
[HttpPost("Hash")]
|
||||
[ProducesResponseType<GenericResponse<string>>((int) HttpStatusCode.OK)]
|
||||
[ProducesResponseType<GenericResponse>((int) HttpStatusCode.BadRequest)]
|
||||
@@ -106,10 +99,7 @@ public sealed class ASFController : ArchiController {
|
||||
return Ok(new GenericResponse<string>(hash));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Updates ASF's global config.
|
||||
/// </summary>
|
||||
[Consumes("application/json")]
|
||||
[EndpointSummary("Updates ASF's global config")]
|
||||
[HttpPost]
|
||||
[ProducesResponseType<GenericResponse>((int) HttpStatusCode.OK)]
|
||||
[ProducesResponseType<GenericResponse>((int) HttpStatusCode.BadRequest)]
|
||||
@@ -163,9 +153,7 @@ public sealed class ASFController : ArchiController {
|
||||
return Ok(new GenericResponse(result));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Makes ASF shutdown itself.
|
||||
/// </summary>
|
||||
[EndpointSummary("Makes ASF shutdown itself")]
|
||||
[HttpPost("Exit")]
|
||||
[ProducesResponseType<GenericResponse>((int) HttpStatusCode.OK)]
|
||||
public ActionResult<GenericResponse> ExitPost() {
|
||||
@@ -174,9 +162,7 @@ public sealed class ASFController : ArchiController {
|
||||
return Ok(new GenericResponse(success, message));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Makes ASF restart itself.
|
||||
/// </summary>
|
||||
[EndpointSummary("Makes ASF restart itself")]
|
||||
[HttpPost("Restart")]
|
||||
[ProducesResponseType<GenericResponse>((int) HttpStatusCode.OK)]
|
||||
public ActionResult<GenericResponse> RestartPost() {
|
||||
@@ -185,9 +171,7 @@ public sealed class ASFController : ArchiController {
|
||||
return Ok(new GenericResponse(success, message));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Makes ASF update itself.
|
||||
/// </summary>
|
||||
[EndpointSummary("Makes ASF update itself")]
|
||||
[HttpPost("Update")]
|
||||
[ProducesResponseType<GenericResponse<string>>((int) HttpStatusCode.OK)]
|
||||
public async Task<ActionResult<GenericResponse<string>>> UpdatePost([FromBody] UpdateRequest request) {
|
||||
|
||||
@@ -23,18 +23,16 @@
|
||||
|
||||
using System.Net;
|
||||
using ArchiSteamFarm.IPC.Responses;
|
||||
using ArchiSteamFarm.Storage;
|
||||
using Microsoft.AspNetCore.Mvc;
|
||||
using Swashbuckle.AspNetCore.Annotations;
|
||||
|
||||
namespace ArchiSteamFarm.IPC.Controllers.Api;
|
||||
|
||||
[ApiController]
|
||||
[Produces("application/json")]
|
||||
[ProducesResponseType<GenericResponse>((int) HttpStatusCode.BadRequest)]
|
||||
[ProducesResponseType<GenericResponse<StatusCodeResponse>>((int) HttpStatusCode.Unauthorized)]
|
||||
[ProducesResponseType<GenericResponse<StatusCodeResponse>>((int) HttpStatusCode.Forbidden)]
|
||||
[ProducesResponseType((int) HttpStatusCode.InternalServerError)]
|
||||
[ProducesResponseType((int) HttpStatusCode.ServiceUnavailable)]
|
||||
[Route("Api")]
|
||||
[SwaggerResponse((int) HttpStatusCode.BadRequest, $"The request has failed, check {nameof(GenericResponse.Message)} from response body for actual reason. Most of the time this is ASF, understanding the request, but refusing to execute it due to provided reason.", typeof(GenericResponse))]
|
||||
[SwaggerResponse((int) HttpStatusCode.Unauthorized, $"ASF has {nameof(GlobalConfig.IPCPassword)} set, but you've failed to authenticate. See {SharedInfo.ProjectURL}/wiki/IPC#authentication.", typeof(GenericResponse<StatusCodeResponse>))]
|
||||
[SwaggerResponse((int) HttpStatusCode.Forbidden, $"ASF lacks {nameof(GlobalConfig.IPCPassword)} and you're not permitted to access the API, or {nameof(GlobalConfig.IPCPassword)} is set and you've failed to authenticate too many times (try again in an hour). See {SharedInfo.ProjectURL}/wiki/IPC#authentication.", typeof(GenericResponse<StatusCodeResponse>))]
|
||||
[SwaggerResponse((int) HttpStatusCode.InternalServerError, "ASF has encountered an unexpected error while serving the request. The log may include extra info related to this issue.")]
|
||||
[SwaggerResponse((int) HttpStatusCode.ServiceUnavailable, "ASF has encountered an error while requesting a third-party resource. Try again later.")]
|
||||
public abstract class ArchiController : ControllerBase;
|
||||
|
||||
@@ -34,6 +34,7 @@ using ArchiSteamFarm.IPC.Responses;
|
||||
using ArchiSteamFarm.Localization;
|
||||
using ArchiSteamFarm.Steam;
|
||||
using ArchiSteamFarm.Steam.Storage;
|
||||
using Microsoft.AspNetCore.Http;
|
||||
using Microsoft.AspNetCore.Mvc;
|
||||
using SteamKit2;
|
||||
using SteamKit2.Internal;
|
||||
@@ -42,10 +43,7 @@ namespace ArchiSteamFarm.IPC.Controllers.Api;
|
||||
|
||||
[Route("Api/Bot")]
|
||||
public sealed class BotController : ArchiController {
|
||||
/// <summary>
|
||||
/// Adds (free) licenses on given bots.
|
||||
/// </summary>
|
||||
[Consumes("application/json")]
|
||||
[EndpointSummary("Adds (free) licenses on given bots")]
|
||||
[HttpPost("{botNames:required}/AddLicense")]
|
||||
[ProducesResponseType<GenericResponse<IReadOnlyDictionary<string, BotAddLicenseResponse>>>((int) HttpStatusCode.OK)]
|
||||
[ProducesResponseType<GenericResponse>((int) HttpStatusCode.BadRequest)]
|
||||
@@ -74,9 +72,7 @@ public sealed class BotController : ArchiController {
|
||||
return Ok(new GenericResponse<IReadOnlyDictionary<string, BotAddLicenseResponse>>(result));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Deletes all files related to given bots.
|
||||
/// </summary>
|
||||
[EndpointSummary("Deletes all files related to given bots")]
|
||||
[HttpDelete("{botNames:required}")]
|
||||
[ProducesResponseType<GenericResponse>((int) HttpStatusCode.OK)]
|
||||
[ProducesResponseType<GenericResponse>((int) HttpStatusCode.BadRequest)]
|
||||
@@ -94,9 +90,7 @@ public sealed class BotController : ArchiController {
|
||||
return Ok(new GenericResponse(results.All(static result => result)));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Fetches common info related to given bots.
|
||||
/// </summary>
|
||||
[EndpointSummary("Fetches common info related to given bots")]
|
||||
[HttpGet("{botNames:required}")]
|
||||
[ProducesResponseType<GenericResponse<IReadOnlyDictionary<string, Bot>>>((int) HttpStatusCode.OK)]
|
||||
[ProducesResponseType<GenericResponse>((int) HttpStatusCode.BadRequest)]
|
||||
@@ -112,10 +106,7 @@ public sealed class BotController : ArchiController {
|
||||
return Ok(new GenericResponse<IReadOnlyDictionary<string, Bot>>(bots.Where(static bot => !string.IsNullOrEmpty(bot.BotName)).ToDictionary(static bot => bot.BotName, static bot => bot, Bot.BotsComparer)));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Updates bot config of given bot.
|
||||
/// </summary>
|
||||
[Consumes("application/json")]
|
||||
[EndpointSummary("Updates bot config of given bot")]
|
||||
[HttpPost("{botNames:required}")]
|
||||
[ProducesResponseType<GenericResponse<IReadOnlyDictionary<string, bool>>>((int) HttpStatusCode.OK)]
|
||||
[ProducesResponseType<GenericResponse>((int) HttpStatusCode.BadRequest)]
|
||||
@@ -185,9 +176,7 @@ public sealed class BotController : ArchiController {
|
||||
return Ok(new GenericResponse<IReadOnlyDictionary<string, bool>>(result.Values.All(static value => value), result));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Removes BGR output files of given bots.
|
||||
/// </summary>
|
||||
[EndpointSummary("Removes BGR output files of given bots")]
|
||||
[HttpDelete("{botNames:required}/GamesToRedeemInBackground")]
|
||||
[ProducesResponseType<GenericResponse>((int) HttpStatusCode.OK)]
|
||||
[ProducesResponseType<GenericResponse>((int) HttpStatusCode.BadRequest)]
|
||||
@@ -205,9 +194,7 @@ public sealed class BotController : ArchiController {
|
||||
return Ok(results.All(static result => result) ? new GenericResponse(true) : new GenericResponse(false, Strings.WarningFailed));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Fetches BGR output files of given bots.
|
||||
/// </summary>
|
||||
[EndpointSummary("Fetches BGR output files of given bots")]
|
||||
[HttpGet("{botNames:required}/GamesToRedeemInBackground")]
|
||||
[ProducesResponseType<GenericResponse<IReadOnlyDictionary<string, GamesToRedeemInBackgroundResponse>>>((int) HttpStatusCode.OK)]
|
||||
[ProducesResponseType<GenericResponse>((int) HttpStatusCode.BadRequest)]
|
||||
@@ -232,10 +219,7 @@ public sealed class BotController : ArchiController {
|
||||
return Ok(new GenericResponse<IReadOnlyDictionary<string, GamesToRedeemInBackgroundResponse>>(result));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Adds keys to redeem using BGR to given bot.
|
||||
/// </summary>
|
||||
[Consumes("application/json")]
|
||||
[EndpointSummary("Adds keys to redeem using BGR to given bot")]
|
||||
[HttpPost("{botNames:required}/GamesToRedeemInBackground")]
|
||||
[ProducesResponseType<GenericResponse<IReadOnlyDictionary<string, IOrderedDictionary>>>((int) HttpStatusCode.OK)]
|
||||
[ProducesResponseType<GenericResponse>((int) HttpStatusCode.BadRequest)]
|
||||
@@ -270,10 +254,7 @@ public sealed class BotController : ArchiController {
|
||||
return Ok(new GenericResponse<IReadOnlyDictionary<string, IOrderedDictionary>>(result));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Provides input value to given bot for next usage.
|
||||
/// </summary>
|
||||
[Consumes("application/json")]
|
||||
[EndpointSummary("Provides input value to given bot for next usage")]
|
||||
[HttpPost("{botNames:required}/Input")]
|
||||
[ProducesResponseType<GenericResponse>((int) HttpStatusCode.OK)]
|
||||
[ProducesResponseType<GenericResponse>((int) HttpStatusCode.BadRequest)]
|
||||
@@ -296,10 +277,7 @@ public sealed class BotController : ArchiController {
|
||||
return Ok(results.All(static result => result) ? new GenericResponse(true) : new GenericResponse(false, Strings.WarningFailed));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Pauses given bots.
|
||||
/// </summary>
|
||||
[Consumes("application/json")]
|
||||
[EndpointSummary("Pauses given bots")]
|
||||
[HttpPost("{botNames:required}/Pause")]
|
||||
[ProducesResponseType<GenericResponse>((int) HttpStatusCode.OK)]
|
||||
[ProducesResponseType<GenericResponse>((int) HttpStatusCode.BadRequest)]
|
||||
@@ -318,10 +296,7 @@ public sealed class BotController : ArchiController {
|
||||
return Ok(new GenericResponse(results.All(static result => result.Success), string.Join(Environment.NewLine, results.Select(static result => result.Message))));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Redeems points on given bots.
|
||||
/// </summary>
|
||||
[Consumes("application/json")]
|
||||
[EndpointSummary("Redeems points on given bots")]
|
||||
[HttpPost("{botNames:required}/RedeemPoints/{definitionID:required}")]
|
||||
[ProducesResponseType<GenericResponse<IReadOnlyDictionary<string, EResult>>>((int) HttpStatusCode.OK)]
|
||||
[ProducesResponseType<GenericResponse>((int) HttpStatusCode.BadRequest)]
|
||||
@@ -346,14 +321,8 @@ public sealed class BotController : ArchiController {
|
||||
return Ok(new GenericResponse<IReadOnlyDictionary<string, EResult>>(result));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Redeems cd-keys on given bot.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// Response contains a map that maps each provided cd-key to its redeem result.
|
||||
/// Redeem result can be a null value, this means that ASF didn't even attempt to send a request (e.g. because of bot not being connected to Steam network).
|
||||
/// </remarks>
|
||||
[Consumes("application/json")]
|
||||
[EndpointDescription("Response contains a map that maps each provided cd-key to its redeem result. Redeem result can be a null value, this means that ASF didn't even attempt to send a request (e.g. because of bot not being connected to Steam network)")]
|
||||
[EndpointSummary("Redeems cd-keys on given bot")]
|
||||
[HttpPost("{botNames:required}/Redeem")]
|
||||
[ProducesResponseType<GenericResponse<IReadOnlyDictionary<string, IReadOnlyDictionary<string, CStore_RegisterCDKey_Response>>>>((int) HttpStatusCode.OK)]
|
||||
[ProducesResponseType<GenericResponse>((int) HttpStatusCode.BadRequest)]
|
||||
@@ -389,10 +358,7 @@ public sealed class BotController : ArchiController {
|
||||
return Ok(new GenericResponse<IReadOnlyDictionary<string, IReadOnlyDictionary<string, CStore_RegisterCDKey_Response?>>>(result.Values.SelectMany(static responses => responses.Values).All(static value => value != null), result));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Renames given bot along with all its related files.
|
||||
/// </summary>
|
||||
[Consumes("application/json")]
|
||||
[EndpointSummary("Renames given bot along with all its related files")]
|
||||
[HttpPost("{botName:required}/Rename")]
|
||||
[ProducesResponseType<GenericResponse>((int) HttpStatusCode.OK)]
|
||||
[ProducesResponseType<GenericResponse>((int) HttpStatusCode.BadRequest)]
|
||||
@@ -417,9 +383,7 @@ public sealed class BotController : ArchiController {
|
||||
return Ok(new GenericResponse(result));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Resumes given bots.
|
||||
/// </summary>
|
||||
[EndpointSummary("Resumes given bots")]
|
||||
[HttpPost("{botNames:required}/Resume")]
|
||||
[ProducesResponseType<GenericResponse>((int) HttpStatusCode.OK)]
|
||||
[ProducesResponseType<GenericResponse>((int) HttpStatusCode.BadRequest)]
|
||||
@@ -437,9 +401,7 @@ public sealed class BotController : ArchiController {
|
||||
return Ok(new GenericResponse(results.All(static result => result.Success), string.Join(Environment.NewLine, results.Select(static result => result.Message))));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Starts given bots.
|
||||
/// </summary>
|
||||
[EndpointSummary("Starts given bots")]
|
||||
[HttpPost("{botNames:required}/Start")]
|
||||
[ProducesResponseType<GenericResponse>((int) HttpStatusCode.OK)]
|
||||
[ProducesResponseType<GenericResponse>((int) HttpStatusCode.BadRequest)]
|
||||
@@ -457,9 +419,7 @@ public sealed class BotController : ArchiController {
|
||||
return Ok(new GenericResponse(results.All(static result => result.Success), string.Join(Environment.NewLine, results.Select(static result => result.Message))));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Stops given bots.
|
||||
/// </summary>
|
||||
[EndpointSummary("Stops given bots")]
|
||||
[HttpPost("{botNames:required}/Stop")]
|
||||
[ProducesResponseType<GenericResponse>((int) HttpStatusCode.OK)]
|
||||
[ProducesResponseType<GenericResponse>((int) HttpStatusCode.BadRequest)]
|
||||
|
||||
@@ -31,6 +31,7 @@ using ArchiSteamFarm.IPC.Responses;
|
||||
using ArchiSteamFarm.Localization;
|
||||
using ArchiSteamFarm.Steam;
|
||||
using ArchiSteamFarm.Storage;
|
||||
using Microsoft.AspNetCore.Http;
|
||||
using Microsoft.AspNetCore.Mvc;
|
||||
using Microsoft.Extensions.Hosting;
|
||||
|
||||
@@ -46,14 +47,8 @@ public sealed class CommandController : ArchiController {
|
||||
ApplicationLifetime = applicationLifetime;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Executes a command.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// This API endpoint is supposed to be entirely replaced by ASF actions available under /Api/ASF/{action} and /Api/Bot/{bot}/{action}.
|
||||
/// You should use "given bot" commands when executing this endpoint, omitting targets of the command will cause the command to be executed on first defined bot
|
||||
/// </remarks>
|
||||
[Consumes("application/json")]
|
||||
[EndpointDescription($"This API endpoint is supposed to be entirely replaced by ASF actions available under /Api/ASF/{{action}} and /Api/Bot/{{bot}}/{{action}}. You should use \"given bot\" commands when executing this endpoint, omitting targets of the command will cause the command to be executed on {nameof(GlobalConfig.DefaultBot)}")]
|
||||
[EndpointSummary("Executes a command")]
|
||||
[HttpPost]
|
||||
[ProducesResponseType<GenericResponse<string>>((int) HttpStatusCode.OK)]
|
||||
[ProducesResponseType<GenericResponse>((int) HttpStatusCode.BadRequest)]
|
||||
|
||||
@@ -32,18 +32,15 @@ using ArchiSteamFarm.Localization;
|
||||
using ArchiSteamFarm.Web;
|
||||
using ArchiSteamFarm.Web.GitHub;
|
||||
using ArchiSteamFarm.Web.GitHub.Data;
|
||||
using Microsoft.AspNetCore.Http;
|
||||
using Microsoft.AspNetCore.Mvc;
|
||||
|
||||
namespace ArchiSteamFarm.IPC.Controllers.Api;
|
||||
|
||||
[Route("Api/WWW/GitHub")]
|
||||
public sealed class GitHubController : ArchiController {
|
||||
/// <summary>
|
||||
/// Fetches the most recent GitHub release of ASF project.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// This is internal API being utilizied by our ASF-ui IPC frontend. You should not depend on existence of any /Api/WWW endpoints as they can disappear and change anytime.
|
||||
/// </remarks>
|
||||
[EndpointDescription("This is internal API being utilizied by our ASF-ui IPC frontend. You should not depend on existence of any /Api/WWW endpoints as they can disappear and change anytime")]
|
||||
[EndpointSummary("Fetches the most recent GitHub release of ASF project")]
|
||||
[HttpGet("Release")]
|
||||
[ProducesResponseType<GenericResponse<GitHubReleaseResponse>>((int) HttpStatusCode.OK)]
|
||||
[ProducesResponseType<GenericResponse>((int) HttpStatusCode.ServiceUnavailable)]
|
||||
@@ -55,12 +52,8 @@ public sealed class GitHubController : ArchiController {
|
||||
return releaseResponse != null ? Ok(new GenericResponse<GitHubReleaseResponse>(new GitHubReleaseResponse(releaseResponse))) : StatusCode((int) HttpStatusCode.ServiceUnavailable, new GenericResponse(false, Strings.FormatErrorRequestFailedTooManyTimes(WebBrowser.MaxTries)));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Fetches specific GitHub release of ASF project. Use "latest" for latest stable release.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// This is internal API being utilizied by our ASF-ui IPC frontend. You should not depend on existence of any /Api/WWW endpoints as they can disappear and change anytime.
|
||||
/// </remarks>
|
||||
[EndpointDescription("This is internal API being utilizied by our ASF-ui IPC frontend. You should not depend on existence of any /Api/WWW endpoints as they can disappear and change anytime")]
|
||||
[EndpointSummary("Fetches specific GitHub release of ASF project. Use \"latest\" for latest stable release")]
|
||||
[HttpGet("Release/{version:required}")]
|
||||
[ProducesResponseType<GenericResponse<GitHubReleaseResponse>>((int) HttpStatusCode.OK)]
|
||||
[ProducesResponseType<GenericResponse>((int) HttpStatusCode.BadRequest)]
|
||||
@@ -90,12 +83,8 @@ public sealed class GitHubController : ArchiController {
|
||||
return releaseResponse != null ? Ok(new GenericResponse<GitHubReleaseResponse>(new GitHubReleaseResponse(releaseResponse))) : StatusCode((int) HttpStatusCode.ServiceUnavailable, new GenericResponse(false, Strings.FormatErrorRequestFailedTooManyTimes(WebBrowser.MaxTries)));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Fetches history of specific GitHub page from ASF project.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// This is internal API being utilizied by our ASF-ui IPC frontend. You should not depend on existence of any /Api/WWW endpoints as they can disappear and change anytime.
|
||||
/// </remarks>
|
||||
[EndpointDescription("This is internal API being utilizied by our ASF-ui IPC frontend. You should not depend on existence of any /Api/WWW endpoints as they can disappear and change anytime")]
|
||||
[EndpointSummary("Fetches history of specific GitHub page from ASF project")]
|
||||
[HttpGet("Wiki/History/{page:required}")]
|
||||
[ProducesResponseType<GenericResponse<string>>((int) HttpStatusCode.OK)]
|
||||
[ProducesResponseType<GenericResponse>((int) HttpStatusCode.BadRequest)]
|
||||
@@ -110,13 +99,8 @@ public sealed class GitHubController : ArchiController {
|
||||
return revisions != null ? revisions.Count > 0 ? Ok(new GenericResponse<ImmutableDictionary<string, DateTime>>(revisions.ToImmutableDictionary())) : BadRequest(new GenericResponse(false, Strings.FormatErrorIsInvalid(nameof(page)))) : StatusCode((int) HttpStatusCode.ServiceUnavailable, new GenericResponse(false, Strings.FormatErrorRequestFailedTooManyTimes(WebBrowser.MaxTries)));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Fetches specific GitHub page of ASF project.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// This is internal API being utilizied by our ASF-ui IPC frontend. You should not depend on existence of any /Api/WWW endpoints as they can disappear and change anytime.
|
||||
/// Specifying revision is optional - when not specified, will fetch latest available. If specified revision is invalid, GitHub will automatically fetch the latest revision as well.
|
||||
/// </remarks>
|
||||
[EndpointDescription("This is internal API being utilizied by our ASF-ui IPC frontend. You should not depend on existence of any /Api/WWW endpoints as they can disappear and change anytime. Specifying revision is optional - when not specified, will fetch latest available. If specified revision is invalid, GitHub will automatically fetch the latest revision as well")]
|
||||
[EndpointSummary("Fetches specific GitHub page of ASF project")]
|
||||
[HttpGet("Wiki/Page/{page:required}")]
|
||||
[ProducesResponseType<GenericResponse<string>>((int) HttpStatusCode.OK)]
|
||||
[ProducesResponseType<GenericResponse>((int) HttpStatusCode.BadRequest)]
|
||||
|
||||
@@ -26,6 +26,7 @@ using System.Net;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
using ArchiSteamFarm.IPC.Responses;
|
||||
using Microsoft.AspNetCore.Http;
|
||||
using Microsoft.AspNetCore.Mvc;
|
||||
using Microsoft.Extensions.Diagnostics.HealthChecks;
|
||||
|
||||
@@ -43,6 +44,8 @@ public sealed class HealthCheckController : ControllerBase {
|
||||
HealthCheckService = healthCheckService;
|
||||
}
|
||||
|
||||
[EndpointDescription("This endpoint can be called in order to easily check whether the program is up")]
|
||||
[EndpointSummary("Fetches current application's status")]
|
||||
[HttpGet]
|
||||
[ProducesResponseType(typeof(HealthCheckResponse), (int) HttpStatusCode.OK)]
|
||||
[ProducesResponseType(typeof(HealthCheckResponse), (int) HttpStatusCode.ServiceUnavailable)]
|
||||
|
||||
@@ -28,15 +28,14 @@ using System.Net;
|
||||
using ArchiSteamFarm.IPC.Integration;
|
||||
using ArchiSteamFarm.IPC.Responses;
|
||||
using ArchiSteamFarm.Localization;
|
||||
using Microsoft.AspNetCore.Http;
|
||||
using Microsoft.AspNetCore.Mvc;
|
||||
|
||||
namespace ArchiSteamFarm.IPC.Controllers.Api;
|
||||
|
||||
[Route("Api/IPC/Bans")]
|
||||
public sealed class IPCBansController : ArchiController {
|
||||
/// <summary>
|
||||
/// Clears the list of all IP addresses currently blocked by ASFs IPC module
|
||||
/// </summary>
|
||||
[EndpointSummary("Clears the list of all IP addresses currently blocked by ASFs IPC module")]
|
||||
[HttpDelete]
|
||||
[ProducesResponseType<GenericResponse>((int) HttpStatusCode.OK)]
|
||||
public ActionResult<GenericResponse> Delete() {
|
||||
@@ -45,9 +44,7 @@ public sealed class IPCBansController : ArchiController {
|
||||
return Ok(new GenericResponse(true));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Removes an IP address from the list of addresses currently blocked by ASFs IPC module
|
||||
/// </summary>
|
||||
[EndpointSummary("Removes an IP address from the list of addresses currently blocked by ASFs IPC module")]
|
||||
[HttpDelete("{ipAddress:required}")]
|
||||
[ProducesResponseType<GenericResponse>((int) HttpStatusCode.OK)]
|
||||
[ProducesResponseType<GenericResponse>((int) HttpStatusCode.BadRequest)]
|
||||
@@ -67,9 +64,7 @@ public sealed class IPCBansController : ArchiController {
|
||||
return Ok(new GenericResponse(true));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets all IP addresses currently blocked by ASFs IPC module
|
||||
/// </summary>
|
||||
[EndpointSummary("Gets all IP addresses currently blocked by ASFs IPC module")]
|
||||
[HttpGet]
|
||||
[ProducesResponseType<GenericResponse<IReadOnlySet<string>>>((int) HttpStatusCode.OK)]
|
||||
public ActionResult<GenericResponse<IReadOnlySet<string>>> Get() => Ok(new GenericResponse<IReadOnlySet<string>>(ApiAuthenticationMiddleware.GetCurrentlyBannedIPs().Select(static ip => ip.ToString()).ToHashSet()));
|
||||
|
||||
@@ -6,7 +6,7 @@
|
||||
// /_/ \_\|_| \___||_| |_||_||____/ \__|\___| \__,_||_| |_| |_||_| \__,_||_| |_| |_| |_|
|
||||
// ----------------------------------------------------------------------------------------------
|
||||
// |
|
||||
// Copyright 2015-2024 Łukasz "JustArchi" Domeradzki
|
||||
// Copyright 2015-2025 Łukasz "JustArchi" Domeradzki
|
||||
// Contact: JustArchi@JustArchi.net
|
||||
// |
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
@@ -24,6 +24,7 @@
|
||||
using System;
|
||||
using System.Collections.Concurrent;
|
||||
using System.Collections.Generic;
|
||||
using System.ComponentModel;
|
||||
using System.Linq;
|
||||
using System.Net;
|
||||
using System.Net.WebSockets;
|
||||
@@ -37,6 +38,7 @@ using ArchiSteamFarm.Localization;
|
||||
using ArchiSteamFarm.NLog;
|
||||
using ArchiSteamFarm.NLog.Targets;
|
||||
using Microsoft.AspNetCore.Connections;
|
||||
using Microsoft.AspNetCore.Http;
|
||||
using Microsoft.AspNetCore.Mvc;
|
||||
using Microsoft.Extensions.Hosting;
|
||||
|
||||
@@ -54,16 +56,12 @@ public sealed class NLogController : ArchiController {
|
||||
ApplicationLifetime = applicationLifetime;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Fetches ASF log file, this works on assumption that the log file is in fact generated, as user could disable it through custom configuration.
|
||||
/// </summary>
|
||||
/// <param name="count">Maximum amount of lines from the log file returned. The respone naturally might have less amount than specified, if you've read whole file already.</param>
|
||||
/// <param name="lastAt">Ending index, used for pagination. Omit it for the first request, then initialize to TotalLines returned, and on every following request subtract count that you've used in the previous request from it until you hit 0 or less, which means you've read whole file already.</param>
|
||||
[EndpointSummary("Fetches ASF log file, this works on assumption that the log file is in fact generated, as user could disable it through custom configuration")]
|
||||
[HttpGet("File")]
|
||||
[ProducesResponseType<GenericResponse<GenericResponse<LogResponse>>>((int) HttpStatusCode.OK)]
|
||||
[ProducesResponseType<GenericResponse>((int) HttpStatusCode.BadRequest)]
|
||||
[ProducesResponseType<GenericResponse>((int) HttpStatusCode.ServiceUnavailable)]
|
||||
public async Task<ActionResult<GenericResponse>> FileGet(int count = 100, int lastAt = 0) {
|
||||
public async Task<ActionResult<GenericResponse>> FileGet([Description("Maximum amount of lines from the log file returned. The respone naturally might have less amount than specified, if you've read whole file already")] int count = 100, [Description("Ending index, used for pagination. Omit it for the first request, then initialize to TotalLines returned, and on every following request subtract count that you've used in the previous request from it until you hit 0 or less, which means you've read whole file already")] int lastAt = 0) {
|
||||
if (count <= 0) {
|
||||
return BadRequest(new GenericResponse(false, Strings.FormatErrorIsInvalid(nameof(count))));
|
||||
}
|
||||
@@ -91,12 +89,8 @@ public sealed class NLogController : ArchiController {
|
||||
return Ok(new GenericResponse<LogResponse>(new LogResponse(lines.Length, lines[startFrom..lastAt])));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Fetches ASF log in realtime.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// This API endpoint requires a websocket connection.
|
||||
/// </remarks>
|
||||
[EndpointDescription("This API endpoint requires a websocket connection")]
|
||||
[EndpointSummary("Fetches ASF log in realtime")]
|
||||
[HttpGet]
|
||||
[ProducesResponseType<IEnumerable<GenericResponse<string>>>((int) HttpStatusCode.OK)]
|
||||
[ProducesResponseType<GenericResponse>((int) HttpStatusCode.BadRequest)]
|
||||
|
||||
@@ -31,15 +31,14 @@ using ArchiSteamFarm.Localization;
|
||||
using ArchiSteamFarm.Plugins;
|
||||
using ArchiSteamFarm.Plugins.Interfaces;
|
||||
using ArchiSteamFarm.Steam.Interaction;
|
||||
using Microsoft.AspNetCore.Http;
|
||||
using Microsoft.AspNetCore.Mvc;
|
||||
|
||||
namespace ArchiSteamFarm.IPC.Controllers.Api;
|
||||
|
||||
[Route("Api/Plugins")]
|
||||
public sealed class PluginsController : ArchiController {
|
||||
/// <summary>
|
||||
/// Gets active plugins loaded into the process.
|
||||
/// </summary>
|
||||
[EndpointSummary("Gets active plugins loaded into the process")]
|
||||
[HttpGet]
|
||||
[ProducesResponseType<GenericResponse<IReadOnlyCollection<IPlugin>>>((int) HttpStatusCode.OK)]
|
||||
public ActionResult<GenericResponse<IReadOnlyCollection<IPlugin>>> PluginsGet([FromQuery] bool official = true, [FromQuery] bool custom = true) {
|
||||
@@ -60,9 +59,7 @@ public sealed class PluginsController : ArchiController {
|
||||
return Ok(new GenericResponse<IReadOnlyCollection<IPlugin>>(result));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Makes ASF update selected plugins.
|
||||
/// </summary>
|
||||
[EndpointSummary("Makes ASF update selected plugins")]
|
||||
[HttpPost("Update")]
|
||||
[ProducesResponseType<GenericResponse<string>>((int) HttpStatusCode.OK)]
|
||||
public async Task<ActionResult<GenericResponse<string>>> UpdatePost([FromBody] PluginUpdateRequest request) {
|
||||
|
||||
@@ -26,15 +26,14 @@ using System.Net;
|
||||
using System.Text.Json;
|
||||
using ArchiSteamFarm.Core;
|
||||
using ArchiSteamFarm.IPC.Responses;
|
||||
using Microsoft.AspNetCore.Http;
|
||||
using Microsoft.AspNetCore.Mvc;
|
||||
|
||||
namespace ArchiSteamFarm.IPC.Controllers.Api;
|
||||
|
||||
[Route("Api/Storage/{key:required}")]
|
||||
public sealed class StorageController : ArchiController {
|
||||
/// <summary>
|
||||
/// Deletes entry under specified key from ASF's persistent KeyValue JSON storage.
|
||||
/// </summary>
|
||||
[EndpointSummary("Deletes entry under specified key from ASF's persistent KeyValue JSON storage")]
|
||||
[HttpDelete]
|
||||
[ProducesResponseType<GenericResponse>((int) HttpStatusCode.OK)]
|
||||
public ActionResult<GenericResponse> StorageDelete(string key) {
|
||||
@@ -49,9 +48,7 @@ public sealed class StorageController : ArchiController {
|
||||
return Ok(new GenericResponse(true));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Loads entry under specified key from ASF's persistent KeyValue JSON storage.
|
||||
/// </summary>
|
||||
[EndpointSummary("Loads entry under specified key from ASF's persistent KeyValue JSON storage")]
|
||||
[HttpGet]
|
||||
[ProducesResponseType<GenericResponse<JsonElement?>>((int) HttpStatusCode.OK)]
|
||||
public ActionResult<GenericResponse> StorageGet(string key) {
|
||||
@@ -66,10 +63,7 @@ public sealed class StorageController : ArchiController {
|
||||
return Ok(new GenericResponse<JsonElement?>(true, value.ValueKind != JsonValueKind.Undefined ? value : null));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Saves entry under specified key in ASF's persistent KeyValue JSON storage.
|
||||
/// </summary>
|
||||
[Consumes("application/json")]
|
||||
[EndpointSummary("Saves entry under specified key in ASF's persistent KeyValue JSON storage")]
|
||||
[HttpPost]
|
||||
[ProducesResponseType<GenericResponse>((int) HttpStatusCode.OK)]
|
||||
public ActionResult<GenericResponse> StoragePost(string key, [FromBody] JsonElement value) {
|
||||
|
||||
@@ -26,18 +26,15 @@ using System.Diagnostics.CodeAnalysis;
|
||||
using System.Net;
|
||||
using ArchiSteamFarm.IPC.Responses;
|
||||
using ArchiSteamFarm.Localization;
|
||||
using Microsoft.AspNetCore.Http;
|
||||
using Microsoft.AspNetCore.Mvc;
|
||||
|
||||
namespace ArchiSteamFarm.IPC.Controllers.Api;
|
||||
|
||||
[Route("Api/Structure")]
|
||||
public sealed class StructureController : ArchiController {
|
||||
/// <summary>
|
||||
/// Fetches structure of given type.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// Structure is defined as a representation of given object in its default state.
|
||||
/// </remarks>
|
||||
[EndpointDescription("Structure is defined as a representation of given object in its default state")]
|
||||
[EndpointSummary("Fetches structure of given type")]
|
||||
[HttpGet("{structure:required}")]
|
||||
[ProducesResponseType<GenericResponse<object>>((int) HttpStatusCode.OK)]
|
||||
[ProducesResponseType<GenericResponse>((int) HttpStatusCode.BadRequest)]
|
||||
|
||||
@@ -33,15 +33,14 @@ using ArchiSteamFarm.Localization;
|
||||
using ArchiSteamFarm.Steam;
|
||||
using ArchiSteamFarm.Steam.Data;
|
||||
using ArchiSteamFarm.Steam.Security;
|
||||
using Microsoft.AspNetCore.Http;
|
||||
using Microsoft.AspNetCore.Mvc;
|
||||
|
||||
namespace ArchiSteamFarm.IPC.Controllers.Api;
|
||||
|
||||
[Route("Api/Bot/{botNames:required}/TwoFactorAuthentication")]
|
||||
public sealed class TwoFactorAuthenticationController : ArchiController {
|
||||
/// <summary>
|
||||
/// Fetches pending 2FA confirmations of given bots, requires ASF 2FA module to be active on them.
|
||||
/// </summary>
|
||||
[EndpointSummary("Fetches pending 2FA confirmations of given bots, requires ASF 2FA module to be active on them")]
|
||||
[HttpGet("Confirmations")]
|
||||
[ProducesResponseType<GenericResponse<IReadOnlyDictionary<string, GenericResponse<IReadOnlyCollection<Confirmation>>>>>((int) HttpStatusCode.OK)]
|
||||
[ProducesResponseType<GenericResponse>((int) HttpStatusCode.BadRequest)]
|
||||
@@ -66,10 +65,7 @@ public sealed class TwoFactorAuthenticationController : ArchiController {
|
||||
return Ok(new GenericResponse<IReadOnlyDictionary<string, GenericResponse<IReadOnlyCollection<Confirmation>>>>(result));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Handles 2FA confirmations of given bots, requires ASF 2FA module to be active on them.
|
||||
/// </summary>
|
||||
[Consumes("application/json")]
|
||||
[EndpointSummary("Handles 2FA confirmations of given bots, requires ASF 2FA module to be active on them")]
|
||||
[HttpPost("Confirmations")]
|
||||
[ProducesResponseType<GenericResponse<IReadOnlyDictionary<string, GenericResponse<IReadOnlyCollection<Confirmation>>>>>((int) HttpStatusCode.OK)]
|
||||
[ProducesResponseType<GenericResponse>((int) HttpStatusCode.BadRequest)]
|
||||
@@ -99,9 +95,7 @@ public sealed class TwoFactorAuthenticationController : ArchiController {
|
||||
return Ok(new GenericResponse<IReadOnlyDictionary<string, GenericResponse<IReadOnlyCollection<Confirmation>>>>(result));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Deletes the MobileAuthenticator of given bots if an ASF 2FA module is active on them.
|
||||
/// </summary>
|
||||
[EndpointSummary("Deletes the MobileAuthenticator of given bots if an ASF 2FA module is active on them")]
|
||||
[HttpDelete]
|
||||
[ProducesResponseType<GenericResponse<IReadOnlyDictionary<string, GenericResponse<string>>>>((int) HttpStatusCode.OK)]
|
||||
[ProducesResponseType<GenericResponse>((int) HttpStatusCode.BadRequest)]
|
||||
@@ -126,10 +120,7 @@ public sealed class TwoFactorAuthenticationController : ArchiController {
|
||||
return Ok(new GenericResponse<IReadOnlyDictionary<string, GenericResponse<string>>>(result));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Imports a MobileAuthenticator into the ASF 2FA module of a given bot.
|
||||
/// </summary>
|
||||
[Consumes("application/json")]
|
||||
[EndpointSummary("Imports a MobileAuthenticator into the ASF 2FA module of a given bot")]
|
||||
[HttpPost]
|
||||
[ProducesResponseType<GenericResponse<IReadOnlyDictionary<string, GenericResponse>>>((int) HttpStatusCode.OK)]
|
||||
[ProducesResponseType<GenericResponse>((int) HttpStatusCode.BadRequest)]
|
||||
@@ -155,9 +146,7 @@ public sealed class TwoFactorAuthenticationController : ArchiController {
|
||||
return Ok(new GenericResponse<IReadOnlyDictionary<string, GenericResponse>>(result));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Fetches 2FA tokens of given bots, requires ASF 2FA module to be active on them.
|
||||
/// </summary>
|
||||
[EndpointSummary("Fetches 2FA tokens of given bots, requires ASF 2FA module to be active on them")]
|
||||
[HttpGet("Token")]
|
||||
[ProducesResponseType<GenericResponse<IReadOnlyDictionary<string, GenericResponse<string>>>>((int) HttpStatusCode.OK)]
|
||||
[ProducesResponseType<GenericResponse>((int) HttpStatusCode.BadRequest)]
|
||||
|
||||
@@ -32,18 +32,15 @@ using System.Text.Json.Serialization;
|
||||
using ArchiSteamFarm.Core;
|
||||
using ArchiSteamFarm.IPC.Responses;
|
||||
using ArchiSteamFarm.Localization;
|
||||
using Microsoft.AspNetCore.Http;
|
||||
using Microsoft.AspNetCore.Mvc;
|
||||
|
||||
namespace ArchiSteamFarm.IPC.Controllers.Api;
|
||||
|
||||
[Route("Api/Type")]
|
||||
public sealed class TypeController : ArchiController {
|
||||
/// <summary>
|
||||
/// Fetches type info of given type.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// Type info is defined as a representation of given object with its fields and properties being assigned to a string value that defines their type.
|
||||
/// </remarks>
|
||||
[EndpointDescription("Type info is defined as a representation of given object with its fields and properties being assigned to a string value that defines their type")]
|
||||
[EndpointSummary("Fetches type info of given type")]
|
||||
[HttpGet("{type:required}")]
|
||||
[ProducesResponseType<GenericResponse<TypeResponse>>((int) HttpStatusCode.OK)]
|
||||
[ProducesResponseType<GenericResponse>((int) HttpStatusCode.BadRequest)]
|
||||
|
||||
Reference in New Issue
Block a user