import Head from 'next/head' import Image from 'next/image' import { useRouter } from 'next/router' import { useEffect, useState } from 'react' import { FontAwesomeIcon } from '@fortawesome/react-fontawesome' import { useTranslation, Trans } from 'next-i18next' import { serverSideTranslations } from 'next-i18next/serverSideTranslations' import siteConfig from '../../../config/site.config' import Navbar from '../../components/Navbar' import Footer from '../../components/Footer' import { getAuthPersonInfo, requestTokenWithAuthCode, sendTokenToServer } from '../../utils/oAuthHandler' import { LoadingIcon } from '../../components/Loading' export default function OAuthStep3({ accessToken, expiryTime, refreshToken, error, description, errorUri }) { const router = useRouter() const [expiryTimeLeft, setExpiryTimeLeft] = useState(expiryTime) const { t } = useTranslation() useEffect(() => { if (!expiryTimeLeft) return const intervalId = setInterval(() => { setExpiryTimeLeft(expiryTimeLeft - 1) }, 1000) return () => clearInterval(intervalId) }, [expiryTimeLeft]) const [buttonContent, setButtonContent] = useState(
{t('Store tokens')}
) const [buttonError, setButtonError] = useState(false) const sendAuthTokensToServer = async () => { setButtonError(false) setButtonContent(
{t('Storing tokens')}
) // verify identity of the authenticated user with the Microsoft Graph API const { data, status } = await getAuthPersonInfo(accessToken) if (status !== 200) { setButtonError(true) setButtonContent(
{t('Error validating identify, restart')}
) return } if (data.userPrincipalName !== siteConfig.userPrincipalName) { setButtonError(true) setButtonContent(
{t('Do not pretend to be the site owner')}
) return } await sendTokenToServer(accessToken, refreshToken, expiryTime) .then(() => { setButtonError(false) setButtonContent(
{t('Stored! Going home...')}
) setTimeout(() => { router.push('/') }, 2000) }) .catch(_ => { setButtonError(true) setButtonContent(
{t('Error storing the token')}
) }) } return (
{t('OAuth Step 3 - {{title}}', { title: siteConfig.title })}
fabulous celebration

{t('Welcome to your new onedrive-vercel-index 🎉')}

{t('Step 3/3: Get access and refresh tokens')}

{error ? (

{t('Whoops, looks like we got a problem: {{error}}.', { // t('No auth code present') error: t(error), })}

{ // t('Where is the auth code? Did you follow step 2 you silly donut?') t(description) }

{errorUri && (

Check out{' '} {/* eslint-disable-next-line react/no-unescaped-entities */} Microsoft's official explanation {' '} on the error message.

)}
) : (

{t('Success! The API returned what we needed.')}

    {accessToken && (
  1. {' '} {t('Acquired access_token: ')} {`${accessToken.substring(0, 60)}...`}
  2. )} {refreshToken && (
  3. {' '} {t('Acquired refresh_token: ')} {`${refreshToken.substring(0, 60)}...`}
  4. )}

{' '} {t('These tokens may take a few seconds to populate after you click the button below. ') + t('If you go back home and still see the welcome page telling you to re-authenticate, ') + t('revisit home and do a hard refresh.')}

{t( 'Final step, click the button below to store these tokens persistently before they expire after {{minutes}} minutes {{seconds}} seconds. ', { minutes: Math.floor(expiryTimeLeft / 60), seconds: expiryTimeLeft - Math.floor(expiryTimeLeft / 60) * 60, } ) + t( "Don't worry, after storing them, onedrive-vercel-index will take care of token refreshes and updates after your site goes live." )}

)}
) } export async function getServerSideProps({ query, locale }) { const { authCode } = query // Return if no auth code is present if (!authCode) { return { props: { error: 'No auth code present', description: 'Where is the auth code? Did you follow step 2 you silly donut?', ...(await serverSideTranslations(locale, ['common'])), }, } } const response = await requestTokenWithAuthCode(authCode) // If error response, return invalid if ('error' in response) { return { props: { error: response.error, description: response.errorDescription, errorUri: response.errorUri, ...(await serverSideTranslations(locale, ['common'])), }, } } const { expiryTime, accessToken, refreshToken } = response return { props: { error: null, expiryTime, accessToken, refreshToken, ...(await serverSideTranslations(locale, ['common'])), }, } }