mirror of
https://github.com/JustArchiNET/ArchiSteamFarm.git
synced 2026-01-01 14:10:53 +00:00
Improve 2FA import process
This commit is contained in:
@@ -1450,7 +1450,45 @@ namespace ArchiSteamFarm {
|
||||
ArchiLogger.LogGenericInfo(Strings.BotAuthenticatorConverting);
|
||||
|
||||
try {
|
||||
MobileAuthenticator authenticator = JsonConvert.DeserializeObject<MobileAuthenticator>(await RuntimeCompatibility.File.ReadAllTextAsync(maFilePath).ConfigureAwait(false));
|
||||
string json = await RuntimeCompatibility.File.ReadAllTextAsync(maFilePath).ConfigureAwait(false);
|
||||
|
||||
if (string.IsNullOrEmpty(json)) {
|
||||
ArchiLogger.LogGenericError(string.Format(Strings.ErrorIsEmpty, nameof(json)));
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
MobileAuthenticator authenticator = JsonConvert.DeserializeObject<MobileAuthenticator>(json);
|
||||
|
||||
if (authenticator == null) {
|
||||
ArchiLogger.LogNullError(nameof(authenticator));
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
if (!authenticator.HasValidDeviceID) {
|
||||
ArchiLogger.LogGenericWarning(Strings.BotAuthenticatorInvalidDeviceID);
|
||||
|
||||
if (string.IsNullOrEmpty(DeviceID)) {
|
||||
string deviceID = Program.GetUserInput(ASF.EUserInputType.DeviceID, BotName);
|
||||
|
||||
if (string.IsNullOrEmpty(deviceID)) {
|
||||
return;
|
||||
}
|
||||
|
||||
SetUserInput(ASF.EUserInputType.DeviceID, deviceID);
|
||||
}
|
||||
|
||||
if (!MobileAuthenticator.IsValidDeviceID(DeviceID)) {
|
||||
ArchiLogger.LogGenericWarning(Strings.BotAuthenticatorInvalidDeviceID);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
authenticator.CorrectDeviceID(DeviceID);
|
||||
}
|
||||
|
||||
authenticator.Init(this);
|
||||
await BotDatabase.SetMobileAuthenticator(authenticator).ConfigureAwait(false);
|
||||
File.Delete(maFilePath);
|
||||
} catch (Exception e) {
|
||||
@@ -1459,32 +1497,6 @@ namespace ArchiSteamFarm {
|
||||
return;
|
||||
}
|
||||
|
||||
if (BotDatabase.MobileAuthenticator == null) {
|
||||
ArchiLogger.LogNullError(nameof(BotDatabase.MobileAuthenticator));
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
BotDatabase.MobileAuthenticator.Init(this);
|
||||
|
||||
if (!BotDatabase.MobileAuthenticator.HasCorrectDeviceID) {
|
||||
ArchiLogger.LogGenericWarning(Strings.BotAuthenticatorInvalidDeviceID);
|
||||
|
||||
if (string.IsNullOrEmpty(DeviceID)) {
|
||||
string deviceID = Program.GetUserInput(ASF.EUserInputType.DeviceID, BotName);
|
||||
|
||||
if (string.IsNullOrEmpty(deviceID)) {
|
||||
await BotDatabase.SetMobileAuthenticator().ConfigureAwait(false);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
SetUserInput(ASF.EUserInputType.DeviceID, deviceID);
|
||||
}
|
||||
|
||||
await BotDatabase.CorrectMobileAuthenticatorDeviceID(DeviceID).ConfigureAwait(false);
|
||||
}
|
||||
|
||||
ArchiLogger.LogGenericInfo(Strings.BotAuthenticatorImportFinished);
|
||||
}
|
||||
|
||||
|
||||
@@ -137,18 +137,6 @@ namespace ArchiSteamFarm {
|
||||
}
|
||||
}
|
||||
|
||||
internal async Task CorrectMobileAuthenticatorDeviceID(string deviceID) {
|
||||
if (string.IsNullOrEmpty(deviceID) || (MobileAuthenticator == null)) {
|
||||
ASF.ArchiLogger.LogNullError(nameof(deviceID) + " || " + nameof(MobileAuthenticator));
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
if (MobileAuthenticator.CorrectDeviceID(deviceID)) {
|
||||
await Save().ConfigureAwait(false);
|
||||
}
|
||||
}
|
||||
|
||||
internal static async Task<BotDatabase> CreateOrLoad(string filePath) {
|
||||
if (string.IsNullOrEmpty(filePath)) {
|
||||
ASF.ArchiLogger.LogNullError(nameof(filePath));
|
||||
|
||||
@@ -45,8 +45,7 @@ namespace ArchiSteamFarm {
|
||||
private static DateTime LastSteamTimeCheck;
|
||||
private static int? SteamTimeDifference;
|
||||
|
||||
// "ERROR" is being used by SteamDesktopAuthenticator
|
||||
internal bool HasCorrectDeviceID => !string.IsNullOrEmpty(DeviceID) && !DeviceID.Equals("ERROR");
|
||||
internal bool HasValidDeviceID => !string.IsNullOrEmpty(DeviceID) && IsValidDeviceID(DeviceID);
|
||||
|
||||
#pragma warning disable 649
|
||||
[JsonProperty(PropertyName = "identity_secret", Required = Required.Always)]
|
||||
@@ -65,20 +64,20 @@ namespace ArchiSteamFarm {
|
||||
|
||||
private MobileAuthenticator() { }
|
||||
|
||||
internal bool CorrectDeviceID(string deviceID) {
|
||||
internal void CorrectDeviceID(string deviceID) {
|
||||
if (string.IsNullOrEmpty(deviceID)) {
|
||||
Bot.ArchiLogger.LogNullError(nameof(deviceID));
|
||||
|
||||
return false;
|
||||
return;
|
||||
}
|
||||
|
||||
if (!string.IsNullOrEmpty(DeviceID) && DeviceID.Equals(deviceID)) {
|
||||
return false;
|
||||
if (!IsValidDeviceID(deviceID)) {
|
||||
Bot.ArchiLogger.LogGenericError(string.Format(Strings.ErrorIsInvalid, nameof(deviceID)));
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
DeviceID = deviceID;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
internal async Task<string> GenerateToken() {
|
||||
@@ -100,7 +99,7 @@ namespace ArchiSteamFarm {
|
||||
return null;
|
||||
}
|
||||
|
||||
if (!HasCorrectDeviceID) {
|
||||
if (!HasValidDeviceID) {
|
||||
Bot.ArchiLogger.LogGenericError(Strings.ErrorMobileAuthenticatorInvalidDeviceID);
|
||||
|
||||
return null;
|
||||
@@ -128,7 +127,7 @@ namespace ArchiSteamFarm {
|
||||
}
|
||||
|
||||
internal async Task<HashSet<Confirmation>> GetConfirmations(Steam.ConfirmationDetails.EType acceptedType = Steam.ConfirmationDetails.EType.Unknown) {
|
||||
if (!HasCorrectDeviceID) {
|
||||
if (!HasValidDeviceID) {
|
||||
Bot.ArchiLogger.LogGenericError(Strings.ErrorMobileAuthenticatorInvalidDeviceID);
|
||||
|
||||
return null;
|
||||
@@ -228,7 +227,7 @@ namespace ArchiSteamFarm {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!HasCorrectDeviceID) {
|
||||
if (!HasValidDeviceID) {
|
||||
Bot.ArchiLogger.LogGenericError(Strings.ErrorMobileAuthenticatorInvalidDeviceID);
|
||||
|
||||
return false;
|
||||
@@ -278,6 +277,26 @@ namespace ArchiSteamFarm {
|
||||
|
||||
internal void Init(Bot bot) => Bot = bot ?? throw new ArgumentNullException(nameof(bot));
|
||||
|
||||
internal static bool IsValidDeviceID(string deviceID) {
|
||||
if (string.IsNullOrEmpty(deviceID)) {
|
||||
ASF.ArchiLogger.LogNullError(nameof(deviceID));
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
// To the best of my knowledge, Steam uses android identifier even on iOS and other devices right now
|
||||
// If we ever need to correct this, we also need to clean up other places
|
||||
const string deviceIdentifier = "android:";
|
||||
|
||||
if (!deviceID.StartsWith(deviceIdentifier, StringComparison.Ordinal) || (deviceID.Length != deviceIdentifier.Length + 36)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
string hash = deviceID.Substring(deviceIdentifier.Length).Replace("-", "");
|
||||
|
||||
return (hash.Length == 32) && Utilities.IsValidHexadecimalString(hash);
|
||||
}
|
||||
|
||||
private string GenerateConfirmationHash(uint time, string tag = null) {
|
||||
if (time == 0) {
|
||||
Bot.ArchiLogger.LogNullError(nameof(time));
|
||||
|
||||
@@ -180,17 +180,55 @@ namespace ArchiSteamFarm {
|
||||
return false;
|
||||
}
|
||||
|
||||
const byte split = 16;
|
||||
|
||||
for (byte i = 0; i < text.Length; i += split) {
|
||||
string textPart = string.Join("", text.Skip(i).Take(split));
|
||||
|
||||
if (!ulong.TryParse(textPart, NumberStyles.HexNumber, null, out _)) {
|
||||
return false;
|
||||
}
|
||||
if (text.Length % 2 != 0) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
// ulong is 64-bits wide, each hexadecimal character is 4-bits wide, so we split each 16
|
||||
const byte split = 16;
|
||||
|
||||
string lastHex;
|
||||
|
||||
if (text.Length >= split) {
|
||||
StringBuilder hex = new StringBuilder(split);
|
||||
|
||||
foreach (char character in text) {
|
||||
hex.Append(character);
|
||||
|
||||
if (hex.Length < split) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (!ulong.TryParse(hex.ToString(), NumberStyles.HexNumber, null, out _)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
hex.Clear();
|
||||
}
|
||||
|
||||
if (hex.Length == 0) {
|
||||
return true;
|
||||
}
|
||||
|
||||
lastHex = hex.ToString();
|
||||
} else {
|
||||
lastHex = text;
|
||||
}
|
||||
|
||||
switch (lastHex.Length) {
|
||||
case 2:
|
||||
|
||||
return byte.TryParse(lastHex, NumberStyles.HexNumber, null, out _);
|
||||
case 4:
|
||||
|
||||
return ushort.TryParse(lastHex, NumberStyles.HexNumber, null, out _);
|
||||
case 8:
|
||||
|
||||
return uint.TryParse(lastHex, NumberStyles.HexNumber, null, out _);
|
||||
default:
|
||||
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
internal static int RandomNext() {
|
||||
|
||||
Reference in New Issue
Block a user