UserAffiliationsController.js 9.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316
  1. import _ from 'lodash'
  2. /* eslint-disable
  3. max-len,
  4. no-return-assign,
  5. no-useless-escape,
  6. */
  7. import App from '../../../base'
  8. export default App.controller('UserAffiliationsController', function(
  9. $scope,
  10. UserAffiliationsDataService,
  11. $q,
  12. $window
  13. ) {
  14. $scope.userEmails = []
  15. $scope.linkedInstitutionIds = []
  16. $scope.hideInstitutionNotifications = {}
  17. $scope.closeInstitutionNotification = type => {
  18. $scope.hideInstitutionNotifications[type] = true
  19. }
  20. $scope.samlBetaSession = ExposedSettings.hasSamlBeta
  21. $scope.samlInitPath = ExposedSettings.samlInitPath
  22. const LOCAL_AND_DOMAIN_REGEX = /([^@]+)@(.+)/
  23. const EMAIL_REGEX = /^(([^<>()[\]\\.,;:\s@\"]+(\.[^<>()[\]\\.,;:\s@\"]+)*)|(\ ".+\"))@((\[[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\])|(([a-zA -Z\-0-9]+\.)+[a-zA-Z]{2,}))$/
  24. const _matchLocalAndDomain = function(userEmailInput) {
  25. const match = userEmailInput
  26. ? userEmailInput.match(LOCAL_AND_DOMAIN_REGEX)
  27. : undefined
  28. if (match) {
  29. return { local: match[1], domain: match[2] }
  30. } else {
  31. return { local: null, domain: null }
  32. }
  33. }
  34. const _ssoAvailableForAffiliation = affiliation => {
  35. if (!affiliation) return false
  36. const institution = affiliation.institution
  37. if (!_ssoAvailableForInstitution(institution)) return false
  38. if (!institution.confirmed) return false // domain is confirmed, not the email
  39. return true
  40. }
  41. const _ssoAvailableForDomain = domain => {
  42. if (!domain) return false
  43. if (!domain.confirmed) return false // domain is confirmed, not the email
  44. const institution = domain.university
  45. if (!_ssoAvailableForInstitution(institution)) return false
  46. return true
  47. }
  48. const _ssoAvailableForInstitution = institution => {
  49. if (!ExposedSettings.hasSamlFeature) return false
  50. if (!institution) return false
  51. if (institution.ssoEnabled) return true
  52. if ($scope.samlBetaSession && institution.ssoBeta) return true
  53. return false
  54. }
  55. $scope.getEmailSuggestion = function(userInput) {
  56. const userInputLocalAndDomain = _matchLocalAndDomain(userInput)
  57. $scope.ui.isValidEmail = EMAIL_REGEX.test(userInput)
  58. $scope.ui.isBlacklistedEmail = false
  59. $scope.ui.showManualUniversitySelectionUI = false
  60. if (userInputLocalAndDomain.domain) {
  61. $scope.ui.isBlacklistedEmail = UserAffiliationsDataService.isDomainBlacklisted(
  62. userInputLocalAndDomain.domain
  63. )
  64. return UserAffiliationsDataService.getUniversityDomainFromPartialDomainInput(
  65. userInputLocalAndDomain.domain
  66. )
  67. .then(function(universityDomain) {
  68. const currentUserInputLocalAndDomain = _matchLocalAndDomain(
  69. $scope.newAffiliation.email
  70. )
  71. if (
  72. currentUserInputLocalAndDomain.domain === universityDomain.hostname
  73. ) {
  74. $scope.newAffiliation.university = universityDomain.university
  75. $scope.newAffiliation.department = universityDomain.department
  76. $scope.newAffiliation.ssoAvailable = _ssoAvailableForDomain(
  77. universityDomain
  78. )
  79. } else {
  80. _resetAffiliationSuggestion()
  81. }
  82. return $q.resolve(
  83. `${userInputLocalAndDomain.local}@${universityDomain.hostname}`
  84. )
  85. })
  86. .catch(function() {
  87. _resetAffiliationSuggestion()
  88. return $q.reject(null)
  89. })
  90. } else {
  91. _resetAffiliationSuggestion()
  92. return $q.reject(null)
  93. }
  94. }
  95. $scope.linkInstitutionAcct = function(email, institutionId) {
  96. _resetMakingRequestType()
  97. $scope.ui.isMakingRequest = true
  98. $scope.ui.isProcessing = true
  99. $window.location.href = `${
  100. $scope.samlInitPath
  101. }?university_id=${institutionId}&auto=/user/settings&email=${email}`
  102. }
  103. $scope.selectUniversityManually = function() {
  104. _resetAffiliationSuggestion()
  105. $scope.ui.showManualUniversitySelectionUI = true
  106. }
  107. $scope.changeAffiliation = function(userEmail) {
  108. if (_.get(userEmail, ['affiliation', 'institution', 'id'])) {
  109. UserAffiliationsDataService.getUniversityDetails(
  110. userEmail.affiliation.institution.id
  111. ).then(
  112. universityDetails =>
  113. ($scope.affiliationToChange.university = universityDetails)
  114. )
  115. }
  116. $scope.affiliationToChange.email = userEmail.email
  117. $scope.affiliationToChange.role = userEmail.affiliation.role
  118. $scope.affiliationToChange.department = userEmail.affiliation.department
  119. }
  120. $scope.saveAffiliationChange = function(userEmail) {
  121. userEmail.affiliation.role = $scope.affiliationToChange.role
  122. userEmail.affiliation.department = $scope.affiliationToChange.department
  123. _resetAffiliationToChange()
  124. return _monitorRequest(
  125. UserAffiliationsDataService.addRoleAndDepartment(
  126. userEmail.email,
  127. userEmail.affiliation.role,
  128. userEmail.affiliation.department
  129. )
  130. ).then(() => setTimeout(() => _getUserEmails()))
  131. }
  132. $scope.cancelAffiliationChange = email => _resetAffiliationToChange()
  133. $scope.isChangingAffiliation = email =>
  134. $scope.affiliationToChange.email === email
  135. $scope.showAddEmailForm = () => ($scope.ui.showAddEmailUI = true)
  136. $scope.addNewEmail = function() {
  137. let addEmailPromise
  138. if (!$scope.newAffiliation.university) {
  139. addEmailPromise = UserAffiliationsDataService.addUserEmail(
  140. $scope.newAffiliation.email
  141. )
  142. } else {
  143. if ($scope.newAffiliation.university.isUserSuggested) {
  144. addEmailPromise = UserAffiliationsDataService.addUserAffiliationWithUnknownUniversity(
  145. $scope.newAffiliation.email,
  146. $scope.newAffiliation.university.name,
  147. $scope.newAffiliation.country.code,
  148. $scope.newAffiliation.role,
  149. $scope.newAffiliation.department
  150. )
  151. } else {
  152. addEmailPromise = UserAffiliationsDataService.addUserAffiliation(
  153. $scope.newAffiliation.email,
  154. $scope.newAffiliation.university.id,
  155. $scope.newAffiliation.role,
  156. $scope.newAffiliation.department
  157. )
  158. }
  159. }
  160. $scope.ui.isAddingNewEmail = true
  161. $scope.ui.showAddEmailUI = false
  162. return _monitorRequest(addEmailPromise)
  163. .then(function() {
  164. _resetNewAffiliation()
  165. _resetAddingEmail()
  166. setTimeout(() => _getUserEmails())
  167. })
  168. .finally(() => ($scope.ui.isAddingNewEmail = false))
  169. }
  170. $scope.setDefaultUserEmail = userEmail =>
  171. _monitorRequest(
  172. UserAffiliationsDataService.setDefaultUserEmail(userEmail.email)
  173. ).then(function() {
  174. for (let email of $scope.userEmails || []) {
  175. email.default = false
  176. }
  177. userEmail.default = true
  178. })
  179. $scope.removeUserEmail = function(userEmail) {
  180. $scope.userEmails = $scope.userEmails.filter(ue => ue !== userEmail)
  181. return _monitorRequest(
  182. UserAffiliationsDataService.removeUserEmail(userEmail.email)
  183. )
  184. }
  185. $scope.resendConfirmationEmail = function(userEmail) {
  186. _resetMakingRequestType()
  187. $scope.ui.isResendingConfirmation = true
  188. return _monitorRequest(
  189. UserAffiliationsDataService.resendConfirmationEmail(userEmail.email)
  190. ).finally(() => ($scope.ui.isResendingConfirmation = false))
  191. }
  192. $scope.acknowledgeError = function() {
  193. _reset()
  194. return _getUserEmails()
  195. }
  196. var _resetAffiliationToChange = () =>
  197. ($scope.affiliationToChange = {
  198. email: '',
  199. university: null,
  200. role: null,
  201. department: null
  202. })
  203. var _resetNewAffiliation = () =>
  204. ($scope.newAffiliation = {
  205. email: '',
  206. country: null,
  207. university: null,
  208. role: null,
  209. department: null
  210. })
  211. var _resetAddingEmail = function() {
  212. $scope.ui.showAddEmailUI = false
  213. $scope.ui.isValidEmail = false
  214. $scope.ui.isBlacklistedEmail = false
  215. $scope.ui.showManualUniversitySelectionUI = false
  216. }
  217. var _resetAffiliationSuggestion = () => {
  218. $scope.newAffiliation = {
  219. email: $scope.newAffiliation.email
  220. }
  221. }
  222. var _resetMakingRequestType = function() {
  223. $scope.ui.isLoadingEmails = false
  224. $scope.ui.isProcessing = false
  225. $scope.ui.isResendingConfirmation = false
  226. }
  227. var _reset = function() {
  228. $scope.ui = {
  229. hasError: false,
  230. errorMessage: '',
  231. showChangeAffiliationUI: false,
  232. isMakingRequest: false,
  233. isLoadingEmails: false,
  234. isAddingNewEmail: false
  235. }
  236. _resetAffiliationToChange()
  237. _resetNewAffiliation()
  238. return _resetAddingEmail()
  239. }
  240. _reset()
  241. var _monitorRequest = function(promise) {
  242. $scope.ui.hasError = false
  243. $scope.ui.isMakingRequest = true
  244. promise
  245. .catch(function(response) {
  246. $scope.ui.hasError = true
  247. $scope.ui.errorMessage = _.get(response, ['data', 'message'])
  248. })
  249. .finally(() => ($scope.ui.isMakingRequest = false))
  250. return promise
  251. }
  252. $scope.institutionAlreadyLinked = function(emailData) {
  253. const institutionId =
  254. emailData.affiliation &&
  255. emailData.affiliation.institution &&
  256. emailData.affiliation.institution &&
  257. emailData.affiliation.institution.id
  258. ? emailData.affiliation.institution.id.toString()
  259. : undefined
  260. return $scope.linkedInstitutionIds.indexOf(institutionId) !== -1
  261. }
  262. // Populates the emails table
  263. var _getUserEmails = function() {
  264. _resetMakingRequestType()
  265. $scope.ui.isLoadingEmails = true
  266. _monitorRequest(
  267. UserAffiliationsDataService.getUserEmailsEnsureAffiliation()
  268. )
  269. .then(emails => {
  270. $scope.userEmails = emails.map(email => {
  271. email.ssoAvailable = _ssoAvailableForAffiliation(email.affiliation)
  272. return email
  273. })
  274. $scope.linkedInstitutionIds = emails
  275. .filter(email => {
  276. if (email.samlProviderId) {
  277. return email.samlProviderId
  278. }
  279. })
  280. .map(email => email.samlProviderId)
  281. })
  282. .finally(() => ($scope.ui.isLoadingEmails = false))
  283. }
  284. _getUserEmails()
  285. })