@growy/strapi-plugin-encrypted-field 2.4.2 → 2.4.3

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.
Files changed (3) hide show
  1. package/CHANGELOG.md +5 -0
  2. package/README.md +58 -55
  3. package/package.json +1 -1
package/CHANGELOG.md CHANGED
@@ -2,6 +2,11 @@
2
2
 
3
3
  All notable changes to this project will be documented in this file.
4
4
 
5
+ ## [2.4.3] - 2026-02-26
6
+
7
+ ### Changed
8
+ - README full consistency review: Node.js requirement corrected to 23.x, redundant feature bullets consolidated, Option B clarified, rebuild step scoped to first install only, Key Rotation guide expanded with multi-line command for readability.
9
+
5
10
  ## [2.4.2] - 2026-02-26
6
11
 
7
12
  ### Changed
package/README.md CHANGED
@@ -12,15 +12,20 @@ Official **Growy AI** plugin for Strapi that provides a custom encrypted text fi
12
12
  - ✅ **Automatic encryption** AES-256-GCM on save
13
13
  - ✅ **Transparent decryption** on read (admin panel and API)
14
14
  - ✅ **Backend validation** with regex and length constraint support
15
- - ✅ **Native Strapi v5 UI** with visibility controls, resizable inputs and copy to clipboard
16
- - ✅ **Values hidden** by default with show/hide toggle
17
- - ✅ **Copy notifications** confirmation when copying values
18
- - ✅ **Multi-language support (i18n)**: English and Spanish
15
+ - ✅ **Admin UI** with show/hide toggle, resizable inputs and copy to clipboard
16
+ - ✅ **Copy notifications** with confirmation toast when copying values
17
+ - ✅ **Multi-language support (i18n)**: English and Spanish in the admin panel
19
18
  - ✅ **Robust key management** with validation and clear error messages
20
19
  - ✅ **Encrypted data** in database with unique IV and Auth Tag per operation
21
20
  - ✅ **Reusable** in any collection or component
22
21
  - ✅ **Full support** for nested components and complex structures
23
22
 
23
+ ## Requirements
24
+
25
+ - **Strapi**: v5.0.0 or higher
26
+ - **Node.js**: 18.x - 23.x
27
+ - **npm**: 6.0.0 or higher
28
+
24
29
  ## Installation
25
30
 
26
31
  ```bash
@@ -55,14 +60,14 @@ ENCRYPTION_KEY=your_64_character_hex_key_here
55
60
 
56
61
  #### Option B: Configuration file
57
62
 
58
- Edit `config/plugins.js`:
63
+ Use this option if you need to read the key from a different environment variable name or from a secrets provider:
59
64
 
60
65
  ```javascript
61
66
  module.exports = ({ env }) => ({
62
67
  'encrypted-field': {
63
68
  enabled: true,
64
69
  config: {
65
- encryptionKey: env('ENCRYPTION_KEY'),
70
+ encryptionKey: env('MY_CUSTOM_SECRET_KEY'),
66
71
  },
67
72
  },
68
73
  });
@@ -70,11 +75,13 @@ module.exports = ({ env }) => ({
70
75
 
71
76
  #### Generate a secure key
72
77
 
78
+ Run this command once to generate a valid key:
79
+
73
80
  ```bash
74
81
  node -e "console.log(require('crypto').randomBytes(32).toString('hex'))"
75
82
  ```
76
83
 
77
- This will generate a 64-character hexadecimal key (32 bytes).
84
+ This outputs a 64-character hexadecimal key (32 bytes) ready to use.
78
85
 
79
86
  ⚠️ **CRITICAL - Key Management**:
80
87
  - **Store the key securely** (secrets manager, encrypted environment variables)
@@ -83,37 +90,15 @@ This will generate a 64-character hexadecimal key (32 bytes).
83
90
  - **Use the same key** across all environments sharing the same database
84
91
  - **For production**, consider services like AWS Secrets Manager, HashiCorp Vault or similar
85
92
 
86
- ### 3. Rebuild the admin
93
+ ### 3. Rebuild the admin panel (first install only)
94
+
95
+ After installing the plugin for the first time, rebuild the admin panel:
87
96
 
88
97
  ```bash
89
98
  npm run build
90
99
  npm run develop
91
100
  ```
92
101
 
93
- ## Requirements
94
-
95
- - **Strapi**: v5.0.0 or higher
96
- - **Node.js**: 18.x - 22.x
97
- - **npm**: 6.0.0 or higher
98
-
99
- ## Data Validation
100
-
101
- The plugin supports validation before encryption:
102
-
103
- ### Configure regex validation
104
-
105
- 1. In Content-Type Builder, select the encrypted field
106
- 2. Go to the **"Advanced Settings"** tab
107
- 3. In **"RegEx pattern"**, enter your regular expression
108
- 4. Save the changes
109
-
110
- **Example**: To validate API key format:
111
- ```regex
112
- ^sk-[a-zA-Z0-9]{32}$
113
- ```
114
-
115
- If the value does not match the pattern, an error will be thrown before encryption.
116
-
117
102
  ## Usage
118
103
 
119
104
  ### 1. Add an encrypted field to a collection
@@ -125,23 +110,24 @@ If the value does not match the pattern, an error will be thrown before encrypti
125
110
  5. Set the field name
126
111
  6. Save and restart Strapi
127
112
 
128
- ### 2. Using the field
113
+ ### 2. Using the field in the admin panel
129
114
 
130
115
  The field works like a regular text field with additional security features:
131
116
 
132
- - **In the panel**: Type text normally
133
- - **Hidden values**: Values are shown as `***` by default
117
+ - **Values are hidden** by default (shown as `***`)
134
118
  - **Eye button**: Toggles between show/hide the value
135
119
  - **Copy button**: Copies the value to clipboard with a confirmation notification
136
- - **On save**: Automatically encrypted
137
- - **On read**: Automatically decrypted
138
- - **In the DB**: Stored encrypted with format `iv:authTag:encrypted`
120
+ - **On save**: Value is automatically encrypted before storing
121
+ - **On read**: Value is automatically decrypted before displaying
122
+ - **In the DB**: Stored as `iv:authTag:encryptedText` (unreadable without the key)
139
123
  - **In components**: Works the same in nested components at any depth
140
124
 
141
125
  ### 3. API Usage
142
126
 
127
+ The API always returns **decrypted** values for authorized requests. You write plain text, the plugin handles encryption transparently.
128
+
143
129
  ```bash
144
- # Create with an encrypted field
130
+ # Create an entry with an encrypted field
145
131
  curl -X POST http://localhost:1337/api/users \
146
132
  -H "Content-Type: application/json" \
147
133
  -d '{
@@ -151,11 +137,27 @@ curl -X POST http://localhost:1337/api/users \
151
137
  }
152
138
  }'
153
139
 
154
- # Read (returns decrypted)
140
+ # Read (automatically returns decrypted)
155
141
  curl -X GET http://localhost:1337/api/users/1
156
142
  # Response: { "name": "John", "apiKey": "my-secret-key-123" }
157
143
  ```
158
144
 
145
+ ## Data Validation
146
+
147
+ The plugin supports validation before encryption. If validation fails, the value is rejected before being encrypted or saved.
148
+
149
+ ### Configure regex validation
150
+
151
+ 1. In Content-Type Builder, select the encrypted field
152
+ 2. Go to the **"Advanced Settings"** tab
153
+ 3. In **"RegEx pattern"**, enter your regular expression
154
+ 4. Save the changes
155
+
156
+ **Example**: To only accept values that look like an API key:
157
+ ```regex
158
+ ^sk-[a-zA-Z0-9]{32}$
159
+ ```
160
+
159
161
  ## Usage Example
160
162
 
161
163
  ### "User" collection with an encrypted API Key
@@ -169,12 +171,12 @@ curl -X GET http://localhost:1337/api/users/1
169
171
  }
170
172
  ```
171
173
 
172
- **In the DB:**
174
+ **What gets stored in the DB:**
173
175
  ```
174
176
  apiKey: "a1b2c3d4e5f6....:f9e8d7c6b5a4....:9f8e7d6c5b4a3..."
175
177
  ```
176
178
 
177
- **In the panel and API:**
179
+ **What the admin panel and API show:**
178
180
  ```
179
181
  apiKey: "sk-1234567890abcdef"
180
182
  ```
@@ -194,14 +196,14 @@ apiKey: "sk-1234567890abcdef"
194
196
 
195
197
  - ✅ **Authenticated encryption**: GCM provides both confidentiality and integrity
196
198
  - ✅ **Unique IV**: Every encryption operation generates a random IV
197
- - ✅ **Tamper resistance**: Auth Tag detects any modification
199
+ - ✅ **Tamper resistance**: Auth Tag detects any modification to the ciphertext
198
200
  - ✅ **Input validation**: Regex and custom constraints supported
199
201
  - ✅ **Safe error handling**: Controlled logs without exposing sensitive data
200
202
  - ✅ **Double-layer decryption**: Lifecycle hooks (internal) + middleware (API responses)
201
203
 
202
204
  ### Best Practices
203
205
 
204
- 1. **Key rotation**: Use the included rotation script (see below)
206
+ 1. **Key rotation**: Use the included rotation script when changing keys (see below)
205
207
  2. **Environment separation**: Use different keys per dev/staging/prod
206
208
  3. **Auditing**: Monitor encryption/decryption error logs
207
209
  4. **Key backup**: Keep secure copies of keys in multiple locations
@@ -209,30 +211,31 @@ apiKey: "sk-1234567890abcdef"
209
211
 
210
212
  ### Key Rotation (Preventing Data Loss)
211
213
 
212
- ⚠️ **IMPORTANT**: If you change `ENCRYPTION_KEY` in your `.env` without re-encrypting your data first, **all existing data will become unreadable**.
214
+ ⚠️ **IMPORTANT**: If you change `ENCRYPTION_KEY` in your `.env` without re-encrypting your data first, **all existing data will become permanently unreadable**.
213
215
 
214
- #### Safe Rotation Process:
216
+ Follow this safe process to rotate your key:
215
217
 
216
- 1. **Keep your OLD key** accessible for a moment.
218
+ 1. **Keep your OLD key** do not remove it yet.
217
219
  2. **Generate a NEW key** (64-character hexadecimal).
218
220
  3. **Export the encrypted values** from your database.
219
221
  4. **Run the rotation script** included in this plugin:
220
222
  ```bash
221
- # From your project root
222
- node node_modules/@growy/strapi-plugin-encrypted-field/scripts/rotate-key.js --old=<OLD_KEY> --new=<NEW_KEY>
223
+ # From your Strapi project root
224
+ node node_modules/@growy/strapi-plugin-encrypted-field/scripts/rotate-key.js \
225
+ --old=<YOUR_CURRENT_64_CHAR_KEY> \
226
+ --new=<YOUR_NEW_64_CHAR_KEY>
223
227
  ```
224
- 5. **Update your database** with the new encrypted values returned by the script.
225
- 6. **Update your `.env`** with the `NEW_KEY`.
228
+ The script reads encrypted values from stdin, decrypts with the old key, and re-encrypts with the new key, writing the results to stdout.
229
+ 5. **Update your database** with the new encrypted values output by the script.
230
+ 6. **Update your `.env`** with the `NEW_KEY` and remove the old one.
226
231
  7. **Restart Strapi**.
227
232
 
228
- The script works as a pipe (stdin to stdout). See the script output or documentation for database-specific integration examples (e.g., PostgreSQL loops).
229
-
230
233
  ## Use Cases
231
234
 
232
235
  - 🔑 Third-party API Keys
233
236
  - 🔐 Access tokens
234
237
  - 🔒 Webhook secrets
235
- - 💳 Sensitive information
238
+ - 💳 Payment or sensitive information
236
239
  - 📧 SMTP credentials
237
240
  - 🔑 Application passwords
238
241
 
@@ -241,7 +244,7 @@ The script works as a pipe (stdin to stdout). See the script output or documenta
241
244
  - ❌ **Search**: Cannot search by encrypted fields (data is encrypted in DB)
242
245
  - ❌ **Sorting**: Cannot sort by encrypted fields
243
246
  - ❌ **Filters**: Cannot apply direct filters on encrypted fields
244
- - ❌ **Unique constraint**: Strapi's unique validation will not work correctly on encrypted fields because each encryption produces a different ciphertext (random IV)
247
+ - ❌ **Unique constraint**: Strapi's unique validation will not work correctly on encrypted fields because each encryption produces different ciphertext (random IV)
245
248
  - ⚠️ **Performance**: Encryption/decryption adds minimal overhead (~1-2ms per operation)
246
249
  - ⚠️ **Key synchronization**: All environments sharing the same DB must use the same key
247
250
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@growy/strapi-plugin-encrypted-field",
3
- "version": "2.4.2",
3
+ "version": "2.4.3",
4
4
  "description": "Custom encrypted text field plugin for Strapi using AES-256-GCM",
5
5
  "strapi": {
6
6
  "name": "encrypted-field",