Files: 94672a88d8a56a28418985f1b77ad53e84f05c9a / confirm.js
3950 bytesRaw
1 | var proc = require('child_process') |
2 | var fs = require('fs') |
3 | var http = require('http') |
4 | var URL = require('url') |
5 | var crypto = require('crypto') |
6 | var os = require('os') |
7 | |
8 | function escapeHTML (html) { |
9 | return String(html) |
10 | .replace(/</g, '<') |
11 | .replace(/>/g, '>') |
12 | } |
13 | |
14 | function noPublish(content, cb) { |
15 | cb(new Error('missing publish function')) |
16 | } |
17 | |
18 | function noPrivatePublish(content, recps, cb) { |
19 | cb(new Error('missing private publish function')) |
20 | } |
21 | |
22 | function confirm(opts, cb) { |
23 | var content = opts.content |
24 | var browser = opts.browser |
25 | var recps = opts.recps |
26 | var publish = opts.publish || noPublish |
27 | var privatePublish = opts.privatePublish || noPrivatePublish |
28 | |
29 | if (!browser) { |
30 | return cb(new TypeError('missing browser option')) |
31 | } |
32 | if (recps && !Array.isArray(recps)) { |
33 | return cb(new TypeError('recps should be array')) |
34 | } |
35 | |
36 | var token = crypto.randomBytes(32).toString('base64') |
37 | |
38 | function publish1(content, recps, cb) { |
39 | if (recps) privatePublish(content, recps, cb) |
40 | else publish(content, cb) |
41 | } |
42 | |
43 | var server = http.createServer(function (req, res) { |
44 | var url = URL.parse(req.url, true) |
45 | if (url.pathname !== '/') { |
46 | res.writeHead(404) |
47 | return res.end('Not Found') |
48 | } |
49 | |
50 | if (url.query.token === token) { |
51 | if (url.query.publish) { |
52 | return publish1(content, recps, function (err, msg) { |
53 | if (err) { |
54 | res.writeHead(500, {'Content-Type': 'text/html'}) |
55 | res.end('<!doctype html><html><head><meta charset=utf8><title>publish error</title></head><body>' |
56 | + '<h1>' + escapeHTML(err.name || err) + '</h1>' |
57 | + '<pre>' + escapeHTML(err.stack || '') + '</pre>' |
58 | + '</body></html>') |
59 | server.close() |
60 | return cb(err) |
61 | } |
62 | var json = JSON.stringify(msg, 0, 2) |
63 | res.writeHead(200, {'Content-Type': 'text/html'}) |
64 | res.end('<!doctype html><html><head><meta charset=utf8><title>published</title></head><body>' |
65 | + '<pre>' + escapeHTML(json) + '</pre>' |
66 | + '</body></html>') |
67 | server.close() |
68 | return cb(null, msg) |
69 | }) |
70 | } |
71 | if (url.query.cancel) { |
72 | res.writeHead(200, {'Content-Type': 'text/html'}) |
73 | res.end('<!doctype html><html><head><meta charset=utf8><title>canceled</title></head><body>' |
74 | + '<p>Cancelled</p>' |
75 | + '</body></html>') |
76 | server.close() |
77 | return cb(new Error('User cancelled')) |
78 | } |
79 | } |
80 | |
81 | var contentJson = JSON.stringify(content, null, 2) |
82 | var recpsJson = JSON.stringify(recps, null, 2) |
83 | res.writeHead(200, {'Content-Type': 'text/html'}) |
84 | res.end('<!doctype html><html><head><meta charset=utf8><title>publish</title></head><body>' |
85 | + '<form action="/" method="get">' |
86 | + (recps ? '<pre>' + recpsJson + '</pre>' : '') |
87 | + '<pre>' + escapeHTML(contentJson) + '</pre>' |
88 | + '<input type="hidden" name="token" value="' + token + '">' |
89 | + '<input type="submit" name="publish" value="Publish"> ' |
90 | + '<input type="submit" name="cancel" value="Cancel">' |
91 | + '</form>' |
92 | + '</body></html>') |
93 | }).listen(0, '127.0.0.1', function () { |
94 | var port = this.address().port |
95 | var url = 'http://127.0.0.1:' + port + '/' |
96 | proc.spawn(browser, [url], {stdio: 'inherit'}) |
97 | }).on('error', cb) |
98 | } |
99 | |
100 | module.exports = function (opts) { |
101 | var publish = opts.publish |
102 | var privatePublish = opts.privatePublish |
103 | var config = opts.config || {} |
104 | var browser = config.browser || |
105 | (os.platform() === 'darwin' ? 'open' : 'xdg-open') |
106 | var name = opts.name || 'confirm' |
107 | |
108 | return { |
109 | publish: function (content, cb) { |
110 | confirm({ |
111 | publish: publish, |
112 | content: content, |
113 | browser: browser, |
114 | }, cb) |
115 | }, |
116 | privatePublish: function (content, recps, cb) { |
117 | confirm({ |
118 | privatePublish: privatePublish, |
119 | recps: recps, |
120 | content: content, |
121 | browser: browser, |
122 | }, cb) |
123 | } |
124 | } |
125 | } |
126 |
Built with git-ssb-web