git ssb

2+

Dominic / yap



Tree: b4c65fe0668bf7f8c17503206a51cbb417ee9727

Files: b4c65fe0668bf7f8c17503206a51cbb417ee9727 / index.js

6444 bytesRaw
1#! /usr/bin/env node
2var fs = require('fs')
3var path = require('path')
4var ref = require('ssb-ref')
5var Stack = require('stack')
6
7//refactor to ditch these things
8var nested = require('libnested')
9var pull = require('pull-stream')
10var URL = require('url')
11var QS = require('qs')
12var u = require('./util')
13var toHTML = u.toHTML
14var uniq = require('lodash.uniq')
15
16// middleware
17var Logger = require('morgan')
18var Emoji = require('emoji-server')
19var Static = require('ecstatic')
20var BodyParser = require('urlencoded-request-parser')
21var FavIcon = require('serve-favicon')
22var Coherence = require('coherence-framework')
23
24//actions may make writes to sbot, or can set things
25
26require('ssb-client')(function (err, sbot) {
27 if(err) throw err
28 sbot.identities.main(function (err, id) {
29 sbot.id = id
30
31 if(!sbot.id) throw new Error('sbot id missing')
32 var coherence = Coherence(require('./layout'))
33
34 //core: render an avatar, select
35 .use('avatar', require('./apis/avatar')(sbot))
36 .use('identitySelect', require('./apis/identity-select')(sbot))
37 //called by preview (to clarify who you are mentioning)
38 .use('mentions', require('./apis/mentions')(sbot))
39
40 .use('messageLink', require('./apis/message-link')(sbot))
41 .use('channelLink', require('./apis/channel-link')(sbot))
42
43 //render a single message
44 .use('message', require('./apis/message')(sbot))
45
46 //show how much things there are to do...
47 .use('progress', require('./apis/progress')(sbot))
48
49 //core message writing...
50 .use('preview', require('./apis/preview')(sbot))
51 .use('compose', require('./apis/compose')(sbot))
52 .use('publish', require('./apis/publish')(sbot))
53
54 //view (and filtered views) on the raw log
55 .use('public', require('./apis/public')(sbot))
56 .use('more', require('./apis/more')(sbot))
57 .use('private', require('./apis/private')(sbot))
58 .use('friends', require('./apis/friends')(sbot))
59 .use('search', require('./apis/search')(sbot))
60
61 //patchthreads
62 .use('thread', require('./apis/thread')(sbot))
63 .use('messages/post', require('./apis/messages/post')(sbot))
64 .use('messages/vote', require('./apis/messages/vote')(sbot))
65
66 var actions = {
67 //note: opts is post body
68
69 //sets id in cookie
70 identitySelect: function (opts, req, cb) {
71 var context = req.cookies
72 context.id = opts.id
73 cb(null, null, context)
74 },
75
76 //sets id in cookie
77 languageSelect: function (opts, req, cb) {
78 throw new Error('not implemented yet')
79 },
80
81 //theme, in cookie
82
83 publish: function (opts, req, cb) {
84 if(opts.content.recps === '')
85 delete opts.content.recps
86 else if('string' === typeof opts.content.recps) {
87 opts.content.recps = opts.content.recps.split(',')
88 }
89
90 if(Array.isArray(opts.content.recps))
91 opts.private = true
92 else if(opts.private && !opts.content.recps) {
93 opts.content.recps = uniq(
94 [opts.id]
95 .concat(opts.content.mentions || [])
96 .map(function (e) { return ref.isFeed(e) ? e : ref.isFeed(e.link) ? e.link : null })
97 .filter(Boolean)
98 )
99 }
100
101 sbot.identities.publishAs(opts, function (err, msg) {
102 if(err) cb(err)
103 else cb()
104 })
105 }
106 }
107
108 require('http').createServer(Stack(
109 Logger(),
110 //everything breaks if blobs isn't first, but not sure why?
111 require('ssb-ws/blobs')(sbot, {prefix: '/blobs'}),
112 FavIcon(path.join(__dirname, 'static', 'favicon.ico')),
113 BodyParser(),
114 /*
115 some settings we want to store in a cookie:
116 * current identity
117 * current language
118
119 stuff that shouldn't be in links.
120 this makes it possible to share links without including
121 state people might not want for them.
122 also: light/dark theme etc
123 */
124 function (req, res, next) {
125 //just do it this simple way because it works
126 //I tried the cookie parser middleware but things got weird.
127 req.cookies = QS.parse(req.headers.cookie||'') || {id: sbot.id}
128 next()
129 },
130 //handle posts.
131 function (req, res, next) {
132 if(req.method == 'GET') return next()
133 var id = req.cookies.id || sbot.id
134 var opts = req.body
135
136 // handle preview specially, (to confirm a message)
137
138 if(opts.type === 'preview') {
139 // TODO: pass opts.id in, and wether this message
140 // preview should allow recipient selection, or changing id.
141 // api.preview can set the shape of the message if it likes.
142
143 req.url = '/preview?'+QS.stringify(opts)
144 return coherence(req, res, next)
145 }
146 actions[opts.type](opts, req, function (err, _opts, context) {
147 if(err) return next(err)
148 if(context) {
149 req.cookies = context
150 res.setHeader('set-Cookie', QS.stringify(context))
151 }
152 /*
153 After handling the post, redirect to a normal page.
154 This is a work around for if you hit refresh
155 and the browser wants to resubmit the POST.
156
157 I think we want to do this for most types,
158 exception is for preview - in which we return
159 the same data rendered differently and don't write
160 to DB at all.
161
162 Should preview be implemented like this too?
163 */
164 res.setHeader('location', req.url)
165 res.writeHead(303)
166 res.end()
167 })
168 },
169
170 Emoji('/img/emoji'),
171 Static({
172 root: path.join(__dirname, 'static'), baseDir: '/static'
173 }),
174 coherence
175 )).listen(8005, 'localhost')
176
177 /*
178 generic ssb invalidation
179 if a message links to another, invalidate the other key.
180 (this will get threads, likes, etc)
181 if a message links to a feed, invalidate the feed.
182
183 that doesn't cover follows though... but maybe that can be invalidated
184 as one thing?
185 */
186
187 pull(
188 sbot.createLogStream({live: true, old: false, sync: false, private: true}),
189 pull.drain(function (data) {
190 nested.each(data.value.content, function (v) {
191 if(ref.isMsg(v))
192 coherence.invalidate(v, data.ts)
193 else if(ref.isFeed(v)) {
194 coherence.invalidate('in:'+v, data.ts)
195 coherence.invalidate('out:'+data.value.author, data.ts)
196 }
197 })
198 })
199 )
200})})
201
202
203
204
205
206

Built with git-ssb-web