├── .dockerignore
├── .github
├── FUNDING.yml
└── workflows
│ └── build-release.yaml
├── .gitignore
├── .tmp
└── .gitignore
├── CHANGELOG.md
├── CONTRIBUTING.md
├── Dockerfile
├── LICENSE.md
├── README.md
├── SECURITY.md
├── about.php
├── admin.php
├── api
├── admin
│ └── get_admin_settings.php
├── categories
│ └── get_categories.php
├── currencies
│ └── get_currencies.php
├── fixer
│ └── get_fixer.php
├── household
│ └── get_household.php
├── notifications
│ └── get_notification_settings.php
├── payment_methods
│ └── get_payment_methods.php
├── settings
│ └── get_settings.php
├── status
│ └── version.php
├── subscriptions
│ ├── get_ical_feed.php
│ ├── get_monthly_cost.php
│ └── get_subscriptions.php
└── users
│ └── get_user.php
├── calendar.php
├── cronjobs
├── db
└── wallos.empty.db
├── docker-compose.yaml
├── endpoints
├── admin
│ ├── adduser.php
│ ├── deleteunusedlogos.php
│ ├── deleteuser.php
│ ├── saveopenregistrations.php
│ ├── savesmtpsettings.php
│ └── updatenotification.php
├── categories
│ ├── category.php
│ └── sort.php
├── cronjobs
│ ├── checkforupdates.php
│ ├── createdatabase.php
│ ├── sendcancellationnotifications.php
│ ├── sendnotifications.php
│ ├── sendresetpasswordemails.php
│ ├── sendverificationemails.php
│ ├── settimezone.php
│ ├── storetotalyearlycost.php
│ ├── updateexchange.php
│ ├── updatenextpayment.php
│ └── validate.php
├── currency
│ ├── add.php
│ ├── currency.php
│ ├── edit.php
│ ├── fixer_api_key.php
│ ├── remove.php
│ └── update_exchange.php
├── db
│ ├── backup.php
│ ├── import.php
│ ├── migrate.php
│ └── restore.php
├── household
│ └── household.php
├── logos
│ └── search.php
├── notifications
│ ├── savediscordnotifications.php
│ ├── saveemailnotifications.php
│ ├── savegotifynotifications.php
│ ├── savenotificationsettings.php
│ ├── saventfynotifications.php
│ ├── savepushovernotifications.php
│ ├── savetelegramnotifications.php
│ ├── savewebhooknotifications.php
│ ├── testdiscordnotifications.php
│ ├── testemailnotifications.php
│ ├── testgotifynotifications.php
│ ├── testntfynotifications.php
│ ├── testpushovernotifications.php
│ ├── testtelegramnotifications.php
│ └── testwebhooknotifications.php
├── payments
│ ├── add.php
│ ├── delete.php
│ ├── get.php
│ ├── payment.php
│ ├── rename.php
│ ├── search.php
│ └── sort.php
├── settings
│ ├── colortheme.php
│ ├── convert_currency.php
│ ├── customcss.php
│ ├── customtheme.php
│ ├── deleteaccount.php
│ ├── disabled_to_bottom.php
│ ├── hide_disabled.php
│ ├── mobile_navigation.php
│ ├── monthly_price.php
│ ├── remove_background.php
│ ├── resettheme.php
│ ├── show_original_price.php
│ ├── subscription_progress.php
│ └── theme.php
├── subscription
│ ├── add.php
│ ├── clone.php
│ ├── delete.php
│ ├── exportcalendar.php
│ ├── get.php
│ ├── getcalendar.php
│ └── renew.php
├── subscriptions
│ ├── export.php
│ └── get.php
└── user
│ ├── budget.php
│ ├── delete_avatar.php
│ ├── disable_totp.php
│ ├── enable_totp.php
│ ├── regenerateapikey.php
│ └── save_user.php
├── images
├── Thumbs.db
├── avatars
│ ├── 0.svg
│ ├── 1.svg
│ ├── 2.svg
│ ├── 3.svg
│ ├── 4.svg
│ ├── 5.svg
│ ├── 6.svg
│ ├── 7.svg
│ ├── 8.svg
│ └── 9.svg
├── icon
│ ├── android-chrome-192x192.png
│ ├── android-chrome-512x512.png
│ ├── apple-touch-icon-152.png
│ ├── apple-touch-icon-180.png
│ ├── apple-touch-icon.png
│ ├── favicon-16x16.png
│ ├── favicon-32x32.png
│ ├── favicon.ico
│ ├── maskable_icon_x192.png
│ └── maskable_icon_x512.png
├── screenshots
│ ├── desktop.png
│ └── mobile.png
├── siteicons
│ ├── payments
│ │ ├── Amex.png
│ │ ├── ApplePay.png
│ │ ├── Bitcoin.png
│ │ ├── BitcoinCash.png
│ │ ├── DinersClub.png
│ │ ├── Discover.png
│ │ ├── Etherium.png
│ │ ├── Forbrugsforeningen.png
│ │ ├── GooglePay.png
│ │ ├── Interac.png
│ │ ├── JCB.png
│ │ ├── Klarna.png
│ │ ├── Lightcoin.png
│ │ ├── Maestro.png
│ │ ├── Mastercard.png
│ │ ├── PayPal.png
│ │ ├── Payoneer.png
│ │ ├── Stripe.png
│ │ ├── Thumbs.db
│ │ ├── Visa.png
│ │ ├── Yandex.png
│ │ ├── affirm.png
│ │ ├── alipay.png
│ │ ├── amazonpay.png
│ │ ├── bancontact.png
│ │ ├── bitpay.png
│ │ ├── citadele.png
│ │ ├── directdebit.png
│ │ ├── elo.png
│ │ ├── facebookpay.png
│ │ ├── gitopay.png
│ │ ├── ideal.png
│ │ ├── paysafe.png
│ │ ├── poli.png
│ │ ├── qiwi.png
│ │ ├── samsungpay.png
│ │ ├── shoppay.png
│ │ ├── skrill.png
│ │ ├── sofort.png
│ │ ├── unionpay.png
│ │ ├── venmo.png
│ │ ├── verifone.png
│ │ ├── webmoney.png
│ │ └── wechat.png
│ ├── pwa
│ │ ├── about.png
│ │ ├── calendar.png
│ │ ├── settings.png
│ │ ├── stats.png
│ │ └── subscriptions.png
│ ├── svg
│ │ ├── automatic.php
│ │ ├── category.php
│ │ ├── check.php
│ │ ├── clone.php
│ │ ├── delete.php
│ │ ├── edit.php
│ │ ├── export_ical.php
│ │ ├── logo.php
│ │ ├── manual.php
│ │ ├── mobile-menu
│ │ │ ├── about.php
│ │ │ ├── admin.php
│ │ │ ├── calendar.php
│ │ │ ├── clone.php
│ │ │ ├── delete.php
│ │ │ ├── edit.php
│ │ │ ├── home.php
│ │ │ ├── logout.php
│ │ │ ├── profile.php
│ │ │ ├── renew.php
│ │ │ ├── settings.php
│ │ │ └── statistics.php
│ │ ├── notes.php
│ │ ├── payment.php
│ │ ├── renew.php
│ │ ├── save.php
│ │ ├── subscription.php
│ │ ├── web.php
│ │ └── websearch.php
│ ├── wallos.png
│ └── walloswhite.png
├── siteimages
│ ├── Thumbs.db
│ ├── empty.png
│ ├── emptydark.png
│ ├── mobilenav.png
│ └── mobilenavdark.png
├── uploads
│ └── icons
│ │ ├── Thumbs.db
│ │ ├── affirm.png
│ │ ├── alipay.png
│ │ ├── amazonpay.png
│ │ ├── applepay.png
│ │ ├── banktransfer.png
│ │ ├── creditcard.png
│ │ ├── crypto.png
│ │ ├── directdebit.png
│ │ ├── elo.png
│ │ ├── facebookpay.png
│ │ ├── giropay.png
│ │ ├── googlepay.png
│ │ ├── ideal.png
│ │ ├── interac.png
│ │ ├── klarna.png
│ │ ├── money.png
│ │ ├── paypal.png
│ │ ├── paysafe.png
│ │ ├── poli.png
│ │ ├── qiwi.png
│ │ ├── samsungpay.png
│ │ ├── sepa.png
│ │ ├── shoppay.png
│ │ ├── skrill.png
│ │ ├── sofort.png
│ │ ├── stripe.png
│ │ ├── unionpay.png
│ │ ├── venmo.png
│ │ ├── verifone.png
│ │ ├── webmoney.png
│ │ └── wechat.png
├── wallossolid.png
└── wallossolidwhite.png
├── includes
├── checksession.php
├── checkuser.php
├── connect.php
├── connect_endpoint.php
├── connect_endpoint_crontabs.php
├── currency_formatter.php
├── filters_menu.php
├── footer.php
├── getdbkeys.php
├── getsettings.php
├── header.php
├── i18n
│ ├── cs.php
│ ├── da.php
│ ├── de.php
│ ├── el.php
│ ├── en.php
│ ├── es.php
│ ├── fr.php
│ ├── getlang.php
│ ├── id.php
│ ├── it.php
│ ├── jp.php
│ ├── ko.php
│ ├── languages.php
│ ├── nl.php
│ ├── pl.php
│ ├── pt.php
│ ├── pt_br.php
│ ├── ru.php
│ ├── sl.php
│ ├── sr.php
│ ├── sr_lat.php
│ ├── tr.php
│ ├── uk.php
│ ├── vi.php
│ ├── zh_cn.php
│ └── zh_tw.php
├── inputvalidation.php
├── list_subscriptions.php
├── sort_options.php
└── version.php
├── index.php
├── libs
├── OTPHP
│ ├── Factory.php
│ ├── FactoryInterface.php
│ ├── HOTP.php
│ ├── HOTPInterface.php
│ ├── InternalClock.php
│ ├── OTP.php
│ ├── OTPInterface.php
│ ├── ParameterTrait.php
│ ├── TOTP.php
│ ├── TOTPInterface.php
│ └── Url.php
├── PHPMailer
│ ├── Exception.php
│ ├── PHPMailer.php
│ └── SMTP.php
├── Psr
│ └── Clock
│ │ └── ClockInterface.php
└── constant_time_encoding
│ ├── Base32.php
│ ├── Base32Hex.php
│ ├── Base64.php
│ ├── Base64DotSlash.php
│ ├── Base64DotSlashOrdered.php
│ ├── Base64UrlSafe.php
│ ├── Binary.php
│ ├── EncoderInterface.php
│ ├── Encoding.php
│ ├── Hex.php
│ └── RFC4648.php
├── login.php
├── logos.php
├── logout.php
├── manifest.json
├── migrations
├── 000001.php
├── 000002.php
├── 000003.php
├── 000004.php
├── 000005.php
├── 000006.php
├── 000007.php
├── 000008.php
├── 000009.php
├── 000010.php
├── 000011.php
├── 000012.php
├── 000013.php
├── 000014.php
├── 000015.php
├── 000016.php
├── 000017.php
├── 000018.php
├── 000019.php
├── 000020.php
├── 000021.php
├── 000022.php
├── 000023.php
├── 000024.php
├── 000025.php
├── 000026.php
├── 000027.php
├── 000028.php
├── 000029.php
├── 000030.php
├── 000031.php
├── 000032.php
├── 000033.php
├── 000034.php
├── 000035.php
└── 000036.php
├── nginx.conf
├── nginx.default.conf
├── passwordreset.php
├── profile.php
├── registration.php
├── screenshots
├── wallos-calendar.png
├── wallos-dashboard-dark.png
├── wallos-dashboard-light.png
├── wallos-dashboard-mobile-dark.png
├── wallos-dashboard-mobile-light.png
├── wallos-form.png
└── wallos-stats.png
├── scripts
├── admin.js
├── all.js
├── calendar.js
├── common.js
├── dashboard.js
├── i18n
│ ├── cs.js
│ ├── da.js
│ ├── de.js
│ ├── el.js
│ ├── en.js
│ ├── es.js
│ ├── fr.js
│ ├── getlang.js
│ ├── id.js
│ ├── it.js
│ ├── jp.js
│ ├── ko.js
│ ├── nl.js
│ ├── pl.js
│ ├── pt.js
│ ├── pt_br.js
│ ├── ru.js
│ ├── sl.js
│ ├── sr.js
│ ├── sr_lat.js
│ ├── tr.js
│ ├── uk.js
│ ├── vi.js
│ ├── zh_cn.js
│ └── zh_tw.js
├── libs
│ ├── chart.js
│ ├── qrcode.min.js
│ └── sortable.min.js
├── login.js
├── notifications.js
├── profile.js
├── registration.js
├── settings.js
├── stats.js
└── theme.js
├── service-worker.js
├── settings.php
├── startup.sh
├── stats.php
├── styles
├── barlow.css
├── brands.css
├── dark-theme.css
├── font-awesome.min.css
├── login-dark-theme.css
├── login.css
├── styles.css
├── theme.css
└── themes
│ ├── green.css
│ ├── purple.css
│ ├── red.css
│ └── yellow.css
├── totp.php
├── verifyemail.php
└── webfonts
├── fa-brands-400.ttf
├── fa-brands-400.woff2
├── fa-regular-400.ttf
├── fa-regular-400.woff2
├── fa-solid-900.ttf
└── fa-solid-900.woff2
/.dockerignore:
--------------------------------------------------------------------------------
1 | # Exclude .vscode directory
2 | .vscode/
3 |
4 | # Exclude .git directory
5 | .git/
--------------------------------------------------------------------------------
/.github/FUNDING.yml:
--------------------------------------------------------------------------------
1 | # These are supported funding model platforms
2 |
3 | github: [ellite]
4 | custom: ['https://www.paypal.com/paypalme/miguelr']
5 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | /db/*
2 | !/db/wallos.empty.db
3 | /images/uploads/logos/*
4 | !/images/uploads/logos/wallos.png
5 | .DS_Store
6 | .idea/
7 | .vscode/
8 |
--------------------------------------------------------------------------------
/.tmp/.gitignore:
--------------------------------------------------------------------------------
1 | *
2 | !.gitignore
3 |
--------------------------------------------------------------------------------
/Dockerfile:
--------------------------------------------------------------------------------
1 | # Use the php:8.2-fpm-alpine base image
2 | FROM php:8.2-fpm-alpine
3 |
4 | # Set working directory to /var/www/html
5 | WORKDIR /var/www/html
6 |
7 | # Update packages and install dependencies
8 | RUN apk upgrade --no-cache && \
9 | apk add --no-cache shadow sqlite-dev libpng libpng-dev libjpeg-turbo libjpeg-turbo-dev freetype freetype-dev curl autoconf libgomp icu-dev icu-data-full nginx dcron tzdata imagemagick imagemagick-dev libzip-dev sqlite libwebp-dev && \
10 | docker-php-ext-install pdo pdo_sqlite calendar && \
11 | docker-php-ext-enable pdo pdo_sqlite && \
12 | docker-php-ext-configure gd --with-freetype --with-jpeg --with-webp && \
13 | docker-php-ext-install -j$(nproc) gd intl zip && \
14 | apk add --no-cache --virtual .build-deps $PHPIZE_DEPS && \
15 | pecl install imagick && \
16 | docker-php-ext-enable imagick && \
17 | apk del .build-deps
18 |
19 | # Copy your PHP application files into the container
20 | COPY . .
21 |
22 | # Copy Nginx configuration
23 | COPY nginx.conf /etc/nginx/nginx.conf
24 | COPY nginx.default.conf /etc/nginx/http.d/default.conf
25 |
26 | # Copy the custom crontab file
27 | COPY cronjobs /etc/cron.d/cronjobs
28 |
29 | # Convert the line endings, allow read access to the cron file, and create cron log folder
30 | RUN dos2unix /etc/cron.d/cronjobs && \
31 | chmod 0644 /etc/cron.d/cronjobs && \
32 | /usr/bin/crontab /etc/cron.d/cronjobs && \
33 | mkdir /var/log/cron && \
34 | chown -R www-data:www-data /var/www/html && \
35 | chmod +x /var/www/html/startup.sh && \
36 | echo 'pm.max_children = 15' >> /usr/local/etc/php-fpm.d/zz-docker.conf && \
37 | echo 'pm.max_requests = 500' >> /usr/local/etc/php-fpm.d/zz-docker.conf
38 |
39 | # Expose port 80 for Nginx
40 | EXPOSE 80
41 |
42 | ARG SOFTWARE_VERSION=1.20.0
43 |
44 | # Start both PHP-FPM, Nginx
45 | CMD ["sh", "-c", "/var/www/html/startup.sh"]
46 |
--------------------------------------------------------------------------------
/SECURITY.md:
--------------------------------------------------------------------------------
1 | # Security Policy
2 |
3 | ## Reporting a Vulnerability
4 |
5 | If you discover any security vulnerabilities in this project, please report them to the developer by emailing [wallos@henrique.pt](mailto:wallos@henrique.pt). I appreciate your help in keeping the project secure.
6 |
7 | ## Supported Versions
8 |
9 | This project is currently supported with security updates for the following versions:
10 |
11 | | Version | Supported |
12 | | ------- | ------------------ |
13 | | latest | :white_check_mark: |
14 | | main | :white_check_mark: |
15 | | 1.x.x | :x: |
16 |
17 | ## Security Measures
18 |
19 | I take security seriously and am working on ways to implement security measures to protect the project.
20 |
21 | What is being done currenty:
22 | - Periodically scan the docker image for vulnerabilities with trivy.
23 |
24 | ## Reporting a Security Concern
25 |
26 | If you have any security concerns or questions regarding the security of this project, please contact the developer at [wallos@henrique.pt](mailto:wallos@henrique.pt).
27 |
28 | ## Responsible Disclosure
29 |
30 | I kindly request that you follow responsible disclosure practices and give me reasonable time to address any reported vulnerabilities before making them public.
31 |
32 |
--------------------------------------------------------------------------------
/cronjobs:
--------------------------------------------------------------------------------
1 | # Run the scripts every day
2 | 0 1 * * * /usr/local/bin/php /var/www/html/endpoints/cronjobs/updatenextpayment.php >> /var/log/cron/updatenextpayment.log 2>&1
3 | 0 2 * * * /usr/local/bin/php /var/www/html/endpoints/cronjobs/updateexchange.php >> /var/log/cron/updateexchange.log 2>&1
4 | 0 8 * * * /usr/local/bin/php /var/www/html/endpoints/cronjobs/sendcancellationnotifications.php >> /var/log/cron/sendcancellationnotifications.log 2>&1
5 | 0 9 * * * /usr/local/bin/php /var/www/html/endpoints/cronjobs/sendnotifications.php >> /var/log/cron/sendnotifications.log 2>&1
6 | */2 * * * * /usr/local/bin/php /var/www/html/endpoints/cronjobs/sendverificationemails.php >> /var/log/cron/sendverificationemails.log 2>&1
7 | */2 * * * * /usr/local/bin/php /var/www/html/endpoints/cronjobs/sendresetpasswordemails.php >> /var/log/cron/sendresetpasswordemails.log 2>&1
8 | 0 */6 * * * /usr/local/bin/php /var/www/html/endpoints/cronjobs/checkforupdates.php >> /var/log/cron/checkforupdates.log 2>&1
9 | 30 1 * * 1 /usr/local/bin/php /var/www/html/endpoints/cronjobs/storetotalyearlycost.php >> /var/log/cron/storetotalyearlycost.log 2>&1
--------------------------------------------------------------------------------
/db/wallos.empty.db:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ellite/Wallos/a7e26f688a00101bda85606d59cdd500d1cd6970/db/wallos.empty.db
--------------------------------------------------------------------------------
/docker-compose.yaml:
--------------------------------------------------------------------------------
1 | services:
2 | wallos:
3 | container_name: wallos
4 | image: bellamy/wallos:latest
5 | ports:
6 | - "8282:80/tcp"
7 | environment:
8 | TZ: 'America/Toronto'
9 | # Volumes store your data between container upgrades
10 | volumes:
11 | - './db:/var/www/html/db'
12 | - './logos:/var/www/html/images/uploads/logos'
13 | restart: unless-stopped
14 |
--------------------------------------------------------------------------------
/endpoints/admin/deleteunusedlogos.php:
--------------------------------------------------------------------------------
1 | false,
8 | "message" => translate('session_expired', $i18n)
9 | ]));
10 | }
11 |
12 | // Check that user is an admin
13 | if ($userId !== 1) {
14 | die(json_encode([
15 | "success" => false,
16 | "message" => translate('error', $i18n)
17 | ]));
18 | }
19 |
20 | $query = 'SELECT logo FROM subscriptions';
21 | $stmt = $db->prepare($query);
22 | $result = $stmt->execute();
23 |
24 | $logosOnDB = [];
25 | while ($row = $result->fetchArray(SQLITE3_ASSOC)) {
26 | $logosOnDB[] = $row['logo'];
27 | }
28 |
29 | $logosOnDB = array_unique($logosOnDB);
30 |
31 | $uploadDir = '../../images/uploads/logos/';
32 | $uploadFiles = scandir($uploadDir);
33 |
34 | foreach ($uploadFiles as $file) {
35 | if ($file != '.' && $file != '..' && $file != 'avatars') {
36 | $logosOnDisk[] = ['logo' => $file];
37 | }
38 | }
39 |
40 | // Get all logos in the payment_methods table
41 | $query = 'SELECT icon FROM payment_methods';
42 | $stmt = $db->prepare($query);
43 | $result = $stmt->execute();
44 |
45 | while ($row = $result->fetchArray(SQLITE3_ASSOC)) {
46 | if (!strstr($row['icon'], "images/uploads/icons/")) {
47 | $logosOnDB[] = $row['icon'];
48 | }
49 | }
50 |
51 | $logosOnDB = array_unique($logosOnDB);
52 |
53 | // Find and delete unused logos
54 | $count = 0;
55 | foreach ($logosOnDisk as $disk) {
56 | foreach ($logosOnDB as $db) {
57 | $found = false;
58 | if ($disk['logo'] == $db) {
59 | $found = true;
60 | break;
61 | }
62 | }
63 | if (!$found) {
64 | unlink($uploadDir . $disk['logo']);
65 | $count++;
66 | }
67 | }
68 |
69 | echo json_encode([
70 | "success" => true,
71 | "message" => translate('success', $i18n),
72 | 'count' => $count
73 | ]);
74 |
75 |
76 | ?>
--------------------------------------------------------------------------------
/endpoints/admin/savesmtpsettings.php:
--------------------------------------------------------------------------------
1 | false,
8 | "message" => translate('session_expired', $i18n)
9 | ]));
10 | }
11 |
12 | // Check that user is an admin
13 | if ($userId !== 1) {
14 | die(json_encode([
15 | "success" => false,
16 | "message" => translate('error', $i18n)
17 | ]));
18 | }
19 |
20 | if ($_SERVER["REQUEST_METHOD"] === "POST") {
21 |
22 | $postData = file_get_contents("php://input");
23 | $data = json_decode($postData, true);
24 |
25 | $smtpAddress = $data['smtpaddress'];
26 | $smtpPort = $data['smtpport'];
27 | $encryption = $data['encryption'];
28 | $smtpUsername = $data['smtpusername'];
29 | $smtpPassword = $data['smtppassword'];
30 | $fromEmail = $data['fromemail'];
31 |
32 | if (empty($smtpAddress) || empty($smtpPort)) {
33 | die(json_encode([
34 | "success" => false,
35 | "message" => translate('fill_all_fields', $i18n)
36 | ]));
37 | }
38 |
39 | // Save settings
40 | $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');
41 | $stmt->bindValue(':smtp_address', $smtpAddress, SQLITE3_TEXT);
42 | $stmt->bindValue(':smtp_port', $smtpPort, SQLITE3_TEXT);
43 | $encryption = empty($data['encryption']) ? 'tls' : $data['encryption'];
44 | $stmt->bindValue(':encryption', $encryption, SQLITE3_TEXT);
45 | $stmt->bindValue(':smtp_username', $smtpUsername, SQLITE3_TEXT);
46 | $stmt->bindValue(':smtp_password', $smtpPassword, SQLITE3_TEXT);
47 | $stmt->bindValue(':from_email', $fromEmail, SQLITE3_TEXT);
48 | $result = $stmt->execute();
49 |
50 | if ($result) {
51 | die(json_encode([
52 | "success" => true,
53 | "message" => translate('success', $i18n)
54 | ]));
55 | } else {
56 | die(json_encode([
57 | "success" => false,
58 | "message" => translate('error', $i18n)
59 | ]));
60 | }
61 |
62 | }
63 |
64 | ?>
--------------------------------------------------------------------------------
/endpoints/admin/updatenotification.php:
--------------------------------------------------------------------------------
1 | false,
8 | "message" => translate('session_expired', $i18n)
9 | ]));
10 | }
11 |
12 | // Check that user is an admin
13 | if ($userId !== 1) {
14 | die(json_encode([
15 | "success" => false,
16 | "message" => translate('error', $i18n)
17 | ]));
18 | }
19 |
20 | if ($_SERVER["REQUEST_METHOD"] === "POST") {
21 |
22 | $postData = file_get_contents("php://input");
23 | $data = json_decode($postData, true);
24 |
25 | $updateNotification = $data['notificationEnabled'];
26 |
27 | // Save settings
28 | $stmt = $db->prepare('UPDATE admin SET update_notification = :update_notification');
29 | $stmt->bindValue(':update_notification', $updateNotification, SQLITE3_INTEGER);
30 | $result = $stmt->execute();
31 |
32 | if ($result) {
33 | die(json_encode([
34 | "success" => true,
35 | "message" => translate('success', $i18n)
36 | ]));
37 | } else {
38 | die(json_encode([
39 | "success" => false,
40 | "message" => translate('error', $i18n)
41 | ]));
42 | }
43 |
44 | }
45 |
46 | ?>
--------------------------------------------------------------------------------
/endpoints/categories/sort.php:
--------------------------------------------------------------------------------
1 | prepare($sql);
12 | $stmt->bindParam(':order', $order, SQLITE3_INTEGER);
13 | $stmt->bindParam(':categoryId', $categoryId, SQLITE3_INTEGER);
14 | $stmt->bindParam(':userId', $userId, SQLITE3_INTEGER);
15 | $result = $stmt->execute();
16 | $order++;
17 | }
18 |
19 | $response = [
20 | "success" => true,
21 | "message" => translate("sort_order_saved", $i18n)
22 | ];
23 | echo json_encode($response);
24 | } else {
25 | $response = [
26 | "success" => false,
27 | "errorMessage" => translate("session_expired", $i18n)
28 | ];
29 | echo json_encode($response);
30 | die();
31 | }
32 |
33 | ?>
--------------------------------------------------------------------------------
/endpoints/cronjobs/checkforupdates.php:
--------------------------------------------------------------------------------
1 | [
8 | 'header' => "User-Agent: Wallos\r\n"
9 | ]
10 | ];
11 |
12 | $repository = 'ellite/Wallos'; // Change this to your repository if you fork Wallos
13 | $url = "https://api.github.com/repos/$repository/releases/latest";
14 |
15 | $context = stream_context_create($options);
16 | $fetch = file_get_contents($url, false, $context);
17 |
18 | if ($fetch === false) {
19 | die('Error fetching data from GitHub API');
20 | }
21 |
22 | $latestVersion = json_decode($fetch, true)['tag_name'];
23 |
24 | // Check that $latestVersion is a valid version number
25 | if (!preg_match('/^v\d+\.\d+\.\d+$/', $latestVersion)) {
26 | die('Error: Invalid version number from GitHub API');
27 | }
28 |
29 | $db->exec("UPDATE admin SET latest_version = '$latestVersion'");
30 |
31 |
32 | if (php_sapi_name() !== 'cli') {
33 | include __DIR__ . '/../../includes/version.php';
34 | if (version_compare($latestVersion, $version) > 0) {
35 | echo "New version available: $latestVersion";
36 | } else {
37 | echo "No new version available, currently on $version";
38 | }
39 | }
40 | ?>
--------------------------------------------------------------------------------
/endpoints/cronjobs/settimezone.php:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/endpoints/currency/add.php:
--------------------------------------------------------------------------------
1 | prepare($sqlInsert);
12 | $stmtInsert->bindParam(':name', $currencyName, SQLITE3_TEXT);
13 | $stmtInsert->bindParam(':symbol', $currencySymbol, SQLITE3_TEXT);
14 | $stmtInsert->bindParam(':code', $currencyCode, SQLITE3_TEXT);
15 | $stmtInsert->bindParam(':rate', $currencyRate, SQLITE3_TEXT);
16 | $stmtInsert->bindParam(':userId', $userId, SQLITE3_INTEGER);
17 | $resultInsert = $stmtInsert->execute();
18 |
19 | if ($resultInsert) {
20 | $currencyId = $db->lastInsertRowID();
21 | echo $currencyId;
22 | } else {
23 | echo translate('error_adding_currency', $i18n);
24 | }
25 | } else {
26 | $response = [
27 | "success" => false,
28 | "message" => translate('session_expired', $i18n)
29 | ];
30 | echo json_encode($response);
31 | }
32 |
33 | ?>
--------------------------------------------------------------------------------
/endpoints/currency/edit.php:
--------------------------------------------------------------------------------
1 | prepare($sql);
13 | $stmt->bindParam(':name', $name, SQLITE3_TEXT);
14 | $stmt->bindParam(':symbol', $symbol, SQLITE3_TEXT);
15 | $stmt->bindParam(':code', $code, SQLITE3_TEXT);
16 | $stmt->bindParam(':currencyId', $currencyId, SQLITE3_INTEGER);
17 | $stmt->bindParam(':userId', $userId, SQLITE3_INTEGER);
18 | $result = $stmt->execute();
19 |
20 | if ($result) {
21 | $response = [
22 | "success" => true,
23 | "message" => $name . " " . translate('currency_saved', $i18n)
24 | ];
25 | echo json_encode($response);
26 | } else {
27 | $response = [
28 | "success" => false,
29 | "message" => translate('failed_to_store_currency', $i18n)
30 | ];
31 | echo json_encode($response);
32 | }
33 | } else {
34 | $response = [
35 | "success" => false,
36 | "message" => translate('fields_missing', $i18n)
37 | ];
38 | echo json_encode($response);
39 | }
40 | } else {
41 | $response = [
42 | "success" => false,
43 | "message" => translate('session_expired', $i18n)
44 | ];
45 | echo json_encode($response);
46 | }
47 |
48 | ?>
--------------------------------------------------------------------------------
/endpoints/db/migrate.php:
--------------------------------------------------------------------------------
1 | query('SELECT name FROM sqlite_master WHERE type="table" AND name="migrations"')
24 | ->fetchArray(SQLITE3_ASSOC) !== false;
25 |
26 | if ($migrationTableExists) {
27 | $migrationQuery = $db->query('SELECT migration FROM migrations');
28 | while ($row = $migrationQuery->fetchArray(SQLITE3_ASSOC)) {
29 | $completedMigrations[] = $row['migration'];
30 | }
31 | }
32 |
33 | $allMigrations = glob('migrations/*.php');
34 | if (count($allMigrations) == 0) {
35 | $allMigrations = glob('../../migrations/*.php');
36 | }
37 |
38 | $allMigrations = array_map(function ($migration) {
39 | return str_replace('../../', '', $migration);
40 | }, $allMigrations);
41 |
42 | $completedMigrations = array_map(function ($migration) {
43 | return str_replace('../../', '', $migration);
44 | }, $completedMigrations);
45 |
46 | $requiredMigrations = array_diff($allMigrations, $completedMigrations);
47 |
48 | if (count($requiredMigrations) === 0) {
49 | echo "No migrations to run.\n";
50 | }
51 |
52 | foreach ($requiredMigrations as $migration) {
53 | if (!file_exists($migration)) {
54 | $migration = '../../' . $migration;
55 | }
56 | require_once $migration;
57 |
58 | $stmtInsert = $db->prepare('INSERT INTO migrations (migration) VALUES (:migration)');
59 | $stmtInsert->bindParam(':migration', $migration, SQLITE3_TEXT);
60 | $stmtInsert->execute();
61 |
62 | echo sprintf("Migration %s completed successfully.\n", $migration);
63 | }
64 |
--------------------------------------------------------------------------------
/endpoints/payments/delete.php:
--------------------------------------------------------------------------------
1 | prepare($deleteQuery);
10 | $deleteStmt->bindParam(':paymentMethodId', $paymentMethodId, SQLITE3_INTEGER);
11 | $deleteStmt->bindParam(':userId', $userId, SQLITE3_INTEGER);
12 |
13 | if ($deleteStmt->execute()) {
14 | $success['success'] = true;
15 | $success['message'] = translate('payment_method_removed', $i18n);
16 | $json = json_encode($success);
17 | header('Content-Type: application/json');
18 | echo $json;
19 | } else {
20 | http_response_code(500);
21 | echo json_encode(array("message" => translate('error', $i18n)));
22 | }
23 | } else {
24 | http_response_code(405);
25 | echo json_encode(array("message" => translate('invalid_request_method', $i18n)));
26 | }
27 | }
28 | $db->close();
29 |
30 | ?>
--------------------------------------------------------------------------------
/endpoints/payments/payment.php:
--------------------------------------------------------------------------------
1 | false,
7 | "message" => translate('session_expired', $i18n)
8 | ]));
9 | }
10 |
11 | if (!isset($_GET['paymentId']) || !isset($_GET['enabled'])) {
12 | die(json_encode([
13 | "success" => false,
14 | "message" => translate('fields_missing', $i18n)
15 | ]));
16 | }
17 |
18 | $paymentId = $_GET['paymentId'];
19 |
20 | $stmt = $db->prepare('SELECT COUNT(*) as count FROM subscriptions WHERE payment_method_id=:paymentId and user_id=:userId');
21 | $stmt->bindValue(':paymentId', $paymentId, SQLITE3_INTEGER);
22 | $stmt->bindValue(':userId', $userId, SQLITE3_INTEGER);
23 | $result = $stmt->execute();
24 | $row = $result->fetchArray();
25 | $inUse = $row['count'] === 1;
26 |
27 | if ($inUse) {
28 | die(json_encode([
29 | "success" => false,
30 | "message" => translate('payment_in_use', $i18n)
31 | ]));
32 | }
33 |
34 | $enabled = $_GET['enabled'];
35 |
36 | $sqlUpdate = 'UPDATE payment_methods SET enabled=:enabled WHERE id=:id and user_id=:userId';
37 | $stmtUpdate = $db->prepare($sqlUpdate);
38 | $stmtUpdate->bindParam(':enabled', $enabled);
39 | $stmtUpdate->bindParam(':id', $paymentId);
40 | $stmtUpdate->bindParam(':userId', $userId);
41 | $resultUpdate = $stmtUpdate->execute();
42 |
43 | $text = $enabled ? "enabled" : "disabled";
44 |
45 | if ($resultUpdate) {
46 | die(json_encode([
47 | "success" => true,
48 | "message" => translate($text, $i18n)
49 | ]));
50 | }
51 |
52 | die(json_encode([
53 | "success" => false,
54 | "message" => translate('failed_update_payment', $i18n)
55 | ]));
56 |
--------------------------------------------------------------------------------
/endpoints/payments/rename.php:
--------------------------------------------------------------------------------
1 | false,
8 | "message" => translate('session_expired', $i18n)
9 | ]));
10 | }
11 |
12 | if (!isset($_POST['paymentId']) || !isset($_POST['name']) || $_POST['paymentId'] === '' || $_POST['name'] === '') {
13 | die(json_encode([
14 | "success" => false,
15 | "message" => translate('fields_missing', $i18n)
16 | ]));
17 | }
18 |
19 | $paymentId = $_POST['paymentId'];
20 | $name = $_POST['name'];
21 |
22 | $sql = "UPDATE payment_methods SET name = :name WHERE id = :paymentId and user_id = :userId";
23 | $stmt = $db->prepare($sql);
24 | $stmt->bindParam(':name', $name, SQLITE3_TEXT);
25 | $stmt->bindParam(':paymentId', $paymentId, SQLITE3_INTEGER);
26 | $stmt->bindParam(':userId', $userId, SQLITE3_INTEGER);
27 | $result = $stmt->execute();
28 |
29 | if ($result) {
30 | echo json_encode([
31 | "success" => true,
32 | "message" => translate('payment_renamed', $i18n)
33 | ]);
34 | } else {
35 | echo json_encode([
36 | "success" => false,
37 | "message" => translate('payment_not_renamed', $i18n)
38 | ]);
39 | }
40 |
41 | ?>
--------------------------------------------------------------------------------
/endpoints/payments/sort.php:
--------------------------------------------------------------------------------
1 | prepare($sql);
12 | $stmt->bindParam(':order', $order, SQLITE3_INTEGER);
13 | $stmt->bindParam(':paymentMethodId', $paymentMethodId, SQLITE3_INTEGER);
14 | $stmt->bindParam(':userId', $userId, SQLITE3_INTEGER);
15 | $result = $stmt->execute();
16 | $order++;
17 | }
18 |
19 | $response = [
20 | "success" => true,
21 | "message" => translate("sort_order_saved", $i18n)
22 | ];
23 | echo json_encode($response);
24 | } else {
25 | $response = [
26 | "success" => false,
27 | "errorMessage" => translate("session_expired", $i18n)
28 | ];
29 | echo json_encode($response);
30 | die();
31 | }
32 |
33 | ?>
--------------------------------------------------------------------------------
/endpoints/settings/colortheme.php:
--------------------------------------------------------------------------------
1 | false,
8 | "message" => translate('session_expired', $i18n)
9 | ]));
10 | }
11 |
12 | if ($_SERVER["REQUEST_METHOD"] === "POST") {
13 | $postData = file_get_contents("php://input");
14 | $data = json_decode($postData, true);
15 |
16 | $color = $data['color'];
17 |
18 | $stmt = $db->prepare('UPDATE settings SET color_theme = :color WHERE user_id = :userId');
19 | $stmt->bindParam(':color', $color, SQLITE3_TEXT);
20 | $stmt->bindParam(':userId', $userId, SQLITE3_INTEGER);
21 |
22 | if ($stmt->execute()) {
23 | die(json_encode([
24 | "success" => true,
25 | "message" => translate("success", $i18n)
26 | ]));
27 | } else {
28 | die(json_encode([
29 | "success" => false,
30 | "message" => translate("error", $i18n)
31 | ]));
32 | }
33 | }
34 |
35 | ?>
--------------------------------------------------------------------------------
/endpoints/settings/convert_currency.php:
--------------------------------------------------------------------------------
1 | false,
7 | "message" => translate('session_expired', $i18n)
8 | ]));
9 | }
10 |
11 | if ($_SERVER["REQUEST_METHOD"] === "POST") {
12 | $postData = file_get_contents("php://input");
13 | $data = json_decode($postData, true);
14 |
15 | $convert_currency = $data['value'];
16 |
17 | $stmt = $db->prepare('UPDATE settings SET convert_currency = :convert_currency WHERE user_id = :userId');
18 | $stmt->bindParam(':convert_currency', $convert_currency, SQLITE3_INTEGER);
19 | $stmt->bindParam(':userId', $userId, SQLITE3_INTEGER);
20 |
21 | if ($stmt->execute()) {
22 | die(json_encode([
23 | "success" => true,
24 | "message" => translate("success", $i18n)
25 | ]));
26 | } else {
27 | die(json_encode([
28 | "success" => false,
29 | "message" => translate("error", $i18n)
30 | ]));
31 | }
32 | }
33 |
34 | ?>
--------------------------------------------------------------------------------
/endpoints/settings/customcss.php:
--------------------------------------------------------------------------------
1 | false,
8 | "message" => translate('session_expired', $i18n)
9 | ]));
10 | }
11 |
12 | if ($_SERVER["REQUEST_METHOD"] === "POST") {
13 | $postData = file_get_contents("php://input");
14 | $data = json_decode($postData, true);
15 |
16 | $customCss = $data['customCss'];
17 |
18 | $stmt = $db->prepare('DELETE FROM custom_css_style WHERE user_id = :userId');
19 | $stmt->bindParam(':userId', $userId, SQLITE3_INTEGER);
20 | $stmt->execute();
21 |
22 | $stmt = $db->prepare('INSERT INTO custom_css_style (css, user_id) VALUES (:customCss, :userId)');
23 | $stmt->bindParam(':customCss', $customCss, SQLITE3_TEXT);
24 | $stmt->bindParam(':userId', $userId, SQLITE3_INTEGER);
25 |
26 | if ($stmt->execute()) {
27 | die(json_encode([
28 | "success" => true,
29 | "message" => translate("success", $i18n)
30 | ]));
31 | } else {
32 | die(json_encode([
33 | "success" => false,
34 | "message" => translate("error", $i18n)
35 | ]));
36 | }
37 | }
38 |
--------------------------------------------------------------------------------
/endpoints/settings/customtheme.php:
--------------------------------------------------------------------------------
1 | false,
8 | "message" => translate('session_expired', $i18n)
9 | ]));
10 | }
11 |
12 | if ($_SERVER["REQUEST_METHOD"] === "POST") {
13 | $postData = file_get_contents("php://input");
14 | $data = json_decode($postData, true);
15 |
16 | $main_color = $data['mainColor'];
17 | $accent_color = $data['accentColor'];
18 | $hover_color = $data['hoverColor'];
19 |
20 | if ($main_color == $accent_color) {
21 | die(json_encode([
22 | "success" => false,
23 | "message" => translate("main_accent_color_error", $i18n)
24 | ]));
25 | }
26 |
27 | $stmt = $db->prepare('DELETE FROM custom_colors WHERE user_id = :userId');
28 | $stmt->bindParam(':userId', $userId, SQLITE3_INTEGER);
29 | $stmt->execute();
30 |
31 | $stmt = $db->prepare('INSERT INTO custom_colors (main_color, accent_color, hover_color, user_id) VALUES (:main_color, :accent_color, :hover_color, :userId)');
32 | $stmt->bindParam(':main_color', $main_color, SQLITE3_TEXT);
33 | $stmt->bindParam(':accent_color', $accent_color, SQLITE3_TEXT);
34 | $stmt->bindParam(':hover_color', $hover_color, SQLITE3_TEXT);
35 | $stmt->bindParam(':userId', $userId, SQLITE3_INTEGER);
36 |
37 | if ($stmt->execute()) {
38 | die(json_encode([
39 | "success" => true,
40 | "message" => translate("success", $i18n)
41 | ]));
42 | } else {
43 | die(json_encode([
44 | "success" => false,
45 | "message" => translate("error", $i18n)
46 | ]));
47 | }
48 | }
49 |
50 | ?>
--------------------------------------------------------------------------------
/endpoints/settings/disabled_to_bottom.php:
--------------------------------------------------------------------------------
1 | false,
7 | "message" => translate('session_expired', $i18n)
8 | ]));
9 | }
10 |
11 | if ($_SERVER["REQUEST_METHOD"] === "POST") {
12 | $postData = file_get_contents("php://input");
13 | $data = json_decode($postData, true);
14 |
15 | $disabled_to_bottom = $data['value'];
16 |
17 | $stmt = $db->prepare('UPDATE settings SET disabled_to_bottom = :disabled_to_bottom WHERE user_id = :userId');
18 | $stmt->bindParam(':disabled_to_bottom', $disabled_to_bottom, SQLITE3_INTEGER);
19 | $stmt->bindParam(':userId', $userId, SQLITE3_INTEGER);
20 |
21 | if ($stmt->execute()) {
22 | die(json_encode([
23 | "success" => true,
24 | "message" => translate("success", $i18n)
25 | ]));
26 | } else {
27 | die(json_encode([
28 | "success" => false,
29 | "message" => translate("error", $i18n)
30 | ]));
31 | }
32 | }
33 |
34 | ?>
--------------------------------------------------------------------------------
/endpoints/settings/hide_disabled.php:
--------------------------------------------------------------------------------
1 | false,
7 | "message" => translate('session_expired', $i18n)
8 | ]));
9 | }
10 |
11 | if ($_SERVER["REQUEST_METHOD"] === "POST") {
12 | $postData = file_get_contents("php://input");
13 | $data = json_decode($postData, true);
14 |
15 | $hide_disabled = $data['value'];
16 |
17 | $stmt = $db->prepare('UPDATE settings SET hide_disabled = :hide_disabled WHERE user_id = :userId');
18 | $stmt->bindParam(':hide_disabled', $hide_disabled, SQLITE3_INTEGER);
19 | $stmt->bindParam(':userId', $userId, SQLITE3_INTEGER);
20 |
21 | if ($stmt->execute()) {
22 | die(json_encode([
23 | "success" => true,
24 | "message" => translate("success", $i18n)
25 | ]));
26 | } else {
27 | die(json_encode([
28 | "success" => false,
29 | "message" => translate("error", $i18n)
30 | ]));
31 | }
32 | }
33 |
34 | ?>
--------------------------------------------------------------------------------
/endpoints/settings/mobile_navigation.php:
--------------------------------------------------------------------------------
1 | false,
8 | "message" => translate('session_expired', $i18n)
9 | ]));
10 | }
11 |
12 | if ($_SERVER["REQUEST_METHOD"] === "POST") {
13 | $postData = file_get_contents("php://input");
14 | $data = json_decode($postData, true);
15 |
16 | $mobile_nav = $data['value'];
17 |
18 | $stmt = $db->prepare('UPDATE settings SET mobile_nav = :mobile_nav WHERE user_id = :userId');
19 | $stmt->bindParam(':mobile_nav', $mobile_nav, SQLITE3_INTEGER);
20 | $stmt->bindParam(':userId', $userId, SQLITE3_INTEGER);
21 |
22 | if ($stmt->execute()) {
23 | die(json_encode([
24 | "success" => true,
25 | "message" => translate("success", $i18n)
26 | ]));
27 | } else {
28 | die(json_encode([
29 | "success" => false,
30 | "message" => translate("error", $i18n)
31 | ]));
32 | }
33 | }
34 | «
35 |
36 | ?>
--------------------------------------------------------------------------------
/endpoints/settings/monthly_price.php:
--------------------------------------------------------------------------------
1 | false,
7 | "message" => translate('session_expired', $i18n)
8 | ]));
9 | }
10 |
11 | if ($_SERVER["REQUEST_METHOD"] === "POST") {
12 | $postData = file_get_contents("php://input");
13 | $data = json_decode($postData, true);
14 |
15 | $monthly_price = $data['value'];
16 |
17 | $stmt = $db->prepare('UPDATE settings SET monthly_price = :monthly_price WHERE user_id = :userId');
18 | $stmt->bindParam(':monthly_price', $monthly_price, SQLITE3_INTEGER);
19 | $stmt->bindParam(':userId', $userId, SQLITE3_INTEGER);
20 |
21 | if ($stmt->execute()) {
22 | die(json_encode([
23 | "success" => true,
24 | "message" => translate("success", $i18n)
25 | ]));
26 | } else {
27 | die(json_encode([
28 | "success" => false,
29 | "message" => translate("error", $i18n)
30 | ]));
31 | }
32 | }
33 |
34 | ?>
--------------------------------------------------------------------------------
/endpoints/settings/remove_background.php:
--------------------------------------------------------------------------------
1 | false,
7 | "message" => translate('session_expired', $i18n)
8 | ]));
9 | }
10 |
11 | if ($_SERVER["REQUEST_METHOD"] === "POST") {
12 | $postData = file_get_contents("php://input");
13 | $data = json_decode($postData, true);
14 |
15 | $remove_background = $data['value'];
16 |
17 | $stmt = $db->prepare('UPDATE settings SET remove_background = :remove_background WHERE user_id = :userId');
18 | $stmt->bindParam(':remove_background', $remove_background, SQLITE3_INTEGER);
19 | $stmt->bindParam(':userId', $userId, SQLITE3_INTEGER);
20 |
21 | if ($stmt->execute()) {
22 | die(json_encode([
23 | "success" => true,
24 | "message" => translate("success", $i18n)
25 | ]));
26 | } else {
27 | die(json_encode([
28 | "success" => false,
29 | "message" => translate("error", $i18n)
30 | ]));
31 | }
32 | }
33 |
34 | ?>
--------------------------------------------------------------------------------
/endpoints/settings/resettheme.php:
--------------------------------------------------------------------------------
1 | false,
8 | "message" => translate('session_expired', $i18n)
9 | ]));
10 | }
11 |
12 | if ($_SERVER["REQUEST_METHOD"] === "DELETE") {
13 | $stmt = $db->prepare('DELETE FROM custom_colors WHERE user_id = :userId');
14 | $stmt->bindParam(':userId', $userId, SQLITE3_INTEGER);
15 |
16 | if ($stmt->execute()) {
17 | die(json_encode([
18 | "success" => true,
19 | "message" => translate("success", $i18n)
20 | ]));
21 | } else {
22 | die(json_encode([
23 | "success" => false,
24 | "message" => translate("error", $i18n)
25 | ]));
26 | }
27 | }
28 |
29 | ?>
--------------------------------------------------------------------------------
/endpoints/settings/show_original_price.php:
--------------------------------------------------------------------------------
1 | false,
7 | "message" => translate('session_expired', $i18n)
8 | ]));
9 | }
10 |
11 | if ($_SERVER["REQUEST_METHOD"] === "POST") {
12 | $postData = file_get_contents("php://input");
13 | $data = json_decode($postData, true);
14 |
15 | $show_original_price = $data['value'];
16 |
17 | $stmt = $db->prepare('UPDATE settings SET show_original_price = :show_original_price WHERE user_id = :userId');
18 | $stmt->bindParam(':show_original_price', $show_original_price, SQLITE3_INTEGER);
19 | $stmt->bindParam(':userId', $userId, SQLITE3_INTEGER);
20 |
21 | if ($stmt->execute()) {
22 | die(json_encode([
23 | "success" => true,
24 | "message" => translate("success", $i18n)
25 | ]));
26 | } else {
27 | die(json_encode([
28 | "success" => false,
29 | "message" => translate("error", $i18n)
30 | ]));
31 | }
32 | }
33 |
34 | ?>
--------------------------------------------------------------------------------
/endpoints/settings/subscription_progress.php:
--------------------------------------------------------------------------------
1 | false,
7 | "message" => translate('session_expired', $i18n)
8 | ]));
9 | }
10 |
11 | if ($_SERVER["REQUEST_METHOD"] === "POST") {
12 | $postData = file_get_contents("php://input");
13 | $data = json_decode($postData, true);
14 |
15 | $show_subscription_progress = $data['value'];
16 |
17 | $stmt = $db->prepare('UPDATE settings SET show_subscription_progress = :show_subscription_progress WHERE user_id = :userId');
18 | $stmt->bindParam(':show_subscription_progress', $show_subscription_progress, SQLITE3_INTEGER);
19 | $stmt->bindParam(':userId', $userId, SQLITE3_INTEGER);
20 |
21 | if ($stmt->execute()) {
22 | die(json_encode([
23 | "success" => true,
24 | "message" => translate("success", $i18n)
25 | ]));
26 | } else {
27 | die(json_encode([
28 | "success" => false,
29 | "message" => translate("error", $i18n)
30 | ]));
31 | }
32 | }
33 |
34 | ?>
--------------------------------------------------------------------------------
/endpoints/settings/theme.php:
--------------------------------------------------------------------------------
1 | false,
7 | "message" => translate('session_expired', $i18n)
8 | ]));
9 | }
10 |
11 | if ($_SERVER["REQUEST_METHOD"] === "POST") {
12 | $postData = file_get_contents("php://input");
13 | $data = json_decode($postData, true);
14 |
15 | $theme = $data['theme'];
16 |
17 | $stmt = $db->prepare('UPDATE settings SET dark_theme = :theme WHERE user_id = :userId');
18 | $stmt->bindParam(':theme', $theme, SQLITE3_INTEGER);
19 | $stmt->bindParam(':userId', $userId, SQLITE3_INTEGER);
20 |
21 | if ($stmt->execute()) {
22 | die(json_encode([
23 | "success" => true,
24 | "message" => translate("success", $i18n)
25 | ]));
26 | } else {
27 | die(json_encode([
28 | "success" => false,
29 | "message" => translate("error", $i18n)
30 | ]));
31 | }
32 | }
33 |
34 | ?>
--------------------------------------------------------------------------------
/endpoints/subscription/delete.php:
--------------------------------------------------------------------------------
1 | prepare($deleteQuery);
9 | $deleteStmt->bindParam(':subscriptionId', $subscriptionId, SQLITE3_INTEGER);
10 | $deleteStmt->bindParam(':userId', $userId, SQLITE3_INTEGER);
11 |
12 | if ($deleteStmt->execute()) {
13 | $query = "UPDATE subscriptions SET replacement_subscription_id = NULL WHERE replacement_subscription_id = :subscriptionId AND user_id = :userId";
14 | $stmt = $db->prepare($query);
15 | $stmt->bindParam(':subscriptionId', $subscriptionId, SQLITE3_INTEGER);
16 | $stmt->bindParam(':userId', $userId, SQLITE3_INTEGER);
17 | $stmt->execute();
18 |
19 | http_response_code(204);
20 | } else {
21 | http_response_code(500);
22 | echo json_encode(array("message" => translate('error_deleting_subscription', $i18n)));
23 | }
24 | } else {
25 | http_response_code(405);
26 | echo json_encode(array("message" => translate('invalid_request_method', $i18n)));
27 | }
28 | }
29 | $db->close();
30 | ?>
--------------------------------------------------------------------------------
/endpoints/subscription/getcalendar.php:
--------------------------------------------------------------------------------
1 | false,
8 | "message" => translate('session_expired', $i18n)
9 | ]));
10 | }
11 |
12 | if ($_SERVER["REQUEST_METHOD"] === "POST") {
13 | $postData = file_get_contents("php://input");
14 | $data = json_decode($postData, true);
15 |
16 | $id = $data['id'];
17 |
18 | $stmt = $db->prepare('SELECT * FROM subscriptions WHERE id = :id AND user_id = :userId');
19 | $stmt->bindParam(':id', $id, SQLITE3_INTEGER);
20 | $stmt->bindParam(':userId', $_SESSION['userId'], SQLITE3_INTEGER); // Assuming $_SESSION['userId'] holds the logged-in user's ID
21 | $result = $stmt->execute();
22 |
23 | if ($result === false) {
24 | die(json_encode([
25 | 'success' => false,
26 | 'message' => "Subscription not found"
27 | ]));
28 | }
29 |
30 | $subscription = $result->fetchArray(SQLITE3_ASSOC); // Fetch the subscription details as an associative array
31 |
32 | if ($subscription) {
33 | // get payer name from household object
34 | $subscription['payer_user'] = $members[$subscription['payer_user_id']]['name'];
35 | $subscription['category'] = $categories[$subscription['category_id']]['name'];
36 | $subscription['payment_method'] = $payment_methods[$subscription['payment_method_id']]['name'];
37 | $subscription['currency'] = $currencies[$subscription['currency_id']]['symbol'];
38 | $subscription['price'] = number_format($subscription['price'], 2);
39 |
40 | echo json_encode([
41 | 'success' => true,
42 | 'data' => $subscription
43 | ]);
44 | } else {
45 | echo json_encode([
46 | 'success' => false,
47 | 'message' => "Subscription not found"
48 | ]);
49 | }
50 | }
51 | ?>
--------------------------------------------------------------------------------
/endpoints/subscriptions/export.php:
--------------------------------------------------------------------------------
1 | false,
7 | "message" => translate('session_expired', $i18n)
8 | ]));
9 | }
10 |
11 | require_once '../../includes/getdbkeys.php';
12 |
13 | $subscriptions = array();
14 |
15 | $query = "SELECT * FROM subscriptions WHERE user_id = :userId";
16 | $stmt = $db->prepare($query);
17 | $stmt->bindValue(':userId', $userId, SQLITE3_INTEGER);
18 | $result = $stmt->execute();
19 |
20 | while ($row = $result->fetchArray(SQLITE3_ASSOC)) {
21 | $cycle = $cycles[$row['cycle']]['name'];
22 | $frequency =$row['frequency'];
23 |
24 | $cyclesMap = array(
25 | 'Daily' => 'Days',
26 | 'Weekly' => 'Weeks',
27 | 'Monthly' => 'Months',
28 | 'Yearly' => 'Years'
29 | );
30 |
31 | if ($frequency == 1) {
32 | $cyclePrint = $cycle;
33 | } else {
34 | $cyclePrint = "Every " . $frequency . " " . $cyclesMap[$cycle];
35 | }
36 |
37 | $subscriptionDetails = array(
38 | 'Name' => str_replace(',', ' ', $row['name']),
39 | 'Payment Cycle' => $cyclePrint,
40 | 'Next Payment' => $row['next_payment'],
41 | 'Renewal' => $row['auto_renew'] ? 'Automatic' : 'Manual',
42 | 'Category' => str_replace(',', ' ', $categories[$row['category_id']]['name']),
43 | 'Payment Method' => str_replace(',', ' ', $payment_methods[$row['payment_method_id']]['name']),
44 | 'Paid By' => str_replace(',', ' ', $members[$row['payer_user_id']]['name']),
45 | 'Price' => $currencies[$row['currency_id']]['symbol'] . $row['price'],
46 | 'Notes' => str_replace(',', ' ', $row['notes']),
47 | 'URL' => $row['url'],
48 | 'State' => $row['inactive'] ? 'Disabled' : 'Enabled',
49 | 'Notifications' => $row['notify'] ? 'Enabled' : 'Disabled',
50 | 'Cancellation Date' => $row['cancellation_date'],
51 | 'Active' => $row['inactive'] ? 'No' : 'Yes',
52 | );
53 |
54 | $subscriptions[] = $subscriptionDetails;
55 | }
56 |
57 | die(json_encode([
58 | "success" => true,
59 | "subscriptions" => $subscriptions
60 | ]));
61 |
62 |
63 | ?>
64 |
--------------------------------------------------------------------------------
/endpoints/user/budget.php:
--------------------------------------------------------------------------------
1 | false,
9 | "message" => translate('session_expired', $i18n)
10 | ]));
11 | }
12 |
13 | if ($_SERVER["REQUEST_METHOD"] === "POST") {
14 | $postData = file_get_contents("php://input");
15 | $data = json_decode($postData, true);
16 |
17 | $budget = $data["budget"];
18 |
19 | $sql = "UPDATE user SET budget = :budget WHERE id = :userId";
20 | $stmt = $db->prepare($sql);
21 | $stmt->bindValue(':budget', $budget, SQLITE3_TEXT);
22 | $stmt->bindValue(':userId', $userId, SQLITE3_TEXT);
23 | $result = $stmt->execute();
24 |
25 | if ($result) {
26 | $response = [
27 | "success" => true,
28 | "message" => translate('user_details_saved', $i18n)
29 | ];
30 | echo json_encode($response);
31 | } else {
32 | $response = [
33 | "success" => false,
34 | "message" => translate('error_updating_user_data', $i18n)
35 | ];
36 | echo json_encode($response);
37 | }
38 | }
39 |
40 |
41 | ?>
--------------------------------------------------------------------------------
/endpoints/user/delete_avatar.php:
--------------------------------------------------------------------------------
1 | false,
8 | "message" => translate('session_expired', $i18n)
9 | ]));
10 | }
11 |
12 | $input = json_decode(file_get_contents('php://input'), true);
13 | if (isset($input['avatar'])) {
14 | $baseDir = realpath("../../images/uploads/logos/avatars/");
15 | $avatar = $input['avatar'];
16 |
17 | $cleanAvatar = rawurldecode($avatar);
18 | $cleanAvatar = preg_replace('/[^a-zA-Z0-9_\-\.]/', '', $cleanAvatar);
19 |
20 | $filePath = realpath($baseDir . DIRECTORY_SEPARATOR . $cleanAvatar);
21 |
22 | if ($filePath === false || strpos($filePath, $baseDir) !== 0) {
23 | echo json_encode([
24 | "success" => false,
25 | "message" => "Invalid file path"
26 | ]);
27 | exit;
28 | }
29 |
30 | $sql = "SELECT avatar FROM user WHERE id = :userId";
31 | $stmt = $db->prepare($sql);
32 | $stmt->bindValue(':userId', $userId, SQLITE3_INTEGER);
33 | $result = $stmt->execute();
34 | $userAvatar = $result->fetchArray(SQLITE3_ASSOC)['avatar'];
35 |
36 | // Check if $avatar matches the avatar in the user table
37 | if ($avatar === $userAvatar) {
38 | echo json_encode(array("success" => false, "message" => "Avatar in use"));
39 | } else {
40 | if (file_exists($filePath)) {
41 | unlink($filePath);
42 | echo json_encode(array("success" => true, "message" => translate("success", $i18n)));
43 | } else {
44 | echo json_encode(array("success" => false, "message" => translate("error", $i18n)));
45 | }
46 | }
47 | } else {
48 | echo json_encode(array("success" => false, "message" => translate("error", $i18n)));
49 | }
50 |
51 | ?>
--------------------------------------------------------------------------------
/endpoints/user/regenerateapikey.php:
--------------------------------------------------------------------------------
1 | false,
7 | "message" => translate('session_expired', $i18n)
8 | ]));
9 | }
10 |
11 | if ($_SERVER["REQUEST_METHOD"] === "POST") {
12 | $postData = file_get_contents("php://input");
13 | $data = json_decode($postData, true);
14 |
15 | $apiKey = bin2hex(random_bytes(32));
16 |
17 | $sql = "UPDATE user SET api_key = :apiKey WHERE id = :userId";
18 | $stmt = $db->prepare($sql);
19 | $stmt->bindValue(':apiKey', $apiKey, SQLITE3_TEXT);
20 | $stmt->bindValue(':userId', $userId, SQLITE3_TEXT);
21 | $result = $stmt->execute();
22 |
23 | if ($result) {
24 | $response = [
25 | "success" => true,
26 | "message" => translate('user_details_saved', $i18n),
27 | "apiKey" => $apiKey
28 | ];
29 | echo json_encode($response);
30 | } else {
31 | $response = [
32 | "success" => false,
33 | "message" => translate('error_updating_user_data', $i18n)
34 | ];
35 | echo json_encode($response);
36 | }
37 |
38 | }
39 |
40 | ?>
--------------------------------------------------------------------------------
/images/Thumbs.db:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ellite/Wallos/a7e26f688a00101bda85606d59cdd500d1cd6970/images/Thumbs.db
--------------------------------------------------------------------------------
/images/avatars/0.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/images/avatars/1.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/images/avatars/2.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/images/avatars/3.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/images/avatars/4.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/images/avatars/5.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/images/avatars/6.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/images/avatars/7.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/images/avatars/8.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/images/avatars/9.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/images/icon/android-chrome-192x192.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ellite/Wallos/a7e26f688a00101bda85606d59cdd500d1cd6970/images/icon/android-chrome-192x192.png
--------------------------------------------------------------------------------
/images/icon/android-chrome-512x512.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ellite/Wallos/a7e26f688a00101bda85606d59cdd500d1cd6970/images/icon/android-chrome-512x512.png
--------------------------------------------------------------------------------
/images/icon/apple-touch-icon-152.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ellite/Wallos/a7e26f688a00101bda85606d59cdd500d1cd6970/images/icon/apple-touch-icon-152.png
--------------------------------------------------------------------------------
/images/icon/apple-touch-icon-180.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ellite/Wallos/a7e26f688a00101bda85606d59cdd500d1cd6970/images/icon/apple-touch-icon-180.png
--------------------------------------------------------------------------------
/images/icon/apple-touch-icon.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ellite/Wallos/a7e26f688a00101bda85606d59cdd500d1cd6970/images/icon/apple-touch-icon.png
--------------------------------------------------------------------------------
/images/icon/favicon-16x16.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ellite/Wallos/a7e26f688a00101bda85606d59cdd500d1cd6970/images/icon/favicon-16x16.png
--------------------------------------------------------------------------------
/images/icon/favicon-32x32.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ellite/Wallos/a7e26f688a00101bda85606d59cdd500d1cd6970/images/icon/favicon-32x32.png
--------------------------------------------------------------------------------
/images/icon/favicon.ico:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ellite/Wallos/a7e26f688a00101bda85606d59cdd500d1cd6970/images/icon/favicon.ico
--------------------------------------------------------------------------------
/images/icon/maskable_icon_x192.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ellite/Wallos/a7e26f688a00101bda85606d59cdd500d1cd6970/images/icon/maskable_icon_x192.png
--------------------------------------------------------------------------------
/images/icon/maskable_icon_x512.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ellite/Wallos/a7e26f688a00101bda85606d59cdd500d1cd6970/images/icon/maskable_icon_x512.png
--------------------------------------------------------------------------------
/images/screenshots/desktop.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ellite/Wallos/a7e26f688a00101bda85606d59cdd500d1cd6970/images/screenshots/desktop.png
--------------------------------------------------------------------------------
/images/screenshots/mobile.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ellite/Wallos/a7e26f688a00101bda85606d59cdd500d1cd6970/images/screenshots/mobile.png
--------------------------------------------------------------------------------
/images/siteicons/payments/Amex.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ellite/Wallos/a7e26f688a00101bda85606d59cdd500d1cd6970/images/siteicons/payments/Amex.png
--------------------------------------------------------------------------------
/images/siteicons/payments/ApplePay.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ellite/Wallos/a7e26f688a00101bda85606d59cdd500d1cd6970/images/siteicons/payments/ApplePay.png
--------------------------------------------------------------------------------
/images/siteicons/payments/Bitcoin.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ellite/Wallos/a7e26f688a00101bda85606d59cdd500d1cd6970/images/siteicons/payments/Bitcoin.png
--------------------------------------------------------------------------------
/images/siteicons/payments/BitcoinCash.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ellite/Wallos/a7e26f688a00101bda85606d59cdd500d1cd6970/images/siteicons/payments/BitcoinCash.png
--------------------------------------------------------------------------------
/images/siteicons/payments/DinersClub.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ellite/Wallos/a7e26f688a00101bda85606d59cdd500d1cd6970/images/siteicons/payments/DinersClub.png
--------------------------------------------------------------------------------
/images/siteicons/payments/Discover.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ellite/Wallos/a7e26f688a00101bda85606d59cdd500d1cd6970/images/siteicons/payments/Discover.png
--------------------------------------------------------------------------------
/images/siteicons/payments/Etherium.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ellite/Wallos/a7e26f688a00101bda85606d59cdd500d1cd6970/images/siteicons/payments/Etherium.png
--------------------------------------------------------------------------------
/images/siteicons/payments/Forbrugsforeningen.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ellite/Wallos/a7e26f688a00101bda85606d59cdd500d1cd6970/images/siteicons/payments/Forbrugsforeningen.png
--------------------------------------------------------------------------------
/images/siteicons/payments/GooglePay.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ellite/Wallos/a7e26f688a00101bda85606d59cdd500d1cd6970/images/siteicons/payments/GooglePay.png
--------------------------------------------------------------------------------
/images/siteicons/payments/Interac.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ellite/Wallos/a7e26f688a00101bda85606d59cdd500d1cd6970/images/siteicons/payments/Interac.png
--------------------------------------------------------------------------------
/images/siteicons/payments/JCB.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ellite/Wallos/a7e26f688a00101bda85606d59cdd500d1cd6970/images/siteicons/payments/JCB.png
--------------------------------------------------------------------------------
/images/siteicons/payments/Klarna.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ellite/Wallos/a7e26f688a00101bda85606d59cdd500d1cd6970/images/siteicons/payments/Klarna.png
--------------------------------------------------------------------------------
/images/siteicons/payments/Lightcoin.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ellite/Wallos/a7e26f688a00101bda85606d59cdd500d1cd6970/images/siteicons/payments/Lightcoin.png
--------------------------------------------------------------------------------
/images/siteicons/payments/Maestro.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ellite/Wallos/a7e26f688a00101bda85606d59cdd500d1cd6970/images/siteicons/payments/Maestro.png
--------------------------------------------------------------------------------
/images/siteicons/payments/Mastercard.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ellite/Wallos/a7e26f688a00101bda85606d59cdd500d1cd6970/images/siteicons/payments/Mastercard.png
--------------------------------------------------------------------------------
/images/siteicons/payments/PayPal.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ellite/Wallos/a7e26f688a00101bda85606d59cdd500d1cd6970/images/siteicons/payments/PayPal.png
--------------------------------------------------------------------------------
/images/siteicons/payments/Payoneer.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ellite/Wallos/a7e26f688a00101bda85606d59cdd500d1cd6970/images/siteicons/payments/Payoneer.png
--------------------------------------------------------------------------------
/images/siteicons/payments/Stripe.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ellite/Wallos/a7e26f688a00101bda85606d59cdd500d1cd6970/images/siteicons/payments/Stripe.png
--------------------------------------------------------------------------------
/images/siteicons/payments/Thumbs.db:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ellite/Wallos/a7e26f688a00101bda85606d59cdd500d1cd6970/images/siteicons/payments/Thumbs.db
--------------------------------------------------------------------------------
/images/siteicons/payments/Visa.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ellite/Wallos/a7e26f688a00101bda85606d59cdd500d1cd6970/images/siteicons/payments/Visa.png
--------------------------------------------------------------------------------
/images/siteicons/payments/Yandex.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ellite/Wallos/a7e26f688a00101bda85606d59cdd500d1cd6970/images/siteicons/payments/Yandex.png
--------------------------------------------------------------------------------
/images/siteicons/payments/affirm.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ellite/Wallos/a7e26f688a00101bda85606d59cdd500d1cd6970/images/siteicons/payments/affirm.png
--------------------------------------------------------------------------------
/images/siteicons/payments/alipay.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ellite/Wallos/a7e26f688a00101bda85606d59cdd500d1cd6970/images/siteicons/payments/alipay.png
--------------------------------------------------------------------------------
/images/siteicons/payments/amazonpay.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ellite/Wallos/a7e26f688a00101bda85606d59cdd500d1cd6970/images/siteicons/payments/amazonpay.png
--------------------------------------------------------------------------------
/images/siteicons/payments/bancontact.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ellite/Wallos/a7e26f688a00101bda85606d59cdd500d1cd6970/images/siteicons/payments/bancontact.png
--------------------------------------------------------------------------------
/images/siteicons/payments/bitpay.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ellite/Wallos/a7e26f688a00101bda85606d59cdd500d1cd6970/images/siteicons/payments/bitpay.png
--------------------------------------------------------------------------------
/images/siteicons/payments/citadele.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ellite/Wallos/a7e26f688a00101bda85606d59cdd500d1cd6970/images/siteicons/payments/citadele.png
--------------------------------------------------------------------------------
/images/siteicons/payments/directdebit.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ellite/Wallos/a7e26f688a00101bda85606d59cdd500d1cd6970/images/siteicons/payments/directdebit.png
--------------------------------------------------------------------------------
/images/siteicons/payments/elo.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ellite/Wallos/a7e26f688a00101bda85606d59cdd500d1cd6970/images/siteicons/payments/elo.png
--------------------------------------------------------------------------------
/images/siteicons/payments/facebookpay.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ellite/Wallos/a7e26f688a00101bda85606d59cdd500d1cd6970/images/siteicons/payments/facebookpay.png
--------------------------------------------------------------------------------
/images/siteicons/payments/gitopay.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ellite/Wallos/a7e26f688a00101bda85606d59cdd500d1cd6970/images/siteicons/payments/gitopay.png
--------------------------------------------------------------------------------
/images/siteicons/payments/ideal.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ellite/Wallos/a7e26f688a00101bda85606d59cdd500d1cd6970/images/siteicons/payments/ideal.png
--------------------------------------------------------------------------------
/images/siteicons/payments/paysafe.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ellite/Wallos/a7e26f688a00101bda85606d59cdd500d1cd6970/images/siteicons/payments/paysafe.png
--------------------------------------------------------------------------------
/images/siteicons/payments/poli.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ellite/Wallos/a7e26f688a00101bda85606d59cdd500d1cd6970/images/siteicons/payments/poli.png
--------------------------------------------------------------------------------
/images/siteicons/payments/qiwi.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ellite/Wallos/a7e26f688a00101bda85606d59cdd500d1cd6970/images/siteicons/payments/qiwi.png
--------------------------------------------------------------------------------
/images/siteicons/payments/samsungpay.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ellite/Wallos/a7e26f688a00101bda85606d59cdd500d1cd6970/images/siteicons/payments/samsungpay.png
--------------------------------------------------------------------------------
/images/siteicons/payments/shoppay.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ellite/Wallos/a7e26f688a00101bda85606d59cdd500d1cd6970/images/siteicons/payments/shoppay.png
--------------------------------------------------------------------------------
/images/siteicons/payments/skrill.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ellite/Wallos/a7e26f688a00101bda85606d59cdd500d1cd6970/images/siteicons/payments/skrill.png
--------------------------------------------------------------------------------
/images/siteicons/payments/sofort.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ellite/Wallos/a7e26f688a00101bda85606d59cdd500d1cd6970/images/siteicons/payments/sofort.png
--------------------------------------------------------------------------------
/images/siteicons/payments/unionpay.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ellite/Wallos/a7e26f688a00101bda85606d59cdd500d1cd6970/images/siteicons/payments/unionpay.png
--------------------------------------------------------------------------------
/images/siteicons/payments/venmo.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ellite/Wallos/a7e26f688a00101bda85606d59cdd500d1cd6970/images/siteicons/payments/venmo.png
--------------------------------------------------------------------------------
/images/siteicons/payments/verifone.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ellite/Wallos/a7e26f688a00101bda85606d59cdd500d1cd6970/images/siteicons/payments/verifone.png
--------------------------------------------------------------------------------
/images/siteicons/payments/webmoney.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ellite/Wallos/a7e26f688a00101bda85606d59cdd500d1cd6970/images/siteicons/payments/webmoney.png
--------------------------------------------------------------------------------
/images/siteicons/payments/wechat.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ellite/Wallos/a7e26f688a00101bda85606d59cdd500d1cd6970/images/siteicons/payments/wechat.png
--------------------------------------------------------------------------------
/images/siteicons/pwa/about.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ellite/Wallos/a7e26f688a00101bda85606d59cdd500d1cd6970/images/siteicons/pwa/about.png
--------------------------------------------------------------------------------
/images/siteicons/pwa/calendar.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ellite/Wallos/a7e26f688a00101bda85606d59cdd500d1cd6970/images/siteicons/pwa/calendar.png
--------------------------------------------------------------------------------
/images/siteicons/pwa/settings.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ellite/Wallos/a7e26f688a00101bda85606d59cdd500d1cd6970/images/siteicons/pwa/settings.png
--------------------------------------------------------------------------------
/images/siteicons/pwa/stats.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ellite/Wallos/a7e26f688a00101bda85606d59cdd500d1cd6970/images/siteicons/pwa/stats.png
--------------------------------------------------------------------------------
/images/siteicons/pwa/subscriptions.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ellite/Wallos/a7e26f688a00101bda85606d59cdd500d1cd6970/images/siteicons/pwa/subscriptions.png
--------------------------------------------------------------------------------
/images/siteicons/svg/automatic.php:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/images/siteicons/svg/category.php:
--------------------------------------------------------------------------------
1 |
8 |
--------------------------------------------------------------------------------
/images/siteicons/svg/check.php:
--------------------------------------------------------------------------------
1 |
5 |