forked from steemit/condenser
-
Notifications
You must be signed in to change notification settings - Fork 0
/
server.js
162 lines (144 loc) · 5.42 KB
/
server.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
if(process.env.NEW_RELIC_APP_NAME) require('newrelic');
import path from 'path';
import Koa from 'koa';
import mount from 'koa-mount';
import helmet from 'koa-helmet';
import koa_logger from 'koa-logger';
import prod_logger from './prod_logger';
import favicon from 'koa-favicon';
import staticCache from 'koa-static-cache';
import useRedirects from './redirects';
import useOauthLogin from './api/oauth';
import useGeneralApi from './api/general';
import useAccountRecoveryApi from './api/account_recovery';
import useNotificationsApi from './api/notifications';
import useEnterAndConfirmEmailPages from './server_pages/enter_confirm_email';
import useEnterAndConfirmMobilePages from './server_pages/enter_confirm_mobile';
import isBot from 'koa-isbot';
import session from 'koa-session';
import csrf from 'koa-csrf';
import flash from 'koa-flash';
import minimist from 'minimist';
import Grant from 'grant-koa';
import config from '../config';
import secureRandom from 'secure-random'
const grant = new Grant(config.grant);
// import uploadImage from 'server/upload-image' //medium-editor
const app = new Koa();
app.name = 'Steemit app';
const env = process.env.NODE_ENV || 'development';
const cacheOpts = {maxAge: 86400000, gzip: true};
app.keys = [config.session_key];
app.use(session({maxAge: 1000 * 3600 * 24 * 7}, app));
csrf(app);
app.use(mount(grant));
app.use(flash({key: 'flash'}));
// some redirects
app.use(function *(next) {
// redirect to home page/feed if known account
if (this.method === 'GET' && this.url === '/' && this.session.a) {
this.status = 302;
this.redirect(`/@${this.session.a}/feed`);
return;
}
// normalize user name url from cased params
if (this.method === 'GET' && /^\/(@[\w\.\d-]+)\/?$/.test(this.url)) {
const p = this.originalUrl.toLowerCase();
if(p !== this.originalUrl) {
this.redirect(p);
return;
}
}
// start registration process if user get to create_account page and has no id in session yet
if(this.url === '/create_account' && !this.session.user) {
this.status = 302;
this.redirect('/enter_email');
return;
}
// remember ch, cn, r url params in the session and remove them from url
if (this.method === 'GET' && /\?[^\w]*(ch=|cn=|r=)/.test(this.url)) {
let redir = this.url.replace(/((ch|cn|r)=[^&]+)/gi, r => {
const p = r.split('=');
if (p.length === 2) this.session[p[0]] = p[1];
return '';
});
redir = redir.replace(/&&&?/, '');
redir = redir.replace(/\?&?$/, '');
console.log(`server redirect ${this.url} -> ${redir}`);
this.status = 302;
this.redirect(redir);
} else {
yield next;
}
});
if (env === 'production') {
// load production middleware
app.use(require('koa-conditional-get')());
app.use(require('koa-etag')());
app.use(require('koa-compressor')());
app.use(prod_logger());
} else {
app.use(koa_logger());
}
app.use(helmet());
app.use(mount('/static', staticCache(path.join(__dirname, '../app/assets/static'), cacheOpts)));
app.use(mount('/robots.txt', function* () {
this.set('Cache-Control', 'public, max-age=86400000');
this.type = 'text/plain';
this.body = "User-agent: *\nAllow: /";
}));
// set user's uid - used to identify users in logs and some other places
app.use(function* (next) {
const last_visit = this.session.last_visit;
this.session.last_visit = (new Date()).getTime() / 1000 | 0;
if (!this.session.uid) {
this.session.uid = secureRandom.randomBuffer(13).toString('hex');
this.session.new_visit = true;
} else {
this.session.new_visit = this.session.last_visit - last_visit > 1800;
}
yield next;
});
useRedirects(app);
useEnterAndConfirmEmailPages(app);
useEnterAndConfirmMobilePages(app);
if (env === 'production') {
app.use(helmet.contentSecurityPolicy(config.helmet));
}
useAccountRecoveryApi(app);
useOauthLogin(app);
useGeneralApi(app);
useNotificationsApi(app);
app.use(favicon(path.join(__dirname, '../app/assets/images/favicons/favicon.ico')));
app.use(isBot());
app.use(mount('/favicons', staticCache(path.join(__dirname, '../app/assets/images/favicons'), cacheOpts)));
app.use(mount('/images', staticCache(path.join(__dirname, '../app/assets/images'), cacheOpts)));
// Proxy asset folder to webpack development server in development mode
if (env === 'development') {
const PORT = parseInt(process.env.PORT, 10) + 1 || 3001;
const proxy = require('koa-proxy')({
host: 'http://0.0.0.0:' + PORT,
map: (filePath) => 'assets/' + filePath
});
app.use(mount('/assets', proxy));
} else {
app.use(mount('/assets', staticCache(path.join(__dirname, '../dist'), cacheOpts)));
}
if (env !== 'test') {
const appRender = require('./app_render');
app.use(function* () {
yield appRender(this);
// if (app_router.dbStatus.ok) recordWebEvent(this, 'page_load');
const bot = this.state.isBot;
if (bot) {
console.log(` --> ${this.method} ${this.originalUrl} ${this.status} (BOT '${bot}')`);
}
});
const argv = minimist(process.argv.slice(2));
const port = parseInt(argv.port, 10) || parseInt(process.env.PORT, 10) || 3002;
app.listen(port);
// Tell parent process koa-server is started
if (process.send) process.send('online');
console.log(`Application started on port ${port}`);
}
module.exports = app;