export.js 3.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100
  1. import { Exporter } from './exporter';
  2. /* global JsonRoutes */
  3. if (Meteor.isServer) {
  4. // todo XXX once we have a real API in place, move that route there
  5. // todo XXX also share the route definition between the client and the server
  6. // so that we could use something like
  7. // `ApiRoutes.path('boards/export', boardId)``
  8. // on the client instead of copy/pasting the route path manually between the
  9. // client and the server.
  10. /**
  11. * @operation exportJson
  12. * @tag Boards
  13. *
  14. * @summary This route is used to export the board to a json file format.
  15. *
  16. * @description If user is already logged-in, pass loginToken as param
  17. * "authToken": '/api/boards/:boardId/export?authToken=:token'
  18. *
  19. * See https://blog.kayla.com.au/server-side-route-authentication-in-meteor/
  20. * for detailed explanations
  21. *
  22. * @param {string} boardId the ID of the board we are exporting
  23. * @param {string} authToken the loginToken
  24. */
  25. JsonRoutes.add('get', '/api/boards/:boardId/export', function(req, res) {
  26. const boardId = req.params.boardId;
  27. let user = null;
  28. const loginToken = req.query.authToken;
  29. if (loginToken) {
  30. const hashToken = Accounts._hashLoginToken(loginToken);
  31. user = Meteor.users.findOne({
  32. 'services.resume.loginTokens.hashedToken': hashToken,
  33. });
  34. } else if (!Meteor.settings.public.sandstorm) {
  35. Authentication.checkUserId(req.userId);
  36. user = Users.findOne({ _id: req.userId, isAdmin: true });
  37. }
  38. const exporter = new Exporter(boardId);
  39. if (exporter.canExport(user)) {
  40. JsonRoutes.sendResult(res, {
  41. code: 200,
  42. data: exporter.build(),
  43. });
  44. } else {
  45. // we could send an explicit error message, but on the other hand the only
  46. // way to get there is by hacking the UI so let's keep it raw.
  47. JsonRoutes.sendResult(res, 403);
  48. }
  49. });
  50. /**
  51. * @operation exportCSV/TSV
  52. * @tag Boards
  53. *
  54. * @summary This route is used to export the board to a CSV or TSV file format.
  55. *
  56. * @description If user is already logged-in, pass loginToken as param
  57. *
  58. * See https://blog.kayla.com.au/server-side-route-authentication-in-meteor/
  59. * for detailed explanations
  60. *
  61. * @param {string} boardId the ID of the board we are exporting
  62. * @param {string} authToken the loginToken
  63. * @param {string} delimiter delimiter to use while building export. Default is comma ','
  64. */
  65. Picker.route('/api/boards/:boardId/export/csv', function(params, req, res) {
  66. const boardId = params.boardId;
  67. let user = null;
  68. const loginToken = params.query.authToken;
  69. if (loginToken) {
  70. const hashToken = Accounts._hashLoginToken(loginToken);
  71. user = Meteor.users.findOne({
  72. 'services.resume.loginTokens.hashedToken': hashToken,
  73. });
  74. } else if (!Meteor.settings.public.sandstorm) {
  75. Authentication.checkUserId(req.userId);
  76. user = Users.findOne({
  77. _id: req.userId,
  78. isAdmin: true,
  79. });
  80. }
  81. const exporter = new Exporter(boardId);
  82. if (exporter.canExport(user)) {
  83. body = params.query.delimiter
  84. ? exporter.buildCsv(params.query.delimiter)
  85. : exporter.buildCsv();
  86. res.writeHead(200, {
  87. // Checking length does not work https://github.com/wekan/wekan/issues/3173
  88. // so not using it here
  89. //'Content-Length': body.length,
  90. 'Content-Type': params.query.delimiter ? 'text/csv' : 'text/tsv',
  91. });
  92. res.write(body);
  93. res.end();
  94. } else {
  95. res.writeHead(403);
  96. res.end('Permission Error');
  97. }
  98. });
  99. }