hackmd.js 2.7 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697
  1. const logger = require('@alias/logger')('growi:routes:hackmd');
  2. const path = require('path');
  3. const swig = require('swig-templates');
  4. const axios = require('axios');
  5. const ApiResponse = require('../util/apiResponse');
  6. module.exports = function(crowi, app) {
  7. const Page = crowi.models.Page;
  8. // load GROWI agent script for HackMD
  9. const manifest = require(path.join(crowi.publicDir, 'manifest.json'));
  10. const agentScriptPath = path.join(crowi.publicDir, manifest['js/agent-for-hackmd.js']);
  11. // generate swig template
  12. let agentScriptContentTpl = undefined;
  13. /**
  14. * loadAgent action
  15. * This should be access from HackMD and send agent script
  16. *
  17. * @param {object} req
  18. * @param {object} res
  19. */
  20. const loadAgent = function(req, res) {
  21. // generate swig template
  22. if (agentScriptContentTpl == null) {
  23. agentScriptContentTpl = swig.compileFile(agentScriptPath);
  24. }
  25. const origin = `${req.protocol}://${req.get('host')}`;
  26. const styleFilePath = origin + manifest['styles/style-hackmd.css'];
  27. // generate definitions to replace
  28. const definitions = {
  29. origin,
  30. styleFilePath,
  31. };
  32. // inject
  33. const script = agentScriptContentTpl(definitions);
  34. res.set('Content-Type', 'application/javascript');
  35. res.send(script);
  36. };
  37. /**
  38. * Create page on HackMD and start to integrate
  39. * @param {object} req
  40. * @param {object} res
  41. */
  42. const integrate = async function(req, res) {
  43. // validate process.env.HACKMD_URI
  44. const hackMdUri = process.env.HACKMD_URI;
  45. if (hackMdUri == null) {
  46. return res.json(ApiResponse.error('HackMD for GROWI has not been setup'));
  47. }
  48. // validate pageId
  49. const pageId = req.body.pageId;
  50. if (pageId == null) {
  51. return res.json(ApiResponse.error('pageId required'));
  52. }
  53. // validate page
  54. const page = await Page.findOne({ _id: pageId });
  55. if (page == null) {
  56. return res.json(ApiResponse.error(`Page('${pageId}') does not exist`));
  57. }
  58. if (page.pageIdOnHackmd != null) {
  59. return res.json(ApiResponse.error(`'pageIdOnHackmd' of the page '${page.path}' is not empty`));
  60. }
  61. // access to HackMD and create page
  62. const response = await axios.get(`${hackMdUri}/new`);
  63. logger.debug('HackMD responds', response);
  64. // extract page id on HackMD
  65. const pagePathOnHackmd = response.request.path; // e.g. '/NC7bSRraT1CQO1TO7wjCPw'
  66. const pageIdOnHackmd = pagePathOnHackmd.substr(1); // strip the head '/'
  67. // persist
  68. try {
  69. await Page.registerHackmdPage(page, pageIdOnHackmd);
  70. const data = {
  71. pageIdOnHackmd,
  72. };
  73. return res.json(ApiResponse.success(data));
  74. }
  75. catch (err) {
  76. return res.json(ApiResponse.error(err));
  77. }
  78. };
  79. return {
  80. loadAgent,
  81. integrate,
  82. };
  83. };