diff --git a/README.md b/README.md index ad54927..4750958 100644 --- a/README.md +++ b/README.md @@ -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 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 +*/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. diff --git a/admin.php b/admin.php index 0f3eaab..993d730 100644 --- a/admin.php +++ b/admin.php @@ -1,12 +1,183 @@ 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; + ?>
+
+
+

+
+
+
+ /> + +
+
+ + +
+
+

+ + +

+
+
+ /> + +
+ +
+

+ + +

+
+ +
+ + +
+
+

+ + +

+

+ + +

+
+
+ +
+
+
+ + = 0) { + ?> + +
+
+

+
+
+ +
+
+
+
+ +
+
+
+ + + + + + +
+
+ +
+
+

+ + +

+
+
+ + + +
+
+

+
+
+
+ + +
+
+ /> + + /> + +
+
+ +
+
+ +
+
+ +
+
+

+ +

+

+ + +

+
+
+ + +
+
+
+ +

diff --git a/cronjobs b/cronjobs index 0360361..500cc7b 100644 --- a/cronjobs +++ b/cronjobs @@ -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 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 +*/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 diff --git a/endpoints/admin/deleteuser.php b/endpoints/admin/deleteuser.php new file mode 100644 index 0000000..44009da --- /dev/null +++ b/endpoints/admin/deleteuser.php @@ -0,0 +1,132 @@ + 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) + ])); +} + +?> \ No newline at end of file diff --git a/endpoints/admin/saveopenregistrations.php b/endpoints/admin/saveopenregistrations.php new file mode 100644 index 0000000..159cd59 --- /dev/null +++ b/endpoints/admin/saveopenregistrations.php @@ -0,0 +1,59 @@ + 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) + ]); + } +} + +?> \ No newline at end of file diff --git a/endpoints/admin/savesmtpsettings.php b/endpoints/admin/savesmtpsettings.php new file mode 100644 index 0000000..5b040c4 --- /dev/null +++ b/endpoints/admin/savesmtpsettings.php @@ -0,0 +1,64 @@ + 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) + ])); + } + +} + +?> \ No newline at end of file diff --git a/endpoints/categories/category.php b/endpoints/categories/category.php index 21ac2ac..cb70f08 100644 --- a/endpoints/categories/category.php +++ b/endpoints/categories/category.php @@ -2,11 +2,10 @@ require_once '../../includes/connect_endpoint.php'; require_once '../../includes/inputvalidation.php'; -session_start(); - if (isset($_SESSION['loggedin']) && $_SESSION['loggedin'] === true) { 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(); $row = $result->fetchArray(SQLITE3_ASSOC); $maxOrder = $row['maxOrder']; @@ -18,10 +17,11 @@ if (isset($_SESSION['loggedin']) && $_SESSION['loggedin'] === true) { $order = $maxOrder + 1; $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->bindParam(':name', $categoryName, SQLITE3_TEXT); $stmtInsert->bindParam(':order', $order, SQLITE3_INTEGER); + $stmtInsert->bindParam(':userId', $userId, SQLITE3_INTEGER); $resultInsert = $stmtInsert->execute(); if ($resultInsert) { @@ -42,10 +42,11 @@ if (isset($_SESSION['loggedin']) && $_SESSION['loggedin'] === true) { if (isset($_GET['categoryId']) && $_GET['categoryId'] != "" && isset($_GET['name']) && $_GET['name'] != "") { $categoryId = $_GET['categoryId']; $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->bindParam(':name', $name, SQLITE3_TEXT); $stmt->bindParam(':categoryId', $categoryId, SQLITE3_INTEGER); + $stmt->bindParam(':userId', $userId, SQLITE3_INTEGER); $result = $stmt->execute(); if ($result) { @@ -71,9 +72,10 @@ if (isset($_SESSION['loggedin']) && $_SESSION['loggedin'] === true) { } else if (isset($_GET['action']) && $_GET['action'] == "delete") { if (isset($_GET['categoryId']) && $_GET['categoryId'] != "" && $_GET['categoryId'] != 1) { $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->bindParam(':categoryId', $categoryId, SQLITE3_INTEGER); + $checkStmt->bindParam(':userId', $userId, SQLITE3_INTEGER); $checkResult = $checkStmt->execute(); $row = $checkResult->fetchArray(); $count = $row[0]; @@ -85,9 +87,10 @@ if (isset($_SESSION['loggedin']) && $_SESSION['loggedin'] === true) { ]; echo json_encode($response); } else { - $sql = "DELETE FROM categories WHERE id = :categoryId"; + $sql = "DELETE FROM categories WHERE id = :categoryId AND user_id = :userId"; $stmt = $db->prepare($sql); $stmt->bindParam(':categoryId', $categoryId, SQLITE3_INTEGER); + $stmt->bindParam(':userId', $userId, SQLITE3_INTEGER); $result = $stmt->execute(); if ($result) { $response = [ diff --git a/endpoints/categories/sort.php b/endpoints/categories/sort.php index 9552226..1da4277 100644 --- a/endpoints/categories/sort.php +++ b/endpoints/categories/sort.php @@ -2,17 +2,16 @@ require_once '../../includes/connect_endpoint.php'; -session_start(); - if (isset($_SESSION['loggedin']) && $_SESSION['loggedin'] === true) { $categories = $_POST['categoryIds']; $order = 2; 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->bindParam(':order', $order, SQLITE3_INTEGER); $stmt->bindParam(':categoryId', $categoryId, SQLITE3_INTEGER); + $stmt->bindParam(':userId', $userId, SQLITE3_INTEGER); $result = $stmt->execute(); $order++; } diff --git a/endpoints/cronjobs/sendnotifications.php b/endpoints/cronjobs/sendnotifications.php index 984a377..58abdcc 100644 --- a/endpoints/cronjobs/sendnotifications.php +++ b/endpoints/cronjobs/sendnotifications.php @@ -5,465 +5,501 @@ require_once __DIR__ . '/../../includes/connect_endpoint_crontabs.php'; - $days = 1; - $emailNotificationsEnabled = false; - $gotifyNotificationsEnabled = false; - $telegramNotificationsEnabled = false; - $webhookNotificationsEnabled = false; - $pushoverNotificationsEnabled = false; - $discordNotificationsEnabled = false; + require __DIR__ . '/../../libs/PHPMailer/PHPMailer.php'; + require __DIR__ . '/../../libs/PHPMailer/SMTP.php'; + require __DIR__ . '/../../libs/PHPMailer/Exception.php'; - // Get notification settings (how many days before the subscription ends should the notification be sent) - $query = "SELECT days FROM notification_settings"; - $result = $db->query($query); + // Get all user ids + $query = "SELECT id, username FROM user"; + $stmt = $db->prepare($query); + $usersToNotify = $stmt->execute(); - if ($row = $result->fetchArray(SQLITE3_ASSOC)) { - $days = $row['days']; - } + while ($userToNotify = $usersToNotify->fetchArray(SQLITE3_ASSOC)) { + $userId = $userToNotify['id']; + echo "For user: " . $userToNotify['username'] . "
"; + $days = 1; + $emailNotificationsEnabled = false; + $gotifyNotificationsEnabled = false; + $telegramNotificationsEnabled = false; + $webhookNotificationsEnabled = false; + $pushoverNotificationsEnabled = false; + $discordNotificationsEnabled = false; - // Check if email notifications are enabled and get the settings - $query = "SELECT * FROM email_notifications"; - $result = $db->query($query); + // Get notification settings (how many days before the subscription ends should the notification be sent) + $query = "SELECT days FROM notification_settings WHERE user_id = :userId"; + $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"; - } - - // 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; + if ($row = $result->fetchArray(SQLITE3_ASSOC)) { + $days = $row['days']; } - // Get all household members - $stmt = $db->prepare('SELECT * FROM household'); - $resultHousehold = $stmt->execute(); - $household = []; - while ($rowHousehold = $resultHousehold->fetchArray(SQLITE3_ASSOC)) { - $household[$rowHousehold['id']] = $rowHousehold; + // Check if email notifications are enabled and get the settings + $query = "SELECT * FROM email_notifications WHERE user_id = :userId"; + $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 - $stmt = $db->prepare('SELECT * FROM categories'); - $resultCategories = $stmt->execute(); + // Check if Discord notifications are enabled and get the settings + $query = "SELECT * FROM discord_notifications WHERE user_id = :userId"; + $stmt = $db->prepare($query); + $stmt->bindValue(':userId', $userId, SQLITE3_INTEGER); + $result = $stmt->execute(); - $categories = []; - while ($rowCategory = $resultCategories->fetchArray(SQLITE3_ASSOC)) { - $categories[$rowCategory['id']] = $rowCategory; + 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"]; } - $stmt = $db->prepare('SELECT * FROM subscriptions WHERE notify = :notify AND inactive = :inactive ORDER BY payer_user_id ASC'); - $stmt->bindValue(':notify', 1, SQLITE3_INTEGER); - $stmt->bindValue(':inactive', 0, SQLITE3_INTEGER); - $resultSubscriptions = $stmt->execute(); + // Check if Gotify notifications are enabled and get the settings + $query = "SELECT * FROM gotify_notifications WHERE user_id = :userId"; + $stmt = $db->prepare($query); + $stmt->bindValue(':userId', $userId, SQLITE3_INTEGER); + $result = $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++; + 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 WHERE user_id = :userId"; + $stmt = $db->prepare($query); + $stmt->bindValue(':userId', $userId, SQLITE3_INTEGER); + $result = $stmt->execute(); + + 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 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 ($emailNotificationsEnabled) { - require __DIR__ . '/../../libs/PHPMailer/PHPMailer.php'; - require __DIR__ . '/../../libs/PHPMailer/SMTP.php'; - require __DIR__ . '/../../libs/PHPMailer/Exception.php'; + // If no notifications are enabled, no need to run + if (!$notificationsEnabled) { + echo "Notifications are disabled. No need to run.
"; + continue; + } 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'); - $stmt->bindValue(':id', 1, SQLITE3_INTEGER); - $result = $stmt->execute(); - $defaultUser = $result->fetchArray(SQLITE3_ASSOC); - $defaultEmail = $defaultUser['email']; - $defaultName = $defaultUser['username']; + while ($row = $result->fetchArray(SQLITE3_ASSOC)) { + $currencies[$row['id']] = $row; + } - foreach ($notify as $userId => $perUser) { - $message = "The following subscriptions are up for renewal:\n"; + // Get all household members + $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) { - $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); + $household = []; + while ($rowHousehold = $resultHousehold->fetchArray(SQLITE3_ASSOC)) { + $household[$rowHousehold['id']] = $rowHousehold; + } - $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
"; - } else { - echo "Error sending notifications: " . $mail->ErrorInfo; - } + // Get all categories + $query = "SELECT * FROM categories WHERE user_id = :userId"; + $stmt = $db->prepare($query); + $stmt->bindValue(':userId', $userId, SQLITE3_INTEGER); + $resultCategories = $stmt->execute(); + + $categories = []; + while ($rowCategory = $resultCategories->fetchArray(SQLITE3_ASSOC)) { + $categories[$rowCategory['id']] = $rowCategory; + } + + $query = "SELECT * FROM subscriptions WHERE user_id = :user_id AND notify = :notify AND inactive = :inactive ORDER BY payer_user_id ASC"; + $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 ($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); + if (!empty($notify)) { + + // Email notifications if enabled + if ($emailNotificationsEnabled) { + + $stmt = $db->prepare('SELECT * FROM user WHERE id = :user_id'); + $stmt->bindValue(':user_id', $userId, SQLITE3_INTEGER); $result = $stmt->execute(); - $user = $result->fetchArray(SQLITE3_ASSOC); + $defaultUser = $result->fetchArray(SQLITE3_ASSOC); + $defaultEmail = $defaultUser['email']; + $defaultName = $defaultUser['username']; - $title = translate('wallos_notification', $i18n); - - if ($user['name']) { - $message = $user['name'] . ", the following subscriptions are up for renewal:\n"; - } else { + foreach ($notify as $userId => $perUser) { $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
"; + } else { + echo "Error sending notifications: " . $mail->ErrorInfo . "
"; + } + } + } + + // 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) . "
"; + } else { + echo "Discord Notifications sent
"; + } + } + } + + // 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
"; + } + } + } + + // 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
"; + } + } + } + + // 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
"; + } + } + } + + // 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) { - $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']; - } + $payload_json["{{subscriptions}}"] = $subscriptions; + $payload_json[$webhook['iterator']] = $subscriptions; + unset($payload_json["{{subscriptions}}"]); $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_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 ($result === false) { - echo "Error sending notifications: " . curl_error($ch); + if ($response === false) { + echo "Error sending notifications: " . curl_error($ch) . "
"; } else { - echo "Discord Notifications sent
"; + echo "Webhook Notifications sent
"; } + } - } - - // 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
"; - } - } - } - - // 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
"; - } - } - } - - // 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
"; - } - } - } - - // 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
"; - } - - } + - - } else { - echo "Nothing to notify."; + } else { + echo "Nothing to notify.
"; + } + } } + ?> diff --git a/endpoints/cronjobs/sendresetpasswordemails.php b/endpoints/cronjobs/sendresetpasswordemails.php new file mode 100644 index 0000000..50cebbf --- /dev/null +++ b/endpoints/cronjobs/sendresetpasswordemails.php @@ -0,0 +1,82 @@ +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 = 'Logo +
+ A password reset was requested for your account. +
+ Please click the following link to reset your password: Reset Password'; + + $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'] . "
"; + + } + } catch (Exception $e) { + echo "Message could not be sent. Mailer Error: {$mail->ErrorInfo}
"; + } + } else { + // There are no SMTP settings + exit(); + } + } else { + // There are no password reset emails to be sent + exit(); + } + +?> \ No newline at end of file diff --git a/endpoints/cronjobs/sendverificationemails.php b/endpoints/cronjobs/sendverificationemails.php new file mode 100644 index 0000000..6f05ac1 --- /dev/null +++ b/endpoints/cronjobs/sendverificationemails.php @@ -0,0 +1,85 @@ +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 = 'Logo +
+ Registration on Wallos was successful. +
+ Please click the following link to verify your email: Verify Email'; + + $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'] . "
"; + } + } 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(); + } + +?> \ No newline at end of file diff --git a/endpoints/cronjobs/updateexchange.php b/endpoints/cronjobs/updateexchange.php index 19b8d60..91ec4e9 100644 --- a/endpoints/cronjobs/updateexchange.php +++ b/endpoints/cronjobs/updateexchange.php @@ -1,73 +1,92 @@ query($query); + // Get all user ids - if ($result) { - $row = $result->fetchArray(SQLITE3_ASSOC); - - if ($row) { - $apiKey = $row['api_key']; + $query = "SELECT id, username FROM user"; + $stmt = $db->prepare($query); + $usersToUpdateExchange = $stmt->execute(); - $codes = ""; - $query = "SELECT id, name, symbol, code FROM currencies"; - $result = $db->query($query); - 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 = 1"; - $stmt = $db->prepare($query); - $result = $stmt->execute(); + while ($userToUpdateExchange = $usersToUpdateExchange->fetchArray(SQLITE3_ASSOC)) { + $userId = $userToUpdateExchange['id']; + echo "For user: " . $userToUpdateExchange['username'] . "
"; + + $query = "SELECT api_key FROM fixer WHERE user_id = :userId"; + $stmt = $db->prepare($query); + $stmt->bindParam(':userId', $userId, SQLITE3_INTEGER); + $result = $stmt->execute(); + + if ($result) { $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; - $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"; - } - } - $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)"; + $codes = ""; + $query = "SELECT id, name, symbol, code FROM currencies WHERE user_id = :userId"; $stmt = $db->prepare($query); - $stmt->bindParam(':formattedDate', $formattedDate, SQLITE3_TEXT); + $stmt->bindParam(':userId', $userId, SQLITE3_INTEGER); $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(); - echo "Rates updated successfully!"; + $api_url = "http://data.fixer.io/api/latest?access_key=". $apiKey . "&base=EUR&symbols=" . $codes; + $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
"; + } + } + $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!
"; + } + } else { + echo "Exchange rates update skipped. No fixer.io api key provided
"; + $apiKey = null; } } else { - echo "Exchange rates update skipped. No fixer.io api key provided"; + echo "Exchange rates update skipped. No fixer.io api key provided
"; $apiKey = null; } - } else { - echo "Exchange rates update skipped. No fixer.io api key provided"; - $apiKey = null; + } + ?> \ No newline at end of file diff --git a/endpoints/currency/currency.php b/endpoints/currency/currency.php index fa91128..92f8aff 100644 --- a/endpoints/currency/currency.php +++ b/endpoints/currency/currency.php @@ -2,20 +2,19 @@ require_once '../../includes/connect_endpoint.php'; require_once '../../includes/inputvalidation.php'; -session_start(); - if (isset($_SESSION['loggedin']) && $_SESSION['loggedin'] === true) { if (isset($_GET['action']) && $_GET['action'] == "add") { $currencyName = "Currency"; $currencySymbol = "$"; $currencyCode = "CODE"; $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->bindParam(':name', $currencyName, SQLITE3_TEXT); $stmtInsert->bindParam(':symbol', $currencySymbol, SQLITE3_TEXT); $stmtInsert->bindParam(':code', $currencyCode, SQLITE3_TEXT); $stmtInsert->bindParam(':rate', $currencyRate, SQLITE3_TEXT); + $stmtInsert->bindParam(':userId', $userId, SQLITE3_INTEGER); $resultInsert = $stmtInsert->execute(); if ($resultInsert) { @@ -30,12 +29,13 @@ if (isset($_SESSION['loggedin']) && $_SESSION['loggedin'] === true) { $name = validate($_GET['name']); $symbol = validate($_GET['symbol']); $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->bindParam(':name', $name, SQLITE3_TEXT); $stmt->bindParam(':symbol', $symbol, SQLITE3_TEXT); $stmt->bindParam(':code', $code, SQLITE3_TEXT); $stmt->bindParam(':currencyId', $currencyId, SQLITE3_INTEGER); + $stmt->bindParam(':userId', $userId, SQLITE3_INTEGER); $result = $stmt->execute(); if ($result) { @@ -60,16 +60,18 @@ if (isset($_SESSION['loggedin']) && $_SESSION['loggedin'] === true) { } } else if (isset($_GET['action']) && $_GET['action'] == "delete") { 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->bindParam(':userId', $userId, SQLITE3_INTEGER); $result = $stmt->execute(); $row = $result->fetchArray(SQLITE3_ASSOC); $mainCurrencyId = $row['main_currency']; $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->bindParam(':currencyId', $currencyId, SQLITE3_INTEGER); + $checkStmt->bindParam(':userId', $userId, SQLITE3_INTEGER); $checkResult = $checkStmt->execute(); $row = $checkResult->fetchArray(); $count = $row[0]; @@ -90,9 +92,10 @@ if (isset($_SESSION['loggedin']) && $_SESSION['loggedin'] === true) { echo json_encode($response); exit; } else { - $sql = "DELETE FROM currencies WHERE id = :currencyId"; + $sql = "DELETE FROM currencies WHERE id = :currencyId AND user_id = :userId"; $stmt = $db->prepare($sql); $stmt->bindParam(':currencyId', $currencyId, SQLITE3_INTEGER); + $stmt->bindParam(':userId', $userId, SQLITE3_INTEGER); $result = $stmt->execute(); if ($result) { echo json_encode(["success" => true, "message" => translate('currency_removed', $i18n)]); diff --git a/endpoints/currency/fixer_api_key.php b/endpoints/currency/fixer_api_key.php index 02b7fdd..90a5ec7 100644 --- a/endpoints/currency/fixer_api_key.php +++ b/endpoints/currency/fixer_api_key.php @@ -1,14 +1,15 @@ exec($removeOldKey); + $removeOldKey = "DELETE FROM fixer WHERE user_id = :userId"; + $stmt = $db->prepare($removeOldKey); + $stmt->bindParam(":userId", $userId, SQLITE3_INTEGER); + $stmt->execute(); if ($provider == 1) { $testKeyUrl = "https://api.apilayer.com/fixer/latest?base=USD&symbols=EUR"; @@ -27,10 +28,11 @@ $apiData = json_decode($response, true); if ($apiData['success'] && $apiData['success'] == 1) { 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->bindParam(":api_key", $newApiKey, SQLITE3_TEXT); $stmt->bindParam(":provider", $provider, SQLITE3_INTEGER); + $stmt->bindParam(":userId", $userId, SQLITE3_INTEGER); $result = $stmt->execute(); if ($result) { echo json_encode(["success" => true, "message" => translate('api_key_saved', $i18n)]); diff --git a/endpoints/currency/update_exchange.php b/endpoints/currency/update_exchange.php index db3ae19..49f96de 100644 --- a/endpoints/currency/update_exchange.php +++ b/endpoints/currency/update_exchange.php @@ -6,8 +6,10 @@ $shouldUpdate = true; if (isset($_GET['force']) && $_GET['force'] === "true") { $shouldUpdate = true; } else { - $query = "SELECT date FROM last_exchange_update"; - $result = $db->querySingle($query); + $query = "SELECT date FROM last_exchange_update WHERE user_id = :userId"; + $stmt = $db->prepare($query); + $stmt->bindParam(':userId', $userId, SQLITE3_INTEGER); + $result = $stmt->execute(); if ($result) { $lastUpdateDate = new DateTime($result); @@ -34,14 +36,17 @@ if ($result) { $provider = $row['provider']; $codes = ""; - $query = "SELECT id, name, symbol, code FROM currencies"; - $result = $db->query($query); + $query = "SELECT id, name, symbol, code FROM currencies WHERE user_id = :userId"; + $stmt = $db->prepare($query); + $stmt->bindParam(':userId', $userId, SQLITE3_INTEGER); + $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 = 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->bindParam(':userId', $userId, SQLITE3_INTEGER); $result = $stmt->execute(); $row = $result->fetchArray(SQLITE3_ASSOC); $mainCurrencyCode = $row['code']; @@ -72,10 +77,11 @@ if ($result) { } else { $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->bindParam(':rate', $exchangeRate, SQLITE3_TEXT); $updateStmt->bindParam(':code', $currencyCode, SQLITE3_TEXT); + $updateStmt->bindParam(':userId', $userId, SQLITE3_INTEGER); $updateResult = $updateStmt->execute(); if (!$updateResult) { @@ -85,14 +91,11 @@ if ($result) { $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->bindParam(':formattedDate', $formattedDate, SQLITE3_TEXT); - $result = $stmt->execute(); + $updateQuery = "UPDATE last_exchange_update SET date = :formattedDate WHERE user_id = :userId"; + $updateStmt = $db->prepare($updateQuery); + $updateStmt->bindParam(':formattedDate', $formattedDate, SQLITE3_TEXT); + $updateStmt->bindParam(':userId', $userId, SQLITE3_INTEGER); + $updateResult = $updateStmt->execute(); $db->close(); echo "Rates updated successfully!"; diff --git a/endpoints/db/backup.php b/endpoints/db/backup.php index 9f7948c..346e3a7 100644 --- a/endpoints/db/backup.php +++ b/endpoints/db/backup.php @@ -1,6 +1,6 @@ false, diff --git a/endpoints/db/import.php b/endpoints/db/import.php index 38672e1..d346e7e 100644 --- a/endpoints/db/import.php +++ b/endpoints/db/import.php @@ -1,6 +1,5 @@ query("SELECT COUNT(*) as count FROM user"); $row = $result->fetchArray(SQLITE3_NUM); diff --git a/endpoints/db/migrate.php b/endpoints/db/migrate.php index cb65f69..99069b3 100644 --- a/endpoints/db/migrate.php +++ b/endpoints/db/migrate.php @@ -33,6 +33,15 @@ $allMigrations = glob('migrations/*.php'); if (count($allMigrations) == 0) { $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); if (count($requiredMigrations) === 0) { diff --git a/endpoints/db/restore.php b/endpoints/db/restore.php index 60a271e..5803164 100644 --- a/endpoints/db/restore.php +++ b/endpoints/db/restore.php @@ -1,6 +1,6 @@ false, diff --git a/endpoints/household/household.php b/endpoints/household/household.php index 08759af..334e614 100644 --- a/endpoints/household/household.php +++ b/endpoints/household/household.php @@ -2,14 +2,13 @@ require_once '../../includes/connect_endpoint.php'; require_once '../../includes/inputvalidation.php'; -session_start(); - if (isset($_SESSION['loggedin']) && $_SESSION['loggedin'] === true) { if (isset($_GET['action']) && $_GET['action'] == "add") { $householdName = "Member"; - $sqlInsert = "INSERT INTO household (name) VALUES (:name)"; + $sqlInsert = "INSERT INTO household (name, user_id) VALUES (:name, :userId)"; $stmtInsert = $db->prepare($sqlInsert); $stmtInsert->bindParam(':name', $householdName, SQLITE3_TEXT); + $stmtInsert->bindParam(':userId', $userId, SQLITE3_INTEGER); $resultInsert = $stmtInsert->execute(); if ($resultInsert) { @@ -32,11 +31,12 @@ if (isset($_SESSION['loggedin']) && $_SESSION['loggedin'] === true) { $name = validate($_GET['name']); $email = $_GET['email'] ? $_GET['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->bindParam(':name', $name, SQLITE3_TEXT); $stmt->bindParam(':email', $email, SQLITE3_TEXT); $stmt->bindParam(':memberId', $memberId, SQLITE3_INTEGER); + $stmt->bindParam(':userId', $userId, SQLITE3_INTEGER); $result = $stmt->execute(); if ($result) { @@ -62,9 +62,10 @@ if (isset($_SESSION['loggedin']) && $_SESSION['loggedin'] === true) { } else if (isset($_GET['action']) && $_GET['action'] == "delete") { if (isset($_GET['memberId']) && $_GET['memberId'] != "" && $_GET['memberId'] != 1) { $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->bindParam(':memberId', $memberId, SQLITE3_INTEGER); + $checkStmt->bindParam(':userId', $userId, SQLITE3_INTEGER); $checkResult = $checkStmt->execute(); $row = $checkResult->fetchArray(); $count = $row[0]; @@ -76,9 +77,10 @@ if (isset($_SESSION['loggedin']) && $_SESSION['loggedin'] === true) { ]; echo json_encode($response); } else { - $sql = "DELETE FROM household WHERE id = :memberId"; + $sql = "DELETE FROM household WHERE id = :memberId and user_id = :userId"; $stmt = $db->prepare($sql); $stmt->bindParam(':memberId', $memberId, SQLITE3_INTEGER); + $stmt->bindParam(':userId', $userId, SQLITE3_INTEGER); $result = $stmt->execute(); if ($result) { $response = [ diff --git a/endpoints/notifications/savediscordnotifications.php b/endpoints/notifications/savediscordnotifications.php index 2081aa3..f3caaf7 100644 --- a/endpoints/notifications/savediscordnotifications.php +++ b/endpoints/notifications/savediscordnotifications.php @@ -1,7 +1,6 @@ querySingle($query); + $query = "SELECT COUNT(*) FROM discord_notifications WHERE user_id = :userId"; + $stmt = $db->prepare($query); + $stmt->bindParam(":userId", $userId, SQLITE3_INTEGER); + $result = $stmt->execute(); if ($result === false) { $response = [ @@ -38,12 +39,15 @@ require_once '../../includes/connect_endpoint.php'; ]; echo json_encode($response); } else { - if ($result == 0) { - $query = "INSERT INTO discord_notifications (enabled, webhook_url, bot_username, bot_avatar_url) - VALUES (:enabled, :webhook_url, :bot_username, :bot_avatar_url)"; + $row = $result->fetchArray(); + $count = $row[0]; + 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 { $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); @@ -51,6 +55,7 @@ require_once '../../includes/connect_endpoint.php'; $stmt->bindValue(':webhook_url', $webhook_url, SQLITE3_TEXT); $stmt->bindValue(':bot_username', $bot_username, SQLITE3_TEXT); $stmt->bindValue(':bot_avatar_url', $bot_avatar_url, SQLITE3_TEXT); + $stmt->bindValue(':userId', $userId, SQLITE3_INTEGER); if ($stmt->execute()) { $response = [ diff --git a/endpoints/notifications/saveemailnotifications.php b/endpoints/notifications/saveemailnotifications.php index 3042d25..6250431 100644 --- a/endpoints/notifications/saveemailnotifications.php +++ b/endpoints/notifications/saveemailnotifications.php @@ -1,6 +1,5 @@ querySingle($query); + $query = "SELECT COUNT(*) FROM email_notifications WHERE user_id = :userId"; + $stmt = $db->prepare($query); + $stmt->bindParam(":userId", $userId, SQLITE3_INTEGER); + $result = $stmt->execute(); if ($result === false) { $response = [ @@ -46,13 +47,15 @@ ]; echo json_encode($response); } else { - if ($result == 0) { - $query = "INSERT INTO email_notifications (enabled, smtp_address, smtp_port, smtp_username, smtp_password, from_email, encryption) - VALUES (:enabled, :smtpAddress, :smtpPort, :smtpUsername, :smtpPassword, :fromEmail, :encryption)"; + $row = $result->fetchArray(); + $count = $row[0]; + 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 { $query = "UPDATE email_notifications 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); @@ -63,6 +66,7 @@ $stmt->bindValue(':smtpPassword', $smtpPassword, SQLITE3_TEXT); $stmt->bindValue(':fromEmail', $fromEmail, SQLITE3_TEXT); $stmt->bindValue(':encryption', $encryption, SQLITE3_TEXT); + $stmt->bindValue(':userId', $userId, SQLITE3_INTEGER); if ($stmt->execute()) { $response = [ diff --git a/endpoints/notifications/savegotifynotifications.php b/endpoints/notifications/savegotifynotifications.php index 93db541..6dda4e7 100644 --- a/endpoints/notifications/savegotifynotifications.php +++ b/endpoints/notifications/savegotifynotifications.php @@ -1,6 +1,5 @@ querySingle($query); + $query = "SELECT COUNT(*) FROM gotify_notifications WHERE user_id = :userId"; + $stmt = $db->prepare($query); + $stmt->bindParam(":userId", $userId, SQLITE3_INTEGER); + $result = $stmt->execute(); if ($result === false) { $response = [ @@ -37,18 +38,21 @@ ]; echo json_encode($response); } else { - if ($result == 0) { - $query = "INSERT INTO gotify_notifications (enabled, url, token) - VALUES (:enabled, :url, :token)"; + $row = $result->fetchArray(); + $count = $row[0]; + if ($count == 0) { + $query = "INSERT INTO gotify_notifications (enabled, url, token, user_id) + VALUES (:enabled, :url, :token, :userId)"; } else { $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->bindValue(':enabled', $enabled, SQLITE3_INTEGER); $stmt->bindValue(':url', $url, SQLITE3_TEXT); $stmt->bindValue(':token', $token, SQLITE3_TEXT); + $stmt->bindValue(':userId', $userId, SQLITE3_INTEGER); if ($stmt->execute()) { $response = [ diff --git a/endpoints/notifications/savenotificationsettings.php b/endpoints/notifications/savenotificationsettings.php index bcb5841..f6addcc 100644 --- a/endpoints/notifications/savenotificationsettings.php +++ b/endpoints/notifications/savenotificationsettings.php @@ -1,7 +1,6 @@ querySingle($query); + $query = "SELECT COUNT(*) FROM notification_settings WHERE user_id = :userId"; + $stmt = $db->prepare($query); + $stmt->bindParam(":userId", $userId, SQLITE3_INTEGER); + $result = $stmt->execute(); if ($result === false) { $response = [ @@ -32,15 +33,18 @@ ]; echo json_encode($response); } else { - if ($result == 0) { - $query = "INSERT INTO notification_settings (days) - VALUES (:days)"; + $row = $result->fetchArray(); + $count = $row[0]; + if ($count == 0) { + $query = "INSERT INTO notification_settings (days, user_id) + VALUES (:days, :userId)"; } else { - $query = "UPDATE notification_settings SET days = :days"; + $query = "UPDATE notification_settings SET days = :days WHERE user_id = :userId"; } $stmt = $db->prepare($query); $stmt->bindValue(':days', $days, SQLITE3_INTEGER); + $stmt->bindValue(':userId', $userId, SQLITE3_INTEGER); if ($stmt->execute()) { $response = [ diff --git a/endpoints/notifications/savepushovernotifications.php b/endpoints/notifications/savepushovernotifications.php index 6f6a38e..f2295ce 100644 --- a/endpoints/notifications/savepushovernotifications.php +++ b/endpoints/notifications/savepushovernotifications.php @@ -1,7 +1,6 @@ querySingle($query); + $query = "SELECT COUNT(*) FROM pushover_notifications WHERE user_id = :userId"; + $stmt = $db->prepare($query); + $stmt->bindParam(":userId", $userId, SQLITE3_INTEGER); + $result = $stmt->execute(); if ($result === false) { $response = [ @@ -38,18 +39,21 @@ require_once '../../includes/connect_endpoint.php'; ]; echo json_encode($response); } else { - if ($result == 0) { - $query = "INSERT INTO pushover_notifications (enabled, user_key, token) - VALUES (:enabled, :user_key, :token)"; + $row = $result->fetchArray(); + $count = $row[0]; + if ($count == 0) { + $query = "INSERT INTO pushover_notifications (enabled, user_key, token, user_id) + VALUES (:enabled, :user_key, :token, :userId)"; } else { $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->bindValue(':enabled', $enabled, SQLITE3_INTEGER); $stmt->bindValue(':user_key', $user_key, SQLITE3_TEXT); $stmt->bindValue(':token', $token, SQLITE3_TEXT); + $stmt->bindValue(':userId', $userId, SQLITE3_INTEGER); if ($stmt->execute()) { $response = [ diff --git a/endpoints/notifications/savetelegramnotifications.php b/endpoints/notifications/savetelegramnotifications.php index 5640e7b..af54cb2 100644 --- a/endpoints/notifications/savetelegramnotifications.php +++ b/endpoints/notifications/savetelegramnotifications.php @@ -1,6 +1,5 @@ querySingle($query); + $query = "SELECT COUNT(*) FROM telegram_notifications WHERE user_id = :userId"; + $stmt = $db->prepare($query); + $stmt->bindParam(":userId", $userId, SQLITE3_INTEGER); + $result = $stmt->execute(); if ($result === false) { $response = [ @@ -37,18 +38,21 @@ ]; echo json_encode($response); } else { - if ($result == 0) { - $query = "INSERT INTO telegram_notifications (enabled, bot_token, chat_id) - VALUES (:enabled, :bot_token, :chat_id)"; + $row = $result->fetchArray(); + $count = $row[0]; + if ($count == 0) { + $query = "INSERT INTO telegram_notifications (enabled, bot_token, chat_id, user_id) + VALUES (:enabled, :bot_token, :chat_id, :userId)"; } else { $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->bindValue(':enabled', $enabled, SQLITE3_INTEGER); $stmt->bindValue(':bot_token', $bot_token, SQLITE3_TEXT); $stmt->bindValue(':chat_id', $chat_id, SQLITE3_TEXT); + $stmt->bindValue(':userId', $userId, SQLITE3_INTEGER); if ($stmt->execute()) { $response = [ diff --git a/endpoints/notifications/savewebhooknotifications.php b/endpoints/notifications/savewebhooknotifications.php index a80b96d..25fa1be 100644 --- a/endpoints/notifications/savewebhooknotifications.php +++ b/endpoints/notifications/savewebhooknotifications.php @@ -1,6 +1,5 @@ querySingle($query); + $query = "SELECT COUNT(*) FROM webhook_notifications WHERE user_id = :userId"; + $stmt = $db->prepare($query); + $stmt->bindParam(":userId", $userId, SQLITE3_INTEGER); + $result = $stmt->execute(); if ($result === false) { $response = [ @@ -38,12 +39,14 @@ ]; echo json_encode($response); } else { - if ($result == 0) { - $query = "INSERT INTO webhook_notifications (enabled, url, headers, payload) - VALUES (:enabled, :url, :headers, :payload)"; + $row = $result->fetchArray(); + $count = $row[0]; + if ($count == 0) { + $query = "INSERT INTO webhook_notifications (enabled, url, headers, payload, user_id) + VALUES (:enabled, :url, :headers, :payload, :userId)"; } else { $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); @@ -51,6 +54,7 @@ $stmt->bindValue(':url', $url, SQLITE3_TEXT); $stmt->bindValue(':headers', $headers, SQLITE3_TEXT); $stmt->bindValue(':payload', $payload, SQLITE3_TEXT); + $stmt->bindValue(':userId', $userId, SQLITE3_INTEGER); if ($stmt->execute()) { $response = [ diff --git a/endpoints/notifications/testdiscordnotifications.php b/endpoints/notifications/testdiscordnotifications.php index 5322ac0..0d0a7dd 100644 --- a/endpoints/notifications/testdiscordnotifications.php +++ b/endpoints/notifications/testdiscordnotifications.php @@ -1,7 +1,6 @@ prepare($sql); $stmt->bindParam(':id', $newID, SQLITE3_INTEGER); $stmt->bindParam(':name', $name, SQLITE3_TEXT); $stmt->bindParam(':icon', $icon, SQLITE3_TEXT); $stmt->bindParam(':enabled', $enabled, SQLITE3_INTEGER); + $stmt->bindParam(':userId', $userId, SQLITE3_INTEGER); if ($stmt->execute()) { $success['success'] = true; diff --git a/endpoints/payments/delete.php b/endpoints/payments/delete.php index 25d9b86..010f9af 100644 --- a/endpoints/payments/delete.php +++ b/endpoints/payments/delete.php @@ -1,13 +1,14 @@ prepare($deleteQuery); $deleteStmt->bindParam(':paymentMethodId', $paymentMethodId, SQLITE3_INTEGER); + $deleteStmt->bindParam(':userId', $userId, SQLITE3_INTEGER); if ($deleteStmt->execute()) { $success['success'] = true; diff --git a/endpoints/payments/get.php b/endpoints/payments/get.php index 902c645..5ff6af4 100644 --- a/endpoints/payments/get.php +++ b/endpoints/payments/get.php @@ -1,18 +1,22 @@ 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 = []; - while ($row = $paymentsInUseQuery->fetchArray(SQLITE3_ASSOC)) { + while ($row = $result->fetchArray(SQLITE3_ASSOC)) { $paymentsInUse[] = $row['id']; } - $sql = "SELECT * FROM payment_methods"; - - $result = $db->query($sql); + $sql = "SELECT * FROM payment_methods WHERE user_id = :userId"; + $stmt = $db->prepare($sql); + $stmt->bindParam(':userId', $userId, SQLITE3_INTEGER); + $result = $stmt->execute(); + if ($result) { $payments = array(); while ($row = $result->fetchArray(SQLITE3_ASSOC)) { @@ -25,7 +29,7 @@ if (isset($_SESSION['loggedin']) && $_SESSION['loggedin'] === true) { } 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); ?>
false, @@ -17,8 +17,9 @@ if (!isset($_GET['paymentId']) || !isset($_GET['enabled'])) { $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(':userId', $userId, SQLITE3_INTEGER); $result = $stmt->execute(); $row = $result->fetchArray(); $inUse = $row['count'] === 1; @@ -32,10 +33,11 @@ if ($inUse) { $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->bindParam(':enabled', $enabled); $stmtUpdate->bindParam(':id', $paymentId); +$stmtUpdate->bindParam(':userId', $userId); $resultUpdate = $stmtUpdate->execute(); $text = $enabled ? "enabled" : "disabled"; diff --git a/endpoints/payments/rename.php b/endpoints/payments/rename.php index f7ba250..ba0a76b 100644 --- a/endpoints/payments/rename.php +++ b/endpoints/payments/rename.php @@ -1,7 +1,6 @@ prepare($sql); $stmt->bindParam(':name', $name, SQLITE3_TEXT); $stmt->bindParam(':paymentId', $paymentId, SQLITE3_INTEGER); +$stmt->bindParam(':userId', $userId, SQLITE3_INTEGER); $result = $stmt->execute(); if ($result) { diff --git a/endpoints/payments/sort.php b/endpoints/payments/sort.php index 14c5118..a217beb 100644 --- a/endpoints/payments/sort.php +++ b/endpoints/payments/sort.php @@ -2,17 +2,16 @@ require_once '../../includes/connect_endpoint.php'; -session_start(); - if (isset($_SESSION['loggedin']) && $_SESSION['loggedin'] === true) { $paymentMethods = $_POST['paymentMethodIds']; $order = 1; 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->bindParam(':order', $order, SQLITE3_INTEGER); $stmt->bindParam(':paymentMethodId', $paymentMethodId, SQLITE3_INTEGER); + $stmt->bindParam(':userId', $userId, SQLITE3_INTEGER); $result = $stmt->execute(); $order++; } diff --git a/endpoints/settings/colortheme.php b/endpoints/settings/colortheme.php index 516e9d7..00b9c1e 100644 --- a/endpoints/settings/colortheme.php +++ b/endpoints/settings/colortheme.php @@ -1,7 +1,7 @@ false, @@ -15,8 +15,9 @@ $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(':userId', $userId, SQLITE3_INTEGER); if ($stmt->execute()) { die(json_encode([ diff --git a/endpoints/settings/convert_currency.php b/endpoints/settings/convert_currency.php index 86c1b38..0f04d56 100644 --- a/endpoints/settings/convert_currency.php +++ b/endpoints/settings/convert_currency.php @@ -1,6 +1,6 @@ false, @@ -14,8 +14,9 @@ if ($_SERVER["REQUEST_METHOD"] === "POST") { $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(':userId', $userId, SQLITE3_INTEGER); if ($stmt->execute()) { die(json_encode([ diff --git a/endpoints/settings/customtheme.php b/endpoints/settings/customtheme.php index a5c4be5..4d05a10 100644 --- a/endpoints/settings/customtheme.php +++ b/endpoints/settings/customtheme.php @@ -1,7 +1,7 @@ false, @@ -20,10 +20,11 @@ $stmt = $db->prepare('DELETE FROM custom_colors'); $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(':accent_color', $accent_color, SQLITE3_TEXT); $stmt->bindParam(':hover_color', $hover_color, SQLITE3_TEXT); + $stmt->bindParam(':userId', $userId, SQLITE3_INTEGER); if ($stmt->execute()) { die(json_encode([ diff --git a/endpoints/settings/hide_disabled.php b/endpoints/settings/hide_disabled.php index 00a247c..37da598 100644 --- a/endpoints/settings/hide_disabled.php +++ b/endpoints/settings/hide_disabled.php @@ -1,6 +1,6 @@ false, @@ -14,8 +14,9 @@ if ($_SERVER["REQUEST_METHOD"] === "POST") { $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(':userId', $userId, SQLITE3_INTEGER); if ($stmt->execute()) { die(json_encode([ diff --git a/endpoints/settings/monthly_price.php b/endpoints/settings/monthly_price.php index f6dc172..8894a99 100644 --- a/endpoints/settings/monthly_price.php +++ b/endpoints/settings/monthly_price.php @@ -1,6 +1,6 @@ false, @@ -14,8 +14,9 @@ if ($_SERVER["REQUEST_METHOD"] === "POST") { $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(':userId', $userId, SQLITE3_INTEGER); if ($stmt->execute()) { die(json_encode([ diff --git a/endpoints/settings/remove_background.php b/endpoints/settings/remove_background.php index 6eecbcf..2eabd30 100644 --- a/endpoints/settings/remove_background.php +++ b/endpoints/settings/remove_background.php @@ -1,6 +1,6 @@ false, @@ -14,8 +14,9 @@ if ($_SERVER["REQUEST_METHOD"] === "POST") { $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(':userId', $userId, SQLITE3_INTEGER); if ($stmt->execute()) { die(json_encode([ diff --git a/endpoints/settings/resettheme.php b/endpoints/settings/resettheme.php index df80499..f3e38c9 100644 --- a/endpoints/settings/resettheme.php +++ b/endpoints/settings/resettheme.php @@ -1,7 +1,7 @@ false, @@ -10,7 +10,8 @@ } 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()) { die(json_encode([ diff --git a/endpoints/settings/theme.php b/endpoints/settings/theme.php index 48a867c..46ca9ce 100644 --- a/endpoints/settings/theme.php +++ b/endpoints/settings/theme.php @@ -1,6 +1,6 @@ false, @@ -14,8 +14,9 @@ if ($_SERVER["REQUEST_METHOD"] === "POST") { $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(':userId', $userId, SQLITE3_INTEGER); if ($stmt->execute()) { die(json_encode([ diff --git a/endpoints/subscription/add.php b/endpoints/subscription/add.php index bb8f649..5fb3f66 100644 --- a/endpoints/subscription/add.php +++ b/endpoints/subscription/add.php @@ -3,8 +3,6 @@ require_once '../../includes/connect_endpoint.php'; require_once '../../includes/inputvalidation.php'; require_once '../../includes/getsettings.php'; - - session_start(); function sanitizeFilename($filename) { $filename = preg_replace("/[^a-zA-Z0-9\s]/", "", $filename); @@ -184,20 +182,21 @@ if (!$isEdit) { $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, - :paymentMethodId, :payerUserId, :categoryId, :notify, :inactive, :url, :notifyDaysBefore)"; + :paymentMethodId, :payerUserId, :categoryId, :notify, :inactive, :url, :notifyDaysBefore, :userId)"; } else { $id = $_POST['id']; if ($logo != "") { $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, 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 { $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, - 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(':url', $url, SQLITE3_TEXT); $stmt->bindParam(':notifyDaysBefore', $notifyDaysBefore, SQLITE3_INTEGER); + $stmt->bindParam(':userId', $userId, SQLITE3_INTEGER); if ($stmt->execute()) { $success['status'] = "Success"; diff --git a/endpoints/subscription/delete.php b/endpoints/subscription/delete.php index a63af2b..88cfea0 100644 --- a/endpoints/subscription/delete.php +++ b/endpoints/subscription/delete.php @@ -1,12 +1,13 @@ prepare($deleteQuery); $deleteStmt->bindParam(':subscriptionId', $subscriptionId, SQLITE3_INTEGER); + $deleteStmt->bindParam(':userId', $userId, SQLITE3_INTEGER); if ($deleteStmt->execute()) { http_response_code(204); diff --git a/endpoints/subscription/get.php b/endpoints/subscription/get.php index 7ceab23..b69a031 100644 --- a/endpoints/subscription/get.php +++ b/endpoints/subscription/get.php @@ -1,12 +1,13 @@ prepare($query); $stmt->bindParam(':subscriptionId', $subscriptionId, SQLITE3_INTEGER); + $stmt->bindParam(':userId', $userId, SQLITE3_INTEGER); $result = $stmt->execute(); $subscriptionData = array(); diff --git a/endpoints/subscriptions/get.php b/endpoints/subscriptions/get.php index 95dd2fd..908a058 100644 --- a/endpoints/subscriptions/get.php +++ b/endpoints/subscriptions/get.php @@ -1,6 +1,5 @@ prepare($sql); + $stmt->bindValue(':userId', $userId, SQLITE3_INTEGER); foreach ($params as $key => $value) { $stmt->bindValue($key, $value); @@ -84,7 +84,7 @@ $print[$id]['currency_code'] = $currencies[$subscription['currency_id']]['code']; $currencyId = $subscription['currency_id']; $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_name'] = $payment_methods[$paymentMethodId]['name']; $print[$id]['payment_method_id'] = $paymentMethodId; diff --git a/endpoints/user/budget.php b/endpoints/user/budget.php index e88ee1a..06bee21 100644 --- a/endpoints/user/budget.php +++ b/endpoints/user/budget.php @@ -3,9 +3,6 @@ require_once '../../includes/connect_endpoint.php'; require_once '../../includes/inputvalidation.php'; -session_start(); - - if (!isset($_SESSION['loggedin']) || $_SESSION['loggedin'] !== true) { die(json_encode([ "success" => false, @@ -28,8 +25,6 @@ if ($_SERVER["REQUEST_METHOD"] === "POST") { } else { $budget = $data["budget"]; - $userId = $_SESSION['userId']; - $sql = "UPDATE user SET budget = :budget WHERE id = :userId"; $stmt = $db->prepare($sql); $stmt->bindValue(':budget', $budget, SQLITE3_TEXT); diff --git a/endpoints/user/delete_avatar.php b/endpoints/user/delete_avatar.php index c3b0bb3..0e6846c 100644 --- a/endpoints/user/delete_avatar.php +++ b/endpoints/user/delete_avatar.php @@ -1,8 +1,6 @@ prepare($sql); + $stmt->bindValue(':userId', $userId, SQLITE3_INTEGER); $result = $stmt->execute(); $userAvatar = $result->fetchArray(SQLITE3_ASSOC)['avatar']; diff --git a/endpoints/user/save_user.php b/endpoints/user/save_user.php index 3d3540d..b2cd660 100644 --- a/endpoints/user/save_user.php +++ b/endpoints/user/save_user.php @@ -1,12 +1,12 @@ query($query); + $query = "SELECT api_key, provider FROM fixer WHERE user_id = :userId"; + $stmt = $db->prepare($query); + $stmt->bindParam(':userId', $userId, SQLITE3_INTEGER); + $result = $stmt->execute(); if ($result) { $row = $result->fetchArray(SQLITE3_ASSOC); @@ -23,8 +23,9 @@ } $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->bindParam(':userId', $userId, SQLITE3_INTEGER); $result = $stmt->execute(); $row = $result->fetchArray(SQLITE3_ASSOC); $mainCurrencyCode = $row['code']; @@ -55,23 +56,32 @@ } else { $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->bindParam(':rate', $exchangeRate, SQLITE3_TEXT); $updateStmt->bindParam(':code', $currencyCode, SQLITE3_TEXT); + $updateStmt->bindParam(':userId', $userId, SQLITE3_INTEGER); $updateResult = $updateStmt->execute(); } $currentDate = new DateTime(); $formattedDate = $currentDate->format('Y-m-d'); - $deleteQuery = "DELETE FROM last_exchange_update"; - $deleteStmt = $db->prepare($deleteQuery); - $deleteResult = $deleteStmt->execute(); + $query = "SELECT * FROM last_exchange_update WHERE user_id = :userId"; + $stmt = $db->prepare($query); + $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->bindParam(':formattedDate', $formattedDate, SQLITE3_TEXT); - $result = $stmt->execute(); + $stmt->bindParam(':userId', $userId, SQLITE3_INTEGER); + $resutl = $stmt->execute(); $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->bindParam(':userId', $userId, SQLITE3_INTEGER); $result = $stmt->execute(); $row = $result->fetchArray(SQLITE3_ASSOC); $mainCurrencyId = $row['main_currency']; @@ -174,10 +185,39 @@ return ""; } - if (isset($_SESSION['username']) && isset($_POST['username']) && isset($_POST['email']) && isset($_POST['avatar'])) { - $oldUsername = $_SESSION['username']; - $username = validate($_POST['username']); + if (isset($_SESSION['username']) && isset($_POST['email']) && $_POST['email'] !== "" + && isset($_POST['avatar']) && $_POST['avatar'] !== "" + && isset($_POST['main_currency']) && $_POST['main_currency'] !== "" + && isset($_POST['language']) && $_POST['language'] !== "") { + $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']; $main_currency = $_POST['main_currency']; $language = $_POST['language']; @@ -221,17 +261,17 @@ } 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 { - $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->bindParam(':avatar', $avatar, SQLITE3_TEXT); - $stmt->bindParam(':username', $username, SQLITE3_TEXT); $stmt->bindParam(':email', $email, SQLITE3_TEXT); $stmt->bindParam(':main_currency', $main_currency, SQLITE3_INTEGER); $stmt->bindParam(':language', $language, SQLITE3_TEXT); + $stmt->bindParam(':userId', $userId, SQLITE3_INTEGER); if (isset($_POST['password']) && $_POST['password'] != "") { $hashedPassword = password_hash($password, PASSWORD_DEFAULT); @@ -246,14 +286,6 @@ $root = str_replace('/endpoints/user', '', dirname($_SERVER['PHP_SELF'])); $root = $root == '' ? '/' : $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['main_currency'] = $main_currency; diff --git a/includes/checksession.php b/includes/checksession.php index 14cc360..1ebe9bc 100644 --- a/includes/checksession.php +++ b/includes/checksession.php @@ -8,6 +8,7 @@ $stmt->bindValue(':username', $username, SQLITE3_TEXT); $result = $stmt->execute(); $userData = $result->fetchArray(SQLITE3_ASSOC); + $userId = $userData['id']; if ($userData === false) { header('Location: logout.php'); @@ -45,10 +46,10 @@ } $userId = $userData['id']; $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->bindParam(1, $userId, SQLITE3_TEXT); - $stmt->bindParam(2, $token, SQLITE3_TEXT); + $stmt->bindParam(':userId', $userId, SQLITE3_TEXT); + $stmt->bindParam(':token', $token, SQLITE3_TEXT); $result = $stmt->execute(); $row = $result->fetchArray(SQLITE3_ASSOC); diff --git a/includes/connect_endpoint.php b/includes/connect_endpoint.php index 80f4cf1..4355479 100644 --- a/includes/connect_endpoint.php +++ b/includes/connect_endpoint.php @@ -12,4 +12,12 @@ require_once 'i18n/languages.php'; require_once 'i18n/getlang.php'; require_once 'i18n/' . $lang . '.php'; +session_start(); + +if (isset($_SESSION['loggedin']) && $_SESSION['loggedin'] === true) { + $userId = $_SESSION['userId']; +} else { + $userId = 0; +} + ?> \ No newline at end of file diff --git a/includes/getdbkeys.php b/includes/getdbkeys.php index 6caaff1..4c1a6ce 100644 --- a/includes/getdbkeys.php +++ b/includes/getdbkeys.php @@ -1,24 +1,29 @@ query($query); + $query = "SELECT * FROM currencies WHERE user_id = :userId"; + $stmt = $db->prepare($query); + $stmt->bindValue(':userId', $userId, SQLITE3_INTEGER); + $result = $stmt->execute(); while ($row = $result->fetchArray(SQLITE3_ASSOC)) { $currencyId = $row['id']; $currencies[$currencyId] = $row; } $members = array(); - $query = "SELECT * FROM household"; - $result = $db->query($query); + $query = "SELECT * FROM household WHERE user_id = :userId"; + $stmt = $db->prepare($query); + $stmt->bindValue(':userId', $userId, SQLITE3_INTEGER); + $result = $stmt->execute(); while ($row = $result->fetchArray(SQLITE3_ASSOC)) { $memberId = $row['id']; $members[$memberId] = $row; } $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(':userId', $userId, SQLITE3_INTEGER); $result = $query->execute(); while ($row = $result->fetchArray(SQLITE3_ASSOC)) { $payment_methodId = $row['id']; @@ -26,8 +31,10 @@ } $categories = array(); - $query = "SELECT * FROM categories ORDER BY `order` ASC"; - $result = $db->query($query); + $query = "SELECT * FROM categories WHERE user_id = :userId ORDER BY `order` ASC"; + $stmt = $db->prepare($query); + $stmt->bindValue(':userId', $userId, SQLITE3_INTEGER); + $result = $stmt->execute(); while ($row = $result->fetchArray(SQLITE3_ASSOC)) { $categoryId = $row['id']; $categories[$categoryId] = $row; diff --git a/includes/getsettings.php b/includes/getsettings.php index 1248d35..76d8bc4 100644 --- a/includes/getsettings.php +++ b/includes/getsettings.php @@ -1,7 +1,10 @@ query($query); +$query = "SELECT * FROM settings WHERE user_id = :userId"; +$stmt = $db->prepare($query); +$stmt->bindValue(':userId', $userId, SQLITE3_INTEGER); +$result = $stmt->execute(); + $settings = $result->fetchArray(SQLITE3_ASSOC); if ($settings) { $cookieExpire = time() + (30 * 24 * 60 * 60); @@ -14,8 +17,10 @@ if ($settings) { $settings['hideDisabledSubscriptions'] = $settings['hide_disabled'] ? 'true': 'false'; } -$query = "SELECT * FROM custom_colors"; -$result = $db->query($query); +$query = "SELECT * FROM custom_colors WHERE user_id = :userId"; +$stmt = $db->prepare($query); +$stmt->bindValue(':userId', $userId, SQLITE3_INTEGER); +$result = $stmt->execute(); $customColors = $result->fetchArray(SQLITE3_ASSOC); if ($customColors) { diff --git a/includes/i18n/de.php b/includes/i18n/de.php index 5e8818f..6909fa9 100644 --- a/includes/i18n/de.php +++ b/includes/i18n/de.php @@ -10,6 +10,8 @@ $i18n = [ "main_currency" => "Hauptwährung", "language" => "Sprache", "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.", "register" => "Registrieren", "restore_database" => "Datenbank wiederherstellen", @@ -18,6 +20,13 @@ $i18n = [ 'stay_logged_in' => "Angemeldet bleiben (30 Tage)", 'login' => "Login", '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 'subscriptions' => "Abonnements", 'stats' => "Statistiken", @@ -255,6 +264,24 @@ $i18n = [ // User "error_updating_user_data" => "Benutzerangaben konnten nicht aktualisiert werden.", "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", ]; diff --git a/includes/i18n/el.php b/includes/i18n/el.php index 709b365..4893487 100644 --- a/includes/i18n/el.php +++ b/includes/i18n/el.php @@ -10,6 +10,8 @@ $i18n = [ "main_currency" => "Κύριο νόμισμα", "language" => "Γλώσσα", "passwords_dont_match" => "Οι κωδικοί πρόσβασης δεν ταιριάζουν", + "username_exists" => "Το όνομα χρήστη υπάρχει ήδη", + "email_exists" => "Το email υπάρχει ήδη", "registration_failed" => "Η εγγραφή απέτυχε, παρακαλώ προσπάθησε ξανά.", "register" => "Εγγραφή", "restore_database" => "Επαναφορά βάσης δεδομένων", @@ -18,6 +20,13 @@ $i18n = [ 'stay_logged_in' => "Μείνε συνδεδεμένος (30 ημέρες)", 'login' => "Σύνδεση", '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 'subscriptions' => "Συνδρομές", 'stats' => "Στατιστικές", @@ -255,6 +264,24 @@ $i18n = [ // User "error_updating_user_data" => "Σφάλμα ενημέρωσης δεδομένων χρήστη.", "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 απέτυχε", ]; diff --git a/includes/i18n/en.php b/includes/i18n/en.php index 004870d..74982d9 100644 --- a/includes/i18n/en.php +++ b/includes/i18n/en.php @@ -10,6 +10,8 @@ $i18n = [ "main_currency" => "Main Currency", "language" => "Language", "passwords_dont_match" => "Passwords do not match", + "username_exists" => "Username already exists", + "email_exists" => "Email already exists", "registration_failed" => "Registration failed, please try again.", "register" => "Register", "restore_database" => "Restore Database", @@ -18,6 +20,13 @@ $i18n = [ 'stay_logged_in' => "Stay logged in (30 days)", 'login' => "Login", '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 'subscriptions' => "Subscriptions", 'stats' => "Statistics", @@ -255,6 +264,25 @@ $i18n = [ // User "error_updating_user_data" => "Error updating user data.", "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", + ]; diff --git a/includes/i18n/es.php b/includes/i18n/es.php index 6531b3d..42ad2b6 100644 --- a/includes/i18n/es.php +++ b/includes/i18n/es.php @@ -10,6 +10,8 @@ $i18n = [ "main_currency" => "Moneda Principal", "language" => "Idioma", "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.", "register" => "Registrar", "restore_database" => "Restaurar Base de Datos", @@ -18,6 +20,13 @@ $i18n = [ 'stay_logged_in' => "Mantener sesión iniciada (30 días)", 'login' => "Iniciar Sesión", '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 'subscriptions' => "Suscripciones", 'stats' => "Estadísticas", @@ -255,6 +264,24 @@ $i18n = [ // User "error_updating_user_data" => "Error al actualizar los datos del usuario.", "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", ]; diff --git a/includes/i18n/fr.php b/includes/i18n/fr.php index 39b5653..ab9e087 100644 --- a/includes/i18n/fr.php +++ b/includes/i18n/fr.php @@ -10,6 +10,8 @@ $i18n = [ "main_currency" => "Devise principale", "language" => "Langue", "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.", "register" => "S'inscrire", "restore_database" => "Restaurer la base de données", @@ -18,6 +20,13 @@ $i18n = [ 'stay_logged_in' => "Rester connecté (30 jours)", 'login' => "Se connecter", '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 'subscriptions' => "Abonnements", 'stats' => "Statistiques", @@ -255,6 +264,24 @@ $i18n = [ // 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", + // 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é", ]; diff --git a/includes/i18n/it.php b/includes/i18n/it.php index 13fe25e..b1ce8bb 100644 --- a/includes/i18n/it.php +++ b/includes/i18n/it.php @@ -10,6 +10,8 @@ $i18n = [ 'main_currency' => 'Valuta principale', 'language' => 'Lingua', '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.', 'register' => 'Registrati', "restore_database" => 'Ripristina database', @@ -19,6 +21,14 @@ $i18n = [ 'stay_logged_in' => 'Rimani connesso (30 giorni)', 'login' => 'Accedi', '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 'subscriptions' => 'Abbonamenti', @@ -269,6 +279,26 @@ $i18n = [ // User "error_updating_user_data" => "Errore nell'aggiornamento dei dati utente", "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", ]; ?> diff --git a/includes/i18n/jp.php b/includes/i18n/jp.php index 2f9da67..2e3b8a1 100644 --- a/includes/i18n/jp.php +++ b/includes/i18n/jp.php @@ -10,6 +10,8 @@ $i18n = [ "main_currency" => "主要通貨", "language" => "言語", "passwords_dont_match" => "パスワードが違います", + "username_exists" => "ユーザー名が既に存在します", + "email_exists" => "メールアドレスが既に存在します", "registration_failed" => "登録に失敗しました。もう一度お試しください。", "register" => "登録する", "restore_database" => "データベースをリストア", @@ -18,6 +20,13 @@ $i18n = [ 'stay_logged_in' => "ログインしたままにする (30日)", 'login' => "ログイン", 'login_failed' => "ログイン情報が間違っています", + 'registration_successful' => "登録に成功", + 'user_email_waiting_verification' => "Eメールの確認が必要です。メールを確認してください。", + // Password Reset Page + 'forgot_password' => "パスワードを忘れた場合", + 'reset_password' => "パスワードをリセット", + 'reset_sent_check_email' => "パスワードリセットリンクが送信されました。メールを確認してください。", + 'password_reset_successful' => "パスワードリセットに成功", // Header 'subscriptions' => "定期購入", 'stats' => "統計", @@ -255,6 +264,24 @@ $i18n = [ // User "error_updating_user_data" => "ユーザデータの更新エラー", "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" => "メールアドレスの確認に失敗しました", ]; diff --git a/includes/i18n/ko.php b/includes/i18n/ko.php index d1c9f7b..e7817de 100644 --- a/includes/i18n/ko.php +++ b/includes/i18n/ko.php @@ -10,6 +10,8 @@ $i18n = [ "main_currency" => "기본 통화", "language" => "언어", "passwords_dont_match" => "비밀번호가 일치하지 않습니다.", + "username_exists" => "이미 존재하는 유저명입니다.", + "email_exists" => "이미 존재하는 이메일입니다.", "registration_failed" => "회원가입 실패. 다시 시도해 주세요.", "register" => "회원가입", "restore_database" => "데이터베이스 복구", @@ -18,6 +20,13 @@ $i18n = [ 'stay_logged_in' => "로그인 유지 (30일)", 'login' => "로그인", 'login_failed' => "로그인 정보가 부정확합니다.", + 'registration_successful' => "등록 성공", + 'user_email_waiting_verification' => "이메일을 인증해야 합니다. 이메일을 확인해 주세요.", + // Password Reset Page + 'forgot_password' => "비밀번호를 잊으셨나요?", + 'reset_password' => "비밀번호 재설정", + 'reset_sent_check_email' => "비밀번호 재설정 이메일이 전송되었습니다. 이메일을 확인해 주세요.", + 'password_reset_successful' => "비밀번호 재설정 성공", // Header 'subscriptions' => "구독", 'stats' => "통계", @@ -255,6 +264,24 @@ $i18n = [ // User "error_updating_user_data" => "유저 데이터 갱신 실패.", "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" => "이메일 인증 실패", ]; diff --git a/includes/i18n/pl.php b/includes/i18n/pl.php index 3b1047c..b4140ef 100644 --- a/includes/i18n/pl.php +++ b/includes/i18n/pl.php @@ -10,6 +10,8 @@ $i18n = [ "main_currency" => "Główna waluta", "language" => "Język", "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.", "register" => "Rejestracja", "restore_database" => "Przywróć bazę danych", @@ -18,6 +20,13 @@ $i18n = [ 'stay_logged_in' => "Pozostań zalogowany (30 dni)", 'login' => "Zaloguj się", '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 'subscriptions' => "Subskrypcje", 'stats' => "Statystyki", @@ -255,6 +264,24 @@ $i18n = [ // User "error_updating_user_data" => "Błąd podczas aktualizacji danych użytkownika.", "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ę", ]; diff --git a/includes/i18n/pt.php b/includes/i18n/pt.php index a93a01c..fde510e 100644 --- a/includes/i18n/pt.php +++ b/includes/i18n/pt.php @@ -10,6 +10,8 @@ $i18n = [ "main_currency" => "Moeda Principal", "language" => "Linguagem", "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", "register" => "Registar", "restore_database" => "Restaurar base de dados", @@ -18,6 +20,13 @@ $i18n = [ 'stay_logged_in' => "Manter sessão (30 dias)", 'login' => "Iniciar Sessão", '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 'subscriptions' => "Subscrições", 'stats' => "Estatísticas", @@ -255,6 +264,24 @@ $i18n = [ // User "error_updating_user_data" => "Erro ao actualizar dados do utilizador.", "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", ]; diff --git a/includes/i18n/pt_br.php b/includes/i18n/pt_br.php index 10f3cdf..416258f 100644 --- a/includes/i18n/pt_br.php +++ b/includes/i18n/pt_br.php @@ -10,6 +10,8 @@ $i18n = [ "main_currency" => "Moeda principal", "language" => "Idioma", "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", "register" => "Registrar", "restore_database" => "Restaurar banco de dados", @@ -18,6 +20,13 @@ $i18n = [ 'stay_logged_in' => "Me manter logado (30 dias)", 'login' => "Login", '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 'subscriptions' => "Assinaturas", 'stats' => "Estatísticas", @@ -253,6 +262,24 @@ $i18n = [ // User "error_updating_user_data" => "Erro ao atualizar os dados do usuário", "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", ]; diff --git a/includes/i18n/ru.php b/includes/i18n/ru.php index 02059ad..5731a7b 100644 --- a/includes/i18n/ru.php +++ b/includes/i18n/ru.php @@ -10,6 +10,8 @@ $i18n = [ "main_currency" => "Основная валюта", "language" => "Язык", "passwords_dont_match" => "Пароли не совпадают", + "username_exists" => "Имя пользователя уже существует", + "email_exists" => "E-mail уже существует", "registration_failed" => "Регистрация не удалась, попробуйте еще раз.", "register" => "Регистрация", "restore_database" => "Восстановить базу данных", @@ -18,6 +20,13 @@ $i18n = [ 'stay_logged_in' => "Оставаться в системе (30 дней)", 'login' => "Авторизоваться", 'login_failed' => "Данные для входа неверны", + 'registration_successful' => "Регистрация прошла успешно", + 'user_email_waiting_verification' => "Ваша электронная почта нуждается в проверке. Пожалуйста, проверьте свою электронную почту", + // Password Reset Page + 'forgot_password' => "Забыли пароль?", + 'reset_password' => "Сбросить пароль", + 'reset_sent_check_email' => "Ссылка для сброса пароля отправлена на вашу электронную почту", + 'password_reset_successful' => "Пароль успешно сброшен", // Header 'subscriptions' => "Подписки", 'stats' => "Статистика", @@ -255,6 +264,24 @@ $i18n = [ // User "error_updating_user_data" => "Ошибка обновления пользовательских данных.", "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" => "Не удалось подтвердить ваш адрес электронной почты.", ]; diff --git a/includes/i18n/sr.php b/includes/i18n/sr.php index 38e967f..900ae4e 100644 --- a/includes/i18n/sr.php +++ b/includes/i18n/sr.php @@ -10,6 +10,8 @@ $i18n = [ "main_currency" => "Главна валута", "language" => "Језик", "passwords_dont_match" => "Лозинке се не поклапају", + "username_exists" => "Корисничко име већ постоји", + "email_exists" => "Е-пошта већ постоји", "registration_failed" => "Регистрација није успела, покушајте поново.", "register" => "Региструј се", "restore_database" => "Врати базу података", @@ -18,6 +20,13 @@ $i18n = [ 'stay_logged_in' => "Остани пријављен (30 дана)", 'login' => "Пријави се", 'login_failed' => "Подаци за пријаву нису исправни", + 'registration_successful' => "Пријава успешна", + 'user_email_waiting_verification' => "Ваша е-пошта треба да буде верификована. Молимо прегледајте Е-пошту", + // Password Reset Page + 'forgot_password' => "Заборављена лозинка", + 'reset_password' => "Ресетуј лозинку", + 'reset_sent_check_email' => "Ресетовање лозинке је послато на вашу е-пошту", + 'password_reset_successful' => "Ресетовање лозинке је успешно", // Header 'subscriptions' => "Претплате", 'stats' => "Статистике", @@ -254,6 +263,24 @@ $i18n = [ // Корисник "error_updating_user_data" => "Грешка при ажурирању корисничких података.", "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" => "Верификација е-поште није успела", ]; diff --git a/includes/i18n/sr_lat.php b/includes/i18n/sr_lat.php index f989c5b..44cf784 100644 --- a/includes/i18n/sr_lat.php +++ b/includes/i18n/sr_lat.php @@ -10,6 +10,8 @@ $i18n = [ "main_currency" => "Glavna valuta", "language" => "Jezik", "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.", "register" => "Registruj se", "restore_database" => "Vrati bazu podataka", @@ -18,6 +20,13 @@ $i18n = [ 'stay_logged_in' => "Ostani prijavljen (30 dana)", 'login' => "Prijavi se", '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 'subscriptions' => "Pretplate", 'stats' => "Statistike", @@ -255,6 +264,24 @@ $i18n = [ // Korisnik "error_updating_user_data" => "Greška pri ažuriranju korisničkih podataka.", "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", ]; diff --git a/includes/i18n/tr.php b/includes/i18n/tr.php index 7f8fd4d..7bf0a36 100644 --- a/includes/i18n/tr.php +++ b/includes/i18n/tr.php @@ -10,6 +10,8 @@ $i18n = [ "main_currency" => "Ana Para Birimi", "language" => "Dil", "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.", "register" => "Kayıt Ol", "restore_database" => "Veritabanını geri yükle", @@ -18,6 +20,13 @@ $i18n = [ 'stay_logged_in' => "Oturumu açık tut (30 gün)", 'login' => "Giriş Yap", '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 'subscriptions' => "Abonelikler", 'stats' => "İstatistikler", @@ -255,6 +264,25 @@ $i18n = [ // User "error_updating_user_data" => "Kullanıcı verileri güncellenirken hata oluştu.", "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", + ]; diff --git a/includes/i18n/zh_cn.php b/includes/i18n/zh_cn.php index 963b2f5..306a82e 100644 --- a/includes/i18n/zh_cn.php +++ b/includes/i18n/zh_cn.php @@ -10,6 +10,8 @@ $i18n = [ "main_currency" => "主要货币", "language" => "语言", "passwords_dont_match" => "密码不匹配", + "username_exists" => "用户名已存在", + "email_exists" => "电子邮箱已存在", "registration_failed" => "注册失败,请重试。", "register" => "注册", "restore_database" => "恢复数据库", @@ -19,6 +21,14 @@ $i18n = [ 'stay_logged_in' => "30 天内免登录", 'login' => "登录", 'login_failed' => "登录信息错误", + 'registration_successful' => "注册成功", + 'user_email_waiting_verification' => "您的电子邮件需要验证。请检查您的电子邮件", + + // Password Reset Page + 'forgot_password' => "忘记密码", + 'reset_password' => "重置密码", + 'reset_sent_check_email' => "重置密码链接已发送到您的电子邮箱", + 'password_reset_successful' => "密码重置成功", // 页眉 'subscriptions' => "订阅", @@ -272,6 +282,26 @@ $i18n = [ "error_updating_user_data" => "更新用户数据时出错。", "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" => "电子邮件验证失败", + ]; ?> diff --git a/includes/i18n/zh_tw.php b/includes/i18n/zh_tw.php index 3d39cdd..439cfd2 100644 --- a/includes/i18n/zh_tw.php +++ b/includes/i18n/zh_tw.php @@ -10,6 +10,8 @@ $i18n = [ "main_currency" => "主要貨幣單位", "language" => "語言", "passwords_dont_match" => "密碼不一致", + "username_exists" => "使用者名稱已存在", + "email_exists" => "電子信箱已存在", "registration_failed" => "註冊失敗,請再試一次。", "register" => "註冊", "restore_database" => "還原資料庫", @@ -18,6 +20,13 @@ $i18n = [ 'stay_logged_in' => "保持登入 30 天", 'login' => "登入", 'login_failed' => "登入資訊錯誤", + 'registration_successful' => "註冊成功", + 'user_email_waiting_verification' => "您的電子郵件需要驗證。 請查看你的信箱", + // Password Reset Page + 'forgot_password' => "忘記密碼", + 'reset_password' => "重設密碼", + 'reset_sent_check_email' => "重設密碼的電子郵件已發送,請檢查您的電子郵件", + 'password_reset_successful' => "密碼重設成功", // 頁首 'subscriptions' => "訂閱", 'stats' => "統計", @@ -255,6 +264,24 @@ $i18n = [ // User "error_updating_user_data" => "更新使用者資訊時發生錯誤。", "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" => "電子郵件驗證失敗", ]; diff --git a/includes/list_subscriptions.php b/includes/list_subscriptions.php index c03f4ad..fd40448 100644 --- a/includes/list_subscriptions.php +++ b/includes/list_subscriptions.php @@ -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->bindValue(':userId', $userId, SQLITE3_INTEGER); $result = $stmt->execute(); $row = $result->fetchArray(SQLITE3_ASSOC); $mainCurrencyId = $row['main_currency']; diff --git a/includes/version.php b/includes/version.php index 09f588f..736063a 100644 --- a/includes/version.php +++ b/includes/version.php @@ -1,3 +1,3 @@ diff --git a/index.php b/index.php index 758c16a..fc94e88 100644 --- a/index.php +++ b/index.php @@ -5,7 +5,7 @@ include_once 'includes/list_subscriptions.php'; $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'] != "") { $sort = $_COOKIE['sortOrder']; $allowedSortCriteria = ['name', 'id', 'next_payment', 'price', 'payer_user_id', 'category_id', 'payment_method_id']; @@ -14,11 +14,13 @@ $order = "DESC"; } 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) { $subscriptions = array(); while ($row = $result->fetchArray(SQLITE3_ASSOC)) { @@ -160,7 +162,7 @@ $print[$id]['currency_code'] = $currencies[$subscription['currency_id']]['code']; $currencyId = $subscription['currency_id']; $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_name'] = $payment_methods[$paymentMethodId]['name']; $print[$id]['payment_method_id'] = $paymentMethodId; diff --git a/login.php b/login.php index 6b7c6a3..8790819 100644 --- a/login.php +++ b/login.php @@ -31,6 +31,8 @@ if (isset($_COOKIE['colorTheme'])) { } $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'])) { $username = $_POST['username']; $password = $_POST['password']; @@ -48,26 +50,47 @@ if (isset($_POST['username']) && isset($_POST['password'])) { $main_currency = $row['main_currency']; $language = $row['language']; if (password_verify($password, $hashedPasswordFromDb)) { - $_SESSION['username'] = $username; - $_SESSION['loggedin'] = true; - $_SESSION['main_currency'] = $main_currency; - $_SESSION['userId'] = $userId; - $cookieExpire = time() + (30 * 24 * 60 * 60); - setcookie('language', $language, $cookieExpire); - if ($rememberMe) { - $token = bin2hex(random_bytes(32)); - $addLoginTokens = "INSERT INTO login_tokens (user_id, token) VALUES (?, ?)"; - $addLoginTokensStmt = $db->prepare($addLoginTokens); - $addLoginTokensStmt->bindValue(1, $userId, SQLITE3_INTEGER); - $addLoginTokensStmt->bindValue(2, $token, SQLITE3_TEXT); - $addLoginTokensStmt->execute(); - $_SESSION['token'] = $token; - $cookieValue = $username . "|" . $token . "|" . $main_currency; - setcookie('wallos_login', $cookieValue, $cookieExpire); + + // Check if the user is in the email_verification table + $query = "SELECT 1 FROM email_verification WHERE user_id = :userId"; + $stmt = $db->prepare($query); + $stmt->bindValue(':userId', $userId, SQLITE3_INTEGER); + $result = $stmt->execute(); + $verificationRow = $result->fetchArray(SQLITE3_ASSOC); + + if ($verificationRow) { + $userEmailWaitingVerification = true; + $loginFailed = true; + } else { + $_SESSION['username'] = $username; + $_SESSION['loggedin'] = true; + $_SESSION['main_currency'] = $main_currency; + $_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 { $loginFailed = true; } @@ -75,6 +98,32 @@ if (isset($_POST['username']) && isset($_POST['password'])) { $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; +} + ?> @@ -91,6 +140,7 @@ if (isset($_POST['username']) && isset($_POST['password'])) { > > > + > @@ -122,20 +172,74 @@ if (isset($_POST['username']) && isset($_POST['password'])) {
- - - . - -
+ +
    + +
  • + +
  • + +
+ +
    + +
  • + +
  • + +
  • + +
+ + + + +
+ +
+
+ \ No newline at end of file diff --git a/logout.php b/logout.php index 700b087..3c7b112 100644 --- a/logout.php +++ b/logout.php @@ -4,16 +4,17 @@ // get token from cookie to remove from DB if (isset($_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->bindValue(1, $token, SQLITE3_TEXT); + $stmt->bindParam(':token', $token, SQLITE3_TEXT); + $stmt->bindParam(':userId', $userId, SQLITE3_INTEGER); $stmt->execute(); } $_SESSION = array(); session_destroy(); $cookieExpire = time() - 3600; - setcookie('wallos_login', '', $cookieExpire); + setcookie('wallos_login', '', $cookieExpire); $db->close(); - header("Location: ."); + header("Location: ."); exit(); ?> \ No newline at end of file diff --git a/migrations/000020.php b/migrations/000020.php new file mode 100644 index 0000000..9bd1ce9 --- /dev/null +++ b/migrations/000020.php @@ -0,0 +1,54 @@ +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)'); + +?> \ No newline at end of file diff --git a/passwordreset.php b/passwordreset.php new file mode 100644 index 0000000..b5a453e --- /dev/null +++ b/passwordreset.php @@ -0,0 +1,224 @@ +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; + } +} + +?> + + + + + + "/> + Wallos - Subscription Tracker + + + + + + > + > + > + + + > + + +
+
+
+ Wallos Logo Wallos Logo +

+ +

+
+
+ +
+ + +
+
+ +
+ +
    +
  • +
+ +
    +
  • +
+ +
+ + + + +
+
+ + +
+
+ +
+ +
    +
  • +
+ +
    +
  • +
+ +
    +
  • +
+ + +
+
+
+ + + + +?> \ No newline at end of file diff --git a/registration.php b/registration.php index 225b5f0..689adb0 100644 --- a/registration.php +++ b/registration.php @@ -16,11 +16,32 @@ function validate($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) { - header("Location: login.php"); - exit(); + $stmt = $db->prepare('SELECT * FROM admin'); + $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"; if (isset($_COOKIE['theme'])) { $theme = $_COOKIE['theme']; @@ -31,16 +52,100 @@ if (isset($_COOKIE['colorTheme'])) { $colorTheme = $_COOKIE['colorTheme']; } -$currencies = array(); -$query = "SELECT * FROM currencies"; -$result = $db->query($query); -while ($row = $result->fetchArray(SQLITE3_ASSOC)) { - $currencyId = $row['id']; - $currencies[$currencyId] = $row; -} +$currencies = [ + ['id' => 1, 'name' => 'Euro', 'symbol' => '€', 'code' => 'EUR'], + ['id' => 2, 'name' => 'US Dollar', 'symbol' => '$', 'code' => 'USD'], + ['id' => 3, 'name' => 'Japanese Yen', 'symbol' => '¥', 'code' => 'JPY'], + ['id' => 4, 'name' => 'Bulgarian Lev', 'symbol' => 'лв', 'code' => 'BGN'], + ['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; +$usernameExists = false; +$emailExists = false; $registrationFailed = false; +$hasErrors = false; if (isset($_POST['username'])) { $username = validate($_POST['username']); $email = validate($_POST['email']); @@ -52,42 +157,139 @@ if (isset($_POST['username'])) { if ($password != $confirm_password) { $passwordMismatch = true; - } else { - $query = "INSERT INTO user (username, email, password, main_currency, avatar, language) VALUES (:username, :email, :password, :main_currency, :avatar, :language)"; + $hasErrors = true; + } + + $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); $hashedPassword = password_hash($password, PASSWORD_DEFAULT); $stmt->bindValue(':username', $username, SQLITE3_TEXT); $stmt->bindValue(':email', $email, 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(':language', $language, SQLITE3_TEXT); + $stmt->bindValue(':budget', 0, SQLITE3_INTEGER); $result = $stmt->execute(); if ($result) { - $deleteQuery = "DELETE FROM household"; - $stmtDelete = $db->prepare($deleteQuery); - $stmtDelete->execute(); - $deleteQuery = "DELETE FROM subscriptions"; - $stmtDelete = $db->prepare($deleteQuery); - $stmtDelete->execute(); + // Get id of the newly created user + $userId = $db->lastInsertRowID(); - $deleteQuery = "DELETE FROM fixer"; - $stmtDelete = $db->prepare($deleteQuery); - $stmtDelete->execute(); - - $query = "INSERT INTO household (name) VALUES (:name)"; + // Add username as household member for that user + $query = "INSERT INTO household (name, user_id) VALUES (:name, :user_id)"; $stmt = $db->prepare($query); $stmt->bindValue(':name', $username, SQLITE3_TEXT); + $stmt->bindValue(':user_id', $userId, SQLITE3_INTEGER); $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(); - header("Location: login.php"); + header("Location: login.php?registered=true&requireValidation=$requireValidation"); exit(); } else { $registrationFailed = true; } - } + } } ?> @@ -106,6 +308,7 @@ if (isset($_POST['username'])) { > > > + @@ -147,7 +350,7 @@ if (isset($_POST['username'])) { - + @@ -166,32 +369,59 @@ if (isset($_POST['username'])) { ?> + - - - - - - - - + + +
-
- - -
+ +
+ + +
+
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', { +function makeFetchCall(url, data, button) { + return fetch(url, { 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(data => { if (data.success) { - showSuccessMessage(data.message) - window.location.href = 'logout.php'; + 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.message); + showErrorMessage(data.errorMessage); + button.disabled = false; } }) - .catch(error => showErrorMessage('Error:', error)); - } \ No newline at end of file + .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)); + +} \ No newline at end of file diff --git a/service-worker.js b/service-worker.js index 5e81d39..29ced3c 100644 --- a/service-worker.js +++ b/service-worker.js @@ -28,6 +28,7 @@ self.addEventListener('install', function(event) { 'scripts/settings.js', 'scripts/notifications.js', 'scripts/registration.js', + 'scripts/admin.js', 'scripts/i18n/en.js', 'scripts/i18n/de.js', 'scripts/i18n/el.js', diff --git a/settings.php b/settings.php index 594423a..8b40556 100644 --- a/settings.php +++ b/settings.php @@ -52,7 +52,7 @@
- +
@@ -68,8 +68,10 @@
query($query); + $query = "SELECT * FROM currencies WHERE user_id = :userId"; + $query = $db->prepare($query); + $query->bindValue(':userId', $userId, SQLITE3_INTEGER); + $result = $query->execute(); while ($row = $result->fetchArray(SQLITE3_ASSOC)) { $currencyId = $row['id']; $currencies[$currencyId] = $row; @@ -135,8 +137,10 @@ query($sql); + $sql = "SELECT * FROM household WHERE user_id = :userId"; + $stmt = $db->prepare($sql); + $stmt->bindValue(':userId', $userId, SQLITE3_INTEGER); + $result = $stmt->execute(); if ($result) { $household = array(); @@ -153,12 +157,12 @@
$member) { ?>
" placeholder=""> /save.png" title="">