Merge branch 'dev'

This commit is contained in:
shamoon 2025-03-15 07:43:30 -07:00
commit 42af93bef3
No known key found for this signature in database
8 changed files with 23 additions and 11 deletions

View File

@ -56,12 +56,12 @@ COPY --link --chmod=755 docker-entrypoint.sh /usr/local/bin/
RUN apk add --no-cache su-exec RUN apk add --no-cache su-exec
ENV HOSTNAME=:: ENV HOSTNAME=0.0.0.0
ENV PORT=3000 ENV PORT=3000
EXPOSE $PORT EXPOSE $PORT
HEALTHCHECK --interval=10s --timeout=3s --start-period=20s \ 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"] ENTRYPOINT ["docker-entrypoint.sh"]
CMD ["node", "server.js"] CMD ["node", "server.js"]

View File

@ -29,4 +29,8 @@ You have a few options for deploying homepage, depending on your needs. We offer
### `HOMEPAGE_ALLOWED_HOSTS` ### `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 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 more information.
`localhost:3000` and `127.0.0.1:3000` are always allowed, but you can add a domain or IP address to this list to allow access from that host such as `HOMEPAGE_ALLOWED_HOSTS=gethomepage.dev,192.168.1.2:1234`, etc.
This can be disabled by setting `HOMEPAGE_ALLOWED_HOSTS` to `*` but this is not recommended.

View File

@ -223,6 +223,9 @@ spec:
- name: homepage - name: homepage
image: "ghcr.io/gethomepage/homepage:latest" image: "ghcr.io/gethomepage/homepage:latest"
imagePullPolicy: Always imagePullPolicy: Always
env:
- name: HOMEPAGE_ALLOWED_HOSTS
value: gethomepage.dev # required, may need port
ports: ports:
- name: http - name: http
containerPort: 3000 containerPort: 3000

View File

@ -22,7 +22,7 @@ export default function Item({ bookmark, iconOnly = false }) {
className={classNames( className={classNames(
settings.cardBlur !== undefined && `backdrop-blur${settings.cardBlur.length ? "-" : ""}${settings.cardBlur}`, 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", "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 h-full mb-3",
)} )}
> >
{iconOnly ? ( {iconOnly ? (

View File

@ -4,11 +4,12 @@ export function middleware(req) {
// Check the Host header, if HOMEPAGE_ALLOWED_HOSTS is set // Check the Host header, if HOMEPAGE_ALLOWED_HOSTS is set
const host = req.headers.get("host"); const host = req.headers.get("host");
const port = process.env.PORT || 3000; 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) { if (process.env.HOMEPAGE_ALLOWED_HOSTS) {
allowedHosts = allowedHosts.concat(process.env.HOMEPAGE_ALLOWED_HOSTS.split(",")); 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 // eslint-disable-next-line no-console
console.error( console.error(
`Host validation failed for: ${host}. Hint: Set the HOMEPAGE_ALLOWED_HOSTS environment variable to allow requests from this host / port.`, `Host validation failed for: ${host}. Hint: Set the HOMEPAGE_ALLOWED_HOSTS environment variable to allow requests from this host / port.`,

View File

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

View File

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

View File

@ -36,14 +36,14 @@ export default function Component({ service }) {
<Block <Block
label="speedtest.download" label="speedtest.download"
value={t("common.bitrate", { 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, decimals: bitratePrecision,
})} })}
/> />
<Block <Block
label="speedtest.upload" label="speedtest.upload"
value={t("common.bitrate", { 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, decimals: bitratePrecision,
})} })}
/> />