The page could crash if the user clicks too many time on Notificate 'Mark as Seen'

This commit is contained in:
nicolas.dorier 2021-09-09 23:53:26 +09:00
parent 649f650da6
commit 3b9c7db481
No known key found for this signature in database
GPG key ID: 6618763EF09186FE
3 changed files with 51 additions and 59 deletions

View file

@ -1,4 +1,3 @@
@inject LinkGenerator linkGenerator
@inject UserManager<ApplicationUser> UserManager
@inject ISettingsRepository SettingsRepository
@using BTCPayServer.HostedServices
@ -56,47 +55,3 @@ else
</a>
</li>
}
@{
var disabled = (await SettingsRepository.GetPolicies()).DisableInstantNotifications;
if (!disabled)
{
var user = await UserManager.GetUserAsync(User);
disabled = user?.DisabledNotifications == "all";
}
}
@if (!disabled)
{
<script type="text/javascript" csp-sha256>
var supportsWebSockets = 'WebSocket' in window && window.WebSocket.CLOSING === 2;
if (supportsWebSockets) {
var loc = window.location, ws_uri;
if (loc.protocol === "https:") {
ws_uri = "wss:";
} else {
ws_uri = "ws:";
}
ws_uri += "//" + loc.host;
ws_uri += "@linkGenerator.GetPathByAction("SubscribeUpdates", "Notifications")";
var newDataEndpoint = "@linkGenerator.GetPathByAction("GetNotificationDropdownUI", "Notifications")";
try {
socket = new WebSocket(ws_uri);
socket.onmessage = function (e) {
$.get(newDataEndpoint, function(data){
$("#notifications-nav-item").replaceWith($(data));
});
};
socket.onerror = function (e) {
console.error("Error while connecting to websocket for notifications (callback)", e);
};
}
catch (e) {
console.error("Error while connecting to websocket for notifications", e);
}
}
</script>
}

View file

@ -50,7 +50,7 @@ namespace BTCPayServer.TagHelpers
_csp = csp;
}
public override async Task ProcessAsync(TagHelperContext context, TagHelperOutput output)
public override void Process(TagHelperContext context, TagHelperOutput output)
{
if (output.Attributes.ContainsName("src"))
return;
@ -59,18 +59,9 @@ namespace BTCPayServer.TagHelpers
if (attr.Value?.ToString() != "text/javascript")
return;
}
if (output.Attributes.ContainsName("csp-sha256"))
{
var sha = CSPEventTagHelper.GetSha256((await output.GetChildContentAsync(true)).GetContent());
_csp.Add("script-src", $"'sha256-{sha}'");
output.Attributes.RemoveAll("csp-sha256");
}
else
{
var nonce = RandomUtils.GetUInt256().ToString().Substring(0, 32);
output.Attributes.Add(new TagHelperAttribute("nonce", nonce));
_csp.Add("script-src", $"'nonce-{nonce}'");
}
var nonce = RandomUtils.GetUInt256().ToString().Substring(0, 32);
output.Attributes.Add(new TagHelperAttribute("nonce", nonce));
_csp.Add("script-src", $"'nonce-{nonce}'");
}
}

View file

@ -12,9 +12,12 @@
@inject RoleManager<IdentityRole> RoleManager
@inject BTCPayServer.Services.BTCPayServerEnvironment Env
@inject ISettingsRepository SettingsRepository
@inject LinkGenerator linkGenerator
@{
var theme = await SettingsRepository.GetTheme();
}
<!DOCTYPE html>
<html lang="en"@(Env.IsDeveloping ? " data-devenv" : "")>
<head>
@ -136,9 +139,19 @@
}
<partial name="LayoutFoot" />
@await RenderSectionAsync("PageFootContent", false)
<partial name="LayoutPartials/SyncModal" />
@{
var notificationDisabled = (await SettingsRepository.GetPolicies()).DisableInstantNotifications;
if (!notificationDisabled)
{
var user = await UserManager.GetUserAsync(User);
notificationDisabled = user?.DisabledNotifications == "all";
}
}
<script type="text/javascript">
const expectedDomain = @Safe.Json(Env.ExpectedHost);
const expectedProtocol = @Safe.Json(Env.ExpectedProtocol);
@ -147,5 +160,38 @@
document.getElementById("browserScheme").innerText = window.location.protocol.substr(0, window.location.protocol.length -1);
}
</script>
@if (!notificationDisabled)
{
<script>
var supportsWebSockets = 'WebSocket' in window && window.WebSocket.CLOSING === 2;
if (supportsWebSockets) {
var loc = window.location, ws_uri;
if (loc.protocol === "https:") {
ws_uri = "wss:";
} else {
ws_uri = "ws:";
}
ws_uri += "//" + loc.host;
ws_uri += "@linkGenerator.GetPathByAction("SubscribeUpdates", "Notifications")";
var newDataEndpoint = "@linkGenerator.GetPathByAction("GetNotificationDropdownUI", "Notifications")";
try {
socket = new WebSocket(ws_uri);
socket.onmessage = function (e) {
$.get(newDataEndpoint, function (data) {
$("#notifications-nav-item").replaceWith($(data));
});
};
socket.onerror = function (e) {
console.error("Error while connecting to websocket for notifications (callback)", e);
};
}
catch (e) {
console.error("Error while connecting to websocket for notifications", e);
}
}
</script>
}
</body>
</html>