mirror of
https://github.com/gethomepage/homepage.git
synced 2026-10-15 15:09:56 -07:00
Compare commits
2
Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
a22dad3d67 | ||
|
|
11ca29104a |
@@ -55,6 +55,7 @@ export default async function credentialedProxyHandler(req, res, map) {
|
|||||||
"authentik",
|
"authentik",
|
||||||
"cloudflared",
|
"cloudflared",
|
||||||
"ghostfolio",
|
"ghostfolio",
|
||||||
|
"gitea",
|
||||||
"headscale",
|
"headscale",
|
||||||
"hoarder",
|
"hoarder",
|
||||||
"karakeep",
|
"karakeep",
|
||||||
@@ -143,7 +144,7 @@ export default async function credentialedProxyHandler(req, res, map) {
|
|||||||
headers["X-API-Key"] = `${widget.key}`;
|
headers["X-API-Key"] = `${widget.key}`;
|
||||||
}
|
}
|
||||||
|
|
||||||
const [status, contentType, data] = await httpProxy(url, {
|
const [status, contentType, data, responseHeaders] = await httpProxy(url, {
|
||||||
method: req.method,
|
method: req.method,
|
||||||
withCredentials: true,
|
withCredentials: true,
|
||||||
credentials: "include",
|
credentials: "include",
|
||||||
@@ -178,7 +179,7 @@ export default async function credentialedProxyHandler(req, res, map) {
|
|||||||
.status(500)
|
.status(500)
|
||||||
.json({ error: { message: "Invalid data", url: sanitizeErrorURL(url), data: resultData } });
|
.json({ error: { message: "Invalid data", url: sanitizeErrorURL(url), data: resultData } });
|
||||||
}
|
}
|
||||||
if (map) resultData = map(resultData);
|
if (map) resultData = map(resultData, responseHeaders);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (contentType) res.setHeader("Content-Type", contentType);
|
if (contentType) res.setHeader("Content-Type", contentType);
|
||||||
|
|||||||
@@ -45,6 +45,7 @@ vi.mock("widgets/widgets", () => ({
|
|||||||
autobrr: { api: "{url}/{endpoint}" },
|
autobrr: { api: "{url}/{endpoint}" },
|
||||||
jellystat: { api: "{url}/{endpoint}" },
|
jellystat: { api: "{url}/{endpoint}" },
|
||||||
trilium: { api: "{url}/{endpoint}" },
|
trilium: { api: "{url}/{endpoint}" },
|
||||||
|
gitea: { api: "{url}/api/v1/{endpoint}" },
|
||||||
gitlab: { api: "{url}/{endpoint}" },
|
gitlab: { api: "{url}/{endpoint}" },
|
||||||
azuredevops: { api: "{url}/{endpoint}" },
|
azuredevops: { api: "{url}/{endpoint}" },
|
||||||
glances: { api: "{url}/{endpoint}" },
|
glances: { api: "{url}/{endpoint}" },
|
||||||
@@ -135,6 +136,33 @@ describe("utils/proxy/handlers/credentialed", () => {
|
|||||||
expect(res.body).toEqual({ ok: true });
|
expect(res.body).toEqual({ ok: true });
|
||||||
});
|
});
|
||||||
|
|
||||||
|
it("uses Bearer auth for gitea widgets and keeps the key out of the URL", async () => {
|
||||||
|
getServiceWidget.mockResolvedValue({ type: "gitea", url: "http://example", key: "token" });
|
||||||
|
httpProxy.mockResolvedValue([200, "application/json", []]);
|
||||||
|
|
||||||
|
const req = { method: "GET", query: { group: "g", service: "s", endpoint: "notifications?limit=1", index: 0 } };
|
||||||
|
const res = createMockRes();
|
||||||
|
|
||||||
|
await credentialedProxyHandler(req, res);
|
||||||
|
|
||||||
|
const [url, params] = httpProxy.mock.calls[0];
|
||||||
|
expect(params.headers.Authorization).toBe("Bearer token");
|
||||||
|
expect(url.toString()).toBe("http://example/api/v1/notifications?limit=1");
|
||||||
|
});
|
||||||
|
|
||||||
|
it("passes response headers to the mapping function", async () => {
|
||||||
|
getServiceWidget.mockResolvedValue({ type: "gitea", url: "http://example", key: "token" });
|
||||||
|
httpProxy.mockResolvedValue([200, "application/json", [], { "x-total-count": "7" }]);
|
||||||
|
|
||||||
|
const req = { method: "GET", query: { group: "g", service: "s", endpoint: "notifications?limit=1", index: 0 } };
|
||||||
|
const res = createMockRes();
|
||||||
|
|
||||||
|
await credentialedProxyHandler(req, res, (data, headers) => ({ count: Number(headers["x-total-count"]) }));
|
||||||
|
|
||||||
|
expect(res.statusCode).toBe(200);
|
||||||
|
expect(res.body).toEqual({ count: 7 });
|
||||||
|
});
|
||||||
|
|
||||||
it("uses NC-Token auth for nextcloud widgets when key is provided", async () => {
|
it("uses NC-Token auth for nextcloud widgets when key is provided", async () => {
|
||||||
getServiceWidget.mockResolvedValue({ type: "nextcloud", url: "http://example", key: "nc-token" });
|
getServiceWidget.mockResolvedValue({ type: "nextcloud", url: "http://example", key: "nc-token" });
|
||||||
httpProxy.mockResolvedValue([200, "application/json", { ok: true }]);
|
httpProxy.mockResolvedValue([200, "application/json", { ok: true }]);
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
import genericProxyHandler from "utils/proxy/handlers/generic";
|
import credentialedProxyHandler from "utils/proxy/handlers/credentialed";
|
||||||
|
|
||||||
// Get total from header to avoid pagination limit
|
// Get total from header to avoid pagination limit
|
||||||
export function totalCount(data, headers) {
|
export function totalCount(data, headers) {
|
||||||
@@ -7,8 +7,8 @@ export function totalCount(data, headers) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
const widget = {
|
const widget = {
|
||||||
api: "{url}/api/v1/{endpoint}?access_token={key}",
|
api: "{url}/api/v1/{endpoint}",
|
||||||
proxyHandler: genericProxyHandler,
|
proxyHandler: credentialedProxyHandler,
|
||||||
|
|
||||||
mappings: {
|
mappings: {
|
||||||
notifications: {
|
notifications: {
|
||||||
|
|||||||
Reference in New Issue
Block a user