router.js 42 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355
  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 ProjectListController = require('./Features/Project/ProjectListController')
  6. const SpellingController = require('./Features/Spelling/SpellingController')
  7. const EditorRouter = require('./Features/Editor/EditorRouter')
  8. const Settings = require('@overleaf/settings')
  9. const TpdsController = require('./Features/ThirdPartyDataStore/TpdsController')
  10. const SubscriptionRouter = require('./Features/Subscription/SubscriptionRouter')
  11. const UploadsRouter = require('./Features/Uploads/UploadsRouter')
  12. const metrics = require('@overleaf/metrics')
  13. const ReferalController = require('./Features/Referal/ReferalController')
  14. const AuthenticationController = require('./Features/Authentication/AuthenticationController')
  15. const PermissionsController = require('./Features/Authorization/PermissionsController')
  16. const SessionManager = require('./Features/Authentication/SessionManager')
  17. const TagsController = require('./Features/Tags/TagsController')
  18. const NotificationsController = require('./Features/Notifications/NotificationsController')
  19. const CollaboratorsRouter = require('./Features/Collaborators/CollaboratorsRouter')
  20. const UserInfoController = require('./Features/User/UserInfoController')
  21. const UserController = require('./Features/User/UserController')
  22. const UserEmailsController = require('./Features/User/UserEmailsController')
  23. const UserPagesController = require('./Features/User/UserPagesController')
  24. const TutorialController = require('./Features/Tutorial/TutorialController')
  25. const DocumentController = require('./Features/Documents/DocumentController')
  26. const CompileManager = require('./Features/Compile/CompileManager')
  27. const CompileController = require('./Features/Compile/CompileController')
  28. const ClsiCookieManager = require('./Features/Compile/ClsiCookieManager')(
  29. Settings.apis.clsi != null ? Settings.apis.clsi.backendGroupName : undefined
  30. )
  31. const HealthCheckController = require('./Features/HealthCheck/HealthCheckController')
  32. const ProjectDownloadsController = require('./Features/Downloads/ProjectDownloadsController')
  33. const FileStoreController = require('./Features/FileStore/FileStoreController')
  34. const DocumentUpdaterController = require('./Features/DocumentUpdater/DocumentUpdaterController')
  35. const HistoryController = require('./Features/History/HistoryController')
  36. const ExportsController = require('./Features/Exports/ExportsController')
  37. const PasswordResetRouter = require('./Features/PasswordReset/PasswordResetRouter')
  38. const StaticPagesRouter = require('./Features/StaticPages/StaticPagesRouter')
  39. const ChatController = require('./Features/Chat/ChatController')
  40. const Modules = require('./infrastructure/Modules')
  41. const {
  42. RateLimiter,
  43. openProjectRateLimiter,
  44. overleafLoginRateLimiter,
  45. } = require('./infrastructure/RateLimiter')
  46. const RateLimiterMiddleware = require('./Features/Security/RateLimiterMiddleware')
  47. const InactiveProjectController = require('./Features/InactiveData/InactiveProjectController')
  48. const ContactRouter = require('./Features/Contacts/ContactRouter')
  49. const ReferencesController = require('./Features/References/ReferencesController')
  50. const AuthorizationMiddleware = require('./Features/Authorization/AuthorizationMiddleware')
  51. const BetaProgramController = require('./Features/BetaProgram/BetaProgramController')
  52. const AnalyticsRouter = require('./Features/Analytics/AnalyticsRouter')
  53. const MetaController = require('./Features/Metadata/MetaController')
  54. const TokenAccessController = require('./Features/TokenAccess/TokenAccessController')
  55. const TokenAccessRouter = require('./Features/TokenAccess/TokenAccessRouter')
  56. const Features = require('./infrastructure/Features')
  57. const LinkedFilesRouter = require('./Features/LinkedFiles/LinkedFilesRouter')
  58. const TemplatesRouter = require('./Features/Templates/TemplatesRouter')
  59. const UserMembershipRouter = require('./Features/UserMembership/UserMembershipRouter')
  60. const SystemMessageController = require('./Features/SystemMessages/SystemMessageController')
  61. const AnalyticsRegistrationSourceMiddleware = require('./Features/Analytics/AnalyticsRegistrationSourceMiddleware')
  62. const AnalyticsUTMTrackingMiddleware = require('./Features/Analytics/AnalyticsUTMTrackingMiddleware')
  63. const CaptchaMiddleware = require('./Features/Captcha/CaptchaMiddleware')
  64. const { Joi, validate } = require('./infrastructure/Validation')
  65. const {
  66. renderUnsupportedBrowserPage,
  67. unsupportedBrowserMiddleware,
  68. } = require('./infrastructure/UnsupportedBrowserMiddleware')
  69. const logger = require('@overleaf/logger')
  70. const _ = require('lodash')
  71. const { plainTextResponse } = require('./infrastructure/Response')
  72. const PublicAccessLevels = require('./Features/Authorization/PublicAccessLevels')
  73. const rateLimiters = {
  74. addEmail: new RateLimiter('add-email', {
  75. points: 10,
  76. duration: 60,
  77. }),
  78. addProjectToTag: new RateLimiter('add-project-to-tag', {
  79. points: 30,
  80. duration: 60,
  81. }),
  82. addProjectsToTag: new RateLimiter('add-projects-to-tag', {
  83. points: 30,
  84. duration: 60,
  85. }),
  86. canSkipCaptcha: new RateLimiter('can-skip-captcha', {
  87. points: 20,
  88. duration: 60,
  89. }),
  90. changePassword: new RateLimiter('change-password', {
  91. points: 10,
  92. duration: 60,
  93. }),
  94. compileProjectHttp: new RateLimiter('compile-project-http', {
  95. points: 800,
  96. duration: 60 * 60,
  97. }),
  98. confirmEmail: new RateLimiter('confirm-email', {
  99. points: 10,
  100. duration: 60,
  101. }),
  102. createProject: new RateLimiter('create-project', {
  103. points: 20,
  104. duration: 60,
  105. }),
  106. createTag: new RateLimiter('create-tag', {
  107. points: 30,
  108. duration: 60,
  109. }),
  110. deleteEmail: new RateLimiter('delete-email', {
  111. points: 10,
  112. duration: 60,
  113. }),
  114. deleteTag: new RateLimiter('delete-tag', {
  115. points: 30,
  116. duration: 60,
  117. }),
  118. deleteUser: new RateLimiter('delete-user', {
  119. points: 10,
  120. duration: 60,
  121. }),
  122. downloadProjectRevision: new RateLimiter('download-project-revision', {
  123. points: 30,
  124. duration: 60 * 60,
  125. }),
  126. endorseEmail: new RateLimiter('endorse-email', {
  127. points: 30,
  128. duration: 60,
  129. }),
  130. getProjects: new RateLimiter('get-projects', {
  131. points: 30,
  132. duration: 60,
  133. }),
  134. grantTokenAccessReadOnly: new RateLimiter('grant-token-access-read-only', {
  135. points: 10,
  136. duration: 60,
  137. }),
  138. grantTokenAccessReadWrite: new RateLimiter('grant-token-access-read-write', {
  139. points: 10,
  140. duration: 60,
  141. }),
  142. indexAllProjectReferences: new RateLimiter('index-all-project-references', {
  143. points: 30,
  144. duration: 60,
  145. }),
  146. miscOutputDownload: new RateLimiter('misc-output-download', {
  147. points: 1000,
  148. duration: 60 * 60,
  149. }),
  150. multipleProjectsZipDownload: new RateLimiter(
  151. 'multiple-projects-zip-download',
  152. {
  153. points: 10,
  154. duration: 60,
  155. }
  156. ),
  157. openDashboard: new RateLimiter('open-dashboard', {
  158. points: 30,
  159. duration: 60,
  160. }),
  161. readAndWriteToken: new RateLimiter('read-and-write-token', {
  162. points: 15,
  163. duration: 60,
  164. }),
  165. readOnlyToken: new RateLimiter('read-only-token', {
  166. points: 15,
  167. duration: 60,
  168. }),
  169. removeProjectFromTag: new RateLimiter('remove-project-from-tag', {
  170. points: 30,
  171. duration: 60,
  172. }),
  173. removeProjectsFromTag: new RateLimiter('remove-projects-from-tag', {
  174. points: 30,
  175. duration: 60,
  176. }),
  177. renameTag: new RateLimiter('rename-tag', {
  178. points: 30,
  179. duration: 60,
  180. }),
  181. resendConfirmation: new RateLimiter('resend-confirmation', {
  182. points: 1,
  183. duration: 60,
  184. }),
  185. sendChatMessage: new RateLimiter('send-chat-message', {
  186. points: 100,
  187. duration: 60,
  188. }),
  189. statusCompiler: new RateLimiter('status-compiler', {
  190. points: 10,
  191. duration: 60,
  192. }),
  193. zipDownload: new RateLimiter('zip-download', {
  194. points: 10,
  195. duration: 60,
  196. }),
  197. }
  198. function initialize(webRouter, privateApiRouter, publicApiRouter) {
  199. webRouter.use(unsupportedBrowserMiddleware)
  200. if (!Settings.allowPublicAccess) {
  201. webRouter.all('*', AuthenticationController.requireGlobalLogin)
  202. }
  203. webRouter.get('*', AnalyticsRegistrationSourceMiddleware.setInbound())
  204. webRouter.get('*', AnalyticsUTMTrackingMiddleware.recordUTMTags())
  205. // Mount onto /login in order to get the deviceHistory cookie.
  206. webRouter.post(
  207. '/login/can-skip-captcha',
  208. // Keep in sync with the overleaf-login options.
  209. RateLimiterMiddleware.rateLimit(rateLimiters.canSkipCaptcha),
  210. CaptchaMiddleware.canSkipCaptcha
  211. )
  212. webRouter.get('/login', UserPagesController.loginPage)
  213. AuthenticationController.addEndpointToLoginWhitelist('/login')
  214. webRouter.post(
  215. '/login',
  216. RateLimiterMiddleware.rateLimit(overleafLoginRateLimiter), // rate limit IP (20 / 60s)
  217. RateLimiterMiddleware.loginRateLimitEmail, // rate limit email (10 / 120s)
  218. CaptchaMiddleware.validateCaptcha('login'),
  219. AuthenticationController.passportLogin
  220. )
  221. webRouter.get(
  222. '/compromised-password',
  223. AuthenticationController.requireLogin(),
  224. UserPagesController.compromisedPasswordPage
  225. )
  226. webRouter.get('/account-suspended', UserPagesController.accountSuspended)
  227. if (Settings.enableLegacyLogin) {
  228. AuthenticationController.addEndpointToLoginWhitelist('/login/legacy')
  229. webRouter.get('/login/legacy', UserPagesController.loginPage)
  230. webRouter.post(
  231. '/login/legacy',
  232. RateLimiterMiddleware.rateLimit(overleafLoginRateLimiter), // rate limit IP (20 / 60s)
  233. RateLimiterMiddleware.loginRateLimitEmail, // rate limit email (10 / 120s)
  234. CaptchaMiddleware.validateCaptcha('login'),
  235. AuthenticationController.passportLogin
  236. )
  237. }
  238. webRouter.get(
  239. '/read-only/one-time-login',
  240. UserPagesController.oneTimeLoginPage
  241. )
  242. AuthenticationController.addEndpointToLoginWhitelist(
  243. '/read-only/one-time-login'
  244. )
  245. webRouter.post('/logout', UserController.logout)
  246. webRouter.get('/restricted', AuthorizationMiddleware.restricted)
  247. if (Features.hasFeature('registration-page')) {
  248. webRouter.get('/register', UserPagesController.registerPage)
  249. AuthenticationController.addEndpointToLoginWhitelist('/register')
  250. }
  251. EditorRouter.apply(webRouter, privateApiRouter)
  252. CollaboratorsRouter.apply(webRouter, privateApiRouter)
  253. SubscriptionRouter.apply(webRouter, privateApiRouter, publicApiRouter)
  254. UploadsRouter.apply(webRouter, privateApiRouter)
  255. PasswordResetRouter.apply(webRouter, privateApiRouter)
  256. StaticPagesRouter.apply(webRouter, privateApiRouter)
  257. ContactRouter.apply(webRouter, privateApiRouter)
  258. AnalyticsRouter.apply(webRouter, privateApiRouter, publicApiRouter)
  259. LinkedFilesRouter.apply(webRouter, privateApiRouter, publicApiRouter)
  260. TemplatesRouter.apply(webRouter)
  261. UserMembershipRouter.apply(webRouter)
  262. TokenAccessRouter.apply(webRouter)
  263. Modules.applyRouter(webRouter, privateApiRouter, publicApiRouter)
  264. if (Settings.enableSubscriptions) {
  265. webRouter.get(
  266. '/user/bonus',
  267. AuthenticationController.requireLogin(),
  268. ReferalController.bonus
  269. )
  270. }
  271. // .getMessages will generate an empty response for anonymous users.
  272. webRouter.get('/system/messages', SystemMessageController.getMessages)
  273. webRouter.get(
  274. '/user/settings',
  275. AuthenticationController.requireLogin(),
  276. PermissionsController.useCapabilities(),
  277. UserPagesController.settingsPage
  278. )
  279. webRouter.post(
  280. '/user/settings',
  281. AuthenticationController.requireLogin(),
  282. UserController.updateUserSettings
  283. )
  284. webRouter.post(
  285. '/user/password/update',
  286. AuthenticationController.requireLogin(),
  287. RateLimiterMiddleware.rateLimit(rateLimiters.changePassword),
  288. PermissionsController.requirePermission('change-password'),
  289. UserController.changePassword
  290. )
  291. webRouter.get(
  292. '/user/emails',
  293. AuthenticationController.requireLogin(),
  294. PermissionsController.useCapabilities(),
  295. UserController.promises.ensureAffiliationMiddleware,
  296. UserEmailsController.list
  297. )
  298. webRouter.get(
  299. '/user/emails/confirm',
  300. AuthenticationController.requireLogin(),
  301. UserEmailsController.showConfirm
  302. )
  303. webRouter.post(
  304. '/user/emails/confirm',
  305. AuthenticationController.requireLogin(),
  306. RateLimiterMiddleware.rateLimit(rateLimiters.confirmEmail),
  307. UserEmailsController.confirm
  308. )
  309. webRouter.post(
  310. '/user/emails/resend_confirmation',
  311. AuthenticationController.requireLogin(),
  312. RateLimiterMiddleware.rateLimit(rateLimiters.resendConfirmation),
  313. Modules.middleware('resendConfirmationEmail'),
  314. UserEmailsController.resendConfirmation
  315. )
  316. webRouter.get(
  317. '/user/emails/primary-email-check',
  318. AuthenticationController.requireLogin(),
  319. UserEmailsController.primaryEmailCheckPage
  320. )
  321. webRouter.post(
  322. '/user/emails/primary-email-check',
  323. AuthenticationController.requireLogin(),
  324. PermissionsController.useCapabilities(),
  325. UserEmailsController.primaryEmailCheck
  326. )
  327. if (Features.hasFeature('affiliations')) {
  328. webRouter.post(
  329. '/user/emails',
  330. AuthenticationController.requireLogin(),
  331. PermissionsController.requirePermission('add-secondary-email'),
  332. RateLimiterMiddleware.rateLimit(rateLimiters.addEmail),
  333. CaptchaMiddleware.validateCaptcha('addEmail'),
  334. UserEmailsController.add
  335. )
  336. webRouter.post(
  337. '/user/emails/delete',
  338. AuthenticationController.requireLogin(),
  339. RateLimiterMiddleware.rateLimit(rateLimiters.deleteEmail),
  340. Modules.middleware('userDeleteEmail'),
  341. UserEmailsController.remove
  342. )
  343. webRouter.post(
  344. '/user/emails/default',
  345. AuthenticationController.requireLogin(),
  346. UserEmailsController.setDefault
  347. )
  348. webRouter.post(
  349. '/user/emails/endorse',
  350. AuthenticationController.requireLogin(),
  351. PermissionsController.requirePermission('endorse-email'),
  352. RateLimiterMiddleware.rateLimit(rateLimiters.endorseEmail),
  353. UserEmailsController.endorse
  354. )
  355. }
  356. if (Features.hasFeature('saas')) {
  357. webRouter.get(
  358. '/user/emails/add-secondary',
  359. AuthenticationController.requireLogin(),
  360. PermissionsController.requirePermission('add-secondary-email'),
  361. UserEmailsController.addSecondaryEmailPage
  362. )
  363. webRouter.get(
  364. '/user/emails/confirm-secondary',
  365. AuthenticationController.requireLogin(),
  366. PermissionsController.requirePermission('add-secondary-email'),
  367. UserEmailsController.confirmSecondaryEmailPage
  368. )
  369. }
  370. webRouter.get(
  371. '/user/sessions',
  372. AuthenticationController.requireLogin(),
  373. UserPagesController.sessionsPage
  374. )
  375. webRouter.post(
  376. '/user/sessions/clear',
  377. AuthenticationController.requireLogin(),
  378. UserController.clearSessions
  379. )
  380. // deprecated
  381. webRouter.delete(
  382. '/user/newsletter/unsubscribe',
  383. AuthenticationController.requireLogin(),
  384. UserController.unsubscribe
  385. )
  386. webRouter.post(
  387. '/user/newsletter/unsubscribe',
  388. AuthenticationController.requireLogin(),
  389. UserController.unsubscribe
  390. )
  391. webRouter.post(
  392. '/user/newsletter/subscribe',
  393. AuthenticationController.requireLogin(),
  394. UserController.subscribe
  395. )
  396. webRouter.get(
  397. '/user/email-preferences',
  398. AuthenticationController.requireLogin(),
  399. UserPagesController.emailPreferencesPage
  400. )
  401. webRouter.post(
  402. '/user/delete',
  403. RateLimiterMiddleware.rateLimit(rateLimiters.deleteUser),
  404. AuthenticationController.requireLogin(),
  405. PermissionsController.requirePermission('delete-own-account'),
  406. UserController.tryDeleteUser
  407. )
  408. webRouter.get(
  409. '/user/personal_info',
  410. AuthenticationController.requireLogin(),
  411. UserInfoController.getLoggedInUsersPersonalInfo
  412. )
  413. privateApiRouter.get(
  414. '/user/:user_id/personal_info',
  415. AuthenticationController.requirePrivateApiAuth(),
  416. UserInfoController.getPersonalInfo
  417. )
  418. webRouter.get(
  419. '/user/reconfirm',
  420. UserPagesController.renderReconfirmAccountPage
  421. )
  422. // for /user/reconfirm POST, see password router
  423. webRouter.get(
  424. '/user/tpds/queues',
  425. AuthenticationController.requireLogin(),
  426. TpdsController.getQueues
  427. )
  428. webRouter.post(
  429. '/tutorial/:tutorialKey/complete',
  430. AuthenticationController.requireLogin(),
  431. TutorialController.completeTutorial
  432. )
  433. webRouter.post(
  434. '/tutorial/:tutorialKey/postpone',
  435. AuthenticationController.requireLogin(),
  436. TutorialController.postponeTutorial
  437. )
  438. webRouter.get(
  439. '/user/projects',
  440. AuthenticationController.requireLogin(),
  441. ProjectController.userProjectsJson
  442. )
  443. webRouter.get(
  444. '/project/:Project_id/entities',
  445. AuthenticationController.requireLogin(),
  446. AuthorizationMiddleware.ensureUserCanReadProject,
  447. ProjectController.projectEntitiesJson
  448. )
  449. webRouter.get(
  450. '/project',
  451. AuthenticationController.requireLogin(),
  452. RateLimiterMiddleware.rateLimit(rateLimiters.openDashboard),
  453. PermissionsController.useCapabilities(),
  454. ProjectListController.projectListPage
  455. )
  456. webRouter.post(
  457. '/project/new',
  458. AuthenticationController.requireLogin(),
  459. RateLimiterMiddleware.rateLimit(rateLimiters.createProject),
  460. ProjectController.newProject
  461. )
  462. webRouter.post(
  463. '/api/project',
  464. AuthenticationController.requireLogin(),
  465. RateLimiterMiddleware.rateLimit(rateLimiters.getProjects),
  466. ProjectListController.getProjectsJson
  467. )
  468. for (const route of [
  469. // Keep the old route for continuous metrics
  470. '/Project/:Project_id',
  471. // New route for pdf-detach
  472. '/Project/:Project_id/:detachRole(detacher|detached)',
  473. ]) {
  474. webRouter.get(
  475. route,
  476. RateLimiterMiddleware.rateLimit(openProjectRateLimiter, {
  477. params: ['Project_id'],
  478. }),
  479. PermissionsController.useCapabilities(),
  480. AuthorizationMiddleware.ensureUserCanReadProject,
  481. ProjectController.loadEditor
  482. )
  483. }
  484. webRouter.head(
  485. '/Project/:Project_id/file/:File_id',
  486. AuthorizationMiddleware.ensureUserCanReadProject,
  487. FileStoreController.getFileHead
  488. )
  489. webRouter.get(
  490. '/Project/:Project_id/file/:File_id',
  491. AuthorizationMiddleware.ensureUserCanReadProject,
  492. FileStoreController.getFile
  493. )
  494. webRouter.get(
  495. '/Project/:Project_id/doc/:Doc_id/download', // "download" suffix to avoid conflict with private API route at doc/:doc_id
  496. AuthorizationMiddleware.ensureUserCanReadProject,
  497. DocumentUpdaterController.getDoc
  498. )
  499. webRouter.post(
  500. '/project/:Project_id/settings',
  501. validate({
  502. body: Joi.object({
  503. publicAccessLevel: Joi.string()
  504. .valid(PublicAccessLevels.PRIVATE, PublicAccessLevels.TOKEN_BASED)
  505. .optional(),
  506. }),
  507. }),
  508. AuthorizationMiddleware.ensureUserCanWriteProjectSettings,
  509. ProjectController.updateProjectSettings
  510. )
  511. webRouter.post(
  512. '/project/:Project_id/settings/admin',
  513. AuthenticationController.requireLogin(),
  514. AuthorizationMiddleware.ensureUserCanAdminProject,
  515. ProjectController.updateProjectAdminSettings
  516. )
  517. webRouter.post(
  518. '/project/:Project_id/compile',
  519. RateLimiterMiddleware.rateLimit(rateLimiters.compileProjectHttp, {
  520. params: ['Project_id'],
  521. }),
  522. AuthorizationMiddleware.ensureUserCanReadProject,
  523. CompileController.compile
  524. )
  525. webRouter.post(
  526. '/project/:Project_id/compile/stop',
  527. AuthorizationMiddleware.ensureUserCanReadProject,
  528. CompileController.stopCompile
  529. )
  530. // LEGACY: Used by the web download buttons, adds filename header, TODO: remove at some future date
  531. webRouter.get(
  532. '/project/:Project_id/output/output.pdf',
  533. AuthorizationMiddleware.ensureUserCanReadProject,
  534. CompileController.downloadPdf
  535. )
  536. // PDF Download button
  537. webRouter.get(
  538. /^\/download\/project\/([^/]*)\/output\/output\.pdf$/,
  539. function (req, res, next) {
  540. const params = { Project_id: req.params[0] }
  541. req.params = params
  542. next()
  543. },
  544. AuthorizationMiddleware.ensureUserCanReadProject,
  545. CompileController.downloadPdf
  546. )
  547. // PDF Download button for specific build
  548. webRouter.get(
  549. /^\/download\/project\/([^/]*)\/build\/([0-9a-f-]+)\/output\/output\.pdf$/,
  550. function (req, res, next) {
  551. const params = {
  552. Project_id: req.params[0],
  553. build_id: req.params[1],
  554. }
  555. req.params = params
  556. next()
  557. },
  558. AuthorizationMiddleware.ensureUserCanReadProject,
  559. CompileController.downloadPdf
  560. )
  561. // Align with limits defined in CompileController.downloadPdf
  562. const rateLimiterMiddlewareOutputFiles = RateLimiterMiddleware.rateLimit(
  563. rateLimiters.miscOutputDownload,
  564. { params: ['Project_id'] }
  565. )
  566. // Used by the pdf viewers
  567. webRouter.get(
  568. /^\/project\/([^/]*)\/output\/(.*)$/,
  569. function (req, res, next) {
  570. const params = {
  571. Project_id: req.params[0],
  572. file: req.params[1],
  573. }
  574. req.params = params
  575. next()
  576. },
  577. rateLimiterMiddlewareOutputFiles,
  578. AuthorizationMiddleware.ensureUserCanReadProject,
  579. CompileController.getFileFromClsi
  580. )
  581. // direct url access to output files for a specific build (query string not required)
  582. webRouter.get(
  583. /^\/project\/([^/]*)\/build\/([0-9a-f-]+)\/output\/(.*)$/,
  584. function (req, res, next) {
  585. const params = {
  586. Project_id: req.params[0],
  587. build_id: req.params[1],
  588. file: req.params[2],
  589. }
  590. req.params = params
  591. next()
  592. },
  593. rateLimiterMiddlewareOutputFiles,
  594. AuthorizationMiddleware.ensureUserCanReadProject,
  595. CompileController.getFileFromClsi
  596. )
  597. // direct url access to output files for user but no build, to retrieve files when build fails
  598. webRouter.get(
  599. /^\/project\/([^/]*)\/user\/([0-9a-f-]+)\/output\/(.*)$/,
  600. function (req, res, next) {
  601. const params = {
  602. Project_id: req.params[0],
  603. user_id: req.params[1],
  604. file: req.params[2],
  605. }
  606. req.params = params
  607. next()
  608. },
  609. rateLimiterMiddlewareOutputFiles,
  610. AuthorizationMiddleware.ensureUserCanReadProject,
  611. CompileController.getFileFromClsi
  612. )
  613. // direct url access to output files for a specific user and build (query string not required)
  614. webRouter.get(
  615. /^\/project\/([^/]*)\/user\/([0-9a-f]+)\/build\/([0-9a-f-]+)\/output\/(.*)$/,
  616. function (req, res, next) {
  617. const params = {
  618. Project_id: req.params[0],
  619. user_id: req.params[1],
  620. build_id: req.params[2],
  621. file: req.params[3],
  622. }
  623. req.params = params
  624. next()
  625. },
  626. rateLimiterMiddlewareOutputFiles,
  627. AuthorizationMiddleware.ensureUserCanReadProject,
  628. CompileController.getFileFromClsi
  629. )
  630. webRouter.delete(
  631. '/project/:Project_id/output',
  632. validate({ query: { clsiserverid: Joi.string() } }),
  633. AuthorizationMiddleware.ensureUserCanReadProject,
  634. CompileController.deleteAuxFiles
  635. )
  636. webRouter.get(
  637. '/project/:Project_id/sync/code',
  638. AuthorizationMiddleware.ensureUserCanReadProject,
  639. CompileController.proxySyncCode
  640. )
  641. webRouter.get(
  642. '/project/:Project_id/sync/pdf',
  643. AuthorizationMiddleware.ensureUserCanReadProject,
  644. CompileController.proxySyncPdf
  645. )
  646. webRouter.get(
  647. '/project/:Project_id/wordcount',
  648. validate({ query: { clsiserverid: Joi.string() } }),
  649. AuthorizationMiddleware.ensureUserCanReadProject,
  650. CompileController.wordCount
  651. )
  652. webRouter.post(
  653. '/Project/:Project_id/archive',
  654. AuthenticationController.requireLogin(),
  655. AuthorizationMiddleware.ensureUserCanReadProject,
  656. ProjectController.archiveProject
  657. )
  658. webRouter.delete(
  659. '/Project/:Project_id/archive',
  660. AuthenticationController.requireLogin(),
  661. AuthorizationMiddleware.ensureUserCanReadProject,
  662. ProjectController.unarchiveProject
  663. )
  664. webRouter.post(
  665. '/project/:project_id/trash',
  666. AuthenticationController.requireLogin(),
  667. AuthorizationMiddleware.ensureUserCanReadProject,
  668. ProjectController.trashProject
  669. )
  670. webRouter.delete(
  671. '/project/:project_id/trash',
  672. AuthenticationController.requireLogin(),
  673. AuthorizationMiddleware.ensureUserCanReadProject,
  674. ProjectController.untrashProject
  675. )
  676. webRouter.delete(
  677. '/Project/:Project_id',
  678. AuthenticationController.requireLogin(),
  679. AuthorizationMiddleware.ensureUserCanAdminProject,
  680. ProjectController.deleteProject
  681. )
  682. webRouter.post(
  683. '/Project/:Project_id/restore',
  684. AuthenticationController.requireLogin(),
  685. AuthorizationMiddleware.ensureUserCanAdminProject,
  686. ProjectController.restoreProject
  687. )
  688. webRouter.post(
  689. '/Project/:Project_id/clone',
  690. AuthorizationMiddleware.ensureUserCanReadProject,
  691. ProjectController.cloneProject
  692. )
  693. webRouter.post(
  694. '/project/:Project_id/rename',
  695. AuthenticationController.requireLogin(),
  696. AuthorizationMiddleware.ensureUserCanAdminProject,
  697. ProjectController.renameProject
  698. )
  699. webRouter.get(
  700. '/project/:Project_id/updates',
  701. AuthorizationMiddleware.blockRestrictedUserFromProject,
  702. AuthorizationMiddleware.ensureUserCanReadProject,
  703. HistoryController.proxyToHistoryApiAndInjectUserDetails
  704. )
  705. webRouter.get(
  706. '/project/:Project_id/doc/:doc_id/diff',
  707. AuthorizationMiddleware.blockRestrictedUserFromProject,
  708. AuthorizationMiddleware.ensureUserCanReadProject,
  709. HistoryController.proxyToHistoryApi
  710. )
  711. webRouter.get(
  712. '/project/:Project_id/diff',
  713. AuthorizationMiddleware.blockRestrictedUserFromProject,
  714. AuthorizationMiddleware.ensureUserCanReadProject,
  715. HistoryController.proxyToHistoryApiAndInjectUserDetails
  716. )
  717. webRouter.get(
  718. '/project/:Project_id/filetree/diff',
  719. AuthorizationMiddleware.blockRestrictedUserFromProject,
  720. AuthorizationMiddleware.ensureUserCanReadProject,
  721. HistoryController.proxyToHistoryApi
  722. )
  723. webRouter.post(
  724. '/project/:project_id/restore_file',
  725. AuthorizationMiddleware.ensureUserCanWriteProjectContent,
  726. HistoryController.restoreFileFromV2
  727. )
  728. webRouter.post(
  729. '/project/:project_id/revert_file',
  730. AuthorizationMiddleware.ensureUserCanWriteProjectContent,
  731. HistoryController.revertFile
  732. )
  733. webRouter.get(
  734. '/project/:project_id/version/:version/zip',
  735. RateLimiterMiddleware.rateLimit(rateLimiters.downloadProjectRevision),
  736. AuthorizationMiddleware.blockRestrictedUserFromProject,
  737. AuthorizationMiddleware.ensureUserCanReadProject,
  738. HistoryController.downloadZipOfVersion
  739. )
  740. privateApiRouter.post(
  741. '/project/:Project_id/history/resync',
  742. AuthenticationController.requirePrivateApiAuth(),
  743. HistoryController.resyncProjectHistory
  744. )
  745. webRouter.get(
  746. '/project/:Project_id/labels',
  747. AuthorizationMiddleware.blockRestrictedUserFromProject,
  748. AuthorizationMiddleware.ensureUserCanReadProject,
  749. HistoryController.getLabels
  750. )
  751. webRouter.post(
  752. '/project/:Project_id/labels',
  753. AuthorizationMiddleware.ensureUserCanWriteProjectContent,
  754. HistoryController.createLabel
  755. )
  756. webRouter.delete(
  757. '/project/:Project_id/labels/:label_id',
  758. AuthorizationMiddleware.ensureUserCanWriteProjectContent,
  759. HistoryController.deleteLabel
  760. )
  761. webRouter.post(
  762. '/project/:project_id/export/:brand_variation_id',
  763. AuthorizationMiddleware.ensureUserCanWriteProjectContent,
  764. ExportsController.exportProject
  765. )
  766. webRouter.get(
  767. '/project/:project_id/export/:export_id',
  768. AuthorizationMiddleware.ensureUserCanWriteProjectContent,
  769. ExportsController.exportStatus
  770. )
  771. webRouter.get(
  772. '/project/:project_id/export/:export_id/:type',
  773. AuthorizationMiddleware.ensureUserCanWriteProjectContent,
  774. ExportsController.exportDownload
  775. )
  776. webRouter.get(
  777. '/Project/:Project_id/download/zip',
  778. RateLimiterMiddleware.rateLimit(rateLimiters.zipDownload, {
  779. params: ['Project_id'],
  780. }),
  781. AuthorizationMiddleware.ensureUserCanReadProject,
  782. ProjectDownloadsController.downloadProject
  783. )
  784. webRouter.get(
  785. '/project/download/zip',
  786. AuthenticationController.requireLogin(),
  787. RateLimiterMiddleware.rateLimit(rateLimiters.multipleProjectsZipDownload),
  788. AuthorizationMiddleware.ensureUserCanReadMultipleProjects,
  789. ProjectDownloadsController.downloadMultipleProjects
  790. )
  791. webRouter.get(
  792. '/project/:project_id/metadata',
  793. AuthorizationMiddleware.ensureUserCanReadProject,
  794. Settings.allowAnonymousReadAndWriteSharing
  795. ? (req, res, next) => {
  796. next()
  797. }
  798. : AuthenticationController.requireLogin(),
  799. MetaController.getMetadata
  800. )
  801. webRouter.post(
  802. '/project/:project_id/doc/:doc_id/metadata',
  803. AuthorizationMiddleware.ensureUserCanReadProject,
  804. Settings.allowAnonymousReadAndWriteSharing
  805. ? (req, res, next) => {
  806. next()
  807. }
  808. : AuthenticationController.requireLogin(),
  809. MetaController.broadcastMetadataForDoc
  810. )
  811. privateApiRouter.post(
  812. '/internal/expire-deleted-projects-after-duration',
  813. AuthenticationController.requirePrivateApiAuth(),
  814. ProjectController.expireDeletedProjectsAfterDuration
  815. )
  816. privateApiRouter.post(
  817. '/internal/expire-deleted-users-after-duration',
  818. AuthenticationController.requirePrivateApiAuth(),
  819. UserController.expireDeletedUsersAfterDuration
  820. )
  821. privateApiRouter.post(
  822. '/internal/project/:projectId/expire-deleted-project',
  823. AuthenticationController.requirePrivateApiAuth(),
  824. ProjectController.expireDeletedProject
  825. )
  826. privateApiRouter.post(
  827. '/internal/users/:userId/expire',
  828. AuthenticationController.requirePrivateApiAuth(),
  829. UserController.expireDeletedUser
  830. )
  831. privateApiRouter.get(
  832. '/user/:userId/tag',
  833. AuthenticationController.requirePrivateApiAuth(),
  834. TagsController.apiGetAllTags
  835. )
  836. webRouter.get(
  837. '/tag',
  838. AuthenticationController.requireLogin(),
  839. TagsController.getAllTags
  840. )
  841. webRouter.post(
  842. '/tag',
  843. AuthenticationController.requireLogin(),
  844. RateLimiterMiddleware.rateLimit(rateLimiters.createTag),
  845. validate({
  846. body: Joi.object({
  847. name: Joi.string().required(),
  848. color: Joi.string(),
  849. }),
  850. }),
  851. TagsController.createTag
  852. )
  853. webRouter.post(
  854. '/tag/:tagId/rename',
  855. AuthenticationController.requireLogin(),
  856. RateLimiterMiddleware.rateLimit(rateLimiters.renameTag),
  857. validate({
  858. body: Joi.object({
  859. name: Joi.string().required(),
  860. }),
  861. }),
  862. TagsController.renameTag
  863. )
  864. webRouter.post(
  865. '/tag/:tagId/edit',
  866. AuthenticationController.requireLogin(),
  867. RateLimiterMiddleware.rateLimit(rateLimiters.renameTag),
  868. validate({
  869. body: Joi.object({
  870. name: Joi.string().required(),
  871. color: Joi.string(),
  872. }),
  873. }),
  874. TagsController.editTag
  875. )
  876. webRouter.delete(
  877. '/tag/:tagId',
  878. AuthenticationController.requireLogin(),
  879. RateLimiterMiddleware.rateLimit(rateLimiters.deleteTag),
  880. TagsController.deleteTag
  881. )
  882. webRouter.post(
  883. '/tag/:tagId/project/:projectId',
  884. AuthenticationController.requireLogin(),
  885. RateLimiterMiddleware.rateLimit(rateLimiters.addProjectToTag),
  886. TagsController.addProjectToTag
  887. )
  888. webRouter.post(
  889. '/tag/:tagId/projects',
  890. AuthenticationController.requireLogin(),
  891. RateLimiterMiddleware.rateLimit(rateLimiters.addProjectsToTag),
  892. validate({
  893. body: Joi.object({
  894. projectIds: Joi.array().items(Joi.string()).required(),
  895. }),
  896. }),
  897. TagsController.addProjectsToTag
  898. )
  899. webRouter.delete(
  900. '/tag/:tagId/project/:projectId',
  901. AuthenticationController.requireLogin(),
  902. RateLimiterMiddleware.rateLimit(rateLimiters.removeProjectFromTag),
  903. TagsController.removeProjectFromTag
  904. )
  905. webRouter.post(
  906. '/tag/:tagId/projects/remove',
  907. AuthenticationController.requireLogin(),
  908. RateLimiterMiddleware.rateLimit(rateLimiters.removeProjectsFromTag),
  909. validate({
  910. body: Joi.object({
  911. projectIds: Joi.array().items(Joi.string()).required(),
  912. }),
  913. }),
  914. TagsController.removeProjectsFromTag
  915. )
  916. webRouter.get(
  917. '/notifications',
  918. AuthenticationController.requireLogin(),
  919. NotificationsController.getAllUnreadNotifications
  920. )
  921. webRouter.delete(
  922. '/notifications/:notificationId',
  923. AuthenticationController.requireLogin(),
  924. NotificationsController.markNotificationAsRead
  925. )
  926. // Deprecated in favour of /internal/project/:project_id but still used by versioning
  927. privateApiRouter.get(
  928. '/project/:project_id/details',
  929. AuthenticationController.requirePrivateApiAuth(),
  930. ProjectApiController.getProjectDetails
  931. )
  932. // New 'stable' /internal API end points
  933. privateApiRouter.get(
  934. '/internal/project/:project_id',
  935. AuthenticationController.requirePrivateApiAuth(),
  936. ProjectApiController.getProjectDetails
  937. )
  938. privateApiRouter.get(
  939. '/internal/project/:Project_id/zip',
  940. AuthenticationController.requirePrivateApiAuth(),
  941. ProjectDownloadsController.downloadProject
  942. )
  943. privateApiRouter.get(
  944. '/internal/project/:project_id/compile/pdf',
  945. AuthenticationController.requirePrivateApiAuth(),
  946. CompileController.compileAndDownloadPdf
  947. )
  948. privateApiRouter.post(
  949. '/internal/deactivateOldProjects',
  950. AuthenticationController.requirePrivateApiAuth(),
  951. InactiveProjectController.deactivateOldProjects
  952. )
  953. privateApiRouter.post(
  954. '/internal/project/:project_id/deactivate',
  955. AuthenticationController.requirePrivateApiAuth(),
  956. InactiveProjectController.deactivateProject
  957. )
  958. privateApiRouter.get(
  959. /^\/internal\/project\/([^/]*)\/output\/(.*)$/,
  960. function (req, res, next) {
  961. const params = {
  962. Project_id: req.params[0],
  963. file: req.params[1],
  964. }
  965. req.params = params
  966. next()
  967. },
  968. AuthenticationController.requirePrivateApiAuth(),
  969. CompileController.getFileFromClsi
  970. )
  971. privateApiRouter.get(
  972. '/project/:Project_id/doc/:doc_id',
  973. AuthenticationController.requirePrivateApiAuth(),
  974. DocumentController.getDocument
  975. )
  976. privateApiRouter.post(
  977. '/project/:Project_id/doc/:doc_id',
  978. AuthenticationController.requirePrivateApiAuth(),
  979. DocumentController.setDocument
  980. )
  981. privateApiRouter.post(
  982. '/user/:user_id/project/new',
  983. AuthenticationController.requirePrivateApiAuth(),
  984. TpdsController.createProject
  985. )
  986. privateApiRouter.post(
  987. '/tpds/folder-update',
  988. AuthenticationController.requirePrivateApiAuth(),
  989. TpdsController.updateFolder
  990. )
  991. privateApiRouter.post(
  992. '/user/:user_id/update/*',
  993. AuthenticationController.requirePrivateApiAuth(),
  994. TpdsController.mergeUpdate
  995. )
  996. privateApiRouter.delete(
  997. '/user/:user_id/update/*',
  998. AuthenticationController.requirePrivateApiAuth(),
  999. TpdsController.deleteUpdate
  1000. )
  1001. privateApiRouter.post(
  1002. '/project/:project_id/user/:user_id/update/*',
  1003. AuthenticationController.requirePrivateApiAuth(),
  1004. TpdsController.mergeUpdate
  1005. )
  1006. privateApiRouter.delete(
  1007. '/project/:project_id/user/:user_id/update/*',
  1008. AuthenticationController.requirePrivateApiAuth(),
  1009. TpdsController.deleteUpdate
  1010. )
  1011. privateApiRouter.post(
  1012. '/project/:project_id/contents/*',
  1013. AuthenticationController.requirePrivateApiAuth(),
  1014. TpdsController.updateProjectContents
  1015. )
  1016. privateApiRouter.delete(
  1017. '/project/:project_id/contents/*',
  1018. AuthenticationController.requirePrivateApiAuth(),
  1019. TpdsController.deleteProjectContents
  1020. )
  1021. webRouter.post(
  1022. '/spelling/check',
  1023. AuthenticationController.requireLogin(),
  1024. SpellingController.proxyCheckRequestToSpellingApi
  1025. )
  1026. webRouter.post(
  1027. '/spelling/learn',
  1028. validate({
  1029. body: Joi.object({
  1030. word: Joi.string().required(),
  1031. }),
  1032. }),
  1033. AuthenticationController.requireLogin(),
  1034. SpellingController.learn
  1035. )
  1036. webRouter.post(
  1037. '/spelling/unlearn',
  1038. validate({
  1039. body: Joi.object({
  1040. word: Joi.string().required(),
  1041. }),
  1042. }),
  1043. AuthenticationController.requireLogin(),
  1044. SpellingController.unlearn
  1045. )
  1046. webRouter.get(
  1047. '/project/:project_id/messages',
  1048. AuthorizationMiddleware.blockRestrictedUserFromProject,
  1049. AuthorizationMiddleware.ensureUserCanReadProject,
  1050. ChatController.getMessages
  1051. )
  1052. webRouter.post(
  1053. '/project/:project_id/messages',
  1054. AuthorizationMiddleware.blockRestrictedUserFromProject,
  1055. AuthorizationMiddleware.ensureUserCanReadProject,
  1056. RateLimiterMiddleware.rateLimit(rateLimiters.sendChatMessage),
  1057. ChatController.sendMessage
  1058. )
  1059. webRouter.post(
  1060. '/project/:Project_id/references/indexAll',
  1061. AuthorizationMiddleware.ensureUserCanReadProject,
  1062. RateLimiterMiddleware.rateLimit(rateLimiters.indexAllProjectReferences),
  1063. ReferencesController.indexAll
  1064. )
  1065. // disable beta program while v2 is in beta
  1066. webRouter.get(
  1067. '/beta/participate',
  1068. AuthenticationController.requireLogin(),
  1069. BetaProgramController.optInPage
  1070. )
  1071. webRouter.post(
  1072. '/beta/opt-in',
  1073. AuthenticationController.requireLogin(),
  1074. BetaProgramController.optIn
  1075. )
  1076. webRouter.post(
  1077. '/beta/opt-out',
  1078. AuthenticationController.requireLogin(),
  1079. BetaProgramController.optOut
  1080. )
  1081. webRouter.get('/chrome', function (req, res, next) {
  1082. // Match v1 behaviour - this is used for a Chrome web app
  1083. if (SessionManager.isUserLoggedIn(req.session)) {
  1084. res.redirect('/project')
  1085. } else {
  1086. res.redirect('/register')
  1087. }
  1088. })
  1089. webRouter.get(
  1090. '/admin',
  1091. AuthorizationMiddleware.ensureUserIsSiteAdmin,
  1092. AdminController.index
  1093. )
  1094. if (!Features.hasFeature('saas')) {
  1095. webRouter.post(
  1096. '/admin/openEditor',
  1097. AuthorizationMiddleware.ensureUserIsSiteAdmin,
  1098. AdminController.openEditor
  1099. )
  1100. webRouter.post(
  1101. '/admin/closeEditor',
  1102. AuthorizationMiddleware.ensureUserIsSiteAdmin,
  1103. AdminController.closeEditor
  1104. )
  1105. webRouter.post(
  1106. '/admin/disconnectAllUsers',
  1107. AuthorizationMiddleware.ensureUserIsSiteAdmin,
  1108. AdminController.disconnectAllUsers
  1109. )
  1110. }
  1111. webRouter.post(
  1112. '/admin/flushProjectToTpds',
  1113. AuthorizationMiddleware.ensureUserIsSiteAdmin,
  1114. AdminController.flushProjectToTpds
  1115. )
  1116. webRouter.post(
  1117. '/admin/pollDropboxForUser',
  1118. AuthorizationMiddleware.ensureUserIsSiteAdmin,
  1119. AdminController.pollDropboxForUser
  1120. )
  1121. webRouter.post(
  1122. '/admin/messages',
  1123. AuthorizationMiddleware.ensureUserIsSiteAdmin,
  1124. AdminController.createMessage
  1125. )
  1126. webRouter.post(
  1127. '/admin/messages/clear',
  1128. AuthorizationMiddleware.ensureUserIsSiteAdmin,
  1129. AdminController.clearMessages
  1130. )
  1131. privateApiRouter.get('/perfTest', (req, res) => {
  1132. plainTextResponse(res, 'hello')
  1133. })
  1134. publicApiRouter.get('/status', (req, res) => {
  1135. if (Settings.shuttingDown) {
  1136. res.sendStatus(503) // Service unavailable
  1137. } else if (!Settings.siteIsOpen) {
  1138. plainTextResponse(res, 'web site is closed (web)')
  1139. } else if (!Settings.editorIsOpen) {
  1140. plainTextResponse(res, 'web editor is closed (web)')
  1141. } else {
  1142. plainTextResponse(res, 'web is alive (web)')
  1143. }
  1144. })
  1145. privateApiRouter.get('/status', (req, res) => {
  1146. plainTextResponse(res, 'web is alive (api)')
  1147. })
  1148. // used by kubernetes health-check and acceptance tests
  1149. webRouter.get('/dev/csrf', (req, res) => {
  1150. plainTextResponse(res, res.locals.csrfToken)
  1151. })
  1152. publicApiRouter.get(
  1153. '/health_check',
  1154. HealthCheckController.checkActiveHandles,
  1155. HealthCheckController.check
  1156. )
  1157. privateApiRouter.get(
  1158. '/health_check',
  1159. HealthCheckController.checkActiveHandles,
  1160. HealthCheckController.checkApi
  1161. )
  1162. publicApiRouter.get(
  1163. '/health_check/api',
  1164. HealthCheckController.checkActiveHandles,
  1165. HealthCheckController.checkApi
  1166. )
  1167. privateApiRouter.get(
  1168. '/health_check/api',
  1169. HealthCheckController.checkActiveHandles,
  1170. HealthCheckController.checkApi
  1171. )
  1172. publicApiRouter.get(
  1173. '/health_check/full',
  1174. HealthCheckController.checkActiveHandles,
  1175. HealthCheckController.check
  1176. )
  1177. privateApiRouter.get(
  1178. '/health_check/full',
  1179. HealthCheckController.checkActiveHandles,
  1180. HealthCheckController.check
  1181. )
  1182. publicApiRouter.get('/health_check/redis', HealthCheckController.checkRedis)
  1183. privateApiRouter.get('/health_check/redis', HealthCheckController.checkRedis)
  1184. publicApiRouter.get('/health_check/mongo', HealthCheckController.checkMongo)
  1185. privateApiRouter.get('/health_check/mongo', HealthCheckController.checkMongo)
  1186. webRouter.get(
  1187. '/status/compiler/:Project_id',
  1188. RateLimiterMiddleware.rateLimit(rateLimiters.statusCompiler),
  1189. AuthorizationMiddleware.ensureUserCanReadProject,
  1190. function (req, res) {
  1191. const projectId = req.params.Project_id
  1192. // use a valid user id for testing
  1193. const testUserId = '123456789012345678901234'
  1194. const sendRes = _.once(function (statusCode, message) {
  1195. res.status(statusCode)
  1196. plainTextResponse(res, message)
  1197. ClsiCookieManager.clearServerId(projectId, testUserId, () => {})
  1198. }) // force every compile to a new server
  1199. // set a timeout
  1200. let handler = setTimeout(function () {
  1201. sendRes(500, 'Compiler timed out')
  1202. handler = null
  1203. }, 10000)
  1204. // run the compile
  1205. CompileManager.compile(
  1206. projectId,
  1207. testUserId,
  1208. {},
  1209. function (error, status) {
  1210. if (handler) {
  1211. clearTimeout(handler)
  1212. }
  1213. if (error) {
  1214. sendRes(500, `Compiler returned error ${error.message}`)
  1215. } else if (status === 'success') {
  1216. sendRes(200, 'Compiler returned in less than 10 seconds')
  1217. } else {
  1218. sendRes(500, `Compiler returned failure ${status}`)
  1219. }
  1220. }
  1221. )
  1222. }
  1223. )
  1224. webRouter.post('/error/client', function (req, res, next) {
  1225. logger.warn(
  1226. { err: req.body.error, meta: req.body.meta },
  1227. 'client side error'
  1228. )
  1229. metrics.inc('client-side-error')
  1230. res.sendStatus(204)
  1231. })
  1232. webRouter.get(
  1233. `/read/:token(${TokenAccessController.READ_ONLY_TOKEN_PATTERN})`,
  1234. RateLimiterMiddleware.rateLimit(rateLimiters.readOnlyToken),
  1235. AnalyticsRegistrationSourceMiddleware.setSource(
  1236. 'collaboration',
  1237. 'link-sharing'
  1238. ),
  1239. TokenAccessController.tokenAccessPage,
  1240. AnalyticsRegistrationSourceMiddleware.clearSource()
  1241. )
  1242. webRouter.get(
  1243. `/:token(${TokenAccessController.READ_AND_WRITE_TOKEN_PATTERN})`,
  1244. RateLimiterMiddleware.rateLimit(rateLimiters.readAndWriteToken),
  1245. AnalyticsRegistrationSourceMiddleware.setSource(
  1246. 'collaboration',
  1247. 'link-sharing'
  1248. ),
  1249. TokenAccessController.tokenAccessPage,
  1250. AnalyticsRegistrationSourceMiddleware.clearSource()
  1251. )
  1252. webRouter.post(
  1253. `/:token(${TokenAccessController.READ_AND_WRITE_TOKEN_PATTERN})/grant`,
  1254. RateLimiterMiddleware.rateLimit(rateLimiters.grantTokenAccessReadWrite),
  1255. TokenAccessController.grantTokenAccessReadAndWrite
  1256. )
  1257. webRouter.post(
  1258. `/read/:token(${TokenAccessController.READ_ONLY_TOKEN_PATTERN})/grant`,
  1259. RateLimiterMiddleware.rateLimit(rateLimiters.grantTokenAccessReadOnly),
  1260. TokenAccessController.grantTokenAccessReadOnly
  1261. )
  1262. webRouter.get('/unsupported-browser', renderUnsupportedBrowserPage)
  1263. webRouter.get('*', ErrorController.notFound)
  1264. }
  1265. module.exports = { initialize, rateLimiters }