import _ from 'lodash' /* eslint-disable max-len, no-return-assign, no-useless-escape, */ import App from '../../../base' import getMeta from '../../../utils/meta' export default App.controller( 'UserAffiliationsController', function ($scope, $rootScope, UserAffiliationsDataService, $q, $window) { $scope.userEmails = [] $scope.linkedInstitutionIds = [] $scope.hideInstitutionNotifications = {} $scope.closeInstitutionNotification = type => { $scope.hideInstitutionNotifications[type] = true } $scope.samlBetaSession = ExposedSettings.hasSamlBeta $scope.samlInitPath = ExposedSettings.samlInitPath $scope.reconfirmationRemoveEmail = getMeta('ol-reconfirmationRemoveEmail') $scope.reconfirmedViaSAML = getMeta('ol-reconfirmedViaSAML') $scope.showInstitutionalLeaversSurvey = false $scope.dismissInstitutionalLeaversSurvey = () => { try { localStorage.setItem('hideInstitutionalLeaversSurvey', true) } catch (e) {} $scope.showInstitutionalLeaversSurvey = false } function maybeShowInstitutionalLeaversSurvey() { if (localStorage.getItem('hideInstitutionalLeaversSurvey')) return if ( localStorage.getItem('showInstitutionalLeaversSurveyUntil') > Date.now() ) { $scope.showInstitutionalLeaversSurvey = true } } maybeShowInstitutionalLeaversSurvey() const ONE_WEEK_IN_MS = 7 * 24 * 60 * 60 * 1000 const LOCAL_AND_DOMAIN_REGEX = /([^@]+)@(.+)/ 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,}))$/ const _matchLocalAndDomain = function (userEmailInput) { const match = userEmailInput ? userEmailInput.match(LOCAL_AND_DOMAIN_REGEX) : undefined if (match) { return { local: match[1], domain: match[2] } } else { return { local: null, domain: null } } } const _ssoAvailableForAffiliation = affiliation => { if (!affiliation) return false const institution = affiliation.institution if (!_ssoAvailableForInstitution(institution)) return false if (!institution.confirmed) return false // domain is confirmed, not the email return true } const _ssoAvailableForDomain = domain => { if (!domain) return false if (!domain.confirmed) return false // domain is confirmed, not the email const institution = domain.university if (!_ssoAvailableForInstitution(institution)) return false return true } const _ssoAvailableForInstitution = institution => { if (!ExposedSettings.hasSamlFeature) return false if (!institution) return false if (institution.ssoEnabled) return true if ($scope.samlBetaSession && institution.ssoBeta) return true return false } $scope.getEmailSuggestion = function (userInput) { const userInputLocalAndDomain = _matchLocalAndDomain(userInput) $scope.ui.isValidEmail = EMAIL_REGEX.test(userInput) $scope.ui.isBlacklistedEmail = false $scope.ui.showManualUniversitySelectionUI = false if (userInputLocalAndDomain.domain) { $scope.ui.isBlacklistedEmail = UserAffiliationsDataService.isDomainBlacklisted( userInputLocalAndDomain.domain ) return UserAffiliationsDataService.getUniversityDomainFromPartialDomainInput( userInputLocalAndDomain.domain ) .then(function (universityDomain) { const currentUserInputLocalAndDomain = _matchLocalAndDomain( $scope.newAffiliation.email ) if ( currentUserInputLocalAndDomain.domain === universityDomain.hostname ) { $scope.newAffiliation.university = universityDomain.university $scope.newAffiliation.department = universityDomain.department $scope.newAffiliation.ssoAvailable = _ssoAvailableForDomain(universityDomain) } else { _resetAffiliationSuggestion() } return $q.resolve( `${userInputLocalAndDomain.local}@${universityDomain.hostname}` ) }) .catch(function () { _resetAffiliationSuggestion() return $q.reject(null) }) } else { _resetAffiliationSuggestion() return $q.reject(null) } } $scope.linkInstitutionAcct = function (email, institutionId) { _resetMakingRequestType() $scope.ui.isMakingRequest = true $scope.ui.isProcessing = true $window.location.href = `${$scope.samlInitPath}?university_id=${institutionId}&auto=/user/settings&email=${email}` } $scope.selectUniversityManually = function () { _resetAffiliationSuggestion() $scope.ui.showManualUniversitySelectionUI = true } $scope.changeAffiliation = function (userEmail) { if (_.get(userEmail, ['affiliation', 'institution', 'id'])) { UserAffiliationsDataService.getUniversityDetails( userEmail.affiliation.institution.id ).then( universityDetails => ($scope.affiliationToChange.university = universityDetails) ) } $scope.affiliationToChange.email = userEmail.email $scope.affiliationToChange.role = userEmail.affiliation.role $scope.affiliationToChange.department = userEmail.affiliation.department } $scope.saveAffiliationChange = function (userEmail) { userEmail.affiliation.role = $scope.affiliationToChange.role userEmail.affiliation.department = $scope.affiliationToChange.department _resetAffiliationToChange() return _monitorRequest( UserAffiliationsDataService.addRoleAndDepartment( userEmail.email, userEmail.affiliation.role, userEmail.affiliation.department ) ).then(() => setTimeout(() => _getUserEmails())) } $scope.cancelAffiliationChange = email => _resetAffiliationToChange() $scope.isChangingAffiliation = email => $scope.affiliationToChange.email === email $scope.showAddEmailForm = () => ($scope.ui.showAddEmailUI = true) $scope.addNewEmail = function () { let addEmailPromise if (!$scope.newAffiliation.university) { addEmailPromise = UserAffiliationsDataService.addUserEmail( $scope.newAffiliation.email ) } else { if ($scope.newAffiliation.university.isUserSuggested) { addEmailPromise = UserAffiliationsDataService.addUserAffiliationWithUnknownUniversity( $scope.newAffiliation.email, $scope.newAffiliation.university.name, $scope.newAffiliation.country.code, $scope.newAffiliation.role, $scope.newAffiliation.department ) } else { addEmailPromise = UserAffiliationsDataService.addUserAffiliation( $scope.newAffiliation.email, $scope.newAffiliation.university.id, $scope.newAffiliation.role, $scope.newAffiliation.department ) } } $scope.ui.isAddingNewEmail = true $scope.ui.showAddEmailUI = false return _monitorRequest(addEmailPromise) .then(function () { _resetNewAffiliation() _resetAddingEmail() setTimeout(() => _getUserEmails()) }) .finally(() => ($scope.ui.isAddingNewEmail = false)) } $scope.setDefaultUserEmail = userEmail => _monitorRequest( UserAffiliationsDataService.setDefaultUserEmail(userEmail.email) ).then(function () { for (const email of $scope.userEmails || []) { email.default = false } userEmail.default = true window.usersEmail = userEmail.email $rootScope.usersEmail = userEmail.email }) $scope.removeUserEmail = function (userEmail) { $scope.userEmails = $scope.userEmails.filter(ue => ue !== userEmail) return _monitorRequest( UserAffiliationsDataService.removeUserEmail(userEmail.email) ) .then(() => { if ( userEmail.emailHasInstitutionLicence || (userEmail.affiliation && userEmail.affiliation.pastReconfirmDate) ) { const stillHasLicenseAccess = $scope.userEmails.some( ue => ue.emailHasInstitutionLicence ) if (!stillHasLicenseAccess) { try { localStorage.setItem( 'showInstitutionalLeaversSurveyUntil', Date.now() + ONE_WEEK_IN_MS ) maybeShowInstitutionalLeaversSurvey() } catch (e) {} } } }) .catch(() => { $scope.userEmails.push(userEmail) }) } $scope.resendConfirmationEmail = function (userEmail) { _resetMakingRequestType() $scope.ui.isResendingConfirmation = true return _monitorRequest( UserAffiliationsDataService.resendConfirmationEmail(userEmail.email) ).finally(() => ($scope.ui.isResendingConfirmation = false)) } $scope.acknowledgeError = function () { _reset() return _getUserEmails() } const _resetAffiliationToChange = () => ($scope.affiliationToChange = { email: '', university: null, role: null, department: null, }) const _resetNewAffiliation = () => ($scope.newAffiliation = { email: '', country: null, university: null, role: null, department: null, }) function _resetAddingEmail() { $scope.ui.showAddEmailUI = false $scope.ui.isValidEmail = false $scope.ui.isBlacklistedEmail = false $scope.ui.showManualUniversitySelectionUI = false } const _resetAffiliationSuggestion = () => { $scope.newAffiliation = { email: $scope.newAffiliation.email, } } function _resetMakingRequestType() { $scope.ui.isLoadingEmails = false $scope.ui.isProcessing = false $scope.ui.isResendingConfirmation = false } function _reset() { $scope.ui = { hasError: false, errorMessage: '', showChangeAffiliationUI: false, isMakingRequest: false, isLoadingEmails: false, isAddingNewEmail: false, } _resetAffiliationToChange() _resetNewAffiliation() return _resetAddingEmail() } _reset() $scope.ui.showAddEmailUI = window.location.hash === '#add-email' function _monitorRequest(promise) { $scope.ui.hasError = false $scope.ui.isMakingRequest = true promise .catch(function (response) { $scope.ui.hasError = true $scope.ui.errorMessage = _.get(response, ['data', 'message']) }) .finally(() => ($scope.ui.isMakingRequest = false)) return promise } $scope.inReconfirmNotificationPeriod = function (emailData) { return _.get(emailData, ['affiliation', 'inReconfirmNotificationPeriod']) } $scope.institutionAlreadyLinked = function (emailData) { const institutionId = emailData.affiliation && emailData.affiliation.institution && emailData.affiliation.institution && emailData.affiliation.institution.id ? emailData.affiliation.institution.id.toString() : undefined return $scope.linkedInstitutionIds.indexOf(institutionId) !== -1 } // Populates the emails table function _getUserEmails() { _resetMakingRequestType() $scope.ui.isLoadingEmails = true _monitorRequest( UserAffiliationsDataService.getUserEmailsEnsureAffiliation() ) .then(emails => { $scope.userEmails = emails.map(email => { email.ssoAvailable = _ssoAvailableForAffiliation(email.affiliation) return email }) $scope.linkedInstitutionIds = emails .filter(email => { return !!email.samlProviderId }) .map(email => email.samlProviderId) }) .finally(() => ($scope.ui.isLoadingEmails = false)) } _getUserEmails() } )