UserPagesController.js 6.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205
  1. const UserGetter = require('./UserGetter')
  2. const UserSessionsManager = require('./UserSessionsManager')
  3. const ErrorController = require('../Errors/ErrorController')
  4. const logger = require('logger-sharelatex')
  5. const Settings = require('settings-sharelatex')
  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. new_email: req.query.new_email || ''
  23. })
  24. },
  25. activateAccountPage(req, res, next) {
  26. // An 'activation' is actually just a password reset on an account that
  27. // was set with a random password originally.
  28. logger.log({ query: req.query }, 'activiate account page called')
  29. if (req.query.user_id == null || req.query.token == null) {
  30. return ErrorController.notFound(req, res)
  31. }
  32. UserGetter.getUser(
  33. req.query.user_id,
  34. { email: 1, loginCount: 1 },
  35. (error, user) => {
  36. if (error != null) {
  37. return next(error)
  38. }
  39. if (!user) {
  40. return ErrorController.notFound(req, res)
  41. }
  42. if (user.loginCount > 0) {
  43. logger.log(
  44. { user },
  45. 'user has already logged in so is active, sending them to /login'
  46. )
  47. // Already seen this user, so account must be activate
  48. // This lets users keep clicking the 'activate' link in their email
  49. // as a way to log in which, if I know our users, they will.
  50. res.redirect(`/login?email=${encodeURIComponent(user.email)}`)
  51. } else {
  52. res.render('user/activate', {
  53. title: 'activate_account',
  54. email: user.email,
  55. token: req.query.token
  56. })
  57. }
  58. }
  59. )
  60. },
  61. loginPage(req, res) {
  62. // if user is being sent to /login with explicit redirect (redir=/foo),
  63. // such as being sent from the editor to /login, then set the redirect explicitly
  64. if (
  65. req.query.redir != null &&
  66. AuthenticationController._getRedirectFromSession(req) == null
  67. ) {
  68. logger.log(
  69. { redir: req.query.redir },
  70. 'setting explicit redirect from login page'
  71. )
  72. AuthenticationController.setRedirectInSession(req, req.query.redir)
  73. }
  74. res.render('user/login', {
  75. title: 'login',
  76. email: req.query.email
  77. })
  78. },
  79. /**
  80. * Landing page for users who may have received one-time login
  81. * tokens from the read-only maintenance site.
  82. *
  83. * We tell them that Overleaf is back up and that they can login normally.
  84. */
  85. oneTimeLoginPage(req, res, next) {
  86. res.render('user/one_time_login')
  87. },
  88. logoutPage(req, res) {
  89. res.render('user/logout')
  90. },
  91. renderReconfirmAccountPage(req, res) {
  92. const pageData = {
  93. reconfirm_email: req.session.reconfirm_email
  94. }
  95. // when a user must reconfirm their account
  96. res.render('user/reconfirm', pageData)
  97. },
  98. settingsPage(req, res, next) {
  99. const userId = AuthenticationController.getLoggedInUserId(req)
  100. // SSO
  101. const ssoError = req.session.ssoError
  102. if (ssoError) {
  103. delete req.session.ssoError
  104. }
  105. // Institution SSO
  106. const institutionLinked = _.get(req.session, ['saml', 'linked'])
  107. const institutionNotLinked = _.get(req.session, ['saml', 'notLinked'])
  108. delete req.session.saml
  109. logger.log({ user: userId }, 'loading settings page')
  110. let shouldAllowEditingDetails = true
  111. if (Settings.ldap && Settings.ldap.updateUserDetailsOnLogin) {
  112. shouldAllowEditingDetails = false
  113. }
  114. if (Settings.saml && Settings.saml.updateUserDetailsOnLogin) {
  115. shouldAllowEditingDetails = false
  116. }
  117. const oauthProviders = Settings.oauthProviders || {}
  118. UserGetter.getUser(userId, (err, user) => {
  119. if (err != null) {
  120. return next(err)
  121. }
  122. res.render('user/settings', {
  123. title: 'account_settings',
  124. user,
  125. hasPassword: !!user.hashedPassword,
  126. shouldAllowEditingDetails,
  127. languages: Settings.languages,
  128. accountSettingsTabActive: true,
  129. oauthProviders: UserPagesController._translateProviderDescriptions(
  130. oauthProviders,
  131. req
  132. ),
  133. oauthUseV2: Settings.oauthUseV2 || false,
  134. samlInitPath: _.get(Settings, ['saml', 'ukamf', 'initPath']),
  135. institutionLinked,
  136. institutionNotLinked,
  137. ssoError: ssoError,
  138. thirdPartyIds: UserPagesController._restructureThirdPartyIds(user)
  139. })
  140. })
  141. },
  142. sessionsPage(req, res, next) {
  143. const user = AuthenticationController.getSessionUser(req)
  144. logger.log({ userId: user._id }, 'loading sessions page')
  145. UserSessionsManager.getAllUserSessions(
  146. user,
  147. [req.sessionID],
  148. (err, sessions) => {
  149. if (err != null) {
  150. logger.warn({ userId: user._id }, 'error getting all user sessions')
  151. return next(err)
  152. }
  153. res.render('user/sessions', {
  154. title: 'sessions',
  155. sessions
  156. })
  157. }
  158. )
  159. },
  160. _restructureThirdPartyIds(user) {
  161. // 3rd party identifiers are an array of objects
  162. // this turn them into a single object, which
  163. // makes data easier to use in template
  164. if (
  165. !user.thirdPartyIdentifiers ||
  166. user.thirdPartyIdentifiers.length === 0
  167. ) {
  168. return null
  169. }
  170. return user.thirdPartyIdentifiers.reduce((obj, identifier) => {
  171. obj[identifier.providerId] = identifier.externalUserId
  172. return obj
  173. }, {})
  174. },
  175. _translateProviderDescriptions(providers, req) {
  176. const result = {}
  177. if (providers) {
  178. for (let provider in providers) {
  179. const data = providers[provider]
  180. data.description = req.i18n.translate(
  181. data.descriptionKey,
  182. data.descriptionOptions
  183. )
  184. result[provider] = data
  185. }
  186. }
  187. return result
  188. }
  189. }
  190. module.exports = UserPagesController