Skip to content

Commit

Permalink
fix: two issues with board rename and iframes (#2215)
Browse files Browse the repository at this point in the history
  • Loading branch information
Meierschlumpf authored Dec 7, 2024
1 parent b59921b commit 31a7559
Show file tree
Hide file tree
Showing 4 changed files with 48 additions and 30 deletions.
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "homarr",
"version": "0.15.7",
"version": "0.15.8",
"description": "Homarr - A homepage for your server.",
"license": "MIT",
"repository": {
Expand Down
64 changes: 37 additions & 27 deletions src/server/api/routers/board.ts
Original file line number Diff line number Diff line change
@@ -1,29 +1,33 @@
import { TRPCError } from '@trpc/server';
import Consola from 'consola';
import fs from 'fs';
import { z } from 'zod';
import Consola from 'consola';
import { getDefaultBoardAsync } from '~/server/db/queries/userSettings';
import { configExists } from '~/tools/config/configExists';
import { getConfig } from '~/tools/config/getConfig';
import { getFrontendConfig } from '~/tools/config/getFrontendConfig';
import { writeConfig } from '~/tools/config/writeConfig';
import { generateDefaultApp } from '~/tools/shared/app';
import { configNameSchema } from '~/validations/boards';

import { adminProcedure, createTRPCRouter, protectedProcedure } from '../trpc';
import { writeConfig } from '~/tools/config/writeConfig';
import { configNameSchema } from '~/validations/boards';

export const boardRouter = createTRPCRouter({
all: protectedProcedure
.meta({ openapi: { method: 'GET', path: '/boards/all', tags: ['board'] } })
.input(z.void())
.output(z.array(z.object({
name: z.string(),
allowGuests: z.boolean(),
countApps: z.number().min(0),
countWidgets: z.number().min(0),
countCategories: z.number().min(0),
isDefaultForUser: z.boolean(),
})))
.output(
z.array(
z.object({
name: z.string(),
allowGuests: z.boolean(),
countApps: z.number().min(0),
countWidgets: z.number().min(0),
countCategories: z.number().min(0),
isDefaultForUser: z.boolean(),
})
)
)
.query(async ({ ctx }) => {
const files = fs.readdirSync('./data/configs').filter((file) => file.endsWith('.json'));

Expand All @@ -44,7 +48,7 @@ export const boardRouter = createTRPCRouter({
countCategories: config.categories.length,
isDefaultForUser: name === defaultBoard,
};
}),
})
);
}),
addAppsForContainers: adminProcedure
Expand All @@ -58,9 +62,9 @@ export const boardRouter = createTRPCRouter({
name: z.string(),
icon: z.string().optional(),
port: z.number().optional(),
}),
})
),
}),
})
)
.mutation(async ({ input }) => {
if (!configExists(input.boardName)) {
Expand Down Expand Up @@ -101,12 +105,14 @@ export const boardRouter = createTRPCRouter({
const targetPath = `data/configs/${input.boardName}.json`;
fs.writeFileSync(targetPath, JSON.stringify(newConfig, null, 2), 'utf8');
}),
renameBoard: protectedProcedure
renameBoard: adminProcedure
.meta({ openapi: { method: 'PUT', path: '/boards/rename', tags: ['board'] } })
.input(z.object({
oldName: z.string(),
newName: z.string().min(1),
}))
.input(
z.object({
oldName: configNameSchema,
newName: configNameSchema,
})
)
.output(z.void())
.mutation(async ({ input }) => {
if (input.oldName === 'default') {
Expand Down Expand Up @@ -141,15 +147,19 @@ export const boardRouter = createTRPCRouter({
fs.unlinkSync(targetPath);
Consola.info(`Deleted ${input.oldName} from file system`);
}),
duplicateBoard: protectedProcedure
duplicateBoard: adminProcedure
.meta({ openapi: { method: 'POST', path: '/boards/duplicate', tags: ['board'] } })
.input(z.object({
boardName: z.string(),
}))
.input(
z.object({
boardName: z.string(),
})
)
.output(z.void())
.mutation(async ({ input }) => {
if (!configExists(input.boardName)) {
Consola.error(`Tried to duplicate ${input.boardName} but this configuration does not exist.`);
Consola.error(
`Tried to duplicate ${input.boardName} but this configuration does not exist.`
);
throw new TRPCError({
code: 'NOT_FOUND',
message: 'Board not found',
Expand All @@ -164,7 +174,7 @@ export const boardRouter = createTRPCRouter({
config.configProperties.name = targetName;
writeConfig(config);

Consola.info(`Wrote config to name '${targetName}'`)
Consola.info(`Wrote config to name '${targetName}'`);
}),
});

Expand All @@ -185,7 +195,7 @@ const attemptGenerateDuplicateName = (baseName: string, maxAttempts: number) =>
code: 'CONFLICT',
message: 'Board conflicts with an existing board',
});
}
};

const generateDuplicateName = (baseName: string, increment: number) => {
const result = duplicationName.exec(baseName);
Expand All @@ -197,4 +207,4 @@ const generateDuplicateName = (baseName: string, increment: number) => {
}

return `${baseName} (2)`;
}
};
11 changes: 9 additions & 2 deletions src/validations/boards.ts
Original file line number Diff line number Diff line change
@@ -1,8 +1,15 @@
import { DEFAULT_THEME, MANTINE_COLORS, MantineColor } from '@mantine/core';
import { z } from 'zod';
import { BackgroundImageAttachment, BackgroundImageRepeat, BackgroundImageSize } from '~/types/settings';
import {
BackgroundImageAttachment,
BackgroundImageRepeat,
BackgroundImageSize,
} from '~/types/settings';

export const configNameSchema = z.string().regex(/^[a-zA-Z0-9-_\s()]+$/);
export const configNameSchema = z
.string()
.regex(/^[a-zA-Z0-9-_\s()]+$/)
.min(1);

export const createBoardSchemaValidation = z.object({
name: configNameSchema,
Expand Down
1 change: 1 addition & 0 deletions src/widgets/iframe/IFrameTile.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -116,6 +116,7 @@ function IFrameTile({ widget }: IFrameTileProps) {
return (
<Container h="100%" w="100%" maw="initial" mah="initial" p={0}>
<iframe
sandbox="" // Disables js execution see https://developer.mozilla.org/en-US/docs/Web/HTML/Element/iframe#sandbox
className={classes.iframe}
src={widget.properties.embedUrl}
title="widget iframe"
Expand Down

0 comments on commit 31a7559

Please sign in to comment.