Merge branch 'dev' into feature/mcp
Docker CI / Docker Build & Push (push) Has been cancelled
Lint / Linting Checks (push) Has been cancelled
Tests / vitest (1) (push) Has been cancelled
Tests / vitest (2) (push) Has been cancelled
Tests / vitest (3) (push) Has been cancelled
Tests / vitest (4) (push) Has been cancelled

This commit is contained in:
shamoon
2026-06-15 13:34:44 -07:00
committed by GitHub
6 changed files with 19 additions and 5 deletions
+1 -1
View File
@@ -66,7 +66,7 @@ For configuration options, examples and more, [please check out the homepage doc
Please note that when using features such as widgets, Homepage can access personal information (for example from your home automation system). To keep your information private, if Homepage is reachable from any untrusted network, it:
1. **must** sit behind a reverse proxy (and/or VPN) that enforces authentication, TLS, and strictly validates Host headers.
2. An optional built-in OIDC login flow is available (opt-in) offering a simple “authenticated or not” guard.
2. An optional built-in OIDC login flow or simple password login is available (opt-in) offering a simple “authenticated or not” guard.
## With Docker
+3 -1
View File
@@ -60,4 +60,6 @@ For OIDC login (overrides password login):
- `HOMEPAGE_EXTERNAL_URL` (external URL to your Homepage instance; used for callbacks)
- Optional: `HOMEPAGE_OIDC_NAME` (display name), `HOMEPAGE_OIDC_SCOPE` (defaults to `openid email profile`)
All app pages and `/api` routes will require a signed-in session. Static assets remain public. Homepage still does not implement per-user dashboards or roles; authentication is a simple gate only.
All app pages and `/api` routes except `/api/healthcheck` will require a signed-in session. Static assets remain public.
Configure your OIDC provider with the a callback URI like `https://homepage.example.com/api/auth/callback/homepage-oidc`.
+2
View File
@@ -16,3 +16,5 @@ widget:
key: your-api-key
fields: ["running", "stopped", "total", "image_updates"] # optional
```
Using an api key for the widget requires permissions for: `containers:list` `images:list and `image-updates:read`
+1 -1
View File
@@ -27,7 +27,7 @@ export async function middleware(req) {
return NextResponse.json({ error: "Host validation failed. See logs for more details." }, { status: 400 });
}
if (authEnabled) {
if (authEnabled && !new URL(req.url).pathname.startsWith("/api/healthcheck")) {
if (new URL(req.url).pathname === "/api/mcp" && hasMcpToken(req)) {
return NextResponse.next();
}
+12
View File
@@ -88,6 +88,18 @@ describe("middleware", () => {
expect(res).toEqual({ type: "next" });
});
it("allows healthcheck requests without auth when host is allowed", async () => {
process.env.HOMEPAGE_AUTH_ENABLED = "true";
process.env.HOMEPAGE_AUTH_SECRET = "secret";
const middleware = await loadMiddleware();
const res = await middleware(createReq("localhost:3000", "http://localhost:3000/api/healthcheck"));
expect(getToken).not.toHaveBeenCalled();
expect(NextResponse.next).toHaveBeenCalled();
expect(res).toEqual({ type: "next" });
});
it("redirects to signin when auth is enabled and no token is present", async () => {
process.env.HOMEPAGE_AUTH_ENABLED = "true";
process.env.HOMEPAGE_AUTH_SECRET = "secret";
-2
View File
@@ -128,8 +128,6 @@ export default function SignIn({ providers, settings }) {
backgroundBrightness && `backdrop-brightness-${settings.background.brightness}`,
)}
>
<div className="pointer-events-none absolute -left-24 -top-20 h-64 w-64 rounded-full bg-theme-500/20 blur-3xl" />
<div className="pointer-events-none absolute -bottom-24 right-0 h-72 w-72 rounded-full bg-theme-500/10 blur-3xl" />
<div className="grid gap-10 px-8 py-12 md:grid-cols-[1.2fr_1fr] md:px-12">
<section className="flex flex-col justify-between">
<div>