Explorar el Código

Merge pull request #3609 from overleaf/jel-admin-user-affiliations

Add confirmation/reconfirmation to admin user affiliation tab

GitOrigin-RevId: d1e065c5e4d6d97814327742db2c4b131d4f0195
Jessica Lawshe hace 5 años
padre
commit
ac99738495

+ 25 - 10
services/web/app/src/Features/User/UserGetter.js

@@ -13,14 +13,15 @@ const Errors = require('../Errors/Errors')
 const Features = require('../../infrastructure/Features')
 const { normalizeQuery, normalizeMultiQuery } = require('../Helpers/Mongo')
 
-function _emailInReconfirmNotificationPeriod(emailData, institutionData) {
+function _lastDayToReconfirm(emailData, institutionData) {
   const globalReconfirmPeriod = settings.reconfirmNotificationDays
-  if (!globalReconfirmPeriod) return false
+  if (!globalReconfirmPeriod) return undefined
 
   // only show notification for institutions with reconfirmation enabled
-  if (!institutionData || !institutionData.maxConfirmationMonths) return false
+  if (!institutionData || !institutionData.maxConfirmationMonths)
+    return undefined
 
-  if (!emailData.confirmedAt) return false
+  if (!emailData.confirmedAt) return undefined
 
   if (institutionData.ssoEnabled && !emailData.samlProviderId) {
     // For SSO, only show notification for linked email
@@ -30,10 +31,21 @@ function _emailInReconfirmNotificationPeriod(emailData, institutionData) {
   // reconfirmedAt will not always be set, use confirmedAt as fallback
   const lastConfirmed = emailData.reconfirmedAt || emailData.confirmedAt
 
-  const lastDayToReconfirm = moment(lastConfirmed).add(
-    institutionData.maxConfirmationMonths,
-    'months'
-  )
+  return moment(lastConfirmed)
+    .add(institutionData.maxConfirmationMonths, 'months')
+    .toDate()
+}
+
+function _pastReconfirmDate(lastDayToReconfirm) {
+  if (!lastDayToReconfirm) return false
+  return moment(lastDayToReconfirm).isBefore()
+}
+
+function _emailInReconfirmNotificationPeriod(lastDayToReconfirm) {
+  const globalReconfirmPeriod = settings.reconfirmNotificationDays
+
+  if (!globalReconfirmPeriod || !lastDayToReconfirm) return false
+
   const notificationStarts = moment(lastDayToReconfirm).subtract(
     globalReconfirmPeriod,
     'days'
@@ -202,14 +214,17 @@ var decorateFullEmails = (
         licence,
         portal
       } = affiliation
+      const lastDayToReconfirm = _lastDayToReconfirm(emailData, institution)
+      const pastReconfirmDate = _pastReconfirmDate(lastDayToReconfirm)
       const inReconfirmNotificationPeriod = _emailInReconfirmNotificationPeriod(
-        emailData,
-        institution
+        lastDayToReconfirm
       )
       emailData.affiliation = {
         institution,
         inferred,
         inReconfirmNotificationPeriod,
+        lastDayToReconfirm,
+        pastReconfirmDate,
         role,
         department,
         licence,

+ 16 - 0
services/web/frontend/js/filters/formatDate.js

@@ -31,6 +31,22 @@ App.filter(
     }
 )
 
+App.filter(
+  'utcDate',
+  () =>
+    function(date, format) {
+      if (!date) return 'N/A'
+      if (format == null) {
+        format = 'D MMM YYYY, HH:mm:ss'
+      }
+      return (
+        moment(date)
+          .utc()
+          .format(format) + ' UTC'
+      )
+    }
+)
+
 App.filter('relativeDate', () => date => moment(date).calendar())
 
 App.filter('fromNowDate', () => date => moment(date).fromNow())

+ 4 - 0
services/web/frontend/stylesheets/core/type.less

@@ -389,3 +389,7 @@ address {
   font-style: normal;
   line-height: @line-height-base;
 }
+
+.orange-text {
+  color: @orange-dark;
+}

+ 1 - 0
services/web/frontend/stylesheets/core/variables.less

@@ -33,6 +33,7 @@
 @red: #a93529;
 @yellow: #a1a729;
 @orange: #f89406;
+@orange-dark: #9e5e04;
 @pink: #c3325f;
 @purple: #7a43b6;
 

+ 2 - 0
services/web/test/acceptance/src/SubscriptionDashboardTests.js

@@ -521,6 +521,8 @@ describe('Subscriptions', function() {
               name: 'Stanford',
               confirmed: true
             },
+            lastDayToReconfirm: undefined,
+            pastReconfirmDate: false,
             portal: undefined
           }
         ])

+ 18 - 4
services/web/test/acceptance/src/UserEmailsTests.js

@@ -998,6 +998,14 @@ describe('UserEmails', function() {
   describe('notification period', function() {
     let defaultEmail, userHelper, email1, email2, email3
     const maxConfirmationMonths = 12
+    const lastDayToReconfirm = moment()
+      .subtract(maxConfirmationMonths, 'months')
+      .toDate()
+    const oneDayBeforeLastDayToReconfirm = moment(lastDayToReconfirm)
+      .add(1, 'day')
+      .toDate()
+    const daysToBackdate = moment().diff(oneDayBeforeLastDayToReconfirm, 'day')
+    const daysToBackdateForAfterDate = daysToBackdate + 1
 
     beforeEach(async function() {
       if (!Features.hasFeature('affiliations')) {
@@ -1026,14 +1034,17 @@ describe('UserEmails', function() {
       beforeEach(async function() {
         // create a user with 3 affiliations at the institution.
         // all are within in the notification period
-        const backdatedDays = maxConfirmationMonths * 2 * 30
         const userId = userHelper.user._id
         await userHelper.addEmailAndConfirm(userId, email1)
         await userHelper.addEmailAndConfirm(userId, email2)
         await userHelper.addEmailAndConfirm(userId, email3)
-        await userHelper.backdateConfirmation(userId, email1, backdatedDays)
-        await userHelper.backdateConfirmation(userId, email2, backdatedDays)
-        await userHelper.backdateConfirmation(userId, email3, backdatedDays)
+        await userHelper.backdateConfirmation(userId, email1, daysToBackdate)
+        await userHelper.backdateConfirmation(userId, email2, daysToBackdate)
+        await userHelper.backdateConfirmation(
+          userId,
+          email3,
+          daysToBackdateForAfterDate
+        )
       })
 
       it('should flag inReconfirmNotificationPeriod for all affiliations in period', async function() {
@@ -1045,12 +1056,15 @@ describe('UserEmails', function() {
         expect(
           fullEmails[1].affiliation.inReconfirmNotificationPeriod
         ).to.equal(true)
+        expect(fullEmails[1].affiliation.pastReconfirmDate).to.equal(false)
         expect(
           fullEmails[2].affiliation.inReconfirmNotificationPeriod
         ).to.equal(true)
+        expect(fullEmails[2].affiliation.pastReconfirmDate).to.equal(false)
         expect(
           fullEmails[3].affiliation.inReconfirmNotificationPeriod
         ).to.equal(true)
+        expect(fullEmails[3].affiliation.pastReconfirmDate).to.equal(true)
       })
 
       describe('should flag emails before their confirmation expires, but within the notification period', function() {

+ 2 - 0
services/web/test/unit/src/User/UserGetterTests.js

@@ -195,8 +195,10 @@ describe('UserGetter', function() {
                 inferred: affiliationsData[0].inferred,
                 department: affiliationsData[0].department,
                 role: affiliationsData[0].role,
+                lastDayToReconfirm: undefined,
                 licence: affiliationsData[0].licence,
                 inReconfirmNotificationPeriod: false,
+                pastReconfirmDate: false,
                 portal: undefined
               }
             },