juice_auth_routing

Integration glue between juice_auth and juice_routing. Feeds AuthBloc state into routing's guard system, two ways: guards (checked on navigation) and a reactive bridge (redirects when auth changes mid-session).

pub package License: MIT

Why

juice_routing's guards are callback-decoupled, and AuthState supplies exactly the predicates they need (isAuthenticated, hasRole). This package pre-wires them — and adds the piece guards alone can't do: evicting a user whose session ends while they're sitting on a protected route.

Install

dependencies:
  juice_auth: ^0.2.1
  juice_routing: ^1.1.0
  juice_auth_routing: ^0.1.0

Guards (checked on navigation)

final routing = RoutingBloc.withConfig(RoutingConfig(routes: [
  RouteConfig(path: '/profile', builder: ...,
    guards: [AuthBlocAuthGuard(authBloc)]),            // require auth → /login
  RouteConfig(path: '/login', builder: ...,
    guards: [AuthBlocGuestGuard(authBloc)]),           // bounce if logged in
  RouteConfig(path: '/admin', builder: ...,
    guards: [AuthBlocRoleGuard(authBloc, 'admin')]),   // require a role
]));
Guard Behavior
AuthBlocAuthGuard unauthenticated → redirect to loginPath (carries returnTo)
AuthBlocGuestGuard authenticated → redirect to redirectPath (keeps you out of login/signup)
AuthBlocRoleGuard missing role → block

Reactive bridge (auth changes mid-session)

Guards run on navigation — they don't evict a user who logs out (or whose session expires) while already on a protected screen. AuthBlocRoutingBridge watches AuthBloc and reacts:

final bridge = AuthBlocRoutingBridge(
  authBloc,
  routingBloc,
  loginPath: '/login',
  onAuthenticated: (state) => routingBloc.navigate('/'), // optional
)..start();

// ... on teardown
bridge.dispose();
  • Loses auth (logout or sessionExpired) → navigate(loginPath, replace: true).
  • Gains authonAuthenticated(state).

It owns no state — just a subscription.

License

MIT License — see LICENSE.

Libraries

juice_auth_routing
Integration glue between juice_auth and juice_routing.