Skip to content

Instantly share code, notes, and snippets.

@aanation
Created July 13, 2023 20:30
Show Gist options
  • Save aanation/4233098f1b7cbf07cfb001c085b91de1 to your computer and use it in GitHub Desktop.
Save aanation/4233098f1b7cbf07cfb001c085b91de1 to your computer and use it in GitHub Desktop.
atomic router auth example
// protected-route.ts
import type { RouteInstance, RouteParams, RouteParamsAndQuery } from "atomic-router"
import { chainRoute, redirect } from 'atomic-router'
import { type Store, type Event, createEvent, sample } from "effector"
type ChainProtectedParams<Params extends RouteParams> = {
route: RouteInstance<Params>
filter: Store<boolean>
failRoute?: RouteInstance<any>
openOn?: Event<any>[]
cancelOn?: Event<any>[]
}
export function chainProtected<Params extends RouteParams>({
route,
filter,
failRoute,
openOn = [],
cancelOn = [],
}: ChainProtectedParams<Params>) {
const checkStarted = createEvent<RouteParamsAndQuery<Params>>()
const allowed = sample({
clock: checkStarted,
filter,
})
const forbidden = sample({
clock: checkStarted,
filter: filter.map((v) => !v),
})
if (failRoute) {
redirect({
clock: forbidden,
route: failRoute,
})
}
return chainRoute({
route,
beforeOpen: checkStarted,
openOn: [allowed, ...openOn],
cancelOn: [forbidden, ...cancelOn],
})
}
// auth-route.ts
import { RouteInstance, RouteParams, createRoute, redirect } from 'atomic-router'
import { Link, createRoutesView } from 'atomic-router-react'
import { chainProtected } from '~/protected-route'
import { $isAuth, authenticate, resetAuthState } from '~/dal'
export const signInRoute = createRoute()
export function chainAuth<Params extends RouteParams>(route: RouteInstance<Params>) {
return chainProtected({
route,
failRoute: signInRoute,
filter: $isAuth,
openOn: [authenticate],
cancelOn: [resetAuthState],
})
}
redirect({
clock: resetAuthState,
route: signInRoute,
})
// routes.ts
import { RouteInstance, RouteParams, createRoute, redirect } from 'atomic-router'
import { Link, createRoutesView } from 'atomic-router-react'
import { signInRoute, chainAuth } from '~/auth-route.ts'
import { SignInPage } from '~/pages/sign-in/view'
import { HomePage } from '~/pages/home/view'
import { NotFoundPage } from '~/pages/not-found/view'
export const homeRoute = createRoute()
export const authHomeRoute = chainAuth(homeRoute)
export const routes = [
{ path: '/sign-in', route: signInRoute },
{ path: '/', route: homeRoute },
]
export const RoutesView = createRoutesView({
routes: [
{ route: authHomeRoute, view: HomePage },
{ route: signInRoute, view: SignInPage, }
],
otherwise: NotFoundPage,
})
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment