You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

316 lines
6.7 KiB

  1. 'use strict'
  2. /* global entries, git, lang, winston */
  3. const express = require('express')
  4. const router = express.Router()
  5. const _ = require('lodash')
  6. const entryHelper = require('../helpers/entry')
  7. // ==========================================
  8. // EDIT MODE
  9. // ==========================================
  10. /**
  11. * Edit document in Markdown
  12. */
  13. router.get('/edit/*', (req, res, next) => {
  14. if (!res.locals.rights.write) {
  15. return res.render('error-forbidden')
  16. }
  17. let safePath = entryHelper.parsePath(_.replace(req.path, '/edit', ''))
  18. entries.fetchOriginal(safePath, {
  19. parseMarkdown: false,
  20. parseMeta: true,
  21. parseTree: false,
  22. includeMarkdown: true,
  23. includeParentInfo: false,
  24. cache: false
  25. }).then((pageData) => {
  26. if (pageData) {
  27. res.render('pages/edit', { pageData })
  28. } else {
  29. throw new Error(lang.t('errors:invalidpath'))
  30. }
  31. return true
  32. }).catch((err) => {
  33. res.render('error', {
  34. message: err.message,
  35. error: {}
  36. })
  37. })
  38. })
  39. router.put('/edit/*', (req, res, next) => {
  40. if (!res.locals.rights.write) {
  41. return res.json({
  42. ok: false,
  43. error: lang.t('errors:forbidden')
  44. })
  45. }
  46. let safePath = entryHelper.parsePath(_.replace(req.path, '/edit', ''))
  47. entries.update(safePath, req.body.markdown, req.user).then(() => {
  48. return res.json({
  49. ok: true
  50. }) || true
  51. }).catch((err) => {
  52. res.json({
  53. ok: false,
  54. error: err.message
  55. })
  56. })
  57. })
  58. // ==========================================
  59. // CREATE MODE
  60. // ==========================================
  61. router.get('/create/*', (req, res, next) => {
  62. if (!res.locals.rights.write) {
  63. return res.render('error-forbidden')
  64. }
  65. if (_.some(['create', 'edit', 'account', 'source', 'history', 'mk', 'all'], (e) => { return _.startsWith(req.path, '/create/' + e) })) {
  66. return res.render('error', {
  67. message: lang.t('errors:reservedname'),
  68. error: {}
  69. })
  70. }
  71. let safePath = entryHelper.parsePath(_.replace(req.path, '/create', ''))
  72. entries.exists(safePath).then((docExists) => {
  73. if (!docExists) {
  74. return entries.getStarter(safePath).then((contents) => {
  75. let pageData = {
  76. markdown: contents,
  77. meta: {
  78. title: _.startCase(safePath),
  79. path: safePath
  80. }
  81. }
  82. res.render('pages/create', { pageData })
  83. return true
  84. }).catch((err) => {
  85. winston.warn(err)
  86. throw new Error(lang.t('errors:starterfailed'))
  87. })
  88. } else {
  89. throw new Error(lang.t('errors:alreadyexists'))
  90. }
  91. }).catch((err) => {
  92. res.render('error', {
  93. message: err.message,
  94. error: {}
  95. })
  96. })
  97. })
  98. router.put('/create/*', (req, res, next) => {
  99. if (!res.locals.rights.write) {
  100. return res.json({
  101. ok: false,
  102. error: lang.t('errors:forbidden')
  103. })
  104. }
  105. let safePath = entryHelper.parsePath(_.replace(req.path, '/create', ''))
  106. entries.create(safePath, req.body.markdown, req.user).then(() => {
  107. return res.json({
  108. ok: true
  109. }) || true
  110. }).catch((err) => {
  111. return res.json({
  112. ok: false,
  113. error: err.message
  114. })
  115. })
  116. })
  117. // ==========================================
  118. // LIST ALL PAGES
  119. // ==========================================
  120. /**
  121. * View tree view of all pages
  122. */
  123. router.use((req, res, next) => {
  124. if (_.endsWith(req.url, '/all')) {
  125. res.render('pages/all')
  126. } else {
  127. next()
  128. }
  129. })
  130. // ==========================================
  131. // VIEW MODE
  132. // ==========================================
  133. /**
  134. * View source of a document
  135. */
  136. router.get('/source/*', (req, res, next) => {
  137. let safePath = entryHelper.parsePath(_.replace(req.path, '/source', ''))
  138. entries.fetchOriginal(safePath, {
  139. parseMarkdown: false,
  140. parseMeta: true,
  141. parseTree: false,
  142. includeMarkdown: true,
  143. includeParentInfo: false,
  144. cache: false
  145. }).then((pageData) => {
  146. if (pageData) {
  147. res.render('pages/source', { pageData })
  148. } else {
  149. throw new Error(lang.t('errors:invalidpath'))
  150. }
  151. return true
  152. }).catch((err) => {
  153. res.render('error', {
  154. message: err.message,
  155. error: {}
  156. })
  157. })
  158. })
  159. /**
  160. * View history of a document
  161. */
  162. router.get('/hist/*', (req, res, next) => {
  163. let safePath = entryHelper.parsePath(_.replace(req.path, '/hist', ''))
  164. entries.getHistory(safePath).then((pageData) => {
  165. if (pageData) {
  166. res.render('pages/history', { pageData })
  167. } else {
  168. throw new Error(lang.t('errors:invalidpath'))
  169. }
  170. return true
  171. }).catch((err) => {
  172. res.render('error', {
  173. message: err.message,
  174. error: {}
  175. })
  176. })
  177. })
  178. /**
  179. * View history of a document
  180. */
  181. router.post('/hist', (req, res, next) => {
  182. let commit = req.body.commit
  183. let safePath = entryHelper.parsePath(req.body.path)
  184. if (!/^[a-f0-9]{40}$/.test(commit)) {
  185. return res.status(400).json({ ok: false, error: 'Invalid commit' })
  186. }
  187. git.getHistoryDiff(safePath, commit).then((diff) => {
  188. res.json({ ok: true, diff })
  189. return true
  190. }).catch((err) => {
  191. res.status(500).json({ ok: false, error: err.message })
  192. })
  193. })
  194. /**
  195. * View document
  196. */
  197. router.get('/*', (req, res, next) => {
  198. let safePath = entryHelper.parsePath(req.path)
  199. entries.fetch(safePath).then((pageData) => {
  200. if (pageData) {
  201. res.render('pages/view', { pageData })
  202. } else {
  203. res.render('error-notexist', {
  204. newpath: safePath
  205. })
  206. }
  207. return true
  208. }).error((err) => {
  209. if (safePath === 'home') {
  210. res.render('pages/welcome')
  211. } else {
  212. res.render('error-notexist', {
  213. message: err.message,
  214. newpath: safePath
  215. })
  216. }
  217. return true
  218. }).catch((err) => {
  219. res.render('error', {
  220. message: err.message,
  221. error: {}
  222. })
  223. })
  224. })
  225. /**
  226. * Move document
  227. */
  228. router.put('/*', (req, res, next) => {
  229. if (!res.locals.rights.write) {
  230. return res.json({
  231. ok: false,
  232. error: lang.t('errors:forbidden')
  233. })
  234. }
  235. let safePath = entryHelper.parsePath(req.path)
  236. if (_.isEmpty(req.body.move)) {
  237. return res.json({
  238. ok: false,
  239. error: lang.t('errors:invalidaction')
  240. })
  241. }
  242. let safeNewPath = entryHelper.parsePath(req.body.move)
  243. entries.move(safePath, safeNewPath, req.user).then(() => {
  244. res.json({
  245. ok: true
  246. })
  247. }).catch((err) => {
  248. res.json({
  249. ok: false,
  250. error: err.message
  251. })
  252. })
  253. })
  254. /**
  255. * Delete document
  256. */
  257. router.delete('/*', (req, res, next) => {
  258. if (!res.locals.rights.write) {
  259. return res.json({
  260. ok: false,
  261. error: lang.t('errors:forbidden')
  262. })
  263. }
  264. let safePath = entryHelper.parsePath(req.path)
  265. entries.remove(safePath, req.user).then(() => {
  266. res.json({
  267. ok: true
  268. })
  269. }).catch((err) => {
  270. res.json({
  271. ok: false,
  272. error: err.message
  273. })
  274. })
  275. })
  276. module.exports = router