UserAffiliationsController.js 9.9 KB

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