aziendasanitaria-utils 1.2.21 → 1.2.23

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 CHANGED
@@ -3,7 +3,7 @@
3
3
  "engines": {
4
4
  "node": ">=14.0.0"
5
5
  },
6
- "version": "1.2.21",
6
+ "version": "1.2.23",
7
7
  "repository": "deduzzo/aziendasanitaria-utils",
8
8
  "description": "Un utility per gestire i flussi sanitari Siciliani e non solo..",
9
9
  "main": "index.js",
@@ -33,6 +33,7 @@
33
33
  "chokidar": "^4.0.3",
34
34
  "cli-progress": "^3.12.0",
35
35
  "cli-progress-footer": "^2.3.3",
36
+ "crypto": "^1.0.1",
36
37
  "docx": "^9.1.1",
37
38
  "eml-format": "^0.6.1",
38
39
  "excel-date-to-js": "^1.1.5",
@@ -0,0 +1,135 @@
1
+ import crypto from 'crypto';
2
+
3
+ export const ENVELOPE_VERSION = "V1";
4
+
5
+ export default class CryptHelper {
6
+
7
+ static generateIv() {
8
+ return crypto.randomBytes(16);
9
+ }
10
+
11
+ static async RSAGenerateKeyPair() {
12
+ const {publicKey, privateKey} = await crypto.generateKeyPairSync('rsa', {
13
+ modulusLength: 2048,
14
+ publicKeyEncoding: {
15
+ type: 'spki',
16
+ format: 'pem'
17
+ },
18
+ privateKeyEncoding: {
19
+ type: 'pkcs8',
20
+ format: 'pem'
21
+ }
22
+ });
23
+ return {publicKey, privateKey};
24
+ }
25
+
26
+ static RSAEncrypt(data, publicKey) {
27
+ const bufferData = Buffer.from(data, 'utf8'); // Convert string to Buffer
28
+ const encrypted = crypto.publicEncrypt({
29
+ key: publicKey,
30
+ padding: crypto.constants.RSA_PKCS1_OAEP_PADDING
31
+ }, bufferData);
32
+ return encrypted.toString('base64'); // Return as base64 string for easy storage/transfer
33
+ }
34
+
35
+ static RSADecrypt(data, privateKey) {
36
+ const bufferData = Buffer.from(data, 'base64'); // Convert base64 string to Buffer
37
+ const decrypted = crypto.privateDecrypt({
38
+ key: privateKey,
39
+ padding: crypto.constants.RSA_PKCS1_OAEP_PADDING
40
+ }, bufferData);
41
+ return decrypted.toString('utf8'); // Convert Buffer back to string
42
+ }
43
+
44
+ static RSASign(data, privateKey) {
45
+ const sign = crypto.createSign('SHA256');
46
+ sign.update(data);
47
+ sign.end();
48
+ return sign.sign(privateKey, 'base64');
49
+ }
50
+
51
+ static RSASignVerify(data, signature, publicKey) {
52
+ const verify = crypto.createVerify('SHA256');
53
+ verify.update(data);
54
+ verify.end();
55
+ return verify.verify(publicKey, signature, 'base64');
56
+ }
57
+
58
+ static AESGenerateKey(keySize = 256) {
59
+ return crypto.randomBytes(keySize / 8).toString('base64');
60
+ }
61
+
62
+ static AESEncrypt(data, keyBase64, iv) {
63
+ const cipher = crypto.createCipheriv('aes-256-cbc', Buffer.from(keyBase64, 'base64'), iv);
64
+ let encrypted = cipher.update(data, 'utf8', 'base64');
65
+ encrypted += cipher.final('base64');
66
+ return encrypted;
67
+ }
68
+
69
+ static AESDecrypt(encryptedData, keyBase64, iv) {
70
+ const decipher = crypto.createDecipheriv('aes-256-cbc', Buffer.from(keyBase64, 'base64'), iv);
71
+ let decrypted = decipher.update(encryptedData, 'base64', 'utf8');
72
+ decrypted += decipher.final('utf8');
73
+ return decrypted;
74
+ }
75
+
76
+ static convertStringToByte(message) {
77
+ return Buffer.from(message, 'utf8');
78
+ }
79
+
80
+ static convertBase64StringToByte(data) {
81
+ return Buffer.from(data, 'base64');
82
+ }
83
+
84
+ static convertByteToBase64String(data) {
85
+ return Buffer.from(data).toString('base64');
86
+ }
87
+
88
+ static hash(data) {
89
+ return crypto.createHash('md5').update(data).digest('hex');
90
+ }
91
+
92
+ static generateHMAC(data, key) {
93
+ const hmac = crypto.createHmac('sha256', key);
94
+ hmac.update(data);
95
+ return hmac.digest('base64');
96
+ }
97
+
98
+ static async encryptAndSend(message, newVersion, publicKey = null, privateKey = null,AESKey = null) {
99
+ if (!publicKey) {
100
+ ({publicKey, privateKey} = await CryptHelper.RSAGenerateKeyPair());
101
+ }
102
+ if (!AESKey) {
103
+ AESKey = CryptHelper.AESGenerateKey();
104
+ }
105
+ let iv = CryptHelper.generateIv();
106
+
107
+ let encryptedAESKey = CryptHelper.RSAEncrypt(AESKey, publicKey);
108
+ let encryptedMessage = CryptHelper.AESEncrypt(message, AESKey, iv);
109
+ let hmac = CryptHelper.generateHMAC(encryptedMessage, AESKey);
110
+
111
+ let data = {
112
+ message: encryptedMessage,
113
+ key: encryptedAESKey,
114
+ iv: iv.toString('base64'),
115
+ hmac: hmac,
116
+ messageVersion: newVersion,
117
+ envelopeVersion: ENVELOPE_VERSION
118
+ };
119
+
120
+ return {privateKey, publicKey, AESKey, data, originalMessage: message};
121
+ }
122
+
123
+ static async receiveAndDecrypt(data, privateKey) {
124
+ let decryptedAESKey = CryptHelper.RSADecrypt(data.key, privateKey);
125
+ let iv = Buffer.from(data.iv, 'base64');
126
+
127
+ // Verify HMAC first
128
+ let recalculatedHmac = CryptHelper.generateHMAC(data.message, decryptedAESKey);
129
+ if (recalculatedHmac !== data.hmac) {
130
+ throw new Error('Data integrity check failed');
131
+ }
132
+
133
+ return CryptHelper.AESDecrypt(data.message, decryptedAESKey, iv);
134
+ }
135
+ }
@@ -253,10 +253,10 @@ export class Nar2 {
253
253
  });
254
254
  } else {
255
255
  out = await axios.get(Nar2.GET_WS_FALLBACK_INTERNAL.replace("{cf}", cf).replace("{token}", Nar2.#token).replace("{type}", "sogei"));
256
- out = out.sogei;
256
+ out.data = {status: out.data.sogei.status || false, data: out.data.sogei.data};
257
257
  }
258
258
 
259
- if (out.data === undefined || out.data.status.toString().toLowerCase().includes("token is invalid"))
259
+ if (!out.data || out.data === undefined || (fallback && out.data.status.toString().toLowerCase().includes("token is invalid")))
260
260
  await this.getToken(true);
261
261
  else if (out.data.status.toString() !== "true" && out.data.listaMessaggi.p801descrizioneMessaggio.includes("errato")) {
262
262
  assistito.okTs = false;