Move auth routes into /auth folder

This commit is contained in:
Jackson Harper 2022-07-26 10:31:45 -07:00
parent a335bfacfc
commit acd36fe9af
17 changed files with 109 additions and 177 deletions

View file

@ -340,7 +340,7 @@ export function authRouter() {
)
}
return res.redirect(
`${env.client.url}/settings/installation/extensions`
`${env.client.url}/home`
)
}
@ -377,7 +377,7 @@ export function authRouter() {
if (!email || !password) {
return res.redirect(
`${env.client.url}/email-login?errorCodes=${LoginErrorCode.InvalidCredentials}`
`${env.client.url}/auth/email-login?errorCodes=${LoginErrorCode.InvalidCredentials}`
)
}
@ -388,7 +388,7 @@ export function authRouter() {
})
if (!user?.id) {
return res.redirect(
`${env.client.url}/email-login?errorCodes=${LoginErrorCode.UserNotFound}`
`${env.client.url}/auth/email-login?errorCodes=${LoginErrorCode.UserNotFound}`
)
}
@ -399,14 +399,14 @@ export function authRouter() {
name: user.name,
})
return res.redirect(
`${env.client.url}/email-login?errorCodes=PENDING_VERIFICATION`
`${env.client.url}/auth/email-login?errorCodes=PENDING_VERIFICATION`
)
}
if (!user?.password) {
// user has no password, so they need to set one
return res.redirect(
`${env.client.url}/email-login?errorCodes=${LoginErrorCode.WrongSource}`
`${env.client.url}/auth/email-login?errorCodes=${LoginErrorCode.WrongSource}`
)
}
@ -414,7 +414,7 @@ export function authRouter() {
const validPassword = await comparePassword(password, user.password)
if (!validPassword) {
return res.redirect(
`${env.client.url}/email-login?errorCodes=${LoginErrorCode.InvalidCredentials}`
`${env.client.url}/auth/email-login?errorCodes=${LoginErrorCode.InvalidCredentials}`
)
}
@ -423,7 +423,7 @@ export function authRouter() {
await handleSuccessfulLogin(req, res, user, false)
} catch (e) {
logger.info('email-login exception:', e)
res.redirect(`${env.client.url}/email-login?errorCodes=AUTH_FAILED`)
res.redirect(`${env.client.url}/auth/email-login?errorCodes=AUTH_FAILED`)
}
}
)
@ -441,7 +441,7 @@ export function authRouter() {
if (!email || !password || !name || !username) {
return res.redirect(
`${env.client.url}/email-signup?errorCodes=INVALID_CREDENTIALS`
`${env.client.url}/auth/email-signup?errorCodes=INVALID_CREDENTIALS`
)
}
const lowerCasedUsername = username.toLowerCase()
@ -462,15 +462,15 @@ export function authRouter() {
pendingConfirmation: true,
})
res.redirect(`${env.client.url}/verify-email?message=SIGNUP_SUCCESS`)
res.redirect(`${env.client.url}/auth/verify-email?message=SIGNUP_SUCCESS`)
} catch (e) {
logger.info('email-signup exception:', e)
if (isErrorWithCode(e)) {
return res.redirect(
`${env.client.url}/email-signup?errorCodes=${e.errorCode}`
`${env.client.url}/auth/email-signup?errorCodes=${e.errorCode}`
)
}
res.redirect(`${env.client.url}/email-signup?errorCodes=UNKNOWN`)
res.redirect(`${env.client.url}/auth/email-signup?errorCodes=UNKNOWN`)
}
}
)
@ -491,14 +491,14 @@ export function authRouter() {
const claims = await getClaimsByToken(token)
if (!claims) {
return res.redirect(
`${env.client.url}/confirm-email?errorCodes=INVALID_TOKEN`
`${env.client.url}/auth/confirm-email?errorCodes=INVALID_TOKEN`
)
}
const user = await getRepository(User).findOneBy({ id: claims.uid })
if (!user) {
return res.redirect(
`${env.client.url}/confirm-email?errorCodes=USER_NOT_FOUND`
`${env.client.url}/auth/confirm-email?errorCodes=USER_NOT_FOUND`
)
}
@ -514,7 +514,7 @@ export function authRouter() {
if (!updated.affected) {
return res.redirect(
`${env.client.url}/confirm-email?errorCodes=UNKNOWN`
`${env.client.url}/auth/confirm-email?errorCodes=UNKNOWN`
)
}
}
@ -526,11 +526,11 @@ export function authRouter() {
logger.info('confirm-email exception:', e)
if (e instanceof jwt.TokenExpiredError) {
return res.redirect(
`${env.client.url}/confirm-email?errorCodes=TOKEN_EXPIRED`
`${env.client.url}/auth/confirm-email?errorCodes=TOKEN_EXPIRED`
)
}
res.redirect(`${env.client.url}/confirm-email?errorCodes=INVALID_TOKEN`)
res.redirect(`${env.client.url}/auth/confirm-email?errorCodes=INVALID_TOKEN`)
}
}
)
@ -547,7 +547,7 @@ export function authRouter() {
const email = req.body.email
if (!email) {
return res.redirect(
`${env.client.url}/forgot-password?errorCodes=INVALID_EMAIL`
`${env.client.url}/auth/forgot-password?errorCodes=INVALID_EMAIL`
)
}
@ -557,27 +557,27 @@ export function authRouter() {
})
if (!user) {
return res.redirect(
`${env.client.url}/forgot-password?errorCodes=USER_NOT_FOUND`
`${env.client.url}/auth/forgot-password?errorCodes=USER_NOT_FOUND`
)
}
if (user.status === StatusType.Pending) {
return res.redirect(
`${env.client.url}/email-login?errorCodes=PENDING_VERIFICATION`
`${env.client.url}/auth/email-login?errorCodes=PENDING_VERIFICATION`
)
}
if (!(await sendPasswordResetEmail(user))) {
return res.redirect(
`${env.client.url}/forgot-password?errorCodes=INVALID_EMAIL`
`${env.client.url}/auth/forgot-password?errorCodes=INVALID_EMAIL`
)
}
res.redirect(`${env.client.url}/forgot-password?message=SUCCESS`)
res.redirect(`${env.client.url}/auth/forgot-password?message=SUCCESS`)
} catch (e) {
logger.info('forgot-password exception:', e)
res.redirect(`${env.client.url}/forgot-password?errorCodes=UNKNOWN`)
res.redirect(`${env.client.url}/auth/forgot-password?errorCodes=UNKNOWN`)
}
}
)
@ -598,26 +598,26 @@ export function authRouter() {
const claims = await getClaimsByToken(token)
if (!claims) {
return res.redirect(
`${env.client.url}/reset-password?errorCodes=INVALID_TOKEN`
`${env.client.url}/auth/reset-password?errorCodes=INVALID_TOKEN`
)
}
if (!password) {
return res.redirect(
`${env.client.url}/reset-password?errorCodes=INVALID_PASSWORD`
`${env.client.url}/auth/reset-password?errorCodes=INVALID_PASSWORD`
)
}
const user = await getRepository(User).findOneBy({ id: claims.uid })
if (!user) {
return res.redirect(
`${env.client.url}/reset-password?errorCodes=USER_NOT_FOUND`
`${env.client.url}/auth/reset-password?errorCodes=USER_NOT_FOUND`
)
}
if (user.status === StatusType.Pending) {
return res.redirect(
`${env.client.url}/email-login?errorCodes=PENDING_VERIFICATION`
`${env.client.url}/auth/email-login?errorCodes=PENDING_VERIFICATION`
)
}
@ -632,21 +632,21 @@ export function authRouter() {
)
if (!updated.affected) {
return res.redirect(
`${env.client.url}/reset-password?errorCodes=UNKNOWN`
`${env.client.url}/auth/reset-password?errorCodes=UNKNOWN`
)
}
res.redirect(`${env.client.url}/reset-password?message=SUCCESS`)
res.redirect(`${env.client.url}/auth/reset-password?message=SUCCESS`)
} catch (e) {
logger.info('reset-password exception:', e)
if (e instanceof jwt.TokenExpiredError) {
return res.redirect(
`${env.client.url}/reset-password?errorCodes=TOKEN_EXPIRED`
`${env.client.url}/auth/reset-password?errorCodes=TOKEN_EXPIRED`
)
}
res.redirect(
`${env.client.url}/reset-password?errorCodes=INVALID_TOKEN`
`${env.client.url}/auth/reset-password?errorCodes=INVALID_TOKEN`
)
}
}

View file

@ -9,7 +9,7 @@ export const sendConfirmationEmail = async (user: {
}): Promise<boolean> => {
// generate confirmation link
const token = generateVerificationToken(user.id)
const link = `${env.client.url}/confirm-email/${token}`
const link = `${env.client.url}/auth/confirm-email/${token}`
// send email
const dynamicTemplateData = {
name: user.name,
@ -31,7 +31,7 @@ export const sendPasswordResetEmail = async (user: {
}): Promise<boolean> => {
// generate link
const token = generateVerificationToken(user.id)
const link = `${env.client.url}/reset-password/${token}`
const link = `${env.client.url}/auth/reset-password/${token}`
// send email
const dynamicTemplateData = {
name: user.name,

View file

@ -499,7 +499,7 @@ describe('auth router', () => {
302
)
expect(res.header.location).to.endWith(
'/reset-password?message=SUCCESS'
'/auth/reset-password?message=SUCCESS'
)
})
@ -518,7 +518,7 @@ describe('auth router', () => {
it('redirects to reset-password page with error code INVALID_PASSWORD', async () => {
const res = await resetPasswordRequest(token, '').expect(302)
expect(res.header.location).to.endWith(
'/reset-password?errorCodes=INVALID_PASSWORD'
'/auth/reset-password?errorCodes=INVALID_PASSWORD'
)
})
})
@ -531,7 +531,7 @@ describe('auth router', () => {
'new_password'
).expect(302)
expect(res.header.location).to.endWith(
'/reset-password?errorCodes=INVALID_TOKEN'
'/auth/reset-password?errorCodes=INVALID_TOKEN'
)
})
@ -545,7 +545,7 @@ describe('auth router', () => {
302
)
expect(res.header.location).to.endWith(
'/reset-password?errorCodes=TOKEN_EXPIRED'
'/auth/reset-password?errorCodes=TOKEN_EXPIRED'
)
})
})

View file

@ -45,7 +45,7 @@ export function EmailLogin(): JSX.Element {
return (
<form action={`${fetchEndpoint}/auth/email-login`} method="POST">
<VStack alignment="center" css={{ padding: '16px' }}>
<StyledText style="subHeadline">Login</StyledText>
<StyledText style="subHeadline" css={{ color: '$omnivoreGray' }}>Login</StyledText>
<VStack css={{ width: '100%', minWidth: '320px', gap: '16px', pb: '16px' }}>
<SpanBox css={{ width: '100%' }}>
<FormLabel>Email</FormLabel>
@ -111,7 +111,7 @@ export function EmailLogin(): JSX.Element {
}}
>
Don&apos;t have an account? {' '}
<Link href="/email-signup" passHref>
<Link href="/auth/email-signup" passHref>
<StyledTextSpan style="captionLink" css={{ color: '$omnivoreGray' }}>Sign up</StyledTextSpan>
</Link>
</StyledText>
@ -126,7 +126,7 @@ export function EmailLogin(): JSX.Element {
}}
>
Forgot your password? {' '}
<Link href="/email-reset-password" passHref>
<Link href="/auth/forgot-password" passHref>
<StyledTextSpan style="captionLink" css={{ color: '$omnivoreGray' }}>Click here</StyledTextSpan>
</Link>
</StyledText>

View file

@ -173,7 +173,7 @@ export function EmailSignup(): JSX.Element {
}}
>
Already have an account? {' '}
<Link href="/email-login" passHref>
<Link href="/auth/email-login" passHref>
<StyledTextSpan style="captionLink" css={{ color: '$omnivoreGray' }}>Login instead</StyledTextSpan>
</Link>
</StyledText>

View file

@ -106,33 +106,6 @@ export function LoginForm(props: LoginFormProps): JSX.Element {
/>
</Box>
)}
{/*
<StyledText
style="caption"
css={{
pt: '16px',
maxWidth: '220px',
textAlign: 'left',
color: '$omnivoreLightGray',
}}
>
<SpanBox>
Use your email address to{' '}
<Link href="/email-login" passHref>
<StyledTextSpan style="captionLink" css={{ color: '$omnivoreGray' }}>
Login
</StyledTextSpan>
</Link>{' '}
or{' '}
<Link href="/email-signup" passHref>
<StyledTextSpan style="captionLink" css={{ color: '$omnivoreGray' }}>
Signup
</StyledTextSpan>
</Link>{' '}
with your email address.
</SpanBox>
</StyledText> */}
</VStack>
<TermAndConditionsFooter />
</VStack>

View file

@ -24,6 +24,7 @@ const errorMessages: Record<string, string> = {
'error.EXPIRED_TOKEN':
"Your sign up page has timed out, you'll be redirected to Google sign in page to authenticate again.",
'error.USER_EXISTS': 'User with this email exists already',
'error.UNKNOWN': 'An unknown error occurred',
}
const loginPageMessages: Record<string, string> = {

View file

@ -2,14 +2,13 @@ import { useEffect, useRef, useState } from 'react'
import { useRouter } from 'next/router'
import { Toaster } from 'react-hot-toast'
import { applyStoredTheme } from '../../lib/themeUpdater'
import { applyStoredTheme } from '../../../lib/themeUpdater'
import { PrimaryLayout } from '../../components/templates/PrimaryLayout'
import { PrimaryLayout } from '../../../components/templates/PrimaryLayout'
import { HStack, SpanBox } from '../../components/elements/LayoutPrimitives'
import { Loader } from '../../components/templates/SavingRequest'
import { fetchEndpoint } from '../../lib/appConfig'
import { LoadingView } from '../../components/patterns/LoadingView'
import { HStack, SpanBox } from '../../../components/elements/LayoutPrimitives'
import { fetchEndpoint } from '../../../lib/appConfig'
import { LoadingView } from '../../../components/patterns/LoadingView'
export default function ConfirmEmail(): JSX.Element {
const authForm = useRef<HTMLFormElement | null>(null)

View file

@ -0,0 +1,15 @@
import { PageMetaData } from '../../components/patterns/PageMetaData'
import { ProfileLayout } from '../../components/templates/ProfileLayout'
import { EmailLogin } from '../../components/templates/EmailLogin'
export default function EmailLoginPage(): JSX.Element {
return (
<>
<PageMetaData title="Login - Omnivore" path="/email-login" />
<ProfileLayout>
<EmailLogin />
</ProfileLayout>
<div data-testid="email-login-page-tag" />
</>
)
}

View file

@ -0,0 +1,15 @@
import { PageMetaData } from '../../components/patterns/PageMetaData'
import { ProfileLayout } from '../../components/templates/ProfileLayout'
import { EmailSignup } from '../../components/templates/EmailSignup'
export default function EmailRegistrationPage(): JSX.Element {
return (
<>
<PageMetaData title="Sign up with Email - Omnivore" path="/auth-signup" />
<ProfileLayout>
<EmailSignup />
</ProfileLayout>
<div data-testid="auth-signup-page-tag" />
</>
)
}

View file

@ -1,10 +1,10 @@
import { PageMetaData } from '../components/patterns/PageMetaData'
import { ProfileLayout } from '../components/templates/ProfileLayout'
import { EmailResetPassword } from '../components/templates/EmailResetPassword'
import { PageMetaData } from '../../components/patterns/PageMetaData'
import { ProfileLayout } from '../../components/templates/ProfileLayout'
import { EmailResetPassword } from '../../components/templates/EmailResetPassword'
import { useEffect } from 'react'
import { useRouter } from 'next/router'
import toast, { Toaster } from 'react-hot-toast'
import { showSuccessToast } from '../lib/toastHelpers'
import { showSuccessToast } from '../../lib/toastHelpers'
export default function ForgotPassword(): JSX.Element {
const router = useRouter()
@ -21,7 +21,7 @@ export default function ForgotPassword(): JSX.Element {
return (
<>
<PageMetaData title="Reset your password - Omnivore" path="/email-reset-password" />
<PageMetaData title="Reset your password - Omnivore" path="/auth-forgot-password" />
<Toaster
containerStyle={{
top: '5rem',
@ -30,7 +30,7 @@ export default function ForgotPassword(): JSX.Element {
<ProfileLayout>
<EmailResetPassword />
</ProfileLayout>
<div data-testid="email-reset-password-page-tag" />
<div data-testid="auth-forgot-password-page-tag" />
</>
)
}

View file

@ -0,0 +1,15 @@
import { PageMetaData } from '../../components/patterns/PageMetaData'
import { ProfileLayout } from '../../components/templates/ProfileLayout'
import { EmailResetPassword } from '../../components/templates/EmailResetPassword'
export default function EmailRegistrationPage(): JSX.Element {
return (
<>
<PageMetaData title="Forgot your password - Omnivore" path="/auth-forgot-password" />
<ProfileLayout>
<EmailResetPassword />
</ProfileLayout>
<div data-testid="auth-forgot-password-page-tag" />
</>
)
}

View file

@ -0,0 +1,12 @@
import { PageMetaData } from '../../components/patterns/PageMetaData'
import { VerifyEmail } from '../../components/templates/VerifyEmail'
export default function VerifyEmailPage(): JSX.Element {
return (
<>
<PageMetaData title="Verify Email" path="/auth/verify-email" />
<VerifyEmail />
<div data-testid="auth/verify-email-page-tag" />
</>
)
}

View file

@ -1,56 +0,0 @@
import { PageMetaData } from '../components/patterns/PageMetaData'
import { ProfileLayout } from '../components/templates/ProfileLayout'
import { EmailLogin } from '../components/templates/EmailLogin'
export default function EmailLoginPage(): JSX.Element {
return (
<>
<PageMetaData title="Login - Omnivore" path="/email-login" />
<ProfileLayout>
<EmailLogin />
</ProfileLayout>
<div data-testid="email-login-page-tag" />
</>
)
}
// export default function EmailLogin(): JSX.Element {
// const [errorMessage, setErrorMessage] = useState<string | undefined>(
// undefined
// )
// const [message, setMessage] = useState<string | undefined>(undefined)
// const router = useRouter()
// useEffect(() => {
// if (!router.isReady) return
// const errorCode = parseErrorCodes(router.query)
// const errorMsg = errorCode
// ? formatMessage({ id: `error.${errorCode}` })
// : undefined
// setErrorMessage(errorMsg)
// const message = router.query.message
// ? formatMessage({ id: `login.${router.query.message}` })
// : undefined
// setMessage(message)
// }, [router.isReady, router.query])
// return (
// <PrimaryLayout pageTestId="email-login">
// {message && <StyledText style={'headline'}>{message}</StyledText>}
// <h1>Email Login</h1>
// <form action={`${fetchEndpoint}/auth/email-login`} method="POST">
// <div>
// <label>Email</label>
// <input type="email" name={'email'} required />
// </div>
// <div>
// <label>Password</label>
// <input type="password" name={'password'} required />
// </div>
// {errorMessage && <StyledText style="error">{errorMessage}</StyledText>}
// <button type="submit">Login</button>
// </form>
// </PrimaryLayout>
// )
// }

View file

@ -1,15 +0,0 @@
import { PageMetaData } from '../components/patterns/PageMetaData'
import { ProfileLayout } from '../components/templates/ProfileLayout'
import { EmailResetPassword } from '../components/templates/EmailResetPassword'
export default function EmailRegistrationPage(): JSX.Element {
return (
<>
<PageMetaData title="Reset your password - Omnivore" path="/email-reset-password" />
<ProfileLayout>
<EmailResetPassword />
</ProfileLayout>
<div data-testid="email-reset-password-page-tag" />
</>
)
}

View file

@ -1,15 +0,0 @@
import { PageMetaData } from '../components/patterns/PageMetaData'
import { ProfileLayout } from '../components/templates/ProfileLayout'
import { EmailSignup } from '../components/templates/EmailSignup'
export default function EmailRegistrationPage(): JSX.Element {
return (
<>
<PageMetaData title="Sign up with Email - Omnivore" path="/email-signup" />
<ProfileLayout>
<EmailSignup />
</ProfileLayout>
<div data-testid="email-signup-page-tag" />
</>
)
}

View file

@ -1,12 +0,0 @@
import { PageMetaData } from '../components/patterns/PageMetaData'
import { VerifyEmail } from '../components/templates/VerifyEmail'
export default function VerifyEmailPage(): JSX.Element {
return (
<>
<PageMetaData title="Verify Email" path="/verify-email" />
<VerifyEmail />
<div data-testid="verify-email-page-tag" />
</>
)
}