-
Notifications
You must be signed in to change notification settings - Fork 7
/
Copy pathserver.js
122 lines (99 loc) · 3.58 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
(async () => {
const express = require('express');
const compression = require('compression')
const fetch = require('node-fetch');
const FormData = require('form-data');
const { inspect } = require('util');
const fs = require('fs');
require('dotenv').config()
const {STRAVA_CLIENT_ID, STRAVA_CLIENT_SECRET} = process.env;
if (!STRAVA_CLIENT_ID) { throw "STRAVA_CLIENT_ID missing from env"; }
if (!STRAVA_CLIENT_SECRET) { throw "STRAVA_CLIENT_SECRET missing from env"; }
const indexTemplate = fs.readFileSync('public/index-template.html').toString();
const index = indexTemplate.replace('<!-- EXTRA_HEAD -->', process.env.EXTRA_HEAD || '');
fs.writeFileSync('public/index.html', index);
function addSearchParamsFromPairs(url, pairs) {
const searchParams = url.searchParams;
for (let [key, value] of Object.entries(pairs)) {
searchParams.append(key, value);
}
}
function formDataFromPairs(pairs) {
const formData = new FormData();
for (let [key, value] of Object.entries(pairs)) {
formData.append(key, value);
}
return formData
}
const app = express();
app.use(compression());
app.enable('trust proxy') // for herokuapp.com
let PORT = process.env.PORT;
if (process.env.NODE_ENV !== 'production') {
if (!PORT) {
PORT = await require('portfinder').getPortPromise();
}
console.log(`running in development mode: http://localhost:${PORT}/`);
const config = require('./webpack.config.js');
const compiler = require('webpack')(config);
app.use(require('webpack-dev-middleware')(compiler));
app.use(require('webpack-hot-middleware')(compiler));
} else {
if (!PORT) {
console.error('running in production mode, but no PORT env variable! exiting')
console.error(' [ did you mean to `yarn dev`? ]')
process.exit(1)
}
console.log(`running in production mode on ${PORT}`);
}
app.use(express.static('public'));
app.get('/api/redirect-to-auth', (req, res) => {
let redirectURL = new URL('https://www.strava.com/oauth/authorize');
addSearchParamsFromPairs(redirectURL, {
client_id: STRAVA_CLIENT_ID,
response_type: 'code',
redirect_uri: `${req.protocol}://${req.headers.host}/api/receive-auth-code`,
approval_prompt: 'force',
scope: 'read,activity:read,activity:read_all',
});
res.redirect(redirectURL.toString());
});
app.get('/api/receive-auth-code', async (req, res) => {
let redirectURL = new URL(`${req.protocol}://${req.headers.host}/`);
const authCode = req.query.code;
if (authCode) {
const resp = await fetch('https://www.strava.com/oauth/token', {
method: 'POST',
body: formDataFromPairs({
grant_type: 'authorization_code',
client_id: STRAVA_CLIENT_ID,
client_secret: STRAVA_CLIENT_SECRET,
code: authCode,
})
})
let token = await resp.json();
delete token.athlete;
addSearchParamsFromPairs(redirectURL, {
token: JSON.stringify(token),
});
}
res.redirect(redirectURL.toString());
});
app.get('/api/submit-refresh-token', async (req, res) => {
const refresh_token = req.query.refresh_token;
const resp = await fetch('https://www.strava.com/oauth/token', {
method: 'POST',
body: formDataFromPairs({
grant_type: 'refresh_token',
client_id: STRAVA_CLIENT_ID,
client_secret: STRAVA_CLIENT_SECRET,
refresh_token,
})
})
let token = await resp.json();
res.send(token);
});
app.listen(PORT, function () {
console.log('app.listen');
});
})();