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

148 lines
6.2 KiB
Plaintext

@page "/settings/browser-extensions"
@inherits MainBase
@inject IJSRuntime JsRuntime
@inject ILogger<BrowserExtensions> Logger
@using AliasVault.Shared.Core.BrowserExtensions
<LayoutPageTitle>Install Browser Extension</LayoutPageTitle>
<PageHeader
BreadcrumbItems="@BreadcrumbItems"
Title="Install Browser Extension"
Description="Install browser extensions to automatically fill credentials on websites.">
</PageHeader>
<div class="p-4 mb-4 mx-4 bg-white border border-gray-200 rounded-lg shadow-sm dark:border-gray-700 sm:p-6 dark:bg-gray-800">
<div class="mb-6">
<h3 class="text-lg font-medium text-gray-900 dark:text-white mb-2">Available Extensions</h3>
<p class="text-gray-600 dark:text-gray-400">
The AliasVault browser extension allows you to:
</p>
<ul class="list-disc list-inside mt-2 space-y-1 text-gray-600 dark:text-gray-400">
<li>Autofill existing credentials on any website</li>
<li>Generate new aliases during registration</li>
<li>Access received emails on all of your aliases</li>
<li>View your aliases and identities</li>
</ul>
</div>
@if (CurrentBrowser != BrowserType.Unknown)
{
<div class="mb-6">
<h3 class="text-lg font-medium text-gray-900 dark:text-white mb-4">Recommended for Your Browser</h3>
<div class="p-4 border rounded-lg dark:border-amber-500/50 bg-amber-50 dark:bg-amber-800/30 border-amber-400">
<div class="flex flex-col sm:flex-row sm:items-center sm:justify-between gap-4">
<div class="flex items-center">
<img src="@CurrentBrowserExtension?.IconPath" alt="@CurrentBrowserExtension?.Name" class="w-8 h-8 mr-3">
<h4 class="text-lg font-medium text-gray-900 dark:text-white">@CurrentBrowserExtension?.Name</h4>
</div>
@if (CurrentBrowserExtension?.IsAvailable ?? false)
{
<a href="@CurrentBrowserExtension.DownloadUrl"
target="_blank"
class="inline-flex items-center px-4 py-2 text-sm font-medium text-white bg-primary-600 rounded-lg hover:bg-primary-700 focus:ring-4 focus:ring-primary-200 dark:focus:ring-primary-900">
Install for @CurrentBrowserExtension.Name
</a>
}
else
{
<p class="text-sm text-blue-800 dark:text-blue-400">
Support for @CurrentBrowserExtension?.Name is coming soon!
</p>
}
</div>
</div>
</div>
}
<div class="mb-4">
<h3 class="text-lg font-medium text-gray-900 dark:text-white mb-4">Other Browsers</h3>
<div class="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-4">
@foreach (var extension in Constants.Extensions
.Where(x => x.Key != BrowserType.Unknown && x.Key != CurrentBrowser)
.Select(x => x.Value))
{
<div class="p-4 border rounded-lg dark:border-gray-700">
<div class="flex items-center mb-4">
<img src="@extension.IconPath" alt="@extension.Name" class="w-8 h-8 mr-3">
<h4 class="text-lg font-medium text-gray-900 dark:text-white">@extension.Name</h4>
</div>
@if (extension.IsAvailable)
{
<a href="@extension.DownloadUrl"
target="_blank"
class="inline-flex items-center px-4 py-2 text-sm font-medium text-white bg-primary-600 rounded-lg hover:bg-primary-700 focus:ring-4 focus:ring-primary-200 dark:focus:ring-primary-900">
Install for @extension.Name
</a>
}
else
{
<span class="inline-flex items-center px-4 py-2 text-sm font-medium text-gray-500 bg-gray-100 rounded-lg dark:text-gray-400 dark:bg-gray-800">
Coming soon
</span>
}
</div>
}
</div>
</div>
</div>
@code {
/// <summary>
/// The current browser of the user.
/// </summary>
private BrowserType CurrentBrowser { get; set; }
/// <summary>
/// Information for extension for the current browser of the user.
/// </summary>
private BrowserExtensionInfo? CurrentBrowserExtension { get; set; } = null;
/// <inheritdoc />
protected override async Task OnInitializedAsync()
{
await base.OnInitializedAsync();
BreadcrumbItems.Add(new BreadcrumbItem { DisplayName = "Install Browser Extension" });
try
{
CurrentBrowser = await DetermineBrowser();
CurrentBrowserExtension = Constants.Extensions[CurrentBrowser];
}
catch (Exception ex)
{
Logger.LogError(ex, "Error determining browser type");
}
}
/// <summary>
/// Determine current browser.
/// </summary>
/// <returns>Browser type enum value.</returns>
private async Task<BrowserType> DetermineBrowser()
{
try
{
// First check if it's Brave.
var isBrave = await JsRuntime.InvokeAsync<bool>("eval", "navigator.brave?.isBrave() || false");
if (isBrave)
{
return BrowserType.Brave;
}
}
catch (Exception ex)
{
Logger.LogError(ex, "Error checking for Brave browser");
}
var userAgent = await JsRuntime.InvokeAsync<string>("eval", "navigator.userAgent");
return userAgent.ToLower() switch
{
var x when x.Contains("firefox") => BrowserType.Firefox,
var x when x.Contains("chrome") && !x.Contains("edg") => BrowserType.Chrome,
var x when x.Contains("safari") && !x.Contains("chrome") => BrowserType.Safari,
var x when x.Contains("edg") => BrowserType.Edge,
_ => BrowserType.Unknown
};
}
}