Generate secret keys locally

This commit is contained in:
Loporrit
2025-08-08 02:48:49 +00:00
parent 7415b76d7d
commit 65e8707146
5 changed files with 95 additions and 24 deletions

Submodule MareAPI updated: 8b77956ec8...b2f4453b79

View File

@@ -108,6 +108,7 @@ public sealed class Plugin : IDalamudPlugin
collection.AddSingleton<XivDataAnalyzer>();
collection.AddSingleton<CharacterAnalyzer>();
collection.AddSingleton<TokenProvider>();
collection.AddSingleton<AccountRegistrationService>();
collection.AddSingleton<PluginWarningNotificationService>();
collection.AddSingleton<FileCompactor>();
collection.AddSingleton<TagHandler>();

View File

@@ -29,6 +29,7 @@ public partial class IntroUi : WindowMediatorSubscriberBase
private readonly CacheMonitor _cacheMonitor;
private readonly ServerConfigurationManager _serverConfigurationManager;
private readonly DalamudUtilService _dalamudUtilService;
private readonly AccountRegistrationService _registerService;
private readonly UiSharedService _uiShared;
private bool _readFirstPage;
@@ -42,13 +43,14 @@ public partial class IntroUi : WindowMediatorSubscriberBase
public IntroUi(ILogger<IntroUi> logger, UiSharedService uiShared, MareConfigService configService,
CacheMonitor fileCacheManager, ServerConfigurationManager serverConfigurationManager, MareMediator mareMediator,
PerformanceCollectorService performanceCollectorService, DalamudUtilService dalamudUtilService) : base(logger, mareMediator, "Loporrit Setup", performanceCollectorService)
PerformanceCollectorService performanceCollectorService, DalamudUtilService dalamudUtilService, AccountRegistrationService registerService) : base(logger, mareMediator, "Loporrit Setup", performanceCollectorService)
{
_uiShared = uiShared;
_configService = configService;
_cacheMonitor = fileCacheManager;
_serverConfigurationManager = serverConfigurationManager;
_dalamudUtilService = dalamudUtilService;
_registerService = registerService;
IsOpen = false;
ShowCloseButton = false;
RespectCloseHotkey = false;
@@ -261,16 +263,7 @@ This service is provided as-is.
_ = Task.Run(async () => {
try
{
using HttpClient httpClient = new();
var ver = Assembly.GetExecutingAssembly().GetName().Version;
httpClient.DefaultRequestHeaders.UserAgent.Add(new ProductInfoHeaderValue("MareSynchronos", ver!.Major + "." + ver!.Minor + "." + ver!.Build));
var postUri = MareAuth.AuthRegisterFullPath(new Uri(_serverConfigurationManager.CurrentRealApiUrl
.Replace("wss://", "https://", StringComparison.OrdinalIgnoreCase)
.Replace("ws://", "http://", StringComparison.OrdinalIgnoreCase)));
_logger.LogInformation("Registering new account: {uri}", postUri.ToString());
var result = await httpClient.PostAsync(postUri, null).ConfigureAwait(false);
result.EnsureSuccessStatusCode();
var reply = await result.Content.ReadFromJsonAsync<RegisterReplyDto>().ConfigureAwait(false) ?? new();
var reply = await _registerService.RegisterAccount(CancellationToken.None).ConfigureAwait(false);
if (!reply.Success)
{
_logger.LogWarning("Registration failed: {err}", reply.ErrorMessage);

View File

@@ -50,9 +50,10 @@ public class SettingsUi : WindowMediatorSubscriberBase
private readonly ChatService _chatService;
private readonly GuiHookService _guiHookService;
private readonly PerformanceCollectorService _performanceCollector;
private readonly ServerConfigurationManager _serverConfigurationManager;
private readonly PlayerPerformanceConfigService _playerPerformanceConfigService;
private readonly PlayerPerformanceService _playerPerformanceService;
private readonly AccountRegistrationService _registerService;
private readonly ServerConfigurationManager _serverConfigurationManager;
private readonly UiSharedService _uiShared;
private bool _deleteAccountPopupModalShown = false;
private string _lastTab = string.Empty;
@@ -80,7 +81,7 @@ public class SettingsUi : WindowMediatorSubscriberBase
FileCacheManager fileCacheManager,
FileCompactor fileCompactor, ApiController apiController,
IpcManager ipcManager, IpcProvider ipcProvider, CacheMonitor cacheMonitor,
DalamudUtilService dalamudUtilService) : base(logger, mediator, "Loporrit Settings", performanceCollector)
DalamudUtilService dalamudUtilService, AccountRegistrationService registerService) : base(logger, mediator, "Loporrit Settings", performanceCollector)
{
_configService = configService;
_pairManager = pairManager;
@@ -98,6 +99,7 @@ public class SettingsUi : WindowMediatorSubscriberBase
_ipcProvider = ipcProvider;
_cacheMonitor = cacheMonitor;
_dalamudUtilService = dalamudUtilService;
_registerService = registerService;
_fileCompactor = fileCompactor;
_uiShared = uiShared;
AllowClickthrough = false;
@@ -1753,16 +1755,7 @@ public class SettingsUi : WindowMediatorSubscriberBase
_ = Task.Run(async () => {
try
{
using HttpClient httpClient = new();
var ver = Assembly.GetExecutingAssembly().GetName().Version;
httpClient.DefaultRequestHeaders.UserAgent.Add(new ProductInfoHeaderValue("MareSynchronos", ver!.Major + "." + ver!.Minor + "." + ver!.Build));
var postUri = MareAuth.AuthRegisterFullPath(new Uri(selectedServer.ServerUri
.Replace("wss://", "https://", StringComparison.OrdinalIgnoreCase)
.Replace("ws://", "http://", StringComparison.OrdinalIgnoreCase)));
_logger.LogInformation("Registering new account: {uri}", postUri.ToString());
var result = await httpClient.PostAsync(postUri, null).ConfigureAwait(false);
result.EnsureSuccessStatusCode();
var reply = await result.Content.ReadFromJsonAsync<RegisterReplyDto>().ConfigureAwait(false) ?? new();
var reply = await _registerService.RegisterAccount(CancellationToken.None).ConfigureAwait(false);
if (!reply.Success)
{
_logger.LogWarning("Registration failed: {err}", reply.ErrorMessage);

View File

@@ -0,0 +1,84 @@
using MareSynchronos.API.Dto.Account;
using MareSynchronos.API.Routes;
using MareSynchronos.Services;
using MareSynchronos.Services.ServerConfiguration;
using MareSynchronos.Utils;
using MareSynchronos.WebAPI.SignalR;
using Microsoft.Extensions.Logging;
using System.Net.Http.Headers;
using System.Net.Http.Json;
using System.Reflection;
using System.Security.Cryptography;
namespace MareSynchronos.WebAPI;
public sealed class AccountRegistrationService : IDisposable
{
private readonly HttpClient _httpClient;
private readonly ILogger<AccountRegistrationService> _logger;
private readonly ServerConfigurationManager _serverManager;
private readonly RemoteConfigurationService _remoteConfig;
private string GenerateSecretKey()
{
return Convert.ToHexString(SHA256.HashData(RandomNumberGenerator.GetBytes(64)));
}
public AccountRegistrationService(ILogger<AccountRegistrationService> logger, ServerConfigurationManager serverManager, RemoteConfigurationService remoteConfig)
{
_logger = logger;
_serverManager = serverManager;
_remoteConfig = remoteConfig;
_httpClient = new(
new HttpClientHandler
{
AllowAutoRedirect = true,
MaxAutomaticRedirections = 5
}
);
var ver = Assembly.GetExecutingAssembly().GetName().Version;
_httpClient.DefaultRequestHeaders.UserAgent.Add(new ProductInfoHeaderValue("MareSynchronos", ver!.Major + "." + ver!.Minor + "." + ver!.Build));
}
public void Dispose()
{
_httpClient.Dispose();
}
public async Task<RegisterReplyDto> RegisterAccount(CancellationToken token)
{
var authApiUrl = _serverManager.CurrentApiUrl;
// Override the API URL used for auth from remote config, if one is available
if (authApiUrl.Equals(ApiController.LoporritServiceUri, StringComparison.Ordinal))
{
var config = await _remoteConfig.GetConfigAsync<HubConnectionConfig>("mainServer").ConfigureAwait(false) ?? new();
if (!string.IsNullOrEmpty(config.ApiUrl))
authApiUrl = config.ApiUrl;
else
authApiUrl = ApiController.LoporritServiceApiUri;
}
var secretKey = GenerateSecretKey();
var hashedSecretKey = secretKey.GetHash256();
Uri postUri = MareAuth.AuthRegisterV2FullPath(new Uri(authApiUrl
.Replace("wss://", "https://", StringComparison.OrdinalIgnoreCase)
.Replace("ws://", "http://", StringComparison.OrdinalIgnoreCase)));
var result = await _httpClient.PostAsync(postUri, new FormUrlEncodedContent([
new("hashedSecretKey", hashedSecretKey)
]), token).ConfigureAwait(false);
result.EnsureSuccessStatusCode();
var response = await result.Content.ReadFromJsonAsync<RegisterReplyV2Dto>(token).ConfigureAwait(false) ?? new();
return new RegisterReplyDto()
{
Success = response.Success,
ErrorMessage = response.ErrorMessage,
UID = response.UID,
SecretKey = secretKey
};
}
}