-
Notifications
You must be signed in to change notification settings - Fork 3
/
Copy pathindex.js
executable file
·136 lines (115 loc) · 3.72 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
127
128
129
130
131
132
133
134
135
136
#!/usr/bin/env node
/*
* addax: Utility to serve private S3 files through an HTTP server with token authentication.
*
* Commands:
* - addax adduser <user-directory>
* - addax rmuser <user-directory>
* - addax sign <user-directory> <path-relative-to-user-directory>
* - addax start 8080
*
*/
const _ = require('lodash');
const fs = require('fs');
const program = require('commander');
const { randomBytes } = require('crypto');
const startServer = require('./server.js');
const { readAuthFile, writeAuthFile } = require('./authentication.js');
let config;
// -------------------------
async function findTokenByDirectory(directory) {
const authData = await readAuthFile();
return _.findKey(authData, v => v === directory);
}
async function addTokenToAuthFile(directory, token) {
const authData = await readAuthFile();
return writeAuthFile(_.set(authData, token, directory));
}
async function removeTokenFromAuthFile(token) {
const authData = await readAuthFile();
return writeAuthFile(_.omit(authData, [token]));
}
function generateToken() {
return new Promise((resolve, reject) => {
randomBytes(16, (err, buffer) => {
if (err) reject(err);
else resolve(buffer.toString('hex'));
});
});
}
// -------------------------
// operations
async function addUser(directory) {
let token = await findTokenByDirectory(directory);
if (!token) {
token = await generateToken();
await addTokenToAuthFile(directory, token);
}
return { directory, token };
}
async function removeUser(directory) {
const token = await findTokenByDirectory(directory);
if (token) await removeTokenFromAuthFile(token);
}
async function signPath(directory, path) {
const token = await findTokenByDirectory(directory);
if (token) {
return `https://${config.host}/${directory}/${path}?token=${token}`;
}
throw new Error(`ERROR: no token found for ${directory}`);
}
// -------------------------
// CLI interface
program
.command('adduser <directory>')
.action(async (directory) => {
const result = await addUser(directory);
console.log('-> added directory:', result);
});
program
.command('rmuser <directory>')
.action(async (directory) => {
await removeUser(directory);
console.log('-> removed directory:', directory);
});
program
.command('sign <directory> <filepath>')
.action(async (directory, path) => {
const url = await signPath(directory, path);
console.log('-> signed url:', url);
});
program
.command('start [port]')
.action((port = 3000) => {
console.log(` -> starting server on port ${port}`);
startServer(config, { port });
});
program
.command('*')
.action((env) => {
console.error('\n[addax] command not found:', env);
console.log('\nList of available commands:');
console.log(' - adduser <user>: register a new user token');
console.log(' - rmuser <user>: remove a user token');
console.log(' - sign <user> <filepath>: generates a shareable url for that user and filepath');
console.log(' - start [port]: starts the server listeting at the specified port (3000 by default)');
});
// -------------------------
// entry point
const configFile = './config.json';
// first make sure that the config file exists in the curren dir
fs.access(configFile, fs.constants.R_OK, (err) => {
if (err) return console.error('ERROR: config.json file not found in the current directory.');
// read the config file
fs.readFile(configFile, (err, file) => {
if (err) return console.log('[reading config.json] ERROR:', err);
try {
// parse the JSON file
config = JSON.parse(String(file));
// execute the cli command
program.parse(process.argv);
} catch (err) {
console.log('[parsing config.json] ERROR:', err);
}
});
});