Files: 8c686fb2b73c28246604759c61d6636e2812d871 / index.js
5160 bytesRaw
1 | var fs = require('fs') |
2 | var path = require('path') |
3 | var ref = require('ssb-ref') |
4 | var Stack = require('stack') |
5 | |
6 | //refactor to ditch these things |
7 | var nested = require('libnested') |
8 | var URL = require('url') |
9 | var QS = require('qs') |
10 | var u = require('./util') |
11 | var toHTML = u.toHTML |
12 | |
13 | // middleware |
14 | var Logger = require('morgan') |
15 | var Emoji = require('emoji-server') |
16 | var Static = require('ecstatic') |
17 | var BodyParser = require('urlencoded-request-parser') |
18 | var FavIcon = require('serve-favicon') |
19 | var Coherence = require('coherence-framework') |
20 | |
21 | //actions may make writes to sbot, or can set things |
22 | |
23 | require('ssb-client')(function (err, sbot) { |
24 | if(err) throw err |
25 | |
26 | var coherence = Coherence(require('./layout')) |
27 | .use('avatar', require('./apis/avatar')(sbot)) |
28 | .use('identitySelect', require('./apis/identity-select')(sbot)) |
29 | .use('public', require('./apis/public')(sbot)) |
30 | .use('private', require('./apis/private')(sbot)) |
31 | .use('message', require('./apis/message')(sbot)) |
32 | .use('messageLink', require('./apis/message-link')(sbot)) |
33 | .use('channelLink', require('./apis/channel-link')(sbot)) |
34 | .use('messages/post', require('./apis/messages/post')(sbot)) |
35 | .use('messages/vote', require('./apis/messages/vote')(sbot)) |
36 | .use('progress', require('./apis/progress')(sbot)) |
37 | .use('thread', require('./apis/thread')(sbot)) |
38 | .use('compose', require('./apis/compose')(sbot)) |
39 | .use('publish', require('./apis/publish')(sbot)) |
40 | .use('preview', require('./apis/preview')(sbot)) |
41 | .use('friends', require('./apis/friends')(sbot)) |
42 | .use('search', require('./apis/search')(sbot)) |
43 | .use('mentions', require('./apis/mentions')(sbot)) |
44 | |
45 | var actions = { |
46 | //note: opts is post body |
47 | |
48 | //sets id in cookie |
49 | identitySelect: function (opts, req, cb) { |
50 | var context = req.cookies |
51 | context.id = opts.id |
52 | cb(null, null, context) |
53 | }, |
54 | |
55 | //sets id in cookie |
56 | languageSelect: function (opts, req, cb) { |
57 | throw new Error('not implemented yet') |
58 | }, |
59 | |
60 | //theme, in cookie |
61 | |
62 | publish: function (opts, req, cb) { |
63 | if(opts.content.recps === '') |
64 | delete opts.content.recps |
65 | else if('string' === typeof opts.content.recps) { |
66 | opts.content.recps = opts.content.recps.split(',') |
67 | } |
68 | |
69 | if(Array.isArray(opts.content.recps)) |
70 | opts.private = true |
71 | |
72 | sbot.identities.publishAs(opts, function (err, msg) { |
73 | if(err) cb(err) |
74 | else cb() |
75 | }) |
76 | } |
77 | } |
78 | |
79 | require('http').createServer(Stack( |
80 | Logger(), |
81 | //everything breaks if blobs isn't first, but not sure why? |
82 | require('ssb-ws/blobs')(sbot, {prefix: '/blobs'}), |
83 | FavIcon(path.join(__dirname, 'static', 'favicon.ico')), |
84 | BodyParser(), |
85 | /* |
86 | some settings we want to store in a cookie: |
87 | * current identity |
88 | * current language |
89 | |
90 | stuff that shouldn't be in links. |
91 | this makes it possible to share links without including |
92 | state people might not want for them. |
93 | also: light/dark theme etc |
94 | */ |
95 | function (req, res, next) { |
96 | //just do it this simple way because it works |
97 | //I tried the cookie parser middleware but things got weird. |
98 | req.cookies = QS.parse(req.headers.cookie||'') || {id: sbot.id} |
99 | next() |
100 | }, |
101 | //handle posts. |
102 | function (req, res, next) { |
103 | if(req.method == 'GET') return next() |
104 | var id = req.cookies.id || sbot.id |
105 | var opts = req.body |
106 | |
107 | // handle preview specially, (to confirm a message) |
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 | return coherence(req, res, next) |
116 | } |
117 | actions[opts.type](opts, req, function (err, _opts, context) { |
118 | if(err) return next(err) |
119 | if(context) { |
120 | req.cookies = context |
121 | res.setHeader('set-Cookie', QS.stringify(context)) |
122 | } |
123 | /* |
124 | After handling the post, redirect to a normal page. |
125 | This is a work around for if you hit refresh |
126 | and the browser wants to resubmit the POST. |
127 | |
128 | I think we want to do this for most types, |
129 | exception is for preview - in which we return |
130 | the same data rendered differently and don't write |
131 | to DB at all. |
132 | |
133 | Should preview be implemented like this too? |
134 | */ |
135 | res.setHeader('location', req.url) |
136 | res.writeHead(303) |
137 | res.end() |
138 | }) |
139 | }, |
140 | |
141 | Emoji('/img/emoji'), |
142 | Static({ |
143 | root: path.join(__dirname, 'static'), baseDir: '/static' |
144 | }), |
145 | coherence |
146 | )).listen(8005, 'localhost') |
147 | |
148 | /* |
149 | generic ssb invalidation |
150 | if a message links to another, invalidate the other key. |
151 | (this will get threads, likes, etc) |
152 | if a message links to a feed, invalidate the feed. |
153 | |
154 | that doesn't cover follows though... but maybe that can be invalidated |
155 | as one thing? |
156 | */ |
157 | }) |
158 | |
159 | |
160 |
Built with git-ssb-web