UserPagesController.js 5.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189
  1. const UserGetter = require('./UserGetter')
  2. const OError = require('@overleaf/o-error')
  3. const UserSessionsManager = require('./UserSessionsManager')
  4. const logger = require('logger-sharelatex')
  5. const Settings = require('@overleaf/settings')
  6. const AuthenticationController = require('../Authentication/AuthenticationController')
  7. const _ = require('lodash')
  8. const UserPagesController = {
  9. registerPage(req, res) {
  10. const sharedProjectData = {
  11. project_name: req.query.project_name,
  12. user_first_name: req.query.user_first_name,
  13. }
  14. const newTemplateData = {}
  15. if (req.session.templateData != null) {
  16. newTemplateData.templateName = req.session.templateData.templateName
  17. }
  18. res.render('user/register', {
  19. title: 'register',
  20. sharedProjectData,
  21. newTemplateData,
  22. samlBeta: req.session.samlBeta,
  23. })
  24. },
  25. loginPage(req, res) {
  26. // if user is being sent to /login with explicit redirect (redir=/foo),
  27. // such as being sent from the editor to /login, then set the redirect explicitly
  28. if (
  29. req.query.redir != null &&
  30. AuthenticationController._getRedirectFromSession(req) == null
  31. ) {
  32. AuthenticationController.setRedirectInSession(req, req.query.redir)
  33. }
  34. res.render('user/login', {
  35. title: 'login',
  36. })
  37. },
  38. /**
  39. * Landing page for users who may have received one-time login
  40. * tokens from the read-only maintenance site.
  41. *
  42. * We tell them that Overleaf is back up and that they can login normally.
  43. */
  44. oneTimeLoginPage(req, res, next) {
  45. res.render('user/one_time_login')
  46. },
  47. logoutPage(req, res) {
  48. res.render('user/logout')
  49. },
  50. renderReconfirmAccountPage(req, res) {
  51. const pageData = {
  52. reconfirm_email: req.session.reconfirm_email,
  53. }
  54. // when a user must reconfirm their account
  55. res.render('user/reconfirm', pageData)
  56. },
  57. settingsPage(req, res, next) {
  58. const userId = AuthenticationController.getLoggedInUserId(req)
  59. const reconfirmationRemoveEmail = req.query.remove
  60. // SSO
  61. const ssoError = req.session.ssoError
  62. if (ssoError) {
  63. delete req.session.ssoError
  64. }
  65. // Institution SSO
  66. let institutionLinked = _.get(req.session, ['saml', 'linked'])
  67. if (institutionLinked) {
  68. // copy object if exists because _.get does not
  69. institutionLinked = Object.assign(
  70. {
  71. hasEntitlement: _.get(req.session, ['saml', 'hasEntitlement']),
  72. },
  73. institutionLinked
  74. )
  75. }
  76. const samlError = _.get(req.session, ['saml', 'error'])
  77. const institutionEmailNonCanonical = _.get(req.session, [
  78. 'saml',
  79. 'emailNonCanonical',
  80. ])
  81. const institutionRequestedEmail = _.get(req.session, [
  82. 'saml',
  83. 'requestedEmail',
  84. ])
  85. const reconfirmedViaSAML = _.get(req.session, ['saml', 'reconfirmed'])
  86. delete req.session.saml
  87. let shouldAllowEditingDetails = true
  88. if (Settings.ldap && Settings.ldap.updateUserDetailsOnLogin) {
  89. shouldAllowEditingDetails = false
  90. }
  91. if (Settings.saml && Settings.saml.updateUserDetailsOnLogin) {
  92. shouldAllowEditingDetails = false
  93. }
  94. const oauthProviders = Settings.oauthProviders || {}
  95. UserGetter.getUser(userId, (err, user) => {
  96. if (err != null) {
  97. return next(err)
  98. }
  99. res.render('user/settings', {
  100. title: 'account_settings',
  101. user,
  102. hasPassword: !!user.hashedPassword,
  103. shouldAllowEditingDetails,
  104. languages: Settings.languages,
  105. accountSettingsTabActive: true,
  106. oauthProviders: UserPagesController._translateProviderDescriptions(
  107. oauthProviders,
  108. req
  109. ),
  110. oauthUseV2: Settings.oauthUseV2 || false,
  111. institutionLinked,
  112. samlError,
  113. institutionEmailNonCanonical:
  114. institutionEmailNonCanonical && institutionRequestedEmail
  115. ? institutionEmailNonCanonical
  116. : undefined,
  117. reconfirmedViaSAML,
  118. reconfirmationRemoveEmail,
  119. samlBeta: req.session.samlBeta,
  120. ssoError: ssoError,
  121. thirdPartyIds: UserPagesController._restructureThirdPartyIds(user),
  122. })
  123. })
  124. },
  125. sessionsPage(req, res, next) {
  126. const user = AuthenticationController.getSessionUser(req)
  127. logger.log({ userId: user._id }, 'loading sessions page')
  128. UserSessionsManager.getAllUserSessions(
  129. user,
  130. [req.sessionID],
  131. (err, sessions) => {
  132. if (err != null) {
  133. OError.tag(err, 'error getting all user sessions', {
  134. userId: user._id,
  135. })
  136. return next(err)
  137. }
  138. res.render('user/sessions', {
  139. title: 'sessions',
  140. sessions,
  141. })
  142. }
  143. )
  144. },
  145. _restructureThirdPartyIds(user) {
  146. // 3rd party identifiers are an array of objects
  147. // this turn them into a single object, which
  148. // makes data easier to use in template
  149. if (
  150. !user.thirdPartyIdentifiers ||
  151. user.thirdPartyIdentifiers.length === 0
  152. ) {
  153. return null
  154. }
  155. return user.thirdPartyIdentifiers.reduce((obj, identifier) => {
  156. obj[identifier.providerId] = identifier.externalUserId
  157. return obj
  158. }, {})
  159. },
  160. _translateProviderDescriptions(providers, req) {
  161. const result = {}
  162. if (providers) {
  163. for (const provider in providers) {
  164. const data = providers[provider]
  165. data.description = req.i18n.translate(
  166. data.descriptionKey,
  167. Object.assign({}, data.descriptionOptions)
  168. )
  169. result[provider] = data
  170. }
  171. }
  172. return result
  173. },
  174. }
  175. module.exports = UserPagesController