UNPKG

3.79 kBJavaScriptView Raw
1// Generated by CoffeeScript 2.3.1
2(function() {
3 // Web server
4 // ----------
5 var Cors, DOWNLOAD, REV, TOKEN, UNTIL, UPLOAD, URL, agent, assert, attachments_proxy, crypto, request, strictEqual;
6
7 DOWNLOAD = 'get';
8
9 UPLOAD = 'put';
10
11 TOKEN = 'token';
12
13 REV = 'rev';
14
15 UNTIL = 'until';
16
17 attachments_proxy = function(our_proxy) {
18 var cors, download_uri, handler, hash, secret, signature, timeout, upload_uri, uri_maker;
19 ({secret, hash, timeout} = our_proxy);
20 cors = Cors();
21 if (hash == null) {
22 hash = 'sha256';
23 }
24 if (timeout == null) {
25 timeout = 3600 * 1000; // one hour
26 }
27 signature = function(method, pathname, rev, limit) {
28 strictEqual('string', typeof method, 'method');
29 strictEqual('string', typeof pathname, 'pathname');
30 strictEqual('string', typeof rev, 'rev');
31 strictEqual('string', typeof limit, 'limit');
32 return crypto.createHmac(hash, secret).update(method).update(pathname).update(rev).update(limit).digest('hex');
33 };
34 handler = function(req, res, next) {
35 var limit, pathname, proxy, rev, searchParams, token;
36 if (next == null) {
37 next = function(msg) {
38 res.writeHead(404);
39 res.end(msg);
40 };
41 }
42 proxy = function() {
43 var method, options, the_proxy;
44 ({method} = req);
45 options = our_proxy.target(pathname);
46 if ((options != null ? options.url : void 0) == null) {
47 return next();
48 }
49 options.url.searchParams.set('rev', rev);
50 options.url = options.url.toString();
51 the_proxy = agent(Object.assign({
52 method,
53 followRedirects: false,
54 maxRedirects: 0,
55 headers: {
56 Connection: 'close'
57 }
58 }, options));
59 the_proxy.on('error', function(error) {
60 return console.error('Proxy', method, options.url, error);
61 });
62 req.pipe(the_proxy);
63 the_proxy.pipe(res);
64 };
65 ({pathname, searchParams} = new URL(req.url, our_proxy.url));
66 token = searchParams.get(TOKEN);
67 if (token == null) {
68 return next('Invalid token');
69 }
70 rev = searchParams.get(REV);
71 if (rev == null) {
72 return next('Invalid rev');
73 }
74 limit = searchParams.get(UNTIL);
75 if (!((limit != null ? limit.match(/^\d+$/) : void 0) && parseInt(limit) > Date.now())) {
76 return next(`Invalid limit ${JSON.stringify(limit)}`);
77 }
78 switch (req.method) {
79 case 'OPTIONS':
80 return cors(req, res, next);
81 case 'PUT':
82 if (token === signature(UPLOAD, pathname, rev, limit)) {
83 return proxy();
84 } else {
85 return next("Invalid token");
86 }
87 break;
88 case 'GET':
89 case 'HEAD':
90 if (token === signature(DOWNLOAD, pathname, rev, limit)) {
91 return proxy();
92 } else {
93 return next("Invalid token");
94 }
95 }
96 next();
97 };
98 uri_maker = function(direction) {
99 return function(path, rev) {
100 var limit, url;
101 url = new URL(path, our_proxy.url);
102 url.searchParams.set(REV, rev);
103 limit = Date.now() + timeout;
104 url.searchParams.set(UNTIL, limit);
105 url.searchParams.set(TOKEN, signature(direction, path, rev, limit.toString()));
106 return url.toString();
107 };
108 };
109 download_uri = uri_maker(DOWNLOAD);
110 upload_uri = uri_maker(UPLOAD);
111 return {handler, download_uri, upload_uri};
112 };
113
114 module.exports = attachments_proxy;
115
116 ({URL} = require('url'));
117
118 crypto = require('crypto');
119
120 request = require('request');
121
122 agent = request.defaults();
123
124 Cors = require('cors');
125
126 ({strictEqual} = assert = require('assert'));
127
128}).call(this);