router.js 33 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106
  1. const AdminController = require('./Features/ServerAdmin/AdminController')
  2. const ErrorController = require('./Features/Errors/ErrorController')
  3. const ProjectController = require('./Features/Project/ProjectController')
  4. const ProjectApiController = require('./Features/Project/ProjectApiController')
  5. const SpellingController = require('./Features/Spelling/SpellingController')
  6. const EditorRouter = require('./Features/Editor/EditorRouter')
  7. const Settings = require('settings-sharelatex')
  8. const TpdsController = require('./Features/ThirdPartyDataStore/TpdsController')
  9. const SubscriptionRouter = require('./Features/Subscription/SubscriptionRouter')
  10. const UploadsRouter = require('./Features/Uploads/UploadsRouter')
  11. const metrics = require('metrics-sharelatex')
  12. const ReferalController = require('./Features/Referal/ReferalController')
  13. const AuthenticationController = require('./Features/Authentication/AuthenticationController')
  14. const TagsController = require('./Features/Tags/TagsController')
  15. const NotificationsController = require('./Features/Notifications/NotificationsController')
  16. const CollaboratorsRouter = require('./Features/Collaborators/CollaboratorsRouter')
  17. const UserInfoController = require('./Features/User/UserInfoController')
  18. const UserController = require('./Features/User/UserController')
  19. const UserEmailsController = require('./Features/User/UserEmailsController')
  20. const UserPagesController = require('./Features/User/UserPagesController')
  21. const DocumentController = require('./Features/Documents/DocumentController')
  22. const CompileManager = require('./Features/Compile/CompileManager')
  23. const CompileController = require('./Features/Compile/CompileController')
  24. const ClsiCookieManager = require('./Features/Compile/ClsiCookieManager')(
  25. Settings.apis.clsi != null ? Settings.apis.clsi.backendGroupName : undefined
  26. )
  27. const HealthCheckController = require('./Features/HealthCheck/HealthCheckController')
  28. const ProjectDownloadsController = require('./Features/Downloads/ProjectDownloadsController')
  29. const FileStoreController = require('./Features/FileStore/FileStoreController')
  30. const HistoryController = require('./Features/History/HistoryController')
  31. const ExportsController = require('./Features/Exports/ExportsController')
  32. const PasswordResetRouter = require('./Features/PasswordReset/PasswordResetRouter')
  33. const StaticPagesRouter = require('./Features/StaticPages/StaticPagesRouter')
  34. const ChatController = require('./Features/Chat/ChatController')
  35. const Modules = require('./infrastructure/Modules')
  36. const RateLimiterMiddleware = require('./Features/Security/RateLimiterMiddleware')
  37. const InactiveProjectController = require('./Features/InactiveData/InactiveProjectController')
  38. const ContactRouter = require('./Features/Contacts/ContactRouter')
  39. const ReferencesController = require('./Features/References/ReferencesController')
  40. const AuthorizationMiddleware = require('./Features/Authorization/AuthorizationMiddleware')
  41. const BetaProgramController = require('./Features/BetaProgram/BetaProgramController')
  42. const SudoModeController = require('./Features/SudoMode/SudoModeController')
  43. const SudoModeMiddleware = require('./Features/SudoMode/SudoModeMiddleware')
  44. const AnalyticsRouter = require('./Features/Analytics/AnalyticsRouter')
  45. const MetaController = require('./Features/Metadata/MetaController')
  46. const TokenAccessController = require('./Features/TokenAccess/TokenAccessController')
  47. const Features = require('./infrastructure/Features')
  48. const LinkedFilesRouter = require('./Features/LinkedFiles/LinkedFilesRouter')
  49. const TemplatesRouter = require('./Features/Templates/TemplatesRouter')
  50. const InstitutionsController = require('./Features/Institutions/InstitutionsController')
  51. const UserMembershipRouter = require('./Features/UserMembership/UserMembershipRouter')
  52. const SystemMessageController = require('./Features/SystemMessages/SystemMessageController')
  53. const logger = require('logger-sharelatex')
  54. const _ = require('underscore')
  55. module.exports = { initialize }
  56. function initialize(webRouter, privateApiRouter, publicApiRouter) {
  57. if (!Settings.allowPublicAccess) {
  58. webRouter.all('*', AuthenticationController.requireGlobalLogin)
  59. }
  60. webRouter.get('/login', UserPagesController.loginPage)
  61. AuthenticationController.addEndpointToLoginWhitelist('/login')
  62. webRouter.post('/login', AuthenticationController.passportLogin)
  63. webRouter.get(
  64. '/read-only/one-time-login',
  65. UserPagesController.oneTimeLoginPage
  66. )
  67. AuthenticationController.addEndpointToLoginWhitelist(
  68. '/read-only/one-time-login'
  69. )
  70. webRouter.get('/logout', UserPagesController.logoutPage)
  71. webRouter.post('/logout', UserController.logout)
  72. webRouter.get('/restricted', AuthorizationMiddleware.restricted)
  73. if (Features.hasFeature('registration')) {
  74. webRouter.get('/register', UserPagesController.registerPage)
  75. AuthenticationController.addEndpointToLoginWhitelist('/register')
  76. }
  77. EditorRouter.apply(webRouter, privateApiRouter)
  78. CollaboratorsRouter.apply(webRouter, privateApiRouter)
  79. SubscriptionRouter.apply(webRouter, privateApiRouter, publicApiRouter)
  80. UploadsRouter.apply(webRouter, privateApiRouter)
  81. PasswordResetRouter.apply(webRouter, privateApiRouter)
  82. StaticPagesRouter.apply(webRouter, privateApiRouter)
  83. ContactRouter.apply(webRouter, privateApiRouter)
  84. AnalyticsRouter.apply(webRouter, privateApiRouter, publicApiRouter)
  85. LinkedFilesRouter.apply(webRouter, privateApiRouter, publicApiRouter)
  86. TemplatesRouter.apply(webRouter)
  87. UserMembershipRouter.apply(webRouter)
  88. Modules.applyRouter(webRouter, privateApiRouter, publicApiRouter)
  89. if (Settings.enableSubscriptions) {
  90. webRouter.get(
  91. '/user/bonus',
  92. AuthenticationController.requireLogin(),
  93. ReferalController.bonus
  94. )
  95. }
  96. webRouter.get('/user/activate', UserPagesController.activateAccountPage)
  97. AuthenticationController.addEndpointToLoginWhitelist('/user/activate')
  98. webRouter.get(
  99. '/system/messages',
  100. AuthenticationController.requireLogin(),
  101. SystemMessageController.getMessages
  102. )
  103. webRouter.get(
  104. '/user/settings',
  105. AuthenticationController.requireLogin(),
  106. SudoModeMiddleware.protectPage,
  107. UserPagesController.settingsPage
  108. )
  109. webRouter.post(
  110. '/user/settings',
  111. AuthenticationController.requireLogin(),
  112. UserController.updateUserSettings
  113. )
  114. webRouter.post(
  115. '/user/password/update',
  116. AuthenticationController.requireLogin(),
  117. RateLimiterMiddleware.rateLimit({
  118. endpointName: 'change-password',
  119. maxRequests: 10,
  120. timeInterval: 60
  121. }),
  122. UserController.changePassword
  123. )
  124. webRouter.get(
  125. '/user/emails',
  126. AuthenticationController.requireLogin(),
  127. UserController.promises.ensureAffiliationMiddleware,
  128. UserEmailsController.list
  129. )
  130. webRouter.get('/user/emails/confirm', UserEmailsController.showConfirm)
  131. webRouter.post(
  132. '/user/emails/confirm',
  133. RateLimiterMiddleware.rateLimit({
  134. endpointName: 'confirm-email',
  135. maxRequests: 10,
  136. timeInterval: 60
  137. }),
  138. UserEmailsController.confirm
  139. )
  140. webRouter.post(
  141. '/user/emails/resend_confirmation',
  142. AuthenticationController.requireLogin(),
  143. RateLimiterMiddleware.rateLimit({
  144. endpointName: 'resend-confirmation',
  145. maxRequests: 10,
  146. timeInterval: 60
  147. }),
  148. UserEmailsController.resendConfirmation
  149. )
  150. if (Features.hasFeature('affiliations')) {
  151. webRouter.post(
  152. '/user/emails',
  153. AuthenticationController.requireLogin(),
  154. RateLimiterMiddleware.rateLimit({
  155. endpointName: 'add-email',
  156. maxRequests: 10,
  157. timeInterval: 60
  158. }),
  159. UserEmailsController.add
  160. )
  161. webRouter.post(
  162. '/user/emails/delete',
  163. AuthenticationController.requireLogin(),
  164. RateLimiterMiddleware.rateLimit({
  165. endpointName: 'delete-email',
  166. maxRequests: 10,
  167. timeInterval: 60
  168. }),
  169. UserEmailsController.remove
  170. )
  171. webRouter.post(
  172. '/user/emails/default',
  173. AuthenticationController.requireLogin(),
  174. UserEmailsController.setDefault
  175. )
  176. webRouter.post(
  177. '/user/emails/endorse',
  178. AuthenticationController.requireLogin(),
  179. RateLimiterMiddleware.rateLimit({
  180. endpointName: 'endorse-email',
  181. maxRequests: 30,
  182. timeInterval: 60
  183. }),
  184. UserEmailsController.endorse
  185. )
  186. }
  187. webRouter.get(
  188. '/user/sessions',
  189. AuthenticationController.requireLogin(),
  190. SudoModeMiddleware.protectPage,
  191. UserPagesController.sessionsPage
  192. )
  193. webRouter.post(
  194. '/user/sessions/clear',
  195. AuthenticationController.requireLogin(),
  196. UserController.clearSessions
  197. )
  198. webRouter.delete(
  199. '/user/newsletter/unsubscribe',
  200. AuthenticationController.requireLogin(),
  201. UserController.unsubscribe
  202. )
  203. webRouter.post(
  204. '/user/delete',
  205. RateLimiterMiddleware.rateLimit({
  206. endpointName: 'delete-user',
  207. maxRequests: 10,
  208. timeInterval: 60
  209. }),
  210. AuthenticationController.requireLogin(),
  211. UserController.tryDeleteUser
  212. )
  213. webRouter.get(
  214. '/user/personal_info',
  215. AuthenticationController.requireLogin(),
  216. UserInfoController.getLoggedInUsersPersonalInfo
  217. )
  218. privateApiRouter.get(
  219. '/user/:user_id/personal_info',
  220. AuthenticationController.httpAuth,
  221. UserInfoController.getPersonalInfo
  222. )
  223. webRouter.get(
  224. '/user/reconfirm',
  225. UserPagesController.renderReconfirmAccountPage
  226. )
  227. // for /user/reconfirm POST, see password router
  228. webRouter.get(
  229. '/user/tpds/queues',
  230. AuthenticationController.requireLogin(),
  231. TpdsController.getQueues
  232. )
  233. webRouter.get(
  234. '/user/projects',
  235. AuthenticationController.requireLogin(),
  236. ProjectController.userProjectsJson
  237. )
  238. webRouter.get(
  239. '/project/:Project_id/entities',
  240. AuthenticationController.requireLogin(),
  241. AuthorizationMiddleware.ensureUserCanReadProject,
  242. ProjectController.projectEntitiesJson
  243. )
  244. webRouter.get(
  245. '/project',
  246. AuthenticationController.requireLogin(),
  247. RateLimiterMiddleware.rateLimit({
  248. endpointName: 'open-dashboard',
  249. maxRequests: 30,
  250. timeInterval: 60
  251. }),
  252. ProjectController.projectListPage
  253. )
  254. webRouter.post(
  255. '/project/new',
  256. AuthenticationController.requireLogin(),
  257. RateLimiterMiddleware.rateLimit({
  258. endpointName: 'create-project',
  259. maxRequests: 20,
  260. timeInterval: 60
  261. }),
  262. ProjectController.newProject
  263. )
  264. webRouter.get(
  265. '/Project/:Project_id',
  266. RateLimiterMiddleware.rateLimit({
  267. endpointName: 'open-project',
  268. params: ['Project_id'],
  269. maxRequests: 15,
  270. timeInterval: 60
  271. }),
  272. AuthenticationController.validateUserSession(),
  273. AuthorizationMiddleware.ensureUserCanReadProject,
  274. ProjectController.loadEditor
  275. )
  276. webRouter.head(
  277. '/Project/:Project_id/file/:File_id',
  278. AuthorizationMiddleware.ensureUserCanReadProject,
  279. FileStoreController.getFileHead
  280. )
  281. webRouter.get(
  282. '/Project/:Project_id/file/:File_id',
  283. AuthorizationMiddleware.ensureUserCanReadProject,
  284. FileStoreController.getFile
  285. )
  286. webRouter.post(
  287. '/project/:Project_id/settings',
  288. AuthorizationMiddleware.ensureUserCanWriteProjectSettings,
  289. ProjectController.updateProjectSettings
  290. )
  291. webRouter.post(
  292. '/project/:Project_id/settings/admin',
  293. AuthenticationController.requireLogin(),
  294. AuthorizationMiddleware.ensureUserCanAdminProject,
  295. ProjectController.updateProjectAdminSettings
  296. )
  297. webRouter.post(
  298. '/project/:Project_id/compile',
  299. RateLimiterMiddleware.rateLimit({
  300. endpointName: 'compile-project-http',
  301. params: ['Project_id'],
  302. maxRequests: 800,
  303. timeInterval: 60 * 60
  304. }),
  305. AuthorizationMiddleware.ensureUserCanReadProject,
  306. CompileController.compile
  307. )
  308. webRouter.post(
  309. '/project/:Project_id/compile/stop',
  310. AuthorizationMiddleware.ensureUserCanReadProject,
  311. CompileController.stopCompile
  312. )
  313. // LEGACY: Used by the web download buttons, adds filename header, TODO: remove at some future date
  314. webRouter.get(
  315. '/project/:Project_id/output/output.pdf',
  316. AuthorizationMiddleware.ensureUserCanReadProject,
  317. CompileController.downloadPdf
  318. )
  319. // PDF Download button
  320. webRouter.get(
  321. /^\/download\/project\/([^/]*)\/output\/output\.pdf$/,
  322. function(req, res, next) {
  323. const params = { Project_id: req.params[0] }
  324. req.params = params
  325. next()
  326. },
  327. AuthorizationMiddleware.ensureUserCanReadProject,
  328. CompileController.downloadPdf
  329. )
  330. // PDF Download button for specific build
  331. webRouter.get(
  332. /^\/download\/project\/([^/]*)\/build\/([0-9a-f-]+)\/output\/output\.pdf$/,
  333. function(req, res, next) {
  334. const params = {
  335. Project_id: req.params[0],
  336. build_id: req.params[1]
  337. }
  338. req.params = params
  339. next()
  340. },
  341. AuthorizationMiddleware.ensureUserCanReadProject,
  342. CompileController.downloadPdf
  343. )
  344. // Used by the pdf viewers
  345. webRouter.get(
  346. /^\/project\/([^/]*)\/output\/(.*)$/,
  347. function(req, res, next) {
  348. const params = {
  349. Project_id: req.params[0],
  350. file: req.params[1]
  351. }
  352. req.params = params
  353. next()
  354. },
  355. AuthorizationMiddleware.ensureUserCanReadProject,
  356. CompileController.getFileFromClsi
  357. )
  358. // direct url access to output files for a specific build (query string not required)
  359. webRouter.get(
  360. /^\/project\/([^/]*)\/build\/([0-9a-f-]+)\/output\/(.*)$/,
  361. function(req, res, next) {
  362. const params = {
  363. Project_id: req.params[0],
  364. build_id: req.params[1],
  365. file: req.params[2]
  366. }
  367. req.params = params
  368. next()
  369. },
  370. AuthorizationMiddleware.ensureUserCanReadProject,
  371. CompileController.getFileFromClsi
  372. )
  373. // direct url access to output files for user but no build, to retrieve files when build fails
  374. webRouter.get(
  375. /^\/project\/([^/]*)\/user\/([0-9a-f-]+)\/output\/(.*)$/,
  376. function(req, res, next) {
  377. const params = {
  378. Project_id: req.params[0],
  379. user_id: req.params[1],
  380. file: req.params[2]
  381. }
  382. req.params = params
  383. next()
  384. },
  385. AuthorizationMiddleware.ensureUserCanReadProject,
  386. CompileController.getFileFromClsi
  387. )
  388. // direct url access to output files for a specific user and build (query string not required)
  389. webRouter.get(
  390. /^\/project\/([^/]*)\/user\/([0-9a-f]+)\/build\/([0-9a-f-]+)\/output\/(.*)$/,
  391. function(req, res, next) {
  392. const params = {
  393. Project_id: req.params[0],
  394. user_id: req.params[1],
  395. build_id: req.params[2],
  396. file: req.params[3]
  397. }
  398. req.params = params
  399. next()
  400. },
  401. AuthorizationMiddleware.ensureUserCanReadProject,
  402. CompileController.getFileFromClsi
  403. )
  404. webRouter.delete(
  405. '/project/:Project_id/output',
  406. AuthorizationMiddleware.ensureUserCanReadProject,
  407. CompileController.deleteAuxFiles
  408. )
  409. webRouter.get(
  410. '/project/:Project_id/sync/code',
  411. AuthorizationMiddleware.ensureUserCanReadProject,
  412. CompileController.proxySyncCode
  413. )
  414. webRouter.get(
  415. '/project/:Project_id/sync/pdf',
  416. AuthorizationMiddleware.ensureUserCanReadProject,
  417. CompileController.proxySyncPdf
  418. )
  419. webRouter.get(
  420. '/project/:Project_id/wordcount',
  421. AuthorizationMiddleware.ensureUserCanReadProject,
  422. CompileController.wordCount
  423. )
  424. webRouter.post(
  425. '/Project/:Project_id/archive',
  426. AuthorizationMiddleware.ensureUserCanReadProject,
  427. ProjectController.archiveProject
  428. )
  429. webRouter.delete(
  430. '/Project/:Project_id/archive',
  431. AuthorizationMiddleware.ensureUserCanReadProject,
  432. ProjectController.unarchiveProject
  433. )
  434. webRouter.post(
  435. '/project/:project_id/trash',
  436. AuthorizationMiddleware.ensureUserCanReadProject,
  437. ProjectController.trashProject
  438. )
  439. webRouter.delete(
  440. '/project/:project_id/trash',
  441. AuthorizationMiddleware.ensureUserCanReadProject,
  442. ProjectController.untrashProject
  443. )
  444. webRouter.delete(
  445. '/Project/:Project_id',
  446. AuthenticationController.requireLogin(),
  447. AuthorizationMiddleware.ensureUserCanAdminProject,
  448. ProjectController.deleteProject
  449. )
  450. webRouter.post(
  451. '/Project/:Project_id/restore',
  452. AuthenticationController.requireLogin(),
  453. AuthorizationMiddleware.ensureUserCanAdminProject,
  454. ProjectController.restoreProject
  455. )
  456. webRouter.post(
  457. '/Project/:Project_id/clone',
  458. AuthorizationMiddleware.ensureUserCanReadProject,
  459. ProjectController.cloneProject
  460. )
  461. webRouter.post(
  462. '/project/:Project_id/rename',
  463. AuthenticationController.requireLogin(),
  464. AuthorizationMiddleware.ensureUserCanAdminProject,
  465. ProjectController.renameProject
  466. )
  467. webRouter.get(
  468. '/project/:Project_id/updates',
  469. AuthorizationMiddleware.ensureUserCanReadProject,
  470. HistoryController.selectHistoryApi,
  471. HistoryController.proxyToHistoryApiAndInjectUserDetails
  472. )
  473. webRouter.get(
  474. '/project/:Project_id/doc/:doc_id/diff',
  475. AuthorizationMiddleware.ensureUserCanReadProject,
  476. HistoryController.selectHistoryApi,
  477. HistoryController.proxyToHistoryApi
  478. )
  479. webRouter.get(
  480. '/project/:Project_id/diff',
  481. AuthorizationMiddleware.ensureUserCanReadProject,
  482. HistoryController.selectHistoryApi,
  483. HistoryController.proxyToHistoryApiAndInjectUserDetails
  484. )
  485. webRouter.get(
  486. '/project/:Project_id/filetree/diff',
  487. AuthorizationMiddleware.ensureUserCanReadProject,
  488. HistoryController.selectHistoryApi,
  489. HistoryController.proxyToHistoryApi
  490. )
  491. webRouter.post(
  492. '/project/:Project_id/doc/:doc_id/version/:version_id/restore',
  493. AuthorizationMiddleware.ensureUserCanWriteProjectContent,
  494. HistoryController.selectHistoryApi,
  495. HistoryController.proxyToHistoryApi
  496. )
  497. webRouter.post(
  498. '/project/:project_id/doc/:doc_id/restore',
  499. AuthorizationMiddleware.ensureUserCanWriteProjectContent,
  500. HistoryController.restoreDocFromDeletedDoc
  501. )
  502. webRouter.post(
  503. '/project/:project_id/restore_file',
  504. AuthorizationMiddleware.ensureUserCanWriteProjectContent,
  505. HistoryController.restoreFileFromV2
  506. )
  507. webRouter.get(
  508. '/project/:project_id/version/:version/zip',
  509. AuthorizationMiddleware.ensureUserCanReadProject,
  510. HistoryController.downloadZipOfVersion
  511. )
  512. privateApiRouter.post(
  513. '/project/:Project_id/history/resync',
  514. AuthenticationController.httpAuth,
  515. HistoryController.resyncProjectHistory
  516. )
  517. webRouter.get(
  518. '/project/:Project_id/labels',
  519. AuthorizationMiddleware.ensureUserCanReadProject,
  520. HistoryController.selectHistoryApi,
  521. HistoryController.ensureProjectHistoryEnabled,
  522. HistoryController.getLabels
  523. )
  524. webRouter.post(
  525. '/project/:Project_id/labels',
  526. AuthorizationMiddleware.ensureUserCanWriteProjectContent,
  527. HistoryController.selectHistoryApi,
  528. HistoryController.ensureProjectHistoryEnabled,
  529. HistoryController.createLabel
  530. )
  531. webRouter.delete(
  532. '/project/:Project_id/labels/:label_id',
  533. AuthorizationMiddleware.ensureUserCanWriteProjectContent,
  534. HistoryController.selectHistoryApi,
  535. HistoryController.ensureProjectHistoryEnabled,
  536. HistoryController.deleteLabel
  537. )
  538. webRouter.post(
  539. '/project/:project_id/export/:brand_variation_id',
  540. AuthorizationMiddleware.ensureUserCanWriteProjectContent,
  541. ExportsController.exportProject
  542. )
  543. webRouter.get(
  544. '/project/:project_id/export/:export_id',
  545. AuthorizationMiddleware.ensureUserCanWriteProjectContent,
  546. ExportsController.exportStatus
  547. )
  548. webRouter.get(
  549. '/project/:project_id/export/:export_id/:type',
  550. AuthorizationMiddleware.ensureUserCanWriteProjectContent,
  551. ExportsController.exportDownload
  552. )
  553. webRouter.get(
  554. '/Project/:Project_id/download/zip',
  555. AuthorizationMiddleware.ensureUserCanReadProject,
  556. ProjectDownloadsController.downloadProject
  557. )
  558. webRouter.get(
  559. '/project/download/zip',
  560. AuthorizationMiddleware.ensureUserCanReadMultipleProjects,
  561. ProjectDownloadsController.downloadMultipleProjects
  562. )
  563. webRouter.get(
  564. '/project/:project_id/metadata',
  565. AuthorizationMiddleware.ensureUserCanReadProject,
  566. AuthenticationController.requireLogin(),
  567. MetaController.getMetadata
  568. )
  569. webRouter.post(
  570. '/project/:project_id/doc/:doc_id/metadata',
  571. AuthorizationMiddleware.ensureUserCanReadProject,
  572. AuthenticationController.requireLogin(),
  573. MetaController.broadcastMetadataForDoc
  574. )
  575. privateApiRouter.post(
  576. '/internal/expire-deleted-projects-after-duration',
  577. AuthenticationController.httpAuth,
  578. ProjectController.expireDeletedProjectsAfterDuration
  579. )
  580. privateApiRouter.post(
  581. '/internal/expire-deleted-users-after-duration',
  582. AuthenticationController.httpAuth,
  583. UserController.expireDeletedUsersAfterDuration
  584. )
  585. privateApiRouter.post(
  586. '/internal/project/:projectId/expire-deleted-project',
  587. AuthenticationController.httpAuth,
  588. ProjectController.expireDeletedProject
  589. )
  590. privateApiRouter.post(
  591. '/internal/users/:userId/expire',
  592. AuthenticationController.httpAuth,
  593. UserController.expireDeletedUser
  594. )
  595. privateApiRouter.get(
  596. '/user/:userId/tag',
  597. AuthenticationController.httpAuth,
  598. TagsController.apiGetAllTags
  599. )
  600. webRouter.get(
  601. '/tag',
  602. AuthenticationController.requireLogin(),
  603. TagsController.getAllTags
  604. )
  605. webRouter.post(
  606. '/tag',
  607. AuthenticationController.requireLogin(),
  608. RateLimiterMiddleware.rateLimit({
  609. endpointName: 'create-tag',
  610. maxRequests: 30,
  611. timeInterval: 60
  612. }),
  613. TagsController.createTag
  614. )
  615. webRouter.post(
  616. '/tag/:tagId/rename',
  617. AuthenticationController.requireLogin(),
  618. RateLimiterMiddleware.rateLimit({
  619. endpointName: 'rename-tag',
  620. maxRequests: 30,
  621. timeInterval: 60
  622. }),
  623. TagsController.renameTag
  624. )
  625. webRouter.delete(
  626. '/tag/:tagId',
  627. AuthenticationController.requireLogin(),
  628. RateLimiterMiddleware.rateLimit({
  629. endpointName: 'delete-tag',
  630. maxRequests: 30,
  631. timeInterval: 60
  632. }),
  633. TagsController.deleteTag
  634. )
  635. webRouter.post(
  636. '/tag/:tagId/project/:projectId',
  637. AuthenticationController.requireLogin(),
  638. RateLimiterMiddleware.rateLimit({
  639. endpointName: 'add-project-to-tag',
  640. maxRequests: 30,
  641. timeInterval: 60
  642. }),
  643. TagsController.addProjectToTag
  644. )
  645. webRouter.delete(
  646. '/tag/:tagId/project/:projectId',
  647. AuthenticationController.requireLogin(),
  648. RateLimiterMiddleware.rateLimit({
  649. endpointName: 'remove-project-from-tag',
  650. maxRequests: 30,
  651. timeInterval: 60
  652. }),
  653. TagsController.removeProjectFromTag
  654. )
  655. webRouter.get(
  656. '/notifications',
  657. AuthenticationController.requireLogin(),
  658. NotificationsController.getAllUnreadNotifications
  659. )
  660. webRouter.delete(
  661. '/notifications/:notification_id',
  662. AuthenticationController.requireLogin(),
  663. NotificationsController.markNotificationAsRead
  664. )
  665. // Deprecated in favour of /internal/project/:project_id but still used by versioning
  666. privateApiRouter.get(
  667. '/project/:project_id/details',
  668. AuthenticationController.httpAuth,
  669. ProjectApiController.getProjectDetails
  670. )
  671. // New 'stable' /internal API end points
  672. privateApiRouter.get(
  673. '/internal/project/:project_id',
  674. AuthenticationController.httpAuth,
  675. ProjectApiController.getProjectDetails
  676. )
  677. privateApiRouter.get(
  678. '/internal/project/:Project_id/zip',
  679. AuthenticationController.httpAuth,
  680. ProjectDownloadsController.downloadProject
  681. )
  682. privateApiRouter.get(
  683. '/internal/project/:project_id/compile/pdf',
  684. AuthenticationController.httpAuth,
  685. CompileController.compileAndDownloadPdf
  686. )
  687. privateApiRouter.post(
  688. '/internal/deactivateOldProjects',
  689. AuthenticationController.httpAuth,
  690. InactiveProjectController.deactivateOldProjects
  691. )
  692. privateApiRouter.post(
  693. '/internal/project/:project_id/deactivate',
  694. AuthenticationController.httpAuth,
  695. InactiveProjectController.deactivateProject
  696. )
  697. privateApiRouter.get(
  698. /^\/internal\/project\/([^/]*)\/output\/(.*)$/,
  699. function(req, res, next) {
  700. const params = {
  701. Project_id: req.params[0],
  702. file: req.params[1]
  703. }
  704. req.params = params
  705. next()
  706. },
  707. AuthenticationController.httpAuth,
  708. CompileController.getFileFromClsi
  709. )
  710. privateApiRouter.get(
  711. '/project/:Project_id/doc/:doc_id',
  712. AuthenticationController.httpAuth,
  713. DocumentController.getDocument
  714. )
  715. privateApiRouter.post(
  716. '/project/:Project_id/doc/:doc_id',
  717. AuthenticationController.httpAuth,
  718. DocumentController.setDocument
  719. )
  720. privateApiRouter.post(
  721. '/user/:user_id/update/*',
  722. AuthenticationController.httpAuth,
  723. TpdsController.mergeUpdate
  724. )
  725. privateApiRouter.delete(
  726. '/user/:user_id/update/*',
  727. AuthenticationController.httpAuth,
  728. TpdsController.deleteUpdate
  729. )
  730. privateApiRouter.post(
  731. '/project/:project_id/contents/*',
  732. AuthenticationController.httpAuth,
  733. TpdsController.updateProjectContents
  734. )
  735. privateApiRouter.delete(
  736. '/project/:project_id/contents/*',
  737. AuthenticationController.httpAuth,
  738. TpdsController.deleteProjectContents
  739. )
  740. webRouter.post(
  741. '/spelling/check',
  742. AuthenticationController.requireLogin(),
  743. SpellingController.proxyRequestToSpellingApi
  744. )
  745. webRouter.post(
  746. '/spelling/learn',
  747. AuthenticationController.requireLogin(),
  748. SpellingController.proxyRequestToSpellingApi
  749. )
  750. webRouter.get(
  751. '/project/:project_id/messages',
  752. AuthorizationMiddleware.blockRestrictedUserFromProject,
  753. AuthorizationMiddleware.ensureUserCanReadProject,
  754. ChatController.getMessages
  755. )
  756. webRouter.post(
  757. '/project/:project_id/messages',
  758. AuthorizationMiddleware.blockRestrictedUserFromProject,
  759. AuthorizationMiddleware.ensureUserCanReadProject,
  760. RateLimiterMiddleware.rateLimit({
  761. endpointName: 'send-chat-message',
  762. maxRequests: 100,
  763. timeInterval: 60
  764. }),
  765. ChatController.sendMessage
  766. )
  767. webRouter.post(
  768. '/project/:Project_id/references/index',
  769. AuthorizationMiddleware.ensureUserCanReadProject,
  770. RateLimiterMiddleware.rateLimit({
  771. endpointName: 'index-project-references',
  772. maxRequests: 30,
  773. timeInterval: 60
  774. }),
  775. ReferencesController.index
  776. )
  777. webRouter.post(
  778. '/project/:Project_id/references/indexAll',
  779. AuthorizationMiddleware.ensureUserCanReadProject,
  780. RateLimiterMiddleware.rateLimit({
  781. endpointName: 'index-all-project-references',
  782. maxRequests: 30,
  783. timeInterval: 60
  784. }),
  785. ReferencesController.indexAll
  786. )
  787. // disable beta program while v2 is in beta
  788. webRouter.get(
  789. '/beta/participate',
  790. AuthenticationController.requireLogin(),
  791. BetaProgramController.optInPage
  792. )
  793. webRouter.post(
  794. '/beta/opt-in',
  795. AuthenticationController.requireLogin(),
  796. BetaProgramController.optIn
  797. )
  798. webRouter.post(
  799. '/beta/opt-out',
  800. AuthenticationController.requireLogin(),
  801. BetaProgramController.optOut
  802. )
  803. webRouter.get(
  804. '/confirm-password',
  805. AuthenticationController.requireLogin(),
  806. SudoModeController.sudoModePrompt
  807. )
  808. webRouter.post(
  809. '/confirm-password',
  810. AuthenticationController.requireLogin(),
  811. RateLimiterMiddleware.rateLimit({
  812. endpointName: 'confirm-password',
  813. maxRequests: 10,
  814. timeInterval: 60
  815. }),
  816. SudoModeController.submitPassword
  817. )
  818. // New "api" endpoints. Started as a way for v1 to call over to v2 (for
  819. // long-term features, as opposed to the nominally temporary ones in the
  820. // overleaf-integration module), but may expand beyond that role.
  821. publicApiRouter.post(
  822. '/api/clsi/compile/:submission_id',
  823. AuthenticationController.httpAuth,
  824. CompileController.compileSubmission
  825. )
  826. publicApiRouter.get(
  827. /^\/api\/clsi\/compile\/([^/]*)\/build\/([0-9a-f-]+)\/output\/(.*)$/,
  828. function(req, res, next) {
  829. const params = {
  830. submission_id: req.params[0],
  831. build_id: req.params[1],
  832. file: req.params[2]
  833. }
  834. req.params = params
  835. next()
  836. },
  837. AuthenticationController.httpAuth,
  838. CompileController.getFileFromClsiWithoutUser
  839. )
  840. publicApiRouter.post(
  841. '/api/institutions/confirm_university_domain',
  842. RateLimiterMiddleware.rateLimit({
  843. endpointName: 'confirm-university-domain',
  844. maxRequests: 1,
  845. timeInterval: 60
  846. }),
  847. AuthenticationController.httpAuth,
  848. InstitutionsController.confirmDomain
  849. )
  850. webRouter.get('/chrome', function(req, res, next) {
  851. // Match v1 behaviour - this is used for a Chrome web app
  852. if (AuthenticationController.isUserLoggedIn(req)) {
  853. res.redirect('/project')
  854. } else {
  855. res.redirect('/register')
  856. }
  857. })
  858. // Admin Stuff
  859. webRouter.get(
  860. '/admin',
  861. AuthorizationMiddleware.ensureUserIsSiteAdmin,
  862. AdminController.index
  863. )
  864. webRouter.get(
  865. '/admin/user',
  866. AuthorizationMiddleware.ensureUserIsSiteAdmin,
  867. (req, res) => res.redirect('/admin/register')
  868. ) // this gets removed by admin-panel addon
  869. webRouter.get(
  870. '/admin/register',
  871. AuthorizationMiddleware.ensureUserIsSiteAdmin,
  872. AdminController.registerNewUser
  873. )
  874. webRouter.post(
  875. '/admin/register',
  876. AuthorizationMiddleware.ensureUserIsSiteAdmin,
  877. UserController.register
  878. )
  879. webRouter.post(
  880. '/admin/closeEditor',
  881. AuthorizationMiddleware.ensureUserIsSiteAdmin,
  882. AdminController.closeEditor
  883. )
  884. webRouter.post(
  885. '/admin/dissconectAllUsers',
  886. AuthorizationMiddleware.ensureUserIsSiteAdmin,
  887. AdminController.dissconectAllUsers
  888. )
  889. webRouter.post(
  890. '/admin/flushProjectToTpds',
  891. AuthorizationMiddleware.ensureUserIsSiteAdmin,
  892. AdminController.flushProjectToTpds
  893. )
  894. webRouter.post(
  895. '/admin/pollDropboxForUser',
  896. AuthorizationMiddleware.ensureUserIsSiteAdmin,
  897. AdminController.pollDropboxForUser
  898. )
  899. webRouter.post(
  900. '/admin/messages',
  901. AuthorizationMiddleware.ensureUserIsSiteAdmin,
  902. AdminController.createMessage
  903. )
  904. webRouter.post(
  905. '/admin/messages/clear',
  906. AuthorizationMiddleware.ensureUserIsSiteAdmin,
  907. AdminController.clearMessages
  908. )
  909. privateApiRouter.post(
  910. '/disconnectAllUsers',
  911. AdminController.dissconectAllUsers
  912. )
  913. privateApiRouter.get('/perfTest', (req, res) => res.send('hello'))
  914. publicApiRouter.get('/status', (req, res) =>
  915. res.send('web sharelatex is alive (web)')
  916. )
  917. privateApiRouter.get('/status', (req, res) =>
  918. res.send('web sharelatex is alive (api)')
  919. )
  920. // used by kubernetes health-check and acceptance tests
  921. webRouter.get('/dev/csrf', (req, res) => res.send(res.locals.csrfToken))
  922. publicApiRouter.get('/health_check', HealthCheckController.check)
  923. privateApiRouter.get('/health_check', HealthCheckController.checkApi)
  924. publicApiRouter.get('/health_check/redis', HealthCheckController.checkRedis)
  925. privateApiRouter.get('/health_check/redis', HealthCheckController.checkRedis)
  926. publicApiRouter.get('/health_check/mongo', HealthCheckController.checkMongo)
  927. privateApiRouter.get('/health_check/mongo', HealthCheckController.checkMongo)
  928. webRouter.get(
  929. '/status/compiler/:Project_id',
  930. RateLimiterMiddleware.rateLimit({
  931. endpointName: 'status-compiler',
  932. maxRequests: 10,
  933. timeInterval: 60
  934. }),
  935. AuthorizationMiddleware.ensureUserCanReadProject,
  936. function(req, res) {
  937. const projectId = req.params.Project_id
  938. const sendRes = _.once(function(statusCode, message) {
  939. res.status(statusCode)
  940. res.send(message)
  941. ClsiCookieManager.clearServerId(projectId)
  942. }) // force every compile to a new server
  943. // set a timeout
  944. var handler = setTimeout(function() {
  945. sendRes(500, 'Compiler timed out')
  946. handler = null
  947. }, 10000)
  948. // use a valid user id for testing
  949. const testUserId = '123456789012345678901234'
  950. // run the compile
  951. CompileManager.compile(projectId, testUserId, {}, function(
  952. error,
  953. status
  954. ) {
  955. if (handler) {
  956. clearTimeout(handler)
  957. }
  958. if (error) {
  959. sendRes(500, `Compiler returned error ${error.message}`)
  960. } else if (status === 'success') {
  961. sendRes(200, 'Compiler returned in less than 10 seconds')
  962. } else {
  963. sendRes(500, `Compiler returned failure ${status}`)
  964. }
  965. })
  966. }
  967. )
  968. webRouter.get('/no-cache', function(req, res, next) {
  969. res.header('Cache-Control', 'max-age=0')
  970. res.sendStatus(404)
  971. })
  972. webRouter.get('/oops-express', (req, res, next) =>
  973. next(new Error('Test error'))
  974. )
  975. webRouter.get('/oops-internal', function(req, res, next) {
  976. throw new Error('Test error')
  977. })
  978. webRouter.get('/oops-mongo', (req, res, next) =>
  979. require('./models/Project').Project.findOne({}, function() {
  980. throw new Error('Test error')
  981. })
  982. )
  983. privateApiRouter.get('/opps-small', function(req, res, next) {
  984. logger.err('test error occured')
  985. res.sendStatus(200)
  986. })
  987. webRouter.post('/error/client', function(req, res, next) {
  988. logger.warn(
  989. { err: req.body.error, meta: req.body.meta },
  990. 'client side error'
  991. )
  992. metrics.inc('client-side-error')
  993. res.sendStatus(204)
  994. })
  995. webRouter.get(
  996. `/read/:token(${TokenAccessController.READ_ONLY_TOKEN_PATTERN})`,
  997. RateLimiterMiddleware.rateLimit({
  998. endpointName: 'read-only-token',
  999. maxRequests: 15,
  1000. timeInterval: 60
  1001. }),
  1002. TokenAccessController.tokenAccessPage
  1003. )
  1004. webRouter.get(
  1005. `/:token(${TokenAccessController.READ_AND_WRITE_TOKEN_PATTERN})`,
  1006. RateLimiterMiddleware.rateLimit({
  1007. endpointName: 'read-and-write-token',
  1008. maxRequests: 15,
  1009. timeInterval: 60
  1010. }),
  1011. TokenAccessController.tokenAccessPage
  1012. )
  1013. webRouter.post(
  1014. `/:token(${TokenAccessController.READ_AND_WRITE_TOKEN_PATTERN})/grant`,
  1015. RateLimiterMiddleware.rateLimit({
  1016. endpointName: 'grant-token-access-read-write',
  1017. maxRequests: 10,
  1018. timeInterval: 60
  1019. }),
  1020. TokenAccessController.grantTokenAccessReadAndWrite
  1021. )
  1022. webRouter.post(
  1023. `/read/:token(${TokenAccessController.READ_ONLY_TOKEN_PATTERN})/grant`,
  1024. RateLimiterMiddleware.rateLimit({
  1025. endpointName: 'grant-token-access-read-only',
  1026. maxRequests: 10,
  1027. timeInterval: 60
  1028. }),
  1029. TokenAccessController.grantTokenAccessReadOnly
  1030. )
  1031. webRouter.get('*', ErrorController.notFound)
  1032. }