Skip to content

Commit

Permalink
add recursive flag to handle encrypting directories (closes #165)
Browse files Browse the repository at this point in the history
  • Loading branch information
robinmoisson committed Apr 19, 2023
1 parent 5ef120b commit dfeffc8
Show file tree
Hide file tree
Showing 3 changed files with 67 additions and 27 deletions.
24 changes: 16 additions & 8 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,9 @@ You can then run it with `npx staticrypt ...`. You can also install globally wit

```bash
staticrypt test.html -p MY_LONG_PASSWORD

# or do not include the password if you want to be prompted for it:
staticrypt test.html
```

**Encrypt a file with the password in an environment variable:** set your long password in the `STATICRYPT_PASSWORD` environment variable ([`.env` files](https://www.npmjs.com/package/dotenv#usage) are supported):
Expand All @@ -39,20 +42,23 @@ staticrypt test.html -p MY_LONG_PASSWORD
staticrypt test.html
```

**Encrypt a file and get a shareable link containing the hashed password** - you can include your file URL or leave blank:

```bash
# you can also pass '--share' without specifying the URL to get the `#staticrypt_pwd=...`
staticrypt test.html -p MY_LONG_PASSWORD --share https://example.com/test_encrypted.html
# => https://example.com/test_encrypted.html#staticrypt_pwd=5bfbf1343c7257cd7be23ecd74bb37fa2c76d041042654f358b6255baeab898f
```

**Encrypt multiple files at once** and put them in a `encrypted/` directory:

```bash
# this will encrypt test_A.html, test_B.html and all files in the test/ directory
staticrypt test_A.html test_B.html test/* -p MY_LONG_PASSWORD
# => encrypted files are in encrypted/test_A.html, encrypted/test_B.html, encrypted/test/...

# you can also use the -r flag to recursively encrypt all files in a directory
staticrypt dir_to_encrypt -p MY_LONG_PASSWORD -r
```

**Encrypt a file and get a shareable link containing the hashed password** - you can include your file URL or leave blank:

```bash
# you can also pass '--share' without specifying the URL to get the `#staticrypt_pwd=...`
staticrypt test.html -p MY_LONG_PASSWORD --share https://example.com/test_encrypted.html
# => https://example.com/test_encrypted.html#staticrypt_pwd=5bfbf1343c7257cd7be23ecd74bb37fa2c76d041042654f358b6255baeab898f
```

**Pin the salt to use staticrypt in your CI in a build step** - if you want want the "Remember-me" or share features to work accross multiple pages or multiple successive deployment, the salt needs to stay the same ([see why](https://github.com/robinmoisson/staticrypt#why-does-staticrypt-create-a-config-file)). If you run StatiCrypt in a CI step, you can pin the salt in two ways:
Expand Down Expand Up @@ -84,6 +90,8 @@ The password argument is optional if `STATICRYPT_PASSWORD` is set in the environ
empty to be prompted for it. If
STATICRYPT_PASSWORD is set in the env, we'll
use that instead. [string] [default: null]
-r, --recursive Whether to recursively encrypt the input
directory. [boolean] [default: false]
--remember Expiration in days of the "Remember me"
checkbox that will save the (salted + hashed)
password in localStorage when entered by the
Expand Down
6 changes: 6 additions & 0 deletions cli/helpers.js
Original file line number Diff line number Diff line change
Expand Up @@ -309,6 +309,12 @@ function parseCommandLineArguments() {
" is set in the env, we'll use that instead.",
default: null,
})
.option("r", {
alias: "recursive",
type: "boolean",
describe: "Whether to recursively encrypt the input directory.",
default: false,
})
.option("remember", {
type: "number",
describe:
Expand Down
64 changes: 45 additions & 19 deletions cli/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,8 @@ if (nodeVersion[0] < 16) {
// parse .env file into process.env
require('dotenv').config();

const fs = require("fs");

const cryptoEngine = require("../lib/cryptoEngine.js");
const codec = require("../lib/codec.js");
const { generateRandomSalt } = cryptoEngine;
Expand Down Expand Up @@ -98,30 +100,54 @@ async function runStatiCrypt() {

const hashedPassword = await cryptoEngine.hashPassword(password, salt);

for (const positionalArgument of positionalArguments) {
const inputFilepath = positionalArgument.toString();

// get the file content
const contents = getFileContent(inputFilepath);
positionalArguments.forEach(path => encodeAndGenerateFile(
path.toString(),
hashedPassword,
salt,
baseTemplateData,
isRememberEnabled,
namedArgs
));
}

// encrypt input
const encryptedMsg = await encodeWithHashedPassword(contents, hashedPassword);
async function encodeAndGenerateFile(path, hashedPassword, salt, baseTemplateData, isRememberEnabled, namedArgs) {
// if the path is a directory, get into it and process all files
if (fs.statSync(path).isDirectory()) {
if (!namedArgs.recursive) {
console.log("ERROR: The path '" + path + "' is a directory. Use the -r|--recursive flag to process all files in the directory.");

const staticryptConfig = {
encryptedMsg,
isRememberEnabled,
rememberDurationInDays: namedArgs.remember,
salt,
};
const templateData = {
...baseTemplateData,
staticrypt_config: staticryptConfig,
};
// just return instead of exiting the process, that way all other files can be processed
return;
}

const outputFilepath = namedArgs.directory.replace(/\/+$/, '') + "/" + inputFilepath;
fs.readdirSync(path).forEach(filePath => {
const fullPath = `${path}/${filePath}`;

genFile(templateData, outputFilepath, namedArgs.template);
encodeAndGenerateFile(fullPath, hashedPassword, salt, baseTemplateData, isRememberEnabled, namedArgs);
});
return;
}

// get the file content
const contents = getFileContent(path);

// encrypt input
const encryptedMsg = await encodeWithHashedPassword(contents, hashedPassword);

const staticryptConfig = {
encryptedMsg,
isRememberEnabled,
rememberDurationInDays: namedArgs.remember,
salt,
};
const templateData = {
...baseTemplateData,
staticrypt_config: staticryptConfig,
};

const outputFilepath = namedArgs.directory.replace(/\/+$/, '') + "/" + path;

genFile(templateData, outputFilepath, namedArgs.template);
}

runStatiCrypt();

0 comments on commit dfeffc8

Please sign in to comment.