├── .azure-pipelines └── Release Build.yml ├── .editorconfig ├── .gitattributes ├── .github ├── ISSUE_TEMPLATE │ ├── bug_report.md │ └── feature_request.md ├── media │ └── ask-remote.png ├── pull_request_template.md └── workflows │ ├── build.yml │ └── run_tests.yml ├── .gitignore ├── .gitmodules ├── .vscode ├── launch.json └── tasks.json ├── Agent ├── Agent.csproj ├── Assets │ └── favicon.ico ├── Extensions │ └── PowerShellCompletionExtensions.cs ├── Interfaces │ ├── IAppLauncher.cs │ ├── IDeviceInformationService.cs │ ├── IScriptingShell.cs │ └── IUpdater.cs ├── Models │ └── ChatSession.cs ├── Program.cs ├── Properties │ └── launchSettings.json └── Services │ ├── AgentHubConnection.cs │ ├── ChatClientService.cs │ ├── ConfigService.cs │ ├── CpuUtilizationSampler.cs │ ├── DeviceInfoGeneratorBase.cs │ ├── ExternalScriptingShell.cs │ ├── FileLogsManager.cs │ ├── Linux │ ├── AppLauncherLinux.cs │ ├── DeviceInfoGeneratorLinux.cs │ └── UpdaterLinux.cs │ ├── MacOS │ ├── AppLauncherMac.cs │ ├── DeviceInfoGeneratorMac.cs │ └── UpdaterMac.cs │ ├── PsCoreShell.cs │ ├── ScriptExecutor.cs │ ├── ScriptingShellFactory.cs │ ├── Uninstaller.cs │ ├── UpdateDownloader.cs │ ├── WakeOnLanService.cs │ └── Windows │ ├── AppLauncherWin.cs │ ├── DeviceInfoGeneratorWin.cs │ └── UpdaterWin.cs ├── Assets ├── Remotely_Icon.ico ├── Remotely_Icon.pdn ├── Remotely_Icon.png └── Remotely_Logo.png ├── Desktop.Core ├── Assets │ └── Remotely_Icon.png ├── Conductor.cs ├── Desktop.Core.csproj ├── Enums │ ├── AppMode.cs │ └── ButtonAction.cs ├── Extensions │ └── SKBitmapExtensions.cs ├── Interfaces │ ├── IAudioCapturer.cs │ ├── IChatClientService.cs │ ├── IChatUiService.cs │ ├── IClipboardService.cs │ ├── IConfigService.cs │ ├── ICursorIconWatcher.cs │ ├── IFileTransferService.cs │ ├── IKeyboardMouseInput.cs │ ├── IRemoteControlAccessService.cs │ ├── IScreenCapturer.cs │ ├── ISessionIndicator.cs │ └── IShutdownService.cs ├── Models │ └── CaptureFrame.cs ├── ServiceContainer.cs ├── Services │ ├── CasterSocket.cs │ ├── ChatHostService.cs │ ├── DeviceInitService.cs │ ├── DtoMessageHandler.cs │ ├── IdleTimer.cs │ ├── ScreenCaster.cs │ └── Viewer.cs ├── Utilities │ └── ImageUtils.cs └── ViewModels │ ├── FileUpload.cs │ └── ViewModelBase.cs ├── Desktop.Linux ├── Assets │ ├── Remotely_Icon.png │ ├── avalonia-logo.ico │ └── favicon.ico ├── Desktop.Linux.csproj ├── Program.cs ├── Properties │ ├── PublishProfiles │ │ ├── desktop-linux-x64.pubxml │ │ └── packaged-linux-x64.pubxml │ └── launchSettings.json ├── Services │ ├── AppStartup.cs │ ├── AudioCapturerLinux.cs │ ├── CursorIconWatcherLinux.cs │ ├── FileTransferServiceLinux.cs │ ├── KeyboardMouseInputLinux.cs │ ├── ScreenCapturerLinux.cs │ └── ShutdownServiceLinux.cs ├── Startup │ └── IServiceCollectionExtensions.cs ├── Usings.cs └── nuget.config ├── Desktop.Native ├── Desktop.Native.csproj ├── Linux │ ├── LibX11.cs │ ├── LibXtst.cs │ ├── Libc.cs │ └── libXrandr.cs └── Windows │ ├── ADVAPI32.cs │ ├── GDI32.cs │ ├── Kernel32.cs │ ├── SECUR32.cs │ ├── Shlwapi.cs │ ├── User32.cs │ ├── WTSAPI32.cs │ └── Win32Interop.cs ├── Desktop.Shared ├── Abstractions │ ├── IAppStartup.cs │ ├── IAudioCapturer.cs │ ├── IChatUiService.cs │ ├── IClipboardService.cs │ ├── ICursorIconWatcher.cs │ ├── IFileTransferService.cs │ ├── IKeyboardMouseInput.cs │ ├── IRemoteControlAccessService.cs │ ├── IScreenCapturer.cs │ ├── ISessionIndicator.cs │ └── IShutdownService.cs ├── Assets │ ├── DefaultIcon.ico │ ├── DefaultIcon.png │ ├── Remotely_Icon.png │ └── favicon.ico ├── Desktop.Shared.csproj ├── Enums │ ├── AppMode.cs │ └── ButtonAction.cs ├── Extensions │ └── SKBitmapExtensions.cs ├── Messages │ ├── AppStateHostChangedMessage.cs │ ├── DisplaySettingsChangedMessage.cs │ ├── WindowsSessionEndingMessage.cs │ └── WindowsSessionSwitchedMessage.cs ├── Properties │ └── AssemblyInfo.cs ├── Reactive │ ├── AsyncRelayCommand.cs │ ├── ObservableObject.cs │ └── RelayCommand.cs ├── Services │ ├── AppState.cs │ ├── BrandingProvider.cs │ ├── ChatHostService.cs │ ├── DesktopEnvironment.cs │ ├── DesktopHubConnection.cs │ ├── DtoMessageHandler.cs │ ├── IdleTimer.cs │ ├── ImageHelper.cs │ ├── ScreenCaster.cs │ ├── Viewer.cs │ └── ViewerFactory.cs ├── Startup │ ├── CommandProvider.cs │ ├── IServiceCollectionExtensions.cs │ └── IServiceProviderExtensions.cs ├── StaticServiceProvider.cs └── ViewModels │ └── FileUpload.cs ├── Desktop.UI ├── App.axaml ├── App.axaml.cs ├── Assets │ ├── DefaultIcon.ico │ ├── DefaultIcon.png │ ├── Gear.png │ └── avalonia-logo.ico ├── Controls │ └── Dialogs │ │ ├── MessageBox.axaml │ │ ├── MessageBox.axaml.cs │ │ ├── MessageBoxResult.cs │ │ └── MessageBoxType.cs ├── Desktop.UI.csproj ├── GlobalUsings.cs ├── Services │ ├── ChatUiService.cs │ ├── ClipboardService.cs │ ├── DialogProvider.cs │ ├── RemoteControlAccessService.cs │ ├── SessionIndicator.cs │ ├── UiDispatcher.cs │ └── ViewModelFactory.cs ├── Startup │ └── IServiceCollectionExtensions.cs ├── ViewModels │ ├── BrandedViewModelBase.cs │ ├── ChatWindowViewModel.cs │ ├── Fakes │ │ ├── FakeBrandedViewModelBase.cs │ │ ├── FakeChatWindowViewModel.cs │ │ ├── FakeFileTransferViewModel.cs │ │ ├── FakeHostNamePromptViewModel.cs │ │ ├── FakeMainViewViewModel.cs │ │ ├── FakeMainWindowViewModel.cs │ │ ├── FakeMessageBoxViewModel.cs │ │ ├── FakePromptForAccessViewModel.cs │ │ └── FakeSessionIndicatorWindowViewModel.cs │ ├── FileTransferWindowViewModel.cs │ ├── HostNamePromptViewModel.cs │ ├── MainViewViewModel.cs │ ├── MainWindowViewModel.cs │ ├── MessageBoxViewModel.cs │ ├── PromptForAccessWindowViewModel.cs │ └── SessionIndicatorWindowViewModel.cs └── Views │ ├── ChatWindow.axaml │ ├── ChatWindow.axaml.cs │ ├── FileTransferWindow.axaml │ ├── FileTransferWindow.axaml.cs │ ├── HostNamePrompt.axaml │ ├── HostNamePrompt.axaml.cs │ ├── MainView.axaml │ ├── MainView.axaml.cs │ ├── MainWindow.axaml │ ├── MainWindow.axaml.cs │ ├── PromptForAccessWindow.axaml │ ├── PromptForAccessWindow.axaml.cs │ ├── SessionIndicatorWindow.axaml │ └── SessionIndicatorWindow.axaml.cs ├── Desktop.Win ├── Assets │ ├── Remotely_Icon.png │ └── favicon.ico ├── Desktop.Win.csproj ├── Helpers │ └── DisplayEnumerationHelper.cs ├── Models │ └── DirectXOutput.cs ├── Program.cs ├── Properties │ ├── AssemblyInfo.cs │ ├── PublishProfiles │ │ ├── desktop-win-x64.pubxml │ │ ├── desktop-win-x86.pubxml │ │ ├── install-folder.pubxml │ │ ├── packaged-win-x64-debug.pubxml │ │ ├── packaged-win-x64.pubxml │ │ └── packaged-win-x86.pubxml │ └── launchSettings.json ├── Services │ ├── AppStartup.cs │ ├── AudioCapturerWin.cs │ ├── CursorIconWatcherWin.cs │ ├── FileTransferServiceWin.cs │ ├── KeyboardMouseInputWin.cs │ ├── MessageLoop.cs │ ├── ScreenCapturerWin.cs │ └── ShutdownServiceWin.cs ├── Startup │ └── IServiceCollectionExtensions.cs ├── Usings.cs └── app.manifest ├── Directory.Build.props ├── LICENSE ├── README.md ├── Remotely.sln ├── Remotely.sln.startup.json ├── Remotely.slnLaunch ├── Server ├── API │ ├── AgentUpdateController.cs │ ├── AlertsController.cs │ ├── BrandingController.cs │ ├── ClientDownloadsController.cs │ ├── CustomBinariesController.cs │ ├── DevicesController.cs │ ├── FileSharingController.cs │ ├── HealthCheckController.cs │ ├── LoginController.cs │ ├── OrganizationManagementController.cs │ ├── RemoteControlController.cs │ ├── SavedScriptsController.cs │ ├── ScriptResultsController.cs │ ├── ScriptingController.cs │ └── ServerLogsController.cs ├── Auth │ ├── ApiAuthorizationFilter.cs │ ├── ExpiringTokenFilter.cs │ ├── LocalOnlyFilter.cs │ ├── OrganizationAdminRequirement.cs │ ├── OrganizationAdminRequirementHandler.cs │ ├── PolicyNames.cs │ ├── ServerAdminRequirement.cs │ ├── ServerAdminRequirementHandler.cs │ ├── TwoFactorRequiredHandler.cs │ └── TwoFactorRequiredRequirement.cs ├── Components │ ├── Account │ │ ├── IdentityComponentsEndpointRouteBuilderExtensions.cs │ │ ├── IdentityNoOpEmailSender.cs │ │ ├── IdentityRedirectManager.cs │ │ ├── IdentityRevalidatingAuthenticationStateProvider.cs │ │ ├── IdentityUserAccessor.cs │ │ ├── Pages │ │ │ ├── AccessDenied.razor │ │ │ ├── ConfirmEmail.razor │ │ │ ├── ConfirmEmailChange.razor │ │ │ ├── ExternalLogin.razor │ │ │ ├── ForgotPassword.razor │ │ │ ├── ForgotPasswordConfirmation.razor │ │ │ ├── InvalidPasswordReset.razor │ │ │ ├── InvalidUser.razor │ │ │ ├── Lockout.razor │ │ │ ├── Login.razor │ │ │ ├── LoginWith2fa.razor │ │ │ ├── LoginWithRecoveryCode.razor │ │ │ ├── Manage │ │ │ │ ├── ChangePassword.razor │ │ │ │ ├── DeletePersonalData.razor │ │ │ │ ├── Disable2fa.razor │ │ │ │ ├── Email.razor │ │ │ │ ├── EnableAuthenticator.razor │ │ │ │ ├── ExternalLogins.razor │ │ │ │ ├── GenerateRecoveryCodes.razor │ │ │ │ ├── Index.razor │ │ │ │ ├── PersonalData.razor │ │ │ │ ├── ResetAuthenticator.razor │ │ │ │ ├── SetPassword.razor │ │ │ │ ├── TwoFactorAuthentication.razor │ │ │ │ └── _Imports.razor │ │ │ ├── Register.razor │ │ │ ├── RegisterConfirmation.razor │ │ │ ├── ResendEmailConfirmation.razor │ │ │ ├── ResetPassword.razor │ │ │ ├── ResetPasswordConfirmation.razor │ │ │ └── _Imports.razor │ │ └── Shared │ │ │ ├── AccountLayout.razor │ │ │ ├── ExternalLoginPicker.razor │ │ │ ├── ManageLayout.razor │ │ │ ├── ManageNavMenu.razor │ │ │ ├── RedirectToLogin.razor │ │ │ ├── ShowRecoveryCodes.razor │ │ │ └── StatusMessage.razor │ ├── AlertBanner.razor │ ├── AlertsFrame.razor │ ├── AlertsFrame.razor.css │ ├── App.razor │ ├── AuthComponentBase.cs │ ├── AuthorizedIndex.razor │ ├── ColorPicker.razor │ ├── ColorPicker.razor.css │ ├── Devices │ │ ├── ChatCard.razor │ │ ├── ChatCard.razor.cs │ │ ├── ChatCard.razor.css │ │ ├── ChatFrame.razor │ │ ├── ChatFrame.razor.cs │ │ ├── ChatFrame.razor.css │ │ ├── DeviceCard.razor │ │ ├── DeviceCard.razor.cs │ │ ├── DeviceCard.razor.css │ │ ├── DevicesFrame.razor │ │ ├── DevicesFrame.razor.cs │ │ ├── DevicesFrame.razor.css │ │ ├── Terminal.razor │ │ ├── Terminal.razor.cs │ │ └── Terminal.razor.css │ ├── DropdownButton.razor │ ├── FileInputButton.razor │ ├── Layout │ │ ├── MainLayout.razor │ │ ├── MainLayout.razor.css │ │ ├── NavMenu.razor │ │ └── NavMenu.razor.css │ ├── LoaderHarness.razor │ ├── LoadingSignal.razor │ ├── LoadingSignal.razor.css │ ├── MessengerSubscriber.cs │ ├── ModalContents │ │ ├── EditDeviceGroup.razor │ │ ├── EditDeviceGroup.razor.cs │ │ ├── QuickScriptsSelector.razor │ │ └── QuickScriptsSelector.razor.cs │ ├── ModalHarness.razor │ ├── ModalHarness.razor.js │ ├── Pages │ │ ├── About.razor │ │ ├── ApiKeys.razor │ │ ├── Branding.razor │ │ ├── Branding.razor.css │ │ ├── Credits.razor │ │ ├── Credits.razor.css │ │ ├── Deploy.razor │ │ ├── DeviceDetails.razor │ │ ├── DeviceDetails.razor.cs │ │ ├── Downloads.razor │ │ ├── Error.razor │ │ ├── GetSupport.razor │ │ ├── GetSupport.razor.css │ │ ├── Index.razor │ │ ├── Invite.razor │ │ ├── ManageOrganization.razor │ │ ├── ManageOrganization.razor.cs │ │ ├── ManageOrganization.razor.css │ │ ├── ScriptsPage.razor │ │ ├── ScriptsPage.razor.cs │ │ ├── ServerConfig.razor │ │ ├── ServerConfig.razor.cs │ │ ├── ServerConfig.razor.css │ │ ├── ServerLogs.razor │ │ ├── ServerLogs.razor.css │ │ └── UserOptions.razor │ ├── Routes.razor │ ├── Scripts │ │ ├── RunScript.razor │ │ ├── RunScript.razor.cs │ │ ├── RunScript.razor.css │ │ ├── SavedScripts.razor │ │ ├── SavedScripts.razor.cs │ │ ├── SavedScripts.razor.css │ │ ├── ScriptSchedules.razor │ │ ├── ScriptSchedules.razor.cs │ │ ├── ScriptSchedules.razor.css │ │ └── ScriptTreeNode.cs │ ├── TabControl │ │ ├── TabContent.razor │ │ ├── TabControl.razor │ │ └── TabHeader.razor │ ├── ToastHarness.razor │ ├── ToastHarness.razor.css │ ├── TreeView │ │ ├── TreeItemType.cs │ │ ├── TreeView.razor │ │ ├── TreeView.razor.cs │ │ ├── TreeView.razor.css │ │ ├── TreeViewItem.razor │ │ ├── TreeViewItem.razor.cs │ │ └── TreeViewItem.razor.css │ └── _Imports.razor ├── Converters │ └── PostgresDateTimeOffsetConverter.cs ├── Data │ ├── AppDb.cs │ ├── AppDbFactory.cs │ ├── DesignTimeContexts.cs │ ├── PostgreSqlDbContext.cs │ ├── SqlServerDbContext.cs │ ├── SqliteDbContext.cs │ └── TestingDbContext.cs ├── Dockerfile ├── Dockerfile.old ├── Dockerfile.pipelines ├── Dockerfile.rootless ├── Enums │ ├── DeviceCardState.cs │ ├── StreamerState.cs │ └── ToastType.cs ├── Extensions │ ├── AppDbExtensions.cs │ ├── IApplicationBuilderExtensions.cs │ ├── IHeaderDictionaryExtensions.cs │ └── IQueryableExtensions.cs ├── Filters │ └── ViewerAuthorizationFilter.cs ├── Hubs │ ├── AgentHub.cs │ ├── CircuitConnection.cs │ ├── DesktopHub.cs │ └── ViewerHub.cs ├── Migrations │ ├── PostgreSql │ │ ├── 20201005051254_Initial.Designer.cs │ │ ├── 20201005051254_Initial.cs │ │ ├── 20201204210854_Many-to-many.Designer.cs │ │ ├── 20201204210854_Many-to-many.cs │ │ ├── 20210103153552_WebRtcSetting.Designer.cs │ │ ├── 20210103153552_WebRtcSetting.cs │ │ ├── 20210205114430_IsSponsor property.Designer.cs │ │ ├── 20210205114430_IsSponsor property.cs │ │ ├── 20210205221307_Sponsorship Info.Designer.cs │ │ ├── 20210205221307_Sponsorship Info.cs │ │ ├── 20210206174950_Sponsor Level.Designer.cs │ │ ├── 20210206174950_Sponsor Level.cs │ │ ├── 20210206232836_Branding Info.Designer.cs │ │ ├── 20210206232836_Branding Info.cs │ │ ├── 20210207000358_Rename Branding Props.Designer.cs │ │ ├── 20210207000358_Rename Branding Props.cs │ │ ├── 20210210030835_Change BrandingInfo Id.Designer.cs │ │ ├── 20210210030835_Change BrandingInfo Id.cs │ │ ├── 20210217033418_Remove 3rd Party Services.Designer.cs │ │ ├── 20210217033418_Remove 3rd Party Services.cs │ │ ├── 20210408133040_Add ScriptSchedules.Designer.cs │ │ ├── 20210408133040_Add ScriptSchedules.cs │ │ ├── 20210417155843_Add Alert Details.Designer.cs │ │ ├── 20210417155843_Add Alert Details.cs │ │ ├── 20220827150639_Remove deprecated WebRTC.Designer.cs │ │ ├── 20220827150639_Remove deprecated WebRTC.cs │ │ ├── 20220917171937_Branding fix.Designer.cs │ │ ├── 20220917171937_Branding fix.cs │ │ ├── 20221231192625_Remove RelayCode.Designer.cs │ │ ├── 20221231192625_Remove RelayCode.cs │ │ ├── 20230523215805_Replace DbLogger with Serilog.Designer.cs │ │ ├── 20230523215805_Replace DbLogger with Serilog.cs │ │ ├── 20230622144413_Add_Agent_MacAddress.Designer.cs │ │ ├── 20230622144413_Add_Agent_MacAddress.cs │ │ ├── 20230801210115_Enable_NullableReferences.Designer.cs │ │ ├── 20230801210115_Enable_NullableReferences.cs │ │ ├── 20230821190450_Remove_TitleBranding.Designer.cs │ │ ├── 20230821190450_Remove_TitleBranding.cs │ │ ├── 20240221010243_Add_KeyValueRecords.Designer.cs │ │ ├── 20240221010243_Add_KeyValueRecords.cs │ │ └── PostgreSqlDbContextModelSnapshot.cs │ ├── SqlServer │ │ ├── 20201002214839_InitialCreate.Designer.cs │ │ ├── 20201002214839_InitialCreate.cs │ │ ├── 20201204210331_Many-to-many.Designer.cs │ │ ├── 20201204210331_Many-to-many.cs │ │ ├── 20210103153621_WebRtcSetting.Designer.cs │ │ ├── 20210103153621_WebRtcSetting.cs │ │ ├── 20210205114415_IsSponsor property.Designer.cs │ │ ├── 20210205114415_IsSponsor property.cs │ │ ├── 20210205221252_Sponsorship Info.Designer.cs │ │ ├── 20210205221252_Sponsorship Info.cs │ │ ├── 20210206174936_Sponsor Level.Designer.cs │ │ ├── 20210206174936_Sponsor Level.cs │ │ ├── 20210206232822_Branding Info.Designer.cs │ │ ├── 20210206232822_Branding Info.cs │ │ ├── 20210207000343_Rename Branding Props.Designer.cs │ │ ├── 20210207000343_Rename Branding Props.cs │ │ ├── 20210210030806_Change BrandingInfo Id.Designer.cs │ │ ├── 20210210030806_Change BrandingInfo Id.cs │ │ ├── 20210217033404_Remove 3rd Party Services.Designer.cs │ │ ├── 20210217033404_Remove 3rd Party Services.cs │ │ ├── 20210408133030_Add ScriptSchedules.Designer.cs │ │ ├── 20210408133030_Add ScriptSchedules.cs │ │ ├── 20210417155829_Add Alert Details.Designer.cs │ │ ├── 20210417155829_Add Alert Details.cs │ │ ├── 20220827150630_Remove deprecated WebRTC.Designer.cs │ │ ├── 20220827150630_Remove deprecated WebRTC.cs │ │ ├── 20220917171927_Branding fix.Designer.cs │ │ ├── 20220917171927_Branding fix.cs │ │ ├── 20221231192616_Remove RelayCode.Designer.cs │ │ ├── 20221231192616_Remove RelayCode.cs │ │ ├── 20230523215756_Replace DbLogger with Serilog.Designer.cs │ │ ├── 20230523215756_Replace DbLogger with Serilog.cs │ │ ├── 20230622144404_Add_Agent_MacAddress.Designer.cs │ │ ├── 20230622144404_Add_Agent_MacAddress.cs │ │ ├── 20230801210106_Enable_NullableReferences.Designer.cs │ │ ├── 20230801210106_Enable_NullableReferences.cs │ │ ├── 20230821190440_Remove_TitleBranding.Designer.cs │ │ ├── 20230821190440_Remove_TitleBranding.cs │ │ ├── 20240221010103_Add_KeyValueRecords.Designer.cs │ │ ├── 20240221010103_Add_KeyValueRecords.cs │ │ └── SqlServerDbContextModelSnapshot.cs │ └── Sqlite │ │ ├── 20200305230311_Initial.Designer.cs │ │ ├── 20200305230311_Initial.cs │ │ ├── 20200306013915_IsServerAdmin property.Designer.cs │ │ ├── 20200306013915_IsServerAdmin property.cs │ │ ├── 20200325145606_Alerts.Designer.cs │ │ ├── 20200325145606_Alerts.cs │ │ ├── 20200327034430_Device Notes.Designer.cs │ │ ├── 20200327034430_Device Notes.cs │ │ ├── 20200425052143_PublicIP.Designer.cs │ │ ├── 20200425052143_PublicIP.cs │ │ ├── 20200430222500_DisplayName.Designer.cs │ │ ├── 20200430222500_DisplayName.cs │ │ ├── 20200717143837_Temp password.Designer.cs │ │ ├── 20200717143837_Temp password.cs │ │ ├── 20201204210029_Many-to-many.Designer.cs │ │ ├── 20201204210029_Many-to-many.cs │ │ ├── 20210103153501_WebRtcSetting.Designer.cs │ │ ├── 20210103153501_WebRtcSetting.cs │ │ ├── 20210205114359_IsSponsor property.Designer.cs │ │ ├── 20210205114359_IsSponsor property.cs │ │ ├── 20210205221236_Sponsorship Info.Designer.cs │ │ ├── 20210205221236_Sponsorship Info.cs │ │ ├── 20210206174921_Sponsor Level.Designer.cs │ │ ├── 20210206174921_Sponsor Level.cs │ │ ├── 20210206232808_Branding Info.Designer.cs │ │ ├── 20210206232808_Branding Info.cs │ │ ├── 20210207000327_Rename Branding Props.Designer.cs │ │ ├── 20210207000327_Rename Branding Props.cs │ │ ├── 20210210030737_Change BrandingInfo Id.Designer.cs │ │ ├── 20210210030737_Change BrandingInfo Id.cs │ │ ├── 20210217033350_Remove 3rd Party Services.Designer.cs │ │ ├── 20210217033350_Remove 3rd Party Services.cs │ │ ├── 20210408133020_Add ScriptSchedules.Designer.cs │ │ ├── 20210408133020_Add ScriptSchedules.cs │ │ ├── 20210417155815_Add Alert Details.Designer.cs │ │ ├── 20210417155815_Add Alert Details.cs │ │ ├── 20220827150619_Remove deprecated WebRTC.Designer.cs │ │ ├── 20220827150619_Remove deprecated WebRTC.cs │ │ ├── 20220917171918_Branding fix.Designer.cs │ │ ├── 20220917171918_Branding fix.cs │ │ ├── 20221231192606_Remove RelayCode.Designer.cs │ │ ├── 20221231192606_Remove RelayCode.cs │ │ ├── 20230523215747_Replace DbLogger with Serilog.Designer.cs │ │ ├── 20230523215747_Replace DbLogger with Serilog.cs │ │ ├── 20230622144355_Add_Agent_MacAddress.Designer.cs │ │ ├── 20230622144355_Add_Agent_MacAddress.cs │ │ ├── 20230801210057_Enable_NullableReferences.Designer.cs │ │ ├── 20230801210057_Enable_NullableReferences.cs │ │ ├── 20230821190428_Remove_TitleBranding.Designer.cs │ │ ├── 20230821190428_Remove_TitleBranding.cs │ │ ├── 20240221010154_Add_KeyValueRecords.Designer.cs │ │ ├── 20240221010154_Add_KeyValueRecords.cs │ │ └── SqliteDbContextModelSnapshot.cs ├── Models │ ├── ApiLogin.cs │ ├── ColorPickerModel.cs │ ├── Messages │ │ ├── ChatReceivedMessage.cs │ │ ├── ChatSessionsChangedMessage.cs │ │ ├── DeviceCardStateChangedMessage.cs │ │ ├── DeviceStateChangedMessage.cs │ │ ├── DisplayNotificationMessage.cs │ │ ├── DownloadFileMessage.cs │ │ ├── DownloadFileProgressMessage.cs │ │ ├── PowerShellCompletionsMessage.cs │ │ ├── ReceiveLogsMessage.cs │ │ ├── ScriptResultMessage.cs │ │ ├── ShowLoaderMessage.cs │ │ └── TransferCompleteMessage.cs │ ├── ModalButton.cs │ ├── RemoteControlMode.cs │ ├── RemoteControlRequest.cs │ ├── RemoteControlSession.cs │ ├── SettingsModel.cs │ ├── StreamSignaler.cs │ ├── Toast.cs │ └── ViewerPageTheme.cs ├── Options │ └── ApplicationOptions.cs ├── Pages │ ├── Viewer.cshtml │ └── Viewer.cshtml.cs ├── Program.cs ├── Properties │ ├── AssemblyInfo.cs │ ├── launchSettings.json │ ├── serviceDependencies.json │ └── serviceDependencies.local.json ├── RateLimiting │ └── PolicyNames.cs ├── Server.csproj ├── Services │ ├── AgentHubSessionCache.cs │ ├── AuthService.cs │ ├── CircuitManager.cs │ ├── DataCleanupService.cs │ ├── DataService.cs │ ├── DesktopStreamCache.cs │ ├── EmailSender.cs │ ├── ExpiringTokenService.cs │ ├── JsInterop.cs │ ├── LoaderService.cs │ ├── LogsManager.cs │ ├── ModalService.cs │ ├── OtpProvider.cs │ ├── PascalCasePolicy.cs │ ├── RemoteControlSessionCache.cs │ ├── RemoteControlSessionCleaner.cs │ ├── RemoteControlSessionReconnector.cs │ ├── ScriptScheduleDispatcher.cs │ ├── ScriptScheduler.cs │ ├── SessionRecordingSink.cs │ ├── Stores │ │ ├── ChatSessionStore.cs │ │ ├── SelectedCardsStore.cs │ │ └── TerminalStore.cs │ ├── ThemeProvider.cs │ ├── ToastService.cs │ └── UpgradeService.cs ├── Usings.cs ├── appsettings.json ├── libman.json └── wwwroot │ ├── Content │ ├── Install-MacOS-arm64.sh │ ├── Install-MacOS-x64.sh │ ├── Install-Manjaro-x64.sh │ ├── Install-Remotely.ps1 │ └── Install-Ubuntu-x64.sh │ ├── css │ ├── Themes │ │ ├── darkly.custom.css │ │ ├── darkly.min.css │ │ ├── yeti.custom.css │ │ └── yeti.min.css │ ├── open-iconic │ │ ├── FONT-LICENSE │ │ ├── ICON-LICENSE │ │ ├── README.md │ │ └── font │ │ │ ├── css │ │ │ └── open-iconic-bootstrap.min.css │ │ │ └── fonts │ │ │ ├── open-iconic.eot │ │ │ ├── open-iconic.otf │ │ │ ├── open-iconic.svg │ │ │ ├── open-iconic.ttf │ │ │ └── open-iconic.woff │ ├── remote-control-dark.css │ ├── remote-control-light.css │ ├── remote-control.css │ ├── site.css │ └── site.min.css │ ├── favicon.ico │ ├── images │ ├── DefaultIcon.pdn │ ├── DefaultIcon.png │ ├── DefaultIcon_128.png │ ├── DefaultIcon_512.png │ ├── Remotely_Desktop.png │ ├── Remotely_Icon.pdn │ ├── Remotely_Icon.png │ ├── Remotely_Icon_128.png │ ├── Remotely_Icon_512.png │ ├── Remotely_Icon_Transparent.png │ ├── Remotely_Logo.png │ ├── banner1.svg │ ├── banner2.svg │ ├── banner3.svg │ ├── banner4.svg │ ├── viewer-background-gradient-dark.svg │ └── viewer │ │ ├── remotely-logo-dark.svg │ │ └── remotely-logo-light.svg │ ├── interop.js │ ├── lib │ ├── bootstrap │ │ ├── bootstrap.bundle.min.js │ │ └── bootstrap.bundle.min.js.map │ ├── fontawesome │ │ ├── LICENSE.txt │ │ ├── css │ │ │ ├── all.css │ │ │ ├── all.min.css │ │ │ ├── brands.css │ │ │ ├── brands.min.css │ │ │ ├── fontawesome.css │ │ │ ├── fontawesome.min.css │ │ │ ├── regular.css │ │ │ ├── regular.min.css │ │ │ ├── solid.css │ │ │ ├── solid.min.css │ │ │ ├── svg-with-js.css │ │ │ ├── svg-with-js.min.css │ │ │ ├── v4-font-face.css │ │ │ ├── v4-font-face.min.css │ │ │ ├── v4-shims.css │ │ │ ├── v4-shims.min.css │ │ │ ├── v5-font-face.css │ │ │ └── v5-font-face.min.css │ │ ├── js │ │ │ ├── all.js │ │ │ ├── all.min.js │ │ │ ├── brands.js │ │ │ ├── brands.min.js │ │ │ ├── conflict-detection.js │ │ │ ├── conflict-detection.min.js │ │ │ ├── fontawesome.js │ │ │ ├── fontawesome.min.js │ │ │ ├── regular.js │ │ │ ├── regular.min.js │ │ │ ├── solid.js │ │ │ ├── solid.min.js │ │ │ ├── v4-shims.js │ │ │ └── v4-shims.min.js │ │ ├── sprites │ │ │ ├── brands.svg │ │ │ ├── regular.svg │ │ │ └── solid.svg │ │ └── webfonts │ │ │ ├── fa-brands-400.eot │ │ │ ├── fa-brands-400.svg │ │ │ ├── fa-brands-400.ttf │ │ │ ├── fa-brands-400.woff │ │ │ ├── fa-brands-400.woff2 │ │ │ ├── fa-regular-400.eot │ │ │ ├── fa-regular-400.svg │ │ │ ├── fa-regular-400.ttf │ │ │ ├── fa-regular-400.woff │ │ │ ├── fa-regular-400.woff2 │ │ │ ├── fa-solid-900.eot │ │ │ ├── fa-solid-900.svg │ │ │ ├── fa-solid-900.ttf │ │ │ ├── fa-solid-900.woff │ │ │ ├── fa-solid-900.woff2 │ │ │ ├── fa-v4compatibility.ttf │ │ │ └── fa-v4compatibility.woff2 │ ├── microsoft-signalr │ │ ├── signalr.js │ │ └── signalr.min.js │ ├── microsoft │ │ └── signalr-protocol-msgpack │ │ │ └── dist │ │ │ └── browser │ │ │ ├── signalr-protocol-msgpack.js │ │ │ ├── signalr-protocol-msgpack.js.map │ │ │ ├── signalr-protocol-msgpack.min.js │ │ │ └── signalr-protocol-msgpack.min.js.map │ ├── msgpack │ │ └── dist.es5+umd │ │ │ ├── msgpack.js │ │ │ ├── msgpack.js.map │ │ │ ├── msgpack.min.js │ │ │ └── msgpack.min.js.map │ └── qr │ │ ├── LICENSE │ │ ├── qrcode.js │ │ └── qrcode.min.js │ ├── manifest-rc.json │ ├── manifest.json │ └── src │ ├── App.js │ ├── App.js.map │ ├── App.ts │ ├── CaptureProcessor.js │ ├── CaptureProcessor.js.map │ ├── CaptureProcessor.ts │ ├── ClipboardWatcher.js │ ├── ClipboardWatcher.js.map │ ├── ClipboardWatcher.ts │ ├── DtoChunker.js │ ├── DtoChunker.js.map │ ├── DtoChunker.ts │ ├── DtoMessageHandler.js │ ├── DtoMessageHandler.js.map │ ├── DtoMessageHandler.ts │ ├── Enums │ ├── DtoType.js │ ├── DtoType.js.map │ ├── DtoType.ts │ ├── HubConnectionState.js │ ├── HubConnectionState.js.map │ ├── HubConnectionState.ts │ ├── RemoteControlMode.js │ ├── RemoteControlMode.js.map │ ├── RemoteControlMode.ts │ ├── WindowsSessionType.js │ ├── WindowsSessionType.js.map │ └── WindowsSessionType.ts │ ├── FileTransferService.js │ ├── FileTransferService.js.map │ ├── FileTransferService.ts │ ├── InputEventHandlers.js │ ├── InputEventHandlers.js.map │ ├── InputEventHandlers.ts │ ├── Interfaces │ ├── Dtos.js │ ├── Dtos.js.map │ ├── Dtos.ts │ ├── MessagePack.js │ ├── MessagePack.js.map │ ├── MessagePack.ts │ ├── Settings.js │ ├── Settings.js.map │ └── Settings.ts │ ├── MessageSender.js │ ├── MessageSender.js.map │ ├── MessageSender.ts │ ├── Models │ ├── CursorInfo.js │ ├── CursorInfo.js.map │ ├── CursorInfo.ts │ ├── HubConnection.js │ ├── HubConnection.js.map │ ├── HubConnection.ts │ ├── Point.js │ ├── Point.js.map │ ├── Point.ts │ ├── RemoteControlTarget.js │ ├── RemoteControlTarget.js.map │ ├── RemoteControlTarget.ts │ ├── Result.js │ ├── Result.js.map │ ├── Result.ts │ ├── StreamingState.js │ ├── StreamingState.js.map │ ├── StreamingState.ts │ ├── UserOptions.js │ ├── UserOptions.js.map │ ├── UserOptions.ts │ ├── WindowsSession.js │ ├── WindowsSession.js.map │ └── WindowsSession.ts │ ├── SessionRecorder.js │ ├── SessionRecorder.js.map │ ├── SessionRecorder.ts │ ├── SettingsService.js │ ├── SettingsService.js.map │ ├── SettingsService.ts │ ├── Sound.js │ ├── Sound.js.map │ ├── Sound.ts │ ├── Stream.js │ ├── Stream.js.map │ ├── Stream.ts │ ├── UI.js │ ├── UI.js.map │ ├── UI.ts │ ├── Utilities.js │ ├── Utilities.js.map │ ├── Utilities.ts │ ├── ViewerHubConnection.js │ ├── ViewerHubConnection.js.map │ ├── ViewerHubConnection.ts │ └── tsconfig.json ├── Shared ├── AppConstants.cs ├── Attributes │ └── SortableAttribute.cs ├── DtoEntityBases │ └── ScriptResultBase.cs ├── Dtos │ ├── DeviceClientDto.cs │ ├── ScriptResultDto.cs │ └── ScriptResultResponse.cs ├── Entities │ ├── Alert.cs │ ├── ApiToken.cs │ ├── BrandingInfo.cs │ ├── Device.cs │ ├── DeviceGroup.cs │ ├── InviteLink.cs │ ├── KeyValueRecord.cs │ ├── Organization.cs │ ├── RemotelyUser.cs │ ├── SavedScript.cs │ ├── ScriptResult.cs │ ├── ScriptRun.cs │ ├── ScriptSchedule.cs │ └── SharedFile.cs ├── Enums │ ├── ChatHistoryItemOrigin.cs │ ├── CompletionIntent.cs │ ├── DbProvider.cs │ ├── EventType.cs │ ├── Platform.cs │ ├── PromptForAccessResult.cs │ ├── RepeatInterval.cs │ ├── ScriptInputType.cs │ ├── ScriptingShell.cs │ ├── SessionEndReasonsEx.cs │ ├── SessionSwitchReasonEx.cs │ └── Theme.cs ├── Extensions │ ├── DeviceExtensions.cs │ ├── IEnumerableExtensions.cs │ ├── ILoggerExtensions.cs │ ├── StreamExtensions.cs │ ├── StringExtensions.cs │ └── TaskExtensions.cs ├── Helpers │ ├── Debouncer.cs │ ├── Disposer.cs │ ├── DtoChunker.cs │ ├── PathSanitizer.cs │ ├── RandomGenerator.cs │ ├── RateLImiter.cs │ └── WaitHelper.cs ├── Interfaces │ ├── IAgentHubClient.cs │ ├── IDesktopHubClient.cs │ └── IViewerHubClient.cs ├── Models │ ├── AlertOptions.cs │ ├── ChatMessage.cs │ ├── ConnectionInfo.cs │ ├── CursorInfo.cs │ ├── DeviceSetupOptions.cs │ ├── DisplayInfo.cs │ ├── Drive.cs │ ├── Dtos │ │ ├── AudioSampleDto.cs │ │ ├── ClipboardTextDto.cs │ │ ├── CursorChangeDto.cs │ │ ├── DtoType.cs │ │ ├── DtoWrapper.cs │ │ ├── EmptyDto.cs │ │ ├── FileDto.cs │ │ ├── FrameReceivedDto.cs │ │ ├── KeyDownDto.cs │ │ ├── KeyPressDto.cs │ │ ├── KeyUpDto.cs │ │ ├── MouseDownDto.cs │ │ ├── MouseMoveDto.cs │ │ ├── MouseUpDto.cs │ │ ├── MouseWheelDto.cs │ │ ├── ScreenDataDto.cs │ │ ├── ScreenSizeDto.cs │ │ ├── SelectScreenDto.cs │ │ ├── SessionMetricsDto.cs │ │ ├── TapDto.cs │ │ ├── TextTransferDto.cs │ │ ├── ToggleAudioDto.cs │ │ ├── ToggleBlockInputDto.cs │ │ └── WindowsSessionsDto.cs │ ├── EmbeddedServerData.cs │ ├── PwshCommandCompletion.cs │ ├── RemoteControlAccessRequest.cs │ ├── RemoteControlViewerOptions.cs │ ├── RemotelyUserOptions.cs │ ├── RemotelyUserOptions.cs.d.ts │ ├── ScreenCastRequest.cs │ ├── SentFrame.cs │ └── WindowsSession.cs ├── Primitives │ ├── CallbackDisposable.cs │ ├── CallbackDisposableAsync.cs │ ├── NoopDisposable.cs │ └── Result.cs ├── Services │ ├── ElevationDetectorLinux.cs │ ├── ElevationDetectorMac.cs │ ├── ElevationDetectorWin.cs │ ├── EmbeddedServerDataProvider.cs │ ├── FileLogger.cs │ ├── FileLoggerDefaults.cs │ ├── FileLoggerProvider.cs │ ├── IElevationDetector.cs │ ├── ProcessInvoker.cs │ └── SystemTime.cs ├── Shared.csproj ├── Usings.cs ├── Utilities │ ├── AppVersionHelper.cs │ ├── AppendableStream.cs │ ├── ConsoleHelper.cs │ ├── Debouncer.cs │ ├── Disposer.cs │ ├── EnumMapper.cs │ ├── EnvironmentHelper.cs │ ├── JsonSerializerHelper.cs │ ├── MathHelper.cs │ ├── Time.cs │ └── TimeSpanJsonConverter.cs └── ViewModels │ ├── ChatHistoryItem.cs │ ├── ChatSession.cs │ ├── InviteViewModel.cs │ ├── OrganizationUser.cs │ ├── TerminalLineItem.cs │ └── ViewModelBase.cs ├── Tests ├── Desktop.Win.Tests │ ├── Desktop.Win.Tests.csproj │ ├── ManualTests.cs │ ├── Resources │ │ ├── Image1.jpg │ │ └── Image2.jpg │ └── Usings.cs ├── LoadTester │ ├── CommandLineParser.cs │ ├── LoadTester.csproj │ ├── Program.cs │ └── Properties │ │ └── launchSettings.json ├── Server.Tests │ ├── AgentHubTests.cs │ ├── CircuitConnectionTests.cs │ ├── DataServiceTests.cs │ ├── IoCActivator.cs │ ├── Mocks │ │ └── HubContextFixture.cs │ ├── ScriptScheduleDispatcherTests.cs │ ├── Server.Tests.csproj │ └── TestData.cs └── Shared.Tests │ ├── Shared.Tests.csproj │ ├── StreamExtensionsTests.cs │ └── Usings.cs ├── Utilities ├── Add-Migration.ps1 ├── Example_Apache_Config.txt ├── Example_Nginx_Config.txt ├── Get-CMDCommands.ps1 ├── Get-PSCommands.ps1 ├── Get-WindowsCommands.ps1 ├── Output-PSCommands.ps1 ├── Publish.ps1 ├── Remove-Migration.ps1 ├── Update-Database.ps1 └── signtool.exe └── docker-compose ├── .dockerignore ├── docker-compose.dcproj ├── docker-compose.override.yml ├── docker-compose.yml └── launchSettings.json /.github/ISSUE_TEMPLATE/feature_request.md: -------------------------------------------------------------------------------- 1 | --- 2 | name: Feature request 3 | about: Suggest an idea for this project 4 | title: '' 5 | labels: '' 6 | assignees: '' 7 | 8 | --- 9 | 10 | **Is your feature request related to a problem? Please describe.** 11 | A clear and concise description of what the problem is. Ex. I'm always frustrated when [...] 12 | 13 | **Describe the solution you'd like** 14 | A clear and concise description of what you want to happen. 15 | 16 | **Describe alternatives you've considered** 17 | A clear and concise description of any alternative solutions or features you've considered. 18 | 19 | **Additional context** 20 | Add any other context, mockups or screenshots about the feature request here. 21 | -------------------------------------------------------------------------------- /.github/media/ask-remote.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/immense/Remotely/ec0d45d8f83ee512e60306ce4ddefed6509bd903/.github/media/ask-remote.png -------------------------------------------------------------------------------- /.gitmodules: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/immense/Remotely/ec0d45d8f83ee512e60306ce4ddefed6509bd903/.gitmodules -------------------------------------------------------------------------------- /.vscode/launch.json: -------------------------------------------------------------------------------- 1 | { 2 | // Use IntelliSense to learn about possible attributes. 3 | // Hover to view descriptions of existing attributes. 4 | // For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387 5 | "version": "0.2.0", 6 | "configurations": [ 7 | { 8 | "name": "Linux Desktop", 9 | "type": "coreclr", 10 | "request": "launch", 11 | "preLaunchTask": "build", 12 | "program": "${workspaceFolder}/Desktop.Linux/bin/Debug/.net8.0/Remotely_Desktop.dll", 13 | "args": [], 14 | "cwd": "${workspaceFolder}/Desktop.Linux", 15 | "console": "internalConsole", 16 | "stopAtEntry": false 17 | }, 18 | { 19 | "name": ".NET Core Attach", 20 | "type": "coreclr", 21 | "request": "attach" 22 | } 23 | ] 24 | } -------------------------------------------------------------------------------- /Agent/Assets/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/immense/Remotely/ec0d45d8f83ee512e60306ce4ddefed6509bd903/Agent/Assets/favicon.ico -------------------------------------------------------------------------------- /Agent/Interfaces/IAppLauncher.cs: -------------------------------------------------------------------------------- 1 | using Microsoft.AspNetCore.SignalR.Client; 2 | using System.Threading.Tasks; 3 | 4 | namespace Remotely.Agent.Interfaces; 5 | 6 | public interface IAppLauncher 7 | { 8 | Task LaunchChatService(string pipeName, string userConnectionId, string requesterName, string orgName, string orgId, HubConnection hubConnection); 9 | Task LaunchRemoteControl(int targetSessionId, string sessionId, string accessKey, string userConnectionId, string requesterName, string orgName, string orgId, HubConnection hubConnection); 10 | Task RestartScreenCaster(string[] viewerIds, string sessionId, string accessKey, string userConnectionId, string requesterName, string orgName, string orgId, HubConnection hubConnection, int targetSessionID = -1); 11 | } 12 | -------------------------------------------------------------------------------- /Agent/Interfaces/IDeviceInformationService.cs: -------------------------------------------------------------------------------- 1 | using Remotely.Shared.Dtos; 2 | using System.Threading.Tasks; 3 | 4 | namespace Remotely.Agent.Interfaces; 5 | 6 | public interface IDeviceInformationService 7 | { 8 | Task CreateDevice(string deviceId, string orgId); 9 | } 10 | -------------------------------------------------------------------------------- /Agent/Interfaces/IScriptingShell.cs: -------------------------------------------------------------------------------- 1 | namespace Remotely.Agent.Interfaces; 2 | public interface IScriptingShell 3 | { 4 | bool IsDisposed { get; } 5 | } 6 | -------------------------------------------------------------------------------- /Agent/Interfaces/IUpdater.cs: -------------------------------------------------------------------------------- 1 | using System.Threading.Tasks; 2 | 3 | namespace Remotely.Agent.Interfaces; 4 | 5 | public interface IUpdater 6 | { 7 | Task BeginChecking(); 8 | Task CheckForUpdates(); 9 | Task InstallLatestVersion(); 10 | } -------------------------------------------------------------------------------- /Agent/Models/ChatSession.cs: -------------------------------------------------------------------------------- 1 | using System.IO.Pipes; 2 | 3 | namespace Remotely.Agent.Models; 4 | 5 | public class ChatSession 6 | { 7 | public int ProcessID { get; set; } 8 | public NamedPipeClientStream? PipeStream { get; set; } 9 | } 10 | -------------------------------------------------------------------------------- /Agent/Properties/launchSettings.json: -------------------------------------------------------------------------------- 1 | { 2 | "profiles": { 3 | "Agent": { 4 | "commandName": "Project", 5 | "commandLineArgs": "", 6 | "nativeDebugging": true 7 | } 8 | } 9 | } -------------------------------------------------------------------------------- /Assets/Remotely_Icon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/immense/Remotely/ec0d45d8f83ee512e60306ce4ddefed6509bd903/Assets/Remotely_Icon.ico -------------------------------------------------------------------------------- /Assets/Remotely_Icon.pdn: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/immense/Remotely/ec0d45d8f83ee512e60306ce4ddefed6509bd903/Assets/Remotely_Icon.pdn -------------------------------------------------------------------------------- /Assets/Remotely_Icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/immense/Remotely/ec0d45d8f83ee512e60306ce4ddefed6509bd903/Assets/Remotely_Icon.png -------------------------------------------------------------------------------- /Assets/Remotely_Logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/immense/Remotely/ec0d45d8f83ee512e60306ce4ddefed6509bd903/Assets/Remotely_Logo.png -------------------------------------------------------------------------------- /Desktop.Core/Assets/Remotely_Icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/immense/Remotely/ec0d45d8f83ee512e60306ce4ddefed6509bd903/Desktop.Core/Assets/Remotely_Icon.png -------------------------------------------------------------------------------- /Desktop.Core/Enums/AppMode.cs: -------------------------------------------------------------------------------- 1 | namespace Remotely.Desktop.Core.Enums 2 | { 3 | public enum AppMode 4 | { 5 | Unattended, 6 | Normal, 7 | Chat 8 | } 9 | } 10 | -------------------------------------------------------------------------------- /Desktop.Core/Enums/ButtonAction.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Text; 4 | 5 | namespace Remotely.Desktop.Core.Enums 6 | { 7 | public enum ButtonAction 8 | { 9 | Down, 10 | Up 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /Desktop.Core/Extensions/SKBitmapExtensions.cs: -------------------------------------------------------------------------------- 1 | using Remotely.Shared; 2 | using SkiaSharp; 3 | using System; 4 | using System.Collections.Generic; 5 | using System.Linq; 6 | using System.Text; 7 | using System.Threading.Tasks; 8 | 9 | namespace Remotely.Desktop.Core.Extensions 10 | { 11 | public static class SKBitmapExtensions 12 | { 13 | public static SKRect ToRectangle(this SKBitmap bitmap) 14 | { 15 | return new SKRect(0, 0, bitmap.Width, bitmap.Height); 16 | } 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /Desktop.Core/Interfaces/IAudioCapturer.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | namespace Remotely.Desktop.Core.Interfaces 4 | { 5 | public interface IAudioCapturer 6 | { 7 | event EventHandler AudioSampleReady; 8 | void ToggleAudio(bool toggleOn); 9 | } 10 | } 11 | -------------------------------------------------------------------------------- /Desktop.Core/Interfaces/IChatClientService.cs: -------------------------------------------------------------------------------- 1 | using System.Threading.Tasks; 2 | 3 | namespace Remotely.Desktop.Core.Interfaces 4 | { 5 | public interface IChatClientService 6 | { 7 | Task StartChat(string requesterID, string organizationName); 8 | } 9 | } 10 | -------------------------------------------------------------------------------- /Desktop.Core/Interfaces/IChatUiService.cs: -------------------------------------------------------------------------------- 1 | using Remotely.Shared.Models; 2 | using System; 3 | using System.Collections.Generic; 4 | using System.IO; 5 | using System.IO.Pipes; 6 | using System.Linq; 7 | using System.Text; 8 | using System.Threading.Tasks; 9 | 10 | namespace Remotely.Desktop.Core.Interfaces 11 | { 12 | public interface IChatUiService 13 | { 14 | event EventHandler ChatWindowClosed; 15 | 16 | void ShowChatWindow(string organizationName, StreamWriter writer); 17 | void ReceiveChat(ChatMessage chatMessage); 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /Desktop.Core/Interfaces/IClipboardService.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Threading.Tasks; 3 | 4 | namespace Remotely.Desktop.Core.Interfaces 5 | { 6 | public interface IClipboardService 7 | { 8 | event EventHandler ClipboardTextChanged; 9 | 10 | void BeginWatching(); 11 | 12 | Task SetText(string clipboardText); 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /Desktop.Core/Interfaces/IConfigService.cs: -------------------------------------------------------------------------------- 1 | using Remotely.Shared.Models; 2 | using System; 3 | using System.Collections.Generic; 4 | using System.Linq; 5 | using System.Text; 6 | using System.Threading.Tasks; 7 | 8 | namespace Remotely.Desktop.Core.Interfaces 9 | { 10 | public interface IConfigService 11 | { 12 | DesktopAppConfig GetConfig(); 13 | void Save(DesktopAppConfig config); 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /Desktop.Core/Interfaces/ICursorIconWatcher.cs: -------------------------------------------------------------------------------- 1 | using Remotely.Shared.Models; 2 | using System; 3 | 4 | namespace Remotely.Desktop.Core.Interfaces 5 | { 6 | public interface ICursorIconWatcher 7 | { 8 | event EventHandler OnChange; 9 | 10 | CursorInfo GetCurrentCursor(); 11 | } 12 | 13 | } 14 | -------------------------------------------------------------------------------- /Desktop.Core/Interfaces/IFileTransferService.cs: -------------------------------------------------------------------------------- 1 | using Remotely.Desktop.Core.Services; 2 | using Remotely.Desktop.Core.ViewModels; 3 | using System; 4 | using System.Threading; 5 | using System.Threading.Tasks; 6 | 7 | namespace Remotely.Desktop.Core.Interfaces 8 | { 9 | public interface IFileTransferService 10 | { 11 | string GetBaseDirectory(); 12 | 13 | Task ReceiveFile(byte[] buffer, string fileName, string messageId, bool endOfFile, bool startOfFile); 14 | void OpenFileTransferWindow(Viewer viewer); 15 | Task UploadFile(FileUpload file, Viewer viewer, CancellationToken cancelToken, Action progressUpdateCallback); 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /Desktop.Core/Interfaces/IKeyboardMouseInput.cs: -------------------------------------------------------------------------------- 1 | using Remotely.Desktop.Core.Enums; 2 | using Remotely.Desktop.Core.Services; 3 | 4 | namespace Remotely.Desktop.Core.Interfaces 5 | { 6 | public interface IKeyboardMouseInput 7 | { 8 | void Init(); 9 | void SendKeyDown(string key); 10 | void SendKeyUp(string key); 11 | void SendMouseMove(double percentX, double percentY, Services.Viewer viewer); 12 | void SendMouseWheel(int deltaY); 13 | void SendText(string transferText); 14 | void ToggleBlockInput(bool toggleOn); 15 | void SetKeyStatesUp(); 16 | void SendMouseButtonAction(int button, ButtonAction buttonAction, double percentX, double percentY, Viewer viewer); 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /Desktop.Core/Interfaces/IRemoteControlAccessService.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Text; 4 | using System.Threading.Tasks; 5 | 6 | namespace Remotely.Desktop.Core.Interfaces 7 | { 8 | public interface IRemoteControlAccessService 9 | { 10 | Task PromptForAccess(string requesterName, string organizationName); 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /Desktop.Core/Interfaces/IScreenCapturer.cs: -------------------------------------------------------------------------------- 1 | using Remotely.Shared; 2 | using SkiaSharp; 3 | using System; 4 | using System.Collections.Generic; 5 | using System.Drawing; 6 | 7 | namespace Remotely.Desktop.Core.Interfaces 8 | { 9 | public interface IScreenCapturer : IDisposable 10 | { 11 | event EventHandler ScreenChanged; 12 | 13 | bool CaptureFullscreen { get; set; } 14 | Rectangle CurrentScreenBounds { get; } 15 | string SelectedScreen { get; } 16 | 17 | IEnumerable GetDisplayNames(); 18 | SKRect GetFrameDiffArea(); 19 | 20 | Result GetImageDiff(); 21 | 22 | Result GetNextFrame(); 23 | 24 | int GetScreenCount(); 25 | 26 | int GetSelectedScreenIndex(); 27 | Rectangle GetVirtualScreenBounds(); 28 | 29 | void Init(); 30 | 31 | void SetSelectedScreen(string displayName); 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /Desktop.Core/Interfaces/ISessionIndicator.cs: -------------------------------------------------------------------------------- 1 | namespace Remotely.Desktop.Core.Interfaces 2 | { 3 | public interface ISessionIndicator 4 | { 5 | void Show(); 6 | } 7 | } 8 | -------------------------------------------------------------------------------- /Desktop.Core/Interfaces/IShutdownService.cs: -------------------------------------------------------------------------------- 1 | using System.Threading.Tasks; 2 | 3 | namespace Remotely.Desktop.Core.Interfaces 4 | { 5 | public interface IShutdownService 6 | { 7 | Task Shutdown(); 8 | } 9 | } 10 | -------------------------------------------------------------------------------- /Desktop.Core/Models/CaptureFrame.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Text; 5 | using System.Threading.Tasks; 6 | 7 | namespace Remotely.Desktop.Core.Models 8 | { 9 | public class CaptureFrame 10 | { 11 | public byte[] EncodedImageBytes { get; init; } 12 | public Guid Id { get; } = Guid.NewGuid(); 13 | public int Top { get; init; } 14 | public int Left { get; init; } 15 | public int Height { get; init; } 16 | public int Width { get; init; } 17 | public long Sequence { get; init; } 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /Desktop.Core/ServiceContainer.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | namespace Remotely.Desktop.Core 4 | { 5 | public class ServiceContainer 6 | { 7 | public static IServiceProvider Instance { get; set; } 8 | } 9 | } 10 | -------------------------------------------------------------------------------- /Desktop.Core/ViewModels/ViewModelBase.cs: -------------------------------------------------------------------------------- 1 | using System.ComponentModel; 2 | using System.Runtime.CompilerServices; 3 | 4 | namespace Remotely.Desktop.Core.ViewModels 5 | { 6 | public class ViewModelBase : INotifyPropertyChanged 7 | { 8 | public event PropertyChangedEventHandler PropertyChanged; 9 | 10 | public void FirePropertyChanged([CallerMemberName]string propertyName = "") 11 | { 12 | PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName)); 13 | } 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /Desktop.Linux/Assets/Remotely_Icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/immense/Remotely/ec0d45d8f83ee512e60306ce4ddefed6509bd903/Desktop.Linux/Assets/Remotely_Icon.png -------------------------------------------------------------------------------- /Desktop.Linux/Assets/avalonia-logo.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/immense/Remotely/ec0d45d8f83ee512e60306ce4ddefed6509bd903/Desktop.Linux/Assets/avalonia-logo.ico -------------------------------------------------------------------------------- /Desktop.Linux/Assets/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/immense/Remotely/ec0d45d8f83ee512e60306ce4ddefed6509bd903/Desktop.Linux/Assets/favicon.ico -------------------------------------------------------------------------------- /Desktop.Linux/Properties/PublishProfiles/desktop-linux-x64.pubxml: -------------------------------------------------------------------------------- 1 |  2 | 5 | 6 | 7 | FileSystem 8 | Release 9 | x64 10 | net8.0 11 | ..\Server\wwwroot\Content\Linux-x64\ 12 | linux-x64 13 | true 14 | True 15 | False 16 | true 17 | true 18 | 19 | -------------------------------------------------------------------------------- /Desktop.Linux/Properties/PublishProfiles/packaged-linux-x64.pubxml: -------------------------------------------------------------------------------- 1 |  2 | 5 | 6 | 7 | FileSystem 8 | Release 9 | x64 10 | net8.0 11 | ..\Agent\bin\publish\linux-x64\Desktop 12 | linux-x64 13 | true 14 | False 15 | False 16 | 17 | -------------------------------------------------------------------------------- /Desktop.Linux/Properties/launchSettings.json: -------------------------------------------------------------------------------- 1 | { 2 | "profiles": { 3 | "Desktop.Linux": { 4 | "commandName": "Project", 5 | "commandLineArgs": "-m Attended -h https://localhost:5001" 6 | } 7 | } 8 | } -------------------------------------------------------------------------------- /Desktop.Linux/Services/AudioCapturerLinux.cs: -------------------------------------------------------------------------------- 1 | using Remotely.Desktop.Shared.Abstractions; 2 | 3 | namespace Remotely.Desktop.Linux.Services; 4 | 5 | public class AudioCapturerLinux : IAudioCapturer 6 | { 7 | #pragma warning disable CS0067 8 | public event EventHandler? AudioSampleReady; 9 | #pragma warning restore 10 | 11 | public void ToggleAudio(bool toggleOn) 12 | { 13 | // Not implemented. 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /Desktop.Linux/Services/CursorIconWatcherLinux.cs: -------------------------------------------------------------------------------- 1 | using Remotely.Desktop.Shared.Abstractions; 2 | using Remotely.Shared.Models; 3 | using System.Drawing; 4 | 5 | namespace Remotely.Desktop.Linux.Services; 6 | 7 | public class CursorIconWatcherLinux : ICursorIconWatcher 8 | { 9 | #pragma warning disable CS0067 10 | public event EventHandler? OnChange; 11 | #pragma warning restore 12 | 13 | 14 | public CursorInfo GetCurrentCursor() => new(Array.Empty(), Point.Empty, "default"); 15 | } 16 | -------------------------------------------------------------------------------- /Desktop.Linux/Usings.cs: -------------------------------------------------------------------------------- 1 | global using System; 2 | global using System.Collections.Generic; 3 | global using System.Linq; 4 | global using System.Threading.Tasks; 5 | -------------------------------------------------------------------------------- /Desktop.Linux/nuget.config: -------------------------------------------------------------------------------- 1 | 2 | 3 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | -------------------------------------------------------------------------------- /Desktop.Native/Desktop.Native.csproj: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | net8.0 5 | enable 6 | enable 7 | True 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | -------------------------------------------------------------------------------- /Desktop.Native/Linux/LibXtst.cs: -------------------------------------------------------------------------------- 1 | using System.Runtime.InteropServices; 2 | 3 | namespace Remotely.Desktop.Native.Linux; 4 | 5 | public class LibXtst 6 | { 7 | [DllImport("libXtst")] 8 | public static extern bool XTestQueryExtension(nint display, out int event_base, out int error_base, out int major_version, out int minor_version); 9 | [DllImport("libXtst")] 10 | public static extern void XTestFakeKeyEvent(nint display, uint keycode, bool is_press, ulong delay); 11 | [DllImport("libXtst")] 12 | public static extern void XTestFakeButtonEvent(nint display, uint button, bool is_press, ulong delay); 13 | [DllImport("libXtst")] 14 | public static extern void XTestFakeMotionEvent(nint display, int screen_number, int x, int y, ulong delay); 15 | } 16 | -------------------------------------------------------------------------------- /Desktop.Native/Linux/Libc.cs: -------------------------------------------------------------------------------- 1 | using System.Runtime.InteropServices; 2 | 3 | namespace Remotely.Desktop.Native.Linux; 4 | 5 | public class Libc 6 | { 7 | [DllImport("libc", SetLastError = true)] 8 | public static extern uint geteuid(); 9 | } 10 | -------------------------------------------------------------------------------- /Desktop.Shared/Abstractions/IAppStartup.cs: -------------------------------------------------------------------------------- 1 | namespace Remotely.Desktop.Shared.Abstractions; 2 | 3 | public interface IAppStartup 4 | { 5 | Task Run(); 6 | } 7 | -------------------------------------------------------------------------------- /Desktop.Shared/Abstractions/IAudioCapturer.cs: -------------------------------------------------------------------------------- 1 | namespace Remotely.Desktop.Shared.Abstractions; 2 | 3 | public interface IAudioCapturer 4 | { 5 | event EventHandler AudioSampleReady; 6 | void ToggleAudio(bool toggleOn); 7 | } 8 | -------------------------------------------------------------------------------- /Desktop.Shared/Abstractions/IChatUiService.cs: -------------------------------------------------------------------------------- 1 | using Remotely.Shared.Models; 2 | 3 | namespace Remotely.Desktop.Shared.Abstractions; 4 | 5 | public interface IChatUiService 6 | { 7 | event EventHandler ChatWindowClosed; 8 | 9 | void ShowChatWindow(string organizationName, StreamWriter writer); 10 | Task ReceiveChat(ChatMessage chatMessage); 11 | } 12 | -------------------------------------------------------------------------------- /Desktop.Shared/Abstractions/IClipboardService.cs: -------------------------------------------------------------------------------- 1 | namespace Remotely.Desktop.Shared.Abstractions; 2 | 3 | public interface IClipboardService 4 | { 5 | event EventHandler ClipboardTextChanged; 6 | 7 | void BeginWatching(); 8 | 9 | Task SetText(string clipboardText); 10 | } 11 | -------------------------------------------------------------------------------- /Desktop.Shared/Abstractions/ICursorIconWatcher.cs: -------------------------------------------------------------------------------- 1 | using Remotely.Shared.Models; 2 | 3 | namespace Remotely.Desktop.Shared.Abstractions; 4 | 5 | public interface ICursorIconWatcher 6 | { 7 | [Obsolete("This should be replaced with a message published by IMessenger.")] 8 | event EventHandler OnChange; 9 | 10 | CursorInfo GetCurrentCursor(); 11 | } 12 | -------------------------------------------------------------------------------- /Desktop.Shared/Abstractions/IFileTransferService.cs: -------------------------------------------------------------------------------- 1 | using Remotely.Desktop.Shared.Services; 2 | using Remotely.Desktop.Shared.ViewModels; 3 | 4 | namespace Remotely.Desktop.Shared.Abstractions; 5 | 6 | public interface IFileTransferService 7 | { 8 | string GetBaseDirectory(); 9 | 10 | Task ReceiveFile(byte[] buffer, string fileName, string messageId, bool endOfFile, bool startOfFile); 11 | void OpenFileTransferWindow(IViewer viewer); 12 | Task UploadFile(FileUpload file, IViewer viewer, Action progressUpdateCallback, CancellationToken cancelToken); 13 | } 14 | -------------------------------------------------------------------------------- /Desktop.Shared/Abstractions/IKeyboardMouseInput.cs: -------------------------------------------------------------------------------- 1 | using Remotely.Desktop.Shared.Enums; 2 | using Remotely.Desktop.Shared.Services; 3 | 4 | namespace Remotely.Desktop.Shared.Abstractions; 5 | 6 | public interface IKeyboardMouseInput 7 | { 8 | void Init(); 9 | void SendKeyDown(string key); 10 | void SendKeyUp(string key); 11 | void SendMouseMove(double percentX, double percentY, IViewer viewer); 12 | void SendMouseWheel(int deltaY); 13 | void SendText(string transferText); 14 | void ToggleBlockInput(bool toggleOn); 15 | void SetKeyStatesUp(); 16 | void SendMouseButtonAction(int button, ButtonAction buttonAction, double percentX, double percentY, IViewer viewer); 17 | } 18 | -------------------------------------------------------------------------------- /Desktop.Shared/Abstractions/IRemoteControlAccessService.cs: -------------------------------------------------------------------------------- 1 | using Remotely.Shared.Enums; 2 | 3 | namespace Remotely.Desktop.Shared.Abstractions; 4 | 5 | public interface IRemoteControlAccessService 6 | { 7 | bool IsPromptOpen { get; } 8 | 9 | Task PromptForAccess(string requesterName, string organizationName); 10 | } 11 | -------------------------------------------------------------------------------- /Desktop.Shared/Abstractions/IScreenCapturer.cs: -------------------------------------------------------------------------------- 1 | using Remotely.Shared.Primitives; 2 | using SkiaSharp; 3 | using System.Drawing; 4 | 5 | namespace Remotely.Desktop.Shared.Abstractions; 6 | 7 | public interface IScreenCapturer : IDisposable 8 | { 9 | event EventHandler ScreenChanged; 10 | 11 | bool CaptureFullscreen { get; set; } 12 | Rectangle CurrentScreenBounds { get; } 13 | bool IsGpuAccelerated { get; } 14 | string SelectedScreen { get; } 15 | IEnumerable GetDisplayNames(); 16 | SKRect GetFrameDiffArea(); 17 | 18 | Result GetImageDiff(); 19 | 20 | Result GetNextFrame(); 21 | 22 | int GetScreenCount(); 23 | 24 | Rectangle GetVirtualScreenBounds(); 25 | 26 | void Init(); 27 | 28 | void SetSelectedScreen(string displayName); 29 | } 30 | -------------------------------------------------------------------------------- /Desktop.Shared/Abstractions/ISessionIndicator.cs: -------------------------------------------------------------------------------- 1 | namespace Remotely.Desktop.Shared.Abstractions; 2 | 3 | public interface ISessionIndicator 4 | { 5 | void Show(); 6 | } 7 | -------------------------------------------------------------------------------- /Desktop.Shared/Abstractions/IShutdownService.cs: -------------------------------------------------------------------------------- 1 | namespace Remotely.Desktop.Shared.Abstractions; 2 | 3 | public interface IShutdownService 4 | { 5 | Task Shutdown(); 6 | } 7 | -------------------------------------------------------------------------------- /Desktop.Shared/Assets/DefaultIcon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/immense/Remotely/ec0d45d8f83ee512e60306ce4ddefed6509bd903/Desktop.Shared/Assets/DefaultIcon.ico -------------------------------------------------------------------------------- /Desktop.Shared/Assets/DefaultIcon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/immense/Remotely/ec0d45d8f83ee512e60306ce4ddefed6509bd903/Desktop.Shared/Assets/DefaultIcon.png -------------------------------------------------------------------------------- /Desktop.Shared/Assets/Remotely_Icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/immense/Remotely/ec0d45d8f83ee512e60306ce4ddefed6509bd903/Desktop.Shared/Assets/Remotely_Icon.png -------------------------------------------------------------------------------- /Desktop.Shared/Assets/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/immense/Remotely/ec0d45d8f83ee512e60306ce4ddefed6509bd903/Desktop.Shared/Assets/favicon.ico -------------------------------------------------------------------------------- /Desktop.Shared/Enums/AppMode.cs: -------------------------------------------------------------------------------- 1 | namespace Remotely.Desktop.Shared.Enums; 2 | 3 | public enum AppMode 4 | { 5 | Unattended, 6 | Attended, 7 | Chat 8 | } 9 | -------------------------------------------------------------------------------- /Desktop.Shared/Enums/ButtonAction.cs: -------------------------------------------------------------------------------- 1 | namespace Remotely.Desktop.Shared.Enums; 2 | 3 | public enum ButtonAction 4 | { 5 | Down, 6 | Up 7 | } 8 | -------------------------------------------------------------------------------- /Desktop.Shared/Extensions/SKBitmapExtensions.cs: -------------------------------------------------------------------------------- 1 | using SkiaSharp; 2 | 3 | namespace Remotely.Desktop.Shared.Extensions; 4 | 5 | public static class SKBitmapExtensions 6 | { 7 | public static SKRect ToRectangle(this SKBitmap bitmap) 8 | { 9 | return new SKRect(0, 0, bitmap.Width, bitmap.Height); 10 | } 11 | } 12 | -------------------------------------------------------------------------------- /Desktop.Shared/Messages/AppStateHostChangedMessage.cs: -------------------------------------------------------------------------------- 1 | namespace Remotely.Desktop.Shared.Messages; 2 | 3 | public class AppStateHostChangedMessage 4 | { 5 | public AppStateHostChangedMessage(string newHost) 6 | { 7 | NewHost = newHost; 8 | } 9 | 10 | public string NewHost { get; } 11 | } 12 | -------------------------------------------------------------------------------- /Desktop.Shared/Messages/DisplaySettingsChangedMessage.cs: -------------------------------------------------------------------------------- 1 | namespace Remotely.Desktop.Shared.Messages; 2 | public record DisplaySettingsChangedMessage(); 3 | -------------------------------------------------------------------------------- /Desktop.Shared/Messages/WindowsSessionEndingMessage.cs: -------------------------------------------------------------------------------- 1 | using Remotely.Shared.Enums; 2 | 3 | namespace Remotely.Desktop.Shared.Messages; 4 | 5 | public class WindowsSessionEndingMessage 6 | { 7 | public WindowsSessionEndingMessage(SessionEndReasonsEx reason) 8 | { 9 | Reason = reason; 10 | } 11 | 12 | public SessionEndReasonsEx Reason { get; } 13 | } 14 | -------------------------------------------------------------------------------- /Desktop.Shared/Messages/WindowsSessionSwitchedMessage.cs: -------------------------------------------------------------------------------- 1 | using Remotely.Shared.Enums; 2 | 3 | namespace Remotely.Desktop.Shared.Messages; 4 | 5 | public class WindowsSessionSwitchedMessage 6 | { 7 | public WindowsSessionSwitchedMessage(SessionSwitchReasonEx reason, int sessionId) 8 | { 9 | Reason = reason; 10 | SessionId = sessionId; 11 | } 12 | 13 | public SessionSwitchReasonEx Reason { get; } 14 | public int SessionId { get; } 15 | } 16 | -------------------------------------------------------------------------------- /Desktop.Shared/Properties/AssemblyInfo.cs: -------------------------------------------------------------------------------- 1 | using System.Runtime.CompilerServices; 2 | 3 | [assembly: InternalsVisibleTo("Remotely_Desktop")] -------------------------------------------------------------------------------- /Desktop.Shared/StaticServiceProvider.cs: -------------------------------------------------------------------------------- 1 | namespace Remotely.Desktop.Shared; 2 | 3 | public static class StaticServiceProvider 4 | { 5 | public static IServiceProvider? Instance { get; set; } 6 | } 7 | -------------------------------------------------------------------------------- /Desktop.Shared/ViewModels/FileUpload.cs: -------------------------------------------------------------------------------- 1 | using Remotely.Desktop.Shared.Reactive; 2 | 3 | namespace Remotely.Desktop.Shared.ViewModels; 4 | 5 | public partial class FileUpload : ObservableObject 6 | { 7 | public string FilePath 8 | { 9 | get => Get(defaultValue: string.Empty); 10 | set => Set(value); 11 | } 12 | 13 | 14 | public double PercentProgress 15 | { 16 | get => Get(); 17 | set => Set(value); 18 | } 19 | 20 | public CancellationTokenSource CancellationTokenSource { get; } = new CancellationTokenSource(); 21 | 22 | public string DisplayName => Path.GetFileName(FilePath); 23 | } 24 | -------------------------------------------------------------------------------- /Desktop.UI/Assets/DefaultIcon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/immense/Remotely/ec0d45d8f83ee512e60306ce4ddefed6509bd903/Desktop.UI/Assets/DefaultIcon.ico -------------------------------------------------------------------------------- /Desktop.UI/Assets/DefaultIcon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/immense/Remotely/ec0d45d8f83ee512e60306ce4ddefed6509bd903/Desktop.UI/Assets/DefaultIcon.png -------------------------------------------------------------------------------- /Desktop.UI/Assets/Gear.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/immense/Remotely/ec0d45d8f83ee512e60306ce4ddefed6509bd903/Desktop.UI/Assets/Gear.png -------------------------------------------------------------------------------- /Desktop.UI/Assets/avalonia-logo.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/immense/Remotely/ec0d45d8f83ee512e60306ce4ddefed6509bd903/Desktop.UI/Assets/avalonia-logo.ico -------------------------------------------------------------------------------- /Desktop.UI/Controls/Dialogs/MessageBoxResult.cs: -------------------------------------------------------------------------------- 1 | namespace Remotely.Desktop.UI.Controls.Dialogs; 2 | 3 | public enum MessageBoxResult 4 | { 5 | Cancel, 6 | OK, 7 | Yes, 8 | No 9 | } 10 | -------------------------------------------------------------------------------- /Desktop.UI/Controls/Dialogs/MessageBoxType.cs: -------------------------------------------------------------------------------- 1 | namespace Remotely.Desktop.UI.Controls.Dialogs; 2 | 3 | public enum MessageBoxType 4 | { 5 | OK, 6 | YesNo 7 | } 8 | -------------------------------------------------------------------------------- /Desktop.UI/GlobalUsings.cs: -------------------------------------------------------------------------------- 1 | global using System; 2 | global using System.IO; 3 | global using System.Collections.Generic; 4 | global using System.Linq; 5 | global using System.Threading.Tasks; 6 | global using Remotely.Desktop.UI.Services; 7 | global using Remotely.Desktop.UI.ViewModels; 8 | global using Remotely.Desktop.UI.Views; -------------------------------------------------------------------------------- /Desktop.UI/Services/DialogProvider.cs: -------------------------------------------------------------------------------- 1 | using Remotely.Desktop.UI.Controls.Dialogs; 2 | 3 | namespace Remotely.Desktop.UI.Services; 4 | 5 | public interface IDialogProvider 6 | { 7 | Task Show(string message, string caption, MessageBoxType type); 8 | } 9 | 10 | internal class DialogProvider : IDialogProvider 11 | { 12 | public async Task Show(string message, string caption, MessageBoxType type) 13 | { 14 | return await MessageBox.Show(message, caption, type); 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /Desktop.UI/Services/SessionIndicator.cs: -------------------------------------------------------------------------------- 1 | using Remotely.Desktop.Shared; 2 | using Remotely.Desktop.Shared.Abstractions; 3 | using Microsoft.Extensions.DependencyInjection; 4 | 5 | namespace Remotely.Desktop.UI.Services; 6 | 7 | public class SessionIndicator : ISessionIndicator 8 | { 9 | private readonly IUiDispatcher _dispatcher; 10 | 11 | public SessionIndicator(IUiDispatcher dispatcher) 12 | { 13 | _dispatcher = dispatcher; 14 | } 15 | public void Show() 16 | { 17 | _dispatcher.Post(() => 18 | { 19 | var indicatorWindow = new SessionIndicatorWindow() 20 | { 21 | DataContext = StaticServiceProvider.Instance?.GetRequiredService() 22 | }; 23 | _dispatcher.ShowMainWindow(indicatorWindow); 24 | }); 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /Desktop.UI/ViewModels/Fakes/FakeHostNamePromptViewModel.cs: -------------------------------------------------------------------------------- 1 | using Remotely.Desktop.Shared.Reactive; 2 | using System.Windows.Input; 3 | 4 | namespace Remotely.Desktop.UI.ViewModels.Fakes; 5 | 6 | public class FakeHostNamePromptViewModel : FakeBrandedViewModelBase, IHostNamePromptViewModel 7 | { 8 | public string Host { get; set; } = "https://localhost:7024"; 9 | 10 | public ICommand OKCommand => new RelayCommand(() => { }); 11 | } 12 | -------------------------------------------------------------------------------- /Desktop.UI/ViewModels/Fakes/FakeMainWindowViewModel.cs: -------------------------------------------------------------------------------- 1 | namespace Remotely.Desktop.UI.ViewModels.Fakes; 2 | 3 | public class FakeMainWindowViewModel : FakeBrandedViewModelBase, IMainWindowViewModel 4 | { 5 | } 6 | -------------------------------------------------------------------------------- /Desktop.UI/ViewModels/Fakes/FakeMessageBoxViewModel.cs: -------------------------------------------------------------------------------- 1 | using Remotely.Desktop.Shared.Reactive; 2 | using System.Windows.Input; 3 | using Remotely.Desktop.UI.Controls.Dialogs; 4 | 5 | namespace Remotely.Desktop.UI.ViewModels.Fakes; 6 | 7 | public class FakeMessageBoxViewModel : FakeBrandedViewModelBase, IMessageBoxViewModel 8 | { 9 | public bool AreYesNoButtonsVisible { get; set; } = true; 10 | public string Caption { get; set; } = "Test Caption"; 11 | public bool IsOkButtonVisible { get; set; } = false; 12 | public string Message { get; set; } = "This is a test message."; 13 | 14 | public ICommand NoCommand => new RelayCommand(() => { }); 15 | 16 | public ICommand OKCommand => new RelayCommand(() => { }); 17 | 18 | public MessageBoxResult Result { get; set; } = MessageBoxResult.Yes; 19 | 20 | public ICommand YesCommand => new RelayCommand(() => { }); 21 | } 22 | -------------------------------------------------------------------------------- /Desktop.UI/ViewModels/Fakes/FakePromptForAccessViewModel.cs: -------------------------------------------------------------------------------- 1 | using Remotely.Desktop.Shared.Reactive; 2 | using System.Windows.Input; 3 | 4 | namespace Remotely.Desktop.UI.ViewModels.Fakes; 5 | 6 | public class FakePromptForAccessViewModel : FakeBrandedViewModelBase, IPromptForAccessWindowViewModel 7 | { 8 | public string OrganizationName { get; set; } = "Test Organization"; 9 | public bool PromptResult { get; set; } 10 | public string RequesterName { get; set; } = "Test Requester"; 11 | 12 | 13 | 14 | public ICommand CloseCommand => new RelayCommand(() => { }); 15 | 16 | public ICommand MinimizeCommand => new RelayCommand(() => { }); 17 | 18 | public string RequestMessage => "Test request message"; 19 | 20 | public ICommand SetResultNo => new RelayCommand(() => { }); 21 | 22 | public ICommand SetResultYes => new RelayCommand(() => { }); 23 | } 24 | -------------------------------------------------------------------------------- /Desktop.UI/ViewModels/Fakes/FakeSessionIndicatorWindowViewModel.cs: -------------------------------------------------------------------------------- 1 | namespace Remotely.Desktop.UI.ViewModels.Fakes; 2 | internal class FakeSessionIndicatorWindowViewModel : FakeBrandedViewModelBase, ISessionIndicatorWindowViewModel 3 | { 4 | public Task PromptForExit() 5 | { 6 | return Task.CompletedTask; 7 | } 8 | } 9 | -------------------------------------------------------------------------------- /Desktop.UI/ViewModels/MainWindowViewModel.cs: -------------------------------------------------------------------------------- 1 | using Microsoft.Extensions.Logging; 2 | using Remotely.Desktop.Shared.Services; 3 | 4 | namespace Remotely.Desktop.UI.ViewModels; 5 | 6 | public interface IMainWindowViewModel : IBrandedViewModelBase 7 | { 8 | } 9 | 10 | public class MainWindowViewModel : BrandedViewModelBase, IMainWindowViewModel 11 | { 12 | public MainWindowViewModel( 13 | IBrandingProvider brandingProvider, 14 | IUiDispatcher dispatcher, 15 | ILogger logger) 16 | : base(brandingProvider, dispatcher, logger) 17 | { 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /Desktop.UI/Views/FileTransferWindow.axaml.cs: -------------------------------------------------------------------------------- 1 | using Avalonia; 2 | using Avalonia.Controls; 3 | 4 | namespace Remotely.Desktop.UI.Views; 5 | 6 | public partial class FileTransferWindow : Window 7 | { 8 | public FileTransferWindow() 9 | { 10 | InitializeComponent(); 11 | Opened += FileTransferWindow_Opened; 12 | } 13 | 14 | public IFileTransferWindowViewModel? ViewModel => DataContext as IFileTransferWindowViewModel; 15 | 16 | private void FileTransferWindow_Opened(object? sender, EventArgs e) 17 | { 18 | Topmost = false; 19 | 20 | if (Screens.Primary is not null) 21 | { 22 | var left = Screens.Primary.WorkingArea.Right - FrameSize?.Width ?? Width; 23 | var top = Screens.Primary.WorkingArea.Bottom - FrameSize?.Height ?? Height; 24 | Position = new PixelPoint((int)left, (int)top); 25 | } 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /Desktop.UI/Views/HostNamePrompt.axaml.cs: -------------------------------------------------------------------------------- 1 | using Avalonia.Controls; 2 | 3 | namespace Remotely.Desktop.UI.Views; 4 | 5 | public partial class HostNamePrompt : Window 6 | { 7 | public HostNamePrompt() 8 | { 9 | InitializeComponent(); 10 | } 11 | 12 | public HostNamePromptViewModel? ViewModel => DataContext as HostNamePromptViewModel; 13 | } 14 | -------------------------------------------------------------------------------- /Desktop.UI/Views/MainWindow.axaml: -------------------------------------------------------------------------------- 1 | 14 | 15 | 16 | 17 | -------------------------------------------------------------------------------- /Desktop.UI/Views/MainWindow.axaml.cs: -------------------------------------------------------------------------------- 1 | using Avalonia.Controls; 2 | using Avalonia.Markup.Xaml; 3 | using Remotely.Desktop.Shared; 4 | using Microsoft.Extensions.DependencyInjection; 5 | 6 | namespace Remotely.Desktop.UI.Views; 7 | 8 | public partial class MainWindow : Window 9 | { 10 | public MainWindow() 11 | { 12 | if (!Design.IsDesignMode) 13 | { 14 | DataContext = StaticServiceProvider.Instance?.GetService(); 15 | } 16 | 17 | InitializeComponent(); 18 | Closed += MainWindow_Closed; 19 | } 20 | 21 | private void MainWindow_Closed(object? sender, EventArgs e) 22 | { 23 | var dispatcher = StaticServiceProvider.Instance?.GetService(); 24 | dispatcher?.Shutdown(); 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /Desktop.UI/Views/PromptForAccessWindow.axaml.cs: -------------------------------------------------------------------------------- 1 | using Avalonia.Controls; 2 | using Avalonia.Interactivity; 3 | 4 | namespace Remotely.Desktop.UI.Views; 5 | 6 | public partial class PromptForAccessWindow : Window 7 | { 8 | public PromptForAccessWindow() 9 | { 10 | InitializeComponent(); 11 | Loaded += Window_Loaded; 12 | } 13 | 14 | private void Window_Loaded(object? sender, RoutedEventArgs e) 15 | { 16 | Topmost = false; 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /Desktop.Win/Assets/Remotely_Icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/immense/Remotely/ec0d45d8f83ee512e60306ce4ddefed6509bd903/Desktop.Win/Assets/Remotely_Icon.png -------------------------------------------------------------------------------- /Desktop.Win/Assets/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/immense/Remotely/ec0d45d8f83ee512e60306ce4ddefed6509bd903/Desktop.Win/Assets/favicon.ico -------------------------------------------------------------------------------- /Desktop.Win/Properties/AssemblyInfo.cs: -------------------------------------------------------------------------------- 1 | using System.Runtime.CompilerServices; 2 | 3 | [assembly: InternalsVisibleTo("Remotely.Desktop.Win.Tests")] -------------------------------------------------------------------------------- /Desktop.Win/Properties/PublishProfiles/desktop-win-x64.pubxml: -------------------------------------------------------------------------------- 1 |  2 | 5 | 6 | 7 | FileSystem 8 | Release 9 | x64 10 | net8.0-windows 11 | ..\Server\wwwroot\Content\Win-x64\ 12 | win-x64 13 | true 14 | true 15 | false 16 | false 17 | true 18 | true 19 | 20 | -------------------------------------------------------------------------------- /Desktop.Win/Properties/PublishProfiles/desktop-win-x86.pubxml: -------------------------------------------------------------------------------- 1 |  2 | 5 | 6 | 7 | FileSystem 8 | Release 9 | x86 10 | net8.0-windows 11 | ..\Server\wwwroot\Content\Win-x86\ 12 | win-x86 13 | true 14 | True 15 | False 16 | False 17 | true 18 | true 19 | 20 | -------------------------------------------------------------------------------- /Desktop.Win/Properties/PublishProfiles/install-folder.pubxml: -------------------------------------------------------------------------------- 1 |  2 | 5 | 6 | 7 | Release 8 | x64 9 | C:\Program Files\Remotely\Desktop 10 | FileSystem 11 | net8.0 12 | win-x64 13 | true 14 | False 15 | False 16 | False 17 | 18 | -------------------------------------------------------------------------------- /Desktop.Win/Properties/PublishProfiles/packaged-win-x64-debug.pubxml: -------------------------------------------------------------------------------- 1 |  2 | 5 | 6 | 7 | FileSystem 8 | Debug 9 | x64 10 | net8.0-windows 11 | ..\Agent\bin\publish\win-x64\Desktop 12 | true 13 | win-x64 14 | True 15 | False 16 | False 17 | 18 | -------------------------------------------------------------------------------- /Desktop.Win/Properties/PublishProfiles/packaged-win-x64.pubxml: -------------------------------------------------------------------------------- 1 |  2 | 5 | 6 | 7 | FileSystem 8 | Release 9 | x64 10 | net8.0-windows 11 | ..\Agent\bin\publish\win-x64\Desktop 12 | true 13 | win-x64 14 | false 15 | false 16 | false 17 | 18 | -------------------------------------------------------------------------------- /Desktop.Win/Properties/PublishProfiles/packaged-win-x86.pubxml: -------------------------------------------------------------------------------- 1 |  2 | 5 | 6 | 7 | FileSystem 8 | Release 9 | x86 10 | net8.0-windows 11 | ..\Agent\bin\publish\win-x86\Desktop 12 | win-x86 13 | true 14 | False 15 | False 16 | False 17 | 18 | -------------------------------------------------------------------------------- /Desktop.Win/Properties/launchSettings.json: -------------------------------------------------------------------------------- 1 | { 2 | "profiles": { 3 | "Desktop.Win": { 4 | "commandName": "Project", 5 | "commandLineArgs": "-m Attended -h https://localhost:5001" 6 | } 7 | } 8 | } -------------------------------------------------------------------------------- /Desktop.Win/Usings.cs: -------------------------------------------------------------------------------- 1 | global using System; 2 | global using System.Collections.Generic; 3 | global using System.Linq; 4 | global using System.Threading; 5 | global using System.Threading.Tasks; 6 | global using Microsoft.Extensions.Logging; -------------------------------------------------------------------------------- /Directory.Build.props: -------------------------------------------------------------------------------- 1 | 2 | 3 | enable 4 | Remotely.$(MSBuildProjectName.Replace(" ", "_")) 5 | 6 | 7 | -------------------------------------------------------------------------------- /Remotely.slnLaunch: -------------------------------------------------------------------------------- 1 | [ 2 | { 3 | "Name": "Agent \u002B Server \u002B Desktop", 4 | "Projects": [ 5 | { 6 | "Path": "Agent\\Agent.csproj", 7 | "Action": "Start", 8 | "DebugTarget": "Agent" 9 | }, 10 | { 11 | "Path": "Desktop.Win\\Desktop.Win.csproj", 12 | "Action": "Start", 13 | "DebugTarget": "Desktop.Win" 14 | }, 15 | { 16 | "Path": "Server\\Server.csproj", 17 | "Action": "Start", 18 | "DebugTarget": "Server" 19 | } 20 | ] 21 | }, 22 | { 23 | "Name": "Agent \u002B Server", 24 | "Projects": [ 25 | { 26 | "Path": "Agent\\Agent.csproj", 27 | "Action": "Start", 28 | "DebugTarget": "Agent" 29 | }, 30 | { 31 | "Path": "Server\\Server.csproj", 32 | "Action": "Start", 33 | "DebugTarget": "Server" 34 | } 35 | ] 36 | } 37 | ] -------------------------------------------------------------------------------- /Server/API/HealthCheckController.cs: -------------------------------------------------------------------------------- 1 | using Microsoft.AspNetCore.Mvc; 2 | using Remotely.Server.Auth; 3 | using Remotely.Server.Services; 4 | 5 | namespace Remotely.Server.API; 6 | 7 | /// 8 | /// Can only be accessed from the local machine. The sole purpose 9 | /// is to provide a healthcheck endpoint for Docker that exercises 10 | /// the database connection. 11 | /// 12 | [Route("api/[controller]")] 13 | [ApiController] 14 | [ServiceFilter(typeof(LocalOnlyFilter))] 15 | public class HealthCheckController : ControllerBase 16 | { 17 | private readonly IDataService _dataService; 18 | 19 | public HealthCheckController(IDataService dataService) 20 | { 21 | _dataService = dataService; 22 | } 23 | 24 | [HttpGet] 25 | public async Task Get() 26 | { 27 | _ = await _dataService.GetOrganizationCountAsync(); 28 | return NoContent(); 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /Server/API/SavedScriptsController.cs: -------------------------------------------------------------------------------- 1 | using Microsoft.AspNetCore.Mvc; 2 | using Remotely.Server.Auth; 3 | using Remotely.Server.Services; 4 | using Remotely.Shared.Entities; 5 | 6 | namespace Remotely.Server.API; 7 | 8 | [Route("api/[controller]")] 9 | [ApiController] 10 | public class SavedScriptsController : ControllerBase 11 | { 12 | private readonly IDataService _dataService; 13 | 14 | public SavedScriptsController(IDataService dataService) 15 | { 16 | _dataService = dataService; 17 | } 18 | 19 | [ServiceFilter(typeof(ExpiringTokenFilter))] 20 | [HttpGet("{scriptId}")] 21 | public async Task> GetScript(Guid scriptId) 22 | { 23 | var result = await _dataService.GetSavedScript(scriptId); 24 | if (!result.IsSuccess) 25 | { 26 | return NotFound(); 27 | } 28 | 29 | return result.Value; 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /Server/Auth/LocalOnlyFilter.cs: -------------------------------------------------------------------------------- 1 | using Microsoft.AspNetCore.Mvc; 2 | using Microsoft.AspNetCore.Mvc.Filters; 3 | using System.Net; 4 | 5 | namespace Remotely.Server.Auth; 6 | 7 | public class LocalOnlyFilter : IAuthorizationFilter 8 | { 9 | public void OnAuthorization(AuthorizationFilterContext context) 10 | { 11 | var remoteIp = context.HttpContext.Connection.RemoteIpAddress; 12 | if (remoteIp is null || !IPAddress.IsLoopback(remoteIp)) 13 | { 14 | context.Result = new UnauthorizedResult(); 15 | return; 16 | } 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /Server/Auth/OrganizationAdminRequirement.cs: -------------------------------------------------------------------------------- 1 | using Microsoft.AspNetCore.Authorization; 2 | 3 | namespace Remotely.Server.Auth; 4 | 5 | public class OrganizationAdminRequirement : IAuthorizationRequirement 6 | { 7 | 8 | } 9 | -------------------------------------------------------------------------------- /Server/Auth/PolicyNames.cs: -------------------------------------------------------------------------------- 1 | namespace Remotely.Server.Auth; 2 | 3 | public static class PolicyNames 4 | { 5 | public const string TwoFactorRequired = nameof(TwoFactorRequired); 6 | public const string OrganizationAdminRequired = nameof(OrganizationAdminRequired); 7 | public const string ServerAdminRequired = nameof(ServerAdminRequired); 8 | } 9 | -------------------------------------------------------------------------------- /Server/Auth/ServerAdminRequirement.cs: -------------------------------------------------------------------------------- 1 | using Microsoft.AspNetCore.Authorization; 2 | 3 | namespace Remotely.Server.Auth; 4 | 5 | public class ServerAdminRequirement : IAuthorizationRequirement 6 | { 7 | } 8 | -------------------------------------------------------------------------------- /Server/Auth/TwoFactorRequiredRequirement.cs: -------------------------------------------------------------------------------- 1 | using Microsoft.AspNetCore.Authorization; 2 | 3 | namespace Remotely.Server.Auth; 4 | 5 | public class TwoFactorRequiredRequirement : IAuthorizationRequirement 6 | { 7 | 8 | } 9 | -------------------------------------------------------------------------------- /Server/Components/Account/IdentityUserAccessor.cs: -------------------------------------------------------------------------------- 1 | using Microsoft.AspNetCore.Identity; 2 | using Remotely.Shared.Entities; 3 | 4 | namespace Remotely.Server.Components.Account; 5 | 6 | internal sealed class IdentityUserAccessor(UserManager userManager, IdentityRedirectManager redirectManager) 7 | { 8 | public async Task GetRequiredUserAsync(HttpContext context) 9 | { 10 | var user = await userManager.GetUserAsync(context.User); 11 | 12 | if (user is null) 13 | { 14 | redirectManager.RedirectToWithStatus("Account/InvalidUser", $"Error: Unable to load user with ID '{userManager.GetUserId(context.User)}'.", context); 15 | } 16 | 17 | return user; 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /Server/Components/Account/Pages/AccessDenied.razor: -------------------------------------------------------------------------------- 1 | @page "/Account/AccessDenied" 2 | 3 | Access denied 4 | 5 |
6 |

Access denied

7 |

You do not have access to this resource.

8 |
9 | -------------------------------------------------------------------------------- /Server/Components/Account/Pages/ForgotPasswordConfirmation.razor: -------------------------------------------------------------------------------- 1 | @page "/Account/ForgotPasswordConfirmation" 2 | 3 | Forgot password confirmation 4 | 5 |

Forgot password confirmation

6 |

7 | Please check your email to reset your password. 8 |

9 | -------------------------------------------------------------------------------- /Server/Components/Account/Pages/InvalidPasswordReset.razor: -------------------------------------------------------------------------------- 1 | @page "/Account/InvalidPasswordReset" 2 | 3 | Invalid password reset 4 | 5 |

Invalid password reset

6 |

7 | The password reset link is invalid. 8 |

9 | -------------------------------------------------------------------------------- /Server/Components/Account/Pages/InvalidUser.razor: -------------------------------------------------------------------------------- 1 | @page "/Account/InvalidUser" 2 | 3 | Invalid user 4 | 5 |

Invalid user

6 | 7 | 8 | -------------------------------------------------------------------------------- /Server/Components/Account/Pages/Lockout.razor: -------------------------------------------------------------------------------- 1 | @page "/Account/Lockout" 2 | 3 | Locked out 4 | 5 |
6 |

Locked out

7 |

This account has been locked out, please try again later.

8 |
9 | -------------------------------------------------------------------------------- /Server/Components/Account/Pages/Manage/_Imports.razor: -------------------------------------------------------------------------------- 1 | @layout ManageLayout 2 | @attribute [Microsoft.AspNetCore.Authorization.Authorize] 3 | -------------------------------------------------------------------------------- /Server/Components/Account/Pages/ResetPasswordConfirmation.razor: -------------------------------------------------------------------------------- 1 | @page "/Account/ResetPasswordConfirmation" 2 | Reset password confirmation 3 | 4 |

Reset password confirmation

5 |

6 | Your password has been reset. Please click here to log in. 7 |

8 | -------------------------------------------------------------------------------- /Server/Components/Account/Pages/_Imports.razor: -------------------------------------------------------------------------------- 1 | @using Remotely.Server.Components.Account.Shared 2 | @layout AccountLayout 3 | -------------------------------------------------------------------------------- /Server/Components/Account/Shared/AccountLayout.razor: -------------------------------------------------------------------------------- 1 | @inherits LayoutComponentBase 2 | @layout Remotely.Server.Components.Layout.MainLayout 3 | @inject NavigationManager NavigationManager 4 | 5 | @if (HttpContext is null) 6 | { 7 |

Loading...

8 | } 9 | else 10 | { 11 | @Body 12 | } 13 | 14 | @code { 15 | [CascadingParameter] 16 | private HttpContext? HttpContext { get; set; } 17 | 18 | protected override void OnParametersSet() 19 | { 20 | if (HttpContext is null) 21 | { 22 | // If this code runs, we're currently rendering in interactive mode, so there is no HttpContext. 23 | // The identity pages need to set cookies, so they require an HttpContext. To achieve this we 24 | // must transition back from interactive mode to a server-rendered page. 25 | NavigationManager.Refresh(forceReload: true); 26 | } 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /Server/Components/Account/Shared/ManageLayout.razor: -------------------------------------------------------------------------------- 1 | @inherits LayoutComponentBase 2 | @layout AccountLayout 3 | 4 |

Manage your account

5 | 6 |
7 |

Change your account settings

8 |
9 |
10 |
11 | 12 |
13 |
14 | @Body 15 |
16 |
17 |
18 | -------------------------------------------------------------------------------- /Server/Components/Account/Shared/RedirectToLogin.razor: -------------------------------------------------------------------------------- 1 | @inject NavigationManager NavigationManager 2 | 3 | @code { 4 | protected override void OnInitialized() 5 | { 6 | NavigationManager.NavigateTo($"Account/Login?returnUrl={Uri.EscapeDataString(NavigationManager.Uri)}", forceLoad: true); 7 | } 8 | } 9 | -------------------------------------------------------------------------------- /Server/Components/Account/Shared/ShowRecoveryCodes.razor: -------------------------------------------------------------------------------- 1 |  2 |

Recovery codes

3 | 11 |
12 |
13 | @foreach (var recoveryCode in RecoveryCodes) 14 | { 15 |
16 | @recoveryCode 17 |
18 | } 19 |
20 |
21 | 22 | @code { 23 | [Parameter] 24 | public string[] RecoveryCodes { get; set; } = []; 25 | 26 | [Parameter] 27 | public string? StatusMessage { get; set; } 28 | } 29 | -------------------------------------------------------------------------------- /Server/Components/Account/Shared/StatusMessage.razor: -------------------------------------------------------------------------------- 1 | @if (!string.IsNullOrEmpty(DisplayMessage)) 2 | { 3 | var statusMessageClass = DisplayMessage.StartsWith("Error") ? "danger" : "success"; 4 | 7 | } 8 | 9 | @code { 10 | private string? messageFromCookie; 11 | 12 | [Parameter] 13 | public string? Message { get; set; } 14 | 15 | [CascadingParameter] 16 | private HttpContext HttpContext { get; set; } = default!; 17 | 18 | private string? DisplayMessage => Message ?? messageFromCookie; 19 | 20 | protected override void OnInitialized() 21 | { 22 | messageFromCookie = HttpContext.Request.Cookies[IdentityRedirectManager.StatusCookieName]; 23 | 24 | if (messageFromCookie is not null) 25 | { 26 | HttpContext.Response.Cookies.Delete(IdentityRedirectManager.StatusCookieName); 27 | } 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /Server/Components/AlertsFrame.razor.css: -------------------------------------------------------------------------------- 1 | #alertsButton { 2 | position: absolute; 3 | top: 75px; 4 | right: 5px; 5 | z-index: 4; 6 | transition: .5s ease left; 7 | user-select: none; 8 | } 9 | 10 | 11 | #alertsFrame { 12 | position: fixed; 13 | top: 0; 14 | right: 0; 15 | bottom: 0; 16 | opacity: 0; 17 | transform: translateX(100%); 18 | width: 350px; 19 | overflow-x: hidden; 20 | overflow-y: auto; 21 | text-align: center; 22 | opacity: 0; 23 | z-index: 4; 24 | transition: .25s ease all; 25 | } 26 | 27 | #alertsFrame.open { 28 | opacity: 1; 29 | transition: .25s ease all; 30 | pointer-events: unset; 31 | transform: translateX(0); 32 | } 33 | 34 | 35 | @media (min-width: 641px) { 36 | #alertsButton { 37 | top: 5px; 38 | } 39 | 40 | } -------------------------------------------------------------------------------- /Server/Components/ColorPicker.razor.css: -------------------------------------------------------------------------------- 1 | .color-sample { 2 | width: 50px; 3 | height: 50px; 4 | border-radius: 100%; 5 | } 6 | -------------------------------------------------------------------------------- /Server/Components/Devices/ChatFrame.razor: -------------------------------------------------------------------------------- 1 | @attribute [Authorize] 2 | @inherits AuthComponentBase 3 | 4 | @if (_chatSessions.Any()) 5 | { 6 |
7 | @foreach (var session in _chatSessions) 8 | { 9 | 10 | } 11 |
12 | } -------------------------------------------------------------------------------- /Server/Components/Devices/ChatFrame.razor.css: -------------------------------------------------------------------------------- 1 | .chat-frame { 2 | position: fixed; 3 | bottom: 0; 4 | right: 0; 5 | width: 25em; 6 | max-width: 90%; 7 | max-height: 100vh; 8 | overflow-y: auto; 9 | z-index: 3; 10 | } 11 | -------------------------------------------------------------------------------- /Server/Components/Devices/DevicesFrame.razor.css: -------------------------------------------------------------------------------- 1 | #deviceControlsWrapper { 2 | display: grid; 3 | grid-template-columns: 1fr 1fr; 4 | grid-column-gap: 20px; 5 | grid-row-gap: 10px; 6 | margin-bottom: 5px; 7 | margin-right: 5px; 8 | padding-top: 3px; 9 | } 10 | 11 | #deviceControlsWrapper > :last-child { 12 | text-align: right; 13 | } 14 | 15 | #deviceListDiv{ 16 | overflow-y: auto; 17 | overflow-x: hidden; 18 | } 19 | -------------------------------------------------------------------------------- /Server/Components/DropdownButton.razor: -------------------------------------------------------------------------------- 1 | @inject IJsInterop JsInterop 2 | 3 |
4 | 9 | 12 |
13 | 14 | @code { 15 | [Parameter] 16 | public string? ButtonClass { get; set; } 17 | 18 | [Parameter] 19 | public RenderFragment? ButtonContent { get; set; } 20 | 21 | [Parameter] 22 | public string? WrapperClass { get; set; } 23 | 24 | [Parameter] 25 | public string? DropDownMenuClass { get; set; } 26 | 27 | 28 | [Parameter] 29 | public RenderFragment? ChildListItems { get; set; } 30 | } 31 | -------------------------------------------------------------------------------- /Server/Components/LoaderHarness.razor: -------------------------------------------------------------------------------- 1 | @using Bitbound.SimpleMessenger; 2 | @using Remotely.Server.Models.Messages; 3 | @inherits MessengerSubscriber 4 | 5 | @if (_loaderShown) 6 | { 7 | 8 | } 9 | 10 | @code { 11 | private bool _loaderShown; 12 | private string _statusMessage = string.Empty; 13 | 14 | protected override async Task OnInitializedAsync() 15 | { 16 | await base.OnInitializedAsync(); 17 | await Register(HandleShowLoaderMessage); 18 | } 19 | 20 | private async Task HandleShowLoaderMessage(object subscriber, ShowLoaderMessage message) 21 | { 22 | _loaderShown = message.IsShown; 23 | _statusMessage = message.StatusMessage; 24 | await InvokeAsync(StateHasChanged); 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /Server/Components/LoadingSignal.razor: -------------------------------------------------------------------------------- 1 | @inject IThemeProvider ThemeProvider 2 | 3 |
4 |
5 | @if (!string.IsNullOrEmpty(StatusMessage)) 6 | { 7 |

8 | @StatusMessage 9 |

10 | } 11 |
12 |
13 |
14 | 15 | @code { 16 | private Theme _theme; 17 | 18 | [Parameter] 19 | public string StatusMessage { get; set; } = string.Empty; 20 | 21 | protected override async Task OnInitializedAsync() 22 | { 23 | _theme = await ThemeProvider.GetEffectiveTheme(); 24 | await base.OnInitializedAsync(); 25 | } 26 | 27 | private string GetSignalClass() 28 | { 29 | return _theme == Theme.Dark ? "signal-dark" : "signal-light"; 30 | } 31 | } -------------------------------------------------------------------------------- /Server/Components/ModalContents/EditDeviceGroup.razor: -------------------------------------------------------------------------------- 1 | @attribute [Authorize] 2 | @inherits AuthComponentBase 3 | 4 |
5 | Editing @EditUser?.UserName 6 |
7 | 8 | @foreach (var group in DeviceGroups ?? Array.Empty()) 9 | { 10 |
11 | 17 | 18 |
19 | } 20 | -------------------------------------------------------------------------------- /Server/Components/ModalContents/QuickScriptsSelector.razor: -------------------------------------------------------------------------------- 1 |  7 | 8 |
9 | 10 |
11 | 12 | @code { 13 | private Guid _selectedScriptId; 14 | 15 | [Parameter] 16 | public List QuickScripts { get; set; } = new(); 17 | 18 | [Parameter] 19 | public EventCallback OnRunClicked { get; set; } 20 | 21 | private async Task RunScriptClicked() 22 | { 23 | var script = QuickScripts.Find(x => x.Id == _selectedScriptId); 24 | if (script is not null) 25 | { 26 | await OnRunClicked.InvokeAsync(script); 27 | } 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /Server/Components/ModalContents/QuickScriptsSelector.razor.cs: -------------------------------------------------------------------------------- 1 | using Microsoft.AspNetCore.Components; 2 | 3 | namespace Remotely.Server.Components.ModalContents; 4 | 5 | public partial class QuickScriptsSelector : ComponentBase 6 | { 7 | } 8 | -------------------------------------------------------------------------------- /Server/Components/ModalHarness.razor.js: -------------------------------------------------------------------------------- 1 | /** 2 | * 3 | * @param {HTMLElement} modal 4 | */ 5 | export function showModal(modal) { 6 | const modalApi = new bootstrap.Modal(modal); 7 | modalApi.show(); 8 | } -------------------------------------------------------------------------------- /Server/Components/Pages/About.razor: -------------------------------------------------------------------------------- 1 | @page "/about" 2 | 3 |

About Remotely

4 | 5 |

6 | Project Repo: https://github.com/immense/Remotely 7 |

8 |

9 | Open-Source Licenses: Credits 10 |

11 |

12 | Version: @(AppVersionHelper.GetAppVersion()) 13 |

14 | -------------------------------------------------------------------------------- /Server/Components/Pages/Branding.razor.css: -------------------------------------------------------------------------------- 1 | .branding-icon { 2 | max-width: 8rem; 3 | height: auto; 4 | } -------------------------------------------------------------------------------- /Server/Components/Pages/Credits.razor.css: -------------------------------------------------------------------------------- 1 | li { 2 | word-wrap: break-word; 3 | } 4 | -------------------------------------------------------------------------------- /Server/Components/Pages/GetSupport.razor.css: -------------------------------------------------------------------------------- 1 | input[type='checkbox'] { 2 | width: 25px; 3 | height: 25px; 4 | } 5 | -------------------------------------------------------------------------------- /Server/Components/Pages/ManageOrganization.razor.css: -------------------------------------------------------------------------------- 1 |  -------------------------------------------------------------------------------- /Server/Components/Pages/ServerConfig.razor.css: -------------------------------------------------------------------------------- 1 | .list-box { 2 | padding: 1em; 3 | border: 2px solid gray; 4 | height: 8em; 5 | overflow-y: scroll; 6 | overflow-x: hidden; 7 | white-space: nowrap; 8 | border-radius: 5px; 9 | } 10 | 11 | #saveButton { 12 | position: fixed; 13 | right: 40px; 14 | bottom: 20px; 15 | } -------------------------------------------------------------------------------- /Server/Components/Pages/ServerLogs.razor.css: -------------------------------------------------------------------------------- 1 | .buttons-row { 2 | display: grid; 3 | grid-template-columns: auto auto 1fr; 4 | grid-column-gap: 2em; 5 | } 6 | 7 | .filters-row { 8 | display: grid; 9 | grid-template-columns: auto auto auto 1fr; 10 | grid-column-gap: 1em; 11 | } 12 | 13 | .logs-content { 14 | width: 100%; 15 | white-space: pre; 16 | height: 500px; 17 | } 18 | 19 | 20 | @media (max-width: 641px) { 21 | .buttons-row { 22 | grid-template-columns: 1fr; 23 | text-align: center; 24 | grid-row-gap: 1em; 25 | } 26 | 27 | .filters-row { 28 | grid-template-columns: 1fr 1fr; 29 | align-items: center; 30 | grid-row-gap: 0.5em; 31 | } 32 | } -------------------------------------------------------------------------------- /Server/Components/Routes.razor: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | 6 | 7 | -------------------------------------------------------------------------------- /Server/Components/Scripts/RunScript.razor.css: -------------------------------------------------------------------------------- 1 | .main-grid { 2 | display: grid; 3 | grid-template-rows: auto 1fr; 4 | grid-row-gap: 1em; 5 | grid-template-columns: auto 1fr 1fr; 6 | grid-column-gap: 2em; 7 | } 8 | 9 | .column-wrapper { 10 | display: grid; 11 | grid-template-rows: auto 1fr; 12 | overflow-y: auto; 13 | } 14 | 15 | 16 | .item-list-border { 17 | border: 1px solid gray; 18 | padding: .5em; 19 | height: 100%; 20 | border-radius: 5px; 21 | overflow-y: auto; 22 | } -------------------------------------------------------------------------------- /Server/Components/Scripts/SavedScripts.razor.css: -------------------------------------------------------------------------------- 1 | .outer-grid { 2 | display: grid; 3 | grid-template-columns: 1fr auto; 4 | grid-column-gap: 2.5em; 5 | } 6 | 7 | .left-outer-grid { 8 | display: grid; 9 | grid-template-rows: auto 1fr; 10 | } 11 | 12 | .scripts-tree-view { 13 | border-radius: 5px; 14 | padding: .5em; 15 | 16 | } 17 | 18 | .tree-view-wrapper-grid { 19 | display: grid; 20 | grid-template-rows: auto 1fr; 21 | overflow-y: auto; 22 | } 23 | 24 | 25 | @media (max-width: 641px) { 26 | .controls-section { 27 | display: grid; 28 | grid-template-columns: 1fr; 29 | } 30 | 31 | } -------------------------------------------------------------------------------- /Server/Components/Scripts/ScriptSchedules.razor.css: -------------------------------------------------------------------------------- 1 | .item-list-border { 2 | border: 1px solid gray; 3 | padding: .5em; 4 | height: 300px; 5 | border-radius: 5px; 6 | overflow-y: auto; 7 | } 8 | -------------------------------------------------------------------------------- /Server/Components/Scripts/ScriptTreeNode.cs: -------------------------------------------------------------------------------- 1 | using Remotely.Server.Components.TreeView; 2 | using Remotely.Shared.Entities; 3 | 4 | namespace Remotely.Server.Components.Scripts; 5 | 6 | public class ScriptTreeNode 7 | { 8 | public string Id { get; } = Guid.NewGuid().ToString(); 9 | public TreeItemType ItemType { get; set; } 10 | public string Name { get; init; } = string.Empty; 11 | public ScriptTreeNode? ParentNode { get; set; } 12 | public List ChildItems { get; } = new(); 13 | public SavedScript? Script { get; init; } 14 | } 15 | -------------------------------------------------------------------------------- /Server/Components/TabControl/TabContent.razor: -------------------------------------------------------------------------------- 1 | @if (IsActive) 2 | { 3 |
4 | @ChildContent 5 |
6 | } 7 | 8 | 9 | @code { 10 | [CascadingParameter] 11 | public required TabControl Parent { get; init; } 12 | 13 | [Parameter] 14 | public RenderFragment? ChildContent { get; set; } 15 | 16 | [Parameter] 17 | [EditorRequired] 18 | public required string Name { get; set; } 19 | 20 | private bool IsActive => Parent.ActiveTab == Name; 21 | 22 | protected override void OnInitialized() 23 | { 24 | if (Parent is null) 25 | { 26 | throw new Exception("TabContent must be contained in a TabControl."); 27 | } 28 | 29 | base.OnInitialized(); 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /Server/Components/TabControl/TabControl.razor: -------------------------------------------------------------------------------- 1 |  6 |
7 | 8 | @TabContents 9 | 10 |
11 | 12 | 13 | @code { 14 | [Parameter] 15 | public RenderFragment? TabHeaders { get; set; } 16 | 17 | [Parameter] 18 | public RenderFragment? TabContents { get; set; } 19 | 20 | [Parameter] 21 | public string? InitialActiveTab { get; set; } 22 | 23 | public string? ActiveTab { get; set; } 24 | 25 | protected override void OnInitialized() 26 | { 27 | ActiveTab = InitialActiveTab; 28 | } 29 | 30 | public void SetActiveTab(TabHeader header) 31 | { 32 | ActiveTab = header.Name; 33 | StateHasChanged(); 34 | } 35 | } 36 | -------------------------------------------------------------------------------- /Server/Components/ToastHarness.razor: -------------------------------------------------------------------------------- 1 | @using Remotely.Server.Services 2 | @inject IToastService ToastService 3 | 4 |
5 | @foreach (var toast in ToastService.Toasts) 6 | { 7 |
8 | @toast.Message 9 |
10 | } 11 |
12 | 13 | @code { 14 | 15 | protected override Task OnAfterRenderAsync(bool firstRender) 16 | { 17 | if (firstRender) 18 | { 19 | ToastService.OnToastsChanged += (s, e) => 20 | { 21 | InvokeAsync(StateHasChanged); 22 | }; 23 | } 24 | return base.OnInitializedAsync(); 25 | 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /Server/Components/ToastHarness.razor.css: -------------------------------------------------------------------------------- 1 | .toast-harness { 2 | position: fixed; 3 | bottom: 25px; 4 | right: 25px; 5 | z-index: 5; 6 | user-select: none; 7 | pointer-events: none; 8 | } 9 | 10 | 11 | .toast-message { 12 | background-color: rgb(25,25,25); 13 | color: white; 14 | transform: translate(0, 0); 15 | padding: 10px; 16 | margin-top: 10px; 17 | margin-bottom: 10px; 18 | opacity: 1; 19 | color: white; 20 | border-radius: 5px; 21 | user-select: none; 22 | pointer-events: none; 23 | animation-name: toast-message; 24 | animation-duration: .5s; 25 | animation-fill-mode: forwards; 26 | animation-timing-function: ease-in; 27 | } 28 | 29 | @keyframes toast-message { 30 | from { 31 | transform: translate(0, 0); 32 | opacity: 1; 33 | } 34 | 35 | to { 36 | transform: translate(calc(100% + 50px), 0); 37 | opacity: 0; 38 | } 39 | } 40 | -------------------------------------------------------------------------------- /Server/Components/TreeView/TreeItemType.cs: -------------------------------------------------------------------------------- 1 | namespace Remotely.Server.Components.TreeView; 2 | 3 | public enum TreeItemType 4 | { 5 | Folder, 6 | Item 7 | } 8 | -------------------------------------------------------------------------------- /Server/Components/TreeView/TreeView.razor: -------------------------------------------------------------------------------- 1 | @typeparam T 2 | 3 |
4 | 5 | @foreach (var item in DataSource) 6 | { 7 | 18 | } 19 | 20 |
-------------------------------------------------------------------------------- /Server/Components/TreeView/TreeView.razor.css: -------------------------------------------------------------------------------- 1 | .tree-view-wrapper{ 2 | overflow-y: auto; 3 | } -------------------------------------------------------------------------------- /Server/Components/TreeView/TreeViewItem.razor.css: -------------------------------------------------------------------------------- 1 | .tree-view-item { 2 | padding: .25em .5em .25em .5em; 3 | } -------------------------------------------------------------------------------- /Server/Data/SqlServerDbContext.cs: -------------------------------------------------------------------------------- 1 | using Microsoft.EntityFrameworkCore; 2 | 3 | namespace Remotely.Server.Data; 4 | 5 | public class SqlServerDbContext : AppDb 6 | { 7 | private readonly IConfiguration _configuration; 8 | 9 | public SqlServerDbContext(IConfiguration configuration, IWebHostEnvironment hostEnv) 10 | : base(hostEnv) 11 | { 12 | _configuration = configuration; 13 | } 14 | 15 | protected override void OnConfiguring(DbContextOptionsBuilder options) 16 | { 17 | options.UseSqlServer(_configuration.GetConnectionString("SQLServer")); 18 | base.OnConfiguring(options); 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /Server/Data/SqliteDbContext.cs: -------------------------------------------------------------------------------- 1 | using Microsoft.EntityFrameworkCore; 2 | 3 | namespace Remotely.Server.Data; 4 | 5 | public class SqliteDbContext : AppDb 6 | { 7 | private readonly IConfiguration _configuration; 8 | 9 | public SqliteDbContext(IConfiguration configuration, IWebHostEnvironment hostEnv) 10 | : base(hostEnv) 11 | { 12 | _configuration = configuration; 13 | } 14 | 15 | protected override void OnConfiguring(DbContextOptionsBuilder options) 16 | { 17 | options.UseSqlite(_configuration.GetConnectionString("SQLite")); 18 | base.OnConfiguring(options); 19 | } 20 | } -------------------------------------------------------------------------------- /Server/Data/TestingDbContext.cs: -------------------------------------------------------------------------------- 1 | using Microsoft.EntityFrameworkCore; 2 | 3 | namespace Remotely.Server.Data; 4 | 5 | public class TestingDbContext : AppDb 6 | { 7 | public TestingDbContext(IWebHostEnvironment hostEnvironment) 8 | : base(hostEnvironment) 9 | { 10 | } 11 | 12 | protected override void OnConfiguring(DbContextOptionsBuilder options) 13 | { 14 | options.UseInMemoryDatabase("Remotely"); 15 | base.OnConfiguring(options); 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /Server/Dockerfile: -------------------------------------------------------------------------------- 1 | FROM mcr.microsoft.com/dotnet/aspnet:8.0 2 | 3 | EXPOSE ${ASPNETCORE_HTTP_PORTS} 4 | 5 | RUN apt -y update && apt -y install curl 6 | COPY Server/bin/publish /app 7 | 8 | WORKDIR /app 9 | 10 | ENTRYPOINT ["dotnet", "Remotely_Server.dll"] 11 | 12 | HEALTHCHECK \ 13 | CMD curl -f http://localhost:${ASPNETCORE_HTTP_PORTS}/api/healthcheck || exit 1 -------------------------------------------------------------------------------- /Server/Dockerfile.old: -------------------------------------------------------------------------------- 1 | FROM ubuntu:jammy 2 | 3 | EXPOSE 5000 4 | 5 | ENV ASPNETCORE_ENVIRONMENT="Production" 6 | ENV ASPNETCORE_URLS="http://*:5000" 7 | 8 | RUN \ 9 | apt-get -y update && \ 10 | apt-get -y install \ 11 | apt-utils \ 12 | wget \ 13 | apt-transport-https \ 14 | unzip \ 15 | acl \ 16 | libssl1.0 17 | 18 | RUN \ 19 | apt-get -y install aspnetcore-runtime-8.0 20 | 21 | RUN \ 22 | mkdir -p /app && \ 23 | mkdir /config && \ 24 | wget -q https://github.com/immense/Remotely/releases/latest/download/Remotely_Server_Linux-x64.zip && \ 25 | unzip -o Remotely_Server_Linux-x64.zip -d /app && \ 26 | rm Remotely_Server_Linux-x64.zip 27 | 28 | RUN \ 29 | mkdir -p /remotely-data && \ 30 | sed -i 's/DataSource=Remotely.db/DataSource=\/remotely-data\/Remotely.db/' /app/appsettings.json 31 | 32 | VOLUME "/remotely-data" 33 | 34 | WORKDIR /app 35 | 36 | COPY DockerMain.sh / 37 | 38 | RUN chmod 755 /DockerMain.sh 39 | 40 | ENTRYPOINT ["/DockerMain.sh"] -------------------------------------------------------------------------------- /Server/Dockerfile.pipelines: -------------------------------------------------------------------------------- 1 | FROM mcr.microsoft.com/dotnet/aspnet:8.0 2 | 3 | EXPOSE ${ASPNETCORE_HTTP_PORTS} 4 | 5 | RUN apt -y update && apt -y install curl 6 | COPY /_immense.Remotely/Server/linux-x64/Server /app 7 | 8 | WORKDIR /app 9 | 10 | ENTRYPOINT ["dotnet", "Remotely_Server.dll"] 11 | 12 | HEALTHCHECK \ 13 | CMD curl -f http://localhost:${ASPNETCORE_HTTP_PORTS}/api/healthcheck || exit 1 -------------------------------------------------------------------------------- /Server/Enums/DeviceCardState.cs: -------------------------------------------------------------------------------- 1 | namespace Remotely.Server.Enums; 2 | 3 | public enum DeviceCardState 4 | { 5 | Normal, 6 | Expanded 7 | } 8 | -------------------------------------------------------------------------------- /Server/Enums/StreamerState.cs: -------------------------------------------------------------------------------- 1 | namespace Remotely.Server.Enums; 2 | 3 | [Flags] 4 | public enum StreamerState 5 | { 6 | Unknown = 1 << 0, 7 | Connected = 1 << 1, 8 | Disconnected = 1 << 2, 9 | DisconnectExpected = 1 << 3, 10 | Reconnecting = 1 << 4, 11 | ChangingSessions = 1 << 5, 12 | WindowsLoggingOff = 1 << 6, 13 | WindowsShuttingDown = 1 << 7, 14 | } 15 | -------------------------------------------------------------------------------- /Server/Enums/ToastType.cs: -------------------------------------------------------------------------------- 1 | namespace Remotely.Server.Enums; 2 | 3 | public enum ToastType 4 | { 5 | Primary, 6 | Secondary, 7 | Success, 8 | Info, 9 | Warning, 10 | Error 11 | } 12 | -------------------------------------------------------------------------------- /Server/Extensions/IApplicationBuilderExtensions.cs: -------------------------------------------------------------------------------- 1 | namespace Remotely.Server.Extensions; 2 | 3 | public static class IApplicationBuilderExtensions 4 | { 5 | /// 6 | /// 7 | /// Maps Razor pages and SignalR hubs. The remote control viewer page will be mapped 8 | /// to path "/Viewer", the desktop hub to "/hubs/desktop", and viewer hub 9 | /// to "/hubs/viewer". 10 | /// 11 | /// 12 | /// Important: This must be called after "app.UseRouting()". 13 | /// 14 | /// 15 | /// 16 | /// 17 | public static IApplicationBuilder UseRemoteControlServer(this IApplicationBuilder app) 18 | { 19 | 20 | 21 | return app; 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /Server/Extensions/IQueryableExtensions.cs: -------------------------------------------------------------------------------- 1 | namespace Remotely.Server.Extensions; 2 | 3 | public static class IQueryableExtensions 4 | { 5 | public static IQueryable Apply(this IQueryable query, Action>? queryBuilder) 6 | { 7 | if (queryBuilder is null) 8 | { 9 | return query; 10 | } 11 | 12 | queryBuilder.Invoke(query); 13 | return query; 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /Server/Migrations/PostgreSql/20210103153552_WebRtcSetting.cs: -------------------------------------------------------------------------------- 1 | using Microsoft.EntityFrameworkCore.Migrations; 2 | 3 | namespace Remotely.Server.Migrations.PostgreSql; 4 | 5 | public partial class WebRtcSetting : Migration 6 | { 7 | protected override void Up(MigrationBuilder migrationBuilder) 8 | { 9 | migrationBuilder.AddColumn( 10 | name: "WebRtcSetting", 11 | table: "Devices", 12 | type: "integer", 13 | nullable: false, 14 | defaultValue: 0); 15 | } 16 | 17 | protected override void Down(MigrationBuilder migrationBuilder) 18 | { 19 | migrationBuilder.DropColumn( 20 | name: "WebRtcSetting", 21 | table: "Devices"); 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /Server/Migrations/PostgreSql/20210205114430_IsSponsor property.cs: -------------------------------------------------------------------------------- 1 | using Microsoft.EntityFrameworkCore.Migrations; 2 | 3 | namespace Remotely.Server.Migrations.PostgreSql; 4 | 5 | public partial class IsSponsorproperty : Migration 6 | { 7 | protected override void Up(MigrationBuilder migrationBuilder) 8 | { 9 | migrationBuilder.AddColumn( 10 | name: "IsSponsor", 11 | table: "Organizations", 12 | type: "boolean", 13 | nullable: false, 14 | defaultValue: false); 15 | } 16 | 17 | protected override void Down(MigrationBuilder migrationBuilder) 18 | { 19 | migrationBuilder.DropColumn( 20 | name: "IsSponsor", 21 | table: "Organizations"); 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /Server/Migrations/PostgreSql/20210417155843_Add Alert Details.cs: -------------------------------------------------------------------------------- 1 | using Microsoft.EntityFrameworkCore.Migrations; 2 | 3 | namespace Remotely.Server.Migrations.PostgreSql; 4 | 5 | public partial class AddAlertDetails : Migration 6 | { 7 | protected override void Up(MigrationBuilder migrationBuilder) 8 | { 9 | migrationBuilder.AddColumn( 10 | name: "Details", 11 | table: "Alerts", 12 | type: "text", 13 | nullable: true); 14 | } 15 | 16 | protected override void Down(MigrationBuilder migrationBuilder) 17 | { 18 | migrationBuilder.DropColumn( 19 | name: "Details", 20 | table: "Alerts"); 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /Server/Migrations/PostgreSql/20221231192625_Remove RelayCode.cs: -------------------------------------------------------------------------------- 1 | using Microsoft.EntityFrameworkCore.Migrations; 2 | 3 | #nullable disable 4 | 5 | namespace Remotely.Server.Migrations.PostgreSql; 6 | 7 | public partial class RemoveRelayCode : Migration 8 | { 9 | protected override void Up(MigrationBuilder migrationBuilder) 10 | { 11 | migrationBuilder.DropColumn( 12 | name: "RelayCode", 13 | table: "Organizations"); 14 | } 15 | 16 | protected override void Down(MigrationBuilder migrationBuilder) 17 | { 18 | migrationBuilder.AddColumn( 19 | name: "RelayCode", 20 | table: "Organizations", 21 | type: "text", 22 | nullable: true); 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /Server/Migrations/PostgreSql/20230622144413_Add_Agent_MacAddress.cs: -------------------------------------------------------------------------------- 1 | using Microsoft.EntityFrameworkCore.Migrations; 2 | 3 | #nullable disable 4 | 5 | namespace Remotely.Server.Migrations.PostgreSql; 6 | 7 | /// 8 | public partial class Add_Agent_MacAddress : Migration 9 | { 10 | /// 11 | protected override void Up(MigrationBuilder migrationBuilder) 12 | { 13 | migrationBuilder.AddColumn( 14 | name: "MacAddresses", 15 | table: "Devices", 16 | type: "text", 17 | nullable: true); 18 | } 19 | 20 | /// 21 | protected override void Down(MigrationBuilder migrationBuilder) 22 | { 23 | migrationBuilder.DropColumn( 24 | name: "MacAddresses", 25 | table: "Devices"); 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /Server/Migrations/SqlServer/20210103153621_WebRtcSetting.cs: -------------------------------------------------------------------------------- 1 | using Microsoft.EntityFrameworkCore.Migrations; 2 | 3 | namespace Remotely.Server.Migrations.SqlServer; 4 | 5 | public partial class WebRtcSetting : Migration 6 | { 7 | protected override void Up(MigrationBuilder migrationBuilder) 8 | { 9 | migrationBuilder.AddColumn( 10 | name: "WebRtcSetting", 11 | table: "Devices", 12 | type: "int", 13 | nullable: false, 14 | defaultValue: 0); 15 | } 16 | 17 | protected override void Down(MigrationBuilder migrationBuilder) 18 | { 19 | migrationBuilder.DropColumn( 20 | name: "WebRtcSetting", 21 | table: "Devices"); 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /Server/Migrations/SqlServer/20210205114415_IsSponsor property.cs: -------------------------------------------------------------------------------- 1 | using Microsoft.EntityFrameworkCore.Migrations; 2 | 3 | namespace Remotely.Server.Migrations.SqlServer; 4 | 5 | public partial class IsSponsorproperty : Migration 6 | { 7 | protected override void Up(MigrationBuilder migrationBuilder) 8 | { 9 | migrationBuilder.AddColumn( 10 | name: "IsSponsor", 11 | table: "Organizations", 12 | type: "bit", 13 | nullable: false, 14 | defaultValue: false); 15 | } 16 | 17 | protected override void Down(MigrationBuilder migrationBuilder) 18 | { 19 | migrationBuilder.DropColumn( 20 | name: "IsSponsor", 21 | table: "Organizations"); 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /Server/Migrations/SqlServer/20210417155829_Add Alert Details.cs: -------------------------------------------------------------------------------- 1 | using Microsoft.EntityFrameworkCore.Migrations; 2 | 3 | namespace Remotely.Server.Migrations.SqlServer; 4 | 5 | public partial class AddAlertDetails : Migration 6 | { 7 | protected override void Up(MigrationBuilder migrationBuilder) 8 | { 9 | migrationBuilder.AddColumn( 10 | name: "Details", 11 | table: "Alerts", 12 | type: "nvarchar(max)", 13 | nullable: true); 14 | } 15 | 16 | protected override void Down(MigrationBuilder migrationBuilder) 17 | { 18 | migrationBuilder.DropColumn( 19 | name: "Details", 20 | table: "Alerts"); 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /Server/Migrations/SqlServer/20221231192616_Remove RelayCode.cs: -------------------------------------------------------------------------------- 1 | using Microsoft.EntityFrameworkCore.Migrations; 2 | 3 | #nullable disable 4 | 5 | namespace Remotely.Server.Migrations.SqlServer; 6 | 7 | public partial class RemoveRelayCode : Migration 8 | { 9 | protected override void Up(MigrationBuilder migrationBuilder) 10 | { 11 | migrationBuilder.DropColumn( 12 | name: "RelayCode", 13 | table: "Organizations"); 14 | } 15 | 16 | protected override void Down(MigrationBuilder migrationBuilder) 17 | { 18 | migrationBuilder.AddColumn( 19 | name: "RelayCode", 20 | table: "Organizations", 21 | type: "nvarchar(max)", 22 | nullable: true); 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /Server/Migrations/SqlServer/20230622144404_Add_Agent_MacAddress.cs: -------------------------------------------------------------------------------- 1 | using Microsoft.EntityFrameworkCore.Migrations; 2 | 3 | #nullable disable 4 | 5 | namespace Remotely.Server.Migrations.SqlServer; 6 | 7 | /// 8 | public partial class Add_Agent_MacAddress : Migration 9 | { 10 | /// 11 | protected override void Up(MigrationBuilder migrationBuilder) 12 | { 13 | migrationBuilder.AddColumn( 14 | name: "MacAddresses", 15 | table: "Devices", 16 | type: "nvarchar(max)", 17 | nullable: true); 18 | } 19 | 20 | /// 21 | protected override void Down(MigrationBuilder migrationBuilder) 22 | { 23 | migrationBuilder.DropColumn( 24 | name: "MacAddresses", 25 | table: "Devices"); 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /Server/Migrations/Sqlite/20200306013915_IsServerAdmin property.cs: -------------------------------------------------------------------------------- 1 | using Microsoft.EntityFrameworkCore.Migrations; 2 | 3 | namespace Remotely.Server.Migrations.Sqlite; 4 | 5 | public partial class IsServerAdminproperty : Migration 6 | { 7 | protected override void Up(MigrationBuilder migrationBuilder) 8 | { 9 | migrationBuilder.AddColumn( 10 | name: "IsServerAdmin", 11 | table: "RemotelyUsers", 12 | nullable: true); 13 | } 14 | 15 | protected override void Down(MigrationBuilder migrationBuilder) 16 | { 17 | migrationBuilder.DropColumn( 18 | name: "IsServerAdmin", 19 | table: "RemotelyUsers"); 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /Server/Migrations/Sqlite/20200327034430_Device Notes.cs: -------------------------------------------------------------------------------- 1 | using Microsoft.EntityFrameworkCore.Migrations; 2 | 3 | namespace Remotely.Server.Migrations.Sqlite; 4 | 5 | public partial class DeviceNotes : Migration 6 | { 7 | protected override void Up(MigrationBuilder migrationBuilder) 8 | { 9 | migrationBuilder.AddColumn( 10 | name: "Notes", 11 | table: "Devices", 12 | nullable: true); 13 | } 14 | 15 | protected override void Down(MigrationBuilder migrationBuilder) 16 | { 17 | migrationBuilder.DropColumn( 18 | name: "Notes", 19 | table: "Devices"); 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /Server/Migrations/Sqlite/20200425052143_PublicIP.cs: -------------------------------------------------------------------------------- 1 | using Microsoft.EntityFrameworkCore.Migrations; 2 | 3 | namespace Remotely.Server.Migrations.Sqlite; 4 | 5 | public partial class PublicIP : Migration 6 | { 7 | protected override void Up(MigrationBuilder migrationBuilder) 8 | { 9 | migrationBuilder.AddColumn( 10 | name: "PublicIP", 11 | table: "Devices", 12 | nullable: true); 13 | } 14 | 15 | protected override void Down(MigrationBuilder migrationBuilder) 16 | { 17 | migrationBuilder.DropColumn( 18 | name: "PublicIP", 19 | table: "Devices"); 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /Server/Migrations/Sqlite/20200430222500_DisplayName.cs: -------------------------------------------------------------------------------- 1 | using Microsoft.EntityFrameworkCore.Migrations; 2 | 3 | namespace Remotely.Server.Migrations.Sqlite; 4 | 5 | public partial class DisplayName : Migration 6 | { 7 | protected override void Up(MigrationBuilder migrationBuilder) 8 | { 9 | migrationBuilder.AddColumn( 10 | name: "DisplayName", 11 | table: "RemotelyUsers", 12 | maxLength: 100, 13 | nullable: true); 14 | } 15 | 16 | protected override void Down(MigrationBuilder migrationBuilder) 17 | { 18 | migrationBuilder.DropColumn( 19 | name: "DisplayName", 20 | table: "RemotelyUsers"); 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /Server/Migrations/Sqlite/20200717143837_Temp password.cs: -------------------------------------------------------------------------------- 1 | using Microsoft.EntityFrameworkCore.Migrations; 2 | 3 | namespace Remotely.Server.Migrations.Sqlite; 4 | 5 | public partial class Temppassword : Migration 6 | { 7 | protected override void Up(MigrationBuilder migrationBuilder) 8 | { 9 | migrationBuilder.AddColumn( 10 | name: "TempPassword", 11 | table: "RemotelyUsers", 12 | nullable: true); 13 | } 14 | 15 | protected override void Down(MigrationBuilder migrationBuilder) 16 | { 17 | migrationBuilder.DropColumn( 18 | name: "TempPassword", 19 | table: "RemotelyUsers"); 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /Server/Migrations/Sqlite/20210103153501_WebRtcSetting.cs: -------------------------------------------------------------------------------- 1 | using Microsoft.EntityFrameworkCore.Migrations; 2 | 3 | namespace Remotely.Server.Migrations.Sqlite; 4 | 5 | public partial class WebRtcSetting : Migration 6 | { 7 | protected override void Up(MigrationBuilder migrationBuilder) 8 | { 9 | migrationBuilder.AddColumn( 10 | name: "WebRtcSetting", 11 | table: "Devices", 12 | type: "INTEGER", 13 | nullable: false, 14 | defaultValue: 0); 15 | } 16 | 17 | protected override void Down(MigrationBuilder migrationBuilder) 18 | { 19 | migrationBuilder.DropColumn( 20 | name: "WebRtcSetting", 21 | table: "Devices"); 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /Server/Migrations/Sqlite/20210205114359_IsSponsor property.cs: -------------------------------------------------------------------------------- 1 | using Microsoft.EntityFrameworkCore.Migrations; 2 | 3 | namespace Remotely.Server.Migrations.Sqlite; 4 | 5 | public partial class IsSponsorproperty : Migration 6 | { 7 | protected override void Up(MigrationBuilder migrationBuilder) 8 | { 9 | migrationBuilder.AddColumn( 10 | name: "IsSponsor", 11 | table: "Organizations", 12 | type: "INTEGER", 13 | nullable: false, 14 | defaultValue: false); 15 | } 16 | 17 | protected override void Down(MigrationBuilder migrationBuilder) 18 | { 19 | migrationBuilder.DropColumn( 20 | name: "IsSponsor", 21 | table: "Organizations"); 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /Server/Migrations/Sqlite/20210417155815_Add Alert Details.cs: -------------------------------------------------------------------------------- 1 | using Microsoft.EntityFrameworkCore.Migrations; 2 | 3 | namespace Remotely.Server.Migrations.Sqlite; 4 | 5 | public partial class AddAlertDetails : Migration 6 | { 7 | protected override void Up(MigrationBuilder migrationBuilder) 8 | { 9 | migrationBuilder.AddColumn( 10 | name: "Details", 11 | table: "Alerts", 12 | type: "TEXT", 13 | nullable: true); 14 | } 15 | 16 | protected override void Down(MigrationBuilder migrationBuilder) 17 | { 18 | migrationBuilder.DropColumn( 19 | name: "Details", 20 | table: "Alerts"); 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /Server/Migrations/Sqlite/20220827150619_Remove deprecated WebRTC.cs: -------------------------------------------------------------------------------- 1 | using Microsoft.EntityFrameworkCore.Migrations; 2 | 3 | #nullable disable 4 | 5 | namespace Remotely.Server.Migrations.Sqlite; 6 | 7 | public partial class RemovedeprecatedWebRTC : Migration 8 | { 9 | protected override void Up(MigrationBuilder migrationBuilder) 10 | { 11 | migrationBuilder.DropColumn( 12 | name: "WebRtcSetting", 13 | table: "Devices"); 14 | } 15 | 16 | protected override void Down(MigrationBuilder migrationBuilder) 17 | { 18 | migrationBuilder.AddColumn( 19 | name: "WebRtcSetting", 20 | table: "Devices", 21 | type: "INTEGER", 22 | nullable: false, 23 | defaultValue: 0); 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /Server/Migrations/Sqlite/20221231192606_Remove RelayCode.cs: -------------------------------------------------------------------------------- 1 | using Microsoft.EntityFrameworkCore.Migrations; 2 | 3 | #nullable disable 4 | 5 | namespace Remotely.Server.Migrations.Sqlite; 6 | 7 | public partial class RemoveRelayCode : Migration 8 | { 9 | protected override void Up(MigrationBuilder migrationBuilder) 10 | { 11 | migrationBuilder.DropColumn( 12 | name: "RelayCode", 13 | table: "Organizations"); 14 | } 15 | 16 | protected override void Down(MigrationBuilder migrationBuilder) 17 | { 18 | migrationBuilder.AddColumn( 19 | name: "RelayCode", 20 | table: "Organizations", 21 | type: "TEXT", 22 | nullable: true); 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /Server/Migrations/Sqlite/20230622144355_Add_Agent_MacAddress.cs: -------------------------------------------------------------------------------- 1 | using Microsoft.EntityFrameworkCore.Migrations; 2 | 3 | #nullable disable 4 | 5 | namespace Remotely.Server.Migrations.Sqlite; 6 | 7 | /// 8 | public partial class Add_Agent_MacAddress : Migration 9 | { 10 | /// 11 | protected override void Up(MigrationBuilder migrationBuilder) 12 | { 13 | migrationBuilder.AddColumn( 14 | name: "MacAddresses", 15 | table: "Devices", 16 | type: "TEXT", 17 | nullable: true); 18 | } 19 | 20 | /// 21 | protected override void Down(MigrationBuilder migrationBuilder) 22 | { 23 | migrationBuilder.DropColumn( 24 | name: "MacAddresses", 25 | table: "Devices"); 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /Server/Models/ApiLogin.cs: -------------------------------------------------------------------------------- 1 | namespace Remotely.Server.Models; 2 | 3 | public class ApiLogin 4 | { 5 | public string? Email { get; set; } 6 | public string? Password { get; set; } 7 | } 8 | -------------------------------------------------------------------------------- /Server/Models/ColorPickerModel.cs: -------------------------------------------------------------------------------- 1 | using System.ComponentModel; 2 | 3 | namespace Remotely.Server.Models; 4 | 5 | public class ColorPickerModel 6 | { 7 | [DisplayName("Red")] 8 | public byte Red { get; set; } 9 | 10 | [DisplayName("Green")] 11 | public byte Green { get; set; } 12 | 13 | [DisplayName("Blue")] 14 | public byte Blue { get; set; } 15 | } 16 | -------------------------------------------------------------------------------- /Server/Models/Messages/ChatReceivedMessage.cs: -------------------------------------------------------------------------------- 1 | namespace Remotely.Server.Models.Messages; 2 | 3 | public record ChatReceivedMessage(string DeviceId, string DeviceName, string MessageText, bool DidDisconnect = false); -------------------------------------------------------------------------------- /Server/Models/Messages/ChatSessionsChangedMessage.cs: -------------------------------------------------------------------------------- 1 | namespace Remotely.Server.Models.Messages; 2 | 3 | public record ChatSessionsChangedMessage(); -------------------------------------------------------------------------------- /Server/Models/Messages/DeviceCardStateChangedMessage.cs: -------------------------------------------------------------------------------- 1 | using Remotely.Server.Enums; 2 | 3 | namespace Remotely.Server.Models.Messages; 4 | 5 | public record DeviceCardStateChangedMessage(string DeviceId, DeviceCardState State); -------------------------------------------------------------------------------- /Server/Models/Messages/DeviceStateChangedMessage.cs: -------------------------------------------------------------------------------- 1 | using Remotely.Shared.Entities; 2 | 3 | namespace Remotely.Server.Models.Messages; 4 | 5 | public record DeviceStateChangedMessage(Device Device); 6 | -------------------------------------------------------------------------------- /Server/Models/Messages/DisplayNotificationMessage.cs: -------------------------------------------------------------------------------- 1 | namespace Remotely.Server.Models.Messages; 2 | 3 | public record DisplayNotificationMessage(string ConsoleText, string ToastText, string ClassName); -------------------------------------------------------------------------------- /Server/Models/Messages/DownloadFileMessage.cs: -------------------------------------------------------------------------------- 1 | namespace Remotely.Server.Models.Messages; 2 | 3 | public record DownloadFileMessage(string MessageId); 4 | -------------------------------------------------------------------------------- /Server/Models/Messages/DownloadFileProgressMessage.cs: -------------------------------------------------------------------------------- 1 | namespace Remotely.Server.Models.Messages; 2 | 3 | public record DownloadFileProgressMessage(int ProgressPercent); 4 | -------------------------------------------------------------------------------- /Server/Models/Messages/PowerShellCompletionsMessage.cs: -------------------------------------------------------------------------------- 1 | using Remotely.Shared.Enums; 2 | using Remotely.Shared.Models; 3 | 4 | namespace Remotely.Server.Models.Messages; 5 | 6 | public record PowerShellCompletionsMessage(PwshCommandCompletion Completion, CompletionIntent Intent); -------------------------------------------------------------------------------- /Server/Models/Messages/ReceiveLogsMessage.cs: -------------------------------------------------------------------------------- 1 | namespace Remotely.Server.Models.Messages; 2 | 3 | public record ReceiveLogsMessage(string LogChunk); -------------------------------------------------------------------------------- /Server/Models/Messages/ScriptResultMessage.cs: -------------------------------------------------------------------------------- 1 | using Remotely.Shared.Entities; 2 | 3 | namespace Remotely.Server.Models.Messages; 4 | 5 | public record ScriptResultMessage(ScriptResult ScriptResult); 6 | -------------------------------------------------------------------------------- /Server/Models/Messages/ShowLoaderMessage.cs: -------------------------------------------------------------------------------- 1 | namespace Remotely.Server.Models.Messages; 2 | 3 | public record ShowLoaderMessage(bool IsShown, string StatusMessage); -------------------------------------------------------------------------------- /Server/Models/Messages/TransferCompleteMessage.cs: -------------------------------------------------------------------------------- 1 | namespace Remotely.Server.Models.Messages; 2 | 3 | public record TransferCompleteMessage(string TransferId); -------------------------------------------------------------------------------- /Server/Models/ModalButton.cs: -------------------------------------------------------------------------------- 1 | namespace Remotely.Server.Models; 2 | 3 | public class ModalButton 4 | { 5 | public string Class { get; init; } = string.Empty; 6 | public string Text { get; init; } = string.Empty; 7 | 8 | public required Action OnClick { get; init; } 9 | } 10 | -------------------------------------------------------------------------------- /Server/Models/RemoteControlMode.cs: -------------------------------------------------------------------------------- 1 | namespace Remotely.Server.Models; 2 | 3 | public enum RemoteControlMode 4 | { 5 | Unknown, 6 | Unattended, 7 | Attended 8 | } 9 | -------------------------------------------------------------------------------- /Server/Models/RemoteControlRequest.cs: -------------------------------------------------------------------------------- 1 | namespace Remotely.Server.Models; 2 | 3 | public class RemoteControlRequest 4 | { 5 | public string? DeviceID { get; set; } 6 | public string? Email { get; set; } 7 | public string? Password { get; set; } 8 | } 9 | -------------------------------------------------------------------------------- /Server/Models/Toast.cs: -------------------------------------------------------------------------------- 1 | namespace Remotely.Server.Models; 2 | 3 | public class Toast 4 | { 5 | public Toast(string guid, string message, string classString, TimeSpan expiration, string styleOverrides) 6 | { 7 | Guid = guid; 8 | Message = message; 9 | ClassString = classString; 10 | Expiration = expiration; 11 | StyleOverrides = styleOverrides; 12 | } 13 | 14 | public string ClassString { get; } 15 | public TimeSpan Expiration { get; } 16 | public string Guid { get; } 17 | public string Message { get; } 18 | public string StyleOverrides { get; } 19 | } 20 | -------------------------------------------------------------------------------- /Server/Models/ViewerPageTheme.cs: -------------------------------------------------------------------------------- 1 | namespace Remotely.Server.Models; 2 | 3 | public enum ViewerPageTheme 4 | { 5 | Dark, 6 | Light 7 | } 8 | -------------------------------------------------------------------------------- /Server/Options/ApplicationOptions.cs: -------------------------------------------------------------------------------- 1 | namespace Remotely.Server.Options; 2 | 3 | public class ApplicationOptions 4 | { 5 | public const string SectionKey = "ApplicationOptions"; 6 | public string DbProvider { get; set; } = "SQLite"; 7 | public string? DockerGatewayIp { get; set; } 8 | } 9 | -------------------------------------------------------------------------------- /Server/Properties/AssemblyInfo.cs: -------------------------------------------------------------------------------- 1 | using System.Runtime.CompilerServices; 2 | 3 | [assembly: InternalsVisibleTo("Remotely.Server.Tests")] -------------------------------------------------------------------------------- /Server/Properties/serviceDependencies.json: -------------------------------------------------------------------------------- 1 | { 2 | "dependencies": { 3 | "mssql1": { 4 | "type": "mssql", 5 | "connectionId": "DefaultConnection" 6 | } 7 | } 8 | } -------------------------------------------------------------------------------- /Server/Properties/serviceDependencies.local.json: -------------------------------------------------------------------------------- 1 | { 2 | "dependencies": { 3 | "mssql1": { 4 | "type": "mssql.local", 5 | "connectionId": "DefaultConnection" 6 | } 7 | } 8 | } -------------------------------------------------------------------------------- /Server/RateLimiting/PolicyNames.cs: -------------------------------------------------------------------------------- 1 | namespace Remotely.Server.RateLimiting; 2 | 3 | public static class PolicyNames 4 | { 5 | public const string AgentUpdateDownloads = nameof(AgentUpdateDownloads); 6 | } 7 | -------------------------------------------------------------------------------- /Server/Services/ExpiringTokenService.cs: -------------------------------------------------------------------------------- 1 | using Remotely.Shared.Helpers; 2 | using Microsoft.Extensions.Caching.Memory; 3 | 4 | namespace Remotely.Server.Services; 5 | 6 | public interface IExpiringTokenService 7 | { 8 | string GetToken(DateTimeOffset expiration); 9 | bool TryGetExpiration(string secret, out DateTimeOffset tokenExpiration); 10 | } 11 | 12 | public class ExpiringTokenService : IExpiringTokenService 13 | { 14 | private static readonly MemoryCache _tokenCache = new(new MemoryCacheOptions()); 15 | 16 | public string GetToken(DateTimeOffset expiration) 17 | { 18 | var secret = RandomGenerator.GenerateString(36); 19 | _tokenCache.Set(secret, expiration, expiration); 20 | return secret; 21 | } 22 | 23 | public bool TryGetExpiration(string secret, out DateTimeOffset tokenExpiration) 24 | { 25 | return _tokenCache.TryGetValue(secret, out tokenExpiration); 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /Server/Services/LoaderService.cs: -------------------------------------------------------------------------------- 1 | using Bitbound.SimpleMessenger; 2 | using Remotely.Server.Hubs; 3 | using Remotely.Server.Models.Messages; 4 | 5 | namespace Remotely.Server.Services; 6 | 7 | public interface ILoaderService 8 | { 9 | Task ShowLoader(string statusMessage); 10 | void HideLoader(); 11 | } 12 | 13 | public class LoaderService(IMessenger _messenger, ICircuitConnection _circuitConnection) : ILoaderService 14 | { 15 | public async Task ShowLoader(string statusMessage) 16 | { 17 | await _messenger.Send(new ShowLoaderMessage(true, statusMessage), _circuitConnection.ConnectionId); 18 | return new CallbackDisposable(HideLoader); 19 | } 20 | 21 | public void HideLoader() 22 | { 23 | _messenger.Send(new ShowLoaderMessage(false, string.Empty), _circuitConnection.ConnectionId); 24 | } 25 | } -------------------------------------------------------------------------------- /Server/Services/PascalCasePolicy.cs: -------------------------------------------------------------------------------- 1 | using System.Text.Json; 2 | 3 | namespace Remotely.Server.Services; 4 | 5 | public class PascalCasePolicy : JsonNamingPolicy 6 | { 7 | public override string ConvertName(string name) 8 | { 9 | if (string.IsNullOrWhiteSpace(name)) 10 | { 11 | return name; 12 | } 13 | 14 | var first = name.First().ToString().ToUpper(); 15 | 16 | return first + new string(name.Skip(1).ToArray()); 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /Server/Usings.cs: -------------------------------------------------------------------------------- 1 | global using System; 2 | global using System.Collections.Generic; 3 | global using System.Linq; 4 | global using System.Threading.Tasks; 5 | global using Remotely.Shared.Primitives; 6 | global using Remotely.Server.Components; -------------------------------------------------------------------------------- /Server/appsettings.json: -------------------------------------------------------------------------------- 1 | { 2 | "ConnectionStrings": { 3 | "PostgreSQL": "Host=localhost;Database=Remotely;Username=postgres;", 4 | "SQLite": "DataSource=Remotely.db", 5 | "SQLServer": "Server=(localdb)\\mssqllocaldb;Database=Remotely-Server-53bc9b9d-9d6a-45d4-8429-2a2761773502;Trusted_Connection=True;MultipleActiveResultSets=true" 6 | }, 7 | "Logging": { 8 | "LogLevel": { 9 | "Default": "Information", 10 | "Microsoft.AspNetCore.HttpLogging.HttpLoggingMiddleware": "Information", 11 | "Microsoft.AspNetCore": "Warning" 12 | } 13 | }, 14 | "Serilog": { 15 | "MinimumLevel": { 16 | "Default": "Information", 17 | "Override": { 18 | "Microsoft.AspNetCore": "Warning", 19 | "System": "Warning" 20 | } 21 | } 22 | }, 23 | "ApplicationOptions": { 24 | "DbProvider": "SQLite", 25 | "DockerGatewayIp": "172.28.0.1" 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /Server/wwwroot/css/Themes/darkly.custom.css: -------------------------------------------------------------------------------- 1 | hr { 2 | border-top: 1px solid #282828; 3 | } 4 | 5 | .console-prompt { 6 | color: royalblue; 7 | } 8 | 9 | .console-output { 10 | color: limegreen; 11 | } 12 | 13 | .navbar-brand { 14 | font-size: 1.5rem !important; 15 | } 16 | 17 | .logo-subtitle { 18 | font-size: .5em; 19 | color: deepskyblue; 20 | } 21 | 22 | .form-floating > label { 23 | color: #375a7f; 24 | } -------------------------------------------------------------------------------- /Server/wwwroot/css/Themes/yeti.custom.css: -------------------------------------------------------------------------------- 1 | hr { 2 | border-top: 1px solid #282828; 3 | } 4 | 5 | .console-prompt { 6 | color: slategray; 7 | } 8 | 9 | .console-output { 10 | color: darkgreen; 11 | } 12 | 13 | .logo-title { 14 | font-size: 1.25rem !important; 15 | font-weight: bold; 16 | } 17 | 18 | .logo-subtitle { 19 | font-size: .75em; 20 | color: lightgray; 21 | } 22 | 23 | .jumbotron { 24 | padding: 4rem !important; 25 | } 26 | -------------------------------------------------------------------------------- /Server/wwwroot/css/open-iconic/font/fonts/open-iconic.eot: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/immense/Remotely/ec0d45d8f83ee512e60306ce4ddefed6509bd903/Server/wwwroot/css/open-iconic/font/fonts/open-iconic.eot -------------------------------------------------------------------------------- /Server/wwwroot/css/open-iconic/font/fonts/open-iconic.otf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/immense/Remotely/ec0d45d8f83ee512e60306ce4ddefed6509bd903/Server/wwwroot/css/open-iconic/font/fonts/open-iconic.otf -------------------------------------------------------------------------------- /Server/wwwroot/css/open-iconic/font/fonts/open-iconic.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/immense/Remotely/ec0d45d8f83ee512e60306ce4ddefed6509bd903/Server/wwwroot/css/open-iconic/font/fonts/open-iconic.ttf -------------------------------------------------------------------------------- /Server/wwwroot/css/open-iconic/font/fonts/open-iconic.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/immense/Remotely/ec0d45d8f83ee512e60306ce4ddefed6509bd903/Server/wwwroot/css/open-iconic/font/fonts/open-iconic.woff -------------------------------------------------------------------------------- /Server/wwwroot/css/site.min.css: -------------------------------------------------------------------------------- 1 | body{padding-top:50px;padding-bottom:20px}.body-content{padding-left:15px;padding-right:15px}.carousel-caption p{font-size:20px;line-height:1.4}.carousel-inner .item img[src$=".svg"]{width:100%}#qrCode{margin:15px}@media screen and (max-width:767px){.carousel-caption{display:none}} -------------------------------------------------------------------------------- /Server/wwwroot/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/immense/Remotely/ec0d45d8f83ee512e60306ce4ddefed6509bd903/Server/wwwroot/favicon.ico -------------------------------------------------------------------------------- /Server/wwwroot/images/DefaultIcon.pdn: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/immense/Remotely/ec0d45d8f83ee512e60306ce4ddefed6509bd903/Server/wwwroot/images/DefaultIcon.pdn -------------------------------------------------------------------------------- /Server/wwwroot/images/DefaultIcon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/immense/Remotely/ec0d45d8f83ee512e60306ce4ddefed6509bd903/Server/wwwroot/images/DefaultIcon.png -------------------------------------------------------------------------------- /Server/wwwroot/images/DefaultIcon_128.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/immense/Remotely/ec0d45d8f83ee512e60306ce4ddefed6509bd903/Server/wwwroot/images/DefaultIcon_128.png -------------------------------------------------------------------------------- /Server/wwwroot/images/DefaultIcon_512.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/immense/Remotely/ec0d45d8f83ee512e60306ce4ddefed6509bd903/Server/wwwroot/images/DefaultIcon_512.png -------------------------------------------------------------------------------- /Server/wwwroot/images/Remotely_Desktop.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/immense/Remotely/ec0d45d8f83ee512e60306ce4ddefed6509bd903/Server/wwwroot/images/Remotely_Desktop.png -------------------------------------------------------------------------------- /Server/wwwroot/images/Remotely_Icon.pdn: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/immense/Remotely/ec0d45d8f83ee512e60306ce4ddefed6509bd903/Server/wwwroot/images/Remotely_Icon.pdn -------------------------------------------------------------------------------- /Server/wwwroot/images/Remotely_Icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/immense/Remotely/ec0d45d8f83ee512e60306ce4ddefed6509bd903/Server/wwwroot/images/Remotely_Icon.png -------------------------------------------------------------------------------- /Server/wwwroot/images/Remotely_Icon_128.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/immense/Remotely/ec0d45d8f83ee512e60306ce4ddefed6509bd903/Server/wwwroot/images/Remotely_Icon_128.png -------------------------------------------------------------------------------- /Server/wwwroot/images/Remotely_Icon_512.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/immense/Remotely/ec0d45d8f83ee512e60306ce4ddefed6509bd903/Server/wwwroot/images/Remotely_Icon_512.png -------------------------------------------------------------------------------- /Server/wwwroot/images/Remotely_Icon_Transparent.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/immense/Remotely/ec0d45d8f83ee512e60306ce4ddefed6509bd903/Server/wwwroot/images/Remotely_Icon_Transparent.png -------------------------------------------------------------------------------- /Server/wwwroot/images/Remotely_Logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/immense/Remotely/ec0d45d8f83ee512e60306ce4ddefed6509bd903/Server/wwwroot/images/Remotely_Logo.png -------------------------------------------------------------------------------- /Server/wwwroot/lib/fontawesome/css/regular.css: -------------------------------------------------------------------------------- 1 | /*! 2 | * Font Awesome Free 6.5.2 by @fontawesome - https://fontawesome.com 3 | * License - https://fontawesome.com/license/free (Icons: CC BY 4.0, Fonts: SIL OFL 1.1, Code: MIT License) 4 | * Copyright 2024 Fonticons, Inc. 5 | */ 6 | :root, :host { 7 | --fa-style-family-classic: 'Font Awesome 6 Free'; 8 | --fa-font-regular: normal 400 1em/1 'Font Awesome 6 Free'; } 9 | 10 | @font-face { 11 | font-family: 'Font Awesome 6 Free'; 12 | font-style: normal; 13 | font-weight: 400; 14 | font-display: block; 15 | src: url("../webfonts/fa-regular-400.woff2") format("woff2"), url("../webfonts/fa-regular-400.ttf") format("truetype"); } 16 | 17 | .far, 18 | .fa-regular { 19 | font-weight: 400; } 20 | -------------------------------------------------------------------------------- /Server/wwwroot/lib/fontawesome/css/regular.min.css: -------------------------------------------------------------------------------- 1 | /*! 2 | * Font Awesome Free 6.5.2 by @fontawesome - https://fontawesome.com 3 | * License - https://fontawesome.com/license/free (Icons: CC BY 4.0, Fonts: SIL OFL 1.1, Code: MIT License) 4 | * Copyright 2024 Fonticons, Inc. 5 | */ 6 | :host,:root{--fa-style-family-classic:"Font Awesome 6 Free";--fa-font-regular:normal 400 1em/1 "Font Awesome 6 Free"}@font-face{font-family:"Font Awesome 6 Free";font-style:normal;font-weight:400;font-display:block;src:url(../webfonts/fa-regular-400.woff2) format("woff2"),url(../webfonts/fa-regular-400.ttf) format("truetype")}.fa-regular,.far{font-weight:400} -------------------------------------------------------------------------------- /Server/wwwroot/lib/fontawesome/css/solid.css: -------------------------------------------------------------------------------- 1 | /*! 2 | * Font Awesome Free 6.5.2 by @fontawesome - https://fontawesome.com 3 | * License - https://fontawesome.com/license/free (Icons: CC BY 4.0, Fonts: SIL OFL 1.1, Code: MIT License) 4 | * Copyright 2024 Fonticons, Inc. 5 | */ 6 | :root, :host { 7 | --fa-style-family-classic: 'Font Awesome 6 Free'; 8 | --fa-font-solid: normal 900 1em/1 'Font Awesome 6 Free'; } 9 | 10 | @font-face { 11 | font-family: 'Font Awesome 6 Free'; 12 | font-style: normal; 13 | font-weight: 900; 14 | font-display: block; 15 | src: url("../webfonts/fa-solid-900.woff2") format("woff2"), url("../webfonts/fa-solid-900.ttf") format("truetype"); } 16 | 17 | .fas, 18 | .fa-solid { 19 | font-weight: 900; } 20 | -------------------------------------------------------------------------------- /Server/wwwroot/lib/fontawesome/css/solid.min.css: -------------------------------------------------------------------------------- 1 | /*! 2 | * Font Awesome Free 6.5.2 by @fontawesome - https://fontawesome.com 3 | * License - https://fontawesome.com/license/free (Icons: CC BY 4.0, Fonts: SIL OFL 1.1, Code: MIT License) 4 | * Copyright 2024 Fonticons, Inc. 5 | */ 6 | :host,:root{--fa-style-family-classic:"Font Awesome 6 Free";--fa-font-solid:normal 900 1em/1 "Font Awesome 6 Free"}@font-face{font-family:"Font Awesome 6 Free";font-style:normal;font-weight:900;font-display:block;src:url(../webfonts/fa-solid-900.woff2) format("woff2"),url(../webfonts/fa-solid-900.ttf) format("truetype")}.fa-solid,.fas{font-weight:900} -------------------------------------------------------------------------------- /Server/wwwroot/lib/fontawesome/css/v5-font-face.css: -------------------------------------------------------------------------------- 1 | /*! 2 | * Font Awesome Free 6.5.2 by @fontawesome - https://fontawesome.com 3 | * License - https://fontawesome.com/license/free (Icons: CC BY 4.0, Fonts: SIL OFL 1.1, Code: MIT License) 4 | * Copyright 2024 Fonticons, Inc. 5 | */ 6 | @font-face { 7 | font-family: 'Font Awesome 5 Brands'; 8 | font-display: block; 9 | font-weight: 400; 10 | src: url("../webfonts/fa-brands-400.woff2") format("woff2"), url("../webfonts/fa-brands-400.ttf") format("truetype"); } 11 | 12 | @font-face { 13 | font-family: 'Font Awesome 5 Free'; 14 | font-display: block; 15 | font-weight: 900; 16 | src: url("../webfonts/fa-solid-900.woff2") format("woff2"), url("../webfonts/fa-solid-900.ttf") format("truetype"); } 17 | 18 | @font-face { 19 | font-family: 'Font Awesome 5 Free'; 20 | font-display: block; 21 | font-weight: 400; 22 | src: url("../webfonts/fa-regular-400.woff2") format("woff2"), url("../webfonts/fa-regular-400.ttf") format("truetype"); } 23 | -------------------------------------------------------------------------------- /Server/wwwroot/lib/fontawesome/css/v5-font-face.min.css: -------------------------------------------------------------------------------- 1 | /*! 2 | * Font Awesome Free 6.5.2 by @fontawesome - https://fontawesome.com 3 | * License - https://fontawesome.com/license/free (Icons: CC BY 4.0, Fonts: SIL OFL 1.1, Code: MIT License) 4 | * Copyright 2024 Fonticons, Inc. 5 | */ 6 | @font-face{font-family:"Font Awesome 5 Brands";font-display:block;font-weight:400;src:url(../webfonts/fa-brands-400.woff2) format("woff2"),url(../webfonts/fa-brands-400.ttf) format("truetype")}@font-face{font-family:"Font Awesome 5 Free";font-display:block;font-weight:900;src:url(../webfonts/fa-solid-900.woff2) format("woff2"),url(../webfonts/fa-solid-900.ttf) format("truetype")}@font-face{font-family:"Font Awesome 5 Free";font-display:block;font-weight:400;src:url(../webfonts/fa-regular-400.woff2) format("woff2"),url(../webfonts/fa-regular-400.ttf) format("truetype")} -------------------------------------------------------------------------------- /Server/wwwroot/lib/fontawesome/webfonts/fa-brands-400.eot: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/immense/Remotely/ec0d45d8f83ee512e60306ce4ddefed6509bd903/Server/wwwroot/lib/fontawesome/webfonts/fa-brands-400.eot -------------------------------------------------------------------------------- /Server/wwwroot/lib/fontawesome/webfonts/fa-brands-400.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/immense/Remotely/ec0d45d8f83ee512e60306ce4ddefed6509bd903/Server/wwwroot/lib/fontawesome/webfonts/fa-brands-400.ttf -------------------------------------------------------------------------------- /Server/wwwroot/lib/fontawesome/webfonts/fa-brands-400.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/immense/Remotely/ec0d45d8f83ee512e60306ce4ddefed6509bd903/Server/wwwroot/lib/fontawesome/webfonts/fa-brands-400.woff -------------------------------------------------------------------------------- /Server/wwwroot/lib/fontawesome/webfonts/fa-brands-400.woff2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/immense/Remotely/ec0d45d8f83ee512e60306ce4ddefed6509bd903/Server/wwwroot/lib/fontawesome/webfonts/fa-brands-400.woff2 -------------------------------------------------------------------------------- /Server/wwwroot/lib/fontawesome/webfonts/fa-regular-400.eot: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/immense/Remotely/ec0d45d8f83ee512e60306ce4ddefed6509bd903/Server/wwwroot/lib/fontawesome/webfonts/fa-regular-400.eot -------------------------------------------------------------------------------- /Server/wwwroot/lib/fontawesome/webfonts/fa-regular-400.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/immense/Remotely/ec0d45d8f83ee512e60306ce4ddefed6509bd903/Server/wwwroot/lib/fontawesome/webfonts/fa-regular-400.ttf -------------------------------------------------------------------------------- /Server/wwwroot/lib/fontawesome/webfonts/fa-regular-400.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/immense/Remotely/ec0d45d8f83ee512e60306ce4ddefed6509bd903/Server/wwwroot/lib/fontawesome/webfonts/fa-regular-400.woff -------------------------------------------------------------------------------- /Server/wwwroot/lib/fontawesome/webfonts/fa-regular-400.woff2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/immense/Remotely/ec0d45d8f83ee512e60306ce4ddefed6509bd903/Server/wwwroot/lib/fontawesome/webfonts/fa-regular-400.woff2 -------------------------------------------------------------------------------- /Server/wwwroot/lib/fontawesome/webfonts/fa-solid-900.eot: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/immense/Remotely/ec0d45d8f83ee512e60306ce4ddefed6509bd903/Server/wwwroot/lib/fontawesome/webfonts/fa-solid-900.eot -------------------------------------------------------------------------------- /Server/wwwroot/lib/fontawesome/webfonts/fa-solid-900.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/immense/Remotely/ec0d45d8f83ee512e60306ce4ddefed6509bd903/Server/wwwroot/lib/fontawesome/webfonts/fa-solid-900.ttf -------------------------------------------------------------------------------- /Server/wwwroot/lib/fontawesome/webfonts/fa-solid-900.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/immense/Remotely/ec0d45d8f83ee512e60306ce4ddefed6509bd903/Server/wwwroot/lib/fontawesome/webfonts/fa-solid-900.woff -------------------------------------------------------------------------------- /Server/wwwroot/lib/fontawesome/webfonts/fa-solid-900.woff2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/immense/Remotely/ec0d45d8f83ee512e60306ce4ddefed6509bd903/Server/wwwroot/lib/fontawesome/webfonts/fa-solid-900.woff2 -------------------------------------------------------------------------------- /Server/wwwroot/lib/fontawesome/webfonts/fa-v4compatibility.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/immense/Remotely/ec0d45d8f83ee512e60306ce4ddefed6509bd903/Server/wwwroot/lib/fontawesome/webfonts/fa-v4compatibility.ttf -------------------------------------------------------------------------------- /Server/wwwroot/lib/fontawesome/webfonts/fa-v4compatibility.woff2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/immense/Remotely/ec0d45d8f83ee512e60306ce4ddefed6509bd903/Server/wwwroot/lib/fontawesome/webfonts/fa-v4compatibility.woff2 -------------------------------------------------------------------------------- /Server/wwwroot/manifest.json: -------------------------------------------------------------------------------- 1 | { 2 | "id": "Remotely", 3 | "name": "Remotely", 4 | "short_name": "Remotely", 5 | "start_url": "./", 6 | "display": "standalone", 7 | "background_color": "black", 8 | "theme_color": "white", 9 | "categories": [ "remote control", "remote access", "IT tools" ], 10 | "description": "Remote access tools designed to get things done quickly.", 11 | "icons": [ 12 | { 13 | "src": "./images/Remotely_Icon_128.png", 14 | "sizes": "128x128", 15 | "type": "image/png" 16 | }, 17 | { 18 | "src": "./images/Remotely_Icon_512.png", 19 | "sizes": "512x512", 20 | "type": "image/png" 21 | } 22 | ], 23 | "related_applications": [ 24 | { 25 | "platform": "windows", 26 | "url": "./" 27 | }, 28 | { 29 | "platform": "play", 30 | "url": "./" 31 | }, 32 | { 33 | "platform": "itunes", 34 | "url": "./" 35 | } 36 | ] 37 | } -------------------------------------------------------------------------------- /Server/wwwroot/src/Enums/DtoType.js.map: -------------------------------------------------------------------------------- 1 | {"version":3,"file":"DtoType.js","sourceRoot":"","sources":["DtoType.ts"],"names":[],"mappings":"AAAA,MAAM,CAAN,IAAY,OAyBX;AAzBD,WAAY,OAAO;IACf,iDAAc,CAAA;IACd,iDAAc,CAAA;IACd,uDAAiB,CAAA;IACjB,mDAAe,CAAA;IACf,qDAAgB,CAAA;IAChB,qDAAgB,CAAA;IAChB,+CAAa,CAAA;IACb,+CAAa,CAAA;IACb,4CAAY,CAAA;IACZ,oCAAQ,CAAA;IACR,kDAAe,CAAA;IACf,4CAAY,CAAA;IACZ,wCAAU,CAAA;IACV,kDAAe,CAAA;IACf,oDAAgB,CAAA;IAChB,8DAAqB,CAAA;IACrB,sDAAiB,CAAA;IACjB,8CAAa,CAAA;IACb,sCAAS,CAAA;IACT,4DAAoB,CAAA;IACpB,0DAAmB,CAAA;IACnB,wDAAkB,CAAA;IAClB,0EAA2B,CAAA;IAC3B,0DAAmB,CAAA;AACvB,CAAC,EAzBW,OAAO,KAAP,OAAO,QAyBlB"} -------------------------------------------------------------------------------- /Server/wwwroot/src/Enums/DtoType.ts: -------------------------------------------------------------------------------- 1 | export enum DtoType { 2 | ScreenData = 1, 3 | ScreenSize = 2, 4 | ClipboardText = 4, 5 | AudioSample = 5, 6 | CursorChange = 6, 7 | SelectScreen = 7, 8 | MouseMove = 8, 9 | MouseDown = 9, 10 | MouseUp = 10, 11 | Tap = 11, 12 | MouseWheel = 12, 13 | KeyDown = 13, 14 | KeyUp = 14, 15 | CtrlAltDel = 15, 16 | ToggleAudio = 17, 17 | ToggleBlockInput = 18, 18 | TextTransfer = 19, 19 | KeyPress = 20, 20 | File = 22, 21 | WindowsSessions = 23, 22 | SetKeyStatesUp = 24, 23 | FrameReceived = 25, 24 | OpenFileTransferWindow = 27, 25 | SessionMetrics = 28 26 | } -------------------------------------------------------------------------------- /Server/wwwroot/src/Enums/HubConnectionState.js: -------------------------------------------------------------------------------- 1 | export var HubConnectionState; 2 | (function (HubConnectionState) { 3 | /** The hub connection is disconnected. */ 4 | HubConnectionState["Disconnected"] = "Disconnected"; 5 | /** The hub connection is connecting. */ 6 | HubConnectionState["Connecting"] = "Connecting"; 7 | /** The hub connection is connected. */ 8 | HubConnectionState["Connected"] = "Connected"; 9 | /** The hub connection is disconnecting. */ 10 | HubConnectionState["Disconnecting"] = "Disconnecting"; 11 | /** The hub connection is reconnecting. */ 12 | HubConnectionState["Reconnecting"] = "Reconnecting"; 13 | })(HubConnectionState || (HubConnectionState = {})); 14 | //# sourceMappingURL=HubConnectionState.js.map -------------------------------------------------------------------------------- /Server/wwwroot/src/Enums/HubConnectionState.js.map: -------------------------------------------------------------------------------- 1 | {"version":3,"file":"HubConnectionState.js","sourceRoot":"","sources":["HubConnectionState.ts"],"names":[],"mappings":"AAAA,MAAM,CAAN,IAAY,kBAWX;AAXD,WAAY,kBAAkB;IAC1B,0CAA0C;IAC1C,mDAA6B,CAAA;IAC7B,wCAAwC;IACxC,+CAAyB,CAAA;IACzB,uCAAuC;IACvC,6CAAuB,CAAA;IACvB,2CAA2C;IAC3C,qDAA+B,CAAA;IAC/B,0CAA0C;IAC1C,mDAA6B,CAAA;AACjC,CAAC,EAXW,kBAAkB,KAAlB,kBAAkB,QAW7B"} -------------------------------------------------------------------------------- /Server/wwwroot/src/Enums/HubConnectionState.ts: -------------------------------------------------------------------------------- 1 | export enum HubConnectionState { 2 | /** The hub connection is disconnected. */ 3 | Disconnected = "Disconnected", 4 | /** The hub connection is connecting. */ 5 | Connecting = "Connecting", 6 | /** The hub connection is connected. */ 7 | Connected = "Connected", 8 | /** The hub connection is disconnecting. */ 9 | Disconnecting = "Disconnecting", 10 | /** The hub connection is reconnecting. */ 11 | Reconnecting = "Reconnecting", 12 | } -------------------------------------------------------------------------------- /Server/wwwroot/src/Enums/RemoteControlMode.js: -------------------------------------------------------------------------------- 1 | export var RemoteControlMode; 2 | (function (RemoteControlMode) { 3 | RemoteControlMode[RemoteControlMode["Unknown"] = 0] = "Unknown"; 4 | RemoteControlMode[RemoteControlMode["Unattended"] = 1] = "Unattended"; 5 | RemoteControlMode[RemoteControlMode["Attended"] = 2] = "Attended"; 6 | })(RemoteControlMode || (RemoteControlMode = {})); 7 | //# sourceMappingURL=RemoteControlMode.js.map -------------------------------------------------------------------------------- /Server/wwwroot/src/Enums/RemoteControlMode.js.map: -------------------------------------------------------------------------------- 1 | {"version":3,"file":"RemoteControlMode.js","sourceRoot":"","sources":["RemoteControlMode.ts"],"names":[],"mappings":"AAAA,MAAM,CAAN,IAAY,iBAIX;AAJD,WAAY,iBAAiB;IACzB,+DAAO,CAAA;IACP,qEAAU,CAAA;IACV,iEAAQ,CAAA;AACZ,CAAC,EAJW,iBAAiB,KAAjB,iBAAiB,QAI5B"} -------------------------------------------------------------------------------- /Server/wwwroot/src/Enums/RemoteControlMode.ts: -------------------------------------------------------------------------------- 1 | export enum RemoteControlMode { 2 | Unknown, 3 | Unattended, 4 | Attended 5 | } -------------------------------------------------------------------------------- /Server/wwwroot/src/Enums/WindowsSessionType.js: -------------------------------------------------------------------------------- 1 | export var WindowsSessionType; 2 | (function (WindowsSessionType) { 3 | WindowsSessionType[WindowsSessionType["Console"] = 1] = "Console"; 4 | WindowsSessionType[WindowsSessionType["RDP"] = 2] = "RDP"; 5 | })(WindowsSessionType || (WindowsSessionType = {})); 6 | //# sourceMappingURL=WindowsSessionType.js.map -------------------------------------------------------------------------------- /Server/wwwroot/src/Enums/WindowsSessionType.js.map: -------------------------------------------------------------------------------- 1 | {"version":3,"file":"WindowsSessionType.js","sourceRoot":"","sources":["WindowsSessionType.ts"],"names":[],"mappings":"AAAA,MAAM,CAAN,IAAY,kBAGX;AAHD,WAAY,kBAAkB;IAC1B,iEAAW,CAAA;IACX,yDAAO,CAAA;AACX,CAAC,EAHW,kBAAkB,KAAlB,kBAAkB,QAG7B"} -------------------------------------------------------------------------------- /Server/wwwroot/src/Enums/WindowsSessionType.ts: -------------------------------------------------------------------------------- 1 | export enum WindowsSessionType { 2 | Console = 1, 3 | RDP = 2 4 | } -------------------------------------------------------------------------------- /Server/wwwroot/src/Interfaces/MessagePack.js: -------------------------------------------------------------------------------- 1 | export {}; 2 | //# sourceMappingURL=MessagePack.js.map -------------------------------------------------------------------------------- /Server/wwwroot/src/Interfaces/MessagePack.js.map: -------------------------------------------------------------------------------- 1 | {"version":3,"file":"MessagePack.js","sourceRoot":"","sources":["MessagePack.ts"],"names":[],"mappings":""} -------------------------------------------------------------------------------- /Server/wwwroot/src/Interfaces/MessagePack.ts: -------------------------------------------------------------------------------- 1 | export interface MessagePack { 2 | encode(item: T): Uint8Array; 3 | decode(message: Uint8Array) : T; 4 | decode(message: ArrayBuffer) : T; 5 | } -------------------------------------------------------------------------------- /Server/wwwroot/src/Interfaces/Settings.js: -------------------------------------------------------------------------------- 1 | export {}; 2 | //# sourceMappingURL=Settings.js.map -------------------------------------------------------------------------------- /Server/wwwroot/src/Interfaces/Settings.js.map: -------------------------------------------------------------------------------- 1 | {"version":3,"file":"Settings.js","sourceRoot":"","sources":["Settings.ts"],"names":[],"mappings":""} -------------------------------------------------------------------------------- /Server/wwwroot/src/Interfaces/Settings.ts: -------------------------------------------------------------------------------- 1 | import { RemoteControlViewerOptions } from "./Dtos.js"; 2 | 3 | export interface Settings { 4 | DisplayName: string; 5 | ViewerOptions: RemoteControlViewerOptions; 6 | } -------------------------------------------------------------------------------- /Server/wwwroot/src/Models/CursorInfo.js: -------------------------------------------------------------------------------- 1 | export {}; 2 | //# sourceMappingURL=CursorInfo.js.map -------------------------------------------------------------------------------- /Server/wwwroot/src/Models/CursorInfo.js.map: -------------------------------------------------------------------------------- 1 | {"version":3,"file":"CursorInfo.js","sourceRoot":"","sources":["CursorInfo.ts"],"names":[],"mappings":""} -------------------------------------------------------------------------------- /Server/wwwroot/src/Models/CursorInfo.ts: -------------------------------------------------------------------------------- 1 | import { Point } from "./Point"; 2 | 3 | export interface CursorInfo { 4 | ImageBytes: Uint8Array; 5 | HotSpot: Point; 6 | CssOverride: string; 7 | } -------------------------------------------------------------------------------- /Server/wwwroot/src/Models/HubConnection.js: -------------------------------------------------------------------------------- 1 | export {}; 2 | //# sourceMappingURL=HubConnection.js.map -------------------------------------------------------------------------------- /Server/wwwroot/src/Models/HubConnection.js.map: -------------------------------------------------------------------------------- 1 | {"version":3,"file":"HubConnection.js","sourceRoot":"","sources":["HubConnection.ts"],"names":[],"mappings":""} -------------------------------------------------------------------------------- /Server/wwwroot/src/Models/HubConnection.ts: -------------------------------------------------------------------------------- 1 | import { HubConnectionState } from "../Enums/HubConnectionState.js"; 2 | import { IStreamResult } from "../Stream.js"; 3 | 4 | export type HubConnection = { 5 | start: () => Promise; 6 | onclose: (callback: () => any) => any; 7 | state: HubConnectionState; 8 | invoke(...rest): Promise; 9 | send(...rest): Promise; 10 | stop(): Promise; 11 | stream(methodName: string, ...args: any[]): IStreamResult; 12 | } 13 | -------------------------------------------------------------------------------- /Server/wwwroot/src/Models/Point.js: -------------------------------------------------------------------------------- 1 | export {}; 2 | //# sourceMappingURL=Point.js.map -------------------------------------------------------------------------------- /Server/wwwroot/src/Models/Point.js.map: -------------------------------------------------------------------------------- 1 | {"version":3,"file":"Point.js","sourceRoot":"","sources":["Point.ts"],"names":[],"mappings":""} -------------------------------------------------------------------------------- /Server/wwwroot/src/Models/Point.ts: -------------------------------------------------------------------------------- 1 | export interface Point { 2 | X: number; 3 | Y: number; 4 | IsEmpty: boolean; 5 | } -------------------------------------------------------------------------------- /Server/wwwroot/src/Models/RemoteControlTarget.js: -------------------------------------------------------------------------------- 1 | export class RemoteControlTarget { 2 | } 3 | //# sourceMappingURL=RemoteControlTarget.js.map -------------------------------------------------------------------------------- /Server/wwwroot/src/Models/RemoteControlTarget.js.map: -------------------------------------------------------------------------------- 1 | {"version":3,"file":"RemoteControlTarget.js","sourceRoot":"","sources":["RemoteControlTarget.ts"],"names":[],"mappings":"AAAA,MAAM,OAAO,mBAAmB;CAG/B"} -------------------------------------------------------------------------------- /Server/wwwroot/src/Models/RemoteControlTarget.ts: -------------------------------------------------------------------------------- 1 | export class RemoteControlTarget { 2 | ServiceConnectionId: string; 3 | ViewOnlyMode: boolean; 4 | } -------------------------------------------------------------------------------- /Server/wwwroot/src/Models/Result.js: -------------------------------------------------------------------------------- 1 | export {}; 2 | //# sourceMappingURL=Result.js.map -------------------------------------------------------------------------------- /Server/wwwroot/src/Models/Result.js.map: -------------------------------------------------------------------------------- 1 | {"version":3,"file":"Result.js","sourceRoot":"","sources":["Result.ts"],"names":[],"mappings":""} -------------------------------------------------------------------------------- /Server/wwwroot/src/Models/Result.ts: -------------------------------------------------------------------------------- 1 | export interface Result { 2 | HadException: boolean; 3 | IsSuccess: boolean; 4 | Reason: string; 5 | Value?: T; 6 | } -------------------------------------------------------------------------------- /Server/wwwroot/src/Models/StreamingState.js: -------------------------------------------------------------------------------- 1 | export class StreamingState { 2 | constructor() { 3 | this.Buffer = new Blob(); 4 | this.ReceivedChunks = []; 5 | this.StreamEnded = false; 6 | } 7 | } 8 | //# sourceMappingURL=StreamingState.js.map -------------------------------------------------------------------------------- /Server/wwwroot/src/Models/StreamingState.js.map: -------------------------------------------------------------------------------- 1 | {"version":3,"file":"StreamingState.js","sourceRoot":"","sources":["StreamingState.ts"],"names":[],"mappings":"AAAA,MAAM,OAAO,cAAc;IACvB;QACI,IAAI,CAAC,MAAM,GAAG,IAAI,IAAI,EAAE,CAAC;QACzB,IAAI,CAAC,cAAc,GAAG,EAAE,CAAC;QACzB,IAAI,CAAC,WAAW,GAAG,KAAK,CAAC;IAC7B,CAAC;CAKJ"} -------------------------------------------------------------------------------- /Server/wwwroot/src/Models/StreamingState.ts: -------------------------------------------------------------------------------- 1 | export class StreamingState { 2 | constructor() { 3 | this.Buffer = new Blob(); 4 | this.ReceivedChunks = []; 5 | this.StreamEnded = false; 6 | } 7 | 8 | Buffer: Blob; 9 | ReceivedChunks: Uint8Array[]; 10 | StreamEnded: boolean; 11 | } -------------------------------------------------------------------------------- /Server/wwwroot/src/Models/UserOptions.js: -------------------------------------------------------------------------------- 1 | export {}; 2 | //# sourceMappingURL=UserOptions.js.map -------------------------------------------------------------------------------- /Server/wwwroot/src/Models/UserOptions.js.map: -------------------------------------------------------------------------------- 1 | {"version":3,"file":"UserOptions.js","sourceRoot":"","sources":["UserOptions.ts"],"names":[],"mappings":""} -------------------------------------------------------------------------------- /Server/wwwroot/src/Models/UserOptions.ts: -------------------------------------------------------------------------------- 1 | export interface UserOptions { 2 | ID: string; 3 | ConsolePrompt: string; 4 | CommandModeShortcutWeb: string; 5 | CommandModeShortcutPSCore: string; 6 | CommandModeShortcutWinPS: string; 7 | CommandModeShortcutCMD: string; 8 | CommandModeShortcutBash: string; 9 | } -------------------------------------------------------------------------------- /Server/wwwroot/src/Models/WindowsSession.js: -------------------------------------------------------------------------------- 1 | export class WindowsSession { 2 | } 3 | //# sourceMappingURL=WindowsSession.js.map -------------------------------------------------------------------------------- /Server/wwwroot/src/Models/WindowsSession.js.map: -------------------------------------------------------------------------------- 1 | {"version":3,"file":"WindowsSession.js","sourceRoot":"","sources":["WindowsSession.ts"],"names":[],"mappings":"AAEA,MAAM,OAAO,cAAc;CAK1B"} -------------------------------------------------------------------------------- /Server/wwwroot/src/Models/WindowsSession.ts: -------------------------------------------------------------------------------- 1 | import { WindowsSessionType } from "../Enums/WindowsSessionType.js"; 2 | 3 | export class WindowsSession { 4 | ID: number; 5 | Type: WindowsSessionType; 6 | Name: string; 7 | Username: string; 8 | } -------------------------------------------------------------------------------- /Server/wwwroot/src/SettingsService.js: -------------------------------------------------------------------------------- 1 | const defaultSettings = { 2 | DisplayName: "", 3 | ViewerOptions: { 4 | ShouldRecordSession: false 5 | } 6 | }; 7 | export function GetSettings() { 8 | try { 9 | var settings = localStorage.getItem("Viewer_Settings"); 10 | if (settings) { 11 | return JSON.parse(settings); 12 | } 13 | } 14 | catch (ex) { 15 | console.error(ex); 16 | } 17 | SetSettings(defaultSettings); 18 | return defaultSettings; 19 | } 20 | export function SetSettings(settings) { 21 | localStorage.setItem("Viewer_Settings", JSON.stringify(settings)); 22 | } 23 | //# sourceMappingURL=SettingsService.js.map -------------------------------------------------------------------------------- /Server/wwwroot/src/SettingsService.js.map: -------------------------------------------------------------------------------- 1 | {"version":3,"file":"SettingsService.js","sourceRoot":"","sources":["SettingsService.ts"],"names":[],"mappings":"AAGA,MAAM,eAAe,GAAG;IACpB,WAAW,EAAE,EAAE;IACf,aAAa,EAAE;QACX,mBAAmB,EAAE,KAAK;KACC;CACtB,CAAC;AAGd,MAAM,UAAU,WAAW;IACvB,IAAI,CAAC;QACD,IAAI,QAAQ,GAAG,YAAY,CAAC,OAAO,CAAC,iBAAiB,CAAC,CAAC;QACvD,IAAI,QAAQ,EAAE,CAAC;YACX,OAAO,IAAI,CAAC,KAAK,CAAC,QAAQ,CAAC,CAAC;QAChC,CAAC;IACL,CAAC;IACD,OAAO,EAAE,EAAE,CAAC;QACR,OAAO,CAAC,KAAK,CAAC,EAAE,CAAC,CAAC;IACtB,CAAC;IAED,WAAW,CAAC,eAAe,CAAC,CAAC;IAC7B,OAAO,eAAe,CAAC;AAC3B,CAAC;AAED,MAAM,UAAU,WAAW,CAAC,QAAkB;IAC1C,YAAY,CAAC,OAAO,CAAC,iBAAiB,EAAE,IAAI,CAAC,SAAS,CAAC,QAAQ,CAAC,CAAC,CAAC;AACtE,CAAC"} -------------------------------------------------------------------------------- /Server/wwwroot/src/SettingsService.ts: -------------------------------------------------------------------------------- 1 | import { RemoteControlViewerOptions } from "./Interfaces/Dtos.js"; 2 | import { Settings } from "./Interfaces/Settings.js"; 3 | 4 | const defaultSettings = { 5 | DisplayName: "", 6 | ViewerOptions: { 7 | ShouldRecordSession: false 8 | } as RemoteControlViewerOptions 9 | } as Settings; 10 | 11 | 12 | export function GetSettings(): Settings { 13 | try { 14 | var settings = localStorage.getItem("Viewer_Settings"); 15 | if (settings) { 16 | return JSON.parse(settings); 17 | } 18 | } 19 | catch (ex) { 20 | console.error(ex); 21 | } 22 | 23 | SetSettings(defaultSettings); 24 | return defaultSettings; 25 | } 26 | 27 | export function SetSettings(settings: Settings) { 28 | localStorage.setItem("Viewer_Settings", JSON.stringify(settings)); 29 | } -------------------------------------------------------------------------------- /Server/wwwroot/src/Stream.js: -------------------------------------------------------------------------------- 1 | // Licensed to the .NET Foundation under one or more agreements. 2 | // The .NET Foundation licenses this file to you under the MIT license. 3 | export {}; 4 | //# sourceMappingURL=Stream.js.map -------------------------------------------------------------------------------- /Server/wwwroot/src/Stream.js.map: -------------------------------------------------------------------------------- 1 | {"version":3,"file":"Stream.js","sourceRoot":"","sources":["Stream.ts"],"names":[],"mappings":"AAAA,gEAAgE;AAChE,uEAAuE"} -------------------------------------------------------------------------------- /Server/wwwroot/src/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "noImplicitAny": false, 4 | "noEmitOnError": true, 5 | "removeComments": false, 6 | "sourceMap": true, 7 | "target": "es2017", 8 | "module": "ESNext", 9 | "allowJs": false, 10 | "moduleResolution": "Node" 11 | }, 12 | "exclude": [ 13 | "node_modules", 14 | "obj", 15 | "bin" 16 | ], 17 | "compileOnSave": true 18 | } 19 | -------------------------------------------------------------------------------- /Shared/AppConstants.cs: -------------------------------------------------------------------------------- 1 | namespace Remotely.Shared; 2 | 3 | public class AppConstants 4 | { 5 | public const string DefaultProductName = "Remotely"; 6 | public const string DefaultPublisherName = "Immense Networks"; 7 | public const string DebugOrgId = "e8f4ad87-4a4b-4da1-bcb2-1788eaeb80e8"; 8 | public const int EmbeddedDataBlockLength = 256; 9 | public const long MaxUploadFileSize = 100_000_000; 10 | public const double ScriptRunExpirationMinutes = 30; 11 | public const string ApiKeyHeaderName = "X-Api-Key"; 12 | public const string ExpiringTokenHeaderName = "X-Expiring-Token"; 13 | } 14 | -------------------------------------------------------------------------------- /Shared/Attributes/SortableAttribute.cs: -------------------------------------------------------------------------------- 1 | namespace Remotely.Shared.Attributes; 2 | 3 | [AttributeUsage(AttributeTargets.Property)] 4 | public class SortableAttribute : Attribute 5 | { 6 | } 7 | -------------------------------------------------------------------------------- /Shared/Dtos/ScriptResultDto.cs: -------------------------------------------------------------------------------- 1 | using Remotely.Shared.DtoEntityBases; 2 | 3 | namespace Remotely.Shared.Dtos; 4 | 5 | public class ScriptResultDto : ScriptResultBase 6 | { 7 | 8 | } 9 | -------------------------------------------------------------------------------- /Shared/Dtos/ScriptResultResponse.cs: -------------------------------------------------------------------------------- 1 | namespace Remotely.Shared.Dtos; 2 | public class ScriptResultResponse 3 | { 4 | public required string Id { get; init; } 5 | } 6 | -------------------------------------------------------------------------------- /Shared/Entities/Alert.cs: -------------------------------------------------------------------------------- 1 | using System.ComponentModel.DataAnnotations; 2 | using System.ComponentModel.DataAnnotations.Schema; 3 | using System.Text.Json.Serialization; 4 | 5 | namespace Remotely.Shared.Entities; 6 | 7 | public class Alert 8 | { 9 | [Key] 10 | [DatabaseGenerated(DatabaseGeneratedOption.Identity)] 11 | public string ID { get; set; } = null!; 12 | 13 | public DateTimeOffset CreatedOn { get; set; } = DateTimeOffset.Now; 14 | 15 | [JsonIgnore] 16 | public Device? Device { get; set; } 17 | public string DeviceID { get; set; } = null!; 18 | 19 | public string? Message { get; set; } 20 | 21 | [JsonIgnore] 22 | public Organization? Organization { get; set; } 23 | 24 | public string OrganizationID { get; set; } = null!; 25 | 26 | [JsonIgnore] 27 | public RemotelyUser? User { get; set; } 28 | public string UserID { get; set; } = null!; 29 | public string? Details { get; set; } 30 | } 31 | -------------------------------------------------------------------------------- /Shared/Entities/ApiToken.cs: -------------------------------------------------------------------------------- 1 | using System.ComponentModel.DataAnnotations; 2 | using System.ComponentModel.DataAnnotations.Schema; 3 | using System.Text.Json.Serialization; 4 | 5 | namespace Remotely.Shared.Entities; 6 | 7 | public class ApiToken 8 | { 9 | [Key] 10 | [DatabaseGenerated(DatabaseGeneratedOption.Identity)] 11 | public string ID { get; set; } = null!; 12 | 13 | public DateTimeOffset? LastUsed { get; set; } 14 | 15 | [StringLength(200)] 16 | public string? Name { get; set; } 17 | 18 | [JsonIgnore] 19 | public Organization? Organization { get; set; } 20 | 21 | public string OrganizationID { get; set; } = null!; 22 | public string? Secret { get; set; } 23 | } 24 | -------------------------------------------------------------------------------- /Shared/Entities/BrandingInfo.cs: -------------------------------------------------------------------------------- 1 | #nullable enable 2 | using System.ComponentModel.DataAnnotations; 3 | using System.ComponentModel.DataAnnotations.Schema; 4 | using System.Text.Json.Serialization; 5 | 6 | namespace Remotely.Shared.Entities; 7 | 8 | public class BrandingInfo 9 | { 10 | public static BrandingInfo Default => new(); 11 | 12 | public byte[] Icon { get; set; } = []; 13 | 14 | [Key] 15 | [DatabaseGenerated(DatabaseGeneratedOption.Identity)] 16 | public string Id { get; set; } = null!; 17 | 18 | [JsonIgnore] 19 | public Organization? Organization { get; set; } 20 | 21 | public string OrganizationId { get; set; } = null!; 22 | 23 | [StringLength(25)] 24 | public string Product { get; set; } = "Remote Control"; 25 | } 26 | -------------------------------------------------------------------------------- /Shared/Entities/DeviceGroup.cs: -------------------------------------------------------------------------------- 1 | using System.ComponentModel.DataAnnotations; 2 | using System.ComponentModel.DataAnnotations.Schema; 3 | using System.Text.Json.Serialization; 4 | 5 | namespace Remotely.Shared.Entities; 6 | 7 | public class DeviceGroup 8 | { 9 | [StringLength(200)] 10 | public required string Name { get; set; } 11 | 12 | [Key] 13 | [DatabaseGenerated(DatabaseGeneratedOption.Identity)] 14 | public string ID { get; set; } = null!; 15 | 16 | [JsonIgnore] 17 | public List Devices { get; set; } = new(); 18 | 19 | [JsonIgnore] 20 | public Organization? Organization { get; set; } 21 | 22 | public string OrganizationID { get; set; } = null!; 23 | 24 | [JsonIgnore] 25 | public List Users { get; set; } = new(); 26 | 27 | [JsonIgnore] 28 | public List? ScriptSchedules { get; set; } 29 | } 30 | -------------------------------------------------------------------------------- /Shared/Entities/InviteLink.cs: -------------------------------------------------------------------------------- 1 | using System.ComponentModel.DataAnnotations; 2 | using System.ComponentModel.DataAnnotations.Schema; 3 | using System.Text.Json.Serialization; 4 | 5 | namespace Remotely.Shared.Entities; 6 | 7 | public class InviteLink 8 | { 9 | [Key] 10 | [DatabaseGenerated(DatabaseGeneratedOption.Identity)] 11 | public string ID { get; set; } = null!; 12 | public string? InvitedUser { get; set; } 13 | public bool IsAdmin { get; set; } 14 | public DateTimeOffset DateSent { get; set; } 15 | [JsonIgnore] 16 | public Organization? Organization { get; set; } 17 | public string OrganizationID { get; set; } = null!; 18 | public string? ResetUrl { get; set; } 19 | } 20 | -------------------------------------------------------------------------------- /Shared/Entities/KeyValueRecord.cs: -------------------------------------------------------------------------------- 1 | using System.ComponentModel.DataAnnotations; 2 | 3 | namespace Remotely.Shared.Entities; 4 | 5 | public class KeyValueRecord 6 | { 7 | [Key] 8 | public Guid Key { get; set; } 9 | public string? Value { get; set; } 10 | } 11 | -------------------------------------------------------------------------------- /Shared/Entities/RemotelyUser.cs: -------------------------------------------------------------------------------- 1 | using Microsoft.AspNetCore.Identity; 2 | using Remotely.Shared.Models; 3 | using System.Text.Json.Serialization; 4 | 5 | namespace Remotely.Shared.Entities; 6 | 7 | public class RemotelyUser : IdentityUser 8 | { 9 | public ICollection Alerts { get; set; } = new List(); 10 | 11 | public List DeviceGroups { get; set; } = new(); 12 | public bool IsAdministrator { get; set; } 13 | public bool IsServerAdmin { get; set; } 14 | 15 | [JsonIgnore] 16 | public Organization? Organization { get; set; } 17 | 18 | public string OrganizationID { get; set; } = null!; 19 | 20 | public List SavedScripts { get; set; } = new(); 21 | public List ScriptSchedules { get; set; } = new(); 22 | 23 | public string? TempPassword { get; set; } 24 | 25 | public RemotelyUserOptions? UserOptions { get; set; } 26 | } 27 | -------------------------------------------------------------------------------- /Shared/Entities/ScriptResult.cs: -------------------------------------------------------------------------------- 1 | using Remotely.Shared.DtoEntityBases; 2 | using System.ComponentModel.DataAnnotations; 3 | using System.ComponentModel.DataAnnotations.Schema; 4 | using System.Runtime.Serialization; 5 | using System.Text.Json.Serialization; 6 | 7 | namespace Remotely.Shared.Entities; 8 | 9 | public class ScriptResult : ScriptResultBase 10 | { 11 | [JsonIgnore] 12 | public Device? Device { get; set; } 13 | 14 | [Key] 15 | [DatabaseGenerated(DatabaseGeneratedOption.Identity)] 16 | public string ID { get; set; } = null!; 17 | 18 | [JsonIgnore] 19 | [IgnoreDataMember] 20 | public Organization? Organization { get; set; } 21 | public required string OrganizationID { get; set; } 22 | 23 | [JsonIgnore] 24 | public SavedScript? SavedScript { get; set; } 25 | 26 | [JsonIgnore] 27 | public ScriptSchedule? Schedule { get; set; } 28 | 29 | [JsonIgnore] 30 | public ScriptRun? ScriptRun { get; set; } 31 | } 32 | -------------------------------------------------------------------------------- /Shared/Entities/SharedFile.cs: -------------------------------------------------------------------------------- 1 | using System.ComponentModel.DataAnnotations; 2 | using System.ComponentModel.DataAnnotations.Schema; 3 | 4 | namespace Remotely.Shared.Entities; 5 | 6 | public class SharedFile 7 | { 8 | [Key] 9 | [DatabaseGenerated(DatabaseGeneratedOption.Identity)] 10 | public string ID { get; set; } = null!; 11 | public string? FileName { get; set; } 12 | public string? ContentType { get; set; } 13 | public byte[] FileContents { get; set; } = Array.Empty(); 14 | public DateTimeOffset Timestamp { get; set; } = DateTimeOffset.Now; 15 | public Organization? Organization { get; set; } 16 | public string? OrganizationID { get; set; } 17 | } 18 | -------------------------------------------------------------------------------- /Shared/Enums/ChatHistoryItemOrigin.cs: -------------------------------------------------------------------------------- 1 | namespace Remotely.Shared.Enums; 2 | 3 | public enum ChatHistoryItemOrigin 4 | { 5 | System, 6 | Self, 7 | Device 8 | } 9 | -------------------------------------------------------------------------------- /Shared/Enums/CompletionIntent.cs: -------------------------------------------------------------------------------- 1 | namespace Remotely.Shared.Enums; 2 | 3 | public enum CompletionIntent 4 | { 5 | ShowAll, 6 | NextResult 7 | } 8 | -------------------------------------------------------------------------------- /Shared/Enums/DbProvider.cs: -------------------------------------------------------------------------------- 1 | namespace Remotely.Shared.Enums; 2 | 3 | 4 | public enum DbProvider 5 | { 6 | PostgreSQL, 7 | SQLite, 8 | SQLServer 9 | } 10 | -------------------------------------------------------------------------------- /Shared/Enums/EventType.cs: -------------------------------------------------------------------------------- 1 | namespace Remotely.Shared.Enums; 2 | 3 | public enum EventType 4 | { 5 | Info = 0, 6 | Error = 1, 7 | Debug = 2, 8 | Warning = 3 9 | } 10 | -------------------------------------------------------------------------------- /Shared/Enums/Platform.cs: -------------------------------------------------------------------------------- 1 | namespace Remotely.Shared.Enums; 2 | 3 | public enum Platform 4 | { 5 | Windows, 6 | Linux, 7 | MacOS, 8 | Unknown 9 | } 10 | -------------------------------------------------------------------------------- /Shared/Enums/PromptForAccessResult.cs: -------------------------------------------------------------------------------- 1 | namespace Remotely.Shared.Enums; 2 | 3 | public enum PromptForAccessResult 4 | { 5 | None, 6 | Accepted, 7 | Denied, 8 | Error, 9 | TimedOut, 10 | } 11 | -------------------------------------------------------------------------------- /Shared/Enums/RepeatInterval.cs: -------------------------------------------------------------------------------- 1 | namespace Remotely.Shared.Enums; 2 | 3 | public enum RepeatInterval 4 | { 5 | Hourly, 6 | Daily, 7 | Weekly, 8 | Monthly 9 | } 10 | -------------------------------------------------------------------------------- /Shared/Enums/ScriptInputType.cs: -------------------------------------------------------------------------------- 1 | namespace Remotely.Shared.Enums; 2 | 3 | public enum ScriptInputType 4 | { 5 | Terminal, 6 | OneTimeScript, 7 | ScheduledScript, 8 | Api 9 | } 10 | -------------------------------------------------------------------------------- /Shared/Enums/ScriptingShell.cs: -------------------------------------------------------------------------------- 1 | namespace Remotely.Shared.Enums; 2 | 3 | public enum ScriptingShell 4 | { 5 | PSCore, 6 | WinPS, 7 | Bash, 8 | CMD 9 | } 10 | -------------------------------------------------------------------------------- /Shared/Enums/SessionEndReasonsEx.cs: -------------------------------------------------------------------------------- 1 | namespace Remotely.Shared.Enums; 2 | 3 | public enum SessionEndReasonsEx 4 | { 5 | Logoff = 1, 6 | SystemShutdown = 2 7 | } 8 | -------------------------------------------------------------------------------- /Shared/Enums/SessionSwitchReasonEx.cs: -------------------------------------------------------------------------------- 1 | namespace Remotely.Shared.Enums; 2 | 3 | public enum SessionSwitchReasonEx 4 | { 5 | ConsoleConnect = 1, 6 | ConsoleDisconnect = 2, 7 | RemoteConnect = 3, 8 | RemoteDisconnect = 4, 9 | SessionLogon = 5, 10 | SessionLogoff = 6, 11 | SessionLock = 7, 12 | SessionUnlock = 8, 13 | SessionRemoteControl = 9 14 | } 15 | -------------------------------------------------------------------------------- /Shared/Enums/Theme.cs: -------------------------------------------------------------------------------- 1 | namespace Remotely.Shared.Enums; 2 | 3 | public enum Theme 4 | { 5 | Dark, 6 | Light 7 | } 8 | -------------------------------------------------------------------------------- /Shared/Extensions/DeviceExtensions.cs: -------------------------------------------------------------------------------- 1 | using Remotely.Shared.Dtos; 2 | using Remotely.Shared.Entities; 3 | using System.Runtime.Serialization; 4 | using System.Text.Json; 5 | 6 | namespace Remotely.Shared.Extensions; 7 | 8 | public static class DeviceExtensions 9 | { 10 | private static JsonSerializerOptions _serializerOptions = new() 11 | { 12 | PropertyNameCaseInsensitive = true 13 | }; 14 | 15 | /// 16 | /// A helper method for creating a DeviceClientDto from a Device entity. 17 | /// 18 | /// 19 | /// 20 | public static DeviceClientDto ToDto(this Device device) 21 | { 22 | var json = JsonSerializer.Serialize(device, _serializerOptions); 23 | var dto = JsonSerializer.Deserialize(json, _serializerOptions); 24 | return dto ?? throw new SerializationException("Failed to create DTO."); 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /Shared/Extensions/IEnumerableExtensions.cs: -------------------------------------------------------------------------------- 1 | namespace Remotely.Shared.Extensions; 2 | 3 | public static class IEnumerableExtensions 4 | { 5 | public static async IAsyncEnumerable ToAsyncEnumerable(this IEnumerable source) 6 | { 7 | foreach (var item in source) 8 | { 9 | yield return item; 10 | await Task.Yield(); 11 | } 12 | } 13 | 14 | public static int IndexWhere(this IEnumerable source, Func predicate) 15 | { 16 | var index = 0; 17 | foreach (var item in source) 18 | { 19 | if (predicate(item)) 20 | { 21 | return index; 22 | } 23 | index++; 24 | } 25 | return -1; 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /Shared/Extensions/StreamExtensions.cs: -------------------------------------------------------------------------------- 1 | namespace Remotely.Shared.Extensions; 2 | 3 | public static class StreamExtensions 4 | { 5 | public static async Task CopyToAsync(this Stream source, Stream destination, Action bytesReadCallback) 6 | { 7 | var buffer = new byte[64_000]; 8 | var totalRead = 0; 9 | 10 | int bytesRead; 11 | 12 | while ((bytesRead = await source.ReadAsync(buffer)) != 0) 13 | { 14 | await destination.WriteAsync(buffer.AsMemory(0, bytesRead)); 15 | totalRead += bytesRead; 16 | bytesReadCallback.Invoke(totalRead); 17 | } 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /Shared/Helpers/Disposer.cs: -------------------------------------------------------------------------------- 1 | namespace Remotely.Shared.Helpers; 2 | 3 | public static class Disposer 4 | { 5 | public static void TryDisposeAll(params IDisposable[] disposables) 6 | { 7 | if (disposables is null) 8 | { 9 | return; 10 | } 11 | 12 | foreach (var disposable in disposables) 13 | { 14 | try 15 | { 16 | disposable?.Dispose(); 17 | } 18 | catch { } 19 | } 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /Shared/Helpers/RandomGenerator.cs: -------------------------------------------------------------------------------- 1 | using System.Security.Cryptography; 2 | 3 | namespace Remotely.Shared.Helpers; 4 | 5 | public class RandomGenerator 6 | { 7 | private const string AllowableCharacters = "abcdefghijklmnopqrstuvwxyzABCDEFGHIGKLMNOPQRSTUVWXYZ0123456789"; 8 | 9 | public static string GenerateString(int length) 10 | { 11 | var bytes = RandomNumberGenerator.GetBytes(length); 12 | return new string(bytes.Select(x => AllowableCharacters[x % AllowableCharacters.Length]).ToArray()); 13 | } 14 | 15 | public static string GenerateAccessKey() 16 | { 17 | return GenerateString(64); 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /Shared/Helpers/WaitHelper.cs: -------------------------------------------------------------------------------- 1 | using System.Diagnostics; 2 | 3 | namespace Remotely.Shared.Helpers; 4 | 5 | public static class WaitHelper 6 | { 7 | public static bool WaitFor(Func condition, TimeSpan timeout, int pollingMs = 10) 8 | { 9 | var sw = Stopwatch.StartNew(); 10 | while (!condition() && sw.Elapsed < timeout) 11 | { 12 | Thread.Sleep(pollingMs); 13 | } 14 | return condition(); 15 | } 16 | 17 | public static async Task WaitForAsync(Func condition, TimeSpan timeout, int pollingMs = 10) 18 | { 19 | var sw = Stopwatch.StartNew(); 20 | while (!condition() && sw.Elapsed < timeout) 21 | { 22 | await Task.Delay(pollingMs).ConfigureAwait(false); 23 | } 24 | return condition(); 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /Shared/Interfaces/IDesktopHubClient.cs: -------------------------------------------------------------------------------- 1 | using Remotely.Shared.Enums; 2 | using Remotely.Shared.Models; 3 | 4 | namespace Remotely.Shared.Interfaces; 5 | 6 | public interface IDesktopHubClient 7 | { 8 | Task Disconnect(string reason); 9 | 10 | Task GetScreenCast( 11 | string viewerId, 12 | string requesterName, 13 | bool notifyUser, 14 | Guid streamId); 15 | 16 | Task PromptForAccess(RemoteControlAccessRequest accessRequest); 17 | 18 | Task RequestScreenCast( 19 | string viewerId, 20 | string requesterName, 21 | bool notifyUser, 22 | Guid streamId); 23 | 24 | Task SendDtoToClient(byte[] dtoWrapper, string viewerConnectionId); 25 | 26 | Task ViewerDisconnected(string viewerId); 27 | } 28 | -------------------------------------------------------------------------------- /Shared/Interfaces/IViewerHubClient.cs: -------------------------------------------------------------------------------- 1 | namespace Remotely.Shared.Interfaces; 2 | 3 | public interface IViewerHubClient 4 | { 5 | Task ConnectionFailed(); 6 | 7 | Task ConnectionRequestDenied(); 8 | 9 | Task PingViewer(CancellationToken cancellationToken); 10 | 11 | Task ReconnectFailed(); 12 | 13 | Task Reconnecting(); 14 | 15 | Task RelaunchedScreenCasterReady(Guid newSessionId, string newAccessKey); 16 | 17 | Task ScreenCasterDisconnected(); 18 | 19 | Task SendDtoToViewer(byte[] dtoWrapper); 20 | Task ShowMessage(string message); 21 | 22 | Task ViewerRemoved(); 23 | } 24 | -------------------------------------------------------------------------------- /Shared/Models/AlertOptions.cs: -------------------------------------------------------------------------------- 1 | namespace Remotely.Shared.Models; 2 | 3 | public class AlertOptions 4 | { 5 | public required string AlertDeviceID { get; set; } 6 | public required string AlertMessage { get; set; } 7 | public string? ApiRequestBody { get; set; } 8 | public Dictionary ApiRequestHeaders { get; set; } = new(); 9 | public string? ApiRequestMethod { get; set; } 10 | public string? ApiRequestUrl { get; set; } 11 | public string? EmailBody { get; set; } 12 | public string? EmailSubject { get; set; } 13 | public string? EmailTo { get; set; } 14 | public bool ShouldAlert { get; set; } 15 | public bool ShouldEmail { get; set; } 16 | public bool ShouldSendApiRequest { get; set; } 17 | } 18 | -------------------------------------------------------------------------------- /Shared/Models/ChatMessage.cs: -------------------------------------------------------------------------------- 1 | namespace Remotely.Shared.Models; 2 | 3 | public class ChatMessage 4 | { 5 | public ChatMessage() { } 6 | 7 | public ChatMessage(string senderName, string message, bool disconnected = false) 8 | { 9 | SenderName = senderName; 10 | Message = message; 11 | Disconnected = disconnected; 12 | } 13 | 14 | public bool Disconnected { get; set; } 15 | public string Message { get; set; } = string.Empty; 16 | public string SenderName { get; set; } = string.Empty; 17 | } 18 | -------------------------------------------------------------------------------- /Shared/Models/ConnectionInfo.cs: -------------------------------------------------------------------------------- 1 | #nullable enable 2 | namespace Remotely.Shared.Models; 3 | 4 | public class ConnectionInfo 5 | { 6 | private string? _host; 7 | 8 | public string DeviceID { get; set; } = Guid.NewGuid().ToString(); 9 | public string? Host 10 | { 11 | get 12 | { 13 | return _host?.Trim()?.TrimEnd('/'); 14 | } 15 | set 16 | { 17 | _host = value?.Trim()?.TrimEnd('/'); 18 | } 19 | } 20 | public string? OrganizationID { get; set; } 21 | public string? ServerVerificationToken { get; set; } 22 | 23 | } 24 | -------------------------------------------------------------------------------- /Shared/Models/CursorInfo.cs: -------------------------------------------------------------------------------- 1 | using System.Drawing; 2 | 3 | namespace Remotely.Shared.Models; 4 | 5 | public class CursorInfo 6 | { 7 | 8 | public CursorInfo(byte[] imageBytes, Point hotspot, string cssOverride = "") 9 | { 10 | ImageBytes = imageBytes; 11 | HotSpot = hotspot; 12 | CssOverride = cssOverride; 13 | } 14 | 15 | public byte[] ImageBytes { get; set; } 16 | public Point HotSpot { get; set; } 17 | public string CssOverride { get; set; } 18 | } 19 | -------------------------------------------------------------------------------- /Shared/Models/DeviceSetupOptions.cs: -------------------------------------------------------------------------------- 1 | #nullable enable 2 | namespace Remotely.Shared.Models; 3 | 4 | public class DeviceSetupOptions 5 | { 6 | public string? DeviceAlias { get; set; } 7 | public string? DeviceGroupName { get; set; } 8 | public string? DeviceID { get; set; } 9 | public string? OrganizationID { get; set; } 10 | } 11 | -------------------------------------------------------------------------------- /Shared/Models/DisplayInfo.cs: -------------------------------------------------------------------------------- 1 | using System.Drawing; 2 | using System.Numerics; 3 | using System.Runtime.Serialization; 4 | 5 | namespace Remotely.Shared.Models; 6 | 7 | [DataContract] 8 | public class DisplayInfo 9 | { 10 | [DataMember] 11 | public bool IsPrimary { get; set; } 12 | [DataMember] 13 | public Vector2 ScreenSize { get; set; } 14 | [DataMember] 15 | public Rectangle MonitorArea { get; set; } 16 | [DataMember] 17 | public Rectangle WorkArea { get; set; } 18 | [DataMember] 19 | public string DeviceName { get; set; } = string.Empty; 20 | [DataMember] 21 | public IntPtr Hmon { get; set; } 22 | } -------------------------------------------------------------------------------- /Shared/Models/Drive.cs: -------------------------------------------------------------------------------- 1 | namespace Remotely.Shared.Models; 2 | 3 | public class Drive 4 | { 5 | public DriveType DriveType { get; set; } 6 | public string? RootDirectory { get; set; } 7 | public string? Name { get; set; } 8 | public string? DriveFormat { get; set; } 9 | public double FreeSpace { get; set; } 10 | public double TotalSize { get; set; } 11 | public string? VolumeLabel { get; set; } 12 | } 13 | -------------------------------------------------------------------------------- /Shared/Models/Dtos/AudioSampleDto.cs: -------------------------------------------------------------------------------- 1 | using System.Runtime.Serialization; 2 | 3 | namespace Remotely.Shared.Models.Dtos; 4 | 5 | [DataContract] 6 | public class AudioSampleDto 7 | { 8 | public AudioSampleDto(byte[] buffer) 9 | { 10 | Buffer = buffer; 11 | } 12 | 13 | [DataMember(Name = "Buffer")] 14 | public byte[] Buffer { get; } 15 | } 16 | -------------------------------------------------------------------------------- /Shared/Models/Dtos/ClipboardTextDto.cs: -------------------------------------------------------------------------------- 1 | using System.Runtime.Serialization; 2 | 3 | namespace Remotely.Shared.Models.Dtos; 4 | 5 | [DataContract] 6 | public class ClipboardTextDto 7 | { 8 | public ClipboardTextDto(string clipboardText) 9 | { 10 | ClipboardText = clipboardText; 11 | } 12 | 13 | [DataMember(Name = "ClipboardText")] 14 | public string ClipboardText { get; } 15 | } 16 | -------------------------------------------------------------------------------- /Shared/Models/Dtos/CursorChangeDto.cs: -------------------------------------------------------------------------------- 1 | using System.Runtime.Serialization; 2 | 3 | namespace Remotely.Shared.Models.Dtos; 4 | 5 | [DataContract] 6 | public class CursorChangeDto 7 | { 8 | public CursorChangeDto(byte[] imageBytes, int hotSpotX, int hotSpotY, string cssOverride) 9 | { 10 | ImageBytes = imageBytes; 11 | HotSpotX = hotSpotX; 12 | HotSpotY = hotSpotY; 13 | CssOverride = cssOverride; 14 | } 15 | 16 | [DataMember(Name = "CssOverride")] 17 | public string CssOverride { get; } 18 | 19 | [DataMember(Name = "HotSpotX")] 20 | public int HotSpotX { get; } 21 | 22 | [DataMember(Name = "HotSpotY")] 23 | public int HotSpotY { get; } 24 | 25 | [DataMember(Name = "ImageBytes")] 26 | public byte[] ImageBytes { get; } 27 | } 28 | -------------------------------------------------------------------------------- /Shared/Models/Dtos/DtoWrapper.cs: -------------------------------------------------------------------------------- 1 | using System.Runtime.Serialization; 2 | 3 | namespace Remotely.Shared.Models.Dtos; 4 | 5 | [DataContract] 6 | public class DtoWrapper 7 | { 8 | [DataMember] 9 | public byte[] DtoChunk { get; init; } = Array.Empty(); 10 | 11 | [DataMember] 12 | public DtoType DtoType { get; init; } 13 | 14 | [DataMember] 15 | public bool IsFirstChunk { get; init; } 16 | 17 | [DataMember] 18 | public bool IsLastChunk { get; init; } 19 | 20 | [DataMember] 21 | public string RequestId { get; init; } = string.Empty; 22 | 23 | [DataMember] 24 | public string InstanceId { get; init; } = string.Empty; 25 | 26 | [DataMember] 27 | public int SequenceId { get; init; } 28 | } 29 | -------------------------------------------------------------------------------- /Shared/Models/Dtos/EmptyDto.cs: -------------------------------------------------------------------------------- 1 | using System.Runtime.Serialization; 2 | 3 | namespace Remotely.Shared.Models.Dtos; 4 | 5 | [DataContract] 6 | public class EmptyDto 7 | { 8 | } 9 | -------------------------------------------------------------------------------- /Shared/Models/Dtos/FileDto.cs: -------------------------------------------------------------------------------- 1 | using System.Runtime.Serialization; 2 | 3 | namespace Remotely.Shared.Models.Dtos; 4 | 5 | 6 | [DataContract] 7 | public class FileDto 8 | { 9 | [DataMember(Name = "Buffer")] 10 | public byte[] Buffer { get; set; } = Array.Empty(); 11 | 12 | [DataMember(Name = "FileName")] 13 | public string FileName { get; set; } = string.Empty; 14 | 15 | [DataMember(Name = "MessageId")] 16 | public string MessageId { get; set; } = string.Empty; 17 | 18 | [DataMember(Name = "EndOfFile")] 19 | public bool EndOfFile { get; set; } 20 | 21 | [DataMember(Name = "StartOfFile")] 22 | public bool StartOfFile { get; set; } 23 | } 24 | -------------------------------------------------------------------------------- /Shared/Models/Dtos/FrameReceivedDto.cs: -------------------------------------------------------------------------------- 1 | using System.Runtime.Serialization; 2 | 3 | namespace Remotely.Shared.Models.Dtos; 4 | 5 | [DataContract] 6 | public class FrameReceivedDto 7 | { 8 | [DataMember] 9 | public long Timestamp { get; set; } 10 | } 11 | -------------------------------------------------------------------------------- /Shared/Models/Dtos/KeyDownDto.cs: -------------------------------------------------------------------------------- 1 | using System.Runtime.Serialization; 2 | 3 | namespace Remotely.Shared.Models.Dtos; 4 | 5 | [DataContract] 6 | public class KeyDownDto 7 | { 8 | [DataMember(Name = "Key")] 9 | public string Key { get; set; } = string.Empty; 10 | } 11 | -------------------------------------------------------------------------------- /Shared/Models/Dtos/KeyPressDto.cs: -------------------------------------------------------------------------------- 1 | using System.Runtime.Serialization; 2 | 3 | namespace Remotely.Shared.Models.Dtos; 4 | 5 | [DataContract] 6 | public class KeyPressDto 7 | { 8 | [DataMember(Name = "Key")] 9 | public string Key { get; set; } = string.Empty; 10 | } 11 | -------------------------------------------------------------------------------- /Shared/Models/Dtos/KeyUpDto.cs: -------------------------------------------------------------------------------- 1 | using System.Runtime.Serialization; 2 | 3 | namespace Remotely.Shared.Models.Dtos; 4 | 5 | [DataContract] 6 | public class KeyUpDto 7 | { 8 | [DataMember(Name = "Key")] 9 | public string Key { get; set; } = string.Empty; 10 | 11 | } 12 | -------------------------------------------------------------------------------- /Shared/Models/Dtos/MouseDownDto.cs: -------------------------------------------------------------------------------- 1 | using System.Runtime.Serialization; 2 | 3 | namespace Remotely.Shared.Models.Dtos; 4 | 5 | [DataContract] 6 | public class MouseDownDto 7 | { 8 | [DataMember(Name = "Button")] 9 | public int Button { get; set; } 10 | 11 | [DataMember(Name = "PercentX")] 12 | public double PercentX { get; set; } 13 | 14 | [DataMember(Name = "PercentY")] 15 | public double PercentY { get; set; } 16 | } 17 | -------------------------------------------------------------------------------- /Shared/Models/Dtos/MouseMoveDto.cs: -------------------------------------------------------------------------------- 1 | using System.Runtime.Serialization; 2 | 3 | namespace Remotely.Shared.Models.Dtos; 4 | 5 | [DataContract] 6 | public class MouseMoveDto 7 | { 8 | 9 | [DataMember(Name = "PercentX")] 10 | public double PercentX { get; set; } 11 | 12 | [DataMember(Name = "PercentY")] 13 | public double PercentY { get; set; } 14 | } 15 | -------------------------------------------------------------------------------- /Shared/Models/Dtos/MouseUpDto.cs: -------------------------------------------------------------------------------- 1 | using System.Runtime.Serialization; 2 | 3 | namespace Remotely.Shared.Models.Dtos; 4 | 5 | [DataContract] 6 | public class MouseUpDto 7 | { 8 | [DataMember(Name = "Button")] 9 | public int Button { get; set; } 10 | 11 | [DataMember(Name = "PercentX")] 12 | public double PercentX { get; set; } 13 | 14 | [DataMember(Name = "PercentY")] 15 | public double PercentY { get; set; } 16 | } 17 | -------------------------------------------------------------------------------- /Shared/Models/Dtos/MouseWheelDto.cs: -------------------------------------------------------------------------------- 1 | using System.Runtime.Serialization; 2 | 3 | namespace Remotely.Shared.Models.Dtos; 4 | 5 | [DataContract] 6 | public class MouseWheelDto 7 | { 8 | 9 | [DataMember(Name = "DeltaX")] 10 | public double DeltaX { get; set; } 11 | 12 | [DataMember(Name = "DeltaY")] 13 | public double DeltaY { get; set; } 14 | } 15 | -------------------------------------------------------------------------------- /Shared/Models/Dtos/ScreenDataDto.cs: -------------------------------------------------------------------------------- 1 | using System.Runtime.Serialization; 2 | 3 | namespace Remotely.Shared.Models.Dtos; 4 | 5 | [DataContract] 6 | public class ScreenDataDto 7 | { 8 | [DataMember(Name = "DisplayNames")] 9 | public IEnumerable DisplayNames { get; init; } = Enumerable.Empty(); 10 | 11 | [DataMember(Name = "SelectedDisplay")] 12 | public string SelectedDisplay { get; init; } = string.Empty; 13 | 14 | [DataMember(Name = "MachineName")] 15 | public string MachineName { get; init; } = string.Empty; 16 | 17 | [DataMember(Name = "ScreenWidth")] 18 | public int ScreenWidth { get; init; } 19 | 20 | [DataMember(Name = "ScreenHeight")] 21 | public int ScreenHeight { get; init; } 22 | } 23 | -------------------------------------------------------------------------------- /Shared/Models/Dtos/ScreenSizeDto.cs: -------------------------------------------------------------------------------- 1 | using System.Runtime.Serialization; 2 | 3 | namespace Remotely.Shared.Models.Dtos; 4 | 5 | [DataContract] 6 | public class ScreenSizeDto 7 | { 8 | public ScreenSizeDto(int width, int height) 9 | { 10 | Width = width; 11 | Height = height; 12 | } 13 | 14 | [DataMember(Name = "Width")] 15 | public int Width { get; } 16 | 17 | [DataMember(Name = "Height")] 18 | public int Height { get; } 19 | } 20 | -------------------------------------------------------------------------------- /Shared/Models/Dtos/SelectScreenDto.cs: -------------------------------------------------------------------------------- 1 | using System.Runtime.Serialization; 2 | 3 | namespace Remotely.Shared.Models.Dtos; 4 | 5 | [DataContract] 6 | public class SelectScreenDto 7 | { 8 | [DataMember(Name = "DisplayName")] 9 | public string DisplayName { get; set; } = string.Empty; 10 | } 11 | -------------------------------------------------------------------------------- /Shared/Models/Dtos/SessionMetricsDto.cs: -------------------------------------------------------------------------------- 1 | using MessagePack; 2 | using System.Runtime.Serialization; 3 | 4 | namespace Remotely.Shared.Models.Dtos; 5 | 6 | [DataContract] 7 | public class SessionMetricsDto 8 | { 9 | [SerializationConstructor] 10 | public SessionMetricsDto(double mbps, double fps, double roundTripLatency, bool isGpuAccelerated) 11 | { 12 | Mbps = mbps; 13 | Fps = fps; 14 | RoundTripLatency = roundTripLatency; 15 | IsGpuAccelerated = isGpuAccelerated; 16 | } 17 | 18 | [DataMember] 19 | public double Mbps { get; } 20 | 21 | [DataMember] 22 | public double Fps { get; } 23 | 24 | [DataMember] 25 | public double RoundTripLatency { get; } 26 | 27 | [DataMember] 28 | public bool IsGpuAccelerated { get; } 29 | } 30 | -------------------------------------------------------------------------------- /Shared/Models/Dtos/TapDto.cs: -------------------------------------------------------------------------------- 1 | using System.Runtime.Serialization; 2 | 3 | namespace Remotely.Shared.Models.Dtos; 4 | 5 | [DataContract] 6 | public class TapDto 7 | { 8 | 9 | [DataMember(Name = "PercentX")] 10 | public double PercentX { get; set; } 11 | 12 | [DataMember(Name = "PercentY")] 13 | public double PercentY { get; set; } 14 | } 15 | -------------------------------------------------------------------------------- /Shared/Models/Dtos/TextTransferDto.cs: -------------------------------------------------------------------------------- 1 | using System.Runtime.Serialization; 2 | 3 | namespace Remotely.Shared.Models.Dtos; 4 | 5 | [DataContract] 6 | public class TextTransferDto 7 | { 8 | 9 | [DataMember(Name = "Text")] 10 | public string Text { get; set; } = string.Empty; 11 | 12 | [DataMember(Name = "TypeText")] 13 | public bool TypeText { get; set; } 14 | } 15 | -------------------------------------------------------------------------------- /Shared/Models/Dtos/ToggleAudioDto.cs: -------------------------------------------------------------------------------- 1 | using System.Runtime.Serialization; 2 | 3 | namespace Remotely.Shared.Models.Dtos; 4 | 5 | [DataContract] 6 | public class ToggleAudioDto 7 | { 8 | [DataMember(Name = "ToggleOn")] 9 | public bool ToggleOn { get; set; } 10 | } 11 | -------------------------------------------------------------------------------- /Shared/Models/Dtos/ToggleBlockInputDto.cs: -------------------------------------------------------------------------------- 1 | using System.Runtime.Serialization; 2 | 3 | namespace Remotely.Shared.Models.Dtos; 4 | 5 | [DataContract] 6 | public class ToggleBlockInputDto 7 | { 8 | [DataMember(Name = "ToggleOn")] 9 | public bool ToggleOn { get; set; } 10 | } 11 | -------------------------------------------------------------------------------- /Shared/Models/Dtos/WindowsSessionsDto.cs: -------------------------------------------------------------------------------- 1 | using System.Runtime.Serialization; 2 | 3 | namespace Remotely.Shared.Models.Dtos; 4 | 5 | [DataContract] 6 | public class WindowsSessionsDto 7 | { 8 | public WindowsSessionsDto(List windowsSessions) 9 | { 10 | WindowsSessions = windowsSessions; 11 | } 12 | 13 | 14 | [DataMember(Name = "WindowsSessions")] 15 | public List WindowsSessions { get; set; } 16 | } 17 | -------------------------------------------------------------------------------- /Shared/Models/EmbeddedServerData.cs: -------------------------------------------------------------------------------- 1 | using MessagePack; 2 | using System.Runtime.Serialization; 3 | using System.Text.Json.Serialization; 4 | 5 | namespace Remotely.Shared.Models; 6 | 7 | [DataContract] 8 | public class EmbeddedServerData 9 | { 10 | [SerializationConstructor] 11 | [JsonConstructor] 12 | public EmbeddedServerData(Uri serverUrl, string? organizationId) 13 | { 14 | ServerUrl = serverUrl; 15 | OrganizationId = organizationId ?? string.Empty; 16 | } 17 | 18 | [DataMember] 19 | public string OrganizationId { get; } 20 | 21 | [DataMember] 22 | public Uri ServerUrl { get; } 23 | } 24 | -------------------------------------------------------------------------------- /Shared/Models/RemoteControlAccessRequest.cs: -------------------------------------------------------------------------------- 1 | using MessagePack; 2 | using System.Runtime.Serialization; 3 | using System.Text.Json.Serialization; 4 | 5 | namespace Remotely.Shared.Models; 6 | 7 | [DataContract] 8 | public class RemoteControlAccessRequest 9 | { 10 | [JsonConstructor] 11 | [SerializationConstructor] 12 | public RemoteControlAccessRequest(string viewerConnectionId, string requesterDisplayName, string organizationName) 13 | { 14 | ViewerConnectionId = viewerConnectionId; 15 | RequesterDisplayName = requesterDisplayName; 16 | OrganizationName = organizationName; 17 | } 18 | 19 | [DataMember] 20 | public string OrganizationName { get; } 21 | 22 | [DataMember] 23 | public string RequesterDisplayName { get; } 24 | 25 | [DataMember] 26 | public string ViewerConnectionId { get; } 27 | } 28 | -------------------------------------------------------------------------------- /Shared/Models/RemoteControlViewerOptions.cs: -------------------------------------------------------------------------------- 1 | using System.Runtime.Serialization; 2 | 3 | namespace Remotely.Shared.Models; 4 | 5 | [DataContract] 6 | public class RemoteControlViewerOptions 7 | { 8 | [DataMember] 9 | public bool ShouldRecordSession { get; init; } 10 | } 11 | -------------------------------------------------------------------------------- /Shared/Models/RemotelyUserOptions.cs: -------------------------------------------------------------------------------- 1 | using Remotely.Shared.Enums; 2 | using System.ComponentModel.DataAnnotations; 3 | 4 | namespace Remotely.Shared.Models; 5 | 6 | public class RemotelyUserOptions 7 | { 8 | [Display(Name = "Display Name")] 9 | [StringLength(100)] 10 | public string? DisplayName { get; set; } 11 | 12 | [Display(Name = "PS Core Shortcut")] 13 | [StringLength(10)] 14 | public string CommandModeShortcutPSCore { get; set; } = "/pscore"; 15 | [Display(Name = "Windows PS Shortcut")] 16 | [StringLength(10)] 17 | public string CommandModeShortcutWinPS { get; set; } = "/winps"; 18 | [Display(Name = "CMD Shortcut")] 19 | [StringLength(10)] 20 | public string CommandModeShortcutCMD { get; set; } = "/cmd"; 21 | [Display(Name = "Bash Shortcut")] 22 | [StringLength(10)] 23 | public string CommandModeShortcutBash { get; set; } = "/bash"; 24 | 25 | [Display(Name = "Theme")] 26 | public Theme Theme { get; set; } 27 | } 28 | -------------------------------------------------------------------------------- /Shared/Models/RemotelyUserOptions.cs.d.ts: -------------------------------------------------------------------------------- 1 | interface remotelyUserOptions { 2 | displayName: string; 3 | commandModeShortcutPSCore: string; 4 | commandModeShortcutWinPS: string; 5 | commandModeShortcutCMD: string; 6 | commandModeShortcutBash: string; 7 | theme: any; 8 | } 9 | -------------------------------------------------------------------------------- /Shared/Models/ScreenCastRequest.cs: -------------------------------------------------------------------------------- 1 | namespace Remotely.Shared.Models; 2 | 3 | public class ScreenCastRequest 4 | { 5 | public bool NotifyUser { get; set; } 6 | public string RequesterName { get; set; } = string.Empty; 7 | public string ViewerId { get; set; } = string.Empty; 8 | public Guid StreamId { get; set; } 9 | } 10 | -------------------------------------------------------------------------------- /Shared/Models/SentFrame.cs: -------------------------------------------------------------------------------- 1 | namespace Remotely.Shared.Models; 2 | 3 | public readonly struct SentFrame 4 | { 5 | public SentFrame(int frameSize, DateTimeOffset timestamp) 6 | { 7 | FrameSize = frameSize; 8 | Timestamp = timestamp; 9 | } 10 | 11 | public DateTimeOffset Timestamp { get; } 12 | public int FrameSize { get; } 13 | } 14 | -------------------------------------------------------------------------------- /Shared/Models/WindowsSession.cs: -------------------------------------------------------------------------------- 1 | using System.Runtime.Serialization; 2 | 3 | namespace Remotely.Shared.Models; 4 | 5 | [DataContract] 6 | public enum WindowsSessionType 7 | { 8 | Console = 1, 9 | RDP = 2 10 | } 11 | 12 | [DataContract] 13 | public class WindowsSession 14 | { 15 | [DataMember(Name = "ID")] 16 | public uint Id { get; set; } 17 | [DataMember(Name = "Name")] 18 | public string Name { get; set; } = string.Empty; 19 | [DataMember(Name = "Type")] 20 | public WindowsSessionType Type { get; set; } 21 | [DataMember(Name = "Username")] 22 | public string Username { get; set; } = string.Empty; 23 | } 24 | -------------------------------------------------------------------------------- /Shared/Primitives/NoopDisposable.cs: -------------------------------------------------------------------------------- 1 | namespace Remotely.Shared.Primitives; 2 | public class NoopDisposable : IDisposable 3 | { 4 | public void Dispose() 5 | { 6 | GC.SuppressFinalize(this); 7 | } 8 | } 9 | -------------------------------------------------------------------------------- /Shared/Services/ElevationDetectorLinux.cs: -------------------------------------------------------------------------------- 1 | using System.Runtime.InteropServices; 2 | 3 | namespace Remotely.Shared.Services; 4 | 5 | public class ElevationDetectorLinux : IElevationDetector 6 | { 7 | [DllImport("libc", SetLastError = true)] 8 | private static extern uint geteuid(); 9 | 10 | public bool IsElevated() 11 | { 12 | return geteuid() == 0; 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /Shared/Services/ElevationDetectorMac.cs: -------------------------------------------------------------------------------- 1 | using System.Runtime.InteropServices; 2 | 3 | namespace Remotely.Shared.Services; 4 | 5 | public class ElevationDetectorMac : IElevationDetector 6 | { 7 | [DllImport("libc", SetLastError = true)] 8 | private static extern uint geteuid(); 9 | 10 | public bool IsElevated() 11 | { 12 | return geteuid() == 0; 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /Shared/Services/ElevationDetectorWin.cs: -------------------------------------------------------------------------------- 1 | using System.Runtime.Versioning; 2 | using System.Security.Principal; 3 | 4 | namespace Remotely.Shared.Services; 5 | 6 | [SupportedOSPlatform("windows")] 7 | public class ElevationDetectorWin : IElevationDetector 8 | { 9 | public bool IsElevated() 10 | { 11 | return new WindowsPrincipal(WindowsIdentity.GetCurrent()).IsInRole(WindowsBuiltInRole.Administrator); 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /Shared/Services/FileLoggerProvider.cs: -------------------------------------------------------------------------------- 1 | using Microsoft.Extensions.Logging; 2 | 3 | namespace Remotely.Shared.Services; 4 | 5 | public class FileLoggerProvider : ILoggerProvider 6 | { 7 | private readonly string _componentName; 8 | private readonly string _componentVersion; 9 | 10 | public FileLoggerProvider(string componentName, string componentVersion) 11 | { 12 | _componentName = componentName; 13 | _componentVersion = componentVersion; 14 | } 15 | 16 | public ILogger CreateLogger(string categoryName) 17 | { 18 | return new FileLogger(_componentName, _componentVersion, categoryName); 19 | } 20 | 21 | public void Dispose() 22 | { 23 | GC.SuppressFinalize(this); 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /Shared/Services/IElevationDetector.cs: -------------------------------------------------------------------------------- 1 | namespace Remotely.Shared.Services; 2 | 3 | public interface IElevationDetector 4 | { 5 | bool IsElevated(); 6 | } 7 | -------------------------------------------------------------------------------- /Shared/Usings.cs: -------------------------------------------------------------------------------- 1 | global using System; 2 | global using System.Collections.Generic; 3 | global using System.IO; 4 | global using System.Linq; 5 | global using System.Threading; 6 | global using System.Threading.Tasks; -------------------------------------------------------------------------------- /Shared/Utilities/Disposer.cs: -------------------------------------------------------------------------------- 1 | namespace Remotely.Shared.Utilities; 2 | 3 | public static class Disposer 4 | { 5 | public static void TryDisposeAll(params IDisposable[] disposables) 6 | { 7 | if (disposables is null) 8 | { 9 | return; 10 | } 11 | 12 | foreach (var disposable in disposables) 13 | { 14 | try 15 | { 16 | disposable?.Dispose(); 17 | } 18 | catch { } 19 | } 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /Shared/Utilities/EnumMapper.cs: -------------------------------------------------------------------------------- 1 | namespace Remotely.Shared.Utilities; 2 | 3 | public static class EnumMapper 4 | { 5 | public static ToType ToEnum(FromType fromValue) 6 | where ToType : Enum 7 | where FromType : Enum 8 | { 9 | return (ToType)Enum.Parse(typeof(ToType), fromValue.ToString()); 10 | } 11 | } 12 | -------------------------------------------------------------------------------- /Shared/Utilities/JsonSerializerHelper.cs: -------------------------------------------------------------------------------- 1 | using System.Text.Json; 2 | 3 | namespace Remotely.Shared.Utilities; 4 | 5 | public class JsonSerializerHelper 6 | { 7 | public static JsonSerializerOptions IndentedOptions { get; } = new JsonSerializerOptions() { WriteIndented = true }; 8 | public static JsonSerializerOptions CaseInsensitiveOptions { get; } = new JsonSerializerOptions() { PropertyNameCaseInsensitive = true }; 9 | } 10 | -------------------------------------------------------------------------------- /Shared/Utilities/MathHelper.cs: -------------------------------------------------------------------------------- 1 | namespace Remotely.Shared.Utilities; 2 | 3 | public static class MathHelper 4 | { 5 | public static string GetFormattedPercent(double current, double max) 6 | { 7 | if (current < 1 || max < 1) 8 | { 9 | return "0%"; 10 | } 11 | 12 | return $"{Math.Round(current / max * 100)} %"; 13 | } 14 | 15 | public static string GetFormattedPercent(double percentage) 16 | { 17 | return $"{Math.Round(percentage * 100)} %"; 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /Shared/Utilities/TimeSpanJsonConverter.cs: -------------------------------------------------------------------------------- 1 | using System.Text.Json; 2 | using System.Text.Json.Serialization; 3 | 4 | namespace Remotely.Shared.Utilities; 5 | 6 | public class TimeSpanJsonConverter : JsonConverter 7 | { 8 | public override TimeSpan Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options) 9 | { 10 | var stringValue = reader.GetString(); 11 | if (TimeSpan.TryParse(stringValue, out var result)) 12 | { 13 | return result; 14 | } 15 | 16 | throw new ArgumentException("Failed to convert to TimeSpan."); 17 | } 18 | 19 | public override void Write(Utf8JsonWriter writer, TimeSpan value, JsonSerializerOptions options) 20 | { 21 | writer.WriteStringValue(value.ToString()); 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /Shared/ViewModels/ChatHistoryItem.cs: -------------------------------------------------------------------------------- 1 | using Remotely.Shared.Enums; 2 | 3 | namespace Remotely.Shared.ViewModels; 4 | 5 | public class ChatHistoryItem 6 | { 7 | public ChatHistoryItemOrigin Origin { get; init; } 8 | public string? Message { get; init; } 9 | 10 | public DateTimeOffset Timestamp { get; init; } = DateTime.Now; 11 | 12 | public string ClassName 13 | { 14 | get 15 | { 16 | switch (Origin) 17 | { 18 | case ChatHistoryItemOrigin.System: 19 | return "chat-history-item-system"; 20 | case ChatHistoryItemOrigin.Self: 21 | return "chat-history-item-self"; 22 | case ChatHistoryItemOrigin.Device: 23 | return "chat-history-item-device"; 24 | default: 25 | return string.Empty; 26 | } 27 | } 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /Shared/ViewModels/ChatSession.cs: -------------------------------------------------------------------------------- 1 | using System.Collections.Concurrent; 2 | 3 | namespace Remotely.Shared.ViewModels; 4 | 5 | public class ChatSession 6 | { 7 | public ConcurrentQueue ChatHistory { get; } = new(); 8 | public string? DeviceId { get; set; } 9 | public string? DeviceName { get; set; } 10 | public string ExpandedClass => IsExpanded ? "expanded" : ""; 11 | public bool IsExpanded { get; set; } 12 | 13 | public int MissedChats { get; set; } 14 | public string SessionId { get; } = Guid.NewGuid().ToString(); 15 | } 16 | -------------------------------------------------------------------------------- /Shared/ViewModels/InviteViewModel.cs: -------------------------------------------------------------------------------- 1 | using System.ComponentModel.DataAnnotations; 2 | 3 | namespace Remotely.Shared.ViewModels; 4 | 5 | public class InviteViewModel 6 | { 7 | public string? ID { get; set; } 8 | public bool IsAdmin { get; set; } 9 | public DateTimeOffset DateSent { get; set; } 10 | [EmailAddress] 11 | public string? InvitedUser { get; set; } 12 | } 13 | -------------------------------------------------------------------------------- /Shared/ViewModels/OrganizationUser.cs: -------------------------------------------------------------------------------- 1 | namespace Remotely.Shared.ViewModels; 2 | 3 | public class OrganizationUser 4 | { 5 | public string? ID { get; set; } 6 | public string? UserName { get; set; } 7 | public bool IsAdmin { get; set; } 8 | } 9 | -------------------------------------------------------------------------------- /Shared/ViewModels/TerminalLineItem.cs: -------------------------------------------------------------------------------- 1 | namespace Remotely.Shared.ViewModels; 2 | 3 | public class TerminalLineItem 4 | { 5 | public Guid Id { get; } = Guid.NewGuid(); 6 | public string? Text { get; set; } 7 | public string? ClassName { get; set; } 8 | public string? Title { get; set; } 9 | } 10 | -------------------------------------------------------------------------------- /Tests/Desktop.Win.Tests/Resources/Image1.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/immense/Remotely/ec0d45d8f83ee512e60306ce4ddefed6509bd903/Tests/Desktop.Win.Tests/Resources/Image1.jpg -------------------------------------------------------------------------------- /Tests/Desktop.Win.Tests/Resources/Image2.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/immense/Remotely/ec0d45d8f83ee512e60306ce4ddefed6509bd903/Tests/Desktop.Win.Tests/Resources/Image2.jpg -------------------------------------------------------------------------------- /Tests/Desktop.Win.Tests/Usings.cs: -------------------------------------------------------------------------------- 1 | global using Microsoft.VisualStudio.TestTools.UnitTesting; -------------------------------------------------------------------------------- /Tests/LoadTester/LoadTester.csproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | Exe 5 | net8.0-windows 6 | Remotely.Tests.LoadTester 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | -------------------------------------------------------------------------------- /Tests/LoadTester/Properties/launchSettings.json: -------------------------------------------------------------------------------- 1 | { 2 | "profiles": { 3 | "Tests.LoadTester": { 4 | "commandName": "Project", 5 | "commandLineArgs": "-serverurl https://localhost:5001 -organizationid 0fea8f8b-6ca0-41c7-b6e6-458caca343ec -agentcount 1000" 6 | } 7 | } 8 | } -------------------------------------------------------------------------------- /Tests/Server.Tests/Server.Tests.csproj: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | net8.0 5 | false 6 | Remotely.Server.Tests 7 | AnyCPU;x64;x86 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | -------------------------------------------------------------------------------- /Tests/Shared.Tests/Shared.Tests.csproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | net8.0 5 | enable 6 | enable 7 | false 8 | Remotely.Shared.Tests 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | all 17 | runtime; build; native; contentfiles; analyzers; buildtransitive 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | -------------------------------------------------------------------------------- /Tests/Shared.Tests/StreamExtensionsTests.cs: -------------------------------------------------------------------------------- 1 | using System.Security.Cryptography; 2 | using Remotely.Shared.Extensions; 3 | 4 | namespace Remotely.Shared.Tests; 5 | 6 | [TestClass] 7 | public class StreamExtensionsTests 8 | { 9 | [TestMethod] 10 | public async Task CopyToAsyncTest() 11 | { 12 | var bufferSize = 500_000; 13 | var srcBuffer = new byte[bufferSize]; 14 | RandomNumberGenerator.Fill(srcBuffer); 15 | 16 | using var src = new MemoryStream(srcBuffer); 17 | using var dst = new MemoryStream(); 18 | 19 | var amounts = new List(); 20 | 21 | await src.CopyToAsync(dst, bytesRead => 22 | { 23 | amounts.Add(bytesRead); 24 | }); 25 | 26 | Assert.IsTrue(amounts.Any()); 27 | Assert.AreEqual(bufferSize, amounts.Last()); 28 | } 29 | } -------------------------------------------------------------------------------- /Tests/Shared.Tests/Usings.cs: -------------------------------------------------------------------------------- 1 | global using Microsoft.VisualStudio.TestTools.UnitTesting; -------------------------------------------------------------------------------- /Utilities/Add-Migration.ps1: -------------------------------------------------------------------------------- 1 | param( 2 | [string]$MigrationName 3 | ) 4 | 5 | if (!$MigrationName) { 6 | exit 1 7 | } 8 | 9 | $ErrorActionPreference = "Stop" 10 | 11 | 12 | if ($PSScriptRoot) { 13 | $Root = (Get-Item -Path $PSScriptRoot).Parent.FullName + "\Server" 14 | } 15 | else { 16 | $Root = (Get-Item -Path (Get-Location).Path).Parent.FullName + "\Server" 17 | } 18 | 19 | Push-Location $Root 20 | 21 | dotnet ef migrations add $MigrationName --context "SqliteDbContext" 22 | dotnet ef migrations add $MigrationName --context "SqlServerDbContext" 23 | dotnet ef migrations add $MigrationName --context "PostgreSqlDbContext" 24 | 25 | Pop-Location -------------------------------------------------------------------------------- /Utilities/Output-PSCommands.ps1: -------------------------------------------------------------------------------- 1 | Start-Process -FilePath "powershell.exe" -ArgumentList "-f C:\Users\Typic\Source\Repos\DoXM\Utilities\Get-PSCommands.ps1" 2 | Start-Process -FilePath "C:\Program Files\PowerShell\6\pwsh.exe" -ArgumentList "-f C:\Users\Typic\Source\Repos\DoXM\Utilities\Get-PSCommands.ps1" -------------------------------------------------------------------------------- /Utilities/Remove-Migration.ps1: -------------------------------------------------------------------------------- 1 | $ErrorActionPreference = "Stop" 2 | 3 | if ($PSScriptRoot) { 4 | $Root = (Get-Item -Path $PSScriptRoot).Parent.FullName + "\Server" 5 | } 6 | else { 7 | $Root = (Get-Item -Path (Get-Location).Path).Parent.FullName + "\Server" 8 | } 9 | 10 | Push-Location "$Root" 11 | 12 | dotnet ef migrations remove --context "SqliteDbContext" 13 | dotnet ef migrations remove --context "SqlServerDbContext" 14 | dotnet ef migrations remove --context "PostgreSqlDbContext" 15 | 16 | Pop-Location -------------------------------------------------------------------------------- /Utilities/signtool.exe: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/immense/Remotely/ec0d45d8f83ee512e60306ce4ddefed6509bd903/Utilities/signtool.exe -------------------------------------------------------------------------------- /docker-compose/.dockerignore: -------------------------------------------------------------------------------- 1 | **/.classpath 2 | **/.dockerignore 3 | **/.env 4 | **/.git 5 | **/.gitignore 6 | **/.project 7 | **/.settings 8 | **/.toolstarget 9 | **/.vs 10 | **/.vscode 11 | **/*.*proj.user 12 | **/*.dbmdl 13 | **/*.jfm 14 | **/azds.yaml 15 | **/bin 16 | **/charts 17 | **/docker-compose* 18 | **/Dockerfile* 19 | **/node_modules 20 | **/npm-debug.log 21 | **/obj 22 | **/secrets.dev.yaml 23 | **/values.dev.yaml 24 | LICENSE 25 | README.md -------------------------------------------------------------------------------- /docker-compose/docker-compose.dcproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 2.1 5 | remotely 6 | Linux 7 | False 8 | 90ec49b2-b56a-4ecd-8f63-2162dd140f7c 9 | LaunchBrowser 10 | {Scheme}://localhost:{ServicePort} 11 | remotely 12 | 13 | 14 | 15 | docker-compose.yml 16 | 17 | 18 | 19 | 20 | -------------------------------------------------------------------------------- /docker-compose/docker-compose.override.yml: -------------------------------------------------------------------------------- 1 | version: '3.4' 2 | 3 | 4 | services: 5 | remotely: 6 | environment: 7 | - ASPNETCORE_ENVIRONMENT=Development 8 | - ASPNETCORE_HTTP_PORTS=5000 9 | - ASPNETCORE_HTTPS_PORTS=5001 10 | ports: 11 | - "5000:5000" 12 | - "5001:5001" 13 | volumes: 14 | - ${APPDATA}/Microsoft/UserSecrets:/home/app/.microsoft/usersecrets:ro 15 | - ${APPDATA}/ASP.NET/Https:/home/app/.aspnet/https:ro 16 | build: 17 | context: ../ 18 | dockerfile: Server/Dockerfile -------------------------------------------------------------------------------- /docker-compose/launchSettings.json: -------------------------------------------------------------------------------- 1 | { 2 | "profiles": { 3 | "Docker Compose": { 4 | "commandName": "DockerCompose", 5 | "commandVersion": "1.0", 6 | "composeLaunchAction": "LaunchBrowser", 7 | "composeLaunchServiceName": "remotely", 8 | "composeLaunchUrl": "{Scheme}://localhost:{ServicePort}", 9 | "serviceActions": { 10 | "remotely": "StartDebugging" 11 | } 12 | } 13 | } 14 | } --------------------------------------------------------------------------------