mirror of
https://github.com/btcpayserver/btcpayserver.git
synced 2025-01-19 05:33:31 +01:00
PayButton: Fix CSP problems in Firefox (#4376)
* PayButton: Fix CSP problems in Firefox Firefox does not support [`unsafe-hashes`](https://caniuse.com/?search=unsafe-hashes), so I figured it might be best to get rid of the inline event handlers in general. Closes #4325. * Account for multiple paybuttons on one page
This commit is contained in:
parent
5b20be8cfd
commit
484cf9d8a2
@ -1,14 +1,7 @@
|
|||||||
@inject Security.ContentSecurityPolicies csp
|
|
||||||
@using BTCPayServer.Views.Stores
|
@using BTCPayServer.Views.Stores
|
||||||
@model BTCPayServer.Plugins.PayButton.Models.PayButtonViewModel
|
@model BTCPayServer.Plugins.PayButton.Models.PayButtonViewModel
|
||||||
@{
|
@{
|
||||||
ViewData.SetActivePage(StoreNavPages.PayButton, "Pay Button", Context.GetStoreData().Id);
|
ViewData.SetActivePage(StoreNavPages.PayButton, "Pay Button", Context.GetStoreData().Id);
|
||||||
csp.AllowUnsafeHashes("onBTCPayFormSubmit(event);return false");
|
|
||||||
csp.AllowUnsafeHashes("handleSliderChange(event);return false");
|
|
||||||
csp.AllowUnsafeHashes("handleSliderInput(event);return false");
|
|
||||||
csp.AllowUnsafeHashes("handlePriceSlider(event);return false");
|
|
||||||
csp.AllowUnsafeHashes("handlePriceInput(event);return false");
|
|
||||||
csp.AllowUnsafeHashes("handlePlusMinus(event);return false");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@section PageHeadContent {
|
@section PageHeadContent {
|
||||||
@ -27,7 +20,7 @@
|
|||||||
script.src = @(Safe.Json(Model.UrlRoot + "modal/btcpay.js"));
|
script.src = @(Safe.Json(Model.UrlRoot + "modal/btcpay.js"));
|
||||||
document.getElementsByTagName('head')[0].append(script);
|
document.getElementsByTagName('head')[0].append(script);
|
||||||
}
|
}
|
||||||
function onBTCPayFormSubmit(event) {
|
function handleFormSubmit(event) {
|
||||||
event.preventDefault();
|
event.preventDefault();
|
||||||
var xhttp = new XMLHttpRequest();
|
var xhttp = new XMLHttpRequest();
|
||||||
xhttp.onreadystatechange = function() {
|
xhttp.onreadystatechange = function() {
|
||||||
@ -38,6 +31,12 @@
|
|||||||
xhttp.open('POST', event.target.getAttribute('action'), true);
|
xhttp.open('POST', event.target.getAttribute('action'), true);
|
||||||
xhttp.send(new FormData(event.target));
|
xhttp.send(new FormData(event.target));
|
||||||
}
|
}
|
||||||
|
document.querySelectorAll(".btcpay-form").forEach(function(el) {
|
||||||
|
if (!el.dataset.initialized) {
|
||||||
|
el.addEventListener('submit', handleFormSubmit);
|
||||||
|
el.dataset.initialized = true;
|
||||||
|
}
|
||||||
|
});
|
||||||
</template>
|
</template>
|
||||||
<template id="template-price-buttons" csp-allow>
|
<template id="template-price-buttons" csp-allow>
|
||||||
function handlePlusMinus(event) {
|
function handlePlusMinus(event) {
|
||||||
@ -55,6 +54,12 @@
|
|||||||
el.value = price + step > max ? max : price + step;
|
el.value = price + step > max ? max : price + step;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
document.querySelectorAll(".btcpay-form .plus-minus").forEach(function(el) {
|
||||||
|
if (!el.dataset.initialized) {
|
||||||
|
el.addEventListener('click', handlePlusMinus);
|
||||||
|
el.dataset.initialized = true;
|
||||||
|
}
|
||||||
|
});
|
||||||
</template>
|
</template>
|
||||||
<template id="template-price-input" csp-allow>
|
<template id="template-price-input" csp-allow>
|
||||||
function handlePriceInput(event) {
|
function handlePriceInput(event) {
|
||||||
@ -70,6 +75,12 @@
|
|||||||
event.target.value = max;
|
event.target.value = max;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
document.querySelectorAll(".btcpay-form .btcpay-input-price").forEach(function(el) {
|
||||||
|
if (!el.dataset.initialized) {
|
||||||
|
el.addEventListener('input', handlePriceInput);
|
||||||
|
el.dataset.initialized = true;
|
||||||
|
}
|
||||||
|
});
|
||||||
</template>
|
</template>
|
||||||
<template id="template-price-slider" csp-allow>
|
<template id="template-price-slider" csp-allow>
|
||||||
function handleSliderChange(event) {
|
function handleSliderChange(event) {
|
||||||
@ -86,13 +97,23 @@
|
|||||||
}
|
}
|
||||||
root.querySelector('.btcpay-input-range').value = el.value;
|
root.querySelector('.btcpay-input-range').value = el.value;
|
||||||
}
|
}
|
||||||
|
|
||||||
function handleSliderInput(event) {
|
function handleSliderInput(event) {
|
||||||
event.target.closest('.btcpay-form').querySelector('.btcpay-input-price').value = event.target.value;
|
event.target.closest('.btcpay-form').querySelector('.btcpay-input-price').value = event.target.value;
|
||||||
}
|
}
|
||||||
|
document.querySelectorAll(".btcpay-form .btcpay-input-range").forEach(function(el) {
|
||||||
|
if (!el.dataset.initialized) {
|
||||||
|
el.addEventListener('input', handleSliderInput);
|
||||||
|
el.dataset.initialized = true;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
document.querySelectorAll(".btcpay-form .btcpay-input-price").forEach(function(el) {
|
||||||
|
if (!el.dataset.initialized) {
|
||||||
|
el.addEventListener('change', handleSliderChange);
|
||||||
|
el.dataset.initialized = true;
|
||||||
|
}
|
||||||
|
});
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
const srvModel = @Safe.Json(Model);
|
const srvModel = @Safe.Json(Model);
|
||||||
const payButtonCtrl = new Vue({
|
const payButtonCtrl = new Vue({
|
||||||
|
@ -107,7 +107,7 @@ function inputChanges(event, buttonSize) {
|
|||||||
// Styles
|
// Styles
|
||||||
getStyles('template-paybutton-styles') + (srvModel.buttonType == '2' ? getStyles('template-slider-styles') : '') +
|
getStyles('template-paybutton-styles') + (srvModel.buttonType == '2' ? getStyles('template-slider-styles') : '') +
|
||||||
// Form
|
// Form
|
||||||
'<form method="POST"' + (srvModel.useModal ? ' onsubmit="onBTCPayFormSubmit(event);return false"' : '') + ' action="' + esc(srvModel.urlRoot) + actionUrl + '" class="btcpay-form btcpay-form--' + (srvModel.fitButtonInline ? 'inline' : 'block') +'">\n' +
|
'<form method="POST" action="' + esc(srvModel.urlRoot) + actionUrl + '" class="btcpay-form btcpay-form--' + (srvModel.fitButtonInline ? 'inline' : 'block') +'">\n' +
|
||||||
addInput("storeId", srvModel.storeId);
|
addInput("storeId", srvModel.storeId);
|
||||||
|
|
||||||
if (app) {
|
if (app) {
|
||||||
@ -147,7 +147,7 @@ function inputChanges(event, buttonSize) {
|
|||||||
const max = srvModel.max == null ? null : parseInt(srvModel.max);
|
const max = srvModel.max == null ? null : parseInt(srvModel.max);
|
||||||
|
|
||||||
html += ' <div class="btcpay-custom-container">\n';
|
html += ' <div class="btcpay-custom-container">\n';
|
||||||
html += addInputPrice(priceInputName, srvModel.price, width, min, max, step, 'handleSliderChange(event);return false');
|
html += addInputPrice(priceInputName, srvModel.price, width, min, max, step);
|
||||||
if (allowCurrencySelection) html += addSelectCurrency(srvModel.currency);
|
if (allowCurrencySelection) html += addSelectCurrency(srvModel.currency);
|
||||||
html += addSlider(srvModel.price, srvModel.min, srvModel.max, srvModel.step, width);
|
html += addSlider(srvModel.price, srvModel.min, srvModel.max, srvModel.step, width);
|
||||||
html += ' </div>\n';
|
html += ' </div>\n';
|
||||||
@ -206,17 +206,17 @@ function addPlusMinusButton(type, step, min, max) {
|
|||||||
min = min == null ? 1 : parseInt(min);
|
min = min == null ? 1 : parseInt(min);
|
||||||
max = max == null ? null : parseInt(max);
|
max = max == null ? null : parseInt(max);
|
||||||
|
|
||||||
return ` <button class="plus-minus" type="button" onclick="handlePlusMinus(event);return false" data-type="${type}" data-step="${step}" data-min="${min}" data-max="${max}">${type}</button>\n`;
|
return ` <button class="plus-minus" type="button" data-type="${type}" data-step="${step}" data-min="${min}" data-max="${max}">${type}</button>\n`;
|
||||||
}
|
}
|
||||||
|
|
||||||
function addInputPrice(name, price, widthInput, min = 0, max = 'none', step = 'any', onChange = null) {
|
function addInputPrice(name, price, widthInput, min = 0, max = 'none', step = 'any') {
|
||||||
if (!price) price = min
|
if (!price) price = min
|
||||||
return ` <input class="btcpay-input-price" type="number" name="${esc(name)}" min="${min}" max="${max}" step="${step}" value="${price}" data-price="${price}" style="width:${widthInput};" oninput="handlePriceInput(event);return false"${onChange ? ` onchange="${onChange}"` : ''} />\n`;
|
return ` <input class="btcpay-input-price" type="number" name="${esc(name)}" min="${min}" max="${max}" step="${step}" value="${price}" data-price="${price}" style="width:${widthInput};" />\n`;
|
||||||
}
|
}
|
||||||
|
|
||||||
function addSlider(price, min, max, step, width) {
|
function addSlider(price, min, max, step, width) {
|
||||||
if (!price) price = min
|
if (!price) price = min
|
||||||
return ` <input type="range" class="btcpay-input-range" min="${min}" max="${max}" step="${step}" value="${price}" style="width:${width};margin-bottom:15px;" oninput="handleSliderInput(event);return false" />\n`;
|
return ` <input type="range" class="btcpay-input-range" min="${min}" max="${max}" step="${step}" value="${price}" style="width:${width};margin-bottom:15px;" />\n`;
|
||||||
}
|
}
|
||||||
|
|
||||||
function addSelectCurrency(currency) {
|
function addSelectCurrency(currency) {
|
||||||
|
Loading…
Reference in New Issue
Block a user