MockWebApi.js 3.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135
  1. let MockWebApi
  2. const basicAuth = require('basic-auth')
  3. const tsscmp = require('tsscmp')
  4. const express = require('express')
  5. const bodyParser = require('body-parser')
  6. const { expressify } = require('@overleaf/promise-utils')
  7. const Settings = require('@overleaf/settings')
  8. const app = express()
  9. const MAX_REQUEST_SIZE = 2 * (2 * 1024 * 1024 + 64 * 1024)
  10. module.exports = MockWebApi = {
  11. docs: {},
  12. clearDocs() {
  13. return (this.docs = {})
  14. },
  15. insertDoc(projectId, docId, doc) {
  16. if (doc.version == null) {
  17. doc.version = 0
  18. }
  19. if (doc.lines == null) {
  20. doc.lines = []
  21. }
  22. doc.pathname = '/a/b/c.tex'
  23. return (this.docs[`${projectId}:${docId}`] = doc)
  24. },
  25. async setDocument(
  26. projectId,
  27. docId,
  28. lines,
  29. version,
  30. ranges,
  31. lastUpdatedAt,
  32. lastUpdatedBy
  33. ) {
  34. if (!(`${projectId}:${docId}` in this.docs)) {
  35. return false
  36. }
  37. const doc = this.docs[`${projectId}:${docId}`]
  38. doc.lines = lines
  39. doc.version = version
  40. doc.ranges = ranges
  41. doc.pathname = '/a/b/c.tex'
  42. doc.lastUpdatedAt = lastUpdatedAt
  43. doc.lastUpdatedBy = lastUpdatedBy
  44. return true
  45. },
  46. async getDocument(projectId, docId) {
  47. return this.docs[`${projectId}:${docId}`]
  48. },
  49. async getDocumentController(req, res, next) {
  50. try {
  51. const doc = await this.getDocument(
  52. req.params.project_id,
  53. req.params.doc_id
  54. )
  55. if (doc != null) {
  56. return res.send(JSON.stringify(doc))
  57. } else {
  58. return res.sendStatus(404)
  59. }
  60. } catch (error) {
  61. return res.sendStatus(500)
  62. }
  63. },
  64. async setDocumentController(req, res, next) {
  65. try {
  66. const ok = await this.setDocument(
  67. req.params.project_id,
  68. req.params.doc_id,
  69. req.body.lines,
  70. req.body.version,
  71. req.body.ranges,
  72. req.body.lastUpdatedAt,
  73. req.body.lastUpdatedBy
  74. )
  75. if (!ok) {
  76. return res.sendStatus(404)
  77. }
  78. return res.json({ rev: '123' })
  79. } catch (error) {
  80. return res.sendStatus(500)
  81. }
  82. },
  83. run() {
  84. app.use((req, res, next) => {
  85. const credentials = basicAuth(req)
  86. if (
  87. !credentials ||
  88. !Settings.apis.web.user ||
  89. credentials.name !== Settings.apis.web.user ||
  90. !Settings.apis.web.pass ||
  91. !tsscmp(credentials.pass, Settings.apis.web.pass)
  92. ) {
  93. return res.sendStatus(401)
  94. } else {
  95. next()
  96. }
  97. })
  98. app.get(
  99. '/project/:project_id/doc/:doc_id',
  100. expressify(async (req, res, next) => {
  101. await this.getDocumentController(req, res, next)
  102. })
  103. )
  104. app.post(
  105. '/project/:project_id/doc/:doc_id',
  106. bodyParser.json({ limit: MAX_REQUEST_SIZE }),
  107. expressify(async (req, res, next) => {
  108. await this.setDocumentController(req, res, next)
  109. })
  110. )
  111. return app
  112. .listen(3000, error => {
  113. if (error != null) {
  114. throw error
  115. }
  116. })
  117. .on('error', error => {
  118. console.error('error starting MockWebApi:', error.message)
  119. return process.exit(1)
  120. })
  121. },
  122. }
  123. MockWebApi.run()