Kaynağa Gözat

Merge pull request #2663 from overleaf/jel-sso-missing-email-error

Institution SSO error handling when missing session data

GitOrigin-RevId: c455ef97eb17b98ffbd03eb5f623ceb27678deed
Jessica Lawshe 6 yıl önce
ebeveyn
işleme
30763043d1

+ 32 - 3
services/web/app/src/Features/Errors/Errors.js

@@ -1,4 +1,5 @@
 const OError = require('@overleaf/o-error')
+const settings = require('settings-sharelatex')
 
 // Error class for legacy errors so they inherit OError while staying
 // backward-compatible (can be instantiated with string as argument instead
@@ -67,9 +68,37 @@ class SAMLIdentityExistsError extends BackwardCompatibleError {
 class SAMLSessionDataMissing extends BackwardCompatibleError {
   constructor(arg) {
     super(arg)
-    if (!this.message) {
-      this.message =
-        'Please resubmit your institutional email.<br/><a href="/institutional-login">institutional login</a>'
+
+    const samlSession =
+      typeof arg === 'object' && arg !== null && arg.samlSession
+        ? arg.samlSession
+        : {}
+    this.tryAgain = true
+    const institutionsWithoutEmail = settings.samlInstitutionsWithoutEmail || []
+    const {
+      universityId,
+      universityName,
+      externalUserId,
+      institutionEmail
+    } = samlSession
+
+    if (
+      !universityId &&
+      !universityName &&
+      !externalUserId &&
+      !institutionEmail
+    ) {
+      this.message = 'Missing session data.'
+    } else if (
+      !institutionEmail &&
+      institutionsWithoutEmail.includes(samlSession.universityId)
+    ) {
+      this.tryAgain = false
+      this.message = `Your account settings at your institution prevent us from accessing your email. You will need to make your email public at your institution in order to link with ${
+        settings.appName
+      }. Please contact your IT department if you have any questions.`
+    } else if (!institutionEmail) {
+      this.message = 'Unable to confirm your institution email.'
     }
   }
 }

+ 12 - 0
services/web/app/src/Features/Project/ProjectController.js

@@ -354,6 +354,7 @@ const ProjectController = {
     const userId = AuthenticationController.getLoggedInUserId(req)
     const currentUser = AuthenticationController.getSessionUser(req)
     let noV1Connection = false
+    let institutionLinkingError
     async.parallel(
       {
         tags(cb) {
@@ -515,6 +516,16 @@ const ProjectController = {
                 templateKey: 'notification_institution_sso_linked_by_another'
               })
             }
+
+            // Notification: When there is a session error
+            if (samlSession.error) {
+              institutionLinkingError = samlSession.error
+              notificationsInstitution.push({
+                message: samlSession.error.message,
+                templateKey: 'notification_institution_sso_error',
+                tryAgain: samlSession.error.tryAgain
+              })
+            }
           }
           delete req.session.saml
         }
@@ -551,6 +562,7 @@ const ProjectController = {
             user,
             userAffiliations,
             hasSubscription: results.hasSubscription,
+            institutionLinkingError,
             isShowingV1Projects:
               results.v1Projects != null &&
               results.v1Projects.projects.length > 0,

+ 2 - 0
services/web/app/src/Features/User/UserPagesController.js

@@ -127,6 +127,7 @@ const UserPagesController = {
       'saml',
       'requestedEmail'
     ])
+    const institutionLinkingError = _.get(req.session, ['saml', 'error'])
     delete req.session.saml
     let shouldAllowEditingDetails = true
     if (Settings.ldap && Settings.ldap.updateUserDetailsOnLogin) {
@@ -159,6 +160,7 @@ const UserPagesController = {
           institutionEmailNonCanonical && institutionRequestedEmail
             ? institutionEmailNonCanonical
             : undefined,
+        institutionLinkingError,
         samlBeta: req.session.samlBeta,
         ssoError: ssoError,
         thirdPartyIds: UserPagesController._restructureThirdPartyIds(user)

+ 9 - 0
services/web/app/views/_mixins/saml.pug

@@ -0,0 +1,9 @@
+mixin samlErrorLoggedIn(error)
+	i.fa.fa-exclamation-triangle(aria-hidden="true")
+	| &nbsp;#{translate("generic_something_went_wrong")}.
+	if error.message
+		br
+		| &nbsp;#{institutionLinkingError.message}
+	if error.tryAgain
+		br
+		| &nbsp;#{translate("try_again")}.

+ 12 - 0
services/web/app/views/project/list/notifications.pug

@@ -1,3 +1,5 @@
+include ../../_mixins/saml
+
 .user-notifications(ng-controller="NotificationsController")
 	ul.list-unstyled(
 		ng-if="notifications.length > 0 && projects.length > 0",
@@ -148,6 +150,16 @@
 							span(aria-hidden="true") &times;
 							span.sr-only #{translate("close")}
 
+				if institutionLinkingError
+					.alert.alert-danger(ng-switch-when="notification_institution_sso_error")
+						.notification-body
+							div
+								+samlErrorLoggedIn(institutionLinkingError)
+						.notification-close
+							button(ng-click="dismiss(notification)").close.pull-right
+								span(aria-hidden="true") &times;
+								span.sr-only #{translate("close")}
+
 	ul.list-unstyled(
 		ng-controller="EmailNotificationController",
 		ng-cloak

+ 14 - 0
services/web/app/views/user/settings/user-affiliations.pug

@@ -1,3 +1,5 @@
+include ../../_mixins/saml
+
 mixin aboutInstitutionLink()
 	a(href="/learn/how-to/Institutional_Login") #{translate("find_out_more_about_institution_login")}.
 
@@ -267,6 +269,18 @@ form.row(
 								i.fa.fa-exclamation-triangle(aria-hidden="true")
 								| &nbsp;
 								| !{translate("institution_account_tried_to_add_already_registered")}
+				if institutionLinkingError
+					tr.affiliations-table-error-row(ng-if="!hideInstitutionNotifications.linkError")
+						td.text-center(aria-live="assertive" colspan="3")
+							button.close(
+								type="button"
+								data-dismiss="modal"
+								ng-click="closeInstitutionNotification('linkError')"
+								aria-label=translate("close")
+							)
+								span(aria-hidden="true") &times;
+							.small
+								+samlErrorLoggedIn(institutionLinkingError)
 		hr
 
 script(type="text/ng-template", id="affiliationFormTpl")

+ 3 - 0
services/web/frontend/stylesheets/components/alerts.less

@@ -30,6 +30,9 @@
   > p + p {
     margin-top: 5px;
   }
+  p:last-child {
+    margin-bottom: 0;
+  }
 }
 
 // Dismissable alerts