aboutsummaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
authorIsmaël Bouya <ismael.bouya@normalesup.org>2020-05-05 01:17:41 +0200
committerIsmaël Bouya <ismael.bouya@normalesup.org>2020-05-05 01:17:41 +0200
commitd34561d155e99a263bf8874318a91e0161518e4a (patch)
tree44bd1442ea74514d533f8bab6d93360820f98e3d
parent0ac3ab8ea976f580ff68b6c003436fb536020c5c (diff)
downloadSurfer-d34561d155e99a263bf8874318a91e0161518e4a.tar.gz
Surfer-d34561d155e99a263bf8874318a91e0161518e4a.tar.zst
Surfer-d34561d155e99a263bf8874318a91e0161518e4a.zip
Add raw/tar/zip endpoints
-rw-r--r--frontend/index.html11
-rw-r--r--frontend/public.html9
-rw-r--r--package-lock.json369
-rw-r--r--package.json2
-rwxr-xr-xserver.js53
5 files changed, 438 insertions, 6 deletions
diff --git a/frontend/index.html b/frontend/index.html
index 3a2f7f7..20f2c8d 100644
--- a/frontend/index.html
+++ b/frontend/index.html
@@ -67,6 +67,17 @@
67 </div> 67 </div>
68 <div align="right" v-show="session.valid"> 68 <div align="right" v-show="session.valid">
69 <el-button-group> 69 <el-button-group>
70 <a v-bind:href="'/raw' + path">
71 <el-button type="primary" icon="el-icon-download" size="small">Raw (curl/wget friendly)</el-button>
72 </a>
73 <a v-bind:href="'/tar' + path">
74 <el-button type="primary" icon="el-icon-download" size="small">Download Tar.gz</el-button>
75 </a>
76 <a v-bind:href="'/zip' + path">
77 <el-button type="primary" icon="el-icon-download" size="small">Download Zip</el-button>
78 </a>
79 </el-button-group>
80 <el-button-group>
70 <el-button type="primary" icon="el-icon-upload2" size="small" @click="onUpload">Upload File</el-button> 81 <el-button type="primary" icon="el-icon-upload2" size="small" @click="onUpload">Upload File</el-button>
71 <el-button type="primary" icon="el-icon-upload" size="small" @click="onUploadFolder">Upload Folder</el-button> 82 <el-button type="primary" icon="el-icon-upload" size="small" @click="onUploadFolder">Upload Folder</el-button>
72 <el-button type="primary" icon="el-icon-plus" size="small" @click="onNewFolder">New Folder</el-button> 83 <el-button type="primary" icon="el-icon-plus" size="small" @click="onNewFolder">New Folder</el-button>
diff --git a/frontend/public.html b/frontend/public.html
index 2ddf543..b31401f 100644
--- a/frontend/public.html
+++ b/frontend/public.html
@@ -28,6 +28,15 @@
28 <p style="font-size: 24px; margin: 4px 0;">{{ path }}</p> 28 <p style="font-size: 24px; margin: 4px 0;">{{ path }}</p>
29 </div> 29 </div>
30 <div> 30 <div>
31 <a v-bind:href="'/raw' + path">
32 <el-button type="primary" icon="el-icon-download" size="small">Raw (curl/wget friendly)</el-button>
33 </a>
34 <a v-bind:href="'/tar' + path">
35 <el-button type="primary" icon="el-icon-download" size="small">Download Tar.gz</el-button>
36 </a>
37 <a v-bind:href="'/zip' + path">
38 <el-button type="primary" icon="el-icon-download" size="small">Download Zip</el-button>
39 </a>
31 <a href="/_admin"> 40 <a href="/_admin">
32 <el-button type="primary" icon="el-icon-user" size="small">Login</el-button> 41 <el-button type="primary" icon="el-icon-user" size="small">Login</el-button>
33 </a> 42 </a>
diff --git a/package-lock.json b/package-lock.json
index ad4f43e..69e50a5 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -70,6 +70,107 @@
70 "picomatch": "^2.0.4" 70 "picomatch": "^2.0.4"
71 } 71 }
72 }, 72 },
73 "archiver": {
74 "version": "4.0.1",
75 "resolved": "https://registry.npmjs.org/archiver/-/archiver-4.0.1.tgz",
76 "integrity": "sha512-/YV1pU4Nhpf/rJArM23W6GTUjT0l++VbjykrCRua1TSXrn+yM8Qs7XvtwSiRse0iCe49EPNf7ktXnPsWuSb91Q==",
77 "requires": {
78 "archiver-utils": "^2.1.0",
79 "async": "^2.6.3",
80 "buffer-crc32": "^0.2.1",
81 "glob": "^7.1.6",
82 "readable-stream": "^3.6.0",
83 "tar-stream": "^2.1.2",
84 "zip-stream": "^3.0.1"
85 },
86 "dependencies": {
87 "async": {
88 "version": "2.6.3",
89 "resolved": "https://registry.npmjs.org/async/-/async-2.6.3.tgz",
90 "integrity": "sha512-zflvls11DCy+dQWzTW2dzuilv8Z5X/pjfmZOWba6TNIVDm+2UDaJmXSOXlasHKfNBs8oo3M0aT50fDEWfKZjXg==",
91 "requires": {
92 "lodash": "^4.17.14"
93 }
94 },
95 "glob": {
96 "version": "7.1.6",
97 "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.6.tgz",
98 "integrity": "sha512-LwaxwyZ72Lk7vZINtNNrywX0ZuLyStrdDtabefZKAY5ZGJhVtgdznluResxNmPitE0SAO+O26sWTHeKSI2wMBA==",
99 "requires": {
100 "fs.realpath": "^1.0.0",
101 "inflight": "^1.0.4",
102 "inherits": "2",
103 "minimatch": "^3.0.4",
104 "once": "^1.3.0",
105 "path-is-absolute": "^1.0.0"
106 }
107 },
108 "readable-stream": {
109 "version": "3.6.0",
110 "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.0.tgz",
111 "integrity": "sha512-BViHy7LKeTz4oNnkcLJ+lVSL6vpiFeX6/d3oSH8zCW7UxP2onchk+vTGB143xuFjHS3deTgkKoXXymXqymiIdA==",
112 "requires": {
113 "inherits": "^2.0.3",
114 "string_decoder": "^1.1.1",
115 "util-deprecate": "^1.0.1"
116 }
117 }
118 }
119 },
120 "archiver-utils": {
121 "version": "2.1.0",
122 "resolved": "https://registry.npmjs.org/archiver-utils/-/archiver-utils-2.1.0.tgz",
123 "integrity": "sha512-bEL/yUb/fNNiNTuUz979Z0Yg5L+LzLxGJz8x79lYmR54fmTIb6ob/hNQgkQnIUDWIFjZVQwl9Xs356I6BAMHfw==",
124 "requires": {
125 "glob": "^7.1.4",
126 "graceful-fs": "^4.2.0",
127 "lazystream": "^1.0.0",
128 "lodash.defaults": "^4.2.0",
129 "lodash.difference": "^4.5.0",
130 "lodash.flatten": "^4.4.0",
131 "lodash.isplainobject": "^4.0.6",
132 "lodash.union": "^4.6.0",
133 "normalize-path": "^3.0.0",
134 "readable-stream": "^2.0.0"
135 },
136 "dependencies": {
137 "glob": {
138 "version": "7.1.6",
139 "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.6.tgz",
140 "integrity": "sha512-LwaxwyZ72Lk7vZINtNNrywX0ZuLyStrdDtabefZKAY5ZGJhVtgdznluResxNmPitE0SAO+O26sWTHeKSI2wMBA==",
141 "requires": {
142 "fs.realpath": "^1.0.0",
143 "inflight": "^1.0.4",
144 "inherits": "2",
145 "minimatch": "^3.0.4",
146 "once": "^1.3.0",
147 "path-is-absolute": "^1.0.0"
148 }
149 },
150 "readable-stream": {
151 "version": "2.3.7",
152 "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.7.tgz",
153 "integrity": "sha512-Ebho8K4jIbHAxnuxi7o42OrZgF/ZTNcsZj6nRKyUmkhLFq8CHItp/fy6hQZuZmP/n3yZ9VBUbp4zz/mX8hmYPw==",
154 "requires": {
155 "core-util-is": "~1.0.0",
156 "inherits": "~2.0.3",
157 "isarray": "~1.0.0",
158 "process-nextick-args": "~2.0.0",
159 "safe-buffer": "~5.1.1",
160 "string_decoder": "~1.1.1",
161 "util-deprecate": "~1.0.1"
162 }
163 },
164 "string_decoder": {
165 "version": "1.1.1",
166 "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz",
167 "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==",
168 "requires": {
169 "safe-buffer": "~5.1.0"
170 }
171 }
172 }
173 },
73 "argparse": { 174 "argparse": {
74 "version": "1.0.10", 175 "version": "1.0.10",
75 "resolved": "https://registry.npmjs.org/argparse/-/argparse-1.0.10.tgz", 176 "resolved": "https://registry.npmjs.org/argparse/-/argparse-1.0.10.tgz",
@@ -145,6 +246,11 @@
145 "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.0.tgz", 246 "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.0.tgz",
146 "integrity": "sha1-ibTRmasr7kneFk6gK4nORi1xt2c=" 247 "integrity": "sha1-ibTRmasr7kneFk6gK4nORi1xt2c="
147 }, 248 },
249 "base64-js": {
250 "version": "1.3.1",
251 "resolved": "https://registry.npmjs.org/base64-js/-/base64-js-1.3.1.tgz",
252 "integrity": "sha512-mLQ4i2QO1ytvGWFWmcngKO//JXAQueZvwEKtjgQFM4jIK0kU+ytMfplL8j+n5mspOfjHwoAg+9yhb7BwAHm36g=="
253 },
148 "basic-auth": { 254 "basic-auth": {
149 "version": "2.0.1", 255 "version": "2.0.1",
150 "resolved": "https://registry.npmjs.org/basic-auth/-/basic-auth-2.0.1.tgz", 256 "resolved": "https://registry.npmjs.org/basic-auth/-/basic-auth-2.0.1.tgz",
@@ -160,6 +266,11 @@
160 } 266 }
161 } 267 }
162 }, 268 },
269 "batch": {
270 "version": "0.6.1",
271 "resolved": "https://registry.npmjs.org/batch/-/batch-0.6.1.tgz",
272 "integrity": "sha1-3DQxT05nkxgJP8dgJyUl+UvyXBY="
273 },
163 "bcrypt-pbkdf": { 274 "bcrypt-pbkdf": {
164 "version": "1.0.1", 275 "version": "1.0.1",
165 "resolved": "https://registry.npmjs.org/bcrypt-pbkdf/-/bcrypt-pbkdf-1.0.1.tgz", 276 "resolved": "https://registry.npmjs.org/bcrypt-pbkdf/-/bcrypt-pbkdf-1.0.1.tgz",
@@ -179,6 +290,23 @@
179 "integrity": "sha512-Phlt0plgpIIBOGTT/ehfFnbNlfsDEiqmzE2KRXoX1bLIlir4X/MR+zSyBEkL05ffWgnRSf/DXv+WrUAVr93/ow==", 290 "integrity": "sha512-Phlt0plgpIIBOGTT/ehfFnbNlfsDEiqmzE2KRXoX1bLIlir4X/MR+zSyBEkL05ffWgnRSf/DXv+WrUAVr93/ow==",
180 "dev": true 291 "dev": true
181 }, 292 },
293 "bl": {
294 "version": "4.0.2",
295 "resolved": "https://registry.npmjs.org/bl/-/bl-4.0.2.tgz",
296 "integrity": "sha512-j4OH8f6Qg2bGuWfRiltT2HYGx0e1QcBTrK9KAHNMwMZdQnDZFk0ZSYIpADjYCB3U12nicC5tVJwSIhwOWjb4RQ==",
297 "requires": {
298 "buffer": "^5.5.0",
299 "inherits": "^2.0.4",
300 "readable-stream": "^3.4.0"
301 },
302 "dependencies": {
303 "inherits": {
304 "version": "2.0.4",
305 "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz",
306 "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ=="
307 }
308 }
309 },
182 "body-parser": { 310 "body-parser": {
183 "version": "1.18.2", 311 "version": "1.18.2",
184 "resolved": "https://registry.npmjs.org/body-parser/-/body-parser-1.18.2.tgz", 312 "resolved": "https://registry.npmjs.org/body-parser/-/body-parser-1.18.2.tgz",
@@ -253,6 +381,20 @@
253 "integrity": "sha512-qhAVI1+Av2X7qelOfAIYwXONood6XlZE/fXaBSmW/T5SzLAmCgzi+eiWE7fUvbHaeNBQH13UftjpXxsfLkMpgw==", 381 "integrity": "sha512-qhAVI1+Av2X7qelOfAIYwXONood6XlZE/fXaBSmW/T5SzLAmCgzi+eiWE7fUvbHaeNBQH13UftjpXxsfLkMpgw==",
254 "dev": true 382 "dev": true
255 }, 383 },
384 "buffer": {
385 "version": "5.6.0",
386 "resolved": "https://registry.npmjs.org/buffer/-/buffer-5.6.0.tgz",
387 "integrity": "sha512-/gDYp/UtU0eA1ys8bOs9J6a+E/KWIY+DZ+Q2WESNUA0jFRsJOc0SNUO6xJ5SGA1xueg3NL65W6s+NY5l9cunuw==",
388 "requires": {
389 "base64-js": "^1.0.2",
390 "ieee754": "^1.1.4"
391 }
392 },
393 "buffer-crc32": {
394 "version": "0.2.13",
395 "resolved": "https://registry.npmjs.org/buffer-crc32/-/buffer-crc32-0.2.13.tgz",
396 "integrity": "sha1-DTM+PwDqxQqhRUq9MO+MKl2ackI="
397 },
256 "bunyan": { 398 "bunyan": {
257 "version": "1.8.12", 399 "version": "1.8.12",
258 "resolved": "https://registry.npmjs.org/bunyan/-/bunyan-1.8.12.tgz", 400 "resolved": "https://registry.npmjs.org/bunyan/-/bunyan-1.8.12.tgz",
@@ -400,6 +542,41 @@
400 "resolved": "https://registry.npmjs.org/component-emitter/-/component-emitter-1.3.0.tgz", 542 "resolved": "https://registry.npmjs.org/component-emitter/-/component-emitter-1.3.0.tgz",
401 "integrity": "sha512-Rd3se6QB+sO1TwqZjscQrurpEPIfO0/yYnSin6Q/rD3mOutHvUrCAhJub3r90uNb+SESBuE0QYoB90YdfatsRg==" 543 "integrity": "sha512-Rd3se6QB+sO1TwqZjscQrurpEPIfO0/yYnSin6Q/rD3mOutHvUrCAhJub3r90uNb+SESBuE0QYoB90YdfatsRg=="
402 }, 544 },
545 "compress-commons": {
546 "version": "3.0.0",
547 "resolved": "https://registry.npmjs.org/compress-commons/-/compress-commons-3.0.0.tgz",
548 "integrity": "sha512-FyDqr8TKX5/X0qo+aVfaZ+PVmNJHJeckFBlq8jZGSJOgnynhfifoyl24qaqdUdDIBe0EVTHByN6NAkqYvE/2Xg==",
549 "requires": {
550 "buffer-crc32": "^0.2.13",
551 "crc32-stream": "^3.0.1",
552 "normalize-path": "^3.0.0",
553 "readable-stream": "^2.3.7"
554 },
555 "dependencies": {
556 "readable-stream": {
557 "version": "2.3.7",
558 "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.7.tgz",
559 "integrity": "sha512-Ebho8K4jIbHAxnuxi7o42OrZgF/ZTNcsZj6nRKyUmkhLFq8CHItp/fy6hQZuZmP/n3yZ9VBUbp4zz/mX8hmYPw==",
560 "requires": {
561 "core-util-is": "~1.0.0",
562 "inherits": "~2.0.3",
563 "isarray": "~1.0.0",
564 "process-nextick-args": "~2.0.0",
565 "safe-buffer": "~5.1.1",
566 "string_decoder": "~1.1.1",
567 "util-deprecate": "~1.0.1"
568 }
569 },
570 "string_decoder": {
571 "version": "1.1.1",
572 "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz",
573 "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==",
574 "requires": {
575 "safe-buffer": "~5.1.0"
576 }
577 }
578 }
579 },
403 "compressible": { 580 "compressible": {
404 "version": "2.0.13", 581 "version": "2.0.13",
405 "resolved": "https://registry.npmjs.org/compressible/-/compressible-2.0.13.tgz", 582 "resolved": "https://registry.npmjs.org/compressible/-/compressible-2.0.13.tgz",
@@ -518,6 +695,15 @@
518 "resolved": "https://registry.npmjs.org/crc/-/crc-3.4.4.tgz", 695 "resolved": "https://registry.npmjs.org/crc/-/crc-3.4.4.tgz",
519 "integrity": "sha1-naHpgOO9RPxck79as9ozeNheRms=" 696 "integrity": "sha1-naHpgOO9RPxck79as9ozeNheRms="
520 }, 697 },
698 "crc32-stream": {
699 "version": "3.0.1",
700 "resolved": "https://registry.npmjs.org/crc32-stream/-/crc32-stream-3.0.1.tgz",
701 "integrity": "sha512-mctvpXlbzsvK+6z8kJwSJ5crm7yBwrQMTybJzMw1O4lLGJqjlDCXY2Zw7KheiA6XBEcBmfLx1D88mjRGVJtY9w==",
702 "requires": {
703 "crc": "^3.4.4",
704 "readable-stream": "^3.4.0"
705 }
706 },
521 "cryptiles": { 707 "cryptiles": {
522 "version": "3.1.2", 708 "version": "3.1.2",
523 "resolved": "https://registry.npmjs.org/cryptiles/-/cryptiles-3.1.2.tgz", 709 "resolved": "https://registry.npmjs.org/cryptiles/-/cryptiles-3.1.2.tgz",
@@ -642,6 +828,14 @@
642 "resolved": "https://registry.npmjs.org/encodeurl/-/encodeurl-1.0.2.tgz", 828 "resolved": "https://registry.npmjs.org/encodeurl/-/encodeurl-1.0.2.tgz",
643 "integrity": "sha1-rT/0yG7C0CkyL1oCw6mmBslbP1k=" 829 "integrity": "sha1-rT/0yG7C0CkyL1oCw6mmBslbP1k="
644 }, 830 },
831 "end-of-stream": {
832 "version": "1.4.4",
833 "resolved": "https://registry.npmjs.org/end-of-stream/-/end-of-stream-1.4.4.tgz",
834 "integrity": "sha512-+uw1inIHVPQoaVuHzRyXd21icM+cnt4CzD5rW+NC1wjOUSTOs+Te7FOv7AhN7vS9x/oIyhLP5PR1H+phQAHu5Q==",
835 "requires": {
836 "once": "^1.4.0"
837 }
838 },
645 "es-abstract": { 839 "es-abstract": {
646 "version": "1.17.0", 840 "version": "1.17.0",
647 "resolved": "https://registry.npmjs.org/es-abstract/-/es-abstract-1.17.0.tgz", 841 "resolved": "https://registry.npmjs.org/es-abstract/-/es-abstract-1.17.0.tgz",
@@ -886,6 +1080,11 @@
886 "resolved": "https://registry.npmjs.org/fresh/-/fresh-0.5.2.tgz", 1080 "resolved": "https://registry.npmjs.org/fresh/-/fresh-0.5.2.tgz",
887 "integrity": "sha1-PYyt2Q2XZWn6g1qx+OSyOhBWBac=" 1081 "integrity": "sha1-PYyt2Q2XZWn6g1qx+OSyOhBWBac="
888 }, 1082 },
1083 "fs-constants": {
1084 "version": "1.0.0",
1085 "resolved": "https://registry.npmjs.org/fs-constants/-/fs-constants-1.0.0.tgz",
1086 "integrity": "sha512-y6OAwoSIf7FyjMIv94u+b5rdheZEjzR63GTyZJm5qh4Bi+2YgwLCcI/fPFZkL5PSixOt6ZNKm+w+Hfp/Bciwow=="
1087 },
889 "fs.realpath": { 1088 "fs.realpath": {
890 "version": "1.0.0", 1089 "version": "1.0.0",
891 "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", 1090 "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz",
@@ -960,6 +1159,11 @@
960 "pinkie-promise": "^2.0.0" 1159 "pinkie-promise": "^2.0.0"
961 } 1160 }
962 }, 1161 },
1162 "graceful-fs": {
1163 "version": "4.2.4",
1164 "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.4.tgz",
1165 "integrity": "sha512-WjKPNJF79dtJAVniUlGGWHYGz2jWxT6VhN/4m1NdkbZ2nOsEF+cI1Edgql5zCRhs/VsQYRvrXctxktVXZUkixw=="
1166 },
963 "growl": { 1167 "growl": {
964 "version": "1.10.5", 1168 "version": "1.10.5",
965 "resolved": "https://registry.npmjs.org/growl/-/growl-1.10.5.tgz", 1169 "resolved": "https://registry.npmjs.org/growl/-/growl-1.10.5.tgz",
@@ -1087,6 +1291,11 @@
1087 "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.19.tgz", 1291 "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.19.tgz",
1088 "integrity": "sha512-oTZqweIP51xaGPI4uPa56/Pri/480R+mo7SeU+YETByQNhDG55ycFyNLIgta9vXhILrxXDmF7ZGhqZIcuN0gJQ==" 1292 "integrity": "sha512-oTZqweIP51xaGPI4uPa56/Pri/480R+mo7SeU+YETByQNhDG55ycFyNLIgta9vXhILrxXDmF7ZGhqZIcuN0gJQ=="
1089 }, 1293 },
1294 "ieee754": {
1295 "version": "1.1.13",
1296 "resolved": "https://registry.npmjs.org/ieee754/-/ieee754-1.1.13.tgz",
1297 "integrity": "sha512-4vf7I2LYV/HaWerSo3XmlMkp5eZ83i+/CDluXi/IGTs/O1sejBNhTtnxzmRZfvOUqj7lZjqHkeTvpgSFDlWZTg=="
1298 },
1090 "immediate": { 1299 "immediate": {
1091 "version": "3.0.6", 1300 "version": "3.0.6",
1092 "resolved": "https://registry.npmjs.org/immediate/-/immediate-3.0.6.tgz", 1301 "resolved": "https://registry.npmjs.org/immediate/-/immediate-3.0.6.tgz",
@@ -1210,6 +1419,11 @@
1210 "resolved": "https://registry.npmjs.org/is-typedarray/-/is-typedarray-1.0.0.tgz", 1419 "resolved": "https://registry.npmjs.org/is-typedarray/-/is-typedarray-1.0.0.tgz",
1211 "integrity": "sha1-5HnICFjfDBsR3dppQPlgEfzaSpo=" 1420 "integrity": "sha1-5HnICFjfDBsR3dppQPlgEfzaSpo="
1212 }, 1421 },
1422 "isarray": {
1423 "version": "1.0.0",
1424 "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz",
1425 "integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE="
1426 },
1213 "isexe": { 1427 "isexe": {
1214 "version": "2.0.0", 1428 "version": "2.0.0",
1215 "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", 1429 "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz",
@@ -1290,6 +1504,38 @@
1290 } 1504 }
1291 } 1505 }
1292 }, 1506 },
1507 "lazystream": {
1508 "version": "1.0.0",
1509 "resolved": "https://registry.npmjs.org/lazystream/-/lazystream-1.0.0.tgz",
1510 "integrity": "sha1-9plf4PggOS9hOWvolGJAe7dxaOQ=",
1511 "requires": {
1512 "readable-stream": "^2.0.5"
1513 },
1514 "dependencies": {
1515 "readable-stream": {
1516 "version": "2.3.7",
1517 "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.7.tgz",
1518 "integrity": "sha512-Ebho8K4jIbHAxnuxi7o42OrZgF/ZTNcsZj6nRKyUmkhLFq8CHItp/fy6hQZuZmP/n3yZ9VBUbp4zz/mX8hmYPw==",
1519 "requires": {
1520 "core-util-is": "~1.0.0",
1521 "inherits": "~2.0.3",
1522 "isarray": "~1.0.0",
1523 "process-nextick-args": "~2.0.0",
1524 "safe-buffer": "~5.1.1",
1525 "string_decoder": "~1.1.1",
1526 "util-deprecate": "~1.0.1"
1527 }
1528 },
1529 "string_decoder": {
1530 "version": "1.1.1",
1531 "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz",
1532 "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==",
1533 "requires": {
1534 "safe-buffer": "~5.1.0"
1535 }
1536 }
1537 }
1538 },
1293 "ldap-filter": { 1539 "ldap-filter": {
1294 "version": "0.2.2", 1540 "version": "0.2.2",
1295 "resolved": "https://registry.npmjs.org/ldap-filter/-/ldap-filter-0.2.2.tgz", 1541 "resolved": "https://registry.npmjs.org/ldap-filter/-/ldap-filter-0.2.2.tgz",
@@ -1344,8 +1590,32 @@
1344 "lodash": { 1590 "lodash": {
1345 "version": "4.17.15", 1591 "version": "4.17.15",
1346 "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.15.tgz", 1592 "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.15.tgz",
1347 "integrity": "sha512-8xOcRHvCjnocdS5cpwXQXVzmmh5e5+saE2QGoeQmbKmRS6J3VQppPOIt0MnmE+4xlZoumy0GPG0D0MVIQbNA1A==", 1593 "integrity": "sha512-8xOcRHvCjnocdS5cpwXQXVzmmh5e5+saE2QGoeQmbKmRS6J3VQppPOIt0MnmE+4xlZoumy0GPG0D0MVIQbNA1A=="
1348 "dev": true 1594 },
1595 "lodash.defaults": {
1596 "version": "4.2.0",
1597 "resolved": "https://registry.npmjs.org/lodash.defaults/-/lodash.defaults-4.2.0.tgz",
1598 "integrity": "sha1-0JF4cW/+pN3p5ft7N/bwgCJ0WAw="
1599 },
1600 "lodash.difference": {
1601 "version": "4.5.0",
1602 "resolved": "https://registry.npmjs.org/lodash.difference/-/lodash.difference-4.5.0.tgz",
1603 "integrity": "sha1-nMtOUF1Ia5FlE0V3KIWi3yf9AXw="
1604 },
1605 "lodash.flatten": {
1606 "version": "4.4.0",
1607 "resolved": "https://registry.npmjs.org/lodash.flatten/-/lodash.flatten-4.4.0.tgz",
1608 "integrity": "sha1-8xwiIlqWMtK7+OSt2+8kCqdlph8="
1609 },
1610 "lodash.isplainobject": {
1611 "version": "4.0.6",
1612 "resolved": "https://registry.npmjs.org/lodash.isplainobject/-/lodash.isplainobject-4.0.6.tgz",
1613 "integrity": "sha1-fFJqUtibRcRcxpC4gWO+BJf1UMs="
1614 },
1615 "lodash.union": {
1616 "version": "4.6.0",
1617 "resolved": "https://registry.npmjs.org/lodash.union/-/lodash.union-4.6.0.tgz",
1618 "integrity": "sha1-SLtQiECfFvGCFmZkHETdGqrjzYg="
1349 }, 1619 },
1350 "log-symbols": { 1620 "log-symbols": {
1351 "version": "2.2.0", 1621 "version": "2.2.0",
@@ -1576,8 +1846,7 @@
1576 "normalize-path": { 1846 "normalize-path": {
1577 "version": "3.0.0", 1847 "version": "3.0.0",
1578 "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-3.0.0.tgz", 1848 "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-3.0.0.tgz",
1579 "integrity": "sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==", 1849 "integrity": "sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA=="
1580 "dev": true
1581 }, 1850 },
1582 "oauth-sign": { 1851 "oauth-sign": {
1583 "version": "0.8.2", 1852 "version": "0.8.2",
@@ -1748,8 +2017,7 @@
1748 "process-nextick-args": { 2017 "process-nextick-args": {
1749 "version": "2.0.1", 2018 "version": "2.0.1",
1750 "resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-2.0.1.tgz", 2019 "resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-2.0.1.tgz",
1751 "integrity": "sha512-3ouUOpQhtgrbOa17J7+uxOTpITYWaGP7/AhoR3+A+/1e9skrzelGi/dXzEYyvbxubEF6Wn2ypscTKiKJFFn1ag==", 2020 "integrity": "sha512-3ouUOpQhtgrbOa17J7+uxOTpITYWaGP7/AhoR3+A+/1e9skrzelGi/dXzEYyvbxubEF6Wn2ypscTKiKJFFn1ag=="
1752 "dev": true
1753 }, 2021 },
1754 "proxy-addr": { 2022 "proxy-addr": {
1755 "version": "2.0.2", 2023 "version": "2.0.2",
@@ -1992,6 +2260,61 @@
1992 } 2260 }
1993 } 2261 }
1994 }, 2262 },
2263 "serve-index": {
2264 "version": "1.9.1",
2265 "resolved": "https://registry.npmjs.org/serve-index/-/serve-index-1.9.1.tgz",
2266 "integrity": "sha1-03aNabHn2C5c4FD/9bRTvqEqkjk=",
2267 "requires": {
2268 "accepts": "~1.3.4",
2269 "batch": "0.6.1",
2270 "debug": "2.6.9",
2271 "escape-html": "~1.0.3",
2272 "http-errors": "~1.6.2",
2273 "mime-types": "~2.1.17",
2274 "parseurl": "~1.3.2"
2275 },
2276 "dependencies": {
2277 "depd": {
2278 "version": "1.1.2",
2279 "resolved": "https://registry.npmjs.org/depd/-/depd-1.1.2.tgz",
2280 "integrity": "sha1-m81S4UwJd2PnSbJ0xDRu0uVgtak="
2281 },
2282 "http-errors": {
2283 "version": "1.6.3",
2284 "resolved": "https://registry.npmjs.org/http-errors/-/http-errors-1.6.3.tgz",
2285 "integrity": "sha1-i1VoC7S+KDoLW/TqLjhYC+HZMg0=",
2286 "requires": {
2287 "depd": "~1.1.2",
2288 "inherits": "2.0.3",
2289 "setprototypeof": "1.1.0",
2290 "statuses": ">= 1.4.0 < 2"
2291 }
2292 },
2293 "mime-db": {
2294 "version": "1.44.0",
2295 "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.44.0.tgz",
2296 "integrity": "sha512-/NOTfLrsPBVeH7YtFPgsVWveuL+4SjjYxaQ1xtM1KMFj7HdxlBlxeyNLzhyJVx7r4rZGJAZ/6lkKCitSc/Nmpg=="
2297 },
2298 "mime-types": {
2299 "version": "2.1.27",
2300 "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.27.tgz",
2301 "integrity": "sha512-JIhqnCasI9yD+SsmkquHBxTSEuZdQX5BuQnS2Vc7puQQQ+8yiP5AY5uWhpdv4YL4VM5c6iliiYWPgJ/nJQLp7w==",
2302 "requires": {
2303 "mime-db": "1.44.0"
2304 }
2305 },
2306 "setprototypeof": {
2307 "version": "1.1.0",
2308 "resolved": "https://registry.npmjs.org/setprototypeof/-/setprototypeof-1.1.0.tgz",
2309 "integrity": "sha512-BvE/TwpZX4FXExxOxZyRGQQv651MSwmWKZGqvmPcRIjDqWub67kTKuIMx43cZZrS/cBBzwBcNDWoFxt2XEFIpQ=="
2310 },
2311 "statuses": {
2312 "version": "1.5.0",
2313 "resolved": "https://registry.npmjs.org/statuses/-/statuses-1.5.0.tgz",
2314 "integrity": "sha1-Fhx9rBd2Wf2YEfQ3cfqZOBR4Yow="
2315 }
2316 }
2317 },
1995 "serve-static": { 2318 "serve-static": {
1996 "version": "1.13.1", 2319 "version": "1.13.1",
1997 "resolved": "https://registry.npmjs.org/serve-static/-/serve-static-1.13.1.tgz", 2320 "resolved": "https://registry.npmjs.org/serve-static/-/serve-static-1.13.1.tgz",
@@ -2190,6 +2513,18 @@
2190 "has-flag": "^3.0.0" 2513 "has-flag": "^3.0.0"
2191 } 2514 }
2192 }, 2515 },
2516 "tar-stream": {
2517 "version": "2.1.2",
2518 "resolved": "https://registry.npmjs.org/tar-stream/-/tar-stream-2.1.2.tgz",
2519 "integrity": "sha512-UaF6FoJ32WqALZGOIAApXx+OdxhekNMChu6axLJR85zMMjXKWFGjbIRe+J6P4UnRGg9rAwWvbTT0oI7hD/Un7Q==",
2520 "requires": {
2521 "bl": "^4.0.1",
2522 "end-of-stream": "^1.4.1",
2523 "fs-constants": "^1.0.0",
2524 "inherits": "^2.0.3",
2525 "readable-stream": "^3.1.1"
2526 }
2527 },
2193 "tmp": { 2528 "tmp": {
2194 "version": "0.0.30", 2529 "version": "0.0.30",
2195 "resolved": "https://registry.npmjs.org/tmp/-/tmp-0.0.30.tgz", 2530 "resolved": "https://registry.npmjs.org/tmp/-/tmp-0.0.30.tgz",
@@ -2522,6 +2857,28 @@
2522 "lodash": "^4.17.15", 2857 "lodash": "^4.17.15",
2523 "yargs": "^13.3.0" 2858 "yargs": "^13.3.0"
2524 } 2859 }
2860 },
2861 "zip-stream": {
2862 "version": "3.0.1",
2863 "resolved": "https://registry.npmjs.org/zip-stream/-/zip-stream-3.0.1.tgz",
2864 "integrity": "sha512-r+JdDipt93ttDjsOVPU5zaq5bAyY+3H19bDrThkvuVxC0xMQzU1PJcS6D+KrP3u96gH9XLomcHPb+2skoDjulQ==",
2865 "requires": {
2866 "archiver-utils": "^2.1.0",
2867 "compress-commons": "^3.0.0",
2868 "readable-stream": "^3.6.0"
2869 },
2870 "dependencies": {
2871 "readable-stream": {
2872 "version": "3.6.0",
2873 "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.0.tgz",
2874 "integrity": "sha512-BViHy7LKeTz4oNnkcLJ+lVSL6vpiFeX6/d3oSH8zCW7UxP2onchk+vTGB143xuFjHS3deTgkKoXXymXqymiIdA==",
2875 "requires": {
2876 "inherits": "^2.0.3",
2877 "string_decoder": "^1.1.1",
2878 "util-deprecate": "^1.0.1"
2879 }
2880 }
2881 }
2525 } 2882 }
2526 } 2883 }
2527} 2884}
diff --git a/package.json b/package.json
index 16d58ea..53481f5 100644
--- a/package.json
+++ b/package.json
@@ -20,6 +20,7 @@
20 "url": "https://git.cloudron.io/cloudron/surfer.git" 20 "url": "https://git.cloudron.io/cloudron/surfer.git"
21 }, 21 },
22 "dependencies": { 22 "dependencies": {
23 "archiver": "^4.0.1",
23 "async": "^1.5.2", 24 "async": "^1.5.2",
24 "bcryptjs": "^2.3.0", 25 "bcryptjs": "^2.3.0",
25 "body-parser": "^1.18.2", 26 "body-parser": "^1.18.2",
@@ -40,6 +41,7 @@
40 "readline-sync": "^1.4.9", 41 "readline-sync": "^1.4.9",
41 "request": "^2.83.0", 42 "request": "^2.83.0",
42 "safetydance": "^0.1.1", 43 "safetydance": "^0.1.1",
44 "serve-index": "^1.9.1",
43 "superagent": "^5.1.3", 45 "superagent": "^5.1.3",
44 "underscore": "^1.8.3", 46 "underscore": "^1.8.3",
45 "uuid": "^3.2.1", 47 "uuid": "^3.2.1",
diff --git a/server.js b/server.js
index dd7d7cb..bee74c7 100755
--- a/server.js
+++ b/server.js
@@ -6,8 +6,11 @@ var express = require('express'),
6 morgan = require('morgan'), 6 morgan = require('morgan'),
7 path = require('path'), 7 path = require('path'),
8 fs = require('fs'), 8 fs = require('fs'),
9 archiver = require('archiver'),
9 compression = require('compression'), 10 compression = require('compression'),
10 session = require('express-session'), 11 session = require('express-session'),
12 serveIndex = require('serve-index'),
13 escapeHtml = require('escape-html'),
11 bodyParser = require('body-parser'), 14 bodyParser = require('body-parser'),
12 cookieParser = require('cookie-parser'), 15 cookieParser = require('cookie-parser'),
13 lastMile = require('connect-lastmile'), 16 lastMile = require('connect-lastmile'),
@@ -57,6 +60,49 @@ try {
57 60
58if (typeof config.folderListingEnabled === 'undefined') config.folderListingEnabled = true; 61if (typeof config.folderListingEnabled === 'undefined') config.folderListingEnabled = true;
59 62
63function isRoot(p) {
64 return path.join(ROOT_FOLDER, p) === path.join(ROOT_FOLDER, '/');
65}
66
67function sendArchive(format) {
68 var mime, extension;
69 if (format === "zip") {
70 mime = "application/zip";
71 extension = "zip";
72 } else {
73 mime = "application/tar+gzip";
74 extension = "tar.gz";
75 }
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');
79 res.writeHead(200, {
80 'Content-Type': mime,
81 'Content-disposition': 'attachment; filename=' + path.basename(req.path) + '.' + extension
82 });
83 var archive = archiver(format);
84 archive.pipe(res);
85 archive.directory(path.join(ROOT_FOLDER, req.path), path.basename(req.path))
86 archive.finalize();
87 }
88}
89
90function 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>';
101 }).join("\n");
102 html += '\n</ul></body></html>';
103 callback(null, html);
104};
105
60// Setup the express server and routes 106// Setup the express server and routes
61var app = express(); 107var app = express();
62var router = new express.Router(); 108var router = new express.Router();
@@ -95,6 +141,13 @@ app.use('/api', session({ secret: 'surfin surfin', resave: false, saveUninitiali
95app.use(router); 141app.use(router);
96app.use(webdav.extensions.express('/_webdav', webdavServer)); 142app.use(webdav.extensions.express('/_webdav', webdavServer));
97app.use('/_admin', express.static(__dirname + '/frontend')); 143app.use('/_admin', express.static(__dirname + '/frontend'));
144app.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);
148});
149app.use('/zip', sendArchive("zip"));
150app.use('/tar', sendArchive("tar"));
98app.use('/', express.static(ROOT_FOLDER)); 151app.use('/', express.static(ROOT_FOLDER));
99app.use('/', function welcomePage(req, res, next) { 152app.use('/', function welcomePage(req, res, next) {
100 if (config.folderListingEnabled || req.path !== '/') return next(); 153 if (config.folderListingEnabled || req.path !== '/') return next();