Compare commits

..
Author SHA1 Message Date
ajnart f79095d40e fix(auth): patch critical Auth.js vulnerabilities 2026-09-06 10:03:21 +02:00
6 changed files with 27 additions and 108 deletions

No files matched your search

@@ -1,13 +0,0 @@
export const createNextcloudCalendarServerUrl = (integrationUrl: string) => {
const calendarServerUrl = new URL(integrationUrl);
const integrationPath = calendarServerUrl.pathname.replace(/\/+$/, "");
const davPath = "/remote.php/dav";
calendarServerUrl.pathname = integrationPath.endsWith(davPath)
? `${integrationPath}/`
: `${integrationPath}${davPath}/`;
calendarServerUrl.search = "";
calendarServerUrl.hash = "";
return calendarServerUrl.toString();
};
@@ -21,7 +21,6 @@ import type { ICalendarIntegration } from "../interfaces/calendar/calendar-integ
import type { CalendarEvent } from "../interfaces/calendar/calendar-types";
import type { Notification } from "../interfaces/notifications/notification-types";
import type { INotificationsIntegration } from "../interfaces/notifications/notifications-integration";
import { createNextcloudCalendarServerUrl } from "./nextcloud-url";
// Register all existing timezones
if (ICAL.TimezoneService.count === 0) {
@@ -190,7 +189,7 @@ export class NextcloudIntegration extends Integration implements ICalendarIntegr
private async createCalendarClientAsync(agent?: Agent) {
return new DAVClient({
serverUrl: createNextcloudCalendarServerUrl(this.integration.url),
serverUrl: this.integration.url,
credentials: {
username: this.getSecretValue("username"),
password: this.getSecretValue("password"),
@@ -1,38 +0,0 @@
import type { Agent } from "node:https";
import { DAVClient } from "tsdav";
import { beforeEach, describe, expect, test, vi } from "vitest";
import { NextcloudIntegration } from "../nextcloud.integration";
vi.mock("tsdav", () => ({ DAVClient: vi.fn() }));
interface NextcloudCalendarClientFactory {
createCalendarClientAsync(agent: Agent): Promise<unknown>;
}
describe("NextcloudIntegration", () => {
beforeEach(() => {
vi.mocked(DAVClient).mockClear();
});
test("uses a calendar server URL that preserves the integration subpath", async () => {
const integration = new NextcloudIntegration({
id: "integration-id",
name: "Nextcloud",
url: "https://example.com/nextcloud",
externalUrl: null,
decryptedSecrets: [
{ kind: "username", value: "admin" },
{ kind: "password", value: "password" },
],
});
await (integration as unknown as NextcloudCalendarClientFactory).createCalendarClientAsync({} as Agent);
expect(DAVClient).toHaveBeenCalledWith(
expect.objectContaining({
serverUrl: "https://example.com/nextcloud/remote.php/dav/",
}),
);
});
});
@@ -1,29 +0,0 @@
import { describe, expect, test } from "vitest";
import { createNextcloudCalendarServerUrl } from "../nextcloud-url";
describe("createNextcloudCalendarServerUrl", () => {
test("uses the DAV endpoint for a root installation", () => {
expect(createNextcloudCalendarServerUrl("https://cloud.example.com")).toBe(
"https://cloud.example.com/remote.php/dav/",
);
});
test("preserves the base path for a subpath installation", () => {
expect(createNextcloudCalendarServerUrl("https://example.com/nextcloud")).toBe(
"https://example.com/nextcloud/remote.php/dav/",
);
});
test("does not duplicate a trailing slash", () => {
expect(createNextcloudCalendarServerUrl("https://example.com/nextcloud/")).toBe(
"https://example.com/nextcloud/remote.php/dav/",
);
});
test("does not duplicate an existing DAV endpoint", () => {
expect(createNextcloudCalendarServerUrl("https://example.com/nextcloud/remote.php/dav")).toBe(
"https://example.com/nextcloud/remote.php/dav/",
);
});
});
+23 -23
View File
@@ -25,11 +25,11 @@ catalogs:
specifier: 0.14.9
version: 0.14.9
'@auth/core':
specifier: ^0.41.2
version: 0.41.2
specifier: ^0.41.3
version: 0.41.3
'@auth/drizzle-adapter':
specifier: ^1.11.2
version: 1.11.2
specifier: ^1.11.3
version: 1.11.3
'@babel/parser':
specifier: ^7.29.7
version: 7.29.7
@@ -520,8 +520,8 @@ catalogs:
specifier: 16.3.1
version: 16.3.1
next-auth:
specifier: 5.0.0-beta.31
version: 5.0.0-beta.31
specifier: 5.0.0-beta.32
version: 5.0.0-beta.32
next-intl:
specifier: 4.13.1
version: 4.13.1
@@ -1587,10 +1587,10 @@ importers:
dependencies:
'@auth/core':
specifier: 'catalog:'
version: 0.41.2
version: 0.41.3
'@auth/drizzle-adapter':
specifier: 'catalog:'
version: 1.11.2
version: 1.11.3
'@homarr/common':
specifier: workspace:^0.1.0
version: link:../common
@@ -1620,7 +1620,7 @@ importers:
version: 16.3.1(@babel/core@7.29.0(supports-color@10.2.2))(@opentelemetry/api@1.9.0)(@playwright/test@1.61.1)(@types/node@24.13.3)(babel-plugin-react-compiler@1.0.0)(react-dom@19.2.7(react@19.2.7))(react@19.2.7)(sass@1.101.0)
next-auth:
specifier: 'catalog:'
version: 5.0.0-beta.31(next@16.3.1(@babel/core@7.29.0(supports-color@10.2.2))(@opentelemetry/api@1.9.0)(@playwright/test@1.61.1)(@types/node@24.13.3)(babel-plugin-react-compiler@1.0.0)(react-dom@19.2.7(react@19.2.7))(react@19.2.7)(sass@1.101.0))(react@19.2.7)
version: 5.0.0-beta.32(next@16.3.1(@babel/core@7.29.0(supports-color@10.2.2))(@opentelemetry/api@1.9.0)(@playwright/test@1.61.1)(@types/node@24.13.3)(babel-plugin-react-compiler@1.0.0)(react-dom@19.2.7(react@19.2.7))(react@19.2.7)(sass@1.101.0))(react@19.2.7)
react:
specifier: 'catalog:'
version: 19.2.7
@@ -1989,7 +1989,7 @@ importers:
dependencies:
'@auth/core':
specifier: 'catalog:'
version: 0.41.2
version: 0.41.3
'@homarr/common':
specifier: workspace:^0.1.0
version: link:../common
@@ -3346,12 +3346,12 @@ packages:
react:
optional: true
'@auth/core@0.41.2':
resolution: {integrity: sha512-Hx5MNBxN2fJTbJKGUKAA0wca43D0Akl3TvufY54Gn8lop7F+34vU1zA1pn0vQfIoVuLIrpfc2nkyjwIaPJMW7w==}
'@auth/core@0.41.3':
resolution: {integrity: sha512-sJ3JMHHkXMD3aOjopv7mOBTO1Ocw4b0fAEXJBz6k7YHLpYQI6C40jCUPc5fNvUKxXRXNE1/sRISA15UrwWJBTw==}
peerDependencies:
'@simplewebauthn/browser': ^9.0.1
'@simplewebauthn/server': ^9.0.2
nodemailer: ^7.0.7
nodemailer: ^7.0.7 || ^8.0.5
peerDependenciesMeta:
'@simplewebauthn/browser':
optional: true
@@ -3360,8 +3360,8 @@ packages:
nodemailer:
optional: true
'@auth/drizzle-adapter@1.11.2':
resolution: {integrity: sha512-VOuj7REI8jfJjpSbsYwDM/Zrn55T6lS9Yc+29V+EXMcel8eqG7x+7LodNfd1WHjakfkLYi+qsbYUHB3E6aDA4w==}
'@auth/drizzle-adapter@1.11.3':
resolution: {integrity: sha512-TxqVasPVuf7LDAT1Yuu6bftpuet8o0tjdXW+mXpnXWdSRPQsomdzMoz9RsXkFN/JfdK+/DwdgOEmOTv1gbiFNw==}
'@babel/code-frame@7.29.0':
resolution: {integrity: sha512-9NhCeYjq9+3uxgdtp20LSiJXJvN0FeCtNGpJxuMFZ1Kv3cWUNb6DOhJwUvcVCzKGR66cw4njwM6hrJLqgOwbcw==}
@@ -13685,13 +13685,13 @@ packages:
neverpanic@0.0.8:
resolution: {integrity: sha512-vVdkelrLxaow/fdWDumzNBO+jwm6X8bxeLJc34THtpj70u0C5QBkcV6CRCu2X726km7XD45N0A3QtYCla4RvKw==}
next-auth@5.0.0-beta.31:
resolution: {integrity: sha512-1OBgCKPzo+S7UWWMp3xgvGvIJ0OpV7B3vR4ZDRqD9a4Ch+OT6dakLXG9ivhtmIWVa71nTSXattOHyCg8sNi8/Q==}
next-auth@5.0.0-beta.32:
resolution: {integrity: sha512-CGlChIEWZ6LltNVxrE5yiySMID+Idpmry47JYA5lLwgD8Sx02a8M65VL0TWVz9nbnOioS/tCW/rP/0+mE7Qp4Q==}
peerDependencies:
'@simplewebauthn/browser': ^9.0.1
'@simplewebauthn/server': ^9.0.2
next: ^14.0.0-0 || ^15.0.0 || ^16.0.0
nodemailer: ^7.0.7
nodemailer: ^7.0.7 || ^8.0.5
react: ^18.2.0 || ^19.0.0
peerDependenciesMeta:
'@simplewebauthn/browser':
@@ -17439,7 +17439,7 @@ snapshots:
'@types/react': 19.2.17
react: 19.2.7
'@auth/core@0.41.2':
'@auth/core@0.41.3':
dependencies:
'@panva/hkdf': 1.2.1
jose: 6.2.3
@@ -17447,9 +17447,9 @@ snapshots:
preact: 10.24.3
preact-render-to-string: 6.5.11(preact@10.24.3)
'@auth/drizzle-adapter@1.11.2':
'@auth/drizzle-adapter@1.11.3':
dependencies:
'@auth/core': 0.41.2
'@auth/core': 0.41.3
transitivePeerDependencies:
- '@simplewebauthn/browser'
- '@simplewebauthn/server'
@@ -30001,9 +30001,9 @@ snapshots:
neverpanic@0.0.8: {}
next-auth@5.0.0-beta.31(next@16.3.1(@babel/core@7.29.0(supports-color@10.2.2))(@opentelemetry/api@1.9.0)(@playwright/test@1.61.1)(@types/node@24.13.3)(babel-plugin-react-compiler@1.0.0)(react-dom@19.2.7(react@19.2.7))(react@19.2.7)(sass@1.101.0))(react@19.2.7):
next-auth@5.0.0-beta.32(next@16.3.1(@babel/core@7.29.0(supports-color@10.2.2))(@opentelemetry/api@1.9.0)(@playwright/test@1.61.1)(@types/node@24.13.3)(babel-plugin-react-compiler@1.0.0)(react-dom@19.2.7(react@19.2.7))(react@19.2.7)(sass@1.101.0))(react@19.2.7):
dependencies:
'@auth/core': 0.41.2
'@auth/core': 0.41.3
next: 16.3.1(@babel/core@7.29.0(supports-color@10.2.2))(@opentelemetry/api@1.9.0)(@playwright/test@1.61.1)(@types/node@24.13.3)(babel-plugin-react-compiler@1.0.0)(react-dom@19.2.7(react@19.2.7))(react@19.2.7)(sass@1.101.0)
react: 19.2.7
+3 -3
View File
@@ -14,8 +14,8 @@ catalog:
"@codemirror/state": ^6.6.0
"@codemirror/theme-one-dark": ^6.1.3
"@codemirror/view": ^6.43.0
"@auth/core": ^0.41.2
"@auth/drizzle-adapter": ^1.11.2
"@auth/core": ^0.41.3
"@auth/drizzle-adapter": ^1.11.3
"@ctrl/deluge": ^8.0.0
"@ctrl/qbittorrent": ^9.14.0
"@ctrl/transmission": ^7.4.0
@@ -174,7 +174,7 @@ catalog:
maria2: ^0.4.1
mysql2: 3.22.6
next: 16.3.1
next-auth: 5.0.0-beta.31
next-auth: 5.0.0-beta.32
next-intl: 4.13.1
next-themes: ^0.4.6
node-loader: ^2.1.0