Tweak: whitelist custom.css from auth (#6986)

This commit is contained in:
shamoon
2026-08-14 23:52:46 -07:00
committed by GitHub
parent 58dadddb53
commit 27704f962e
4 changed files with 32 additions and 2 deletions
+4
View File
@@ -7,6 +7,10 @@ As of version v0.6.30 homepage supports adding your own custom css & javascript.
To add custom css simply edit the `custom.css` file under your config directory, similarly for javascript you would edit `custom.js`. You can then target elements in homepage with various classes / ids to customize things to your liking.
!!! warning
When Homepage authentication is enabled, `custom.css` remains publicly accessible so it can style the sign-in page. Do not include secrets or sensitive internal URLs in this file. `custom.js` remains protected and is only loaded after authentication.
You can also set a specific `id` for a service or bookmark to target with your custom css or javascript, e.g.
```yaml
+1 -1
View File
@@ -74,6 +74,6 @@ For OIDC login (overrides password login):
Homepage grants access to any identity that the configured OIDC provider authorizes for this client. Configure client assignments, groups, or access policies at the identity provider. Homepage does not apply additional claim-based authorization.
All app pages and `/api` routes except `/api/healthcheck` will require a signed-in session. Static assets remain public.
All app pages and `/api` routes except `/api/healthcheck` and `/api/config/custom.css` 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 -1
View File
@@ -33,7 +33,8 @@ export async function middleware(req) {
}
const pathname = new URL(req.url).pathname;
if (authEnabled && !pathname.startsWith("/api/healthcheck")) {
const isPublicAuthPath = pathname.startsWith("/api/healthcheck") || pathname === "/api/config/custom.css";
if (authEnabled && !isPublicAuthPath) {
// The MCP API handler authorizes both bearer tokens and Homepage sessions.
if (pathname === "/api/mcp") {
return withPrivateCache(NextResponse.next());
+25
View File
@@ -100,6 +100,31 @@ describe("middleware", () => {
expect(res.type).toBe("next");
});
it("allows custom CSS without auth so it can style the signin page", 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/config/custom.css"));
expect(getToken).not.toHaveBeenCalled();
expect(NextResponse.next).toHaveBeenCalled();
expect(res.type).toBe("next");
});
it("continues to require auth for custom JavaScript", async () => {
process.env.HOMEPAGE_AUTH_ENABLED = "true";
process.env.HOMEPAGE_AUTH_SECRET = "secret";
getToken.mockResolvedValueOnce(null);
const middleware = await loadMiddleware();
const res = await middleware(createReq("localhost:3000", "http://localhost:3000/api/config/custom.js"));
expect(getToken).toHaveBeenCalled();
expect(res.type).toBe("redirect");
});
it.each(["false", "0", "no", "off", ""])("treats HOMEPAGE_AUTH_ENABLED=%j as disabled", async (value) => {
process.env.HOMEPAGE_AUTH_ENABLED = value;