mirror of
https://github.com/dsoaress/link-free.git
synced 2026-08-16 22:46:04 +01:00
feat: add protect routes
This commit is contained in:
@@ -2,8 +2,9 @@ import { useState } from 'react'
|
||||
|
||||
import { useAuth } from 'hooks/useAuth'
|
||||
import { fetchData } from 'services/fetchData'
|
||||
import { guestUserRoute } from 'utils/guestUserRoute'
|
||||
|
||||
import type { GetStaticProps } from 'next'
|
||||
import type { GetServerSideProps } from 'next'
|
||||
|
||||
export default function AuthPage() {
|
||||
const { signIn } = useAuth()
|
||||
@@ -36,7 +37,7 @@ export default function AuthPage() {
|
||||
)
|
||||
}
|
||||
|
||||
export const getStaticProps: GetStaticProps = async () => {
|
||||
export const getServerSideProps: GetServerSideProps = guestUserRoute(async () => {
|
||||
const initialData = await fetchData()
|
||||
return { props: { initialData }, revalidate: 1 }
|
||||
}
|
||||
return { props: { initialData } }
|
||||
})
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
import { Dash } from 'components/Dash'
|
||||
import { fetchData } from 'services/fetchData'
|
||||
import { authenticatedUserRoute } from 'utils/authenticatedUserRoute'
|
||||
|
||||
import type { GetServerSideProps } from 'next'
|
||||
import type { Data } from 'types/Data'
|
||||
@@ -12,7 +13,10 @@ export default function DashPage({ initialData }: DashPageProps) {
|
||||
return <Dash initialData={initialData} />
|
||||
}
|
||||
|
||||
export const getServerSideProps: GetServerSideProps = async () => {
|
||||
const initialData = await fetchData()
|
||||
return { props: { initialData } }
|
||||
}
|
||||
export const getServerSideProps: GetServerSideProps = authenticatedUserRoute(
|
||||
async () => {
|
||||
const initialData = await fetchData()
|
||||
return { props: { initialData } }
|
||||
},
|
||||
{ roles: ['ADMIN', 'EDITOR'] }
|
||||
)
|
||||
|
||||
46
src/utils/authenticatedUserRoute.ts
Normal file
46
src/utils/authenticatedUserRoute.ts
Normal file
@@ -0,0 +1,46 @@
|
||||
import { GetServerSideProps, GetServerSidePropsContext } from 'next'
|
||||
import { parseCookies } from 'nookies'
|
||||
import { decode } from 'jsonwebtoken'
|
||||
|
||||
import { validateUserPermissions } from 'utils/validateUserPermissions'
|
||||
|
||||
import type { Role } from '@prisma/client'
|
||||
|
||||
type Options = {
|
||||
roles: Role[]
|
||||
}
|
||||
|
||||
export function authenticatedUserRoute(fn: GetServerSideProps, options?: Options) {
|
||||
return async (ctx: GetServerSidePropsContext) => {
|
||||
const { accessToken } = parseCookies(ctx)
|
||||
|
||||
if (!accessToken) {
|
||||
return {
|
||||
redirect: {
|
||||
destination: '/auth',
|
||||
permanent: false
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
const { role: userRole } = decode(accessToken) as { role: Role }
|
||||
|
||||
if (options) {
|
||||
const userHasValidPermissions = validateUserPermissions({
|
||||
userRole,
|
||||
roles: options.roles
|
||||
})
|
||||
|
||||
if (!userHasValidPermissions) {
|
||||
return {
|
||||
redirect: {
|
||||
destination: '/',
|
||||
permanent: false
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return await fn(ctx)
|
||||
}
|
||||
}
|
||||
20
src/utils/guestUserRoute.ts
Normal file
20
src/utils/guestUserRoute.ts
Normal file
@@ -0,0 +1,20 @@
|
||||
import { parseCookies } from 'nookies'
|
||||
|
||||
import type { GetStaticProps, GetServerSidePropsContext } from 'next'
|
||||
|
||||
export function guestUserRoute(fn: GetStaticProps) {
|
||||
return async (ctx: GetServerSidePropsContext) => {
|
||||
const { accessToken } = parseCookies(ctx)
|
||||
|
||||
if (accessToken) {
|
||||
return {
|
||||
redirect: {
|
||||
destination: '/dash',
|
||||
permanent: false
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return await fn(ctx)
|
||||
}
|
||||
}
|
||||
20
src/utils/validateUserPermissions.ts
Normal file
20
src/utils/validateUserPermissions.ts
Normal file
@@ -0,0 +1,20 @@
|
||||
import type { Role } from '@prisma/client'
|
||||
|
||||
type ValidateUserPermissionsParams = {
|
||||
userRole: Role
|
||||
roles?: Role[]
|
||||
}
|
||||
|
||||
export function validateUserPermissions({ userRole, roles }: ValidateUserPermissionsParams) {
|
||||
if (roles && roles.length > 0) {
|
||||
const hasPermission = roles.some(role => {
|
||||
return userRole.includes(role)
|
||||
})
|
||||
|
||||
if (!hasPermission) {
|
||||
return false
|
||||
}
|
||||
}
|
||||
|
||||
return true
|
||||
}
|
||||
Reference in New Issue
Block a user