Errors.js 5.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227
  1. const OError = require('@overleaf/o-error')
  2. const settings = require('settings-sharelatex')
  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 {
  79. universityId,
  80. universityName,
  81. externalUserId,
  82. institutionEmail,
  83. } = samlSession
  84. if (
  85. !universityId &&
  86. !universityName &&
  87. !externalUserId &&
  88. !institutionEmail
  89. ) {
  90. this.message = 'Missing session data.'
  91. } else if (
  92. !institutionEmail &&
  93. samlSession &&
  94. samlSession.userEmailAttributeUnreliable
  95. ) {
  96. this.tryAgain = false
  97. 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.`
  98. } else if (!institutionEmail) {
  99. this.message =
  100. '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.'
  101. }
  102. }
  103. }
  104. class ThirdPartyIdentityExistsError extends BackwardCompatibleError {
  105. constructor(arg) {
  106. super(arg)
  107. if (!this.message) {
  108. this.message =
  109. 'provider and external id already linked to another account'
  110. }
  111. }
  112. }
  113. class ThirdPartyUserNotFoundError extends BackwardCompatibleError {
  114. constructor(arg) {
  115. super(arg)
  116. if (!this.message) {
  117. this.message = 'user not found for provider and external id'
  118. }
  119. }
  120. }
  121. class SubscriptionAdminDeletionError extends OErrorV2CompatibleError {
  122. constructor(options) {
  123. super('subscription admins cannot be deleted', options)
  124. }
  125. }
  126. class ProjectNotFoundError extends OErrorV2CompatibleError {
  127. constructor(options) {
  128. super('project not found', options)
  129. }
  130. }
  131. class UserNotFoundError extends OErrorV2CompatibleError {
  132. constructor(options) {
  133. super('user not found', options)
  134. }
  135. }
  136. class UserNotCollaboratorError extends OErrorV2CompatibleError {
  137. constructor(options) {
  138. super('user not a collaborator', options)
  139. }
  140. }
  141. class DocHasRangesError extends OErrorV2CompatibleError {
  142. constructor(options) {
  143. super('document has ranges', options)
  144. }
  145. }
  146. class InvalidQueryError extends OErrorV2CompatibleError {
  147. constructor(options) {
  148. super('invalid search query', options)
  149. }
  150. }
  151. class AffiliationError extends OError {}
  152. class InvalidInstitutionalEmailError extends OError {
  153. get i18nKey() {
  154. return 'invalid_institutional_email'
  155. }
  156. }
  157. module.exports = {
  158. OError,
  159. BackwardCompatibleError,
  160. NotFoundError,
  161. ForbiddenError,
  162. ServiceNotConfiguredError,
  163. TooManyRequestsError,
  164. InvalidNameError,
  165. UnsupportedFileTypeError,
  166. FileTooLargeError,
  167. UnsupportedExportRecordsError,
  168. V1HistoryNotSyncedError,
  169. ProjectHistoryDisabledError,
  170. V1ConnectionError,
  171. UnconfirmedEmailError,
  172. EmailExistsError,
  173. InvalidError,
  174. NotInV2Error,
  175. SAMLIdentityExistsError,
  176. SAMLAlreadyLinkedError,
  177. SAMLEmailNotAffiliatedError,
  178. SAMLEmailAffiliatedWithAnotherInstitutionError,
  179. SAMLSessionDataMissing,
  180. SLInV2Error,
  181. ThirdPartyIdentityExistsError,
  182. ThirdPartyUserNotFoundError,
  183. SubscriptionAdminDeletionError,
  184. ProjectNotFoundError,
  185. UserNotFoundError,
  186. UserNotCollaboratorError,
  187. DocHasRangesError,
  188. InvalidQueryError,
  189. AffiliationError,
  190. InvalidInstitutionalEmailError,
  191. }