Skip to content

Security hooks and route guards

SecurityProvider requires an existing TokenStorage and children, then makes useSecurity state available through context. Token creation/refresh belongs to CoSec; a route guard only decides which React node to render and is not a server authorization boundary.

APIContract
useSecurity(tokenStorage, options = {})Returns currentUser, authenticated, signIn, signOut; missing token uses ANONYMOUS_USER (sub anonymous, empty jti, zero iat/exp).
signIn(tokenOrAsyncProvider)Await provider if supplied, store token, invoke onSignIn. Returns Promise<void>; provider/storage/callback failures propagate.
signOut()Remove token and invoke onSignOut; synchronous exceptions propagate.
useSecurityContext()Returns context; throws outside SecurityProvider.
RouteGuardAuthenticated: children. Otherwise calls onUnauthorized and returns fallback (omitted renders nothing).
RefreshableRouteGuardRequires tokenManager. Refreshes when isRefreshNeeded and isRefreshable; authenticated children win, otherwise refreshing node or fallback. Default refreshing text is Refreshing....

RouteGuard.onUnauthorized runs during render and can run repeatedly; it is not an effect-based navigation callback. Avoid setting unrelated React state or sending requests from it. RefreshableRouteGuard logs refresh errors; it does not expose a local error state or cancel the token manager on unmount. The manager and storage remain application-owned. Context updates follow storage subscriptions, not an independent timer that recomputes authentication every second. Switching tokenStorage changes subscription and action targets; callbacks read latest options.

Complete example

tsx
import type { TokenStorage } from '@ahoo-wang/fetcher-cosec';
import {
  SecurityProvider,
  RouteGuard,
  useSecurityContext,
} from '@ahoo-wang/fetcher-react';
function Account() {
  const { currentUser, signOut } = useSecurityContext();
  return <button onClick={signOut}>Sign out {currentUser.sub}</button>;
}
export function SecureApp({ storage }: { storage: TokenStorage }) {
  return (
    <SecurityProvider tokenStorage={storage}>
      <RouteGuard fallback={<p>Please sign in.</p>}>
        <Account />
      </RouteGuard>
    </SecurityProvider>
  );
}

Public signatures and types

These signatures follow declarations reachable from the current root entry. ? marks optional input; generics/interfaces only constrain compile-time types. Locate inherited and related types through the symbol index. Runtime defaults and failure behavior are described above.

SecurityProvider

ts
export function SecurityProvider(
  options: SecurityContextOptions,
): import('react').JSX.Element;

packages/react/src/cosec/SecurityContext.tsx:107

useSecurityContext

ts
export function useSecurityContext(): SecurityContextValue;

packages/react/src/cosec/SecurityContext.tsx:146

SecurityContextValue

ts
export type SecurityContextValue = UseSecurityReturn;

packages/react/src/cosec/SecurityContext.tsx:30

SecurityContext

ts
declare const SecurityContext: import('react').Context<
  UseSecurityReturn | undefined
>;

packages/react/src/cosec/SecurityContext.tsx:41

SecurityContextOptions

ts
export interface SecurityContextOptions extends UseSecurityOptions {
  tokenStorage: TokenStorage;
  children: ReactNode;
}

packages/react/src/cosec/SecurityContext.tsx:49

useSecurity

ts
export function useSecurity(
  tokenStorage: TokenStorage,
  options?: UseSecurityOptions,
): UseSecurityReturn;

Implementation defaults: options = {}.

packages/react/src/cosec/useSecurity.ts:150

ANONYMOUS_USER

ts
declare const ANONYMOUS_USER: CoSecJwtPayload;

packages/react/src/cosec/useSecurity.ts:29

UseSecurityOptions

ts
export interface UseSecurityOptions {
  onSignIn?: () => void;
  onSignOut?: () => void;
}

packages/react/src/cosec/useSecurity.ts:39

UseSecurityReturn

ts
export interface UseSecurityReturn {
  currentUser: CoSecJwtPayload;
  authenticated: boolean;
  signIn: (compositeTokenProvider: CompositeTokenProvider) => Promise<void>;
  signOut: () => void;
}

packages/react/src/cosec/useSecurity.ts:56

RouteGuard

Expand all fields and members
ts
export function RouteGuard(
  options: RouteGuardProps,
):
  | string
  | number
  | bigint
  | boolean
  | import('react').JSX.Element
  | Iterable<ReactNode>
  | Promise<
      | string
      | number
      | bigint
      | boolean
      | import('react').ReactPortal
      | import('react').ReactElement<
          unknown,
          string | import('react').JSXElementConstructor<any>
        >
      | Iterable<ReactNode>
      | null
      | undefined
    >
  | null
  | undefined;

packages/react/src/cosec/RouteGuard.tsx:66

RouteGuardProps

ts
export interface RouteGuardProps {
  children: ReactNode;
  fallback?: ReactNode;
  onUnauthorized?: () => void;
}

packages/react/src/cosec/RouteGuard.tsx:20

RefreshableRouteGuard

ts
export function RefreshableRouteGuard(
  options: RefreshableRouteGuardProps,
): import('react').JSX.Element;

packages/react/src/cosec/RefreshableRouteGuard.tsx:28

RefreshableRouteGuardProps

ts
export interface RefreshableRouteGuardProps extends Omit<
  RouteGuardProps,
  'onUnauthorized'
> {
  refreshing?: ReactNode;
  tokenManager: JwtTokenManager;
}

packages/react/src/cosec/RefreshableRouteGuard.tsx:20

Fetcher hooks · Promise and query state · API hook factories · Debounced execution · Storage and event subscriptions · Wow query hooks · Monitoring, refs and fullscreen

Released under the Apache License 2.0.