aprog 1.6.3 → 1.6.5
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 +4 -1
- package/bin/cli.js +4 -0
- package/index.js +1 -0
- package/package.json +1 -1
- package/src/check-version.js +27 -0
- package/src/secretStorage.js +63 -0
package/README.md
CHANGED
|
@@ -161,9 +161,12 @@ onInput: (event) => {
|
|
|
161
161
|
|
|
162
162
|
- *cookie, storage*
|
|
163
163
|
|
|
164
|
+
- *saveItem("id", data), loadItem("id")*
|
|
165
|
+
|
|
164
166
|
### Info
|
|
165
167
|
|
|
166
|
-
- Додано безплатний чат із Gemini
|
|
168
|
+
- Додано безплатний чат із `Gemini`
|
|
169
|
+
- Додано методи збереження зашифрованих даних `saveItem` та `loadItem`
|
|
167
170
|
- З часом будуть додаватися можливості створення додаткових інструментів
|
|
168
171
|
|
|
169
172
|
|
package/bin/cli.js
ADDED
package/index.js
CHANGED
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
|
+
};
|
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
import AES from "crypto-js/aes";
|
|
2
|
+
import Utf8 from "crypto-js/enc-utf8";
|
|
3
|
+
|
|
4
|
+
const DB_NAME = 'secureDB';
|
|
5
|
+
const STORE_NAME = 'secureStore';
|
|
6
|
+
const DB_VERSION = 1;
|
|
7
|
+
|
|
8
|
+
const SECRET = import.meta.env.VITE_ENCRYPTION_KEY;
|
|
9
|
+
|
|
10
|
+
const encryptData = (data) => {
|
|
11
|
+
const encrypted = AES.encrypt(JSON.stringify(data), SECRET);
|
|
12
|
+
return encrypted.toString(); // отримаємо base64 рядок
|
|
13
|
+
};
|
|
14
|
+
|
|
15
|
+
const decryptData = (cipher) => {
|
|
16
|
+
const bytes = AES.decrypt(cipher, SECRET);
|
|
17
|
+
const decrypted = bytes.toString(Utf8);
|
|
18
|
+
return JSON.parse(decrypted);
|
|
19
|
+
};
|
|
20
|
+
|
|
21
|
+
const openDB = () => {
|
|
22
|
+
return new Promise((resolve, reject) => {
|
|
23
|
+
const request = indexedDB.open(DB_NAME, DB_VERSION);
|
|
24
|
+
|
|
25
|
+
request.onupgradeneeded = function (event) {
|
|
26
|
+
const db = event.target.result;
|
|
27
|
+
db.createObjectStore(STORE_NAME, { keyPath: 'id' });
|
|
28
|
+
};
|
|
29
|
+
|
|
30
|
+
request.onsuccess = () => resolve(request.result);
|
|
31
|
+
request.onerror = () => reject(request.error);
|
|
32
|
+
});
|
|
33
|
+
};
|
|
34
|
+
|
|
35
|
+
export const saveItem = async (id, data) => {
|
|
36
|
+
const db = await openDB();
|
|
37
|
+
const encrypted = encryptData(data);
|
|
38
|
+
|
|
39
|
+
const tx = db.transaction(STORE_NAME, 'readwrite');
|
|
40
|
+
const store = tx.objectStore(STORE_NAME);
|
|
41
|
+
store.put({ id, data: encrypted });
|
|
42
|
+
|
|
43
|
+
return tx.complete;
|
|
44
|
+
};
|
|
45
|
+
|
|
46
|
+
export const loadItem = async (id) => {
|
|
47
|
+
const db = await openDB();
|
|
48
|
+
const tx = db.transaction(STORE_NAME, 'readonly');
|
|
49
|
+
const store = tx.objectStore(STORE_NAME);
|
|
50
|
+
|
|
51
|
+
return new Promise((resolve, reject) => {
|
|
52
|
+
const request = store.get(id);
|
|
53
|
+
request.onsuccess = () => {
|
|
54
|
+
const record = request.result;
|
|
55
|
+
if (record && record.data) {
|
|
56
|
+
resolve(decryptData(record.data));
|
|
57
|
+
} else {
|
|
58
|
+
resolve(null);
|
|
59
|
+
}
|
|
60
|
+
};
|
|
61
|
+
request.onerror = () => reject(request.error);
|
|
62
|
+
});
|
|
63
|
+
};
|