From 412de28f34bf0f8b472e7505491b627614eb812d Mon Sep 17 00:00:00 2001 From: CR0CKER <6056387+CR0CKER@users.noreply.github.com> Date: Mon, 20 Jul 2026 19:43:36 +0200 Subject: [PATCH] refactor: replace axios with fetch for calendar downloads (audit H3) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Removes the axios dependency and the axios.get on the calendar-fetch path — the surface behind axios' SSRF and prototype-pollution advisories. Calendar data is now fetched with the built-in fetch and parsed from a string via node-ical's synchronous parseICS, so no HTTP client touches the response body. Also fixes error handling: fetch does not reject on HTTP error statuses, so the status is checked explicitly. The old code string-matched a 404 error message that fetch never produces and silently swallowed other failures; non-404 failures now surface a message. node-ical still pulls axios@0.24 transitively but it is off the plugin's code path (only its URL-fetch helpers use it, which we don't call). Removing it needs a node-ical major bump, deferred until the parser test suite lands (H2). Typecheck error count unchanged (65). Runtime network behavior (CORS/redirects in the Logseq renderer) not verifiable off-device — needs a manual smoke-test in Logseq before the next release. Co-Authored-By: Claude Opus 4.8 Claude-Session: https://claude.ai/code/session_019cVCdCtNzUJmy1yen3JyBk --- CHANGELOG.md | 18 +++++++++++++++++- index.ts | 34 +++++++++++++++++++--------------- package-lock.json | 10 ---------- package.json | 1 - 4 files changed, 36 insertions(+), 27 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 07181faa..1b2ffefa 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,6 +1,6 @@ # Changelog -Last updated: 2026-07-20 12:31 PM CDT +Last updated: 2026-07-20 12:42 PM CDT All notable changes to this project are documented here. The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/), @@ -8,6 +8,22 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ## [Unreleased] +### Changed + +- **Replaced `axios` with the built-in `fetch`** for calendar downloads and removed + the `axios` dependency. This eliminates axios from the plugin's fetch/parse path — + the surface behind axios' SSRF and prototype-pollution advisories (audit finding + **H3**). Calendar data is fetched with `fetch` and parsed from a string via + `node-ical`'s synchronous `parseICS`, so no HTTP client touches the response body. + - Error handling is now correct: `fetch` does not reject on HTTP error statuses, + so the response status is checked explicitly (the old `axios` code string-matched + a 404 error message that `fetch` never produces, and silently swallowed other + failures). Non-404 failures now surface a message to the user. + - Note: `node-ical` still pulls `axios@0.24` transitively, but it is not on the + plugin's code path (only its URL-fetch helpers use it, which the plugin doesn't + call). Fully removing it requires a `node-ical` major bump — deferred until the + parser test suite exists (audit H2); Dependabot will surface it. + ### Added - **CI workflow** (`.github/workflows/ci.yml`) on every PR and push to `main`: diff --git a/index.ts b/index.ts index 714c6b36..94a26472 100644 --- a/index.ts +++ b/index.ts @@ -1,7 +1,6 @@ import "@logseq/libs"; import { BlockEntity, PageEntity, SettingSchemaDesc } from "@logseq/libs/dist/LSPlugin.user"; import ical from "node-ical"; -import axios from "axios"; import { getDateForPage, getDateForPageWithoutBrackets, @@ -717,23 +716,28 @@ async function openCalendar2(calendarName, url) { logseq.App.showMsg("Fetching Calendar Items"); // Add cache-busting parameter to force fresh calendar data - const cacheBuster = `?nocache=${new Date().getTime()}`; - const urlWithCacheBuster = url.includes('?') ? `${url}&nocache=${new Date().getTime()}` : url + cacheBuster; + const nocache = `nocache=${new Date().getTime()}`; + const urlWithCacheBuster = url.includes("?") ? `${url}&${nocache}` : `${url}?${nocache}`; + + // fetch (unlike the old axios call) does NOT reject on HTTP error statuses — + // only on network failure — so check response.ok explicitly. + const response = await fetch(urlWithCacheBuster); + if (!response.ok) { + if (response.status === 404) { + logseq.App.showMsg("Calendar not found: Check your URL"); + } else { + logseq.App.showMsg(`Failed to fetch "${calendarName}" (HTTP ${response.status})`); + } + console.log(`Calendar fetch failed for ${calendarName}: ${response.status} ${response.statusText}`); + return; + } - let response2 = await axios.get(urlWithCacheBuster); - console.log(response2); - var hello = await rawParser(response2.data); + const rawData = await response.text(); + const hello = await rawParser(rawData); const date = await findDate(preferredDateFormat); - insertJournalBlocks( - hello, - preferredDateFormat, - calendarName, - date - ); + insertJournalBlocks(hello, preferredDateFormat, calendarName, date); } catch (err) { - if (`${err}` == `Error: Request failed with status code 404`) { - logseq.App.showMsg("Calendar not found: Check your URL"); - } + logseq.App.showMsg(`Error fetching "${calendarName}". Check the URL and your connection.`); console.log(err); } } diff --git a/package-lock.json b/package-lock.json index 93be745c..283913f2 100644 --- a/package-lock.json +++ b/package-lock.json @@ -10,7 +10,6 @@ "license": "ISC", "dependencies": { "@logseq/libs": "0.0.6", - "axios": "^0.25.0", "logseq-dateutils": "latest", "moment": "^2.29.3", "moment-timezone": "^0.5.34", @@ -2676,15 +2675,6 @@ "url": "https://github.com/chalk/ansi-styles?sponsor=1" } }, - "node_modules/axios": { - "version": "0.25.0", - "resolved": "https://registry.npmjs.org/axios/-/axios-0.25.0.tgz", - "integrity": "sha512-cD8FOb0tRH3uuEe6+evtAbgJtfxr7ly3fQjYcMcuPlgkwVS9xboaVIpcDV+cYQe+yGykgwZCs1pzjntcGa6l5g==", - "license": "MIT", - "dependencies": { - "follow-redirects": "^1.14.7" - } - }, "node_modules/base-x": { "version": "3.0.11", "resolved": "https://registry.npmjs.org/base-x/-/base-x-3.0.11.tgz", diff --git a/package.json b/package.json index 4ea56926..af9858e4 100644 --- a/package.json +++ b/package.json @@ -17,7 +17,6 @@ "license": "ISC", "dependencies": { "@logseq/libs": "0.0.6", - "axios": "^0.25.0", "logseq-dateutils": "latest", "moment": "^2.29.3", "moment-timezone": "^0.5.34",