Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -20,8 +20,8 @@
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
<PrivateAssets>all</PrivateAssets>
</PackageReference>
<PackageReference Include="MySql.EntityFrameworkCore" Version="8.0.8" />
<PackageReference Include="Swashbuckle.AspNetCore" Version="6.9.0" />
<PackageReference Include="MySql.EntityFrameworkCore" Version="8.0.8"/>
<PackageReference Include="Swashbuckle.AspNetCore" Version="6.9.0"/>
</ItemGroup>

<ItemGroup>
Expand Down
2 changes: 1 addition & 1 deletion src/Nullinside.Api.Common/Auth/AuthUtils.cs
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
namespace Nullinside.Api.Common.Auth;

/// <summary>
/// Random utilities for authentication.
/// Random utilities for authentication.
/// </summary>
public static class AuthUtils {
/// <summary>
Expand Down
2 changes: 1 addition & 1 deletion src/Nullinside.Api.Common/Desktop/GitHubUpdateManager.cs
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ namespace Nullinside.Api.Common.Desktop;
/// <summary>
/// Handles checking for updates to the application via GitHub releases.
/// </summary>
public class GitHubUpdateManager {
public static class GitHubUpdateManager {
/// <summary>
/// Gets the latest version number of the release.
/// </summary>
Expand Down
9 changes: 8 additions & 1 deletion src/Nullinside.Api.Common/Docker/DockerProxy.cs
Original file line number Diff line number Diff line change
Expand Up @@ -128,7 +128,14 @@ public async Task<bool> TurnOnOffDockerCompose(string name, bool turnOn, Cancell
(!turnOn && output.error.Contains("Stopped", StringComparison.InvariantCultureIgnoreCase));
}

private async Task<(string output, string error)> ExecuteCommand(string command, CancellationToken token,
/// <summary>
/// Executes an SSH command in the given directory.
/// </summary>
/// <param name="command">The command to execute.</param>
/// <param name="token">The cancellation token.</param>
/// <param name="dir">The directory to navigate to before executing the command.</param>
/// <returns>The STDOUT and STDERR of the command's execution.</returns>
private async Task<(string output, string error)> ExecuteCommand(string command, CancellationToken token = new(),
string? dir = null) {
using SshClient client = new(_server!, _username!, _password!);
await client.ConnectAsync(token);
Expand Down
6 changes: 3 additions & 3 deletions src/Nullinside.Api.Common/Nullinside.Api.Common.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -16,10 +16,10 @@
</PropertyGroup>

<ItemGroup>
<PackageReference Include="log4net" Version="2.0.17" />
<PackageReference Include="Microsoft.Extensions.Logging" Version="8.0.1" />
<PackageReference Include="log4net" Version="2.0.17"/>
<PackageReference Include="Microsoft.Extensions.Logging" Version="8.0.1"/>
<PackageReference Include="Newtonsoft.Json" Version="13.0.3"/>
<PackageReference Include="SSH.NET" Version="2024.1.0" />
<PackageReference Include="SSH.NET" Version="2024.1.0"/>
<PackageReference Include="TwitchLib.Api" Version="3.9.0"/>
<PackageReference Include="TwitchLib.Client" Version="3.3.1"/>
</ItemGroup>
Expand Down
2 changes: 1 addition & 1 deletion src/Nullinside.Api.Common/SqlScripts.cs
Original file line number Diff line number Diff line change
Expand Up @@ -71,7 +71,7 @@ public static class SqlScripts {
""";

/// <summary>
/// The inner function for the <see cref="LEVENSHTEIN_DISTANCE_SEARCH" />. Not meant to be called directly.
/// Removes <see cref="LEVENSHTEIN_DISTANCE_SEARCH_INNER_FUNCTION" />.
/// </summary>
public const string LEVENSHTEIN_DISTANCE_SEARCH_INNER_FUNCTION_REMOVE =
"""
Expand Down
107 changes: 107 additions & 0 deletions src/Nullinside.Api.Common/Twitch/ITwitchApiProxy.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,107 @@
using Nullinside.Api.Common.Twitch.Json;

using TwitchLib.Api.Helix.Models.Chat.GetChatters;
using TwitchLib.Api.Helix.Models.Moderation.BanUser;
using TwitchLib.Api.Helix.Models.Moderation.GetModerators;

namespace Nullinside.Api.Common.Twitch;

/// <summary>
/// The proxy for handling communication with Twitch.
/// </summary>
public interface ITwitchApiProxy {
/// <summary>
/// The Twitch access token. These are the credentials used for all requests.
/// </summary>
TwitchAccessToken? OAuth { get; set; }

/// <summary>
/// Creates a new access token from a code using Twitch's OAuth workflow.
/// </summary>
/// <param name="code">The code from twitch to send back to twitch to generate a new access token.</param>
/// <param name="token">The cancellation token.</param>
/// <remarks>The object will have its <see cref="OAuth" /> updated with the new settings for the token.</remarks>
/// <returns>The OAuth details if successful, null otherwise.</returns>
Task<TwitchAccessToken?> CreateAccessToken(string code, CancellationToken token = new());

/// <summary>
/// Refreshes the access token.
/// </summary>
/// <param name="token">The cancellation token.</param>
/// <remarks>The object will have its <see cref="OAuth" /> updated with the new settings for the token.</remarks>
/// <returns>The OAuth details if successful, null otherwise.</returns>
Task<TwitchAccessToken?> RefreshAccessToken(CancellationToken token = new());

/// <summary>
/// Determines if the <see cref="OAuth" /> is valid.
/// </summary>
/// <param name="token">The cancellation token.</param>
/// <returns>True if valid, false otherwise.</returns>
Task<bool> GetAccessTokenIsValid(CancellationToken token = new());

/// <summary>
/// Gets the twitch id and username of the owner of the <see cref="OAuth" />.
/// </summary>
/// <param name="token">The cancellation token.</param>
/// <returns>The twitch username if successful, null otherwise.</returns>
Task<(string? id, string? username)> GetUser(CancellationToken token = new());

/// <summary>
/// Gets the email address of the owner of the <see cref="OAuth" />.
/// </summary>
/// <param name="token">The cancellation token.</param>
/// <returns>The email address if successful, null otherwise.</returns>
Task<string?> GetUserEmail(CancellationToken token = new());

/// <summary>
/// Gets the list of channels the user moderates for.
/// </summary>
/// <param name="userId">The twitch id to scan.</param>
/// <returns>The list of channels the user moderates for.</returns>
Task<IEnumerable<TwitchModeratedChannel>> GetUserModChannels(string userId);

/// <summary>
/// Bans a list of users from a channel.
/// </summary>
/// <param name="channelId">The twitch id of the channel to ban the users from.</param>
/// <param name="botId">The twitch id of the bot user, the one banning the users.</param>
/// <param name="users">The list of users to ban.</param>
/// <param name="reason">The reason for the ban.</param>
/// <param name="token">The stopping token.</param>
/// <returns>The users with confirmed bans.</returns>
Task<IEnumerable<BannedUser>> BanChannelUsers(string channelId, string botId,
IEnumerable<(string Id, string Username)> users, string reason, CancellationToken token = new());

/// <summary>
/// Gets the list of mods for the channel.
/// </summary>
/// <param name="channelId">The twitch id of the channel to get mods for.</param>
/// <param name="token">The cancellation token.</param>
/// <returns>The collection of moderators.</returns>
Task<IEnumerable<Moderator>> GetChannelMods(string channelId, CancellationToken token = new());

/// <summary>
/// Gets the chatters currently in a channel.
/// </summary>
/// <param name="channelId">The twitch id of the channel that we are moderating.</param>
/// <param name="botId">The twitch id of the bot.</param>
/// <param name="token">The cancellation token.</param>
/// <returns>The collection of chatters.</returns>
Task<IEnumerable<Chatter>> GetChannelUsers(string channelId, string botId, CancellationToken token = new());

/// <summary>
/// Checks if the supplied channels are live.
/// </summary>
/// <param name="userIds">The twitch ids of the channels.</param>
/// <returns>The list of twitch channels that are currently live.</returns>
Task<IEnumerable<string>> GetChannelsLive(IEnumerable<string> userIds);

/// <summary>
/// Makes a user a moderator in a channel.
/// </summary>
/// <param name="channelId">The twitch id of the channel to add the mod to.</param>
/// <param name="userId">The twitch id to give the moderator role.</param>
/// <param name="token">The cancellation token.</param>
/// <returns>True if successful, false otherwise.</returns>
Task<bool> AddChannelMod(string channelId, string userId, CancellationToken token = new());
}
21 changes: 21 additions & 0 deletions src/Nullinside.Api.Common/Twitch/TwitchAccessToken.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
namespace Nullinside.Api.Common.Twitch;

/// <summary>
/// Represents an OAuth token in the Twitch workflow.
/// </summary>
public class TwitchAccessToken {
/// <summary>
/// The Twitch access token.
/// </summary>
public string? AccessToken { get; set; }

/// <summary>
/// The refresh token.
/// </summary>
public string? RefreshToken { get; set; }

/// <summary>
/// The UTC <see cref="DateTime" /> when the <see cref="AccessToken" /> expires.
/// </summary>
public DateTime? ExpiresUtc { get; set; }
}
Loading
Loading