92 lines
3.2 KiB
C#
92 lines
3.2 KiB
C#
using System;
|
|
using System.Net;
|
|
using System.Net.Http;
|
|
using System.Runtime.InteropServices;
|
|
using System.Security.Cryptography;
|
|
using System.Text;
|
|
using System.Text.Json;
|
|
using System.Threading;
|
|
using System.Threading.Tasks;
|
|
using StreamPlayer.Desktop.Models;
|
|
|
|
namespace StreamPlayer.Desktop.Services;
|
|
|
|
public sealed class DeviceRegistryService
|
|
{
|
|
private static readonly HttpClient HttpClient = new(new HttpClientHandler
|
|
{
|
|
AutomaticDecompression = DecompressionMethods.All
|
|
})
|
|
{
|
|
Timeout = TimeSpan.FromSeconds(20)
|
|
};
|
|
|
|
private readonly string _deviceId = CreateDeviceId();
|
|
|
|
public async Task<DeviceStatus> SyncAsync(CancellationToken cancellationToken)
|
|
{
|
|
if (string.IsNullOrWhiteSpace(AppVersion.DeviceRegistryUrl))
|
|
{
|
|
return DeviceStatus.Allowed();
|
|
}
|
|
|
|
var payload = new
|
|
{
|
|
deviceId = _deviceId,
|
|
deviceName = Environment.MachineName,
|
|
model = RuntimeInformation.OSDescription,
|
|
manufacturer = "Microsoft",
|
|
osVersion = Environment.OSVersion.VersionString,
|
|
appVersionName = AppVersion.VersionName,
|
|
appVersionCode = AppVersion.VersionCode
|
|
};
|
|
|
|
string endpoint = $"{SanitizeBaseUrl(AppVersion.DeviceRegistryUrl)}/api/devices/register";
|
|
var content = new StringContent(JsonSerializer.Serialize(payload), Encoding.UTF8, "application/json");
|
|
using var request = new HttpRequestMessage(HttpMethod.Post, endpoint)
|
|
{
|
|
Content = content
|
|
};
|
|
using var response = await HttpClient.SendAsync(request, cancellationToken).ConfigureAwait(false);
|
|
response.EnsureSuccessStatusCode();
|
|
string body = await response.Content.ReadAsStringAsync(cancellationToken).ConfigureAwait(false);
|
|
using var document = JsonDocument.Parse(body);
|
|
var root = document.RootElement;
|
|
|
|
bool blocked = root.GetPropertyOrDefaultBool("blocked", false);
|
|
string reason = root.GetPropertyOrDefault("message");
|
|
if (root.TryGetProperty("device", out var deviceElement))
|
|
{
|
|
if (string.IsNullOrWhiteSpace(reason))
|
|
{
|
|
reason = deviceElement.GetPropertyOrDefault("notes");
|
|
}
|
|
}
|
|
string tokenPart = string.Empty;
|
|
if (root.TryGetProperty("verification", out var verificationElement))
|
|
{
|
|
bool verificationRequired = verificationElement.GetPropertyOrDefaultBool("required", false);
|
|
blocked = blocked || verificationRequired;
|
|
tokenPart = verificationElement.GetPropertyOrDefault("clientTokenPart");
|
|
}
|
|
|
|
return new DeviceStatus(blocked, reason, tokenPart);
|
|
}
|
|
|
|
private static string SanitizeBaseUrl(string value)
|
|
{
|
|
if (string.IsNullOrWhiteSpace(value))
|
|
{
|
|
return string.Empty;
|
|
}
|
|
return value.EndsWith("/", StringComparison.Ordinal) ? value.TrimEnd('/') : value;
|
|
}
|
|
|
|
private static string CreateDeviceId()
|
|
{
|
|
string raw = $"{Environment.MachineName}|{Environment.UserName}|{RuntimeInformation.OSDescription}";
|
|
byte[] hash = SHA256.HashData(Encoding.UTF8.GetBytes(raw));
|
|
return Convert.ToHexString(hash)[..24].ToLowerInvariant();
|
|
}
|
|
}
|