-
Notifications
You must be signed in to change notification settings - Fork 3
/
safestore.js
106 lines (97 loc) · 3.68 KB
/
safestore.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
function Safestore(pwp = 'abc123') {
console.log(process.TESTING
? "Running in TEST mode."
: "Running in PRODUCTION mode.");
const tfc = require('./testFasterCache.js')(process.TESTING);
let fn = tfc.hashArg(pwp);
const fs = require('fs');
const path = require('path');
const cryptex = require('cryptex');
const crypto = require('crypto');
const prompt = require('prompt-sync')({sigint: true});
let homeDir = process.env.APPDATA
|| (process.platform == 'darwin'
? path.join(process.env.HOME,"Library","Preferences")
: path.join(process.env.HOME,".local","share")),
keyFile = path.join(homeDir,(process.TESTING ? 'test' : '') + fn + '.txt');
const pw = (!process.TESTING || !fs.existsSync(keyFile))
? prompt("Enter your password (or a new one): ",{echo:'*'})
: pwp;
if(pw != pwp) { // New Password means new file.
fn = tfc.hashArg(pw);
keyFile = path.join(homeDir,(process.TESTING ? 'test' : '') + fn + '.txt');
}
let file = keyFile,
persistent;
cryptex.update({
config: {
keySource: 'plaintext',
keySourceEncoding: 'base64',
keySourceOpts: {
key: crypto.createHash('sha256')
.update(pw).digest('base64')
}
}});
async function replace(obj) {
// Turn object into a string
let toWrite = JSON.stringify(obj);
// Encrypt the string
return cryptex.encrypt(toWrite)
// Write the string to the file
.then((e) => fs.writeFileSync(file, e));
}
async function read(f = file) {
if(!fs.existsSync(f)) await _update("NoDefault NoDefault");
// Put the file contents into a string
let enc64 = fs.readFileSync(f).toString(),
ret = enc64;
await cryptex.decrypt(enc64)
.then(async (r) => {
try { ret = JSON.parse(r);
} catch(e) {
ret = await _update(enc64);
}},async (e) => {
ret = await _update(enc64);
}
);
return ret;
}
async function _update(old, exitOnFail = true) {
let [k,s] = old.split(' ');
if(s) {
console.log("Your data will now be encrypted using the password you just entered.",
"\nThe default values were taken from the old file, which will now be replaced...");
} else {
console.log("Incorrect password.");
return false;
}
const key = prompt("Enter your API key (Or x to start over) ("+k+"): ",k);
if(key == 'x') {
if(exitOnFail) process.exit(); else return;
}
const secret = prompt('Enter your API secret ('+s+'): ',s);
let pw2 = '';
while( pw2 != pw ) {
pw2 = process.TESTING ? pw
: prompt("Enter your password again (Or x to start over): ",{echo:'*'});
if(pw2 == 'x') {
if(exitOnFail) process.exit(); else return;
}
if(pw2 != pw) {
if('y' == (process.TESTING ? (console.log("Changing test pw to ",pw),'y')
: prompt("That's different. Update to this password? (y/n)")[0]
.toLowerCase())) {
pw = pw2;
pw2 = pw2+'x';
}
}
}
let p = {key: key, secret: secret};
await replace(p);
persistent = p;
return p;
}
function getPW() { return pw; }
return Object.freeze({persistent, read, replace, _update, getPW});
}
module.exports = Safestore;