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
|
const { Router } = require('express')
const {
getOauthToken,
getOauthUser,
getUserToken,
verifyUserToken,
fetchInstallation,
fetchInstallationRepos,
fetchKeyboardFiles,
createOauthFlowUrl,
createOauthReturnUrl,
commitChanges
} = require('../services/github')
const { parseKeymap } = require('../services/zmk/keymap')
const router = Router()
const authorize = async (req, res) => {
if (req.query.code) {
try {
const { data: oauth } = await getOauthToken(req.query.code)
const { data: user } = await getOauthUser(oauth.access_token)
const token = getUserToken(oauth, user)
res.redirect(createOauthReturnUrl(token))
} catch (err) {
const message = err.response ? err.response.data : err
console.error(message)
res.sendStatus(500)
}
} else {
res.redirect(createOauthFlowUrl())
}
}
const handleError = (err, req, res, next) => {
const message = err.response ? `[${err.response.status}] ${err.response.data}` : err
console.error(message, err)
if (err.response && err.response.status === 401) {
console.error('Received upstream authentication error', err.re)
return res.sendStatus(401)
}
res.sendStatus(500)
}
const authenticate = (req, res, next) => {
const header = req.headers.authorization
const token = (header || '').split(' ')[1]
if (!token) {
return res.sendStatus(401)
}
try {
req.user = verifyUserToken(token)
} catch (err) {
return res.sendStatus(401)
}
next()
}
const getInstallation = async (req, res, next) => {
const { user } = req
try {
const { data: installation } = await fetchInstallation(user.sub)
if (!installation) {
return res.json({ installation: null })
}
const repositories = await fetchInstallationRepos(user.oauth_access_token, installation.id)
res.json({ installation, repositories })
} catch (err) {
next(err)
}
}
const getKeyboardFiles = async (req, res, next) => {
const { installationId, repository } = req.params
try {
const keyboardFiles = await fetchKeyboardFiles(installationId, repository)
keyboardFiles.keymap = parseKeymap(keyboardFiles.keymap)
res.json(keyboardFiles)
} catch (err) {
next(err)
}
}
const updateKeyboardFiles = async (req, res, next) => {
const { installationId, repository } = req.params
const { keymap, layout } = req.body
try {
await commitChanges(installationId, repository, layout, keymap)
} catch (err) {
return next(err)
}
res.sendStatus(200)
}
const receiveWebhook = (req, res) => {
res.sendStatus(200)
}
router.get('/authorize', authorize)
router.get('/installation', authenticate, getInstallation)
router.get('/keyboard-files/:installationId/:repository', authenticate, getKeyboardFiles)
router.post('/keyboard-files/:installationId/:repository', authenticate, updateKeyboardFiles)
router.post('/webhook', receiveWebhook)
router.use(handleError)
module.exports = router
|