aprog 1.6.4 → 1.6.6
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/bin/cli.js +4 -0
- package/package.json +1 -1
- package/src/check-version.js +27 -0
- package/src/debugger.js +2 -2
- package/src/secretStorage.js +17 -57
package/bin/cli.js
ADDED
package/package.json
CHANGED
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
import https from 'https';
|
|
2
|
+
import { createRequire } from 'module';
|
|
3
|
+
const require = createRequire(import.meta.url);
|
|
4
|
+
const { version } = require('../package.json');
|
|
5
|
+
|
|
6
|
+
export const checkForUpdates = () => {
|
|
7
|
+
return new Promise((resolve) => {
|
|
8
|
+
const req = https.get('https://registry.npmjs.org/aprog/latest', (res) => {
|
|
9
|
+
let data = '';
|
|
10
|
+
res.on('data', chunk => data += chunk);
|
|
11
|
+
res.on('end', () => {
|
|
12
|
+
try {
|
|
13
|
+
const latest = JSON.parse(data).version;
|
|
14
|
+
if (latest !== version) {
|
|
15
|
+
console.log(`\n🔔 Доступна нова версія aprog: v${latest} (встановлена: v${version})`);
|
|
16
|
+
console.log(`👉 Оновити: npm install -g aprog\n`);
|
|
17
|
+
}
|
|
18
|
+
} catch (err) {
|
|
19
|
+
// нічого, просто мовчимо
|
|
20
|
+
}
|
|
21
|
+
resolve();
|
|
22
|
+
});
|
|
23
|
+
});
|
|
24
|
+
|
|
25
|
+
req.on('error', () => resolve());
|
|
26
|
+
});
|
|
27
|
+
};
|
package/src/debugger.js
CHANGED
|
@@ -26,5 +26,5 @@ class Debugger {
|
|
|
26
26
|
}
|
|
27
27
|
|
|
28
28
|
const debuggerClass = new Debugger();
|
|
29
|
-
export const dump = (...args) => debuggerClass.dump(args);
|
|
30
|
-
export const dd = (...args) => debuggerClass.dd(args);
|
|
29
|
+
export const dump = (...args) => debuggerClass.dump(...args);
|
|
30
|
+
export const dd = (...args) => debuggerClass.dd(...args);
|
package/src/secretStorage.js
CHANGED
|
@@ -1,61 +1,21 @@
|
|
|
1
|
+
import AES from "crypto-js/aes";
|
|
2
|
+
import Utf8 from "crypto-js/enc-utf8";
|
|
3
|
+
|
|
1
4
|
const DB_NAME = 'secureDB';
|
|
2
5
|
const STORE_NAME = 'secureStore';
|
|
3
6
|
const DB_VERSION = 1;
|
|
4
7
|
|
|
5
|
-
const
|
|
6
|
-
const password = import.meta.env.VITE_ENCRYPTION_KEY;
|
|
7
|
-
const encoder = new TextEncoder();
|
|
8
|
-
const salt = encoder.encode('nasty');
|
|
9
|
-
|
|
10
|
-
const keyMaterial = await crypto.subtle.importKey(
|
|
11
|
-
'raw',
|
|
12
|
-
encoder.encode(password),
|
|
13
|
-
{ name: 'PBKDF2' },
|
|
14
|
-
false,
|
|
15
|
-
['deriveKey']
|
|
16
|
-
);
|
|
8
|
+
const SECRET = import.meta.env.VITE_ENCRYPTION_KEY;
|
|
17
9
|
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
salt: salt,
|
|
22
|
-
iterations: 100000,
|
|
23
|
-
hash: 'SHA-256'
|
|
24
|
-
},
|
|
25
|
-
keyMaterial,
|
|
26
|
-
{ name: 'AES-GCM', length: 256 },
|
|
27
|
-
true,
|
|
28
|
-
['encrypt', 'decrypt']
|
|
29
|
-
);
|
|
10
|
+
const encryptData = (data) => {
|
|
11
|
+
const encrypted = AES.encrypt(JSON.stringify(data), SECRET);
|
|
12
|
+
return encrypted.toString(); // отримаємо base64 рядок
|
|
30
13
|
};
|
|
31
14
|
|
|
32
|
-
const
|
|
33
|
-
const
|
|
34
|
-
const
|
|
35
|
-
|
|
36
|
-
const encoded = new TextEncoder().encode(JSON.stringify(data));
|
|
37
|
-
const encrypted = await crypto.subtle.encrypt(
|
|
38
|
-
{ name: 'AES-GCM', iv },
|
|
39
|
-
key,
|
|
40
|
-
encoded
|
|
41
|
-
);
|
|
42
|
-
|
|
43
|
-
return {
|
|
44
|
-
iv: Array.from(iv),
|
|
45
|
-
data: Array.from(new Uint8Array(encrypted))
|
|
46
|
-
};
|
|
47
|
-
};
|
|
48
|
-
|
|
49
|
-
const decryptData = async ({ iv, data }) => {
|
|
50
|
-
const key = await getKey();
|
|
51
|
-
const decrypted = await crypto.subtle.decrypt(
|
|
52
|
-
{ name: 'AES-GCM', iv: new Uint8Array(iv) },
|
|
53
|
-
key,
|
|
54
|
-
new Uint8Array(data)
|
|
55
|
-
);
|
|
56
|
-
|
|
57
|
-
const decoded = new TextDecoder().decode(decrypted);
|
|
58
|
-
return JSON.parse(decoded);
|
|
15
|
+
const decryptData = (cipher) => {
|
|
16
|
+
const bytes = AES.decrypt(cipher, SECRET);
|
|
17
|
+
const decrypted = bytes.toString(Utf8);
|
|
18
|
+
return JSON.parse(decrypted);
|
|
59
19
|
};
|
|
60
20
|
|
|
61
21
|
const openDB = () => {
|
|
@@ -74,11 +34,11 @@ const openDB = () => {
|
|
|
74
34
|
|
|
75
35
|
export const saveItem = async (id, data) => {
|
|
76
36
|
const db = await openDB();
|
|
77
|
-
const encrypted =
|
|
37
|
+
const encrypted = encryptData(data);
|
|
78
38
|
|
|
79
39
|
const tx = db.transaction(STORE_NAME, 'readwrite');
|
|
80
40
|
const store = tx.objectStore(STORE_NAME);
|
|
81
|
-
store.put({ id,
|
|
41
|
+
store.put({ id, data: encrypted });
|
|
82
42
|
|
|
83
43
|
return tx.complete;
|
|
84
44
|
};
|
|
@@ -90,10 +50,10 @@ export const loadItem = async (id) => {
|
|
|
90
50
|
|
|
91
51
|
return new Promise((resolve, reject) => {
|
|
92
52
|
const request = store.get(id);
|
|
93
|
-
request.onsuccess =
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
resolve(
|
|
53
|
+
request.onsuccess = () => {
|
|
54
|
+
const record = request.result;
|
|
55
|
+
if (record && record.data) {
|
|
56
|
+
resolve(decryptData(record.data));
|
|
97
57
|
} else {
|
|
98
58
|
resolve(null);
|
|
99
59
|
}
|