-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathindex.js
126 lines (117 loc) · 5.29 KB
/
index.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
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
const { exec, spawn } = require('child_process');
const path = require('path');
const fs = require('fs');
if (!process.env.BW_SERVER) throw Error("ENV BW_SERVER required.");
if (!process.env.BW_CLIENTID) throw Error("ENV BW_CLIENTID required.");
if (!process.env.BW_CLIENTSECRET) throw Error("ENV BW_CLIENTSECRET required.");
if (!process.env.BW_PASSWORD) throw Error("ENV BW_PASSWORD required.");
if (!process.env.KP_PATH) throw Error("ENV KP_PATH required.");
const dir = path.dirname(process.env.KP_PATH);
if (!fs.existsSync(dir)) fs.mkdirSync(dir, { recursive: true });
const tempPath = `${dir}/temp`;
function createDB() {
return new Promise((resolve, reject) => {
if (fs.existsSync(tempPath)) fs.unlinkSync(tempPath);
try {
const child = spawn('keepassxc-cli', ['db-create', '-p', tempPath]);
child.stdout.on('data', (data) => {
const prompt = data.toString();
if (prompt.includes('Success')){ child.kill('SIGINT'); return resolve(true);}
});
child.stderr.on('data', (data) => {
const prompt = data.toString();
if (prompt.includes('password')) return child.stdin.write(`${process.env.BW_PASSWORD}\n`);
});
} catch (e) { reject(e); }
});
}
function createFolder(name) {
return new Promise((resolve, reject) => {
try {
const child = spawn('keepassxc-cli', ['mkdir', tempPath, name]);
child.stdout.on('data', (data) => {
const prompt = data.toString();
if (prompt.includes('Success')){ child.kill('SIGINT'); return resolve(true);}
});
child.stderr.on('data', (data) => {
const prompt = data.toString();
if (prompt.includes('password')) return child.stdin.write(`${process.env.BW_PASSWORD}\n`);
});
} catch (e) { reject(e); }
});
}
function createEntry(name, username, password, url, notes) {
return new Promise((resolve, reject) => {
try {
const params = [];
if (username) params.push(`-u ${username}`);
if (url){ params.push('--url'); params.push(url); }
if (notes){ params.push('--notes'); params.push(notes); }
const child = spawn('keepassxc-cli', [ 'add', '-p', tempPath, name, ...params ]);
child.stdout.on('data', (data) => {
const prompt = data.toString();
if (prompt.includes('Success')){ child.kill('SIGINT'); return resolve(true);}
if (prompt.includes('password for new entry')) return child.stdin.write(`${password}\n`);
});
child.stderr.on('data', (data) => {
const prompt = data.toString();
if (prompt.includes('password')) return child.stdin.write(`${process.env.BW_PASSWORD}\n`);
});
} catch (e) { reject(e); }
});
}
function execProm(command, allowedErr = []) {
return new Promise((resolve, reject) => {
try {
exec(command, function(err, stdout, stderr){
if (stderr||err) {
let allowed = false;
for (const err of allowedErr) {
if ((stderr||err).includes(err)) allowed = true;
} if (!allowed) return reject(stderr||err);
} return resolve(stdout);
});
} catch (e) { reject(e); }
});
}
async function init() {
await execProm(`bw config server ${process.env.BW_SERVER}`, ['creating']);
console.log(`Server set to ${process.env.BW_SERVER}.`);
await execProm('bw logout', ['You are not logged in']);
await execProm('bw login --apikey', ['logged in']);
console.log(`Logged in as ${process.env.BW_CLIENTID}.`);
await execProm('bw lock');
const session = await execProm('bw unlock --passwordenv BW_PASSWORD');
if (!(session).includes('BW_SESSION="')) throw Error(session);
console.log(`Vault unlocked.`);
const BW_SESSION = session.split('BW_SESSION="')[1].split('"')[0];
process.env.BW_SESSION = BW_SESSION;
await createDB();
console.log(`${tempPath} created.`);
const list_folders = await execProm('bw list folders');
const folder_json = JSON.parse(list_folders)||[];
const folders = {};
console.log(`${folder_json.length} folders to create.`);
for (const folder of folder_json) {
if (!folder.id||!folder.name) continue;
folders[folder.id] = folder.name;
await createFolder(folder.name);
}
const list_items = await execProm('bw list items');
const item_json = JSON.parse(list_items)||[];
console.log(`${item_json.length} items to create.`);
for (const item of item_json) {
const name = item.folderId ? `${folders[item.folderId]}/${item.name}` : item.name;
const url = item.login.uris[0].uri;
const note = `${item.notes||""}\n${JSON.stringify(item, null, 2)}`
await createEntry(name, item.login.username, item.login.password, url, note );
}
if (fs.existsSync(process.env.KP_PATH)) fs.unlinkSync(process.env.KP_PATH);
fs.renameSync(tempPath, process.env.KP_PATH);
console.log(`${tempPath} renamed to ${process.env.KP_PATH}.`);
await execProm(`bw lock`);
console.log(`Vault locked.`);
await execProm(`bw logout`);
console.log(`Logged out.`);
}
init();