Merge pull request #199 from gnh1201/dev

Add the mutex to avoid redundant
This commit is contained in:
Namhyeon Go 2025-03-23 15:31:28 +09:00 committed by GitHub
commit 7738b3b898
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
5 changed files with 114 additions and 2 deletions

View File

@ -38,6 +38,7 @@ namespace WelsonJS.Launcher
{
e.Cancel = true;
this.Hide();
this.ShowInTaskbar = false;
notifyIcon1.Visible = true;
}
base.OnFormClosing(e);
@ -47,6 +48,7 @@ namespace WelsonJS.Launcher
{
this.Show();
this.WindowState = FormWindowState.Normal;
this.ShowInTaskbar = true;
this.Focus();
notifyIcon1.Visible = false;
}

View File

@ -2,6 +2,7 @@
using System.Diagnostics;
using System.IO;
using System.Linq;
using System.Threading;
using System.Windows.Forms;
using WelsonJS.Launcher.Tools;
@ -9,14 +10,25 @@ namespace WelsonJS.Launcher
{
internal static class Program
{
static Mutex mutex;
public static ResourceServer resourceServer;
[STAThread]
static void Main()
{
mutex = new Mutex(true, "WelsonJS.Launcher.Mutex", out bool isMutexNotExists);
if (!isMutexNotExists)
{
MessageBox.Show("WelsonJS Launcher already running.");
return;
}
Application.EnableVisualStyles();
Application.SetCompatibleTextRenderingDefault(false);
Application.Run(new MainForm());
mutex.ReleaseMutex();
mutex.Dispose();
}
public static void RunCommandPrompt(string workingDirectory, string entryFileName, string scriptName, bool isConsoleApplication = false, bool isInteractiveServiceAapplication = false)

View File

@ -105,7 +105,7 @@ namespace WelsonJS.Launcher.Tools
const string devtoolsPrefix = "devtools/";
if (path.StartsWith(devtoolsPrefix, StringComparison.OrdinalIgnoreCase))
{
await ServeDevTools(context, path.Substring(devtoolsPrefix.Length - 1));
await ServeDevTools(context, path.Substring(devtoolsPrefix.Length));
return;
}
@ -125,6 +125,14 @@ namespace WelsonJS.Launcher.Tools
return;
}
// Serve TFA request
const string tfaPrefix = "tfa/";
if (path.StartsWith(tfaPrefix, StringComparison.OrdinalIgnoreCase))
{
ServeTfaRequest(context, path.Substring(tfaPrefix.Length));
return;
}
// Serve a resource
ServeResource(context, GetResource(_resourceName), "text/html");
}
@ -170,7 +178,7 @@ namespace WelsonJS.Launcher.Tools
{
using (HttpClient client = new HttpClient())
{
string url = "http://localhost:9222" + endpoint;
string url = "http://localhost:9222/" + endpoint;
string data = await client.GetStringAsync(url);
ServeResource(context, data, "application/json");
@ -251,6 +259,24 @@ namespace WelsonJS.Launcher.Tools
}
}
private void ServeTfaRequest(HttpListenerContext context, string endpoint)
{
Tfa _tfa = new Tfa();
if (endpoint.Equals("pubkey"))
{
ServeResource(context, _tfa.GetPubKey(), "text/plain", 200);
return;
}
ServeResource(context);
}
private void ServeResource(HttpListenerContext context)
{
ServeResource(context, "<error>Not Found</error>", "application/xml", 404);
}
private void ServeResource(HttpListenerContext context, byte[] data, string mimeType = "text/html", int statusCode = 200)
{
string xmlHeader = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>";

View File

@ -0,0 +1,71 @@
using System;
using System.Linq;
using System.Security.Cryptography;
using System.Collections.Generic;
namespace WelsonJS.Launcher.Tools
{
public class Tfa
{
private const string Base32Chars = "ABCDEFGHIJKLMNOPQRSTUVWXYZ234567";
public int GetOtp(string key)
{
byte[] binaryKey = DecodeBase32(key.Replace(" ", ""));
long timestamp = DateTimeOffset.UtcNow.ToUnixTimeSeconds() / 30;
byte[] timestampBytes = BitConverter.GetBytes(timestamp);
Array.Reverse(timestampBytes); // Ensure big-endian order
using (var hmac = new HMACSHA1(binaryKey))
{
byte[] hash = hmac.ComputeHash(timestampBytes);
int offset = hash[hash.Length - 1] & 0xF;
int otp = ((hash[offset] & 0x7F) << 24) |
((hash[offset + 1] & 0xFF) << 16) |
((hash[offset + 2] & 0xFF) << 8) |
(hash[offset + 3] & 0xFF);
return otp % 1000000; // Ensure 6-digit OTP
}
}
public string GetPubKey()
{
using (var rng = RandomNumberGenerator.Create())
{
var key = new char[16];
var randomBytes = new byte[16];
rng.GetBytes(randomBytes);
for (int i = 0; i < 16; i++)
{
key[i] = Base32Chars[randomBytes[i] % Base32Chars.Length];
}
return string.Join(" ", Enumerable.Range(0, 4).Select(i => new string(key, i * 4, 4)));
}
}
private static byte[] DecodeBase32(string key)
{
int buffer = 0, bitsLeft = 0;
var binaryKey = new List<byte>();
foreach (char c in key)
{
int value = Base32Chars.IndexOf(c);
if (value < 0) continue; // Ignore invalid characters
buffer = (buffer << 5) + value;
bitsLeft += 5;
if (bitsLeft >= 8)
{
bitsLeft -= 8;
binaryKey.Add((byte)((buffer >> bitsLeft) & 0xFF));
}
}
return binaryKey.ToArray();
}
}
}

View File

@ -101,6 +101,7 @@
<DependentUpon>GlobalSettingsForm.cs</DependentUpon>
</Compile>
<Compile Include="Tools\ResourceServer.cs" />
<Compile Include="Tools\Tfa.cs" />
<EmbeddedResource Include="EnvForm.resx">
<DependentUpon>EnvForm.cs</DependentUpon>
</EmbeddedResource>