Create a Free Account
@@ -61,7 +60,7 @@
@code {
RegisterModel user = new RegisterModel();
- FullScreenLoadingIndicator loadingIndicator;
+ FullScreenLoadingIndicator loadingIndicator = new();
List validationErrors = new List();
async Task HandleRegister()
@@ -114,10 +113,10 @@
public class ValidationErrorResponse
{
- public string Type { get; set; }
- public string Title { get; set; }
+ public string Type { get; set; } = null!;
+ public string Title { get; set; } = null!;
public int Status { get; set; }
- public IDictionary Errors { get; set; }
- public string TraceId { get; set; }
+ public Dictionary Errors { get; set; } = new();
+ public string TraceId { get; set; } = null!;
}
}
diff --git a/src/AliasVault.WebApp/CustomAuthStateProvider.cs b/src/AliasVault.WebApp/Auth/Providers/AuthStateProvider.cs
similarity index 50%
rename from src/AliasVault.WebApp/CustomAuthStateProvider.cs
rename to src/AliasVault.WebApp/Auth/Providers/AuthStateProvider.cs
index 4bac47c95..948a6ea9c 100644
--- a/src/AliasVault.WebApp/CustomAuthStateProvider.cs
+++ b/src/AliasVault.WebApp/Auth/Providers/AuthStateProvider.cs
@@ -1,24 +1,48 @@
-using AliasVault.WebApp.Auth.Services;
-using Blazored.LocalStorage;
+//-----------------------------------------------------------------------
+//
+// Copyright (c) lanedirt. All rights reserved.
+// Licensed under the MIT license. See LICENSE.md file in the project root for full license information.
+//
+//-----------------------------------------------------------------------
-namespace AliasVault.WebApp;
+namespace AliasVault.WebApp.Auth.Providers;
using System.Security.Claims;
using System.Text.Json;
+using AliasVault.WebApp.Auth.Services;
using Microsoft.AspNetCore.Components.Authorization;
-public class CustomAuthStateProvider : AuthenticationStateProvider
+///
+/// Custom authentication state provider for the application.
+///
+public class AuthStateProvider(AuthService authService) : AuthenticationStateProvider
{
- private readonly AuthService _authService;
-
- public CustomAuthStateProvider(AuthService authService)
+ ///
+ /// Parses the claims from the JWT token.
+ ///
+ /// The JWT token.
+ /// The claims parsed from the JWT token.
+ public static IEnumerable ParseClaimsFromJwt(string jwt)
{
- _authService = authService;
+ var payload = jwt.Split('.')[1];
+ var jsonBytes = ParseBase64WithoutPadding(payload);
+ var keyValuePairs = JsonSerializer.Deserialize>(jsonBytes);
+
+ if (keyValuePairs == null)
+ {
+ throw new InvalidOperationException("Failed to parse JWT token.");
+ }
+
+ return keyValuePairs.Select(kvp => new Claim(kvp.Key, kvp.Value.ToString() ?? string.Empty));
}
+ ///
+ /// Gets the authentication state asynchronously.
+ ///
+ /// The authentication state.
public override async Task GetAuthenticationStateAsync()
{
- string token = await _authService.GetAccessTokenAsync();
+ string token = await authService.GetAccessTokenAsync();
var identity = new ClaimsIdentity();
@@ -31,7 +55,7 @@ public class CustomAuthStateProvider : AuthenticationStateProvider
catch (Exception)
{
Console.WriteLine("Invalid JWT token. Removing...");
- await _authService.RemoveTokensAsync();
+ await authService.RemoveTokensAsync();
identity = new ClaimsIdentity();
}
}
@@ -44,14 +68,11 @@ public class CustomAuthStateProvider : AuthenticationStateProvider
return state;
}
- public static IEnumerable ParseClaimsFromJwt(string jwt)
- {
- var payload = jwt.Split('.')[1];
- var jsonBytes = ParseBase64WithoutPadding(payload);
- var keyValuePairs = JsonSerializer.Deserialize>(jsonBytes);
- return keyValuePairs.Select(kvp => new Claim(kvp.Key, kvp.Value.ToString()));
- }
-
+ ///
+ /// Parses the base64 string without padding.
+ ///
+ /// The base64 string.
+ /// The byte array parsed from the base64 string.
private static byte[] ParseBase64WithoutPadding(string base64)
{
switch (base64.Length % 4)
@@ -59,6 +80,7 @@ public class CustomAuthStateProvider : AuthenticationStateProvider
case 2: base64 += "=="; break;
case 3: base64 += "="; break;
}
+
return Convert.FromBase64String(base64);
}
}
diff --git a/src/AliasVault.WebApp/Auth/Services/AliasVaultApiHandlerService.cs b/src/AliasVault.WebApp/Auth/Services/AliasVaultApiHandlerService.cs
index bb186841b..bdc0f2848 100644
--- a/src/AliasVault.WebApp/Auth/Services/AliasVaultApiHandlerService.cs
+++ b/src/AliasVault.WebApp/Auth/Services/AliasVaultApiHandlerService.cs
@@ -1,19 +1,28 @@
-using Microsoft.AspNetCore.Components;
+//-----------------------------------------------------------------------
+//
+// Copyright (c) lanedirt. All rights reserved.
+// Licensed under the MIT license. See LICENSE.md file in the project root for full license information.
+//
+//-----------------------------------------------------------------------
namespace AliasVault.WebApp.Auth.Services;
using System.Net;
using System.Net.Http.Headers;
+using Microsoft.AspNetCore.Components;
-public class AliasVaultApiHandlerService : DelegatingHandler
+///
+/// This services handles all API requests to the AliasVault API and will add the access token to the request headers.
+/// If a 401 unauthorized is returned by the API it will intercept this response and attempt to automatically refresh the access token.
+///
+public class AliasVaultApiHandlerService(IServiceProvider serviceProvider) : DelegatingHandler
{
- private readonly IServiceProvider _serviceProvider;
-
- public AliasVaultApiHandlerService(IServiceProvider serviceProvider)
- {
- _serviceProvider = serviceProvider;
- }
-
+ ///
+ /// Override the SendAsync method to add the access token to the request headers.
+ ///
+ /// HttpRequestMessage instance.
+ /// CancellationToken instance.
+ /// HttpResponseMessage.
protected override async Task SendAsync(HttpRequestMessage request, CancellationToken cancellationToken)
{
// Check if the request already contains the refreshed token to prevent infinite loop
@@ -25,7 +34,7 @@ public class AliasVaultApiHandlerService : DelegatingHandler
}
// Set the access token in the Authorization header
- var authService = _serviceProvider.GetRequiredService();
+ var authService = serviceProvider.GetRequiredService();
var token = await authService.GetAccessTokenAsync();
request.Headers.Authorization = new AuthenticationHeaderValue("Bearer", token);
@@ -39,21 +48,20 @@ public class AliasVaultApiHandlerService : DelegatingHandler
{
// Retry the original request with the new access token
request.Headers.Authorization = new AuthenticationHeaderValue("Bearer", newToken);
- // Add a custom header to indicate that this is a retry attempt
+
+ // Add a custom header to indicate that the next request is a retry attempt and any failure should be ignored.
request.Headers.Add("X-Ignore-Failure", "true");
response = await base.SendAsync(request, cancellationToken);
return response;
}
else
{
- // Refreshing token failed. This might be caused by the refresh token itself expired or has been revoked.
- // Remove token from localstorage and redirect to login.
+ // Refreshing token failed. This might be caused by the expiration or revocation of the refresh token itself.
+ // Remove the token from local storage and redirect to the login page.
await authService.RemoveTokensAsync();
- // Redirect to the login page.
- var navigationManager = _serviceProvider.GetRequiredService();
+ var navigationManager = serviceProvider.GetRequiredService();
navigationManager.NavigateTo("/user/login");
-
}
}
diff --git a/src/AliasVault.WebApp/Auth/Services/AuthService.cs b/src/AliasVault.WebApp/Auth/Services/AuthService.cs
index 7f248d5e2..f4c6a0304 100644
--- a/src/AliasVault.WebApp/Auth/Services/AuthService.cs
+++ b/src/AliasVault.WebApp/Auth/Services/AuthService.cs
@@ -1,27 +1,43 @@
-
-using System.Net.Http.Headers;
-using Microsoft.AspNetCore.Components.Authorization;
+//-----------------------------------------------------------------------
+//
+// Copyright (c) lanedirt. All rights reserved.
+// Licensed under the MIT license. See LICENSE.md file in the project root for full license information.
+//
+//-----------------------------------------------------------------------
namespace AliasVault.WebApp.Auth.Services;
-using AliasVault.Shared.Models;
-using Blazored.LocalStorage;
using System.Net.Http.Json;
using System.Text.Json;
+using AliasVault.Shared.Models;
+using Blazored.LocalStorage;
+///
+/// This service is responsible for handling authentication-related operations such as refreshing tokens,
+/// storing tokens, and revoking tokens.
+///
public class AuthService
{
- private readonly HttpClient _httpClient;
- private readonly ILocalStorageService _localStorage;
private const string AccessTokenKey = "token";
private const string RefreshTokenKey = "refreshToken";
+ private readonly HttpClient _httpClient;
+ private readonly ILocalStorageService _localStorage;
+ ///
+ /// Initializes a new instance of the class.
+ ///
+ /// The HTTP client.
+ /// The local storage service.
public AuthService(HttpClient httpClient, ILocalStorageService localStorage)
{
_httpClient = httpClient;
_localStorage = localStorage;
}
+ ///
+ /// Refreshes the access token asynchronously.
+ ///
+ /// The new access token.
public async Task RefreshTokenAsync()
{
// Your logic to get the refresh token and request a new access token
@@ -30,8 +46,9 @@ public class AuthService
var tokenInput = new TokenModel { Token = accessToken, RefreshToken = refreshToken };
using var request = new HttpRequestMessage(HttpMethod.Post, "api/Auth/refresh")
{
- Content = JsonContent.Create(tokenInput)
+ Content = JsonContent.Create(tokenInput),
};
+
// Add the X-Ignore-Failure header to the request so any failure does not trigger another refresh token request.
request.Headers.Add("X-Ignore-Failure", "true");
var response = await _httpClient.SendAsync(request);
@@ -55,44 +72,47 @@ public class AuthService
}
///
- /// Retrieve the stored refresh token (e.g., from local storage or a secure place).
+ /// Retrieves the stored access token asynchronously.
///
- ///
+ /// The stored access token.
public async Task GetAccessTokenAsync()
{
- return await _localStorage.GetItemAsStringAsync(AccessTokenKey);
+ return await _localStorage.GetItemAsStringAsync(AccessTokenKey) ?? string.Empty;
}
///
- /// Store the new access token (e.g., in local storage)
+ /// Stores the new access token asynchronously.
///
- ///
+ /// The new access token.
+ /// A representing the asynchronous operation.
public async Task StoreAccessTokenAsync(string newToken)
{
await _localStorage.SetItemAsStringAsync(AccessTokenKey, newToken);
}
///
- /// Retrieve the stored refresh token (e.g., from local storage or a secure place).
+ /// Retrieves the stored refresh token asynchronously.
///
- ///
+ /// The stored refresh token.
public async Task GetRefreshTokenAsync()
{
- return await _localStorage.GetItemAsStringAsync(RefreshTokenKey);
+ return await _localStorage.GetItemAsStringAsync(RefreshTokenKey) ?? string.Empty;
}
///
- /// Store the new access token (e.g., in local storage).
+ /// Stores the new refresh token asynchronously.
///
- ///
+ /// The new refresh token.
+ /// A representing the asynchronous operation.
public async Task StoreRefreshTokenAsync(string newToken)
{
await _localStorage.SetItemAsStringAsync(RefreshTokenKey, newToken);
}
///
- /// Remove the stored access and refresh tokens, called when logging out.
+ /// Removes the stored access and refresh tokens asynchronously, called when logging out.
///
+ /// A representing the asynchronous operation.
public async Task RemoveTokensAsync()
{
await _localStorage.RemoveItemAsync(AccessTokenKey);
@@ -111,15 +131,22 @@ public class AuthService
}
///
- /// Revoke the access and refresh tokens on the server.
+ /// Revokes the access and refresh tokens on the server asynchronously.
///
+ /// A representing the asynchronous operation.
private async Task RevokeTokenAsync()
{
- var tokenInput = new TokenModel { Token = await GetAccessTokenAsync(), RefreshToken = await GetRefreshTokenAsync() };
+ var tokenInput = new TokenModel
+ {
+ Token = await GetAccessTokenAsync(),
+ RefreshToken = await GetRefreshTokenAsync(),
+ };
+
using var request = new HttpRequestMessage(HttpMethod.Post, "api/Auth/revoke")
{
- Content = JsonContent.Create(tokenInput)
+ Content = JsonContent.Create(tokenInput),
};
+
// Add the X-Ignore-Failure header to the request so any failure does not trigger another refresh token request.
request.Headers.Add("X-Ignore-Failure", "true");
await _httpClient.SendAsync(request);
diff --git a/src/AliasVault.WebApp/Components/Alias/Alias.razor b/src/AliasVault.WebApp/Components/Alias/Alias.razor
index ba0d336fc..422287698 100644
--- a/src/AliasVault.WebApp/Components/Alias/Alias.razor
+++ b/src/AliasVault.WebApp/Components/Alias/Alias.razor
@@ -12,18 +12,10 @@
@code {
[Parameter]
public AliasVault.Shared.Models.WebApi.AliasListEntry Obj { get; set; } = new();
- private bool showModal = false;
private void ShowDetails()
{
// Redirect to view page instead for now.
NavigationManager.NavigateTo($"/alias/{Obj.Id}");
- //showModal = true;
}
-
- private void CloseDetails()
- {
- showModal = false;
- }
-
}
diff --git a/src/AliasVault.WebApp/Components/CopyPasteFormRow.razor b/src/AliasVault.WebApp/Components/CopyPasteFormRow.razor
index 529d5e5ea..205d4b89f 100644
--- a/src/AliasVault.WebApp/Components/CopyPasteFormRow.razor
+++ b/src/AliasVault.WebApp/Components/CopyPasteFormRow.razor
@@ -16,8 +16,8 @@
@code {
- [Parameter] public string Label { get; set; }
- [Parameter] public string Value { get; set; }
+ [Parameter] public string Label { get; set; } = "Value";
+ [Parameter] public string Value { get; set; } = string.Empty;
private bool _copied => ClipboardCopyService.GetCopiedId() == _inputId;
private string _inputId = Guid.NewGuid().ToString();
diff --git a/src/AliasVault.WebApp/Components/EditFormRow.razor b/src/AliasVault.WebApp/Components/EditFormRow.razor
index be9791857..49a0d0f9f 100644
--- a/src/AliasVault.WebApp/Components/EditFormRow.razor
+++ b/src/AliasVault.WebApp/Components/EditFormRow.razor
@@ -8,15 +8,29 @@
@code {
- [Parameter] public string Label { get; set; }
- [Parameter] public string Value { get; set; }
- [Parameter] public EventCallback ValueChanged { get; set; }
+ ///
+ /// Label for the input field.
+ ///
+ [Parameter]
+ public string Label { get; set; } = "Value";
+
+ ///
+ /// Value of the input field.
+ ///
+ [Parameter]
+ public string Value { get; set; } = string.Empty;
+
+ ///
+ /// Callback that is triggered when the value changes.
+ ///
+ [Parameter]
+ public EventCallback ValueChanged { get; set; }
private string _inputId = Guid.NewGuid().ToString();
private async Task OnInputChanged(ChangeEventArgs e)
{
- Value = e.Value.ToString();
+ Value = e.Value?.ToString() ?? string.Empty;
await ValueChanged.InvokeAsync(Value);
}
}
diff --git a/src/AliasVault.WebApp/Components/Email/RecentEmails.razor b/src/AliasVault.WebApp/Components/Email/RecentEmails.razor
index ab5d8945b..2440e1cb1 100644
--- a/src/AliasVault.WebApp/Components/Email/RecentEmails.razor
+++ b/src/AliasVault.WebApp/Components/Email/RecentEmails.razor
@@ -1,4 +1,5 @@
-@using BlazorServer.Models.Spamok
+@using AliasVault.WebApp.Pages.Aliases.Models.Spamok
+@using BlazorServer.Models.Spamok
@inherits ComponentBase
@inject IHttpClientFactory HttpClientFactory
@@ -56,23 +57,19 @@ else
@code {
[Parameter]
- public string EmailPrefix { get; set; }
-
+ public string EmailPrefix { get; set; } = string.Empty;
[Parameter]
public List MailboxEmails { get; set; } = new List();
-
public bool IsLoading { get; set; } = true;
- protected override Task OnAfterRenderAsync(bool firstRender)
+ protected override async Task OnAfterRenderAsync(bool firstRender)
{
- base.OnAfterRenderAsync(firstRender);
+ await base.OnAfterRenderAsync(firstRender);
if (firstRender)
{
- LoadRecentEmailsAsync();
+ await LoadRecentEmailsAsync();
}
-
- return Task.CompletedTask;
}
private async Task LoadRecentEmailsAsync()
@@ -81,9 +78,9 @@ else
StateHasChanged();
var client = HttpClientFactory.CreateClient("EmailClient");
- MailboxApiModel mailbox = await client.GetFromJsonAsync($"https://api.spamok.com/v2/EmailBox/{EmailPrefix}");
+ MailboxApiModel? mailbox = await client.GetFromJsonAsync($"https://api.spamok.com/v2/EmailBox/{EmailPrefix}");
- if (mailbox.Mails != null)
+ if (mailbox?.Mails != null)
{
MailboxEmails = mailbox.Mails;
}
@@ -91,5 +88,4 @@ else
IsLoading = false;
StateHasChanged();
}
-
}
diff --git a/src/AliasVault.WebApp/Components/Models/BreadcrumbItem.cs b/src/AliasVault.WebApp/Components/Models/BreadcrumbItem.cs
index 01813e22a..bf8cebdc5 100644
--- a/src/AliasVault.WebApp/Components/Models/BreadcrumbItem.cs
+++ b/src/AliasVault.WebApp/Components/Models/BreadcrumbItem.cs
@@ -1,7 +1,24 @@
+//-----------------------------------------------------------------------
+//
+// Copyright (c) lanedirt. All rights reserved.
+// Licensed under the MIT license. See LICENSE.md file in the project root for full license information.
+//
+//-----------------------------------------------------------------------
+
namespace AliasVault.WebApp.Components.Models;
+///
+/// Represents a breadcrumb item for the breadcrumb component.
+///
public class BreadcrumbItem
{
+ ///
+ /// Gets or sets the display name for the breadcrumb item.
+ ///
public string? DisplayName { get; set; }
+
+ ///
+ /// Gets or sets the URL for the breadcrumb item.
+ ///
public string? Url { get; set; }
}
diff --git a/src/AliasVault.WebApp/Components/RedirectToLogin.razor b/src/AliasVault.WebApp/Components/RedirectToLogin.razor
index 145177ab4..885bbb063 100644
--- a/src/AliasVault.WebApp/Components/RedirectToLogin.razor
+++ b/src/AliasVault.WebApp/Components/RedirectToLogin.razor
@@ -1,6 +1,6 @@
-@code {
- [Inject] private NavigationManager Navigation { get; set; }
+@inject NavigationManager Navigation
+@code {
protected override void OnInitialized()
{
Navigation.NavigateTo("/user/login");
diff --git a/src/AliasVault.WebApp/Pages/Aliases/AddEdit.razor b/src/AliasVault.WebApp/Pages/Aliases/AddEdit.razor
index f6d89937b..aec47cc17 100644
--- a/src/AliasVault.WebApp/Pages/Aliases/AddEdit.razor
+++ b/src/AliasVault.WebApp/Pages/Aliases/AddEdit.razor
@@ -173,6 +173,8 @@ else
protected override async Task OnInitializedAsync()
{
+ await base.OnInitializedAsync();
+
if (EditMode)
{
BreadcrumbItems.Add(new BreadcrumbItem { DisplayName = "Edit alias" });
@@ -189,8 +191,21 @@ else
{
if (EditMode)
{
+ if (Id is null)
+ {
+ Navigation.NavigateTo("/404");
+ return;
+ }
+
// Load existing obj, retrieve from service
- obj = await AliasService.LoadAliasAsync(Id.Value);
+ var alias = await AliasService.LoadAliasAsync(Id.Value);
+ if (alias is null)
+ {
+ Navigation.NavigateTo("/404");
+ return;
+ }
+
+ alias = obj;
}
else
{
@@ -255,7 +270,7 @@ else
// Try to extract favicon from service URL
// TODO: Fix favicon extraction
/*if (obj.Service.Url != null && !string.IsNullOrEmpty(obj.Service.Url))
- {
+ {
obj.Service.Logo = await FaviconExtractor.FaviconService.GetFaviconAsync(obj.Service.Url);
} */
@@ -275,7 +290,10 @@ else
if (EditMode)
{
- await AliasService.UpdateAliasAsync(obj, Id.Value);
+ if (Id is not null)
+ {
+ await AliasService.UpdateAliasAsync(obj, Id.Value);
+ }
}
else
{
diff --git a/src/AliasVault.WebApp/Pages/Aliases/Delete.razor b/src/AliasVault.WebApp/Pages/Aliases/Delete.razor
index 79ce4bd7c..a2e60d2eb 100644
--- a/src/AliasVault.WebApp/Pages/Aliases/Delete.razor
+++ b/src/AliasVault.WebApp/Pages/Aliases/Delete.razor
@@ -19,7 +19,7 @@
@if (IsLoading)
{
-
+
}
else
{
@@ -53,6 +53,7 @@ else
protected override async Task OnInitializedAsync()
{
+ await base.OnInitializedAsync();
BreadcrumbItems.Add(new BreadcrumbItem { Url = "alias/" + Id, DisplayName = "View Alias" });
BreadcrumbItems.Add(new BreadcrumbItem { DisplayName = "Delete alias" });
}
diff --git a/src/AliasVault.WebApp/Pages/Aliases/Mailbox/Models/Spamok/AttachmentApiModel.cs b/src/AliasVault.WebApp/Pages/Aliases/Mailbox/Models/Spamok/AttachmentApiModel.cs
index bc7cc5c17..6200df3cc 100644
--- a/src/AliasVault.WebApp/Pages/Aliases/Mailbox/Models/Spamok/AttachmentApiModel.cs
+++ b/src/AliasVault.WebApp/Pages/Aliases/Mailbox/Models/Spamok/AttachmentApiModel.cs
@@ -1,10 +1,39 @@
+//-----------------------------------------------------------------------
+//
+// Copyright (c) lanedirt. All rights reserved.
+// Licensed under the MIT license. See LICENSE.md file in the project root for full license information.
+//
+//-----------------------------------------------------------------------
+
namespace BlazorServer.Models.Spamok;
+///
+/// Represents an attachment for an email.
+///
public class AttachmentApiModel
{
+ ///
+ /// Gets or sets the ID of the attachment.
+ ///
public int Id { get; set; }
+
+ ///
+ /// Gets or sets the ID of the email the attachment belongs to.
+ ///
public int Email_Id { get; set; }
- public string Filename { get; set; }
- public string MimeType { get; set; }
+
+ ///
+ /// Gets or sets the filename of the attachment.
+ ///
+ public string Filename { get; set; } = null!;
+
+ ///
+ /// Gets or sets the MIME type of the attachment.
+ ///
+ public string MimeType { get; set; } = null!;
+
+ ///
+ /// Gets or sets the size of the attachment in bytes.
+ ///
public int Filesize { get; set; }
-}
\ No newline at end of file
+}
diff --git a/src/AliasVault.WebApp/Pages/Aliases/Mailbox/Models/Spamok/EmailApiModel.cs b/src/AliasVault.WebApp/Pages/Aliases/Mailbox/Models/Spamok/EmailApiModel.cs
index 924294851..f19a899c5 100644
--- a/src/AliasVault.WebApp/Pages/Aliases/Mailbox/Models/Spamok/EmailApiModel.cs
+++ b/src/AliasVault.WebApp/Pages/Aliases/Mailbox/Models/Spamok/EmailApiModel.cs
@@ -1,18 +1,79 @@
+//-----------------------------------------------------------------------
+//
+// Copyright (c) lanedirt. All rights reserved.
+// Licensed under the MIT license. See LICENSE.md file in the project root for full license information.
+//
+//-----------------------------------------------------------------------
+
namespace BlazorServer.Models.Spamok;
+///
+/// Represents an email API model.
+///
public class EmailApiModel
{
+ ///
+ /// Gets or sets the ID of the email.
+ ///
public int Id { get; set; }
- public string Subject { get; set; }
- public string FromDisplay { get; set; }
- public string FromDomain { get; set; }
- public string FromLocal { get; set; }
- public string ToDomain { get; set; }
- public string ToLocal { get; set; }
+
+ ///
+ /// Gets or sets the subject of the email.
+ ///
+ public string Subject { get; set; } = string.Empty;
+
+ ///
+ /// Gets or sets the display name of the sender.
+ ///
+ public string FromDisplay { get; set; } = string.Empty;
+
+ ///
+ /// Gets or sets the domain of the sender's email address.
+ ///
+ public string FromDomain { get; set; } = string.Empty;
+
+ ///
+ /// Gets or sets the local part of the sender's email address.
+ ///
+ public string FromLocal { get; set; } = string.Empty;
+
+ ///
+ /// Gets or sets the domain of the recipient's email address.
+ ///
+ public string ToDomain { get; set; } = string.Empty;
+
+ ///
+ /// Gets or sets the local part of the recipient's email address.
+ ///
+ public string ToLocal { get; set; } = string.Empty;
+
+ ///
+ /// Gets or sets the date of the email.
+ ///
public DateTime Date { get; set; }
+
+ ///
+ /// Gets or sets the system date of the email.
+ ///
public DateTime DateSystem { get; set; }
+
+ ///
+ /// Gets or sets the number of seconds ago the email was received.
+ ///
public double SecondsAgo { get; set; }
+
+ ///
+ /// Gets or sets the HTML content of the email message.
+ ///
public string? MessageHtml { get; set; }
+
+ ///
+ /// Gets or sets the plain text content of the email message.
+ ///
public string? MessagePlain { get; set; }
- public List Attachments { get; set; }
-}
\ No newline at end of file
+
+ ///
+ /// Gets or sets the list of attachments in the email.
+ ///
+ public List Attachments { get; set; } = new();
+}
diff --git a/src/AliasVault.WebApp/Pages/Aliases/Mailbox/Models/Spamok/MailboxApiModel.cs b/src/AliasVault.WebApp/Pages/Aliases/Mailbox/Models/Spamok/MailboxApiModel.cs
index 057912510..45ba35741 100644
--- a/src/AliasVault.WebApp/Pages/Aliases/Mailbox/Models/Spamok/MailboxApiModel.cs
+++ b/src/AliasVault.WebApp/Pages/Aliases/Mailbox/Models/Spamok/MailboxApiModel.cs
@@ -1,8 +1,29 @@
-namespace BlazorServer.Models.Spamok;
+//-----------------------------------------------------------------------
+//
+// Copyright (c) lanedirt. All rights reserved.
+// Licensed under the MIT license. See LICENSE.md file in the project root for full license information.
+//
+//-----------------------------------------------------------------------
+namespace AliasVault.WebApp.Pages.Aliases.Models.Spamok;
+
+///
+/// Represents a mailbox API model.
+///
public class MailboxApiModel
{
- public string Address { get; set; }
+ ///
+ /// Gets or sets the address of the mailbox.
+ ///
+ public string Address { get; set; } = string.Empty;
+
+ ///
+ /// Gets or sets a value indicating whether the mailbox is subscribed.
+ ///
public bool Subscribed { get; set; }
- public List Mails { get; set; }
-}
\ No newline at end of file
+
+ ///
+ /// Gets or sets the list of mailbox email API models.
+ ///
+ public List Mails { get; set; } = new();
+}
diff --git a/src/AliasVault.WebApp/Pages/Aliases/Mailbox/Models/Spamok/MailboxEmailApiModel.cs b/src/AliasVault.WebApp/Pages/Aliases/Mailbox/Models/Spamok/MailboxEmailApiModel.cs
index 7da7477cb..9a40df224 100644
--- a/src/AliasVault.WebApp/Pages/Aliases/Mailbox/Models/Spamok/MailboxEmailApiModel.cs
+++ b/src/AliasVault.WebApp/Pages/Aliases/Mailbox/Models/Spamok/MailboxEmailApiModel.cs
@@ -1,16 +1,69 @@
-namespace BlazorServer.Models.Spamok;
+//-----------------------------------------------------------------------
+//
+// Copyright (c) lanedirt. All rights reserved.
+// Licensed under the MIT license. See LICENSE.md file in the project root for full license information.
+//
+//-----------------------------------------------------------------------
+namespace AliasVault.WebApp.Pages.Aliases.Models.Spamok;
+
+///
+/// Represents a mailbox email API model.
+///
public class MailboxEmailApiModel
{
+ ///
+ /// Gets or sets the ID of the email.
+ ///
public int Id { get; set; }
- public string Subject { get; set; }
- public string FromDisplay { get; set; }
- public string FromDomain { get; set; }
- public string FromLocal { get; set; }
- public string ToDomain { get; set; }
- public string ToLocal { get; set; }
+
+ ///
+ /// Gets or sets the subject of the email.
+ ///
+ public string Subject { get; set; } = string.Empty;
+
+ ///
+ /// Gets or sets the display name of the sender.
+ ///
+ public string FromDisplay { get; set; } = string.Empty;
+
+ ///
+ /// Gets or sets the domain of the sender's email address.
+ ///
+ public string FromDomain { get; set; } = string.Empty;
+
+ ///
+ /// Gets or sets the local part of the sender's email address.
+ ///
+ public string FromLocal { get; set; } = string.Empty;
+
+ ///
+ /// Gets or sets the domain of the recipient's email address.
+ ///
+ public string ToDomain { get; set; } = string.Empty;
+
+ ///
+ /// Gets or sets the local part of the recipient's email address.
+ ///
+ public string ToLocal { get; set; } = string.Empty;
+
+ ///
+ /// Gets or sets the date of the email.
+ ///
public DateTime Date { get; set; }
+
+ ///
+ /// Gets or sets the system date of the email.
+ ///
public DateTime DateSystem { get; set; }
- public string MessagePreview { get; set; }
+
+ ///
+ /// Gets or sets the preview of the email message.
+ ///
+ public string MessagePreview { get; set; } = string.Empty;
+
+ ///
+ /// Gets or sets the number of seconds ago the email was received.
+ ///
public double SecondsAgo { get; set; }
-}
\ No newline at end of file
+}
diff --git a/src/AliasVault.WebApp/Pages/Aliases/View.razor b/src/AliasVault.WebApp/Pages/Aliases/View.razor
index de11a830a..2164fa633 100644
--- a/src/AliasVault.WebApp/Pages/Aliases/View.razor
+++ b/src/AliasVault.WebApp/Pages/Aliases/View.razor
@@ -64,7 +64,7 @@ else