@growy/strapi-plugin-encrypted-field 2.3.1 → 2.3.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.
- package/README.md +168 -86
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -6,29 +6,22 @@
|
|
|
6
6
|
<img src="https://img.shields.io/badge/Strapi-v5-blueviolet" alt="Strapi v5" />
|
|
7
7
|
</div>
|
|
8
8
|
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
- ✅ **
|
|
22
|
-
- ✅ **
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
- ✅ **Native Strapi v5 UI** with visibility controls and copy to clipboard.
|
|
26
|
-
- ✅ **Multi-language support (i18n)**: English and Spanish.
|
|
27
|
-
- ✅ **Secure Key Management** with validation and clear error messages.
|
|
28
|
-
- ✅ **Encrypted Data** in database with unique IV and Auth Tag.
|
|
29
|
-
- ✅ **Nested Components support** at any depth.
|
|
30
|
-
|
|
31
|
-
### Installation
|
|
9
|
+
Official **Growy AI** plugin for Strapi that provides a custom encrypted text field using AES-256-GCM. Protect sensitive information directly in your database with transparent encryption and robust validation.
|
|
10
|
+
|
|
11
|
+
- ✅ **Custom field** "Encrypted Text" in the Content-Type Builder
|
|
12
|
+
- ✅ **Automatic encryption** AES-256-GCM on save
|
|
13
|
+
- ✅ **Transparent decryption** on read (admin panel and API)
|
|
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
|
|
19
|
+
- ✅ **Robust key management** with validation and clear error messages
|
|
20
|
+
- ✅ **Encrypted data** in database with unique IV and Auth Tag per operation
|
|
21
|
+
- ✅ **Reusable** in any collection or component
|
|
22
|
+
- ✅ **Full support** for nested components and complex structures
|
|
23
|
+
|
|
24
|
+
## Installation
|
|
32
25
|
|
|
33
26
|
```bash
|
|
34
27
|
npm install @growy/strapi-plugin-encrypted-field
|
|
@@ -36,9 +29,9 @@ npm install @growy/strapi-plugin-encrypted-field
|
|
|
36
29
|
yarn add @growy/strapi-plugin-encrypted-field
|
|
37
30
|
```
|
|
38
31
|
|
|
39
|
-
|
|
32
|
+
## Configuration
|
|
40
33
|
|
|
41
|
-
|
|
34
|
+
### 1. Enable the plugin
|
|
42
35
|
|
|
43
36
|
Create or edit `config/plugins.js` or `config/plugins.ts`:
|
|
44
37
|
|
|
@@ -50,7 +43,9 @@ module.exports = {
|
|
|
50
43
|
};
|
|
51
44
|
```
|
|
52
45
|
|
|
53
|
-
|
|
46
|
+
### 2. Configure the encryption key (REQUIRED)
|
|
47
|
+
|
|
48
|
+
#### Option A: Environment variable (recommended)
|
|
54
49
|
|
|
55
50
|
Add to your `.env`:
|
|
56
51
|
|
|
@@ -58,103 +53,190 @@ Add to your `.env`:
|
|
|
58
53
|
ENCRYPTION_KEY=your_64_character_hex_key_here
|
|
59
54
|
```
|
|
60
55
|
|
|
61
|
-
|
|
56
|
+
#### Option B: Configuration file
|
|
57
|
+
|
|
58
|
+
Edit `config/plugins.js`:
|
|
59
|
+
|
|
60
|
+
```javascript
|
|
61
|
+
module.exports = ({ env }) => ({
|
|
62
|
+
'encrypted-field': {
|
|
63
|
+
enabled: true,
|
|
64
|
+
config: {
|
|
65
|
+
encryptionKey: env('ENCRYPTION_KEY'),
|
|
66
|
+
},
|
|
67
|
+
},
|
|
68
|
+
});
|
|
69
|
+
```
|
|
70
|
+
|
|
71
|
+
#### Generate a secure key
|
|
72
|
+
|
|
62
73
|
```bash
|
|
63
74
|
node -e "console.log(require('crypto').randomBytes(32).toString('hex'))"
|
|
64
75
|
```
|
|
65
76
|
|
|
66
|
-
|
|
77
|
+
This will generate a 64-character hexadecimal key (32 bytes).
|
|
67
78
|
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
79
|
+
⚠️ **CRITICAL - Key Management**:
|
|
80
|
+
- **Store the key securely** (secrets manager, encrypted environment variables)
|
|
81
|
+
- **Never** include it in version control
|
|
82
|
+
- **If you lose the key**, you will not be able to decrypt existing data
|
|
83
|
+
- **Use the same key** across all environments sharing the same database
|
|
84
|
+
- **For production**, consider services like AWS Secrets Manager, HashiCorp Vault or similar
|
|
73
85
|
|
|
74
|
-
|
|
86
|
+
### 3. Rebuild the admin
|
|
75
87
|
|
|
76
|
-
|
|
88
|
+
```bash
|
|
89
|
+
npm run build
|
|
90
|
+
npm run develop
|
|
91
|
+
```
|
|
77
92
|
|
|
78
|
-
|
|
93
|
+
## Requirements
|
|
79
94
|
|
|
80
|
-
|
|
95
|
+
- **Strapi**: v5.0.0 or higher
|
|
96
|
+
- **Node.js**: 18.x - 22.x
|
|
97
|
+
- **npm**: 6.0.0 or higher
|
|
81
98
|
|
|
82
|
-
|
|
83
|
-
- ✅ **Cifrado automático** AES-256-GCM al guardar.
|
|
84
|
-
- ✅ **Descifrado transparente** al leer (panel y API).
|
|
85
|
-
- ✅ **Validación backend** con soporte para regex y restricciones.
|
|
86
|
-
- ✅ **UI Nativa Strapi v5** con controles de visibilidad y copiar al portapapeles.
|
|
87
|
-
- ✅ **Soporte multi-idioma (i18n)**: Inglés y Español.
|
|
88
|
-
- ✅ **Gestión de claves robusta** con validación y mensajes de error claros.
|
|
89
|
-
- ✅ **Datos cifrados** en base de datos con IV único y Auth Tag.
|
|
90
|
-
- ✅ **Soporte para componentes anidados** a cualquier profundidad.
|
|
99
|
+
## Data Validation
|
|
91
100
|
|
|
92
|
-
|
|
101
|
+
The plugin supports validation before encryption:
|
|
93
102
|
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
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}$
|
|
98
113
|
```
|
|
99
114
|
|
|
100
|
-
|
|
115
|
+
If the value does not match the pattern, an error will be thrown before encryption.
|
|
101
116
|
|
|
102
|
-
|
|
117
|
+
## Usage
|
|
103
118
|
|
|
104
|
-
|
|
119
|
+
### 1. Add an encrypted field to a collection
|
|
105
120
|
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
121
|
+
1. Go to **Content-Type Builder**
|
|
122
|
+
2. Select a collection or create a new one
|
|
123
|
+
3. Click **"Add another field"**
|
|
124
|
+
4. Search for **"Encrypted Text"** (with 🔒 icon)
|
|
125
|
+
5. Set the field name
|
|
126
|
+
6. Save and restart Strapi
|
|
127
|
+
|
|
128
|
+
### 2. Using the field
|
|
129
|
+
|
|
130
|
+
The field works like a regular text field with additional security features:
|
|
113
131
|
|
|
114
|
-
|
|
132
|
+
- **In the panel**: Type text normally
|
|
133
|
+
- **Hidden values**: Values are shown as `***` by default
|
|
134
|
+
- **Eye button**: Toggles between show/hide the value
|
|
135
|
+
- **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`
|
|
139
|
+
- **In components**: Works the same in nested components at any depth
|
|
115
140
|
|
|
116
|
-
|
|
141
|
+
### 3. API Usage
|
|
117
142
|
|
|
118
143
|
```bash
|
|
119
|
-
|
|
144
|
+
# Create with an encrypted field
|
|
145
|
+
curl -X POST http://localhost:1337/api/users \
|
|
146
|
+
-H "Content-Type: application/json" \
|
|
147
|
+
-d '{
|
|
148
|
+
"data": {
|
|
149
|
+
"name": "John",
|
|
150
|
+
"apiKey": "my-secret-key-123"
|
|
151
|
+
}
|
|
152
|
+
}'
|
|
153
|
+
|
|
154
|
+
# Read (returns decrypted)
|
|
155
|
+
curl -X GET http://localhost:1337/api/users/1
|
|
156
|
+
# Response: { "name": "John", "apiKey": "my-secret-key-123" }
|
|
120
157
|
```
|
|
121
158
|
|
|
122
|
-
|
|
159
|
+
## Usage Example
|
|
123
160
|
|
|
124
|
-
|
|
125
|
-
2. Selecciona una colección.
|
|
126
|
-
3. Click en **"Add another field"**.
|
|
127
|
-
4. Selecciona **"Texto Cifrado"** (icono 🔒).
|
|
128
|
-
5. Los valores están ocultos por defecto en el panel pero pueden mostrarse o copiarse con los botones integrados.
|
|
161
|
+
### "User" collection with an encrypted API Key
|
|
129
162
|
|
|
130
|
-
|
|
163
|
+
**Schema:**
|
|
164
|
+
```json
|
|
165
|
+
{
|
|
166
|
+
"name": "string",
|
|
167
|
+
"email": "email",
|
|
168
|
+
"apiKey": "plugin::encrypted-field.encrypted-text"
|
|
169
|
+
}
|
|
170
|
+
```
|
|
131
171
|
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
172
|
+
**In the DB:**
|
|
173
|
+
```
|
|
174
|
+
apiKey: "a1b2c3d4e5f6....:f9e8d7c6b5a4....:9f8e7d6c5b4a3..."
|
|
175
|
+
```
|
|
136
176
|
|
|
137
|
-
|
|
177
|
+
**In the panel and API:**
|
|
178
|
+
```
|
|
179
|
+
apiKey: "sk-1234567890abcdef"
|
|
180
|
+
```
|
|
138
181
|
|
|
139
|
-
|
|
140
|
-
- ❌ **Ordenamiento**: No se puede ordenar por campos cifrados.
|
|
141
|
-
- ❌ **Filtros**: No se pueden aplicar filtros directos sobre datos cifrados.
|
|
182
|
+
## Security & Architecture
|
|
142
183
|
|
|
143
|
-
|
|
184
|
+
### Technical Specifications
|
|
185
|
+
|
|
186
|
+
- **Algorithm**: AES-256-GCM (NIST standard, military grade)
|
|
187
|
+
- **Key size**: 256 bits (32 bytes, 64 hex characters)
|
|
188
|
+
- **IV (Initialization Vector)**: 96 bits (12 bytes) randomly generated per operation
|
|
189
|
+
- **Auth Tag**: 128 bits (16 bytes) for integrity verification
|
|
190
|
+
- **Stored format**: `iv:authTag:encryptedData` (all in hexadecimal)
|
|
191
|
+
- **Key caching**: Encryption key is parsed and cached in memory for optimal performance
|
|
192
|
+
|
|
193
|
+
### Security Features
|
|
194
|
+
|
|
195
|
+
- ✅ **Authenticated encryption**: GCM provides both confidentiality and integrity
|
|
196
|
+
- ✅ **Unique IV**: Every encryption operation generates a random IV
|
|
197
|
+
- ✅ **Tamper resistance**: Auth Tag detects any modification
|
|
198
|
+
- ✅ **Input validation**: Regex and custom constraints supported
|
|
199
|
+
- ✅ **Safe error handling**: Controlled logs without exposing sensitive data
|
|
200
|
+
- ✅ **Double-layer decryption**: Lifecycle hooks (internal) + middleware (API responses)
|
|
201
|
+
|
|
202
|
+
### Best Practices
|
|
203
|
+
|
|
204
|
+
1. **Key rotation**: Plan a periodic rotation process
|
|
205
|
+
2. **Environment separation**: Use different keys per dev/staging/prod
|
|
206
|
+
3. **Auditing**: Monitor encryption/decryption error logs
|
|
207
|
+
4. **Key backup**: Keep secure copies of keys in multiple locations
|
|
208
|
+
5. **Private fields**: Mark sensitive fields as "private" to exclude them from the public API
|
|
209
|
+
|
|
210
|
+
## Use Cases
|
|
211
|
+
|
|
212
|
+
- 🔑 Third-party API Keys
|
|
213
|
+
- 🔐 Access tokens
|
|
214
|
+
- 🔒 Webhook secrets
|
|
215
|
+
- 💳 Sensitive information
|
|
216
|
+
- 📧 SMTP credentials
|
|
217
|
+
- 🔑 Application passwords
|
|
218
|
+
|
|
219
|
+
## Known Limitations
|
|
220
|
+
|
|
221
|
+
- ❌ **Search**: Cannot search by encrypted fields (data is encrypted in DB)
|
|
222
|
+
- ❌ **Sorting**: Cannot sort by encrypted fields
|
|
223
|
+
- ❌ **Filters**: Cannot apply direct filters on encrypted fields
|
|
224
|
+
- ⚠️ **Performance**: Encryption/decryption adds minimal overhead (~1-2ms per operation)
|
|
225
|
+
- ⚠️ **Key synchronization**: All environments sharing the same DB must use the same key
|
|
144
226
|
|
|
145
|
-
## License
|
|
227
|
+
## License
|
|
146
228
|
|
|
147
229
|
MIT © 2025 Growy AI
|
|
148
230
|
|
|
149
|
-
##
|
|
231
|
+
## Developed by
|
|
150
232
|
|
|
151
|
-
**Growy AI** -
|
|
233
|
+
**Growy AI** - AI and business automation solutions
|
|
152
234
|
|
|
153
|
-
**Main
|
|
235
|
+
**Main author**: Zahir El isaac
|
|
154
236
|
|
|
155
237
|
---
|
|
156
238
|
|
|
157
239
|
<div align="center">
|
|
158
|
-
<p>If this plugin is useful to you, consider giving it a ⭐ on GitHub
|
|
159
|
-
<p>Made with ❤️ by Growy AI
|
|
240
|
+
<p>If this plugin is useful to you, consider giving it a ⭐ on GitHub</p>
|
|
241
|
+
<p>Made with ❤️ by the Growy AI team</p>
|
|
160
242
|
</div>
|