Skip to content

Commit

Permalink
fix: xss security vulnerability with the avatar selection
Browse files Browse the repository at this point in the history
fix: don't update next payment date for disabled subscriptions
feat: add total monthly cost trend graph to the statistics page
feat: allow email notifications without authentication
  • Loading branch information
ellite authored Dec 21, 2024
1 parent 153a6a4 commit e7185f9
Show file tree
Hide file tree
Showing 27 changed files with 126 additions and 11 deletions.
2 changes: 1 addition & 1 deletion endpoints/cronjobs/updatenextpayment.php
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@
$cycles[$cycleId] = $row;
}

$query = "SELECT id, next_payment, frequency, cycle FROM subscriptions WHERE next_payment < :currentDate AND auto_renew = 1";
$query = "SELECT id, next_payment, frequency, cycle FROM subscriptions WHERE next_payment < :currentDate AND auto_renew = 1 AND inactive = 0";
$stmt = $db->prepare($query);
$stmt->bindValue(':currentDate', $currentDate->format('Y-m-d'));
$result = $stmt->execute();
Expand Down
2 changes: 1 addition & 1 deletion endpoints/user/save_user.php
Original file line number Diff line number Diff line change
Expand Up @@ -231,7 +231,7 @@ function resizeAndUploadAvatar($uploadedFile, $uploadDir, $name)
}
}

$avatar = $_POST['avatar'];
$avatar = filter_var($_POST['avatar'], FILTER_SANITIZE_URL);
$main_currency = $_POST['main_currency'];
$language = $_POST['language'];

Expand Down
2 changes: 1 addition & 1 deletion includes/header.php
Original file line number Diff line number Diff line change
Expand Up @@ -161,7 +161,7 @@ function hex2rgb($hex)
<nav>
<div class="dropdown">
<button class="dropbtn" onClick="toggleDropdown()">
<img src="<?= $userData['avatar'] ?>" alt="me" id="avatar">
<img src="<?= htmlspecialchars($userData['avatar'], ENT_QUOTES, 'UTF-8') ?>" alt="me" id="avatar">
<span id="user" class="mobileNavigationHideOnMobile"><?= $username ?></span>
</button>
<div class="dropdown-content">
Expand Down
1 change: 1 addition & 0 deletions includes/i18n/de.php
Original file line number Diff line number Diff line change
Expand Up @@ -116,6 +116,7 @@
"category_split" => "Kategorien",
"household_split" => "Haushalt",
"payment_method_split" => "Zahlungsmethode",
"total_cost_trend" => "Kostenentwicklung",
// About page
"about_and_credits" => "Informationen und Danksagungen",
"credits" => "Danksagungen",
Expand Down
1 change: 1 addition & 0 deletions includes/i18n/el.php
Original file line number Diff line number Diff line change
Expand Up @@ -116,6 +116,7 @@
"category_split" => "Διαχωρισμός κατηγορίας",
"household_split" => "Διαχωρισμός νοικοκυριού",
"payment_method_split" => "Διαχωρισμός τρόπου πληρωμής",
"total_cost_trend" => "Τάση συνολικού κόστους",
// About page
"about_and_credits" => "Σχετικά και Credits",
"credits" => "Credits",
Expand Down
1 change: 1 addition & 0 deletions includes/i18n/en.php
Original file line number Diff line number Diff line change
Expand Up @@ -116,6 +116,7 @@
"category_split" => "Category Split",
"household_split" => "Household Split",
"payment_method_split" => "Payment Method Split",
"total_cost_trend" => "Total Cost Trend",
// About page
"about_and_credits" => "About and Credits",
"credits" => "Credits",
Expand Down
1 change: 1 addition & 0 deletions includes/i18n/es.php
Original file line number Diff line number Diff line change
Expand Up @@ -116,6 +116,7 @@
"category_split" => "División por Categoría",
"household_split" => "División por Hogar",
"payment_method_split" => "División por Método de Pago",
"total_cost_trend" => "Tendencia del Costo Total",
// About page
"about_and_credits" => "Acerca de y Créditos",
"credits" => "Créditos",
Expand Down
2 changes: 2 additions & 0 deletions includes/i18n/fr.php
Original file line number Diff line number Diff line change
Expand Up @@ -116,6 +116,8 @@
"category_split" => "Répartition par catégorie",
"household_split" => "Répartition du ménage",
"payment_method_split" => "Répartition par méthode de paiement",
"total_cost_trend" => "Tendance du coût total",

// Page À propos
"about_and_credits" => "À propos et crédits",
"credits" => "Crédits",
Expand Down
1 change: 1 addition & 0 deletions includes/i18n/it.php
Original file line number Diff line number Diff line change
Expand Up @@ -122,6 +122,7 @@
"category_split" => 'Suddivisione per categoria',
"household_split" => 'Suddivisione per nucleo familiare',
"payment_method_split" => 'Suddivisione per metodo di pagamento',
"total_cost_trend" => 'Trend del costo totale',

// About
"about_and_credits" => 'Informazioni e crediti',
Expand Down
1 change: 1 addition & 0 deletions includes/i18n/jp.php
Original file line number Diff line number Diff line change
Expand Up @@ -116,6 +116,7 @@
"category_split" => "カテゴリ別",
"household_split" => "世帯別",
"payment_method_split" => "支払い方法別",
"total_cost_trend" => "合計費用のトレンド",
// About page
"about_and_credits" => "概要とクレジット",
"credits" => "クレジット",
Expand Down
1 change: 1 addition & 0 deletions includes/i18n/ko.php
Original file line number Diff line number Diff line change
Expand Up @@ -116,6 +116,7 @@
"category_split" => "카테고리별",
"household_split" => "가구별",
"payment_method_split" => "지불방법별",
"total_cost_trend" => "총 비용 추이",
// About page
"about_and_credits" => "개요 및 크레딧",
"credits" => "크레딧",
Expand Down
1 change: 1 addition & 0 deletions includes/i18n/nl.php
Original file line number Diff line number Diff line change
Expand Up @@ -116,6 +116,7 @@
"category_split" => "Categorieverdeling",
"household_split" => "Huishoudenverdeling",
"payment_method_split" => "Betaalmethodeverdeling",
"total_cost_trend" => "Totale kosten trend",
// About page
"about_and_credits" => "Over en credits",
"credits" => "Credits",
Expand Down
1 change: 1 addition & 0 deletions includes/i18n/pl.php
Original file line number Diff line number Diff line change
Expand Up @@ -116,6 +116,7 @@
"category_split" => "Podział kategorii",
"household_split" => "Podział gospodarstwa domowego",
"payment_method_split" => "Podział metod płatności",
"total_cost_trend" => "Trend całkowitego kosztu",
// About page
"about_and_credits" => "Informacje i podziękowania",
"credits" => "Podziękowania",
Expand Down
1 change: 1 addition & 0 deletions includes/i18n/pt.php
Original file line number Diff line number Diff line change
Expand Up @@ -116,6 +116,7 @@
"category_split" => "Por Categoria",
"household_split" => "Por Membro",
"payment_method_split" => "Por Método de Pagamento",
"total_cost_trend" => "Tendência de Custo Total",
// About page
"about_and_credits" => "Sobre e Créditos",
"credits" => "Créditos",
Expand Down
1 change: 1 addition & 0 deletions includes/i18n/pt_br.php
Original file line number Diff line number Diff line change
Expand Up @@ -116,6 +116,7 @@
"category_split" => "Por categoria",
"household_split" => "Por membro",
"payment_method_split" => "Por método de pagamento",
"total_cost_trend" => "Tendência de custo total",
// About page
"about_and_credits" => "Sobre e Créditos",
"credits" => "Créditos",
Expand Down
1 change: 1 addition & 0 deletions includes/i18n/ru.php
Original file line number Diff line number Diff line change
Expand Up @@ -116,6 +116,7 @@
"category_split" => "По категориям",
"household_split" => "По членам семьи",
"payment_method_split" => "По способам оплаты",
"total_cost_trend" => "Тенденция общей стоимости",
// About page
"about_and_credits" => "О компании и авторах",
"credits" => "Благодарности",
Expand Down
1 change: 1 addition & 0 deletions includes/i18n/sl.php
Original file line number Diff line number Diff line change
Expand Up @@ -116,6 +116,7 @@
"category_split" => "Razdelitev kategorije",
"household_split" => "Razdelitev gospodinjstva",
"payment_method_split" => "Razdelitev načina plačila",
"total_cost_trend" => "Trend skupnih stroškov",
// About page
"about_and_credits" => "O programu in zahvale",
"credits" => "Zahvale",
Expand Down
1 change: 1 addition & 0 deletions includes/i18n/sr.php
Original file line number Diff line number Diff line change
Expand Up @@ -116,6 +116,7 @@
"category_split" => "Подела по категоријама",
"household_split" => "Подела по домаћинству",
"payment_method_split" => "Подела по начинима плаћања",
"total_cost_trend" => "Тренд укупних трошкова",
// Страница о апликацији
"about_and_credits" => "О апликацији и заслугама",
"credits" => "Заслуге",
Expand Down
1 change: 1 addition & 0 deletions includes/i18n/sr_lat.php
Original file line number Diff line number Diff line change
Expand Up @@ -116,6 +116,7 @@
"category_split" => "Podela po kategorijama",
"household_split" => "Podela po domaćinstvima",
"payment_method_split" => "Podela po načinu plaćanja",
"total_cost_trend" => "Trend ukupnog troška",
// Stranica O aplikaciji
"about_and_credits" => "O aplikaciji i zasluge",
"credits" => "Zasluge",
Expand Down
1 change: 1 addition & 0 deletions includes/i18n/tr.php
Original file line number Diff line number Diff line change
Expand Up @@ -116,6 +116,7 @@
"category_split" => "Kategori Bölümü",
"household_split" => "Hane Bölümü",
"payment_method_split" => "Ödeme Yöntemi Bölümü",
"total_cost_trend" => "Toplam Maliyet Eğilimi",
// About page
"about_and_credits" => "Hakkında ve Teşekkürler",
"credits" => "Teşekkürler",
Expand Down
1 change: 1 addition & 0 deletions includes/i18n/vi.php
Original file line number Diff line number Diff line change
Expand Up @@ -116,6 +116,7 @@
"category_split" => "Phân chia theo danh mục",
"household_split" => "Phân chia theo hộ gia đình",
"payment_method_split" => "Phân chia theo phương thức thanh toán",
"total_cost_trend" => "Xu hướng chi phí tổng cộng",
// About page
"about_and_credits" => "Giới thiệu và cảm ơn",
"credits" => "Cảm ơn",
Expand Down
1 change: 1 addition & 0 deletions includes/i18n/zh_cn.php
Original file line number Diff line number Diff line change
Expand Up @@ -122,6 +122,7 @@
"category_split" => "分类视图",
"household_split" => "家庭视图",
"payment_method_split" => "支付方式视图",
"total_cost_trend" => "总费用趋势",

// 关于页面
"about_and_credits" => "关于和鸣谢",
Expand Down
1 change: 1 addition & 0 deletions includes/i18n/zh_tw.php
Original file line number Diff line number Diff line change
Expand Up @@ -116,6 +116,7 @@
"category_split" => "類別分割",
"household_split" => "家庭分割",
"payment_method_split" => "付款方式分割",
"total_cost_trend" => "總費用趨勢",
// 關於頁面
"about_and_credits" => "關於和致謝",
"credits" => "致謝",
Expand Down
2 changes: 1 addition & 1 deletion includes/version.php
Original file line number Diff line number Diff line change
@@ -1,3 +1,3 @@
<?php
$version = "v2.41.0";
$version = "v2.42.0";
?>
4 changes: 2 additions & 2 deletions profile.php
Original file line number Diff line number Diff line change
Expand Up @@ -19,14 +19,14 @@
<div class="fields">
<div>
<div class="user-avatar">
<img src="<?= $userData['avatar'] ?>" alt="avatar" class="avatar" id="avatarImg"
<img src="<?= htmlspecialchars($userData['avatar'], ENT_QUOTES, 'UTF-8') ?>" alt="avatar" class="avatar" id="avatarImg"
onClick="toggleAvatarSelect()" />
<span class="edit-avatar" onClick="toggleAvatarSelect()" title="Change Avatar">
<i class="fa-solid fa-pencil"></i>
</span>
</div>

<input type="hidden" name="avatar" value="<?= $userData['avatar'] ?>" id="avatarUser" />
<input type="hidden" name="avatar" value="<?= htmlspecialchars($userData['avatar'], ENT_QUOTES, 'UTF-8') ?>" id="avatarUser" />
<div class="avatar-select" id="avatarSelect">
<div class="avatar-list">
<?php foreach (scandir('images/avatars') as $index => $image): ?>
Expand Down
64 changes: 64 additions & 0 deletions scripts/stats.js
Original file line number Diff line number Diff line change
Expand Up @@ -21,11 +21,75 @@ function loadGraph(container, dataPoints, currency, run) {
animateRotate: true,
animateScale: true,
},
plugins: {
legend: {
display: true,
position: 'top',
},
tooltip: {
callbacks: {
label: function(context) {
let label = " ";
if (currency) {
label += new Intl.NumberFormat(navigator.language, { style: 'currency', currency }).format(context.raw);
} else {
label += new Intl.NumberFormat(navigator.language).format(context.raw);
}
return label;
}
}
}
}
},
});
}
}

function loadLineGraph(container, dataPoints, currency, run) {
if (run) {
var ctx = document.getElementById(container).getContext('2d');

var chart = new Chart(ctx, {
type: 'line',
data: {
datasets: [{
label: '',
data: dataPoints.map(point => point.y),
}],
labels: dataPoints.map(point => {
return `${point.label}`;
}),
},
options: {
animation: {
animateRotate: true,
animateScale: true,
},
scales: {
y: {
beginAtZero: false,
ticks: {
callback: function(value, index, values) {
if (currency) {
return new Intl.NumberFormat(navigator.language, { style: 'currency', currency }).format(value);
} else {
return new Intl.NumberFormat(navigator.language).format(value);
}
}
}
}
},
plugins: {
legend: {
display: false
}
}
}
});
}
}


function closeSubMenus() {
var subMenus = document.querySelectorAll('.filtermenu-submenu-content');
subMenus.forEach(subMenu => {
Expand Down
40 changes: 35 additions & 5 deletions stats.php
Original file line number Diff line number Diff line change
Expand Up @@ -263,6 +263,23 @@ function getPriceConverted($price, $currency, $database, $userId)
}
}

$query = "SELECT * FROM total_yearly_cost WHERE user_id = :userId";
$stmt = $db->prepare($query);
$stmt->bindValue(':userId', $userId, SQLITE3_INTEGER);
$result = $stmt->execute();

$totalMonthlyCostDataPoints = [];
while ($row = $result->fetchArray(SQLITE3_ASSOC)) {
$totalMonthlyCostDataPoints[] = [
"label" => html_entity_decode($row['date']),
"y" => round($row['cost'] / 12, 2),
];
}

$showTotalMonthlyCostGraph = count($totalMonthlyCostDataPoints) > 1;
echo "ASD -> " . count($totalMonthlyCostDataPoints);
echo "SHOW: -> " . $showTotalMonthlyCostGraph;

?>
<section class="contain">
<?php
Expand Down Expand Up @@ -519,8 +536,8 @@ function getPriceConverted($price, $currency, $database, $userId)
}
}

$showpaymentMethodsGraph = count($paymentMethodDataPoints) > 1;
if ($showCategoryCostGraph || $showMemberCostGraph || $showpaymentMethodsGraph) {
$showPaymentMethodsGraph = count($paymentMethodDataPoints) > 1;
if ($showCategoryCostGraph || $showMemberCostGraph || $showPaymentMethodsGraph) {
?>
<h2><?= translate('split_views', $i18n) ?></h2>
<div class="graphs">
Expand Down Expand Up @@ -549,7 +566,7 @@ function getPriceConverted($price, $currency, $database, $userId)
<?php
}

if ($showpaymentMethodsGraph) {
if ($showPaymentMethodsGraph) {
?>
<section class="graph">
<header>
Expand All @@ -560,6 +577,18 @@ function getPriceConverted($price, $currency, $database, $userId)
<?php
}

if ($showTotalMonthlyCostGraph) {
?>
<section class="graph">
<header>
<?= translate('total_cost_trend', $i18n) ?>
<div class="sub-header">(<?= translate('monthly_cost', $i18n) ?>)</div>
</header>
<canvas id="totalMonthlyCostChart" style="height: 370px; width: 100%;"></canvas>
</section>
<?php
}

?>
</div>
<?php
Expand All @@ -568,14 +597,15 @@ function getPriceConverted($price, $currency, $database, $userId)

</section>
<?php
if ($showCategoryCostGraph || $showMemberCostGraph || $showpaymentMethodsGraph) {
if ($showCategoryCostGraph || $showMemberCostGraph || $showPaymentMethodsGraph || $showTotalMonthlyCostGraph) {
?>
<script src="scripts/libs/chart.js"></script>
<script type="text/javascript">
window.onload = function () {
loadGraph("categorySplitChart", <?php echo json_encode($categoryDataPoints, JSON_NUMERIC_CHECK); ?>, "<?= $code ?>", <?= $showCategoryCostGraph ?>);
loadGraph("memberSplitChart", <?php echo json_encode($memberDataPoints, JSON_NUMERIC_CHECK); ?>, "<?= $code ?>", <?= $showMemberCostGraph ?>);
loadGraph("paymentMethidSplitChart", <?php echo json_encode($paymentMethodDataPoints, JSON_NUMERIC_CHECK); ?>, "", <?= $showpaymentMethodsGraph ?>);
loadGraph("paymentMethidSplitChart", <?php echo json_encode($paymentMethodDataPoints, JSON_NUMERIC_CHECK); ?>, "", <?= $showPaymentMethodsGraph ?>);
loadLineGraph("totalMonthlyCostChart", <?php echo json_encode($totalMonthlyCostDataPoints, JSON_NUMERIC_CHECK); ?>, "<?= $code ?>", "<?= $showTotalMonthlyCostGraph ?>");
}
</script>
<?php
Expand Down

0 comments on commit e7185f9

Please sign in to comment.