Skip to content

Commit

Permalink
try and fix caching issue for login
Browse files Browse the repository at this point in the history
  • Loading branch information
docimin committed Jun 29, 2024
1 parent f36fe99 commit 0bfe0f3
Show file tree
Hide file tree
Showing 12 changed files with 222 additions and 76 deletions.
113 changes: 83 additions & 30 deletions src/app/[locale]/(auth)/login/mfa/page.client.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -13,11 +13,27 @@ import {
} from '@/utils/actions/account/account'
import { useEffect, useState } from 'react'
import { useRouter } from '@/navigation'
import { mfaChallengeNeeded } from '@/utils/server-api/account/user'

export default function MfaPageClient() {
const { toast } = useToast()
const router = useRouter()
const [challengeId, setChallengeId] = useState('')
const [needsMfa, setNeedsMfa] = useState(false)

useEffect(() => {
const checkMfa = async () => {
const mfaNeeded = await mfaChallengeNeeded()
if (mfaNeeded.type === 'general_unauthorized_scope') {
window.location.href = '/login'
} else if (mfaNeeded.$id) {
window.location.href = '/account'
} else {
setNeedsMfa(true)
}
}
checkMfa().then()
})

const createMfaCode = async () => {
try {
Expand All @@ -36,7 +52,7 @@ export default function MfaPageClient() {
try {
await updateMfaChallenge(challengeId, otp)

router.push('/account')
router.replace('/account')
} catch (error) {
if (error.type === 'user_invalid_token') {
toast({
Expand All @@ -45,6 +61,7 @@ export default function MfaPageClient() {
"Incorrect code. Please try again. If you're having trouble, please contact support.",
variant: 'destructive',
})
return
} else {
toast({
title: 'Error',
Expand All @@ -53,37 +70,73 @@ export default function MfaPageClient() {
variant: 'destructive',
})
Sentry.captureException(error)
return
}
}
}

return (
<InputOTP
maxLength={6}
onComplete={(result) => {
handleMfaVerify(result).catch((error) => {
console.log(error)
toast({
title: 'Error',
description:
"You encountered an error. But don't worry, we're on it.",
variant: 'destructive',
})
Sentry.captureException(error)
})
}}
>
<InputOTPGroup>
<InputOTPSlot index={0} />
<InputOTPSlot index={1} />
<InputOTPSlot index={2} />
</InputOTPGroup>
<InputOTPSeparator />
<InputOTPGroup>
<InputOTPSlot index={3} />
<InputOTPSlot index={4} />
<InputOTPSlot index={5} />
</InputOTPGroup>
</InputOTP>
)
if (!needsMfa) {
return (
<div className="flex flex-1 justify-center items-center absolute inset-0">
<div className="mx-auto mt-14 min-w-1/3 rounded-2xl p-8 dark:bg-[#04050a]/85 dark:ring-white">
<div className="mt-10">
<div>
<div className={'text-center'}>
<h2 className="mt-8 text-2xl font-bold leading-9 tracking-tight">
Loading...
</h2>
</div>
</div>
</div>
</div>
</div>
)
} else {
return (
<div className="flex flex-1 justify-center items-center absolute inset-0">
{/* Add justify-center and items-center here */}
<div className="mx-auto mt-14 min-w-1/3 rounded-2xl p-8 dark:bg-[#04050a]/85 dark:ring-white">
<div className="mt-10">
<div>
<div className={'text-center'}>
<h2 className="mt-8 text-2xl font-bold leading-9 tracking-tight">
Please fill in your 2FA code
</h2>
</div>
<div key="1" className="mx-auto max-w-4xl p-6 space-y-6">
<InputOTP
maxLength={6}
onComplete={(result) => {
handleMfaVerify(result).catch((error) => {
console.log(error)
toast({
title: 'Error',
description:
"You encountered an error. But don't worry, we're on it.",
variant: 'destructive',
})
Sentry.captureException(error)
return
})
}}
>
<InputOTPGroup>
<InputOTPSlot index={0} />
<InputOTPSlot index={1} />
<InputOTPSlot index={2} />
</InputOTPGroup>
<InputOTPSeparator />
<InputOTPGroup>
<InputOTPSlot index={3} />
<InputOTPSlot index={4} />
<InputOTPSlot index={5} />
</InputOTPGroup>
</InputOTP>
</div>
</div>
</div>
</div>
</div>
)
}
}
34 changes: 2 additions & 32 deletions src/app/[locale]/(auth)/login/mfa/page.tsx
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
import { Button } from '@/components/ui/button'
import { Link, redirect } from '@/navigation'
import { Link } from '@/navigation'
import MfaPageClient from '@/app/[locale]/(auth)/login/mfa/page.client'
import { mfaChallengeNeeded } from '@/utils/server-api/account/user'

export const metadata = {
title: 'Login',
Expand All @@ -12,41 +11,12 @@ export const metadata = {
export const runtime = 'edge'

export default async function Page() {
const mfaNeeded = await mfaChallengeNeeded()
if (mfaNeeded.type === 'general_unauthorized_scope') {
return redirect('/login')
}
if (mfaNeeded.$id) {
return redirect('/account')
}

return (
<>
<div className="lines">
<div className="line" />
<div className="line" />
<div className="line" />
</div>
<Link href={'/'} className={'absolute top-8 left-8 z-10'}>
<Button>Home</Button>
</Link>
<div className="flex flex-1 justify-center items-center absolute inset-0">
{/* Add justify-center and items-center here */}
<div className="mx-auto mt-14 min-w-1/3 rounded-2xl p-8 dark:bg-[#04050a]/85 dark:ring-white">
<div className="mt-10">
<div>
<div className={'text-center'}>
<h2 className="mt-8 text-2xl font-bold leading-9 tracking-tight">
Please fill in your 2FA code
</h2>
</div>
<div key="1" className="mx-auto max-w-4xl p-6 space-y-6">
<MfaPageClient />
</div>
</div>
</div>
</div>
</div>
<MfaPageClient />
</>
)
}
15 changes: 7 additions & 8 deletions src/app/[locale]/(auth)/login/page.client.tsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
'use client'
import { useState } from 'react'
import { useEffect, useState } from 'react'

Check warning on line 2 in src/app/[locale]/(auth)/login/page.client.tsx

View workflow job for this annotation

GitHub Actions / Qodana for JS

Unused import

Unused import specifier useEffect
import {
SiGithub,
SiDiscord,
Expand Down Expand Up @@ -57,27 +57,31 @@ export default function Login() {
description: 'Invalid E-Mail or password provided.',
variant: 'destructive',
})
return
} else if (response.code === 401) {
toast({
title: 'Error',
description: 'E-Mail or Password incorrect.',
variant: 'destructive',
})
return
} else if (response.code === 409) {
toast({
title: 'Error',
description: 'E-Mail already in use.',
variant: 'destructive',
})
return
} else if (response.code === 429) {
toast({
title: 'Error',
description: 'Too many requests, please try again later.',
variant: 'destructive',
})
return
}

router.push('/account')
window.location.href = '/account'
} else {
const signIn = await fetch('/api/user/signin', {
method: 'POST',
Expand Down Expand Up @@ -108,17 +112,12 @@ export default function Login() {

client.setSession(dataResponse.secret)

router.push('/login/mfa')
router.replace('/login/mfa')
}
}

return (
<>
<div className="lines">
<div className="line" />
<div className="line" />
<div className="line" />
</div>
<Button className={'m-8 absolute z-10'} onClick={() => router.push('/')}>
Home
</Button>
Expand Down
4 changes: 3 additions & 1 deletion src/app/[locale]/(auth)/login/page.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,9 @@ export default async function LoginPage() {
const accountData = await account.get().catch((e) => {
if (e.type === 'user_more_factors_required') redirect('/login/mfa')
})
if (accountData) redirect('/account')
if (accountData) {
redirect('/account')
}

return (
<>
Expand Down
63 changes: 63 additions & 0 deletions src/app/[locale]/(user)/notifications/page.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
import PageLayout from '@/components/pageLayout'
import { ChevronRight, MegaphoneIcon } from 'lucide-react'

Check warning on line 2 in src/app/[locale]/(user)/notifications/page.tsx

View workflow job for this annotation

GitHub Actions / Qodana for JS

Unused import

Unused import specifier MegaphoneIcon
import { getUserNotifications } from '@/utils/server-api/notifications/getUserNotifications'
import { getUserDataSingle } from '@/utils/server-api/user/getUserData'
import { Avatar, AvatarFallback, AvatarImage } from '@/components/ui/avatar'
import { getAvatarImageUrlPreview } from '@/components/getStorageItem'

export default async function Page() {
const notifications = await getUserNotifications()
return (
<PageLayout title={'Notifications'}>
<ul
role="list"
className="mx-auto mb-4 mt-8 max-w-4xl divide-y divide-gray-100 overflow-hidden shadow-sm ring-1 ring-black/95 dark:ring-white/95 sm:rounded-xl"
>
{notifications &&
notifications.documents.map(async (notification) => {
if (notification.type === 'newFollower') {
const user = await getUserDataSingle(notification.userId)

return (
<li
key={notification.$id}
className="relative flex justify-between gap-x-6 px-4 py-5 hover:bg-gray-50/90 dark:hover:bg-gray-50/10 sm:px-6"
>
<div className="flex min-w-0 gap-x-4">
<Avatar>
<AvatarImage
src={
getAvatarImageUrlPreview(
user.avatarId,
'width=250&height=250'
) || null
}
/>
<AvatarFallback>
{user.displayName.charAt(0).toUpperCase()}
</AvatarFallback>
</Avatar>
<div className="min-w-0 flex-auto">
<p className="text-sm font-semibold leading-6">
<span className="absolute inset-x-0 -top-px bottom-0" />
New Follower!
</p>
<p className="mt-1 flex text-xs leading-5 text-gray-400 dark:text-gray-300">
{user.displayName} followed you! 🎉
</p>
</div>
</div>
<div className="flex shrink-0 items-center gap-x-4">
<ChevronRight
className="h-5 w-5 flex-none text-gray-400"
aria-hidden="true"
/>
</div>
</li>
)
}
})}
</ul>
</PageLayout>
)
}
4 changes: 3 additions & 1 deletion src/app/[locale]/(user)/user/[profileUrl]/page.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -181,7 +181,9 @@ export default async function UserProfile({ params: { profileUrl } }) {
className={'col-span-3 border-none md:col-span-1 lg:col-span-2'}
>
<CardHeader>
<div className={'grid grid-cols-2'}>
<div
className={'grid grid-cols-1 xl:grid-cols-2 gap-4 xl:gap-0'}
>
<CardTitle className={'col-span-1'}>
{userData.displayName}
</CardTitle>
Expand Down
1 change: 1 addition & 0 deletions src/components/header/data.tsx
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
'use client'
import {
CalendarIcon,
CircleUserIcon,
Expand Down
2 changes: 2 additions & 0 deletions src/components/header/header-server.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,8 @@ import SidebarResizable from '@/components/header/header-resizable'
import MobileNav from '@/components/header/mobile-nav'
import { createSessionServerClient } from '@/app/appwrite-session'

export const dynamic = 'force-dynamic'

export default async function HeaderServer({
children,
locale,
Expand Down
1 change: 1 addition & 0 deletions src/utils/server-api/account/user.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
'use server'
import { createSessionServerClient } from '@/app/appwrite-session'
import { Models } from 'node-appwrite'
import { Account } from '@/utils/types/models'
Expand Down
7 changes: 7 additions & 0 deletions src/utils/server-api/notifications/getUserNotifications.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
import { createSessionServerClient } from '@/app/appwrite-session'
import { Notifications } from '@/utils/types/models'

export async function getUserNotifications(): Promise<Notifications.NotificationsType> {
const { databases } = await createSessionServerClient()
return await databases.listDocuments('hp_db', 'user-notifications')
}
Loading

0 comments on commit 0bfe0f3

Please sign in to comment.