From 6a88d734bdb4660945923c3f4a38c14e45847c2c Mon Sep 17 00:00:00 2001 From: kongjun Date: Tue, 29 Apr 2025 03:49:28 +0000 Subject: feat: store passwords in a local scope instead of as a buffer variable --- lua/encrypt/helpers.lua | 19 ++++++++++++------- 1 file changed, 12 insertions(+), 7 deletions(-) (limited to 'lua') diff --git a/lua/encrypt/helpers.lua b/lua/encrypt/helpers.lua index 37a96b3..ff8baef 100644 --- a/lua/encrypt/helpers.lua +++ b/lua/encrypt/helpers.lua @@ -1,13 +1,18 @@ ----@return string -local function getPassword() - local password = vim.b["password"] - if password == nil then - password = vim.fn.inputsecret("Enter password: ") - vim.b["password"] = password +---@return function string +local getPasswordFactory = function() + local bufferPasswordMap = {} + + return function() + local key = string.format("%s", vim.fn.bufnr()) + if bufferPasswordMap[key] == nil then + password = vim.fn.inputsecret("Enter password: ") + bufferPasswordMap[key] = password + end + return bufferPasswordMap[key] end - return password end +local getPassword = getPasswordFactory() local ENCRYPTED_PREFIX = "# <<>>" return { getPassword = getPassword, ENCRYPTED_PREFIX = ENCRYPTED_PREFIX } -- cgit v1.2.3 From e6057b3c13f004477f4963f3cdf054e5ca1bf2f4 Mon Sep 17 00:00:00 2001 From: kongjun Date: Tue, 29 Apr 2025 04:05:35 +0000 Subject: feat: lock the encrypted file to read-only mode to avoid unintended corruption --- lua/encrypt/decrypt.lua | 1 + lua/encrypt/helpers.lua | 8 +++++++- lua/encrypt/init.lua | 4 ++-- lua/encrypt/setup-buffer.lua | 9 ++++++++- 4 files changed, 18 insertions(+), 4 deletions(-) (limited to 'lua') diff --git a/lua/encrypt/decrypt.lua b/lua/encrypt/decrypt.lua index 2ae4e2a..72e93c3 100644 --- a/lua/encrypt/decrypt.lua +++ b/lua/encrypt/decrypt.lua @@ -20,6 +20,7 @@ local function decrypt() end vim.fn.timer_start(0, function() + vim.bo.modifiable = true vim.api.nvim_buf_set_lines(0, 0, -1, false, decrypted_lines) vim.bo.modified = false end) diff --git a/lua/encrypt/helpers.lua b/lua/encrypt/helpers.lua index ff8baef..a2ccc51 100644 --- a/lua/encrypt/helpers.lua +++ b/lua/encrypt/helpers.lua @@ -15,4 +15,10 @@ end local getPassword = getPasswordFactory() local ENCRYPTED_PREFIX = "# <<>>" -return { getPassword = getPassword, ENCRYPTED_PREFIX = ENCRYPTED_PREFIX } +---@enum buftype +local BUFTYPE = { + encrypted = 1, + plaintext = 2, +} + +return { getPassword = getPassword, ENCRYPTED_PREFIX = ENCRYPTED_PREFIX, BUFTYPE = BUFTYPE} diff --git a/lua/encrypt/init.lua b/lua/encrypt/init.lua index 53fc259..cfa1aa6 100644 --- a/lua/encrypt/init.lua +++ b/lua/encrypt/init.lua @@ -5,7 +5,7 @@ local helpers = require("encrypt.helpers") local function setup() vim.api.nvim_create_user_command("X", function() - setupBuffer() + setupBuffer(helpers.BUFTYPE.decrypted) encrypt() end, {}) @@ -13,7 +13,7 @@ local function setup() callback = function() local first_line = vim.api.nvim_buf_get_lines(0, 0, 1, false)[1] if first_line == helpers.ENCRYPTED_PREFIX then - setupBuffer() + setupBuffer(helpers.BUFTYPE.encrypted) decrypt() end end, diff --git a/lua/encrypt/setup-buffer.lua b/lua/encrypt/setup-buffer.lua index 8b950ec..e03f71c 100644 --- a/lua/encrypt/setup-buffer.lua +++ b/lua/encrypt/setup-buffer.lua @@ -1,4 +1,5 @@ local encrypt = require("encrypt.encrypt") +local helpers = require("encrypt.helpers") local function createWriteAutoCmd() if vim.b["encryptionAutoCmd"] ~= nil then @@ -18,12 +19,18 @@ local function createWriteAutoCmd() }) end -local function setupBuffer() +---@param buftype buftype +local function setupBuffer(buftype) -- buftype="acwrite" means save using the BufWriteCmd command vim.bo.buftype = "acwrite" vim.bo.swapfile = false vim.bo.undofile = false vim.b["encrypted"] = true + -- Lock the encrypted file to read-only mode to avoid corruption + -- caused by unintended modifications. + if buftype == helpers.BUFTYPE.encrypted then + vim.bo.modifiable = false + end createWriteAutoCmd() end -- cgit v1.2.3 From 872632670c31f682f3db01707468dbc12f154ab4 Mon Sep 17 00:00:00 2001 From: kongjun Date: Tue, 29 Apr 2025 06:51:01 +0000 Subject: feat: :X decrypts or encrypts files --- lua/encrypt/helpers.lua | 14 +++++++++++++- lua/encrypt/init.lua | 12 ++++++++---- 2 files changed, 21 insertions(+), 5 deletions(-) (limited to 'lua') diff --git a/lua/encrypt/helpers.lua b/lua/encrypt/helpers.lua index a2ccc51..b740f28 100644 --- a/lua/encrypt/helpers.lua +++ b/lua/encrypt/helpers.lua @@ -21,4 +21,16 @@ local BUFTYPE = { plaintext = 2, } -return { getPassword = getPassword, ENCRYPTED_PREFIX = ENCRYPTED_PREFIX, BUFTYPE = BUFTYPE} +local function bufferEncrypted() + local first_line = vim.api.nvim_buf_get_lines(0, 0, 1, false)[1] + if first_line == ENCRYPTED_PREFIX then + return true + end +end + +return { + getPassword = getPassword, + ENCRYPTED_PREFIX = ENCRYPTED_PREFIX, + BUFTYPE = BUFTYPE, + bufferEncrypted = bufferEncrypted, +} diff --git a/lua/encrypt/init.lua b/lua/encrypt/init.lua index cfa1aa6..ea5368f 100644 --- a/lua/encrypt/init.lua +++ b/lua/encrypt/init.lua @@ -5,14 +5,18 @@ local helpers = require("encrypt.helpers") local function setup() vim.api.nvim_create_user_command("X", function() - setupBuffer(helpers.BUFTYPE.decrypted) - encrypt() + if helpers.bufferEncrypted() then + setupBuffer(helpers.BUFTYPE.encrypted) + decrypt() + else + setupBuffer(helpers.BUFTYPE.plaintext) + encrypt() + end end, {}) vim.api.nvim_create_autocmd({ "BufReadPost" }, { callback = function() - local first_line = vim.api.nvim_buf_get_lines(0, 0, 1, false)[1] - if first_line == helpers.ENCRYPTED_PREFIX then + if helpers.bufferEncrypted() then setupBuffer(helpers.BUFTYPE.encrypted) decrypt() end -- cgit v1.2.3 From c7a16c626a0379d9304e0337348affb4bde9ba4e Mon Sep 17 00:00:00 2001 From: kongjun Date: Tue, 6 May 2025 10:10:59 +0000 Subject: feat: support password with special characters --- lua/encrypt/decrypt.lua | 2 +- lua/encrypt/encrypt.lua | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) (limited to 'lua') diff --git a/lua/encrypt/decrypt.lua b/lua/encrypt/decrypt.lua index 72e93c3..de49019 100644 --- a/lua/encrypt/decrypt.lua +++ b/lua/encrypt/decrypt.lua @@ -5,7 +5,7 @@ local helpers = require("encrypt.helpers") ---@param password string local function decrypt_lines(lines, password) return vim.fn.systemlist( - "base64 --decode | openssl enc -d -aes-256-cbc -pbkdf2 -salt -in - -out - -k " .. password, + "base64 --decode | openssl enc -d -aes-256-cbc -pbkdf2 -salt -in - -out - -k " .. vim.fn.shellescape(password), lines ) end diff --git a/lua/encrypt/encrypt.lua b/lua/encrypt/encrypt.lua index 5cdf8a9..93d2b78 100644 --- a/lua/encrypt/encrypt.lua +++ b/lua/encrypt/encrypt.lua @@ -5,7 +5,7 @@ local helpers = require("encrypt.helpers") ---@param password string local function encrypt_lines(lines, password) return vim.fn.systemlist( - "openssl enc -aes-256-cbc -pbkdf2 -salt -in - -out - -k " .. password .. " | base64", + "openssl enc -aes-256-cbc -pbkdf2 -salt -in - -out - -k " .. vim.fn.shellescape(password) .. " | base64", lines ) end -- cgit v1.2.3 From a9e7d700eb546800e3d341bc53667964ac821a38 Mon Sep 17 00:00:00 2001 From: kongjun Date: Tue, 6 May 2025 10:14:39 +0000 Subject: feat: handle the case where the inputsecret() is cancelled --- lua/encrypt/decrypt.lua | 4 ++++ lua/encrypt/encrypt.lua | 4 ++++ lua/encrypt/helpers.lua | 3 +++ 3 files changed, 11 insertions(+) (limited to 'lua') diff --git a/lua/encrypt/decrypt.lua b/lua/encrypt/decrypt.lua index de49019..a1d6b66 100644 --- a/lua/encrypt/decrypt.lua +++ b/lua/encrypt/decrypt.lua @@ -12,6 +12,10 @@ end local function decrypt() local password = helpers.getPassword() + if not password then + vim.notify("Password can not be empty", vim.log.levels.ERROR) + return + end local encrypted_lines = vim.api.nvim_buf_get_lines(0, 1, -1, false) local decrypted_lines = decrypt_lines(encrypted_lines, password) if vim.v.shell_error ~= 0 then diff --git a/lua/encrypt/encrypt.lua b/lua/encrypt/encrypt.lua index 93d2b78..c7efb1f 100644 --- a/lua/encrypt/encrypt.lua +++ b/lua/encrypt/encrypt.lua @@ -12,6 +12,10 @@ end local function encrypt() local password = helpers.getPassword() + if not password then + vim.notify("Password can not be empty", vim.log.levels.ERROR) + return + end local buf_lines = vim.api.nvim_buf_get_lines(0, 0, -1, false) local encrypted_lines = encrypt_lines(buf_lines, password) diff --git a/lua/encrypt/helpers.lua b/lua/encrypt/helpers.lua index b740f28..c88b448 100644 --- a/lua/encrypt/helpers.lua +++ b/lua/encrypt/helpers.lua @@ -6,6 +6,9 @@ local getPasswordFactory = function() local key = string.format("%s", vim.fn.bufnr()) if bufferPasswordMap[key] == nil then password = vim.fn.inputsecret("Enter password: ") + if password == "" then + vim.notify("Password is cancelled", vim.log.levels.WARN) + end bufferPasswordMap[key] = password end return bufferPasswordMap[key] -- cgit v1.2.3