Merge branch 'hotfix/21.56.9' into master
[gitter.git] / server / api / private / issue-mirror.js
blob65c142a0751adea68d7b9357078c7e6bd2e2a720
1 'use strict';
3 var env = require('gitter-web-env');
4 var logger = env.logger;
5 var stats = env.stats;
6 var StatusError = require('statuserror');
7 var GithubIssueService = require('gitter-web-github').GitHubIssueService;
8 var GitLabIssuableService = require('gitter-web-gitlab').GitLabIssuableService;
9 var processText = require('gitter-web-text-processor');
10 var util = require('util');
11 var highlight = require('highlight.js');
13 var EXPIRES_SECONDS = 180;
14 var EXPIRES_MILLISECONDS = EXPIRES_SECONDS * 1000;
16 function getIssueInfoFromQuery(query) {
17   var type = query.t ? String(query.t) : 'issue';
18   var provider = query.p ? String(query.p) : undefined;
19   var repo = query.r ? String(query.r) : undefined;
20   var iid = query.i ? String(query.i) : undefined;
22   if (repo && iid) {
23     return {
24       type: type,
25       provider: provider,
26       repo: repo,
27       iid: iid
28     };
29   }
31   return null;
34 module.exports = function(req, res, next) {
35   var issueQueryInfo = getIssueInfoFromQuery(req.query);
37   if (!issueQueryInfo || !issueQueryInfo.repo || !issueQueryInfo.iid) {
38     return next(new StatusError(400));
39   }
41   var getIssueInfoFromQueryPromise;
42   if (issueQueryInfo.provider === 'gitlab') {
43     var glService = new GitLabIssuableService(req.user, issueQueryInfo.type);
44     getIssueInfoFromQueryPromise = glService.getIssue(issueQueryInfo.repo, issueQueryInfo.iid);
45   } else {
46     var ghService = new GithubIssueService(req.user);
47     getIssueInfoFromQueryPromise = ghService.getIssue(issueQueryInfo.repo, issueQueryInfo.iid);
48   }
50   return getIssueInfoFromQueryPromise
51     .then(function(issueInfo) {
52       res.setHeader('Cache-Control', 'public, max-age=' + EXPIRES_SECONDS);
53       res.setHeader('Expires', new Date(Date.now() + EXPIRES_MILLISECONDS).toUTCString());
55       if (req.query.renderMarkdown && issueInfo.body) {
56         return processText(issueInfo.body).then(function(result) {
57           issueInfo.bodyHtml = result.html;
58           return issueInfo;
59         });
60       }
62       // TODO: handle async processing of diffs
63       if (
64         req.query.renderPatchIfSingle &&
65         issueInfo.files &&
66         issueInfo.files.length === 1 &&
67         issueInfo.files[0].patch
68       ) {
69         issueInfo.files[0].patch_html = util.format(
70           '<pre><code>%s</code></pre>',
71           highlight.highlight('diff', issueInfo.files[0].patch).value
72         );
73       }
75       return issueInfo;
76     })
77     .then(function(issueInfo) {
78       res.send(issueInfo);
79     })
80     .catch(function(e) {
81       stats.eventHF('issue.state.query.fail', 1, 1);
83       logger.warn(
84         'Unable to obtain issue state for ' +
85           issueQueryInfo.provider +
86           ' ' +
87           issueQueryInfo.repo +
88           '/' +
89           issueQueryInfo.iid +
90           ': ' +
91           e,
92         { exception: e }
93       );
94       throw e;
95     })
96     .catch(next);