aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDavid Elentok <3david@gmail.com>2024-05-14 18:15:13 +0300
committerDavid Elentok <3david@gmail.com>2024-05-14 18:17:09 +0300
commita805d34f123bc8add01bd44ad28f0baf57710083 (patch)
treeb868cef404823eaf4b7c78316459cf8b2a3fd013
downloadencrypt.nvim-a805d34f123bc8add01bd44ad28f0baf57710083.tar.gz
Initial commit
-rw-r--r--LICENSE21
-rw-r--r--README.md29
-rw-r--r--lua/encrypt/decrypt.lua28
-rw-r--r--lua/encrypt/encrypt.lua25
-rw-r--r--lua/encrypt/helpers.lua13
-rw-r--r--lua/encrypt/init.lua23
-rw-r--r--lua/encrypt/setup-buffer.lua28
-rw-r--r--lua/stylua.toml3
8 files changed, 170 insertions, 0 deletions
diff --git a/LICENSE b/LICENSE
new file mode 100644
index 0000000..18fd882
--- /dev/null
+++ b/LICENSE
@@ -0,0 +1,21 @@
+MIT License
+
+Copyright (c) 2023 David Elentok
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in all
+copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+SOFTWARE.
diff --git a/README.md b/README.md
new file mode 100644
index 0000000..45a94b7
--- /dev/null
+++ b/README.md
@@ -0,0 +1,29 @@
+# encrypt.nvim
+
+This is a simple alternative to the "X" command that was removed from Neovim.
+
+Disclaimer: It's probably not the most secure implementation (if such thing is
+even possible) but it gives the ability to edit files that will be stored in
+encrypted on the disk.
+
+## Usage
+
+1. Open a file
+2. Run `:X`
+3. Enter a password
+
+Now the file is encrypted and every time you open it you'll be asked for the
+password.
+
+## Installation
+
+Add the following to your package manager:
+
+```lua
+{ "elentok/encrypt.nvim", opts = {} },
+```
+
+## TODO
+
+- [ ] Store the password in a local scope in the plugin instead of as a buffer
+ variable.
diff --git a/lua/encrypt/decrypt.lua b/lua/encrypt/decrypt.lua
new file mode 100644
index 0000000..2ae4e2a
--- /dev/null
+++ b/lua/encrypt/decrypt.lua
@@ -0,0 +1,28 @@
+local helpers = require("encrypt.helpers")
+
+---@return string[]
+---@param lines string | string[]
+---@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,
+ lines
+ )
+end
+
+local function decrypt()
+ local password = helpers.getPassword()
+ 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
+ vim.notify("Error decrypting", vim.log.levels.ERROR)
+ return
+ end
+
+ vim.fn.timer_start(0, function()
+ vim.api.nvim_buf_set_lines(0, 0, -1, false, decrypted_lines)
+ vim.bo.modified = false
+ end)
+end
+
+return decrypt
diff --git a/lua/encrypt/encrypt.lua b/lua/encrypt/encrypt.lua
new file mode 100644
index 0000000..5cdf8a9
--- /dev/null
+++ b/lua/encrypt/encrypt.lua
@@ -0,0 +1,25 @@
+local helpers = require("encrypt.helpers")
+
+---@return string[]
+---@param lines string | string[]
+---@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",
+ lines
+ )
+end
+
+local function encrypt()
+ local password = helpers.getPassword()
+ local buf_lines = vim.api.nvim_buf_get_lines(0, 0, -1, false)
+ local encrypted_lines = encrypt_lines(buf_lines, password)
+
+ table.insert(encrypted_lines, 1, helpers.ENCRYPTED_PREFIX)
+
+ vim.fn.writefile(encrypted_lines, vim.fn.expand("%"))
+ vim.bo.modified = false
+ print("Encrypted " .. vim.fn.expand("%:t"))
+end
+
+return encrypt
diff --git a/lua/encrypt/helpers.lua b/lua/encrypt/helpers.lua
new file mode 100644
index 0000000..37a96b3
--- /dev/null
+++ b/lua/encrypt/helpers.lua
@@ -0,0 +1,13 @@
+---@return string
+local function getPassword()
+ local password = vim.b["password"]
+ if password == nil then
+ password = vim.fn.inputsecret("Enter password: ")
+ vim.b["password"] = password
+ end
+ return password
+end
+
+local ENCRYPTED_PREFIX = "# <<<encrypted>>>"
+
+return { getPassword = getPassword, ENCRYPTED_PREFIX = ENCRYPTED_PREFIX }
diff --git a/lua/encrypt/init.lua b/lua/encrypt/init.lua
new file mode 100644
index 0000000..53fc259
--- /dev/null
+++ b/lua/encrypt/init.lua
@@ -0,0 +1,23 @@
+local setupBuffer = require("encrypt.setup-buffer")
+local encrypt = require("encrypt.encrypt")
+local decrypt = require("encrypt.decrypt")
+local helpers = require("encrypt.helpers")
+
+local function setup()
+ vim.api.nvim_create_user_command("X", function()
+ setupBuffer()
+ encrypt()
+ 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
+ setupBuffer()
+ decrypt()
+ end
+ end,
+ })
+end
+
+return { setup = setup }
diff --git a/lua/encrypt/setup-buffer.lua b/lua/encrypt/setup-buffer.lua
new file mode 100644
index 0000000..a09cdfb
--- /dev/null
+++ b/lua/encrypt/setup-buffer.lua
@@ -0,0 +1,28 @@
+local encrypt = require("encrypt.encrypt")
+
+local function createWriteAutoCmd()
+ if vim.b["encryptionAutoCmd"] ~= nil then
+ return
+ end
+
+ vim.b["encryptionAutoCmd"] = vim.api.nvim_create_autocmd({ "BufWriteCmd" }, {
+ callback = function()
+ if vim.b["encrypted"] ~= true then
+ return
+ end
+
+ encrypt()
+ end,
+ })
+end
+
+local function setupBuffer()
+ -- buftype="acwrite" means save using the BufWriteCmd command
+ vim.bo.buftype = "acwrite"
+ vim.bo.swapfile = false
+ vim.bo.undofile = false
+ vim.b["encrypted"] = true
+ createWriteAutoCmd()
+end
+
+return setupBuffer
diff --git a/lua/stylua.toml b/lua/stylua.toml
new file mode 100644
index 0000000..2278abd
--- /dev/null
+++ b/lua/stylua.toml
@@ -0,0 +1,3 @@
+indent_type = "Spaces"
+indent_width = 2
+column_width = 100