hedgedoc/lib/response.js
Tilman Vatteroth d7a3e0f58c
Don't throw error if gitlab response is not okay-ish
Signed-off-by: Tilman Vatteroth <git@tilmanvatteroth.de>
2021-10-29 20:57:20 +02:00

184 lines
4.9 KiB
JavaScript

'use strict'
// response
// external modules
const fs = require('fs')
const path = require('path')
const fetch = require('node-fetch')
// core
const config = require('./config')
const logger = require('./logger')
const models = require('./models')
const noteUtil = require('./web/note/util')
const errors = require('./errors')
// public
const response = {
showIndex: showIndex,
githubActions: githubActions,
gitlabActions: gitlabActions
}
function showIndex (req, res, next) {
const authStatus = req.isAuthenticated()
const deleteToken = ''
const data = {
signin: authStatus,
infoMessage: req.flash('info'),
errorMessage: req.flash('error'),
imprint: fs.existsSync(path.join(config.docsPath, 'imprint.md')),
privacyStatement: fs.existsSync(path.join(config.docsPath, 'privacy.md')),
termsOfUse: fs.existsSync(path.join(config.docsPath, 'terms-of-use.md')),
deleteToken: deleteToken
}
if (authStatus) {
models.User.findOne({
where: {
id: req.user.id
}
}).then(function (user) {
if (user) {
data.deleteToken = user.deleteToken
res.render('index.ejs', data)
}
})
} else {
res.render('index.ejs', data)
}
}
function githubActions (req, res, next) {
const noteId = req.params.noteId
noteUtil.findNote(req, res, function (note) {
const action = req.params.action
switch (action) {
case 'gist':
githubActionGist(req, res, note)
break
default:
res.redirect(config.serverURL + '/' + noteId)
break
}
})
}
function githubActionGist (req, res, note) {
const code = req.query.code
const state = req.query.state
if (!code || !state) {
return errors.errorForbidden(res)
} else {
const data = {
client_id: config.github.clientID,
client_secret: config.github.clientSecret,
code: code,
state: state
}
const authUrl = 'https://github.com/login/oauth/access_token'
fetch(authUrl, {
method: 'POST',
body: JSON.stringify(data),
headers: {
'Content-Type': 'application/json',
Accept: 'application/json'
}
}).then(resp => {
if (!resp.ok) {
throw new Error('forbidden')
}
return resp.json()
}).then(body => {
const accessToken = body.access_token
if (!accessToken) {
throw new Error('forbidden')
}
const content = note.content
const title = models.Note.decodeTitle(note.title)
const filename = title.replace('/', ' ') + '.md'
const gist = {
files: {}
}
gist.files[filename] = {
content: content
}
const gistUrl = 'https://api.github.com/gists'
return fetch(gistUrl, {
method: 'POST',
body: JSON.stringify(gist),
headers: {
'User-Agent': 'HedgeDoc',
Authorization: 'token ' + accessToken,
'Content-Type': 'application/json',
Accept: 'application/json'
}
})
}).then(resp => {
if (resp.status !== 201) {
throw new Error('forbidden')
}
return resp.json()
}).then(body => {
res.setHeader('referer', '')
res.redirect(body.html_url)
}).catch(error => {
if (error.message === 'forbidden') {
return errors.errorForbidden(res)
}
logger.error('GitHub Gist auth failed: ' + error)
return errors.errorInternalError(res)
})
}
}
function gitlabActions (req, res, next) {
const noteId = req.params.noteId
noteUtil.findNote(req, res, function (note) {
const action = req.params.action
switch (action) {
case 'projects':
gitlabActionProjects(req, res, note)
break
default:
res.redirect(config.serverURL + '/' + noteId)
break
}
})
}
function gitlabActionProjects (req, res, note) {
if (req.isAuthenticated()) {
models.User.findOne({
where: {
id: req.user.id
}
}).then(function (user) {
if (!user) {
return errors.errorNotFound(res)
}
const ret = { baseURL: config.gitlab.baseURL, version: config.gitlab.version }
ret.accesstoken = user.accessToken
ret.profileid = user.profileid
const apiUrl = `${config.gitlab.baseURL}/api/${config.gitlab.version}/projects?membership=yes&per_page=100&access_token=${user.accessToken}`
fetch(apiUrl).then(resp => {
if (!resp.ok) {
res.send(ret)
return Promise.reject(new Error('HTTP request returned not okay-ish status'))
}
return resp.json()
}).then(body => {
ret.projects = body
return res.send(ret)
}).catch(err => {
logger.error('gitlab action projects failed: ', err)
})
}).catch(function (err) {
logger.error('gitlab action projects failed: ' + err)
return errors.errorInternalError(res)
})
} else {
return errors.errorForbidden(res)
}
}
module.exports = response