feat!: allow registration of multiple users (#340)

feat: administration area
feat: add reset password functionality
This commit is contained in:
Miguel Ribeiro 2024-05-26 23:30:51 +02:00 committed by GitHub
parent 57b5c3deec
commit e1006e5823
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
90 changed files with 3132 additions and 868 deletions

View File

@ -81,6 +81,8 @@ See instructions to run Wallos below.
0 1 * * * php /var/www/html/endpoints/cronjobs/updatenextpayment.php >> /var/log/cron/updatenextpayment.log 2>&1 0 1 * * * php /var/www/html/endpoints/cronjobs/updatenextpayment.php >> /var/log/cron/updatenextpayment.log 2>&1
0 2 * * * php /var/www/html/endpoints/cronjobs/updateexchange.php >> /var/log/cron/updateexchange.log 2>&1 0 2 * * * php /var/www/html/endpoints/cronjobs/updateexchange.php >> /var/log/cron/updateexchange.log 2>&1
0 9 * * * php /var/www/html/endpoints/cronjobs/sendnotifications.php >> /var/log/cron/sendnotifications.log 2>&1 0 9 * * * php /var/www/html/endpoints/cronjobs/sendnotifications.php >> /var/log/cron/sendnotifications.log 2>&1
*/2 * * * * php /var/www/html/endpoints/cronjobs/sendverificationemails.php >> /var/log/cron/sendverificationemail.log 2>&1
*/2 * * * * php /var/www/html/endpoints/cronjobs/sendresetpasswordemails.php >> /var/log/cron/sendresetpasswordemails.log 2>&1
``` ```
5. If your web root is not `/var/www/html/` adjust the cronjobs above accordingly. 5. If your web root is not `/var/www/html/` adjust the cronjobs above accordingly.

175
admin.php
View File

@ -1,12 +1,183 @@
<?php <?php
require_once 'includes/header.php'; require_once 'includes/header.php';
$settings = []; if ($isAdmin != 1) {
$settings['registrations'] = false; header('Location: index.php');
exit;
}
// get admin settings from admin table
$stmt = $db->prepare('SELECT * FROM admin');
$result = $stmt->execute();
$settings = $result->fetchArray(SQLITE3_ASSOC);
// get user accounts where id is not 1
$stmt = $db->prepare('SELECT id, username, email FROM user ORDER BY id ASC');
$result = $stmt->execute();
$users = [];
while ($row = $result->fetchArray(SQLITE3_ASSOC)) {
$users[] = $row;
}
$userCount = is_array($users) ? count($users) : 0;
?> ?>
<section class="contain settings"> <section class="contain settings">
<section class="account-section">
<header>
<h2><?= translate('registrations', $i18n) ?></h2>
</header>
<div class="admin-form">
<div class="form-group-inline">
<input type="checkbox" id="registrations" <?= $settings['registrations_open'] ? 'checked' : '' ?> />
<label for="registrations"><?= translate('enable_user_registrations', $i18n) ?></label>
</div>
<div class="form-group">
<label for="maxUsers"><?= translate('maximum_number_users', $i18n) ?></label>
<input type="number" id="maxUsers" value="<?= $settings['max_users'] ?>" />
</div>
<div class="settings-notes">
<p>
<i class="fa-solid fa-circle-info"></i>
<?= translate('max_users_info', $i18n) ?>
</p>
</div>
<div class="form-group-inline">
<input type="checkbox" id="requireEmail" <?= $settings['require_email_verification'] ? 'checked' : '' ?> <?= empty($settings['smtp_address']) ? 'disabled' : '' ?>/>
<label for="requireEmail">
<?= translate('require_email_verification', $i18n) ?>
</label>
</div>
<?php
if (empty($settings['smtp_address'])) {
?>
<div class="settings-notes">
<p>
<i class="fa-solid fa-circle-info"></i>
<?= translate('configure_smtp_settings_to_enable', $i18n) ?>
</p>
</div>
<?php
}
?>
<div class="form-group">
<label for="serverUrl"><?= translate('server_url', $i18n) ?></label>
<input type="text" id="serverUrl" value="<?= $settings['server_url'] ?>" />
</div>
<div class="settings-notes">
<p>
<i class="fa-solid fa-circle-info"></i>
<?= translate('server_url_info', $i18n) ?>
</p>
<p>
<i class="fa-solid fa-circle-info"></i>
<?= translate('server_url_password_reset', $i18n) ?>
</p>
</div>
<div class="buttons">
<input type="submit" class="thin" value="<?= translate('save', $i18n) ?>" id="saveAccountRegistrations" onClick="saveAccountRegistrationsButton()"/>
</div>
</div>
</section>
<?php
if ($userCount >= 0) {
?>
<section class="account-section">
<header>
<h2><?= translate('user_management', $i18n) ?></h2>
</header>
<div class="user-list">
<?php
foreach ($users as $user) {
$userIcon = $user['id'] == 1 ? 'fa-user-tie' : 'fa-id-badge';
?>
<div class="form-group-inline" data-userid="<?= $user['id'] ?>">
<div class="user-list-row">
<div title="<?= translate('username', $i18n) ?>"><i class="fa-solid <?= $userIcon ?>"></i><?= $user['username'] ?></div>
<div title="<?= translate('email', $i18n) ?>"><i class="fa-solid fa-envelope"></i>
<a href="mailto:<?= $user['email']?>"><?= $user['email']?></a>
</div>
</div>
<div>
<?php
if ($user['id'] != 1) {
?>
<button class="image-button medium" onClick="removeUser(<?= $user['id'] ?>)">
<img src="images/siteicons/<?= $colorTheme ?>/delete.png" title="<?= translate('delete_user', $i18n) ?>">
</button>
<?php
} else {
?>
<button class="image-button medium disabled" disabled>
<img src="images/siteicons/<?= $colorTheme ?>/delete.png" title="<?= translate('delete_user', $i18n) ?>">
</button>
<?php
}
?>
</div>
</div>
<?php
}
?>
</div>
<div class="settings-notes">
<p>
<i class="fa-solid fa-circle-info"></i>
<?= translate('delete_user_info', $i18n) ?>
</p>
</div>
</section>
<?php
}
?>
<section class="account-section">
<header>
<h2><?= translate('smtp_settings', $i18n) ?></h2>
</header>
<div class="admin-form">
<div class="form-group-inline">
<input type="text" name="smtpaddress" id="smtpaddress" placeholder="<?= translate('smtp_address', $i18n) ?>" value="<?= $settings['smtp_address'] ?>" />
<input type="text" name="smtpport" id="smtpport" placeholder="<?= translate('port', $i18n) ?>" class="one-third" value="<?= $settings['smtp_port'] ?>" />
</div>
<div class="form-group-inline">
<input type="radio" name="encryption" id="encryptiontls" value="tls" <?= empty($settings['encryption']) || $settings['encryption'] == "tls" ? "checked" : "" ?> />
<label for="encryptiontls"><?= translate('tls', $i18n) ?></label>
<input type="radio" name="encryption" id="encryptionssl" value="ssl" <?= $settings['encryption'] == "ssl" ? "checked" : "" ?> />
<label for="encryptionssl"><?= translate('ssl', $i18n) ?></label>
</div>
<div class="form-group-inline">
<input type="text" name="smtpusername" id="smtpusername" placeholder="<?= translate('smtp_username', $i18n) ?>" value="<?= $settings['smtp_username'] ?>" />
</div>
<div class="form-group-inline">
<input type="password" name="smtppassword" id="smtppassword" placeholder="<?= translate('smtp_password', $i18n) ?>" value="<?= $settings['smtp_password'] ?>" />
</div>
<div class="form-group-inline">
<input type="text" name="fromemail" id="fromemail" placeholder="<?= translate('from_email', $i18n) ?>" value="<?= $settings['from_email'] ?>" />
</div>
<div class="settings-notes">
<p>
<i class="fa-solid fa-circle-info"></i> <?= translate('smtp_info', $i18n) ?>
</p>
<p>
<i class="fa-solid fa-circle-info"></i>
<?= translate('smtp_usage_info', $i18n) ?>
</p>
</div>
<div class="buttons">
<input type="button" class="secondary-button thin" value="<?= translate('test', $i18n) ?>" id="testSmtpSettingsButton" onClick="testSmtpSettingsButton()"/>
<input type="submit" class="thin" value="<?= translate('save', $i18n) ?>" id="saveSmtpSettingsButton" onClick="saveSmtpSettingsButton()"/>
</div>
</div>
</section>
<section class="account-section"> <section class="account-section">
<header> <header>
<h2><?= translate('backup_and_restore', $i18n) ?></h2> <h2><?= translate('backup_and_restore', $i18n) ?></h2>

View File

@ -2,3 +2,5 @@
0 1 * * * /usr/local/bin/php /var/www/html/endpoints/cronjobs/updatenextpayment.php >> /var/log/cron/updatenextpayment.log 2>&1 0 1 * * * /usr/local/bin/php /var/www/html/endpoints/cronjobs/updatenextpayment.php >> /var/log/cron/updatenextpayment.log 2>&1
0 2 * * * /usr/local/bin/php /var/www/html/endpoints/cronjobs/updateexchange.php >> /var/log/cron/updateexchange.log 2>&1 0 2 * * * /usr/local/bin/php /var/www/html/endpoints/cronjobs/updateexchange.php >> /var/log/cron/updateexchange.log 2>&1
0 9 * * * /usr/local/bin/php /var/www/html/endpoints/cronjobs/sendnotifications.php >> /var/log/cron/sendnotifications.log 2>&1 0 9 * * * /usr/local/bin/php /var/www/html/endpoints/cronjobs/sendnotifications.php >> /var/log/cron/sendnotifications.log 2>&1
*/2 * * * * /usr/local/bin/php /var/www/html/endpoints/cronjobs/sendverificationemails.php >> /var/log/cron/sendverificationemails.log 2>&1
*/2 * * * * /usr/local/bin/php /var/www/html/endpoints/cronjobs/sendresetpasswordemails.php >> /var/log/cron/sendresetpasswordemails.log 2>&1

View File

@ -0,0 +1,132 @@
<?php
require_once '../../includes/connect_endpoint.php';
if (!isset($_SESSION['loggedin']) || $_SESSION['loggedin'] !== true) {
die(json_encode([
"success" => false,
"message" => translate('session_expired', $i18n)
]));
}
// Check that user is an admin
if ($userId !== 1) {
die(json_encode([
"success" => false,
"message" => translate('error', $i18n)
]));
}
if ($_SERVER["REQUEST_METHOD"] === "POST") {
$postData = file_get_contents("php://input");
$data = json_decode($postData, true);
$userId = $data['userId'];
if ($userId == 1) {
die(json_encode([
"success" => false,
"message" => translate('error', $i18n)
]));
} else {
// Delete user
$stmt = $db->prepare('DELETE FROM user WHERE id = :id');
$stmt->bindValue(':id', $userId, SQLITE3_INTEGER);
$result = $stmt->execute();
// Delete subscriptions
$stmt = $db->prepare('DELETE FROM subscriptions WHERE user_id = :id');
$stmt->bindValue(':id', $userId, SQLITE3_INTEGER);
$result = $stmt->execute();
// Delete settings
$stmt = $db->prepare('DELETE FROM settings WHERE user_id = :id');
$stmt->bindValue(':id', $userId, SQLITE3_INTEGER);
$result = $stmt->execute();
// Delete fixer
$stmt = $db->prepare('DELETE FROM fixer WHERE user_id = :id');
$stmt->bindValue(':id', $userId, SQLITE3_INTEGER);
$result = $stmt->execute();
// Delete custom colors
$stmt = $db->prepare('DELETE FROM custom_colors WHERE user_id = :id');
$stmt->bindValue(':id', $userId, SQLITE3_INTEGER);
$result = $stmt->execute();
// Delete currencies
$stmt = $db->prepare('DELETE FROM currencies WHERE user_id = :id');
$stmt->bindValue(':id', $userId, SQLITE3_INTEGER);
$result = $stmt->execute();
// Delete categories
$stmt = $db->prepare('DELETE FROM categories WHERE user_id = :id');
$stmt->bindValue(':id', $userId, SQLITE3_INTEGER);
$result = $stmt->execute();
// Delete household
$stmt = $db->prepare('DELETE FROM household WHERE user_id = :id');
$stmt->bindValue(':id', $userId, SQLITE3_INTEGER);
$result = $stmt->execute();
// Delete payment methods
$stmt = $db->prepare('DELETE FROM payment_methods WHERE user_id = :id');
$stmt->bindValue(':id', $userId, SQLITE3_INTEGER);
$result = $stmt->execute();
// Delete email notifications
$stmt = $db->prepare('DELETE FROM email_notifications WHERE user_id = :id');
$stmt->bindValue(':id', $userId, SQLITE3_INTEGER);
$result = $stmt->execute();
// Delete telegram notifications
$stmt = $db->prepare('DELETE FROM telegram_notifications WHERE user_id = :id');
$stmt->bindValue(':id', $userId, SQLITE3_INTEGER);
$result = $stmt->execute();
// Delete webhook notifications
$stmt = $db->prepare('DELETE FROM webhook_notifications WHERE user_id = :id');
$stmt->bindValue(':id', $userId, SQLITE3_INTEGER);
$result = $stmt->execute();
// Delete gotify notifications
$stmt = $db->prepare('DELETE FROM gotify_notifications WHERE user_id = :id');
$stmt->bindValue(':id', $userId, SQLITE3_INTEGER);
$result = $stmt->execute();
// Delete pushover notifications
$stmt = $db->prepare('DELETE FROM pushover_notifications WHERE user_id = :id');
$stmt->bindValue(':id', $userId, SQLITE3_INTEGER);
$result = $stmt->execute();
// Dele notification settings
$stmt = $db->prepare('DELETE FROM notification_settings WHERE user_id = :id');
$stmt->bindValue(':id', $userId, SQLITE3_INTEGER);
$result = $stmt->execute();
// Delete last exchange update
$stmt = $db->prepare('DELETE FROM last_exchange_update WHERE user_id = :id');
$stmt->bindValue(':id', $userId, SQLITE3_INTEGER);
$result = $stmt->execute();
// Delete email verification
$stmt = $db->prepare('DELETE FROM email_verification WHERE user_id = :id');
$stmt->bindValue(':id', $userId, SQLITE3_INTEGER);
$result = $stmt->execute();
die(json_encode([
"success" => true,
"message" => translate('success', $i18n)
]));
}
} else {
die(json_encode([
"success" => false,
"message" => translate('error', $i18n)
]));
}
?>

View File

@ -0,0 +1,59 @@
<?php
require_once '../../includes/connect_endpoint.php';
if (!isset($_SESSION['loggedin']) || $_SESSION['loggedin'] !== true) {
die(json_encode([
"success" => false,
"message" => translate('session_expired', $i18n)
]));
}
// Check that user is an admin
if ($userId !== 1) {
die(json_encode([
"success" => false,
"message" => translate('error', $i18n)
]));
}
if ($_SERVER["REQUEST_METHOD"] === "POST") {
$postData = file_get_contents("php://input");
$data = json_decode($postData, true);
$openRegistrations = $data['open_registrations'];
$maxUsers = $data['max_users'];
$requireEmailVerification = $data['require_email_validation'];
$serverUrl = $data['server_url'];
if ($requireEmailVerification == 1 && $serverUrl == "") {
echo json_encode([
"success" => false,
"message" => translate('fill_all_fields', $i18n)
]);
die();
}
$sql = "UPDATE admin SET registrations_open = :openRegistrations, max_users = :maxUsers, require_email_verification = :requireEmailVerification, server_url = :serverUrl";
$stmt = $db->prepare($sql);
$stmt->bindParam(':openRegistrations', $openRegistrations, SQLITE3_INTEGER);
$stmt->bindParam(':maxUsers', $maxUsers, SQLITE3_INTEGER);
$stmt->bindParam(':requireEmailVerification', $requireEmailVerification, SQLITE3_INTEGER);
$stmt->bindParam(':serverUrl', $serverUrl, SQLITE3_TEXT);
$result = $stmt->execute();
if ($result) {
echo json_encode([
"success" => true,
"message" => translate('success', $i18n)
]);
} else {
echo json_encode([
"success" => false,
"message" => translate('error', $i18n)
]);
}
}
?>

View File

@ -0,0 +1,64 @@
<?php
require_once '../../includes/connect_endpoint.php';
if (!isset($_SESSION['loggedin']) || $_SESSION['loggedin'] !== true) {
die(json_encode([
"success" => false,
"message" => translate('session_expired', $i18n)
]));
}
// Check that user is an admin
if ($userId !== 1) {
die(json_encode([
"success" => false,
"message" => translate('error', $i18n)
]));
}
if ($_SERVER["REQUEST_METHOD"] === "POST") {
$postData = file_get_contents("php://input");
$data = json_decode($postData, true);
$smtpAddress = $data['smtpaddress'];
$smtpPort = $data['smtpport'];
$encryption = $data['encryption'];
$smtpUsername = $data['smtpusername'];
$smtpPassword = $data['smtppassword'];
$fromEmail = $data['fromemail'];
if (empty($smtpAddress) || empty($smtpPort)) {
die(json_encode([
"success" => false,
"message" => translate('fill_all_fields', $i18n)
]));
}
// Save settings
$stmt = $db->prepare('UPDATE admin SET smtp_address = :smtp_address, smtp_port = :smtp_port, encryption = :encryption, smtp_username = :smtp_username, smtp_password = :smtp_password, from_email = :from_email');
$stmt->bindValue(':smtp_address', $smtpAddress, SQLITE3_TEXT);
$stmt->bindValue(':smtp_port', $smtpPort, SQLITE3_TEXT);
$encryption = empty($data['encryption']) ? 'tls' : $data['encryption'];
$stmt->bindValue(':encryption', $encryption, SQLITE3_TEXT);
$stmt->bindValue(':smtp_username', $smtpUsername, SQLITE3_TEXT);
$stmt->bindValue(':smtp_password', $smtpPassword, SQLITE3_TEXT);
$stmt->bindValue(':from_email', $fromEmail, SQLITE3_TEXT);
$result = $stmt->execute();
if ($result) {
die(json_encode([
"success" => true,
"message" => translate('success', $i18n)
]));
} else {
die(json_encode([
"success" => false,
"message" => translate('error', $i18n)
]));
}
}
?>

View File

@ -2,11 +2,10 @@
require_once '../../includes/connect_endpoint.php'; require_once '../../includes/connect_endpoint.php';
require_once '../../includes/inputvalidation.php'; require_once '../../includes/inputvalidation.php';
session_start();
if (isset($_SESSION['loggedin']) && $_SESSION['loggedin'] === true) { if (isset($_SESSION['loggedin']) && $_SESSION['loggedin'] === true) {
if (isset($_GET['action']) && $_GET['action'] == "add") { if (isset($_GET['action']) && $_GET['action'] == "add") {
$stmt = $db->prepare('SELECT MAX("order") as maxOrder FROM categories'); $stmt = $db->prepare('SELECT MAX("order") as maxOrder FROM categories WHERE user_id = :userId');
$stmt->bindParam(':userId', $userId, SQLITE3_INTEGER);
$result = $stmt->execute(); $result = $stmt->execute();
$row = $result->fetchArray(SQLITE3_ASSOC); $row = $result->fetchArray(SQLITE3_ASSOC);
$maxOrder = $row['maxOrder']; $maxOrder = $row['maxOrder'];
@ -18,10 +17,11 @@ if (isset($_SESSION['loggedin']) && $_SESSION['loggedin'] === true) {
$order = $maxOrder + 1; $order = $maxOrder + 1;
$categoryName = "Category"; $categoryName = "Category";
$sqlInsert = 'INSERT INTO categories ("name", "order") VALUES (:name, :order)'; $sqlInsert = 'INSERT INTO categories ("name", "order", "user_id") VALUES (:name, :order, :userId)';
$stmtInsert = $db->prepare($sqlInsert); $stmtInsert = $db->prepare($sqlInsert);
$stmtInsert->bindParam(':name', $categoryName, SQLITE3_TEXT); $stmtInsert->bindParam(':name', $categoryName, SQLITE3_TEXT);
$stmtInsert->bindParam(':order', $order, SQLITE3_INTEGER); $stmtInsert->bindParam(':order', $order, SQLITE3_INTEGER);
$stmtInsert->bindParam(':userId', $userId, SQLITE3_INTEGER);
$resultInsert = $stmtInsert->execute(); $resultInsert = $stmtInsert->execute();
if ($resultInsert) { if ($resultInsert) {
@ -42,10 +42,11 @@ if (isset($_SESSION['loggedin']) && $_SESSION['loggedin'] === true) {
if (isset($_GET['categoryId']) && $_GET['categoryId'] != "" && isset($_GET['name']) && $_GET['name'] != "") { if (isset($_GET['categoryId']) && $_GET['categoryId'] != "" && isset($_GET['name']) && $_GET['name'] != "") {
$categoryId = $_GET['categoryId']; $categoryId = $_GET['categoryId'];
$name = validate($_GET['name']); $name = validate($_GET['name']);
$sql = "UPDATE categories SET name = :name WHERE id = :categoryId"; $sql = "UPDATE categories SET name = :name WHERE id = :categoryId AND user_id = :userId";
$stmt = $db->prepare($sql); $stmt = $db->prepare($sql);
$stmt->bindParam(':name', $name, SQLITE3_TEXT); $stmt->bindParam(':name', $name, SQLITE3_TEXT);
$stmt->bindParam(':categoryId', $categoryId, SQLITE3_INTEGER); $stmt->bindParam(':categoryId', $categoryId, SQLITE3_INTEGER);
$stmt->bindParam(':userId', $userId, SQLITE3_INTEGER);
$result = $stmt->execute(); $result = $stmt->execute();
if ($result) { if ($result) {
@ -71,9 +72,10 @@ if (isset($_SESSION['loggedin']) && $_SESSION['loggedin'] === true) {
} else if (isset($_GET['action']) && $_GET['action'] == "delete") { } else if (isset($_GET['action']) && $_GET['action'] == "delete") {
if (isset($_GET['categoryId']) && $_GET['categoryId'] != "" && $_GET['categoryId'] != 1) { if (isset($_GET['categoryId']) && $_GET['categoryId'] != "" && $_GET['categoryId'] != 1) {
$categoryId = $_GET['categoryId']; $categoryId = $_GET['categoryId'];
$checkCategory = "SELECT COUNT(*) FROM subscriptions WHERE category_id = :categoryId"; $checkCategory = "SELECT COUNT(*) FROM subscriptions WHERE category_id = :categoryId AND user_id = :userId";
$checkStmt = $db->prepare($checkCategory); $checkStmt = $db->prepare($checkCategory);
$checkStmt->bindParam(':categoryId', $categoryId, SQLITE3_INTEGER); $checkStmt->bindParam(':categoryId', $categoryId, SQLITE3_INTEGER);
$checkStmt->bindParam(':userId', $userId, SQLITE3_INTEGER);
$checkResult = $checkStmt->execute(); $checkResult = $checkStmt->execute();
$row = $checkResult->fetchArray(); $row = $checkResult->fetchArray();
$count = $row[0]; $count = $row[0];
@ -85,9 +87,10 @@ if (isset($_SESSION['loggedin']) && $_SESSION['loggedin'] === true) {
]; ];
echo json_encode($response); echo json_encode($response);
} else { } else {
$sql = "DELETE FROM categories WHERE id = :categoryId"; $sql = "DELETE FROM categories WHERE id = :categoryId AND user_id = :userId";
$stmt = $db->prepare($sql); $stmt = $db->prepare($sql);
$stmt->bindParam(':categoryId', $categoryId, SQLITE3_INTEGER); $stmt->bindParam(':categoryId', $categoryId, SQLITE3_INTEGER);
$stmt->bindParam(':userId', $userId, SQLITE3_INTEGER);
$result = $stmt->execute(); $result = $stmt->execute();
if ($result) { if ($result) {
$response = [ $response = [

View File

@ -2,17 +2,16 @@
require_once '../../includes/connect_endpoint.php'; require_once '../../includes/connect_endpoint.php';
session_start();
if (isset($_SESSION['loggedin']) && $_SESSION['loggedin'] === true) { if (isset($_SESSION['loggedin']) && $_SESSION['loggedin'] === true) {
$categories = $_POST['categoryIds']; $categories = $_POST['categoryIds'];
$order = 2; $order = 2;
foreach ($categories as $categoryId) { foreach ($categories as $categoryId) {
$sql = "UPDATE categories SET `order` = :order WHERE id = :categoryId"; $sql = "UPDATE categories SET `order` = :order WHERE id = :categoryId AND user_id = :userId";
$stmt = $db->prepare($sql); $stmt = $db->prepare($sql);
$stmt->bindParam(':order', $order, SQLITE3_INTEGER); $stmt->bindParam(':order', $order, SQLITE3_INTEGER);
$stmt->bindParam(':categoryId', $categoryId, SQLITE3_INTEGER); $stmt->bindParam(':categoryId', $categoryId, SQLITE3_INTEGER);
$stmt->bindParam(':userId', $userId, SQLITE3_INTEGER);
$result = $stmt->execute(); $result = $stmt->execute();
$order++; $order++;
} }

View File

@ -5,465 +5,501 @@
require_once __DIR__ . '/../../includes/connect_endpoint_crontabs.php'; require_once __DIR__ . '/../../includes/connect_endpoint_crontabs.php';
$days = 1; require __DIR__ . '/../../libs/PHPMailer/PHPMailer.php';
$emailNotificationsEnabled = false; require __DIR__ . '/../../libs/PHPMailer/SMTP.php';
$gotifyNotificationsEnabled = false; require __DIR__ . '/../../libs/PHPMailer/Exception.php';
$telegramNotificationsEnabled = false;
$webhookNotificationsEnabled = false;
$pushoverNotificationsEnabled = false;
$discordNotificationsEnabled = false;
// Get notification settings (how many days before the subscription ends should the notification be sent) // Get all user ids
$query = "SELECT days FROM notification_settings"; $query = "SELECT id, username FROM user";
$result = $db->query($query); $stmt = $db->prepare($query);
$usersToNotify = $stmt->execute();
if ($row = $result->fetchArray(SQLITE3_ASSOC)) { while ($userToNotify = $usersToNotify->fetchArray(SQLITE3_ASSOC)) {
$days = $row['days']; $userId = $userToNotify['id'];
} echo "For user: " . $userToNotify['username'] . "<br />";
$days = 1;
$emailNotificationsEnabled = false;
$gotifyNotificationsEnabled = false;
$telegramNotificationsEnabled = false;
$webhookNotificationsEnabled = false;
$pushoverNotificationsEnabled = false;
$discordNotificationsEnabled = false;
// Check if email notifications are enabled and get the settings // Get notification settings (how many days before the subscription ends should the notification be sent)
$query = "SELECT * FROM email_notifications"; $query = "SELECT days FROM notification_settings WHERE user_id = :userId";
$result = $db->query($query); $stmt = $db->prepare($query);
$stmt->bindValue(':userId', $userId, SQLITE3_INTEGER);
$result = $stmt->execute();
if ($row = $result->fetchArray(SQLITE3_ASSOC)) { if ($row = $result->fetchArray(SQLITE3_ASSOC)) {
$emailNotificationsEnabled = $row['enabled']; $days = $row['days'];
$email['smtpAddress'] = $row["smtp_address"];
$email['smtpPort'] = $row["smtp_port"];
$email['encryption'] = $row["encryption"];
$email['smtpUsername'] = $row["smtp_username"];
$email['smtpPassword'] = $row["smtp_password"];
$email['fromEmail'] = $row["from_email"] ? $row["from_email"] : "wallos@wallosapp.com";
}
// Check if Discord notifications are enabled and get the settings
$query = "SELECT * FROM discord_notifications";
$result = $db->query($query);
if ($row = $result->fetchArray(SQLITE3_ASSOC)) {
$discordNotificationsEnabled = $row['enabled'];
$discord['webhook_url'] = $row["webhook_url"];
$discord['bot_username'] = $row["bot_username"];
$discord['bot_avatar_url'] = $row["bot_avatar_url"];
}
// Check if Gotify notifications are enabled and get the settings
$query = "SELECT * FROM gotify_notifications";
$result = $db->query($query);
if ($row = $result->fetchArray(SQLITE3_ASSOC)) {
$gotifyNotificationsEnabled = $row['enabled'];
$gotify['serverUrl'] = $row["url"];
$gotify['appToken'] = $row["token"];
}
// Check if Telegram notifications are enabled and get the settings
$query = "SELECT * FROM telegram_notifications";
$result = $db->query($query);
if ($row = $result->fetchArray(SQLITE3_ASSOC)) {
$telegramNotificationsEnabled = $row['enabled'];
$telegram['botToken'] = $row["bot_token"];
$telegram['chatId'] = $row["chat_id"];
}
// Check if Pushover notifications are enabled and get the settings
$query = "SELECT * FROM pushover_notifications";
$result = $db->query($query);
if ($row = $result->fetchArray(SQLITE3_ASSOC)) {
$pushoverNotificationsEnabled = $row['enabled'];
$pushover['user_key'] = $row["user_key"];
$pushover['token'] = $row["token"];
}
// Check if Webhook notifications are enabled and get the settings
$query = "SELECT * FROM webhook_notifications";
$result = $db->query($query);
if ($row = $result->fetchArray(SQLITE3_ASSOC)) {
$webhookNotificationsEnabled = $row['enabled'];
$webhook['url'] = $row["url"];
$webhook['request_method'] = $row["request_method"];
$webhook['headers'] = $row["headers"];
$webhook['payload'] = $row["payload"];
$webhook['iterator'] = $row["iterator"];
if ($webhook['iterator'] === "") {
$webhook['iterator'] = "subscriptions";
}
}
$notificationsEnabled = $emailNotificationsEnabled || $gotifyNotificationsEnabled || $telegramNotificationsEnabled || $webhookNotificationsEnabled || $pushoverNotificationsEnabled || $discordNotificationsEnabled;
// If no notifications are enabled, no need to run
if (!$notificationsEnabled) {
echo "Notifications are disabled. No need to run.";
exit();
} else {
// Get all currencies
$currencies = array();
$query = "SELECT * FROM currencies";
$result = $db->query($query);
while ($row = $result->fetchArray(SQLITE3_ASSOC)) {
$currencies[$row['id']] = $row;
} }
// Get all household members
$stmt = $db->prepare('SELECT * FROM household');
$resultHousehold = $stmt->execute();
$household = []; // Check if email notifications are enabled and get the settings
while ($rowHousehold = $resultHousehold->fetchArray(SQLITE3_ASSOC)) { $query = "SELECT * FROM email_notifications WHERE user_id = :userId";
$household[$rowHousehold['id']] = $rowHousehold; $stmt = $db->prepare($query);
$stmt->bindValue(':userId', $userId, SQLITE3_INTEGER);
$result = $stmt->execute();
if ($row = $result->fetchArray(SQLITE3_ASSOC)) {
$emailNotificationsEnabled = $row['enabled'];
$email['smtpAddress'] = $row["smtp_address"];
$email['smtpPort'] = $row["smtp_port"];
$email['encryption'] = $row["encryption"];
$email['smtpUsername'] = $row["smtp_username"];
$email['smtpPassword'] = $row["smtp_password"];
$email['fromEmail'] = $row["from_email"] ? $row["from_email"] : "wallos@wallosapp.com";
} }
// Get all categories // Check if Discord notifications are enabled and get the settings
$stmt = $db->prepare('SELECT * FROM categories'); $query = "SELECT * FROM discord_notifications WHERE user_id = :userId";
$resultCategories = $stmt->execute(); $stmt = $db->prepare($query);
$stmt->bindValue(':userId', $userId, SQLITE3_INTEGER);
$result = $stmt->execute();
$categories = []; if ($row = $result->fetchArray(SQLITE3_ASSOC)) {
while ($rowCategory = $resultCategories->fetchArray(SQLITE3_ASSOC)) { $discordNotificationsEnabled = $row['enabled'];
$categories[$rowCategory['id']] = $rowCategory; $discord['webhook_url'] = $row["webhook_url"];
$discord['bot_username'] = $row["bot_username"];
$discord['bot_avatar_url'] = $row["bot_avatar_url"];
} }
$stmt = $db->prepare('SELECT * FROM subscriptions WHERE notify = :notify AND inactive = :inactive ORDER BY payer_user_id ASC'); // Check if Gotify notifications are enabled and get the settings
$stmt->bindValue(':notify', 1, SQLITE3_INTEGER); $query = "SELECT * FROM gotify_notifications WHERE user_id = :userId";
$stmt->bindValue(':inactive', 0, SQLITE3_INTEGER); $stmt = $db->prepare($query);
$resultSubscriptions = $stmt->execute(); $stmt->bindValue(':userId', $userId, SQLITE3_INTEGER);
$result = $stmt->execute();
$notify = []; $i = 0; if ($row = $result->fetchArray(SQLITE3_ASSOC)) {
$currentDate = new DateTime('now'); $gotifyNotificationsEnabled = $row['enabled'];
while ($rowSubscription = $resultSubscriptions->fetchArray(SQLITE3_ASSOC)) { $gotify['serverUrl'] = $row["url"];
if ($rowSubscription['notify_days_before'] !== 0) { $gotify['appToken'] = $row["token"];
$daysToCompare = $rowSubscription['notify_days_before']; }
} else {
$daysToCompare = $days; // Check if Telegram notifications are enabled and get the settings
} $query = "SELECT * FROM telegram_notifications WHERE user_id = :userId";
$nextPaymentDate = new DateTime($rowSubscription['next_payment']); $stmt = $db->prepare($query);
$difference = $currentDate->diff($nextPaymentDate)->days + 1; $stmt->bindValue(':userId', $userId, SQLITE3_INTEGER);
if ($difference === $daysToCompare) { $result = $stmt->execute();
$notify[$rowSubscription['payer_user_id']][$i]['name'] = $rowSubscription['name'];
$notify[$rowSubscription['payer_user_id']][$i]['price'] = $rowSubscription['price'] . $currencies[$rowSubscription['currency_id']]['symbol']; if ($row = $result->fetchArray(SQLITE3_ASSOC)) {
$notify[$rowSubscription['payer_user_id']][$i]['currency'] = $currencies[$rowSubscription['currency_id']]['name']; $telegramNotificationsEnabled = $row['enabled'];
$notify[$rowSubscription['payer_user_id']][$i]['category'] = $categories[$rowSubscription['category_id']]['name']; $telegram['botToken'] = $row["bot_token"];
$notify[$rowSubscription['payer_user_id']][$i]['payer'] = $household[$rowSubscription['payer_user_id']]['name']; $telegram['chatId'] = $row["chat_id"];
$notify[$rowSubscription['payer_user_id']][$i]['date'] = $rowSubscription['next_payment']; }
$notify[$rowSubscription['payer_user_id']][$i]['days'] = $daysToCompare;
$i++; // Check if Pushover notifications are enabled and get the settings
$query = "SELECT * FROM pushover_notifications WHERE user_id = :userId";
$stmt = $db->prepare($query);
$stmt->bindValue(':userId', $userId, SQLITE3_INTEGER);
$result = $stmt->execute();
if ($row = $result->fetchArray(SQLITE3_ASSOC)) {
$pushoverNotificationsEnabled = $row['enabled'];
$pushover['user_key'] = $row["user_key"];
$pushover['token'] = $row["token"];
}
// Check if Webhook notifications are enabled and get the settings
$query = "SELECT * FROM webhook_notifications WHERE user_id = :userId";
$stmt = $db->prepare($query);
$stmt->bindValue(':userId', $userId, SQLITE3_INTEGER);
$result = $stmt->execute();
if ($row = $result->fetchArray(SQLITE3_ASSOC)) {
$webhookNotificationsEnabled = $row['enabled'];
$webhook['url'] = $row["url"];
$webhook['request_method'] = $row["request_method"];
$webhook['headers'] = $row["headers"];
$webhook['payload'] = $row["payload"];
$webhook['iterator'] = $row["iterator"];
if ($webhook['iterator'] === "") {
$webhook['iterator'] = "subscriptions";
} }
} }
if (!empty($notify)) { $notificationsEnabled = $emailNotificationsEnabled || $gotifyNotificationsEnabled || $telegramNotificationsEnabled || $webhookNotificationsEnabled || $pushoverNotificationsEnabled || $discordNotificationsEnabled;
// Email notifications if enabled // If no notifications are enabled, no need to run
if ($emailNotificationsEnabled) { if (!$notificationsEnabled) {
require __DIR__ . '/../../libs/PHPMailer/PHPMailer.php'; echo "Notifications are disabled. No need to run.<br />";
require __DIR__ . '/../../libs/PHPMailer/SMTP.php'; continue;
require __DIR__ . '/../../libs/PHPMailer/Exception.php'; } else {
// Get all currencies
$currencies = array();
$query = "SELECT * FROM currencies WHERE user_id = :userId";
$stmt = $db->prepare($query);
$stmt->bindValue(':userId', $userId, SQLITE3_INTEGER);
$result = $stmt->execute();
$stmt = $db->prepare('SELECT * FROM user WHERE id = :id'); while ($row = $result->fetchArray(SQLITE3_ASSOC)) {
$stmt->bindValue(':id', 1, SQLITE3_INTEGER); $currencies[$row['id']] = $row;
$result = $stmt->execute(); }
$defaultUser = $result->fetchArray(SQLITE3_ASSOC);
$defaultEmail = $defaultUser['email'];
$defaultName = $defaultUser['username'];
foreach ($notify as $userId => $perUser) { // Get all household members
$message = "The following subscriptions are up for renewal:\n"; $query = "SELECT * FROM household WHERE user_id = :userId";
$stmt = $db->prepare($query);
$stmt->bindValue(':userId', $userId, SQLITE3_INTEGER);
$resultHousehold = $stmt->execute();
foreach ($perUser as $subscription) { $household = [];
$dayText = $subscription['days'] == 1 ? "Tomorrow" : "In " . $subscription['days'] . " days"; while ($rowHousehold = $resultHousehold->fetchArray(SQLITE3_ASSOC)) {
$message .= $subscription['name'] . " for " . $subscription['price'] . " (" . $dayText . ")\n"; $household[$rowHousehold['id']] = $rowHousehold;
} }
$mail = new PHPMailer(true);
$mail->CharSet="UTF-8";
$mail->isSMTP();
$mail->Host = $email['smtpAddress'];
$mail->SMTPAuth = true;
$mail->Username = $email['smtpUsername'];
$mail->Password = $email['smtpPassword'];
$mail->SMTPSecure = $email['encryption'];
$mail->Port = $email['smtpPort'];
$stmt = $db->prepare('SELECT * FROM household WHERE id = :userId');
$stmt->bindValue(':userId', $userId, SQLITE3_INTEGER);
$result = $stmt->execute();
$user = $result->fetchArray(SQLITE3_ASSOC);
$emailaddress = !empty($user['email']) ? $user['email'] : $defaultEmail; // Get all categories
$name = !empty($user['name']) ? $user['name'] : $defaultName; $query = "SELECT * FROM categories WHERE user_id = :userId";
$stmt = $db->prepare($query);
$mail->setFrom($email['fromEmail'], 'Wallos App'); $stmt->bindValue(':userId', $userId, SQLITE3_INTEGER);
$mail->addAddress($emailaddress, $name); $resultCategories = $stmt->execute();
$mail->Subject = 'Wallos Notification'; $categories = [];
$mail->Body = $message; while ($rowCategory = $resultCategories->fetchArray(SQLITE3_ASSOC)) {
$categories[$rowCategory['id']] = $rowCategory;
if ($mail->send()) { }
echo "Email Notifications sent<br />";
} else { $query = "SELECT * FROM subscriptions WHERE user_id = :user_id AND notify = :notify AND inactive = :inactive ORDER BY payer_user_id ASC";
echo "Error sending notifications: " . $mail->ErrorInfo; $stmt = $db->prepare($query);
} $stmt->bindValue(':user_id', $userId, SQLITE3_INTEGER);
$stmt->bindValue(':notify', 1, SQLITE3_INTEGER);
$stmt->bindValue(':inactive', 0, SQLITE3_INTEGER);
$resultSubscriptions = $stmt->execute();
$notify = []; $i = 0;
$currentDate = new DateTime('now');
while ($rowSubscription = $resultSubscriptions->fetchArray(SQLITE3_ASSOC)) {
if ($rowSubscription['notify_days_before'] !== 0) {
$daysToCompare = $rowSubscription['notify_days_before'];
} else {
$daysToCompare = $days;
}
$nextPaymentDate = new DateTime($rowSubscription['next_payment']);
$difference = $currentDate->diff($nextPaymentDate)->days + 1;
if ($difference === $daysToCompare) {
$notify[$rowSubscription['payer_user_id']][$i]['name'] = $rowSubscription['name'];
$notify[$rowSubscription['payer_user_id']][$i]['price'] = $rowSubscription['price'] . $currencies[$rowSubscription['currency_id']]['symbol'];
$notify[$rowSubscription['payer_user_id']][$i]['currency'] = $currencies[$rowSubscription['currency_id']]['name'];
$notify[$rowSubscription['payer_user_id']][$i]['category'] = $categories[$rowSubscription['category_id']]['name'];
$notify[$rowSubscription['payer_user_id']][$i]['payer'] = $household[$rowSubscription['payer_user_id']]['name'];
$notify[$rowSubscription['payer_user_id']][$i]['date'] = $rowSubscription['next_payment'];
$notify[$rowSubscription['payer_user_id']][$i]['days'] = $daysToCompare;
$i++;
} }
} }
// Discord notifications if enabled if (!empty($notify)) {
if ($discordNotificationsEnabled) {
foreach ($notify as $userId => $perUser) { // Email notifications if enabled
// Get name of user from household table if ($emailNotificationsEnabled) {
$stmt = $db->prepare('SELECT * FROM household WHERE id = :userId');
$stmt->bindValue(':userId', $userId, SQLITE3_INTEGER); $stmt = $db->prepare('SELECT * FROM user WHERE id = :user_id');
$stmt->bindValue(':user_id', $userId, SQLITE3_INTEGER);
$result = $stmt->execute(); $result = $stmt->execute();
$user = $result->fetchArray(SQLITE3_ASSOC); $defaultUser = $result->fetchArray(SQLITE3_ASSOC);
$defaultEmail = $defaultUser['email'];
$defaultName = $defaultUser['username'];
$title = translate('wallos_notification', $i18n); foreach ($notify as $userId => $perUser) {
if ($user['name']) {
$message = $user['name'] . ", the following subscriptions are up for renewal:\n";
} else {
$message = "The following subscriptions are up for renewal:\n"; $message = "The following subscriptions are up for renewal:\n";
foreach ($perUser as $subscription) {
$dayText = $subscription['days'] == 1 ? "Tomorrow" : "In " . $subscription['days'] . " days";
$message .= $subscription['name'] . " for " . $subscription['price'] . " (" . $dayText . ")\n";
}
$mail = new PHPMailer(true);
$mail->CharSet="UTF-8";
$mail->isSMTP();
$mail->Host = $email['smtpAddress'];
$mail->SMTPAuth = true;
$mail->Username = $email['smtpUsername'];
$mail->Password = $email['smtpPassword'];
$mail->SMTPSecure = $email['encryption'];
$mail->Port = $email['smtpPort'];
$stmt = $db->prepare('SELECT * FROM household WHERE id = :userId');
$stmt->bindValue(':userId', $userId, SQLITE3_INTEGER);
$result = $stmt->execute();
$user = $result->fetchArray(SQLITE3_ASSOC);
$emailaddress = !empty($user['email']) ? $user['email'] : $defaultEmail;
$name = !empty($user['name']) ? $user['name'] : $defaultName;
$mail->setFrom($email['fromEmail'], 'Wallos App');
$mail->addAddress($emailaddress, $name);
$mail->Subject = 'Wallos Notification';
$mail->Body = $message;
if ($mail->send()) {
echo "Email Notifications sent<br />";
} else {
echo "Error sending notifications: " . $mail->ErrorInfo . "<br />";
}
}
}
// Discord notifications if enabled
if ($discordNotificationsEnabled) {
foreach ($notify as $userId => $perUser) {
// Get name of user from household table
$stmt = $db->prepare('SELECT * FROM household WHERE id = :userId');
$stmt->bindValue(':userId', $userId, SQLITE3_INTEGER);
$result = $stmt->execute();
$user = $result->fetchArray(SQLITE3_ASSOC);
$title = translate('wallos_notification', $i18n);
if ($user['name']) {
$message = $user['name'] . ", the following subscriptions are up for renewal:\n";
} else {
$message = "The following subscriptions are up for renewal:\n";
}
foreach ($perUser as $subscription) {
$dayText = $subscription['days'] == 1 ? "Tomorrow" : "In " . $subscription['days'] . " days";
$message .= $subscription['name'] . " for " . $subscription['price'] . " (" . $dayText . ")\n";
}
$postfields = [
'content' => $message
];
if (!empty($discord['bot_username'])) {
$postfields['username'] = $discord['bot_username'];
}
if (!empty($discord['bot_avatar_url'])) {
$postfields['avatar_url'] = $discord['bot_avatar_url'];
}
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $discord['webhook_url']);
curl_setopt($ch, CURLOPT_POST, 1);
curl_setopt($ch, CURLOPT_POSTFIELDS, json_encode($postfields));
curl_setopt($ch, CURLOPT_HTTPHEADER, [
'Content-Type: application/json'
]);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
$response = curl_exec($ch);
curl_close($ch);
if ($result === false) {
echo "Error sending notifications: " . curl_error($ch) . "<br />";
} else {
echo "Discord Notifications sent<br />";
}
}
}
// Gotify notifications if enabled
if ($gotifyNotificationsEnabled) {
foreach ($notify as $userId => $perUser) {
// Get name of user from household table
$stmt = $db->prepare('SELECT * FROM household WHERE id = :userId');
$stmt->bindValue(':userId', $userId, SQLITE3_INTEGER);
$result = $stmt->execute();
$user = $result->fetchArray(SQLITE3_ASSOC);
if ($user['name']) {
$message = $user['name'] . ", the following subscriptions are up for renewal:\n";
} else {
$message = "The following subscriptions are up for renewal:\n";
}
foreach ($perUser as $subscription) {
$dayText = $subscription['days'] == 1 ? "Tomorrow" : "In " . $subscription['days'] . " days";
$message .= $subscription['name'] . " for " . $subscription['price'] . " (" . $dayText . ")\n";
}
$data = array(
'message' => $message,
'priority' => 5
);
$data_string = json_encode($data);
$ch = curl_init($gotify['serverUrl'] . '/message?token=' . $gotify['appToken']);
curl_setopt($ch, CURLOPT_CUSTOMREQUEST, "POST");
curl_setopt($ch, CURLOPT_POSTFIELDS, $data_string);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_HTTPHEADER, array(
'Content-Type: application/json',
'Content-Length: ' . strlen($data_string))
);
$result = curl_exec($ch);
if ($result === false) {
echo "Error sending notifications: " . curl_error($ch) . "<br />";
} else {
echo "Gotify Notifications sent<br />";
}
}
}
// Telegram notifications if enabled
if ($telegramNotificationsEnabled) {
foreach ($notify as $userId => $perUser) {
// Get name of user from household table
$stmt = $db->prepare('SELECT * FROM household WHERE id = :userId');
$stmt->bindValue(':userId', $userId, SQLITE3_INTEGER);
$result = $stmt->execute();
$user = $result->fetchArray(SQLITE3_ASSOC);
if ($user['name']) {
$message = $user['name'] . ", the following subscriptions are up for renewal:\n";
} else {
$message = "The following subscriptions are up for renewal:\n";
}
foreach ($perUser as $subscription) {
$dayText = $subscription['days'] == 1 ? "Tomorrow" : "In " . $subscription['days'] . " days";
$message .= $subscription['name'] . " for " . $subscription['price'] . " (" . $dayText . ")\n";
}
$data = array(
'chat_id' => $telegram['chatId'],
'text' => $message
);
$data_string = json_encode($data);
$ch = curl_init('https://api.telegram.org/bot' . $telegram['botToken'] . '/sendMessage');
curl_setopt($ch, CURLOPT_CUSTOMREQUEST, "POST");
curl_setopt($ch, CURLOPT_POSTFIELDS, $data_string);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_HTTPHEADER, array(
'Content-Type: application/json',
'Content-Length: ' . strlen($data_string))
);
$result = curl_exec($ch);
if ($result === false) {
echo "Error sending notifications: " . curl_error($ch) . "<br />";
} else {
echo "Telegram Notifications sent<br />";
}
}
}
// Pushover notifications if enabled
if ($pushoverNotificationsEnabled) {
foreach ($notify as $userId => $perUser) {
// Get name of user from household table
$stmt = $db->prepare('SELECT * FROM household WHERE id = :userId');
$stmt->bindValue(':userId', $userId, SQLITE3_INTEGER);
$result = $stmt->execute();
$user = $result->fetchArray(SQLITE3_ASSOC);
if ($user['name']) {
$message = $user['name'] . ", the following subscriptions are up for renewal:\n";
} else {
$message = "The following subscriptions are up for renewal:\n";
}
foreach ($perUser as $subscription) {
$dayText = $subscription['days'] == 1 ? "Tomorrow" : "In " . $subscription['days'] . " days";
$message .= $subscription['name'] . " for " . $subscription['price'] . " (" . $dayText . ")\n";
}
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, "https://api.pushover.net/1/messages.json");
curl_setopt($ch, CURLOPT_POST, 1);
curl_setopt($ch, CURLOPT_POSTFIELDS, http_build_query([
'token' => $pushover['token'],
'user' => $pushover['user_key'],
'message' => $message,
]));
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
$result = curl_exec($ch);
curl_close($ch);
if ($result === false) {
echo "Error sending notifications: " . curl_error($ch) . "<br />";
} else {
echo "Pushover Notifications sent<br />";
}
}
}
// Webhook notifications if enabled
if ($webhookNotificationsEnabled) {
// Get webhook payload and turn it into a json object
$payload = str_replace("{{days_until}}", $days, $webhook['payload']); // The default value for all subscriptions
$payload_json = json_decode($payload, true);
$subscription_template = $payload_json["{{subscriptions}}"];
$subscriptions = [];
foreach ($notify as $userId => $perUser) {
// Get name of user from household table
$stmt = $db->prepare('SELECT * FROM household WHERE id = :userId');
$stmt->bindValue(':userId', $userId, SQLITE3_INTEGER);
$result = $stmt->execute();
$user = $result->fetchArray(SQLITE3_ASSOC);
if ($user['name']) {
$payer = $user['name'];
}
foreach ($perUser as $k => $subscription) {
$temp_subscription = $subscription_template[0];
foreach ($temp_subscription as $key => $value) {
if (is_string($value)) {
$temp_subscription[$key] = str_replace("{{subscription_name}}", $subscription['name'], $value);
$temp_subscription[$key] = str_replace("{{subscription_price}}", $subscription['price'], $temp_subscription[$key]);
$temp_subscription[$key] = str_replace("{{subscription_currency}}", $subscription['currency'], $temp_subscription[$key]);
$temp_subscription[$key] = str_replace("{{subscription_category}}", $subscription['category'], $temp_subscription[$key]);
$temp_subscription[$key] = str_replace("{{subscription_payer}}", $subscription['payer'], $temp_subscription[$key]);
$temp_subscription[$key] = str_replace("{{subscription_date}}", $subscription['date'], $temp_subscription[$key]);
$temp_subscription[$key] = str_replace("{{subscription_days_until_payment}}", $subscription['days'], $temp_subscription[$key]); // The de facto value for this subscription
}
}
$subscriptions[] = $temp_subscription;
}
} }
foreach ($perUser as $subscription) { $payload_json["{{subscriptions}}"] = $subscriptions;
$dayText = $subscription['days'] == 1 ? "Tomorrow" : "In " . $subscription['days'] . " days"; $payload_json[$webhook['iterator']] = $subscriptions;
$message .= $subscription['name'] . " for " . $subscription['price'] . " (" . $dayText . ")\n"; unset($payload_json["{{subscriptions}}"]);
}
$postfields = [
'content' => $message
];
if (!empty($discord['bot_username'])) {
$postfields['username'] = $discord['bot_username'];
}
if (!empty($discord['bot_avatar_url'])) {
$postfields['avatar_url'] = $discord['bot_avatar_url'];
}
$ch = curl_init(); $ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $webhook['url']);
curl_setopt($ch, CURLOPT_URL, $discord['webhook_url']); curl_setopt($ch, CURLOPT_CUSTOMREQUEST, $webhook['request_method']);
curl_setopt($ch, CURLOPT_POST, 1); curl_setopt($ch, CURLOPT_POSTFIELDS, json_encode($payload_json));
curl_setopt($ch, CURLOPT_POSTFIELDS, json_encode($postfields)); if (!empty($customheaders)) {
curl_setopt($ch, CURLOPT_HTTPHEADER, [ curl_setopt($ch, CURLOPT_HTTPHEADER, $webhook['headers']);
'Content-Type: application/json' }
]);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true); curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
$response = curl_exec($ch); $response = curl_exec($ch);
curl_close($ch); curl_close($ch);
if ($result === false) { if ($response === false) {
echo "Error sending notifications: " . curl_error($ch); echo "Error sending notifications: " . curl_error($ch) . "<br />";
} else { } else {
echo "Discord Notifications sent<br />"; echo "Webhook Notifications sent<br />";
} }
} }
}
// Gotify notifications if enabled
if ($gotifyNotificationsEnabled) {
foreach ($notify as $userId => $perUser) {
// Get name of user from household table
$stmt = $db->prepare('SELECT * FROM household WHERE id = :userId');
$stmt->bindValue(':userId', $userId, SQLITE3_INTEGER);
$result = $stmt->execute();
$user = $result->fetchArray(SQLITE3_ASSOC);
if ($user['name']) {
$message = $user['name'] . ", the following subscriptions are up for renewal:\n";
} else {
$message = "The following subscriptions are up for renewal:\n";
}
foreach ($perUser as $subscription) {
$dayText = $subscription['days'] == 1 ? "Tomorrow" : "In " . $subscription['days'] . " days";
$message .= $subscription['name'] . " for " . $subscription['price'] . " (" . $dayText . ")\n";
}
$data = array(
'message' => $message,
'priority' => 5
);
$data_string = json_encode($data);
$ch = curl_init($gotify['serverUrl'] . '/message?token=' . $gotify['appToken']);
curl_setopt($ch, CURLOPT_CUSTOMREQUEST, "POST");
curl_setopt($ch, CURLOPT_POSTFIELDS, $data_string);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_HTTPHEADER, array(
'Content-Type: application/json',
'Content-Length: ' . strlen($data_string))
);
$result = curl_exec($ch);
if ($result === false) {
echo "Error sending notifications: " . curl_error($ch);
} else {
echo "Gotify Notifications sent<br />";
}
}
}
// Telegram notifications if enabled
if ($telegramNotificationsEnabled) {
foreach ($notify as $userId => $perUser) {
// Get name of user from household table
$stmt = $db->prepare('SELECT * FROM household WHERE id = :userId');
$stmt->bindValue(':userId', $userId, SQLITE3_INTEGER);
$result = $stmt->execute();
$user = $result->fetchArray(SQLITE3_ASSOC);
if ($user['name']) {
$message = $user['name'] . ", the following subscriptions are up for renewal:\n";
} else {
$message = "The following subscriptions are up for renewal:\n";
}
foreach ($perUser as $subscription) {
$dayText = $subscription['days'] == 1 ? "Tomorrow" : "In " . $subscription['days'] . " days";
$message .= $subscription['name'] . " for " . $subscription['price'] . " (" . $dayText . ")\n";
}
$data = array(
'chat_id' => $telegram['chatId'],
'text' => $message
);
$data_string = json_encode($data);
$ch = curl_init('https://api.telegram.org/bot' . $telegram['botToken'] . '/sendMessage');
curl_setopt($ch, CURLOPT_CUSTOMREQUEST, "POST");
curl_setopt($ch, CURLOPT_POSTFIELDS, $data_string);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_HTTPHEADER, array(
'Content-Type: application/json',
'Content-Length: ' . strlen($data_string))
);
$result = curl_exec($ch);
if ($result === false) {
echo "Error sending notifications: " . curl_error($ch);
} else {
echo "Telegram Notifications sent<br />";
}
}
}
// Pushover notifications if enabled
if ($pushoverNotificationsEnabled) {
foreach ($notify as $userId => $perUser) {
// Get name of user from household table
$stmt = $db->prepare('SELECT * FROM household WHERE id = :userId');
$stmt->bindValue(':userId', $userId, SQLITE3_INTEGER);
$result = $stmt->execute();
$user = $result->fetchArray(SQLITE3_ASSOC);
if ($user['name']) {
$message = $user['name'] . ", the following subscriptions are up for renewal:\n";
} else {
$message = "The following subscriptions are up for renewal:\n";
}
foreach ($perUser as $subscription) {
$dayText = $subscription['days'] == 1 ? "Tomorrow" : "In " . $subscription['days'] . " days";
$message .= $subscription['name'] . " for " . $subscription['price'] . " (" . $dayText . ")\n";
}
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, "https://api.pushover.net/1/messages.json");
curl_setopt($ch, CURLOPT_POST, 1);
curl_setopt($ch, CURLOPT_POSTFIELDS, http_build_query([
'token' => $pushover['token'],
'user' => $pushover['user_key'],
'message' => $message,
]));
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
$result = curl_exec($ch);
curl_close($ch);
if ($result === false) {
echo "Error sending notifications: " . curl_error($ch);
} else {
echo "Pushover Notifications sent<br />";
}
}
}
// Webhook notifications if enabled
if ($webhookNotificationsEnabled) {
// Get webhook payload and turn it into a json object
$payload = str_replace("{{days_until}}", $days, $webhook['payload']); // The default value for all subscriptions
$payload_json = json_decode($payload, true);
$subscription_template = $payload_json["{{subscriptions}}"];
$subscriptions = [];
foreach ($notify as $userId => $perUser) {
// Get name of user from household table
$stmt = $db->prepare('SELECT * FROM household WHERE id = :userId');
$stmt->bindValue(':userId', $userId, SQLITE3_INTEGER);
$result = $stmt->execute();
$user = $result->fetchArray(SQLITE3_ASSOC);
if ($user['name']) {
$payer = $user['name'];
}
foreach ($perUser as $k => $subscription) {
$temp_subscription = $subscription_template[0];
foreach ($temp_subscription as $key => $value) {
if (is_string($value)) {
$temp_subscription[$key] = str_replace("{{subscription_name}}", $subscription['name'], $value);
$temp_subscription[$key] = str_replace("{{subscription_price}}", $subscription['price'], $temp_subscription[$key]);
$temp_subscription[$key] = str_replace("{{subscription_currency}}", $subscription['currency'], $temp_subscription[$key]);
$temp_subscription[$key] = str_replace("{{subscription_category}}", $subscription['category'], $temp_subscription[$key]);
$temp_subscription[$key] = str_replace("{{subscription_payer}}", $subscription['payer'], $temp_subscription[$key]);
$temp_subscription[$key] = str_replace("{{subscription_date}}", $subscription['date'], $temp_subscription[$key]);
$temp_subscription[$key] = str_replace("{{subscription_days_until_payment}}", $subscription['days'], $temp_subscription[$key]); // The de facto value for this subscription
}
}
$subscriptions[] = $temp_subscription;
}
}
$payload_json["{{subscriptions}}"] = $subscriptions;
$payload_json[$webhook['iterator']] = $subscriptions;
unset($payload_json["{{subscriptions}}"]);
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $webhook['url']);
curl_setopt($ch, CURLOPT_CUSTOMREQUEST, $webhook['request_method']);
curl_setopt($ch, CURLOPT_POSTFIELDS, json_encode($payload_json));
if (!empty($customheaders)) {
curl_setopt($ch, CURLOPT_HTTPHEADER, $webhook['headers']);
}
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
$response = curl_exec($ch);
curl_close($ch);
if ($response === false) {
echo "Error sending notifications: " . curl_error($ch);
} else {
echo "Webhook Notifications sent<br />";
}
}
} else {
} else { echo "Nothing to notify.<br />";
echo "Nothing to notify."; }
} }
} }
?> ?>

View File

@ -0,0 +1,82 @@
<?php
use PHPMailer\PHPMailer\PHPMailer;
use PHPMailer\PHPMailer\SMTP;
use PHPMailer\PHPMailer\Exception;
require_once __DIR__ . '/../../includes/connect_endpoint_crontabs.php';
$query = "SELECT * FROM admin";
$stmt = $db->prepare($query);
$result = $stmt->execute();
$admin = $result->fetchArray(SQLITE3_ASSOC);
$query = "SELECT * FROM password_resets WHERE email_sent = 0";
$stmt = $db->prepare($query);
$result = $stmt->execute();
$rows = [];
while ($row = $result->fetchArray(SQLITE3_ASSOC)) {
$rows[] = $row;
}
if ($rows) {
if ($admin['smtp_address'] && $admin['smtp_port'] && $admin['smtp_username'] && $admin['smtp_password'] && $admin['encryption']) {
// There are SMTP settings
$smtpAddress = $admin['smtp_address'];
$smtpPort = $admin['smtp_port'];
$smtpUsername = $admin['smtp_username'];
$smtpPassword = $admin['smtp_password'];
$fromEmail = empty($admin['from_email']) ? 'wallos@wallosapp.com' : $admin['from_email'];
$encryption = $admin['encryption'];
$server_url = $admin['server_url'];
require __DIR__ . '/../../libs/PHPMailer/PHPMailer.php';
require __DIR__ . '/../../libs/PHPMailer/SMTP.php';
require __DIR__ . '/../../libs/PHPMailer/Exception.php';
$mail = new PHPMailer(true);
$mail->isSMTP();
$mail->Host = $smtpAddress;
$mail->SMTPAuth = true;
$mail->Username = $smtpUsername;
$mail->Password = $smtpPassword;
$mail->SMTPSecure = $encryption;
$mail->Port = $smtpPort;
$mail->setFrom($fromEmail);
try {
foreach ($rows as $user) {
$mail->addAddress($user['email']);
$mail->isHTML(true);
$mail->Subject = 'Wallos - Reset Password';
$mail->Body = '<img src="' . $server_url . '/images/siteicons/blue/wallos.png" alt="Logo" />
<br>
A password reset was requested for your account.
<br>
Please click the following link to reset your password: <a href="' . $server_url . '/passwordreset.php?email=' . $user['email'] . '&token=' . $user['token'] . '">Reset Password</a>';
$mail->send();
$query = "UPDATE password_resets SET email_sent = 1 WHERE id = :id";
$stmt = $db->prepare($query);
$stmt->bindParam(':id', $user['id'], SQLITE3_INTEGER);
$stmt->execute();
$mail->clearAddresses();
echo "Password reset email sent to " . $user['email'] . "<br>";
}
} catch (Exception $e) {
echo "Message could not be sent. Mailer Error: {$mail->ErrorInfo} <br>";
}
} else {
// There are no SMTP settings
exit();
}
} else {
// There are no password reset emails to be sent
exit();
}
?>

View File

@ -0,0 +1,85 @@
<?php
use PHPMailer\PHPMailer\PHPMailer;
use PHPMailer\PHPMailer\SMTP;
use PHPMailer\PHPMailer\Exception;
require_once __DIR__ . '/../../includes/connect_endpoint_crontabs.php';
$query = "SELECT * FROM admin";
$stmt = $db->prepare($query);
$result = $stmt->execute();
$admin = $result->fetchArray(SQLITE3_ASSOC);
if ($admin['require_email_verification'] == 0) {
die("Email verification is not required.");
}
$query = "SELECT * FROM email_verification WHERE email_sent = 0";
$stmt = $db->prepare($query);
$result = $stmt->execute();
$rows = [];
while ($row = $result->fetchArray(SQLITE3_ASSOC)) {
$rows[] = $row;
}
if ($rows) {
if ($admin['smtp_address'] && $admin['smtp_port'] && $admin['smtp_username'] && $admin['smtp_password'] && $admin['encryption']) {
// There are SMTP settings
$smtpAddress = $admin['smtp_address'];
$smtpPort = $admin['smtp_port'];
$smtpUsername = $admin['smtp_username'];
$smtpPassword = $admin['smtp_password'];
$fromEmail = empty($admin['from_email']) ? 'wallos@wallosapp.com' : $admin['from_email'];
$encryption = $admin['encryption'];
$server_url = $admin['server_url'];
require __DIR__ . '/../../libs/PHPMailer/PHPMailer.php';
require __DIR__ . '/../../libs/PHPMailer/SMTP.php';
require __DIR__ . '/../../libs/PHPMailer/Exception.php';
$mail = new PHPMailer(true);
$mail->isSMTP();
$mail->Host = $smtpAddress;
$mail->SMTPAuth = true;
$mail->Username = $smtpUsername;
$mail->Password = $smtpPassword;
$mail->SMTPSecure = $encryption;
$mail->Port = $smtpPort;
$mail->setFrom($fromEmail);
try {
foreach ($rows as $user) {
$mail->addAddress($user['email']);
$mail->isHTML(true);
$mail->Subject = 'Wallos - Email Verification';
$mail->Body = '<img src="' . $server_url . '/images/siteicons/blue/wallos.png" alt="Logo" />
<br>
Registration on Wallos was successful.
<br>
Please click the following link to verify your email: <a href="' . $server_url . '/verifyemail.php?email=' . $user['email'] . '&token=' . $user['token'] . '">Verify Email</a>';
$mail->send();
$query = "UPDATE email_verification SET email_sent = 1 WHERE id = :id";
$stmt = $db->prepare($query);
$stmt->bindParam(':id', $user['id'], SQLITE3_INTEGER);
$stmt->execute();
$mail->clearAddresses();
echo "Verification email sent to " . $user['email'] . "<br>";
}
} catch (Exception $e) {
echo "Message could not be sent. Mailer Error: {$mail->ErrorInfo}";
}
} else {
// There are no SMTP settings
exit();
}
} else {
// There are no verification emails to be sent
exit();
}
?>

View File

@ -1,73 +1,92 @@
<?php <?php
require_once __DIR__ . '/../../includes/connect_endpoint_crontabs.php'; require_once __DIR__ . '/../../includes/connect_endpoint_crontabs.php';
$query = "SELECT api_key FROM fixer"; // Get all user ids
$result = $db->query($query);
if ($result) { $query = "SELECT id, username FROM user";
$row = $result->fetchArray(SQLITE3_ASSOC); $stmt = $db->prepare($query);
$usersToUpdateExchange = $stmt->execute();
if ($row) {
$apiKey = $row['api_key'];
$codes = ""; while ($userToUpdateExchange = $usersToUpdateExchange->fetchArray(SQLITE3_ASSOC)) {
$query = "SELECT id, name, symbol, code FROM currencies"; $userId = $userToUpdateExchange['id'];
$result = $db->query($query); echo "For user: " . $userToUpdateExchange['username'] . "<br />";
while ($row = $result->fetchArray(SQLITE3_ASSOC)) {
$codes .= $row['code'].","; $query = "SELECT api_key FROM fixer WHERE user_id = :userId";
} $stmt = $db->prepare($query);
$codes = rtrim($codes, ','); $stmt->bindParam(':userId', $userId, SQLITE3_INTEGER);
$query = "SELECT u.main_currency, c.code FROM user u LEFT JOIN currencies c ON u.main_currency = c.id WHERE u.id = 1"; $result = $stmt->execute();
$stmt = $db->prepare($query);
$result = $stmt->execute(); if ($result) {
$row = $result->fetchArray(SQLITE3_ASSOC); $row = $result->fetchArray(SQLITE3_ASSOC);
$mainCurrencyCode = $row['code'];
$mainCurrencyId = $row['main_currency']; if ($row) {
$apiKey = $row['api_key'];
$api_url = "http://data.fixer.io/api/latest?access_key=". $apiKey . "&base=EUR&symbols=" . $codes; $codes = "";
$response = file_get_contents($api_url); $query = "SELECT id, name, symbol, code FROM currencies WHERE user_id = :userId";
$apiData = json_decode($response, true);
$mainCurrencyToEUR = $apiData['rates'][$mainCurrencyCode];
if ($apiData !== null && isset($apiData['rates'])) {
foreach ($apiData['rates'] as $currencyCode => $rate) {
if ($currencyCode === $mainCurrencyCode) {
$exchangeRate = 1.0;
} else {
$exchangeRate = $rate / $mainCurrencyToEUR;
}
$updateQuery = "UPDATE currencies SET rate = :rate WHERE code = :code";
$updateStmt = $db->prepare($updateQuery);
$updateStmt->bindParam(':rate', $exchangeRate, SQLITE3_TEXT);
$updateStmt->bindParam(':code', $currencyCode, SQLITE3_TEXT);
$updateResult = $updateStmt->execute();
if (!$updateResult) {
echo "Error updating rate for currency: $currencyCode";
}
}
$currentDate = new DateTime();
$formattedDate = $currentDate->format('Y-m-d');
$deleteQuery = "DELETE FROM last_exchange_update";
$deleteStmt = $db->prepare($deleteQuery);
$deleteResult = $deleteStmt->execute();
$query = "INSERT INTO last_exchange_update (date) VALUES (:formattedDate)";
$stmt = $db->prepare($query); $stmt = $db->prepare($query);
$stmt->bindParam(':formattedDate', $formattedDate, SQLITE3_TEXT); $stmt->bindParam(':userId', $userId, SQLITE3_INTEGER);
$result = $stmt->execute(); $result = $stmt->execute();
while ($row = $result->fetchArray(SQLITE3_ASSOC)) {
$codes .= $row['code'].",";
}
$codes = rtrim($codes, ',');
$query = "SELECT u.main_currency, c.code FROM user u LEFT JOIN currencies c ON u.main_currency = c.id WHERE u.id = :userId";
$stmt = $db->prepare($query);
$stmt->bindParam(':userId', $userId, SQLITE3_INTEGER);
$result = $stmt->execute();
$row = $result->fetchArray(SQLITE3_ASSOC);
$mainCurrencyCode = $row['code'];
$mainCurrencyId = $row['main_currency'];
$db->close(); $api_url = "http://data.fixer.io/api/latest?access_key=". $apiKey . "&base=EUR&symbols=" . $codes;
echo "Rates updated successfully!"; $response = file_get_contents($api_url);
$apiData = json_decode($response, true);
$mainCurrencyToEUR = $apiData['rates'][$mainCurrencyCode];
if ($apiData !== null && isset($apiData['rates'])) {
foreach ($apiData['rates'] as $currencyCode => $rate) {
if ($currencyCode === $mainCurrencyCode) {
$exchangeRate = 1.0;
} else {
$exchangeRate = $rate / $mainCurrencyToEUR;
}
$updateQuery = "UPDATE currencies SET rate = :rate WHERE code = :code";
$updateStmt = $db->prepare($updateQuery);
$updateStmt->bindParam(':rate', $exchangeRate, SQLITE3_TEXT);
$updateStmt->bindParam(':code', $currencyCode, SQLITE3_TEXT);
$updateResult = $updateStmt->execute();
if (!$updateResult) {
echo "Error updating rate for currency: $currencyCode <br />";
}
}
$currentDate = new DateTime();
$formattedDate = $currentDate->format('Y-m-d');
$deleteQuery = "DELETE FROM last_exchange_update WHERE user_id = :userId";
$deleteStmt = $db->prepare($deleteQuery);
$deleteResult = $deleteStmt->execute();
$query = "INSERT INTO last_exchange_update (date, user_id) VALUES (:formattedDate, :userId)";
$stmt = $db->prepare($query);
$stmt->bindParam(':formattedDate', $formattedDate, SQLITE3_TEXT);
$stmt->bindParam(':userId', $userId, SQLITE3_INTEGER);
$result = $stmt->execute();
$db->close();
echo "Rates updated successfully!<br />";
}
} else {
echo "Exchange rates update skipped. No fixer.io api key provided<br />";
$apiKey = null;
} }
} else { } else {
echo "Exchange rates update skipped. No fixer.io api key provided"; echo "Exchange rates update skipped. No fixer.io api key provided<br />";
$apiKey = null; $apiKey = null;
} }
} else {
echo "Exchange rates update skipped. No fixer.io api key provided";
$apiKey = null;
} }
?> ?>

View File

@ -2,20 +2,19 @@
require_once '../../includes/connect_endpoint.php'; require_once '../../includes/connect_endpoint.php';
require_once '../../includes/inputvalidation.php'; require_once '../../includes/inputvalidation.php';
session_start();
if (isset($_SESSION['loggedin']) && $_SESSION['loggedin'] === true) { if (isset($_SESSION['loggedin']) && $_SESSION['loggedin'] === true) {
if (isset($_GET['action']) && $_GET['action'] == "add") { if (isset($_GET['action']) && $_GET['action'] == "add") {
$currencyName = "Currency"; $currencyName = "Currency";
$currencySymbol = "$"; $currencySymbol = "$";
$currencyCode = "CODE"; $currencyCode = "CODE";
$currencyRate = 1; $currencyRate = 1;
$sqlInsert = "INSERT INTO currencies (name, symbol, code, rate) VALUES (:name, :symbol, :code, :rate)"; $sqlInsert = "INSERT INTO currencies (name, symbol, code, rate, user_id) VALUES (:name, :symbol, :code, :rate, :userId)";
$stmtInsert = $db->prepare($sqlInsert); $stmtInsert = $db->prepare($sqlInsert);
$stmtInsert->bindParam(':name', $currencyName, SQLITE3_TEXT); $stmtInsert->bindParam(':name', $currencyName, SQLITE3_TEXT);
$stmtInsert->bindParam(':symbol', $currencySymbol, SQLITE3_TEXT); $stmtInsert->bindParam(':symbol', $currencySymbol, SQLITE3_TEXT);
$stmtInsert->bindParam(':code', $currencyCode, SQLITE3_TEXT); $stmtInsert->bindParam(':code', $currencyCode, SQLITE3_TEXT);
$stmtInsert->bindParam(':rate', $currencyRate, SQLITE3_TEXT); $stmtInsert->bindParam(':rate', $currencyRate, SQLITE3_TEXT);
$stmtInsert->bindParam(':userId', $userId, SQLITE3_INTEGER);
$resultInsert = $stmtInsert->execute(); $resultInsert = $stmtInsert->execute();
if ($resultInsert) { if ($resultInsert) {
@ -30,12 +29,13 @@ if (isset($_SESSION['loggedin']) && $_SESSION['loggedin'] === true) {
$name = validate($_GET['name']); $name = validate($_GET['name']);
$symbol = validate($_GET['symbol']); $symbol = validate($_GET['symbol']);
$code = validate($_GET['code']); $code = validate($_GET['code']);
$sql = "UPDATE currencies SET name = :name, symbol = :symbol, code = :code WHERE id = :currencyId"; $sql = "UPDATE currencies SET name = :name, symbol = :symbol, code = :code WHERE id = :currencyId AND user_id = :userId";
$stmt = $db->prepare($sql); $stmt = $db->prepare($sql);
$stmt->bindParam(':name', $name, SQLITE3_TEXT); $stmt->bindParam(':name', $name, SQLITE3_TEXT);
$stmt->bindParam(':symbol', $symbol, SQLITE3_TEXT); $stmt->bindParam(':symbol', $symbol, SQLITE3_TEXT);
$stmt->bindParam(':code', $code, SQLITE3_TEXT); $stmt->bindParam(':code', $code, SQLITE3_TEXT);
$stmt->bindParam(':currencyId', $currencyId, SQLITE3_INTEGER); $stmt->bindParam(':currencyId', $currencyId, SQLITE3_INTEGER);
$stmt->bindParam(':userId', $userId, SQLITE3_INTEGER);
$result = $stmt->execute(); $result = $stmt->execute();
if ($result) { if ($result) {
@ -60,16 +60,18 @@ if (isset($_SESSION['loggedin']) && $_SESSION['loggedin'] === true) {
} }
} else if (isset($_GET['action']) && $_GET['action'] == "delete") { } else if (isset($_GET['action']) && $_GET['action'] == "delete") {
if (isset($_GET['currencyId']) && $_GET['currencyId'] != "") { if (isset($_GET['currencyId']) && $_GET['currencyId'] != "") {
$query = "SELECT main_currency FROM user WHERE id = 1"; $query = "SELECT main_currency FROM user WHERE id = :userId";
$stmt = $db->prepare($query); $stmt = $db->prepare($query);
$stmt->bindParam(':userId', $userId, SQLITE3_INTEGER);
$result = $stmt->execute(); $result = $stmt->execute();
$row = $result->fetchArray(SQLITE3_ASSOC); $row = $result->fetchArray(SQLITE3_ASSOC);
$mainCurrencyId = $row['main_currency']; $mainCurrencyId = $row['main_currency'];
$currencyId = $_GET['currencyId']; $currencyId = $_GET['currencyId'];
$checkQuery = "SELECT COUNT(*) FROM subscriptions WHERE currency_id = :currencyId"; $checkQuery = "SELECT COUNT(*) FROM subscriptions WHERE currency_id = :currencyId AND user_id = :userId";
$checkStmt = $db->prepare($checkQuery); $checkStmt = $db->prepare($checkQuery);
$checkStmt->bindParam(':currencyId', $currencyId, SQLITE3_INTEGER); $checkStmt->bindParam(':currencyId', $currencyId, SQLITE3_INTEGER);
$checkStmt->bindParam(':userId', $userId, SQLITE3_INTEGER);
$checkResult = $checkStmt->execute(); $checkResult = $checkStmt->execute();
$row = $checkResult->fetchArray(); $row = $checkResult->fetchArray();
$count = $row[0]; $count = $row[0];
@ -90,9 +92,10 @@ if (isset($_SESSION['loggedin']) && $_SESSION['loggedin'] === true) {
echo json_encode($response); echo json_encode($response);
exit; exit;
} else { } else {
$sql = "DELETE FROM currencies WHERE id = :currencyId"; $sql = "DELETE FROM currencies WHERE id = :currencyId AND user_id = :userId";
$stmt = $db->prepare($sql); $stmt = $db->prepare($sql);
$stmt->bindParam(':currencyId', $currencyId, SQLITE3_INTEGER); $stmt->bindParam(':currencyId', $currencyId, SQLITE3_INTEGER);
$stmt->bindParam(':userId', $userId, SQLITE3_INTEGER);
$result = $stmt->execute(); $result = $stmt->execute();
if ($result) { if ($result) {
echo json_encode(["success" => true, "message" => translate('currency_removed', $i18n)]); echo json_encode(["success" => true, "message" => translate('currency_removed', $i18n)]);

View File

@ -1,14 +1,15 @@
<?php <?php
require_once '../../includes/connect_endpoint.php'; require_once '../../includes/connect_endpoint.php';
session_start();
if (isset($_SESSION['loggedin']) && $_SESSION['loggedin'] === true) { if (isset($_SESSION['loggedin']) && $_SESSION['loggedin'] === true) {
if ($_SERVER["REQUEST_METHOD"] === "POST") { if ($_SERVER["REQUEST_METHOD"] === "POST") {
$newApiKey = isset($_POST["api_key"]) ? $_POST["api_key"] : ""; $newApiKey = isset($_POST["api_key"]) ? $_POST["api_key"] : "";
$provider = isset($_POST["provider"]) ? $_POST["provider"] : 0; $provider = isset($_POST["provider"]) ? $_POST["provider"] : 0;
$removeOldKey = "DELETE FROM fixer"; $removeOldKey = "DELETE FROM fixer WHERE user_id = :userId";
$db->exec($removeOldKey); $stmt = $db->prepare($removeOldKey);
$stmt->bindParam(":userId", $userId, SQLITE3_INTEGER);
$stmt->execute();
if ($provider == 1) { if ($provider == 1) {
$testKeyUrl = "https://api.apilayer.com/fixer/latest?base=USD&symbols=EUR"; $testKeyUrl = "https://api.apilayer.com/fixer/latest?base=USD&symbols=EUR";
@ -27,10 +28,11 @@
$apiData = json_decode($response, true); $apiData = json_decode($response, true);
if ($apiData['success'] && $apiData['success'] == 1) { if ($apiData['success'] && $apiData['success'] == 1) {
if (!empty($newApiKey)) { if (!empty($newApiKey)) {
$insertNewKey = "INSERT INTO fixer (api_key, provider) VALUES (:api_key, :provider)"; $insertNewKey = "INSERT INTO fixer (api_key, provider, user_id) VALUES (:api_key, :provider, :userId)";
$stmt = $db->prepare($insertNewKey); $stmt = $db->prepare($insertNewKey);
$stmt->bindParam(":api_key", $newApiKey, SQLITE3_TEXT); $stmt->bindParam(":api_key", $newApiKey, SQLITE3_TEXT);
$stmt->bindParam(":provider", $provider, SQLITE3_INTEGER); $stmt->bindParam(":provider", $provider, SQLITE3_INTEGER);
$stmt->bindParam(":userId", $userId, SQLITE3_INTEGER);
$result = $stmt->execute(); $result = $stmt->execute();
if ($result) { if ($result) {
echo json_encode(["success" => true, "message" => translate('api_key_saved', $i18n)]); echo json_encode(["success" => true, "message" => translate('api_key_saved', $i18n)]);

View File

@ -6,8 +6,10 @@ $shouldUpdate = true;
if (isset($_GET['force']) && $_GET['force'] === "true") { if (isset($_GET['force']) && $_GET['force'] === "true") {
$shouldUpdate = true; $shouldUpdate = true;
} else { } else {
$query = "SELECT date FROM last_exchange_update"; $query = "SELECT date FROM last_exchange_update WHERE user_id = :userId";
$result = $db->querySingle($query); $stmt = $db->prepare($query);
$stmt->bindParam(':userId', $userId, SQLITE3_INTEGER);
$result = $stmt->execute();
if ($result) { if ($result) {
$lastUpdateDate = new DateTime($result); $lastUpdateDate = new DateTime($result);
@ -34,14 +36,17 @@ if ($result) {
$provider = $row['provider']; $provider = $row['provider'];
$codes = ""; $codes = "";
$query = "SELECT id, name, symbol, code FROM currencies"; $query = "SELECT id, name, symbol, code FROM currencies WHERE user_id = :userId";
$result = $db->query($query); $stmt = $db->prepare($query);
$stmt->bindParam(':userId', $userId, SQLITE3_INTEGER);
$result = $stmt->execute();
while ($row = $result->fetchArray(SQLITE3_ASSOC)) { while ($row = $result->fetchArray(SQLITE3_ASSOC)) {
$codes .= $row['code'].","; $codes .= $row['code'].",";
} }
$codes = rtrim($codes, ','); $codes = rtrim($codes, ',');
$query = "SELECT u.main_currency, c.code FROM user u LEFT JOIN currencies c ON u.main_currency = c.id WHERE u.id = 1"; $query = "SELECT u.main_currency, c.code FROM user u LEFT JOIN currencies c ON u.main_currency = c.id WHERE u.id = :userId";
$stmt = $db->prepare($query); $stmt = $db->prepare($query);
$stmt->bindParam(':userId', $userId, SQLITE3_INTEGER);
$result = $stmt->execute(); $result = $stmt->execute();
$row = $result->fetchArray(SQLITE3_ASSOC); $row = $result->fetchArray(SQLITE3_ASSOC);
$mainCurrencyCode = $row['code']; $mainCurrencyCode = $row['code'];
@ -72,10 +77,11 @@ if ($result) {
} else { } else {
$exchangeRate = $rate / $mainCurrencyToEUR; $exchangeRate = $rate / $mainCurrencyToEUR;
} }
$updateQuery = "UPDATE currencies SET rate = :rate WHERE code = :code"; $updateQuery = "UPDATE currencies SET rate = :rate WHERE code = :code AND user_id = :userId";
$updateStmt = $db->prepare($updateQuery); $updateStmt = $db->prepare($updateQuery);
$updateStmt->bindParam(':rate', $exchangeRate, SQLITE3_TEXT); $updateStmt->bindParam(':rate', $exchangeRate, SQLITE3_TEXT);
$updateStmt->bindParam(':code', $currencyCode, SQLITE3_TEXT); $updateStmt->bindParam(':code', $currencyCode, SQLITE3_TEXT);
$updateStmt->bindParam(':userId', $userId, SQLITE3_INTEGER);
$updateResult = $updateStmt->execute(); $updateResult = $updateStmt->execute();
if (!$updateResult) { if (!$updateResult) {
@ -85,14 +91,11 @@ if ($result) {
$currentDate = new DateTime(); $currentDate = new DateTime();
$formattedDate = $currentDate->format('Y-m-d'); $formattedDate = $currentDate->format('Y-m-d');
$deleteQuery = "DELETE FROM last_exchange_update"; $updateQuery = "UPDATE last_exchange_update SET date = :formattedDate WHERE user_id = :userId";
$deleteStmt = $db->prepare($deleteQuery); $updateStmt = $db->prepare($updateQuery);
$deleteResult = $deleteStmt->execute(); $updateStmt->bindParam(':formattedDate', $formattedDate, SQLITE3_TEXT);
$updateStmt->bindParam(':userId', $userId, SQLITE3_INTEGER);
$query = "INSERT INTO last_exchange_update (date) VALUES (:formattedDate)"; $updateResult = $updateStmt->execute();
$stmt = $db->prepare($query);
$stmt->bindParam(':formattedDate', $formattedDate, SQLITE3_TEXT);
$result = $stmt->execute();
$db->close(); $db->close();
echo "Rates updated successfully!"; echo "Rates updated successfully!";

View File

@ -1,6 +1,6 @@
<?php <?php
require_once '../../includes/connect_endpoint.php'; require_once '../../includes/connect_endpoint.php';
session_start();
if (!isset($_SESSION['loggedin']) || $_SESSION['loggedin'] !== true) { if (!isset($_SESSION['loggedin']) || $_SESSION['loggedin'] !== true) {
die(json_encode([ die(json_encode([
"success" => false, "success" => false,

View File

@ -1,6 +1,5 @@
<?php <?php
require_once '../../includes/connect_endpoint.php'; require_once '../../includes/connect_endpoint.php';
session_start();
$result = $db->query("SELECT COUNT(*) as count FROM user"); $result = $db->query("SELECT COUNT(*) as count FROM user");
$row = $result->fetchArray(SQLITE3_NUM); $row = $result->fetchArray(SQLITE3_NUM);

View File

@ -33,6 +33,15 @@ $allMigrations = glob('migrations/*.php');
if (count($allMigrations) == 0) { if (count($allMigrations) == 0) {
$allMigrations = glob('../../migrations/*.php'); $allMigrations = glob('../../migrations/*.php');
} }
$allMigrations = array_map(function($migration) {
return str_replace('../../', '', $migration);
}, $allMigrations);
$completedMigrations = array_map(function($migration) {
return str_replace('../../', '', $migration);
}, $completedMigrations);
$requiredMigrations = array_diff($allMigrations, $completedMigrations); $requiredMigrations = array_diff($allMigrations, $completedMigrations);
if (count($requiredMigrations) === 0) { if (count($requiredMigrations) === 0) {

View File

@ -1,6 +1,6 @@
<?php <?php
require_once '../../includes/connect_endpoint.php'; require_once '../../includes/connect_endpoint.php';
session_start();
if (!isset($_SESSION['loggedin']) || $_SESSION['loggedin'] !== true) { if (!isset($_SESSION['loggedin']) || $_SESSION['loggedin'] !== true) {
die(json_encode([ die(json_encode([
"success" => false, "success" => false,

View File

@ -2,14 +2,13 @@
require_once '../../includes/connect_endpoint.php'; require_once '../../includes/connect_endpoint.php';
require_once '../../includes/inputvalidation.php'; require_once '../../includes/inputvalidation.php';
session_start();
if (isset($_SESSION['loggedin']) && $_SESSION['loggedin'] === true) { if (isset($_SESSION['loggedin']) && $_SESSION['loggedin'] === true) {
if (isset($_GET['action']) && $_GET['action'] == "add") { if (isset($_GET['action']) && $_GET['action'] == "add") {
$householdName = "Member"; $householdName = "Member";
$sqlInsert = "INSERT INTO household (name) VALUES (:name)"; $sqlInsert = "INSERT INTO household (name, user_id) VALUES (:name, :userId)";
$stmtInsert = $db->prepare($sqlInsert); $stmtInsert = $db->prepare($sqlInsert);
$stmtInsert->bindParam(':name', $householdName, SQLITE3_TEXT); $stmtInsert->bindParam(':name', $householdName, SQLITE3_TEXT);
$stmtInsert->bindParam(':userId', $userId, SQLITE3_INTEGER);
$resultInsert = $stmtInsert->execute(); $resultInsert = $stmtInsert->execute();
if ($resultInsert) { if ($resultInsert) {
@ -32,11 +31,12 @@ if (isset($_SESSION['loggedin']) && $_SESSION['loggedin'] === true) {
$name = validate($_GET['name']); $name = validate($_GET['name']);
$email = $_GET['email'] ? $_GET['email'] : ""; $email = $_GET['email'] ? $_GET['email'] : "";
$email = validate($email); $email = validate($email);
$sql = "UPDATE household SET name = :name, email = :email WHERE id = :memberId"; $sql = "UPDATE household SET name = :name, email = :email WHERE id = :memberId AND user_id = :userId";
$stmt = $db->prepare($sql); $stmt = $db->prepare($sql);
$stmt->bindParam(':name', $name, SQLITE3_TEXT); $stmt->bindParam(':name', $name, SQLITE3_TEXT);
$stmt->bindParam(':email', $email, SQLITE3_TEXT); $stmt->bindParam(':email', $email, SQLITE3_TEXT);
$stmt->bindParam(':memberId', $memberId, SQLITE3_INTEGER); $stmt->bindParam(':memberId', $memberId, SQLITE3_INTEGER);
$stmt->bindParam(':userId', $userId, SQLITE3_INTEGER);
$result = $stmt->execute(); $result = $stmt->execute();
if ($result) { if ($result) {
@ -62,9 +62,10 @@ if (isset($_SESSION['loggedin']) && $_SESSION['loggedin'] === true) {
} else if (isset($_GET['action']) && $_GET['action'] == "delete") { } else if (isset($_GET['action']) && $_GET['action'] == "delete") {
if (isset($_GET['memberId']) && $_GET['memberId'] != "" && $_GET['memberId'] != 1) { if (isset($_GET['memberId']) && $_GET['memberId'] != "" && $_GET['memberId'] != 1) {
$memberId = $_GET['memberId']; $memberId = $_GET['memberId'];
$checkMember = "SELECT COUNT(*) FROM subscriptions WHERE payer_user_id = :memberId"; $checkMember = "SELECT COUNT(*) FROM subscriptions WHERE payer_user_id = :memberId AND user_id = :userId";
$checkStmt = $db->prepare($checkMember); $checkStmt = $db->prepare($checkMember);
$checkStmt->bindParam(':memberId', $memberId, SQLITE3_INTEGER); $checkStmt->bindParam(':memberId', $memberId, SQLITE3_INTEGER);
$checkStmt->bindParam(':userId', $userId, SQLITE3_INTEGER);
$checkResult = $checkStmt->execute(); $checkResult = $checkStmt->execute();
$row = $checkResult->fetchArray(); $row = $checkResult->fetchArray();
$count = $row[0]; $count = $row[0];
@ -76,9 +77,10 @@ if (isset($_SESSION['loggedin']) && $_SESSION['loggedin'] === true) {
]; ];
echo json_encode($response); echo json_encode($response);
} else { } else {
$sql = "DELETE FROM household WHERE id = :memberId"; $sql = "DELETE FROM household WHERE id = :memberId and user_id = :userId";
$stmt = $db->prepare($sql); $stmt = $db->prepare($sql);
$stmt->bindParam(':memberId', $memberId, SQLITE3_INTEGER); $stmt->bindParam(':memberId', $memberId, SQLITE3_INTEGER);
$stmt->bindParam(':userId', $userId, SQLITE3_INTEGER);
$result = $stmt->execute(); $result = $stmt->execute();
if ($result) { if ($result) {
$response = [ $response = [

View File

@ -1,7 +1,6 @@
<?php <?php
require_once '../../includes/connect_endpoint.php'; require_once '../../includes/connect_endpoint.php';
session_start();
if (!isset($_SESSION['loggedin']) || $_SESSION['loggedin'] !== true) { if (!isset($_SESSION['loggedin']) || $_SESSION['loggedin'] !== true) {
die(json_encode([ die(json_encode([
@ -28,8 +27,10 @@ require_once '../../includes/connect_endpoint.php';
$bot_username = $data["bot_username"]; $bot_username = $data["bot_username"];
$bot_avatar_url = $data["bot_avatar"]; $bot_avatar_url = $data["bot_avatar"];
$query = "SELECT COUNT(*) FROM discord_notifications"; $query = "SELECT COUNT(*) FROM discord_notifications WHERE user_id = :userId";
$result = $db->querySingle($query); $stmt = $db->prepare($query);
$stmt->bindParam(":userId", $userId, SQLITE3_INTEGER);
$result = $stmt->execute();
if ($result === false) { if ($result === false) {
$response = [ $response = [
@ -38,12 +39,15 @@ require_once '../../includes/connect_endpoint.php';
]; ];
echo json_encode($response); echo json_encode($response);
} else { } else {
if ($result == 0) { $row = $result->fetchArray();
$query = "INSERT INTO discord_notifications (enabled, webhook_url, bot_username, bot_avatar_url) $count = $row[0];
VALUES (:enabled, :webhook_url, :bot_username, :bot_avatar_url)"; if ($count == 0) {
$query = "INSERT INTO discord_notifications (enabled, webhook_url, bot_username, bot_avatar_url, user_id)
VALUES (:enabled, :webhook_url, :bot_username, :bot_avatar_url, :userId)";
} else { } else {
$query = "UPDATE discord_notifications $query = "UPDATE discord_notifications
SET enabled = :enabled, webhook_url = :webhook_url, bot_username = :bot_username, bot_avatar_url = :bot_avatar_url"; SET enabled = :enabled, webhook_url = :webhook_url, bot_username = :bot_username, bot_avatar_url = :bot_avatar_url
WHERE user_id = :userId";
} }
$stmt = $db->prepare($query); $stmt = $db->prepare($query);
@ -51,6 +55,7 @@ require_once '../../includes/connect_endpoint.php';
$stmt->bindValue(':webhook_url', $webhook_url, SQLITE3_TEXT); $stmt->bindValue(':webhook_url', $webhook_url, SQLITE3_TEXT);
$stmt->bindValue(':bot_username', $bot_username, SQLITE3_TEXT); $stmt->bindValue(':bot_username', $bot_username, SQLITE3_TEXT);
$stmt->bindValue(':bot_avatar_url', $bot_avatar_url, SQLITE3_TEXT); $stmt->bindValue(':bot_avatar_url', $bot_avatar_url, SQLITE3_TEXT);
$stmt->bindValue(':userId', $userId, SQLITE3_INTEGER);
if ($stmt->execute()) { if ($stmt->execute()) {
$response = [ $response = [

View File

@ -1,6 +1,5 @@
<?php <?php
require_once '../../includes/connect_endpoint.php'; require_once '../../includes/connect_endpoint.php';
session_start();
if (!isset($_SESSION['loggedin']) || $_SESSION['loggedin'] !== true) { if (!isset($_SESSION['loggedin']) || $_SESSION['loggedin'] !== true) {
die(json_encode([ die(json_encode([
@ -36,8 +35,10 @@
$smtpPassword = $data["smtppassword"]; $smtpPassword = $data["smtppassword"];
$fromEmail = $data["fromemail"]; $fromEmail = $data["fromemail"];
$query = "SELECT COUNT(*) FROM email_notifications"; $query = "SELECT COUNT(*) FROM email_notifications WHERE user_id = :userId";
$result = $db->querySingle($query); $stmt = $db->prepare($query);
$stmt->bindParam(":userId", $userId, SQLITE3_INTEGER);
$result = $stmt->execute();
if ($result === false) { if ($result === false) {
$response = [ $response = [
@ -46,13 +47,15 @@
]; ];
echo json_encode($response); echo json_encode($response);
} else { } else {
if ($result == 0) { $row = $result->fetchArray();
$query = "INSERT INTO email_notifications (enabled, smtp_address, smtp_port, smtp_username, smtp_password, from_email, encryption) $count = $row[0];
VALUES (:enabled, :smtpAddress, :smtpPort, :smtpUsername, :smtpPassword, :fromEmail, :encryption)"; if ($count == 0) {
$query = "INSERT INTO email_notifications (enabled, smtp_address, smtp_port, smtp_username, smtp_password, from_email, encryption, user_id)
VALUES (:enabled, :smtpAddress, :smtpPort, :smtpUsername, :smtpPassword, :fromEmail, :encryption, :userId)";
} else { } else {
$query = "UPDATE email_notifications $query = "UPDATE email_notifications
SET enabled = :enabled, smtp_address = :smtpAddress, smtp_port = :smtpPort, SET enabled = :enabled, smtp_address = :smtpAddress, smtp_port = :smtpPort,
smtp_username = :smtpUsername, smtp_password = :smtpPassword, from_email = :fromEmail, encryption = :encryption"; smtp_username = :smtpUsername, smtp_password = :smtpPassword, from_email = :fromEmail, encryption = :encryption WHERE user_id = :userId";
} }
$stmt = $db->prepare($query); $stmt = $db->prepare($query);
@ -63,6 +66,7 @@
$stmt->bindValue(':smtpPassword', $smtpPassword, SQLITE3_TEXT); $stmt->bindValue(':smtpPassword', $smtpPassword, SQLITE3_TEXT);
$stmt->bindValue(':fromEmail', $fromEmail, SQLITE3_TEXT); $stmt->bindValue(':fromEmail', $fromEmail, SQLITE3_TEXT);
$stmt->bindValue(':encryption', $encryption, SQLITE3_TEXT); $stmt->bindValue(':encryption', $encryption, SQLITE3_TEXT);
$stmt->bindValue(':userId', $userId, SQLITE3_INTEGER);
if ($stmt->execute()) { if ($stmt->execute()) {
$response = [ $response = [

View File

@ -1,6 +1,5 @@
<?php <?php
require_once '../../includes/connect_endpoint.php'; require_once '../../includes/connect_endpoint.php';
session_start();
if (!isset($_SESSION['loggedin']) || $_SESSION['loggedin'] !== true) { if (!isset($_SESSION['loggedin']) || $_SESSION['loggedin'] !== true) {
die(json_encode([ die(json_encode([
@ -27,8 +26,10 @@
$url = $data["gotify_url"]; $url = $data["gotify_url"];
$token = $data["token"]; $token = $data["token"];
$query = "SELECT COUNT(*) FROM gotify_notifications"; $query = "SELECT COUNT(*) FROM gotify_notifications WHERE user_id = :userId";
$result = $db->querySingle($query); $stmt = $db->prepare($query);
$stmt->bindParam(":userId", $userId, SQLITE3_INTEGER);
$result = $stmt->execute();
if ($result === false) { if ($result === false) {
$response = [ $response = [
@ -37,18 +38,21 @@
]; ];
echo json_encode($response); echo json_encode($response);
} else { } else {
if ($result == 0) { $row = $result->fetchArray();
$query = "INSERT INTO gotify_notifications (enabled, url, token) $count = $row[0];
VALUES (:enabled, :url, :token)"; if ($count == 0) {
$query = "INSERT INTO gotify_notifications (enabled, url, token, user_id)
VALUES (:enabled, :url, :token, :userId)";
} else { } else {
$query = "UPDATE gotify_notifications $query = "UPDATE gotify_notifications
SET enabled = :enabled, url = :url, token = :token"; SET enabled = :enabled, url = :url, token = :token WHERE user_id = :userId";
} }
$stmt = $db->prepare($query); $stmt = $db->prepare($query);
$stmt->bindValue(':enabled', $enabled, SQLITE3_INTEGER); $stmt->bindValue(':enabled', $enabled, SQLITE3_INTEGER);
$stmt->bindValue(':url', $url, SQLITE3_TEXT); $stmt->bindValue(':url', $url, SQLITE3_TEXT);
$stmt->bindValue(':token', $token, SQLITE3_TEXT); $stmt->bindValue(':token', $token, SQLITE3_TEXT);
$stmt->bindValue(':userId', $userId, SQLITE3_INTEGER);
if ($stmt->execute()) { if ($stmt->execute()) {
$response = [ $response = [

View File

@ -1,7 +1,6 @@
<?php <?php
require_once '../../includes/connect_endpoint.php'; require_once '../../includes/connect_endpoint.php';
session_start();
if (!isset($_SESSION['loggedin']) || $_SESSION['loggedin'] !== true) { if (!isset($_SESSION['loggedin']) || $_SESSION['loggedin'] !== true) {
die(json_encode([ die(json_encode([
@ -22,8 +21,10 @@
echo json_encode($response); echo json_encode($response);
} else { } else {
$days = $data["days"]; $days = $data["days"];
$query = "SELECT COUNT(*) FROM notification_settings"; $query = "SELECT COUNT(*) FROM notification_settings WHERE user_id = :userId";
$result = $db->querySingle($query); $stmt = $db->prepare($query);
$stmt->bindParam(":userId", $userId, SQLITE3_INTEGER);
$result = $stmt->execute();
if ($result === false) { if ($result === false) {
$response = [ $response = [
@ -32,15 +33,18 @@
]; ];
echo json_encode($response); echo json_encode($response);
} else { } else {
if ($result == 0) { $row = $result->fetchArray();
$query = "INSERT INTO notification_settings (days) $count = $row[0];
VALUES (:days)"; if ($count == 0) {
$query = "INSERT INTO notification_settings (days, user_id)
VALUES (:days, :userId)";
} else { } else {
$query = "UPDATE notification_settings SET days = :days"; $query = "UPDATE notification_settings SET days = :days WHERE user_id = :userId";
} }
$stmt = $db->prepare($query); $stmt = $db->prepare($query);
$stmt->bindValue(':days', $days, SQLITE3_INTEGER); $stmt->bindValue(':days', $days, SQLITE3_INTEGER);
$stmt->bindValue(':userId', $userId, SQLITE3_INTEGER);
if ($stmt->execute()) { if ($stmt->execute()) {
$response = [ $response = [

View File

@ -1,7 +1,6 @@
<?php <?php
require_once '../../includes/connect_endpoint.php'; require_once '../../includes/connect_endpoint.php';
session_start();
if (!isset($_SESSION['loggedin']) || $_SESSION['loggedin'] !== true) { if (!isset($_SESSION['loggedin']) || $_SESSION['loggedin'] !== true) {
die(json_encode([ die(json_encode([
@ -28,8 +27,10 @@ require_once '../../includes/connect_endpoint.php';
$user_key = $data["user_key"]; $user_key = $data["user_key"];
$token = $data["token"]; $token = $data["token"];
$query = "SELECT COUNT(*) FROM pushover_notifications"; $query = "SELECT COUNT(*) FROM pushover_notifications WHERE user_id = :userId";
$result = $db->querySingle($query); $stmt = $db->prepare($query);
$stmt->bindParam(":userId", $userId, SQLITE3_INTEGER);
$result = $stmt->execute();
if ($result === false) { if ($result === false) {
$response = [ $response = [
@ -38,18 +39,21 @@ require_once '../../includes/connect_endpoint.php';
]; ];
echo json_encode($response); echo json_encode($response);
} else { } else {
if ($result == 0) { $row = $result->fetchArray();
$query = "INSERT INTO pushover_notifications (enabled, user_key, token) $count = $row[0];
VALUES (:enabled, :user_key, :token)"; if ($count == 0) {
$query = "INSERT INTO pushover_notifications (enabled, user_key, token, user_id)
VALUES (:enabled, :user_key, :token, :userId)";
} else { } else {
$query = "UPDATE pushover_notifications $query = "UPDATE pushover_notifications
SET enabled = :enabled, user_key = :user_key, token = :token"; SET enabled = :enabled, user_key = :user_key, token = :token, user_id = :userId";
} }
$stmt = $db->prepare($query); $stmt = $db->prepare($query);
$stmt->bindValue(':enabled', $enabled, SQLITE3_INTEGER); $stmt->bindValue(':enabled', $enabled, SQLITE3_INTEGER);
$stmt->bindValue(':user_key', $user_key, SQLITE3_TEXT); $stmt->bindValue(':user_key', $user_key, SQLITE3_TEXT);
$stmt->bindValue(':token', $token, SQLITE3_TEXT); $stmt->bindValue(':token', $token, SQLITE3_TEXT);
$stmt->bindValue(':userId', $userId, SQLITE3_INTEGER);
if ($stmt->execute()) { if ($stmt->execute()) {
$response = [ $response = [

View File

@ -1,6 +1,5 @@
<?php <?php
require_once '../../includes/connect_endpoint.php'; require_once '../../includes/connect_endpoint.php';
session_start();
if (!isset($_SESSION['loggedin']) || $_SESSION['loggedin'] !== true) { if (!isset($_SESSION['loggedin']) || $_SESSION['loggedin'] !== true) {
die(json_encode([ die(json_encode([
@ -27,8 +26,10 @@
$bot_token = $data["bot_token"]; $bot_token = $data["bot_token"];
$chat_id = $data["chat_id"]; $chat_id = $data["chat_id"];
$query = "SELECT COUNT(*) FROM telegram_notifications"; $query = "SELECT COUNT(*) FROM telegram_notifications WHERE user_id = :userId";
$result = $db->querySingle($query); $stmt = $db->prepare($query);
$stmt->bindParam(":userId", $userId, SQLITE3_INTEGER);
$result = $stmt->execute();
if ($result === false) { if ($result === false) {
$response = [ $response = [
@ -37,18 +38,21 @@
]; ];
echo json_encode($response); echo json_encode($response);
} else { } else {
if ($result == 0) { $row = $result->fetchArray();
$query = "INSERT INTO telegram_notifications (enabled, bot_token, chat_id) $count = $row[0];
VALUES (:enabled, :bot_token, :chat_id)"; if ($count == 0) {
$query = "INSERT INTO telegram_notifications (enabled, bot_token, chat_id, user_id)
VALUES (:enabled, :bot_token, :chat_id, :userId)";
} else { } else {
$query = "UPDATE telegram_notifications $query = "UPDATE telegram_notifications
SET enabled = :enabled, bot_token = :bot_token, chat_id = :chat_id"; SET enabled = :enabled, bot_token = :bot_token, chat_id = :chat_id WHERE user_id = :userId";
} }
$stmt = $db->prepare($query); $stmt = $db->prepare($query);
$stmt->bindValue(':enabled', $enabled, SQLITE3_INTEGER); $stmt->bindValue(':enabled', $enabled, SQLITE3_INTEGER);
$stmt->bindValue(':bot_token', $bot_token, SQLITE3_TEXT); $stmt->bindValue(':bot_token', $bot_token, SQLITE3_TEXT);
$stmt->bindValue(':chat_id', $chat_id, SQLITE3_TEXT); $stmt->bindValue(':chat_id', $chat_id, SQLITE3_TEXT);
$stmt->bindValue(':userId', $userId, SQLITE3_INTEGER);
if ($stmt->execute()) { if ($stmt->execute()) {
$response = [ $response = [

View File

@ -1,6 +1,5 @@
<?php <?php
require_once '../../includes/connect_endpoint.php'; require_once '../../includes/connect_endpoint.php';
session_start();
if (!isset($_SESSION['loggedin']) || $_SESSION['loggedin'] !== true) { if (!isset($_SESSION['loggedin']) || $_SESSION['loggedin'] !== true) {
die(json_encode([ die(json_encode([
@ -28,8 +27,10 @@
$headers = $data["headers"]; $headers = $data["headers"];
$payload = $data["payload"]; $payload = $data["payload"];
$query = "SELECT COUNT(*) FROM webhook_notifications"; $query = "SELECT COUNT(*) FROM webhook_notifications WHERE user_id = :userId";
$result = $db->querySingle($query); $stmt = $db->prepare($query);
$stmt->bindParam(":userId", $userId, SQLITE3_INTEGER);
$result = $stmt->execute();
if ($result === false) { if ($result === false) {
$response = [ $response = [
@ -38,12 +39,14 @@
]; ];
echo json_encode($response); echo json_encode($response);
} else { } else {
if ($result == 0) { $row = $result->fetchArray();
$query = "INSERT INTO webhook_notifications (enabled, url, headers, payload) $count = $row[0];
VALUES (:enabled, :url, :headers, :payload)"; if ($count == 0) {
$query = "INSERT INTO webhook_notifications (enabled, url, headers, payload, user_id)
VALUES (:enabled, :url, :headers, :payload, :userId)";
} else { } else {
$query = "UPDATE webhook_notifications $query = "UPDATE webhook_notifications
SET enabled = :enabled, url = :url, headers = :headers, payload = :payload"; SET enabled = :enabled, url = :url, headers = :headers, payload = :payload WHERE user_id = :userId";
} }
$stmt = $db->prepare($query); $stmt = $db->prepare($query);
@ -51,6 +54,7 @@
$stmt->bindValue(':url', $url, SQLITE3_TEXT); $stmt->bindValue(':url', $url, SQLITE3_TEXT);
$stmt->bindValue(':headers', $headers, SQLITE3_TEXT); $stmt->bindValue(':headers', $headers, SQLITE3_TEXT);
$stmt->bindValue(':payload', $payload, SQLITE3_TEXT); $stmt->bindValue(':payload', $payload, SQLITE3_TEXT);
$stmt->bindValue(':userId', $userId, SQLITE3_INTEGER);
if ($stmt->execute()) { if ($stmt->execute()) {
$response = [ $response = [

View File

@ -1,7 +1,6 @@
<?php <?php
require_once '../../includes/connect_endpoint.php'; require_once '../../includes/connect_endpoint.php';
session_start();
if (!isset($_SESSION['loggedin']) || $_SESSION['loggedin'] !== true) { if (!isset($_SESSION['loggedin']) || $_SESSION['loggedin'] !== true) {
die(json_encode([ die(json_encode([

View File

@ -5,7 +5,6 @@ use PHPMailer\PHPMailer\SMTP;
use PHPMailer\PHPMailer\Exception; use PHPMailer\PHPMailer\Exception;
require_once '../../includes/connect_endpoint.php'; require_once '../../includes/connect_endpoint.php';
session_start();
if (!isset($_SESSION['loggedin']) || $_SESSION['loggedin'] !== true) { if (!isset($_SESSION['loggedin']) || $_SESSION['loggedin'] !== true) {
die(json_encode([ die(json_encode([

View File

@ -1,6 +1,5 @@
<?php <?php
require_once '../../includes/connect_endpoint.php'; require_once '../../includes/connect_endpoint.php';
session_start();
if (!isset($_SESSION['loggedin']) || $_SESSION['loggedin'] !== true) { if (!isset($_SESSION['loggedin']) || $_SESSION['loggedin'] !== true) {
die(json_encode([ die(json_encode([

View File

@ -1,7 +1,6 @@
<?php <?php
require_once '../../includes/connect_endpoint.php'; require_once '../../includes/connect_endpoint.php';
session_start();
if (!isset($_SESSION['loggedin']) || $_SESSION['loggedin'] !== true) { if (!isset($_SESSION['loggedin']) || $_SESSION['loggedin'] !== true) {
die(json_encode([ die(json_encode([

View File

@ -1,6 +1,5 @@
<?php <?php
require_once '../../includes/connect_endpoint.php'; require_once '../../includes/connect_endpoint.php';
session_start();
if (!isset($_SESSION['loggedin']) || $_SESSION['loggedin'] !== true) { if (!isset($_SESSION['loggedin']) || $_SESSION['loggedin'] !== true) {
die(json_encode([ die(json_encode([

View File

@ -1,7 +1,6 @@
<?php <?php
require_once '../../includes/connect_endpoint.php'; require_once '../../includes/connect_endpoint.php';
session_start();
if (!isset($_SESSION['loggedin']) || $_SESSION['loggedin'] !== true) { if (!isset($_SESSION['loggedin']) || $_SESSION['loggedin'] !== true) {
die(json_encode([ die(json_encode([

View File

@ -4,8 +4,6 @@
require_once '../../includes/inputvalidation.php'; require_once '../../includes/inputvalidation.php';
require_once '../../includes/getsettings.php'; require_once '../../includes/getsettings.php';
session_start();
function sanitizeFilename($filename) { function sanitizeFilename($filename) {
$filename = preg_replace("/[^a-zA-Z0-9\s]/", "", $filename); $filename = preg_replace("/[^a-zA-Z0-9\s]/", "", $filename);
$filename = str_replace(" ", "-", $filename); $filename = str_replace(" ", "-", $filename);
@ -193,13 +191,14 @@
$newID = max($maxID + 1, 32); $newID = max($maxID + 1, 32);
// Insert the new record with the new ID // Insert the new record with the new ID
$sql = "INSERT INTO payment_methods (id, name, icon, enabled) VALUES (:id, :name, :icon, :enabled)"; $sql = "INSERT INTO payment_methods (id, name, icon, enabled, user_id) VALUES (:id, :name, :icon, :enabled, :userId)";
$stmt = $db->prepare($sql); $stmt = $db->prepare($sql);
$stmt->bindParam(':id', $newID, SQLITE3_INTEGER); $stmt->bindParam(':id', $newID, SQLITE3_INTEGER);
$stmt->bindParam(':name', $name, SQLITE3_TEXT); $stmt->bindParam(':name', $name, SQLITE3_TEXT);
$stmt->bindParam(':icon', $icon, SQLITE3_TEXT); $stmt->bindParam(':icon', $icon, SQLITE3_TEXT);
$stmt->bindParam(':enabled', $enabled, SQLITE3_INTEGER); $stmt->bindParam(':enabled', $enabled, SQLITE3_INTEGER);
$stmt->bindParam(':userId', $userId, SQLITE3_INTEGER);
if ($stmt->execute()) { if ($stmt->execute()) {
$success['success'] = true; $success['success'] = true;

View File

@ -1,13 +1,14 @@
<?php <?php
require_once '../../includes/connect_endpoint.php'; require_once '../../includes/connect_endpoint.php';
session_start();
if (isset($_SESSION['loggedin']) && $_SESSION['loggedin'] === true) { if (isset($_SESSION['loggedin']) && $_SESSION['loggedin'] === true) {
if ($_SERVER["REQUEST_METHOD"] === "DELETE") { if ($_SERVER["REQUEST_METHOD"] === "DELETE") {
$paymentMethodId = $_GET["id"]; $paymentMethodId = $_GET["id"];
$deleteQuery = "DELETE FROM payment_methods WHERE id = :paymentMethodId"; $deleteQuery = "DELETE FROM payment_methods WHERE id = :paymentMethodId and user_id = :userId";
$deleteStmt = $db->prepare($deleteQuery); $deleteStmt = $db->prepare($deleteQuery);
$deleteStmt->bindParam(':paymentMethodId', $paymentMethodId, SQLITE3_INTEGER); $deleteStmt->bindParam(':paymentMethodId', $paymentMethodId, SQLITE3_INTEGER);
$deleteStmt->bindParam(':userId', $userId, SQLITE3_INTEGER);
if ($deleteStmt->execute()) { if ($deleteStmt->execute()) {
$success['success'] = true; $success['success'] = true;

View File

@ -1,18 +1,22 @@
<?php <?php
require_once '../../includes/connect_endpoint.php'; require_once '../../includes/connect_endpoint.php';
session_start();
if (isset($_SESSION['loggedin']) && $_SESSION['loggedin'] === true) { if (isset($_SESSION['loggedin']) && $_SESSION['loggedin'] === true) {
$paymentsInUseQuery = $db->query('SELECT id FROM payment_methods WHERE id IN (SELECT DISTINCT payment_method_id FROM subscriptions)'); $paymentsInUseQuery = $db->prepare('SELECT id FROM payment_methods WHERE id IN (SELECT DISTINCT payment_method_id FROM subscriptions) AND user_id = :userId');
$paymentsInUseQuery->bindParam(':userId', $userId, SQLITE3_INTEGER);
$result = $paymentsInUseQuery->execute();
$paymentsInUse = []; $paymentsInUse = [];
while ($row = $paymentsInUseQuery->fetchArray(SQLITE3_ASSOC)) { while ($row = $result->fetchArray(SQLITE3_ASSOC)) {
$paymentsInUse[] = $row['id']; $paymentsInUse[] = $row['id'];
} }
$sql = "SELECT * FROM payment_methods"; $sql = "SELECT * FROM payment_methods WHERE user_id = :userId";
$stmt = $db->prepare($sql);
$result = $db->query($sql); $stmt->bindParam(':userId', $userId, SQLITE3_INTEGER);
$result = $stmt->execute();
if ($result) { if ($result) {
$payments = array(); $payments = array();
while ($row = $result->fetchArray(SQLITE3_ASSOC)) { while ($row = $result->fetchArray(SQLITE3_ASSOC)) {
@ -25,7 +29,7 @@ if (isset($_SESSION['loggedin']) && $_SESSION['loggedin'] === true) {
} }
foreach ($payments as $payment) { foreach ($payments as $payment) {
$paymentIconFolder = $payment['id'] <= 31 ? 'images/uploads/icons/' : 'images/uploads/logos/'; $paymentIconFolder = (strpos($payment['icon'], 'images/uploads/icons/') !== false) ? "" : "images/uploads/logos/";
$inUse = in_array($payment['id'], $paymentsInUse); $inUse = in_array($payment['id'], $paymentsInUse);
?> ?>
<div class="payments-payment" <div class="payments-payment"

View File

@ -1,6 +1,6 @@
<?php <?php
require_once '../../includes/connect_endpoint.php'; require_once '../../includes/connect_endpoint.php';
session_start();
if (!isset($_SESSION['loggedin']) || $_SESSION['loggedin'] !== true) { if (!isset($_SESSION['loggedin']) || $_SESSION['loggedin'] !== true) {
die(json_encode([ die(json_encode([
"success" => false, "success" => false,
@ -17,8 +17,9 @@ if (!isset($_GET['paymentId']) || !isset($_GET['enabled'])) {
$paymentId = $_GET['paymentId']; $paymentId = $_GET['paymentId'];
$stmt = $db->prepare('SELECT COUNT(*) as count FROM subscriptions WHERE payment_method_id=:paymentId'); $stmt = $db->prepare('SELECT COUNT(*) as count FROM subscriptions WHERE payment_method_id=:paymentId and user_id=:userId');
$stmt->bindValue(':paymentId', $paymentId, SQLITE3_INTEGER); $stmt->bindValue(':paymentId', $paymentId, SQLITE3_INTEGER);
$stmt->bindValue(':userId', $userId, SQLITE3_INTEGER);
$result = $stmt->execute(); $result = $stmt->execute();
$row = $result->fetchArray(); $row = $result->fetchArray();
$inUse = $row['count'] === 1; $inUse = $row['count'] === 1;
@ -32,10 +33,11 @@ if ($inUse) {
$enabled = $_GET['enabled']; $enabled = $_GET['enabled'];
$sqlUpdate = 'UPDATE payment_methods SET enabled=:enabled WHERE id=:id'; $sqlUpdate = 'UPDATE payment_methods SET enabled=:enabled WHERE id=:id and user_id=:userId';
$stmtUpdate = $db->prepare($sqlUpdate); $stmtUpdate = $db->prepare($sqlUpdate);
$stmtUpdate->bindParam(':enabled', $enabled); $stmtUpdate->bindParam(':enabled', $enabled);
$stmtUpdate->bindParam(':id', $paymentId); $stmtUpdate->bindParam(':id', $paymentId);
$stmtUpdate->bindParam(':userId', $userId);
$resultUpdate = $stmtUpdate->execute(); $resultUpdate = $stmtUpdate->execute();
$text = $enabled ? "enabled" : "disabled"; $text = $enabled ? "enabled" : "disabled";

View File

@ -1,7 +1,6 @@
<?php <?php
require_once '../../includes/connect_endpoint.php'; require_once '../../includes/connect_endpoint.php';
session_start();
if (!isset($_SESSION['loggedin']) || $_SESSION['loggedin'] !== true) { if (!isset($_SESSION['loggedin']) || $_SESSION['loggedin'] !== true) {
die(json_encode([ die(json_encode([
@ -20,10 +19,11 @@ if (!isset($_POST['paymentId']) || !isset($_POST['name']) || $_POST['paymentId']
$paymentId = $_POST['paymentId']; $paymentId = $_POST['paymentId'];
$name = $_POST['name']; $name = $_POST['name'];
$sql = "UPDATE payment_methods SET name = :name WHERE id = :paymentId"; $sql = "UPDATE payment_methods SET name = :name WHERE id = :paymentId and user_id = :userId";
$stmt = $db->prepare($sql); $stmt = $db->prepare($sql);
$stmt->bindParam(':name', $name, SQLITE3_TEXT); $stmt->bindParam(':name', $name, SQLITE3_TEXT);
$stmt->bindParam(':paymentId', $paymentId, SQLITE3_INTEGER); $stmt->bindParam(':paymentId', $paymentId, SQLITE3_INTEGER);
$stmt->bindParam(':userId', $userId, SQLITE3_INTEGER);
$result = $stmt->execute(); $result = $stmt->execute();
if ($result) { if ($result) {

View File

@ -2,17 +2,16 @@
require_once '../../includes/connect_endpoint.php'; require_once '../../includes/connect_endpoint.php';
session_start();
if (isset($_SESSION['loggedin']) && $_SESSION['loggedin'] === true) { if (isset($_SESSION['loggedin']) && $_SESSION['loggedin'] === true) {
$paymentMethods = $_POST['paymentMethodIds']; $paymentMethods = $_POST['paymentMethodIds'];
$order = 1; $order = 1;
foreach ($paymentMethods as $paymentMethodId) { foreach ($paymentMethods as $paymentMethodId) {
$sql = "UPDATE payment_methods SET `order` = :order WHERE id = :paymentMethodId"; $sql = "UPDATE payment_methods SET `order` = :order WHERE id = :paymentMethodId and user_id = :userId";
$stmt = $db->prepare($sql); $stmt = $db->prepare($sql);
$stmt->bindParam(':order', $order, SQLITE3_INTEGER); $stmt->bindParam(':order', $order, SQLITE3_INTEGER);
$stmt->bindParam(':paymentMethodId', $paymentMethodId, SQLITE3_INTEGER); $stmt->bindParam(':paymentMethodId', $paymentMethodId, SQLITE3_INTEGER);
$stmt->bindParam(':userId', $userId, SQLITE3_INTEGER);
$result = $stmt->execute(); $result = $stmt->execute();
$order++; $order++;
} }

View File

@ -1,7 +1,7 @@
<?php <?php
require_once '../../includes/connect_endpoint.php'; require_once '../../includes/connect_endpoint.php';
session_start();
if (!isset($_SESSION['loggedin']) || $_SESSION['loggedin'] !== true) { if (!isset($_SESSION['loggedin']) || $_SESSION['loggedin'] !== true) {
die(json_encode([ die(json_encode([
"success" => false, "success" => false,
@ -15,8 +15,9 @@
$color = $data['color']; $color = $data['color'];
$stmt = $db->prepare('UPDATE settings SET color_theme = :color'); $stmt = $db->prepare('UPDATE settings SET color_theme = :color WHERE user_id = :userId');
$stmt->bindParam(':color', $color, SQLITE3_TEXT); $stmt->bindParam(':color', $color, SQLITE3_TEXT);
$stmt->bindParam(':userId', $userId, SQLITE3_INTEGER);
if ($stmt->execute()) { if ($stmt->execute()) {
die(json_encode([ die(json_encode([

View File

@ -1,6 +1,6 @@
<?php <?php
require_once '../../includes/connect_endpoint.php'; require_once '../../includes/connect_endpoint.php';
session_start();
if (!isset($_SESSION['loggedin']) || $_SESSION['loggedin'] !== true) { if (!isset($_SESSION['loggedin']) || $_SESSION['loggedin'] !== true) {
die(json_encode([ die(json_encode([
"success" => false, "success" => false,
@ -14,8 +14,9 @@ if ($_SERVER["REQUEST_METHOD"] === "POST") {
$convert_currency = $data['value']; $convert_currency = $data['value'];
$stmt = $db->prepare('UPDATE settings SET convert_currency = :convert_currency'); $stmt = $db->prepare('UPDATE settings SET convert_currency = :convert_currency WHERE user_id = :userId');
$stmt->bindParam(':convert_currency', $convert_currency, SQLITE3_INTEGER); $stmt->bindParam(':convert_currency', $convert_currency, SQLITE3_INTEGER);
$stmt->bindParam(':userId', $userId, SQLITE3_INTEGER);
if ($stmt->execute()) { if ($stmt->execute()) {
die(json_encode([ die(json_encode([

View File

@ -1,7 +1,7 @@
<?php <?php
require_once '../../includes/connect_endpoint.php'; require_once '../../includes/connect_endpoint.php';
session_start();
if (!isset($_SESSION['loggedin']) || $_SESSION['loggedin'] !== true) { if (!isset($_SESSION['loggedin']) || $_SESSION['loggedin'] !== true) {
die(json_encode([ die(json_encode([
"success" => false, "success" => false,
@ -20,10 +20,11 @@
$stmt = $db->prepare('DELETE FROM custom_colors'); $stmt = $db->prepare('DELETE FROM custom_colors');
$stmt->execute(); $stmt->execute();
$stmt = $db->prepare('INSERT INTO custom_colors (main_color, accent_color, hover_color) VALUES (:main_color, :accent_color, :hover_color)'); $stmt = $db->prepare('INSERT INTO custom_colors (main_color, accent_color, hover_color, user_id) VALUES (:main_color, :accent_color, :hover_color, :userId)');
$stmt->bindParam(':main_color', $main_color, SQLITE3_TEXT); $stmt->bindParam(':main_color', $main_color, SQLITE3_TEXT);
$stmt->bindParam(':accent_color', $accent_color, SQLITE3_TEXT); $stmt->bindParam(':accent_color', $accent_color, SQLITE3_TEXT);
$stmt->bindParam(':hover_color', $hover_color, SQLITE3_TEXT); $stmt->bindParam(':hover_color', $hover_color, SQLITE3_TEXT);
$stmt->bindParam(':userId', $userId, SQLITE3_INTEGER);
if ($stmt->execute()) { if ($stmt->execute()) {
die(json_encode([ die(json_encode([

View File

@ -1,6 +1,6 @@
<?php <?php
require_once '../../includes/connect_endpoint.php'; require_once '../../includes/connect_endpoint.php';
session_start();
if (!isset($_SESSION['loggedin']) || $_SESSION['loggedin'] !== true) { if (!isset($_SESSION['loggedin']) || $_SESSION['loggedin'] !== true) {
die(json_encode([ die(json_encode([
"success" => false, "success" => false,
@ -14,8 +14,9 @@ if ($_SERVER["REQUEST_METHOD"] === "POST") {
$hide_disabled = $data['value']; $hide_disabled = $data['value'];
$stmt = $db->prepare('UPDATE settings SET hide_disabled = :hide_disabled'); $stmt = $db->prepare('UPDATE settings SET hide_disabled = :hide_disabled WHERE user_id = :userId');
$stmt->bindParam(':hide_disabled', $hide_disabled, SQLITE3_INTEGER); $stmt->bindParam(':hide_disabled', $hide_disabled, SQLITE3_INTEGER);
$stmt->bindParam(':userId', $userId, SQLITE3_INTEGER);
if ($stmt->execute()) { if ($stmt->execute()) {
die(json_encode([ die(json_encode([

View File

@ -1,6 +1,6 @@
<?php <?php
require_once '../../includes/connect_endpoint.php'; require_once '../../includes/connect_endpoint.php';
session_start();
if (!isset($_SESSION['loggedin']) || $_SESSION['loggedin'] !== true) { if (!isset($_SESSION['loggedin']) || $_SESSION['loggedin'] !== true) {
die(json_encode([ die(json_encode([
"success" => false, "success" => false,
@ -14,8 +14,9 @@ if ($_SERVER["REQUEST_METHOD"] === "POST") {
$monthly_price = $data['value']; $monthly_price = $data['value'];
$stmt = $db->prepare('UPDATE settings SET monthly_price = :monthly_price'); $stmt = $db->prepare('UPDATE settings SET monthly_price = :monthly_price WHERE user_id = :userId');
$stmt->bindParam(':monthly_price', $monthly_price, SQLITE3_INTEGER); $stmt->bindParam(':monthly_price', $monthly_price, SQLITE3_INTEGER);
$stmt->bindParam(':userId', $userId, SQLITE3_INTEGER);
if ($stmt->execute()) { if ($stmt->execute()) {
die(json_encode([ die(json_encode([

View File

@ -1,6 +1,6 @@
<?php <?php
require_once '../../includes/connect_endpoint.php'; require_once '../../includes/connect_endpoint.php';
session_start();
if (!isset($_SESSION['loggedin']) || $_SESSION['loggedin'] !== true) { if (!isset($_SESSION['loggedin']) || $_SESSION['loggedin'] !== true) {
die(json_encode([ die(json_encode([
"success" => false, "success" => false,
@ -14,8 +14,9 @@ if ($_SERVER["REQUEST_METHOD"] === "POST") {
$remove_background = $data['value']; $remove_background = $data['value'];
$stmt = $db->prepare('UPDATE settings SET remove_background = :remove_background'); $stmt = $db->prepare('UPDATE settings SET remove_background = :remove_background WHERE user_id = :userId');
$stmt->bindParam(':remove_background', $remove_background, SQLITE3_INTEGER); $stmt->bindParam(':remove_background', $remove_background, SQLITE3_INTEGER);
$stmt->bindParam(':userId', $userId, SQLITE3_INTEGER);
if ($stmt->execute()) { if ($stmt->execute()) {
die(json_encode([ die(json_encode([

View File

@ -1,7 +1,7 @@
<?php <?php
require_once '../../includes/connect_endpoint.php'; require_once '../../includes/connect_endpoint.php';
session_start();
if (!isset($_SESSION['loggedin']) || $_SESSION['loggedin'] !== true) { if (!isset($_SESSION['loggedin']) || $_SESSION['loggedin'] !== true) {
die(json_encode([ die(json_encode([
"success" => false, "success" => false,
@ -10,7 +10,8 @@
} }
if ($_SERVER["REQUEST_METHOD"] === "DELETE") { if ($_SERVER["REQUEST_METHOD"] === "DELETE") {
$stmt = $db->prepare('DELETE FROM custom_colors'); $stmt = $db->prepare('DELETE FROM custom_colors WHERE user_id = :userId');
$stmt->bindParam(':userId', $userId, SQLITE3_INTEGER);
if ($stmt->execute()) { if ($stmt->execute()) {
die(json_encode([ die(json_encode([

View File

@ -1,6 +1,6 @@
<?php <?php
require_once '../../includes/connect_endpoint.php'; require_once '../../includes/connect_endpoint.php';
session_start();
if (!isset($_SESSION['loggedin']) || $_SESSION['loggedin'] !== true) { if (!isset($_SESSION['loggedin']) || $_SESSION['loggedin'] !== true) {
die(json_encode([ die(json_encode([
"success" => false, "success" => false,
@ -14,8 +14,9 @@ if ($_SERVER["REQUEST_METHOD"] === "POST") {
$theme = $data['theme']; $theme = $data['theme'];
$stmt = $db->prepare('UPDATE settings SET dark_theme = :theme'); $stmt = $db->prepare('UPDATE settings SET dark_theme = :theme WHERE user_id = :userId');
$stmt->bindParam(':theme', $theme, SQLITE3_INTEGER); $stmt->bindParam(':theme', $theme, SQLITE3_INTEGER);
$stmt->bindParam(':userId', $userId, SQLITE3_INTEGER);
if ($stmt->execute()) { if ($stmt->execute()) {
die(json_encode([ die(json_encode([

View File

@ -3,8 +3,6 @@
require_once '../../includes/connect_endpoint.php'; require_once '../../includes/connect_endpoint.php';
require_once '../../includes/inputvalidation.php'; require_once '../../includes/inputvalidation.php';
require_once '../../includes/getsettings.php'; require_once '../../includes/getsettings.php';
session_start();
function sanitizeFilename($filename) { function sanitizeFilename($filename) {
$filename = preg_replace("/[^a-zA-Z0-9\s]/", "", $filename); $filename = preg_replace("/[^a-zA-Z0-9\s]/", "", $filename);
@ -184,20 +182,21 @@
if (!$isEdit) { if (!$isEdit) {
$sql = "INSERT INTO subscriptions (name, logo, price, currency_id, next_payment, cycle, frequency, notes, $sql = "INSERT INTO subscriptions (name, logo, price, currency_id, next_payment, cycle, frequency, notes,
payment_method_id, payer_user_id, category_id, notify, inactive, url, notify_days_before) payment_method_id, payer_user_id, category_id, notify, inactive, url, notify_days_before, user_id)
VALUES (:name, :logo, :price, :currencyId, :nextPayment, :cycle, :frequency, :notes, VALUES (:name, :logo, :price, :currencyId, :nextPayment, :cycle, :frequency, :notes,
:paymentMethodId, :payerUserId, :categoryId, :notify, :inactive, :url, :notifyDaysBefore)"; :paymentMethodId, :payerUserId, :categoryId, :notify, :inactive, :url, :notifyDaysBefore, :userId)";
} else { } else {
$id = $_POST['id']; $id = $_POST['id'];
if ($logo != "") { if ($logo != "") {
$sql = "UPDATE subscriptions SET name = :name, logo = :logo, price = :price, currency_id = :currencyId, $sql = "UPDATE subscriptions SET name = :name, logo = :logo, price = :price, currency_id = :currencyId,
next_payment = :nextPayment, cycle = :cycle, frequency = :frequency, notes = :notes, payment_method_id = :paymentMethodId, next_payment = :nextPayment, cycle = :cycle, frequency = :frequency, notes = :notes, payment_method_id = :paymentMethodId,
payer_user_id = :payerUserId, category_id = :categoryId, notify = :notify, inactive = :inactive, payer_user_id = :payerUserId, category_id = :categoryId, notify = :notify, inactive = :inactive,
url = :url, notify_days_before = :notifyDaysBefore WHERE id = :id"; url = :url, notify_days_before = :notifyDaysBefore WHERE id = :id AND user_id = :userId";
} else { } else {
$sql = "UPDATE subscriptions SET name = :name, price = :price, currency_id = :currencyId, next_payment = :nextPayment, $sql = "UPDATE subscriptions SET name = :name, price = :price, currency_id = :currencyId, next_payment = :nextPayment,
cycle = :cycle, frequency = :frequency, notes = :notes, payment_method_id = :paymentMethodId, payer_user_id = :payerUserId, cycle = :cycle, frequency = :frequency, notes = :notes, payment_method_id = :paymentMethodId, payer_user_id = :payerUserId,
category_id = :categoryId, notify = :notify, inactive = :inactive, url = :url,notify_days_before = :notifyDaysBefore WHERE id = :id"; category_id = :categoryId, notify = :notify, inactive = :inactive, url = :url,notify_days_before = :notifyDaysBefore
WHERE id = :id AND user_id = :userId";
} }
} }
@ -222,6 +221,7 @@
$stmt->bindParam(':inactive', $inactive, SQLITE3_INTEGER); $stmt->bindParam(':inactive', $inactive, SQLITE3_INTEGER);
$stmt->bindParam(':url', $url, SQLITE3_TEXT); $stmt->bindParam(':url', $url, SQLITE3_TEXT);
$stmt->bindParam(':notifyDaysBefore', $notifyDaysBefore, SQLITE3_INTEGER); $stmt->bindParam(':notifyDaysBefore', $notifyDaysBefore, SQLITE3_INTEGER);
$stmt->bindParam(':userId', $userId, SQLITE3_INTEGER);
if ($stmt->execute()) { if ($stmt->execute()) {
$success['status'] = "Success"; $success['status'] = "Success";

View File

@ -1,12 +1,13 @@
<?php <?php
require_once '../../includes/connect_endpoint.php'; require_once '../../includes/connect_endpoint.php';
session_start();
if (isset($_SESSION['loggedin']) && $_SESSION['loggedin'] === true) { if (isset($_SESSION['loggedin']) && $_SESSION['loggedin'] === true) {
if ($_SERVER["REQUEST_METHOD"] === "DELETE") { if ($_SERVER["REQUEST_METHOD"] === "DELETE") {
$subscriptionId = $_GET["id"]; $subscriptionId = $_GET["id"];
$deleteQuery = "DELETE FROM subscriptions WHERE id = :subscriptionId"; $deleteQuery = "DELETE FROM subscriptions WHERE id = :subscriptionId AND user_id = :userId";
$deleteStmt = $db->prepare($deleteQuery); $deleteStmt = $db->prepare($deleteQuery);
$deleteStmt->bindParam(':subscriptionId', $subscriptionId, SQLITE3_INTEGER); $deleteStmt->bindParam(':subscriptionId', $subscriptionId, SQLITE3_INTEGER);
$deleteStmt->bindParam(':userId', $userId, SQLITE3_INTEGER);
if ($deleteStmt->execute()) { if ($deleteStmt->execute()) {
http_response_code(204); http_response_code(204);

View File

@ -1,12 +1,13 @@
<?php <?php
require_once '../../includes/connect_endpoint.php'; require_once '../../includes/connect_endpoint.php';
session_start();
if (isset($_SESSION['loggedin']) && $_SESSION['loggedin'] === true) { if (isset($_SESSION['loggedin']) && $_SESSION['loggedin'] === true) {
if (isset($_GET['id']) && $_GET['id'] != "") { if (isset($_GET['id']) && $_GET['id'] != "") {
$subscriptionId = intval($_GET['id']); $subscriptionId = intval($_GET['id']);
$query = "SELECT * FROM subscriptions WHERE id = :subscriptionId"; $query = "SELECT * FROM subscriptions WHERE id = :subscriptionId AND user_id = :userId";
$stmt = $db->prepare($query); $stmt = $db->prepare($query);
$stmt->bindParam(':subscriptionId', $subscriptionId, SQLITE3_INTEGER); $stmt->bindParam(':subscriptionId', $subscriptionId, SQLITE3_INTEGER);
$stmt->bindParam(':userId', $userId, SQLITE3_INTEGER);
$result = $stmt->execute(); $result = $stmt->execute();
$subscriptionData = array(); $subscriptionData = array();

View File

@ -1,6 +1,5 @@
<?php <?php
require_once '../../includes/connect_endpoint.php'; require_once '../../includes/connect_endpoint.php';
session_start();
require_once '../../includes/currency_formatter.php'; require_once '../../includes/currency_formatter.php';
require_once '../../includes/getdbkeys.php'; require_once '../../includes/getdbkeys.php';
@ -35,7 +34,7 @@
} }
$params = array(); $params = array();
$sql = "SELECT * FROM subscriptions WHERE 1=1"; $sql = "SELECT * FROM subscriptions WHERE user_id = :userId";
if (isset($_GET['category']) && $_GET['category'] != "") { if (isset($_GET['category']) && $_GET['category'] != "") {
$sql .= " AND category_id = :category"; $sql .= " AND category_id = :category";
@ -55,6 +54,7 @@
$sql .= " ORDER BY $sort $order, inactive ASC"; $sql .= " ORDER BY $sort $order, inactive ASC";
$stmt = $db->prepare($sql); $stmt = $db->prepare($sql);
$stmt->bindValue(':userId', $userId, SQLITE3_INTEGER);
foreach ($params as $key => $value) { foreach ($params as $key => $value) {
$stmt->bindValue($key, $value); $stmt->bindValue($key, $value);
@ -84,7 +84,7 @@
$print[$id]['currency_code'] = $currencies[$subscription['currency_id']]['code']; $print[$id]['currency_code'] = $currencies[$subscription['currency_id']]['code'];
$currencyId = $subscription['currency_id']; $currencyId = $subscription['currency_id'];
$print[$id]['next_payment'] = date('M d, Y', strtotime($subscription['next_payment'])); $print[$id]['next_payment'] = date('M d, Y', strtotime($subscription['next_payment']));
$paymentIconFolder = $paymentMethodId <= 31 ? 'images/uploads/icons/' : 'images/uploads/logos/'; $paymentIconFolder = (strpos($payment_methods[$paymentMethodId]['icon'], 'images/uploads/icons/') !== false) ? "" : "images/uploads/logos/";
$print[$id]['payment_method_icon'] = $paymentIconFolder . $payment_methods[$paymentMethodId]['icon']; $print[$id]['payment_method_icon'] = $paymentIconFolder . $payment_methods[$paymentMethodId]['icon'];
$print[$id]['payment_method_name'] = $payment_methods[$paymentMethodId]['name']; $print[$id]['payment_method_name'] = $payment_methods[$paymentMethodId]['name'];
$print[$id]['payment_method_id'] = $paymentMethodId; $print[$id]['payment_method_id'] = $paymentMethodId;

View File

@ -3,9 +3,6 @@
require_once '../../includes/connect_endpoint.php'; require_once '../../includes/connect_endpoint.php';
require_once '../../includes/inputvalidation.php'; require_once '../../includes/inputvalidation.php';
session_start();
if (!isset($_SESSION['loggedin']) || $_SESSION['loggedin'] !== true) { if (!isset($_SESSION['loggedin']) || $_SESSION['loggedin'] !== true) {
die(json_encode([ die(json_encode([
"success" => false, "success" => false,
@ -28,8 +25,6 @@ if ($_SERVER["REQUEST_METHOD"] === "POST") {
} else { } else {
$budget = $data["budget"]; $budget = $data["budget"];
$userId = $_SESSION['userId'];
$sql = "UPDATE user SET budget = :budget WHERE id = :userId"; $sql = "UPDATE user SET budget = :budget WHERE id = :userId";
$stmt = $db->prepare($sql); $stmt = $db->prepare($sql);
$stmt->bindValue(':budget', $budget, SQLITE3_TEXT); $stmt->bindValue(':budget', $budget, SQLITE3_TEXT);

View File

@ -1,8 +1,6 @@
<?php <?php
require_once '../../includes/connect_endpoint.php'; require_once '../../includes/connect_endpoint.php';
session_start();
if (!isset($_SESSION['loggedin']) || $_SESSION['loggedin'] !== true) { if (!isset($_SESSION['loggedin']) || $_SESSION['loggedin'] !== true) {
die(json_encode([ die(json_encode([
@ -14,8 +12,9 @@
$input = json_decode(file_get_contents('php://input'), true); $input = json_decode(file_get_contents('php://input'), true);
if (isset($input['avatar'])) { if (isset($input['avatar'])) {
$avatar = "images/uploads/logos/avatars/".$input['avatar']; $avatar = "images/uploads/logos/avatars/".$input['avatar'];
$sql = "SELECT avatar FROM user"; $sql = "SELECT avatar FROM user WHERE id = :userId";
$stmt = $db->prepare($sql); $stmt = $db->prepare($sql);
$stmt->bindValue(':userId', $userId, SQLITE3_INTEGER);
$result = $stmt->execute(); $result = $stmt->execute();
$userAvatar = $result->fetchArray(SQLITE3_ASSOC)['avatar']; $userAvatar = $result->fetchArray(SQLITE3_ASSOC)['avatar'];

View File

@ -1,12 +1,12 @@
<?php <?php
require_once '../../includes/connect_endpoint.php'; require_once '../../includes/connect_endpoint.php';
require_once '../../includes/inputvalidation.php'; require_once '../../includes/inputvalidation.php';
session_start();
function update_exchange_rate($db) { function update_exchange_rate($db) {
$query = "SELECT api_key, provider FROM fixer"; $query = "SELECT api_key, provider FROM fixer WHERE user_id = :userId";
$result = $db->query($query); $stmt = $db->prepare($query);
$stmt->bindParam(':userId', $userId, SQLITE3_INTEGER);
$result = $stmt->execute();
if ($result) { if ($result) {
$row = $result->fetchArray(SQLITE3_ASSOC); $row = $result->fetchArray(SQLITE3_ASSOC);
@ -23,8 +23,9 @@
} }
$codes = rtrim($codes, ','); $codes = rtrim($codes, ',');
$query = "SELECT u.main_currency, c.code FROM user u LEFT JOIN currencies c ON u.main_currency = c.id WHERE u.id = 1"; $query = "SELECT u.main_currency, c.code FROM user u LEFT JOIN currencies c ON u.main_currency = c.id WHERE u.id = :userId";
$stmt = $db->prepare($query); $stmt = $db->prepare($query);
$stmt->bindParam(':userId', $userId, SQLITE3_INTEGER);
$result = $stmt->execute(); $result = $stmt->execute();
$row = $result->fetchArray(SQLITE3_ASSOC); $row = $result->fetchArray(SQLITE3_ASSOC);
$mainCurrencyCode = $row['code']; $mainCurrencyCode = $row['code'];
@ -55,23 +56,32 @@
} else { } else {
$exchangeRate = $rate / $mainCurrencyToEUR; $exchangeRate = $rate / $mainCurrencyToEUR;
} }
$updateQuery = "UPDATE currencies SET rate = :rate WHERE code = :code"; $updateQuery = "UPDATE currencies SET rate = :rate WHERE code = :code AND user_id = :userId";
$updateStmt = $db->prepare($updateQuery); $updateStmt = $db->prepare($updateQuery);
$updateStmt->bindParam(':rate', $exchangeRate, SQLITE3_TEXT); $updateStmt->bindParam(':rate', $exchangeRate, SQLITE3_TEXT);
$updateStmt->bindParam(':code', $currencyCode, SQLITE3_TEXT); $updateStmt->bindParam(':code', $currencyCode, SQLITE3_TEXT);
$updateStmt->bindParam(':userId', $userId, SQLITE3_INTEGER);
$updateResult = $updateStmt->execute(); $updateResult = $updateStmt->execute();
} }
$currentDate = new DateTime(); $currentDate = new DateTime();
$formattedDate = $currentDate->format('Y-m-d'); $formattedDate = $currentDate->format('Y-m-d');
$deleteQuery = "DELETE FROM last_exchange_update"; $query = "SELECT * FROM last_exchange_update WHERE user_id = :userId";
$deleteStmt = $db->prepare($deleteQuery); $stmt = $db->prepare($query);
$deleteResult = $deleteStmt->execute(); $stmt->bindParam(':userId', $userId, SQLITE3_INTEGER);
$result = $stmt->execute();
$row = $result->fetchArray(SQLITE3_ASSOC);
if ($row) {
$query = "UPDATE last_exchange_update SET date = :formattedDate WHERE user_id = :userId";
} else {
$query = "INSERT INTO last_exchange_update (date, user_id) VALUES (:formattedDate, :userId)";
}
$query = "INSERT INTO last_exchange_update (date) VALUES (:formattedDate)";
$stmt = $db->prepare($query); $stmt = $db->prepare($query);
$stmt->bindParam(':formattedDate', $formattedDate, SQLITE3_TEXT); $stmt->bindParam(':formattedDate', $formattedDate, SQLITE3_TEXT);
$result = $stmt->execute(); $stmt->bindParam(':userId', $userId, SQLITE3_INTEGER);
$resutl = $stmt->execute();
$db->close(); $db->close();
} }
@ -79,8 +89,9 @@
} }
} }
$query = "SELECT main_currency FROM user WHERE id = 1"; $query = "SELECT main_currency FROM user WHERE id = :userId";
$stmt = $db->prepare($query); $stmt = $db->prepare($query);
$stmt->bindParam(':userId', $userId, SQLITE3_INTEGER);
$result = $stmt->execute(); $result = $stmt->execute();
$row = $result->fetchArray(SQLITE3_ASSOC); $row = $result->fetchArray(SQLITE3_ASSOC);
$mainCurrencyId = $row['main_currency']; $mainCurrencyId = $row['main_currency'];
@ -174,10 +185,39 @@
return ""; return "";
} }
if (isset($_SESSION['username']) && isset($_POST['username']) && isset($_POST['email']) && isset($_POST['avatar'])) { if (isset($_SESSION['username']) && isset($_POST['email']) && $_POST['email'] !== ""
$oldUsername = $_SESSION['username']; && isset($_POST['avatar']) && $_POST['avatar'] !== ""
$username = validate($_POST['username']); && isset($_POST['main_currency']) && $_POST['main_currency'] !== ""
&& isset($_POST['language']) && $_POST['language'] !== "") {
$email = validate($_POST['email']); $email = validate($_POST['email']);
$query = "SELECT email FROM user WHERE id = :user_id";
$stmt = $db->prepare($query);
$stmt->bindValue(':user_id', $userId, SQLITE3_TEXT);
$result = $stmt->execute();
$user = $result->fetchArray(SQLITE3_ASSOC);
$oldEmail = $user['email'];
if ($oldEmail != $email) {
$query = "SELECT email FROM user WHERE email = :email AND id != :userId";
$stmt = $db->prepare($query);
$stmt->bindValue(':email', $email, SQLITE3_TEXT);
$stmt->bindValue(':userId', $userId, SQLITE3_INTEGER);
$result = $stmt->execute();
$otherUser = $result->fetchArray(SQLITE3_ASSOC);
if ($otherUser) {
$response = [
"success" => false,
"errorMessage" => translate('email_exists', $i18n)
];
echo json_encode($response);
exit();
}
}
$avatar = $_POST['avatar']; $avatar = $_POST['avatar'];
$main_currency = $_POST['main_currency']; $main_currency = $_POST['main_currency'];
$language = $_POST['language']; $language = $_POST['language'];
@ -221,17 +261,17 @@
} }
if (isset($_POST['password']) && $_POST['password'] != "") { if (isset($_POST['password']) && $_POST['password'] != "") {
$sql = "UPDATE user SET avatar = :avatar, username = :username, email = :email, password = :password, main_currency = :main_currency, language = :language WHERE id = 1"; $sql = "UPDATE user SET avatar = :avatar, email = :email, password = :password, main_currency = :main_currency, language = :language WHERE id = :userId";
} else { } else {
$sql = "UPDATE user SET avatar = :avatar, username = :username, email = :email, main_currency = :main_currency, language = :language WHERE id = 1"; $sql = "UPDATE user SET avatar = :avatar, email = :email, main_currency = :main_currency, language = :language WHERE id = :userId";
} }
$stmt = $db->prepare($sql); $stmt = $db->prepare($sql);
$stmt->bindParam(':avatar', $avatar, SQLITE3_TEXT); $stmt->bindParam(':avatar', $avatar, SQLITE3_TEXT);
$stmt->bindParam(':username', $username, SQLITE3_TEXT);
$stmt->bindParam(':email', $email, SQLITE3_TEXT); $stmt->bindParam(':email', $email, SQLITE3_TEXT);
$stmt->bindParam(':main_currency', $main_currency, SQLITE3_INTEGER); $stmt->bindParam(':main_currency', $main_currency, SQLITE3_INTEGER);
$stmt->bindParam(':language', $language, SQLITE3_TEXT); $stmt->bindParam(':language', $language, SQLITE3_TEXT);
$stmt->bindParam(':userId', $userId, SQLITE3_INTEGER);
if (isset($_POST['password']) && $_POST['password'] != "") { if (isset($_POST['password']) && $_POST['password'] != "") {
$hashedPassword = password_hash($password, PASSWORD_DEFAULT); $hashedPassword = password_hash($password, PASSWORD_DEFAULT);
@ -246,14 +286,6 @@
$root = str_replace('/endpoints/user', '', dirname($_SERVER['PHP_SELF'])); $root = str_replace('/endpoints/user', '', dirname($_SERVER['PHP_SELF']));
$root = $root == '' ? '/' : $root; $root = $root == '' ? '/' : $root;
setcookie('language', $language, $cookieExpire, $root); setcookie('language', $language, $cookieExpire, $root);
if ($username != $oldUsername) {
$_SESSION['username'] = $username;
if (isset($_COOKIE['wallos_login'])) {
$cookie = explode('|', $_COOKIE['wallos_login'], 2) ;
$token = $cookie[1];
$cookieValue = $username . "|" . $token . "|" . $main_currency;
}
}
$_SESSION['avatar'] = $avatar; $_SESSION['avatar'] = $avatar;
$_SESSION['main_currency'] = $main_currency; $_SESSION['main_currency'] = $main_currency;

View File

@ -8,6 +8,7 @@
$stmt->bindValue(':username', $username, SQLITE3_TEXT); $stmt->bindValue(':username', $username, SQLITE3_TEXT);
$result = $stmt->execute(); $result = $stmt->execute();
$userData = $result->fetchArray(SQLITE3_ASSOC); $userData = $result->fetchArray(SQLITE3_ASSOC);
$userId = $userData['id'];
if ($userData === false) { if ($userData === false) {
header('Location: logout.php'); header('Location: logout.php');
@ -45,10 +46,10 @@
} }
$userId = $userData['id']; $userId = $userData['id'];
$main_currency = $userData['main_currency']; $main_currency = $userData['main_currency'];
$sql = "SELECT * FROM login_tokens WHERE user_id = ? AND token = ?"; $sql = "SELECT * FROM login_tokens WHERE user_id = :userId AND token = :token";
$stmt = $db->prepare($sql); $stmt = $db->prepare($sql);
$stmt->bindParam(1, $userId, SQLITE3_TEXT); $stmt->bindParam(':userId', $userId, SQLITE3_TEXT);
$stmt->bindParam(2, $token, SQLITE3_TEXT); $stmt->bindParam(':token', $token, SQLITE3_TEXT);
$result = $stmt->execute(); $result = $stmt->execute();
$row = $result->fetchArray(SQLITE3_ASSOC); $row = $result->fetchArray(SQLITE3_ASSOC);

View File

@ -12,4 +12,12 @@ require_once 'i18n/languages.php';
require_once 'i18n/getlang.php'; require_once 'i18n/getlang.php';
require_once 'i18n/' . $lang . '.php'; require_once 'i18n/' . $lang . '.php';
session_start();
if (isset($_SESSION['loggedin']) && $_SESSION['loggedin'] === true) {
$userId = $_SESSION['userId'];
} else {
$userId = 0;
}
?> ?>

View File

@ -1,24 +1,29 @@
<?php <?php
$currencies = array(); $currencies = array();
$query = "SELECT * FROM currencies"; $query = "SELECT * FROM currencies WHERE user_id = :userId";
$result = $db->query($query); $stmt = $db->prepare($query);
$stmt->bindValue(':userId', $userId, SQLITE3_INTEGER);
$result = $stmt->execute();
while ($row = $result->fetchArray(SQLITE3_ASSOC)) { while ($row = $result->fetchArray(SQLITE3_ASSOC)) {
$currencyId = $row['id']; $currencyId = $row['id'];
$currencies[$currencyId] = $row; $currencies[$currencyId] = $row;
} }
$members = array(); $members = array();
$query = "SELECT * FROM household"; $query = "SELECT * FROM household WHERE user_id = :userId";
$result = $db->query($query); $stmt = $db->prepare($query);
$stmt->bindValue(':userId', $userId, SQLITE3_INTEGER);
$result = $stmt->execute();
while ($row = $result->fetchArray(SQLITE3_ASSOC)) { while ($row = $result->fetchArray(SQLITE3_ASSOC)) {
$memberId = $row['id']; $memberId = $row['id'];
$members[$memberId] = $row; $members[$memberId] = $row;
} }
$payment_methods = array(); $payment_methods = array();
$query = $db->prepare("SELECT * FROM payment_methods WHERE enabled=:enabled"); $query = $db->prepare("SELECT * FROM payment_methods WHERE enabled=:enabled AND user_id = :userId");
$query->bindValue(':enabled', 1, SQLITE3_INTEGER); $query->bindValue(':enabled', 1, SQLITE3_INTEGER);
$query->bindValue(':userId', $userId, SQLITE3_INTEGER);
$result = $query->execute(); $result = $query->execute();
while ($row = $result->fetchArray(SQLITE3_ASSOC)) { while ($row = $result->fetchArray(SQLITE3_ASSOC)) {
$payment_methodId = $row['id']; $payment_methodId = $row['id'];
@ -26,8 +31,10 @@
} }
$categories = array(); $categories = array();
$query = "SELECT * FROM categories ORDER BY `order` ASC"; $query = "SELECT * FROM categories WHERE user_id = :userId ORDER BY `order` ASC";
$result = $db->query($query); $stmt = $db->prepare($query);
$stmt->bindValue(':userId', $userId, SQLITE3_INTEGER);
$result = $stmt->execute();
while ($row = $result->fetchArray(SQLITE3_ASSOC)) { while ($row = $result->fetchArray(SQLITE3_ASSOC)) {
$categoryId = $row['id']; $categoryId = $row['id'];
$categories[$categoryId] = $row; $categories[$categoryId] = $row;

View File

@ -1,7 +1,10 @@
<?php <?php
$query = "SELECT * FROM settings"; $query = "SELECT * FROM settings WHERE user_id = :userId";
$result = $db->query($query); $stmt = $db->prepare($query);
$stmt->bindValue(':userId', $userId, SQLITE3_INTEGER);
$result = $stmt->execute();
$settings = $result->fetchArray(SQLITE3_ASSOC); $settings = $result->fetchArray(SQLITE3_ASSOC);
if ($settings) { if ($settings) {
$cookieExpire = time() + (30 * 24 * 60 * 60); $cookieExpire = time() + (30 * 24 * 60 * 60);
@ -14,8 +17,10 @@ if ($settings) {
$settings['hideDisabledSubscriptions'] = $settings['hide_disabled'] ? 'true': 'false'; $settings['hideDisabledSubscriptions'] = $settings['hide_disabled'] ? 'true': 'false';
} }
$query = "SELECT * FROM custom_colors"; $query = "SELECT * FROM custom_colors WHERE user_id = :userId";
$result = $db->query($query); $stmt = $db->prepare($query);
$stmt->bindValue(':userId', $userId, SQLITE3_INTEGER);
$result = $stmt->execute();
$customColors = $result->fetchArray(SQLITE3_ASSOC); $customColors = $result->fetchArray(SQLITE3_ASSOC);
if ($customColors) { if ($customColors) {

View File

@ -10,6 +10,8 @@ $i18n = [
"main_currency" => "Hauptwährung", "main_currency" => "Hauptwährung",
"language" => "Sprache", "language" => "Sprache",
"passwords_dont_match" => "Die Passwörter stimmen nicht überein", "passwords_dont_match" => "Die Passwörter stimmen nicht überein",
"username_exists" => "Benutzername existiert bereits",
"email_exists" => "E-Mail existiert bereits",
"registration_failed" => "Registrierung fehlgeschlagen, bitte erneut versuchen.", "registration_failed" => "Registrierung fehlgeschlagen, bitte erneut versuchen.",
"register" => "Registrieren", "register" => "Registrieren",
"restore_database" => "Datenbank wiederherstellen", "restore_database" => "Datenbank wiederherstellen",
@ -18,6 +20,13 @@ $i18n = [
'stay_logged_in' => "Angemeldet bleiben (30 Tage)", 'stay_logged_in' => "Angemeldet bleiben (30 Tage)",
'login' => "Login", 'login' => "Login",
'login_failed' => "Loginangaben sind nicht korrekt", 'login_failed' => "Loginangaben sind nicht korrekt",
'registration_successful' => "Registrierung erfolgreich",
'user_email_waiting_verification' => "Ihre E-Mail muss noch verifiziert werden. Bitte überprüfen Sie Ihre E-Mail.",
// Password Reset Page
'forgot_password' => "Passwort vergessen?",
'reset_password' => "Passwort zurücksetzen",
'reset_sent_check_email' => "Passwort zurücksetzen E-Mail wurde gesendet. Bitte überprüfen Sie Ihr Postfach.",
'password_reset_successful' => "Passwort erfolgreich zurückgesetzt",
// Header // Header
'subscriptions' => "Abonnements", 'subscriptions' => "Abonnements",
'stats' => "Statistiken", 'stats' => "Statistiken",
@ -255,6 +264,24 @@ $i18n = [
// User // User
"error_updating_user_data" => "Benutzerangaben konnten nicht aktualisiert werden.", "error_updating_user_data" => "Benutzerangaben konnten nicht aktualisiert werden.",
"user_details_saved" => "Benutzerangaben gespeichert", "user_details_saved" => "Benutzerangaben gespeichert",
// Admin Page
"registrations" => "Registrierungen",
"enable_user_registrations" => "Benutzerregistrierungen aktivieren",
"maximum_number_users" => "Maximale Anzahl an Benutzern",
"require_email_verification" => "E-Mail Verifizierung erforderlich",
"configure_smtp_settings_to_enable" => "Konfiguriere SMTP Einstellungen um dies zu aktivieren",
"server_url" => "Server URL",
"server_url_info" => "Wird für die E-Mail-Überprüfung und die Passwortwiederherstellung verwendet. Muss eine gültige öffentliche URL sein.",
"server_url_password_reset" => "Wenn diese Option gesetzt ist, wird auch die Funktion zum Zurücksetzen des Passworts aktiviert.",
"max_users_info" => "0 für unbegrenzte Anzahl an Benutzern",
"user_management" => "Benutzerverwaltung",
"delete_user" => "Benutzer löschen",
"delete_user_info" => "Durch das Löschen eines Benutzers werden auch alle seine Abonnements und Einstellungen gelöscht.",
"smtp_settings" => "SMTP Einstellungen",
"smtp_usage_info" => "Wird für die Passwortwiederherstellung und andere System-E-Mails verwendet",
// Email Verification
"email_verified" => "E-Mail verifiziert",
"email_verification_failed" => "E-Mail konnte nicht verifiziert werden",
]; ];

View File

@ -10,6 +10,8 @@ $i18n = [
"main_currency" => "Κύριο νόμισμα", "main_currency" => "Κύριο νόμισμα",
"language" => "Γλώσσα", "language" => "Γλώσσα",
"passwords_dont_match" => "Οι κωδικοί πρόσβασης δεν ταιριάζουν", "passwords_dont_match" => "Οι κωδικοί πρόσβασης δεν ταιριάζουν",
"username_exists" => "Το όνομα χρήστη υπάρχει ήδη",
"email_exists" => "Το email υπάρχει ήδη",
"registration_failed" => "Η εγγραφή απέτυχε, παρακαλώ προσπάθησε ξανά.", "registration_failed" => "Η εγγραφή απέτυχε, παρακαλώ προσπάθησε ξανά.",
"register" => "Εγγραφή", "register" => "Εγγραφή",
"restore_database" => "Επαναφορά βάσης δεδομένων", "restore_database" => "Επαναφορά βάσης δεδομένων",
@ -18,6 +20,13 @@ $i18n = [
'stay_logged_in' => "Μείνε συνδεδεμένος (30 ημέρες)", 'stay_logged_in' => "Μείνε συνδεδεμένος (30 ημέρες)",
'login' => "Σύνδεση", 'login' => "Σύνδεση",
'login_failed' => "Τα στοιχεία σύνδεσης είναι λανθασμένα", 'login_failed' => "Τα στοιχεία σύνδεσης είναι λανθασμένα",
'registration_successful' => "Επιτυχής Εγγραφή",
'user_email_waiting_verification' => "Το email σας πρέπει να επαληθευτεί. Παρακαλούμε ελέγξτε το email σας",
// Password Reset Page
'forgot_password' => "Ξέχασες τον κωδικό σου; Κάνε κλικ",
'reset_password' => "Επαναφορά κωδικού πρόσβασης",
'reset_sent_check_email' => "Ένα email με οδηγίες για την επαναφορά του κωδικού πρόσβασης σας έχει σταλεί. Παρακαλώ ελέγξτε το email σας.",
'password_reset_successful' => "Επιτυχής επαναφορά κωδικού πρόσβασης",
// Header // Header
'subscriptions' => "Συνδρομές", 'subscriptions' => "Συνδρομές",
'stats' => "Στατιστικές", 'stats' => "Στατιστικές",
@ -255,6 +264,24 @@ $i18n = [
// User // User
"error_updating_user_data" => "Σφάλμα ενημέρωσης δεδομένων χρήστη.", "error_updating_user_data" => "Σφάλμα ενημέρωσης δεδομένων χρήστη.",
"user_details_saved" => "Αποθήκευση στοιχείων χρήστη", "user_details_saved" => "Αποθήκευση στοιχείων χρήστη",
// Admin Page
"registrations" => "Εγγραφές",
"enable_user_registrations" => "Ενεργοποίηση εγγραφών χρηστών",
"maximum_number_users" => "Μέγιστος αριθμός χρηστών",
"require_email_verification" => "Απαιτείται επιβεβαίωση email",
"configure_smtp_settings_to_enable" => "Διαμόρφωσε τις ρυθμίσεις SMTP για να ενεργοποιήσεις αυτή την επιλογή",
"server_url" => "Διεύθυνση URL διακομιστή",
"server_url_info" => "Χρησιμοποιείται για επαλήθευση email και ανάκτηση κωδικού πρόσβασης. Πρέπει να είναι ένα έγκυρο δημόσιο URL.",
"server_url_password_reset" => "Εάν οριστεί, θα ενεργοποιήσει επίσης τη λειτουργία επαναφοράς κωδικού πρόσβασης.",
"max_users_info" => "Ο μέγιστος αριθμός χρηστών που μπορούν να εγγραφούν. Αν η τιμή είναι 0, δεν υπάρχει όριο.",
"user_management" => "Διαχείριση χρηστών",
"delete_user" => "Διαγραφή χρήστη",
"delete_user_info" => "Η διαγραφή ενός χρήστη θα διαγράψει επίσης όλες τις συνδρομές και τις ρυθμίσεις του.",
"smtp_settings" => "SMTP ρυθμίσεις",
"smtp_usage_info" => "Θα χρησιμοποιηθεί για ανάκτηση κωδικού πρόσβασης και άλλα μηνύματα ηλεκτρονικού ταχυδρομείου συστήματος.",
// Email Verification
"email_verified" => "Το email επιβεβαιώθηκε",
"email_verification_failed" => "Η επαλήθευση email απέτυχε",
]; ];

View File

@ -10,6 +10,8 @@ $i18n = [
"main_currency" => "Main Currency", "main_currency" => "Main Currency",
"language" => "Language", "language" => "Language",
"passwords_dont_match" => "Passwords do not match", "passwords_dont_match" => "Passwords do not match",
"username_exists" => "Username already exists",
"email_exists" => "Email already exists",
"registration_failed" => "Registration failed, please try again.", "registration_failed" => "Registration failed, please try again.",
"register" => "Register", "register" => "Register",
"restore_database" => "Restore Database", "restore_database" => "Restore Database",
@ -18,6 +20,13 @@ $i18n = [
'stay_logged_in' => "Stay logged in (30 days)", 'stay_logged_in' => "Stay logged in (30 days)",
'login' => "Login", 'login' => "Login",
'login_failed' => "Login details are incorrect", 'login_failed' => "Login details are incorrect",
'registration_successful' => "Registration successful",
'user_email_waiting_verification' => "Your email needs to be verified. Please check your email.",
// Password Reset Page
'forgot_password' => "Forgot Password",
'reset_password' => "Reset Password",
'reset_sent_check_email' => "Reset email sent. Please check your email.",
'password_reset_successful' => "Password reset successful",
// Header // Header
'subscriptions' => "Subscriptions", 'subscriptions' => "Subscriptions",
'stats' => "Statistics", 'stats' => "Statistics",
@ -255,6 +264,25 @@ $i18n = [
// User // User
"error_updating_user_data" => "Error updating user data.", "error_updating_user_data" => "Error updating user data.",
"user_details_saved" => "User details saved", "user_details_saved" => "User details saved",
// Admin Page
"registrations" => "Registrations",
"enable_user_registrations" => "Enable user registrations",
"maximum_number_users" => "Maximum number of users",
"require_email_verification" => "Require email verification",
"configure_smtp_settings_to_enable" => "Configure SMTP settings to enable",
"server_url" => "Server URL",
"server_url_info" => "Used for email verification and password recovery. Must be a valid public URL.",
"server_url_password_reset" => "If set will also enable password reset functionality.",
"max_users_info" => "0 means unlimited",
"user_management" => "User Management",
"delete_user" => "Delete User",
"delete_user_info" => "Deleting a user will also delete all their subscriptions and settings.",
"smtp_settings" => "SMTP Settings",
"smtp_usage_info" => "Will be used for password recovery and other system emails.",
// Email Verification
"email_verified" => "Email verified successfully",
"email_verification_failed" => "Email verification failed",
]; ];

View File

@ -10,6 +10,8 @@ $i18n = [
"main_currency" => "Moneda Principal", "main_currency" => "Moneda Principal",
"language" => "Idioma", "language" => "Idioma",
"passwords_dont_match" => "Las contraseñas no coinciden", "passwords_dont_match" => "Las contraseñas no coinciden",
"username_exists" => "El nombre de usuario ya existe",
"email_exists" => "El correo electrónico ya está registrado",
"registration_failed" => "Error en el registro, por favor inténtalo de nuevo.", "registration_failed" => "Error en el registro, por favor inténtalo de nuevo.",
"register" => "Registrar", "register" => "Registrar",
"restore_database" => "Restaurar Base de Datos", "restore_database" => "Restaurar Base de Datos",
@ -18,6 +20,13 @@ $i18n = [
'stay_logged_in' => "Mantener sesión iniciada (30 días)", 'stay_logged_in' => "Mantener sesión iniciada (30 días)",
'login' => "Iniciar Sesión", 'login' => "Iniciar Sesión",
'login_failed' => "Los detalles de inicio de sesión son incorrectos", 'login_failed' => "Los detalles de inicio de sesión son incorrectos",
'registration_successful' => "Registro efectuado con éxito",
'user_email_waiting_verification' => "Tu correo electrónico necesita ser verificado. Por favor, compruebe su correo electrónico",
// Password Reset Page
'forgot_password' => "¿Olvidaste tu contraseña?",
'reset_password' => "Restablecer Contraseña",
'reset_sent_check_email' => "Se ha enviado un correo electrónico con instrucciones para restablecer la contraseña. Por favor, compruebe su correo electrónico.",
'password_reset_successful' => "Contraseña restablecida con éxito",
// Header // Header
'subscriptions' => "Suscripciones", 'subscriptions' => "Suscripciones",
'stats' => "Estadísticas", 'stats' => "Estadísticas",
@ -255,6 +264,24 @@ $i18n = [
// User // User
"error_updating_user_data" => "Error al actualizar los datos del usuario.", "error_updating_user_data" => "Error al actualizar los datos del usuario.",
"user_details_saved" => "Detalles del usuario guardados", "user_details_saved" => "Detalles del usuario guardados",
// Admin Page
"registrations" => "Registro de Usuarios",
"enable_user_registrations" => "Habilitar registro de usuarios",
"maximum_number_users" => "Número máximo de usuarios",
"require_email_verification" => "Requerir verificación de correo electrónico",
"configure_smtp_settings_to_enable" => "Configura la configuración SMTP para habilitar",
"server_url" => "URL del Servidor",
"server_url_info" => "Se utiliza para verificar el correo electrónico y recuperar la contraseña. Debe ser una URL pública válida.",
"server_url_password_reset" => "Si se configura, también se habilitará la función de restablecimiento de contraseña.",
"max_users_info" => "0 para ilimitado",
"user_management" => "Gestión de Usuarios",
"delete_user" => "Eliminar Usuario",
"delete_user_info" => "Al eliminar un usuario, también se eliminarán todas sus suscripciones y configuraciones.",
"smtp_settings" => "Configuración SMTP",
"smtp_usage_info" => "Se utilizará para recuperar contraseñas y otros correos electrónicos del sistema.",
// Email Verification
"email_verified" => "Correo electrónico verificado",
"email_verification_failed" => "Error al verificar el correo electrónico",
]; ];

View File

@ -10,6 +10,8 @@ $i18n = [
"main_currency" => "Devise principale", "main_currency" => "Devise principale",
"language" => "Langue", "language" => "Langue",
"passwords_dont_match" => "Les mots de passe ne correspondent pas", "passwords_dont_match" => "Les mots de passe ne correspondent pas",
"username_exists" => "Le nom d'utilisateur existe déjà",
"email_exists" => "L'adresse courriel existe déjà",
"registration_failed" => "L'inscription a échoué, veuillez réessayer.", "registration_failed" => "L'inscription a échoué, veuillez réessayer.",
"register" => "S'inscrire", "register" => "S'inscrire",
"restore_database" => "Restaurer la base de données", "restore_database" => "Restaurer la base de données",
@ -18,6 +20,13 @@ $i18n = [
'stay_logged_in' => "Rester connecté (30 jours)", 'stay_logged_in' => "Rester connecté (30 jours)",
'login' => "Se connecter", 'login' => "Se connecter",
'login_failed' => "Les détails de connexion sont incorrects", 'login_failed' => "Les détails de connexion sont incorrects",
'registration_successful' => "Inscription réussie",
'user_email_waiting_verification' => "Votre email doit être vérifié. Veuillez vérifier votre email",
// Password Reset Page
'forgot_password' => "Mot de passe oublié",
'reset_password' => "Réinitialiser le mot de passe",
'reset_sent_check_email' => "Un courriel a été envoyé à l'adresse fournie. Vérifiez votre boîte de réception.",
'password_reset_successful' => "Réinitialisation du mot de passe réussie",
// En-tête // En-tête
'subscriptions' => "Abonnements", 'subscriptions' => "Abonnements",
'stats' => "Statistiques", 'stats' => "Statistiques",
@ -255,6 +264,24 @@ $i18n = [
// Utilisateur // Utilisateur
"error_updating_user_data" => "Erreur lors de la mise à jour des données utilisateur.", "error_updating_user_data" => "Erreur lors de la mise à jour des données utilisateur.",
"user_details_saved" => "Détails de l'utilisateur enregistrés", "user_details_saved" => "Détails de l'utilisateur enregistrés",
// Admin Page
"registrations" => "Inscriptions",
"enable_user_registrations" => "Activer les inscriptions d'utilisateurs",
"maximum_number_users" => "Nombre maximum d'utilisateurs",
"require_email_verification" => "Exiger la vérification de l'adresse courriel",
"configure_smtp_settings_to_enable" => "Configurer les paramètres SMTP pour activer",
"server_url" => "URL du serveur",
"server_url_info" => "Utilisé pour la vérification du courrier électronique et la récupération du mot de passe. Il doit s'agir d'une URL publique valide.",
"server_url_password_reset" => "Si cette option est activée, la fonction de réinitialisation du mot de passe sera également activée.",
"max_users_info" => "0 signifie un nombre illimité d'utilisateurs",
"user_management" => "Gestion des utilisateurs",
"delete_user" => "Supprimer l'utilisateur",
"delete_user_info" => "La suppression d'un utilisateur supprimera également tous ses abonnements et paramètres.",
"smtp_settings" => "Paramètres SMTP",
"smtp_usage_info" => "Sera utilisé pour la récupération du mot de passe et d'autres e-mails système.",
// Email Verification
"email_verified" => "Votre adresse courriel a été vérifiée avec succès",
"email_verification_failed" => "La vérification de l'adresse courriel a échoué",
]; ];

View File

@ -10,6 +10,8 @@ $i18n = [
'main_currency' => 'Valuta principale', 'main_currency' => 'Valuta principale',
'language' => 'Lingua', 'language' => 'Lingua',
'passwords_dont_match' => 'Le password non corrispondono', 'passwords_dont_match' => 'Le password non corrispondono',
'username_exists' => 'Il nome utente esiste già',
'email_exists' => 'L\'indirizzo email esiste già',
'registration_failed' => 'Registrazione fallita, riprova.', 'registration_failed' => 'Registrazione fallita, riprova.',
'register' => 'Registrati', 'register' => 'Registrati',
"restore_database" => 'Ripristina database', "restore_database" => 'Ripristina database',
@ -19,6 +21,14 @@ $i18n = [
'stay_logged_in' => 'Rimani connesso (30 giorni)', 'stay_logged_in' => 'Rimani connesso (30 giorni)',
'login' => 'Accedi', 'login' => 'Accedi',
'login_failed' => 'Le credenziali non sono corrette', 'login_failed' => 'Le credenziali non sono corrette',
'registration_successful' => "L'account è stato creato con successo",
'user_email_waiting_verification' => "L'e-mail deve essere verificata. Controlla la tua email",
// Password Reset Page
'forgot_password' => "Hai dimenticato la password?",
'reset_password' => "Reimposta password",
'reset_sent_check_email' => "Un'email è stata inviata. Controlla la tua casella di posta",
'password_reset_successful' => "La password è stata reimpostata con successo",
// Header // Header
'subscriptions' => 'Abbonamenti', 'subscriptions' => 'Abbonamenti',
@ -269,6 +279,26 @@ $i18n = [
// User // User
"error_updating_user_data" => "Errore nell'aggiornamento dei dati utente", "error_updating_user_data" => "Errore nell'aggiornamento dei dati utente",
"user_details_saved" => "Dettagli utente salvati", "user_details_saved" => "Dettagli utente salvati",
// Admin Page
"registrations" => "Registrazioni",
"enable_user_registrations" => "Abilita le registrazioni utente",
"maximum_number_users" => "Numero massimo di utenti",
"require_email_verification" => "Richiedi la verifica dell'e-mail",
"configure_smtp_settings_to_enable" => "Configura le impostazioni SMTP per abilitare",
"server_url" => "URL del server",
"server_url_info" => "Utilizzato per la verifica dell'e-mail e il recupero della password. Deve essere un URL pubblico valido.",
"server_url_password_reset" => "Se impostato, abilita anche la funzionalità di reimpostazione della password.",
"max_users_info" => "Impostare a 0 per un numero illimitato di utenti",
"user_management" => "Gestione utenti",
"delete_user" => "Elimina utente",
"delete_user_info" => "L'eliminazione di un utente eliminerà anche tutte le sue iscrizioni e impostazioni.",
"smtp_settings" => "Impostazioni SMTP",
"smtp_usage_info" => "Verrà utilizzato per il recupero della password e altre e-mail di sistema.",
// Email Verification
"email_verified" => "L'indirizzo email è stato verificato con successo",
"email_verification_failed" => "La verifica dell'email è fallita",
]; ];
?> ?>

View File

@ -10,6 +10,8 @@ $i18n = [
"main_currency" => "主要通貨", "main_currency" => "主要通貨",
"language" => "言語", "language" => "言語",
"passwords_dont_match" => "パスワードが違います", "passwords_dont_match" => "パスワードが違います",
"username_exists" => "ユーザー名が既に存在します",
"email_exists" => "メールアドレスが既に存在します",
"registration_failed" => "登録に失敗しました。もう一度お試しください。", "registration_failed" => "登録に失敗しました。もう一度お試しください。",
"register" => "登録する", "register" => "登録する",
"restore_database" => "データベースをリストア", "restore_database" => "データベースをリストア",
@ -18,6 +20,13 @@ $i18n = [
'stay_logged_in' => "ログインしたままにする (30日)", 'stay_logged_in' => "ログインしたままにする (30日)",
'login' => "ログイン", 'login' => "ログイン",
'login_failed' => "ログイン情報が間違っています", 'login_failed' => "ログイン情報が間違っています",
'registration_successful' => "登録に成功",
'user_email_waiting_verification' => "Eメールの確認が必要です。メールを確認してください。",
// Password Reset Page
'forgot_password' => "パスワードを忘れた場合",
'reset_password' => "パスワードをリセット",
'reset_sent_check_email' => "パスワードリセットリンクが送信されました。メールを確認してください。",
'password_reset_successful' => "パスワードリセットに成功",
// Header // Header
'subscriptions' => "定期購入", 'subscriptions' => "定期購入",
'stats' => "統計", 'stats' => "統計",
@ -255,6 +264,24 @@ $i18n = [
// User // User
"error_updating_user_data" => "ユーザデータの更新エラー", "error_updating_user_data" => "ユーザデータの更新エラー",
"user_details_saved" => "ユーザー詳細の保存", "user_details_saved" => "ユーザー詳細の保存",
// Admin Page
"registrations" => "登録",
"enable_user_registrations" => "ユーザー登録を有効にする",
"maximum_number_users" => "最大ユーザ数",
"require_email_verification" => "メール確認を必要とする",
"configure_smtp_settings_to_enable" => "SMTP設定を構成して有効にする",
"server_url" => "サーバーURL",
"server_url_info" => "電子メール認証とパスワード回復に使用される。有効な公開URLでなければなりません。",
"server_url_password_reset" => "設定すると、パスワードリセット機能も有効になる。",
"max_users_info" => "0に設定すると無制限になります",
"user_management" => "ユーザー管理",
"delete_user" => "ユーザーを削除",
"delete_user_info" => "ユーザーを削除すると、そのユーザーのサブスクリプションと設定もすべて削除されます。",
"smtp_settings" => "SMTP設定",
"smtp_usage_info" => "パスワードの回復やその他のシステム電子メールに使用されます。",
// Email Verification
"email_verified" => "メールアドレスが確認されました",
"email_verification_failed" => "メールアドレスの確認に失敗しました",
]; ];

View File

@ -10,6 +10,8 @@ $i18n = [
"main_currency" => "기본 통화", "main_currency" => "기본 통화",
"language" => "언어", "language" => "언어",
"passwords_dont_match" => "비밀번호가 일치하지 않습니다.", "passwords_dont_match" => "비밀번호가 일치하지 않습니다.",
"username_exists" => "이미 존재하는 유저명입니다.",
"email_exists" => "이미 존재하는 이메일입니다.",
"registration_failed" => "회원가입 실패. 다시 시도해 주세요.", "registration_failed" => "회원가입 실패. 다시 시도해 주세요.",
"register" => "회원가입", "register" => "회원가입",
"restore_database" => "데이터베이스 복구", "restore_database" => "데이터베이스 복구",
@ -18,6 +20,13 @@ $i18n = [
'stay_logged_in' => "로그인 유지 (30일)", 'stay_logged_in' => "로그인 유지 (30일)",
'login' => "로그인", 'login' => "로그인",
'login_failed' => "로그인 정보가 부정확합니다.", 'login_failed' => "로그인 정보가 부정확합니다.",
'registration_successful' => "등록 성공",
'user_email_waiting_verification' => "이메일을 인증해야 합니다. 이메일을 확인해 주세요.",
// Password Reset Page
'forgot_password' => "비밀번호를 잊으셨나요?",
'reset_password' => "비밀번호 재설정",
'reset_sent_check_email' => "비밀번호 재설정 이메일이 전송되었습니다. 이메일을 확인해 주세요.",
'password_reset_successful' => "비밀번호 재설정 성공",
// Header // Header
'subscriptions' => "구독", 'subscriptions' => "구독",
'stats' => "통계", 'stats' => "통계",
@ -255,6 +264,24 @@ $i18n = [
// User // User
"error_updating_user_data" => "유저 데이터 갱신 실패.", "error_updating_user_data" => "유저 데이터 갱신 실패.",
"user_details_saved" => "유저 세부정보 저장 성공", "user_details_saved" => "유저 세부정보 저장 성공",
// Admin Page
"registrations" => "회원가입",
"enable_user_registrations" => "유저 회원가입 활성화",
"maximum_number_users" => "최대 유저 수",
"require_email_verification" => "이메일 인증 필요",
"configure_smtp_settings_to_enable" => "SMTP 설정을 구성하여 이메일 인증을 활성화합니다.",
"server_url" => "서버 URL",
"server_url_info" => "이메일 인증 및 비밀번호 복구에 사용됩니다. 유효한 공개 URL이어야 합니다.",
"server_url_password_reset" => "설정하면 비밀번호 재설정 기능도 활성화됩니다.",
"max_users_info" => "0으로 설정하면 무제한으로 설정됩니다.",
"user_management" => "유저 관리",
"delete_user" => "유저 삭제",
"delete_user_info" => "사용자를 삭제하면 모든 구독 및 설정도 삭제됩니다.",
"smtp_settings" => "SMTP 설정",
"smtp_usage_info" => "비밀번호 복구 및 기타 시스템 이메일에 사용됩니다.",
// Email Verification
"email_verified" => "이메일 인증 완료",
"email_verification_failed" => "이메일 인증 실패",
]; ];

View File

@ -10,6 +10,8 @@ $i18n = [
"main_currency" => "Główna waluta", "main_currency" => "Główna waluta",
"language" => "Język", "language" => "Język",
"passwords_dont_match" => "Hasła nie pasują", "passwords_dont_match" => "Hasła nie pasują",
"username_exists" => "Nazwa użytkownika już istnieje",
"email_exists" => "E-mail już istnieje",
"registration_failed" => "Rejestracja nie powiodła się, spróbuj ponownie.", "registration_failed" => "Rejestracja nie powiodła się, spróbuj ponownie.",
"register" => "Rejestracja", "register" => "Rejestracja",
"restore_database" => "Przywróć bazę danych", "restore_database" => "Przywróć bazę danych",
@ -18,6 +20,13 @@ $i18n = [
'stay_logged_in' => "Pozostań zalogowany (30 dni)", 'stay_logged_in' => "Pozostań zalogowany (30 dni)",
'login' => "Zaloguj się", 'login' => "Zaloguj się",
'login_failed' => "Dane logowania są nieprawidłowe", 'login_failed' => "Dane logowania są nieprawidłowe",
'registration_successful' => "Pomyślnie zarejestrowano",
'user_email_waiting_verification' => "Twój adres e-mail musi zostać zweryfikowany. Sprawdź swój adres e-mail",
// Password Reset Page
'forgot_password' => "Zapomniałeś hasła? Kliknij tutaj",
'reset_password' => "Zresetuj hasło",
'reset_sent_check_email' => "Link do zresetowania hasła został wysłany na Twój adres e-mail",
'password_reset_successful' => "Hasło zostało zresetowane pomyślnie",
// Header // Header
'subscriptions' => "Subskrypcje", 'subscriptions' => "Subskrypcje",
'stats' => "Statystyki", 'stats' => "Statystyki",
@ -255,6 +264,24 @@ $i18n = [
// User // User
"error_updating_user_data" => "Błąd podczas aktualizacji danych użytkownika.", "error_updating_user_data" => "Błąd podczas aktualizacji danych użytkownika.",
"user_details_saved" => "Dane użytkownika zostały zapisane", "user_details_saved" => "Dane użytkownika zostały zapisane",
// Admin Page
"registrations" => "Rejestracje",
"enable_user_registrations" => "Włącz rejestracje użytkowników",
"maximum_number_users" => "Maksymalna liczba użytkowników",
"require_email_verification" => "Wymagaj weryfikacji e-maila",
"configure_smtp_settings_to_enable" => "Skonfiguruj ustawienia SMTP, aby włączyć",
"server_url" => "Adres URL serwera",
"server_url_info" => "Służy do weryfikacji adresu e-mail i odzyskiwania hasła. Musi to być prawidłowy publiczny adres URL.",
"server_url_password_reset" => "Jeśli zostanie ustawiona, włączy również funkcję resetowania hasła.",
"max_users_info" => "Jeśli ustawisz 0, nie będzie limitu użytkowników.",
"user_management" => "Zarządzanie użytkownikami",
"delete_user" => "Usuń użytkownika",
"delete_user_info" => "Usunięcie użytkownika spowoduje również usunięcie wszystkich jego subskrypcji i ustawień.",
"smtp_settings" => "Ustawienia SMTP",
"smtp_usage_info" => "Będzie używany do odzyskiwania hasła i innych e-maili systemowych.",
// Email Verification
"email_verified" => "E-mail został zweryfikowany",
"email_verification_failed" => "Weryfikacja e-maila nie powiodła się",
]; ];

View File

@ -10,6 +10,8 @@ $i18n = [
"main_currency" => "Moeda Principal", "main_currency" => "Moeda Principal",
"language" => "Linguagem", "language" => "Linguagem",
"passwords_dont_match" => "As passwords não coincidem", "passwords_dont_match" => "As passwords não coincidem",
"username_exists" => "Nome de utilizador já existe",
"email_exists" => "Email já existe",
"registration_failed" => "O registo falhou. Tente novamente", "registration_failed" => "O registo falhou. Tente novamente",
"register" => "Registar", "register" => "Registar",
"restore_database" => "Restaurar base de dados", "restore_database" => "Restaurar base de dados",
@ -18,6 +20,13 @@ $i18n = [
'stay_logged_in' => "Manter sessão (30 dias)", 'stay_logged_in' => "Manter sessão (30 dias)",
'login' => "Iniciar Sessão", 'login' => "Iniciar Sessão",
'login_failed' => "Dados de autenticação incorrectos", 'login_failed' => "Dados de autenticação incorrectos",
'registration_successful' => "Registo efectuado com sucesso.",
'user_email_waiting_verification' => "O seu e-mail precisa de ser validado. Verifique o seu correio eletrónico",
// Password Reset Page
'forgot_password' => "Esqueceu-se da password?",
'reset_password' => "Repor Password",
'reset_sent_check_email' => "Pedido de reposição de password enviado. Verifique o seu email.",
'password_reset_successful' => "Password reposta com sucesso",
// Header // Header
'subscriptions' => "Subscrições", 'subscriptions' => "Subscrições",
'stats' => "Estatísticas", 'stats' => "Estatísticas",
@ -255,6 +264,24 @@ $i18n = [
// User // User
"error_updating_user_data" => "Erro ao actualizar dados do utilizador.", "error_updating_user_data" => "Erro ao actualizar dados do utilizador.",
"user_details_saved" => "Dados do utiliador actualizados.", "user_details_saved" => "Dados do utiliador actualizados.",
// Admin Page
"registrations" => "Registos",
"enable_user_registrations" => "Activar Registos de Utilizadores",
"maximum_number_users" => "Número Máximo de Utilizadores",
"require_email_verification" => "Requerer verificação de email",
"configure_smtp_settings_to_enable" => "Configure as definições SMTP para activar esta funcionalidade.",
"server_url" => "URL do Servidor",
"server_url_info" => "Usado para gerar links de verificação de email. Deve ser um URL público e válido.",
"server_url_password_reset" => "Se definido, também activará a funcionalidade de reposição da palavra-passe.",
"max_users_info" => "0 para ilimitado",
"user_management" => "Gestão de Utilizadores",
"delete_user" => "Apagar Utilizador",
"delete_user_info" => "Apagar utilizador irá remover todas as suas subscrições e dados associados.",
"smtp_settings" => "Definições SMTP",
"smtp_usage_info" => "Será usado para recuperações de password e outros emails do sistema.",
// Email Verification
"email_verified" => "Email verificado",
"email_verification_failed" => "Verificação de email falhou",
]; ];

View File

@ -10,6 +10,8 @@ $i18n = [
"main_currency" => "Moeda principal", "main_currency" => "Moeda principal",
"language" => "Idioma", "language" => "Idioma",
"passwords_dont_match" => "As senhas não são iguais", "passwords_dont_match" => "As senhas não são iguais",
"username_exists" => "O nome de usuário já existe",
"email_exists" => "O email já está em uso",
"registration_failed" => "O registro falhou. Por favor, tente novamente", "registration_failed" => "O registro falhou. Por favor, tente novamente",
"register" => "Registrar", "register" => "Registrar",
"restore_database" => "Restaurar banco de dados", "restore_database" => "Restaurar banco de dados",
@ -18,6 +20,13 @@ $i18n = [
'stay_logged_in' => "Me manter logado (30 dias)", 'stay_logged_in' => "Me manter logado (30 dias)",
'login' => "Login", 'login' => "Login",
'login_failed' => "As informações de login estão incorretas", 'login_failed' => "As informações de login estão incorretas",
'registration_successful' => "Registro bem-sucedido",
'user_email_waiting_verification' => "Seu e-mail precisa ser validado. Por favor, verifique seu e-mail",
// Password Reset Page
'forgot_password' => "Esqueceu a senha?",
'reset_password' => "Redefinir senha",
'reset_sent_check_email' => "Redefinição de senha enviada. Por favor, verifique seu email",
'password_reset_successful' => "Senha redefinida com sucesso",
// Header // Header
'subscriptions' => "Assinaturas", 'subscriptions' => "Assinaturas",
'stats' => "Estatísticas", 'stats' => "Estatísticas",
@ -253,6 +262,24 @@ $i18n = [
// User // User
"error_updating_user_data" => "Erro ao atualizar os dados do usuário", "error_updating_user_data" => "Erro ao atualizar os dados do usuário",
"user_details_saved" => "Dados do usuário salvos", "user_details_saved" => "Dados do usuário salvos",
// Admin Page
"registrations" => "Registros",
"enable_user_registrations" => "Ativar registros de usuários",
"maximum_number_users" => "Número máximo de usuários",
"require_email_verification" => "Requerer verificação de email",
"configure_smtp_settings_to_enable" => "Configure as configurações SMTP para ativar o envio de email",
"server_url" => "URL do servidor",
"server_url_info" => "Será usado para gerar links de verificação de email, deve ser um endereço público e válido.",
"server_url_password_reset" => "Se definido, também ativará a funcionalidade de redefinição de senha.",
"max_users_info" => "0 para ilimitado",
"user_management" => "Gerenciamento de usuários",
"delete_user" => "Excluir usuário",
"delete_user_info" => "Excluir um usuário também excluirá todas as assinaturas e dados associados",
"smtp_settings" => "Configurações SMTP",
"smtp_usage_info" => "Será usado para recuperação de senha e outros e-mails do sistema.",
// Email Verification
"email_verified" => "Email verificado",
"email_verification_failed" => "Falha na verificação do email",
]; ];

View File

@ -10,6 +10,8 @@ $i18n = [
"main_currency" => "Основная валюта", "main_currency" => "Основная валюта",
"language" => "Язык", "language" => "Язык",
"passwords_dont_match" => "Пароли не совпадают", "passwords_dont_match" => "Пароли не совпадают",
"username_exists" => "Имя пользователя уже существует",
"email_exists" => "E-mail уже существует",
"registration_failed" => "Регистрация не удалась, попробуйте еще раз.", "registration_failed" => "Регистрация не удалась, попробуйте еще раз.",
"register" => "Регистрация", "register" => "Регистрация",
"restore_database" => "Восстановить базу данных", "restore_database" => "Восстановить базу данных",
@ -18,6 +20,13 @@ $i18n = [
'stay_logged_in' => "Оставаться в системе (30 дней)", 'stay_logged_in' => "Оставаться в системе (30 дней)",
'login' => "Авторизоваться", 'login' => "Авторизоваться",
'login_failed' => "Данные для входа неверны", 'login_failed' => "Данные для входа неверны",
'registration_successful' => "Регистрация прошла успешно",
'user_email_waiting_verification' => "Ваша электронная почта нуждается в проверке. Пожалуйста, проверьте свою электронную почту",
// Password Reset Page
'forgot_password' => "Забыли пароль?",
'reset_password' => "Сбросить пароль",
'reset_sent_check_email' => "Ссылка для сброса пароля отправлена на вашу электронную почту",
'password_reset_successful' => "Пароль успешно сброшен",
// Header // Header
'subscriptions' => "Подписки", 'subscriptions' => "Подписки",
'stats' => "Статистика", 'stats' => "Статистика",
@ -255,6 +264,24 @@ $i18n = [
// User // User
"error_updating_user_data" => "Ошибка обновления пользовательских данных.", "error_updating_user_data" => "Ошибка обновления пользовательских данных.",
"user_details_saved" => "Данные пользователя сохранены.", "user_details_saved" => "Данные пользователя сохранены.",
// Admin Page
"registrations" => "Регистрации",
"enable_user_registrations" => "Включить регистрацию пользователей",
"maximum_number_users" => "Максимальное количество пользователей",
"require_email_verification" => "Требовать подтверждение по электронной почте",
"configure_smtp_settings_to_enable" => "Настройте SMTP, чтобы включить эту функцию.",
"server_url" => "URL-адрес сервера",
"server_url_info" => "Используется для проверки электронной почты и восстановления пароля. Должен быть действительным публичным URL.",
"server_url_password_reset" => "Если этот параметр установлен, он также включает функцию сброса пароля.",
"max_users_info" => "Установите 0 для неограниченного количества пользователей.",
"user_management" => "Управление пользователями",
"delete_user" => "Удалить пользователя",
"delete_user_info" => "Удаление пользователя также приведет к удалению всех его подписок и настроек.",
"smtp_settings" => "Настройки SMTP",
"smtp_usage_info" => "Будет использоваться для восстановления пароля и других системных писем.",
// Email Verification
"email_verified" => "Ваш адрес электронной почты подтвержден. Теперь вы можете войти.",
"email_verification_failed" => "Не удалось подтвердить ваш адрес электронной почты.",
]; ];

View File

@ -10,6 +10,8 @@ $i18n = [
"main_currency" => "Главна валута", "main_currency" => "Главна валута",
"language" => "Језик", "language" => "Језик",
"passwords_dont_match" => "Лозинке се не поклапају", "passwords_dont_match" => "Лозинке се не поклапају",
"username_exists" => "Корисничко име већ постоји",
"email_exists" => "Е-пошта већ постоји",
"registration_failed" => "Регистрација није успела, покушајте поново.", "registration_failed" => "Регистрација није успела, покушајте поново.",
"register" => "Региструј се", "register" => "Региструј се",
"restore_database" => "Врати базу података", "restore_database" => "Врати базу података",
@ -18,6 +20,13 @@ $i18n = [
'stay_logged_in' => "Остани пријављен (30 дана)", 'stay_logged_in' => "Остани пријављен (30 дана)",
'login' => "Пријави се", 'login' => "Пријави се",
'login_failed' => "Подаци за пријаву нису исправни", 'login_failed' => "Подаци за пријаву нису исправни",
'registration_successful' => "Пријава успешна",
'user_email_waiting_verification' => "Ваша е-пошта треба да буде верификована. Молимо прегледајте Е-пошту",
// Password Reset Page
'forgot_password' => "Заборављена лозинка",
'reset_password' => "Ресетуј лозинку",
'reset_sent_check_email' => "Ресетовање лозинке је послато на вашу е-пошту",
'password_reset_successful' => "Ресетовање лозинке је успешно",
// Header // Header
'subscriptions' => "Претплате", 'subscriptions' => "Претплате",
'stats' => "Статистике", 'stats' => "Статистике",
@ -254,6 +263,24 @@ $i18n = [
// Корисник // Корисник
"error_updating_user_data" => "Грешка при ажурирању корисничких података.", "error_updating_user_data" => "Грешка при ажурирању корисничких података.",
"user_details_saved" => "Кориснички подаци сачувани", "user_details_saved" => "Кориснички подаци сачувани",
// Admin Page
"registrations" => "Регистрације",
"enable_user_registrations" => "Омогући регистрације корисника",
"maximum_number_users" => "Максималан број корисника",
"require_email_verification" => "Захтевај верификацију е-поште",
"configure_smtp_settings_to_enable" => "Конфигуришите SMTP подешавања да бисте омогућили ову опцију",
"server_url" => "URL сервера",
"server_url_info" => "Користи се за верификацију е-поште и опоравак лозинке. Мора да буде важећи јавни УРЛ.",
"server_url_password_reset" => "Ако је подешено, такође ће се омогућити функција ресетовања лозинке.",
"max_users_info" => "Максималан број корисника који могу бити регистровани. 0 за неограничено.",
"user_management" => "Управљање корисницима",
"delete_user" => "Обриши корисника",
"delete_user_info" => "Брисање корисника ће такође обрисати све његове претплате и податке.",
"smtp_settings" => "SMTP подешавања",
"smtp_usage_info" => "SMTP се користи за слање е-поште за обавештења.",
// Email Verification
"email_verified" => "Е-пошта је верификована",
"email_verification_failed" => "Верификација е-поште није успела",
]; ];

View File

@ -10,6 +10,8 @@ $i18n = [
"main_currency" => "Glavna valuta", "main_currency" => "Glavna valuta",
"language" => "Jezik", "language" => "Jezik",
"passwords_dont_match" => "Lozinke se ne poklapaju", "passwords_dont_match" => "Lozinke se ne poklapaju",
"username_exists" => "Korisničko ime već postoji",
"email_exists" => "E-pošta već postoji",
"registration_failed" => "Registracija nije uspela, pokušajte ponovo.", "registration_failed" => "Registracija nije uspela, pokušajte ponovo.",
"register" => "Registruj se", "register" => "Registruj se",
"restore_database" => "Vrati bazu podataka", "restore_database" => "Vrati bazu podataka",
@ -18,6 +20,13 @@ $i18n = [
'stay_logged_in' => "Ostani prijavljen (30 dana)", 'stay_logged_in' => "Ostani prijavljen (30 dana)",
'login' => "Prijavi se", 'login' => "Prijavi se",
'login_failed' => "Podaci za prijavu nisu ispravni", 'login_failed' => "Podaci za prijavu nisu ispravni",
'registration_successful' => "Registracija uspešna",
'user_email_waiting_verification' => "Vaša e-pošta treba da bude verifikovana. Molimo pregledajte E-poštu",
// Password Reset Page
'forgot_password' => "Zaboravili ste lozinku?",
'reset_password' => "Resetuj lozinku",
'reset_sent_check_email' => "Poslali smo vam e-poštu sa uputstvima za resetovanje lozinke",
'password_reset_successful' => "Lozinka uspešno resetovana",
// Header // Header
'subscriptions' => "Pretplate", 'subscriptions' => "Pretplate",
'stats' => "Statistike", 'stats' => "Statistike",
@ -255,6 +264,24 @@ $i18n = [
// Korisnik // Korisnik
"error_updating_user_data" => "Greška pri ažuriranju korisničkih podataka.", "error_updating_user_data" => "Greška pri ažuriranju korisničkih podataka.",
"user_details_saved" => "Korisnički podaci sačuvani", "user_details_saved" => "Korisnički podaci sačuvani",
// Admin Page
"registrations" => "Registracije",
"enable_user_registrations" => "Omogući registracije korisnika",
"maximum_number_users" => "Maksimalan broj korisnika",
"require_email_verification" => "Zahtevaj verifikaciju e-pošte",
"configure_smtp_settings_to_enable" => "Konfigurišite SMTP podešavanja da biste omogućili ovu opciju",
"server_url" => "URL servera",
"server_url_info" => "Koristi se za verifikaciju e-pošte i oporavak lozinke. Mora da bude važeći javni URL.",
"server_url_password_reset" => "Ako je podešeno, takođe će se omogućiti funkcija resetovanja lozinke.",
"max_users_info" => "0 za neograničen broj korisnika",
"user_management" => "Upravljanje korisnicima",
"delete_user" => "Izbriši korisnika",
"delete_user_info" => "Brisanjem korisnika izbrisaće se i sve njegove pretplate i podešavanja.",
"smtp_settings" => "SMTP podešavanja",
"smtp_usage_info" => "Koristiće se za oporavak lozinke i druge sistemske e-poruke.",
// Email Verification
"email_verified" => "E-pošta je uspešno verifikovana",
"email_verification_failed" => "Verifikacija e-pošte nije uspela",
]; ];

View File

@ -10,6 +10,8 @@ $i18n = [
"main_currency" => "Ana Para Birimi", "main_currency" => "Ana Para Birimi",
"language" => "Dil", "language" => "Dil",
"passwords_dont_match" => "Şifreler eşleşmiyor", "passwords_dont_match" => "Şifreler eşleşmiyor",
"username_exists" => "Bu kullanıcı adı zaten mevcut",
"email_exists" => "Bu e-posta zaten mevcut",
"registration_failed" => "Kayıt başarısız, lütfen tekrar deneyin.", "registration_failed" => "Kayıt başarısız, lütfen tekrar deneyin.",
"register" => "Kayıt Ol", "register" => "Kayıt Ol",
"restore_database" => "Veritabanını geri yükle", "restore_database" => "Veritabanını geri yükle",
@ -18,6 +20,13 @@ $i18n = [
'stay_logged_in' => "Oturumu açık tut (30 gün)", 'stay_logged_in' => "Oturumu açık tut (30 gün)",
'login' => "Giriş Yap", 'login' => "Giriş Yap",
'login_failed' => "Giriş bilgileri hatalı", 'login_failed' => "Giriş bilgileri hatalı",
'registration_successful' => "Kayıt başarılı",
'user_email_waiting_verification' => "E-postanızın doğrulanması gerekiyor. Lütfen e-postanızı kontrol edin",
// Password Reset Page
'forgot_password' => "Şifremi Unuttum",
'reset_password' => "Şifreyi Sıfırla",
'reset_sent_check_email' => "Şifre sıfırlama bağlantısı e-posta adresinize gönderildi. Lütfen e-postanızı kontrol edin.",
'password_reset_successful' => "Şifre sıfırlama başarılı",
// Header // Header
'subscriptions' => "Abonelikler", 'subscriptions' => "Abonelikler",
'stats' => "İstatistikler", 'stats' => "İstatistikler",
@ -255,6 +264,25 @@ $i18n = [
// User // User
"error_updating_user_data" => "Kullanıcı verileri güncellenirken hata oluştu.", "error_updating_user_data" => "Kullanıcı verileri güncellenirken hata oluştu.",
"user_details_saved" => "Kullanıcı detayları kaydedildi", "user_details_saved" => "Kullanıcı detayları kaydedildi",
// Admin Page
"registrations" => "Kayıtlar",
"enable_user_registrations" => "Kullanıcı kayıtlarını etkinleştir",
"maximum_number_users" => "Maksimum kullanıcı sayısı",
"require_email_verification" => "E-posta doğrulaması gerektir",
"configure_smtp_settings_to_enable" => "E-posta doğrulamasını etkinleştirmek için SMTP ayarlarını yapılandırın",
"server_url" => "Sunucu URL'si",
"server_url_info" => "E-posta doğrulama ve şifre kurtarma için kullanılır. Geçerli bir genel URL olmalıdır.",
"server_url_password_reset" => "Ayarlanırsa şifre sıfırlama işlevini de etkinleştirir.",
"max_users_info" => "0 veya boş bırakıldığında sınırsız kullanıcı sayısı",
"user_management" => "Kullanıcı Yönetimi",
"delete_user" => "Kullanıcıyı Sil",
"delete_user_info" => "Bir kullanıcının silinmesi aynı zamanda tüm aboneliklerinin ve ayarlarının da silinmesine neden olur.",
"smtp_settings" => "SMTP Ayarları",
"smtp_usage_info" => "Şifre kurtarma ve diğer sistem e-postaları için kullanılacaktır.",
// Email Verification
"email_verified" => "E-posta doğrulandı",
"email_verification_failed" => "E-posta doğrulaması başarısız oldu",
]; ];

View File

@ -10,6 +10,8 @@ $i18n = [
"main_currency" => "主要货币", "main_currency" => "主要货币",
"language" => "语言", "language" => "语言",
"passwords_dont_match" => "密码不匹配", "passwords_dont_match" => "密码不匹配",
"username_exists" => "用户名已存在",
"email_exists" => "电子邮箱已存在",
"registration_failed" => "注册失败,请重试。", "registration_failed" => "注册失败,请重试。",
"register" => "注册", "register" => "注册",
"restore_database" => "恢复数据库", "restore_database" => "恢复数据库",
@ -19,6 +21,14 @@ $i18n = [
'stay_logged_in' => "30 天内免登录", 'stay_logged_in' => "30 天内免登录",
'login' => "登录", 'login' => "登录",
'login_failed' => "登录信息错误", 'login_failed' => "登录信息错误",
'registration_successful' => "注册成功",
'user_email_waiting_verification' => "您的电子邮件需要验证。请检查您的电子邮件",
// Password Reset Page
'forgot_password' => "忘记密码",
'reset_password' => "重置密码",
'reset_sent_check_email' => "重置密码链接已发送到您的电子邮箱",
'password_reset_successful' => "密码重置成功",
// 页眉 // 页眉
'subscriptions' => "订阅", 'subscriptions' => "订阅",
@ -272,6 +282,26 @@ $i18n = [
"error_updating_user_data" => "更新用户数据时出错。", "error_updating_user_data" => "更新用户数据时出错。",
"user_details_saved" => "用户详细信息已保存", "user_details_saved" => "用户详细信息已保存",
// Admin Page
"registrations" => "注册",
"enable_user_registrations" => "启用用户注册",
"maximum_number_users" => "最大用户数",
"require_email_verification" => "需要电子邮件验证",
"configure_smtp_settings_to_enable" => "要启用此功能,请配置 SMTP 设置。",
"server_url" => "服务器 URL",
"server_url_info" => "用于电子邮件验证和密码恢复。必须是有效的公共 URL。",
"server_url_password_reset" => "如果设置,还将启用密码重置功能。",
"max_users_info" => "设置为 0 以无限制用户数",
"user_management" => "用户管理",
"delete_user" => "删除用户",
"delete_user_info" => "删除用户也会删除其所有订阅和设置。",
"smtp_settings" => "SMTP 设置",
"smtp_usage_info" => "将用于密码恢复和其他系统电子邮件。",
// Email Verification
"email_verified" => "电子邮件已验证",
"email_verification_failed" => "电子邮件验证失败",
]; ];
?> ?>

View File

@ -10,6 +10,8 @@ $i18n = [
"main_currency" => "主要貨幣單位", "main_currency" => "主要貨幣單位",
"language" => "語言", "language" => "語言",
"passwords_dont_match" => "密碼不一致", "passwords_dont_match" => "密碼不一致",
"username_exists" => "使用者名稱已存在",
"email_exists" => "電子信箱已存在",
"registration_failed" => "註冊失敗,請再試一次。", "registration_failed" => "註冊失敗,請再試一次。",
"register" => "註冊", "register" => "註冊",
"restore_database" => "還原資料庫", "restore_database" => "還原資料庫",
@ -18,6 +20,13 @@ $i18n = [
'stay_logged_in' => "保持登入 30 天", 'stay_logged_in' => "保持登入 30 天",
'login' => "登入", 'login' => "登入",
'login_failed' => "登入資訊錯誤", 'login_failed' => "登入資訊錯誤",
'registration_successful' => "註冊成功",
'user_email_waiting_verification' => "您的電子郵件需要驗證。 請查看你的信箱",
// Password Reset Page
'forgot_password' => "忘記密碼",
'reset_password' => "重設密碼",
'reset_sent_check_email' => "重設密碼的電子郵件已發送,請檢查您的電子郵件",
'password_reset_successful' => "密碼重設成功",
// 頁首 // 頁首
'subscriptions' => "訂閱", 'subscriptions' => "訂閱",
'stats' => "統計", 'stats' => "統計",
@ -255,6 +264,24 @@ $i18n = [
// User // User
"error_updating_user_data" => "更新使用者資訊時發生錯誤。", "error_updating_user_data" => "更新使用者資訊時發生錯誤。",
"user_details_saved" => "使用者資訊已儲存", "user_details_saved" => "使用者資訊已儲存",
// Admin Page
"registrations" => "註冊",
"enable_user_registrations" => "啟用使用者註冊",
"maximum_number_users" => "最大使用者數",
"require_email_verification" => "需要電子郵件驗證",
"configure_smtp_settings_to_enable" => "要啟用使用者註冊,請先設定 SMTP 設定。",
"server_url" => "伺服器 URL",
"server_url_info" => "用於電子郵件驗證和密碼恢復。 必須是有效的公共 URL。",
"server_url_password_reset" => "如果設置,還將啟用密碼重置功能。",
"max_users_info" => "設定為 0 以無限制使用者數",
"user_management" => "使用者管理",
"delete_user" => "刪除使用者",
"delete_user_info" => "刪除用戶也會刪除其所有訂閱和設定。",
"smtp_settings" => "SMTP 設定",
"smtp_usage_info" => "將用於密碼恢復和其他系統電子郵件。",
// Email Verification
"email_verified" => "電子郵件已驗證",
"email_verification_failed" => "電子郵件驗證失敗",
]; ];

View File

@ -147,8 +147,9 @@
} }
} }
$query = "SELECT main_currency FROM user WHERE id = 1"; $query = "SELECT main_currency FROM user WHERE id = :userId";
$stmt = $db->prepare($query); $stmt = $db->prepare($query);
$stmt->bindValue(':userId', $userId, SQLITE3_INTEGER);
$result = $stmt->execute(); $result = $stmt->execute();
$row = $result->fetchArray(SQLITE3_ASSOC); $row = $result->fetchArray(SQLITE3_ASSOC);
$mainCurrencyId = $row['main_currency']; $mainCurrencyId = $row['main_currency'];

View File

@ -1,3 +1,3 @@
<?php <?php
$version = "v1.29.1"; $version = "v2.0.0";
?> ?>

View File

@ -5,7 +5,7 @@
include_once 'includes/list_subscriptions.php'; include_once 'includes/list_subscriptions.php';
$sort = "next_payment"; $sort = "next_payment";
$sql = "SELECT * FROM subscriptions ORDER BY next_payment ASC, inactive ASC"; $sql = "SELECT * FROM subscriptions WHERE user_id = :userId ORDER BY next_payment ASC, inactive ASC";
if (isset($_COOKIE['sortOrder']) && $_COOKIE['sortOrder'] != "") { if (isset($_COOKIE['sortOrder']) && $_COOKIE['sortOrder'] != "") {
$sort = $_COOKIE['sortOrder']; $sort = $_COOKIE['sortOrder'];
$allowedSortCriteria = ['name', 'id', 'next_payment', 'price', 'payer_user_id', 'category_id', 'payment_method_id']; $allowedSortCriteria = ['name', 'id', 'next_payment', 'price', 'payer_user_id', 'category_id', 'payment_method_id'];
@ -14,11 +14,13 @@
$order = "DESC"; $order = "DESC";
} }
if (in_array($sort, $allowedSortCriteria)) { if (in_array($sort, $allowedSortCriteria)) {
$sql = "SELECT * FROM subscriptions ORDER BY $sort $order, inactive ASC"; $sql = "SELECT * FROM subscriptions WHERE user_id = :userId ORDER BY $sort $order, inactive ASC";
} }
} }
$result = $db->query($sql); $stmt = $db->prepare($sql);
$stmt->bindValue(':userId', $userId, SQLITE3_INTEGER);
$result = $stmt->execute();
if ($result) { if ($result) {
$subscriptions = array(); $subscriptions = array();
while ($row = $result->fetchArray(SQLITE3_ASSOC)) { while ($row = $result->fetchArray(SQLITE3_ASSOC)) {
@ -160,7 +162,7 @@
$print[$id]['currency_code'] = $currencies[$subscription['currency_id']]['code']; $print[$id]['currency_code'] = $currencies[$subscription['currency_id']]['code'];
$currencyId = $subscription['currency_id']; $currencyId = $subscription['currency_id'];
$print[$id]['next_payment'] = date('M d, Y', strtotime($subscription['next_payment'])); $print[$id]['next_payment'] = date('M d, Y', strtotime($subscription['next_payment']));
$paymentIconFolder = $paymentMethodId <= 31 ? 'images/uploads/icons/' : 'images/uploads/logos/'; $paymentIconFolder = (strpos($payment_methods[$paymentMethodId]['icon'], 'images/uploads/icons/') !== false) ? "" : "images/uploads/logos/";
$print[$id]['payment_method_icon'] = $paymentIconFolder . $payment_methods[$paymentMethodId]['icon']; $print[$id]['payment_method_icon'] = $paymentIconFolder . $payment_methods[$paymentMethodId]['icon'];
$print[$id]['payment_method_name'] = $payment_methods[$paymentMethodId]['name']; $print[$id]['payment_method_name'] = $payment_methods[$paymentMethodId]['name'];
$print[$id]['payment_method_id'] = $paymentMethodId; $print[$id]['payment_method_id'] = $paymentMethodId;

160
login.php
View File

@ -31,6 +31,8 @@ if (isset($_COOKIE['colorTheme'])) {
} }
$loginFailed = false; $loginFailed = false;
$hasSuccessMessage = (isset($_GET['validated']) && $_GET['validated'] == "true") || (isset($_GET['registered']) && $_GET['registered'] == true) ? true : false;
$userEmailWaitingVerification = false;
if (isset($_POST['username']) && isset($_POST['password'])) { if (isset($_POST['username']) && isset($_POST['password'])) {
$username = $_POST['username']; $username = $_POST['username'];
$password = $_POST['password']; $password = $_POST['password'];
@ -48,26 +50,47 @@ if (isset($_POST['username']) && isset($_POST['password'])) {
$main_currency = $row['main_currency']; $main_currency = $row['main_currency'];
$language = $row['language']; $language = $row['language'];
if (password_verify($password, $hashedPasswordFromDb)) { if (password_verify($password, $hashedPasswordFromDb)) {
$_SESSION['username'] = $username;
$_SESSION['loggedin'] = true; // Check if the user is in the email_verification table
$_SESSION['main_currency'] = $main_currency; $query = "SELECT 1 FROM email_verification WHERE user_id = :userId";
$_SESSION['userId'] = $userId; $stmt = $db->prepare($query);
$cookieExpire = time() + (30 * 24 * 60 * 60); $stmt->bindValue(':userId', $userId, SQLITE3_INTEGER);
setcookie('language', $language, $cookieExpire); $result = $stmt->execute();
if ($rememberMe) { $verificationRow = $result->fetchArray(SQLITE3_ASSOC);
$token = bin2hex(random_bytes(32));
$addLoginTokens = "INSERT INTO login_tokens (user_id, token) VALUES (?, ?)"; if ($verificationRow) {
$addLoginTokensStmt = $db->prepare($addLoginTokens); $userEmailWaitingVerification = true;
$addLoginTokensStmt->bindValue(1, $userId, SQLITE3_INTEGER); $loginFailed = true;
$addLoginTokensStmt->bindValue(2, $token, SQLITE3_TEXT); } else {
$addLoginTokensStmt->execute(); $_SESSION['username'] = $username;
$_SESSION['token'] = $token; $_SESSION['loggedin'] = true;
$cookieValue = $username . "|" . $token . "|" . $main_currency; $_SESSION['main_currency'] = $main_currency;
setcookie('wallos_login', $cookieValue, $cookieExpire); $_SESSION['userId'] = $userId;
$cookieExpire = time() + (30 * 24 * 60 * 60);
setcookie('language', $language, $cookieExpire);
if ($rememberMe) {
$query = "SELECT color_theme FROM settings";
$stmt = $db->prepare($query);
$result = $stmt->execute();
$settings = $result->fetchArray(SQLITE3_ASSOC);
setcookie('colorTheme', $settings['color_theme'], $cookieExpire);
$token = bin2hex(random_bytes(32));
$addLoginTokens = "INSERT INTO login_tokens (user_id, token) VALUES (:userId, :token)";
$addLoginTokensStmt = $db->prepare($addLoginTokens);
$addLoginTokensStmt->bindParam(':userId', $userId, SQLITE3_INTEGER);
$addLoginTokensStmt->bindParam(':token', $token, SQLITE3_TEXT);
$addLoginTokensStmt->execute();
$_SESSION['token'] = $token;
$cookieValue = $username . "|" . $token . "|" . $main_currency;
setcookie('wallos_login', $cookieValue, $cookieExpire);
}
$db->close();
header("Location: .");
exit();
} }
$db->close();
header("Location: .");
exit();
} else { } else {
$loginFailed = true; $loginFailed = true;
} }
@ -75,6 +98,32 @@ if (isset($_POST['username']) && isset($_POST['password'])) {
$loginFailed = true; $loginFailed = true;
} }
} }
//Check if registration is open
$registrations = false;
$adminQuery = "SELECT registrations_open, max_users, server_url, smtp_address FROM admin";
$adminResult = $db->query($adminQuery);
$adminRow = $adminResult->fetchArray(SQLITE3_ASSOC);
$registrationsOpen = $adminRow['registrations_open'];
$maxUsers = $adminRow['max_users'];
if ($registrationsOpen == 1 && $maxUsers == 0) {
$registrations = true;
} else if ($registrationsOpen == 1 && $maxUsers > 0) {
$userCountQuery = "SELECT COUNT(id) as userCount FROM user";
$userCountResult = $db->query($userCountQuery);
$userCountRow = $userCountResult->fetchArray(SQLITE3_ASSOC);
$userCount = $userCountRow['userCount'];
if ($userCount < $maxUsers) {
$registrations = true;
}
}
$resetPasswordEnabled = false;
if ($adminRow['smtp_address'] != "" && $adminRow['server_url'] != "") {
$resetPasswordEnabled = true;
}
?> ?>
<!DOCTYPE html> <!DOCTYPE html>
<html dir="<?= $languages[$lang]['dir'] ?>"> <html dir="<?= $languages[$lang]['dir'] ?>">
@ -91,6 +140,7 @@ if (isset($_POST['username']) && isset($_POST['password'])) {
<link rel="stylesheet" href="styles/themes/red.css?<?= $version ?>" id="red-theme" <?= $colorTheme != "red" ? "disabled" : "" ?>> <link rel="stylesheet" href="styles/themes/red.css?<?= $version ?>" id="red-theme" <?= $colorTheme != "red" ? "disabled" : "" ?>>
<link rel="stylesheet" href="styles/themes/green.css?<?= $version ?>" id="green-theme" <?= $colorTheme != "green" ? "disabled" : "" ?>> <link rel="stylesheet" href="styles/themes/green.css?<?= $version ?>" id="green-theme" <?= $colorTheme != "green" ? "disabled" : "" ?>>
<link rel="stylesheet" href="styles/themes/yellow.css?<?= $version ?>" id="yellow-theme" <?= $colorTheme != "yellow" ? "disabled" : "" ?>> <link rel="stylesheet" href="styles/themes/yellow.css?<?= $version ?>" id="yellow-theme" <?= $colorTheme != "yellow" ? "disabled" : "" ?>>
<link rel="stylesheet" href="styles/font-awesome.min.css">
<link rel="stylesheet" href="styles/barlow.css"> <link rel="stylesheet" href="styles/barlow.css">
<link rel="stylesheet" href="styles/login-dark-theme.css?<?= $version ?>" id="dark-theme" <?= $theme == "light" ? "disabled" : "" ?>> <link rel="stylesheet" href="styles/login-dark-theme.css?<?= $version ?>" id="dark-theme" <?= $theme == "light" ? "disabled" : "" ?>>
</head> </head>
@ -122,20 +172,74 @@ if (isset($_POST['username']) && isset($_POST['password'])) {
<input type="checkbox" id="remember" name="remember"> <input type="checkbox" id="remember" name="remember">
<label for="remember"><?= translate('stay_logged_in', $i18n) ?></label> <label for="remember"><?= translate('stay_logged_in', $i18n) ?></label>
</div> </div>
<?php
if ($loginFailed) {
?>
<sup class="error">
<?= translate('login_failed', $i18n) ?>.
</sup>
<?php
}
?>
<div class="form-group"> <div class="form-group">
<input type="submit" value="<?= translate('login', $i18n) ?>"> <input type="submit" value="<?= translate('login', $i18n) ?>">
</div> </div>
<?php
if ($loginFailed) {
?>
<ul class="error-box">
<?php
if ($userEmailWaitingVerification) {
?>
<li><i class="fa-solid fa-triangle-exclamation"></i><?= translate('user_email_waiting_verification', $i18n) ?></li>
<?php
} else {
?>
<li><i class="fa-solid fa-triangle-exclamation"></i><?= translate('login_failed', $i18n) ?></li>
<?php
}
?>
</ul>
<?php
}
if ($hasSuccessMessage) {
?>
<ul class="success-box">
<?php
if (isset($_GET['validated']) && $_GET['validated'] == "true") {
?>
<li><i class="fa-solid fa-check"></i><?= translate('email_verified', $i18n) ?></li>
<?php
} else if (isset($_GET['registered']) && $_GET['registered']) {
?>
<li><i class="fa-solid fa-check"></i><?= translate('registration_successful', $i18n) ?></li>
<?php
if (isset($_GET['requireValidation']) && $_GET['requireValidation'] == true) {
?>
<li><?= translate('user_email_waiting_verification', $i18n) ?></li>
<?php
}
}
?>
</ul>
<?php
}
if ($resetPasswordEnabled) {
?>
<div class="login-form-link">
<a href="passwordreset.php"><?= translate('forgot_password', $i18n) ?></a>
</div>
<?php
}
?>
<?php
if ($registrations) {
?>
<div class="separator">
<input type="button" class="secondary-button" onclick="openRegitrationPage()" value="<?= translate('register', $i18n) ?>"></input>
</div>
<?php
}
?>
</form> </form>
</section> </section>
</div> </div>
<script type="text/javascript">
function openRegitrationPage() {
window.location.href = "registration.php";
}
</script>
</body> </body>
</html> </html>

View File

@ -4,16 +4,17 @@
// get token from cookie to remove from DB // get token from cookie to remove from DB
if (isset($_SESSION['token'])) { if (isset($_SESSION['token'])) {
$token = $_SESSION['token']; $token = $_SESSION['token'];
$sql = "DELETE FROM login_tokens WHERE token = ?"; $sql = "DELETE FROM login_tokens WHERE token = :token AND user_id = :userId";
$stmt = $db->prepare($sql); $stmt = $db->prepare($sql);
$stmt->bindValue(1, $token, SQLITE3_TEXT); $stmt->bindParam(':token', $token, SQLITE3_TEXT);
$stmt->bindParam(':userId', $userId, SQLITE3_INTEGER);
$stmt->execute(); $stmt->execute();
} }
$_SESSION = array(); $_SESSION = array();
session_destroy(); session_destroy();
$cookieExpire = time() - 3600; $cookieExpire = time() - 3600;
setcookie('wallos_login', '', $cookieExpire); setcookie('wallos_login', '', $cookieExpire);
$db->close(); $db->close();
header("Location: ."); header("Location: .");
exit(); exit();
?> ?>

54
migrations/000020.php Normal file
View File

@ -0,0 +1,54 @@
<?php
/*
/ This migration adds user_id foreign key to all the relevant tables, to allow for multiple users.
/ It also creates the admin table to store the admin settings.
*/
/** @noinspection PhpUndefinedVariableInspection */
$tablesToUpdate = ['payment_methods', 'subscriptions', 'categories', 'currencies', 'fixer', 'household', 'settings', 'custom_colors', 'notification_settings', 'telegram_notifications', 'webhook_notifications', 'gotify_notifications', 'email_notifications', 'pushover_notifications', 'discord_notifications', 'last_exchange_update'];
foreach ($tablesToUpdate as $table) {
$columnQuery = $db->query("SELECT * FROM pragma_table_info('$table') WHERE name='user_id'");
$columnRequired = $columnQuery->fetchArray(SQLITE3_ASSOC) === false;
if ($columnRequired) {
$db->exec("ALTER TABLE $table ADD COLUMN user_id INTEGER DEFAULT 1");
}
}
$db->exec('CREATE TABLE IF NOT EXISTS admin (
id INTEGER PRIMARY KEY,
registrations_open BOOLEAN DEFAULT 0,
max_users INTEGER DEFAULT 0,
require_email_verification BOOLEAN DEFAULT 0,
server_url TEXT,
smtp_address TEXT,
smtp_port INTEGER DEFAULT 587,
smtp_username TEXT,
smtp_password TEXT,
from_email TEXT,
encryption TEXT DEFAULT "tls"
)');
$db->exec('INSERT INTO admin (id, registrations_open, require_email_verification, server_url, max_users, smtp_address, smtp_port, smtp_username, smtp_password, from_email, encryption) VALUES (1, 0, 0, "", 0, "", 587, "", "", "", "tls")');
$updateQuery = "UPDATE payment_methods SET icon = 'images/uploads/icons/' || icon WHERE id < 32 AND icon NOT LIKE '%/images/uploads/icons%'";
$db->exec($updateQuery);
$db->exec('CREATE TABLE IF NOT EXISTS email_verification (
id INTEGER PRIMARY KEY,
user_id INTEGER,
email TEXT,
token TEXT,
email_sent BOOLEAN DEFAULT 0)');
$db->exec('CREATE TABLE IF NOT EXISTS password_resets (
id INTEGER PRIMARY KEY,
user_id INTEGER,
email TEXT,
token TEXT,
created_at DATETIME DEFAULT CURRENT_TIMESTAMP,
email_sent BOOLEAN DEFAULT 0)');
?>

224
passwordreset.php Normal file
View File

@ -0,0 +1,224 @@
<?php
require_once 'includes/connect.php';
require_once 'includes/checkuser.php';
require_once 'includes/i18n/languages.php';
require_once 'includes/i18n/getlang.php';
require_once 'includes/i18n/' . $lang . '.php';
require_once 'includes/version.php';
session_start();
if (isset($_SESSION['loggedin']) && $_SESSION['loggedin'] === true) {
$db->close();
header("Location: .");
exit();
}
$requestMode = true;
$resetMode = false;
$theme = "light";
if (isset($_COOKIE['theme'])) {
$theme = $_COOKIE['theme'];
}
$colorTheme = "blue";
if (isset($_COOKIE['colorTheme'])) {
$colorTheme = $_COOKIE['colorTheme'];
}
$settings = $db->querySingle("SELECT * FROM admin", true);
if ($settings['smtp_address'] == "" || $settings['server_url'] == "") {
header("Location: .");
} else {
$resetPasswordEnabled = true;
}
$hasSuccessMessage = false;
$hasErrorMessage = false;
$passwordsMismatch = false;
$hideForm = false;
if (isset($_POST['email']) && $_POST['email'] != "" && isset($_GET['submit']) && $_GET['submit'] && !(isset($_GET['token'])) && !(isset($_POST['token']))) {
$requestMode = true;
$resetMode = false;
$email = $_POST['email'];
$user = $db->querySingle("SELECT * FROM user WHERE email = '$email'", true);
if ($user) {
$db->exec("DELETE FROM password_resets WHERE email = '$email'");
$token = bin2hex(random_bytes(32));
$db->exec("INSERT INTO password_resets (user_id, email, token) VALUES (" . $user['id'] . ", '$email', '$token')");
}
$hasSuccessMessage = true;
}
if (isset($_GET['token']) && $_GET['token'] != "" && isset($_GET['email']) && $_GET['email'] != "") {
$requestMode = false;
$resetMode = true;
$token = $_GET['token'];
$email = $_GET['email'];
$matchCount = "SELECT COUNT(*) FROM password_resets WHERE token = :token and email = :email";
$stmt = $db->prepare($matchCount);
$stmt->bindValue(':token', $token, SQLITE3_TEXT);
$stmt->bindValue(':email', $email, SQLITE3_TEXT);
$count = $stmt->execute()->fetchArray(SQLITE3_NUM);
if ($count[0] == 0) {
$hasErrorMessage = true;
$hideForm = true;
}
}
if (isset($_POST['password']) && $_POST['password'] != "" && isset($_POST['confirm_password']) && $_POST['confirm_password'] != "" && isset($_GET['submit']) && $_GET['submit']) {
$requestMode = false;
$resetMode = true;
$password = $_POST['password'];
$confirmPassword = $_POST['confirm_password'];
$token = $_POST['token'];
$email = $_POST['email'];
$resetQuery = "SELECT * FROM password_resets WHERE token = :token AND email = :email";
$stmt = $db->prepare($resetQuery);
$stmt->bindValue(':token', $token, SQLITE3_TEXT);
$stmt->bindValue(':email', $email, SQLITE3_TEXT);
$reset = $stmt->execute()->fetchArray(SQLITE3_ASSOC);
if ($reset) {
$user = $db->querySingle("SELECT * FROM user WHERE email = '" . $reset['email'] . "'", true);
if ($password == $confirmPassword) {
$passwordHash = password_hash($password, PASSWORD_DEFAULT);
$db->exec("UPDATE user SET password = '$passwordHash' WHERE id = " . $user['id']);
$db->exec("DELETE FROM password_resets WHERE token = '$token'");
$hasSuccessMessage = true;
$hideForm = true;
} else {
$hasErrorMessage = true;
$passwordsMismatch = true;
}
} else {
$hasSuccessMessage = false;
$hasErrorMessage = true;
}
}
?>
<!DOCTYPE html>
<html dir="<?= $languages[$lang]['dir'] ?>">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no">
<meta name="theme-color" content="<?= $theme == "light" ? "#FFFFFF" : "#222222" ?>"/>
<title>Wallos - Subscription Tracker</title>
<link rel="icon" type="image/png" href="images/icon/favicon.ico" sizes="16x16">
<link rel="apple-touch-icon" sizes="180x180" href="images/icon/apple-touch-icon.png">
<link rel="manifest" href="manifest.json">
<link rel="stylesheet" href="styles/theme.css?<?= $version ?>">
<link rel="stylesheet" href="styles/login.css?<?= $version ?>">
<link rel="stylesheet" href="styles/themes/red.css?<?= $version ?>" id="red-theme" <?= $colorTheme != "red" ? "disabled" : "" ?>>
<link rel="stylesheet" href="styles/themes/green.css?<?= $version ?>" id="green-theme" <?= $colorTheme != "green" ? "disabled" : "" ?>>
<link rel="stylesheet" href="styles/themes/yellow.css?<?= $version ?>" id="yellow-theme" <?= $colorTheme != "yellow" ? "disabled" : "" ?>>
<link rel="stylesheet" href="styles/font-awesome.min.css">
<link rel="stylesheet" href="styles/barlow.css">
<link rel="stylesheet" href="styles/login-dark-theme.css?<?= $version ?>" id="dark-theme" <?= $theme == "light" ? "disabled" : "" ?>>
</head>
<body class="<?= $languages[$lang]['dir'] ?>">
<div class="content">
<section class="container">
<header>
<?php
if ($theme == "light") {
?> <img src="images/siteicons/<?= $colorTheme ?>/wallos.png" alt="Wallos Logo" title="Wallos - Subscription Tracker" width="215" /> <?php
} else {
?> <img src="images/siteicons/<?= $colorTheme ?>/walloswhite.png" alt="Wallos Logo" title="Wallos - Subscription Tracker" width="215" /> <?php
}
?>
<p>
<?= translate('reset_password', $i18n) ?>
</p>
</header>
<form action="passwordreset.php?submit=true" method="post">
<?php
if ($requestMode) {
if (!$hideForm) {
?>
<div class="form-group">
<label for="email"><?= translate('email', $i18n) ?>:</label>
<input type="text" id="email" name="email" required>
</div>
<div class="form-group">
<input type="submit" value="<?= translate('reset_password', $i18n) ?>">
</div>
<?php
}
if ($hasSuccessMessage) {
?>
<ul class="success-box">
<li><i class="fa-solid fa-check"></i><?= translate('reset_sent_check_email', $i18n) ?></li>
</ul>
<?php
}
if ($hasErrorMessage) {
?>
<ul class="error-box">
<li><i class="fa-solid fa-triangle-exclamation"></i><?= translate('error', $i18n) ?></li>
</ul>
<?php
}
}
if ($resetMode) {
if (!$hideForm) {
?>
<div class="form-group">
<input type="hidden" name="token" value="<?= $token ?>">
<input type="hidden" name="email" value="<?= $email ?>">
<label for="password"><?= translate('password', $i18n) ?>:</label>
<input type="password" id="password" name="password" required>
</div>
<div class="form-group">
<label for="confirm_password"><?= translate('confirm_password', $i18n) ?>:</label>
<input type="password" id="confirm_password" name="confirm_password" required>
</div>
<div class="form-group">
<input type="submit" value="<?= translate('reset_password', $i18n) ?>">
</div>
<?php
}
if ($hasErrorMessage) {
if ($passwordsMismatch) {
?>
<ul class="error-box">
<li><i class="fa-solid fa-triangle-exclamation"></i><?= translate('passwords_dont_match', $i18n) ?></li>
</ul>
<?php
} else {
?>
<ul class="error-box">
<li><i class="fa-solid fa-triangle-exclamation"></i><?= translate('error', $i18n) ?></li>
</ul>
<?php
}
}
if ($hasSuccessMessage) {
?>
<ul class="success-box">
<li><i class="fa-solid fa-check"></i><?= translate('password_reset_successful', $i18n) ?></li>
</ul>
<?php
}
}
?>
<div class="login-form-link">
<a href="login.php"><?= translate('login', $i18n) ?></a>
</div>
</form>
</section>
</div>
<script type="text/javascript">
function openRegitrationPage() {
window.location.href = "registration.php";
}
</script>
</body>
</html>
?>

View File

@ -16,11 +16,32 @@ function validate($value) {
return $value; return $value;
} }
// If there's already a user on the database, redirect to login page if registrations are closed or maxn users is reached
$stmt = $db->prepare('SELECT COUNT(*) as userCount FROM user');
$result = $stmt->execute();
$userCountResult = $result->fetchArray(SQLITE3_ASSOC);
$userCount = $userCountResult['userCount'];
if ($userCount > 0) { if ($userCount > 0) {
header("Location: login.php"); $stmt = $db->prepare('SELECT * FROM admin');
exit(); $result = $stmt->execute();
$settings = $result->fetchArray(SQLITE3_ASSOC);
if ($settings['registrations_open'] == 0) {
header("Location: login.php");
exit();
}
if ($settings['max_users'] != 0) {
if ($userCount >= $settings['max_users']) {
header("Location: login.php");
exit();
}
}
} }
$theme = "light"; $theme = "light";
if (isset($_COOKIE['theme'])) { if (isset($_COOKIE['theme'])) {
$theme = $_COOKIE['theme']; $theme = $_COOKIE['theme'];
@ -31,16 +52,100 @@ if (isset($_COOKIE['colorTheme'])) {
$colorTheme = $_COOKIE['colorTheme']; $colorTheme = $_COOKIE['colorTheme'];
} }
$currencies = array(); $currencies = [
$query = "SELECT * FROM currencies"; ['id' => 1, 'name' => 'Euro', 'symbol' => '€', 'code' => 'EUR'],
$result = $db->query($query); ['id' => 2, 'name' => 'US Dollar', 'symbol' => '$', 'code' => 'USD'],
while ($row = $result->fetchArray(SQLITE3_ASSOC)) { ['id' => 3, 'name' => 'Japanese Yen', 'symbol' => '¥', 'code' => 'JPY'],
$currencyId = $row['id']; ['id' => 4, 'name' => 'Bulgarian Lev', 'symbol' => 'лв', 'code' => 'BGN'],
$currencies[$currencyId] = $row; ['id' => 5, 'name' => 'Czech Republic Koruna', 'symbol' => 'Kč', 'code' => 'CZK'],
} ['id' => 6, 'name' => 'Danish Krone', 'symbol' => 'kr', 'code' => 'DKK'],
['id' => 7, 'name' => 'British Pound Sterling', 'symbol' => '£', 'code' => 'GBP'],
['id' => 8, 'name' => 'Hungarian Forint', 'symbol' => 'Ft', 'code' => 'HUF'],
['id' => 9, 'name' => 'Polish Zloty', 'symbol' => 'zł', 'code' => 'PLN'],
['id' => 10, 'name' => 'Romanian Leu', 'symbol' => 'lei', 'code' => 'RON'],
['id' => 11, 'name' => 'Swedish Krona', 'symbol' => 'kr', 'code' => 'SEK'],
['id' => 12, 'name' => 'Swiss Franc', 'symbol' => 'Fr', 'code' => 'CHF'],
['id' => 13, 'name' => 'Icelandic Króna', 'symbol' => 'kr', 'code' => 'ISK'],
['id' => 14, 'name' => 'Norwegian Krone', 'symbol' => 'kr', 'code' => 'NOK'],
['id' => 15, 'name' => 'Russian Ruble', 'symbol' => '₽', 'code' => 'RUB'],
['id' => 16, 'name' => 'Turkish Lira', 'symbol' => '₺', 'code' => 'TRY'],
['id' => 17, 'name' => 'Australian Dollar', 'symbol' => '$', 'code' => 'AUD'],
['id' => 18, 'name' => 'Brazilian Real', 'symbol' => 'R$', 'code' => 'BRL'],
['id' => 19, 'name' => 'Canadian Dollar', 'symbol' => '$', 'code' => 'CAD'],
['id' => 20, 'name' => 'Chinese Yuan', 'symbol' => '¥', 'code' => 'CNY'],
['id' => 21, 'name' => 'Hong Kong Dollar', 'symbol' => 'HK$', 'code' => 'HKD'],
['id' => 22, 'name' => 'Indonesian Rupiah', 'symbol' => 'Rp', 'code' => 'IDR'],
['id' => 23, 'name' => 'Israeli New Sheqel', 'symbol' => '₪', 'code' => 'ILS'],
['id' => 24, 'name' => 'Indian Rupee', 'symbol' => '₹', 'code' => 'INR'],
['id' => 25, 'name' => 'South Korean Won', 'symbol' => '₩', 'code' => 'KRW'],
['id' => 26, 'name' => 'Mexican Peso', 'symbol' => 'Mex$', 'code' => 'MXN'],
['id' => 27, 'name' => 'Malaysian Ringgit', 'symbol' => 'RM', 'code' => 'MYR'],
['id' => 28, 'name' => 'New Zealand Dollar', 'symbol' => 'NZ$', 'code' => 'NZD'],
['id' => 29, 'name' => 'Philippine Peso', 'symbol' => '₱', 'code' => 'PHP'],
['id' => 30, 'name' => 'Singapore Dollar', 'symbol' => 'S$', 'code' => 'SGD'],
['id' => 31, 'name' => 'Thai Baht', 'symbol' => '฿', 'code' => 'THB'],
['id' => 32, 'name' => 'South African Rand', 'symbol' => 'R', 'code' => 'ZAR'],
];
$categories = [
['id' => 1, 'name' => 'No category'],
['id' => 2, 'name' => 'Entertainment'],
['id' => 3, 'name' => 'Music'],
['id' => 4, 'name' => 'Utilities'],
['id' => 5, 'name' => 'Food & Beverages'],
['id' => 6, 'name' => 'Health & Wellbeing'],
['id' => 7, 'name' => 'Productivity'],
['id' => 8, 'name' => 'Banking'],
['id' => 9, 'name' => 'Transport'],
['id' => 10, 'name' => 'Education'],
['id' => 11, 'name' => 'Insurance'],
['id' => 12, 'name' => 'Gaming'],
['id' => 13, 'name' => 'News & Magazines'],
['id' => 14, 'name' => 'Software'],
['id' => 15, 'name' => 'Technology'],
['id' => 16, 'name' => 'Cloud Services'],
['id' => 17, 'name' => 'Charity & Donations'],
];
$payment_methods = [
['id' => 1, 'name' => 'PayPal', 'icon' => 'images/uploads/icons/paypal.png'],
['id' => 2, 'name' => 'Credit Card', 'icon' => 'images/uploads/icons/creditcard.png'],
['id' => 3, 'name' => 'Bank Transfer', 'icon' => 'images/uploads/icons/banktransfer.png'],
['id' => 4, 'name' => 'Direct Debit', 'icon' => 'images/uploads/icons/directdebit.png'],
['id' => 5, 'name' => 'Money', 'icon' => 'images/uploads/icons/money.png'],
['id' => 6, 'name' => 'Google Pay', 'icon' => 'images/uploads/icons/googlepay.png'],
['id' => 7, 'name' => 'Samsung Pay', 'icon' => 'images/uploads/icons/samsungpay.png'],
['id' => 8, 'name' => 'Apple Pay', 'icon' => 'images/uploads/icons/applepay.png'],
['id' => 9, 'name' => 'Crypto', 'icon' => 'images/uploads/icons/crypto.png'],
['id' => 10, 'name' => 'Klarna', 'icon' => 'images/uploads/icons/klarna.png'],
['id' => 11, 'name' => 'Amazon Pay', 'icon' => 'images/uploads/icons/amazonpay.png'],
['id' => 12, 'name' => 'SEPA', 'icon' => 'images/uploads/icons/sepa.png'],
['id' => 13, 'name' => 'Skrill', 'icon' => 'images/uploads/icons/skrill.png'],
['id' => 14, 'name' => 'Sofort', 'icon' => 'images/uploads/icons/sofort.png'],
['id' => 15, 'name' => 'Stripe', 'icon' => 'images/uploads/icons/stripe.png'],
['id' => 16, 'name' => 'Affirm', 'icon' => 'images/uploads/icons/affirm.png'],
['id' => 17, 'name' => 'AliPay', 'icon' => 'images/uploads/icons/alipay.png'],
['id' => 18, 'name' => 'Elo', 'icon' => 'images/uploads/icons/elo.png'],
['id' => 19, 'name' => 'Facebook Pay', 'icon' => 'images/uploads/icons/facebookpay.png'],
['id' => 20, 'name' => 'GiroPay', 'icon' => 'images/uploads/icons/giropay.png'],
['id' => 21, 'name' => 'iDeal', 'icon' => 'images/uploads/icons/ideal.png'],
['id' => 22, 'name' => 'Union Pay', 'icon' => 'images/uploads/icons/unionpay.png'],
['id' => 23, 'name' => 'Interac', 'icon' => 'images/uploads/icons/interac.png'],
['id' => 24, 'name' => 'WeChat', 'icon' => 'images/uploads/icons/wechat.png'],
['id' => 25, 'name' => 'Paysafe', 'icon' => 'images/uploads/icons/paysafe.png'],
['id' => 26, 'name' => 'Poli', 'icon' => 'images/uploads/icons/poli.png'],
['id' => 27, 'name' => 'Qiwi', 'icon' => 'images/uploads/icons/qiwi.png'],
['id' => 28, 'name' => 'ShopPay', 'icon' => 'images/uploads/icons/shoppay.png'],
['id' => 29, 'name' => 'Venmo', 'icon' => 'images/uploads/icons/venmo.png'],
['id' => 30, 'name' => 'VeriFone', 'icon' => 'images/uploads/icons/verifone.png'],
['id' => 31, 'name' => 'WebMoney', 'icon' => 'images/uploads/icons/webmoney.png'],
];
$passwordMismatch = false; $passwordMismatch = false;
$usernameExists = false;
$emailExists = false;
$registrationFailed = false; $registrationFailed = false;
$hasErrors = false;
if (isset($_POST['username'])) { if (isset($_POST['username'])) {
$username = validate($_POST['username']); $username = validate($_POST['username']);
$email = validate($_POST['email']); $email = validate($_POST['email']);
@ -52,42 +157,139 @@ if (isset($_POST['username'])) {
if ($password != $confirm_password) { if ($password != $confirm_password) {
$passwordMismatch = true; $passwordMismatch = true;
} else { $hasErrors = true;
$query = "INSERT INTO user (username, email, password, main_currency, avatar, language) VALUES (:username, :email, :password, :main_currency, :avatar, :language)"; }
$emailQuery = "SELECT * FROM user WHERE email = :email";
$stmtEmail = $db->prepare($emailQuery);
$stmtEmail->bindValue(':email', $email, SQLITE3_TEXT);
$resultEmail = $stmtEmail->execute();
if ($resultEmail->fetchArray()) {
$emailExists = true;
$hasErrors = true;
}
$usernameQuery = "SELECT * FROM user WHERE username = :username";
$stmtUsername = $db->prepare($usernameQuery);
$stmtUsername->bindValue(':username', $username, SQLITE3_TEXT);
$resultUsername = $stmtUsername->execute();
if ($resultUsername->fetchArray()) {
$usernameExists = true;
$hasErrors = true;
}
$requireValidation = false;
if ($hasErrors == false) {
$query = "INSERT INTO user (username, email, password, main_currency, avatar, language, budget) VALUES (:username, :email, :password, :main_currency, :avatar, :language, :budget)";
$stmt = $db->prepare($query); $stmt = $db->prepare($query);
$hashedPassword = password_hash($password, PASSWORD_DEFAULT); $hashedPassword = password_hash($password, PASSWORD_DEFAULT);
$stmt->bindValue(':username', $username, SQLITE3_TEXT); $stmt->bindValue(':username', $username, SQLITE3_TEXT);
$stmt->bindValue(':email', $email, SQLITE3_TEXT); $stmt->bindValue(':email', $email, SQLITE3_TEXT);
$stmt->bindValue(':password', $hashedPassword, SQLITE3_TEXT); $stmt->bindValue(':password', $hashedPassword, SQLITE3_TEXT);
$stmt->bindValue(':main_currency', $main_currency, SQLITE3_TEXT); $stmt->bindValue(':main_currency', 1, SQLITE3_TEXT);
$stmt->bindValue(':avatar', $avatar, SQLITE3_TEXT); $stmt->bindValue(':avatar', $avatar, SQLITE3_TEXT);
$stmt->bindValue(':language', $language, SQLITE3_TEXT); $stmt->bindValue(':language', $language, SQLITE3_TEXT);
$stmt->bindValue(':budget', 0, SQLITE3_INTEGER);
$result = $stmt->execute(); $result = $stmt->execute();
if ($result) { if ($result) {
$deleteQuery = "DELETE FROM household";
$stmtDelete = $db->prepare($deleteQuery);
$stmtDelete->execute();
$deleteQuery = "DELETE FROM subscriptions"; // Get id of the newly created user
$stmtDelete = $db->prepare($deleteQuery); $userId = $db->lastInsertRowID();
$stmtDelete->execute();
$deleteQuery = "DELETE FROM fixer"; // Add username as household member for that user
$stmtDelete = $db->prepare($deleteQuery); $query = "INSERT INTO household (name, user_id) VALUES (:name, :user_id)";
$stmtDelete->execute();
$query = "INSERT INTO household (name) VALUES (:name)";
$stmt = $db->prepare($query); $stmt = $db->prepare($query);
$stmt->bindValue(':name', $username, SQLITE3_TEXT); $stmt->bindValue(':name', $username, SQLITE3_TEXT);
$stmt->bindValue(':user_id', $userId, SQLITE3_INTEGER);
$stmt->execute(); $stmt->execute();
if ($userId > 1) {
// Add categories for that user
$query = 'INSERT INTO categories (name, "order", user_id) VALUES (:name, :order, :user_id)';
$stmt = $db->prepare($query);
foreach ($categories as $index => $category) {
$stmt->bindValue(':name', $category['name'], SQLITE3_TEXT);
$stmt->bindValue(':order', $index + 1, SQLITE3_INTEGER);
$stmt->bindValue(':user_id', $userId, SQLITE3_INTEGER);
$stmt->execute();
}
// Add payment methods for that user
$query = 'INSERT INTO payment_methods (name, icon, "order", user_id) VALUES (:name, :icon, :order, :user_id)';
$stmt = $db->prepare($query);
foreach ($payment_methods as $index => $payment_method) {
$stmt->bindValue(':name', $payment_method['name'], SQLITE3_TEXT);
$stmt->bindValue(':icon', $payment_method['icon'], SQLITE3_TEXT);
$stmt->bindValue(':order', $index + 1, SQLITE3_INTEGER);
$stmt->bindValue(':user_id', $userId, SQLITE3_INTEGER);
$stmt->execute();
}
// Add currencies for that user
$query = "INSERT INTO currencies (name, symbol, code, rate, user_id) VALUES (:name, :symbol, :code, :rate, :user_id)";
$stmt = $db->prepare($query);
foreach ($currencies as $currency) {
$stmt->bindValue(':name', $currency['name'], SQLITE3_TEXT);
$stmt->bindValue(':symbol', $currency['symbol'], SQLITE3_TEXT);
$stmt->bindValue(':code', $currency['code'], SQLITE3_TEXT);
$stmt->bindValue(':rate', 1, SQLITE3_FLOAT);
$stmt->bindValue(':user_id', $userId, SQLITE3_INTEGER);
$stmt->execute();
}
// Retrieve main currency id
$query = "SELECT id FROM currencies WHERE code = :code AND user_id = :user_id";
$stmt = $db->prepare($query);
$stmt->bindValue(':code', $main_currency, SQLITE3_TEXT);
$stmt->bindValue(':user_id', $userId, SQLITE3_INTEGER);
$result = $stmt->execute();
$currency = $result->fetchArray(SQLITE3_ASSOC);
// Update user main currency
$query = "UPDATE user SET main_currency = :main_currency WHERE id = :user_id";
$stmt = $db->prepare($query);
$stmt->bindValue(':main_currency', $currency['id'], SQLITE3_INTEGER);
$stmt->bindValue(':user_id', $userId, SQLITE3_INTEGER);
$stmt->execute();
// Add settings for that user
$query = "INSERT INTO settings (dark_theme, monthly_price, convert_currency, remove_background, color_theme, hide_disabled, user_id)
VALUES (0, 0, 0, 0, 'blue', 0, :user_id)";
$stmt = $db->prepare($query);
$stmt->bindValue(':user_id', $userId, SQLITE3_INTEGER);
$stmt->execute();
// If email verification is required add the user to the email_verification table
$query = "SELECT * FROM admin";
$stmt = $db->prepare($query);
$result = $stmt->execute();
$settings = $result->fetchArray(SQLITE3_ASSOC);
if ($settings['require_email_verification'] == 1) {
$query = "INSERT INTO email_verification (user_id, email, token, email_sent) VALUES (:user_id, :email, :token, 0)";
$stmt = $db->prepare($query);
$token = bin2hex(random_bytes(32));
$stmt->bindValue(':user_id', $userId, SQLITE3_INTEGER);
$stmt->bindValue(':token', $token, SQLITE3_TEXT);
$stmt->bindValue(':email', $email, SQLITE3_TEXT);
$stmt->execute();
$requireValidation = true;
}
}
$db->close(); $db->close();
header("Location: login.php"); header("Location: login.php?registered=true&requireValidation=$requireValidation");
exit(); exit();
} else { } else {
$registrationFailed = true; $registrationFailed = true;
} }
} }
} }
?> ?>
<!DOCTYPE html> <!DOCTYPE html>
@ -106,6 +308,7 @@ if (isset($_POST['username'])) {
<link rel="stylesheet" href="styles/themes/green.css?<?= $version ?>" id="green-theme" <?= $colorTheme != "green" ? "disabled" : "" ?>> <link rel="stylesheet" href="styles/themes/green.css?<?= $version ?>" id="green-theme" <?= $colorTheme != "green" ? "disabled" : "" ?>>
<link rel="stylesheet" href="styles/themes/yellow.css?<?= $version ?>" id="yellow-theme" <?= $colorTheme != "yellow" ? "disabled" : "" ?>> <link rel="stylesheet" href="styles/themes/yellow.css?<?= $version ?>" id="yellow-theme" <?= $colorTheme != "yellow" ? "disabled" : "" ?>>
<link rel="stylesheet" href="styles/login-dark-theme.css?<?= $version ?>" id="dark-theme" <?= $theme == "light" ? "disabled" : "" ?>> <link rel="stylesheet" href="styles/login-dark-theme.css?<?= $version ?>" id="dark-theme" <?= $theme == "light" ? "disabled" : "" ?>>
<link rel="stylesheet" href="styles/font-awesome.min.css">
<link rel="stylesheet" href="styles/barlow.css"> <link rel="stylesheet" href="styles/barlow.css">
<script type="text/javascript" src="scripts/registration.js?<?= $version ?>"></script> <script type="text/javascript" src="scripts/registration.js?<?= $version ?>"></script>
</head> </head>
@ -147,7 +350,7 @@ if (isset($_POST['username'])) {
<?php <?php
foreach ($currencies as $currency) { foreach ($currencies as $currency) {
?> ?>
<option value="<?= $currency['id'] ?>"><?= $currency['name'] ?></option> <option value="<?= $currency['code'] ?>"><?= $currency['name'] ?></option>
<?php <?php
} }
?> ?>
@ -166,32 +369,59 @@ if (isset($_POST['username'])) {
?> ?>
</select> </select>
</div> </div>
<?php <?php
if ($passwordMismatch) { if ($hasErrors) {
?> ?>
<sup class="error"> <ul class="error-box">
<?= translate('passwords_dont_match', $i18n) ?> <?php
</sup> if ($passwordMismatch) {
<?php ?>
} <li><i class="fa-solid fa-triangle-exclamation"></i><?= translate('passwords_dont_match', $i18n) ?></li>
?> <?php
<?php }
if ($registrationFailed) { ?>
?> <?php
<sup class="error"> if ($usernameExists) {
<?= translate('registration_failed', $i18n) ?> ?>
</sup> <li><i class="fa-solid fa-triangle-exclamation"></i><?= translate('username_exists', $i18n) ?></li>
<?php
}
?>
<?php
if ($emailExists) {
?>
<li><i class="fa-solid fa-triangle-exclamation"></i><?= translate('email_exists', $i18n) ?></li>
<?php
}
?>
<?php
if ($registrationFailed) {
?>
<li><i class="fa-solid fa-triangle-exclamation"></i><?= translate('registration_failed', $i18n) ?></li>
<?php
}
?>
</ul>
<?php <?php
} }
?> ?>
<div class="form-group"> <div class="form-group">
<input type="submit" value="<?= translate('register', $i18n) ?>"> <input type="submit" value="<?= translate('register', $i18n) ?>">
</div> </div>
</form> </form>
<div class="separator"> <?php
<input type="button" class="secondary-button" value="<?= translate('restore_database', $i18n) ?>" id="restoreDB" onClick="openRestoreDBFileSelect()" /> if ($userCount == 0) {
<input type="file" name="restoreDBFile" id="restoreDBFile" style="display: none;" onChange="restoreDB()" accept=".zip"> ?>
</div> <div class="separator">
<input type="button" class="secondary-button" value="<?= translate('restore_database', $i18n) ?>" id="restoreDB" onClick="openRestoreDBFileSelect()" />
<input type="file" name="restoreDBFile" id="restoreDBFile" style="display: none;" onChange="restoreDB()" accept=".zip">
</div>
<?php
}
?>
</section> </section>
</div> </div>
<?php <?php

View File

@ -1,59 +1,218 @@
function backupDB() { function makeFetchCall(url, data, button) {
const button = document.getElementById("backupDB"); return fetch(url, {
button.disabled = true;
fetch('endpoints/db/backup.php')
.then(response => response.json())
.then(data => {
if (data.success) {
const link = document.createElement('a');
const filename = data.file;
link.href = '.tmp/' + filename;
link.download = 'backup.zip';
document.body.appendChild(link);
link.click();
document.body.removeChild(link);
button.disabled = false;
} else {
showErrorMessage(data.errorMessage);
button.disabled = false;
}
})
.catch(error => {
showErrorMessage(error);
button.disabled = false;
});
}
function openRestoreDBFileSelect() {
document.getElementById('restoreDBFile').click();
};
function restoreDB() {
const input = document.getElementById('restoreDBFile');
const file = input.files[0];
if (!file) {
console.error('No file selected');
return;
}
const formData = new FormData();
formData.append('file', file);
fetch('endpoints/db/restore.php', {
method: 'POST', method: 'POST',
body: formData headers: {
}) 'Content-Type': 'application/json',
},
body: JSON.stringify(data),
})
.then(response => response.json())
.then(data => {
if (data.success) {
showSuccessMessage(data.message);
} else {
showErrorMessage(data.message);
}
button.disabled = false;
})
.catch((error) => {
showErrorMessage(error);
button.disabled = false;
});
}
function testSmtpSettingsButton() {
const button = document.getElementById("testSmtpSettingsButton");
button.disabled = true;
const smtpAddress = document.getElementById("smtpaddress").value;
const smtpPort = document.getElementById("smtpport").value;
const encryption = document.querySelector('input[name="encryption"]:checked').value;
const smtpUsername = document.getElementById("smtpusername").value;
const smtpPassword = document.getElementById("smtppassword").value;
const fromEmail = document.getElementById("fromemail").value;
const data = {
smtpaddress: smtpAddress,
smtpport: smtpPort,
encryption: encryption,
smtpusername: smtpUsername,
smtppassword: smtpPassword,
fromemail: fromEmail
};
makeFetchCall('endpoints/notifications/testemailnotifications.php', data, button);
}
function saveSmtpSettingsButton() {
const button = document.getElementById("saveSmtpSettingsButton");
button.disabled = true;
const smtpAddress = document.getElementById("smtpaddress").value;
const smtpPort = document.getElementById("smtpport").value;
const encryption = document.querySelector('input[name="encryption"]:checked').value;
const smtpUsername = document.getElementById("smtpusername").value;
const smtpPassword = document.getElementById("smtppassword").value;
const fromEmail = document.getElementById("fromemail").value;
const data = {
smtpaddress: smtpAddress,
smtpport: smtpPort,
encryption: encryption,
smtpusername: smtpUsername,
smtppassword: smtpPassword,
fromemail: fromEmail
};
fetch('endpoints/admin/savesmtpsettings.php', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
},
body: JSON.stringify(data),
})
.then(response => response.json())
.then(data => {
if (data.success) {
const emailVerificationCheckbox = document.getElementById('requireEmail');
emailVerificationCheckbox.disabled = false;
showSuccessMessage(data.message);
} else {
showErrorMessage(data.message);
}
button.disabled = false;
})
.catch((error) => {
showErrorMessage(error);
button.disabled = false;
});
}
function backupDB() {
const button = document.getElementById("backupDB");
button.disabled = true;
fetch('endpoints/db/backup.php')
.then(response => response.json()) .then(response => response.json())
.then(data => { .then(data => {
if (data.success) { if (data.success) {
showSuccessMessage(data.message) const link = document.createElement('a');
window.location.href = 'logout.php'; const filename = data.file;
link.href = '.tmp/' + filename;
link.download = 'backup.zip';
document.body.appendChild(link);
link.click();
document.body.removeChild(link);
button.disabled = false;
} else { } else {
showErrorMessage(data.message); showErrorMessage(data.errorMessage);
button.disabled = false;
} }
}) })
.catch(error => showErrorMessage('Error:', error)); .catch(error => {
} showErrorMessage(error);
button.disabled = false;
});
}
function openRestoreDBFileSelect() {
document.getElementById('restoreDBFile').click();
};
function restoreDB() {
const input = document.getElementById('restoreDBFile');
const file = input.files[0];
if (!file) {
console.error('No file selected');
return;
}
const formData = new FormData();
formData.append('file', file);
fetch('endpoints/db/restore.php', {
method: 'POST',
body: formData
})
.then(response => response.json())
.then(data => {
if (data.success) {
showSuccessMessage(data.message)
window.location.href = 'logout.php';
} else {
showErrorMessage(data.message);
}
})
.catch(error => showErrorMessage('Error:', error));
}
function saveAccountRegistrationsButton () {
const button = document.getElementById('saveAccountRegistrations');
button.disabled = true;
const open_registrations = document.getElementById('registrations').checked ? 1 : 0;
const max_users = document.getElementById('maxUsers').value;
const require_email_validation = document.getElementById('requireEmail').checked ? 1 : 0;
const server_url = document.getElementById('serverUrl').value;
const data = {
open_registrations: open_registrations,
max_users: max_users,
require_email_validation: require_email_validation,
server_url: server_url
};
fetch('endpoints/admin/saveopenregistrations.php', {
method: 'POST',
headers: {
'Content-Type': 'application/json'
},
body: JSON.stringify(data)
})
.then(response => response.json())
.then(data => {
if (data.success) {
showSuccessMessage(data.message);
button.disabled = false;
} else {
showErrorMessage(data.message);
button.disabled = false;
}
})
.catch(error => {
showErrorMessage(error);
button.disabled = false;
});
}
function removeUser(userId) {
const data = {
userId: userId
};
fetch('endpoints/admin/deleteuser.php', {
method: 'POST',
headers: {
'Content-Type': 'application/json'
},
body: JSON.stringify(data)
})
.then(response => response.json())
.then(data => {
if (data.success) {
showSuccessMessage(data.message);
const userContainer = document.querySelector(`.form-group-inline[data-userid="${userId}"]`);
if (userContainer) {
userContainer.remove();
}
} else {
showErrorMessage(data.message);
}
})
.catch(error => showErrorMessage('Error:', error));
}

View File

@ -28,6 +28,7 @@ self.addEventListener('install', function(event) {
'scripts/settings.js', 'scripts/settings.js',
'scripts/notifications.js', 'scripts/notifications.js',
'scripts/registration.js', 'scripts/registration.js',
'scripts/admin.js',
'scripts/i18n/en.js', 'scripts/i18n/en.js',
'scripts/i18n/de.js', 'scripts/i18n/de.js',
'scripts/i18n/el.js', 'scripts/i18n/el.js',

View File

@ -52,7 +52,7 @@
<div class="grow"> <div class="grow">
<div class="form-group"> <div class="form-group">
<label for="username"><?= translate('username', $i18n) ?>:</label> <label for="username"><?= translate('username', $i18n) ?>:</label>
<input type="text" id="username" name="username" value="<?= $userData['username'] ?>" required> <input type="text" id="username" name="username" value="<?= $userData['username'] ?>" disabled>
</div> </div>
<div class="form-group"> <div class="form-group">
<label for="email"><?= translate('email', $i18n) ?>:</label> <label for="email"><?= translate('email', $i18n) ?>:</label>
@ -68,8 +68,10 @@
</div> </div>
<?php <?php
$currencies = array(); $currencies = array();
$query = "SELECT * FROM currencies"; $query = "SELECT * FROM currencies WHERE user_id = :userId";
$result = $db->query($query); $query = $db->prepare($query);
$query->bindValue(':userId', $userId, SQLITE3_INTEGER);
$result = $query->execute();
while ($row = $result->fetchArray(SQLITE3_ASSOC)) { while ($row = $result->fetchArray(SQLITE3_ASSOC)) {
$currencyId = $row['id']; $currencyId = $row['id'];
$currencies[$currencyId] = $row; $currencies[$currencyId] = $row;
@ -135,8 +137,10 @@
</section> </section>
<?php <?php
$sql = "SELECT * FROM household"; $sql = "SELECT * FROM household WHERE user_id = :userId";
$result = $db->query($sql); $stmt = $db->prepare($sql);
$stmt->bindValue(':userId', $userId, SQLITE3_INTEGER);
$result = $stmt->execute();
if ($result) { if ($result) {
$household = array(); $household = array();
@ -153,12 +157,12 @@
<div class="account-members"> <div class="account-members">
<div id="householdMembers"> <div id="householdMembers">
<?php <?php
foreach ($household as $member) { foreach ($household as $index => $member) {
?> ?>
<div class="form-group-inline" data-memberid="<?= $member['id'] ?>"> <div class="form-group-inline" data-memberid="<?= $member['id'] ?>">
<input type="text" name="member" value="<?= $member['name'] ?>" placeholder="Member"> <input type="text" name="member" value="<?= $member['name'] ?>" placeholder="Member">
<?php <?php
if ($member['id'] !== 1) { if ($index !== 0) {
?> ?>
<input type="text" name="email" value="<?= $member['email'] ?? "" ?>" placeholder="<?= translate("email", $i18n) ?>"> <input type="text" name="email" value="<?= $member['email'] ?? "" ?>" placeholder="<?= translate("email", $i18n) ?>">
<?php <?php
@ -168,7 +172,7 @@
<img src="images/siteicons/<?= $colorTheme ?>/save.png" title="<?= translate('save_member', $i18n) ?>"> <img src="images/siteicons/<?= $colorTheme ?>/save.png" title="<?= translate('save_member', $i18n) ?>">
</button> </button>
<?php <?php
if ($member['id'] != 1) { if ($index !== 0) {
?> ?>
<button class="image-button medium" onClick="removeMember(<?= $member['id'] ?>)"> <button class="image-button medium" onClick="removeMember(<?= $member['id'] ?>)">
<img src="images/siteicons/<?= $colorTheme ?>/delete.png" title="<?= translate('delete_member', $i18n) ?>"> <img src="images/siteicons/<?= $colorTheme ?>/delete.png" title="<?= translate('delete_member', $i18n) ?>">
@ -200,8 +204,10 @@
<?php <?php
// Notification settings // Notification settings
$sql = "SELECT * FROM notification_settings LIMIT 1"; $sql = "SELECT * FROM notification_settings WHERE user_id = :userId LIMIT 1";
$result = $db->query($sql); $stmt = $db->prepare($sql);
$stmt->bindValue(':userId', $userId, SQLITE3_INTEGER);
$result = $stmt->execute();
$rowCount = 0; $rowCount = 0;
while ($row = $result->fetchArray(SQLITE3_ASSOC)) { while ($row = $result->fetchArray(SQLITE3_ASSOC)) {
@ -214,8 +220,10 @@
} }
// Email notifications // Email notifications
$sql = "SELECT * FROM email_notifications LIMIT 1"; $sql = "SELECT * FROM email_notifications WHERE user_id = :userId LIMIT 1";
$result = $db->query($sql); $stmt = $db->prepare($sql);
$stmt->bindValue(':userId', $userId, SQLITE3_INTEGER);
$result = $stmt->execute();
$rowCount = 0; $rowCount = 0;
while ($row = $result->fetchArray(SQLITE3_ASSOC)) { while ($row = $result->fetchArray(SQLITE3_ASSOC)) {
@ -240,8 +248,10 @@
} }
// Discord notifications // Discord notifications
$sql = "SELECT * FROM discord_notifications LIMIT 1"; $sql = "SELECT * FROM discord_notifications WHERE user_id = :userId LIMIT 1";
$result = $db->query($sql); $stmt = $db->prepare($sql);
$stmt->bindValue(':userId', $userId, SQLITE3_INTEGER);
$result = $stmt->execute();
$rowCount = 0; $rowCount = 0;
while ($row = $result->fetchArray(SQLITE3_ASSOC)) { while ($row = $result->fetchArray(SQLITE3_ASSOC)) {
@ -260,8 +270,10 @@
} }
// Pushover notifications // Pushover notifications
$sql = "SELECT * FROM pushover_notifications LIMIT 1"; $sql = "SELECT * FROM pushover_notifications WHERE user_id = :userId LIMIT 1";
$result = $db->query($sql); $stmt = $db->prepare($sql);
$stmt->bindValue(':userId', $userId, SQLITE3_INTEGER);
$result = $stmt->execute();
$rowCount = 0; $rowCount = 0;
while ($row = $result->fetchArray(SQLITE3_ASSOC)) { while ($row = $result->fetchArray(SQLITE3_ASSOC)) {
@ -278,8 +290,10 @@
} }
// Telegram notifications // Telegram notifications
$sql = "SELECT * FROM telegram_notifications LIMIT 1"; $sql = "SELECT * FROM telegram_notifications WHERE user_id = :userId LIMIT 1";
$result = $db->query($sql); $stmt = $db->prepare($sql);
$stmt->bindValue(':userId', $userId, SQLITE3_INTEGER);
$result = $stmt->execute();
$rowCount = 0; $rowCount = 0;
while ($row = $result->fetchArray(SQLITE3_ASSOC)) { while ($row = $result->fetchArray(SQLITE3_ASSOC)) {
@ -296,9 +310,10 @@
} }
// Webhook notifications // Webhook notifications
$sql = "SELECT * FROM webhook_notifications LIMIT 1"; $sql = "SELECT * FROM webhook_notifications WHERE user_id = :userId LIMIT 1";
$result = $db->query($sql); $stmt = $db->prepare($sql);
$stmt->bindValue(':userId', $userId, SQLITE3_INTEGER);
$result = $stmt->execute();
$rowCount = 0; $rowCount = 0;
while ($row = $result->fetchArray(SQLITE3_ASSOC)) { while ($row = $result->fetchArray(SQLITE3_ASSOC)) {
$notificationsWebhook['enabled'] = $row['enabled']; $notificationsWebhook['enabled'] = $row['enabled'];
@ -335,8 +350,10 @@
} }
// Gotify notifications // Gotify notifications
$sql = "SELECT * FROM gotify_notifications LIMIT 1"; $sql = "SELECT * FROM gotify_notifications WHERE user_id = :userId LIMIT 1";
$result = $db->query($sql); $stmt = $db->prepare($sql);
$stmt->bindValue(':userId', $userId, SQLITE3_INTEGER);
$result = $stmt->execute();
$rowCount = 0; $rowCount = 0;
while ($row = $result->fetchArray(SQLITE3_ASSOC)) { while ($row = $result->fetchArray(SQLITE3_ASSOC)) {
@ -569,8 +586,10 @@
</section> </section>
<?php <?php
$sql = "SELECT * FROM categories ORDER BY `order` ASC"; $sql = "SELECT * FROM categories WHERE user_id = :userId ORDER BY `order` ASC";
$result = $db->query($sql); $stmt = $db->prepare($sql);
$stmt->bindValue(':userId', $userId, SQLITE3_INTEGER);
$result = $stmt->execute();
if ($result) { if ($result) {
$categories = array(); $categories = array();
@ -591,9 +610,10 @@
if ($category['id'] != 1) { if ($category['id'] != 1) {
$canDelete = true; $canDelete = true;
$query = "SELECT COUNT(*) as count FROM subscriptions WHERE category_id = :categoryId"; $query = "SELECT COUNT(*) as count FROM subscriptions WHERE category_id = :categoryId AND user_id = :userId";
$stmt = $db->prepare($query); $stmt = $db->prepare($query);
$stmt->bindParam(':categoryId', $category['id'], SQLITE3_INTEGER); $stmt->bindParam(':categoryId', $category['id'], SQLITE3_INTEGER);
$stmt->bindParam(':userId', $userId, SQLITE3_INTEGER);
$result = $stmt->execute(); $result = $stmt->execute();
$row = $result->fetchArray(SQLITE3_ASSOC); $row = $result->fetchArray(SQLITE3_ASSOC);
$isUsed = $row['count']; $isUsed = $row['count'];
@ -636,8 +656,10 @@
</section> </section>
<?php <?php
$sql = "SELECT * FROM currencies"; $sql = "SELECT * FROM currencies WHERE user_id = :userId";
$result = $db->query($sql); $stmt = $db->prepare($sql);
$stmt->bindValue(':userId', $userId, SQLITE3_INTEGER);
$result = $stmt->execute();
if ($result) { if ($result) {
$currencies = array(); $currencies = array();
@ -646,8 +668,9 @@
} }
} }
$query = "SELECT main_currency FROM user WHERE id = 1"; $query = "SELECT main_currency FROM user WHERE id = :userId";
$stmt = $db->prepare($query); $stmt = $db->prepare($query);
$stmt->bindParam(':userId', $userId, SQLITE3_INTEGER);
$result = $stmt->execute(); $result = $stmt->execute();
$row = $result->fetchArray(SQLITE3_ASSOC); $row = $result->fetchArray(SQLITE3_ASSOC);
$mainCurrencyId = $row['main_currency']; $mainCurrencyId = $row['main_currency'];
@ -743,8 +766,10 @@
<?php <?php
$apiKey = ""; $apiKey = "";
$sql = "SELECT api_key, provider FROM fixer"; $sql = "SELECT api_key, provider FROM fixer WHERE user_id = :userId";
$result = $db->query($sql); $stmt = $db->prepare($sql);
$stmt->bindValue(':userId', $userId, SQLITE3_INTEGER);
$result = $stmt->execute();
if ($result) { if ($result) {
$row = $result->fetchArray(SQLITE3_ASSOC); $row = $result->fetchArray(SQLITE3_ASSOC);
if ($row) { if ($row) {
@ -798,8 +823,10 @@
</section> </section>
<?php <?php
$sql = "SELECT * FROM payment_methods ORDER BY `order` ASC"; $sql = "SELECT * FROM payment_methods WHERE user_id = :userId ORDER BY `order` ASC";
$result = $db->query($sql); $stmt = $db->prepare($sql);
$stmt->bindValue(':userId', $userId, SQLITE3_INTEGER);
$result = $stmt->execute();
if ($result) { if ($result) {
$payments = array(); $payments = array();
@ -815,14 +842,18 @@
</header> </header>
<div class="payments-list" id="payments-list"> <div class="payments-list" id="payments-list">
<?php <?php
$paymentsInUseQuery = $db->query('SELECT id FROM payment_methods WHERE id IN (SELECT DISTINCT payment_method_id FROM subscriptions)'); $paymentsInUseQuery = $db->prepare('SELECT id FROM payment_methods WHERE user_id = :userId AND id IN (SELECT DISTINCT payment_method_id FROM subscriptions WHERE user_id = :userId)');
$paymentsInUseQuery->bindValue(':userId', $userId, SQLITE3_INTEGER);
$result = $paymentsInUseQuery->execute();
$paymentsInUse = []; $paymentsInUse = [];
while ($row = $paymentsInUseQuery->fetchArray(SQLITE3_ASSOC)) { while ($row = $result->fetchArray(SQLITE3_ASSOC)) {
$paymentsInUse[] = $row['id']; $paymentsInUse[] = $row['id'];
} }
foreach ($payments as $payment) { foreach ($payments as $payment) {
$paymentIconFolder = $payment['id'] <= 31 ? 'images/uploads/icons/' : 'images/uploads/logos/'; $paymentIconFolder = (strpos($payment['icon'], 'images/uploads/icons/') !== false) ? "" : "images/uploads/logos/";
$inUse = in_array($payment['id'], $paymentsInUse); $inUse = in_array($payment['id'], $paymentsInUse);
?> ?>
<div class="payments-payment" <div class="payments-payment"

View File

@ -24,9 +24,10 @@
function getPriceConverted($price, $currency, $database) { function getPriceConverted($price, $currency, $database) {
$query = "SELECT rate FROM currencies WHERE id = :currency"; $query = "SELECT rate FROM currencies WHERE id = :currency AND user_id = :userId";
$stmt = $database->prepare($query); $stmt = $database->prepare($query);
$stmt->bindParam(':currency', $currency, SQLITE3_INTEGER); $stmt->bindParam(':currency', $currency, SQLITE3_INTEGER);
$stmt->bindParam(':userId', $userId, SQLITE3_INTEGER);
$result = $stmt->execute(); $result = $stmt->execute();
$exchangeRate = $result->fetchArray(SQLITE3_ASSOC); $exchangeRate = $result->fetchArray(SQLITE3_ASSOC);
@ -40,8 +41,10 @@
//Get household members //Get household members
$members = array(); $members = array();
$query = "SELECT * FROM household"; $query = "SELECT * FROM household WHERE user_id = :userId";
$result = $db->query($query); $stmt = $db->prepare($query);
$stmt->bindValue(':userId', $userId, SQLITE3_INTEGER);
$result = $stmt->execute();
while ($row = $result->fetchArray(SQLITE3_ASSOC)) { while ($row = $result->fetchArray(SQLITE3_ASSOC)) {
$memberId = $row['id']; $memberId = $row['id'];
$members[$memberId] = $row; $members[$memberId] = $row;
@ -51,8 +54,10 @@ while ($row = $result->fetchArray(SQLITE3_ASSOC)) {
// Get categories // Get categories
$categories = array(); $categories = array();
$query = "SELECT * FROM categories ORDER BY 'order' ASC"; $query = "SELECT * FROM categories WHERE user_id = :userId ORDER BY 'order' ASC";
$result = $db->query($query); $stmt = $db->prepare($query);
$stmt->bindValue(':userId', $userId, SQLITE3_INTEGER);
$result = $stmt->execute();
while ($row = $result->fetchArray(SQLITE3_ASSOC)) { while ($row = $result->fetchArray(SQLITE3_ASSOC)) {
$categoryId = $row['id']; $categoryId = $row['id'];
$categories[$categoryId] = $row; $categories[$categoryId] = $row;
@ -62,8 +67,10 @@ while ($row = $result->fetchArray(SQLITE3_ASSOC)) {
// Get payment methods // Get payment methods
$paymentMethodCount = array(); $paymentMethodCount = array();
$query = "SELECT * FROM payment_methods WHERE enabled = 1"; $query = "SELECT * FROM payment_methods WHERE user_id = :userId AND enabled = 1";
$result = $db->query($query); $stmt = $db->prepare($query);
$stmt->bindValue(':userId', $userId, SQLITE3_INTEGER);
$result = $stmt->execute();
while ($row = $result->fetchArray(SQLITE3_ASSOC)) { while ($row = $result->fetchArray(SQLITE3_ASSOC)) {
$paymentMethodId = $row['id']; $paymentMethodId = $row['id'];
$paymentMethodCount[$paymentMethodId] = $row; $paymentMethodCount[$paymentMethodId] = $row;
@ -75,8 +82,9 @@ while ($row = $result->fetchArray(SQLITE3_ASSOC)) {
$query = "SELECT c.code $query = "SELECT c.code
FROM currencies c FROM currencies c
INNER JOIN user u ON c.id = u.main_currency INNER JOIN user u ON c.id = u.main_currency
WHERE u.id = 1"; WHERE u.id = :userId";
$stmt = $db->prepare($query); $stmt = $db->prepare($query);
$stmt->bindValue(':userId', $userId, SQLITE3_INTEGER);
$result = $stmt->execute(); $result = $stmt->execute();
$row = $result->fetchArray(SQLITE3_ASSOC); $row = $result->fetchArray(SQLITE3_ASSOC);
$code = $row['code']; $code = $row['code'];
@ -113,6 +121,9 @@ if (isset($_GET['payment'])) {
$statsSubtitleParts[] = $paymentMethodCount[$_GET['payment']]['name']; $statsSubtitleParts[] = $paymentMethodCount[$_GET['payment']]['name'];
} }
$conditions[] = "user_id = :userId";
$params[':userId'] = $userId;
if (!empty($conditions)) { if (!empty($conditions)) {
$query .= " WHERE " . implode(' AND ', $conditions); $query .= " WHERE " . implode(' AND ', $conditions);
} }
@ -398,28 +409,32 @@ $numberOfElements = 6;
</div> </div>
<?php <?php
$categoryDataPoints = []; $categoryDataPoints = [];
foreach ($categoryCost as $category) { if (isset($categoryCost)) {
if ($category['cost'] != 0) { foreach ($categoryCost as $category) {
$categoryDataPoints[] = [ if ($category['cost'] != 0) {
"label" => $category['name'], $categoryDataPoints[] = [
"y" => $category["cost"], "label" => $category['name'],
]; "y" => $category["cost"],
];
}
} }
} }
$showCategoryCostGraph = count($categoryDataPoints) > 1; $showCategoryCostGraph = count($categoryDataPoints) > 1;
$memberDataPoints = []; $memberDataPoints = [];
foreach ($memberCost as $member) { if (isset($memberCost)) {
if ($member['cost'] != 0) { foreach ($memberCost as $member) {
$memberDataPoints[] = [ if ($member['cost'] != 0) {
"label" => $member['name'], $memberDataPoints[] = [
"y" => $member["cost"], "label" => $member['name'],
]; "y" => $member["cost"],
];
}
} }
} }
$showMemberCostGraph = count($memberDataPoints) > 1; $showMemberCostGraph = count($memberDataPoints) > 1;
$paymentMethodDataPoints = []; $paymentMethodDataPoints = [];

View File

@ -45,6 +45,16 @@ body, html {
text-align: center; text-align: center;
} }
.container > .message {
text-align: center;
font-size: 18px;
}
.container > .message a {
color: var(--main-color);
text-decoration: none;
}
h2 { h2 {
text-align: center; text-align: center;
margin-bottom: 20px; margin-bottom: 20px;
@ -144,11 +154,53 @@ input[type="checkbox"] {
margin-bottom: 20px; margin-bottom: 20px;
} }
.error-box,
.success-box {
display: block;
color: #FFFFFF;
margin-bottom: 20px;
padding: 14px 14px 16px 14px;
border: 1px solid var(--error-color);
background-color: rgba(var(--error-color-rgb), 0.8);
border-radius: 8px;
}
.success-box {
border: 1px solid var(--success-color);
background-color: rgba(var(--success-color-rgb), 0.5);
}
.error-box li,
.success-box li {
list-style: none;
font-size: 15px;
display: flex;
gap: 8px;
align-items: baseline;
margin-bottom: 5px;
}
.error-box li:last-of-type,
.success-box li:last-of-type {
margin-bottom: 0px;
}
.separator { .separator {
border-top: 1px solid #ccc; border-top: 1px solid #ccc;
padding-top: 20px; padding-top: 20px;
} }
.login-form-link {
text-align: center;
margin: 20px 0px;
}
.login-form-link a {
color: var(--main-color);
text-decoration: none;
font-size: 16px;
}
/* TOAST MESSAGE */ /* TOAST MESSAGE */
.toast { .toast {

View File

@ -662,7 +662,8 @@ header #avatar {
.account-currencies .buttons, .account-currencies .buttons,
.account-fixer .buttons, .account-fixer .buttons,
.account-categories .buttons, .account-categories .buttons,
.account-notifications .buttons { .account-notifications .buttons,
.admin-form .buttons {
display: flex; display: flex;
justify-content: flex-end; justify-content: flex-end;
align-items: center; align-items: center;
@ -814,6 +815,14 @@ header #avatar {
margin: 0px; margin: 0px;
} }
.settings-notes {
margin-bottom: 1.5em;
}
.settings-notes > p {
margin-bottom: 0px;
}
.credits-list > p > span, .credits-list > p > span,
.settings-notes > p > span { .settings-notes > p > span {
color: #AAA; color: #AAA;
@ -1545,6 +1554,8 @@ textarea.thin {
.statistic > .subtitle > img { .statistic > .subtitle > img {
width: 100px; width: 100px;
max-height: 40px;
object-fit: contain;
} }
.graphs { .graphs {
@ -1841,4 +1852,39 @@ textarea.thin {
.wrap { .wrap {
flex-wrap: wrap; flex-wrap: wrap;
}
.user-list {
display: flex;
flex-direction: column;
flex-wrap: wrap;
justify-content: space-between;
}
.user-list > div {
display: flex;
flex-direction: row;
flex-grow: 1;
}
.user-list .user-list-row {
display: flex;
flex-direction: row;
flex-grow: 1;
}
.user-list .user-list-row:last-of-type {
flex-grow: 0;
}
.user-list .user-list-row > div {
display: flex;
flex-basis: 50%;
gap: 12px;
align-items: baseline;
}
.user-list a {
color: var(--main-color);
text-decoration: none;
} }

120
verifyemail.php Normal file
View File

@ -0,0 +1,120 @@
<?php
require_once 'includes/connect.php';
require_once 'includes/checkuser.php';
require_once 'includes/i18n/languages.php';
require_once 'includes/i18n/getlang.php';
require_once 'includes/i18n/' . $lang . '.php';
require_once 'includes/version.php';
if ($userCount == 0) {
header("Location: registration.php");
exit();
}
session_start();
if (isset($_SESSION['loggedin']) && $_SESSION['loggedin'] === true) {
$db->close();
header("Location: .");
exit();
}
$theme = "light";
if (isset($_COOKIE['theme'])) {
$theme = $_COOKIE['theme'];
}
$colorTheme = "blue";
if (isset($_COOKIE['colorTheme'])) {
$colorTheme = $_COOKIE['colorTheme'];
}
$validated = false;
if (isset($_GET['email']) && isset($_GET['token'])) {
$email = $_GET['email'];
$token = $_GET['token'];
$query = "SELECT * FROM email_verification WHERE email = :email AND token = :token";
$stmt = $db->prepare($query);
$stmt->bindValue(':email', $email, SQLITE3_TEXT);
$stmt->bindValue(':token', $token, SQLITE3_TEXT);
$result = $stmt->execute();
$row = $result->fetchArray(SQLITE3_ASSOC);
if ($row) {
$query = "DELETE FROM email_verification WHERE email = :email AND token = :token";
$stmt = $db->prepare($query);
$stmt->bindValue(':email', $email, SQLITE3_TEXT);
$stmt->bindValue(':token', $token, SQLITE3_TEXT);
$stmt->execute();
$validated = true;
header("Location: login.php?validated=true");
exit;
} else {
$query = "SELECT require_email_verification FROM admin";
$stmt = $db->prepare($query);
$result = $stmt->execute();
$settings = $result->fetchArray(SQLITE3_ASSOC);
if ($settings['require_email_verification'] != 1) {
header("Location: .");
exit;
}
}
}
?>
<!DOCTYPE html>
<html dir="<?= $languages[$lang]['dir'] ?>">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no">
<meta name="theme-color" content="<?= $theme == "light" ? "#FFFFFF" : "#222222" ?>"/>
<title>Wallos - Subscription Tracker</title>
<link rel="icon" type="image/png" href="images/icon/favicon.ico" sizes="16x16">
<link rel="apple-touch-icon" sizes="180x180" href="images/icon/apple-touch-icon.png">
<link rel="manifest" href="manifest.json">
<link rel="stylesheet" href="styles/theme.css?<?= $version ?>">
<link rel="stylesheet" href="styles/login.css?<?= $version ?>">
<link rel="stylesheet" href="styles/themes/red.css?<?= $version ?>" id="red-theme" <?= $colorTheme != "red" ? "disabled" : "" ?>>
<link rel="stylesheet" href="styles/themes/green.css?<?= $version ?>" id="green-theme" <?= $colorTheme != "green" ? "disabled" : "" ?>>
<link rel="stylesheet" href="styles/themes/yellow.css?<?= $version ?>" id="yellow-theme" <?= $colorTheme != "yellow" ? "disabled" : "" ?>>
<link rel="stylesheet" href="styles/font-awesome.min.css">
<link rel="stylesheet" href="styles/barlow.css">
<link rel="stylesheet" href="styles/login-dark-theme.css?<?= $version ?>" id="dark-theme" <?= $theme == "light" ? "disabled" : "" ?>>
</head>
<body class="<?= $languages[$lang]['dir'] ?>">
<div class="content">
<section class="container">
<header>
<?php
if ($theme == "light") {
?> <img src="images/siteicons/<?= $colorTheme ?>/wallos.png" alt="Wallos Logo" title="Wallos - Subscription Tracker" width="215" /> <?php
} else {
?> <img src="images/siteicons/<?= $colorTheme ?>/walloswhite.png" alt="Wallos Logo" title="Wallos - Subscription Tracker" width="215" /> <?php
}
?>
</header>
<div class="message">
<?php
if ($validated == false) {
?>
<ul class="error-box">
<li><i class="fa-solid fa-triangle-exclamation"></i><?= translate('email_verification_failed', $i18n) ?></li>
</ul>
<?php
}
?>
</div>
<div class="separator"></div>
<input type="button" class="button" onclick="window.location.href='login.php'" value="<?= translate('login', $i18n) ?>"></input>
</section>
</div>
</body>
</html>