@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.
Files changed (2) hide show
  1. package/package.json +1 -1
  2. package/server/bootstrap.js +94 -137
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@growy/strapi-plugin-encrypted-field",
3
- "version": "1.6.0",
3
+ "version": "1.7.1",
4
4
  "description": "Campo personalizado de texto cifrado para Strapi",
5
5
  "strapi": {
6
6
  "name": "encrypted-field",
@@ -1,157 +1,114 @@
1
1
  const { encrypt, decrypt, validateValue, isEncryptedField } = require('./utils/crypto');
2
2
 
3
3
  module.exports = ({ strapi }) => {
4
- // Registrar middleware de descifrado
5
- strapi.server.use(async (ctx, next) => {
6
- await next();
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
- if (!ctx.body || !ctx.body.data) return;
12
+ const uid = model.uid;
13
+
14
+ strapi.log.info(`Registrando lifecycles de cifrado para ${uid}`);
9
15
 
10
- const decryptData = (data) => {
11
- if (!data || typeof data !== 'object') return;
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
- if (!model?.attributes) return;
59
-
60
- for (const [key, attribute] of Object.entries(model.attributes)) {
61
- if (!isEncryptedField(attribute)) continue;
62
- if (Object.prototype.hasOwnProperty.call(data, key)) {
63
- const value = data[key];
64
- if (value === null || value === undefined || value === '') continue;
65
-
66
- // No cifrar si ya está cifrado (formato: iv:authTag:encrypted)
67
- if (typeof value === 'string' && value.split(':').length === 3) {
68
- strapi.log.info(`Campo ${key} ya está cifrado, saltando cifrado`);
69
- continue;
70
- }
71
-
72
- const validation = validateValue(value, attribute);
73
- if (!validation.valid) {
74
- throw new Error(`Validación fallida para el campo "${key}": ${validation.error}`);
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
- async beforeUpdate(event) {
84
- if (!event.model?.uid) return;
85
-
86
- const { data } = event.params;
87
- const model = strapi.getModel(event.model.uid);
88
-
89
- if (!model?.attributes) return;
90
-
91
- for (const [key, attribute] of Object.entries(model.attributes)) {
92
- if (!isEncryptedField(attribute)) continue;
93
- if (Object.prototype.hasOwnProperty.call(data, key)) {
94
- const value = data[key];
95
- if (value === null || value === undefined || value === '') continue;
96
-
97
- // No cifrar si ya está cifrado (formato: iv:authTag:encrypted)
98
- if (typeof value === 'string' && value.split(':').length === 3) {
99
- strapi.log.info(`Campo ${key} ya está cifrado, saltando cifrado`);
100
- continue;
101
- }
102
-
103
- const validation = validateValue(value, attribute);
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
- async afterFindOne(event) {
115
- const { result } = event;
116
- if (!result) return;
117
- if (!event.model?.uid) return;
118
-
119
- const model = strapi.getModel(event.model.uid);
120
-
121
- if (!model?.attributes) return;
122
-
123
- for (const [key, attribute] of Object.entries(model.attributes)) {
124
- if (!isEncryptedField(attribute)) continue;
125
- if (Object.prototype.hasOwnProperty.call(result, key)) {
126
- const value = result[key];
127
- if (typeof value === 'string' && value) {
128
- strapi.log.info(`Descifrando campo ${key} en ${event.model.uid}`);
129
- result[key] = decrypt(value, strapi);
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
- async afterFindMany(event) {
136
- const { result } = event;
137
- if (!result || !Array.isArray(result)) return;
138
- if (!event.model?.uid) return;
139
-
140
- const model = strapi.getModel(event.model.uid);
141
-
142
- if (!model?.attributes) return;
143
-
144
- for (const item of result) {
145
- for (const [key, attribute] of Object.entries(model.attributes)) {
146
- if (!isEncryptedField(attribute)) continue;
147
- if (Object.prototype.hasOwnProperty.call(item, key)) {
148
- const value = item[key];
149
- if (typeof value === 'string' && value) {
150
- item[key] = decrypt(value, strapi);
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
  };