Compare commits

...

30 Commits

Author SHA1 Message Date
shamoon
6fbe080b28 Bump version to 1.0.4 2025-03-16 14:13:12 -07:00
shamoon
4047f8d6e8 Merge branch 'dev' 2025-03-16 14:12:45 -07:00
github-actions[bot]
59cd5564f8 New Crowdin translations by GitHub Action (#4985)
Co-authored-by: Crowdin Bot <support+bot@crowdin.com>
2025-03-16 14:12:30 -07:00
shamoon
5f19e4af91 Fix: fix custom quicklaunch search without search widget (#5003) 2025-03-16 13:12:20 -07:00
shamoon
5ea46881ee Fix: re-add tailwind css safelist (#4999) 2025-03-16 08:32:27 -07:00
shamoon
9545757bb9 Fix: fix bookmark heights again (#4997) 2025-03-16 07:33:30 -07:00
shamoon
95507aab54 Change: re-enable k8s ingress by default (#4988) 2025-03-16 02:35:43 -07:00
shamoon
564dfb7ce3 Add k3d ingress setting and HOMEPAGE_ALLOWED_HOSTS 2025-03-15 21:05:11 -07:00
shamoon
7b72442114 Update index.md 2025-03-15 16:29:02 -07:00
shamoon
65370a7668 Fix: fix Kubernetes stats in v1.0.0 (#4984)
Co-authored-by: djeinstine <2105133+djeinstine@users.noreply.github.com>
2025-03-15 16:23:29 -07:00
shamoon
6e9339b14c Chore: update minecraftstatuspinger to 1.2.2 (#4982) 2025-03-15 15:30:21 -07:00
shamoon
241c786710 Merge branch 'main' into dev 2025-03-15 10:18:34 -07:00
shamoon
801ce479d8 Add links to docs 2025-03-15 10:18:26 -07:00
shamoon
16730ffec2 Merge branch 'main' into dev 2025-03-15 09:46:36 -07:00
shamoon
b35dd80e8c Improve docs 2025-03-15 09:46:23 -07:00
shamoon
82b159bf14 Improve docs 2025-03-15 09:30:10 -07:00
shamoon
6292a0709c Bump version to 1.0.3 2025-03-15 07:43:43 -07:00
shamoon
42af93bef3 Merge branch 'dev' 2025-03-15 07:43:30 -07:00
Xavier Alexander
964991781c Documentation: add HOMEPAGE_ALLOWED_HOSTS to k8s docs (#4969) 2025-03-15 07:40:26 -07:00
shamoon
607a14083e Fix: jellyfin handle empty episode numbers (#4970) 2025-03-15 07:38:35 -07:00
shamoon
133a0a6539 Fix this 2025-03-15 07:31:15 -07:00
shamoon
0d0f465e16 Update index.md 2025-03-15 07:16:42 -07:00
shamoon
16c1b2da9b Enhancement: allow disabling host header checking (#4967) 2025-03-15 07:14:41 -07:00
shamoon
4761a56b3d Remove reference to helm chart 2025-03-15 07:13:23 -07:00
shamoon
9d40b67d49 Change: prefer IPv4 in docker image (#4954) 2025-03-14 22:51:07 -07:00
shamoon
97f4bcbdb0 Documentation: note disable ipv6 2025-03-14 22:35:47 -07:00
brikim
ea1375e575 Fix: correct units for speedtest tracker API v2 (#4950)
Co-authored-by: shamoon <4887959+shamoon@users.noreply.github.com>
2025-03-14 22:02:13 -07:00
shamoon
733a3140d1 Documentation: note komga api key 2025-03-14 21:16:20 -07:00
shamoon
b5ac617597 Fix: fix kavita API body with key (#4948) 2025-03-14 21:09:46 -07:00
shamoon
9b06212a92 Fix: wrapping in bookmarks (#4945) 2025-03-14 18:29:27 -07:00
23 changed files with 247 additions and 265 deletions

View File

@@ -56,12 +56,12 @@ COPY --link --chmod=755 docker-entrypoint.sh /usr/local/bin/
RUN apk add --no-cache su-exec
ENV HOSTNAME=::
ENV HOSTNAME=0.0.0.0
ENV PORT=3000
EXPOSE $PORT
HEALTHCHECK --interval=10s --timeout=3s --start-period=20s \
CMD wget --no-verbose --tries=1 --spider --no-check-certificate http://localhost:$PORT/api/healthcheck || exit 1
CMD wget --no-verbose --tries=1 --spider --no-check-certificate http://127.0.0.1:$PORT/api/healthcheck || exit 1
ENTRYPOINT ["docker-entrypoint.sh"]
CMD ["node", "server.js"]

View File

@@ -80,7 +80,7 @@ services:
image: ghcr.io/gethomepage/homepage:latest
container_name: homepage
environment:
HOMEPAGE_ALLOWED_HOSTS: gethomepage.dev # required, may need port
HOMEPAGE_ALLOWED_HOSTS: gethomepage.dev # required, may need port. See gethomepage.dev/installation/#homepage_allowed_hosts
PUID: 1000 # optional, your user id
PGID: 1000 # optional, your group id
ports:

View File

@@ -25,13 +25,13 @@ To configure Kubernetes gateway-api, ingress or ingressRoute service discovery,
Example settings:
```yaml
ingress: true # enable ingress only
ingress: true # default, enable ingress only
```
or
```yaml
ingress: true # enable ingress
ingress: true # default, enable ingress
traefik: true # enable traefik ingressRoute
gateway: true # enable gateway-api
```

View File

@@ -16,7 +16,7 @@ services:
- /path/to/config:/app/config # Make sure your local config directory exists
- /var/run/docker.sock:/var/run/docker.sock # (optional) For docker integrations
environment:
HOMEPAGE_ALLOWED_HOSTS: gethomepage.dev # required, may need port
HOMEPAGE_ALLOWED_HOSTS: gethomepage.dev # required, may need port. See gethomepage.dev/installation/#homepage_allowed_hosts
```
### Running as non-root
@@ -38,7 +38,7 @@ services:
- /path/to/config:/app/config # Make sure your local config directory exists
- /var/run/docker.sock:/var/run/docker.sock # (optional) For docker integrations, see alternative methods
environment:
HOMEPAGE_ALLOWED_HOSTS: gethomepage.dev # required, may need port
HOMEPAGE_ALLOWED_HOSTS: gethomepage.dev # required, may need port. See gethomepage.dev/installation/#homepage_allowed_hosts
PUID: $PUID
PGID: $PGID
```

View File

@@ -29,4 +29,12 @@ You have a few options for deploying homepage, depending on your needs. We offer
### `HOMEPAGE_ALLOWED_HOSTS`
As of v1.0 there is one required environment variable when deploying via a public URL, <code>HOMEPAGE_ALLOWED_HOSTS</code>. This is a comma separated (no spaces) list of allowed hosts (sometimes with the port) that can access your homepage. See the [docker](docker.md) and [source](source.md) installation pages for examples.
As of v1.0 there is one required environment variable to access homepage via a URL other than `localhost`, <code>HOMEPAGE_ALLOWED_HOSTS</code>. The setting helps prevent certain kinds of attacks when retrieving data from the homepage API proxy.
The value is a comma-separated (no spaces) list of allowed hosts (sometimes with the port) that can host your homepage install. See the [docker](docker.md), [kubernetes](k8s.md) and [source](source.md) installation pages for more information about where / how to set the variable.
`localhost:3000` and `127.0.0.1:3000` are always included, but you can add a domain or IP address to this list to allow that host such as `HOMEPAGE_ALLOWED_HOSTS=gethomepage.dev,192.168.1.2:1234`, etc.
If you are seeing errors about host validation, check the homepage logs and ensure that the host exactly as output in the logs is in the `HOMEPAGE_ALLOWED_HOSTS` list.
This can be disabled by setting `HOMEPAGE_ALLOWED_HOSTS` to `*` but this is not recommended.

View File

@@ -3,85 +3,6 @@ title: Kubernetes Installation
description: Install on Kubernetes
---
## Install with Helm
There is an [unofficial helm chart](https://github.com/jameswynn/helm-charts/tree/main/charts/homepage) that creates all the necessary manifests, including the service account and RBAC entities necessary for service discovery.
```sh
helm repo add jameswynn https://jameswynn.github.io/helm-charts
helm install homepage jameswynn/homepage -f values.yaml
```
The helm chart allows for all the configurations to be inlined directly in your `values.yaml`:
```yaml
config:
bookmarks:
- Developer:
- Github:
- abbr: GH
href: https://github.com/
services:
- My First Group:
- My First Service:
href: http://localhost/
description: Homepage is awesome
- My Second Group:
- My Second Service:
href: http://localhost/
description: Homepage is the best
- My Third Group:
- My Third Service:
href: http://localhost/
description: Homepage is 😎
widgets:
# show the kubernetes widget, with the cluster summary and individual nodes
- kubernetes:
cluster:
show: true
cpu: true
memory: true
showLabel: true
label: "cluster"
nodes:
show: true
cpu: true
memory: true
showLabel: true
- search:
provider: duckduckgo
target: _blank
kubernetes:
mode: cluster
settings:
# The service account is necessary to allow discovery of other services
serviceAccount:
create: true
name: homepage
# This enables the service account to access the necessary resources
enableRbac: true
ingress:
main:
enabled: true
annotations:
# Example annotations to add Homepage to your Homepage!
gethomepage.dev/enabled: "true"
gethomepage.dev/name: "Homepage"
gethomepage.dev/description: "Dynamically Detected Homepage"
gethomepage.dev/group: "Dynamic"
gethomepage.dev/icon: "homepage.png"
hosts:
- host: homepage.example.com
paths:
- path: /
pathType: Prefix
```
## Install with Kubernetes Manifests
If you don't want to use the unofficial Helm chart, you can also create your own Kubernetes manifest(s) and apply them with `kubectl apply -f filename.yaml`.
@@ -302,6 +223,9 @@ spec:
- name: homepage
image: "ghcr.io/gethomepage/homepage:latest"
imagePullPolicy: Always
env:
- name: HOMEPAGE_ALLOWED_HOSTS
value: gethomepage.dev # required, may need port. See gethomepage.dev/installation/#homepage_allowed_hosts
ports:
- name: http
containerPort: 3000

View File

@@ -25,3 +25,5 @@ HOMEPAGE_ALLOWED_HOSTS=gethomepage.dev:1234 pnpm start
```
When updating homepage versions you will need to re-build the static files i.e. repeat the process above.
See [HOMEPAGE_ALLOWED_HOSTS](index.md#homepage_allowed_hosts) for more information on this environment variable.

View File

@@ -12,6 +12,7 @@ hide:
- Check config/logs/homepage.log, on docker simply e.g. `docker logs homepage`. This may provide some insight into the reason for an error.
- Check the browser error console, this can also sometimes provide useful information.
- Consider setting the `ENV` variable `LOG_LEVEL` to `debug`.
- If certain widgets are failing when connecting to public APIs, consider [disabling IPv6](#disabling-ipv6).
## Service Widget Errors
@@ -66,3 +67,24 @@ All service widgets work essentially the same, that is, homepage makes a proxied
## Missing custom icons
If, after correctly adding and mapping your custom icons via the [Icons](../configs/services.md#icons) instructions, you are still unable to see your icons please try recreating your container.
## Disabling IPv6
If you are having issues with certain widgets that are unable to reach public APIs (e.g. weather), you may need to disable IPv6 on your host machine. This can be done by adding the following to your `docker-compose.yml` file (or for docker run, the equivalent flag):
```yaml
services:
homepage:
...
sysctls:
- net.ipv6.conf.all.disable_ipv6=1
```
or disable IPv6 for the docker network:
```yaml
networks:
some_network:
driver: bridge
enable_ipv6: false
```

View File

@@ -20,4 +20,5 @@ widget:
url: http://komga.host.or.ip:port
username: username
password: password
key: komgaapikey # optional
```

View File

@@ -46,6 +46,10 @@ config:
docker:
settings:
env:
- name: HOMEPAGE_ALLOWED_HOSTS
value: "homepage.k3d.localhost:8080"
serviceAccount:
create: true
name: homepage

View File

@@ -1,6 +1,6 @@
{
"name": "homepage",
"version": "1.0.2",
"version": "1.0.4",
"private": true,
"scripts": {
"preinstall": "npx only-allow pnpm",
@@ -24,7 +24,7 @@
"json-rpc-2.0": "^1.7.0",
"luxon": "^3.5.0",
"memory-cache": "^0.2.0",
"minecraftstatuspinger": "^1.2.1",
"minecraftstatuspinger": "^1.2.2",
"next": "^15.1.7",
"next-i18next": "^12.1.0",
"ping": "^0.4.4",

24
pnpm-lock.yaml generated
View File

@@ -48,8 +48,8 @@ importers:
specifier: ^0.2.0
version: 0.2.0
minecraftstatuspinger:
specifier: ^1.2.1
version: 1.2.1
specifier: ^1.2.2
version: 1.2.2
next:
specifier: ^15.1.7
version: 15.1.7(react-dom@18.3.1(react@18.3.1))(react@18.3.1)
@@ -101,10 +101,6 @@ importers:
xml-js:
specifier: ^1.6.11
version: 1.6.11
optionalDependencies:
osx-temperature-sensor:
specifier: ^1.0.8
version: 1.0.8
devDependencies:
'@tailwindcss/forms':
specifier: ^0.5.10
@@ -151,6 +147,10 @@ importers:
typescript:
specifier: ^5.7.3
version: 5.7.3
optionalDependencies:
osx-temperature-sensor:
specifier: ^1.0.8
version: 1.0.8
packages:
@@ -1911,9 +1911,9 @@ packages:
resolution: {integrity: sha512-e5ISH9xMYU0DzrT+jl8q2ze9D6eWBto+I8CNpe+VI+K2J/F/k3PdkdTdz4wvGVH4NTpo+NRYTVIuMQEMMcsLqg==}
engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0}
minecraftstatuspinger@1.2.1:
resolution: {integrity: sha512-Qo/3TzV0UeULbVyqMqS9sUPbNKGFK7U7as1xlS/xeXryQQEwitOz5SkVhVphY4fCTacl5a+E4VXiTq6TPKYDKw==}
engines: {node: '>=16.0.0'}
minecraftstatuspinger@1.2.2:
resolution: {integrity: sha512-3PDWcifjw6cliGnGqw0+nJVWWPOcpLDyNLh4D84vCNzPD2h9REbN5Ne11I//CMkIu5xJiIuyGwI44gyRYYbpuw==}
engines: {node: '>=14.0.0'}
mini-svg-data-uri@1.4.4:
resolution: {integrity: sha512-r9deDe9p5FJUPZAk3A59wGH7Ii9YrjjWw0jmw/liSbHl2CHiyXj6FcDXDu2K3TjVAXqiJdaw3xxwlZZr9E6nHg==}
@@ -3918,7 +3918,7 @@ snapshots:
transitivePeerDependencies:
- supports-color
eslint-module-utils@2.12.0(@typescript-eslint/parser@8.24.1(eslint@9.21.0(jiti@2.4.2))(typescript@5.7.3))(eslint-import-resolver-node@0.3.9)(eslint-import-resolver-typescript@3.8.2(eslint-plugin-import@2.31.0)(eslint@9.21.0(jiti@2.4.2)))(eslint@9.21.0(jiti@2.4.2)):
eslint-module-utils@2.12.0(@typescript-eslint/parser@8.24.1(eslint@9.21.0(jiti@2.4.2))(typescript@5.7.3))(eslint-import-resolver-node@0.3.9)(eslint-import-resolver-typescript@3.8.2)(eslint@9.21.0(jiti@2.4.2)):
dependencies:
debug: 3.2.7
optionalDependencies:
@@ -3940,7 +3940,7 @@ snapshots:
doctrine: 2.1.0
eslint: 9.21.0(jiti@2.4.2)
eslint-import-resolver-node: 0.3.9
eslint-module-utils: 2.12.0(@typescript-eslint/parser@8.24.1(eslint@9.21.0(jiti@2.4.2))(typescript@5.7.3))(eslint-import-resolver-node@0.3.9)(eslint-import-resolver-typescript@3.8.2(eslint-plugin-import@2.31.0)(eslint@9.21.0(jiti@2.4.2)))(eslint@9.21.0(jiti@2.4.2))
eslint-module-utils: 2.12.0(@typescript-eslint/parser@8.24.1(eslint@9.21.0(jiti@2.4.2))(typescript@5.7.3))(eslint-import-resolver-node@0.3.9)(eslint-import-resolver-typescript@3.8.2)(eslint@9.21.0(jiti@2.4.2))
hasown: 2.0.2
is-core-module: 2.16.1
is-glob: 4.0.3
@@ -4652,7 +4652,7 @@ snapshots:
mimic-response@4.0.0: {}
minecraftstatuspinger@1.2.1: {}
minecraftstatuspinger@1.2.2: {}
mini-svg-data-uri@1.4.4: {}

View File

@@ -85,16 +85,16 @@
"ping": {
"error": "Error",
"ping": "Ping",
"down": "Down",
"up": "Up",
"down": "Behera",
"up": "Gora",
"not_available": "Not Available"
},
"siteMonitor": {
"http_status": "HTTP status",
"error": "Error",
"response": "Response",
"down": "Down",
"up": "Up",
"response": "Erantzuna",
"down": "Behera",
"up": "Gora",
"not_available": "Not Available"
},
"emby": {
@@ -102,8 +102,8 @@
"transcoding": "Transcoding",
"bitrate": "Bit-tasa",
"no_active": "No Active Streams",
"movies": "Movies",
"series": "Series",
"movies": "Filmak",
"series": "Serieak",
"episodes": "Episodes",
"songs": "Abestiak"
},
@@ -115,39 +115,39 @@
"unknown": "Ezezaguna"
},
"evcc": {
"pv_power": "Production",
"battery_soc": "Battery",
"grid_power": "Grid",
"home_power": "Consumption",
"charge_power": "Charger",
"pv_power": "Produkzioak",
"battery_soc": "Bateria",
"grid_power": "Sarea",
"home_power": "Kontsumoa",
"charge_power": "Kargagailua",
"kilowatt": "kW"
},
"flood": {
"download": "Download",
"upload": "Upload",
"download": "Jeitsierak",
"upload": "Kargatu",
"leech": "Leech",
"seed": "Seed"
},
"freshrss": {
"subscriptions": "Subscriptions",
"unread": "Unread"
"subscriptions": "Harpidetzak",
"unread": "Irakurri gabe"
},
"fritzbox": {
"connectionStatus": "Status",
"connectionStatusUnconfigured": "Unconfigured",
"connectionStatusConnecting": "Connecting",
"connectionStatusConnecting": "Konektatzen",
"connectionStatusAuthenticating": "Authenticating",
"connectionStatusPendingDisconnect": "Pending Disconnect",
"connectionStatusDisconnecting": "Disconnecting",
"connectionStatusDisconnected": "Disconnected",
"connectionStatusConnected": "Connected",
"connectionStatusDisconnected": "Deskonektatuta",
"connectionStatusConnected": "Konektatuta",
"uptime": "Uptime",
"maxDown": "Max. Down",
"maxUp": "Max. Up",
"down": "Down",
"up": "Up",
"down": "Behera",
"up": "Gora",
"received": "Received",
"sent": "Sent",
"sent": "Bidalita",
"externalIPAddress": "Ext. IP",
"externalIPv6Address": "Ext. IPv6",
"externalIPv6Prefix": "Ext. IPv6-Prefix"
@@ -189,7 +189,7 @@
"plex": {
"streams": "Active Streams",
"albums": "Albums",
"movies": "Movies",
"movies": "Filmak",
"tv": "TV Shows"
},
"sabnzbd": {
@@ -199,18 +199,18 @@
},
"rutorrent": {
"active": "Active",
"upload": "Upload",
"download": "Download"
"upload": "Kargatu",
"download": "Jeitsierak"
},
"transmission": {
"download": "Download",
"upload": "Upload",
"download": "Jeitsierak",
"upload": "Kargatu",
"leech": "Leech",
"seed": "Seed"
},
"qbittorrent": {
"download": "Download",
"upload": "Upload",
"download": "Jeitsierak",
"upload": "Kargatu",
"leech": "Leech",
"seed": "Seed"
},
@@ -223,8 +223,8 @@
"invalid": "Invalid"
},
"deluge": {
"download": "Download",
"upload": "Upload",
"download": "Jeitsierak",
"upload": "Kargatu",
"leech": "Leech",
"seed": "Seed"
},
@@ -233,15 +233,15 @@
"cachemissbytes": "Cache Miss Bytes"
},
"downloadstation": {
"download": "Download",
"upload": "Upload",
"download": "Jeitsierak",
"upload": "Kargatu",
"leech": "Leech",
"seed": "Seed"
},
"sonarr": {
"wanted": "Wanted",
"queued": "Queued",
"series": "Series",
"series": "Serieak",
"queue": "Queue",
"unknown": "Ezezaguna"
},
@@ -249,7 +249,7 @@
"wanted": "Wanted",
"missing": "Missing",
"queued": "Queued",
"movies": "Movies",
"movies": "Filmak",
"queue": "Queue",
"unknown": "Ezezaguna"
},
@@ -285,7 +285,7 @@
},
"netalertx": {
"total": "Guztira",
"connected": "Connected",
"connected": "Konektatuta",
"new_devices": "New Devices",
"down_alerts": "Down Alerts"
},
@@ -302,8 +302,8 @@
"latency": "Latency"
},
"speedtest": {
"upload": "Upload",
"download": "Download",
"upload": "Kargatu",
"download": "Jeitsierak",
"ping": "Ping"
},
"portainer": {
@@ -315,7 +315,7 @@
"download": "Downloaded",
"nondownload": "Non-Downloaded",
"read": "Read",
"unread": "Unread",
"unread": "Irakurri gabe",
"downloadedread": "Downloaded & Read",
"downloadedunread": "Downloaded & Unread",
"nondownloadedread": "Non-Downloaded & Read",
@@ -405,7 +405,7 @@
"medusa": {
"wanted": "Wanted",
"queued": "Queued",
"series": "Series"
"series": "Serieak"
},
"minecraft": {
"players": "Jokalariak",
@@ -416,7 +416,7 @@
},
"miniflux": {
"read": "Read",
"unread": "Unread"
"unread": "Irakurri gabe"
},
"authentik": {
"users": "Users",
@@ -523,15 +523,15 @@
"up_to_date": "Up to Date",
"child_bridges": "Child Bridges",
"child_bridges_status": "{{ok}}/{{total}}",
"up": "Up",
"up": "Gora",
"pending": "Pending",
"down": "Down"
"down": "Behera"
},
"healthchecks": {
"new": "New",
"up": "Up",
"up": "Gora",
"grace": "In Grace Period",
"down": "Down",
"down": "Behera",
"paused": "Paused",
"status": "Status",
"last_ping": "Last Ping",
@@ -646,8 +646,8 @@
"load": "Load Avg",
"memory": "Mem Usage",
"wanStatus": "WAN Status",
"up": "Up",
"down": "Down",
"up": "Gora",
"down": "Behera",
"temp": "Temp",
"disk": "Disk Usage",
"wanIP": "WAN IP"
@@ -660,7 +660,7 @@
},
"immich": {
"users": "Users",
"photos": "Photos",
"photos": "Argazkiak",
"videos": "Videos",
"storage": "Storage"
},
@@ -672,14 +672,14 @@
"m": "m"
},
"atsumeru": {
"series": "Series",
"series": "Serieak",
"archives": "Archives",
"chapters": "Chapters",
"categories": "Categories"
},
"komga": {
"libraries": "Libraries",
"series": "Series",
"series": "Serieak",
"books": "Books"
},
"diskstation": {
@@ -688,13 +688,13 @@
"volumeAvailable": "Available"
},
"mylar": {
"series": "Series",
"issues": "Issues",
"series": "Serieak",
"issues": "Arazoak",
"wanted": "Wanted"
},
"photoprism": {
"albums": "Albums",
"photos": "Photos",
"photos": "Argazkiak",
"videos": "Videos",
"people": "People"
},
@@ -772,7 +772,7 @@
"books": "Books",
"authors": "Authors",
"categories": "Categories",
"series": "Series"
"series": "Serieak"
},
"jdownloader": {
"downloadCount": "Queue",
@@ -781,7 +781,7 @@
"downloadSpeed": "Speed"
},
"kavita": {
"seriesCount": "Series",
"seriesCount": "Serieak",
"totalFiles": "Files"
},
"azuredevops": {
@@ -801,8 +801,8 @@
"status": "Status",
"online": "Online",
"offline": "Offline",
"name": "Name",
"map": "Map",
"name": "Izena",
"map": "Mapa",
"currentPlayers": "Current players",
"players": "Jokalariak",
"maxPlayers": "Max players",
@@ -819,10 +819,10 @@
"recipes": "Recipes",
"users": "Users",
"categories": "Categories",
"tags": "Tags"
"tags": "Etiketak"
},
"openmediavault": {
"downloading": "Downloading",
"downloading": "Deskargatzen",
"total": "Guztira",
"running": "Running",
"stopped": "Stopped",
@@ -832,8 +832,8 @@
"openwrt": {
"uptime": "Uptime",
"cpuLoad": "CPU Load Avg (5m)",
"up": "Up",
"down": "Down",
"up": "Gora",
"down": "Behera",
"bytesTx": "Transmitted",
"bytesRx": "Received"
},
@@ -846,9 +846,9 @@
"sitesDown": "Sites Down",
"paused": "Paused",
"notyetchecked": "Not Yet Checked",
"up": "Up",
"up": "Gora",
"seemsdown": "Seems Down",
"down": "Down",
"down": "Behera",
"unknown": "Ezezaguna"
},
"calendar": {
@@ -856,7 +856,7 @@
"physicalRelease": "Physical release",
"digitalRelease": "Digital release",
"noEventsToday": "No events for today!",
"noEventsFound": "No events found"
"noEventsFound": "Ez da gertaerarik aurkitu."
},
"romm": {
"platforms": "Platforms",
@@ -868,7 +868,7 @@
},
"mailcow": {
"domains": "Domains",
"mailboxes": "Mailboxes",
"mailboxes": "Gutunontziak",
"mails": "Mails",
"storage": "Storage"
},
@@ -877,14 +877,14 @@
"criticals": "Criticals"
},
"plantit": {
"events": "Events",
"plants": "Plants",
"photos": "Photos",
"events": "Ekitaldiak",
"plants": "Landareak",
"photos": "Argazkiak",
"species": "Species"
},
"gitea": {
"notifications": "Notifications",
"issues": "Issues",
"notifications": "Jakinarazpenak",
"issues": "Arazoak",
"pulls": "Pull Requests"
},
"stash": {
@@ -894,34 +894,34 @@
"playDuration": "Time Watched",
"sceneSize": "Scenes Size",
"sceneDuration": "Scenes Duration",
"images": "Images",
"imageSize": "Images Size",
"images": "Irudia",
"imageSize": "Irudiaren tamaina",
"galleries": "Galleries",
"performers": "Performers",
"studios": "Studios",
"movies": "Movies",
"tags": "Tags",
"movies": "Filmak",
"tags": "Etiketak",
"oCount": "O Count"
},
"tandoor": {
"users": "Users",
"recipes": "Recipes",
"keywords": "Keywords"
"keywords": "Hitz gakoak"
},
"homebox": {
"items": "Items",
"items": "Elementuak",
"totalWithWarranty": "With Warranty",
"locations": "Locations",
"labels": "Labels",
"labels": "Etiketak",
"users": "Users",
"totalValue": "Total Value"
"totalValue": "Guztira"
},
"crowdsec": {
"alerts": "Alerts",
"bans": "Bans"
},
"wgeasy": {
"connected": "Connected",
"connected": "Konektatuta",
"enabled": "Enabled",
"disabled": "Disabled",
"total": "Guztira"
@@ -934,8 +934,8 @@
},
"myspeed": {
"ping": "Ping",
"download": "Download",
"upload": "Upload"
"download": "Jeitsierak",
"upload": "Kargatu"
},
"stocks": {
"stocks": "Stocks",
@@ -951,23 +951,23 @@
},
"linkwarden": {
"links": "Links",
"collections": "Collections",
"tags": "Tags"
"collections": "Bildumak",
"tags": "Etiketak"
},
"zabbix": {
"unclassified": "Not classified",
"information": "Informazioa",
"warning": "Warning",
"average": "Average",
"high": "High",
"warning": "Abisua",
"average": "Batez besteko",
"high": "Altua",
"disaster": "Disaster"
},
"lubelogger": {
"vehicle": "Vehicle",
"vehicles": "Vehicles",
"vehicles": "Ibilgailuak",
"serviceRecords": "Service Records",
"reminders": "Reminders",
"nextReminder": "Next Reminder",
"reminders": "Oroigarriak",
"nextReminder": "Hurrengo abisua",
"none": "None"
},
"vikunja": {
@@ -977,7 +977,7 @@
"tasksInProgress": "Tasks In Progress"
},
"headscale": {
"name": "Name",
"name": "Izena",
"address": "Address",
"last_seen": "Last Seen",
"status": "Status",
@@ -985,10 +985,10 @@
"offline": "Offline"
},
"beszel": {
"name": "Name",
"name": "Izena",
"systems": "Systems",
"up": "Up",
"down": "Down",
"up": "Gora",
"down": "Behera",
"paused": "Paused",
"pending": "Pending",
"status": "Status",
@@ -999,23 +999,23 @@
"network": "NET"
},
"argocd": {
"apps": "Apps",
"synced": "Synced",
"apps": "Aplikazioak",
"synced": "Sinkronizatuta",
"outOfSync": "Out Of Sync",
"healthy": "Osasuntsu",
"degraded": "Degraded",
"progressing": "Progressing",
"missing": "Missing",
"suspended": "Suspended"
"suspended": "Etenda"
},
"spoolman": {
"loading": "Loading"
},
"gitlab": {
"groups": "Groups",
"issues": "Issues",
"groups": "Taldeak",
"issues": "Arazoak",
"merges": "Merge Requests",
"projects": "Projects"
"projects": "Proiektuak"
},
"apcups": {
"status": "Status",
@@ -1024,11 +1024,11 @@
"timeleft": "Time Left"
},
"hoarder": {
"bookmarks": "Bookmarks",
"favorites": "Favorites",
"archived": "Archived",
"bookmarks": "Laster-markak",
"favorites": "Gogokoak",
"archived": "Artxibatuta",
"highlights": "Highlights",
"lists": "Lists",
"tags": "Tags"
"lists": "Zerrendak",
"tags": "Etiketak"
}
}

View File

@@ -22,7 +22,7 @@ export default function Item({ bookmark, iconOnly = false }) {
className={classNames(
settings.cardBlur !== undefined && `backdrop-blur${settings.cardBlur.length ? "-" : ""}${settings.cardBlur}`,
"text-left cursor-pointer transition-all rounded-md font-medium text-theme-700 dark:text-theme-200 dark:hover:text-theme-300 shadow-md shadow-theme-900/10 dark:shadow-theme-900/20 bg-theme-100/20 hover:bg-theme-300/20 dark:bg-white/5 dark:hover:bg-white/10",
iconOnly ? "h-[60px] w-[60px] grid" : "block w-full h-8 mb-3",
iconOnly ? "h-[60px] w-[60px] grid" : "block w-full mb-3",
)}
>
{iconOnly ? (

View File

@@ -4,11 +4,12 @@ export function middleware(req) {
// Check the Host header, if HOMEPAGE_ALLOWED_HOSTS is set
const host = req.headers.get("host");
const port = process.env.PORT || 3000;
let allowedHosts = [`localhost:${port}`];
let allowedHosts = [`localhost:${port}`, `127.0.0.1:${port}`];
const allowAll = process.env.HOMEPAGE_ALLOWED_HOSTS === "*";
if (process.env.HOMEPAGE_ALLOWED_HOSTS) {
allowedHosts = allowedHosts.concat(process.env.HOMEPAGE_ALLOWED_HOSTS.split(","));
}
if (!host || !allowedHosts.includes(host)) {
if (!allowAll && (!host || !allowedHosts.includes(host))) {
// eslint-disable-next-line no-console
console.error(
`Host validation failed for: ${host}. Hint: Set the HOMEPAGE_ALLOWED_HOSTS environment variable to allow requests from this host / port.`,

View File

@@ -12,6 +12,55 @@ import { TabProvider } from "utils/contexts/tab";
import nextI18nextConfig from "../../next-i18next.config";
// eslint-disable-next-line no-unused-vars
const tailwindSafelist = [
// TODO: remove pending https://github.com/tailwindlabs/tailwindcss/pull/17147
"backdrop-blur",
"backdrop-blur-sm",
"backdrop-blur-md",
"backdrop-blur-xl",
"backdrop-saturate-0",
"backdrop-saturate-50",
"backdrop-saturate-100",
"backdrop-saturate-150",
"backdrop-saturate-200",
"backdrop-brightness-0",
"backdrop-brightness-50",
"backdrop-brightness-75",
"backdrop-brightness-90",
"backdrop-brightness-95",
"backdrop-brightness-100",
"backdrop-brightness-105",
"backdrop-brightness-110",
"backdrop-brightness-125",
"backdrop-brightness-150",
"backdrop-brightness-200",
"grid-cols-1",
"md:grid-cols-1",
"md:grid-cols-2",
"lg:grid-cols-1",
"lg:grid-cols-2",
"lg:grid-cols-3",
"lg:grid-cols-4",
"lg:grid-cols-5",
"lg:grid-cols-6",
"lg:grid-cols-7",
"lg:grid-cols-8",
// for status
"bg-white",
"bg-black",
"dark:bg-white",
"bg-orange-400",
"dark:bg-orange-400",
// yep
"h-0 h-1 h-2 h-3 h-4 h-5 h-6 h-7 h-8 h-9 h-10 h-11 h-12 h-13 h-14 h-15 h-16 h-17 h-18 h-19 h-20 h-21 h-22 h-23 h-24 h-25 h-26 h-27 h-28 h-29 h-30 h-31 h-32 h-33 h-34 h-35 h-36 h-37 h-38 h-39 h-40 h-41 h-42 h-43 h-44 h-45 h-46 h-47 h-48 h-49 h-50 h-51 h-52 h-53 h-54 h-55 h-56 h-57 h-58 h-59 h-60 h-61 h-62 h-63 h-64 h-65 h-66 h-67 h-68 h-69 h-70 h-71 h-72 h-73 h-74 h-75 h-76 h-77 h-78 h-79 h-80 h-81 h-82 h-83 h-84 h-85 h-86 h-87 h-88 h-89 h-90 h-91 h-92 h-93 h-94 h-95 h-96",
"sm:h-0 sm:h-1 sm:h-2 sm:h-3 sm:h-4 sm:h-5 sm:h-6 sm:h-7 sm:h-8 sm:h-9 sm:h-10 sm:h-11 sm:h-12 sm:h-13 sm:h-14 sm:h-15 sm:h-16 sm:h-17 sm:h-18 sm:h-19 sm:h-20 sm:h-21 sm:h-22 sm:h-23 sm:h-24 sm:h-25 sm:h-26 sm:h-27 sm:h-28 sm:h-29 sm:h-30 sm:h-31 sm:h-32 sm:h-33 sm:h-34 sm:h-35 sm:h-36 sm:h-37 sm:h-38 sm:h-39 sm:h-40 sm:h-41 sm:h-42 sm:h-43 sm:h-44 sm:h-45 sm:h-46 sm:h-47 sm:h-48 sm:h-49 sm:h-50 sm:h-51 sm:h-52 sm:h-53 sm:h-54 sm:h-55 sm:h-56 sm:h-57 sm:h-58 sm:h-59 sm:h-60 sm:h-61 sm:h-62 sm:h-63 sm:h-64 sm:h-65 sm:h-66 sm:h-67 sm:h-68 sm:h-69 sm:h-70 sm:h-71 sm:h-72 sm:h-73 sm:h-74 sm:h-75 sm:h-76 sm:h-77 sm:h-78 sm:h-79 sm:h-80 sm:h-81 sm:h-82 sm:h-83 sm:h-84 sm:h-85 sm:h-86 sm:h-87 sm:h-88 sm:h-89 sm:h-90 sm:h-91 sm:h-92 sm:h-93 sm:h-94 sm:h-95 sm:h-96",
"md:h-0 md:h-1 md:h-2 md:h-3 md:h-4 md:h-5 md:h-6 md:h-7 md:h-8 md:h-9 md:h-10 md:h-11 md:h-12 md:h-13 md:h-14 md:h-15 md:h-16 md:h-17 md:h-18 md:h-19 md:h-20 md:h-21 md:h-22 md:h-23 md:h-24 md:h-25 md:h-26 md:h-27 md:h-28 md:h-29 md:h-30 md:h-31 md:h-32 md:h-33 md:h-34 md:h-35 md:h-36 md:h-37 md:h-38 md:h-39 md:h-40 md:h-41 md:h-42 md:h-43 md:h-44 md:h-45 md:h-46 md:h-47 md:h-48 md:h-49 md:h-50 md:h-51 md:h-52 md:h-53 md:h-54 md:h-55 md:h-56 md:h-57 md:h-58 md:h-59 md:h-60 md:h-61 md:h-62 md:h-63 md:h-64 md:h-65 md:h-66 md:h-67 md:h-68 md:h-69 md:h-70 md:h-71 md:h-72 md:h-73 md:h-74 md:h-75 md:h-76 md:h-77 md:h-78 md:h-79 md:h-80 md:h-81 md:h-82 md:h-83 md:h-84 md:h-85 md:h-86 md:h-87 md:h-88 md:h-89 md:h-90 md:h-91 md:h-92 md:h-93 md:h-94 md:h-95 md:h-96",
"lg:h-0 lg:h-1 lg:h-2 lg:h-3 lg:h-4 lg:h-5 lg:h-6 lg:h-7 lg:h-8 lg:h-9 lg:h-10 lg:h-11 lg:h-12 lg:h-13 lg:h-14 lg:h-15 lg:h-16 lg:h-17 lg:h-18 lg:h-19 lg:h-20 lg:h-21 lg:h-22 lg:h-23 lg:h-24 lg:h-25 lg:h-26 lg:h-27 lg:h-28 lg:h-29 lg:h-30 lg:h-31 lg:h-32 lg:h-33 lg:h-34 lg:h-35 lg:h-36 lg:h-37 lg:h-38 lg:h-39 lg:h-40 lg:h-41 lg:h-42 lg:h-43 lg:h-44 lg:h-45 lg:h-46 lg:h-47 lg:h-48 lg:h-49 lg:h-50 lg:h-51 lg:h-52 lg:h-53 lg:h-54 lg:h-55 lg:h-56 lg:h-57 lg:h-58 lg:h-59 lg:h-60 lg:h-61 lg:h-62 lg:h-63 lg:h-64 lg:h-65 lg:h-66 lg:h-67 lg:h-68 lg:h-69 lg:h-70 lg:h-71 lg:h-72 lg:h-73 lg:h-74 lg:h-75 lg:h-76 lg:h-77 lg:h-78 lg:h-79 lg:h-80 lg:h-81 lg:h-82 lg:h-83 lg:h-84 lg:h-85 lg:h-86 lg:h-87 lg:h-88 lg:h-89 lg:h-90 lg:h-91 lg:h-92 lg:h-93 lg:h-94 lg:h-95 lg:h-96",
"xl:h-0 xl:h-1 xl:h-2 xl:h-3 xl:h-4 xl:h-5 xl:h-6 xl:h-7 xl:h-8 xl:h-9 xl:h-10 xl:h-11 xl:h-12 xl:h-13 xl:h-14 xl:h-15 xl:h-16 xl:h-17 xl:h-18 xl:h-19 xl:h-20 xl:h-21 xl:h-22 xl:h-23 xl:h-24 xl:h-25 xl:h-26 xl:h-27 xl:h-28 xl:h-29 xl:h-30 xl:h-31 xl:h-32 xl:h-33 xl:h-34 xl:h-35 xl:h-36 xl:h-37 xl:h-38 xl:h-39 xl:h-40 xl:h-41 xl:h-42 xl:h-43 xl:h-44 xl:h-45 xl:h-46 xl:h-47 xl:h-48 xl:h-49 xl:h-50 xl:h-51 xl:h-52 xl:h-53 xl:h-54 xl:h-55 xl:h-56 xl:h-57 xl:h-58 xl:h-59 xl:h-60 xl:h-61 xl:h-62 xl:h-63 xl:h-64 xl:h-65 xl:h-66 xl:h-67 xl:h-68 xl:h-69 xl:h-70 xl:h-71 xl:h-72 xl:h-73 xl:h-74 xl:h-75 xl:h-76 xl:h-77 xl:h-78 xl:h-79 xl:h-80 xl:h-81 xl:h-82 xl:h-83 xl:h-84 xl:h-85 xl:h-86 xl:h-87 xl:h-88 xl:h-89 xl:h-90 xl:h-91 xl:h-92 xl:h-93 xl:h-94 xl:h-95 xl:h-96",
"2xl:h-0 2xl:h-1 2xl:h-2 2xl:h-3 2xl:h-4 2xl:h-5 2xl:h-6 2xl:h-7 2xl:h-8 2xl:h-9 2xl:h-10 2xl:h-11 2xl:h-12 2xl:h-13 2xl:h-14 2xl:h-15 2xl:h-16 2xl:h-17 2xl:h-18 2xl:h-19 2xl:h-20 2xl:h-21 2xl:h-22 2xl:h-23 2xl:h-24 2xl:h-25 2xl:h-26 2xl:h-27 2xl:h-28 2xl:h-29 2xl:h-30 2xl:h-31 2xl:h-32 2xl:h-33 2xl:h-34 2xl:h-35 2xl:h-36 2xl:h-37 2xl:h-38 2xl:h-39 2xl:h-40 2xl:h-41 2xl:h-42 2xl:h-43 2xl:h-44 2xl:h-45 2xl:h-46 2xl:h-47 2xl:h-48 2xl:h-49 2xl:h-50 2xl:h-51 2xl:h-52 2xl:h-53 2xl:h-54 2xl:h-55 2xl:h-56 2xl:h-57 2xl:h-58 2xl:h-59 2xl:h-60 2xl:h-61 2xl:h-62 2xl:h-63 2xl:h-64 2xl:h-65 2xl:h-66 2xl:h-67 2xl:h-68 2xl:h-69 2xl:h-70 2xl:h-71 2xl:h-72 2xl:h-73 2xl:h-74 2xl:h-75 2xl:h-76 2xl:h-77 2xl:h-78 2xl:h-79 2xl:h-80 2xl:h-81 2xl:h-82 2xl:h-83 2xl:h-84 2xl:h-85 2xl:h-86 2xl:h-87 2xl:h-88 2xl:h-89 2xl:h-90 2xl:h-91 2xl:h-92 2xl:h-93 2xl:h-94 2xl:h-95 2xl:h-96",
];
function MyApp({ Component, pageProps }) {
return (
<SWRConfig

View File

@@ -71,8 +71,8 @@ export default async function handler(req, res) {
let depMem = 0;
let depCpu = 0;
const podMetrics = await metricsApi
.getPodMetrics(namespace, pod.metadata.name)
.then((response) => response)
.getPodMetrics(namespace, pod.items)
.then((response) => response.items)
.catch((err) => {
// 404 generally means that the metrics have not been populated yet
if (err.statusCode !== 404) {
@@ -81,9 +81,11 @@ export default async function handler(req, res) {
return null;
});
if (podMetrics) {
podMetrics.containers.forEach((container) => {
depMem += parseMemory(container.usage.memory);
depCpu += parseCpu(container.usage.cpu);
podMetrics.forEach((metrics) => {
metrics.containers.forEach((container) => {
depMem += parseMemory(container.usage.memory);
depCpu += parseCpu(container.usage.cpu);
});
});
}
return {

View File

@@ -1,5 +1,6 @@
import { searchProviders } from "components/widgets/search/search";
import { getSettings } from "utils/config/config";
import cachedFetch from "utils/proxy/cached-fetch";
import { widgetsFromConfig } from "utils/config/widget-helpers";
@@ -12,8 +13,16 @@ export default async function handler(req, res) {
const widgets = await widgetsFromConfig();
const searchWidget = widgets.find((w) => w.type === "search");
provider.url = searchWidget.options.url;
provider.suggestionUrl = searchWidget.options.suggestionUrl;
if (searchWidget) {
provider.url = searchWidget.options.url;
provider.suggestionUrl = searchWidget.options.suggestionUrl;
} else {
const settings = getSettings();
if (settings.quicklaunch && settings.quicklaunch.provider === "custom") {
provider.url = settings.quicklaunch.url;
provider.suggestionUrl = settings.quicklaunch.suggestionUrl;
}
}
}
if (!provider.suggestionUrl) {

View File

@@ -8,7 +8,7 @@ const kc = getKubeConfig();
export default async function listIngress() {
const networking = kc.makeApiClient(NetworkingV1Api);
const { ingress } = getKubernetes();
const { ingress = true } = getKubernetes();
let ingressList = [];
if (ingress) {

View File

@@ -35,8 +35,8 @@ function generateStreamTitle(session, enableUser, showEpisodeNumber) {
let streamTitle = "";
if (Type === "Episode" && showEpisodeNumber) {
const seasonStr = `S${ParentIndexNumber.toString().padStart(2, "0")}`;
const episodeStr = `E${IndexNumber.toString().padStart(2, "0")}`;
const seasonStr = ParentIndexNumber ? `S${ParentIndexNumber.toString().padStart(2, "0")}` : "";
const episodeStr = IndexNumber ? `E${IndexNumber.toString().padStart(2, "0")}` : "";
streamTitle = `${SeriesName}: ${seasonStr} · ${episodeStr} - ${Name}`;
} else {
streamTitle = `${Name}${SeriesName ? ` - ${SeriesName}` : ""}`;

View File

@@ -14,7 +14,11 @@ async function login(widget, service) {
const endpoint = "Account/login";
const api = widgets?.[widget.type]?.api;
const loginUrl = new URL(formatApiCall(api, { endpoint, ...widget }));
const loginBody = {};
const loginBody = {
username: "",
password: "",
apiKey: "",
};
if (widget.username && widget.password) {
loginBody.username = widget.username;
loginBody.password = widget.password;

View File

@@ -36,14 +36,14 @@ export default function Component({ service }) {
<Block
label="speedtest.download"
value={t("common.bitrate", {
value: speedtestData.data.download * 1000 * 1000,
value: widget.version === 2 ? speedtestData.data.download * 8 : speedtestData.data.download * 1000 * 1000,
decimals: bitratePrecision,
})}
/>
<Block
label="speedtest.upload"
value={t("common.bitrate", {
value: speedtestData.data.upload * 1000 * 1000,
value: widget.version === 2 ? speedtestData.data.upload * 8 : speedtestData.data.upload * 1000 * 1000,
decimals: bitratePrecision,
})}
/>

View File

@@ -33,48 +33,4 @@ module.exports = {
},
},
plugins: [tailwindForms, tailwindScrollbars],
// always include these in build as classes are dynamically constructed
safelist: [
"backdrop-blur",
"backdrop-blur-sm",
"backdrop-blur-md",
"backdrop-blur-xl",
"backdrop-saturate-0",
"backdrop-saturate-50",
"backdrop-saturate-100",
"backdrop-saturate-150",
"backdrop-saturate-200",
"backdrop-brightness-0",
"backdrop-brightness-50",
"backdrop-brightness-75",
"backdrop-brightness-90",
"backdrop-brightness-95",
"backdrop-brightness-100",
"backdrop-brightness-105",
"backdrop-brightness-110",
"backdrop-brightness-125",
"backdrop-brightness-150",
"backdrop-brightness-200",
"grid-cols-1",
"md:grid-cols-1",
"md:grid-cols-2",
"lg:grid-cols-1",
"lg:grid-cols-2",
"lg:grid-cols-3",
"lg:grid-cols-4",
"lg:grid-cols-5",
"lg:grid-cols-6",
"lg:grid-cols-7",
"lg:grid-cols-8",
// for status
"bg-white",
"bg-black",
"dark:bg-white",
"bg-orange-400",
"dark:bg-orange-400",
{
pattern: /h-([0-96])/,
variants: ["sm", "md", "lg", "xl", "2xl"],
},
],
};