Files
aliasvault/apps/server/AliasVault.Client/Main/Pages/Credentials/View.razor
2025-04-30 19:03:18 +02:00

262 lines
10 KiB
Plaintext

@page "/credentials/{id:guid}"
@inherits MainBase
@inject CredentialService CredentialService
@implements IAsyncDisposable
<LayoutPageTitle>View credentials</LayoutPageTitle>
@if (IsLoading || Alias == null)
{
<LoadingIndicator />
}
else
{
<PageHeader
BreadcrumbItems="@BreadcrumbItems"
Title="View credential">
<CustomActions>
<LinkButton
Text="Edit"
AdditionalText="credential"
Href="@($"/credentials/{Id}/edit")"
Color="primary" />
<LinkButton
Text="Delete"
AdditionalText="credential"
Href="@($"/credentials/{Id}/delete")"
Color="danger" />
</CustomActions>
</PageHeader>
<div class="grid grid-cols-1 px-4 pt-6 md:grid-cols-2 lg:grid-cols-3 lg:gap-4 dark:bg-gray-900">
<div class="col-span-1 md:col-span-2 lg:col-span-1">
<div class="p-4 mb-4 bg-white border border-gray-200 rounded-lg shadow-sm 2xl:col-span-2 dark:border-gray-700 sm:p-6 dark:bg-gray-800">
<div class="items-center flex space-x-4">
<DisplayFavicon FaviconBytes="@Alias.Service.Logo" Padding="true" />
<div>
<h3 class="mb-1 text-xl font-bold text-gray-900 dark:text-white">@Alias.Service.Name</h3>
@if (Alias.Service.Url is not null && Alias.Service.Url.Length > 0)
{
var url = Alias.Service.Url;
if (!url.StartsWith("http://") && !url.StartsWith("https://"))
{
url = "https://" + url;
}
<a href="@url" target="_blank" class="text-blue-500 break-all dark:text-blue-400">@Alias.Service.Url</a>
}
</div>
</div>
</div>
<RecentEmails EmailAddress="@Alias.Alias.Email" />
@if (Alias.TotpCodes.Count > 0)
{
<TotpViewer TotpCodeList="@Alias.TotpCodes" />
}
@if (Alias.Notes != null && Alias.Notes.Length > 0)
{
<FormattedNote Notes="@Alias.Notes" />
}
@if (Alias.Attachments.Count > 0)
{
<AttachmentViewer Attachments="@Alias.Attachments" />
}
</div>
<div class="col-span-1 md:col-span-2 lg:col-span-2">
<div class="p-4 mb-4 bg-white border border-gray-200 rounded-lg shadow-sm 2xl:col-span-2 dark:border-gray-700 sm:p-6 dark:bg-gray-800">
<h3 class="mb-2 text-xl font-semibold dark:text-white">Login credentials</h3>
<p class="mb-4 text-sm text-gray-600 dark:text-gray-400">
@if (EmailService.IsAliasVaultSupportedDomain(Alias.Alias.Email ?? string.Empty))
{
<span>Below you can view and copy the generated credentials for this account. Any emails sent to the shown address will automatically appear on this page.</span>
}
else
{
<span>Below you can view and copy the stored login credentials for this account.</span>
}
</p>
<form action="#">
<div class="grid gap-6">
@if (!string.IsNullOrWhiteSpace(Alias.Alias.Email))
{
<div class="col-span-6 sm:col-span-3">
<CopyPasteFormRow Id="email" Label="Email" Value="@Alias.Alias.Email"></CopyPasteFormRow>
</div>
}
<div class="col-span-6 sm:col-span-3">
<CopyPasteFormRow Id="username" Label="Username" Value="@(Alias.Username)"></CopyPasteFormRow>
</div>
<div class="col-span-6 sm:col-span-3">
<CopyPastePasswordFormRow Id="password" Label="Password" Value="@(Alias.Passwords.FirstOrDefault()?.Value ?? string.Empty)"></CopyPastePasswordFormRow>
</div>
</div>
</form>
</div>
@if (HasAlias)
{
<div class="p-4 mb-4 bg-white border border-gray-200 rounded-lg shadow-sm 2xl:col-span-2 dark:border-gray-700 sm:p-6 dark:bg-gray-800">
<h3 class="mb-4 text-xl font-semibold dark:text-white">Alias</h3>
<form action="#">
<div class="grid grid-cols-6 gap-6">
@if (!string.IsNullOrWhiteSpace(Alias.Alias.FirstName) && !string.IsNullOrWhiteSpace(Alias.Alias.LastName))
{
<div class="col-span-6">
<CopyPasteFormRow Label="Full name" Value="@(Alias.Alias.FirstName + " " + Alias.Alias.LastName)"></CopyPasteFormRow>
</div>
}
@if (!string.IsNullOrWhiteSpace(Alias.Alias.FirstName))
{
<div class="col-span-6 sm:col-span-3">
<CopyPasteFormRow Label="First name" Value="@(Alias.Alias.FirstName)"></CopyPasteFormRow>
</div>
}
@if (!string.IsNullOrWhiteSpace(Alias.Alias.LastName))
{
<div class="col-span-6 sm:col-span-3">
<CopyPasteFormRow Label="Last name" Value="@(Alias.Alias.LastName)"></CopyPasteFormRow>
</div>
}
@if (IsValidDate(Alias.Alias.BirthDate))
{
<div class="col-span-6 sm:col-span-3">
<CopyPasteFormRow Label="Birthdate" Value="@(Alias.Alias.BirthDate.ToString("yyyy-MM-dd"))"></CopyPasteFormRow>
</div>
}
@if (!string.IsNullOrWhiteSpace(Alias.Alias.NickName))
{
<div class="col-span-6 sm:col-span-3">
<CopyPasteFormRow Label="Nickname" Value="@(Alias.Alias.NickName)"></CopyPasteFormRow>
</div>
}
</div>
</form>
</div>
}
</div>
</div>
}
@code {
/// <summary>
/// Gets or sets the credentials ID.
/// </summary>
[Parameter]
public Guid Id { get; set; }
private bool IsLoading { get; set; } = true;
private Credential? Alias { get; set; } = new();
private bool HasAlias { get; set; } = false;
/// <summary>
/// Checks if a date is valid and not a min value.
/// </summary>
/// <param name="date">The date to check.</param>
/// <returns>True if the date is valid and not a min value, false otherwise.</returns>
private static bool IsValidDate(DateTime date)
{
// Check if date is min value (year 1 or 0001-01-01)
if (date.Year <= 1 || date.ToString("yyyy-MM-dd") == "0001-01-01")
{
return false;
}
return true;
}
/// <summary>
/// Checks if the alias has any valid data.
/// </summary>
/// <param name="alias">The credential containing alias information.</param>
/// <returns>True if the alias has any valid data, false otherwise.</returns>
private static bool CheckHasAlias(Credential alias)
{
if (alias?.Alias == null)
{
return false;
}
return !string.IsNullOrWhiteSpace(alias.Alias.FirstName) ||
!string.IsNullOrWhiteSpace(alias.Alias.LastName) ||
!string.IsNullOrWhiteSpace(alias.Alias.NickName) ||
IsValidDate(alias.Alias.BirthDate);
}
/// <inheritdoc />
protected override async Task OnInitializedAsync()
{
await base.OnInitializedAsync();
BreadcrumbItems.Add(new BreadcrumbItem { DisplayName = "View credential" });
}
/// <inheritdoc />
protected override async Task OnParametersSetAsync()
{
await base.OnParametersSetAsync();
await LoadEntryAsync();
}
/// <summary>
/// Loads the credential.
/// </summary>
private async Task LoadEntryAsync()
{
IsLoading = true;
StateHasChanged();
// Load the aliases from the webapi via AliasService.
Alias = await CredentialService.LoadEntryAsync(Id);
if (Alias is null)
{
// Error loading alias.
GlobalNotificationService.AddErrorMessage("This credential does not exist (anymore). Please try again.");
NavigationManager.NavigateTo("/credentials", false, true);
return;
}
// Check if the alias has any valid data
HasAlias = CheckHasAlias(Alias);
IsLoading = false;
StateHasChanged();
}
/// <inheritdoc />
async ValueTask IAsyncDisposable.DisposeAsync()
{
await KeyboardShortcutService.UnregisterShortcutAsync("ge");
await KeyboardShortcutService.UnregisterShortcutAsync("gd");
}
/// <inheritdoc />
protected override async Task OnAfterRenderAsync(bool firstRender)
{
await base.OnAfterRenderAsync(firstRender);
if (firstRender)
{
await KeyboardShortcutService.RegisterShortcutAsync("ge", NavigateToEdit);
await KeyboardShortcutService.RegisterShortcutAsync("gd", NavigateToDelete);
}
}
/// <summary>
/// Navigates to the edit page.
/// </summary>
private Task NavigateToEdit()
{
NavigationManager.NavigateTo($"/credentials/{Id}/edit");
return Task.CompletedTask;
}
/// <summary>
/// Navigates to the delete page.
/// </summary>
private Task NavigateToDelete()
{
NavigationManager.NavigateTo($"/credentials/{Id}/delete");
return Task.CompletedTask;
}
}