git ssb

3+

cel / ssb-publishguard



Tree: 2d613e9d6e6888fc6cf9cdd2eaab0729966e438f

Files: 2d613e9d6e6888fc6cf9cdd2eaab0729966e438f / confirm.js

4941 bytesRaw
1var proc = require('child_process')
2var fs = require('fs')
3var http = require('http')
4var URL = require('url')
5var crypto = require('crypto')
6var os = require('os')
7
8function escapeHTML (html) {
9 return String(html)
10 .replace(/</g, '&lt;')
11 .replace(/>/g, '&gt;')
12}
13
14function noPublish(content, cb) {
15 cb(new Error('missing publish function'))
16}
17
18function noPrivatePublish(content, recps, cb) {
19 cb(new Error('missing private publish function'))
20}
21
22function 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 getUrl = opts.getUrl
28 var privatePublish = opts.privatePublish || noPrivatePublish
29 var redirectBase = opts.redirectBase
30
31 if (typeof cb !== 'function') {
32 throw new TypeError('bad callback')
33 }
34
35 if (browser && getUrl) {
36 return cb(new TypeError('browser option and getUrl option conflict'))
37 }
38 if (!browser && !getUrl) {
39 return cb(new TypeError('missing browser option'))
40 }
41 if (recps && !Array.isArray(recps)) {
42 return cb(new TypeError('recps should be array'))
43 }
44
45 var token = crypto.randomBytes(32).toString('base64')
46
47 function publish1(content, recps, cb) {
48 if (recps) privatePublish(content, recps, cb)
49 else publish(content, cb)
50 }
51
52 var server = http.createServer(function (req, res) {
53 var url = URL.parse(req.url, true)
54 if (url.pathname !== '/') {
55 res.writeHead(404)
56 return res.end('Not Found')
57 }
58
59 if (url.query.token === token) {
60 if (url.query.publish) {
61 return publish1(content, recps, function (err, msg) {
62 if (err) {
63 res.writeHead(500, {'Content-Type': 'text/html'})
64 res.end('<!doctype html><html><head><meta charset=utf8><title>publish error</title></head><body>'
65 + '<h1>' + escapeHTML(err.name || err) + '</h1>'
66 + '<pre>' + escapeHTML(err.stack || '') + '</pre>'
67 + '</body></html>')
68 server.close()
69 return !getUrl && cb(err)
70 }
71 var json = JSON.stringify(msg, 0, 2)
72 if (redirectBase) {
73 var url = redirectBase + encodeURIComponent(msg.key)
74 res.writeHead(302, {'Location': url})
75 res.end()
76 } else {
77 res.writeHead(200, {'Content-Type': 'text/html'})
78 res.end('<!doctype html><html><head><meta charset=utf8><title>published</title></head><body>'
79 + '<pre>' + escapeHTML(json) + '</pre>'
80 + '</body></html>')
81 }
82 server.close()
83 return !getUrl && cb(null, msg)
84 })
85 }
86 if (url.query.cancel) {
87 res.writeHead(200, {'Content-Type': 'text/html'})
88 res.end('<!doctype html><html><head><meta charset=utf8><title>canceled</title></head><body>'
89 + '<p>Cancelled</p>'
90 + '</body></html>')
91 if (server) server.close()
92 return !getUrl && cb(new Error('User cancelled'))
93 }
94 }
95
96 var contentJson = JSON.stringify(content, null, 2)
97 var recpsJson = JSON.stringify(recps, null, 2)
98 res.writeHead(200, {'Content-Type': 'text/html'})
99 res.end('<!doctype html><html><head><meta charset=utf8><title>publish</title></head><body>'
100 + '<form action="/" method="get">'
101 + (recps ? '<pre>' + recpsJson + '</pre>' : '')
102 + '<pre>' + escapeHTML(contentJson) + '</pre>'
103 + '<input type="hidden" name="token" value="' + token + '">'
104 + '<input type="submit" name="publish" value="Publish"> '
105 + '<input type="submit" name="cancel" value="Cancel">'
106 + '</form>'
107 + '</body></html>')
108 }).listen(0, '127.0.0.1', function () {
109 var port = this.address().port
110 var url = 'http://127.0.0.1:' + port + '/'
111 if (browser) proc.spawn(browser, [url], {stdio: 'inherit'})
112 else cb(null, url)
113 }).on('error', cb)
114}
115
116module.exports = function (opts) {
117 var publish = opts.publish
118 var privatePublish = opts.privatePublish
119 var config = opts.config || {}
120 var browser = config.browser ||
121 (os.platform() === 'darwin' ? 'open' : 'xdg-open')
122 var name = opts.name || 'confirm'
123
124 return {
125 publish: function (content, cb) {
126 confirm({
127 publish: publish,
128 content: content,
129 browser: browser,
130 }, cb)
131 },
132 privatePublish: function (content, recps, cb) {
133 confirm({
134 privatePublish: privatePublish,
135 recps: recps,
136 content: content,
137 browser: browser,
138 }, cb)
139 },
140 publishGetUrl: function (opts, cb) {
141 confirm({
142 publish: publish,
143 content: opts.content,
144 redirectBase: opts.redirectBase,
145 getUrl: true,
146 }, cb)
147 },
148 privatePublishGetUrl: function (opts, cb) {
149 confirm({
150 privatePublish: privatePublish,
151 recps: opts.recps,
152 content: opts.content,
153 redirectBase: opts.redirectBase,
154 getUrl: true,
155 }, cb)
156 }
157 }
158}
159

Built with git-ssb-web