diff --git a/lib/response.js b/lib/response.js index 66e01bb5..a0424432 100644 --- a/lib/response.js +++ b/lib/response.js @@ -65,69 +65,73 @@ function githubActions (req, res, next) { function githubActionGist (req, res, note) { const code = req.query.code const state = req.query.state - if (!code || !state) { + const sessionsState = req.session.githubGistState + const redirectUri = req.session.githubGistRedirectUri + delete req.session.githubGistState + delete req.session.githubGistRedirectUri + if (!code || !state || sessionsState !== state) { return errors.errorForbidden(res) - } else { - const data = { - client_id: config.github.clientID, - client_secret: config.github.clientSecret, - code, - state + } + + const data = { + client_id: config.github.clientID, + client_secret: config.github.clientSecret, + code, + redirect_uri: redirectUri + } + 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' } - const authUrl = 'https://github.com/login/oauth/access_token' - fetch(authUrl, { + }).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 + } + const gistUrl = 'https://api.github.com/gists' + return fetch(gistUrl, { method: 'POST', - body: JSON.stringify(data), + body: JSON.stringify(gist), headers: { + 'User-Agent': 'HedgeDoc', + Authorization: 'token ' + accessToken, '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 - } - 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) }) - } + }).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) { diff --git a/lib/web/note/actions.js b/lib/web/note/actions.js index 61eab0ee..aa673c75 100644 --- a/lib/web/note/actions.js +++ b/lib/web/note/actions.js @@ -32,11 +32,15 @@ exports.getInfo = function getInfo (req, res, note) { } exports.createGist = function createGist (req, res, note) { + const state = nanoid.nanoid() + const redirectUri = config.serverURL + '/auth/github/callback/' + models.Note.encodeNoteId(note.id) + '/gist' + req.session.githubGistState = state + req.session.githubGistRedirectUri = redirectUri const data = { client_id: config.github.clientID, - redirect_uri: config.serverURL + '/auth/github/callback/' + models.Note.encodeNoteId(note.id) + '/gist', + redirect_uri: redirectUri, scope: 'gist', - state: nanoid.nanoid() + state } const query = querystring.stringify(data) res.redirect('https://github.com/login/oauth/authorize?' + query)