]>
git.immae.eu Git - perso/Immae/Projets/Nodejs/Surfer.git/blob - server.js
bee74c7ee5e71b500e6db60b36d20b898c94d40b
5 var express
= require('express'),
6 morgan
= require('morgan'),
7 path
= require('path'),
9 archiver
= require('archiver'),
10 compression
= require('compression'),
11 session
= require('express-session'),
12 serveIndex
= require('serve-index'),
13 escapeHtml
= require('escape-html'),
14 bodyParser
= require('body-parser'),
15 cookieParser
= require('cookie-parser'),
16 lastMile
= require('connect-lastmile'),
17 HttpError
= require('connect-lastmile').HttpError
,
18 HttpSuccess
= require('connect-lastmile').HttpSuccess
,
19 multipart
= require('./src/multipart'),
20 mkdirp
= require('mkdirp'),
21 auth
= require('./src/auth.js'),
22 webdav
= require('webdav-server').v2
,
23 files
= require('./src/files.js')(path
.resolve(__dirname
, process
.argv
[2] || 'files'));
26 const ROOT_FOLDER
= path
.resolve(__dirname
, process
.argv
[2] || 'files');
27 const CONFIG_FILE
= path
.resolve(__dirname
, process
.argv
[3] || '.config.json');
29 // Ensure the root folder exists
30 mkdirp
.sync(ROOT_FOLDER
);
33 folderListingEnabled: false
36 function getSettings(req
, res
, next
) {
37 res
.send({ folderListingEnabled: !!config
.folderListingEnabled
});
40 function setSettings(req
, res
, next
) {
41 if (typeof req
.body
.folderListingEnabled
=== 'undefined') return next(new HttpError(400, 'missing folderListingEnabled boolean'));
43 config
.folderListingEnabled
= !!req
.body
.folderListingEnabled
;
45 fs
.writeFile(CONFIG_FILE
, JSON
.stringify(config
), function (error
) {
46 if (error
) return next(new HttpError(500, 'unable to save settings'));
48 next(new HttpSuccess(201, {}));
52 // Load the config file
54 console
.log(`Using config file at: ${CONFIG_FILE}`);
55 config
= require(CONFIG_FILE
);
57 if (e
.code
=== 'MODULE_NOT_FOUND') console
.log(`Config file ${CONFIG_FILE} not found`);
58 else console
.log(`Cannot load config file ${CONFIG_FILE}`, e
);
61 if (typeof config
.folderListingEnabled
=== 'undefined') config
.folderListingEnabled
= true;
64 return path
.join(ROOT_FOLDER
, p
) === path
.join(ROOT_FOLDER
, '/');
67 function sendArchive(format
) {
69 if (format
=== "zip") {
70 mime
= "application/zip";
73 mime
= "application/tar+gzip";
76 return function(req
, res
, next
) {
77 if (isRoot(req
.path
) || !fs
.existsSync(path
.join(ROOT_FOLDER
, req
.path
)))
78 return res
.status(404).sendFile(__dirname
+ '/frontend/404.html');
81 'Content-disposition': 'attachment; filename=' + path
.basename(req
.path
) + '.' + extension
83 var archive
= archiver(format
);
85 archive
.directory(path
.join(ROOT_FOLDER
, req
.path
), path
.basename(req
.path
))
90 function rawTemplate(locals
, callback
) {
91 var html
= '<!DOCTYPE html><html><head><meta charset="utf-8"><title>wget/curl friendly directory listing of ';
92 html
+= locals
.directory
;
93 html
+= '</title></head><body><ul>\n';
94 html
+= locals
.fileList
.map(function (file
) {
95 if (file
.name
=== "..") { return ""; }
96 var isDir
= file
.stat
&& file
.stat
.isDirectory();
97 var fpath
= locals
.directory
.split('/').map(function (c
) { return encodeURIComponent(c
); });
98 if (!isDir
) { fpath
.shift(); fpath
[0] = ""; }
99 fpath
.push(encodeURIComponent(file
.name
));
100 return '<li><a href="' + escapeHtml(path
.normalize(fpath
.join('/'))) + '">' + escapeHtml(file
.name
) + '</a></li>';
102 html
+= '\n</ul></body></html>';
103 callback(null, html
);
106 // Setup the express server and routes
108 var router
= new express
.Router();
110 var webdavServer
= new webdav
.WebDAVServer({
111 requireAuthentification: true,
112 httpAuthentication: new webdav
.HTTPBasicAuthentication(new auth
.WebdavUserManager(), 'Cloudron Surfer')
115 webdavServer
.setFileSystem('/', new webdav
.PhysicalFileSystem(ROOT_FOLDER
), function (success
) {
116 if (success
) console
.log(`Mounting webdav resource from: ${ROOT_FOLDER}`);
119 var multipart
= multipart({ maxFieldsSize: 2 * 1024, limit: '512mb', timeout: 3 * 60 * 1000 });
121 router
.post ('/api/login', auth
.login
);
122 router
.post ('/api/logout', auth
.verify
, auth
.logout
);
123 router
.get ('/api/settings', auth
.verify
, getSettings
);
124 router
.put ('/api/settings', auth
.verify
, setSettings
);
125 router
.get ('/api/tokens', auth
.verify
, auth
.getTokens
);
126 router
.post ('/api/tokens', auth
.verify
, auth
.createToken
);
127 router
.delete('/api/tokens/:token', auth
.verify
, auth
.delToken
);
128 router
.get ('/api/profile', auth
.verify
, auth
.getProfile
);
129 router
.get ('/api/files/*', auth
.verifyIfNeeded
, files
.get);
130 router
.post ('/api/files/*', auth
.verify
, multipart
, files
.post
);
131 router
.put ('/api/files/*', auth
.verify
, files
.put
);
132 router
.delete('/api/files/*', auth
.verify
, files
.del
);
134 app
.use('/api/healthcheck', function (req
, res
) { res
.status(200).send(); });
135 app
.use(morgan('dev'));
136 app
.use(compression());
137 app
.use('/api', bodyParser
.json());
138 app
.use('/api', bodyParser
.urlencoded({ extended: false, limit: '100mb' }));
139 app
.use('/api', cookieParser());
140 app
.use('/api', session({ secret: 'surfin surfin', resave: false, saveUninitialized: false }));
142 app
.use(webdav
.extensions
.express('/_webdav', webdavServer
));
143 app
.use('/_admin', express
.static(__dirname
+ '/frontend'));
144 app
.use('/raw', function serveRaw(req
, res
, next
) {
145 if (isRoot(req
.path
) || !fs
.existsSync(path
.join(ROOT_FOLDER
, req
.path
)))
146 return res
.status(404).sendFile(__dirname
+ '/frontend/404.html');
147 serveIndex(ROOT_FOLDER
, { template: rawTemplate
})(req
, res
, next
);
149 app
.use('/zip', sendArchive("zip"));
150 app
.use('/tar', sendArchive("tar"));
151 app
.use('/', express
.static(ROOT_FOLDER
));
152 app
.use('/', function welcomePage(req
, res
, next
) {
153 if (config
.folderListingEnabled
|| req
.path
!== '/') return next();
154 res
.status(200).sendFile(path
.join(__dirname
, '/frontend/welcome.html'));
156 app
.use('/', function (req
, res
) {
157 if (!config
.folderListingEnabled
) return res
.status(404).sendFile(__dirname
+ '/frontend/404.html');
159 if (!fs
.existsSync(path
.join(ROOT_FOLDER
, req
.path
))) return res
.status(404).sendFile(__dirname
+ '/frontend/404.html');
161 res
.status(200).sendFile(__dirname
+ '/frontend/public.html');
165 var server
= app
.listen(3000, function () {
166 var host
= server
.address().address
;
167 var port
= server
.address().port
;
169 console
.log(`Base path: ${ROOT_FOLDER}`);
171 console
.log(`Listening on http://${host}:${port}`);