Errors.js 10 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396
  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. /**
  8. * @param {string | { message: string, info?: Object }} messageOrOptions
  9. */
  10. constructor(messageOrOptions) {
  11. if (typeof messageOrOptions === 'string') {
  12. super(messageOrOptions)
  13. } else if (messageOrOptions) {
  14. const { message, info } = messageOrOptions
  15. super(message, info)
  16. } else {
  17. super()
  18. }
  19. }
  20. }
  21. // Error class that facilitates the migration to OError v3 by providing
  22. // a signature in which the 2nd argument can be an object containing
  23. // the `info` object.
  24. class OErrorV2CompatibleError extends OError {
  25. constructor(message, options) {
  26. if (options) {
  27. super(message, options.info)
  28. } else {
  29. super(message)
  30. }
  31. }
  32. }
  33. class NotFoundError extends BackwardCompatibleError {}
  34. class ForbiddenError extends BackwardCompatibleError {}
  35. class ServiceNotConfiguredError extends BackwardCompatibleError {}
  36. class TooManyRequestsError extends BackwardCompatibleError {}
  37. class ResourceGoneError extends BackwardCompatibleError {}
  38. class DuplicateNameError extends OError {}
  39. class InvalidNameError extends BackwardCompatibleError {}
  40. class IndeterminateInvoiceError extends OError {}
  41. class UnsupportedFileTypeError extends BackwardCompatibleError {}
  42. class FileTooLargeError extends BackwardCompatibleError {}
  43. class UnsupportedExportRecordsError extends BackwardCompatibleError {}
  44. class V1HistoryNotSyncedError extends BackwardCompatibleError {}
  45. class ProjectHistoryDisabledError extends BackwardCompatibleError {}
  46. class V1ConnectionError extends BackwardCompatibleError {}
  47. class UnconfirmedEmailError extends BackwardCompatibleError {}
  48. class EmailExistsError extends OErrorV2CompatibleError {
  49. constructor(options) {
  50. super('Email already exists', options)
  51. }
  52. }
  53. class InvalidError extends BackwardCompatibleError {}
  54. class NotInV2Error extends BackwardCompatibleError {}
  55. class SLInV2Error extends BackwardCompatibleError {}
  56. class SAMLCommonsUnavailable extends OError {
  57. get i18nKey() {
  58. return 'saml_commons_unavailable'
  59. }
  60. }
  61. class SAMLIdentityExistsError extends OError {
  62. get i18nKey() {
  63. return 'institution_account_tried_to_add_already_registered'
  64. }
  65. }
  66. class SAMLAlreadyLinkedError extends OError {
  67. get i18nKey() {
  68. return 'institution_account_tried_to_add_already_linked'
  69. }
  70. }
  71. class SAMLEmailNotAffiliatedError extends OError {
  72. get i18nKey() {
  73. return 'institution_account_tried_to_add_not_affiliated_2'
  74. }
  75. }
  76. class SAMLEmailAffiliatedWithAnotherInstitutionError extends OError {
  77. get i18nKey() {
  78. return 'institution_account_tried_to_add_affiliated_with_another_institution_2'
  79. }
  80. }
  81. class SAMLAuthenticationError extends OError {
  82. get i18nKey() {
  83. return 'saml_auth_error'
  84. }
  85. }
  86. class SAMLAssertionAudienceMismatch extends SAMLAuthenticationError {}
  87. class SAMLAuthenticationRequiredError extends SAMLAuthenticationError {
  88. get i18nKey() {
  89. return 'saml_authentication_required_error'
  90. }
  91. }
  92. class SAMLGroupSSOLoginIdentityMismatchError extends SAMLAuthenticationError {
  93. get i18nKey() {
  94. return 'saml_login_identity_mismatch_error'
  95. }
  96. }
  97. class SAMLGroupSSOLoginIdentityNotFoundError extends SAMLAuthenticationError {
  98. get i18nKey() {
  99. return 'saml_login_identity_not_found_error'
  100. }
  101. }
  102. class SAMLGroupSSODisabledError extends SAMLAuthenticationError {
  103. get i18nKey() {
  104. return 'saml_login_disabled_error'
  105. }
  106. }
  107. class SAMLInvalidSignatureError extends SAMLAuthenticationError {
  108. get i18nKey() {
  109. return 'saml_invalid_signature_error'
  110. }
  111. }
  112. class SAMLMissingSignatureError extends SAMLAuthenticationError {
  113. get i18nKey() {
  114. return 'saml_missing_signature_error'
  115. }
  116. }
  117. class SAMLInvalidUserIdentifierError extends SAMLAuthenticationError {
  118. get i18nKey() {
  119. return 'saml_authentication_required_error'
  120. }
  121. }
  122. class SAMLInvalidUserAttributeError extends SAMLAuthenticationError {
  123. get i18nKey() {
  124. return 'saml_authentication_required_error'
  125. }
  126. }
  127. class SAMLMissingUserIdentifierError extends SAMLAuthenticationError {
  128. get i18nKey() {
  129. return 'saml_missing_user_attribute'
  130. }
  131. }
  132. class SAMLInvalidResponseError extends SAMLAuthenticationError {}
  133. class SAMLResponseAlreadyProcessedError extends SAMLInvalidResponseError {
  134. constructor() {
  135. super('saml response already processed')
  136. }
  137. }
  138. class SAMLLoginFailureError extends SAMLAuthenticationError {
  139. get i18nKey() {
  140. return 'saml_login_failure'
  141. }
  142. }
  143. class SAMLEmailNotRecognizedError extends SAMLAuthenticationError {
  144. get i18nKey() {
  145. return 'saml_email_not_recognized'
  146. }
  147. }
  148. class SAMLDomainCaptureRegisterError extends SAMLAuthenticationError {}
  149. class SAMLRequestDeniedError extends SAMLAuthenticationError {
  150. get i18nKey() {
  151. return 'saml_request_denied_error'
  152. }
  153. }
  154. class SAMLSessionDataMissing extends BackwardCompatibleError {
  155. constructor(arg) {
  156. super(arg)
  157. const samlSession =
  158. typeof arg === 'object' && arg !== null && arg.samlSession
  159. ? arg.samlSession
  160. : {}
  161. this.tryAgain = true
  162. const { universityId, universityName, externalUserId, institutionEmail } =
  163. samlSession
  164. if (
  165. !universityId &&
  166. !universityName &&
  167. !externalUserId &&
  168. !institutionEmail
  169. ) {
  170. this.message = 'Missing session data.'
  171. } else if (
  172. !institutionEmail &&
  173. samlSession &&
  174. samlSession.userEmailAttributeUnreliable
  175. ) {
  176. this.tryAgain = false
  177. 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.`
  178. } else if (!institutionEmail) {
  179. this.message =
  180. '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.'
  181. }
  182. }
  183. }
  184. class SAMLProviderRequesterError extends SAMLAuthenticationError {}
  185. class SAMLProviderRequesterInvalidNameIDPolicyError extends SAMLProviderRequesterError {
  186. get i18nKey() {
  187. return 'sso_provider_error_invalid_name'
  188. }
  189. }
  190. class ThirdPartyIdentityExistsError extends BackwardCompatibleError {
  191. constructor(arg) {
  192. super(arg)
  193. if (!this.message) {
  194. this.message =
  195. 'provider and external id already linked to another account'
  196. }
  197. }
  198. }
  199. class ThirdPartyUserNotFoundError extends BackwardCompatibleError {
  200. constructor(arg) {
  201. super(arg)
  202. if (!this.message) {
  203. this.message = 'user not found for provider and external id'
  204. }
  205. }
  206. }
  207. class OutputFileFetchFailedError extends OError {}
  208. class SubscriptionAdminDeletionError extends OErrorV2CompatibleError {
  209. constructor(options) {
  210. super('subscription admins cannot be deleted', options)
  211. }
  212. }
  213. class SubscriptionNotFoundError extends OErrorV2CompatibleError {
  214. constructor(options) {
  215. super('subscription not found', options)
  216. }
  217. }
  218. class ProjectNotFoundError extends OErrorV2CompatibleError {
  219. constructor(options) {
  220. super('project not found', options)
  221. }
  222. }
  223. class UserNotFoundError extends OErrorV2CompatibleError {
  224. constructor(options) {
  225. super('user not found', options)
  226. }
  227. }
  228. class UserNotCollaboratorError extends OErrorV2CompatibleError {
  229. constructor(options) {
  230. super('user not a collaborator', options)
  231. }
  232. }
  233. class DocHasRangesError extends OErrorV2CompatibleError {
  234. constructor(options) {
  235. super('document has ranges', options)
  236. }
  237. }
  238. class InvalidQueryError extends OErrorV2CompatibleError {
  239. constructor(options) {
  240. super('invalid search query', options)
  241. }
  242. }
  243. class AffiliationError extends OError {}
  244. class InvalidEmailError extends OError {
  245. get i18nKey() {
  246. return 'invalid_email'
  247. }
  248. }
  249. class InvalidInstitutionalEmailError extends OError {
  250. get i18nKey() {
  251. return 'invalid_institutional_email'
  252. }
  253. }
  254. class NonDeletableEntityError extends OError {
  255. get i18nKey() {
  256. return 'non_deletable_entity'
  257. }
  258. }
  259. class FoundConnectedClientsError extends OError {
  260. constructor(nConnectedClients) {
  261. super(`found ${nConnectedClients} remaining connected clients`)
  262. }
  263. }
  264. class ConcurrentLoadingOfDocsDetectedError extends OError {
  265. constructor() {
  266. super('concurrent loading of docs detected')
  267. }
  268. }
  269. module.exports = {
  270. OError,
  271. BackwardCompatibleError,
  272. NotFoundError,
  273. ForbiddenError,
  274. ServiceNotConfiguredError,
  275. TooManyRequestsError,
  276. ResourceGoneError,
  277. DuplicateNameError,
  278. InvalidNameError,
  279. UnsupportedFileTypeError,
  280. FileTooLargeError,
  281. UnsupportedExportRecordsError,
  282. V1HistoryNotSyncedError,
  283. ProjectHistoryDisabledError,
  284. V1ConnectionError,
  285. UnconfirmedEmailError,
  286. EmailExistsError,
  287. InvalidError,
  288. IndeterminateInvoiceError,
  289. NotInV2Error,
  290. OutputFileFetchFailedError,
  291. SAMLAssertionAudienceMismatch,
  292. SAMLAuthenticationRequiredError,
  293. SAMLCommonsUnavailable,
  294. SAMLIdentityExistsError,
  295. SAMLAlreadyLinkedError,
  296. SAMLEmailNotAffiliatedError,
  297. SAMLEmailAffiliatedWithAnotherInstitutionError,
  298. SAMLSessionDataMissing,
  299. SAMLAuthenticationError,
  300. SAMLGroupSSOLoginIdentityMismatchError,
  301. SAMLGroupSSOLoginIdentityNotFoundError,
  302. SAMLGroupSSODisabledError,
  303. SAMLInvalidUserAttributeError,
  304. SAMLInvalidUserIdentifierError,
  305. SAMLInvalidSignatureError,
  306. SAMLMissingUserIdentifierError,
  307. SAMLMissingSignatureError,
  308. SAMLProviderRequesterError,
  309. SAMLProviderRequesterInvalidNameIDPolicyError,
  310. SAMLInvalidResponseError,
  311. SAMLLoginFailureError,
  312. SAMLEmailNotRecognizedError,
  313. SAMLResponseAlreadyProcessedError,
  314. SAMLRequestDeniedError,
  315. SAMLDomainCaptureRegisterError,
  316. SLInV2Error,
  317. ThirdPartyIdentityExistsError,
  318. ThirdPartyUserNotFoundError,
  319. SubscriptionAdminDeletionError,
  320. SubscriptionNotFoundError,
  321. ProjectNotFoundError,
  322. UserNotFoundError,
  323. UserNotCollaboratorError,
  324. DocHasRangesError,
  325. InvalidQueryError,
  326. AffiliationError,
  327. InvalidEmailError,
  328. InvalidInstitutionalEmailError,
  329. NonDeletableEntityError,
  330. FoundConnectedClientsError,
  331. ConcurrentLoadingOfDocsDetectedError,
  332. }