Skip to content

Commit c21cd65

Browse files
committed
Add clipboard service + Argument parser
1 parent 0da2003 commit c21cd65

File tree

5 files changed

+111
-11
lines changed

5 files changed

+111
-11
lines changed

Arguments.cs

+37
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
using System.ComponentModel;
2+
using Ookii.CommandLine;
3+
4+
namespace SteamAuth
5+
{
6+
[ParseOptions(
7+
Mode = ParsingMode.LongShort,
8+
CaseSensitive = false,
9+
ArgumentNameTransform = NameTransform.DashCase,
10+
ValueDescriptionTransform = NameTransform.DashCase
11+
)]
12+
[Description("Generates a steam TOTP code using a provided secret.")]
13+
public class Arguments
14+
{
15+
16+
[CommandLineArgument(Position = 0, IsRequired = false)]
17+
[Description("Steam TOTP secret")]
18+
public string? Secret { get; set; }
19+
20+
[CommandLineArgument(IsRequired = false, ShortName = 's')]
21+
[Description("Whether to save the encrypted secret to a config file")]
22+
public bool Save { get; set; }
23+
24+
internal bool IsInvalid { get; private set; }
25+
26+
public Arguments()
27+
{
28+
Secret = null;
29+
Save = false;
30+
}
31+
32+
internal Arguments(bool isInvalid) : this()
33+
{
34+
IsInvalid = isInvalid;
35+
}
36+
}
37+
}

Program.cs

+24-9
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,9 @@
22
using SteamGuardTotp = SteamGuard.TOTP.SteamGuard;
33
using SteamAuth.Utils;
44
using System.Security.Cryptography;
5+
using TextCopy;
6+
using Ookii.CommandLine;
7+
using Ookii.CommandLine.Terminal;
58

69
namespace SteamAuth;
710

@@ -10,33 +13,39 @@ class Program
1013
const string STEAMGUARD_FILE = "steamauth.json";
1114
private static readonly SteamGuardTotp steamGuard = new();
1215
private static readonly string steamGuardPath = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, STEAMGUARD_FILE);
16+
private static readonly ConsoleWriter console = new();
1317

14-
private static int Main(string[] args)
18+
private static int Main()
1519
{
16-
var result = args.Length == 0 ? ProcessFile() : ProcessArgs(args);
20+
var args = CommandLineParser.Parse<Arguments>() ?? new(isInvalid: true);
21+
if (args.IsInvalid)
22+
{
23+
return (int)Status.InvalidArguments;
24+
}
25+
26+
var result = string.IsNullOrWhiteSpace(args.Secret) ? ProcessFile() : ProcessArgs(args);
1727

1828
if (result != Status.Success)
1929
{
20-
Console.Error.WriteLine(result.GetMessage());
30+
console.WriteLine(result.GetMessage(), TextFormat.ForegroundRed, TextFormat.BoldBright);
2131
}
2232

2333
return (int)result;
2434
}
2535

26-
private static Status ProcessArgs(string[] args)
36+
private static Status ProcessArgs(Arguments args)
2737
{
28-
var secret = args[0];
29-
var shouldSave = args.Length > 1 && args[1].Contains("-s", StringComparison.InvariantCultureIgnoreCase);
38+
var secret = args.Secret ?? string.Empty;
3039

3140
var code = steamGuard.GenerateAuthenticationCode(secret);
3241
if (code is null)
3342
{
3443
return Status.TotpGenerationFailure;
3544
}
3645

37-
Console.WriteLine(code);
46+
OutputTotpCode(code);
3847

39-
if (shouldSave)
48+
if (args.Save)
4049
{
4150
var entropy = new byte[20];
4251
RandomNumberGenerator.Fill(entropy);
@@ -84,10 +93,16 @@ private static Status ProcessFile()
8493
var code = steamGuard.GenerateAuthenticationCode(secret);
8594
if (code is not null)
8695
{
87-
Console.WriteLine(code);
96+
OutputTotpCode(code);
8897
return Status.Success;
8998
}
9099

91100
return Status.TotpGenerationFailure;
92101
}
102+
103+
private static void OutputTotpCode(string code)
104+
{
105+
console.WriteLine(code, TextFormat.ForegroundGreen, TextFormat.BoldBright);
106+
ClipboardService.SetText(code);
107+
}
93108
}

Utils/Status.cs Status.cs

+2-1
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,8 @@
1-
namespace SteamAuth.Utils;
1+
namespace SteamAuth;
22
enum Status
33
{
44
Success = 0,
5+
InvalidArguments = -1,
56
PlatformNotSupported = -2,
67
ConfigFileNotFound = -3,
78
EncryptionFailure = -4,

SteamAuth.csproj

+6-1
Original file line numberDiff line numberDiff line change
@@ -1,22 +1,27 @@
11
<Project Sdk="Microsoft.NET.Sdk">
22

33
<PropertyGroup>
4+
<Version>0.0.2</Version>
45
<TargetFramework>net7.0</TargetFramework>
56
<RootNamespace>SteamAuth</RootNamespace>
67
<ImplicitUsings>enable</ImplicitUsings>
78
<Nullable>enable</Nullable>
9+
<WarningsAsErrors>Nullable</WarningsAsErrors>
810
</PropertyGroup>
911

1012
<PropertyGroup>
1113
<OutputType>Exe</OutputType>
1214
<PublishSingleFile>true</PublishSingleFile>
1315
<PublishReadyToRun>true</PublishReadyToRun>
1416
<PublishTrimmed>true</PublishTrimmed>
17+
<SuppressTrimAnalysisWarnings>true</SuppressTrimAnalysisWarnings>
1518
</PropertyGroup>
1619

1720
<ItemGroup>
1821
<PackageReference Include="CrossPlatformProtectedData" Version="1.0.3" />
22+
<PackageReference Include="Ookii.CommandLine" Version="3.0.0" />
1923
<PackageReference Include="SteamGuard.TOTP" Version="1.0.0" />
24+
<PackageReference Include="TextCopy" Version="6.2.1" />
2025
</ItemGroup>
2126

22-
</Project>
27+
</Project>

Utils/ConsoleWriter.cs

+42
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
using Ookii.CommandLine.Terminal;
2+
3+
namespace SteamAuth.Utils
4+
{
5+
public class ConsoleWriter : IDisposable
6+
{
7+
private readonly VirtualTerminalSupport virtualTerminal;
8+
private readonly bool _formatSupported = false;
9+
10+
public ConsoleWriter()
11+
{
12+
virtualTerminal = VirtualTerminal.EnableColor(StandardStream.Output);
13+
_formatSupported = virtualTerminal.IsSupported;
14+
}
15+
16+
public void Write(string text, params string[] formats)
17+
{
18+
if (_formatSupported)
19+
{
20+
Console.Write(formats);
21+
}
22+
23+
Console.Write(text);
24+
}
25+
26+
public void WriteLine(string text, params string[] formats)
27+
{
28+
if (_formatSupported)
29+
{
30+
Console.Write(string.Concat(formats));
31+
}
32+
33+
Console.WriteLine(text);
34+
}
35+
36+
public void Dispose()
37+
{
38+
virtualTerminal.Dispose();
39+
GC.SuppressFinalize(this);
40+
}
41+
}
42+
}

0 commit comments

Comments
 (0)