feat(widget): add restriction callback to restrict visibility and modification of widget kinds (#2658)

* feat(widget): add restriction callback to restrict visibility and modification of widget kinds

* fix: typecheck issue

* chore: address pull request feedback
This commit is contained in:
Meier Lukas
2025-03-28 10:16:46 +01:00
committed by GitHub
parent 78b55202e7
commit 84f73d33a0
16 changed files with 292 additions and 253 deletions

View File

@@ -1,9 +1,12 @@
import type { Session } from "@homarr/auth";
import { isWidgetRestricted } from "@homarr/auth/shared";
import { createId } from "@homarr/db";
import { createDbInsertCollectionForTransaction } from "@homarr/db/collection";
import { logger } from "@homarr/log";
import type { BoardSize } from "@homarr/old-schema";
import { boardSizes, getBoardSizeName } from "@homarr/old-schema";
import { widgetImports } from "../../../../widgets/src";
import { fixSectionIssues } from "../../fix-section-issues";
import { mapBoard } from "../../mappers/map-board";
import { mapBreakpoint } from "../../mappers/map-breakpoint";
@@ -17,6 +20,7 @@ import type { InitialOldmarrImportSettings } from "../../settings";
export const createBoardInsertCollection = (
{ preparedApps, preparedBoards }: Omit<ReturnType<typeof prepareMultipleImports>, "preparedIntegrations">,
settings: InitialOldmarrImportSettings,
session: Session | null,
) => {
const insertCollection = createDbInsertCollectionForTransaction([
"apps",
@@ -105,10 +109,18 @@ export const createBoardInsertCollection = (
layoutMapping,
mappedBoard.id,
);
preparedItems.forEach(({ layouts, ...item }) => {
insertCollection.items.push(item);
insertCollection.itemLayouts.push(...layouts);
});
preparedItems
.filter((item) => {
return !isWidgetRestricted({
definition: widgetImports[item.kind].definition,
user: session?.user ?? null,
check: (level) => level !== "none",
});
})
.forEach(({ layouts, ...item }) => {
insertCollection.items.push(item);
insertCollection.itemLayouts.push(...layouts);
});
logger.debug(`Added items to board insert collection count=${insertCollection.items.length}`);
});

View File

@@ -1,5 +1,6 @@
import type { z } from "zod";
import type { Session } from "@homarr/auth";
import { Stopwatch } from "@homarr/common";
import { handleTransactionsAsync } from "@homarr/db";
import type { Database } from "@homarr/db";
@@ -16,6 +17,7 @@ import { ensureValidTokenOrThrow } from "./validate-token";
export const importInitialOldmarrAsync = async (
db: Database,
input: z.infer<typeof importInitialOldmarrInputSchema>,
session: Session | null,
) => {
const stopwatch = new Stopwatch();
const { checksum, configs, users: importUsers } = await analyseOldmarrImportAsync(input.file);
@@ -29,7 +31,7 @@ export const importInitialOldmarrAsync = async (
logger.info("Preparing import data in insert collections for database");
const boardInsertCollection = createBoardInsertCollection({ preparedApps, preparedBoards }, input.settings);
const boardInsertCollection = createBoardInsertCollection({ preparedApps, preparedBoards }, input.settings, session);
const userInsertCollection = createUserInsertCollection(importUsers, input.token);
const integrationInsertCollection = createIntegrationInsertCollection(preparedIntegrations, input.token);

View File

@@ -1,3 +1,4 @@
import type { Session } from "@homarr/auth";
import { handleTransactionsAsync, inArray } from "@homarr/db";
import type { Database } from "@homarr/db";
import { apps } from "@homarr/db/schema";
@@ -12,6 +13,7 @@ export const importSingleOldmarrConfigAsync = async (
db: Database,
config: OldmarrConfig,
settings: OldmarrImportConfiguration,
session: Session | null,
) => {
const { preparedApps, preparedBoards } = prepareSingleImport(config, settings);
const existingApps = await db.query.apps.findMany({
@@ -29,7 +31,7 @@ export const importSingleOldmarrConfigAsync = async (
return app;
});
const boardInsertCollection = createBoardInsertCollection({ preparedApps, preparedBoards }, settings);
const boardInsertCollection = createBoardInsertCollection({ preparedApps, preparedBoards }, settings, session);
await handleTransactionsAsync(db, {
async handleAsync(db) {