/* THIS IS A GENERATED/BUNDLED FILE BY ESBUILD if you want to view the source, please visit the github repository of this plugin */ var __create = Object.create; var __defProp = Object.defineProperty; var __getOwnPropDesc = Object.getOwnPropertyDescriptor; var __getOwnPropNames = Object.getOwnPropertyNames; var __getProtoOf = Object.getPrototypeOf; var __hasOwnProp = Object.prototype.hasOwnProperty; var __esm = (fn, res) => function __init() { return fn && (res = (0, fn[__getOwnPropNames(fn)[0]])(fn = 0)), res; }; var __commonJS = (cb, mod) => function __require() { return mod || (0, cb[__getOwnPropNames(cb)[0]])((mod = { exports: {} }).exports, mod), mod.exports; }; var __export = (target, all) => { for (var name in all) __defProp(target, name, { get: all[name], enumerable: true }); }; var __copyProps = (to, from, except, desc) => { if (from && typeof from === "object" || typeof from === "function") { for (let key of __getOwnPropNames(from)) if (!__hasOwnProp.call(to, key) && key !== except) __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable }); } return to; }; var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps( // If the importer is in node compatibility mode or this is not an ESM // file that has been converted to a CommonJS file using a Babel- // compatible transform (i.e. "__esModule" has not been set), then set // "default" to the CommonJS "module.exports" for node compatibility. isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target, mod )); var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod); // node_modules/argon2-browser/dist/argon2.js var require_argon2 = __commonJS({ "node_modules/argon2-browser/dist/argon2.js"(exports, module2) { var Module2 = typeof self !== "undefined" && typeof self.Module !== "undefined" ? self.Module : {}; var jsModule = Module2; var moduleOverrides = {}; var key; for (key in Module2) { if (Module2.hasOwnProperty(key)) { moduleOverrides[key] = Module2[key]; } } var arguments_ = []; var thisProgram = "./this.program"; var quit_ = function(status, toThrow) { throw toThrow; }; var ENVIRONMENT_IS_WEB = false; var ENVIRONMENT_IS_WORKER = false; var ENVIRONMENT_IS_NODE = false; var ENVIRONMENT_IS_SHELL = false; ENVIRONMENT_IS_WEB = typeof window === "object"; ENVIRONMENT_IS_WORKER = typeof importScripts === "function"; ENVIRONMENT_IS_NODE = typeof process === "object" && typeof process.versions === "object" && typeof process.versions.node === "string"; ENVIRONMENT_IS_SHELL = !ENVIRONMENT_IS_WEB && !ENVIRONMENT_IS_NODE && !ENVIRONMENT_IS_WORKER; var scriptDirectory = ""; function locateFile(path) { if (Module2["locateFile"]) { return Module2["locateFile"](path, scriptDirectory); } return scriptDirectory + path; } var read_; var readAsync; var readBinary; var setWindowTitle; var nodeFS; var nodePath; if (ENVIRONMENT_IS_NODE) { if (ENVIRONMENT_IS_WORKER) { scriptDirectory = require("path").dirname(scriptDirectory) + "/"; } else { scriptDirectory = __dirname + "/"; } read_ = function shell_read(filename, binary) { if (!nodeFS) nodeFS = require("fs"); if (!nodePath) nodePath = require("path"); filename = nodePath["normalize"](filename); return nodeFS["readFileSync"](filename, binary ? null : "utf8"); }; readBinary = function readBinary2(filename) { var ret = read_(filename, true); if (!ret.buffer) { ret = new Uint8Array(ret); } assert(ret.buffer); return ret; }; if (process["argv"].length > 1) { thisProgram = process["argv"][1].replace(/\\/g, "/"); } arguments_ = process["argv"].slice(2); if (typeof module2 !== "undefined") { module2["exports"] = Module2; } process["on"]("uncaughtException", function(ex) { if (!(ex instanceof ExitStatus)) { throw ex; } }); process["on"]("unhandledRejection", abort); quit_ = function(status) { process["exit"](status); }; Module2["inspect"] = function() { return "[Emscripten Module object]"; }; } else if (ENVIRONMENT_IS_SHELL) { if (typeof read != "undefined") { read_ = function shell_read(f) { return read(f); }; } readBinary = function readBinary2(f) { var data; if (typeof readbuffer === "function") { return new Uint8Array(readbuffer(f)); } data = read(f, "binary"); assert(typeof data === "object"); return data; }; if (typeof scriptArgs != "undefined") { arguments_ = scriptArgs; } else if (typeof arguments != "undefined") { arguments_ = arguments; } if (typeof quit === "function") { quit_ = function(status) { quit(status); }; } if (typeof print !== "undefined") { if (typeof console === "undefined") console = {}; console.log = print; console.warn = console.error = typeof printErr !== "undefined" ? printErr : print; } } else if (ENVIRONMENT_IS_WEB || ENVIRONMENT_IS_WORKER) { if (ENVIRONMENT_IS_WORKER) { scriptDirectory = self.location.href; } else if (typeof document !== "undefined" && document.currentScript) { scriptDirectory = document.currentScript.src; } if (scriptDirectory.indexOf("blob:") !== 0) { scriptDirectory = scriptDirectory.substr(0, scriptDirectory.lastIndexOf("/") + 1); } else { scriptDirectory = ""; } { read_ = function(url) { var xhr = new XMLHttpRequest(); xhr.open("GET", url, false); xhr.send(null); return xhr.responseText; }; if (ENVIRONMENT_IS_WORKER) { readBinary = function(url) { var xhr = new XMLHttpRequest(); xhr.open("GET", url, false); xhr.responseType = "arraybuffer"; xhr.send(null); return new Uint8Array(xhr.response); }; } readAsync = function(url, onload, onerror) { var xhr = new XMLHttpRequest(); xhr.open("GET", url, true); xhr.responseType = "arraybuffer"; xhr.onload = function() { if (xhr.status == 200 || xhr.status == 0 && xhr.response) { onload(xhr.response); return; } onerror(); }; xhr.onerror = onerror; xhr.send(null); }; } setWindowTitle = function(title) { document.title = title; }; } else { } var out = Module2["print"] || console.log.bind(console); var err = Module2["printErr"] || console.warn.bind(console); for (key in moduleOverrides) { if (moduleOverrides.hasOwnProperty(key)) { Module2[key] = moduleOverrides[key]; } } moduleOverrides = null; if (Module2["arguments"]) arguments_ = Module2["arguments"]; if (Module2["thisProgram"]) thisProgram = Module2["thisProgram"]; if (Module2["quit"]) quit_ = Module2["quit"]; var wasmBinary; if (Module2["wasmBinary"]) wasmBinary = Module2["wasmBinary"]; var noExitRuntime = Module2["noExitRuntime"] || true; if (typeof WebAssembly !== "object") { abort("no native wasm support detected"); } var wasmMemory; var ABORT = false; var EXITSTATUS; function assert(condition, text) { if (!condition) { abort("Assertion failed: " + text); } } var ALLOC_NORMAL = 0; var ALLOC_STACK = 1; function allocate(slab, allocator) { var ret; if (allocator == ALLOC_STACK) { ret = stackAlloc(slab.length); } else { ret = _malloc(slab.length); } if (slab.subarray || slab.slice) { HEAPU8.set(slab, ret); } else { HEAPU8.set(new Uint8Array(slab), ret); } return ret; } var UTF8Decoder = typeof TextDecoder !== "undefined" ? new TextDecoder("utf8") : void 0; function UTF8ArrayToString(heap, idx, maxBytesToRead) { var endIdx = idx + maxBytesToRead; var endPtr = idx; while (heap[endPtr] && !(endPtr >= endIdx)) ++endPtr; if (endPtr - idx > 16 && heap.subarray && UTF8Decoder) { return UTF8Decoder.decode(heap.subarray(idx, endPtr)); } else { var str = ""; while (idx < endPtr) { var u0 = heap[idx++]; if (!(u0 & 128)) { str += String.fromCharCode(u0); continue; } var u1 = heap[idx++] & 63; if ((u0 & 224) == 192) { str += String.fromCharCode((u0 & 31) << 6 | u1); continue; } var u2 = heap[idx++] & 63; if ((u0 & 240) == 224) { u0 = (u0 & 15) << 12 | u1 << 6 | u2; } else { u0 = (u0 & 7) << 18 | u1 << 12 | u2 << 6 | heap[idx++] & 63; } if (u0 < 65536) { str += String.fromCharCode(u0); } else { var ch = u0 - 65536; str += String.fromCharCode(55296 | ch >> 10, 56320 | ch & 1023); } } } return str; } function UTF8ToString(ptr, maxBytesToRead) { return ptr ? UTF8ArrayToString(HEAPU8, ptr, maxBytesToRead) : ""; } function alignUp(x, multiple) { if (x % multiple > 0) { x += multiple - x % multiple; } return x; } var buffer; var HEAP8; var HEAPU8; var HEAP16; var HEAPU16; var HEAP32; var HEAPU32; var HEAPF32; var HEAPF64; function updateGlobalBufferAndViews(buf) { buffer = buf; Module2["HEAP8"] = HEAP8 = new Int8Array(buf); Module2["HEAP16"] = HEAP16 = new Int16Array(buf); Module2["HEAP32"] = HEAP32 = new Int32Array(buf); Module2["HEAPU8"] = HEAPU8 = new Uint8Array(buf); Module2["HEAPU16"] = HEAPU16 = new Uint16Array(buf); Module2["HEAPU32"] = HEAPU32 = new Uint32Array(buf); Module2["HEAPF32"] = HEAPF32 = new Float32Array(buf); Module2["HEAPF64"] = HEAPF64 = new Float64Array(buf); } var INITIAL_MEMORY = Module2["INITIAL_MEMORY"] || 16777216; var wasmTable; var __ATPRERUN__ = []; var __ATINIT__ = []; var __ATPOSTRUN__ = []; var runtimeInitialized = false; function preRun() { if (Module2["preRun"]) { if (typeof Module2["preRun"] == "function") Module2["preRun"] = [Module2["preRun"]]; while (Module2["preRun"].length) { addOnPreRun(Module2["preRun"].shift()); } } callRuntimeCallbacks(__ATPRERUN__); } function initRuntime() { runtimeInitialized = true; callRuntimeCallbacks(__ATINIT__); } function postRun() { if (Module2["postRun"]) { if (typeof Module2["postRun"] == "function") Module2["postRun"] = [Module2["postRun"]]; while (Module2["postRun"].length) { addOnPostRun(Module2["postRun"].shift()); } } callRuntimeCallbacks(__ATPOSTRUN__); } function addOnPreRun(cb) { __ATPRERUN__.unshift(cb); } function addOnInit(cb) { __ATINIT__.unshift(cb); } function addOnPostRun(cb) { __ATPOSTRUN__.unshift(cb); } var runDependencies = 0; var runDependencyWatcher = null; var dependenciesFulfilled = null; function addRunDependency(id) { runDependencies++; if (Module2["monitorRunDependencies"]) { Module2["monitorRunDependencies"](runDependencies); } } function removeRunDependency(id) { runDependencies--; if (Module2["monitorRunDependencies"]) { Module2["monitorRunDependencies"](runDependencies); } if (runDependencies == 0) { if (runDependencyWatcher !== null) { clearInterval(runDependencyWatcher); runDependencyWatcher = null; } if (dependenciesFulfilled) { var callback = dependenciesFulfilled; dependenciesFulfilled = null; callback(); } } } Module2["preloadedImages"] = {}; Module2["preloadedAudios"] = {}; function abort(what) { if (Module2["onAbort"]) { Module2["onAbort"](what); } what += ""; err(what); ABORT = true; EXITSTATUS = 1; what = "abort(" + what + "). Build with -s ASSERTIONS=1 for more info."; var e = new WebAssembly.RuntimeError(what); throw e; } var dataURIPrefix = "data:application/octet-stream;base64,"; function isDataURI(filename) { return filename.startsWith(dataURIPrefix); } function isFileURI(filename) { return filename.startsWith("file://"); } var wasmBinaryFile = "argon2.wasm"; if (!isDataURI(wasmBinaryFile)) { wasmBinaryFile = locateFile(wasmBinaryFile); } function getBinary(file) { try { if (file == wasmBinaryFile && wasmBinary) { return new Uint8Array(wasmBinary); } if (readBinary) { return readBinary(file); } else { throw "both async and sync fetching of the wasm failed"; } } catch (err2) { abort(err2); } } function getBinaryPromise() { if (!wasmBinary && (ENVIRONMENT_IS_WEB || ENVIRONMENT_IS_WORKER)) { if (typeof fetch === "function" && !isFileURI(wasmBinaryFile)) { return fetch(wasmBinaryFile, { credentials: "same-origin" }).then(function(response) { if (!response["ok"]) { throw "failed to load wasm binary file at '" + wasmBinaryFile + "'"; } return response["arrayBuffer"](); }).catch(function() { return getBinary(wasmBinaryFile); }); } else { if (readAsync) { return new Promise(function(resolve, reject) { readAsync(wasmBinaryFile, function(response) { resolve(new Uint8Array(response)); }, reject); }); } } } return Promise.resolve().then(function() { return getBinary(wasmBinaryFile); }); } function createWasm() { var info = { "a": asmLibraryArg }; function receiveInstance(instance, module3) { var exports3 = instance.exports; Module2["asm"] = exports3; wasmMemory = Module2["asm"]["c"]; updateGlobalBufferAndViews(wasmMemory.buffer); wasmTable = Module2["asm"]["k"]; addOnInit(Module2["asm"]["d"]); removeRunDependency("wasm-instantiate"); } addRunDependency("wasm-instantiate"); function receiveInstantiationResult(result) { receiveInstance(result["instance"]); } function instantiateArrayBuffer(receiver) { return getBinaryPromise().then(function(binary) { var result = WebAssembly.instantiate(binary, info); return result; }).then(receiver, function(reason) { err("failed to asynchronously prepare wasm: " + reason); abort(reason); }); } function instantiateAsync() { if (!wasmBinary && typeof WebAssembly.instantiateStreaming === "function" && !isDataURI(wasmBinaryFile) && !isFileURI(wasmBinaryFile) && typeof fetch === "function") { return fetch(wasmBinaryFile, { credentials: "same-origin" }).then(function(response) { var result = WebAssembly.instantiateStreaming(response, info); return result.then(receiveInstantiationResult, function(reason) { err("wasm streaming compile failed: " + reason); err("falling back to ArrayBuffer instantiation"); return instantiateArrayBuffer(receiveInstantiationResult); }); }); } else { return instantiateArrayBuffer(receiveInstantiationResult); } } if (Module2["instantiateWasm"]) { try { var exports2 = Module2["instantiateWasm"](info, receiveInstance); return exports2; } catch (e) { err("Module.instantiateWasm callback failed with error: " + e); return false; } } instantiateAsync(); return {}; } function callRuntimeCallbacks(callbacks) { while (callbacks.length > 0) { var callback = callbacks.shift(); if (typeof callback == "function") { callback(Module2); continue; } var func = callback.func; if (typeof func === "number") { if (callback.arg === void 0) { wasmTable.get(func)(); } else { wasmTable.get(func)(callback.arg); } } else { func(callback.arg === void 0 ? null : callback.arg); } } } function _emscripten_memcpy_big(dest, src, num) { HEAPU8.copyWithin(dest, src, src + num); } function emscripten_realloc_buffer(size) { try { wasmMemory.grow(size - buffer.byteLength + 65535 >>> 16); updateGlobalBufferAndViews(wasmMemory.buffer); return 1; } catch (e) { } } function _emscripten_resize_heap(requestedSize) { var oldSize = HEAPU8.length; requestedSize = requestedSize >>> 0; var maxHeapSize = 2147418112; if (requestedSize > maxHeapSize) { return false; } for (var cutDown = 1; cutDown <= 4; cutDown *= 2) { var overGrownHeapSize = oldSize * (1 + 0.2 / cutDown); overGrownHeapSize = Math.min(overGrownHeapSize, requestedSize + 100663296); var newSize = Math.min(maxHeapSize, alignUp(Math.max(requestedSize, overGrownHeapSize), 65536)); var replacement = emscripten_realloc_buffer(newSize); if (replacement) { return true; } } return false; } var asmLibraryArg = { "a": _emscripten_memcpy_big, "b": _emscripten_resize_heap }; var asm = createWasm(); var ___wasm_call_ctors = Module2["___wasm_call_ctors"] = function() { return (___wasm_call_ctors = Module2["___wasm_call_ctors"] = Module2["asm"]["d"]).apply(null, arguments); }; var _argon2_hash = Module2["_argon2_hash"] = function() { return (_argon2_hash = Module2["_argon2_hash"] = Module2["asm"]["e"]).apply(null, arguments); }; var _malloc = Module2["_malloc"] = function() { return (_malloc = Module2["_malloc"] = Module2["asm"]["f"]).apply(null, arguments); }; var _free = Module2["_free"] = function() { return (_free = Module2["_free"] = Module2["asm"]["g"]).apply(null, arguments); }; var _argon2_verify = Module2["_argon2_verify"] = function() { return (_argon2_verify = Module2["_argon2_verify"] = Module2["asm"]["h"]).apply(null, arguments); }; var _argon2_error_message = Module2["_argon2_error_message"] = function() { return (_argon2_error_message = Module2["_argon2_error_message"] = Module2["asm"]["i"]).apply(null, arguments); }; var _argon2_encodedlen = Module2["_argon2_encodedlen"] = function() { return (_argon2_encodedlen = Module2["_argon2_encodedlen"] = Module2["asm"]["j"]).apply(null, arguments); }; var _argon2_hash_ext = Module2["_argon2_hash_ext"] = function() { return (_argon2_hash_ext = Module2["_argon2_hash_ext"] = Module2["asm"]["l"]).apply(null, arguments); }; var _argon2_verify_ext = Module2["_argon2_verify_ext"] = function() { return (_argon2_verify_ext = Module2["_argon2_verify_ext"] = Module2["asm"]["m"]).apply(null, arguments); }; var stackAlloc = Module2["stackAlloc"] = function() { return (stackAlloc = Module2["stackAlloc"] = Module2["asm"]["n"]).apply(null, arguments); }; Module2["allocate"] = allocate; Module2["UTF8ToString"] = UTF8ToString; Module2["ALLOC_NORMAL"] = ALLOC_NORMAL; var calledRun; function ExitStatus(status) { this.name = "ExitStatus"; this.message = "Program terminated with exit(" + status + ")"; this.status = status; } dependenciesFulfilled = function runCaller() { if (!calledRun) run(); if (!calledRun) dependenciesFulfilled = runCaller; }; function run(args) { args = args || arguments_; if (runDependencies > 0) { return; } preRun(); if (runDependencies > 0) { return; } function doRun() { if (calledRun) return; calledRun = true; Module2["calledRun"] = true; if (ABORT) return; initRuntime(); if (Module2["onRuntimeInitialized"]) Module2["onRuntimeInitialized"](); postRun(); } if (Module2["setStatus"]) { Module2["setStatus"]("Running..."); setTimeout(function() { setTimeout(function() { Module2["setStatus"](""); }, 1); doRun(); }, 1); } else { doRun(); } } Module2["run"] = run; if (Module2["preInit"]) { if (typeof Module2["preInit"] == "function") Module2["preInit"] = [Module2["preInit"]]; while (Module2["preInit"].length > 0) { Module2["preInit"].pop()(); } } run(); if (typeof module2 !== "undefined") module2.exports = Module2; Module2.unloadRuntime = function() { if (typeof self !== "undefined") { delete self.Module; } Module2 = jsModule = wasmMemory = wasmTable = asm = buffer = HEAP8 = HEAPU8 = HEAP16 = HEAPU16 = HEAP32 = HEAPU32 = HEAPF32 = HEAPF64 = void 0; if (typeof module2 !== "undefined") { delete module2.exports; } }; } }); // node_modules/argon2-browser/dist/argon2.wasm var require_argon22 = __commonJS({ "node_modules/argon2-browser/dist/argon2.wasm"(exports, module2) { module2.exports = "./assets/argon2.wasm"; } }); // node_modules/argon2-browser/lib/argon2.js var require_argon23 = __commonJS({ "node_modules/argon2-browser/lib/argon2.js"(exports, module2) { (function(root, factory) { if (typeof define === "function" && define.amd) { define([], factory); } else if (typeof module2 === "object" && module2.exports) { module2.exports = factory(); } else { root.argon2 = factory(); } })(typeof self !== "undefined" ? self : exports, function() { const global = typeof self !== "undefined" ? self : this; const ArgonType = { Argon2d: 0, Argon2i: 1, Argon2id: 2 }; function loadModule(mem) { if (loadModule._promise) { return loadModule._promise; } if (loadModule._module) { return Promise.resolve(loadModule._module); } let promise; if (global.process && global.process.versions && global.process.versions.node) { promise = loadWasmModule().then( (Module2) => new Promise((resolve) => { Module2.postRun = () => resolve(Module2); }) ); } else { promise = loadWasmBinary().then((wasmBinary) => { const wasmMemory = mem ? createWasmMemory(mem) : void 0; return initWasm(wasmBinary, wasmMemory); }); } loadModule._promise = promise; return promise.then((Module2) => { loadModule._module = Module2; delete loadModule._promise; return Module2; }); } function initWasm(wasmBinary, wasmMemory) { return new Promise((resolve) => { global.Module = { wasmBinary, wasmMemory, postRun() { resolve(Module); } }; return loadWasmModule(); }); } function loadWasmModule() { if (global.loadArgon2WasmModule) { return global.loadArgon2WasmModule(); } if (typeof require === "function") { return Promise.resolve(require_argon2()); } return Promise.resolve().then(() => __toESM(require_argon2())); } function loadWasmBinary() { if (global.loadArgon2WasmBinary) { return global.loadArgon2WasmBinary(); } if (typeof require === "function") { return Promise.resolve(require_argon22()).then( (wasmModule) => { return decodeWasmBinary(wasmModule); } ); } const wasmPath = global.argon2WasmPath || "node_modules/argon2-browser/dist/argon2.wasm"; return fetch(wasmPath).then((response) => response.arrayBuffer()).then((ab) => new Uint8Array(ab)); } function decodeWasmBinary(base64) { const text = atob(base64); const binary = new Uint8Array(new ArrayBuffer(text.length)); for (let i = 0; i < text.length; i++) { binary[i] = text.charCodeAt(i); } return binary; } function createWasmMemory(mem) { const KB = 1024; const MB = 1024 * KB; const GB = 1024 * MB; const WASM_PAGE_SIZE = 64 * KB; const totalMemory = (2 * GB - 64 * KB) / WASM_PAGE_SIZE; const initialMemory = Math.min( Math.max(Math.ceil(mem * KB / WASM_PAGE_SIZE), 256) + 256, totalMemory ); return new WebAssembly.Memory({ initial: initialMemory, maximum: totalMemory }); } function allocateArray(Module2, arr) { return Module2.allocate(arr, "i8", Module2.ALLOC_NORMAL); } function allocateArrayStr(Module2, arr) { const nullTerminatedArray = new Uint8Array([...arr, 0]); return allocateArray(Module2, nullTerminatedArray); } function encodeUtf8(str) { if (typeof str !== "string") { return str; } if (typeof TextEncoder === "function") { return new TextEncoder().encode(str); } else if (typeof Buffer === "function") { return Buffer.from(str); } else { throw new Error("Don't know how to encode UTF8"); } } function argon2Hash(params) { const mCost = params.mem || 1024; return loadModule(mCost).then((Module2) => { const tCost = params.time || 1; const parallelism = params.parallelism || 1; const pwdEncoded = encodeUtf8(params.pass); const pwd = allocateArrayStr(Module2, pwdEncoded); const pwdlen = pwdEncoded.length; const saltEncoded = encodeUtf8(params.salt); const salt = allocateArrayStr(Module2, saltEncoded); const saltlen = saltEncoded.length; const argon2Type = params.type || ArgonType.Argon2d; const hash = Module2.allocate( new Array(params.hashLen || 24), "i8", Module2.ALLOC_NORMAL ); const secret = params.secret ? allocateArray(Module2, params.secret) : 0; const secretlen = params.secret ? params.secret.byteLength : 0; const ad = params.ad ? allocateArray(Module2, params.ad) : 0; const adlen = params.ad ? params.ad.byteLength : 0; const hashlen = params.hashLen || 24; const encodedlen = Module2._argon2_encodedlen( tCost, mCost, parallelism, saltlen, hashlen, argon2Type ); const encoded = Module2.allocate( new Array(encodedlen + 1), "i8", Module2.ALLOC_NORMAL ); const version = 19; let err; let res; try { res = Module2._argon2_hash_ext( tCost, mCost, parallelism, pwd, pwdlen, salt, saltlen, hash, hashlen, encoded, encodedlen, argon2Type, secret, secretlen, ad, adlen, version ); } catch (e) { err = e; } let result; if (res === 0 && !err) { let hashStr = ""; const hashArr = new Uint8Array(hashlen); for (let i = 0; i < hashlen; i++) { const byte = Module2.HEAP8[hash + i]; hashArr[i] = byte; hashStr += ("0" + (255 & byte).toString(16)).slice(-2); } const encodedStr = Module2.UTF8ToString(encoded); result = { hash: hashArr, hashHex: hashStr, encoded: encodedStr }; } else { try { if (!err) { err = Module2.UTF8ToString( Module2._argon2_error_message(res) ); } } catch (e) { } result = { message: err, code: res }; } try { Module2._free(pwd); Module2._free(salt); Module2._free(hash); Module2._free(encoded); if (ad) { Module2._free(ad); } if (secret) { Module2._free(secret); } } catch (e) { } if (err) { throw result; } else { return result; } }); } function argon2Verify(params) { return loadModule().then((Module2) => { const pwdEncoded = encodeUtf8(params.pass); const pwd = allocateArrayStr(Module2, pwdEncoded); const pwdlen = pwdEncoded.length; const secret = params.secret ? allocateArray(Module2, params.secret) : 0; const secretlen = params.secret ? params.secret.byteLength : 0; const ad = params.ad ? allocateArray(Module2, params.ad) : 0; const adlen = params.ad ? params.ad.byteLength : 0; const encEncoded = encodeUtf8(params.encoded); const enc = allocateArrayStr(Module2, encEncoded); let argon2Type = params.type; if (argon2Type === void 0) { let typeStr = params.encoded.split("$")[1]; if (typeStr) { typeStr = typeStr.replace("a", "A"); argon2Type = ArgonType[typeStr] || ArgonType.Argon2d; } } let err; let res; try { res = Module2._argon2_verify_ext( enc, pwd, pwdlen, secret, secretlen, ad, adlen, argon2Type ); } catch (e) { err = e; } let result; if (res || err) { try { if (!err) { err = Module2.UTF8ToString( Module2._argon2_error_message(res) ); } } catch (e) { } result = { message: err, code: res }; } try { Module2._free(pwd); Module2._free(enc); } catch (e) { } if (err) { throw result; } else { return result; } }); } function unloadRuntime() { if (loadModule._module) { loadModule._module.unloadRuntime(); delete loadModule._promise; delete loadModule._module; } } return { ArgonType, hash: argon2Hash, verify: argon2Verify, unloadRuntime }; }); } }); // src/encryption/aesWithPassword.ts var aesWithPassword_exports = {}; __export(aesWithPassword_exports, { decryptBytesWithPassword: () => decryptBytesWithPassword, decryptWithPassword: () => decryptWithPassword, encryptBytesWithPassword: () => encryptBytesWithPassword, encryptWithPassword: () => encryptWithPassword }); async function encryptWithPassword(password, text, keyCache, kdfOpts) { const encoder = new TextEncoder(); const salt = crypto.getRandomValues(new Uint8Array(16)); const iv = crypto.getRandomValues(new Uint8Array(12)); const key = keyCache ? await getOrDeriveKey(password, salt, keyCache, kdfOpts) : await deriveKeyDirect(password, salt, kdfOpts); const encrypted = await crypto.subtle.encrypt( { name: "AES-GCM", iv }, key, encoder.encode(text) ); return { salt: bufferToBase64(salt), iv: bufferToBase64(iv), data: bufferToBase64(encrypted) }; } async function encryptBytesWithPassword(password, bytes, keyCache, kdfOpts) { const salt = crypto.getRandomValues(new Uint8Array(16)); const iv = crypto.getRandomValues(new Uint8Array(12)); const key = keyCache ? await getOrDeriveKey(password, salt, keyCache, kdfOpts) : await deriveKeyDirect(password, salt, kdfOpts); const data = bytes instanceof Uint8Array ? bytes : new Uint8Array(bytes); const encrypted = await crypto.subtle.encrypt( { name: "AES-GCM", iv }, key, data ); return { salt: bufferToBase64(salt), iv: bufferToBase64(iv), data: bufferToBase64(encrypted) }; } async function decryptWithPassword(password, saltB64, ivB64, dataB64, keyCache, kdfOpts) { const decoder = new TextDecoder(); const salt = base64ToBuffer(saltB64); const iv = base64ToBuffer(ivB64); const data = base64ToBuffer(dataB64); const key = keyCache ? await getOrDeriveKey(password, salt, keyCache, kdfOpts) : await deriveKeyDirect(password, salt, kdfOpts); try { const decrypted = await crypto.subtle.decrypt( { name: "AES-GCM", iv }, key, data ); return decoder.decode(decrypted); } catch (error) { console.error("AES decryption failed:", error); throw error; } } async function decryptBytesWithPassword(password, saltB64, ivB64, dataB64, keyCache, kdfOpts) { const salt = base64ToBuffer(saltB64); const iv = base64ToBuffer(ivB64); const data = base64ToBuffer(dataB64); const key = keyCache ? await getOrDeriveKey(password, salt, keyCache, kdfOpts) : await deriveKeyDirect(password, salt, kdfOpts); const decrypted = await crypto.subtle.decrypt( { name: "AES-GCM", iv }, key, data ); return new Uint8Array(decrypted); } async function getKeyMaterial(password) { const enc = new TextEncoder(); return crypto.subtle.importKey( "raw", enc.encode(password), { name: "PBKDF2" }, false, ["deriveBits", "deriveKey"] ); } async function deriveKeyPBKDF2(keyMaterial, salt, iterations) { return crypto.subtle.deriveKey( { name: "PBKDF2", salt, iterations, hash: "SHA-256" }, keyMaterial, { name: "AES-GCM", length: 256 }, false, ["encrypt", "decrypt"] ); } async function deriveKeyArgon2id(password, salt, kdfOpts) { var _a, _b, _c, _d, _e, _f, _g; const memKB = (_a = kdfOpts == null ? void 0 : kdfOpts.argon2MemoryKB) != null ? _a : 65536; const iters = (_b = kdfOpts == null ? void 0 : kdfOpts.argon2Iterations) != null ? _b : 3; const para = (_c = kdfOpts == null ? void 0 : kdfOpts.argon2Parallelism) != null ? _c : 1; const hashLen = (_d = kdfOpts == null ? void 0 : kdfOpts.argon2HashLen) != null ? _d : 32; try { const argon2 = await Promise.resolve().then(() => __toESM(require_argon23())); const res = await argon2.hash({ pass: password, salt, type: (_f = (_e = argon2.ArgonType) == null ? void 0 : _e.Argon2id) != null ? _f : 2, mem: memKB, time: iters, parallelism: para, hashLen, distPath: void 0 // let bundler handle assets }); const keyBytes = new Uint8Array(res.hash); return crypto.subtle.importKey( "raw", keyBytes, { name: "AES-GCM", length: 256 }, false, ["encrypt", "decrypt"] ); } catch (e) { const keyMaterial = await getKeyMaterial(password); const iterations = (_g = kdfOpts == null ? void 0 : kdfOpts.pbkdf2Iterations) != null ? _g : 6e5; return deriveKeyPBKDF2(keyMaterial, salt, iterations); } } function makeCachePasswordTag(password, kdfOpts) { var _a, _b, _c, _d, _e; if (!kdfOpts || kdfOpts.type === "PBKDF2") { const it = (_a = kdfOpts == null ? void 0 : kdfOpts.pbkdf2Iterations) != null ? _a : 6e5; return `pbkdf2:${it}:${password}`; } const memKB = (_b = kdfOpts.argon2MemoryKB) != null ? _b : 65536; const iters = (_c = kdfOpts.argon2Iterations) != null ? _c : 3; const para = (_d = kdfOpts.argon2Parallelism) != null ? _d : 1; const len = (_e = kdfOpts.argon2HashLen) != null ? _e : 32; return `argon2id:m${memKB}:t${iters}:p${para}:l${len}:${password}`; } async function deriveKey(password, salt, kdfOpts) { var _a; if ((kdfOpts == null ? void 0 : kdfOpts.type) === "Argon2id") { return deriveKeyArgon2id(password, salt, kdfOpts); } const keyMaterial = await getKeyMaterial(password); const iterations = (_a = kdfOpts == null ? void 0 : kdfOpts.pbkdf2Iterations) != null ? _a : 6e5; return deriveKeyPBKDF2(keyMaterial, salt, iterations); } async function deriveKeyDirect(password, salt, kdfOpts) { return deriveKey(password, salt, kdfOpts); } async function getOrDeriveKey(password, salt, keyCache, kdfOpts) { const cachePass = makeCachePasswordTag(password, kdfOpts); const cached = await keyCache.get(cachePass, salt); if (cached) return cached; const key = await deriveKeyDirect(password, salt, kdfOpts); await keyCache.set(cachePass, salt, key); return key; } function bufferToBase64(buffer) { if (buffer instanceof ArrayBuffer) { return Buffer.from(new Uint8Array(buffer)).toString("base64"); } return Buffer.from(new Uint8Array(buffer.buffer, buffer.byteOffset, buffer.byteLength)).toString("base64"); } function base64ToBuffer(base64) { const buf = Buffer.from(base64, "base64"); return Uint8Array.from(buf); } var init_aesWithPassword = __esm({ "src/encryption/aesWithPassword.ts"() { } }); // src/encryption/eccWithPassword.ts var eccWithPassword_exports = {}; __export(eccWithPassword_exports, { decryptWithPassword: () => decryptWithPassword2, encryptWithPassword: () => encryptWithPassword2 }); async function encryptWithPassword2(password, text, keyCache, kdfOpts) { const encoder = new TextEncoder(); const salt = crypto.getRandomValues(new Uint8Array(16)); const iv = crypto.getRandomValues(new Uint8Array(12)); const keyPair = await crypto.subtle.generateKey( { name: "ECDH", namedCurve: "P-256" }, true, ["deriveKey", "deriveBits"] ); const key = keyCache ? await getOrDeriveKey2(password, salt, keyCache, kdfOpts) : await deriveKeyDirect2(password, salt, kdfOpts); const encrypted = await crypto.subtle.encrypt( { name: "AES-GCM", iv }, key, encoder.encode(text) ); const publicKey = await crypto.subtle.exportKey("raw", keyPair.publicKey); const ephemeralKeyPair = await crypto.subtle.generateKey( { name: "ECDH", namedCurve: "P-256" }, true, ["deriveKey", "deriveBits"] ); const ephemeralPublicKey = await crypto.subtle.exportKey("raw", ephemeralKeyPair.publicKey); return { salt: bufferToBase642(salt), iv: bufferToBase642(iv), data: bufferToBase642(encrypted), publicKey: bufferToBase642(publicKey), ephemeralPublicKey: bufferToBase642(ephemeralPublicKey) }; } async function decryptWithPassword2(password, saltB64, ivB64, dataB64, publicKeyB64, ephemeralPublicKeyB64, keyCache, kdfOpts) { const decoder = new TextDecoder(); const salt = base64ToBuffer2(saltB64); const iv = base64ToBuffer2(ivB64); const data = base64ToBuffer2(dataB64); const key = keyCache ? await getOrDeriveKey2(password, salt, keyCache, kdfOpts) : await deriveKeyDirect2(password, salt, kdfOpts); const decrypted = await crypto.subtle.decrypt( { name: "AES-GCM", iv }, key, data ); return decoder.decode(decrypted); } async function getKeyMaterial2(password) { const enc = new TextEncoder(); return crypto.subtle.importKey( "raw", enc.encode(password), { name: "PBKDF2" }, false, ["deriveBits", "deriveKey"] ); } async function deriveKeyPBKDF22(keyMaterial, salt, iterations) { return crypto.subtle.deriveKey( { name: "PBKDF2", salt, iterations, hash: "SHA-256" }, keyMaterial, { name: "AES-GCM", length: 256 }, false, ["encrypt", "decrypt"] ); } async function deriveKeyArgon2id2(password, salt, kdfOpts) { var _a, _b, _c, _d, _e, _f, _g; const memKB = (_a = kdfOpts == null ? void 0 : kdfOpts.argon2MemoryKB) != null ? _a : 65536; const iters = (_b = kdfOpts == null ? void 0 : kdfOpts.argon2Iterations) != null ? _b : 3; const para = (_c = kdfOpts == null ? void 0 : kdfOpts.argon2Parallelism) != null ? _c : 1; const hashLen = (_d = kdfOpts == null ? void 0 : kdfOpts.argon2HashLen) != null ? _d : 32; try { const argon2 = await Promise.resolve().then(() => __toESM(require_argon23())); const res = await argon2.hash({ pass: password, salt, type: (_f = (_e = argon2.ArgonType) == null ? void 0 : _e.Argon2id) != null ? _f : 2, mem: memKB, time: iters, parallelism: para, hashLen, distPath: void 0 }); const keyBytes = new Uint8Array(res.hash); return crypto.subtle.importKey( "raw", keyBytes, { name: "AES-GCM", length: 256 }, false, ["encrypt", "decrypt"] ); } catch (e) { const keyMaterial = await getKeyMaterial2(password); const iterations = (_g = kdfOpts == null ? void 0 : kdfOpts.pbkdf2Iterations) != null ? _g : 6e5; return deriveKeyPBKDF22(keyMaterial, salt, iterations); } } function makeCachePasswordTag2(password, kdfOpts) { var _a, _b, _c, _d, _e; if (!kdfOpts || kdfOpts.type === "PBKDF2") { const it = (_a = kdfOpts == null ? void 0 : kdfOpts.pbkdf2Iterations) != null ? _a : 6e5; return `pbkdf2:${it}:${password}`; } const memKB = (_b = kdfOpts.argon2MemoryKB) != null ? _b : 65536; const iters = (_c = kdfOpts.argon2Iterations) != null ? _c : 3; const para = (_d = kdfOpts.argon2Parallelism) != null ? _d : 1; const len = (_e = kdfOpts.argon2HashLen) != null ? _e : 32; return `argon2id:m${memKB}:t${iters}:p${para}:l${len}:${password}`; } async function deriveKey2(password, salt, kdfOpts) { var _a; if ((kdfOpts == null ? void 0 : kdfOpts.type) === "Argon2id") { return deriveKeyArgon2id2(password, salt, kdfOpts); } const keyMaterial = await getKeyMaterial2(password); const iterations = (_a = kdfOpts == null ? void 0 : kdfOpts.pbkdf2Iterations) != null ? _a : 6e5; return deriveKeyPBKDF22(keyMaterial, salt, iterations); } async function deriveKeyDirect2(password, salt, kdfOpts) { return deriveKey2(password, salt, kdfOpts); } async function getOrDeriveKey2(password, salt, keyCache, kdfOpts) { const cacheTag = makeCachePasswordTag2(password, kdfOpts); const cached = await keyCache.get(cacheTag, salt); if (cached) return cached; const key = await deriveKeyDirect2(password, salt, kdfOpts); await keyCache.set(cacheTag, salt, key); return key; } function bufferToBase642(buffer) { if (buffer instanceof ArrayBuffer) { return Buffer.from(new Uint8Array(buffer)).toString("base64"); } return Buffer.from(new Uint8Array(buffer.buffer, buffer.byteOffset, buffer.byteLength)).toString("base64"); } function base64ToBuffer2(base64) { const buf = Buffer.from(base64, "base64"); return Uint8Array.from(buf); } var init_eccWithPassword = __esm({ "src/encryption/eccWithPassword.ts"() { } }); // src/encryption/keyCache.ts var keyCache_exports = {}; __export(keyCache_exports, { KeyCache: () => KeyCache }); var KeyCache; var init_keyCache = __esm({ "src/encryption/keyCache.ts"() { KeyCache = class { constructor(ttlMinutes = 5, maxSize = 10) { this.cache = /* @__PURE__ */ new Map(); this.TTL = ttlMinutes * 60 * 1e3; this.MAX_CACHE_SIZE = maxSize; } /** * Generate cache key from password and salt * Uses SHA-256 hash to avoid storing password in plain text */ async generateCacheKey(password, salt) { const encoder = new TextEncoder(); const passwordData = encoder.encode(password); const combined = new Uint8Array(passwordData.length + salt.length); combined.set(passwordData); combined.set(salt, passwordData.length); const hashBuffer = await crypto.subtle.digest("SHA-256", combined); const hashArray = Array.from(new Uint8Array(hashBuffer)); const hashHex = hashArray.map((b) => b.toString(16).padStart(2, "0")).join(""); return hashHex; } /** * Get cached key or return null if not found/expired */ async get(password, salt) { const cacheKey = await this.generateCacheKey(password, salt); const cached = this.cache.get(cacheKey); if (!cached) { return null; } const now = Date.now(); if (now - cached.timestamp > this.TTL) { this.cache.delete(cacheKey); return null; } const saltBase64 = Buffer.from(salt).toString("base64"); if (cached.saltBase64 !== saltBase64) { this.cache.delete(cacheKey); return null; } return cached.key; } /** * Store key in cache */ async set(password, salt, key) { const cacheKey = await this.generateCacheKey(password, salt); const saltBase64 = Buffer.from(salt).toString("base64"); if (this.cache.size >= this.MAX_CACHE_SIZE) { const firstKey = this.cache.keys().next().value; if (firstKey) { this.cache.delete(firstKey); } } this.cache.set(cacheKey, { key, timestamp: Date.now(), saltBase64 }); } /** * Clear all cached keys * Call this when plugin unloads or user logs out */ clear() { this.cache.clear(); } /** * Remove expired entries */ cleanup() { const now = Date.now(); const keysToDelete = []; this.cache.forEach((value, key) => { if (now - value.timestamp > this.TTL) { keysToDelete.push(key); } }); keysToDelete.forEach((key) => this.cache.delete(key)); } /** * Get cache statistics */ getStats() { return { size: this.cache.size, maxSize: this.MAX_CACHE_SIZE, ttl: this.TTL }; } }; } }); // src/types/fileData.ts var _FileDataHelper, FileDataHelper, JsonFileEncoding; var init_fileData = __esm({ "src/types/fileData.ts"() { _FileDataHelper = class { static async encrypt(password, text, type, originalExt, hint, algorithm, keyCache, kdfOptions) { const useAlgorithm = algorithm || "AES"; if (useAlgorithm === "ECC") { const eccCrypto = await Promise.resolve().then(() => (init_eccWithPassword(), eccWithPassword_exports)); const { salt, iv, data, publicKey, ephemeralPublicKey } = await eccCrypto.encryptWithPassword(password, text, keyCache || void 0, kdfOptions); let kdfLine = ""; if ((kdfOptions == null ? void 0 : kdfOptions.type) === "Argon2id") { const mem = kdfOptions.argon2MemoryKB || 65536; const iters = kdfOptions.argon2Iterations || 3; const para = kdfOptions.argon2Parallelism || 1; const len = kdfOptions.argon2HashLen || 32; kdfLine = `KDF:Argon2id:${mem}:${iters}:${para}:${len}`; } else { kdfLine = `KDF:PBKDF2:${(kdfOptions == null ? void 0 : kdfOptions.pbkdf2Iterations) || 6e5}`; } return { version: _FileDataHelper.DEFAULT_VERSION, encodedData: `SALT:${salt} IV:${iv} DATA:${data} PUBLIC_KEY:${publicKey} EPHEMERAL_PUBLIC_KEY:${ephemeralPublicKey} ${kdfLine}`, type, originalExt, hint, algorithm: "ECC", kdf: (kdfOptions == null ? void 0 : kdfOptions.type) || "PBKDF2", iterations: (kdfOptions == null ? void 0 : kdfOptions.type) === "PBKDF2" ? (kdfOptions == null ? void 0 : kdfOptions.pbkdf2Iterations) || 6e5 : void 0, argon2MemoryKB: (kdfOptions == null ? void 0 : kdfOptions.type) === "Argon2id" ? (kdfOptions == null ? void 0 : kdfOptions.argon2MemoryKB) || 65536 : void 0, argon2Iterations: (kdfOptions == null ? void 0 : kdfOptions.type) === "Argon2id" ? (kdfOptions == null ? void 0 : kdfOptions.argon2Iterations) || 3 : void 0, argon2Parallelism: (kdfOptions == null ? void 0 : kdfOptions.type) === "Argon2id" ? (kdfOptions == null ? void 0 : kdfOptions.argon2Parallelism) || 1 : void 0, argon2HashLen: (kdfOptions == null ? void 0 : kdfOptions.type) === "Argon2id" ? (kdfOptions == null ? void 0 : kdfOptions.argon2HashLen) || 32 : void 0 }; } else { const aesCrypto = await Promise.resolve().then(() => (init_aesWithPassword(), aesWithPassword_exports)); const { salt, iv, data } = await aesCrypto.encryptWithPassword(password, text, keyCache || void 0, kdfOptions); let kdfLine = ""; if ((kdfOptions == null ? void 0 : kdfOptions.type) === "Argon2id") { const mem = kdfOptions.argon2MemoryKB || 65536; const iters = kdfOptions.argon2Iterations || 3; const para = kdfOptions.argon2Parallelism || 1; const len = kdfOptions.argon2HashLen || 32; kdfLine = `KDF:Argon2id:${mem}:${iters}:${para}:${len}`; } else { kdfLine = `KDF:PBKDF2:${(kdfOptions == null ? void 0 : kdfOptions.pbkdf2Iterations) || 6e5}`; } return { version: _FileDataHelper.DEFAULT_VERSION, encodedData: `SALT:${salt} IV:${iv} DATA:${data} ${kdfLine}`, type, originalExt, hint, algorithm: "AES", kdf: (kdfOptions == null ? void 0 : kdfOptions.type) || "PBKDF2", iterations: (kdfOptions == null ? void 0 : kdfOptions.type) === "PBKDF2" ? (kdfOptions == null ? void 0 : kdfOptions.pbkdf2Iterations) || 6e5 : void 0, argon2MemoryKB: (kdfOptions == null ? void 0 : kdfOptions.type) === "Argon2id" ? (kdfOptions == null ? void 0 : kdfOptions.argon2MemoryKB) || 65536 : void 0, argon2Iterations: (kdfOptions == null ? void 0 : kdfOptions.type) === "Argon2id" ? (kdfOptions == null ? void 0 : kdfOptions.argon2Iterations) || 3 : void 0, argon2Parallelism: (kdfOptions == null ? void 0 : kdfOptions.type) === "Argon2id" ? (kdfOptions == null ? void 0 : kdfOptions.argon2Parallelism) || 1 : void 0, argon2HashLen: (kdfOptions == null ? void 0 : kdfOptions.type) === "Argon2id" ? (kdfOptions == null ? void 0 : kdfOptions.argon2HashLen) || 32 : void 0 }; } } static async decrypt(data, password, keyCache, kdfOptions) { var _a, _b, _c, _d, _e, _f; if (!data.encodedData) { return ""; } const parts = data.encodedData.split("\n"); if (parts.length < 3) { console.error(`Invalid encoded data format: expected at least 3 parts, got ${parts.length}`); throw new Error(`Invalid encoded data format: expected at least 3 parts, got ${parts.length}`); } const salt = ((_a = parts.find((p) => p.startsWith("SALT:"))) == null ? void 0 : _a.replace("SALT:", "")) || ""; const iv = ((_b = parts.find((p) => p.startsWith("IV:"))) == null ? void 0 : _b.replace("IV:", "")) || ""; const encData = ((_c = parts.find((p) => p.startsWith("DATA:"))) == null ? void 0 : _c.replace("DATA:", "")) || ""; const kdfLine = (_d = parts.find((p) => p.startsWith("KDF:"))) == null ? void 0 : _d.replace("KDF:", ""); let kdfType = (kdfOptions == null ? void 0 : kdfOptions.type) || "PBKDF2"; let iterations = 6e5; let argon2Opts; if (kdfLine) { const segs = kdfLine.split(":"); const parsedType = segs[0].toUpperCase() === "ARGON2ID" ? "Argon2id" : "PBKDF2"; if (!kdfOptions) { kdfType = parsedType; } if (kdfType === "PBKDF2" && segs[1]) { const n = parseInt(segs[1], 10); if (!isNaN(n) && n > 0) iterations = n; } else if (kdfType === "Argon2id" && segs.length >= 5) { argon2Opts = { memoryKB: parseInt(segs[1], 10) || 65536, iterations: parseInt(segs[2], 10) || 3, parallelism: parseInt(segs[3], 10) || 1, hashLen: parseInt(segs[4], 10) || 32 }; } } else if (data.kdf) { if (!kdfOptions) { kdfType = data.kdf; if (kdfType === "PBKDF2" && data.iterations && data.iterations > 0) { iterations = data.iterations; } else if (kdfType === "Argon2id") { argon2Opts = { memoryKB: data.argon2MemoryKB || 65536, iterations: data.argon2Iterations || 3, parallelism: data.argon2Parallelism || 1, hashLen: data.argon2HashLen || 32 }; } } } if (!salt || !iv || !encData) { console.error(`Missing encryption data: salt=${!!salt}, iv=${!!iv}, data=${!!encData}`); throw new Error(`Missing encryption data: salt=${!!salt}, iv=${!!iv}, data=${!!encData}`); } const finalKdfOptions = kdfOptions || (kdfType === "Argon2id" && argon2Opts ? { type: "Argon2id", argon2MemoryKB: argon2Opts.memoryKB, argon2Iterations: argon2Opts.iterations, argon2Parallelism: argon2Opts.parallelism, argon2HashLen: argon2Opts.hashLen } : { type: "PBKDF2", pbkdf2Iterations: iterations }); const publicKey = ((_e = parts.find((p) => p.startsWith("PUBLIC_KEY:"))) == null ? void 0 : _e.replace("PUBLIC_KEY:", "")) || ""; const ephemeralPublicKey = ((_f = parts.find((p) => p.startsWith("EPHEMERAL_PUBLIC_KEY:"))) == null ? void 0 : _f.replace("EPHEMERAL_PUBLIC_KEY:", "")) || ""; const hasKdfInfo = !!kdfLine || !!data.kdf; const tryPbkdf2Fallbacks = async (decryptFn) => { const fallbackIterations = [1e5, 25e4, 5e4, 5e5]; for (const it of fallbackIterations) { if (finalKdfOptions.type === "PBKDF2" && finalKdfOptions.pbkdf2Iterations === it) continue; try { return await decryptFn(it); } catch (e) { } } throw new Error("Decryption failed for all PBKDF2 fallbacks"); }; if (publicKey || data.algorithm === "ECC") { const eccCrypto = await Promise.resolve().then(() => (init_eccWithPassword(), eccWithPassword_exports)); try { const result = await eccCrypto.decryptWithPassword( password, salt, iv, encData, publicKey || "", ephemeralPublicKey, keyCache || void 0, finalKdfOptions ); return result; } catch (error) { console.error("ECC decryption failed:", error); if (!hasKdfInfo && finalKdfOptions.type === "PBKDF2") { try { return await tryPbkdf2Fallbacks(async (iters) => eccCrypto.decryptWithPassword( password, salt, iv, encData, publicKey || "", ephemeralPublicKey, keyCache || void 0, { type: "PBKDF2", pbkdf2Iterations: iters } )); } catch (e) { } } throw error; } } else { const aesCrypto = await Promise.resolve().then(() => (init_aesWithPassword(), aesWithPassword_exports)); try { const result = await aesCrypto.decryptWithPassword(password, salt, iv, encData, keyCache || void 0, finalKdfOptions); return result; } catch (error) { console.error("AES decryption failed:", error); if (!hasKdfInfo && finalKdfOptions.type === "PBKDF2") { try { return await tryPbkdf2Fallbacks(async (iters) => aesCrypto.decryptWithPassword( password, salt, iv, encData, keyCache || void 0, { type: "PBKDF2", pbkdf2Iterations: iters } )); } catch (e) { } } throw error; } } } }; FileDataHelper = _FileDataHelper; FileDataHelper.DEFAULT_VERSION = "2.0"; JsonFileEncoding = class { static encode(data) { return JSON.stringify(data, null, 2); } static decode(text) { var _a, _b, _c, _d, _e, _f, _g, _h, _i; if (!text) { return { version: FileDataHelper.DEFAULT_VERSION, encodedData: "", type: "temporary", originalExt: "md" }; } if (text.startsWith("%%ENC")) { const lines = text.split("\n"); const typeMatch = (_a = lines.find((line) => line.startsWith("TYPE:"))) == null ? void 0 : _a.substring(5); const originalExtMatch = (_b = lines.find((line) => line.startsWith("ORIGINAL_EXT:"))) == null ? void 0 : _b.substring(13); const saltMatch = (_c = lines.find((line) => line.startsWith("SALT:"))) == null ? void 0 : _c.substring(5); const ivMatch = (_d = lines.find((line) => line.startsWith("IV:"))) == null ? void 0 : _d.substring(3); const dataMatch = (_e = lines.find((line) => line.startsWith("DATA:"))) == null ? void 0 : _e.substring(5); const hintMatch = (_f = lines.find((line) => line.startsWith("HINT:"))) == null ? void 0 : _f.substring(5); const kdfMatch = (_g = lines.find((line) => line.startsWith("KDF:"))) == null ? void 0 : _g.substring(4); const publicKeyMatch = (_h = lines.find((line) => line.startsWith("PUBLIC_KEY:"))) == null ? void 0 : _h.substring(11); const ephemeralPublicKeyMatch = (_i = lines.find((line) => line.startsWith("EPHEMERAL_PUBLIC_KEY:"))) == null ? void 0 : _i.substring(21); if (!saltMatch || !ivMatch || !dataMatch) { throw new Error("Invalid file format"); } const encodedLines = [ `SALT:${saltMatch}`, `IV:${ivMatch}`, `DATA:${dataMatch}`, ...publicKeyMatch ? [`PUBLIC_KEY:${publicKeyMatch}`] : [], ...ephemeralPublicKeyMatch ? [`EPHEMERAL_PUBLIC_KEY:${ephemeralPublicKeyMatch}`] : [], ...kdfMatch ? [`KDF:${kdfMatch}`] : [] ]; return { version: FileDataHelper.DEFAULT_VERSION, encodedData: encodedLines.join("\n"), type: typeMatch || "temporary", originalExt: originalExtMatch || "md", hint: hintMatch, algorithm: publicKeyMatch ? "ECC" : "AES" }; } try { return JSON.parse(text); } catch (error) { throw new Error("Invalid file format"); } } static isEncoded(text) { if (text.startsWith("%%ENC")) { return true; } try { const data = JSON.parse(text); return data.version !== void 0 && data.encodedData !== void 0; } catch (e) { return false; } } }; } }); // src/utils/attachmentHelper.ts var attachmentHelper_exports = {}; __export(attachmentHelper_exports, { AttachmentHelper: () => AttachmentHelper }); var import_obsidian4, AttachmentHelper; var init_attachmentHelper = __esm({ "src/utils/attachmentHelper.ts"() { import_obsidian4 = require("obsidian"); init_fileData(); init_aesWithPassword(); AttachmentHelper = class { /** * Normalize a link by removing query/hash, trimming whitespace and angle brackets, * and attempting URL decoding. */ static normalizeLink(raw) { if (!raw) return raw; let link = raw.trim(); if (link.startsWith("<") && link.endsWith(">")) { link = link.substring(1, link.length - 1).trim(); } link = link.split("|")[0]; const hashIdx = link.indexOf("#"); if (hashIdx !== -1) link = link.substring(0, hashIdx); const qIdx = link.indexOf("?"); if (qIdx !== -1) link = link.substring(0, qIdx); try { link = decodeURI(link); } catch (e) { } link = link.replace(/\\/g, "/"); link = link.replace(/\/\/+/, "/"); return link.trim(); } /** * Extract all attachment links from markdown content * Supports: ![[image.png]], ![](image.png), [[document.pdf]] */ static extractAttachmentLinks(content) { const attachments = []; const wikiLinkRegex = /!?\[\[([^\]]+?)\]\]/g; let match; while ((match = wikiLinkRegex.exec(content)) !== null) { const link = this.normalizeLink(match[1]); if (this.isAttachment(link) || link.endsWith(".eccfile") || link.endsWith(".peccfile")) { attachments.push(link); } } const mdImageRegex = /!\[([^\]]*)\]\(([^)]+)\)/g; while ((match = mdImageRegex.exec(content)) !== null) { const link = this.normalizeLink(match[2]); if (this.isAttachment(link) || link.endsWith(".eccfile") || link.endsWith(".peccfile")) { attachments.push(link); } } return [...new Set(attachments)]; } /** * Check if a link points to an attachment (non-markdown file) */ static isAttachment(link) { var _a; const ext = (_a = link.split(".").pop()) == null ? void 0 : _a.toLowerCase(); if (!ext) return false; const attachmentExts = [ "png", "jpg", "jpeg", "gif", "bmp", "svg", "webp", // Images "pdf", "doc", "docx", "xls", "xlsx", "ppt", "pptx", // Documents "mp3", "mp4", "wav", "avi", "mov", // Media "zip", "rar", "7z", // Archives "json", "xml", "csv", "txt" // Data files ]; return attachmentExts.includes(ext); } /** * Resolve attachment path relative to a note */ static resolveAttachmentPath(vault, notePath, attachmentLink) { const cleanLink = this.normalizeLink(attachmentLink); let file = vault.getAbstractFileByPath(cleanLink); if (file instanceof import_obsidian4.TFile) return file; const noteDir = notePath.substring(0, notePath.lastIndexOf("/")); const relativePath = noteDir ? `${noteDir}/${cleanLink}` : cleanLink; file = vault.getAbstractFileByPath(relativePath); if (file instanceof import_obsidian4.TFile) return file; const commonFolders = ["attachments", "assets", "files", "images"]; for (const folder of commonFolders) { file = vault.getAbstractFileByPath(`${folder}/${cleanLink}`); if (file instanceof import_obsidian4.TFile) return file; } const base = cleanLink.split("/").pop(); if (base) { for (const folder of commonFolders) { const candidate = vault.getAbstractFileByPath(`${folder}/${base}`); if (candidate instanceof import_obsidian4.TFile) return candidate; } } return null; } /** * Encrypt a binary file (image, PDF, etc.) */ static async encryptBinaryFile(vault, file, password, type, kdfOpts) { const arrayBuffer = await vault.readBinary(file); const { salt, iv, data } = await encryptBytesWithPassword(password, arrayBuffer, void 0, kdfOpts); let kdfLine = ""; if ((kdfOpts == null ? void 0 : kdfOpts.type) === "Argon2id") { const mem = kdfOpts.argon2MemoryKB || 65536; const iters = kdfOpts.argon2Iterations || 3; const para = kdfOpts.argon2Parallelism || 1; const len = kdfOpts.argon2HashLen || 32; kdfLine = `KDF:Argon2id:${mem}:${iters}:${para}:${len}`; } else { kdfLine = `KDF:PBKDF2:${(kdfOpts == null ? void 0 : kdfOpts.pbkdf2Iterations) || 6e5}`; } const encodedData = `SALT:${salt} IV:${iv} DATA:${data} FORMAT:BIN ${kdfLine}`; const encryptedData = { version: FileDataHelper.DEFAULT_VERSION, encodedData, type, originalExt: file.extension, algorithm: "AES", kdf: (kdfOpts == null ? void 0 : kdfOpts.type) || "PBKDF2", iterations: (kdfOpts == null ? void 0 : kdfOpts.type) === "PBKDF2" ? (kdfOpts == null ? void 0 : kdfOpts.pbkdf2Iterations) || 6e5 : void 0, argon2MemoryKB: (kdfOpts == null ? void 0 : kdfOpts.type) === "Argon2id" ? (kdfOpts == null ? void 0 : kdfOpts.argon2MemoryKB) || 65536 : void 0, argon2Iterations: (kdfOpts == null ? void 0 : kdfOpts.type) === "Argon2id" ? (kdfOpts == null ? void 0 : kdfOpts.argon2Iterations) || 3 : void 0, argon2Parallelism: (kdfOpts == null ? void 0 : kdfOpts.type) === "Argon2id" ? (kdfOpts == null ? void 0 : kdfOpts.argon2Parallelism) || 1 : void 0, argon2HashLen: (kdfOpts == null ? void 0 : kdfOpts.type) === "Argon2id" ? (kdfOpts == null ? void 0 : kdfOpts.argon2HashLen) || 32 : void 0 }; const encryptedExt = type === "permanent" ? "peccfile" : "eccfile"; const encryptedPath = `${file.path}.${encryptedExt}`; const encryptedContent = JSON.stringify(encryptedData, null, 2); const existingFile = vault.getAbstractFileByPath(encryptedPath); if (existingFile instanceof import_obsidian4.TFile) { await vault.modify(existingFile, encryptedContent); } else { await vault.create(encryptedPath, encryptedContent); } await vault.delete(file); return encryptedPath; } /** * Decrypt a binary file */ static async decryptBinaryFile(vault, encryptedFile, password, kdfOpts) { var _a, _b, _c, _d, _e; const content = await vault.read(encryptedFile); const encryptedData = JSON.parse(content); const parts = encryptedData.encodedData.split("\n"); const salt = ((_a = parts.find((p) => p.startsWith("SALT:"))) == null ? void 0 : _a.slice(5)) || ""; const iv = ((_b = parts.find((p) => p.startsWith("IV:"))) == null ? void 0 : _b.slice(3)) || ""; const data = ((_c = parts.find((p) => p.startsWith("DATA:"))) == null ? void 0 : _c.slice(5)) || ""; const format = ((_d = parts.find((p) => p.startsWith("FORMAT:"))) == null ? void 0 : _d.slice(7).toUpperCase()) || ""; if (!salt || !iv || !data) return null; let finalKdfOpts = kdfOpts; const kdfLine = (_e = parts.find((p) => p.startsWith("KDF:"))) == null ? void 0 : _e.slice(4); if (!finalKdfOpts) { if (kdfLine) { const segs = kdfLine.split(":"); if (segs[0].toUpperCase() === "ARGON2ID" && segs.length >= 5) { finalKdfOpts = { type: "Argon2id", argon2MemoryKB: parseInt(segs[1], 10) || 65536, argon2Iterations: parseInt(segs[2], 10) || 3, argon2Parallelism: parseInt(segs[3], 10) || 1, argon2HashLen: parseInt(segs[4], 10) || 32 }; } else if (segs[0].toUpperCase() === "PBKDF2") { finalKdfOpts = { type: "PBKDF2", pbkdf2Iterations: parseInt(segs[1], 10) || 6e5 }; } } else if (encryptedData.kdf) { if (encryptedData.kdf === "Argon2id") { finalKdfOpts = { type: "Argon2id", argon2MemoryKB: encryptedData.argon2MemoryKB || 65536, argon2Iterations: encryptedData.argon2Iterations || 3, argon2Parallelism: encryptedData.argon2Parallelism || 1, argon2HashLen: encryptedData.argon2HashLen || 32 }; } else { finalKdfOpts = { type: "PBKDF2", pbkdf2Iterations: encryptedData.iterations || 6e5 }; } } } const tryLegacyPbkdf2 = async (fn) => { const fallbackIterations = [1e5, 25e4, 5e4, 5e5]; for (const it of fallbackIterations) { if (finalKdfOpts && finalKdfOpts.type === "PBKDF2" && finalKdfOpts.pbkdf2Iterations === it) continue; try { return await fn(it); } catch (e) { } } return null; }; const isPbkdf2NoMetadata = !kdfLine && !encryptedData.kdf && (!finalKdfOpts || finalKdfOpts.type === "PBKDF2"); let arrayBuffer; if (format === "BIN") { try { const bytes = await decryptBytesWithPassword(password, salt, iv, data, void 0, finalKdfOpts); arrayBuffer = bytes.buffer.slice(bytes.byteOffset, bytes.byteOffset + bytes.byteLength); } catch (err) { if (isPbkdf2NoMetadata) { const fallback = await tryLegacyPbkdf2(async (iters) => { const bytes = await decryptBytesWithPassword( password, salt, iv, data, void 0, { type: "PBKDF2", pbkdf2Iterations: iters } ); return bytes; }); if (fallback) { arrayBuffer = fallback.buffer.slice(fallback.byteOffset, fallback.byteOffset + fallback.byteLength); } else { throw err; } } else { throw err; } } } else { try { const base64 = await FileDataHelper.decrypt(encryptedData, password, void 0, finalKdfOpts); if (!base64) return null; arrayBuffer = this.base64ToArrayBuffer(base64); } catch (err) { if (isPbkdf2NoMetadata) { const fallback = await tryLegacyPbkdf2(async (iters) => FileDataHelper.decrypt( encryptedData, password, void 0, { type: "PBKDF2", pbkdf2Iterations: iters } )); if (fallback) { arrayBuffer = this.base64ToArrayBuffer(fallback); } else { throw err; } } else { throw err; } } } const originalPath = encryptedFile.path.replace(/\.eccfile$/, "").replace(/\.peccfile$/, ""); const existingFile = vault.getAbstractFileByPath(originalPath); if (existingFile instanceof import_obsidian4.TFile) { await vault.modifyBinary(existingFile, arrayBuffer); } else { await vault.createBinary(originalPath, arrayBuffer); } if (encryptedData.type === "temporary") { await vault.delete(encryptedFile); } return vault.getAbstractFileByPath(originalPath); } /** * Update attachment links in note content * @param content - The note content * @param encryptionType - "encrypt" to add .eccirian/.peccirian, "decrypt" to remove * @param mode - "temporary" or "permanent" */ static updateAttachmentLinks(content, encryptionType, mode) { const ext = mode === "permanent" ? "peccfile" : "eccfile"; if (encryptionType === "encrypt") { content = content.replace( /(!?\[\[)([^\]]+?)(\]\])/g, (match, prefix, filename, suffix) => { if (this.isAttachment(filename)) { return `${prefix}${filename}.${ext}${suffix}`; } return match; } ); content = content.replace( /(!)\[([^\]]*)\]\(([^)]+?)\)/g, (match, exclaim, alt, path) => { if (this.isAttachment(path)) { return `${exclaim}[${alt}](${path}.${ext})`; } return match; } ); } else { content = content.replace( new RegExp(`(!?\\[\\[[^\\]]+?)\\.${ext}(\\]\\])`, "g"), "$1$2" ); content = content.replace( new RegExp(`(!\\[[^\\]]*\\]\\([^)]+?)\\.${ext}(\\))`, "g"), "$1$2" ); } return content; } /** * Convert ArrayBuffer to Base64 */ static arrayBufferToBase64(buffer) { return Buffer.from(new Uint8Array(buffer)).toString("base64"); } /** * Convert Base64 to ArrayBuffer */ static base64ToArrayBuffer(base64) { const buf = Buffer.from(base64, "base64"); return buf.buffer.slice(buf.byteOffset, buf.byteOffset + buf.byteLength); } }; } }); // src/main.ts var main_exports = {}; __export(main_exports, { default: () => EccEncryptPlugin }); module.exports = __toCommonJS(main_exports); var import_obsidian9 = require("obsidian"); init_aesWithPassword(); init_eccWithPassword(); // src/ui/passwordModal.ts var import_obsidian = require("obsidian"); var PasswordModal = class extends import_obsidian.Modal { constructor(app, onSuccess, onCancel, defaultMode = "temporary", isDecrypt = false, requirePasswordConfirmation = false, showHint = false, defaultEncryptionMethod = "AES", plugin, showModeSelection = true, existingHint) { super(app); this.password = ""; this.confirmPassword = ""; this.hint = ""; this.encryptionMode = "temporary"; this.encryptionMethod = "AES"; this.isSubmitted = false; this.isDecrypt = false; this.requirePasswordConfirmation = false; this.showHint = false; this.showModeSelection = true; this.onSuccess = onSuccess; this.onCancel = onCancel; this.encryptionMode = defaultMode; this.isDecrypt = isDecrypt; this.requirePasswordConfirmation = requirePasswordConfirmation; this.showHint = showHint; this.encryptionMethod = defaultEncryptionMethod; this.plugin = plugin; this.showModeSelection = showModeSelection; this.existingHint = existingHint; } onOpen() { const { contentEl } = this; contentEl.empty(); new import_obsidian.Setting(contentEl).setName("Eccirian Encryption").setHeading(); if (this.isDecrypt && this.existingHint) { const hintContainer = contentEl.createDiv({ cls: "setting-item" }); const hintInfo = hintContainer.createDiv({ cls: "setting-item-info" }); hintInfo.createDiv({ cls: "setting-item-name", text: "Password Hint" }); const hintControl = hintContainer.createDiv({ cls: "setting-item-control" }); const hintCode = hintControl.createEl("code", { text: this.existingHint, cls: "eccirian-hint-code" }); hintCode.style.padding = "4px 8px"; hintCode.style.backgroundColor = "var(--background-modifier-border)"; hintCode.style.borderRadius = "4px"; hintCode.style.fontSize = "0.9em"; } if (!this.isDecrypt) { new import_obsidian.Setting(contentEl).setName("Encryption Method").setDesc("Choose encryption method").addDropdown( (drop) => drop.addOption("AES", "AES-256 (Symmetric)").addOption("ECC", "ECC+AES (Asymmetric)").setValue(this.encryptionMethod).onChange((value) => { this.encryptionMethod = value; }) ); if (this.showModeSelection) { new import_obsidian.Setting(contentEl).setName("Encryption Mode").setDesc("Choose encryption mode").addDropdown( (drop) => drop.addOption("temporary", "Temporary (Single Use)").addOption("permanent", "Permanent (Repeatable)").setValue(this.encryptionMode).onChange((value) => { this.encryptionMode = value; }) ); } } new import_obsidian.Setting(contentEl).setName("Password").addText((text) => { text.setPlaceholder("Enter password").setValue(this.password).onChange((value) => { this.password = value; }); text.inputEl.type = "password"; text.inputEl.addEventListener("keypress", (e) => { if (e.key === "Enter" && this.password) { if (!this.requirePasswordConfirmation || this.confirmPassword) { this.submit(); } } }); }); if (!this.isDecrypt && this.requirePasswordConfirmation) { new import_obsidian.Setting(contentEl).setName("Confirm Password").addText((text) => { text.setPlaceholder("Confirm password").setValue(this.confirmPassword).onChange((value) => { this.confirmPassword = value; }); text.inputEl.type = "password"; text.inputEl.addEventListener("keypress", (e) => { if (e.key === "Enter" && this.password && this.confirmPassword) { this.submit(); } }); }); } if (!this.isDecrypt && this.showHint) { new import_obsidian.Setting(contentEl).setName("Password Hint").setDesc("Optional hint to help remember the password").addText((text) => { text.setPlaceholder("Enter password hint (optional)").setValue(this.hint).onChange((value) => { this.hint = value; }); }); } new import_obsidian.Setting(contentEl).addButton((button) => { button.setButtonText("Confirm").setCta().onClick(() => { this.submit(); }); }).addButton((button) => { button.setButtonText("Cancel").onClick(() => { this.close(); this.onCancel(); }); }); } async submit() { if (!this.password) { if (this.plugin.settings.showNotice) new import_obsidian.Notice("Please enter a password"); return; } if (!this.isDecrypt && this.requirePasswordConfirmation) { if (!this.confirmPassword) { if (this.plugin.settings.showNotice) new import_obsidian.Notice("Please confirm your password"); return; } if (this.password !== this.confirmPassword) { if (this.plugin.settings.showNotice) new import_obsidian.Notice("Passwords do not match"); return; } } if (!this.isDecrypt) { const extension = this.encryptionMode === "permanent" ? "peccirian" : "eccirian"; this.plugin.settings.fileExtension = extension; await this.plugin.saveSettings(); } this.isSubmitted = true; this.close(); this.onSuccess(this.password, this.encryptionMethod, this.hint, this.encryptionMode); } onClose() { const { contentEl } = this; contentEl.empty(); if (!this.isSubmitted) { this.onCancel(); } } }; // src/ui/settingsTab.ts var import_obsidian2 = require("obsidian"); // src/i18n/index.ts var en = { // Sections settingsSectionGeneral: "General", settingsSectionUI: "UI", settingsSectionSecurity: "Security", settingsSectionAdvanced: "Advanced", // Settings settingsDefaultEncryptionMethod: "Default Encryption Method", settingsDefaultEncryptionMethodDesc: "Choose a method to use to encrypt the note content", settingsDefaultEncryptionMode: "Default Encryption Mode", settingsDefaultEncryptionModeDesc: "Choose the default encryption mode", settingsIconStyle: "Icon Style", settingsIconStyleDesc: "Choose the icon style for the lock page", settingsRequirePasswordConfirmation: "Require Password Confirmation", settingsRequirePasswordConfirmationDesc: "When enabled, requires entering password twice when encrypting", settingsShowToggleExtensionButton: "Show Toggle Extension Button", settingsShowToggleExtensionButtonDesc: "Show the button to toggle between .md and .eccirian extensions", settingsShowNotices: "Show Notices", settingsShowNoticesDesc: "Show notification messages when encrypting/decrypting files", settingsShowHint: "Show Password Hint", settingsShowHintDesc: "Allow adding password hints when encrypting", settingsEncryptAttachments: "Encrypt Attachments", settingsEncryptAttachmentsDesc: "Automatically encrypt attachments (images, PDFs, etc.) linked in encrypted notes", settingsFileExtension: "Encrypted File Extension", settingsFileExtensionDesc: "Default extension for encrypted notes (without dot)", settingsKdfType: "Key Derivation Function", settingsKdfTypeDesc: "Choose PBKDF2 or Argon2id", settingsPbkdf2Iterations: "PBKDF2 Iterations", settingsPbkdf2IterationsDesc: "Higher is safer but slower. (Default: 600,000, WASP 2023)", settingsArgon2Memory: "Argon2id Memory (KB)", settingsArgon2MemoryDesc: "Memory cost in KiB. Higher = more secure, slower.", settingsArgon2Iterations: "Argon2id Iterations", settingsArgon2IterationsDesc: "Time cost (number of iterations).", settingsArgon2Parallelism: "Argon2id Parallelism", settingsArgon2ParallelismDesc: "Degree of parallelism (lanes/threads); higher uses more CPU.", settingsArgon2HashLen: "Argon2id Hash Length (bytes)", settingsArgon2HashLenDesc: "Derived key length. 32 is typical for AES-256.", kdfOptionPBKDF2: "PBKDF2", kdfOptionArgon2id: "Argon2id", // Advanced settings settingsEnableKeyCache: "Enable Key Cache", settingsEnableKeyCacheDesc: "Cache derived keys in memory to speed up repeated operations (recommended)", settingsKeyCacheTTL: "Key Cache TTL (Time to Live)", settingsKeyCacheTTLDesc: "How long to keep cached keys in memory (minutes, default: 5)", settingsKeyCacheMaxSize: "Key Cache Max Size", settingsKeyCacheMaxSizeDesc: "Maximum number of keys to cache simultaneously (default: 10)", settingsClearKeyCache: "Clear Key Cache", settingsClearKeyCacheDesc: "Manually clear all cached keys from memory", buttonClearCache: "Clear Cache", messageKeyCacheCleared: "Key cache cleared", messageKeyCacheNotEnabled: "Key cache is not enabled", // Encryption methods encryptionMethodAES: "AES-256 (Symmetric)", encryptionMethodECC: "ECC+AES (Asymmetric)", // Encryption modes encryptionModeTemporary: "Temporary (Single Use)", encryptionModePermanent: "Permanent (Repeatable)", // Icon styles iconStyleLock: "\u{1F512} Lock", iconStyleShield: "\u{1F6E1}\uFE0F Shield", iconStyleKey: "\u{1F511} Key", iconStylePadlock: "\u{1F510} Padlock", // Messages messageFileEncrypted: "File encrypted", messageFileDecrypted: "File decrypted", messageDecryptionFailed: "Decryption failed", messageInvalidFileFormat: "Invalid file format", messagePasswordIncorrect: "Password may be incorrect", messageUnexpectedError: "Unexpected error", messageFileDoesNotExist: "File does not exist", messageNotEncryptedFile: "This is not an encrypted file, restored as normal file", messagePleaseOpenFileFirst: "Please open a file first", messageOnlyMdCanBeConverted: "Only .md files can be converted to .eccirian", messageFileAlreadyDecrypted: "This file is already decrypted", messageConversionSuccess: "File converted to markdown successfully", messageConversionFailed: "Conversion failed", messagePleaseDecryptFirst: "Please decrypt the file first", messageFailedToGetCurrentFile: "Failed to get current file", messageFolderEncrypted: "Folder encrypted", messageFolderDecrypted: "Folder decrypted", commandEncryptFolder: "Encrypt Folder", // Lock view lockViewMessage: "is encrypted. Click below to unlock.", lockViewUnlockButton: "Unlock", // File conflict dialogs dialogFileAlreadyExists: "File Already Exists", dialogFileAlreadyExistsDesc1: 'A file named "{filename}" already exists.', dialogFileAlreadyExistsDesc2: "Decrypting will overwrite the existing file.", dialogFileAlreadyExistsDesc3: "Do you want to continue?", buttonCancel: "Cancel", buttonContinue: "Continue" }; var zhCN = { // Sections settingsSectionGeneral: "\u5E38\u89C4", settingsSectionUI: "\u754C\u9762", settingsSectionSecurity: "\u5B89\u5168", settingsSectionAdvanced: "\u9AD8\u7EA7", // Settings settingsDefaultEncryptionMethod: "\u9ED8\u8BA4\u52A0\u5BC6\u7B97\u6CD5", settingsDefaultEncryptionMethodDesc: "\u9009\u62E9\u4F7F\u7528\u54EA\u79CD\u65B9\u5F0F\u52A0\u5BC6\u7B14\u8BB0\u5185\u5BB9", settingsDefaultEncryptionMode: "\u9ED8\u8BA4\u52A0\u5BC6\u6A21\u5F0F", settingsDefaultEncryptionModeDesc: "\u9009\u62E9\u9ED8\u8BA4\u52A0\u5BC6\u6A21\u5F0F", settingsIconStyle: "\u56FE\u6807\u6837\u5F0F", settingsIconStyleDesc: "\u9009\u62E9\u9501\u5B9A\u9875\u9762\u56FE\u6807\u6837\u5F0F", settingsRequirePasswordConfirmation: "\u9700\u8981\u5BC6\u7801\u786E\u8BA4", settingsRequirePasswordConfirmationDesc: "\u542F\u7528\u540E\uFF0C\u52A0\u5BC6\u65F6\u9700\u8981\u8F93\u5165\u4E24\u6B21\u5BC6\u7801", settingsShowToggleExtensionButton: "\u663E\u793A\u6269\u5C55\u540D\u8F6C\u6362\u6309\u94AE", settingsShowToggleExtensionButtonDesc: "\u663E\u793A\u5728 .md \u548C .eccirian \u6269\u5C55\u540D\u4E4B\u95F4\u5207\u6362\u7684\u6309\u94AE", settingsShowNotices: "\u663E\u793A\u901A\u77E5", settingsShowNoticesDesc: "\u52A0\u5BC6/\u89E3\u5BC6\u6587\u4EF6\u65F6\u663E\u793A\u901A\u77E5\u6D88\u606F", settingsShowHint: "\u663E\u793A\u5BC6\u7801\u63D0\u793A", settingsShowHintDesc: "\u52A0\u5BC6\u65F6\u5141\u8BB8\u6DFB\u52A0\u5BC6\u7801\u63D0\u793A", settingsEncryptAttachments: "\u52A0\u5BC6\u9644\u4EF6", settingsEncryptAttachmentsDesc: "\u81EA\u52A8\u52A0\u5BC6\u7B14\u8BB0\u4E2D\u94FE\u63A5\u7684\u9644\u4EF6\uFF08\u56FE\u7247\u3001PDF\u7B49\uFF09", settingsFileExtension: "\u52A0\u5BC6\u6587\u4EF6\u6269\u5C55\u540D", settingsFileExtensionDesc: "\u52A0\u5BC6\u7B14\u8BB0\u7684\u9ED8\u8BA4\u6269\u5C55\u540D\uFF08\u4E0D\u542B\u70B9\uFF09", settingsKdfType: "\u5BC6\u94A5\u6D3E\u751F\u51FD\u6570", settingsKdfTypeDesc: "\u9009\u62E9 PBKDF2 \u6216 Argon2id", settingsPbkdf2Iterations: "PBKDF2 \u8FED\u4EE3\u6B21\u6570", settingsPbkdf2IterationsDesc: "\u6B21\u6570\u8D8A\u9AD8\u8D8A\u5B89\u5168\u4F46\u8D8A\u6162\uFF0C\u63A8\u8350\uFF1A100,000", settingsArgon2Memory: "Argon2id \u5185\u5B58 (KB)", settingsArgon2MemoryDesc: "\u5185\u5B58\u6D88\u8017\uFF08KiB\uFF09\uFF0C\u66F4\u9AD8\u66F4\u5B89\u5168\u4F46\u66F4\u6162\u3002", settingsArgon2Iterations: "Argon2id \u8FED\u4EE3\u6B21\u6570", settingsArgon2IterationsDesc: "\u65F6\u95F4\u6210\u672C\uFF08\u8FED\u4EE3\u6B21\u6570\uFF09", settingsArgon2Parallelism: "Argon2id \u5E76\u884C\u5EA6", settingsArgon2ParallelismDesc: "\u5E76\u884C\u901A\u9053\u6570\u91CF\uFF08lanes/\u7EBF\u7A0B\uFF09\uFF0C\u66F4\u9AD8\u4F1A\u5360\u7528\u66F4\u591A CPU", settingsArgon2HashLen: "Argon2id \u54C8\u5E0C\u957F\u5EA6 (\u5B57\u8282)", settingsArgon2HashLenDesc: "\u6D3E\u751F\u5BC6\u94A5\u957F\u5EA6\uFF0C32 \u9002\u7528\u4E8E AES-256", kdfOptionPBKDF2: "PBKDF2", kdfOptionArgon2id: "Argon2id", // Advanced settings settingsEnableKeyCache: "\u542F\u7528\u5BC6\u94A5\u7F13\u5B58", settingsEnableKeyCacheDesc: "\u5728\u5185\u5B58\u4E2D\u7F13\u5B58\u6D3E\u751F\u5BC6\u94A5\u4EE5\u52A0\u901F\u91CD\u590D\u64CD\u4F5C\uFF08\u63A8\u8350\uFF09", settingsKeyCacheTTL: "\u5BC6\u94A5\u7F13\u5B58\u5B58\u6D3B\u65F6\u95F4", settingsKeyCacheTTLDesc: "\u5728\u5185\u5B58\u4E2D\u4FDD\u7559\u7F13\u5B58\u5BC6\u94A5\u7684\u65F6\u957F\uFF08\u5206\u949F\uFF0C\u9ED8\u8BA45\uFF09", settingsKeyCacheMaxSize: "\u5BC6\u94A5\u7F13\u5B58\u6700\u5927\u6570\u91CF", settingsKeyCacheMaxSizeDesc: "\u540C\u65F6\u7F13\u5B58\u7684\u6700\u5927\u5BC6\u94A5\u6570\u91CF\uFF08\u9ED8\u8BA410\uFF09", settingsClearKeyCache: "\u6E05\u9664\u5BC6\u94A5\u7F13\u5B58", settingsClearKeyCacheDesc: "\u624B\u52A8\u6E05\u9664\u5185\u5B58\u4E2D\u7684\u6240\u6709\u7F13\u5B58\u5BC6\u94A5", buttonClearCache: "\u6E05\u9664\u7F13\u5B58", messageKeyCacheCleared: "\u5BC6\u94A5\u7F13\u5B58\u5DF2\u6E05\u9664", messageKeyCacheNotEnabled: "\u5BC6\u94A5\u7F13\u5B58\u672A\u542F\u7528", // Encryption methods encryptionMethodAES: "AES-256\uFF08\u5BF9\u79F0\u52A0\u5BC6\uFF09", encryptionMethodECC: "ECC+AES\uFF08\u975E\u5BF9\u79F0\u52A0\u5BC6\uFF09", // Encryption modes encryptionModeTemporary: "\u4E34\u65F6\uFF08\u5355\u6B21\u4F7F\u7528\uFF09", encryptionModePermanent: "\u6C38\u4E45\uFF08\u91CD\u590D\u4F7F\u7528\uFF09", // Icon styles iconStyleLock: "\u{1F512} \u9501", iconStyleShield: "\u{1F6E1}\uFE0F \u76FE\u724C", iconStyleKey: "\u{1F511} \u94A5\u5319", iconStylePadlock: "\u{1F510} \u6302\u9501", // Messages messageFileEncrypted: "\u6587\u4EF6\u5DF2\u52A0\u5BC6", messageFileDecrypted: "\u6587\u4EF6\u5DF2\u89E3\u5BC6", messageDecryptionFailed: "\u89E3\u5BC6\u5931\u8D25", messageInvalidFileFormat: "\u65E0\u6548\u7684\u6587\u4EF6\u683C\u5F0F", messagePasswordIncorrect: "\u5BC6\u7801\u53EF\u80FD\u4E0D\u6B63\u786E", messageUnexpectedError: "\u610F\u5916\u9519\u8BEF", messageFileDoesNotExist: "\u6587\u4EF6\u4E0D\u5B58\u5728", messageNotEncryptedFile: "\u8FD9\u4E0D\u662F\u52A0\u5BC6\u6587\u4EF6\uFF0C\u5DF2\u6062\u590D\u4E3A\u666E\u901A\u6587\u4EF6", messagePleaseOpenFileFirst: "\u8BF7\u5148\u6253\u5F00\u4E00\u4E2A\u6587\u4EF6", messageOnlyMdCanBeConverted: "\u53EA\u6709 .md \u6587\u4EF6\u53EF\u4EE5\u8F6C\u6362\u4E3A .eccirian", messageFileAlreadyDecrypted: "\u6B64\u6587\u4EF6\u5DF2\u89E3\u5BC6", messageConversionSuccess: "\u6587\u4EF6\u5DF2\u6210\u529F\u8F6C\u6362\u4E3A markdown", messageConversionFailed: "\u8F6C\u6362\u5931\u8D25", messagePleaseDecryptFirst: "\u8BF7\u5148\u89E3\u5BC6\u6587\u4EF6", messageFailedToGetCurrentFile: "\u65E0\u6CD5\u83B7\u53D6\u5F53\u524D\u6587\u4EF6", messageFolderEncrypted: "\u6587\u4EF6\u5939\u5DF2\u52A0\u5BC6", messageFolderDecrypted: "\u6587\u4EF6\u5939\u5DF2\u89E3\u5BC6", commandEncryptFolder: "\u52A0\u5BC6\u6587\u4EF6\u5939", // Lock view lockViewMessage: "\u5DF2\u52A0\u5BC6\u3002\u70B9\u51FB\u4E0B\u65B9\u89E3\u9501\u3002", lockViewUnlockButton: "\u89E3\u9501", // File conflict dialogs dialogFileAlreadyExists: "\u6587\u4EF6\u5DF2\u5B58\u5728", dialogFileAlreadyExistsDesc1: '\u540D\u4E3A "{filename}" \u7684\u6587\u4EF6\u5DF2\u5B58\u5728\u3002', dialogFileAlreadyExistsDesc2: "\u89E3\u5BC6\u5C06\u8986\u76D6\u73B0\u6709\u6587\u4EF6\u3002", dialogFileAlreadyExistsDesc3: "\u8981\u7EE7\u7EED\u5417\uFF1F", buttonCancel: "\u53D6\u6D88", buttonContinue: "\u7EE7\u7EED" }; var locales = { "en": en, "zh": zhCN, "zh-CN": zhCN, "zh-cn": zhCN }; function getI18n(locale) { if (locales[locale]) { return locales[locale]; } const langCode = locale.split("-")[0]; if (locales[langCode]) { return locales[langCode]; } return en; } function t(key, locale) { const i18n = getI18n(locale); return i18n[key] || key; } // src/ui/settingsTab.ts var ConfirmModal = class extends import_obsidian2.Modal { constructor(app) { super(app); } onOpen() { const { contentEl } = this; new import_obsidian2.Setting(contentEl).setName("Visit GitHub Repository?").setHeading(); contentEl.createEl("p", { text: "Do you want to visit the GitHub repository?" }); new import_obsidian2.Setting(contentEl).addButton((button) => { button.setButtonText("Cancel").onClick(() => { this.close(); }); }).addButton((button) => { button.setButtonText("Confirm").setCta().onClick(() => { window.open("https://github.com/Enthalpiex/eccirian-encrypt", "_blank"); this.close(); }); }); } onClose() { const { contentEl } = this; contentEl.empty(); } }; var EccEncryptSettingTab = class extends import_obsidian2.PluginSettingTab { constructor(app, plugin) { super(app, plugin); this.plugin = plugin; } display() { const { containerEl } = this; containerEl.empty(); const locale = import_obsidian2.moment.locale(); const logoContainer = containerEl.createDiv("eccirian-logo-container"); logoContainer.style.textAlign = "center"; logoContainer.style.marginBottom = "2rem"; logoContainer.style.cursor = "pointer"; logoContainer.style.width = "100%"; const logo = logoContainer.createEl("img", { attr: { src: "data:image/png;base64,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", alt: "Eccirian Logo" } }); logo.style.width = "100%"; logo.style.height = "auto"; logo.style.objectFit = "cover"; logoContainer.addEventListener("click", () => { new ConfirmModal(this.app).open(); }); new import_obsidian2.Setting(containerEl).setName(t("settingsSectionGeneral", locale)).setHeading(); new import_obsidian2.Setting(containerEl).setName(t("settingsDefaultEncryptionMethod", locale)).setDesc(t("settingsDefaultEncryptionMethodDesc", locale)).addDropdown( (drop) => drop.addOption("AES", t("encryptionMethodAES", locale)).addOption("ECC", t("encryptionMethodECC", locale)).setValue(this.plugin.settings.encryptionMethod).onChange(async (value) => { this.plugin.settings.encryptionMethod = value; await this.plugin.saveSettings(); }) ); new import_obsidian2.Setting(containerEl).setName(t("settingsDefaultEncryptionMode", locale)).setDesc(t("settingsDefaultEncryptionModeDesc", locale)).addDropdown( (drop) => drop.addOption("temporary", t("encryptionModeTemporary", locale)).addOption("permanent", t("encryptionModePermanent", locale)).setValue(this.plugin.settings.defaultEncryptionMode).onChange(async (value) => { this.plugin.settings.defaultEncryptionMode = value; await this.plugin.saveSettings(); }) ); new import_obsidian2.Setting(containerEl).setName(t("settingsSectionUI", locale)).setHeading(); new import_obsidian2.Setting(containerEl).setName(t("settingsIconStyle", locale)).setDesc(t("settingsIconStyleDesc", locale)).addDropdown( (drop) => drop.addOption("lock", t("iconStyleLock", locale)).addOption("shield", t("iconStyleShield", locale)).addOption("key", t("iconStyleKey", locale)).addOption("padlock", t("iconStylePadlock", locale)).setValue(this.plugin.settings.iconStyle).onChange(async (value) => { this.plugin.settings.iconStyle = value; await this.plugin.saveSettings(); }) ); new import_obsidian2.Setting(containerEl).setName(t("settingsRequirePasswordConfirmation", locale)).setDesc(t("settingsRequirePasswordConfirmationDesc", locale)).addToggle( (toggle) => toggle.setValue(this.plugin.settings.requirePasswordConfirmation).onChange(async (value) => { this.plugin.settings.requirePasswordConfirmation = value; await this.plugin.saveSettings(); }) ); new import_obsidian2.Setting(containerEl).setName(t("settingsShowToggleExtensionButton", locale)).setDesc(t("settingsShowToggleExtensionButtonDesc", locale)).addToggle( (toggle) => toggle.setValue(this.plugin.settings.showToggleExtensionButton).onChange(async (value) => { this.plugin.settings.showToggleExtensionButton = value; await this.plugin.saveSettings(); this.plugin.updateToggleExtensionButton(); }) ); new import_obsidian2.Setting(containerEl).setName(t("settingsShowNotices", locale)).setDesc(t("settingsShowNoticesDesc", locale)).addToggle( (toggle) => toggle.setValue(this.plugin.settings.showNotice).onChange(async (value) => { this.plugin.settings.showNotice = value; await this.plugin.saveSettings(); }) ); new import_obsidian2.Setting(containerEl).setName(t("settingsShowHint", locale)).setDesc(t("settingsShowHintDesc", locale)).addToggle( (toggle) => toggle.setValue(this.plugin.settings.showHint).onChange(async (value) => { this.plugin.settings.showHint = value; await this.plugin.saveSettings(); }) ); new import_obsidian2.Setting(containerEl).setName(t("settingsSectionSecurity", locale)).setHeading(); new import_obsidian2.Setting(containerEl).setName(t("settingsEncryptAttachments", locale)).setDesc(t("settingsEncryptAttachmentsDesc", locale)).addToggle( (toggle) => toggle.setValue(this.plugin.settings.encryptAttachments).onChange(async (value) => { this.plugin.settings.encryptAttachments = value; await this.plugin.saveSettings(); }) ); new import_obsidian2.Setting(containerEl).setName(t("settingsKdfType", locale)).setDesc(t("settingsKdfTypeDesc", locale)).addDropdown( (drop) => drop.addOption("PBKDF2", t("kdfOptionPBKDF2", locale)).addOption("Argon2id", t("kdfOptionArgon2id", locale)).setValue(this.plugin.settings.kdfType).onChange(async (value) => { const prevScroll = containerEl.scrollTop; this.plugin.settings.kdfType = value; await this.plugin.saveSettings(); this.display(); setTimeout(() => { containerEl.scrollTop = prevScroll; }, 0); }) ); if (this.plugin.settings.kdfType === "PBKDF2") { new import_obsidian2.Setting(containerEl).setName(t("settingsPbkdf2Iterations", locale)).setDesc(t("settingsPbkdf2IterationsDesc", locale)).addDropdown( (drop) => drop.addOption("100000", "100,000 (Fast)").addOption("600000", "600,000 (Balanced)").addOption("1000000", "1,000,000 (Strong)").setValue(String(this.plugin.settings.pbkdf2Iterations)).onChange(async (value) => { const v = parseInt(value, 10); this.plugin.settings.pbkdf2Iterations = v; await this.plugin.saveSettings(); }) ); } if (this.plugin.settings.kdfType === "Argon2id") { new import_obsidian2.Setting(containerEl).setName(t("settingsArgon2Memory", locale)).setDesc(t("settingsArgon2MemoryDesc", locale)).addText( (text) => text.setPlaceholder("65536").setValue(String(this.plugin.settings.argon2MemoryKB)).onChange(async (value) => { const v = Math.max(8192, parseInt(value || "65536", 10) || 65536); this.plugin.settings.argon2MemoryKB = v; await this.plugin.saveSettings(); }) ); new import_obsidian2.Setting(containerEl).setName(t("settingsArgon2Iterations", locale)).setDesc(t("settingsArgon2IterationsDesc", locale)).addDropdown( (drop) => drop.addOption("1", "1 (Fast)").addOption("3", "3 (Balanced)").addOption("5", "5 (Strong)").setValue(String(this.plugin.settings.argon2Iterations)).onChange(async (value) => { const v = parseInt(value, 10) || 3; this.plugin.settings.argon2Iterations = v; await this.plugin.saveSettings(); }) ); new import_obsidian2.Setting(containerEl).setName(t("settingsArgon2Parallelism", locale)).setDesc(t("settingsArgon2ParallelismDesc", locale)).addDropdown( (drop) => drop.addOption("1", "1").addOption("2", "2").addOption("4", "4").setValue(String(this.plugin.settings.argon2Parallelism)).onChange(async (value) => { const v = parseInt(value, 10) || 1; this.plugin.settings.argon2Parallelism = v; await this.plugin.saveSettings(); }) ); new import_obsidian2.Setting(containerEl).setName(t("settingsArgon2HashLen", locale)).setDesc(t("settingsArgon2HashLenDesc", locale)).addDropdown( (drop) => drop.addOption("16", "16").addOption("32", "32 (AES-256)").addOption("64", "64").setValue(String(this.plugin.settings.argon2HashLen)).onChange(async (value) => { const v = parseInt(value, 10) || 32; this.plugin.settings.argon2HashLen = v; await this.plugin.saveSettings(); }) ); } new import_obsidian2.Setting(containerEl).setName(t("settingsSectionAdvanced", locale)).setHeading(); new import_obsidian2.Setting(containerEl).setName(t("settingsEnableKeyCache", locale)).setDesc(t("settingsEnableKeyCacheDesc", locale)).addToggle( (toggle) => toggle.setValue(this.plugin.settings.enableKeyCache).onChange(async (value) => { this.plugin.settings.enableKeyCache = value; await this.plugin.saveSettings(); if (value && !this.plugin.keyCache) { const { KeyCache: KeyCache2 } = await Promise.resolve().then(() => (init_keyCache(), keyCache_exports)); this.plugin.keyCache = new KeyCache2( this.plugin.settings.keyCacheTTL, this.plugin.settings.keyCacheMaxSize ); } else if (!value && this.plugin.keyCache) { this.plugin.keyCache.clear(); this.plugin.keyCache = null; } this.display(); }) ); if (this.plugin.settings.enableKeyCache) { new import_obsidian2.Setting(containerEl).setName(t("settingsKeyCacheTTL", locale)).setDesc(t("settingsKeyCacheTTLDesc", locale)).addSlider( (slider) => slider.setLimits(1, 30, 1).setValue(this.plugin.settings.keyCacheTTL).setDynamicTooltip().onChange(async (value) => { this.plugin.settings.keyCacheTTL = value; await this.plugin.saveSettings(); if (this.plugin.keyCache) { const { KeyCache: KeyCache2 } = await Promise.resolve().then(() => (init_keyCache(), keyCache_exports)); const oldCache = this.plugin.keyCache; oldCache.clear(); this.plugin.keyCache = new KeyCache2(value, this.plugin.settings.keyCacheMaxSize); } }) ); new import_obsidian2.Setting(containerEl).setName(t("settingsKeyCacheMaxSize", locale)).setDesc(t("settingsKeyCacheMaxSizeDesc", locale)).addSlider( (slider) => slider.setLimits(5, 50, 5).setValue(this.plugin.settings.keyCacheMaxSize).setDynamicTooltip().onChange(async (value) => { this.plugin.settings.keyCacheMaxSize = value; await this.plugin.saveSettings(); if (this.plugin.keyCache) { const { KeyCache: KeyCache2 } = await Promise.resolve().then(() => (init_keyCache(), keyCache_exports)); const oldCache = this.plugin.keyCache; oldCache.clear(); this.plugin.keyCache = new KeyCache2(this.plugin.settings.keyCacheTTL, value); } }) ); new import_obsidian2.Setting(containerEl).setName(t("settingsClearKeyCache", locale)).setDesc(t("settingsClearKeyCacheDesc", locale)).addButton( (button) => button.setButtonText(t("buttonClearCache", locale)).setWarning().onClick(() => { if (this.plugin.settings.showNotice) { if (this.plugin.keyCache) { this.plugin.keyCache.clear(); new import_obsidian2.Notice(t("messageKeyCacheCleared", locale)); } else { new import_obsidian2.Notice(t("messageKeyCacheNotEnabled", locale)); } } }) ); } } }; // src/settings.ts var DEFAULT_SETTINGS = { encryptionMethod: "ECC", defaultEncryptionMode: "temporary", iconStyle: "lock", requirePasswordConfirmation: true, showToggleExtensionButton: true, showNotice: false, showHint: true, fileExtension: "eccirian", encryptAttachments: true, kdfType: "PBKDF2", pbkdf2Iterations: 6e5, argon2MemoryKB: 65536, argon2Iterations: 3, argon2Parallelism: 1, argon2HashLen: 32, // Advanced defaults enableKeyCache: true, keyCacheTTL: 5, keyCacheMaxSize: 10 }; // src/utils/fileHelper.ts var import_obsidian3 = require("obsidian"); async function changeFileExtension(vault, file, newExt) { const pathParts = file.path.split("/"); const fileName = pathParts.pop(); const baseName = fileName.replace(/\.[^/.]+$/, ""); const newPath = [...pathParts, `${baseName}.${newExt}`].join("/"); const result = await vault.rename(file, newPath); const newFile = vault.getAbstractFileByPath(newPath); if (!(newFile instanceof import_obsidian3.TFile)) { throw new Error(`Expected a file at path ${newPath} but got a folder or null`); } return newFile; } // src/view/eccirianView.ts var import_obsidian6 = require("obsidian"); var import_obsidian7 = require("obsidian"); init_aesWithPassword(); init_eccWithPassword(); init_attachmentHelper(); // src/utils/folderHelper.ts var import_obsidian5 = require("obsidian"); var FolderHelper = class { /** * Pack folder contents into a JSON structure */ static async packFolder(vault, folder) { const folderData = { isFolder: true, folderName: folder.name, folderPath: folder.path, files: [], subfolders: [] }; const files = this.getAllFilesInFolder(folder); for (const file of files) { const content = await vault.read(file); folderData.files.push({ path: file.path.replace(folder.path + "/", ""), // Relative path content, extension: file.extension }); } return JSON.stringify(folderData); } /** * Unpack folder from JSON structure */ static async unpackFolder(vault, folderData, targetPath) { const data = JSON.parse(folderData); if (!data.isFolder) { throw new Error("Not a folder encryption data"); } const folderPath = targetPath || data.folderPath; const existingFolder = vault.getAbstractFileByPath(folderPath); if (!existingFolder) { await vault.createFolder(folderPath); } for (const fileData of data.files) { const filePath = `${folderPath}/${fileData.path}`; const parentPath = filePath.substring(0, filePath.lastIndexOf("/")); if (parentPath && !vault.getAbstractFileByPath(parentPath)) { await vault.createFolder(parentPath); } const existingFile = vault.getAbstractFileByPath(filePath); if (existingFile instanceof import_obsidian5.TFile) { await vault.modify(existingFile, fileData.content); } else { await vault.create(filePath, fileData.content); } } } /** * Get all files in a folder recursively */ static getAllFilesInFolder(folder) { const files = []; for (const child of folder.children) { if (child instanceof import_obsidian5.TFile) { files.push(child); } else if (child instanceof import_obsidian5.TFolder) { files.push(...this.getAllFilesInFolder(child)); } } return files; } /** * Check if encrypted content is a folder */ static isFolderEncryption(content) { try { const data = JSON.parse(content); return data.isFolder === true; } catch (e) { return false; } } /** * Get folder metadata from encrypted content */ static getFolderMetadata(content) { try { const data = JSON.parse(content); if (!data.isFolder) return null; return { folderName: data.folderName, fileCount: data.files.length, folderPath: data.folderPath }; } catch (e) { return null; } } }; // src/view/eccirianView.ts init_fileData(); var ECCIDIAN_VIEW_TYPE = "eccirian-encrypt-view"; var EccidianView = class extends import_obsidian6.FileView { constructor(leaf, plugin) { super(leaf); this.loadingFile = false; this.displayName = "Encrypted Note"; this.filePath = ""; this.navigation = true; this.plugin = plugin; } updateTitle(newTitle) { this.displayName = newTitle; } getViewType() { return ECCIDIAN_VIEW_TYPE; } getDisplayText() { if (this.file) { return this.file.basename; } return this.displayName; } getIcon() { return "lock"; } async setState(state, result) { await super.setState(state, result); if (state == null ? void 0 : state.file) { if (state.file instanceof import_obsidian7.TFile) { this.file = state.file; this.filePath = state.file.path; this.updateTitle(state.file.basename); } else if (typeof state.file === "string") { this.filePath = state.file; const file = this.app.vault.getAbstractFileByPath(this.filePath); if (file instanceof import_obsidian7.TFile) { this.file = file; this.updateTitle(file.basename); } } } await this.onOpen(); } getState() { return { file: this.filePath, type: ECCIDIAN_VIEW_TYPE }; } async onOpen() { const container = this.containerEl.children[1]; const containerEl = this.containerEl; containerEl.style.backgroundColor = "var(--background-primary)"; containerEl.style.position = "relative"; const contentContainer = container; contentContainer.style.position = "relative"; let isFolder = false; let folderMetadata = null; if (this.file) { try { const content = await this.app.vault.read(this.file); const isFolderMatch = content.match(/IS_FOLDER:(.+)/); isFolder = !!(isFolderMatch && isFolderMatch[1] === "true"); if (isFolder) { } } catch (error) { console.error("Error checking folder status:", error); } } const iconMap = { lock: "\u{1F512}", shield: "\u{1F6E1}\uFE0F", key: "\u{1F511}", padlock: "\u{1F510}" }; const icon = iconMap[this.plugin.settings.iconStyle] || "\u{1F512}"; const displayIcon = isFolder ? "\u{1F4C1}" : icon; const lockView = container.createDiv({ cls: "eccirian-lock-view" }); lockView.style.cssText = ` position: absolute; top: 0; left: 0; right: 0; bottom: 0; height: 100%; width: 100%; display: flex; flex-direction: column; align-items: center; justify-content: center; text-align: center; padding: 2rem; background-color: var(--background-primary); z-index: 1000; pointer-events: auto; `; const contentElements = contentContainer.querySelectorAll("*:not(.eccirian-lock-view)"); contentElements.forEach((el) => { if (el !== lockView && !lockView.contains(el)) { el.style.pointerEvents = "none"; } }); lockView.addEventListener("keydown", (e) => { e.stopPropagation(); e.preventDefault(); }); lockView.addEventListener("keyup", (e) => { e.stopPropagation(); e.preventDefault(); }); lockView.addEventListener("keypress", (e) => { e.stopPropagation(); e.preventDefault(); }); lockView.addEventListener("mousedown", (e) => { if (e.target.tagName !== "BUTTON") { e.stopPropagation(); } }); const lockIcon = lockView.createDiv({ cls: "eccirian-lock-icon" }); lockIcon.style.cssText = ` font-size: 64px; margin-bottom: 1.5rem; opacity: 0.8; transition: transform 0.3s ease; `; lockIcon.setText(displayIcon); const message = lockView.createEl("p", { cls: "eccirian-message" }); message.style.cssText = ` margin-bottom: 2rem; font-size: 1.1rem; color: var(--text-muted); line-height: 1.5; `; const itemType = isFolder ? "folder" : "file"; message.setText(this.file ? `"${this.file.basename}" is an encrypted ${itemType}. Click below to unlock.` : `This file is encrypted. Click below to unlock.`); const unlockBtn = lockView.createEl("button", { cls: "eccirian-unlock-button" }); unlockBtn.style.cssText = ` padding: 0.75rem 1.5rem; font-size: 1rem; cursor: pointer; border-radius: 6px; border: 1px solid var(--background-modifier-border); background-color: var(--background-primary); color: var(--text-normal); transition: all 0.2s ease; box-shadow: 0 2px 4px rgba(0,0,0,0.1); `; unlockBtn.setText("Unlock"); unlockBtn.addEventListener("mouseenter", () => { unlockBtn.style.backgroundColor = "var(--background-secondary)"; unlockBtn.style.transform = "translateY(-1px)"; lockIcon.style.transform = "scale(1.1)"; }); unlockBtn.addEventListener("mouseleave", () => { unlockBtn.style.backgroundColor = "var(--background-primary)"; unlockBtn.style.transform = "translateY(0)"; lockIcon.style.transform = "scale(1)"; }); unlockBtn.addEventListener("click", async () => { if (this.filePath) { const file = this.app.vault.getAbstractFileByPath(this.filePath); if (file instanceof import_obsidian7.TFile) { this.file = file; } } if (!this.file) { if (this.plugin.settings.showNotice) { new import_obsidian7.Notice("File does not exist"); } return; } try { const encContent = await this.app.vault.read(this.file); const looksJson = encContent.trim().startsWith("{") && encContent.includes("encodedData"); if (!encContent.includes("%%ENC") && !looksJson) { if (this.plugin.settings.showNotice) { new import_obsidian7.Notice("This is not an encrypted file"); } const leaf = this.app.workspace.getLeaf(); await leaf.openFile(this.file, { state: { mode: "source" } }); return; } const isFolderMatch0 = encContent.match(/IS_FOLDER:(.+)/); const isFolder0 = isFolderMatch0 && isFolderMatch0[1] === "true"; if (!encContent.includes("%%ENC") && looksJson) { try { const dataObj = JSON.parse(encContent); const originalExt2 = (dataObj.originalExt || "md").toLowerCase(); const encoded = String(dataObj.encodedData || ""); new PasswordModal( this.app, async (password) => { var _a, _b, _c, _d, _e; try { const parts = encoded.split("\n"); const saltLine = parts.find((p) => p.startsWith("SALT:")); const ivLine = parts.find((p) => p.startsWith("IV:")); const dataLine = parts.find((p) => p.startsWith("DATA:")); const fmtLine = parts.find((p) => p.startsWith("FORMAT:")); const kdfLine = (_a = parts.find((p) => p.startsWith("KDF:"))) == null ? void 0 : _a.slice(4); if (!saltLine || !ivLine || !dataLine) { if (this.plugin.settings.showNotice) new import_obsidian7.Notice("Invalid JSON format"); return; } const salt = saltLine.slice(5); const iv = ivLine.slice(3); const data = dataLine.slice(5); const fmt = (fmtLine ? fmtLine.slice(7) : "").toUpperCase(); let kdfOpts; if (kdfLine) { const segs = kdfLine.split(":"); if (segs[0].toUpperCase() === "ARGON2ID" && segs.length >= 5) { kdfOpts = { type: "Argon2id", argon2MemoryKB: parseInt(segs[1], 10) || 65536, argon2Iterations: parseInt(segs[2], 10) || 3, argon2Parallelism: parseInt(segs[3], 10) || 1, argon2HashLen: parseInt(segs[4], 10) || 32 }; } else if (segs[0].toUpperCase() === "PBKDF2") { kdfOpts = { type: "PBKDF2", pbkdf2Iterations: parseInt(segs[1], 10) || 6e5 }; } } else if (dataObj.kdf) { if (dataObj.kdf === "Argon2id") { kdfOpts = { type: "Argon2id", argon2MemoryKB: dataObj.argon2MemoryKB || 65536, argon2Iterations: dataObj.argon2Iterations || 3, argon2Parallelism: dataObj.argon2Parallelism || 1, argon2HashLen: dataObj.argon2HashLen || 32 }; } else { kdfOpts = { type: "PBKDF2", pbkdf2Iterations: dataObj.iterations || 6e5 }; } } if (originalExt2 !== "md") { let arrayBuffer; if (fmt === "BIN") { const { decryptBytesWithPassword: decryptBytesWithPassword2 } = await Promise.resolve().then(() => (init_aesWithPassword(), aesWithPassword_exports)); const bytes = await decryptBytesWithPassword2(password, salt, iv, data, ((_c = (_b = this.plugin) == null ? void 0 : _b.getKeyCache) == null ? void 0 : _c.call(_b)) || void 0, kdfOpts); arrayBuffer = bytes.buffer.slice(bytes.byteOffset, bytes.byteOffset + bytes.byteLength); } else { const txt = await FileDataHelper.decrypt(dataObj, password, ((_e = (_d = this.plugin) == null ? void 0 : _d.getKeyCache) == null ? void 0 : _e.call(_d)) || void 0, kdfOpts); if (!txt) { if (this.plugin.settings.showNotice) new import_obsidian7.Notice("Decryption failed"); return; } const buf = Buffer.from(txt, "base64"); arrayBuffer = buf.buffer.slice(buf.byteOffset, buf.byteOffset + buf.byteLength); } if (!this.file) { if (this.plugin.settings.showNotice) new import_obsidian7.Notice("File not found"); return; } const basePath = this.file.path.replace(/\.eccirian$/, "").replace(/\.peccirian$/, ""); const originalPath = basePath.toLowerCase().endsWith(".md") ? basePath : `${basePath}.md`; const existing = this.app.vault.getAbstractFileByPath(originalPath); if (existing instanceof import_obsidian7.TFile) { const shouldOverwrite = await new Promise((resolve) => { const modal = new import_obsidian7.Modal(this.app); modal.titleEl.setText(this.plugin.i18n.dialogFileAlreadyExists || "File Already Exists"); const desc = modal.contentEl.createDiv(); const filename = originalPath.split("/").pop() || originalPath; desc.createEl("p", { text: (this.plugin.i18n.dialogFileAlreadyExistsDesc1 || 'A file named "{filename}" already exists.').replace("{filename}", filename) }); desc.createEl("p", { text: this.plugin.i18n.dialogFileAlreadyExistsDesc2 || "Decrypting will overwrite the existing file.", cls: "mod-warning" }); desc.createEl("p", { text: this.plugin.i18n.dialogFileAlreadyExistsDesc3 || "Do you want to continue?" }); const buttonContainer = modal.contentEl.createDiv("modal-button-container"); const cancelBtn = buttonContainer.createEl("button", { text: this.plugin.i18n.buttonCancel || "Cancel", cls: "mod-cancel" }); cancelBtn.addEventListener("click", () => { resolve(false); modal.close(); }); const continueBtn = buttonContainer.createEl("button", { text: this.plugin.i18n.buttonContinue || "Continue", cls: "mod-cta mod-warning" }); continueBtn.addEventListener("click", () => { resolve(true); modal.close(); }); modal.open(); }); if (!shouldOverwrite) { return; } await this.app.vault.delete(existing); } if (existing instanceof import_obsidian7.TFile) { await this.app.vault.modifyBinary(existing, arrayBuffer); } else { await this.app.vault.createBinary(originalPath, arrayBuffer); } await this.app.vault.delete(this.file); if (this.plugin.settings.showNotice) new import_obsidian7.Notice("File decrypted"); const restored = this.app.vault.getAbstractFileByPath(originalPath); if (restored instanceof import_obsidian7.TFile) { const leaf = this.app.workspace.getLeaf(); await leaf.openFile(restored); } return; } } catch (e) { if (this.plugin.settings.showNotice) new import_obsidian7.Notice("Decryption failed"); } }, async () => { }, this.plugin.settings.defaultEncryptionMode, true, this.plugin.settings.requirePasswordConfirmation, this.plugin.settings.showHint, this.plugin.settings.encryptionMethod, this.plugin, true, void 0 ).open(); return; } catch (e) { } } if (isFolder0) { const saltMatch2 = encContent.match(/SALT:(.+)/); const ivMatch2 = encContent.match(/IV:(.+)/); const dataMatch2 = encContent.match(/DATA:(.+)/); const typeMatch2 = encContent.match(/TYPE:(.+)/); const hintMatch2 = encContent.match(/HINT:(.+)/); const encryptionType2 = typeMatch2 ? typeMatch2[1] : "temporary"; const hint2 = hintMatch2 ? hintMatch2[1] : void 0; if (!saltMatch2 || !ivMatch2 || !dataMatch2) { if (this.plugin.settings.showNotice) new import_obsidian7.Notice("Decryption failed: Invalid file format"); return; } new PasswordModal( this.app, async (password) => { var _a, _b, _c, _d, _e; try { let decrypted; const publicKeyMatch = encContent.match(/PUBLIC_KEY:(.+)/); const ephemeralPublicKeyMatch = encContent.match(/EPHEMERAL_PUBLIC_KEY:(.+)/); const kdfLine = encContent.match(/KDF:(.+)/); let kdfOpts; if (kdfLine) { const segs = kdfLine[1].split(":"); if (segs[0].toUpperCase() === "ARGON2ID" && segs.length >= 5) { kdfOpts = { type: "Argon2id", argon2MemoryKB: parseInt(segs[1], 10) || 65536, argon2Iterations: parseInt(segs[2], 10) || 3, argon2Parallelism: parseInt(segs[3], 10) || 1, argon2HashLen: parseInt(segs[4], 10) || 32 }; } else if (segs[0].toUpperCase() === "PBKDF2") { kdfOpts = { type: "PBKDF2", pbkdf2Iterations: parseInt(segs[1], 10) || 6e5 }; } } if (publicKeyMatch) { const ephemeralKey = ephemeralPublicKeyMatch ? ephemeralPublicKeyMatch[1] : void 0; decrypted = await decryptWithPassword2( password, saltMatch2[1], ivMatch2[1], dataMatch2[1], publicKeyMatch[1], ephemeralKey, ((_b = (_a = this.plugin) == null ? void 0 : _a.getKeyCache) == null ? void 0 : _b.call(_a)) || void 0, kdfOpts ); } else { decrypted = await decryptWithPassword( password, saltMatch2[1], ivMatch2[1], dataMatch2[1], ((_d = (_c = this.plugin) == null ? void 0 : _c.getKeyCache) == null ? void 0 : _d.call(_c)) || void 0, kdfOpts ); } const originalPathMatch = encContent.match(/ORIGINAL_PATH:(.+)/); const originalPath = originalPathMatch ? originalPathMatch[1] : null; if (!originalPath) { if (this.plugin.settings.showNotice) new import_obsidian7.Notice("Missing ORIGINAL_PATH"); return; } const getAvailableFolderPath = (basePath) => { const lastSlash = basePath.lastIndexOf("/"); const dir = lastSlash >= 0 ? basePath.substring(0, lastSlash) : ""; const name = lastSlash >= 0 ? basePath.substring(lastSlash + 1) : basePath; const buildPath = (n2) => { const suffix = n2 === 0 ? "" : n2 === 1 ? " (Restored)" : ` (Restored ${n2})`; const finalName = `${name}${suffix}`; return dir ? `${dir}/${finalName}` : finalName; }; let n = 0; let candidate = buildPath(n); while (this.app.vault.getAbstractFileByPath(candidate)) { n += 1; candidate = buildPath(n); } return candidate; }; const targetPath = getAvailableFolderPath(originalPath); await FolderHelper.unpackFolder(this.app.vault, decrypted, targetPath); if (this.file) { await this.app.vault.delete(this.file); } if (this.plugin.settings.showNotice) { new import_obsidian7.Notice(`${this.plugin.i18n.messageFolderDecrypted} \u2192 ${targetPath}`); } } catch (error) { console.error("Folder decryption failed:", error); console.error("Salt:", saltMatch2 == null ? void 0 : saltMatch2[1]); console.error("IV:", ivMatch2 == null ? void 0 : ivMatch2[1]); console.error("Data:", ((_e = dataMatch2 == null ? void 0 : dataMatch2[1]) == null ? void 0 : _e.substring(0, 50)) + "..."); console.error("Error details:", error instanceof Error ? error.message : String(error)); if (this.plugin.settings.showNotice) { new import_obsidian7.Notice("Decryption failed: " + (error instanceof Error ? error.message : "Unknown error")); } } }, async () => { }, this.plugin.settings.defaultEncryptionMode, true, this.plugin.settings.requirePasswordConfirmation, this.plugin.settings.showHint, this.plugin.settings.encryptionMethod, this.plugin, true, hint2 ).open(); return; } const mdPath = this.file.path.replace(/\.[^/.]+$/, ".md"); const existingMdFile = this.app.vault.getAbstractFileByPath(mdPath); if (existingMdFile) { const continueDecrypt = await new Promise((resolve) => { const modal = new import_obsidian7.Modal(this.app); modal.titleEl.setText(this.plugin.i18n.dialogFileAlreadyExists || "File Already Exists"); const desc = modal.contentEl.createDiv(); const filename = mdPath.split("/").pop() || mdPath; desc.createEl("p", { text: (this.plugin.i18n.dialogFileAlreadyExistsDesc1 || 'A file named "{filename}" already exists.').replace("{filename}", filename) }); desc.createEl("p", { text: this.plugin.i18n.dialogFileAlreadyExistsDesc2 || "Decrypting will overwrite the existing file.", cls: "mod-warning" }); desc.createEl("p", { text: this.plugin.i18n.dialogFileAlreadyExistsDesc3 || "Do you want to continue?" }); const buttonContainer = modal.contentEl.createDiv("modal-button-container"); const cancelBtn = buttonContainer.createEl("button", { text: this.plugin.i18n.buttonCancel || "Cancel", cls: "mod-cancel" }); cancelBtn.addEventListener("click", () => { resolve(false); modal.close(); }); const continueBtn = buttonContainer.createEl("button", { text: this.plugin.i18n.buttonContinue || "Continue", cls: "mod-cta mod-warning" }); continueBtn.addEventListener("click", () => { resolve(true); modal.close(); }); modal.open(); }); if (!continueDecrypt) { return; } await this.app.vault.delete(existingMdFile); } const mdFile = await changeFileExtension(this.app.vault, this.file, "md"); const content = await this.app.vault.read(mdFile); if (!content.includes("%%ENC")) { if (this.plugin.settings.showNotice) new import_obsidian7.Notice("This is not an encrypted file, restored as normal file"); const leaf = this.app.workspace.getLeaf(); await leaf.openFile(mdFile, { state: { mode: "source" } }); return; } const saltMatch = content.match(/SALT:(.+)/); const ivMatch = content.match(/IV:(.+)/); const dataMatch = content.match(/DATA:(.+)/); const typeMatch = content.match(/TYPE:(.+)/); const isFolderMatch = content.match(/IS_FOLDER:(.+)/); const isFolder2 = isFolderMatch && isFolderMatch[1] === "true"; const originalExtMatch = content.match(/ORIGINAL_EXT:(.+)/); if (!saltMatch || !ivMatch || !dataMatch || !typeMatch) { await changeFileExtension(this.app.vault, mdFile, "eccirian"); if (this.plugin.settings.showNotice) { new import_obsidian7.Notice("Decryption failed: Invalid file format"); } return; } if (!isFolder2 && !originalExtMatch) { await changeFileExtension(this.app.vault, mdFile, "eccirian"); if (this.plugin.settings.showNotice) { new import_obsidian7.Notice("Decryption failed: Invalid file format"); } return; } const encryptionType = typeMatch[1]; const originalExt = originalExtMatch ? originalExtMatch[1] : "md"; const hintMatch = content.match(/HINT:(.+)/); const hint = hintMatch ? hintMatch[1] : void 0; this.plugin.settings.defaultEncryptionMode = encryptionType; await this.plugin.saveSettings(); new PasswordModal( this.app, async (password) => { var _a, _b; try { const dataObj = JsonFileEncoding.decode(content); const decrypted = await FileDataHelper.decrypt(dataObj, password, ((_b = (_a = this.plugin) == null ? void 0 : _a.getKeyCache) == null ? void 0 : _b.call(_a)) || void 0); if (!decrypted) { await changeFileExtension(this.app.vault, mdFile, "eccirian"); if (this.plugin.settings.showNotice) new import_obsidian7.Notice("Decryption failed: Password may be incorrect"); return; } try { const isFolderMatch2 = content.match(/IS_FOLDER:(.+)/); const isFolder3 = isFolderMatch2 && isFolderMatch2[1] === "true"; if (isFolder3) { const originalPathMatch = content.match(/ORIGINAL_PATH:(.+)/); const originalPath2 = originalPathMatch ? originalPathMatch[1] : null; if (originalPath2) { const getAvailableFolderPath = (basePath) => { const lastSlash = basePath.lastIndexOf("/"); const dir = lastSlash >= 0 ? basePath.substring(0, lastSlash) : ""; const name = lastSlash >= 0 ? basePath.substring(lastSlash + 1) : basePath; const buildPath = (n2) => { const suffix = n2 === 0 ? "" : n2 === 1 ? " (Restored)" : ` (Restored ${n2})`; const finalName = `${name}${suffix}`; return dir ? `${dir}/${finalName}` : finalName; }; let n = 0; let candidate = buildPath(n); while (this.app.vault.getAbstractFileByPath(candidate)) { n += 1; candidate = buildPath(n); } return candidate; }; const targetPath = getAvailableFolderPath(originalPath2); await FolderHelper.unpackFolder(this.app.vault, decrypted, targetPath); await this.app.vault.delete(mdFile); if (this.plugin.settings.showNotice) { new import_obsidian7.Notice(`${this.plugin.i18n.messageFolderDecrypted} \u2192 ${targetPath}`); } return; } } let processedText = decrypted.trim() === "$\xB7-\xB7$" ? "" : decrypted; const decodedType = JsonFileEncoding.decode(content).type; if (this.plugin.settings.encryptAttachments && decodedType === "temporary") { const attachmentLinks = AttachmentHelper.extractAttachmentLinks(processedText); await Promise.all( attachmentLinks.map(async (link) => { try { const encryptedAttachment = AttachmentHelper.resolveAttachmentPath( this.app.vault, mdFile.path, link ); if (!encryptedAttachment) { console.warn(`Attachment not found: ${link}`); return; } await AttachmentHelper.decryptBinaryFile( this.app.vault, encryptedAttachment, password ); } catch (error) { console.error(`Failed to decrypt attachment ${link}:`, error); } }) ); processedText = AttachmentHelper.updateAttachmentLinks( processedText, "decrypt", "temporary" ); } await this.app.vault.modify(mdFile, processedText); if (this.plugin.settings.showNotice) new import_obsidian7.Notice("File decrypted"); const leaf = this.app.workspace.getLeaf(); const decoded = JsonFileEncoding.decode(content); const originalExt2 = decoded.originalExt || "md"; const originalPath = mdFile.path.replace(/\.[^/.]+$/, `.${originalExt2}`); const existingOriginalFile = this.app.vault.getAbstractFileByPath(originalPath); if (existingOriginalFile && existingOriginalFile !== mdFile) { const continueRestore = await new Promise((resolve) => { const modal = new import_obsidian7.Modal(this.app); modal.titleEl.setText(this.plugin.i18n.dialogFileAlreadyExists || "File Already Exists"); const desc = modal.contentEl.createDiv(); const filename = originalPath.split("/").pop() || originalPath; desc.createEl("p", { text: (this.plugin.i18n.dialogFileAlreadyExistsDesc1 || 'A file named "{filename}" already exists.').replace("{filename}", filename) }); desc.createEl("p", { text: this.plugin.i18n.dialogFileAlreadyExistsDesc2 || "Decrypting will overwrite the existing file.", cls: "mod-warning" }); desc.createEl("p", { text: this.plugin.i18n.dialogFileAlreadyExistsDesc3 || "Do you want to continue?" }); const buttonContainer = modal.contentEl.createDiv("modal-button-container"); const cancelBtn = buttonContainer.createEl("button", { text: this.plugin.i18n.buttonCancel || "Cancel", cls: "mod-cancel" }); cancelBtn.addEventListener("click", () => { resolve(false); modal.close(); }); const continueBtn = buttonContainer.createEl("button", { text: this.plugin.i18n.buttonContinue || "Continue", cls: "mod-cta mod-warning" }); continueBtn.addEventListener("click", () => { resolve(true); modal.close(); }); modal.open(); }); if (!continueRestore) { await leaf.openFile(mdFile, { state: { mode: "source" } }); return; } await this.app.vault.delete(existingOriginalFile); } const originalFile = await changeFileExtension(this.app.vault, mdFile, originalExt2); await leaf.openFile(originalFile, { state: { mode: "source" } }); } catch (err) { const leaf = this.app.workspace.getLeaf(); await leaf.openFile(mdFile, { state: { mode: "source" } }); return; } } catch (err) { console.error("Decryption error:", err); await changeFileExtension(this.app.vault, mdFile, "eccirian"); if (this.plugin.settings.showNotice) { new import_obsidian7.Notice("Decryption failed: Unexpected error"); } return; } }, async () => { try { await changeFileExtension(this.app.vault, mdFile, "eccirian"); } catch (err) { if (this.plugin.settings.showNotice) { new import_obsidian7.Notice("Failed to restore file extension"); } } }, this.plugin.settings.defaultEncryptionMode, true, this.plugin.settings.requirePasswordConfirmation, this.plugin.settings.showHint, this.plugin.settings.encryptionMethod, this.plugin, true, // Show mode selection hint // Pass the hint to display ).open(); } catch (err) { if (this.plugin.settings.showNotice) new import_obsidian7.Notice("Failed to change file extension"); } }); } async onClose() { await super.onClose(); } }; // src/view/peccirianView.ts var import_obsidian8 = require("obsidian"); init_fileData(); var PECCIDIAN_VIEW_TYPE = "peccidian-encrypt-view"; var PEccidianView = class extends import_obsidian8.MarkdownView { constructor(leaf, plugin) { super(leaf); this.loadingFile = false; this.displayName = "Encrypted Note"; this.password = null; this.encryptedData = null; this.isSavingEnabled = true; this.isLoadingFileInProgress = false; this.isSavingInProgress = false; this.isPasswordModalOpen = false; this.isInitialized = false; this.lastChangeTime = 0; this.changeDebounceTimeout = null; this.memoryKey = null; this.isViewActive = false; this.isSwitchingView = false; this.lockView = null; this.isLockViewVisible = false; this.lastOpenedFilePath = null; this.plugin = plugin; this.filePath = ""; this.generateMemoryKey(); } generateMemoryKey() { const array = new Uint8Array(32); crypto.getRandomValues(array); this.memoryKey = Array.from(array, (byte) => byte.toString(16).padStart(2, "0")).join(""); } encryptForMemory(text) { if (!this.memoryKey) { this.generateMemoryKey(); } const key = this.memoryKey; let result = ""; for (let i = 0; i < text.length; i++) { const charCode = text.charCodeAt(i) ^ key.charCodeAt(i % key.length); result += String.fromCharCode(charCode); } return btoa(result); } decryptFromMemory(encryptedText) { if (!this.memoryKey) return encryptedText; const key = this.memoryKey; const text = atob(encryptedText); let result = ""; for (let i = 0; i < text.length; i++) { const charCode = text.charCodeAt(i) ^ key.charCodeAt(i % key.length); result += String.fromCharCode(charCode); } return result; } setPassword(password) { const encryptedPassword = this.encryptForMemory(password); this.password = encryptedPassword; } getPassword() { if (!this.password) return null; return this.decryptFromMemory(this.password); } getViewType() { return PECCIDIAN_VIEW_TYPE; } updateTitle(newTitle) { this.displayName = newTitle; const titleEl = this.contentEl.querySelector(".inline-title"); if (titleEl) { titleEl.textContent = newTitle; titleEl.setAttribute("data-inline-title", newTitle); } } getDisplayText() { if (this.file) { return this.file.basename; } return this.displayName; } getIcon() { return "lock"; } createLockView() { if (this.lockView) { this.lockView.remove(); this.lockView = null; } const contentEl = this.contentEl; if (contentEl) { contentEl.style.pointerEvents = "none"; } const containerEl = this.containerEl; containerEl.style.backgroundColor = "var(--background-primary)"; containerEl.style.position = "relative"; const container = this.containerEl.children[1]; container.style.position = "relative"; this.lockView = container.createDiv({ cls: "peccirian-lock-view" }); this.lockView.style.cssText = ` position: absolute; top: 0; left: 0; right: 0; bottom: 0; height: 100%; width: 100%; display: flex; flex-direction: column; align-items: center; justify-content: center; text-align: center; padding: 2rem; background-color: var(--background-primary); z-index: 1000; pointer-events: auto; `; this.lockView.addEventListener("keydown", (e) => { e.stopPropagation(); e.preventDefault(); }); this.lockView.addEventListener("keyup", (e) => { e.stopPropagation(); e.preventDefault(); }); this.lockView.addEventListener("keypress", (e) => { e.stopPropagation(); e.preventDefault(); }); this.lockView.addEventListener("mousedown", (e) => { if (e.target.tagName !== "BUTTON") { e.stopPropagation(); } }); const iconMap = { lock: "\u{1F512}", shield: "\u{1F6E1}\uFE0F", key: "\u{1F511}", padlock: "\u{1F510}" }; const icon = iconMap[this.plugin.settings.iconStyle] || "\u{1F512}"; const lockIcon = this.lockView.createDiv({ cls: "peccirian-lock-icon" }); lockIcon.style.cssText = ` font-size: 64px; margin-bottom: 1.5rem; opacity: 0.8; transition: transform 0.3s ease; `; lockIcon.setText(icon); const message = this.lockView.createEl("p", { cls: "peccirian-message" }); message.style.cssText = ` margin-bottom: 2rem; font-size: 1.1rem; color: var(--text-muted); line-height: 1.5; `; message.setText(this.file ? `"${this.file.basename}" is an encrypted file. Click below to unlock.` : "This file is encrypted. Click below to unlock."); const unlockBtn = this.lockView.createEl("button", { cls: "peccirian-unlock-button" }); unlockBtn.style.cssText = ` padding: 0.75rem 1.5rem; font-size: 1rem; cursor: pointer; border-radius: 6px; border: 1px solid var(--background-modifier-border); background-color: var(--background-primary); color: var(--text-normal); transition: all 0.2s ease; box-shadow: 0 2px 4px rgba(0,0,0,0.1); `; unlockBtn.setText("Unlock"); unlockBtn.addEventListener("mouseenter", () => { unlockBtn.style.backgroundColor = "var(--background-secondary)"; unlockBtn.style.transform = "translateY(-1px)"; lockIcon.style.transform = "scale(1.1)"; }); unlockBtn.addEventListener("mouseleave", () => { unlockBtn.style.backgroundColor = "var(--background-primary)"; unlockBtn.style.transform = "translateY(0)"; lockIcon.style.transform = "scale(1)"; }); unlockBtn.addEventListener("click", async () => { await this.showPasswordModal(); }); this.isLockViewVisible = true; } hideLockView() { if (this.lockView) { this.lockView.style.display = "none"; this.isLockViewVisible = false; } const contentEl = this.contentEl; if (contentEl) { contentEl.style.pointerEvents = "auto"; } } async showPasswordModal() { if (this.isPasswordModalOpen || this.isLoadingFileInProgress) { return; } this.isLoadingFileInProgress = true; try { if (!this.file) { this.leaf.detach(); return; } const fileContents = await this.app.vault.read(this.file); try { this.encryptedData = JsonFileEncoding.decode(fileContents); if (!this.encryptedData || !this.encryptedData.encodedData) { this.leaf.detach(); return; } } catch (error) { this.leaf.detach(); return; } return new Promise((resolve, reject) => { var _a; if (this.isPasswordModalOpen) { reject(new Error("Password modal already open")); return; } this.isPasswordModalOpen = true; const hint = (_a = this.encryptedData) == null ? void 0 : _a.hint; const modal = new PasswordModal( this.app, async (password) => { try { if (!this.encryptedData) { this.leaf.detach(); reject(new Error("No encrypted data")); return; } const kdfOpts = this.plugin.settings.kdfType === "Argon2id" ? { type: "Argon2id", argon2MemoryKB: this.plugin.settings.argon2MemoryKB, argon2Iterations: this.plugin.settings.argon2Iterations, argon2Parallelism: this.plugin.settings.argon2Parallelism, argon2HashLen: this.plugin.settings.argon2HashLen } : { type: "PBKDF2", pbkdf2Iterations: this.plugin.settings.pbkdf2Iterations }; const decryptedText = await FileDataHelper.decrypt(this.encryptedData, password, this.plugin.getKeyCache() || void 0, kdfOpts); if (!decryptedText) { if (this.plugin.settings.showNotice) new import_obsidian8.Notice("Decryption failed: Password may be incorrect"); this.leaf.detach(); reject(new Error("Decryption failed")); return; } const processedText = decryptedText.trim() === "$\xB7-\xB7$" ? "" : decryptedText; this.setPassword(password); this.setUnencryptedViewData(processedText, true); this.isSavingEnabled = true; this.registerEditorChangeHandler(); this.hideLockView(); modal.close(); resolve(); } catch (err) { if (this.plugin.settings.showNotice) new import_obsidian8.Notice("Decryption failed: Unexpected error"); this.leaf.detach(); reject(err); } finally { this.isPasswordModalOpen = false; this.isLoadingFileInProgress = false; } }, () => { this.isPasswordModalOpen = false; this.isLoadingFileInProgress = false; this.leaf.detach(); resolve(); }, "permanent", true, false, false, this.plugin.settings.encryptionMethod, this.plugin, false, // Hide mode selection for permanent files hint // Pass the hint to display ); modal.open(); }); } catch (error) { this.isPasswordModalOpen = false; this.isLoadingFileInProgress = false; if (!(error instanceof Error && error.name === "UserCancelled")) { this.leaf.detach(); } } } async setState(state, result) { if (this.isLoadingFileInProgress || this.isPasswordModalOpen || this.isSwitchingView) { return; } const isViewSwitch = !this.isViewActive && ((state == null ? void 0 : state.file) instanceof import_obsidian8.TFile || typeof (state == null ? void 0 : state.file) === "string"); this.isViewActive = true; this.isSwitchingView = true; try { await super.setState(state, result); if (state == null ? void 0 : state.file) { if (state.file instanceof import_obsidian8.TFile) { this.file = state.file; this.filePath = state.file.path; this.updateTitle(state.file.basename); } else if (typeof state.file === "string") { this.filePath = state.file; const file = this.app.vault.getAbstractFileByPath(this.filePath); if (file instanceof import_obsidian8.TFile) { this.file = file; this.updateTitle(file.basename); } } } if (!this.isInitialized) { this.isInitialized = true; await this.onOpen(); } } finally { this.isSwitchingView = false; } } getState() { return { file: this.filePath, type: PECCIDIAN_VIEW_TYPE }; } async onLoadFile(file) { if (this.isSavingEnabled && this.password && this.file && this.file.path !== file.path && this.file.extension === "peccirian") { try { await this.save(false); } catch (error) { console.error("Failed to save before loading new file:", error); } } if (file.extension !== "peccirian") { this.handleNonPeccirianFile(file); return; } const isSameFile = this.lastOpenedFilePath === file.path; if (isSameFile) { return; } if (this.changeDebounceTimeout) { clearTimeout(this.changeDebounceTimeout); this.changeDebounceTimeout = null; } this.password = null; this.encryptedData = null; this.isSavingEnabled = false; this.isInitialized = false; this.lastOpenedFilePath = file.path; this.createLockView(); } async handleNonPeccirianFile(file) { if (this.isSavingEnabled && this.password && this.file && this.file.extension === "peccirian") { try { await this.save(false); } catch (error) { console.error("Failed to save before switching files:", error); } } if (this.changeDebounceTimeout) { clearTimeout(this.changeDebounceTimeout); this.changeDebounceTimeout = null; } this.isSavingEnabled = false; this.password = null; this.encryptedData = null; const currentLeaf = this.leaf; const newLeaf = this.app.workspace.getLeaf("tab"); await newLeaf.openFile(file); currentLeaf.detach(); } registerEditorChangeHandler() { setTimeout(() => { if (!this.editor) return; this.registerEvent( this.app.workspace.on("editor-change", (editor) => { if (editor === this.editor) { this.handleEditorChange(); } }) ); const cmEditor = this.editor.cm; if (cmEditor) { this.registerDomEvent(cmEditor.dom, "change", () => { this.handleEditorChange(); }); this.registerDomEvent(cmEditor.dom, "keyup", () => { this.handleEditorChange(); }); } }, 100); } handleEditorChange() { if (this.changeDebounceTimeout) { clearTimeout(this.changeDebounceTimeout); } this.changeDebounceTimeout = setTimeout(async () => { var _a, _b; if (!this.isSavingEnabled || !this.password) { return; } try { const currentContent = this.getUnencryptedViewData(); const password = this.getPassword(); if (!password) { throw new Error("Failed to retrieve password from memory"); } const kdfOpts2 = this.plugin.settings.kdfType === "Argon2id" ? { type: "Argon2id", argon2MemoryKB: this.plugin.settings.argon2MemoryKB, argon2Iterations: this.plugin.settings.argon2Iterations, argon2Parallelism: this.plugin.settings.argon2Parallelism, argon2HashLen: this.plugin.settings.argon2HashLen } : { type: "PBKDF2", pbkdf2Iterations: this.plugin.settings.pbkdf2Iterations }; this.encryptedData = await FileDataHelper.encrypt( password, currentContent, "permanent", ((_a = this.encryptedData) == null ? void 0 : _a.originalExt) || "md", (_b = this.encryptedData) == null ? void 0 : _b.hint, this.plugin.settings.encryptionMethod, // Pass algorithm from settings this.plugin.getKeyCache() || void 0, kdfOpts2 ); this.isSavingInProgress = true; try { const encryptedContent = JsonFileEncoding.encode(this.encryptedData); if (this.file) { await this.app.vault.modify(this.file, encryptedContent); } } finally { this.isSavingInProgress = false; } } catch (error) { console.error("Auto-encryption failed:", error); } }, 2e3); } outputStats(content) { const wordCount = content.split(/\s+/).filter((word) => word.length > 0).length; const charCount = content.length; const lineCount = content.split("\n").length; } async save(clear) { var _a, _b; if (this.isSavingInProgress) { return; } if (!this.file || !this.isSavingEnabled || !this.password) { return; } this.isSavingInProgress = true; try { let unencryptedDataToSave = this.getUnencryptedViewData(); const password = this.getPassword(); if (!password) { throw new Error("Failed to retrieve password from memory"); } if (this.plugin.settings.encryptAttachments) { const AttachmentHelper2 = (await Promise.resolve().then(() => (init_attachmentHelper(), attachmentHelper_exports))).AttachmentHelper; unencryptedDataToSave = AttachmentHelper2.updateAttachmentLinks( unencryptedDataToSave, "encrypt", "permanent" ); } const processedData = unencryptedDataToSave === "" ? "$\xB7-\xB7$" : unencryptedDataToSave; const kdfOpts3 = this.plugin.settings.kdfType === "Argon2id" ? { type: "Argon2id", argon2MemoryKB: this.plugin.settings.argon2MemoryKB, argon2Iterations: this.plugin.settings.argon2Iterations, argon2Parallelism: this.plugin.settings.argon2Parallelism, argon2HashLen: this.plugin.settings.argon2HashLen } : { type: "PBKDF2", pbkdf2Iterations: this.plugin.settings.pbkdf2Iterations }; this.encryptedData = await FileDataHelper.encrypt( password, processedData, "permanent", ((_a = this.file) == null ? void 0 : _a.extension) || "md", (_b = this.encryptedData) == null ? void 0 : _b.hint, this.plugin.settings.encryptionMethod, // Pass algorithm from settings this.plugin.getKeyCache() || void 0, kdfOpts3 ); if (!this.file) { return; } const encryptedContent = JsonFileEncoding.encode(this.encryptedData); await this.app.vault.modify(this.file, encryptedContent); } catch (error) { console.error("Save operation failed:", error); } finally { this.isSavingInProgress = false; } } getViewData() { if (this.isSavingInProgress && this.encryptedData) { return JsonFileEncoding.encode(this.encryptedData); } return this.getUnencryptedViewData(); } setViewData(data, clear) { if (JsonFileEncoding.isEncoded(data)) { try { const newEncoded = JsonFileEncoding.decode(data); if (!this.password) { this.leaf.detach(); return; } FileDataHelper.decrypt(newEncoded, this.password).then((decryptedText) => { if (decryptedText === null) { this.leaf.detach(); return; } this.setUnencryptedViewData(decryptedText, clear); }).catch((error) => { }); } catch (error) { } return; } this.setUnencryptedViewData(data, clear); } setUnencryptedViewData(data, clear) { super.setViewData(data, clear); if (this.file) { this.updateTitle(this.file.basename); } } getUnencryptedViewData() { return super.getViewData(); } detachSafely() { this.save(); this.isSavingEnabled = false; this.leaf.detach(); } async onOpen() { if (!this.file || !this.isViewActive || this.isSwitchingView) { return; } if (this.isPasswordModalOpen || this.isLoadingFileInProgress) { return; } try { await this.onLoadFile(this.file); } catch (error) { if (!(error instanceof Error && error.name === "UserCancelled")) { this.leaf.detach(); } } } async onunload() { var _a, _b; await super.onunload(); this.isViewActive = false; this.isSwitchingView = false; if (this.changeDebounceTimeout) { clearTimeout(this.changeDebounceTimeout); this.changeDebounceTimeout = null; } try { if (this.isSavingEnabled && this.password && this.file) { const currentContent = this.getUnencryptedViewData(); const password = this.getPassword(); if (!password) { return; } const kdfOpts4 = this.plugin.settings.kdfType === "Argon2id" ? { type: "Argon2id", argon2MemoryKB: this.plugin.settings.argon2MemoryKB, argon2Iterations: this.plugin.settings.argon2Iterations, argon2Parallelism: this.plugin.settings.argon2Parallelism, argon2HashLen: this.plugin.settings.argon2HashLen } : { type: "PBKDF2", pbkdf2Iterations: this.plugin.settings.pbkdf2Iterations }; this.encryptedData = await FileDataHelper.encrypt( password, currentContent, "permanent", ((_a = this.encryptedData) == null ? void 0 : _a.originalExt) || "md", (_b = this.encryptedData) == null ? void 0 : _b.hint, this.plugin.settings.encryptionMethod, // Pass algorithm from settings void 0, kdfOpts4 ); if (!this.file) { return; } const encryptedContent = JsonFileEncoding.encode(this.encryptedData); await this.app.vault.modify(this.file, encryptedContent); } } catch (error) { console.error("Error during final save:", error); } finally { this.memoryKey = null; this.password = null; this.encryptedData = null; this.isSavingEnabled = false; this.lastOpenedFilePath = null; } } setSavingEnabled(enabled) { this.isSavingEnabled = enabled; } isDecrypted() { return this.password !== null; } isDecrypting() { return this.isLoadingFileInProgress || this.isPasswordModalOpen; } async getDecryptedContent() { if (!this.isDecrypted()) { throw new Error("File is not decrypted"); } const content = this.getUnencryptedViewData(); return content; } getDecryptedPassword() { return this.getPassword(); } async onUnloadFile(file) { if (this.isInitialized && this.password && this.isSavingEnabled) { try { await super.onUnloadFile(file); } catch (error) { console.debug("Error during onUnloadFile:", error); } } } async detach() { await this.leaf.detach(); } async handlePasswordInput(password) { if (!this.file) return; try { let decryptedContent = await this.decryptFile(this.file, password); if (this.plugin.settings.encryptAttachments) { const AttachmentHelper2 = (await Promise.resolve().then(() => (init_attachmentHelper(), attachmentHelper_exports))).AttachmentHelper; decryptedContent = AttachmentHelper2.updateAttachmentLinks( decryptedContent, "decrypt", "permanent" ); } this.setViewData(decryptedContent, false); this.hideLockView(); this.setPassword(password); if (this.plugin.settings.showNotice) { new import_obsidian8.Notice("File decrypted"); } } catch (error) { console.error("Decryption failed:", error); if (this.plugin.settings.showNotice) { new import_obsidian8.Notice("Decryption failed: Password may be incorrect"); } } } async decryptFile(file, password) { try { const content = await this.app.vault.read(file); const data = JsonFileEncoding.decode(content); if (!data || !data.encodedData) { throw new Error("Invalid file format"); } const decryptedText = await FileDataHelper.decrypt(data, password); if (!decryptedText) { throw new Error("Decryption failed"); } return decryptedText; } catch (error) { console.error("Decryption error:", error); if (this.plugin.settings.showNotice) new import_obsidian8.Notice("Decryption failed: Unexpected error"); throw error; } } }; // src/main.ts init_fileData(); init_attachmentHelper(); init_keyCache(); var EccEncryptPlugin = class extends import_obsidian9.Plugin { constructor() { super(...arguments); this.toggleExtensionButton = null; this.keyCache = null; this.isConvertingToMarkdown = false; } // Mutex to prevent concurrent conversions async onload() { await this.loadSettings(); this.i18n = getI18n(window.localStorage.getItem("language") || "en"); if (this.settings.enableKeyCache) { this.keyCache = new KeyCache( this.settings.keyCacheTTL, this.settings.keyCacheMaxSize ); this.registerInterval(window.setInterval(() => { var _a; (_a = this.keyCache) == null ? void 0 : _a.cleanup(); }, 60 * 1e3)); } this.addCommand({ id: "encrypt-decrypt", name: "Toggle between .md and .eccirian", callback: async () => { const activeFile = this.app.workspace.getActiveFile(); if (!activeFile) { if (this.settings.showNotice) { new import_obsidian9.Notice("Please open a file first"); } return; } try { if (activeFile.extension === "eccirian") { const mdFile = await changeFileExtension(this.app.vault, activeFile, "md"); const leaf = this.app.workspace.getLeaf(); await leaf.openFile(mdFile); } else if (activeFile.extension === "md") { const eccFile = await changeFileExtension(this.app.vault, activeFile, "eccirian"); const leaf = this.app.workspace.getLeaf(); await leaf.openFile(eccFile); } else { if (this.settings.showNotice) new import_obsidian9.Notice("Only .md files can be converted to .eccirian"); } } catch (err) { } } }); this.addRibbonIcon(this.settings.iconStyle, "Encrypt/Decrypt Current File", async () => { await this.handleEncryptDecrypt(false); }); this.updateToggleExtensionButton(); this.registerView( ECCIDIAN_VIEW_TYPE, (leaf) => new EccidianView(leaf, this) ); this.registerView( PECCIDIAN_VIEW_TYPE, (leaf) => new PEccidianView(leaf, this) ); this.registerExtensions(["eccirian"], ECCIDIAN_VIEW_TYPE); this.registerExtensions(["peccirian"], PECCIDIAN_VIEW_TYPE); this.registerEvent( this.app.workspace.on("file-open", async (file) => { try { if (!file || !(file instanceof import_obsidian9.TFile)) return; if (file.extension !== "eccirian" && file.extension !== "peccirian") { return; } let leaf = this.app.workspace.getMostRecentLeaf(); if (!leaf) { leaf = this.app.workspace.getLeaf(); } const viewType = file.extension === "eccirian" ? ECCIDIAN_VIEW_TYPE : PECCIDIAN_VIEW_TYPE; await leaf.setViewState({ type: viewType, active: true }); const view = leaf.view; if (file.extension === "eccirian" && view instanceof EccidianView || file.extension === "peccirian" && view instanceof PEccidianView) { await view.setState({ file }, { history: true }); } else { console.error("View is not of correct type:", { extension: file.extension, viewType: view.getViewType() }); } } catch (error) { console.error("Error opening file:", error); if (this.settings.showNotice) { } } }) ); this.addSettingTab(new EccEncryptSettingTab(this.app, this)); this.registerDomEvent(document, "DOMContentLoaded", () => { this.loadStyles(); }); this.addCommand({ id: "encrypt-decrypt-file", name: "Encrypt/Decrypt file", callback: async () => { await this.handleEncryptDecrypt(true); } }); this.addCommand({ id: "encrypt-folder", name: "Encrypt Folder", checkCallback: (checking) => { const folder = this.getSelectedFolder(); if (folder) { if (!checking) { this.encryptFolder(folder); } return true; } return false; } }); this.addCommand({ id: "convert-to-md", name: "Remove Permanent Encryption (Convert to Normal Markdown)", checkCallback: (checking) => { const view = this.app.workspace.getActiveViewOfType(PEccidianView); if (view) { if (!checking) { this.convertToMarkdown(view); } return true; } return false; } }); this.addRibbonIcon("file-input", "Remove Permanent Encryption", async () => { const activeFile = this.app.workspace.getActiveFile(); if (!activeFile) { if (this.settings.showNotice) new import_obsidian9.Notice("Please open a file first"); return; } const activeView = this.app.workspace.getActiveViewOfType(PEccidianView); if (!activeView || activeView.file !== activeFile) { if (this.settings.showNotice) new import_obsidian9.Notice("Please open a decrypted permanently encrypted file first"); return; } try { this.convertToMarkdown(activeView); } catch (error) { console.error("Error converting file:", error); if (this.settings.showNotice) new import_obsidian9.Notice("Failed to convert file: " + (error instanceof Error ? error.message : "Unknown error")); } }); this.addCommand({ id: "convert-to-markdown", name: "Convert to Markdown", callback: async () => { const activeFile = this.app.workspace.getActiveFile(); if (!activeFile) { if (this.settings.showNotice) { new import_obsidian9.Notice("Please open a file first"); } return; } const activeView = this.app.workspace.getActiveViewOfType(PEccidianView); if (!activeView || activeView.file !== activeFile) { if (this.settings.showNotice) { new import_obsidian9.Notice("Please open a decrypted permanently encrypted file first"); } return; } try { await this.convertToMarkdown(activeView); } catch (error) { console.error("Error converting file:", error); if (this.settings.showNotice) { new import_obsidian9.Notice("Failed to convert file: " + (error instanceof Error ? error.message : "Unknown error")); } } } }); this.registerEvent( this.app.workspace.on("file-menu", (menu, file) => { if (file instanceof import_obsidian9.TFolder) { menu.addItem((item) => { item.setTitle(this.i18n.commandEncryptFolder).setIcon("lock").onClick(async () => { await this.encryptFolder(file); }); }); } }) ); } updateToggleExtensionButton() { if (this.toggleExtensionButton) { this.toggleExtensionButton.remove(); this.toggleExtensionButton = null; } if (this.settings.showToggleExtensionButton) { this.toggleExtensionButton = this.addRibbonIcon("file-text", "Toggle File Extension", async () => { const activeFile = this.app.workspace.getActiveFile(); if (!activeFile) { return; } try { if (activeFile.extension === "eccirian") { const mdFile = await changeFileExtension(this.app.vault, activeFile, "md"); const leaf = this.app.workspace.getLeaf(); await leaf.openFile(mdFile); } else if (activeFile.extension === "md") { const eccFile = await changeFileExtension(this.app.vault, activeFile, "eccirian"); const leaf = this.app.workspace.getLeaf(); await leaf.openFile(eccFile); } else { if (this.settings.showNotice) new import_obsidian9.Notice("Only .md files can be converted to .eccirian"); } } catch (err) { } }); } } async onunload() { if (this.keyCache) { this.keyCache.clear(); } if (this.toggleExtensionButton) { this.toggleExtensionButton.remove(); this.toggleExtensionButton = null; } this.app.workspace.detachLeavesOfType(ECCIDIAN_VIEW_TYPE); this.app.workspace.detachLeavesOfType(PECCIDIAN_VIEW_TYPE); } getKeyCache() { return this.keyCache; } async switchToMarkdownView(file) { this.app.workspace.detachLeavesOfType(ECCIDIAN_VIEW_TYPE); const leaf = this.app.workspace.getLeaf(); await leaf.openFile(file, { state: { mode: "source" } }); } async loadSettings() { this.settings = Object.assign({}, DEFAULT_SETTINGS, await this.loadData()); } async saveSettings() { await this.saveData(this.settings); } loadStyles() { const link = document.createElement("link"); link.rel = "stylesheet"; link.type = "text/css"; link.href = this.app.vault.adapter.getResourcePath(`${this.manifest.dir}/styles.css`); document.head.appendChild(link); } async convertToMarkdown(view) { var _a, _b, _c, _d, _e; if (this.isConvertingToMarkdown) { if (this.settings.showNotice) { new import_obsidian9.Notice("A conversion is already in progress. Please wait."); } return; } if (!view.isDecrypted() || view.isDecrypting()) { if (this.settings.showNotice) { new import_obsidian9.Notice("Please wait until decryption is complete."); } return; } this.isConvertingToMarkdown = true; try { if (!view.isDecrypted()) { if (this.settings.showNotice) { new import_obsidian9.Notice("Please decrypt the file first"); } return; } let content = await view.getDecryptedContent(); const currentFile = view.file; if (!currentFile) { if (this.settings.showNotice) { new import_obsidian9.Notice("Failed to get current file"); } return; } try { const raw = await this.app.vault.read(currentFile); if (raw.trim().startsWith("{") && raw.includes("encodedData")) { const dataObj = JsonFileEncoding.decode(raw); const originalExt = (dataObj.originalExt || "md").toLowerCase(); if (originalExt !== "md") { const password2 = view.getDecryptedPassword(); if (!password2) { if (this.settings.showNotice) new import_obsidian9.Notice("Missing password to restore file"); return; } const lines = String(dataObj.encodedData || "").split("\n"); const salt = ((_a = lines.find((l) => l.startsWith("SALT:"))) == null ? void 0 : _a.slice(5)) || ""; const iv = ((_b = lines.find((l) => l.startsWith("IV:"))) == null ? void 0 : _b.slice(3)) || ""; const data = ((_c = lines.find((l) => l.startsWith("DATA:"))) == null ? void 0 : _c.slice(5)) || ""; const fmt = (((_d = lines.find((l) => l.startsWith("FORMAT:"))) == null ? void 0 : _d.slice(7)) || "").toUpperCase(); const kdfLine = (_e = lines.find((l) => l.startsWith("KDF:"))) == null ? void 0 : _e.slice(4); if (!salt || !iv || !data) { if (this.settings.showNotice) new import_obsidian9.Notice("Invalid encrypted container"); return; } let finalKdfOpts = void 0; if (kdfLine) { const segs = kdfLine.split(":"); if (segs[0].toUpperCase() === "ARGON2ID" && segs.length >= 5) { finalKdfOpts = { type: "Argon2id", argon2MemoryKB: parseInt(segs[1], 10) || 65536, argon2Iterations: parseInt(segs[2], 10) || 3, argon2Parallelism: parseInt(segs[3], 10) || 1, argon2HashLen: parseInt(segs[4], 10) || 32 }; } else if (segs[0].toUpperCase() === "PBKDF2") { finalKdfOpts = { type: "PBKDF2", pbkdf2Iterations: parseInt(segs[1], 10) || 6e5 }; } } else if (dataObj.kdf) { if (dataObj.kdf === "Argon2id") { finalKdfOpts = { type: "Argon2id", argon2MemoryKB: dataObj.argon2MemoryKB || 65536, argon2Iterations: dataObj.argon2Iterations || 3, argon2Parallelism: dataObj.argon2Parallelism || 1, argon2HashLen: dataObj.argon2HashLen || 32 }; } else { finalKdfOpts = { type: "PBKDF2", pbkdf2Iterations: dataObj.iterations || 6e5 }; } } let arrayBuffer; if (fmt === "BIN") { const { decryptBytesWithPassword: decryptBytesWithPassword2 } = await Promise.resolve().then(() => (init_aesWithPassword(), aesWithPassword_exports)); const bytes = await decryptBytesWithPassword2(password2, salt, iv, data, this.keyCache || void 0, finalKdfOpts); arrayBuffer = bytes.buffer.slice(bytes.byteOffset, bytes.byteOffset + bytes.byteLength); } else { const base64 = await FileDataHelper.decrypt(dataObj, password2, this.keyCache || void 0, finalKdfOpts); if (!base64) { if (this.settings.showNotice) new import_obsidian9.Notice("Decryption failed: Password may be incorrect"); return; } const buf = Buffer.from(base64, "base64"); arrayBuffer = buf.buffer.slice(buf.byteOffset, buf.byteOffset + buf.byteLength); } const basePath2 = currentFile.path.replace(/\.peccirian$/, "").replace(/\.eccirian$/, ""); const originalPath = basePath2.toLowerCase().endsWith(".md") ? basePath2 : `${basePath2}.md`; const existing = this.app.vault.getAbstractFileByPath(originalPath); if (existing instanceof import_obsidian9.TFile) { const shouldOverwrite = await new Promise((resolve) => { const modal = new import_obsidian9.Modal(this.app); modal.titleEl.setText(this.i18n.dialogFileAlreadyExists || "File Already Exists"); const desc = modal.contentEl.createDiv(); const filename = originalPath.split("/").pop() || originalPath; desc.createEl("p", { text: (this.i18n.dialogFileAlreadyExistsDesc1 || 'A file named "{filename}" already exists.').replace("{filename}", filename) }); desc.createEl("p", { text: this.i18n.dialogFileAlreadyExistsDesc2 || "Decrypting will overwrite the existing file.", cls: "mod-warning" }); desc.createEl("p", { text: this.i18n.dialogFileAlreadyExistsDesc3 || "Do you want to continue?" }); const buttonContainer = modal.contentEl.createDiv({ cls: "modal-button-container" }); buttonContainer.style.display = "flex"; buttonContainer.style.justifyContent = "flex-end"; buttonContainer.style.gap = "8px"; buttonContainer.style.marginTop = "16px"; const cancelBtn = buttonContainer.createEl("button", { text: this.i18n.buttonCancel || "Cancel" }); cancelBtn.addEventListener("click", () => { modal.close(); resolve(false); }); const overwriteBtn = buttonContainer.createEl("button", { text: this.i18n.buttonContinue || "Continue", cls: "mod-warning" }); overwriteBtn.addEventListener("click", () => { modal.close(); resolve(true); }); modal.open(); }); if (!shouldOverwrite) { return; } await this.app.vault.delete(existing); } if (existing instanceof import_obsidian9.TFile) { await this.app.vault.modifyBinary(existing, arrayBuffer); } else { await this.app.vault.createBinary(originalPath, arrayBuffer); } view.setSavingEnabled(false); await this.app.vault.delete(currentFile); const leaf2 = this.app.workspace.getLeaf(); const restored = this.app.vault.getAbstractFileByPath(originalPath); if (restored instanceof import_obsidian9.TFile) await leaf2.openFile(restored); if (this.settings.showNotice) new import_obsidian9.Notice("Permanent encryption removed. Restored original file."); return; } } } catch (e) { } const password = view.getDecryptedPassword(); if (this.settings.encryptAttachments && password) { const contentWithEncryptedLinks = AttachmentHelper.updateAttachmentLinks( content, "encrypt", "permanent" ); const attachmentLinks = AttachmentHelper.extractAttachmentLinks(contentWithEncryptedLinks); await Promise.all( attachmentLinks.map(async (link) => { let encryptedAttachment = AttachmentHelper.resolveAttachmentPath( this.app.vault, currentFile.path, link ); if (encryptedAttachment) { try { await AttachmentHelper.decryptBinaryFile( this.app.vault, encryptedAttachment, password ); } catch (error) { console.error(`Failed to decrypt attachment ${link}:`, error); } } }) ); } content = AttachmentHelper.updateAttachmentLinks( content, "decrypt", "permanent" ); const basePath = currentFile.path.replace(/\.(peccirian|eccirian)$/i, ""); const mdPath = basePath.toLowerCase().endsWith(".md") ? basePath : `${basePath}.md`; const existingMdFile = this.app.vault.getAbstractFileByPath(mdPath); if (existingMdFile && existingMdFile instanceof import_obsidian9.TFile) { const shouldOverwrite = await new Promise((resolve) => { const modal = new import_obsidian9.Modal(this.app); modal.titleEl.setText(this.i18n.dialogFileAlreadyExists || "File Already Exists"); const desc = modal.contentEl.createDiv(); const filename = existingMdFile.basename; desc.createEl("p", { text: (this.i18n.dialogFileAlreadyExistsDesc1 || 'A file named "{filename}" already exists.').replace("{filename}", filename) }); desc.createEl("p", { text: this.i18n.dialogFileAlreadyExistsDesc2 || "Decrypting will overwrite the existing file.", cls: "mod-warning" }); desc.createEl("p", { text: this.i18n.dialogFileAlreadyExistsDesc3 || "Do you want to continue?" }); const buttonContainer = modal.contentEl.createDiv({ cls: "modal-button-container" }); buttonContainer.style.display = "flex"; buttonContainer.style.justifyContent = "flex-end"; buttonContainer.style.gap = "8px"; buttonContainer.style.marginTop = "16px"; const cancelBtn = buttonContainer.createEl("button", { text: this.i18n.buttonCancel || "Cancel" }); cancelBtn.addEventListener("click", () => { modal.close(); resolve(false); }); const overwriteBtn = buttonContainer.createEl("button", { text: this.i18n.buttonContinue || "Continue", cls: "mod-warning" }); overwriteBtn.addEventListener("click", () => { modal.close(); resolve(true); }); modal.open(); }); if (!shouldOverwrite) { return; } await this.app.vault.delete(existingMdFile); } await this.app.vault.rename(currentFile, mdPath); const mdFileAbs = this.app.vault.getAbstractFileByPath(mdPath); if (!(mdFileAbs instanceof import_obsidian9.TFile)) { throw new Error(`Failed to locate restored file at ${mdPath}`); } await this.app.vault.modify(mdFileAbs, content); view.setSavingEnabled(false); await view.detach(); const leaf = this.app.workspace.getLeaf(); await leaf.openFile(mdFileAbs); if (this.settings.showNotice) { new import_obsidian9.Notice("Permanent encryption removed. File is now a normal markdown file."); } } catch (error) { console.error("Error converting file:", error); if (this.settings.showNotice) { new import_obsidian9.Notice("Conversion failed: " + (error instanceof Error ? error.message : String(error))); } } finally { this.isConvertingToMarkdown = false; } } /** * Get currently selected folder from file explorer */ getSelectedFolder() { const fileExplorer = this.app.workspace.getLeavesOfType("file-explorer")[0]; if (fileExplorer) { const explorerView = fileExplorer.view; if (explorerView) { const fileItems = explorerView.fileItems; if (fileItems) { for (const [path, item] of Object.entries(fileItems)) { if (item.selfEl && item.selfEl.hasClass("is-active")) { const file = this.app.vault.getAbstractFileByPath(path); if (file instanceof import_obsidian9.TFolder) { return file; } } } } } } return null; } /** * Handle encryption/decryption for the active file * Used by both ribbon icon and command palette */ async handleEncryptDecrypt(showHintNotice = false) { const activeFile = this.app.workspace.getActiveFile(); if (!activeFile) { if (this.settings.showNotice) new import_obsidian9.Notice("Please open a file first"); return; } const activeView = this.app.workspace.getActiveViewOfType(PEccidianView); if (activeView && activeView.file === activeFile && activeView.isDecrypted()) { if (this.settings.showNotice) new import_obsidian9.Notice("This file is already decrypted"); return; } if (activeFile.extension === "peccirian") { if (activeView) { const unlockBtn = activeView.contentEl.querySelector(".peccirian-unlock-button"); if (unlockBtn) { unlockBtn.click(); } return; } } const buildKdfOptsFromSettings = () => { if (this.settings.kdfType === "Argon2id") { return { type: "Argon2id", argon2MemoryKB: this.settings.argon2MemoryKB, argon2Iterations: this.settings.argon2Iterations, argon2Parallelism: this.settings.argon2Parallelism, argon2HashLen: this.settings.argon2HashLen }; } return { type: "PBKDF2", pbkdf2Iterations: this.settings.pbkdf2Iterations }; }; const kdfOpts = buildKdfOptsFromSettings(); if (activeFile.extension !== "md" && activeFile.extension !== "eccirian" && activeFile.extension !== "peccirian") { new PasswordModal( this.app, async (password, encryptionMethod, hint, encryptionMode) => { const selectedMode = encryptionMode || this.settings.defaultEncryptionMode; try { const bytes = await this.app.vault.readBinary(activeFile); const { encryptBytesWithPassword: encryptBytesWithPassword2 } = await Promise.resolve().then(() => (init_aesWithPassword(), aesWithPassword_exports)); const { salt, iv, data } = await encryptBytesWithPassword2(password, bytes, this.keyCache || void 0, kdfOpts); let kdfLine = ""; if (kdfOpts.type === "Argon2id") { const mem = kdfOpts.argon2MemoryKB || 65536; const iters = kdfOpts.argon2Iterations || 3; const para = kdfOpts.argon2Parallelism || 1; const len = kdfOpts.argon2HashLen || 32; kdfLine = `KDF:Argon2id:${mem}:${iters}:${para}:${len}`; } else { kdfLine = `KDF:PBKDF2:${kdfOpts.pbkdf2Iterations || 6e5}`; } const encodedData = `SALT:${salt} IV:${iv} DATA:${data} FORMAT:BIN ${kdfLine}`; const container = { version: FileDataHelper.DEFAULT_VERSION, encodedData, type: selectedMode, originalExt: activeFile.extension, algorithm: "AES", kdf: kdfOpts.type === "PBKDF2" ? "PBKDF2" : "Argon2id", iterations: kdfOpts.type === "PBKDF2" ? kdfOpts.pbkdf2Iterations || 6e5 : void 0, argon2MemoryKB: kdfOpts.type === "Argon2id" ? kdfOpts.argon2MemoryKB || 65536 : void 0, argon2Iterations: kdfOpts.type === "Argon2id" ? kdfOpts.argon2Iterations || 3 : void 0, argon2Parallelism: kdfOpts.type === "Argon2id" ? kdfOpts.argon2Parallelism || 1 : void 0, argon2HashLen: kdfOpts.type === "Argon2id" ? kdfOpts.argon2HashLen || 32 : void 0 }; const ext = selectedMode === "permanent" ? "peccirian" : "eccirian"; const encPath = `${activeFile.path}.${ext}`; await this.app.vault.create(encPath, JSON.stringify(container, null, 2)); await this.app.vault.delete(activeFile); if (this.settings.showNotice) new import_obsidian9.Notice("File encrypted"); const encFile = this.app.vault.getAbstractFileByPath(encPath); if (encFile instanceof import_obsidian9.TFile) { const leaf = this.app.workspace.getLeaf(); await leaf.openFile(encFile); } } catch (error) { console.error("Binary encryption failed", error); if (this.settings.showNotice) new import_obsidian9.Notice("Encryption failed"); } }, () => { }, this.settings.defaultEncryptionMode, false, this.settings.requirePasswordConfirmation, this.settings.showHint, this.settings.encryptionMethod, this, true, void 0 ).open(); return; } let fileContent; const mdView = this.app.workspace.getActiveViewOfType(import_obsidian9.MarkdownView); if (mdView && mdView.file === activeFile && mdView.editor) { fileContent = mdView.editor.getValue(); } else { fileContent = await this.app.vault.read(activeFile); } const isEncryptedWithENC = fileContent.includes("%%ENC"); const isEncryptedWithJSON = fileContent.trim().startsWith("{") && fileContent.includes("encodedData"); if (isEncryptedWithENC || isEncryptedWithJSON) { const hintMatch = fileContent.match(/HINT:(.+)/); const hint = hintMatch ? hintMatch[1] : void 0; if (hint && showHintNotice && this.settings.showNotice) { new import_obsidian9.Notice(`Password Hint: ${hint}`); } new PasswordModal( this.app, async (password, encryptionMethod, hintInput, encryptionMode) => { try { if (isEncryptedWithENC) { const saltMatch = fileContent.match(/SALT:(.+)/); const ivMatch = fileContent.match(/IV:(.+)/); const dataMatch = fileContent.match(/DATA:(.+)/); const publicKeyMatch = fileContent.match(/PUBLIC_KEY:(.+)/); const ephemeralPublicKeyMatch = fileContent.match(/EPHEMERAL_PUBLIC_KEY:(.+)/); if (saltMatch && ivMatch && dataMatch) { const typeMatch = fileContent.match(/TYPE:(.+)/); const encryptionType = typeMatch ? typeMatch[1] : "temporary"; const originalExtMatch = fileContent.match(/ORIGINAL_EXT:(.+)/); const hintMatchInEnc = fileContent.match(/HINT:(.+)/); const publicKey = publicKeyMatch ? publicKeyMatch[1] : void 0; const ephemeral = ephemeralPublicKeyMatch ? ephemeralPublicKeyMatch[1] : void 0; const encodedLines = [ `SALT:${saltMatch[1]}`, `IV:${ivMatch[1]}`, `DATA:${dataMatch[1]}`, ...publicKey ? [`PUBLIC_KEY:${publicKey}`] : [], ...ephemeral ? [`EPHEMERAL_PUBLIC_KEY:${ephemeral}`] : [] ]; const fileData = { version: FileDataHelper.DEFAULT_VERSION, encodedData: encodedLines.join("\n"), type: encryptionType, originalExt: originalExtMatch ? originalExtMatch[1] : "md", hint: hintMatchInEnc ? hintMatchInEnc[1] : void 0, algorithm: publicKey ? "ECC" : "AES" }; const decrypted = await FileDataHelper.decrypt(fileData, password, this.keyCache || void 0, kdfOpts); if (!decrypted) { if (this.settings.showNotice) { new import_obsidian9.Notice("Decryption failed: Password may be incorrect"); } return; } let processedText = decrypted.trim() === "$\xB7-\xB7$" ? "" : decrypted; const encryptionTypeStr = encryptionType; if (this.settings.encryptAttachments) { const attachmentLinks = AttachmentHelper.extractAttachmentLinks(processedText); await Promise.all( attachmentLinks.map(async (link) => { let encryptedAttachment = AttachmentHelper.resolveAttachmentPath( this.app.vault, activeFile.path, link ); if (encryptedAttachment) { try { await AttachmentHelper.decryptBinaryFile( this.app.vault, encryptedAttachment, password ); } catch (error) { console.error(`Failed to decrypt attachment ${link}:`, error); } } else { console.warn(`Attachment not found: ${link}`); } }) ); processedText = AttachmentHelper.updateAttachmentLinks( processedText, "decrypt", encryptionTypeStr ); } const mdFile = await changeFileExtension(this.app.vault, activeFile, "md"); await this.app.vault.modify(mdFile, processedText); if (this.settings.showNotice) { new import_obsidian9.Notice("File decrypted"); } const leaf = this.app.workspace.getLeaf(); await leaf.openFile(mdFile); } else { if (this.settings.showNotice) { new import_obsidian9.Notice("Decryption failed: Invalid file format"); } } } else if (isEncryptedWithJSON) { try { const encryptedData = JSON.parse(fileContent); if (!encryptedData || !encryptedData.encodedData) { if (this.settings.showNotice) { new import_obsidian9.Notice("Decryption failed: Invalid JSON format"); } return; } const decryptedText = await FileDataHelper.decrypt(encryptedData, password, this.keyCache || void 0, kdfOpts); if (!decryptedText) { if (this.settings.showNotice) { new import_obsidian9.Notice("Decryption failed: Password may be incorrect"); } return; } const processedText = decryptedText.trim() === "$\xB7-\xB7$" ? "" : decryptedText; await this.app.vault.modify(activeFile, processedText); const mdFile = await changeFileExtension(this.app.vault, activeFile, "md"); if (this.settings.showNotice) { new import_obsidian9.Notice("File decrypted"); } const leaf = this.app.workspace.getLeaf(); await leaf.openFile(mdFile); } catch (error) { if (this.settings.showNotice) { new import_obsidian9.Notice("Decryption failed: " + (error instanceof Error ? error.message : "Unknown error")); } } } } catch (err) { if (err instanceof Error && err.message.includes("Error Password")) { if (this.settings.showNotice) { new import_obsidian9.Notice("Operation failed: Password may be incorrect"); } } } }, () => { }, this.settings.defaultEncryptionMode, true, this.settings.requirePasswordConfirmation, this.settings.showHint, this.settings.encryptionMethod, this, true, hint ).open(); } else { new PasswordModal( this.app, async (password, encryptionMethod, hint, encryptionMode) => { try { let contentToEncrypt = fileContent || "$\xB7-\xB7$"; const selectedMode = encryptionMode || this.settings.defaultEncryptionMode; if (this.settings.encryptAttachments) { const attachmentLinks = AttachmentHelper.extractAttachmentLinks(contentToEncrypt); await Promise.all( attachmentLinks.map(async (link) => { const attachmentFile = AttachmentHelper.resolveAttachmentPath( this.app.vault, activeFile.path, link ); if (attachmentFile) { try { await AttachmentHelper.encryptBinaryFile( this.app.vault, attachmentFile, password, selectedMode, kdfOpts ); } catch (error) { console.error(`Failed to encrypt attachment ${link}:`, error); } } }) ); contentToEncrypt = AttachmentHelper.updateAttachmentLinks( contentToEncrypt, "encrypt", selectedMode ); } if (encryptionMethod === "AES") { const { salt, iv, data } = await encryptWithPassword(password, contentToEncrypt, this.keyCache || void 0, kdfOpts); let kdfLine = ""; if (kdfOpts.type === "Argon2id") { const mem = kdfOpts.argon2MemoryKB || 65536; const iters = kdfOpts.argon2Iterations || 3; const para = kdfOpts.argon2Parallelism || 1; const len = kdfOpts.argon2HashLen || 32; kdfLine = ` KDF:Argon2id:${mem}:${iters}:${para}:${len}`; } else { kdfLine = ` KDF:PBKDF2:${kdfOpts.pbkdf2Iterations || 6e5}`; } const encrypted = `%%ENC TYPE:${selectedMode} ORIGINAL_EXT:${activeFile.extension} SALT:${salt} IV:${iv} DATA:${data}${kdfLine}${hint ? ` HINT:${hint}` : ""}`; const encFile = await changeFileExtension(this.app.vault, activeFile, this.settings.fileExtension); await this.app.vault.modify(encFile, encrypted); if (this.settings.showNotice) new import_obsidian9.Notice("File encrypted"); const leaf = this.app.workspace.getLeaf(); await leaf.openFile(encFile); } else { const { salt, iv, data, publicKey, ephemeralPublicKey } = await encryptWithPassword2(password, contentToEncrypt, this.keyCache || void 0, kdfOpts); let kdfLine = ""; if (kdfOpts.type === "Argon2id") { const mem = kdfOpts.argon2MemoryKB || 65536; const iters = kdfOpts.argon2Iterations || 3; const para = kdfOpts.argon2Parallelism || 1; const len = kdfOpts.argon2HashLen || 32; kdfLine = ` KDF:Argon2id:${mem}:${iters}:${para}:${len}`; } else { kdfLine = ` KDF:PBKDF2:${kdfOpts.pbkdf2Iterations || 6e5}`; } const encrypted = `%%ENC TYPE:${selectedMode} ORIGINAL_EXT:${activeFile.extension} SALT:${salt} IV:${iv} DATA:${data} PUBLIC_KEY:${publicKey} EPHEMERAL_PUBLIC_KEY:${ephemeralPublicKey}${kdfLine}${hint ? ` HINT:${hint}` : ""}`; const encFile = await changeFileExtension(this.app.vault, activeFile, this.settings.fileExtension); await this.app.vault.modify(encFile, encrypted); if (this.settings.showNotice) { new import_obsidian9.Notice("File encrypted"); } const leaf = this.app.workspace.getLeaf(); await leaf.openFile(encFile); } } catch (err) { if (err instanceof Error && err.message.includes("Error Password")) { if (this.settings.showNotice) { new import_obsidian9.Notice("Operation failed: Password may be incorrect"); } } } }, () => { }, this.settings.defaultEncryptionMode, false, this.settings.requirePasswordConfirmation, this.settings.showHint, this.settings.encryptionMethod, this, true, void 0 ).open(); } } /** * Encrypt a folder * Note: Folder encryption only supports temporary mode. * Permanent mode is not supported for folders due to memory and complexity constraints. */ async encryptFolder(folder) { const kdfOpts = this.settings.kdfType === "Argon2id" ? { type: "Argon2id", argon2MemoryKB: this.settings.argon2MemoryKB, argon2Iterations: this.settings.argon2Iterations, argon2Parallelism: this.settings.argon2Parallelism, argon2HashLen: this.settings.argon2HashLen } : { type: "PBKDF2", pbkdf2Iterations: this.settings.pbkdf2Iterations }; new PasswordModal( this.app, async (password, encryptionMethod, hint, encryptionMode) => { try { const folderContent = await FolderHelper.packFolder(this.app.vault, folder); const selectedMode = "temporary"; let kdfLine = ""; if (kdfOpts.type === "Argon2id") { const mem = kdfOpts.argon2MemoryKB || 65536; const iters = kdfOpts.argon2Iterations || 3; const para = kdfOpts.argon2Parallelism || 1; const len = kdfOpts.argon2HashLen || 32; kdfLine = ` KDF:Argon2id:${mem}:${iters}:${para}:${len}`; } else { kdfLine = ` KDF:PBKDF2:${kdfOpts.pbkdf2Iterations || 6e5}`; } if (encryptionMethod === "AES") { const { salt, iv, data } = await encryptWithPassword(password, folderContent, this.keyCache || void 0, kdfOpts); const encrypted = `%%ENC TYPE:${selectedMode} IS_FOLDER:true ORIGINAL_PATH:${folder.path} SALT:${salt} IV:${iv} DATA:${data}${kdfLine}${hint ? ` HINT:${hint}` : ""}`; let encryptedFileName = `${folder.path}.${this.settings.fileExtension}`; let n = 1; while (this.app.vault.getAbstractFileByPath(encryptedFileName)) { const basePath = `${folder.path}.${this.settings.fileExtension}`; encryptedFileName = `${basePath.replace(`.${this.settings.fileExtension}$`, "")} (${n}).${this.settings.fileExtension}`; n++; } await this.app.vault.create(encryptedFileName, encrypted); await this.app.vault.delete(folder, true); if (this.settings.showNotice) { new import_obsidian9.Notice(this.i18n.messageFolderEncrypted); } const encFile = this.app.vault.getAbstractFileByPath(encryptedFileName); if (encFile instanceof import_obsidian9.TFile) { const leaf = this.app.workspace.getLeaf(); await leaf.openFile(encFile); } } else { const { salt, iv, data, publicKey, ephemeralPublicKey } = await encryptWithPassword2(password, folderContent, this.keyCache || void 0, kdfOpts); const encrypted = `%%ENC TYPE:${selectedMode} IS_FOLDER:true ORIGINAL_PATH:${folder.path} SALT:${salt} IV:${iv} DATA:${data} PUBLIC_KEY:${publicKey} EPHEMERAL_PUBLIC_KEY:${ephemeralPublicKey}${kdfLine}${hint ? ` HINT:${hint}` : ""}`; let encryptedFileName = `${folder.path}.${this.settings.fileExtension}`; let n = 1; while (this.app.vault.getAbstractFileByPath(encryptedFileName)) { const basePath = `${folder.path}.${this.settings.fileExtension}`; encryptedFileName = `${basePath.replace(`.${this.settings.fileExtension}$`, "")} (${n}).${this.settings.fileExtension}`; n++; } await this.app.vault.create(encryptedFileName, encrypted); await this.app.vault.delete(folder, true); if (this.settings.showNotice) { new import_obsidian9.Notice(this.i18n.messageFolderEncrypted); } const encFile = this.app.vault.getAbstractFileByPath(encryptedFileName); if (encFile instanceof import_obsidian9.TFile) { const leaf = this.app.workspace.getLeaf(); await leaf.openFile(encFile, { active: true }); } } } catch (error) { console.error("Error encrypting folder:", error); if (this.settings.showNotice) new import_obsidian9.Notice("Folder encryption failed: " + (error instanceof Error ? error.message : "Unknown error")); } }, () => { }, "temporary", // Force temporary mode for folders false, this.settings.requirePasswordConfirmation, this.settings.showHint, this.settings.encryptionMethod, this, false, // Hide mode selection for folder encryption void 0 // No existing hint ).open(); } }; /* nosourcemap */