Updates for PostgreSQL switch.

This commit is contained in:
Jared Goodwin 2020-02-28 19:06:56 -08:00
parent 2524a530db
commit ee2a35a83f
13 changed files with 141 additions and 121 deletions

View File

@ -70,6 +70,8 @@ namespace Remotely.Agent.Services
// The above can be caused by temporary issues on the server. So we'll do
// nothing here and wait for it to get resolved.
Logger.Write("There was an issue registering with the server. The server might be undergoing maintenance, or the supplied organization ID might be incorrect.");
await Task.Delay(TimeSpan.FromMinutes(1));
await HubConnection.StopAsync();
return;
}

View File

@ -10,7 +10,7 @@ using Remotely.Server.Data;
namespace Remotely.Server.Migrations
{
[DbContext(typeof(ApplicationDbContext))]
[Migration("20200226021333_Initial")]
[Migration("20200229022500_Initial")]
partial class Initial
{
protected override void BuildTargetModel(ModelBuilder modelBuilder)
@ -516,9 +516,6 @@ namespace Remotely.Server.Migrations
{
b.HasBaseType("Microsoft.AspNetCore.Identity.IdentityUser");
b.Property<string>("DeviceGroupID")
.HasColumnType("text");
b.Property<bool>("IsAdministrator")
.HasColumnType("boolean");
@ -528,8 +525,6 @@ namespace Remotely.Server.Migrations
b.Property<string>("UserOptions")
.HasColumnType("text");
b.HasIndex("DeviceGroupID");
b.HasIndex("OrganizationID");
b.HasIndex("UserName");
@ -654,10 +649,6 @@ namespace Remotely.Server.Migrations
modelBuilder.Entity("Remotely.Shared.Models.RemotelyUser", b =>
{
b.HasOne("Remotely.Shared.Models.DeviceGroup", null)
.WithMany("Users")
.HasForeignKey("DeviceGroupID");
b.HasOne("Remotely.Shared.Models.Organization", "Organization")
.WithMany("RemotelyUsers")
.HasForeignKey("OrganizationID");

View File

@ -167,6 +167,41 @@ namespace Remotely.Server.Migrations
onDelete: ReferentialAction.Restrict);
});
migrationBuilder.CreateTable(
name: "RemotelyUsers",
columns: table => new
{
Id = table.Column<string>(nullable: false),
UserName = table.Column<string>(maxLength: 256, nullable: true),
NormalizedUserName = table.Column<string>(maxLength: 256, nullable: true),
Email = table.Column<string>(maxLength: 256, nullable: true),
NormalizedEmail = table.Column<string>(maxLength: 256, nullable: true),
EmailConfirmed = table.Column<bool>(nullable: false),
PasswordHash = table.Column<string>(nullable: true),
SecurityStamp = table.Column<string>(nullable: true),
ConcurrencyStamp = table.Column<string>(nullable: true),
PhoneNumber = table.Column<string>(nullable: true),
PhoneNumberConfirmed = table.Column<bool>(nullable: false),
TwoFactorEnabled = table.Column<bool>(nullable: false),
LockoutEnd = table.Column<DateTimeOffset>(nullable: true),
LockoutEnabled = table.Column<bool>(nullable: false),
AccessFailedCount = table.Column<int>(nullable: false),
Discriminator = table.Column<string>(nullable: false),
UserOptions = table.Column<string>(nullable: true),
OrganizationID = table.Column<string>(nullable: true),
IsAdministrator = table.Column<bool>(nullable: true)
},
constraints: table =>
{
table.PrimaryKey("PK_RemotelyUsers", x => x.Id);
table.ForeignKey(
name: "FK_RemotelyUsers_Organizations_OrganizationID",
column: x => x.OrganizationID,
principalTable: "Organizations",
principalColumn: "ID",
onDelete: ReferentialAction.Restrict);
});
migrationBuilder.CreateTable(
name: "SharedFiles",
columns: table => new
@ -233,48 +268,6 @@ namespace Remotely.Server.Migrations
onDelete: ReferentialAction.Restrict);
});
migrationBuilder.CreateTable(
name: "RemotelyUsers",
columns: table => new
{
Id = table.Column<string>(nullable: false),
UserName = table.Column<string>(maxLength: 256, nullable: true),
NormalizedUserName = table.Column<string>(maxLength: 256, nullable: true),
Email = table.Column<string>(maxLength: 256, nullable: true),
NormalizedEmail = table.Column<string>(maxLength: 256, nullable: true),
EmailConfirmed = table.Column<bool>(nullable: false),
PasswordHash = table.Column<string>(nullable: true),
SecurityStamp = table.Column<string>(nullable: true),
ConcurrencyStamp = table.Column<string>(nullable: true),
PhoneNumber = table.Column<string>(nullable: true),
PhoneNumberConfirmed = table.Column<bool>(nullable: false),
TwoFactorEnabled = table.Column<bool>(nullable: false),
LockoutEnd = table.Column<DateTimeOffset>(nullable: true),
LockoutEnabled = table.Column<bool>(nullable: false),
AccessFailedCount = table.Column<int>(nullable: false),
Discriminator = table.Column<string>(nullable: false),
UserOptions = table.Column<string>(nullable: true),
OrganizationID = table.Column<string>(nullable: true),
IsAdministrator = table.Column<bool>(nullable: true),
DeviceGroupID = table.Column<string>(nullable: true)
},
constraints: table =>
{
table.PrimaryKey("PK_RemotelyUsers", x => x.Id);
table.ForeignKey(
name: "FK_RemotelyUsers_DeviceGroups_DeviceGroupID",
column: x => x.DeviceGroupID,
principalTable: "DeviceGroups",
principalColumn: "ID",
onDelete: ReferentialAction.Restrict);
table.ForeignKey(
name: "FK_RemotelyUsers_Organizations_OrganizationID",
column: x => x.OrganizationID,
principalTable: "Organizations",
principalColumn: "ID",
onDelete: ReferentialAction.Restrict);
});
migrationBuilder.CreateTable(
name: "AspNetUserClaims",
columns: table => new
@ -477,11 +470,6 @@ namespace Remotely.Server.Migrations
column: "NormalizedUserName",
unique: true);
migrationBuilder.CreateIndex(
name: "IX_RemotelyUsers_DeviceGroupID",
table: "RemotelyUsers",
column: "DeviceGroupID");
migrationBuilder.CreateIndex(
name: "IX_RemotelyUsers_OrganizationID",
table: "RemotelyUsers",
@ -540,10 +528,10 @@ namespace Remotely.Server.Migrations
name: "AspNetRoles");
migrationBuilder.DropTable(
name: "RemotelyUsers");
name: "DeviceGroups");
migrationBuilder.DropTable(
name: "DeviceGroups");
name: "RemotelyUsers");
migrationBuilder.DropTable(
name: "Organizations");

View File

@ -514,9 +514,6 @@ namespace Remotely.Server.Migrations
{
b.HasBaseType("Microsoft.AspNetCore.Identity.IdentityUser");
b.Property<string>("DeviceGroupID")
.HasColumnType("text");
b.Property<bool>("IsAdministrator")
.HasColumnType("boolean");
@ -526,8 +523,6 @@ namespace Remotely.Server.Migrations
b.Property<string>("UserOptions")
.HasColumnType("text");
b.HasIndex("DeviceGroupID");
b.HasIndex("OrganizationID");
b.HasIndex("UserName");
@ -652,10 +647,6 @@ namespace Remotely.Server.Migrations
modelBuilder.Entity("Remotely.Shared.Models.RemotelyUser", b =>
{
b.HasOne("Remotely.Shared.Models.DeviceGroup", null)
.WithMany("Users")
.HasForeignKey("DeviceGroupID");
b.HasOne("Remotely.Shared.Models.Organization", "Organization")
.WithMany("RemotelyUsers")
.HasForeignKey("OrganizationID");

View File

@ -5,7 +5,7 @@
}
<div class="row mb-3">
<h4>Screen-Sharing Client</h4>
<h4>Instant Support Client</h4>
<div class="text-info col-sm-12 pl-0 mb-2">
Instant desktop sharing. No account required.
</div>

View File

@ -71,17 +71,20 @@ namespace Remotely.Server
}
else if (dbProvider == "postgresql")
{
var connectionBuilder = new NpgsqlConnectionStringBuilder(Configuration.GetConnectionString("PostgreSQL"));
// Password needs to be set in User Secrets in dev environment.
// Password should be set in User Secrets in dev environment.
// See https://docs.microsoft.com/en-us/aspnet/core/security/app-secrets?view=aspnetcore-3.1
if (IsDev)
if (!string.IsNullOrWhiteSpace(Configuration.GetValue<string>("PostgresPassword")))
{
var connectionBuilder = new NpgsqlConnectionStringBuilder(Configuration.GetConnectionString("PostgreSQL"));
connectionBuilder.Password = Configuration["PostgresPassword"];
services.AddDbContext<ApplicationDbContext>(options =>
options.UseNpgsql(connectionBuilder.ConnectionString));
}
else
{
services.AddDbContext<ApplicationDbContext>(options =>
options.UseNpgsql(Configuration.GetConnectionString("PostgreSQL")));
}
services.AddDbContext<ApplicationDbContext>(options =>
options.UseNpgsql(connectionBuilder.ConnectionString));
}
services.AddIdentity<RemotelyUser, IdentityRole>(options => options.Stores.MaxLengthForKeys = 128)

View File

@ -1,9 +1,9 @@
<?xml version="1.0" encoding="utf-8"?>
<configuration>
<system.webServer>
<modules runAllManagedModulesForAllRequests="false">
<!--<modules runAllManagedModulesForAllRequests="false">
<remove name="WebDAVModule" />
</modules>
</modules>-->
<security>
<requestFiltering>
<requestLimits maxAllowedContentLength="100000000" />

View File

@ -131,4 +131,8 @@ span.label.code {
}
.chat-input {
background-color: lightgray;
}
#deviceGrid .fas:hover {
color: #2A9FD6 !important;
}

View File

@ -123,4 +123,8 @@ span.label.code {
.chat-header {
color: white;
background-color: #008cba;
}
#deviceGrid .fas:hover {
color: #008cba !important;
}

View File

@ -3,6 +3,7 @@ import { Main } from "./Main.js";
import { DeviceGrid } from "./UI.js";
import { AddConsoleOutput } from "./Console.js";
import { CreateChatWindow } from "./Chat.js";
import * as BrowserSockets from "./BrowserSockets.js";
export const DataSource = new Array();
export const FilterOptions = new class {
constructor() {
@ -66,7 +67,8 @@ export function AddOrUpdateDevice(device) {
<td>${device.TotalMemory.toLocaleString()}</td>
<td>
<i class="fas fa-comment device-chat-button mr-2" title="Chat" style="font-size:1.5em"></i>
<span class="fas fa-edit device-edit-button" title="Edit" style="font-size:1.5em" />
<i class="fas fa-mouse device-remotecontrol-button mr-2" title="Remote Control" style="font-size:1.5em"></i>
<i class="fas fa-edit device-edit-button" title="Edit" style="font-size:1.5em"></i>
</td>`;
recordRow.querySelector(".device-edit-button").onclick = (ev) => {
ev.preventDefault();
@ -78,6 +80,12 @@ export function AddOrUpdateDevice(device) {
ev.stopPropagation();
CreateChatWindow(device.ID, device.DeviceName);
};
recordRow.querySelector(".device-remotecontrol-button").onclick = (ev) => {
ev.preventDefault();
ev.stopPropagation();
AddConsoleOutput("Launching remote control on client device...");
BrowserSockets.Connection.invoke("RemoteControl", device.ID);
};
UpdateDeviceCounts();
}
export function ApplyFilter() {

File diff suppressed because one or more lines are too long

View File

@ -4,6 +4,7 @@ import { Main } from "./Main.js";
import { DeviceGrid } from "./UI.js";
import { AddConsoleOutput } from "./Console.js";
import { CreateChatWindow } from "./Chat.js";
import * as BrowserSockets from "./BrowserSockets.js"
export const DataSource: Array<Device> = new Array<Device>();
@ -74,7 +75,8 @@ export function AddOrUpdateDevice(device: Device) {
<td>${device.TotalMemory.toLocaleString()}</td>
<td>
<i class="fas fa-comment device-chat-button mr-2" title="Chat" style="font-size:1.5em"></i>
<span class="fas fa-edit device-edit-button" title="Edit" style="font-size:1.5em" />
<i class="fas fa-mouse device-remotecontrol-button mr-2" title="Remote Control" style="font-size:1.5em"></i>
<i class="fas fa-edit device-edit-button" title="Edit" style="font-size:1.5em"></i>
</td>`;
@ -88,6 +90,12 @@ export function AddOrUpdateDevice(device: Device) {
ev.stopPropagation();
CreateChatWindow(device.ID, device.DeviceName);
};
(recordRow.querySelector(".device-remotecontrol-button") as HTMLButtonElement).onclick = (ev) => {
ev.preventDefault();
ev.stopPropagation();
AddConsoleOutput("Launching remote control on client device...");
BrowserSockets.Connection.invoke("RemoteControl", device.ID);
};
UpdateDeviceCounts();
}
export function ApplyFilter() {

View File

@ -14,9 +14,15 @@ param (
[Parameter(Mandatory=$True)]
[string]$BindingHostname,
[switch]$Quiet
[switch]$Quiet,
[string]$WacsPath,
[string]$EmailAddress
)
[Net.ServicePointManager]::SecurityProtocol = [Net.SecurityProtocolType]::Tls12
$ErrorActionPreference = "Stop"
$Host.UI.RawUI.WindowTitle = "Remotely Setup"
Clear-Host
@ -139,10 +145,19 @@ if ((Get-Package -Name "*PostgreSQL*" -ErrorAction SilentlyContinue) -eq $null){
Wrap-Host
Wrap-Host "ERROR: PostgreSQL was not found. Please install it from https://postgresql.org." -ForegroundColor Red
Wrap-Host
pause
Do-Pause
return
}
if ((Get-Package -Name "*3.1.2 - Windows Server Hosting*" -ErrorAction SilentlyContinue) -eq $null){
Wrap-Host "Downloading .NET Core Runtime and Hosting Bundle..."
$ProgressPreference = "SilentlyContinue"
Invoke-WebRequest -Uri "https://download.visualstudio.microsoft.com/download/pr/dd119832-dc46-4ccf-bc12-69e7bfa61b18/990843c6e0cbd97f9df68c94f6de6bb6/dotnet-hosting-3.1.2-win.exe" -OutFile "$env:TEMP\dotnet-hosting-3.1.2-win.exe"
$ProgressPreference = "Continue"
Start-Process -FilePath "$env:TEMP\dotnet-hosting-3.1.2-win.exe" -ArgumentList "/install /quiet /norestart" -Wait
Wrap-Host
Wrap-Host ".NET Runtime installation completed."
}
#endregion
@ -171,7 +186,7 @@ Wrap-Host "**********************************"
Wrap-Host
Wrap-Host "Hello, and thank you for trying out Remotely!" -ForegroundColor Green
Wrap-Host
Wrap-Host "This setup script will install Remotely on this machine. Please make sure you've already created a website in IIS where Remotely will be installed." -ForegroundColor Green
Wrap-Host "This setup script will create an IIS site and install Remotely on this machine." -ForegroundColor Green
Wrap-Host
Wrap-Host "If you encounter any problems or have any questions, please contact Translucency_Software@outlook.com." -ForegroundColor Green
Wrap-Host
@ -190,36 +205,36 @@ if ($ServerCmdlets) {
{
$RebootRequired = $true
}
Write-Progress -Activity "IIS Component Installation" -Status "Installing ASP.NET" -PercentComplete (2/7*100)
$Result = Add-WindowsFeature Web-Asp-Net
if ($Result.RestartNeeded -like "Yes")
{
$RebootRequired = $true
}
Write-Progress -Activity "IIS Component Installation" -Status "Installing ASP.NET 4.5" -PercentComplete (3/7*100)
$Result = Add-WindowsFeature Web-Asp-Net45
if ($Result.RestartNeeded -like "Yes")
{
$RebootRequired = $true
}
Write-Progress -Activity "IIS Component Installation" -Status "Installing web sockets" -PercentComplete (4/7*100)
$Result = Add-WindowsFeature Web-WebSockets
if ($Result.RestartNeeded -like "Yes")
{
$RebootRequired = $true
}
#Write-Progress -Activity "IIS Component Installation" -Status "Installing ASP.NET" -PercentComplete (2/7*100)
#$Result = Add-WindowsFeature Web-Asp-Net
#if ($Result.RestartNeeded -like "Yes")
#{
# $RebootRequired = $true
#}
#Write-Progress -Activity "IIS Component Installation" -Status "Installing ASP.NET 4.5" -PercentComplete (3/7*100)
#$Result = Add-WindowsFeature Web-Asp-Net45
#if ($Result.RestartNeeded -like "Yes")
#{
# $RebootRequired = $true
#}
#Write-Progress -Activity "IIS Component Installation" -Status "Installing web sockets" -PercentComplete (4/7*100)
#$Result = Add-WindowsFeature Web-WebSockets
#if ($Result.RestartNeeded -like "Yes")
#{
# $RebootRequired = $true
#}
Write-Progress -Activity "IIS Component Installation" -Status "Installing IIS management tools" -PercentComplete (5/7*100)
$Result = Add-WindowsFeature Web-Mgmt-Tools
if ($Result.RestartNeeded -like "Yes")
{
$RebootRequired = $true
}
Write-Progress -Activity "IIS Component Installation" -Status "Installing web filtering" -PercentComplete (6/7*100)
$Result = Add-WindowsFeature Web-Filtering
if ($Result.RestartNeeded -like "Yes")
{
$RebootRequired = $true
}
#Write-Progress -Activity "IIS Component Installation" -Status "Installing web filtering" -PercentComplete (6/7*100)
#$Result = Add-WindowsFeature Web-Filtering
#if ($Result.RestartNeeded -like "Yes")
#{
# $RebootRequired = $true
#}
Write-Progress -Activity "IIS Component Installation" -Status "IIS setup completed" -PercentComplete (7/7*100) -Completed
Start-Sleep 2
@ -231,20 +246,20 @@ else
Write-Progress -Activity "IIS Component Installation" -Status "Installing web server" -PercentComplete (1/7*100)
DISM /Online /Enable-Feature /FeatureName:IIS-WebServer /All /Quiet
Write-Progress -Activity "IIS Component Installation" -Status "Installing ASP.NET" -PercentComplete (2/7*100)
DISM /Online /Enable-Feature /FeatureName:IIS-ASPNET /All /Quiet
#Write-Progress -Activity "IIS Component Installation" -Status "Installing ASP.NET" -PercentComplete (2/7*100)
#DISM /Online /Enable-Feature /FeatureName:IIS-ASPNET /All /Quiet
Write-Progress -Activity "IIS Component Installation" -Status "Installing ASP.NET 4.5" -PercentComplete (3/7*100)
DISM /Online /Enable-Feature /FeatureName:IIS-ASPNET45 /All /Quiet
#Write-Progress -Activity "IIS Component Installation" -Status "Installing ASP.NET 4.5" -PercentComplete (3/7*100)
#DISM /Online /Enable-Feature /FeatureName:IIS-ASPNET45 /All /Quiet
Write-Progress -Activity "IIS Component Installation" -Status "Installing web sockets" -PercentComplete (4/7*100)
DISM /Online /Enable-Feature /FeatureName:IIS-WebSockets /All /Quiet
#Write-Progress -Activity "IIS Component Installation" -Status "Installing web sockets" -PercentComplete (4/7*100)
#DISM /Online /Enable-Feature /FeatureName:IIS-WebSockets /All /Quiet
Write-Progress -Activity "IIS Component Installation" -Status "Installing IIS management tools" -PercentComplete (5/7*100)
DISM /Online /Enable-Feature /FeatureName:IIS-ManagementConsole /All /Quiet
Write-Progress -Activity "IIS Component Installation" -Status "Installing web filtering" -PercentComplete (6/7*100)
DISM /Online /Enable-Feature /FeatureName:IIS-RequestFiltering /All /Quiet
#Write-Progress -Activity "IIS Component Installation" -Status "Installing web filtering" -PercentComplete (6/7*100)
#DISM /Online /Enable-Feature /FeatureName:IIS-RequestFiltering /All /Quiet
Write-Progress -Activity "IIS Component Installation" -Status "IIS setup completed" -PercentComplete (7/7*100) -Completed
Start-Sleep 2
@ -253,15 +268,14 @@ else
Clear-Host
### Create IIS Site ##
[System.IO.Directory]::CreateDirectory($FilePath)
[System.IO.Directory]::CreateDirectory($SitePath)
if ((Get-IISAppPool -Name $AppPoolName) -eq $null) {
New-WebAppPool -Name $AppPoolName
}
if ((Get-Website -Name $SiteName) -eq $null) {
New-Website -Name $SiteName -PhysicalPath $SitePath -HostHeader $BindingHostname
New-WebBinding -Name $SiteName -Protocol "https" -Port 443 -HostHeader $BindingHostname
New-Website -Name $SiteName -PhysicalPath $SitePath -HostHeader $BindingHostname -ApplicationPool $AppPoolName
}
@ -300,8 +314,9 @@ try {
Remove-Item -Path "$env:TEMP\Remotely_Server_Win-x64.zip" -Force
}
Wrap-Host "Downloading server package..."
[Net.ServicePointManager]::SecurityProtocol = [Net.SecurityProtocolType]::Tls12
$ProgressPreference = "SilentlyContinue"
Invoke-WebRequest -Uri "https://github.com/Jay-Rad/Remotely/releases/latest/download/Remotely_Server_Win-x64.zip" -OutFile "$env:TEMP\Remotely_Server_Win-x64.zip"
$ProgressPreference = "Continue"
Wrap-Host "Extracting server files..."
[System.Reflection.Assembly]::LoadWithPartialName("System.IO.Compression.FileSystem") | Out-Null
[System.IO.Compression.ZipFile]::ExtractToDirectory("$env:TEMP\Remotely_Server_Win-x64.zip", $SitePath)
@ -349,6 +364,12 @@ catch
# Start website.
Start-Website -Name $SiteName
### SSL certificate installation. ###
if ($WacsPath -ne $null -and (Test-Path -Path $WacsPath)) {
&"$WacsPath" --target iis --siteid (Get-Website -Name $SiteName).ID --installation iis --emailaddress $EmailAddress --accepttos
}
Wrap-Host
Wrap-Host
Wrap-Host
@ -356,7 +377,7 @@ Wrap-Host "**********************************"
Wrap-Host " Server setup complete!" -ForegroundColor Green
Wrap-Host "**********************************"
Wrap-Host
Wrap-Host "Website bindings and SSL need to be set up in IIS, if they're not already. This process needs to be completed manually. I recommend researching Let's Encrypt for free, automated SSL certificates." -ForegroundColor Green
Wrap-Host "If a path to Win-Acme exe path (WacsPath) wasn't provided, SSL/TLS needs to be set up in IIS. I recommend checking out Let's Encrypt for free, automated SSL certificates." -ForegroundColor Green
if ($RebootRequired) {
Wrap-Host