IP address to DNS when router
5ebd068a3f76066a1e87eadb73531d98b898888f
6 files changed
src/Vimexx_API/AuthToken.cssrc/Vimexx_API/DNSRecord.cssrc/Vimexx_API/GetDnsResponse.cssrc/Vimexx_API/Response.cssrc/Vimexx_API/VimexxApi.cssrc/Vimexx_API/Vimexx_API.csproj
diff --git a/src/Vimexx_API/AuthToken.cs b/src/Vimexx_API/AuthToken.cs
index 65c989f..5f9433d 100644
--- a/src/Vimexx_API/AuthToken.cs
+++ b/src/Vimexx_API/AuthToken.cs
@@ -4,8 +4,8 @@ namespace Vimexx_API;
internal class AuthToken
{
- public string token_type { get; set; }
+ public string? token_type { get; set; }
public int expires_in { get; set; }
- public string access_token { get; set; }
- public string refresh_token { get; set; }
+ public string? access_token { get; set; }
+ public string? refresh_token { get; set; }
}
diff --git a/src/Vimexx_API/DNSRecord.cs b/src/Vimexx_API/DNSRecord.cs
index 04516eb..e4dd2b8 100644
--- a/src/Vimexx_API/DNSRecord.cs
+++ b/src/Vimexx_API/DNSRecord.cs
@@ -1,11 +1,11 @@
namespace Vimexx_API;
-
public class DnsRecord
{
- public string name { get; set; }
- public string type { get; set; }
- public string content { get; set; }
- public object prio { get; set; }
- public object ttl { get; set; }
+ public string name { get; set; } = string.Empty;
+ public string? type { get; set; }
+ public string? content { get; set; }
+ public object? prio { get; set; }
+ public object? ttl { get; set; }
}
+
diff --git a/src/Vimexx_API/GetDnsResponse.cs b/src/Vimexx_API/GetDnsResponse.cs
index a6e32b1..f36b68d 100644
--- a/src/Vimexx_API/GetDnsResponse.cs
+++ b/src/Vimexx_API/GetDnsResponse.cs
@@ -3,7 +3,7 @@ namespace Vimexx_API;
public class DnsRecords
{
- public List<DnsRecord> dns_records { get; set; }
+ public List<DnsRecord>? dns_records { get; set; }
}
public class GetDNSResponse : Response<DnsRecords>
diff --git a/src/Vimexx_API/Response.cs b/src/Vimexx_API/Response.cs
index 685fc82..00798c8 100644
--- a/src/Vimexx_API/Response.cs
+++ b/src/Vimexx_API/Response.cs
@@ -4,8 +4,8 @@ namespace Vimexx_API;
public class Response<T>
{
- public string message { get; set; }
+ public string? message { get; set; }
public bool result { get; set; }
- public T data { get; set; }
+ public T? data { get; set; }
}
diff --git a/src/Vimexx_API/VimexxApi.cs b/src/Vimexx_API/VimexxApi.cs
index afa5c76..c026307 100644
--- a/src/Vimexx_API/VimexxApi.cs
+++ b/src/Vimexx_API/VimexxApi.cs
@@ -1,60 +1,75 @@
-
-
-using System.Diagnostics;
-using System.Net.Http.Headers;
-
+using System.Dynamic;
using System.Text;
using System.Text.Json;
+
namespace Vimexx_API;
-public class VimexxApi
+public class VimexxApi(StringBuilder log)
{
+ private const int TTL = 3600;
private const string USER_AGENT = "Vimexx-WHMCS api agent .NET core 1.0";
private const string API_URL = "https://api.vimexx.nl";
private const string API_VERSION = "8.6.1-release.1";
- private string endpoint;
+ private string endpoint = API_URL + "/api/v1";
- private AuthToken token;
+ private AuthToken? token;
- private bool DEBUG = false;
+ private readonly StringBuilder log = log;
- async private Task<T> RequestAsync<T>(HttpMethod method, string apiMethod, object data)
+ async private Task<T?> RequestAsync<T>(HttpMethod method, string apiMethod, object data)
{
- var httpClient = new HttpClient();
+ var jsonResult = string.Empty;
+ var jsonRequest = string.Empty;
- httpClient.DefaultRequestHeaders.Add("User-Agent", USER_AGENT);
+ if (this.token == null)
+ {
+ log.AppendLine("Error: token is null");
+ return default;
+ }
- httpClient.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer", this.token.access_token);
+ try
+ {
+ var httpClient = new HttpClient();
- var json = JsonSerializer.Serialize(new { body = data, version = API_VERSION });
+ httpClient.DefaultRequestHeaders.Add("User-Agent", USER_AGENT);
- var request = new HttpRequestMessage(method, this.endpoint + apiMethod)
- {
- Content = new StringContent(json, Encoding.UTF8, "application/json")
- };
+ httpClient.DefaultRequestHeaders.Authorization =
+ new System.Net.Http.Headers.AuthenticationHeaderValue("Bearer", this.token.access_token);
- var httpResponseMessage = await httpClient.SendAsync(request);
+ jsonRequest = JsonSerializer.Serialize(new { body = data, version = API_VERSION });
- httpResponseMessage.EnsureSuccessStatusCode();
+ var request = new HttpRequestMessage(method, this.endpoint + apiMethod)
+ {
+ Content = new StringContent(jsonRequest, Encoding.UTF8, "application/json")
+ };
- if (httpResponseMessage.IsSuccessStatusCode)
- {
- var stream = await httpResponseMessage.Content.ReadAsStreamAsync();
+ var httpResponseMessage = await httpClient.SendAsync(request);
+
+ httpResponseMessage.EnsureSuccessStatusCode();
- if (DEBUG)
+ if (httpResponseMessage.IsSuccessStatusCode)
{
- var sr = new StreamReader(stream);
+ var stream = await httpResponseMessage.Content.ReadAsStreamAsync();
- var jsonResult = await sr.ReadToEndAsync();
+ var sr = new StreamReader(stream);
- Debug.WriteLine(jsonResult);
+ jsonResult = await sr.ReadToEndAsync();
- return JsonSerializer.Deserialize<T>(jsonResult);
+ try
+ {
+ return JsonSerializer.Deserialize<T>(jsonResult);
+ }
+ catch
+ {
+ log.AppendLine($"Error: Deserialize: {apiMethod}{Environment.NewLine}{jsonRequest}{Environment.NewLine}{jsonResult}{Environment.NewLine}");
+ }
}
-
- return await JsonSerializer.DeserializeAsync<T>(stream);
+ }
+ catch(Exception eee)
+ {
+ log.AppendLine($"Error: Exception: {eee.Message}: {apiMethod}{Environment.NewLine}{jsonRequest}{Environment.NewLine}{jsonResult}{Environment.NewLine}");
}
return default;
@@ -91,36 +106,42 @@ public class VimexxApi
if (testmodus)
this.endpoint = API_URL + "/apitest/v1";
- else
- this.endpoint = API_URL + "/api/v1";
-
}
- async public Task<GetDNSResponse> GetDNSAsync(string domainname)
+ async public Task<GetDNSResponse?> GetDNSAsync(string domainname)
{
var args = domainname.Split('.');
return await RequestAsync<GetDNSResponse>(HttpMethod.Post, "/whmcs/domain/dns", new { sld = args[0], tld = args[1] });
}
- async public Task<SaveDNSResponse> SaveDNSAsync(string domainname, List<DnsRecord> dns_records)
+ async public Task<SaveDNSResponse?> SaveDNSAsync(string domainname, List<DnsRecord> dns_records)
{
var args = domainname.Split('.');
- dns_records.Where(x => x.ttl == null).ToList().ForEach(x => x.ttl = 3600);
- dns_records.Where(x => x.type == "CAA").ToList().ForEach(x => x.ttl = 300);
+ dns_records.Where(x => x.ttl == null).ToList().ForEach(x => x.ttl = TTL);
+ dns_records.Where(x => x.type == "CAA").ToList().ForEach(x => x.ttl = TTL);
return await RequestAsync<SaveDNSResponse>(HttpMethod.Put, "/whmcs/domain/dns", new { sld = args[0], tld = args[1], dns_records });
}
- async public Task<Response<object>> LetsEncryptAsync(string domainname, List<string> challenges)
+ async public Task<Response<object>?> LetsEncryptAsync(string domainname, List<string> challenges)
{
var getdnsresponse = await GetDNSAsync(domainname);
+ if (getdnsresponse == null)
+ {
+ log.AppendLine($"Error: GetDNSAsync returned null on {domainname}");
+ return null;
+ }
+
if (getdnsresponse.result == false)
return new Response<object>() { result = getdnsresponse.result, message = getdnsresponse.message };
- var records = getdnsresponse.data.dns_records.Where(x => !x.name.StartsWith("_acme-challenge.")).ToList();
+ if (getdnsresponse.data == null || getdnsresponse.data.dns_records == null)
+ return null;
+
+ var records = getdnsresponse.data.dns_records.Where(x => x.name.StartsWith("_acme-challenge.")).ToList();
foreach(var challenge in challenges)
records.Add(new DnsRecord() { name = "_acme-challenge", content = challenge, type = "TXT", ttl = 300 });
@@ -128,18 +149,27 @@ public class VimexxApi
return await SaveDNSAsync(domainname, records);
}
- async public Task<Response<object>> LetsEncryptAsync(string domainname, string challenge)
+ async public Task<Response<object>?> LetsEncryptAsync(string domainname, string challenge)
{
var getdnsresponse = await GetDNSAsync(domainname);
+ if (getdnsresponse == null)
+ {
+ log.AppendLine($"Error: LetsEncryptAsync GetDNSAsync returns null");
+ return null;
+ }
+
if (getdnsresponse.result == false)
return new Response<object>() { result = getdnsresponse.result, message = getdnsresponse.message };
+ if (getdnsresponse.data == null || getdnsresponse.data.dns_records == null)
+ return null;
+
var records = getdnsresponse.data.dns_records;
// clear all _acme-challenge records
if (string.IsNullOrWhiteSpace(challenge))
- records = records.Where(x => !x.name.StartsWith("_acme-challenge.")).ToList();
+ records = records.Where(x => x.name.StartsWith("_acme-challenge.")).ToList();
if(!string.IsNullOrWhiteSpace(challenge))
records.Add(new DnsRecord() { name = "_acme-challenge", content = challenge, type = "TXT", ttl = 300 });
diff --git a/src/Vimexx_API/Vimexx_API.csproj b/src/Vimexx_API/Vimexx_API.csproj
index ceef3d4..e05aebc 100644
--- a/src/Vimexx_API/Vimexx_API.csproj
+++ b/src/Vimexx_API/Vimexx_API.csproj
@@ -3,7 +3,7 @@
<PropertyGroup>
<TargetFramework>net8.0</TargetFramework>
<ImplicitUsings>enable</ImplicitUsings>
-
+ <Nullable>enable</Nullable>
</PropertyGroup>
</Project>