Compare commits

...
221 Commits
Author SHA1 Message Date
Releases Homarr a3e53ec291 chore(release): 1.45.1 [skip ci] 2025-12-03 17:43:49 +00:00
homarr-releases[bot] 38a1c9ca83 chore(release): automatic release v1.45.1 2025-12-03 17:42:39 +00:00
Meier Lukas b40deba9ff fix(security): rce vulnerability in nextjs 2025-12-03 18:33:01 +01:00
homarr-renovate[bot] d5d59dd256 fix(deps): update mantine monorepo to ^8.3.9 (#4576)
Co-authored-by: homarr-renovate[bot] <158783068+homarr-renovate[bot]@users.noreply.github.com>
2025-12-03 13:44:52 +00:00
homarr-renovate[bot] 3453482ed4 fix(deps): update trpc monorepo to ^11.7.2 (#4579)
Co-authored-by: homarr-renovate[bot] <158783068+homarr-renovate[bot]@users.noreply.github.com>
2025-12-03 12:57:36 +00:00
homarr-renovate[bot] d2c1dc3cc1 fix(deps): update dependency swagger-ui-react to ^5.30.3 (#4574)
Co-authored-by: homarr-renovate[bot] <158783068+homarr-renovate[bot]@users.noreply.github.com>
2025-12-03 12:54:17 +00:00
homarr-renovate[bot] 59bcbc8b4d fix(deps): update tanstack-query monorepo (#4578)
Co-authored-by: homarr-renovate[bot] <158783068+homarr-renovate[bot]@users.noreply.github.com>
2025-12-03 11:33:29 +00:00
homarr-renovate[bot] b2c46d33d6 fix(deps): update dependency chroma-js to ^3.2.0 (#4585)
Co-authored-by: homarr-renovate[bot] <158783068+homarr-renovate[bot]@users.noreply.github.com>
2025-12-03 11:28:54 +00:00
homarr-renovate[bot] ca01a31fe5 fix(deps): update dependency isomorphic-dompurify to ^2.33.0 (#4581)
Co-authored-by: homarr-renovate[bot] <158783068+homarr-renovate[bot]@users.noreply.github.com>
2025-12-03 10:53:13 +00:00
homarr-renovate[bot] deb5e9d960 fix(deps): update dependency superjson to v2.2.6 (#4573)
Co-authored-by: homarr-renovate[bot] <158783068+homarr-renovate[bot]@users.noreply.github.com>
2025-12-03 10:48:15 +00:00
homarr-renovate[bot] 16f12d98e6 fix(deps): update nextjs monorepo to v16.0.5 (#4577)
Co-authored-by: homarr-renovate[bot] <158783068+homarr-renovate[bot]@users.noreply.github.com>
2025-12-03 10:45:55 +00:00
homarr-renovate[bot] 10bdd74b2b fix(deps): update testcontainers-node monorepo to ^11.9.0 (#4583)
Co-authored-by: homarr-renovate[bot] <158783068+homarr-renovate[bot]@users.noreply.github.com>
2025-12-03 10:35:20 +00:00
Meier Lukas a91955a35b chore(docs): update sitemap 2025-12-03 11:31:46 +01:00
Meier Lukas 87deba417f chore: update bug-report template 2025-12-03 11:30:41 +01:00
homarr-renovate[bot] 220f68ee04 chore(deps): update pnpm to v10.24.0 (#4580)
Co-authored-by: homarr-renovate[bot] <158783068+homarr-renovate[bot]@users.noreply.github.com>
2025-12-03 10:27:50 +00:00
homarr-renovate[bot] d6fc46df3b fix(deps): update dependency chroma-js to ^3.1.4 (#4570)
Co-authored-by: homarr-renovate[bot] <158783068+homarr-renovate[bot]@users.noreply.github.com>
2025-12-03 10:24:55 +00:00
homarr-renovate[bot] 7a8c50fa4c fix(deps): update dependency sass to ^1.94.2 (#4572)
Co-authored-by: homarr-renovate[bot] <158783068+homarr-renovate[bot]@users.noreply.github.com>
2025-12-03 10:24:23 +00:00
homarr-renovate[bot] 59eecaf842 chore(deps): update vitest monorepo to ^4.0.14 (#4568)
Co-authored-by: homarr-renovate[bot] <158783068+homarr-renovate[bot]@users.noreply.github.com>
2025-12-03 10:12:54 +00:00
homarr-renovate[bot] 879a77ff2a fix(deps): update dependency zod to ^4.1.13 (#4575)
Co-authored-by: homarr-renovate[bot] <158783068+homarr-renovate[bot]@users.noreply.github.com>
2025-12-03 10:10:53 +00:00
homarr-renovate[bot] b53bcb77e9 chore(deps): update dependency prettier-plugin-packagejson to ^2.5.20 (#4566)
Co-authored-by: homarr-renovate[bot] <158783068+homarr-renovate[bot]@users.noreply.github.com>
2025-12-03 10:06:51 +00:00
homarr-renovate[bot] 3062ddafbe fix(deps): update dependency next-intl to v4.5.6 (#4571)
Co-authored-by: homarr-renovate[bot] <158783068+homarr-renovate[bot]@users.noreply.github.com>
2025-12-03 10:06:32 +00:00
homarr-renovate[bot] 7f782220a1 chore(deps): update dependency vite@&gt;&#x3d;5.0.0 &lt;&#x3d;5.4.18 to >=7.2.4 (#4567)
Co-authored-by: homarr-renovate[bot] <158783068+homarr-renovate[bot]@users.noreply.github.com>
2025-12-03 10:06:17 +00:00
homarr-renovate[bot] aa2ec5d221 chore(deps): update dependency hono@&lt;4.6.5 to >=4.10.7 (#4565)
Co-authored-by: homarr-renovate[bot] <158783068+homarr-renovate[bot]@users.noreply.github.com>
2025-12-03 10:00:23 +00:00
homarr-renovate[bot] e6db47aaab chore(deps): update dependency @types/react to v19.2.7 (#4564)
Co-authored-by: homarr-renovate[bot] <158783068+homarr-renovate[bot]@users.noreply.github.com>
2025-12-03 09:59:46 +00:00
homarr-crowdin[bot] f3d2026746 chore(lang): update translations from crowdin (#4560)
Co-authored-by: Crowdin Homarr <190541745+homarr-crowdin[bot]@users.noreply.github.com>
2025-12-01 10:43:38 +01:00
homarr-crowdin[bot] ed31e32150 chore(lang): updated translations from crowdin
Co-authored-by: Crowdin Homarr <190541745+homarr-crowdin[bot]@users.noreply.github.com>
2025-11-29 00:50:15 +00:00
Releases Homarr d07730b5f8 chore(release): 1.45.0 [skip ci] 2025-11-28 19:15:49 +00:00
homarr-releases[bot] 681236ec3b chore(release): automatic release v1.45.0 2025-11-28 19:14:48 +00:00
Meier Lukas 524e1a485b fix(security): restrict modification of entrypoint script (#4555) 2025-11-28 18:34:51 +01:00
homarr-renovate[bot] 2bc6964f7e fix(deps): update dependency next-intl to v4.5.5 (#4542)
Co-authored-by: homarr-renovate[bot] <158783068+homarr-renovate[bot]@users.noreply.github.com>
2025-11-28 17:27:04 +00:00
Meier Lukas 21de817dba chore(deps): security hardening (#4551) 2025-11-28 18:09:10 +01:00
homarr-update-contributors[bot] b15d96e8dd chore: update contributors (#4554)
Co-authored-by: Homarr Update Contributors <210161987+homarr-update-contributors[bot]@users.noreply.github.com>
2025-11-28 12:36:13 +00:00
Noah Croghan 99949fe095 fix: Add fallback when no icon in Minecraft Server widget (#4544) (#4545) 2025-11-27 17:06:31 +01:00
homarr-crowdin[bot] 85d4931538 chore(lang): updated translations from crowdin
Co-authored-by: Crowdin Homarr <190541745+homarr-crowdin[bot]@users.noreply.github.com>
2025-11-26 00:52:18 +00:00
homarr-renovate[bot] 77a86ead41 fix(deps): update dependency next-intl to v4.5.4 (#4540)
Co-authored-by: homarr-renovate[bot] <158783068+homarr-renovate[bot]@users.noreply.github.com>
2025-11-24 13:02:10 +00:00
homarr-renovate[bot] 27ca124d2a chore(deps): update dependency rollup@&gt;&#x3d;4.0.0 &lt;4.22.4 to >=4.53.3 (#4537)
Co-authored-by: homarr-renovate[bot] <158783068+homarr-renovate[bot]@users.noreply.github.com>
2025-11-24 09:51:55 +00:00
homarr-renovate[bot] 3ca6cb18eb chore(deps): update dependency @types/dockerode to ^3.3.47 (#4539)
Co-authored-by: homarr-renovate[bot] <158783068+homarr-renovate[bot]@users.noreply.github.com>
2025-11-24 09:39:01 +00:00
homarr-crowdin[bot] 245bab7cdd chore(lang): updated translations from crowdin
Co-authored-by: Crowdin Homarr <190541745+homarr-crowdin[bot]@users.noreply.github.com>
2025-11-24 00:56:25 +00:00
homarr-renovate[bot] 18a6bfd69d fix(deps): update dependency glob to v12 (#4530)
Co-authored-by: homarr-renovate[bot] <158783068+homarr-renovate[bot]@users.noreply.github.com>
2025-11-23 20:07:39 +01:00
homarr-renovate[bot] c4e6528e6c chore(deps): update dependency @types/react to v19.2.6 (#4532)
Co-authored-by: homarr-renovate[bot] <158783068+homarr-renovate[bot]@users.noreply.github.com>
2025-11-23 04:47:11 +00:00
homarr-renovate[bot] 24c985424e fix(deps): update dependency glob to ^11.1.0 (#4529)
Co-authored-by: homarr-renovate[bot] <158783068+homarr-renovate[bot]@users.noreply.github.com>
2025-11-23 04:06:56 +00:00
homarr-renovate[bot] 292e36fec5 fix(deps): update dependency sass to ^1.94.1 (#4531)
Co-authored-by: homarr-renovate[bot] <158783068+homarr-renovate[bot]@users.noreply.github.com>
2025-11-23 02:19:13 +00:00
homarr-renovate[bot] 7eee48ae88 chore(deps): update vitest monorepo to ^4.0.10 (#4528)
Co-authored-by: homarr-renovate[bot] <158783068+homarr-renovate[bot]@users.noreply.github.com>
2025-11-22 13:34:54 +00:00
homarr-renovate[bot] 1b09b588f3 chore(deps): update dependency form-data@&gt;&#x3d;4.0.0 &lt;4.0.4 to >=4.0.5 (#4525)
Co-authored-by: homarr-renovate[bot] <158783068+homarr-renovate[bot]@users.noreply.github.com>
2025-11-22 10:42:15 +00:00
ManuelandCopilot Autofix powered by AI 22fb696f25 ci(security): missing permissions for workflow (#4474)
Co-authored-by: Copilot Autofix powered by AI <62310815+github-advanced-security[bot]@users.noreply.github.com>
2025-11-22 10:39:45 +00:00
generalmat82andMeier Lukas 60ab98ae36 feat(docker): hide containers with label homarr.hide (#4506)
Co-authored-by: Meier Lukas <meierschlumpf@gmail.com>
2025-11-22 11:32:31 +01:00
homarr-renovate[bot] 9a3feb404c fix(deps): update dependency zod-validation-error to v5 (#4437)
Co-authored-by: homarr-renovate[bot] <158783068+homarr-renovate[bot]@users.noreply.github.com>
2025-11-22 10:35:43 +01:00
homarr-renovate[bot] 9c5c4f33ef chore(deps): update node.js to v24.11.1 (#4502)
Co-authored-by: homarr-renovate[bot] <158783068+homarr-renovate[bot]@users.noreply.github.com>
2025-11-22 10:34:17 +01:00
homarr-crowdin[bot] 3ec0c4097a chore(lang): updated translations from crowdin
Co-authored-by: Crowdin Homarr <190541745+homarr-crowdin[bot]@users.noreply.github.com>
2025-11-22 00:49:38 +00:00
homarr-renovate[bot] e87170ae6e fix(deps): update dependency @tanstack/react-query to ^5.90.10 (#4523)
Co-authored-by: homarr-renovate[bot] <158783068+homarr-renovate[bot]@users.noreply.github.com>
2025-11-21 21:29:15 +00:00
Meier Lukas 30fedcb6f1 chore: update bug-report template 2025-11-21 22:14:37 +01:00
Releases Homarr 6cc1209fc0 chore(release): 1.44.0 [skip ci] 2025-11-21 19:17:06 +00:00
homarr-releases[bot] 2b8fdc0281 chore(release): automatic release v1.44.0 2025-11-21 19:16:09 +00:00
Meier Lukas d9cc35b985 fix(media-requests): incorrect availability mapping (#4520) 2025-11-21 19:05:51 +01:00
Meier Lukas 5a418d73bd fix(iframe): allow clicking links within (#4521) 2025-11-21 19:05:24 +01:00
homarr-renovate[bot] ded4e72e54 fix(deps): update mantine monorepo to ^8.3.8 (#4516)
Co-authored-by: homarr-renovate[bot] <158783068+homarr-renovate[bot]@users.noreply.github.com>
2025-11-20 11:30:16 +00:00
homarr-renovate[bot] de3602da84 chore(deps): update dependency @semantic-release/npm to ^13.1.2 (#4513)
Co-authored-by: homarr-renovate[bot] <158783068+homarr-renovate[bot]@users.noreply.github.com>
2025-11-19 23:30:39 +00:00
homarr-renovate[bot] c80075f1c3 chore(deps): update dependency @types/react to v19.2.5 (#4515)
Co-authored-by: homarr-renovate[bot] <158783068+homarr-renovate[bot]@users.noreply.github.com>
2025-11-19 22:32:13 +00:00
homarr-renovate[bot] be52cb82fd chore(deps): update vitest monorepo to ^4.0.9 (#4509)
Co-authored-by: homarr-renovate[bot] <158783068+homarr-renovate[bot]@users.noreply.github.com>
2025-11-19 21:28:39 +00:00
homarr-renovate[bot] 9304d73054 chore(deps): update dependency hono@&lt;4.6.5 to >=4.10.6 (#4512)
Co-authored-by: homarr-renovate[bot] <158783068+homarr-renovate[bot]@users.noreply.github.com>
2025-11-19 21:27:46 +00:00
homarr-renovate[bot] 912f9ff884 chore(deps): update dependency @types/dockerode to ^3.3.46 (#4514)
Co-authored-by: homarr-renovate[bot] <158783068+homarr-renovate[bot]@users.noreply.github.com>
2025-11-19 20:33:11 +00:00
homarr-renovate[bot] 5e57a4906b fix(deps): update dependency fast-xml-parser to ^5.3.2 (#4510)
Co-authored-by: homarr-renovate[bot] <158783068+homarr-renovate[bot]@users.noreply.github.com>
2025-11-19 09:36:42 +00:00
homarr-renovate[bot] b3db5d5f7b fix(deps): update dependency @tanstack/react-query to ^5.90.9 (#4508)
Co-authored-by: homarr-renovate[bot] <158783068+homarr-renovate[bot]@users.noreply.github.com>
2025-11-19 08:41:31 +00:00
homarr-renovate[bot] ebc5bd170d chore(deps): update dependency glob to v11.1.0 [security] (#4500)
Co-authored-by: homarr-renovate[bot] <158783068+homarr-renovate[bot]@users.noreply.github.com>
2025-11-19 03:19:15 +00:00
homarr-renovate[bot] b4f9fb8b46 fix(deps): update dependency drizzle-kit to ^0.31.7 (#4507)
Co-authored-by: homarr-renovate[bot] <158783068+homarr-renovate[bot]@users.noreply.github.com>
2025-11-18 23:31:02 +00:00
homarr-renovate[bot] 7d0c1a14fd fix(deps): update nextjs monorepo to v16.0.3 (#4504)
Co-authored-by: homarr-renovate[bot] <158783068+homarr-renovate[bot]@users.noreply.github.com>
2025-11-18 22:34:27 +00:00
Meier Lukas c89e35e13c feat(pi-hole): support no-auth (#4480) 2025-11-18 21:05:00 +01:00
homarr-renovate[bot] 8ea6cffb53 fix(deps): update dependency @tanstack/react-query-next-experimental to ^5.91.0 (#4505)
Co-authored-by: homarr-renovate[bot] <158783068+homarr-renovate[bot]@users.noreply.github.com>
2025-11-18 17:39:07 +00:00
homarr-renovate[bot] 1bb96ce5cf chore(deps): update pnpm to v10.22.0 (#4495)
Co-authored-by: homarr-renovate[bot] <158783068+homarr-renovate[bot]@users.noreply.github.com>
2025-11-18 17:38:36 +00:00
homarr-renovate[bot] 6da511bc2e chore(deps): update dependency @types/react to v19.2.4 (#4501)
Co-authored-by: homarr-renovate[bot] <158783068+homarr-renovate[bot]@users.noreply.github.com>
2025-11-18 17:36:32 +00:00
homarr-renovate[bot] 064277373c fix(deps): update dependency next-intl to v4.5.3 (#4503)
Co-authored-by: homarr-renovate[bot] <158783068+homarr-renovate[bot]@users.noreply.github.com>
2025-11-18 17:34:29 +00:00
homarr-crowdin[bot] 88fd0a63b6 chore(lang): updated translations from crowdin
Co-authored-by: Crowdin Homarr <190541745+homarr-crowdin[bot]@users.noreply.github.com>
2025-11-18 00:51:48 +00:00
homarr-renovate[bot] 7fd5bf0699 chore(deps): update dependency jsdom to ^27.2.0 (#4492)
Co-authored-by: homarr-renovate[bot] <158783068+homarr-renovate[bot]@users.noreply.github.com>
2025-11-17 14:35:27 +00:00
homarr-renovate[bot] 1bfa9d7158 chore(deps): update dependency @vitejs/plugin-react to ^5.1.1 (#4493)
Co-authored-by: homarr-renovate[bot] <158783068+homarr-renovate[bot]@users.noreply.github.com>
2025-11-17 13:43:40 +00:00
homarr-renovate[bot] 57140f2c71 chore(deps): update dependency @types/react-dom to v19.2.3 (#4491)
Co-authored-by: homarr-renovate[bot] <158783068+homarr-renovate[bot]@users.noreply.github.com>
2025-11-17 13:43:26 +00:00
homarr-renovate[bot] a5b6203be6 fix(deps): update dependency @tanstack/react-query to ^5.90.8 (#4494)
Co-authored-by: homarr-renovate[bot] <158783068+homarr-renovate[bot]@users.noreply.github.com>
2025-11-17 13:00:35 +00:00
homarr-renovate[bot] aae81d3120 chore(deps): update dependency node to v24.11.1 (#4490)
Co-authored-by: homarr-renovate[bot] <158783068+homarr-renovate[bot]@users.noreply.github.com>
2025-11-17 02:07:01 +00:00
homarr-crowdin[bot] 0fb01c90e9 chore(lang): updated translations from crowdin
Co-authored-by: Crowdin Homarr <190541745+homarr-crowdin[bot]@users.noreply.github.com>
2025-11-17 00:53:59 +00:00
homarr-renovate[bot] 06942ecbcd fix(deps): update dependency next-intl to v4.5.1 (#4484)
Co-authored-by: homarr-renovate[bot] <158783068+homarr-renovate[bot]@users.noreply.github.com>
2025-11-16 16:38:54 +00:00
homarr-renovate[bot] 006dee9e9b chore(deps): update node.js to v24.11.1 (#4481)
Co-authored-by: homarr-renovate[bot] <158783068+homarr-renovate[bot]@users.noreply.github.com>
2025-11-16 16:37:12 +00:00
homarr-renovate[bot] f2df9839f1 chore(deps): update dependency @types/react to v19.2.3 (#4487)
Co-authored-by: homarr-renovate[bot] <158783068+homarr-renovate[bot]@users.noreply.github.com>
2025-11-16 16:36:19 +00:00
homarr-renovate[bot] dcc23e721a chore(deps): update dependency hono@&lt;4.6.5 to >=4.10.5 (#4485)
Co-authored-by: homarr-renovate[bot] <158783068+homarr-renovate[bot]@users.noreply.github.com>
2025-11-16 16:35:49 +00:00
homarr-renovate[bot] 64657d831c fix(deps): update testcontainers-node monorepo to ^11.8.1 (#4486)
Co-authored-by: homarr-renovate[bot] <158783068+homarr-renovate[bot]@users.noreply.github.com>
2025-11-16 15:30:16 +00:00
homarr-renovate[bot] cd124d6e83 fix(deps): update turbo monorepo to ^2.6.1 (#4483)
Co-authored-by: homarr-renovate[bot] <158783068+homarr-renovate[bot]@users.noreply.github.com>
2025-11-16 06:43:04 +00:00
homarr-renovate[bot] 19ecedea43 fix(deps): update dependency sass to ^1.94.0 (#4482)
Co-authored-by: homarr-renovate[bot] <158783068+homarr-renovate[bot]@users.noreply.github.com>
2025-11-16 02:12:03 +00:00
homarr-renovate[bot] 5b55a4751b chore(deps): update dependency rollup@&gt;&#x3d;4.0.0 &lt;4.22.4 to >=4.53.2 (#4479)
Co-authored-by: homarr-renovate[bot] <158783068+homarr-renovate[bot]@users.noreply.github.com>
2025-11-15 09:30:25 +00:00
homarr-renovate[bot] 266b9ffd1b chore(deps): update pnpm to v10.21.0 (#4478)
Co-authored-by: homarr-renovate[bot] <158783068+homarr-renovate[bot]@users.noreply.github.com>
2025-11-15 02:01:31 +00:00
homarr-renovate[bot] 7a3a05b172 chore(deps): update dependency esbuild@&lt;&#x3d;0.24.2 to >=0.27.0 (#4477)
Co-authored-by: homarr-renovate[bot] <158783068+homarr-renovate[bot]@users.noreply.github.com>
2025-11-14 20:36:02 +00:00
homarr-renovate[bot] a62c1385e3 chore(deps): update dependency esbuild to ^0.27.0 (#4476)
Co-authored-by: homarr-renovate[bot] <158783068+homarr-renovate[bot]@users.noreply.github.com>
2025-11-14 19:28:44 +00:00
Releases Homarr 0bba7be8d5 chore(release): 1.43.3 [skip ci] 2025-11-14 19:16:15 +00:00
homarr-releases[bot] 96b556f558 chore(release): automatic release v1.43.3 2025-11-14 19:15:12 +00:00
Manuel aaa23f3732 Merge commit from fork
* fix: sanitize user-media svg api endpoint using isomorphic dompurify

* fix: add iframe sandbox to prevent priviledge escalation
2025-11-14 18:00:15 +01:00
homarr-update-contributors[bot] d33cfe211a chore: update contributors (#4473)
Co-authored-by: Homarr Update Contributors <210161987+homarr-update-contributors[bot]@users.noreply.github.com>
2025-11-14 12:36:49 +00:00
homarr-renovate[bot] e7071bf2bf fix(deps): update dependency fastify to ^5.6.2 (#4471)
Co-authored-by: homarr-renovate[bot] <158783068+homarr-renovate[bot]@users.noreply.github.com>
2025-11-14 10:35:22 +00:00
homarr-renovate[bot] 8a87dbad59 fix(deps): update mantine monorepo to ^8.3.7 (#4472)
Co-authored-by: homarr-renovate[bot] <158783068+homarr-renovate[bot]@users.noreply.github.com>
2025-11-14 09:35:28 +00:00
homarr-renovate[bot] 6a5f069383 chore(deps): update dependency esbuild@&lt;&#x3d;0.24.2 to >=0.26.0 (#4470)
Co-authored-by: homarr-renovate[bot] <158783068+homarr-renovate[bot]@users.noreply.github.com>
2025-11-14 04:37:00 +00:00
homarr-renovate[bot] d8e4255733 chore(deps): update dependency esbuild to ^0.26.0 (#4469)
Co-authored-by: homarr-renovate[bot] <158783068+homarr-renovate[bot]@users.noreply.github.com>
2025-11-14 03:25:59 +00:00
homarr-crowdin[bot] 1916eacb4d chore(lang): updated translations from crowdin
Co-authored-by: Crowdin Homarr <190541745+homarr-crowdin[bot]@users.noreply.github.com>
2025-11-14 00:52:23 +00:00
AartSchinkelandMeier Lukas c30c98b153 fix(stock-price): ignore missing data points in price history (#4429)
Co-authored-by: Meier Lukas <meierschlumpf@gmail.com>
2025-11-13 22:07:23 +01:00
homarr-renovate[bot] 89aed57645 chore(deps): update semantic-release monorepo (#4464)
Co-authored-by: homarr-renovate[bot] <158783068+homarr-renovate[bot]@users.noreply.github.com>
2025-11-13 14:33:37 +00:00
homarr-renovate[bot] 251d1d0da3 chore(deps): update dependency rollup@&gt;&#x3d;4.0.0 &lt;4.22.4 to >=4.53.1 (#4465)
Co-authored-by: homarr-renovate[bot] <158783068+homarr-renovate[bot]@users.noreply.github.com>
2025-11-12 22:31:40 +00:00
homarr-renovate[bot] 51ce5da45b fix(deps): update dependency next-intl to v4.5.0 (#4462)
Co-authored-by: homarr-renovate[bot] <158783068+homarr-renovate[bot]@users.noreply.github.com>
2025-11-12 17:33:22 +00:00
homarr-renovate[bot] eff2202e92 chore(deps): update vitest monorepo to ^4.0.8 (#4459)
Co-authored-by: homarr-renovate[bot] <158783068+homarr-renovate[bot]@users.noreply.github.com>
2025-11-12 17:32:42 +00:00
homarr-renovate[bot] bb25410a40 chore(deps): update dependency vite@&gt;&#x3d;5.0.0 &lt;&#x3d;5.4.18 to >=7.2.2 (#4457)
Co-authored-by: homarr-renovate[bot] <158783068+homarr-renovate[bot]@users.noreply.github.com>
2025-11-12 17:31:53 +00:00
homarr-renovate[bot] 1a56a56989 chore(deps): update dependency rollup@&gt;&#x3d;4.0.0 &lt;4.22.4 to >=4.53.0 (#4463)
Co-authored-by: homarr-renovate[bot] <158783068+homarr-renovate[bot]@users.noreply.github.com>
2025-11-12 16:42:50 +00:00
homarr-renovate[bot] ddfed18acf fix(deps): update dependency @ctrl/qbittorrent to ^9.11.0 (#4456)
Co-authored-by: homarr-renovate[bot] <158783068+homarr-renovate[bot]@users.noreply.github.com>
2025-11-11 07:32:42 +00:00
homarr-renovate[bot] 7bc2f87f31 fix(deps): update dependency @tanstack/react-query to ^5.90.7 (#4451)
Co-authored-by: homarr-renovate[bot] <158783068+homarr-renovate[bot]@users.noreply.github.com>
2025-11-11 05:33:17 +00:00
homarr-renovate[bot] 05a9d26138 chore(deps): update dependency vite@&gt;&#x3d;5.0.0 &lt;&#x3d;5.4.18 to >=7.2.1 (#4454)
Co-authored-by: homarr-renovate[bot] <158783068+homarr-renovate[bot]@users.noreply.github.com>
2025-11-11 04:37:45 +00:00
homarr-renovate[bot] 4f96cdf9f7 chore(deps): update dependency vite@&gt;&#x3d;5.0.0 &lt;&#x3d;5.4.18 to >=7.2.0 (#4449)
Co-authored-by: homarr-renovate[bot] <158783068+homarr-renovate[bot]@users.noreply.github.com>
2025-11-10 15:13:48 +00:00
ManuelandMeier Lukas 1c1f8a48d2 fix(users): next button in create form always disabled (#4443)
Co-authored-by: Meier Lukas <meierschlumpf@gmail.com>
2025-11-10 16:02:14 +01:00
homarr-renovate[bot] f648af0e2b fix(deps): update testcontainers-node monorepo to ^11.8.0 (#4450)
Co-authored-by: homarr-renovate[bot] <158783068+homarr-renovate[bot]@users.noreply.github.com>
2025-11-10 10:36:35 +00:00
homarr-crowdin[bot] 35ca0571ad chore(lang): updated translations from crowdin
Co-authored-by: Crowdin Homarr <190541745+homarr-crowdin[bot]@users.noreply.github.com>
2025-11-10 00:55:24 +00:00
homarr-renovate[bot] 92a91329c9 chore(deps): update dependency axios@&gt;&#x3d;1.0.0 &lt;1.8.2 to >=1.13.2 (#4447)
Co-authored-by: homarr-renovate[bot] <158783068+homarr-renovate[bot]@users.noreply.github.com>
2025-11-09 20:31:57 +00:00
homarr-renovate[bot] 23edb55c67 chore(deps): update dependency eslint to ^9.39.1 (#4440)
Co-authored-by: homarr-renovate[bot] <158783068+homarr-renovate[bot]@users.noreply.github.com>
2025-11-09 16:34:41 +00:00
homarr-renovate[bot] 8449d606d7 chore(deps): update vitest monorepo to ^4.0.7 (#4444)
Co-authored-by: homarr-renovate[bot] <158783068+homarr-renovate[bot]@users.noreply.github.com>
2025-11-09 15:28:38 +00:00
homarr-renovate[bot] d3edfcf3dc fix(deps): update dependency swagger-ui-react to ^5.30.2 (#4442)
Co-authored-by: homarr-renovate[bot] <158783068+homarr-renovate[bot]@users.noreply.github.com>
2025-11-09 10:30:28 +00:00
homarr-renovate[bot] 65f2e825fd fix(deps): update dependency fast-xml-parser to ^5.3.1 (#4435)
Co-authored-by: homarr-renovate[bot] <158783068+homarr-renovate[bot]@users.noreply.github.com>
2025-11-08 19:36:33 +00:00
homarr-renovate[bot] 286f4e764a chore(deps): update dependency @types/node to ^24.10.0 (#4434)
Co-authored-by: homarr-renovate[bot] <158783068+homarr-renovate[bot]@users.noreply.github.com>
2025-11-08 01:57:46 +00:00
Releases Homarr def87f36fd chore(release): 1.43.2 [skip ci] 2025-11-07 19:16:38 +00:00
homarr-releases[bot] 5adc2049cc chore(release): automatic release v1.43.2 2025-11-07 19:15:38 +00:00
homarr-renovate[bot] 5f9054b162 fix(deps): update dependency @tanstack/react-query to ^5.90.6 (#4427)
Co-authored-by: homarr-renovate[bot] <158783068+homarr-renovate[bot]@users.noreply.github.com>
2025-11-07 03:23:11 +00:00
homarr-renovate[bot] b450ff6877 chore(deps): update dependency esbuild@&lt;&#x3d;0.24.2 to >=0.25.12 (#4431)
Co-authored-by: homarr-renovate[bot] <158783068+homarr-renovate[bot]@users.noreply.github.com>
2025-11-07 02:04:23 +00:00
homarr-renovate[bot] 97052b8bff chore(deps): update dependency esbuild to ^0.25.12 (#4430)
Co-authored-by: homarr-renovate[bot] <158783068+homarr-renovate[bot]@users.noreply.github.com>
2025-11-07 02:03:50 +00:00
homarr-renovate[bot] 07af9d8673 fix(deps): update dependency jotai to ^2.15.1 (#4426)
Co-authored-by: homarr-renovate[bot] <158783068+homarr-renovate[bot]@users.noreply.github.com>
2025-11-06 06:44:55 +00:00
homarr-renovate[bot] 4516f27fa6 fix(deps): update dependency @gitbeaker/rest to ^43.8.0 (#4425)
Co-authored-by: homarr-renovate[bot] <158783068+homarr-renovate[bot]@users.noreply.github.com>
2025-11-06 06:44:37 +00:00
homarr-renovate[bot] f2164272a5 fix(deps): update dependency sass to ^1.93.3 (#4421)
Co-authored-by: homarr-renovate[bot] <158783068+homarr-renovate[bot]@users.noreply.github.com>
2025-11-06 02:05:33 +00:00
homarr-renovate[bot] 50caa1fcf9 chore(deps): update vitest monorepo to ^4.0.6 (#4420)
Co-authored-by: homarr-renovate[bot] <158783068+homarr-renovate[bot]@users.noreply.github.com>
2025-11-05 23:30:24 +00:00
homarr-renovate[bot] 742ef66e3c fix(deps): update turbo monorepo to ^2.6.0 (#4422)
Co-authored-by: homarr-renovate[bot] <158783068+homarr-renovate[bot]@users.noreply.github.com>
2025-11-05 22:34:14 +00:00
homarr-renovate[bot] 0d10b2b99a chore(deps): update dependency @semantic-release/github to ^12.0.1 (#4423)
Co-authored-by: homarr-renovate[bot] <158783068+homarr-renovate[bot]@users.noreply.github.com>
2025-11-05 22:31:09 +00:00
homarr-renovate[bot] 2ff32627f4 chore(deps): update dependency eslint to ^9.39.0 (#4424)
Co-authored-by: homarr-renovate[bot] <158783068+homarr-renovate[bot]@users.noreply.github.com>
2025-11-05 21:32:12 +00:00
homarr-renovate[bot] d9b14db6a1 fix(deps): update dependency swagger-ui-react to ^5.30.1 (#4418)
Co-authored-by: homarr-renovate[bot] <158783068+homarr-renovate[bot]@users.noreply.github.com>
2025-11-05 09:36:37 +00:00
homarr-renovate[bot] 186e3e445d fix(deps): update dependency octokit to ^5.0.5 (#4413)
Co-authored-by: homarr-renovate[bot] <158783068+homarr-renovate[bot]@users.noreply.github.com>
2025-11-05 09:35:58 +00:00
homarr-renovate[bot] 160c20a9a6 fix(deps): update dependency tsdav to ^2.1.6 (#4417)
Co-authored-by: homarr-renovate[bot] <158783068+homarr-renovate[bot]@users.noreply.github.com>
2025-11-05 08:43:04 +00:00
homarr-renovate[bot] 97cbade713 fix(deps): update dependency dayjs to ^1.11.19 (#4414)
Co-authored-by: homarr-renovate[bot] <158783068+homarr-renovate[bot]@users.noreply.github.com>
2025-11-05 07:32:10 +00:00
homarr-renovate[bot] 816c6a0329 chore(deps): update dependency jsdom to ^27.1.0 (#4416)
Co-authored-by: homarr-renovate[bot] <158783068+homarr-renovate[bot]@users.noreply.github.com>
2025-11-05 06:44:28 +00:00
homarr-renovate[bot] 018a33b078 fix(deps): update dependency @octokit/auth-app to ^8.1.2 (#4412)
Co-authored-by: homarr-renovate[bot] <158783068+homarr-renovate[bot]@users.noreply.github.com>
2025-11-05 02:04:46 +00:00
homarr-renovate[bot] 168458e9e1 chore(deps): update actions/setup-node action to v6 (#4320)
Co-authored-by: homarr-renovate[bot] <158783068+homarr-renovate[bot]@users.noreply.github.com>
2025-11-04 22:15:15 +01:00
homarr-renovate[bot] ebc64f3090 chore(deps): update dependency dotenv-cli to v11 (#4402)
Co-authored-by: homarr-renovate[bot] <158783068+homarr-renovate[bot]@users.noreply.github.com>
2025-11-04 22:13:26 +01:00
homarr-renovate[bot]andMeier Lukas d255492bb7 chore(deps): update vitest monorepo to v4 (major) (#4367)
Co-authored-by: homarr-renovate[bot] <158783068+homarr-renovate[bot]@users.noreply.github.com>
Co-authored-by: Meier Lukas <meierschlumpf@gmail.com>
2025-11-04 22:03:43 +01:00
homarr-renovate[bot]andMeier Lukas dcf960fa97 fix(deps): update dependency @gitbeaker/rest to ^43.7.0 (#4386)
Co-authored-by: homarr-renovate[bot] <158783068+homarr-renovate[bot]@users.noreply.github.com>
Co-authored-by: Meier Lukas <meierschlumpf@gmail.com>
2025-11-04 21:28:11 +01:00
homarr-renovate[bot]andMeier Lukas 6ce23a6e97 fix(deps): update nextjs monorepo to v16 (major) (#4363)
Co-authored-by: homarr-renovate[bot] <158783068+homarr-renovate[bot]@users.noreply.github.com>
Co-authored-by: Meier Lukas <meierschlumpf@gmail.com>
2025-11-04 21:26:44 +01:00
homarr-renovate[bot] a43ac18bef chore(deps): update node.js to v24 (#4395)
Co-authored-by: homarr-renovate[bot] <158783068+homarr-renovate[bot]@users.noreply.github.com>
2025-11-04 21:14:13 +01:00
homarr-renovate[bot] 881d0d1219 chore(deps): update dependency hono@&lt;4.6.5 to >=4.10.4 (#4410)
Co-authored-by: homarr-renovate[bot] <158783068+homarr-renovate[bot]@users.noreply.github.com>
2025-11-04 19:03:28 +00:00
homarr-crowdin[bot] 3fff8b88b3 chore(lang): updated translations from crowdin
Co-authored-by: Crowdin Homarr <190541745+homarr-crowdin[bot]@users.noreply.github.com>
2025-11-04 00:50:14 +00:00
homarr-renovate[bot] 57d1a91866 fix(deps): update dependency @ctrl/deluge to ^7.5.0 (#4407)
Co-authored-by: homarr-renovate[bot] <158783068+homarr-renovate[bot]@users.noreply.github.com>
2025-11-03 21:18:41 +00:00
homarr-renovate[bot] d34f9e5b3e fix(deps): update tiptap monorepo to v2.27.1 (#4405)
Co-authored-by: homarr-renovate[bot] <158783068+homarr-renovate[bot]@users.noreply.github.com>
2025-11-03 16:37:13 +00:00
homarr-renovate[bot] cf89a03f0c chore(deps): update dependency axios@&gt;&#x3d;1.0.0 &lt;1.8.2 to >=1.13.1 (#4401)
Co-authored-by: homarr-renovate[bot] <158783068+homarr-renovate[bot]@users.noreply.github.com>
2025-11-03 10:36:04 +00:00
homarr-renovate[bot] f4caddfd56 fix(deps): update tiptap monorepo to v2.27.0 (#4404)
Co-authored-by: homarr-renovate[bot] <158783068+homarr-renovate[bot]@users.noreply.github.com>
2025-11-03 09:38:19 +00:00
homarr-renovate[bot] 9e2bbb8a3f fix(deps): update mantine monorepo to ^8.3.6 (#4403)
Co-authored-by: homarr-renovate[bot] <158783068+homarr-renovate[bot]@users.noreply.github.com>
2025-11-03 06:45:35 +00:00
homarr-renovate[bot] 6dbd2802c9 chore(deps): update pnpm to v10.20.0 (#4400)
Co-authored-by: homarr-renovate[bot] <158783068+homarr-renovate[bot]@users.noreply.github.com>
2025-11-02 18:37:28 +00:00
homarr-renovate[bot] 19e25a095f fix(deps): update dependency superjson to v2.2.5 (#4398)
Co-authored-by: homarr-renovate[bot] <158783068+homarr-renovate[bot]@users.noreply.github.com>
2025-11-02 17:26:14 +00:00
homarr-renovate[bot] 4c4e901e7d fix(deps): update dependency @jellyfin/sdk to ^0.13.0 (#4399)
Co-authored-by: homarr-renovate[bot] <158783068+homarr-renovate[bot]@users.noreply.github.com>
2025-11-02 16:34:38 +00:00
homarr-renovate[bot] 5aca5d1b0a fix(deps): update trpc monorepo to ^11.7.1 (#4396)
Co-authored-by: homarr-renovate[bot] <158783068+homarr-renovate[bot]@users.noreply.github.com>
2025-11-02 14:27:23 +00:00
homarr-renovate[bot] 59434ee33a fix(deps): update dependency drizzle-kit to ^0.31.6 (#4397)
Co-authored-by: homarr-renovate[bot] <158783068+homarr-renovate[bot]@users.noreply.github.com>
2025-11-02 13:34:04 +00:00
homarr-renovate[bot] b59ee77c28 chore(deps): update node.js to v22.21.1 (#4355)
Co-authored-by: homarr-renovate[bot] <158783068+homarr-renovate[bot]@users.noreply.github.com>
2025-11-02 02:09:11 +00:00
homarr-renovate[bot] 5effee8148 chore(deps): update dependency @types/pg to ^8.15.6 (#4394)
Co-authored-by: homarr-renovate[bot] <158783068+homarr-renovate[bot]@users.noreply.github.com>
2025-11-02 02:08:59 +00:00
homarr-renovate[bot] ba82853f5c chore(deps): update dependency @types/chroma-js to v3.1.2 (#4393)
Co-authored-by: homarr-renovate[bot] <158783068+homarr-renovate[bot]@users.noreply.github.com>
2025-11-01 21:26:47 +00:00
homarr-renovate[bot] 1491b0fe0e chore(deps): update dependency axios@&gt;&#x3d;1.0.0 &lt;1.8.2 to >=1.13.0 (#4392)
Co-authored-by: homarr-renovate[bot] <158783068+homarr-renovate[bot]@users.noreply.github.com>
2025-11-01 16:33:43 +00:00
homarr-renovate[bot] b51e285c92 fix(deps): update dependency swagger-ui-react to ^5.30.0 (#4391)
Co-authored-by: homarr-renovate[bot] <158783068+homarr-renovate[bot]@users.noreply.github.com>
2025-11-01 12:51:55 +00:00
Meier Lukas 6d9726e19e chore: update bug report template 2025-10-31 23:35:49 +01:00
Releases Homarr 145bea727f chore(release): 1.43.1 [skip ci] 2025-10-31 19:14:59 +00:00
homarr-releases[bot] 5b7de36642 chore(release): automatic release v1.43.1 2025-10-31 19:13:48 +00:00
Meier Lukas 6f3b7ec491 fix(media-releases): support more media type mappings for jellyfin and emby (#4382) 2025-10-31 16:56:15 +01:00
homarr-update-contributors[bot] bbfc6e48fe chore: update contributors (#4389)
Co-authored-by: Homarr Update Contributors <210161987+homarr-update-contributors[bot]@users.noreply.github.com>
2025-10-31 12:36:00 +00:00
homarr-renovate[bot] 2fe36564c2 fix(deps): update dependency @auth/drizzle-adapter to ^1.11.1 (#4388)
Co-authored-by: homarr-renovate[bot] <158783068+homarr-renovate[bot]@users.noreply.github.com>
2025-10-31 04:38:56 +00:00
homarr-renovate[bot] 747bb922cc fix(deps): update dependency @auth/core to ^0.41.1 (#4387)
Co-authored-by: homarr-renovate[bot] <158783068+homarr-renovate[bot]@users.noreply.github.com>
2025-10-31 03:22:51 +00:00
homarr-renovate[bot] 24def99827 fix(deps): update trpc monorepo to ^11.7.0 (#4385)
Co-authored-by: homarr-renovate[bot] <158783068+homarr-renovate[bot]@users.noreply.github.com>
2025-10-30 17:29:32 +00:00
castielwaverly e0526c5ea7 fix(releases-widget): Search multiple docker hub pages for releases (#4158) 2025-10-29 19:33:50 +01:00
homarr-renovate[bot] 9e4b93abcf chore(deps): update dependency node to v24 (#4368)
Co-authored-by: homarr-renovate[bot] <158783068+homarr-renovate[bot]@users.noreply.github.com>
2025-10-29 18:30:02 +01:00
homarr-renovate[bot] c544d6ec2e fix(deps): update dependency next-auth to v5.0.0-beta.30 [security] (#4379)
Co-authored-by: homarr-renovate[bot] <158783068+homarr-renovate[bot]@users.noreply.github.com>
2025-10-29 12:55:30 +00:00
homarr-renovate[bot] 2c0c589bb5 chore(deps): update dependency @vitejs/plugin-react to ^5.1.0 (#4377)
Co-authored-by: homarr-renovate[bot] <158783068+homarr-renovate[bot]@users.noreply.github.com>
2025-10-29 09:34:20 +00:00
homarr-renovate[bot] 8242bfc95c fix(deps): update dependency drizzle-orm to ^0.44.7 (#4372)
Co-authored-by: homarr-renovate[bot] <158783068+homarr-renovate[bot]@users.noreply.github.com>
2025-10-29 06:46:08 +00:00
homarr-renovate[bot] 3a06ce7553 chore(deps): update dependency @types/dockerode to ^3.3.45 (#4376)
Co-authored-by: homarr-renovate[bot] <158783068+homarr-renovate[bot]@users.noreply.github.com>
2025-10-29 05:33:31 +00:00
homarr-renovate[bot] c18d04616e chore(deps): update dependency @types/cookies to v0.9.2 (#4375)
Co-authored-by: homarr-renovate[bot] <158783068+homarr-renovate[bot]@users.noreply.github.com>
2025-10-29 04:39:02 +00:00
homarr-crowdin[bot] 6e5fbde23b chore(lang): update translations from crowdin (#4362)
Co-authored-by: Crowdin Homarr <190541745+homarr-crowdin[bot]@users.noreply.github.com>
2025-10-28 16:13:39 +01:00
homarr-renovate[bot] 136ed8e8b4 fix(deps): update tiptap monorepo to v2.26.4 (#4371)
Co-authored-by: homarr-renovate[bot] <158783068+homarr-renovate[bot]@users.noreply.github.com>
2025-10-28 13:43:01 +00:00
homarr-renovate[bot] 920a33861f chore(deps): update dependency vite@&gt;&#x3d;5.0.0 &lt;&#x3d;5.4.18 to >=7.1.12 (#4370)
Co-authored-by: homarr-renovate[bot] <158783068+homarr-renovate[bot]@users.noreply.github.com>
2025-10-28 07:32:04 +00:00
homarr-renovate[bot] 7329135fd8 fix(deps): update testcontainers-node monorepo to ^11.7.2 (#4366)
Co-authored-by: homarr-renovate[bot] <158783068+homarr-renovate[bot]@users.noreply.github.com>
2025-10-27 13:00:55 +00:00
homarr-renovate[bot] 18cc04e7f2 fix(deps): update dependency superjson to v2.2.3 (#4364)
Co-authored-by: homarr-renovate[bot] <158783068+homarr-renovate[bot]@users.noreply.github.com>
2025-10-27 11:28:47 +00:00
homarr-renovate[bot] ce6338840c fix(deps): update dependency next-intl to v4.4.0 (#4365)
Co-authored-by: homarr-renovate[bot] <158783068+homarr-renovate[bot]@users.noreply.github.com>
2025-10-27 10:36:32 +00:00
homarr-renovate[bot] 6e6c912225 fix(deps): update dependency mysql2 to v3.15.3 (#4360)
Co-authored-by: homarr-renovate[bot] <158783068+homarr-renovate[bot]@users.noreply.github.com>
2025-10-26 19:33:05 +00:00
homarr-renovate[bot] 554d19a458 fix(deps): update dependency @jellyfin/sdk to ^0.12.0 (#4359)
Co-authored-by: homarr-renovate[bot] <158783068+homarr-renovate[bot]@users.noreply.github.com>
2025-10-26 17:12:05 +00:00
homarr-renovate[bot] 0491598d59 chore(deps): update pnpm to v10.19.0 (#4358)
Co-authored-by: homarr-renovate[bot] <158783068+homarr-renovate[bot]@users.noreply.github.com>
2025-10-26 14:28:32 +00:00
homarr-renovate[bot] 3c4c26ee21 fix(deps): update dependency ioredis to v5.8.2 (#4357)
Co-authored-by: homarr-renovate[bot] <158783068+homarr-renovate[bot]@users.noreply.github.com>
2025-10-26 14:28:07 +00:00
homarr-renovate[bot] 29da5cc905 chore(deps): update dependency node to v22.21.0 (#4354)
Co-authored-by: homarr-renovate[bot] <158783068+homarr-renovate[bot]@users.noreply.github.com>
2025-10-26 03:23:45 +00:00
homarr-renovate[bot] f96cbe0652 fix(deps): update dependency typescript-eslint to ^8.46.2 (#4352)
Co-authored-by: homarr-renovate[bot] <158783068+homarr-renovate[bot]@users.noreply.github.com>
2025-10-26 03:23:16 +00:00
homarr-renovate[bot] fc46d88071 chore(deps): update dependency @types/node to ^22.18.12 (#4350)
Co-authored-by: homarr-renovate[bot] <158783068+homarr-renovate[bot]@users.noreply.github.com>
2025-10-26 02:06:12 +00:00
homarr-crowdin[bot] 1abece05ae chore(lang): updated translations from crowdin
Co-authored-by: Crowdin Homarr <190541745+homarr-crowdin[bot]@users.noreply.github.com>
2025-10-26 00:53:29 +00:00
Meier Lukas 945d2a1244 chore: update bug report template 2025-10-25 10:06:52 +02:00
homarr-crowdin[bot] d9d9afd5e3 chore(lang): updated translations from crowdin
Co-authored-by: Crowdin Homarr <190541745+homarr-crowdin[bot]@users.noreply.github.com>
2025-10-25 08:03:49 +00:00
homarr-renovate[bot] ddb8a99631 chore(deps): update node.js to v22.21.0 (#4349)
Co-authored-by: homarr-renovate[bot] <158783068+homarr-renovate[bot]@users.noreply.github.com>
2025-10-25 08:02:56 +00:00
homarr-renovate[bot] ef18c58f5b fix(deps): update dependency node-ical to ^0.22.1 (#4346)
Co-authored-by: homarr-renovate[bot] <158783068+homarr-renovate[bot]@users.noreply.github.com>
2025-10-25 10:02:42 +02:00
homarr-renovate[bot] 94eafddc72 chore(deps): update semantic-release monorepo (#4318)
Co-authored-by: homarr-renovate[bot] <158783068+homarr-renovate[bot]@users.noreply.github.com>
2025-10-25 10:01:51 +02:00
homarr-renovate[bot] 074d27e37e fix(deps): update dependency @paralleldrive/cuid2 to v3 (#4343)
Co-authored-by: homarr-renovate[bot] <158783068+homarr-renovate[bot]@users.noreply.github.com>
2025-10-25 10:00:19 +02:00
homarr-renovate[bot] b030c128c1 chore(deps): update dependency hono@&lt;4.6.5 to >=4.10.3 [security] (#4347)
Co-authored-by: homarr-renovate[bot] <158783068+homarr-renovate[bot]@users.noreply.github.com>
2025-10-24 21:22:24 +00:00
Releases Homarr 0ca225d790 chore(release): 1.43.0 [skip ci] 2025-10-24 19:16:03 +00:00
homarr-releases[bot] cd391c6b08 chore(release): automatic release v1.43.0 2025-10-24 19:14:56 +00:00
homarr-renovate[bot] 7281b4ae32 fix(deps): update dependency node-ical to ^0.22.0 (#4344)
Co-authored-by: homarr-renovate[bot] <158783068+homarr-renovate[bot]@users.noreply.github.com>
2025-10-24 18:40:53 +00:00
homarr-renovate[bot] 4cab12b80a fix(deps): update dependency @tanstack/react-query to ^5.90.5 (#4316)
Co-authored-by: homarr-renovate[bot] <158783068+homarr-renovate[bot]@users.noreply.github.com>
2025-10-24 18:39:45 +00:00
Meier Lukas 172db0e3f9 feat(integrations): add app linking (#4338) 2025-10-24 20:21:27 +02:00
homarr-renovate[bot] 6f0b5d7e04 chore(deps): update dependency jsdom to ^27.0.1 (#4341)
Co-authored-by: homarr-renovate[bot] <158783068+homarr-renovate[bot]@users.noreply.github.com>
2025-10-23 16:56:22 +00:00
homarr-renovate[bot] 6d5153e5dc chore(deps): update dependency rollup@&gt;&#x3d;4.0.0 &lt;4.22.4 to >=4.52.5 (#4342)
Co-authored-by: homarr-renovate[bot] <158783068+homarr-renovate[bot]@users.noreply.github.com>
2025-10-23 16:55:56 +00:00
homarr-renovate[bot] ee8d49c7e4 chore(deps): update dependency hono@&lt;4.6.5 to >=4.10.2 [security] (#4337)
Co-authored-by: homarr-renovate[bot] <158783068+homarr-renovate[bot]@users.noreply.github.com>
2025-10-22 22:21:01 +00:00
homarr-renovate[bot] c9637021f0 chore(deps): update dependency eslint to ^9.38.0 (#4339)
Co-authored-by: homarr-renovate[bot] <158783068+homarr-renovate[bot]@users.noreply.github.com>
2025-10-22 21:17:18 +00:00
homarr-renovate[bot] bd983701b7 fix(deps): update dependency octokit to ^5.0.4 (#4340)
Co-authored-by: homarr-renovate[bot] <158783068+homarr-renovate[bot]@users.noreply.github.com>
2025-10-22 20:36:10 +00:00
homarr-renovate[bot] e7598ee0e1 chore(deps): update dependency @types/node to ^22.18.11 (#4334)
Co-authored-by: homarr-renovate[bot] <158783068+homarr-renovate[bot]@users.noreply.github.com>
2025-10-22 17:14:28 +02:00
homarr-crowdin[bot] 26a11e5d62 chore(lang): updated translations from crowdin
Co-authored-by: Crowdin Homarr <190541745+homarr-crowdin[bot]@users.noreply.github.com>
2025-10-22 15:04:16 +00:00
homarr-renovate[bot] 0df6e8fb20 fix(deps): update nextjs monorepo to v15.5.6 (#4314)
Co-authored-by: homarr-renovate[bot] <158783068+homarr-renovate[bot]@users.noreply.github.com>
2025-10-22 14:37:02 +00:00
homarr-renovate[bot] c2453b6c96 chore(deps): update dependency hono@&lt;4.6.5 to >=4.10.1 (#4332)
Co-authored-by: homarr-renovate[bot] <158783068+homarr-renovate[bot]@users.noreply.github.com>
2025-10-22 14:35:23 +00:00
homarr-renovate[bot] fb4b8f7ca3 fix(deps): update dependency swagger-ui-react to ^5.29.5 (#4335)
Co-authored-by: homarr-renovate[bot] <158783068+homarr-renovate[bot]@users.noreply.github.com>
2025-10-22 13:45:28 +00:00
homarr-renovate[bot] 592412d240 chore(deps): update dependency hono@&lt;4.6.5 to >=4.10.0 (#4308)
Co-authored-by: homarr-renovate[bot] <158783068+homarr-renovate[bot]@users.noreply.github.com>
2025-10-21 22:28:55 +00:00
homarr-renovate[bot] eb717da792 chore(deps): update dependency vite@&gt;&#x3d;5.0.0 &lt;&#x3d;5.4.18 to >=7.1.11 [security] (#4328)
Co-authored-by: homarr-renovate[bot] <158783068+homarr-renovate[bot]@users.noreply.github.com>
2025-10-20 22:23:40 +00:00
Meier Lukas ed5127de64 ci(renovate): add config validation job (#4303) 2025-10-20 19:18:22 +02:00
homarr-crowdin[bot] e1b4186aa2 chore(lang): updated translations from crowdin
Co-authored-by: Crowdin Homarr <190541745+homarr-crowdin[bot]@users.noreply.github.com>
2025-10-20 11:08:44 +00:00
homarr-renovate[bot] 63c5c9ca98 fix(deps): update mantine monorepo to ^8.3.5 (#4291)
Co-authored-by: homarr-renovate[bot] <158783068+homarr-renovate[bot]@users.noreply.github.com>
2025-10-20 04:39:14 +00:00
homarr-renovate[bot] b0e44943a3 chore(deps): update dependency esbuild to ^0.25.11 (#4325)
Co-authored-by: homarr-renovate[bot] <158783068+homarr-renovate[bot]@users.noreply.github.com>
2025-10-20 04:37:22 +00:00
homarr-renovate[bot] 448272091b chore(deps): update dependency esbuild@&lt;&#x3d;0.24.2 to >=0.25.11 (#4326)
Co-authored-by: homarr-renovate[bot] <158783068+homarr-renovate[bot]@users.noreply.github.com>
2025-10-20 03:29:55 +00:00
homarr-renovate[bot] ceec6d2789 chore(deps): update dependency vite@&gt;&#x3d;5.0.0 &lt;&#x3d;5.4.18 to >=7.1.10 (#4323)
Co-authored-by: homarr-renovate[bot] <158783068+homarr-renovate[bot]@users.noreply.github.com>
2025-10-19 13:34:19 +00:00
homarr-renovate[bot] e216ae3a70 chore(deps): update pnpm to v10.18.3 (#4322)
Co-authored-by: homarr-renovate[bot] <158783068+homarr-renovate[bot]@users.noreply.github.com>
2025-10-19 10:29:49 +00:00
homarr-crowdin[bot] ce26cdf2b2 chore(lang): updated translations from crowdin
Co-authored-by: Crowdin Homarr <190541745+homarr-crowdin[bot]@users.noreply.github.com>
2025-10-19 00:55:57 +00:00
Meier Lukas d66be5ff82 chore: update bug report template 2025-10-18 20:45:30 +02:00
211 changed files with 12807 additions and 4406 deletions

No files matched your search

+5
View File
@@ -33,6 +33,11 @@ body:
options:
# The below comment is used to insert a new version with on-release.yml
#NEXT_VERSION#
- 1.45.0
- 1.44.0
- 1.43.1
- 1.43.0
- 1.42.1
- 1.42.0
- 1.41.0
- 1.40.0
+17 -2
View File
@@ -3,18 +3,33 @@
extends: ["config:recommended"],
packageRules: [
{
matchPackagePatterns: ["^@homarr/"],
matchPackageNames: ["^@homarr/"],
enabled: false,
},
// Reenable once https://github.com/privatenumber/tsx/issues/737 is fixed
{
matchPackagePatterns: ["tsx"],
matchPackageNames: ["tsx"],
enabled: false,
},
{
matchUpdateTypes: ["minor", "patch", "pin", "digest"],
automerge: true,
},
{
// disallow automerge for onlyBuiltDependencies
matchPackageNames: [
"@tree-sitter-grammars/tree-sitter-yaml",
"bcrypt",
"better-sqlite3",
"cpu-features",
"esbuild",
"sharp",
"ssh2",
"tree-sitter",
"tree-sitter-json",
],
automerge: false,
},
],
updateInternalDeps: true,
rangeStrategy: "bump",
+2
View File
@@ -1,4 +1,6 @@
name: "[Quality] Code Analysis"
permissions:
contents: read
on:
pull_request:
+2
View File
@@ -1,4 +1,6 @@
name: "[Crowdin] Upload translations"
permissions:
contents: read
on:
workflow_dispatch:
@@ -61,10 +61,10 @@ jobs:
persist-credentials: false
- uses: pnpm/action-setup@v4
if: env.SKIP_RELEASE == 'false'
- uses: actions/setup-node@v5
- uses: actions/setup-node@v6
if: env.SKIP_RELEASE == 'false'
with:
node-version: 22.20.0
node-version: 24.11.1
cache: "pnpm"
- run: npm i -g pnpm
if: env.SKIP_RELEASE == 'false'
@@ -0,0 +1,18 @@
name: "[Renovate] Validate configuration"
permissions:
contents: read
on:
pull_request:
branches: ["*"]
paths: [".github/renovate.json5"]
jobs:
renovate-validate:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v5
- run: |
npx --yes --package renovate -- \
renovate-config-validator --strict .github/renovate.json5
+3 -1
View File
@@ -9,6 +9,8 @@ env:
GITHUB_TOKEN: "${{ secrets.GITHUB_TOKEN }}"
CROWDIN_TOKEN: "${{ secrets.CROWDIN_UPDATE_CONTRIBUTORS_TOKEN }}"
permissions:
contents: read
jobs:
update-contributors:
runs-on: ubuntu-latest
@@ -32,7 +34,7 @@ jobs:
- uses: pnpm/action-setup@v4
- name: Use Node.js ${{ matrix.node-version }}
uses: actions/setup-node@v5
uses: actions/setup-node@v6
with:
node-version: ${{ matrix.node-version }}
cache: "pnpm"
+1
View File
@@ -3,3 +3,4 @@
# @link https://docs.expo.dev/guides/monorepos/#common-issues
node-linker=hoisted
strict-peer-dependencies=false
engine-strict=true
+1 -1
View File
@@ -1 +1 @@
22.20.0
24.11.1
+138
View File
@@ -1,3 +1,141 @@
## [1.45.1](https://github.com/homarr-labs/homarr/compare/v1.45.0...v1.45.1) (2025-12-03)
### Bug Fixes
* **deps:** update dependency chroma-js to ^3.1.4 ([#4570](https://github.com/homarr-labs/homarr/issues/4570)) ([d6fc46d](https://github.com/homarr-labs/homarr/commit/d6fc46df3b5e2dd79ff6f9a3dd3a3e2050a0eeef))
* **deps:** update dependency chroma-js to ^3.2.0 ([#4585](https://github.com/homarr-labs/homarr/issues/4585)) ([b2c46d3](https://github.com/homarr-labs/homarr/commit/b2c46d33d6cc769e89e208fd29d3a1d143cf74c7))
* **deps:** update dependency isomorphic-dompurify to ^2.33.0 ([#4581](https://github.com/homarr-labs/homarr/issues/4581)) ([ca01a31](https://github.com/homarr-labs/homarr/commit/ca01a31fe5cbce53eb0e6bd1a943320c092161ef))
* **deps:** update dependency next-intl to v4.5.6 ([#4571](https://github.com/homarr-labs/homarr/issues/4571)) ([3062dda](https://github.com/homarr-labs/homarr/commit/3062ddafbe0bc1dbac9259af4036f0fa32d85237))
* **deps:** update dependency sass to ^1.94.2 ([#4572](https://github.com/homarr-labs/homarr/issues/4572)) ([7a8c50f](https://github.com/homarr-labs/homarr/commit/7a8c50fa4c5224dd74af3c17f56e2e5b8d6a4f43))
* **deps:** update dependency superjson to v2.2.6 ([#4573](https://github.com/homarr-labs/homarr/issues/4573)) ([deb5e9d](https://github.com/homarr-labs/homarr/commit/deb5e9d96092069e296ba473eaad58367b516f85))
* **deps:** update dependency swagger-ui-react to ^5.30.3 ([#4574](https://github.com/homarr-labs/homarr/issues/4574)) ([d2c1dc3](https://github.com/homarr-labs/homarr/commit/d2c1dc3cc1dd72fc9fc8ae9613467fa0b0b8d75a))
* **deps:** update dependency zod to ^4.1.13 ([#4575](https://github.com/homarr-labs/homarr/issues/4575)) ([879a77f](https://github.com/homarr-labs/homarr/commit/879a77ff2a81b0d0a17d1487eaf6d8539a955301))
* **deps:** update mantine monorepo to ^8.3.9 ([#4576](https://github.com/homarr-labs/homarr/issues/4576)) ([d5d59dd](https://github.com/homarr-labs/homarr/commit/d5d59dd2561f0be2f4f4c689f33c6a9a7840a21c))
* **deps:** update nextjs monorepo to v16.0.5 ([#4577](https://github.com/homarr-labs/homarr/issues/4577)) ([16f12d9](https://github.com/homarr-labs/homarr/commit/16f12d98e6cdae50fe2989db0911cb1350fcb93b))
* **deps:** update tanstack-query monorepo ([#4578](https://github.com/homarr-labs/homarr/issues/4578)) ([59bcbc8](https://github.com/homarr-labs/homarr/commit/59bcbc8b4de4a0a8cee8adf6336c7c10477c766a))
* **deps:** update testcontainers-node monorepo to ^11.9.0 ([#4583](https://github.com/homarr-labs/homarr/issues/4583)) ([10bdd74](https://github.com/homarr-labs/homarr/commit/10bdd74b2b287cb08ec0926147ac0e7fcfd492bb))
* **deps:** update trpc monorepo to ^11.7.2 ([#4579](https://github.com/homarr-labs/homarr/issues/4579)) ([3453482](https://github.com/homarr-labs/homarr/commit/3453482ed43644025c39dee8e20549e1beb86be0))
* **security:** rce vulnerability in nextjs ([b40deba](https://github.com/homarr-labs/homarr/commit/b40deba9ff1a3d629b6027565378d9f3ad2f1980))
## [1.45.0](https://github.com/homarr-labs/homarr/compare/v1.44.0...v1.45.0) (2025-11-28)
### Features
* **docker:** hide containers with label homarr.hide ([#4506](https://github.com/homarr-labs/homarr/issues/4506)) ([60ab98a](https://github.com/homarr-labs/homarr/commit/60ab98ae36abe712c825f7828394d3e3e98c888a))
### Bug Fixes
* Add fallback when no icon in Minecraft Server widget ([#4544](https://github.com/homarr-labs/homarr/issues/4544)) ([#4545](https://github.com/homarr-labs/homarr/issues/4545)) ([99949fe](https://github.com/homarr-labs/homarr/commit/99949fe095ac5a3616c8e9c1964d7eb253c9f826))
* **deps:** update dependency @tanstack/react-query to ^5.90.10 ([#4523](https://github.com/homarr-labs/homarr/issues/4523)) ([e87170a](https://github.com/homarr-labs/homarr/commit/e87170ae6e56cdbeef52e943353060329c39bdc9))
* **deps:** update dependency glob to ^11.1.0 ([#4529](https://github.com/homarr-labs/homarr/issues/4529)) ([24c9854](https://github.com/homarr-labs/homarr/commit/24c985424ecc795eb96b56881a9b00c0c37386c1))
* **deps:** update dependency glob to v12 ([#4530](https://github.com/homarr-labs/homarr/issues/4530)) ([18a6bfd](https://github.com/homarr-labs/homarr/commit/18a6bfd69d86de8c58dbfe6dc8b8fab78b2b5ee6))
* **deps:** update dependency next-intl to v4.5.4 ([#4540](https://github.com/homarr-labs/homarr/issues/4540)) ([77a86ea](https://github.com/homarr-labs/homarr/commit/77a86ead41c0d098987561249203667ac4d88177))
* **deps:** update dependency next-intl to v4.5.5 ([#4542](https://github.com/homarr-labs/homarr/issues/4542)) ([2bc6964](https://github.com/homarr-labs/homarr/commit/2bc6964f7efb5203f626d2f07b847dffd53191f0))
* **deps:** update dependency sass to ^1.94.1 ([#4531](https://github.com/homarr-labs/homarr/issues/4531)) ([292e36f](https://github.com/homarr-labs/homarr/commit/292e36fec5acff9b1d143f19e18ea170c87fa0d0))
* **deps:** update dependency zod-validation-error to v5 ([#4437](https://github.com/homarr-labs/homarr/issues/4437)) ([9a3feb4](https://github.com/homarr-labs/homarr/commit/9a3feb404c0c284b4f33fce12d87a469741a6ebd))
* **security:** restrict modification of entrypoint script ([#4555](https://github.com/homarr-labs/homarr/issues/4555)) ([524e1a4](https://github.com/homarr-labs/homarr/commit/524e1a485be56dbebf8f71d4546bc65672737f30))
## [1.44.0](https://github.com/homarr-labs/homarr/compare/v1.43.3...v1.44.0) (2025-11-21)
### Features
* **pi-hole:** support no-auth ([#4480](https://github.com/homarr-labs/homarr/issues/4480)) ([c89e35e](https://github.com/homarr-labs/homarr/commit/c89e35e13c794bbdf98748c00644b86f7f5dbe68))
### Bug Fixes
* **deps:** update dependency @tanstack/react-query to ^5.90.8 ([#4494](https://github.com/homarr-labs/homarr/issues/4494)) ([a5b6203](https://github.com/homarr-labs/homarr/commit/a5b6203be6ac3c2308614f10ef6a17590917e2c9))
* **deps:** update dependency @tanstack/react-query to ^5.90.9 ([#4508](https://github.com/homarr-labs/homarr/issues/4508)) ([b3db5d5](https://github.com/homarr-labs/homarr/commit/b3db5d5f7bc2d146f0b2c230a52e7bd4efad3bcb))
* **deps:** update dependency @tanstack/react-query-next-experimental to ^5.91.0 ([#4505](https://github.com/homarr-labs/homarr/issues/4505)) ([8ea6cff](https://github.com/homarr-labs/homarr/commit/8ea6cffb537ca54a413c583ab8b8fd24a52185be))
* **deps:** update dependency drizzle-kit to ^0.31.7 ([#4507](https://github.com/homarr-labs/homarr/issues/4507)) ([b4f9fb8](https://github.com/homarr-labs/homarr/commit/b4f9fb8b46a8f74e2d7896dfe98e80618cfbcde4))
* **deps:** update dependency fast-xml-parser to ^5.3.2 ([#4510](https://github.com/homarr-labs/homarr/issues/4510)) ([5e57a49](https://github.com/homarr-labs/homarr/commit/5e57a4906bcedc53d220e983827293f4a699c425))
* **deps:** update dependency next-intl to v4.5.1 ([#4484](https://github.com/homarr-labs/homarr/issues/4484)) ([06942ec](https://github.com/homarr-labs/homarr/commit/06942ecbcd245f5540f2960f437ca2955a5ed0c3))
* **deps:** update dependency next-intl to v4.5.3 ([#4503](https://github.com/homarr-labs/homarr/issues/4503)) ([0642773](https://github.com/homarr-labs/homarr/commit/064277373cacd3309d8da3779d5451d195da7f81))
* **deps:** update dependency sass to ^1.94.0 ([#4482](https://github.com/homarr-labs/homarr/issues/4482)) ([19ecede](https://github.com/homarr-labs/homarr/commit/19ecedea4370924d47545ca8d9d46a0b7c016cc9))
* **deps:** update mantine monorepo to ^8.3.8 ([#4516](https://github.com/homarr-labs/homarr/issues/4516)) ([ded4e72](https://github.com/homarr-labs/homarr/commit/ded4e72e5407b0076495a06111f3b04445f27276))
* **deps:** update nextjs monorepo to v16.0.3 ([#4504](https://github.com/homarr-labs/homarr/issues/4504)) ([7d0c1a1](https://github.com/homarr-labs/homarr/commit/7d0c1a14fdf1731ff44e3d00793cf4cd1c3e9b1f))
* **deps:** update testcontainers-node monorepo to ^11.8.1 ([#4486](https://github.com/homarr-labs/homarr/issues/4486)) ([64657d8](https://github.com/homarr-labs/homarr/commit/64657d831cbe28a59708b280b07889b9f0232743))
* **deps:** update turbo monorepo to ^2.6.1 ([#4483](https://github.com/homarr-labs/homarr/issues/4483)) ([cd124d6](https://github.com/homarr-labs/homarr/commit/cd124d6e8392eef5df0092481ec3cc26599f2902))
* **iframe:** allow clicking links within ([#4521](https://github.com/homarr-labs/homarr/issues/4521)) ([5a418d7](https://github.com/homarr-labs/homarr/commit/5a418d73bdb07cf3d3270983b6881f2de8d58ad7))
* **media-requests:** incorrect availability mapping ([#4520](https://github.com/homarr-labs/homarr/issues/4520)) ([d9cc35b](https://github.com/homarr-labs/homarr/commit/d9cc35b9859a14f44c4e4b13c6518287f8d18e54))
## [1.43.3](https://github.com/homarr-labs/homarr/compare/v1.43.2...v1.43.3) (2025-11-14)
### Bug Fixes
* **deps:** update dependency @ctrl/qbittorrent to ^9.11.0 ([#4456](https://github.com/homarr-labs/homarr/issues/4456)) ([ddfed18](https://github.com/homarr-labs/homarr/commit/ddfed18acf44596dba15ea0ef56233c4936f9775))
* **deps:** update dependency @tanstack/react-query to ^5.90.7 ([#4451](https://github.com/homarr-labs/homarr/issues/4451)) ([7bc2f87](https://github.com/homarr-labs/homarr/commit/7bc2f87f31f1babe691fa4a086a3897977f2d871))
* **deps:** update dependency fast-xml-parser to ^5.3.1 ([#4435](https://github.com/homarr-labs/homarr/issues/4435)) ([65f2e82](https://github.com/homarr-labs/homarr/commit/65f2e825fdb9e5e79b814c9b49f663d1afac784d))
* **deps:** update dependency fastify to ^5.6.2 ([#4471](https://github.com/homarr-labs/homarr/issues/4471)) ([e7071bf](https://github.com/homarr-labs/homarr/commit/e7071bf2bf6a45ff760cd3e7bd06382d2ed66cdc))
* **deps:** update dependency next-intl to v4.5.0 ([#4462](https://github.com/homarr-labs/homarr/issues/4462)) ([51ce5da](https://github.com/homarr-labs/homarr/commit/51ce5da45bdccf061e593097ed751cf09d663437))
* **deps:** update dependency swagger-ui-react to ^5.30.2 ([#4442](https://github.com/homarr-labs/homarr/issues/4442)) ([d3edfcf](https://github.com/homarr-labs/homarr/commit/d3edfcf3dca3d34afd5ef8ec21599cd08fde5092))
* **deps:** update mantine monorepo to ^8.3.7 ([#4472](https://github.com/homarr-labs/homarr/issues/4472)) ([8a87dba](https://github.com/homarr-labs/homarr/commit/8a87dbad59786fa9789dd3efb8d9424bb950e977))
* **deps:** update testcontainers-node monorepo to ^11.8.0 ([#4450](https://github.com/homarr-labs/homarr/issues/4450)) ([f648af0](https://github.com/homarr-labs/homarr/commit/f648af0e2b2b5d5f8180402c2734ea0c04559daa))
* **stock-price:** ignore missing data points in price history ([#4429](https://github.com/homarr-labs/homarr/issues/4429)) ([c30c98b](https://github.com/homarr-labs/homarr/commit/c30c98b153fbec21551e45aedf83e0ae29d6e773))
* **users:** next button in create form always disabled ([#4443](https://github.com/homarr-labs/homarr/issues/4443)) ([1c1f8a4](https://github.com/homarr-labs/homarr/commit/1c1f8a48d259c65ebeeec6856e1fe339defb4aaf))
## [1.43.2](https://github.com/homarr-labs/homarr/compare/v1.43.1...v1.43.2) (2025-11-07)
### Bug Fixes
* **deps:** update dependency @ctrl/deluge to ^7.5.0 ([#4407](https://github.com/homarr-labs/homarr/issues/4407)) ([57d1a91](https://github.com/homarr-labs/homarr/commit/57d1a9186653dd4c327b360a3bdaa78fd8e1187b))
* **deps:** update dependency @gitbeaker/rest to ^43.7.0 ([#4386](https://github.com/homarr-labs/homarr/issues/4386)) ([dcf960f](https://github.com/homarr-labs/homarr/commit/dcf960fa97011c24475f303d587152b42eabec45))
* **deps:** update dependency @gitbeaker/rest to ^43.8.0 ([#4425](https://github.com/homarr-labs/homarr/issues/4425)) ([4516f27](https://github.com/homarr-labs/homarr/commit/4516f27fa69445e5aec16760e1f6ed8080bc8fff))
* **deps:** update dependency @jellyfin/sdk to ^0.13.0 ([#4399](https://github.com/homarr-labs/homarr/issues/4399)) ([4c4e901](https://github.com/homarr-labs/homarr/commit/4c4e901e7d38faf83a4725b7cee5526b0b223dc3))
* **deps:** update dependency @octokit/auth-app to ^8.1.2 ([#4412](https://github.com/homarr-labs/homarr/issues/4412)) ([018a33b](https://github.com/homarr-labs/homarr/commit/018a33b07812fa59f1469ce8b4baa7b1d55c6103))
* **deps:** update dependency @tanstack/react-query to ^5.90.6 ([#4427](https://github.com/homarr-labs/homarr/issues/4427)) ([5f9054b](https://github.com/homarr-labs/homarr/commit/5f9054b162daf974baafdbee9f844b3a860cbdd0))
* **deps:** update dependency dayjs to ^1.11.19 ([#4414](https://github.com/homarr-labs/homarr/issues/4414)) ([97cbade](https://github.com/homarr-labs/homarr/commit/97cbade7135cb06e0780dd1b448c78c8802794ea))
* **deps:** update dependency drizzle-kit to ^0.31.6 ([#4397](https://github.com/homarr-labs/homarr/issues/4397)) ([59434ee](https://github.com/homarr-labs/homarr/commit/59434ee33ae16e06f96e2f07cf85337c313c73f6))
* **deps:** update dependency jotai to ^2.15.1 ([#4426](https://github.com/homarr-labs/homarr/issues/4426)) ([07af9d8](https://github.com/homarr-labs/homarr/commit/07af9d8673ea9573bc436626cd84d11980d023bc))
* **deps:** update dependency octokit to ^5.0.5 ([#4413](https://github.com/homarr-labs/homarr/issues/4413)) ([186e3e4](https://github.com/homarr-labs/homarr/commit/186e3e445dfe6b4fb1aeda3830ae1f260b605882))
* **deps:** update dependency sass to ^1.93.3 ([#4421](https://github.com/homarr-labs/homarr/issues/4421)) ([f216427](https://github.com/homarr-labs/homarr/commit/f2164272a5ca9b51bdf9110664ed5a40b87b60f6))
* **deps:** update dependency superjson to v2.2.5 ([#4398](https://github.com/homarr-labs/homarr/issues/4398)) ([19e25a0](https://github.com/homarr-labs/homarr/commit/19e25a095fb0252e8f2a459e0a97d44a37d2188a))
* **deps:** update dependency swagger-ui-react to ^5.30.0 ([#4391](https://github.com/homarr-labs/homarr/issues/4391)) ([b51e285](https://github.com/homarr-labs/homarr/commit/b51e285c92ef707076f321f0ce1a15d5cbd5de7d))
* **deps:** update dependency swagger-ui-react to ^5.30.1 ([#4418](https://github.com/homarr-labs/homarr/issues/4418)) ([d9b14db](https://github.com/homarr-labs/homarr/commit/d9b14db6a1af515796951a1db670431d10f81eaf))
* **deps:** update dependency tsdav to ^2.1.6 ([#4417](https://github.com/homarr-labs/homarr/issues/4417)) ([160c20a](https://github.com/homarr-labs/homarr/commit/160c20a9a6f850f75537e246f42e93f9a2ed79a0))
* **deps:** update mantine monorepo to ^8.3.6 ([#4403](https://github.com/homarr-labs/homarr/issues/4403)) ([9e2bbb8](https://github.com/homarr-labs/homarr/commit/9e2bbb8a3f2db95c5598e5dca993bf6cd4ebc127))
* **deps:** update nextjs monorepo to v16 (major) ([#4363](https://github.com/homarr-labs/homarr/issues/4363)) ([6ce23a6](https://github.com/homarr-labs/homarr/commit/6ce23a6e971b064292970fc4df90cc69cdb59a95))
* **deps:** update tiptap monorepo to v2.27.0 ([#4404](https://github.com/homarr-labs/homarr/issues/4404)) ([f4caddf](https://github.com/homarr-labs/homarr/commit/f4caddfd564553014854347eb6dd14cc800eb027))
* **deps:** update tiptap monorepo to v2.27.1 ([#4405](https://github.com/homarr-labs/homarr/issues/4405)) ([d34f9e5](https://github.com/homarr-labs/homarr/commit/d34f9e5b3ef999559a4c5f1165488fe4f8828a83))
* **deps:** update trpc monorepo to ^11.7.1 ([#4396](https://github.com/homarr-labs/homarr/issues/4396)) ([5aca5d1](https://github.com/homarr-labs/homarr/commit/5aca5d1b0a76ab4cf0ed27dac62183c766ad398a))
* **deps:** update turbo monorepo to ^2.6.0 ([#4422](https://github.com/homarr-labs/homarr/issues/4422)) ([742ef66](https://github.com/homarr-labs/homarr/commit/742ef66e3cf56fd351c8dee2d3dd05cd639e51fa))
## [1.43.1](https://github.com/homarr-labs/homarr/compare/v1.43.0...v1.43.1) (2025-10-31)
### Bug Fixes
* **deps:** update dependency @auth/core to ^0.41.1 ([#4387](https://github.com/homarr-labs/homarr/issues/4387)) ([747bb92](https://github.com/homarr-labs/homarr/commit/747bb922ccf0508bd00c37faeab29e28876577b1))
* **deps:** update dependency @auth/drizzle-adapter to ^1.11.1 ([#4388](https://github.com/homarr-labs/homarr/issues/4388)) ([2fe3656](https://github.com/homarr-labs/homarr/commit/2fe36564c26c33ae2625eb22ef4503c6dd8ebcf9))
* **deps:** update dependency @jellyfin/sdk to ^0.12.0 ([#4359](https://github.com/homarr-labs/homarr/issues/4359)) ([554d19a](https://github.com/homarr-labs/homarr/commit/554d19a458e856141f90e795ecebabf205e945e9))
* **deps:** update dependency @paralleldrive/cuid2 to v3 ([#4343](https://github.com/homarr-labs/homarr/issues/4343)) ([074d27e](https://github.com/homarr-labs/homarr/commit/074d27e37e3430e7e98cf28e2876afe009811027))
* **deps:** update dependency drizzle-orm to ^0.44.7 ([#4372](https://github.com/homarr-labs/homarr/issues/4372)) ([8242bfc](https://github.com/homarr-labs/homarr/commit/8242bfc95cd0e67397b1bfc46d65aec3f568c304))
* **deps:** update dependency ioredis to v5.8.2 ([#4357](https://github.com/homarr-labs/homarr/issues/4357)) ([3c4c26e](https://github.com/homarr-labs/homarr/commit/3c4c26ee214a37193aea31b69ce75322862fc534))
* **deps:** update dependency mysql2 to v3.15.3 ([#4360](https://github.com/homarr-labs/homarr/issues/4360)) ([6e6c912](https://github.com/homarr-labs/homarr/commit/6e6c9122257934402848d6fdc51e6ccdfc2dcca0))
* **deps:** update dependency next-auth to v5.0.0-beta.30 [security] ([#4379](https://github.com/homarr-labs/homarr/issues/4379)) ([c544d6e](https://github.com/homarr-labs/homarr/commit/c544d6ec2e426bc4c82db547d7c4a5dc4d6e2a27))
* **deps:** update dependency next-intl to v4.4.0 ([#4365](https://github.com/homarr-labs/homarr/issues/4365)) ([ce63388](https://github.com/homarr-labs/homarr/commit/ce6338840c20fc46048687ed5566ff12fa4b2502))
* **deps:** update dependency node-ical to ^0.22.1 ([#4346](https://github.com/homarr-labs/homarr/issues/4346)) ([ef18c58](https://github.com/homarr-labs/homarr/commit/ef18c58f5b09bafd697365a0182ab7bc8719db2b))
* **deps:** update dependency superjson to v2.2.3 ([#4364](https://github.com/homarr-labs/homarr/issues/4364)) ([18cc04e](https://github.com/homarr-labs/homarr/commit/18cc04e7f2740226f7bc7c75c0b0cdaec7cda6f8))
* **deps:** update dependency typescript-eslint to ^8.46.2 ([#4352](https://github.com/homarr-labs/homarr/issues/4352)) ([f96cbe0](https://github.com/homarr-labs/homarr/commit/f96cbe06525515112fad466cb8a5f33d74517aba))
* **deps:** update testcontainers-node monorepo to ^11.7.2 ([#4366](https://github.com/homarr-labs/homarr/issues/4366)) ([7329135](https://github.com/homarr-labs/homarr/commit/7329135fd85906602a16a9bdc16a1ef1cc4607c5))
* **deps:** update tiptap monorepo to v2.26.4 ([#4371](https://github.com/homarr-labs/homarr/issues/4371)) ([136ed8e](https://github.com/homarr-labs/homarr/commit/136ed8e8b401b801ba16f2079bdfb5aeebe9f57f))
* **deps:** update trpc monorepo to ^11.7.0 ([#4385](https://github.com/homarr-labs/homarr/issues/4385)) ([24def99](https://github.com/homarr-labs/homarr/commit/24def9982709cd6de1765a7235169fe1ceb3cbea))
* **media-releases:** support more media type mappings for jellyfin and emby ([#4382](https://github.com/homarr-labs/homarr/issues/4382)) ([6f3b7ec](https://github.com/homarr-labs/homarr/commit/6f3b7ec4915754e183300a915baebc11f264df62))
* **releases-widget:** Search multiple docker hub pages for releases ([#4158](https://github.com/homarr-labs/homarr/issues/4158)) ([e0526c5](https://github.com/homarr-labs/homarr/commit/e0526c5ea7ee83adcd22d78fbf63334cb59bcf79))
## [1.43.0](https://github.com/homarr-labs/homarr/compare/v1.42.1...v1.43.0) (2025-10-24)
### Features
* **integrations:** add app linking ([#4338](https://github.com/homarr-labs/homarr/issues/4338)) ([172db0e](https://github.com/homarr-labs/homarr/commit/172db0e3f905839b01e934a121c5bc5e45f3314a))
### Bug Fixes
* **deps:** update dependency @tanstack/react-query to ^5.90.5 ([#4316](https://github.com/homarr-labs/homarr/issues/4316)) ([4cab12b](https://github.com/homarr-labs/homarr/commit/4cab12b80a4a37a20393ed8a3727997e157405d3))
* **deps:** update dependency node-ical to ^0.22.0 ([#4344](https://github.com/homarr-labs/homarr/issues/4344)) ([7281b4a](https://github.com/homarr-labs/homarr/commit/7281b4ae32f6b86d3a1c6666db84419387b496a5))
* **deps:** update dependency octokit to ^5.0.4 ([#4340](https://github.com/homarr-labs/homarr/issues/4340)) ([bd98370](https://github.com/homarr-labs/homarr/commit/bd983701b7d4eea15c81e7d6482f1390b98a35fb))
* **deps:** update dependency swagger-ui-react to ^5.29.5 ([#4335](https://github.com/homarr-labs/homarr/issues/4335)) ([fb4b8f7](https://github.com/homarr-labs/homarr/commit/fb4b8f7ca3cc3c11392dc1665be2ad907d15772e))
* **deps:** update mantine monorepo to ^8.3.5 ([#4291](https://github.com/homarr-labs/homarr/issues/4291)) ([63c5c9c](https://github.com/homarr-labs/homarr/commit/63c5c9ca9846d6c11cc44372366a68d3d46ee57c))
* **deps:** update nextjs monorepo to v15.5.6 ([#4314](https://github.com/homarr-labs/homarr/issues/4314)) ([0df6e8f](https://github.com/homarr-labs/homarr/commit/0df6e8fb20e59457e7c12d123ba7f948619062e1))
## [1.42.1](https://github.com/homarr-labs/homarr/compare/v1.42.0...v1.42.1) (2025-10-18)
### Bug Fixes
+2 -2
View File
@@ -1,4 +1,4 @@
FROM node:22.20.0-alpine AS base
FROM node:24.11.1-alpine AS base
FROM base AS builder
RUN apk add --no-cache libc6-compat
@@ -55,7 +55,7 @@ COPY --from=builder /app/apps/nextjs/.next/standalone ./
COPY --from=builder /app/apps/nextjs/.next/static ./apps/nextjs/.next/static
COPY --from=builder /app/apps/nextjs/public ./apps/nextjs/public
COPY scripts/run.sh ./run.sh
COPY --chmod=777 scripts/entrypoint.sh ./entrypoint.sh
COPY --chmod=755 scripts/entrypoint.sh ./entrypoint.sh
COPY packages/redis/redis.conf /app/redis.conf
COPY nginx.conf /etc/nginx/templates/nginx.conf
+11 -4
View File
@@ -20,19 +20,26 @@ const withNextIntl = createNextIntlPlugin({
const nextConfig: NextConfig = {
output: "standalone",
reactStrictMode: true,
/** We already do linting and typechecking as separate tasks in CI */
eslint: { ignoreDuringBuilds: true },
reactCompiler: true,
/** We already do typechecking as separate tasks in CI */
typescript: { ignoreBuildErrors: true },
/**
* dockerode is required in the external server packages because of https://github.com/homarr-labs/homarr/issues/612
* isomorphic-dompurify and jsdom are required, see https://github.com/kkomelin/isomorphic-dompurify/issues/356
*/
serverExternalPackages: ["dockerode"],
serverExternalPackages: ["dockerode", "isomorphic-dompurify", "jsdom"],
experimental: {
optimizePackageImports: ["@mantine/core", "@mantine/hooks", "@tabler/icons-react"],
turbopackFileSystemCacheForDev: true,
},
transpilePackages: ["@homarr/ui", "@homarr/notifications", "@homarr/modals", "@homarr/spotlight", "@homarr/widgets"],
images: {
domains: ["cdn.jsdelivr.net"],
localPatterns: [
{
pathname: "/**",
search: "",
},
],
},
// eslint-disable-next-line @typescript-eslint/require-await,no-restricted-syntax
async headers() {
+29 -27
View File
@@ -50,57 +50,59 @@
"@homarr/ui": "workspace:^0.1.0",
"@homarr/validation": "workspace:^0.1.0",
"@homarr/widgets": "workspace:^0.1.0",
"@mantine/colors-generator": "^8.3.4",
"@mantine/core": "^8.3.4",
"@mantine/dropzone": "^8.3.4",
"@mantine/hooks": "^8.3.4",
"@mantine/modals": "^8.3.4",
"@mantine/tiptap": "^8.3.4",
"@mantine/colors-generator": "^8.3.9",
"@mantine/core": "^8.3.9",
"@mantine/dropzone": "^8.3.9",
"@mantine/hooks": "^8.3.9",
"@mantine/modals": "^8.3.9",
"@mantine/tiptap": "^8.3.9",
"@million/lint": "1.0.14",
"@tabler/icons-react": "^3.35.0",
"@tanstack/react-query": "^5.90.2",
"@tanstack/react-query-devtools": "^5.90.2",
"@tanstack/react-query-next-experimental": "^5.90.2",
"@trpc/client": "^11.6.0",
"@trpc/next": "^11.6.0",
"@trpc/react-query": "^11.6.0",
"@trpc/server": "^11.6.0",
"@tanstack/react-query": "^5.90.11",
"@tanstack/react-query-devtools": "^5.91.1",
"@tanstack/react-query-next-experimental": "^5.91.0",
"@trpc/client": "^11.7.2",
"@trpc/next": "^11.7.2",
"@trpc/react-query": "^11.7.2",
"@trpc/server": "^11.7.2",
"@xterm/addon-canvas": "^0.7.0",
"@xterm/addon-fit": "0.10.0",
"@xterm/xterm": "^5.5.0",
"chroma-js": "^3.1.2",
"babel-plugin-react-compiler": "^1.0.0",
"chroma-js": "^3.2.0",
"clsx": "^2.1.1",
"dayjs": "^1.11.18",
"dayjs": "^1.11.19",
"dotenv": "^17.2.3",
"flag-icons": "^7.5.0",
"glob": "^11.0.3",
"jotai": "^2.15.0",
"glob": "^12.0.0",
"isomorphic-dompurify": "^2.33.0",
"jotai": "^2.15.1",
"mantine-react-table": "2.0.0-beta.9",
"next": "15.5.5",
"next": "16.0.7",
"postcss-preset-mantine": "^1.18.0",
"prismjs": "^1.30.0",
"react": "19.2.0",
"react-dom": "19.2.0",
"react-error-boundary": "^6.0.0",
"react-simple-code-editor": "^0.14.1",
"sass": "^1.93.2",
"superjson": "2.2.2",
"swagger-ui-react": "^5.29.4",
"sass": "^1.94.2",
"superjson": "2.2.6",
"swagger-ui-react": "^5.30.3",
"use-deep-compare-effect": "^1.8.1",
"zod": "^4.1.12"
"zod": "^4.1.13"
},
"devDependencies": {
"@homarr/eslint-config": "workspace:^0.2.0",
"@homarr/prettier-config": "workspace:^0.1.0",
"@homarr/tsconfig": "workspace:^0.1.0",
"@types/chroma-js": "3.1.1",
"@types/node": "^22.18.10",
"@types/chroma-js": "3.1.2",
"@types/node": "^24.10.1",
"@types/prismjs": "^1.26.5",
"@types/react": "19.2.2",
"@types/react-dom": "19.2.2",
"@types/react": "19.2.7",
"@types/react-dom": "19.2.3",
"@types/swagger-ui-react": "^5.18.0",
"concurrently": "^9.2.1",
"eslint": "^9.37.0",
"eslint": "^9.39.1",
"node-loader": "^2.1.0",
"prettier": "^3.6.2",
"typescript": "^5.9.3"
@@ -1,7 +1,6 @@
"use client";
import { useCallback, useEffect } from "react";
import Link from "next/link";
import { useRouter } from "next/navigation";
import { Group, Menu, ScrollArea } from "@mantine/core";
import { useHotkeys } from "@mantine/hooks";
@@ -19,6 +18,7 @@ import {
} from "@tabler/icons-react";
import { clientApi } from "@homarr/api/client";
import { useSession } from "@homarr/auth/client";
import { useRequiredBoard } from "@homarr/boards/context";
import { useEditMode } from "@homarr/boards/edit-mode";
import { revalidatePathActionAsync } from "@homarr/common/client";
@@ -28,6 +28,7 @@ import { useConfirmModal, useModalAction } from "@homarr/modals";
import { AppSelectModal } from "@homarr/modals-collection";
import { showErrorNotification, showSuccessNotification } from "@homarr/notifications";
import { useI18n, useScopedI18n } from "@homarr/translation/client";
import { Link } from "@homarr/ui";
import { useItemActions } from "~/components/board/items/item-actions";
import { ItemSelectModal } from "~/components/board/items/item-select-modal";
@@ -62,6 +63,7 @@ export const BoardContentHeaderActions = () => {
};
const AddMenu = () => {
const { data: session } = useSession();
const { openModal: openCategoryEditModal } = useModalAction(CategoryEditModal);
const { openModal: openItemSelectModal } = useModalAction(ItemSelectModal);
const { openModal: openAppSelectModal } = useModalAction(AppSelectModal);
@@ -96,12 +98,13 @@ const AddMenu = () => {
const handleSelectApp = useCallback(() => {
openAppSelectModal({
onSelect: (appId) => {
onSelect: (app) => {
createItem({
kind: "app",
options: { appId },
options: { appId: app.id },
});
},
withCreate: session?.user.permissions.includes("app-create") ?? false,
});
}, [openAppSelectModal, createItem]);
@@ -1,4 +1,3 @@
import Link from "next/link";
import type { MantineColor } from "@mantine/core";
import { Button, Card, Stack, Text } from "@mantine/core";
import { IconBook2, IconCategoryPlus, IconLayoutDashboard, IconMailForward } from "@tabler/icons-react";
@@ -8,6 +7,7 @@ import { getMantineColor } from "@homarr/common";
import { db } from "@homarr/db";
import { createDocumentationLink } from "@homarr/definitions";
import { getScopedI18n } from "@homarr/translation/server";
import { Link } from "@homarr/ui";
import type { TablerIcon } from "@homarr/ui";
export const InitFinish = async () => {
@@ -1,5 +1,4 @@
import { Fragment } from "react";
import Link from "next/link";
import { redirect } from "next/navigation";
import { ActionIcon, ActionIconGroup, Anchor, Avatar, Card, Group, Stack, Text, Title } from "@mantine/core";
import { IconBox, IconPencil } from "@tabler/icons-react";
@@ -10,7 +9,7 @@ import { api } from "@homarr/api/server";
import { auth } from "@homarr/auth/next";
import type { inferSearchParamsFromSchema } from "@homarr/common/types";
import { getI18n, getScopedI18n } from "@homarr/translation/server";
import { SearchInput, TablePagination } from "@homarr/ui";
import { Link, SearchInput, TablePagination } from "@homarr/ui";
import { ManageContainer } from "~/components/manage/manage-container";
import { MobileAffixButton } from "~/components/manage/mobile-affix-button";
@@ -1,7 +1,6 @@
"use client";
import { useCallback } from "react";
import Link from "next/link";
import { Menu } from "@mantine/core";
import { IconCopy, IconDeviceMobile, IconHome, IconSettings, IconTrash } from "@tabler/icons-react";
@@ -12,6 +11,7 @@ import { revalidatePathActionAsync } from "@homarr/common/client";
import { useConfirmModal, useModalAction } from "@homarr/modals";
import { DuplicateBoardModal } from "@homarr/modals-collection";
import { useScopedI18n } from "@homarr/translation/client";
import { Link } from "@homarr/ui";
import { useBoardPermissions } from "~/components/board/permissions/client";
@@ -1,4 +1,3 @@
import Link from "next/link";
import {
ActionIcon,
Badge,
@@ -21,7 +20,7 @@ import type { RouterOutputs } from "@homarr/api";
import { api } from "@homarr/api/server";
import { auth } from "@homarr/auth/next";
import { getScopedI18n } from "@homarr/translation/server";
import { UserAvatar } from "@homarr/ui";
import { Link, UserAvatar } from "@homarr/ui";
import { getBoardPermissionsAsync } from "~/components/board/permissions/server";
import { ManageContainer } from "~/components/manage/manage-container";
@@ -1,20 +1,22 @@
"use client";
import { useState } from "react";
import Link from "next/link";
import { useRouter } from "next/navigation";
import { Alert, Button, Fieldset, Group, Stack, Text, TextInput } from "@mantine/core";
import { IconInfoCircle } from "@tabler/icons-react";
import type { z } from "zod/v4";
import { Alert, Anchor, Button, ButtonGroup, Fieldset, Group, Stack, Text, TextInput } from "@mantine/core";
import { IconInfoCircle, IconPencil, IconPlus, IconUnlink } from "@tabler/icons-react";
import { z } from "zod/v4";
import type { RouterOutputs } from "@homarr/api";
import { clientApi } from "@homarr/api/client";
import { useSession } from "@homarr/auth/client";
import { revalidatePathActionAsync } from "@homarr/common/client";
import { getAllSecretKindOptions, getDefaultSecretKinds } from "@homarr/definitions";
import { useZodForm } from "@homarr/form";
import { useConfirmModal } from "@homarr/modals";
import { useConfirmModal, useModalAction } from "@homarr/modals";
import { AppSelectModal } from "@homarr/modals-collection";
import { showErrorNotification, showSuccessNotification } from "@homarr/notifications";
import { useI18n } from "@homarr/translation/client";
import { Link } from "@homarr/ui";
import { integrationUpdateSchema } from "@homarr/validation/integration";
import { SecretCard } from "../../_components/secrets/integration-secret-card";
@@ -27,6 +29,19 @@ interface EditIntegrationForm {
integration: RouterOutputs["integration"]["byId"];
}
const formSchema = integrationUpdateSchema.omit({ id: true, appId: true }).and(
z.object({
app: z
.object({
id: z.string(),
name: z.string(),
iconUrl: z.string(),
href: z.string().nullable(),
})
.nullable(),
}),
);
export const EditIntegrationForm = ({ integration }: EditIntegrationForm) => {
const t = useI18n();
const { openConfirmModal } = useConfirmModal();
@@ -40,7 +55,7 @@ export const EditIntegrationForm = ({ integration }: EditIntegrationForm) => {
const hasUrlSecret = initialSecretsKinds.includes("url");
const router = useRouter();
const form = useZodForm(integrationUpdateSchema.omit({ id: true }), {
const form = useZodForm(formSchema, {
initialValues: {
name: integration.name,
url: integration.url,
@@ -48,6 +63,7 @@ export const EditIntegrationForm = ({ integration }: EditIntegrationForm) => {
kind,
value: integration.secrets.find((secret) => secret.kind === kind)?.value ?? "",
})),
app: integration.app ?? null,
},
});
const { mutateAsync, isPending } = clientApi.integration.update.useMutation();
@@ -55,7 +71,7 @@ export const EditIntegrationForm = ({ integration }: EditIntegrationForm) => {
const secretsMap = new Map(integration.secrets.map((secret) => [secret.kind, secret]));
const handleSubmitAsync = async (values: FormType) => {
const handleSubmitAsync = async ({ app, ...values }: FormType) => {
const url = hasUrlSecret
? new URL(values.secrets.find((secret) => secret.kind === "url")?.value ?? values.url).origin
: values.url;
@@ -68,6 +84,7 @@ export const EditIntegrationForm = ({ integration }: EditIntegrationForm) => {
kind: secret.kind,
value: secret.value === "" ? null : secret.value,
})),
appId: app?.id ?? null,
},
{
onSuccess: (data) => {
@@ -102,7 +119,7 @@ export const EditIntegrationForm = ({ integration }: EditIntegrationForm) => {
form.values.secrets.length === initialSecretsKinds.length;
return (
<form onSubmit={form.onSubmit((values) => void handleSubmitAsync(values))}>
<form onSubmit={form.onSubmit(async (values) => await handleSubmitAsync(values))}>
<Stack>
<TextInput withAsterisk label={t("integration.field.name.label")} {...form.getInputProps("name")} />
@@ -169,6 +186,8 @@ export const EditIntegrationForm = ({ integration }: EditIntegrationForm) => {
</Stack>
</Fieldset>
<IntegrationLinkApp value={form.values.app} onChange={(app) => form.setFieldValue("app", app)} />
{error !== null && <IntegrationTestConnectionError error={error} url={form.values.url} />}
<Group justify="end" align="center">
@@ -184,4 +203,80 @@ export const EditIntegrationForm = ({ integration }: EditIntegrationForm) => {
);
};
type FormType = Omit<z.infer<typeof integrationUpdateSchema>, "id">;
type FormType = z.infer<typeof formSchema>;
interface IntegrationAppSelectProps {
value: FormType["app"];
onChange: (app: FormType["app"]) => void;
}
const IntegrationLinkApp = ({ value, onChange }: IntegrationAppSelectProps) => {
const { openModal } = useModalAction(AppSelectModal);
const t = useI18n();
const { data: session } = useSession();
const canCreateApps = session?.user.permissions.includes("app-create") ?? false;
const handleChange = () =>
openModal(
{
onSelect: onChange,
withCreate: canCreateApps,
},
{
title: t("integration.page.edit.app.action.select"),
},
);
if (!value) {
return (
<Button
variant="subtle"
color="gray"
leftSection={<IconPlus size={16} stroke={1.5} />}
fullWidth
onClick={handleChange}
>
{t("integration.page.edit.app.action.add")}
</Button>
);
}
return (
<Fieldset legend={t("integration.field.app.sectionTitle")}>
<Group justify="space-between">
<Group gap="sm">
{/* eslint-disable-next-line @next/next/no-img-element */}
<img src={value.iconUrl} alt={value.name} width={32} height={32} />
<Stack gap={0}>
<Text size="sm" fw="bold">
{value.name}
</Text>
{value.href !== null && (
<Anchor href={value.href} target="_blank" rel="noopener noreferrer" size="sm">
{value.href}
</Anchor>
)}
</Stack>
</Group>
<ButtonGroup>
<Button
variant="subtle"
color="gray"
leftSection={<IconUnlink size={16} stroke={1.5} />}
onClick={() => onChange(null)}
>
{t("integration.page.edit.app.action.remove")}
</Button>
<Button
variant="subtle"
color="gray"
leftSection={<IconPencil size={16} stroke={1.5} />}
onClick={handleChange}
>
{t("common.action.change")}
</Button>
</ButtonGroup>
</Group>
</Fieldset>
);
};
@@ -2,13 +2,12 @@
import type { ChangeEvent } from "react";
import React, { useMemo, useState } from "react";
import Link from "next/link";
import { Flex, Group, Menu, ScrollArea, Text, TextInput } from "@mantine/core";
import { IconSearch } from "@tabler/icons-react";
import { getIntegrationName, integrationKinds } from "@homarr/definitions";
import { useI18n } from "@homarr/translation/client";
import { IntegrationAvatar } from "@homarr/ui";
import { IntegrationAvatar, Link } from "@homarr/ui";
interface IntegrationCreateDropdownContentProps {
enableMockIntegration: boolean;
@@ -1,14 +1,28 @@
"use client";
import { useState } from "react";
import Link from "next/link";
import { startTransition, useState } from "react";
import { useRouter } from "next/navigation";
import { Alert, Button, Checkbox, Collapse, Fieldset, Group, Stack, Text, TextInput } from "@mantine/core";
import { IconInfoCircle } from "@tabler/icons-react";
import {
Alert,
Button,
Checkbox,
Collapse,
Fieldset,
Group,
Loader,
SegmentedControl,
Select,
Stack,
Text,
TextInput,
} from "@mantine/core";
import { IconCheck, IconInfoCircle } from "@tabler/icons-react";
import { z } from "zod/v4";
import { clientApi } from "@homarr/api/client";
import { useSession } from "@homarr/auth/client";
import { revalidatePathActionAsync } from "@homarr/common/client";
import type { Modify } from "@homarr/common/types";
import type { IntegrationKind } from "@homarr/definitions";
import {
getAllSecretKindOptions,
@@ -17,9 +31,11 @@ import {
getIntegrationName,
integrationDefs,
} from "@homarr/definitions";
import type { GetInputPropsReturnType, UseFormReturnType } from "@homarr/form";
import { useZodForm } from "@homarr/form";
import { showErrorNotification, showSuccessNotification } from "@homarr/notifications";
import { useI18n } from "@homarr/translation/client";
import { Link } from "@homarr/ui";
import { appHrefSchema } from "@homarr/validation/app";
import { integrationCreateSchema } from "@homarr/validation/integration";
@@ -34,10 +50,11 @@ interface NewIntegrationFormProps {
};
}
const formSchema = integrationCreateSchema.omit({ kind: true }).and(
const formSchema = integrationCreateSchema.omit({ kind: true, app: true }).and(
z.object({
createApp: z.boolean(),
hasApp: z.boolean(),
appHref: appHrefSchema,
appId: z.string().nullable(),
}),
);
@@ -46,7 +63,8 @@ export const NewIntegrationForm = ({ searchParams }: NewIntegrationFormProps) =>
const secretKinds = getAllSecretKindOptions(searchParams.kind);
const hasUrlSecret = secretKinds.some((kinds) => kinds.includes("url"));
const router = useRouter();
const [opened, setOpened] = useState(false);
const { data: session } = useSession();
const canCreateApps = session?.user.permissions.includes("app-create") ?? false;
let url = searchParams.url ?? getIntegrationDefaultUrl(searchParams.kind) ?? "";
if (hasUrlSecret) {
@@ -62,31 +80,40 @@ export const NewIntegrationForm = ({ searchParams }: NewIntegrationFormProps) =>
value: "",
})),
attemptSearchEngineCreation: true,
createApp: false,
appHref: "",
},
onValuesChange(values, previous) {
if (values.createApp !== previous.createApp) {
setOpened(values.createApp);
}
hasApp: false,
appHref: url,
appId: null,
},
});
const { mutateAsync: createIntegrationAsync, isPending: isPendingIntegration } =
clientApi.integration.create.useMutation();
const { mutateAsync: createAppAsync, isPending: isPendingApp } = clientApi.app.create.useMutation();
const isPending = isPendingIntegration || isPendingApp;
const { mutateAsync: createIntegrationAsync, isPending } = clientApi.integration.create.useMutation();
const [error, setError] = useState<null | AnyMappedTestConnectionError>(null);
const handleSubmitAsync = async (values: FormType) => {
const handleSubmitAsync = async ({ appId, appHref, hasApp, ...values }: FormType) => {
const url = hasUrlSecret
? new URL(values.secrets.find((secret) => secret.kind === "url")?.value ?? values.url).origin
: values.url;
const hasCustomHref = appHref !== null && appHref.trim().length >= 1;
const app = hasApp
? appId !== null
? { id: appId }
: {
name: values.name,
href: hasCustomHref ? appHref : url,
iconUrl: getIconUrl(searchParams.kind),
description: null,
pingUrl: url,
}
: undefined;
await createIntegrationAsync(
{
kind: searchParams.kind,
...values,
url,
app,
},
{
async onSuccess(data) {
@@ -105,32 +132,7 @@ export const NewIntegrationForm = ({ searchParams }: NewIntegrationFormProps) =>
message: t("integration.page.create.notification.success.message"),
});
if (!values.createApp) {
await revalidatePathActionAsync("/manage/integrations").then(() => router.push("/manage/integrations"));
return;
}
const hasCustomHref = values.appHref !== null && values.appHref.trim().length >= 1;
await createAppAsync(
{
name: values.name,
href: hasCustomHref ? values.appHref : url,
iconUrl: getIconUrl(searchParams.kind),
description: null,
pingUrl: url,
},
{
async onSettled() {
await revalidatePathActionAsync("/manage/integrations").then(() => router.push("/manage/integrations"));
},
onError() {
showErrorNotification({
title: t("app.page.create.notification.error.title"),
message: t("app.page.create.notification.error.message"),
});
},
},
);
await revalidatePathActionAsync("/manage/integrations").then(() => router.push("/manage/integrations"));
},
onError: () => {
showErrorNotification({
@@ -184,15 +186,7 @@ export const NewIntegrationForm = ({ searchParams }: NewIntegrationFormProps) =>
/>
)}
<Checkbox
{...form.getInputProps("createApp", { type: "checkbox" })}
label={t("integration.field.createApp.label")}
description={t("integration.field.createApp.description")}
/>
<Collapse in={opened}>
<TextInput placeholder={t("integration.field.appHref.placeholder")} {...form.getInputProps("appHref")} />
</Collapse>
<AppForm form={form} canCreateApps={canCreateApps} />
<Group justify="end" align="center">
<Button variant="default" component={Link} href="/manage/integrations">
@@ -208,3 +202,114 @@ export const NewIntegrationForm = ({ searchParams }: NewIntegrationFormProps) =>
};
type FormType = z.infer<typeof formSchema>;
const AppForm = ({ form, canCreateApps }: { form: UseFormReturnType<FormType>; canCreateApps: boolean }) => {
const t = useI18n();
const checkboxInputProps = form.getInputProps("hasApp", { type: "checkbox" });
return (
<>
<Checkbox
{...checkboxInputProps}
onChange={(event) => {
startTransition(() => {
form.setFieldValue("appHref", event.currentTarget.checked ? form.values.url : null);
// eslint-disable-next-line @typescript-eslint/no-unsafe-call
checkboxInputProps.onChange(event);
});
}}
label={t("integration.field.createApp.label")}
description={t("integration.field.createApp.description")}
/>
<Collapse in={form.values.hasApp}>
<Fieldset legend={t("integration.field.app.sectionTitle")}>
<Stack gap="sm">
{canCreateApps && (
<SegmentedControl
data={(["new", "existing"] as const).map((value) => ({
value,
label: t(`integration.page.create.app.option.${value}.title`),
}))}
value={form.values.appHref === null ? "existing" : "new"}
onChange={(value) => {
if (value === "existing") {
form.setFieldValue("appId", null);
form.setFieldValue("appHref", null);
} else {
form.setFieldValue("appId", null);
form.setFieldValue("appHref", form.values.url);
}
}}
/>
)}
{typeof form.values.appHref === "string" && canCreateApps ? (
<TextInput
placeholder={t("integration.field.appHref.placeholder")}
withAsterisk
label={t("integration.page.create.app.option.new.url.label")}
description={t("integration.page.create.app.option.new.url.description")}
{...form.getInputProps("appHref")}
/>
) : (
<IntegrationAppSelect {...form.getInputProps("appId")} />
)}
</Stack>
</Fieldset>
</Collapse>
</>
);
};
type IntegrationAppSelectProps = Modify<
GetInputPropsReturnType,
{
value?: string | null;
onChange: (value: string | null) => void;
}
>;
const IntegrationAppSelect = ({ value, ...props }: IntegrationAppSelectProps) => {
const { data, isPending } = clientApi.app.selectable.useQuery();
const t = useI18n();
const appMap = new Map(data?.map((app) => [app.id, app] as const));
return (
<Select
withAsterisk
label={t("integration.page.create.app.option.existing.label")}
searchable
clearable
leftSection={
// eslint-disable-next-line @next/next/no-img-element
value ? <img width={20} height={20} src={appMap.get(value)?.iconUrl} alt={appMap.get(value)?.name} /> : null
}
renderOption={({ option, checked }) => (
<Group flex="1" gap="xs">
{/* eslint-disable-next-line @next/next/no-img-element */}
<img width={20} height={20} src={appMap.get(option.value)?.iconUrl} alt={option.label} />
<Stack gap={0}>
<Text>{option.label}</Text>
<Text size="xs" c="dimmed">
{appMap.get(option.value)?.href}
</Text>
</Stack>
{checked && (
<IconCheck
style={{ marginInlineStart: "auto" }}
stroke={1.5}
color="currentColor"
opacity={0.6}
size={18}
/>
)}
</Group>
)}
{...props}
data={data?.map((app) => ({ value: app.id, label: app.name }))}
rightSection={isPending ? <Loader size="sm" /> : null}
/>
);
};
@@ -1,6 +1,5 @@
import { Fragment } from "react";
import type { PropsWithChildren } from "react";
import Link from "next/link";
import { redirect } from "next/navigation";
import {
AccordionControl,
@@ -36,7 +35,7 @@ import { objectEntries } from "@homarr/common";
import type { IntegrationKind } from "@homarr/definitions";
import { getIntegrationName } from "@homarr/definitions";
import { getScopedI18n } from "@homarr/translation/server";
import { CountBadge, IntegrationAvatar } from "@homarr/ui";
import { CountBadge, IntegrationAvatar, Link } from "@homarr/ui";
import { ManageContainer } from "~/components/manage/manage-container";
import { DynamicBreadcrumb } from "~/components/navigation/dynamic-breadcrumb";
@@ -1,4 +1,3 @@
import Link from "next/link";
import { notFound } from "next/navigation";
import {
ActionIcon,
@@ -25,7 +24,7 @@ import { humanFileSize } from "@homarr/common";
import type { inferSearchParamsFromSchema } from "@homarr/common/types";
import { createLocalImageUrl } from "@homarr/icons/local";
import { getI18n } from "@homarr/translation/server";
import { SearchInput, TablePagination, UserAvatar } from "@homarr/ui";
import { Link, SearchInput, TablePagination, UserAvatar } from "@homarr/ui";
import { ManageContainer } from "~/components/manage/manage-container";
import { DynamicBreadcrumb } from "~/components/navigation/dynamic-breadcrumb";
+1 -1
View File
@@ -1,10 +1,10 @@
import type { Metadata } from "next";
import Link from "next/link";
import { Card, Group, SimpleGrid, Space, Stack, Text } from "@mantine/core";
import { IconArrowRight } from "@tabler/icons-react";
import { api } from "@homarr/api/server";
import { getScopedI18n } from "@homarr/translation/server";
import { Link } from "@homarr/ui";
import { DynamicBreadcrumb } from "~/components/navigation/dynamic-breadcrumb";
import { createMetaTitle } from "~/metadata";
@@ -1,6 +1,5 @@
"use client";
import Link from "next/link";
import type { SegmentedControlItem } from "@mantine/core";
import { Button, Fieldset, Grid, Group, SegmentedControl, Stack, Textarea, TextInput } from "@mantine/core";
import { WidgetIntegrationSelect } from "node_modules/@homarr/widgets/src/widget-integration-select";
@@ -12,6 +11,7 @@ import { useZodForm } from "@homarr/form";
import { IconPicker } from "@homarr/forms-collection";
import type { TranslationFunction } from "@homarr/translation";
import { useI18n } from "@homarr/translation/client";
import { Link } from "@homarr/ui";
import { searchEngineManageSchema } from "@homarr/validation/search-engine";
type FormType = z.infer<typeof searchEngineManageSchema>;
@@ -1,4 +1,3 @@
import Link from "next/link";
import { redirect } from "next/navigation";
import { ActionIcon, ActionIconGroup, Anchor, Avatar, Card, Group, Stack, Text, Title } from "@mantine/core";
import { IconPencil, IconSearch } from "@tabler/icons-react";
@@ -9,7 +8,7 @@ import { api } from "@homarr/api/server";
import { auth } from "@homarr/auth/next";
import type { inferSearchParamsFromSchema } from "@homarr/common/types";
import { getI18n, getScopedI18n } from "@homarr/translation/server";
import { SearchInput, TablePagination } from "@homarr/ui";
import { Link, SearchInput, TablePagination } from "@homarr/ui";
import { ManageContainer } from "~/components/manage/manage-container";
import { MobileAffixButton } from "~/components/manage/mobile-affix-button";
@@ -1,5 +1,4 @@
import { X509Certificate } from "node:crypto";
import Link from "next/link";
import { notFound } from "next/navigation";
import {
Button,
@@ -19,6 +18,7 @@ import { IconCertificateOff } from "@tabler/icons-react";
import { auth } from "@homarr/auth/next";
import { getTrustedCertificateHostnamesAsync } from "@homarr/certificates/server";
import { getI18n } from "@homarr/translation/server";
import { Link } from "@homarr/ui";
import { DynamicBreadcrumb } from "~/components/navigation/dynamic-breadcrumb";
import { NoResults } from "~/components/no-results";
@@ -1,5 +1,4 @@
import { X509Certificate } from "node:crypto";
import Link from "next/link";
import { notFound } from "next/navigation";
import { Button, Card, Group, SimpleGrid, Stack, Text, Title } from "@mantine/core";
import { IconAlertTriangle, IconCertificate, IconCertificateOff } from "@tabler/icons-react";
@@ -10,6 +9,7 @@ import { loadCustomRootCertificatesAsync } from "@homarr/certificates/server";
import { getMantineColor } from "@homarr/common";
import type { SupportedLanguage } from "@homarr/translation";
import { getI18n } from "@homarr/translation/server";
import { Link } from "@homarr/ui";
import { DynamicBreadcrumb } from "~/components/navigation/dynamic-breadcrumb";
import { NoResults } from "~/components/no-results";
@@ -1,10 +1,10 @@
"use client";
import Link from "next/link";
import { Anchor, Center, Stack, Text } from "@mantine/core";
import { IconShipOff } from "@tabler/icons-react";
import { useI18n } from "@homarr/translation/client";
import { Link } from "@homarr/ui";
export default function DockerErrorPage() {
const t = useI18n();
@@ -1,10 +1,10 @@
"use client";
import Link from "next/link";
import { Anchor, Center, Stack, Text } from "@mantine/core";
import { IconCubeOff } from "@tabler/icons-react";
import { useI18n } from "@homarr/translation/client";
import { Link } from "@homarr/ui";
export default function KubernetesErrorPage() {
const t = useI18n();
@@ -1,11 +1,11 @@
import React from "react";
import Image from "next/image";
import Link from "next/link";
import { Card, Group, Text } from "@mantine/core";
import { IconArrowRight } from "@tabler/icons-react";
import type { KubernetesLabelResourceType } from "@homarr/definitions";
import { useI18n } from "@homarr/translation/client";
import { Link } from "@homarr/ui";
import classes from "./resource-tile.module.css";
@@ -1,7 +1,6 @@
"use client";
import { useMemo } from "react";
import Link from "next/link";
import { Anchor, Button, Group, Text, Title, Tooltip } from "@mantine/core";
import { IconCheck } from "@tabler/icons-react";
import type { MRT_ColumnDef } from "mantine-react-table";
@@ -10,7 +9,7 @@ import { MantineReactTable } from "mantine-react-table";
import type { RouterOutputs } from "@homarr/api";
import { clientApi } from "@homarr/api/client";
import { useI18n, useScopedI18n } from "@homarr/translation/client";
import { UserAvatar } from "@homarr/ui";
import { Link, UserAvatar } from "@homarr/ui";
import { useTranslatedMantineReactTable } from "@homarr/ui/hooks";
interface UserListComponentProps {
@@ -1,6 +1,6 @@
"use client";
import { startTransition, useCallback, useMemo, useState } from "react";
import { startTransition, useCallback, useState } from "react";
import {
Badge,
Button,
@@ -20,8 +20,9 @@ import { IconPlus, IconUserCheck } from "@tabler/icons-react";
import { z } from "zod/v4";
import { clientApi } from "@homarr/api/client";
import { everyoneGroup, groupPermissions } from "@homarr/definitions";
import type { GroupPermissionKey } from "@homarr/definitions";
import { everyoneGroup, groupPermissions } from "@homarr/definitions";
import type { IsValid } from "@homarr/form";
import { useZodForm } from "@homarr/form";
import { useModalAction } from "@homarr/modals";
import { showErrorNotification } from "@homarr/notifications";
@@ -113,11 +114,9 @@ export const UserCreateStepperComponent = ({ initialGroups }: UserCreateStepperC
},
);
const allForms = useMemo(() => [generalForm, securityForm, groupsForm], [generalForm, securityForm, groupsForm]);
const activeForm = allForms[active];
const isCurrentFormValid = activeForm ? activeForm.isValid : () => true;
const canNavigateToNextStep = isCurrentFormValid();
const allForms = [generalForm, securityForm, groupsForm];
const isValidCallback: IsValid<unknown> | undefined = allForms[active]?.isValid;
const currentFormValid = isValidCallback?.() ?? true;
const controlledGoToNextStep = useCallback(async () => {
if (active + 1 === stepperMax) {
@@ -218,7 +217,7 @@ export const UserCreateStepperComponent = ({ initialGroups }: UserCreateStepperC
</Stepper.Completed>
</Stepper>
<StepperNavigationComponent
hasNext={hasNext && canNavigateToNextStep}
hasNext={hasNext && currentFormValid}
hasPrevious={hasPrevious}
isComplete={active === stepperMax}
isLoadingNextStep={isPending}
@@ -1,8 +1,8 @@
import Link from "next/link";
import { Button, Card, Group } from "@mantine/core";
import { IconArrowBackUp, IconArrowLeft, IconArrowRight, IconRotate } from "@tabler/icons-react";
import { useI18n } from "@homarr/translation/client";
import { Link } from "@homarr/ui";
interface StepperNavigationComponentProps {
hasPrevious: boolean;
@@ -1,10 +1,11 @@
"use client";
import type { ReactNode } from "react";
import Link from "next/link";
import { usePathname } from "next/navigation";
import { NavLink } from "@mantine/core";
import { Link } from "@homarr/ui";
interface NavigationLinkProps {
href: string;
label: string;
@@ -1,11 +1,11 @@
"use client";
import Link from "next/link";
import { Alert, Anchor } from "@mantine/core";
import { IconExclamationCircle } from "@tabler/icons-react";
import { createDocumentationLink } from "@homarr/definitions";
import { useI18n } from "@homarr/translation/client";
import { Link } from "@homarr/ui";
export const ReservedGroupAlert = () => {
const t = useI18n();
@@ -1,10 +1,10 @@
import type { PropsWithChildren } from "react";
import Link from "next/link";
import { Button, Grid, GridCol, Group, Stack, Text, Title } from "@mantine/core";
import { IconId, IconLock, IconSettings, IconUsersGroup } from "@tabler/icons-react";
import { api } from "@homarr/api/server";
import { getI18n, getScopedI18n } from "@homarr/translation/server";
import { Link } from "@homarr/ui";
import { ManageContainer } from "~/components/manage/manage-container";
import { NavigationLink } from "./_navigation";
@@ -1,4 +1,3 @@
import Link from "next/link";
import { notFound } from "next/navigation";
import { Alert, Anchor, Center, Group, Stack, Table, TableTbody, TableTd, TableTr, Text, Title } from "@mantine/core";
import { IconExclamationCircle } from "@tabler/icons-react";
@@ -10,7 +9,7 @@ import { auth } from "@homarr/auth/next";
import { isProviderEnabled } from "@homarr/auth/server";
import { everyoneGroup } from "@homarr/definitions";
import { getI18n, getScopedI18n } from "@homarr/translation/server";
import { SearchInput, UserAvatar } from "@homarr/ui";
import { Link, SearchInput, UserAvatar } from "@homarr/ui";
import { ReservedGroupAlert } from "../_reserved-group-alert";
import { AddGroupMember } from "./_add-group-member";
@@ -2,7 +2,6 @@
import type { ReactNode } from "react";
import { useMemo, useState } from "react";
import Link from "next/link";
import type { DragEndEvent, DraggableAttributes, DragStartEvent } from "@dnd-kit/core";
import {
closestCenter,
@@ -41,7 +40,7 @@ import { clientApi } from "@homarr/api/client";
import { revalidatePathActionAsync } from "@homarr/common/client";
import { showSuccessNotification } from "@homarr/notifications";
import { useI18n } from "@homarr/translation/client";
import { UserAvatarGroup } from "@homarr/ui";
import { Link, UserAvatarGroup } from "@homarr/ui";
interface GroupsTableProps {
initialGroupIds: string[];
@@ -1,4 +1,3 @@
import Link from "next/link";
import { notFound } from "next/navigation";
import { Card, Group, Stack, Text, ThemeIcon, Title, UnstyledButton } from "@mantine/core";
import { IconChevronRight, IconUsersGroup } from "@tabler/icons-react";
@@ -7,6 +6,7 @@ import { api } from "@homarr/api/server";
import { auth } from "@homarr/auth/next";
import { everyoneGroup } from "@homarr/definitions";
import { getI18n } from "@homarr/translation/server";
import { Link } from "@homarr/ui";
import { ManageContainer } from "~/components/manage/manage-container";
import { DynamicBreadcrumb } from "~/components/navigation/dynamic-breadcrumb";
@@ -1,6 +1,7 @@
import { notFound } from "next/navigation";
import { NextResponse } from "next/server";
import type { NextRequest } from "next/server";
import DOMPurify from "isomorphic-dompurify";
import { db, eq } from "@homarr/db";
import { medias } from "@homarr/db/schema";
@@ -19,11 +20,24 @@ export async function GET(_req: NextRequest, props: { params: Promise<{ id: stri
notFound();
}
let content = new Uint8Array(image.content);
// Sanitize SVG content to prevent XSS attacks
if (image.contentType === "image/svg+xml" || image.contentType === "image/svg") {
const svgText = new TextDecoder().decode(content);
const sanitized = DOMPurify.sanitize(svgText, {
USE_PROFILES: { svg: true, svgFilters: true },
});
content = new TextEncoder().encode(sanitized);
}
const headers = new Headers();
headers.set("Content-Type", image.contentType);
headers.set("Content-Length", image.content.length.toString());
headers.set("Content-Length", content.length.toString());
headers.set("Content-Security-Policy", "default-src 'none'; style-src 'unsafe-inline'; sandbox");
headers.set("X-Content-Type-Options", "nosniff");
return new NextResponse(new Uint8Array(image.content), {
return new NextResponse(content, {
status: 200,
headers,
});
@@ -1,10 +1,10 @@
import { useState } from "react";
import Link from "next/link";
import { Anchor, Button, Group, Stack, Table, TableTbody, TableTh, TableThead, TableTr } from "@mantine/core";
import { IconPlus } from "@tabler/icons-react";
import { useModalAction } from "@homarr/modals";
import { useI18n, useScopedI18n } from "@homarr/translation/client";
import { Link } from "@homarr/ui";
import type { AccessQueryData } from "./access-settings";
import { AccessSelectRow } from "./access-table-rows";
@@ -1,11 +1,10 @@
import { useState } from "react";
import Link from "next/link";
import { Anchor, Box, Button, Group, Stack, Table, TableTbody, TableTh, TableThead, TableTr } from "@mantine/core";
import { IconPlus } from "@tabler/icons-react";
import { useModalAction } from "@homarr/modals";
import { useI18n, useScopedI18n } from "@homarr/translation/client";
import { UserAvatar } from "@homarr/ui";
import { Link, UserAvatar } from "@homarr/ui";
import type { AccessQueryData } from "./access-settings";
import { AccessDisplayRow, AccessSelectRow } from "./access-table-rows";
+1 -1
View File
@@ -1,8 +1,8 @@
import type { ReactNode } from "react";
import Link from "next/link";
import { AppShellHeader, Group, UnstyledButton } from "@mantine/core";
import { Spotlight } from "@homarr/spotlight";
import { Link } from "@homarr/ui";
import { ClientBurger } from "./header/burger";
import { DesktopSearchInput, MobileSearchButton } from "./header/search";
@@ -1,9 +1,10 @@
import type { ForwardedRef, ReactNode } from "react";
import { forwardRef } from "react";
import Link from "next/link";
import type { ActionIconProps } from "@mantine/core";
import { ActionIcon } from "@mantine/core";
import { Link } from "@homarr/ui";
type HeaderButtonProps = (
| {
onClick?: () => void;
@@ -1,10 +1,11 @@
"use client";
import type { ReactNode } from "react";
import Link from "next/link";
import { usePathname } from "next/navigation";
import { NavLink } from "@mantine/core";
import { Link } from "@homarr/ui";
export const CommonNavLink = (props: ClientNavigationLink) =>
"href" in props ? <NavLinkHref {...props} /> : <NavLinkWithItems {...props} />;
@@ -2,7 +2,6 @@
import type { ReactNode } from "react";
import { useCallback, useEffect } from "react";
import Link from "next/link";
import { useRouter } from "next/navigation";
import { Center, Menu, Stack, Text, useMantineColorScheme } from "@mantine/core";
import { useHotkeys, useTimeout } from "@mantine/hooks";
@@ -22,6 +21,7 @@ import { signOut, useSession } from "@homarr/auth/client";
import { hotkeys } from "@homarr/definitions";
import { createModal, useModalAction } from "@homarr/modals";
import { useScopedI18n } from "@homarr/translation/client";
import { Link } from "@homarr/ui";
import { useAuthContext } from "~/app/[locale]/_client-providers/session";
import { CurrentLanguageCombobox } from "./language/current-language-combobox";
@@ -1,10 +1,7 @@
import { NextResponse } from "next/server";
import type { NextRequest } from "next/server";
import { createTRPCClient, httpLink } from "@trpc/client";
import SuperJSON from "superjson";
import { NextResponse } from "next/server";
import type { AppRouter } from "@homarr/api";
import { createHeadersCallbackForSource, getTrpcUrl } from "@homarr/api/shared";
import { api } from "@homarr/api/server";
import { localeCookieKey } from "@homarr/definitions";
import type { SupportedLanguage } from "@homarr/translation";
import { supportedLanguages } from "@homarr/translation";
@@ -12,12 +9,12 @@ import { createI18nMiddleware } from "@homarr/translation/middleware";
let isOnboardingFinished = false;
export async function middleware(request: NextRequest) {
export async function proxy(request: NextRequest) {
// Redirect to onboarding if it's not finished yet
const pathname = request.nextUrl.pathname;
if (!isOnboardingFinished && !pathname.endsWith("/init")) {
const currentOnboardingStep = await serverFetchApi.onboard.currentStep.query();
const currentOnboardingStep = await api.onboard.currentStep();
if (currentOnboardingStep.current !== "finish") {
return NextResponse.redirect(new URL("/init", request.url));
}
@@ -29,11 +26,12 @@ export async function middleware(request: NextRequest) {
const currentLocale = request.cookies.get(localeCookieKey)?.value;
let defaultLocale: SupportedLanguage = "en";
if (!currentLocale || !supportedLanguages.includes(currentLocale as SupportedLanguage)) {
defaultLocale = await serverFetchApi.serverSettings.getCulture.query().then((culture) => culture.defaultLocale);
defaultLocale = await api.serverSettings.getCulture().then((culture) => culture.defaultLocale);
}
// We don't want to fallback to accept-language header so we clear it
request.headers.set("accept-language", "");
const next = createI18nMiddleware(defaultLocale);
return next(request);
}
@@ -41,13 +39,3 @@ export async function middleware(request: NextRequest) {
export const config = {
matcher: ["/((?!api|static|.*\\..*|_next|favicon.ico|robots.txt).*)"],
};
export const serverFetchApi = createTRPCClient<AppRouter>({
links: [
httpLink({
url: getTrpcUrl(),
transformer: SuperJSON,
headers: createHeadersCallbackForSource("server-fetch"),
}),
],
});
+7 -7
View File
@@ -37,20 +37,20 @@
"@homarr/server-settings": "workspace:^0.1.0",
"@homarr/validation": "workspace:^0.1.0",
"@homarr/widgets": "workspace:^0.1.0",
"dayjs": "^1.11.18",
"dayjs": "^1.11.19",
"dotenv": "^17.2.3",
"fastify": "^5.6.1",
"superjson": "2.2.2",
"fastify": "^5.6.2",
"superjson": "2.2.6",
"undici": "7.16.0"
},
"devDependencies": {
"@homarr/eslint-config": "workspace:^0.2.0",
"@homarr/prettier-config": "workspace:^0.1.0",
"@homarr/tsconfig": "workspace:^0.1.0",
"@types/node": "^22.18.10",
"dotenv-cli": "^10.0.0",
"esbuild": "^0.25.10",
"eslint": "^9.37.0",
"@types/node": "^24.10.1",
"dotenv-cli": "^11.0.0",
"esbuild": "^0.27.0",
"eslint": "^9.39.1",
"prettier": "^3.6.2",
"tsx": "4.20.4",
"typescript": "^5.9.3"
+2 -2
View File
@@ -34,8 +34,8 @@
"@homarr/prettier-config": "workspace:^0.1.0",
"@homarr/tsconfig": "workspace:^0.1.0",
"@types/ws": "^8.18.1",
"esbuild": "^0.25.10",
"eslint": "^9.37.0",
"esbuild": "^0.27.0",
"eslint": "^9.39.1",
"prettier": "^3.6.2",
"typescript": "^5.9.3"
}
+23 -21
View File
@@ -1,6 +1,6 @@
{
"name": "homarr",
"version": "1.42.1",
"version": "1.45.1",
"private": true,
"scripts": {
"build": "cross-env CI=true turbo build",
@@ -39,28 +39,30 @@
"@semantic-release/changelog": "^6.0.3",
"@semantic-release/commit-analyzer": "^13.0.1",
"@semantic-release/git": "^10.0.1",
"@semantic-release/github": "^11.0.6",
"@semantic-release/npm": "^12.0.2",
"@semantic-release/github": "^12.0.2",
"@semantic-release/npm": "^13.1.2",
"@semantic-release/release-notes-generator": "^14.1.0",
"@testcontainers/redis": "^11.7.1",
"@turbo/gen": "^2.5.8",
"@vitejs/plugin-react": "^5.0.4",
"@vitest/coverage-v8": "^3.2.4",
"@vitest/ui": "^3.2.4",
"@testcontainers/redis": "^11.9.0",
"@turbo/gen": "^2.6.1",
"@vitejs/plugin-react": "^5.1.1",
"@vitest/coverage-v8": "^4.0.14",
"@vitest/ui": "^4.0.14",
"conventional-changelog-conventionalcommits": "^9.1.0",
"cross-env": "^10.1.0",
"jsdom": "^27.0.0",
"jsdom": "^27.2.0",
"json5": "^2.2.3",
"prettier": "^3.6.2",
"semantic-release": "^24.2.9",
"testcontainers": "^11.7.1",
"turbo": "^2.5.8",
"semantic-release": "^25.0.2",
"testcontainers": "^11.9.0",
"turbo": "^2.6.1",
"typescript": "^5.9.3",
"vite-tsconfig-paths": "^5.1.4",
"vitest": "^3.2.4"
"vitest": "^4.0.14"
},
"packageManager": "pnpm@10.18.2",
"packageManager": "pnpm@10.24.0",
"engines": {
"node": ">=22.20.0"
"node": ">=24.11.1",
"pnpm": ">=10.24.0"
},
"pnpm": {
"onlyBuiltDependencies": [
@@ -77,23 +79,23 @@
"overrides": {
"@babel/helpers@<7.26.10": ">=7.28.4",
"@babel/runtime@<7.26.10": ">=7.28.4",
"axios@>=1.0.0 <1.8.2": ">=1.12.2",
"axios@>=1.0.0 <1.8.2": ">=1.13.2",
"brace-expansion@>=2.0.0 <=2.0.1": ">=4.0.1",
"brace-expansion@>=1.0.0 <=1.1.11": ">=4.0.1",
"esbuild@<=0.24.2": ">=0.25.10",
"form-data@>=4.0.0 <4.0.4": ">=4.0.4",
"hono@<4.6.5": ">=4.9.12",
"esbuild@<=0.24.2": ">=0.27.0",
"form-data@>=4.0.0 <4.0.4": ">=4.0.5",
"hono@<4.6.5": ">=4.10.7",
"linkifyjs@<4.3.2": ">=4.3.2",
"nanoid@>=4.0.0 <5.0.9": ">=5.1.6",
"prismjs@<1.30.0": ">=1.30.0",
"proxmox-api>undici": "7.16.0",
"react-is": "^19.2.0",
"rollup@>=4.0.0 <4.22.4": ">=4.52.4",
"rollup@>=4.0.0 <4.22.4": ">=4.53.3",
"sha.js@<=2.4.11": ">=2.4.12",
"tar-fs@>=3.0.0 <3.0.9": ">=3.1.1",
"tar-fs@>=2.0.0 <2.1.3": ">=3.1.1",
"tmp@<=0.2.3": ">=0.2.5",
"vite@>=5.0.0 <=5.4.18": ">=7.1.9"
"vite@>=5.0.0 <=5.4.18": ">=7.2.4"
},
"patchedDependencies": {
"@types/node-unifi": "patches/@types__node-unifi.patch",
+2 -2
View File
@@ -26,13 +26,13 @@
"@homarr/log": "workspace:^0.1.0",
"@homarr/server-settings": "workspace:^0.1.0",
"@umami/node": "^0.4.0",
"superjson": "2.2.2"
"superjson": "2.2.6"
},
"devDependencies": {
"@homarr/eslint-config": "workspace:^0.2.0",
"@homarr/prettier-config": "workspace:^0.1.0",
"@homarr/tsconfig": "workspace:^0.1.0",
"eslint": "^9.37.0",
"eslint": "^9.39.1",
"typescript": "^5.9.3"
}
}
+9 -9
View File
@@ -43,24 +43,24 @@
"@homarr/translation": "workspace:^0.1.0",
"@homarr/validation": "workspace:^0.1.0",
"@kubernetes/client-node": "^1.4.0",
"@tanstack/react-query": "^5.90.2",
"@trpc/client": "^11.6.0",
"@trpc/react-query": "^11.6.0",
"@trpc/server": "^11.6.0",
"@trpc/tanstack-react-query": "^11.6.0",
"@tanstack/react-query": "^5.90.11",
"@trpc/client": "^11.7.2",
"@trpc/react-query": "^11.7.2",
"@trpc/server": "^11.7.2",
"@trpc/tanstack-react-query": "^11.7.2",
"lodash.clonedeep": "^4.5.0",
"next": "15.5.5",
"next": "16.0.7",
"react": "19.2.0",
"react-dom": "19.2.0",
"superjson": "2.2.2",
"superjson": "2.2.6",
"trpc-to-openapi": "^3.1.0",
"zod": "^4.1.12"
"zod": "^4.1.13"
},
"devDependencies": {
"@homarr/eslint-config": "workspace:^0.2.0",
"@homarr/prettier-config": "workspace:^0.1.0",
"@homarr/tsconfig": "workspace:^0.1.0",
"eslint": "^9.37.0",
"eslint": "^9.39.1",
"prettier": "^3.6.2",
"typescript": "^5.9.3"
}
@@ -32,6 +32,7 @@ export const createOneIntegrationMiddleware = <TKind extends IntegrationKind>(
const integration = await ctx.db.query.integrations.findFirst({
where: and(eq(integrations.id, input.integrationId), inArray(integrations.kind, kinds)),
with: {
app: true,
secrets: true,
groupPermissions: true,
userPermissions: true,
@@ -65,6 +66,7 @@ export const createOneIntegrationMiddleware = <TKind extends IntegrationKind>(
ctx: {
integration: {
...rest,
externalUrl: rest.app?.href ?? null,
kind: kind as TKind,
decryptedSecrets: secrets.map((secret) => ({
...secret,
@@ -96,6 +98,7 @@ export const createManyIntegrationMiddleware = <TKind extends IntegrationKind>(
? await ctx.db.query.integrations.findMany({
where: and(inArray(integrations.id, input.integrationIds), inArray(integrations.kind, kinds)),
with: {
app: true,
secrets: true,
items: {
with: {
@@ -125,6 +128,7 @@ export const createManyIntegrationMiddleware = <TKind extends IntegrationKind>(
integrations: dbIntegrations.map(
({ secrets, kind, items: _ignore1, groupPermissions: _ignore2, userPermissions: _ignore3, ...rest }) => ({
...rest,
externalUrl: rest.app?.href ?? null,
kind: kind as TKind,
decryptedSecrets: secrets.map((secret) => ({
...secret,
+6 -4
View File
@@ -118,20 +118,22 @@ export const appRouter = createTRPCRouter({
create: permissionRequiredProcedure
.requiresPermission("app-create")
.input(appManageSchema)
.output(z.object({ appId: z.string() }))
.output(z.object({ appId: z.string() }).and(selectAppSchema))
.meta({ openapi: { method: "POST", path: "/api/apps", tags: ["apps"], protect: true } })
.mutation(async ({ ctx, input }) => {
const id = createId();
await ctx.db.insert(apps).values({
const insertValues = {
id,
name: input.name,
description: input.description,
iconUrl: input.iconUrl,
href: input.href,
pingUrl: input.pingUrl === "" ? null : input.pingUrl,
});
};
await ctx.db.insert(apps).values(insertValues);
return { appId: id };
// TODO: breaking change necessary for removing appId property
return { appId: id, ...insertValues };
}),
createMany: permissionRequiredProcedure
.requiresPermission("app-create")
@@ -6,6 +6,7 @@ import { decryptSecret, encryptSecret } from "@homarr/common/server";
import type { Database } from "@homarr/db";
import { and, asc, eq, handleTransactionsAsync, inArray, like, or } from "@homarr/db";
import {
apps,
groupMembers,
groupPermissions,
integrationGroupPermissions,
@@ -212,6 +213,14 @@ export const integrationRouter = createTRPCRouter({
updatedAt: true,
},
},
app: {
columns: {
id: true,
name: true,
iconUrl: true,
href: true,
},
},
},
});
@@ -233,6 +242,7 @@ export const integrationRouter = createTRPCRouter({
value: integrationSecretKindObject[secret.kind].isPublic ? decryptSecret(secret.value) : null,
updatedAt: secret.updatedAt,
})),
app: integration.app,
};
}),
create: permissionRequiredProcedure
@@ -245,6 +255,13 @@ export const integrationRouter = createTRPCRouter({
url: input.url,
});
if (input.app && "name" in input.app && !ctx.session.user.permissions.includes("app-create")) {
throw new TRPCError({
code: "FORBIDDEN",
message: "Permission denied",
});
}
const result = await testConnectionAsync({
id: "new",
name: input.name,
@@ -267,12 +284,15 @@ export const integrationRouter = createTRPCRouter({
};
}
const appId = await createAppIfNecessaryAsync(ctx.db, input.app);
const integrationId = createId();
await ctx.db.insert(integrations).values({
id: integrationId,
name: input.name,
url: input.url,
kind: input.kind,
appId,
});
if (input.secrets.length >= 1) {
@@ -358,6 +378,7 @@ export const integrationRouter = createTRPCRouter({
.set({
name: input.name,
url: input.url,
appId: input.appId,
})
.where(eq(integrations.id, input.id));
@@ -652,3 +673,30 @@ const addSecretAsync = async (db: Database, input: AddSecretInput) => {
integrationId: input.integrationId,
});
};
const createAppIfNecessaryAsync = async (db: Database, app: z.infer<typeof integrationCreateSchema>["app"]) => {
if (!app) return null;
if ("id" in app) return app.id;
logger.info("Creating app", {
name: app.name,
url: app.href,
});
const appId = createId();
await db.insert(apps).values({
id: appId,
name: app.name,
description: app.description,
iconUrl: app.iconUrl,
href: app.href,
pingUrl: app.pingUrl,
});
logger.info("Created app", {
id: appId,
name: app.name,
url: app.href,
});
return appId;
};
@@ -5,7 +5,7 @@ import { getAllSecretKindOptions } from "@homarr/definitions";
import { createIntegrationAsync } from "@homarr/integrations";
import { logger } from "@homarr/log";
type FormIntegration = Integration & {
type FormIntegration = Omit<Integration, "appId"> & {
secrets: {
kind: IntegrationSecretKind;
value: string | null;
@@ -75,6 +75,7 @@ export const testConnectionAsync = async (
const integrationInstance = await createIntegrationAsync({
...baseIntegration,
decryptedSecrets,
externalUrl: null,
});
const result = await integrationInstance.testConnectionAsync();
@@ -4,7 +4,7 @@ import { describe, expect, test, vi } from "vitest";
import type { Session } from "@homarr/auth";
import { createId } from "@homarr/common";
import { encryptSecret } from "@homarr/common/server";
import { integrations, integrationSecrets } from "@homarr/db/schema";
import { apps, integrations, integrationSecrets } from "@homarr/db/schema";
import { createDb } from "@homarr/db/test";
import type { GroupPermissionKey } from "@homarr/definitions";
@@ -251,6 +251,102 @@ describe("create should create a new integration", () => {
);
});
test("with create integration access should create a new integration with new linked app", async () => {
const db = createDb();
const caller = integrationRouter.createCaller({
db,
deviceType: undefined,
session: defaultSessionWithPermissions(["integration-create", "app-create"]),
});
const input = {
name: "Jellyfin",
kind: "jellyfin" as const,
url: "http://jellyfin.local",
secrets: [{ kind: "apiKey" as const, value: "1234567890" }],
attemptSearchEngineCreation: false,
app: {
name: "Jellyfin",
description: null,
pingUrl: "http://jellyfin.local",
href: "https://jellyfin.home",
iconUrl: "logo.png",
},
};
const fakeNow = new Date("2023-07-01T00:00:00Z");
vi.useFakeTimers();
vi.setSystemTime(fakeNow);
await caller.create(input);
vi.useRealTimers();
const dbIntegration = await db.query.integrations.findFirst({
with: {
app: true,
},
});
const dbSecret = await db.query.integrationSecrets.findFirst();
expect(dbIntegration).toBeDefined();
expect(dbIntegration!.name).toBe(input.name);
expect(dbIntegration!.kind).toBe(input.kind);
expect(dbIntegration!.url).toBe(input.url);
expect(dbIntegration!.app!.name).toBe(input.app.name);
expect(dbIntegration!.app!.pingUrl).toBe(input.app.pingUrl);
expect(dbIntegration!.app!.href).toBe(input.app.href);
expect(dbIntegration!.app!.iconUrl).toBe(input.app.iconUrl);
expect(dbSecret!.integrationId).toBe(dbIntegration!.id);
expect(dbSecret).toBeDefined();
expect(dbSecret!.kind).toBe(input.secrets[0]!.kind);
expect(dbSecret!.value).toMatch(/^[a-f0-9]+.[a-f0-9]+$/);
expect(dbSecret!.updatedAt).toEqual(fakeNow);
});
test("with create integration access should create a new integration with existing linked app", async () => {
const db = createDb();
const appId = createId();
await db.insert(apps).values({
id: appId,
name: "Existing Jellyfin",
iconUrl: "logo.png",
});
const caller = integrationRouter.createCaller({
db,
deviceType: undefined,
session: defaultSessionWithPermissions(["integration-create"]),
});
const input = {
name: "Jellyfin",
kind: "jellyfin" as const,
url: "http://jellyfin.local",
secrets: [{ kind: "apiKey" as const, value: "1234567890" }],
attemptSearchEngineCreation: false,
app: {
id: appId,
},
};
const fakeNow = new Date("2023-07-01T00:00:00Z");
vi.useFakeTimers();
vi.setSystemTime(fakeNow);
await caller.create(input);
vi.useRealTimers();
const dbIntegration = await db.query.integrations.findFirst();
const dbSecret = await db.query.integrationSecrets.findFirst();
expect(dbIntegration).toBeDefined();
expect(dbIntegration!.name).toBe(input.name);
expect(dbIntegration!.kind).toBe(input.kind);
expect(dbIntegration!.url).toBe(input.url);
expect(dbIntegration!.appId).toBe(appId);
expect(dbSecret!.integrationId).toBe(dbIntegration!.id);
expect(dbSecret).toBeDefined();
expect(dbSecret!.kind).toBe(input.secrets[0]!.kind);
expect(dbSecret!.value).toMatch(/^[a-f0-9]+.[a-f0-9]+$/);
expect(dbSecret!.updatedAt).toEqual(fakeNow);
});
test("without create integration access should throw permission error", async () => {
// Arrange
const db = createDb();
@@ -273,6 +369,36 @@ describe("create should create a new integration", () => {
// Assert
await expect(actAsync()).rejects.toThrow("Permission denied");
});
test("without create app access should throw permission error with new linked app", async () => {
// Arrange
const db = createDb();
const caller = integrationRouter.createCaller({
db,
deviceType: undefined,
session: defaultSessionWithPermissions(["integration-create"]),
});
const input = {
name: "Jellyfin",
kind: "jellyfin" as const,
url: "http://jellyfin.local",
secrets: [{ kind: "apiKey" as const, value: "1234567890" }],
attemptSearchEngineCreation: false,
app: {
name: "Jellyfin",
description: null,
href: "https://jellyfin.home",
iconUrl: "logo.png",
pingUrl: null,
},
};
// Act
const actAsync = async () => await caller.create(input);
// Assert
await expect(actAsync()).rejects.toThrow("Permission denied");
});
});
describe("update should update an integration", () => {
@@ -285,6 +411,7 @@ describe("update should update an integration", () => {
});
const lastWeek = new Date("2023-06-24T00:00:00Z");
const appId = createId();
const integrationId = createId();
const toInsert = {
id: integrationId,
@@ -293,6 +420,11 @@ describe("update should update an integration", () => {
url: "http://hole.local",
};
await db.insert(apps).values({
id: appId,
name: "Previous",
iconUrl: "logo.png",
});
await db.insert(integrations).values(toInsert);
const usernameToInsert = {
@@ -320,6 +452,7 @@ describe("update should update an integration", () => {
{ kind: "password" as const, value: null },
{ kind: "apiKey" as const, value: "1234567890" },
],
appId,
};
const fakeNow = new Date("2023-07-01T00:00:00Z");
@@ -335,6 +468,7 @@ describe("update should update an integration", () => {
expect(dbIntegration!.name).toBe(input.name);
expect(dbIntegration!.kind).toBe(input.kind);
expect(dbIntegration!.url).toBe(input.url);
expect(dbIntegration!.appId).toBe(appId);
expect(dbSecrets.length).toBe(3);
const username = expectToBeDefined(dbSecrets.find((secret) => secret.kind === "username"));
@@ -365,6 +499,7 @@ describe("update should update an integration", () => {
name: "Pi Hole",
url: "http://hole.local",
secrets: [],
appId: null,
});
await expect(actAsync()).rejects.toThrow("Integration not found");
});
@@ -385,6 +520,7 @@ describe("update should update an integration", () => {
name: "Pi Hole",
url: "http://hole.local",
secrets: [],
appId: null,
});
// Assert
@@ -55,6 +55,7 @@ describe("testConnectionAsync should run test connection of integration", () =>
value: "secret",
}),
],
externalUrl: null,
});
});
@@ -104,6 +105,7 @@ describe("testConnectionAsync should run test connection of integration", () =>
value: "dbSecret",
}),
],
externalUrl: null,
});
});
@@ -153,6 +155,7 @@ describe("testConnectionAsync should run test connection of integration", () =>
value: "secret",
}),
],
externalUrl: null,
});
});
@@ -206,6 +209,7 @@ describe("testConnectionAsync should run test connection of integration", () =>
value: "secret",
}),
],
externalUrl: null,
});
});
@@ -263,6 +267,7 @@ describe("testConnectionAsync should run test connection of integration", () =>
value: "dbPassword",
}),
],
externalUrl: null,
});
});
@@ -336,6 +341,7 @@ describe("testConnectionAsync should run test connection of integration", () =>
value: "privateKey",
}),
],
externalUrl: null,
});
});
});
@@ -3,6 +3,7 @@ import { z } from "zod/v4";
import { getIntegrationKindsByCategory } from "@homarr/definitions";
import { createIntegrationAsync } from "@homarr/integrations";
import { mediaRequestStatusConfiguration } from "@homarr/integrations/types";
import type { MediaRequest } from "@homarr/integrations/types";
import { mediaRequestListRequestHandler } from "@homarr/request-handler/media-request-list";
import { mediaRequestStatsRequestHandler } from "@homarr/request-handler/media-request-stats";
@@ -35,7 +36,10 @@ export const mediaRequestsRouter = createTRPCRouter({
return dataB.createdAt.getTime() - dataA.createdAt.getTime();
}
return dataA.status - dataB.status;
return (
mediaRequestStatusConfiguration[dataA.status].position -
mediaRequestStatusConfiguration[dataB.status].position
);
});
}),
subscribeToLatestRequests: publicProcedure
+15 -8
View File
@@ -40,15 +40,22 @@ export const releasesRouter = createTRPCRouter({
.query(async ({ ctx, input }) => {
return await Promise.all(
input.repositories.map(async (repository) => {
const innerHandler = releasesRequestHandler.handler(ctx.integration, {
id: repository.id,
identifier: repository.identifier,
versionRegex: formatVersionFilterRegex(repository.versionFilter),
});
const response = await releasesRequestHandler
.handler(ctx.integration, {
id: repository.id,
identifier: repository.identifier,
versionRegex: formatVersionFilterRegex(repository.versionFilter),
})
.getCachedOrUpdatedDataAsync({
forceUpdate: false,
});
return await innerHandler.getCachedOrUpdatedDataAsync({
forceUpdate: false,
});
return {
id: repository.id,
integration: { name: ctx.integration.name, kind: ctx.integration.kind },
timestamp: response.timestamp,
...response.data,
};
}),
);
}),
+7 -7
View File
@@ -23,8 +23,8 @@
},
"prettier": "@homarr/prettier-config",
"dependencies": {
"@auth/core": "^0.41.0",
"@auth/drizzle-adapter": "^1.11.0",
"@auth/core": "^0.41.1",
"@auth/drizzle-adapter": "^1.11.1",
"@homarr/certificates": "workspace:^0.1.0",
"@homarr/common": "workspace:^0.1.0",
"@homarr/core": "workspace:^0.1.0",
@@ -35,19 +35,19 @@
"bcrypt": "^6.0.0",
"cookies": "^0.9.1",
"ldapts": "8.0.9",
"next": "15.5.5",
"next-auth": "5.0.0-beta.29",
"next": "16.0.7",
"next-auth": "5.0.0-beta.30",
"react": "19.2.0",
"react-dom": "19.2.0",
"zod": "^4.1.12"
"zod": "^4.1.13"
},
"devDependencies": {
"@homarr/eslint-config": "workspace:^0.2.0",
"@homarr/prettier-config": "workspace:^0.1.0",
"@homarr/tsconfig": "workspace:^0.1.0",
"@types/bcrypt": "6.0.0",
"@types/cookies": "0.9.1",
"eslint": "^9.37.0",
"@types/cookies": "0.9.2",
"eslint": "^9.39.1",
"prettier": "^3.6.2",
"typescript": "^5.9.3"
}
@@ -23,12 +23,11 @@ describe("authorizeWithLdapCredentials", () => {
test("should fail when wrong ldap base credentials", async () => {
// Arrange
const spy = vi.spyOn(ldapClient, "LdapClient");
spy.mockImplementation(
() =>
({
bindAsync: vi.fn(() => Promise.reject(new Error("bindAsync"))),
}) as unknown as ldapClient.LdapClient,
);
spy.mockImplementation(function () {
return {
bindAsync: vi.fn(() => Promise.reject(new Error("bindAsync"))),
} as unknown as ldapClient.LdapClient;
});
// Act
const act = () =>
@@ -44,13 +43,12 @@ describe("authorizeWithLdapCredentials", () => {
test("should fail when user not found", async () => {
// Arrange
const spy = vi.spyOn(ldapClient, "LdapClient");
spy.mockImplementation(
() =>
({
bindAsync: vi.fn(() => Promise.resolve()),
searchAsync: vi.fn(() => Promise.resolve([])),
}) as unknown as ldapClient.LdapClient,
);
spy.mockImplementation(function () {
return {
bindAsync: vi.fn(() => Promise.resolve()),
searchAsync: vi.fn(() => Promise.resolve([])),
} as unknown as ldapClient.LdapClient;
});
// Act
const act = () =>
@@ -66,20 +64,19 @@ describe("authorizeWithLdapCredentials", () => {
test("should fail when user has invalid email", async () => {
// Arrange
const spy = vi.spyOn(ldapClient, "LdapClient");
spy.mockImplementation(
() =>
({
bindAsync: vi.fn(() => Promise.resolve()),
searchAsync: vi.fn(() =>
Promise.resolve([
{
dn: "test",
mail: "test",
},
]),
),
}) as unknown as ldapClient.LdapClient,
);
spy.mockImplementation(function () {
return {
bindAsync: vi.fn(() => Promise.resolve()),
searchAsync: vi.fn(() =>
Promise.resolve([
{
dn: "test",
mail: "test",
},
]),
),
} as unknown as ldapClient.LdapClient;
});
// Act
const act = () =>
@@ -103,15 +100,14 @@ describe("authorizeWithLdapCredentials", () => {
]),
);
const spy = vi.spyOn(ldapClient, "LdapClient");
spy.mockImplementation(
() =>
({
bindAsync: vi.fn((props: ldapClient.BindOptions) =>
props.distinguishedName === "test" ? Promise.reject(new Error("bindAsync")) : Promise.resolve(),
),
searchAsync: searchSpy,
}) as unknown as ldapClient.LdapClient,
);
spy.mockImplementation(function () {
return {
bindAsync: vi.fn((props: ldapClient.BindOptions) =>
props.distinguishedName === "test" ? Promise.reject(new Error("bindAsync")) : Promise.resolve(),
),
searchAsync: searchSpy,
} as unknown as ldapClient.LdapClient;
});
// Act
const act = () =>
@@ -129,21 +125,20 @@ describe("authorizeWithLdapCredentials", () => {
// Arrange
const db = createDb();
const spy = vi.spyOn(ldapClient, "LdapClient");
spy.mockImplementation(
() =>
({
bindAsync: vi.fn(() => Promise.resolve()),
searchAsync: vi.fn(() =>
Promise.resolve([
{
dn: "test",
mail: "test@gmail.com",
},
]),
),
disconnectAsync: vi.fn(),
}) as unknown as ldapClient.LdapClient,
);
spy.mockImplementation(function () {
return {
bindAsync: vi.fn(() => Promise.resolve()),
searchAsync: vi.fn(() =>
Promise.resolve([
{
dn: "test",
mail: "test@gmail.com",
},
]),
),
disconnectAsync: vi.fn(),
} as unknown as ldapClient.LdapClient;
});
// Act
const result = await authorizeWithLdapCredentialsAsync(db, {
@@ -168,21 +163,20 @@ describe("authorizeWithLdapCredentials", () => {
// Arrange
const db = createDb();
const spy = vi.spyOn(ldapClient, "LdapClient");
spy.mockImplementation(
() =>
({
bindAsync: vi.fn(() => Promise.resolve()),
searchAsync: vi.fn(() =>
Promise.resolve([
{
dn: "test",
mail: "test@gmail.com",
},
]),
),
disconnectAsync: vi.fn(),
}) as unknown as ldapClient.LdapClient,
);
spy.mockImplementation(function () {
return {
bindAsync: vi.fn(() => Promise.resolve()),
searchAsync: vi.fn(() =>
Promise.resolve([
{
dn: "test",
mail: "test@gmail.com",
},
]),
),
disconnectAsync: vi.fn(),
} as unknown as ldapClient.LdapClient;
});
await db.insert(users).values({
id: createId(),
name: "test",
@@ -220,21 +214,20 @@ describe("authorizeWithLdapCredentials", () => {
test("should authorize user with correct credentials and return updated name", async () => {
// Arrange
const spy = vi.spyOn(ldapClient, "LdapClient");
spy.mockImplementation(
() =>
({
bindAsync: vi.fn(() => Promise.resolve()),
searchAsync: vi.fn(() =>
Promise.resolve([
{
dn: "test55",
mail: "test@gmail.com",
},
]),
),
disconnectAsync: vi.fn(),
}) as unknown as ldapClient.LdapClient,
);
spy.mockImplementation(function () {
return {
bindAsync: vi.fn(() => Promise.resolve()),
searchAsync: vi.fn(() =>
Promise.resolve([
{
dn: "test55",
mail: "test@gmail.com",
},
]),
),
disconnectAsync: vi.fn(),
} as unknown as ldapClient.LdapClient;
});
const userId = createId();
const db = createDb();
@@ -268,27 +261,26 @@ describe("authorizeWithLdapCredentials", () => {
test("should authorize user with correct credentials and return his groups", async () => {
// Arrange
const spy = vi.spyOn(ldapClient, "LdapClient");
spy.mockImplementation(
() =>
({
bindAsync: vi.fn(() => Promise.resolve()),
searchAsync: vi.fn((argument: { options: { filter: string } }) =>
argument.options.filter.includes("group")
? Promise.resolve([
{
cn: "homarr_example",
},
])
: Promise.resolve([
{
dn: "test55",
mail: "test@gmail.com",
},
]),
),
disconnectAsync: vi.fn(),
}) as unknown as ldapClient.LdapClient,
);
spy.mockImplementation(function () {
return {
bindAsync: vi.fn(() => Promise.resolve()),
searchAsync: vi.fn((argument: { options: { filter: string } }) =>
argument.options.filter.includes("group")
? Promise.resolve([
{
cn: "homarr_example",
},
])
: Promise.resolve([
{
dn: "test55",
mail: "test@gmail.com",
},
]),
),
disconnectAsync: vi.fn(),
} as unknown as ldapClient.LdapClient;
});
const db = createDb();
const userId = createId();
await db.insert(users).values({
+1 -1
View File
@@ -32,7 +32,7 @@
"@homarr/eslint-config": "workspace:^0.2.0",
"@homarr/prettier-config": "workspace:^0.1.0",
"@homarr/tsconfig": "workspace:^0.1.0",
"eslint": "^9.37.0",
"eslint": "^9.39.1",
"typescript": "^5.9.3"
}
}
+1 -1
View File
@@ -30,7 +30,7 @@
"@homarr/eslint-config": "workspace:^0.2.0",
"@homarr/prettier-config": "workspace:^0.1.0",
"@homarr/tsconfig": "workspace:^0.1.0",
"eslint": "^9.37.0",
"eslint": "^9.39.1",
"typescript": "^5.9.3"
}
}
+2 -2
View File
@@ -34,8 +34,8 @@
"@homarr/eslint-config": "workspace:^0.2.0",
"@homarr/prettier-config": "workspace:^0.1.0",
"@homarr/tsconfig": "workspace:^0.1.0",
"esbuild": "^0.25.10",
"eslint": "^9.37.0",
"esbuild": "^0.27.0",
"eslint": "^9.39.1",
"typescript": "^5.9.3"
}
}
+7 -7
View File
@@ -29,22 +29,22 @@
"dependencies": {
"@homarr/core": "workspace:^0.1.0",
"@homarr/log": "workspace:^0.1.0",
"@paralleldrive/cuid2": "^2.2.2",
"dayjs": "^1.11.18",
"@paralleldrive/cuid2": "^3.1.0",
"dayjs": "^1.11.19",
"dns-caching": "^0.2.7",
"next": "15.5.5",
"octokit": "^5.0.3",
"next": "16.0.7",
"octokit": "^5.0.5",
"react": "19.2.0",
"react-dom": "19.2.0",
"undici": "7.16.0",
"zod": "^4.1.12",
"zod-validation-error": "^4.0.2"
"zod": "^4.1.13",
"zod-validation-error": "^5.0.0"
},
"devDependencies": {
"@homarr/eslint-config": "workspace:^0.2.0",
"@homarr/prettier-config": "workspace:^0.1.0",
"@homarr/tsconfig": "workspace:^0.1.0",
"eslint": "^9.37.0",
"eslint": "^9.39.1",
"typescript": "^5.9.3"
}
}
+3 -3
View File
@@ -25,14 +25,14 @@
"prettier": "@homarr/prettier-config",
"dependencies": {
"@t3-oss/env-nextjs": "^0.13.8",
"ioredis": "5.8.1",
"zod": "^4.1.12"
"ioredis": "5.8.2",
"zod": "^4.1.13"
},
"devDependencies": {
"@homarr/eslint-config": "workspace:^0.2.0",
"@homarr/prettier-config": "workspace:^0.1.0",
"@homarr/tsconfig": "workspace:^0.1.0",
"eslint": "^9.37.0",
"eslint": "^9.39.1",
"typescript": "^5.9.3"
}
}
+7 -7
View File
@@ -29,21 +29,21 @@
"@homarr/core": "workspace:^0.1.0",
"@homarr/cron-jobs": "workspace:^0.1.0",
"@homarr/log": "workspace:^0.1.0",
"@tanstack/react-query": "^5.90.2",
"@trpc/client": "^11.6.0",
"@trpc/server": "^11.6.0",
"@trpc/tanstack-react-query": "^11.6.0",
"@tanstack/react-query": "^5.90.11",
"@trpc/client": "^11.7.2",
"@trpc/server": "^11.7.2",
"@trpc/tanstack-react-query": "^11.7.2",
"node-cron": "^4.2.1",
"react": "19.2.0",
"zod": "^4.1.12"
"zod": "^4.1.13"
},
"devDependencies": {
"@homarr/eslint-config": "workspace:^0.2.0",
"@homarr/prettier-config": "workspace:^0.1.0",
"@homarr/tsconfig": "workspace:^0.1.0",
"@types/node-cron": "^3.0.11",
"@types/react": "19.2.2",
"eslint": "^9.37.0",
"@types/react": "19.2.7",
"eslint": "^9.39.1",
"typescript": "^5.9.3"
}
}
+1 -1
View File
@@ -29,7 +29,7 @@
"@homarr/eslint-config": "workspace:^0.2.0",
"@homarr/prettier-config": "workspace:^0.1.0",
"@homarr/tsconfig": "workspace:^0.1.0",
"eslint": "^9.37.0",
"eslint": "^9.39.1",
"typescript": "^5.9.3"
}
}
+1 -1
View File
@@ -33,7 +33,7 @@
"@homarr/prettier-config": "workspace:^0.1.0",
"@homarr/tsconfig": "workspace:^0.1.0",
"@types/node-cron": "^3.0.11",
"eslint": "^9.37.0",
"eslint": "^9.39.1",
"typescript": "^5.9.3"
}
}
+1 -1
View File
@@ -44,7 +44,7 @@
"@homarr/eslint-config": "workspace:^0.2.0",
"@homarr/prettier-config": "workspace:^0.1.0",
"@homarr/tsconfig": "workspace:^0.1.0",
"eslint": "^9.37.0",
"eslint": "^9.39.1",
"typescript": "^5.9.3"
}
}
@@ -0,0 +1,2 @@
ALTER TABLE `integration` ADD `app_id` varchar(128);--> statement-breakpoint
ALTER TABLE `integration` ADD CONSTRAINT `integration_app_id_app_id_fk` FOREIGN KEY (`app_id`) REFERENCES `app`(`id`) ON DELETE set null ON UPDATE no action;
File diff suppressed because it is too large. Load diff
@@ -253,6 +253,13 @@
"when": 1756701556908,
"tag": "0035_increase-secret-kind-length",
"breakpoints": true
},
{
"idx": 36,
"version": "5",
"when": 1760968518445,
"tag": "0036_add_app_reference_to_integration",
"breakpoints": true
}
]
}
@@ -0,0 +1,2 @@
ALTER TABLE "integration" ADD COLUMN "app_id" varchar(128);--> statement-breakpoint
ALTER TABLE "integration" ADD CONSTRAINT "integration_app_id_app_id_fk" FOREIGN KEY ("app_id") REFERENCES "public"."app"("id") ON DELETE set null ON UPDATE no action;
File diff suppressed because it is too large. Load diff
@@ -15,6 +15,13 @@
"when": 1756701573101,
"tag": "0001_increase-secret-kind-length",
"breakpoints": true
},
{
"idx": 2,
"version": "7",
"when": 1760968530084,
"tag": "0002_add_app_reference_to_integration",
"breakpoints": true
}
]
}
+1
View File
@@ -150,6 +150,7 @@ const seedDefaultIntegrationsAsync = async (db: Database) => {
name: `${name} Default`,
url: defaultUrl,
kind,
appId: null,
});
}
@@ -0,0 +1 @@
ALTER TABLE `integration` ADD `app_id` text REFERENCES app(id);
File diff suppressed because it is too large. Load diff
@@ -239,6 +239,13 @@
"when": 1750014001941,
"tag": "0033_add_cron_job_configuration",
"breakpoints": true
},
{
"idx": 34,
"version": "6",
"when": 1760968503571,
"tag": "0034_add_app_reference_to_integration",
"breakpoints": true
}
]
}
+13 -13
View File
@@ -43,34 +43,34 @@
},
"prettier": "@homarr/prettier-config",
"dependencies": {
"@auth/core": "^0.41.0",
"@auth/core": "^0.41.1",
"@homarr/common": "workspace:^0.1.0",
"@homarr/core": "workspace:^0.1.0",
"@homarr/definitions": "workspace:^0.1.0",
"@homarr/log": "workspace:^0.1.0",
"@homarr/server-settings": "workspace:^0.1.0",
"@mantine/core": "^8.3.4",
"@paralleldrive/cuid2": "^2.2.2",
"@testcontainers/mysql": "^11.7.1",
"@testcontainers/postgresql": "^11.7.1",
"@mantine/core": "^8.3.9",
"@paralleldrive/cuid2": "^3.1.0",
"@testcontainers/mysql": "^11.9.0",
"@testcontainers/postgresql": "^11.9.0",
"better-sqlite3": "^12.4.1",
"dotenv": "^17.2.3",
"drizzle-kit": "^0.31.5",
"drizzle-orm": "^0.44.6",
"drizzle-kit": "^0.31.7",
"drizzle-orm": "^0.44.7",
"drizzle-zod": "^0.8.3",
"mysql2": "3.15.2",
"mysql2": "3.15.3",
"pg": "^8.16.3",
"superjson": "2.2.2"
"superjson": "2.2.6"
},
"devDependencies": {
"@homarr/eslint-config": "workspace:^0.2.0",
"@homarr/prettier-config": "workspace:^0.1.0",
"@homarr/tsconfig": "workspace:^0.1.0",
"@types/better-sqlite3": "7.6.13",
"@types/pg": "^8.15.5",
"dotenv-cli": "^10.0.0",
"esbuild": "^0.25.10",
"eslint": "^9.37.0",
"@types/pg": "^8.15.6",
"dotenv-cli": "^11.0.0",
"esbuild": "^0.27.0",
"eslint": "^9.39.1",
"prettier": "^3.6.2",
"tsx": "4.20.4",
"typescript": "^5.9.3"
+1
View File
@@ -16,6 +16,7 @@ export const getItemsWithIntegrationsAsync = async <TKind extends WidgetKind>(
with: {
integration: {
with: {
app: true,
secrets: {
columns: {
kind: true,
+6 -1
View File
@@ -199,6 +199,7 @@ export const integrations = mysqlTable(
name: text().notNull(),
url: text().notNull(),
kind: varchar({ length: 128 }).$type<IntegrationKind>().notNull(),
appId: varchar({ length: 128 }).references(() => apps.id, { onDelete: "set null" }),
},
(integrations) => ({
kindIdx: index("integration__kind_idx").on(integrations.kind),
@@ -627,11 +628,15 @@ export const boardGroupPermissionRelations = relations(boardGroupPermissions, ({
}),
}));
export const integrationRelations = relations(integrations, ({ many }) => ({
export const integrationRelations = relations(integrations, ({ one, many }) => ({
secrets: many(integrationSecrets),
items: many(integrationItems),
userPermissions: many(integrationUserPermissions),
groupPermissions: many(integrationGroupPermissions),
app: one(apps, {
fields: [integrations.appId],
references: [apps.id],
}),
}));
export const integrationUserPermissionRelations = relations(integrationUserPermissions, ({ one }) => ({
+6 -1
View File
@@ -198,6 +198,7 @@ export const integrations = pgTable(
name: text().notNull(),
url: text().notNull(),
kind: varchar({ length: 128 }).$type<IntegrationKind>().notNull(),
appId: varchar({ length: 128 }).references(() => apps.id, { onDelete: "set null" }),
},
(integrations) => ({
kindIdx: index("integration__kind_idx").on(integrations.kind),
@@ -626,11 +627,15 @@ export const boardGroupPermissionRelations = relations(boardGroupPermissions, ({
}),
}));
export const integrationRelations = relations(integrations, ({ many }) => ({
export const integrationRelations = relations(integrations, ({ one, many }) => ({
secrets: many(integrationSecrets),
items: many(integrationItems),
userPermissions: many(integrationUserPermissions),
groupPermissions: many(integrationGroupPermissions),
app: one(apps, {
fields: [integrations.appId],
references: [apps.id],
}),
}));
export const integrationUserPermissionRelations = relations(integrationUserPermissions, ({ one }) => ({
+6 -1
View File
@@ -185,6 +185,7 @@ export const integrations = sqliteTable(
name: text().notNull(),
url: text().notNull(),
kind: text().$type<IntegrationKind>().notNull(),
appId: text().references(() => apps.id, { onDelete: "set null" }),
},
(integrations) => ({
kindIdx: index("integration__kind_idx").on(integrations.kind),
@@ -612,11 +613,15 @@ export const boardGroupPermissionRelations = relations(boardGroupPermissions, ({
}),
}));
export const integrationRelations = relations(integrations, ({ many }) => ({
export const integrationRelations = relations(integrations, ({ one, many }) => ({
secrets: many(integrationSecrets),
items: many(integrationItems),
userPermissions: many(integrationUserPermissions),
groupPermissions: many(integrationGroupPermissions),
app: one(apps, {
fields: [integrations.appId],
references: [apps.id],
}),
}));
export const integrationUserPermissionRelations = relations(integrationUserPermissions, ({ one }) => ({
+3 -3
View File
@@ -24,14 +24,14 @@
"prettier": "@homarr/prettier-config",
"dependencies": {
"@homarr/common": "workspace:^0.1.0",
"fast-xml-parser": "^5.3.0",
"zod": "^4.1.12"
"fast-xml-parser": "^5.3.2",
"zod": "^4.1.13"
},
"devDependencies": {
"@homarr/eslint-config": "workspace:^0.2.0",
"@homarr/prettier-config": "workspace:^0.1.0",
"@homarr/tsconfig": "workspace:^0.1.0",
"eslint": "^9.37.0",
"eslint": "^9.39.1",
"tsx": "4.20.4",
"typescript": "^5.9.3"
}
@@ -144,6 +144,7 @@ export type HomarrDocumentationPath =
| "/docs/getting-started/installation/proxmox"
| "/docs/getting-started/installation/qnap"
| "/docs/getting-started/installation/railway"
| "/docs/getting-started/installation/runtipi"
| "/docs/getting-started/installation/saltbox"
| "/docs/getting-started/installation/source"
| "/docs/getting-started/installation/synology"
+1 -1
View File
@@ -145,7 +145,7 @@ export const integrationDefs = {
},
piHole: {
name: "Pi-hole",
secretKinds: [["apiKey"]],
secretKinds: [["apiKey"], []],
iconUrl: "https://cdn.jsdelivr.net/gh/homarr-labs/dashboard-icons@master/svg/pi-hole.svg",
category: ["dnsHole"],
documentationUrl: createDocumentationLink("/docs/integrations/pi-hole"),
+2 -2
View File
@@ -32,8 +32,8 @@
"@homarr/eslint-config": "workspace:^0.2.0",
"@homarr/prettier-config": "workspace:^0.1.0",
"@homarr/tsconfig": "workspace:^0.1.0",
"@types/dockerode": "^3.3.44",
"eslint": "^9.37.0",
"@types/dockerode": "^3.3.47",
"eslint": "^9.39.1",
"typescript": "^5.9.3"
}
}
+1
View File
@@ -8,3 +8,4 @@ export type { Docker };
export const containerStates = ["created", "running", "paused", "restarting", "exited", "removing", "dead"] as const;
export type ContainerState = (typeof containerStates)[number];
export * from "./labels";
+4
View File
@@ -0,0 +1,4 @@
export const dockerLabels = {
// Label to hide a container from Homarrs docker integration
hide: "homarr.hide",
} as const;
+3 -3
View File
@@ -26,15 +26,15 @@
"@homarr/common": "workspace:^0.1.0",
"@homarr/translation": "workspace:^0.1.0",
"@homarr/validation": "workspace:^0.1.0",
"@mantine/form": "^8.3.4",
"@mantine/form": "^8.3.9",
"mantine-form-zod-resolver": "^1.3.0",
"zod": "^4.1.12"
"zod": "^4.1.13"
},
"devDependencies": {
"@homarr/eslint-config": "workspace:^0.2.0",
"@homarr/prettier-config": "workspace:^0.1.0",
"@homarr/tsconfig": "workspace:^0.1.0",
"eslint": "^9.37.0",
"eslint": "^9.39.1",
"typescript": "^5.9.3"
}
}
+4 -3
View File
@@ -28,16 +28,17 @@
"@homarr/form": "workspace:^0.1.0",
"@homarr/notifications": "workspace:^0.1.0",
"@homarr/translation": "workspace:^0.1.0",
"@homarr/ui": "workspace:^0.1.0",
"@homarr/validation": "workspace:^0.1.0",
"@mantine/core": "^8.3.4",
"@mantine/core": "^8.3.9",
"react": "19.2.0",
"zod": "^4.1.12"
"zod": "^4.1.13"
},
"devDependencies": {
"@homarr/eslint-config": "workspace:^0.2.0",
"@homarr/prettier-config": "workspace:^0.1.0",
"@homarr/tsconfig": "workspace:^0.1.0",
"eslint": "^9.37.0",
"eslint": "^9.39.1",
"typescript": "^5.9.3"
}
}
@@ -2,7 +2,6 @@
import type { ChangeEventHandler } from "react";
import { useEffect, useRef } from "react";
import Link from "next/link";
import { Button, Checkbox, Collapse, Group, Stack, Textarea, TextInput } from "@mantine/core";
import { useDebouncedValue, useDisclosure } from "@mantine/hooks";
import type { z } from "zod/v4";
@@ -10,6 +9,7 @@ import type { z } from "zod/v4";
import { clientApi } from "@homarr/api/client";
import { useZodForm } from "@homarr/form";
import { useI18n } from "@homarr/translation/client";
import { Link } from "@homarr/ui";
import { appManageSchema } from "@homarr/validation/app";
import { IconPicker } from "../icon-picker/icon-picker";
+1 -1
View File
@@ -31,7 +31,7 @@
"@homarr/eslint-config": "workspace:^0.2.0",
"@homarr/prettier-config": "workspace:^0.1.0",
"@homarr/tsconfig": "workspace:^0.1.0",
"eslint": "^9.37.0",
"eslint": "^9.39.1",
"typescript": "^5.9.3"
}
}
+1 -1
View File
@@ -33,7 +33,7 @@
"@homarr/prettier-config": "workspace:^0.1.0",
"@homarr/tsconfig": "workspace:^0.1.0",
"@types/bcrypt": "6.0.0",
"eslint": "^9.37.0",
"eslint": "^9.39.1",
"typescript": "^5.9.3"
}
}
+10 -10
View File
@@ -25,10 +25,10 @@
},
"prettier": "@homarr/prettier-config",
"dependencies": {
"@ctrl/deluge": "^7.4.0",
"@ctrl/qbittorrent": "^9.10.0",
"@ctrl/deluge": "^7.5.0",
"@ctrl/qbittorrent": "^9.11.0",
"@ctrl/transmission": "^7.4.0",
"@gitbeaker/rest": "^43.5.0",
"@gitbeaker/rest": "^43.8.0",
"@homarr/certificates": "workspace:^0.1.0",
"@homarr/common": "workspace:^0.1.0",
"@homarr/db": "workspace:^0.1.0",
@@ -39,17 +39,17 @@
"@homarr/redis": "workspace:^0.1.0",
"@homarr/translation": "workspace:^0.1.0",
"@homarr/validation": "workspace:^0.1.0",
"@jellyfin/sdk": "^0.11.0",
"@octokit/auth-app": "^8.1.1",
"@jellyfin/sdk": "^0.13.0",
"@octokit/auth-app": "^8.1.2",
"ical.js": "^2.2.1",
"maria2": "^0.4.1",
"node-ical": "^0.21.0",
"octokit": "^5.0.3",
"node-ical": "^0.22.1",
"octokit": "^5.0.5",
"proxmox-api": "1.1.1",
"tsdav": "^2.1.5",
"tsdav": "^2.1.6",
"undici": "7.16.0",
"xml2js": "^0.6.2",
"zod": "^4.1.12"
"zod": "^4.1.13"
},
"devDependencies": {
"@homarr/eslint-config": "workspace:^0.2.0",
@@ -57,7 +57,7 @@
"@homarr/tsconfig": "workspace:^0.1.0",
"@types/node-unifi": "^2.5.1",
"@types/xml2js": "^0.4.14",
"eslint": "^9.37.0",
"eslint": "^9.39.1",
"typescript": "^5.9.3"
}
}
+1 -18
View File
@@ -1,7 +1,4 @@
import { decryptSecret } from "@homarr/common/server";
import type { Modify } from "@homarr/common/types";
import type { Integration as DbIntegration } from "@homarr/db/schema";
import type { IntegrationKind, IntegrationSecretKind } from "@homarr/definitions";
import type { IntegrationKind } from "@homarr/definitions";
import { AdGuardHomeIntegration } from "../adguard-home/adguard-home-integration";
import { CodebergIntegration } from "../codeberg/codeberg-integration";
@@ -62,20 +59,6 @@ export const createIntegrationAsync = async <TKind extends keyof typeof integrat
return new creator(integration) as IntegrationInstanceOfKind<TKind>;
};
export const createIntegrationAsyncFromSecrets = <TKind extends keyof typeof integrationCreators>(
integration: Modify<DbIntegration, { kind: TKind }> & {
secrets: { kind: IntegrationSecretKind; value: `${string}.${string}` }[];
},
) => {
return createIntegrationAsync({
...integration,
decryptedSecrets: integration.secrets.map((secret) => ({
...secret,
value: decryptSecret(secret.value),
})),
});
};
type IntegrationInstance = new (integration: IntegrationInput) => Integration;
// factories are an array, to differentiate in js between class constructors and functions
Loaded 100 of 211 files, more files were not shown because too many files have changed in this diff. Show more