diff --git a/services/web/app/src/Features/Errors/Errors.js b/services/web/app/src/Features/Errors/Errors.js
index 11158ea6e7..83f26b17a8 100644
--- a/services/web/app/src/Features/Errors/Errors.js
+++ b/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.
institutional login'
+
+ 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.'
}
}
}
diff --git a/services/web/app/src/Features/Project/ProjectController.js b/services/web/app/src/Features/Project/ProjectController.js
index f717ade836..b32a1f03ca 100644
--- a/services/web/app/src/Features/Project/ProjectController.js
+++ b/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,
diff --git a/services/web/app/src/Features/User/UserPagesController.js b/services/web/app/src/Features/User/UserPagesController.js
index a23f2e7227..23ef4cec65 100644
--- a/services/web/app/src/Features/User/UserPagesController.js
+++ b/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)
diff --git a/services/web/app/views/_mixins/saml.pug b/services/web/app/views/_mixins/saml.pug
new file mode 100644
index 0000000000..f87a3a8b61
--- /dev/null
+++ b/services/web/app/views/_mixins/saml.pug
@@ -0,0 +1,9 @@
+mixin samlErrorLoggedIn(error)
+ i.fa.fa-exclamation-triangle(aria-hidden="true")
+ | #{translate("generic_something_went_wrong")}.
+ if error.message
+ br
+ | #{institutionLinkingError.message}
+ if error.tryAgain
+ br
+ | #{translate("try_again")}.
diff --git a/services/web/app/views/project/list/notifications.pug b/services/web/app/views/project/list/notifications.pug
index 19446e602a..ea2a98e46d 100644
--- a/services/web/app/views/project/list/notifications.pug
+++ b/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") ×
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") ×
+ span.sr-only #{translate("close")}
+
ul.list-unstyled(
ng-controller="EmailNotificationController",
ng-cloak
diff --git a/services/web/app/views/user/settings/user-affiliations.pug b/services/web/app/views/user/settings/user-affiliations.pug
index 7815dcf6a0..58efc748e2 100644
--- a/services/web/app/views/user/settings/user-affiliations.pug
+++ b/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")
|
| !{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") ×
+ .small
+ +samlErrorLoggedIn(institutionLinkingError)
hr
script(type="text/ng-template", id="affiliationFormTpl")
diff --git a/services/web/frontend/stylesheets/components/alerts.less b/services/web/frontend/stylesheets/components/alerts.less
index 31bea4f4ae..e11d8906ae 100755
--- a/services/web/frontend/stylesheets/components/alerts.less
+++ b/services/web/frontend/stylesheets/components/alerts.less
@@ -30,6 +30,9 @@
> p + p {
margin-top: 5px;
}
+ p:last-child {
+ margin-bottom: 0;
+ }
}
// Dismissable alerts