git ssb

0+

dangerousbeans / yap



forked from Dominic / yap

Tree: 1e8620476d8c3fff86c6a9de29b0e986ad14babe

Files: 1e8620476d8c3fff86c6a9de29b0e986ad14babe / index.js

5225 bytesRaw
1var fs = require('fs')
2var path = require('path')
3var nested = require('libnested')
4var Stack = require('stack')
5var URL = require('url')
6var QS = require('qs')
7var u = require('./util')
8var toHTML = u.toHTML
9var pull = require('pull-stream')
10var toPull = require('stream-to-pull-stream')
11var ref = require('ssb-ref')
12
13// middleware
14var Logger = require('morgan')
15var Emoji = require('emoji-server')
16var Static = require('ecstatic')
17var BodyParser = require('urlencoded-request-parser')
18var FavIcon = require('serve-favicon')
19var Coherence = require('coherence-framework')
20
21var doctype = '<!DOCTYPE html \n PUBLIC "-//W3C//DTD HTML 4.01//EN"\n "http://www.w3.org/TR/html4/strict.dtd">'
22
23//actions may make writes to sbot, or can set things
24var actions = {
25 //note: opts is post body
26 identitySelect: function (opts, apply, req, cb) {
27 var context = req.cookies
28 context.id = opts.id
29 cb(null, opts, context)
30 },
31 preview: function (opts, apply, req, cb) {
32 cb(null, opts)
33 },
34 publish: function (opts, apply, req, cb) {
35 if(opts.content.recps === '')
36 delete opts.content.recps
37 else if('string' === typeof opts.content.recps) {
38 opts.content.recps = opts.content.recps.split(',')
39 }
40
41 if(Array.isArray(opts.content.recps))
42 opts.private = true
43
44 sbot.identities.publishAs(opts, function (err, msg) {
45 if(err) cb(err)
46 else cb()
47 })
48 }
49}
50
51require('ssb-client')(function (err, sbot) {
52 if(err) throw err
53
54 var coherence = Coherence(require('./layout'))
55 .use('avatar', require('./apis/avatar')(sbot))
56 .use('identitySelect', require('./apis/identity-select')(sbot))
57 .use('public', require('./apis/public')(sbot))
58 .use('private', require('./apis/private')(sbot))
59 .use('message', require('./apis/message')(sbot))
60 .use('messageLink', require('./apis/message-link')(sbot))
61 .use('channelLink', require('./apis/channel-link')(sbot))
62 .use('messages/post', require('./apis/messages/post')(sbot))
63 .use('messages/vote', require('./apis/messages/vote')(sbot))
64 .use('progress', require('./apis/progress')(sbot))
65 .use('thread', require('./apis/thread')(sbot))
66 .use('compose', require('./apis/compose')(sbot))
67 .use('publish', require('./apis/publish')(sbot))
68 .use('preview', require('./apis/preview')(sbot))
69 .use('friends', require('./apis/friends')(sbot))
70 .use('search', require('./apis/search')(sbot))
71 .use('mentions', require('./apis/mentions')(sbot))
72
73 require('http').createServer(Stack(
74 Logger(),
75 //everything breaks if blobs isn't first, but not sure why?
76 require('ssb-ws/blobs')(sbot, {prefix: '/blobs'}),
77 FavIcon(path.join(__dirname, 'static', 'favicon.ico')),
78 BodyParser(),
79 /*
80 some settings we want to store in a cookie:
81 * current identity
82 * current language
83
84 stuff that shouldn't be in links.
85 this makes it possible to share links without including
86 state people might not want for them.
87 also: light/dark theme etc
88 */
89 function (req, res, next) {
90 //just do it this simple way because it works
91 //I tried the cookie parser middleware but things got weird.
92 req.cookies = QS.parse(req.headers.cookie||'') || {id: sbot.id}
93 next()
94 },
95 //handle posts.
96 function (req, res, next) {
97 if(req.method == 'GET') return next()
98 var id = req.cookies.id || sbot.id
99 var opts = req.body
100 function callApi (path, opts) {
101 try {
102 var fn = nested.get(apis, path)
103 if(!fn) return next()
104 return fn(opts, apply, req)
105 } catch(err) {
106 next(err)
107 }
108 }
109 if(opts.type === 'preview') {
110 // TODO: pass opts.id in, and wether this message
111 // preview should allow recipient selection, or changing id.
112 // api.preview can set the shape of the message if it likes.
113
114 req.url = '/preview?'+QS.stringify(opts)
115 coherence(req, res, next)
116
117 //XXX this isn't working
118
119// toHTML(layout.call(self, callApi(['preview'], opts))) (function (err, result) {
120// if(err) next(err)
121// else res.end('<!DOCTYPE html>'+result.outerHTML)
122// })
123 return
124 }
125 actions[opts.type](opts, null, req, function (err, _opts, context) {
126 if(err) return next(err)
127 if(context) {
128 req.cookies = context
129 res.setHeader('set-Cookie', QS.stringify(context))
130 }
131 /*
132 after handling the post,
133 redirect to a normal page.
134 this is a work around for if you hit refresh
135 and the browser wants to resubmit the POST.
136
137 I think we want to do this for most types,
138 exception is for preview - in which we return
139 the same data rendered differently and don't write
140 to DB at all.
141 */
142 res.setHeader('location', req.url)
143 res.writeHead(303)
144 res.end()
145 })
146 },
147
148 Emoji('/img/emoji'),
149 Static({
150 root: path.join(__dirname, 'static'), baseDir: '/static'
151 }),
152 coherence
153 )).listen(8005)
154})
155
156
157

Built with git-ssb-web