diff --git a/CHANGELOG.md b/CHANGELOG.md index 68015c1..b027f00 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,7 +2,60 @@ All notable changes to this project will be documented in this file. -## [0.4.0] - Basil (2026-03-18) +## [0.6.1] - Slifer (2026-03-24) + +### Added + +- `fetch()` shim that proxies cross-origin requests through `/api/proxy` to bypass CORS restrictions +- Automatic `Origin: app://obsidian.md` header injection for cross-origin requests to match Obsidian desktop app +- User-Agent forwarding from browser to proxy for cross-origin requests + +### Fixed + +- Obsidian Sync API authentication now works in browser (was blocked by CORS) +- Proxy response headers cleaned to exclude hop-by-hop headers (`content-encoding`, `transfer-encoding`, `content-length`, `connection`) + +## [0.6.0] - Slifer (2026-03-23) + +### Added + +- `zlib` shim using `pako` library for compression/decompression operations (deflate, inflate, gzip, gunzip, etc.) +- File descriptor operations: `fs.open()`, `fs.read()`, `fs.close()`, `fs.fstat()` and sync variants +- `fs.promises.open()` returning FileHandle objects with `stat()`, `read()`, `close()` methods +- `showOpenDialog` electron dialog shim with browser file picker and vault upload +- `showOpenDialogSync` hacky workaround using file staging registry and two-step upload flow +- Enhanced `Buffer` shim with `alloc()`, `allocUnsafe()`, `byteLength()`, and `isEncoding()` methods + +### Fixed + +- `MessageDialog` modal dismiss error when confirm button clicked +- Dialog shim modal event ordering to prevent null reference errors + +## [0.5.0] - Scatha (2026-03-22) + +### Added + +- Compression middleware (gzip/brotli) for API responses to reduce bandwidth +- Plugin installation prompt system with per-vault trust flags +- Versioning system with cache-busting query parameters on script URLs +- Option to install ignis-bridge plugin to vaults imported at runtime + +### Changed + +- Auto-creation of default vault now requires `AUTO_CREATE_DEFAULT=true` environment variable +- Script URLs (`ignis-ui.js`, `shim-loader.js`) now include version query params for automatic cache invalidation +- Cache headers: versioned assets cached for 1 year, non-versioned for 5 minutes + +### Fixed + +- Vault manager not displaying when no vaults exist +- `window.close()` now shows vault manager when no vault is configured + +### Removed + +- Unused `VAULT_PATH` environment variable fallback logic + +## [0.4.0] - Gostir (2026-03-18) ### Added diff --git a/package-lock.json b/package-lock.json index c853069..2810674 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,16 +1,18 @@ { "name": "ignis", - "version": "0.1.0", + "version": "0.5.0", "lockfileVersion": 3, "requires": true, "packages": { "": { "name": "ignis", - "version": "0.1.0", + "version": "0.5.0", "dependencies": { "chokidar": "^3.6.0", + "compression": "^1.7.4", "cors": "^2.8.5", "express": "^4.21.0", + "pako": "^2.1.0", "ws": "^8.16.0" }, "devDependencies": { @@ -661,6 +663,45 @@ "periscopic": "^3.1.0" } }, + "node_modules/compressible": { + "version": "2.0.18", + "resolved": "https://registry.npmjs.org/compressible/-/compressible-2.0.18.tgz", + "integrity": "sha512-AF3r7P5dWxL8MxyITRMlORQNaOA2IkAFaTr4k7BUumjPtRpGDTZpl0Pb1XCO6JeDCBdp126Cgs9sMxqSjgYyRg==", + "license": "MIT", + "dependencies": { + "mime-db": ">= 1.43.0 < 2" + }, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/compression": { + "version": "1.8.1", + "resolved": "https://registry.npmjs.org/compression/-/compression-1.8.1.tgz", + "integrity": "sha512-9mAqGPHLakhCLeNyxPkK4xVo746zQ/czLH1Ky+vkitMnWfWZps8r0qXuwhwizagCRttsL4lfG4pIOvaWLpAP0w==", + "license": "MIT", + "dependencies": { + "bytes": "3.1.2", + "compressible": "~2.0.18", + "debug": "2.6.9", + "negotiator": "~0.6.4", + "on-headers": "~1.1.0", + "safe-buffer": "5.2.1", + "vary": "~1.1.2" + }, + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/compression/node_modules/negotiator": { + "version": "0.6.4", + "resolved": "https://registry.npmjs.org/negotiator/-/negotiator-0.6.4.tgz", + "integrity": "sha512-myRT3DiWPHqho5PrJaIRyaMv2kgYf0mUVgBNOYMuCH5Ki1yEiQaf/ZJuQ62nvpc44wL5WDbTX7yGJi1Neevw8w==", + "license": "MIT", + "engines": { + "node": ">= 0.6" + } + }, "node_modules/content-disposition": { "version": "0.5.4", "resolved": "https://registry.npmjs.org/content-disposition/-/content-disposition-0.5.4.tgz", @@ -1357,6 +1398,21 @@ "node": ">= 0.8" } }, + "node_modules/on-headers": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/on-headers/-/on-headers-1.1.0.tgz", + "integrity": "sha512-737ZY3yNnXy37FHkQxPzt4UZ2UWPWiCZWLvFZ4fu5cueciegX0zGPnrlY6bwRg4FdQOe9YU8MkmJwGhoMybl8A==", + "license": "MIT", + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/pako": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/pako/-/pako-2.1.0.tgz", + "integrity": "sha512-w+eufiZ1WuJYgPXbV/PO3NCMEc3xqylkKHzp8bxp1uW4qaSNQUkwmLLEc3kKsfz8lpV1F8Ht3U1Cm+9Srog2ug==", + "license": "(MIT AND Zlib)" + }, "node_modules/parseurl": { "version": "1.3.3", "resolved": "https://registry.npmjs.org/parseurl/-/parseurl-1.3.3.tgz", diff --git a/package.json b/package.json index 30cc8b4..d1a7c04 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "ignis", - "version": "0.4.0", + "version": "0.6.1", "private": true, "description": "An Electron shim and server bridge for running Obsidian in a browser.", "scripts": { @@ -10,8 +10,10 @@ }, "dependencies": { "chokidar": "^3.6.0", + "compression": "^1.7.4", "cors": "^2.8.5", "express": "^4.21.0", + "pako": "^2.1.0", "ws": "^8.16.0" }, "devDependencies": { diff --git a/scripts/patch-obsidian.js b/scripts/patch-obsidian.js index c11b673..023353e 100644 --- a/scripts/patch-obsidian.js +++ b/scripts/patch-obsidian.js @@ -6,6 +6,7 @@ const fs = require("fs"); const path = require("path"); +const { getVersion } = require("../server/version"); const asarDir = process.argv[2]; if (!asarDir) { @@ -13,7 +14,7 @@ if (!asarDir) { process.exit(1); } -function patchHtml(filePath) { +function patchHtml(filePath, version) { const backupPath = filePath + ".orig"; if (!fs.existsSync(filePath) && !fs.existsSync(backupPath)) { @@ -46,8 +47,8 @@ function patchHtml(filePath) { // Inject ignis scripts before the first \n' + - '\n' + + `\n` + + `\n` + ' + + + + + + +
+

This vault doesn't have the Ignis Bridge plugin installed.

+

+ The plugin adds additional functionality such as file uploads. + Obsidian will work without it, but some features will be unavailable. +

+
+ + + + +
+ + diff --git a/src/ui/index.js b/src/ui/index.js index 11fd0d4..6fdb228 100644 --- a/src/ui/index.js +++ b/src/ui/index.js @@ -2,3 +2,4 @@ export { default as VaultManager } from "./views/VaultManager.svelte"; export { default as MessageDialog } from "./components/layout/MessageDialog.svelte"; export { default as ConfirmDialog } from "./components/layout/ConfirmDialog.svelte"; export { default as PromptDialog } from "./components/layout/PromptDialog.svelte"; +export { default as PluginInstallDialog } from "./components/layout/PluginInstallDialog.svelte"; diff --git a/src/ui/views/VaultManager.svelte b/src/ui/views/VaultManager.svelte index ffe8589..59c2048 100644 --- a/src/ui/views/VaultManager.svelte +++ b/src/ui/views/VaultManager.svelte @@ -30,6 +30,7 @@ let dialogValue = ""; let errorMessage = ""; let pendingReload = false; + let version = ""; const menuItems = [ { id: "rename", label: "Rename" }, @@ -47,6 +48,16 @@ ) : vaults; + async function fetchVersion() { + try { + const res = await fetch("/api/version"); + const data = await res.json(); + version = data.version; + } catch (e) { + console.warn("[VaultManager] Failed to fetch version:", e); + } + } + async function refreshVaults() { try { vaults = await vaultService.listVaults(); @@ -177,6 +188,7 @@ onMount(() => { refreshVaults(); + fetchVersion(); }); @@ -246,6 +258,11 @@ +