diff --git a/Dockerfile b/Dockerfile
index 251ef3f..f590ce7 100644
--- a/Dockerfile
+++ b/Dockerfile
@@ -32,13 +32,13 @@ WORKDIR /app
ARG BUILD_DATE
ARG VCS_REF
-ARG VERSION="0.2.0"
+ARG VERSION="0.3.0"
LABEL org.opencontainers.image.created=$BUILD_DATE \
org.opencontainers.image.title="Software Station" \
- org.opencontainers.image.description="A software distribution platform." \
+ org.opencontainers.image.description="A secure software distribution platform." \
org.opencontainers.image.url="https://quad4.io" \
- org.opencontainers.image.documentation="https://github.com/Quad4-Software/software-station/blob/main/README.md" \
+ org.opencontainers.image.documentation="https://git.quad4.io/Quad4-Software/software-station/src/branch/master/frontend/src/lib/docs" \
org.opencontainers.image.source="https://github.com/Quad4-Software/software-station" \
org.opencontainers.image.version=$VERSION \
org.opencontainers.image.revision=$VCS_REF \
diff --git a/Makefile b/Makefile
index 94c7287..f9faacf 100644
--- a/Makefile
+++ b/Makefile
@@ -1,4 +1,4 @@
-.PHONY: all build-frontend build-go build-wasm clean release run lint scan check format test test-wasm dev docker-build
+.PHONY: all build-frontend build-go build-wasm clean release run lint scan check format tidy test test-wasm dev docker-build
BINARY_NAME=software-station
FRONTEND_DIR=frontend
@@ -51,6 +51,8 @@ scan:
check:
cd $(FRONTEND_DIR) && pnpm run check
+tidy: format lint check
+
test: test-wasm
go test -v -coverpkg=./... ./...
diff --git a/docker-compose.coolify.yaml b/docker-compose.coolify.yaml
index 5ae41e7..70456c2 100644
--- a/docker-compose.coolify.yaml
+++ b/docker-compose.coolify.yaml
@@ -12,6 +12,7 @@ services:
CONFIG_PATH: /app/data/software.txt
UA_BLOCKLIST_PATH: /app/data/ua-blocklist.txt
ALLOWED_ORIGINS: https://software.quad4.io
+ CACHE_ASSETS: true
volumes:
- software-station-data:/app/data
- software-station-cache:/app/.cache
diff --git a/docker-compose.yml b/docker-compose.yml
index 46055cc..1290966 100644
--- a/docker-compose.yml
+++ b/docker-compose.yml
@@ -12,6 +12,7 @@ services:
- GITEA_SERVER=${GITEA_SERVER:-https://git.quad4.io}
- CONFIG_PATH=/app/data/software.txt
- UA_BLOCKLIST_PATH=/app/data/ua-blocklist.txt
+ - CACHE_ASSETS=true
security_opt:
- no-new-privileges:true
restart: unless-stopped
diff --git a/frontend/src/lib/components/SearchBar.svelte b/frontend/src/lib/components/SearchBar.svelte
index 9252df2..4ba2053 100644
--- a/frontend/src/lib/components/SearchBar.svelte
+++ b/frontend/src/lib/components/SearchBar.svelte
@@ -5,10 +5,10 @@
let { searchQuery = $bindable('') }: { searchQuery?: string } = $props();
-
+
-
{$t('common.title')}
-
{$t('common.subtitle')}
+
{$t('common.title')}
+
{$t('common.subtitle')}
diff --git a/frontend/src/lib/docs/software/webnews.de.md b/frontend/src/lib/docs/software/webnews.de.md
index dfdb40f..244bf4f 100644
--- a/frontend/src/lib/docs/software/webnews.de.md
+++ b/frontend/src/lib/docs/software/webnews.de.md
@@ -17,6 +17,7 @@ Web News ist ein auf Privatsphäre ausgerichteter, offline-fähiger RSS-Reader u
## Privatsphäre und Sicherheit
Web News basiert auf einer "Zero-Knowledge"-Philosophie, um sicherzustellen, dass Benutzerdaten privat bleiben:
+
- **Datensouveränität**: Ihre Leseliste und Ihr Verlauf verlassen niemals Ihr Gerät.
- **Anonymer Zugriff**: Verwendet 16-stellige Kontonummern für den Serverzugriff anstelle von persönlichen Identifikatoren.
- **Gehärtetes Backend**: Verfügt über integriertes Bot-Blocking, Ratenbegrenzung und sichere Token-Generierung.
diff --git a/frontend/src/lib/docs/software/webnews.it.md b/frontend/src/lib/docs/software/webnews.it.md
index ceb546d..b5981a2 100644
--- a/frontend/src/lib/docs/software/webnews.it.md
+++ b/frontend/src/lib/docs/software/webnews.it.md
@@ -17,6 +17,7 @@ Web News è un lettore RSS orientato alla privacy, progettato per funzionare off
## Privacy e sicurezza
Web News è costruito su una filosofia "zero-knowledge" per garantire che i dati degli utenti rimangano privati:
+
- **Sovranità dei dati**: La tua lista di lettura e la tua cronologia non lasciano mai il tuo dispositivo.
- **Accesso anonimo**: Utilizza numeri di conto a 16 cifre per l'accesso al server invece di identificatori personali.
- **Backend blindato**: Include blocco dei bot integrato, limitazione della frequenza e generazione di token sicuri.
diff --git a/frontend/src/lib/docs/software/webnews.md b/frontend/src/lib/docs/software/webnews.md
index 9be8bd2..8d61d70 100644
--- a/frontend/src/lib/docs/software/webnews.md
+++ b/frontend/src/lib/docs/software/webnews.md
@@ -17,6 +17,7 @@ Web News is a privacy-focused, offline-first RSS reader and full-text extractor.
## Privacy and Security
Web News is built on a "zero-knowledge" philosophy to ensure user data remains private:
+
- **Data Sovereignty**: Your reading list and history never leave your device.
- **Anonymous Access**: Uses 16-digit account numbers for server access instead of personal identifiers.
- **Hardened Backend**: Features built-in bot blocking, rate limiting, and secure token generation.
diff --git a/frontend/src/lib/docs/software/webnews.ru.md b/frontend/src/lib/docs/software/webnews.ru.md
index 8cc09d3..486cddf 100644
--- a/frontend/src/lib/docs/software/webnews.ru.md
+++ b/frontend/src/lib/docs/software/webnews.ru.md
@@ -17,6 +17,7 @@ Web News — это ориентированный на конфиденциал
## Конфиденциальность и безопасность
Web News построен на философии «нулевого знания», чтобы гарантировать приватность пользовательских данных:
+
- **Суверенитет данных**: Ваш список чтения и история никогда не покидают ваше устройство.
- **Анонимный доступ**: Использует 16-значные номера счетов для доступа к серверу вместо личных идентификаторов.
- **Защищенный бэкенд**: Встроенная блокировка ботов, ограничение скорости и безопасная генерация токенов.
diff --git a/frontend/src/lib/i18n/locales/de.json b/frontend/src/lib/i18n/locales/de.json
index f087e21..a0ad532 100644
--- a/frontend/src/lib/i18n/locales/de.json
+++ b/frontend/src/lib/i18n/locales/de.json
@@ -35,7 +35,11 @@
"pageNotFound": "Seite nicht gefunden",
"pageNotFoundDesc": "Die gesuchte Seite wurde möglicherweise entfernt, ihr Name wurde geändert oder sie ist vorübergehend nicht verfügbar.",
"error": "Fehler",
- "backHome": "Zurück zur Startseite"
+ "backHome": "Zurück zur Startseite",
+ "tooManyRequests": "Zu viele Anfragen",
+ "tooManyRequestsDesc": "Sie haben in kurzer Zeit zu viele Anfragen gesendet. Bitte warten Sie einen Moment und versuchen Sie es dann erneut.",
+ "forbidden": "Zugriff verweigert",
+ "forbiddenDesc": "Ihr Zugriff wurde von unserem Sicherheitssystem eingeschränkt. Dies kann aufgrund verdächtiger Muster oder automatisiertem Bot-Verhalten passieren."
},
"os": {
"windows": "Windows",
diff --git a/frontend/src/lib/i18n/locales/en.json b/frontend/src/lib/i18n/locales/en.json
index 4fdac63..6da158a 100644
--- a/frontend/src/lib/i18n/locales/en.json
+++ b/frontend/src/lib/i18n/locales/en.json
@@ -35,7 +35,11 @@
"pageNotFound": "Page Not Found",
"pageNotFoundDesc": "The page you are looking for might have been removed, had its name changed, or is temporarily unavailable.",
"error": "Error",
- "backHome": "Back to Home"
+ "backHome": "Back to Home",
+ "tooManyRequests": "Too Many Requests",
+ "tooManyRequestsDesc": "You've sent too many requests in a short period of time. Please slow down and try again later.",
+ "forbidden": "Access Denied",
+ "forbiddenDesc": "Your access has been restricted by our security system. This can happen due to suspicious patterns or automated bot behavior."
},
"os": {
"windows": "Windows",
diff --git a/frontend/src/lib/i18n/locales/it.json b/frontend/src/lib/i18n/locales/it.json
index db3bb28..a4d6812 100644
--- a/frontend/src/lib/i18n/locales/it.json
+++ b/frontend/src/lib/i18n/locales/it.json
@@ -35,7 +35,11 @@
"pageNotFound": "Pagina non trovata",
"pageNotFoundDesc": "La pagina che stai cercando potrebbe essere stata rimossa, aver cambiato nome o essere temporaneamente non disponibile.",
"error": "Errore",
- "backHome": "Torna alla Home"
+ "backHome": "Torna alla Home",
+ "tooManyRequests": "Troppe richieste",
+ "tooManyRequestsDesc": "Hai inviato troppe richieste in un breve periodo di tempo. Per favore, rallenta e riprova più tardi.",
+ "forbidden": "Accesso negato",
+ "forbiddenDesc": "Il tuo accesso è stato limitato dal nostro sistema di sicurezza. Ciò può accadere a causa di pattern sospetti o comportamenti da bot automatizzati."
},
"os": {
"windows": "Windows",
diff --git a/frontend/src/lib/i18n/locales/ru.json b/frontend/src/lib/i18n/locales/ru.json
index 200397d..0f26c76 100644
--- a/frontend/src/lib/i18n/locales/ru.json
+++ b/frontend/src/lib/i18n/locales/ru.json
@@ -35,7 +35,11 @@
"pageNotFound": "Страница не найдена",
"pageNotFoundDesc": "Запрошенная страница могла быть удалена, ее название изменено или она временно недоступна.",
"error": "Ошибка",
- "backHome": "На главную"
+ "backHome": "На главную",
+ "tooManyRequests": "Слишком много запросов",
+ "tooManyRequestsDesc": "Вы отправили слишком много запросов за короткий промежуток времени. Пожалуйста, подождите и попробуйте позже.",
+ "forbidden": "Доступ запрещен",
+ "forbiddenDesc": "Ваш доступ был ограничен нашей системой безопасности. Это может произойти из-за подозрительной активности или использования ботов."
},
"os": {
"windows": "Windows",
diff --git a/frontend/src/routes/+error.svelte b/frontend/src/routes/+error.svelte
index 3236c2b..232a4e7 100644
--- a/frontend/src/routes/+error.svelte
+++ b/frontend/src/routes/+error.svelte
@@ -7,6 +7,8 @@
const message = $page.error?.message || $t('common.errorOccurred');
const is404 = status === 404;
+ const is429 = status === 429;
+ const is403 = status === 403;