fix(custom-widgets): require explicit request bindings

This commit is contained in:
Thomas Camlong committed 2026-07-20 17:02:59 +02:00
1 parent 4c69ad90df
commit a26846fa31
23 files changed
+363 -52

No files matched your search

@@ -107,7 +107,7 @@ export const managementQueryProcedures = {
),
optionRequests: widget.requests
.filter((request) => request.kind === "query")
.map(({ id, parameters }) => ({ id, parameters })),
.map(({ id, parameters, optionsBinding }) => ({ id, parameters, optionsBinding })),
updatedAt: definition.updatedAt,
};
});
@@ -89,13 +89,24 @@ export const previewBaseProcedures = {
optionsSchema: session.optionsSchema,
defaultOptions: session.defaultOptions,
requests: session.requests.map(
({ id, kind, method, minimumBoardPermission, trigger, parameters, confirmation, invalidates }) => ({
({
id,
kind,
method,
minimumBoardPermission,
trigger,
parameters,
optionsBinding,
confirmation,
invalidates,
}) => ({
id,
kind,
method,
minimumBoardPermission,
trigger,
parameters,
optionsBinding,
confirmation,
invalidates,
}),
@@ -1,6 +1,8 @@
import { TRPCError } from "@trpc/server";
import { z } from "zod/v4";
import { resolveCustomWidgetOptionsBinding } from "@homarr/custom-widgets/core";
import { permissionRequiredProcedure } from "../../trpc";
import {
getPreviewRequestSource,
@@ -31,8 +33,10 @@ export const previewQueryProcedures = {
if (!request) throw new TRPCError({ code: "NOT_FOUND", message: "Preview query was not found" });
const resolved = getPreviewRequestSource(session, request.sourceId);
if (!resolved) throw new TRPCError({ code: "NOT_FOUND", message: "Preview source was not found" });
const targetUrl = renderRequestTarget(resolved.source.baseUrl, request, input.params);
const body = renderRequestBody(request.bodyTemplate, input.params);
const params =
request.trigger === "load" ? resolveCustomWidgetOptionsBinding(request, session.defaultOptions) : input.params;
const targetUrl = renderRequestTarget(resolved.source.baseUrl, request, params);
const body = renderRequestBody(request.bodyTemplate, params);
const release = await acquireCustomWidgetRequestLimit({
category: "query",
userId: ctx.session.user.id,
@@ -50,7 +54,7 @@ export const previewQueryProcedures = {
auth: request.auth === "none" ? undefined : resolved.auth,
networkScope: resolved.source.networkScope,
kind: "query",
cacheKey: `custom-jsx:preview:${session.id}:${request.id}:${hashRuntimeParams(input.params)}`,
cacheKey: `custom-jsx:preview:${session.id}:${request.id}:${hashRuntimeParams(params)}`,
cacheTtlSeconds: request.cacheTtlSeconds,
});
await recordPreviewJournal(session, {