From dc5bdd860951ffbeba625de55b19070362dfbd2e Mon Sep 17 00:00:00 2001 From: Lucy Dryaeva <48590492+ShadiestGoat@users.noreply.github.com> Date: Sat, 31 Jan 2026 17:03:20 +0000 Subject: [PATCH] Slight refactor, add support for exact & glob matchers --- package.json | 3 + pnpm-lock.yaml | 35 ++++++-- src/components/Path.svelte | 21 ----- src/components/SettingsPaths.svelte | 29 +++++-- src/components/path/PathWithSuggestion.svelte | 87 +++++++++++++++++++ src/components/path/SinglePath.svelte | 29 +++++++ src/main.ts | 31 +++++-- src/settings.ts | 39 ++++----- src/utils.ts | 18 ++++ 9 files changed, 235 insertions(+), 57 deletions(-) delete mode 100644 src/components/Path.svelte create mode 100644 src/components/path/PathWithSuggestion.svelte create mode 100644 src/components/path/SinglePath.svelte create mode 100644 src/utils.ts diff --git a/package.json b/package.json index f2c1483..dcbcd62 100644 --- a/package.json +++ b/package.json @@ -40,5 +40,8 @@ "tslib": "2.4.0", "typescript": "5.8.3", "typescript-eslint": "^8.29.1" + }, + "dependencies": { + "minimatch": "^10.1.1" } } diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 2e07327..93b3546 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -7,6 +7,10 @@ settings: importers: .: + dependencies: + minimatch: + specifier: ^10.1.1 + version: 10.1.1 devDependencies: '@eslint/js': specifier: ^9.24.0 @@ -287,6 +291,14 @@ packages: resolution: {integrity: sha512-xeO57FpIu4p1Ri3Jq/EXq4ClRm86dVF2z/+kvFnyqVYRavTZmaFaUBbWCOuuTh0o/g7DSsk6kc2vrS4Vl5oPOQ==} engines: {node: '>=18.18'} + '@isaacs/balanced-match@4.0.1': + resolution: {integrity: sha512-yzMTt9lEb8Gv7zRioUilSglI0c0smZ9k5D65677DLWLtWJaXIS3CqcGyUFByYKlnUj6TkjLVs54fBl6+TiGQDQ==} + engines: {node: 20 || >=22} + + '@isaacs/brace-expansion@5.0.0': + resolution: {integrity: sha512-ZT55BDLV0yv0RBm2czMiZ+SqCGO7AvmOM3G/w2xhVPH+te0aKgFjmBvGlL1dH+ql2tgGO3MVrbb3jCKyvpgnxA==} + engines: {node: 20 || >=22} + '@jridgewell/gen-mapping@0.3.8': resolution: {integrity: sha512-imAbBGkb+ebQyxKgzv5Hu2nmROxoDOXHh80evxdoXNOrvAnVx7zimzc1Oo5h9RlfV4vPXaE2iM5pOFbvOCClWA==} engines: {node: '>=6.0.0'} @@ -435,36 +447,43 @@ packages: resolution: {integrity: sha512-FX2FV7vpLE/+Z0NZX9/1pwWud5Wocm/2PgpUXbT5aSV3QEB10kBPJAzssOQylvdj8mOHoKl5pVkXpbCwww/T2g==} cpu: [arm64] os: [linux] + libc: [glibc] '@unrs/resolver-binding-linux-arm64-musl@1.5.0': resolution: {integrity: sha512-+gF97xst1BZb28T3nwwzEtq2ewCoMDGKsenYsZuvpmNrW0019G1iUAunZN+FG55L21y+uP7zsGX06OXDQ/viKw==} cpu: [arm64] os: [linux] + libc: [musl] '@unrs/resolver-binding-linux-ppc64-gnu@1.5.0': resolution: {integrity: sha512-5bEmVcQw9js8JYM2LkUBw5SeELSIxX+qKf9bFrfFINKAp4noZ//hUxLpbF7u/3gTBN1GsER6xOzIZlw/VTdXtA==} cpu: [ppc64] os: [linux] + libc: [glibc] '@unrs/resolver-binding-linux-riscv64-gnu@1.5.0': resolution: {integrity: sha512-GGk/8TPUsf1Q99F+lzMdjE6sGL26uJCwQ9TlvBs8zR3cLQNw/MIumPN7zrs3GFGySjnwXc8gA6J3HKbejywmqA==} cpu: [riscv64] os: [linux] + libc: [glibc] '@unrs/resolver-binding-linux-s390x-gnu@1.5.0': resolution: {integrity: sha512-5uRkFYYVNAeVaA4W/CwugjFN3iDOHCPqsBLCCOoJiMfFMMz4evBRsg+498OFa9w6VcTn2bD5aI+RRayaIgk2Sw==} cpu: [s390x] os: [linux] + libc: [glibc] '@unrs/resolver-binding-linux-x64-gnu@1.5.0': resolution: {integrity: sha512-j905CZH3nehYy6NimNqC2B14pxn4Ltd7guKMyPTzKehbFXTUgihQS/ZfHQTdojkMzbSwBOSgq1dOrY+IpgxDsA==} cpu: [x64] os: [linux] + libc: [glibc] '@unrs/resolver-binding-linux-x64-musl@1.5.0': resolution: {integrity: sha512-dmLevQTuzQRwu5A+mvj54R5aye5I4PVKiWqGxg8tTaYP2k2oTs/3Mo8mgnhPk28VoYCi0fdFYpgzCd4AJndQvQ==} cpu: [x64] os: [linux] + libc: [musl] '@unrs/resolver-binding-wasm32-wasi@1.5.0': resolution: {integrity: sha512-LtJMhwu7avhoi+kKfAZOKN773RtzLBVVF90YJbB0wyMpUj9yQPeA+mteVUI9P70OG/opH47FeV5AWeaNWWgqJg==} @@ -853,8 +872,8 @@ packages: resolution: {integrity: sha512-PXwfBhYu0hBCPw8Dn0E+WDYb7af3dSLVWKi3HGv84IdF4TyFoC0ysxFd0Goxw7nSv4T/PzEJQxsYsEiFCKo2BA==} engines: {node: '>=8.6'} - minimatch@10.0.1: - resolution: {integrity: sha512-ethXTt3SGGR+95gudmqJ1eNhRO7eGEGIgYA9vnPatK4/etz2MEVDno5GMCibdMTuBMyElzIlgxMna3K94XDIDQ==} + minimatch@10.1.1: + resolution: {integrity: sha512-enIvLvRAFZYXJzkCYG5RKmPfrFArdLv+R+lbQ53BmIMLIry74bjKzX6iHAm8WYamJkhSSEabrWN5D97XnKObjQ==} engines: {node: 20 || >=22} minimatch@3.1.2: @@ -1328,6 +1347,12 @@ snapshots: '@humanwhocodes/retry@0.4.2': {} + '@isaacs/balanced-match@4.0.1': {} + + '@isaacs/brace-expansion@5.0.0': + dependencies: + '@isaacs/balanced-match': 4.0.1 + '@jridgewell/gen-mapping@0.3.8': dependencies: '@jridgewell/set-array': 1.2.1 @@ -1685,7 +1710,7 @@ snapshots: eslint-import-resolver-node: 0.3.9 get-tsconfig: 4.10.0 is-glob: 4.0.3 - minimatch: 10.0.1 + minimatch: 10.1.1 semver: 7.7.1 stable-hash: 0.0.5 tslib: 2.8.1 @@ -1925,9 +1950,9 @@ snapshots: braces: 3.0.3 picomatch: 2.3.1 - minimatch@10.0.1: + minimatch@10.1.1: dependencies: - brace-expansion: 2.0.1 + '@isaacs/brace-expansion': 5.0.0 minimatch@3.1.2: dependencies: diff --git a/src/components/Path.svelte b/src/components/Path.svelte deleted file mode 100644 index 6face12..0000000 --- a/src/components/Path.svelte +++ /dev/null @@ -1,21 +0,0 @@ - - - diff --git a/src/components/SettingsPaths.svelte b/src/components/SettingsPaths.svelte index 644a282..b6d9d25 100644 --- a/src/components/SettingsPaths.svelte +++ b/src/components/SettingsPaths.svelte @@ -1,10 +1,11 @@ + + + + diff --git a/src/components/path/SinglePath.svelte b/src/components/path/SinglePath.svelte new file mode 100644 index 0000000..a320fe3 --- /dev/null +++ b/src/components/path/SinglePath.svelte @@ -0,0 +1,29 @@ + + + + +{#key type} + +{/key} diff --git a/src/main.ts b/src/main.ts index 41f5967..b399fe1 100644 --- a/src/main.ts +++ b/src/main.ts @@ -2,9 +2,10 @@ import type { WorkspaceLeaf } from 'obsidian' import { type TFile } from 'obsidian' import { FileView, Notice, Plugin, setIcon } from 'obsidian' import type { Settings } from './settings' -import { DEFAULT_SETTINGS, PrivacyMode, SettingsTab } from './settings' +import { DEFAULT_SETTINGS, PrivacyMode, ProtectedPathType, SettingsTab } from './settings' import { RequirePasswordModal } from './modals' import { modifySearchLeaf } from './search' +import { normalizePath, pathComparer } from './utils' const STR_RIBBON_LOCKED = 'Vault is locked' const STR_RIBBON_UNLOCKED = 'Vault is unlocked' @@ -124,10 +125,9 @@ export default class SimplePassword extends Plugin { } isPathLocked(testPath: string): boolean { - for (const _p of this.settings.protectedPaths) { - const p = decodeURIComponent(new URL(_p, 'file://').pathname) - - if (('/' + testPath).startsWith(p)) { + testPath = normalizePath(testPath) + for (const pp of this.settings.protectedPaths) { + if (pathComparer[pp.type](pp.content, testPath)) { return true } } @@ -263,6 +263,27 @@ export default class SimplePassword extends Plugin { async loadSettings() { this.settings = Object.assign({}, DEFAULT_SETTINGS, await this.loadData()) + await this.migrateSettings() + } + + async migrateSettings() { + let changed = false + if (this.settings.protectedPaths.length != 0) { + this.settings.protectedPaths = this.settings.protectedPaths.map(v => { + if (typeof v == "string") { + changed = true + return { + type: ProtectedPathType.PREFIX, + content: v + } + } + return v + }) + } + + if (changed) { + await this.saveSettings() + } } async saveSettings() { diff --git a/src/settings.ts b/src/settings.ts index d87a147..a5cdbf3 100644 --- a/src/settings.ts +++ b/src/settings.ts @@ -12,19 +12,35 @@ export enum PrivacyMode { NONE = '' } +export enum ProtectedPathType { + PREFIX = 'prefix', + EXACT = 'exact', + GLOB = 'glob', +} + +export interface ProtectedPath { + type: ProtectedPathType + content: string +} + export interface Settings { autoLockMinutes: number privacyMode: PrivacyMode - protectedPaths: string[] hint: string password: string blockGraph: boolean + protectedPaths: ProtectedPath[] } export const DEFAULT_SETTINGS: Settings = { autoLockMinutes: 15, privacyMode: PrivacyMode.BLUR, - protectedPaths: ['/'], + protectedPaths: [ + { + type: ProtectedPathType.PREFIX, + content: '/' + } + ], hint: '', password: '', blockGraph: true @@ -214,22 +230,3 @@ export class SettingsTab extends PluginSettingTab { super.hide() } } - -export class PathSuggestions extends AbstractInputSuggest { - protected getSuggestions(query: string): string[] { - const p = new URL(query, 'file://').pathname - - return this.app.vault - .getAllFolders(true) - .filter((v) => { - if (('/' + v.path).startsWith(p)) { - return true - } - }) - .map((v) => v.path) - } - - renderSuggestion(value: string, el: HTMLElement): void { - el.setText(value) - } -} diff --git a/src/utils.ts b/src/utils.ts new file mode 100644 index 0000000..bc9722d --- /dev/null +++ b/src/utils.ts @@ -0,0 +1,18 @@ +import { minimatch } from "minimatch" +import { ProtectedPathType } from "./settings" + +export function normalizePath(str: string) { + return decodeURIComponent(new URL(str, 'file://').pathname) +} + +export const pathComparer: Record boolean> = { + [ProtectedPathType.PREFIX]: (content, realPath) => { + return realPath.startsWith(content) + }, + [ProtectedPathType.EXACT]: (content, realPath) => { + return normalizePath(content) == normalizePath(realPath) + }, + [ProtectedPathType.GLOB]: (content, realPath) => { + return minimatch(realPath, content) + } +}