From 331ce510851aed6efcc2f32199fa810b3019a667 Mon Sep 17 00:00:00 2001 From: Tagaishi Date: Mon, 11 Sep 2023 02:57:32 +0200 Subject: [PATCH 001/141] =?UTF-8?q?=E2=9C=A8=20Removes=20trailing=20slashe?= =?UTF-8?q?s=20from=20URLs=20on=20save?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../Dashboard/Modals/EditAppModal/EditAppModal.tsx | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/src/components/Dashboard/Modals/EditAppModal/EditAppModal.tsx b/src/components/Dashboard/Modals/EditAppModal/EditAppModal.tsx index c447115d6..b8d19ae29 100644 --- a/src/components/Dashboard/Modals/EditAppModal/EditAppModal.tsx +++ b/src/components/Dashboard/Modals/EditAppModal/EditAppModal.tsx @@ -11,11 +11,12 @@ import { IconPlug, } from '@tabler/icons-react'; import { useTranslation } from 'next-i18next'; +import { removeTrailingSlash } from 'next/dist/shared/lib/router/utils/remove-trailing-slash'; import { useState } from 'react'; - import { useConfigContext } from '~/config/provider'; import { useConfigStore } from '~/config/store'; import { AppType } from '~/types/app'; + import { DebouncedImage } from '../../../IconSelector/DebouncedImage'; import { useEditModeStore } from '../../Views/useEditModeStore'; import { AppearanceTab } from './Tabs/AppereanceTab/AppereanceTab'; @@ -90,6 +91,9 @@ export const EditAppModal = ({ return; } + values.url = removeTrailingSlash(values.url); + values.behaviour.externalUrl = removeTrailingSlash(values.behaviour.externalUrl); + updateConfig( configName, (previousConfig) => ({ From 3c015d297b13d256149b351862cca98882562e75 Mon Sep 17 00:00:00 2001 From: Tagaishi Date: Mon, 11 Sep 2023 02:58:05 +0200 Subject: [PATCH 002/141] =?UTF-8?q?=E2=9C=A8=20Add=20common=20troubleshoot?= =?UTF-8?q?ing=20prompt=20on=20button?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- public/locales/en/layout/modals/add-app.json | 13 +++++- .../Tabs/GeneralTab/GeneralTab.tsx | 46 +++++++++++++++++-- 2 files changed, 54 insertions(+), 5 deletions(-) diff --git a/public/locales/en/layout/modals/add-app.json b/public/locales/en/layout/modals/add-app.json index afa4b7540..b9ecdd46b 100644 --- a/public/locales/en/layout/modals/add-app.json +++ b/public/locales/en/layout/modals/add-app.json @@ -13,7 +13,18 @@ }, "internalAddress": { "label": "Internal address", - "description": "Internal IP-address of the app." + "description": "Internal IP-address of the app.", + "troubleshoot": { + "label": "Common Troubleshooting", + "header": "This is a list of commonly made mistake and troubleshooting:", + "lines": { + "nothingAfterPort": "You should, in most if not all cases, not input anything after the port, even the '/admin' for pihole.", + "protocolCheck": "Always make sure that the URL is preceded by http or https, and to make sure you are using the right one.", + "iframe": "When it comes to iframes, those should always be using the same protocol (http/s) as Homarr.", + "clearCache": "Some informations are registered in cache, so an integration might not work unless you clear the cache in Homarr's general options." + }, + "footer": "For more troubleshooting, reach out on our {{discord}}." + } }, "externalAddress": { "label": "External address", diff --git a/src/components/Dashboard/Modals/EditAppModal/Tabs/GeneralTab/GeneralTab.tsx b/src/components/Dashboard/Modals/EditAppModal/Tabs/GeneralTab/GeneralTab.tsx index 16d8f6194..979cfc1ae 100644 --- a/src/components/Dashboard/Modals/EditAppModal/Tabs/GeneralTab/GeneralTab.tsx +++ b/src/components/Dashboard/Modals/EditAppModal/Tabs/GeneralTab/GeneralTab.tsx @@ -1,9 +1,10 @@ -import { Stack, Tabs, Text, TextInput } from '@mantine/core'; +import { Anchor, Button, Card, Collapse, Group, Stack, Tabs, Text, TextInput } from '@mantine/core'; import { UseFormReturnType } from '@mantine/form'; -import { IconClick, IconCursorText, IconLink } from '@tabler/icons-react'; +import { useDisclosure } from '@mantine/hooks'; +import { IconAlertCircle, IconClick, IconCursorText, IconLink } from '@tabler/icons-react'; import { useTranslation } from 'next-i18next'; - import { AppType } from '~/types/app'; + import { EditAppModalTab } from '../type'; interface GeneralTabProps { @@ -13,6 +14,16 @@ interface GeneralTabProps { export const GeneralTab = ({ form, openTab }: GeneralTabProps) => { const { t } = useTranslation('layout/modals/add-app'); + + const [opened, { toggle }] = useDisclosure(false); + + const commonMistakes = [ + t('general.internalAddress.troubleshoot.lines.nothingAfterPort'), + t('general.internalAddress.troubleshoot.lines.protocolCheck'), + t('general.internalAddress.troubleshoot.lines.iframe'), + t('general.internalAddress.troubleshoot.lines.clearCache'), + ]; + return ( @@ -46,12 +57,39 @@ export const GeneralTab = ({ form, openTab }: GeneralTabProps) => { {...form.getInputProps('behaviour.externalUrl')} /> + + + + + + + {t('general.internalAddress.troubleshoot.header')} + {commonMistakes.map((value: string, key: number) => { + return ( + + + {value} + + ); + })} + + {t('general.internalAddress.troubleshoot.footer').split('{{discord}}')[0]} + + Discord + + {t('general.internalAddress.troubleshoot.footer').split('{{discord}}')[1]} + + + + {!form.values.behaviour.externalUrl.startsWith('https://') && !form.values.behaviour.externalUrl.startsWith('http://') && ( {t('behaviour.customProtocolWarning')} - )} + )} ); From f3f4f23718ad06a2fb9564eda0e3a0350874f8c2 Mon Sep 17 00:00:00 2001 From: Manuel <30572287+manuel-rw@users.noreply.github.com> Date: Mon, 9 Oct 2023 21:29:41 +0200 Subject: [PATCH 003/141] =?UTF-8?q?=F0=9F=94=92=EF=B8=8F=20Fix=20tiptap=20?= =?UTF-8?q?url=20CVE=20(#1459)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/widgets/notebook/NotebookEditor.tsx | 13 ++++++++++--- 1 file changed, 10 insertions(+), 3 deletions(-) diff --git a/src/widgets/notebook/NotebookEditor.tsx b/src/widgets/notebook/NotebookEditor.tsx index ce71e9f13..4ec8ccb69 100644 --- a/src/widgets/notebook/NotebookEditor.tsx +++ b/src/widgets/notebook/NotebookEditor.tsx @@ -5,12 +5,12 @@ import { IconEdit, IconEditOff } from '@tabler/icons-react'; import { BubbleMenu, useEditor } from '@tiptap/react'; import StarterKit from '@tiptap/starter-kit'; import { useState } from 'react'; +import { useEditModeStore } from '~/components/Dashboard/Views/useEditModeStore'; +import { useConfigContext } from '~/config/provider'; import { useConfigStore } from '~/config/store'; import { useColorTheme } from '~/tools/color'; import { api } from '~/utils/api'; -import { useEditModeStore } from '~/components/Dashboard/Views/useEditModeStore'; -import { useConfigContext } from '~/config/provider'; import { WidgetLoading } from '../loading'; import { INotebookWidget } from './NotebookWidgetTile'; @@ -33,7 +33,14 @@ export function Editor({ widget }: { widget: INotebookWidget }) { const [debouncedContent] = useDebouncedValue(content, 500); const editor = useEditor({ - extensions: [StarterKit, Link], + extensions: [ + StarterKit, + Link.configure({ + validate(url) { + return /^https?:\/\//.test(url); + }, + }), + ], content, editable: false, onUpdate: (e) => { From 24024cc7f2539e292e1290048b763604ed29cbec Mon Sep 17 00:00:00 2001 From: Tagaishi Date: Thu, 12 Oct 2023 19:23:16 +0200 Subject: [PATCH 004/141] =?UTF-8?q?=F0=9F=8E=A8=20Added=20troubleshoot=20s?= =?UTF-8?q?teps=20+=20external=20address=20"/"?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- public/locales/en/layout/modals/add-app.json | 2 ++ src/components/Dashboard/Modals/EditAppModal/EditAppModal.tsx | 1 - .../Modals/EditAppModal/Tabs/GeneralTab/GeneralTab.tsx | 2 ++ 3 files changed, 4 insertions(+), 1 deletion(-) diff --git a/public/locales/en/layout/modals/add-app.json b/public/locales/en/layout/modals/add-app.json index b9ecdd46b..f975210f8 100644 --- a/public/locales/en/layout/modals/add-app.json +++ b/public/locales/en/layout/modals/add-app.json @@ -20,6 +20,8 @@ "lines": { "nothingAfterPort": "You should, in most if not all cases, not input anything after the port, even the '/admin' for pihole.", "protocolCheck": "Always make sure that the URL is preceded by http or https, and to make sure you are using the right one.", + "preferIP": "It is recommended to use the direct ip of the machine or container you are trying to communicate with.", + "wget": "To make sure that homarr can communicate with the other apps, make sure to wget/curl/ping the app's IP:port.", "iframe": "When it comes to iframes, those should always be using the same protocol (http/s) as Homarr.", "clearCache": "Some informations are registered in cache, so an integration might not work unless you clear the cache in Homarr's general options." }, diff --git a/src/components/Dashboard/Modals/EditAppModal/EditAppModal.tsx b/src/components/Dashboard/Modals/EditAppModal/EditAppModal.tsx index b8d19ae29..7ff6e3058 100644 --- a/src/components/Dashboard/Modals/EditAppModal/EditAppModal.tsx +++ b/src/components/Dashboard/Modals/EditAppModal/EditAppModal.tsx @@ -92,7 +92,6 @@ export const EditAppModal = ({ } values.url = removeTrailingSlash(values.url); - values.behaviour.externalUrl = removeTrailingSlash(values.behaviour.externalUrl); updateConfig( configName, diff --git a/src/components/Dashboard/Modals/EditAppModal/Tabs/GeneralTab/GeneralTab.tsx b/src/components/Dashboard/Modals/EditAppModal/Tabs/GeneralTab/GeneralTab.tsx index 979cfc1ae..aa6f56f85 100644 --- a/src/components/Dashboard/Modals/EditAppModal/Tabs/GeneralTab/GeneralTab.tsx +++ b/src/components/Dashboard/Modals/EditAppModal/Tabs/GeneralTab/GeneralTab.tsx @@ -20,6 +20,8 @@ export const GeneralTab = ({ form, openTab }: GeneralTabProps) => { const commonMistakes = [ t('general.internalAddress.troubleshoot.lines.nothingAfterPort'), t('general.internalAddress.troubleshoot.lines.protocolCheck'), + t('general.internalAddress.troubleshoot.lines.preferIP'), + t('general.internalAddress.troubleshoot.lines.wget'), t('general.internalAddress.troubleshoot.lines.iframe'), t('general.internalAddress.troubleshoot.lines.clearCache'), ]; From 62cb758db572fe61034de4026e8bc2700aaddc9f Mon Sep 17 00:00:00 2001 From: Tagaishi Date: Fri, 13 Oct 2023 21:55:39 +0200 Subject: [PATCH 005/141] =?UTF-8?q?=E2=9C=A8=20Adds=20support=20for=20post?= =?UTF-8?q?er=20on=20Radarr=20v5's=20api?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- public/locales/en/modules/calendar.json | 3 +++ src/modules/common/MediaDisplay.tsx | 7 ++++++- src/widgets/calendar/CalendarTile.tsx | 4 ++++ 3 files changed, 13 insertions(+), 1 deletion(-) diff --git a/public/locales/en/modules/calendar.json b/public/locales/en/modules/calendar.json index 454ab0390..239dc8054 100644 --- a/public/locales/en/modules/calendar.json +++ b/public/locales/en/modules/calendar.json @@ -7,6 +7,9 @@ "useSonarrv4": { "label": "Use Sonarr v4 API" }, + "useRadarrv5": { + "label": "Use Radarr v5 API" + }, "radarrReleaseType": { "label": "Radarr release type", "data":{ diff --git a/src/modules/common/MediaDisplay.tsx b/src/modules/common/MediaDisplay.tsx index b873455c5..363247576 100644 --- a/src/modules/common/MediaDisplay.tsx +++ b/src/modules/common/MediaDisplay.tsx @@ -134,7 +134,12 @@ export function LidarrMediaDisplay(props: any) { export function RadarrMediaDisplay(props: any) { const { media }: { media: any } = props; + const { config } = useConfigContext(); + const calendar = config?.widgets.find((w) => w.type === 'calendar'); + const useRadarrv5 = calendar?.properties.useRadarrv5 ?? false; + // Find a poster CoverType + const poster = media.images.find((image: any) => image.coverType === 'poster'); return ( image.coverType === 'poster')?.url, + poster: useRadarrv5 ? poster.remoteUrl : poster.url, voteAverage: media.ratings.tmdb.value.toString(), imdbId: media.imdbId, type: 'movie', diff --git a/src/widgets/calendar/CalendarTile.tsx b/src/widgets/calendar/CalendarTile.tsx index b12d40bf1..fe4c087f9 100644 --- a/src/widgets/calendar/CalendarTile.tsx +++ b/src/widgets/calendar/CalendarTile.tsx @@ -30,6 +30,10 @@ const definition = defineWidget({ type: 'switch', defaultValue: false, }, + useRadarrv5: { + type: 'switch', + defaultValue: false, + }, radarrReleaseType: { type: 'select', defaultValue: 'inCinemas', From b8fab01c0b7ab7b5b8438ecb4cb626598f60a5e7 Mon Sep 17 00:00:00 2001 From: Meier Lukas Date: Wed, 18 Oct 2023 20:39:23 +0200 Subject: [PATCH 006/141] Fix allow guest issue (#1472) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * 🐛 Issue with migrate script for node 20 * 🐛 Issue with allow guest check when default config not present --- src/pages/board/index.tsx | 2 +- tsconfig.json | 1 - 2 files changed, 1 insertion(+), 2 deletions(-) diff --git a/src/pages/board/index.tsx b/src/pages/board/index.tsx index 20f25295a..6a283e919 100644 --- a/src/pages/board/index.tsx +++ b/src/pages/board/index.tsx @@ -45,7 +45,7 @@ export const getServerSideProps: GetServerSideProps = a ); const config = await getFrontendConfig(boardName); - if (!config.settings.access.allowGuests && !session?.user) { + if (!config?.settings?.access?.allowGuests && !session?.user) { return { notFound: true, props: { diff --git a/tsconfig.json b/tsconfig.json index 4fb9c134d..ddd387b7f 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -38,7 +38,6 @@ "node_modules" ], "ts-node": { - "esm": true, "compilerOptions": { "module": "nodenext", }, From d60cd2ed8df64ff11654cd57f32314cbb2a27633 Mon Sep 17 00:00:00 2001 From: Meier Lukas Date: Wed, 18 Oct 2023 20:40:54 +0200 Subject: [PATCH 007/141] =?UTF-8?q?=F0=9F=90=9B=20Issue=20with=20migrate?= =?UTF-8?q?=20script=20for=20node=2020=20(#1467)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * 🐛 Issue with migrate script for node 20 * 🐛 Wrong database url in example env file --- .env.example | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.env.example b/.env.example index 8cdf80f91..db8aaac59 100644 --- a/.env.example +++ b/.env.example @@ -10,7 +10,7 @@ # should be updated accordingly. # Database -DATABASE_URL="file:../database/db.sqlite" +DATABASE_URL="file:./database/db.sqlite" # Next Auth # You can generate a new secret on the command line with: From 0a98be4553b46f3b075857e98ad21f3c975d0682 Mon Sep 17 00:00:00 2001 From: Meier Lukas Date: Wed, 18 Oct 2023 20:41:59 +0200 Subject: [PATCH 008/141] =?UTF-8?q?=E2=9C=85=20Add=20tests=20for=20invite?= =?UTF-8?q?=20router=20(#1456)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * ✅ Add test for invite router * ✅ Add cleanup to invite-router tests, add tests for creation and deletion of invites * ♻️ Fix typo * ♻️ Remove nullish for limit of invite router all procedure --- .../User/Invite/delete-invite.modal.tsx | 2 +- src/server/api/root.ts | 15 +- .../api/routers/invite/invite-router.spec.ts | 234 ++++++++++++++++++ .../{invite.ts => invite/invite-router.ts} | 10 +- src/server/db/index.ts | 2 +- 5 files changed, 249 insertions(+), 14 deletions(-) create mode 100644 src/server/api/routers/invite/invite-router.spec.ts rename src/server/api/routers/{invite.ts => invite/invite-router.ts} (86%) diff --git a/src/components/Manage/User/Invite/delete-invite.modal.tsx b/src/components/Manage/User/Invite/delete-invite.modal.tsx index 9b4cf3826..b1d709b2a 100644 --- a/src/components/Manage/User/Invite/delete-invite.modal.tsx +++ b/src/components/Manage/User/Invite/delete-invite.modal.tsx @@ -29,7 +29,7 @@ export const DeleteInviteModal = ({ id, innerProps }: ContextModalProps<{ tokenI