Source: octokit/index.js

  1. /**
  2. * @module octokit
  3. */
  4. const {request} = require("@octokit/request");
  5. const log = require("../../util/log");
  6. const digest = require("../digest");
  7. /**
  8. * Cryptographically anonymise the data of an issue body
  9. * to ensure privacy of users.
  10. * Anonymise the following parameters (if present):
  11. * email, ip, name, reCAPTCHA response.
  12. * The anonymised data can be used for reference by server
  13. * admins with the possession of the server's secret.
  14. * @param {Object} data
  15. * @return {Object} anonymised data
  16. */
  17. const anonymiseData = (data) => {
  18. if (data.email) {
  19. const anonId = digest.hashPassWithSaltInHex(
  20. data.email,
  21. process.env.SERVER_SECRET,
  22. );
  23. data.email = anonId;
  24. }
  25. if (data.ip) {
  26. const anonIp = digest.hashPassWithSaltInHex(
  27. data.ip,
  28. process.env.SERVER_SECRET,
  29. );
  30. data.ip = anonIp;
  31. }
  32. if (data.name) {
  33. const anonName = digest.hashPassWithSaltInHex(
  34. data.name,
  35. process.env.SERVER_SECRET,
  36. );
  37. data.name = anonName;
  38. }
  39. if (data['g-recaptcha-response']) {
  40. const anonRes = digest.hashPassWithSaltInHex(
  41. data['g-recaptcha-response'],
  42. process.env.SERVER_SECRET,
  43. );
  44. data['g-recaptcha-response'] = anonRes;
  45. }
  46. if (data['_csrf']) {
  47. const anonRes = digest.hashPassWithSaltInHex(
  48. data['_csrf'],
  49. process.env.SERVER_SECRET,
  50. );
  51. data['_csrf'] = anonRes;
  52. }
  53. return data;
  54. };
  55. /**
  56. * Create markdown formatted issue body string
  57. * from pretty printed issue data and metadata.
  58. * @param {Object} data
  59. * @return {String} markdown formatted issue body
  60. */
  61. const createIssueBody = (data) => {
  62. return `### ${data.subject ? data.subject : 'Route ' + data.originalUrl}\n\n` +
  63. `${data.report ? data.report : data.message}\n\n` +
  64. 'Metadata:\n```yaml\n' +
  65. JSON.stringify(data, null, 4) +
  66. '\n```';
  67. };
  68. /**
  69. * Create bugreport Github issue:
  70. * Anonymise PII in bugreport, create
  71. * formatted issue body and post the
  72. * issue to Github via Github API.
  73. * @param {Object} bugreport
  74. */
  75. const createBugreportIssue = async (bugreport) => {
  76. await createIssue(
  77. `[bugreport] ${bugreport.subject ? bugreport.subject : 'Auto bugreport for route ' + bugreport.originalUrl}`,
  78. createIssueBody(anonymiseData(bugreport)),
  79. "bugreport",
  80. );
  81. };
  82. /**
  83. * Create feature request Github issue:
  84. * Anonymise PII in feature request, create
  85. * formatted issue body and post the
  86. * issue to Github via Github API.
  87. * @param {Object} featureRequest
  88. */
  89. const createFeatureRequestIssue = async (featureRequest) => {
  90. await createIssue(
  91. `[feature request] ${featureRequest.subject}`,
  92. createIssueBody(anonymiseData(featureRequest)),
  93. "feature request",
  94. );
  95. };
  96. /**
  97. * Create an issue on Github via Github API
  98. * with given issue title, body and label.
  99. * @param {String} title
  100. * @param {String} body
  101. * @param {String} label
  102. */
  103. const createIssue = async (title, body, label) => {
  104. try {
  105. if (process.env.CREATE_GITHUB_ISSUES === '0') {
  106. log.info("Skipping creation of Github Issue - %s", title);
  107. return;
  108. }
  109. log.info("Creating Github Issue - %s", title);
  110. await request("POST /repos/almasen/rdf-mapped/issues", {
  111. headers: {
  112. authorization: `token ${process.env.GITHUB_TOKEN}`,
  113. },
  114. title,
  115. body,
  116. labels: [label],
  117. });
  118. log.info("Successfully created Github Issue - %s", title);
  119. } catch (error) {
  120. log.error("Github Issue creation FAILED, err: " + error.message);
  121. };
  122. };
  123. module.exports = {
  124. createBugreportIssue,
  125. createFeatureRequestIssue,
  126. };