diff --git a/src/DecryptPreviewModal.ts b/src/DecryptPreviewModal.ts index d1e135e..d8ae696 100644 --- a/src/DecryptPreviewModal.ts +++ b/src/DecryptPreviewModal.ts @@ -102,7 +102,7 @@ export class DecryptPreviewModal extends Modal { } } // Send Decrypt command - let decryptedTextResult: GpgResult = await gpgDecrypt(this.plugin.settings, this.encryptedMessage, passphrase); + let decryptedTextResult: GpgResult = await gpgDecrypt(this.plugin, this.plugin.settings, this.encryptedMessage, passphrase); // Check if result contains data if (decryptedTextResult.result) { // Cache the passphrase after a successful decrypt (openpgpjs only) diff --git a/src/EncryptModal.ts b/src/EncryptModal.ts index c7be719..505a1fd 100644 --- a/src/EncryptModal.ts +++ b/src/EncryptModal.ts @@ -65,7 +65,7 @@ export class EncryptModal extends Modal { return; } // Show which key will be used - let openpgpKeys = await getListPublicKey(this.plugin.settings); + let openpgpKeys = await getListPublicKey(this.plugin, this.plugin.settings); if (openpgpKeys.length > 0) { contentEl.createEl("p", { text: "Encrypting with key: " + openpgpKeys[0].userID + " (" + openpgpKeys[0].keyID + ")" }); } @@ -86,7 +86,7 @@ export class EncryptModal extends Modal { // Help text is created to select GPG keys contentEl.createEl("p", { text: "Select which Public GPG key(s) you want to be able to decrypt the text:" }); // Get list of GPG public Keys - let gpgPublicKeys: { keyID: string; userID: string }[] = await getListPublicKey(this.plugin.settings); + let gpgPublicKeys: { keyID: string; userID: string }[] = await getListPublicKey(this.plugin, this.plugin.settings); // Sign key name by ID let gpgSignName: string = ""; // Iterate over each public key @@ -166,7 +166,7 @@ export class EncryptModal extends Modal { // Check if EncryptMode is Inline if (this.encryptMode == EncryptModalMode.INLINE) { // Send Encrypt command with list of GPG public keys IDs - let encryptedTextResult: GpgResult = await gpgEncrypt(this.plugin.settings, this.editor.getSelection(), this.listPublicKeyToEncrypt, this.plugin.settings.pgpSignPublicKeyId, passphrase); + let encryptedTextResult: GpgResult = await gpgEncrypt(this.plugin, this.plugin.settings, this.editor.getSelection(), this.listPublicKeyToEncrypt, this.plugin.settings.pgpSignPublicKeyId, passphrase); // Check if any error exists if (encryptedTextResult.error) { // Show the error message @@ -187,7 +187,7 @@ export class EncryptModal extends Modal { // Check if EncryptMode is Document else if (this.encryptMode == EncryptModalMode.DOCUMENT) { // Send Encrypt command with list of GPG public keys IDs - let encryptedTextResult: GpgResult = await gpgEncrypt(this.plugin.settings, this.editor.getValue(), this.listPublicKeyToEncrypt, this.plugin.settings.pgpSignPublicKeyId, passphrase); + let encryptedTextResult: GpgResult = await gpgEncrypt(this.plugin, this.plugin.settings, this.editor.getValue(), this.listPublicKeyToEncrypt, this.plugin.settings.pgpSignPublicKeyId, passphrase); // Check if result contains data if (encryptedTextResult.result) { // Cache the passphrase after a successful sign+encrypt diff --git a/src/Settings.ts b/src/Settings.ts index 7446d62..29ca628 100644 --- a/src/Settings.ts +++ b/src/Settings.ts @@ -2,7 +2,7 @@ import GpgEncryptPlugin from "main"; // Settings object export interface GpgEncryptSettings { - pgpExecPath: string; + pgpExecPaths: string[]; pgpSignPublicKeyId: string pgpAlwaysTrust: boolean, pgpDefaultEncryptKeys: Array, @@ -20,7 +20,7 @@ export interface GpgEncryptSettings { // Default settings values const DEFAULT_SETTINGS: GpgEncryptSettings = { - pgpExecPath: getDefaultExecPath(), + pgpExecPaths: getDefaultExecPaths(), pgpSignPublicKeyId: "0", pgpAlwaysTrust: false, pgpDefaultEncryptKeys: [], @@ -49,34 +49,78 @@ export class Settings { // Load Settings from Plugin Data async loadSettings() { - this.plugin.settings = Object.assign({}, DEFAULT_SETTINGS, await this.plugin.loadData()); + const loadedData = await this.plugin.loadData(); + this.plugin.settings = Object.assign({}, DEFAULT_SETTINGS, loadedData); + + // Migration: convert old single pgpExecPath to pgpExecPaths array + if (loadedData && 'pgpExecPath' in loadedData && typeof loadedData.pgpExecPath === 'string') { + if (loadedData.pgpExecPath) { + // If old path exists, put it first in array, then add defaults + this.plugin.settings.pgpExecPaths = [loadedData.pgpExecPath, ...getDefaultExecPaths().filter(p => p !== loadedData.pgpExecPath)]; + } else { + // If old path was empty, just use defaults + this.plugin.settings.pgpExecPaths = getDefaultExecPaths(); + } + // Save migrated settings + await this.saveSettings(); + } } // Save Settings to Plugin Data async saveSettings() { await this.plugin.saveData(this.plugin.settings); } + + // Get the first working GPG executable path from the list + async getWorkingGpgPath(): Promise { + // Lazy require so it works on mobile + if (typeof process === "undefined" || !process.platform) { + return null; + } + + const fs = require('fs'); + + // Try each path in order + for (const path of this.plugin.settings.pgpExecPaths) { + if (!path) continue; + + try { + // Check if file exists and is a gpg executable + if (fs.existsSync(path) && + (path.endsWith("gpg") || path.endsWith("gpg.exe") || + path.endsWith("gpg2") || path.endsWith("gpg2.exe"))) { + return path; + } + } catch (ex) { + // Continue to next path + continue; + } + } + + return null; + } } -// Get Default Exec Path in base on platform name -function getDefaultExecPath(): string { +// Get Default Exec Paths for all platforms +function getDefaultExecPaths(): string[] { // On mobile there is no Node process; return empty (native GPG is unavailable there) if (typeof process === "undefined" || !process.platform) { - return ""; - } - // Check platform name - switch (process.platform) { - // In case of Windows OS - case "win32": - return "C:\\Program Files (x86)\\GnuPG\\bin\\gpg.exe"; - // In case of MacOS - case "darwin": - return "/usr/local/bin/gpg"; - // In case of Linux - case "linux": - return "/usr/bin/gpg"; - // In default value return empty - default: - return ""; + return []; } + // Return common paths for all platforms so config works cross-platform + return [ + // Windows paths + "C:\\Program Files (x86)\\GnuPG\\bin\\gpg.exe", + "C:\\Program Files\\GnuPG\\bin\\gpg.exe", + // macOS paths + "/usr/local/bin/gpg", + "/opt/homebrew/bin/gpg", + "/usr/local/MacGPG2/bin/gpg", + "/usr/local/MacGPG2/bin/gpg2", + // Linux paths + "/usr/bin/gpg", + "/usr/bin/gpg2", + "/bin/gpg", + "/bin/gpg2" + ]; } diff --git a/src/SettingsTab.ts b/src/SettingsTab.ts index b2cda34..c6cee5c 100644 --- a/src/SettingsTab.ts +++ b/src/SettingsTab.ts @@ -1,4 +1,4 @@ -import spawnGPG, { GpgResult, getListPublicKey } from 'src/gpg'; +import spawnGPG, { GpgResult, getListPublicKey, clearWorkingPathCache } from 'src/gpg'; import { App, DropdownComponent, PluginSettingTab, Setting } from 'obsidian'; import GpgEncryptPlugin from 'main'; import { Settings } from './Settings'; @@ -24,7 +24,8 @@ export class GpgSettingsTab extends PluginSettingTab { this.plugin = plugin; } // List of settings objetcts - private gpgExecPath: Setting; + private gpgExecPaths: Setting; + private gpgExecPathsList: HTMLDivElement; private gpgAditionalCommands: Setting; private gpgAditionalCommandsBefore: Setting; private gpgAditionalCommandsAfter: Setting; @@ -74,24 +75,25 @@ export class GpgSettingsTab extends PluginSettingTab { // ---------- OpenPGP.js settings ---------- // ---------- GPG executable setting ---------- - this.gpgExecPath = new Setting(containerEl) - .setName('GPG executable') - .setDesc('Path to GPG executable') - .addText(text => text - .setPlaceholder('gpg') - .setValue(this.plugin.settings.pgpExecPath) - .onChange(async (value: string) => { - await this.checkGpgPath(value); - })); + this.gpgExecPaths = new Setting(containerEl) + .setName('GPG executable paths') + .setDesc('List of GPG executable paths to try (first working path will be used)'); + // Div to show list of paths + this.gpgExecPathsList = this.gpgExecPaths.descEl.createDiv(); + this.gpgExecPathsList.className = "gpg-paths-list"; + // Render the paths list + this.renderGpgPathsList(); // Div to show GPG Path status - this.gpgExecPathStatus = this.gpgExecPath.descEl.createDiv(); + this.gpgExecPathStatus = containerEl.createDiv(); + this.gpgExecPathStatus.style.marginTop = "10px"; + this.gpgExecPathStatus.style.marginBottom = "10px"; // ---------- GPG executable setting ---------- // ---------- List of GPG Public Keys ---------- this.gpgPublicKeysList = new Setting(containerEl) .setName("Public keys") - // Run by first time checkGpgPath function - this.checkGpgPath(this.plugin.settings.pgpExecPath); + // Run by first time checkGpgPaths function + this.checkGpgPaths(); // ---------- List of GPG Public Keys ---------- // ---------- Always Trust ---------- @@ -161,41 +163,80 @@ export class GpgSettingsTab extends PluginSettingTab { // ---------- Aditional Commands ---------- } - // Function to check if GPG Path exits - private async checkGpgPath(value: string) { + // Function to render GPG paths list with add/remove functionality + private renderGpgPathsList() { + // Clear the list + this.gpgExecPathsList.empty(); + + // Iterate over each path + this.plugin.settings.pgpExecPaths.forEach((path, index) => { + const pathDiv = this.gpgExecPathsList.createDiv(); + pathDiv.className = "gpg-path-item"; + + const pathSetting = new Setting(pathDiv) + .addText(text => text + .setPlaceholder('/usr/bin/gpg or C:\\Program Files\\GnuPG\\bin\\gpg.exe') + .setValue(path) + .onChange(async (value: string) => { + this.plugin.settings.pgpExecPaths[index] = value; + await new Settings(this.plugin).saveSettings(); + clearWorkingPathCache(); + this.checkGpgPaths(); + })) + .addButton(button => button + .setButtonText("Remove") + .setWarning() + .onClick(async () => { + this.plugin.settings.pgpExecPaths.splice(index, 1); + await new Settings(this.plugin).saveSettings(); + clearWorkingPathCache(); + this.renderGpgPathsList(); + this.checkGpgPaths(); + })); + }); + + // Add button to add new path + new Setting(this.gpgExecPathsList) + .addButton(button => button + .setButtonText("Add path") + .setCta() + .onClick(async () => { + this.plugin.settings.pgpExecPaths.push(""); + await new Settings(this.plugin).saveSettings(); + this.renderGpgPathsList(); + })); + } + + // Function to check all GPG paths and find working one + private async checkGpgPaths() { // Check if pgp Library is openpgpjs if (this.plugin.settings.pgpLibrary == "openpgpjs") // Abort the process return; - // Lazy require so the settings tab still loads on mobile, where fs is absent - const fs = require('fs'); - // Set settig variable pgpExecPath with new value - this.plugin.settings.pgpExecPath = value; - // Save settings with change - await new Settings(this.plugin).saveSettings(); + // Hide list of public GPG Keys this.gpgPublicKeysList.settingEl.hide(); // Start with Loading status while real one is calculated this.changeGpgPathStatus(GpgExecPathStatus.LOADING); + + // Get working path + const workingPath = await new Settings(this.plugin).getWorkingGpgPath(); + + if (!workingPath) { + this.changeGpgPathStatus(GpgExecPathStatus.FILE_NOT_FOUND); + return; + } + + // Check if path ends with any gpg executable + if (!workingPath.endsWith("gpg") && !workingPath.endsWith("gpg.exe") && !workingPath.endsWith("gpg2") && !workingPath.endsWith("gpg2.exe")){ + this.changeGpgPathStatus(GpgExecPathStatus.NO_GPG_IN_PATH); + return; + } + // Start a try in case of exception - try - { - // Check if file doesn not exist - if (!fs.existsSync(value)) { - // Change the status to File Not Found - this.changeGpgPathStatus(GpgExecPathStatus.FILE_NOT_FOUND); - // End this check process - return; - } - // Check if path ends with any gpg executable - if (!value.endsWith("gpg") && !value.endsWith("gpg.exe") && !value.endsWith("gpg2") && !value.endsWith("gpg2.exe")){ - // Change the status to No GPG In Path - this.changeGpgPathStatus(GpgExecPathStatus.NO_GPG_IN_PATH); - // End this check process - return; - } + try { // Check GPG version in console - let gpgResult: GpgResult = await spawnGPG(this.plugin.settings, null, ["--logger-fd", "1", "--version"]); + let gpgResult: GpgResult = await spawnGPG(this.plugin, this.plugin.settings, null, ["--logger-fd", "1", "--version"]); // Check if result is not null and is not an error if(gpgResult.result && !gpgResult.error) { // Get version string from result @@ -203,7 +244,7 @@ export class GpgSettingsTab extends PluginSettingTab { // In case of words gpg or GnuPG are include in output if(version.includes("gpg") && version.includes("GnuPG")) { // Change the status to OK - this.changeGpgPathStatus(GpgExecPathStatus.OK); + this.changeGpgPathStatus(GpgExecPathStatus.OK, workingPath); // Refresh GPG public key list await this.RefreshGpgPublicKeyList(); // End this check process @@ -251,10 +292,20 @@ export class GpgSettingsTab extends PluginSettingTab { } } + // Function to check if GPG Path exits (legacy - kept for compatibility) + private async checkGpgPath(value: string) { + // Just call the new checkGpgPaths function + await this.checkGpgPaths(); + } + // Function to change GPG executable path status - private changeGpgPathStatus(status: GpgExecPathStatus) { + private changeGpgPathStatus(status: GpgExecPathStatus, workingPath?: string) { // Change text status with new one - this.gpgExecPathStatus.setText(`Status: ${status}`); + let statusText = `Status: ${status}`; + if (status === GpgExecPathStatus.OK && workingPath) { + statusText += ` (using: ${workingPath})`; + } + this.gpgExecPathStatus.setText(statusText); // Swich to identify status style switch (status) { // In case of Loading status @@ -278,7 +329,7 @@ export class GpgSettingsTab extends PluginSettingTab { // Function to refresh list of GPG Public Keys private async RefreshGpgPublicKeyList() { // Get list of GPG public Keys - let gpgPublicKeys: { keyID: string; userID: string }[] = await getListPublicKey(this.plugin.settings); + let gpgPublicKeys: { keyID: string; userID: string }[] = await getListPublicKey(this.plugin, this.plugin.settings); // Iterate over each sub-element in list while (this.gpgPublicKeysList.descEl.firstChild) { // Remove each sub-element in list to clear list @@ -337,7 +388,7 @@ export class GpgSettingsTab extends PluginSettingTab { // Check ir requireSign to populate DropDown if (requireSign) { // Get list of GPG public Keys - let gpgPublicKeys: { keyID: string; userID: string }[] = await getListPublicKey(this.plugin.settings); + let gpgPublicKeys: { keyID: string; userID: string }[] = await getListPublicKey(this.plugin, this.plugin.settings); // Discard result if a newer call has already started if (generation !== this.signListGeneration) return; // Clear all DropDown items @@ -396,7 +447,7 @@ export class GpgSettingsTab extends PluginSettingTab { // Save settings with change await new Settings(this.plugin).saveSettings(); // Run a script to check gpg path with pgpAditionalCommandsBefore - await this.checkGpgPath(this.plugin.settings.pgpExecPath); + await this.checkGpgPaths(); })); this.gpgAditionalCommandsAfter.addText(text => text .setPlaceholder('command') @@ -407,7 +458,7 @@ export class GpgSettingsTab extends PluginSettingTab { // Save settings with change await new Settings(this.plugin).saveSettings(); // Run a script to check gpg path with pgpAditionalCommandsAfter - await this.checkGpgPath(this.plugin.settings.pgpExecPath); + await this.checkGpgPaths(); })); this.gpgAditionalCommandsConsole.addToggle((toggle) => { // Toggle component default value is false @@ -435,7 +486,7 @@ export class GpgSettingsTab extends PluginSettingTab { this.plugin.settings.pgpAditionalCommands = false; // And hide the aditional commands settings this.gpgAditionalCommands.settingEl.hide(); - this.gpgExecPath.settingEl.hide(); + this.gpgExecPaths.settingEl.hide(); this.gpgPublicKeysList.settingEl.hide(); this.gpgSignKeyId.settingEl.hide(); this.gpgSignText.settingEl.hide(); @@ -450,7 +501,7 @@ export class GpgSettingsTab extends PluginSettingTab { this.openpgpSettingsEl.empty(); // And show the aditional commands settings this.gpgAditionalCommands.settingEl.show(); - this.gpgExecPath.settingEl.show(); + this.gpgExecPaths.settingEl.show(); this.gpgPublicKeysList.settingEl.show(); this.gpgSignText.settingEl.show(); this.gpgAlwaysTrust.settingEl.show(); @@ -462,7 +513,7 @@ export class GpgSettingsTab extends PluginSettingTab { // Repopulate sign key dropdown with native GPG keys this.RefreshListSign(this.plugin.settings.pgpSignPublicKeyId != "0"); - this.checkGpgPath(this.plugin.settings.pgpExecPath); + this.checkGpgPaths(); } // Call method to show/hide aditional commands @@ -555,7 +606,7 @@ export class GpgSettingsTab extends PluginSettingTab { return; } try { - const keys = await getListPublicKey(this.plugin.settings); + const keys = await getListPublicKey(this.plugin, this.plugin.settings); if (keys.length > 0) { const infoEl = this.openpgpKeyInfoEl.createDiv(); infoEl.className = "text-color-green"; diff --git a/src/gpg.ts b/src/gpg.ts index cef1aab..6734ee5 100644 --- a/src/gpg.ts +++ b/src/gpg.ts @@ -1,9 +1,14 @@ -import { GpgEncryptSettings } from "./Settings"; +import { GpgEncryptSettings, Settings } from "./Settings"; import * as openpgpBackend from "./openpgp"; +import GpgEncryptPlugin from "main"; // Default and Global Args const globalArgs: string[] = ["--batch"]; +// Cache for working GPG path to avoid repeated lookups +let cachedWorkingPath: string | null = null; +let cachedPlugin: GpgEncryptPlugin | null = null; + // Object that is returned when spawnGPG method is called export interface GpgResult { result?: Buffer | string; @@ -23,12 +28,42 @@ function AditionalArgs(settings: GpgEncryptSettings): string[] { return aditionalArgs; } +// Function to get working GPG path from settings (with caching) +async function getWorkingGpgPath(plugin: GpgEncryptPlugin): Promise { + // Return cached path if available and plugin hasn't changed + if (cachedWorkingPath && cachedPlugin === plugin) { + return cachedWorkingPath; + } + + // Get working path from settings + cachedWorkingPath = await new Settings(plugin).getWorkingGpgPath(); + cachedPlugin = plugin; + + return cachedWorkingPath; +} + +// Function to clear cached working path (useful when settings change) +export function clearWorkingPathCache() { + cachedWorkingPath = null; + cachedPlugin = null; +} + // Function to execute GPG command with some arguments and input text -export default function spawnGPG(settings: GpgEncryptSettings, input: string | Buffer | null, args?: string[]): Promise { +export default async function spawnGPG(plugin: GpgEncryptPlugin, settings: GpgEncryptSettings, input: string | Buffer | null, args?: string[]): Promise { // New Promise to resolve when GPG command is executed - return new Promise((resolve) => { + return new Promise(async (resolve) => { // Try to catch all exceptions try { + // Get working GPG path + const workingPath = await getWorkingGpgPath(plugin); + if (!workingPath) { + resolve({ + result: undefined, + error: new Error("❌ No working GPG executable found in configured paths") + }); + return; + } + // In case of args are null if (!args) { // Create an empty args array @@ -45,7 +80,7 @@ export default function spawnGPG(settings: GpgEncryptSettings, input: string | if (settings.pgpAditionalCommands && settings.pgpAditionalCommandsBefore !== '') { command = settings.pgpAditionalCommandsBefore + " && "; } - command += "\"" + settings.pgpExecPath + "\""; + command += "\"" + workingPath + "\""; fullArgs.forEach(arg => { command += " " + arg; }); @@ -108,19 +143,19 @@ export default function spawnGPG(settings: GpgEncryptSettings, input: string | } // Get list of all Public Key availables (routes to the selected library) -export async function getListPublicKey(settings: GpgEncryptSettings): Promise<{ keyID: string; userID: string }[]> { +export async function getListPublicKey(plugin: GpgEncryptPlugin, settings: GpgEncryptSettings): Promise<{ keyID: string; userID: string }[]> { // When openpgpjs is selected, use the OpenPGP.js backend if (settings.pgpLibrary === "openpgpjs") { return openpgpBackend.getListPublicKey(settings); } // Otherwise use the native GPG executable - return nativeGetListPublicKey(settings); + return nativeGetListPublicKey(plugin, settings); } // Get list of all Public Key availables using the native GPG executable -async function nativeGetListPublicKey(settings: GpgEncryptSettings): Promise<{ keyID: string; userID: string }[]> { +async function nativeGetListPublicKey(plugin: GpgEncryptPlugin, settings: GpgEncryptSettings): Promise<{ keyID: string; userID: string }[]> { // Build the executable and args - const gpgResult: GpgResult = await spawnGPG(settings, null, ["--logger-fd", "1", "--list-public-keys", "--with-colons"]); + const gpgResult: GpgResult = await spawnGPG(plugin, settings, null, ["--logger-fd", "1", "--list-public-keys", "--with-colons"]); // Check if result are null if(!gpgResult.result) { // And return a null array @@ -154,17 +189,17 @@ async function nativeGetListPublicKey(settings: GpgEncryptSettings): Promise<{ k } // Function to encrypt a plainText with a list of GPG public keys ID (routes to the selected library) -export async function gpgEncrypt(settings: GpgEncryptSettings, plainText:string, publicKeyIds: string[], signPublicKeyId: string, passphrase?: string | null): Promise { +export async function gpgEncrypt(plugin: GpgEncryptPlugin, settings: GpgEncryptSettings, plainText:string, publicKeyIds: string[], signPublicKeyId: string, passphrase?: string | null): Promise { // When openpgpjs is selected, use the OpenPGP.js backend if (settings.pgpLibrary === "openpgpjs") { return openpgpBackend.gpgEncrypt(settings, plainText, publicKeyIds, signPublicKeyId, passphrase); } // Otherwise use the native GPG executable - return nativeGpgEncrypt(settings, plainText, publicKeyIds, signPublicKeyId); + return nativeGpgEncrypt(plugin, settings, plainText, publicKeyIds, signPublicKeyId); } // Function to encrypt a plainText using the native GPG executable -async function nativeGpgEncrypt(settings: GpgEncryptSettings, plainText:string, publicKeyIds: string[], signPublicKeyId: string): Promise { +async function nativeGpgEncrypt(plugin: GpgEncryptPlugin, settings: GpgEncryptSettings, plainText:string, publicKeyIds: string[], signPublicKeyId: string): Promise { // Check if at least one public key is selected if (publicKeyIds.length <= 0) { // And return with error message @@ -186,7 +221,7 @@ async function nativeGpgEncrypt(settings: GpgEncryptSettings, plainText:string, args = args.concat(["--recipient", publicKey]); }); // Build the executable and args - const gpgResult: GpgResult = await spawnGPG(settings, plainText, args); + const gpgResult: GpgResult = await spawnGPG(plugin, settings, plainText, args); // Check if error is null if(gpgResult.error) { // Return with error message @@ -209,21 +244,21 @@ async function nativeGpgEncrypt(settings: GpgEncryptSettings, plainText:string, // Function to decrypt an encrypted text with a private key (routes to the selected library) -export async function gpgDecrypt(settings: GpgEncryptSettings, encryptedText:string, passphrase?: string | null): Promise { +export async function gpgDecrypt(plugin: GpgEncryptPlugin, settings: GpgEncryptSettings, encryptedText:string, passphrase?: string | null): Promise { // When openpgpjs is selected, use the OpenPGP.js backend if (settings.pgpLibrary === "openpgpjs") { return openpgpBackend.gpgDecrypt(settings, encryptedText, passphrase); } // Otherwise use the native GPG executable - return nativeGpgDecrypt(settings, encryptedText); + return nativeGpgDecrypt(plugin, settings, encryptedText); } // Function to decrypt an encrypted text using the native GPG executable -async function nativeGpgDecrypt(settings: GpgEncryptSettings, encryptedText:string): Promise { +async function nativeGpgDecrypt(plugin: GpgEncryptPlugin, settings: GpgEncryptSettings, encryptedText:string): Promise { // List of Args before publicKeyIds let args: string[] = ["--decrypt"].concat(AditionalArgs(settings)); // Build the executable and args - const gpgResult: GpgResult = await spawnGPG(settings, encryptedText, args); + const gpgResult: GpgResult = await spawnGPG(plugin, settings, encryptedText, args); // Check if error is null if(gpgResult.error) { // Return with error message diff --git a/styles.css b/styles.css index 0f61d7c..698f9c7 100644 --- a/styles.css +++ b/styles.css @@ -49,4 +49,10 @@ width: 100%; font-family: monospace; font-size: 11px; +} +.gpg-paths-list { + margin-top: 10px; +} +.gpg-path-item { + margin-bottom: 8px; } \ No newline at end of file