All files / pages/auth login.js

31.25% Statements 15/48
3.44% Branches 1/29
40% Functions 2/5
29.78% Lines 14/47

Press n or j to go to the next uncovered block, b, p or k for the previous block.

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 1511x 1x 1x 1x 1x 1x 1x           1x 1x   1x 1x     1x 1x                                                                                           1x                                                                                                                                                                        
import { useEffect } from 'react'
import { useRouter } from 'next/router'
import { signIn } from 'next-auth/react'
import LoadingSpinner from '../../components/LoadingSpinner'
import MetaData from '../../components/MetaData'
import { authOptions } from '../../pages/api/auth/[...nextauth]'
import { getServerSession } from 'next-auth/next'
import {
  AuthIsDisabled,
  AuthIsValid,
  ValidateSession,
  getIdToken,
} from '../../lib/auth'
import querystring from 'querystring'
 
export default function Login(props) {
  const router = useRouter()
 
  //signIn('ecasProvider')
  useEffect(() => {
    if (!router.isReady) return
    Iif (!router.query.error) {
      //If auth is disabled, redirect to dashboard without triggering signIn event, for testing purposes only
      Iif (props.authDisabled) {
        setTimeout(() => {
          props.locale === 'en'
            ? router.push('/en/my-dashboard')
            : router.push('/fr/mon-tableau-de-bord')
        }, 3000)
        return
      }
 
      const redirectLang = props.locale === 'en' ? 'eng' : 'fra'
      const params = new URLSearchParams(props.redirectQueryString)
      Iif (!params.has('Lang')) {
        params.append('Lang', redirectLang)
      }
      const curamRedirect =
        props.ecasUrl + props.curamRedirect + params.toString()
      const redirectTarget = props.redirectQueryString
        ? curamRedirect
        : props.locale === 'en'
          ? `${window.location.origin}/api/welcome?locale=en`
          : `${window.location.origin}/api/welcome?locale=fr`
 
      signIn('ecasProvider', {
        callbackUrl: redirectTarget,
      })
    }
  }, [router.isReady, props.authDisabled, router, props.locale])
 
  return (
    <div role="main">
      <MetaData language="en" data={props.meta}></MetaData>
      <h1
        className="grid h-screen place-items-center"
        data-cy="loading-spinner"
        aria-live="polite"
        aria-busy="true"
      >
        <LoadingSpinner text="Loading / Chargement en cours ..." />
      </h1>
    </div>
  )
}
 
Login.getLayout = function PageLayout(page) {
  return <>{page}</>
}
 
export async function getServerSideProps({ req, res, locale, query }) {
  //Temporary for testing purposes until auth flow is publicly accessible
  const authDisabled = AuthIsDisabled() ? true : false
 
  const session = await getServerSession(req, res, authOptions)
  const token = await getIdToken(req)
  const ecasUrl = process.env.AUTH_ECAS_BASE_URL
  const curamRedirect = process.env.AUTH_ECAS_CURAM_REDIRECT
  // TODO: Compare vs a whitelist
  const queryRedirect = query.link ? querystring.stringify(query) : ''
 
  //If Next-Auth session is valid, check to see if ECAS session is and then redirect to dashboard instead of reinitiating auth
  Iif (!AuthIsDisabled() && (await AuthIsValid(req, session))) {
    const sessionValid = await ValidateSession(
      process.env.CLIENT_ID,
      token?.sid,
    )
    Iif (sessionValid) {
      return {
        redirect: {
          destination:
            locale === 'en' ? '/en/my-dashboard' : '/fr/mon-tableau-de-bord',
          permanent: false,
        },
      }
    }
  }
 
  // If we get into the flow above and are already logged in, ignore redirect
  let redirectQueryString = ''
  const isSecure = req.headers['x-forwarded-proto'] === 'https'
  if (queryRedirect) {
    // If there's a query parameter, it overrides any cookies
    res.setHeader(
      'Set-Cookie',
      `redirectquery=${queryRedirect}; max-age=900; path=/; samesite=strict ; HttpOnly; ${isSecure ? 'Secure;' : ''}`,
    )
    redirectQueryString = queryRedirect
  } else {
    const redirectCookie = req.cookies.redirectquery
    Iif (redirectCookie) {
      // If there's no query parameter, set to the redirect cookie value
      redirectQueryString = redirectCookie
    }
    // If there's no query paramater AND no cookie, return empty to trigger normal flow
  }
 
  /* Place-holder Meta Data Props */
  const meta = {
    data_en: {
      title: 'Loading-Chargement en cours - Canada.ca',
      desc: 'English',
      author: 'Service Canada',
      keywords: '',
      service: 'ESDC-EDSC_MSCA-MSDC-SCH',
      creator: 'Employment and Social Development Canada',
      accessRights: '1',
    },
    data_fr: {
      title: 'Loading-Chargement en cours - Canada.ca',
      desc: 'Français',
      author: 'Service Canada',
      keywords: '',
      service: 'ESDC-EDSC_MSCA-MSDC-SCH',
      creator: 'Emploi et Développement social Canada',
      accessRights: '1',
    },
  }
 
  return {
    props: {
      locale,
      meta,
      authDisabled: authDisabled ?? true,
      redirectQueryString: redirectQueryString,
      ecasUrl: ecasUrl,
      curamRedirect: curamRedirect,
    },
  }
}