mo-fouad / next-shield

The shield that every Next.js project needs.

Home Page:https://imjulianeral.github.io/next-shield/

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

NextShield

πŸ˜‰ The shield that every Next.js project needs.

import { Loading } from '@components/routes/loading'

const MyApp: NextPage<AppProps> = ({ Component, pageProps }) => {
  const { isAuth, isLoading } = useAuth()
  const router = useRouter()

  const privateRoutes = ['/protected']
  const publicRoutes = ['/']
  const hybridRoutes = ['/products/[slug]']

  return (
    <NextShield
      isAuth={isAuth}
      isLoading={isLoading}
      router={router}
      privateRoutes={privateRoutes}
      publicRoutes={publicRoutes}
      hybridRoutes={hybridRoutes}
      LoadingComponent={<Loading />}
    >
      <Component {...pageProps} />
    </NextShield>
  )
}

export default MyApp

NextShieldProps

isAuth

πŸ”‘ This value must be provided by the state of your app. Indicates if the user is authenticated or not.

Here's a simple example with firebase auth. But applies the same logic for any auth provider. πŸ˜‹

const [isAuth, setAuth] = useState(false)
useEffect(() => {
  const unsubscribe = auth().onAuthStateChanged(user => {
    if (user) {
      setAuth(true)
      return
    }

    setAuth(false)
  })

  return () => unsubscribe()
}, [isAuth])

isLoading

⏳ This value must be provided by the state of your app. Indicates if the user is already available or not.

Here's a simple example with firebase auth. But applies the same logic for any auth provider. πŸ˜‹

const [isAuth, setAuth] = useState(false)
const [isLoading, setLoading] = useState(true)
useEffect(() => {
  const unsubscribe = auth().onAuthStateChanged(user => {
    if (user) {
      setAuth(true)
      setLoading(false)
      return
    }

    setAuth(false)
    setLoading(false)
  })

  return () => unsubscribe()
}, [isAuth])

router

⇆ Instance of your router.

const router = useRouter()
...
return (
  <NextShield
    ...
    router={router}
    ...
  >
    <Component {...pageProps} />
  </NextShield>
)

loginRoute

πŸ“‹ Login page, must be a public route.

...
return (
  <NextShield
    ...
    loginRoute="/login"
    ...
  >
    <Component {...pageProps} />
  </NextShield>
)

accessRoute

🚧 Route where your user is going to access after login, must be a private route.

...
return (
  <NextShield
    ...
    accessRoute="/control-panel"
    ...
  >
    <Component {...pageProps} />
  </NextShield>
)

privateRoutes

🚧 🚧 🚧 Array of private routes. These are only accessible when the user is authenticated.

const privateRoutes = ['/control-panel', '/sales', '/user/[id]']

publicRoutes

πŸ‘€ πŸ‘€ πŸ‘€ Array of public routes. These are only accessible when the user is NOT authenticated.

const publicRoutes = ['/', '/login', '/services/[slug]']

hybridRoutes

🚦🚦🚦 Array of hybrid routes. These are always accessible; doesn't matter the user state.

You are not required to use this prop, it's only helpful if you wanna track which routes are always accessible.

const hybridRoutes = ['/support', '/pricing', '/products/[slug]']

LoadingComponent

πŸŒ€ React Component which is going to appear when isLoading equals to true.

Loading.tsx:

export function Loading() {
  return <p>Loading...</p>
}

_app.tsx:

import { Loading } from '@components/routes/loading'

const MyApp: NextPage<AppProps> = ({ Component, pageProps }) => {
  return (
    <NextShield
      ...
      LoadingComponent={<Loading />}
      ...
    >
      <Component {...pageProps} />
    </NextShield>
  )
}

RBAC

πŸ” πŸ” πŸ”’ Role Based Access Control.

You can define an object literal to specify which roles are supported and which routes the role have access.

You must define the accessRoute on each Role.

return (
  <NextShield
    ...
    accessRoute="/profile"
    RBAC={{
      ADMIN: ['/profile', '/control-panel'],
      EMPLOYEE: ['/profile', '/dashboard'],
    }}
    ...
  >
    <Component {...pageProps} />
  </NextShield>
)

userRole

🎭 The auth user role.

  • This value must be provided when using RBAC.
  • Should by provided by the session or state of the application.
  • Must match with the roles defined on RBAC
const { user } = useAuth()

return (
  <NextShield
    ...
    userRole={user.role} // "ADMIN"
    ...
  >
    <Component {...pageProps} />
  </NextShield>
)

About

The shield that every Next.js project needs.

https://imjulianeral.github.io/next-shield/

License:MIT License


Languages

Language:TypeScript 97.2%Language:HTML 1.6%Language:Shell 1.1%Language:JavaScript 0.2%