Skip to content

Commit

Permalink
for-of, optional useAuth, comments
Browse files Browse the repository at this point in the history
  • Loading branch information
Tobbe committed Mar 18, 2021
1 parent 15381e4 commit a72ab25
Show file tree
Hide file tree
Showing 3 changed files with 26 additions and 14 deletions.
14 changes: 10 additions & 4 deletions packages/router/src/private-context.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,9 @@ import { useRouterState } from './router-context'
* component
* @param unauthorized - Use this function to check if the user is allowed to
* go to this route or not
* @param unauthorized - Name of the route to go to if not authorized to visit
* any of the routes in the containing `<Private>` block
* @param unauthenticated - Name of the route to go to if not authorized to
* visit any of the routes in the containing
* `<Private>` block
*/
interface PrivateState {
isPrivate: boolean
Expand All @@ -31,7 +32,12 @@ export const PrivateContextProvider: React.FC<ProviderProps> = ({
unauthenticated,
}) => {
const routerState = useRouterState()
const { isAuthenticated, hasRole } = routerState.useAuth()
const isAuthenticated = routerState.useAuth
? routerState.useAuth().isAuthenticated
: false
const hasRole = routerState.useAuth
? routerState.useAuth().hasRole
: () => false

const unauthorized = useCallback(() => {
return !(isAuthenticated && (!role || hasRole(role)))
Expand All @@ -54,6 +60,6 @@ export const usePrivate = () => {
return {
isPrivate: !!context?.isPrivate,
unauthorized,
unauthenticated
unauthenticated,
}
}
6 changes: 3 additions & 3 deletions packages/router/src/router-context.tsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import React, { useReducer, createContext, useContext } from 'react'

import type { AuthContextInterface, useAuth } from '@redwoodjs/auth'
import type { useAuth } from '@redwoodjs/auth'

import { ParamType } from './internal'

Expand All @@ -9,7 +9,7 @@ const DEFAULT_PAGE_LOADING_DELAY = 1000 // milliseconds
export interface RouterState {
paramTypes?: Record<string, ParamType>
pageLoadingDelay?: number
useAuth: typeof useAuth
useAuth?: typeof useAuth
}

const RouterStateContext = createContext<RouterState | undefined>(undefined)
Expand All @@ -27,7 +27,7 @@ function stateReducer(state: RouterState, newState: Partial<RouterState>) {
}

export const RouterContextProvider: React.FC<RouterState> = ({
useAuth = () => ({} as AuthContextInterface),
useAuth,
paramTypes,
pageLoadingDelay = DEFAULT_PAGE_LOADING_DELAY,
children,
Expand Down
20 changes: 13 additions & 7 deletions packages/router/src/router.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ import { flattenAll, isReactElement } from './util'
* A more specific interface will be generated by
* babel-plugin-redwood-routes-auto-loader when a redwood project is built
*
* Example:
* @example
* interface AvailableRoutes {
* home: () => "/"
* test: () => "/test"
Expand All @@ -35,6 +35,8 @@ interface AvailableRoutes {
[key: string]: (args?: Record<string, string>) => string
}

// namedRoutes is populated at run-time by iterating over the `<Route />`
// components, and appending them to this object.
const namedRoutes: AvailableRoutes = {}

type PageType =
Expand Down Expand Up @@ -87,6 +89,12 @@ const Route: React.VFC<RouteProps> = ({
}

if (isPrivate) {
if (!routerState.useAuth) {
throw new Error(
'You need to pass `useAuth` to the router when using private routes'
)
}

const { loading } = routerState.useAuth()

if (loading) {
Expand Down Expand Up @@ -219,10 +227,7 @@ const NotFoundChecker: React.FC<{ children: React.ReactNode }> = ({
let NotFoundPage: PageType | undefined = undefined
const flatChildArray = flattenAll(children)

let i = 0;
while (i < flatChildArray.length && !foundMatchingRoute) {
const child = flatChildArray[i]

for (const child of flatChildArray) {
if (isRoute(child)) {
const { path } = child.props

Expand All @@ -235,15 +240,16 @@ const NotFoundChecker: React.FC<{ children: React.ReactNode }> = ({

if (match) {
foundMatchingRoute = true
// No need to loop further. As soon as we have a matching route we
// know we will not have to render the NotFound page
break
}
}

if (child.props.notfound && child.props.page) {
NotFoundPage = child.props.page
}
}

i++
}

if (!foundMatchingRoute && NotFoundPage) {
Expand Down

0 comments on commit a72ab25

Please sign in to comment.