|
@@ -1,4 +1,4 @@
|
|
|
-import { useState, useEffect, useLayoutEffect } from 'react'
|
|
|
|
|
|
|
+import { useState } from 'react'
|
|
|
import { UserEmailData } from '../../../../../../types/user-email'
|
|
import { UserEmailData } from '../../../../../../types/user-email'
|
|
|
import getMeta from '../../../../utils/meta'
|
|
import getMeta from '../../../../utils/meta'
|
|
|
import ReconfirmationInfoSuccess from './reconfirmation-info/reconfirmation-info-success'
|
|
import ReconfirmationInfoSuccess from './reconfirmation-info/reconfirmation-info-success'
|
|
@@ -7,14 +7,11 @@ import OLRow from '@/features/ui/components/ol/ol-row'
|
|
|
import OLCol from '@/features/ui/components/ol/ol-col'
|
|
import OLCol from '@/features/ui/components/ol/ol-col'
|
|
|
import OLNotification from '@/features/ui/components/ol/ol-notification'
|
|
import OLNotification from '@/features/ui/components/ol/ol-notification'
|
|
|
import { useUserEmailsContext } from '@/features/settings/context/user-email-context'
|
|
import { useUserEmailsContext } from '@/features/settings/context/user-email-context'
|
|
|
-import { FetchError, postJSON } from '@/infrastructure/fetch-json'
|
|
|
|
|
-import { debugConsole } from '@/utils/debugging'
|
|
|
|
|
import { ssoAvailableForInstitution } from '@/features/settings/utils/sso'
|
|
import { ssoAvailableForInstitution } from '@/features/settings/utils/sso'
|
|
|
-import { Trans, useTranslation } from 'react-i18next'
|
|
|
|
|
-import useAsync from '@/shared/hooks/use-async'
|
|
|
|
|
|
|
+import { useTranslation } from 'react-i18next'
|
|
|
import { useLocation } from '@/shared/hooks/use-location'
|
|
import { useLocation } from '@/shared/hooks/use-location'
|
|
|
import OLButton from '@/features/ui/components/ol/ol-button'
|
|
import OLButton from '@/features/ui/components/ol/ol-button'
|
|
|
-import LoadingSpinner from '@/shared/components/loading-spinner'
|
|
|
|
|
|
|
+import ResendConfirmationCodeModal from '@/features/settings/components/emails/resend-confirmation-code-modal'
|
|
|
|
|
|
|
|
type ReconfirmationInfoProps = {
|
|
type ReconfirmationInfoProps = {
|
|
|
userEmailData: UserEmailData
|
|
userEmailData: UserEmailData
|
|
@@ -22,50 +19,21 @@ type ReconfirmationInfoProps = {
|
|
|
|
|
|
|
|
function ReconfirmationInfo({ userEmailData }: ReconfirmationInfoProps) {
|
|
function ReconfirmationInfo({ userEmailData }: ReconfirmationInfoProps) {
|
|
|
const reconfirmedViaSAML = getMeta('ol-reconfirmedViaSAML')
|
|
const reconfirmedViaSAML = getMeta('ol-reconfirmedViaSAML')
|
|
|
-
|
|
|
|
|
|
|
+ const affiliation = userEmailData.affiliation
|
|
|
const { t } = useTranslation()
|
|
const { t } = useTranslation()
|
|
|
const { samlInitPath } = getMeta('ol-ExposedSettings')
|
|
const { samlInitPath } = getMeta('ol-ExposedSettings')
|
|
|
- const { error, isLoading, isError, isSuccess, runAsync } = useAsync()
|
|
|
|
|
- const { state, setLoading: setUserEmailsContextLoading } =
|
|
|
|
|
- useUserEmailsContext()
|
|
|
|
|
- const [hasSent, setHasSent] = useState(false)
|
|
|
|
|
|
|
+ const {
|
|
|
|
|
+ state,
|
|
|
|
|
+ setLoading: setUserEmailsContextLoading,
|
|
|
|
|
+ getEmails,
|
|
|
|
|
+ } = useUserEmailsContext()
|
|
|
const [isPending, setIsPending] = useState(false)
|
|
const [isPending, setIsPending] = useState(false)
|
|
|
const location = useLocation()
|
|
const location = useLocation()
|
|
|
const ssoAvailable = Boolean(
|
|
const ssoAvailable = Boolean(
|
|
|
- ssoAvailableForInstitution(userEmailData.affiliation?.institution ?? null)
|
|
|
|
|
|
|
+ ssoAvailableForInstitution(affiliation?.institution ?? null)
|
|
|
)
|
|
)
|
|
|
|
|
|
|
|
- const handleRequestReconfirmation = () => {
|
|
|
|
|
- if (userEmailData.affiliation?.institution && ssoAvailable) {
|
|
|
|
|
- setIsPending(true)
|
|
|
|
|
- location.assign(
|
|
|
|
|
- `${samlInitPath}?university_id=${userEmailData.affiliation.institution.id}&reconfirm=/user/settings`
|
|
|
|
|
- )
|
|
|
|
|
- } else {
|
|
|
|
|
- runAsync(
|
|
|
|
|
- postJSON('/user/emails/send-reconfirmation', {
|
|
|
|
|
- body: {
|
|
|
|
|
- email: userEmailData.email,
|
|
|
|
|
- },
|
|
|
|
|
- })
|
|
|
|
|
- ).catch(debugConsole.error)
|
|
|
|
|
- }
|
|
|
|
|
- }
|
|
|
|
|
-
|
|
|
|
|
- useEffect(() => {
|
|
|
|
|
- setUserEmailsContextLoading(isLoading)
|
|
|
|
|
- }, [setUserEmailsContextLoading, isLoading])
|
|
|
|
|
-
|
|
|
|
|
- useLayoutEffect(() => {
|
|
|
|
|
- if (isSuccess) {
|
|
|
|
|
- setHasSent(true)
|
|
|
|
|
- }
|
|
|
|
|
- }, [isSuccess])
|
|
|
|
|
-
|
|
|
|
|
- const rateLimited =
|
|
|
|
|
- isError && error instanceof FetchError && error.response?.status === 429
|
|
|
|
|
-
|
|
|
|
|
- if (!userEmailData.affiliation) {
|
|
|
|
|
|
|
+ if (!affiliation) {
|
|
|
return null
|
|
return null
|
|
|
}
|
|
}
|
|
|
|
|
|
|
@@ -80,7 +48,7 @@ function ReconfirmationInfo({ userEmailData }: ReconfirmationInfoProps) {
|
|
|
type="info"
|
|
type="info"
|
|
|
content={
|
|
content={
|
|
|
<ReconfirmationInfoSuccess
|
|
<ReconfirmationInfoSuccess
|
|
|
- institution={userEmailData.affiliation.institution}
|
|
|
|
|
|
|
+ institution={affiliation.institution}
|
|
|
/>
|
|
/>
|
|
|
}
|
|
}
|
|
|
/>
|
|
/>
|
|
@@ -89,86 +57,45 @@ function ReconfirmationInfo({ userEmailData }: ReconfirmationInfoProps) {
|
|
|
)
|
|
)
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
- if (userEmailData.affiliation.inReconfirmNotificationPeriod) {
|
|
|
|
|
- return (
|
|
|
|
|
- <OLRow>
|
|
|
|
|
- <OLCol lg={12}>
|
|
|
|
|
- <OLNotification
|
|
|
|
|
- type="info"
|
|
|
|
|
- content={
|
|
|
|
|
- <>
|
|
|
|
|
- {hasSent ? (
|
|
|
|
|
- <Trans
|
|
|
|
|
- i18nKey="please_check_your_inbox_to_confirm"
|
|
|
|
|
- values={{
|
|
|
|
|
- institutionName:
|
|
|
|
|
- userEmailData.affiliation.institution.name,
|
|
|
|
|
- }}
|
|
|
|
|
- shouldUnescape
|
|
|
|
|
- tOptions={{ interpolation: { escapeValue: true } }}
|
|
|
|
|
- components={
|
|
|
|
|
- /* eslint-disable-next-line jsx-a11y/anchor-has-content, react/jsx-key */
|
|
|
|
|
- [<strong />]
|
|
|
|
|
- }
|
|
|
|
|
- />
|
|
|
|
|
- ) : (
|
|
|
|
|
- <ReconfirmationInfoPromptText
|
|
|
|
|
- institutionName={userEmailData.affiliation.institution.name}
|
|
|
|
|
- primary={userEmailData.default}
|
|
|
|
|
- />
|
|
|
|
|
- )}
|
|
|
|
|
- <br />
|
|
|
|
|
- {isError && (
|
|
|
|
|
- <div className="text-danger">
|
|
|
|
|
- {rateLimited
|
|
|
|
|
- ? t('too_many_requests')
|
|
|
|
|
- : t('generic_something_went_wrong')}
|
|
|
|
|
- </div>
|
|
|
|
|
- )}
|
|
|
|
|
- </>
|
|
|
|
|
- }
|
|
|
|
|
- action={
|
|
|
|
|
- hasSent ? (
|
|
|
|
|
- <>
|
|
|
|
|
- {isLoading ? (
|
|
|
|
|
- <>
|
|
|
|
|
- <LoadingSpinner loadingText={`${t('sending')}…`} />
|
|
|
|
|
- </>
|
|
|
|
|
- ) : (
|
|
|
|
|
- <OLButton
|
|
|
|
|
- variant="link"
|
|
|
|
|
- disabled={state.isLoading}
|
|
|
|
|
- onClick={handleRequestReconfirmation}
|
|
|
|
|
- className="btn-inline-link"
|
|
|
|
|
- >
|
|
|
|
|
- {t('resend_confirmation_email')}
|
|
|
|
|
- </OLButton>
|
|
|
|
|
- )}
|
|
|
|
|
- </>
|
|
|
|
|
- ) : (
|
|
|
|
|
- <OLButton
|
|
|
|
|
- variant="secondary"
|
|
|
|
|
- disabled={isPending}
|
|
|
|
|
- isLoading={isLoading}
|
|
|
|
|
- onClick={handleRequestReconfirmation}
|
|
|
|
|
- >
|
|
|
|
|
- {isLoading ? (
|
|
|
|
|
- <>
|
|
|
|
|
- <LoadingSpinner loadingText={`${t('sending')}…`} />
|
|
|
|
|
- </>
|
|
|
|
|
- ) : (
|
|
|
|
|
- t('confirm_affiliation')
|
|
|
|
|
- )}
|
|
|
|
|
- </OLButton>
|
|
|
|
|
- )
|
|
|
|
|
- }
|
|
|
|
|
- />
|
|
|
|
|
- </OLCol>
|
|
|
|
|
- </OLRow>
|
|
|
|
|
- )
|
|
|
|
|
|
|
+ if (!affiliation.inReconfirmNotificationPeriod) {
|
|
|
|
|
+ return null
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
- return null
|
|
|
|
|
|
|
+ return (
|
|
|
|
|
+ <OLNotification
|
|
|
|
|
+ type="info"
|
|
|
|
|
+ content={
|
|
|
|
|
+ <ReconfirmationInfoPromptText
|
|
|
|
|
+ institutionName={affiliation.institution.name}
|
|
|
|
|
+ primary={userEmailData.default}
|
|
|
|
|
+ />
|
|
|
|
|
+ }
|
|
|
|
|
+ action={
|
|
|
|
|
+ affiliation?.institution && ssoAvailable ? (
|
|
|
|
|
+ <OLButton
|
|
|
|
|
+ variant="secondary"
|
|
|
|
|
+ disabled={isPending}
|
|
|
|
|
+ onClick={() => {
|
|
|
|
|
+ setIsPending(true)
|
|
|
|
|
+ location.assign(
|
|
|
|
|
+ `${samlInitPath}?university_id=${affiliation.institution.id}&reconfirm=/user/settings`
|
|
|
|
|
+ )
|
|
|
|
|
+ }}
|
|
|
|
|
+ >
|
|
|
|
|
+ {t('confirm_affiliation')}
|
|
|
|
|
+ </OLButton>
|
|
|
|
|
+ ) : (
|
|
|
|
|
+ <ResendConfirmationCodeModal
|
|
|
|
|
+ email={userEmailData.email}
|
|
|
|
|
+ setGroupLoading={setUserEmailsContextLoading}
|
|
|
|
|
+ groupLoading={state.isLoading}
|
|
|
|
|
+ onSuccess={getEmails}
|
|
|
|
|
+ triggerVariant="secondary"
|
|
|
|
|
+ />
|
|
|
|
|
+ )
|
|
|
|
|
+ }
|
|
|
|
|
+ />
|
|
|
|
|
+ )
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
export default ReconfirmationInfo
|
|
export default ReconfirmationInfo
|