router.mjs 39 KB

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