Errors.js 5.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223
  1. const OError = require('@overleaf/o-error')
  2. const settings = require('@overleaf/settings')
  3. // Error class for legacy errors so they inherit OError while staying
  4. // backward-compatible (can be instantiated with string as argument instead
  5. // of object)
  6. class BackwardCompatibleError extends OError {
  7. constructor(messageOrOptions) {
  8. if (typeof messageOrOptions === 'string') {
  9. super(messageOrOptions)
  10. } else if (messageOrOptions) {
  11. const { message, info } = messageOrOptions
  12. super(message, info)
  13. } else {
  14. super()
  15. }
  16. }
  17. }
  18. // Error class that facilitates the migration to OError v3 by providing
  19. // a signature in which the 2nd argument can be an object containing
  20. // the `info` object.
  21. class OErrorV2CompatibleError extends OError {
  22. constructor(message, options) {
  23. if (options) {
  24. super(message, options.info)
  25. } else {
  26. super(message)
  27. }
  28. }
  29. }
  30. class NotFoundError extends BackwardCompatibleError {}
  31. class ForbiddenError extends BackwardCompatibleError {}
  32. class ServiceNotConfiguredError extends BackwardCompatibleError {}
  33. class TooManyRequestsError extends BackwardCompatibleError {}
  34. class InvalidNameError extends BackwardCompatibleError {}
  35. class UnsupportedFileTypeError extends BackwardCompatibleError {}
  36. class FileTooLargeError extends BackwardCompatibleError {}
  37. class UnsupportedExportRecordsError extends BackwardCompatibleError {}
  38. class V1HistoryNotSyncedError extends BackwardCompatibleError {}
  39. class ProjectHistoryDisabledError extends BackwardCompatibleError {}
  40. class V1ConnectionError extends BackwardCompatibleError {}
  41. class UnconfirmedEmailError extends BackwardCompatibleError {}
  42. class EmailExistsError extends OErrorV2CompatibleError {
  43. constructor(options) {
  44. super('Email already exists', options)
  45. }
  46. }
  47. class InvalidError extends BackwardCompatibleError {}
  48. class NotInV2Error extends BackwardCompatibleError {}
  49. class SLInV2Error extends BackwardCompatibleError {}
  50. class SAMLIdentityExistsError extends OError {
  51. get i18nKey() {
  52. return 'institution_account_tried_to_add_already_registered'
  53. }
  54. }
  55. class SAMLAlreadyLinkedError extends OError {
  56. get i18nKey() {
  57. return 'institution_account_tried_to_add_already_linked'
  58. }
  59. }
  60. class SAMLEmailNotAffiliatedError extends OError {
  61. get i18nKey() {
  62. return 'institution_account_tried_to_add_not_affiliated'
  63. }
  64. }
  65. class SAMLEmailAffiliatedWithAnotherInstitutionError extends OError {
  66. get i18nKey() {
  67. return 'institution_account_tried_to_add_affiliated_with_another_institution'
  68. }
  69. }
  70. class SAMLSessionDataMissing extends BackwardCompatibleError {
  71. constructor(arg) {
  72. super(arg)
  73. const samlSession =
  74. typeof arg === 'object' && arg !== null && arg.samlSession
  75. ? arg.samlSession
  76. : {}
  77. this.tryAgain = true
  78. const { universityId, universityName, externalUserId, institutionEmail } =
  79. samlSession
  80. if (
  81. !universityId &&
  82. !universityName &&
  83. !externalUserId &&
  84. !institutionEmail
  85. ) {
  86. this.message = 'Missing session data.'
  87. } else if (
  88. !institutionEmail &&
  89. samlSession &&
  90. samlSession.userEmailAttributeUnreliable
  91. ) {
  92. this.tryAgain = false
  93. this.message = `Your account settings at your institution prevent us from accessing your email address. You will need to make your email address public at your institution in order to link with ${settings.appName}. Please contact your IT department if you have any questions.`
  94. } else if (!institutionEmail) {
  95. this.message =
  96. 'Unable to confirm your institutional email address. The institutional identity provider did not provide an email address in the expected attribute. Please contact us if this keeps happening.'
  97. }
  98. }
  99. }
  100. class ThirdPartyIdentityExistsError extends BackwardCompatibleError {
  101. constructor(arg) {
  102. super(arg)
  103. if (!this.message) {
  104. this.message =
  105. 'provider and external id already linked to another account'
  106. }
  107. }
  108. }
  109. class ThirdPartyUserNotFoundError extends BackwardCompatibleError {
  110. constructor(arg) {
  111. super(arg)
  112. if (!this.message) {
  113. this.message = 'user not found for provider and external id'
  114. }
  115. }
  116. }
  117. class SubscriptionAdminDeletionError extends OErrorV2CompatibleError {
  118. constructor(options) {
  119. super('subscription admins cannot be deleted', options)
  120. }
  121. }
  122. class ProjectNotFoundError extends OErrorV2CompatibleError {
  123. constructor(options) {
  124. super('project not found', options)
  125. }
  126. }
  127. class UserNotFoundError extends OErrorV2CompatibleError {
  128. constructor(options) {
  129. super('user not found', options)
  130. }
  131. }
  132. class UserNotCollaboratorError extends OErrorV2CompatibleError {
  133. constructor(options) {
  134. super('user not a collaborator', options)
  135. }
  136. }
  137. class DocHasRangesError extends OErrorV2CompatibleError {
  138. constructor(options) {
  139. super('document has ranges', options)
  140. }
  141. }
  142. class InvalidQueryError extends OErrorV2CompatibleError {
  143. constructor(options) {
  144. super('invalid search query', options)
  145. }
  146. }
  147. class AffiliationError extends OError {}
  148. class InvalidInstitutionalEmailError extends OError {
  149. get i18nKey() {
  150. return 'invalid_institutional_email'
  151. }
  152. }
  153. module.exports = {
  154. OError,
  155. BackwardCompatibleError,
  156. NotFoundError,
  157. ForbiddenError,
  158. ServiceNotConfiguredError,
  159. TooManyRequestsError,
  160. InvalidNameError,
  161. UnsupportedFileTypeError,
  162. FileTooLargeError,
  163. UnsupportedExportRecordsError,
  164. V1HistoryNotSyncedError,
  165. ProjectHistoryDisabledError,
  166. V1ConnectionError,
  167. UnconfirmedEmailError,
  168. EmailExistsError,
  169. InvalidError,
  170. NotInV2Error,
  171. SAMLIdentityExistsError,
  172. SAMLAlreadyLinkedError,
  173. SAMLEmailNotAffiliatedError,
  174. SAMLEmailAffiliatedWithAnotherInstitutionError,
  175. SAMLSessionDataMissing,
  176. SLInV2Error,
  177. ThirdPartyIdentityExistsError,
  178. ThirdPartyUserNotFoundError,
  179. SubscriptionAdminDeletionError,
  180. ProjectNotFoundError,
  181. UserNotFoundError,
  182. UserNotCollaboratorError,
  183. DocHasRangesError,
  184. InvalidQueryError,
  185. AffiliationError,
  186. InvalidInstitutionalEmailError,
  187. }