mirror of
https://github.com/immense/Remotely.git
synced 2025-10-26 11:27:15 +00:00
394 lines
18 KiB
Plaintext
394 lines
18 KiB
Plaintext
@page "/server-config"
|
|
|
|
@attribute [Authorize]
|
|
@inherits AuthComponentBase
|
|
|
|
|
|
@if (User?.IsServerAdmin == true)
|
|
{
|
|
<AlertBanner Message="@_alertMessage" />
|
|
|
|
<h3 class="mt-3">Server Info</h3>
|
|
|
|
<div class="row">
|
|
<div class="col-md-8">
|
|
<div class="mb-4" style="display:flex; justify-content: space-evenly">
|
|
<div class="d-inline-block text-center mr-2">
|
|
<label>Devices Online</label>
|
|
<br />
|
|
<span class="badge badge-primary p-2">@AgentHub.ServiceConnections.Count</span>
|
|
</div>
|
|
|
|
<div class="d-inline-block text-center mr-2">
|
|
<label>Devices Outdated</label>
|
|
<br />
|
|
|
|
<button class="btn btn-sm btn-secondary" @onclick="ShowOutdatedDevices">
|
|
<i class="oi oi-question-mark"></i>
|
|
</button>
|
|
<span class="badge badge-primary p-2 mx-2">@(OutdatedDevices?.Count() ?? 0)</span>
|
|
<button class="btn btn-secondary btn-sm" type="button" title="Update All" @onclick="UpdateAllDevices">
|
|
<span class="oi oi-reload"></span>
|
|
</button>
|
|
</div>
|
|
|
|
<div class="d-inline-block text-center mr-2">
|
|
<label>Devices Total</label>
|
|
<br />
|
|
<span class="badge badge-primary p-2">@TotalDevices</span>
|
|
</div>
|
|
<div class="d-inline-block text-center mr-2">
|
|
<label>Active Users</label>
|
|
<br />
|
|
<span class="badge badge-primary p-2">@CircuitManager.Connections.Count</span>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<div class="row">
|
|
<div class="col-md-8">
|
|
<h3 class="mt3">Server Admins</h3>
|
|
|
|
<div class="form-group">
|
|
<label class="control-label">Server Admins</label>
|
|
<br />
|
|
|
|
<div class="small">
|
|
<input class="align-middle mr-1" type="checkbox" @bind="_showMyOrgAdminsOnly" />
|
|
<span class="align-middle">Show my organization only</span>
|
|
</div>
|
|
<div class="small">
|
|
<input class="align-middle mr-1" type="checkbox" @bind="_showAdminsOnly" />
|
|
<span class="align-middle">Show current admins only</span>
|
|
</div>
|
|
|
|
<br />
|
|
<div class="list-box">
|
|
@foreach (var user in UserList)
|
|
{
|
|
<div @key="user.Id">
|
|
<input type="checkbox" disabled="@(user.Id == User.Id)" checked="@user.IsServerAdmin" @onchange="ev => SetIsServerAdmin(ev, user)" />
|
|
<span class="ml-2 align-top" style="line-height:1.3em">@user.UserName</span>
|
|
</div>
|
|
}
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<div class="row">
|
|
<div class="col-md-8">
|
|
<EditForm Model="Input" OnValidSubmit="HandleValidSubmit" autocomplete="off">
|
|
<DataAnnotationsValidator />
|
|
|
|
<h3 class="mt-3">Application Settings</h3>
|
|
|
|
<ValidationSummary Model="Input" />
|
|
|
|
|
|
<div class="form-group">
|
|
<label>Allow API Login</label>
|
|
<br />
|
|
<InputCheckbox @bind-Value="Input.AllowApiLogin" autocomplete="off" />
|
|
<br />
|
|
<ValidationMessage For="() => Input.AllowApiLogin" />
|
|
</div>
|
|
<div class="form-group">
|
|
<label class="control-label">Banned Devices</label>
|
|
<br />
|
|
<select size="4" class="form-control" @bind="_bannedDeviceSelected">
|
|
@foreach (var bannedDevice in Input.BannedDevices)
|
|
{
|
|
<option @key="bannedDevice" value="@bannedDevice">@bannedDevice</option>
|
|
}
|
|
</select>
|
|
|
|
<div class="text-right mb-2 mt-1">
|
|
<button type="button" class="btn btn-secondary" @onclick="RemoveBannedDevice">Remove</button>
|
|
</div>
|
|
<div class="input-group">
|
|
<input placeholder="Add banned device ID, name, or IP"
|
|
class="form-control" autocomplete="off"
|
|
@bind="_bannedDeviceToAdd"
|
|
@bind:event="oninput"
|
|
@onkeydown="HandleBannedDeviceKeyDown" />
|
|
<button type="button" class="btn btn-secondary" @onclick="AddBannedDevice">Add</button>
|
|
</div>
|
|
<ValidationMessage For="() => Input.BannedDevices" />
|
|
</div>
|
|
<div class="form-group">
|
|
<label class="control-label">Data Retention in Days</label>
|
|
<br />
|
|
<InputNumber @bind-Value="Input.DataRetentionInDays" class="form-control" autocomplete="off" />
|
|
<br />
|
|
<ValidationMessage For="() => Input.DataRetentionInDays" />
|
|
</div>
|
|
<div class="form-group">
|
|
<label class="control-label">Database Provider</label>
|
|
<br />
|
|
<select class="form-control" @bind="Input.DBProvider">
|
|
@foreach (var provider in Enum.GetValues<DbProvider>())
|
|
{
|
|
<option @key="provider" value="@provider">@provider</option>
|
|
}
|
|
</select>
|
|
<br />
|
|
<ValidationMessage For="() => Input.DBProvider" />
|
|
</div>
|
|
<div class="form-group">
|
|
<label>Enable Windows Event Log</label>
|
|
<br />
|
|
<InputCheckbox @bind-Value="Input.EnableWindowsEventLog" autocomplete="off" />
|
|
<br />
|
|
<ValidationMessage For="() => Input.EnableWindowsEventLog" />
|
|
</div>
|
|
<div class="form-group">
|
|
<label>Enforce Attended Access</label>
|
|
<br />
|
|
<InputCheckbox @bind-Value="Input.EnforceAttendedAccess" autocomplete="off" />
|
|
<br />
|
|
<ValidationMessage For="() => Input.EnforceAttendedAccess" />
|
|
</div>
|
|
<div class="form-group">
|
|
<label class="control-label">Known Proxies</label>
|
|
<br />
|
|
<select class="form-control" @bind="_knownProxySelected" size="4">
|
|
@foreach (var proxy in Input.KnownProxies)
|
|
{
|
|
<option @key="proxy" value="@proxy">@proxy</option>
|
|
}
|
|
</select>
|
|
<div class="text-right mb-2 mt-1">
|
|
<button type="button" class="btn btn-secondary" @onclick="RemoveKnownProxy">Remove</button>
|
|
</div>
|
|
<div class="input-group">
|
|
<input @bind="_knownProxyToAdd"
|
|
@bind:event="oninput"
|
|
placeholder="Add a known proxy"
|
|
class="form-control"
|
|
autocomplete="off"
|
|
@onkeydown="HandleKnownProxyKeyDown" />
|
|
|
|
<button type="button" class="btn btn-secondary" @onclick="AddKnownProxy">Add</button>
|
|
</div>
|
|
<ValidationMessage For="() => Input.KnownProxies" />
|
|
</div>
|
|
<div class="form-group">
|
|
<label class="control-label">Max Organization Count</label>
|
|
<br />
|
|
<InputNumber @bind-Value="Input.MaxOrganizationCount" class="form-control" autocomplete="off" />
|
|
<br />
|
|
<ValidationMessage For="() => Input.MaxOrganizationCount" />
|
|
</div>
|
|
<div class="form-group">
|
|
<label class="control-label">Max Concurrent Updates</label>
|
|
<br />
|
|
<InputNumber @bind-Value="Input.MaxConcurrentUpdates" class="form-control" autocomplete="off" />
|
|
<br />
|
|
<ValidationMessage For="() => Input.MaxConcurrentUpdates" />
|
|
</div>
|
|
<div class="form-group">
|
|
<label class="control-label">Message of the Day</label>
|
|
<br />
|
|
<InputText @bind-Value="Input.MessageOfTheDay" class="form-control" autocomplete="off" />
|
|
<br />
|
|
<ValidationMessage For="() => Input.MessageOfTheDay" />
|
|
</div>
|
|
<div class="form-group">
|
|
<label>Redirect to HTTPS</label>
|
|
<br />
|
|
<InputCheckbox @bind-Value="Input.RedirectToHttps" autocomplete="off" />
|
|
<br />
|
|
<ValidationMessage For="() => Input.RedirectToHttps" />
|
|
</div>
|
|
<div class="form-group">
|
|
<label>Remote Control Notify User</label>
|
|
<br />
|
|
<InputCheckbox @bind-Value="Input.RemoteControlNotifyUser" autocomplete="off" />
|
|
<br />
|
|
<ValidationMessage For="() => Input.RemoteControlNotifyUser" />
|
|
</div>
|
|
<div class="form-group">
|
|
<label>Require Authentication on Remote Control Page</label>
|
|
<br />
|
|
<InputCheckbox @bind-Value="Input.RemoteControlRequiresAuthentication" autocomplete="off" />
|
|
<br />
|
|
<ValidationMessage For="() => Input.RemoteControlRequiresAuthentication" />
|
|
</div>
|
|
<div class="form-group">
|
|
<label class="control-label">Remote Control Session Limit</label>
|
|
<br />
|
|
<InputNumber @bind-Value="Input.RemoteControlSessionLimit" class="form-control" autocomplete="off" />
|
|
<br />
|
|
<ValidationMessage For="() => Input.RemoteControlSessionLimit" />
|
|
</div>
|
|
<div class="form-group">
|
|
<label>Require 2FA</label>
|
|
<br />
|
|
<InputCheckbox @bind-Value="Input.Require2FA" autocomplete="off" />
|
|
<br />
|
|
<ValidationMessage For="() => Input.Require2FA" />
|
|
</div>
|
|
<div class="form-group">
|
|
<label class="control-label">SMTP Display Name</label>
|
|
<br />
|
|
<InputText @bind-Value="Input.SmtpDisplayName" class="form-control" autocomplete="off" />
|
|
<br />
|
|
<ValidationMessage For="() => Input.SmtpDisplayName" />
|
|
</div>
|
|
<div class="form-group">
|
|
<label class="control-label">SMTP Email</label>
|
|
<br />
|
|
<InputText type="email" @bind-Value="Input.SmtpEmail" class="form-control" autocomplete="off" />
|
|
<br />
|
|
<ValidationMessage For="() => Input.SmtpEmail" />
|
|
</div>
|
|
<div class="form-group">
|
|
<label class="control-label">SMTP Host</label>
|
|
<br />
|
|
<InputText @bind-Value="Input.SmtpHost" class="form-control" autocomplete="off" />
|
|
<br />
|
|
<ValidationMessage For="() => Input.SmtpHost" />
|
|
</div>
|
|
<div class="form-group">
|
|
<label class="control-label">SMTP Port</label>
|
|
<br />
|
|
<InputNumber @bind-Value="Input.SmtpPort" class="form-control" autocomplete="off" />
|
|
<br />
|
|
<ValidationMessage For="() => Input.SmtpPort" />
|
|
</div>
|
|
<div class="form-group">
|
|
<label class="control-label">SMTP Check Certificate Revocation</label>
|
|
<div class="small text-muted">
|
|
This sometimes needs to be disabled for Let's Encrypt certificates.
|
|
</div>
|
|
<br />
|
|
<InputCheckbox @bind-Value="Input.SmtpCheckCertificateRevocation" autocomplete="off" />
|
|
<br />
|
|
<ValidationMessage For="() => Input.SmtpCheckCertificateRevocation" />
|
|
</div>
|
|
<div class="form-group">
|
|
<label class="control-label">SMTP Local Domain</label>
|
|
<br />
|
|
<InputText @bind-Value="Input.SmtpLocalDomain" class="form-control" autocomplete="off" />
|
|
<br />
|
|
<ValidationMessage For="() => Input.SmtpLocalDomain" />
|
|
</div>
|
|
<div class="form-group">
|
|
<label class="control-label">SMTP Username</label>
|
|
<br />
|
|
<InputText @bind-Value="Input.SmtpUserName" class="form-control" autocomplete="new-password" />
|
|
<br />
|
|
<ValidationMessage For="() => Input.SmtpUserName" />
|
|
</div>
|
|
<div class="form-group">
|
|
<label class="control-label">SMTP Password</label>
|
|
<br />
|
|
<InputText type="password" @bind-Value="Input.SmtpPassword" class="form-control" autocomplete="new-password" />
|
|
<br />
|
|
<ValidationMessage For="() => Input.SmtpPassword" />
|
|
</div>
|
|
<div class="form-group text-right">
|
|
<button id="sendTestEmailButton" type="button" class="btn btn-secondary" @onclick="SaveAndTestSmtpSettings">Test</button>
|
|
</div>
|
|
<div class="form-group">
|
|
<label class="control-label">Theme</label>
|
|
<br />
|
|
<select class="form-control" @bind="Input.Theme">
|
|
@foreach (var theme in Enum.GetValues<Theme>())
|
|
{
|
|
<option @key="theme" value="@theme">@theme</option>
|
|
}
|
|
|
|
</select>
|
|
<br />
|
|
<ValidationMessage For="() => Input.Theme" />
|
|
</div>
|
|
<div class="form-group">
|
|
<label class="control-label">Trusted CORS Origins</label>
|
|
<br />
|
|
<select class="form-control" @bind="_trustedCorsOriginSelected" size="4">
|
|
@foreach (var origin in Input.TrustedCorsOrigins)
|
|
{
|
|
<option @key="origin" value="@origin">@origin</option>
|
|
}
|
|
</select>
|
|
|
|
<div class="text-right mb-2 mt-1">
|
|
<button type="button" class="btn btn-secondary" @onclick="RemoveTrustedCorsOrigin">Remove</button>
|
|
</div>
|
|
<div class="input-group">
|
|
<input placeholder="Add trusted URL"
|
|
class="form-control"
|
|
autocomplete="off"
|
|
@bind="_trustedCorsOriginToAdd"
|
|
@bind:event="oninput"
|
|
@onkeydown="HandleTrustedCorsKeyDown" />
|
|
|
|
<button id="trustedCorsAddButton" type="button" class="btn btn-secondary" @onclick="AddTrustedCorsOrigin">Add</button>
|
|
</div>
|
|
<ValidationMessage For="() => Input.TrustedCorsOrigins" />
|
|
</div>
|
|
<div class="form-group">
|
|
<label>Use HSTS</label>
|
|
<br />
|
|
<InputCheckbox @bind-Value="Input.UseHsts" autocomplete="off" />
|
|
<br />
|
|
<ValidationMessage For="() => Input.UseHsts" />
|
|
</div>
|
|
|
|
<div class="form-group">
|
|
<label>Use WebRTC</label>
|
|
<br />
|
|
<InputCheckbox @bind-Value="Input.UseWebRtc" autocomplete="off" />
|
|
<br />
|
|
<ValidationMessage For="() => Input.UseWebRtc" />
|
|
</div>
|
|
|
|
<div class="form-group">
|
|
<label>ICE Servers</label>
|
|
<br />
|
|
<span class="text-muted">Must be edited in appsettings.json.</span>
|
|
</div>
|
|
|
|
<h4>Connection Strings</h4>
|
|
|
|
<div class="form-group">
|
|
<label class="control-label">PostgreSQL</label>
|
|
<br />
|
|
<InputText @bind-Value="ConnectionStrings.PostgreSQL" class="form-control" autocomplete="off" />
|
|
<br />
|
|
<ValidationMessage For="() => ConnectionStrings.PostgreSQL" />
|
|
</div>
|
|
|
|
<div class="form-group">
|
|
<label class="control-label">SQLite</label>
|
|
<br />
|
|
<InputText @bind-Value="ConnectionStrings.SQLite" class="form-control" autocomplete="off" />
|
|
<br />
|
|
<ValidationMessage For="() => ConnectionStrings.SQLite" />
|
|
</div>
|
|
|
|
|
|
<div class="form-group">
|
|
<label class="control-label">SQL Server</label>
|
|
<br />
|
|
<InputText @bind-Value="ConnectionStrings.SQLServer" class="form-control" autocomplete="off" />
|
|
<br />
|
|
<ValidationMessage For="() => ConnectionStrings.SQLServer" />
|
|
</div>
|
|
|
|
|
|
<div class="form-group mt-3">
|
|
<button type="button" class="btn btn-primary" @onclick="Save">Save</button>
|
|
</div>
|
|
</EditForm>
|
|
</div>
|
|
</div>
|
|
|
|
}
|
|
else
|
|
{
|
|
<h5 class="text-muted">Only organization administrators can view this page.</h5>
|
|
} |