TeamInvitesController.js 4.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167
  1. const settings = require('@overleaf/settings')
  2. const TeamInvitesHandler = require('./TeamInvitesHandler')
  3. const SessionManager = require('../Authentication/SessionManager')
  4. const SubscriptionLocator = require('./SubscriptionLocator')
  5. const ErrorController = require('../Errors/ErrorController')
  6. const EmailHelper = require('../Helpers/EmailHelper')
  7. const UserGetter = require('../User/UserGetter')
  8. const { expressify } = require('../../util/promises')
  9. const HttpErrorHandler = require('../Errors/HttpErrorHandler')
  10. const PermissionsManager = require('../Authorization/PermissionsManager')
  11. function createInvite(req, res, next) {
  12. const teamManagerId = SessionManager.getLoggedInUserId(req.session)
  13. const subscription = req.entity
  14. const email = EmailHelper.parseEmail(req.body.email)
  15. if (!email) {
  16. return res.status(422).json({
  17. error: {
  18. code: 'invalid_email',
  19. message: req.i18n.translate('invalid_email'),
  20. },
  21. })
  22. }
  23. TeamInvitesHandler.createInvite(
  24. teamManagerId,
  25. subscription,
  26. email,
  27. function (err, inviteUserData) {
  28. if (err) {
  29. if (err.alreadyInTeam) {
  30. return res.status(400).json({
  31. error: {
  32. code: 'user_already_added',
  33. message: req.i18n.translate('user_already_added'),
  34. },
  35. })
  36. }
  37. if (err.limitReached) {
  38. return res.status(400).json({
  39. error: {
  40. code: 'group_full',
  41. message: req.i18n.translate('group_full'),
  42. },
  43. })
  44. }
  45. return next(err)
  46. }
  47. res.json({ user: inviteUserData })
  48. }
  49. )
  50. }
  51. async function viewInvite(req, res, next) {
  52. const { token } = req.params
  53. const userId = SessionManager.getLoggedInUserId(req.session)
  54. const { invite, subscription } = await TeamInvitesHandler.promises.getInvite(
  55. token
  56. )
  57. if (!invite) {
  58. return ErrorController.notFound(req, res)
  59. }
  60. let validationStatus = new Map()
  61. if (userId) {
  62. const personalSubscription =
  63. await SubscriptionLocator.promises.getUsersSubscription(userId)
  64. const hasIndividualRecurlySubscription =
  65. personalSubscription &&
  66. personalSubscription.groupPlan === false &&
  67. personalSubscription.recurlyStatus?.state !== 'canceled' &&
  68. personalSubscription.recurlySubscription_id &&
  69. personalSubscription.recurlySubscription_id !== ''
  70. if (subscription?.groupPolicy) {
  71. if (!subscription.populated('groupPolicy')) {
  72. await subscription.populate('groupPolicy')
  73. }
  74. const user = await UserGetter.promises.getUser(userId)
  75. if (
  76. user.enrollment?.managedBy &&
  77. user.enrollment?.managedBy.toString() !== subscription._id.toString()
  78. ) {
  79. return HttpErrorHandler.forbidden(
  80. req,
  81. res,
  82. 'User is already managed by a different subscription'
  83. )
  84. }
  85. validationStatus =
  86. await PermissionsManager.promises.getUserValidationStatus({
  87. user,
  88. groupPolicy: subscription.groupPolicy,
  89. subscription,
  90. })
  91. return res.render('subscriptions/team/invite-managed', {
  92. inviterName: invite.inviterName,
  93. inviteToken: invite.token,
  94. expired: req.query.expired,
  95. validationStatus: Object.fromEntries(validationStatus),
  96. })
  97. } else {
  98. return res.render('subscriptions/team/invite', {
  99. inviterName: invite.inviterName,
  100. inviteToken: invite.token,
  101. hasIndividualRecurlySubscription,
  102. appName: settings.appName,
  103. expired: req.query.expired,
  104. userRestrictions: Array.from(req.userRestrictions || []),
  105. })
  106. }
  107. } else {
  108. const userByEmail = await UserGetter.promises.getUserByMainEmail(
  109. invite.email
  110. )
  111. return res.render('subscriptions/team/invite_logged_out', {
  112. inviterName: invite.inviterName,
  113. inviteToken: invite.token,
  114. appName: settings.appName,
  115. accountExists: userByEmail != null,
  116. emailAddress: invite.email,
  117. })
  118. }
  119. }
  120. async function acceptInvite(req, res, next) {
  121. const { token } = req.params
  122. const userId = SessionManager.getLoggedInUserId(req.session)
  123. await TeamInvitesHandler.promises.acceptInvite(token, userId)
  124. res.sendStatus(204)
  125. }
  126. function revokeInvite(req, res, next) {
  127. const subscription = req.entity
  128. const email = EmailHelper.parseEmail(req.params.email)
  129. const teamManagerId = SessionManager.getLoggedInUserId(req.session)
  130. if (!email) {
  131. return res.sendStatus(400)
  132. }
  133. TeamInvitesHandler.revokeInvite(
  134. teamManagerId,
  135. subscription,
  136. email,
  137. function (err, results) {
  138. if (err) {
  139. return next(err)
  140. }
  141. res.sendStatus(204)
  142. }
  143. )
  144. }
  145. module.exports = {
  146. createInvite,
  147. viewInvite: expressify(viewInvite),
  148. acceptInvite: expressify(acceptInvite),
  149. revokeInvite,
  150. }