252 lines
9.3 KiB
C#
252 lines
9.3 KiB
C#
using GreenHome.Application;
|
|
using GreenHome.Sms.Ippanel;
|
|
using Microsoft.EntityFrameworkCore;
|
|
using Microsoft.Extensions.Logging;
|
|
|
|
namespace GreenHome.Infrastructure;
|
|
|
|
/// <summary>
|
|
/// سرویس مدیریت توکن و تنظیمات دستگاه
|
|
/// </summary>
|
|
public sealed class DeviceTokenService : IDeviceTokenService
|
|
{
|
|
private readonly GreenHomeDbContext dbContext;
|
|
private readonly ISmsService smsService;
|
|
private readonly ILogger<DeviceTokenService> logger;
|
|
|
|
public DeviceTokenService(
|
|
GreenHomeDbContext dbContext,
|
|
ISmsService smsService,
|
|
ILogger<DeviceTokenService> logger)
|
|
{
|
|
this.dbContext = dbContext;
|
|
this.smsService = smsService;
|
|
this.logger = logger;
|
|
}
|
|
|
|
/// <summary>
|
|
/// دریافت فاصله زمانی آپلود بر اساس شماره تلفن یا شناسه دستگاه
|
|
/// </summary>
|
|
public async Task<GetUploadIntervalResponse> GetUploadIntervalAsync(
|
|
GetUploadIntervalRequest request,
|
|
CancellationToken cancellationToken)
|
|
{
|
|
try
|
|
{
|
|
Domain.DeviceSettings? settings = null;
|
|
|
|
// جستجو بر اساس DeviceId یا DevicePhoneNumber
|
|
if (request.DeviceId.HasValue)
|
|
{
|
|
settings = await dbContext.DeviceSettings
|
|
.AsNoTracking()
|
|
.FirstOrDefaultAsync(ds => ds.DeviceId == request.DeviceId.Value, cancellationToken);
|
|
}
|
|
else if (!string.IsNullOrWhiteSpace(request.DevicePhoneNumber))
|
|
{
|
|
settings = await dbContext.DeviceSettings
|
|
.AsNoTracking()
|
|
.FirstOrDefaultAsync(ds => ds.DevicePhoneNumber == request.DevicePhoneNumber, cancellationToken);
|
|
}
|
|
|
|
if (settings == null)
|
|
{
|
|
return new GetUploadIntervalResponse
|
|
{
|
|
Success = false,
|
|
Message = "دستگاه یافت نشد"
|
|
};
|
|
}
|
|
|
|
return new GetUploadIntervalResponse
|
|
{
|
|
Success = true,
|
|
UploadIntervalMin = settings.UploadIntervalMin
|
|
};
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
logger.LogError(ex, "Error getting upload interval for device");
|
|
return new GetUploadIntervalResponse
|
|
{
|
|
Success = false,
|
|
Message = "خطا در دریافت اطلاعات"
|
|
};
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// درخواست توکن دستگاه (تولید و ارسال کد)
|
|
/// </summary>
|
|
public async Task<RequestDeviceTokenResponse> RequestDeviceTokenAsync(
|
|
RequestDeviceTokenRequest request,
|
|
CancellationToken cancellationToken)
|
|
{
|
|
try
|
|
{
|
|
// پیدا کردن تنظیمات دستگاه بر اساس شماره تلفن
|
|
var settings = await dbContext.DeviceSettings
|
|
.FirstOrDefaultAsync(ds => ds.DevicePhoneNumber == request.DevicePhoneNumber, cancellationToken);
|
|
|
|
if (settings == null)
|
|
{
|
|
return new RequestDeviceTokenResponse
|
|
{
|
|
Success = false,
|
|
Message = "دستگاه با این شماره تلفن یافت نشد"
|
|
};
|
|
}
|
|
|
|
// تولید کد توکن 5 رقمی
|
|
var random = new Random();
|
|
var tokenCode = random.Next(10000, 99999).ToString();
|
|
|
|
// تولید کد تایید بر اساس فرمول: (TokenCode * 7 + 12345) % 100000
|
|
var verificationCode = ((int.Parse(tokenCode) * 7 + 12345) % 100000).ToString("D5");
|
|
|
|
// ذخیره کدها
|
|
settings.TokenCode = tokenCode;
|
|
settings.VerificationCode = verificationCode;
|
|
settings.TokenExpiresAt = DateTime.UtcNow.AddMinutes(30); // اعتبار 10 دقیقه
|
|
settings.UpdatedAt = DateTime.UtcNow;
|
|
|
|
await dbContext.SaveChangesAsync(cancellationToken);
|
|
|
|
// ارسال کد توکن از طریق پیامک
|
|
try
|
|
{
|
|
await smsService.SendWebserviceSmsAsync(new WebserviceSmsRequest
|
|
{
|
|
Recipient = request.DevicePhoneNumber,
|
|
Message = $"0911925302120#{tokenCode}"
|
|
}, cancellationToken);
|
|
}
|
|
catch (Exception smsEx)
|
|
{
|
|
logger.LogError(smsEx, "Error sending token SMS to {PhoneNumber}", request.DevicePhoneNumber);
|
|
return new RequestDeviceTokenResponse
|
|
{
|
|
Success = false,
|
|
Message = "خطا در ارسال پیامک"
|
|
};
|
|
}
|
|
|
|
logger.LogInformation("Token requested for device phone {PhoneNumber}", request.DevicePhoneNumber);
|
|
|
|
return new RequestDeviceTokenResponse
|
|
{
|
|
Success = true,
|
|
Message = "کد تایید با موفقیت ارسال شد",
|
|
TokenCode = $"0911925302120#{tokenCode}"
|
|
};
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
logger.LogError(ex, "Error requesting device token");
|
|
return new RequestDeviceTokenResponse
|
|
{
|
|
Success = false,
|
|
Message = "خطا در درخواست توکن"
|
|
};
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// تایید توکن دستگاه (ارسال تنظیمات)
|
|
/// </summary>
|
|
public async Task<VerifyDeviceTokenResponse> VerifyDeviceTokenAsync(
|
|
VerifyDeviceTokenRequest request,
|
|
CancellationToken cancellationToken)
|
|
{
|
|
try
|
|
{
|
|
// پیدا کردن تنظیمات دستگاه
|
|
var settings = await dbContext.DeviceSettings
|
|
.Include(ds => ds.Device)
|
|
.FirstOrDefaultAsync(ds => ds.DevicePhoneNumber == request.DevicePhoneNumber, cancellationToken);
|
|
|
|
if (settings == null)
|
|
{
|
|
return new VerifyDeviceTokenResponse
|
|
{
|
|
Success = false,
|
|
Message = "دستگاه با این شماره تلفن یافت نشد"
|
|
};
|
|
}
|
|
|
|
// بررسی انقضای توکن
|
|
if (settings.TokenExpiresAt == null || settings.TokenExpiresAt < DateTime.UtcNow)
|
|
{
|
|
return new VerifyDeviceTokenResponse
|
|
{
|
|
Success = false,
|
|
Message = "کد تایید منقضی شده است"
|
|
};
|
|
}
|
|
|
|
// بررسی کد تایید
|
|
if (settings.VerificationCode != request.VerificationCode)
|
|
{
|
|
return new VerifyDeviceTokenResponse
|
|
{
|
|
Success = false,
|
|
Message = "کد تایید نادرست است"
|
|
};
|
|
}
|
|
Random rnd = new Random();
|
|
// رمزگذاری ساده تنظیمات: DeviceName|UploadIntervalMin به Base64
|
|
var deviceId = settings.Device.Id;
|
|
var uploadInterval = settings.UploadIntervalMin;
|
|
string smsConfig = (settings.MinimumSmsIntervalMinutes != 0 ? "1" : rnd.Next(2, 9).ToString())
|
|
+ settings.MinimumSmsIntervalMinutes;
|
|
var plainText = $"{deviceId}01|{rnd.Next(1,9)}{uploadInterval}|{smsConfig}|{rnd.Next(139,97654)}|{rnd.Next(1,9)}{(int)settings.SimCardType}";
|
|
var encodedSettings = plainText; //Convert.ToBase64String(System.Text.Encoding.UTF8.GetBytes(plainText));
|
|
|
|
// ارسال تنظیمات کدشده از طریق پیامک
|
|
try
|
|
{
|
|
await smsService.SendWebserviceSmsAsync(new WebserviceSmsRequest
|
|
{
|
|
Recipient = request.DevicePhoneNumber,
|
|
Message = $"{encodedSettings}"
|
|
}, cancellationToken);
|
|
}
|
|
catch (Exception smsEx)
|
|
{
|
|
logger.LogError(smsEx, "Error sending settings SMS to {PhoneNumber}", request.DevicePhoneNumber);
|
|
return new VerifyDeviceTokenResponse
|
|
{
|
|
Success = false,
|
|
Message = "خطا در ارسال پیامک"
|
|
};
|
|
}
|
|
|
|
// پاک کردن کدها بعد از استفاده موفق
|
|
settings.TokenCode = null;
|
|
settings.VerificationCode = null;
|
|
settings.TokenExpiresAt = null;
|
|
settings.UpdatedAt = DateTime.UtcNow;
|
|
await dbContext.SaveChangesAsync(cancellationToken);
|
|
|
|
logger.LogInformation("Device token verified for {PhoneNumber}", request.DevicePhoneNumber);
|
|
|
|
return new VerifyDeviceTokenResponse
|
|
{
|
|
Success = true,
|
|
Message = "تنظیمات با موفقیت ارسال شد",
|
|
EncodedSettings = encodedSettings
|
|
};
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
logger.LogError(ex, "Error verifying device token");
|
|
return new VerifyDeviceTokenResponse
|
|
{
|
|
Success = false,
|
|
Message = "خطا در تایید توکن"
|
|
};
|
|
}
|
|
}
|
|
}
|
|
|