wilcocrypt 2.1.1 → 2.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -1,21 +1,23 @@
1
1
  # WilcoCrypt
2
2
 
3
- **WilcoCrypt** is a small, secure, and predictable encryption library for Node.js.
3
+ [![js-semistandard-style](https://img.shields.io/badge/code%20style-semistandard-brightgreen.svg)](https://github.com/standard/semistandard)
4
4
 
5
- It is designed around strong defaults, minimal dependencies, and consistent behavior across environments — from servers to low-end devices like Raspberry Pi.
5
+ > **The `master` branch may be unstable during active development.**
6
+ > For production use, always install from [npm](https://www.npmjs.com/package/wilcocrypt) or use a tagged [GitHub Release](https://github.com/computer-wilco/wilcocrypt/releases).
7
+
8
+ A simple, modern Node.js encryption library and CLI tool. AES-256-GCM, password-based key derivation via scrypt, optional gzip compression, and a streaming API for large files.
6
9
 
7
10
  ---
8
11
 
9
12
  ## Features
10
13
 
11
14
  - AES-256-GCM authenticated encryption
12
- - Password-based key derivation using scrypt
15
+ - scrypt key derivation with a random salt per encryption
13
16
  - Optional gzip compression before encryption
14
- - Compact binary format using MessagePack
15
- - Built-in versioning and compatibility checks
16
- - Clear and consistent error handling
17
- - Simple, dependency-light design
18
- - CLI for quick file encryption and decryption
17
+ - Streaming API for large files (`encryptFileStream` / `decryptFileStream`)
18
+ - CLI with interactive password prompt
19
+ - TypeScript types included
20
+ - semistandard code style
19
21
 
20
22
  ---
21
23
 
@@ -25,99 +27,92 @@ It is designed around strong defaults, minimal dependencies, and consistent beha
25
27
  npm install wilcocrypt
26
28
  ```
27
29
 
28
- ### CLI (global)
29
-
30
- ```bash
31
- npm install -g wilcocrypt
32
- ```
30
+ Requires Node.js 18 or later.
33
31
 
34
32
  ---
35
33
 
36
- ## Usage (Node.js)
34
+ ## Quick Start
37
35
 
38
36
  ```js
39
37
  import wilcocrypt from 'wilcocrypt';
40
38
 
41
- // Encrypt a file
42
- wilcocrypt.encryptFile('document.txt', 'myStrongPassword');
43
-
44
- // Decrypt a file
45
- const content = wilcocrypt.decryptFile('document.txt.enc', 'myStrongPassword');
46
-
47
- console.log(content);
48
- ```
49
-
50
- ### Working with Buffers
51
-
52
- ```js
53
- import wilcocrypt from 'wilcocrypt';
39
+ // Encrypt / decrypt a Buffer
40
+ const encrypted = wilcocrypt.encryptData(Buffer.from('Hello!'), 'my-password');
41
+ const decrypted = wilcocrypt.decryptData(encrypted, 'my-password');
54
42
 
55
- const data = Buffer.from('Hello world');
43
+ // Encrypt a file → writes file.txt.enc
44
+ wilcocrypt.encryptFile('file.txt', 'my-password');
56
45
 
57
- // Encrypt
58
- const encrypted = wilcocrypt.encryptData(data, 'password');
46
+ // Decrypt to Buffer
47
+ const buf = wilcocrypt.decryptFile('file.txt.enc', 'my-password');
59
48
 
60
- // Decrypt
61
- const decrypted = wilcocrypt.decryptData(encrypted, 'password');
49
+ // Decrypt directly to disk
50
+ wilcocrypt.decryptFile('file.txt.enc', 'my-password', 'output.txt');
62
51
 
63
- console.log(decrypted.toString());
52
+ // Stream API (memory-efficient for large files)
53
+ await wilcocrypt.encryptFileStream('big.zip', 'big.zip.enc', 'my-password');
54
+ await wilcocrypt.decryptFileStream('big.zip.enc', 'big.zip', 'my-password');
64
55
  ```
65
56
 
66
57
  ---
67
58
 
68
- ## CLI Usage
59
+ ## CLI
69
60
 
70
61
  ```bash
71
62
  # Encrypt
72
- wilcocrypt -e file.txt
73
- wilcocrypt --encrypt file.txt
63
+ wilcocrypt -e secret.txt
64
+ # prompts for password, writes secret.txt.enc
65
+
66
+ # Decrypt to stdout
67
+ wilcocrypt -d secret.txt.enc
74
68
 
75
- # Decrypt
76
- wilcocrypt -d file.txt.enc
77
- wilcocrypt --decrypt file.txt.enc
69
+ # Decrypt to a file
70
+ wilcocrypt -d secret.txt.enc -o secret.txt
78
71
  ```
79
72
 
80
- The CLI will securely prompt for a password (input is masked).
73
+ See `wilcocrypt --help` for all options.
81
74
 
82
75
  ---
83
76
 
84
- ## Internal API
77
+ ## Binary Payload Format
85
78
 
86
- Advanced users can access internal helpers via:
87
-
88
- ```js
89
- wilcocrypt._
79
+ ```
80
+ [ HEADER (10) ] [ VERSION (dynamic) ] [ salt (16) ] [ iv (12) ] [ ciphertext ] [ authTag (16) ]
90
81
  ```
91
82
 
92
- These APIs are **not stable** and may change between versions.
83
+ The auth tag is appended at the end for streaming compatibility. See [DOCS.md](./DOCS.md#binary-payload-format) for the full layout.
93
84
 
94
- ---
85
+ > **Note:** The format changed in v2.2.0. Payloads from v2.1.x are not compatible.
95
86
 
96
- ## Format Overview
87
+ ---
97
88
 
98
- Encrypted output is stored as a MessagePack-encoded object containing:
89
+ ## Error Handling
99
90
 
100
- - payload (ciphertext, hex)
101
- - authTag (hex)
102
- - salt (hex)
103
- - iv (hex)
104
- - version
91
+ All errors are instances of `WilcoCryptError` with a machine-readable `code` property.
105
92
 
106
- ---
107
-
108
- ## Version
93
+ ```js
94
+ import wilcocrypt from 'wilcocrypt';
95
+ const { WilcoCryptError } = wilcocrypt._;
96
+
97
+ try {
98
+ wilcocrypt.decryptData(payload, 'wrong');
99
+ } catch (err) {
100
+ if (err instanceof WilcoCryptError) {
101
+ console.error(err.code); // e.g. DECRYPTION_FAILED
102
+ console.error(err.message);
103
+ }
104
+ }
105
+ ```
109
106
 
110
- - Current version: **2.1.1**
111
- - Encrypted data must match the exact version
107
+ Common codes: `WEAK_PASSWORD`, `INVALID_HEADER`, `VERSION_MISMATCH`, `DECRYPTION_FAILED`, `INVALID_FILE_EXTENSION`.
112
108
 
113
109
  ---
114
110
 
115
- ## Security Notes
111
+ ## Documentation
112
+
113
+ Full API reference, CLI docs, payload format, TypeScript usage, and security notes: **[DOCS.md](./DOCS.md)**
116
114
 
117
- - Always use strong, unique passwords
118
- - Losing the password means permanent data loss
119
- - Do not modify encrypted files manually
120
- - Compression can be disabled if not needed
115
+ Changelog: **[CHANGELOG.md](./CHANGELOG.md)**
121
116
 
122
117
  ---
123
118
 
package/SECURITY.md ADDED
@@ -0,0 +1,48 @@
1
+ # Security Policy
2
+
3
+ ## Supported Versions
4
+
5
+ The following versions of WilcoCrypt are currently supported with security updates:
6
+
7
+ | Version | Supported |
8
+ | ------- | ------------------ |
9
+ | 2.1.x | :white_check_mark: |
10
+ | 2.0.x | :x: |
11
+ | 1.x | :x: |
12
+
13
+ Only the latest minor version in the 2.x range receives security updates. All the versions below that are not supported.
14
+
15
+ ---
16
+
17
+ ## Reporting a Vulnerability
18
+
19
+ If you discover a security vulnerability in WilcoCrypt, please report it responsibly.
20
+
21
+ ### How to report
22
+
23
+ - Open a **private security advisory** via the GitHub repository
24
+
25
+ Please include:
26
+
27
+ * A clear description of the issue
28
+ * Steps to reproduce (if possible)
29
+ * Impact assessment (what can go wrong)
30
+
31
+ ### What to expect
32
+
33
+ * You will receive a response within **48 hours**
34
+ * I will investigate and confirm the issue
35
+ * If accepted, a fix will be developed as soon as possible
36
+ * A patched version will be released and documented
37
+
38
+ ### Responsible disclosure
39
+
40
+ Please do **not** publicly disclose the vulnerability until a fix has been released.
41
+
42
+ ---
43
+
44
+ ## Notes
45
+
46
+ * WilcoCrypt is designed with strong cryptographic defaults, but misuse (e.g. weak passwords) can still lead to insecure outcomes
47
+ * Always use strong, unique passwords
48
+ * Security is a shared responsibility between the library and its users
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "wilcocrypt",
3
- "version": "2.1.1",
3
+ "version": "2.2.0",
4
4
  "description": "A encrypting tool",
5
5
  "keywords": [
6
6
  "encrypting",
@@ -13,9 +13,11 @@
13
13
  "bin": "src/cli.js",
14
14
  "types": "types/wilcocrypt.d.ts",
15
15
  "scripts": {
16
- "test": "echo \"Error: no test specified\" && exit 1",
16
+ "test": "node src/cli.js",
17
+ "lint": "npx semistandard",
18
+ "lint:fix": "npx semistandard --fix",
17
19
  "update": "npx -y Jelmerro/nus",
18
- "rollup": "rollup -c && node src/scripts/fix-cli-min-import.js && node src/scripts/chmod.js",
20
+ "rollup": "node src/scripts/shebang-fix.js pre && rollup -c && node src/scripts/shebang-fix.js post && node src/scripts/fix-cli-min-import.js && node src/scripts/chmod.js",
19
21
  "sea:blob": "node src/scripts/sea-blob.js",
20
22
  "sea:linux-x64": "cp node-binaries/linux-x64/node release/wilcocrypt-linux-x64 && npx postject release/wilcocrypt-linux-x64 NODE_SEA_BLOB sea/wilcocrypt.sea --sentinel-fuse NODE_SEA_FUSE_fce680ab2cc467b6e072b8b5df1996b2 && chmod +x release/wilcocrypt-linux-x64",
21
23
  "sea:linux-arm64": "cp node-binaries/linux-arm64/node release/wilcocrypt-linux-arm64 && npx postject release/wilcocrypt-linux-arm64 NODE_SEA_BLOB sea/wilcocrypt.sea --sentinel-fuse NODE_SEA_FUSE_fce680ab2cc467b6e072b8b5df1996b2 && chmod +x release/wilcocrypt-linux-arm64",
@@ -26,14 +28,15 @@
26
28
  "clean": "rm -rf dist && rm -rf sea/*.sea && rm -rf release/*"
27
29
  },
28
30
  "dependencies": {
29
- "commander": "14.0.3",
30
- "notepack.io": "3.0.1"
31
+ "commander": "14.0.3"
31
32
  },
32
33
  "devDependencies": {
33
34
  "@rollup/plugin-commonjs": "29.0.2",
34
35
  "@rollup/plugin-node-resolve": "16.0.3",
35
36
  "@rollup/plugin-replace": "6.0.3",
36
37
  "@rollup/plugin-terser": "1.0.0",
37
- "rollup": "4.60.2"
38
+ "@types/node": "25.6.0",
39
+ "rollup": "4.60.2",
40
+ "semistandard": "17.0.0"
38
41
  }
39
42
  }
package/src/cli.js CHANGED
@@ -1,3 +1,4 @@
1
+ #!/usr/bin/env node
1
2
  import { Command } from 'commander';
2
3
  import wilcocrypt from './wilcocrypt.js';
3
4
 
@@ -5,7 +6,7 @@ import wilcocrypt from './wilcocrypt.js';
5
6
  Helpers
6
7
  ========================= */
7
8
 
8
- function promptPassword(promptText = 'Password: ') {
9
+ function promptPassword (promptText = 'Password: ') {
9
10
  return new Promise((resolve) => {
10
11
  const stdin = process.stdin;
11
12
  const stdout = process.stdout;
@@ -16,7 +17,7 @@ function promptPassword(promptText = 'Password: ') {
16
17
  'NO_TTY'
17
18
  );
18
19
  }
19
-
20
+
20
21
  stdout.write(promptText);
21
22
 
22
23
  let password = '';
@@ -25,7 +26,7 @@ function promptPassword(promptText = 'Password: ') {
25
26
  stdin.resume();
26
27
  stdin.setEncoding('utf8');
27
28
 
28
- function onData(char) {
29
+ function onData (char) {
29
30
  if (char === '\r' || char === '\n') {
30
31
  stdout.write('\n');
31
32
  stdin.setRawMode(false);
@@ -72,6 +73,8 @@ program
72
73
 
73
74
  .option('-e, --encrypt <file>', 'Encrypt file')
74
75
  .option('-d, --decrypt <file>', 'Decrypt file')
76
+ .option('-o, --output <file>', 'Write output to file instead of stdout (decrypt only)')
77
+ .option('--stdout', 'Write decrypted output to stdout (default behavior, explicit flag)')
75
78
 
76
79
  .helpOption('-h, --help', 'Display help');
77
80
 
@@ -85,8 +88,7 @@ const options = program.opts();
85
88
 
86
89
  const actions = [
87
90
  options.encrypt,
88
- options.decrypt,
89
- options.unpack
91
+ options.decrypt
90
92
  ].filter(Boolean);
91
93
 
92
94
  if (actions.length === 0) {
@@ -94,7 +96,17 @@ if (actions.length === 0) {
94
96
  }
95
97
 
96
98
  if (actions.length > 1) {
97
- console.error('error: please specify only one action (-e, -d or --unpack)');
99
+ console.error('error: please specify only one action (-e or -d)');
100
+ process.exit(1);
101
+ }
102
+
103
+ if (options.output && options.stdout) {
104
+ console.error('error: --output and --stdout are mutually exclusive');
105
+ process.exit(1);
106
+ }
107
+
108
+ if (options.output && options.encrypt) {
109
+ console.error('error: --output is only supported for decryption');
98
110
  process.exit(1);
99
111
  }
100
112
 
@@ -113,9 +125,14 @@ if (actions.length > 1) {
113
125
 
114
126
  if (options.decrypt) {
115
127
  const password = await promptPassword('Decryption password: ');
116
- const result = wilcocrypt.decryptFile(options.decrypt, password);
117
- process.stdout.write(result);
118
- return;
128
+
129
+ if (options.output) {
130
+ wilcocrypt.decryptFile(options.decrypt, password, options.output);
131
+ console.log(`Decrypted: ${options.output}`);
132
+ } else {
133
+ const result = wilcocrypt.decryptFile(options.decrypt, password);
134
+ process.stdout.write(result);
135
+ }
119
136
  }
120
137
  } catch (err) {
121
138
  console.error(`error: ${err.message}`);