@growy/strapi-plugin-encrypted-field 1.6.0 → 1.7.1
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/package.json +1 -1
- package/server/bootstrap.js +94 -137
package/package.json
CHANGED
package/server/bootstrap.js
CHANGED
|
@@ -1,157 +1,114 @@
|
|
|
1
1
|
const { encrypt, decrypt, validateValue, isEncryptedField } = require('./utils/crypto');
|
|
2
2
|
|
|
3
3
|
module.exports = ({ strapi }) => {
|
|
4
|
-
|
|
5
|
-
strapi.
|
|
6
|
-
|
|
4
|
+
|
|
5
|
+
const models = Object.values(strapi.contentTypes);
|
|
6
|
+
|
|
7
|
+
models.forEach((model) => {
|
|
8
|
+
const hasEncryptedFields = Object.values(model.attributes || {}).some(isEncryptedField);
|
|
9
|
+
|
|
10
|
+
if (!hasEncryptedFields) return;
|
|
7
11
|
|
|
8
|
-
|
|
12
|
+
const uid = model.uid;
|
|
13
|
+
|
|
14
|
+
strapi.log.info(`Registrando lifecycles de cifrado para ${uid}`);
|
|
9
15
|
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
// Intentar obtener el modelo del content type
|
|
14
|
-
const uid = ctx.state?.route?.info?.apiName
|
|
15
|
-
? `api::${ctx.state.route.info.apiName}.${ctx.state.route.info.apiName}`
|
|
16
|
-
: null;
|
|
17
|
-
|
|
18
|
-
if (!uid) return;
|
|
19
|
-
|
|
20
|
-
let model;
|
|
21
|
-
try {
|
|
22
|
-
model = strapi.getModel(uid);
|
|
23
|
-
} catch (e) {
|
|
24
|
-
return;
|
|
25
|
-
}
|
|
26
|
-
|
|
27
|
-
if (!model?.attributes) return;
|
|
28
|
-
|
|
29
|
-
for (const [key, attribute] of Object.entries(model.attributes)) {
|
|
30
|
-
if (!isEncryptedField(attribute)) continue;
|
|
31
|
-
|
|
32
|
-
if (data[key] && typeof data[key] === 'string') {
|
|
33
|
-
try {
|
|
34
|
-
const decrypted = decrypt(data[key], strapi);
|
|
35
|
-
strapi.log.info(`Descifrando campo ${key} en respuesta API`);
|
|
36
|
-
data[key] = decrypted;
|
|
37
|
-
} catch (error) {
|
|
38
|
-
strapi.log.error(`Error descifrando campo ${key}: ${error.message}`);
|
|
39
|
-
}
|
|
40
|
-
}
|
|
41
|
-
}
|
|
42
|
-
};
|
|
43
|
-
|
|
44
|
-
if (Array.isArray(ctx.body.data)) {
|
|
45
|
-
ctx.body.data.forEach(decryptData);
|
|
46
|
-
} else {
|
|
47
|
-
decryptData(ctx.body.data);
|
|
48
|
-
}
|
|
49
|
-
});
|
|
50
|
-
|
|
51
|
-
strapi.db.lifecycles.subscribe({
|
|
52
|
-
async beforeCreate(event) {
|
|
53
|
-
if (!event.model?.uid) return;
|
|
54
|
-
|
|
55
|
-
const { data } = event.params;
|
|
56
|
-
const model = strapi.getModel(event.model.uid);
|
|
16
|
+
|
|
17
|
+
strapi.db.lifecycles.subscribe({
|
|
18
|
+
models: [uid],
|
|
57
19
|
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
if (
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
20
|
+
async beforeCreate(event) {
|
|
21
|
+
if (!event.model?.uid) return;
|
|
22
|
+
|
|
23
|
+
const { data } = event.params;
|
|
24
|
+
const currentModel = strapi.getModel(event.model.uid);
|
|
25
|
+
|
|
26
|
+
if (!currentModel?.attributes) return;
|
|
27
|
+
|
|
28
|
+
for (const [key, attribute] of Object.entries(currentModel.attributes)) {
|
|
29
|
+
if (!isEncryptedField(attribute)) continue;
|
|
30
|
+
if (Object.prototype.hasOwnProperty.call(data, key)) {
|
|
31
|
+
const value = data[key];
|
|
32
|
+
if (value === null || value === undefined || value === '') continue;
|
|
33
|
+
|
|
34
|
+
const validation = validateValue(value, attribute);
|
|
35
|
+
if (!validation.valid) {
|
|
36
|
+
throw new Error(`Validación fallida para el campo "${key}": ${validation.error}`);
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
strapi.log.info(`Cifrando campo ${key} en ${event.model.uid}`);
|
|
40
|
+
data[key] = encrypt(value, strapi);
|
|
75
41
|
}
|
|
76
|
-
|
|
77
|
-
strapi.log.info(`Cifrando campo ${key} en ${event.model.uid}`);
|
|
78
|
-
data[key] = encrypt(value, strapi);
|
|
79
42
|
}
|
|
80
|
-
}
|
|
81
|
-
},
|
|
43
|
+
},
|
|
82
44
|
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
if (!validation.valid) {
|
|
105
|
-
throw new Error(`Validación fallida para el campo "${key}": ${validation.error}`);
|
|
45
|
+
async beforeUpdate(event) {
|
|
46
|
+
if (!event.model?.uid) return;
|
|
47
|
+
|
|
48
|
+
const { data } = event.params;
|
|
49
|
+
const currentModel = strapi.getModel(event.model.uid);
|
|
50
|
+
|
|
51
|
+
if (!currentModel?.attributes) return;
|
|
52
|
+
|
|
53
|
+
for (const [key, attribute] of Object.entries(currentModel.attributes)) {
|
|
54
|
+
if (!isEncryptedField(attribute)) continue;
|
|
55
|
+
if (Object.prototype.hasOwnProperty.call(data, key)) {
|
|
56
|
+
const value = data[key];
|
|
57
|
+
if (value === null || value === undefined || value === '') continue;
|
|
58
|
+
|
|
59
|
+
const validation = validateValue(value, attribute);
|
|
60
|
+
if (!validation.valid) {
|
|
61
|
+
throw new Error(`Validación fallida para el campo "${key}": ${validation.error}`);
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
strapi.log.info(`Cifrando campo ${key} en ${event.model.uid}`);
|
|
65
|
+
data[key] = encrypt(value, strapi);
|
|
106
66
|
}
|
|
107
|
-
|
|
108
|
-
strapi.log.info(`Cifrando campo ${key} en ${event.model.uid}`);
|
|
109
|
-
data[key] = encrypt(value, strapi);
|
|
110
67
|
}
|
|
111
|
-
}
|
|
112
|
-
},
|
|
68
|
+
},
|
|
113
69
|
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
70
|
+
async afterFindOne(event) {
|
|
71
|
+
const { result } = event;
|
|
72
|
+
if (!result) return;
|
|
73
|
+
if (!event.model?.uid) return;
|
|
74
|
+
|
|
75
|
+
const currentModel = strapi.getModel(event.model.uid);
|
|
76
|
+
|
|
77
|
+
if (!currentModel?.attributes) return;
|
|
78
|
+
|
|
79
|
+
for (const [key, attribute] of Object.entries(currentModel.attributes)) {
|
|
80
|
+
if (!isEncryptedField(attribute)) continue;
|
|
81
|
+
if (Object.prototype.hasOwnProperty.call(result, key)) {
|
|
82
|
+
const value = result[key];
|
|
83
|
+
if (typeof value === 'string' && value) {
|
|
84
|
+
strapi.log.info(`Descifrando campo ${key} en ${event.model.uid}`);
|
|
85
|
+
result[key] = decrypt(value, strapi);
|
|
86
|
+
}
|
|
130
87
|
}
|
|
131
88
|
}
|
|
132
|
-
}
|
|
133
|
-
},
|
|
89
|
+
},
|
|
134
90
|
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
91
|
+
async afterFindMany(event) {
|
|
92
|
+
const { result } = event;
|
|
93
|
+
if (!result || !Array.isArray(result)) return;
|
|
94
|
+
if (!event.model?.uid) return;
|
|
95
|
+
|
|
96
|
+
const currentModel = strapi.getModel(event.model.uid);
|
|
97
|
+
|
|
98
|
+
if (!currentModel?.attributes) return;
|
|
99
|
+
|
|
100
|
+
for (const item of result) {
|
|
101
|
+
for (const [key, attribute] of Object.entries(currentModel.attributes)) {
|
|
102
|
+
if (!isEncryptedField(attribute)) continue;
|
|
103
|
+
if (Object.prototype.hasOwnProperty.call(item, key)) {
|
|
104
|
+
const value = item[key];
|
|
105
|
+
if (typeof value === 'string' && value) {
|
|
106
|
+
item[key] = decrypt(value, strapi);
|
|
107
|
+
}
|
|
151
108
|
}
|
|
152
109
|
}
|
|
153
110
|
}
|
|
154
|
-
}
|
|
155
|
-
}
|
|
111
|
+
},
|
|
112
|
+
});
|
|
156
113
|
});
|
|
157
114
|
};
|