diff --git a/.github/FUNDING.yml b/.github/FUNDING.yml
deleted file mode 100644
index a85367c..0000000
--- a/.github/FUNDING.yml
+++ /dev/null
@@ -1 +0,0 @@
-custom: ["https://web.satispay.com/app/match/link/user/S6Y-CON--88923C30-BEC8-487E-9814-68A5449F7D83?amount=500¤cy=EUR"]
diff --git a/.github/ISSUE_TEMPLATE/bug-report.md b/.github/ISSUE_TEMPLATE/bug-report.md
index 1379a16..78d4791 100644
--- a/.github/ISSUE_TEMPLATE/bug-report.md
+++ b/.github/ISSUE_TEMPLATE/bug-report.md
@@ -1,18 +1,17 @@
---
name: Bug Report
-about: Create a bug report to help us improve the Safe Exam Browser Patch
+about: Create a bug report to help us improve Safe Exam Browser.
title: ''
-labels: bug
-assignees: theitaliandeveloper
+labels: ''
+assignees: dbuechel
---
> [!IMPORTANT]
-> - Please _always_ consult the FAQs before creating an issue: https://git.vichingo455.freeddns.org/school-cheating/SEBPatch/wiki/FAQs.
+> - Please _always_ consult the documentation first before creating a bug report: https://safeexambrowser.org/windows/win_usermanual_en.html.
> - Please _always_ attach the log file(s) of the affected session(s)! They can be found under `%LocalAppData%\SafeExamBrowser\Logs`.
-> - Please follow this issue template. Saves me some work while reading all issues.
-**Bug Description**
+**Describe the Bug**
A clear and concise description of what the bug is.
**Steps to Reproduce**
@@ -30,18 +29,7 @@ If applicable, add screenshots to help explain your problem.
**Version Information**
- OS: [e.g. Windows 10 Professional, Version 1803]
- - SEB version: [e.g. SEB 3.0.1]
- - SEB patch version: [e.g. 1.5.1]
+ - SEB-Version [e.g. SEB 3.0.1]
**Additional Context**
Add any other context about the problem here.
-
-**SEB Logs**
-```
-Paste here the SEB logs
-```
-
-**SEB Patcher logs (optional, read below)**
-```
-Paste here the SEB patcher logs (if issue is SEB patcher related, else just ignore this section)
-```
diff --git a/.github/ISSUE_TEMPLATE/config.yml b/.github/ISSUE_TEMPLATE/config.yml
deleted file mode 100644
index e6c5858..0000000
--- a/.github/ISSUE_TEMPLATE/config.yml
+++ /dev/null
@@ -1,11 +0,0 @@
-blank_issues_enabled: false
-contact_links:
- - name: FAQs
- url: https://git.vichingo455.freeddns.org/school-cheating/SEBPatch/wiki/FAQs
- about: Before opening an issue, check out the FAQs. Any issue corresponding to the FAQs will be ignored and closed.
- - name: Questions
- url: https://github.com/theitaliandeveloper/SEBPatch/discussions/categories/q-a
- about: Ask questions here about the Safe Exam Browser Patch
- - name: Feature Requests
- url: https://github.com/theitaliandeveloper/SEBPatch/discussions/categories/ideas
- about: Propose a feature or a change for the Safe Exam Browser Patch.
diff --git a/.github/ISSUE_TEMPLATE/feature-request.md b/.github/ISSUE_TEMPLATE/feature-request.md
new file mode 100644
index 0000000..325de6b
--- /dev/null
+++ b/.github/ISSUE_TEMPLATE/feature-request.md
@@ -0,0 +1,20 @@
+---
+name: Feature Request
+about: Suggest an idea or new feature for Safe Exam Browser.
+title: ''
+labels: ''
+assignees: dbuechel
+
+---
+
+**Is your feature request related to a problem? Please describe.**
+A clear and concise description of what the problem is. Ex. I'm always frustrated when [...]
+
+**Describe the solution you'd like**
+A clear and concise description of what you want to happen.
+
+**Describe alternatives you've considered**
+A clear and concise description of any alternative solutions or features you've considered.
+
+**Additional context**
+Add any other context or screenshots about the feature request here.
diff --git a/.github/workflows/codeql.yml b/.github/workflows/codeql.yml
new file mode 100644
index 0000000..57f0fc6
--- /dev/null
+++ b/.github/workflows/codeql.yml
@@ -0,0 +1,54 @@
+name: "CodeQL"
+
+on:
+ push:
+ branches: [ "master", "*" ]
+ pull_request:
+ branches: [ "master", "*" ]
+ schedule:
+ - cron: '0 0 * * 1'
+
+jobs:
+ analyze:
+ name: Analyze
+ runs-on: "windows-latest"
+ timeout-minutes: 360
+ permissions:
+ actions: read
+ contents: read
+ security-events: write
+
+ strategy:
+ fail-fast: false
+ matrix:
+ language: [ 'csharp', 'javascript-typescript' ]
+
+ steps:
+ - name: Checkout repository
+ uses: actions/checkout@v3
+
+ - name: Initialize CodeQL
+ uses: github/codeql-action/init@v2
+ with:
+ languages: ${{ matrix.language }}
+ queries: security-extended,security-and-quality
+
+ # Autobuild attempts to build any compiled languages (C/C++, C#, Go, Java, or Swift).
+ # If this step fails, then you should remove it and run the build manually (see below)
+ - name: Autobuild
+ uses: github/codeql-action/autobuild@v2
+
+ # ℹ️ Command-line programs to run using the OS shell.
+ # 📚 See https://docs.github.com/en/actions/using-workflows/workflow-syntax-for-github-actions#jobsjob_idstepsrun
+
+ # If the Autobuild fails above, remove it and uncomment the following three lines.
+ # modify them (or add more) to build your code if your project, please refer to the EXAMPLE below for guidance.
+
+ # - run: |
+ # echo "Run, Build Application using script"
+ # ./location_of_script_within_repo/buildscript.sh
+
+ - name: Perform CodeQL Analysis
+ uses: github/codeql-action/analyze@v2
+ with:
+ category: "/language:${{matrix.language}}"
diff --git a/SafeExamBrowser.Applications.Contracts/FactoryResult.cs b/SafeExamBrowser.Applications.Contracts/FactoryResult.cs
index 0286fe7..3624615 100644
--- a/SafeExamBrowser.Applications.Contracts/FactoryResult.cs
+++ b/SafeExamBrowser.Applications.Contracts/FactoryResult.cs
@@ -18,6 +18,11 @@ namespace SafeExamBrowser.Applications.Contracts
///
Error,
+ ///
+ /// The application has been found but is invalid (e.g. because it is not the correct version or has been manipulated).
+ ///
+ Invalid,
+
///
/// The application could not be found on the system.
///
diff --git a/SafeExamBrowser.Applications.UnitTests/ILLink/ILLink.Descriptors.LibraryBuild.xml b/SafeExamBrowser.Applications.UnitTests/ILLink/ILLink.Descriptors.LibraryBuild.xml
deleted file mode 100644
index a42d7f0..0000000
--- a/SafeExamBrowser.Applications.UnitTests/ILLink/ILLink.Descriptors.LibraryBuild.xml
+++ /dev/null
@@ -1,8 +0,0 @@
-
-
-
-
-
-
-
-
diff --git a/SafeExamBrowser.Applications.UnitTests/SafeExamBrowser.Applications.UnitTests.csproj b/SafeExamBrowser.Applications.UnitTests/SafeExamBrowser.Applications.UnitTests.csproj
index 466b469..9edb9a2 100644
--- a/SafeExamBrowser.Applications.UnitTests/SafeExamBrowser.Applications.UnitTests.csproj
+++ b/SafeExamBrowser.Applications.UnitTests/SafeExamBrowser.Applications.UnitTests.csproj
@@ -1,9 +1,9 @@
-
-
-
-
+
+
+
+
Debug
@@ -63,78 +63,82 @@
- ..\packages\Castle.Core.5.1.1\lib\net462\Castle.Core.dll
+ ..\packages\Castle.Core.5.2.1\lib\net462\Castle.Core.dll
-
- ..\packages\Microsoft.ApplicationInsights.2.22.0\lib\net46\Microsoft.ApplicationInsights.dll
+
+ ..\packages\Microsoft.ApplicationInsights.2.23.0\lib\net46\Microsoft.ApplicationInsights.dll
-
- ..\packages\Microsoft.Testing.Platform.MSBuild.1.5.2\lib\netstandard2.0\Microsoft.Testing.Extensions.MSBuild.dll
+
+ ..\packages\Microsoft.Testing.Platform.MSBuild.1.8.3\lib\netstandard2.0\Microsoft.Testing.Extensions.MSBuild.dll
-
- ..\packages\Microsoft.Testing.Extensions.Telemetry.1.5.2\lib\netstandard2.0\Microsoft.Testing.Extensions.Telemetry.dll
+
+ ..\packages\Microsoft.Testing.Extensions.Telemetry.1.8.3\lib\netstandard2.0\Microsoft.Testing.Extensions.Telemetry.dll
-
- ..\packages\Microsoft.Testing.Extensions.TrxReport.Abstractions.1.5.2\lib\netstandard2.0\Microsoft.Testing.Extensions.TrxReport.Abstractions.dll
+
+ ..\packages\Microsoft.Testing.Extensions.TrxReport.Abstractions.1.8.3\lib\netstandard2.0\Microsoft.Testing.Extensions.TrxReport.Abstractions.dll
-
- ..\packages\Microsoft.Testing.Extensions.VSTestBridge.1.5.2\lib\netstandard2.0\Microsoft.Testing.Extensions.VSTestBridge.dll
+
+ ..\packages\Microsoft.Testing.Extensions.VSTestBridge.1.8.3\lib\netstandard2.0\Microsoft.Testing.Extensions.VSTestBridge.dll
-
- ..\packages\Microsoft.Testing.Platform.1.5.2\lib\netstandard2.0\Microsoft.Testing.Platform.dll
+
+ ..\packages\Microsoft.Testing.Platform.1.8.3\lib\netstandard2.0\Microsoft.Testing.Platform.dll
+
+
+ ..\packages\Microsoft.TestPlatform.AdapterUtilities.17.14.1\lib\net462\Microsoft.TestPlatform.AdapterUtilities.dll
+ True
- ..\packages\Microsoft.TestPlatform.ObjectModel.17.12.0\lib\net462\Microsoft.TestPlatform.CoreUtilities.dll
+ ..\packages\Microsoft.TestPlatform.ObjectModel.17.14.1\lib\net462\Microsoft.TestPlatform.CoreUtilities.dll
- ..\packages\Microsoft.TestPlatform.ObjectModel.17.12.0\lib\net462\Microsoft.TestPlatform.PlatformAbstractions.dll
+ ..\packages\Microsoft.TestPlatform.ObjectModel.17.14.1\lib\net462\Microsoft.TestPlatform.PlatformAbstractions.dll
- ..\packages\Microsoft.TestPlatform.ObjectModel.17.12.0\lib\net462\Microsoft.VisualStudio.TestPlatform.ObjectModel.dll
+ ..\packages\Microsoft.TestPlatform.ObjectModel.17.14.1\lib\net462\Microsoft.VisualStudio.TestPlatform.ObjectModel.dll
- ..\packages\MSTest.TestFramework.3.7.2\lib\net462\Microsoft.VisualStudio.TestPlatform.TestFramework.dll
+ ..\packages\MSTest.TestFramework.3.10.3\lib\net462\Microsoft.VisualStudio.TestPlatform.TestFramework.dll
- ..\packages\MSTest.TestFramework.3.7.2\lib\net462\Microsoft.VisualStudio.TestPlatform.TestFramework.Extensions.dll
+ ..\packages\MSTest.TestFramework.3.10.3\lib\net462\Microsoft.VisualStudio.TestPlatform.TestFramework.Extensions.dll
..\packages\Moq.4.20.72\lib\net462\Moq.dll
-
- ..\packages\NuGet.Frameworks.6.12.1\lib\net472\NuGet.Frameworks.dll
+
+ ..\packages\NuGet.Frameworks.6.14.0\lib\net472\NuGet.Frameworks.dll
-
- ..\packages\System.Buffers.4.6.0\lib\net462\System.Buffers.dll
+
+ ..\packages\System.Buffers.4.6.1\lib\net462\System.Buffers.dll
-
- ..\packages\System.Collections.Immutable.9.0.1\lib\net462\System.Collections.Immutable.dll
+
+ ..\packages\System.Collections.Immutable.9.0.8\lib\net462\System.Collections.Immutable.dll
-
- ..\packages\System.Diagnostics.DiagnosticSource.9.0.1\lib\net462\System.Diagnostics.DiagnosticSource.dll
+
+ ..\packages\System.Diagnostics.DiagnosticSource.9.0.8\lib\net462\System.Diagnostics.DiagnosticSource.dll
-
- ..\packages\System.Memory.4.6.0\lib\net462\System.Memory.dll
+
+ ..\packages\System.Memory.4.6.3\lib\net462\System.Memory.dll
-
- ..\packages\System.Numerics.Vectors.4.6.0\lib\net462\System.Numerics.Vectors.dll
+
+ ..\packages\System.Numerics.Vectors.4.6.1\lib\net462\System.Numerics.Vectors.dll
-
- ..\packages\System.Reflection.Metadata.9.0.1\lib\net462\System.Reflection.Metadata.dll
+
+ ..\packages\System.Reflection.Metadata.9.0.8\lib\net462\System.Reflection.Metadata.dll
-
- ..\packages\System.Runtime.CompilerServices.Unsafe.6.1.0\lib\net462\System.Runtime.CompilerServices.Unsafe.dll
+
+ ..\packages\System.Runtime.CompilerServices.Unsafe.6.1.2\lib\net462\System.Runtime.CompilerServices.Unsafe.dll
-
- ..\packages\System.Threading.Tasks.Extensions.4.6.0\lib\net462\System.Threading.Tasks.Extensions.dll
+
+ ..\packages\System.Threading.Tasks.Extensions.4.6.3\lib\net462\System.Threading.Tasks.Extensions.dll
@@ -184,11 +188,8 @@
-
-
-
-
-
+
+
@@ -196,13 +197,17 @@
This project references NuGet package(s) that are missing on this computer. Use NuGet Package Restore to download them. For more information, see http://go.microsoft.com/fwlink/?LinkID=322105. The missing file is {0}.
-
-
-
-
-
-
+
+
+
+
+
+
+
+
-
-
+
+
+
+
\ No newline at end of file
diff --git a/SafeExamBrowser.Applications.UnitTests/app.config b/SafeExamBrowser.Applications.UnitTests/app.config
index 4a41c0d..259d7bd 100644
--- a/SafeExamBrowser.Applications.UnitTests/app.config
+++ b/SafeExamBrowser.Applications.UnitTests/app.config
@@ -4,7 +4,7 @@
-
+
@@ -12,31 +12,31 @@
-
+
-
+
-
+
-
+
-
+
-
+
-
+
diff --git a/SafeExamBrowser.Applications.UnitTests/packages.config b/SafeExamBrowser.Applications.UnitTests/packages.config
index da1800f..32e6e53 100644
--- a/SafeExamBrowser.Applications.UnitTests/packages.config
+++ b/SafeExamBrowser.Applications.UnitTests/packages.config
@@ -1,24 +1,25 @@
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/SafeExamBrowser.Applications/ApplicationFactory.cs b/SafeExamBrowser.Applications/ApplicationFactory.cs
index 497600d..cb940b2 100644
--- a/SafeExamBrowser.Applications/ApplicationFactory.cs
+++ b/SafeExamBrowser.Applications/ApplicationFactory.cs
@@ -8,7 +8,9 @@
using System;
using System.Collections.Generic;
+using System.Diagnostics;
using System.IO;
+using System.Security.Cryptography.X509Certificates;
using SafeExamBrowser.Applications.Contracts;
using SafeExamBrowser.Logging.Contracts;
using SafeExamBrowser.Monitoring.Contracts.Applications;
@@ -43,42 +45,62 @@ namespace SafeExamBrowser.Applications
public FactoryResult TryCreate(WhitelistApplication settings, out IApplication application)
{
var name = $"'{settings.DisplayName}' ({settings.ExecutableName})";
+ var result = FactoryResult.Error;
application = default;
try
{
- var success = TryFindApplication(settings, out var executablePath);
+ var found = TryFindApplication(settings, out var executablePath);
+ var valid = found && VerifyApplication(executablePath, name, settings);
- if (success)
+ if (found && valid)
{
- application = BuildApplication(executablePath, settings);
- application.Initialize();
-
- logger.Debug($"Successfully initialized application {name}.");
-
- return FactoryResult.Success;
+ application = InitializeApplication(executablePath, settings);
}
- logger.Error($"Could not find application {name}!");
-
- return FactoryResult.NotFound;
+ result = DetermineResult(name, found, valid);
}
catch (Exception e)
{
logger.Error($"Unexpected error while trying to initialize application {name}!", e);
}
- return FactoryResult.Error;
+ return result;
}
- private IApplication BuildApplication(string executablePath, WhitelistApplication settings)
+ private FactoryResult DetermineResult(string name, bool found, bool valid)
+ {
+ var result = default(FactoryResult);
+
+ if (!found)
+ {
+ result = FactoryResult.NotFound;
+ logger.Error($"Could not find application {name}!");
+ }
+ else if (!valid)
+ {
+ result = FactoryResult.Invalid;
+ logger.Error($"The application {name} is not valid or has been manipulated!");
+ }
+ else
+ {
+ result = FactoryResult.Success;
+ logger.Debug($"Successfully initialized application {name}.");
+ }
+
+ return result;
+ }
+
+ private IApplication InitializeApplication(string executablePath, WhitelistApplication settings)
{
const int ONE_SECOND = 1000;
var applicationLogger = logger.CloneFor(settings.DisplayName);
var application = new ExternalApplication(applicationMonitor, executablePath, applicationLogger, nativeMethods, processFactory, settings, ONE_SECOND);
+ application.Initialize();
+
return application;
}
@@ -143,5 +165,99 @@ namespace SafeExamBrowser.Applications
return default;
}
+
+ private bool VerifyApplication(string executablePath, string name, WhitelistApplication settings)
+ {
+ var valid = true;
+
+ valid &= VerifyName(executablePath, name, settings);
+ valid &= VerifyOriginalName(executablePath, name, settings);
+ valid &= VerifySignature(executablePath, name, settings);
+
+ return valid;
+ }
+
+ private bool VerifyName(string executablePath, string name, WhitelistApplication settings)
+ {
+ var valid = Path.GetFileName(executablePath).Equals(settings.ExecutableName, StringComparison.OrdinalIgnoreCase);
+
+ if (!valid)
+ {
+ logger.Warn($"The executable name of application {name} at '{executablePath}' does not match the configured value!");
+ }
+
+ return valid;
+ }
+
+ private bool VerifyOriginalName(string executablePath, string name, WhitelistApplication settings)
+ {
+ var ignoreOriginalName = string.IsNullOrWhiteSpace(settings.OriginalName);
+ var valid = ignoreOriginalName;
+
+ if (!ignoreOriginalName && TryLoadOriginalName(executablePath, out var originalName))
+ {
+ valid = originalName.Equals(settings.OriginalName, StringComparison.OrdinalIgnoreCase);
+ }
+
+ if (!valid)
+ {
+ logger.Warn($"The original name of application {name} at '{executablePath}' does not match the configured value!");
+ }
+
+ return valid;
+ }
+
+ private bool VerifySignature(string executablePath, string name, WhitelistApplication settings)
+ {
+ var ignoreSignature = string.IsNullOrWhiteSpace(settings.Signature);
+ var valid = ignoreSignature;
+
+ if (!ignoreSignature && TryLoadSignature(executablePath, out var signature))
+ {
+ valid = signature.Equals(settings.Signature, StringComparison.OrdinalIgnoreCase);
+ }
+
+ if (!valid)
+ {
+ logger.Warn($"The signature of application {name} at '{executablePath}' does not match the configured value!");
+ }
+
+ return valid;
+ }
+
+ private bool TryLoadOriginalName(string path, out string originalName)
+ {
+ originalName = default;
+
+ try
+ {
+ originalName = FileVersionInfo.GetVersionInfo(path).OriginalFilename;
+ }
+ catch (Exception e)
+ {
+ logger.Error($"Failed to load original name for '{path}'!", e);
+ }
+
+ return originalName != default;
+ }
+
+ private bool TryLoadSignature(string path, out string signature)
+ {
+ signature = default;
+
+ try
+ {
+ using (var certificate = X509Certificate.CreateFromSignedFile(path))
+ {
+ signature = certificate.GetCertHashString();
+ }
+ }
+ catch (Exception e)
+ {
+ logger.Error($"Failed to load signature for '{path}'!", e);
+ }
+
+ return signature != default;
+ }
}
}
diff --git a/SafeExamBrowser.Browser.UnitTests/Filters/RequestFilterTests.cs b/SafeExamBrowser.Browser.UnitTests/Filters/RequestFilterTests.cs
index 941c5b5..c674dcf 100644
--- a/SafeExamBrowser.Browser.UnitTests/Filters/RequestFilterTests.cs
+++ b/SafeExamBrowser.Browser.UnitTests/Filters/RequestFilterTests.cs
@@ -102,13 +102,13 @@ namespace SafeExamBrowser.Browser.UnitTests.Filters
}
[TestMethod]
- [ExpectedException(typeof(NotImplementedException))]
public void MustNotAllowUnsupportedResult()
{
var rule = new Mock();
rule.SetupGet(r => r.Result).Returns((FilterResult) (-1));
- sut.Load(rule.Object);
+
+ Assert.ThrowsExactly(() => sut.Load(rule.Object));
}
}
}
diff --git a/SafeExamBrowser.Browser.UnitTests/Filters/RuleFactoryTests.cs b/SafeExamBrowser.Browser.UnitTests/Filters/RuleFactoryTests.cs
index 85c3b33..86f731e 100644
--- a/SafeExamBrowser.Browser.UnitTests/Filters/RuleFactoryTests.cs
+++ b/SafeExamBrowser.Browser.UnitTests/Filters/RuleFactoryTests.cs
@@ -33,10 +33,9 @@ namespace SafeExamBrowser.Browser.UnitTests.Filters
}
[TestMethod]
- [ExpectedException(typeof(NotImplementedException))]
public void MustNotAllowUnsupportedFilterType()
{
- sut.CreateRule((FilterRuleType) (-1));
+ Assert.ThrowsExactly(() => sut.CreateRule((FilterRuleType) (-1)));
}
}
}
diff --git a/SafeExamBrowser.Browser.UnitTests/Filters/Rules/RegexRuleTests.cs b/SafeExamBrowser.Browser.UnitTests/Filters/Rules/RegexRuleTests.cs
index d4af886..0c3d612 100644
--- a/SafeExamBrowser.Browser.UnitTests/Filters/Rules/RegexRuleTests.cs
+++ b/SafeExamBrowser.Browser.UnitTests/Filters/Rules/RegexRuleTests.cs
@@ -51,17 +51,15 @@ namespace SafeExamBrowser.Browser.UnitTests.Filters.Rules
}
[TestMethod]
- [ExpectedException(typeof(ArgumentNullException))]
public void MustNotAllowUndefinedExpression()
{
- sut.Initialize(new FilterRuleSettings());
+ Assert.ThrowsExactly(() => sut.Initialize(new FilterRuleSettings()));
}
[TestMethod]
- [ExpectedException(typeof(ArgumentException))]
public void MustValidateExpression()
{
- sut.Initialize(new FilterRuleSettings { Expression = "ç+\"}%&*/(+)=?{=*+¦]@#°§]`?´^¨'°[¬|¢" });
+ Assert.ThrowsExactly(() => sut.Initialize(new FilterRuleSettings { Expression = "ç+\"}%&*/(+)=?{=*+¦]@#°§]`?´^¨'°[¬|¢" }));
}
}
}
diff --git a/SafeExamBrowser.Browser.UnitTests/Filters/Rules/SimplifiedRuleTests.cs b/SafeExamBrowser.Browser.UnitTests/Filters/Rules/SimplifiedRuleTests.cs
index 4d49b26..d28a48c 100644
--- a/SafeExamBrowser.Browser.UnitTests/Filters/Rules/SimplifiedRuleTests.cs
+++ b/SafeExamBrowser.Browser.UnitTests/Filters/Rules/SimplifiedRuleTests.cs
@@ -51,10 +51,9 @@ namespace SafeExamBrowser.Browser.UnitTests.Filters.Rules
}
[TestMethod]
- [ExpectedException(typeof(ArgumentNullException))]
public void MustNotAllowUndefinedExpression()
{
- sut.Initialize(new FilterRuleSettings());
+ Assert.ThrowsExactly(() => sut.Initialize(new FilterRuleSettings()));
}
[TestMethod]
@@ -73,7 +72,7 @@ namespace SafeExamBrowser.Browser.UnitTests.Filters.Rules
foreach (var expression in invalid)
{
- Assert.ThrowsException(() => sut.Initialize(new FilterRuleSettings { Expression = expression }));
+ Assert.ThrowsExactly(() => sut.Initialize(new FilterRuleSettings { Expression = expression }));
}
}
diff --git a/SafeExamBrowser.Browser.UnitTests/Handlers/RequestHandlerTests.cs b/SafeExamBrowser.Browser.UnitTests/Handlers/RequestHandlerTests.cs
index 64c554f..440451c 100644
--- a/SafeExamBrowser.Browser.UnitTests/Handlers/RequestHandlerTests.cs
+++ b/SafeExamBrowser.Browser.UnitTests/Handlers/RequestHandlerTests.cs
@@ -12,6 +12,7 @@ using Microsoft.VisualStudio.TestTools.UnitTesting;
using Moq;
using SafeExamBrowser.Browser.Contracts.Filters;
using SafeExamBrowser.Browser.Handlers;
+using SafeExamBrowser.Browser.Integrations;
using SafeExamBrowser.Configuration.Contracts;
using SafeExamBrowser.Configuration.Contracts.Cryptography;
using SafeExamBrowser.I18n.Contracts;
@@ -41,6 +42,13 @@ namespace SafeExamBrowser.Browser.UnitTests.Handlers
[TestInitialize]
public void Initialize()
{
+ var integrations = new Integration[]
+ {
+ new GenericIntegration(new Mock().Object),
+ new EdxIntegration(new Mock().Object),
+ new MoodleIntegration(new Mock().Object)
+ };
+
appConfig = new AppConfig();
filter = new Mock();
keyGenerator = new Mock();
@@ -48,7 +56,7 @@ namespace SafeExamBrowser.Browser.UnitTests.Handlers
settings = new BrowserSettings();
windowSettings = new WindowSettings();
text = new Mock();
- resourceHandler = new ResourceHandler(appConfig, filter.Object, keyGenerator.Object, logger.Object, default, settings, windowSettings, text.Object);
+ resourceHandler = new ResourceHandler(appConfig, filter.Object, integrations, keyGenerator.Object, logger.Object, default, settings, windowSettings, text.Object);
sut = new TestableRequestHandler(appConfig, filter.Object, logger.Object, resourceHandler, settings, windowSettings);
}
@@ -285,7 +293,13 @@ namespace SafeExamBrowser.Browser.UnitTests.Handlers
private class TestableRequestHandler : RequestHandler
{
- internal TestableRequestHandler(AppConfig appConfig, IRequestFilter filter, ILogger logger, ResourceHandler resourceHandler, BrowserSettings settings, WindowSettings windowSettings) : base(appConfig, filter, logger, resourceHandler, settings, windowSettings)
+ internal TestableRequestHandler(
+ AppConfig appConfig,
+ IRequestFilter filter,
+ ILogger logger,
+ ResourceHandler resourceHandler,
+ BrowserSettings settings,
+ WindowSettings windowSettings) : base(appConfig, filter, logger, resourceHandler, settings, windowSettings)
{
}
diff --git a/SafeExamBrowser.Browser.UnitTests/Handlers/ResourceHandlerTests.cs b/SafeExamBrowser.Browser.UnitTests/Handlers/ResourceHandlerTests.cs
index 92b3111..c8ec7b7 100644
--- a/SafeExamBrowser.Browser.UnitTests/Handlers/ResourceHandlerTests.cs
+++ b/SafeExamBrowser.Browser.UnitTests/Handlers/ResourceHandlerTests.cs
@@ -7,6 +7,7 @@
*/
using System;
+using System.Collections.Generic;
using System.Collections.Specialized;
using System.Net.Mime;
using System.Threading;
@@ -14,6 +15,7 @@ using CefSharp;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using Moq;
using SafeExamBrowser.Browser.Contracts.Filters;
+using SafeExamBrowser.Browser.Integrations;
using SafeExamBrowser.Configuration.Contracts;
using SafeExamBrowser.Configuration.Contracts.Cryptography;
using SafeExamBrowser.I18n.Contracts;
@@ -42,6 +44,13 @@ namespace SafeExamBrowser.Browser.UnitTests.Handlers
[TestInitialize]
public void Initialize()
{
+ var integrations = new Integration[]
+ {
+ new GenericIntegration(new Mock().Object),
+ new EdxIntegration(new Mock().Object),
+ new MoodleIntegration(new Mock().Object)
+ };
+
appConfig = new AppConfig();
filter = new Mock();
keyGenerator = new Mock();
@@ -50,7 +59,7 @@ namespace SafeExamBrowser.Browser.UnitTests.Handlers
windowSettings = new WindowSettings();
text = new Mock();
- sut = new TestableResourceHandler(appConfig, filter.Object, keyGenerator.Object, logger.Object, SessionMode.Server, settings, windowSettings, text.Object);
+ sut = new TestableResourceHandler(appConfig, filter.Object, integrations, keyGenerator.Object, logger.Object, SessionMode.Server, settings, windowSettings, text.Object);
}
[TestMethod]
@@ -325,12 +334,13 @@ namespace SafeExamBrowser.Browser.UnitTests.Handlers
internal TestableResourceHandler(
AppConfig appConfig,
IRequestFilter filter,
+ IEnumerable integrations,
IKeyGenerator keyGenerator,
ILogger logger,
SessionMode sessionMode,
BrowserSettings settings,
WindowSettings windowSettings,
- IText text) : base(appConfig, filter, keyGenerator, logger, sessionMode, settings, windowSettings, text)
+ IText text) : base(appConfig, filter, integrations, keyGenerator, logger, sessionMode, settings, windowSettings, text)
{
}
diff --git a/SafeExamBrowser.Browser.UnitTests/ILLink/ILLink.Descriptors.LibraryBuild.xml b/SafeExamBrowser.Browser.UnitTests/ILLink/ILLink.Descriptors.LibraryBuild.xml
deleted file mode 100644
index a42d7f0..0000000
--- a/SafeExamBrowser.Browser.UnitTests/ILLink/ILLink.Descriptors.LibraryBuild.xml
+++ /dev/null
@@ -1,8 +0,0 @@
-
-
-
-
-
-
-
-
diff --git a/SafeExamBrowser.Browser.UnitTests/SafeExamBrowser.Browser.UnitTests.csproj b/SafeExamBrowser.Browser.UnitTests/SafeExamBrowser.Browser.UnitTests.csproj
index df98d1c..41b0683 100644
--- a/SafeExamBrowser.Browser.UnitTests/SafeExamBrowser.Browser.UnitTests.csproj
+++ b/SafeExamBrowser.Browser.UnitTests/SafeExamBrowser.Browser.UnitTests.csproj
@@ -1,12 +1,12 @@
-
-
-
-
-
-
-
+
+
+
+
+
+
+
Debug
@@ -66,84 +66,88 @@
- ..\packages\Castle.Core.5.1.1\lib\net462\Castle.Core.dll
+ ..\packages\Castle.Core.5.2.1\lib\net462\Castle.Core.dll
-
- ..\packages\CefSharp.Common.131.3.50\lib\net462\CefSharp.dll
+
+ ..\packages\CefSharp.Common.139.0.280\lib\net462\CefSharp.dll
-
- ..\packages\CefSharp.Common.131.3.50\lib\net462\CefSharp.Core.dll
+
+ ..\packages\CefSharp.Common.139.0.280\lib\net462\CefSharp.Core.dll
-
- ..\packages\Microsoft.ApplicationInsights.2.22.0\lib\net46\Microsoft.ApplicationInsights.dll
+
+ ..\packages\Microsoft.ApplicationInsights.2.23.0\lib\net46\Microsoft.ApplicationInsights.dll
-
- ..\packages\Microsoft.Testing.Platform.MSBuild.1.5.2\lib\netstandard2.0\Microsoft.Testing.Extensions.MSBuild.dll
+
+ ..\packages\Microsoft.Testing.Platform.MSBuild.1.8.3\lib\netstandard2.0\Microsoft.Testing.Extensions.MSBuild.dll
-
- ..\packages\Microsoft.Testing.Extensions.Telemetry.1.5.2\lib\netstandard2.0\Microsoft.Testing.Extensions.Telemetry.dll
+
+ ..\packages\Microsoft.Testing.Extensions.Telemetry.1.8.3\lib\netstandard2.0\Microsoft.Testing.Extensions.Telemetry.dll
-
- ..\packages\Microsoft.Testing.Extensions.TrxReport.Abstractions.1.5.2\lib\netstandard2.0\Microsoft.Testing.Extensions.TrxReport.Abstractions.dll
+
+ ..\packages\Microsoft.Testing.Extensions.TrxReport.Abstractions.1.8.3\lib\netstandard2.0\Microsoft.Testing.Extensions.TrxReport.Abstractions.dll
-
- ..\packages\Microsoft.Testing.Extensions.VSTestBridge.1.5.2\lib\netstandard2.0\Microsoft.Testing.Extensions.VSTestBridge.dll
+
+ ..\packages\Microsoft.Testing.Extensions.VSTestBridge.1.8.3\lib\netstandard2.0\Microsoft.Testing.Extensions.VSTestBridge.dll
-
- ..\packages\Microsoft.Testing.Platform.1.5.2\lib\netstandard2.0\Microsoft.Testing.Platform.dll
+
+ ..\packages\Microsoft.Testing.Platform.1.8.3\lib\netstandard2.0\Microsoft.Testing.Platform.dll
+
+
+ ..\packages\Microsoft.TestPlatform.AdapterUtilities.17.14.1\lib\net462\Microsoft.TestPlatform.AdapterUtilities.dll
+ True
- ..\packages\Microsoft.TestPlatform.ObjectModel.17.12.0\lib\net462\Microsoft.TestPlatform.CoreUtilities.dll
+ ..\packages\Microsoft.TestPlatform.ObjectModel.17.14.1\lib\net462\Microsoft.TestPlatform.CoreUtilities.dll
- ..\packages\Microsoft.TestPlatform.ObjectModel.17.12.0\lib\net462\Microsoft.TestPlatform.PlatformAbstractions.dll
+ ..\packages\Microsoft.TestPlatform.ObjectModel.17.14.1\lib\net462\Microsoft.TestPlatform.PlatformAbstractions.dll
- ..\packages\Microsoft.TestPlatform.ObjectModel.17.12.0\lib\net462\Microsoft.VisualStudio.TestPlatform.ObjectModel.dll
+ ..\packages\Microsoft.TestPlatform.ObjectModel.17.14.1\lib\net462\Microsoft.VisualStudio.TestPlatform.ObjectModel.dll
- ..\packages\MSTest.TestFramework.3.7.2\lib\net462\Microsoft.VisualStudio.TestPlatform.TestFramework.dll
+ ..\packages\MSTest.TestFramework.3.10.3\lib\net462\Microsoft.VisualStudio.TestPlatform.TestFramework.dll
- ..\packages\MSTest.TestFramework.3.7.2\lib\net462\Microsoft.VisualStudio.TestPlatform.TestFramework.Extensions.dll
+ ..\packages\MSTest.TestFramework.3.10.3\lib\net462\Microsoft.VisualStudio.TestPlatform.TestFramework.Extensions.dll
..\packages\Moq.4.20.72\lib\net462\Moq.dll
-
- ..\packages\NuGet.Frameworks.6.12.1\lib\net472\NuGet.Frameworks.dll
+
+ ..\packages\NuGet.Frameworks.6.14.0\lib\net472\NuGet.Frameworks.dll
-
- ..\packages\System.Buffers.4.6.0\lib\net462\System.Buffers.dll
+
+ ..\packages\System.Buffers.4.6.1\lib\net462\System.Buffers.dll
-
- ..\packages\System.Collections.Immutable.9.0.1\lib\net462\System.Collections.Immutable.dll
+
+ ..\packages\System.Collections.Immutable.9.0.8\lib\net462\System.Collections.Immutable.dll
-
- ..\packages\System.Diagnostics.DiagnosticSource.9.0.1\lib\net462\System.Diagnostics.DiagnosticSource.dll
+
+ ..\packages\System.Diagnostics.DiagnosticSource.9.0.8\lib\net462\System.Diagnostics.DiagnosticSource.dll
-
- ..\packages\System.Memory.4.6.0\lib\net462\System.Memory.dll
+
+ ..\packages\System.Memory.4.6.3\lib\net462\System.Memory.dll
-
- ..\packages\System.Numerics.Vectors.4.6.0\lib\net462\System.Numerics.Vectors.dll
+
+ ..\packages\System.Numerics.Vectors.4.6.1\lib\net462\System.Numerics.Vectors.dll
-
- ..\packages\System.Reflection.Metadata.9.0.1\lib\net462\System.Reflection.Metadata.dll
+
+ ..\packages\System.Reflection.Metadata.9.0.8\lib\net462\System.Reflection.Metadata.dll
-
- ..\packages\System.Runtime.CompilerServices.Unsafe.6.1.0\lib\net462\System.Runtime.CompilerServices.Unsafe.dll
+
+ ..\packages\System.Runtime.CompilerServices.Unsafe.6.1.2\lib\net462\System.Runtime.CompilerServices.Unsafe.dll
-
- ..\packages\System.Threading.Tasks.Extensions.4.6.0\lib\net462\System.Threading.Tasks.Extensions.dll
+
+ ..\packages\System.Threading.Tasks.Extensions.4.6.3\lib\net462\System.Threading.Tasks.Extensions.dll
@@ -200,11 +204,8 @@
-
-
-
-
-
+
+
@@ -212,18 +213,22 @@
This project references NuGet package(s) that are missing on this computer. Use NuGet Package Restore to download them. For more information, see http://go.microsoft.com/fwlink/?LinkID=322105. The missing file is {0}.
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
-
-
-
+
+
+
+
+
\ No newline at end of file
diff --git a/SafeExamBrowser.Browser.UnitTests/app.config b/SafeExamBrowser.Browser.UnitTests/app.config
index ee510e7..4e06ece 100644
--- a/SafeExamBrowser.Browser.UnitTests/app.config
+++ b/SafeExamBrowser.Browser.UnitTests/app.config
@@ -4,11 +4,11 @@
-
+
-
+
@@ -16,11 +16,11 @@
-
+
-
+
@@ -28,27 +28,27 @@
-
+
-
+
-
+
-
+
-
+
-
+
diff --git a/SafeExamBrowser.Browser.UnitTests/packages.config b/SafeExamBrowser.Browser.UnitTests/packages.config
index da5a1d8..71db1cb 100644
--- a/SafeExamBrowser.Browser.UnitTests/packages.config
+++ b/SafeExamBrowser.Browser.UnitTests/packages.config
@@ -1,27 +1,28 @@
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/SafeExamBrowser.Browser/BrowserApplication.cs b/SafeExamBrowser.Browser/BrowserApplication.cs
index b27ed63..17c8962 100644
--- a/SafeExamBrowser.Browser/BrowserApplication.cs
+++ b/SafeExamBrowser.Browser/BrowserApplication.cs
@@ -18,6 +18,7 @@ using SafeExamBrowser.Applications.Contracts.Events;
using SafeExamBrowser.Browser.Contracts;
using SafeExamBrowser.Browser.Contracts.Events;
using SafeExamBrowser.Browser.Events;
+using SafeExamBrowser.Browser.Integrations;
using SafeExamBrowser.Configuration.Contracts;
using SafeExamBrowser.Configuration.Contracts.Cryptography;
using SafeExamBrowser.Core.Contracts.Resources.Icons;
@@ -119,6 +120,7 @@ namespace SafeExamBrowser.Browser
InitializeCookies();
InitializeDownAndUploadDirectory();
InitializeIntegrityKeys();
+ InitializePreferences();
logger.Info("Initialized browser.");
}
@@ -167,6 +169,12 @@ namespace SafeExamBrowser.Browser
private void CreateNewWindow(PopupRequestedEventArgs args = default)
{
var id = ++windowIdCounter;
+ var integrations = new Integration[]
+ {
+ new GenericIntegration(logger.CloneFor($"{nameof(GenericIntegration)} #{id}")),
+ new EdxIntegration(logger.CloneFor($"{nameof(EdxIntegration)} #{id}")),
+ new MoodleIntegration(logger.CloneFor($"{nameof(MoodleIntegration)} #{id}"))
+ };
var isMainWindow = windows.Count == 0;
var startUrl = GenerateStartUrl();
var windowLogger = logger.CloneFor($"Browser Window #{id}");
@@ -176,6 +184,7 @@ namespace SafeExamBrowser.Browser
fileSystemDialog,
hashAlgorithm,
id,
+ integrations,
isMainWindow,
keyGenerator,
windowLogger,
@@ -197,7 +206,7 @@ namespace SafeExamBrowser.Browser
window.InitializeControl();
windows.Add(window);
- if (args != default(PopupRequestedEventArgs))
+ if (args != default)
{
args.Window = window;
}
@@ -213,6 +222,7 @@ namespace SafeExamBrowser.Browser
private void DeleteCookies()
{
var callback = new TaskDeleteCookiesCallback();
+ var cookieManager = Cef.GetGlobalCookieManager();
callback.Task.ContinueWith(task =>
{
@@ -226,7 +236,7 @@ namespace SafeExamBrowser.Browser
}
});
- if (Cef.GetGlobalCookieManager().DeleteCookies(callback: callback))
+ if (cookieManager != default && cookieManager.DeleteCookies(callback: callback))
{
logger.Debug("Successfully initiated cookie deletion.");
}
@@ -316,7 +326,6 @@ namespace SafeExamBrowser.Browser
cefSettings.AcceptLanguageList = CultureInfo.CurrentUICulture.Name;
cefSettings.CachePath = appConfig.BrowserCachePath;
- cefSettings.CefCommandLineArgs.Add("touch-events", "enabled");
cefSettings.LogFile = appConfig.BrowserLogFilePath;
cefSettings.LogSeverity = error ? LogSeverity.Error : (warning ? LogSeverity.Warning : LogSeverity.Info);
cefSettings.PersistSessionCookies = !settings.DeleteCookiesOnStartup || !settings.DeleteCookiesOnShutdown;
@@ -339,6 +348,7 @@ namespace SafeExamBrowser.Browser
cefSettings.CefCommandLineArgs.Add("enable-media-stream");
cefSettings.CefCommandLineArgs.Add("enable-usermedia-screen-capturing");
+ cefSettings.CefCommandLineArgs.Add("touch-events", "enabled");
cefSettings.CefCommandLineArgs.Add("use-fake-ui-for-media-stream");
InitializeProxySettings(cefSettings);
@@ -417,6 +427,18 @@ namespace SafeExamBrowser.Browser
}
}
+ private void InitializePreferences()
+ {
+ Cef.UIThreadTaskFactory.StartNew(() =>
+ {
+ using (var requestContext = Cef.GetGlobalRequestContext())
+ {
+ requestContext.SetPreference("autofill.credit_card_enabled", false, out _);
+ requestContext.SetPreference("autofill.profile_enabled", false, out _);
+ }
+ });
+ }
+
private void InitializeProxySettings(CefSettings cefSettings)
{
if (settings.Proxy.Policy == ProxyPolicy.Custom)
@@ -506,6 +528,7 @@ namespace SafeExamBrowser.Browser
private void Window_ResetRequested()
{
logger.Info("Attempting to reset browser...");
+
AwaitReady();
foreach (var window in windows)
diff --git a/SafeExamBrowser.Browser/BrowserControl.cs b/SafeExamBrowser.Browser/BrowserControl.cs
index 445d4b0..823dc66 100644
--- a/SafeExamBrowser.Browser/BrowserControl.cs
+++ b/SafeExamBrowser.Browser/BrowserControl.cs
@@ -23,6 +23,7 @@ namespace SafeExamBrowser.Browser
{
private readonly Clipboard clipboard;
private readonly ICefSharpControl control;
+ private readonly IContextMenuHandler contextMenuHandler;
private readonly IDialogHandler dialogHandler;
private readonly IDisplayHandler displayHandler;
private readonly IDownloadHandler downloadHandler;
@@ -47,6 +48,7 @@ namespace SafeExamBrowser.Browser
public BrowserControl(
Clipboard clipboard,
ICefSharpControl control,
+ IContextMenuHandler contextMenuHandler,
IDialogHandler dialogHandler,
IDisplayHandler displayHandler,
IDownloadHandler downloadHandler,
@@ -58,8 +60,9 @@ namespace SafeExamBrowser.Browser
IRenderProcessMessageHandler renderProcessMessageHandler,
IRequestHandler requestHandler)
{
- this.control = control;
this.clipboard = clipboard;
+ this.control = control;
+ this.contextMenuHandler = contextMenuHandler;
this.dialogHandler = dialogHandler;
this.displayHandler = displayHandler;
this.downloadHandler = downloadHandler;
@@ -89,31 +92,20 @@ namespace SafeExamBrowser.Browser
{
control.BrowserCore.EvaluateScriptAsync(code).ContinueWith(t =>
{
- callback?.Invoke(new JavaScriptResult
- {
- Message = t.Result.Message,
- Result = t.Result.Result,
- Success = t.Result.Success
- });
+ callback?.Invoke(new JavaScriptResult { Message = t.Result.Message, Result = t.Result.Result, Success = t.Result.Success });
});
}
else
{
- Task.Run(() => callback?.Invoke(new JavaScriptResult
- {
- Message = "JavaScript can't be executed in main frame!",
- Success = false
- }));
+ Task.Run(() => callback?.Invoke(new JavaScriptResult { Message = "Could not execute JavaScript in main frame!", Success = false }));
}
}
catch (Exception e)
{
- logger.Error($"Failed to execute JavaScript '{(code.Length > 50 ? code.Take(50) : code)}'!", e);
- Task.Run(() => callback?.Invoke(new JavaScriptResult
- {
- Message = $"Failed to execute JavaScript '{(code.Length > 50 ? code.Take(50) : code)}'! Reason: {e.Message}",
- Success = false
- }));
+ var message = "Failed to execute JavaScript in main frame!";
+
+ logger.Error(message, e);
+ Task.Run(() => callback?.Invoke(new JavaScriptResult { Message = $"{message} Reason: {e.Message}", Success = false }));
}
}
@@ -129,10 +121,13 @@ namespace SafeExamBrowser.Browser
control.AddressChanged += (o, e) => AddressChanged?.Invoke(e.Address);
control.AuthCredentialsRequired += (w, b, o, i, h, p, r, s, c, a) => a.Value = requestHandler.GetAuthCredentials(w, b, o, i, h, p, r, s, c);
control.BeforeBrowse += (w, b, f, r, u, i, a) => a.Value = requestHandler.OnBeforeBrowse(w, b, f, r, u, i);
+ control.BeforeContextMenu += (w, b, f, p, m) => contextMenuHandler.OnBeforeContextMenu(w, b, f, p, m);
control.BeforeDownload += (w, b, d, c, a) => a.Value = a.Value = downloadHandler.OnBeforeDownload(w, b, d, c);
control.BeforeUnloadDialog += (w, b, m, r, c, a) => a.Value = javaScriptDialogHandler.OnBeforeUnloadDialog(w, b, m, r, c);
control.CanDownload += (w, b, u, r, a) => a.Value = downloadHandler.CanDownload(w, b, u, r);
control.ContextCreated += (w, b, f) => renderProcessMessageHandler.OnContextCreated(w, b, f);
+ control.ContextMenuCommand += (w, b, f, p, c, e, a) => a.Value = contextMenuHandler.OnContextMenuCommand(w, b, f, p, c, e);
+ control.ContextMenuDismissed += (w, b, f) => contextMenuHandler.OnContextMenuDismissed(w, b, f);
control.ContextReleased += (w, b, f) => renderProcessMessageHandler.OnContextReleased(w, b, f);
control.DialogClosed += (w, b) => javaScriptDialogHandler.OnDialogClosed(w, b);
control.DownloadUpdated += (w, b, d, c) => downloadHandler.OnDownloadUpdated(w, b, d, c);
@@ -152,6 +147,7 @@ namespace SafeExamBrowser.Browser
control.PreKeyEvent += (IWebBrowser w, IBrowser b, KeyType t, int k, int n, CefEventFlags m, bool i, ref bool s, GenericEventArgs a) => a.Value = keyboardHandler.OnPreKeyEvent(w, b, t, k, n, m, i, ref s);
control.ResetDialogState += (w, b) => javaScriptDialogHandler.OnResetDialogState(w, b);
control.ResourceRequestHandlerRequired += (IWebBrowser w, IBrowser b, IFrame f, IRequest r, bool n, bool d, string i, ref bool h, ResourceRequestEventArgs a) => a.Handler = requestHandler.GetResourceRequestHandler(w, b, f, r, n, d, i, ref h);
+ control.RunContextMenu += (w, b, f, p, m, c, a) => a.Value = contextMenuHandler.RunContextMenu(w, b, f, p, m, c);
control.SetFocus += (w, b, s, a) => a.Value = focusHandler.OnSetFocus(w, b, s);
control.TakeFocus += (w, b, n) => focusHandler.OnTakeFocus(w, b, n);
control.TitleChanged += (o, e) => TitleChanged?.Invoke(e.Title);
@@ -193,9 +189,21 @@ namespace SafeExamBrowser.Browser
control.BrowserCore.SetZoomLevel(level);
}
- private void Clipboard_Changed(long id)
+ private void Clipboard_Changed(string id)
{
- ExecuteJavaScript($"SafeExamBrowser.clipboard.update({id}, '{clipboard.Content}');");
+ try
+ {
+ var script = $"SafeExamBrowser.clipboard.update('{id}', '{clipboard.Content}');";
+
+ foreach (var frame in control.BrowserCore?.GetAllFrames() ?? Enumerable.Empty