mirror of
https://github.com/achiez/NebulaAuth-Steam-Desktop-Authenticator-by-Achies.git
synced 2026-07-25 06:14:31 +00:00
30cf049f23
- Rename AuthorizedDomains to WebDomains - Introduce explicit Steam audience constants and web audience mappings - Improve Steam token/domain resolution and cookie installation flow - Allow mobile-issued tokens with "web" audience to be used for web domains - Align authorization logic closer to actual Steam audience behavior - Rename cookie APIs from Add* to Set* where appropriate
159 lines
5.2 KiB
C#
159 lines
5.2 KiB
C#
using System;
|
|
using System.Collections.Generic;
|
|
using System.ComponentModel;
|
|
using System.Linq;
|
|
using System.Net.Http;
|
|
using System.Threading;
|
|
using System.Threading.Tasks;
|
|
using System.Windows;
|
|
using AchiesUtilities.Web.Models;
|
|
using AchiesUtilities.Web.Proxy;
|
|
using CommunityToolkit.Mvvm.ComponentModel;
|
|
using NebulaAuth.Core;
|
|
using NebulaAuth.Model.Entities;
|
|
using SteamLib.Api.Mobile;
|
|
using SteamLib.Api.Trade;
|
|
using SteamLib.Authentication;
|
|
using SteamLib.SteamMobile.Confirmations;
|
|
using SteamLib.Web;
|
|
using SteamLibForked.Abstractions;
|
|
|
|
namespace NebulaAuth.Model.MAAC;
|
|
|
|
public partial class PortableMaClient : ObservableObject, IDisposable
|
|
{
|
|
private const string LOC_PATH = "MAAC";
|
|
public Mafile Mafile { get; }
|
|
private HttpClient Client { get; }
|
|
private HttpClientHandler ClientHandler { get; }
|
|
private DynamicProxy Proxy { get; }
|
|
|
|
private readonly CancellationTokenSource _cts = new();
|
|
[ObservableProperty] private bool _autoConfirmMarket;
|
|
|
|
[ObservableProperty] private bool _autoConfirmTrades;
|
|
[ObservableProperty] private PortableMaClientStatus _status = PortableMaClientStatus.Ok();
|
|
|
|
public PortableMaClient(Mafile mafile)
|
|
{
|
|
Mafile = mafile;
|
|
Proxy = new DynamicProxy();
|
|
Proxy.SetData(mafile.Proxy?.Data);
|
|
var pair = ClientBuilder.BuildMobileClient(Proxy, mafile.SessionData);
|
|
Client = pair.Client;
|
|
ClientHandler = pair.Handler;
|
|
UpdateCookies(mafile.SessionData);
|
|
Mafile.PropertyChanged += Mafile_PropertyChanged;
|
|
SetStatus(PortableMaClientStatus.Ok());
|
|
}
|
|
|
|
private void Mafile_PropertyChanged(object? sender, PropertyChangedEventArgs e)
|
|
{
|
|
if (e.PropertyName == nameof(Mafile.SessionData))
|
|
{
|
|
UpdateCookies(Mafile.SessionData);
|
|
}
|
|
}
|
|
|
|
private void UpdateCookies(IMobileSessionData? sessionData)
|
|
{
|
|
var newStatus = MAACRequestHandler.ClearErrors(Mafile);
|
|
if (!newStatus.Equals(Status))
|
|
SetStatus(newStatus);
|
|
|
|
ClientHandler.CookieContainer.ClearAllCookies();
|
|
ClientHandler.CookieContainer.SetSteamMobileCookies(sessionData);
|
|
}
|
|
|
|
|
|
public async Task<int> Confirm()
|
|
{
|
|
Proxy.SetData(Mafile.Proxy?.Data ?? MaClient.DefaultProxy);
|
|
var conf = (await GetConfirmations()).ToList();
|
|
|
|
var toConfirm = new List<Confirmation>();
|
|
if (AutoConfirmMarket)
|
|
{
|
|
var market = conf.Where(c =>
|
|
c.ConfType is ConfirmationType.MarketSellTransaction or ConfirmationType.Purchase);
|
|
toConfirm.AddRange(market);
|
|
}
|
|
|
|
if (AutoConfirmTrades)
|
|
{
|
|
var trade = conf.Where(c => c.ConfType == ConfirmationType.Trade);
|
|
toConfirm.AddRange(trade);
|
|
}
|
|
|
|
if (toConfirm.Count == 0) return 0;
|
|
Shell.Logger.Debug("Timer {accountName}: Sending confirmations. Count: {count}", Mafile.AccountName,
|
|
toConfirm.Count);
|
|
var success = await SendConfirmations(toConfirm);
|
|
//TODO: handle success == false
|
|
Shell.Logger.Debug("Timer {accountName}: Confirmation sent: {confirmResult}", Mafile.AccountName, success);
|
|
return toConfirm.Count;
|
|
}
|
|
|
|
|
|
private async Task<IEnumerable<Confirmation>> GetConfirmations()
|
|
{
|
|
return await SteamMobileConfirmationsApi.GetConfirmations(Client, Mafile, Mafile.SessionData!.SteamId,
|
|
_cts.Token);
|
|
}
|
|
|
|
private async Task<bool> SendConfirmations(IEnumerable<Confirmation> confirmations)
|
|
{
|
|
var conf = confirmations.ToList();
|
|
var res = await SteamMobileConfirmationsApi.SendMultipleConfirmations(Client, conf,
|
|
Mafile.SessionData!.SteamId, Mafile, true, _cts.Token);
|
|
|
|
if (!res && conf.Any(c => c.ConfType == ConfirmationType.Trade))
|
|
{
|
|
Shell.Logger.Warn("Timer {accountName}: Failed to send trade confirmations. Sending ack",
|
|
Mafile.AccountName);
|
|
await SteamTradeApi.Acknowledge(Client, Mafile.SessionData!.SessionId, _cts.Token);
|
|
await Task.Delay(10, _cts.Token);
|
|
}
|
|
else
|
|
{
|
|
return res;
|
|
}
|
|
|
|
return await SteamMobileConfirmationsApi.SendMultipleConfirmations(Client, conf,
|
|
Mafile.SessionData!.SteamId, Mafile, true, _cts.Token);
|
|
}
|
|
|
|
public HttpClientHandlerPair Chp()
|
|
{
|
|
return new HttpClientHandlerPair(Client, ClientHandler);
|
|
}
|
|
|
|
private static string GetLocalization(string key)
|
|
{
|
|
return LocManager.GetCodeBehindOrDefault(key, LOC_PATH, key);
|
|
}
|
|
|
|
private string GetTimerPrefix()
|
|
{
|
|
return GetLocalization("TimerPrefix") + Mafile.AccountName + ": ";
|
|
}
|
|
|
|
public void SetStatus(PortableMaClientStatus status)
|
|
{
|
|
Application.Current.Dispatcher.Invoke(() => Status = status);
|
|
if (status.StatusType == PortableMaClientStatusType.Error)
|
|
{
|
|
Shell.Logger.Warn("Timer {accountName}: disabled due to error.", Mafile.AccountName);
|
|
SnackbarController.SendSnackbar(GetTimerPrefix() + status.Message);
|
|
}
|
|
}
|
|
|
|
public void Dispose()
|
|
{
|
|
_cts.Cancel();
|
|
_cts.Dispose();
|
|
Mafile.PropertyChanged -= Mafile_PropertyChanged;
|
|
Client.Dispose();
|
|
ClientHandler.Dispose();
|
|
}
|
|
} |