-
Notifications
You must be signed in to change notification settings - Fork 3
/
server.js
115 lines (97 loc) · 3.12 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
import 'babel-polyfill';
import path from 'path';
import { parse } from 'url';
import express from 'express'
import session from 'express-session';
import helmet from 'helmet';
import next from 'next';
import passport from 'passport';
import bodyParser from 'body-parser';
import { graphqlExpress, graphiqlExpress } from 'apollo-server-express';
import { makeExecutableSchema } from 'graphql-tools';
import ytdl from 'ytdl-core';
import { ensureLoggedIn } from 'connect-ensure-login';
import storeBuilder from 'connect-session-sequelize';
import typeDefs from './graphql/schema';
import resolvers from './graphql/resolvers';
import { db, User } from './graphql/connectors';
import parseXml from './utils/parseXml';
import startCron from './utils/cron';
import { setupPassport, buildHelmetOptions } from './utils/auth';
const port = parseInt(process.env.PORT, 10) || 3000
const dev = process.env.NODE_ENV !== 'production'
const app = next({ dev });
const handle = app.getRequestHandler()
const server = express();
setupPassport();
startCron();
const schema = makeExecutableSchema({ typeDefs, resolvers });
const SequelizeStore = storeBuilder(session.Store);
if (process.env.PROXY === 'true') {
server.set('trust proxy', 1); // trust first proxy
}
// Middlewares
server.disable('x-powered-by');
server.use(helmet(buildHelmetOptions()));
server.use(bodyParser.json());
server.use(session({
store: new SequelizeStore({ db }),
secret: 'dogs',
name: 'session',
cookie: {
secure: process.env.HTTPS === 'true',
expires: new Date(Date.now() + 48 * 60 * 60 * 1000) // 48 hours
},
}));
server.use(passport.initialize());
server.use(passport.session());
app.prepare().then(() => {
server.use('/graphql', graphqlExpress((request, response) => ({
schema,
context: {
user: request.user,
request,
response,
},
})));
if (process.env.NODE_ENV !== 'production') {
server.use('/graphql-explorer', graphiqlExpress({
endpointURL: '/graphql',
}));
}
server.use('/videoplayback', ensureLoggedIn(), (req, res) => {
const { v: videoId } = req.query;
// Default timeout is 5 minutes, which is too short for videos
req.setTimeout(10 * 60 * 60 * 1000);
if (!ytdl.validateID(videoId)) {
res.status(400).send({
error: 'VALIDATION_ERROR',
reason: 'Invalid video id',
});
return;
}
ytdl(`https://youtube.com/watch?v=${videoId}`).pipe(res);
});
server.use('/subtitles', ensureLoggedIn(), async (req, res) => {
const { url } = req.query;
const result = await fetch(url);
if (!result.ok) {
res.status(500).send({
error: 'FETCH_ERROR',
reason: 'Failed to fetch the subtitles',
});
}
const xml = await result.text();
const payload = await parseXml(xml);
res.type('text/vtt').send(payload);
});
server.use('/sw.js', express.static(path.join(__dirname, '../.next/sw.js')));
server.get('*', (req, res) => {
const parsedUrl = parse(req.url, true);
return handle(req, res, parsedUrl);
})
server.listen(port, (err) => {
if (err) throw err
console.log(`> Ready on http://localhost:${port}`)
});
});