router.js 32 KB

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